ITANetAudioTest.cpp 7.41 KB
Newer Older
Anne Heimes's avatar
Anne Heimes committed
1
#include <ITANetAudioStreamingServer.h>
2
#include <ITANetAudioSampleServer.h>
Anne Heimes's avatar
Anne Heimes committed
3
4
5
6
7
#include <ITANetAudioStream.h>
#include <ITAPortaudioInterface.h>
#include <ITAStreamFunctionGenerator.h>
#include <ITAStreamMultiplier1N.h>
#include <ITAException.h>
Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
8
#include <ITAFileDataSource.h>
Anne Heimes's avatar
Anne Heimes committed
9
#include <ITAStreamProbe.h>
Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
10
#include <ITAStreamPatchBay.h>
11
#include <ITAAsioInterface.h>
12
#include <ITAStreamInfo.h>
Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
13

Anne Heimes's avatar
Anne Heimes committed
14
#include <VistaBase/VistaStreamUtils.h>
15
16
#include <VistaBase/VistaTimeUtils.h>
#include <VistaBase/VistaExceptionBase.h>
Anne Heimes's avatar
Anne Heimes committed
17

Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
18
19
20
21
#include <cmath>
#include <iostream>
#include <string>

Anne Heimes's avatar
Anne Heimes committed
22
23
using namespace std;

24
const static string g_sServerName = "localhost";
Anne Heimes's avatar
Anne Heimes committed
25
26
const static string g_sInputFilePath = "gershwin-mono.wav";
const static int g_iServerPort = 12480;
27
const static double g_dSampleRate = 44100;
28
const static int g_iBlockLength = 128;
29
const static int g_iChannels = 2;
30
const static int g_iTargetLatencySamples = g_iBlockLength * 4;
31
const static int g_iRingerBufferCapacity = g_iBlockLength * 10;
32
const static double g_dDuration = 10.0f;
33
const static double g_dSyncTimout = 0.001f;
34
const static bool g_bUseASIO = true;
Jonas Stienen's avatar
Jonas Stienen committed
35
36
37
//const static string g_sAudioInterface = "ASIO MADIface USB";
//const static string g_sAudioInterface = "ASIO4ALL v2";
const static string g_sAudioInterface = "ASIO Hammerfall DSP";
38
const static bool g_bUseUDP = false;
39

40
class CSampleGenerator : public CITASampleProcessor
41
42
{
public:
43
	inline CSampleGenerator() 
44
		: CITASampleProcessor( g_iChannels, g_dSampleRate, g_iBlockLength )
45
46
47
	{};
	
	inline void Process( const ITAStreamInfo* pStreamInfo )
Anne Heimes's avatar
Anne Heimes committed
48
	{
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
		for( size_t c = 0; c < m_vvfSampleBuffer.size(); c++ )
		{
			for( size_t n = 0; n < m_vvfSampleBuffer[ c ].size(); n++ )
			{
				float fSample = ( c == 0 ? 1.0f : -1.0f ) * ( 1.0f - 2.0f * n / float( GetBlocklength() ) );
				m_vvfSampleBuffer[ c ][ n ] = fSample;
			}
		}
	};
};

class CSampleServerExample : public VistaThread
{
public:
	inline CSampleServerExample()
	{
		m_pSampleGenerator = new CSampleGenerator();
		m_pSampleServer = new CITANetAudioSampleServer( m_pSampleGenerator );
		m_pSampleServer->SetDebuggingEnabled( true );
		m_pSampleServer->SetTargetLatencySamples( g_iTargetLatencySamples );
		m_pSampleServer->SetServerLogBaseName( "ITANetAudioTest_Server" );

		Run();
	};

	inline ~CSampleServerExample()
	{
		delete m_pSampleServer;
		delete m_pSampleGenerator;
	};

	void ThreadBody()
	{
		vstr::out() << "[ NetAudioTestServer ] Starting net audio sample server and waiting for client connections on '" << g_sServerName << "' on port " << g_iServerPort << endl;
		m_pSampleServer->Start( g_sServerName, g_iServerPort, g_dSyncTimout, g_bUseUDP );
	};

