From eb288d176020d32c015fa6212a9c51ba4af12b65 Mon Sep 17 00:00:00 2001 From: Weird Constructor Date: Wed, 18 Aug 2021 06:38:37 +0200 Subject: [PATCH] The preset format now stores denormalized values, for better compatibility when the parameter ranges change. --- src/matrix.rs | 6 +++- src/matrix_repr.rs | 72 ++++++++++++++++++++++++++++++++++++++---- src/nodes/node_conf.rs | 10 ++++-- 3 files changed, 78 insertions(+), 10 deletions(-) diff --git a/src/matrix.rs b/src/matrix.rs index e1aec7f..fa7164c 100644 --- a/src/matrix.rs +++ b/src/matrix.rs @@ -728,6 +728,7 @@ impl Matrix { atoms, patterns, properties, + version: 2, } } @@ -739,9 +740,12 @@ impl Matrix { pub fn from_repr(&mut self, repr: &MatrixRepr) -> Result<(), MatrixError> { self.clear(); + let normalize_params = repr.version > 1; + self.config.load_dumped_param_values( &repr.params[..], - &repr.atoms[..]); + &repr.atoms[..], + normalize_params); for (key, val) in repr.properties.iter() { self.set_prop(key, val.clone()); diff --git a/src/matrix_repr.rs b/src/matrix_repr.rs index 227afa4..3952d4c 100644 --- a/src/matrix_repr.rs +++ b/src/matrix_repr.rs @@ -195,6 +195,7 @@ pub struct MatrixRepr { pub atoms: Vec<(ParamId, SAtom)>, pub patterns: Vec>, pub properties: Vec<(String, SAtom)>, + pub version: i64, } #[derive(Debug, Clone)] @@ -293,6 +294,7 @@ impl MatrixRepr { atoms, patterns, properties, + version: 2, } } @@ -339,15 +341,17 @@ impl MatrixRepr { pub fn deserialize(s: &str) -> Result { let v : Value = serde_json::from_str(s)?; + let mut m = MatrixRepr::empty(); + if let Some(version) = v.get("VERSION") { let version : i64 = version.as_i64().unwrap_or(0); - if version != 1 { + if version > 2 { return Err(MatrixDeserError::BadVersion); } - } - let mut m = MatrixRepr::empty(); + m.version = version; + } let cells = &v["cells"]; if let Value::Array(cells) = cells { @@ -413,7 +417,7 @@ impl MatrixRepr { pub fn serialize(&mut self) -> String { let mut v = json!({ - "VERSION": 1, + "VERSION": self.version, }); self.properties.sort_by(|a, b| a.0.partial_cmp(&b.0).unwrap()); @@ -518,7 +522,7 @@ mod tests { let s = matrix_repr.serialize(); assert_eq!(s, - "{\"VERSION\":1,\"atoms\":[],\"cells\":[],\"params\":[],\"patterns\":[],\"props\":[]}"); + "{\"VERSION\":2,\"atoms\":[],\"cells\":[],\"params\":[],\"patterns\":[],\"props\":[]}"); assert!(MatrixRepr::deserialize(&s).is_ok()); } @@ -548,7 +552,7 @@ mod tests { let s = mr.serialize(); assert_eq!(s, - "{\"VERSION\":1,\"atoms\":[[\"out\",0,\"mono\",[\"i\",0]]],\"cells\":[[\"sin\",2,0,0,[-1,-1,-1],[-1,\"sig\",-1]],[\"out\",0,1,0,[-1,\"ch1\",-1],[-1,-1,-1]]],\"params\":[[\"out\",0,\"ch1\",0.0],[\"out\",0,\"ch2\",0.0],[\"sin\",0,\"det\",0.0],[\"sin\",1,\"det\",0.0],[\"sin\",2,\"det\",0.0],[\"sin\",0,\"freq\",0.0],[\"sin\",1,\"freq\",0.0],[\"sin\",2,\"freq\",-0.10000000149011612],[\"out\",0,\"gain\",0.5]],\"patterns\":[null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null],\"props\":[]}"); + "{\"VERSION\":2,\"atoms\":[[\"out\",0,\"mono\",[\"i\",0]]],\"cells\":[[\"sin\",2,0,0,[-1,-1,-1],[-1,\"sig\",-1]],[\"out\",0,1,0,[-1,\"ch1\",-1],[-1,-1,-1]]],\"params\":[[\"out\",0,\"ch1\",0.0],[\"out\",0,\"ch2\",0.0],[\"sin\",0,\"det\",0.0],[\"sin\",1,\"det\",0.0],[\"sin\",2,\"det\",0.0],[\"sin\",0,\"freq\",440.0],[\"sin\",1,\"freq\",440.0],[\"sin\",2,\"freq\",220.0],[\"out\",0,\"gain\",1.0]],\"patterns\":[null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null],\"props\":[]}"); let mut mr2 = MatrixRepr::deserialize(&s).unwrap(); let s2 = mr2.serialize(); @@ -726,6 +730,62 @@ mod tests { } } + #[test] + fn check_matrix_repr_version_1_load() { + use crate::nodes::new_node_engine; + + let s = + "{\"VERSION\":1,\"atoms\":[[\"out\",0,\"mono\",[\"i\",0]]],\"cells\":[[\"sin\",2,0,0,[-1,-1,-1],[-1,\"sig\",-1]],[\"out\",0,1,0,[-1,\"ch1\",-1],[-1,-1,-1]]],\"params\":[[\"out\",0,\"ch1\",0.0],[\"out\",0,\"ch2\",0.0],[\"sin\",0,\"det\",0.0],[\"sin\",1,\"det\",0.0],[\"sin\",2,\"det\",0.0],[\"sin\",0,\"freq\",0.0],[\"sin\",1,\"freq\",0.0],[\"sin\",2,\"freq\",-0.10000000149011612],[\"out\",0,\"gain\",0.5]],\"patterns\":[null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null],\"props\":[]}"; + + { + let (node_conf, mut _node_exec) = new_node_engine(); + let mut matrix = Matrix::new(node_conf, 3, 3); + + let mr = MatrixRepr::deserialize(&s).unwrap(); + matrix.from_repr(&mr).unwrap(); + + let mut v = std::collections::HashMap::new(); + matrix.for_each_atom(|unique_idx, param_id, atom, modamt| { + v.insert( + format!("{}_{}", unique_idx, param_id.name().to_string()), + param_id.denorm(atom.f())); + }); + + assert_eq!(*v.get("0_freq").unwrap(), 440.0); + assert_eq!(*v.get("1_freq").unwrap(), 440.0); + assert_eq!(*v.get("2_freq").unwrap(), 220.0); + assert_eq!(*v.get("0_det").unwrap(), 0.0); + } + } + + #[test] + fn check_matrix_repr_version_2_load() { + use crate::nodes::new_node_engine; + + let s = + "{\"VERSION\":2,\"atoms\":[[\"out\",0,\"mono\",[\"i\",0]]],\"cells\":[[\"sin\",2,0,0,[-1,-1,-1],[-1,\"sig\",-1]],[\"out\",0,1,0,[-1,\"ch1\",-1],[-1,-1,-1]]],\"params\":[[\"out\",0,\"ch1\",0.0],[\"out\",0,\"ch2\",0.0],[\"sin\",0,\"det\",0.0],[\"sin\",1,\"det\",0.0],[\"sin\",2,\"det\",0.0],[\"sin\",0,\"freq\",440.0],[\"sin\",1,\"freq\",441.0],[\"sin\",2,\"freq\",220.0],[\"out\",0,\"gain\",0.5]],\"patterns\":[null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null],\"props\":[]}"; + + { + let (node_conf, mut _node_exec) = new_node_engine(); + let mut matrix = Matrix::new(node_conf, 3, 3); + + let mr = MatrixRepr::deserialize(&s).unwrap(); + matrix.from_repr(&mr).unwrap(); + + let mut v = std::collections::HashMap::new(); + matrix.for_each_atom(|unique_idx, param_id, atom, modamt| { + v.insert( + format!("{}_{}", unique_idx, param_id.name().to_string()), + param_id.denorm(atom.f())); + }); + + assert_eq!(*v.get("0_freq").unwrap(), 440.0); + assert_eq!(*v.get("1_freq").unwrap(), 441.0); + assert_eq!(*v.get("2_freq").unwrap(), 220.0); + assert_eq!(*v.get("0_det").unwrap(), 0.0); + } + } + #[test] fn check_matrix_repr_mod_amt_1() { use crate::nodes::new_node_engine; diff --git a/src/nodes/node_conf.rs b/src/nodes/node_conf.rs index 0da42b2..d1bb25d 100644 --- a/src/nodes/node_conf.rs +++ b/src/nodes/node_conf.rs @@ -450,7 +450,7 @@ impl NodeConfigurator { .iter() .map(|(param_id, value)| (*param_id, - *value, + param_id.denorm(*value), self.param_modamt .get(param_id) .copied() @@ -471,10 +471,14 @@ impl NodeConfigurator { pub fn load_dumped_param_values( &mut self, params: &[(ParamId, f32, Option)], - atoms: &[(ParamId, SAtom)]) + atoms: &[(ParamId, SAtom)], + normalize_params: bool) { for (param_id, val, modamt) in params.iter() { - self.set_param(*param_id, (*val).into()); + let val = + if normalize_params { param_id.norm(*val) } + else { *val }; + self.set_param(*param_id, val.into()); self.set_param_modamt(*param_id, *modamt); }