Less weak plugin preset system (maybe AU preset stuff can use the 'normal' thing instead of being all weird now?).

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
This commit is contained in:
David Robillard 2009-02-14 03:28:12 +00:00
parent f609d97ccd
commit ef172d7ad6
7 changed files with 124 additions and 35 deletions

View File

@ -594,12 +594,12 @@ else:
if env['LV2']: if env['LV2']:
conf = env.Configure(custom_tests = { 'CheckPKGVersion' : CheckPKGVersion}) 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'] = LibraryInfo()
libraries['slv2'].ParseConfig('pkg-config --cflags --libs slv2') libraries['slv2'].ParseConfig('pkg-config --cflags --libs slv2')
env.Append (CCFLAGS="-DHAVE_LV2") env.Append (CCFLAGS="-DHAVE_LV2")
else: 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 env['LV2'] = 0
conf.Finish() conf.Finish()
else: else:

View File

@ -342,8 +342,8 @@ PlugUIBase::PlugUIBase (boost::shared_ptr<PluginInsert> pi)
bypass_button (_("Bypass")), bypass_button (_("Bypass")),
latency_gui (*pi, pi->session().frame_rate(), pi->session().get_block_size()) latency_gui (*pi, pi->session().frame_rate(), pi->session().get_block_size())
{ {
//preset_combo.set_use_arrows_always(true); //preset_combo.set_use_arrows_always(true);
set_popdown_strings (preset_combo, plugin->get_presets()); update_presets();
preset_combo.set_size_request (100, -1); preset_combo.set_size_request (100, -1);
preset_combo.set_active_text (""); preset_combo.set_active_text ("");
preset_combo.signal_changed().connect(mem_fun(*this, &PlugUIBase::setting_selected)); preset_combo.signal_changed().connect(mem_fun(*this, &PlugUIBase::setting_selected));
@ -389,8 +389,12 @@ void
PlugUIBase::setting_selected() PlugUIBase::setting_selected()
{ {
if (preset_combo.get_active_text().length() > 0) { if (preset_combo.get_active_text().length() > 0) {
if (!plugin->load_preset(preset_combo.get_active_text())) { const Plugin::PresetRecord* pr = plugin->preset_by_label(preset_combo.get_active_text());
warning << string_compose(_("Plugin preset %1 not found"), preset_combo.get_active_text()) << endmsg; 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 ()) { switch (prompter.run ()) {
case Gtk::RESPONSE_ACCEPT: case Gtk::RESPONSE_ACCEPT:
string name; string name;
prompter.get_result(name); prompter.get_result(name);
if (name.length()) { if (name.length()) {
if(plugin->save_preset(name)){ if (plugin->save_preset(name)) {
set_popdown_strings (preset_combo, plugin->get_presets()); update_presets();
preset_combo.set_active_text (name); preset_combo.set_active_text (name);
} }
} }
@ -460,5 +461,11 @@ PlugUIBase::focus_toggled (GdkEventButton* ev)
void void
PlugUIBase::update_presets () 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);
} }

View File

@ -109,7 +109,9 @@ class LV2Plugin : public ARDOUR::Plugin
XMLNode& get_state(); XMLNode& get_state();
int set_state(const XMLNode& node); 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; bool has_editor() const;
@ -129,6 +131,7 @@ class LV2Plugin : public ARDOUR::Plugin
float* _latency_control_port; float* _latency_control_port;
bool _was_activated; bool _was_activated;
vector<bool> _port_is_input; vector<bool> _port_is_input;
map<string,uint32_t> _port_indices;
typedef struct { const void* (*extension_data)(const char* uri); } LV2_DataAccess; typedef struct { const void* (*extension_data)(const char* uri); } LV2_DataAccess;
LV2_DataAccess _data_access_extension_data; LV2_DataAccess _data_access_extension_data;

View 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_input(uint32_t) const = 0;
virtual bool parameter_is_output(uint32_t) const = 0; virtual bool parameter_is_output(uint32_t) const = 0;
virtual bool save_preset(string name) = 0; virtual bool save_preset(string uri) = 0;
virtual bool load_preset (const string preset_label); virtual bool load_preset (const string uri);
virtual std::vector<std::string> get_presets();
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; virtual bool has_editor() const = 0;
@ -189,8 +199,8 @@ class Plugin : public PBD::StatefulDestructible, public Latent
ARDOUR::Session& _session; ARDOUR::Session& _session;
PluginInfoPtr _info; PluginInfoPtr _info;
uint32_t _cycles; uint32_t _cycles;
map<string,string> presets; map<string,PresetRecord> presets;
bool save_preset(string name, string domain /* vst, ladspa etc. */); bool save_preset(string uri, string domain /* vst, ladspa etc. */);
}; };
PluginPtr find_plugin(ARDOUR::Session&, string unique_id, ARDOUR::PluginType); PluginPtr find_plugin(ARDOUR::Session&, string unique_id, ARDOUR::PluginType);

View File

@ -806,10 +806,10 @@ AUPlugin::load_preset (const string preset_label)
return false; return false;
} }
vector<string> vector<Plugin::PresetRecord>
AUPlugin::get_presets () AUPlugin::get_presets ()
{ {
vector<string> presets; vector<PresetRecord> presets;
return presets; return presets;
} }

View 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); uint32_t latency_port = (latent ? slv2_plugin_get_latency_port_index(plugin) : 0);
for (uint32_t i = 0; i < num_ports; ++i) { 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)) { if (parameter_is_control(i)) {
SLV2Port port = slv2_plugin_get_port_by_index(plugin, i);
SLV2Value def; SLV2Value def;
slv2_port_get_range(plugin, port, &def, NULL, NULL); slv2_port_get_range(plugin, port, &def, NULL, NULL);
_defaults[i] = def ? slv2_value_as_float(def) : 0.0f; _defaults[i] = def ? slv2_value_as_float(def) : 0.0f;
@ -274,10 +276,50 @@ LV2Plugin::get_state()
return *root; 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 bool
LV2Plugin::save_preset (string name) LV2Plugin::save_preset (string name)
{ {
return Plugin::save_preset (name, "lv2"); return false;
} }
bool bool

View File

@ -26,6 +26,7 @@
#include <dirent.h> #include <dirent.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <cerrno> #include <cerrno>
#include <utility>
#include <lrdf.h> #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() Plugin::get_presets()
{ {
vector<string> labels; vector<PresetRecord> result;
uint32_t id; uint32_t id;
std::string unique (unique_id()); std::string unique (unique_id());
@ -83,7 +107,7 @@ Plugin::get_presets()
*/ */
if (!isdigit (unique[0])) { if (!isdigit (unique[0])) {
return labels; return result;
} }
id = atol (unique.c_str()); id = atol (unique.c_str());
@ -93,23 +117,21 @@ Plugin::get_presets()
if (set_uris) { if (set_uris) {
for (uint32_t i = 0; i < (uint32_t) set_uris->count; ++i) { for (uint32_t i = 0; i < (uint32_t) set_uris->count; ++i) {
if (char* label = lrdf_get_label(set_uris->items[i])) { if (char* label = lrdf_get_label(set_uris->items[i])) {
labels.push_back(label); PresetRecord rec(set_uris->items[i], label);
presets[label] = set_uris->items[i]; result.push_back(rec);
presets.insert(std::make_pair(set_uris->items[i], rec));
} }
} }
lrdf_free_uris(set_uris); lrdf_free_uris(set_uris);
} }
// GTK2FIX find an equivalent way to do this with a vector (needed by GUI apis) return result;
// labels.unique();
return labels;
} }
bool 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) { if (defs) {
for (uint32_t i = 0; i < (uint32_t) defs->count; ++i) { for (uint32_t i = 0; i < (uint32_t) defs->count; ++i) {
@ -126,7 +148,7 @@ Plugin::load_preset(const string preset_label)
} }
bool bool
Plugin::save_preset (string name, string domain) Plugin::save_preset (string uri, string domain)
{ {
lrdf_portvalue portvalues[parameter_count()]; lrdf_portvalue portvalues[parameter_count()];
lrdf_defaults defaults; 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)); 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); string path = string_compose("%1/.%2", envvar, domain);
if (g_mkdir_with_parents (path.c_str(), 0775)) { if (g_mkdir_with_parents (path.c_str(), 0775)) {