filter.hpp (1502B)
1 #pragma once 2 3 #include "buffer.hpp" 4 #include "signal.hpp" 5 6 namespace bogaudio { 7 namespace dsp { 8 9 struct Filter { 10 virtual ~Filter() {} 11 12 virtual float next(float sample) = 0; 13 }; 14 15 struct ResetableFilter : Filter { 16 virtual void reset() = 0; 17 }; 18 19 template<typename T> 20 struct BiquadFilter : ResetableFilter { 21 T _a0 = 0.0; 22 T _a1 = 0.0; 23 T _a2 = 0.0; 24 T _b1 = 0.0; 25 T _b2 = 0.0 ; 26 27 T _x[3] {}; 28 T _y[3] {}; 29 30 void setParams(T a0, T a1, T a2, T b0, T b1, T b2) { 31 T ib0 = 1.0 / b0; 32 _a0 = a0 * ib0; 33 _a1 = a1 * ib0; 34 _a2 = a2 * ib0; 35 _b1 = b1 * ib0; 36 _b2 = b2 * ib0; 37 } 38 39 void reset() override { 40 _x[0] = _x[1] = _x[2] = 0.0; 41 _y[0] = _y[1] = _y[2] = 0.0; 42 } 43 44 float next(float sample) override { 45 _x[2] = _x[1]; 46 _x[1] = _x[0]; 47 _x[0] = sample; 48 49 _y[2] = _y[1]; 50 _y[1] = _y[0]; 51 _y[0] = _a0 * _x[0]; 52 _y[0] += _a1 * _x[1]; 53 _y[0] += _a2 * _x[2]; 54 _y[0] -= _b1 * _y[1]; 55 _y[0] -= _b2 * _y[2]; 56 57 return _y[0]; 58 } 59 }; 60 61 struct LowPassFilter : ResetableFilter { 62 float _sampleRate = 0.0f; 63 float _cutoff = 0.0f; 64 float _q = 0.0f; 65 66 BiquadFilter<double> _biquad; // double is necessary here to make low cutoffs work at high sample rates. 67 68 LowPassFilter(float sampleRate = 1000.0f, float cutoff = 100.0f, float q = 0.001f) { 69 setParams(sampleRate, cutoff, q); 70 } 71 72 void setParams(float sampleRate, float cutoff, float q = 0.001f); 73 void reset() override { _biquad.reset(); } 74 float next(float sample) override { 75 return _biquad.next(sample); 76 } 77 }; 78 79 } // namespace dsp 80 } // namespace bogaudio