Beginner Plugin Development Tutorial (Windows)

Please refer to the official page for Mac and Linux: https://vcvrack.com/manual/PluginDevelopmentTutorial

Having said that, i think it’s handy to have the tutorial condensed here so here we go:

Prerequisites

  • Familiarity with C++, although creating Rack plugins is a great way to learn programming and C++.
  • Familiarity with navigating the command line ( cd , ls , etc).
  • Familiarity with modular synthesizers. Digital signal processing (DSP) knowledge is only required if creating sound generators and processors.

Setting up your development environment

Before building Rack or Rack plugins, you must install build dependencies provided by your system’s package manager. Rack’s own dependencies (GLEW, glfw, etc) do not need to be installed on your system, since specific versions are compiled locally during the build process. However, you need proper tools to build Rack and these dependencies.

Free stuff you’ll need to download

Initial Setup

  • install VCV Rack, Inkscape, GitHubDesktop and Atom

  • Verify that everything is working properly

  • Install MSYS2 and launch the MinGW 64-bit shell from the Start menu, not the default MSYS shell

  • Update the package manager itself with this ([Shift]+[Ins] to paste in the shell):

pacman -Syu
  • Close the shell window and relaunch it

  • now install packages with:

pacman -Su git wget make tar unzip zip mingw-w64-x86_64-gcc mingw-w64-x86_64-gdb mingw-w64-x86_64-cmake autoconf automake mingw-w64-x86_64-libtool mingw-w64-x86_64-jq python
  • Don’t close the shell. On Desktop create a new folder named VCV and put the Rack-SDK inside

Creating the template plugin

The helper.py script included in the Rack SDK is an easy way to create a plugin template. You can run it with no arguments to show documentation.

Decide on a slug for your plugin. We will use MyPlugin for this tutorial. Run

C:/Users/USERNAME/Desktop/vcv/Rack-SDK/helper.py createplugin MyPlugin

Change USERNAME with your windows username.

This will create a folder called MyPlugin/ in your current directory. Example session:

