1 module ddsp.filter.onepole; 2 3 import ddsp.effect.effect : AudioEffect; 4 5 import std.math : PI, cos, sqrt; 6 7 class OnePoleFilter(T) : AudioEffect!T 8 { 9 abstract void calcCoefficients(); 10 11 void setFrequency(float frequency) 12 { 13 _frequency = frequency; 14 calcCoefficients(); 15 } 16 17 override float getNextSample( const(float) input) nothrow @nogc 18 { 19 immutable float output = _a0 * input - _b1 * _yn1; 20 _yn1 = input; 21 return output; 22 } 23 24 override void reset() nothrow @nogc 25 { 26 _thetac = 0; 27 _gamma = 0; 28 _b1 = 0; 29 _a0 = 0; 30 _yn1 = 0; 31 } 32 33 protected: 34 float _frequency; 35 float _thetac; 36 float _gamma; 37 float _b1; 38 float _a0; 39 40 private: 41 float _yn1 = 0; 42 } 43 44 class OnePoleLPF(T) : OnePoleFilter!T 45 { 46 override void calcCoefficients() 47 { 48 _thetac = 2 * PI * _frequency / _sampleRate; 49 _gamma = 2 - cos(_thetac); 50 _b1 = sqrt((_gamma * _gamma) - 1) - _gamma; 51 _a0 = 1 + _b1; 52 } 53 } 54 55 56 class OnePoleHPF(T) : OnePoleFilter!T 57 { 58 override void calcCoefficients() 59 { 60 _thetac = 2 * PI * _frequency / _sampleRate; 61 _gamma = 2 + cos(_thetac); 62 _b1 = _gamma - sqrt((_gamma * _gamma) - 1); 63 _a0 = 1 - _b1; 64 } 65 } 66 67 unittest 68 { 69 import std.stdio; 70 writeln("****************************"); 71 writeln("* One-pole Filter tests *"); 72 writeln("****************************"); 73 74 OnePoleLPF!float lowpass = new OnePoleLPF!float(); 75 lowpass.setSampleRate(44100); 76 lowpass.setFrequency(1000); 77 78 OnePoleHPF!float highpass = new OnePoleHPF!float(); 79 highpass.setSampleRate(44100); 80 highpass.setFrequency(1000); 81 82 float[] impulse = [1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f]; 83 float[] lpfOutput = []; 84 float[] hpfOutput = []; 85 foreach(sample; impulse) 86 { 87 lpfOutput ~= lowpass.getNextSample(sample); 88 hpfOutput ~= highpass.getNextSample(sample); 89 } 90 91 writeln("Lowpass Output:"); 92 writeln(lpfOutput); 93 writeln("Highpass Output"); 94 writeln(hpfOutput); 95 }