Skip to content
Back to skills

Yup Guide

ASecurity

Step-by-step guide for building a YUP audio plugin from scratch. Use when the user asks "how do I create a YUP plugin", "set up a YUP project", "add parameters to my YUP plugin", "package my CLAP or VST3", or "how do I wire up AudioParameterHandle". Trigger on phrases like "create a YUP plugin", "YUP CMake setup", "yup_audio_plugin", "AudioParameterBuilder", "AudioParameterHandle", or "createPluginProcessor".

  • 18 stars
  • 0 votes
  • 0 copies
  • 3 views
  • Added May 26, 2026
developmentgit

Security analysis

A100/100

Scanned May 27, 2026

npx -y skills add kunitoki/sonic-skills --skill yup-guide --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Yup Guide?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Yup Guide
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/kunitoki-yup-guide/badge)](https://www.skillsdirectory.com/skills/kunitoki-yup-guide)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: yup-guide
description: >
  Step-by-step guide for building a YUP audio plugin from scratch. Use when the user
  asks "how do I create a YUP plugin", "set up a YUP project", "add parameters to my
  YUP plugin", "package my CLAP or VST3", or "how do I wire up AudioParameterHandle".
  Trigger on phrases like "create a YUP plugin", "YUP CMake setup", "yup_audio_plugin",
  "AudioParameterBuilder", "AudioParameterHandle", or "createPluginProcessor".
---

# YUP Audio Plugin - Build Guide

Five steps from empty folder to a working CLAP/VST3/standalone plugin. Do each step in order; skip none.

## Step 1 - Project setup (CMake + YUP)

- Add YUP as a git submodule or `FetchContent` target; disable examples/tests for plugin projects unless needed.
- Use `yup_audio_plugin (...)` to declare the plugin target.
- Set `TARGET_NAME`, `TARGET_VERSION`, `TARGET_APP_ID`, `TARGET_APP_NAMESPACE`, and `TARGET_CXX_STANDARD 20`.
- Set plugin metadata in the same call: `PLUGIN_ID`, `PLUGIN_NAME`, `PLUGIN_VENDOR`, `PLUGIN_VERSION`, `PLUGIN_DESCRIPTION`, `PLUGIN_IS_SYNTH`, and `PLUGIN_IS_MONO`.
- Enable only the formats you need: `PLUGIN_CREATE_CLAP`, `PLUGIN_CREATE_VST3`, `PLUGIN_CREATE_STANDALONE`.
- Link at least `yup::yup_gui` and `yup::yup_audio_processors` in `MODULES`.
- Add plugin sources to `${target_name}_shared`; the format targets link against that shared interface target.

## Step 2 - AudioProcessor skeleton

- Subclass `yup::AudioProcessor`.
- Construct it with a processor name and immutable `yup::AudioBusLayout`, e.g. stereo output:
  `AudioProcessor ("MyPlugin", yup::AudioBusLayout ({}, { yup::AudioBus ("main", yup::AudioBus::Audio, yup::AudioBus::Output, 2) }))`.
- Override `prepareToPlay (float sampleRate, int maxBlockSize)`, `releaseResources()`, `processBlock (yup::AudioSampleBuffer& audioBuffer, yup::MidiBuffer& midiBuffer)`, and `flush()`.
- In `prepareToPlay`: store sample rate, allocate worst-case scratch storage, initialise `AudioParameterHandle`s, and reset all filters, envelopes, oscillators, delay lines, MIDI/voice state, and smoothers.
- In `processBlock`: assume realtime constraints; no allocation, locks, `yup::String` formatting, logging, file/network access, or UI calls.
- Implement preset and state methods: `getCurrentPreset`, `setCurrentPreset`, `getNumPresets`, `getPresetName`, `setPresetName`, `loadStateFromMemory`, and `saveStateIntoMemory`.
- Export the plugin entry point:

```cpp
extern "C" yup::AudioProcessor* createPluginProcessor()
{
    return new MyPluginProcessor();
}
```

## Step 3 - Parameters via AudioParameterBuilder

- Add parameters in the processor constructor with `addParameter (...)`.
- Keep each `yup::AudioParameter::Ptr` as a processor member; parameter IDs must be stable and unique.
- Use `yup::AudioParameterBuilder().withID (...).withName (...).withRange (...).withDefault (...).withSmoothing (...).build()`.
- For audio-thread reads, construct a `yup::AudioParameterHandle` in `prepareToPlay` with the parameter and sample rate.
- In `processBlock`, call `handle.updateNextAudioBlock()` once per block, then use `getNextValue()` per sample or `skip (numSamples)` for block ramps.
- From the editor, wrap user drags with `beginChangeGesture()` and `endChangeGesture()`, and use `setValueNotifyingHost()` for host-visible parameter changes.
- For presets or state restore, prefer setting the real value with `setValue()` or `setNormalizedValue()` from a non-audio thread, then let the audio handle pick it up next block.

## Step 4 - Editor and UI

- Subclass `yup::AudioProcessorEditor`.
- Implement `isResizable()`, `getPreferredSize()`, `paint (yup::Graphics&)`, and `resized()`.
- The editor owns UI components; the processor must work correctly with no editor open.
- The editor may keep `AudioParameter::Ptr`s and poll values from a `yup::Timer` for display sync.
- Do not store a raw editor pointer in the processor. Use `hasEditor()` and `createEditor()` as the factory boundary.
- UI controls should notify parameters through gestures, e.g. slider drag start/end plus `setValueNotifyingHost()`.

## Step 5 - Build, test, package

- Configure: `cmake -B build -DCMAKE_BUILD_TYPE=Release -DYUP_BUILD_TESTS=OFF -DYUP_BUILD_EXAMPLES=OFF`
- Build: `cmake --build build --config Release`
- Validate the produced CLAP/VST3/standalone targets in at least one host.
- Test sample-rate changes, buffer-size changes, transport reset, preset recall, automation, MIDI timing, bypass/suspend/resume, and editor open/close.
- If the plugin reports latency or tail, override `getLatencySamples()` and `getTailSamples()` and verify hosts receive correct values.

## Common pitfalls

| Pitfall | Correct approach |
|---------|------------------|
| Reading raw `AudioParameter` values directly for smoothed DSP | Use `AudioParameterHandle` initialised in `prepareToPlay` |
| Forgetting `updateNextAudioBlock()` | Call it once at the top of each audio block before `getNextValue()` or `skip()` |
| Calling `setValueNotifyingHost()` from `processBlock` | Use it from UI/host-control paths; keep audio-thread changes local or lock-free |
| Allocating MIDI voices on note-on | Preallocate a bounded voice pool in `prepareToPlay` |
| Hard-coding stereo processing without matching `AudioBusLayout` | Declare the layout explicitly and guard channel access |
| Missing state methods | Implement `loadStateFromMemory` / `saveStateIntoMemory`; hosts depend on them for recall |
| Holding `getProcessLock()` from UI/background work | Keep state swaps short; the CLAP wrapper uses a try-lock around processing |
| Leaving state stale after `prepareToPlay` or `flush()` | Reset voices, smoothers, filter history, delay buffers, and pending MIDI unconditionally |

Use the `yup-review` skill to audit finished processor code for YUP-specific thread, parameter, wrapper, and bus-layout issues.

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.