Refactoring. And fixing problem with ring buffer size in NetAudioStream...

Refactoring. And fixing problem with ring buffer size in NetAudioStream initialization. Was giving an overhead of 3x the capacity ...
parent 8785c0c4
......@@ -59,6 +59,22 @@ public:
inline CITANetAudioProtocol() {};
inline ~CITANetAudioProtocol() {};
inline static std::string GetNPMessageID( const int iMessageType )
{
switch( iMessageType )
{
case NP_CLIENT_IDLE: return "CLIENT_IDLE";
case NP_CLIENT_OPEN: return "CLIENT_OPEN";
case NP_CLIENT_CLOSE: return "CLIENT_CLOSE";
case NP_CLIENT_SENDING_RINGBUFFER_FREE_SAMPLES: return "CLIENT_SENDING_RINGBUFFER_FREE_SAMPLES";
case NP_SERVER_OPEN: return "SERVER_OPEN";
case NP_SERVER_CLOSE: return "SERVER_CLOSE";
case NP_SERVER_GET_RINGBUFFER_FREE_SAMPLES: return "SERVER_GET_RINGBUFFER_FREE_SAMPLES";
case NP_SERVER_SENDING_SAMPLES: return "SERVER_SENDING_SAMPLES";
default: return "INVALID";
}
};
struct StreamingParameters
{
......
......@@ -180,6 +180,9 @@ protected:
*/
int GetRingBufferFreeSamples() const;
//! Returns a string for the streaming status identifier
static std::string GetStreamingStatusString( int iStreamingStatus );
private:
CITANetAudioStreamingClient* m_pNetAudioStreamingClient; //!< Audio streaming network client
......@@ -198,11 +201,10 @@ private:
ITABufferedDataLoggerImplNet* m_pNetworkStreamLogger; //!< Logging for the network stream
std::string m_sNetAudioStreamLoggerBaseName;
int iAudioStreamingBlockID; //!< Audio streaming block id
int iNetStreamingBlockID; //!< Network streaming block id
int m_iAudioStreamingBlockID; //!< Audio streaming block id
int m_iNetStreamingBlockID; //!< Network streaming block id
friend class CITANetAudioStreamingClient;
static std::string GetStreamingStatusString( int iStreamingStatus );
};
#endif // INCLUDE_WATCHER_ITA_NET_AUDIO_STREAM
......@@ -22,16 +22,16 @@
#include <ITADataSourcesDefinitions.h>
#include <ITANetAudioProtocol.h>
#include <ITANetAudioProtocol.h>
#include <ITASampleFrame.h>
#include <ITAStopWatch.h>
#include <VistaInterProcComm/Concurrency/VistaThreadLoop.h>
#include <string>
#include <vector>
#include <iostream>
#include <fstream>
#include <ITANetAudioProtocol.h>
#include <VistaInterProcComm/Concurrency/VistaThreadLoop.h>
#include <ITASampleFrame.h>
class ITADatasource;
class CITANetAudioMessage;
......@@ -102,9 +102,10 @@ private:
int iServerBlockId;
ITABufferedDataLoggerImplServer* m_pServerLogger;
std::string m_sServerLogBaseName;
ITAStopWatch m_swTryReadBlockStats, m_swTryReadAccessStats;
int m_iUpdateStrategy;
int m_iClientRingBufferFreeSamples;
int m_iEstimatedClientRingBufferFreeSamples;
int m_iTargetLatencySamples;
int m_iMaxSendBlocks;
double m_dLastTimeStamp;
......
......@@ -91,7 +91,7 @@ void CITANetAudioMessage::ResetMessage()
// from deleting the buffer while it is still being read
// by the connection
if( m_pConnection != NULL )
m_pConnection->WaitForSendFinish();
m_pConnection->WaitForSendFinish(); // can be time-costly
m_nMessageId = S_nMessageIds++;
......@@ -104,7 +104,6 @@ void CITANetAudioMessage::ResetMessage()
m_nMessageType = -1;
oLog.dInternalProcessingTime = ITAClock::getDefaultClock()->getTime() - dInTime;
m_pMessageLogger->log( oLog );
......
......@@ -57,7 +57,7 @@ struct ITANetworkStreamLog : public ITALogDataBase
{
os << "BlockId";
os << "\t" << "WorldTimeStamp";
os << "\t" << "Bufferstatus";
os << "\t" << "BufferStatus";
os << "\t" << "FreeSamples";
os << "\t" << "NumSamplesTransmitted";
os << std::endl;
......@@ -68,7 +68,7 @@ struct ITANetworkStreamLog : public ITALogDataBase
{
os << uiBlockId;
os << "\t" << std::setprecision( 12 ) << dWorldTimeStamp;
os << "\t" << iBufferStatus;
os << "\t" << sBufferStatus;
os << "\t" << iFreeSamples;
os << "\t" << iNumSamplesTransmitted;
os << std::endl;
......@@ -77,7 +77,7 @@ struct ITANetworkStreamLog : public ITALogDataBase
unsigned int uiBlockId;
double dWorldTimeStamp;
int iBufferStatus;
std::string sBufferStatus;
int iFreeSamples;
int iNumSamplesTransmitted;
};
......@@ -86,32 +86,30 @@ class ITABufferedDataLoggerImplStream : public ITABufferedDataLogger < ITAAudioS
class ITABufferedDataLoggerImplNet : public ITABufferedDataLogger < ITANetworkStreamLog > {};
CITANetAudioStream::CITANetAudioStream(int iChannels, double dSamplingRate, int iBufferSize, int iTargetSampleLatencyServer)
CITANetAudioStream::CITANetAudioStream(int iChannels, double dSamplingRate, int iBufferSize, int iRingBufferCapacity /* = 2048 */)
: m_sfOutputStreamBuffer( iChannels, iBufferSize, true )
, m_dSampleRate( dSamplingRate )
, m_sfRingBuffer(iChannels, iTargetSampleLatencyServer * 3, true)
, m_sfRingBuffer( iChannels, iRingBufferCapacity, true )
, m_bRingBufferFull( false )
, m_iStreamingStatus( INVALID )
, m_dLastStreamingTimeCode( 0.0f )
, m_iReadCursor( 0 )
, m_iWriteCursor( 0 ) // always ahead, i.e. iWriteCursor >= iReadCursor if unwrapped
, m_iAudioStreamingBlockID( 0 )
, m_iNetStreamingBlockID( 0 )
{
m_bRingBufferFull = false;
if (iBufferSize > iTargetSampleLatencyServer)
if( iBufferSize > iRingBufferCapacity )
ITA_EXCEPT1( INVALID_PARAMETER, "Ring buffer capacity can not be smaller than Target Sample Latency." );
m_pNetAudioStreamingClient = new CITANetAudioStreamingClient( this );
m_iReadCursor = 0;
m_iWriteCursor = 0; // always ahead, i.e. iWriteCursor >= iReadCursor if unwrapped
m_iStreamingStatus = STOPPED;
// Logging
m_pAudioStreamLogger = new ITABufferedDataLoggerImplStream();
iAudioStreamingBlockID = 0;
m_pNetworkStreamLogger = new ITABufferedDataLoggerImplNet();
iNetStreamingBlockID = 0;
SetNetAudioStreamingLoggerBaseName( "ITANetAudioStream" );
m_iStreamingStatus = STOPPED;
}
CITANetAudioStream::~CITANetAudioStream()
......@@ -245,7 +243,7 @@ void CITANetAudioStream::IncrementBlockPointer()
oLog.sStreamingStatus = GetStreamingStatusString( m_iStreamingStatus );
oLog.dWorldTimeStamp = ITAClock::getDefaultClock()->getTime();
oLog.dStreamingTimeCode = m_dLastStreamingTimeCode;
oLog.uiBlockId = ++iAudioStreamingBlockID;
oLog.uiBlockId = ++m_iAudioStreamingBlockID;
oLog.iFreeSamples = GetRingBufferFreeSamples( );
m_pAudioStreamLogger->log( oLog );
......@@ -298,10 +296,10 @@ int CITANetAudioStream::Transmit( const ITASampleFrame& sfNewSamples, int iNumSa
#endif
}
}
oLog.iBufferStatus = m_iStreamingStatus;
oLog.sBufferStatus = GetStreamingStatusString( m_iStreamingStatus );
oLog.dWorldTimeStamp = ITAClock::getDefaultClock( )->getTime( );
oLog.uiBlockId = ++iAudioStreamingBlockID;
oLog.iFreeSamples = GetRingBufferFreeSamples( );
oLog.uiBlockId = ++m_iAudioStreamingBlockID;
oLog.iFreeSamples = GetRingBufferFreeSamples();
oLog.iNumSamplesTransmitted = iNumSamples;
m_pNetworkStreamLogger->log( oLog );
......@@ -318,41 +316,11 @@ int CITANetAudioStream::GetRingBufferFreeSamples() const
if( m_bRingBufferFull )
return 0;
int iFreeSamples = GetRingBufferSize() - ((m_iWriteCursor - m_iReadCursor + GetRingBufferSize()) % GetRingBufferSize());
int iFreeSamples = GetRingBufferSize() - ( ( m_iWriteCursor - m_iReadCursor + GetRingBufferSize() ) % GetRingBufferSize() );
assert( iFreeSamples > 0 );
return iFreeSamples;
}
std::string CITANetAudioStream::GetStreamingStatusString( int iStreamingStatus )
{
if( iStreamingStatus == CITANetAudioStream::INVALID )
return "INVALID";
if( iStreamingStatus == CITANetAudioStream::STOPPED )
return "STOPPED";
if( iStreamingStatus == CITANetAudioStream::CONNECTED )
return "CONNECTED";
if( iStreamingStatus == CITANetAudioStream::STREAMING )
return "STREAMING";
if( iStreamingStatus == CITANetAudioStream::BUFFER_UNDERRUN )
return "BUFFER_UNDERRUN";
if( iStreamingStatus == CITANetAudioStream::BUFFER_OVERRUN )
return "BUFFER_OVERRUN";
return "UNKOWN";
}
std::string CITANetAudioStream::GetNetAudioStreamLoggerBaseName() const
{
return m_sNetAudioStreamLoggerBaseName;
}
void CITANetAudioStream::SetNetAudioStreamingLoggerBaseName( const std::string& sBaseName )
{
m_sNetAudioStreamLoggerBaseName = sBaseName;
m_pAudioStreamLogger->setOutputFile( GetNetAudioStreamLoggerBaseName() + "_AudioStream.log" );
m_pNetworkStreamLogger->setOutputFile( GetNetAudioStreamLoggerBaseName() + "_NetworkStream.log" );
}
int CITANetAudioStream::GetRingBufferSize() const
{
return m_sfRingBuffer.GetLength();
......@@ -382,3 +350,34 @@ double CITANetAudioStream::GetSampleRate() const
{
return m_dSampleRate;
}
std::string CITANetAudioStream::GetStreamingStatusString( int iStreamingStatus )
{
if( iStreamingStatus == CITANetAudioStream::INVALID )
return "INVALID";
if( iStreamingStatus == CITANetAudioStream::STOPPED )
return "STOPPED";
if( iStreamingStatus == CITANetAudioStream::CONNECTED )
return "CONNECTED";
if( iStreamingStatus == CITANetAudioStream::STREAMING )
return "STREAMING";
if( iStreamingStatus == CITANetAudioStream::BUFFER_UNDERRUN )
return "BUFFER_UNDERRUN";
if( iStreamingStatus == CITANetAudioStream::BUFFER_OVERRUN )
return "BUFFER_OVERRUN";
return "UNKOWN";
}
std::string CITANetAudioStream::GetNetAudioStreamLoggerBaseName() const
{
return m_sNetAudioStreamLoggerBaseName;
}
void CITANetAudioStream::SetNetAudioStreamingLoggerBaseName( const std::string& sBaseName )
{
m_sNetAudioStreamLoggerBaseName = sBaseName;
m_pAudioStreamLogger->setOutputFile( GetNetAudioStreamLoggerBaseName() + "_AudioStream.log" );
m_pNetworkStreamLogger->setOutputFile( GetNetAudioStreamLoggerBaseName() + "_NetworkStream.log" );
m_pNetAudioStreamingClient->SetClientLoggerBaseName( sBaseName );
}
......@@ -18,6 +18,7 @@ struct ITAClientLog : public ITALogDataBase
os << "BlockId";
os << "\t" << "WorldTimeStamp";
os << "\t" << "ProtocolStatus";
os << "\t" << "TransmittedRingBufferFreeSamples";
os << "\t" << "FreeSamples";
os << std::endl;
return os;
......@@ -27,7 +28,8 @@ struct ITAClientLog : public ITALogDataBase
{
os << uiBlockId;
os << "\t" << std::setprecision( 12 ) << dWorldTimeStamp;
os << "\t" << iProtocolStatus;
os << "\t" << sProtocolStatus;
os << "\t" << ( bTransmittedRingBufferFreeSamples ? "true" : "false" );
os << "\t" << iFreeSamples;
os << std::endl;
return os;
......@@ -35,7 +37,8 @@ struct ITAClientLog : public ITALogDataBase
unsigned int uiBlockId; //!< Block identifier (audio streaming)
double dWorldTimeStamp;
int iProtocolStatus; //!< ... usw
std::string sProtocolStatus;
bool bTransmittedRingBufferFreeSamples;
int iFreeSamples;
};
......@@ -77,8 +80,8 @@ CITANetAudioStreamingClient::~CITANetAudioStreamingClient()
delete m_pClient;
delete m_pMessage;
vstr::out() << "Try-read block calc time (ms): " << m_swTryReadBlockStats.ToString() << endl;
vstr::out() << "Try-read access time : " << m_swTryReadAccessStats.ToString() << endl;
vstr::out() << "[ ITANetAudioStreamingClient ] Processing statistics: " << m_swTryReadBlockStats.ToString() << std::endl;
vstr::out() << "[ ITANetAudioStreamingClient ] Try-read access statistics: " << m_swTryReadAccessStats.ToString() << std::endl;
}
bool CITANetAudioStreamingClient::Connect( const std::string& sAddress, int iPort )
......@@ -124,7 +127,8 @@ bool CITANetAudioStreamingClient::LoopBody()
ITAClientLog oLog;
oLog.uiBlockId = ++m_iStreamingBlockId;
oLog.iFreeSamples = m_pStream->GetRingBufferFreeSamples();
oLog.iProtocolStatus = CITANetAudioProtocol::NP_CLIENT_IDLE;
oLog.sProtocolStatus = CITANetAudioProtocol::GetNPMessageID( CITANetAudioProtocol::NP_CLIENT_IDLE );
oLog.bTransmittedRingBufferFreeSamples = false;
oLog.dWorldTimeStamp = ITAClock::getDefaultClock()->getTime();
......@@ -158,8 +162,7 @@ bool CITANetAudioStreamingClient::LoopBody()
m_swTryReadAccessStats.start();
if( m_pMessage->ReadMessage( 1 ) )
{
double dAccessTime = m_swTryReadAccessStats.stop();
m_swTryReadAccessStats.stop();
int iMsgType = m_pMessage->GetMessageType();
switch( iMsgType )
......@@ -169,7 +172,7 @@ bool CITANetAudioStreamingClient::LoopBody()
if( m_pStream->GetRingBufferFreeSamples() >= m_sfReceivingBuffer.GetLength() )
m_pStream->Transmit( m_sfReceivingBuffer, m_sfReceivingBuffer.GetLength() );
#ifdef NET_AUDIO_SHOW_TRAFFIC
vstr::out() << "[ITANetAudioStreamingClient] Recived " << m_sfReceivingBuffer.GetLength() << " samples" << std::endl;
vstr::out() << "[ITANetAudioStreamingClient] Received " << m_sfReceivingBuffer.GetLength() << " samples" << std::endl;
#endif
break;
......@@ -191,12 +194,11 @@ bool CITANetAudioStreamingClient::LoopBody()
}
// Also log message type on incoming message
oLog.iProtocolStatus = iMsgType;
oLog.sProtocolStatus = CITANetAudioProtocol::GetNPMessageID( iMsgType );
}
m_swTryReadBlockStats.stop();
m_pClientLogger->log( oLog );
if( m_swTryReadBlockStats.started() )
m_swTryReadBlockStats.stop();
// Send ring buffer free samples occasionally (as requested by server)
const double dNow = ITAClock::getDefaultClock()->getTime();
......@@ -206,7 +208,10 @@ bool CITANetAudioStreamingClient::LoopBody()
m_pMessage->WriteInt( m_pStream->GetRingBufferFreeSamples() );
m_pMessage->WriteMessage();
m_dServerClockSyncLastSyncTime = dNow;
oLog.bTransmittedRingBufferFreeSamples = true;
}
m_pClientLogger->log( oLog );
return false;
}
......@@ -221,7 +226,7 @@ void CITANetAudioStreamingClient::SetClientLoggerBaseName( const std::string& sB
m_sClientLoggerBaseName = sBaseName;
m_pClientLogger->setOutputFile( m_sClientLoggerBaseName + ".log" );
m_pMessage->SetMessageLoggerBaseName( GetClientLoggerBaseName() + "_Messages.log" );
m_pMessage->SetMessageLoggerBaseName( GetClientLoggerBaseName() + "_Messages" );
}
bool CITANetAudioStreamingClient::GetIsConnected() const
......
......@@ -29,7 +29,8 @@ struct ITAServerLog : public ITALogDataBase
os << "BlockId";
os << "\t" << "WorldTimeStamp";
os << "\t" << "ProtocolStatus";
os << "\t" << "FreeSamples";
os << "\t" << "EstimatedFreeSamples";
os << "\t" << "TransmittedSamples";
os << std::endl;
return os;
};
......@@ -38,16 +39,18 @@ struct ITAServerLog : public ITALogDataBase
{
os << uiBlockId;
os << "\t" << std::setprecision( 12 ) << dWorldTimeStamp;
os << "\t" << iProtocolStatus;
os << "\t" << iFreeSamples;
os << "\t" << sProtocolStatus;
os << "\t" << iEstimatedFreeSamples;
os << "\t" << iTransmittedSamples;
os << std::endl;
return os;
};
unsigned int uiBlockId; //!< Block identifier (audio streaming)
double dWorldTimeStamp;
int iProtocolStatus; //!< ... usw
int iFreeSamples;
std::string sProtocolStatus;
int iEstimatedFreeSamples;
int iTransmittedSamples;
};
class ITABufferedDataLoggerImplServer : public ITABufferedDataLogger < ITAServerLog > {};
......@@ -63,13 +66,16 @@ CITANetAudioStreamingServer::CITANetAudioStreamingServer()
{
iServerBlockId = 0;
m_iMaxSendBlocks = 40;
m_iClientRingBufferFreeSamples = 0;
m_iEstimatedClientRingBufferFreeSamples = 0;
}
CITANetAudioStreamingServer::~CITANetAudioStreamingServer()
{
delete m_pNetAudioServer;
delete m_pServerLogger;
vstr::out() << "[ ITANetAudioStreamingServer ] Processing statistics: " << m_swTryReadBlockStats.ToString() << std::endl;
vstr::out() << "[ ITANetAudioStreamingServer ] Try-read access statistics: " << m_swTryReadAccessStats.ToString() << std::endl;
}
bool CITANetAudioStreamingServer::Start( const std::string& sAddress, int iPort, double dTimeIntervalCientSendStatus )
......@@ -95,7 +101,7 @@ bool CITANetAudioStreamingServer::Start( const std::string& sAddress, int iPort,
bool bOK = false;
m_oServerParams.iRingBufferSize = oClientParams.iRingBufferSize;
m_oServerParams.iBlockSize = oClientParams.iBlockSize;
m_iClientRingBufferFreeSamples = m_oServerParams.iRingBufferSize;
m_iEstimatedClientRingBufferFreeSamples = m_oServerParams.iRingBufferSize;
m_dLastTimeStamp = ITAClock::getDefaultClock()->getTime();
if( m_oServerParams == oClientParams )
......@@ -130,21 +136,23 @@ bool CITANetAudioStreamingServer::Start( const std::string& sAddress, int iPort,
bool CITANetAudioStreamingServer::LoopBody()
{
bool bAskClient = false;
m_pMessage->ResetMessage();
const double dNow = ITAClock::getDefaultClock()->getTime();
ITAServerLog oLog;
oLog.dWorldTimeStamp = dNow;
oLog.uiBlockId = ++iServerBlockId;
int iMsgType;
// Sending Samples
oLog.iTransmittedSamples = 0;
// Sending Samples
int iBlockLength = m_pInputStream->GetBlocklength();
int iClientRingBufferTargetLatencyFreeSamples = m_iClientRingBufferFreeSamples - ( m_oServerParams.iRingBufferSize - m_iTargetLatencySamples );
int iEstimatedClientRingBufferTargetLatencyFreeSamples = m_iEstimatedClientRingBufferFreeSamples - ( m_oServerParams.iRingBufferSize - m_iTargetLatencySamples );
if( iClientRingBufferTargetLatencyFreeSamples >= iBlockLength )
if( iEstimatedClientRingBufferTargetLatencyFreeSamples >= iBlockLength )
{
// Send Samples
int iSendBlocks = iClientRingBufferTargetLatencyFreeSamples / iBlockLength;
bAskClient = true;
int iSendBlocks = iEstimatedClientRingBufferTargetLatencyFreeSamples / iBlockLength;
// Besser wre vermutlich, gleich alle samples zu senden und nicht nur einen Block nach dem anderen
if( m_sfTempTransmitBuffer.GetLength() != iBlockLength )
m_sfTempTransmitBuffer.init( m_pInputStream->GetNumberOfChannels(), iBlockLength, false );
......@@ -159,43 +167,45 @@ bool CITANetAudioStreamingServer::LoopBody()
if( pfData != 0 )
m_sfTempTransmitBuffer[ i ].write( pfData, iBlockLength, 0 );
}
m_pInputStream->IncrementBlockPointer();
iMsgType = CITANetAudioProtocol::NP_SERVER_SENDING_SAMPLES;
m_pMessage->SetMessageType( iMsgType );
m_pMessage->ResetMessage();
m_pMessage->SetMessageType( CITANetAudioProtocol::NP_SERVER_SENDING_SAMPLES );
m_pMessage->WriteSampleFrame( &m_sfTempTransmitBuffer );
m_pMessage->WriteMessage();
m_iClientRingBufferFreeSamples -= iBlockLength;
m_pMessage->ResetMessage();
m_iEstimatedClientRingBufferFreeSamples -= iBlockLength;
}
#ifdef NET_AUDIO_SHOW_TRAFFIC
vstr::out() << "[ITANetAudioStreamingServer] Transmitted " << iSendSamples << " samples for "
<< m_pInputStream->GetNumberOfChannels() << " channels" << std::endl;
#endif
}
else
bAskClient = true;
// Try to Empfange Daten
oLog.iTransmittedSamples = iSendBlocks * m_pInputStream->GetBlocklength();
}
// Try-read incoming messages from client (e.g. regular status information)
m_pMessage->ResetMessage();
m_swTryReadBlockStats.start();
m_swTryReadAccessStats.start();
if( m_pMessage->ReadMessage( 1 ) )
{
ITAServerLog oLog;
oLog.uiBlockId = ++iServerBlockId;
m_swTryReadAccessStats.stop();
int iMsgType = m_pMessage->GetMessageType();
switch( iMsgType )
{
case CITANetAudioProtocol::NP_CLIENT_SENDING_RINGBUFFER_FREE_SAMPLES:
{
m_iClientRingBufferFreeSamples = m_pMessage->ReadInt();
m_dLastTimeStamp = ITAClock::getDefaultClock()->getTime();
bAskClient = false;
m_iEstimatedClientRingBufferFreeSamples = m_pMessage->ReadInt();
m_dLastTimeStamp = dNow;
break;
}
case CITANetAudioProtocol::NP_CLIENT_CLOSE:
{
// Stop here because answer on client close might be blocking, we don't want that in our statistics
m_swTryReadBlockStats.stop();
m_pMessage->ResetMessage();
m_pMessage->SetMessageType( CITANetAudioProtocol::NP_SERVER_CLOSE );
m_pMessage->WriteMessage();
......@@ -203,55 +213,31 @@ bool CITANetAudioStreamingServer::LoopBody()
StopGently( false );
m_pConnection = NULL;
Stop();
bAskClient = false;
break;
}
default:
{
vstr::out() << "[ITANetAudioStreamingServer] Unkown protocol type : " << iMsgType << std::endl;
vstr::out() << "[ ITANetAudioStreamingServer ] Unkown protocol type : " << iMsgType << std::endl;
break;
}
}
oLog.iFreeSamples = m_iClientRingBufferFreeSamples;
oLog.iProtocolStatus = iMsgType;
oLog.dWorldTimeStamp = ITAClock::getDefaultClock()->getTime();
m_pServerLogger->log( oLog );
oLog.sProtocolStatus = CITANetAudioProtocol::GetNPMessageID( iMsgType );
}
else
{
ITAServerLog oLog;
oLog.uiBlockId = ++iServerBlockId;
// Neue Samples, bei ca 1ms warten
const double dTimestamp = ITAClock::getDefaultClock()->getTime();
const double dTimeDiff = dTimestamp - m_dLastTimeStamp;
m_dLastTimeStamp = dTimestamp;
oLog.dWorldTimeStamp = dTimestamp;
// There is no status message, so we estimate the client-side ring buffer status
const double dTimeDiff = dNow - m_dLastTimeStamp;
m_dLastTimeStamp = dNow;
double dEstimatedSamples = dTimeDiff * m_pInputStream->GetSampleRate();
m_iClientRingBufferFreeSamples += ( int ) dEstimatedSamples;
oLog.iFreeSamples = m_iClientRingBufferFreeSamples;
oLog.iProtocolStatus = 555;
m_pServerLogger->log( oLog );
m_iEstimatedClientRingBufferFreeSamples += ( int ) dEstimatedSamples;
oLog.sProtocolStatus = "SERVER_ESTIMATION";
}
bAskClient = false;
if( bAskClient )
{
#ifdef NET_AUDIO_SHOW_TRAFFIC
vstr::out() << "[ITANetAudioStreamingServer] Not enough free samples in client buffer, requesting a trigger when more free samples available" << std::endl;
#endif
ITAServerLog oLog;
oLog.uiBlockId = ++iServerBlockId;
m_pMessage->ResetMessage();
iMsgType = CITANetAudioProtocol::NP_SERVER_GET_RINGBUFFER_FREE_SAMPLES;
m_pMessage->SetMessageType( iMsgType );
m_pMessage->WriteBool( true );
m_pMessage->WriteMessage();
oLog.iProtocolStatus = iMsgType;
oLog.iFreeSamples = m_iClientRingBufferFreeSamples;
oLog.dWorldTimeStamp = ITAClock::getDefaultClock()->getTime();
m_pServerLogger->log( oLog );
}
if( m_swTryReadBlockStats.started() ) // only stop if still running
m_swTryReadBlockStats.stop();
oLog.iEstimatedFreeSamples = m_iEstimatedClientRingBufferFreeSamples;
m_pServerLogger->log( oLog );
return false;
}
......
......@@ -23,8 +23,8 @@ const static int g_iServerPort = 12480;
const static double g_dSampleRate = 44100;
const static int g_iBlockLength = 512;
const static int g_iChannels = 2;
const static int g_iTargetLatencySamples = g_iBlockLength * 10;
const static int g_iRingerBufferSize = g_iBlockLength * 10;
const static int g_iTargetLatencySamples = g_iBlockLength * 3;
const static int g_iRingerBufferCapacity = g_iBlockLength * 4;
class CServer : public VistaThread
{
......@@ -72,8 +72,8 @@ int main( int, char** )
CServer* pServer = new CServer( g_sInputFilePath );
// Client dumping received stream and mixing down to two channels
CITANetAudioStream oNetAudioStream( g_iChannels, g_dSampleRate, g_iBlockLength, g_iRingerBufferSize );
oNetAudioStream.SetNetAudioStreamingLoggerBaseName( "ITANetAudioTest_NetAudioStream" );
CITANetAudioStream oNetAudioStream( g_iChannels, g_dSampleRate, g_iBlockLength, g_iRingerBufferCapacity );
oNetAudioStream.SetNetAudioStreamingLoggerBaseName( "ITANetAudioTest_Client" );
ITAStreamPatchbay oPatchbay( g_dSampleRate, g_iBlockLength );
oPatchbay.AddInput( &oNetAudioStream );
......
%% Einlesen der Logs
close all;
clear all;
NetAudioLogNet = readtable( 'NetAudioLogNet_BS32_Ch2.txt', 'FileType', 'text', 'Delimiter', '\t');
NetAudioLogStream = readtable( 'NetAudioLogStream_BS32_Ch2.txt', 'FileType', 'text', 'Delimiter', '\t')
NetAudioLogClient = readtable( 'NetAudioLogClient_BS32_Ch2.txt', 'FileType', 'text', 'Delimiter', '\t' );
NetAudioLogBaseData = readtable( 'NetAudioLogBaseData_BS32_Ch2.txt', 'FileType', 'text', 'Delimiter', '\t' );
%% Load
ITANetAudioTest_Client = readtable( 'ITANetAudioTest_Client.log', 'FileType', 'text', 'Delimiter', '\t');
ITANetAudioTest_Server = readtable( 'ITANetAudioTest_Server.log', 'FileType', 'text', 'Delimiter', '\t');
ITANetAudioTest_Client_AudioStream = readtable( 'ITANetAudioTest_Client_AudioStream.log', 'FileType', 'text', 'Delimiter', '\t');
% Save Base Data
Channel = NetAudioLogBaseData.Channel(1);
SampleRate = NetAudioLogBaseData.Samplerate(1);
BufferSize = NetAudioLogBaseData.BufferSize(1);
RingBufferSize = NetAudioLogBaseData.RingBufferSize(1);
TargetSampleLatency = NetAudioLogBaseData.TargetSampleLatency(1);
minTime = min(NetAudioLogStream.WorldTimeStamp(1),NetAudioLogNet.WorldTimeStamp(1));
TimeNet = NetAudioLogNet.WorldTimeStamp - minTime;
TimeStream = NetAudioLogStream.WorldTimeStamp - minTime;
%% Settings
RB = 512*4;
TL = 512*3;
TimeState = [TimeStream NetAudioLogStream.StreamingStatus];