TestVCF.hpp (9844B)
1 #pragma once 2 3 #include "bogaudio.hpp" 4 #include "dsp/filters/experiments.hpp" 5 #include "dsp/filters/resample.hpp" 6 #include "dsp/signal.hpp" 7 8 using namespace bogaudio::dsp; 9 10 extern Model* modelTestVCF; 11 12 namespace bogaudio { 13 14 struct TestVCF : BGModule { 15 enum ParamsIds { 16 CUTOFF_PARAM, 17 Q_PARAM, 18 DRIVE_PARAM, 19 TOPOLOGY_PARAM, 20 MODE_PARAM, 21 POLES_PARAM, 22 NUM_PARAMS 23 }; 24 25 enum InputsIds { 26 IN_INPUT, 27 NUM_INPUTS 28 }; 29 30 enum OutputsIds { 31 OUT_OUTPUT, 32 OUT_B_OUTPUT, 33 NUM_OUTPUTS 34 }; 35 36 enum LightsIds { 37 LOWPASS_LIGHT, 38 HIGHPASS_LIGHT, 39 BANDPASS_LIGHT, 40 BAND_REJECT_LIGHT, 41 POLES_2_LIGHT, 42 POLES_4_LIGHT, 43 POLES_6_LIGHT, 44 POLES_8_LIGHT, 45 POLES_10_LIGHT, 46 POLES_12_LIGHT, 47 NUM_LIGHTS 48 }; 49 50 enum Mode { 51 LOWPASS_MODE, 52 HIGHPASS_MODE, 53 BANDPASS_MODE, 54 BAND_REJECT_MODE 55 }; 56 57 enum Poles { 58 POLES_2, 59 POLES_4, 60 POLES_6, 61 POLES_8, 62 POLES_10, 63 POLES_12 64 }; 65 66 template<typename T> 67 struct BicubicFilter : Filter { 68 T _a0 = 0.0; 69 T _a1 = 0.0; 70 T _a2 = 0.0; 71 T _a3 = 0.0; 72 T _b1 = 0.0; 73 T _b2 = 0.0 ; 74 T _b3 = 0.0 ; 75 76 T _x[4] {}; 77 T _y[4] {}; 78 79 void setParams(T a0, T a1, T a2, T a3, T b0, T b1, T b2, T b3) { 80 if (b0 == 1.0) { 81 _a0 = a0; 82 _a1 = a1; 83 _a2 = a2; 84 _a3 = a3; 85 _b1 = b1; 86 _b2 = b2; 87 _b3 = b3; 88 } 89 else { 90 _a0 = a0 / b0; 91 _a1 = a1 / b0; 92 _a2 = a2 / b0; 93 _a3 = a3 / b0; 94 _b1 = b1 / b0; 95 _b2 = b2 / b0; 96 _b3 = b3 / b0; 97 } 98 } 99 100 void reset() { 101 _x[0] = _x[1] = _x[2] = _x[3] = 0.0; 102 _y[0] = _y[1] = _y[2] = _y[3] = 0.0; 103 } 104 105 float next(float sample) override { 106 _x[3] = _x[2]; 107 _x[2] = _x[1]; 108 _x[1] = _x[0]; 109 _x[0] = sample; 110 111 _y[3] = _y[2]; 112 _y[2] = _y[1]; 113 _y[1] = _y[0]; 114 _y[0] = _a0 * _x[0]; 115 _y[0] += _a1 * _x[1]; 116 _y[0] += _a2 * _x[2]; 117 _y[0] += _a3 * _x[3]; 118 _y[0] -= _b1 * _y[1]; 119 _y[0] -= _b2 * _y[2]; 120 _y[0] -= _b3 * _y[3]; 121 122 return _y[0]; 123 } 124 }; 125 126 template<typename T> 127 struct BiquarticFilter : Filter { 128 T _a0 = 0.0; 129 T _a1 = 0.0; 130 T _a2 = 0.0; 131 T _a3 = 0.0; 132 T _a4 = 0.0; 133 T _b1 = 0.0; 134 T _b2 = 0.0 ; 135 T _b3 = 0.0 ; 136 T _b4 = 0.0 ; 137 138 T _x[5] {}; 139 T _y[5] {}; 140 141 void setParams(T a0, T a1, T a2, T a3, T a4, T b0, T b1, T b2, T b3, T b4) { 142 if (b0 == 1.0) { 143 _a0 = a0; 144 _a1 = a1; 145 _a2 = a2; 146 _a3 = a3; 147 _a4 = a4; 148 _b1 = b1; 149 _b2 = b2; 150 _b3 = b3; 151 _b4 = b4; 152 } 153 else { 154 _a0 = a0 / b0; 155 _a1 = a1 / b0; 156 _a2 = a2 / b0; 157 _a3 = a3 / b0; 158 _a4 = a4 / b0; 159 _b1 = b1 / b0; 160 _b2 = b2 / b0; 161 _b3 = b3 / b0; 162 _b4 = b4 / b0; 163 } 164 } 165 166 void reset() { 167 _x[0] = _x[1] = _x[2] = _x[3] = _x[4] = 0.0; 168 _y[0] = _y[1] = _y[2] = _y[3] = _y[4] = 0.0; 169 } 170 171 float next(float sample) override { 172 _x[4] = _x[3]; 173 _x[3] = _x[2]; 174 _x[2] = _x[1]; 175 _x[1] = _x[0]; 176 _x[0] = sample; 177 178 _y[4] = _y[3]; 179 _y[3] = _y[2]; 180 _y[2] = _y[1]; 181 _y[1] = _y[0]; 182 _y[0] = _a0 * _x[0]; 183 _y[0] += _a1 * _x[1]; 184 _y[0] += _a2 * _x[2]; 185 _y[0] += _a3 * _x[3]; 186 _y[0] += _a4 * _x[4]; 187 _y[0] -= _b1 * _y[1]; 188 _y[0] -= _b2 * _y[2]; 189 _y[0] -= _b3 * _y[3]; 190 _y[0] -= _b4 * _y[4]; 191 192 return _y[0]; 193 } 194 }; 195 196 struct Model { 197 virtual ~Model() {} 198 virtual void setParams(float cutoff, float bandwidth, float resonance, Mode mode, Poles poles, float topology) = 0; 199 virtual float next(float sample) = 0; 200 }; 201 202 struct LPFModel : Model { 203 LowPassFilter _filter; 204 205 void setParams(float cutoff, float bandwidth, float resonance, Mode mode, Poles poles, float topology) override; 206 float next(float sample) override; 207 }; 208 209 struct MultipoleModel : Model { 210 MultipoleFilter _filter; 211 212 void setParams(float cutoff, float bandwidth, float resonance, Mode mode, Poles poles, float topology) override; 213 float next(float sample) override; 214 }; 215 216 struct ComplexModel : Model { 217 ComplexBiquadFilter _pair1a; 218 ComplexBiquadFilter _pair1b; 219 220 void setParams(float cutoff, float bandwidth, float resonance, Mode mode, Poles poles, float topology) override; 221 float next(float sample) override; 222 }; 223 224 struct BookExampleModel : Model { 225 BiquadFilter<float> _filter1; 226 BiquadFilter<float> _filter2; 227 BiquadFilter<float> _filter3; 228 BiquadFilter<float> _filter4; 229 Poles _poles = POLES_2; 230 231 void setParams(float cutoff, float bandwidth, float resonance, Mode mode, Poles poles, float topology) override; 232 float next(float sample) override; 233 }; 234 235 struct ButterworthModel : Model { 236 static constexpr int maxPoles = 12; 237 BiquadFilter<float> _filters[maxPoles / 2]; 238 int _nFilters = 1; 239 240 void setParams(float cutoff, float bandwidth, float resonance, Mode mode, Poles poles, float topology) override; 241 float next(float sample) override; 242 }; 243 244 template<typename T> 245 struct BPButterworthModel1 : Model { 246 static constexpr int maxPoles = 12; 247 BicubicFilter<T> _filters[maxPoles / 2]; 248 int _nFilters = 1; 249 250 void setParams(float cutoff, float bandwidth, float resonance, Mode mode, Poles poles, float topology) override; 251 float next(float sample) override; 252 }; 253 254 template<typename T> 255 struct BandButterworthModel : Model { 256 static constexpr int maxPoles = 12; 257 BiquadFilter<T> _filters[maxPoles]; 258 int _nFilterPairs = 1; 259 260 void setParams(float cutoff, float bandwidth, float resonance, Mode mode, Poles poles, float topology) override; 261 float next(float sample) override; 262 }; 263 264 template<typename T> 265 struct QuarticBandButterworthModel : Model { 266 static constexpr int maxPoles = 12; 267 BiquarticFilter<T> _filters[maxPoles / 2]; 268 int _nFilters = 1; 269 270 void setParams(float cutoff, float bandwidth, float resonance, Mode mode, Poles poles, float topology) override; 271 float next(float sample) override; 272 }; 273 274 struct AllPassModel : Model { 275 BiquadFilter<float> _filter; 276 277 void setParams(float cutoff, float bandwidth, float resonance, Mode mode, Poles poles, float topology) override; 278 float next(float sample) override; 279 }; 280 281 template<typename T> 282 struct ChebyshevModel : Model { 283 static constexpr int maxPoles = 12; 284 BiquadFilter<T> _filters[maxPoles]; 285 int _nFilters = 1; 286 float _outGain = 1.0f; 287 288 void setParams(float cutoff, float bandwidth, float resonance, Mode mode, Poles poles, float topology) override; 289 void setParamsLPHP(float cutoff, float bandwidth, float resonance, Mode mode, Poles poles, float topology); 290 void setParamsBPBR(float cutoff, float bandwidth, float resonance, Mode mode, Poles poles, float topology); 291 int polesToFilters(Mode mode, BiquadFilter<T>* fs, T x, T y, T wa, T W, T w02); 292 void polesToFilterLPHP(Mode mode, BiquadFilter<T>& f, T x, T y, T wa); 293 void polesToFiltersBPBR(Mode mode, BiquadFilter<T>& f0, BiquadFilter<T>& f1, T re, T im, T W, T w02); 294 float next(float sample) override; 295 }; 296 297 template<typename T> 298 struct TwoPoleResonatorModel : Model { 299 BiquadFilter<T> _filter; 300 T _outGain = 0.0; 301 302 void setParams(float cutoff, float bandwidth, float resonance, Mode mode, Poles poles, float topology) override; 303 float next(float sample) override; 304 }; 305 306 template<typename M, int FACTOR> 307 struct OversamplingModel : Model { 308 M _model; 309 CICInterpolator _interpolator; 310 CICDecimator _decimator; 311 312 void setParams(float cutoff, float bandwidth, float resonance, Mode mode, Poles poles, float topology) override; 313 float next(float sample) override; 314 }; 315 316 template<typename M> 317 struct FeedbackModel : Model { 318 M _model; 319 float _q = 0.0f; 320 float _last = 0.0f; 321 322 void setParams(float cutoff, float bandwidth, float resonance, Mode mode, Poles poles, float topology) override; 323 float next(float sample) override; 324 }; 325 326 template<typename M, typename T> 327 struct AddResonanceModel : Model { 328 M _model; 329 TwoPoleResonatorModel<T> _resonator; 330 331 void setParams(float cutoff, float bandwidth, float resonance, Mode mode, Poles poles, float topology) override; 332 float next(float sample) override; 333 }; 334 335 static constexpr float maxCutoff = 22000.0f; 336 Mode _mode = LOWPASS_MODE; 337 Poles _poles = POLES_2; 338 Model* _model = NULL; 339 Model* _model2 = NULL; 340 Amplifier _amplifier; 341 Saturator _saturator; 342 Saturator _saturator2; 343 344 TestVCF() { 345 config(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS); 346 configParam(CUTOFF_PARAM, 0.0f, 1.0f, 0.0f, "cutoff", " hz", 0.0f, maxCutoff); 347 configParam(Q_PARAM, 0.0f, 1.0f, 0.0f, "resonance/bandwidth"); 348 configParam(DRIVE_PARAM, 0.0f, 1.0f, 0.0f, "drive", " dB", 0.0f, Amplifier::maxDecibels); 349 configParam(TOPOLOGY_PARAM, 0.0f, 1.0f, 0.0f, "topology"); 350 configParam(MODE_PARAM, 0.0f, 3.0f, 0.0f, "mode"); 351 configParam(POLES_PARAM, 0.0f, 5.0f, 0.0f, "poles"); 352 353 // _model = new LPFModel(); 354 // _model = new MultipoleModel(); 355 // _model = new ComplexModel(); 356 // _model = new BookExampleModel(); 357 // _model = new ButterworthModel(); 358 // _model = new BPButterworthModel1<double>(); 359 // _model = new OversamplingModel<BPButterworthModel1<double>, 8>(); 360 // _model = new BandButterworthModel<double>(); 361 // _model = new OversamplingModel<BandButterworthModel<double>, 8>(); 362 // _model = new AllPassModel(); 363 // _model = new QuarticBandButterworthModel<double>(); 364 // _model = new OversamplingModel<QuarticBandButterworthModel<long double>, 32>(); 365 _model = new ChebyshevModel<double>(); 366 // _model = new OversamplingModel<ChebyshevModel<double>, 8>(); 367 // _model = new FeedbackModel<OversamplingModel<ChebyshevModel<double>, 8>>(); 368 // _model = new TwoPoleResonatorModel<double>(); 369 // _model = new AddResonanceModel<OversamplingModel<ChebyshevModel<double>, 8>, double>(); 370 371 // _model2 = new OversamplingModel<MultipoleModel, 8>(); 372 // _model2 = new FeedbackModel<OversamplingModel<ButterworthModel, 8>>(); 373 // _model2 = new OversamplingModel<ButterworthModel, 8>(); 374 _model2 = new OversamplingModel<BandButterworthModel<double>, 8>(); 375 } 376 virtual ~TestVCF() { 377 if (_model) { 378 delete _model; 379 } 380 if (_model2) { 381 delete _model2; 382 } 383 } 384 385 void modulate() override; 386 void processAll(const ProcessArgs& args) override; 387 }; 388 389 } // namespace bogaudio