diff --git a/src/dsp/mod.rs b/src/dsp/mod.rs index 4b0b35b..3aa73e6 100644 --- a/src/dsp/mod.rs +++ b/src/dsp/mod.rs @@ -513,7 +513,7 @@ mod node_map; #[allow(non_upper_case_globals)] mod node_midicc; #[allow(non_upper_case_globals)] -mod node_exta; +mod node_ext; #[allow(non_upper_case_globals)] mod node_midip; #[allow(non_upper_case_globals)] @@ -607,7 +607,12 @@ use node_fbwr_fbrd::FbWr; use node_formfm::FormFM; use node_map::Map; use node_midicc::MidiCC; -use node_exta::ExtA; +use node_ext::ExtA; +use node_ext::ExtB; +use node_ext::ExtC; +use node_ext::ExtD; +use node_ext::ExtE; +use node_ext::ExtF; use node_midip::MidiP; use node_mix3::Mix3; use node_mux9::Mux9; @@ -1460,6 +1465,46 @@ macro_rules! node_list { [0 sig1] [1 sig2] [2 sig3], + extb => ExtB UIType::Generic UICategory::IOUtil + (0 slew n_timz d_timz r_tmz f_ms stp_m 0.0, 1.0, 0.0) + (1 atv1 n_id d_id r_id f_def stp_d -1.0, 1.0, 1.0) + (2 atv2 n_id d_id r_id f_def stp_d -1.0, 1.0, 1.0) + (3 atv3 n_id d_id r_id f_def stp_d -1.0, 1.0, 1.0) + [0 sig1] + [1 sig2] + [2 sig3], + extc => ExtC UIType::Generic UICategory::IOUtil + (0 slew n_timz d_timz r_tmz f_ms stp_m 0.0, 1.0, 0.0) + (1 atv1 n_id d_id r_id f_def stp_d -1.0, 1.0, 1.0) + (2 atv2 n_id d_id r_id f_def stp_d -1.0, 1.0, 1.0) + (3 atv3 n_id d_id r_id f_def stp_d -1.0, 1.0, 1.0) + [0 sig1] + [1 sig2] + [2 sig3], + extd => ExtD UIType::Generic UICategory::IOUtil + (0 slew n_timz d_timz r_tmz f_ms stp_m 0.0, 1.0, 0.0) + (1 atv1 n_id d_id r_id f_def stp_d -1.0, 1.0, 1.0) + (2 atv2 n_id d_id r_id f_def stp_d -1.0, 1.0, 1.0) + (3 atv3 n_id d_id r_id f_def stp_d -1.0, 1.0, 1.0) + [0 sig1] + [1 sig2] + [2 sig3], + exte => ExtE UIType::Generic UICategory::IOUtil + (0 slew n_timz d_timz r_tmz f_ms stp_m 0.0, 1.0, 0.0) + (1 atv1 n_id d_id r_id f_def stp_d -1.0, 1.0, 1.0) + (2 atv2 n_id d_id r_id f_def stp_d -1.0, 1.0, 1.0) + (3 atv3 n_id d_id r_id f_def stp_d -1.0, 1.0, 1.0) + [0 sig1] + [1 sig2] + [2 sig3], + extf => ExtF UIType::Generic UICategory::IOUtil + (0 slew n_timz d_timz r_tmz f_ms stp_m 0.0, 1.0, 0.0) + (1 atv1 n_id d_id r_id f_def stp_d -1.0, 1.0, 1.0) + (2 atv2 n_id d_id r_id f_def stp_d -1.0, 1.0, 1.0) + (3 atv3 n_id d_id r_id f_def stp_d -1.0, 1.0, 1.0) + [0 sig1] + [1 sig2] + [2 sig3], out => Out UIType::Generic UICategory::IOUtil (0 ch1 n_id d_id r_id f_def stp_d -1.0, 1.0, 0.0) (1 ch2 n_id d_id r_id f_def stp_d -1.0, 1.0, 0.0) diff --git a/src/dsp/node_ext.rs b/src/dsp/node_ext.rs new file mode 100644 index 0000000..86761fe --- /dev/null +++ b/src/dsp/node_ext.rs @@ -0,0 +1,109 @@ +// Copyright (c) 2022 Weird Constructor +// This file is a part of HexoDSP. Released under GPL-3.0-or-later. +// See README.md and COPYING for details. + +use crate::dsp::{ + denorm, inp, out_idx, DspNode, LedPhaseVals, NodeContext, NodeId, ProcBuf, SAtom, +}; +use crate::nodes::{NodeAudioContext, NodeExecContext}; +use synfx_dsp::SlewValue; + + +macro_rules! define_ext { + ($name: ident, $p1: ident, $p2: ident, $p3: ident) => { + #[derive(Debug, Clone)] + pub struct $name { + slew1: SlewValue, + slew2: SlewValue, + slew3: SlewValue, + } + + impl $name { + pub fn new(_nid: &NodeId) -> Self { + Self { slew1: SlewValue::new(), slew2: SlewValue::new(), slew3: SlewValue::new() } + } + + pub const slew: &'static str = "ExtA-F slew\nSlew limiter for the 3 parameters\nRange: (0..1)"; + pub const atv1: &'static str = "ExtA-F atv1\nAttenuverter for the A1 parameter\nRange: (-1..1)"; + pub const atv2: &'static str = "ExtA-F atv2\nAttenuverter for the A2 parameter\nRange: (-1..1)"; + pub const atv3: &'static str = "ExtA-F atv3\nAttenuverter for the A3 parameter\nRange: (-1..1)"; + + pub const sig1: &'static str = "ExtA-F sig1\nA1 output channel\nRange: (-1..1)"; + pub const sig2: &'static str = "ExtA-F sig2\nA2 output channel\nRange: (-1..1)"; + pub const sig3: &'static str = "ExtA-F sig3\nA3 output channel\nRange: (-1..1)"; + + pub const DESC: &'static str = "External Parameter Set A-F Input\n\n\ + \ + \ + \ + "; + pub const HELP: &'static str = r#"External Parameter Set A-F Input + "#; + } + + impl DspNode for $name { + fn outputs() -> usize { + 0 + } + + fn set_sample_rate(&mut self, _srate: f32) {} + fn reset(&mut self) {} + + #[inline] + fn process( + &mut self, + ctx: &mut T, + ectx: &mut NodeExecContext, + _nctx: &NodeContext, + _atoms: &[SAtom], + inputs: &[ProcBuf], + outputs: &mut [ProcBuf], + ctx_vals: LedPhaseVals, + ) { + let slew = inp::$name::slew(inputs); + let atv1 = inp::$name::atv1(inputs); + let atv2 = inp::$name::atv2(inputs); + let atv3 = inp::$name::atv3(inputs); + let sig2_i = out_idx::$name::sig2(); + let (sig1, r) = outputs.split_at_mut(sig2_i); + let (sig2, sig3) = r.split_at_mut(1); + let sig1 = &mut sig1[0]; + let sig2 = &mut sig2[0]; + let sig3 = &mut sig3[0]; + + if let Some(params) = &ectx.ext_param { + let p1 = params.$p1(); + let p2 = params.$p2(); + let p3 = params.$p3(); + + for frame in 0..ctx.nframes() { + let slew_ms = denorm::$name::slew(slew, frame); + sig1.write( + frame, + denorm::$name::atv1(atv1, frame) * self.slew1.next(p1, slew_ms), + ); + sig2.write( + frame, + denorm::$name::atv2(atv2, frame) * self.slew2.next(p2, slew_ms), + ); + sig3.write( + frame, + denorm::$name::atv3(atv3, frame) * self.slew3.next(p3, slew_ms), + ); + } + } + + let last_frame = ctx.nframes() - 1; + ctx_vals[0].set(sig1.read(last_frame)); + } + } + + } +} + +define_ext! {ExtA, a1, a2, a3} +define_ext! {ExtB, b1, b2, b3} +define_ext! {ExtC, c1, c2, c3} +define_ext! {ExtD, d1, d2, d3} +define_ext! {ExtE, e1, e2, e3} +define_ext! {ExtF, f1, f2, f3} diff --git a/src/dsp/node_exta.rs b/src/dsp/node_exta.rs deleted file mode 100644 index 7f9c7d1..0000000 --- a/src/dsp/node_exta.rs +++ /dev/null @@ -1,94 +0,0 @@ -// Copyright (c) 2022 Weird Constructor -// This file is a part of HexoDSP. Released under GPL-3.0-or-later. -// See README.md and COPYING for details. - -use crate::dsp::{ - denorm, inp, out_idx, DspNode, LedPhaseVals, NodeContext, NodeId, ProcBuf, SAtom, -}; -use crate::nodes::{NodeAudioContext, NodeExecContext}; -use synfx_dsp::SlewValue; - -#[derive(Debug, Clone)] -pub struct ExtA { - slew1: SlewValue, - slew2: SlewValue, - slew3: SlewValue, -} - -impl ExtA { - pub fn new(_nid: &NodeId) -> Self { - Self { slew1: SlewValue::new(), slew2: SlewValue::new(), slew3: SlewValue::new() } - } -} - -impl DspNode for ExtA { - fn outputs() -> usize { - 0 - } - - fn set_sample_rate(&mut self, _srate: f32) {} - fn reset(&mut self) {} - - #[inline] - fn process( - &mut self, - ctx: &mut T, - ectx: &mut NodeExecContext, - _nctx: &NodeContext, - _atoms: &[SAtom], - inputs: &[ProcBuf], - outputs: &mut [ProcBuf], - ctx_vals: LedPhaseVals, - ) { - let slew = inp::ExtA::slew(inputs); - let atv1 = inp::ExtA::atv1(inputs); - let atv2 = inp::ExtA::atv2(inputs); - let atv3 = inp::ExtA::atv3(inputs); - let sig2_i = out_idx::ExtA::sig2(); - let (sig1, r) = outputs.split_at_mut(sig2_i); - let (sig2, sig3) = r.split_at_mut(1); - let sig1 = &mut sig1[0]; - let sig2 = &mut sig2[0]; - let sig3 = &mut sig3[0]; - - if let Some(params) = &ectx.ext_param { - for frame in 0..ctx.nframes() { - let slew_ms = denorm::ExtA::slew(slew, frame); - sig1.write( - frame, - denorm::ExtA::atv1(atv1, frame) * self.slew1.next(params.a1(), slew_ms), - ); - sig2.write( - frame, - denorm::ExtA::atv2(atv2, frame) * self.slew2.next(params.a2(), slew_ms), - ); - sig3.write( - frame, - denorm::ExtA::atv3(atv3, frame) * self.slew3.next(params.a3(), slew_ms), - ); - } - } - - let last_frame = ctx.nframes() - 1; - ctx_vals[0].set(sig1.read(last_frame)); - } -} - -impl ExtA { - pub const slew: &'static str = "ExtA slew\nSlew limiter for the 3 parameters\nRange: (0..1)"; - pub const atv1: &'static str = "ExtA atv1\nAttenuverter for the A1 parameter\nRange: (-1..1)"; - pub const atv2: &'static str = "ExtA atv2\nAttenuverter for the A2 parameter\nRange: (-1..1)"; - pub const atv3: &'static str = "ExtA atv3\nAttenuverter for the A3 parameter\nRange: (-1..1)"; - - pub const sig1: &'static str = "ExtA sig1\nA1 output channel\nRange: (-1..1)"; - pub const sig2: &'static str = "ExtA sig2\nA2 output channel\nRange: (-1..1)"; - pub const sig3: &'static str = "ExtA sig3\nA3 output channel\nRange: (-1..1)"; - - pub const DESC: &'static str = "External Parameter Set A Input\n\n\ - \ - \ - \ - "; - pub const HELP: &'static str = r#"External Parameter Set A Input -"#; -} diff --git a/src/nodes/node_exec.rs b/src/nodes/node_exec.rs index 15bd9a5..46a7a2f 100644 --- a/src/nodes/node_exec.rs +++ b/src/nodes/node_exec.rs @@ -181,6 +181,21 @@ pub trait ExternalParams: Send + Sync { fn a1(&self) -> f32; fn a2(&self) -> f32; fn a3(&self) -> f32; + fn b1(&self) -> f32 { self.a1() } + fn b2(&self) -> f32 { self.a2() } + fn b3(&self) -> f32 { self.a3() } + fn c1(&self) -> f32 { self.a1() } + fn c2(&self) -> f32 { self.a2() } + fn c3(&self) -> f32 { self.a3() } + fn d1(&self) -> f32 { self.a1() } + fn d2(&self) -> f32 { self.a2() } + fn d3(&self) -> f32 { self.a3() } + fn e1(&self) -> f32 { self.a1() } + fn e2(&self) -> f32 { self.a2() } + fn e3(&self) -> f32 { self.a3() } + fn f1(&self) -> f32 { self.a1() } + fn f2(&self) -> f32 { self.a2() } + fn f3(&self) -> f32 { self.a3() } } /// Contains global state that all nodes can access. diff --git a/tests/node_exta.rs b/tests/node_exta.rs index 6324679..5e8ede9 100644 --- a/tests/node_exta.rs +++ b/tests/node_exta.rs @@ -79,3 +79,65 @@ fn check_node_exta() { ] ); } + +#[test] +fn check_node_exta_slew() { + let (node_conf, mut node_exec) = new_node_engine(); + let mut matrix = Matrix::new(node_conf, 3, 3); + + let myparams = std::sync::Arc::new(MyParams {}); + + let mut chain = MatrixCellChain::new(CellDir::B); + chain + .node_out("exta", "sig1") + .set_denorm("slew", 40.0) + .node_inp("out", "ch1") + .place(&mut matrix, 0, 0) + .unwrap(); + let mut chain = MatrixCellChain::new(CellDir::B); + chain + .node_out("exta", "sig3") + .set_denorm("slew", 40.0) + .node_inp("out", "ch2") + .place(&mut matrix, 1, 0) + .unwrap(); + matrix.sync().unwrap(); + + node_exec.set_external_params(myparams); + + let (ch1, ch2) = node_exec.test_run(0.1, false, &[]); + assert_decimated_feq!( + ch1, + 80, + vec![ + 0.00056689343, + 0.045918357, + 0.09126975, + 0.13662128, + 0.18197326, + 0.22732525, + 0.23, + 0.23, + 0.23, + 0.23, + 0.23 + ] + ); + assert_decimated_feq!( + ch2, + 80, + vec![ + -0.00056689343, + -0.045918357, + -0.09126975, + -0.13662128, + -0.18197326, + -0.22732525, + -0.2726772, + -0.3180292, + -0.33, + -0.33, + -0.33 + ] + ); +}