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;
401 ladspa->inplace_broken = LADSPA_IS_INPLACE_BROKEN(ladspa->descriptor->Properties);
403 if (sinkcount==0 && srccount == 1) {
404 /* get mode (no sink pads) */
405 GST_DEBUG (0, "mono get mode with 1 src pad");
407 ladspa->newcaps = TRUE;
408 ladspa->samplerate = 44100;
409 ladspa->buffersize = 64;
411 gst_pad_set_connect_function (ladspa->srcpads[0], gst_ladspa_connect_get);
412 gst_pad_set_get_function (ladspa->srcpads[0], gst_ladspa_get);
414 } else if (sinkcount==1){
415 /* with one sink we can use the chain function */
416 GST_DEBUG (0, "chain mode");
418 gst_pad_set_connect_function (ladspa->sinkpads[0], gst_ladspa_connect);
419 gst_pad_set_chain_function (ladspa->sinkpads[0], gst_ladspa_chain);
420 gst_pad_set_bufferpool_function (ladspa->sinkpads[0], gst_ladspa_get_bufferpool);
421 } else if (sinkcount > 1){
422 /* more than one sink pad needs loop mode */
423 GST_DEBUG (0, "loop mode with %d sink pads and %d src pads", sinkcount, srccount);
425 for (i=0;i<sinkcount;i++) {
426 gst_pad_set_connect_function (ladspa->sinkpads[i], gst_ladspa_connect);
427 gst_pad_set_bufferpool_function (ladspa->sinkpads[i], gst_ladspa_get_bufferpool);
429 gst_element_set_loop_function (GST_ELEMENT (ladspa), gst_ladspa_loop);
431 else if (sinkcount==0 && srccount == 0){
432 /* for some reason these plugins exist - we'll just ignore them */
434 g_warning("%d sink pads, %d src pads not yet supported", sinkcount, srccount);
437 gst_ladspa_instantiate(ladspa);
441 gst_ladspa_update_int(const GValue *value, gpointer data)
443 gfloat *target = (gfloat*) data;
444 *target = (gfloat)g_value_get_int(value);
447 static GstPadConnectReturn
448 gst_ladspa_connect (GstPad *pad, GstCaps *caps)
450 GstLADSPA *ladspa = (GstLADSPA *) GST_PAD_PARENT (pad);
451 GstLADSPAClass *oclass = (GstLADSPAClass *) (G_OBJECT_GET_CLASS (ladspa));
455 g_return_val_if_fail (caps != NULL, GST_PAD_CONNECT_DELAYED);
456 g_return_val_if_fail (pad != NULL, GST_PAD_CONNECT_DELAYED);
458 if (gst_caps_get_int (caps, "rate", &rate)){
459 /* have to instantiate ladspa plugin when samplerate changes (groan) */
460 if (ladspa->samplerate != rate){
461 ladspa->samplerate = rate;
463 if (! gst_ladspa_instantiate(ladspa))
464 return GST_PAD_CONNECT_REFUSED;
468 /* if the caps are fixed, we are going to try to set all srcpads using this
469 one caps object. if any of the pads barfs, we'll refuse the connection. i'm
470 not sure if this is correct. */
471 if (GST_CAPS_IS_FIXED (caps)) {
472 for (i=0;i<oclass->numsrcpads;i++) {
473 if (! gst_pad_try_set_caps (ladspa->srcpads[i], caps))
474 return GST_PAD_CONNECT_REFUSED;
478 return GST_PAD_CONNECT_OK;
481 static GstPadConnectReturn
482 gst_ladspa_connect_get (GstPad *pad, GstCaps *caps)
484 GstLADSPA *ladspa = (GstLADSPA*)GST_OBJECT_PARENT (pad);
487 g_return_val_if_fail (caps != NULL, GST_PAD_CONNECT_DELAYED);
488 g_return_val_if_fail (pad != NULL, GST_PAD_CONNECT_DELAYED);
490 if (gst_caps_get_int (caps, "rate", &rate)){
491 if (ladspa->samplerate != rate) {
492 ladspa->samplerate = rate;
493 if (! gst_ladspa_instantiate(ladspa))
494 return GST_PAD_CONNECT_REFUSED;
498 return GST_PAD_CONNECT_OK;
502 gst_ladspa_force_src_caps(GstLADSPA *ladspa, GstPad *pad)
504 GST_DEBUG (0, "forcing caps with rate %d", ladspa->samplerate);
505 gst_pad_try_set_caps (pad, gst_caps_new (
509 "format", GST_PROPS_STRING ("float"),
510 "layout", GST_PROPS_STRING ("gfloat"),
511 "intercept", GST_PROPS_FLOAT(0.0),
512 "slope", GST_PROPS_FLOAT(1.0),
513 "rate", GST_PROPS_INT (ladspa->samplerate),
514 "channels", GST_PROPS_INT (1),
518 ladspa->newcaps=FALSE;
522 gst_ladspa_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec)
524 GstLADSPA *ladspa = (GstLADSPA*)object;
525 gint cid = prop_id - ARG_LAST;
526 GstLADSPAClass *oclass;
527 ladspa_control_info *control_info;
530 /* these are only registered in get mode */
533 ladspa->samplerate = g_value_get_int (value);
534 ladspa->newcaps=TRUE;
537 ladspa->buffersize = g_value_get_int (value);
541 /* is it a ladspa plugin arg? */
544 oclass = (GstLADSPAClass*)(G_OBJECT_GET_CLASS (object));
546 /* verify it exists and is a control (not a port) */
547 g_return_if_fail(cid < oclass->numcontrols);
549 control_info = &(oclass->control_info[cid]);
550 g_return_if_fail (control_info->name != NULL);
552 /* check to see if it's writable */
553 g_return_if_fail (control_info->writable);
555 /* now see what type it is */
556 if (control_info->toggled) {
557 if (g_value_get_boolean (value))
558 ladspa->controls[cid] = 1.0;
560 ladspa->controls[cid] = 0.0;
561 } else if (control_info->integer) {
562 val = (gfloat)g_value_get_int (value);
563 ladspa->controls[cid] = val;
565 val = g_value_get_float (value);
566 ladspa->controls[cid] = val;
569 GST_DEBUG (0, "set arg %s to %f", control_info->name, ladspa->controls[cid]);
573 gst_ladspa_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec)
575 GstLADSPA *ladspa = (GstLADSPA*)object;
576 gint cid = prop_id - ARG_LAST;
577 GstLADSPAClass *oclass = (GstLADSPAClass*)(G_OBJECT_GET_CLASS (object));
578 ladspa_control_info *control_info;
580 /* these are only registered in get mode */
583 g_value_set_int (value, ladspa->samplerate);
586 g_value_set_int (value, ladspa->buffersize);
592 /* verify it exists and is a control (not a port) */
593 if (cid >= oclass->numcontrols) return;
594 control_info = &(oclass->control_info[cid]);
595 if (control_info->name == NULL) return;
597 GST_DEBUG (0, "got arg %s as %f", control_info->name, ladspa->controls[cid]);
599 /* now see what type it is */
600 if (control_info->toggled) {
601 if (ladspa->controls[cid] == 1.0)
602 g_value_set_boolean (value, TRUE);
604 g_value_set_boolean (value, FALSE);
605 } else if (control_info->integer) {
606 g_value_set_int (value, (gint)ladspa->controls[cid]);
608 g_value_set_float (value, ladspa->controls[cid]);
613 gst_ladspa_instantiate (GstLADSPA *ladspa)
615 LADSPA_Descriptor *desc;
617 GstLADSPAClass *oclass = (GstLADSPAClass*)(G_OBJECT_GET_CLASS (ladspa));
618 gboolean was_activated;
620 desc = ladspa->descriptor;
622 /* check for old handle */
623 was_activated = ladspa->activated;
624 if (ladspa->handle != NULL){
625 gst_ladspa_deactivate(ladspa);
626 desc->cleanup(ladspa->handle);
629 /* instantiate the plugin */
630 GST_DEBUG (0, "instantiating the plugin");
632 ladspa->handle = desc->instantiate(desc,ladspa->samplerate);
633 g_return_val_if_fail (ladspa->handle != NULL, FALSE);
635 /* walk through the ports and add all the arguments */
636 for (i=0;i<oclass->numcontrols;i++) {
637 /* connect the argument to the plugin */
638 GST_DEBUG (0, "added control port %d", oclass->control_portnums[i]);
639 desc->connect_port(ladspa->handle,
640 oclass->control_portnums[i],
641 &(ladspa->controls[i]));
644 /* reactivate if it was activated before the reinstantiation */
646 gst_ladspa_activate(ladspa);
651 static GstElementStateReturn
652 gst_ladspa_change_state (GstElement *element)
654 LADSPA_Descriptor *desc;
655 GstLADSPA *ladspa = (GstLADSPA*)element;
656 desc = ladspa->descriptor;
658 GST_DEBUG (0, "changing state");
659 switch (GST_STATE_TRANSITION (element)) {
660 case GST_STATE_NULL_TO_READY:
661 gst_ladspa_activate(ladspa);
663 case GST_STATE_READY_TO_NULL:
664 gst_ladspa_deactivate(ladspa);
670 if (GST_ELEMENT_CLASS (parent_class)->change_state)
671 return GST_ELEMENT_CLASS (parent_class)->change_state (element);
673 return GST_STATE_SUCCESS;
677 gst_ladspa_activate(GstLADSPA *ladspa)
679 LADSPA_Descriptor *desc;
680 desc = ladspa->descriptor;
682 if (ladspa->activated){
683 gst_ladspa_deactivate(ladspa);
686 GST_DEBUG (0, "activating");
688 /* activate the plugin (function might be null) */
689 if (desc->activate != NULL) {
690 desc->activate(ladspa->handle);
693 ladspa->activated = TRUE;
697 gst_ladspa_deactivate(GstLADSPA *ladspa)
699 LADSPA_Descriptor *desc;
700 desc = ladspa->descriptor;
702 GST_DEBUG (0, "deactivating");
704 /* deactivate the plugin (function might be null) */
705 if (ladspa->activated && (desc->deactivate != NULL)) {
706 desc->deactivate(ladspa->handle);
709 ladspa->activated = FALSE;
713 gst_ladspa_loop(GstElement *element)
715 guint bufferbytesize, i, numsrcpads, numsinkpads, num_empty_pads;
716 guint num_processed, num_to_process;
717 GstEvent *event = NULL;
719 LADSPA_Data **data_in, **data_out;
720 GstBuffer **buffers_in, **buffers_out;
721 GstBufferPool *bufpool;
722 GstByteStream **bytestreams;
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 && !ladspa->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 || ladspa->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 = NULL;
877 GstBuffer **buffers_out = NULL;
879 unsigned long num_samples;
880 guint num_to_process, num_processed, i, numsrcpads;
883 GstLADSPAClass *oclass;
885 g_return_if_fail(pad != NULL);
886 g_return_if_fail(GST_IS_PAD(pad));
887 g_return_if_fail(buf != NULL);
889 ladspa = (GstLADSPA *)gst_pad_get_parent (pad);
890 g_return_if_fail(ladspa != NULL);
892 /* this might happen if caps nego hasn't happened */
893 g_return_if_fail(ladspa->handle != NULL);
895 oclass = (GstLADSPAClass *) (G_OBJECT_GET_CLASS (ladspa));
897 if (GST_IS_EVENT (buf)) {
898 /* push the event out all the src pads */
899 for (i=0 ; i<oclass->numsrcpads ; i++){
900 gst_pad_push (ladspa->srcpads[0], buf);
905 data_in = (LADSPA_Data *) GST_BUFFER_DATA(buf);
906 num_samples = GST_BUFFER_SIZE(buf) / sizeof(gfloat);
907 numsrcpads = oclass->numsrcpads;
909 desc = ladspa->descriptor;
912 guint num_created_buffers = 0;
913 buffers_out = g_new(GstBuffer*, numsrcpads);
914 data_out = g_new(LADSPA_Data*, numsrcpads);
916 if (ladspa->inplace_broken){
917 num_created_buffers = numsrcpads;
920 /* we can share the buffer for input and output */
921 buffers_out[0] = buf;
922 data_out[0] = (LADSPA_Data *)GST_BUFFER_DATA(buf);
923 num_created_buffers = numsrcpads - 1;
926 if (num_created_buffers > 0){
927 GstBufferPool *bufpool;
928 bufpool = gst_buffer_pool_get_default (sizeof (LADSPA_Data) * GST_BUFFER_SIZE(buf), ladspa->numbuffers);
930 for (i = numsrcpads - num_created_buffers ; i<numsrcpads ; i++){
931 buffers_out[i] = gst_buffer_new_from_pool (ladspa->bufpool, 0, 0);
932 GST_BUFFER_TIMESTAMP(buffers_out[i]) = GST_BUFFER_TIMESTAMP(buf);
933 data_out[i] = (LADSPA_Data *) GST_BUFFER_DATA(buffers_out[i]);
938 num_to_process = GST_DPMAN_PREPROCESS(ladspa->dpman, num_samples, GST_BUFFER_TIMESTAMP(buf));
941 /* split up processing of the buffer into chunks so that dparams can
942 * be updated when required.
943 * In many cases the buffer will be processed in one chunk anyway.
945 while(GST_DPMAN_PROCESS_CHUNK(ladspa->dpman, num_to_process, num_processed)) {
946 desc->connect_port(ladspa->handle,oclass->sinkpad_portnums[0],data_in);
947 for (i=0 ; i<numsrcpads ; i++){
948 desc->connect_port(ladspa->handle,oclass->srcpad_portnums[i],data_out[i]);
950 desc->run(ladspa->handle, num_to_process);
952 data_in += num_to_process;
953 for (i=0 ; i<numsrcpads ; i++){
954 data_out[i] += num_to_process;
956 num_processed += num_to_process;
961 for (i=0 ; i<numsrcpads ; i++){
962 gst_pad_push (ladspa->srcpads[i], buffers_out[i]);
969 /* if we have reached here, there are no src pads */
970 gst_buffer_unref(buf);
974 gst_ladspa_get(GstPad *pad)
977 GstLADSPAClass *oclass;
981 LADSPA_Descriptor *desc;
983 guint num_to_process, num_processed;
985 g_return_val_if_fail(pad != NULL, NULL);
986 g_return_val_if_fail(GST_IS_PAD(pad), NULL);
988 ladspa = (GstLADSPA *)gst_pad_get_parent (pad);
989 g_return_val_if_fail(ladspa != NULL, NULL);
991 /* this might happen if caps nego hasn't happened */
992 g_return_val_if_fail(ladspa->handle != NULL, NULL);
994 oclass = (GstLADSPAClass*)(G_OBJECT_GET_CLASS(ladspa));
996 /* force src pad to set caps */
997 if (ladspa->newcaps) {
998 gst_ladspa_force_src_caps(ladspa, ladspa->srcpads[0]);
1001 /* get a bufferpool */
1002 if (ladspa->bufpool == NULL) {
1003 ladspa->bufpool = gst_pad_get_bufferpool (ladspa->srcpads[0]);
1004 if (ladspa->bufpool == NULL) {
1005 ladspa->bufpool = gst_buffer_pool_get_default (sizeof (LADSPA_Data) * ladspa->buffersize, ladspa->numbuffers);
1009 buf = gst_buffer_new_from_pool (ladspa->bufpool, 0, 0);
1010 GST_BUFFER_TIMESTAMP(buf) = ladspa->timestamp;
1011 data = (LADSPA_Data *) GST_BUFFER_DATA(buf);
1013 desc = ladspa->descriptor;
1014 num_to_process = GST_DPMAN_PREPROCESS(ladspa->dpman, ladspa->buffersize, ladspa->timestamp);
1017 /* update timestamp */
1018 ladspa->timestamp += num_to_process * 10^9 / ladspa->samplerate;
1020 /* split up processing of the buffer into chunks so that dparams can
1021 * be updated when required.
1022 * In many cases the buffer will be processed in one chunk anyway.
1024 while(GST_DPMAN_PROCESS_CHUNK(ladspa->dpman, num_to_process, num_processed)) {
1025 desc->connect_port(ladspa->handle,oclass->srcpad_portnums[0],data);
1026 desc->run(ladspa->handle, num_to_process);
1028 data += num_to_process;
1029 num_processed = num_to_process;
1037 ladspa_describe_plugin(const char *pcFullFilename,
1038 void *pvPluginHandle,
1039 LADSPA_Descriptor_Function pfDescriptorFunction)
1041 const LADSPA_Descriptor *desc;
1044 GstElementDetails *details;
1045 GTypeInfo typeinfo = {
1046 sizeof(GstLADSPAClass),
1049 (GClassInitFunc)gst_ladspa_class_init,
1054 (GInstanceInitFunc)gst_ladspa_init,
1057 GstElementFactory *factory;
1059 /* walk through all the plugins in this pluginlibrary */
1061 while ((desc = pfDescriptorFunction(i++))) {
1064 /* construct the type */
1065 type_name = g_strdup_printf("ladspa_%s",desc->Label);
1066 g_strcanon (type_name, G_CSET_A_2_Z G_CSET_a_2_z G_CSET_DIGITS "-_+", '-');
1067 /* if it's already registered, drop it */
1068 if (g_type_from_name(type_name)) {
1072 /* create the type now */
1073 type = g_type_register_static(GST_TYPE_ELEMENT, type_name, &typeinfo, 0);
1075 /* construct the element details struct */
1076 details = g_new0(GstElementDetails,1);
1077 details->longname = g_strdup(desc->Name);
1078 details->klass = "Filter/Audio/LADSPA";
1079 details->description = details->longname;
1080 details->version = g_strdup_printf("%ld",desc->UniqueID);
1081 details->author = g_strdup(desc->Maker);
1082 details->copyright = g_strdup(desc->Copyright);
1084 /* register the plugin with gstreamer */
1085 factory = gst_element_factory_new(type_name,type,details);
1086 g_return_if_fail(factory != NULL);
1087 gst_plugin_add_feature (ladspa_plugin, GST_PLUGIN_FEATURE (factory));
1089 /* add this plugin to the hash */
1090 g_hash_table_insert(ladspa_descriptors,
1091 GINT_TO_POINTER(type),
1095 /* only add sink padtemplate if there are sinkpads */
1096 for (j=0;j<desc->PortCount;j++) {
1097 if (LADSPA_IS_PORT_AUDIO(desc->PortDescriptors[j]) &&
1098 LADSPA_IS_PORT_INPUT(desc->PortDescriptors[j])) {
1099 sinktempl = ladspa_sink_factory();
1100 gst_element_factory_add_pad_template (factory, sinktempl);
1105 /* only add src padtemplate if there are srcpads */
1106 for (j=0;j<desc->PortCount;j++) {
1107 if (LADSPA_IS_PORT_AUDIO(desc->PortDescriptors[j]) &&
1108 LADSPA_IS_PORT_OUTPUT(desc->PortDescriptors[j])) {
1109 srctempl = ladspa_src_factory();
1110 gst_element_factory_add_pad_template (factory, srctempl);
1119 plugin_init (GModule *module, GstPlugin *plugin)
1121 ladspa_descriptors = g_hash_table_new(NULL,NULL);
1122 parent_class = g_type_class_ref(GST_TYPE_ELEMENT);
1124 ladspa_plugin = plugin;
1126 LADSPAPluginSearch(ladspa_describe_plugin);
1128 if (! gst_library_load ("gstbytestream")) {
1129 gst_info ("gstladspa: could not load support library: 'gstbytestream'\n");
1133 if (! gst_library_load ("gstcontrol")) {
1134 gst_info ("gstladspa: could not load support library: 'gstcontrol'\n");
1141 GstPluginDesc plugin_desc = {