Skip to content

Instantly share code, notes, and snippets.

@nikreiman
Last active September 12, 2019 15:26
Show Gist options
  • Save nikreiman/736032 to your computer and use it in GitHub Desktop.
Save nikreiman/736032 to your computer and use it in GitHub Desktop.
Code snippits for creating a VST 2.x plugin host
void resumePlugin(AEffect *plugin) {
dispatcher(plugin, effMainsChanged, 0, 1, NULL, 0.0f);
}
void suspendPlugin(AEffect *plugin) {
dispatcher(plugin, effMainsChanged, 0, 0, NULL, 0.0f);
}
extern "C" {
VstIntPtr VSTCALLBACK hostCallback(AEffect *effect, VstInt32 opcode, VstInt32 index,
VstInt32 value, void *ptr, float opt) {
switch(opcode) {
case audioMasterVersion:
return 2400;
case audioMasterIdle:
effect->dispatcher(effect, effEditIdle, 0, 0, 0, 0);
// Handle other opcodes here... there will be lots of them
default:
printf("Plugin requested value of opcode %d\n", opcode);
break;
}
}
}
int initPlugin(AEffect *plugin) {
// Check plugin's magic number
// If incorrect, then the file either was not loaded properly, is not a real
// VST plugin, or is otherwise corrupt.
if(plugin->magic != kEffectMagic) {
printf("Plugin's magic number is bad\n");
return -1;
}
// Create dispatcher handle
dispatcherFuncPtr dispatcher = (dispatcherFuncPtr)(plugin->dispatcher);
// Set up plugin callback functions
plugin->getParameter = (getParameterFuncPtr)plugin->getParameter;
plugin->processReplacing = (processFuncPtr)plugin->processReplacing;
plugin->setParameter = (setParameterFuncPtr)plugin->setParameter;
return plugin;
}
AEffect* loadPlugin() {
AEffect *plugin = NULL;
audioMasterCallback hostCallbackFuncPtr = hostCallback;
char *pluginPath = "/wherever/the/plugin/is/located.vst";
// Create a path to the bundle
CFStringRef pluginPathStringRef = CFStringCreateWithCString(NULL, pluginPath, kCFStringEncodingASCII);
CFURLRef bundleUrl = CFURLCreateWithFileSystemPath(kCFAllocatorDefault,
pluginPathStringRef, kCFURLPOSIXPathStyle, true);
if(bundleUrl == NULL) {
printf("Couldn't make URL reference for plugin\n");
return NULL;
}
// Open the bundle
CFBundleRef bundle;
bundle = CFBundleCreate(kCFAllocatorDefault, bundleUrl);
if(bundle == NULL) {
printf("Couldn't create bundle reference\n");
CFRelease(pluginPathStringRef);
CFRelease(bundleUrl);
return NULL;
}
vstPluginFuncPtr mainEntryPoint = NULL;
mainEntryPoint = (vstPluginFuncPtr)CFBundleGetFunctionPointerForName(bundle, CFSTR("VSTPluginMain"));
// VST plugins previous to the 2.4 SDK used main_macho for the entry point name
if(mainEntryPoint == NULL) {
mainEntryPoint = (vstPluginFuncPtr)CFBundleGetFunctionPointerForName(bundle, CFSTR("main_macho"));
}
if(mainEntryPoint == NULL) {
printf("Couldn't get a pointer to plugin's main()\n");
CFBundleUnloadExecutable(bundle);
CFRelease(bundle);
return NULL;
}
plugin = mainEntryPoint(hostCallback);
if(plugin == NULL) {
printf("Plugin's main() returns null\n");
CFBundleUnloadExecutable(bundle);
CFRelease(bundle);
return NULL;
}
// Clean up
CFRelease(pluginPathStringRef);
CFRelease(bundleUrl);
return plugin;
}
AEffect* loadPlugin() {
AEffect *plugin = NULL;
char *vstPath = "c:\\wherever\\the\\plugin\\is\\located.vst";
modulePtr = LoadLibrary(vstPath);
if(modulePtr == NULL) {
printf("Failed trying to load VST from '%s', error %d\n", vstPath, GetLastError());
return NULL;
}
vstPluginFuncPtr mainEntryPoint = (vstPluginFuncPtr)GetProcAddress(modulePtr, "VSTPluginMain");
// Instantiate the plugin
plugin = mainEntryPoint(hostCallback);
return plugin;
}
void initPlugin(AEffect *plugin) {
dispatcher(plugin, effOpen, 0, 0, NULL, 0.0f);
// Set some default properties
float sampleRate = 44100.0f;
dispatcher(plugin, effSetSampleRate, 0, 0, NULL, sampleRate);
int blocksize = 512;
dispatcher(plugin, effSetBlockSize, 0, blocksize, NULL, 0.0f);
resume();
}
#include "aeffectx.h"
// C callbacks
extern "C" {
// Main host callback
VstIntPtr VSTCALLBACK hostCallback(AEffect *effect, VstInt32 opcode, VstInt32 index,
VstInt32 value, void *ptr, float opt);
}
// Plugin's entry point
typedef AEffect *(*vstPluginFuncPtr)(audioMasterCallback host);
// Plugin's dispatcher function
typedef VstIntPtr (*dispatcherFuncPtr)(AEffect *effect, VstInt32 opCode, VstInt32 index,
VstInt32 value, void *ptr, float opt);
// Plugin's getParameter() method
typedef float (*getParameterFuncPtr)(AEffect *effect, VstInt32 index);
// Plugin's setParameter() method
typedef void (*setParameterFuncPtr)(AEffect *effect, VstInt32 index, float value);
// Plugin's processEvents() method
typedef VstInt32 (*processEventsFuncPtr)(VstEvents *events);
// Plugin's process() method
typedef void (*processFuncPtr)(AEffect *effect, float **inputs, float **outputs, VstInt32 sampleFrames);
bool canPluginDo(char *canDoString) {
return (dispatcher(plugin, effCanDo, 0, 0, (void*)canDoString, 0.0f) > 0);
}
void processAudio(AEffect *plugin, float **inputs, float **outputs, long numFrames) {
// Note: If you are processing an instrument, you should probably zero out the input
// channels first to avoid any accidental noise. If you are processing an effect, you
// should probably zero the values in the output channels. See the silenceChannel()
// method below.
plugin->processReplacing(plugin, inputs, outputs, numFrames);
}
void silenceChannel(float **channelData, int numChannels, long numFrames) {
for(int channel = 0; channels < numChannels; ++channel) {
for(long frame = 0; frame < numFrames; ++frame) {
channelData[channel][frame] = 0.0f;
}
}
}
void processMidi(AEffect *plugin, VstEvents *events) {
dispatcher(plugin, effProcessEvents, 0, 0, events, 0.0f);
}
@nikreiman
Copy link
Author

nikreiman commented Sep 2, 2019

does this support vst3? i have been looking for something like this for a long time

@demberto Nope, it's VST 2.x only. I'll update the title of this gist for clarity's sake.

Copy link

ghost commented Sep 3, 2019

Can you make snippet for vst3.x as well?

@nikreiman
Copy link
Author

@demberto Sorry, no. I have no idea how VST 3.x works and have no experience with that version of the SDK at all.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment