support correct auto jitter buffer settings for 64 and 128 samples frame size
This commit is contained in:
parent
16ecb72ecd
commit
32e8eb7e94
4 changed files with 76 additions and 44 deletions
|
@ -91,7 +91,13 @@ bool CNetBuf::Get ( CVector<uint8_t>& vecbyData,
|
|||
|
||||
/* Network buffer with statistic calculations implementation ******************/
|
||||
CNetBufWithStats::CNetBufWithStats() :
|
||||
CNetBuf ( false ) // base class init: no simulation mode
|
||||
CNetBuf ( false ), // base class init: no simulation mode
|
||||
iMaxStatisticCount ( MAX_STATISTIC_COUNT ),
|
||||
bUseDoubleSystemFrameSize ( false ),
|
||||
dAutoFilt_WightUpNormal ( IIR_WEIGTH_UP_NORMAL ),
|
||||
dAutoFilt_WightDownNormal ( IIR_WEIGTH_DOWN_NORMAL ),
|
||||
dAutoFilt_WightUpFast ( IIR_WEIGTH_UP_FAST ),
|
||||
dAutoFilt_WightDownFast ( IIR_WEIGTH_DOWN_FAST )
|
||||
{
|
||||
// Define the sizes of the simulation buffers,
|
||||
// must be NUM_STAT_SIMULATION_BUFFERS elements!
|
||||
|
@ -143,13 +149,31 @@ void CNetBufWithStats::Init ( const int iNewBlockSize,
|
|||
// inits for statistics calculation
|
||||
if ( !bPreserve )
|
||||
{
|
||||
// set the auto filter weights and max statistic count
|
||||
if ( bUseDoubleSystemFrameSize )
|
||||
{
|
||||
dAutoFilt_WightUpNormal = IIR_WEIGTH_UP_NORMAL_DOUBLE_FRAME_SIZE;
|
||||
dAutoFilt_WightDownNormal = IIR_WEIGTH_DOWN_NORMAL_DOUBLE_FRAME_SIZE;
|
||||
dAutoFilt_WightUpFast = IIR_WEIGTH_UP_FAST_DOUBLE_FRAME_SIZE;
|
||||
dAutoFilt_WightDownFast = IIR_WEIGTH_DOWN_FAST_DOUBLE_FRAME_SIZE;
|
||||
iMaxStatisticCount = MAX_STATISTIC_COUNT_DOUBLE_FRAME_SIZE;
|
||||
}
|
||||
else
|
||||
{
|
||||
dAutoFilt_WightUpNormal = IIR_WEIGTH_UP_NORMAL;
|
||||
dAutoFilt_WightDownNormal = IIR_WEIGTH_DOWN_NORMAL;
|
||||
dAutoFilt_WightUpFast = IIR_WEIGTH_UP_FAST;
|
||||
dAutoFilt_WightDownFast = IIR_WEIGTH_DOWN_FAST;
|
||||
iMaxStatisticCount = MAX_STATISTIC_COUNT;
|
||||
}
|
||||
|
||||
for ( int i = 0; i < NUM_STAT_SIMULATION_BUFFERS; i++ )
|
||||
{
|
||||
// init simulation buffers with the correct size
|
||||
SimulationBuffer[i].Init ( iNewBlockSize, viBufSizesForSim[i] );
|
||||
|
||||
// init statistics
|
||||
ErrorRateStatistic[i].Init ( MAX_STATISTIC_COUNT, true );
|
||||
ErrorRateStatistic[i].Init ( iMaxStatisticCount, true );
|
||||
}
|
||||
|
||||
// reset the initialization counter which controls the initialization
|
||||
|
@ -170,7 +194,7 @@ void CNetBufWithStats::ResetInitCounter()
|
|||
// of the error rate statistic buffers which should be ok for a good
|
||||
// initialization value (initialization phase should be as short as
|
||||
// possible)
|
||||
iInitCounter = MAX_STATISTIC_COUNT / 4;
|
||||
iInitCounter = iMaxStatisticCount / 4;
|
||||
}
|
||||
|
||||
bool CNetBufWithStats::Put ( const CVector<uint8_t>& vecbyData,
|
||||
|
@ -276,8 +300,7 @@ void CNetBufWithStats::UpdateAutoSetting()
|
|||
// the current jitter buffer size significantly.
|
||||
// For the initialization phase, use lower weight values to get faster
|
||||
// adaptation.
|
||||
double dWeightUp = IIR_WEIGTH_UP_NORMAL;
|
||||
double dWeightDown = IIR_WEIGTH_DOWN_NORMAL;
|
||||
double dWeightUp, dWeightDown;
|
||||
const double dHysteresisValue = FILTER_DECISION_HYSTERESIS;
|
||||
bool bUseFastAdaptation = false;
|
||||
|
||||
|
@ -301,9 +324,13 @@ void CNetBufWithStats::UpdateAutoSetting()
|
|||
|
||||
if ( bUseFastAdaptation )
|
||||
{
|
||||
// overwrite weigth values with lower values
|
||||
dWeightUp = IIR_WEIGTH_UP_FAST;
|
||||
dWeightDown = IIR_WEIGTH_DOWN_FAST;
|
||||
dWeightUp = dAutoFilt_WightUpFast;
|
||||
dWeightDown = dAutoFilt_WightDownFast;
|
||||
}
|
||||
else
|
||||
{
|
||||
dWeightUp = dAutoFilt_WightUpNormal;
|
||||
dWeightDown = dAutoFilt_WightDownNormal;
|
||||
}
|
||||
|
||||
// apply non-linear IIR filter
|
||||
|
@ -338,7 +365,7 @@ else
|
|||
// Initialization phase check and correction -------------------------------
|
||||
// sometimes in the very first period after a connection we get a bad error
|
||||
// rate result -> delete this from the initialization phase
|
||||
if ( iInitCounter == MAX_STATISTIC_COUNT / 8 )
|
||||
if ( iInitCounter == iMaxStatisticCount / 8 )
|
||||
{
|
||||
// check error rate of the largest buffer as the indicator
|
||||
if ( ErrorRateStatistic[NUM_STAT_SIMULATION_BUFFERS - 1].
|
||||
|
|
59
src/buffer.h
59
src/buffer.h
|
@ -31,43 +31,41 @@
|
|||
/* Definitions ****************************************************************/
|
||||
// number of simulation network jitter buffers for evaluating the statistic
|
||||
// NOTE If you want to change this number, the code has to modified, too!
|
||||
#define NUM_STAT_SIMULATION_BUFFERS 10
|
||||
#define NUM_STAT_SIMULATION_BUFFERS 10
|
||||
|
||||
// hysteresis for buffer size decision to avoid fast changes if close to the bound
|
||||
#define FILTER_DECISION_HYSTERESIS 0.1
|
||||
#define FILTER_DECISION_HYSTERESIS 0.1
|
||||
|
||||
// definition of the upper error bound of the jitter buffers
|
||||
#define ERROR_RATE_BOUND 0.001
|
||||
#define ERROR_RATE_BOUND 0.001
|
||||
|
||||
// definition of the upper jitter buffer error bound, if that one is reached we
|
||||
// have to speed up the filtering to quickly get out of a incorrect buffer
|
||||
// size state
|
||||
#define UP_MAX_ERROR_BOUND 0.01
|
||||
#define UP_MAX_ERROR_BOUND 0.01
|
||||
|
||||
#if ( SYSTEM_FRAME_SIZE_SAMPLES == 64 )
|
||||
// each regular buffer access lead to a count for put and get, assuming 2.66 ms
|
||||
// blocks we have 15 s / 2.66 ms * 2 = approx. 11000
|
||||
#define MAX_STATISTIC_COUNT_DOUBLE_FRAME_SIZE 11000
|
||||
|
||||
// Note that the following definitions of the weigh constants assume a block
|
||||
// size of 128 samples at a sampling rate of 48 kHz.
|
||||
#define IIR_WEIGTH_UP_NORMAL_DOUBLE_FRAME_SIZE 0.999995
|
||||
#define IIR_WEIGTH_DOWN_NORMAL_DOUBLE_FRAME_SIZE 0.9999
|
||||
#define IIR_WEIGTH_UP_FAST_DOUBLE_FRAME_SIZE 0.9995
|
||||
#define IIR_WEIGTH_DOWN_FAST_DOUBLE_FRAME_SIZE 0.999
|
||||
|
||||
// each regular buffer access lead to a count for put and get, assuming 1.33 ms
|
||||
// blocks we have 15 s / 1.33 ms * 2 = approx. 22500
|
||||
# define MAX_STATISTIC_COUNT 22500
|
||||
#define MAX_STATISTIC_COUNT 22500
|
||||
|
||||
// convert numbers from 128 samples case using http://www.tsdconseil.fr/tutos/tuto-iir1-en.pdf
|
||||
// and https://octave-online.net:
|
||||
// gamma = exp(-Ts/tau), after some calculations we get: x=0.999995;exp(64/128*log(x))
|
||||
# define IIR_WEIGTH_UP_NORMAL 0.9999975
|
||||
# define IIR_WEIGTH_DOWN_NORMAL 0.99994999875
|
||||
# define IIR_WEIGTH_UP_FAST 0.9997499687422
|
||||
# define IIR_WEIGTH_DOWN_FAST 0.999499875
|
||||
#else
|
||||
// each regular buffer access lead to a count for put and get, assuming 2.66 ms
|
||||
// blocks we have 15 s / 2.66 ms * 2 = approx. 11000
|
||||
# define MAX_STATISTIC_COUNT 11000
|
||||
|
||||
// Note that the following definitions of the weigh constants assume a block
|
||||
// size of 128 samples at a sampling rate of 48 kHz.
|
||||
# define IIR_WEIGTH_UP_NORMAL 0.999995
|
||||
# define IIR_WEIGTH_DOWN_NORMAL 0.9999
|
||||
# define IIR_WEIGTH_UP_FAST 0.9995
|
||||
# define IIR_WEIGTH_DOWN_FAST 0.999
|
||||
#endif
|
||||
#define IIR_WEIGTH_UP_NORMAL 0.9999975
|
||||
#define IIR_WEIGTH_DOWN_NORMAL 0.99994999875
|
||||
#define IIR_WEIGTH_UP_FAST 0.9997499687422
|
||||
#define IIR_WEIGTH_DOWN_FAST 0.999499875
|
||||
|
||||
|
||||
/* Classes ********************************************************************/
|
||||
|
@ -90,7 +88,6 @@ public:
|
|||
{
|
||||
// copy old data in new vector using get pointer as zero per
|
||||
// definition
|
||||
|
||||
int iCurPos;
|
||||
|
||||
// copy current data in temporary vector
|
||||
|
@ -158,8 +155,7 @@ public:
|
|||
// perform copying of second part
|
||||
for ( iCurPos = 0; iCurPos < iRemainingCopyLen; iCurPos++ )
|
||||
{
|
||||
vecMemory[iCurPos + iFirstPartLen] =
|
||||
vecTempMemory[iCurPos];
|
||||
vecMemory[iCurPos + iFirstPartLen] = vecTempMemory[iCurPos];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -428,10 +424,12 @@ class CNetBufWithStats : public CNetBuf
|
|||
public:
|
||||
CNetBufWithStats();
|
||||
|
||||
void Init ( const int iNewBlockSize,
|
||||
const int iNewNumBlocks,
|
||||
void Init ( const int iNewBlockSize,
|
||||
const int iNewNumBlocks,
|
||||
const bool bPreserve = false );
|
||||
|
||||
void SetUseDoubleSystemFrameSize ( const bool bNDSFSize ) { bUseDoubleSystemFrameSize = bNDSFSize; }
|
||||
|
||||
virtual bool Put ( const CVector<uint8_t>& vecbyData, const int iInSize );
|
||||
virtual bool Get ( CVector<uint8_t>& vecbyData, const int iOutSize );
|
||||
|
||||
|
@ -454,6 +452,13 @@ protected:
|
|||
int iCurDecidedResult;
|
||||
int iInitCounter;
|
||||
int iCurAutoBufferSizeSetting;
|
||||
int iMaxStatisticCount;
|
||||
|
||||
bool bUseDoubleSystemFrameSize;
|
||||
double dAutoFilt_WightUpNormal;
|
||||
double dAutoFilt_WightDownNormal;
|
||||
double dAutoFilt_WightUpFast;
|
||||
double dAutoFilt_WightDownFast;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -140,14 +140,13 @@ void CChannel::SetEnable ( const bool bNEnStat )
|
|||
}
|
||||
|
||||
void CChannel::SetAudioStreamProperties ( const EAudComprType eNewAudComprType,
|
||||
const int iNewNetwFrameSize,
|
||||
const int iNewNetwFrameSizeFact,
|
||||
const int iNewNumAudioChannels )
|
||||
const int iNewNetwFrameSize,
|
||||
const int iNewNetwFrameSizeFact,
|
||||
const int iNewNumAudioChannels )
|
||||
{
|
||||
/*
|
||||
this function is intended for the client (not the server)
|
||||
*/
|
||||
|
||||
CNetworkTransportProps NetworkTransportProps;
|
||||
|
||||
Mutex.lock();
|
||||
|
@ -161,6 +160,7 @@ void CChannel::SetAudioStreamProperties ( const EAudComprType eNewAudComprType,
|
|||
MutexSocketBuf.lock();
|
||||
{
|
||||
// init socket buffer
|
||||
SockBuf.SetUseDoubleSystemFrameSize ( eAudioCompressionType == CT_OPUS ); // NOTE must be set BEFORE the init()
|
||||
SockBuf.Init ( iNetwFrameSize, iCurSockBufNumFrames );
|
||||
}
|
||||
MutexSocketBuf.unlock();
|
||||
|
@ -173,8 +173,7 @@ void CChannel::SetAudioStreamProperties ( const EAudComprType eNewAudComprType,
|
|||
MutexConvBuf.unlock();
|
||||
|
||||
// fill network transport properties struct
|
||||
NetworkTransportProps =
|
||||
GetNetworkTransportPropsFromCurrentSettings();
|
||||
NetworkTransportProps = GetNetworkTransportPropsFromCurrentSettings();
|
||||
}
|
||||
Mutex.unlock();
|
||||
|
||||
|
@ -369,7 +368,8 @@ void CChannel::OnNetTranspPropsReceived ( CNetworkTransportProps NetworkTranspor
|
|||
MutexSocketBuf.lock();
|
||||
{
|
||||
// update socket buffer (the network block size is a multiple of the
|
||||
// minimum network frame size
|
||||
// minimum network frame size)
|
||||
SockBuf.SetUseDoubleSystemFrameSize ( eAudioCompressionType == CT_OPUS ); // NOTE must be set BEFORE the init()
|
||||
SockBuf.Init ( iNetwFrameSize, iCurSockBufNumFrames );
|
||||
}
|
||||
MutexSocketBuf.unlock();
|
||||
|
|
|
@ -730,7 +730,7 @@
|
|||
<tabstop>cbxAudioQuality</tabstop>
|
||||
<tabstop>edtNewClientLevel</tabstop>
|
||||
<tabstop>chbGUIDesignFancy</tabstop>
|
||||
<tabstop>chbDisplayChannelFaders</tabstop>
|
||||
<tabstop>chbDisplayChannelLevels</tabstop>
|
||||
<tabstop>chbDefaultCentralServer</tabstop>
|
||||
<tabstop>edtCentralServerAddress</tabstop>
|
||||
</tabstops>
|
||||
|
|
Loading…
Reference in a new issue