ITANetAudioTest.cpp 7.27 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;
Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
28
const static int g_iBlockLength = 512;
29
const static int g_iChannels = 2;
30 31
const static int g_iTargetLatencySamples = g_iBlockLength * 2;
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;
Dipl.-Ing. Jonas Stienen's avatar
Dipl.-Ing. Jonas Stienen committed
35 36
const static string g_sAudioInterface = "ASIO4ALL v2";
//const static string g_sAudioInterface = "ASIO Hammerfall DSP";
37
const static bool g_bUseUDP = false;
38

39
class CSampleGenerator : public CITASampleProcessor
40 41
{
public:
42 43 44 45 46
	inline CSampleGenerator() 
		: CITASampleProcessor( g_dSampleRate, g_iChannels, g_iBlockLength )
	{};
	
	inline void Process( const ITAStreamInfo* pStreamInfo )
Anne Heimes's avatar
Anne Heimes committed
47
	{
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
		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
105 106

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

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

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

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

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

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

	// Client dumping received stream and mixing down to two channels
138 139
	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
140
	oNetAudioStream.SetDebuggingEnabled( true );
Anne Heimes's avatar
Anne Heimes committed
141 142 143 144 145 146

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

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

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

	ITAPortaudioInterface ITAPA( g_dSampleRate, g_iBlockLength );
153
	if( g_bUseASIO )
Anne Heimes's avatar
Anne Heimes committed
154
	{
155 156 157 158 159 160 161 162 163 164 165 166
		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
167
	}
168
	else
Anne Heimes's avatar
Anne Heimes committed
169
	{
170 171 172 173
		ITAPA.Initialize();
		ITAPA.SetPlaybackDatasource( &oProbe );
		ITAPA.Open();
		ITAPA.Start();
Anne Heimes's avatar
Anne Heimes committed
174
	}
175 176 177 178 179 180

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

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

181
	if( !oNetAudioStream.Connect( g_sServerName, g_iServerPort, g_bUseUDP ) )
182
		ITA_EXCEPT1( INVALID_PARAMETER, "Could not connect to net audio server" );
Anne Heimes's avatar
Anne Heimes committed
183 184 185
	vstr::out() << "[ NetAudioTestClient ] Connected." << endl;

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

191 192
	oNetAudioStream.Disconnect();

Anne Heimes's avatar
Anne Heimes committed
193 194
	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;
195
	VistaTimeUtils::Sleep( int( 1.0f * 1.0e3 ) );
Anne Heimes's avatar
Anne Heimes committed
196

197 198 199 200 201 202 203 204 205 206 207 208 209
	if( g_bUseASIO )
	{
		ITAsioStop();
		ITAsioDisposeBuffers();
		ITAsioFinalizeDriver();
		ITAsioFinalizeLibrary();
	}
	else
	{
		ITAPA.Stop();
		ITAPA.Close();
		ITAPA.Finalize();
	}
Anne Heimes's avatar
Anne Heimes committed
210

211 212
	delete pServer;

213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231
};

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
232
	return 0;
233

Anne Heimes's avatar
Anne Heimes committed
234
}