aboutsummaryrefslogtreecommitdiffstats
path: root/alc
diff options
context:
space:
mode:
authorChris Robinson <[email protected]>2019-12-21 02:02:57 -0800
committerChris Robinson <[email protected]>2019-12-21 02:02:57 -0800
commit54e7f48df9366db30e4e7f5f3cca1d7a3ca9a1b4 (patch)
tree6b60392a0e355bcbaa0531c11677623ceb0b8f54 /alc
parent274fd36eddb8d37dcbe44cea1117a7027a653a67 (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.cpp33
-rw-r--r--alc/effects/distortion.cpp8
-rw-r--r--alc/effects/echo.cpp3
-rw-r--r--alc/effects/equalizer.cpp14
-rw-r--r--alc/effects/modulator.cpp5
-rw-r--r--alc/effects/reverb.cpp27
-rw-r--r--alc/filters/biquad.cpp2
-rw-r--r--alc/filters/biquad.h38
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)
{