1
0
Fork 0

Completely reset smoothing on init or restore

This commit is contained in:
Robbert van der Helm 2022-02-02 21:41:20 +01:00
parent f8eb0e4ea6
commit 0ecec104fb
4 changed files with 49 additions and 37 deletions

View file

@ -34,9 +34,10 @@ pub trait Param {
/// The plain parameter type. /// The plain parameter type.
type Plain; type Plain;
/// Update the smoother state to point to the current value. Used when initializing and /// Update the smoother state to point to the current value. Also used when initializing and
/// restoring a plugin so everything is in sync. /// restoring a plugin so everything is in sync. In that case the smoother should completely
fn update_smoother(&mut self, sample_rate: f32); /// reset to the current value.
fn update_smoother(&mut self, sample_rate: f32, reset: bool);
/// Set this parameter based on a string. Returns whether the updating succeeded. That can fail /// Set this parameter based on a string. Returns whether the updating succeeded. That can fail
/// if the string cannot be parsed. /// if the string cannot be parsed.
@ -162,8 +163,8 @@ macro_rules! impl_plainparam {
impl Param for $ty { impl Param for $ty {
type Plain = $plain; type Plain = $plain;
fn update_smoother(&mut self, sample_rate: f32) { fn update_smoother(&mut self, sample_rate: f32, reset: bool) {
self.smoothed.set_target(sample_rate, self.value); self.smoothed.set_target(sample_rate, self.value, reset);
} }
fn set_from_string(&mut self, string: &str) -> bool { fn set_from_string(&mut self, string: &str) -> bool {
@ -234,7 +235,7 @@ impl_plainparam!(IntParam, i32);
impl Param for BoolParam { impl Param for BoolParam {
type Plain = bool; type Plain = bool;
fn update_smoother(&mut self, _sample_rate: f32) { fn update_smoother(&mut self, _sample_rate: f32, _init: bool) {
// Can't really smooth a binary parameter now can you // Can't really smooth a binary parameter now can you
} }

View file

@ -119,18 +119,19 @@ impl ParamPtr {
} }
} }
/// Update the smoother state to point to the current value. Used when initializing and /// Update the smoother state to point to the current value. Also used when initializing and
/// restoring a plugin so everything is in sync. /// restoring a plugin so everything is in sync. In that case the smoother should completely
/// reset to the current value.
/// ///
/// # Safety /// # Safety
/// ///
/// Calling this function is only safe as long as the object this `ParamPtr` was created for is /// Calling this function is only safe as long as the object this `ParamPtr` was created for is
/// still alive. /// still alive.
pub unsafe fn update_smoother(&self, sample_rate: f32) { pub unsafe fn update_smoother(&self, sample_rate: f32, reset: bool) {
match &self { match &self {
ParamPtr::FloatParam(p) => (**p).update_smoother(sample_rate), ParamPtr::FloatParam(p) => (**p).update_smoother(sample_rate, reset),
ParamPtr::IntParam(p) => (**p).update_smoother(sample_rate), ParamPtr::IntParam(p) => (**p).update_smoother(sample_rate, reset),
ParamPtr::BoolParam(p) => (**p).update_smoother(sample_rate), ParamPtr::BoolParam(p) => (**p).update_smoother(sample_rate, reset),
} }
} }

View file

@ -71,18 +71,23 @@ impl<T: Default> Smoother<T> {
// unwrap all of those options is not going to be very fun. // unwrap all of those options is not going to be very fun.
impl Smoother<f32> { impl Smoother<f32> {
/// Set the target value. /// Set the target value.
pub fn set_target(&mut self, sample_rate: f32, target: f32) { pub fn set_target(&mut self, sample_rate: f32, target: f32, reset: bool) {
self.target = target; self.target = target;
self.steps_left = match self.style { if reset {
SmoothingStyle::None => 1, self.current = self.target;
SmoothingStyle::SmoothLinear(time) => (sample_rate * time / 1000.0).round() as u32, self.steps_left = 0;
}; } else {
self.step_size = match self.style { self.steps_left = match self.style {
SmoothingStyle::None => 0.0, SmoothingStyle::None => 1,
SmoothingStyle::SmoothLinear(_) => { SmoothingStyle::SmoothLinear(time) => (sample_rate * time / 1000.0).round() as u32,
(self.target - self.current) / self.steps_left as f32 };
} self.step_size = match self.style {
}; SmoothingStyle::None => 0.0,
SmoothingStyle::SmoothLinear(_) => {
(self.target - self.current) / self.steps_left as f32
}
};
}
} }
// Yes, Clippy, like I said, this was intentional // Yes, Clippy, like I said, this was intentional
@ -109,18 +114,23 @@ impl Smoother<f32> {
} }
impl Smoother<i32> { impl Smoother<i32> {
pub fn set_target(&mut self, sample_rate: f32, target: i32) { pub fn set_target(&mut self, sample_rate: f32, target: i32, reset: bool) {
self.target = target; self.target = target;
self.steps_left = match self.style { if reset {
SmoothingStyle::None => 1, self.current = self.target as f32;
SmoothingStyle::SmoothLinear(time) => (sample_rate * time / 1000.0).round() as u32, self.steps_left = 0;
}; } else {
self.step_size = match self.style { self.steps_left = match self.style {
SmoothingStyle::None => 0.0, SmoothingStyle::None => 1,
SmoothingStyle::SmoothLinear(_) => { SmoothingStyle::SmoothLinear(time) => (sample_rate * time / 1000.0).round() as u32,
(self.target as f32 - self.current) / self.steps_left as f32 };
} self.step_size = match self.style {
}; SmoothingStyle::None => 0.0,
SmoothingStyle::SmoothLinear(_) => {
(self.target as f32 - self.current) / self.steps_left as f32
}
};
}
} }
#[allow(clippy::should_implement_trait)] #[allow(clippy::should_implement_trait)]

View file

@ -277,7 +277,7 @@ impl<P: Plugin> WrapperInner<'_, P> {
match (param_ptr, sample_rate) { match (param_ptr, sample_rate) {
(_, Some(sample_rate)) => { (_, Some(sample_rate)) => {
param_ptr.set_normalized_value(normalized_value as f32); param_ptr.set_normalized_value(normalized_value as f32);
param_ptr.update_smoother(sample_rate); param_ptr.update_smoother(sample_rate, false);
} }
_ => param_ptr.set_normalized_value(normalized_value as f32), _ => param_ptr.set_normalized_value(normalized_value as f32),
} }
@ -536,7 +536,7 @@ impl<P: Plugin> IComponent for Wrapper<'_, P> {
// Make sure everything starts out in sync // Make sure everything starts out in sync
if let Some(sample_rate) = sample_rate { if let Some(sample_rate) = sample_rate {
param_ptr.update_smoother(sample_rate); param_ptr.update_smoother(sample_rate, true);
} }
} }
@ -934,7 +934,7 @@ impl<P: Plugin> IAudioProcessor for Wrapper<'_, P> {
// Befure initializing the plugin, make sure all smoothers are set the the default values // Befure initializing the plugin, make sure all smoothers are set the the default values
for param in self.inner.param_by_hash.values() { for param in self.inner.param_by_hash.values() {
param.update_smoother(buffer_config.sample_rate); param.update_smoother(buffer_config.sample_rate, true);
} }
if self if self