Remove ModOpSigRange and test NodeProg dump output.

This commit is contained in:
Weird Constructor 2021-07-10 08:32:52 +02:00
parent 5d975c91a4
commit 4b8f3d67e7
4 changed files with 108 additions and 81 deletions

View file

@ -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))");
}
}

View file

@ -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], },
}

View file

@ -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(&param) {
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);
}
}
}

View file

@ -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,
/// (<out vec index>, <own node input index>,
/// (<mod index into NodeProg::modops>, <mod amt>, <mod sig type>))
pub inputs: Vec<(usize, usize, Option<(usize, f32, ModOpSigRange)>)>,
/// (<mod index into NodeProg::modops>, <mod amt>))
pub inputs: Vec<(usize, usize, Option<usize>)>,
}
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<usize>)
{
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]);
}
}
}