fixes for the client audio standard deviation measurement, added code for asio interface for using power of two size blocks (not enabled right now)
This commit is contained in:
parent
c206f84308
commit
e42c3afb81
6 changed files with 77 additions and 82 deletions
|
@ -200,7 +200,7 @@ void CClient::Init()
|
|||
RespTimeMoAvBuf.Init ( LEN_MOV_AV_RESPONSE );
|
||||
|
||||
// init time for response time evaluation
|
||||
TimeLastBlock = QTime::currentTime();
|
||||
TimeLastBlock = PreciseTime.elapsed();
|
||||
|
||||
AudioReverb.Clear();
|
||||
}
|
||||
|
@ -338,56 +338,8 @@ void CClient::run()
|
|||
PostWinMessage ( MS_JIT_BUF_GET, MUL_COL_LED_RED );
|
||||
}
|
||||
|
||||
#ifdef _DEBUG_
|
||||
#if 0
|
||||
#if 0
|
||||
/* Determine network delay. We can do this very simple if only this client is
|
||||
connected to the server. In this case, exactly the same audio material is
|
||||
coming back and we can simply compare the samples */
|
||||
/* store send data instatic buffer (may delay is 100 ms) */
|
||||
const int iMaxDelaySamples = (int) ((float) 0.3 /*0.1*/ * SYSTEM_SAMPLE_RATE);
|
||||
static CVector<short> vecsOutBuf(iMaxDelaySamples);
|
||||
|
||||
/* update buffer */
|
||||
const int iBufDiff = iMaxDelaySamples - iBlockSizeSam;
|
||||
for (i = 0; i < iBufDiff; i++)
|
||||
vecsOutBuf[i + iBlockSizeSam] = vecsOutBuf[i];
|
||||
for (i = 0; i < iBlockSizeSam; i++)
|
||||
vecsOutBuf[i] = vecsNetwork[i];
|
||||
|
||||
/* now search for equal samples */
|
||||
int iDelaySamples = 0;
|
||||
for (i = 0; i < iMaxDelaySamples - 1; i++)
|
||||
{
|
||||
/* compare two successive samples */
|
||||
if ((vecsOutBuf[i] == (short) vecdNetwData[0]) &&
|
||||
(vecsOutBuf[i + 1] == (short) vecdNetwData[1]))
|
||||
{
|
||||
iDelaySamples = i;
|
||||
}
|
||||
}
|
||||
|
||||
static FILE* pFileDelay = fopen("delay.dat", "w");
|
||||
fprintf(pFileDelay, "%d\n", iDelaySamples);
|
||||
fflush(pFileDelay);
|
||||
#else
|
||||
/* just store both, input and output, streams */
|
||||
// fid=fopen('v.dat','r');x=fread(fid,'int16');fclose(fid);
|
||||
static FILE* pFileDelay = fopen("v.dat", "wb");
|
||||
short sData[2];
|
||||
for (i = 0; i < iBlockSizeSam; i++)
|
||||
{
|
||||
sData[0] = vecsNetwork[i];
|
||||
sData[1] = (short) vecdNetwData[i];
|
||||
fwrite(&sData, size_t(2), size_t(2), pFileDelay);
|
||||
}
|
||||
fflush(pFileDelay);
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
// TEST
|
||||
// fid=fopen('v.dat','r');x=fread(fid,'int16');fclose(fid);
|
||||
static FILE* pFileDelay = fopen("v.dat", "wb");
|
||||
short sData[2];
|
||||
|
@ -399,7 +351,6 @@ for (i = 0; i < iBlockSizeSam; i++)
|
|||
fflush(pFileDelay);
|
||||
*/
|
||||
|
||||
|
||||
// check if channel is connected
|
||||
if ( Channel.IsConnected() )
|
||||
{
|
||||
|
@ -443,12 +394,12 @@ fflush(pFileDelay);
|
|||
|
||||
// update response time measurement ------------------------------------
|
||||
// add time difference
|
||||
const QTime CurTime = QTime::currentTime();
|
||||
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) TimeLastBlock.msecsTo ( CurTime ) - MIN_BLOCK_DURATION_MS );
|
||||
( (double) ( CurTime - TimeLastBlock ) - MIN_BLOCK_DURATION_MS );
|
||||
|
||||
RespTimeMoAvBuf.Add ( dCurAddVal * dCurAddVal ); // add squared value
|
||||
|
||||
|
|
|
@ -178,12 +178,12 @@ protected:
|
|||
CAudioResample ResampleObjUpL; // left channel
|
||||
CAudioResample ResampleObjUpR; // right channel
|
||||
|
||||
// for ping measurement
|
||||
// for ping measurement and standard deviation of audio interface
|
||||
CPreciseTime PreciseTime;
|
||||
|
||||
// debugging, evaluating
|
||||
CMovingAv<double> RespTimeMoAvBuf;
|
||||
QTime TimeLastBlock;
|
||||
int TimeLastBlock;
|
||||
|
||||
public slots:
|
||||
void OnSendProtMessage ( CVector<uint8_t> vecMessage );
|
||||
|
|
|
@ -357,6 +357,11 @@ void CLlconClientDlg::UpdateDisplay()
|
|||
{
|
||||
TextLabelStatus->setText ( tr ( "disconnected" ) );
|
||||
}
|
||||
|
||||
// TEST
|
||||
//TextLabelStatus->setText ( QString( "Std dev: %1" ).arg ( pClient->GetTimingStdDev() ) );
|
||||
|
||||
|
||||
}
|
||||
|
||||
void CLlconClientDlg::customEvent ( QEvent* Event )
|
||||
|
|
|
@ -107,6 +107,7 @@ void CServer::Start()
|
|||
|
||||
// init time for response time evaluation
|
||||
TimeLastBlock = QTime::currentTime();
|
||||
RespTimeMoAvBuf.Reset();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -158,9 +159,19 @@ void CServer::OnTimer()
|
|||
ChannelSet.PrepSendPacket ( vecChanID[i], vecsSendData ),
|
||||
ChannelSet.GetAddress ( vecChanID[i] ) );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Disable server if no clients are connected. In this case the server
|
||||
// does not consume any significant CPU when no client is connected.
|
||||
#ifndef _WIN32
|
||||
// event handling of custom events seems not to work under Windows in this
|
||||
// class, do not use automatic start/stop of server in Windows version
|
||||
Stop();
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
// update response time measurement ------------------------------------
|
||||
// update response time measurement ----------------------------------------
|
||||
// add time difference
|
||||
const QTime CurTime = QTime::currentTime();
|
||||
|
||||
|
@ -174,17 +185,6 @@ void CServer::OnTimer()
|
|||
// store old time value
|
||||
TimeLastBlock = CurTime;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Disable server if no clients are connected. In this case the server
|
||||
// does not consume any significant CPU when no client is connected.
|
||||
#ifndef _WIN32
|
||||
// event handling of custom events seems not to work under Windows in this
|
||||
// class, do not use automatic start/stop of server in Windows version
|
||||
Stop();
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
CVector<short> CServer::ProcessData ( CVector<CVector<double> >& vecvecdData,
|
||||
CVector<double>& vecdGains )
|
||||
|
|
26
src/util.h
26
src/util.h
|
@ -269,6 +269,7 @@ public:
|
|||
|
||||
virtual void Init ( const int iNewSize );
|
||||
void InitVec ( const int iNewSize, const int iNewVecSize );
|
||||
void Reset();
|
||||
|
||||
protected:
|
||||
int iCurIdx;
|
||||
|
@ -284,6 +285,14 @@ template<class TData> void CMovingAv<TData>::Init ( const int iNewSize )
|
|||
CVector<TData>::Init ( iNewSize );
|
||||
}
|
||||
|
||||
template<class TData> void CMovingAv<TData>::Reset()
|
||||
{
|
||||
iNorm = 0;
|
||||
iCurIdx = 0;
|
||||
tCurAvResult = TData ( 0 ); // only for scalars!
|
||||
CVector<TData>::Reset ( TData ( 0 ) );
|
||||
}
|
||||
|
||||
template<class TData> void CMovingAv<TData>::Add ( const TData tNewD )
|
||||
{
|
||||
/*
|
||||
|
@ -433,6 +442,23 @@ protected:
|
|||
};
|
||||
|
||||
|
||||
// Mathematics utilities -------------------------------------------------------
|
||||
class LlconMath
|
||||
{
|
||||
public:
|
||||
static int NextPowerOfTwo ( const int& iSizeIn )
|
||||
{
|
||||
// calculate the next power of 2 of the given size
|
||||
int iPowerOfTwo = 1;
|
||||
while ( iPowerOfTwo < iSizeIn )
|
||||
{
|
||||
iPowerOfTwo <<= 1; // multiply by 2
|
||||
}
|
||||
return iPowerOfTwo;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// Precise time ----------------------------------------------------------------
|
||||
// needed for ping measurement
|
||||
class CPreciseTime
|
||||
|
|
|
@ -407,6 +407,7 @@ bool CSound::LoadAndInitializeFirstValidDriver()
|
|||
std::string CSound::PrepareDriver()
|
||||
{
|
||||
int i;
|
||||
int iDesiredBufferSizeMono;
|
||||
|
||||
// check the number of available channels
|
||||
long lNumInChan;
|
||||
|
@ -442,15 +443,31 @@ std::string CSound::PrepareDriver()
|
|||
&HWBufferInfo.lPreferredSize,
|
||||
&HWBufferInfo.lGranularity );
|
||||
|
||||
// calculate the desired mono buffer size
|
||||
|
||||
// TEST -> put this in the GUI and implement the code for the Linux driver, too
|
||||
// setting this variable to false sets the previous behaviour
|
||||
const bool bPreferPowerOfTwoAudioBufferSize = false;
|
||||
|
||||
if ( bPreferPowerOfTwoAudioBufferSize )
|
||||
{
|
||||
// use next power of 2 for desired block size mono
|
||||
iDesiredBufferSizeMono = LlconMath().NextPowerOfTwo ( iBufferSizeMono );
|
||||
}
|
||||
else
|
||||
{
|
||||
iDesiredBufferSizeMono = iBufferSizeMono;
|
||||
}
|
||||
|
||||
// calculate "nearest" buffer size and set internal parameter accordingly
|
||||
// first check minimum and maximum values
|
||||
if ( iBufferSizeMono < HWBufferInfo.lMinSize )
|
||||
if ( iDesiredBufferSizeMono < HWBufferInfo.lMinSize )
|
||||
{
|
||||
iASIOBufferSizeMono = HWBufferInfo.lMinSize;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( iBufferSizeMono > HWBufferInfo.lMaxSize )
|
||||
if ( iDesiredBufferSizeMono > HWBufferInfo.lMaxSize )
|
||||
{
|
||||
iASIOBufferSizeMono = HWBufferInfo.lMaxSize;
|
||||
}
|
||||
|
@ -464,18 +481,14 @@ std::string CSound::PrepareDriver()
|
|||
// test loop
|
||||
while ( ( iTrialBufSize <= HWBufferInfo.lMaxSize ) && ( !bSizeFound ) )
|
||||
{
|
||||
if ( iTrialBufSize >= iBufferSizeMono )
|
||||
if ( iTrialBufSize >= iDesiredBufferSizeMono )
|
||||
{
|
||||
// test which buffer size fits better: the old one or the
|
||||
// current one
|
||||
if ( ( iTrialBufSize - iBufferSizeMono ) <
|
||||
( iBufferSizeMono - iLastTrialBufSize ) )
|
||||
if ( ( iTrialBufSize - iDesiredBufferSizeMono ) >
|
||||
( iDesiredBufferSizeMono - iLastTrialBufSize ) )
|
||||
{
|
||||
iBufferSizeMono = iTrialBufSize;
|
||||
}
|
||||
else
|
||||
{
|
||||
iBufferSizeMono = iLastTrialBufSize;
|
||||
iTrialBufSize = iLastTrialBufSize;
|
||||
}
|
||||
|
||||
// exit while loop
|
||||
|
|
Loading…
Reference in a new issue