Started implementing the Dattorro plate reverb
This commit is contained in:
parent
a99c703781
commit
3d2c4c0c74
3 changed files with 140 additions and 0 deletions
|
@ -9,4 +9,31 @@
|
||||||
// ValleyRackFree Copyright (C) 2020, Valley Audio Soft, Dale Johnson
|
// ValleyRackFree Copyright (C) 2020, Valley Audio Soft, Dale Johnson
|
||||||
// Adapted under the GPL-3.0-or-later License.
|
// 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],
|
||||||
|
}
|
||||||
|
|
|
@ -844,6 +844,56 @@ pub fn process_1pole_lowpass(input: f32, freq: f32, israte: f32, z: &mut f32) ->
|
||||||
*z
|
*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:
|
// one pole hp from valley rack free:
|
||||||
// https://github.com/ValleyAudio/ValleyRackFree/blob/v1.0/src/Common/DSP/OnePoleFilters.cpp
|
// https://github.com/ValleyAudio/ValleyRackFree/blob/v1.0/src/Common/DSP/OnePoleFilters.cpp
|
||||||
#[inline]
|
#[inline]
|
||||||
|
@ -883,6 +933,68 @@ pub fn process_1pole_highpass(input: f32, freq: f32, israte: f32, z: &mut f32, y
|
||||||
v
|
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:
|
// one pole from:
|
||||||
// http://www.willpirkle.com/Downloads/AN-4VirtualAnalogFilters.pdf
|
// http://www.willpirkle.com/Downloads/AN-4VirtualAnalogFilters.pdf
|
||||||
// (page 5)
|
// (page 5)
|
||||||
|
|
|
@ -45,6 +45,7 @@ mod node_tslfo;
|
||||||
|
|
||||||
pub mod biquad;
|
pub mod biquad;
|
||||||
pub mod tracker;
|
pub mod tracker;
|
||||||
|
pub mod dattorro;
|
||||||
mod satom;
|
mod satom;
|
||||||
pub mod helpers;
|
pub mod helpers;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue