Skip to main content

Plugin

Struct Plugin 

Source
pub struct Plugin { /* private fields */ }
Expand description

VST3 plugin instance

Implementations§

Source§

impl Plugin

Source

pub fn info(&self) -> &PluginInfo

Get plugin information

Source

pub fn sample_rate(&self) -> f64

The sample rate (Hz) this plugin was configured with at load.

Source

pub fn block_size(&self) -> usize

The maximum block size (frames per process_audio call) configured at load.

Source

pub fn reconfigure(&mut self, sample_rate: f64, block_size: usize) -> Result<()>

Reconfigure the plugin for a new sample rate and/or maximum block size, re-running the plugin’s setupProcessing and rebuilding its audio buffers.

Use this when the audio device’s sample rate changes mid-session instead of reloading. The plugin must not be processing: call Self::stop_processing first, reconfigure, then Self::start_processing again. Returns an error if called while processing, or on an invalid sample rate / zero block size. Works both in-process and across process isolation.

Source

pub fn set_process_mode(&mut self, mode: ProcessMode) -> Result<()>

Switch the plugin between real-time and offline processing, re-running the plugin’s setupProcessing so it can adjust quality / look-ahead for a faster-than-real-time bounce.

Like Self::reconfigure, the plugin must not be processing: call Self::stop_processing first. Returns an error if called while processing. Works both in-process and across process isolation.

Source

pub fn bus_arrangements(&self) -> Result<BusArrangements>

Query the current speaker arrangement of each audio input/output bus. Works both in-process and across process isolation.

Source

pub fn set_bus_arrangements( &mut self, inputs: &[SpeakerArrangement], outputs: &[SpeakerArrangement], ) -> Result<()>

Request specific speaker arrangements for the audio buses (e.g. force stereo, or a surround layout). The slices give one SpeakerArrangement per input bus and per output bus, in bus-index order.

Re-runs the plugin’s setupProcessing, so the plugin must not be processing (call Self::stop_processing first). A plugin may decline a requested layout and keep its own; re-query with Self::bus_arrangements to see what was actually applied. Errors while processing. Works both in-process and across process isolation.

Source

pub fn set_bus_active( &mut self, media_type: MediaType, direction: BusDirection, bus_index: i32, active: bool, ) -> Result<()>

Activate or deactivate a single bus on the plugin (IComponent::activateBus).

Hosts must explicitly activate the buses they intend to use; a plugin’s secondary buses (sidechain / aux inputs, extra outputs) commonly start inactive and only receive/produce audio once activated. (The load sequence already activates the main audio and event buses, so call this to enable the rest.)

media_type selects audio vs event buses and direction selects input vs output; bus_index is the 0-based index within that (media_type, direction) group (the same indexing as crate::discovery::BusLayout). active true activates, false deactivates.

VST3 requires bus activation to happen while the component is inactive — i.e. before processing starts. This therefore returns an error if called while the plugin is processing; call Self::stop_processing first, activate the bus, then Self::start_processing again. Returns an error for an out-of-range bus_index, and under process isolation activation marshals across the boundary.

Source

pub fn get_parameters(&self) -> Result<Vec<Parameter>>

Get all parameters

Source

pub fn set_parameter(&mut self, id: u32, value: f64) -> Result<()>

Set a parameter value by ID

Source

pub fn set_parameter_at( &mut self, id: u32, value: f64, sample_offset: i32, ) -> Result<()>

Set a parameter value at a specific sample offset within the next process block.

This is the sample-accurate building block for automation: call it once per sub-block point (e.g. from ParameterAutomation::points_for_block) and the plugin receives the changes at their offsets in the next process_audio. Like Self::set_parameter, value is normalized 0.0..=1.0.

sample_offset is clamped to the block. Under process isolation the offset is now carried across the boundary and applied by the helper’s in-process plugin.

Source

pub fn set_tempo(&mut self, bpm: f64) -> Result<()>

