The preset format now stores denormalized values, for better compatibility when the parameter ranges change.

This commit is contained in:
Weird Constructor 2021-08-18 06:38:37 +02:00
parent 2774c42d69
commit eb288d1760
3 changed files with 78 additions and 10 deletions

View file

@ -728,6 +728,7 @@ impl Matrix {
atoms, atoms,
patterns, patterns,
properties, properties,
version: 2,
} }
} }
@ -739,9 +740,12 @@ impl Matrix {
pub fn from_repr(&mut self, repr: &MatrixRepr) -> Result<(), MatrixError> { pub fn from_repr(&mut self, repr: &MatrixRepr) -> Result<(), MatrixError> {
self.clear(); self.clear();
let normalize_params = repr.version > 1;
self.config.load_dumped_param_values( self.config.load_dumped_param_values(
&repr.params[..], &repr.params[..],
&repr.atoms[..]); &repr.atoms[..],
normalize_params);
for (key, val) in repr.properties.iter() { for (key, val) in repr.properties.iter() {
self.set_prop(key, val.clone()); self.set_prop(key, val.clone());

View file

@ -195,6 +195,7 @@ pub struct MatrixRepr {
pub atoms: Vec<(ParamId, SAtom)>, pub atoms: Vec<(ParamId, SAtom)>,
pub patterns: Vec<Option<PatternRepr>>, pub patterns: Vec<Option<PatternRepr>>,
pub properties: Vec<(String, SAtom)>, pub properties: Vec<(String, SAtom)>,
pub version: i64,
} }
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
@ -293,6 +294,7 @@ impl MatrixRepr {
atoms, atoms,
patterns, patterns,
properties, properties,
version: 2,
} }
} }
@ -339,15 +341,17 @@ impl MatrixRepr {
pub fn deserialize(s: &str) -> Result<MatrixRepr, MatrixDeserError> { pub fn deserialize(s: &str) -> Result<MatrixRepr, MatrixDeserError> {
let v : Value = serde_json::from_str(s)?; let v : Value = serde_json::from_str(s)?;
let mut m = MatrixRepr::empty();
if let Some(version) = v.get("VERSION") { if let Some(version) = v.get("VERSION") {
let version : i64 = version.as_i64().unwrap_or(0); let version : i64 = version.as_i64().unwrap_or(0);
if version != 1 { if version > 2 {
return Err(MatrixDeserError::BadVersion); return Err(MatrixDeserError::BadVersion);
} }
}
let mut m = MatrixRepr::empty(); m.version = version;
}
let cells = &v["cells"]; let cells = &v["cells"];
if let Value::Array(cells) = cells { if let Value::Array(cells) = cells {
@ -413,7 +417,7 @@ impl MatrixRepr {
pub fn serialize(&mut self) -> String { pub fn serialize(&mut self) -> String {
let mut v = json!({ let mut v = json!({
"VERSION": 1, "VERSION": self.version,
}); });
self.properties.sort_by(|a, b| a.0.partial_cmp(&b.0).unwrap()); self.properties.sort_by(|a, b| a.0.partial_cmp(&b.0).unwrap());
@ -518,7 +522,7 @@ mod tests {
let s = matrix_repr.serialize(); let s = matrix_repr.serialize();
assert_eq!(s, assert_eq!(s,
"{\"VERSION\":1,\"atoms\":[],\"cells\":[],\"params\":[],\"patterns\":[],\"props\":[]}"); "{\"VERSION\":2,\"atoms\":[],\"cells\":[],\"params\":[],\"patterns\":[],\"props\":[]}");
assert!(MatrixRepr::deserialize(&s).is_ok()); assert!(MatrixRepr::deserialize(&s).is_ok());
} }
@ -548,7 +552,7 @@ mod tests {
let s = mr.serialize(); let s = mr.serialize();
assert_eq!(s, 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 mut mr2 = MatrixRepr::deserialize(&s).unwrap();
let s2 = mr2.serialize(); 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] #[test]
fn check_matrix_repr_mod_amt_1() { fn check_matrix_repr_mod_amt_1() {
use crate::nodes::new_node_engine; use crate::nodes::new_node_engine;

View file

@ -450,7 +450,7 @@ impl NodeConfigurator {
.iter() .iter()
.map(|(param_id, value)| .map(|(param_id, value)|
(*param_id, (*param_id,
*value, param_id.denorm(*value),
self.param_modamt self.param_modamt
.get(param_id) .get(param_id)
.copied() .copied()
@ -471,10 +471,14 @@ impl NodeConfigurator {
pub fn load_dumped_param_values( pub fn load_dumped_param_values(
&mut self, &mut self,
params: &[(ParamId, f32, Option<f32>)], params: &[(ParamId, f32, Option<f32>)],
atoms: &[(ParamId, SAtom)]) atoms: &[(ParamId, SAtom)],
normalize_params: bool)
{ {
for (param_id, val, modamt) in params.iter() { 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); self.set_param_modamt(*param_id, *modamt);
} }