2: Building the AGain example

This 2nd tutorial will explain how to build the AGain plugin demo which comes with the VST SDK. We will be using MinGW and Scons (which you should have up and running after reading the previous tutorial) to do the job. AGain is a pretty unexciting plugin which just adjusts the gain applied to an input signal and sends it to the output, however, you will be able to do a lot more interesting stuff once you understand the basic framework of the source files in this example. This is what the plugin and interface look like in VSTHost.

again

I personally like to leave the SDK folder in the root of my c:\ drive and then build plugins in a different folder, for example “My Documents\VSTdev” or something similar but this is up to you. The first step is to copy the AGain directory and its contents to your development directory and then in this copied directory make a plain text file named SConstruct with no extension. Load this file up in your preferred text editor and then paste in the following build script.

# Scons build script for ADelay demo in VSTsdk v2.4
#
# bmoviehorror - Feb 2009

#Adjust the following line to suit your setup
vstPlugName = 'again'
vstSDKDir = 'C:\\vstsdk2.4'

#This line tells the compiler where the sdk is so it can find the necessary include files
env = Environment(CPPPATH= vstSDKDir, tools=['mingw'])

#This line sets some optional compiler flags
#  -Wall shows all warnings during the build
#  -O3 MAkes the output dll highly optimised (fast)
env['CCFLAGS'] = ['-Wall -O3']

#The shared library command makes scons build a dll under windows.
#At this stage we specify all the source files in the project.
env.SharedLibrary(vstPlugName, [
          vstPlugName+'.cpp',
          vstSDKDir+'\\public.sdk\\source\\vst2.x\\audioeffect.cpp',
          vstSDKDir+'\\public.sdk\\source\\vst2.x\\audioeffectx.cpp',
          vstSDKDir+'\\public.sdk\\source\\vst2.x\\vstplugmain.cpp'])

Hopefully there are enough comments in there to make each stage clear. Those readers who are familiar with the make tool can accomplish the same this with the following script. It is a lot longer and less intuitive than the SCons script in my opinion. The original can be found at http://schmid.dk/wiki/index.php/VST_Plug-ins

# change this to the location of your unpacked VST SDK:
VSTSDKDIR = ../vstsdk2.4

CPP       = g++.exe
OBJ       = PLUGINNAME.o $(VSTSDKDIR)/public.sdk/source/vst2.x/vstplugmain.o $(VSTSDKDIR)/public.sdk/source/vst2.x/audioeffect.o $(VSTSDKDIR)/public.sdk/source/vst2.x/audioeffectx.o
LIBS      = -L. --add-stdcall-alias -lole32 -lkernel32 -lgdi32 -luuid -luser32 -mwindows --no-export-all-symbols --def PLUGINNAME.def
CXXINCS   = -I"$(VSTSDKDIR)/pluginterfaces/vst2.x" -I"$(VSTSDKDIR)/public.sdk/source/vst2.x" -I"$(VSTSDKDIR)" -I"$(VSTSDKDIR)/vstgui.sf/vstgui" -I.
BIN       = PLUGINNAME.dll
CXXFLAGS  = $(CXXINCS) -DBUILDING_DLL=1 -mwindows -O3
RM        = rm -f

.PHONY: all clean

all: PLUGINNAME.dll

clean:
        ${RM} $(OBJ) $(BIN)

DLLWRAP   = dllwrap.exe
DEFFILE   = libPLUGINNAME.def
STATICLIB = libPLUGINNAME.a

$(BIN): $(OBJ)
        $(DLLWRAP) --output-def $(DEFFILE) --driver-name c++ --implib $(STATICLIB) $(OBJ) $(LIBS) -o $(BIN)

PLUGINNAME.o: PLUGINNAME.cpp
        $(CPP) -c PLUGINNAME.cpp -o PLUGINNAME.o $(CXXFLAGS)

$(VSTSDKDIR)/public.sdk/source/vst2.x/vstplugmain.o: $(VSTSDKDIR)/public.sdk/source/vst2.x/vstplugmain.cpp
        $(CPP) -c $(VSTSDKDIR)/public.sdk/source/vst2.x/vstplugmain.cpp -o $(VSTSDKDIR)/public.sdk/source/vst2.x/vstplugmain.o $(CXXFLAGS)

$(VSTSDKDIR)/public.sdk/source/vst2.x/audioeffect.o: $(VSTSDKDIR)/public.sdk/source/vst2.x/audioeffect.cpp
        $(CPP) -c $(VSTSDKDIR)/public.sdk/source/vst2.x/audioeffect.cpp -o $(VSTSDKDIR)/public.sdk/source/vst2.x/audioeffect.o $(CXXFLAGS)

