13
0

Fix LV2 preset deletion and clash between plugins.

Before this, LV2 preset deletion in Ardour was doubly broken: the wrong file
was being removed, and removing the correct file would only result in a broken
preset.  This change uses a new version of Lilv which has a more sophisticated
mechanism for preset deletion.

Also, fix "clashing" presets saved with the same name for different plugins, by
prefixing the plugin name to the bundle (this is now a recommendation in the
LV2 preset specification).
This commit is contained in:
David Robillard 2015-03-07 14:54:03 -05:00
parent 0cb096a978
commit de078a04e2
3 changed files with 36 additions and 13 deletions

View File

@ -285,7 +285,7 @@ LV2PluginUI::lv2ui_instantiate(const std::string& title)
const LilvUI* ui = (const LilvUI*)_lv2->c_ui();
const LilvNode* bundle = lilv_ui_get_bundle_uri(ui);
const LilvNode* binary = lilv_ui_get_binary_uri(ui);
#ifdef HAVE_LILV_0_21_1
#ifdef HAVE_LILV_0_21_3
char* ui_bundle_path = lilv_file_uri_parse(lilv_node_as_uri(bundle), NULL);
char* ui_binary_path = lilv_file_uri_parse(lilv_node_as_uri(binary), NULL);
#else

View File

@ -1074,11 +1074,13 @@ ARDOUR::lv2plugin_get_port_value(const char* port_symbol,
std::string
LV2Plugin::do_save_preset(string name)
{
LilvNode* plug_name = lilv_plugin_get_name(_impl->plugin);
const string prefix = legalize_for_uri(lilv_node_as_string(plug_name));
const string base_name = legalize_for_uri(name);
const string file_name = base_name + ".ttl";
const string bundle = Glib::build_filename(
Glib::get_home_dir(),
Glib::build_filename(".lv2", base_name + ".lv2"));
Glib::build_filename(".lv2", prefix + "_" + base_name + ".lv2"));
LilvState* state = lilv_state_new_from_instance(
_impl->plugin,
@ -1110,7 +1112,7 @@ LV2Plugin::do_save_preset(string name)
std::string uri = Glib::filename_to_uri(Glib::build_filename(bundle, file_name));
LilvNode *node_bundle = lilv_new_uri(_world.world, Glib::filename_to_uri(Glib::build_filename(bundle, "/")).c_str());
LilvNode *node_preset = lilv_new_uri(_world.world, uri.c_str());
#ifdef HAVE_LILV_0_19_2
#ifdef HAVE_LILV_0_21_3
lilv_world_unload_resource(_world.world, node_preset);
lilv_world_unload_bundle(_world.world, node_bundle);
#endif
@ -1118,20 +1120,41 @@ LV2Plugin::do_save_preset(string name)
lilv_world_load_resource(_world.world, node_preset);
lilv_node_free(node_bundle);
lilv_node_free(node_preset);
lilv_node_free(plug_name);
return uri;
}
void
LV2Plugin::do_remove_preset(string name)
{
string preset_file = Glib::build_filename(
Glib::get_home_dir(),
Glib::build_filename(
Glib::build_filename(".lv2", "presets"),
name + ".ttl"
)
);
::g_unlink(preset_file.c_str());
#ifdef HAVE_LILV_0_21_3
/* Look up preset record by label (FIXME: ick, label as ID) */
const PresetRecord* r = preset_by_label(name);
if (!r) {
return;
}
/* Load a LilvState for the preset. */
LilvWorld* world = _world.world;
LilvNode* pset = lilv_new_uri(world, r->uri.c_str());
LilvState* state = lilv_state_new_from_world(world, _uri_map.urid_map(), pset);
if (!state) {
lilv_node_free(pset);
return;
}
/* Delete it from the file system. This will remove the preset file and the entry
from the manifest. If this results in an empty manifest (i.e. the
preset is the only thing in the bundle), then the bundle is removed. */
lilv_state_delete(world, state);
lilv_state_free(state);
lilv_node_free(pset);
#endif
/* Without lilv_state_delete(), we could delete the preset file, but this
would leave a broken bundle/manifest around, so the preset would still
be visible, but broken. Naively deleting a bundle is too dangerous, so
we simply do not support preset deletion with older Lilv */
}
bool

View File

@ -277,8 +277,8 @@ def configure(conf):
atleast_version='0.16.0', mandatory=False)
autowaf.check_pkg(conf, 'lilv-0', uselib_store='LILV_0_19_2',
atleast_version='0.19.2', mandatory=False)
autowaf.check_pkg(conf, 'lilv-0', uselib_store='LILV_0_21_1',
atleast_version='0.21.1', mandatory=False)
autowaf.check_pkg(conf, 'lilv-0', uselib_store='LILV_0_21_3',
atleast_version='0.21.3', mandatory=False)
autowaf.check_pkg(conf, 'suil-0', uselib_store='SUIL',
atleast_version='0.6.0', mandatory=False)
conf.define ('LV2_SUPPORT', 1)