pub struct DelayLine { buffer: [f32; LEN], index: usize, } impl DelayLine { pub fn new() -> Self { Self { buffer: [0.0; LEN], index: 0, } } /// write to delay line and advance index pub fn write_and_advance(&mut self, value: f32) { self.buffer[self.index] = value; if self.index == LEN - 1 { self.index = 0; } else { self.index += 1; } } /// write to delay line, advance index, and return the oldest sample pub fn write_and_advance_get_last(&mut self, value: f32) -> f32 { self.write_and_advance(value); self.wrapped_index(self.index + 1) } /// Returns the sample at idx after taking modulo LEN pub fn wrapped_index(&self, idx: usize) -> f32 { self.buffer[idx % LEN] } /// Indexes the buffer but interpolates between the current and the next sample pub fn floating_index(&self, val: f32) -> f32 { let idx = val.trunc() as usize; let frac = val.fract(); let xm1 = if idx == 0 { self.wrapped_index(LEN - 1) } else { self.wrapped_index(idx - 1) }; let x0 = self.wrapped_index(idx); let x1 = self.wrapped_index(idx + 1); let x2 = self.wrapped_index(idx + 2); // linear interpolation // return (1.0 - frac) * x0 + frac * x1; crate::hermite(frac, xm1, x0, x1, x2) } /// Get a reference to the delay line's index. pub fn idx(&self) -> &usize { &self.index } /// Get a reference to the delay line's buffer. pub fn buffer(&self) -> &[f32; LEN] { &self.buffer } pub fn read_slice(&self, slice: &mut [f32]) { // Copy values in order for i in 0..LEN { slice[i] = self.wrapped_index(self.index + i); } } } pub struct DelayLines { pub l: DelayLine, pub r: DelayLine, } impl DelayLines { pub fn new() -> Self { Self { l: DelayLine::::new(), r: DelayLine::::new(), } } pub fn read_slices(&self, l: &mut [f32], r: &mut [f32]) { self.l.read_slice(l); self.r.read_slice(r); } pub fn read_to_buffers(&self, buffers: &mut crate::buffers::Buffers) { self.l.read_slice(&mut buffers.l); self.r.read_slice(&mut buffers.r); } pub fn write_and_advance(&mut self, l: f32, r: f32) { self.l.write_and_advance(l); self.r.write_and_advance(r); } }