some more work for multiple sample rate support
This commit is contained in:
parent
1459271f3d
commit
c7168206d0
5 changed files with 100 additions and 61 deletions
|
@ -1160,7 +1160,9 @@ EPutDataStat CChannel::PutData ( const CVector<uint8_t>& vecbyData,
|
||||||
// on the system sample rate, therefore we use the
|
// on the system sample rate, therefore we use the
|
||||||
// decompressed audio buffer size instead of the network
|
// decompressed audio buffer size instead of the network
|
||||||
// buffer size)
|
// buffer size)
|
||||||
CycleTimeVariance.Init ( iAudioSize, TIME_MOV_AV_RESPONSE );
|
CycleTimeVariance.Init ( iAudioSize,
|
||||||
|
SYSTEM_SAMPLE_RATE, TIME_MOV_AV_RESPONSE );
|
||||||
|
|
||||||
CycleTimeVariance.Reset();
|
CycleTimeVariance.Reset();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
|
@ -303,7 +303,8 @@ void CClient::Init ( const int iSampleRate,
|
||||||
vecdNetwData.Init ( iMonoBlockSizeSam );
|
vecdNetwData.Init ( iMonoBlockSizeSam );
|
||||||
|
|
||||||
// init response time evaluation
|
// init response time evaluation
|
||||||
CycleTimeVariance.Init ( iMonoBlockSizeSam, TIME_MOV_AV_RESPONSE );
|
CycleTimeVariance.Init ( iMonoBlockSizeSam,
|
||||||
|
iClientSampleRate, TIME_MOV_AV_RESPONSE );
|
||||||
|
|
||||||
CycleTimeVariance.Reset();
|
CycleTimeVariance.Reset();
|
||||||
|
|
||||||
|
|
141
src/resample.cpp
141
src/resample.cpp
|
@ -4,13 +4,6 @@
|
||||||
* Author(s):
|
* Author(s):
|
||||||
* Volker Fischer
|
* Volker Fischer
|
||||||
*
|
*
|
||||||
* Description:
|
|
||||||
* Resample routine for arbitrary sample-rate conversions in a low range.
|
|
||||||
* The algorithm is based on a polyphase structure. We upsample the input
|
|
||||||
* signal with a factor INTERP_DECIM_I_D1 and calculate two successive samples
|
|
||||||
* whereby we perform a linear interpolation between these two samples to get
|
|
||||||
* an arbitraty sample grid.
|
|
||||||
*
|
|
||||||
* The polyphase filter is calculated with Matlab, the associated file
|
* The polyphase filter is calculated with Matlab, the associated file
|
||||||
* is ResampleFilter.m.
|
* is ResampleFilter.m.
|
||||||
*
|
*
|
||||||
|
@ -156,65 +149,105 @@ void CStereoAudioResample::Init ( const int iNewMonoInputBlockSize,
|
||||||
// set correct parameters
|
// set correct parameters
|
||||||
if ( iFrom >= iTo ) // downsampling case
|
if ( iFrom >= iTo ) // downsampling case
|
||||||
{
|
{
|
||||||
switch ( iTo )
|
if ( iFrom == SND_CRD_SAMPLE_RATE )
|
||||||
{
|
{
|
||||||
case ( SND_CRD_SAMPLE_RATE / 2 ): // 48 kHz to 24 kHz
|
// sound card resampling
|
||||||
pFiltTaps = fResTaps2;
|
switch ( iTo )
|
||||||
iNumTaps = INTERP_I_2 * NUM_TAPS_PER_PHASE2;
|
{
|
||||||
iI = DECIM_D_2;
|
case ( SND_CRD_SAMPLE_RATE / 2 ): // 48 kHz to 24 kHz
|
||||||
break;
|
pFiltTaps = fResTaps2;
|
||||||
|
iNumTaps = INTERP_I_2 * NUM_TAPS_PER_PHASE2;
|
||||||
|
iI = DECIM_D_2;
|
||||||
|
break;
|
||||||
|
|
||||||
case ( SND_CRD_SAMPLE_RATE * 7 / 12 ): // 48 kHz to 28 kHz
|
case ( SND_CRD_SAMPLE_RATE * 7 / 12 ): // 48 kHz to 28 kHz
|
||||||
pFiltTaps = fResTaps12_7;
|
pFiltTaps = fResTaps12_7;
|
||||||
iNumTaps = INTERP_I_12_7 * NUM_TAPS_PER_PHASE12_7;
|
iNumTaps = INTERP_I_12_7 * NUM_TAPS_PER_PHASE12_7;
|
||||||
iI = DECIM_D_12_7;
|
iI = DECIM_D_12_7;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ( SND_CRD_SAMPLE_RATE * 2 / 3 ): // 48 kHz to 32 kHz
|
case ( SND_CRD_SAMPLE_RATE * 2 / 3 ): // 48 kHz to 32 kHz
|
||||||
pFiltTaps = fResTaps3_2;
|
pFiltTaps = fResTaps3_2;
|
||||||
iNumTaps = INTERP_I_3_2 * NUM_TAPS_PER_PHASE3_2;
|
iNumTaps = INTERP_I_3_2 * NUM_TAPS_PER_PHASE3_2;
|
||||||
iI = DECIM_D_3_2;
|
iI = DECIM_D_3_2;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SND_CRD_SAMPLE_RATE: // 48 kHz to 48 kHz
|
case SND_CRD_SAMPLE_RATE: // 48 kHz to 48 kHz
|
||||||
// no resampling needed
|
// no resampling needed
|
||||||
pFiltTaps = NULL;
|
pFiltTaps = NULL;
|
||||||
iNumTaps = 0;
|
iNumTaps = 0;
|
||||||
iI = 1;
|
iI = 1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
// resample ratio not defined, throw error
|
// resample ratio not defined, throw error
|
||||||
throw 0;
|
throw 0;
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// general sampling rate conversion
|
||||||
|
if ( ( iFrom == 32000 ) && ( iTo == 24000 ) )
|
||||||
|
{
|
||||||
|
// 32 kHz to 24 kHz
|
||||||
|
pFiltTaps = fResTaps4_3;
|
||||||
|
iNumTaps = INTERP_I_4_3 * NUM_TAPS_PER_PHASE4_3;
|
||||||
|
iI = DECIM_D_4_3;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// resample ratio not defined, throw error
|
||||||
|
throw 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else // upsampling case (assumption: iTo == SND_CRD_SAMPLE_RATE)
|
else // upsampling case
|
||||||
{
|
{
|
||||||
switch ( iFrom )
|
if ( iTo == SND_CRD_SAMPLE_RATE )
|
||||||
{
|
{
|
||||||
case ( SND_CRD_SAMPLE_RATE / 2 ): // 24 kHz to 48 kHz
|
// sound card resampling
|
||||||
pFiltTaps = fResTaps2;
|
switch ( iFrom )
|
||||||
iNumTaps = DECIM_D_2 * NUM_TAPS_PER_PHASE2;
|
{
|
||||||
iI = INTERP_I_2;
|
case ( SND_CRD_SAMPLE_RATE / 2 ): // 24 kHz to 48 kHz
|
||||||
break;
|
pFiltTaps = fResTaps2;
|
||||||
|
iNumTaps = DECIM_D_2 * NUM_TAPS_PER_PHASE2;
|
||||||
|
iI = INTERP_I_2;
|
||||||
|
break;
|
||||||
|
|
||||||
case ( SND_CRD_SAMPLE_RATE * 7 / 12 ): // 28 kHz to 48 kHz
|
case ( SND_CRD_SAMPLE_RATE * 7 / 12 ): // 28 kHz to 48 kHz
|
||||||
pFiltTaps = fResTaps12_7;
|
pFiltTaps = fResTaps12_7;
|
||||||
iNumTaps = DECIM_D_12_7 * NUM_TAPS_PER_PHASE12_7;
|
iNumTaps = DECIM_D_12_7 * NUM_TAPS_PER_PHASE12_7;
|
||||||
iI = INTERP_I_12_7;
|
iI = INTERP_I_12_7;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ( SND_CRD_SAMPLE_RATE * 2 / 3 ): // 32 kHz to 48 kHz
|
case ( SND_CRD_SAMPLE_RATE * 2 / 3 ): // 32 kHz to 48 kHz
|
||||||
pFiltTaps = fResTaps3_2;
|
pFiltTaps = fResTaps3_2;
|
||||||
iNumTaps = DECIM_D_3_2 * NUM_TAPS_PER_PHASE3_2;
|
iNumTaps = DECIM_D_3_2 * NUM_TAPS_PER_PHASE3_2;
|
||||||
iI = INTERP_I_3_2;
|
iI = INTERP_I_3_2;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
// resample ratio not defined, throw error
|
// resample ratio not defined, throw error
|
||||||
throw 0;
|
throw 0;
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// general sampling rate conversion
|
||||||
|
if ( ( iFrom == 24000 ) && ( iTo == 32000 ) )
|
||||||
|
{
|
||||||
|
// 24 kHz to 32 kHz
|
||||||
|
pFiltTaps = fResTaps4_3;
|
||||||
|
iNumTaps = DECIM_D_4_3 * NUM_TAPS_PER_PHASE4_3;
|
||||||
|
iI = INTERP_I_4_3;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// resample ratio not defined, throw error
|
||||||
|
throw 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -38,8 +38,8 @@ CServer::CServer ( const QString& strLoggingFileName,
|
||||||
vecsSendData.Init ( MIN_SERVER_BLOCK_SIZE_SAMPLES );
|
vecsSendData.Init ( MIN_SERVER_BLOCK_SIZE_SAMPLES );
|
||||||
|
|
||||||
// init moving average buffer for response time evaluation
|
// init moving average buffer for response time evaluation
|
||||||
CycleTimeVariance.Init (
|
CycleTimeVariance.Init ( MIN_SERVER_BLOCK_SIZE_SAMPLES,
|
||||||
MIN_SERVER_BLOCK_SIZE_SAMPLES, TIME_MOV_AV_RESPONSE );
|
SYSTEM_SAMPLE_RATE, TIME_MOV_AV_RESPONSE );
|
||||||
|
|
||||||
// connect timer timeout signal
|
// connect timer timeout signal
|
||||||
QObject::connect ( &Timer, SIGNAL ( timeout() ),
|
QObject::connect ( &Timer, SIGNAL ( timeout() ),
|
||||||
|
|
|
@ -556,14 +556,16 @@ public:
|
||||||
virtual ~CCycleTimeVariance() {}
|
virtual ~CCycleTimeVariance() {}
|
||||||
|
|
||||||
void Init ( const int iNewBlockLengthAtSystemSampleRate,
|
void Init ( const int iNewBlockLengthAtSystemSampleRate,
|
||||||
|
const int iNewSystemSampleRate,
|
||||||
const int iHistoryLengthTime )
|
const int iHistoryLengthTime )
|
||||||
{
|
{
|
||||||
// store block size
|
// store block size and sample rate
|
||||||
iBlockLengthAtSystemSampleRate = iNewBlockLengthAtSystemSampleRate;
|
iBlockLengthAtSystemSampleRate = iNewBlockLengthAtSystemSampleRate;
|
||||||
|
iSystemSampleRate = iNewSystemSampleRate;
|
||||||
|
|
||||||
// calculate actual moving average length and initialize buffer
|
// calculate actual moving average length and initialize buffer
|
||||||
RespTimeMoAvBuf.Init ( iHistoryLengthTime *
|
RespTimeMoAvBuf.Init ( iHistoryLengthTime *
|
||||||
SYSTEM_SAMPLE_RATE / iNewBlockLengthAtSystemSampleRate );
|
iNewSystemSampleRate / iNewBlockLengthAtSystemSampleRate );
|
||||||
}
|
}
|
||||||
|
|
||||||
int GetBlockLength() { return iBlockLengthAtSystemSampleRate; }
|
int GetBlockLength() { return iBlockLengthAtSystemSampleRate; }
|
||||||
|
@ -582,7 +584,7 @@ public:
|
||||||
// we want to calculate the standard deviation (we assume that the mean
|
// we want to calculate the standard deviation (we assume that the mean
|
||||||
// is correct at the block period time)
|
// is correct at the block period time)
|
||||||
const double dCurAddVal = ( (double) ( CurTime - TimeLastBlock ) -
|
const double dCurAddVal = ( (double) ( CurTime - TimeLastBlock ) -
|
||||||
( iBlockLengthAtSystemSampleRate * 1000 / SYSTEM_SAMPLE_RATE ) );
|
( iBlockLengthAtSystemSampleRate * 1000 / iSystemSampleRate ) );
|
||||||
|
|
||||||
RespTimeMoAvBuf.Add ( dCurAddVal * dCurAddVal ); // add squared value
|
RespTimeMoAvBuf.Add ( dCurAddVal * dCurAddVal ); // add squared value
|
||||||
|
|
||||||
|
@ -601,6 +603,7 @@ protected:
|
||||||
CMovingAv<double> RespTimeMoAvBuf;
|
CMovingAv<double> RespTimeMoAvBuf;
|
||||||
int TimeLastBlock;
|
int TimeLastBlock;
|
||||||
int iBlockLengthAtSystemSampleRate;
|
int iBlockLengthAtSystemSampleRate;
|
||||||
|
int iSystemSampleRate;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* !defined ( UTIL_HOIH934256GEKJH98_3_43445KJIUHF1912__INCLUDED_ ) */
|
#endif /* !defined ( UTIL_HOIH934256GEKJH98_3_43445KJIUHF1912__INCLUDED_ ) */
|
||||||
|
|
Loading…
Reference in a new issue