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
|
||||
// decompressed audio buffer size instead of the network
|
||||
// buffer size)
|
||||
CycleTimeVariance.Init ( iAudioSize, TIME_MOV_AV_RESPONSE );
|
||||
CycleTimeVariance.Init ( iAudioSize,
|
||||
SYSTEM_SAMPLE_RATE, TIME_MOV_AV_RESPONSE );
|
||||
|
||||
CycleTimeVariance.Reset();
|
||||
}
|
||||
else
|
||||
|
|
|
@ -303,7 +303,8 @@ void CClient::Init ( const int iSampleRate,
|
|||
vecdNetwData.Init ( iMonoBlockSizeSam );
|
||||
|
||||
// init response time evaluation
|
||||
CycleTimeVariance.Init ( iMonoBlockSizeSam, TIME_MOV_AV_RESPONSE );
|
||||
CycleTimeVariance.Init ( iMonoBlockSizeSam,
|
||||
iClientSampleRate, TIME_MOV_AV_RESPONSE );
|
||||
|
||||
CycleTimeVariance.Reset();
|
||||
|
||||
|
|
141
src/resample.cpp
141
src/resample.cpp
|
@ -4,13 +4,6 @@
|
|||
* Author(s):
|
||||
* 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
|
||||
* is ResampleFilter.m.
|
||||
*
|
||||
|
@ -156,65 +149,105 @@ void CStereoAudioResample::Init ( const int iNewMonoInputBlockSize,
|
|||
// set correct parameters
|
||||
if ( iFrom >= iTo ) // downsampling case
|
||||
{
|
||||
switch ( iTo )
|
||||
if ( iFrom == SND_CRD_SAMPLE_RATE )
|
||||
{
|
||||
case ( SND_CRD_SAMPLE_RATE / 2 ): // 48 kHz to 24 kHz
|
||||
pFiltTaps = fResTaps2;
|
||||
iNumTaps = INTERP_I_2 * NUM_TAPS_PER_PHASE2;
|
||||
iI = DECIM_D_2;
|
||||
break;
|
||||
// sound card resampling
|
||||
switch ( iTo )
|
||||
{
|
||||
case ( SND_CRD_SAMPLE_RATE / 2 ): // 48 kHz to 24 kHz
|
||||
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
|
||||
pFiltTaps = fResTaps12_7;
|
||||
iNumTaps = INTERP_I_12_7 * NUM_TAPS_PER_PHASE12_7;
|
||||
iI = DECIM_D_12_7;
|
||||
break;
|
||||
case ( SND_CRD_SAMPLE_RATE * 7 / 12 ): // 48 kHz to 28 kHz
|
||||
pFiltTaps = fResTaps12_7;
|
||||
iNumTaps = INTERP_I_12_7 * NUM_TAPS_PER_PHASE12_7;
|
||||
iI = DECIM_D_12_7;
|
||||
break;
|
||||
|
||||
case ( SND_CRD_SAMPLE_RATE * 2 / 3 ): // 48 kHz to 32 kHz
|
||||
pFiltTaps = fResTaps3_2;
|
||||
iNumTaps = INTERP_I_3_2 * NUM_TAPS_PER_PHASE3_2;
|
||||
iI = DECIM_D_3_2;
|
||||
break;
|
||||
case ( SND_CRD_SAMPLE_RATE * 2 / 3 ): // 48 kHz to 32 kHz
|
||||
pFiltTaps = fResTaps3_2;
|
||||
iNumTaps = INTERP_I_3_2 * NUM_TAPS_PER_PHASE3_2;
|
||||
iI = DECIM_D_3_2;
|
||||
break;
|
||||
|
||||
case SND_CRD_SAMPLE_RATE: // 48 kHz to 48 kHz
|
||||
// no resampling needed
|
||||
pFiltTaps = NULL;
|
||||
iNumTaps = 0;
|
||||
iI = 1;
|
||||
break;
|
||||
case SND_CRD_SAMPLE_RATE: // 48 kHz to 48 kHz
|
||||
// no resampling needed
|
||||
pFiltTaps = NULL;
|
||||
iNumTaps = 0;
|
||||
iI = 1;
|
||||
break;
|
||||
|
||||
default:
|
||||
// resample ratio not defined, throw error
|
||||
throw 0;
|
||||
break;
|
||||
default:
|
||||
// resample ratio not defined, throw error
|
||||
throw 0;
|
||||
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
|
||||
pFiltTaps = fResTaps2;
|
||||
iNumTaps = DECIM_D_2 * NUM_TAPS_PER_PHASE2;
|
||||
iI = INTERP_I_2;
|
||||
break;
|
||||
// sound card resampling
|
||||
switch ( iFrom )
|
||||
{
|
||||
case ( SND_CRD_SAMPLE_RATE / 2 ): // 24 kHz to 48 kHz
|
||||
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
|
||||
pFiltTaps = fResTaps12_7;
|
||||
iNumTaps = DECIM_D_12_7 * NUM_TAPS_PER_PHASE12_7;
|
||||
iI = INTERP_I_12_7;
|
||||
break;
|
||||
case ( SND_CRD_SAMPLE_RATE * 7 / 12 ): // 28 kHz to 48 kHz
|
||||
pFiltTaps = fResTaps12_7;
|
||||
iNumTaps = DECIM_D_12_7 * NUM_TAPS_PER_PHASE12_7;
|
||||
iI = INTERP_I_12_7;
|
||||
break;
|
||||
|
||||
case ( SND_CRD_SAMPLE_RATE * 2 / 3 ): // 32 kHz to 48 kHz
|
||||
pFiltTaps = fResTaps3_2;
|
||||
iNumTaps = DECIM_D_3_2 * NUM_TAPS_PER_PHASE3_2;
|
||||
iI = INTERP_I_3_2;
|
||||
break;
|
||||
case ( SND_CRD_SAMPLE_RATE * 2 / 3 ): // 32 kHz to 48 kHz
|
||||
pFiltTaps = fResTaps3_2;
|
||||
iNumTaps = DECIM_D_3_2 * NUM_TAPS_PER_PHASE3_2;
|
||||
iI = INTERP_I_3_2;
|
||||
break;
|
||||
|
||||
default:
|
||||
// resample ratio not defined, throw error
|
||||
throw 0;
|
||||
break;
|
||||
default:
|
||||
// resample ratio not defined, throw error
|
||||
throw 0;
|
||||
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 );
|
||||
|
||||
// init moving average buffer for response time evaluation
|
||||
CycleTimeVariance.Init (
|
||||
MIN_SERVER_BLOCK_SIZE_SAMPLES, TIME_MOV_AV_RESPONSE );
|
||||
CycleTimeVariance.Init ( MIN_SERVER_BLOCK_SIZE_SAMPLES,
|
||||
SYSTEM_SAMPLE_RATE, TIME_MOV_AV_RESPONSE );
|
||||
|
||||
// connect timer timeout signal
|
||||
QObject::connect ( &Timer, SIGNAL ( timeout() ),
|
||||
|
|
|
@ -556,14 +556,16 @@ public:
|
|||
virtual ~CCycleTimeVariance() {}
|
||||
|
||||
void Init ( const int iNewBlockLengthAtSystemSampleRate,
|
||||
const int iNewSystemSampleRate,
|
||||
const int iHistoryLengthTime )
|
||||
{
|
||||
// store block size
|
||||
// store block size and sample rate
|
||||
iBlockLengthAtSystemSampleRate = iNewBlockLengthAtSystemSampleRate;
|
||||
iSystemSampleRate = iNewSystemSampleRate;
|
||||
|
||||
// calculate actual moving average length and initialize buffer
|
||||
RespTimeMoAvBuf.Init ( iHistoryLengthTime *
|
||||
SYSTEM_SAMPLE_RATE / iNewBlockLengthAtSystemSampleRate );
|
||||
iNewSystemSampleRate / iNewBlockLengthAtSystemSampleRate );
|
||||
}
|
||||
|
||||
int GetBlockLength() { return iBlockLengthAtSystemSampleRate; }
|
||||
|
@ -582,7 +584,7 @@ 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 ) -
|
||||
( iBlockLengthAtSystemSampleRate * 1000 / SYSTEM_SAMPLE_RATE ) );
|
||||
( iBlockLengthAtSystemSampleRate * 1000 / iSystemSampleRate ) );
|
||||
|
||||
RespTimeMoAvBuf.Add ( dCurAddVal * dCurAddVal ); // add squared value
|
||||
|
||||
|
@ -601,6 +603,7 @@ protected:
|
|||
CMovingAv<double> RespTimeMoAvBuf;
|
||||
int TimeLastBlock;
|
||||
int iBlockLengthAtSystemSampleRate;
|
||||
int iSystemSampleRate;
|
||||
};
|
||||
|
||||
#endif /* !defined ( UTIL_HOIH934256GEKJH98_3_43445KJIUHF1912__INCLUDED_ ) */
|
||||
|
|
Loading…
Reference in a new issue