Last active
September 12, 2019 15:26
-
-
Save nikreiman/736032 to your computer and use it in GitHub Desktop.
Code snippits for creating a VST 2.x plugin host
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
void resumePlugin(AEffect *plugin) { | |
dispatcher(plugin, effMainsChanged, 0, 1, NULL, 0.0f); | |
} | |
void suspendPlugin(AEffect *plugin) { | |
dispatcher(plugin, effMainsChanged, 0, 0, NULL, 0.0f); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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(); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
bool canPluginDo(char *canDoString) { | |
return (dispatcher(plugin, effCanDo, 0, 0, (void*)canDoString, 0.0f) > 0); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
void processMidi(AEffect *plugin, VstEvents *events) { | |
dispatcher(plugin, effProcessEvents, 0, 0, events, 0.0f); | |
} |
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.
Can you make snippet for vst3.x as well?
@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
does this support vst3? i have been looking for something like this for a long time