Change the transport tempo (beats per minute) advertised to the plugin in the host ProcessContext, taking effect on the next processed block — even while the plugin is actively processing. Drives tempo-synced DSP (LFOs, synced delays, arpeggiators).

bpm must be finite and greater than 0 (a non-positive tempo would freeze or reverse the derived musical playhead). Works both in-process and across process isolation.

Source

pub fn set_time_signature( &mut self, numerator: i32, denominator: i32, ) -> Result<()>

Change the transport time signature advertised to the plugin in the host ProcessContext (numerator/denominator, e.g. 7, 8), taking effect on the next processed block — even while the plugin is actively processing.

numerator must be greater than 0 and denominator must be a power of two between 1 and 16 (1, 2, 4, 8, or 16) — the standard note values a time signature can denominate. Works both in-process and across process isolation.

Source

pub fn set_playing(&mut self, playing: bool) -> Result<()>

Toggle the transport playing state advertised to the plugin in the host ProcessContext (the kPlaying flag), taking effect on the next processed block — even while the plugin is actively processing.

While playing, the host advances the continuous and musical playhead each block; while stopped, the playhead still advances but the plugin sees the transport as not playing (so tempo-synced effects can react to a paused transport). Works both in-process and across process isolation.

Source

pub fn get_units(&self) -> Result<Vec<PluginUnit>>

Enumerate the plugin’s units and their program lists (IUnitInfo).

Returns an empty list for plugins that don’t implement IUnitInfo. The root unit (id 0) is typically present. Works both in-process and across process isolation.

Source

pub fn select_program(&mut self, unit_id: i32, program_index: i32) -> Result<()>

Select a program (preset) in a unit’s program list (IUnitInfo).

unit_id is a PluginUnit::id from get_units (the root unit is 0); program_index is a 0-based index into that unit’s PluginUnit::programs. Internally this locates the unit’s program-change parameter (the controller parameter tied to the unit with the VST3 kIsProgramChange flag) and sets it to the normalized value program_index / max(1, program_count - 1), driving both the controller (for the editor/display) and the processor (for the audio DSP).

Returns an error for an unknown unit, a unit with no program list, an out-of-range index, a plugin that doesn’t implement IUnitInfo, or a plugin running under process isolation only if the helper cannot resolve the unit. Works both in-process and across the isolation boundary.

Source

pub fn latency_samples(&self) -> u32

The plugin’s reported processing latency in samples (e.g. from look-ahead or oversampling), via IAudioProcessor::getLatencySamples. Use it to delay-compensate when aligning the plugin’s output with other signals. 0 if it reports none. Works both in-process and across process isolation.

Source

pub fn tail_samples(&self) -> u32

The plugin’s reported tail length in samples (how long it keeps producing output after input stops — e.g. reverb/delay), via IAudioProcessor::getTailSamples. 0 means no tail; u32::MAX means an infinite tail. Works both in-process and across process isolation.

Source

pub fn midi_cc_to_parameter( &self, bus: i32, channel: i16, cc: u16, ) -> Option<u32>

Resolve a MIDI controller to the parameter it’s mapped to, via the plugin’s IMidiMapping (getMidiControllerAssignment).

bus is the event input bus index (usually 0), channel the 0-based MIDI channel, and cc the MIDI controller number (0–127, or the VST3 specials such as 128 aftertouch / 129 pitch-bend). Returns the parameter id the controller drives, or None if the plugin doesn’t implement IMidiMapping or the controller is unmapped. Works both in-process and across process isolation.

Source

pub fn get_parameter(&self, id: u32) -> Result<f64>

Get a parameter value by ID

Source

pub fn format_parameter(&self, id: u32, normalized: f64) -> Result<String>

Format a parameter value as the plugin itself would display it.

VST3 keeps all parameter values normalized (0.0–1.0) and delegates human-readable formatting to the plugin’s controller. This asks the plugin to render normalized for parameter id, returning exactly what its own UI would show — e.g. "440.00 Hz", "-6.0 dB", "Sine". Prefer this over Parameter::format_value, which can only approximate without the plugin’s internal mapping.

