devalang_wasm/engine/audio/effects/processors/
highpass.rs

1use crate::engine::audio::effects::processors::super_trait::EffectProcessor;
2
3#[derive(Debug, Clone)]
4pub struct HighpassProcessor {
5    pub cutoff: f32,
6    pub resonance: f32,
7    prev_x_l: f32,
8    prev_x_r: f32,
9    prev_y_l: f32,
10    prev_y_r: f32,
11}
12
13impl HighpassProcessor {
14    pub fn new(cutoff: f32, resonance: f32) -> Self {
15        Self {
16            cutoff: cutoff.clamp(20.0, 20000.0),
17            resonance: resonance.clamp(0.0, 1.0),
18            prev_x_l: 0.0,
19            prev_x_r: 0.0,
20            prev_y_l: 0.0,
21            prev_y_r: 0.0,
22        }
23    }
24}
25
26impl Default for HighpassProcessor {
27    fn default() -> Self {
28        Self::new(200.0, 0.1)
29    }
30}
31
32impl EffectProcessor for HighpassProcessor {
33    fn process(&mut self, samples: &mut [f32], sr: u32) {
34        let fs = sr as f32;
35        let fc = self.cutoff.max(20.0).min(fs * 0.49);
36        let omega = 2.0 * std::f32::consts::PI * fc / fs;
37        let alpha = 1.0 / (omega + 1.0);
38
39        for i in (0..samples.len()).step_by(2) {
40            let x_l = samples[i];
41            let y_l = alpha * (self.prev_y_l + x_l - self.prev_x_l);
42            self.prev_x_l = x_l;
43            self.prev_y_l = y_l;
44            samples[i] = y_l;
45            if i + 1 < samples.len() {
46                let x_r = samples[i + 1];
47                let y_r = alpha * (self.prev_y_r + x_r - self.prev_x_r);
48                self.prev_x_r = x_r;
49                self.prev_y_r = y_r;
50                samples[i + 1] = y_r;
51            }
52        }
53    }
54
55    fn reset(&mut self) {
56        self.prev_x_l = 0.0;
57        self.prev_x_r = 0.0;
58        self.prev_y_l = 0.0;
59        self.prev_y_r = 0.0;
60    }
61
62    fn name(&self) -> &str {
63        "Highpass"
64    }
65}