VOLTAreference

Reference / Connect and share

Export a patch as an instrument plugin

Connect and share

Open in the workbench →
On this page · 7 sections

Package a Volta patch as a CLAP instrument for use in another music application, within the supported export limits.

What you get#

volta export plugin examples/songs/aphelion.volta \
     --patch fogPad --name "Fog Pad" -o ~/plugins

→ ~/plugins/Fog Pad.clap, an instrument plugin that:

  • plays fogPad from host MIDI, note-on/note-off with the patch's own release (held notes, not fixed-length one-shots);
  • exposes every macro the patch reads as a CLAP parameter under its own name and declared range/unit (macro "cut" 800Hz → cut, 0–20000 Hz), plus a Level trim;
  • has its own plugin name and CLAP id (org.voltalang.patch.fog-pad), so ten exported patches are ten devices in the browser;
  • follows the host tempo for tempo-relative rates inside the patch;
  • carries its own source: Contents/Resources/patch.volta is the exact standalone module that was compiled in, so the plugin round-trips back into Volta (open it, edit it, re-export).

Install on macOS: cp -R "~/plugins/Fog Pad.clap" ~/Library/Audio/Plug-Ins/CLAP/.

The command#

volta export plugin <song.volta> [--patch <name>] -o <dir>
                    [--name "Display Name"] [--id <clap-id>]
                    [--no-build] [--debug] [--plugin-target <dir>]
flagmeaning
--patch <name>which patch to export. Optional when the song declares exactly one; otherwise the error lists the candidates.
-o / --outoutput directory (default .).
--namethe plugin's display name and bundle name. Default: the patch's binding name.
--idCLAP id. Default org.voltalang.patch.<slug of name>.
--no-buildstop after slicing: writes <slug>.volta (the standalone module) and the export spec, builds nothing. The fast way to see what would be exported.
--debugbuild the player in the dev profile — much faster, not for delivery.
--plugin-target <dir>where plugin-target/ lives. Default: $VOLTA_PLUGIN_TARGET, then the checkout this CLI was built from, then a walk up from the working directory.

Exporting builds a small crate (design doc §3 says why: nih-plug reads the plugin's identity from compile-time consts), so the machine doing the export needs a Volta checkout and cargo. Warm builds take ~10 s; the first one on a clean checkout compiles the engine. The artifact needs neither.

What gets sliced out#

The patch plus every local top-level binding it needs, transitively — the macro it reads, the helper that macro reads, the patch it extends with with — in buffer order. Tracks, songs and arrangements never come along. On top of that:

  • the song's tempo = declaration is carried even when the patch never names it (tempo-relative rates are a compile-time input);
  • an import line survives only if the closure uses one of its names, and the imported module's text travels with the export (into the spec and into Contents/Resources/<path>.volta).

The sliced module is compiled on its own before anything is built, so a bad slice is a CLI error with the compiler's own message, never a broken plugin.

Parameters#

ParamMeaning
<macro name>one float per declared macro, in declaration order, over its declared range with its unit as suffix, defaulting to its declared initial. A parameter drives its macro once it moves; untouched, the patch's own value and modulation graph stay authoritative. A value already off the default when the plugin loads (project recall) is written through at load.
Leveloutput trim, 0–2, smoothed.

Parameter ids are positional (m0, m1, …). Renaming a macro is safe; inserting a new macro before an existing one shifts the ids, so automation written against an older export moves. Export order = declaration order in the sliced module.

Limits (Stage 1)#

  • No sample bank. sample "…", bounceOf, convolve, wavetableOf and latentOf sources render silence in the exported plugin — the CLI warns at export time. (Design doc Stage 3.)
  • No plugin GUI — the host's generic parameter panel, with real names.
  • CLAP only (VST3 would make the artifact GPLv3 — Use Volta as a plugin §1).
  • One patch per export; the song's mixer/inserts/arrangement stay behind.
  • No pitch bend, poly pressure or CC — plain note-on/note-off, velocity.

Testing an export headlessly#

The player's own suite can be re-baked around a real export, which is the cheapest way to prove one before opening a DAW:

cd plugin-target
VOLTA_PATCH_SPEC=target/patch-export/<slug>/spec.json cargo test -p volta-patch-player

It asserts the embedded patch compiles, a note-on sounds, a note-off releases, and a macro write lands under its baked name. clap-validator validate "<Name>.clap" covers the CLAP layer (2026-08-12: 44 tests, 32 passed, 4 failed, 8 skipped — the state-reproducibility-* family, the same pre-existing param-layer issue Use Volta as a plugin records).

Where things live#

piecefile
island slice (closure + code-position scan)compiler/src/island.rs
the commandcli/src/pluginexport.rs
identity/source/param codegenplugin-target/patch-player/build.rs
audio thread + CLAP entryplugin-target/patch-player/src/lib.rs
control thread (compile, notes, macros)plugin-target/patch-player/src/control.rs
headless render suiteplugin-target/patch-player/tests/render.rs
export spec (schema volta.patch-plugin/1)plugin-target/target/patch-export/<slug>/spec.json