One of the main pain point with developing a VST plugin is that it is very hard to even know where to start. The recommended approach is to copy/paste one of the example plugin and modify it. But it is not very clear what should or shouldn’t be changed. Nor is it obvious which command to run and with which parameters to start the editor, run the validation steps, generate an audio unit wrapper, etc… It turns out that none of it is trivial and is either poorly or simply not documented.

Jamba was specifically designed to simplify all this by

  • providing a very easy way to generate a blank/skeleton plugin with all the necessary boiler plate code in the right place
  • providing a way to automatically download and setup the required dependencies
  • providing a very simple to use script ( / jamba.bat) which takes care of invoking the proper cmake targets with the proper parameters and dependencies

Step 1 - Generate the skeleton plugin

You have 2 options to do this:

  • you can follow the Web steps which lets you provide the information necessary directly in the browser and generate a zip file with the plugin ready to build. This is the recommended approach since you do not have to download and/or clone anything locally
  • you can follow the Command Line steps which involves cloning the github repository and locally running a python script which will ask a few questions

Both options will end up generating a “blank” plugin which is a fully buildable, testable, editable and deployable plugin, which simply copies the stereo input to the stereo output so that it is easy to build from there.


Once the plugin is generated, feel free to edit/modify any file you want as the generating phase is only meant to be run once in order to quickly get a plugin with all the pieces (and boilerplate code) in place.

Step 2 - Run the configure script

The plugin contains a script for macOS (resp. configure.bat for Windows) that you run from wherever you want the build to happen. A build subdirectory of the directory from which you run the command will be created. This script is a very small wrapper around cmake to invoke it with the proper arguments.

# Example of run (from the source tree, but can be ANYWHERE)

> cd ~/src/Kooza-src
> ./
-- The C compiler identification is AppleClang
-- The CXX compiler identification is AppleClang
-- Check for working C compiler: /Applications/
-- Check for working C compiler: /Applications/ -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Detecting C compile features
-- Detecting C compile features - done
-- Check for working CXX compiler: /Applications/
-- Check for working CXX compiler: /Applications/ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Downloading VST369...
-- VST3_SDK_ROOT set to /Users/ypujante/src/Kooza-src/build/_deps/vst369-src/VST3_SDK
-- Fetching jamba
-- jamba git version - v3.2.2
-- VST3_SDK_ROOT=/Users/ypujante/src/Kooza-src/build/_deps/vst369-src/VST3_SDK
-- Building with Xcode version: 9.2
-- macOS Deployment Target: 
-- SMTG_VST3_TARGET_PATH is set to : /Users/ypujante/Library/Audio/Plug-ins/VST3
-- SMTG_MYPLUGINS_SRC_PATH is not set. If you want to add your own plug-ins folder, specify it!
-- Found EXPAT: /usr/lib/libexpat.dylib (found version "2.2.1") 
-- Fetching googletest
-- Found PythonInterp: /opt/local/bin/python (found version "2.7.8") 
-- Looking for pthread.h
-- Looking for pthread.h - found
-- Looking for pthread_create
-- Looking for pthread_create - found
-- Found Threads: TRUE  
-- acme_Kooza will be VST2 compatible
-- Adding target acme_Kooza_test for test cases: test/cpp/test-Kooza.cpp
-- Configuring done
-- Generating done
-- Build files have been written to: /Users/ypujante/src/Kooza-src/build

Please ignore the output about SMTG_MYPLUGINS_SRC_PATH not being set as it is displayed by the VST SDK but Jamba does not use it.


The main point of running this command is to download all the dependencies and setup the (resp. jamba.bat) main script that you will use in the next step. You should not have to rerun this command afterwards.


After this step, you can open the project in XCode (resp. Visual Studio) as the project has been created in the build folder generated (ex: Kooza.xcodeproj). Note that you can also open the project directly in CLion without even running this step since CLion natively supports cmake.

Step 3 - Build and test the plugin

The skeleton plugin main processing code simply copies the (stereo) input to the output. It is now ready to be built and tested. For this you use the (resp. jamba.bat) script that was generated during Step 2.


Check the documentation page for more details about the command.

Running -h (resp. jamba.bat -h) gives you the list of all commands the script understands.

