From 6fd22b3ba99428bf8badb93569c678f03d972c2d Mon Sep 17 00:00:00 2001 From: Robbert van der Helm Date: Sun, 19 Feb 2023 15:43:40 +0100 Subject: [PATCH] Move audio setup related structs to a new module --- src/audio_setup.rs | 84 +++++++++++++++++++++++++ src/lib.rs | 3 +- src/plugin.rs | 82 +----------------------- src/prelude.rs | 8 +-- src/wrapper/clap/wrapper.rs | 6 +- src/wrapper/standalone/backend/cpal.rs | 3 +- src/wrapper/standalone/backend/dummy.rs | 3 +- src/wrapper/standalone/wrapper.rs | 7 +-- src/wrapper/state.rs | 3 +- src/wrapper/vst3/inner.rs | 5 +- src/wrapper/vst3/wrapper.rs | 8 +-- 11 files changed, 108 insertions(+), 104 deletions(-) create mode 100644 src/audio_setup.rs diff --git a/src/audio_setup.rs b/src/audio_setup.rs new file mode 100644 index 00000000..4c8062c3 --- /dev/null +++ b/src/audio_setup.rs @@ -0,0 +1,84 @@ +//! Types and definitions surrounding a plugin's audio bus setup. + +use crate::buffer::Buffer; + +/// The plugin's IO configuration. +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub struct BusConfig { + /// The number of input channels for the plugin. + pub num_input_channels: u32, + /// The number of output channels for the plugin. + pub num_output_channels: u32, + /// Any additional sidechain inputs. + pub aux_input_busses: AuxiliaryIOConfig, + /// Any additional outputs. + pub aux_output_busses: AuxiliaryIOConfig, +} + +/// Configuration for auxiliary inputs or outputs on [`BusConfig`]. +#[derive(Debug, Default, Clone, Copy, PartialEq, Eq)] +pub struct AuxiliaryIOConfig { + /// The number of auxiliary input or output busses. + pub num_busses: u32, + /// The number of channels in each bus. + pub num_channels: u32, +} + +/// Contains auxiliary (sidechain) input and output buffers for a process call. +pub struct AuxiliaryBuffers<'a> { + /// All auxiliary (sidechain) inputs defined for this plugin. The data in these buffers can + /// safely be overwritten. Auxiliary inputs can be defined by setting + /// [`Plugin::DEFAULT_AUX_INPUTS`][`crate::prelude::Plugin::DEFAULT_AUX_INPUTS`]. + pub inputs: &'a mut [Buffer<'a>], + /// Get all auxiliary outputs defined for this plugin. Auxiliary outputs can be defined by + /// setting [`Plugin::DEFAULT_AUX_OUTPUTS`][`crate::prelude::Plugin::DEFAULT_AUX_OUTPUTS`]. + pub outputs: &'a mut [Buffer<'a>], +} + +/// Contains names for the main input and output ports as well as for all of the auxiliary input and +/// output ports. Setting these is optional, but it makes working with multi-output plugins much +/// more convenient. +#[derive(Debug, Default, Clone, PartialEq, Eq)] +pub struct PortNames { + /// The name for the main input port. Will be generated if not set. + pub main_input: Option<&'static str>, + /// The name for the main output port. Will be generated if not set. + pub main_output: Option<&'static str>, + /// Names for auxiliary (sidechain) input ports. Will be generated if not set or if this slice + /// does not contain enough names. + pub aux_inputs: Option<&'static [&'static str]>, + /// Names for auxiliary output ports. Will be generated if not set or if this slice does not + /// contain enough names. + pub aux_outputs: Option<&'static [&'static str]>, +} + +/// Configuration for (the host's) audio buffers. +#[derive(Debug, Clone, Copy, PartialEq)] +pub struct BufferConfig { + /// The current sample rate. + pub sample_rate: f32, + /// The minimum buffer size the host will use. This may not be set. + pub min_buffer_size: Option, + /// The maximum buffer size the host will use. The plugin should be able to accept variable + /// sized buffers up to this size, or between the minimum and the maximum buffer size if both + /// are set. + pub max_buffer_size: u32, + /// The current processing mode. The host will reinitialize the plugin any time this changes. + pub process_mode: ProcessMode, +} + +/// The plugin's current processing mode. Exposed through [`BufferConfig::process_mode`]. The host +/// will reinitialize the plugin whenever this changes. +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub enum ProcessMode { + /// The plugin is processing audio in real time at a fixed rate. + Realtime, + /// The plugin is processing audio at a real time-like pace, but at irregular intervals. The + /// host may do this to process audio ahead of time to loosen realtime constraints and to reduce + /// the chance of xruns happening. This is only used by VST3. + Buffered, + /// The plugin is rendering audio offline, potentially faster than realtime ('freewheeling'). + /// The host will continuously call the process function back to back until all audio has been + /// processed. + Offline, +} diff --git a/src/lib.rs b/src/lib.rs index dd247c65..b44ab9c6 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -97,10 +97,11 @@ pub use log; /// Everything you'll need to use NIH-plug. Import this with `use nih_plug::prelude::*;`. pub mod prelude; -// These modules have also been re-exported in the prelude. +// These modules are also re-exported in the prelude pub mod formatters; pub mod util; +pub mod audio_setup; pub mod buffer; pub mod context; pub mod editor; diff --git a/src/plugin.rs b/src/plugin.rs index 85c6fdf4..d454404c 100644 --- a/src/plugin.rs +++ b/src/plugin.rs @@ -2,6 +2,7 @@ use std::sync::Arc; +use crate::audio_setup::{AuxiliaryBuffers, AuxiliaryIOConfig, BufferConfig, BusConfig, PortNames}; use crate::buffer::Buffer; use crate::context::gui::AsyncExecutor; use crate::context::init::InitContext; @@ -286,71 +287,6 @@ const fn swap_vst3_uid_byte_order(mut uid: [u8; 16]) -> [u8; 16] { uid } -/// The plugin's IO configuration. -#[derive(Debug, Clone, Copy, PartialEq, Eq)] -pub struct BusConfig { - /// The number of input channels for the plugin. - pub num_input_channels: u32, - /// The number of output channels for the plugin. - pub num_output_channels: u32, - /// Any additional sidechain inputs. - pub aux_input_busses: AuxiliaryIOConfig, - /// Any additional outputs. - pub aux_output_busses: AuxiliaryIOConfig, -} - -/// Configuration for auxiliary inputs or outputs on [`BusConfig`]. -#[derive(Debug, Default, Clone, Copy, PartialEq, Eq)] -pub struct AuxiliaryIOConfig { - /// The number of auxiliary input or output busses. - pub num_busses: u32, - /// The number of channels in each bus. - pub num_channels: u32, -} - -/// Contains names for the main input and output ports as well as for all of the auxiliary input and -/// output ports. Setting these is optional, but it makes working with multi-output plugins much -/// more convenient. -#[derive(Debug, Default, Clone, PartialEq, Eq)] -pub struct PortNames { - /// The name for the main input port. Will be generated if not set. - pub main_input: Option<&'static str>, - /// The name for the main output port. Will be generated if not set. - pub main_output: Option<&'static str>, - /// Names for auxiliary (sidechain) input ports. Will be generated if not set or if this slice - /// does not contain enough names. - pub aux_inputs: Option<&'static [&'static str]>, - /// Names for auxiliary output ports. Will be generated if not set or if this slice does not - /// contain enough names. - pub aux_outputs: Option<&'static [&'static str]>, -} - -/// Configuration for (the host's) audio buffers. -#[derive(Debug, Clone, Copy, PartialEq)] -pub struct BufferConfig { - /// The current sample rate. - pub sample_rate: f32, - /// The minimum buffer size the host will use. This may not be set. - pub min_buffer_size: Option, - /// The maximum buffer size the host will use. The plugin should be able to accept variable - /// sized buffers up to this size, or between the minimum and the maximum buffer size if both - /// are set. - pub max_buffer_size: u32, - /// The current processing mode. The host will reinitialize the plugin any time this changes. - pub process_mode: ProcessMode, -} - -/// Contains auxiliary (sidechain) input and output buffers for a process call. -pub struct AuxiliaryBuffers<'a> { - /// All auxiliary (sidechain) inputs defined for this plugin. The data in these buffers can - /// safely be overwritten. Auxiliary inputs can be defined by setting - /// [`Plugin::DEFAULT_AUX_INPUTS`][`crate::prelude::Plugin::DEFAULT_AUX_INPUTS`]. - pub inputs: &'a mut [Buffer<'a>], - /// Get all auxiliary outputs defined for this plugin. Auxiliary outputs can be defined by - /// setting [`Plugin::DEFAULT_AUX_OUTPUTS`][`crate::prelude::Plugin::DEFAULT_AUX_OUTPUTS`]. - pub outputs: &'a mut [Buffer<'a>], -} - /// Indicates the current situation after the plugin has processed audio. #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub enum ProcessStatus { @@ -367,22 +303,6 @@ pub enum ProcessStatus { KeepAlive, } -/// The plugin's current processing mode. Exposed through [`BufferConfig::process_mode`]. The host -/// will reinitialize the plugin whenever this changes. -#[derive(Debug, Clone, Copy, PartialEq, Eq)] -pub enum ProcessMode { - /// The plugin is processing audio in real time at a fixed rate. - Realtime, - /// The plugin is processing audio at a real time-like pace, but at irregular intervals. The - /// host may do this to process audio ahead of time to loosen realtime constraints and to reduce - /// the chance of xruns happening. This is only used by VST3. - Buffered, - /// The plugin is rendering audio offline, potentially faster than realtime ('freewheeling'). - /// The host will continuously call the process function back to back until all audio has been - /// processed. - Offline, -} - /// Configuration for the plugin's polyphonic modulation options, if it supports . pub struct PolyModulationConfig { /// The maximum number of voices this plugin will ever use. Call the context's diff --git a/src/prelude.rs b/src/prelude.rs index ddf26572..f9e6d2d2 100644 --- a/src/prelude.rs +++ b/src/prelude.rs @@ -10,6 +10,9 @@ pub use crate::wrapper::standalone::{nih_export_standalone, nih_export_standalon pub use crate::formatters; pub use crate::util; +pub use crate::audio_setup::{ + AuxiliaryBuffers, AuxiliaryIOConfig, BufferConfig, BusConfig, PortNames, ProcessMode, +}; pub use crate::buffer::Buffer; pub use crate::context::gui::{AsyncExecutor, GuiContext, ParamSetter}; pub use crate::context::init::InitContext; @@ -26,10 +29,7 @@ pub use crate::params::Params; pub use crate::params::{BoolParam, FloatParam, IntParam, Param, ParamFlags}; #[cfg(feature = "vst3")] pub use crate::plugin::Vst3Plugin; -pub use crate::plugin::{ - AuxiliaryBuffers, AuxiliaryIOConfig, BufferConfig, BusConfig, ClapPlugin, Plugin, - PolyModulationConfig, PortNames, ProcessMode, ProcessStatus, TaskExecutor, -}; +pub use crate::plugin::{ClapPlugin, Plugin, PolyModulationConfig, ProcessStatus, TaskExecutor}; pub use crate::wrapper::clap::features::ClapFeature; pub use crate::wrapper::state::PluginState; #[cfg(feature = "vst3")] diff --git a/src/wrapper/clap/wrapper.rs b/src/wrapper/clap/wrapper.rs index abfa59f8..c5c2ce8c 100644 --- a/src/wrapper/clap/wrapper.rs +++ b/src/wrapper/clap/wrapper.rs @@ -78,6 +78,7 @@ use std::time::Duration; use super::context::{WrapperGuiContext, WrapperInitContext, WrapperProcessContext}; use super::descriptor::PluginDescriptor; use super::util::ClapPtr; +use crate::audio_setup::{AuxiliaryBuffers, BufferConfig, BusConfig, ProcessMode}; use crate::buffer::Buffer; use crate::context::gui::AsyncExecutor; use crate::context::process::Transport; @@ -87,10 +88,7 @@ use crate::midi::sysex::SysExMessage; use crate::midi::{MidiConfig, MidiResult, NoteEvent, PluginNoteEvent}; use crate::params::internals::ParamPtr; use crate::params::{ParamFlags, Params}; -use crate::plugin::{ - AuxiliaryBuffers, BufferConfig, BusConfig, ClapPlugin, Plugin, ProcessMode, ProcessStatus, - TaskExecutor, -}; +use crate::plugin::{ClapPlugin, Plugin, ProcessStatus, TaskExecutor}; use crate::util::permit_alloc; use crate::wrapper::clap::util::{read_stream, write_stream}; use crate::wrapper::state::{self, PluginState}; diff --git a/src/wrapper/standalone/backend/cpal.rs b/src/wrapper/standalone/backend/cpal.rs index c527aa49..a32a7b19 100644 --- a/src/wrapper/standalone/backend/cpal.rs +++ b/src/wrapper/standalone/backend/cpal.rs @@ -8,10 +8,11 @@ use rtrb::RingBuffer; use super::super::config::WrapperConfig; use super::Backend; +use crate::audio_setup::{AuxiliaryIOConfig, BusConfig}; use crate::buffer::Buffer; use crate::context::process::Transport; use crate::midi::{MidiConfig, PluginNoteEvent}; -use crate::plugin::{AuxiliaryIOConfig, BusConfig, Plugin}; +use crate::plugin::Plugin; /// Uses CPAL for audio and midir for MIDI. pub struct Cpal { diff --git a/src/wrapper/standalone/backend/dummy.rs b/src/wrapper/standalone/backend/dummy.rs index 70b228bd..da53db5f 100644 --- a/src/wrapper/standalone/backend/dummy.rs +++ b/src/wrapper/standalone/backend/dummy.rs @@ -2,10 +2,11 @@ use std::time::{Duration, Instant}; use super::super::config::WrapperConfig; use super::Backend; +use crate::audio_setup::{AuxiliaryIOConfig, BusConfig}; use crate::buffer::Buffer; use crate::context::process::Transport; use crate::midi::PluginNoteEvent; -use crate::plugin::{AuxiliaryIOConfig, BusConfig, Plugin}; +use crate::plugin::Plugin; /// This backend doesn't input or output any audio or MIDI. It only exists so the standalone /// application can continue to run even when there is no audio backend available. This can be diff --git a/src/wrapper/standalone/wrapper.rs b/src/wrapper/standalone/wrapper.rs index 78f92baa..db1e09a4 100644 --- a/src/wrapper/standalone/wrapper.rs +++ b/src/wrapper/standalone/wrapper.rs @@ -13,6 +13,8 @@ use std::thread; use super::backend::Backend; use super::config::WrapperConfig; use super::context::{WrapperGuiContext, WrapperInitContext, WrapperProcessContext}; +use crate::audio_setup::AuxiliaryBuffers; +use crate::audio_setup::{AuxiliaryIOConfig, BufferConfig, BusConfig, ProcessMode}; use crate::context::gui::AsyncExecutor; use crate::context::process::Transport; use crate::editor::{Editor, ParentWindowHandle}; @@ -20,10 +22,7 @@ use crate::event_loop::{EventLoop, MainThreadExecutor, OsEventLoop}; use crate::midi::PluginNoteEvent; use crate::params::internals::ParamPtr; use crate::params::{ParamFlags, Params}; -use crate::plugin::{ - AuxiliaryBuffers, AuxiliaryIOConfig, BufferConfig, BusConfig, Plugin, ProcessMode, - ProcessStatus, TaskExecutor, -}; +use crate::plugin::{Plugin, ProcessStatus, TaskExecutor}; use crate::util::permit_alloc; use crate::wrapper::state::{self, PluginState}; use crate::wrapper::util::process_wrapper; diff --git a/src/wrapper/state.rs b/src/wrapper/state.rs index 8fff90bb..bdbaec5a 100644 --- a/src/wrapper/state.rs +++ b/src/wrapper/state.rs @@ -6,9 +6,10 @@ use serde::{Deserialize, Serialize}; use std::collections::{BTreeMap, HashMap}; use std::sync::Arc; +use crate::audio_setup::BufferConfig; use crate::params::internals::ParamPtr; use crate::params::{Param, ParamMut, Params}; -use crate::plugin::{BufferConfig, Plugin}; +use crate::plugin::Plugin; // These state objects are also exposed directly to the plugin so it can do its own internal preset // management diff --git a/src/wrapper/vst3/inner.rs b/src/wrapper/vst3/inner.rs index acc83a8a..8be4262c 100644 --- a/src/wrapper/vst3/inner.rs +++ b/src/wrapper/vst3/inner.rs @@ -14,6 +14,7 @@ use super::note_expressions::NoteExpressionController; use super::param_units::ParamUnits; use super::util::{ObjectPtr, VstPtr, VST3_MIDI_PARAMS_END, VST3_MIDI_PARAMS_START}; use super::view::WrapperView; +use crate::audio_setup::{BufferConfig, BusConfig, ProcessMode}; use crate::buffer::Buffer; use crate::context::gui::AsyncExecutor; use crate::context::process::Transport; @@ -22,9 +23,7 @@ use crate::event_loop::{EventLoop, MainThreadExecutor, OsEventLoop}; use crate::midi::{MidiConfig, PluginNoteEvent}; use crate::params::internals::ParamPtr; use crate::params::{ParamFlags, Params}; -use crate::plugin::{ - BufferConfig, BusConfig, Plugin, ProcessMode, ProcessStatus, TaskExecutor, Vst3Plugin, -}; +use crate::plugin::{Plugin, ProcessStatus, TaskExecutor, Vst3Plugin}; use crate::wrapper::state::{self, PluginState}; use crate::wrapper::util::{hash_param_id, process_wrapper}; diff --git a/src/wrapper/vst3/wrapper.rs b/src/wrapper/vst3/wrapper.rs index 31087d69..5ba7503a 100644 --- a/src/wrapper/vst3/wrapper.rs +++ b/src/wrapper/vst3/wrapper.rs @@ -26,15 +26,15 @@ use super::util::{ }; use super::util::{VST3_MIDI_CHANNELS, VST3_MIDI_PARAMS_END}; use super::view::WrapperView; +use crate::audio_setup::{ + AuxiliaryBuffers, AuxiliaryIOConfig, BufferConfig, BusConfig, ProcessMode, +}; use crate::buffer::Buffer; use crate::context::process::Transport; use crate::midi::sysex::SysExMessage; use crate::midi::{MidiConfig, NoteEvent}; use crate::params::ParamFlags; -use crate::plugin::{ - AuxiliaryBuffers, AuxiliaryIOConfig, BufferConfig, BusConfig, ProcessMode, ProcessStatus, - Vst3Plugin, -}; +use crate::plugin::{ProcessStatus, Vst3Plugin}; use crate::util::permit_alloc; use crate::wrapper::state; use crate::wrapper::util::{clamp_input_event_timing, clamp_output_event_timing, process_wrapper};