!j development
Programming Article:
Designing VST plugins completely 'visual' with
Borland® C++Builder®
by !jdev
©2003-2006 !j development division audio
This article is copyrighted. All rights reserved. Don't publish entirely
or parts without explicit permission.
Vision: Imagine, you could develop native VST plugins based on
a modular visual component library with drag and drop and complete access
to the C/C++ source code.

The image above shows our VCL extension inside C++Builders component palette.
About 25 components and controls encapsulate the entire VST 2.3 SDK including
the VSTGUILib 2.2.
Introduction
We have seen so many Visual Component Library (VCL®) extensions for
Borland C++Builder® on the Windows® platform, but not even one
for building VST® plugins with Steinbergs Virtual Studio Technology.
There may be some stuff available for Delphi, but not as a complete integration
of the VST SDK and even no one such a concept for C++Builder.
Normally one uses Microsoft's® Visual C++® to build VST plugins
on Windows, because the core Interface (provided by Steinberg®) is
supplied for this compiler. This leads in some difficulties - even for
beginners - because the core VST interface is pure (platform independent)
C/C++ hack and the development of the graphical user interface (GUI) for
VST plugins must be done also with rough source code based programming
and linked resource files.
The current state is absolutely unsatisfactory, because the developer
has no possibility to "see" what he is designing in realtime.
He codes GUIs rather than design it. This is time consuming and the result
often somehow "ugly".
The developer also has to spend quite allot time to understand the often
unsatisfactory documented VST and VSTGUILib header files and to understand
all the nifty things around the interfaces. One has often to develop a
minimalist debug-able host application to debug and somehow comfortable
design the plugins interface, because most of the hosts applications don't
support designing and debugging of plugins directly or make it very difficult.
Plugins are even not directly executable and need a host application to
execute. This finally results in endless compiling, loading and testing
the plugins on the host applications on each little change of the plugins
source code. Especially the GUI development can lead into pure horror
with this.
Note: There are some other visual design techniques out there, where
the user can create VST plugins on demand by using modular elements. But
the result is neither a native plugin nor has the user access to the source
code. Mostly the possibilities are limited by the availability of third
party components and the direct support and implementation of such building
systems. Those techniques are not part of the discussion here.
So it would be a good thing to do something with the "magic"
Borland Visual Programming techniques, where you simply drag and drop
some components on a form and compile it to a ready to use plugin application.
In this way, the developer can concentrate to the really important things,
like DSP coding and the (realtime) visual design of the user interface.
Of course this will be neither platform independent, nor compiler independent
but very productive with platform specific development. In this case Windows
specific.
Borland's compilers ( or better: Integrated Development Environments
(IDEs) ) do an excellent job in supporting developers with true "Visual
Design". No matter which Borland IDE you use (Delphi or C++Builder),
all use the VCL or similar component libraries. The VCL has its roots
on Object Pascal (initially developed for Delphi) and is also completely
implemented into C++Builder. The VCL is an extendable component based
code library with full designtime support.
The entire Borland concept is in our opinion somehow better than the Microsoft
Visual Basic® or Visual C++® or C# concept, because the Borland
component system is not limited to external COM objects (ActiveX) or Microsoft's
new .NET Framework. You design components more in the manner of "reusable
code" or code libraries, which can be directly compiled into the
final applications and plugins.
The clou is, that you can use also VCL components written in Object Pascal
inside C++Builder and write your own either in Object Pascal or even C/C++
( this is not possible vice versa with Delphi ). Reuse of code libraries,
visual or none-visual is a cake with Borland C++Builder and predestined
for our project. Nevertheless our components project will be designed
100% in pure C++.
The Project
Step1: To realize our project, we need at first to encapsulate Steinbergs
core VST Interface.
The plan was to design easy to use modular components, which can be dropped
to a standard VCL form (the window). The components (4 connectable base
components) encapsulate the entire skeleton of a ready to use VST 2.3
plugin. This is also supports VST and MIDI events and synthesizers.
The four base VST components are:
- TVSTEffectX, the effect base component
- TVSTEventDispatcher, optional component to provide
VSTEvent, VSTMidiEvent support
- TVSTSysExProvider, an additional extension to provide
SysEx support with VST
- TVSTParameter, the base component for handling the
parameters of a VST plugin
NEW:
A few days after the release of the Steinberg VST
Module Architecture, we have started the development of a new component:
- TVSTModule, the new MIDI module base component
With this component and the VSTGUI components below, you can design new
MIDI plugins for Steinberg's VST Module Architecture. The usage differs
not so much from the development of normal VST plugins with our component
package. You design MIDI modules completely visual with C++Builder, using
the VSTGUILib in realtime.
We also prepare a startup Template for VST Module plugins.
Note: The "T" before the components class name is a Borland
VCL naming convention.
The Template
The project requires at least, that C++Builder is able to generate a
DLL project, which is 100% compatible with the host applications (mostly
developed with Microsoft's compilers). Off course is C++Builder able to
do that.
We generate a DLL template project in Visual C++ style, include VCL support
and add some initializations code to prepare the VST entry point, the "main"
function. Then we add a module definition file to rename the per default
generated "_main" export symbol to "main". This is
necessary, because C++Builder adds normally an underscore to export functions.
But the hosts scan only for "main" functions and not "_main".
Inside the main function we initialise our main component and create
the audio effect class with its own VCL driven Editor. ( Previously we
have included a Form (window) to the project dropped our VST base components
on this Form. )
This is all. If we compile the project, we have at least a complete VST
plugin with its own window, which does actually nothing special, but prepares
all the functionality needed for the VST audio process, for instance MIDI
automation, programs and banks, SysEx support multi output and so on.
All aspects of our VST plugin can now be edited completely "visual"
with C++Builders property editor.
//---------------------------------------------------------------------------
// ©2003 !j development VST®ToolKit. All rights reserved.
// BUFFERSCOPE 2 for Borland C++Builder® 5/6
//---------------------------------------------------------------------------
#include <vcl.h>
#include <windows.h>
#pragma hdrstop
#pragma option -a8
/*---------------------------------------------------------------------------
VST SDK (Version 2.3)
©1999, Steinberg Soft und Hardware GmbH, All Rights Reserved.
©2002, Steinberg Media Technologies AG, All Rights Reserved.
©2003, Steinberg, The Audio Group of Pinnacle Systems Inc.
All Rights Reserved.
---------------------------------------------------------------------------*/
#include "AEffect.h"
#include "AudioEffect.cpp"
#include "audioeffectx.cpp"
#include "Unit1.h"
//---------------------------------------------------------------------------
static AudioEffect *effect = NULL;
//---------------------------------------------------------------------------
extern "C"{
AEffect* __cdecl main (audioMasterCallback
audioMaster); }
AEffect *main (audioMasterCallback audioMaster)
{
if ( !audioMaster(0, audioMasterVersion,
0, 0, 0, 0) )
return NULL;
TEditor* Editor = new
TEditor(NULL);
if (Editor)
{
effect = Editor->VSTPlugin->Create(audioMaster);
if
(!effect)
{
delete
Editor;
ShowMessage("VSTPlugin::main:
The effect class for BufferScope2 could not be \n\
created.");
return
NULL;
}
return
effect->getAeffect();
}
ShowMessage("VSTPlugin::main: The editor class
for BufferScope2 could not be created.");
return NULL;
}
//---------------------------------------------------------------------------
#pragma argsused
void* hInstance = NULL;
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fwdreason, LPVOID lpvReserved)
{
hInstance = hinstDLL;
return TRUE;
}
//---------------------------------------------------------------------------
This works, because our underlying VST component is a really complex wrapper
class, which has some heavy built in logic to do all the generic stuff
for us.
But the principe should be very clearly here: We want to provide an easy
to use "drag and drop" component and a simple generic template
to make building VST plugins on Microsoft Windows with Borland C++Builder
a snap.

This can be the result of our ready to use project. You see the Borland
C++Builder 5 visual designing a VST plugin, including a main window, a
separate about box and a trace window for special debug diagnostics, all
design based on the standard VCL and our extensions to it. The example
shows the downloadable example application called "BufferScope2",
which is a simple but impressive MIDI automate able volume leveler effect
with inbuilt stereo oscillograph and error tracing. The plugin supports
all basic Windows elements, like windows, popup menus, text fields, hints,
list boxes and so on.
Step 2: To complete our component library for VST, we have also developed
a VCL extension with graphical controls based on the Steinberg VSTGUILib,
an optional GUI framework for VST plugins. We will encapsulate and extend
the about 20 controls for a very easy usage while designtime with C++Builder.
The user drops those controls on a VSTCFrame base component on the C++Builder
Form and designs the visual appearance of the entire plugin GUI in WYSIWYG
mode.
The controls will be connected with the base plugin components via the
C++Builder object inspector and only a few lines of additional code create
a very complex functionality for our plugin. The encapsulated objects
are fully accessible while runtime, so the core developer works like usually
with the VST SDK and VSTGUILib code.
Additionally we have extended the possibilities of the VSTGUILib to load
JPEG images while design- and runtime from files. Skin able interfaces
are easy to implemented, based on this technique.
Never was is so easy to develop new plugins for VST. What formerly was
done in months, we can do now inside a few hours.
Following VSTGUILib components are available:
- TVSTCFrame, base component for all VSTGUI controls
- TVSTCViewContainer, encapsulates CViewContainer for
designtime support
- TVSTCCanvas, encapsulates CDrawContext for designtime
support
- TVSTCKnob, encapsulates CKnob for designtime support
- TVSTCOnOffButton, encapsulates CCOnOffButton for designtime
support
- TVSTCParamDisplay, encapsulates CParamDisplay for designtime
support
- TVSTCTextEdit, encapsulates CTextEdit for designtime
support
- TVSTCOptionMenu, encapsulates COptionMenu for designtime
support
- TVSTCAnimKnob, encapsulates CAnimKnob for designtime
support
- TVSTCVerticalSwitch, encapsulates CVerticalSwitch for
designtime support
- TVSTCHorizontalSwitch, encapsulates CHorizontalSwitch
for designtime support
- TVSTCRockerSwitch, encapsulates CRockerSwitch for designtime
support
- TVSTCMovieBitmap, encapsulates CMovieBitmap for designtime
support
- TVSTCMovieButton, encapsulates CMovieButton for designtime
support
- TVSTCAutoAnimation, encapsulates CAutoAnimation for
designtime support
- TVSTCVerticalSlider, encapsulates CVerticalSlider for
designtime support
- TVSTCHorizontalSlider, encapsulates CHorizontalSlider
for designtime support
- TVSTCSpecialDigit, encapsulates CSpecialDigit for designtime
support
- TVSTCKickButton, encapsulates CKickButton for designtime
support
- TVSTCSplashScreen, encapsulates CSplashScreen for designtime
support
- TVSTCVuMeter, encapsulates CVuMeter for designtime
support
Note: It is also possible to use other GUI libraries for our plugin.
The "Bufferscope2" plugin uses for instance our !j development
PlusControls library, a high quality GUI framework, based on Microsoft's
new GDI+ interface. There are much more things possible (i.e. antialiased
text and vector graphics and real alpha blending) than the platform independent
VSTGUILib can offer.
Step 3: A VST plugin is not much worth, if we have no variety of basic
audio processing classes. Finally we want to code new audio plugins, which
are somehow useful. So we design additionally a independent VCL extension
with some ready to use DSP algorithms and ready to use complete "engines".
This library should be extendable and independent from our VST plugin
components. One can imagine the DSP Lib as a kind of modular DSP source
code components.
For a basic set of DSP opcodes, the following components are currently
being adapted:
- TBuffer,
- TInterpolator,
- TMixer,
- TPitchConverter,
- TVAOscillators,
- TWavetable,
- TWavetableOscillator,
- TSVFilter6db,
- TSVFilter12db,
- TSVFilter24db,
- TLFO,
- TEnvelope,
- TModMatrix,
- TFFT,
- TReverb,
- TDelay,
- TChorus,
- TPhaser,
- TDistortion,
- TLimiter,
- TEqualizer,
- ...

One can download the compiled BufferScope2 visual example effect plugin created with C++Builder 5: BufferScope2.dll
Tip: Use the right mouse
button to invoke an option menu for several operation modes.
There is also a demonstration application for the different widgets of the VSTGUI lib. This application is also created with C++Builder 5: VSTControls.zip
This program includes a first demonstration of our VarioSkin© tool for the CBuilder VST component library described in this article. An example *.ini file for loading a generic user interface for an imaginary plugin (including the images) is attached.
|