Add polyphonic modulation IDs to parameters
In a bit we should be able to use this with a new `PolyModulation` note event to allow polyphonic modulation.
This commit is contained in:
parent
7ea2851775
commit
992fcfe969
15
src/param.rs
15
src/param.rs
|
@ -60,6 +60,21 @@ pub trait Param: Display {
|
|||
/// Get the unit label for this parameter, if any.
|
||||
fn unit(&self) -> &'static str;
|
||||
|
||||
/// Get this parameter's polyphonic modulation ID. If this is set for a parameter in a CLAP
|
||||
/// plugin, then polyphonic modulation will be enabled for that parameter. Polyphonic modulation
|
||||
/// is sent through [`NoteEvent::PolyModulation][crate::prelude::NoteEvent::PolyModulation`]
|
||||
/// events containing a **normalized** value for this parameter. This value must be converted to
|
||||
/// a plain value using [`preview_plain()`][Self::preview_plain()] before it can be used. The
|
||||
/// plugin should use this value in place of the parameter's normal (smoothed) value for the
|
||||
/// affected note, and it should apply smooth to these values as necessary.
|
||||
///
|
||||
/// # Important
|
||||
///
|
||||
/// After enabling polyphonic modulation, the plugin **must** start sending
|
||||
/// [`NoteEvent::VoiceTerminated`][crate::prelude::NoteEvent::VoiceEnd] events to the host when a voice
|
||||
/// has fully ended. This allows the host to reuse its modulation resources.
|
||||
fn poly_modulation_id(&self) -> Option<u32>;
|
||||
|
||||
/// Get the unnormalized value for this parameter.
|
||||
fn plain_value(&self) -> Self::Plain;
|
||||
|
||||
|
|
|
@ -36,6 +36,12 @@ pub struct BoolParam {
|
|||
|
||||
/// The parameter's human readable display name.
|
||||
name: String,
|
||||
/// If this parameter has been marked as polyphonically modulatable, then this will be a unique
|
||||
/// integer identifying the parameter. Because this value is determined by the plugin itself,
|
||||
/// the plugin can easily map
|
||||
/// [`NoteEvent::PolyModulation][crate::prelude::NoteEvent::PolyModulation`] events to the
|
||||
/// correct parameter by pattern matching on a constant.
|
||||
poly_modulation_id: Option<u32>,
|
||||
/// Optional custom conversion function from a boolean value to a string.
|
||||
value_to_string: Option<Arc<dyn Fn(bool) -> String + Send + Sync>>,
|
||||
/// Optional custom conversion function from a string to a boolean value. If the string cannot
|
||||
|
@ -65,6 +71,10 @@ impl Param for BoolParam {
|
|||
""
|
||||
}
|
||||
|
||||
fn poly_modulation_id(&self) -> Option<u32> {
|
||||
self.poly_modulation_id
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn plain_value(&self) -> Self::Plain {
|
||||
self.value
|
||||
|
@ -207,11 +217,27 @@ impl BoolParam {
|
|||
value_changed: None,
|
||||
|
||||
name: name.into(),
|
||||
poly_modulation_id: None,
|
||||
value_to_string: None,
|
||||
string_to_value: None,
|
||||
}
|
||||
}
|
||||
|
||||
/// Enable polyphonic modulation for this parameter. The ID is used to uniquely identify this
|
||||
/// parameter in [`NoteEvent::PolyModulation][crate::prelude::NoteEvent::PolyModulation`]
|
||||
/// events, and must thus be unique between _all_ polyphonically modulatable parameters. See the
|
||||
/// event's documentation for more information on how to use this.
|
||||
///
|
||||
/// # Important
|
||||
///
|
||||
/// After enabling polyphonic modulation, the plugin **must** start sending
|
||||
/// [`NoteEvent::VoiceTerminated`][crate::prelude::NoteEvent::VoiceEnd] events to the host when
|
||||
/// a voice has fully ended. This allows the host to reuse its modulation resources.
|
||||
pub fn with_poly_modulation_id(mut self, id: u32) -> Self {
|
||||
self.poly_modulation_id = Some(id);
|
||||
self
|
||||
}
|
||||
|
||||
/// Run a callback whenever this parameter's value changes. The argument passed to this function
|
||||
/// is the parameter's new value. This should not do anything expensive as it may be called
|
||||
/// multiple times in rapid succession, and it can be run from both the GUI and the audio
|
||||
|
|
|
@ -117,6 +117,10 @@ impl<T: Enum + PartialEq> Param for EnumParam<T> {
|
|||
self.inner.unit()
|
||||
}
|
||||
|
||||
fn poly_modulation_id(&self) -> Option<u32> {
|
||||
self.inner.poly_modulation_id()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn plain_value(&self) -> Self::Plain {
|
||||
T::from_index(self.inner.plain_value() as usize)
|
||||
|
@ -195,6 +199,10 @@ impl Param for EnumParamInner {
|
|||
""
|
||||
}
|
||||
|
||||
fn poly_modulation_id(&self) -> Option<u32> {
|
||||
self.inner.poly_modulation_id()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn plain_value(&self) -> Self::Plain {
|
||||
self.inner.plain_value()
|
||||
|
@ -326,6 +334,21 @@ impl<T: Enum + PartialEq + 'static> EnumParam<T> {
|
|||
}
|
||||
}
|
||||
|
||||
/// Enable polyphonic modulation for this parameter. The ID is used to uniquely identify this
|
||||
/// parameter in [`NoteEvent::PolyModulation][crate::prelude::NoteEvent::PolyModulation`]
|
||||
/// events, and must thus be unique between _all_ polyphonically modulatable parameters. See the
|
||||
/// event's documentation for more information on how to use this.
|
||||
///
|
||||
/// # Important
|
||||
///
|
||||
/// After enabling polyphonic modulation, the plugin **must** start sending
|
||||
/// [`NoteEvent::VoiceTerminated`][crate::prelude::NoteEvent::VoiceEnd] events to the host when
|
||||
/// a voice has fully ended. This allows the host to reuse its modulation resources.
|
||||
pub fn with_poly_modulation_id(mut self, id: u32) -> Self {
|
||||
self.inner.inner = self.inner.inner.with_poly_modulation_id(id);
|
||||
self
|
||||
}
|
||||
|
||||
/// Run a callback whenever this parameter's value changes. The argument passed to this function
|
||||
/// is the parameter's new value. This should not do anything expensive as it may be called
|
||||
/// multiple times in rapid succession, and it can be run from both the GUI and the audio
|
||||
|
|
|
@ -64,6 +64,12 @@ pub struct FloatParam {
|
|||
/// The parameter value's unit, added after [`value_to_string`][Self::value_to_string] if that
|
||||
/// is set. NIH-plug will not automatically add a space before the unit.
|
||||
unit: &'static str,
|
||||
/// If this parameter has been marked as polyphonically modulatable, then this will be a unique
|
||||
/// integer identifying the parameter. Because this value is determined by the plugin itself,
|
||||
/// the plugin can easily map
|
||||
/// [`NoteEvent::PolyModulation][crate::prelude::NoteEvent::PolyModulation`] events to the
|
||||
/// correct parameter by pattern matching on a constant.
|
||||
poly_modulation_id: Option<u32>,
|
||||
/// Optional custom conversion function from a plain **unnormalized** value to a string.
|
||||
value_to_string: Option<Arc<dyn Fn(f32) -> String + Send + Sync>>,
|
||||
/// Optional custom conversion function from a string to a plain **unnormalized** value. If the
|
||||
|
@ -99,6 +105,10 @@ impl Param for FloatParam {
|
|||
self.unit
|
||||
}
|
||||
|
||||
fn poly_modulation_id(&self) -> Option<u32> {
|
||||
self.poly_modulation_id
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn plain_value(&self) -> Self::Plain {
|
||||
self.value
|
||||
|
@ -275,11 +285,26 @@ impl FloatParam {
|
|||
step_size: None,
|
||||
name: name.into(),
|
||||
unit: "",
|
||||
poly_modulation_id: None,
|
||||
value_to_string: None,
|
||||
string_to_value: None,
|
||||
}
|
||||
}
|
||||
|
||||
/// Enable polyphonic modulation for this parameter. The ID is used to uniquely identify this
|
||||
/// parameter in [`NoteEvent::PolyModulation][crate::prelude::NoteEvent::PolyModulation`]
|
||||
/// events, and must thus be unique between _all_ polyphonically modulatable parameters.
|
||||
///
|
||||
/// # Important
|
||||
///
|
||||
/// After enabling polyphonic modulation, the plugin **must** start sending
|
||||
/// [`NoteEvent::VoiceTerminated`][crate::prelude::NoteEvent::VoiceEnd] events to the host when
|
||||
/// a voice has fully ended. This allows the host to reuse its modulation resources.
|
||||
pub fn with_poly_modulation_id(mut self, id: u32) -> Self {
|
||||
self.poly_modulation_id = Some(id);
|
||||
self
|
||||
}
|
||||
|
||||
/// Set up a smoother that can gradually interpolate changes made to this parameter, preventing
|
||||
/// clicks and zipper noises.
|
||||
pub fn with_smoother(mut self, style: SmoothingStyle) -> Self {
|
||||
|
|
|
@ -60,6 +60,12 @@ pub struct IntParam {
|
|||
/// The parameter value's unit, added after `value_to_string` if that is set. NIH-plug will not
|
||||
/// automatically add a space before the unit.
|
||||
unit: &'static str,
|
||||
/// If this parameter has been marked as polyphonically modulatable, then this will be a unique
|
||||
/// integer identifying the parameter. Because this value is determined by the plugin itself,
|
||||
/// the plugin can easily map
|
||||
/// [`NoteEvent::PolyModulation][crate::prelude::NoteEvent::PolyModulation`] events to the
|
||||
/// correct parameter by pattern matching on a constant.
|
||||
poly_modulation_id: Option<u32>,
|
||||
/// Optional custom conversion function from a plain **unnormalized** value to a string.
|
||||
value_to_string: Option<Arc<dyn Fn(i32) -> String + Send + Sync>>,
|
||||
/// Optional custom conversion function from a string to a plain **unnormalized** value. If the
|
||||
|
@ -91,6 +97,10 @@ impl Param for IntParam {
|
|||
self.unit
|
||||
}
|
||||
|
||||
fn poly_modulation_id(&self) -> Option<u32> {
|
||||
self.poly_modulation_id
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn plain_value(&self) -> Self::Plain {
|
||||
self.value
|
||||
|
@ -239,11 +249,27 @@ impl IntParam {
|
|||
range,
|
||||
name: name.into(),
|
||||
unit: "",
|
||||
poly_modulation_id: None,
|
||||
value_to_string: None,
|
||||
string_to_value: None,
|
||||
}
|
||||
}
|
||||
|
||||
/// Enable polyphonic modulation for this parameter. The ID is used to uniquely identify this
|
||||
/// parameter in [`NoteEvent::PolyModulation][crate::prelude::NoteEvent::PolyModulation`]
|
||||
/// events, and must thus be unique between _all_ polyphonically modulatable parameters. See the
|
||||
/// event's documentation for more information on how to use this.
|
||||
///
|
||||
/// # Important
|
||||
///
|
||||
/// After enabling polyphonic modulation, the plugin **must** start sending
|
||||
/// [`NoteEvent::VoiceTerminated`][crate::prelude::NoteEvent::VoiceEnd] events to the host when
|
||||
/// a voice has fully ended. This allows the host to reuse its modulation resources.
|
||||
pub fn with_poly_modulation_id(mut self, id: u32) -> Self {
|
||||
self.poly_modulation_id = Some(id);
|
||||
self
|
||||
}
|
||||
|
||||
/// Set up a smoother that can gradually interpolate changes made to this parameter, preventing
|
||||
/// clicks and zipper noises.
|
||||
pub fn with_smoother(mut self, style: SmoothingStyle) -> Self {
|
||||
|
|
|
@ -154,6 +154,7 @@ macro_rules! param_ptr_forward(
|
|||
impl ParamPtr {
|
||||
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 poly_modulation_id(&self) -> Option<u32>);
|
||||
param_ptr_forward!(pub unsafe fn 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);
|
||||
|
|
Loading…
Reference in a new issue