9

I'm struggling to find a basic example on how to set up a minimal plugin host with VST 3.x SDK. The official documentation is absolutely criptic and brief, I can't get anywhere. I would like to:

  1. understand the minimal setup: required headers, interfaces to implement, ...;
  2. load a VST3 plugin (no fancy GUI, for now);
  3. print out some data (e.g. plugin name, parameters, ...).

That would be a great start :)

Ignorant
  • 2,411
  • 4
  • 31
  • 48
  • possible duplicate of [How are VST Plugins made?](http://stackoverflow.com/questions/2581025/how-are-vst-plugins-made) – πάντα ῥεῖ Jun 29 '14 at 16:51
  • @πάνταῥεῖ Hope I am not mistaken, they are talking about plugins... I would like to build a plugin _host_ :) – Ignorant Jun 29 '14 at 16:56
  • Check if this is better for your needs: https://www.google.de/url?sa=t&rct=j&q=&esrc=s&source=web&cd=1&cad=rja&uact=8&ved=0CCAQFjAA&url=http%3A%2F%2Fteragonaudio.com%2Farticle%2FHow-to-make-your-own-VST-host.html&ei=YEWwU4rMOY6Y0QW4mYCoBg&usg=AFQjCNF8oDH1LjoNZ9UuJbnh5WvcDbbeKA&sig2=6TGzaAWwtdG1Qtgzj3Xx1w&bvm=bv.69837884,d.bGQ Please don't misuse SO as a replacement for google in 1st place. – πάντα ῥεῖ Jun 29 '14 at 16:57
  • 1
    Unfortunately that link is based on VST2.x protocol, which is a completely different story from VST3 - VST2.x was a lot easier, but no longer supported. – Ignorant Jun 29 '14 at 17:03

2 Answers2

9

Yeah, VST3 is rather mysterious and poorly documented. There are not many good examples partially because not many companies (other than Steinberg) actually care about VST3. But all cynicism aside, your best bet would be to look at the Juce source code to see their implementation of a VST3 host:

https://github.com/julianstorer/JUCE/blob/master/modules/juce_audio_processors/format_types/juce_VST3PluginFormat.cpp

There's a few other VST3-related files in that package which are worth checking out. Anyways, this should at least be enough information to get get you started with a VST3 host.

It's worth noting that Juce is GPL (unless you pay for a license), so it's a big no-no to borrow code directly from it unless you are also using the GPL or have a commercial license. Just a friendly reminder to be a responsible programmer when looking at GPL'd code on the net. :)

Nik Reiman
  • 39,067
  • 29
  • 104
  • 160
  • Haha, just found a gem in there: https://github.com/juce-framework/JUCE/blob/master/modules/juce_audio_processors/format_types/juce_VST3Headers.h#L26 – VincentDM Jun 16 '21 at 20:17
3

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.