From 3bd2999252a52224254c6a85b7a4384b692f3bab Mon Sep 17 00:00:00 2001 From: Volker Fischer Date: Fri, 31 Jul 2009 19:55:28 +0000 Subject: [PATCH] some initial work on server timer problem --- src/channel.cpp | 10 +++++----- src/global.h | 4 ++-- src/server.cpp | 51 +++++++++++++++++++++++++++++++++++-------------- src/server.h | 27 +++++++++++++++++++++++--- 4 files changed, 68 insertions(+), 24 deletions(-) diff --git a/src/channel.cpp b/src/channel.cpp index 56e32641..ba476352 100755 --- a/src/channel.cpp +++ b/src/channel.cpp @@ -136,7 +136,7 @@ void CChannel::SetNetwFrameSizeAndFact ( const int iNewNetwFrameSize, ConvBuf.Init ( iNetwFrameSize * iNetwFrameSizeFact ); // initialize and reset cycle time variance measurement - CycleTimeVariance.Init ( iNetwFrameSizeFact * SYSTEM_BLOCK_SIZE_SAMPLES, + CycleTimeVariance.Init ( iNetwFrameSizeFact * SYSTEM_BLOCK_FRAME_SAMPLES, SYSTEM_SAMPLE_RATE, TIME_MOV_AV_RESPONSE ); CycleTimeVariance.Reset(); @@ -157,7 +157,7 @@ bool CChannel::SetSockBufSize ( const int iNumBlocks ) // the network block size is a multiple of the internal minimal // block size - SockBuf.Init ( SYSTEM_BLOCK_SIZE_SAMPLES, iNumBlocks ); + SockBuf.Init ( SYSTEM_BLOCK_FRAME_SAMPLES, iNumBlocks ); return false; // -> no error } @@ -432,12 +432,12 @@ EGetDataStat CChannel::GetData ( CVector& vecbyData ) // subtract the number of samples of the current block since the // time out counter is based on samples not on blocks (definition: // always one atomic block is get by using the GetData() function - // where the atomic block size is "SYSTEM_BLOCK_SIZE_SAMPLES") + // where the atomic block size is "SYSTEM_BLOCK_FRAME_SAMPLES") // TODO this code only works with the above assumption -> better // implementation so that we are not depending on assumptions - iConTimeOut -= SYSTEM_BLOCK_SIZE_SAMPLES; + iConTimeOut -= SYSTEM_BLOCK_FRAME_SAMPLES; if ( iConTimeOut <= 0 ) { @@ -490,7 +490,7 @@ CVector CChannel::PrepSendPacket ( const CVector& vecbyNPacket int CChannel::GetUploadRateKbps() { - const int iAudioSizeOut = iNetwFrameSizeFact * SYSTEM_BLOCK_SIZE_SAMPLES; + const int iAudioSizeOut = iNetwFrameSizeFact * SYSTEM_BLOCK_FRAME_SAMPLES; // we assume that the UDP packet which is transported via IP has an // additional header size of diff --git a/src/global.h b/src/global.h index ad7ad820..f8ff6908 100755 --- a/src/global.h +++ b/src/global.h @@ -60,10 +60,10 @@ // System block size, this is the block size on which the audio coder works. // All other block sizes must be a multiple of this size -#define SYSTEM_BLOCK_SIZE_SAMPLES 128 +#define SYSTEM_BLOCK_FRAME_SAMPLES 128 #define SYSTEM_BLOCK_DURATION_MS_FLOAT \ - ( static_cast ( SYSTEM_BLOCK_SIZE_SAMPLES ) / \ + ( static_cast ( SYSTEM_BLOCK_FRAME_SAMPLES ) / \ SYSTEM_SAMPLE_RATE * 1000 ) // define the maximum mono audio buffer size at a sample rate diff --git a/src/server.cpp b/src/server.cpp index 2887a0e6..26c8c156 100755 --- a/src/server.cpp +++ b/src/server.cpp @@ -50,15 +50,34 @@ CServer::CServer ( const QString& strLoggingFileName, vstrChatColors[4] = "maroon"; vstrChatColors[5] = "coral"; - vecsSendData.Init ( SYSTEM_BLOCK_SIZE_SAMPLES ); + vecsSendData.Init ( SYSTEM_BLOCK_FRAME_SAMPLES ); // init moving average buffer for response time evaluation - CycleTimeVariance.Init ( SYSTEM_BLOCK_SIZE_SAMPLES, + CycleTimeVariance.Init ( SYSTEM_BLOCK_FRAME_SAMPLES, SYSTEM_SAMPLE_RATE, TIME_MOV_AV_RESPONSE ); + // connect timer timeout signal - QObject::connect ( &Timer, SIGNAL ( timeout() ), - this, SLOT ( OnTimer() ) ); + QObject::connect ( &HighPrecisionTimer, SIGNAL ( timeout() ), + this, SLOT ( OnHighPrecisionTimer() ) ); + + + +/* +// init timer stuff +//vTimeOutIntervals = [0 ] + +// for 128 sample frame size at 48 kHz sampling rate: +// actual intervals: 0.0 2.666 5.333 8.0 +// quantized to 1 ms: 0 3 5 8 (0) + +// for 256 sample frame size at 48 kHz sampling rate: +// actual intervals: 0.0 5.333 10.666 16.0 +// quantized to 1 ms: 0 5 11 16 (0) +*/ + + + // enable logging (if requested) if ( !strLoggingFileName.isEmpty() ) @@ -176,10 +195,8 @@ void CServer::Start() { if ( !IsRunning() ) { - // start main timer - -// TEST -Timer.start ( static_cast ( ceil ( SYSTEM_BLOCK_DURATION_MS_FLOAT ) ) ); + // start main timer with lowest possible resolution + HighPrecisionTimer.start ( MIN_TIMER_RESOLUTION_MS ); // init time for response time evaluation CycleTimeVariance.Reset(); @@ -189,16 +206,22 @@ Timer.start ( static_cast ( ceil ( SYSTEM_BLOCK_DURATION_MS_FLOAT ) ) ); void CServer::Stop() { // stop main timer - Timer.stop(); + HighPrecisionTimer.stop(); // logging Logging.AddServerStopped(); } +void CServer::OnHighPrecisionTimer() +{ + // TEST + OnTimer(); +} + void CServer::OnTimer() { CVector vecChanID; - CVector > vecvecdData ( SYSTEM_BLOCK_SIZE_SAMPLES ); + CVector > vecvecdData ( SYSTEM_BLOCK_FRAME_SAMPLES ); CVector > vecvecdGains; // get data from all connected clients @@ -240,7 +263,7 @@ void CServer::GetBlockAllConC ( CVector& vecChanID, bool bChannelIsNowDisconnected = false; // init temporal data vector and clear input buffers - CVector vecdData ( SYSTEM_BLOCK_SIZE_SAMPLES ); + CVector vecdData ( SYSTEM_BLOCK_FRAME_SAMPLES ); vecChanID.Init ( 0 ); vecvecdData.Init ( 0 ); @@ -668,7 +691,7 @@ CVector CServer::ProcessData ( CVector >& vecvecdData, int i; // init return vector with zeros since we mix all channels on that vector - CVector vecsOutData ( SYSTEM_BLOCK_SIZE_SAMPLES, 0 ); + CVector vecsOutData ( SYSTEM_BLOCK_FRAME_SAMPLES, 0 ); const int iNumClients = vecvecdData.Size(); @@ -678,7 +701,7 @@ CVector CServer::ProcessData ( CVector >& vecvecdData, // if channel gain is 1, avoid multiplication for speed optimization if ( vecdGains[j] == static_cast ( 1.0 ) ) { - for ( i = 0; i < SYSTEM_BLOCK_SIZE_SAMPLES; i++ ) + for ( i = 0; i < SYSTEM_BLOCK_FRAME_SAMPLES; i++ ) { vecsOutData[i] = Double2Short ( vecsOutData[i] + vecvecdData[j][i] ); @@ -686,7 +709,7 @@ CVector CServer::ProcessData ( CVector >& vecvecdData, } else { - for ( i = 0; i < SYSTEM_BLOCK_SIZE_SAMPLES; i++ ) + for ( i = 0; i < SYSTEM_BLOCK_FRAME_SAMPLES; i++ ) { vecsOutData[i] = Double2Short ( vecsOutData[i] + diff --git a/src/server.h b/src/server.h index cff32de3..c586aa6c 100755 --- a/src/server.h +++ b/src/server.h @@ -29,6 +29,7 @@ #include #include #include +#include "celt.h" #include "global.h" #include "socket.h" #include "channel.h" @@ -40,6 +41,18 @@ // no valid channel number #define INVALID_CHANNEL_ID ( MAX_NUM_CHANNELS + 1 ) +// minimum timer precision +#define MIN_TIMER_RESOLUTION_MS 1 // ms + +// add some error checking, the high precision timer implementation only +// supports 128 and 256 samples frame size at 48 kHz sampling rate +#if ( ( SYSTEM_BLOCK_FRAME_SAMPLES != 128 ) && ( SYSTEM_BLOCK_FRAME_SAMPLES != 256 ) ) +# error "Only system frame sizes of 128 and 256 samples are supported by this module" +#endif +#if SYSTEM_SAMPLE_RATE != 48000 +# error "Only a system sample rate of 48 kHz is supported by this module" +#endif + /* Classes ********************************************************************/ class CServer : public QObject @@ -56,7 +69,7 @@ public: void Start(); void Stop(); - bool IsRunning() { return Timer.isActive(); } + bool IsRunning() { return HighPrecisionTimer.isActive(); } bool GetTimingStdDev ( double& dCurTiStdDev ); @@ -100,12 +113,20 @@ protected: CVector& vecdGains ); virtual void customEvent ( QEvent* Event ); + void OnTimer(); /* do not use the vector class since CChannel does not have appropriate copy constructor/operator */ CChannel vecChannels[MAX_NUM_CHANNELS]; QMutex Mutex; + // audio encoder/decoder + CELTMode* CeltMode[MAX_NUM_CHANNELS]; + CELTEncoder* CeltEncoder[MAX_NUM_CHANNELS]; + CELTDecoder* CeltDecoder[MAX_NUM_CHANNELS]; + int iCeltNumCodedBytes[MAX_NUM_CHANNELS]; + CVector vecCeltData[MAX_NUM_CHANNELS]; + CVector vstrChatColors; // HTML file server status @@ -113,7 +134,7 @@ protected: QString strServerHTMLFileListName; QString strServerNameWithPort; - QTimer Timer; + QTimer HighPrecisionTimer; CVector vecsSendData; // actual working objects @@ -125,7 +146,7 @@ protected: CServerLogging Logging; public slots: - void OnTimer(); + void OnHighPrecisionTimer(); void OnSendProtMessage ( int iChID, CVector vecMessage ); // CODE TAG: MAX_NUM_CHANNELS_TAG