diff options
Diffstat (limited to 'ext')
-rw-r--r-- | ext/lv2/README | 18 | ||||
-rw-r--r-- | ext/lv2/gstlv2.c | 175 | ||||
-rw-r--r-- | ext/lv2/gstlv2.h | 20 |
3 files changed, 119 insertions, 94 deletions
diff --git a/ext/lv2/README b/ext/lv2/README new file mode 100644 index 00000000..d1431b77 --- /dev/null +++ b/ext/lv2/README @@ -0,0 +1,18 @@ +Gst-LV2 Quickstart + +Dependencies: + +SLV2 0.6.* <http://drobilla.net/software/slv2> + +Which in turn depends on: + +librdf (redland) >= 1.0.6 <http://librdf.org> + + +Example Pipeline: + +Requires swh-lv2 <http://plugin.org.uk/releases/> + +gst-launch-0.10 -v filesrc location=/usr/share/sounds/login.wav ! wavparse ! audioconvert ! http---plugin-org-uk-swh-plugins-djFlanger ! audioconvert ! alsasink + +(A longer wav will be a better example) diff --git a/ext/lv2/gstlv2.c b/ext/lv2/gstlv2.c index 5d05f603..533d9d47 100644 --- a/ext/lv2/gstlv2.c +++ b/ext/lv2/gstlv2.c @@ -24,6 +24,7 @@ #endif #include <string.h> #include <math.h> +#include <glib.h> #include <gst/audio/audio.h> #include <gst/controller/gstcontroller.h> @@ -59,6 +60,13 @@ static GstPlugin *gst_lv2_plugin; GST_DEBUG_CATEGORY_STATIC (lv2_debug); #define GST_CAT_DEFAULT lv2_debug +static gint +gst_lv2_value_cmp (gconstpointer a, gconstpointer b) +{ + if (slv2_value_equals ((SLV2Value) a, (SLV2Value) b)) + return 0; + return 1; +} static void gst_lv2_base_init (gpointer g_class) @@ -68,7 +76,8 @@ gst_lv2_base_init (gpointer g_class) GstSignalProcessorClass *gsp_class = GST_SIGNAL_PROCESSOR_CLASS (g_class); GstElementDetails *details; SLV2Plugin lv2plugin; - SLV2Value val; + SLV2Value val, pred; + SLV2Values values; guint j, audio_in_count, audio_out_count, control_in_count, control_out_count; gchar *klass_tags; @@ -149,36 +158,64 @@ gst_lv2_base_init (gpointer g_class) g_free (details->author); g_free (details); - klass->audio_in_portnums = g_new0 (gint, gsp_class->num_audio_in); - klass->audio_out_portnums = g_new0 (gint, gsp_class->num_audio_out); - klass->control_in_portnums = g_new0 (gint, gsp_class->num_control_in); - klass->control_out_portnums = g_new0 (gint, gsp_class->num_control_out); + klass->groups = NULL; + + klass->audio_in_ports = g_new0 (struct _GstLV2Port, gsp_class->num_audio_in); + klass->audio_out_ports = + g_new0 (struct _GstLV2Port, gsp_class->num_audio_out); + klass->control_in_ports = + g_new0 (struct _GstLV2Port, gsp_class->num_control_in); + klass->control_out_ports = + g_new0 (struct _GstLV2Port, gsp_class->num_control_out); audio_in_count = audio_out_count = control_in_count = control_out_count = 0; + pred = slv2_value_new_uri (world, + "http://lv2plug.in/ns/dev/port-groups#inGroup"); + for (j = 0; j < slv2_plugin_get_num_ports (lv2plugin); j++) { SLV2Port port = slv2_plugin_get_port_by_index (lv2plugin, j); gboolean is_input = slv2_port_is_a (lv2plugin, port, input_class); + struct _GstLV2Port *desc = NULL; if (slv2_port_is_a (lv2plugin, port, audio_class)) { if (is_input) - klass->audio_in_portnums[audio_in_count++] = j; + desc = &klass->audio_in_ports[audio_in_count++]; else - klass->audio_out_portnums[audio_out_count++] = j; + desc = &klass->audio_out_ports[audio_out_count++]; } else if (slv2_port_is_a (lv2plugin, port, control_class)) { if (is_input) - klass->control_in_portnums[control_in_count++] = j; + desc = &klass->control_in_ports[control_in_count++]; else - klass->control_out_portnums[control_out_count++] = j; + desc = &klass->control_out_ports[control_out_count++]; + } else { + /* unknown port type */ + continue; + } + desc->index = j; + values = slv2_port_get_value (lv2plugin, port, pred); + if (slv2_values_size (values) > 0) { + SLV2Value v = slv2_values_get_at (values, 0); + desc->group = v; + if (!g_slist_find_custom (klass->groups, v, gst_lv2_value_cmp)) { + klass->groups = + g_slist_prepend (klass->groups, slv2_value_duplicate (v)); + } } + slv2_values_free (values); } + slv2_value_free (pred); + g_assert (audio_in_count == gsp_class->num_audio_in); g_assert (audio_out_count == gsp_class->num_audio_out); g_assert (control_in_count == gsp_class->num_control_in); g_assert (control_out_count == gsp_class->num_control_out); - /*if (!LV2_IS_INPLACE_BROKEN (desc->Properties)) - GST_SIGNAL_PROCESSOR_CLASS_SET_CAN_PROCESS_IN_PLACE (klass); */ + pred = slv2_value_new_uri (world, + "http://lv2plug.in/ns/lv2core#inPlaceBroken"); + if (!slv2_plugin_has_feature (lv2plugin, pred)) + GST_SIGNAL_PROCESSOR_CLASS_SET_CAN_PROCESS_IN_PLACE (klass); + slv2_value_free (pred); klass->plugin = lv2plugin; } @@ -274,7 +311,7 @@ gst_lv2_class_init (GstLV2Class * klass, SLV2Plugin lv2plugin) for (i = 0; i < gsp_class->num_control_in; i++) { GParamSpec *p; - p = gst_lv2_class_get_param_spec (klass, klass->control_in_portnums[i]); + p = gst_lv2_class_get_param_spec (klass, klass->control_in_ports[i].index); /* properties have an offset of 1 */ g_object_class_install_property (G_OBJECT_CLASS (klass), i + 1, p); @@ -283,7 +320,7 @@ gst_lv2_class_init (GstLV2Class * klass, SLV2Plugin lv2plugin) for (i = 0; i < gsp_class->num_control_out; i++) { GParamSpec *p; - p = gst_lv2_class_get_param_spec (klass, klass->control_out_portnums[i]); + p = gst_lv2_class_get_param_spec (klass, klass->control_out_ports[i].index); /* properties have an offset of 1, and we already added num_control_in */ g_object_class_install_property (G_OBJECT_CLASS (klass), @@ -294,19 +331,15 @@ gst_lv2_class_init (GstLV2Class * klass, SLV2Plugin lv2plugin) static void gst_lv2_init (GstLV2 * lv2, GstLV2Class * klass) { -#if 0 lv2->plugin = klass->plugin; lv2->instance = NULL; lv2->activated = FALSE; - lv2->inplace_broken = LV2_IS_INPLACE_BROKEN (lv2->descriptor->Properties); -#endif } static void gst_lv2_set_property (GObject * object, guint prop_id, const GValue * value, GParamSpec * pspec) { -#if 0 GstSignalProcessor *gsp; GstSignalProcessorClass *gsp_class; @@ -322,7 +355,7 @@ gst_lv2_set_property (GObject * object, guint prop_id, const GValue * value, /* now see what type it is */ switch (pspec->value_type) { case G_TYPE_BOOLEAN: - gsp->control_in[prop_id] = g_value_get_boolean (value) ? 1.f : 0.f; + gsp->control_in[prop_id] = g_value_get_boolean (value) ? 0.0f : 1.0f; break; case G_TYPE_INT: gsp->control_in[prop_id] = g_value_get_int (value); @@ -333,14 +366,12 @@ gst_lv2_set_property (GObject * object, guint prop_id, const GValue * value, default: g_assert_not_reached (); } -#endif } static void gst_lv2_get_property (GObject * object, guint prop_id, GValue * value, GParamSpec * pspec) { -#if 0 GstSignalProcessor *gsp; GstSignalProcessorClass *gsp_class; gfloat *controls; @@ -363,7 +394,7 @@ gst_lv2_get_property (GObject * object, guint prop_id, GValue * value, /* now see what type it is */ switch (pspec->value_type) { case G_TYPE_BOOLEAN: - g_value_set_boolean (value, controls[prop_id] > 0.5); + g_value_set_boolean (value, controls[prop_id] > 0.0f); break; case G_TYPE_INT: g_value_set_int (value, CLAMP (controls[prop_id], G_MININT, G_MAXINT)); @@ -374,64 +405,52 @@ gst_lv2_get_property (GObject * object, guint prop_id, GValue * value, default: g_return_if_reached (); } -#endif } static gboolean gst_lv2_setup (GstSignalProcessor * gsp, guint sample_rate) { -#if 0 - GstLV2 *ladspa; + GstLV2 *lv2; GstLV2Class *oclass; GstSignalProcessorClass *gsp_class; - LV2_Descriptor *desc; int i; gsp_class = GST_SIGNAL_PROCESSOR_GET_CLASS (gsp); - ladspa = (GstLV2 *) gsp; + lv2 = (GstLV2 *) gsp; oclass = (GstLV2Class *) gsp_class; - desc = ladspa->descriptor; - g_return_val_if_fail (ladspa->handle == NULL, FALSE); - g_return_val_if_fail (ladspa->activated == FALSE, FALSE); + g_return_val_if_fail (lv2->activated == FALSE, FALSE); - GST_DEBUG_OBJECT (ladspa, "instantiating the plugin at %d Hz", sample_rate); + GST_DEBUG_OBJECT (lv2, "instantiating the plugin at %d Hz", sample_rate); - ladspa->handle = desc->instantiate (desc, sample_rate); + lv2->instance = slv2_plugin_instantiate (oclass->plugin, sample_rate, NULL); - g_return_val_if_fail (ladspa->handle != NULL, FALSE); + g_return_val_if_fail (lv2->instance != NULL, FALSE); /* connect the control ports */ for (i = 0; i < gsp_class->num_control_in; i++) - desc->connect_port (ladspa->handle, - oclass->control_in_portnums[i], &(gsp->control_in[i])); + slv2_instance_connect_port (lv2->instance, + oclass->control_in_ports[i].index, &(gsp->control_in[i])); for (i = 0; i < gsp_class->num_control_out; i++) - desc->connect_port (ladspa->handle, - oclass->control_out_portnums[i], &(gsp->control_out[i])); -#endif + slv2_instance_connect_port (lv2->instance, + oclass->control_out_ports[i].index, &(gsp->control_out[i])); + return TRUE; } static gboolean gst_lv2_start (GstSignalProcessor * gsp) { -#if 0 - GstLV2 *ladspa; - LV2_Descriptor *desc; - - ladspa = (GstLV2 *) gsp; - desc = ladspa->descriptor; + GstLV2 *lv2 = (GstLV2 *) gsp; - g_return_val_if_fail (ladspa->activated == FALSE, FALSE); - g_return_val_if_fail (ladspa->handle != NULL, FALSE); + g_return_val_if_fail (lv2->activated == FALSE, FALSE); + g_return_val_if_fail (lv2->instance != NULL, FALSE); - GST_DEBUG_OBJECT (ladspa, "activating"); + GST_DEBUG_OBJECT (lv2, "activating"); - if (desc->activate) - desc->activate (ladspa->handle); + slv2_instance_activate (lv2->instance); - ladspa->activated = TRUE; -#endif + lv2->activated = TRUE; return TRUE; } @@ -439,71 +458,53 @@ gst_lv2_start (GstSignalProcessor * gsp) static void gst_lv2_stop (GstSignalProcessor * gsp) { -#if 0 - GstLV2 *ladspa; - LV2_Descriptor *desc; + GstLV2 *lv2 = (GstLV2 *) gsp; - ladspa = (GstLV2 *) gsp; - desc = ladspa->descriptor; + g_return_if_fail (lv2->activated == TRUE); + g_return_if_fail (lv2->instance != NULL); - g_return_if_fail (ladspa->activated == TRUE); - g_return_if_fail (ladspa->handle != NULL); + GST_DEBUG_OBJECT (lv2, "deactivating"); - GST_DEBUG_OBJECT (ladspa, "deactivating"); + slv2_instance_deactivate (lv2->instance); - if (desc->activate) - desc->activate (ladspa->handle); - - ladspa->activated = FALSE; -#endif + lv2->activated = FALSE; } static void gst_lv2_cleanup (GstSignalProcessor * gsp) { -#if 0 - GstLV2 *ladspa; - LV2_Descriptor *desc; - - ladspa = (GstLV2 *) gsp; - desc = ladspa->descriptor; + GstLV2 *lv2 = (GstLV2 *) gsp; - g_return_if_fail (ladspa->activated == FALSE); - g_return_if_fail (ladspa->handle != NULL); + g_return_if_fail (lv2->activated == FALSE); + g_return_if_fail (lv2->instance != NULL); - GST_DEBUG_OBJECT (ladspa, "cleaning up"); + GST_DEBUG_OBJECT (lv2, "cleaning up"); - if (desc->cleanup) - desc->cleanup (ladspa->handle); + slv2_instance_free (lv2->instance); - ladspa->handle = NULL; -#endif + lv2->instance = NULL; } static void gst_lv2_process (GstSignalProcessor * gsp, guint nframes) { -#if 0 GstSignalProcessorClass *gsp_class; - GstLV2 *ladspa; + GstLV2 *lv2; GstLV2Class *oclass; - LV2_Descriptor *desc; guint i; gsp_class = GST_SIGNAL_PROCESSOR_GET_CLASS (gsp); - ladspa = (GstLV2 *) gsp; + lv2 = (GstLV2 *) gsp; oclass = (GstLV2Class *) gsp_class; - desc = ladspa->descriptor; for (i = 0; i < gsp_class->num_audio_in; i++) - desc->connect_port (ladspa->handle, oclass->audio_in_portnums[i], - gsp->audio_in[i]); + slv2_instance_connect_port (lv2->instance, + oclass->audio_in_ports[i].index, gsp->audio_in[i]); for (i = 0; i < gsp_class->num_audio_out; i++) - desc->connect_port (ladspa->handle, oclass->audio_out_portnums[i], - gsp->audio_out[i]); + slv2_instance_connect_port (lv2->instance, + oclass->audio_out_ports[i].index, gsp->audio_out[i]); - desc->run (ladspa->handle, nframes); -#endif + slv2_instance_run (lv2->instance, nframes); } /* search the plugin path diff --git a/ext/lv2/gstlv2.h b/ext/lv2/gstlv2.h index 389c03d1..836f1a0b 100644 --- a/ext/lv2/gstlv2.h +++ b/ext/lv2/gstlv2.h @@ -51,11 +51,15 @@ typedef struct _GstLV2Class GstLV2Class; struct _GstLV2 { GstSignalProcessor parent; - SLV2Plugin *plugin; - SLV2Instance *instance; + SLV2Plugin plugin; + SLV2Instance instance; gboolean activated; - gboolean inplace_broken; +}; + +struct _GstLV2Port { + gint index; + SLV2Value group; }; struct _GstLV2Class { @@ -63,10 +67,12 @@ struct _GstLV2Class { SLV2Plugin plugin; - gint *audio_in_portnums; - gint *audio_out_portnums; - gint *control_in_portnums; - gint *control_out_portnums; + GSList *groups; + + struct _GstLV2Port *audio_in_ports; + struct _GstLV2Port *audio_out_ports; + struct _GstLV2Port *control_in_ports; + struct _GstLV2Port *control_out_ports; }; |