1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
use super::*;
pub struct LowPass {
fc: MathT,
r: MathT,
coeff: [SampleT; 4],
outs: [SampleT; 3]
}
impl LowPass {
pub fn new(fc: MathT, r: MathT) -> LowPass {
let fc = fc.min(SAMPLE_RATE as MathT / 2.0);
let r = r.min(1.0).max(0.0);
let mut lp = LowPass {
fc,
r,
coeff: [0.0; 4],
outs: [SampleT::default(); 3]
};
lp.reset();
lp
}
pub fn get_central_frequency(&self) -> MathT {
self.fc
}
pub fn set_central_frequency(&mut self, fc: MathT) {
let fc = fc.min(SAMPLE_RATE as MathT / 2.0);
self.fc = fc;
self.reset();
}
pub fn get_resonance(&self) -> MathT {
self.r
}
pub fn set_resonance(&mut self, r: MathT) {
let r = r.min(1.0).max(0.0);
self.r = r;
self.reset();
}
fn reset(&mut self) {
let theta = (std::f64::consts::PI / 6.0) * (4.0 - self.r);
let k = 1.0 - 2.0 * theta.cos();
let w = 2.0 * std::f64::consts::PI * self.fc;
let t = w * INV_SAMPLE_RATE;
let g = t.powf(3.0) + k*t.powf(2.0) + k*t + 1.0;
self.coeff[0] = (t.powf(3.0) / g) as SampleT;
self.coeff[1] = ((k*t.powf(2.0) + 2.0*k*t + 3.0) / g) as SampleT;
self.coeff[2] = ((-k*t - 3.0) / g) as SampleT;
self.coeff[3] = (1.0 / g) as SampleT;
}
}
impl Modifier for LowPass {
fn process(&mut self, x: SampleT) -> SampleT {
let y = self.coeff[0]*x +
self.coeff[1]*self.outs[0] +
self.coeff[2]*self.outs[1] +
self.coeff[3]*self.outs[2];
self.outs[2] = self.outs[1];
self.outs[1] = self.outs[0];
self.outs[0] = y;
y
}
}
impl Clone for LowPass {
fn clone(&self) -> Self {
LowPass {
fc: self.fc,
r: self.r,
coeff: self.coeff,
outs: [SampleT::default(); 3]
}
}
}