Skip to main content

Plugin

Trait Plugin 

Source
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§

Source

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§

Source

fn info() -> PluginInfo
where Self: Sized,

Static metadata about the plugin.

Use plugin_info!() for zero-boilerplate (reads from truce.toml

  • Cargo.toml at compile time - no build.rs required).
Source

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.

Source

fn process( &mut self, buffer: &mut AudioBuffer<'_, Self::Sample>, events: &EventList, context: &mut ProcessContext<'_>, ) -> ProcessStatus

Real-time audio processing.

Provided Methods§

Source

fn supports_in_place() -> bool
where 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.

Source

fn bus_layouts() -> Vec<BusLayout>
where Self: Sized,

Supported bus layouts. The host picks one.

Source

fn init(&mut self)

Called once after construction. Not real-time safe.

Source

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.

Source

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).

Source

fn editor(&mut self) -> Option<Box<dyn Editor>>

GUI editor. Return None for headless plugins.

Source

fn latency(&self) -> u32

Processing latency in samples. Host uses this for delay compensation. Return 0 if the plugin adds no latency (default).

Source

fn tail(&self) -> u32

Tail time in samples. Return u32::MAX for infinite tail. Return 0 for no tail (default).

Source

fn get_meter(&self, _meter_id: u32) -> f32

Read a meter value by ID (0.0–1.0). Called by the GUI at ~60fps. Override to expose level meters, gain reduction, etc.

Implementors§