Anatomy of a plug-in
You write one AudioProcessor (the sound) and optionally one AudioProcessorEditor (the window). JUCE compiles a thin wrapper around them for each plug-in format, and the wrapper translates the host's calls into yours.
The moving parts
The build produces one shared-code static library containing your processor and editor. It then links that library into one small target per format (see Build systems).[1] This is why a JUCE plug-in project has targets like MyPlugin_VST3, MyPlugin_AU, and MyPlugin_Standalone.
The AudioProcessor contract
The method names and their purposes come from AudioProcessor.[2] The "Thread" column is this site's summary of common host behaviour; JUCE does not guarantee it, hence the footnote below the table.
| Method | Thread | Called when | Your job |
|---|---|---|---|
| constructor | message | the host instantiates the plug-in | declare buses (BusesProperties) and parameters |
prepareToPlay (sampleRate, maxBlockSize) | message* | before playback, or when the rate or block size changes | allocate buffers, reset filters |
processBlock (AudioBuffer&, MidiBuffer&) | audio | every block | read input, write output, consume and produce MIDI |
releaseResources() | message* | playback stops | free what prepareToPlay allocated |
isBusesLayoutSupported() | message* | the host proposes a channel layout | accept or reject mono, stereo, surround… |
getStateInformation (MemoryBlock&) | message* | the host saves a project or preset | serialise your state (usually the APVTS ValueTree) |
setStateInformation (data, size) | message* | the host loads a project or preset | restore it |
createEditor() / hasEditor() | message | the user opens the plug-in window | return a new editor |
getName(), acceptsMidi(), getTailLengthSeconds() … | any | the host asks | describe the plug-in |
* Usually the message thread, but hosts vary. Treat these as "not the audio thread, but not guaranteed to be the GUI thread either". This is a cautious reading, not a documented guarantee.
A plug-in's life, from the host's point of view
The editor is disposable. Hosts open and close the window at will, and some never open it. All state must live in the processor; the editor only displays and edits it.
Parameters
Parameters are how the host sees your plug-in's controls: for automation lanes, generic UIs, and control surfaces.
- Each is a subclass of
AudioProcessorParameter: usuallyAudioParameterFloat,AudioParameterInt,AudioParameterBool, orAudioParameterChoice(allRangedAudioParameters). - Most plug-ins create them through
AudioProcessorValueTreeState, then bind editor widgets with attachments. - The audio thread reads the current value via
getRawParameterValue()(anstd::atomic<float>*)[3] or directly from the parameter object. - Parameter IDs are part of your saved-state format and automation data. Never rename them after release. A
ParameterIDalso carries aversionHint, which keeps Audio Unit parameter ordering backwards-compatible in Logic and GarageBand when you add parameters in a later release.[4]
Buses and channels
A bus is a group of channels, such as a stereo main input, a mono side-chain, or a 5.1 output. You declare buses in the constructor with BusesProperties. The host negotiates the actual layout via isBusesLayoutSupported(). In processBlock(), the single AudioBuffer holds every channel of every bus; use getBusBuffer() to get the slice for one bus.
Formats at a glance
| Format | Owner | Platforms | Notes |
|---|---|---|---|
| VST3 | Steinberg | macOS, Windows, Linux[5] | SDK bundled with JUCE[6] |
| AU (Audio Unit v2) | Apple | macOS[1:1] | JUCE's docs mention Logic and GarageBand AU compatibility[4:1] |
| AUv3 | Apple | macOS, iOS | App extension. Built only with the Xcode generator[1:2] |
| AAX | Avid | macOS, Windows | Pro Tools; commercially available Pro Tools needs PACE-signed plug-ins[7] |
| LV2 | Open standard | not checked | Authoring and hosting added in JUCE 7[8] |
| Standalone | JUCE | desktop | Your plug-in in its own app window (StandalonePluginHolder)[9] |
| Unity | Unity | not checked | Native audio plug-in for the Unity game engine[10] |
| VST (VST2) | Steinberg | — | Legacy. Steinberg discontinued VST 2[11]; JUCE needs you to supply the SDK path |
Platforms marked "not checked", and the owner column generally, come from common knowledge of each format rather than a source in this repository.
Hosting other plug-ins
The same abstractions work in reverse. AudioPluginFormatManager knows the formats. KnownPluginList and PluginListComponent scan for and list installed plug-ins, and createPluginInstance() gives you an AudioPluginInstance (an AudioProcessor). You can then put it in an AudioProcessorGraph. extras/AudioPluginHost is a complete working example.[12]
Try it
- Build
examples/CMake/AudioPlugin(see Learning path). - Open the Standalone target, then load the VST3 into
AudioPluginHost. - Put a breakpoint in
prepareToPlay()andprocessBlock()and watch the order of calls.
Sources
docs/CMake API.md,FORMATS: valid valuesStandalone Unity VST3 AU AUv3 AAX VST LV2; "AUandAUv3plugins will only be enabled when building on macOS;AUv3plugins will only be enabled when using the Xcode generator"; one target per format, for exampleMyPlugin_VST3. ↩︎ ↩︎ ↩︎juce_AudioProcessor.h:prepareToPlay,processBlock,releaseResources,createEditor,getTailLengthSeconds,getBusBuffer, and thewrapperType_*enum (VST, VST3, AudioUnit, AudioUnitv3, AAX, Standalone, Unity, LV2). ↩︎juce_AudioProcessorParameterWithID.h:versionHint"Influences parameter ordering in Audio Unit plugins. Used to provide backwards compatibility of Audio Unit plugins in Logic and GarageBand." ↩︎ ↩︎CHANGE_LIST.md, Version 6.0.0: "Added VST3 support on Linux";README.mddeployment targets list macOS, Windows, and Linux. ↩︎CHANGE_LIST.md, Version 8.0.11: "Updated the VST3 SDK to 3.8.0 (MIT license)"; JUCE 8.0.0: "Bundled the AAX SDK". See also the SPDX bill of materials. ↩︎README.md, "AAX Plug-Ins": AAX plug-ins must be signed with PACE tools "before they will run in commercially available versions of Pro Tools". Avid as the owner of AAX is named in the same section. ↩︎CHANGE_LIST.md, Version 7.0.0: "Added support for authoring and hosting LV2 plug-ins". ↩︎CHANGE_LIST.mdmentions "Unity native plug-in support" (Version 5.4.0); the Unity wrapper type is injuce_AudioProcessor.h. That Unity is a game engine is general knowledge. ↩︎VST 2 Discontinued, Steinberg Help Center; Steinberg closing down VST2 for good, JUCE Forum; the
juce_set_vst2_sdk_pathrequirement is indocs/CMake API.md. Retrieved 2026-09-29 from search-result summaries; the Steinberg page itself was not opened. ↩︎extras/AudioPluginHost; the scanning and format classes are injuce_KnownPluginList.handjuce_PluginListComponent.h. ↩︎