summaryrefslogtreecommitdiffstats
path: root/src/server/BlockFactory.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/server/BlockFactory.cpp')
-rw-r--r--src/server/BlockFactory.cpp61
1 files changed, 55 insertions, 6 deletions
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));
+ }
}
}