mirror of
https://github.com/AndroidAudioMods/ViPERFX_RE.git
synced 2024-12-22 22:47:25 +08:00
Finish MultiBiquad implementation
This commit is contained in:
parent
420c09be29
commit
64e356c7b7
@ -4,17 +4,17 @@
|
||||
ViPERBass::ViPERBass() {
|
||||
this->samplingRate = DEFAULT_SAMPLERATE;
|
||||
this->speaker = 60;
|
||||
this->invertedSamplingRate = 1.0f / DEFAULT_SAMPLERATE;
|
||||
this->invertedSamplingRate = 1.0 / DEFAULT_SAMPLERATE;
|
||||
this->antiPop = 0.0;
|
||||
this->processMode = ProcessMode::NATURAL_BASS;
|
||||
this->bassFactor = 0.0f;
|
||||
this->bassFactor = 0.0;
|
||||
this->polyphase = new Polyphase(2);
|
||||
this->biquad = new Biquad();
|
||||
this->subwoofer = new Subwoofer();
|
||||
this->waveBuffer = new WaveBuffer(1, 0x1000);
|
||||
|
||||
this->biquad->Reset();
|
||||
this->biquad->SetLowPassParameter(this->speaker, this->samplingRate, 0.53);
|
||||
this->biquad->SetLowPassParameter((float) this->speaker, this->samplingRate, 0.53);
|
||||
this->subwoofer->SetBassGain(this->samplingRate, 0.0);
|
||||
this->Reset();
|
||||
}
|
||||
@ -89,7 +89,7 @@ void ViPERBass::Reset() {
|
||||
this->waveBuffer->Reset();
|
||||
this->waveBuffer->PushZeros(this->polyphase->GetLatency());
|
||||
this->subwoofer->SetBassGain(this->samplingRate, this->bassFactor * 2.5f);
|
||||
this->biquad->SetLowPassParameter(this->speaker, this->samplingRate, 0.53);
|
||||
this->biquad->SetLowPassParameter((float) this->speaker, this->samplingRate, 0.53);
|
||||
this->antiPop = 0.0f;
|
||||
this->invertedSamplingRate = 1.0f / (float) this->samplingRate;
|
||||
}
|
||||
@ -113,7 +113,7 @@ void ViPERBass::SetSamplingRate(uint32_t samplingRate) {
|
||||
this->samplingRate = samplingRate;
|
||||
this->invertedSamplingRate = 1.0f / (float) samplingRate;
|
||||
this->polyphase->SetSamplingRate(samplingRate);
|
||||
this->biquad->SetLowPassParameter(this->speaker, samplingRate, 0.53);
|
||||
this->biquad->SetLowPassParameter((float) this->speaker, samplingRate, 0.53);
|
||||
this->subwoofer->SetBassGain(samplingRate, this->bassFactor * 2.5f);
|
||||
}
|
||||
}
|
||||
@ -121,6 +121,6 @@ void ViPERBass::SetSamplingRate(uint32_t samplingRate) {
|
||||
void ViPERBass::SetSpeaker(uint32_t speaker) {
|
||||
if (this->speaker != speaker) {
|
||||
this->speaker = speaker;
|
||||
this->biquad->SetLowPassParameter(this->speaker, this->samplingRate, 0.53);
|
||||
this->biquad->SetLowPassParameter((float) this->speaker, this->samplingRate, 0.53);
|
||||
}
|
||||
}
|
||||
|
@ -47,56 +47,10 @@ MultiBiquad::RefreshFilter(FilterType type, float gainAmp, float frequency, uint
|
||||
y = sinX / ((double) qFactor / 2.0);
|
||||
z = -1.0;
|
||||
} else {
|
||||
y = sinh(((double) qFactor * (log(2) / 2.0) * x) / sinX);
|
||||
y = sinh(((double) qFactor * (log(2.0) / 2.0) * x) / sinX);
|
||||
z = -1.0;
|
||||
}
|
||||
|
||||
switch (type) {
|
||||
case LOWPASS: {
|
||||
|
||||
break;
|
||||
}
|
||||
case HIGHPASS: {
|
||||
|
||||
break;
|
||||
}
|
||||
case BANDPASS: {
|
||||
|
||||
break;
|
||||
}
|
||||
case BANDSTOP: {
|
||||
|
||||
break;
|
||||
}
|
||||
case ALLPASS: {
|
||||
|
||||
break;
|
||||
}
|
||||
case PEAK: {
|
||||
|
||||
break;
|
||||
}
|
||||
case LOWSHELF: {
|
||||
|
||||
break;
|
||||
}
|
||||
case HIGHSHELF: {
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool uVar1;
|
||||
double dVar4;
|
||||
double dVar5;
|
||||
double dVar6;
|
||||
double dVar7;
|
||||
double dVar8;
|
||||
double dVar9;
|
||||
double dVar10;
|
||||
double dVar11;
|
||||
double a0;
|
||||
double a1;
|
||||
double a2;
|
||||
@ -104,108 +58,93 @@ MultiBiquad::RefreshFilter(FilterType type, float gainAmp, float frequency, uint
|
||||
double b1;
|
||||
double b2;
|
||||
|
||||
dVar10 = pow(10.0, gainAmp / 40.0);
|
||||
dVar4 = (frequency * 2 * M_PI) / samplingRate;
|
||||
dVar5 = sin(dVar4);
|
||||
dVar11 = cos(dVar4);
|
||||
uVar1 = type == HIGHSHELF;
|
||||
dVar4 = (1.0 / dVar10 + dVar10) * (1.0 / qFactor - 1.0) + 2.0;
|
||||
dVar6 = sqrt(dVar4);
|
||||
if (!(bool) uVar1) {
|
||||
dVar4 = sinh(dVar4);
|
||||
dVar6 = dVar4;
|
||||
}
|
||||
dVar4 = sqrt(dVar10);
|
||||
dVar5 = dVar5 * 0.5 * dVar6;
|
||||
if (!(bool) uVar1) {
|
||||
dVar4 = sinh(dVar10);
|
||||
}
|
||||
dVar4 = (dVar4 + dVar4) * dVar5;
|
||||
switch (type) {
|
||||
case LOWPASS:
|
||||
b1 = 1.0 - dVar11;
|
||||
dVar10 = b1;
|
||||
b0 = dVar10 * 0.5;
|
||||
a0 = dVar5 + 1.0;
|
||||
a1 = dVar11 * -2.0;
|
||||
a2 = 1.0 - dVar5;
|
||||
case LOWPASS: {
|
||||
b1 = 1.0 - cosX;
|
||||
b0 = (1.0 - cosX) / 2.0;
|
||||
a1 = -cosX * 2.0;
|
||||
a2 = 1.0 - y;
|
||||
a0 = 1.0 + y;
|
||||
b2 = b0;
|
||||
break;
|
||||
case HIGHPASS:
|
||||
b1 = 0.0 - (dVar11 + 1.0);
|
||||
dVar10 = dVar11 + 1.0;
|
||||
b0 = dVar10 * 0.5;
|
||||
a0 = dVar5 + 1.0;
|
||||
a1 = dVar11 * -2.0;
|
||||
a2 = 1.0 - dVar5;
|
||||
}
|
||||
case HIGHPASS: {
|
||||
b1 = -1.0 - cosX;
|
||||
b0 = (1.0 + cosX) / 2.0;
|
||||
a1 = -cosX * 2.0;
|
||||
a2 = 1.0 - y;
|
||||
a0 = 1.0 + y;
|
||||
b2 = b0;
|
||||
break;
|
||||
case BANDPASS:
|
||||
a1 = dVar11 * -2.0;
|
||||
a2 = 1.0 - dVar5;
|
||||
a0 = dVar5 + 1.0;
|
||||
}
|
||||
case BANDPASS: {
|
||||
b1 = 0.0;
|
||||
b0 = dVar5;
|
||||
b2 = 0.0 - dVar5;
|
||||
a1 = -cosX * 2.0;
|
||||
a2 = 1.0 - y;
|
||||
a0 = 1.0 + y;
|
||||
b0 = y;
|
||||
b2 = -y;
|
||||
break;
|
||||
case BANDSTOP:
|
||||
b1 = dVar11 * -2.0;
|
||||
a2 = 1.0 - dVar5;
|
||||
a0 = dVar5 + 1.0;
|
||||
}
|
||||
case BANDSTOP: {
|
||||
b1 = -cosX * 2.0;
|
||||
a2 = 1.0 - y;
|
||||
a0 = 1.0 + y;
|
||||
b0 = 1.0;
|
||||
b2 = 1.0;
|
||||
a1 = b1;
|
||||
break;
|
||||
case ALLPASS:
|
||||
b1 = dVar11 * -2.0;
|
||||
a2 = 1.0 - dVar5;
|
||||
a0 = dVar5 + 1.0;
|
||||
}
|
||||
case ALLPASS: {
|
||||
b1 = -cosX * 2.0;
|
||||
a2 = 1.0 - y;
|
||||
a0 = 1.0 + y;
|
||||
b0 = a2;
|
||||
b2 = a0;
|
||||
a1 = b1;
|
||||
break;
|
||||
case PEAK:
|
||||
b1 = dVar11 * -2.0;
|
||||
a2 = 1.0 - dVar5 / dVar10;
|
||||
a0 = dVar5 / dVar10 + 1.0;
|
||||
b0 = dVar5 * dVar10 + 1.0;
|
||||
b2 = 1.0 - dVar5 * dVar10;
|
||||
}
|
||||
case PEAK: {
|
||||
b1 = -cosX * 2.0;
|
||||
a2 = 1.0 - y / (double) gain;
|
||||
a0 = 1.0 + y / (double) gain;
|
||||
b0 = 1.0 + y * (double) gain;
|
||||
b2 = 1.0 - y * (double) gain;
|
||||
a1 = b1;
|
||||
break;
|
||||
case LOWSHELF:
|
||||
dVar6 = dVar10 - 1.0;
|
||||
dVar7 = dVar10 + 1.0;
|
||||
dVar5 = dVar7 - dVar6 * dVar11;
|
||||
dVar8 = dVar7 + dVar6 * dVar11;
|
||||
a0 = dVar8 + dVar4;
|
||||
b1 = (dVar10 + dVar10) * (dVar6 - dVar11 * dVar7);
|
||||
a2 = dVar8 - dVar4;
|
||||
a1 = (dVar6 + dVar11 * dVar7) * -2.0;
|
||||
b0 = (dVar5 + dVar4) * dVar10;
|
||||
b2 = (dVar5 - dVar4) * dVar10;
|
||||
}
|
||||
case LOWSHELF: {
|
||||
double tmp1 = (gain + 1.0) - (gain - 1.0) * cosX;
|
||||
double tmp2 = (gain + 1.0) + (gain - 1.0) * cosX;
|
||||
a1 = ((gain - 1.0) + (gain + 1.0) * cosX) * -2.0;
|
||||
a2 = tmp2 - z;
|
||||
b1 = (gain * 2.0) * ((gain - 1.0) - (gain + 1.0) * cosX);
|
||||
a0 = tmp2 + z;
|
||||
b0 = (tmp1 + z) * gain;
|
||||
b2 = (tmp1 - z) * gain;
|
||||
break;
|
||||
case HIGHSHELF:
|
||||
dVar6 = dVar10 - 1.0;
|
||||
dVar8 = dVar10 + 1.0;
|
||||
dVar5 = dVar8 + dVar6 * dVar11;
|
||||
dVar9 = dVar8 - dVar6 * dVar11;
|
||||
dVar7 = dVar6 - dVar11 * dVar8;
|
||||
a0 = dVar9 + dVar4;
|
||||
b1 = dVar10 * -2.0 * (dVar6 + dVar11 * dVar8);
|
||||
a2 = dVar9 - dVar4;
|
||||
a1 = dVar7 + dVar7;
|
||||
b0 = (dVar5 + dVar4) * dVar10;
|
||||
b2 = (dVar5 - dVar4) * dVar10;
|
||||
}
|
||||
case HIGHSHELF: {
|
||||
double tmp1 = (gain + 1.0) + (gain - 1.0) * cosX;
|
||||
double tmp2 = (gain + 1.0) - (gain - 1.0) * cosX;
|
||||
a2 = tmp2 - z;
|
||||
a0 = tmp2 + z;
|
||||
a1 = ((gain - 1.0) - (gain + 1.0) * cosX) * 2.0;
|
||||
b1 = gain * -2.0 * ((gain - 1.0) + (gain + 1.0) * cosX);
|
||||
b0 = (tmp1 + z) * gain;
|
||||
b2 = (tmp1 - z) * gain;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
this->a1 = a1 / a0;
|
||||
this->a2 = a2 / a0;
|
||||
this->x_1 = 0.0;
|
||||
this->x_2 = 0.0;
|
||||
this->y_1 = 0.0;
|
||||
this->y_2 = 0.0;
|
||||
|
||||
this->a1 = -a1 / a0;
|
||||
this->a2 = -a2 / a0;
|
||||
this->b0 = b0 / a0;
|
||||
this->b1 = b1 / a0;
|
||||
this->b2 = b2 / a0;
|
||||
|
||||
this->y_2 = 0.f;
|
||||
this->y_1 = 0.f;
|
||||
this->x_2 = 0.f;
|
||||
this->x_1 = 0.f;
|
||||
}
|
||||
|
@ -27,10 +27,10 @@ void Subwoofer::SetBassGain(uint32_t samplingRate, float gainDb) {
|
||||
float gain = 20.0f * log10( gainDb);
|
||||
float gainLower = 20.0f * log10( gainDb / 8.0f);
|
||||
|
||||
this->peak[0].RefreshFilter(FilterType::PEAK, gain, 44.0, (double) samplingRate, 0.75, true);
|
||||
this->peak[1].RefreshFilter(FilterType::PEAK, gain, 44.0, (double) samplingRate, 0.75, true);
|
||||
this->peakLow[0].RefreshFilter(FilterType::PEAK, gainLower, 80.0, (double) samplingRate, 0.2, true);
|
||||
this->peakLow[1].RefreshFilter(FilterType::PEAK, gainLower, 80.0, (double) samplingRate, 0.2, true);
|
||||
this->lowpass[0].RefreshFilter(FilterType::LOWPASS, 0.0, 380.0, (double) samplingRate, 0.6, false);
|
||||
this->lowpass[1].RefreshFilter(FilterType::LOWPASS, 0.0, 380.0, (double) samplingRate, 0.6, false);
|
||||
this->peak[0].RefreshFilter(FilterType::PEAK, gain, 44.0, samplingRate, 0.75, true);
|
||||
this->peak[1].RefreshFilter(FilterType::PEAK, gain, 44.0, samplingRate, 0.75, true);
|
||||
this->peakLow[0].RefreshFilter(FilterType::PEAK, gainLower, 80.0, samplingRate, 0.2, true);
|
||||
this->peakLow[1].RefreshFilter(FilterType::PEAK, gainLower, 80.0, samplingRate, 0.2, true);
|
||||
this->lowpass[0].RefreshFilter(FilterType::LOWPASS, 0.0, 380.0, samplingRate, 0.6, false);
|
||||
this->lowpass[1].RefreshFilter(FilterType::LOWPASS, 0.0, 380.0, samplingRate, 0.6, false);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user