1
0
Fork 0

Add prefix to plain_value() and normalized_value()

To make it clearer that these functions include monophonic modulation.
When creating GUI widgets, you should be using the unmodulated variants.
This commit is contained in:
Robbert van der Helm 2022-11-07 13:03:44 +01:00
parent 3a22b12d8f
commit b2da26ecd7
14 changed files with 66 additions and 50 deletions

View file

@ -6,6 +6,15 @@ new and what's changed, this document lists all breaking changes in reverse
chronological order. If a new feature did not require any changes to existing chronological order. If a new feature did not require any changes to existing
code then it will not be listed here. code then it will not be listed here.
## [2022-11-07]
- `Param::plain_value()` and `Param::normalized_value()` have been renamed to
`Param::modulated_plain_value()` and `Param::modulated_normalized_value()`.
These functions are only used when creating GUIs, so this shouldn't break any
other plugin code. This change was made to make it extra clear that these
values do include monophonic modulation, as it's very easy to mistakenly use
the wrong value when handling user input in GUI widgets.
## [2022-11-06] ## [2022-11-06]
- `nih_plug_vizia::create_vizia_editor_without_theme()` has been removed, and - `nih_plug_vizia::create_vizia_editor_without_theme()` has been removed, and

View file

@ -66,11 +66,11 @@ impl<'a, P: Param> ParamSlider<'a, P> {
} }
fn plain_value(&self) -> P::Plain { fn plain_value(&self) -> P::Plain {
self.param.plain_value() self.param.modulated_plain_value()
} }
fn normalized_value(&self) -> f32 { fn normalized_value(&self) -> f32 {
self.param.normalized_value() self.param.modulated_normalized_value()
} }
fn string_value(&self) -> String { fn string_value(&self) -> String {

View file

@ -192,7 +192,7 @@ impl<'a, P: Param> ParamSlider<'a, P> {
// avoid this normalized->plain->normalized conversion for parameters that don't need // avoid this normalized->plain->normalized conversion for parameters that don't need
// it // it
let plain_value = self.param.preview_plain(normalized_value); let plain_value = self.param.preview_plain(normalized_value);
let current_plain_value = self.param.plain_value(); let current_plain_value = self.param.modulated_plain_value();
if plain_value != current_plain_value { if plain_value != current_plain_value {
// For the aforementioned snapping // For the aforementioned snapping
let normalized_plain_value = self.param.preview_normalized(plain_value); let normalized_plain_value = self.param.preview_normalized(plain_value);
@ -331,7 +331,7 @@ impl<'a, P: Param> Widget<ParamMessage, Renderer> for ParamSlider<'a, P> {
// When holding down shift while clicking on a parameter we want to // When holding down shift while clicking on a parameter we want to
// granuarly edit the parameter without jumping to a new value // granuarly edit the parameter without jumping to a new value
self.state.granular_drag_start_x_value = self.state.granular_drag_start_x_value =
Some((cursor_position.x, self.param.normalized_value())); Some((cursor_position.x, self.param.modulated_normalized_value()));
} else { } else {
shell.publish(ParamMessage::BeginSetParameter(self.param.as_ptr())); shell.publish(ParamMessage::BeginSetParameter(self.param.as_ptr()));
self.state.drag_active = true; self.state.drag_active = true;
@ -367,7 +367,7 @@ impl<'a, P: Param> Widget<ParamMessage, Renderer> for ParamSlider<'a, P> {
.state .state
.granular_drag_start_x_value .granular_drag_start_x_value
.get_or_insert_with(|| { .get_or_insert_with(|| {
(cursor_position.x, self.param.normalized_value()) (cursor_position.x, self.param.modulated_normalized_value())
}); });
self.set_normalized_value( self.set_normalized_value(
@ -484,7 +484,7 @@ impl<'a, P: Param> Widget<ParamMessage, Renderer> for ParamSlider<'a, P> {
// We'll visualize the difference between the current value and the default value if the // We'll visualize the difference between the current value and the default value if the
// default value lies somewhere in the middle and the parameter is continuous. Otherwise // default value lies somewhere in the middle and the parameter is continuous. Otherwise
// this appraoch looks a bit jarring. // this appraoch looks a bit jarring.
let current_value = self.param.normalized_value(); let current_value = self.param.modulated_normalized_value();
let default_value = self.param.default_normalized_value(); let default_value = self.param.default_normalized_value();
let fill_start_x = util::remap_rect_x_t( let fill_start_x = util::remap_rect_x_t(
&bounds_without_borders, &bounds_without_borders,

View file

@ -212,9 +212,9 @@ impl ParamWidgetBase {
param_ptr_forward!(pub fn name(&self) -> &str); param_ptr_forward!(pub fn name(&self) -> &str);
param_ptr_forward!(pub fn unit(&self) -> &'static str); param_ptr_forward!(pub fn unit(&self) -> &'static str);
param_ptr_forward!(pub fn poly_modulation_id(&self) -> Option<u32>); param_ptr_forward!(pub fn poly_modulation_id(&self) -> Option<u32>);
param_ptr_forward!(pub fn plain_value(&self) -> f32); param_ptr_forward!(pub fn modulated_plain_value(&self) -> f32);
param_ptr_forward!(pub fn unmodulated_plain_value(&self) -> f32); param_ptr_forward!(pub fn unmodulated_plain_value(&self) -> f32);
param_ptr_forward!(pub fn normalized_value(&self) -> f32); param_ptr_forward!(pub fn modulated_normalized_value(&self) -> f32);
param_ptr_forward!(pub fn unmodulated_normalized_value(&self) -> f32); param_ptr_forward!(pub fn unmodulated_normalized_value(&self) -> f32);
param_ptr_forward!(pub fn default_plain_value(&self) -> f32); param_ptr_forward!(pub fn default_plain_value(&self) -> f32);
param_ptr_forward!(pub fn default_normalized_value(&self) -> f32); param_ptr_forward!(pub fn default_normalized_value(&self) -> f32);

View file

@ -47,7 +47,7 @@ impl ParamButton {
.checked(ParamWidgetBase::make_lens( .checked(ParamWidgetBase::make_lens(
params, params,
params_to_param, params_to_param,
|param| param.normalized_value() >= 0.5, |param| param.modulated_normalized_value() >= 0.5,
)) ))
} }

View file

@ -189,7 +189,7 @@ impl ParamSlider {
( (
modulation_start, modulation_start,
param.normalized_value() - modulation_start, param.modulated_normalized_value() - modulation_start,
) )
} }
} }

View file

@ -83,23 +83,24 @@ pub trait Param: Display {
fn poly_modulation_id(&self) -> Option<u32>; fn poly_modulation_id(&self) -> Option<u32>;
/// Get the unnormalized value for this parameter. /// Get the unnormalized value for this parameter.
fn plain_value(&self) -> Self::Plain; fn modulated_plain_value(&self) -> Self::Plain;
/// Get the normalized `[0, 1]` value for this parameter. /// Get the normalized `[0, 1]` value for this parameter.
fn normalized_value(&self) -> f32; fn modulated_normalized_value(&self) -> f32;
/// Get the unnormalized value for this parameter before any (monophonic) modulation coming from /// Get the unnormalized value for this parameter before any (monophonic) modulation coming from
/// the host has been applied. If the host is not currently modulating this parameter than this /// the host has been applied. If the host is not currently modulating this parameter than this
/// will be the same as [`plain_value()`][Self::plain_value()]. This may be useful for /// will be the same as [`modulated_plain_value()`][Self::modulated_plain_value()]. This may be
/// displaying modulation differently in plugin GUIs. Right now only CLAP plugins in Bitwig /// useful for displaying modulation differently in plugin GUIs. Right now only CLAP plugins in
/// Studio use modulation. /// Bitwig Studio use modulation.
fn unmodulated_plain_value(&self) -> Self::Plain; fn unmodulated_plain_value(&self) -> Self::Plain;
/// Get the normalized `[0, 1]` value for this parameter before any (monophonic) modulation /// Get the normalized `[0, 1]` value for this parameter before any (monophonic) modulation
/// coming from the host has been applied. If the host is not currently modulating this /// coming from the host has been applied. If the host is not currently modulating this
/// parameter than this will be the same as [`plain_value()`][Self::plain_value()]. This may be /// parameter than this will be the same as
/// useful for displaying modulation differently in plugin GUIs. Right now only CLAP plugins in /// [`modulated_normalized_value()`][Self::modulated_normalized_value()]. This may be useful for
/// Bitwig Studio use modulation. /// displaying modulation differently in plugin GUIs. Right now only CLAP plugins in Bitwig
/// Studio use modulation.
fn unmodulated_normalized_value(&self) -> f32; fn unmodulated_normalized_value(&self) -> f32;
/// Get the unnormalized default value for this parameter. /// Get the unnormalized default value for this parameter.

View file

@ -77,12 +77,12 @@ impl Param for BoolParam {
} }
#[inline] #[inline]
fn plain_value(&self) -> Self::Plain { fn modulated_plain_value(&self) -> Self::Plain {
self.value.load(Ordering::Relaxed) self.value.load(Ordering::Relaxed)
} }
#[inline] #[inline]
fn normalized_value(&self) -> f32 { fn modulated_normalized_value(&self) -> f32 {
self.normalized_value.load(Ordering::Relaxed) self.normalized_value.load(Ordering::Relaxed)
} }
@ -228,7 +228,7 @@ impl BoolParam {
/// calling `param.plain_value()`. /// calling `param.plain_value()`.
#[inline] #[inline]
pub fn value(&self) -> bool { pub fn value(&self) -> bool {
self.plain_value() self.modulated_plain_value()
} }
/// Enable polyphonic modulation for this parameter. The ID is used to uniquely identify this /// Enable polyphonic modulation for this parameter. The ID is used to uniquely identify this

View file

@ -102,7 +102,11 @@ impl<T: Enum + PartialEq> Display for EnumParam<T> {
impl Display for EnumParamInner { impl Display for EnumParamInner {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", self.variants[self.inner.plain_value() as usize]) write!(
f,
"{}",
self.variants[self.inner.modulated_plain_value() as usize]
)
} }
} }
@ -122,13 +126,13 @@ impl<T: Enum + PartialEq> Param for EnumParam<T> {
} }
#[inline] #[inline]
fn plain_value(&self) -> Self::Plain { fn modulated_plain_value(&self) -> Self::Plain {
T::from_index(self.inner.plain_value() as usize) T::from_index(self.inner.modulated_plain_value() as usize)
} }
#[inline] #[inline]
fn normalized_value(&self) -> f32 { fn modulated_normalized_value(&self) -> f32 {
self.inner.normalized_value() self.inner.modulated_normalized_value()
} }
#[inline] #[inline]
@ -200,13 +204,13 @@ impl Param for EnumParamInner {
} }
#[inline] #[inline]
fn plain_value(&self) -> Self::Plain { fn modulated_plain_value(&self) -> Self::Plain {
self.inner.plain_value() self.inner.modulated_plain_value()
} }
#[inline] #[inline]
fn normalized_value(&self) -> f32 { fn modulated_normalized_value(&self) -> f32 {
self.inner.normalized_value() self.inner.modulated_normalized_value()
} }
#[inline] #[inline]
@ -329,7 +333,7 @@ impl<T: Enum + PartialEq + 'static> EnumParam<T> {
/// Get the active enum variant. /// Get the active enum variant.
#[inline] #[inline]
pub fn value(&self) -> T { pub fn value(&self) -> T {
self.plain_value() self.modulated_plain_value()
} }
/// Enable polyphonic modulation for this parameter. The ID is used to uniquely identify this /// Enable polyphonic modulation for this parameter. The ID is used to uniquely identify this

View file

@ -102,12 +102,12 @@ impl Param for FloatParam {
} }
#[inline] #[inline]
fn plain_value(&self) -> Self::Plain { fn modulated_plain_value(&self) -> Self::Plain {
self.value.load(Ordering::Relaxed) self.value.load(Ordering::Relaxed)
} }
#[inline] #[inline]
fn normalized_value(&self) -> f32 { fn modulated_normalized_value(&self) -> f32 {
self.normalized_value.load(Ordering::Relaxed) self.normalized_value.load(Ordering::Relaxed)
} }
@ -233,9 +233,10 @@ impl ParamMut for FloatParam {
fn update_smoother(&self, sample_rate: f32, reset: bool) { fn update_smoother(&self, sample_rate: f32, reset: bool) {
if reset { if reset {
self.smoothed.reset(self.plain_value()); self.smoothed.reset(self.modulated_plain_value());
} else { } else {
self.smoothed.set_target(sample_rate, self.plain_value()); self.smoothed
.set_target(sample_rate, self.modulated_plain_value());
} }
} }
} }
@ -270,7 +271,7 @@ impl FloatParam {
/// calling `param.plain_value()`. /// calling `param.plain_value()`.
#[inline] #[inline]
pub fn value(&self) -> f32 { pub fn value(&self) -> f32 {
self.plain_value() self.modulated_plain_value()
} }
/// Enable polyphonic modulation for this parameter. The ID is used to uniquely identify this /// Enable polyphonic modulation for this parameter. The ID is used to uniquely identify this

View file

@ -94,12 +94,12 @@ impl Param for IntParam {
} }
#[inline] #[inline]
fn plain_value(&self) -> Self::Plain { fn modulated_plain_value(&self) -> Self::Plain {
self.value.load(Ordering::Relaxed) self.value.load(Ordering::Relaxed)
} }
#[inline] #[inline]
fn normalized_value(&self) -> f32 { fn modulated_normalized_value(&self) -> f32 {
self.normalized_value.load(Ordering::Relaxed) self.normalized_value.load(Ordering::Relaxed)
} }
@ -213,9 +213,10 @@ impl ParamMut for IntParam {
fn update_smoother(&self, sample_rate: f32, reset: bool) { fn update_smoother(&self, sample_rate: f32, reset: bool) {
if reset { if reset {
self.smoothed.reset(self.plain_value()); self.smoothed.reset(self.modulated_plain_value());
} else { } else {
self.smoothed.set_target(sample_rate, self.plain_value()); self.smoothed
.set_target(sample_rate, self.modulated_plain_value());
} }
} }
} }
@ -249,7 +250,7 @@ impl IntParam {
/// calling `param.plain_value()`. /// calling `param.plain_value()`.
#[inline] #[inline]
pub fn value(&self) -> i32 { pub fn value(&self) -> i32 {
self.plain_value() self.modulated_plain_value()
} }
/// Enable polyphonic modulation for this parameter. The ID is used to uniquely identify this /// Enable polyphonic modulation for this parameter. The ID is used to uniquely identify this

View file

@ -64,7 +64,7 @@ impl ParamPtr {
param_ptr_forward!(pub unsafe fn name(&self) -> &str); param_ptr_forward!(pub unsafe fn name(&self) -> &str);
param_ptr_forward!(pub unsafe fn unit(&self) -> &'static str); param_ptr_forward!(pub unsafe fn unit(&self) -> &'static str);
param_ptr_forward!(pub unsafe fn poly_modulation_id(&self) -> Option<u32>); param_ptr_forward!(pub unsafe fn poly_modulation_id(&self) -> Option<u32>);
param_ptr_forward!(pub unsafe fn normalized_value(&self) -> f32); param_ptr_forward!(pub unsafe fn modulated_normalized_value(&self) -> f32);
param_ptr_forward!(pub unsafe fn unmodulated_normalized_value(&self) -> f32); param_ptr_forward!(pub unsafe fn unmodulated_normalized_value(&self) -> f32);
param_ptr_forward!(pub unsafe fn default_normalized_value(&self) -> f32); param_ptr_forward!(pub unsafe fn default_normalized_value(&self) -> f32);
param_ptr_forward!(pub unsafe fn step_count(&self) -> Option<usize>); param_ptr_forward!(pub unsafe fn step_count(&self) -> Option<usize>);
@ -90,12 +90,12 @@ impl ParamPtr {
/// ///
/// 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 plain_value(&self) -> f32 { pub unsafe fn modulated_plain_value(&self) -> f32 {
match self { match self {
ParamPtr::FloatParam(p) => (**p).plain_value(), ParamPtr::FloatParam(p) => (**p).modulated_plain_value(),
ParamPtr::IntParam(p) => (**p).plain_value() as f32, ParamPtr::IntParam(p) => (**p).modulated_plain_value() as f32,
ParamPtr::BoolParam(p) => (**p).normalized_value(), ParamPtr::BoolParam(p) => (**p).modulated_normalized_value(),
ParamPtr::EnumParam(p) => (**p).plain_value() as f32, ParamPtr::EnumParam(p) => (**p).modulated_plain_value() as f32,
} }
} }
@ -131,7 +131,7 @@ impl ParamPtr {
match self { match self {
ParamPtr::FloatParam(p) => (**p).default_plain_value(), ParamPtr::FloatParam(p) => (**p).default_plain_value(),
ParamPtr::IntParam(p) => (**p).default_plain_value() as f32, ParamPtr::IntParam(p) => (**p).default_plain_value() as f32,
ParamPtr::BoolParam(p) => (**p).normalized_value(), ParamPtr::BoolParam(p) => (**p).modulated_normalized_value(),
ParamPtr::EnumParam(p) => (**p).default_plain_value() as f32, ParamPtr::EnumParam(p) => (**p).default_plain_value() as f32,
} }
} }

View file

@ -3027,7 +3027,7 @@ impl<P: ClapPlugin> Wrapper<P> {
match wrapper.param_by_hash.get(&param_id) { match wrapper.param_by_hash.get(&param_id) {
Some(param_ptr) => { Some(param_ptr) => {
*value = param_ptr.normalized_value() as f64 *value = param_ptr.modulated_normalized_value() as f64
* param_ptr.step_count().unwrap_or(1) as f64; * param_ptr.step_count().unwrap_or(1) as f64;
true true

View file

@ -749,7 +749,7 @@ impl<P: Vst3Plugin> IEditController for Wrapper<P> {
unsafe fn get_param_normalized(&self, id: u32) -> f64 { unsafe fn get_param_normalized(&self, id: u32) -> f64 {
match self.inner.param_by_hash.get(&id) { match self.inner.param_by_hash.get(&id) {
Some(param_ptr) => param_ptr.normalized_value() as f64, Some(param_ptr) => param_ptr.modulated_normalized_value() as f64,
_ => 0.5, _ => 0.5,
} }
} }