1
0
Fork 0

Update rustdoc formatting for links

Apparently it showed this text verbatim, and not in monospace.
This commit is contained in:
Robbert van der Helm 2022-03-03 23:05:01 +01:00
parent ca461d3d15
commit f581294d7b
32 changed files with 232 additions and 209 deletions

View file

@ -5,6 +5,7 @@ use quote::quote;
use std::collections::HashSet; use std::collections::HashSet;
use syn::spanned::Spanned; use syn::spanned::Spanned;
/// Derive the `Params` trait for your plugin's parameters struct. See the `Plugin` trait.
#[proc_macro_derive(Params, attributes(id, persist, nested))] #[proc_macro_derive(Params, attributes(id, persist, nested))]
pub fn derive_params(input: TokenStream) -> TokenStream { pub fn derive_params(input: TokenStream) -> TokenStream {
let ast = syn::parse_macro_input!(input as syn::DeriveInput); let ast = syn::parse_macro_input!(input as syn::DeriveInput);
@ -265,6 +266,7 @@ pub fn derive_params(input: TokenStream) -> TokenStream {
.into() .into()
} }
/// Derive the `Enum` trait for your simple enum parameters. See `EnumParam` for more information.
#[proc_macro_derive(Enum, attributes(name))] #[proc_macro_derive(Enum, attributes(name))]
pub fn derive_enum(input: TokenStream) -> TokenStream { pub fn derive_enum(input: TokenStream) -> TokenStream {
let ast = syn::parse_macro_input!(input as syn::DeriveInput); let ast = syn::parse_macro_input!(input as syn::DeriveInput);

View file

@ -17,16 +17,16 @@ pub use egui;
pub mod widgets; pub mod widgets;
/// Create an [Editor] instance using an [::egui] GUI. Using the user state parameter is optional, /// Create an [`Editor`] instance using an [`egui`][::egui] GUI. Using the user state parameter is
/// but it can be useful for keeping track of some temporary GUI-only settings. See the `gui_gain` /// optional, but it can be useful for keeping track of some temporary GUI-only settings. See the
/// example for more information on how to use this. The [EguiState] passed to this function /// `gui_gain` example for more information on how to use this. The [`EguiState`] passed to this
/// contains the GUI's intitial size, and this is kept in sync whenever the GUI gets resized. You /// function contains the GUI's intitial size, and this is kept in sync whenever the GUI gets
/// can also use this to know if the GUI is open, so you can avoid performing potentially expensive /// resized. You can also use this to know if the GUI is open, so you can avoid performing
/// calculations while the GUI is not open. If you want this size to be persisted when restoring a /// potentially expensive calculations while the GUI is not open. If you want this size to be
/// plugin instance, then you can store it in a `#[persist = "key"]` field on your parameters /// persisted when restoring a plugin instance, then you can store it in a `#[persist = "key"]`
/// struct. /// field on your parameters struct.
/// ///
/// See [EguiState::from_size()]. /// See [`EguiState::from_size()`].
// //
// TODO: DPI scaling, this needs to be implemented on the framework level // TODO: DPI scaling, this needs to be implemented on the framework level
pub fn create_egui_editor<T, U>( pub fn create_egui_editor<T, U>(
@ -53,7 +53,7 @@ pub struct EguiState {
} }
impl EguiState { impl EguiState {
/// Initialize the GUI's state. This is passed to [create_egui_editor()]. /// Initialize the GUI's state. This is passed to [`create_egui_editor()`].
pub fn from_size(width: u32, height: u32) -> Arc<EguiState> { pub fn from_size(width: u32, height: u32) -> Arc<EguiState> {
Arc::new(EguiState { Arc::new(EguiState {
size: AtomicCell::new((width, height)), size: AtomicCell::new((width, height)),
@ -73,7 +73,7 @@ impl EguiState {
} }
} }
/// An [Editor] implementation that calls an egui draw loop. /// An [`Editor`] implementation that calls an egui draw loop.
struct EguiEditor<T> { struct EguiEditor<T> {
egui_state: Arc<EguiState>, egui_state: Arc<EguiState>,
/// The plugin's state. This is kept in between editor openenings. /// The plugin's state. This is kept in between editor openenings.
@ -146,7 +146,7 @@ where
} }
} }
/// The window handle used for [EguiEditor]. /// The window handle used for [`EguiEditor`].
struct EguiEditorHandle { struct EguiEditorHandle {
egui_state: Arc<EguiState>, egui_state: Arc<EguiState>,
window: WindowHandle, window: WindowHandle,

View file

@ -13,7 +13,7 @@ lazy_static! {
static ref DRAG_AMOUNT_MEMORY_ID: egui::Id = egui::Id::new((file!(), 1)); static ref DRAG_AMOUNT_MEMORY_ID: egui::Id = egui::Id::new((file!(), 1));
} }
/// A slider widget similar to [egui::widgets::Slider] that knows about NIH-plug parameters ranges /// A slider widget similar to [`egui::widgets::Slider`] that knows about NIH-plug parameters ranges
/// and can get values for it. /// and can get values for it.
/// ///
/// TODO: Vertical orientation /// TODO: Vertical orientation
@ -31,7 +31,7 @@ pub struct ParamSlider<'a, P: Param> {
impl<'a, P: Param> ParamSlider<'a, P> { impl<'a, P: Param> ParamSlider<'a, P> {
/// Create a new slider for a parameter. Use the other methods to modify the slider before /// Create a new slider for a parameter. Use the other methods to modify the slider before
/// passing it to [Ui::add()]. /// passing it to [`Ui::add()`].
pub fn for_param(param: &'a P, setter: &'a ParamSetter<'a>) -> Self { pub fn for_param(param: &'a P, setter: &'a ParamSetter<'a>) -> Self {
Self { Self {
param, param,

View file

@ -108,7 +108,7 @@ pub fn chdir_workspace_root() -> Result<()> {
/// Bundle a package using the provided `cargo build` arguments. Options from the `bundler.toml` /// Bundle a package using the provided `cargo build` arguments. Options from the `bundler.toml`
/// file in the workspace's root are respected (see /// file in the workspace's root are respected (see
/// <https://github.com/robbert-vdh/nih-plug/blob/master/bundler.toml>). This requires the current /// <https://github.com/robbert-vdh/nih-plug/blob/master/bundler.toml>). This requires the current
/// working directory to have been set to the workspace's root using [chdir_workspace_root]. /// working directory to have been set to the workspace's root using [`chdir_workspace_root()`].
pub fn bundle(package: &str, args: &[String]) -> Result<()> { pub fn bundle(package: &str, args: &[String]) -> Result<()> {
let bundle_name = match load_bundler_config()?.and_then(|c| c.get(package).cloned()) { let bundle_name = match load_bundler_config()?.and_then(|c| c.get(package).cloned()) {
Some(PackageConfig { name: Some(name) }) => name, Some(PackageConfig { name: Some(name) }) => name,
@ -295,7 +295,7 @@ fn compilation_target(cross_compile_target: Option<&str>) -> Result<CompilationT
} }
} }
/// The base directory for the compiled binaries. This does not use [CompilationTarget] as we need /// The base directory for the compiled binaries. This does not use [`CompilationTarget`] as we need
/// to be able to differentiate between native and cross-compilation. /// to be able to differentiate between native and cross-compilation.
fn target_base(cross_compile_target: Option<&str>) -> Result<&'static str> { fn target_base(cross_compile_target: Option<&str>) -> Result<&'static str> {
match cross_compile_target { match cross_compile_target {

View file

@ -32,8 +32,8 @@ pub struct Biquad<T> {
s2: T, s2: T,
} }
/// The coefficients `[b0, b1, b2, a1, a2]` for [Biquad]. These coefficients are all prenormalized, /// The coefficients `[b0, b1, b2, a1, a2]` for [`Biquad`]. These coefficients are all
/// i.e. they have been divided by `a0`. /// prenormalized, i.e. they have been divided by `a0`.
/// ///
/// The type parameter T should be either an `f32` or a SIMD type. /// The type parameter T should be either an `f32` or a SIMD type.
#[derive(Clone, Copy, Debug)] #[derive(Clone, Copy, Debug)]

View file

@ -57,7 +57,7 @@ struct Diopser {
sample_rate: f32, sample_rate: f32,
/// All of the all-pass filters, with vectorized coefficients so they can be calculated for /// All of the all-pass filters, with vectorized coefficients so they can be calculated for
/// multiple channels at once. [DiopserParams::num_stages] controls how many filters are /// multiple channels at once. [`DiopserParams::num_stages`] controls how many filters are
/// actually active. /// actually active.
#[cfg(feature = "simd")] #[cfg(feature = "simd")]
filters: [filter::Biquad<f32x2>; MAX_NUM_FILTERS], filters: [filter::Biquad<f32x2>; MAX_NUM_FILTERS],
@ -315,8 +315,9 @@ impl Plugin for Diopser {
} }
impl Diopser { impl Diopser {
/// Check if the filters need to be updated beased on [Self::should_update_filters] and the /// Check if the filters need to be updated beased on
/// smoothing interval, and update them as needed. /// [`should_update_filters`][Self::should_update_filters] and the smoothing interval, and
/// update them as needed.
fn maybe_update_filters(&mut self, smoothing_interval: u32) { fn maybe_update_filters(&mut self, smoothing_interval: u32) {
// In addition to updating the filters, we should also clear the filter's state when // In addition to updating the filters, we should also clear the filter's state when
// changing a setting we can't neatly interpolate between. // changing a setting we can't neatly interpolate between.

View file

@ -18,7 +18,7 @@ struct Gain {
/// Needed to normalize the peak meter's response based on the sample rate. /// Needed to normalize the peak meter's response based on the sample rate.
peak_meter_decay_weight: f32, peak_meter_decay_weight: f32,
/// The current data for the peak meter. This is stored as an [Arc] so we can share it between /// The current data for the peak meter. This is stored as an [`Arc`] so we can share it between
/// the GUI and the audio processing parts. If you have more state to share, then it's a good /// the GUI and the audio processing parts. If you have more state to share, then it's a good
/// idea to put all of that in a struct behind a single `Arc`. /// idea to put all of that in a struct behind a single `Arc`.
/// ///

View file

@ -33,9 +33,9 @@ pub struct SamplesIter<'slice, 'sample: 'slice> {
} }
/// Can construct iterators over actual iterator over the channel data for a sample, yielded by /// Can construct iterators over actual iterator over the channel data for a sample, yielded by
/// [Samples]. Can be turned into an iterator, or [Channels::iter_mut()] can be used to iterate over /// [`Samples`]. Can be turned into an iterator, or [`Channels::iter_mut()`] can be used to iterate
/// the channel data multiple times, or more efficiently you can use [Channels::get_unchecked_mut()] /// over the channel data multiple times, or more efficiently you can use
/// to do the same thing. /// [`Channels::get_unchecked_mut()`] to do the same thing.
pub struct Channels<'slice, 'sample: 'slice> { pub struct Channels<'slice, 'sample: 'slice> {
/// The raw output buffers. /// The raw output buffers.
pub(self) buffers: *mut [&'sample mut [f32]], pub(self) buffers: *mut [&'sample mut [f32]],
@ -43,7 +43,7 @@ pub struct Channels<'slice, 'sample: 'slice> {
pub(self) _marker: PhantomData<&'slice mut [&'sample mut [f32]]>, pub(self) _marker: PhantomData<&'slice mut [&'sample mut [f32]]>,
} }
/// The actual iterator over the channel data for a sample, yielded by [Channels]. /// The actual iterator over the channel data for a sample, yielded by [`Channels`].
pub struct ChannelsIter<'slice, 'sample: 'slice> { pub struct ChannelsIter<'slice, 'sample: 'slice> {
/// The raw output buffers. /// The raw output buffers.
pub(self) buffers: *mut [&'sample mut [f32]], pub(self) buffers: *mut [&'sample mut [f32]],
@ -55,8 +55,8 @@ pub struct ChannelsIter<'slice, 'sample: 'slice> {
// Per-block per-channel per-sample iterators // Per-block per-channel per-sample iterators
/// An iterator over all samples in the buffer, slicing over the sample-dimension with a maximum /// An iterator over all samples in the buffer, slicing over the sample-dimension with a maximum
/// size of [Self::max_block_size]. See [Buffer::iter_blocks()]. Yields both the block and the /// size of `max_block_size`. See [`Buffer::iter_blocks()`]. Yields both the block and the offset
/// offset from the start of the buffer. /// from the start of the buffer.
pub struct BlocksIter<'slice, 'sample: 'slice> { pub struct BlocksIter<'slice, 'sample: 'slice> {
/// The raw output buffers. /// The raw output buffers.
pub(self) buffers: *mut [&'sample mut [f32]], pub(self) buffers: *mut [&'sample mut [f32]],
@ -65,8 +65,8 @@ pub struct BlocksIter<'slice, 'sample: 'slice> {
pub(self) _marker: PhantomData<&'slice mut [&'sample mut [f32]]>, pub(self) _marker: PhantomData<&'slice mut [&'sample mut [f32]]>,
} }
/// A block yielded by [BlocksIter]. Can be iterated over once or multiple times, and also supports /// A block yielded by [`BlocksIter`]. Can be iterated over once or multiple times, and also
/// direct access to the block's samples if needed. /// supports direct access to the block's samples if needed.
pub struct Block<'slice, 'sample: 'slice> { pub struct Block<'slice, 'sample: 'slice> {
/// The raw output buffers. /// The raw output buffers.
pub(self) buffers: *mut [&'sample mut [f32]], pub(self) buffers: *mut [&'sample mut [f32]],
@ -75,8 +75,8 @@ pub struct Block<'slice, 'sample: 'slice> {
pub(self) _marker: PhantomData<&'slice mut [&'sample mut [f32]]>, pub(self) _marker: PhantomData<&'slice mut [&'sample mut [f32]]>,
} }
/// An iterator over all channels in a block yielded by [Block]. Analogous to [ChannelsIter] but for /// An iterator over all channels in a block yielded by [`Block`]. Analogous to [`ChannelsIter`] but
/// blocks. /// for blocks.
pub struct BlockChannelsIter<'slice, 'sample: 'slice> { pub struct BlockChannelsIter<'slice, 'sample: 'slice> {
/// The raw output buffers. /// The raw output buffers.
pub(self) buffers: *mut [&'sample mut [f32]], pub(self) buffers: *mut [&'sample mut [f32]],
@ -262,11 +262,12 @@ impl<'a> Buffer<'a> {
/// SIMD. /// SIMD.
/// ///
/// The parameter smoothers can also produce smoothed values for an entire block using /// The parameter smoothers can also produce smoothed values for an entire block using
/// [crate::Smoother::next_block()]. Before using this, you will need to call /// [`Smoother::next_block()`][crate::Smoother::next_block()]. Before using this, you will need
/// [crate::Plugin::initialize_block_smoothers()] with the same `max_block_size` in your /// to call
/// initialization function first. /// [`Plugin::initialize_block_smoothers()`][crate::Plugin::initialize_block_smoothers()] with
/// the same `max_block_size` in your initialization function first.
/// ///
/// You can use this to obtain block-slices from a buffer so you can pass them to a libraryq: /// You can use this to obtain block-slices from a buffer so you can pass them to a library:
/// ///
/// ```ignore /// ```ignore
/// for block in buffer.iter_blocks(128) { /// for block in buffer.iter_blocks(128) {
@ -309,7 +310,7 @@ impl<'slice, 'sample> Channels<'slice, 'sample> {
} }
/// A resetting iterator. This lets you iterate over the same channels multiple times. Otherwise /// A resetting iterator. This lets you iterate over the same channels multiple times. Otherwise
/// you don't need to use this function as [Channels] already implements [Iterator]. /// you don't need to use this function as [`Channels`] already implements [Iterator].
pub fn iter_mut(&mut self) -> ChannelsIter<'slice, 'sample> { pub fn iter_mut(&mut self) -> ChannelsIter<'slice, 'sample> {
ChannelsIter { ChannelsIter {
buffers: self.buffers, buffers: self.buffers,
@ -333,7 +334,7 @@ impl<'slice, 'sample> Channels<'slice, 'sample> {
} }
} }
/// The same as [Self::get_mut], but without any bounds checking. /// The same as [`get_mut()`][Self::get_mut()], but without any bounds checking.
/// ///
/// # Safety /// # Safety
/// ///
@ -390,7 +391,7 @@ impl<'slice, 'sample> Channels<'slice, 'sample> {
} }
/// Write data from a SIMD vector to this sample's channel data. This takes the padding added by /// Write data from a SIMD vector to this sample's channel data. This takes the padding added by
/// [Self::to_simd()] into account. /// [`to_simd()`][Self::to_simd()] into account.
#[cfg(feature = "simd")] #[cfg(feature = "simd")]
#[allow(clippy::wrong_self_convention)] #[allow(clippy::wrong_self_convention)]
#[inline] #[inline]
@ -438,8 +439,8 @@ impl<'slice, 'sample> Block<'slice, 'sample> {
} }
/// A resetting iterator. This lets you iterate over the same block multiple times. Otherwise /// A resetting iterator. This lets you iterate over the same block multiple times. Otherwise
/// you don't need to use this function as [Block] already implements [Iterator]. You can also /// you don't need to use this function as [`Block`] already implements [`Iterator`]. You can
/// use the direct accessor functions on this block instead. /// also use the direct accessor functions on this block instead.
pub fn iter_mut(&mut self) -> BlockChannelsIter<'slice, 'sample> { pub fn iter_mut(&mut self) -> BlockChannelsIter<'slice, 'sample> {
BlockChannelsIter { BlockChannelsIter {
buffers: self.buffers, buffers: self.buffers,
@ -450,7 +451,7 @@ impl<'slice, 'sample> Block<'slice, 'sample> {
} }
} }
/// Access a channel by index. Useful when you would otherwise iterate over this [Block] /// Access a channel by index. Useful when you would otherwise iterate over this [`Block`]
/// multiple times. /// multiple times.
#[inline] #[inline]
pub fn get_mut(&mut self, channel_index: usize) -> Option<&mut [f32]> { pub fn get_mut(&mut self, channel_index: usize) -> Option<&mut [f32]> {
@ -464,7 +465,7 @@ impl<'slice, 'sample> Block<'slice, 'sample> {
} }
} }
/// The same as [Self::get_mut], but without any bounds checking. /// The same as [`get_mut()`][Self::get_mut], but without any bounds checking.
/// ///
/// # Safety /// # Safety
/// ///
@ -533,7 +534,7 @@ impl<'slice, 'sample> Block<'slice, 'sample> {
} }
/// Write data from a SIMD vector to this sample's channel data for a specific sample in this /// Write data from a SIMD vector to this sample's channel data for a specific sample in this
/// block. This takes the padding added by [Self::to_simd()] into account. /// block. This takes the padding added by [`to_simd()`][Self::to_simd()] into account.
/// ///
/// Returns `false` if `sample_index` is out of bounds. /// Returns `false` if `sample_index` is out of bounds.
#[cfg(feature = "simd")] #[cfg(feature = "simd")]

View file

@ -7,7 +7,8 @@ use crate::plugin::NoteEvent;
// TODO: ProcessContext for parameter automation and sending events // TODO: ProcessContext for parameter automation and sending events
/// General callbacks the plugin can make during its lifetime. This is passed to the plugin during /// General callbacks the plugin can make during its lifetime. This is passed to the plugin during
/// [crate::plugin::Plugin::initialize()] and as part of [crate::plugin::Plugin::process()]. /// [`Plugin::initialize()`][crate::plugin::Plugin::initialize()] and as part of
/// [`Plugin::process()`][crate::plugin::Plugin::process()].
// //
// # Safety // # Safety
// //
@ -32,16 +33,16 @@ pub trait ProcessContext {
} }
/// Callbacks the plugin can make when the user interacts with its GUI such as updating parameter /// Callbacks the plugin can make when the user interacts with its GUI such as updating parameter
/// values. This is passed to the plugin during [crate::Editor::spawn()]. All of these functions /// values. This is passed to the plugin during [`Editor::spawn()`][crate::Editor::spawn()]. All of
/// assume they're being called from the main GUI thread. /// these functions assume they're being called from the main GUI thread.
// //
// # Safety // # Safety
// //
// The implementing wrapper can assume that everything is being called from the main thread. Since // The implementing wrapper can assume that everything is being called from the main thread. Since
// NIH-plug doesn't own the GUI event loop, this invariant cannot be part of the interface. // NIH-plug doesn't own the GUI event loop, this invariant cannot be part of the interface.
pub trait GuiContext: Send + Sync + 'static { pub trait GuiContext: Send + Sync + 'static {
/// Inform the host a parameter will be automated. Create a [ParamSetter] and use /// Inform the host a parameter will be automated. Create a [`ParamSetter`] and use
/// [ParamSetter::begin_set_parameter] instead for a safe, user friendly API. /// [`ParamSetter::begin_set_parameter()`] instead for a safe, user friendly API.
/// ///
/// # Safety /// # Safety
/// ///
@ -50,7 +51,8 @@ pub trait GuiContext: Send + Sync + 'static {
unsafe fn raw_begin_set_parameter(&self, param: ParamPtr); unsafe fn raw_begin_set_parameter(&self, param: ParamPtr);
/// Inform the host a parameter is being automated with an already normalized value. Create a /// Inform the host a parameter is being automated with an already normalized value. Create a
/// [ParamSetter] and use [ParamSetter::set_parameter] instead for a safe, user friendly API. /// [`ParamSetter`] and use [`ParamSetter::set_parameter()`] instead for a safe, user friendly
/// API.
/// ///
/// # Safety /// # Safety
/// ///
@ -58,8 +60,8 @@ pub trait GuiContext: Send + Sync + 'static {
/// mostly marked as unsafe for API reasons. /// mostly marked as unsafe for API reasons.
unsafe fn raw_set_parameter_normalized(&self, param: ParamPtr, normalized: f32); unsafe fn raw_set_parameter_normalized(&self, param: ParamPtr, normalized: f32);
/// Inform the host a parameter has been automated. Create a [ParamSetter] and use /// Inform the host a parameter has been automated. Create a [`ParamSetter`] and use
/// [ParamSetter::end_set_parameter] instead for a safe, user friendly API. /// [`ParamSetter::end_set_parameter()`] instead for a safe, user friendly API.
/// ///
/// # Safety /// # Safety
/// ///
@ -68,8 +70,8 @@ pub trait GuiContext: Send + Sync + 'static {
unsafe fn raw_end_set_parameter(&self, param: ParamPtr); unsafe fn raw_end_set_parameter(&self, param: ParamPtr);
/// Retrieve the default value for a parameter, in case you forgot. This does not perform a /// Retrieve the default value for a parameter, in case you forgot. This does not perform a
/// callback Create a [ParamSetter] and use [ParamSetter::default_param_value] instead for a /// callback Create a [`ParamSetter`] and use [`ParamSetter::default_param_value()`] instead for
/// safe, user friendly API. /// a safe, user friendly API.
/// ///
/// # Safety /// # Safety
/// ///
@ -91,16 +93,17 @@ 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 parmater. This needs to be called before
/// calling [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.context.raw_begin_set_parameter(param.as_ptr()) }; unsafe { self.context.raw_begin_set_parameter(param.as_ptr()) };
} }
/// Set a parameter to the specified parameter value. You will need to call /// Set a parameter to the specified parameter value. You will need to call
/// [Self::begin_set_parameter()] before and [Self::end_set_parameter()] after calling this so /// [`begin_set_parameter()`][Self::begin_set_parameter()] before and
/// the host can properly record automation for the parameter. This can be called multiple times /// [`end_set_parameter()`][Self::end_set_parameter()] after calling this so the host can
/// in a row before calling [Self::end_set_parameter()], for instance when moving a slider /// properly record automation for the parameter. This can be called multiple times in a row
/// around. /// before calling [`end_set_parameter()`][Self::end_set_parameter()], for instance when moving
/// a slider around.
/// ///
/// This function assumes you're already calling this from a GUI thread. Calling any of these /// This function assumes you're already calling this from a GUI thread. Calling any of these
/// functions from any other thread may result in unexpected behavior. /// functions from any other thread may result in unexpected behavior.
@ -111,20 +114,20 @@ impl<'a> ParamSetter<'a> {
} }
/// Set a parameter to an already normalized value. Works exactly the same as /// Set a parameter to an already normalized value. Works exactly the same as
/// [Self::set_parameter] and needs to follow the same rules, but this may be useful when /// [`set_parameter()`][Self::set_parameter()] and needs to follow the same rules, but this may
/// implementing a GUI. /// be useful when implementing a GUI.
/// ///
/// This does not perform any snapping. Consider converting the normalized value to a plain /// This does not perform any snapping. Consider converting the normalized value to a plain
/// value and setting that with [Self::set_parameter()] instead so the normalized value known to /// value and setting that with [`set_parameter()`][Self::set_parameter()] instead so the
/// the host matches `param.normalized_value()`. /// normalized value known to the host matches `param.normalized_value()`.
pub fn set_parameter_normalized<P: Param>(&self, param: &P, normalized: f32) { pub fn set_parameter_normalized<P: Param>(&self, param: &P, normalized: f32) {
let ptr = param.as_ptr(); let ptr = param.as_ptr();
unsafe { self.context.raw_set_parameter_normalized(ptr, normalized) }; unsafe { self.context.raw_set_parameter_normalized(ptr, normalized) };
} }
/// Inform the host that you are done automating a parameter. This needs to be called after one /// Inform the host that you are done automating a parameter. This needs to be called after one
/// or more [Self::set_parameter()] calls for a parameter so the host knows the automation /// or more [`set_parameter()`][Self::set_parameter()] calls for a parameter so the host knows
/// gesture has finished. /// the automation gesture has finished.
pub fn end_set_parameter<P: Param>(&self, param: &P) { pub fn end_set_parameter<P: Param>(&self, param: &P) {
unsafe { self.context.raw_end_set_parameter(param.as_ptr()) }; unsafe { self.context.raw_end_set_parameter(param.as_ptr()) };
} }
@ -138,7 +141,8 @@ impl<'a> ParamSetter<'a> {
} }
} }
/// The same as [Self::default_normalized_param_value], but without the normalization. /// The same as [`default_normalized_param_value()`][Self::default_normalized_param_value()],
/// but without the normalization.
pub fn default_param_value<P: Param>(&self, param: &P) -> P::Plain { pub fn default_param_value<P: Param>(&self, param: &P) -> P::Plain {
param.preview_plain(self.default_normalized_param_value(param)) param.preview_plain(self.default_normalized_param_value(param))
} }

View file

@ -9,7 +9,7 @@ use std::thread::{self, JoinHandle, ThreadId};
use super::{EventLoop, MainThreadExecutor}; use super::{EventLoop, MainThreadExecutor};
use crate::nih_log; use crate::nih_log;
/// See [super::EventLoop]. /// See [`EventLoop`][super::EventLoop].
#[cfg_attr( #[cfg_attr(
target_os = "macos", target_os = "macos",
deprecated = "macOS needs to have its own event loop implementation, this implementation may not work correctly" deprecated = "macOS needs to have its own event loop implementation, this implementation may not work correctly"
@ -24,12 +24,12 @@ pub(crate) struct LinuxEventLoop<T, E> {
/// queue. /// queue.
main_thread_id: ThreadId, main_thread_id: ThreadId,
/// A thread that act as our worker thread. When [Self::do_maybe_async()] is called, this thread will be /// A thread that act as our worker thread. When [`do_maybe_async()`][Self::do_maybe_async()] is
/// woken up to execute the task on the executor. This is wrapped in an `Option` so the thread /// called, this thread will be woken up to execute the task on the executor. This is wrapped in
/// can be taken out of it and joined when this struct gets dropped. /// an `Option` so the thread can be taken out of it and joined when this struct gets dropped.
worker_thread: Option<JoinHandle<()>>, worker_thread: Option<JoinHandle<()>>,
/// A channel for waking up the worker thread and having it perform one of the tasks from /// A channel for waking up the worker thread and having it perform one of the tasks from
/// [Message]. /// [`Message`].
worker_thread_channel: channel::Sender<Message<T>>, worker_thread_channel: channel::Sender<Message<T>>,
} }
@ -98,7 +98,8 @@ impl<T, E> Drop for LinuxEventLoop<T, E> {
} }
} }
/// The worker thread used in [EventLoop] that executes incmoing tasks on the event loop's executor. /// The worker thread used in [`EventLoop`] that executes incmoing tasks on the event loop's
/// 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
T: Send, T: Send,

