1use crate::{Biquad, BiquadCoefs};
8use std::simd::f32x4;
9
10#[derive(Debug, Copy, Clone)]
19pub struct Oversampling<const N: usize> {
20 filters: [Biquad; 4],
21 buffer: [f32; N],
22}
23
24impl<const N: usize> Oversampling<N> {
25 pub fn new() -> Self {
26 let mut this = Self { filters: [Biquad::new(); 4], buffer: [0.0; N] };
27
28 this.set_sample_rate(44100.0);
29
30 this
31 }
32
33 pub fn reset(&mut self) {
34 self.buffer = [0.0; N];
35 for filt in &mut self.filters {
36 filt.reset();
37 }
38 }
39
40 pub fn set_sample_rate(&mut self, srate: f32) {
41 let cutoff = 0.98 * (0.5 * srate);
42
43 let ovr_srate = (N as f32) * srate;
44 let filters_len = self.filters.len();
45
46 for (i, filt) in self.filters.iter_mut().enumerate() {
47 let q = BiquadCoefs::calc_cascaded_butter_q(2 * 4, filters_len - i);
48
49 filt.set_coefs(BiquadCoefs::lowpass(ovr_srate, q, cutoff));
50 }
51 }
52
53 #[inline]
54 pub fn upsample(&mut self, v: f32) {
55 self.buffer.fill(0.0);
56 self.buffer[0] = (N as f32) * v;
57
58 for s in &mut self.buffer {
59 for filt in &mut self.filters {
60 *s = filt.tick(*s);
61 }
62 }
63 }
64
65 #[inline]
66 pub fn resample_buffer(&mut self) -> &mut [f32; N] {
67 &mut self.buffer
68 }
69
70 #[inline]
71 pub fn downsample(&mut self) -> f32 {
72 let mut ret = 0.0;
73 for s in &mut self.buffer {
74 ret = *s;
75 for filt in &mut self.filters {
76 ret = filt.tick(ret);
77 }
78 }
79
80 ret
81 }
82}
83
84#[derive(Debug, Copy, Clone)]
93struct Allpass {
94 a: f32x4,
95 x0: f32x4,
96 x1: f32x4,
97 x2: f32x4,
98
99 y0: f32x4,
100 y1: f32x4,
101 y2: f32x4,
102}
103
104impl Default for Allpass {
105 fn default() -> Allpass {
106 Allpass {
107 a: f32x4::splat(0.),
108
109 x0: f32x4::splat(0.),
110 x1: f32x4::splat(0.),
111 x2: f32x4::splat(0.),
112
113 y0: f32x4::splat(0.),
114 y1: f32x4::splat(0.),
115 y2: f32x4::splat(0.),
116 }
117 }
118}
119impl Allpass {
120 fn process(&mut self, input: f32x4) -> f32x4 {
121 self.x2 = self.x1;
123 self.x1 = self.x0;
124 self.x0 = input;
125
126 self.y2 = self.y1;
128 self.y1 = self.y0;
129
130 let output = self.x2 + ((input - self.y2) * self.a);
132
133 self.y0 = output;
134 output
135 }
136}
137#[derive(Debug, Copy, Clone)]
138struct AllpassCascade {
139 allpasses: [Allpass; 6],
140 num_filters: usize,
141}
142
143impl AllpassCascade {
144 fn process(&mut self, input: f32x4) -> f32x4 {
145 let mut output = input;
146 for i in 0..self.num_filters {
147 output = self.allpasses[i].process(output)
148 }
149 output
150 }
151}
152
153#[derive(Debug, Copy, Clone)]
199pub struct PolyIIRHalfbandFilter {
200 filter_a: AllpassCascade,
201 filter_b: AllpassCascade,
202 old_out: f32x4,
203}
204
205impl PolyIIRHalfbandFilter {
206 pub fn new(order: usize, steep: bool) -> PolyIIRHalfbandFilter {
211 let a_coefficients: Vec<f32>;
212 let b_coefficients: Vec<f32>;
213
214 if steep {
215 if order == 12 {
217 a_coefficients = vec![
218 0.036681502163648017,
219 0.2746317593794541,
220 0.56109896978791948,
221 0.769741833862266,
222 0.8922608180038789,
223 0.962094548378084,
224 ];
225
226 b_coefficients = vec![
227 0.13654762463195771,
228 0.42313861743656667,
229 0.6775400499741616,
230 0.839889624849638,
231 0.9315419599631839,
232 0.9878163707328971,
233 ];
234 }
235 else if order == 10 {
237 a_coefficients = vec![
238 0.051457617441190984,
239 0.35978656070567017,
240 0.6725475931034693,
241 0.8590884928249939,
242 0.9540209867860787,
243 ];
244
245 b_coefficients = vec![
246 0.18621906251989334,
247 0.529951372847964,
248 0.7810257527489514,
249 0.9141815687605308,
250 0.985475023014907,
251 ];
252 }
253 else if order == 8 {
255 a_coefficients = vec![
256 0.07711507983241622,
257 0.4820706250610472,
258 0.7968204713315797,
259 0.9412514277740471,
260 ];
261
262 b_coefficients = vec![
263 0.2659685265210946,
264 0.6651041532634957,
265 0.8841015085506159,
266 0.9820054141886075,
267 ];
268 }
269 else if order == 6 {
271 a_coefficients = vec![0.1271414136264853, 0.6528245886369117, 0.9176942834328115];
272
273 b_coefficients = vec![0.40056789819445626, 0.8204163891923343, 0.9763114515836773];
274 }
275 else if order == 4 {
277 a_coefficients = vec![0.12073211751675449, 0.6632020224193995];
278
279 b_coefficients = vec![0.3903621872345006, 0.890786832653497];
280 }
281 else {
283 a_coefficients = vec![0.23647102099689224];
284 b_coefficients = vec![0.7145421497126001];
285 }
286 }
287 else {
289 if order == 12 {
291 a_coefficients = vec![
292 0.01677466677723562,
293 0.13902148819717805,
294 0.3325011117394731,
295 0.53766105314488,
296 0.7214184024215805,
297 0.8821858402078155,
298 ];
299 b_coefficients = vec![
300 0.06501319274445962,
301 0.23094129990840923,
302 0.4364942348420355,
303 0.6329609551399348, 0.80378086794111226,
305 0.9599687404800694,
306 ];
307 }
308 else if order == 10 {
310 a_coefficients = vec![
311 0.02366831419883467,
312 0.18989476227180174,
313 0.43157318062118555,
314 0.6632020224193995,
315 0.860015542499582,
316 ];
317 b_coefficients = vec![
318 0.09056555904993387,
319 0.3078575723749043,
320 0.5516782402507934,
321 0.7652146863779808,
322 0.95247728378667541,
323 ];
324 }
325 else if order == 8 {
327 a_coefficients = vec![
328 0.03583278843106211,
329 0.2720401433964576,
330 0.5720571972357003,
331 0.827124761997324,
332 ];
333
334 b_coefficients = vec![
335 0.1340901419430669,
336 0.4243248712718685,
337 0.7062921421386394,
338 0.9415030941737551,
339 ];
340 }
341 else if order == 6 {
343 a_coefficients = vec![0.06029739095712437, 0.4125907203610563, 0.7727156537429234];
344
345 b_coefficients = vec![0.21597144456092948, 0.6043586264658363, 0.9238861386532906];
346 }
347 else if order == 4 {
349 a_coefficients = vec![0.07986642623635751, 0.5453536510711322];
350
351 b_coefficients = vec![0.28382934487410993, 0.8344118914807379];
352 }
353 else {
355 a_coefficients = vec![0.23647102099689224];
356 b_coefficients = vec![0.7145421497126001];
357 }
358 }
359 let mut allpasses_a = [Allpass::default(); 6];
360 for i in 0..order / 2 {
361 allpasses_a[i].a = f32x4::splat(a_coefficients[i]);
362 }
363 let filter_a = AllpassCascade { num_filters: order / 2, allpasses: allpasses_a };
364 let mut allpasses_b = [Allpass::default(); 6];
365 for i in 0..order / 2 {
366 allpasses_b[i].a = f32x4::splat(b_coefficients[i]);
367 }
368 let filter_b = AllpassCascade { num_filters: order / 2, allpasses: allpasses_b };
369 PolyIIRHalfbandFilter { filter_a, filter_b, old_out: f32x4::splat(0.) }
370 }
371
372 pub fn process(&mut self, input: f32x4) -> f32x4 {
373 let output = (self.filter_a.process(input) + self.old_out) * f32x4::splat(0.5);
374 self.old_out = self.filter_b.process(input);
375 output
376 }
377}
378
379impl Default for PolyIIRHalfbandFilter {
380 fn default() -> PolyIIRHalfbandFilter {
381 let a_coefficients = vec![
382 0.01677466677723562,
383 0.13902148819717805,
384 0.3325011117394731,
385 0.53766105314488,
386 0.7214184024215805,
387 0.8821858402078155,
388 ];
389
390 let b_coefficients = vec![
391 0.06501319274445962,
392 0.23094129990840923,
393 0.4364942348420355,
394 0.6329609551399348, 0.80378086794111226,
396 0.9599687404800694,
397 ];
398 let mut allpasses_a = [Allpass::default(); 6];
399 for i in 0..12 / 2 {
400 allpasses_a[i].a = f32x4::splat(a_coefficients[i]);
401 }
402 let filter_a = AllpassCascade { num_filters: 12 / 2, allpasses: allpasses_a };
403 let mut allpasses_b = [Allpass::default(); 6];
404 for i in 0..12 / 2 {
405 allpasses_b[i].a = f32x4::splat(b_coefficients[i]);
406 }
407 let filter_b = AllpassCascade { num_filters: 12 / 2, allpasses: allpasses_b };
408 PolyIIRHalfbandFilter { filter_a, filter_b, old_out: f32x4::splat(0.0) }
409 }
410}