From d24ee6130a45aa930376776e35a6a52f4465932d Mon Sep 17 00:00:00 2001 From: Erik Natanael Gustafsson Date: Mon, 4 Sep 2023 18:45:24 +0200 Subject: [PATCH] Add Lag Gen --- src/graph.rs | 68 ++++++++++++++++++++++++++++++++++++++++++++++++++ src/prelude.rs | 4 +-- 2 files changed, 70 insertions(+), 2 deletions(-) diff --git a/src/graph.rs b/src/graph.rs index 249bf8e..dd93340 100644 --- a/src/graph.rs +++ b/src/graph.rs @@ -3841,6 +3841,74 @@ struct FeedbackEdge { feedback_destination: NodeKey, } +/// Move to the target value exponentially by -60db attenuation over the specified time. +/// *Inputs* +/// 0. "value" +/// 1. "time" in seconds +/// *Outputs* +/// 0. "smoothed_value" +#[derive(Default)] +pub struct Lag { + // Compare with the current value. If there is change, recalculate the mix. + last_time: Sample, + current_value: Sample, + mix: Sample, + sample_rate: Sample, +} + +impl Lag { + #[allow(missing_docs)] + pub fn new() -> Self { + Self::default() + } +} +impl Gen for Lag { + fn process(&mut self, ctx: GenContext, _resources: &mut Resources) -> GenState { + for i in 0..ctx.block_size() { + let value = ctx.inputs.read(0, i); + let time = ctx.inputs.read(1, i); + if time != self.last_time { + self.last_time = time; + let num_samples = (time * self.sample_rate).floor(); + self.mix = 1.0 - 0.001_f32.powf(1.0 / num_samples); + } + self.current_value += (value - self.current_value) * self.mix; + ctx.outputs.write(self.current_value, 0, i); + } + GenState::Continue + } + + fn num_inputs(&self) -> usize { + 2 + } + + fn num_outputs(&self) -> usize { + 1 + } + + fn init(&mut self, _block_size: usize, sample_rate: Sample) { + self.sample_rate = sample_rate; + } + + fn input_desc(&self, input: usize) -> &'static str { + match input { + 0 => "value", + 1 => "time", + _ => "", + } + } + + fn output_desc(&self, output: usize) -> &'static str { + match output { + 0 => "smoothed_value", + _ => "", + } + } + + fn name(&self) -> &'static str { + "Lag" + } +} /// When input 0 changes, move smoothly to the new value over the time in seconds given by input 1. #[derive(Default)] pub struct Ramp { diff --git a/src/prelude.rs b/src/prelude.rs index 9ad5802..71c3740 100644 --- a/src/prelude.rs +++ b/src/prelude.rs @@ -6,8 +6,8 @@ pub use crate::controller::{CallbackHandle, KnystCommands}; pub use crate::graph::{ connection::constant, connection::{ConnectionBundle, InputBundle}, - gen, Connection, GenContext, GenState, Graph, GraphInput, GraphSettings, Mult, NodeAddress, - PanMonoToStereo, ParameterChange, Ramp, RunGraphSettings, + gen, Connection, GenContext, GenState, Graph, GraphInput, GraphSettings, Lag, Mult, + NodeAddress, PanMonoToStereo, ParameterChange, Ramp, RunGraphSettings, }; pub use crate::inputs; pub use crate::time::{Superbeats, Superseconds};