vst source code archive, no-frills version
Please notice that this version does NOT contain the comments you can find in the fancy version...
You can find the fancy version here.
The PDF version of this no-frills archive can not be found anywhere, yet
Contents
Type : Equalizer plugin /w gui and FFTW
References :Posted by gsternagl[at]t-online.de (Gerald Sternagl)
Linked file : MyEQ_readme1st.txt
Linked file : MyEQ.zip
Notes :
Gerald submits source code of a whole plugin, an multiband graphical equalizer. It features graphics using VSTGUI and processing using FFTW (source and description included)
The included project file is for MSVC 6
Please look at the ReadMe first...
Type : Graphics Tool
References :Posted by urs@u-he.com, Tobybear
Linked file : http://www.idevgames.com/downloads/toolchest/SpriteLiner.sit
Linked file : http://www.trentsoft.com/software/trst10.exe
Notes :
I found a useful tool on the net. It works under MacOS X (maybe 9 with CarbonLib) and is initially intended for game developers. Source Code is available, too, from the developer's homepage at http://www.silverstreaksoftware.com.
If you have a set of TIFFs, numbered 0.tiff to N.tiff, this tool creates a single TIFF with all images tiled. If you set columns to 1, you get an image with all subpixmaps stacked vertically for use as CAnimKnob resource pic.
There is an equivalent for Windows, too, TrentStitch at http://www.trentsoftware.com
Yet, the pain generating the single bitmaps of a rotated knob remains...
;) Urs
Type : Phaser
References :Posted by sureshotstudiovst@hotmail.com
Linked file : http://www.sureshotstudio.cjb.net//VST.htm
Notes :
www.sureshotstudio.cjb.net//VST.htm
go here to download the source with the plug-in
if someone makes something cool with this code please send the source to me so i can learn from it. I'm still working on some improvements like filters in the feedback loop and some softclipping and stuff. by the Way i'm still looking for someone who can explain to how to program a gui using the vstGui library. And please send your comments to sureshotstudiovst@hotmail.com
ok now have fun!!!!!!!
greetz
thomas hopman
Type : Filehandling MacOS
References :Posted by paul.kellett@mda-vst.com
Notes :
This example code demonstrates how to convert between full paths and Mac FSSpec records.
This could be very useful for VSTs that need to import audiofiles i.e. samplers or preferences that are not included in plugin parameter files (.fxp/.fxb).
Code :
// macpaths.cpp - converts between full paths and Mac FSSpec records
//
// This code is free software. You can redistribute it and/or modify
// it without limitation. Paul Kellett (@mda-vst.com) September 2002
//
// This code will probably give real Mac programmers nightmares, but
// it works, and sometimes you want to stick with the standard C/C++
// file I/O, and to do that you need paths not the FSSpec structures
// that are returned by VSTGUI functions like openFileSelector() and
// getDirectory(). I'm publishing this code because I couldn't find
// any decent documentation on this stuff, and all the code examples
// I found depended on a load of other files. Hopfully this "quick &
// dirty" version will save someone some time.
#include <Files.h> //Mac-specific stuff
#include <stdio.h>
#include <string.h>
//path2fss makes an FSSpec from a path with or without a filename
int path2fss(FSSpec *fss, char *path)
{
char buf[256];
char *p = &buf[1];
strcpy(p, path); //convert to Str255
buf[0] = strlen(p);
return(FSMakeFSSpec(0, 0, (unsigned char *)buf, fss)); //== noErr
}
//fss2path takes the FSSpec of a file, folder or volume and returns it's path
void fss2path(char *path, FSSpec *fss)
{
int l; //fss->name contains name of last item in path
for(l=0; l<(fss->name[0]); l++) path[l] = fss->name[l + 1];
path[l] = 0;
if(fss->parID != fsRtParID) //path is more than just a volume name
{
int i, len;
CInfoPBRec pb;
pb.dirInfo.ioNamePtr = fss->name;
pb.dirInfo.ioVRefNum = fss->vRefNum;
pb.dirInfo.ioDrParID = fss->parID;
do
{
pb.dirInfo.ioFDirIndex = -1; //get parent directory name
pb.dirInfo.ioDrDirID = pb.dirInfo.ioDrParID;
if(PBGetCatInfoSync(&pb) != noErr) break;
len = fss->name[0] + 1;
for(i=l; i>=0; i--) path[i + len] = path[i];
for(i=1; i<len; i++) path[i - 1] = fss->name[i]; //add to start of path
path[i - 1] = ':';
l += len;
} while(pb.dirInfo.ioDrDirID != fsRtDirID); //while more directory levels
}
}
void main() //not plug-in code, just an example...
{
//start with a path
char path[256];
strcpy(path, "Macintosh HD:foldername:filename");
printf("Original path... %s\n", path);
//convert to FSSpec
FSSpec fss;
path2fss(&fss, path);
fss.name[fss.name[0] + 1] = 0; //fiddle to display a Str255...
printf("To FSSpec... vol=%d dir=%d name=%s\n", fss.vRefNum, fss.parID, &fss.name[1]);
//convert back to a path
fss2path(path, &fss);
printf("Back to a path... %s\n", path);
}
Type : Rotary encoders which behave as endless rotary encoder srather than as pots
References :Posted by dave@dmalham.freeserve.co.uk
Linked file : dmcontrols.zip
Linked file : dmcontrols.hpp
Linked file : dmcontrols.cpp
Notes :
There are a number of different possible knob modes which can be set (for instance, in Nuendo's 'Preferences' dialogue). Circular, Linearand the very useful Relative Circular mode,
in which you can click anywhere on the control and the knob does not jump to the new position, but instead can be dragged around. This mode is also
available when the knob is set in Circular mode by holding down the 'Alt' key when clicking on the knob. In Linear and in Relative mode, the alt key
puts you into circular mode. This is not remembered by the interface, so you have to do it each time. Please note that 'normal' VST knobs go into linear
mode if you hold down the 'Alt' key when clicking on the knob. Note also that currently you have to close down and re-open the gui to get it to see the
new mode when you set this in Nuendo's preferences dialogue.
Type : graphic XY pad
References :Posted by paul[at]expdigital.co.uk
Linked file : CTouchPad.h
Linked file : CTouchPad.cpp
Notes :
provides two outputs, going 0 - 1 which can be routed to anything you want.
Almost identical to XY COntrol pad, but provides two outputs instead of one.
Type : simple plugin for pan control
References :Posted by Michael Beer - beerml[at]freenet.de
Linked file : ms_matrix_gcc.zip
Notes :
What the author says:
The plugin is nothing special...
The .zip-file simply has to be expanded into the directory where vst2sdk resides.
You point your shell into plugins/MSmatrix and compile with
mingw32-make dirs
mingw32-make
You find the plug in plugins/win32/dll
The original VST-Examples show something about BEOS instead of __GNUC__. BEOS does use GCC, so this might probably also work with mach-o accordingly.
(translated from German by Urs, might contain errors)
Code :
To make this compilable with GCC, the *.def-File needed to change in those lines:
EXPORTS main in
EXPORTS main=main_plugin
and in your plugin's *Main.cpp:
#if __GNUC__
#define main main_plugin
extern "C" __declspec(dllexport) AEffect *main_plugin (audioMasterCallback audioMaster);
#else
AEffect *main (audioMasterCallback audioMaster);
#endif
Type : Tips & Tricks
References :Posted by dougalli
Notes :
Originally posted to VST -plugins mailing list by Yvan Grabit.
Code :
popupMenu (context)
{
CPoint where;
context->getMouseLocation (where);
CRect menuRect (0, 0, 0, 0);
menuRect.offset (where.h, where.v + 2);
menu = new COptionMenu (menuRect, this, tag, 0, 0,
kMultipleCheckStyle|kNoDrawStyle);
menu->addEntry ("Yvan");
menu->addEntry ("Grabit");
menu->setDirty (false);
editorParent->addView (menu); // editorParent which could be frame
menu->mouse (context, where);
menu->looseFocus (context);
editorParent->removeView (menu);
menu = 0;
}
Type : Glue code
References :Posted by urs[at]u-he.com
Linked file : cfm_mach_o_glue.txt
Notes :
A summary of a thread on VST list (small edits by me), mails by Stefano Daino, Angus F. Hewlett and Arne Scheffler.
Explains how to set up function pointers in a CFM based host to call correctly into a Mach-O based VST plugin.
Type : howto
References :Posted by MatWillis[at]aol.com
Notes :
1. Create a new Project, selecting .dll project type
- Delete the auto-generated cpp and hpp files
- add the VST plugin source files.
2. Copy the 'common' directory from the VST SDK to the local source directory
3. Add the following VST 'common' source files to the project
- AudioEffect.cpp
- audioeffectx.cpp
- vstgui.cpp ** modified **
- aeffguieditor.cpp
- vstcontrols.cpp
4. Add the following directories to the include search path in the Project Options/directories dialog.
- Common
- Possibly the resource directory, if any .h files needed by cpp compilation.
5. Modify the VSTNAMEEditMain.cpp file (!!!)
- #if BEOS… becomes #if __GNUC__ && (WIN32 || BEOS)
- add asm("main") to the *main_plugin(…) definition line
- add extern "C" to the dllmain(…) definition (to get GUI to work)
6. Modify vstgui.cpp file (!!!)
- Remove the reference to OFN_ENABLESIZING from line 5833 and line 5971
- In function checkResolveLink, cast wsz using (WCHAR *) in line 7338 and line 7340
7. Add 5 windows libraries to the Project linker parameters in the Project Options dialog
- -luuid
- -lole32
- -lgdi32
- -lcomdlg32
- -lvfw32
8. Possibly modify the VSTNAME.rc file
- Ensure there are no spaces in any filename
- Comment out reference to unknown header files such as #include "afxres.h"
9. Add the resource directory (where bitmaps are) to in the Project Options/ directories dialog.
10. Fix any bugs in code or errors identified by harsher / different language dialect / compiler
11. Build and copy VSTNAME.dll into the VST plugin directory of your host
Type : Demonstration of the VST Shell principle
References :Posted by Pierre-Alexandre Pages
Linked file : vst_shell_example.zip
Notes :
Hi! Since I found almost no information about VST-Shells, I decided to contribute
this little code sample, which implements the shell interface. Please note that
this code was made under Win32 and uses some specific API calls (for directory
listing and file selection). But all the non-portable parts of the code have been
delimited by #ifdef's, and can easily be replaced by other platform-specific method
calls.
This code was part of my work on the VST interface for the jMax application. The
shell alternative was a good solution for us, since we wanted to offer the user the
ability to use his/her own .jmax patch files (i.e. the documents of the jMax
application) as VST plugins in any compatible host.
The basic concept is that the shell is a plugin container, which exports a list of
plugins. The host will be able to instantiate any plugin in the list with one unique
interface. In our case, the advantage was that we could create a wide variety of
virtual plugins, one for each user patch file, with only one physical .dll.
[you can find more details within the zip]
Type : Simple LED display for VSTGui apps
References :Posted by Hermann Seib
Linked file : LED_view.hpp
Notes :
This simulates a LED (who would have guessed :-)
As a little gimmick, the LED is of the 3-legged variant, i.e., you can use up to 4 states: off, colour 1, colour 2, colours 1+2. Each of the colours can be freely assigned.
Have fun,
Hermann
Type : Tips & Tricks
References :Posted by dougalli
Notes :
Originally posted to the VST-plugins mailing list by Sandor Drieënhuizen
Only works in Windows
Code :
class CBitmapEx : public CBitmap
{
public:
CBitmapEx(int) : CBitmap(resourceID) { };
void loadFromFile(char *filename);
};
void CBitmapEx::loadFromFile(char *filename)
{
BITMAP bm;
pMask = 0;
pHandle = (HBITMAP)LoadImage(NULL, filename, IMAGE_BITMAP, 0, 0,
LR_LOADFROMFILE | LR_CREATEDIBSECTION);
if (pHandle)
{
if (GetObject(pHandle, sizeof(bm), &bm))
{
width = bm.bmWidth;
height = bm.bmHeight;
}
else
{
NDebug::WriteStr("*GetObject() failed for bitmap
");
NDebug::WriteLine(filename);
}
}
else
{
NDebug::WriteStr("*LoadImage() failed for bitmap ");
NDebug::WriteLine(filename);
}
}
CbitmapEx *bitmap = new CBitmapEx(NULL);
bitmap->loadFromFile("bitmap.bmp");
//now you can use the object 'bitmap' just like a normal CBitmap object.
Type : Tips & Tricks
References :Posted by dougalli
Notes :
Originally posted to the VST-plugins mailing list by Sandor Drieënhuizen
Only works in Windows
Code :
class CBitmapEx : public CBitmap
{
public:
CBitmapEx(int) : CBitmap(resourceID) { };
void loadFromFile(char *filename);
};
void CBitmapEx::loadFromFile(char *filename)
{
BITMAP bm;
pMask = 0;
pHandle = (HBITMAP)LoadImage(NULL, filename, IMAGE_BITMAP, 0, 0,
LR_LOADFROMFILE | LR_CREATEDIBSECTION);
if (pHandle)
{
if (GetObject(pHandle, sizeof(bm), &bm))
{
width = bm.bmWidth;
height = bm.bmHeight;
}
}
}
CbitmapEx *bitmap = new CBitmapEx(NULL);
bitmap->loadFromFile("bitmap.bmp");
//now you can use the object 'bitmap' just like a normal CBitmap object.
Type : Sample loading
References :Posted by williamk@dashsynthesis.com
Notes :
This code can be used to retrieve RAW 16bit samples from resources.
It's for WIN only, i.e. MSVC++ 6.0
Code :
float* VstXSynth::loadWaveform(int resID)
{
HGLOBAL hRData = NULL;
HRSRC hResource = NULL;
short* pRData;
long bufferSize;
// Load Resource //
hResource = FindResource(hModule, MAKEINTRESOURCE(resID), "WAV");
bufferSize = ((long) SizeofResource( hModule, hResource )/2);
hRData = LoadResource( hModule, hResource );
pRData = (short *)LockResource(hRData);
UnlockResource(hRData);
FreeResource(hRData);
// Convert to Float //
float *data;
long samples = bufferSize+1;
data = (float *) new float[samples];
short *buf = (short *)data;
buf = pRData;
long i = 0;
for (i=bufferSize-1; i>=0; i--)
data[i] = buf[i];
return data;
}
long VstXSynth::sizeWaveform(int resID)
{
HRSRC hResource = NULL;
hResource = FindResource(hModule, MAKEINTRESOURCE(resID), "WAV");
return ((long) SizeofResource( hModule, hResource )/2);
}
Type : C enum & string array of Midi Control Changes
References :Posted by Remy Muller
Linked file : midiCtrl.h
Notes :
It is an array in which I wrote the name of the GM controlers, there's also an enumeration for using human-names instead of index when using it.
Type : Free, Open Source, VST API Monitoring and Logging Tool
References :Posted by ost12666 [at] gmail.com
Linked file : http://www.achitophelconsulting.com/downloads/PluginConsultantSource-1.0.zip
Notes :
Plugin Consultant makes it easier for VST plugin and host developers to debug their products and for new developers to learn how the VST API works.
With Plugin Consultant you can monitor and log VST API calls between your plugin and any host, between your host and any plugin or between any plugin and any host.
Plugin Consultant provides clear view of all communications between VST plugins and hosts:
- Shows what functions and op codes are called and how often
- Provides control of what functions and op codes are logged and with what details
- Generates detailed log, using standard Win32 OutputDebugString, can be viewed in your debugger or in any debug viewer
- Does not change plugin or host behavior Does not require the logged plugin or host to be compiled in Debug mode
- Can log plugins and hosts written in any language (the VST C API is logged), including plugins created with SynthEdit
- Can log plugins and hosts that will not agree to run under a debugger
- Works with plugins and hosts that use VST SDK version 2.3 or earlier
Code :
Type : custom vstgui widget
References :Posted by urs@u-he.com
Linked file : c_radio_group.cpp
Linked file : c_radio_group.hpp
Notes :
These files can be used to implement a CControl for standard Radiobuttons with arbitrary number. It is an extension to VSTGUI.
It is easy to implement and demonstrates the ease of creating custom control objects.
One button is always ON, the others are always OFF. The parameter values is passed between 0,f and 1.f, spaced according to the number of buttons.
Type : Tips & Tricks
References :Posted by dougalli@hotmail.com
Notes :
Orginally from VST-plugins mailing list, posted by Wolfram Franke.
Might have problems on very early Logic versions on MAC ~4.2.1
Code :
rect.right = width;
rect.bottom = height;
frame->setSize(width, height);
frame->draw();
Type : Event Handling
References :Posted by mdsp @ smartelectronix
Notes :
this is a very simple and generic event scheduler based on the STL with some example code which shows how to schedule events inside a given time-slice.
You can use it to schedule midi events for example but you'll have to build your own voice handling around it, in-order to make a full-fledge synth.
But you can also use it for sample accurate automation or timeline sequencing.
Code :
//class definition-----------------------------------------
#include <map>
using std::multimap;
template<typename E>
class Scheduler
{
typedef multimap<long,E> EventList;
EventList events;
public:
typedef typename EventList::iterator iterator;
typedef std::pair<iterator,iterator> range;
Scheduler(){}
virtual ~Scheduler(){}
void Clear(){events.clear();}
void AddEvent(long time,E event){events.insert(EventList::value_type(time,event));}
long GetTimeTag(iterator i){return i->first;}
E& GetEvent(iterator i){return i->second;}
range GetRange(long start, long end){return range(events.lower_bound(start),events.upper_bound(end));}
iterator First(){return events.begin();}
iterator End() {return events.end();}
};
// use you own one
struct Event
{
Event(long note=64,long velocity=0):note(note),velocity(velocity){}
long note;
long velocity;
};
//usage---------------------------------------------------
const long size = 1024;
Scheduler<Event> scheduler;
//you can add events in any order
scheduler.AddEvent(0, Event(64,127));
scheduler.AddEvent(170, Event(70,127));
scheduler.AddEvent(900, Event(70,0));
scheduler.AddEvent(170, Event(64,0));
scheduler.AddEvent(700, Event(64,127));
scheduler.AddEvent(500, Event(64,127));
// or even add events outside the current range
// the scheduler will not take
scheduler.AddEvent(-170, Event(64,0));
scheduler.AddEvent(-70, Event(64,127));
long left = 0;
EventScheduler::range range = scheduler.GetRange(0,size);
for(EventScheduler::iterator ei =range.first;
ei!=range.second; ++ei)
{
long right = scheduler.GetTimeTag(ei);
if(left<right)
//process(...,right-left);
left = right;
Event &evt = scheduler.GetEvent(ei);
//handle event here
}
if(left<size)
//process(...,size-left);
scheduler.Clear();
Type : helper class
References :Posted by Urs Heckmann urs[at]u-he.com
Linked file : note_scheduler.h
Linked file : note_scheduler.cpp
Notes :
This is an old beta implementation for conveniently scheduling Note events from MIDI thread to Process thread. It automatically cares about stealing voices etc. I don't know how well it works, but I think it might be of interest. Please tell me if you encounter bugs.
It's full of printf-messages, so you can trace what's going on first before finally implementing it.
Read the comments in the header file.
Type : VST plugin with synced LFO
References :Posted by urs@u-he.com
Linked file : sync_x_readme.txt
Linked file : sync_xmain.cpp
Linked file : sync_x.cpp
Linked file : sync_x.hpp
Notes :
This is complete source code for a VST plugin.
It sports a syncable LFO that modulates a lowpass filter.
It also shows how to use two nested loops inside process functions to speed up things that need expensive calculation and are therefore interpolated linearly over a couple of samples.
Code :
Look at the files
Type : Graphics generation
References :Posted by paul.kellett@mda-vst.com
Notes :
At the moment this is just a function for drawing anti-aliased lines. Maybe someone else will do the next stage...
Code :
// Draw a line with simple anti-aliasing, suitable for draggable envelope displays.
// By Paul Kellett (@mda-vst.com) October 2002.
//
// The anti-aliasing works by oversampling the drawing position by 256 then using
// the fractional part to fade in the pixel on one side of the line while fading
// out the pixel on the other side. The ends of the line aren't perfect, but these
// will probably be hidden by drag handles.
//
// Uses fictional function: drawpixel(int x, int y, int brightness) where brightness
// is a value from 0 to 255, so it's easiest to draw a red, green or blue line on a
// black (or near-black) background.
void antialiasedLine(int x0, int y0, int x1, int y1)
{
int x, y, xx, yy, v;
int dx = x1 - x0;
int dy = y1 - y0;
if(abs(dx) > abs(dy)) //for each x pixel
{
if(x0 > x1) //for increasing x
{
x = x0; x0 = x1; x1 = x;
y = y0; y0 = y1; y1 = y;
}
dy = (dy << 8) / dx; //oversample y by 256
yy = y0 << 8;
for(x=x0; x<x1; x++) //draw line
{
v = yy & 0xFF;
int y = yy >> 8;
yy = yy + dy;
drawPixel(x, y, 255);
drawpixel(x, y + 1, v);
drawPixel(x, y - 1, 255 - v);
}
}
else //for each y pixel
{
if(y0 > y1) //for increasing y
{
y = y0; y0 = y1; y1 = y;
x = x0; x0 = x1; x1 = x;
}
dx = (dx << 8) / dy; //oversample x by 256
xx = x0 << 8;
for(y=y0; y<y1; y++)
{
v = xx & 0xFF;
x = xx >> 8;
xx = xx + dx;
drawPixel(x, y, 255);
drawPixel(x + 1, y, v);
drawPixel(x - 1, y, 255 - v);
}
}
}
Type : plugin persistence with custom data
References :originally posted by Karl Steinberg
Notes :
[I took this from a post to the mailing list by Charlie. - Urs]
...the programmer labelled these methods from the host point of view. thus getChunk means 'dear plug please give me your data for persistent storage', while setChunk means 'hi plug here's what you gave me for storage, load it back in'.
[Annotation: if you havn't got the data already allocated in memory like this example demonstrates - if you need to assemble it for getChunk, that is -, it is save to free the pointer in resume() or on plugin destruction - Urs]
Code :
//--------------------------------------------------------------------------
struct MyPreset
{
float gain;
};
//--------------------------------------------------------------------------
struct MyProjectData
{
long version;
MyPreset presets[kNumPrograms];
};
static MyProjectData projectData = {1, 1, {0}};
//--------------------------------------------------------------------------
long MyPlug::getChunk (void** data, bool isPreset)
{
if (isPreset)
{
*data = &projectData.presets[currentProgram];
return sizeof (MyPreset);
}
*data = &projectData;
return sizeof (MyProjectData);
}
//--------------------------------------------------------------------------
long MyPlug::setChunk (void* data, long byteSize, bool isPreset)
{
if (isPreset)
{
if (byteSize != sizeof (MyPreset))
return 0;
projectData.presets[currentProgram] = *(MyPreset*)data;
}
else
{
if (byteSize != sizeof (MyProjectData))
return 0;
projectData = *(MyProjectData*)data;
}
return 1;
}
(written off my head, no guarantee)
charlie
Type : parameter persistence
References :Posted by Ged Grey
Notes :
It might be a good idea also to place a call to:
setProgram(curProgram); // new parameters will now kick in
as the last thing in your setChunk() method, as it is not certain whether the
host will actually call this for you.
Also, be sure to declare programsAreChunks(true) or whatever it's called
in your plug's constructor...
References :Posted by adi[at]pflugshaupt.com
Notes :
Using the CPDFContext class, a true vector pdf screenshot of the actual state of a plugin GUI using VSTGUI 3.0 can be written to a file. Everything drawn by CoreGraphics (especially fonts) are then 100% scalable. This is a nice way to do a plugin screenshot for printout!
Using COffScreenContext objects will result in pixelation, however this is not needed on OSX anyway. To use the class, #include "CPDFContext" in your editor and execute a screenshot the following way:
void mVstEditor::savePdf()
{
CPDFContext* mContext = new CPDFContext(frame, "/Screenshot.pdf");
frame->draw(mContext);
delete mContext;
}
The file name is posix compatible.
Code :
/*
* cpdfcontext.h
*
* Created by Adrian Pflugshaupt on 1/23/06.
*
*/
#pragma once
#include <vstgui.h>
#if MAC && QUARTZ
class CPDFContext : public CDrawContext
{
public:
CPDFContext(CFrame* frame, char* outputFile);
~CPDFContext();
};
#endif
/*
* cpdfcontext.cpp
*
* Created by Adrian Pflugshaupt on 1/23/06.
*
*/
#include "cpdfcontext.h"
#if MAC && QUARTZ
CPDFContext::CPDFContext(CFrame* frame, char* outputFile) : CDrawContext(frame, NULL, NULL)
{
CFURLRef mUrl = CFURLCreateFromFileSystemRepresentation(NULL, (UInt8*)outputFile, strlen(outputFile), false);
gCGContext = CGPDFContextCreateWithURL(mUrl, NULL, NULL);
if (!gCGContext)
fprintf(stderr, "[CPDFContext::CPDFContext] Error creating pdf context\n");
else
{
fprintf(stderr, "[CPDFContext::CPDFContext] Setting up PDF context for file %s\n", outputFile);
CRect mSize;
frame->getSize(mSize);
CGRect box=CGRectMake((float)mSize.left, (float)mSize.top, (float)mSize.right, (float)mSize.bottom);
CGContextBeginPage(gCGContext, &box);
CGContextTranslateCTM (gCGContext, 0, (float)mSize.height());
CGAffineTransform cgCTM = CGAffineTransformMake (1.0, 0.0, 0.0, -1.0, 0.0, 0.0);
CGContextSetTextMatrix (gCGContext, cgCTM);
}
}
CPDFContext::~CPDFContext()
{
if (gCGContext)
{
CGContextEndPage(gCGContext);
CGContextRelease(gCGContext);
gCGContext=NULL;
}
}
#endif
References :Posted by dunk
Notes :
NB - This is just the way I've done it - mostly taken from "controlsguieditor.cpp" in the VSTGUI docs.
I've got a Plugin parameter called "kDoLoadWave". When this is automated to 1.0, the pluginedit "setparameter" proc calls a plugin procedure "loadWaveFile(filename)" with the filename selected in the fileselector.
There's a CKickButton set with tag=kDoLoadWave. When it's clicked, it tries to bring up the fileselector. If a file is selected, it sets the wavefilename to the filename(+path) and then setParameterAutomated(kDoLoadWave, 1).
NB - it seems that only Cubase supports this fileselector (?) - so you might need to implemented a GUI object that allows drag and drop loading of wav files to use in other hosts.
regards,
dunk
Code :
case kDoLoadWave:
{
control->update (context);
effect->setParameterAutomated (kPlay, 0);
AudioEffectX *effect = (AudioEffectX*)getEffect ();
if (effect && control->getValue () > 0.5f)
{
if (effect->canHostDo ("openFileSelector"))
{
VstFileType aiffType ("AIFF File", "AIFF", "aif", "aiff", "audio/aiff", "audio/x-aiff");
VstFileType aifcType ("AIFC File", "AIFC", "aif", "aifc", "audio/x-aifc");
VstFileType waveType ("Wave File", ".WAV", "wav", "wav", "audio/wav", "audio/x-wav");
VstFileType sdIIType ("SoundDesigner II File", "Sd2f", "sd2", "sd2");
VstFileSelect vstFileSelect;
memset (&vstFileSelect, 0, sizeof (VstFileType));
vstFileSelect.command = kVstFileLoad;
vstFileSelect.type = kVstFileType;
strcpy (vstFileSelect.title, "Test for open file selector");
vstFileSelect.nbFileTypes = 1;
vstFileSelect.fileTypes = &waveType;
vstFileSelect.returnPath = new char[1024];
//vstFileSelect.initialPath = new char[1024];
vstFileSelect.initialPath = 0;
if (effect->openFileSelector (&vstFileSelect))
{
//feedback to a text edit box in GUI
debugText->setText("Trying To Load");
debugText->setDirty(true);
waveFileName = vstFileSelect.returnPath;
//feedback to a text edit box in GUI
debugText->setText(waveFileName);
debugText->setDirty(true);
effect->setParameterAutomated (tag, 1);
}
else
{
// Load cancelled
}
delete []vstFileSelect.returnPath;
if (vstFileSelect.initialPath)
delete []vstFileSelect.initialPath;
}
else
{
//feedback to a text edit box in GUI
debugText->setText("fileselector dialog not supported - please drag and drop .wavs");
debugText->setDirty(true);
}
}
}
control->update (context);
break;
Type : VST hosting example
References :Posted by C Budde & Tobybear
Linked file : vsthost_delphi.zip
Notes :
Christian and Tobybear contributed this hosting example for Delphi. It's quite complex, but the instructions delivered with the zip should help you setting it up 8-)
Type : host code
References :Posted by Dave of Muon Software Ltd
Linked file : Host.cpp
Notes :
The application in file Host.cpp "is a rather simple program that queries plugins for info and just basically tests them - I found this ideal, since it helps you understand the basics without messing with user interfaces, etc." says Dave.
Note: It needs Win APIs, but you can easily set it up for Mac or anything... (Urs)
Type : CFM compatibility layer
References :Posted by Alex Lagutin alex[AT]rogueamoeba.com
Linked file : vst_macho_bridge.dmg
Notes :
[if download looks crappy, use command-click "and save to disc"]
from Alex's mail:
I am not sure if you find this code useful at all, but it might help.
I made it long time ago (pre vst mach-o days) and did not make it available to public.
Here's a cut from the Readme:
---cut here---
DESCRIPTION:
VST Mach-O Bridge allows you to create VST Mac OS X plug-ins using
Mach-O development toolchain (Project Builder, etc.)
With these development tools it is very easy to use low-level
Mac OS X APIs such as POSIX threads or BSD sockets in your plug-ins.
DISCUSSION:
Mac OS X VST plug-ins are implemented as PowerPC code resources
in CFM PEF object format. Apple's Project Builder development
environment cannot create objects in this format (at least not in
the standard distribution.)
VST Mach-O Bridge removes this limitation by providing a "bridge"
that loads a plug-in in Mach-O object format and translates calls
from CFM binary interface to Mach-O binary interface and vice versa.
The "bridge" operations are totally transparent to the host application
and plug-in code.
TECHNICAL DETAILS:
Completed plug-in using VST Mach-O Bridge is assembled from 2 pieces -
1. Bridge code resource of type 'aEff' (source code included)
This part is implemented as ordinary VST plug-in with
the only difference - it does nothing but loads the real plug-in code
and translates host-to-plugin and plugin-to-host calls.
It is stored as the resource of type 'aEff' in the resource fork of
resulting plug-in file.
2. Plug-in in Mach-O object format of type 'MH_BUNDLE'
This part is created using Mach-O development toolchain (Project Builder, etc.)
and is put as data fork into resulting plug-in file.
Also, plug-in file should have file type 'aPcs' to be recognized by host application
as a file containing VST plug-in code.
---cut here---
Type : VST MIDI
References :Posted by davidv@plogue.com
Linked file : http://www.plogue.com/VSTMIDI_GAIN.zip
Notes :
This is a hack on top of VST 2.x to process MIDI events
in a convenient processMIDI function,
using VstMidiEvent std::vectors
Charlie announced that VST 3.0 would have better native MIDI
processing, but in the mean time, I think that this code might be usefull for you to start trying out MIDI effects.
This currently does _not_ work in SX, it worked in previous
versions of Cubase. Works also in bidule (of course), needs to be tried in other hosts...
Please provide any suggestions/comments...
Cheers
Type : Handy classes I use for all my parameters
References :Posted by kaleja@estarcion.com
Linked file : VParams.zip
Notes :
This is a set of classes I use to define all the VST parameters I use in my plugins; you can do things like set the floating point range that you care about (i.e 2.7 to 9.43) and the class takes care of mapping between that range and the native VST 0.0-1.0 range. A zip file containing the code is at:
http://www.estarcion.com/tinygod/code/VParams.zip
It's for win32/VC++, but I tried to isolate some platform-specific stuff to make it easier to port.
Code :
Type : How to code under BC++3
References :Posted by DSPMaster [at] free.fr
Notes :
If you want to write VST plugins with Borland C++ Builder, you may experience some little problems when using the Steinberg SDK, due to slight differences between VC++ (for which SDK was written) and BC++.
Just proceed to following changes, and writing VST plugins under BC++ will be a game..
Code :
1) in the main DLL source file, change the main() function both in the definition and the prototype otherwise function will not be exported
__declspec (dllexport) AEffect *main (audioMasterCallback audioMaster);
2) create a .DEF file for your project containing at least this line :
EXPORTS main=_main
3) add a USEDEF ("xxxxxx.DEF") clause in your main project file (I got the habit to put it just under the USERES clause
4) in the SDK sourcefiles, the #ifdef __BORLANDC__ section is not correct (at least for BC++3).
Replace the existing blocks of instructions by the following ones
(***** top of aeffectx.h *****)
#if PRAGMA_STRUCT_ALIGN || __MWERKS__
#pragma options align=mac68k
#elif defined __BORLANDC__
#pragma -a8
#pragma option push -a8
#elif defined(WIN32) || defined(__FLAT__)
#pragma pack(push)
#pragma pack(8)
#endif
(***** end of aeffectx.h *****)
#if PRAGMA_STRUCT_ALIGN || __MWERKS__
#pragma options align=reset
#elif defined(WIN32) || defined(__FLAT__)
// #pragma pack(pop)
#pragma option pop
#elif defined __BORLANDC__
#pragma -a-
#endif
(***** top of aeffect.h *****)
#if CARBON
#if PRAGMA_STRUCT_ALIGN || __MWERKS__
#pragma options align=mac68k
#endif
#else
#if PRAGMA_ALIGN_SUPPORTED || __MWERKS__
#pragma options align=mac68k
#endif
#endif
#if defined __BORLANDC__
#pragma -a8
#pragma option push -a8
#define VSTCALLBACK __cdecl
#elif defined(WIN32) || defined(__FLAT__) || defined CBUILDER
#pragma pack(push)
#pragma pack(8)
#define VSTCALLBACK __cdecl
#else
#define VSTCALLBACK
#endif
(****** end of affect.h *****)
#if CARBON
#if PRAGMA_STRUCT_ALIGN || __MWERKS__
#pragma options align=reset
#endif
#else
#if PRAGMA_ALIGN_SUPPORTED || __MWERKS__
#pragma options align=reset
#elif defined(WIN32) || defined(__FLAT__)
// #pragma pack(pop)
#pragma option pop
#elif defined __BORLANDC__
#pragma -a-
#endif
#endif
Type : development environment recipe
References :Posted by gabriel.lindeborg[at]sverige.nu
Linked file : vst_with_dev_c.txt
Notes :
How to make VSTpluggs with Dev-C++ v. 4.9.8.0 [http://bloodshed.net] or later.
(Note: this document is going to grow, i.e. by a VSTGUI recipe as well. Please comment - Urs)
Type : debug apparatus
References :Posted by mfm@u-he.com
Notes :
Open a file and write a variable into it...
Code :
//somewhere at the beginning of your file
#include <stdio.h>
//somwhere in your code
FILE* verbose;
verbose = fopen ( "debug_dump", "w+" );
float value = 0.5f; // whatsoever
fprintf ( verbose, "value = %f", value );
fclose ( verbose );
Type : Advanced Control
References :Posted by Alexis Glass mail[AT]mutagene.net
Linked file : CXYControlSurface.cpp
Notes :
Very rudimentary implementation of a 2-d touch pad that multiplexes the data into a single output value. The resolution of each axis in the output value is specified by the variable 'resolution' when the control is constructed. Note that each axis varies between 0 and 1, not -1 and +1.
Code :
See attached file (it contains the hpp-part on top of the cpp...)