Teragon Audio

Welcome to the Teragon Audio website. Here you will find audio software for both Mac OS X and Windows platforms, including VST/AudioUnit plugins, utilities, and developer tools. All of the software you find here is free, and most of it is open-source, too. Note that we offer absolutely no warranty or guarantee on any software listed here, so use at your own risk. If you have any questions or problems with the software found here, please either make a comment on the page, or see the contact page to reach us directly.



How to make VST Plugins in Visual Studio

Recently, 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.

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 3.x SDK is not very widely supported yet.

Step 1: Download Requirements:
  1. Steinberg's VST SDK, which requires you to make a free Steinberg Developer account.  This tutorial assumes you are developing a VST 2.4 plugin.
  2. VSTGUI, which is provided with the VST SDK
  3. Microsoft's Visual C++ 2008 Express (version 9)
  4. Microsoft's Platform SDK.  This tutorial assumes you are using the Windows Server 2003 R2 SDK.
  5. Libpng and Zlib (optional)

Step 2: Install Visual C++

First, 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 Files\Microsoft Visual Studio 9. This document will use to refer to whatever path you chose to install to.

Step 3: Create 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.

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).

Step 4: 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 following files from the VST SDK, which includes everything under the vstsdk2.4/public.sdk/source/vst2.x.

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


#include "audioeffectx.h"

#define NUM_PARAMS 0

class YourProjectName : public AudioEffectX {
public:
YourProjectName(audioMasterCallback audioMaster);
~YourProjectName();

void processReplacing(float **inputs, float **outputs, VstInt32 sampleFrames);
};

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

#include "YourProjectName.h"

AudioEffect* createEffectInstance(audioMasterCallback audioMaster) {
return new YourProjectName(audioMaster);
}

YourProjectName::YourProjectName(audioMasterCallback audioMaster) : AudioEffectX(audioMaster, 0, NUM_PARAMS) {
}

YourProjectName::~YourProjectName() {
}

void YourProjectName::processReplacing(float **inputs, float **outputs, VstInt32 sampleFrames) {
}

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 a normal plaintext file which should contain the following text:

LIBRARY YOURPROJECTNAME
EXPORTS
VSTPluginMain
main=VSTPluginMain

Step 5: Configure Project Build Settings

Go to the project settings either by double clicking on the project name in the Property Manager or in the menu under Project → YourProjectName 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:
        • "$(ProjectDir)\vstsdk2.4" (or wherever you put the VST SDK)
        • "$(ProjectDir)\vstsdk2.4\public.sdk\source\vst2.x"
        • Your source code directory
        • Any other directories which you may have header files stored in
    • Preprocessor:
      • Preprocessor Definitions: WINDOWS;_WINDOWS;WIN32;_USRDLL;_USE_MATH_DEFINES
      • You may also wish to add DEBUG=1;_DEBUG=1 for Debug builds
      • If you wish to use PNG graphics for a VSTGUI frontend, add USE_LIBPNG=1.
      • _CRT_SECURE_NO_DEPRECATE is also nice to define, or else you'll get lots of compiler nags and warnings.
      • It also may be necessary to define VST_FORCE_DEPRECATED=0 in some circumstances.
    • 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:
        • Create/Use Precompiled Header: Not Using Precompiled Headers
      • Browse Information:
        • Enable Browse Information: None
      • Advanced:
        • Compile As: Default
    • 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 (optional)
          • libpng.lib (optional)
        • Additional Dependencies (for Debug builds):
          • shell32.lib
          • msvcrtd.lib
          • ole32.lib
          • gdi32.lib
          • User32.lib
          • advapi32.lib
          • zlib.lib (optional)
          • libpng.lib (optional)
        • Ignore Specific Library (for Release builds):
          • msvcrt.lib
          • libc.lib
          • msvcrtd.lib
          • libcd.lib
          • libcmtd.lib
        • Ignore Specific Library (for Debug builds):
          • libcmt.lib
          • libcmtd.lib
          • msvcrt.lib
        • Module Definition File: YourProjectName.def
    Step 6: Adding support for VSTGUI (optional)

    To 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
    Step 7: 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 "projects\visualc71" 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 CVS. 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.

    Next, you need your actual graphics to the project. Unfortunately, VC++ Express does not include a resource editor, as this is one of the features in the commercial versions of Visual Studio. However, making the changes by hand is not too difficult. In the YourProjectName.rc file, add references to your graphics in the DATA section like so:


    IDB_BITMAP1 PNG DISCARDABLE "../resources/bmp10001.png"
    IDB_BITMAP2 PNG DISCARDABLE "../resources/bmp10002.png"


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


    #define IDB_BITMAP1 1
    #define IDB_BITMAP2 2


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

    Final considerations

    Compiler optimization
    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.

    Disabling parallel builds
    If you are developing on a multi-core machine, then you should disable parallel builds by setting the number of parallel builds to 1 under Tools → Options → Projects and Solutions → Build and Run.  VS does not always link your projects in the order which you would expect it to, and this causes errors during linking with missing symbols.  This behavior may be fixed in more recent builds of VC++, but as of this writing, I was still having experiencing this problem.

    Disabling intellisense
    VC++ includes a technology called intellisense which indexes one's source code to create nifty little menus for tab-completing functions, variables, and other stuff.  Compared to IDE's like IntelliJ and Eclipse, the suggestions shown in these menus are not always logically sorted and do not always determine class relationships.  While intellisense can be somewhat helpful, but it also uses a lot of CPU and frequently runs in the background, which can be very irritating with large projects or when working on slower machines.  To disable intellisense, delete the following file (when VC++ is closed): \VC\vcpackages\feacp.dll. This will not effect VC++ in any way other than it not being able to run intellisense on your projects anymore.

    3 comments:

    Anonymous said...

    thanks a lot for this tutorial

    Anonymous said...

    Hi, I'm getting unresolved externals linker errors for audioeffect.obj for vst_strncpy _imp_strncpy and _imp_floor and _imp_strncat.
    Any idea what might cause this. I have added audioeffedct.cpp and .h to the project? I'm using Visual Studio 2008.
    whatsdtrad@gmail.com

    Anonymous said...

    sorted my linker errors
    did not distinguish between release and debug configuration for .lib files
    Many thanks for this tutorial
    whatsdtrad@gmail.com

    Post a Comment