BogaudioModules

BogaudioModules for VCV Rack
Log | Files | Refs | README | LICENSE

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