This guide explains how to create audio plugins using the YUP framework. YUP supports multiple plugin formats including CLAP, VST3, and more.
A basic YUP plugin consists of the following components:
- A processor class that handles audio processing
- An editor class for the plugin's user interface
- Plugin format-specific wrapper code
Here's a minimal example of a plugin:
#include <yup_audio_plugin_client/yup_audio_plugin_client.h>
class MyPluginProcessor : public yup::AudioProcessor
{
public:
MyPluginProcessor()
{
// Add parameters
addParameter (gainParameter = yup::AudioParameterBuilder{}
.withID ("gain")
.withName ("Gain")
.withRange (0.0f, 1.0f)
.withDefault (0.5f)
.build());
}
void prepareToPlay (double sampleRate, int samplesPerBlock) override
{
// Initialize processing resources
gain = yup::AudioParameterHandle (*gainParameter, sampleRate);
}
void releaseResources() override
{
// Clean up resources
}
void processBlock (yup::AudioBuffer<float>& audioBuffer, yup::MidiBuffer& midiMessages) override
{
if (gain.updateNextAudioBlock())
{
float currentGain = gain.getCurrentValue();
float destinationGain = gain.skip (audioBuffer.getNumSamples());
audioBuffer.applyGainRamp (0, audioBuffer.getNumSamples(), currentGain, destinationGain);
}
else
{
audioBuffer.applyGain (gain.getCurrentValue());
}
}
bool hasEditor() const override { return true; }
yup::AudioProcessorEditor* createEditor() override;
private:
yup::AudioParameter::Ptr gainParameter;
yup::AudioParameterHandle gain;
};
class MyPluginEditor : public yup::AudioProcessorEditor
{
public:
MyPluginEditor (MyPluginProcessor& p)
: AudioProcessorEditor (&p)
, processor (p)
{
setSize (400, 300);
}
void paint (yup::Graphics& g) override
{
g.fillAll (findColour (yup::ResizableWindow::backgroundColourId));
}
private:
MyPluginProcessor& processor;
};
yup::AudioProcessorEditor* MyPluginProcessor::createEditor() override
{
return new MyPluginEditor (*this);
}
// Plugin entry point
extern "C" yup::AudioProcessor* createPluginProcessor()
{
return new MyPluginProcessor();
}Create a CMakeLists.txt file for your plugin:
cmake_minimum_required (VERSION 3.31)
set (target_name my_plugin)
set (target_version "0.0.1")
project (${target_name} VERSION ${target_version})
include (FetchContent)
FetchContent_Declare(
yup
GIT_REPOSITORY https://github.com/kunitoki/yup.git
GIT_TAG main)
set (YUP_BUILD_EXAMPLES OFF)
set (YUP_BUILD_TESTS OFF)
FetchContent_MakeAvailable(yup)
# Create the plugin target
yup_audio_plugin (
TARGET_NAME ${target_name}
TARGET_VERSION ${target_version}
TARGET_IDE_GROUP "MyPlugin"
TARGET_APP_ID "com.mycompany.${target_name}"
TARGET_APP_NAMESPACE "com.mycompany"
TARGET_CXX_STANDARD 20
PLUGIN_ID "com.mycompany.MyPlugin"
PLUGIN_NAME "MyPlugin"
PLUGIN_VENDOR "com.mycompany"
PLUGIN_EMAIL "support@mycompany.com"
PLUGIN_VERSION "${target_version}"
PLUGIN_DESCRIPTION "The best audio plugin ever."
PLUGIN_URL "https://www.mycompany.com"
PLUGIN_IS_SYNTH OFF
PLUGIN_IS_MONO OFF
PLUGIN_CREATE_CLAP ON
PLUGIN_CREATE_VST3 ON
PLUGIN_CREATE_AU ON
PLUGIN_CREATE_STANDALONE ON
MODULES
yup::yup_gui
yup::yup_audio_processors)
# Add source files
file (GLOB sources "${CMAKE_CURRENT_LIST_DIR}/*.cpp")
source_group (TREE ${CMAKE_CURRENT_LIST_DIR}/ FILES ${sources})
target_sources (${target_name}_shared PUBLIC ${sources})cmake -G "Xcode" . -B build -DYUP_ENABLE_TESTS=OFF -DYUP_ENABLE_EXAMPLES=OFF
cmake --build build --config Releasecmake -G "Visual Studio 17 2022" -A x64 . -B build -DYUP_ENABLE_TESTS=OFF -DYUP_ENABLE_EXAMPLES=OFF
cmake --build build --config Releasecmake -G "Ninja" . -B build -DYUP_ENABLE_TESTS=OFF -DYUP_ENABLE_EXAMPLES=OFF
cmake --build build --config Release- VST3:
~/Library/Audio/Plug-Ins/VST3/ - AU:
~/Library/Audio/Plug-Ins/Components/ - AUv3:
~/Library/Audio/Plug-Ins/AppExtensions/ - CLAP:
~/Library/Audio/Plug-Ins/CLAP/ - AAX:
~/Application Support/Avid/Audio/Plug-Ins/
- VST3:
C:\Program Files\Common Files\VST3\ - CLAP:
C:\Program Files\Common Files\CLAP\
- VST3:
~/.vst3/ - CLAP:
~/.clap/
-
Parameter Management
- Use
addParameter()in the processor constructor - Handle parameter changes in
processBlock()
- Use
-
Editor Design
- Keep the editor lightweight
- Handle resizing appropriately
-
Resource Management
- Initialize resources in
prepareToPlay() - Clean up in
releaseResources() - Use RAII for resource management
- Initialize resources in
-
Performance
- Minimize allocations in the audio thread
- Use SIMD operations when possible
- Profile your plugin for CPU usage
-
Testing
- Test your plugin in different DAWs
- Verify parameter automation
- Check for memory leaks
- Test different sample rates and buffer sizes
-
Plugin Not Showing Up
- Verify installation path
- Check plugin format compatibility
- Ensure proper permissions
-
Audio Issues
- Verify buffer sizes
- Check for denormal numbers
- Monitor CPU usage
-
UI Problems
- Handle window resizing
- Manage component lifetimes
- Test different DPI settings
- CMake API Reference - Full reference of all CMake options and functions
- CLAP Documentation
- VST3 Documentation