diff options
author | Chris Robinson <[email protected]> | 2019-12-21 02:02:57 -0800 |
---|---|---|
committer | Chris Robinson <[email protected]> | 2019-12-21 02:02:57 -0800 |
commit | 54e7f48df9366db30e4e7f5f3cca1d7a3ca9a1b4 (patch) | |
tree | 6b60392a0e355bcbaa0531c11677623ceb0b8f54 /alc | |
parent | 274fd36eddb8d37dcbe44cea1117a7027a653a67 (diff) |
Use unique setters for biquad filter parameters
One for whether a slope parameter is used, and one for bandwidth.
Diffstat (limited to 'alc')
-rw-r--r-- | alc/alu.cpp | 33 | ||||
-rw-r--r-- | alc/effects/distortion.cpp | 8 | ||||
-rw-r--r-- | alc/effects/echo.cpp | 3 | ||||
-rw-r--r-- | alc/effects/equalizer.cpp | 14 | ||||
-rw-r--r-- | alc/effects/modulator.cpp | 5 | ||||
-rw-r--r-- | alc/effects/reverb.cpp | 27 | ||||
-rw-r--r-- | alc/filters/biquad.cpp | 2 | ||||
-rw-r--r-- | alc/filters/biquad.h | 38 |
8 files changed, 64 insertions, 66 deletions
diff --git a/alc/alu.cpp b/alc/alu.cpp index bd011029..ef6b2ed7 100644 --- a/alc/alu.cpp +++ b/alc/alu.cpp @@ -1171,20 +1171,17 @@ void CalcPanningAndFilters(ALvoice *voice, const ALfloat xpos, const ALfloat ypo } { - const ALfloat hfScale{props->Direct.HFReference / Frequency}; - const ALfloat lfScale{props->Direct.LFReference / Frequency}; - const ALfloat gainHF{maxf(DryGain.HF, 0.001f)}; /* Limit -60dB */ - const ALfloat gainLF{maxf(DryGain.LF, 0.001f)}; + const float hfNorm{props->Direct.HFReference / Frequency}; + const float lfNorm{props->Direct.LFReference / Frequency}; voice->mDirect.FilterType = AF_None; - if(gainHF != 1.0f) voice->mDirect.FilterType |= AF_LowPass; - if(gainLF != 1.0f) voice->mDirect.FilterType |= AF_HighPass; + if(DryGain.HF != 1.0f) voice->mDirect.FilterType |= AF_LowPass; + if(DryGain.LF != 1.0f) voice->mDirect.FilterType |= AF_HighPass; + auto &lowpass = voice->mChans[0].mDryParams.LowPass; auto &highpass = voice->mChans[0].mDryParams.HighPass; - lowpass.setParams(BiquadType::HighShelf, gainHF, hfScale, - lowpass.rcpQFromSlope(gainHF, 1.0f)); - highpass.setParams(BiquadType::LowShelf, gainLF, lfScale, - highpass.rcpQFromSlope(gainLF, 1.0f)); + lowpass.setParamsFromSlope(BiquadType::HighShelf, hfNorm, DryGain.HF, 1.0f); + highpass.setParamsFromSlope(BiquadType::LowShelf, lfNorm, DryGain.LF, 1.0f); for(ALuint c{1};c < num_channels;c++) { voice->mChans[c].mDryParams.LowPass.copyParamsFrom(lowpass); @@ -1193,21 +1190,17 @@ void CalcPanningAndFilters(ALvoice *voice, const ALfloat xpos, const ALfloat ypo } for(ALuint i{0};i < NumSends;i++) { - const ALfloat hfScale{props->Send[i].HFReference / Frequency}; - const ALfloat lfScale{props->Send[i].LFReference / Frequency}; - const ALfloat gainHF{maxf(WetGain[i].HF, 0.001f)}; - const ALfloat gainLF{maxf(WetGain[i].LF, 0.001f)}; + const float hfNorm{props->Send[i].HFReference / Frequency}; + const float lfNorm{props->Send[i].LFReference / Frequency}; voice->mSend[i].FilterType = AF_None; - if(gainHF != 1.0f) voice->mSend[i].FilterType |= AF_LowPass; - if(gainLF != 1.0f) voice->mSend[i].FilterType |= AF_HighPass; + if(WetGain[i].HF != 1.0f) voice->mSend[i].FilterType |= AF_LowPass; + if(WetGain[i].LF != 1.0f) voice->mSend[i].FilterType |= AF_HighPass; auto &lowpass = voice->mChans[0].mWetParams[i].LowPass; auto &highpass = voice->mChans[0].mWetParams[i].HighPass; - lowpass.setParams(BiquadType::HighShelf, gainHF, hfScale, - lowpass.rcpQFromSlope(gainHF, 1.0f)); - highpass.setParams(BiquadType::LowShelf, gainLF, lfScale, - highpass.rcpQFromSlope(gainLF, 1.0f)); + lowpass.setParamsFromSlope(BiquadType::HighShelf, hfNorm, WetGain[i].HF, 1.0f); + highpass.setParamsFromSlope(BiquadType::LowShelf, lfNorm, WetGain[i].LF, 1.0f); for(ALuint c{1};c < num_channels;c++) { voice->mChans[c].mWetParams[i].LowPass.copyParamsFrom(lowpass); diff --git a/alc/effects/distortion.cpp b/alc/effects/distortion.cpp index 7dd43008..0916b7c6 100644 --- a/alc/effects/distortion.cpp +++ b/alc/effects/distortion.cpp @@ -73,18 +73,16 @@ void DistortionState::update(const ALCcontext *context, const ALeffectslot *slot ALfloat cutoff{props->Distortion.LowpassCutoff}; /* Bandwidth value is constant in octaves. */ ALfloat bandwidth{(cutoff / 2.0f) / (cutoff * 0.67f)}; - /* Multiply sampling frequency by the amount of oversampling done during + /* Divide normalized frequency by the amount of oversampling done during * processing. */ auto frequency = static_cast<ALfloat>(device->Frequency); - mLowpass.setParams(BiquadType::LowPass, 1.0f, cutoff / (frequency*4.0f), - mLowpass.rcpQFromBandwidth(cutoff / (frequency*4.0f), bandwidth)); + mLowpass.setParamsFromBandwidth(BiquadType::LowPass, cutoff/frequency/4.0f, 1.0f, bandwidth); cutoff = props->Distortion.EQCenter; /* Convert bandwidth in Hz to octaves. */ bandwidth = props->Distortion.EQBandwidth / (cutoff * 0.67f); - mBandpass.setParams(BiquadType::BandPass, 1.0f, cutoff / (frequency*4.0f), - mBandpass.rcpQFromBandwidth(cutoff / (frequency*4.0f), bandwidth)); + mBandpass.setParamsFromBandwidth(BiquadType::BandPass, cutoff/frequency/4.0f, 1.0f, bandwidth); ALfloat coeffs[MAX_AMBI_CHANNELS]; CalcDirectionCoeffs({0.0f, 0.0f, -1.0f}, 0.0f, coeffs); diff --git a/alc/effects/echo.cpp b/alc/effects/echo.cpp index a9213df5..e68baddc 100644 --- a/alc/effects/echo.cpp +++ b/alc/effects/echo.cpp @@ -97,8 +97,7 @@ void EchoState::update(const ALCcontext *context, const ALeffectslot *slot, cons mTap[1].delay = float2uint(props->Echo.LRDelay*frequency + 0.5f) + mTap[0].delay; const ALfloat gainhf{maxf(1.0f - props->Echo.Damping, 0.0625f)}; /* Limit -24dB */ - mFilter.setParams(BiquadType::HighShelf, gainhf, LOWPASSFREQREF/frequency, - mFilter.rcpQFromSlope(gainhf, 1.0f)); + mFilter.setParamsFromSlope(BiquadType::HighShelf, LOWPASSFREQREF/frequency, gainhf, 1.0f); mFeedGain = props->Echo.Feedback; diff --git a/alc/effects/equalizer.cpp b/alc/effects/equalizer.cpp index 929bff14..11fb1498 100644 --- a/alc/effects/equalizer.cpp +++ b/alc/effects/equalizer.cpp @@ -122,23 +122,21 @@ void EqualizerState::update(const ALCcontext *context, const ALeffectslot *slot, */ gain = maxf(std::sqrt(props->Equalizer.LowGain), 0.0625f); /* Limit -24dB */ f0norm = props->Equalizer.LowCutoff/frequency; - mChans[0].filter[0].setParams(BiquadType::LowShelf, gain, f0norm, - BiquadFilter::rcpQFromSlope(gain, 0.75f)); + mChans[0].filter[0].setParamsFromSlope(BiquadType::LowShelf, f0norm, gain, 0.75f); gain = maxf(std::sqrt(props->Equalizer.Mid1Gain), 0.0625f); f0norm = props->Equalizer.Mid1Center/frequency; - mChans[0].filter[1].setParams(BiquadType::Peaking, gain, f0norm, - BiquadFilter::rcpQFromBandwidth(f0norm, props->Equalizer.Mid1Width)); + mChans[0].filter[1].setParamsFromBandwidth(BiquadType::Peaking, f0norm, gain, + props->Equalizer.Mid1Width); gain = maxf(std::sqrt(props->Equalizer.Mid2Gain), 0.0625f); f0norm = props->Equalizer.Mid2Center/frequency; - mChans[0].filter[2].setParams(BiquadType::Peaking, gain, f0norm, - BiquadFilter::rcpQFromBandwidth(f0norm, props->Equalizer.Mid2Width)); + mChans[0].filter[2].setParamsFromBandwidth(BiquadType::Peaking, f0norm, gain, + props->Equalizer.Mid2Width); gain = maxf(std::sqrt(props->Equalizer.HighGain), 0.0625f); f0norm = props->Equalizer.HighCutoff/frequency; - mChans[0].filter[3].setParams(BiquadType::HighShelf, gain, f0norm, - BiquadFilter::rcpQFromSlope(gain, 0.75f)); + mChans[0].filter[3].setParamsFromSlope(BiquadType::HighShelf, f0norm, gain, 0.75f); /* Copy the filter coefficients for the other input channels. */ for(size_t i{1u};i < slot->Wet.Buffer.size();++i) diff --git a/alc/effects/modulator.cpp b/alc/effects/modulator.cpp index aee896fb..aa339dea 100644 --- a/alc/effects/modulator.cpp +++ b/alc/effects/modulator.cpp @@ -115,11 +115,10 @@ void ModulatorState::update(const ALCcontext *context, const ALeffectslot *slot, else /*if(props->Modulator.Waveform == AL_RING_MODULATOR_SQUARE)*/ mGetSamples = Modulate<Square>; - ALfloat f0norm{props->Modulator.HighPassCutoff / static_cast<ALfloat>(device->Frequency)}; + float f0norm{props->Modulator.HighPassCutoff / static_cast<ALfloat>(device->Frequency)}; f0norm = clampf(f0norm, 1.0f/512.0f, 0.49f); /* Bandwidth value is constant in octaves. */ - mChans[0].Filter.setParams(BiquadType::HighPass, 1.0f, f0norm, - BiquadFilter::rcpQFromBandwidth(f0norm, 0.75f)); + mChans[0].Filter.setParamsFromBandwidth(BiquadType::HighPass, f0norm, 1.0f, 0.75f); for(size_t i{1u};i < slot->Wet.Buffer.size();++i) mChans[i].Filter.copyParamsFrom(mChans[0].Filter); diff --git a/alc/effects/reverb.cpp b/alc/effects/reverb.cpp index 6e56adf2..6a5503f5 100644 --- a/alc/effects/reverb.cpp +++ b/alc/effects/reverb.cpp @@ -706,15 +706,13 @@ void T60Filter::calcCoeffs(const ALfloat length, const ALfloat lfDecayTime, const ALfloat mfDecayTime, const ALfloat hfDecayTime, const ALfloat lf0norm, const ALfloat hf0norm) { - const ALfloat mfGain{CalcDecayCoeff(length, mfDecayTime)}; - const ALfloat lfGain{maxf(CalcDecayCoeff(length, lfDecayTime)/mfGain, 0.001f)}; - const ALfloat hfGain{maxf(CalcDecayCoeff(length, hfDecayTime)/mfGain, 0.001f)}; + const float mfGain{CalcDecayCoeff(length, mfDecayTime)}; + const float lfGain{CalcDecayCoeff(length, lfDecayTime) / mfGain}; + const float hfGain{CalcDecayCoeff(length, hfDecayTime) / mfGain}; MidGain[1] = mfGain; - LFFilter.setParams(BiquadType::LowShelf, lfGain, lf0norm, - LFFilter.rcpQFromSlope(lfGain, 1.0f)); - HFFilter.setParams(BiquadType::HighShelf, hfGain, hf0norm, - HFFilter.rcpQFromSlope(hfGain, 1.0f)); + LFFilter.setParamsFromSlope(BiquadType::LowShelf, lf0norm, lfGain, 1.0f); + HFFilter.setParamsFromSlope(BiquadType::HighShelf, hf0norm, hfGain, 1.0f); } /* Update the early reflection line lengths and gain coefficients. */ @@ -915,17 +913,10 @@ void ReverbState::update(const ALCcontext *Context, const ALeffectslot *Slot, co const auto frequency = static_cast<ALfloat>(Device->Frequency); /* Calculate the master filters */ - ALfloat hf0norm{minf(props->Reverb.HFReference / frequency, 0.49f)}; - /* Restrict the filter gains from going below -60dB to keep the filter from - * killing most of the signal. - */ - ALfloat gainhf{maxf(props->Reverb.GainHF, 0.001f)}; - mFilter[0].Lp.setParams(BiquadType::HighShelf, gainhf, hf0norm, - mFilter[0].Lp.rcpQFromSlope(gainhf, 1.0f)); - ALfloat lf0norm{minf(props->Reverb.LFReference / frequency, 0.49f)}; - ALfloat gainlf{maxf(props->Reverb.GainLF, 0.001f)}; - mFilter[0].Hp.setParams(BiquadType::LowShelf, gainlf, lf0norm, - mFilter[0].Hp.rcpQFromSlope(gainlf, 1.0f)); + float hf0norm{minf(props->Reverb.HFReference/frequency, 0.49f)}; + mFilter[0].Lp.setParamsFromSlope(BiquadType::HighShelf, hf0norm, props->Reverb.GainHF, 1.0f); + float lf0norm{minf(props->Reverb.LFReference/frequency, 0.49f)}; + mFilter[0].Hp.setParamsFromSlope(BiquadType::LowShelf, lf0norm, props->Reverb.GainLF, 1.0f); for(size_t i{1u};i < NUM_LINES;i++) { mFilter[i].Lp.copyParamsFrom(mFilter[0].Lp); diff --git a/alc/filters/biquad.cpp b/alc/filters/biquad.cpp index 8a8810e2..13cbca3f 100644 --- a/alc/filters/biquad.cpp +++ b/alc/filters/biquad.cpp @@ -11,7 +11,7 @@ template<typename Real> -void BiquadFilterR<Real>::setParams(BiquadType type, Real gain, Real f0norm, Real rcpQ) +void BiquadFilterR<Real>::setParams(BiquadType type, Real f0norm, Real gain, Real rcpQ) { // Limit gain to -100dB assert(gain > 0.00001f); diff --git a/alc/filters/biquad.h b/alc/filters/biquad.h index 9af954ae..d7a195a9 100644 --- a/alc/filters/biquad.h +++ b/alc/filters/biquad.h @@ -1,6 +1,7 @@ #ifndef FILTERS_BIQUAD_H #define FILTERS_BIQUAD_H +#include <algorithm> #include <cmath> #include <cstddef> #include <utility> @@ -44,6 +45,8 @@ class BiquadFilterR { /* Transfer function coefficients "a" (denominator; a0 is pre-applied). */ Real mA1{0.0f}, mA2{0.0f}; + void setParams(BiquadType type, Real f0norm, Real gain, Real rcpQ); + public: void clear() noexcept { mZ1 = mZ2 = 0.0f; } @@ -51,17 +54,34 @@ public: * Sets the filter state for the specified filter type and its parameters. * * \param type The type of filter to apply. + * \param f0norm The normalized reference frequency (ref / sample_rate). + * This is the center point for the Shelf, Peaking, and BandPass filter + * types, or the cutoff frequency for the LowPass and HighPass filter + * types. + * \param gain The gain for the reference frequency response. Only used by + * the Shelf and Peaking filter types. + * \param slope Slope steepness of the transition band. + */ + void setParamsFromSlope(BiquadType type, Real f0norm, Real gain, Real slope) + { + gain = std::max<Real>(gain, 0.001f); /* Limit -60dB */ + setParams(type, gain, f0norm, rcpQFromSlope(gain, slope)); + } + + /** + * Sets the filter state for the specified filter type and its parameters. + * + * \param type The type of filter to apply. + * \param f0norm The normalized reference frequency (ref / sample_rate). + * This is the center point for the Shelf, Peaking, and BandPass filter + * types, or the cutoff frequency for the LowPass and HighPass filter + * types. * \param gain The gain for the reference frequency response. Only used by - * the Shelf and Peaking filter types. - * \param f0norm The reference frequency normal (ref_freq / sample_rate). - * This is the center point for the Shelf, Peaking, and - * BandPass filter types, or the cutoff frequency for the - * LowPass and HighPass filter types. - * \param rcpQ The reciprocal of the Q coefficient for the filter's - * transition band. Can be generated from rcpQFromSlope or - * rcpQFromBandwidth as needed. + * the Shelf and Peaking filter types. + * \param bandwidth Normalized bandwidth of the transition band. */ - void setParams(BiquadType type, Real gain, Real f0norm, Real rcpQ); + void setParamsFromBandwidth(BiquadType type, Real f0norm, Real gain, Real bandwidth) + { setParams(type, gain, f0norm, rcpQFromBandwidth(f0norm, bandwidth)); } void copyParamsFrom(const BiquadFilterR &other) { |