Simple VST3 hosts already exist in the VST SDK. It is not difficult to augment them, but there are some things to keep in mind.
- The samples under public.skd/vst-hosting in the VST SDK contain an EditorHost and and AudioHost. The first handles the GUI, the second handles the effect (the signal processing). You can combine the two. Neither is a full implementation.
- VST objects are COM objects and so you have to make sure to set up the application context correctly, so that your COM objects persist between calls. EditorHost and AudioHost both do that in a couple of lines in a global context variable (look for pluginContext).
- If you use separate calls to load and unload effects, process data, and so on, you have to keep COM object pointers, so they are not unloaded. For example, you may be tempted to ignore the Steinberg::Vst::Module module, since you don't need it once the effect is loaded, but you would have to keep a pointer to it somewhere globally or in the main application thread. If not, the automatic unloading of that pointer will also unload the plugin as well and subsequent calls to the plugin will fail.
- The construction of VST effects is relatively simple. They consist of a component (the effect) and a controller (the GUI). Both are instantiated when Steinberg::Vst::PlugProvider is loaded (some effects do not have a GUI). Both examples above load a plugprovider. Once you load a plugprovider, you are essentially done.
The following code is sufficient to load a plugprovider (the whole effect). Assume returning -1 means an error:
std::string error;
std::string path = "somepath/someeffect.vst3";
VST3::Hosting::Module::Ptr module =
VST3::Hosting::Module::create(path, error);
if (! module)
return -1;
IPtr<PlugProvider> plugProvider;
VST3::Optional<VST3::UID> effectID = std::move(uid);
for (auto& classInfo : module->
getFactory().classInfos())
{
if (classInfo.category() == kVstAudioEffectClass)
{
if (effectID)
{
if (*effectID != classInfo.ID())
continue;
}
plugProvider = owned(new
PlugProvider(module->getFactory(),
classInfo, true));
break;
}
}
if (! plugProvider)
return -1;
After this, plugProvider->getComponent() and plugProvider->getController() give you the effect and GUI. The controller has to be displayed in a window, of course, which is done in EditorHost. These are the implementations of IComponent,IAudioProcessor and IEditController in the VST SDK.
The source/vst/testsuite part of the VST SDK will show you the full functionality of both of these parts (it will essentially give you the functional calls that you can use to do everything you want to do).
Note the module and plugprovider loaded in the code above. As mentioned above, if you don't keep the module pointer, there is no guarantee the plugprovider pointer will survive. It is difficult to keep track of what gets released when in the VST SDK.