1 /** 2 * Copyright 2017 Cut Through Recordings 3 * License: MIT License 4 * Author(s): Ethan Reker 5 */ 6 module ddsp.filter.lowpass; 7 8 import ddsp.filter.biquad; 9 10 import std.math; 11 12 /// First order lowpass filter 13 class LowpassO1 : BiQuad 14 { 15 public: 16 override void calcCoefficients() nothrow @nogc 17 { 18 _thetac = 2 * PI * _frequency / _sampleRate; 19 _gamma = cos(_thetac) / (1 + sin(_thetac)); 20 _a0 = (1 - _gamma) / 2; 21 _a1 = _a0; 22 _a2 = 0.0; 23 _b1 = -_gamma; 24 _b2 = 0.0; 25 } 26 27 private: 28 float _thetac; 29 float _gamma; 30 31 } 32 33 /// Second order lowpass filter 34 class LowpassO2 : BiQuad 35 { 36 public: 37 void setQualityFactor(float Q) nothrow @nogc 38 { 39 if(Q != _q) 40 { 41 _q = Q; 42 calcCoefficients(); 43 } 44 } 45 46 override void calcCoefficients() nothrow @nogc 47 { 48 _thetac = 2 * PI * _frequency / _sampleRate; 49 _d0 = 1 / _q; 50 _beta = 0.5 * (1 - (_d0 / 2) * sin(_thetac)) / (1 + (_d0 / 2) * sin(_thetac)); 51 _gamma = (0.5 + _beta) * cos(_thetac); 52 _a1 = 0.5 + _beta - _gamma; 53 _a0 = _a1 / 2.0; 54 _a2 = _a0; 55 _b1 = -2.0 * _gamma; 56 _b2 = 2.0 * _beta; 57 } 58 59 private: 60 float _thetac; 61 float _q = 0.707f; 62 float _beta; 63 float _gamma; 64 } 65 66 /// Second order butterworth lowpass filter 67 class ButterworthLP : BiQuad 68 { 69 public: 70 override void calcCoefficients() nothrow @nogc 71 { 72 _C = 1.0 / tan(PI * _frequency / _sampleRate); 73 _a0 = 1.0 / (1 + sqrt(2.0f) * _C + (_C * _C)); 74 _a1 = 2.0 * _a0; 75 _a2 = _a0; 76 _b1 = 2.0 * _a0 * (1 - _C * _C); 77 _b2 = _a0 * (1.0f - sqrt(2.0f) * _C + _C * _C); 78 } 79 private: 80 float _C; 81 } 82 83 //Second order linkwitz-riley lowpass filter 84 class LinkwitzRileyLP : BiQuad 85 { 86 public: 87 override void calcCoefficients() nothrow @nogc 88 { 89 _theta = pi * _frequency / _sampleRate; 90 _omega = pi * _frequency; 91 _kappa = _omega / tan(_theta); 92 _delta = _kappa * _kappa + _omega * _omega + 2 * _kappa * _omega; 93 _a0 = (_omega * _omega) / _delta; 94 _a1 = 2 * _a0; 95 _a2 = _a0; 96 _b1 = (-2 * _kappa * _kappa + 2 * _omega * _omega) / _delta; 97 _b2 = (-2 * _kappa * _omega + _kappa * _kappa + _omega * _omega) / _delta; 98 } 99 private: 100 float _theta; 101 float _omega; 102 float _kappa; 103 float _delta; 104 }