2 * Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
3 * <2001> Steve Baker <stevebaker_org@yahoo.co.uk>
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Library General Public
7 * License as published by the Free Software Foundation; either
8 * version 2 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Library General Public License for more details.
15 * You should have received a copy of the GNU Library General Public
16 * License along with this library; if not, write to the
17 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 * Boston, MA 02111-1307, USA.
23 #include <gst/control/control.h>
25 #include "gstladspa.h"
26 #include "ladspa.h" /* main ladspa sdk include file */
27 #include "utils.h" /* ladspa sdk utility functions */
30 GST_PAD_TEMPLATE_FACTORY (ladspa_sink_factory,
37 "rate", GST_PROPS_INT_RANGE (4000, 96000),
38 "format", GST_PROPS_STRING ("float"),
39 "layout", GST_PROPS_STRING ("gfloat"),
40 "intercept", GST_PROPS_FLOAT(0.0),
41 "slope", GST_PROPS_FLOAT(1.0),
42 "channels", GST_PROPS_INT (1)
46 GST_PAD_TEMPLATE_FACTORY (ladspa_src_factory,
53 "rate", GST_PROPS_INT_RANGE (4000, 96000),
54 "format", GST_PROPS_STRING ("float"),
55 "layout", GST_PROPS_STRING ("gfloat"),
56 "intercept", GST_PROPS_FLOAT (0.0),
57 "slope", GST_PROPS_FLOAT (1.0),
58 "channels", GST_PROPS_INT (1)
62 static GstPadTemplate *srctempl, *sinktempl;
71 static void gst_ladspa_class_init (GstLADSPAClass *klass);
72 static void gst_ladspa_init (GstLADSPA *ladspa);
74 static void gst_ladspa_update_int(const GValue *value, gpointer data);
75 static GstPadConnectReturn gst_ladspa_connect (GstPad *pad, GstCaps *caps);
76 static GstPadConnectReturn gst_ladspa_connect_get (GstPad *pad, GstCaps *caps);
77 static void gst_ladspa_force_src_caps (GstLADSPA *ladspa, GstPad *pad);
79 static void gst_ladspa_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec);
80 static void gst_ladspa_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec);
82 static gboolean gst_ladspa_instantiate (GstLADSPA *ladspa);
83 static void gst_ladspa_activate (GstLADSPA *ladspa);
84 static void gst_ladspa_deactivate (GstLADSPA *ladspa);
86 static GstElementStateReturn gst_ladspa_change_state (GstElement *element);
87 static void gst_ladspa_loop (GstElement *element);
88 static void gst_ladspa_chain (GstPad *pad,GstBuffer *buf);
89 static GstBuffer * gst_ladspa_get (GstPad *pad);
91 static GstElementClass *parent_class = NULL;
92 /* static guint gst_ladspa_signals[LAST_SIGNAL] = { 0 }; */
94 static GstPlugin *ladspa_plugin;
95 static GHashTable *ladspa_descriptors;
98 gst_ladspa_get_bufferpool (GstPad *pad)
102 GstLADSPA *ladspa = (GstLADSPA *) gst_pad_get_parent (pad);
103 GstLADSPAClass *oclass = (GstLADSPAClass *) (G_OBJECT_GET_CLASS (ladspa));
105 if (oclass->numsrcpads > 0)
106 for (i=0;i<oclass->numsrcpads;i++)
107 if ((bp = gst_pad_get_bufferpool(ladspa->srcpads[i])) != NULL)
114 gst_ladspa_class_init (GstLADSPAClass *klass)
116 GObjectClass *gobject_class;
117 GstElementClass *gstelement_class;
118 LADSPA_Descriptor *desc;
119 gint i,current_portnum,sinkcount,srccount,controlcount;
121 gint argtype,argperms;
122 GParamSpec *paramspec = NULL;
123 gchar *argname, *tempstr, *paren;
125 gobject_class = (GObjectClass*)klass;
126 gstelement_class = (GstElementClass*)klass;
128 gobject_class->set_property = gst_ladspa_set_property;
129 gobject_class->get_property = gst_ladspa_get_property;
131 gstelement_class->change_state = gst_ladspa_change_state;
133 /* look up and store the ladspa descriptor */
134 klass->descriptor = g_hash_table_lookup(ladspa_descriptors,GINT_TO_POINTER(G_TYPE_FROM_CLASS(klass)));
135 desc = klass->descriptor;
137 klass->numports = desc->PortCount;
139 klass->numsinkpads = 0;
140 klass->numsrcpads = 0;
141 klass->numcontrols = 0;
143 /* walk through the ports, count the input, output and control ports */
144 for (i=0;i<desc->PortCount;i++) {
145 if (LADSPA_IS_PORT_AUDIO(desc->PortDescriptors[i]) &&
146 LADSPA_IS_PORT_INPUT(desc->PortDescriptors[i])){
147 klass->numsinkpads++;
150 if (LADSPA_IS_PORT_AUDIO(desc->PortDescriptors[i]) &&
151 LADSPA_IS_PORT_OUTPUT(desc->PortDescriptors[i])){
155 if (LADSPA_IS_PORT_CONTROL(desc->PortDescriptors[i]) &&
156 LADSPA_IS_PORT_INPUT(desc->PortDescriptors[i])){
157 klass->numcontrols++;
161 klass->srcpad_portnums = g_new0(gint,klass->numsrcpads);
162 klass->sinkpad_portnums = g_new0(gint,klass->numsinkpads);
163 klass->control_portnums = g_new0(gint,klass->numcontrols);
168 /* walk through the ports, note the portnums for srcpads, sinkpads and control
170 for (i=0;i<desc->PortCount;i++) {
171 if (LADSPA_IS_PORT_AUDIO(desc->PortDescriptors[i]) &&
172 LADSPA_IS_PORT_INPUT(desc->PortDescriptors[i])){
173 GST_DEBUG (0, "input port %d", i);
174 klass->sinkpad_portnums[sinkcount++] = i;
177 if (LADSPA_IS_PORT_AUDIO(desc->PortDescriptors[i]) &&
178 LADSPA_IS_PORT_OUTPUT(desc->PortDescriptors[i])){
179 GST_DEBUG (0, "output port %d", i);
180 klass->srcpad_portnums[srccount++] = i;
183 if (LADSPA_IS_PORT_CONTROL(desc->PortDescriptors[i]) &&
184 LADSPA_IS_PORT_INPUT(desc->PortDescriptors[i])){
185 GST_DEBUG (0, "control port %d", i);
186 klass->control_portnums[controlcount++] = i;
190 /* no sink pads - we'll use get mode and add params for samplerate and
192 if (klass->numsinkpads == 0 && klass->numsrcpads > 0){
193 g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_SAMPLERATE,
194 g_param_spec_int("samplerate","samplerate","samplerate",
195 0,G_MAXINT,44100,G_PARAM_READWRITE));
196 g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_BUFFERSIZE,
197 g_param_spec_int("buffersize","buffersize","buffersize",
198 0,G_MAXINT,64,G_PARAM_READWRITE));
202 /* now build the contorl info from the control ports */
203 klass->control_info = g_new0(ladspa_control_info,klass->numcontrols);
205 for (i=0;i<klass->numcontrols;i++) {
206 current_portnum = klass->control_portnums[i];
208 /* short name for hint descriptor */
209 hintdesc = desc->PortRangeHints[current_portnum].HintDescriptor;
211 /* get the various bits */
212 if (LADSPA_IS_HINT_TOGGLED(hintdesc))
213 klass->control_info[i].toggled = TRUE;
214 if (LADSPA_IS_HINT_LOGARITHMIC(hintdesc))
215 klass->control_info[i].logarithmic = TRUE;
216 if (LADSPA_IS_HINT_INTEGER(hintdesc))
217 klass->control_info[i].integer = TRUE;
219 /* figure out the argument details */
220 if (klass->control_info[i].toggled) argtype = G_TYPE_BOOLEAN;
221 else if (klass->control_info[i].integer) argtype = G_TYPE_INT;
222 else argtype = G_TYPE_FLOAT;
224 /* grab the bounds */
225 if (LADSPA_IS_HINT_BOUNDED_BELOW(hintdesc)) {
226 klass->control_info[i].lower = TRUE;
227 klass->control_info[i].lowerbound =
228 desc->PortRangeHints[current_portnum].LowerBound;
230 if (argtype==G_TYPE_INT) klass->control_info[i].lowerbound = (gfloat)G_MININT;
231 if (argtype==G_TYPE_FLOAT) klass->control_info[i].lowerbound = -G_MAXFLOAT;
234 if (LADSPA_IS_HINT_BOUNDED_ABOVE(hintdesc)) {
235 klass->control_info[i].upper = TRUE;
236 klass->control_info[i].upperbound =
237 desc->PortRangeHints[current_portnum].UpperBound;
238 if (LADSPA_IS_HINT_SAMPLE_RATE(hintdesc))
239 klass->control_info[i].samplerate = TRUE;
241 if (argtype==G_TYPE_INT) klass->control_info[i].upperbound = (gfloat)G_MAXINT;
242 if (argtype==G_TYPE_FLOAT) klass->control_info[i].upperbound = G_MAXFLOAT;
245 if (LADSPA_IS_PORT_INPUT(desc->PortDescriptors[current_portnum])) {
246 argperms = G_PARAM_READWRITE;
247 klass->control_info[i].writable = TRUE;
249 argperms = G_PARAM_READABLE;
250 klass->control_info[i].writable = FALSE;
253 klass->control_info[i].name = g_strdup(desc->PortNames[current_portnum]);
254 argname = g_strdup(klass->control_info[i].name);
255 /* find out if there is a (unitname) at the end of the argname and get rid
257 paren = g_strrstr (argname, " (");
261 /* this is the same thing that param_spec_* will do */
262 g_strcanon (argname, G_CSET_A_2_Z G_CSET_a_2_z G_CSET_DIGITS "-", '-');
263 /* satisfy glib2 (argname[0] must be [A-Za-z]) */
264 if (!((argname[0] >= 'a' && argname[0] <= 'z') || (argname[0] >= 'A' && argname[0] <= 'Z'))) {
266 argname = g_strconcat("param-", argname, NULL);
270 /* check for duplicate property names */
271 if (g_object_class_find_property(G_OBJECT_CLASS(klass), argname) != NULL){
273 gchar *numargname = g_strdup_printf("%s_%d",argname,numarg++);
274 while (g_object_class_find_property(G_OBJECT_CLASS(klass), numargname) != NULL){
276 numargname = g_strdup_printf("%s_%d",argname,numarg++);
278 argname = numargname;
281 klass->control_info[i].param_name = argname;
283 GST_DEBUG (0, "adding arg %s from %s",argname, klass->control_info[i].name);
285 if (argtype==G_TYPE_BOOLEAN){
286 paramspec = g_param_spec_boolean(argname,argname,argname, FALSE, argperms);
287 } else if (argtype==G_TYPE_INT){
288 paramspec = g_param_spec_int(argname,argname,argname,
289 (gint)klass->control_info[i].lowerbound,
290 (gint)klass->control_info[i].upperbound,
291 (gint)klass->control_info[i].lowerbound, argperms);
292 } else if (klass->control_info[i].samplerate){
293 paramspec = g_param_spec_float(argname,argname,argname,
297 paramspec = g_param_spec_float(argname,argname,argname,
298 klass->control_info[i].lowerbound, klass->control_info[i].upperbound,
299 klass->control_info[i].lowerbound, argperms);
302 g_object_class_install_property(G_OBJECT_CLASS(klass), i+ARG_LAST, paramspec);
307 gst_ladspa_init (GstLADSPA *ladspa)
309 GstLADSPAClass *oclass = (GstLADSPAClass*)(G_OBJECT_GET_CLASS(ladspa));
310 ladspa_control_info cinfo;
312 LADSPA_Descriptor *desc;
313 gint i,sinkcount,srccount,controlcount;
315 desc = oclass->descriptor;
316 ladspa->descriptor = oclass->descriptor;
318 /* allocate the various arrays */
319 ladspa->srcpads = g_new0(GstPad*,oclass->numsrcpads);
320 ladspa->sinkpads = g_new0(GstPad*,oclass->numsinkpads);
321 ladspa->controls = g_new(gfloat,oclass->numcontrols);
322 ladspa->dpman = gst_dpman_new ("ladspa_dpman", GST_ELEMENT(ladspa));
324 /* walk through the ports and add all the pads */
328 for (i=0;i<desc->PortCount;i++) {
330 if (LADSPA_IS_PORT_AUDIO(desc->PortDescriptors[i])){
331 gchar *canon_port_name = g_strdup((gchar *)desc->PortNames[i]);
332 g_strcanon (canon_port_name, G_CSET_A_2_Z G_CSET_a_2_z G_CSET_DIGITS "-", '-');
333 if (LADSPA_IS_PORT_INPUT(desc->PortDescriptors[i])) {
334 ladspa->sinkpads[sinkcount] = gst_pad_new_from_template (sinktempl, canon_port_name);
335 gst_element_add_pad(GST_ELEMENT(ladspa),ladspa->sinkpads[sinkcount]);
338 if (LADSPA_IS_PORT_OUTPUT(desc->PortDescriptors[i])) {
339 ladspa->srcpads[srccount] = gst_pad_new_from_template (srctempl, canon_port_name);
340 gst_element_add_pad(GST_ELEMENT(ladspa),ladspa->srcpads[srccount]);
344 if (LADSPA_IS_PORT_CONTROL(desc->PortDescriptors[i]) &&
345 LADSPA_IS_PORT_INPUT(desc->PortDescriptors[i])) {
346 cinfo = oclass->control_info[controlcount];
347 /* use the lowerbound as the default value if it exists */
349 ladspa->controls[controlcount]=cinfo.lowerbound;
351 ladspa->controls[controlcount] = 0.0;
354 /* set up dparams for this instance */
356 gst_dpman_add_required_dparam_callback (
358 g_param_spec_int(cinfo.param_name, cinfo.name, cinfo.name,
359 0, 1, (gint)(ladspa->controls[controlcount]), G_PARAM_READWRITE),
360 "int", gst_ladspa_update_int, &(ladspa->controls[controlcount])
363 else if (cinfo.integer){
364 gst_dpman_add_required_dparam_callback (
366 g_param_spec_int(cinfo.param_name, cinfo.name, cinfo.name,
367 (gint)cinfo.lowerbound, (gint)cinfo.upperbound,
368 (gint)ladspa->controls[controlcount], G_PARAM_READWRITE),
369 "int", gst_ladspa_update_int, &(ladspa->controls[controlcount])
372 else if (cinfo.samplerate){
373 gst_dpman_add_required_dparam_direct (
375 g_param_spec_float(cinfo.param_name, cinfo.name, cinfo.name,
376 cinfo.lowerbound, cinfo.upperbound,
377 ladspa->controls[controlcount], G_PARAM_READWRITE),
378 "hertz-rate-bound", &(ladspa->controls[controlcount])
382 gst_dpman_add_required_dparam_direct (
384 g_param_spec_float(cinfo.param_name, cinfo.name, cinfo.name,
385 cinfo.lowerbound, cinfo.upperbound,
386 ladspa->controls[controlcount], G_PARAM_READWRITE),
387 "float", &(ladspa->controls[controlcount])
395 ladspa->samplerate = 0;
396 ladspa->buffersize = 64;
397 ladspa->numbuffers = 16;
398 ladspa->newcaps = FALSE;
399 ladspa->activated = FALSE;
400 ladspa->bufpool = NULL;
402 if (sinkcount==0 && srccount == 1) {
403 /* get mode (no sink pads) */
404 GST_DEBUG (0, "mono get mode with 1 src pad");
406 ladspa->newcaps = TRUE;
407 ladspa->samplerate = 44100;
408 ladspa->buffersize = 64;
410 gst_pad_set_connect_function (ladspa->srcpads[0], gst_ladspa_connect_get);
411 gst_pad_set_get_function (ladspa->srcpads[0], gst_ladspa_get);
413 } else if (sinkcount==1){
414 /* with one sink we can use the chain function */
415 GST_DEBUG (0, "chain mode");
417 gst_pad_set_connect_function (ladspa->sinkpads[0], gst_ladspa_connect);
418 gst_pad_set_chain_function (ladspa->sinkpads[0], gst_ladspa_chain);
419 gst_pad_set_bufferpool_function (ladspa->sinkpads[0], gst_ladspa_get_bufferpool);
420 } else if (sinkcount > 1){
421 /* more than one sink pad needs loop mode */
422 GST_DEBUG (0, "loop mode with %d sink pads and %d src pads", sinkcount, srccount);
424 for (i=0;i<sinkcount;i++) {
425 gst_pad_set_connect_function (ladspa->sinkpads[i], gst_ladspa_connect);
426 gst_pad_set_bufferpool_function (ladspa->sinkpads[i], gst_ladspa_get_bufferpool);
428 gst_element_set_loop_function (GST_ELEMENT (ladspa), gst_ladspa_loop);
430 else if (sinkcount==0 && srccount == 0){
431 /* for some reason these plugins exist - we'll just ignore them */
433 g_warning("%d sink pads, %d src pads not yet supported", sinkcount, srccount);
436 gst_ladspa_instantiate(ladspa);
440 gst_ladspa_update_int(const GValue *value, gpointer data)
442 gfloat *target = (gfloat*) data;
443 *target = (gfloat)g_value_get_int(value);
446 static GstPadConnectReturn
447 gst_ladspa_connect (GstPad *pad, GstCaps *caps)
449 GstLADSPA *ladspa = (GstLADSPA *) GST_PAD_PARENT (pad);
450 GstLADSPAClass *oclass = (GstLADSPAClass *) (G_OBJECT_GET_CLASS (ladspa));
454 g_return_val_if_fail (caps != NULL, GST_PAD_CONNECT_DELAYED);
455 g_return_val_if_fail (pad != NULL, GST_PAD_CONNECT_DELAYED);
457 if (gst_caps_get_int (caps, "rate", &rate)){
458 /* have to instantiate ladspa plugin when samplerate changes (groan) */
459 if (ladspa->samplerate != rate){
460 ladspa->samplerate = rate;
462 if (! gst_ladspa_instantiate(ladspa))
463 return GST_PAD_CONNECT_REFUSED;
467 /* if the caps are fixed, we are going to try to set all srcpads using this
468 one caps object. if any of the pads barfs, we'll refuse the connection. i'm
469 not sure if this is correct. */
470 if (GST_CAPS_IS_FIXED (caps)) {
471 for (i=0;i<oclass->numsrcpads;i++) {
472 if (! gst_pad_try_set_caps (ladspa->srcpads[i], caps))
473 return GST_PAD_CONNECT_REFUSED;
477 return GST_PAD_CONNECT_OK;
480 static GstPadConnectReturn
481 gst_ladspa_connect_get (GstPad *pad, GstCaps *caps)
483 GstLADSPA *ladspa = (GstLADSPA*)GST_OBJECT_PARENT (pad);
486 g_return_val_if_fail (caps != NULL, GST_PAD_CONNECT_DELAYED);
487 g_return_val_if_fail (pad != NULL, GST_PAD_CONNECT_DELAYED);
489 if (gst_caps_get_int (caps, "rate", &rate)){
490 if (ladspa->samplerate != rate) {
491 ladspa->samplerate = rate;
492 if (! gst_ladspa_instantiate(ladspa))
493 return GST_PAD_CONNECT_REFUSED;
497 return GST_PAD_CONNECT_OK;
501 gst_ladspa_force_src_caps(GstLADSPA *ladspa, GstPad *pad)
503 GST_DEBUG (0, "forcing caps with rate %d", ladspa->samplerate);
504 gst_pad_try_set_caps (pad, gst_caps_new (
508 "format", GST_PROPS_STRING ("float"),
509 "layout", GST_PROPS_STRING ("gfloat"),
510 "intercept", GST_PROPS_FLOAT(0.0),
511 "slope", GST_PROPS_FLOAT(1.0),
512 "rate", GST_PROPS_INT (ladspa->samplerate),
513 "channels", GST_PROPS_INT (1),
517 ladspa->newcaps=FALSE;
521 gst_ladspa_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec)
523 GstLADSPA *ladspa = (GstLADSPA*)object;
524 gint cid = prop_id - ARG_LAST;
525 GstLADSPAClass *oclass;
526 ladspa_control_info *control_info;
529 /* these are only registered in get mode */
532 ladspa->samplerate = g_value_get_int (value);
533 ladspa->newcaps=TRUE;
536 ladspa->buffersize = g_value_get_int (value);
540 /* is it a ladspa plugin arg? */
543 oclass = (GstLADSPAClass*)(G_OBJECT_GET_CLASS (object));
545 /* verify it exists and is a control (not a port) */
546 g_return_if_fail(cid < oclass->numcontrols);
548 control_info = &(oclass->control_info[cid]);
549 g_return_if_fail (control_info->name != NULL);
551 /* check to see if it's writable */
552 g_return_if_fail (control_info->writable);
554 /* now see what type it is */
555 if (control_info->toggled) {
556 if (g_value_get_boolean (value))
557 ladspa->controls[cid] = 1.0;
559 ladspa->controls[cid] = 0.0;
560 } else if (control_info->integer) {
561 val = (gfloat)g_value_get_int (value);
562 ladspa->controls[cid] = val;
564 val = g_value_get_float (value);
565 ladspa->controls[cid] = val;
568 GST_DEBUG (0, "set arg %s to %f", control_info->name, ladspa->controls[cid]);
572 gst_ladspa_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec)
574 GstLADSPA *ladspa = (GstLADSPA*)object;
575 gint cid = prop_id - ARG_LAST;
576 GstLADSPAClass *oclass = (GstLADSPAClass*)(G_OBJECT_GET_CLASS (object));
577 ladspa_control_info *control_info;
579 /* these are only registered in get mode */
582 g_value_set_int (value, ladspa->samplerate);
585 g_value_set_int (value, ladspa->buffersize);
591 /* verify it exists and is a control (not a port) */
592 if (cid >= oclass->numcontrols) return;
593 control_info = &(oclass->control_info[cid]);
594 if (control_info->name == NULL) return;
596 GST_DEBUG (0, "got arg %s as %f", control_info->name, ladspa->controls[cid]);
598 /* now see what type it is */
599 if (control_info->toggled) {
600 if (ladspa->controls[cid] == 1.0)
601 g_value_set_boolean (value, TRUE);
603 g_value_set_boolean (value, FALSE);
604 } else if (control_info->integer) {
605 g_value_set_int (value, (gint)ladspa->controls[cid]);
607 g_value_set_float (value, ladspa->controls[cid]);
612 gst_ladspa_instantiate (GstLADSPA *ladspa)
614 LADSPA_Descriptor *desc;
616 GstLADSPAClass *oclass = (GstLADSPAClass*)(G_OBJECT_GET_CLASS (ladspa));
617 gboolean was_activated;
619 desc = ladspa->descriptor;
621 /* check for old handle */
622 was_activated = ladspa->activated;
623 if (ladspa->handle != NULL){
624 gst_ladspa_deactivate(ladspa);
625 desc->cleanup(ladspa->handle);
628 /* instantiate the plugin */
629 GST_DEBUG (0, "instantiating the plugin");
631 ladspa->handle = desc->instantiate(desc,ladspa->samplerate);
632 g_return_val_if_fail (ladspa->handle != NULL, FALSE);
634 /* walk through the ports and add all the arguments */
635 for (i=0;i<oclass->numcontrols;i++) {
636 /* connect the argument to the plugin */
637 GST_DEBUG (0, "added control port %d", oclass->control_portnums[i]);
638 desc->connect_port(ladspa->handle,
639 oclass->control_portnums[i],
640 &(ladspa->controls[i]));
643 /* reactivate if it was activated before the reinstantiation */
645 gst_ladspa_activate(ladspa);
650 static GstElementStateReturn
651 gst_ladspa_change_state (GstElement *element)
653 LADSPA_Descriptor *desc;
654 GstLADSPA *ladspa = (GstLADSPA*)element;
655 desc = ladspa->descriptor;
657 GST_DEBUG (0, "changing state");
658 switch (GST_STATE_TRANSITION (element)) {
659 case GST_STATE_NULL_TO_READY:
660 gst_ladspa_activate(ladspa);
662 case GST_STATE_READY_TO_NULL:
663 gst_ladspa_deactivate(ladspa);
669 if (GST_ELEMENT_CLASS (parent_class)->change_state)
670 return GST_ELEMENT_CLASS (parent_class)->change_state (element);
672 return GST_STATE_SUCCESS;
676 gst_ladspa_activate(GstLADSPA *ladspa)
678 LADSPA_Descriptor *desc;
679 desc = ladspa->descriptor;
681 if (ladspa->activated){
682 gst_ladspa_deactivate(ladspa);
685 GST_DEBUG (0, "activating");
687 /* activate the plugin (function might be null) */
688 if (desc->activate != NULL) {
689 desc->activate(ladspa->handle);
692 ladspa->activated = TRUE;
696 gst_ladspa_deactivate(GstLADSPA *ladspa)
698 LADSPA_Descriptor *desc;
699 desc = ladspa->descriptor;
701 GST_DEBUG (0, "deactivating");
703 /* deactivate the plugin (function might be null) */
704 if (ladspa->activated && (desc->deactivate != NULL)) {
705 desc->deactivate(ladspa->handle);
708 ladspa->activated = FALSE;
712 gst_ladspa_loop(GstElement *element)
714 guint bufferbytesize, i, numsrcpads, numsinkpads, num_empty_pads;
715 guint num_processed, num_to_process;
716 GstEvent *event = NULL;
718 LADSPA_Data **data_in, **data_out;
719 GstBuffer **buffers_in, **buffers_out;
720 GstBufferPool *bufpool;
721 GstByteStream **bytestreams;
722 gboolean inplace_broken;
724 GstLADSPA *ladspa = (GstLADSPA *)element;
725 GstLADSPAClass *oclass = (GstLADSPAClass*)(G_OBJECT_GET_CLASS (ladspa));
726 LADSPA_Descriptor *desc = ladspa->descriptor;
728 numsinkpads = oclass->numsinkpads;
729 numsrcpads = oclass->numsrcpads;
731 data_in = g_new0(LADSPA_Data*, numsinkpads);
732 data_out = g_new0(LADSPA_Data*, numsrcpads);
733 buffers_in = g_new0(GstBuffer*, numsinkpads);
734 buffers_out = g_new0(GstBuffer*, numsrcpads);
735 bytestreams = g_new0(GstByteStream*, numsinkpads);
737 bufferbytesize = sizeof (LADSPA_Data) * ladspa->buffersize;
739 /* find a bufferpool */
740 bufpool = gst_buffer_pool_get_default (bufferbytesize, ladspa->numbuffers);
742 /* get the bytestreams for each pad */
743 for (i=0 ; i<numsinkpads ; i++){
744 bytestreams[i] = gst_bytestream_new (ladspa->sinkpads[i]);
747 /* since this is a loop element, we just loop here til things fall apart. */
750 /* first get all the necessary data from the input ports */
751 for (i=0 ; i<numsinkpads ; i++){
752 GST_DEBUG (0, "pulling %u bytes through channel %d'sbytestream", bufferbytesize, i);
753 buffers_in[i] = gst_bytestream_read (bytestreams[i], bufferbytesize);
755 if (buffers_in[i] == NULL) {
756 /* we need to check for an event. */
757 gst_bytestream_get_status (bytestreams[i], &waiting, &event);
759 if (event && GST_EVENT_TYPE(event) == GST_EVENT_EOS) {
760 /* if we get an EOS event from one of our sink pads, we assume that
761 pad's finished handling data. delete the bytestream, free up the
762 pad, and free up the memory associated with the input channel. */
763 GST_DEBUG (0, "got an EOS event on sinkpad %d", i);
765 /* CHECKME should maybe check for other events and try to pull more data here */
768 data_in[i] = (LADSPA_Data *) GST_BUFFER_DATA(buffers_in[i]);
769 GST_BUFFER_TIMESTAMP(buffers_in[i]) = ladspa->timestamp;
773 if (num_empty_pads > 0){
774 if (num_empty_pads < numsinkpads){
775 /* only some pads have EOS, need to create some empty buffers */
776 for (i=0 ; i<numsinkpads ; i++){
777 if (buffers_in[i] == NULL){
780 buffers_in[i] = gst_buffer_new_from_pool (ladspa->bufpool, 0, 0);
781 GST_BUFFER_TIMESTAMP(buffers_in[i]) = ladspa->timestamp;
782 data_in[i] = data = (LADSPA_Data *) GST_BUFFER_DATA(buffers_in[i]);
783 for (x=0 ; x < ladspa->buffersize ; x++)
786 data_in[i] = (LADSPA_Data *) GST_BUFFER_DATA(buffers_in[i]);
787 GST_BUFFER_TIMESTAMP(buffers_in[i]) = ladspa->timestamp;
792 /* all pads have EOS, time to quit */
793 /* CHECKME do I have to push EOS events here? */
794 GST_DEBUG (0, "All sink pads have EOS, finishing.");
799 /* we now have a full set of buffers_in.
800 * now share or create the buffers_out */
801 for (i=0 ; i<numsrcpads ; i++){
802 if (i <= numsinkpads && !inplace_broken){
803 /* we can share buffers */
804 buffers_out[i] = buffers_in[i];
805 data_out[i] = data_in[i];
807 buffers_out[i] = gst_buffer_new_from_pool (bufpool, 0, 0);
808 GST_BUFFER_TIMESTAMP(buffers_out[i]) = ladspa->timestamp;
809 data_out[i] = (LADSPA_Data *) GST_BUFFER_DATA(buffers_out[i]);
813 num_to_process = GST_DPMAN_PREPROCESS(ladspa->dpman, ladspa->buffersize, ladspa->timestamp);
816 /* split up processing of the buffer into chunks so that dparams can
817 * be updated when required.
818 * In many cases the buffer will be processed in one chunk anyway.
820 while(GST_DPMAN_PROCESS_CHUNK(ladspa->dpman, num_to_process, num_processed)) {
822 for (i=0 ; i<numsinkpads ; i++){
823 desc->connect_port (ladspa->handle, oclass->sinkpad_portnums[i], data_in[i]);
825 for (i=0 ; i<numsrcpads ; i++){
826 desc->connect_port (ladspa->handle, oclass->srcpad_portnums[i], data_out[i]);
828 desc->run(ladspa->handle, num_to_process);
829 for (i=0 ; i<numsinkpads ; i++){
830 data_in[i] += num_to_process;
832 for (i=0 ; i<numsrcpads ; i++){
833 data_out[i] += num_to_process;
836 num_processed = num_to_process;
840 for (i=0 ; i<numsrcpads ; i++) {
841 GST_DEBUG (0, "pushing buffer (%p) on src pad %d", buffers_out[i], i);
842 gst_pad_push (ladspa->srcpads[i], buffers_out[i]);
845 buffers_out[i] = NULL;
847 for (i=0 ; i<numsinkpads ; i++) {
848 if (i > numsrcpads || inplace_broken){
849 /* we have some buffers to unref */
850 gst_buffer_unref(buffers_in[i]);
853 buffers_in[i] = NULL;
856 ladspa->timestamp += ladspa->buffersize * 10^9 / ladspa->samplerate;
859 gst_buffer_pool_unref(bufpool);
861 for (i=0 ; i<numsinkpads ; i++){
862 gst_bytestream_destroy (bytestreams[i]);
865 g_free (buffers_out);
869 g_free (bytestreams);
873 gst_ladspa_chain (GstPad *pad, GstBuffer *buf)
875 LADSPA_Descriptor *desc;
876 LADSPA_Data *data_in, **data_out;
877 GstBuffer **buffers_out;
879 unsigned long num_samples;
880 gboolean inplace_broken;
881 guint num_to_process, num_processed, i, numsrcpads;
884 GstLADSPAClass *oclass;
886 g_return_if_fail(pad != NULL);
887 g_return_if_fail(GST_IS_PAD(pad));
888 g_return_if_fail(buf != NULL);
890 ladspa = (GstLADSPA *)gst_pad_get_parent (pad);
891 g_return_if_fail(ladspa != NULL);
893 /* this might happen if caps nego hasn't happened */
894 g_return_if_fail(ladspa->handle != NULL);
896 oclass = (GstLADSPAClass *) (G_OBJECT_GET_CLASS (ladspa));
898 if (GST_IS_EVENT (buf)) {
899 /* push the event out all the src pads */
900 for (i=0 ; i<oclass->numsrcpads ; i++){
901 gst_pad_push (ladspa->srcpads[0], buf);
906 data_in = (LADSPA_Data *) GST_BUFFER_DATA(buf);
907 num_samples = GST_BUFFER_SIZE(buf) / sizeof(gfloat);
908 numsrcpads = oclass->numsrcpads;
910 desc = ladspa->descriptor;
912 inplace_broken = LADSPA_IS_INPLACE_BROKEN(desc->Properties);
914 guint num_created_buffers = 0;
915 buffers_out = g_new(GstBuffer*, numsrcpads);
916 data_out = g_new(LADSPA_Data*, numsrcpads);
919 num_created_buffers = numsrcpads;
922 /* we can share the buffer for input and output */
923 buffers_out[0] = buf;
924 data_out[0] = (LADSPA_Data *)GST_BUFFER_DATA(buf);
925 num_created_buffers = numsrcpads - 1;
928 if (num_created_buffers > 0){
929 GstBufferPool *bufpool;
930 bufpool = gst_buffer_pool_get_default (sizeof (LADSPA_Data) * GST_BUFFER_SIZE(buf), ladspa->numbuffers);
932 for (i = numsrcpads - num_created_buffers ; i<numsrcpads ; i++){
933 buffers_out[i] = gst_buffer_new_from_pool (ladspa->bufpool, 0, 0);
934 GST_BUFFER_TIMESTAMP(buffers_out[i]) = GST_BUFFER_TIMESTAMP(buf);
935 data_out[i] = (LADSPA_Data *) GST_BUFFER_DATA(buffers_out[i]);
940 num_to_process = GST_DPMAN_PREPROCESS(ladspa->dpman, num_samples, GST_BUFFER_TIMESTAMP(buf));
943 /* split up processing of the buffer into chunks so that dparams can
944 * be updated when required.
945 * In many cases the buffer will be processed in one chunk anyway.
947 while(GST_DPMAN_PROCESS_CHUNK(ladspa->dpman, num_to_process, num_processed)) {
948 desc->connect_port(ladspa->handle,oclass->sinkpad_portnums[0],data_in);
949 for (i=0 ; i<numsrcpads ; i++){
950 desc->connect_port(ladspa->handle,oclass->srcpad_portnums[i],data_out[i]);
952 desc->run(ladspa->handle, num_to_process);
954 data_in += num_to_process;
955 for (i=0 ; i<numsrcpads ; i++){
956 data_out[i] += num_to_process;
958 num_processed += num_to_process;
963 for (i=0 ; i<numsrcpads ; i++){
964 gst_pad_push (ladspa->srcpads[i], buffers_out[i]);
971 /* if we have reached here, there are no src pads */
972 gst_buffer_unref(buf);
976 gst_ladspa_get(GstPad *pad)
979 GstLADSPAClass *oclass;
983 LADSPA_Descriptor *desc;
985 guint num_to_process, num_processed;
987 g_return_val_if_fail(pad != NULL, NULL);
988 g_return_val_if_fail(GST_IS_PAD(pad), NULL);
990 ladspa = (GstLADSPA *)gst_pad_get_parent (pad);
991 g_return_val_if_fail(ladspa != NULL, NULL);
993 /* this might happen if caps nego hasn't happened */
994 g_return_val_if_fail(ladspa->handle != NULL, NULL);
996 oclass = (GstLADSPAClass*)(G_OBJECT_GET_CLASS(ladspa));
998 /* force src pad to set caps */
999 if (ladspa->newcaps) {
1000 gst_ladspa_force_src_caps(ladspa, ladspa->srcpads[0]);
1003 /* get a bufferpool */
1004 if (ladspa->bufpool == NULL) {
1005 ladspa->bufpool = gst_pad_get_bufferpool (ladspa->srcpads[0]);
1006 if (ladspa->bufpool == NULL) {
1007 ladspa->bufpool = gst_buffer_pool_get_default (sizeof (LADSPA_Data) * ladspa->buffersize, ladspa->numbuffers);
1011 buf = gst_buffer_new_from_pool (ladspa->bufpool, 0, 0);
1012 GST_BUFFER_TIMESTAMP(buf) = ladspa->timestamp;
1013 data = (LADSPA_Data *) GST_BUFFER_DATA(buf);
1015 desc = ladspa->descriptor;
1016 num_to_process = GST_DPMAN_PREPROCESS(ladspa->dpman, ladspa->buffersize, ladspa->timestamp);
1019 /* update timestamp */
1020 ladspa->timestamp += num_to_process * 10^9 / ladspa->samplerate;
1022 /* split up processing of the buffer into chunks so that dparams can
1023 * be updated when required.
1024 * In many cases the buffer will be processed in one chunk anyway.
1026 while(GST_DPMAN_PROCESS_CHUNK(ladspa->dpman, num_to_process, num_processed)) {
1027 desc->connect_port(ladspa->handle,oclass->srcpad_portnums[0],data);
1028 desc->run(ladspa->handle, num_to_process);
1030 data += num_to_process;
1031 num_processed = num_to_process;
1039 ladspa_describe_plugin(const char *pcFullFilename,
1040 void *pvPluginHandle,
1041 LADSPA_Descriptor_Function pfDescriptorFunction)
1043 const LADSPA_Descriptor *desc;
1046 GstElementDetails *details;
1047 GTypeInfo typeinfo = {
1048 sizeof(GstLADSPAClass),
1051 (GClassInitFunc)gst_ladspa_class_init,
1056 (GInstanceInitFunc)gst_ladspa_init,
1059 GstElementFactory *factory;
1061 /* walk through all the plugins in this pluginlibrary */
1063 while ((desc = pfDescriptorFunction(i++))) {
1066 /* construct the type */
1067 type_name = g_strdup_printf("ladspa_%s",desc->Label);
1068 g_strcanon (type_name, G_CSET_A_2_Z G_CSET_a_2_z G_CSET_DIGITS "-_+", '-');
1069 /* if it's already registered, drop it */
1070 if (g_type_from_name(type_name)) {
1074 /* create the type now */
1075 type = g_type_register_static(GST_TYPE_ELEMENT, type_name, &typeinfo, 0);
1077 /* construct the element details struct */
1078 details = g_new0(GstElementDetails,1);
1079 details->longname = g_strdup(desc->Name);
1080 details->klass = "Filter/LADSPA";
1081 details->description = details->longname;
1082 details->version = g_strdup_printf("%ld",desc->UniqueID);
1083 details->author = g_strdup(desc->Maker);
1084 details->copyright = g_strdup(desc->Copyright);
1086 /* register the plugin with gstreamer */
1087 factory = gst_element_factory_new(type_name,type,details);
1088 g_return_if_fail(factory != NULL);
1089 gst_plugin_add_feature (ladspa_plugin, GST_PLUGIN_FEATURE (factory));
1091 /* add this plugin to the hash */
1092 g_hash_table_insert(ladspa_descriptors,
1093 GINT_TO_POINTER(type),
1097 /* only add sink padtemplate if there are sinkpads */
1098 for (j=0;j<desc->PortCount;j++) {
1099 if (LADSPA_IS_PORT_AUDIO(desc->PortDescriptors[j]) &&
1100 LADSPA_IS_PORT_INPUT(desc->PortDescriptors[j])) {
1101 sinktempl = ladspa_sink_factory();
1102 gst_element_factory_add_pad_template (factory, sinktempl);
1107 /* only add src padtemplate if there are srcpads */
1108 for (j=0;j<desc->PortCount;j++) {
1109 if (LADSPA_IS_PORT_AUDIO(desc->PortDescriptors[j]) &&
1110 LADSPA_IS_PORT_OUTPUT(desc->PortDescriptors[j])) {
1111 srctempl = ladspa_src_factory();
1112 gst_element_factory_add_pad_template (factory, srctempl);
1121 plugin_init (GModule *module, GstPlugin *plugin)
1123 ladspa_descriptors = g_hash_table_new(NULL,NULL);
1124 parent_class = g_type_class_ref(GST_TYPE_ELEMENT);
1126 ladspa_plugin = plugin;
1128 LADSPAPluginSearch(ladspa_describe_plugin);
1130 if (! gst_library_load ("gstbytestream")) {
1131 gst_info ("gstladspa: could not load support library: 'gstbytestream'\n");
1135 if (! gst_library_load ("gstcontrol")) {
1136 gst_info ("gstladspa: could not load support library: 'gstcontrol'\n");
1143 GstPluginDesc plugin_desc = {