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 }