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;
720 LADSPA_Data **data_in, **data_out;
721 GstBuffer **buffers_in, **buffers_out;
722 GstBufferPool *bufpool;
723 GstByteStream **bytestreams;
725 GstLADSPA *ladspa = (GstLADSPA *)element;
726 GstLADSPAClass *oclass = (GstLADSPAClass*)(G_OBJECT_GET_CLASS (ladspa));
727 LADSPA_Descriptor *desc = ladspa->descriptor;
729 numsinkpads = oclass->numsinkpads;
730 numsrcpads = oclass->numsrcpads;
732 data_in = g_new0(LADSPA_Data*, numsinkpads);
733 data_out = g_new0(LADSPA_Data*, numsrcpads);
734 buffers_in = g_new0(GstBuffer*, numsinkpads);
735 buffers_out = g_new0(GstBuffer*, numsrcpads);
736 bytestreams = g_new0(GstByteStream*, numsinkpads);
738 bufferbytesize = sizeof (LADSPA_Data) * ladspa->buffersize;
740 /* find a bufferpool */
741 bufpool = gst_buffer_pool_get_default (bufferbytesize, ladspa->numbuffers);
743 /* get the bytestreams for each pad */
744 for (i=0 ; i<numsinkpads ; i++){
745 bytestreams[i] = gst_bytestream_new (ladspa->sinkpads[i]);
748 /* since this is a loop element, we just loop here til things fall apart. */
751 /* first get all the necessary data from the input ports */
752 for (i=0 ; i<numsinkpads ; i++){
753 GST_DEBUG (0, "pulling %u bytes through channel %d'sbytestream", bufferbytesize, i);
754 got_bytes = gst_bytestream_read (bytestreams[i], buffers_in + i, bufferbytesize);
756 if (got_bytes != bufferbytesize) {
757 /* we need to check for an event. */
758 gst_bytestream_get_status (bytestreams[i], &waiting, &event);
760 if (event && GST_EVENT_TYPE(event) == GST_EVENT_EOS) {
761 /* if we get an EOS event from one of our sink pads, we assume that
762 pad's finished handling data. delete the bytestream, free up the
763 pad, and free up the memory associated with the input channel. */
764 GST_DEBUG (0, "got an EOS event on sinkpad %d", i);
766 /* CHECKME should maybe check for other events and try to pull more data here */
769 data_in[i] = (LADSPA_Data *) GST_BUFFER_DATA(buffers_in[i]);
770 GST_BUFFER_TIMESTAMP(buffers_in[i]) = ladspa->timestamp;
774 if (num_empty_pads > 0){
775 if (num_empty_pads < numsinkpads){
776 /* only some pads have EOS, need to create some empty buffers */
777 for (i=0 ; i<numsinkpads ; i++){
778 if (buffers_in[i] == NULL){
781 buffers_in[i] = gst_buffer_new_from_pool (ladspa->bufpool, 0, 0);
782 GST_BUFFER_TIMESTAMP(buffers_in[i]) = ladspa->timestamp;
783 data_in[i] = data = (LADSPA_Data *) GST_BUFFER_DATA(buffers_in[i]);
784 for (x=0 ; x < ladspa->buffersize ; x++)
787 data_in[i] = (LADSPA_Data *) GST_BUFFER_DATA(buffers_in[i]);
788 GST_BUFFER_TIMESTAMP(buffers_in[i]) = ladspa->timestamp;
793 /* all pads have EOS, time to quit */
794 /* CHECKME do I have to push EOS events here? */
795 GST_DEBUG (0, "All sink pads have EOS, finishing.");
800 /* we now have a full set of buffers_in.
801 * now share or create the buffers_out */
802 for (i=0 ; i<numsrcpads ; i++){
803 if (i <= numsinkpads && !ladspa->inplace_broken){
804 /* we can share buffers */
805 buffers_out[i] = buffers_in[i];
806 data_out[i] = data_in[i];
808 buffers_out[i] = gst_buffer_new_from_pool (bufpool, 0, 0);
809 GST_BUFFER_TIMESTAMP(buffers_out[i]) = ladspa->timestamp;
810 data_out[i] = (LADSPA_Data *) GST_BUFFER_DATA(buffers_out[i]);
814 GST_DPMAN_PREPROCESS(ladspa->dpman, ladspa->buffersize, ladspa->timestamp);
817 /* split up processing of the buffer into chunks so that dparams can
818 * be updated when required.
819 * In many cases the buffer will be processed in one chunk anyway.
821 while(GST_DPMAN_PROCESS(ladspa->dpman, num_processed)) {
823 num_to_process = GST_DPMAN_FRAMES_TO_PROCESS(ladspa->dpman);
824 for (i=0 ; i<numsinkpads ; i++){
825 desc->connect_port (ladspa->handle, oclass->sinkpad_portnums[i], data_in[i]);
827 for (i=0 ; i<numsrcpads ; i++){
828 desc->connect_port (ladspa->handle, oclass->srcpad_portnums[i], data_out[i]);
830 desc->run(ladspa->handle, num_to_process);
831 for (i=0 ; i<numsinkpads ; i++){
832 data_in[i] += num_to_process;
834 for (i=0 ; i<numsrcpads ; i++){
835 data_out[i] += num_to_process;
838 num_processed += num_to_process;
841 for (i=0 ; i<numsrcpads ; i++) {
842 GST_DEBUG (0, "pushing buffer (%p) on src pad %d", buffers_out[i], i);
843 gst_pad_push (ladspa->srcpads[i], buffers_out[i]);
846 buffers_out[i] = NULL;
848 for (i=0 ; i<numsinkpads ; i++) {
849 if (i > numsrcpads || ladspa->inplace_broken){
850 /* we have some buffers to unref */
851 gst_buffer_unref(buffers_in[i]);
854 buffers_in[i] = NULL;
857 ladspa->timestamp += ladspa->buffersize * 10^9 / ladspa->samplerate;
860 gst_buffer_pool_unref(bufpool);
862 for (i=0 ; i<numsinkpads ; i++){
863 gst_bytestream_destroy (bytestreams[i]);
866 g_free (buffers_out);
870 g_free (bytestreams);
874 gst_ladspa_chain (GstPad *pad, GstBuffer *buf)
876 LADSPA_Descriptor *desc;
877 LADSPA_Data *data_in, **data_out = NULL;
878 GstBuffer **buffers_out = NULL;
880 unsigned long num_samples;
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;
913 guint num_created_buffers = 0;
914 buffers_out = g_new(GstBuffer*, numsrcpads);
915 data_out = g_new(LADSPA_Data*, numsrcpads);
917 if (ladspa->inplace_broken){
918 num_created_buffers = numsrcpads;
921 /* we can share the buffer for input and output */
922 buffers_out[0] = buf;
923 data_out[0] = (LADSPA_Data *)GST_BUFFER_DATA(buf);
924 num_created_buffers = numsrcpads - 1;
927 if (num_created_buffers > 0){
928 GstBufferPool *bufpool;
929 bufpool = gst_buffer_pool_get_default (sizeof (LADSPA_Data) * GST_BUFFER_SIZE(buf), ladspa->numbuffers);
931 for (i = numsrcpads - num_created_buffers ; i<numsrcpads ; i++){
932 buffers_out[i] = gst_buffer_new_from_pool (ladspa->bufpool, 0, 0);
933 GST_BUFFER_TIMESTAMP(buffers_out[i]) = GST_BUFFER_TIMESTAMP(buf);
934 data_out[i] = (LADSPA_Data *) GST_BUFFER_DATA(buffers_out[i]);
939 GST_DPMAN_PREPROCESS(ladspa->dpman, num_samples, GST_BUFFER_TIMESTAMP(buf));
942 /* split up processing of the buffer into chunks so that dparams can
943 * be updated when required.
944 * In many cases the buffer will be processed in one chunk anyway.
946 while(GST_DPMAN_PROCESS(ladspa->dpman, num_processed)) {
947 num_to_process = GST_DPMAN_FRAMES_TO_PROCESS(ladspa->dpman);
949 desc->connect_port(ladspa->handle,oclass->sinkpad_portnums[0],data_in);
950 for (i=0 ; i<numsrcpads ; i++){
951 desc->connect_port(ladspa->handle,oclass->srcpad_portnums[i],data_out[i]);
953 desc->run(ladspa->handle, num_to_process);
955 data_in += num_to_process;
956 for (i=0 ; i<numsrcpads ; i++){
957 data_out[i] += num_to_process;
959 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 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(ladspa->dpman, num_processed)) {
1027 num_to_process = GST_DPMAN_FRAMES_TO_PROCESS(ladspa->dpman);
1029 desc->connect_port(ladspa->handle,oclass->srcpad_portnums[0],data);
1030 desc->run(ladspa->handle, num_to_process);
1032 data += num_to_process;
1033 num_processed = num_to_process;
1040 ladspa_describe_plugin(const char *pcFullFilename,
1041 void *pvPluginHandle,
1042 LADSPA_Descriptor_Function pfDescriptorFunction)
1044 const LADSPA_Descriptor *desc;
1047 GstElementDetails *details;
1048 GTypeInfo typeinfo = {
1049 sizeof(GstLADSPAClass),
1052 (GClassInitFunc)gst_ladspa_class_init,
1057 (GInstanceInitFunc)gst_ladspa_init,
1060 GstElementFactory *factory;
1062 /* walk through all the plugins in this pluginlibrary */
1064 while ((desc = pfDescriptorFunction(i++))) {
1067 /* construct the type */
1068 type_name = g_strdup_printf("ladspa_%s",desc->Label);
1069 g_strcanon (type_name, G_CSET_A_2_Z G_CSET_a_2_z G_CSET_DIGITS "-_+", '-');
1070 /* if it's already registered, drop it */
1071 if (g_type_from_name(type_name)) {
1075 /* create the type now */
1076 type = g_type_register_static(GST_TYPE_ELEMENT, type_name, &typeinfo, 0);
1078 /* construct the element details struct */
1079 details = g_new0(GstElementDetails,1);
1080 details->longname = g_strdup(desc->Name);
1081 details->klass = "Filter/Audio/LADSPA";
1082 details->description = details->longname;
1083 details->version = g_strdup_printf("%ld",desc->UniqueID);
1084 details->author = g_strdup(desc->Maker);
1085 details->copyright = g_strdup(desc->Copyright);
1087 /* register the plugin with gstreamer */
1088 factory = gst_element_factory_new(type_name,type,details);
1089 g_return_if_fail(factory != NULL);
1090 gst_plugin_add_feature (ladspa_plugin, GST_PLUGIN_FEATURE (factory));
1092 /* add this plugin to the hash */
1093 g_hash_table_insert(ladspa_descriptors,
1094 GINT_TO_POINTER(type),
1098 /* only add sink padtemplate if there are sinkpads */
1099 for (j=0;j<desc->PortCount;j++) {
1100 if (LADSPA_IS_PORT_AUDIO(desc->PortDescriptors[j]) &&
1101 LADSPA_IS_PORT_INPUT(desc->PortDescriptors[j])) {
1102 sinktempl = ladspa_sink_factory();
1103 gst_element_factory_add_pad_template (factory, sinktempl);
1108 /* only add src padtemplate if there are srcpads */
1109 for (j=0;j<desc->PortCount;j++) {
1110 if (LADSPA_IS_PORT_AUDIO(desc->PortDescriptors[j]) &&
1111 LADSPA_IS_PORT_OUTPUT(desc->PortDescriptors[j])) {
1112 srctempl = ladspa_src_factory();
1113 gst_element_factory_add_pad_template (factory, srctempl);
1122 plugin_init (GModule *module, GstPlugin *plugin)
1124 ladspa_descriptors = g_hash_table_new(NULL,NULL);
1125 parent_class = g_type_class_ref(GST_TYPE_ELEMENT);
1127 ladspa_plugin = plugin;
1129 LADSPAPluginSearch(ladspa_describe_plugin);
1131 if (! gst_library_load ("gstbytestream")) {
1132 gst_info ("gstladspa: could not load support library: 'gstbytestream'\n");
1136 if (! gst_library_load ("gstcontrol")) {
1137 gst_info ("gstladspa: could not load support library: 'gstcontrol'\n");
1144 GstPluginDesc plugin_desc = {