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

1use crate::engine::audio::effects::processors::super_trait::EffectProcessor;
2
3#[derive(Debug, Clone)]
4pub struct FreezeProcessor {
5    pub enabled: bool,
6    pub fade: f32,
7    pub hold: f32,
8    buffer_l: Vec<f32>,
9    buffer_r: Vec<f32>,
10    captured: bool,
11}
12
13impl FreezeProcessor {
14    pub fn new(enabled: bool, fade: f32, hold: f32) -> Self {
15        let max = 44100usize * 5;
16        Self {
17            enabled,
18            fade: fade.clamp(0.0, 1.0),
19            hold: hold.clamp(0.05, 5.0),
20            buffer_l: vec![0.0; max],
21            buffer_r: vec![0.0; max],
22            captured: false,
23        }
24    }
25}
26
27impl Default for FreezeProcessor {
28    fn default() -> Self {
29        Self::new(false, 0.2, 0.5)
30    }
31}
32
33impl EffectProcessor for FreezeProcessor {
34    fn process(&mut self, samples: &mut [f32], _sr: u32) {
35        if !self.enabled {
36            return;
37        }
38        // capture the buffer once then replay it
39        if !self.captured {
40            let len = samples.len() / 2;
41            for i in 0..len {
42                let idx = i * 2;
43                self.buffer_l[i] = samples[idx];
44                self.buffer_r[i] = if idx + 1 < samples.len() {
45                    samples[idx + 1]
46                } else {
47                    samples[idx]
48                };
49            }
50            self.captured = true;
51        }
52        let len = samples.len() / 2;
53        for i in 0..len {
54            let idx = i * 2;
55            let frozen_l = self.buffer_l[i];
56            let frozen_r = self.buffer_r[i];
57            samples[idx] = samples[idx] * (1.0 - self.fade) + frozen_l * self.fade;
58            if idx + 1 < samples.len() {
59                samples[idx + 1] = samples[idx + 1] * (1.0 - self.fade) + frozen_r * self.fade;
60            }
61        }
62    }
63    fn reset(&mut self) {
64        self.captured = false;
65    }
66    fn name(&self) -> &str {
67        "Freeze"
68    }
69}