Loading VST3 Plugins From File Path in JUCE
JUCE offers extensive support for working with audio plugins of all the major types. There is even
PluginListComponent class that implements ready-to-use UI for scanning and managing plugins by the user. The class supports in-process scanning by default. However, some plugins crash while being scanned, so out-of-process scanning is often desirable. JUCE
AudioPluginHost app extends PluginListComponent to support this scenario as well. PluginListComponent is an excellent choice for building fill-featured plugin hosts. But what if don’t want to perform full scanning and only need to instantiate a single plugin of specific type given its file path? It turns out that that’s ver easy to do, but it is not immediately obvious neither from JUCE documentation, nor from code samples.
Class ultimately responsible for creating plugin instances is
AudioPluginFormat. We need a concrete subclass for specific format, for example
VST3PluginFormat. To create a plugin instance, we must obtain its
PluginDescription from given file. We do that by calling findAllTypesForFile on the audio format. Some plugins can have multiple plugin types bundled in a single file. That’s why findAllTypesForFile takes an array for adding all plugin descriptions it finds. In the example below, we simply grab the last description. Finally, we call createInstanceFromDescription which, if successful, returns a pointer to
AudioPluginInstance.
Bellow is a complete code snippet demonstrating how to load a VST3 plugin from its file path:
void loadPlugin(const juce::String& pluginFilePath,
juce::String& errorMessage)
{
juce::OwnedArray<juce::PluginDescription> descs;
vst3Format.findAllTypesForFile(descs, pluginFilePath);
if (descs.isEmpty())
{
errorMessage = "No VST3 plugin found at " + pluginFilePath;
return;
}
auto pluginInstance = vst3Format.createInstanceFromDescription(*descs.getLast(),
getSampleRate(),
getBlockSize(),
errorMessage);
if (pluginInstance == nullptr)
{
// show errorMessage
return;
}
hostedPluginInstance = std::move(pluginInstance);
}
juce::VST3PluginFormat vst3Format;
std::unique_ptr<juce::AudioPluginInstance> hostedPluginInstance;
There is also an asynchronous version of this method which creates plugin instance on a background thread, for example:
auto callback = [this](auto pluginInstance, const auto& errorMessage)
{
pluginLoadingError = errorMessage;
hostedPluginInstance = std::move(pluginInstance);
sendChangeMessage();
};
vst3Format.createPluginInstanceAsync(*descs.getLast(),
getSampleRate(),
getBlockSize(),
std::move(callback));
Using background thread for plugin instantiation is not strictly necessary for the VST3 format, but it is required for AUv3.