pub struct Plugin { /* private fields */ }Expand description
VST3 plugin instance
Implementations§
Source§impl Plugin
impl Plugin
Sourcepub fn info(&self) -> &PluginInfo
pub fn info(&self) -> &PluginInfo
Get plugin information
Sourcepub fn class_compatibility(&self) -> &[ClassCompatibility]
pub fn class_compatibility(&self) -> &[ClassCompatibility]
Current/retired class-id replacement mappings advertised by this plug-in.
These come from moduleinfo.json when present, otherwise from the factory’s optional
IPluginCompatibility class.
Sourcepub fn replaced_class_ids(&self) -> &[String]
pub fn replaced_class_ids(&self) -> &[String]
Retired class ids which this loaded audio class replaces.
Sourcepub fn sample_rate(&self) -> f64
pub fn sample_rate(&self) -> f64
The sample rate (Hz) this plugin was configured with at load.
Sourcepub fn block_size(&self) -> usize
pub fn block_size(&self) -> usize
The maximum block size (frames per process_audio call) configured at load.
Sourcepub fn reconfigure(&mut self, sample_rate: f64, block_size: usize) -> Result<()>
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.
Sourcepub fn set_process_mode(&mut self, mode: ProcessMode) -> Result<()>
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.
Sourcepub fn bus_arrangements(&self) -> Result<BusArrangements>
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.
Sourcepub fn set_bus_arrangements(
&mut self,
inputs: &[SpeakerArrangement],
outputs: &[SpeakerArrangement],
) -> Result<()>
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.
Sourcepub fn set_bus_active(
&mut self,
media_type: MediaType,
direction: BusDirection,
bus_index: i32,
active: bool,
) -> Result<()>
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.
Sourcepub fn get_parameters(&self) -> Result<Vec<Parameter>>
pub fn get_parameters(&self) -> Result<Vec<Parameter>>
Get all parameters
Sourcepub fn set_parameter_at(
&mut self,
id: u32,
value: f64,
sample_offset: i32,
) -> Result<()>
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.
Sourcepub fn set_tempo(&mut self, bpm: f64) -> Result<()>
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.
Sourcepub fn set_time_signature(
&mut self,
numerator: i32,
denominator: i32,
) -> Result<()>
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.
Sourcepub fn set_playing(&mut self, playing: bool) -> Result<()>
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.
Sourcepub fn get_units(&self) -> Result<Vec<PluginUnit>>
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.
Sourcepub fn select_program(&mut self, unit_id: i32, program_index: i32) -> Result<()>
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.
Sourcepub fn selected_unit(&self) -> Result<Option<i32>>
pub fn selected_unit(&self) -> Result<Option<i32>>
Return the unit currently selected by the plugin, or None without IUnitInfo.
Sourcepub fn select_unit(&mut self, unit_id: i32) -> Result<()>
pub fn select_unit(&mut self, unit_id: i32) -> Result<()>
Select a unit through IUnitInfo::selectUnit.
Sourcepub fn program_pitch_names(
&self,
program_list_id: i32,
program_index: i32,
) -> Result<Vec<ProgramPitchName>>
pub fn program_pitch_names( &self, program_list_id: i32, program_index: i32, ) -> Result<Vec<ProgramPitchName>>
Query the plugin’s MIDI-pitch names for one program.
Sourcepub fn get_program_data(
&self,
program_list_id: i32,
program_index: i32,
) -> Result<Option<Vec<u8>>>
pub fn get_program_data( &self, program_list_id: i32, program_index: i32, ) -> Result<Option<Vec<u8>>>
Read opaque per-program data, or None when IProgramListData is absent/unsupported.
Sourcepub fn set_program_data(
&mut self,
program_list_id: i32,
program_index: i32,
data: &[u8],
) -> Result<()>
pub fn set_program_data( &mut self, program_list_id: i32, program_index: i32, data: &[u8], ) -> Result<()>
Restore opaque per-program data through IProgramListData.
Sourcepub fn get_unit_data(&self, unit_id: i32) -> Result<Option<Vec<u8>>>
pub fn get_unit_data(&self, unit_id: i32) -> Result<Option<Vec<u8>>>
Read opaque per-unit data, or None when IUnitData is absent/unsupported.
Sourcepub fn set_unit_data(&mut self, unit_id: i32, data: &[u8]) -> Result<()>
pub fn set_unit_data(&mut self, unit_id: i32, data: &[u8]) -> Result<()>
Restore opaque per-unit data through IUnitData.
Sourcepub fn begin_host_edit(&mut self, parameter_id: u32) -> Result<()>
pub fn begin_host_edit(&mut self, parameter_id: u32) -> Result<()>
Begin a controller-side host edit session for a parameter.
Sourcepub fn end_host_edit(&mut self, parameter_id: u32) -> Result<()>
pub fn end_host_edit(&mut self, parameter_id: u32) -> Result<()>
End a controller-side host edit session previously begun with Self::begin_host_edit.
Sourcepub fn send_midi_learn(
&mut self,
bus: i32,
channel: i16,
controller: u16,
) -> Result<()>
pub fn send_midi_learn( &mut self, bus: i32, channel: i16, controller: u16, ) -> Result<()>
Notify a controller implementing IMidiLearn of live MIDI-controller input.
Sourcepub fn set_automation_state(&mut self, state: AutomationState) -> Result<()>
pub fn set_automation_state(&mut self, state: AutomationState) -> Result<()>
Report the host’s automation mode to a controller implementing IAutomationState.
Sourcepub fn remap_parameter_id(
&self,
old_plugin_uid: &str,
old_param_id: u32,
) -> Result<Option<u32>>
pub fn remap_parameter_id( &self, old_plugin_uid: &str, old_param_id: u32, ) -> Result<Option<u32>>
Map a parameter id from an older/replaced plugin class through IRemapParamID.
old_plugin_uid must be the canonical separator-free 32-hex-character VST3 class id.
Returns None when the controller does not implement remapping or has no mapping for
this class/id pair. On Windows the canonical id is converted to COM-compatible byte
order before the controller is called. Works both in-process and across isolation.
Sourcepub fn latency_samples(&self) -> u32
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.
Sourcepub fn tail_samples(&self) -> u32
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.
Sourcepub fn midi_cc_to_parameter(
&self,
bus: i32,
channel: i16,
cc: u16,
) -> Option<u32>
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.
Sourcepub fn get_parameter(&self, id: u32) -> Result<f64>
pub fn get_parameter(&self, id: u32) -> Result<f64>
Get a parameter value by ID
Sourcepub fn format_parameter(&self, id: u32, normalized: f64) -> Result<String>
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.
Sourcepub fn set_parameter_by_name(&mut self, name: &str, value: f64) -> Result<()>
pub fn set_parameter_by_name(&mut self, name: &str, value: f64) -> Result<()>
Set a parameter by name
Sourcepub fn find_parameter(&self, name: &str) -> Result<Parameter>
pub fn find_parameter(&self, name: &str) -> Result<Parameter>
Find a parameter by name
Sourcepub fn send_midi_note(
&mut self,
note: u8,
velocity: u8,
channel: MidiChannel,
) -> Result<()>
pub fn send_midi_note( &mut self, note: u8, velocity: u8, channel: MidiChannel, ) -> Result<()>
Send a MIDI note on event
Sourcepub fn send_midi_note_off(
&mut self,
note: u8,
channel: MidiChannel,
) -> Result<()>
pub fn send_midi_note_off( &mut self, note: u8, channel: MidiChannel, ) -> Result<()>
Send a MIDI note off event
Sourcepub fn send_midi_cc(
&mut self,
controller: u8,
value: u8,
channel: MidiChannel,
) -> Result<()>
pub fn send_midi_cc( &mut self, controller: u8, value: u8, channel: MidiChannel, ) -> Result<()>
Send a MIDI control change event
Sourcepub fn send_midi_event(&mut self, event: MidiEvent) -> Result<()>
pub fn send_midi_event(&mut self, event: MidiEvent) -> Result<()>
Send a generic MIDI event.
Every data field is range-checked against the MIDI spec (0–127, or 0–16383 for
pitch bend) before the event reaches the plugin, the same way
send_midi_note and send_midi_cc
check theirs.
Sourcepub fn send_midi_event_at(
&mut self,
event: MidiEvent,
sample_offset: i32,
) -> Result<()>
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. The event’s data fields are
range-checked exactly as in send_midi_event.
Sourcepub fn send_plugin_event(&mut self, event: PluginEvent) -> Result<()>
pub fn send_plugin_event(&mut self, event: PluginEvent) -> Result<()>
Send a fully owned VST3 event.
This is the lossless event path for SysEx, note-expression text/integer values, chord,
and scale events. Pointer-backed data is owned by event and kept alive until the plugin
has consumed it.
Sourcepub fn send_sysex(&mut self, bytes: Vec<u8>) -> Result<()>
pub fn send_sysex(&mut self, bytes: Vec<u8>) -> Result<()>
Send MIDI SysEx bytes at block start.
Sourcepub fn send_sysex_at(
&mut self,
bytes: Vec<u8>,
sample_offset: i32,
) -> Result<()>
pub fn send_sysex_at( &mut self, bytes: Vec<u8>, sample_offset: i32, ) -> Result<()>
Send MIDI SysEx bytes at a sample offset within the next process block.
Sourcepub fn note_on(
&mut self,
channel: MidiChannel,
note: u8,
velocity: u8,
) -> Result<NoteId>
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.
note and velocity are range-checked (0–127), as in
send_midi_note.
Sourcepub fn note_on_at(
&mut self,
channel: MidiChannel,
note: u8,
velocity: u8,
sample_offset: i32,
) -> Result<NoteId>
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.
note and velocity must be 0–127, as for
send_midi_note.
Sourcepub fn note_off_at(&mut self, id: NoteId, sample_offset: i32) -> Result<()>
pub fn note_off_at(&mut self, id: NoteId, sample_offset: i32) -> Result<()>
note_off scheduled at a sample offset within the next block.
Sourcepub fn send_note_expression(
&mut self,
id: NoteId,
kind: NoteExpressionType,
value: f64,
) -> Result<()>
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).
Sourcepub fn send_note_expression_at(
&mut self,
id: NoteId,
kind: NoteExpressionType,
value: f64,
sample_offset: i32,
) -> Result<()>
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.
Sourcepub fn note_expressions(&self) -> Result<Vec<NoteExpressionInfo>>
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.
Sourcepub fn start_processing(&mut self) -> Result<()>
pub fn start_processing(&mut self) -> Result<()>
Start audio processing
Sourcepub fn stop_processing(&mut self) -> Result<()>
pub fn stop_processing(&mut self) -> Result<()>
Stop audio processing
Sourcepub fn process_audio(&mut self, buffers: &mut AudioBuffers) -> Result<()>
pub fn process_audio(&mut self, buffers: &mut AudioBuffers) -> Result<()>
Process audio buffers.
§Thread safety
Both playback paths call this from the audio thread, so any callback registered
with Self::on_audio_process runs there too — see that method’s warning.
Sourcepub fn audio_bus_layout(&self) -> Result<AudioBusLayout>
pub fn audio_bus_layout(&self) -> Result<AudioBusLayout>
Return every audio bus’s current channel count and activation state.
Sourcepub fn create_bus_audio_buffers(
&self,
block_size: usize,
) -> Result<BusAudioBuffers>
pub fn create_bus_audio_buffers( &self, block_size: usize, ) -> Result<BusAudioBuffers>
Allocate a bus-aware silent buffer set matching the plug-in’s current configuration.
Do this on the control thread when configuring an audio stream, then reuse the returned storage for every callback. If bus activation or arrangements change, query/create again.
Sourcepub fn process_bus_audio(&mut self, buffers: &mut BusAudioBuffers) -> Result<()>
pub fn process_bus_audio(&mut self, buffers: &mut BusAudioBuffers) -> Result<()>
Process audio without flattening VST3 bus boundaries.
The buffer set must contain every bus in index order, including inactive buses. Its
activation flags and channel counts are validated against the current component state.
Reuse a set created by Self::create_bus_audio_buffers for allocation-free in-process
steady-state processing.
Sourcepub fn get_output_levels(&self) -> AudioLevels
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.
Sourcepub fn is_processing(&self) -> bool
pub fn is_processing(&self) -> bool
Check if the plugin is currently processing
Sourcepub fn on_parameter_change<F>(&mut self, callback: F)
pub fn on_parameter_change<F>(&mut self, callback: F)
Set a callback invoked whenever Self::set_parameter succeeds, with the parameter id
and its new normalized value.
§This callback runs on the caller’s thread — including the audio thread
It fires inline from set_parameter, so it runs on whichever thread made that call.
Playback-ring automation uses a processor-only queue and does not invoke this callback
(or IEditController) on the audio thread.
Sourcepub fn on_audio_process<F>(&mut self, callback: F)
pub fn on_audio_process<F>(&mut self, callback: F)
Set a callback invoked after each Self::process_audio cycle with the freshly
computed output levels.
§This callback runs on the AUDIO thread
It fires from inside process_audio, which both playback paths call on the audio
callback thread, while the level mutex is held. Keep the body real-time safe — no
allocation, no locks, no I/O, no blocking on a UI thread. For metering in a UI, poll
Self::get_output_levels from the UI thread instead.
Sourcepub fn has_editor(&self) -> bool
pub fn has_editor(&self) -> bool
Check if the plugin has an editor GUI
Sourcepub fn open_editor(&mut self, parent: WindowHandle) -> Result<()>
pub fn open_editor(&mut self, parent: WindowHandle) -> Result<()>
Open the plugin editor window
Sourcepub fn service_run_loop(&mut self)
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.
Sourcepub fn close_editor(&mut self) -> Result<()>
pub fn close_editor(&mut self) -> Result<()>
Close the plugin editor window
Sourcepub fn get_editor_size(&self) -> Result<(i32, i32)>
pub fn get_editor_size(&self) -> Result<(i32, i32)>
Get the preferred editor size
Sourcepub fn editor_can_resize(&self) -> bool
pub fn editor_can_resize(&self) -> bool
Whether the plugin editor accepts host-driven resize requests.
With an editor open this reads the live view. With no editor open it has to create a throwaway view to ask, which costs on the order of milliseconds (~4.6 ms for Dexed) — cache the answer rather than calling it per UI frame.
Sourcepub fn resize_editor(&mut self, width: i32, height: i32) -> Result<(i32, i32)>
pub fn resize_editor(&mut self, width: i32, height: i32) -> Result<(i32, i32)>
Resize the open plugin editor, honoring the plugin’s size constraints.
Returns the size the plugin accepted, which may differ from the requested dimensions.
Sourcepub fn set_editor_scale_factor(&mut self, factor: f32) -> Result<bool>
pub fn set_editor_scale_factor(&mut self, factor: f32) -> Result<bool>
Communicate the editor’s logical-to-physical content scale.
Returns false when the editor does not implement VST3 content-scale support.
Sourcepub fn update_parameters<F>(&mut self, f: F) -> Result<()>
pub fn update_parameters<F>(&mut self, f: F) -> Result<()>
Collect several parameter changes with a ParameterUpdate and apply them in one call.
§This batch is not atomic
The queued changes are applied in the order they were set, and the first failure
stops the batch and is returned — the changes queued before it have already been
applied to the plugin and are not rolled back, and the ones after it were never
attempted. The error does not say how far the batch got. If that matters, call
Self::set_parameter per parameter and handle each result, or re-read the values
with Self::get_parameters after an error.
Sourcepub fn midi_panic(&mut self) -> Result<()>
pub fn midi_panic(&mut self) -> Result<()>
Send MIDI panic (all notes off, all sounds off, reset controllers)
Sourcepub fn get_parameter_changes(&self) -> Vec<(u32, f64)>
pub fn get_parameter_changes(&self) -> Vec<(u32, f64)>
Drain the parameter values that changed behind the host’s back, as
(parameter_id, normalized_value) pairs.
Two sources feed this: edits the plugin’s editor reported through
IComponentHandler::performEdit, and points the processor wrote into its
outputParameterChanges queue during process() (a compressor’s gain-reduction readout,
an internal LFO driving a visible control). Call it regularly — every UI frame — to keep
the host’s own display in step with the plugin.
Sourcepub fn take_parameter_edits(&mut self) -> Vec<ParameterEdit>
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 (BeginGesture … ValueChange* … 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.
Sourcepub fn take_host_notifications(&mut self) -> Vec<HostNotification>
pub fn take_host_notifications(&mut self) -> Vec<HostNotification>
Drain ordered requests the plugin reported through IComponentHandler2.
Sourcepub fn take_data_exchange_blocks(&mut self) -> Vec<DataExchangeBlock>
pub fn take_data_exchange_blocks(&mut self) -> Vec<DataExchangeBlock>
Dispatch and drain blocks sent through VST3’s IDataExchangeHandler.
Call this regularly on the plug-in’s control/UI thread. Queues whose controller requested background dispatch are delivered automatically, but their owned snapshots are drained here too. Storage is bounded; when the host-side snapshot sink is full, newer snapshots are dropped while controller delivery continues.
Execute a plugin context-menu entry previously received through
Self::take_host_notifications.
A popup can be completed once. Calling this invokes the plugin-provided
IContextMenuTarget on the plugin control/UI thread and releases all targets retained for
that popup.
Dismiss a pending plugin context menu and release its retained targets.
Sourcepub fn take_restart_flags(&mut self) -> RestartFlags
pub fn take_restart_flags(&mut self) -> RestartFlags
Take the flags the plugin raised via IComponentHandler::restartComponent since the
last call — its way of saying “something about me changed, re-read it”.
Poll this next to Self::take_parameter_edits (e.g. each UI frame). See
RestartFlags for what each one asks of the host. Returns an empty set for a plugin
that hasn’t raised anything. Works across process isolation.
Sourcepub fn service_host_requests(&mut self) -> Result<RestartFlags>
pub fn service_host_requests(&mut self) -> Result<RestartFlags>
Service pending restart requests on the caller’s control thread.
Latency and I/O requests are applied through the required stop/deactivate/reactivate
lifecycle. The returned flags still describe every request; in particular,
RestartFlags::reload_component means the caller must replace this plugin instance.
Sourcepub fn take_output_midi(&self) -> Vec<MidiEvent>
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.
Sourcepub fn take_output_events(&self) -> Vec<OutputEvent> ⓘ
pub fn take_output_events(&self) -> Vec<OutputEvent> ⓘ
Take every event the plugin has emitted, preserving SysEx and all VST3 event variants.
Sourcepub fn output_midi_handle(&self) -> Option<OutputMidiConsumer>
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.
Sourcepub fn output_event_handle(&self) -> Option<OutputEventConsumer>
pub fn output_event_handle(&self) -> Option<OutputEventConsumer>
Get a lock-free handle for draining all emitted VST3 events.
Sourcepub fn save_state(&self) -> Result<Vec<u8>>
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 blob is a versioned envelope holding the two streams VST3 defines — the component’s
state and, for a plugin whose controller is a separate object, the controller’s — not a
bare copy of either. Treat it as opaque and pair it with the plugin’s identity
(PluginInfo::uid); it only means something to the same plugin, and only
Self::load_state can unpack it. (Blobs written by older releases, which were the raw
component stream, still load.) Persist it to restore a patch later, or to snapshot a
session. Call this on the main thread (see the
threading model). For a blob other VST3 hosts can read,
use Self::save_vstpreset.
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.
Sourcepub fn load_state(&mut self, data: &[u8]) -> Result<()>
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.
The plugin is told this is a project/session restore (StateContext::Project). Use
Self::load_state_with_context when the bytes came from a preset file instead.
Sourcepub fn load_state_with_context(
&mut self,
data: &[u8],
context: &StateContext,
) -> Result<()>
pub fn load_state_with_context( &mut self, data: &[u8], context: &StateContext, ) -> Result<()>
Restore plugin state as Self::load_state does, and tell the plugin where the bytes
came from.
VST3 plugins can read the context off the stream they are given (the SDK’s
Vst::Helpers::isProjectState() does exactly that) and restore differently for a
session than for a preset. Self::load_vstpreset and Self::load_preset already
pass StateContext::Preset with the file they read; reach for this directly when
your host holds preset bytes it loaded some other way.
Works both in-process and across process isolation — an isolated plugin’s setState
sees the same attributes.
Sourcepub fn save_preset<P: AsRef<Path>>(&self, path: P) -> Result<()>
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.
Sourcepub fn load_preset<P: AsRef<Path>>(&mut self, path: P) -> Result<()>
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).
The plugin sees this as a preset load (StateContext::Preset) carrying path, not
as a session restore.
Sourcepub fn save_vstpreset<P: AsRef<Path>>(&self, path: P) -> Result<()>
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 component and optional controller streams from Self::save_state in "Comp" and
"Cont" chunks, 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.
Sourcepub fn load_vstpreset<P: AsRef<Path>>(&mut self, path: P) -> Result<()>
pub fn load_vstpreset<P: AsRef<Path>>(&mut self, path: P) -> Result<()>
Load a Steinberg .vstpreset file and apply its component and controller state.
Parses the .vstpreset container written by Self::save_vstpreset (or another VST3
host), extracts the "Comp" and optional "Cont" chunks and passes them 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.
The plugin is told this is a preset load (StateContext::Preset) and is given the
file’s full path, the way a DAW’s preset browser would — not the project-restore
context Self::load_state uses.
Sourcepub fn isolation_pid(&self) -> Option<u32>
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.
Sourcepub fn recovery_count(&self) -> u64
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.
Sourcepub fn output_channel_count(&self) -> usize
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.
Sourcepub fn take_editor_resize_request(&self) -> Option<(i32, i32)>
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.
Sourcepub fn recover(&mut self) -> Result<()>
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.