	CITANetAudioSampleServer* m_pSampleServer;
	CSampleGenerator* m_pSampleGenerator;
};

class CStreamServerExample : public VistaThread
{
public:
	inline CStreamServerExample( const string& sInputFilePath )
	{
		m_pStreamingServer = new CITANetAudioStreamingServer;
		m_pStreamingServer->SetDebuggingEnabled( true );
		m_pStreamingServer->SetTargetLatencySamples( g_iTargetLatencySamples );
		m_pStreamingServer->SetServerLogBaseName( "ITANetAudioTest_Server" );

		m_pInputFile = new ITAFileDatasource( sInputFilePath, g_iBlockLength );
		m_pInputFile->SetIsLooping( true );
		assert( m_pInputFile->GetNumberOfChannels() == 1 );
		m_pMultiplier = new ITAStreamMultiplier1N( m_pInputFile, g_iChannels );
		m_pInputStreamProbe = new ITAStreamProbe( m_pMultiplier, "ITANetAudioTest.serverstream.wav" );
		m_pStreamingServer->SetInputStream( m_pInputStreamProbe );
Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
106
107

		Run();
Anne's avatar
Anne committed
108
	};
Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
109

110
	inline ~CStreamServerExample()
Anne's avatar
Anne committed
111
	{
112
113
114
115
		delete m_pInputFile;
		delete m_pMultiplier;
		delete m_pStreamingServer;
		delete m_pInputStreamProbe;
Anne's avatar
Anne committed
116
	};
Anne's avatar
Anne committed
117

Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
118
	void ThreadBody( )
Anne Heimes's avatar
Anne Heimes committed
119
	{
120
		vstr::out() << "[ NetAudioTestServer ] Starting net audio server and waiting for client connections on '" << g_sServerName << "' on port " << g_iServerPort << endl;
121
		m_pStreamingServer->Start( g_sServerName, g_iServerPort, g_dSyncTimout, g_bUseUDP );
Anne's avatar
Anne committed
122
	};
Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
123

Anne's avatar
Anne committed
124
private:
125
126
127
128
	ITAFileDatasource* m_pInputFile;
	ITAStreamMultiplier1N* m_pMultiplier;
	CITANetAudioStreamingServer* m_pStreamingServer;
	ITAStreamProbe* m_pInputStreamProbe;
Anne Heimes's avatar
Anne Heimes committed
129
130
};

