Skip to content

Commit

Permalink
Refactor supported Lv2 features
Browse files Browse the repository at this point in the history
... from multiple places in Lv2Proc into Lv2Manager.
  • Loading branch information
JohannesLorenz committed Jul 26, 2020
1 parent 2f7d0b5 commit 5c94781
Show file tree
Hide file tree
Showing 4 changed files with 58 additions and 12 deletions.
6 changes: 6 additions & 0 deletions include/Lv2Manager.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
#ifdef LMMS_HAVE_LV2

#include <map>
#include <set>
#include <lilv/lilv.h>

#include "Lv2Basics.h"
Expand Down Expand Up @@ -116,12 +117,17 @@ class Lv2Manager
Iterator end() { return m_lv2InfoMap.end(); }

UridMap& uridMap() { return m_uridMap; }
const std::set<const char*>& 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<const char*> m_supportedFeatureURIs;
bool isSubclassOf(const LilvPluginClass *clvss, const char *uriStr);
};

Expand Down
8 changes: 7 additions & 1 deletion include/Lv2Proc.h
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,10 @@ class Lv2Proc : public LinkedModelGroup

const LilvPlugin* m_plugin;
LilvInstance* m_instance;
std::vector<LV2_Feature*> m_features;
//!< feature storage
std::vector<LV2_Feature> m_features;
//!< pointers to m_features, required for lilv_plugin_instantiate
std::vector<const LV2_Feature*> m_featurePointers;

std::vector<std::unique_ptr<Lv2Ports::PortBase>> m_ports;
StereoPortRef m_inPorts, m_outPorts;
Expand All @@ -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);
Expand Down
3 changes: 3 additions & 0 deletions src/core/lv2/Lv2Manager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}


Expand Down
53 changes: 42 additions & 11 deletions src/core/lv2/Lv2Proc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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())
Expand Down Expand Up @@ -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)
{
Expand All @@ -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; }
}


Expand Down Expand Up @@ -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<const char*, void*> 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<const char* const, void*>& 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,
Expand Down

0 comments on commit 5c94781

Please sign in to comment.