Browse Source

Cleaned up some VST3 code to deal with plugins that fail to initialise.

tags/2021-05-28
jules 12 years ago
parent
commit
ef00bcc024
1 changed files with 82 additions and 87 deletions
  1. +82
    -87
      modules/juce_audio_processors/format_types/juce_VST3PluginFormat.cpp

+ 82
- 87
modules/juce_audio_processors/format_types/juce_VST3PluginFormat.cpp View File

@@ -125,13 +125,13 @@ struct VST3Classes
#endif
#if JUCE_DEBUG
static void warnOnFailure (int result)
static int warnOnFailure (int result)
{
const char* message = "Unknown result!";
switch (result)
{
case kResultOk: return;
case kResultOk: return result;
case kNotImplemented: message = "kNotImplemented"; break;
case kNoInterface: message = "kNoInterface"; break;
case kResultFalse: message = "kResultFalse"; break;
@@ -143,6 +143,7 @@ static void warnOnFailure (int result)
}
DBG (message);
return result;
}
#else
#define warnOnFailure(x) x
@@ -188,11 +189,6 @@ public:
return factory->createInstance (uuid, ObjectType::iid, (void**) &source) == kResultOk;
}
bool loadFrom (IPluginFactory* factory, const PClassInfo& info)
{
return loadFrom (factory, info.cid);
}
private:
ObjectType* source;
};
@@ -678,6 +674,8 @@ public:
JUCE_DECLARE_VST3_COM_REF_METHODS
FUnknown* getFUnknown() { return static_cast<Vst::IComponentHandler*> (this); }
//==============================================================================
tresult PLUGIN_API beginEdit (Vst::ParamID) override
{
@@ -831,7 +829,7 @@ public:
{
if (doIdsMatch (iid, Vst::IAttributeList::iid))
{
*obj = dynamic_cast<Vst::IAttributeList*> (attributeList.get());
*obj = attributeList.get();
return kResultOk;
}
@@ -1141,9 +1139,9 @@ public:
{
ComSmartPtr<Vst::IComponent> component;
if (component.loadFrom (factory, info))
if (component.loadFrom (factory, info.cid))
{
if (component->initialize (dynamic_cast<Vst::IComponentHandler*> (vst3HostContext.get())) == kResultOk)
if (component->initialize (vst3HostContext->getFUnknown()) == kResultOk)
{
numInputs = getNumSingleDirectionChannelsFor (component, true, true);
numOutputs = getNumSingleDirectionChannelsFor (component, false, true);
@@ -1678,16 +1676,14 @@ public:
VST3PluginInstance (const VST3ModuleHandle::Ptr& handle)
: module (handle),
result (1, 1),
inputParameterChanges (new ParameterChangeList()),
outputParameterChanges (new ParameterChangeList()),
midiInputs (new MidiEventList()),
midiOutputs (new MidiEventList()),
isComponentInitialised (false),
isControllerInitialised (false)
{
midiInputs = new MidiEventList();
midiOutputs = new MidiEventList();
inputParameterChanges = new ParameterChangeList();
outputParameterChanges = new ParameterChangeList();
host = new VST3HostContext (this);
initialise();
}
~VST3PluginInstance()
@@ -1711,6 +1707,36 @@ public:
component = nullptr;
}
bool initialise()
{
#if JUCE_WINDOWS
// On Windows it's highly advisable to create your plugins using the message thread,
// because many plugins need a chance to create HWNDs that will get their messages
// delivered by the main message thread, and that's not possible from a background thread.
jassert (MessageManager::getInstance()->isThisTheMessageThread());
#endif
ComSmartPtr<IPluginFactory> factory (module->getPluginFactory());
PFactoryInfo factoryInfo;
factory->getFactoryInfo (&factoryInfo);
company = toString (factoryInfo.vendor).trim();
if (! fetchComponentAndController (factory, factory->countClasses()))
return false;
if (warnOnFailure (editController->initialize (host->getFUnknown())) != kResultTrue)
return false;
isControllerInitialised = true;
editController->setComponentHandler (host);
grabInformationObjects();
synchroniseStates();
interconnectComponentAndController();
setupIO();
return true;
}
//==============================================================================
void fillInPluginDescription (PluginDescription& description) const override
{
@@ -1744,11 +1770,8 @@ public:
warnOnFailure (processor->setupProcessing (setup));
if (! isControllerInitialised)
isControllerInitialised = editController->initialize (dynamic_cast<Vst::IComponentHandler*> (host.get())) == kResultTrue;
if (! isComponentInitialised)
isComponentInitialised = component->initialize (dynamic_cast<Vst::IComponentHandler*> (host.get())) == kResultTrue;
isComponentInitialised = component->initialize (host->getFUnknown()) == kResultTrue;
editController->setComponentHandler (host);
@@ -1768,8 +1791,11 @@ public:
void releaseResources() override
{
processor->setProcessing (false);
component->setActive (false);
if (processor != nullptr)
processor->setProcessing (false);
if (component != nullptr)
component->setActive (false);
}
void processBlock (AudioSampleBuffer& buffer, MidiBuffer& midiMessages) override
@@ -2081,12 +2107,10 @@ private:
ComSmartPtr<ParameterChangeList> inputParameterChanges, outputParameterChanges;
ComSmartPtr<MidiEventList> midiInputs, midiOutputs;
Vst::ProcessContext timingInfo; //< Only use this in processBlock()!
bool isComponentInitialised;
bool isControllerInitialised;
bool isComponentInitialised, isControllerInitialised;
//==============================================================================
void fetchComponentAndController (IPluginFactory* factory, const Steinberg::int32 numClasses)
bool fetchComponentAndController (IPluginFactory* factory, const Steinberg::int32 numClasses)
{
jassert (numClasses >= 0); // The plugin must provide at least an IComponent and IEditController!
@@ -2119,7 +2143,7 @@ private:
if (pf3.loadFrom (factory))
{
pf3->setHostContext (dynamic_cast<Vst::IComponentHandler*> (host.get()));
pf3->setHostContext (host->getFUnknown());
infoW = new PClassInfoW();
pf3->getClassInfoUnicode (i, infoW);
}
@@ -2131,42 +2155,38 @@ private:
bool failed = true;
if (component.loadFrom (factory, *info) && component != nullptr)
if (component.loadFrom (factory, info->cid) && component != nullptr)
{
warnOnFailure (component->setIoMode (isNonRealtime() ? Vst::kOffline : Vst::kRealtime));
if (component->initialize (dynamic_cast<Vst::IComponentHandler*> (host.get())) == kResultOk)
{
isComponentInitialised = true;
if (warnOnFailure (component->initialize (host->getFUnknown())) != kResultOk)
return false;
// Get the IEditController:
TUID controllerCID = { 0 };
isComponentInitialised = true;
if (component->getControllerClassId (controllerCID) == kResultTrue && FUID (controllerCID).isValid())
editController.loadFrom (factory, controllerCID);
// Get the IEditController:
TUID controllerCID = { 0 };
if (editController == nullptr)
editController.loadFrom (component);
if (component->getControllerClassId (controllerCID) == kResultTrue && FUID (controllerCID).isValid())
editController.loadFrom (factory, controllerCID);
if (editController == nullptr)
if (editController == nullptr)
{
// Try finding the IEditController the long way around:
for (Steinberg::int32 i = 0; i < numClasses; ++i)
{
// Try finding the IEditController the long way around:
for (Steinberg::int32 i = 0; i < numClasses; ++i)
{
PClassInfo classInfo;
factory->getClassInfo (i, &classInfo);
if (std::strcmp (classInfo.category, kVstComponentControllerClass) == 0)
editController.loadFrom (factory, classInfo);
}
}
PClassInfo classInfo;
factory->getClassInfo (i, &classInfo);
failed = editController == nullptr;
}
else
{
jassertfalse;
if (std::strcmp (classInfo.category, kVstComponentControllerClass) == 0)
editController.loadFrom (factory, classInfo.cid);
}
}
if (editController == nullptr)
editController.loadFrom (component);
failed = editController == nullptr;
}
if (failed)
@@ -2185,11 +2205,13 @@ private:
editController = nullptr;
}
return;
break;
}
break;
return true;
}
return false;
}
/** Some plugins need to be "connected" to intercommunicate between their implemented classes */
@@ -2250,38 +2272,6 @@ private:
setup.sampleRate, (int) setup.maxSamplesPerBlock);
}
void initialise()
{
jassert (module != nullptr);
#if JUCE_WINDOWS
// On Windows it's highly advisable to create your plugins using the message thread,
// because many plugins need a chance to create HWNDs that will get their messages
// delivered by the main message thread, and that's not possible from a background thread.
jassert (MessageManager::getInstance()->isThisTheMessageThread());
#endif
ComSmartPtr<IPluginFactory> factory (module->getPluginFactory());
PFactoryInfo factoryInfo;
factory->getFactoryInfo (&factoryInfo);
company = toString (factoryInfo.vendor).trim();
fetchComponentAndController (factory, factory->countClasses());
jassert (info != nullptr);
isControllerInitialised = editController->initialize (dynamic_cast<Vst::IComponentHandler*> (host.get())) == kResultTrue;
jassert (isControllerInitialised);
editController->setComponentHandler (host);
grabInformationObjects();
synchroniseStates();
interconnectComponentAndController();
setupIO();
}
//==============================================================================
Vst::BusInfo getBusInfo (bool forInput, bool forAudio, int index = 0) const
{
@@ -2387,8 +2377,13 @@ AudioPluginInstance* VST3PluginFormat::createInstanceFromDescription (const Plug
file.getParentDirectory().setAsCurrentWorkingDirectory();
if (const VST3Classes::VST3ModuleHandle::Ptr module = VST3Classes::VST3ModuleHandle::findOrCreateModule (file, description))
{
result = new VST3Classes::VST3PluginInstance (module);
if (! result->initialise())
result = nullptr;
}
previousWorkingDirectory.setAsCurrentWorkingDirectory();
}


Loading…
Cancel
Save