View file

@ -33,7 +33,7 @@ const NOTIFY_MESSAGE_ID: u32 = WM_USER;
/// casted from a regular pointer. /// casted from a regular pointer.
type PollCallback = Box<dyn Fn()>; type PollCallback = Box<dyn Fn()>;
/// See [super::EventLoop]. /// See [`EventLoop`][super::EventLoop].
pub(crate) struct WindowsEventLoop<T, E> { pub(crate) struct WindowsEventLoop<T, E> {
/// The thing that ends up executing these tasks. The tasks are usually executed from the worker /// The thing that ends up executing these tasks. The tasks are usually executed from the worker
/// thread, but if the current thread is the main thread then the task cna also be executed /// thread, but if the current thread is the main thread then the task cna also be executed

View file

@ -37,7 +37,7 @@ pub trait Param: Display {
fn plain_value(&self) -> Self::Plain; fn plain_value(&self) -> Self::Plain;
/// Set this parameter based on a plain, unnormalized value. This does **not** snap to step /// Set this parameter based on a plain, unnormalized value. This does **not** snap to step
/// sizes for continuous parameters (i.e. [FloatParam]). /// sizes for continuous parameters (i.e. [`FloatParam`]).
/// ///
/// This does **not** update the smoother. /// This does **not** update the smoother.
fn set_plain_value(&mut self, plain: Self::Plain); fn set_plain_value(&mut self, plain: Self::Plain);
@ -46,7 +46,7 @@ pub trait Param: Display {
fn normalized_value(&self) -> f32; fn normalized_value(&self) -> f32;
/// Set this parameter based on a normalized value. This **does** snap to step sizes for /// Set this parameter based on a normalized value. This **does** snap to step sizes for
/// continuous parameters (i.e. [FloatParam]). /// continuous parameters (i.e. [`FloatParam`]).
/// ///
/// This does **not** update the smoother. /// This does **not** update the smoother.
fn set_normalized_value(&mut self, normalized: f32); fn set_normalized_value(&mut self, normalized: f32);
@ -64,7 +64,7 @@ pub trait Param: Display {
fn preview_normalized(&self, plain: Self::Plain) -> f32; fn preview_normalized(&self, plain: Self::Plain) -> f32;
/// Get the plain, unnormalized value for a normalized value, as a float. Used as part of the /// Get the plain, unnormalized value for a normalized value, as a float. Used as part of the
/// wrappers. This **does** snap to step sizes for continuous parameters (i.e. [FloatParam]). /// wrappers. This **does** snap to step sizes for continuous parameters (i.e. [`FloatParam`]).
fn preview_plain(&self, normalized: f32) -> Self::Plain; fn preview_plain(&self, normalized: f32) -> Self::Plain;
/// Set this parameter based on a string. Returns whether the updating succeeded. That can fail /// Set this parameter based on a string. Returns whether the updating succeeded. That can fail
@ -78,11 +78,12 @@ pub trait Param: Display {
/// reset to the current value. /// reset to the current value.
fn update_smoother(&mut self, sample_rate: f32, reset: bool); fn update_smoother(&mut self, sample_rate: f32, reset: bool);
/// Allocate memory for block-based smoothing. The [crate::Plugin::initialize_block_smoothers()] /// Allocate memory for block-based smoothing. The
/// method will do this for every smoother. /// [`Plugin::initialize_block_smoothers()`][crate::Plugin::initialize_block_smoothers()] method
/// will do this for every smoother.
fn initialize_block_smoother(&mut self, max_block_size: usize); fn initialize_block_smoother(&mut self, max_block_size: usize);
/// Internal implementation detail for implementing [internals::Params]. This should not be used /// Internal implementation detail for implementing [`Params`][internals::Params]. This should
/// directly. /// not be used directly.
fn as_ptr(&self) -> internals::ParamPtr; fn as_ptr(&self) -> internals::ParamPtr;
} }

View file

@ -142,7 +142,7 @@ impl Param for BoolParam {
} }
impl BoolParam { impl BoolParam {
/// Build a new [Self]. Use the other associated functions to modify the behavior of the /// Build a new [`BoolParam`]. Use the other associated functions to modify the behavior of the
/// parameter. /// parameter.
pub fn new(name: &'static str, default: bool) -> Self { pub fn new(name: &'static str, default: bool) -> Self {
Self { Self {

View file

@ -33,15 +33,17 @@ pub trait Enum {
fn variants() -> &'static [&'static str]; fn variants() -> &'static [&'static str];
/// Get the variant index (which may not be the same as the discriminator) corresponding to the /// Get the variant index (which may not be the same as the discriminator) corresponding to the
/// active variant. The index needs to correspond to the name in [Self::variants()]. /// active variant. The index needs to correspond to the name in
/// [`variants()`][Self::variants()].
fn to_index(self) -> usize; fn to_index(self) -> usize;
/// Get the variant corresponding to the variant with the same index in [Self::variants()]. This /// Get the variant corresponding to the variant with the same index in
/// must always return a value. If the index is out of range, return the first variatn. /// [`variants()`][Self::variants()]. This must always return a value. If the index is out of
/// range, return the first variatn.
fn from_index(index: usize) -> Self; fn from_index(index: usize) -> Self;
} }
/// An [IntParam]-backed categorical parameter that allows convenient conversion to and from a /// An [`IntParam`]-backed categorical parameter that allows convenient conversion to and from a
/// simple enum. This enum must derive the re-exported [Enum] trait. Check the trait's documentation /// simple enum. This enum must derive the re-exported [Enum] trait. Check the trait's documentation
/// for more information on how this works. /// for more information on how this works.
pub struct EnumParam<T: Enum> { pub struct EnumParam<T: Enum> {
@ -50,12 +52,12 @@ pub struct EnumParam<T: Enum> {
inner: EnumParamInner, inner: EnumParamInner,
/// `T` is only used on the plugin side to convert back to an enum variant. Internally /// `T` is only used on the plugin side to convert back to an enum variant. Internally
/// everything works through the variants field on [EnumParamInner]. /// everything works through the variants field on [`EnumParamInner`].
_marker: PhantomData<T>, _marker: PhantomData<T>,
} }
/// The type-erased internals for [EnumParam] so that the wrapper can interact with it. Acts like an /// The type-erased internals for [`EnumParam`] so that the wrapper can interact with it. Acts like
/// [IntParam] but with different conversions from strings to values. /// an [`IntParam`] but with different conversions from strings to values.
pub struct EnumParamInner { pub struct EnumParamInner {
/// The integer parameter backing this enum parameter. /// The integer parameter backing this enum parameter.
pub(crate) inner: IntParam, pub(crate) inner: IntParam,

View file

@ -12,7 +12,7 @@ use super::Param;
/// process. /// process.
/// ///
/// You can either initialize the struct directly, using `..Default::default()` to fill in the /// You can either initialize the struct directly, using `..Default::default()` to fill in the
/// unused fields, or you can use the builder interface with [Self::new()]. /// unused fields, or you can use the builder interface with [`FloatParam::new()`].
// //
// XXX: To keep the API simple and to allow the optimizer to do its thing, the values are stored as // XXX: To keep the API simple and to allow the optimizer to do its thing, the values are stored as
// plain primitive values that are modified through the `*mut` pointers from the plugin's // plain primitive values that are modified through the `*mut` pointers from the plugin's
@ -44,13 +44,13 @@ pub struct FloatParam {
/// The distribution of the parameter's values. /// The distribution of the parameter's values.
pub range: FloatRange, pub range: FloatRange,
/// The distance between discrete steps in this parameter. Mostly useful for quantizing GUI /// The distance between discrete steps in this parameter. Mostly useful for quantizing GUI
/// input. If this is set and if [Self::value_to_string] is not set, then this is also used when /// input. If this is set and if [`value_to_string`][Self::value_to_string] is not set, then
/// formatting the parameter. This must be a positive, nonzero number. /// this is also used when formatting the parameter. This must be a positive, nonzero number.
pub step_size: Option<f32>, pub step_size: Option<f32>,
/// The parameter's human readable display name. /// The parameter's human readable display name.
pub name: &'static str, pub name: &'static str,
/// The parameter value's unit, added after `value_to_string` if that is set. NIH-plug will not /// The parameter value's unit, added after [`value_to_string`][Self::value_to_string] if that
/// automatically add a space before the unit. /// is set. NIH-plug will not automatically add a space before the unit.
pub unit: &'static str, pub unit: &'static str,
/// Optional custom conversion function from a plain **unnormalized** value to a string. /// Optional custom conversion function from a plain **unnormalized** value to a string.
pub value_to_string: Option<Arc<dyn Fn(f32) -> String + Send + Sync>>, pub value_to_string: Option<Arc<dyn Fn(f32) -> String + Send + Sync>>,
@ -197,7 +197,7 @@ impl Param for FloatParam {
} }
impl FloatParam { impl FloatParam {
/// Build a new [Self]. Use the other associated functions to modify the behavior of the /// Build a new [`FloatParam`]. Use the other associated functions to modify the behavior of the
/// parameter. /// parameter.
pub fn new(name: &'static str, default: f32, range: FloatRange) -> Self { pub fn new(name: &'static str, default: f32, range: FloatRange) -> Self {
Self { Self {
@ -225,7 +225,7 @@ impl FloatParam {
} }
/// Display a unit when rendering this parameter to a string. Appended after the /// Display a unit when rendering this parameter to a string. Appended after the
/// [Self::value_to_string] function if that is also set. NIH-plug will not /// [`value_to_string`][Self::value_to_string] function if that is also set. NIH-plug will not
/// automatically add a space before the unit. /// automatically add a space before the unit.
pub fn with_unit(mut self, unit: &'static str) -> Self { pub fn with_unit(mut self, unit: &'static str) -> Self {
self.unit = unit; self.unit = unit;
@ -233,8 +233,8 @@ impl FloatParam {
} }
/// Set the distance between steps of a [FloatParam]. Mostly useful for quantizing GUI input. If /// Set the distance between steps of a [FloatParam]. Mostly useful for quantizing GUI input. If
/// this is set and if [Self::value_to_string] is not set, then this is also used when /// this is set and if [`value_to_string`][Self::value_to_string] is not set, then this is also
/// formatting the parameter. This must be a positive, nonzero number. /// used when formatting the parameter. This must be a positive, nonzero number.
pub fn with_step_size(mut self, step_size: f32) -> Self { pub fn with_step_size(mut self, step_size: f32) -> Self {
self.step_size = Some(step_size); self.step_size = Some(step_size);
self self

View file

@ -12,7 +12,7 @@ use super::Param;
/// process. /// process.
/// ///
/// You can either initialize the struct directly, using `..Default::default()` to fill in the /// You can either initialize the struct directly, using `..Default::default()` to fill in the
/// unused fields, or you can use the builder interface with [Self::new()]. /// unused fields, or you can use the builder interface with [`IntParam::new()`].
// //
// XXX: To keep the API simple and to allow the optimizer to do its thing, the values are stored as // XXX: To keep the API simple and to allow the optimizer to do its thing, the values are stored as
// plain primitive values that are modified through the `*mut` pointers from the plugin's // plain primitive values that are modified through the `*mut` pointers from the plugin's
@ -176,7 +176,7 @@ impl Param for IntParam {
} }
impl IntParam { impl IntParam {
/// Build a new [Self]. Use the other associated functions to modify the behavior of the /// Build a new [`IntParam`]. Use the other associated functions to modify the behavior of the
/// parameter. /// parameter.
pub fn new(name: &'static str, default: i32, range: IntRange) -> Self { pub fn new(name: &'static str, default: i32, range: IntRange) -> Self {
Self { Self {
@ -204,7 +204,7 @@ impl IntParam {
} }
/// Display a unit when rendering this parameter to a string. Appended after the /// Display a unit when rendering this parameter to a string. Appended after the
/// [Self::value_to_string] function if that is also set. NIH-plug will not /// [`value_to_string`][Self::value_to_string] function if that is also set. NIH-plug will not
/// automatically add a space before the unit. /// automatically add a space before the unit.
pub fn with_unit(mut self, unit: &'static str) -> Self { pub fn with_unit(mut self, unit: &'static str) -> Self {
self.unit = unit; self.unit = unit;

View file

@ -5,21 +5,21 @@ use std::pin::Pin;
use super::Param; use super::Param;
/// Re-export for use in the [Params] proc-macro. /// Re-export for use in the [`Params`] proc-macro.
pub use serde_json::from_str as deserialize_field; pub use serde_json::from_str as deserialize_field;
/// Re-export for use in the [Params] proc-macro. /// Re-export for use in the [`Params`] proc-macro.
pub use serde_json::to_string as serialize_field; pub use serde_json::to_string as serialize_field;
/// Describes a struct containing parameters and other persistent fields. The idea is that we can /// Describes a struct containing parameters and other persistent fields. The idea is that we can
/// have a normal struct containing [super::FloatParam] and other parameter types with attributes /// have a normal struct containing [`FloatParam`][super::FloatParam] and other parameter types with
/// assigning a unique identifier to each parameter. We can then build a mapping from those /// attributes assigning a unique identifier to each parameter. We can then build a mapping from
/// parameter IDs to the parameters using the [Params::param_map()] function. That way we can have /// those parameter IDs to the parameters using the [`Params::param_map()`] function. That way we
/// easy to work with JUCE-style parameter objects in the plugin without needing to manually /// can have easy to work with JUCE-style parameter objects in the plugin without needing to
/// register each parameter, like you would in JUCE. When deriving this trait, any of those /// manually register each parameter, like you would in JUCE. When deriving this trait, any of those
/// parameters should have the `#[id = "stable"]` attribute, where `stable` is an up to 6 character /// parameters should have the `#[id = "stable"]` attribute, where `stable` is an up to 6 character
/// (to avoid collisions) string that will be used for the parameter's internal identifier. /// (to avoid collisions) string that will be used for the parameter's internal identifier.
/// ///
/// The other persistent parameters should be [PersistentField]s containing types that can be /// The other persistent parameters should be [`PersistentField`]s containing types that can be
/// serialized and deserialized with Serde. When deriving this trait, any of those fields should be /// serialized and deserialized with Serde. When deriving this trait, any of those fields should be
/// marked with `#[persist = "key"]`. /// marked with `#[persist = "key"]`.
/// ///
@ -54,13 +54,14 @@ pub trait Params {
/// 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
/// JSON-representations of those fields so they can be written to the plugin's state and /// JSON-representations of those fields so they can be written to the plugin's state and
/// recalled later. This uses [serialize_field()] under the hood. /// recalled later. This uses [`serialize_field()`] under the hood.
fn serialize_fields(&self) -> HashMap<String, String>; fn serialize_fields(&self) -> HashMap<String, String>;
/// 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
/// [Self::serialize_fields()]. All of thse fields should be wrapped in a [PersistentField] with /// [`serialize_fields()`][Self::serialize_fields()]. All of thse fields should be wrapped in a
/// thread safe interior mutability, like an `RwLock` or a `Mutex`. This gets called when the /// [`PersistentField`] with thread safe interior mutability, like an `RwLock` or a `Mutex`.
/// plugin's state is being restored. This uses [deserialize_field()] under the hood. /// This gets called when the plugin's state is being restored. This uses [deserialize_field()]
/// under the hood.
fn deserialize_fields(&self, serialized: &HashMap<String, String>); fn deserialize_fields(&self, serialized: &HashMap<String, String>);
} }
@ -96,17 +97,17 @@ where
F: Fn(&T) -> R; F: Fn(&T) -> R;
} }
/// Generate a [ParamPtr] function that forwards the function call to the underlying `Param`. We /// Generate a [`ParamPtr`] function that forwards the function call to the underlying `Param`. We
/// can't have an `.as_param()` function since the return type would differ depending on the /// can't have an `.as_param()` function since the return type would differ depending on the
/// underlying parameter type, so instead we need to type erase all of the functions individually. /// underlying parameter type, so instead we need to type erase all of the functions individually.
macro_rules! param_ptr_forward( macro_rules! param_ptr_forward(
(pub unsafe fn $method:ident(&self $(, $arg_name:ident: $arg_ty:ty)*) $(-> $ret:ty)?) => { (pub unsafe fn $method:ident(&self $(, $arg_name:ident: $arg_ty:ty)*) $(-> $ret:ty)?) => {
/// Calls the corresponding method on the underlying [Param] object. /// Calls the corresponding method on the underlying [`Param`] object.
/// ///
/// # Safety /// # Safety
/// ///
/// Calling this function is only safe as long as the object this [ParamPtr] was created for /// Calling this function is only safe as long as the object this [`ParamPtr`] was created
/// is still alive. /// for is still alive.
pub unsafe fn $method(&self $(, $arg_name: $arg_ty)*) $(-> $ret)? { pub unsafe fn $method(&self $(, $arg_name: $arg_ty)*) $(-> $ret)? {
match &self { match &self {
ParamPtr::FloatParam(p) => (**p).$method($($arg_name),*), ParamPtr::FloatParam(p) => (**p).$method($($arg_name),*),
@ -119,12 +120,12 @@ macro_rules! param_ptr_forward(
// XXX: Is there a way to combine these two? Hygienic macros don't let you call `&self` without // XXX: Is there a way to combine these two? Hygienic macros don't let you call `&self` without
// it being defined in the macro. // it being defined in the macro.
(pub unsafe fn $method:ident(&mut self $(, $arg_name:ident: $arg_ty:ty)*) $(-> $ret:ty)?) => { (pub unsafe fn $method:ident(&mut self $(, $arg_name:ident: $arg_ty:ty)*) $(-> $ret:ty)?) => {
/// Calls the corresponding method on the underlying [Param] object. /// Calls the corresponding method on the underlying [`Param`] object.
/// ///
/// # Safety /// # Safety
/// ///
/// Calling this function is only safe as long as the object this [ParamPtr] was created for /// Calling this function is only safe as long as the object this [`ParamPtr`] was created
/// is still alive. /// for is still alive.
pub unsafe fn $method(&mut self $(, $arg_name: $arg_ty)*) $(-> $ret)? { pub unsafe fn $method(&mut self $(, $arg_name: $arg_ty)*) $(-> $ret)? {
match &self { match &self {
ParamPtr::FloatParam(p) => (**p).$method($($arg_name),*), ParamPtr::FloatParam(p) => (**p).$method($($arg_name),*),

View file

@ -7,13 +7,13 @@ pub enum FloatRange {
Linear { min: f32, max: f32 }, Linear { min: f32, max: f32 },
/// The range is skewed by a factor. Values above 1.0 will make the end of the range wider, /// The range is skewed by a factor. Values above 1.0 will make the end of the range wider,
/// while values between 0 and 1 will skew the range towards the start. Use /// while values between 0 and 1 will skew the range towards the start. Use
/// [FloatRange::skew_factor()] for a more intuitively way to calculate the skew factor where /// [`FloatRange::skew_factor()`] for a more intuitively way to calculate the skew factor where
/// positive values skew the range towards the end while negative values skew the range toward /// positive values skew the range towards the end while negative values skew the range toward
/// the start. /// the start.
Skewed { min: f32, max: f32, factor: f32 }, Skewed { min: f32, max: f32, factor: f32 },
/// The same as [FloatRange::Skewed], but with the skewing happening from a central point. This /// The same as [`FloatRange::Skewed`], but with the skewing happening from a central point.
/// central point is rescaled to be at 50% of the parameter's range for convenience of use. Git /// This central point is rescaled to be at 50% of the parameter's range for convenience of use.
/// blame this comment to find a version that doesn't do this. /// Git blame this comment to find a version that doesn't do this.
SymmetricalSkewed { SymmetricalSkewed {
min: f32, min: f32,
max: f32, max: f32,
@ -44,7 +44,7 @@ impl Default for IntRange {
} }
impl FloatRange { impl FloatRange {
/// Calculate a skew factor for [FloatRange::Skewed] and [FloatRange::SymmetricalSkewed]. /// Calculate a skew factor for [`FloatRange::Skewed`] and [`FloatRange::SymmetricalSkewed`].
/// Positive values make the end of the range wider while negative make the start of the range /// Positive values make the end of the range wider while negative make the start of the range
/// wider. /// wider.
pub fn skew_factor(factor: f32) -> f32 { pub fn skew_factor(factor: f32) -> f32 {

View file

@ -42,7 +42,8 @@ pub struct Smoother<T> {
target: T, target: T,
/// A dense buffer containing smoothed values for an entire block of audio. Useful when using /// A dense buffer containing smoothed values for an entire block of audio. Useful when using
/// [crate::Buffer::iter_blocks()] to process small blocks of audio multiple times. /// [`Buffer::iter_blocks()`][crate::Buffer::iter_blocks()] to process small blocks of audio
/// multiple times.
block_values: AtomicRefCell<Vec<T>>, block_values: AtomicRefCell<Vec<T>>,
} }
@ -74,15 +75,15 @@ impl<T: Default> Smoother<T> {
Default::default() Default::default()
} }
/// Whether calling [Self::next()] will yield a new value or an old value. Useful if you need to /// Whether calling [`next()`][Self::next()] will yield a new value or an old value. Useful if
/// recompute something wheenver this parameter changes. /// you need to recompute something wheenver this parameter changes.
pub fn is_smoothing(&self) -> bool { pub fn is_smoothing(&self) -> bool {
self.steps_left.load(Ordering::Relaxed) > 0 self.steps_left.load(Ordering::Relaxed) > 0
} }
/// Allocate memory to store smoothed values for an entire block of audio. Call this in /// Allocate memory to store smoothed values for an entire block of audio. Call this in
/// [crate::Plugin::initialize()] with the same max block size you are going to pass to /// [`Plugin::initialize()`][crate::Plugin::initialize()] with the same max block size you are
/// [crate::Buffer::iter_blocks()]. /// going to pass to [`Buffer::iter_blocks()`][crate::Buffer::iter_blocks()].
pub fn initialize_block_smoother(&mut self, max_block_size: usize) { pub fn initialize_block_smoother(&mut self, max_block_size: usize) {
self.block_values self.block_values
.borrow_mut() .borrow_mut()
@ -135,10 +136,11 @@ impl Smoother<f32> {
} }
/// Produce smoothed values for an entire block of audio. Used in conjunction with /// Produce smoothed values for an entire block of audio. Used in conjunction with
/// [crate::Buffer::iter_blocks()]. Make sure to call /// [`Buffer::iter_blocks()`][crate::Buffer::iter_blocks()]. Make sure to call
/// [crate::Plugin::initialize_block_smoothers()] with the same maximum buffer block size as the /// [`Plugin::initialize_block_smoothers()`][crate::Plugin::initialize_block_smoothers()] with
/// one passed to `iter_blocks()` in your [crate::Plugin::initialize()] function first to /// the same maximum buffer block size as the one passed to `iter_blocks()` in your
/// allocate memory for the block smoothing. /// [`Plugin::initialize()`][crate::Plugin::initialize()] function first to allocate memory for
/// the block smoothing.
/// ///
/// Returns a `None` value if the block length exceed's the allocated capacity. /// Returns a `None` value if the block length exceed's the allocated capacity.
/// ///
@ -163,10 +165,10 @@ impl Smoother<f32> {
})) }))
} }
/// [Self::next()], but with the ability to skip forward in the smoother. [Self::next()] is /// [`next()`][Self::next()], but with the ability to skip forward in the smoother.
/// equivalent to calling this function with a `steps` value of 1. Calling this function with a /// [`next()`][Self::next()] is equivalent to calling this function with a `steps` value of 1.
/// `steps` value of `n` means will cause you to skip the next `n - 1` values and return the /// Calling this function with a `steps` value of `n` means will cause you to skip the next `n -
/// `n`th value. /// 1` values and return the `n`th value.
#[inline] #[inline]
pub fn next_step(&self, steps: u32) -> f32 { pub fn next_step(&self, steps: u32) -> f32 {
nih_debug_assert_ne!(steps, 0); nih_debug_assert_ne!(steps, 0);
@ -236,10 +238,11 @@ impl Smoother<i32> {
} }
/// Produce smoothed values for an entire block of audio. Used in conjunction with /// Produce smoothed values for an entire block of audio. Used in conjunction with
/// [crate::Buffer::iter_blocks()]. Make sure to call /// [`Buffer::iter_blocks()`][crate::Buffer::iter_blocks()]. Make sure to call
/// [crate::Plugin::initialize_block_smoothers()] with the same maximum buffer block size as the /// [`Plugin::initialize_block_smoothers()`][crate::Plugin::initialize_block_smoothers()] with
/// one passed to `iter_blocks()` in your [crate::Plugin::initialize()] function first to /// the same maximum buffer block size as the one passed to `iter_blocks()` in your
/// allocate memory for the block smoothing. /// [`Plugin::initialize()`][crate::Plugin::initialize()] function first to allocate memory for
/// the block smoothing.
/// ///
/// Returns a `None` value if the block length exceed's the allocated capacity. /// Returns a `None` value if the block length exceed's the allocated capacity.
/// ///
@ -260,10 +263,10 @@ impl Smoother<i32> {
})) }))
} }
/// [Self::next()], but with the ability to skip forward in the smoother. [Self::next()] is /// [`next()`][Self::next()], but with the ability to skip forward in the smoother.
/// equivalent to calling this function with a `steps` value of 1. Calling this function with a /// [`next()`][Self::next()] is equivalent to calling this function with a `steps` value of 1.
/// `steps` value of `n` means will cause you to skip the next `n - 1` values and return the /// Calling this function with a `steps` value of `n` means will cause you to skip the next `n -
/// `n`th value. /// 1` values and return the `n`th value.
pub fn next_step(&self, steps: u32) -> i32 { pub fn next_step(&self, steps: u32) -> i32 {
nih_debug_assert_ne!(steps, 0); nih_debug_assert_ne!(steps, 0);

View file

@ -54,10 +54,11 @@ pub trait Plugin: Default + Send + Sync + 'static {
fn params(&self) -> Pin<&dyn Params>; fn params(&self) -> Pin<&dyn Params>;
/// The plugin's editor, if it has one. The actual editor instance is created in /// The plugin's editor, if it has one. The actual editor instance is created in
/// [Editor::spawn]. A plugin editor likely wants to interact with the plugin's parameters and /// [`Editor::spawn()`]. A plugin editor likely wants to interact with the plugin's parameters
/// other shared data, so you'll need to move [Arc] pointing to any data you want to access into /// and other shared data, so you'll need to move [`Arc`] pointing to any data you want to
/// the editor. You can later modify the parameters through the [crate::GuiContext] and /// access into the editor. You can later modify the parameters through the
/// [crate::ParamSetter] after the editor GUI has been created. /// [`GuiContext`][crate::GuiContext] and [`ParamSetter`][crate::ParamSetter] after the editor
/// GUI has been created.
fn editor(&self) -> Option<Box<dyn Editor>> { fn editor(&self) -> Option<Box<dyn Editor>> {
None None
} }
@ -97,14 +98,16 @@ pub trait Plugin: Default + Send + Sync + 'static {
/// abort the program when any allocation accurs in the process function while running in debug /// abort the program when any allocation accurs 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
/// either per-sample per-channel, or per-block per-channel per-sample. The first approach is /// either per-sample per-channel, or per-block per-channel per-sample. The first approach is
/// preferred for plugins that don't require block-based processing because of their use of /// preferred for plugins that don't require block-based processing because of their use of
/// per-sample SIMD or excessive branching. The parameter smoothers can also work in both modes: /// per-sample SIMD or excessive branching. The parameter smoothers can also work in both modes:
/// use [crate::Smoother::next()] for per-sample processing, and [crate::Smoother::next_block()] /// use [`Smoother::next()`][crate::Smoother::next()] for per-sample processing, and
/// for block-based processing. In order to use block-based smoothing, you will need to call /// [`Smoother::next_block()`][crate::Smoother::next_block()] for block-based processing. In
/// [Self::initialize_block_smoothers()] in your [Self::initialize()] function first to reserve /// order to use block-based smoothing, you will need to call
/// enough capacity in the smoothers. /// [`initialize_block_smoothers()`][Self::initialize_block_smoothers()] in your
/// [`initialize()`][Self::initialize()] function first to reserve enough capacity in the
/// smoothers.
/// ///
/// 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 /// assymetric
@ -113,10 +116,10 @@ pub trait Plugin: Default + Send + Sync + 'static {
fn process(&mut self, buffer: &mut Buffer, context: &mut impl ProcessContext) -> ProcessStatus; fn process(&mut self, buffer: &mut Buffer, context: &mut impl ProcessContext) -> ProcessStatus;
/// Convenience function to allocate memory for block-based smoothing. Since this allocates /// Convenience function to allocate memory for block-based smoothing. Since this allocates
/// memory, this should be called in [Self::initialize()]. If you are going to use /// memory, this should be called in [`initialize()`][Self::initialize()]. If you are going to
/// [Buffer::iter_blocks] and want to use parameter smoothing in those blocks, then call this /// use [`Buffer::iter_blocks()`] and want to use parameter smoothing in those blocks, then call
/// function with the same maximum block size first before calling /// this function with the same maximum block size first before calling
/// [crate::Smoother::next_block()]. /// [`Smoother::next_block()`][crate::Smoother::next_block()].
fn initialize_block_smoothers(&mut self, max_block_size: usize) { fn initialize_block_smoothers(&mut self, max_block_size: usize) {
for param in self.params().param_map().values_mut() { for param in self.params().param_map().values_mut() {
unsafe { param.initialize_block_smoother(max_block_size) }; unsafe { param.initialize_block_smoother(max_block_size) };
@ -152,13 +155,13 @@ 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: /// logner 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>
const VST3_CATEGORIES: &'static str; const VST3_CATEGORIES: &'static str;
/// [Self::VST3_CLASS_ID] in the correct order for the current platform so projects and presets /// [`VST3_CLASS_ID`][Self::VST3_CLASS_ID`] in the correct order for the current platform so
/// can be shared between platforms. This should not be overridden. /// projects and presets can be shared between platforms. This should not be overridden.
const PLATFORM_VST3_CLASS_ID: [u8; 16] = swap_vst3_uid_byte_order(Self::VST3_CLASS_ID); const PLATFORM_VST3_CLASS_ID: [u8; 16] = swap_vst3_uid_byte_order(Self::VST3_CLASS_ID);
} }
@ -185,16 +188,16 @@ const fn swap_vst3_uid_byte_order(mut uid: [u8; 16]) -> [u8; 16] {
uid uid
} }
/// An editor for a [Plugin]. /// An editor for a [`Plugin`].
pub trait Editor: Send + Sync { pub trait Editor: Send + Sync {
/// Create an instance of the plugin's editor and embed it in the parent window. As explained in /// Create an instance of the plugin's editor and embed it in the parent window. As explained in
/// [Plugin::editor], you can then read the parameter values directly from your [crate::Params] /// [`Plugin::editor()`], you can then read the parameter values directly from your [`Params`]
/// object, and modifying the values can be done using the functions on the /// object, and modifying the values can be done using the functions on the
/// [crate::ParamSetter]. When you change a parameter value that way it will be broadcasted to /// [`ParamSetter`][crate::ParamSetter]. When you change a parameter value that way it will be
/// the host and also updated in your [Params] struct. /// broadcasted to the host and also updated in your [`Params`] struct.
/// ///
/// This function should return a handle to the editor, which will be dropped when the editor /// This function should return a handle to the editor, which will be dropped when the editor
/// gets closed. Implement the [Drop] trait on the returned handle if you need to explicitly /// gets closed. Implement the [`Drop`] trait on the returned handle if you need to explicitly
/// handle the editor's closing behavior. /// handle the editor's closing behavior.
/// ///
/// The wrapper guarantees that a previous handle has been dropped before this function is /// The wrapper guarantees that a previous handle has been dropped before this function is

View file

@ -10,7 +10,7 @@ pub fn db_to_gain(dbs: f32) -> f32 {
} }
/// Convert a voltage gain ratio to decibels. Gain ratios that aren't positive will be treated as /// Convert a voltage gain ratio to decibels. Gain ratios that aren't positive will be treated as
/// [MINUS_INFINITY_DB]. /// [`MINUS_INFINITY_DB`].
pub fn gain_to_db(gain: f32) -> f32 { pub fn gain_to_db(gain: f32) -> f32 {
if gain > 0.0 { if gain > 0.0 {
gain.log10() * 20.0 gain.log10() * 20.0

View file

@ -10,14 +10,14 @@ use crate::param::internals::ParamPtr;
use crate::plugin::{ClapPlugin, NoteEvent}; use crate::plugin::{ClapPlugin, NoteEvent};
use crate::GuiContext; use crate::GuiContext;
/// A [GuiContext] implementation for the wrapper. This is passed to the plugin in /// A [`GuiContext`] implementation for the wrapper. This is passed to the plugin in
/// [crate::Editor::spawn()] so it can interact with the rest of the plugin and with the host for /// [`Editor::spawn()`][crate::Editor::spawn()] so it can interact with the rest of the plugin and
/// things like setting parameters. /// with the host for things like setting parameters.
pub(crate) struct WrapperGuiContext<P: ClapPlugin> { pub(crate) struct WrapperGuiContext<P: ClapPlugin> {
pub(super) wrapper: Arc<Wrapper<P>>, pub(super) wrapper: Arc<Wrapper<P>>,
} }
/// A [ProcessContext] implementation for the wrapper. This is a separate object so it can hold on /// A [`ProcessContext`] implementation for the wrapper. This is a separate object so it can hold on
/// to lock guards for event queues. Otherwise reading these events would require constant /// to lock guards for event queues. Otherwise reading these events would require constant
/// unnecessary atomic operations to lock the uncontested RwLocks. /// unnecessary atomic operations to lock the uncontested RwLocks.
pub(crate) struct WrapperProcessContext<'a, P: ClapPlugin> { pub(crate) struct WrapperProcessContext<'a, P: ClapPlugin> {

View file

@ -11,7 +11,8 @@ use crate::plugin::ClapPlugin;
/// A static descriptor for a plugin. This is used in both the descriptor and on the plugin object /// A static descriptor for a plugin. This is used in both the descriptor and on the plugin object
/// itself. /// itself.
/// ///
/// This cannot be cloned as [Self::clap_features_ptrs] contains pointers to [Self::clap_features]. /// This cannot be cloned as [`Self::clap_features_ptrs`] contains pointers to
/// [Self::clap_features].
pub struct PluginDescriptor<P: ClapPlugin> { pub struct PluginDescriptor<P: ClapPlugin> {
// We need [CString]s for all of `ClapPlugin`'s `&str` fields // We need [CString]s for all of `ClapPlugin`'s `&str` fields
clap_id: CString, clap_id: CString,

View file

@ -8,7 +8,7 @@ macro_rules! check_null_ptr {
}; };
} }
/// The same as [check_null_ptr!], but with a custom message. /// The same as [`check_null_ptr!`], but with a custom message.
macro_rules! check_null_ptr_msg { macro_rules! check_null_ptr_msg {
($msg:expr, $ret:expr, $ptr:expr $(, $ptrs:expr)* $(, )?) => { ($msg:expr, $ret:expr, $ptr:expr $(, $ptrs:expr)* $(, )?) => {
if $ptr.is_null() $(|| $ptrs.is_null())* { if $ptr.is_null() $(|| $ptrs.is_null())* {

View file

@ -90,7 +90,7 @@ pub struct Wrapper<P: ClapPlugin> {
/// The wrapped plugin instance. /// The wrapped plugin instance.
plugin: RwLock<P>, plugin: RwLock<P>,
/// The plugin's editor, if it has one. This object does not do anything on its own, but we need /// The plugin's editor, if it has one. This object does not do anything on its own, but we need
/// to instantiate this in advance so we don't need to lock the entire [Plugin] object when /// to instantiate this in advance so we don't need to lock the entire [`Plugin`] object when
/// creating an editor. /// creating an editor.
editor: Option<Arc<dyn Editor>>, editor: Option<Arc<dyn Editor>>,
/// A handle for the currently active editor instance. The plugin should implement `Drop` on /// A handle for the currently active editor instance. The plugin should implement `Drop` on
@ -112,8 +112,8 @@ pub struct Wrapper<P: ClapPlugin> {
/// TODO: Maybe load these lazily at some point instead of needing to spool them all to this /// TODO: Maybe load these lazily at some point instead of needing to spool them all to this
/// queue first /// queue first
input_events: AtomicRefCell<VecDeque<NoteEvent>>, input_events: AtomicRefCell<VecDeque<NoteEvent>>,
/// The current latency in samples, as set by the plugin through the [ProcessContext]. uses the /// The current latency in samples, as set by the plugin through the [`ProcessContext`]. uses
/// latency extnesion /// the latency extnesion
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 form
/// apointer to pointers, so this needs to be preallocated in the setup call and kept around /// apointer to pointers, so this needs to be preallocated in the setup call and kept around
@ -171,9 +171,10 @@ pub struct Wrapper<P: ClapPlugin> {
/// Mappings from string parameter indentifiers to parameter hashes. Useful for debug logging /// Mappings from string parameter indentifiers 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<&'static str, u32>, param_id_to_hash: HashMap<&'static str, u32>,
/// The inverse mapping from [Self::param_by_hash]. This is needed to be able to have an /// The inverse mapping from [`param_by_hash`][Self::param_by_hash]. This is needed to be able
/// ergonomic parameter setting API that uses references to the parameters instead of having to /// to have an ergonomic parameter setting API that uses references to the parameters instead of
/// add a setter function to the parameter (or even worse, have it be completely untyped). /// having to add a setter function to the parameter (or even worse, have it be completely
/// untyped).
pub param_ptr_to_hash: HashMap<ParamPtr, u32>, pub param_ptr_to_hash: HashMap<ParamPtr, u32>,
/// A queue of parameter changes that should be output in either the next process call or in the /// A queue of parameter changes that should be output in either the next process call or in the
/// next parameter flush. /// next parameter flush.
@ -190,18 +191,19 @@ pub struct Wrapper<P: ClapPlugin> {
/// A queue of tasks that still need to be performed. Because CLAP lets the plugin request a /// A queue of tasks that still need to be performed. Because CLAP lets the plugin request a
/// host callback directly, we don't need to use the OsEventLoop we use in our other plugin /// host callback directly, we don't need to use the OsEventLoop we use in our other plugin
/// implementations. Instead, we'll post tasks to this queue, ask the host to call /// implementations. Instead, we'll post tasks to this queue, ask the host to call
/// [Self::on_main_thread] on the main thread, and then continue to pop tasks off this queue /// [`on_main_thread()`][Self::on_main_thread()] on the main thread, and then continue to pop
/// there until it is empty. /// tasks off this queue there until it is empty.
tasks: ArrayQueue<Task>, tasks: ArrayQueue<Task>,
/// The ID of the main thread. In practice this is the ID of the thread that created this /// The ID of the main thread. In practice this is the ID of the thread that created this
/// object. If the host supports the thread check extension (and [Self::thread_check] thus /// object. If the host supports the thread check extension (and
/// contains a value), then that extension is used instead. /// [`host_thread_check`][Self::host_thread_check] thus contains a value), then that extension
/// is used instead.
main_thread_id: ThreadId, main_thread_id: ThreadId,
} }
/// Tasks that can be sent from the plugin to be executed on the main thread in a non-blocking /// Tasks that can be sent from the plugin to be executed on the main thread in a non-blocking
/// realtime safe way. Instead of using a random thread or the OS' event loop like in the Linux /// realtime safe way. Instead of using a random thread or the OS' event loop like in the Linux
/// implementation, this uses [clap_host::request_callback()] instead. /// implementation, this uses [`clap_host::request_callback()`] instead.
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub enum Task { pub enum Task {
/// Inform the host that the latency has changed. /// Inform the host that the latency has changed.
@ -223,11 +225,11 @@ pub struct OutputParamChange {
/// The internal hash for the parameter. /// The internal hash for the parameter.
pub param_hash: u32, pub param_hash: u32,
/// The 'plain' value as reported to CLAP. This is the normalized value multiplied by /// The 'plain' value as reported to CLAP. This is the normalized value multiplied by
/// [crate::Param::step_size]. /// [`Param::step_size()`][crate::Param::step_size()].
pub clap_plain_value: f64, pub clap_plain_value: f64,
} }
/// Because CLAP has this [clap_host::request_host_callback()] function, we don't need to use /// Because CLAP has this [`clap_host::request_host_callback()`] function, we don't need to use
/// `OsEventLoop` and can instead just request a main thread callback directly. /// `OsEventLoop` and can instead just request a main thread callback directly.
impl<P: ClapPlugin> EventLoop<Task, Wrapper<P>> for Wrapper<P> { impl<P: ClapPlugin> EventLoop<Task, Wrapper<P>> for Wrapper<P> {
fn new_and_spawn(_executor: std::sync::Weak<Self>) -> Self { fn new_and_spawn(_executor: std::sync::Weak<Self>) -> Self {
@ -613,8 +615,8 @@ impl<P: ClapPlugin> Wrapper<P> {
} }
} }
/// Handle an incoming CLAP event. You must clear [Self::input_events] first before calling this /// Handle an incoming CLAP event. You must clear [`input_events`][Self::input_events] first
/// from the process function. /// before calling this from the process function.
/// ///
/// To save on mutex operations when handing MIDI events, the lock guard for the input events /// To save on mutex operations when handing MIDI events, the lock guard for the input events
/// need to be passed into this function. /// need to be passed into this function.

View file

@ -26,7 +26,7 @@ pub(crate) struct State {
/// parmaeter automation though, depending on how the host impelments that. /// parmaeter automation though, depending on how the host impelments that.
pub params: HashMap<String, ParamValue>, pub params: HashMap<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 [crate::param::internals::Params] struct that's annotated with `#[persist = /// on the [`Params`][crate::param::internals::Params] struct that's annotated with `#[persist =
/// "stable_name"]` will be persisted this way. /// "stable_name"]` will be persisted this way.
/// ///
/// The individual fields are also serialized as JSON so they can safely be restored /// The individual fields are also serialized as JSON so they can safely be restored

View file

@ -50,7 +50,7 @@ pub fn strlcpy(dest: &mut [c_char], src: &str) {
dest[copy_len] = 0; dest[copy_len] = 0;
} }
/// The same as [strlcpy()], but for VST3's fun UTF-16 strings instead. /// The same as [`strlcpy()`], but for VST3's fun UTF-16 strings instead.
pub fn u16strlcpy(dest: &mut [TChar], src: &str) { pub fn u16strlcpy(dest: &mut [TChar], src: &str) {
if dest.is_empty() { if dest.is_empty() {
return; return;

View file

@ -10,14 +10,14 @@ use crate::event_loop::EventLoop;
use crate::param::internals::ParamPtr; use crate::param::internals::ParamPtr;
use crate::plugin::{NoteEvent, Vst3Plugin}; use crate::plugin::{NoteEvent, Vst3Plugin};
/// A [GuiContext] implementation for the wrapper. This is passed to the plugin in /// A [`GuiContext`] implementation for the wrapper. This is passed to the plugin in
/// [crate::Editor::spawn()] so it can interact with the rest of the plugin and with the host for /// [`Editor::spawn()`][crate::Editor::spawn()] so it can interact with the rest of the plugin and
/// things like setting parameters. /// with the host for things like setting parameters.
pub(crate) struct WrapperGuiContext<P: Vst3Plugin> { pub(crate) struct WrapperGuiContext<P: Vst3Plugin> {
pub(super) inner: Arc<WrapperInner<P>>, pub(super) inner: Arc<WrapperInner<P>>,
} }
/// A [ProcessContext] implementation for the wrapper. This is a separate object so it can hold on /// A [`ProcessContext`] implementation for the wrapper. This is a separate object so it can hold on
/// to lock guards for event queues. Otherwise reading these events would require constant /// to lock guards for event queues. Otherwise reading these events would require constant
/// unnecessary atomic operations to lock the uncontested locks. /// unnecessary atomic operations to lock the uncontested locks.
pub(crate) struct WrapperProcessContext<'a, P: Vst3Plugin> { pub(crate) struct WrapperProcessContext<'a, P: Vst3Plugin> {

View file

@ -24,16 +24,16 @@ pub(crate) struct WrapperInner<P: Vst3Plugin> {
/// The wrapped plugin instance. /// The wrapped plugin instance.
pub plugin: RwLock<P>, pub plugin: RwLock<P>,
/// The plugin's editor, if it has one. This object does not do anything on its own, but we need /// The plugin's editor, if it has one. This object does not do anything on its own, but we need
/// to instantiate this in advance so we don't need to lock the entire [Plugin] object when /// to instantiate this in advance so we don't need to lock the entire [`Plugin`] object when
/// creating an editor. /// creating an editor.
pub editor: Option<Arc<dyn Editor>>, pub editor: Option<Arc<dyn Editor>>,
/// The host's `IComponentHandler` instance, if passed through /// The host's [`IComponentHandler`] instance, if passed through
/// `IEditController::set_component_handler`. /// [`IEditController::set_component_handler`].
pub component_handler: AtomicRefCell<Option<VstPtr<dyn IComponentHandler>>>, pub component_handler: AtomicRefCell<Option<VstPtr<dyn IComponentHandler>>>,
/// Our own [IPlugView] instance. This is set while the editor is actually visible (which is /// Our own [`IPlugView`] instance. This is set while the editor is actually visible (which is
/// different form the lifetimei of [super::WrapperView] itself). /// different form the lifetime of [`WrapperView`][super::WrapperView] itself).
pub plug_view: RwLock<Option<ObjectPtr<WrapperView<P>>>>, pub plug_view: RwLock<Option<ObjectPtr<WrapperView<P>>>>,
/// A realtime-safe task queue so the plugin can schedule tasks that need to be run later on the /// A realtime-safe task queue so the plugin can schedule tasks that need to be run later on the
@ -58,7 +58,7 @@ pub(crate) struct WrapperInner<P: Vst3Plugin> {
pub bypass_state: AtomicBool, pub bypass_state: AtomicBool,
/// 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.
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 form
/// apointer to pointers, so this needs to be preallocated in the setup call and kept around /// apointer to pointers, so this needs to be preallocated in the setup call and kept around
@ -84,9 +84,10 @@ pub(crate) struct WrapperInner<P: Vst3Plugin> {
/// Mappings from string parameter indentifiers to parameter hashes. Useful for debug logging /// Mappings from string parameter indentifiers to parameter hashes. Useful for debug logging
/// and when storing and restorign plugin state. /// and when storing and restorign plugin state.
pub param_id_to_hash: HashMap<&'static str, u32>, pub param_id_to_hash: HashMap<&'static str, u32>,
/// The inverse mapping from [Self::param_by_hash]. This is needed to be able to have an /// The inverse mapping from [`param_by_hash`][Self::param_by_hash]. This is needed to be able
/// ergonomic parameter setting API that uses references to the parameters instead of having to /// to have an ergonomic parameter setting API that uses references to the parameters instead of
/// add a setter function to the parameter (or even worse, have it be completely untyped). /// having to add a setter function to the parameter (or even worse, have it be completely
/// untyped).
pub param_ptr_to_hash: HashMap<ParamPtr, u32>, pub param_ptr_to_hash: HashMap<ParamPtr, u32>,
} }
@ -96,7 +97,7 @@ pub(crate) struct WrapperInner<P: Vst3Plugin> {
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub enum Task { pub enum Task {
/// Trigger a restart with the given restart flags. This is a bit set of the flags from /// Trigger a restart with the given restart flags. This is a bit set of the flags from
/// [vst3_sys::vst::RestartFlags]. /// [`vst3_sys::vst::RestartFlags`].
TriggerRestart(i32), TriggerRestart(i32),
} }

View file

@ -19,7 +19,7 @@ macro_rules! check_null_ptr {
}; };
} }
/// The same as [check_null_ptr!], but with a custom message. /// The same as [`check_null_ptr!`], but with a custom message.
macro_rules! check_null_ptr_msg { macro_rules! check_null_ptr_msg {
($msg:expr, $ptr:expr $(, $ptrs:expr)* $(, )?) => { ($msg:expr, $ptr:expr $(, $ptrs:expr)* $(, )?) => {
if $ptr.is_null() $(|| $ptrs.is_null())* { if $ptr.is_null() $(|| $ptrs.is_null())* {
@ -35,8 +35,8 @@ pub struct VstPtr<T: vst3_sys::ComInterface + ?Sized> {
ptr: vst3_sys::VstPtr<T>, ptr: vst3_sys::VstPtr<T>,
} }
/// The same as [VstPtr] with shared semnatics, but for objects we defined ourself since VstPtr only /// The same as [`VstPtr`] with shared semnatics, but for objects we defined ourself since VstPtr
/// works for interfaces. /// only works for interfaces.
#[repr(transparent)] #[repr(transparent)]
pub struct ObjectPtr<T: IUnknown> { pub struct ObjectPtr<T: IUnknown> {
ptr: *const T, ptr: *const T,

View file

@ -28,7 +28,7 @@ const VST3_PLATFORM_UIVIEW: &str = "UIView";
#[allow(unused)] #[allow(unused)]
const VST3_PLATFORM_X11_WINDOW: &str = "X11EmbedWindowID"; const VST3_PLATFORM_X11_WINDOW: &str = "X11EmbedWindowID";
/// The plugin's [IPlugView] instance created in [IEditController::create_view] if `P` has an /// The plugin's [`IPlugView`] instance created in [`IEditController::create_view()`] if `P` has an
/// editor. This is managed separately so the lifetime bounds match up. /// editor. This is managed separately so the lifetime bounds match up.
#[VST3(implements(IPlugView))] #[VST3(implements(IPlugView))]
pub(crate) struct WrapperView<P: Vst3Plugin> { pub(crate) struct WrapperView<P: Vst3Plugin> {

View file

@ -334,7 +334,7 @@ impl<P: Vst3Plugin> IEditController for Wrapper<P> {
u16strlcpy(&mut info.title, param_ptr.name()); u16strlcpy(&mut info.title, param_ptr.name());
u16strlcpy(&mut info.short_title, param_ptr.name()); u16strlcpy(&mut info.short_title, param_ptr.name());
u16strlcpy(&mut info.units, param_ptr.unit()); u16strlcpy(&mut info.units, param_ptr.unit());
// TODO: The host assumes these steps are distirbuted linearly, so this may cause weird // TODO: The host assumes these steps are distributed linearly, so this may cause weird
// behavior with skewed integers // behavior with skewed integers
info.step_count = param_ptr.step_count().unwrap_or(0) as i32; info.step_count = param_ptr.step_count().unwrap_or(0) as i32;
info.default_normalized_value = *default_value as f64; info.default_normalized_value = *default_value as f64;