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 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))]
pub fn derive_params(input: TokenStream) -> TokenStream {
let ast = syn::parse_macro_input!(input as syn::DeriveInput);
@ -265,6 +266,7 @@ pub fn derive_params(input: TokenStream) -> TokenStream {
.into()
}
/// Derive the `Enum` trait for your simple enum parameters. See `EnumParam` for more information.
#[proc_macro_derive(Enum, attributes(name))]
pub fn derive_enum(input: TokenStream) -> TokenStream {
let ast = syn::parse_macro_input!(input as syn::DeriveInput);

View file

@ -17,16 +17,16 @@ pub use egui;
pub mod widgets;
/// Create an [Editor] instance using an [::egui] GUI. Using the user state parameter is optional,
/// but it can be useful for keeping track of some temporary GUI-only settings. See the `gui_gain`
/// example for more information on how to use this. The [EguiState] passed to this function
/// contains the GUI's intitial size, and this is kept in sync whenever the GUI gets resized. You
/// can also use this to know if the GUI is open, so you can avoid performing potentially expensive
/// calculations while the GUI is not open. If you want this size to be persisted when restoring a
/// plugin instance, then you can store it in a `#[persist = "key"]` field on your parameters
/// struct.
/// Create an [`Editor`] instance using an [`egui`][::egui] GUI. Using the user state parameter is
/// optional, but it can be useful for keeping track of some temporary GUI-only settings. See the
/// `gui_gain` example for more information on how to use this. The [`EguiState`] passed to this
/// function contains the GUI's intitial size, and this is kept in sync whenever the GUI gets
/// resized. You can also use this to know if the GUI is open, so you can avoid performing
/// potentially expensive calculations while the GUI is not open. If you want this size to be
/// persisted when restoring a plugin instance, then you can store it in a `#[persist = "key"]`
/// 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
pub fn create_egui_editor<T, U>(
@ -53,7 +53,7 @@ pub struct 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> {
Arc::new(EguiState {
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> {
egui_state: Arc<EguiState>,
/// 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 {
egui_state: Arc<EguiState>,
window: WindowHandle,

View file

@ -13,7 +13,7 @@ lazy_static! {
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.
///
/// TODO: Vertical orientation
@ -31,7 +31,7 @@ pub struct ParamSlider<'a, P: Param> {
impl<'a, P: Param> ParamSlider<'a, P> {
/// 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 {
Self {
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`
/// file in the workspace's root are respected (see
/// <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<()> {
let bundle_name = match load_bundler_config()?.and_then(|c| c.get(package).cloned()) {
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.
fn target_base(cross_compile_target: Option<&str>) -> Result<&'static str> {
match cross_compile_target {

View file

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

View file

@ -57,7 +57,7 @@ struct Diopser {
sample_rate: f32,
/// 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.
#[cfg(feature = "simd")]
filters: [filter::Biquad<f32x2>; MAX_NUM_FILTERS],
@ -315,8 +315,9 @@ impl Plugin for Diopser {
}
impl Diopser {
/// Check if the filters need to be updated beased on [Self::should_update_filters] and the
/// smoothing interval, and update them as needed.
/// Check if the filters need to be updated beased on
/// [`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) {
// In addition to updating the filters, we should also clear the filter's state when
// 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.
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
/// 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
/// [Samples]. Can be turned into an iterator, or [Channels::iter_mut()] can be used to iterate over
/// the channel data multiple times, or more efficiently you can use [Channels::get_unchecked_mut()]
/// to do the same thing.
/// [`Samples`]. Can be turned into an iterator, or [`Channels::iter_mut()`] can be used to iterate
/// over the channel data multiple times, or more efficiently you can use
/// [`Channels::get_unchecked_mut()`] to do the same thing.
pub struct Channels<'slice, 'sample: 'slice> {
/// The raw output buffers.
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]]>,
}
/// 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> {
/// The raw output buffers.
pub(self) buffers: *mut [&'sample mut [f32]],
@ -55,8 +55,8 @@ pub struct ChannelsIter<'slice, 'sample: 'slice> {
// Per-block per-channel per-sample iterators
/// 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
/// offset from the start of the buffer.
/// size of `max_block_size`. See [`Buffer::iter_blocks()`]. Yields both the block and the offset
/// from the start of the buffer.
pub struct BlocksIter<'slice, 'sample: 'slice> {
/// The raw output buffers.
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]]>,
}
/// A block yielded by [BlocksIter]. Can be iterated over once or multiple times, and also supports
/// direct access to the block's samples if needed.
/// A block yielded by [`BlocksIter`]. Can be iterated over once or multiple times, and also
/// supports direct access to the block's samples if needed.
pub struct Block<'slice, 'sample: 'slice> {
/// The raw output buffers.
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]]>,
}
/// An iterator over all channels in a block yielded by [Block]. Analogous to [ChannelsIter] but for
/// blocks.
/// An iterator over all channels in a block yielded by [`Block`]. Analogous to [`ChannelsIter`] but
/// for blocks.
pub struct BlockChannelsIter<'slice, 'sample: 'slice> {
/// The raw output buffers.
pub(self) buffers: *mut [&'sample mut [f32]],
@ -262,11 +262,12 @@ impl<'a> Buffer<'a> {
/// SIMD.
///
/// 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
/// [crate::Plugin::initialize_block_smoothers()] with the same `max_block_size` in your
/// initialization function first.
/// [`Smoother::next_block()`][crate::Smoother::next_block()]. Before using this, you will need
/// to call
/// [`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
/// 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
/// 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> {
ChannelsIter {
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
///
@ -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
/// [Self::to_simd()] into account.
/// [`to_simd()`][Self::to_simd()] into account.
#[cfg(feature = "simd")]
#[allow(clippy::wrong_self_convention)]
#[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
/// you don't need to use this function as [Block] already implements [Iterator]. You can also
/// use the direct accessor functions on this block instead.
/// you don't need to use this function as [`Block`] already implements [`Iterator`]. You can
/// also use the direct accessor functions on this block instead.
pub fn iter_mut(&mut self) -> BlockChannelsIter<'slice, 'sample> {
BlockChannelsIter {
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.
#[inline]
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
///
@ -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
/// 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.
#[cfg(feature = "simd")]

View file

@ -7,7 +7,8 @@ use crate::plugin::NoteEvent;
// TODO: ProcessContext for parameter automation and sending events
/// 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
//
@ -32,16 +33,16 @@ pub trait ProcessContext {
}
/// 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
/// assume they're being called from the main GUI thread.
/// values. This is passed to the plugin during [`Editor::spawn()`][crate::Editor::spawn()]. All of
/// these functions assume they're being called from the main GUI thread.
//
// # Safety
//
// 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.
pub trait GuiContext: Send + Sync + 'static {
/// Inform the host a parameter will be automated. Create a [ParamSetter] and use
/// [ParamSetter::begin_set_parameter] instead for a safe, user friendly API.
/// Inform the host a parameter will be automated. Create a [`ParamSetter`] and use
/// [`ParamSetter::begin_set_parameter()`] instead for a safe, user friendly API.
///
/// # Safety
///
@ -50,7 +51,8 @@ pub trait GuiContext: Send + Sync + 'static {
unsafe fn raw_begin_set_parameter(&self, param: ParamPtr);
/// 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
///
@ -58,8 +60,8 @@ pub trait GuiContext: Send + Sync + 'static {
/// mostly marked as unsafe for API reasons.
unsafe fn raw_set_parameter_normalized(&self, param: ParamPtr, normalized: f32);
/// Inform the host a parameter has been automated. Create a [ParamSetter] and use
/// [ParamSetter::end_set_parameter] instead for a safe, user friendly API.
/// Inform the host a parameter has been automated. Create a [`ParamSetter`] and use
/// [`ParamSetter::end_set_parameter()`] instead for a safe, user friendly API.
///
/// # Safety
///
@ -68,8 +70,8 @@ pub trait GuiContext: Send + Sync + 'static {
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
/// callback Create a [ParamSetter] and use [ParamSetter::default_param_value] instead for a
/// safe, user friendly API.
/// callback Create a [`ParamSetter`] and use [`ParamSetter::default_param_value()`] instead for
/// a safe, user friendly API.
///
/// # 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
/// 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) {
unsafe { self.context.raw_begin_set_parameter(param.as_ptr()) };
}
/// 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
/// the host can properly record automation for the parameter. This can be called multiple times
/// in a row before calling [Self::end_set_parameter()], for instance when moving a slider
/// around.
/// [`begin_set_parameter()`][Self::begin_set_parameter()] before and
/// [`end_set_parameter()`][Self::end_set_parameter()] after calling this so the host can
/// properly record automation for the parameter. This can be called multiple times in a row
/// 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
/// 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
/// [Self::set_parameter] and needs to follow the same rules, but this may be useful when
/// implementing a GUI.
/// [`set_parameter()`][Self::set_parameter()] and needs to follow the same rules, but this may
/// be useful when implementing a GUI.
///
/// 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
/// the host matches `param.normalized_value()`.
/// value and setting that with [`set_parameter()`][Self::set_parameter()] instead so the
/// normalized value known to the host matches `param.normalized_value()`.
pub fn set_parameter_normalized<P: Param>(&self, param: &P, normalized: f32) {
let ptr = param.as_ptr();
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
/// or more [Self::set_parameter()] calls for a parameter so the host knows the automation
/// gesture has finished.
/// or more [`set_parameter()`][Self::set_parameter()] calls for a parameter so the host knows
/// the automation gesture has finished.
pub fn end_set_parameter<P: Param>(&self, param: &P) {
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 {
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 crate::nih_log;
/// See [super::EventLoop].
/// See [`EventLoop`][super::EventLoop].
#[cfg_attr(
target_os = "macos",
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.
main_thread_id: ThreadId,
/// A thread that act as our worker thread. When [Self::do_maybe_async()] is called, this thread will be
/// woken up to execute the task on the executor. This is wrapped in an `Option` so the thread
/// can be taken out of it and joined when this struct gets dropped.
/// A thread that act as our worker thread. When [`do_maybe_async()`][Self::do_maybe_async()] is
/// called, this thread will be woken up to execute the task on the executor. This is wrapped in
/// an `Option` so the thread can be taken out of it and joined when this struct gets dropped.
worker_thread: Option<JoinHandle<()>>,
/// 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>>,
}
@ -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>)
where
T: Send,

View file

@ -33,7 +33,7 @@ const NOTIFY_MESSAGE_ID: u32 = WM_USER;
/// casted from a regular pointer.
type PollCallback = Box<dyn Fn()>;
/// See [super::EventLoop].
/// See [`EventLoop`][super::EventLoop].
pub(crate) struct WindowsEventLoop<T, E> {
/// 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

View file

@ -37,7 +37,7 @@ pub trait Param: Display {
fn plain_value(&self) -> Self::Plain;
/// 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.
fn set_plain_value(&mut self, plain: Self::Plain);
@ -46,7 +46,7 @@ pub trait Param: Display {
fn normalized_value(&self) -> f32;
/// 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.
fn set_normalized_value(&mut self, normalized: f32);
@ -64,7 +64,7 @@ pub trait Param: Display {
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
/// 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;
/// 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.
fn update_smoother(&mut self, sample_rate: f32, reset: bool);
/// Allocate memory for block-based smoothing. The [crate::Plugin::initialize_block_smoothers()]
/// method will do this for every smoother.
/// Allocate memory for block-based smoothing. The
/// [`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);
/// Internal implementation detail for implementing [internals::Params]. This should not be used
/// directly.
/// Internal implementation detail for implementing [`Params`][internals::Params]. This should
/// not be used directly.
fn as_ptr(&self) -> internals::ParamPtr;
}

View file

@ -142,7 +142,7 @@ impl Param for 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.
pub fn new(name: &'static str, default: bool) -> Self {
Self {

View file

@ -33,15 +33,17 @@ pub trait Enum {
fn variants() -> &'static [&'static str];
/// 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;
/// Get the variant corresponding to the variant with the same index in [Self::variants()]. This
/// must always return a value. If the index is out of range, return the first variatn.
/// 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
/// range, return the first variatn.
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
/// for more information on how this works.
pub struct EnumParam<T: Enum> {
@ -50,12 +52,12 @@ pub struct EnumParam<T: Enum> {
inner: EnumParamInner,
/// `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>,
}
/// The type-erased internals for [EnumParam] so that the wrapper can interact with it. Acts like an
/// [IntParam] but with different conversions from strings to values.
/// The type-erased internals for [`EnumParam`] so that the wrapper can interact with it. Acts like
/// an [`IntParam`] but with different conversions from strings to values.
pub struct EnumParamInner {
/// The integer parameter backing this enum parameter.
pub(crate) inner: IntParam,

View file

@ -12,7 +12,7 @@ use super::Param;
/// process.
///
/// 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
// 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.
pub range: FloatRange,
/// 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
/// formatting the parameter. This must be a positive, nonzero number.
/// input. If this is set and if [`value_to_string`][Self::value_to_string] is not set, then
/// this is also used when formatting the parameter. This must be a positive, nonzero number.
pub step_size: Option<f32>,
/// The parameter's human readable display name.
pub name: &'static str,
/// The parameter value's unit, added after `value_to_string` if that is set. NIH-plug will not
/// automatically add a space before the unit.
/// The parameter value's unit, added after [`value_to_string`][Self::value_to_string] if that
/// is set. NIH-plug will not automatically add a space before the unit.
pub unit: &'static str,
/// Optional custom conversion function from a plain **unnormalized** value to a string.
pub value_to_string: Option<Arc<dyn Fn(f32) -> String + Send + Sync>>,
@ -197,7 +197,7 @@ impl Param for 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.
pub fn new(name: &'static str, default: f32, range: FloatRange) -> Self {
Self {
@ -225,7 +225,7 @@ impl FloatParam {
}
/// 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.
pub fn with_unit(mut self, unit: &'static str) -> Self {
self.unit = unit;
@ -233,8 +233,8 @@ impl FloatParam {
}
/// 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
/// formatting the parameter. This must be a positive, nonzero number.
/// this is set and if [`value_to_string`][Self::value_to_string] is not set, then this is also
/// used when formatting the parameter. This must be a positive, nonzero number.
pub fn with_step_size(mut self, step_size: f32) -> Self {
self.step_size = Some(step_size);
self

View file

@ -12,7 +12,7 @@ use super::Param;
/// process.
///
/// 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
// plain primitive values that are modified through the `*mut` pointers from the plugin's
@ -176,7 +176,7 @@ impl Param for 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.
pub fn new(name: &'static str, default: i32, range: IntRange) -> Self {
Self {
@ -204,7 +204,7 @@ impl IntParam {
}
/// 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.
pub fn with_unit(mut self, unit: &'static str) -> Self {
self.unit = unit;

View file

@ -5,21 +5,21 @@ use std::pin::Pin;
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;
/// 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;
/// 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
/// assigning a unique identifier to each parameter. We can then build a mapping from those
/// parameter IDs to the parameters using the [Params::param_map()] function. That way we can have
/// easy to work with JUCE-style parameter objects in the plugin without needing to manually
/// register each parameter, like you would in JUCE. When deriving this trait, any of those
/// have a normal struct containing [`FloatParam`][super::FloatParam] and other parameter types with
/// attributes assigning a unique identifier to each parameter. We can then build a mapping from
/// those parameter IDs to the parameters using the [`Params::param_map()`] function. That way we
/// can have easy to work with JUCE-style parameter objects in the plugin without needing to
/// 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
/// (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
/// marked with `#[persist = "key"]`.
///
@ -54,13 +54,14 @@ pub trait Params {
/// 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
/// 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>;
/// 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
/// 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()] under the hood.
/// [`serialize_fields()`][Self::serialize_fields()]. All of thse fields should be wrapped in a
/// [`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()]
/// under the hood.
fn deserialize_fields(&self, serialized: &HashMap<String, String>);
}
@ -96,17 +97,17 @@ where
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
/// underlying parameter type, so instead we need to type erase all of the functions individually.
macro_rules! param_ptr_forward(
(pub unsafe fn $method:ident(&self $(, $arg_name:ident: $arg_ty:ty)*) $(-> $ret:ty)?) => {
/// Calls the corresponding method on the underlying [Param] object.
/// Calls the corresponding method on the underlying [`Param`] object.
///
/// # Safety
///
/// Calling this function is only safe as long as the object this [ParamPtr] was created for
/// is still alive.
/// Calling this function is only safe as long as the object this [`ParamPtr`] was created
/// for is still alive.
pub unsafe fn $method(&self $(, $arg_name: $arg_ty)*) $(-> $ret)? {
match &self {
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
// it being defined in the macro.
(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
///
/// Calling this function is only safe as long as the object this [ParamPtr] was created for
/// is still alive.
/// Calling this function is only safe as long as the object this [`ParamPtr`] was created
/// for is still alive.
pub unsafe fn $method(&mut self $(, $arg_name: $arg_ty)*) $(-> $ret)? {
match &self {
ParamPtr::FloatParam(p) => (**p).$method($($arg_name),*),

View file

@ -7,13 +7,13 @@ pub enum FloatRange {
Linear { min: f32, max: f32 },
/// 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
/// [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
/// the start.
Skewed { min: f32, max: f32, factor: f32 },
/// The same as [FloatRange::Skewed], but with the skewing happening from a central point. This
/// central point is rescaled to be at 50% of the parameter's range for convenience of use. Git
/// blame this comment to find a version that doesn't do this.
/// The same as [`FloatRange::Skewed`], but with the skewing happening from a central point.
/// This central point is rescaled to be at 50% of the parameter's range for convenience of use.
/// Git blame this comment to find a version that doesn't do this.
SymmetricalSkewed {
min: f32,
max: f32,
@ -44,7 +44,7 @@ impl Default for IntRange {
}
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
/// wider.
pub fn skew_factor(factor: f32) -> f32 {

View file

@ -42,7 +42,8 @@ pub struct Smoother<T> {
target: T,
/// 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>>,
}
@ -74,15 +75,15 @@ impl<T: Default> Smoother<T> {
Default::default()
}
/// Whether calling [Self::next()] will yield a new value or an old value. Useful if you need to
/// recompute something wheenver this parameter changes.
/// 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.
pub fn is_smoothing(&self) -> bool {
self.steps_left.load(Ordering::Relaxed) > 0
}
/// 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
/// [crate::Buffer::iter_blocks()].
/// [`Plugin::initialize()`][crate::Plugin::initialize()] with the same max block size you are
/// going to pass to [`Buffer::iter_blocks()`][crate::Buffer::iter_blocks()].
pub fn initialize_block_smoother(&mut self, max_block_size: usize) {
self.block_values
.borrow_mut()
@ -135,10 +136,11 @@ impl Smoother<f32> {
}
/// Produce smoothed values for an entire block of audio. Used in conjunction with
/// [crate::Buffer::iter_blocks()]. Make sure to call
/// [crate::Plugin::initialize_block_smoothers()] with the same maximum buffer block size as the
/// one passed to `iter_blocks()` in your [crate::Plugin::initialize()] function first to
/// allocate memory for the block smoothing.
/// [`Buffer::iter_blocks()`][crate::Buffer::iter_blocks()]. Make sure to call
/// [`Plugin::initialize_block_smoothers()`][crate::Plugin::initialize_block_smoothers()] with
/// the same maximum buffer block size as the one passed to `iter_blocks()` in your
/// [`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.
///
@ -163,10 +165,10 @@ impl Smoother<f32> {
}))
}
/// [Self::next()], but with the ability to skip forward in the smoother. [Self::next()] is
/// equivalent to calling this function with a `steps` value of 1. Calling this function with a
/// `steps` value of `n` means will cause you to skip the next `n - 1` values and return the
/// `n`th value.
/// [`next()`][Self::next()], but with the ability to skip forward in the smoother.
/// [`next()`][Self::next()] is equivalent to calling this function with a `steps` value of 1.
/// Calling this function with a `steps` value of `n` means will cause you to skip the next `n -
/// 1` values and return the `n`th value.
#[inline]
pub fn next_step(&self, steps: u32) -> f32 {
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
/// [crate::Buffer::iter_blocks()]. Make sure to call
/// [crate::Plugin::initialize_block_smoothers()] with the same maximum buffer block size as the
/// one passed to `iter_blocks()` in your [crate::Plugin::initialize()] function first to
/// allocate memory for the block smoothing.
/// [`Buffer::iter_blocks()`][crate::Buffer::iter_blocks()]. Make sure to call
/// [`Plugin::initialize_block_smoothers()`][crate::Plugin::initialize_block_smoothers()] with
/// the same maximum buffer block size as the one passed to `iter_blocks()` in your
/// [`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.
///
@ -260,10 +263,10 @@ impl Smoother<i32> {
}))
}
/// [Self::next()], but with the ability to skip forward in the smoother. [Self::next()] is
/// equivalent to calling this function with a `steps` value of 1. Calling this function with a
/// `steps` value of `n` means will cause you to skip the next `n - 1` values and return the
/// `n`th value.
/// [`next()`][Self::next()], but with the ability to skip forward in the smoother.
/// [`next()`][Self::next()] is equivalent to calling this function with a `steps` value of 1.
/// Calling this function with a `steps` value of `n` means will cause you to skip the next `n -
/// 1` values and return the `n`th value.
pub fn next_step(&self, steps: u32) -> i32 {
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>;
/// 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
/// other shared data, so you'll need to move [Arc] pointing to any data you want to access into
/// the editor. You can later modify the parameters through the [crate::GuiContext] and
/// [crate::ParamSetter] after the editor GUI has been created.
/// [`Editor::spawn()`]. A plugin editor likely wants to interact with the plugin's parameters
/// and other shared data, so you'll need to move [`Arc`] pointing to any data you want to
/// access into the editor. You can later modify the parameters through the
/// [`GuiContext`][crate::GuiContext] and [`ParamSetter`][crate::ParamSetter] after the editor
/// GUI has been created.
fn editor(&self) -> Option<Box<dyn Editor>> {
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
/// 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
/// 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:
/// use [crate::Smoother::next()] for per-sample processing, and [crate::Smoother::next_block()]
/// for block-based processing. In order to use block-based smoothing, you will need to call
/// [Self::initialize_block_smoothers()] in your [Self::initialize()] function first to reserve
/// enough capacity in the smoothers.
/// use [`Smoother::next()`][crate::Smoother::next()] for per-sample processing, and
/// [`Smoother::next_block()`][crate::Smoother::next_block()] for block-based processing. In
/// order to use block-based smoothing, you will need to call
/// [`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
/// assymetric
@ -113,10 +116,10 @@ pub trait Plugin: Default + Send + Sync + 'static {
fn process(&mut self, buffer: &mut Buffer, context: &mut impl ProcessContext) -> ProcessStatus;
/// 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
/// [Buffer::iter_blocks] and want to use parameter smoothing in those blocks, then call this
/// function with the same maximum block size first before calling
/// [crate::Smoother::next_block()].
/// memory, this should be called in [`initialize()`][Self::initialize()]. If you are going to
/// use [`Buffer::iter_blocks()`] and want to use parameter smoothing in those blocks, then call
/// this function with the same maximum block size first before calling
/// [`Smoother::next_block()`][crate::Smoother::next_block()].
fn initialize_block_smoothers(&mut self, max_block_size: usize) {
for param in self.params().param_map().values_mut() {
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.
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:
/// <https://github.com/steinbergmedia/vst3_pluginterfaces/blob/2ad397ade5b51007860bedb3b01b8afd2c5f6fba/vst/ivstaudioprocessor.h#L49-L90>
const VST3_CATEGORIES: &'static str;
/// [Self::VST3_CLASS_ID] in the correct order for the current platform so projects and presets
/// can be shared between platforms. This should not be overridden.
/// [`VST3_CLASS_ID`][Self::VST3_CLASS_ID`] in the correct order for the current platform so
/// 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);
}
@ -185,16 +188,16 @@ const fn swap_vst3_uid_byte_order(mut uid: [u8; 16]) -> [u8; 16] {
uid
}
/// An editor for a [Plugin].
/// An editor for a [`Plugin`].
pub trait Editor: Send + Sync {
/// 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
/// [crate::ParamSetter]. When you change a parameter value that way it will be broadcasted to
/// the host and also updated in your [Params] struct.
/// [`ParamSetter`][crate::ParamSetter]. When you change a parameter value that way it will be
/// 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
/// 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.
///
/// 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
/// [MINUS_INFINITY_DB].
/// [`MINUS_INFINITY_DB`].
pub fn gain_to_db(gain: f32) -> f32 {
if gain > 0.0 {
gain.log10() * 20.0

View file

@ -10,14 +10,14 @@ use crate::param::internals::ParamPtr;
use crate::plugin::{ClapPlugin, NoteEvent};
use crate::GuiContext;
/// 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
/// things like setting parameters.
/// A [`GuiContext`] implementation for the wrapper. This is passed to the plugin in
/// [`Editor::spawn()`][crate::Editor::spawn()] so it can interact with the rest of the plugin and
/// with the host for things like setting parameters.
pub(crate) struct WrapperGuiContext<P: ClapPlugin> {
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
/// unnecessary atomic operations to lock the uncontested RwLocks.
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
/// 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> {
// We need [CString]s for all of `ClapPlugin`'s `&str` fields
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 {
($msg:expr, $ret:expr, $ptr:expr $(, $ptrs:expr)* $(, )?) => {
if $ptr.is_null() $(|| $ptrs.is_null())* {

View file

@ -90,7 +90,7 @@ pub struct Wrapper<P: ClapPlugin> {
/// The wrapped plugin instance.
plugin: RwLock<P>,
/// 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.
editor: Option<Arc<dyn Editor>>,
/// 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
/// queue first
input_events: AtomicRefCell<VecDeque<NoteEvent>>,
/// The current latency in samples, as set by the plugin through the [ProcessContext]. uses the
/// latency extnesion
/// The current latency in samples, as set by the plugin through the [`ProcessContext`]. uses
/// the latency extnesion
pub current_latency: AtomicU32,
/// 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
@ -171,9 +171,10 @@ pub struct Wrapper<P: ClapPlugin> {
/// Mappings from string parameter indentifiers to parameter hashes. Useful for debug logging
/// and when storing and restoring plugin state.
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
/// ergonomic parameter setting API that uses references to the parameters instead of having to
/// add a setter function to the parameter (or even worse, have it be completely untyped).
/// 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
/// 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>,
/// A queue of parameter changes that should be output in either the next process call or in the
/// 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
/// 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
/// [Self::on_main_thread] on the main thread, and then continue to pop tasks off this queue
/// there until it is empty.
/// [`on_main_thread()`][Self::on_main_thread()] on the main thread, and then continue to pop
/// tasks off this queue there until it is empty.
tasks: ArrayQueue<Task>,
/// 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
/// contains a value), then that extension is used instead.
/// object. If the host supports the thread check extension (and
/// [`host_thread_check`][Self::host_thread_check] thus contains a value), then that extension
/// is used instead.
main_thread_id: ThreadId,
}
/// 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
/// implementation, this uses [clap_host::request_callback()] instead.
/// implementation, this uses [`clap_host::request_callback()`] instead.
#[derive(Debug, Clone)]
pub enum Task {
/// Inform the host that the latency has changed.
@ -223,11 +225,11 @@ pub struct OutputParamChange {
/// The internal hash for the parameter.
pub param_hash: u32,
/// 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,
}
/// 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.
impl<P: ClapPlugin> EventLoop<Task, Wrapper<P>> for Wrapper<P> {
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
/// from the process function.
/// Handle an incoming CLAP event. You must clear [`input_events`][Self::input_events] first
/// before calling this from the process function.
///
/// To save on mutex operations when handing MIDI events, the lock guard for the input events
/// 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.
pub params: HashMap<String, ParamValue>,
/// 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.
///
/// 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;
}
/// 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) {
if dest.is_empty() {
return;

View file

@ -10,14 +10,14 @@ use crate::event_loop::EventLoop;
use crate::param::internals::ParamPtr;
use crate::plugin::{NoteEvent, Vst3Plugin};
/// 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
/// things like setting parameters.
/// A [`GuiContext`] implementation for the wrapper. This is passed to the plugin in
/// [`Editor::spawn()`][crate::Editor::spawn()] so it can interact with the rest of the plugin and
/// with the host for things like setting parameters.
pub(crate) struct WrapperGuiContext<P: Vst3Plugin> {
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
/// unnecessary atomic operations to lock the uncontested locks.
pub(crate) struct WrapperProcessContext<'a, P: Vst3Plugin> {

View file

@ -24,16 +24,16 @@ pub(crate) struct WrapperInner<P: Vst3Plugin> {
/// The wrapped plugin instance.
pub plugin: RwLock<P>,
/// 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.
pub editor: Option<Arc<dyn Editor>>,
/// The host's `IComponentHandler` instance, if passed through
/// `IEditController::set_component_handler`.
/// The host's [`IComponentHandler`] instance, if passed through
/// [`IEditController::set_component_handler`].
pub component_handler: AtomicRefCell<Option<VstPtr<dyn IComponentHandler>>>,
/// Our own [IPlugView] instance. This is set while the editor is actually visible (which is
/// different form the lifetimei of [super::WrapperView] itself).
/// Our own [`IPlugView`] instance. This is set while the editor is actually visible (which is
/// different form the lifetime of [`WrapperView`][super::WrapperView] itself).
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
@ -58,7 +58,7 @@ pub(crate) struct WrapperInner<P: Vst3Plugin> {
pub bypass_state: AtomicBool,
/// The last process status returned by the plugin. This is used for tail handling.
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,
/// 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
@ -84,9 +84,10 @@ pub(crate) struct WrapperInner<P: Vst3Plugin> {
/// Mappings from string parameter indentifiers to parameter hashes. Useful for debug logging
/// and when storing and restorign plugin state.
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
/// ergonomic parameter setting API that uses references to the parameters instead of having to
/// add a setter function to the parameter (or even worse, have it be completely untyped).
/// 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
/// 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>,
}
@ -96,7 +97,7 @@ pub(crate) struct WrapperInner<P: Vst3Plugin> {
#[derive(Debug, Clone)]
pub enum Task {
/// 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),
}

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

View file

@ -28,7 +28,7 @@ const VST3_PLATFORM_UIVIEW: &str = "UIView";
#[allow(unused)]
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.
#[VST3(implements(IPlugView))]
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.short_title, param_ptr.name());
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
info.step_count = param_ptr.step_count().unwrap_or(0) as i32;
info.default_normalized_value = *default_value as f64;