Less weak plugin preset system (maybe AU preset stuff can use the 'normal' thing...
authorDavid Robillard <d@drobilla.net>
Sat, 14 Feb 2009 03:28:12 +0000 (03:28 +0000)
committerDavid Robillard <d@drobilla.net>
Sat, 14 Feb 2009 03:28:12 +0000 (03:28 +0000)
LV2 preset support as implemented in svn calf plugins (experimental extension).

git-svn-id: svn://localhost/ardour2/branches/3.0@4547 d708f5d6-7413-0410-9779-e7cbd77b26cf

SConstruct
gtk2_ardour/plugin_ui.cc
libs/ardour/ardour/lv2_plugin.h
libs/ardour/ardour/plugin.h
libs/ardour/audio_unit.cc
libs/ardour/lv2_plugin.cc
libs/ardour/plugin.cc

index e2536c60ad187cbc969c8eaabbc85b0a61a50dd2..1b4bc349b36ab9db41222fa187fed6604c896590 100644 (file)
@@ -594,12 +594,12 @@ else:
 if env['LV2']:
        conf = env.Configure(custom_tests = { 'CheckPKGVersion' : CheckPKGVersion})
        
-       if conf.CheckPKGVersion('slv2', '0.6.2'):
+       if conf.CheckPKGVersion('slv2', '0.6.4'):
                libraries['slv2'] = LibraryInfo()
                libraries['slv2'].ParseConfig('pkg-config --cflags --libs slv2')
                 env.Append (CCFLAGS="-DHAVE_LV2")
        else:
-               print 'LV2 support is not enabled (SLV2 not found or older than 0.6.0)'
+               print 'LV2 support is not enabled (SLV2 not found or older than 0.6.4 (svn))'
                env['LV2'] = 0
        conf.Finish()
 else:
index 336b7ea3df2ed567194c675ff418734ab5de1368..eae0d91388c866b1b2c0c81bd7eb79359dd19fb6 100644 (file)
@@ -342,8 +342,8 @@ PlugUIBase::PlugUIBase (boost::shared_ptr<PluginInsert> pi)
          bypass_button (_("Bypass")),
          latency_gui (*pi, pi->session().frame_rate(), pi->session().get_block_size())
 {
-        //preset_combo.set_use_arrows_always(true);
-       set_popdown_strings (preset_combo, plugin->get_presets());
+       //preset_combo.set_use_arrows_always(true);
+       update_presets();
        preset_combo.set_size_request (100, -1);
        preset_combo.set_active_text ("");
        preset_combo.signal_changed().connect(mem_fun(*this, &PlugUIBase::setting_selected));
@@ -389,8 +389,12 @@ void
 PlugUIBase::setting_selected()
 {
        if (preset_combo.get_active_text().length() > 0) {
-               if (!plugin->load_preset(preset_combo.get_active_text())) {
-                       warning << string_compose(_("Plugin preset %1 not found"), preset_combo.get_active_text()) << endmsg;
+               const Plugin::PresetRecord* pr = plugin->preset_by_label(preset_combo.get_active_text());
+               if (pr) {
+                       plugin->load_preset(pr->uri);
+               } else {
+                       warning << string_compose(_("Plugin preset %1 not found"),
+                                       preset_combo.get_active_text()) << endmsg;
                }
        }
 }
@@ -408,14 +412,11 @@ PlugUIBase::save_plugin_setting ()
 
        switch (prompter.run ()) {
        case Gtk::RESPONSE_ACCEPT:
-
                string name;
-
                prompter.get_result(name);
-
                if (name.length()) {
-                       if(plugin->save_preset(name)){
-                               set_popdown_strings (preset_combo, plugin->get_presets());
+                       if (plugin->save_preset(name)) {
+                               update_presets();
                                preset_combo.set_active_text (name);
                        }
                }
@@ -460,5 +461,11 @@ PlugUIBase::focus_toggled (GdkEventButton* ev)
 void
 PlugUIBase::update_presets ()
 {
-       set_popdown_strings (preset_combo, plugin->get_presets());
+       vector<string> preset_labels;
+       vector<ARDOUR::Plugin::PresetRecord> presets = plugin->get_presets();
+       for (vector<ARDOUR::Plugin::PresetRecord>::const_iterator i = presets.begin();
+                  i != presets.end(); ++i) {
+               preset_labels.push_back(i->label);
+       }
+       set_popdown_strings (preset_combo, preset_labels);
 }
index 7114428626e51edaaf1601450fe870cfbd146a12..bfc2be3ff12f9ac79221f54f270f6089ffa9b62b 100644 (file)
@@ -109,7 +109,9 @@ class LV2Plugin : public ARDOUR::Plugin
 
        XMLNode& get_state();
        int      set_state(const XMLNode& node);
-       bool     save_preset(std::string name);
+       bool     save_preset(std::string uri);
+       bool     load_preset(const string uri);
+       virtual std::vector<Plugin::PresetRecord> get_presets();
 
        bool has_editor() const;
 
@@ -129,6 +131,7 @@ class LV2Plugin : public ARDOUR::Plugin
        float*                   _latency_control_port;
        bool                     _was_activated;
        vector<bool>             _port_is_input;
+       map<string,uint32_t>     _port_indices;
 
        typedef struct { const void* (*extension_data)(const char* uri); } LV2_DataAccess;
        LV2_DataAccess _data_access_extension_data;
index bb81776d535827b3092f7c80e1e077aca75adb0d..68e94a9231ce9127e5272104b6aabb11b0eee234 100644 (file)
@@ -138,9 +138,19 @@ class Plugin : public PBD::StatefulDestructible, public Latent
        virtual bool parameter_is_input(uint32_t) const = 0;
        virtual bool parameter_is_output(uint32_t) const = 0;
 
-       virtual bool save_preset(string name) = 0;
-       virtual bool load_preset (const string preset_label);
-       virtual std::vector<std::string> get_presets();
+       virtual bool save_preset(string uri) = 0;
+       virtual bool load_preset (const string uri);
+
+       struct PresetRecord {
+               PresetRecord(const std::string& u, const std::string& l) : uri(u), label(l) {}
+               string uri;
+               string label;
+       };
+
+       virtual std::vector<PresetRecord> get_presets();
+
+       const PresetRecord* preset_by_label(const string& label);
+       const PresetRecord* preset_by_uri(const string& uri);
 
        virtual bool has_editor() const = 0;
 
@@ -189,8 +199,8 @@ class Plugin : public PBD::StatefulDestructible, public Latent
        ARDOUR::Session& _session;
        PluginInfoPtr _info;
        uint32_t _cycles;
-       map<string,string>       presets;
-       bool save_preset(string name, string domain /* vst, ladspa etc. */);
+       map<string,PresetRecord> presets;
+       bool save_preset(string uri, string domain /* vst, ladspa etc. */);
 };
 
 PluginPtr find_plugin(ARDOUR::Session&, string unique_id, ARDOUR::PluginType);
index 16d5e390f8610294f87dbe91ecd824bf7501d1af..4a432ba544483e8bb3a2e8f616a63a18cd64ee48 100644 (file)
@@ -806,10 +806,10 @@ AUPlugin::load_preset (const string preset_label)
        return false;
 }
 
-vector<string>
+vector<Plugin::PresetRecord>
 AUPlugin::get_presets ()
 {
-       vector<string> presets;
+       vector<PresetRecord> presets;
        
        return presets;
 }
index 906edb3bda439ee8fdd40bcc87270d32aeb9c927..03e3ea5bc264f60a29c57eec4125876a12d50794 100644 (file)
@@ -119,8 +119,10 @@ LV2Plugin::init (LV2World& world, SLV2Plugin plugin, nframes_t rate)
        uint32_t latency_port = (latent ? slv2_plugin_get_latency_port_index(plugin) : 0);
 
        for (uint32_t i = 0; i < num_ports; ++i) {
+               SLV2Port port = slv2_plugin_get_port_by_index(plugin, i);
+               SLV2Value sym = slv2_port_get_symbol(_plugin, port);
+               _port_indices.insert(std::make_pair(slv2_value_as_string(sym), i));
                if (parameter_is_control(i)) {
-                       SLV2Port port = slv2_plugin_get_port_by_index(plugin, i);
                        SLV2Value def;
                        slv2_port_get_range(plugin, port, &def, NULL, NULL);
                        _defaults[i] = def ? slv2_value_as_float(def) : 0.0f;
@@ -274,10 +276,50 @@ LV2Plugin::get_state()
        return *root;
 }
 
+vector<Plugin::PresetRecord>
+LV2Plugin::get_presets()
+{
+       vector<PresetRecord> result;
+       SLV2Results presets = slv2_plugin_query_sparql(_plugin,
+                       "PREFIX lv2p: <http://lv2plug.in/ns/dev/presets#>\n"
+                       "PREFIX dc:  <http://dublincore.org/documents/dcmi-namespace/>\n"
+                       "SELECT ?p ?name WHERE { <> lv2p:hasPreset ?p . ?p dc:title ?name }\n");
+       for (; !slv2_results_finished(presets); slv2_results_next(presets)) {
+               SLV2Value uri  = slv2_results_get_binding_value(presets, 0);
+               SLV2Value name = slv2_results_get_binding_value(presets, 1);
+               PresetRecord rec(slv2_value_as_string(uri), slv2_value_as_string(name));
+               result.push_back(rec);
+               this->presets.insert(std::make_pair(slv2_value_as_string(uri), rec));
+       }
+       slv2_results_free(presets);
+       return result;
+}
+
+bool
+LV2Plugin::load_preset(const string uri)
+{
+       const string query = string(
+                       "PREFIX lv2p: <http://lv2plug.in/ns/dev/presets#>\n"
+                       "PREFIX dc:  <http://dublincore.org/documents/dcmi-namespace/>\n"
+                       "SELECT ?sym ?val WHERE { <") + uri + "> lv2:port ?port . "
+                               " ?port lv2:symbol ?sym ; lv2p:value ?val . }";
+       SLV2Results values = slv2_plugin_query_sparql(_plugin, query.c_str());
+       for (; !slv2_results_finished(values); slv2_results_next(values)) {
+               SLV2Value sym  = slv2_results_get_binding_value(values, 0);
+               SLV2Value val = slv2_results_get_binding_value(values, 1);
+               if (slv2_value_is_float(val)) {
+                       uint32_t index = _port_indices[slv2_value_as_string(sym)];
+                       set_parameter(index, slv2_value_as_float(val));
+               }
+       }
+       slv2_results_free(values);
+       return true;
+}
+
 bool
 LV2Plugin::save_preset (string name)
 {
-       return Plugin::save_preset (name, "lv2");
+       return false;
 }
        
 bool
index c52a027915a4692bb56e6bee5958fe079be2a715..8a08811e7eaf3ee07ceeb00dcd7abaccf65723d5 100644 (file)
@@ -26,6 +26,7 @@
 #include <dirent.h>
 #include <sys/stat.h>
 #include <cerrno>
+#include <utility>
 
 #include <lrdf.h>
 
@@ -70,10 +71,33 @@ Plugin::~Plugin ()
 {
 }
 
-vector<string>
+const Plugin::PresetRecord*
+Plugin::preset_by_label(const string& label)
+{
+       // FIXME: O(n)
+       for (map<string,PresetRecord>::const_iterator i = presets.begin(); i != presets.end(); ++i) {
+               if (i->second.label == label) {
+                       return &i->second;
+               }
+       }
+       return NULL;
+}
+
+const Plugin::PresetRecord*
+Plugin::preset_by_uri(const string& uri)
+{
+       map<string,PresetRecord>::const_iterator pr = presets.find(uri);
+       if (pr != presets.end()) {
+               return &pr->second;
+       } else {
+               return NULL;
+       }
+}
+
+vector<Plugin::PresetRecord>
 Plugin::get_presets()
 {
-       vector<string> labels;
+       vector<PresetRecord> result;
        uint32_t id;
        std::string unique (unique_id());
 
@@ -83,7 +107,7 @@ Plugin::get_presets()
        */
 
        if (!isdigit (unique[0])) {
-               return labels;
+               return result;
        }
 
        id = atol (unique.c_str());
@@ -93,23 +117,21 @@ Plugin::get_presets()
        if (set_uris) {
                for (uint32_t i = 0; i < (uint32_t) set_uris->count; ++i) {
                        if (char* label = lrdf_get_label(set_uris->items[i])) {
-                               labels.push_back(label);
-                               presets[label] = set_uris->items[i];
+                               PresetRecord rec(set_uris->items[i], label);
+                               result.push_back(rec);
+                               presets.insert(std::make_pair(set_uris->items[i], rec));
                        }
                }
                lrdf_free_uris(set_uris);
        }
 
-       // GTK2FIX find an equivalent way to do this with a vector (needed by GUI apis)
-       // labels.unique();
-
-       return labels;
+       return result;
 }
 
 bool
-Plugin::load_preset(const string preset_label)
+Plugin::load_preset(const string preset_uri)
 {
-       lrdf_defaults* defs = lrdf_get_setting_values(presets[preset_label].c_str());
+       lrdf_defaults* defs = lrdf_get_setting_values(preset_uri.c_str());
 
        if (defs) {
                for (uint32_t i = 0; i < (uint32_t) defs->count; ++i) {
@@ -126,7 +148,7 @@ Plugin::load_preset(const string preset_label)
 }
 
 bool
-Plugin::save_preset (string name, string domain)
+Plugin::save_preset (string uri, string domain)
 {
        lrdf_portvalue portvalues[parameter_count()];
        lrdf_defaults defaults;
@@ -162,7 +184,12 @@ Plugin::save_preset (string name, string domain)
        
        string source(string_compose("file:%1/.%2/rdf/ardour-presets.n3", envvar, domain));
 
-       free(lrdf_add_preset(source.c_str(), name.c_str(), id,  &defaults));
+       map<string,PresetRecord>::const_iterator pr = presets.find(uri);
+       if (pr == presets.end()) {
+               warning << _("Could not find preset ") << uri << endmsg;
+               return false;
+       }
+       free(lrdf_add_preset(source.c_str(), pr->second.label.c_str(), id,  &defaults));
 
        string path = string_compose("%1/.%2", envvar, domain);
        if (g_mkdir_with_parents (path.c_str(), 0775)) {