diff --git a/src/matrix.rs b/src/matrix.rs index 34a2320..a4a20bf 100644 --- a/src/matrix.rs +++ b/src/matrix.rs @@ -1236,4 +1236,87 @@ mod tests { output2: (NodeId::Sin(2), 0), })); } + + #[test] + fn check_matrix_mod_amt_pre_sync() { + use crate::nodes::new_node_engine; + + let (node_conf, mut node_exec) = new_node_engine(); + let mut matrix = Matrix::new(node_conf, 3, 3); + + matrix.place(0, 0, + Cell::empty(NodeId::Sin(0)) + .out(None, Some(0), None)); + matrix.place(1, 0, + Cell::empty(NodeId::Sin(1)) + .input(None, Some(0), None) + .out(None, None, Some(0))); + matrix.place(0, 1, + Cell::empty(NodeId::Sin(3)) + .input(None, None, None) + .out(None, Some(0), None)); + matrix.place(1, 1, + Cell::empty(NodeId::Sin(2)) + .input(Some(0), Some(1), None)); + matrix.set_param_modamt( + NodeId::Sin(1).param_by_idx(0).unwrap(), + Some(0.5)).unwrap(); + matrix.set_param_modamt( + NodeId::Sin(1).param_by_idx(1).unwrap(), + Some(0.33)).unwrap(); + matrix.set_param_modamt( + NodeId::Sin(0).param_by_idx(0).unwrap(), + Some(0.25)).unwrap(); + matrix.set_param_modamt( + NodeId::Sin(2).param_by_idx(0).unwrap(), + Some(0.75)).unwrap(); + matrix.set_param_modamt( + NodeId::Sin(2).param_by_idx(1).unwrap(), + Some(-0.75)).unwrap(); + matrix.sync().unwrap(); + + node_exec.process_graph_updates(); + + let prog = node_exec.get_prog(); + assert_eq!(prog.prog[0].to_string(), "Op(i=0 out=(0-1) in=(0-2) at=(0-0) mod=(0-1))"); + assert_eq!(prog.prog[1].to_string(), "Op(i=3 out=(3-4) in=(6-8) at=(0-0) mod=(5-5))"); + assert_eq!(prog.prog[2].to_string(), "Op(i=1 out=(1-2) in=(2-4) at=(0-0) mod=(1-3) cpy=(o0 => i2) mod=1)"); + assert_eq!(prog.prog[3].to_string(), "Op(i=2 out=(2-3) in=(4-6) at=(0-0) mod=(3-5) cpy=(o1 => i4) cpy=(o3 => i5) mod=3 mod=4)"); + } + + #[test] + fn check_matrix_mod_amt_post_sync() { + use crate::nodes::new_node_engine; + + let (node_conf, mut node_exec) = new_node_engine(); + let mut matrix = Matrix::new(node_conf, 3, 3); + + matrix.place(0, 0, + Cell::empty(NodeId::Sin(0)) + .out(None, Some(0), None)); + matrix.place(1, 0, + Cell::empty(NodeId::Sin(1)) + .input(None, Some(0), None) + .out(None, None, Some(0))); + matrix.place(1, 1, + Cell::empty(NodeId::Sin(2)) + .input(Some(0), None, None)); + matrix.sync().unwrap(); + matrix.set_param_modamt( + NodeId::Sin(1).param_by_idx(0).unwrap(), + Some(0.5)).unwrap(); + matrix.set_param_modamt( + NodeId::Sin(1).param_by_idx(1).unwrap(), + Some(0.33)).unwrap(); + matrix.set_param_modamt( + NodeId::Sin(0).param_by_idx(0).unwrap(), + Some(0.25)).unwrap(); + + node_exec.process_graph_updates(); + + let prog = node_exec.get_prog(); + assert_eq!(prog.prog[0].to_string(), "Op(i=0 out=(0-1) in=(0-2) at=(0-0) mod=(0-1))"); + assert_eq!(prog.prog[1].to_string(), "Op(i=1 out=(1-2) in=(2-4) at=(0-0) mod=(1-3) cpy=(o0 => i2) mod=1)"); + assert_eq!(prog.prog[2].to_string(), "Op(i=2 out=(2-3) in=(4-6) at=(0-0) mod=(3-3) cpy=(o1 => i4))"); + } } diff --git a/src/nodes/mod.rs b/src/nodes/mod.rs index fa6f45b..c430b31 100644 --- a/src/nodes/mod.rs +++ b/src/nodes/mod.rs @@ -54,9 +54,9 @@ pub enum GraphMessage { /// and the NodeConfigurator. #[derive(Debug)] pub enum QuickMessage { - AtomUpdate { at_idx: usize, value: SAtom }, + AtomUpdate { at_idx: usize, value: SAtom }, ParamUpdate { input_idx: usize, value: f32 }, - ModamtUpdate { input_idx: usize, mod_idx: usize, modamt: f32 }, + ModamtUpdate { mod_idx: usize, modamt: f32 }, /// Sets the buffer indices to monitor with the FeedbackProcessor. SetMonitor { bufs: [usize; MON_SIG_CNT], }, } diff --git a/src/nodes/node_conf.rs b/src/nodes/node_conf.rs index 9f15f11..1db8578 100644 --- a/src/nodes/node_conf.rs +++ b/src/nodes/node_conf.rs @@ -4,7 +4,7 @@ use super::{ GraphMessage, QuickMessage, - NodeProg, ModOpSigRange, NodeOp, + NodeProg, NodeOp, FeedbackFilter, MAX_ALLOCATED_NODES, MAX_INPUTS, @@ -348,12 +348,9 @@ impl NodeConfigurator { return false; } - let mut input_idx = None; - let mut mod_idx = None; + let mut mod_idx = None; if let Some(nparam) = self.params.get_mut(¶m) { - input_idx = Some(nparam.input_idx); - if let Some(modamt) = &mut nparam.modamt { mod_idx = Some(modamt.0); modamt.1 = v.unwrap_or(0.0); @@ -373,17 +370,10 @@ impl NodeConfigurator { let modamt = v.unwrap(); self.param_modamt.insert(param, v); - // TODO: Check if the ModamtUpdate message really needs - // the input_idx once the NodeExecutor backend - // code for that message has been implemented! - if let Some(input_idx) = input_idx { - if let Some(mod_idx) = mod_idx { - let _ = - self.shared.quick_update_prod.push( - QuickMessage::ModamtUpdate { - input_idx, mod_idx, modamt - }); - } + if let Some(mod_idx) = mod_idx { + let _ = + self.shared.quick_update_prod.push( + QuickMessage::ModamtUpdate { mod_idx, modamt }); } false @@ -876,10 +866,7 @@ impl NodeConfigurator { // After iterating through the parameters we can // store the range of the indices of this node. - node_instance - .as_mut() - .unwrap() - .set_mod(mod_idx, mod_len); + node_instance.as_mut().unwrap().set_mod(mod_idx, mod_len); // Create new atom data and initialize it if it did not // already exist from a previous matrix instance. @@ -958,13 +945,11 @@ impl NodeConfigurator { if let (Some(input_index), Some(output_index)) = (input_index, output_index) { - // TODO: Fetch output signal range from adjacent_output! - prog.append_edge( op, input_index, output_index, - mod_index.map(|amt| (amt, ModOpSigRange::Unipolar))); + mod_index); } } } diff --git a/src/nodes/node_prog.rs b/src/nodes/node_prog.rs index 5f1c3a7..578e064 100644 --- a/src/nodes/node_prog.rs +++ b/src/nodes/node_prog.rs @@ -5,25 +5,9 @@ use crate::dsp::{ProcBuf, SAtom}; use triple_buffer::{Input, Output, TripleBuffer}; -#[derive(Debug, Clone, Copy)] -pub enum ModOpSigRange { - Unipolar, - Bipolar, -} - -impl std::fmt::Display for ModOpSigRange { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - match self { - ModOpSigRange::Unipolar => write!(f, "SigRange::Unipolar"), - ModOpSigRange::Bipolar => write!(f, "SigRange::Bipolar"), - } - } -} - #[derive(Debug, Clone)] pub struct ModOp { amount: f32, - range: ModOpSigRange, modbuf: ProcBuf, outbuf: ProcBuf, inbuf: ProcBuf, @@ -38,7 +22,6 @@ impl Drop for ModOp { impl ModOp { pub fn new() -> Self { Self { - range: ModOpSigRange::Unipolar, amount: 0.0, modbuf: ProcBuf::new(), outbuf: ProcBuf::null(), @@ -50,10 +33,6 @@ impl ModOp { self.amount = amt; } - pub fn set_range(&mut self, range: ModOpSigRange) { - self.range = range; - } - pub fn lock(&mut self, inbuf: ProcBuf, outbuf: ProcBuf) { self.inbuf = inbuf; self.outbuf = outbuf; @@ -70,24 +49,11 @@ impl ModOp { let inbuf = &mut self.inbuf; let outbuf = &mut self.outbuf; - match self.range { - ModOpSigRange::Bipolar => { - for frame in 0..nframes { - modbuf.write(frame, - modbuf.read(frame) - * ((outbuf.read(frame) + 1.0) * 0.5) - .clamp(0.0, 1.0) - + inbuf.read(frame)); - } - }, - ModOpSigRange::Unipolar => { - for frame in 0..nframes { - modbuf.write(frame, - modbuf.read(frame) - * outbuf.read(frame).clamp(0.0, 1.0) - + inbuf.read(frame)); - } - }, + for frame in 0..nframes { + modbuf.write(frame, + modbuf.read(frame) + * outbuf.read(frame) + + inbuf.read(frame)); } } } @@ -108,8 +74,8 @@ pub struct NodeOp { pub mod_idxlen: (usize, usize), /// Input indices, /// (, , - /// (, , )) - pub inputs: Vec<(usize, usize, Option<(usize, f32, ModOpSigRange)>)>, + /// (, )) + pub inputs: Vec<(usize, usize, Option)>, } impl std::fmt::Display for NodeOp { @@ -127,9 +93,11 @@ impl std::fmt::Display for NodeOp { for i in self.inputs.iter() { write!(f, " cpy=(o{} => i{})", i.0, i.1)?; + } - if let Some((idx, amt, rng)) = i.2 { - write!(f, " mod=({:6.4}/{} @{})", amt, rng, idx)?; + for i in self.inputs.iter() { + if let Some(idx) = i.2 { + write!(f, " mod={}", idx)?; } } @@ -279,18 +247,11 @@ impl NodeProg { node_op: NodeOp, inp_index: usize, out_index: usize, - mod_amt: Option<(usize, ModOpSigRange)>) + mod_index: Option) { for n_op in self.prog.iter_mut() { if n_op.idx == node_op.idx { - if let Some((idx, range)) = mod_amt { - self.modops[idx].set_range(range); - } - - n_op.inputs.push( - (out_index, - inp_index, - mod_amt.map(|(idx, sigrng)| (idx, 0.0, sigrng)))); + n_op.inputs.push((out_index, inp_index, mod_index)); return; } } @@ -366,10 +327,8 @@ impl NodeProg { for io in op.inputs.iter() { input_bufs[io.1] = out_bufs[io.0]; - if let Some((idx, _, _)) = io.2 { - self.modops[idx].lock( - self.inp[io.1], - out_bufs[io.0]); + if let Some(idx) = io.2 { + self.modops[idx].lock(self.inp[io.1], out_bufs[io.0]); } } }