Source

pub fn set_parameter_by_name(&mut self, name: &str, value: f64) -> Result<()>

Set a parameter by name

Source

pub fn find_parameter(&self, name: &str) -> Result<Parameter>

Find a parameter by name

Source

pub fn send_midi_note( &mut self, note: u8, velocity: u8, channel: MidiChannel, ) -> Result<()>

Send a MIDI note on event

Source

pub fn send_midi_note_off( &mut self, note: u8, channel: MidiChannel, ) -> Result<()>

Send a MIDI note off event

Source

pub fn send_midi_cc( &mut self, controller: u8, value: u8, channel: MidiChannel, ) -> Result<()>

Send a MIDI control change event

Source

pub fn send_midi_event(&mut self, event: MidiEvent) -> Result<()>

Send a generic MIDI event

Source

pub fn send_midi_event_at( &mut self, event: MidiEvent, sample_offset: i32, ) -> Result<()>

Schedule a MIDI event at a sample offset within the next process_audio block.

Use this for sample-accurate sequencing: an event sent with sample_offset = N takes effect N frames into the next processed block, rather than at its start. Keep the offset within the upcoming block’s frame count (Plugin::block_size is the maximum); a negative offset is treated as 0, and an offset past the block end is plugin-defined.

Works both in-process and across process isolation — the offset is carried across the boundary and applied by the helper’s in-process plugin.

Source

pub fn note_on( &mut self, channel: MidiChannel, note: u8, velocity: u8, ) -> Result<NoteId>

Start a note and get a per-voice NoteId handle for sending per-note (MPE-style) expression to that exact voice via send_note_expression.

Unlike send_midi_note (which uses a shared note id and can’t be individually expressed), this allocates a unique voice id. Pair it with note_off. Per-note expression works both in-process and under process isolation — the calls marshal across the boundary.

Source

pub fn note_on_at( &mut self, channel: MidiChannel, note: u8, velocity: u8, sample_offset: i32, ) -> Result<NoteId>

note_on scheduled at a sample offset within the next block.

Source

pub fn note_off(&mut self, id: NoteId) -> Result<()>

Release a note started with note_on.

Source

pub fn note_off_at(&mut self, id: NoteId, sample_offset: i32) -> Result<()>

note_off scheduled at a sample offset within the next block.

Source

pub fn send_note_expression( &mut self, id: NoteId, kind: NoteExpressionType, value: f64, ) -> Result<()>

Send a per-note expression value for a voice (normalized 0.0..=1.0; bipolar dimensions like Tuning center at 0.5). The plugin must implement INoteExpressionController and the dimension must be one it advertises (see note_expressions).

Source

pub fn send_note_expression_at( &mut self, id: NoteId, kind: NoteExpressionType, value: f64, sample_offset: i32, ) -> Result<()>

send_note_expression scheduled at a sample offset.

Source

pub fn note_expressions(&self) -> Result<Vec<NoteExpressionInfo>>

Enumerate the per-note expression dimensions the plugin advertises for the given event bus / channel (defaults: bus 0, channel 0), via INoteExpressionController. Empty if the plugin doesn’t implement it.

Source

pub fn start_processing(&mut self) -> Result<()>

Start audio processing

Source

pub fn stop_processing(&mut self) -> Result<()>

Stop audio processing

Source

pub fn process_audio(&mut self, buffers: &mut AudioBuffers) -> Result<()>

Process audio buffers

Source

pub fn get_output_levels(&self) -> AudioLevels

Get current output levels.

Recovers automatically if the audio thread panicked while holding the lock (poisoned mutex) rather than propagating the panic to the caller — metering must never take down a UI thread polling it.

Source

pub fn is_processing(&self) -> bool

Check if the plugin is currently processing

Source

pub fn on_parameter_change<F>(&mut self, callback: F)
where F: Fn(u32, f64) + Send + 'static,

Set a callback for parameter changes

Source

pub fn on_audio_process<F>(&mut self, callback: F)
where F: Fn(&AudioLevels) + Send + 'static,

