mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-23 18:21:04 +00:00
lv2: add support for saving presets
Plugns supporting the state interface can now save their presets under '.lv2'.
This commit is contained in:
parent
e9a2c4f1e1
commit
adf2092b3d
4 changed files with 112 additions and 8 deletions
|
@ -91,7 +91,9 @@ gst_lv2_filter_load_preset (GstPreset * preset, const gchar * name)
|
||||||
static gboolean
|
static gboolean
|
||||||
gst_lv2_filter_save_preset (GstPreset * preset, const gchar * name)
|
gst_lv2_filter_save_preset (GstPreset * preset, const gchar * name)
|
||||||
{
|
{
|
||||||
return FALSE;
|
GstLV2Filter *self = (GstLV2Filter *) preset;
|
||||||
|
|
||||||
|
return gst_lv2_save_preset (&self->lv2, (GstObject *) self, name);
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
|
@ -104,7 +106,9 @@ gst_lv2_filter_rename_preset (GstPreset * preset, const gchar * old_name,
|
||||||
static gboolean
|
static gboolean
|
||||||
gst_lv2_filter_delete_preset (GstPreset * preset, const gchar * name)
|
gst_lv2_filter_delete_preset (GstPreset * preset, const gchar * name)
|
||||||
{
|
{
|
||||||
return FALSE;
|
GstLV2Filter *self = (GstLV2Filter *) preset;
|
||||||
|
|
||||||
|
return gst_lv2_delete_preset (&self->lv2, (GstObject *) self, name);
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
|
|
|
@ -108,7 +108,9 @@ gst_lv2_source_load_preset (GstPreset * preset, const gchar * name)
|
||||||
static gboolean
|
static gboolean
|
||||||
gst_lv2_source_save_preset (GstPreset * preset, const gchar * name)
|
gst_lv2_source_save_preset (GstPreset * preset, const gchar * name)
|
||||||
{
|
{
|
||||||
return FALSE;
|
GstLV2Source *self = (GstLV2Source *) preset;
|
||||||
|
|
||||||
|
return gst_lv2_save_preset (&self->lv2, (GstObject *) self, name);
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
|
@ -121,7 +123,9 @@ gst_lv2_source_rename_preset (GstPreset * preset, const gchar * old_name,
|
||||||
static gboolean
|
static gboolean
|
||||||
gst_lv2_source_delete_preset (GstPreset * preset, const gchar * name)
|
gst_lv2_source_delete_preset (GstPreset * preset, const gchar * name)
|
||||||
{
|
{
|
||||||
return FALSE;
|
GstLV2Source *self = (GstLV2Source *) preset;
|
||||||
|
|
||||||
|
return gst_lv2_delete_preset (&self->lv2, (GstObject *) self, name);
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
|
|
|
@ -225,7 +225,6 @@ set_port_value (const char *port_symbol, void *data, const void *value,
|
||||||
g_object_set (obj, prop_name, fvalue, NULL);
|
g_object_set (obj, prop_name, fvalue, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
gboolean
|
gboolean
|
||||||
gst_lv2_load_preset (GstLV2 * lv2, GstObject * obj, const gchar * name)
|
gst_lv2_load_preset (GstLV2 * lv2, GstObject * obj, const gchar * name)
|
||||||
{
|
{
|
||||||
|
@ -242,26 +241,120 @@ gst_lv2_load_preset (GstLV2 * lv2, GstObject * obj, const gchar * name)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
static const void *
|
||||||
|
get_port_value (const char *port_symbol, void *data, uint32_t * size,
|
||||||
|
uint32_t * type)
|
||||||
|
{
|
||||||
|
gpointer *user_data = (gpointer *) data;
|
||||||
|
GstLV2Class *klass = user_data[0];
|
||||||
|
GstObject *obj = user_data[1];
|
||||||
|
gchar *prop_name = g_hash_table_lookup (klass->sym_to_name, port_symbol);
|
||||||
|
static gfloat fvalue;
|
||||||
|
|
||||||
|
if (!prop_name) {
|
||||||
|
GST_WARNING_OBJECT (obj, "Preset port '%s' is missing", port_symbol);
|
||||||
|
*size = *type = 0;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
*size = sizeof (float);
|
||||||
|
*type = forge.Float;
|
||||||
|
g_object_get (obj, prop_name, &fvalue, NULL);
|
||||||
|
/* FIXME: can we return &lv2->ports.{in,out}[x]; */
|
||||||
|
return &fvalue;
|
||||||
|
}
|
||||||
|
|
||||||
gboolean
|
gboolean
|
||||||
gst_lv2_save_preset (GstLV2 * lv2, GstObject * obj, const gchar * name)
|
gst_lv2_save_preset (GstLV2 * lv2, GstObject * obj, const gchar * name)
|
||||||
{
|
{
|
||||||
return FALSE;
|
gchar *filename, *basename, *bundle, *dir, *tmp_dir, *s;
|
||||||
|
gpointer user_data[] = { lv2->klass, obj };
|
||||||
|
GstElementFactory *factory;
|
||||||
|
LilvState *state;
|
||||||
|
LilvNode *bundle_dir;
|
||||||
|
LilvInstance *instance = lv2->instance;
|
||||||
|
gboolean res;
|
||||||
|
|
||||||
|
factory = gst_element_get_factory ((GstElement *) obj);
|
||||||
|
basename = g_strdup (gst_element_factory_get_metadata (factory,
|
||||||
|
GST_ELEMENT_METADATA_LONGNAME));
|
||||||
|
s = basename;
|
||||||
|
while ((s = strchr (s, ' '))) {
|
||||||
|
*s = '_';
|
||||||
|
}
|
||||||
|
|
||||||
|
filename = g_strjoin (NULL, name, ".ttl", NULL);
|
||||||
|
bundle = g_strjoin (NULL, basename, "_", name, ".preset.lv2", NULL);
|
||||||
|
/* dir needs to end on a dir separator for the lilv_new_file_uri() to work */
|
||||||
|
dir =
|
||||||
|
g_build_filename (g_get_home_dir (), ".lv2", bundle, G_DIR_SEPARATOR_S,
|
||||||
|
NULL);
|
||||||
|
tmp_dir = g_dir_make_tmp ("gstlv2-XXXXXX", NULL);
|
||||||
|
g_mkdir_with_parents (dir, 0750);
|
||||||
|
|
||||||
|
if (!instance) {
|
||||||
|
/* instance is NULL until we play!! */
|
||||||
|
instance = lilv_plugin_instantiate (lv2->klass->plugin, GST_AUDIO_DEF_RATE,
|
||||||
|
lv2_features);
|
||||||
|
}
|
||||||
|
|
||||||
|
state = lilv_state_new_from_instance (lv2->klass->plugin, instance, &lv2_map,
|
||||||
|
tmp_dir, dir, dir, dir, get_port_value, user_data,
|
||||||
|
LV2_STATE_IS_POD | LV2_STATE_IS_PORTABLE, NULL);
|
||||||
|
|
||||||
|
lilv_state_set_label (state, name);
|
||||||
|
|
||||||
|
res = lilv_state_save (world, &lv2_map, &lv2_unmap, state, /*uri */ NULL, dir,
|
||||||
|
filename) != 0;
|
||||||
|
|
||||||
|
/* reload bundle into the world */
|
||||||
|
bundle_dir = lilv_new_file_uri (world, NULL, dir);
|
||||||
|
lilv_world_unload_bundle (world, bundle_dir);
|
||||||
|
lilv_world_load_bundle (world, bundle_dir);
|
||||||
|
lilv_node_free (bundle_dir);
|
||||||
|
|
||||||
|
lilv_world_load_resource (world, lilv_state_get_uri (state));
|
||||||
|
g_hash_table_insert (lv2->presets, g_strdup (name),
|
||||||
|
lilv_node_duplicate (lilv_state_get_uri (state)));
|
||||||
|
|
||||||
|
lilv_state_free (state);
|
||||||
|
if (!lv2->instance) {
|
||||||
|
lilv_instance_free (instance);
|
||||||
|
}
|
||||||
|
|
||||||
|
g_free (tmp_dir);
|
||||||
|
g_free (dir);
|
||||||
|
g_free (bundle);
|
||||||
|
g_free (filename);
|
||||||
|
g_free (basename);
|
||||||
|
|
||||||
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
gboolean
|
gboolean
|
||||||
gst_lv2_rename_preset (GstLV2 * lv2, GstObject * obj,
|
gst_lv2_rename_preset (GstLV2 * lv2, GstObject * obj,
|
||||||
const gchar * old_name, const gchar * new_name)
|
const gchar * old_name, const gchar * new_name)
|
||||||
{
|
{
|
||||||
|
/* need to relabel the preset */
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
gboolean
|
gboolean
|
||||||
gst_lv2_delete_preset (GstLV2 * lv2, GstObject * obj, const gchar * name)
|
gst_lv2_delete_preset (GstLV2 * lv2, GstObject * obj, const gchar * name)
|
||||||
{
|
{
|
||||||
|
LilvNode *preset = g_hash_table_lookup (lv2->presets, name);
|
||||||
|
LilvState *state = lilv_state_new_from_world (world, &lv2_map, preset);
|
||||||
|
|
||||||
|
lilv_world_unload_resource (world, lilv_state_get_uri (state));
|
||||||
|
lilv_state_delete (world, state);
|
||||||
|
lilv_state_free (state);
|
||||||
|
|
||||||
|
g_hash_table_remove (lv2->presets, name);
|
||||||
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/* api helpers */
|
/* api helpers */
|
||||||
|
|
|
@ -106,6 +106,9 @@ void gst_lv2_host_init (void);
|
||||||
|
|
||||||
gchar **gst_lv2_get_preset_names (GstLV2 * lv2, GstObject * obj);
|
gchar **gst_lv2_get_preset_names (GstLV2 * lv2, GstObject * obj);
|
||||||
gboolean gst_lv2_load_preset (GstLV2 * lv2, GstObject * obj, const gchar * name);
|
gboolean gst_lv2_load_preset (GstLV2 * lv2, GstObject * obj, const gchar * name);
|
||||||
|
gboolean gst_lv2_save_preset (GstLV2 * lv2, GstObject * obj, const gchar * name);
|
||||||
|
gboolean gst_lv2_delete_preset (GstLV2 * lv2, GstObject * obj, const gchar * name);
|
||||||
|
|
||||||
|
|
||||||
void gst_lv2_init (GstLV2 * lv2, GstLV2Class * lv2_class);
|
void gst_lv2_init (GstLV2 * lv2, GstLV2Class * lv2_class);
|
||||||
void gst_lv2_finalize (GstLV2 * lv2);
|
void gst_lv2_finalize (GstLV2 * lv2);
|
||||||
|
|
Loading…
Reference in a new issue