$(VSTSDKDIR)/public.sdk/source/vst2.x/audioeffectx.o: $(VSTSDKDIR)/public.sdk/source/vst2.x/audioeffectx.cpp
        $(CPP) -c $(VSTSDKDIR)/public.sdk/source/vst2.x/audioeffectx.cpp -o $(VSTSDKDIR)/public.sdk/source/vst2.x/audioeffectx.o $(CXXFLAGS)

Anyhow, back to our build. Using your console application, navigate to the AGain directory in your development directory and give the following command

scons

If all goes according to plan you will see the following output in your command window. If scons exits with an error or build terminated warning, then please carefully read over tutorial #1 again.

 

scons: Reading SConscript files ...
c:\Python26\Lib\site-packages\scons-1.1.0\SCons\Platform\posix.py:38: DeprecationWarning: The popen2 module is deprecated. Use the subprocess module.
import popen2
c:\Python26\Lib\site-packages\scons-1.1.0\SCons\Tool\msvs.py:37: DeprecationWarning: the md5 module is deprecated; use hashlib instead
import md5
scons: done reading SConscript files.
scons: Building targets ...
g++ -o again.o -c "-Wall -O3" -IC:\vstsdk2.4 again.cpp
again.cpp:27:15: warning: multi-character character constant
g++ -o C:\vstsdk2.4\public.sdk\source\vst2.x\audioeffect.o -c "-Wall -O3" -IC:\vstsdk2.4 C:\vstsdk2.4\public.sdk\source\vst2.x\audioeffect.cpp
g++ -o C:\vstsdk2.4\public.sdk\source\vst2.x\audioeffectx.o -c "-Wall -O3" -IC:\vstsdk2.4 C:\vstsdk2.4\public.sdk\source\vst2.x\audioeffectx.cpp
g++ -o C:\vstsdk2.4\public.sdk\source\vst2.x\vstplugmain.o -c "-Wall -O3" -IC:\vstsdk2.4 C:\vstsdk2.4\public.sdk\source\vst2.x\vstplugmain.cpp
g++ -shared -o again.dll again.o C:\vstsdk2.4\public.sdk\source\vst2.x\audioeffect.o C:\vstsdk2.4\public.sdk\source\vst2.x\audioeffectx.o C:\vstsdk2.4\public.sdk\source\vst2.x\vstplugmain.o -Wl,--out-implib,libagain.a -Wl,--output-def,again.def
Creating library file: libagain.a
scons: done building targets.

Success! The plugin .dll will now be located in the same directory as your SConstruct file and is ready to load into a vst host. If you want to clean up all of the files generated in the build, including the output .dll, issue the following command . . .

scons -c

If you wish to rebuild the sources again then re-issue

scons

If the plugin has built successfully, then now would be a good time to really understand how the plugin is functioning. Head on over to Euphoria Audio and look at this tutorial http://www.euphoriaaudio.com/tutorials/vstexample/vstexample1.php .Once you understand how this works then have a go at modifying the source to crossfade between the input signal and noise or something similar. Another good resource is the tremolo example at Euphoria Audio http://www.euphoriaaudio.com/tutorials/tremolo/tremolo1.php . Once comfortable with these simple demos we will move on to building the ADelay example which comes with the sdk and its big brother Surrounddelay, which has a custom GUI.

