15.12.2020

How To Make A Vst Plugin In Reaper

Cockos Reaper Tips & Techniques
  • DAWs >Reaper

Effects controls duplicated across every channel to provide a mixing console-style view of a project.

Create a custom channel strip, complete with controls, in Reaper’s Mixer.

Click 'Insert' in the top menu bar, then click 'Insert Virtual Instrument on New Track.' Click 'VST' in the left-hand column, then click on the new VST. Click 'OK' to add it to a new track in Reaper.

Scroll down to Plugins, then VST. Look at the text window right under VST Paths. You need to make Reaper 'point' to all the locations to which the plugins have been moved. I built a new machine mid-year 2020. Plugins Automatically resize VST/DX config windows: By default, REAPER will automatically resize the window containing FX plug-ins to match the size of the size of the largest plug-in displayed. Select the down check box if you want the window to automatically resize down when switching to a plug-in with a smaller GUI.

Getting ‘granular’ with your plug-in parameters is great for really detailed work, but sometimes you want the opposite: to see your whole (virtual) mixing desk laid out in front of you. Unlike some other DAWs, Reaper doesn’t feature a default console-style view for your plug-ins, but it’s actually quite easy to roll your own. In fact, Reaper allows you to show your choice of effects parameter knobs from any combination of plug-ins in each mixer channel.

Getting Started

To illustrate this, let’s go through the process of building a classic channel strip layout, comprising a gate, basic compression controls, and a three-band semi-parametric EQ. We’ll also throw in a single-knob saturation control to top it off. For this exercise, and to allow people to play along at home, I’ll stick to Reaper’s bundled plug-ins, but you can use third-party ones too.

Let’s create a new track and set up the plug-ins we’d like. Starting with a blank project, hit Cmd-T (for Mac; it’s Ctrl-T in Windows) to instantiate a new track, then hit the ‘FX’ button on the track’s control panel to bring up its effects window. Click on ‘Add’ to bring up the ‘Add FX’ window, choose VST:ReaGate from the list, and hit OK. Repeat the process to bring in VST:ReaComp, VST:ReaEQ and, finally, JS:Saturation. You’ll end up with something similar to what’s show opposite. Close the effects window.

The track effects window with our chosen four effects plug-ins loaded.

Now, turn your attention to the mixer. If the mixer window is not already visible, hit Cmd-M (Mac) or Ctrl-M (PC) to bring it up. From the Mixer menu untick ‘Dock mixer in docker’, and maximise the mixer so it fills the screen. Then select ‘show FX parameters when size permits’. Several greyed-out knob controls will appear on your mixer strip — this is where your channel-strip controls will reside.

Free piano vst windows. Right-click in one of the mixer strip’s empty knob slots and, from the pop-up menu, select ‘VST:ReaGate (Cockos) -> Thresh’. This should populate the top slot with a knob marked ‘Thresh’, which is linked to the ReaGate plug-in on that channel. Next, we’ll assign compression controls. Again, right-click in the empty area. Select ‘VST:ReaComp (Cockos) -> Thresh’ to create a knob that’s assigned to the compressor’s threshold control. Work your way through, adding all the parameters you want to be able to control from the mixer.

For this exercise, I’d suggest including the following parameters in addition to the two that we’ve already assigned:

  • VST:Reacomp -> Ratio
  • VST:Reacomp -> Attack
  • VST:Reacomp -> Release
  • VST:ReaEQ -> Gain-High Shelf
  • VST:ReaEQ -> Gain-Band 2
  • VST:ReaEQ -> Freq-Band 2
  • VST:ReaEQ -> Gain-Low Shelf
  • JS:Saturation -> Amount (%)

The left channel’s knobs have default labels, taken from the plug-in parameters to which they’re assigned. The right channel has more meaningful user-defined labels.As you add more controllers, you may find that they exceed the space available in the mixer strip, in which case some little up/down scroll buttons will appear. You can (at the expense of sends or inserts, or even by reducing the fader length) click and drag on the dividers between mixer sections to free up more display space.

Once you’re done, you should end up with a mixer strip that looks something like the second image. This is already broadly functional, but the default labelling of controls leaves something to be desired! You have two knobs marked ‘Thresh’, some of the labels are wider than the strip, and there’s no clue as to what the ‘Amount’ knob does. Reaper’s ‘controller aliasing’ can be used to tidy up the control labels. Right-click on the top ‘Thresh’ control, then select ‘Alias: VST:ReaGate (Cockos): Thresh’. A pop-up window should prompt you to enter a new parameter name. Keep it short and identifiable — we’ll use ‘Gate’ for now.

