diff --git a/README.md b/README.md index 802ae38..6665fec 100644 --- a/README.md +++ b/README.md @@ -663,6 +663,8 @@ refer to the fundsp [readme](https://github.com/SamiPerttu/fundsp), and [docs](h - inputs: `n`, `0 -> 1` (input node) - node: ins and outs are the same as the given node - tick the input node once every n samples +- `s()` + - same as `kr()` but since `kr()` will tick the node less frequently than it would normally, that has an effect on how it behaves (times and frequencies get stretched) `s()` avoids that by setting the sr of the given node to sr/n in order to preserve the time of that node - `sr()` - inputs: `n`, `0 -> 1` (input node) - set the sample rate for the input node diff --git a/src/functions.rs b/src/functions.rs index c56dee3..d7cbb4e 100644 --- a/src/functions.rs +++ b/src/functions.rs @@ -1277,6 +1277,7 @@ pub fn str_to_op_num(op: &str) -> u16 { "quantize()" => 66, "feedback()" => 67, "kr()" => 68, + "s()" => 95, "reset()" => 69, "sr()" => 70, "trig_reset()" => 71, diff --git a/src/nodes.rs b/src/nodes.rs index 7d237be..55cef10 100644 --- a/src/nodes.rs +++ b/src/nodes.rs @@ -239,15 +239,17 @@ pub struct Kr { count: usize, inputs: usize, outputs: usize, + // set the sr of the inner net to sr/n to keep durations and frequencies unchanged + preserve_time: bool, } impl Kr { - pub fn new(x: Net, n: usize) -> Self { + pub fn new(x: Net, n: usize, preserve_time: bool) -> Self { let inputs = x.inputs(); let outputs = x.outputs(); let mut vals = Vec::new(); vals.resize(outputs, 0.); - Kr { x, n, vals, count: 0, inputs, outputs } + Kr { x, n, vals, count: 0, inputs, outputs, preserve_time } } } @@ -259,7 +261,11 @@ impl AudioUnit for Kr { } fn set_sample_rate(&mut self, sample_rate: f64) { - self.x.set_sample_rate(sample_rate); + if self.preserve_time { + self.x.set_sample_rate(sample_rate / self.n as f64); + } else { + self.x.set_sample_rate(sample_rate); + } } fn tick(&mut self, input: &[f32], output: &mut [f32]) { diff --git a/src/process.rs b/src/process.rs index 5b24552..67292da 100644 --- a/src/process.rs +++ b/src/process.rs @@ -1517,8 +1517,8 @@ pub fn process( } } } - // kr() | reset() | sr() - 68..=70 => { + // kr() | reset() | sr() | s() + 68..=70 | 95 => { let op_changed = op_changed_query.get(*id).unwrap().0; let lost = lost_wh_query.get(*id).unwrap().0; let num_changed = num_query.get_mut(*id).unwrap().is_changed(); @@ -1539,14 +1539,17 @@ pub fn process( let net = net_query.get(input).unwrap().0.clone(); let n = num_query.get(*id).unwrap().0; let output = &mut net_query.get_mut(*id).unwrap().0; + // kr() if op_num == 68 { - // kr() - *output = Net::wrap(Box::new(Kr::new(net, n.max(1.) as usize))); + *output = Net::wrap(Box::new(Kr::new(net, n.max(1.) as usize, false))); + // s() + } else if op_num == 95 { + *output = Net::wrap(Box::new(Kr::new(net, n.max(1.) as usize, true))); + // reset() } else if op_num == 69 && net.inputs() == 0 && net.outputs() == 1 { - // reset() *output = Net::wrap(Box::new(An(Reset::new(net, n)))); + // sr() } else if op_num == 70 { - // sr() *output = net; output.set_sample_rate(n as f64); }