multimode.hpp (5632B)
1 #pragma once 2 3 #include <complex> 4 5 #include "filters/filter.hpp" 6 7 #ifdef RACK_SIMD 8 #include "simd/Vector.hpp" 9 using rack::simd::float_4; 10 #endif 11 12 namespace bogaudio { 13 namespace dsp { 14 15 #ifdef RACK_SIMD 16 struct Biquad4 { 17 float_4 _a0; 18 float_4 _a1; 19 float_4 _a2; 20 float_4 _b1; 21 float_4 _b2; 22 float_4 _x[3] {}; 23 float_4 _y[3] {}; 24 bool _disable = false; 25 int _outputIndex = 3; 26 27 void setParams(int i, float a0, float a1, float a2, float b0, float b1, float b2); 28 void reset(); 29 void setN(int n, bool minDelay = false); 30 inline void disable(bool disable) { _disable = disable; } 31 float next(float sample); 32 }; 33 #endif 34 35 template<typename T, int N> 36 struct BiquadBank : ResetableFilter { 37 #ifdef RACK_SIMD 38 Biquad4 _biquads[N / 4]; 39 #else 40 BiquadFilter<T> _biquads[N]; 41 int _n = N; 42 #endif 43 44 void setParams(int i, T a0, T a1, T a2, T b0, T b1, T b2); 45 void reset() override; 46 void setN(int n, bool minDelay = false); 47 float next(float sample) override; 48 }; 49 50 struct MultimodeTypes { 51 typedef float T; 52 typedef std::complex<T> TC; 53 54 enum Type { 55 UNKNOWN_TYPE, 56 BUTTERWORTH_TYPE, 57 CHEBYSHEV_TYPE 58 }; 59 60 enum Mode { 61 UNKNOWN_MODE, 62 LOWPASS_MODE, 63 HIGHPASS_MODE, 64 BANDPASS_MODE, 65 BANDREJECT_MODE 66 }; 67 68 enum BandwidthMode { 69 UNKNOWN_BANDWIDTH_MODE, 70 LINEAR_BANDWIDTH_MODE, 71 PITCH_BANDWIDTH_MODE 72 }; 73 74 enum DelayMode { 75 UNKNOWN_DELAY_MODE, 76 FIXED_DELAY_MODE, 77 MINIMUM_DELAY_MODE 78 }; 79 80 static constexpr int minPoles = 1; 81 static constexpr int maxPoles = 16; 82 static constexpr int modPoles = 1; 83 static constexpr float minFrequency = 3.0f; // FIXME: this can go down to at least 1.0f if T is double. 84 static constexpr float maxFrequency = 21000.0f; 85 static constexpr float minQbw = 0.0f; 86 static constexpr float maxQbw = 1.0f; 87 static constexpr float minBWLinear = 10.0f; 88 static constexpr float maxBWLinear = 5000.0f; 89 static constexpr float minBWPitch = 1.0f / (1.0f * 12.0f * 100.0f / 25.0f); 90 static constexpr float maxBWPitch = 2.0f; 91 }; 92 93 template<int N> 94 struct MultimodeDesigner : MultimodeTypes { 95 struct Pole { 96 TC p; 97 T x = 0.0; 98 T y = 0.0; 99 TC pc; 100 TC p2; 101 TC i2p; 102 TC i2pc; 103 T r = 0.0; 104 105 Pole() {} 106 Pole(T re, T im, T x, T y) : p(TC(re, im)), x(x), y(y) { 107 pc = std::conj(p); 108 p2 = p * p; 109 i2p = (T)1.0 / ((T)2.0 * p); 110 i2pc = (T)1.0 / ((T)2.0 * pc); 111 r = std::abs(p); 112 } 113 }; 114 115 float _sampleRate = 44100.0f; 116 float _half2PiST = 0.0f; 117 Type _type = UNKNOWN_TYPE; 118 Mode _mode = UNKNOWN_MODE; 119 int _nPoles = 0; 120 float _frequency = -1.0f; 121 float _qbw = -1.0f; 122 BandwidthMode _bandwidthMode = UNKNOWN_BANDWIDTH_MODE; 123 DelayMode _delayMode = UNKNOWN_DELAY_MODE; 124 Pole _poles[maxPoles / 2]; 125 int _nBiquads = 0; 126 127 float effectiveMinimumFrequency(); 128 void setParams( 129 BiquadBank<T, N>& biquads, 130 float& outGain, 131 float sampleRate, 132 Type type, 133 int poles, 134 Mode mode, 135 float frequency, 136 float qbw, 137 BandwidthMode bwm = PITCH_BANDWIDTH_MODE, 138 DelayMode dm = FIXED_DELAY_MODE 139 ); 140 }; 141 142 struct MultimodeFilter : MultimodeTypes, ResetableFilter { 143 virtual void setParams( 144 float sampleRate, 145 Type type, 146 int poles, 147 Mode mode, 148 float frequency, 149 float qbw, 150 BandwidthMode bwm = PITCH_BANDWIDTH_MODE, 151 DelayMode dm = FIXED_DELAY_MODE 152 ) = 0; 153 }; 154 155 template<int N> 156 struct MultimodeBase : MultimodeFilter { 157 MultimodeDesigner<N> _designer; 158 BiquadBank<T, N> _biquads; 159 float _outGain = 1.0f; 160 161 inline float effectiveMinimumFrequency() { return _designer.effectiveMinimumFrequency(); } 162 void setParams( 163 float sampleRate, 164 Type type, 165 int poles, 166 Mode mode, 167 float frequency, 168 float qbw, 169 BandwidthMode bwm = PITCH_BANDWIDTH_MODE, 170 DelayMode dm = FIXED_DELAY_MODE 171 ) override; 172 float next(float sample) override; 173 void reset() override; 174 }; 175 176 typedef MultimodeBase<16> MultimodeFilter16; 177 typedef MultimodeBase<8> MultimodeFilter8; 178 typedef MultimodeBase<4> MultimodeFilter4; 179 180 struct FourPoleButtworthLowpassFilter { 181 MultimodeFilter4 _filter; 182 183 inline void setParams( 184 float sampleRate, 185 float frequency, 186 float q 187 ) { 188 _filter.setParams( 189 sampleRate, 190 MultimodeFilter::BUTTERWORTH_TYPE, 191 4, 192 MultimodeFilter::LOWPASS_MODE, 193 frequency, 194 q 195 ); 196 } 197 inline float next(float sample) { return _filter.next(sample); } 198 inline void reset() { _filter.reset(); } 199 }; 200 201 struct FourPoleButtworthHighpassFilter { 202 MultimodeFilter4 _filter; 203 204 inline void setParams( 205 float sampleRate, 206 float frequency, 207 float q 208 ) { 209 _filter.setParams( 210 sampleRate, 211 MultimodeFilter::BUTTERWORTH_TYPE, 212 4, 213 MultimodeFilter::HIGHPASS_MODE, 214 frequency, 215 q 216 ); 217 } 218 inline float next(float sample) { return _filter.next(sample); } 219 inline void reset() { _filter.reset(); } 220 }; 221 222 struct TwoPoleButtworthBandpassFilter { 223 MultimodeFilter4 _filter; 224 225 inline void setParams( 226 float sampleRate, 227 float frequency, 228 float bw, 229 MultimodeFilter::BandwidthMode bwm = MultimodeFilter::PITCH_BANDWIDTH_MODE 230 ) { 231 _filter.setParams( 232 sampleRate, 233 MultimodeFilter::BUTTERWORTH_TYPE, 234 2, 235 MultimodeFilter::BANDPASS_MODE, 236 frequency, 237 bw, 238 bwm 239 ); 240 } 241 inline float next(float sample) { return _filter.next(sample); } 242 inline void reset() { _filter.reset(); } 243 }; 244 245 struct FourPoleButtworthBandpassFilter { 246 MultimodeFilter4 _filter; 247 248 inline void setParams( 249 float sampleRate, 250 float frequency, 251 float bw, 252 MultimodeFilter::BandwidthMode bwm = MultimodeFilter::PITCH_BANDWIDTH_MODE 253 ) { 254 _filter.setParams( 255 sampleRate, 256 MultimodeFilter::BUTTERWORTH_TYPE, 257 4, 258 MultimodeFilter::BANDPASS_MODE, 259 frequency, 260 bw, 261 bwm 262 ); 263 } 264 inline float next(float sample) { return _filter.next(sample); } 265 inline void reset() { _filter.reset(); } 266 }; 267 268 } // namespace dsp 269 } // namespace bogaudio