Commit 6de9f983 authored by Jonas Stienen's avatar Jonas Stienen
Browse files

Improving Portaudio playback loop

Adding NetAudio test (file playback over server/client system using ITADataSource)
parent de9eb8e5
......@@ -523,12 +523,16 @@ static int PortaudioCallbackFunction( const void* pInBuffer, void* pOutBuffer, u
{
int iNumOutputChannels = pipdsPlaybackDatasource->GetNumberOfChannels();
const float* pOutDataBlock;
std::vector< const float* > vpBlockPointer( iNumOutputChannels );
for( int j = 0; j < iNumOutputChannels; j++ )
vpBlockPointer[ j ] = pipdsPlaybackDatasource->GetBlockPointer( j, &oStreamInfo );
for( unsigned int i = 0; i < ulBuffersize; i++ )
{
for( int j = 0; j < iNumOutputChannels; j++ )
{
int index = i*iNumOutputChannels + j;
pOutDataBlock = pipdsPlaybackDatasource->GetBlockPointer( j, &oStreamInfo );
pOutDataBlock = vpBlockPointer[ j ];
float fValue = pOutDataBlock ? pOutDataBlock[ i ] : 0.0f;
out[ index ] = fValue;
}
......
......@@ -8,50 +8,108 @@
//#include <VistaBase/VistaTimeUtils.h>
#include <VistaInterProcComm/IPNet/VistaIPAddress.h>
#include <ITAStringUtils.h>
#include <ITASampleFrame.h>
#include <cassert>
int main( int argc, char** argv )
{
std::string sServerName = "localhost";
int iServerPort = 12343;
std::cout << "Setting up ITANA server command channel on '" << sServerName << ":" << iServerPort << "'" << std::endl;
VistaTCPServer oNAServer( sServerName, iServerPort, 1 );
using namespace std;
std::cout << "Waiting for connection" << std::endl;
VistaTCPSocket* pSocket = oNAServer.GetNextClient();
static string g_sServerName = "localhost";
static int g_iServerPort = 12480;
if( oNAServer.GetIsValid() == false )
//! NetAudio buffer server
class CITANAServer : public VistaThreadLoop
{
public:
CITANAServer()
{
std::cerr << "Could not start server" << std::endl;
return 255;
m_pServer = new VistaTCPServer( g_sServerName, g_iServerPort, 1 );
cout << "ITANA server running, waiting for connection" << endl;
m_sfBuffer.Load( "Bauer.wav" );
m_iReadPointer = 0;
m_pSocket = m_pServer->GetNextClient();
Run();
}
std::cout << "Waiting for result channel port" << std::endl;
unsigned long l = pSocket->WaitForIncomingData( 0 );
~CITANAServer()
{
delete m_pServer;
}
if( l == 8 )
bool LoopBody()
{
unsigned long iRequestedResultChannelPort;
pSocket->ReceiveRaw( &iRequestedResultChannelPort, 8 );
if( m_pSocket->GetIsConnected() == false )
{
cout << "Connection closed. Stopping loop." << endl;
StopGently( true );
return false;
}
std::string sRemoteAddress;
VistaSocketAddress sAddr;
pSocket->GetPeerSockName( sAddr );
sAddr.GetIPAddress().GetAddressString( sRemoteAddress );
size_t nGetReceiveBufferSize = m_pSocket->GetReceiveBufferSize();
VistaConnectionIP oConnection( VistaConnectionIP::CT_TCP, sRemoteAddress, iRequestedResultChannelPort );
cout << "Waiting for new incoming data" << endl;
long nIncomingBytes = m_pSocket->WaitForIncomingData( 0 );
cout << "Server incoming bytes: " << nIncomingBytes << " bytes" << endl;
bool bAck = oConnection.GetIsConnected();
oConnection.Send( &bAck, sizeof( bool ) );
oConnection.WaitForSendFinish( 0 );
if( nGetReceiveBufferSize == nIncomingBytes )
cout << "Warning: payload as long as receiver buffer size ... problem will occur!" << endl;
std::cout << "Result channel connection successfully established" << std::endl;
if( nIncomingBytes == 0 )
{
cout << "Connection closed. Stopping loop." << endl;
StopGently( true );
oConnection.Close( false );
return false;
}
assert( sizeof( int ) <= nIncomingBytes );
int iChannelIndex;
int iBytesReceived = m_pSocket->ReceiveRaw( &iChannelIndex, sizeof( int ) );
nIncomingBytes = m_pSocket->WaitForIncomingData( 0 );
assert( sizeof( int ) <= nIncomingBytes );
int iNumSamples;
iBytesReceived = m_pSocket->ReceiveRaw( &iNumSamples, sizeof( int ) );
if( m_sfOutBuffer.channels() <= iChannelIndex || m_sfOutBuffer.length() != iNumSamples )
m_sfOutBuffer.init( iChannelIndex + 1, iNumSamples, true );
else
m_sfOutBuffer.zero();
cout << "Server sending samples";
ITASampleBuffer* pBuf = &m_sfBuffer[ iChannelIndex ];
pBuf->cyclic_read( m_sfOutBuffer[ iChannelIndex ].data(), iNumSamples, m_iReadPointer );
m_pSocket->SendRaw( m_sfOutBuffer[ iChannelIndex ].data(), iNumSamples * sizeof( float ) );
m_pSocket->WaitForSendFinish( 0 );
cout << " ... finished" << endl;
m_iReadPointer += iNumSamples;
m_iReadPointer = m_iReadPointer % m_sfBuffer.length();
return true;
}
pSocket->CloseSocket();
private:
VistaTCPServer* m_pServer;
VistaTCPSocket* m_pSocket;
ITASampleFrame m_sfBuffer;
ITASampleFrame m_sfOutBuffer;
int m_iReadPointer;
};
int main( int , char** )
{
CITANAServer oITANAServer;
cout << "Press any key to quit" << endl;
int iIn;
cin >> iIn;
return 0;
}
......@@ -6,55 +6,120 @@
#include <VistaInterProcComm/IPNet/VistaTCPSocket.h>
#include <VistaInterProcComm/IPNet/VistaIPAddress.h>
#include <ITAStringUtils.h>
#include <ITAStopwatch.h>
#include <ITAStringUtils.h>
#include <ITAPortaudioInterface.h>
#include <ITADataSource.h>
#include <ITASampleFrame.h>
#include <ITAStreamMultiplier1N.h>
int main(int argc, char** argv)
{
std::string sServerName ="localhost";
int iServerPort = 12343;
using namespace std;
std::cout << "Attempting to connect to ITANA server at '" << sServerName << ":" << iServerPort << "'" << std::endl;
static string g_sServerName = "localhost";
static int g_iServerPort = 12480;
static double g_dSampleRate = 44.1e3;
static int g_iBufferSize = 256;
VistaConnectionIP oCommandChannelConnection( VistaConnectionIP::CT_TCP, sServerName, iServerPort);
class CITANAStream : public ITADatasource
{
public:
inline CITANAStream( int iChannels, double dSamplingRate, int iBufferSize )
: m_iBufferSize( iBufferSize )
, m_dSampleRate( dSamplingRate )
, m_iNumChannels( iChannels )
//, m_iReadPointer( 0 )
, m_sfOutBuffer( iChannels, iBufferSize, true )
, m_pConnection( NULL )
{
m_sfNetBuffer.Load( "Bauer.wav" );
if( oCommandChannelConnection.GetIsConnected() == false )
m_pConnection = new VistaConnectionIP( VistaConnectionIP::CT_TCP, g_sServerName, g_iServerPort );
if( m_pConnection->GetIsConnected() )
{
cout << "Connection established" << endl;
}
};
inline ~CITANAStream()
{
std::cerr << "Connection error, exiting." << std::endl;
return 255;
}
delete m_pConnection;
};
std::string sLocalAddress;
oCommandChannelConnection.GetLocalAddress().GetIPAddress().GetAddressString( sLocalAddress );
inline unsigned int GetBlocklength() const
{
return m_iBufferSize;
};
int iBackChannelPort = 12481;
VistaTCPServer oServer( sLocalAddress, iBackChannelPort, 1 );
if( oServer.GetIsValid() == false)
inline unsigned int GetNumberOfChannels() const
{
std::cerr << "Could not start server" << std::endl;
return 255;
}
else
return m_iNumChannels;
};
inline double GetSampleRate() const
{
std::cout << "Duplex connection opened, data communication channel port: " << iBackChannelPort << std::endl;
}
return m_dSampleRate;
};
// Transmit port on command channel
oCommandChannelConnection.WriteRawBuffer( &iBackChannelPort, 8 );
VistaTCPSocket* pSocket = oServer.GetNextClient();
unsigned long l = pSocket->WaitForIncomingData( 0 );
inline const float* GetBlockPointer( unsigned int uiChannel, const ITAStreamInfo* )
{
// get buffer from net audio stream
if( m_pConnection->GetIsConnected() )
{
m_pConnection->Send( &uiChannel, sizeof( int ) );
m_pConnection->Send( &m_iBufferSize, sizeof( int ) );
void* pDestination = ( void* ) m_sfOutBuffer[ uiChannel ].data();
int iReceiveBufferLength = sizeof( float ) * m_iBufferSize;
int l = m_pConnection->Receive( pDestination, iReceiveBufferLength );
assert( l == iReceiveBufferLength );
//cout << "Data received: " << l << endl;
}
else
{
m_sfOutBuffer.zero();
}
return m_sfOutBuffer[ uiChannel].GetData();
};
if( l == sizeof( VistaType::byte ) )
void IncrementBlockPointer()
{
bool bAck;
pSocket->ReceiveRaw( &bAck, l );
std::cout << "Client received acknowledge flag '" << bAck << "'" << std::endl;
}
//m_iReadPointer += m_iBufferSize;
//m_iReadPointer = m_iReadPointer % m_sfNetBuffer.GetLength();
//cout << "Block pointer increment" << endl;
};
private:
int m_iBufferSize;
int m_iNumChannels;
double m_dSampleRate;
ITASampleFrame m_sfNetBuffer;
ITASampleFrame m_sfOutBuffer;
//int m_iReadPointer;
VistaConnectionIP* m_pConnection;
};
int main(int , char** )
{
CITANAStream* pNetAudioStream = new CITANAStream( 1, g_dSampleRate, g_iBufferSize );
ITAStreamMultiplier1N oMultiplier( pNetAudioStream, 2 );
ITAPortaudioInterface ITAPA( g_dSampleRate, g_iBufferSize );
ITAPA.Initialize();
ITAPA.SetPlaybackDatasource( &oMultiplier );
ITAPA.Open();
ITAPA.Start();
// Playback
float seconds = 10.0f;
cout << "Playback started, waiting " << seconds << " seconds" << endl;
ITAPA.Sleep( seconds ); // blocking
cout << "Done." << endl;
ITAPA.Stop();
ITAPA.Close();
ITAPA.Finalize();
delete pNetAudioStream;
oCommandChannelConnection.Close( false );
return 0;
}
......@@ -24,7 +24,8 @@ public:
Run();
}
~CServer() {
~CServer()
{
delete m_pServer;
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment