test implementation for automatic network buffer size setting
This commit is contained in:
parent
4e94893aa0
commit
d741bc6e30
5 changed files with 133 additions and 31 deletions
112
src/client.cpp
112
src/client.cpp
|
@ -35,7 +35,8 @@ CClient::CClient ( const quint16 iPortNumber ) : bRun ( false ),
|
|||
bReverbOnLeftChan ( false ),
|
||||
iNetwBufSizeFactIn ( DEF_NET_BLOCK_SIZE_FACTOR ),
|
||||
strIPAddress ( "" ), strName ( "" ),
|
||||
bOpenChatOnNewMessage ( true )
|
||||
bOpenChatOnNewMessage ( true ),
|
||||
bDoAutoSockBufSize ( false )
|
||||
{
|
||||
// connection for protocol
|
||||
QObject::connect ( &Channel,
|
||||
|
@ -391,20 +392,9 @@ fflush(pFileDelay);
|
|||
PostWinMessage ( MS_SOUND_OUT, MUL_COL_LED_GREEN );
|
||||
}
|
||||
|
||||
|
||||
// update response time measurement ------------------------------------
|
||||
// add time difference
|
||||
const int CurTime = PreciseTime.elapsed();
|
||||
|
||||
// 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_BLOCK_DURATION_MS );
|
||||
|
||||
RespTimeMoAvBuf.Add ( dCurAddVal * dCurAddVal ); // add squared value
|
||||
|
||||
// store old time value
|
||||
TimeLastBlock = CurTime;
|
||||
// update response time measurement and socket buffer size
|
||||
UpdateTimeResponseMeasurement();
|
||||
UpdateSocketBufferSize();
|
||||
}
|
||||
|
||||
// disable channel
|
||||
|
@ -427,3 +417,95 @@ bool CClient::Stop()
|
|||
// give thread some time to terminate, return status
|
||||
return wait ( 5000 );
|
||||
}
|
||||
|
||||
void CClient::UpdateTimeResponseMeasurement()
|
||||
{
|
||||
// add time difference
|
||||
const int CurTime = PreciseTime.elapsed();
|
||||
|
||||
// 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_BLOCK_DURATION_MS );
|
||||
|
||||
RespTimeMoAvBuf.Add ( dCurAddVal * dCurAddVal ); // add squared value
|
||||
|
||||
// store old time value
|
||||
TimeLastBlock = CurTime;
|
||||
}
|
||||
|
||||
void CClient::UpdateSocketBufferSize()
|
||||
{
|
||||
|
||||
// TEST
|
||||
static double test = 4;
|
||||
|
||||
// just update the socket buffer size if auto setting is enabled, otherwise
|
||||
// do nothing
|
||||
|
||||
|
||||
//if ( bDoAutoSockBufSize )
|
||||
{
|
||||
// we use the time response measurement for the automatic setting
|
||||
// Assumptions:
|
||||
// - the network jitter can be neglected compared to the audio
|
||||
// interface jitter
|
||||
// - the audio interface jitter is assumed to be Gaussian
|
||||
// - the buffer size is set to two times the standard deviation of
|
||||
// the audio interface jitter (~95% of the jitter should be fit in the
|
||||
// buffer)
|
||||
// - introduce a hysteresis to avoid switching the buffer sizes all the
|
||||
// time in case the time response measurement is close to a bound
|
||||
// - only use time response measurement results if averaging buffer is
|
||||
// completely filled
|
||||
const double dHysteresis = 0.3;
|
||||
|
||||
|
||||
|
||||
//if ( RespTimeMoAvBuf.IsInitialized() )
|
||||
{
|
||||
// calculate current buffer setting
|
||||
|
||||
// TODO 2* seems not give optimal results, maybe use 3*?
|
||||
|
||||
//const double dEstCurBufSet = 2 * GetTimingStdDev();
|
||||
|
||||
|
||||
// TEST
|
||||
test = test + 0.01 * (2*LlconMath().round ( (double)rand()/RAND_MAX )-1);
|
||||
if ( test < 0.5 ) test = 0.5;
|
||||
if ( test > 10 ) test = 10;
|
||||
const double dEstCurBufSet = test;
|
||||
|
||||
|
||||
// upper/lower hysteresis decision
|
||||
const int iUpperHystDec = LlconMath().round ( dEstCurBufSet - dHysteresis );
|
||||
const int iLowerHystDec = LlconMath().round ( dEstCurBufSet + dHysteresis );
|
||||
|
||||
// if both decisions are equal than use the result
|
||||
if ( iUpperHystDec == iLowerHystDec )
|
||||
{
|
||||
|
||||
SetSockBufSize ( iUpperHystDec );
|
||||
}
|
||||
else
|
||||
{
|
||||
// we are in the middle of the decision region, use
|
||||
// previous setting for determing the new decision
|
||||
if ( !( ( GetSockBufSize() == iUpperHystDec ) ||
|
||||
( GetSockBufSize() == iLowerHystDec ) ) )
|
||||
{
|
||||
// the old result is not near the new decision,
|
||||
// use per definition the upper decision
|
||||
SetSockBufSize ( iUpperHystDec );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static FILE* pFile = fopen("test.dat", "w");
|
||||
fprintf(pFile, "%e %d\n",test,GetSockBufSize());
|
||||
fflush(pFile);
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
|
18
src/client.h
18
src/client.h
|
@ -92,13 +92,18 @@ public:
|
|||
AudioReverb.Clear();
|
||||
}
|
||||
|
||||
void SetDoAutoSockBufSize ( const bool bValue )
|
||||
{ bDoAutoSockBufSize = bValue; }
|
||||
void SetSockBufSize ( const int iNumBlocks )
|
||||
{
|
||||
// set the new socket size
|
||||
Channel.SetSockBufSize ( iNumBlocks );
|
||||
if ( Channel.GetSockBufSize() != iNumBlocks )
|
||||
{
|
||||
// set the new socket size
|
||||
Channel.SetSockBufSize ( iNumBlocks );
|
||||
|
||||
// tell the server that size has changed
|
||||
Channel.CreateJitBufMes ( iNumBlocks );
|
||||
// tell the server that size has changed
|
||||
Channel.CreateJitBufMes ( iNumBlocks );
|
||||
}
|
||||
}
|
||||
int GetSockBufSize() { return Channel.GetSockBufSize(); }
|
||||
|
||||
|
@ -138,10 +143,13 @@ public:
|
|||
QString strName;
|
||||
|
||||
protected:
|
||||
virtual void run();
|
||||
virtual void run();
|
||||
void UpdateTimeResponseMeasurement();
|
||||
void UpdateSocketBufferSize();
|
||||
|
||||
// only one channel is needed for client application
|
||||
CChannel Channel;
|
||||
bool bDoAutoSockBufSize;
|
||||
|
||||
CSocket Socket;
|
||||
CSound Sound;
|
||||
|
|
|
@ -84,8 +84,7 @@ CClientSettingsDlg::CClientSettingsDlg ( CClient* pNCliP, QWidget* parent,
|
|||
// network buffer
|
||||
SliderNetBuf->setRange ( 0, MAX_NET_BUF_SIZE_NUM_BL );
|
||||
const int iCurNumNetBuf = pClient->GetSockBufSize();
|
||||
SliderNetBuf->setValue ( iCurNumNetBuf );
|
||||
TextNetBuf->setText ( "Size: " + QString().setNum ( iCurNumNetBuf ) );
|
||||
UpdateNetworkBufSlider ( iCurNumNetBuf );
|
||||
|
||||
// network buffer size factor in
|
||||
SliderNetBufSiFactIn->setRange ( 1, MAX_NET_BLOCK_SIZE_FACTOR );
|
||||
|
@ -184,6 +183,12 @@ CClientSettingsDlg::CClientSettingsDlg ( CClient* pNCliP, QWidget* parent,
|
|||
TimerStatus.start ( DISPLAY_UPDATE_TIME );
|
||||
}
|
||||
|
||||
void CClientSettingsDlg::UpdateNetworkBufSlider ( const int iCurNumNetBuf )
|
||||
{
|
||||
SliderNetBuf->setValue ( iCurNumNetBuf );
|
||||
TextNetBuf->setText ( "Size: " + QString().setNum ( iCurNumNetBuf ) );
|
||||
}
|
||||
|
||||
void CClientSettingsDlg::UpdateSndBufInSlider ( const int iCurNumInBuf )
|
||||
{
|
||||
SliderSndBufIn->setValue ( iCurNumInBuf );
|
||||
|
@ -348,8 +353,9 @@ void CClientSettingsDlg::OnPingTimeResult ( int iPingTime )
|
|||
void CClientSettingsDlg::UpdateDisplay()
|
||||
{
|
||||
// update slider controls (settings might have been changed by sound interface)
|
||||
UpdateSndBufInSlider ( pClient->GetSndInterface()->GetInNumBuf() );
|
||||
UpdateSndBufOutSlider ( pClient->GetSndInterface()->GetOutNumBuf() );
|
||||
UpdateSndBufInSlider ( pClient->GetSndInterface()->GetInNumBuf() );
|
||||
UpdateSndBufOutSlider ( pClient->GetSndInterface()->GetOutNumBuf() );
|
||||
UpdateNetworkBufSlider ( pClient->GetSockBufSize() );
|
||||
|
||||
if ( !pClient->IsRunning() )
|
||||
{
|
||||
|
|
|
@ -72,8 +72,9 @@ protected:
|
|||
virtual void showEvent ( QShowEvent* showEvent );
|
||||
virtual void hideEvent ( QHideEvent* hideEvent );
|
||||
|
||||
void UpdateSndBufInSlider ( const int iCurNumInBuf );
|
||||
void UpdateSndBufOutSlider ( const int iCurNumOutBuf );
|
||||
void UpdateSndBufInSlider ( const int iCurNumInBuf );
|
||||
void UpdateSndBufOutSlider ( const int iCurNumOutBuf );
|
||||
void UpdateNetworkBufSlider ( const int iCurNumNetBuf );
|
||||
|
||||
public slots:
|
||||
void OnTimerStatus() { UpdateDisplay(); }
|
||||
|
|
15
src/util.h
15
src/util.h
|
@ -447,15 +447,20 @@ protected:
|
|||
class LlconMath
|
||||
{
|
||||
public:
|
||||
static int NextPowerOfTwo ( const int& iSizeIn )
|
||||
static int NextPowerOfTwo ( const int& x )
|
||||
{
|
||||
// calculate the next power of 2 of the given size
|
||||
int iPowerOfTwo = 1;
|
||||
while ( iPowerOfTwo < iSizeIn )
|
||||
int y = 1;
|
||||
while ( y < x )
|
||||
{
|
||||
iPowerOfTwo <<= 1; // multiply by 2
|
||||
y <<= 1; // multiply by 2
|
||||
}
|
||||
return iPowerOfTwo;
|
||||
return y;
|
||||
}
|
||||
|
||||
static int round ( double x )
|
||||
{
|
||||
return (int) ( ( x - floor ( x ) ) >= 0.5 ) ? ceil(x) : floor(x);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in a new issue