Fixed a bug in the allpass filter, and the dattorro reverb sounds better and better, still some weird glitchy stuff in the modulation
This commit is contained in:
parent
e45b8a5ebd
commit
c57274bfe4
3 changed files with 66 additions and 30 deletions
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in a new issue