131
void run_test()
Anne Heimes's avatar
Anne Heimes committed
132
{
133

Anne Heimes's avatar
Anne Heimes committed
134
	// Sample server (forked away into a thread)
135
136
	//CStreamServerExample* pServer = new CStreamServerExample( g_sInputFilePath );
	CSampleServerExample* pServer = new CSampleServerExample();
Anne Heimes's avatar
Anne Heimes committed
137
138

	// Client dumping received stream and mixing down to two channels
139
140
	CITANetAudioStream oNetAudioStream( g_iChannels, g_dSampleRate, g_iBlockLength, g_iRingerBufferCapacity );
	oNetAudioStream.SetNetAudioStreamingLoggerBaseName( "ITANetAudioTest_Client" );
Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
141
	oNetAudioStream.SetDebuggingEnabled( true );
Anne Heimes's avatar
Anne Heimes committed
142
143
144
145
146
147

	ITAStreamPatchbay oPatchbay( g_dSampleRate, g_iBlockLength );
	oPatchbay.AddInput( &oNetAudioStream );
	int iOutputID = oPatchbay.AddOutput( 2 );

	int N = int( oNetAudioStream.GetNumberOfChannels() );
148
	for( int i = 0; i < N; i++ )
Anne Heimes's avatar
Anne Heimes committed
149
		oPatchbay.ConnectChannels( 0, i, 0, i % 2, 1 / double( N ) );
150

151
	ITAStreamProbe oProbe( oPatchbay.GetOutputDatasource( iOutputID ), "ITANetAudioTest.netstream.wav" );
Anne Heimes's avatar
Anne Heimes committed
152
153

	ITAPortaudioInterface ITAPA( g_dSampleRate, g_iBlockLength );
154
	if( g_bUseASIO )
Anne Heimes's avatar
Anne Heimes committed
155
	{
156
157
158
159
160
161
162
163
164
165
166
167
		ITAsioInitializeLibrary();
		ITAsioInitializeDriver( g_sAudioInterface );

		long lBuffersize, lDummy;
		ITAsioGetBufferSize( &lDummy, &lDummy, &lBuffersize, &lDummy );
		ITAsioSetSampleRate( ( ASIOSampleRate ) g_dSampleRate );
		long lNumInputChannels, lNumOutputChannels;
		ITAsioGetChannels( &lNumInputChannels, &lNumOutputChannels );
		ITAsioCreateBuffers( 0, 2, lBuffersize );
		ITAsioSetPlaybackDatasource( &oProbe );
		ITAsioStart();

Anne Heimes's avatar
Anne Heimes committed
168
	}
169
	else
Anne Heimes's avatar
Anne Heimes committed
170
	{
171
172
173
174
		ITAPA.Initialize();
		ITAPA.SetPlaybackDatasource( &oProbe );
		ITAPA.Open();
		ITAPA.Start();
Anne Heimes's avatar
Anne Heimes committed
175
	}
176

177
178
179
180
	try
	{
		vstr::out() << "[ NetAudioTestClient ] Waiting 1 second (net audio stream not connected and playing back zeros)" << endl;
		VistaTimeUtils::Sleep( int( 1.0f * 1.0e3 ) );
181

182
		vstr::out() << "[ NetAudioTestClient ] Will now connect to net audio server '" << g_sServerName << "' on port " << g_iServerPort << endl;
183

184
185
186
187
		if( !oNetAudioStream.Connect( g_sServerName, g_iServerPort, g_bUseUDP ) )
			vstr::out() << "[ NetAudioTestClient ] Connection failed." << endl;
		else
			vstr::out() << "[ NetAudioTestClient ] Connected." << endl;
Anne Heimes's avatar
Anne Heimes committed
188

189
190
191
192
193
		// Playback
		float fSeconds = float( g_dDuration );
		vstr::out() << "[ NetAudioTestClient ] Playback started, waiting " << fSeconds << " seconds" << endl;
		VistaTimeUtils::Sleep( int( fSeconds * 1.0e3 ) ); // blocking
		vstr::out() << "[ NetAudioTestClient ] Done." << endl;
Anne Heimes's avatar
Anne Heimes committed
194

195
		oNetAudioStream.Disconnect();
196

197
198
199
200
201
202
203
204
		vstr::out() << "[ NetAudioTestClient ] Will now disconnect from net audio server '" << g_sServerName << "' and port " << g_iServerPort << endl;
		vstr::out() << "[ NetAudioTestClient ] Closing in 1 second (net audio stream not connected and playing back zeros)" << endl;
		VistaTimeUtils::Sleep( int( 1.0f * 1.0e3 ) );
	}
	catch( ITAException& e )
	{
		cerr << e << endl;
	}
Anne Heimes's avatar
Anne Heimes committed
205

206
207
208
209
210
211
212
213
214
215
216
217
218
	if( g_bUseASIO )
	{
		ITAsioStop();
		ITAsioDisposeBuffers();
		ITAsioFinalizeDriver();
		ITAsioFinalizeLibrary();
	}
	else
	{
		ITAPA.Stop();
		ITAPA.Close();
		ITAPA.Finalize();
	}
Anne Heimes's avatar
Anne Heimes committed
219

220
221
	delete pServer;

222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
};

int main( int, char** )
{
	try
	{
		run_test();
	}
	catch( ITAException& ie )
	{
		vstr::err() << ie << endl;
		return 255;
	}
	catch( VistaExceptionBase& ve )
	{
		vstr::err() << ve.GetBacktraceString() << endl;
		return 255;
	}

Anne Heimes's avatar
Anne Heimes committed
241
	return 0;
242

Anne Heimes's avatar
Anne Heimes committed
243
}