devalang_wasm/engine/audio/effects/processors/
stretch.rs1use crate::engine::audio::effects::processors::super_trait::EffectProcessor;
2
3#[derive(Debug, Clone)]
4pub struct StretchProcessor {
5 pub factor: f32, pub pitch: f32, pub formant: bool,
8}
9
10impl StretchProcessor {
11 pub fn new(factor: f32, pitch: f32, formant: bool) -> Self {
12 Self {
13 factor: factor.clamp(0.25, 4.0),
14 pitch: pitch.clamp(-48.0, 48.0),
15 formant,
16 }
17 }
18}
19
20impl Default for StretchProcessor {
21 fn default() -> Self {
22 Self::new(1.0, 0.0, false)
23 }
24}
25
26impl EffectProcessor for StretchProcessor {
27 fn process(&mut self, samples: &mut [f32], _sr: u32) {
28 let frames = samples.len() / 2;
30 if self.factor == 1.0 {
31 return;
32 }
33 let mut out = vec![0.0f32; samples.len()];
34 for i in 0..frames {
35 let src_f = (i as f32) / self.factor;
36 let idx = src_f.floor() as usize;
37 let frac = src_f - idx as f32;
38
39 let a_l = samples.get(idx * 2).copied().unwrap_or(0.0);
40 let b_l = samples.get((idx + 1) * 2).copied().unwrap_or(a_l);
41 let val_l = a_l * (1.0 - frac) + b_l * frac;
42 out[i * 2] = val_l;
43 let a_r = samples.get(idx * 2 + 1).copied().unwrap_or(a_l);
44 let b_r = samples.get((idx + 1) * 2 + 1).copied().unwrap_or(a_r);
45 let val_r = a_r * (1.0 - frac) + b_r * frac;
46 out[i * 2 + 1] = val_r;
47 }
48 samples.copy_from_slice(&out);
49 }
50 fn reset(&mut self) {}
51 fn name(&self) -> &str {
52 "Stretch"
53 }
54}