Set a callback for audio processing (called after each process cycle)

Source

pub fn has_editor(&self) -> bool

Check if the plugin has an editor GUI

Source

pub fn open_editor(&mut self, parent: WindowHandle) -> Result<()>

Open the plugin editor window

Source

pub fn service_run_loop(&mut self)

Drive the Linux IRunLoop services (timers and file-descriptor events) that the plugin’s editor registered with the host frame. VSTGUI-based editors paint and respond ONLY when this runs - call it on the UI thread every frame (e.g. 30-60 Hz) while an editor is open. A no-op when nothing is registered, on non-Linux, or under process isolation.

Source

pub fn close_editor(&mut self) -> Result<()>

Close the plugin editor window

Source

pub fn get_editor_size(&self) -> Result<(i32, i32)>

Get the preferred editor size

Source

pub fn update_parameters<F>(&mut self, f: F) -> Result<()>
where F: FnOnce(&mut ParameterUpdate<'_>) -> Result<()>,

Create a batch parameter update

Source

pub fn midi_panic(&mut self) -> Result<()>

Send MIDI panic (all notes off, all sounds off, reset controllers)

Source

pub fn get_parameter_changes(&self) -> Vec<(u32, f64)>

Get parameter changes from plugin GUI Returns a vector of (parameter_id, normalized_value) pairs This should be called regularly to pick up parameter changes made through the plugin’s GUI

Source

pub fn take_parameter_edits(&mut self) -> Vec<ParameterEdit>

Drain the ordered log of parameter-edit gestures the plugin’s editor has reported since the last call.

This is the richer superset of Self::get_parameter_changes: rather than just the value changes, it preserves the begin/change/end ordering of each gesture, so the host can tell a deliberate, completed edit (BeginGestureValueChange* … EndGesture) from a stream of intermediate drag values. Poll it regularly (e.g. each UI frame) while the editor is open; an empty vector means nothing was reported. Works across process isolation — gestures are marshalled back from the helper.

See ParameterEdit / ParameterEditKind.

Source

pub fn take_output_midi(&self) -> Vec<MidiEvent>

Take the MIDI events the plugin has emitted (e.g. from an arpeggiator or MPE controller) since the last call, draining the internal buffer.

Output MIDI is captured while the plugin processes audio, so poll this regularly (e.g. each UI frame) while the plugin is playing; an empty vector means the plugin emitted nothing. This works for process-isolated plugins too — emitted events are marshalled back alongside each processed block.

The buffer is capped at 4096 events: if you never poll while a chatty plugin keeps emitting, the oldest events are dropped (silently) to bound memory.

Source

pub fn output_midi_handle(&self) -> Option<OutputMidiConsumer>

Get a Send handle for draining emitted MIDI from another thread without locking the audio thread (see OutputMidiConsumer). Returns None for an unloaded plugin or the process-isolation path. Useful with RealtimePluginRunner: take the handle, move the plugin into the runner, and poll it from your UI thread while the audio thread renders.

Source

pub fn save_state(&self) -> Result<Vec<u8>>

Save the plugin’s current state (parameters, internal settings, loaded preset) to an opaque byte blob.

The bytes are the plugin’s own serialized state — treat them as opaque and pair them with the plugin’s identity (PluginInfo::uid); they only mean something to the same plugin. Persist them to restore a patch later with Self::load_state, or to snapshot a session. Call this on the main thread (see the threading model).

Works both in-process and across process isolation (the state blob is marshalled over the IPC boundary). Returns an error for plugins that don’t implement state saving.

Source

pub fn load_state(&mut self, data: &[u8]) -> Result<()>

Restore plugin state from a blob produced by Self::save_state on the same plugin. Applies to both the processor and the controller, so parameter values and the editor reflect the restored state.

Passing bytes from a different plugin has undefined results (the plugin decides what to do with bytes it doesn’t recognize). Call this on the main thread.

Source

pub fn save_preset<P: AsRef<Path>>(&self, path: P) -> Result<()>

Save this plugin’s state to a file as a PluginPreset (JSON: the plugin’s uid and name plus the opaque state blob). The embedded uid lets Self::load_preset reject a preset saved from a different plugin.

Source

pub fn load_preset<P: AsRef<Path>>(&mut self, path: P) -> Result<()>

Load a PluginPreset file written by Self::save_preset and apply its state. Returns an error if the preset’s uid doesn’t match this plugin (loading another plugin’s state is undefined).

Source

pub fn save_vstpreset<P: AsRef<Path>>(&self, path: P) -> Result<()>

Save this plugin’s state to a standard Steinberg .vstpreset file.

Unlike Self::save_preset (a JSON wrapper specific to this library), the .vstpreset container is the interchange format shared by VST3 hosts and plugins, so the file can be read by other hosts (and by the plugin’s own preset browser). It wraps the same opaque bytes from Self::save_state in a single "Comp" (component state) chunk, tagged with this plugin’s class id (PluginInfo::uid) so a loader can reject presets from a different plugin. Call this on the main thread.

Source

pub fn load_vstpreset<P: AsRef<Path>>(&mut self, path: P) -> Result<()>

Load a Steinberg .vstpreset file and apply its component state to this plugin.

Parses the .vstpreset container written by Self::save_vstpreset (or another VST3 host), extracts the "Comp" (component state) chunk and passes it to Self::load_state. Returns an error if the file’s magic is invalid, or if its class id doesn’t match this plugin (loading another plugin’s state is undefined). Call this on the main thread.

Source

pub fn isolation_pid(&self) -> Option<u32>

The OS process id of the isolated helper hosting this plugin, or None if it runs in-process. Useful for monitoring an isolated plugin’s resource use.

Source

pub fn recovery_count(&self) -> u64

How many times this plugin has been recovered (helper respawned + reloaded), via either Self::recover or automatic recovery (Vst3HostBuilder::auto_recover_plugins).

A recovery reloads the plugin from defaults — parameter values and loaded state are NOT replayed. With auto-recover on, a crash is otherwise invisible (the call returns Ok), so poll this count to detect that a reset happened and re-apply a saved save_state snapshot.

Source

pub fn output_channel_count(&self) -> usize

Total number of output audio channels across the plugin’s output buses.

Reflects the plugin’s actual bus layout (mono / stereo / surround / multi-bus), not a stereo assumption — useful for sizing meters or output buffers. Returns 2 if unknown.

Source

pub fn take_editor_resize_request(&self) -> Option<(i32, i32)>

Poll for an editor resize the plugin requested via VST3’s IPlugFrame since the last call, as (width, height) in pixels, or None.

Plugins with resizable editors call back to ask the host to resize the window hosting their view. Poll this on your UI thread (e.g. each frame) while the editor is open and resize your editor container to match. Only the in-process editor path reports this.

Source

pub fn recover(&mut self) -> Result<()>

Recover a process-isolated plugin whose helper has crashed.

When an isolated plugin’s helper process dies, calls return Error::PluginCrashed and the host itself stays alive. This respawns the helper and reloads the plugin from the same path and audio settings, restarting processing if it was running.

The reloaded plugin starts from its default state — parameter values and any loaded preset are lost. Snapshot with Self::save_state beforehand and Self::load_state after recovering to preserve them. Returns an error for in-process plugins (an in-process crash takes down the whole host) and if the reload itself fails.

Auto Trait Implementations§

§

impl !RefUnwindSafe for Plugin

§

impl !Sync for Plugin

§

impl !UnwindSafe for Plugin

§

impl Freeze for Plugin

§

impl Send for Plugin

§

impl Unpin for Plugin

§

impl UnsafeUnpin for Plugin

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<S, T> Duplex<S> for T
where T: FromSample<S> + ToSample<S>,

Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<S> FromSample<S> for S

Source§

fn from_sample_(s: S) -> S

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> ToSample<U> for T
where U: FromSample<T>,

Source§

fn to_sample_(self) -> U

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.