> -h
   Usage: [-hdrn] <command>

     -h : usage help
     -d : use Debug build config (default)
     -r : use Release build config (Debug if not defined)
     -n : dry run (prints what it is going to do)

     ---- VST Commands ----
     clean    : clean all builds
     build    : build the VST plugin
     edit     : start the GUI editor (Debug only)
     install  : install the VST plugin in their default location
     test     : run the unit tests
     validate : run the VST3 validator
     ---- Audio Unit Commands ----
     build-au    : build the Audio Unit wrapper plugin
     install-au  : install the Audio Unit plugin in its default location
     validate-au : run the Audio Unit validator
     ---- Generic Commands ----
     archive : generate the zip file containing the plugin(s) and README/License
     prod    : run test/validate/archive (default to Release, override with -d)
     ---- CMake target ----
     <target> : invoke cmake with the provided target

By running validate, you will build the plugin and runs the VST3 validation tool that is provided by the VST SDK to validate that the plugin is actually a VST3 plugin and behaves properly.


The first time you run this command it will take a little while since most of the SDK needs to be built.

# Example of run
> validate

* Loading module...


* Scanning classes...

  Factory Info:
	vendor = acme
	url =
	email =

  Class Info 0:
	name = Kooza
	category = Audio Module Class
	cid = D5D0FAB71AE14269BB49F87CDA113CAD

  Class Info 1:
	name = KoozaController
	category = Component Controller Class
	cid = 0CD45EEF511A4198BAAD745F467F6602
Result: 39 tests passed, 0 tests failed

Step 4 - Run the editor

Let’s now run the editor which is another tool that comes with the VST SDK and which lets you build, in a WYSIWIG fashion, the UI of your plugin.

> edit

You should see something like this (after you right click in the window and select Open UIDescription Editor).

Kooza - Editor

The skeleton plugin UI only contains 2 text labels that gives you instructions on what to do:

  • right click to open the editor
  • select menu File / Save as to save the xml file (which represents the UI) with the proper name in its proper location (should be under <PLUGIN_ROOT>/resource/<PLUGIN_NAME>.uidesc as shown in the UI). After saving it the first time, you can simply select File / Save (or use the shortcut) once you make modifications.

Step 5 - Install the plugin

Now that the plugin builds properly (and pass validation), you should install it to be able to try it right away in your favorite DAW. Since the blank plugin is essentially a passthrough effect (copies input to output), you should be able to:

  • see the plugin listed in the list of plugins of your favorite DAW (the plugin name will be <xxx>_Debug since we are building in debug mode, for example Kooza_Debug in this example)
  • add the plugin as an effect to any instrument and verify that you can still hear the output of the instrument (passthrough)

    > install
    /Applications/ -E make_directory /Users/ypujante/Library/Audio/Plug-Ins/VST
    /Applications/ -E remove_directory /Users/ypujante/Library/Audio/Plug-Ins/VST/Kooza_Debug.vst
    /Applications/ -E copy_directory /Users/ypujante/src/Kooza-src/build/VST3/Debug/acme_Kooza.vst3 /Users/ypujante/Library/Audio/Plug-Ins/VST/Kooza_Debug.vst

The editor is actually part of the plugin when building in Debug mode, so you can right click to open it (like in Step 5).


On macOS, if you start your DAW from the command line, you can see the output of the plugin (DLOG_F statements):

