finished AD tests and added preliminary graph impl
This commit is contained in:
parent
32dd6468a8
commit
e13cf0834e
4 changed files with 106 additions and 9 deletions
|
@ -59,8 +59,9 @@ pub const MAX_BLOCK_SIZE : usize = 128;
|
||||||
/// This trait is an interface between the graph functions
|
/// This trait is an interface between the graph functions
|
||||||
/// and the AtomDataModel of the UI.
|
/// and the AtomDataModel of the UI.
|
||||||
pub trait GraphAtomData {
|
pub trait GraphAtomData {
|
||||||
fn get(&self, node_id: usize, param_idx: u32) -> Option<SAtom>;
|
fn get(&self, param_idx: u32) -> Option<SAtom>;
|
||||||
fn get_denorm(&self, node_id: usize, param_idx: u32) -> f32;
|
fn get_denorm(&self, param_idx: u32) -> f32;
|
||||||
|
fn get_norm(&self, param_idx: u32) -> f32;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub type GraphFun = Box<dyn FnMut(&dyn GraphAtomData, bool, f32) -> f32>;
|
pub type GraphFun = Box<dyn FnMut(&dyn GraphAtomData, bool, f32) -> f32>;
|
||||||
|
|
|
@ -3,7 +3,10 @@
|
||||||
// See README.md and COPYING for details.
|
// See README.md and COPYING for details.
|
||||||
|
|
||||||
use crate::nodes::{NodeAudioContext, NodeExecContext};
|
use crate::nodes::{NodeAudioContext, NodeExecContext};
|
||||||
use crate::dsp::{NodeId, SAtom, ProcBuf, DspNode, LedPhaseVals};
|
use crate::dsp::{
|
||||||
|
NodeId, SAtom, ProcBuf, DspNode, LedPhaseVals,
|
||||||
|
GraphAtomData, GraphFun,
|
||||||
|
};
|
||||||
use super::helpers::{Trigger, TrigSignal, sqrt4_to_pow4};
|
use super::helpers::{Trigger, TrigSignal, sqrt4_to_pow4};
|
||||||
|
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
|
@ -230,4 +233,18 @@ impl DspNode for Ad {
|
||||||
ctx_vals[0].set(self.value as f32);
|
ctx_vals[0].set(self.value as f32);
|
||||||
// ctx_vals[1].set(self.phase / self. + self.stage * );
|
// ctx_vals[1].set(self.phase / self. + self.stage * );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn graph_fun() -> Option<GraphFun> {
|
||||||
|
Some(Box::new(|gd: &dyn GraphAtomData, _init: bool, x: f32| -> f32 {
|
||||||
|
let atk_idx = NodeId::Ad(0).inp_param("atk").unwrap().inp();
|
||||||
|
let dcy_idx = NodeId::Ad(0).inp_param("dcy").unwrap().inp();
|
||||||
|
let ashp_idx = NodeId::Ad(0).inp_param("ashp").unwrap().inp();
|
||||||
|
let dshp_idx = NodeId::Ad(0).inp_param("dshp").unwrap().inp();
|
||||||
|
|
||||||
|
let ashp = gd.get_denorm(ashp_idx as u32);
|
||||||
|
|
||||||
|
let v = sqrt4_to_pow4(x * gd.get_norm(atk_idx as u32), ashp);
|
||||||
|
v
|
||||||
|
}))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -162,6 +162,38 @@ assertion failed: `(left[{}] == right[{}])`
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#[macro_export]
|
||||||
|
macro_rules! assert_decimated_slope_feq_fine {
|
||||||
|
($vec:expr, $decimate:expr, $cmp_vec:expr) => {
|
||||||
|
let cmp_vec = $cmp_vec;
|
||||||
|
let mut res : Vec<f32> = vec![];
|
||||||
|
let mut prev = 0.0;
|
||||||
|
for (i, s) in $vec.iter().enumerate() {
|
||||||
|
let delta = *s - prev;
|
||||||
|
if i > 0 {
|
||||||
|
res.push(delta);
|
||||||
|
}
|
||||||
|
prev = *s;
|
||||||
|
}
|
||||||
|
|
||||||
|
let res : Vec<f32> = res.iter().step_by($decimate).copied().collect();
|
||||||
|
|
||||||
|
for (i, (s, scmp)) in res.iter().zip(cmp_vec.iter()).enumerate() {
|
||||||
|
if (s - scmp).abs() > 0.0000001 {
|
||||||
|
panic!(r#"
|
||||||
|
table_left: {:?}
|
||||||
|
|
||||||
|
table_right: {:?}
|
||||||
|
|
||||||
|
assertion failed: `(left[{}] == right[{}])`
|
||||||
|
left: `{:?}`,
|
||||||
|
right: `{:?}`"#, &res[i..], &(cmp_vec[i..]), i, i, s, scmp)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! assert_rmsmima {
|
macro_rules! assert_rmsmima {
|
||||||
($rms:expr, $b:expr) => {
|
($rms:expr, $b:expr) => {
|
||||||
|
|
|
@ -256,9 +256,8 @@ fn check_node_ad_shp_exp() {
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn check_node_ad_trig_out() {
|
fn check_node_ad_eoet() {
|
||||||
let (node_conf, mut node_exec) = new_node_engine();
|
let (node_conf, mut node_exec) = new_node_engine();
|
||||||
let mut matrix = Matrix::new(node_conf, 3, 3);
|
let mut matrix = Matrix::new(node_conf, 3, 3);
|
||||||
|
|
||||||
|
@ -274,10 +273,7 @@ fn check_node_ad_trig_out() {
|
||||||
.input(out.inp("ch2"), None, None));
|
.input(out.inp("ch2"), None, None));
|
||||||
matrix.sync().unwrap();
|
matrix.sync().unwrap();
|
||||||
|
|
||||||
let trig_p = ad.inp_param("trig").unwrap();
|
|
||||||
|
|
||||||
pset_n(&mut matrix, ad, "trig", 1.0);
|
pset_n(&mut matrix, ad, "trig", 1.0);
|
||||||
|
|
||||||
let res = run_for_ms(&mut node_exec, 25.0);
|
let res = run_for_ms(&mut node_exec, 25.0);
|
||||||
// just make sure we are running an env:
|
// just make sure we are running an env:
|
||||||
assert_decimated_slope_feq!(res.0, 50, vec![
|
assert_decimated_slope_feq!(res.0, 50, vec![
|
||||||
|
@ -308,7 +304,7 @@ fn check_node_ad_trig_out() {
|
||||||
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn check_node_ad_atk() {
|
fn check_node_ad_atk_dcy() {
|
||||||
let (node_conf, mut node_exec) = new_node_engine();
|
let (node_conf, mut node_exec) = new_node_engine();
|
||||||
let mut matrix = Matrix::new(node_conf, 3, 3);
|
let mut matrix = Matrix::new(node_conf, 3, 3);
|
||||||
|
|
||||||
|
@ -346,4 +342,55 @@ fn check_node_ad_atk() {
|
||||||
// attack phase ended, and now we decay:
|
// attack phase ended, and now we decay:
|
||||||
-0.002267599
|
-0.002267599
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
// check if decay stays stable:
|
||||||
|
let res = run_for_ms(&mut node_exec, 2.0);
|
||||||
|
assert_decimated_slope_feq!(res.0, 40, vec![-0.002267599; 3]);
|
||||||
|
|
||||||
|
pset_d(&mut matrix, ad, "dcy", 200.0);
|
||||||
|
let res = run_for_ms(&mut node_exec, 20.0);
|
||||||
|
assert_decimated_slope_feq!(res.0, 40, vec![
|
||||||
|
// Slope is getting less and less steep, as expected:
|
||||||
|
-0.002197802, -0.0012806058, -0.00083732605, -0.0005899668,
|
||||||
|
-0.00043797493, -0.00033789873, -0.00026863813, -0.00021868944,
|
||||||
|
-0.00018143654, -0.00015294552, -0.00013071299,
|
||||||
|
// Slope does not change after the "dcy" change has been smoothed
|
||||||
|
-0.000113368034, -0.000113368034, -0.00011339784, -0.00011339784,
|
||||||
|
-0.000113368034, -0.000113368034, -0.00011339784, -0.000113368034,
|
||||||
|
-0.000113368034, -0.00011339784, -0.000113368034, -0.000113368034
|
||||||
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn check_node_ad_mult() {
|
||||||
|
let (node_conf, mut node_exec) = new_node_engine();
|
||||||
|
let mut matrix = Matrix::new(node_conf, 3, 3);
|
||||||
|
|
||||||
|
let ad = NodeId::Ad(0);
|
||||||
|
let out = NodeId::Out(0);
|
||||||
|
matrix.place(0, 0, Cell::empty(ad)
|
||||||
|
.out(None, None, ad.out("sig")));
|
||||||
|
matrix.place(0, 1, Cell::empty(out)
|
||||||
|
.input(out.inp("ch1"), None, None));
|
||||||
|
matrix.sync().unwrap();
|
||||||
|
|
||||||
|
pset_n(&mut matrix, ad, "trig", 1.0);
|
||||||
|
pset_n(&mut matrix, ad, "mult", 2.0);
|
||||||
|
let res = run_for_ms(&mut node_exec, 2000.0);
|
||||||
|
assert_decimated_slope_feq_fine!(res.0, 1800, vec![
|
||||||
|
0.0,
|
||||||
|
// looong attack:
|
||||||
|
0.00007558, 0.00007558, 0.00007558, 0.00007558,
|
||||||
|
0.00007558, 0.00007558, 0.00007558,
|
||||||
|
// looong decay:
|
||||||
|
-0.000022709, -0.000022709, -0.000022709, -0.000022709, -0.000022709,
|
||||||
|
-0.000022709, -0.000022709, -0.000022709, -0.000022709, -0.000022709,
|
||||||
|
-0.000022709, -0.000022709, -0.000022709, -0.000022709, -0.000022709,
|
||||||
|
-0.000022709, -0.000022709, -0.000022709, -0.000022709, -0.000022709,
|
||||||
|
-0.000022709, -0.000022709, -0.000022709, -0.000022709, -0.000022709,
|
||||||
|
0.0, 0.0, 0.0, 0.0, 0.0,
|
||||||
|
0.0, 0.0, 0.0, 0.0, 0.0,
|
||||||
|
0.0, 0.0, 0.0, 0.0, 0.0,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue