pub trait Plugin: Send + 'static {
type Sample: Sample;
// Required methods
fn info() -> PluginInfo
where Self: Sized;
fn reset(&mut self, sample_rate: f64, max_block_size: usize);
fn process(
&mut self,
buffer: &mut AudioBuffer<'_, Self::Sample>,
events: &EventList,
context: &mut ProcessContext<'_>,
) -> ProcessStatus;
// Provided methods
fn supports_in_place() -> bool
where Self: Sized { ... }
fn bus_layouts() -> Vec<BusLayout>
where Self: Sized { ... }
fn init(&mut self) { ... }
fn save_state(&self) -> Vec<u8> ⓘ { ... }
fn load_state(&mut self, _data: &[u8]) -> Result<(), StateLoadError> { ... }
fn editor(&mut self) -> Option<Box<dyn Editor>> { ... }
fn latency(&self) -> u32 { ... }
fn tail(&self) -> u32 { ... }
fn get_meter(&self, _meter_id: u32) -> f32 { ... }
}Expand description
The format-facing plugin trait. Plugin authors do NOT implement this directly.
Plugin is the surface every format wrapper (CLAP, VST3, VST2,
LV2, AU, AAX) consumes. The truce::plugin! macro generates an
impl Plugin for __HotShellWrapper from the user’s
truce_plugin::PluginLogic impl, bridging the GUI-aware user
trait into this GUI-free format-wrapper surface so truce-core
doesn’t pull in truce-gui types.
What plugin authors implement instead:
impl truce::prelude::PluginLogic for MyPlugin {
fn reset(&mut self, sr: f64, bs: usize) { /* ... */ }
fn process(&mut self, /* ... */) -> ProcessStatus { /* ... */ }
fn layout(&self) -> GridLayout { /* ... */ }
}
truce::plugin! { logic: MyPlugin, params: MyPluginParams }The macro-emitted impl Plugin routes each method directly to the
user’s impl, except editor() which the macro builds from the
user’s custom_editor (preferred) or layout (built-in fallback).
Required Associated Types§
Sourcetype Sample: Sample
type Sample: Sample
The plugin’s chosen audio sample precision. Either f32 (the
default - matches host wire format for nearly all formats) or
f64 (for plugins whose DSP path runs in f64 end-to-end:
high-order biquads, oscillator phase accumulators, long-running
cumulative state).
The format wrapper bridges between host buffer precision and
Self::Sample at the block boundary - so the plugin’s
process() always receives AudioBuffer<Self::Sample>
regardless of what the host sent. See
truce_core::RawBufferScratch for the conversion machinery.
Drive this from the prelude: truce::prelude / truce::prelude32
implies f32, truce::prelude64 implies f64. The
truce::plugin! macro emits type Sample = …; based on
which prelude is in scope at the macro call site.
Required Methods§
Sourcefn info() -> PluginInfowhere
Self: Sized,
fn info() -> PluginInfowhere
Self: Sized,
Static metadata about the plugin.
Use plugin_info!() for zero-boilerplate (reads from truce.toml
- Cargo.toml at compile time - no
build.rsrequired).
Sourcefn reset(&mut self, sample_rate: f64, max_block_size: usize)
fn reset(&mut self, sample_rate: f64, max_block_size: usize)
Called when sample rate or max block size changes. Reset filters, delay lines, etc. Not real-time safe.
Sourcefn process(
&mut self,
buffer: &mut AudioBuffer<'_, Self::Sample>,
events: &EventList,
context: &mut ProcessContext<'_>,
) -> ProcessStatus
fn process( &mut self, buffer: &mut AudioBuffer<'_, Self::Sample>, events: &EventList, context: &mut ProcessContext<'_>, ) -> ProcessStatus
Real-time audio processing.
Provided Methods§
Sourcefn supports_in_place() -> boolwhere
Self: Sized,
fn supports_in_place() -> boolwhere
Self: Sized,
Opt into zero-copy in-place I/O. When this returns true,
the format wrapper skips its safety memcpy on host-aliased
buffers and hands the plugin the raw shared memory through
AudioBuffer::in_out_mut(ch). The plugin must check
AudioBuffer::is_in_place(ch) per channel before reading
input(ch) - for in-place channels input(ch) returns an
empty slice, and the data lives only in the shared buffer.
Default false: the wrapper copies aliased inputs into scratch
so input(ch) and output(ch) are always disjoint. Costs one
memcpy per aliased channel per block (a few hundred KB/sec at
audio rates) and lets plugin code stay format-agnostic.
where Self: Sized so a dyn Plugin trait object stays
dyn-compatible - the format wrappers consume P: Plugin
generically and call the method statically.
Sourcefn bus_layouts() -> Vec<BusLayout>where
Self: Sized,
fn bus_layouts() -> Vec<BusLayout>where
Self: Sized,
Supported bus layouts. The host picks one.
Sourcefn save_state(&self) -> Vec<u8> ⓘ
fn save_state(&self) -> Vec<u8> ⓘ
Save extra state beyond parameter values. Empty Vec means
“no extra state”: matches the user-facing
truce_plugin::PluginLogic::save_state shape so the wrapper
bridge is a passthrough rather than an Option<Vec<u8>> to
Vec<u8> translation.
Sourcefn load_state(&mut self, _data: &[u8]) -> Result<(), StateLoadError>
fn load_state(&mut self, _data: &[u8]) -> Result<(), StateLoadError>
Restore extra state. Matches the user-facing
truce_plugin::PluginLogic::load_state Result shape so the
wrapper bridge is a passthrough.
§Errors
Returns Err when the macro-generated impl forwards a
PluginLogic::load_state failure (malformed bytes, version
skew between session file and plugin build, etc).
Sourcefn latency(&self) -> u32
fn latency(&self) -> u32
Processing latency in samples. Host uses this for delay compensation. Return 0 if the plugin adds no latency (default).
Dyn Compatibility§
This trait is dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety".