storing the modulation amount in the NodeConfigurator / Matrix is now implemented
This commit is contained in:
parent
b48d423b5a
commit
196d094673
5 changed files with 115 additions and 24 deletions
|
@ -470,7 +470,7 @@ impl Matrix {
|
||||||
let _ = self.sync();
|
let _ = self.sync();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn for_each_atom<F: FnMut(usize, ParamId, &SAtom)>(&self, f: F) {
|
pub fn for_each_atom<F: FnMut(usize, ParamId, &SAtom, Option<f32>)>(&self, f: F) {
|
||||||
self.config.for_each_param(f);
|
self.config.for_each_param(f);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -623,6 +623,17 @@ impl Matrix {
|
||||||
self.config.set_param(param, at);
|
self.config.set_param(param, at);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Assign or remove modulation of an input parameter.
|
||||||
|
pub fn set_param_modamt(&mut self, param: ParamId, modamt: Option<f32>)
|
||||||
|
-> Result<(), MatrixError>
|
||||||
|
{
|
||||||
|
if self.config.set_param_modamt(param, modamt) {
|
||||||
|
self.sync()
|
||||||
|
} else {
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn get_adjacent_output(&self, x: usize, y: usize, dir: CellDir)
|
pub fn get_adjacent_output(&self, x: usize, y: usize, dir: CellDir)
|
||||||
-> Option<(NodeId, u8)>
|
-> Option<(NodeId, u8)>
|
||||||
{
|
{
|
||||||
|
|
|
@ -142,7 +142,7 @@ impl PatternRepr {
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct MatrixRepr {
|
pub struct MatrixRepr {
|
||||||
pub cells: Vec<CellRepr>,
|
pub cells: Vec<CellRepr>,
|
||||||
pub params: Vec<(ParamId, f32)>,
|
pub params: Vec<(ParamId, f32, Option<f32>)>,
|
||||||
pub atoms: Vec<(ParamId, SAtom)>,
|
pub atoms: Vec<(ParamId, SAtom)>,
|
||||||
pub patterns: Vec<Option<PatternRepr>>,
|
pub patterns: Vec<Option<PatternRepr>>,
|
||||||
}
|
}
|
||||||
|
@ -312,7 +312,9 @@ impl MatrixRepr {
|
||||||
|
|
||||||
if let Some(param_id) = param_id {
|
if let Some(param_id) = param_id {
|
||||||
m.params.push(
|
m.params.push(
|
||||||
(param_id, v[3].as_f64().unwrap_or(0.0) as f32));
|
(param_id,
|
||||||
|
v[3].as_f64().unwrap_or(0.0) as f32,
|
||||||
|
v[4].as_f64().map(|v| v as f32)));
|
||||||
} else {
|
} else {
|
||||||
return Err(
|
return Err(
|
||||||
MatrixDeserError::UnknownParamId(v.to_string()));
|
MatrixDeserError::UnknownParamId(v.to_string()));
|
||||||
|
@ -358,14 +360,21 @@ impl MatrixRepr {
|
||||||
|
|
||||||
let mut params = json!([]);
|
let mut params = json!([]);
|
||||||
if let Value::Array(params) = &mut params {
|
if let Value::Array(params) = &mut params {
|
||||||
for (p, v) in self.params.iter() {
|
for (p, v, ma) in self.params.iter() {
|
||||||
params.push(
|
let mut param_v = json!([
|
||||||
json!([
|
|
||||||
p.node_id().name(),
|
p.node_id().name(),
|
||||||
p.node_id().instance(),
|
p.node_id().instance(),
|
||||||
p.name(),
|
p.name(),
|
||||||
v
|
v,
|
||||||
]));
|
]);
|
||||||
|
|
||||||
|
if let Value::Array(param_v) = &mut param_v {
|
||||||
|
if let Some(ma) = ma {
|
||||||
|
param_v.push(json!(ma));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
params.push(param_v);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -55,6 +55,7 @@ pub enum GraphMessage {
|
||||||
pub enum QuickMessage {
|
pub enum QuickMessage {
|
||||||
AtomUpdate { at_idx: usize, value: SAtom },
|
AtomUpdate { at_idx: usize, value: SAtom },
|
||||||
ParamUpdate { input_idx: usize, value: f32 },
|
ParamUpdate { input_idx: usize, value: f32 },
|
||||||
|
ModamtUpdate { input_idx: usize, modamt: f32 },
|
||||||
/// Sets the buffer indices to monitor with the FeedbackProcessor.
|
/// Sets the buffer indices to monitor with the FeedbackProcessor.
|
||||||
SetMonitor { bufs: [usize; MON_SIG_CNT], },
|
SetMonitor { bufs: [usize; MON_SIG_CNT], },
|
||||||
}
|
}
|
||||||
|
|
|
@ -154,6 +154,8 @@ pub struct NodeConfigurator {
|
||||||
params: std::collections::HashMap<ParamId, NodeInputParam>,
|
params: std::collections::HashMap<ParamId, NodeInputParam>,
|
||||||
/// Stores the most recently set parameter values
|
/// Stores the most recently set parameter values
|
||||||
param_values: std::collections::HashMap<ParamId, f32>,
|
param_values: std::collections::HashMap<ParamId, f32>,
|
||||||
|
/// Stores the modulation amount of a parameter
|
||||||
|
param_modamt: std::collections::HashMap<ParamId, Option<f32>>,
|
||||||
/// Contains non automateable atom data for the nodes
|
/// Contains non automateable atom data for the nodes
|
||||||
atoms: std::collections::HashMap<ParamId, NodeInputAtom>,
|
atoms: std::collections::HashMap<ParamId, NodeInputAtom>,
|
||||||
/// Stores the most recently set atoms
|
/// Stores the most recently set atoms
|
||||||
|
@ -241,6 +243,7 @@ impl NodeConfigurator {
|
||||||
output_fb_cons: None,
|
output_fb_cons: None,
|
||||||
params: std::collections::HashMap::new(),
|
params: std::collections::HashMap::new(),
|
||||||
param_values: std::collections::HashMap::new(),
|
param_values: std::collections::HashMap::new(),
|
||||||
|
param_modamt: std::collections::HashMap::new(),
|
||||||
atoms: std::collections::HashMap::new(),
|
atoms: std::collections::HashMap::new(),
|
||||||
atom_values: std::collections::HashMap::new(),
|
atom_values: std::collections::HashMap::new(),
|
||||||
node2idx: HashMap::new(),
|
node2idx: HashMap::new(),
|
||||||
|
@ -299,6 +302,47 @@ impl NodeConfigurator {
|
||||||
self.nodes.get_mut(idx)
|
self.nodes.get_mut(idx)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Set the modulation amount of a parameter.
|
||||||
|
/// Returns true if a new [NodeProg] needs to be created, which can be
|
||||||
|
/// necessary if there was no modulation amount assigned to this parameter
|
||||||
|
/// yet.
|
||||||
|
pub fn set_param_modamt(&mut self, param: ParamId, v: Option<f32>) -> bool {
|
||||||
|
if param.is_atom() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if the modulation amount was already set, if not, we need
|
||||||
|
// to reconstruct the graph and upload an updated NodeProg.
|
||||||
|
if let Some(_old_modamt) =
|
||||||
|
self.param_modamt.get(¶m).copied().flatten()
|
||||||
|
{
|
||||||
|
if v.is_none() {
|
||||||
|
self.param_modamt.insert(param, v);
|
||||||
|
true
|
||||||
|
|
||||||
|
} else {
|
||||||
|
let modamt = v.unwrap();
|
||||||
|
|
||||||
|
self.param_modamt.insert(param, v);
|
||||||
|
|
||||||
|
if let Some(nparam) = self.params.get_mut(¶m) {
|
||||||
|
let input_idx = nparam.input_idx;
|
||||||
|
let _ =
|
||||||
|
self.shared.quick_update_prod.push(
|
||||||
|
QuickMessage::ModamtUpdate {
|
||||||
|
input_idx, modamt
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
false
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
self.param_modamt.insert(param, v);
|
||||||
|
true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Assign [SAtom] values to input parameters and atoms.
|
/// Assign [SAtom] values to input parameters and atoms.
|
||||||
///
|
///
|
||||||
/// Only updates the DSP backend if [NodeConfigurator::rebuild_node_ports] was called
|
/// Only updates the DSP backend if [NodeConfigurator::rebuild_node_ports] was called
|
||||||
|
@ -356,12 +400,18 @@ impl NodeConfigurator {
|
||||||
/// Most useful for serialization and saving patches.
|
/// Most useful for serialization and saving patches.
|
||||||
#[allow(clippy::type_complexity)]
|
#[allow(clippy::type_complexity)]
|
||||||
pub fn dump_param_values(&self)
|
pub fn dump_param_values(&self)
|
||||||
-> (Vec<(ParamId, f32)>, Vec<(ParamId, SAtom)>)
|
-> (Vec<(ParamId, f32, Option<f32>)>, Vec<(ParamId, SAtom)>)
|
||||||
{
|
{
|
||||||
let params : Vec<(ParamId, f32)> =
|
let params : Vec<(ParamId, f32, Option<f32>)> =
|
||||||
self.param_values
|
self.param_values
|
||||||
.iter()
|
.iter()
|
||||||
.map(|(param_id, value)| (*param_id, *value))
|
.map(|(param_id, value)|
|
||||||
|
(*param_id,
|
||||||
|
*value,
|
||||||
|
self.param_modamt
|
||||||
|
.get(param_id)
|
||||||
|
.copied()
|
||||||
|
.flatten()))
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
let atoms : Vec<(ParamId, SAtom)> =
|
let atoms : Vec<(ParamId, SAtom)> =
|
||||||
|
@ -376,10 +426,13 @@ impl NodeConfigurator {
|
||||||
/// Loads parameter values from a dump. You will still need to upload
|
/// Loads parameter values from a dump. You will still need to upload
|
||||||
/// a new [NodeProg] which contains these values.
|
/// a new [NodeProg] which contains these values.
|
||||||
pub fn load_dumped_param_values(
|
pub fn load_dumped_param_values(
|
||||||
&mut self, params: &[(ParamId, f32)], atoms: &[(ParamId, SAtom)])
|
&mut self,
|
||||||
|
params: &[(ParamId, f32, Option<f32>)],
|
||||||
|
atoms: &[(ParamId, SAtom)])
|
||||||
{
|
{
|
||||||
for (param_id, val) in params.iter() {
|
for (param_id, val, modamt) in params.iter() {
|
||||||
self.set_param(*param_id, (*val).into());
|
self.set_param(*param_id, (*val).into());
|
||||||
|
self.set_param_modamt(*param_id, *modamt);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (param_id, val) in atoms.iter() {
|
for (param_id, val) in atoms.iter() {
|
||||||
|
@ -389,12 +442,12 @@ impl NodeConfigurator {
|
||||||
|
|
||||||
/// Iterates over every parameter and calls the given function with
|
/// Iterates over every parameter and calls the given function with
|
||||||
/// it's current value.
|
/// it's current value.
|
||||||
pub fn for_each_param<F: FnMut(usize, ParamId, &SAtom)>(&self, mut f: F) {
|
pub fn for_each_param<F: FnMut(usize, ParamId, &SAtom, Option<f32>)>(&self, mut f: F) {
|
||||||
for (_, node_input) in self.atoms.iter() {
|
for (_, node_input) in self.atoms.iter() {
|
||||||
if let Some(unique_idx) =
|
if let Some(unique_idx) =
|
||||||
self.unique_index_for(&node_input.param_id.node_id())
|
self.unique_index_for(&node_input.param_id.node_id())
|
||||||
{
|
{
|
||||||
f(unique_idx, node_input.param_id, &node_input.value);
|
f(unique_idx, node_input.param_id, &node_input.value, None);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -402,8 +455,15 @@ impl NodeConfigurator {
|
||||||
if let Some(unique_idx) =
|
if let Some(unique_idx) =
|
||||||
self.unique_index_for(&node_input.param_id.node_id())
|
self.unique_index_for(&node_input.param_id.node_id())
|
||||||
{
|
{
|
||||||
|
let modamt =
|
||||||
|
self.param_modamt
|
||||||
|
.get(&node_input.param_id)
|
||||||
|
.copied()
|
||||||
|
.flatten();
|
||||||
|
|
||||||
f(unique_idx, node_input.param_id,
|
f(unique_idx, node_input.param_id,
|
||||||
&SAtom::param(node_input.value));
|
&SAtom::param(node_input.value),
|
||||||
|
modamt);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -513,11 +573,15 @@ impl NodeConfigurator {
|
||||||
/// The monitor data can be retrieved using
|
/// The monitor data can be retrieved using
|
||||||
/// [NodeConfigurator::get_minmax_monitor_samples].
|
/// [NodeConfigurator::get_minmax_monitor_samples].
|
||||||
pub fn monitor(&mut self,
|
pub fn monitor(&mut self,
|
||||||
node_id: &NodeId, inputs: &[Option<u8>], outputs: &[Option<u8>])
|
node_id: &NodeId,
|
||||||
|
inputs: &[Option<u8>],
|
||||||
|
outputs: &[Option<u8>])
|
||||||
{
|
{
|
||||||
let mut bufs = [UNUSED_MONITOR_IDX; MON_SIG_CNT];
|
let mut bufs = [UNUSED_MONITOR_IDX; MON_SIG_CNT];
|
||||||
|
|
||||||
if let Some((_node_info, Some(node_instance))) = self.node_by_id(node_id) {
|
if let Some((_node_info, Some(node_instance))) =
|
||||||
|
self.node_by_id(node_id)
|
||||||
|
{
|
||||||
let mut i = 0;
|
let mut i = 0;
|
||||||
for inp_idx in inputs.iter().take(MON_SIG_CNT / 2) {
|
for inp_idx in inputs.iter().take(MON_SIG_CNT / 2) {
|
||||||
if let Some(inp_idx) = inp_idx {
|
if let Some(inp_idx) = inp_idx {
|
||||||
|
@ -572,6 +636,7 @@ impl NodeConfigurator {
|
||||||
self.nodes.fill_with(|| (NodeInfo::Nop, None));
|
self.nodes.fill_with(|| (NodeInfo::Nop, None));
|
||||||
self.params .clear();
|
self.params .clear();
|
||||||
self.param_values.clear();
|
self.param_values.clear();
|
||||||
|
self.param_modamt.clear();
|
||||||
self.atoms .clear();
|
self.atoms .clear();
|
||||||
self.atom_values .clear();
|
self.atom_values .clear();
|
||||||
|
|
||||||
|
|
|
@ -398,6 +398,11 @@ impl NodeExecutor {
|
||||||
QuickMessage::ParamUpdate { input_idx, value } => {
|
QuickMessage::ParamUpdate { input_idx, value } => {
|
||||||
self.set_param(input_idx, value);
|
self.set_param(input_idx, value);
|
||||||
},
|
},
|
||||||
|
// TODO: MODAMT
|
||||||
|
// QuickMessage::ModamtUpdate { input_idx, modamt } => {
|
||||||
|
QuickMessage::ModamtUpdate { .. } => {
|
||||||
|
// assign to NodeProg
|
||||||
|
},
|
||||||
QuickMessage::SetMonitor { bufs } => {
|
QuickMessage::SetMonitor { bufs } => {
|
||||||
self.monitor_signal_cur_inp_indices = bufs;
|
self.monitor_signal_cur_inp_indices = bufs;
|
||||||
},
|
},
|
||||||
|
|
Loading…
Reference in a new issue