diff --git a/libs/ardour/ardour/vst3_plugin.h b/libs/ardour/ardour/vst3_plugin.h index 5798ecb8c7..c71052f0a7 100644 --- a/libs/ardour/ardour/vst3_plugin.h +++ b/libs/ardour/ardour/vst3_plugin.h @@ -108,7 +108,7 @@ public: FUID const& fuid () const { return _fuid; } /* Ardour Preset Helpers */ - Vst::IUnitInfo* unit_info (); + IPtr unit_info (); Vst::ParameterInfo const& program_change_port () const { return _program_change_port; } void set_n_factory_presets (size_t n) { _n_factory_presets = n; } diff --git a/libs/ardour/vst3_module.cc b/libs/ardour/vst3_module.cc index f954d28910..7870c37c95 100644 --- a/libs/ardour/vst3_module.cc +++ b/libs/ardour/vst3_module.cc @@ -232,6 +232,7 @@ VST3PluginModule::factory () GetFactoryProc fp = (GetFactoryProc)fn_ptr ("GetPluginFactory"); if (fp) { _factory = fp (); + _factory->addRef (); } } return _factory; diff --git a/libs/ardour/vst3_plugin.cc b/libs/ardour/vst3_plugin.cc index ed2f3ce5b3..9d5eda413c 100644 --- a/libs/ardour/vst3_plugin.cc +++ b/libs/ardour/vst3_plugin.cc @@ -855,7 +855,7 @@ VST3Plugin::find_presets () _preset_uri_map.clear (); /* read vst3UnitPrograms */ - Vst::IUnitInfo* nfo = _plug->unit_info (); + IPtr nfo = _plug->unit_info (); if (nfo && _plug->program_change_port ().id != Vst::kNoParamId) { Vst::UnitID program_unit_id = _plug->program_change_port ().unitId; @@ -1053,14 +1053,16 @@ VST3PI::VST3PI (boost::shared_ptr m, std::string uniqu #endif if (factory->createInstance (_fuid.toTUID (), Vst::IComponent::iid, (void**)&_component) != kResultTrue) { + DEBUG_TRACE (DEBUG::VST3Config, "VST3PI create instance failed\n"); throw failed_constructor (); } if (!_component || _component->initialize (HostApplication::getHostContext ()) != kResultOk) { + DEBUG_TRACE (DEBUG::VST3Config, "VST3PI component initialize failed\n"); throw failed_constructor (); } - _controller = FUnknownPtr (_component); + _controller = FUnknownPtr (_component).take (); if (!_controller) { TUID controllerCID; @@ -1073,30 +1075,44 @@ VST3PI::VST3PI (boost::shared_ptr m, std::string uniqu } } - if (_controller && (_controller->initialize (HostApplication::getHostContext ()) != kResultOk)) { + if (!_controller) { + DEBUG_TRACE (DEBUG::VST3Config, "VST3PI no controller was found\n"); _component->terminate (); _component->release (); throw failed_constructor (); } - if (!_controller) { - _component->terminate (); - _component->release (); - throw failed_constructor (); - } + /* The official Steinberg SDK's source/vst/hosting/plugprovider.cpp + * only initializes the controller if it is separate of the component. + * + * However some plugins expect and unconditional call and other + * hosts incl. JUCE based one initialize a controller separately because + * FUnknownPtr<> cast may return a new obeject. + * + * So do not check for errors. + * if Vst::IEditController is-a Vst::IComponent the Controller + * may or may not already be initialized. + */ + _controller->initialize (HostApplication::getHostContext ()); if (_controller->setComponentHandler (this) != kResultOk) { + _controller->terminate (); + _controller->release (); _component->terminate (); _component->release (); throw failed_constructor (); } - if (!(_processor = FUnknownPtr (_component))) { + if (!(_processor = FUnknownPtr (_component).take ())) { + _controller->terminate (); + _controller->release (); _component->terminate (); _component->release (); throw failed_constructor (); } + _processor->addRef (); + /* prepare process context */ memset (&_context, 0, sizeof (Vst::ProcessContext)); @@ -1195,10 +1211,10 @@ VST3PI::~VST3PI () terminate (); } -Vst::IUnitInfo* +IPtr VST3PI::unit_info () { - Vst::IUnitInfo* nfo = FUnknownPtr (_component); + IPtr nfo = FUnknownPtr (_component); if (nfo) { return nfo; } @@ -1206,7 +1222,7 @@ VST3PI::unit_info () } #if 0 -Vst::IUnitData* +IPtr VST3PI::unit_data () { Vst::IUnitData* iud = FUnknownPtr (_component); @@ -1226,26 +1242,19 @@ VST3PI::terminate () deactivate (); + _processor->release (); _processor = 0; disconnect_components (); - bool controller_is_component = false; - if (_component) { - controller_is_component = FUnknownPtr (_component) != 0; - _component->terminate (); - } - if (_controller) { _controller->setComponentHandler (0); - } - - if (_controller && controller_is_component == false) { _controller->terminate (); _controller->release (); } if (_component) { + _component->terminate (); _component->release (); } @@ -2934,7 +2943,7 @@ VST3PI::try_create_view () const view = _controller->createView (0); } if (!view) { - view = FUnknownPtr (_controller); + view = FUnknownPtr (_controller).take (); if (view) { view->addRef (); } diff --git a/libs/ardour/vst3_scan.cc b/libs/ardour/vst3_scan.cc index 5de69c64b8..dc7c46283d 100644 --- a/libs/ardour/vst3_scan.cc +++ b/libs/ardour/vst3_scan.cc @@ -139,7 +139,7 @@ discover_vst3 (boost::shared_ptr m, std::vector (factory); + IPtr factory2 = FUnknownPtr (factory); int32 class_cnt = factory->countClasses (); if (verbose) { @@ -203,7 +203,7 @@ discover_vst3 (boost::shared_ptr m, std::vector processor; + IPtr processor; if (!(processor = FUnknownPtr (component))) { cerr << "VST3: No valid processor"; component->terminate ();