pub trait Plugin: HasParameters + Default {
type Config: ProcessorConfig;
type Processor: AudioProcessor<Plugin = Self, Parameters = Self::Parameters>;
Show 22 methods
// Required method
fn prepare(self, config: Self::Config) -> Self::Processor;
// Provided methods
fn input_bus_count(&self) -> usize { ... }
fn output_bus_count(&self) -> usize { ... }
fn input_bus_info(&self, index: usize) -> Option<BusInfo> { ... }
fn output_bus_info(&self, index: usize) -> Option<BusInfo> { ... }
fn wants_midi(&self) -> bool { ... }
fn midi_cc_to_parameter(
&self,
bus_index: i32,
channel: i16,
cc: u8,
) -> Option<u32> { ... }
fn midi_cc_config(&self) -> Option<MidiCcConfig> { ... }
fn on_midi_learn(&mut self, bus_index: i32, channel: i16, cc: u8) -> bool { ... }
fn midi1_assignments(&self) -> &[Midi1Assignment] { ... }
fn midi2_assignments(&self) -> &[Midi2Assignment] { ... }
fn on_midi1_learn(&mut self, bus_index: i32, channel: u8, cc: u8) -> bool { ... }
fn on_midi2_learn(
&mut self,
bus_index: i32,
channel: u8,
controller: Midi2Controller,
) -> bool { ... }
fn note_expression_count(&self, bus_index: i32, channel: i16) -> usize { ... }
fn note_expression_info(
&self,
bus_index: i32,
channel: i16,
index: usize,
) -> Option<NoteExpressionTypeInfo> { ... }
fn note_expression_value_to_string(
&self,
bus_index: i32,
channel: i16,
type_id: u32,
value: f64,
) -> String { ... }
fn note_expression_string_to_value(
&self,
bus_index: i32,
channel: i16,
type_id: u32,
string: &str,
) -> Option<f64> { ... }
fn keyswitch_count(&self, bus_index: i32, channel: i16) -> usize { ... }
fn keyswitch_info(
&self,
bus_index: i32,
channel: i16,
index: usize,
) -> Option<KeyswitchInfo> { ... }
fn physical_ui_mappings(
&self,
bus_index: i32,
channel: i16,
) -> &[PhysicalUIMap] { ... }
fn enable_mpe_input_processing(&mut self, enabled: bool) -> bool { ... }
fn set_mpe_input_device_settings(
&mut self,
settings: MpeInputDeviceSettings,
) -> bool { ... }
}Expand description
The unprepared plugin - holds parameters before audio config is known.
This is the primary trait that plugin authors implement to create a complete
audio plugin. It holds parameters and configuration that doesn’t depend on
sample rate, and transforms into an AudioProcessor via Plugin::prepare()
when audio configuration becomes available.
§Two-Phase Lifecycle
Plugin::default() -> Plugin (unprepared, holds parameters)
|
v Plugin::prepare(config)
|
v
AudioProcessor (prepared, ready for audio)
|
v AudioProcessor::unprepare()
|
v
Plugin (unprepared, parameters preserved)§Example: Simple Gain (NoConfig)
#[derive(Default, HasParameters)]
pub struct GainPlugin {
#[parameters]
parameters: GainParameters,
}
impl Plugin for GainPlugin {
type Config = NoConfig;
type Processor = GainProcessor;
fn prepare(self, _: NoConfig) -> GainProcessor {
GainProcessor { parameters: self.parameters }
}
}
#[derive(HasParameters)]
pub struct GainProcessor {
#[parameters]
parameters: GainParameters,
}
impl AudioProcessor for GainProcessor {
type Plugin = GainPlugin;
fn process(&mut self, buffer: &mut Buffer, _aux: &mut AuxiliaryBuffers, _context: &ProcessContext) {
let gain = self.parameters.gain_linear();
for (input, output) in buffer.zip_channels() {
for (i, o) in input.iter().zip(output.iter_mut()) {
*o = *i * gain;
}
}
}
fn unprepare(self) -> GainPlugin {
GainPlugin { parameters: self.parameters }
}
}§Example: Delay (AudioSetup)
#[derive(Default, HasParameters)]
pub struct DelayPlugin {
#[parameters]
parameters: DelayParameters,
}
impl Plugin for DelayPlugin {
type Config = AudioSetup;
type Processor = DelayProcessor;
fn prepare(self, config: AudioSetup) -> DelayProcessor {
let buffer_size = (MAX_DELAY_SECONDS * config.sample_rate) as usize;
DelayProcessor {
parameters: self.parameters,
sample_rate: config.sample_rate, // Real value from start!
buffer: vec![0.0; buffer_size], // Correct allocation!
}
}
}§Note on HasParameters
The Plugin trait requires HasParameters as a supertrait, which provides the
parameters() and parameters_mut() methods. Use #[derive(HasParameters)] with a
#[parameters] field annotation to implement this automatically.
Required Associated Types§
Sourcetype Config: ProcessorConfig
type Config: ProcessorConfig
The configuration type this plugin needs to prepare.
NoConfig: For plugins that don’t need sample rate (simple gain)AudioSetup: For plugins that need sample rate and max buffer sizeFullAudioSetup: For plugins that also need bus layout information
Sourcetype Processor: AudioProcessor<Plugin = Self, Parameters = Self::Parameters>
type Processor: AudioProcessor<Plugin = Self, Parameters = Self::Parameters>
The prepared processor type created by Plugin::prepare().
Required Methods§
Sourcefn prepare(self, config: Self::Config) -> Self::Processor
fn prepare(self, config: Self::Config) -> Self::Processor
Transform this plugin into a prepared processor.
This is called when audio configuration becomes available (in VST3,
during setupProcessing()). The plugin is consumed and transformed
into a processor with valid configuration - no placeholder values.
§Arguments
config- The audio configuration (sample rate, buffer size, layout)
§Returns
A prepared processor ready for audio processing.
Provided Methods§
Sourcefn input_bus_count(&self) -> usize
fn input_bus_count(&self) -> usize
Returns the number of audio input buses.
Default returns 1 (single stereo input).
Sourcefn output_bus_count(&self) -> usize
fn output_bus_count(&self) -> usize
Returns the number of audio output buses.
Default returns 1 (single stereo output).
Sourcefn input_bus_info(&self, index: usize) -> Option<BusInfo>
fn input_bus_info(&self, index: usize) -> Option<BusInfo>
Returns information about an input bus.
Default returns a stereo main bus for index 0.
Sourcefn output_bus_info(&self, index: usize) -> Option<BusInfo>
fn output_bus_info(&self, index: usize) -> Option<BusInfo>
Returns information about an output bus.
Default returns a stereo main bus for index 0.
Sourcefn wants_midi(&self) -> bool
fn wants_midi(&self) -> bool
Returns whether this plugin processes MIDI events.
Override to return true if your plugin needs MIDI input/output.
This is used by the host to determine event bus configuration.
Note: This method is also on AudioProcessor, but the Plugin
version is queried during bus configuration (before prepare).
Both should return the same value.
Default returns false.
Sourcefn midi_cc_to_parameter(
&self,
bus_index: i32,
channel: i16,
cc: u8,
) -> Option<u32>
fn midi_cc_to_parameter( &self, bus_index: i32, channel: i16, cc: u8, ) -> Option<u32>
Get the parameter ID mapped to a MIDI CC.
Override this to enable DAW MIDI learn for your parameters. When the DAW queries which parameter is assigned to a MIDI CC, this method is called.
§Arguments
bus_index- MIDI bus index (usually 0)channel- MIDI channel (0-15), or -1 to query all channelscc- MIDI CC number (0-127)
§Returns
Some(parameter_id) if this CC is mapped to a parameter, None otherwise.
§Example
fn midi_cc_to_parameter(&self, _bus: i32, _channel: i16, cc: u8) -> Option<u32> {
match cc {
cc::MOD_WHEEL => Some(PARAM_VIBRATO_DEPTH),
cc::EXPRESSION => Some(PARAM_VOLUME),
_ => None,
}
}Sourcefn midi_cc_config(&self) -> Option<MidiCcConfig>
fn midi_cc_config(&self) -> Option<MidiCcConfig>
Returns MIDI CC configuration for automatic host mapping.
Override to enable MIDI CC/pitch bend/aftertouch reception via IMidiMapping. The framework will:
- Create hidden parameters for each enabled controller
- Handle IMidiMapping queries from the DAW
- Convert parameter changes to MidiEvents in process_midi()
- Provide direct CC value access via ProcessContext::midi_cc()
This solves the VST3 MIDI input problem where most DAWs don’t send
kLegacyMIDICCOutEvent for input. Instead, they use the IMidiMapping
interface to map MIDI controllers to parameters.
§Example
impl Plugin for MySynth {
fn midi_cc_config(&self) -> Option<MidiCcConfig> {
Some(MidiCcConfig::new()
.with_pitch_bend()
.with_mod_wheel()
.with_aftertouch()
.with_ccs(&[7, 10, 11, 64])) // Volume, Pan, Expression, Sustain
}
}
// Access CC values during processing:
fn process(&mut self, buffer: &mut Buffer, _aux: &mut AuxiliaryBuffers, context: &ProcessContext) {
if let Some(cc) = context.midi_cc() {
let pitch_bend = cc.pitch_bend(); // -1.0 to 1.0
let mod_wheel = cc.mod_wheel(); // 0.0 to 1.0
}
}Sourcefn on_midi_learn(&mut self, bus_index: i32, channel: i16, cc: u8) -> bool
fn on_midi_learn(&mut self, bus_index: i32, channel: i16, cc: u8) -> bool
Called by DAW when live MIDI CC input is received during learn mode.
Override this to implement MIDI learn in your plugin UI. When the user enables “MIDI Learn” mode and moves a MIDI CC knob, the DAW calls this method so the plugin can map that CC to a parameter.
§Arguments
bus_index- MIDI bus index (usually 0)channel- MIDI channel (0-15)cc- MIDI CC number that was moved
§Returns
true if the input was handled (learned), false otherwise.
Sourcefn midi1_assignments(&self) -> &[Midi1Assignment]
fn midi1_assignments(&self) -> &[Midi1Assignment]
Get all MIDI 1.0 CC assignments for bulk query.
Override to provide mappings for DAW queries. This is more efficient
than individual midi_cc_to_parameter queries when there are many mappings.
Default returns empty slice (no mappings).
Sourcefn midi2_assignments(&self) -> &[Midi2Assignment]
fn midi2_assignments(&self) -> &[Midi2Assignment]
Get all MIDI 2.0 controller assignments for bulk query.
Override to provide MIDI 2.0 Registered/Assignable controller mappings.
Default returns empty slice (no mappings).
Sourcefn on_midi1_learn(&mut self, bus_index: i32, channel: u8, cc: u8) -> bool
fn on_midi1_learn(&mut self, bus_index: i32, channel: u8, cc: u8) -> bool
Called when MIDI 1.0 CC input is received during learn mode.
This is the MIDI 2.0 version of on_midi_learn with separate methods
for MIDI 1.0 and MIDI 2.0 controllers.
Default returns false (not handled).
Sourcefn on_midi2_learn(
&mut self,
bus_index: i32,
channel: u8,
controller: Midi2Controller,
) -> bool
fn on_midi2_learn( &mut self, bus_index: i32, channel: u8, controller: Midi2Controller, ) -> bool
Called when MIDI 2.0 controller input is received during learn mode.
Override to implement MIDI 2.0 controller learning.
Default returns false (not handled).
Sourcefn note_expression_count(&self, bus_index: i32, channel: i16) -> usize
fn note_expression_count(&self, bus_index: i32, channel: i16) -> usize
Returns the number of supported note expression types.
Override to advertise which note expressions your plugin supports (e.g., volume, pan, tuning for MPE instruments).
Default returns 0 (no note expressions).
Sourcefn note_expression_info(
&self,
bus_index: i32,
channel: i16,
index: usize,
) -> Option<NoteExpressionTypeInfo>
fn note_expression_info( &self, bus_index: i32, channel: i16, index: usize, ) -> Option<NoteExpressionTypeInfo>
Returns information about a note expression type by index.
Override to provide details about each supported expression type.
Default returns None.
Sourcefn note_expression_value_to_string(
&self,
bus_index: i32,
channel: i16,
type_id: u32,
value: f64,
) -> String
fn note_expression_value_to_string( &self, bus_index: i32, channel: i16, type_id: u32, value: f64, ) -> String
Converts a normalized note expression value to a display string.
Override to provide custom formatting (e.g., “2.5 semitones” for tuning).
Default returns the value as a percentage.
Sourcefn note_expression_string_to_value(
&self,
bus_index: i32,
channel: i16,
type_id: u32,
string: &str,
) -> Option<f64>
fn note_expression_string_to_value( &self, bus_index: i32, channel: i16, type_id: u32, string: &str, ) -> Option<f64>
Parses a string to a normalized note expression value.
Override to support custom parsing.
Default returns None (parsing not supported).
Sourcefn keyswitch_count(&self, bus_index: i32, channel: i16) -> usize
fn keyswitch_count(&self, bus_index: i32, channel: i16) -> usize
Returns the number of keyswitches (articulations).
Override for sample libraries and orchestral instruments that support keyswitching between articulations.
Default returns 0 (no keyswitches).
Sourcefn keyswitch_info(
&self,
bus_index: i32,
channel: i16,
index: usize,
) -> Option<KeyswitchInfo>
fn keyswitch_info( &self, bus_index: i32, channel: i16, index: usize, ) -> Option<KeyswitchInfo>
Returns information about a keyswitch by index.
Override to provide keyswitch details for DAW expression maps.
Default returns None.
Sourcefn physical_ui_mappings(&self, bus_index: i32, channel: i16) -> &[PhysicalUIMap]
fn physical_ui_mappings(&self, bus_index: i32, channel: i16) -> &[PhysicalUIMap]
Returns mappings from physical UI controllers to note expressions.
Override to define how MPE controllers (X-axis, Y-axis, Pressure) map to your plugin’s note expression types.
§Example
fn physical_ui_mappings(&self, _bus: i32, _channel: i16) -> &[PhysicalUIMap] {
&[
PhysicalUIMap::y_axis(note_expression::BRIGHTNESS),
PhysicalUIMap::pressure(note_expression::EXPRESSION),
]
}Default returns empty slice (no mappings).
Sourcefn enable_mpe_input_processing(&mut self, enabled: bool) -> bool
fn enable_mpe_input_processing(&mut self, enabled: bool) -> bool
Called to enable or disable MPE input processing.
Override to handle MPE enable/disable notifications from wrappers.
Default does nothing and returns true.
Sourcefn set_mpe_input_device_settings(
&mut self,
settings: MpeInputDeviceSettings,
) -> bool
fn set_mpe_input_device_settings( &mut self, settings: MpeInputDeviceSettings, ) -> bool
Called when the MPE input device settings change.
Override to receive MPE zone configuration from wrappers.
Default does nothing and returns true.
Dyn Compatibility§
This trait is not dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety", so this trait is not object safe.