Support for a true stereo reverberation effect
This commit is contained in:
parent
963f1f7849
commit
ac10994d5c
4 changed files with 76 additions and 49 deletions
|
@ -1,3 +1,9 @@
|
|||
3.3.4
|
||||
|
||||
- true stereo reverberation effect (previously it was a mono reverberation
|
||||
effect on both stereo channels)
|
||||
|
||||
|
||||
3.3.3
|
||||
|
||||
- support for storing/recovering the window positions
|
||||
|
|
|
@ -911,11 +911,8 @@ void CClient::ProcessAudioDataIntern ( CVector<int16_t>& vecsStereoSndCrd )
|
|||
// for stereo always apply reverberation effect on both channels
|
||||
for ( i = 0; i < iStereoBlockSizeSam; i += 2 )
|
||||
{
|
||||
// left channel
|
||||
AudioReverbL.ProcessSample ( vecsStereoSndCrd[i], dRevLev );
|
||||
|
||||
// right channel
|
||||
AudioReverbR.ProcessSample ( vecsStereoSndCrd[i + 1], dRevLev );
|
||||
// both channels (stereo)
|
||||
AudioReverbL.ProcessSample ( vecsStereoSndCrd[i], vecsStereoSndCrd[i + 1], dRevLev );
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -925,7 +922,8 @@ void CClient::ProcessAudioDataIntern ( CVector<int16_t>& vecsStereoSndCrd )
|
|||
for ( i = 0; i < iStereoBlockSizeSam; i += 2 )
|
||||
{
|
||||
// left channel
|
||||
AudioReverbL.ProcessSample ( vecsStereoSndCrd[i], dRevLev );
|
||||
int16_t sRightDummy = 0; // has to be 0 for mono reverb
|
||||
AudioReverbL.ProcessSample ( vecsStereoSndCrd[i], sRightDummy, dRevLev );
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -933,7 +931,8 @@ void CClient::ProcessAudioDataIntern ( CVector<int16_t>& vecsStereoSndCrd )
|
|||
for ( i = 1; i < iStereoBlockSizeSam; i += 2 )
|
||||
{
|
||||
// right channel
|
||||
AudioReverbR.ProcessSample ( vecsStereoSndCrd[i], dRevLev );
|
||||
int16_t sRightDummy = 0; // has to be 0 for mono reverb
|
||||
AudioReverbR.ProcessSample ( vecsStereoSndCrd[i], sRightDummy, dRevLev );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
93
src/util.cpp
93
src/util.cpp
|
@ -167,7 +167,7 @@ void CAudioReverb::Init ( const int iSampleRate,
|
|||
int delay, i;
|
||||
|
||||
// delay lengths for 44100 Hz sample rate
|
||||
int lengths[9] = { 1777, 1847, 1993, 2137, 389, 127, 43, 211, 179 };
|
||||
int lengths[9] = { 1116, 1356, 1422, 1617, 225, 341, 441, 211, 179 };
|
||||
const double scaler = (double) iSampleRate / 44100.0;
|
||||
|
||||
if ( scaler != 1.0 )
|
||||
|
@ -192,16 +192,18 @@ void CAudioReverb::Init ( const int iSampleRate,
|
|||
|
||||
for ( i = 0; i < 3; i++ )
|
||||
{
|
||||
allpassDelays_[i].Init ( lengths[i + 4] );
|
||||
allpassDelays[i].Init ( lengths[i + 4] );
|
||||
}
|
||||
|
||||
for ( i = 0; i < 4; i++ )
|
||||
{
|
||||
combDelays_[i].Init ( lengths[i] );
|
||||
combDelays[i].Init ( lengths[i] );
|
||||
}
|
||||
|
||||
setT60 ( rT60, iSampleRate );
|
||||
allpassCoefficient_ = (double) 0.7;
|
||||
outLeftDelay.Init ( lengths[7] );
|
||||
outRightDelay.Init ( lengths[8] );
|
||||
allpassCoefficient = (double) 0.7;
|
||||
Clear();
|
||||
}
|
||||
|
||||
|
@ -237,13 +239,15 @@ bool CAudioReverb::isPrime ( const int number )
|
|||
void CAudioReverb::Clear()
|
||||
{
|
||||
// reset and clear all internal state
|
||||
allpassDelays_[0].Reset ( 0 );
|
||||
allpassDelays_[1].Reset ( 0 );
|
||||
allpassDelays_[2].Reset ( 0 );
|
||||
combDelays_[0].Reset ( 0 );
|
||||
combDelays_[1].Reset ( 0 );
|
||||
combDelays_[2].Reset ( 0 );
|
||||
combDelays_[3].Reset ( 0 );
|
||||
allpassDelays[0].Reset ( 0 );
|
||||
allpassDelays[1].Reset ( 0 );
|
||||
allpassDelays[2].Reset ( 0 );
|
||||
combDelays[0].Reset ( 0 );
|
||||
combDelays[1].Reset ( 0 );
|
||||
combDelays[2].Reset ( 0 );
|
||||
combDelays[3].Reset ( 0 );
|
||||
outRightDelay.Reset ( 0 );
|
||||
outLeftDelay.Reset ( 0 );
|
||||
}
|
||||
|
||||
void CAudioReverb::setT60 ( const double rT60,
|
||||
|
@ -252,48 +256,63 @@ void CAudioReverb::setT60 ( const double rT60,
|
|||
// 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 * iSampleRate ) ) );
|
||||
combCoefficient[i] = pow ( (double) 10.0, (double) ( -3.0 *
|
||||
combDelays[i].Size() / ( rT60 * iSampleRate ) ) );
|
||||
}
|
||||
}
|
||||
|
||||
void CAudioReverb::ProcessSample ( int16_t& input,
|
||||
void CAudioReverb::ProcessSample ( int16_t& iInputOutputLeft,
|
||||
int16_t& iInputOutputRight,
|
||||
const double dAttenuation )
|
||||
{
|
||||
// compute one output sample
|
||||
double temp, temp0, temp1, temp2;
|
||||
|
||||
temp = allpassDelays_[0].Get();
|
||||
temp0 = allpassCoefficient_ * temp;
|
||||
temp0 += input;
|
||||
allpassDelays_[0].Add ( (int) temp0 );
|
||||
temp0 = - ( allpassCoefficient_ * temp0 ) + temp;
|
||||
// we sum up the stereo input channels (in case mono input is used, a zero
|
||||
// shall be input for the right channel)
|
||||
const double dMixedInput = 0.5 * ( iInputOutputLeft + iInputOutputRight );
|
||||
|
||||
temp = allpassDelays_[1].Get();
|
||||
temp1 = allpassCoefficient_ * temp;
|
||||
temp = allpassDelays[0].Get();
|
||||
temp0 = allpassCoefficient * temp;
|
||||
temp0 += dMixedInput;
|
||||
allpassDelays[0].Add ( temp0 );
|
||||
temp0 = - ( allpassCoefficient * temp0 ) + temp;
|
||||
|
||||
temp = allpassDelays[1].Get();
|
||||
temp1 = allpassCoefficient * temp;
|
||||
temp1 += temp0;
|
||||
allpassDelays_[1].Add ( (int) temp1 );
|
||||
temp1 = - ( allpassCoefficient_ * temp1 ) + temp;
|
||||
allpassDelays[1].Add ( temp1 );
|
||||
temp1 = - ( allpassCoefficient * temp1 ) + temp;
|
||||
|
||||
temp = allpassDelays_[2].Get();
|
||||
temp2 = allpassCoefficient_ * temp;
|
||||
temp = allpassDelays[2].Get();
|
||||
temp2 = allpassCoefficient * temp;
|
||||
temp2 += temp1;
|
||||
allpassDelays_[2].Add ( (int) temp2 );
|
||||
temp2 = - ( allpassCoefficient_ * temp2 ) + temp;
|
||||
allpassDelays[2].Add ( temp2 );
|
||||
temp2 = - ( allpassCoefficient * temp2 ) + temp;
|
||||
|
||||
const double temp3 = temp2 + ( combCoefficient_[0] * combDelays_[0].Get() );
|
||||
const double temp4 = temp2 + ( combCoefficient_[1] * combDelays_[1].Get() );
|
||||
const double temp5 = temp2 + ( combCoefficient_[2] * combDelays_[2].Get() );
|
||||
const double temp6 = temp2 + ( combCoefficient_[3] * combDelays_[3].Get() );
|
||||
const double temp3 = temp2 + ( combCoefficient[0] * combDelays[0].Get() );
|
||||
const double temp4 = temp2 + ( combCoefficient[1] * combDelays[1].Get() );
|
||||
const double temp5 = temp2 + ( combCoefficient[2] * combDelays[2].Get() );
|
||||
const double temp6 = temp2 + ( combCoefficient[3] * combDelays[3].Get() );
|
||||
|
||||
combDelays_[0].Add ( (int) temp3 );
|
||||
combDelays_[1].Add ( (int) temp4 );
|
||||
combDelays_[2].Add ( (int) temp5 );
|
||||
combDelays_[3].Add ( (int) temp6 );
|
||||
combDelays[0].Add ( temp3 );
|
||||
combDelays[1].Add ( temp4 );
|
||||
combDelays[2].Add ( temp5 );
|
||||
combDelays[3].Add ( temp6 );
|
||||
|
||||
const double filtout = temp3 + temp4 + temp5 + temp6;
|
||||
|
||||
outLeftDelay.Add ( filtout );
|
||||
outRightDelay.Add ( filtout );
|
||||
|
||||
// inplace apply the attenuated reverb signal
|
||||
input = Double2Short ( input +
|
||||
( temp3 + temp4 + temp5 + temp6 ) * (double) 0.5 * dAttenuation );
|
||||
iInputOutputLeft = Double2Short (
|
||||
( 1.0 - dAttenuation ) * iInputOutputLeft +
|
||||
0.5 * dAttenuation * outLeftDelay.Get() );
|
||||
|
||||
iInputOutputRight = Double2Short (
|
||||
( 1.0 - dAttenuation ) * iInputOutputRight +
|
||||
0.5 * dAttenuation * outRightDelay.Get() );
|
||||
}
|
||||
|
||||
|
||||
|
|
13
src/util.h
13
src/util.h
|
@ -869,17 +869,20 @@ public:
|
|||
|
||||
void Init ( const int iSampleRate, const double rT60 = (double) 1.1 );
|
||||
void Clear();
|
||||
void ProcessSample ( int16_t& input,
|
||||
void ProcessSample ( int16_t& iInputOutputLeft,
|
||||
int16_t& iInputOutputRight,
|
||||
const double dAttenuation );
|
||||
|
||||
protected:
|
||||
void setT60 ( const double rT60, const int iSampleRate );
|
||||
bool isPrime ( const int number );
|
||||
|
||||
CFIFO<int> allpassDelays_[3];
|
||||
CFIFO<int> combDelays_[4];
|
||||
double allpassCoefficient_;
|
||||
double combCoefficient_[4];
|
||||
CFIFO<double> allpassDelays[3];
|
||||
CFIFO<double> combDelays[4];
|
||||
CFIFO<double> outLeftDelay;
|
||||
CFIFO<double> outRightDelay;
|
||||
double allpassCoefficient;
|
||||
double combCoefficient[4];
|
||||
};
|
||||
|
||||
|
||||
|
|
Loading…
Reference in a new issue