Plugin name [MyPlugin]: My Plugin
Version [1.0.0]:
License (if open-source, use license identifier from https://spdx.org/licenses/) [proprietary]: CC0-1.0
Brand (prefix for all module names) [My Plugin]:
Author []: VCV
Author email (optional) []: contact@vcvrack.com
Author website URL (optional) []: https://vcvrack.com/
Plugin website URL (optional) []:
Manual website URL (optional) []:
Source code URL (optional) []:
Donate URL (optional) []:
Manifest written to MyPlugin/plugin.json
Created template plugin in MyPlugin/
Initialized empty Git repository in /home/VCV/MyPlugin/.git/

You can change this manifest later by editing plugin.json. (See Manifest).

Let’s test the build system. Move in the plugin directory

cd MyPlugin

and run

RACK_DIR=C:/Users/USERNAME/Desktop/vcv/Rack-SDK/ make

If it succeeds, an “empty” plugin will be built containing no modules. However, this is an good opportunity to check that your build environment is set up correctly.

Creating panels

For each module you wish to create, follow the Panel Guide to design an SVG panel graphic.

For this tutorial, we will create a module with the slug MyModule and panel file MyModule.svg. Save this file to res/ and run

C:/Users/USERNAME/Desktop/vcv/Rack-SDK/helper.py createmodule MyModule res/MyModule.svg src/MyModule.cpp

This will create a C++ file automatically from components in the SVG file. Example session:

Module name [MyModule]: My Module
One-line description (optional) []: Simple sine oscillator
Tags (comma-separated, case-insensitive, see https://github.com/VCVRack/Rack/blob/v1/src/tag.cpp for list) []: VCO
Added MyModule to plugin.json
Panel found at res/MyModule.svg. Generating source file.
Found 1 params, 1 inputs, 1 outputs, 0 lights, and 0 custom widgets.
Components extracted from res/MyModule.svgSource file generated at src/MyModule.cpp

To enable the module, add
extern Model *modelMyModule;
to plugin.hpp, and add
p->addModel(modelMyModule);
to the init() function in plugin.cpp.

Open MyModule.svg with Inkscape, open the Layers panel, and hide the components layer to hide component placeholders.

Let’s move on to CodeLite. Install it, launch it and follow the Setup wizard. Specify that you already have a compiler which is the program will find.

Next go to

File->Open->Open Folder... and select “MyPlugin” folder.

Implementing the DSP kernel

Rack modules have four basic components, as we saw in the Panel Guide.

Param: Read with params[...].getValue()
Input: Read with inputs[...].getVoltage()
Output: Write with outputs[...].setVoltage(voltage)
Light: Write with lights[...].setBrightness(brightness)

In this tutorial, we will implement a simple sine oscillator with a PITCH param, 1V/oct PITCH input, SINE output, and a BLINK light that flashes at 1 Hz.

Open the generated src/MyModule.cpp source file and add the following member variables to the Module class.

float phase = 0.f;
float blinkPhase = 0.f;

These variables store the internal state of the module. Then add the following code to the process() function, which is called every audio frame (e.g. 44,100 times per second if the sample rate is 44,100 Hz).

void process(const ProcessArgs &args) override {
    // Compute the frequency from the pitch parameter and input
    float pitch = params[PITCH_PARAM].getValue();
    pitch += inputs[PITCH_INPUT].getVoltage();
    pitch = clamp(pitch, -4.f, 4.f);
    // The default pitch is C4 = 261.6256f
    float freq = dsp::FREQ_C4 * std::pow(2.f, pitch);

    // Accumulate the phase
    phase += freq * args.sampleTime;
    if (phase >= 0.5f)
        phase -= 1.f;

    // Compute the sine output
    float sine = std::sin(2.f * M_PI * phase);
    // Audio signals are typically +/-5V
    // https://vcvrack.com/manual/VoltageStandards.html
    outputs[SINE_OUTPUT].setVoltage(5.f * sine);

    // Blink light at 1Hz
    blinkPhase += args.sampleTime;
    if (blinkPhase >= 1.f)
        blinkPhase -= 1.f;
    lights[BLINK_LIGHT].setBrightness(blinkPhase < 0.5f ? 1.f : 0.f);
}

Compile the plugin with

RACK_DIR=C:/Users/maste/Desktop/vcv/Rack-SDK/  make

If this succeeds, you can build a distributable plugin package with

RACK_DIR=C:/Users/maste/Desktop/vcv/Rack-SDK/  make dist

or automatically install it to your Rack installation with

RACK_DIR=C:/Users/maste/Desktop/vcv/Rack-SDK/  make install

You should now be able to test your plugin by opening Rack and adding your module from the Module Browser.

Beyond the tutorial

The Rack API is very flexible for creating custom DSP algorithms and custom interactive widgets handling many types of events from the keyboard, mouse, etc. See the Rack API headers or the Rack API documentation for the full reference, or review the source code of the many open-source plugins if you prefer learning by example.

The Voltage Standards article defines the behavior for handling signals in a consistent way.

You can find a wealth of information on the Developer category of the VCV Community forum by searching or creating a new thread.

Releasing

Eventually you may want to release your hard work.

See Plugin Licensing for information about following Rack’s license, particularly if developing a commercial plugin. It is recommended to add a LICENSE.txt file to your plugin’s root folder that specifies your preferred license (whether open-source or proprietary).

Review your plugin.json manifest file for correctness, spelling, and capitalization. Finally, submit your plugin to the VCV Library to allow users to easily download your plugin from their VCV account.

2 Likes

The tutorial you linked is also for Windows. Why copy/paste the whole thing here? Do you plan to keep this up-to-date throughout the years?

Actually i’ve had a hard time following the official tutorial, so i thought to make it more easy to follow with a step-by-step approach. Also, here users can comment and post questions and get faster feedback. Hope it helps.

Okay whatever. Just be sure to license your tutorial as CC BY-SA 4.0 since I wrote 98% of it, which is apparently “hard to follow”.

2 Likes

My Boyfriend had an easy time following the official manual on vcv website. He quick compiled a basic module which I can use on linux.

For me it is always searching for additional ressources. Even while following along a C++ Course I lack too many of the basic concepts of programming and hardware knowledge in order to grab what’s to be done in the next step. I spend a lot of time deciphering what is perfectly obvious to those who know. Lucky for me I like maths.

I guess it if hard to follow for either people who are not into programming at all or people who never learned it propperly plus they’re somewhat not too well organized and structured (that would be me). Yet I experience a deeper and consistent gain of knowledge by chewing on a problem for hours and investing time to find out, what parts I am missing.

From a teacher’s perspective the manual is perfect to get a real deep understanding and keep the knowledge for a long time. An approach with smaller steps could be usefull for those, who would get lost on the way while not finding out, what knowledge they are missing.

For the time being I stopped learning programming in order to get to know vcv rack as well as hardware modular better. When I’ve mastered those I will try batteling C++ and hardware/software interaction again (let’s see if I succeed in 5 years :D).

4 Likes

The first thing to do would be to correct this first line. Andrew has pointed out that the official page is also for Windows. I use Windows, and followed the official documentation to build a plugin. What is difference between these instructions and the official docs?

1 Like