Shipping

Plugins

CLAP, VST3 and Audio Unit, from an object file and a header.

Anyone who wants the patch in a DAW.

A compiled patch is an object file with a C API, which is the shape a plugin wrapper wants. There is no Pole runtime for the plugin to carry and nothing for a user to install.

Patchwerk does this end to end — graph to CLAP, VST3, Audio Unit and a standalone app — and the DSP inside those plugins is Pole, compiled by --emit=export and linked into a shell.

What turns DSP into a plugin?#

A DAW does not load a raw DSP function. It loads a plugin bundle that implements its format's lifecycle: discover controls, prepare for a sample rate, process blocks, respond to automation and release resources. The shell translates those requests into calls to the generated Pole interface.

This means two pieces have different responsibilities. Your Pole code describes the sound. The shell describes how that sound lives inside a host application.

Follow one instance through its lifetime#

  1. Create: allocate the state and buffers described by the generated header. Each plugin instance needs independent state.
  2. Prepare: seed the state, bind external buffers, initialize parameter values and run any required init entry before audio processing.
  3. Process: map the host's audio, automation and events into the declared endpoints, then call the appropriate node or graph render interface.
  4. Reset or destroy: clear and reinitialize state when a reset is requested, or release host-owned resources when the instance is destroyed.

Use the host's actual sample rate. Hard-coding 48 kHz in a wrapper changes the meaning of rate-dependent code when the DAW runs at another rate.

External data is a separate asset#

A declared external buffer describes data the host supplies; its contents are not automatically embedded in the object file. A wavetable or sample-based plugin must package or locate its assets and bind them to the generated external entries before use.

For local execution, a node-qualified name such as --data=osc.wave=table.wav identifies an external inside a graph. That command line binding is different from arranging asset loading in a shipped plugin. The state chapter explains ownership and why a DSP reset need not unload a sample.

Check the exported instrument as a listener#

Test a fresh instance, a changed sample rate, a parameter sweep, a held note and its release, and a reset while a tail is active. An exported object can compile correctly while a shell still maps a gate to the wrong input or forgets to initialize a control. These checks exercise the contract between the two pieces.

Next: WebAssembly shows the corresponding compile, link and host steps for a browser.