diff --git a/src/dsp/dattorro.rs b/src/dsp/dattorro.rs index c790cb4..4a44d8d 100644 --- a/src/dsp/dattorro.rs +++ b/src/dsp/dattorro.rs @@ -419,26 +419,27 @@ impl DattorroReverb { self.left_sum = right * decay; let mut left_accum = left_apf_tap; - left_accum += self.delay1[0].0.tap( DAT_LEFT_TAPS_TIME_MS[0]); - left_accum += self.delay1[0].0.tap( DAT_LEFT_TAPS_TIME_MS[1]); - left_accum -= self.apf2[0].0.delay_tap(DAT_LEFT_TAPS_TIME_MS[2]); - left_accum += self.delay2[0].0.tap( DAT_LEFT_TAPS_TIME_MS[3]); - left_accum -= self.delay1[1].0.tap( DAT_LEFT_TAPS_TIME_MS[4]); - left_accum -= self.apf2[1].0.delay_tap(DAT_LEFT_TAPS_TIME_MS[5]); - left_accum -= self.delay2[1].0.tap( DAT_LEFT_TAPS_TIME_MS[6]); + left_accum += self.delay1[0].0.tap_n( DAT_LEFT_TAPS_TIME_MS[0]); + left_accum += self.delay1[0].0.tap_n( DAT_LEFT_TAPS_TIME_MS[1]); + left_accum -= self.apf2[0].0.delay_tap_n(DAT_LEFT_TAPS_TIME_MS[2]); + left_accum += self.delay2[0].0.tap_n( DAT_LEFT_TAPS_TIME_MS[3]); + left_accum -= self.delay1[1].0.tap_n( DAT_LEFT_TAPS_TIME_MS[4]); + left_accum -= self.apf2[1].0.delay_tap_n(DAT_LEFT_TAPS_TIME_MS[5]); + left_accum -= self.delay2[1].0.tap_n( DAT_LEFT_TAPS_TIME_MS[6]); let mut right_accum = right_apf_tap; - right_accum += self.delay1[1].0.tap( DAT_RIGHT_TAPS_TIME_MS[0]); - right_accum += self.delay1[1].0.tap( DAT_RIGHT_TAPS_TIME_MS[1]); - right_accum -= self.apf2[1].0.delay_tap(DAT_RIGHT_TAPS_TIME_MS[2]); - right_accum += self.delay2[1].0.tap( DAT_RIGHT_TAPS_TIME_MS[3]); - right_accum -= self.delay1[0].0.tap( DAT_RIGHT_TAPS_TIME_MS[4]); - right_accum -= self.apf2[0].0.delay_tap(DAT_RIGHT_TAPS_TIME_MS[5]); - right_accum -= self.delay2[0].0.tap( DAT_RIGHT_TAPS_TIME_MS[6]); + right_accum += self.delay1[1].0.tap_n( DAT_RIGHT_TAPS_TIME_MS[0]); + right_accum += self.delay1[1].0.tap_n( DAT_RIGHT_TAPS_TIME_MS[1]); + right_accum -= self.apf2[1].0.delay_tap_n(DAT_RIGHT_TAPS_TIME_MS[2]); + right_accum += self.delay2[1].0.tap_n( DAT_RIGHT_TAPS_TIME_MS[3]); + right_accum -= self.delay1[0].0.tap_n( DAT_RIGHT_TAPS_TIME_MS[4]); + right_accum -= self.apf2[0].0.delay_tap_n(DAT_RIGHT_TAPS_TIME_MS[5]); + right_accum -= self.delay2[0].0.tap_n( DAT_RIGHT_TAPS_TIME_MS[6]); let left_out = self.out_dc_block[0].next(left_accum); let right_out = self.out_dc_block[1].next(right_accum); +// (left_out * 0.5, right_out * 0.5) (left_out * 0.5, right_out * 0.5) } } diff --git a/src/dsp/helpers.rs b/src/dsp/helpers.rs index 625337c..16d9e61 100644 --- a/src/dsp/helpers.rs +++ b/src/dsp/helpers.rs @@ -751,10 +751,40 @@ impl DelayBuffer { /// Shorthand for [DelayBuffer::cubic_interpolate_at]. #[inline] - pub fn tap(&self, delay_time_ms: f32) -> f32 { + pub fn tap_c(&self, delay_time_ms: f32) -> f32 { self.cubic_interpolate_at(delay_time_ms) } + /// Shorthand for [DelayBuffer::cubic_interpolate_at]. + #[inline] + pub fn tap_n(&self, delay_time_ms: f32) -> f32 { + self.nearest_at(delay_time_ms) + } + + /// Shorthand for [DelayBuffer::cubic_interpolate_at]. + #[inline] + pub fn tap_l(&self, delay_time_ms: f32) -> f32 { + self.linear_interpolate_at(delay_time_ms) + } + + /// Fetch a sample from the delay buffer at the given time. + /// + /// * `delay_time_ms` - Delay time in milliseconds. + pub fn linear_interpolate_at(&self, delay_time_ms: f32) -> f32 { + let data = &self.data[..]; + let len = data.len(); + let s_offs = (delay_time_ms * self.srate) / 1000.0; + let offs = s_offs.floor() as usize % len; + let fract = s_offs.fract(); + + let i = (self.wr + len) - offs; + let x0 = data[i % len]; + let x1 = data[(i + 1) % len]; + + let fract = fract as f32; + x0 * (1.0 - fract) + x1 * fract + } + /// Fetch a sample from the delay buffer at the given time. /// /// * `delay_time_ms` - Delay time in milliseconds. @@ -830,15 +860,16 @@ impl AllPass { } #[inline] - pub fn delay_tap(&self, time: f32) -> f32 { - self.delay.cubic_interpolate_at(time) + pub fn delay_tap_n(&self, time: f32) -> f32 { + self.delay.tap_n(time) } #[inline] pub fn next(&mut self, time: f32, g: f32, v: f32) -> f32 { let s = self.delay.cubic_interpolate_at(time); - self.delay.feed(v + s * g); - s + -1.0 * g * v + let input = v + -g * s; + self.delay.feed(input); + input * g + s } } @@ -863,8 +894,13 @@ impl Comb { } #[inline] - pub fn delay_tap(&self, time: f32) -> f32 { - self.delay.cubic_interpolate_at(time) + pub fn delay_tap_c(&self, time: f32) -> f32 { + self.delay.tap_c(time) + } + + #[inline] + pub fn delay_tap_n(&self, time: f32) -> f32 { + self.delay.tap_n(time) } #[inline] @@ -877,8 +913,7 @@ impl Comb { #[inline] pub fn next_feedforward(&mut self, time: f32, g: f32, v: f32) -> f32 { - let s = self.delay.cubic_interpolate_at(time); - self.delay.feed(v); + let s = self.delay.next_cubic(time, v); v + s * g } } diff --git a/tests/node_allp.rs b/tests/node_allp.rs index 686c809..a4b9cdd 100644 --- a/tests/node_allp.rs +++ b/tests/node_allp.rs @@ -40,24 +40,24 @@ fn check_node_allp() { // now signal on ch1 from the allpass: // starts with original signal * -0.7 - let mut v = vec![-0.7; (2.0 * 44.1_f32).ceil() as usize]; + let mut v = vec![0.7; (2.0 * 44.1_f32).ceil() as usize]; // silence for 1ms, which is the internal delay of the allpass v.append(&mut vec![0.0; (1.0 * 44.1_f32).floor() as usize - 3]); // allpass feedback of the original signal for 2ms: // XXX: the smearing before and after the allpass is due to the // cubic interpolation! - v.append(&mut vec![-0.03150302, 0.25802, 1.0735]); - v.append(&mut vec![1.0; (2.0 * 44.1_f32).ceil() as usize - 3]); - v.append(&mut vec![1.0315, 0.7419, -0.0735]); + v.append(&mut vec![-0.01606654, 0.13159, 0.54748535]); + v.append(&mut vec![0.51; (2.0 * 44.1_f32).ceil() as usize - 3]); + v.append(&mut vec![0.52606, 0.37840945, -0.037485]); // 1ms allpass silence like before: v.append(&mut vec![0.0; (1.0 * 44.1_f32).floor() as usize - 6]); // 2ms the previous 1.0 * 0.7 fed back into the filter, // including even more smearing due to cubic interpolation: - v.append(&mut vec![0.0006, -0.0120, 0.0106, 0.3444, 0.7801, 0.6962]); - v.append(&mut vec![0.7; (2.0 * 44.1_f32).floor() as usize - 5]); - v.append(&mut vec![0.6993, 0.712, 0.6893, 0.3555, -0.0801, 0.0037]); + v.append(&mut vec![-0.000354, 0.00615, -0.005424, -0.17565, -0.39786, -0.3550714]); + v.append(&mut vec![-0.357; (2.0 * 44.1_f32).floor() as usize - 5]); + v.append(&mut vec![-0.3566457, -0.363158, -0.35157552, -0.18134634, 0.040867306, -0.0019286368]); //d// println!("res={:?}", res.1); assert_vec_feq!(res.0, v);