From 5c94781cb83d1cedb6328cbb3d82476450a1f09d Mon Sep 17 00:00:00 2001 From: Johannes Lorenz Date: Sat, 25 Jul 2020 05:21:12 +0200 Subject: [PATCH] Refactor supported Lv2 features ... from multiple places in Lv2Proc into Lv2Manager. --- include/Lv2Manager.h | 6 +++++ include/Lv2Proc.h | 8 +++++- src/core/lv2/Lv2Manager.cpp | 3 +++ src/core/lv2/Lv2Proc.cpp | 53 +++++++++++++++++++++++++++++-------- 4 files changed, 58 insertions(+), 12 deletions(-) diff --git a/include/Lv2Manager.h b/include/Lv2Manager.h index 4e96381b019..7da3ad7b83c 100644 --- a/include/Lv2Manager.h +++ b/include/Lv2Manager.h @@ -30,6 +30,7 @@ #ifdef LMMS_HAVE_LV2 #include +#include #include #include "Lv2Basics.h" @@ -116,12 +117,17 @@ class Lv2Manager Iterator end() { return m_lv2InfoMap.end(); } UridMap& uridMap() { return m_uridMap; } + const std::set& supportedFeatureURIs() const + { + return m_supportedFeatureURIs; + } private: bool m_debug; //!< if set, debug output will be printed LilvWorld* m_world; Lv2InfoMap m_lv2InfoMap; UridMap m_uridMap; + std::set m_supportedFeatureURIs; bool isSubclassOf(const LilvPluginClass *clvss, const char *uriStr); }; diff --git a/include/Lv2Proc.h b/include/Lv2Proc.h index bee06145d1e..011ba2d5547 100644 --- a/include/Lv2Proc.h +++ b/include/Lv2Proc.h @@ -156,7 +156,10 @@ class Lv2Proc : public LinkedModelGroup const LilvPlugin* m_plugin; LilvInstance* m_instance; - std::vector m_features; + //!< feature storage + std::vector m_features; + //!< pointers to m_features, required for lilv_plugin_instantiate + std::vector m_featurePointers; std::vector> m_ports; StereoPortRef m_inPorts, m_outPorts; @@ -175,6 +178,9 @@ class Lv2Proc : public LinkedModelGroup void dumpPort(std::size_t num); + //! fill m_features and m_featurePointers + void initFeatures(); + static bool portIsSideChain(const LilvPlugin* plugin, const LilvPort *port); static bool portIsOptional(const LilvPlugin* plugin, const LilvPort *port); static AutoLilvNode uri(const char* uriStr); diff --git a/src/core/lv2/Lv2Manager.cpp b/src/core/lv2/Lv2Manager.cpp index bce3bf372ca..f0f82c67726 100644 --- a/src/core/lv2/Lv2Manager.cpp +++ b/src/core/lv2/Lv2Manager.cpp @@ -50,6 +50,9 @@ Lv2Manager::Lv2Manager() m_world = lilv_world_new(); lilv_world_load_all(m_world); + + m_supportedFeatureURIs.insert(LV2_URID__map); + m_supportedFeatureURIs.insert(LV2_URID__unmap); } diff --git a/src/core/lv2/Lv2Proc.cpp b/src/core/lv2/Lv2Proc.cpp index 40596312c77..40ea18a9ede 100644 --- a/src/core/lv2/Lv2Proc.cpp +++ b/src/core/lv2/Lv2Proc.cpp @@ -74,11 +74,16 @@ Plugin::PluginTypes Lv2Proc::check(const LilvPlugin *plugin, AutoLilvNodes reqFeats(lilv_plugin_get_required_features(plugin)); LILV_FOREACH (nodes, itr, reqFeats.get()) { - const char* featName = lilv_node_as_string( + const char* reqFeatName = lilv_node_as_string( lilv_nodes_get(reqFeats.get(), itr)); - if( strcmp(featName, LV2_URID__map) - && strcmp(featName, LV2_URID__unmap)) - issues.emplace_back(featureNotSupported, featName); + bool found = false; + for(const char* supportedFeatName : + Engine::getLv2Manager()->supportedFeatureURIs()) + if(!strcmp(reqFeatName, supportedFeatName)) + { + found = true; break; + } + if(!found) { issues.emplace_back(featureNotSupported, reqFeatName); } } if (printIssues && issues.size()) @@ -243,15 +248,12 @@ AutomatableModel *Lv2Proc::modelAtPort(const QString &uri) void Lv2Proc::initPlugin() { - Lv2Manager* man = Engine::getLv2Manager(); - m_features.push_back(new LV2_Feature { LV2_URID__map, man->uridMap().mapFeature() }); - m_features.push_back(new LV2_Feature { LV2_URID__unmap, man->uridMap().unmapFeature() }); - m_features.push_back(nullptr); + initFeatures(); createPorts(); m_instance = lilv_plugin_instantiate(m_plugin, Engine::mixer()->processingSampleRate(), - m_features.data()); + m_featurePointers.data()); if (m_instance) { @@ -278,8 +280,6 @@ void Lv2Proc::shutdownPlugin() lilv_instance_deactivate(m_instance); lilv_instance_free(m_instance); m_instance = nullptr; - - for(LV2_Feature* feat : m_features) { delete feat; } } @@ -526,6 +526,37 @@ void Lv2Proc::dumpPort(std::size_t num) +// fill m_features and m_featurePointers +void Lv2Proc::initFeatures() +{ + Lv2Manager* man = Engine::getLv2Manager(); + + // create map feature URI -> feature + std::map featureByUri; + for(const char* uri : man->supportedFeatureURIs()) + { + featureByUri.emplace(uri, nullptr); + } + featureByUri[LV2_URID__map] = man->uridMap().mapFeature(); + featureByUri[LV2_URID__unmap] = man->uridMap().unmapFeature(); + + // create vector of features + for(std::pair& pr : featureByUri) + { + assert(pr.second != nullptr); + m_features.push_back(LV2_Feature { pr.first, pr.second }); + } + // create pointer vector (for lilv_plugin_instantiate) + for(std::size_t i = 0; i < m_features.size(); ++i) + { + m_featurePointers.push_back(&m_features[i]); + } + m_featurePointers.push_back(nullptr); +} + + + + bool Lv2Proc::portIsSideChain(const LilvPlugin *plugin, const LilvPort *port) { return lilv_port_has_property(plugin, port,