diff --git a/src/dsp/mod.rs b/src/dsp/mod.rs index 45428ea..7669d17 100644 --- a/src/dsp/mod.rs +++ b/src/dsp/mod.rs @@ -51,7 +51,7 @@ use crate::fa_sampl_dir; use crate::fa_ad_mult; use crate::fa_delay_mode; use crate::fa_noise_mode; -use crate::fa_map_mode; +use crate::fa_map_clip; use node_amp::Amp; use node_sin::Sin; @@ -203,7 +203,6 @@ impl std::fmt::Display for ProcBuf { // Setting { labels: &'static [&'static str], unit: &'static str }, //} - #[derive(Debug, Clone, Copy, PartialOrd, PartialEq)] pub enum UIType { Generic, @@ -263,13 +262,12 @@ macro_rules! define_exp4 { macro_rules! n_pit { ($x: expr) => { ((($x as f32).max(0.01) / 440.0).log2() / 10.0) -// ((($x as f32).max(0.01) / 440.0).log2() / 5.0) } } macro_rules! d_pit { ($x: expr) => { { let note : f32 = ($x as f32) * 10.0; - 440.0 * (2.0_f32).powf(note) + 440.0 * (2.0_f32).powf(note.clamp(-10.0, 10.0)) } } } @@ -337,6 +335,26 @@ macro_rules! r_fms { ($x: expr, $coarse: expr) => { } } } +/// The rounding function for freq knobs (n_pit / d_pit) +macro_rules! r_fq { ($x: expr, $coarse: expr) => { + if $coarse { + ($x * 10.0).round() / 10.0 + } else { + let p = d_pit!($x); + if p < 10.0 { + n_pit!((p * 10.0).round() / 10.0) + } else if p < 100.0 { + n_pit!(p.round()) + } else if p < 1000.0 { + n_pit!((p / 10.0).round() * 10.0) + } else if p < 10000.0 { + n_pit!((p / 100.0).round() * 100.0) + } else { + n_pit!((p / 1000.0).round() * 1000.0) + } + } +} } + /// The default steps function: macro_rules! stp_d { () => { (20.0, 100.0) } } /// The UI steps to control parameters with a finer fine control: @@ -433,9 +451,11 @@ macro_rules! node_list { (0 inp n_id d_id r_id f_def stp_d -1.0, 1.0, 0.0) (1 atv n_id d_id r_id f_def stp_d -1.0, 1.0, 1.0) (2 offs n_id d_id r_id f_def stp_d -1.0, 1.0, 0.0) - (3 min n_id d_id r_id f_def stp_d -1.0, 1.0, -1.0) - (4 max n_id d_id r_id f_def stp_d -1.0, 1.0, 1.0) - {5 0 mode setting(0) fa_map_mode 0 1} + (3 imin n_id d_id r_id f_def stp_d -1.0, 1.0, -1.0) + (4 imax n_id d_id r_id f_def stp_d -1.0, 1.0, 1.0) + (5 min n_id d_id r_id f_def stp_d -1.0, 1.0, -1.0) + (6 max n_id d_id r_id f_def stp_d -1.0, 1.0, 1.0) + {7 0 clip setting(0) fa_map_clip 0 1} [0 sig], tseq => TSeq UIType::Generic UICategory::CV (0 clock n_id d_id r_id f_def stp_d 0.0, 1.0, 0.0) @@ -454,7 +474,7 @@ macro_rules! node_list { [10 gat5] [11 gat6], sampl => Sampl UIType::Generic UICategory::Osc - (0 freq n_pit d_pit r_id f_def stp_d -1.0, 1.0, 440.0) + (0 freq n_pit d_pit r_fq f_def stp_d -1.0, 0.564713133, 440.0) (1 trig n_id n_id r_id f_def stp_d -1.0, 1.0, 0.0) (2 offs n_id n_id r_id f_def stp_d 0.0, 1.0, 0.0) (3 len n_id n_id r_id f_def stp_d 0.0, 1.0, 1.0) @@ -469,7 +489,7 @@ macro_rules! node_list { // name denorm round format steps norm norm denorm // norm_fun fun fun fun def min max default sin => Sin UIType::Generic UICategory::Osc - (0 freq n_pit d_pit r_id f_freq stp_d -1.0, 1.0, 440.0) + (0 freq n_pit d_pit r_fq f_freq stp_d -1.0, 0.564713133, 440.0) (1 det n_det d_det r_det f_det stp_f -0.2, 0.2, 0.0) [0 sig], out => Out UIType::Generic UICategory::IOUtil diff --git a/src/dsp/node_map.rs b/src/dsp/node_map.rs index 4f40a9d..c8ac5e4 100644 --- a/src/dsp/node_map.rs +++ b/src/dsp/node_map.rs @@ -6,11 +6,11 @@ use crate::nodes::{NodeAudioContext, NodeExecContext}; use crate::dsp::{NodeId, SAtom, ProcBuf, DspNode, LedPhaseVals}; #[macro_export] -macro_rules! fa_map_mode { ($formatter: expr, $v: expr, $denorm_v: expr) => { { +macro_rules! fa_map_clip { ($formatter: expr, $v: expr, $denorm_v: expr) => { { let s = match ($v.round() as usize) { - 0 => "Bipolar", - 1 => "Unipolar", + 0 => "Off", + 1 => "Clip", _ => "?", }; write!($formatter, "{}", s) @@ -32,12 +32,16 @@ impl Map { "Map atv\n\nRange: (0..1)\n"; pub const offs : &'static str = "Map offs\nSignal input offset\nRange: (-1..1)\n"; + pub const imin : &'static str = + "Map imin\n\nRange: (0..1)\n"; + pub const imax : &'static str = + "Map imax\n\nRange: (0..1)\n"; pub const min : &'static str = "Map min\n\nRange: (0..1)\n"; pub const max : &'static str = "Map max\n\nRange: (0..1)\n"; - pub const mode : &'static str = - "Map mode\n"; + pub const clip : &'static str = + "Map clip\n"; pub const sig : &'static str = "Map sig\nMapped signal output\nRange: (-1..1)\n"; pub const DESC : &'static str = @@ -65,46 +69,68 @@ impl DspNode for Map { { use crate::dsp::{out, inp, denorm, denorm_v, inp_dir, at}; -// let gain = inp::Amp::gain(inputs); -// let att = inp::Amp::att(inputs); -// let inp = inp::Amp::inp(inputs); -// let out = out::Amp::sig(outputs); -// let neg = at::Amp::neg_att(atoms); -// -// let last_frame = ctx.nframes() - 1; -// -// let last_val = -// if neg.i() > 0 { -// for frame in 0..ctx.nframes() { -// out.write(frame, -// inp.read(frame) -// * denorm_v::Amp::att( -// inp_dir::Amp::att(att, frame) -// .max(0.0)) -// * denorm::Amp::gain(gain, frame)); -// } -// -// inp.read(last_frame) -// * denorm_v::Amp::att( -// inp_dir::Amp::att(att, last_frame) -// .max(0.0)) -// * denorm::Amp::gain(gain, last_frame) -// -// } else { -// for frame in 0..ctx.nframes() { -// out.write(frame, -// inp.read(frame) -// * denorm_v::Amp::att( -// inp_dir::Amp::att(att, frame).abs()) -// * denorm::Amp::gain(gain, frame)); -// } -// -// inp.read(last_frame) -// * denorm_v::Amp::att( -// inp_dir::Amp::att(att, last_frame).abs()) -// * denorm::Amp::gain(gain, last_frame) -// }; -// -// ctx_vals[0].set(last_val); + let inp = inp::Map::inp(inputs); + let atv = inp::Map::atv(inputs); + let offs = inp::Map::offs(inputs); + let imin = inp::Map::imin(inputs); + let imax = inp::Map::imax(inputs); + let min = inp::Map::min(inputs); + let max = inp::Map::max(inputs); + let out = out::Map::sig(outputs); + + let clip = at::Map::clip(atoms); + + let mut last_val = 0.0; + + if clip.i() == 0 { + for frame in 0..ctx.nframes() { + let s = + (inp.read(frame) * atv.read(frame)) + + offs.read(frame); + + let imin = imin.read(frame); + let imax = imax.read(frame); + let min = min.read(frame); + let max = max.read(frame); + + let x = + if (imax - imin).abs() < std::f32::EPSILON { + 1.0 + } else { + ((s - imin) / (imax - imin)).abs() + }; + last_val = x; + let s = min + (max - min) * x; + + out.write(frame, s); + } + } else { + for frame in 0..ctx.nframes() { + let s = + (inp.read(frame) * atv.read(frame)) + + offs.read(frame); + + let imin = imin.read(frame); + let imax = imax.read(frame); + let min = min.read(frame); + let max = max.read(frame); + + let x = + if (imax - imin).abs() < std::f32::EPSILON { + 1.0 + } else { + ((s - imin) / (imax - imin)).abs() + }; + last_val = x; + let s = min + (max - min) * x; + + out.write( + frame, + if min < max { s.clamp(min, max) } + else { s.clamp(max, min) }); + } + } + + ctx_vals[0].set(last_val); } } diff --git a/src/matrix_repr.rs b/src/matrix_repr.rs index 9616e4b..067c88a 100644 --- a/src/matrix_repr.rs +++ b/src/matrix_repr.rs @@ -328,9 +328,9 @@ impl MatrixRepr { if let Some(param_id) = param_id { m.atoms.push((param_id, deserialize_atom(&v[3])?)) - } else { - return Err( - MatrixDeserError::UnknownParamId(v.to_string())); + //d// } else { + //d// return Err( + //d// MatrixDeserError::UnknownParamId(v.to_string())); } } }