summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ingen/LV2Features.hpp3
-rw-r--r--ingen/URIMap.hpp2
-rw-r--r--src/LV2Features.cpp6
-rw-r--r--src/server/BlockFactory.cpp61
-rw-r--r--src/server/LV2Options.hpp4
-rw-r--r--src/server/LV2ResizeFeature.hpp2
-rw-r--r--src/server/Worker.hpp2
7 files changed, 73 insertions, 7 deletions
diff --git a/ingen/LV2Features.hpp b/ingen/LV2Features.hpp
index 80339c84..214d62bb 100644
--- a/ingen/LV2Features.hpp
+++ b/ingen/LV2Features.hpp
@@ -40,6 +40,8 @@ public:
public:
virtual ~Feature() {}
+ virtual const char* uri() const = 0;
+
virtual SharedPtr<LV2_Feature> feature(World* world,
Node* block) = 0;
};
@@ -60,6 +62,7 @@ public:
};
void add_feature(SharedPtr<Feature> feature);
+ bool is_supported(const std::string& uri) const;
SharedPtr<FeatureArray> lv2_features(World* world,
Node* block) const;
diff --git a/ingen/URIMap.hpp b/ingen/URIMap.hpp
index 5f3aca63..e5ca71e3 100644
--- a/ingen/URIMap.hpp
+++ b/ingen/URIMap.hpp
@@ -46,6 +46,8 @@ public:
_feature.data = data;
}
+ const char* uri() const { return _feature.URI; }
+
SharedPtr<LV2_Feature> feature(World*, Node*) {
return SharedPtr<LV2_Feature>(&_feature, NullDeleter<LV2_Feature>);
}
diff --git a/src/LV2Features.cpp b/src/LV2Features.cpp
index 122f794e..612cd9f7 100644
--- a/src/LV2Features.cpp
+++ b/src/LV2Features.cpp
@@ -47,6 +47,12 @@ LV2Features::FeatureArray::~FeatureArray()
free(_array);
}
+bool
+LV2Features::is_supported(const std::string& uri) const
+{
+ return false;
+}
+
SharedPtr<LV2Features::FeatureArray>
LV2Features::lv2_features(World* world, Node* node) const
{
diff --git a/src/server/BlockFactory.cpp b/src/server/BlockFactory.cpp
index 484e0c63..6d961047 100644
--- a/src/server/BlockFactory.cpp
+++ b/src/server/BlockFactory.cpp
@@ -18,6 +18,7 @@
#include "lilv/lilv.h"
+#include "ingen/LV2Features.hpp"
#include "ingen/Log.hpp"
#include "ingen/World.hpp"
#include "internals/Controller.hpp"
@@ -118,24 +119,72 @@ BlockFactory::load_plugin(const Raul::URI& uri)
void
BlockFactory::load_lv2_plugins()
{
+ // Build an array of port type nodes for checking compatibility
+ typedef std::vector< SharedPtr<LilvNode> > Types;
+ Types types;
+ for (unsigned t = PortType::AUDIO; t <= PortType::ATOM; ++t) {
+ const Raul::URI& uri(PortType((PortType::Symbol)t).uri());
+ types.push_back(SharedPtr<LilvNode>(
+ lilv_new_uri(_world->lilv_world(), uri.c_str()),
+ lilv_node_free));
+ }
+
const LilvPlugins* plugins = lilv_world_get_all_plugins(_world->lilv_world());
LILV_FOREACH(plugins, i, plugins) {
const LilvPlugin* lv2_plug = lilv_plugins_get(plugins, i);
const Raul::URI uri(lilv_node_as_uri(lilv_plugin_get_uri(lv2_plug)));
+
+ // Ignore plugins that require features Ingen doesn't support
+ LilvNodes* features = lilv_plugin_get_required_features(lv2_plug);
+ bool supported = true;
+ LILV_FOREACH(nodes, f, features) {
+ const char* feature = lilv_node_as_uri(lilv_nodes_get(features, f));
+ if (!_world->lv2_features().is_supported(feature)) {
+ supported = false;
+ _world->log().warn(
+ Raul::fmt("Ignoring <%1%>; required feature <%2%>\n")
+ % uri % feature);
+ break;
+ }
+ }
+ if (!supported) {
+ continue;
+ }
+
+ // Ignore plugins that are missing ports
if (!lilv_plugin_get_port_by_index(lv2_plug, 0)) {
_world->log().warn(
- Raul::fmt("Ignoring plugin <%1%> with invalid ports\n") % uri);
+ Raul::fmt("Ignoring <%1%>; missing or corrupt ports\n") % uri);
continue;
}
- if (_plugins.find(uri) != _plugins.end()) {
+ const uint32_t n_ports = lilv_plugin_get_num_ports(lv2_plug);
+ for (uint32_t p = 0; p < n_ports; ++p) {
+ const LilvPort* port = lilv_plugin_get_port_by_index(lv2_plug, p);
+ supported = false;
+ for (Types::const_iterator t = types.begin(); t != types.end(); ++t) {
+ if (lilv_port_is_a(lv2_plug, port, t->get())) {
+ supported = true;
+ break;
+ }
+ }
+ if (!supported) {
+ _world->log().warn(
+ Raul::fmt("Ignoring <%1%>; unsupported port <%2%>\n")
+ % uri % lilv_node_as_string(
+ lilv_port_get_symbol(lv2_plug, port)));
+ break;
+ }
+ }
+ if (!supported) {
continue;
}
- LV2Plugin* const plugin = new LV2Plugin(_lv2_info, uri);
-
- plugin->lilv_plugin(lv2_plug);
- _plugins.insert(make_pair(uri, plugin));
+ if (_plugins.find(uri) == _plugins.end()) {
+ LV2Plugin* const plugin = new LV2Plugin(_lv2_info, uri);
+ plugin->lilv_plugin(lv2_plug);
+ _plugins.insert(make_pair(uri, plugin));
+ }
}
}
diff --git a/src/server/LV2Options.hpp b/src/server/LV2Options.hpp
index ee8e3ee6..5f100f2a 100644
--- a/src/server/LV2Options.hpp
+++ b/src/server/LV2Options.hpp
@@ -48,7 +48,9 @@ struct LV2Options : public Ingen::LV2Features::Feature {
engine.world()->uris().atom_Sequence);
}
}
-
+
+ const char* uri() const { return LV2_OPTIONS__options; }
+
SharedPtr<LV2_Feature> feature(World* w, Node* n) {
BlockImpl* block = dynamic_cast<BlockImpl*>(n);
if (!block) {
diff --git a/src/server/LV2ResizeFeature.hpp b/src/server/LV2ResizeFeature.hpp
index 47f30e41..8edd7868 100644
--- a/src/server/LV2ResizeFeature.hpp
+++ b/src/server/LV2ResizeFeature.hpp
@@ -47,6 +47,8 @@ struct ResizeFeature : public Ingen::LV2Features::Feature {
free(feature);
}
+ const char* uri() const { return LV2_RESIZE_PORT_URI; }
+
SharedPtr<LV2_Feature> feature(World* w, Node* n) {
BlockImpl* block = dynamic_cast<BlockImpl*>(n);
if (!block)
diff --git a/src/server/Worker.hpp b/src/server/Worker.hpp
index 9b69edb2..69597439 100644
--- a/src/server/Worker.hpp
+++ b/src/server/Worker.hpp
@@ -38,6 +38,8 @@ public:
~Worker();
struct Schedule : public LV2Features::Feature {
+ const char* uri() const { return LV2_WORKER__schedule; }
+
SharedPtr<LV2_Feature> feature(World* world, Node* n);
};