More work on Dattorro reverb

This commit is contained in:
Weird Constructor 2021-08-06 19:25:24 +02:00
parent 83b8c1a1fc
commit 2f71b682b0
2 changed files with 100 additions and 33 deletions

View file

@ -31,21 +31,31 @@ const DAT_LEFT_APF2_TIME_MS : f32 = 1800.0 / DAT_SAMPLES_PER_MS;
const DAT_RIGHT_APF1_TIME_MS : f32 = 908.0 / DAT_SAMPLES_PER_MS;
const DAT_RIGHT_APF2_TIME_MS : f32 = 2656.0 / DAT_SAMPLES_PER_MS;
// const long _kLeftApf1Time = 672;
// const long _kLeftDelay1Time = 4453;
// const long _kLeftApf2Time = 1800;
// const long _kLeftDelay2Time = 3720;
//
// const long _kRightApf1Time = 908;
// const long _kRightDelay1Time = 4217;
// const long _kRightApf2Time = 2656;
// const long _kRightDelay2Time = 3163;
const DAT_LEFT_DELAY1_TIME_MS : f32 = 4453.0 / DAT_SAMPLES_PER_MS;
const DAT_LEFT_DELAY2_TIME_MS : f32 = 3720.0 / DAT_SAMPLES_PER_MS;
const DAT_RIGHT_DELAY1_TIME_MS : f32 = 4217.0 / DAT_SAMPLES_PER_MS;
const DAT_RIGHT_DELAY2_TIME_MS : f32 = 3163.0 / DAT_SAMPLES_PER_MS;
const DAT_TAPS_TIME_MS : [f32; 7] = [
266.0 / DAT_SAMPLES_PER_MS,
2974.0 / DAT_SAMPLES_PER_MS,
1913.0 / DAT_SAMPLES_PER_MS,
1996.0 / DAT_SAMPLES_PER_MS,
1990.0 / DAT_SAMPLES_PER_MS,
187.0 / DAT_SAMPLES_PER_MS,
1066.0 / DAT_SAMPLES_PER_MS,
];
const DAT_LFO_FREQS_HZ : [f32; 4] = [ 0.1, 0.15, 0.12, 0.18 ];
const DAT_INPUT_DIFFUSION1 : f32 = 0.75;
const DAT_INPUT_DIFFUSION2 : f32 = 0.625;
const DAT_PLATE_DIFFUSION1 : f32 = 0.7;
const DAT_PLATE_DIFFUSION2 : f32 = 0.5;
const DAT_LFO_EXCURSION_MS : f32 = 16.0 / DAT_SAMPLES_PER_MS;
use crate::dsp::helpers::{
AllPass,
TriSawLFO,
@ -67,21 +77,20 @@ pub struct DattorroReverb {
input_lpf: OnePoleLPF,
pre_delay: DelayBuffer,
input_apfs: [(AllPass, f32); 4],
input_apfs: [(AllPass, f32, f32); 4],
apf1: [(AllPass, f32); 2],
apf1: [(AllPass, f32, f32); 2],
hpf: [OnePoleHPF; 2],
lpf: [OnePoleLPF; 2],
apf2: [AllPass; 2],
delay1: [DelayBuffer; 2],
delay2: [DelayBuffer; 2],
time_scale_factor: f32,
apf2: [(AllPass, f32, f32); 2],
delay1: [(DelayBuffer, f32); 2],
delay2: [(DelayBuffer, f32); 2],
}
pub trait DattorroReverbParams {
/// Time for the pre-delay of the reverb.
fn pre_delay_time_s(&self) -> f32;
fn time_scale(&self) -> f32;
}
impl DattorroReverb {
@ -98,15 +107,14 @@ impl DattorroReverb {
input_lpf: OnePoleLPF::new(),
pre_delay: DelayBuffer::new(),
input_apfs: [(AllPass::new(), 0.0); 4],
input_apfs: Default::default(),
apf1: [(AllPass::new(), 0.0); 2],
apf1: Default::default(),
hpf: [OnePoleHPF::new(); 2],
lpf: [OnePoleLPF::new(); 2],
apf2: [AllPass::new(); 2],
delay1: [DelayBuffer::new(); 2],
delay2: [DelayBuffer::new(); 2],
time_scale_factor: 1.0,
apf2: Default::default(),
delay1: Default::default(),
delay2: Default::default(),
};
this.reset();
@ -115,20 +123,64 @@ impl DattorroReverb {
}
pub fn reset(&mut self) {
self.input_lpf.reset();
self.input_hpf.reset();
self.input_lpf.set_freq(22000.0);
self.input_hpf.set_freq(0.0);
self.input_apfs[0].1 = DAT_INPUT_APF_TIMES_MS[0];
self.input_apfs[1].1 = DAT_INPUT_APF_TIMES_MS[1];
self.input_apfs[2].1 = DAT_INPUT_APF_TIMES_MS[2];
self.input_apfs[3].1 = DAT_INPUT_APF_TIMES_MS[3];
self.input_apfs[0] =
(AllPass::new(), DAT_INPUT_APF_TIMES_MS[0], DAT_INPUT_DIFFUSION1);
self.input_apfs[1] =
(AllPass::new(), DAT_INPUT_APF_TIMES_MS[1], DAT_INPUT_DIFFUSION1);
self.input_apfs[2] =
(AllPass::new(), DAT_INPUT_APF_TIMES_MS[2], DAT_INPUT_DIFFUSION2);
self.input_apfs[3] =
(AllPass::new(), DAT_INPUT_APF_TIMES_MS[3], DAT_INPUT_DIFFUSION2);
self.apf1[0] =
(AllPass::new(), DAT_LEFT_APF1_TIME_MS, -DAT_PLATE_DIFFUSION1);
self.apf1[1] =
(AllPass::new(), DAT_RIGHT_APF1_TIME_MS, -DAT_PLATE_DIFFUSION1);
self.apf2[0] =
(AllPass::new(), DAT_LEFT_APF2_TIME_MS, -DAT_PLATE_DIFFUSION2);
self.apf2[1] =
(AllPass::new(), DAT_RIGHT_APF2_TIME_MS, -DAT_PLATE_DIFFUSION2);
self.delay1[0] = (DelayBuffer::new(), DAT_LEFT_DELAY1_TIME_MS);
self.delay1[1] = (DelayBuffer::new(), DAT_RIGHT_DELAY1_TIME_MS);
self.delay2[0] = (DelayBuffer::new(), DAT_LEFT_DELAY2_TIME_MS);
self.delay2[1] = (DelayBuffer::new(), DAT_RIGHT_DELAY2_TIME_MS);
self.lpf[0].reset();
self.lpf[1].reset();
self.lpf[0].set_freq(10000.0);
self.lpf[1].set_freq(10000.0);
self.hpf[0].reset();
self.hpf[1].reset();
self.hpf[0].set_freq(0.0);
self.hpf[1].set_freq(0.0);
self.lfos[0].set(DAT_LFO_FREQS_HZ[0], 0.5);
self.lfos[0].set_phase_offs(0.0);
self.lfos[0].reset();
self.lfos[1].set(DAT_LFO_FREQS_HZ[1], 0.5);
self.lfos[1].set_phase_offs(0.25);
self.lfos[1].reset();
self.lfos[2].set(DAT_LFO_FREQS_HZ[2], 0.5);
self.lfos[2].set_phase_offs(0.5);
self.lfos[2].reset();
self.lfos[3].set(DAT_LFO_FREQS_HZ[3], 0.5);
self.lfos[3].set_phase_offs(0.75);
self.lfos[3].reset();
self.set_time_scale(1.0);
}
#[inline]
pub fn set_time_scale(&mut self, scale: f32) {
if (self.last_scale - scale).abs() > std::f32::consts::EPSILON {
if (self.last_scale - scale).abs() > std::f32::EPSILON {
let scale = scale.max(0.0001);
self.last_scale = scale;
@ -140,9 +192,16 @@ impl DattorroReverb {
}
pub fn set_sample_rate(&mut self, srate: f32) {
self.time_scale_factor = srate / DAT_SAMPLE_RATE;
}
pub fn process(&mut self, params: &mut dyn DattorroReverbParams, input: f32) -> (f32, f32) {
pub fn process(
&mut self,
params: &mut dyn DattorroReverbParams,
input_l: f32, input_r: f32
) -> (f32, f32)
{
self.set_time_scale(params.time_scale());
(0.0, 0.0)
}
}

View file

@ -655,7 +655,7 @@ impl TriggerSampleClock {
/// Default size of the delay buffer: 5 seconds at 8 times 48kHz
const DEFAULT_DELAY_BUFFER_SAMPLES : usize = 8 * 48000 * 5;
#[derive(Debug, Clone)]
#[derive(Debug, Clone, Default)]
pub struct DelayBuffer {
data: Vec<f32>,
wr: usize,
@ -748,7 +748,7 @@ impl DelayBuffer {
/// Default size of the delay buffer: 1 seconds at 8 times 48kHz
const DEFAULT_ALLPASS_COMB_SAMPLES : usize = 8 * 48000;
#[derive(Debug, Clone)]
#[derive(Debug, Clone, Default)]
pub struct AllPass {
delay: DelayBuffer,
}
@ -1289,7 +1289,7 @@ pub fn process_stilson_moog(
// translated from Odin 2 Synthesizer Plugin
// Copyright (C) 2020 TheWaveWarden
// under GPLv3 or any later
#[derive(Debug, Clone)]
#[derive(Debug, Clone, Copy)]
pub struct DCBlockFilter {
xm1: f64,
ym1: f64,
@ -1786,6 +1786,8 @@ pub struct TriSawLFO {
/// Precomputed rise/fall rate of the LFO.
rise_r: f64,
fall_r: f64,
/// Initial phase offset.
init_phase: f64,
}
impl TriSawLFO {
@ -1798,11 +1800,17 @@ impl TriSawLFO {
freq: 1.0,
fall_r: 0.0,
rise_r: 0.0,
init_phase: 0.0,
};
this.recalc();
this
}
pub fn set_phase_offs(&mut self, phase: f64) {
self.init_phase = phase;
self.phase = phase;
}
#[inline]
fn recalc(&mut self) {
self.rev = self.rev.clamp(0.0001, 0.999);
@ -1816,7 +1824,7 @@ impl TriSawLFO {
}
pub fn reset(&mut self) {
self.phase = 0.0;
self.phase = self.init_phase;
self.rev = 0.5;
self.rising = true;
}