1
0
Fork 0

Move param setting functions to new ParamMut trait

This makes things slightly less confusing because these functions should
never be called from user code.
This commit is contained in:
Robbert van der Helm 2022-05-01 18:45:35 +02:00
parent a17c63bf71
commit 1d3ac1b2af
7 changed files with 147 additions and 133 deletions

View file

@ -113,18 +113,6 @@ pub trait Param: Display {
self.preview_normalized(self.next_step(self.preview_plain(from)))
}
/// 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`]).
///
/// This does **not** update the smoother.
fn set_normalized_value(&mut self, normalized: f32);
/// Get the string representation for a normalized value. Used as part of the wrappers. Most
/// plugin formats already have support for units, in which case it shouldn't be part of this
/// string or some DAWs may show duplicate units.
@ -141,11 +129,6 @@ pub trait Param: Display {
/// wrappers. This **does** snap to step sizes for continuous parameters (i.e. [`FloatParam`]).
fn preview_plain(&self, normalized: f32) -> Self::Plain;
/// 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.
fn update_smoother(&mut self, sample_rate: f32, reset: bool);
/// Allocate memory for block-based smoothing. The
/// [`Plugin::initialize_block_smoothers()`][crate::prelude::Plugin::initialize_block_smoothers()] method
/// will do this for every smoother.
@ -158,3 +141,23 @@ pub trait Param: Display {
/// not be used directly.
fn as_ptr(&self) -> internals::ParamPtr;
}
/// 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`]).
///
/// 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`]).
///
/// This does **not** update the smoother.
fn set_normalized_value(&mut self, normalized: 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.
fn update_smoother(&mut self, sample_rate: f32, reset: bool);
}

View file

@ -4,7 +4,7 @@ use std::fmt::Display;
use std::sync::Arc;
use super::internals::ParamPtr;
use super::{Param, ParamFlags};
use super::{Param, ParamFlags, ParamMut};
/// A simple boolean parameter.
#[repr(C, align(4))]
@ -98,26 +98,6 @@ impl Param for BoolParam {
true
}
fn set_plain_value(&mut self, plain: Self::Plain) {
self.unmodulated_value = plain;
self.unmodulated_normalized_value = self.preview_normalized(plain);
self.value = self.unmodulated_value;
self.normalized_value = self.unmodulated_normalized_value;
if let Some(f) = &self.value_changed {
f(self.value);
}
}
fn set_normalized_value(&mut self, normalized: f32) {
self.unmodulated_value = self.preview_plain(normalized);
self.unmodulated_normalized_value = normalized;
self.value = self.unmodulated_value;
self.normalized_value = self.unmodulated_normalized_value;
if let Some(f) = &self.value_changed {
f(self.value);
}
}
fn normalized_value_to_string(&self, normalized: f32, _include_unit: bool) -> String {
let value = self.preview_plain(normalized);
match (value, &self.value_to_string) {
@ -149,10 +129,6 @@ impl Param for BoolParam {
normalized > 0.5
}
fn update_smoother(&mut self, _sample_rate: f32, _init: bool) {
// Can't really smooth a binary parameter now can you
}
fn initialize_block_smoother(&mut self, _max_block_size: usize) {}
fn flags(&self) -> ParamFlags {
@ -164,6 +140,32 @@ impl Param for BoolParam {
}
}
impl ParamMut for BoolParam {
fn set_plain_value(&mut self, plain: Self::Plain) {
self.unmodulated_value = plain;
self.unmodulated_normalized_value = self.preview_normalized(plain);
self.value = self.unmodulated_value;
self.normalized_value = self.unmodulated_normalized_value;
if let Some(f) = &self.value_changed {
f(self.value);
}
}
fn set_normalized_value(&mut self, normalized: f32) {
self.unmodulated_value = self.preview_plain(normalized);
self.unmodulated_normalized_value = normalized;
self.value = self.unmodulated_value;
self.normalized_value = self.unmodulated_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
}
}
impl BoolParam {
/// Build a new [`BoolParam`]. Use the other associated functions to modify the behavior of the
/// parameter.

View file

@ -6,7 +6,7 @@ use std::sync::Arc;
use super::internals::ParamPtr;
use super::range::IntRange;
use super::{IntParam, Param, ParamFlags};
use super::{IntParam, Param, ParamFlags, ParamMut};
// Re-export the derive macro
pub use nih_plug_derive::Enum;
@ -125,14 +125,6 @@ impl<T: Enum + PartialEq> Param for EnumParam<T> {
T::from_index(self.inner.next_step(T::to_index(from) as i32) as usize)
}
fn set_plain_value(&mut self, plain: Self::Plain) {
self.inner.set_plain_value(T::to_index(plain) as i32)
}
fn set_normalized_value(&mut self, normalized: f32) {
self.inner.set_normalized_value(normalized)
}
fn normalized_value_to_string(&self, normalized: f32, include_unit: bool) -> String {
self.inner
.normalized_value_to_string(normalized, include_unit)
@ -150,10 +142,6 @@ impl<T: Enum + PartialEq> Param for EnumParam<T> {
T::from_index(self.inner.preview_plain(normalized) as usize)
}
fn update_smoother(&mut self, sample_rate: f32, reset: bool) {
self.inner.update_smoother(sample_rate, reset)
}
fn initialize_block_smoother(&mut self, max_block_size: usize) {
self.inner.initialize_block_smoother(max_block_size)
}
@ -215,14 +203,6 @@ impl Param for EnumParamInner {
self.inner.next_step(from)
}
fn set_plain_value(&mut self, plain: Self::Plain) {
self.inner.set_plain_value(plain)
}
fn set_normalized_value(&mut self, normalized: f32) {
self.inner.set_normalized_value(normalized)
}
fn normalized_value_to_string(&self, normalized: f32, _include_unit: bool) -> String {
let index = self.preview_plain(normalized);
self.variants[index as usize].to_string()
@ -244,10 +224,6 @@ impl Param for EnumParamInner {
self.inner.preview_plain(normalized)
}
fn update_smoother(&mut self, sample_rate: f32, reset: bool) {
self.inner.update_smoother(sample_rate, reset)
}
fn initialize_block_smoother(&mut self, max_block_size: usize) {
self.inner.initialize_block_smoother(max_block_size)
}
@ -261,6 +237,34 @@ impl Param for EnumParamInner {
}
}
impl<T: Enum + PartialEq> ParamMut for EnumParam<T> {
fn set_plain_value(&mut self, plain: Self::Plain) {
self.inner.set_plain_value(T::to_index(plain) as i32)
}
fn set_normalized_value(&mut self, normalized: f32) {
self.inner.set_normalized_value(normalized)
}
fn update_smoother(&mut self, sample_rate: f32, reset: bool) {
self.inner.update_smoother(sample_rate, reset)
}
}
impl ParamMut for EnumParamInner {
fn set_plain_value(&mut self, plain: Self::Plain) {
self.inner.set_plain_value(plain)
}
fn set_normalized_value(&mut self, normalized: f32) {
self.inner.set_normalized_value(normalized)
}
fn update_smoother(&mut self, sample_rate: f32, reset: bool) {
self.inner.update_smoother(sample_rate, reset)
}
}
impl<T: Enum + PartialEq + 'static> EnumParam<T> {
/// Build a new [Self]. Use the other associated functions to modify the behavior of the
/// parameter.

View file

@ -6,7 +6,7 @@ use std::sync::Arc;
use super::internals::ParamPtr;
use super::range::FloatRange;
use super::smoothing::{Smoother, SmoothingStyle};
use super::{Param, ParamFlags};
use super::{Param, ParamFlags, ParamMut};
/// A floating point parameter that's stored unnormalized. The range is used for the normalization
/// process.
@ -147,26 +147,6 @@ impl Param for FloatParam {
.clamp(self.range.min(), self.range.max())
}
fn set_plain_value(&mut self, plain: Self::Plain) {
self.unmodulated_value = plain;
self.unmodulated_normalized_value = self.preview_normalized(plain);
self.value = self.unmodulated_value;
self.normalized_value = self.unmodulated_normalized_value;
if let Some(f) = &self.value_changed {
f(self.value);
}
}
fn set_normalized_value(&mut self, normalized: f32) {
self.unmodulated_value = self.preview_plain(normalized);
self.unmodulated_normalized_value = normalized;
self.value = self.unmodulated_value;
self.normalized_value = self.unmodulated_normalized_value;
if let Some(f) = &self.value_changed {
f(self.value);
}
}
fn normalized_value_to_string(&self, normalized: f32, include_unit: bool) -> String {
let value = self.preview_plain(normalized);
match (&self.value_to_string, &self.step_size, include_unit) {
@ -207,14 +187,6 @@ impl Param for FloatParam {
}
}
fn update_smoother(&mut self, sample_rate: f32, reset: bool) {
if reset {
self.smoothed.reset(self.value);
} else {
self.smoothed.set_target(sample_rate, self.value);
}
}
fn initialize_block_smoother(&mut self, max_block_size: usize) {
self.smoothed.initialize_block_smoother(max_block_size);
}
@ -228,6 +200,36 @@ impl Param for FloatParam {
}
}
impl ParamMut for FloatParam {
fn set_plain_value(&mut self, plain: Self::Plain) {
self.unmodulated_value = plain;
self.unmodulated_normalized_value = self.preview_normalized(plain);
self.value = self.unmodulated_value;
self.normalized_value = self.unmodulated_normalized_value;
if let Some(f) = &self.value_changed {
f(self.value);
}
}
fn set_normalized_value(&mut self, normalized: f32) {
self.unmodulated_value = self.preview_plain(normalized);
self.unmodulated_normalized_value = normalized;
self.value = self.unmodulated_value;
self.normalized_value = self.unmodulated_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);
} else {
self.smoothed.set_target(sample_rate, self.value);
}
}
}
impl FloatParam {
/// Build a new [`FloatParam`]. Use the other associated functions to modify the behavior of the
/// parameter.

View file

@ -6,7 +6,7 @@ use std::sync::Arc;
use super::internals::ParamPtr;
use super::range::IntRange;
use super::smoothing::{Smoother, SmoothingStyle};
use super::{Param, ParamFlags};
use super::{Param, ParamFlags, ParamMut};
/// A discrete integer parameter that's stored unnormalized. The range is used for the normalization
/// process.
@ -124,26 +124,6 @@ impl Param for IntParam {
(from + 1).clamp(self.range.min(), self.range.max())
}
fn set_plain_value(&mut self, plain: Self::Plain) {
self.unmodulated_value = plain;
self.unmodulated_normalized_value = self.preview_normalized(plain);
self.value = self.unmodulated_value;
self.normalized_value = self.unmodulated_normalized_value;
if let Some(f) = &self.value_changed {
f(self.value);
}
}
fn set_normalized_value(&mut self, normalized: f32) {
self.unmodulated_value = self.preview_plain(normalized);
self.unmodulated_normalized_value = normalized;
self.value = self.unmodulated_value;
self.normalized_value = self.unmodulated_normalized_value;
if let Some(f) = &self.value_changed {
f(self.value);
}
}
fn normalized_value_to_string(&self, normalized: f32, include_unit: bool) -> String {
let value = self.preview_plain(normalized);
match (&self.value_to_string, include_unit) {
@ -172,14 +152,6 @@ impl Param for IntParam {
self.range.unnormalize(normalized)
}
fn update_smoother(&mut self, sample_rate: f32, reset: bool) {
if reset {
self.smoothed.reset(self.value);
} else {
self.smoothed.set_target(sample_rate, self.value);
}
}
fn initialize_block_smoother(&mut self, max_block_size: usize) {
self.smoothed.initialize_block_smoother(max_block_size);
}
@ -193,6 +165,36 @@ impl Param for IntParam {
}
}
impl ParamMut for IntParam {
fn set_plain_value(&mut self, plain: Self::Plain) {
self.unmodulated_value = plain;
self.unmodulated_normalized_value = self.preview_normalized(plain);
self.value = self.unmodulated_value;
self.normalized_value = self.unmodulated_normalized_value;
if let Some(f) = &self.value_changed {
f(self.value);
}
}
fn set_normalized_value(&mut self, normalized: f32) {
self.unmodulated_value = self.preview_plain(normalized);
self.unmodulated_normalized_value = normalized;
self.value = self.unmodulated_value;
self.normalized_value = self.unmodulated_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);
} else {
self.smoothed.set_target(sample_rate, self.value);
}
}
}
impl IntParam {
/// Build a new [`IntParam`]. Use the other associated functions to modify the behavior of the
/// parameter.

View file

@ -2,7 +2,7 @@
use std::collections::HashMap;
use super::{Param, ParamFlags};
use super::{Param, ParamFlags, ParamMut};
pub use nih_plug_derive::Params;
/// Re-export for use in the [`Params`] proc-macro.
@ -109,14 +109,14 @@ where
/// can't have an `.as_param()` function since the return type would differ depending on the
/// underlying parameter type, so instead we need to type erase all of the functions individually.
macro_rules! param_ptr_forward(
(pub unsafe fn $method:ident(&self $(, $arg_name:ident: $arg_ty:ty)*) $(-> $ret:ty)?) => {
($vis:vis unsafe fn $method:ident(&self $(, $arg_name:ident: $arg_ty:ty)*) $(-> $ret:ty)?) => {
/// Calls the corresponding method on the underlying [`Param`] object.
///
/// # Safety
///
/// Calling this function is only safe as long as the object this [`ParamPtr`] was created
/// for is still alive.
pub unsafe fn $method(&self $(, $arg_name: $arg_ty)*) $(-> $ret)? {
$vis unsafe fn $method(&self $(, $arg_name: $arg_ty)*) $(-> $ret)? {
match &self {
ParamPtr::FloatParam(p) => (**p).$method($($arg_name),*),
ParamPtr::IntParam(p) => (**p).$method($($arg_name),*),
@ -127,14 +127,14 @@ macro_rules! param_ptr_forward(
};
// XXX: Is there a way to combine these two? Hygienic macros don't let you call `&self` without
// it being defined in the macro.
(pub unsafe fn $method:ident(&mut self $(, $arg_name:ident: $arg_ty:ty)*) $(-> $ret:ty)?) => {
($vis:vis unsafe fn $method:ident(&mut self $(, $arg_name:ident: $arg_ty:ty)*) $(-> $ret:ty)?) => {
/// Calls the corresponding method on the underlying [`Param`] object.
///
/// # Safety
///
/// Calling this function is only safe as long as the object this [`ParamPtr`] was created
/// for is still alive.
pub unsafe fn $method(&mut self $(, $arg_name: $arg_ty)*) $(-> $ret)? {
$vis unsafe fn $method(&mut self $(, $arg_name: $arg_ty)*) $(-> $ret)? {
match &self {
ParamPtr::FloatParam(p) => (**p).$method($($arg_name),*),
ParamPtr::IntParam(p) => (**p).$method($($arg_name),*),
@ -154,13 +154,14 @@ impl ParamPtr {
param_ptr_forward!(pub unsafe fn step_count(&self) -> Option<usize>);
param_ptr_forward!(pub unsafe fn previous_normalized_step(&self, from: f32) -> f32);
param_ptr_forward!(pub unsafe fn next_normalized_step(&self, from: f32) -> f32);
param_ptr_forward!(pub unsafe fn set_normalized_value(&self, normalized: f32));
param_ptr_forward!(pub unsafe fn update_smoother(&self, sample_rate: f32, reset: bool));
param_ptr_forward!(pub unsafe fn initialize_block_smoother(&mut self, max_block_size: usize));
param_ptr_forward!(pub unsafe fn normalized_value_to_string(&self, normalized: f32, include_unit: bool) -> String);
param_ptr_forward!(pub unsafe fn string_to_normalized_value(&self, string: &str) -> Option<f32>);
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 update_smoother(&self, sample_rate: f32, reset: bool));
// These functions involve casts since the plugin formats only do floating point types, so we
// can't generate them with the macro:

View file

@ -6,7 +6,7 @@ use std::collections::HashMap;
use std::sync::Arc;
use crate::param::internals::{ParamPtr, Params};
use crate::param::Param;
use crate::param::{Param, ParamMut};
use crate::plugin::BufferConfig;
// These state objects are also exposed directly to the plugin so it can do its own internal preset