Have fun and see you in tutorial 3!

 

  1. Jeff Minnear
    October 30, 2009 at 02:27

    Whenever I run scons I get a message that there is a syntax error in line 6. Is this the correct line?

    06.vstPlugName = ‘again’

    • October 30, 2009 at 12:37

      This is a nice simple one to fix. What it appears that you have done is to copy the text from your web browser including the line numbers on the left! What you need to do is hover your mouse over the code on my webpage and then click the copy source to clipboard link in the top right. You can then paste the source into your SConstruct file **without** the line numbers and all should work out fine.

  2. Kamran
    November 4, 2009 at 22:03

    Can you tell me Please what is wrong here!!! I installed mingw compiler and rest successfully as you described. But the following errors received after using command “scons”….

    I need your help, Thanks in advance….

    C:\Documents and Settings\Kamran\My Documents\VSTdev\again\source>gcc -v
    Reading specs from c:/mingw/bin/../lib/gcc/mingw32/3.4.5/specs
    Configured with: ../gcc-3.4.5-20060117-3/configure –with-gcc –with-gnu-ld –wi
    th-gnu-as –host=mingw32 –target=mingw32 –prefix=/mingw –enable-threads –dis
    able-nls –enable-languages=c,c++,f77,ada,objc,java –disable-win32-registry –d
    isable-shared –enable-sjlj-exceptions –enable-libgcj –disable-java-awt –with
    out-x –enable-java-gc=boehm –disable-libgcj-debug –enable-interpreter –enabl
    e-hash-synchronization –enable-libstdcxx-debug
    Thread model: win32
    gcc version 3.4.5 (mingw-vista special r3)

    C:\Documents and Settings\Kamran\My Documents\VSTdev\again\source>scons -v
    SCons by Steven Knight et al.:
    engine: v1.2.0.d20090919.r4369[MODIFIED], 2009/09/19 16:58:54, by scons
    on scons-dev
    Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 The SCons Fou
    ndation

    C:\Documents and Settings\Kamran\My Documents\VSTdev\again\source>scons
    scons: Reading SConscript files …
    scons: done reading SConscript files.
    scons: Building targets …
    g++ -o again.o -c “-Wall -O3” -IC:\vstsdk2.4 again.cpp
    In file included from again.cpp:13:
    again.h:16:51: public.sdk/source/vst2.x/audioeffectx.h: No such file or director
    y
    In file included from again.cpp:13:
    again.h:20: error: expected class-name before ‘{‘ token
    again.h:22: error: expected `)’ before “audioMaster”
    again.h:26: error: `VstInt32′ has not been declared
    again.h:26: error: ISO C++ forbids declaration of `sampleFrames’ with no type
    again.h:27: error: `VstInt32′ has not been declared
    again.h:27: error: ISO C++ forbids declaration of `sampleFrames’ with no type
    again.h:34: error: `VstInt32′ has not been declared
    again.h:34: error: ISO C++ forbids declaration of `index’ with no type
    again.h:35: error: `VstInt32′ has not been declared
    again.h:35: error: ISO C++ forbids declaration of `index’ with no type
    again.h:36: error: `VstInt32′ has not been declared
    again.h:36: error: ISO C++ forbids declaration of `index’ with no type
    again.h:37: error: `VstInt32′ has not been declared
    again.h:37: error: ISO C++ forbids declaration of `index’ with no type
    again.h:38: error: `VstInt32′ has not been declared
    again.h:38: error: ISO C++ forbids declaration of `index’ with no type
    again.h:43: error: `VstInt32′ does not name a type
    again.h:47: error: `kVstMaxProgNameLen’ was not declared in this scope
    again.h:20: warning: `class AGain’ has virtual functions but non-virtual destruc
    tor
    again.cpp:16: error: expected constructor, destructor, or type conversion before
    ‘*’ token
    again.cpp:22: error: expected `)’ before “audioMaster”
    again.cpp:27:15: warning: multi-character character constant
    again.cpp: In member function `virtual void AGain::setProgramName(char*)’:
    again.cpp:44: error: `programName’ was not declared in this scope
    again.cpp:44: error: `kVstMaxProgNameLen’ was not declared in this scope
    again.cpp:44: error: `vst_strncpy’ was not declared in this scope
    again.cpp:44: warning: unused variable ‘programName’
    again.cpp:44: warning: unused variable ‘kVstMaxProgNameLen’
    again.cpp:44: warning: unused variable ‘vst_strncpy’
    again.cpp: In member function `virtual void AGain::getProgramName(char*)’:
    again.cpp:50: error: `programName’ was not declared in this scope
    again.cpp:50: error: `kVstMaxProgNameLen’ was not declared in this scope
    again.cpp:50: error: `vst_strncpy’ was not declared in this scope
    again.cpp:50: warning: unused variable ‘programName’
    again.cpp:50: warning: unused variable ‘kVstMaxProgNameLen’
    again.cpp:50: warning: unused variable ‘vst_strncpy’
    again.cpp: At global scope:
    again.cpp:54: error: variable or field `setParameter’ declared void
    again.cpp:54: error: `int AGain::setParameter’ is not a static member of `class
    AGain’
    again.cpp:54: error: `VstInt32′ was not declared in this scope
    again.cpp:54: error: expected primary-expression before “float”
    again.cpp:55: error: initializer expression list treated as compound expression
    again.cpp:55: error: expected `,’ or `;’ before ‘{‘ token
    again.cpp:60: error: `float AGain::getParameter’ is not a static member of `clas
    s AGain’
    again.cpp:60: error: `VstInt32′ was not declared in this scope
    again.cpp:61: error: expected `,’ or `;’ before ‘{‘ token
    again.cpp:66: error: variable or field `getParameterName’ declared void
    again.cpp:66: error: `int AGain::getParameterName’ is not a static member of `cl
    ass AGain’
    again.cpp:66: error: `VstInt32′ was not declared in this scope
    again.cpp:66: error: expected primary-expression before “char”
    again.cpp:67: error: initializer expression list treated as compound expression
    again.cpp:67: error: expected `,’ or `;’ before ‘{‘ token
    again.cpp:72: error: variable or field `getParameterDisplay’ declared void
    again.cpp:72: error: `int AGain::getParameterDisplay’ is not a static member of
    `class AGain’
    again.cpp:72: error: `VstInt32′ was not declared in this scope
    again.cpp:72: error: expected primary-expression before “char”
    again.cpp:73: error: initializer expression list treated as compound expression
    again.cpp:73: error: expected `,’ or `;’ before ‘{‘ token
    again.cpp:78: error: variable or field `getParameterLabel’ declared void
    again.cpp:78: error: `int AGain::getParameterLabel’ is not a static member of `c
    lass AGain’
    again.cpp:78: error: `VstInt32′ was not declared in this scope
    again.cpp:78: error: expected primary-expression before “char”
    again.cpp:79: error: initializer expression list treated as compound expression
    again.cpp:79: error: expected `,’ or `;’ before ‘{‘ token
    again.cpp: In member function `virtual bool AGain::getEffectName(char*)’:
    again.cpp:86: error: `kVstMaxEffectNameLen’ was not declared in this scope
    again.cpp:86: error: `vst_strncpy’ was not declared in this scope
    again.cpp:86: warning: unused variable ‘kVstMaxEffectNameLen’
    again.cpp:86: warning: unused variable ‘vst_strncpy’
    again.cpp: In member function `virtual bool AGain::getProductString(char*)’:
    again.cpp:93: error: `kVstMaxProductStrLen’ was not declared in this scope
    again.cpp:93: error: `vst_strncpy’ was not declared in this scope
    again.cpp:93: warning: unused variable ‘kVstMaxProductStrLen’
    again.cpp:93: warning: unused variable ‘vst_strncpy’
    again.cpp: In member function `virtual bool AGain::getVendorString(char*)’:
    again.cpp:100: error: `kVstMaxVendorStrLen’ was not declared in this scope
    again.cpp:100: error: `vst_strncpy’ was not declared in this scope
    again.cpp:100: warning: unused variable ‘kVstMaxVendorStrLen’
    again.cpp:100: warning: unused variable ‘vst_strncpy’
    again.cpp: At global scope:
    again.cpp:105: error: `VstInt32′ does not name a type
    again.cpp:111: error: `VstInt32′ has not been declared
    again.cpp:112: error: ISO C++ forbids declaration of `sampleFrames’ with no type

    again.cpp:126: error: `VstInt32′ has not been declared
    again.cpp:127: error: ISO C++ forbids declaration of `sampleFrames’ with no type

    scons: *** [again.o] Error 1
    scons: building terminated because of errors.

  3. November 5, 2009 at 01:33

    YOu have the compiler and scons set up fine. All that error message stuff is resultant from this one problem:

    again.h:16:51: public.sdk/source/vst2.x/audioeffectx.h: No such file or director
    y

    Double check you followed my instructions in this tutorial to the letter as it cant find that header file.

  4. Kamran
    November 12, 2009 at 07:35

    Thanks,
    I was making the following mistake
    c:\vst_sdk2_4_rev2\vstsdk2.4\…

    Correct path as following
    C:\vstsdk2.4\…

    You have done a very nice work…I would like to say you thanks for this tutorial once again….

    • November 12, 2009 at 15:21

      Glad you got it all working 🙂 Best of luck on your VST development journey!

      • Chris
        July 20, 2010 at 07:21

        I have tried and retried this a million times and I just cannot seem to get the directories right. The tutorial is vague on how to configure the directory in the SConstruct file. I am having the same Exact problem as KAMRAN. same error message. Ive tried everything. Please help. does running a 64 bit OS make a difference?

  5. Zach
    November 22, 2009 at 17:56

    Whenever I run scons I get this output:

    scons: Reading SConscript file
    scons: done reading SConscript
    scons: Building targets …
    scons: `.’ is up to date.
    scons: done building targets.

    It doesn’t seem to have any errors, but it doesn’t produce anything. Any idea what I’m doing wrong?

    • November 24, 2009 at 16:59

      .dll should just be in the same folder as your SConscript. If its not there, try:

      scons -c
      scons

      . . and it should just rebuild rather than telling you everything is up to date.

  6. Jure
    January 14, 2010 at 21:30

    Hi!

    Just found your page and is totally awesome for a beginner like me.
    I just tried to build AGain project using MiniGW compiler & sCons, but i get following error:

    E:\Moji Dokumenti\Dokumenti\Diploma\Builds\AGain Test>scons
    scons: Reading SConscript files …
    scons: done reading SConscript files.

    scons: *** MSVC error while executing C:\Program Files (x86)\Microsoft Visual St
    udio 9.0\VC\vcvarsall.bat with args amd64 (error was The specified configuration
    type is missing. The tools for the
    configuration might not be installed.)
    File “C:\Python25\Lib\site-packages\scons-1.2.0.d20091224\SCons\Tool\MSCommon\vc
    .py”, line 351, in msvc_setup_env

    Do you have any idea what could be wrong?
    I guess there is some conflict between MinGW or. SCons and Visual Studio (VC++), which I have also installed.
    Or maybe becouse I installed x86 version of Phyton, ‘couse when i insalled 64bit version SCons could not recognize installed Python.

    Anyway maybe I’m just complicating a little with this command line build – I managed to build the project in Visual Studio, but I just dont like it. As you said too many unnecessary files & stuff.

    Well tnx for the help. Keep it rollin’ 🙂

    • Jure
      January 15, 2010 at 01:06

      hi again!

      sorry for the mess, but i got it working. 🙂 i’ll describe the solution if somebdy is having similar problems.

      still dont know the exact reason..but i presume the error occured becouse of 64bit wins & becouse by default Scons wants to use MSVC compiler which does not work with 64, so I commented out lines that check existance of MSVC from the Scons Script: C:\Python25\Lib\site-packages\scons-1.2.0.d20091224\SCons\Tool\MSCommon\vc.py
      if fact I commented out lines of the VisualStudio path in lines 116 – 129.

      So after this change scons is able to build targets.
      If you know the exact reason why this happend please tell me, couse I could be totally wrong 😀

      • January 19, 2010 at 09:14

        I’ve never seen that error before. Seems strange that SCons is doing anything with MSVC when we use the following in the SConstruct file

        tools=[‘mingw’]

        . . . anyway, I’m glad you got it working.

        Thanks for the comments.

  7. Owen
    February 26, 2010 at 23:58

    Hi

    Well, I managed to compile ‘again’!!

    Great!

    This is the first time I have ever done anything like this and it feels great!

    A few things about the tutorial, which I found a little confusing, and you may need to clear up…

    1. You really do need to omit those line numbers from the code. I notice that one reader had an issue with this, and I nearly did, but decided to omit them and it worked. Just plain code with no line numbers would be fine!

    2. Regarding the SConstruct file; you need to make it a little clearer what you mean by ‘make a file with no extension’. I figured this out, but a real beginner may need help.

    3. You need to explain what this line means;

    again.cpp:27:15: warning: multi-character character constant

    I got this warning too, and thought something was not compiling correctly. Everything was OK, in the end, but warnings like this usually mean something is not working perfectly.

    4. The SConstruct file location is very ambiguous; it needs to be in the same directory as the .cpp and .h files, or nothing will work. Seems obvious, I know, but your instructions do not explicitly mention this.

    Otherwise, fantastic!

    You know a hell of a lot more than me about this, and I just wanted to make things clear for other readers, so thank you once again, and I look forward to working through the rest of your tutorials!

    Great!!

  8. Jakub Kúdela
    November 19, 2011 at 18:19

    Hi there, while compiling using your SConstruct script I got this error message:

    C:\User\********\Documents\VST Development\again\source\scons
    scons: Reading SConscript files …
    scons: done reading SConscript files.
    scons: Building targets …
    g++ -o again.o -c “-Wall -O3” -IC:\vstsdk2.4 again.cpp
    cc1plus.exe: error: unrecognized command line option ‘-Wall -O3’
    scons: *** [again.o] Error 1
    scons: building terminated because of errors.

    I guess the MinGW compilers have changed since this tutorial was written, because of uknown flags “-Wall -O3”. I am using “MinGW-Get version 0.4-alpha-1”. Is this the problem? I had commented the flag line (#env[‘CCFLAGS’] = [‘-Wall -O3’]) and it passed the compilation without any problem. Now what should I do please to get this optimalization (# -O3 Makes the output dll highly optimised (fast))

    Thank you!
    BTW nice article, it is very understandable.

  1. No trackbacks yet.

Leave a comment