Skip to main content

Module wrapper

Module wrapper 

Source
Expand description

Helpers shared across format wrappers (CLAP, VST3, VST2, AU, AAX, LV2).

Each wrapper still owns its format-specific descriptor types and callback tables; those don’t unify cleanly. What unifies is the “boring” boundary glue: building CStrings from ParamInfo fields, picking the default bus layout, and resolving install-time name overrides.

Each helper is a single small function so the wrappers stay greppable - the per-format vtable construction code reads as “for each param, get cstrings, build descriptor” without inlined CString::new(...).unwrap_or_default() boilerplate.

Adding a new format wrapper? Reach for these first; only fall back to direct CString::new etc. when the format genuinely needs something none of the other formats does.

Structs§

ParamCStrings
CStrings derived from a single ParamInfo. All four conversions follow the same pattern (unwrap_or_default() so a \0 in metadata degrades to an empty C string instead of panicking the host); pulling them into one struct keeps the per-format vtable loops uniform.
PluginCell
PluginGuard
Guard handing out the exclusive &mut T; releases the handoff on drop so the next owner’s Acquire sees this owner’s writes.

Functions§

default_io_channels
(input_channels, output_channels) for the plugin’s default bus layout, or None when the plugin declares no layouts. Used by every format’s vtable / descriptor to advertise channel counts at registration time.
enter_plugin
Take ownership of the plugin for the current callback. Never blocks: the audio thread owns the plugin while active, the host thread while inactive, and the host contract keeps the two from overlapping, so there is nothing to wait on. The returned guard’s &mut is exclusive by that contract; the Acquire inside observes the previous owner’s writes.
find_bus_layout
Find the bus_layouts() index whose total input/output channel counts match (inputs, outputs). Wrappers that negotiate a layout from a host-proposed arrangement (VST3 setBusArrangements, AU channel-config selection, the standalone device match, VST2’s fixed I/O at load) use this to map a request onto a supported layout. None when nothing matches; the caller then rejects the arrangement or falls back to the first layout.
first_bus_layout
Pick the plugin’s first bus layout, or None when the plugin declares no layouts. Used by wrappers (AAX, VST2) that need to read the layout before host-side bus-config negotiation, where a missing layout would otherwise produce silently-misreported channel counts.
log_midi_ports_clamped
Diagnostic for a plugin that declared more MIDI ports than the format can carry. The wrapper clamps to a single port and routes all traffic to port 0; without this line the truncation would read as “multi-port supported.” declared is the plugin’s per-direction port count; nothing is logged for the single-port (or zero-port) case. direction is "input" / "output".
log_missing_bus_layout
Standard diagnostic emitted by register_* when first_bus_layout or default_io_channels returns None. Centralised so every wrapper prints the same actionable message.
max_io_channels
(max_input_channels, max_output_channels) across every declared bus layout, or None when the plugin declares no layouts. Wrappers that let the host switch layouts at runtime (AU’s per-instance stream format) size their process-time scratch to this so a later, wider layout selection doesn’t outgrow buffers allocated for the first one.
run_audio_block
Run a per-block audio-thread body under std::panic::catch_unwind.
run_audio_block_with
Like run_audio_block but for callbacks that return a status code. Returns body’s value on a clean exit, fallback if the body panicked. Used by the CLAP wrapper, whose process callback returns a clap_process_status i32.
run_extern_callback_with
Run a generic extern "C" callback body under std::panic::catch_unwind. Returns body’s value on a clean exit, fallback if the body panicked.
run_register
Run a register_* body under std::panic::catch_unwind.
save_extra
Read the plugin’s custom-state blob for a host state save.
shared_plugin
Wrap a freshly created plugin in the wrapper-standard ownership cell. See SharedPlugin.

Type Aliases§

SharedPlugin
The ownership cell every format wrapper puts around its plugin instance. The audio thread owns the plugin while the host is processing (process, the queued state apply); the host thread owns it while processing is stopped (init, reset, an inactive state load). The host contract makes those two mutually exclusive in time - a spec-compliant host never overlaps process with a lifecycle callback - so PluginCell holds no OS lock and the audio thread never waits. Ownership handoff carries a release-acquire edge (each owner observes the previous owner’s writes), not mutual exclusion.