From 6c4bce84c3883dbf37da8c42c07bb13cc179e956 Mon Sep 17 00:00:00 2001 From: falkTX Date: Mon, 29 Oct 2012 05:12:11 +0000 Subject: [PATCH] Carla: Implement new lv2_lib_descriptor init call --- c++/carla-backend/carla_engine.cpp | 2 + c++/carla-backend/carla_plugin.h | 6 + c++/carla-backend/lv2.cpp | 219 ++++++++++++++++++----------- 3 files changed, 146 insertions(+), 81 deletions(-) diff --git a/c++/carla-backend/carla_engine.cpp b/c++/carla-backend/carla_engine.cpp index 31fafe3..c60e756 100644 --- a/c++/carla-backend/carla_engine.cpp +++ b/c++/carla-backend/carla_engine.cpp @@ -22,6 +22,8 @@ CARLA_BACKEND_START_NAMESPACE // ----------------------------------------------------------------------- +unsigned int CarlaPlugin::m_count = 0; + unsigned short CarlaEngine::m_maxPluginNumber = 0; CarlaEngine::CarlaEngine() diff --git a/c++/carla-backend/carla_plugin.h b/c++/carla-backend/carla_plugin.h index 3474f76..44d8ab6 100644 --- a/c++/carla-backend/carla_plugin.h +++ b/c++/carla-backend/carla_plugin.h @@ -239,6 +239,8 @@ public: osc.data.target = nullptr; osc.thread = nullptr; #endif + + m_count += 1; } /*! @@ -302,6 +304,8 @@ public: } custom.clear(); } + + m_count -= 1; } // ------------------------------------------------------------------- @@ -2206,6 +2210,8 @@ protected: // ------------------------------------------------------------------- // Utilities + static unsigned int m_count; + static double fixParameterValue(double& value, const ParameterRanges& ranges) { if (value < ranges.min) diff --git a/c++/carla-backend/lv2.cpp b/c++/carla-backend/lv2.cpp index 88f5431..68ef65f 100644 --- a/c++/carla-backend/lv2.cpp +++ b/c++/carla-backend/lv2.cpp @@ -24,6 +24,8 @@ #include "lv2_atom_queue.h" #include "rtmempool/rtmempool.h" +#include + #include #include @@ -458,6 +460,18 @@ public: } customURIDs.clear(); + + // cleanup all descriptors if this is the last plugin loaded + if (m_count == 1) + { + for (auto it = libDescs.begin(); it != libDescs.end(); it++) + { + const LV2_Lib_Descriptor* libDesc(*it); + libDesc->cleanup(libDesc->handle); + } + + libDescs.clear(); + } } // ------------------------------------------------------------------- @@ -3813,84 +3827,6 @@ public: return false; } - // --------------------------------------------------------------- - // get DLL main entry - - const LV2_Descriptor_Function descFn = (LV2_Descriptor_Function)libSymbol("lv2_descriptor"); - - if (! descFn) - { - setLastError("Could not find the LV2 Descriptor in the plugin library"); - return false; - } - - // --------------------------------------------------------------- - // get descriptor that matches URI - - uint32_t i = 0; - while ((descriptor = descFn(i++))) - { - if (strcmp(descriptor->URI, URI) == 0) - break; - } - - if (! descriptor) - { - setLastError("Could not find the requested plugin URI in the plugin library"); - return false; - } - - // --------------------------------------------------------------- - // check supported port-types and features - - bool canContinue = true; - - // Check supported ports - for (i=0; i < rdf_descriptor->PortCount; i++) - { - LV2_Property PortType = rdf_descriptor->Ports[i].Type; - if (! bool(LV2_IS_PORT_AUDIO(PortType) || LV2_IS_PORT_CONTROL(PortType) || LV2_IS_PORT_ATOM_SEQUENCE(PortType) || LV2_IS_PORT_EVENT(PortType) || LV2_IS_PORT_MIDI_LL(PortType))) - { - if (! LV2_IS_PORT_OPTIONAL(rdf_descriptor->Ports[i].Properties)) - { - setLastError("Plugin requires a port that is not currently supported"); - canContinue = false; - break; - } - } - } - - // Check supported features - for (i=0; i < rdf_descriptor->FeatureCount && canContinue; i++) - { - if (LV2_IS_FEATURE_REQUIRED(rdf_descriptor->Features[i].Type) && ! is_lv2_feature_supported(rdf_descriptor->Features[i].URI)) - { - QString msg = QString("Plugin requires a feature that is not supported:\n%1").arg(rdf_descriptor->Features[i].URI); - setLastError(msg.toUtf8().constData()); - canContinue = false; - break; - } - } - - // Check extensions - for (i=0; i < rdf_descriptor->ExtensionCount; i++) - { - if (strcmp(rdf_descriptor->Extensions[i], LV2_PROGRAMS__Interface) == 0) - m_hints |= PLUGIN_HAS_EXTENSION_PROGRAMS; - else if (strcmp(rdf_descriptor->Extensions[i], LV2_STATE__interface) == 0) - m_hints |= PLUGIN_HAS_EXTENSION_STATE; - else if (strcmp(rdf_descriptor->Extensions[i], LV2_WORKER__interface) == 0) - m_hints |= PLUGIN_HAS_EXTENSION_WORKER; - else - qDebug("Plugin has non-supported extension: '%s'", rdf_descriptor->Extensions[i]); - } - - if (! canContinue) - { - // error already set - return false; - } - // --------------------------------------------------------------- // initialize features @@ -4014,6 +3950,123 @@ public: features[lv2_feature_id_worker]->URI = LV2_WORKER__schedule; features[lv2_feature_id_worker]->data = workerFt; + // --------------------------------------------------------------- + // get DLL main entry + + const LV2_Lib_Descriptor_Function descLibFn = (LV2_Lib_Descriptor_Function)libSymbol("lv2_lib_descriptor"); + + if (descLibFn) + { + // ----------------------------------------------------------- + // get lib descriptor + + const LV2_Lib_Descriptor* libDesc = descLibFn(rdf_descriptor->Bundle, features); + + if (! libDesc) + { + setLastError("Plugin failed to return library descriptor"); + return false; + } + + // ----------------------------------------------------------- + // get descriptor that matches URI + + uint32_t i = 0; + while ((descriptor = libDesc->get_plugin(libDesc->handle, i++))) + { + if (strcmp(descriptor->URI, URI) == 0) + break; + } + + if (libDescs.count(libDesc) > 0) + { + if (! descriptor) + libDesc->cleanup(libDesc->handle); + } + else + libDescs.insert(libDesc); + } + else + { + const LV2_Descriptor_Function descFn = (LV2_Descriptor_Function)libSymbol("lv2_descriptor"); + + // ----------------------------------------------------------- + // if no descriptor function found, return error + + if (! descFn) + { + setLastError("Could not find the LV2 Descriptor in the plugin library"); + return false; + } + + // ----------------------------------------------------------- + // get descriptor that matches URI + + uint32_t i = 0; + while ((descriptor = descFn(i++))) + { + if (strcmp(descriptor->URI, URI) == 0) + break; + } + } + + if (! descriptor) + { + setLastError("Could not find the requested plugin URI in the plugin library"); + return false; + } + + // --------------------------------------------------------------- + // check supported port-types and features + + bool canContinue = true; + + // Check supported ports + for (uint32_t i=0; i < rdf_descriptor->PortCount; i++) + { + LV2_Property PortType = rdf_descriptor->Ports[i].Type; + if (! bool(LV2_IS_PORT_AUDIO(PortType) || LV2_IS_PORT_CONTROL(PortType) || LV2_IS_PORT_ATOM_SEQUENCE(PortType) || LV2_IS_PORT_EVENT(PortType) || LV2_IS_PORT_MIDI_LL(PortType))) + { + if (! LV2_IS_PORT_OPTIONAL(rdf_descriptor->Ports[i].Properties)) + { + setLastError("Plugin requires a port that is not currently supported"); + canContinue = false; + break; + } + } + } + + // Check supported features + for (uint32_t i=0; i < rdf_descriptor->FeatureCount && canContinue; i++) + { + if (LV2_IS_FEATURE_REQUIRED(rdf_descriptor->Features[i].Type) && ! is_lv2_feature_supported(rdf_descriptor->Features[i].URI)) + { + QString msg = QString("Plugin requires a feature that is not supported:\n%1").arg(rdf_descriptor->Features[i].URI); + setLastError(msg.toUtf8().constData()); + canContinue = false; + break; + } + } + + // Check extensions + for (uint32_t i=0; i < rdf_descriptor->ExtensionCount; i++) + { + if (strcmp(rdf_descriptor->Extensions[i], LV2_PROGRAMS__Interface) == 0) + m_hints |= PLUGIN_HAS_EXTENSION_PROGRAMS; + else if (strcmp(rdf_descriptor->Extensions[i], LV2_STATE__interface) == 0) + m_hints |= PLUGIN_HAS_EXTENSION_STATE; + else if (strcmp(rdf_descriptor->Extensions[i], LV2_WORKER__interface) == 0) + m_hints |= PLUGIN_HAS_EXTENSION_WORKER; + else + qDebug("Plugin has non-supported extension: '%s'", rdf_descriptor->Extensions[i]); + } + + if (! canContinue) + { + // error already set + return false; + } + // --------------------------------------------------------------- // get info @@ -4058,7 +4111,7 @@ public: int eQt4, eCocoa, eHWND, eX11, eGtk2, eGtk3, iCocoa, iHWND, iX11, iQt4, iExt, iSuil, iFinal; eQt4 = eCocoa = eHWND = eX11 = eGtk2 = eGtk3 = iQt4 = iCocoa = iHWND = iX11 = iExt = iSuil = iFinal = -1; - for (i=0; i < rdf_descriptor->UICount; i++) + for (uint32_t i=0; i < rdf_descriptor->UICount; i++) { switch (rdf_descriptor->UIs[i].Type) { @@ -4172,7 +4225,7 @@ public: canContinue = true; - for (i=0; i < ui.rdf_descriptor->FeatureCount; i++) + for (uint32_t i=0; i < ui.rdf_descriptor->FeatureCount; i++) { if (LV2_IS_FEATURE_REQUIRED(ui.rdf_descriptor->Features[i].Type) && is_lv2_ui_feature_supported(ui.rdf_descriptor->Features[i].URI) == false) { @@ -4226,7 +4279,7 @@ public: // ------------------------------------------------------- // get descriptor that matches URI - i = 0; + uint32_t i = 0; while ((ui.descriptor = ui_descFn(i++))) { if (strcmp(ui.descriptor->URI, ui.rdf_descriptor->URI) == 0) @@ -4431,8 +4484,12 @@ private: bool lastTimePosPlaying; uint32_t lastTimePosFrame; + + static std::set libDescs; }; +std::set Lv2Plugin::libDescs; + /**@}*/ // -------------------------------------------------------------------------------------------------------------------