bae_rs/modifiers/
bandpass.rs1use super::*;
4
5pub struct BandPass {
7 central_f: MathT,
8 quality: MathT,
9 a0: MathT,
10 b1: MathT,
11 b2: MathT,
12 x1: SampleT,
13 x2: SampleT,
14 y1: SampleT,
15 y2: SampleT,
16}
17
18impl BandPass {
19 pub fn new(f: MathT, q: MathT) -> Self {
25 let mut bp = BandPass {
26 central_f: f,
27 quality: q,
28 a0: 0.0,
29 b1: 0.0,
30 b2: 0.0,
31 x1: SampleT::default(),
32 x2: SampleT::default(),
33 y1: SampleT::default(),
34 y2: SampleT::default(),
35 };
36
37 bp.reset();
38
39 bp
40 }
41
42 pub fn from_corners(f: (MathT,MathT)) -> Self {
44 let mut bp = BandPass {
45 central_f: (f.0*f.1).abs().sqrt(),
46 quality: (f.0*f.1).abs().sqrt()/(f.1-f.0).abs(),
47 a0: 0.0,
48 b1: 0.0,
49 b2: 0.0,
50 x1: SampleT::default(),
51 x2: SampleT::default(),
52 y1: SampleT::default(),
53 y2: SampleT::default(),
54 };
55
56 bp.reset();
57
58 bp
59 }
60
61 pub fn get_central_frequency(&self) -> MathT {
63 self.central_f
64 }
65
66 pub fn set_central_frequency(&mut self, f: MathT) {
68 self.central_f = f;
69
70 self.reset();
71 }
72
73 pub fn get_quality(&self) -> MathT {
75 self.quality
76 }
77
78 pub fn set_quality(&mut self, q: MathT) {
83 self.quality = q;
84
85 self.reset();
86 }
87
88 pub fn get_corner_frequencies(&self) -> (MathT,MathT) {
90 let b = -self.central_f/self.quality;
91
92 let (p,n) = quadratic(1.0, b, -self.central_f*self.central_f);
93 let fl = if p > 0.0 {
94 p
95 } else {
96 n
97 };
98 let fh = fl + b;
99
100 if fl < fh {
101 (fl, fh)
102 } else {
103 (fh, fl)
104 }
105 }
106
107 pub fn set_corner_frequencies(&mut self, f: (MathT,MathT)) {
109 self.central_f = (f.0 * f.1).sqrt();
110 self.quality = self.central_f/(f.0-f.1).abs();
111
112 self.reset();
113 }
114
115 fn reset(&mut self) {
116 let (fh, fl) = self.get_corner_frequencies();
117
118 let theta_l = (std::f64::consts::PI * fl * INV_SAMPLE_RATE).tan();
119 let theta_h = (std::f64::consts::PI * fh * INV_SAMPLE_RATE).tan();
120
121 let al = 1.0 / (1.0+theta_l);
122 let ah = 1.0 / (1.0+theta_h);
123
124 let bl = (1.0-theta_l) / (1.0+theta_l);
125 let bh = (1.0-theta_h) / (1.0+theta_h);
126
127 self.a0 = (1.0-al) * ah;
128 self.b1 = bl + bh;
129 self.b2 = bl * bh;
130 }
131}
132
133impl Modifier for BandPass {
134 fn process(&mut self, x: SampleT) -> SampleT {
135 let y = (self.a0 * (x - self.x2) as MathT +
136 self.b1 * self.y1 as MathT -
137 self.b2 * self.y2 as MathT) as SampleT;
138
139 self.y2 = self.y1;
140 self.y1 = y;
141 self.x2 = self.x1;
142 self.x1 = x;
143
144 y
145 }
146}
147
148fn quadratic(a: MathT, b: MathT, c: MathT) -> (MathT,MathT) {
149 (
150 (-b + (b*b - 4.0*a*c).sqrt())/(2.0*a),
151 (-b - (b*b - 4.0*a*c).sqrt())/(2.0*a)
152 )
153}
154
155impl Clone for BandPass {
156 fn clone(&self) -> Self {
157 BandPass {
158 central_f: self.central_f,
159 quality: self.quality,
160 a0: self.a0,
161 b1: self.b1,
162 b2: self.b2,
163 x1: SampleT::default(),
164 x2: SampleT::default(),
165 y1: SampleT::default(),
166 y2: SampleT::default(),
167 }
168 }
169}