Work through, creating an alias for any parameters you wish. The compression controls are fairly self-explanatory, but the EQ needs some clarification. Right-click on ‘Gain-High Shelf’, select ‘Alias: VST:ReaEQ (Cockos): Gain-High Shelf’ and rename it ‘High’, and continue down the strip. I replaced ‘Gain-Band 2’ with ‘Mid’, ‘Freq-Band 2’ with ‘Mid Freq’, ‘Gain-Low Shelf’ with ‘Low’ and ‘Amount (%)’ with ‘Saturation’. .

You should now have good ‘big-picture’ control of your plug-ins from the mixer. If you need to drill down to a greater level of control, double-clicking any knob will open up the associated effects window, where you can tweak any parameters as usual.

The layout of your effects controls in the mixer strip always reflect your signal chain — so if you open the track effects window (click on the FX button in the mixer strip) and drag JS:Saturation from the bottom of the list to the top, the knob layout in the mixer strip will change accordingly.

Once you’re happy with your chain and controller layout, you’ll likely want to save it for use in other projects. To do this, save it as an FX Chain: open up the track effects window, right-click in the effects list and select ‘FX Chains -> Save all FX as chain’. A save dialogue box will appear, where you name your chain and then hit Save. An effects chain stores the plug-in instances, parameters, order, and the mixer control assignments.

Your mixer effects controls also appear in the track control panel.

To demonstrate this, create a new track in the project and bring up the track effects window, then right-click the empty effects list, select ‘FX Chains -> Load FX Chain’ and choose ‘SOS Channel Strip.RfxChain’. Your blank track will be populated with the same plug-ins and knobs as your original track. If you have the free SWS/S&M Extension (www.sws-extension.org) you’ll also find custom actions for copying and pasting effects chains across multiple tracks. And for more on custom actions, check out Reaper Notes from SOS March 2016.

If you love your new mixer layout so much you want to use it all the time, you can also choose to assign it as the default for new tracks. From the track effects window, right-click on the track list and select ‘FX Chains -> Save all FX as default chain for new tracks’. Any newly instantiated track will now come pre-loaded with your plug-in chain and controller assignments.

Drawbacks & Compromises

Hopefully, all is well.. but there can be a few niggles and drawbacks. A little more control over the aesthetic of the knob layout would be very handy — things like on/off toggles, spacers and colour customisation would allow for much more ergonomic controller layouts. And while it’s nice that the knob layout reflects the signal chain, it would be useful to be able to re-order the knobs according to preference. Another minor quibble is that if you flick back to Reaper’s main arrange view and zoom in vertically to a track, you’ll notice that the effects controls are also visible in the track control panel. This can be very useful, but the presentation is a little untidy and there’s no way to turn it off while leaving the mixer controls intact. Thankfully, in reality I very seldom zoom in quite enough for this to cause me problems.

What Next?

There are a few extra tricks to try. You can assign controls from any plug-in you like, and there’s nothing to say you must use the same ones for every track — you could set up identical controller layouts with specific plug-ins appropriate to that track. For instance, you might use ReaComp as your go-to compressor on most channels but replace it with a more characterful compressor on certain tracks, and keep the control interface consistent on all those channels.

You may also want to explore mapping the effects controls to external MIDI controllers. This is trivially simple: from the mixer, right-click on the knob you wish to assign, select ‘Learn’ and move the MIDI controller you want to assign. I’ve had great success using eight rotary encoders mapped to EQ and compression settings to instantly tweak parameters on the selected track.

Watch The Video

Introduction

Microsoft announced that it would offer Visual Studio Express free of charge forever. Though the Express version of Visual C++ (hereafter referred to as VC++) has some limitations, it’s still a great tool and it’s nice to see Microsoft taking some steps to support the developers writing software for their platform. This document will describe how to get VC++ installed and building VST plugins. It assumes that you have prior experience developing VST plugins, and are familiar with the structure and layout of the VST SDK.

