From 3d099f884c2a487b9615a4061924a3c67484cb40 Mon Sep 17 00:00:00 2001 From: Weird Constructor Date: Sat, 10 Jul 2021 22:34:03 +0200 Subject: [PATCH] added RC filter implementation --- src/dsp/mod.rs | 2 +- src/dsp/node_sfilter.rs | 29 ++++++++++++++++++++++++++--- tests/node_sfilter.rs | 8 ++++++++ 3 files changed, 35 insertions(+), 4 deletions(-) diff --git a/src/dsp/mod.rs b/src/dsp/mod.rs index 0ff1914..26cc353 100644 --- a/src/dsp/mod.rs +++ b/src/dsp/mod.rs @@ -582,7 +582,7 @@ macro_rules! node_list { sfilter => SFilter UIType::Generic UICategory::Signal (0 inp n_id d_id r_id f_def stp_d -1.0, 1.0, 0.0) (1 freq n_pit d_pit r_fq f_freq stp_d -1.0, 0.5647131, 1000.0) - {2 0 ftype setting(0) fa_sfilter_type 0 2} + {2 0 ftype setting(0) fa_sfilter_type 0 3} [0 sig], test => Test UIType::Generic UICategory::IOUtil (0 f n_id d_id r_id f_def stp_d 0.0, 1.0, 0.5) diff --git a/src/dsp/node_sfilter.rs b/src/dsp/node_sfilter.rs index 150e86c..bdc7900 100644 --- a/src/dsp/node_sfilter.rs +++ b/src/dsp/node_sfilter.rs @@ -9,8 +9,10 @@ use crate::dsp::{NodeId, SAtom, ProcBuf, DspNode, LedPhaseVals, NodeContext}; macro_rules! fa_sfilter_type { ($formatter: expr, $v: expr, $denorm_v: expr) => { { let s = match ($v.round() as usize) { - 0 => "LP(1p)", - 1 => "HP(1p)", + 0 => "LPDat(1p)", + 1 => "LPSVF(1p)", + 2 => "LPDAFX(1p)", + 3 => "RC", _ => "?", }; write!($formatter, "{}", s) @@ -21,6 +23,7 @@ macro_rules! fa_sfilter_type { ($formatter: expr, $v: expr, $denorm_v: expr) => pub struct SFilter { israte: f64, z: f64, + y: f64, } impl SFilter { @@ -28,6 +31,7 @@ impl SFilter { Self { israte: 1.0 / 44100.0, z: 0.0, + y: 0.0, } } pub const inp : &'static str = @@ -57,6 +61,7 @@ impl DspNode for SFilter { } fn reset(&mut self) { self.z = 0.0; + self.y = 0.0; } #[inline] @@ -124,7 +129,25 @@ impl DspNode for SFilter { self.z = a * input - b * self.z; out.write(frame, self.z as f32); } - } + }, + // From https://en.wikipedia.org/wiki/RC_circuit + 3 => { + for frame in 0..ctx.nframes() { + let input = inp.read(frame) as f64; + let c = + 2.0 + / (std::f64::consts::TAU + * (denorm::SFilter::freq(freq, frame) as f64) + * self.israte); + + let y = (input + self.z - self.y * (1.0 - c)) / (1.0 + c); + self.z = input; + self.y = y; + + // highpass: self.z - self.y + out.write(frame, y as f32); + } + }, _ => {}, } } diff --git a/tests/node_sfilter.rs b/tests/node_sfilter.rs index d863419..5ba9f68 100644 --- a/tests/node_sfilter.rs +++ b/tests/node_sfilter.rs @@ -53,6 +53,14 @@ fn check_node_sfilter_compare() { let ta = std::time::Instant::now().duration_since(ta); println!("ta3 Elapsed: {:?}", ta); + pset_s(&mut matrix, sf, "ftype", 3); + + let ta = std::time::Instant::now(); + let (out_l, _) = run_for_ms(&mut node_exec, 10000.0); + save_wav("check_noise_sfilt4.wav", &out_l); + let ta = std::time::Instant::now().duration_since(ta); + println!("ta4 Elapsed: {:?}", ta); + // let fft = run_and_get_fft4096(&mut node_exec, 5, 1000.0); // for (fq, lvl) in fft { // println!("{:5}: {}", fq, lvl);