fixed a bug in the delay line, that made it 1 sample off, getting incrementally worse

This commit is contained in:
Weird Constructor 2021-06-23 05:11:24 +02:00
parent 1e0caab020
commit 3f8bee1301
3 changed files with 19 additions and 18 deletions

View file

@ -561,8 +561,8 @@ impl DelayBuffer {
#[inline] #[inline]
pub fn feed(&mut self, input: f32) { pub fn feed(&mut self, input: f32) {
self.wr = (self.wr + 1) % self.data.len();
self.data[self.wr] = input; self.data[self.wr] = input;
self.wr = (self.wr + 1) % self.data.len();
} }
#[inline] #[inline]

View file

@ -21,7 +21,6 @@ macro_rules! fa_delay_mode { ($formatter: expr, $v: expr, $denorm_v: expr) => {
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct Delay { pub struct Delay {
buffer: Box<DelayBuffer>, buffer: Box<DelayBuffer>,
fb_sample: f32,
clock: TriggerSampleClock, clock: TriggerSampleClock,
} }
@ -29,7 +28,6 @@ impl Delay {
pub fn new(_nid: &NodeId) -> Self { pub fn new(_nid: &NodeId) -> Self {
Self { Self {
buffer: Box::new(DelayBuffer::new()), buffer: Box::new(DelayBuffer::new()),
fb_sample: 0.0,
clock: TriggerSampleClock::new(), clock: TriggerSampleClock::new(),
} }
} }
@ -108,43 +106,36 @@ impl DspNode for Delay {
let mix = inp::Delay::mix(inputs); let mix = inp::Delay::mix(inputs);
let out = out::Delay::sig(outputs); let out = out::Delay::sig(outputs);
let mut fb_s = self.fb_sample;
if mode.i() == 0 { if mode.i() == 0 {
for frame in 0..ctx.nframes() { for frame in 0..ctx.nframes() {
let dry = inp.read(frame); let dry = inp.read(frame);
buffer.feed(dry + fb_s * denorm::Delay::fb(fb, frame));
let out_sample = let out_sample =
buffer.cubic_interpolate_at( buffer.cubic_interpolate_at(
denorm::Delay::time(time, frame)); denorm::Delay::time(time, frame));
buffer.feed(dry + out_sample * denorm::Delay::fb(fb, frame));
out.write(frame, out.write(frame,
crossfade(dry, out_sample, crossfade(dry, out_sample,
denorm::Delay::mix(mix, frame).clamp(0.0, 1.0))); denorm::Delay::mix(mix, frame).clamp(0.0, 1.0)));
fb_s = out_sample;
} }
} else { } else {
for frame in 0..ctx.nframes() { for frame in 0..ctx.nframes() {
let dry = inp.read(frame); let dry = inp.read(frame);
buffer.feed(dry + fb_s * denorm::Delay::fb(fb, frame));
let clock_samples = let clock_samples =
self.clock.next(denorm::Delay::trig(trig, frame)); self.clock.next(denorm::Delay::trig(trig, frame));
let out_sample = buffer.at(clock_samples as usize); let out_sample = buffer.at(clock_samples as usize);
buffer.feed(dry + out_sample * denorm::Delay::fb(fb, frame));
out.write(frame, out.write(frame,
crossfade(dry, out_sample, crossfade(dry, out_sample,
denorm::Delay::mix(mix, frame).clamp(0.0, 1.0))); denorm::Delay::mix(mix, frame).clamp(0.0, 1.0)));
fb_s = out_sample;
} }
} }
self.fb_sample = fb_s;
let last_frame = ctx.nframes() - 1; let last_frame = ctx.nframes() - 1;
ctx_vals[0].set(out.read(last_frame)); ctx_vals[0].set(out.read(last_frame));
} }

View file

@ -225,7 +225,7 @@ fn check_node_delay_fb() {
let idxs_big = collect_signal_changes(&res.0[..], 50); let idxs_big = collect_signal_changes(&res.0[..], 50);
// We expect the signal to be delayed by 20ms: // We expect the signal to be delayed by 20ms:
assert_eq!(idxs_big, vec![(220, 106), (441, 53)]); assert_eq!(idxs_big, vec![(220, 106), (440, 53)]);
} }
#[test] #[test]
@ -258,7 +258,7 @@ fn check_node_delay_fb_neg() {
let idxs_big = collect_signal_changes(&res.0[..], 70); let idxs_big = collect_signal_changes(&res.0[..], 70);
assert_eq!(idxs_big, vec![(441, 100), (883, -100), (1325, 100)]); assert_eq!(idxs_big, vec![(441, 100), (882, -100), (1323, 100)]);
} }
@ -288,9 +288,19 @@ fn check_node_delay_fb_pos() {
// Emit the trigger signal: // Emit the trigger signal:
pset_n(&mut matrix, test, "trig", 1.0); pset_n(&mut matrix, test, "trig", 1.0);
let res = run_for_ms(&mut node_exec, 40.0); let res = run_for_ms(&mut node_exec, 100.0);
let idxs_big = collect_signal_changes(&res.0[..], 70); let idxs_big = collect_signal_changes(&res.0[..], 70);
assert_eq!(idxs_big, vec![(441, 100), (883, 100), (1325, 100)]); assert_eq!(idxs_big, vec![
(441, 100),
(441 + 1 * 441, 100),
(441 + 2 * 441, 100),
(441 + 3 * 441, 100),
(441 + 4 * 441, 100),
(441 + 5 * 441, 100),
(441 + 6 * 441, 100),
(441 + 7 * 441, 100),
(441 + 8 * 441, 100),
]);
} }