If you are trying to write VST’s in a language other than C++, than this guide is not for you. There are lots of other frameworks out there for developing VST plugins in other languages (such as C#, Java, Ruby and Python, just to name a few).

This tutorial will walk you through the process of installing and configuring the tools you’ll need to build your own VST plugins with Visual Studio, and creating a simple VST plugin with optional support for a VSTGUI frontend. This guide only covers building VST 2.x plugins, as the VST3 SDK is not very widely supported yet. Note that Steinberg’s website is a bit confusing and it is easy to accidentally download the wrong version of the SDK, so double-check to make sure that you have the 2.4 SDK.

Download required packages

  1. Steinberg’s VST SDK, which requires you to make a free Steinberg Developer account.
  2. Microsoft’s Visual C++. This guide uses the 2010 Express edition, as it was the latest version at time of writing.
  3. Libpng and zlib (optional)

Install Visual C++

If you already have a working installation of VC++, you can skip this step. Otherwise, download VC++ and install it. The standard installation should be OK, but you can choose to perform a custom installation if you don’t want documentation or other stuff installed with it. Before installing VC++, you must remove any other versions of VC++ on your computer.

Next, download and install the Platform SDK, which will provide you with the standard header files and libraries you’ll need to build software. You may choose to install VC++ anywhere on your hard drive, but the default location is C:Program FilesMicrosoft Visual Studio 10.0.

Creating your project

Create a new project of type “Class Library”, which we’ll call YourProjectName. In the rest of this tutorial, whenever you see YourProjectName, replace that text with the actual name of your project.

Vst

In Visual Studio 9, you’d make a new project with the wizard found at File -> New -> Project. Select Visual C++ -> Win32 Console Application, and choose a directory for your project. When the wizard opens, press “Next” and select DLL as the Application Type. Also check the “Empty Project” box.

If you prefer not to start with an empty project, then you can remove all of the files that VC++ creates for you, but keep the resource.h and YourProjectName.rc files, and remove any references to these files (such as YourProjectName.ico being listed in the resource file).

Add Source Code to the Project

If you already have source code for your plugin, simply add it to the project. Otherwise, you need to create the following files:

  • YourProjectName.cpp
  • YourProjectName.h
  • resource.h (Only needed if building a plugin GUI)
  • YourProjectName.rc (Only needed if building a plugin GUI)

You will also need to add the files from the VST SDK, which includes everything under the vstsdk2.4/public.sdk/source/vst2.x and vstsdk2.4/pluginterfaces/vst2.x directories. I usually prefer to manually make groups for these directories and drag the files to the groups from Explorer, as dragging the entire “vstsdk2.4” directory to VS can cause it to choke when it tries to add a bunch of unused files to the project.

To start out with, the plugin’s entry point header file (YourProjectName.h) should look something like this:

The accompanying class definition (YourProjectName.cpp) should look something like this:

Note that your project won’t compile just yet, but be patient!

The above code samples are simply blank entry points which don’t do anything exciting. The VST SDK offers lots of methods which you can override in order to do things like setting parameters, receiving MIDI messages, and so on. These things are beyond the scope of this tutorial; if you don’t know what code to put inside of processReplacing, try checking out the “again” example distributed within the VST SDK in the public.sdk/samples/vst2.x/again folder.

You must also create a module definition file for your project, named YourProjectName.def. Usually this file is placed in the same directory as the VC++ project file, but you may place it somewhere else so long as this definition matches the Module Definition File settings in the Linker section of the project preferences. This is just a plain-text file which should contain the following text:

Configure build settings

Go to the project settings either by right clicking on the project in the solution explorer and then selecting “Properties”. Make the following changes to the project for all build configurations:

  • General
    • Character Set: Not Set
    • Common Language Runtime Support: No Common Language Runtime Support
  • C/C++
    • General:
      • Additional Include Directories:
        1. (or wherever you put the VST SDK)
        2. Your source code directory
        3. Any other directories which you may have header files stored in Global SDK directories, such as
    • Preprocessor:
      • Preprocessor Definitions:
      • For Debug builds you may also wish to add
      • If you wish to use PNG graphics for a VSTGUI frontend, add
      • To avoid lots of compiler nags and warnings, define
      • In some cases, you may also need to define
    • Code Generation:
      • Runtime Library: Multi-threaded. Multi-threaded debug may be used for debug builds. This will build the VC++ common runtime library statically into your plugin, increasing its size by approximately 200Kb. If you choose to use the CRL as a dynamic library, then you must also distribute a copy of the CRL with your application, which complicates deployment and distribution.
    • Precompiled Headers:
      • Precompiled Header: Not Using Precompiled Headers. Yeah, this makes rebuilding a bit slower, but will avoid a bunch of weird errors as you are getting your project set up. Once you get the project building you can revisit this step.
  • Linker
    • General:
      • Additional Library Directories: Add any other library directories which your project depends on.
    • Input:
      • Additional Dependencies (for Release builds):
        • libcmt.lib
        • uuid.lib
        • shell32.lib
        • ole32.lib
        • gdi32.lib
        • User32.lib
        • advapi32.lib
        • zlib.lib (only if you are building with a GUI)
        • libpng.lib (only if you are building with a GUI)
      • Additional Dependencies (for Debug builds):
        • shell32.lib
        • msvcrtd.lib
        • ole32.lib
        • gdi32.lib
        • User32.lib
        • advapi32.lib
        • zlib.lib (only if you are building with a GUI)
        • libpng.lib (only if you are building with a GUI)
      • Ignore Specific Default Library (for Release builds):
        • msvcrt.lib
        • libc.lib
        • msvcrtd.lib
        • libcd.lib
        • libcmtd.lib
      • Ignore Specific Default Library (for Debug builds):
        • libcmt.lib
        • libcmtd.lib
        • msvcrt.lib
      • Module Definition File: YourProjectName.def

Adding support for VSTGUI (optional)

Make

Include VSTGUI support in your plugin, simply add the VSTGUI files into your project in addition to your own editor class. At a very minimum, these are:

  • aeffguieditor.cpp
  • vstcontrols.cpp
  • vstgui.cpp

Adding support for PNG graphics (optional)

If you would like to use PNG’s in your plugin instead of BMP graphics, you will need to also build your own version of libpng and zlib. Download the source code for both libraries from the links given in the “Requirements” section of the document and place them in the same directory. There is a Visual Studio project for libpng which will also build zlib for you; it is located in the projectsvisualc71 directory. In order to get the projects to build correctly, you’ll need to rename the source code directories to simply “libpng” and “zlib”, removing the version numbers from the directory name.

When you open the project up, VC++ will run you through the project conversion wizard. Convert the project, and change the “Runtime Library” settings in both libpng and zlib to be Multi-Threaded, as described above. Unless this step is performed, the dependency on the CLR will be present in your project. Next, choose the LIB ASM Release or LIB Release build style and build the project; if you build the libraries as DLL’s, you will be unable to statically link them into your plugin. The project should build ok, but throw a few errors when attempting to run the pngtest files. You can ignore these problems, as the libraries will still be correctly compiled and can now be linked to your project.

Visual Studio doesn’t need to have the libraries within your actual project. Instead, place the libraries in a directory of your choosing and be sure to add this path to the list of “Additional Library Directories” in the Linker preferences for your project. You may choose to place the libraries in the same directory as the Microsoft Platform SDK stuff, but I personally prefer to keep them in a separate directory checked into version control. Also be sure to add references to libpng.lib and zlib.lib for your project in the “Additional Dependencies” section of your Linker preferences for the project.

The path must be relative to the location of the project file. Then, in resource.h, add the following preprocessor definitions:

Now you can use IDB_BITMAP1 (or any other name of your choosing) in your code when creating new CBitmap objects.

I have heard some reports of vstgui.cpp not compiling properly due to the missing symbol png_set_expand_gray_1_2_4_to_8. Changing png_set_gray_1_2_4_to_8 to png_set_expand_gray_1_2_4_to_8 in vstgui.cpp seems to fix this issue.

Final considerations

VC++ ships with an optimizing compiler, but sometimes the compiler will choke on certain files and optimization must be disabled. In particular, I have experienced this with Laurent de Soras’ FFTReal libraries, since they are written as template classes. In general, however, optimization is a good idea, as is “Eliminating Unreferenced Data” (in the linker settings). The “Whole Program Optimization” setting appears tempting, but usually results in dozens of build errors and problems, so it’s best to avoid this. Also, be sure to use the optimization features of this compiler and linker, as they can greatly boost runtime performance.

If you are developing on a multi-core machine, then you might need to disable parallel builds by setting the number of parallel builds to 1 under Tools -> Options -> Projects and Solutions -> Build and Run. In past verisons of VS, I noticed that the compiler does not always link projects in the order one would expect, which caused odd errors during linking about missing symbols. However, VS2010 users probably shouldn’t need worry about this setting.

Unresolved symbols when linking

Sometimes you may see errors like the following:

If you are getting errors in your build about missing symbols, make sure that you double- and triple-check the debug and release configurations for the library configuration above, since some of the libraries which are used in one build style are specifically excluded from the other. Also, when you close and re-open the project’s build properties, VS always “forgets” the last selected build style, so remember to check and set this appropriately.

Also, you should check to make sure that the Platform SDK was correctly installed on your system and that your project’s include and library paths are pointing to these directories.

Unresolved external symbols

If you are seeing errors like this:

Then this most likely means that the file which contains the given symbol is not correctly added to the VC++ solution.

Linking errors with symbols defined multiple times

This is undoubtedly one of the most frustrating problems which can occur when building a VST in VC++. If you are seeing error messages like this, then it most likely means there is some problem with your library configuration:

How To Use Vst Plugins In Reaper

Most likely, the libcmt and msvcrt libraries are being included incorrectly in your build. Double-check the library list above, keeping in mind that the recommended configuration uses libcmt for release builds only, and msvcrtd for debug builds only.