Fix typos in documentation
This commit is contained in:
parent
d1600a9dce
commit
f4995abf88
|
@ -12,7 +12,7 @@ struct Gain {
|
||||||
/// of a parameters struct for multiple identical oscillators/filters/envelopes.
|
/// of a parameters struct for multiple identical oscillators/filters/envelopes.
|
||||||
#[derive(Params)]
|
#[derive(Params)]
|
||||||
struct GainParams {
|
struct GainParams {
|
||||||
/// The parameter's ID is used to identify the parameter in the wrappred plugin API. As long as
|
/// The parameter's ID is used to identify the parameter in the wrapped plugin API. As long as
|
||||||
/// these IDs remain constant, you can rename and reorder these fields as you wish. The
|
/// these IDs remain constant, you can rename and reorder these fields as you wish. The
|
||||||
/// parameters are exposed to the host in the same order they were defined. In this case, this
|
/// parameters are exposed to the host in the same order they were defined. In this case, this
|
||||||
/// gain parameter is stored as linear gain while the values are displayed in decibels.
|
/// gain parameter is stored as linear gain while the values are displayed in decibels.
|
||||||
|
|
|
@ -17,8 +17,8 @@ pub use samples::{ChannelSamples, ChannelSamplesIter, SamplesIter};
|
||||||
/// this either way. Maybe just get rid of it in favor for raw pointers.
|
/// this either way. Maybe just get rid of it in favor for raw pointers.
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
pub struct Buffer<'a> {
|
pub struct Buffer<'a> {
|
||||||
/// Contains slices for the plugin's outputs. You can't directly create a nested slice form
|
/// Contains slices for the plugin's outputs. You can't directly create a nested slice from a
|
||||||
/// apointer to pointers, so this needs to be preallocated in the setup call and kept around
|
/// pointer to pointers, so this needs to be preallocated in the setup call and kept around
|
||||||
/// between process calls. And because storing a reference to this means a) that you need a lot
|
/// between process calls. And because storing a reference to this means a) that you need a lot
|
||||||
/// of lifetime annotations everywhere and b) that at some point you need unsound lifetime casts
|
/// of lifetime annotations everywhere and b) that at some point you need unsound lifetime casts
|
||||||
/// because this `Buffers` either cannot have the same lifetime as the separately stored output
|
/// because this `Buffers` either cannot have the same lifetime as the separately stored output
|
||||||
|
@ -28,7 +28,7 @@ pub struct Buffer<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Buffer<'a> {
|
impl<'a> Buffer<'a> {
|
||||||
/// Returns the numer of samples in this buffer.
|
/// Returns the number of samples in this buffer.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn len(&self) -> usize {
|
pub fn len(&self) -> usize {
|
||||||
if self.output_slices.is_empty() {
|
if self.output_slices.is_empty() {
|
||||||
|
@ -38,7 +38,7 @@ impl<'a> Buffer<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the numer of channels in this buffer.
|
/// Returns the number of channels in this buffer.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn channels(&self) -> usize {
|
pub fn channels(&self) -> usize {
|
||||||
self.output_slices.len()
|
self.output_slices.len()
|
||||||
|
@ -76,7 +76,7 @@ impl<'a> Buffer<'a> {
|
||||||
|
|
||||||
/// Iterate over the buffer in blocks with the specified maximum size. The ideal maximum block
|
/// Iterate over the buffer in blocks with the specified maximum size. The ideal maximum block
|
||||||
/// size depends on the plugin in question, but 64 or 128 samples works for most plugins. Since
|
/// size depends on the plugin in question, but 64 or 128 samples works for most plugins. Since
|
||||||
/// the buffer's total size may not be cleanly divisble by the maximum size, the returned
|
/// the buffer's total size may not be cleanly divisible by the maximum size, the returned
|
||||||
/// buffers may have any size in `[1, max_block_size]`. This is useful when using algorithms
|
/// buffers may have any size in `[1, max_block_size]`. This is useful when using algorithms
|
||||||
/// that work on entire blocks of audio, like those that would otherwise need to perform
|
/// that work on entire blocks of audio, like those that would otherwise need to perform
|
||||||
/// expensive per-sample branching or that can use per-sample SIMD as opposed to per-channel
|
/// expensive per-sample branching or that can use per-sample SIMD as opposed to per-channel
|
||||||
|
|
|
@ -131,7 +131,7 @@ impl<'slice, 'sample> Block<'slice, 'sample> {
|
||||||
self.current_block_end - self.current_block_start
|
self.current_block_end - self.current_block_start
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the numer of channels in this buffer.
|
/// Returns the number of channels in this buffer.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn channels(&self) -> usize {
|
pub fn channels(&self) -> usize {
|
||||||
unsafe { (*self.buffers).len() }
|
unsafe { (*self.buffers).len() }
|
||||||
|
|
|
@ -179,7 +179,7 @@ pub struct Transport {
|
||||||
/// [`Plugin::initialize()`][crate::prelude::Plugin::initialize()], so if you need this then you
|
/// [`Plugin::initialize()`][crate::prelude::Plugin::initialize()], so if you need this then you
|
||||||
/// can also store that value.
|
/// can also store that value.
|
||||||
pub sample_rate: f32,
|
pub sample_rate: f32,
|
||||||
/// The proejct's tempo in beats per minute.
|
/// The project's tempo in beats per minute.
|
||||||
pub tempo: Option<f64>,
|
pub tempo: Option<f64>,
|
||||||
/// The time signature's numerator.
|
/// The time signature's numerator.
|
||||||
pub time_sig_numerator: Option<i32>,
|
pub time_sig_numerator: Option<i32>,
|
||||||
|
@ -206,15 +206,15 @@ pub struct Transport {
|
||||||
|
|
||||||
/// The loop range in samples, if the loop is active and this information is available. None of
|
/// The loop range in samples, if the loop is active and this information is available. None of
|
||||||
/// the plugin API docs mention whether this is exclusive or inclusive, but just assume that the
|
/// the plugin API docs mention whether this is exclusive or inclusive, but just assume that the
|
||||||
/// end is exclusive. Can be calulcated from the other loop range information if needed.
|
/// end is exclusive. Can be calculated from the other loop range information if needed.
|
||||||
pub(crate) loop_range_samples: Option<(i64, i64)>,
|
pub(crate) loop_range_samples: Option<(i64, i64)>,
|
||||||
/// The loop range in seconds, if the loop is active and this information is available. None of
|
/// The loop range in seconds, if the loop is active and this information is available. None of
|
||||||
/// the plugin API docs mention whether this is exclusive or inclusive, but just assume that the
|
/// the plugin API docs mention whether this is exclusive or inclusive, but just assume that the
|
||||||
/// end is exclusive. Can be calulcated from the other loop range information if needed.
|
/// end is exclusive. Can be calculated from the other loop range information if needed.
|
||||||
pub(crate) loop_range_seconds: Option<(f64, f64)>,
|
pub(crate) loop_range_seconds: Option<(f64, f64)>,
|
||||||
/// The loop range in quarter notes, if the loop is active and this information is available.
|
/// The loop range in quarter notes, if the loop is active and this information is available.
|
||||||
/// None of the plugin API docs mention whether this is exclusive or inclusive, but just assume
|
/// None of the plugin API docs mention whether this is exclusive or inclusive, but just assume
|
||||||
/// that the end is exclusive. Can be calulcated from the other loop range information if
|
/// that the end is exclusive. Can be calculated from the other loop range information if
|
||||||
/// needed.
|
/// needed.
|
||||||
pub(crate) loop_range_beats: Option<(f64, f64)>,
|
pub(crate) loop_range_beats: Option<(f64, f64)>,
|
||||||
}
|
}
|
||||||
|
@ -440,7 +440,7 @@ impl<'a> ParamSetter<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Inform the host that you will start automating a parmater. This needs to be called before
|
/// Inform the host that you will start automating a parameter. This needs to be called before
|
||||||
/// calling [`set_parameter()`][Self::set_parameter()] for the specified parameter.
|
/// calling [`set_parameter()`][Self::set_parameter()] for the specified parameter.
|
||||||
pub fn begin_set_parameter<P: Param>(&self, param: &P) {
|
pub fn begin_set_parameter<P: Param>(&self, param: &P) {
|
||||||
unsafe { self.raw_context.raw_begin_set_parameter(param.as_ptr()) };
|
unsafe { self.raw_context.raw_begin_set_parameter(param.as_ptr()) };
|
||||||
|
|
|
@ -104,7 +104,7 @@ impl<T, E> Drop for LinuxEventLoop<T, E> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The worker thread used in [`EventLoop`] that executes incmoing tasks on the event loop's
|
/// The worker thread used in [`EventLoop`] that executes incoming tasks on the event loop's
|
||||||
/// executor.
|
/// executor.
|
||||||
fn worker_thread<T, E>(receiver: channel::Receiver<Message<T>>, executor: Weak<E>)
|
fn worker_thread<T, E>(receiver: channel::Receiver<Message<T>>, executor: Weak<E>)
|
||||||
where
|
where
|
||||||
|
|
|
@ -26,10 +26,10 @@ use crate::util::permit_alloc;
|
||||||
const NOTIFY_MESSAGE_ID: u32 = WM_USER;
|
const NOTIFY_MESSAGE_ID: u32 = WM_USER;
|
||||||
|
|
||||||
/// A type erased function passed to the window so it can poll for events. We can't pass the tasks
|
/// A type erased function passed to the window so it can poll for events. We can't pass the tasks
|
||||||
/// queue and executor to the window callback sicne the callback wouldn't know what types they are,
|
/// queue and executor to the window callback since the callback wouldn't know what types they are,
|
||||||
/// but we can wrap the polling loop in a closure and pass that instead.
|
/// but we can wrap the polling loop in a closure and pass that instead.
|
||||||
///
|
///
|
||||||
/// This needs to be double boxed when passed to the function since fat pointers canont be directly
|
/// This needs to be double boxed when passed to the function since fat pointers cannot be directly
|
||||||
/// casted from a regular pointer.
|
/// casted from a regular pointer.
|
||||||
type PollCallback = Box<dyn Fn()>;
|
type PollCallback = Box<dyn Fn()>;
|
||||||
|
|
||||||
|
@ -45,7 +45,7 @@ pub(crate) struct WindowsEventLoop<T, E> {
|
||||||
main_thread_id: ThreadId,
|
main_thread_id: ThreadId,
|
||||||
|
|
||||||
/// An invisible window that we can post a message to when we need to do something on the main
|
/// An invisible window that we can post a message to when we need to do something on the main
|
||||||
/// thread. The host's message loop will then cause our message to be proceded.
|
/// thread. The host's message loop will then cause our message to be proceeded.
|
||||||
message_window: HWND,
|
message_window: HWND,
|
||||||
/// The unique class for the message window, we'll clean this up together with the window.
|
/// The unique class for the message window, we'll clean this up together with the window.
|
||||||
message_window_class_name: CString,
|
message_window_class_name: CString,
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
//! Convenience functions for formatting and parsing parameter values in various common formats.
|
//! Convenience functions for formatting and parsing parameter values in various common formats.
|
||||||
//!
|
//!
|
||||||
//! Functions prefixed with `v2s_` are meant to be used with the `.value_to_string()` parameter
|
//! Functions prefixed with `v2s_` are meant to be used with the `.value_to_string()` parameter
|
||||||
//! fucntions, while the `s2v_` functions are meant to be used wit the `.string_to_value()`.
|
//! functions, while the `s2v_` functions are meant to be used wit the `.string_to_value()`.
|
||||||
//! functions. Most of these formatters come as a pair. Check each formatter's documentation for any
|
//! functions. Most of these formatters come as a pair. Check each formatter's documentation for any
|
||||||
//! additional usage information.
|
//! additional usage information.
|
||||||
|
|
||||||
|
@ -203,7 +203,7 @@ pub fn s2v_i32_note_formatter() -> Arc<dyn Fn(&str) -> Option<i32> + Send + Sync
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Display 'Bypassed' or 'Not Bypassed' depending on whether the parameter is true or false.
|
/// Display 'Bypassed' or 'Not Bypassed' depending on whether the parameter is true or false.
|
||||||
/// 'Enabled' would have also been a possibilty here, but that could be a bit confusing.
|
/// 'Enabled' would have also been a possibility here, but that could be a bit confusing.
|
||||||
pub fn v2s_bool_bypass() -> Arc<dyn Fn(bool) -> String + Send + Sync> {
|
pub fn v2s_bool_bypass() -> Arc<dyn Fn(bool) -> String + Send + Sync> {
|
||||||
Arc::new(move |value| {
|
Arc::new(move |value| {
|
||||||
if value {
|
if value {
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
//! debugger is attached, in which case the output is logged to the debug console instead. The
|
//! debugger is attached, in which case the output is logged to the debug console instead. The
|
||||||
//! `NIH_LOG` environment variable controls whether output is logged to STDERR, the Windows debug
|
//! `NIH_LOG` environment variable controls whether output is logged to STDERR, the Windows debug
|
||||||
//! console, or to a file. Check the [`nih_log!()`] macro for more information.
|
//! console, or to a file. Check the [`nih_log!()`] macro for more information.
|
||||||
//! - The abovementioned debug module also contains non-fatal debug-assertions macros that are only
|
//! - The aforementioned debug module also contains non-fatal debug-assertions macros that are only
|
||||||
//! evaluated during debug builds. The framework uses these all over the place to check for
|
//! evaluated during debug builds. The framework uses these all over the place to check for
|
||||||
//! invariants, so it's important to test your plugins using debug builds while developing.
|
//! invariants, so it's important to test your plugins using debug builds while developing.
|
||||||
//! - Check out the features list in NIH-plug's `Cargo.toml` file for optional features you can
|
//! - Check out the features list in NIH-plug's `Cargo.toml` file for optional features you can
|
||||||
|
@ -38,7 +38,7 @@
|
||||||
//! calculations or IO at this point.
|
//! calculations or IO at this point.
|
||||||
//! 2. The host or the plugin wrapper will call
|
//! 2. The host or the plugin wrapper will call
|
||||||
//! [`Plugin::accepts_bus_config()`][prelude::Plugin::accepts_bus_config()] several times with
|
//! [`Plugin::accepts_bus_config()`][prelude::Plugin::accepts_bus_config()] several times with
|
||||||
//! different IO configuratinos to poll whether your plugin supports certain IO configurations.
|
//! different IO configurations to poll whether your plugin supports certain IO configurations.
|
||||||
//! The plugin should not do any work at this point and just reply with boolean whether it
|
//! The plugin should not do any work at this point and just reply with boolean whether it
|
||||||
//! supports the configuration or not.
|
//! supports the configuration or not.
|
||||||
//! 3. After that, [`Plugin::initialize()`][prelude::Plugin::initialize()] will be called with the
|
//! 3. After that, [`Plugin::initialize()`][prelude::Plugin::initialize()] will be called with the
|
||||||
|
@ -78,7 +78,7 @@
|
||||||
//! out the [`Smoother`][prelude::Smoother] API for more details.
|
//! out the [`Smoother`][prelude::Smoother] API for more details.
|
||||||
//!
|
//!
|
||||||
//! There's a whole lot more to discuss, but once you understand the above you should be able to
|
//! There's a whole lot more to discuss, but once you understand the above you should be able to
|
||||||
//! figure out the rest by reading through the examples and the API documetnation. Good luck!
|
//! figure out the rest by reading through the examples and the API documentation. Good luck!
|
||||||
|
|
||||||
#![cfg_attr(feature = "docs", feature(doc_auto_cfg))]
|
#![cfg_attr(feature = "docs", feature(doc_auto_cfg))]
|
||||||
#![cfg_attr(feature = "simd", feature(portable_simd))]
|
#![cfg_attr(feature = "simd", feature(portable_simd))]
|
||||||
|
|
|
@ -98,7 +98,7 @@ pub enum NoteEvent {
|
||||||
/// monophonic modulation. This is `parameter.value` for unsmoothed parameters, and smoothed
|
/// monophonic modulation. This is `parameter.value` for unsmoothed parameters, and smoothed
|
||||||
/// parameters should use block smoothing so the smoothed values can be reused by multiple
|
/// parameters should use block smoothing so the smoothed values can be reused by multiple
|
||||||
/// voices.
|
/// voices.
|
||||||
/// - If a `PolyModulation` event is emited for the voice, that voice should use the the
|
/// - If a `PolyModulation` event is emitted for the voice, that voice should use the the
|
||||||
/// _normalized offset_ contained within the event to compute the voice's modulated value and
|
/// _normalized offset_ contained within the event to compute the voice's modulated value and
|
||||||
/// use that in place of the global value.
|
/// use that in place of the global value.
|
||||||
/// - This value can be obtained by calling `param.preview_plain(param.normalized_value() +
|
/// - This value can be obtained by calling `param.preview_plain(param.normalized_value() +
|
||||||
|
@ -137,9 +137,9 @@ pub enum NoteEvent {
|
||||||
normalized_offset: f32,
|
normalized_offset: f32,
|
||||||
},
|
},
|
||||||
/// A notification to inform the plugin that a polyphonically modulated parameter has received a
|
/// A notification to inform the plugin that a polyphonically modulated parameter has received a
|
||||||
/// new automation value. This is used in conjuction with the `PolyModulation` event. See that
|
/// new automation value. This is used in conjunction with the `PolyModulation` event. See that
|
||||||
/// event's documentation for more details. The parameter's global value has already been
|
/// event's documentation for more details. The parameter's global value has already been
|
||||||
/// updated when this event is emited.
|
/// updated when this event is emitted.
|
||||||
MonoAutomation {
|
MonoAutomation {
|
||||||
timing: u32,
|
timing: u32,
|
||||||
/// The ID that was set for the modulated parameter using the `.with_poly_modulation_id()`
|
/// The ID that was set for the modulated parameter using the `.with_poly_modulation_id()`
|
||||||
|
|
|
@ -103,7 +103,7 @@ pub trait Param: Display {
|
||||||
self.preview_normalized(self.default_plain_value())
|
self.preview_normalized(self.default_plain_value())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get the number of steps for this paramter, if it is discrete. Used for the host's generic
|
/// Get the number of steps for this parameter, if it is discrete. Used for the host's generic
|
||||||
/// UI.
|
/// UI.
|
||||||
fn step_count(&self) -> Option<usize>;
|
fn step_count(&self) -> Option<usize>;
|
||||||
|
|
||||||
|
|
|
@ -21,7 +21,7 @@ pub struct BoolParam {
|
||||||
/// from the host has been applied. This will always be the same as `value` for VST3 plugins.
|
/// from the host has been applied. This will always be the same as `value` for VST3 plugins.
|
||||||
unmodulated_normalized_value: AtomicF32,
|
unmodulated_normalized_value: AtomicF32,
|
||||||
/// A value in `[-1, 1]` indicating the amount of modulation applied to
|
/// A value in `[-1, 1]` indicating the amount of modulation applied to
|
||||||
/// `unmodulated_normalized_`. This needs to be stored separately since the normalied values are
|
/// `unmodulated_normalized_`. This needs to be stored separately since the normalized values are
|
||||||
/// clamped, and this value persists after new automation events.
|
/// clamped, and this value persists after new automation events.
|
||||||
modulation_offset: AtomicF32,
|
modulation_offset: AtomicF32,
|
||||||
/// The field's default value.
|
/// The field's default value.
|
||||||
|
@ -286,7 +286,7 @@ impl BoolParam {
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Mark the paramter as non-automatable. This means that the parameter cannot be changed from
|
/// Mark the parameter as non-automatable. This means that the parameter cannot be changed from
|
||||||
/// an automation lane. The parameter can however still be manually changed by the user from
|
/// an automation lane. The parameter can however still be manually changed by the user from
|
||||||
/// either the plugin's own GUI or from the host's generic UI.
|
/// either the plugin's own GUI or from the host's generic UI.
|
||||||
pub fn non_automatable(mut self) -> Self {
|
pub fn non_automatable(mut self) -> Self {
|
||||||
|
|
|
@ -63,7 +63,7 @@ pub trait Enum {
|
||||||
|
|
||||||
/// Get the variant corresponding to the variant with the same index in
|
/// Get the variant corresponding to the variant with the same index in
|
||||||
/// [`variants()`][Self::variants()]. This must always return a value. If the index is out of
|
/// [`variants()`][Self::variants()]. This must always return a value. If the index is out of
|
||||||
/// range, return the first variatn.
|
/// range, return the first variant.
|
||||||
fn from_index(index: usize) -> Self;
|
fn from_index(index: usize) -> Self;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -360,7 +360,7 @@ impl<T: Enum + PartialEq + 'static> EnumParam<T> {
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Mark the paramter as non-automatable. This means that the parameter cannot be changed from
|
/// Mark the parameter as non-automatable. This means that the parameter cannot be changed from
|
||||||
/// an automation lane. The parameter can however still be manually changed by the user from
|
/// an automation lane. The parameter can however still be manually changed by the user from
|
||||||
/// either the plugin's own GUI or from the host's generic UI.
|
/// either the plugin's own GUI or from the host's generic UI.
|
||||||
pub fn non_automatable(mut self) -> Self {
|
pub fn non_automatable(mut self) -> Self {
|
||||||
|
|
|
@ -24,7 +24,7 @@ pub struct FloatParam {
|
||||||
/// from the host has been applied. This will always be the same as `value` for VST3 plugins.
|
/// from the host has been applied. This will always be the same as `value` for VST3 plugins.
|
||||||
unmodulated_normalized_value: AtomicF32,
|
unmodulated_normalized_value: AtomicF32,
|
||||||
/// A value in `[-1, 1]` indicating the amount of modulation applied to
|
/// A value in `[-1, 1]` indicating the amount of modulation applied to
|
||||||
/// `unmodulated_normalized_`. This needs to be stored separately since the normalied values are
|
/// `unmodulated_normalized_`. This needs to be stored separately since the normalized values are
|
||||||
/// clamped, and this value persists after new automation events.
|
/// clamped, and this value persists after new automation events.
|
||||||
modulation_offset: AtomicF32,
|
modulation_offset: AtomicF32,
|
||||||
/// The field's default plain, unnormalized value.
|
/// The field's default plain, unnormalized value.
|
||||||
|
@ -39,7 +39,7 @@ pub struct FloatParam {
|
||||||
/// the parameter's new **plain** value. This should not do anything expensive as it may be
|
/// the parameter's new **plain** value. This should not do anything expensive as it may be
|
||||||
/// called multiple times in rapid succession.
|
/// called multiple times in rapid succession.
|
||||||
///
|
///
|
||||||
/// To use this, you'll probably want to store an `Arc<Atomic*>` alongside the parmater in the
|
/// To use this, you'll probably want to store an `Arc<Atomic*>` alongside the parameter in the
|
||||||
/// parameters struct, move a clone of that `Arc` into this closure, and then modify that.
|
/// parameters struct, move a clone of that `Arc` into this closure, and then modify that.
|
||||||
///
|
///
|
||||||
/// TODO: We probably also want to pass the old value to this function.
|
/// TODO: We probably also want to pass the old value to this function.
|
||||||
|
@ -363,7 +363,7 @@ impl FloatParam {
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Mark the paramter as non-automatable. This means that the parameter cannot be changed from
|
/// Mark the parameter as non-automatable. This means that the parameter cannot be changed from
|
||||||
/// an automation lane. The parameter can however still be manually changed by the user from
|
/// an automation lane. The parameter can however still be manually changed by the user from
|
||||||
/// either the plugin's own GUI or from the host's generic UI.
|
/// either the plugin's own GUI or from the host's generic UI.
|
||||||
pub fn non_automatable(mut self) -> Self {
|
pub fn non_automatable(mut self) -> Self {
|
||||||
|
@ -387,7 +387,7 @@ impl FloatParam {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Caldculate how many decimals to round to when displaying a floating point value with a specific
|
/// Calculate how many decimals to round to when displaying a floating point value with a specific
|
||||||
/// step size. We'll perform some rounding to ignore spurious extra precision caused by the floating
|
/// step size. We'll perform some rounding to ignore spurious extra precision caused by the floating
|
||||||
/// point quantization.
|
/// point quantization.
|
||||||
fn decimals_from_step_size(step_size: f32) -> usize {
|
fn decimals_from_step_size(step_size: f32) -> usize {
|
||||||
|
|
|
@ -24,7 +24,7 @@ pub struct IntParam {
|
||||||
/// from the host has been applied. This will always be the same as `value` for VST3 plugins.
|
/// from the host has been applied. This will always be the same as `value` for VST3 plugins.
|
||||||
unmodulated_normalized_value: AtomicF32,
|
unmodulated_normalized_value: AtomicF32,
|
||||||
/// A value in `[-1, 1]` indicating the amount of modulation applied to
|
/// A value in `[-1, 1]` indicating the amount of modulation applied to
|
||||||
/// `unmodulated_normalized_`. This needs to be stored separately since the normalied values are
|
/// `unmodulated_normalized_`. This needs to be stored separately since the normalized values are
|
||||||
/// clamped, and this value persists after new automation events.
|
/// clamped, and this value persists after new automation events.
|
||||||
modulation_offset: AtomicF32,
|
modulation_offset: AtomicF32,
|
||||||
/// The field's default plain, unnormalized value.
|
/// The field's default plain, unnormalized value.
|
||||||
|
@ -39,7 +39,7 @@ pub struct IntParam {
|
||||||
/// the parameter's new **plain** value. This should not do anything expensive as it may be
|
/// the parameter's new **plain** value. This should not do anything expensive as it may be
|
||||||
/// called multiple times in rapid succession.
|
/// called multiple times in rapid succession.
|
||||||
///
|
///
|
||||||
/// To use this, you'll probably want to store an `Arc<Atomic*>` alongside the parmater in the
|
/// To use this, you'll probably want to store an `Arc<Atomic*>` alongside the parameter in the
|
||||||
/// parameters struct, move a clone of that `Arc` into this closure, and then modify that.
|
/// parameters struct, move a clone of that `Arc` into this closure, and then modify that.
|
||||||
///
|
///
|
||||||
/// TODO: We probably also want to pass the old value to this function.
|
/// TODO: We probably also want to pass the old value to this function.
|
||||||
|
@ -332,7 +332,7 @@ impl IntParam {
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Mark the paramter as non-automatable. This means that the parameter cannot be changed from
|
/// Mark the parameter as non-automatable. This means that the parameter cannot be changed from
|
||||||
/// an automation lane. The parameter can however still be manually changed by the user from
|
/// an automation lane. The parameter can however still be manually changed by the user from
|
||||||
/// either the plugin's own GUI or from the host's generic UI.
|
/// either the plugin's own GUI or from the host's generic UI.
|
||||||
pub fn non_automatable(mut self) -> Self {
|
pub fn non_automatable(mut self) -> Self {
|
||||||
|
|
|
@ -39,7 +39,7 @@ pub mod serialize_atomic_cell {
|
||||||
/// This trait can be derived on a struct containing [`FloatParam`][super::FloatParam] and other
|
/// This trait can be derived on a struct containing [`FloatParam`][super::FloatParam] and other
|
||||||
/// parameter fields. When deriving this trait, any of those parameter fields should have the `#[id
|
/// parameter fields. When deriving this trait, any of those parameter fields should have the `#[id
|
||||||
/// = "stable"]` attribute, where `stable` is an up to 6 character long string (to avoid collisions)
|
/// = "stable"]` attribute, where `stable` is an up to 6 character long string (to avoid collisions)
|
||||||
/// that will be used to identify the parameter internall so you can safely move it around and
|
/// that will be used to identify the parameter internally so you can safely move it around and
|
||||||
/// rename the field without breaking compatibility with old presets.
|
/// rename the field without breaking compatibility with old presets.
|
||||||
///
|
///
|
||||||
/// The struct can also contain other fields that should be persisted along with the rest of the
|
/// The struct can also contain other fields that should be persisted along with the rest of the
|
||||||
|
@ -50,7 +50,7 @@ pub mod serialize_atomic_cell {
|
||||||
/// And finally when deriving this trait, it is also possible to inherit the parameters from other
|
/// And finally when deriving this trait, it is also possible to inherit the parameters from other
|
||||||
/// `Params` objects by adding the `#[nested = "Group Name"]` attribute to those fields. These
|
/// `Params` objects by adding the `#[nested = "Group Name"]` attribute to those fields. These
|
||||||
/// groups will be displayed as a tree-like structure if your DAW supports it. Parameter IDs and
|
/// groups will be displayed as a tree-like structure if your DAW supports it. Parameter IDs and
|
||||||
/// persisting keys still need to be **unique** when usting nested parameter structs. This currently
|
/// persisting keys still need to be **unique** when using nested parameter structs. This currently
|
||||||
/// has the following caveats:
|
/// has the following caveats:
|
||||||
///
|
///
|
||||||
/// - Enforcing that parameter IDs and persist keys are unique does not work across nested structs.
|
/// - Enforcing that parameter IDs and persist keys are unique does not work across nested structs.
|
||||||
|
@ -71,13 +71,13 @@ pub unsafe trait Params: 'static + Send + Sync {
|
||||||
/// exist or you may encounter panics. The derive macro does this for every parameter field
|
/// exist or you may encounter panics. The derive macro does this for every parameter field
|
||||||
/// marked with `#[id = "stable"]`, and it also inlines all fields from nested child `Params`
|
/// marked with `#[id = "stable"]`, and it also inlines all fields from nested child `Params`
|
||||||
/// structs marked with `#[nested = "Group Name"]` while prefixing that group name before the
|
/// structs marked with `#[nested = "Group Name"]` while prefixing that group name before the
|
||||||
/// parameter's originanl group name. Dereferencing the pointers stored in the values is only
|
/// parameter's original group name. Dereferencing the pointers stored in the values is only
|
||||||
/// valid as long as this object is valid.
|
/// valid as long as this object is valid.
|
||||||
///
|
///
|
||||||
/// # Note
|
/// # Note
|
||||||
///
|
///
|
||||||
/// This uses `String` even though for the `Params` derive macro `&'static str` would have been
|
/// This uses `String` even though for the `Params` derive macro `&'static str` would have been
|
||||||
/// fine to be able to support custom reusable Params implemnetations.
|
/// fine to be able to support custom reusable Params implementations.
|
||||||
fn param_map(&self) -> Vec<(String, ParamPtr, String)>;
|
fn param_map(&self) -> Vec<(String, ParamPtr, String)>;
|
||||||
|
|
||||||
/// Serialize all fields marked with `#[persist = "stable_name"]` into a hash map containing
|
/// Serialize all fields marked with `#[persist = "stable_name"]` into a hash map containing
|
||||||
|
@ -88,7 +88,7 @@ pub unsafe trait Params: 'static + Send + Sync {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Restore all fields marked with `#[persist = "stable_name"]` from a hashmap created by
|
/// Restore all fields marked with `#[persist = "stable_name"]` from a hashmap created by
|
||||||
/// [`serialize_fields()`][Self::serialize_fields()]. All of thse fields should be wrapped in a
|
/// [`serialize_fields()`][Self::serialize_fields()]. All of these fields should be wrapped in a
|
||||||
/// [`PersistentField`] with thread safe interior mutability, like an `RwLock` or a `Mutex`.
|
/// [`PersistentField`] with thread safe interior mutability, like an `RwLock` or a `Mutex`.
|
||||||
/// This gets called when the plugin's state is being restored. This uses [deserialize_field()]
|
/// This gets called when the plugin's state is being restored. This uses [deserialize_field()]
|
||||||
/// under the hood.
|
/// under the hood.
|
||||||
|
|
|
@ -167,7 +167,7 @@ impl FloatRange {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Snap a vlue to a step size, clamping to the minimum and maximum value of the range.
|
/// Snap a value to a step size, clamping to the minimum and maximum value of the range.
|
||||||
pub fn snap_to_step(&self, value: f32, step_size: f32) -> f32 {
|
pub fn snap_to_step(&self, value: f32, step_size: f32) -> f32 {
|
||||||
match self {
|
match self {
|
||||||
FloatRange::Linear { min, max }
|
FloatRange::Linear { min, max }
|
||||||
|
|
|
@ -47,7 +47,7 @@ pub struct Smoother<T: Smoothable> {
|
||||||
/// uniform.
|
/// uniform.
|
||||||
///
|
///
|
||||||
/// In the case of the `Exponential` smoothing style this is the coefficient `x` that the
|
/// In the case of the `Exponential` smoothing style this is the coefficient `x` that the
|
||||||
/// previous sample is multplied by.
|
/// previous sample is multiplied by.
|
||||||
step_size: AtomicF32,
|
step_size: AtomicF32,
|
||||||
/// The value for the current sample. Always stored as floating point for obvious reasons.
|
/// The value for the current sample. Always stored as floating point for obvious reasons.
|
||||||
current: AtomicF32,
|
current: AtomicF32,
|
||||||
|
@ -119,7 +119,7 @@ impl SmoothingStyle {
|
||||||
/// Compute the next value from `current` leading up to `target` using the `step_size` computed
|
/// Compute the next value from `current` leading up to `target` using the `step_size` computed
|
||||||
/// using [`SmoothingStyle::step_size()`]. Depending on the smoothing style this function may
|
/// using [`SmoothingStyle::step_size()`]. Depending on the smoothing style this function may
|
||||||
/// never completely reach `target`, so you will need to snap to `target` yourself after
|
/// never completely reach `target`, so you will need to snap to `target` yourself after
|
||||||
/// cmoputing the target number of steps.
|
/// computing the target number of steps.
|
||||||
///
|
///
|
||||||
/// See the docstring on the [`SmoothingStyle::next_step()`] function for the formulas used.
|
/// See the docstring on the [`SmoothingStyle::next_step()`] function for the formulas used.
|
||||||
#[inline]
|
#[inline]
|
||||||
|
@ -229,7 +229,7 @@ impl<T: Smoothable> Smoother<T> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Whether calling [`next()`][Self::next()] will yield a new value or an old value. Useful if
|
/// Whether calling [`next()`][Self::next()] will yield a new value or an old value. Useful if
|
||||||
/// you need to recompute something wheenver this parameter changes.
|
/// you need to recompute something whenever this parameter changes.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn is_smoothing(&self) -> bool {
|
pub fn is_smoothing(&self) -> bool {
|
||||||
self.steps_left() > 0
|
self.steps_left() > 0
|
||||||
|
|
|
@ -52,7 +52,7 @@ pub trait Plugin: Default + Send + Sync + 'static {
|
||||||
/// configuration works the same was as with `DEFAULT_INPUT_CHANNELS`.
|
/// configuration works the same was as with `DEFAULT_INPUT_CHANNELS`.
|
||||||
const DEFAULT_AUX_INPUTS: Option<AuxiliaryIOConfig> = None;
|
const DEFAULT_AUX_INPUTS: Option<AuxiliaryIOConfig> = None;
|
||||||
/// If set, then the plugin will have this many auxiliary output busses with a default number of
|
/// If set, then the plugin will have this many auxiliary output busses with a default number of
|
||||||
/// channels. Negotiating the actual configuration wroks the same was as with
|
/// channels. Negotiating the actual configuration works the same was as with
|
||||||
/// `DEFAULT_INPUT_CHANNELS`.
|
/// `DEFAULT_INPUT_CHANNELS`.
|
||||||
const DEFAULT_AUX_OUTPUTS: Option<AuxiliaryIOConfig> = None;
|
const DEFAULT_AUX_OUTPUTS: Option<AuxiliaryIOConfig> = None;
|
||||||
|
|
||||||
|
@ -70,7 +70,7 @@ pub trait Plugin: Default + Send + Sync + 'static {
|
||||||
/// is set to [`MidiConfig::None`], then the plugin won't receive any note events.
|
/// is set to [`MidiConfig::None`], then the plugin won't receive any note events.
|
||||||
const MIDI_INPUT: MidiConfig = MidiConfig::None;
|
const MIDI_INPUT: MidiConfig = MidiConfig::None;
|
||||||
/// Whether the plugin can output note events. If this is set to [`MidiConfig::None`], then the
|
/// Whether the plugin can output note events. If this is set to [`MidiConfig::None`], then the
|
||||||
/// plugin won't have a note output port. When this is set to another value, then in most hsots
|
/// plugin won't have a note output port. When this is set to another value, then in most hosts
|
||||||
/// the plugin will consume all note and MIDI CC input. If you don't want that, then you will
|
/// the plugin will consume all note and MIDI CC input. If you don't want that, then you will
|
||||||
/// need to forward those events yourself.
|
/// need to forward those events yourself.
|
||||||
const MIDI_OUTPUT: MidiConfig = MidiConfig::None;
|
const MIDI_OUTPUT: MidiConfig = MidiConfig::None;
|
||||||
|
@ -117,14 +117,14 @@ pub trait Plugin: Default + Send + Sync + 'static {
|
||||||
/// have already been restored at this point. If based on those parameters (or for any reason
|
/// have already been restored at this point. If based on those parameters (or for any reason
|
||||||
/// whatsoever) the plugin needs to introduce latency, then you can do so here using the process
|
/// whatsoever) the plugin needs to introduce latency, then you can do so here using the process
|
||||||
/// context. Depending on how the host restores plugin state, this function may also be called
|
/// context. Depending on how the host restores plugin state, this function may also be called
|
||||||
/// twice in rapid succession. If the plugin fails to inialize for whatever reason, then this
|
/// twice in rapid succession. If the plugin fails to initialize for whatever reason, then this
|
||||||
/// should return `false`.
|
/// should return `false`.
|
||||||
///
|
///
|
||||||
/// Before this point, the plugin should not have done any expensive initialization. Please
|
/// Before this point, the plugin should not have done any expensive initialization. Please
|
||||||
/// don't be that plugin that takes twenty seconds to scan.
|
/// don't be that plugin that takes twenty seconds to scan.
|
||||||
///
|
///
|
||||||
/// After this function [`reset()`][Self::reset()] will always be called. If you need to clear
|
/// After this function [`reset()`][Self::reset()] will always be called. If you need to clear
|
||||||
/// state, such as filters or envelopes, then you should do so in that function inistead.
|
/// state, such as filters or envelopes, then you should do so in that function instead.
|
||||||
fn initialize(
|
fn initialize(
|
||||||
&mut self,
|
&mut self,
|
||||||
bus_config: &BusConfig,
|
bus_config: &BusConfig,
|
||||||
|
@ -141,9 +141,9 @@ pub trait Plugin: Default + Send + Sync + 'static {
|
||||||
|
|
||||||
/// Process audio. The host's input buffers have already been copied to the output buffers if
|
/// Process audio. The host's input buffers have already been copied to the output buffers if
|
||||||
/// they are not processing audio in place (most hosts do however). All channels are also
|
/// they are not processing audio in place (most hosts do however). All channels are also
|
||||||
/// guarenteed to contain the same number of samples. Lastly, denormals have already been taken
|
/// guaranteed to contain the same number of samples. Lastly, denormals have already been taken
|
||||||
/// case of by NIH-plug, and you can optionally enable the `assert_process_allocs` feature to
|
/// case of by NIH-plug, and you can optionally enable the `assert_process_allocs` feature to
|
||||||
/// abort the program when any allocation accurs in the process function while running in debug
|
/// abort the program when any allocation occurs in the process function while running in debug
|
||||||
/// mode.
|
/// mode.
|
||||||
///
|
///
|
||||||
/// The framework provides convenient iterators on the [`Buffer`] object to process audio either
|
/// The framework provides convenient iterators on the [`Buffer`] object to process audio either
|
||||||
|
@ -159,7 +159,7 @@ pub trait Plugin: Default + Send + Sync + 'static {
|
||||||
/// auxiliary output buffers if it has any.
|
/// auxiliary output buffers if it has any.
|
||||||
///
|
///
|
||||||
/// TODO: Provide a way to access auxiliary input channels if the IO configuration is
|
/// TODO: Provide a way to access auxiliary input channels if the IO configuration is
|
||||||
/// assymetric
|
/// asymmetric
|
||||||
fn process(
|
fn process(
|
||||||
&mut self,
|
&mut self,
|
||||||
buffer: &mut Buffer,
|
buffer: &mut Buffer,
|
||||||
|
@ -205,7 +205,7 @@ pub trait Vst3Plugin: Plugin {
|
||||||
/// This will be shuffled into a different byte order on Windows for project-compatibility.
|
/// This will be shuffled into a different byte order on Windows for project-compatibility.
|
||||||
const VST3_CLASS_ID: [u8; 16];
|
const VST3_CLASS_ID: [u8; 16];
|
||||||
/// One or more categories, separated by pipe characters (`|`), up to 127 characters. Anything
|
/// One or more categories, separated by pipe characters (`|`), up to 127 characters. Anything
|
||||||
/// logner than that will be truncated. See the VST3 SDK for examples of common categories:
|
/// longer than that will be truncated. See the VST3 SDK for examples of common categories:
|
||||||
/// <https://github.com/steinbergmedia/vst3_pluginterfaces/blob/2ad397ade5b51007860bedb3b01b8afd2c5f6fba/vst/ivstaudioprocessor.h#L49-L90>
|
/// <https://github.com/steinbergmedia/vst3_pluginterfaces/blob/2ad397ade5b51007860bedb3b01b8afd2c5f6fba/vst/ivstaudioprocessor.h#L49-L90>
|
||||||
//
|
//
|
||||||
// TODO: Create a category enum similar to ClapFeature
|
// TODO: Create a category enum similar to ClapFeature
|
||||||
|
@ -271,7 +271,7 @@ pub trait Editor: Send + Sync {
|
||||||
context: Arc<dyn GuiContext>,
|
context: Arc<dyn GuiContext>,
|
||||||
) -> Box<dyn Any + Send + Sync>;
|
) -> Box<dyn Any + Send + Sync>;
|
||||||
|
|
||||||
/// Returns the (currnent) size of the editor in pixels as a `(width, height)` pair. This size
|
/// Returns the (current) size of the editor in pixels as a `(width, height)` pair. This size
|
||||||
/// must be reported in _logical pixels_, i.e. the size before being multiplied by the DPI
|
/// must be reported in _logical pixels_, i.e. the size before being multiplied by the DPI
|
||||||
/// scaling factor to get the actual physical screen pixels.
|
/// scaling factor to get the actual physical screen pixels.
|
||||||
fn size(&self) -> (u32, u32);
|
fn size(&self) -> (u32, u32);
|
||||||
|
@ -285,7 +285,7 @@ pub trait Editor: Send + Sync {
|
||||||
/// there.
|
/// there.
|
||||||
fn set_scale_factor(&self, factor: f32) -> bool;
|
fn set_scale_factor(&self, factor: f32) -> bool;
|
||||||
|
|
||||||
/// A callback that will be called wheneer the parameter values changed while the editor is
|
/// A callback that will be called whenever the parameter values changed while the editor is
|
||||||
/// open. You don't need to do anything with this, but this can be used to force a redraw when
|
/// open. You don't need to do anything with this, but this can be used to force a redraw when
|
||||||
/// the host sends a new value for a parameter or when a parameter change sent to the host gets
|
/// the host sends a new value for a parameter or when a parameter change sent to the host gets
|
||||||
/// processed.
|
/// processed.
|
||||||
|
@ -325,7 +325,7 @@ pub struct BusConfig {
|
||||||
pub aux_output_busses: AuxiliaryIOConfig,
|
pub aux_output_busses: AuxiliaryIOConfig,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Configuration for auxiliary inputs or outputs on [`BusCofnig`].
|
/// Configuration for auxiliary inputs or outputs on [`BusConfig`].
|
||||||
#[derive(Debug, Default, Clone, Copy, PartialEq, Eq)]
|
#[derive(Debug, Default, Clone, Copy, PartialEq, Eq)]
|
||||||
pub struct AuxiliaryIOConfig {
|
pub struct AuxiliaryIOConfig {
|
||||||
/// The number of auxiliary input or output busses.
|
/// The number of auxiliary input or output busses.
|
||||||
|
@ -389,7 +389,7 @@ pub enum ProcessStatus {
|
||||||
Tail(u32),
|
Tail(u32),
|
||||||
/// This plugin will continue to produce sound regardless of whether or not the input is silent,
|
/// This plugin will continue to produce sound regardless of whether or not the input is silent,
|
||||||
/// and should thus not be deactivated by the host. This is essentially the same as having an
|
/// and should thus not be deactivated by the host. This is essentially the same as having an
|
||||||
/// infite tail.
|
/// infinite tail.
|
||||||
KeepAlive,
|
KeepAlive,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -57,7 +57,7 @@ pub struct StftHelper<const NUM_SIDECHAIN_INPUTS: usize = 0> {
|
||||||
padding: usize,
|
padding: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Marker struct for the version wtihout sidechaining.
|
/// Marker struct for the version without sidechaining.
|
||||||
struct NoSidechain;
|
struct NoSidechain;
|
||||||
|
|
||||||
impl StftInput for Buffer<'_> {
|
impl StftInput for Buffer<'_> {
|
||||||
|
@ -255,7 +255,7 @@ impl<const NUM_SIDECHAIN_INPUTS: usize> StftHelper<NUM_SIDECHAIN_INPUTS> {
|
||||||
self.main_input_ring_buffers.capacity()
|
self.main_input_ring_buffers.capacity()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The amount of latency introduced when processing audio throug hthis [`StftHelper`].
|
/// The amount of latency introduced when processing audio through this [`StftHelper`].
|
||||||
pub fn latency_samples(&self) -> u32 {
|
pub fn latency_samples(&self) -> u32 {
|
||||||
self.main_input_ring_buffers[0].len() as u32
|
self.main_input_ring_buffers[0].len() as u32
|
||||||
}
|
}
|
||||||
|
@ -496,7 +496,7 @@ impl<const NUM_SIDECHAIN_INPUTS: usize> StftHelper<NUM_SIDECHAIN_INPUTS> {
|
||||||
/// Similar to [`process_overlap_add()`][Self::process_overlap_add()], but without the inverse
|
/// Similar to [`process_overlap_add()`][Self::process_overlap_add()], but without the inverse
|
||||||
/// STFT part. `buffer` will only ever be read from. This can be useful for providing FFT data
|
/// STFT part. `buffer` will only ever be read from. This can be useful for providing FFT data
|
||||||
/// for a spectrum analyzer in a plugin GUI. These is still a delay to the analysis equal to the
|
/// for a spectrum analyzer in a plugin GUI. These is still a delay to the analysis equal to the
|
||||||
/// blcok size.
|
/// block size.
|
||||||
pub fn process_analyze_only<B, F>(
|
pub fn process_analyze_only<B, F>(
|
||||||
&mut self,
|
&mut self,
|
||||||
buffer: &B,
|
buffer: &B,
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
//! Windowing functions, useful in conjuction with [`StftHelper`][super::StftHelper].
|
//! Windowing functions, useful in conjunction with [`StftHelper`][super::StftHelper].
|
||||||
|
|
||||||
use std::f32;
|
use std::f32;
|
||||||
|
|
||||||
|
|
|
@ -10,7 +10,7 @@ use super::descriptor::PluginDescriptor;
|
||||||
use super::wrapper::Wrapper;
|
use super::wrapper::Wrapper;
|
||||||
use crate::plugin::ClapPlugin;
|
use crate::plugin::ClapPlugin;
|
||||||
|
|
||||||
/// The plugin's factory. Initialized using a lazy_static from the entry poiunt's `get_factory()`
|
/// The plugin's factory. Initialized using a lazy_static from the entry point's `get_factory()`
|
||||||
/// function. From this point onwards we don't need to generate code with macros anymore.
|
/// function. From this point onwards we don't need to generate code with macros anymore.
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
|
|
|
@ -28,7 +28,7 @@ macro_rules! check_null_ptr_msg {
|
||||||
/// be null pointers, people will still use null pointers for some of the function arguments. This
|
/// be null pointers, people will still use null pointers for some of the function arguments. This
|
||||||
/// also happens in the official `clap-helpers`. As such, these functions are now `Option<fn(...)>`
|
/// also happens in the official `clap-helpers`. As such, these functions are now `Option<fn(...)>`
|
||||||
/// optional function pointers in `clap-sys`. This macro asserts that the pointer is not null, and
|
/// optional function pointers in `clap-sys`. This macro asserts that the pointer is not null, and
|
||||||
/// prints a nicely formatted error message containing the struct and funciton name if it is. It
|
/// prints a nicely formatted error message containing the struct and function name if it is. It
|
||||||
/// also emulates C's syntax for accessing fields struct through a pointer. Except that it uses `=>`
|
/// also emulates C's syntax for accessing fields struct through a pointer. Except that it uses `=>`
|
||||||
/// instead of `->`. Because that sounds like it would be hilarious.
|
/// instead of `->`. Because that sounds like it would be hilarious.
|
||||||
macro_rules! clap_call {
|
macro_rules! clap_call {
|
||||||
|
|
|
@ -143,10 +143,10 @@ pub struct Wrapper<P: ClapPlugin> {
|
||||||
/// The last process status returned by the plugin. This is used for tail handling.
|
/// The last process status returned by the plugin. This is used for tail handling.
|
||||||
last_process_status: AtomicCell<ProcessStatus>,
|
last_process_status: AtomicCell<ProcessStatus>,
|
||||||
/// The current latency in samples, as set by the plugin through the [`ProcessContext`]. uses
|
/// The current latency in samples, as set by the plugin through the [`ProcessContext`]. uses
|
||||||
/// the latency extnesion
|
/// the latency extension
|
||||||
pub current_latency: AtomicU32,
|
pub current_latency: AtomicU32,
|
||||||
/// Contains slices for the plugin's outputs. You can't directly create a nested slice form
|
/// Contains slices for the plugin's outputs. You can't directly create a nested slice from
|
||||||
/// apointer to pointers, so this needs to be preallocated in the setup call and kept around
|
/// a pointer to pointers, so this needs to be preallocated in the setup call and kept around
|
||||||
/// between process calls. This buffer owns the vector, because otherwise it would need to store
|
/// between process calls. This buffer owns the vector, because otherwise it would need to store
|
||||||
/// a mutable reference to the data contained in this mutex.
|
/// a mutable reference to the data contained in this mutex.
|
||||||
output_buffer: AtomicRefCell<Buffer<'static>>,
|
output_buffer: AtomicRefCell<Buffer<'static>>,
|
||||||
|
@ -215,7 +215,7 @@ pub struct Wrapper<P: ClapPlugin> {
|
||||||
/// by slashes, and they're only used to allow the DAW to display parameters in a tree
|
/// by slashes, and they're only used to allow the DAW to display parameters in a tree
|
||||||
/// structure.
|
/// structure.
|
||||||
param_group_by_hash: HashMap<u32, String>,
|
param_group_by_hash: HashMap<u32, String>,
|
||||||
/// Mappings from string parameter indentifiers to parameter hashes. Useful for debug logging
|
/// Mappings from string parameter identifiers to parameter hashes. Useful for debug logging
|
||||||
/// and when storing and restoring plugin state.
|
/// and when storing and restoring plugin state.
|
||||||
param_id_to_hash: HashMap<String, u32>,
|
param_id_to_hash: HashMap<String, u32>,
|
||||||
/// The inverse mapping from [`param_by_hash`][Self::param_by_hash]. This is needed to be able
|
/// The inverse mapping from [`param_by_hash`][Self::param_by_hash]. This is needed to be able
|
||||||
|
@ -230,7 +230,7 @@ pub struct Wrapper<P: ClapPlugin> {
|
||||||
/// A queue of parameter changes and gestures that should be output in either the next process
|
/// A queue of parameter changes and gestures that should be output in either the next process
|
||||||
/// call or in the next parameter flush.
|
/// call or in the next parameter flush.
|
||||||
///
|
///
|
||||||
/// XXX: There's no guarentee that a single parameter doesn't occur twice in this queue, but
|
/// XXX: There's no guarantee that a single parameter doesn't occur twice in this queue, but
|
||||||
/// even if it does then that should still not be a problem because the host also reads it
|
/// even if it does then that should still not be a problem because the host also reads it
|
||||||
/// in the same order, right?
|
/// in the same order, right?
|
||||||
output_parameter_events: ArrayQueue<OutputParamEvent>,
|
output_parameter_events: ArrayQueue<OutputParamEvent>,
|
||||||
|
@ -690,7 +690,7 @@ impl<P: ClapPlugin> Wrapper<P> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Queue a parmeter output event to be sent to the host at the end of the audio processing
|
/// Queue a parameter output event to be sent to the host at the end of the audio processing
|
||||||
/// cycle, and request a parameter flush from the host if the plugin is not currently processing
|
/// cycle, and request a parameter flush from the host if the plugin is not currently processing
|
||||||
/// audio. The parameter's actual value will only be updated at that point so the value won't
|
/// audio. The parameter's actual value will only be updated at that point so the value won't
|
||||||
/// change in the middle of a processing call.
|
/// change in the middle of a processing call.
|
||||||
|
@ -746,7 +746,7 @@ impl<P: ClapPlugin> Wrapper<P> {
|
||||||
///
|
///
|
||||||
/// After calling this function, you should call
|
/// After calling this function, you should call
|
||||||
/// [`notify_param_values_changed()`][Self::notify_param_values_changed()] to allow the editor
|
/// [`notify_param_values_changed()`][Self::notify_param_values_changed()] to allow the editor
|
||||||
/// to update itself. This needs to be done seperately so you can process parameter changes in
|
/// to update itself. This needs to be done separately so you can process parameter changes in
|
||||||
/// batches.
|
/// batches.
|
||||||
///
|
///
|
||||||
/// # Note
|
/// # Note
|
||||||
|
@ -812,13 +812,13 @@ impl<P: ClapPlugin> Wrapper<P> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Similar to [`handle_in_events()`][Self::handle_in_events()], but will stop just before an
|
/// Similar to [`handle_in_events()`][Self::handle_in_events()], but will stop just before an
|
||||||
/// event if the preducate returns true for that events. This predicate is only called for
|
/// event if the predicate returns true for that events. This predicate is only called for
|
||||||
/// events that occur after `current_sample_idx`. This is used to stop before a tempo or time
|
/// events that occur after `current_sample_idx`. This is used to stop before a tempo or time
|
||||||
/// signature change, or before next parameter change event with `raw_event.time >
|
/// signature change, or before next parameter change event with `raw_event.time >
|
||||||
/// current_sample_idx` and return the **absolute** (relative to the entire buffer that's being
|
/// current_sample_idx` and return the **absolute** (relative to the entire buffer that's being
|
||||||
/// split) sample index of that event along with the its index in the event queue as a
|
/// split) sample index of that event along with the its index in the event queue as a
|
||||||
/// `(sample_idx, event_idx)` tuple. This allows for splitting the audio buffer into segments
|
/// `(sample_idx, event_idx)` tuple. This allows for splitting the audio buffer into segments
|
||||||
/// with distinct sample values to enable sample accurate automation without modifcations to the
|
/// with distinct sample values to enable sample accurate automation without modifications to the
|
||||||
/// wrapped plugin.
|
/// wrapped plugin.
|
||||||
pub unsafe fn handle_in_events_until(
|
pub unsafe fn handle_in_events_until(
|
||||||
&self,
|
&self,
|
||||||
|
@ -3199,7 +3199,7 @@ impl<P: ClapPlugin> Wrapper<P> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Convenience function to query an extennsion from the host.
|
/// Convenience function to query an extension from the host.
|
||||||
///
|
///
|
||||||
/// # Safety
|
/// # Safety
|
||||||
///
|
///
|
||||||
|
|
|
@ -318,7 +318,7 @@ impl<P: Plugin, B: Backend> Wrapper<P, B> {
|
||||||
/// processing cycle, and this won't do anything if the parameter has not been registered by the
|
/// processing cycle, and this won't do anything if the parameter has not been registered by the
|
||||||
/// plugin.
|
/// plugin.
|
||||||
///
|
///
|
||||||
/// This returns false if the parmeter was not set because the `Paramptr` was either unknown or
|
/// This returns false if the parameter was not set because the `ParamPtr` was either unknown or
|
||||||
/// the queue is full.
|
/// the queue is full.
|
||||||
pub fn set_parameter(&self, param: ParamPtr, normalized: f32) -> bool {
|
pub fn set_parameter(&self, param: ParamPtr, normalized: f32) -> bool {
|
||||||
if !self.known_parameters.contains(¶m) {
|
if !self.known_parameters.contains(¶m) {
|
||||||
|
|
|
@ -40,9 +40,9 @@ pub struct PluginState {
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
pub version: String,
|
pub version: String,
|
||||||
|
|
||||||
/// The plugin's parameter values. These are stored unnormalized. This mean sthe old values will
|
/// The plugin's parameter values. These are stored unnormalized. This means the old values will
|
||||||
/// be recalled when when the parameter's range gets increased. Doing so may still mess with
|
/// be recalled when when the parameter's range gets increased. Doing so may still mess with
|
||||||
/// parameter automation though, depending on how the host impelments that.
|
/// parameter automation though, depending on how the host implements that.
|
||||||
pub params: BTreeMap<String, ParamValue>,
|
pub params: BTreeMap<String, ParamValue>,
|
||||||
/// Arbitrary fields that should be persisted together with the plugin's parameters. Any field
|
/// Arbitrary fields that should be persisted together with the plugin's parameters. Any field
|
||||||
/// on the [`Params`][crate::param::internals::Params] struct that's annotated with `#[persist =
|
/// on the [`Params`][crate::param::internals::Params] struct that's annotated with `#[persist =
|
||||||
|
|
|
@ -13,7 +13,7 @@ use super::wrapper::Wrapper;
|
||||||
use crate::plugin::Vst3Plugin;
|
use crate::plugin::Vst3Plugin;
|
||||||
use crate::wrapper::util::strlcpy;
|
use crate::wrapper::util::strlcpy;
|
||||||
|
|
||||||
/// The VST3 SDK version this is roughtly based on. The bindings include some VST 3.7 things but not
|
/// The VST3 SDK version this is roughly based on. The bindings include some VST 3.7 things but not
|
||||||
/// everything, so we'll play it safe.
|
/// everything, so we'll play it safe.
|
||||||
const VST3_SDK_VERSION: &str = "VST 3.6.14";
|
const VST3_SDK_VERSION: &str = "VST 3.6.14";
|
||||||
|
|
||||||
|
|
|
@ -55,7 +55,7 @@ pub(crate) struct WrapperInner<P: Vst3Plugin> {
|
||||||
/// This AtomicRefCell+Option is only needed because it has to be initialized late. There is no
|
/// This AtomicRefCell+Option is only needed because it has to be initialized late. There is no
|
||||||
/// reason to mutably borrow the event loop, so reads will never be contested.
|
/// reason to mutably borrow the event loop, so reads will never be contested.
|
||||||
///
|
///
|
||||||
/// TODO: Is there a better type for Send+Sync late initializaiton?
|
/// TODO: Is there a better type for Send+Sync late initialization?
|
||||||
pub event_loop: AtomicRefCell<Option<OsEventLoop<Task, Self>>>,
|
pub event_loop: AtomicRefCell<Option<OsEventLoop<Task, Self>>>,
|
||||||
|
|
||||||
/// Whether the plugin is currently processing audio. In other words, the last state
|
/// Whether the plugin is currently processing audio. In other words, the last state
|
||||||
|
@ -72,8 +72,8 @@ pub(crate) struct WrapperInner<P: Vst3Plugin> {
|
||||||
pub last_process_status: AtomicCell<ProcessStatus>,
|
pub last_process_status: AtomicCell<ProcessStatus>,
|
||||||
/// The current latency in samples, as set by the plugin through the [`ProcessContext`].
|
/// The current latency in samples, as set by the plugin through the [`ProcessContext`].
|
||||||
pub current_latency: AtomicU32,
|
pub current_latency: AtomicU32,
|
||||||
/// Contains slices for the plugin's outputs. You can't directly create a nested slice form
|
/// Contains slices for the plugin's outputs. You can't directly create a nested slice from
|
||||||
/// apointer to pointers, so this needs to be preallocated in the setup call and kept around
|
/// a pointer to pointers, so this needs to be preallocated in the setup call and kept around
|
||||||
/// between process calls. This buffer owns the vector, because otherwise it would need to store
|
/// between process calls. This buffer owns the vector, because otherwise it would need to store
|
||||||
/// a mutable reference to the data contained in this mutex.
|
/// a mutable reference to the data contained in this mutex.
|
||||||
pub output_buffer: AtomicRefCell<Buffer<'static>>,
|
pub output_buffer: AtomicRefCell<Buffer<'static>>,
|
||||||
|
@ -102,7 +102,7 @@ pub(crate) struct WrapperInner<P: Vst3Plugin> {
|
||||||
pub output_events: AtomicRefCell<VecDeque<NoteEvent>>,
|
pub output_events: AtomicRefCell<VecDeque<NoteEvent>>,
|
||||||
/// VST3 has several useful predefined note expressions, but for some reason they are the only
|
/// VST3 has several useful predefined note expressions, but for some reason they are the only
|
||||||
/// note event type that don't have MIDI note ID and channel fields. So we need to keep track of
|
/// note event type that don't have MIDI note ID and channel fields. So we need to keep track of
|
||||||
/// the msot recent VST3 note IDs we've seen, and then map those back to MIDI note IDs and
|
/// the most recent VST3 note IDs we've seen, and then map those back to MIDI note IDs and
|
||||||
/// channels as needed.
|
/// channels as needed.
|
||||||
pub note_expression_controller: AtomicRefCell<NoteExpressionController>,
|
pub note_expression_controller: AtomicRefCell<NoteExpressionController>,
|
||||||
/// Unprocessed parameter changes and note events sent by the host during a process call.
|
/// Unprocessed parameter changes and note events sent by the host during a process call.
|
||||||
|
@ -134,8 +134,8 @@ pub(crate) struct WrapperInner<P: Vst3Plugin> {
|
||||||
/// `params` object does not get deallocated.
|
/// `params` object does not get deallocated.
|
||||||
pub param_by_hash: HashMap<u32, ParamPtr>,
|
pub param_by_hash: HashMap<u32, ParamPtr>,
|
||||||
pub param_units: ParamUnits,
|
pub param_units: ParamUnits,
|
||||||
/// Mappings from string parameter indentifiers to parameter hashes. Useful for debug logging
|
/// Mappings from string parameter identifiers to parameter hashes. Useful for debug logging
|
||||||
/// and when storing and restorign plugin state.
|
/// and when storing and restoring plugin state.
|
||||||
pub param_id_to_hash: HashMap<String, u32>,
|
pub param_id_to_hash: HashMap<String, u32>,
|
||||||
/// The inverse mapping from [`param_by_hash`][Self::param_by_hash]. This is needed to be able
|
/// The inverse mapping from [`param_by_hash`][Self::param_by_hash]. This is needed to be able
|
||||||
/// to have an ergonomic parameter setting API that uses references to the parameters instead of
|
/// to have an ergonomic parameter setting API that uses references to the parameters instead of
|
||||||
|
@ -153,7 +153,7 @@ pub enum Task {
|
||||||
/// [`vst3_sys::vst::RestartFlags`].
|
/// [`vst3_sys::vst::RestartFlags`].
|
||||||
TriggerRestart(i32),
|
TriggerRestart(i32),
|
||||||
/// Request the editor to be resized according to its current size. Right now there is no way to
|
/// Request the editor to be resized according to its current size. Right now there is no way to
|
||||||
/// handle denied resize requestsyet.
|
/// handle "denied resize" requests yet.
|
||||||
RequestResize,
|
RequestResize,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -384,7 +384,7 @@ impl<P: Vst3Plugin> WrapperInner<P> {
|
||||||
///
|
///
|
||||||
/// After calling this function, you should call
|
/// After calling this function, you should call
|
||||||
/// [`notify_param_values_changed()`][Self::notify_param_values_changed()] to allow the editor
|
/// [`notify_param_values_changed()`][Self::notify_param_values_changed()] to allow the editor
|
||||||
/// to update itself. This needs to be done seperately so you can process parameter changes in
|
/// to update itself. This needs to be done separately so you can process parameter changes in
|
||||||
/// batches.
|
/// batches.
|
||||||
pub fn set_normalized_value_by_hash(
|
pub fn set_normalized_value_by_hash(
|
||||||
&self,
|
&self,
|
||||||
|
|
|
@ -26,7 +26,7 @@ pub const EXPRESSION_EXPRESSION_ID: u32 = 4;
|
||||||
pub const BRIGHTNESS_EXPRESSION_ID: u32 = 5;
|
pub const BRIGHTNESS_EXPRESSION_ID: u32 = 5;
|
||||||
|
|
||||||
/// The note expressions we support. It's completely undocumented, but apparently VST3 plugins need
|
/// The note expressions we support. It's completely undocumented, but apparently VST3 plugins need
|
||||||
/// to specifically define a custom note expression for the predefined note expressiosn for them to
|
/// to specifically define a custom note expression for the predefined note expressions for them to
|
||||||
/// work.
|
/// work.
|
||||||
pub const KNOWN_NOTE_EXPRESSIONS: [NoteExpressionInfo; 6] = [
|
pub const KNOWN_NOTE_EXPRESSIONS: [NoteExpressionInfo; 6] = [
|
||||||
NoteExpressionInfo {
|
NoteExpressionInfo {
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
//! Parameter hierarchies in VST3 requires you to define units, which are linearly indexed logical
|
//! Parameter hierarchies in VST3 requires you to define units, which are linearly indexed logical
|
||||||
//! units that have a name, a parent, and then a whole bunch of other data like note numbers and
|
//! units that have a name, a parent, and then a whole bunch of other data like note numbers and
|
||||||
//! MIDI program state. We'll need to implement some of that to conver our list of slash-separated
|
//! MIDI program state. We'll need to implement some of that to convert our list of slash-separated
|
||||||
//! parameter group paths to units.
|
//! parameter group paths to units.
|
||||||
//!
|
//!
|
||||||
//! <https://steinbergmedia.github.io/vst3_doc/vstinterfaces/classSteinberg_1_1Vst_1_1IUnitInfo.html>
|
//! <https://steinbergmedia.github.io/vst3_doc/vstinterfaces/classSteinberg_1_1Vst_1_1IUnitInfo.html>
|
||||||
|
@ -152,7 +152,7 @@ impl ParamUnits {
|
||||||
Some((index as i32 + 1, info))
|
Some((index as i32 + 1, info))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get the ID of the unit the paramter belongs to or. `kRootUnitId`/0 indicates the root unit.
|
/// Get the ID of the unit the parameter belongs to. `kRootUnitId`/0 indicates the root unit.
|
||||||
pub fn get_vst3_unit_id(&self, param_hash: u32) -> Option<i32> {
|
pub fn get_vst3_unit_id(&self, param_hash: u32) -> Option<i32> {
|
||||||
self.unit_id_by_hash.get(¶m_hash).copied()
|
self.unit_id_by_hash.get(¶m_hash).copied()
|
||||||
}
|
}
|
||||||
|
|
|
@ -80,7 +80,7 @@ struct RunLoopEventHandler<P: Vst3Plugin> {
|
||||||
/// this object gets dropped so no work is lost.
|
/// this object gets dropped so no work is lost.
|
||||||
inner: Arc<WrapperInner<P>>,
|
inner: Arc<WrapperInner<P>>,
|
||||||
|
|
||||||
/// The host's run lopp interface. This lets us run tasks on the same thread as the host's UI.
|
/// The host's run loop interface. This lets us run tasks on the same thread as the host's UI.
|
||||||
run_loop: VstPtr<dyn IRunLoop>,
|
run_loop: VstPtr<dyn IRunLoop>,
|
||||||
|
|
||||||
/// We need a Unix domain socket the host can poll to know that we have an event to handle. In
|
/// We need a Unix domain socket the host can poll to know that we have an event to handle. In
|
||||||
|
|
Loading…
Reference in a new issue