diff --git a/src/client.cpp b/src/client.cpp index 3b1f5178..3ab965a9 100755 --- a/src/client.cpp +++ b/src/client.cpp @@ -37,6 +37,7 @@ CClient::CClient ( const quint16 iPortNumber ) : bOpenChatOnNewMessage ( true ), bDoAutoSockBufSize ( true ), iSndCrdPreferredMonoBlSizeIndex ( CSndCrdBufferSizes::GetDefaultIndex() ), + iClientSampleRate ( SYSTEM_SAMPLE_RATE ), iSndCrdMonoBlockSizeSam ( 0 ) { // connection for protocol @@ -163,7 +164,7 @@ void CClient::SetSndCrdPreferredMonoBlSizeIndex ( const int iNewIdx ) } // init with new block size index parameter - Init ( iSndCrdPreferredMonoBlSizeIndex ); + Init ( iClientSampleRate, iSndCrdPreferredMonoBlSizeIndex ); if ( bWasRunning ) { @@ -190,7 +191,7 @@ QString CClient::SetSndCrdDev ( const int iNewDev ) // init again because the sound card actual buffer size might // be changed on new device - Init ( iSndCrdPreferredMonoBlSizeIndex ); + Init ( iClientSampleRate, iSndCrdPreferredMonoBlSizeIndex ); if ( bWasRunning ) { @@ -213,7 +214,7 @@ void CClient::OnSndCrdReinitRequest() // reinit the driver (we use the currently selected driver) and // init client object, too Sound.SetDev ( Sound.GetDev() ); - Init ( iSndCrdPreferredMonoBlSizeIndex ); + Init ( iClientSampleRate, iSndCrdPreferredMonoBlSizeIndex ); if ( bWasRunning ) { @@ -224,7 +225,7 @@ void CClient::OnSndCrdReinitRequest() void CClient::Start() { // init object - Init ( iSndCrdPreferredMonoBlSizeIndex ); + Init ( iClientSampleRate, iSndCrdPreferredMonoBlSizeIndex ); // enable channel Channel.SetEnable ( true ); @@ -262,8 +263,12 @@ void CClient::AudioCallback ( CVector& psData, void* arg ) pMyClientObj->ProcessAudioData ( psData ); } -void CClient::Init ( const int iPrefMonoBlockSizeSamIndexAtSndCrdSamRate ) +void CClient::Init ( const int iSampleRate, + const int iPrefMonoBlockSizeSamIndexAtSndCrdSamRate ) { + // store new sample rate + iClientSampleRate = iSampleRate; + // translate block size index in actual block size const int iPrefMonoBlockSizeSamAtSndCrdSamRate = CSndCrdBufferSizes:: GetBufferSizeFromIndex ( iPrefMonoBlockSizeSamIndexAtSndCrdSamRate ); @@ -272,7 +277,7 @@ void CClient::Init ( const int iPrefMonoBlockSizeSamIndexAtSndCrdSamRate ) iSndCrdMonoBlockSizeSam = Sound.Init ( iPrefMonoBlockSizeSamAtSndCrdSamRate ); iSndCrdStereoBlockSizeSam = 2 * iSndCrdMonoBlockSizeSam; - iMonoBlockSizeSam = iSndCrdMonoBlockSizeSam * SYSTEM_SAMPLE_RATE / SND_CRD_SAMPLE_RATE; + iMonoBlockSizeSam = iSndCrdMonoBlockSizeSam * iClientSampleRate / SND_CRD_SAMPLE_RATE; iStereoBlockSizeSam = 2 * iMonoBlockSizeSam; // the channel works on the same block size as the sound interface @@ -286,10 +291,12 @@ void CClient::Init ( const int iPrefMonoBlockSizeSamIndexAtSndCrdSamRate ) // resample objects are always initialized with the input block size // record - ResampleObjDown.Init ( iSndCrdMonoBlockSizeSam, SND_CRD_SAMPLE_RATE, SYSTEM_SAMPLE_RATE ); + ResampleObjDown.Init ( iSndCrdMonoBlockSizeSam, + SND_CRD_SAMPLE_RATE, iClientSampleRate ); // playback - ResampleObjUp.Init ( iMonoBlockSizeSam, SYSTEM_SAMPLE_RATE, SND_CRD_SAMPLE_RATE ); + ResampleObjUp.Init ( iMonoBlockSizeSam, + iClientSampleRate, SND_CRD_SAMPLE_RATE ); // init network buffers vecsNetwork.Init ( iMonoBlockSizeSam ); @@ -300,7 +307,8 @@ void CClient::Init ( const int iPrefMonoBlockSizeSamIndexAtSndCrdSamRate ) CycleTimeVariance.Reset(); - AudioReverb.Clear(); + // init reverberation + AudioReverb.Init ( iClientSampleRate ); } void CClient::ProcessAudioData ( CVector& vecsStereoSndCrd ) @@ -463,7 +471,7 @@ void CClient::UpdateSocketBufferSize() // a minimum buffer size of the sum of both sizes const double dAudioBufferDurationMs = ( iMonoBlockSizeSam + Channel.GetAudioBlockSizeIn() ) * 1000 / - SYSTEM_SAMPLE_RATE; + iClientSampleRate; // accumulate the standard deviations of input network stream and // internal timer, diff --git a/src/client.h b/src/client.h index 75b93187..d80495d2 100755 --- a/src/client.h +++ b/src/client.h @@ -160,7 +160,8 @@ protected: // callback function must be static, otherwise it does not work static void AudioCallback ( CVector& psData, void* arg ); - void Init ( const int iPrefMonoBlockSizeSamIndexAtSndCrdSamRate ); + void Init ( const int iSampleRate, + const int iPrefMonoBlockSizeSamIndexAtSndCrdSamRate ); void ProcessAudioData ( CVector& vecsStereoSndCrd ); void UpdateSocketBufferSize(); @@ -180,6 +181,7 @@ protected: CAudioReverb AudioReverb; int iSndCrdPreferredMonoBlSizeIndex; + int iClientSampleRate; int iSndCrdMonoBlockSizeSam; int iSndCrdStereoBlockSizeSam; diff --git a/src/util.cpp b/src/util.cpp index c2ceadde..d3ef776b 100755 --- a/src/util.cpp +++ b/src/util.cpp @@ -166,13 +166,13 @@ uint32_t CCRC::GetCRC() three series allpass units, followed by four parallel comb filters, and two decorrelation delay lines in parallel at the output. */ -CAudioReverb::CAudioReverb ( const double rT60 ) +void CAudioReverb::Init ( const int iSampleRate, const double rT60 ) { int delay, i; // delay lengths for 44100 Hz sample rate int lengths[9] = { 1777, 1847, 1993, 2137, 389, 127, 43, 211, 179 }; - const double scaler = (double) SYSTEM_SAMPLE_RATE / 44100.0; + const double scaler = (double) iSampleRate / 44100.0; if ( scaler != 1.0 ) { @@ -204,7 +204,7 @@ CAudioReverb::CAudioReverb ( const double rT60 ) combDelays_[i].Init ( lengths[i] ); } - setT60 ( rT60 ); + setT60 ( rT60, iSampleRate ); allpassCoefficient_ = (double) 0.7; Clear(); } @@ -250,13 +250,14 @@ void CAudioReverb::Clear() combDelays_[3].Reset ( 0 ); } -void CAudioReverb::setT60 ( const double rT60 ) +void CAudioReverb::setT60 ( const double rT60, + const int iSampleRate ) { // set the reverberation T60 decay time for ( int i = 0; i < 4; i++ ) { combCoefficient_[i] = pow ( (double) 10.0, (double) ( -3.0 * - combDelays_[i].Size() / ( rT60 * SYSTEM_SAMPLE_RATE ) ) ); + combDelays_[i].Size() / ( rT60 * iSampleRate ) ) ); } } diff --git a/src/util.h b/src/util.h index a2dc212f..ef59b582 100755 --- a/src/util.h +++ b/src/util.h @@ -473,13 +473,14 @@ public: class CAudioReverb { public: - CAudioReverb ( const double rT60 = (double) 5.0 ); - + CAudioReverb() {} + + void Init ( const int iSampleRate, const double rT60 = (double) 5.0 ); void Clear(); double ProcessSample ( const double input ); protected: - void setT60 ( const double rT60 ); + void setT60 ( const double rT60, const int iSampleRate ); bool isPrime ( const int number ); CFIFO allpassDelays_[3];