> /Applications/
2020-02-20 07:13:42.285 (   0.000s) [            A61C]     KoozaProcessor.cpp:18       0| [Kooza_Debug] KoozaProcessor() - jamba: v4.1.0-0 - plugin: v1.0.0
2020-02-20 07:13:42.286 (   0.000s) [            A61C]     KoozaProcessor.cpp:22       0| Parameters --->
| ID   | TITLE  | TYP | OW | TRS | SHA | DEF.N | DEF.S | STP | FLG   | SHORT  | PRE | UID | UNS |
| 1000 | Bypass | vst | rt |     |     | 0.000 | Off   | 1   | 65537 | Bypass | 4   | 0   |     |
2020-02-20 07:13:42.286 (   0.000s) [            A61C]     KoozaProcessor.cpp:39       0| KoozaProcessor::initialize()
2020-02-20 07:13:42.286 (   0.000s) [            A61C]     KoozaProcessor.cpp:60       0| RT Save State - Version=1 --->
| ID   | TITLE  |
| 1000 | Bypass |
2020-02-20 07:13:42.286 (   0.001s) [            A61C]    KoozaController.cpp:10       0| KoozaController()
2020-02-20 07:13:42.286 (   0.001s) [            A61C]    KoozaController.cpp:38       0| GUI Save State - Version=0 --->
| ID | TITLE |
2020-02-20 07:13:42.286 (   0.001s) [            A61C]                Kooza.h:89       0| RTState::write - 1000=0.000/Off
2020-02-20 07:13:42.286 (   0.001s) [            A61C]     KoozaProcessor.cpp:91       0| KoozaProcessor::setupProcessing(Realtime, 32bits, maxSamples=256, sampleRate=48000.000000)
2020-02-20 07:13:53.321 (  11.036s) [            A61C]    KoozaController.cpp:18       0| ~KoozaController()
2020-02-20 07:13:53.321 (  11.036s) [            A61C]     KoozaProcessor.cpp:71       0| KoozaProcessor::terminate()
2020-02-20 07:13:53.321 (  11.036s) [            A61C]     KoozaProcessor.cpp:31       0| ~KoozaProcessor()```

Step 6 - Add your own files

You are now ready to start implementing the logic of your plugin by adding new files

Adding source files

When you add new source files, add them to the CMakeLists.txt file in the vst_sources section (feel free to change the CMakeLists.txt to your liking, for example if you want to include all files without having to explicitly add them, although not recommended, this is possible… refer to cmake for more info).





Adding (unit) test files

When you add new tests files, they are added automatically as long as they are located under test/cpp. Jamba integrates with Google Test for unit testing but feel free to use something different if you want to.

Here is an example of unit test

#include <pongasoft/logging/logging.h>
#include <gtest/gtest.h>

namespace ... {

// PluginTest - Test1
TEST(PluginTest, Test1)
  DLOG_F(INFO, "Demonstrating test capability");

  ASSERT_EQ(4, 2+2);

... }

Adding resource files (GUI)


The way macOS and Windows handle GUI resources is very different (Info.plist vs .rc file). Thankfully Jamba makes it easy and will generate the right file for the right platform if you use the jamba_add_vst3_resource function as described below.

When you add new resources for the GUI (images for example), they need to be added to CMakeLists.txt:

# example (see commented line in CMakeLists.txt)
jamba_add_vst3_resource(${target} PNG "background.png")

In the UI editor when adding a bitmap and saving the xxx.uidesc file, the fullpath of the image might be recorded. Make sure to edit the xxx.uidesc and modify it to keep ONLY the filename

<!-- this is WRONG!!!!! -->
<bitmap name="background" path="/private/tmp/pongasoft-Kooza-plugin/resource/background.png"/>

<!-- this is right -->
<bitmap name="background" path="background.png"/>

cmake automatically detects changes to CMakeLists.txt so you should not have to do anything special when you make any changes.

Step 7 - Next

Here are some recommended steps:

  • If you have never written a VST3 plugin I would suggest reading the VST3 documentation that comes with the SDK (you can find more information on the concepts, how the editor works, etc…). At the end of the day you are still writing a VST3 plugin not a Jamba plugin! Simply open the index.html file at the root of the SDK.
  • Check jamba-sample-gain for documentation and explanation of the Jamba concepts and in particular:
    • Check <Name>.h which is where you define the Vst (and Jmb) parameters your plugin will use
    • Check RT/<Name>Processor.cpp which contains the main logic of the plugin
    • Use the editor to change the UI of the plugin (which then saves the resource/<Name>.uidesc xml file). You can edit the xml file by hand, but it is definitely recommended to use the editor to do so.
    • Check <Name>_VST2.cpp on instructions about how to register the VST2 plugin ID with Steinberg (unfortunately this is a manual process). You don’t have to do this right away… only when you are ready to release your plugin.
  • Check the VST3 SDK section so that the VST3 SDK is installed for all your plugins instead of being donwloaded with each one.

    If you have followed the quickstart steps, the SDK has been downloaded during Step 2 so you can simply copy it in a more permanent location.