commit 8ebc14df5044e2320340912fc9a86115bb49f7cf
parent 34eacdfdaf8349db5c5ec56877f931739cfe9717
Author: Matt Demanett <matt@demanett.net>
Date: Tue, 23 Jun 2020 23:21:57 -0400
Refactor MultimodeFilter interfaces; speed up FFB and PEQ*.
Diffstat:
8 files changed, 110 insertions(+), 83 deletions(-)
diff --git a/src/FFB.hpp b/src/FFB.hpp
@@ -47,9 +47,9 @@ struct FFB : BGModule {
};
struct Engine {
- MultimodeFilter _lowPass;
+ MultimodeFilter8 _lowPass;
FourPoleButtworthBandpassFilter _bandPasses[12];
- MultimodeFilter _highPass;
+ MultimodeFilter8 _highPass;
Amplifier _amplifiers[14];
bogaudio::dsp::SlewLimiter _slews[14];
diff --git a/src/LVCF.hpp b/src/LVCF.hpp
@@ -38,10 +38,10 @@ struct LVCF : BGModule {
};
struct Engine {
- MultimodeFilter _filter;
+ MultimodeFilter16 _filter;
float _sampleRate;
bogaudio::dsp::SlewLimiter _frequencySL;
- MultimodeFilter _finalHP;
+ MultimodeFilter4 _finalHP;
Engine() {
sampleRateChange();
diff --git a/src/VCF.hpp b/src/VCF.hpp
@@ -40,12 +40,12 @@ struct VCF : BGModule {
static constexpr int maxPoles = 12;
static constexpr int minPoles = 1;
static constexpr int nFilters = maxPoles;
- MultimodeFilter _filters[nFilters];
+ MultimodeFilter16 _filters[nFilters];
float _gains[nFilters] {};
bogaudio::dsp::SlewLimiter _gainSLs[nFilters];
float _sampleRate;
bogaudio::dsp::SlewLimiter _frequencySL;
- MultimodeFilter _finalHP;
+ MultimodeFilter4 _finalHP;
Engine() {
sampleRateChange();
diff --git a/src/dsp/filters/filter.hpp b/src/dsp/filters/filter.hpp
@@ -7,14 +7,17 @@ namespace bogaudio {
namespace dsp {
struct Filter {
- Filter() {}
virtual ~Filter() {}
virtual float next(float sample) = 0;
};
+struct ResetableFilter : Filter {
+ virtual void reset() = 0;
+};
+
template<typename T>
-struct BiquadFilter : Filter {
+struct BiquadFilter : ResetableFilter {
T _a0 = 0.0;
T _a1 = 0.0;
T _a2 = 0.0;
@@ -33,7 +36,7 @@ struct BiquadFilter : Filter {
_b2 = b2 * ib0;
}
- void reset() {
+ void reset() override {
_x[0] = _x[1] = _x[2] = 0.0;
_y[0] = _y[1] = _y[2] = 0.0;
}
@@ -55,7 +58,7 @@ struct BiquadFilter : Filter {
}
};
-struct LowPassFilter : Filter {
+struct LowPassFilter : ResetableFilter {
float _sampleRate = 0.0f;
float _cutoff = 0.0f;
float _q = 0.0f;
@@ -67,7 +70,7 @@ struct LowPassFilter : Filter {
}
void setParams(float sampleRate, float cutoff, float q = 0.001f);
- void reset() { _biquad.reset(); }
+ void reset() override { _biquad.reset(); }
float next(float sample) override {
return _biquad.next(sample);
}
diff --git a/src/dsp/filters/multimode.cpp b/src/dsp/filters/multimode.cpp
@@ -68,6 +68,36 @@ template<> float BiquadBank<MultimodeTypes::T, 4>::next(float sample) {
return _biquads->next(sample);
}
+
+template<> void BiquadBank<MultimodeTypes::T, 8>::setParams(int i, MultimodeTypes::T a0, MultimodeTypes::T a1, MultimodeTypes::T a2, MultimodeTypes::T b0, MultimodeTypes::T b1, MultimodeTypes::T b2) {
+ assert(i >= 0 && i < 8);
+ _biquads[i / 4].setParams(i % 4, a0, a1, a2, b0, b1, b2);
+}
+
+template<> void BiquadBank<MultimodeTypes::T, 8>::reset() {
+ _biquads[0].reset();
+ _biquads[1].reset();
+}
+
+template<> void BiquadBank<MultimodeTypes::T, 8>::setN(int n, bool minDelay) {
+ assert(n > 0 && n <= 8);
+ for (int i = 0, nn = n / 4; i < nn; ++i) {
+ _biquads[i].setN(4, false);
+ }
+ if (n % 4 != 0) {
+ _biquads[n / 4].setN(n % 4, minDelay);
+ }
+ for (int i = 0; i < 2; ++i) {
+ _biquads[i].disable(4 * i >= n);
+ }
+}
+
+template<> float BiquadBank<MultimodeTypes::T, 8>::next(float sample) {
+ sample = _biquads[0].next(sample);
+ return _biquads[1].next(sample);
+}
+
+
template<> void BiquadBank<MultimodeTypes::T, 16>::setParams(int i, MultimodeTypes::T a0, MultimodeTypes::T a1, MultimodeTypes::T a2, MultimodeTypes::T b0, MultimodeTypes::T b1, MultimodeTypes::T b2) {
assert(i >= 0 && i < 16);
_biquads[i / 4].setParams(i % 4, a0, a1, a2, b0, b1, b2);
@@ -131,6 +161,7 @@ template<typename T, int N> float BiquadBank<T, N>::next(float sample) {
#endif
template struct BiquadBank<MultimodeTypes::T, 4>;
+template struct BiquadBank<MultimodeTypes::T, 8>;
template struct BiquadBank<MultimodeTypes::T, 16>;
@@ -440,10 +471,11 @@ template<int N> void MultimodeDesigner<N>::setParams(
}
template struct MultimodeDesigner<4>;
+template struct MultimodeDesigner<8>;
template struct MultimodeDesigner<16>;
-template<int N> void MultimodeBase<N>::design(
+template<int N> void MultimodeBase<N>::setParams(
float sampleRate,
Type type,
int poles,
@@ -476,6 +508,7 @@ template<int N> void MultimodeBase<N>::reset() {
}
template struct MultimodeBase<4>;
+template struct MultimodeBase<8>;
template struct MultimodeBase<16>;
} // namespace dsp
diff --git a/src/dsp/filters/multimode.hpp b/src/dsp/filters/multimode.hpp
@@ -33,7 +33,7 @@ namespace dsp {
#endif
template<typename T, int N>
-struct BiquadBank : Filter {
+struct BiquadBank : ResetableFilter {
#ifdef RACK_SIMD
Biquad4 _biquads[N / 4];
#else
@@ -42,7 +42,7 @@ struct BiquadBank : Filter {
#endif
void setParams(int i, T a0, T a1, T a2, T b0, T b1, T b2);
- void reset();
+ void reset() override;
void setN(int n, bool minDelay = false);
float next(float sample) override;
};
@@ -138,13 +138,8 @@ struct MultimodeDesigner : MultimodeTypes {
);
};
-template<int N>
-struct MultimodeBase : MultimodeTypes, Filter {
- MultimodeDesigner<N> _designer;
- BiquadBank<T, N> _biquads;
- float _outGain = 1.0f;
-
- void design(
+struct MultimodeFilter : MultimodeTypes, ResetableFilter {
+ virtual void setParams(
float sampleRate,
Type type,
int poles,
@@ -153,37 +148,16 @@ struct MultimodeBase : MultimodeTypes, Filter {
float qbw,
BandwidthMode bwm = PITCH_BANDWIDTH_MODE,
DelayMode dm = FIXED_DELAY_MODE
- );
- float next(float sample) override;
- void reset();
+ ) = 0;
};
-struct MultimodeFilter : MultimodeBase<16> {
- inline void setParams(
- float sampleRate,
- Type type,
- int poles,
- Mode mode,
- float frequency,
- float qbw,
- BandwidthMode bwm = PITCH_BANDWIDTH_MODE,
- DelayMode dm = FIXED_DELAY_MODE
- ) {
- design(
- sampleRate,
- type,
- poles,
- mode,
- frequency,
- qbw,
- bwm,
- dm
- );
- }
-};
+template<int N>
+struct MultimodeBase : MultimodeFilter {
+ MultimodeDesigner<N> _designer;
+ BiquadBank<T, N> _biquads;
+ float _outGain = 1.0f;
-struct FourPoleMultimodeFilter : MultimodeBase<4> {
- inline void setParams(
+ void setParams(
float sampleRate,
Type type,
int poles,
@@ -192,90 +166,101 @@ struct FourPoleMultimodeFilter : MultimodeBase<4> {
float qbw,
BandwidthMode bwm = PITCH_BANDWIDTH_MODE,
DelayMode dm = FIXED_DELAY_MODE
- ) {
- design(
- sampleRate,
- type,
- poles,
- mode,
- frequency,
- qbw,
- bwm,
- dm
- );
- }
+ ) override;
+ float next(float sample) override;
+ void reset() override;
};
-struct FourPoleButtworthLowpassFilter : MultimodeBase<4> {
+typedef MultimodeBase<16> MultimodeFilter16;
+typedef MultimodeBase<8> MultimodeFilter8;
+typedef MultimodeBase<4> MultimodeFilter4;
+
+struct FourPoleButtworthLowpassFilter {
+ MultimodeFilter4 _filter;
+
inline void setParams(
float sampleRate,
float frequency,
float q
) {
- design(
+ _filter.setParams(
sampleRate,
- BUTTERWORTH_TYPE,
+ MultimodeFilter::BUTTERWORTH_TYPE,
4,
- LOWPASS_MODE,
+ MultimodeFilter::LOWPASS_MODE,
frequency,
q
);
}
+ inline float next(float sample) { return _filter.next(sample); }
+ inline void reset() { _filter.reset(); }
};
-struct FourPoleButtworthHighpassFilter : MultimodeBase<4> {
+struct FourPoleButtworthHighpassFilter {
+ MultimodeFilter4 _filter;
+
inline void setParams(
float sampleRate,
float frequency,
float q
) {
- design(
+ _filter.setParams(
sampleRate,
- BUTTERWORTH_TYPE,
+ MultimodeFilter::BUTTERWORTH_TYPE,
4,
- HIGHPASS_MODE,
+ MultimodeFilter::HIGHPASS_MODE,
frequency,
q
);
}
+ inline float next(float sample) { return _filter.next(sample); }
+ inline void reset() { _filter.reset(); }
};
-struct TwoPoleButtworthBandpassFilter : MultimodeBase<4> {
+struct TwoPoleButtworthBandpassFilter {
+ MultimodeFilter4 _filter;
+
inline void setParams(
float sampleRate,
float frequency,
float bw,
- BandwidthMode bwm = PITCH_BANDWIDTH_MODE
+ MultimodeFilter::BandwidthMode bwm = MultimodeFilter::PITCH_BANDWIDTH_MODE
) {
- design(
+ _filter.setParams(
sampleRate,
- BUTTERWORTH_TYPE,
+ MultimodeFilter::BUTTERWORTH_TYPE,
2,
- BANDPASS_MODE,
+ MultimodeFilter::BANDPASS_MODE,
frequency,
bw,
bwm
);
}
+ inline float next(float sample) { return _filter.next(sample); }
+ inline void reset() { _filter.reset(); }
};
-struct FourPoleButtworthBandpassFilter : MultimodeBase<4> {
+struct FourPoleButtworthBandpassFilter {
+ MultimodeFilter4 _filter;
+
inline void setParams(
float sampleRate,
float frequency,
float bw,
- BandwidthMode bwm = PITCH_BANDWIDTH_MODE
+ MultimodeFilter::BandwidthMode bwm = MultimodeFilter::PITCH_BANDWIDTH_MODE
) {
- design(
+ _filter.setParams(
sampleRate,
- BUTTERWORTH_TYPE,
+ MultimodeFilter::BUTTERWORTH_TYPE,
4,
- BANDPASS_MODE,
+ MultimodeFilter::BANDPASS_MODE,
frequency,
bw,
bwm
);
}
+ inline float next(float sample) { return _filter.next(sample); }
+ inline void reset() { _filter.reset(); }
};
} // namespace dsp
diff --git a/src/parametric_eq.cpp b/src/parametric_eq.cpp
@@ -67,7 +67,7 @@ void PEQChannel::modulate() {
}
bw = MultimodeFilter::minQbw + bw * (MultimodeFilter::maxQbw - MultimodeFilter::minQbw);
}
- _filter.setParams(
+ _filter->setParams(
_sampleRate,
MultimodeFilter::BUTTERWORTH_TYPE,
_poles,
@@ -79,7 +79,7 @@ void PEQChannel::modulate() {
}
void PEQChannel::next(float sample) {
- out = _amplifier.next(_filter.next(sample));
+ out = _amplifier.next(_filter->next(sample));
rms = _rms.next(out / 5.0f);
}
diff --git a/src/parametric_eq.hpp b/src/parametric_eq.hpp
@@ -19,7 +19,7 @@ struct PEQChannel {
float _sampleRate;
Amplifier _amplifier;
bogaudio::dsp::SlewLimiter _levelSL;
- MultimodeFilter _filter;
+ MultimodeFilter* _filter = NULL;
bogaudio::dsp::SlewLimiter _frequencySL;
bogaudio::dsp::SlewLimiter _bandwidthSL;
RootMeanSquare _rms;
@@ -42,6 +42,7 @@ struct PEQChannel {
float rms = 0.0f;
PEQChannel(
+ MultimodeFilter* filter,
int polyChannel,
Param& levelParam,
Param& frequencyParam,
@@ -54,7 +55,8 @@ struct PEQChannel {
Input* bandwidthCvInput,
float sampleRate = 1000.0f
)
- : _c(polyChannel)
+ : _filter(filter)
+ , _c(polyChannel)
, _levelParam(levelParam)
, _frequencyParam(frequencyParam)
, _frequencyCv1Param(frequencyCv1Param)
@@ -69,6 +71,9 @@ struct PEQChannel {
setFilterMode(MultimodeFilter::BANDPASS_MODE);
_rms.setSensitivity(0.05f);
}
+ virtual ~PEQChannel() {
+ delete _filter;
+ }
void setSampleRate(float sampleRate);
void setFilterMode(MultimodeFilter::Mode mode);
@@ -106,6 +111,7 @@ struct PEQEngine {
Input* bandwidthCvInput
) {
_channels[i] = new PEQChannel(
+ i == 0 || i == _n - 1 ? (MultimodeFilter*)(new MultimodeFilter8()) : (MultimodeFilter*)(new MultimodeFilter4()),
polyChannel,
levelParam,
frequencyParam,