Skip to main content

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

1use crate::engine::audio::effects::processors::super_trait::EffectProcessor;
2
3#[derive(Debug, Clone)]
4pub struct EqProcessor {
5    low_gain: f32,
6    mid_gain: f32,
7    high_gain: f32,
8    low_l: f32,
9    low_r: f32,
10    high_prev_x_l: f32,
11    high_prev_x_r: f32,
12    high_prev_y_l: f32,
13    high_prev_y_r: f32,
14}
15
16impl EqProcessor {
17    pub fn new(low_gain: f32, mid_gain: f32, high_gain: f32) -> Self {
18        Self {
19            low_gain: low_gain.clamp(0.0, 2.0),
20            mid_gain: mid_gain.clamp(0.0, 2.0),
21            high_gain: high_gain.clamp(0.0, 2.0),
22            low_l: 0.0,
23            low_r: 0.0,
24            high_prev_x_l: 0.0,
25            high_prev_x_r: 0.0,
26            high_prev_y_l: 0.0,
27            high_prev_y_r: 0.0,
28        }
29    }
30}
31
32impl Default for EqProcessor {
33    fn default() -> Self {
34        Self::new(1.0, 1.0, 1.0)
35    }
36}
37
38impl EffectProcessor for EqProcessor {
39    fn process(&mut self, samples: &mut [f32], sample_rate: u32) {
40        let fs = sample_rate as f32;
41
42        let low_fc = 320.0_f32.min(fs * 0.49);
43        let low_omega = 2.0 * std::f32::consts::PI * low_fc / fs;
44        let low_alpha = low_omega / (low_omega + 1.0);
45
46        let high_fc = 3200.0_f32.min(fs * 0.49);
47        let high_omega = 2.0 * std::f32::consts::PI * high_fc / fs;
48        let high_alpha = 1.0 / (high_omega + 1.0);
49
50        for i in (0..samples.len()).step_by(2) {
51            let input_l = samples[i];
52            self.low_l += low_alpha * (input_l - self.low_l);
53            let high_l = high_alpha * (self.high_prev_y_l + input_l - self.high_prev_x_l);
54            self.high_prev_x_l = input_l;
55            self.high_prev_y_l = high_l;
56            let mid_l = input_l - self.low_l - high_l;
57            samples[i] =
58                self.low_l * self.low_gain + mid_l * self.mid_gain + high_l * self.high_gain;
59
60            if i + 1 < samples.len() {
61                let input_r = samples[i + 1];
62                self.low_r += low_alpha * (input_r - self.low_r);
63                let high_r = high_alpha * (self.high_prev_y_r + input_r - self.high_prev_x_r);
64                self.high_prev_x_r = input_r;
65                self.high_prev_y_r = high_r;
66                let mid_r = input_r - self.low_r - high_r;
67                samples[i + 1] =
68                    self.low_r * self.low_gain + mid_r * self.mid_gain + high_r * self.high_gain;
69            }
70        }
71    }
72
73    fn reset(&mut self) {
74        self.low_l = 0.0;
75        self.low_r = 0.0;
76        self.high_prev_x_l = 0.0;
77        self.high_prev_x_r = 0.0;
78        self.high_prev_y_l = 0.0;
79        self.high_prev_y_r = 0.0;
80    }
81
82    fn name(&self) -> &str {
83        "EQ"
84    }
85}