From ddbaffc0bbf25461b7f7453a9b8c56856921a152 Mon Sep 17 00:00:00 2001 From: Robbert van der Helm Date: Sun, 1 May 2022 18:53:16 +0200 Subject: [PATCH] Add ParamMut method for setting modulation offset This will be used in the CLAP wrapper to handle `CLAP_EVENT_PARAM_MOD`. --- src/param.rs | 15 +++++++++++---- src/param/boolean.rs | 9 +++++++++ src/param/enums.rs | 8 ++++++++ src/param/float.rs | 9 +++++++++ src/param/integer.rs | 9 +++++++++ src/param/internals.rs | 1 + 6 files changed, 47 insertions(+), 4 deletions(-) diff --git a/src/param.rs b/src/param.rs index aecc1772..48bcbb3f 100644 --- a/src/param.rs +++ b/src/param.rs @@ -144,18 +144,25 @@ pub trait Param: Display { /// Contains the setters for parameters. These should not be exposed to plugins to avoid confusion. pub(crate) trait ParamMut: Param { - /// Set this parameter based on a plain, unnormalized value. This does **not** snap to step - /// sizes for continuous parameters (i.e. [`FloatParam`]). + /// Set this parameter based on a plain, unnormalized value. This does not snap to step sizes + /// for continuous parameters (i.e. [`FloatParam`]). /// /// This does **not** update the smoother. fn set_plain_value(&mut self, plain: Self::Plain); - /// Set this parameter based on a normalized value. This **does** snap to step sizes for - /// continuous parameters (i.e. [`FloatParam`]). + /// Set this parameter based on a normalized value. The normalized value will be snapped to the + /// step size for continuous parameters (i.e. [`FloatParam`]). /// /// This does **not** update the smoother. fn set_normalized_value(&mut self, normalized: f32); + /// Add a modulation offset to the value's unmodulated value. Out of bound values will be + /// clamped to the parameter's range. The normalized value will be snapped to the step size for + /// continuous parameters (i.e. [`FloatParam`]). + /// + /// This does **not** update the smoother. + fn modulate_value(&mut self, modulation_offset: f32); + /// Update the smoother state to point to the current value. Also used when initializing and /// restoring a plugin so everything is in sync. In that case the smoother should completely /// reset to the current value. diff --git a/src/param/boolean.rs b/src/param/boolean.rs index f26f75db..78875ebf 100644 --- a/src/param/boolean.rs +++ b/src/param/boolean.rs @@ -161,6 +161,15 @@ impl ParamMut for BoolParam { } } + fn modulate_value(&mut self, modulation_offset: f32) { + self.normalized_value = + (self.unmodulated_normalized_value + modulation_offset).clamp(0.0, 1.0); + self.value = self.preview_plain(self.normalized_value); + if let Some(f) = &self.value_changed { + f(self.value); + } + } + fn update_smoother(&mut self, _sample_rate: f32, _init: bool) { // Can't really smooth a binary parameter now can you } diff --git a/src/param/enums.rs b/src/param/enums.rs index acf82169..9d446665 100644 --- a/src/param/enums.rs +++ b/src/param/enums.rs @@ -246,6 +246,10 @@ impl ParamMut for EnumParam { self.inner.set_normalized_value(normalized) } + fn modulate_value(&mut self, modulation_offset: f32) { + self.inner.modulate_value(modulation_offset) + } + fn update_smoother(&mut self, sample_rate: f32, reset: bool) { self.inner.update_smoother(sample_rate, reset) } @@ -260,6 +264,10 @@ impl ParamMut for EnumParamInner { self.inner.set_normalized_value(normalized) } + fn modulate_value(&mut self, modulation_offset: f32) { + self.inner.modulate_value(modulation_offset) + } + fn update_smoother(&mut self, sample_rate: f32, reset: bool) { self.inner.update_smoother(sample_rate, reset) } diff --git a/src/param/float.rs b/src/param/float.rs index ee761408..e066ded1 100644 --- a/src/param/float.rs +++ b/src/param/float.rs @@ -221,6 +221,15 @@ impl ParamMut for FloatParam { } } + fn modulate_value(&mut self, modulation_offset: f32) { + self.normalized_value = + (self.unmodulated_normalized_value + modulation_offset).clamp(0.0, 1.0); + self.value = self.preview_plain(self.normalized_value); + if let Some(f) = &self.value_changed { + f(self.value); + } + } + fn update_smoother(&mut self, sample_rate: f32, reset: bool) { if reset { self.smoothed.reset(self.value); diff --git a/src/param/integer.rs b/src/param/integer.rs index d4d44d83..1fae8592 100644 --- a/src/param/integer.rs +++ b/src/param/integer.rs @@ -186,6 +186,15 @@ impl ParamMut for IntParam { } } + fn modulate_value(&mut self, modulation_offset: f32) { + self.normalized_value = + (self.unmodulated_normalized_value + modulation_offset).clamp(0.0, 1.0); + self.value = self.preview_plain(self.normalized_value); + if let Some(f) = &self.value_changed { + f(self.value); + } + } + fn update_smoother(&mut self, sample_rate: f32, reset: bool) { if reset { self.smoothed.reset(self.value); diff --git a/src/param/internals.rs b/src/param/internals.rs index 892025bb..3491f70a 100644 --- a/src/param/internals.rs +++ b/src/param/internals.rs @@ -160,6 +160,7 @@ impl ParamPtr { param_ptr_forward!(pub unsafe fn flags(&self) -> ParamFlags); param_ptr_forward!(pub(crate) unsafe fn set_normalized_value(&self, normalized: f32)); + param_ptr_forward!(pub(crate) unsafe fn modulate_value(&self, modulation_offset: f32)); param_ptr_forward!(pub(crate) unsafe fn update_smoother(&self, sample_rate: f32, reset: bool)); // These functions involve casts since the plugin formats only do floating point types, so we