finally get to the bottom of where NO_PLUGIN_STATE needs to be in order to be useful
[ardour.git] / libs / ardour / lv2_plugin.cc
index f7189be1634fd82cc09013da1bfdfc8972a37936..5ea76934a5ffe85923ee5be67d6c052aaacb45c5 100644 (file)
@@ -31,6 +31,7 @@
 
 #include <boost/utility.hpp>
 
+#include "pbd/pathscanner.h"
 #include "pbd/compose.h"
 #include "pbd/error.h"
 #include "pbd/xml++.h"
@@ -46,6 +47,7 @@
 #include "ardour/types.h"
 #include "ardour/utils.h"
 #include "ardour/worker.h"
+#include "ardour/lv2_bundled_search_path.h"
 
 #include "i18n.h"
 #include <locale.h>
@@ -110,6 +112,8 @@ public:
        LV2World ();
        ~LV2World ();
 
+       void load_bundled_plugins();
+
        LilvWorld* world;
 
        LilvNode* atom_AtomPort;
@@ -126,6 +130,7 @@ public:
        LilvNode* lv2_InputPort;
        LilvNode* lv2_OutputPort;
        LilvNode* lv2_enumeration;
+       LilvNode* lv2_freewheeling;
        LilvNode* lv2_inPlaceBroken;
        LilvNode* lv2_integer;
        LilvNode* lv2_reportsLatency;
@@ -137,6 +142,9 @@ public:
        LilvNode* time_Position;
        LilvNode* ui_GtkUI;
        LilvNode* ui_external;
+
+private:
+       bool _bundle_checked;
 };
 
 static LV2World _world;
@@ -1225,6 +1233,8 @@ LV2Plugin::set_state(const XMLNode& node, int version)
                return -1;
        }
 
+#ifndef NO_PLUGIN_STATE
+
        if (version < 3000) {
                nodes = node.children("port");
        } else {
@@ -1280,6 +1290,7 @@ LV2Plugin::set_state(const XMLNode& node, int version)
        }
 
        latency_compute_run();
+#endif
 
        return Plugin::set_state(node, version);
 }
@@ -1336,6 +1347,17 @@ LV2Plugin::describe_parameter(Evoral::Parameter which)
                                        lilv_plugin_get_port_by_index(_impl->plugin, which.id()), _world.ext_notOnGUI)) {
                        return X_("hidden");
                }
+
+               if (lilv_port_has_property(_impl->plugin,
+                                       lilv_plugin_get_port_by_index(_impl->plugin, which.id()), _world.lv2_freewheeling)) {
+                       return X_("hidden");
+               }
+
+               if (lilv_port_has_property(_impl->plugin,
+                                       lilv_plugin_get_port_by_index(_impl->plugin, which.id()), _world.lv2_sampleRate)) {
+                       return X_("hidden");
+               }
+
                if (lilv_port_has_property(_impl->plugin,
                                        lilv_plugin_get_port_by_index(_impl->plugin, which.id()), _world.lv2_reportsLatency)) {
                        return X_("latency");
@@ -1879,10 +1901,20 @@ LV2Plugin::Impl::designated_input (const char* uri, void** bufptrs[], void** buf
        return port;
 }
 
+static bool lv2_filter (const string& str, void *arg)
+{
+       /* Not a dotfile, has a prefix before a period, suffix is "lv2" */
+       
+       return str[0] != '.' && (str.length() > 3 && str.find (".lv2") == (str.length() - 4));
+}
+
+
 LV2World::LV2World()
        : world(lilv_world_new())
+       , _bundle_checked(false)
 {
        lilv_world_load_all(world);
+
        atom_AtomPort      = lilv_new_uri(world, LV2_ATOM__AtomPort);
        atom_Chunk         = lilv_new_uri(world, LV2_ATOM__Chunk);
        atom_Sequence      = lilv_new_uri(world, LV2_ATOM__Sequence);
@@ -1902,6 +1934,7 @@ LV2World::LV2World()
        lv2_sampleRate     = lilv_new_uri(world, LV2_CORE__sampleRate);
        lv2_toggled        = lilv_new_uri(world, LV2_CORE__toggled);
        lv2_enumeration    = lilv_new_uri(world, LV2_CORE__enumeration);
+       lv2_freewheeling   = lilv_new_uri(world, LV2_CORE__freeWheeling);
        midi_MidiEvent     = lilv_new_uri(world, LILV_URI_MIDI_EVENT);
        rdfs_comment       = lilv_new_uri(world, LILV_NS_RDFS "comment");
        rsz_minimumSize    = lilv_new_uri(world, LV2_RESIZE_PORT__minimumSize);
@@ -1919,6 +1952,7 @@ LV2World::~LV2World()
        lilv_node_free(rdfs_comment);
        lilv_node_free(midi_MidiEvent);
        lilv_node_free(lv2_enumeration);
+       lilv_node_free(lv2_freewheeling);
        lilv_node_free(lv2_toggled);
        lilv_node_free(lv2_sampleRate);
        lilv_node_free(lv2_reportsLatency);
@@ -1939,6 +1973,31 @@ LV2World::~LV2World()
        lilv_node_free(atom_AtomPort);
 }
 
+void
+LV2World::load_bundled_plugins()
+{
+       if (!_bundle_checked) {
+               cout << "Scanning folders for bundled LV2s: " << ARDOUR::lv2_bundled_search_path().to_string() << endl;
+               PathScanner scanner;
+               vector<string *> *plugin_objects = scanner (ARDOUR::lv2_bundled_search_path().to_string(), lv2_filter, 0, true, true);
+               if (plugin_objects) {
+                       for ( vector<string *>::iterator x = plugin_objects->begin(); x != plugin_objects->end (); ++x) {
+#ifdef WINDOWS
+                               string uri = "file:///" + **x + "/";
+#else
+                               string uri = "file://" + **x + "/";
+#endif
+                               LilvNode *node = lilv_new_uri(world, uri.c_str());
+                               lilv_world_load_bundle(world, node);
+                               lilv_node_free(node);
+                       }
+               }
+               delete (plugin_objects);
+
+               _bundle_checked = true;
+       }
+}
+
 LV2PluginInfo::LV2PluginInfo (const void* c_plugin)
        : _c_plugin(c_plugin)
 {
@@ -1970,6 +2029,8 @@ LV2PluginInfo::load(Session& session)
 PluginInfoList*
 LV2PluginInfo::discover()
 {
+       _world.load_bundled_plugins();
+
        PluginInfoList*    plugs   = new PluginInfoList;
        const LilvPlugins* plugins = lilv_world_get_all_plugins(_world.world);