From 9dd942bec679035dfa39ad1f523ff0296f44e44a Mon Sep 17 00:00:00 2001 From: Volker Fischer Date: Tue, 17 Mar 2009 06:50:00 +0000 Subject: [PATCH] bug fixes for timing variance calculation, new init parameters for CycleTime class, added CycleTime for channel estimating input network stream variance of timing --- src/channel.cpp | 30 +++++++++++++++++++++++++++--- src/channel.h | 4 ++++ src/client.cpp | 18 ++++++++---------- src/global.h | 1 - src/llconclientdlg.cpp | 2 +- src/server.cpp | 3 ++- src/util.h | 19 ++++++++++++++----- 7 files changed, 56 insertions(+), 21 deletions(-) diff --git a/src/channel.cpp b/src/channel.cpp index 3d003e70..f220d062 100755 --- a/src/channel.cpp +++ b/src/channel.cpp @@ -660,9 +660,12 @@ void CChannelSet::WriteHTMLChannelList() /******************************************************************************\ * CChannel * \******************************************************************************/ -CChannel::CChannel ( const bool bNIsServer ) : bIsServer ( bNIsServer ), - sName ( "" ), vecdGains ( USED_NUM_CHANNELS, (double) 1.0 ), - bIsEnabled ( false ), iCurNetwOutBlSiFact ( DEF_NET_BLOCK_SIZE_FACTOR ) +CChannel::CChannel ( const bool bNIsServer ) : + bIsServer ( bNIsServer ), + sName ( "" ), + vecdGains ( USED_NUM_CHANNELS, (double) 1.0 ), + bIsEnabled ( false ), + iCurNetwOutBlSiFact ( DEF_NET_BLOCK_SIZE_FACTOR ) { // query all possible network in buffer sizes for determining if an // audio packet was received (the following code only works if all @@ -1122,6 +1125,24 @@ EPutDataStat CChannel::PutData ( const CVector& vecbyData, { eRet = PS_AUDIO_ERR; } + + // update cycle time variance measurement, take care of + // re-initialization, too, if necessary + if ( iAudioSize != CycleTimeVariance.GetBlockLength() ) + { + // re-init + CycleTimeVariance.Init ( iAudioSize, TIME_MOV_AV_RESPONSE ); + CycleTimeVariance.Reset(); + } + else + { + +// TODO only update if time difference of received packets is below +// a limit to avoid having short network troubles incorporated in the +// statistic + + CycleTimeVariance.Update(); + } } else { @@ -1156,6 +1177,9 @@ EPutDataStat CChannel::PutData ( const CVector& vecbyData, Protocol.CreateReqNetwTranspPropsMes(); } + // reset cycle time variance measurement + CycleTimeVariance.Reset(); + // inform other objects that new connection was established emit NewConnection(); } diff --git a/src/channel.h b/src/channel.h index afa098c4..a261dd78 100755 --- a/src/channel.h +++ b/src/channel.h @@ -115,6 +115,8 @@ public: int GetAudioBlockSizeIn() { return iCurAudioBlockSizeIn; } int GetUploadRateKbps(); + double GetTimingStdDev() { return CycleTimeVariance.GetStdDev(); } + void SetNetwBufSizeFactOut ( const int iNewNetwBlSiFactOut ); int GetNetwBufSizeFactOut() { return iCurNetwOutBlSiFact; } @@ -173,6 +175,8 @@ protected: CNetBuf SockBuf; int iCurSockBufSize; + CCycleTimeVariance CycleTimeVariance; + // network output conversion buffer CConvBuf ConvBuf; diff --git a/src/client.cpp b/src/client.cpp index 5f192b81..bc3a6085 100755 --- a/src/client.cpp +++ b/src/client.cpp @@ -297,8 +297,7 @@ void CClient::Init ( const int iPrefMonoBlockSizeSamIndexAtSndCrdSamRate ) vecdNetwData.Init ( iMonoBlockSizeSam ); // init response time evaluation - CycleTimeVariance.Init ( - TIME_MOV_AV_RESPONSE * SYSTEM_SAMPLE_RATE / iMonoBlockSizeSam ); + CycleTimeVariance.Init ( iMonoBlockSizeSam, TIME_MOV_AV_RESPONSE ); CycleTimeVariance.Reset(); @@ -457,12 +456,6 @@ void CClient::UpdateSocketBufferSize() const double dHysteresis = 0.3; // calculate current buffer setting -// TODO 2* seems not give optimal results, maybe use 3*? -// add .5 to "round up" -> ceil -// divide by MIN_SERVER_BLOCK_DURATION_MS because this is the size of -// one block in the jitter buffer -// add one block for actual network jitter - // Use worst case scenario: We add the block size of input and // output. This is not required if the smaller block size is a // multiple of the bigger size, but in the general case where @@ -472,8 +465,13 @@ void CClient::UpdateSocketBufferSize() ( iMonoBlockSizeSam + Channel.GetAudioBlockSizeIn() ) * 1000 / SYSTEM_SAMPLE_RATE; - const double dEstCurBufSet = 1 + ( dAudioBufferDurationMs + - 2 * ( CycleTimeVariance.GetStdDev() + 0.5 ) ) / + // accumulate the standard deviations of input network stream and + // internal timer, + // add .5 to "round up" -> ceil, + // divide by MIN_SERVER_BLOCK_DURATION_MS because this is the size of + // one block in the jitter buffer + const double dEstCurBufSet = ( dAudioBufferDurationMs + + 2 * ( Channel.GetTimingStdDev() + CycleTimeVariance.GetStdDev() + 0.5 ) ) / MIN_SERVER_BLOCK_DURATION_MS; // upper/lower hysteresis decision diff --git a/src/global.h b/src/global.h index 8f43b2b5..483329a5 100755 --- a/src/global.h +++ b/src/global.h @@ -111,7 +111,6 @@ // length of the moving average buffer for response time measurement #define TIME_MOV_AV_RESPONSE 30 // seconds -#define LEN_MOV_AV_RESPONSE_SERVER ( TIME_MOV_AV_RESPONSE * 1000 / MIN_SERVER_BLOCK_DURATION_MS ) // GUI definition: width/heigth size of LED pixmaps #define LED_WIDTH_HEIGHT_SIZE_PIXEL 20 diff --git a/src/llconclientdlg.cpp b/src/llconclientdlg.cpp index f34f56cd..4324855c 100755 --- a/src/llconclientdlg.cpp +++ b/src/llconclientdlg.cpp @@ -393,7 +393,7 @@ void CLlconClientDlg::UpdateDisplay() } // TEST -//TextLabelStatus->setText ( QString( "Std dev: %1" ).arg ( pClient->GetTimingStdDev() ) ); +//TextLabelStatus->setText ( QString( "Time: %1, Netw: %2" ).arg ( pClient->GetTimingStdDev() ).arg ( pClient->GetChannel()->GetTimingStdDev() ) ); } diff --git a/src/server.cpp b/src/server.cpp index de216ec8..455c0d3f 100755 --- a/src/server.cpp +++ b/src/server.cpp @@ -37,7 +37,8 @@ CServer::CServer ( const QString& strLoggingFileName, vecsSendData.Init ( MIN_SERVER_BLOCK_SIZE_SAMPLES ); // init moving average buffer for response time evaluation - CycleTimeVariance.Init ( LEN_MOV_AV_RESPONSE_SERVER ); + CycleTimeVariance.Init ( + MIN_SERVER_BLOCK_SIZE_SAMPLES, TIME_MOV_AV_RESPONSE ); // connect timer timeout signal QObject::connect ( &Timer, SIGNAL ( timeout() ), diff --git a/src/util.h b/src/util.h index eeaa7a39..cea61ba2 100755 --- a/src/util.h +++ b/src/util.h @@ -610,14 +610,22 @@ protected: class CCycleTimeVariance { public: - CCycleTimeVariance() {} + CCycleTimeVariance() : iBlockLengthAtSystemSampleRate ( 0 ) {} virtual ~CCycleTimeVariance() {} - void Init ( const int iMovingAverageLength ) + void Init ( const int iNewBlockLengthAtSystemSampleRate, + const int iHistoryLengthTime ) { - RespTimeMoAvBuf.Init ( iMovingAverageLength ); + // store block size + iBlockLengthAtSystemSampleRate = iNewBlockLengthAtSystemSampleRate; + + // calculate actual moving average length and initialize buffer + RespTimeMoAvBuf.Init ( iHistoryLengthTime * + SYSTEM_SAMPLE_RATE / iNewBlockLengthAtSystemSampleRate ); } + int GetBlockLength() { return iBlockLengthAtSystemSampleRate; } + void Reset() { TimeLastBlock = PreciseTime.elapsed(); @@ -631,8 +639,8 @@ public: // we want to calculate the standard deviation (we assume that the mean // is correct at the block period time) - const double dCurAddVal = - ( (double) ( CurTime - TimeLastBlock ) - MIN_SERVER_BLOCK_DURATION_MS ); + const double dCurAddVal = ( (double) ( CurTime - TimeLastBlock ) - + ( iBlockLengthAtSystemSampleRate * 1000 / SYSTEM_SAMPLE_RATE ) ); RespTimeMoAvBuf.Add ( dCurAddVal * dCurAddVal ); // add squared value @@ -650,6 +658,7 @@ protected: CPreciseTime PreciseTime; CMovingAv RespTimeMoAvBuf; int TimeLastBlock; + int iBlockLengthAtSystemSampleRate; }; #endif /* !defined ( UTIL_HOIH934256GEKJH98_3_43445KJIUHF1912__INCLUDED_ ) */