atagen

headroom

public
Star0
Watch0
9de515ea3b0766e46f3f383ac3721debb042c85f
1
ssh://brewery@pls.lobotomise.me:33/atagen/headroom.git

Blame: crates/headroom-dsp/src/delay.rs

614b4e43f9f3atagen2026-05-27 15:49 UTC1
//! fixed-length fifo sample delay.
614b4e43f9f3atagen2026-05-27 15:49 UTC2
614b4e43f9f3atagen2026-05-27 15:49 UTC3
pub struct DelayLine {
614b4e43f9f3atagen2026-05-27 15:49 UTC4
    buf: Vec<f32>,
614b4e43f9f3atagen2026-05-27 15:49 UTC5
    write_idx: usize,
614b4e43f9f3atagen2026-05-27 15:49 UTC6
}
614b4e43f9f3atagen2026-05-27 15:49 UTC7
614b4e43f9f3atagen2026-05-27 15:49 UTC8
impl DelayLine {
614b4e43f9f3atagen2026-05-27 15:49 UTC9
    /// 0 clamps to 1 (one-sample identity minimum).
614b4e43f9f3atagen2026-05-27 15:49 UTC10
    #[must_use]
614b4e43f9f3atagen2026-05-27 15:49 UTC11
    pub fn new(samples: usize) -> Self {
614b4e43f9f3atagen2026-05-27 15:49 UTC12
        Self {
614b4e43f9f3atagen2026-05-27 15:49 UTC13
            buf: vec![0.0; samples.max(1)],
614b4e43f9f3atagen2026-05-27 15:49 UTC14
            write_idx: 0,
614b4e43f9f3atagen2026-05-27 15:49 UTC15
        }
614b4e43f9f3atagen2026-05-27 15:49 UTC16
    }
614b4e43f9f3atagen2026-05-27 15:49 UTC17
614b4e43f9f3atagen2026-05-27 15:49 UTC18
    #[must_use]
614b4e43f9f3atagen2026-05-27 15:49 UTC19
    pub fn len(&self) -> usize {
614b4e43f9f3atagen2026-05-27 15:49 UTC20
        self.buf.len()
614b4e43f9f3atagen2026-05-27 15:49 UTC21
    }
614b4e43f9f3atagen2026-05-27 15:49 UTC22
614b4e43f9f3atagen2026-05-27 15:49 UTC23
    #[must_use]
614b4e43f9f3atagen2026-05-27 15:49 UTC24
    pub fn is_empty(&self) -> bool {
614b4e43f9f3atagen2026-05-27 15:49 UTC25
        false
614b4e43f9f3atagen2026-05-27 15:49 UTC26
    }
614b4e43f9f3atagen2026-05-27 15:49 UTC27
614b4e43f9f3atagen2026-05-27 15:49 UTC28
    /// write `x`, return the sample written `len` calls ago.
614b4e43f9f3atagen2026-05-27 15:49 UTC29
    pub fn push_pop(&mut self, x: f32) -> f32 {
614b4e43f9f3atagen2026-05-27 15:49 UTC30
        let out = self.buf[self.write_idx];
614b4e43f9f3atagen2026-05-27 15:49 UTC31
        self.buf[self.write_idx] = x;
614b4e43f9f3atagen2026-05-27 15:49 UTC32
        self.write_idx = (self.write_idx + 1) % self.buf.len();
614b4e43f9f3atagen2026-05-27 15:49 UTC33
        out
614b4e43f9f3atagen2026-05-27 15:49 UTC34
    }
614b4e43f9f3atagen2026-05-27 15:49 UTC35
614b4e43f9f3atagen2026-05-27 15:49 UTC36
    pub fn reset(&mut self) {
614b4e43f9f3atagen2026-05-27 15:49 UTC37
        for v in &mut self.buf {
614b4e43f9f3atagen2026-05-27 15:49 UTC38
            *v = 0.0;
614b4e43f9f3atagen2026-05-27 15:49 UTC39
        }
614b4e43f9f3atagen2026-05-27 15:49 UTC40
        self.write_idx = 0;
614b4e43f9f3atagen2026-05-27 15:49 UTC41
    }
614b4e43f9f3atagen2026-05-27 15:49 UTC42
}
614b4e43f9f3atagen2026-05-27 15:49 UTC43
614b4e43f9f3atagen2026-05-27 15:49 UTC44
#[cfg(test)]
614b4e43f9f3atagen2026-05-27 15:49 UTC45
mod tests {
614b4e43f9f3atagen2026-05-27 15:49 UTC46
    use super::*;
614b4e43f9f3atagen2026-05-27 15:49 UTC47
614b4e43f9f3atagen2026-05-27 15:49 UTC48
    #[test]
614b4e43f9f3atagen2026-05-27 15:49 UTC49
    fn delays_exactly_n_samples() {
614b4e43f9f3atagen2026-05-27 15:49 UTC50
        let mut d = DelayLine::new(4);
614b4e43f9f3atagen2026-05-27 15:49 UTC51
        let expected = [0.0, 0.0, 0.0, 0.0, 1.0, 2.0, 3.0, 4.0];
614b4e43f9f3atagen2026-05-27 15:49 UTC52
        let inputs = [1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0];
614b4e43f9f3atagen2026-05-27 15:49 UTC53
        for (i, &x) in inputs.iter().enumerate() {
614b4e43f9f3atagen2026-05-27 15:49 UTC54
            let y = d.push_pop(x);
614b4e43f9f3atagen2026-05-27 15:49 UTC55
            assert!((y - expected[i]).abs() < 1e-9, "i={i} y={y}");
614b4e43f9f3atagen2026-05-27 15:49 UTC56
        }
614b4e43f9f3atagen2026-05-27 15:49 UTC57
    }
614b4e43f9f3atagen2026-05-27 15:49 UTC58
614b4e43f9f3atagen2026-05-27 15:49 UTC59
    #[test]
614b4e43f9f3atagen2026-05-27 15:49 UTC60
    fn zero_length_clamps_to_one() {
614b4e43f9f3atagen2026-05-27 15:49 UTC61
        let mut d = DelayLine::new(0);
614b4e43f9f3atagen2026-05-27 15:49 UTC62
        assert_eq!(d.len(), 1);
614b4e43f9f3atagen2026-05-27 15:49 UTC63
        assert_eq!(d.push_pop(1.0), 0.0);
614b4e43f9f3atagen2026-05-27 15:49 UTC64
        assert_eq!(d.push_pop(2.0), 1.0);
614b4e43f9f3atagen2026-05-27 15:49 UTC65
    }
614b4e43f9f3atagen2026-05-27 15:49 UTC66
}