From 3d2c4c0c749fd322eeb57db602a1a3786039f2f9 Mon Sep 17 00:00:00 2001 From: Weird Constructor Date: Fri, 6 Aug 2021 06:05:13 +0200 Subject: [PATCH] Started implementing the Dattorro plate reverb --- src/dsp/dattorro.rs | 27 +++++++++++ src/dsp/helpers.rs | 112 ++++++++++++++++++++++++++++++++++++++++++++ src/dsp/mod.rs | 1 + 3 files changed, 140 insertions(+) diff --git a/src/dsp/dattorro.rs b/src/dsp/dattorro.rs index 7f6d9a7..b03027b 100644 --- a/src/dsp/dattorro.rs +++ b/src/dsp/dattorro.rs @@ -9,4 +9,31 @@ // ValleyRackFree Copyright (C) 2020, Valley Audio Soft, Dale Johnson // Adapted under the GPL-3.0-or-later License. +use crate::dsp::helpers::{ + AllPass, + TriSawLFO, + OnePoleLPF, + OnePoleHPF, + DelayBuffer, + DCBlockFilter +}; +pub struct DattorroReverb { + inp_dc_block: [DCBlockFilter; 2], + out_dc_block: [DCBlockFilter; 2], + + lfos: [TriSawLFO; 4], + + input_hpf: OnePoleHPF, + input_lpf: OnePoleLPF, + + pre_delay: DelayBuffer, + input_apfs: [AllPass; 4], + + apf1: [AllPass; 2], + hpf: [OnePoleHPF; 2], + lpf: [OnePoleLPF; 2], + apf2: [AllPass; 2], + delay1: [DelayBuffer; 2], + delay2: [DelayBuffer; 2], +} diff --git a/src/dsp/helpers.rs b/src/dsp/helpers.rs index e2d9456..55e1293 100644 --- a/src/dsp/helpers.rs +++ b/src/dsp/helpers.rs @@ -844,6 +844,56 @@ pub fn process_1pole_lowpass(input: f32, freq: f32, israte: f32, z: &mut f32) -> *z } +#[derive(Debug, Clone, Copy, Default)] +pub struct OnePoleLPF { + israte: f32, + a: f32, + b: f32, + freq: f32, + z: f32, +} + +impl OnePoleLPF { + pub fn new() -> Self { + Self { + israte: 1.0 / 44100.0, + a: 0.0, + b: 0.0, + freq: 1000.0, + z: 0.0, + } + } + + pub fn reset(&mut self) { + self.z = 0.0; + } + + #[inline] + fn recalc(&mut self) { + self.b = (-std::f32::consts::TAU * self.freq * self.israte).exp(); + self.a = 1.0 - self.b; + } + + pub fn set_sample_rate(&mut self, srate: f32) { + self.israte = 1.0 / srate; + self.recalc(); + } + + #[inline] + pub fn set_freq(&mut self, freq: f32) { + if freq != self.freq { + self.freq = freq; + self.recalc(); + } + } + + #[inline] + pub fn process(&mut self, input: f32) -> f32 { + self.z = self.a * input + self.z * self.b; + self.z + } +} + // one pole hp from valley rack free: // https://github.com/ValleyAudio/ValleyRackFree/blob/v1.0/src/Common/DSP/OnePoleFilters.cpp #[inline] @@ -883,6 +933,68 @@ pub fn process_1pole_highpass(input: f32, freq: f32, israte: f32, z: &mut f32, y v } +#[derive(Debug, Clone, Copy, Default)] +pub struct OnePoleHPF { + israte: f32, + a: f32, + b: f32, + freq: f32, + z: f32, + y: f32, +} + +impl OnePoleHPF { + pub fn new() -> Self { + Self { + israte: 1.0 / 44100.0, + a: 0.0, + b: 0.0, + freq: 1000.0, + z: 0.0, + y: 0.0, + } + } + + pub fn reset(&mut self) { + self.z = 0.0; + self.y = 0.0; + } + + #[inline] + fn recalc(&mut self) { + self.b = (-std::f32::consts::TAU * self.freq * self.israte).exp(); + self.a = (1.0 + self.b) / 2.0; + } + + + pub fn set_sample_rate(&mut self, srate: f32) { + self.israte = 1.0 / srate; + self.recalc(); + } + + #[inline] + pub fn set_freq(&mut self, freq: f32) { + if freq != self.freq { + self.freq = freq; + self.recalc(); + } + } + + #[inline] + pub fn process(&mut self, input: f32) -> f32 { + let v = + self.a * input + - self.a * self.z + + self.b * self.y; + + self.y = v; + self.z = input; + + v + } +} + + // one pole from: // http://www.willpirkle.com/Downloads/AN-4VirtualAnalogFilters.pdf // (page 5) diff --git a/src/dsp/mod.rs b/src/dsp/mod.rs index 6d7ecb6..ac25490 100644 --- a/src/dsp/mod.rs +++ b/src/dsp/mod.rs @@ -45,6 +45,7 @@ mod node_tslfo; pub mod biquad; pub mod tracker; +pub mod dattorro; mod satom; pub mod helpers;