devalang_wasm/engine/audio/effects/processors/
eq.rs1use 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}