From 1a1512a0325ba5a8179d669782c78c095bc2d27f Mon Sep 17 00:00:00 2001 From: Weird Constructor Date: Thu, 18 Aug 2022 19:46:32 +0200 Subject: [PATCH] Added 'det' detune parameter to FormFM oscillator --- src/dsp/mod.rs | 7 ++++--- src/dsp/node_formfm.rs | 8 +++++--- src/dsp/node_sin.rs | 2 +- tests/node_formfm.rs | 35 +++++++++++++++++++++++++++++++++++ 4 files changed, 45 insertions(+), 7 deletions(-) diff --git a/src/dsp/mod.rs b/src/dsp/mod.rs index c41d73b..c307717 100644 --- a/src/dsp/mod.rs +++ b/src/dsp/mod.rs @@ -1527,9 +1527,10 @@ macro_rules! node_list { [0 sig], formfm => FormFM UIType::Generic UICategory::Osc (0 freq n_pit d_pit r_fq f_freq stp_d -1.0, 0.5647131, 440.0) - (1 form n_pit d_pit r_fq f_freq stp_d -1.0, 0.5647131, 440.0) - (2 side n_id d_id r_id f_def stp_d 0.0, 1.0, 0.2) - (3 peak n_id d_id r_id f_def stp_d 0.0, 1.0, 0.4) + (1 det n_det d_det r_det f_det stp_f -0.2, 0.2, 0.0) + (2 form n_pit d_pit r_fq f_freq stp_d -1.0, 0.5647131, 440.0) + (3 side n_id d_id r_id f_def stp_d 0.0, 1.0, 0.2) + (4 peak n_id d_id r_id f_def stp_d 0.0, 1.0, 0.4) [0 sig], sfilter => SFilter UIType::Generic UICategory::Signal (0 inp n_id d_id r_id f_def stp_d -1.0, 1.0, 0.0) diff --git a/src/dsp/node_formfm.rs b/src/dsp/node_formfm.rs index b53ec01..cc141bf 100644 --- a/src/dsp/node_formfm.rs +++ b/src/dsp/node_formfm.rs @@ -16,7 +16,8 @@ impl FormFM { pub fn new(_nid: &NodeId) -> Self { Self { inv_sample_rate: 1.0 / 44100.0, phase: 0.0 } } - pub const freq: &'static str = "Formant freq\nBase frequency to oscilate at\n"; + pub const freq: &'static str = "Formant freq\nBase frequency to oscillate at\n"; + pub const det: &'static str = "Formant det\nDetune the oscillator in semitones and cents.\n"; pub const form: &'static str = "Formant form\nFrequency of the formant\nThis affects how much lower or higher tones the sound has."; pub const side: &'static str = "Formant side\nWhich side the peak of the wave is. Values more towards 0.0 or 1.0 make the base frequency more pronounced"; @@ -74,9 +75,10 @@ impl DspNode for FormFM { outputs: &mut [ProcBuf], _ctx_vals: LedPhaseVals, ) { - use crate::dsp::{denorm, inp, out}; + use crate::dsp::{denorm, denorm_offs, inp, out}; let base_freq = inp::FormFM::freq(inputs); + let det = inp::FormFM::det(inputs); let formant_freq = inp::FormFM::form(inputs); let side_val = inp::FormFM::side(inputs); let peak_val = inp::FormFM::peak(inputs); @@ -84,7 +86,7 @@ impl DspNode for FormFM { for frame in 0..ctx.nframes() { // get the inputs - let base_freq = denorm::FormFM::freq(base_freq, frame); + let base_freq = denorm_offs::FormFM::freq(base_freq, det.read(frame), frame); let formant_freq = denorm::FormFM::form(formant_freq, frame); let side_val = denorm::FormFM::side(side_val, frame).min(1.0 - 1e-6).max(1e-6); let peak_val = denorm::FormFM::peak(peak_val, frame); diff --git a/src/dsp/node_sin.rs b/src/dsp/node_sin.rs index 3988b40..b6cbd3f 100644 --- a/src/dsp/node_sin.rs +++ b/src/dsp/node_sin.rs @@ -88,7 +88,7 @@ impl DspNode for Sin { let mut last_val = 0.0; for frame in 0..ctx.nframes() { - let freq = denorm_offs::Sampl::freq(freq, det.read(frame), frame); + let freq = denorm_offs::Sin::freq(freq, det.read(frame), frame); last_val = fast_sin(self.phase * TWOPI); o.write(frame, last_val); diff --git a/tests/node_formfm.rs b/tests/node_formfm.rs index dc728e6..fb97d3e 100644 --- a/tests/node_formfm.rs +++ b/tests/node_formfm.rs @@ -162,3 +162,38 @@ fn check_formant_freq() { let fft = run_and_get_avg_fft4096_now(&mut node_exec, 100); assert_eq!(fft, vec![(323, 106), (334, 131), (431, 430), (441, 708), (452, 288), (549, 140)]); } + +#[test] +fn check_formant_freq_det() { + let (node_conf, mut node_exec) = new_node_engine(); + + let mut matrix = Matrix::new(node_conf, 3, 3); + + let mut chain = MatrixCellChain::new(CellDir::B); + chain + .node_out("formfm", "sig") + .set_denorm("det", 0.1) + .node_inp("out", "ch1") + .place(&mut matrix, 0, 0) + .unwrap(); + + matrix.sync().unwrap(); + + let formant = NodeId::FormFM(0); + + // params + let freq_p = formant.inp_param("freq").unwrap(); + let form_p = formant.inp_param("form").unwrap(); + let side_p = formant.inp_param("side").unwrap(); + let peak_p = formant.inp_param("peak").unwrap(); + + // set params to reasonable values + matrix.set_param(freq_p, SAtom::param(-0.2)); + matrix.set_param(form_p, SAtom::param(0.0)); + matrix.set_param(side_p, SAtom::param(0.2)); + matrix.set_param(peak_p, SAtom::param(0.4)); + + // run + let fft = run_and_get_avg_fft4096_now(&mut node_exec, 100); + assert_eq!(fft, vec![(334, 146), (431, 297), (441, 696), (452, 406), (549, 127), (560, 107)]); +}