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.
24 #include "gstladspa.h"
25 #include "ladspa.h" /* main ladspa sdk include file */
26 #include "utils.h" /* ladspa sdk utility functions */
29 static GstPadTemplate*
30 ladspa_src_factory (void)
41 "format", GST_PROPS_STRING ("float"),
42 "layout", GST_PROPS_STRING ("gfloat"),
43 "intercept", GST_PROPS_FLOAT(0.0),
44 "slope", GST_PROPS_FLOAT(1.0),
45 "channels", GST_PROPS_INT (1),
46 "rate", GST_PROPS_INT_RANGE (0,G_MAXINT),
51 static GstPadTemplate*
52 ladspa_sink_factory (void)
63 "format", GST_PROPS_STRING ("float"),
64 "layout", GST_PROPS_STRING ("gfloat"),
65 "intercept", GST_PROPS_FLOAT(0.0),
66 "slope", GST_PROPS_FLOAT(1.0),
67 "channels", GST_PROPS_INT (1),
68 "rate", GST_PROPS_INT_RANGE (0,G_MAXINT),
81 static void gst_ladspa_class_init (GstLADSPAClass *klass);
82 static void gst_ladspa_init (GstLADSPA *ladspa);
84 static GstPadConnectReturn gst_ladspa_connect (GstPad *pad, GstCaps *caps);
85 static GstPadConnectReturn gst_ladspa_connect_get (GstPad *pad, GstCaps *caps);
86 static void gst_ladspa_force_src_caps (GstLADSPA *ladspa, GstPad *pad);
88 static void gst_ladspa_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec);
89 static void gst_ladspa_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec);
91 static gboolean gst_ladspa_instantiate (GstLADSPA *ladspa);
92 static void gst_ladspa_activate (GstLADSPA *ladspa);
93 static void gst_ladspa_deactivate (GstLADSPA *ladspa);
95 static GstElementStateReturn gst_ladspa_change_state (GstElement *element);
96 static void gst_ladspa_loop (GstElement *element);
97 static void gst_ladspa_chain_mono (GstPad *pad,GstBuffer *buf);
98 static GstBuffer * gst_ladspa_get (GstPad *pad);
100 static GstElementClass *parent_class = NULL;
101 static GstPadTemplate *srctempl, *sinktempl;
102 /* static guint gst_ladspa_signals[LAST_SIGNAL] = { 0 }; */
104 static GstPlugin *ladspa_plugin;
105 static GHashTable *ladspa_descriptors;
107 static GstBufferPool*
108 gst_ladspa_get_bufferpool (GstPad *pad)
112 GstLADSPA *ladspa = (GstLADSPA *) gst_pad_get_parent (pad);
113 GstLADSPAClass *oclass = (GstLADSPAClass *) (G_OBJECT_GET_CLASS (ladspa));
115 if (oclass->numsrcpads > 0)
116 for (i=0;i<oclass->numsrcpads;i++)
117 if ((bp = gst_pad_get_bufferpool(ladspa->srcpads[0])) != NULL)
124 gst_ladspa_class_init (GstLADSPAClass *klass)
126 GObjectClass *gobject_class;
127 GstElementClass *gstelement_class;
128 LADSPA_Descriptor *desc;
129 gint i,current_portnum,sinkcount,srccount,controlcount;
131 gint argtype,argperms;
132 GParamSpec *paramspec = NULL;
133 gchar *argname, *tempstr, *paren;
135 gobject_class = (GObjectClass*)klass;
136 gstelement_class = (GstElementClass*)klass;
138 gobject_class->set_property = gst_ladspa_set_property;
139 gobject_class->get_property = gst_ladspa_get_property;
141 gstelement_class->change_state = gst_ladspa_change_state;
143 g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_LOOP_BASED,
144 g_param_spec_boolean("loop-based","loop-based","loop-based",
145 FALSE,G_PARAM_READWRITE));
147 /* look up and store the ladspa descriptor */
148 klass->descriptor = g_hash_table_lookup(ladspa_descriptors,GINT_TO_POINTER(G_TYPE_FROM_CLASS(klass)));
149 desc = klass->descriptor;
151 klass->numports = desc->PortCount;
153 klass->numsinkpads = 0;
154 klass->numsrcpads = 0;
155 klass->numcontrols = 0;
157 /* walk through the ports, count the input, output and control ports */
158 for (i=0;i<desc->PortCount;i++) {
159 if (LADSPA_IS_PORT_AUDIO(desc->PortDescriptors[i]) &&
160 LADSPA_IS_PORT_INPUT(desc->PortDescriptors[i])){
161 klass->numsinkpads++;
164 if (LADSPA_IS_PORT_AUDIO(desc->PortDescriptors[i]) &&
165 LADSPA_IS_PORT_OUTPUT(desc->PortDescriptors[i])){
169 if (LADSPA_IS_PORT_CONTROL(desc->PortDescriptors[i]) &&
170 LADSPA_IS_PORT_INPUT(desc->PortDescriptors[i])){
171 klass->numcontrols++;
175 klass->srcpad_portnums = g_new0(gint,klass->numsrcpads);
176 klass->sinkpad_portnums = g_new0(gint,klass->numsinkpads);
177 klass->control_portnums = g_new0(gint,klass->numcontrols);
182 /* walk through the ports, note the portnums for srcpads, sinkpads and control
184 for (i=0;i<desc->PortCount;i++) {
185 if (LADSPA_IS_PORT_AUDIO(desc->PortDescriptors[i]) &&
186 LADSPA_IS_PORT_INPUT(desc->PortDescriptors[i])){
187 GST_DEBUG (0, "input port %d", i);
188 klass->sinkpad_portnums[sinkcount++] = i;
191 if (LADSPA_IS_PORT_AUDIO(desc->PortDescriptors[i]) &&
192 LADSPA_IS_PORT_OUTPUT(desc->PortDescriptors[i])){
193 GST_DEBUG (0, "output port %d", i);
194 klass->srcpad_portnums[srccount++] = i;
197 if (LADSPA_IS_PORT_CONTROL(desc->PortDescriptors[i]) &&
198 LADSPA_IS_PORT_INPUT(desc->PortDescriptors[i])){
199 GST_DEBUG (0, "control port %d", i);
200 klass->control_portnums[controlcount++] = i;
204 /* no sink pads - we'll use get mode and add params for samplerate and
206 if (klass->numsinkpads == 0 && klass->numsrcpads > 0){
207 g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_SAMPLERATE,
208 g_param_spec_int("samplerate","samplerate","samplerate",
209 0,G_MAXINT,44100,G_PARAM_READWRITE));
210 g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_BUFFERSIZE,
211 g_param_spec_int("buffersize","buffersize","buffersize",
212 0,G_MAXINT,64,G_PARAM_READWRITE));
216 /* now build the contorl info from the control ports */
217 klass->control_info = g_new0(ladspa_control_info,klass->numcontrols);
219 for (i=0;i<klass->numcontrols;i++) {
220 current_portnum = klass->control_portnums[i];
222 /* short name for hint descriptor */
223 hintdesc = desc->PortRangeHints[current_portnum].HintDescriptor;
225 /* get the various bits */
226 if (LADSPA_IS_HINT_TOGGLED(hintdesc))
227 klass->control_info[i].toggled = TRUE;
228 if (LADSPA_IS_HINT_LOGARITHMIC(hintdesc))
229 klass->control_info[i].logarithmic = TRUE;
230 if (LADSPA_IS_HINT_INTEGER(hintdesc))
231 klass->control_info[i].integer = TRUE;
233 /* figure out the argument details */
234 if (klass->control_info[i].toggled) argtype = G_TYPE_BOOLEAN;
235 else if (klass->control_info[i].integer) argtype = G_TYPE_INT;
236 else argtype = G_TYPE_FLOAT;
238 /* grab the bounds */
239 if (LADSPA_IS_HINT_BOUNDED_BELOW(hintdesc)) {
240 klass->control_info[i].lower = TRUE;
241 klass->control_info[i].lowerbound =
242 desc->PortRangeHints[current_portnum].LowerBound;
244 if (argtype==G_TYPE_INT) klass->control_info[i].lowerbound = (gfloat)G_MININT;
245 if (argtype==G_TYPE_FLOAT) klass->control_info[i].lowerbound = G_MINFLOAT;
248 if (LADSPA_IS_HINT_BOUNDED_ABOVE(hintdesc)) {
249 klass->control_info[i].upper = TRUE;
250 klass->control_info[i].upperbound =
251 desc->PortRangeHints[current_portnum].UpperBound;
252 if (LADSPA_IS_HINT_SAMPLE_RATE(hintdesc))
253 klass->control_info[i].samplerate = TRUE;
255 if (argtype==G_TYPE_INT) klass->control_info[i].upperbound = (gfloat)G_MAXINT;
256 if (argtype==G_TYPE_FLOAT) klass->control_info[i].upperbound = G_MAXFLOAT;
259 if (LADSPA_IS_PORT_INPUT(desc->PortDescriptors[current_portnum])) {
260 argperms = G_PARAM_READWRITE;
261 klass->control_info[i].writable = TRUE;
263 argperms = G_PARAM_READABLE;
264 klass->control_info[i].writable = FALSE;
267 klass->control_info[i].name = g_strdup(desc->PortNames[current_portnum]);
268 argname = g_strdup(klass->control_info[i].name);
269 /* find out if there is a (unitname) at the end of the argname and get rid
271 paren = g_strrstr (argname, " (");
275 /* this is the same thing that param_spec_* will do */
276 g_strcanon (argname, G_CSET_A_2_Z G_CSET_a_2_z G_CSET_DIGITS "-", '-');
277 /* satisfy glib2 (argname[0] must be [A-Za-z]) */
278 if (!((argname[0] >= 'a' && argname[0] <= 'z') || (argname[0] >= 'A' && argname[0] <= 'Z'))) {
280 argname = g_strconcat("param-", argname, NULL);
284 /* check for duplicate property names */
285 if (g_object_class_find_property(G_OBJECT_CLASS(klass), argname) != NULL){
287 gchar *numargname = g_strdup_printf("%s_%d",argname,numarg++);
288 while (g_object_class_find_property(G_OBJECT_CLASS(klass), numargname) != NULL){
290 numargname = g_strdup_printf("%s_%d",argname,numarg++);
292 argname = numargname;
295 g_print("adding arg %s from %s\n",argname, klass->control_info[i].name);
297 if (argtype==G_TYPE_BOOLEAN){
298 paramspec = g_param_spec_boolean(argname,argname,argname, FALSE, argperms);
299 } else if (argtype==G_TYPE_INT){
300 paramspec = g_param_spec_int(argname,argname,argname,
301 (gint)klass->control_info[i].lowerbound, (gint)klass->control_info[i].upperbound, 0, argperms);
303 paramspec = g_param_spec_float(argname,argname,argname,
304 klass->control_info[i].lowerbound, klass->control_info[i].upperbound,
305 (klass->control_info[i].lowerbound + klass->control_info[i].upperbound) / 2.0f, argperms);
308 g_object_class_install_property(G_OBJECT_CLASS(klass), i+ARG_LAST, paramspec);
313 gst_ladspa_init (GstLADSPA *ladspa)
315 GstLADSPAClass *oclass = (GstLADSPAClass*)(G_OBJECT_GET_CLASS(ladspa));
317 LADSPA_Descriptor *desc;
318 gint i,sinkcount,srccount,controlcount;
320 desc = oclass->descriptor;
321 ladspa->descriptor = oclass->descriptor;
323 /* allocate the various arrays */
324 ladspa->srcpads = g_new0(GstPad*,oclass->numsrcpads);
325 ladspa->sinkpads = g_new0(GstPad*,oclass->numsinkpads);
326 ladspa->bytestreams = g_new0(GstByteStream*,oclass->numsinkpads);
327 ladspa->controls = g_new(gfloat,oclass->numcontrols);
329 /* walk through the ports and add all the pads */
333 for (i=0;i<desc->PortCount;i++) {
334 if (LADSPA_IS_PORT_AUDIO(desc->PortDescriptors[i]) &&
335 LADSPA_IS_PORT_INPUT(desc->PortDescriptors[i])) {
336 ladspa->sinkpads[sinkcount] = gst_pad_new_from_template (sinktempl, (gchar *)desc->PortNames[i]);
337 ladspa->bytestreams[sinkcount] = gst_bytestream_new (ladspa->sinkpads[sinkcount]);
338 gst_element_add_pad(GST_ELEMENT(ladspa),ladspa->sinkpads[sinkcount]);
341 if (LADSPA_IS_PORT_AUDIO(desc->PortDescriptors[i]) &&
342 LADSPA_IS_PORT_OUTPUT(desc->PortDescriptors[i])) {
343 ladspa->srcpads[srccount] = gst_pad_new_from_template (srctempl, (gchar *)desc->PortNames[i]);
344 gst_element_add_pad(GST_ELEMENT(ladspa),ladspa->srcpads[srccount]);
347 if (LADSPA_IS_PORT_CONTROL(desc->PortDescriptors[i]) &&
348 LADSPA_IS_PORT_INPUT(desc->PortDescriptors[i])) {
349 /* use the lowerbound as the default value if it exists */
350 if (oclass->control_info[controlcount].lower){
351 ladspa->controls[controlcount]=oclass->control_info[controlcount].lowerbound;
353 ladspa->controls[controlcount] = 0.0;
359 ladspa->samplerate = 0;
360 ladspa->buffersize = 64;
361 ladspa->numbuffers = 16;
362 ladspa->newcaps = FALSE;
363 ladspa->activated = FALSE;
364 ladspa->bufpool = NULL;
366 /* we assume srccount > 0 because there are no LADSPA sink elements. */
369 /* get mode (no sink pads) */
370 GST_INFO (0, "get mode with %d src pads\n", srccount);
372 ladspa->newcaps = TRUE;
373 ladspa->samplerate = 44100;
374 ladspa->buffersize = 64;
376 for (i=0;i<srccount;i++) {
377 gst_pad_set_connect_function (ladspa->srcpads[i], gst_ladspa_connect_get);
378 gst_pad_set_get_function (ladspa->srcpads[i], gst_ladspa_get);
380 } else if (sinkcount==1 && srccount==1){
382 GST_INFO (0, "inplace mono chain mode\n");
384 gst_pad_set_connect_function (ladspa->sinkpads[0], gst_ladspa_connect);
385 gst_pad_set_chain_function (ladspa->sinkpads[0], gst_ladspa_chain_mono);
386 gst_pad_set_bufferpool_function (ladspa->sinkpads[0], gst_ladspa_get_bufferpool);
388 /* sinkcount>0 and srccount>0 : N sink pads and M src pads */
389 GST_INFO (0, "loop mode with %d sink pads and %d src pads\n", sinkcount, srccount);
391 for (i=0;i<sinkcount;i++) {
392 gst_pad_set_connect_function (ladspa->sinkpads[i], gst_ladspa_connect);
393 gst_pad_set_bufferpool_function (ladspa->sinkpads[i], gst_ladspa_get_bufferpool);
396 ladspa->loopbased = TRUE;
397 gst_element_set_loop_function (GST_ELEMENT (ladspa), gst_ladspa_loop);
400 gst_ladspa_instantiate(ladspa);
403 static GstPadConnectReturn
404 gst_ladspa_connect (GstPad *pad, GstCaps *caps)
406 GstLADSPA *ladspa = (GstLADSPA *) GST_PAD_PARENT (pad);
407 GstLADSPAClass *oclass = (GstLADSPAClass *) (G_OBJECT_GET_CLASS (ladspa));
411 g_return_val_if_fail (caps != NULL, GST_PAD_CONNECT_DELAYED);
412 g_return_val_if_fail (pad != NULL, GST_PAD_CONNECT_DELAYED);
414 gst_caps_get_int (caps, "rate", &rate);
415 /* have to instantiate ladspa plugin when samplerate changes (groan) */
416 if (ladspa->samplerate != rate){
417 ladspa->samplerate = rate;
418 if (! gst_ladspa_instantiate(ladspa))
419 return GST_PAD_CONNECT_REFUSED;
422 /* if the caps are fixed, we are going to try to set all srcpads using this
423 one caps object. if any of the pads barfs, we'll refuse the connection. i'm
424 not sure if this is correct. */
425 if (GST_CAPS_IS_FIXED (caps)) {
426 for (i=0;i<oclass->numsrcpads;i++) {
427 if (! gst_pad_try_set_caps (ladspa->srcpads[i], caps))
428 return GST_PAD_CONNECT_REFUSED;
432 return GST_PAD_CONNECT_DELAYED;
435 static GstPadConnectReturn
436 gst_ladspa_connect_get (GstPad *pad, GstCaps *caps)
438 GstLADSPA *ladspa = (GstLADSPA*)GST_OBJECT_PARENT (pad);
441 g_return_val_if_fail (caps != NULL, GST_PAD_CONNECT_DELAYED);
442 g_return_val_if_fail (pad != NULL, GST_PAD_CONNECT_DELAYED);
444 gst_caps_get_int (caps, "rate", &rate);
446 if (ladspa->samplerate != rate) {
447 ladspa->samplerate = rate;
448 if (! gst_ladspa_instantiate(ladspa))
449 return GST_PAD_CONNECT_REFUSED;
452 return GST_PAD_CONNECT_DELAYED;
456 gst_ladspa_force_src_caps(GstLADSPA *ladspa, GstPad *pad)
458 GST_DEBUG (0, "forcing caps");
459 gst_pad_try_set_caps (pad, gst_caps_new (
463 "format", GST_PROPS_STRING ("float"),
464 "layout", GST_PROPS_STRING ("gfloat"),
465 "intercept", GST_PROPS_FLOAT(0.0),
466 "slope", GST_PROPS_FLOAT(1.0),
467 "rate", GST_PROPS_INT (ladspa->samplerate),
468 "channels", GST_PROPS_INT (1),
472 ladspa->newcaps=FALSE;
476 gst_ladspa_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec)
478 GstLADSPA *ladspa = (GstLADSPA*)object;
479 gint cid = prop_id - ARG_LAST;
480 GstLADSPAClass *oclass;
481 ladspa_control_info *control_info;
484 /* these are only registered in get mode */
487 ladspa->samplerate = g_value_get_int (value);
488 ladspa->newcaps=TRUE;
491 ladspa->buffersize = g_value_get_int (value);
495 /* is it a ladspa plugin arg? */
499 if (id == ARG_LOOP_BASED) {
500 * we can only do this in NULL state *
501 g_return_if_fail (GST_STATE(object) != GST_STATE_NULL);
502 ladspa->loopbased = g_value_get_boolean (value);
503 if (ladspa->loopbased) {
504 gst_element_set_loop_function (GST_ELEMENT (ladspa), gst_ladspa_loop);
506 gst_element_set_loop_function (GST_ELEMENT (ladspa), NULL);
511 oclass = (GstLADSPAClass*)(G_OBJECT_GET_CLASS (object));
513 /* verify it exists and is a control (not a port) */
514 g_return_if_fail(cid < oclass->numcontrols);
516 control_info = &(oclass->control_info[cid]);
517 g_return_if_fail (control_info->name != NULL);
519 /* check to see if it's writable */
520 g_return_if_fail (control_info->writable);
522 /* now see what type it is */
523 if (control_info->toggled) {
524 if (g_value_get_boolean (value))
525 ladspa->controls[cid] = 1.0;
527 ladspa->controls[cid] = 0.0;
528 } else if (control_info->integer) {
529 val = (gfloat)g_value_get_int (value);
530 ladspa->controls[cid] = val;
532 val = g_value_get_float (value);
533 ladspa->controls[cid] = val;
536 GST_DEBUG (0, "set arg %s to %f", control_info->name, ladspa->controls[cid]);
540 gst_ladspa_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec)
542 GstLADSPA *ladspa = (GstLADSPA*)object;
543 gint cid = prop_id - ARG_LAST;
544 GstLADSPAClass *oclass = (GstLADSPAClass*)(G_OBJECT_GET_CLASS (object));
545 ladspa_control_info *control_info;
547 /* these are only registered in get mode */
550 g_value_set_int (value, ladspa->samplerate);
553 g_value_set_int (value, ladspa->buffersize);
559 /* verify it exists and is a control (not a port) */
560 if (cid >= oclass->numcontrols) return;
561 control_info = &(oclass->control_info[cid]);
562 if (control_info->name == NULL) return;
564 GST_DEBUG (0, "got arg %s as %f", control_info->name, ladspa->controls[cid]);
566 /* now see what type it is */
567 if (control_info->toggled) {
568 if (ladspa->controls[cid] == 1.0)
569 g_value_set_boolean (value, TRUE);
571 g_value_set_boolean (value, FALSE);
572 } else if (control_info->integer) {
573 g_value_set_int (value, (gint)ladspa->controls[cid]);
575 g_value_set_float (value, ladspa->controls[cid]);
580 gst_ladspa_instantiate (GstLADSPA *ladspa)
582 LADSPA_Descriptor *desc;
584 GstLADSPAClass *oclass = (GstLADSPAClass*)(G_OBJECT_GET_CLASS (ladspa));
585 gboolean was_activated;
587 desc = ladspa->descriptor;
589 /* check for old handle */
590 was_activated = ladspa->activated;
591 if (ladspa->handle != NULL){
592 gst_ladspa_deactivate(ladspa);
593 desc->cleanup(ladspa->handle);
596 /* instantiate the plugin */
597 GST_DEBUG (0, "instantiating the plugin");
599 ladspa->handle = desc->instantiate(desc,ladspa->samplerate);
600 g_return_val_if_fail (ladspa->handle != NULL, FALSE);
602 /* walk through the ports and add all the arguments */
603 for (i=0;i<oclass->numcontrols;i++) {
604 /* connect the argument to the plugin */
605 GST_DEBUG (0, "added control port %d", oclass->control_portnums[i]);
606 desc->connect_port(ladspa->handle,
607 oclass->control_portnums[i],
608 &(ladspa->controls[i]));
611 /* reactivate if it was activated before the reinstantiation */
613 gst_ladspa_activate(ladspa);
618 static GstElementStateReturn
619 gst_ladspa_change_state (GstElement *element)
621 LADSPA_Descriptor *desc;
622 GstLADSPA *ladspa = (GstLADSPA*)element;
623 desc = ladspa->descriptor;
625 GST_DEBUG (0, "changing state");
626 switch (GST_STATE_TRANSITION (element)) {
627 case GST_STATE_NULL_TO_READY:
628 gst_ladspa_activate(ladspa);
630 case GST_STATE_READY_TO_NULL:
631 gst_ladspa_deactivate(ladspa);
637 if (GST_ELEMENT_CLASS (parent_class)->change_state)
638 return GST_ELEMENT_CLASS (parent_class)->change_state (element);
640 return GST_STATE_SUCCESS;
644 gst_ladspa_activate(GstLADSPA *ladspa)
646 LADSPA_Descriptor *desc;
647 desc = ladspa->descriptor;
649 if (ladspa->activated){
650 gst_ladspa_deactivate(ladspa);
653 GST_DEBUG (0, "activating");
655 /* activate the plugin (function might be null) */
656 if (desc->activate != NULL) {
657 desc->activate(ladspa->handle);
660 ladspa->activated = TRUE;
664 gst_ladspa_deactivate(GstLADSPA *ladspa)
666 LADSPA_Descriptor *desc;
667 desc = ladspa->descriptor;
669 GST_DEBUG (0, "deactivating");
671 /* deactivate the plugin (function might be null) */
672 if (ladspa->activated && (desc->deactivate != NULL)) {
673 desc->deactivate(ladspa->handle);
676 ladspa->activated = FALSE;
680 gst_ladspa_loop (GstElement *element)
682 gint8 *raw_in, *zero_out, i;
683 GstBuffer **buffers_out;
684 GstEvent *event = NULL;
686 LADSPA_Data **data_in, *data_out;
689 GstLADSPA *ladspa = (GstLADSPA *)element;
690 GstLADSPAClass *oclass = (GstLADSPAClass*)(G_OBJECT_GET_CLASS (ladspa));
691 LADSPA_Descriptor *desc = ladspa->descriptor;
693 data_in = g_new0(LADSPA_Data *, oclass->numsinkpads);
694 buffers_out = g_new0(GstBuffer *, oclass->numsrcpads);
696 /* set up the bufferpool first if necessary */
698 while ((ladspa->bufpool == NULL) && (i < oclass->numsrcpads)) {
699 ladspa->bufpool = gst_pad_get_bufferpool (ladspa->srcpads[i++]);
701 if (ladspa->bufpool == NULL) {
702 ladspa->bufpool = gst_buffer_pool_get_default (sizeof (LADSPA_Data) * ladspa->buffersize,
706 /* since this is a loop element, we just loop here til things fall apart. */
709 /* first get all the necessary data from the input ports */
710 for (i=0;i<oclass->numsinkpads;i++){
711 GST_DEBUG (0, "pulling %d bytes through channel %d'sbytestream\n",
712 ladspa->buffersize * sizeof (LADSPA_Data), i);
713 raw_in = gst_bytestream_peek_bytes (ladspa->bytestreams[i], ladspa->buffersize * sizeof (LADSPA_Data));
715 if (raw_in == NULL) {
716 /* we need to check for an event. */
717 gst_bytestream_get_status (ladspa->bytestreams[i], &waiting, &event);
720 if (GST_EVENT_TYPE(event) == GST_EVENT_EOS) {
721 /* if we get an EOS event from one of our sink pads, we assume that
722 pad's finished handling data. delete the bytestream, free up the
723 pad, and free up the memory associated with the input channel. */
724 GST_DEBUG (0, "got an EOS event on sinkpad %d", i);
727 /* we need to create some zeroed out data to feed to this port of the
729 data_in[i] = g_new0 (LADSPA_Data, ladspa->buffersize * sizeof (LADSPA_Data));
731 /* copy the retrieved data and bind the ladspa src port to the data */
732 data_in[i] = (LADSPA_Data *) raw_in;
737 desc->connect_port (ladspa->handle, oclass->sinkpad_portnums[i], data_in[i]);
738 gst_bytestream_flush (ladspa->bytestreams[i], ladspa->buffersize * sizeof (LADSPA_Data));
741 /* now set up the output ports */
742 for (i=0;i<oclass->numsrcpads;i++) {
743 buffers_out[i] = (GstBuffer *) gst_buffer_new_from_pool (ladspa->bufpool, 0, 0);
745 if (buffers_out[i] == NULL)
746 GST_ERROR (0, "could not get new output buffer for srcpad %d !\n", i);
748 data_out = (LADSPA_Data *) GST_BUFFER_DATA (buffers_out[i]);
749 size = GST_BUFFER_SIZE (buffers_out[i]);
750 GST_BUFFER_TIMESTAMP (buffers_out[i]) = ladspa->timestamp;
752 /* initialize the output data to 0 */
753 zero_out = (gint8 *) GST_BUFFER_DATA (buffers_out[i]);
754 for (i = 0; i < size; i++)
757 desc->connect_port (ladspa->handle, oclass->srcpad_portnums[i], data_out);
760 /* i'm not sure if this will work ; the number of samples might be
761 nonconstant across sources and sinks ... */
762 desc->run (ladspa->handle, ladspa->buffersize);
764 /* now go through and reset the ladspa ports, pushing out the output buffers
766 for (i=0;i<oclass->numsinkpads;i++) {
767 desc->connect_port (ladspa->handle, oclass->sinkpad_portnums[i], NULL);
769 for (i=0;i<oclass->numsrcpads;i++) {
770 GST_DEBUG (0, "pushing buffer (%p) on src pad %d", buffers_out[i], i);
771 gst_pad_push (ladspa->srcpads[i], buffers_out[i]);
772 buffers_out[i] = NULL;
773 desc->connect_port (ladspa->handle, oclass->srcpad_portnums[i], NULL);
776 ladspa->timestamp += ladspa->buffersize * ladspa->samplerate * 10^9;
779 g_free (buffers_out);
783 gst_ladspa_chain_mono (GstPad *pad, GstBuffer *buf)
785 LADSPA_Descriptor *desc;
787 unsigned long num_samples;
790 GstLADSPAClass *oclass;
792 g_return_if_fail(pad != NULL);
793 g_return_if_fail(GST_IS_PAD(pad));
794 g_return_if_fail(buf != NULL);
796 ladspa = (GstLADSPA *)gst_pad_get_parent (pad);
797 g_return_if_fail(ladspa != NULL);
799 /* this might happen if caps nego hasn't happened */
800 g_return_if_fail(ladspa->handle != NULL);
802 if (! GST_IS_EVENT (buf)) {
803 oclass = (GstLADSPAClass *) (G_OBJECT_GET_CLASS (ladspa));
804 data = (LADSPA_Data *) GST_BUFFER_DATA(buf);
805 num_samples = GST_BUFFER_SIZE(buf) / sizeof(gfloat);
807 desc = ladspa->descriptor;
809 /* we know that we're dealing here with a filter that has one sink and one
811 desc->connect_port(ladspa->handle,oclass->sinkpad_portnums[0],data);
812 desc->connect_port(ladspa->handle,oclass->srcpad_portnums[0],data);
814 desc->run(ladspa->handle,num_samples);
816 desc->connect_port(ladspa->handle,oclass->sinkpad_portnums[0],NULL);
817 desc->connect_port(ladspa->handle,oclass->srcpad_portnums[0],NULL);
820 gst_pad_push (ladspa->srcpads[0], buf);
824 gst_ladspa_get(GstPad *pad)
826 LADSPA_Descriptor *desc;
830 GstLADSPAClass *oclass;
836 g_return_val_if_fail(pad != NULL, NULL);
837 g_return_val_if_fail(GST_IS_PAD(pad), NULL);
839 ladspa = (GstLADSPA *)gst_pad_get_parent (pad);
840 g_return_val_if_fail(ladspa != NULL, NULL);
842 /* this might happen if caps nego hasn't happened */
843 g_return_val_if_fail(ladspa->handle != NULL, NULL);
845 oclass = (GstLADSPAClass*)(G_OBJECT_GET_CLASS(ladspa));
847 /* force all src pads to set their caps */
848 if (ladspa->newcaps) {
849 for (i=0;i<oclass->numsrcpads;i++) {
850 gst_ladspa_force_src_caps(ladspa, ladspa->srcpads[0]);
854 /* get a bufferpool */
856 while ((ladspa->bufpool == NULL) && (i < oclass->numsrcpads)) {
857 ladspa->bufpool = gst_pad_get_bufferpool (ladspa->srcpads[i++]);
859 if (ladspa->bufpool == NULL) {
860 ladspa->bufpool = gst_buffer_pool_get_default (sizeof (LADSPA_Data) * ladspa->buffersize,
864 buf = (GstBuffer *) gst_buffer_new_from_pool (ladspa->bufpool, 0, 0);
865 g_return_val_if_fail (buf, NULL);
867 /* initialize the output data to 0 */
868 zero_out = (gint8 *) GST_BUFFER_DATA (buf);
869 for (i = 0; i < GST_BUFFER_SIZE (buf); i++)
872 data = (LADSPA_Data *) GST_BUFFER_DATA(buf);
873 size = GST_BUFFER_SIZE(buf);
874 GST_BUFFER_TIMESTAMP(buf) = ladspa->timestamp;
875 ladspa->timestamp += size * ladspa->samplerate * 10^9;
877 desc = ladspa->descriptor;
879 for (i=0;i<oclass->numsrcpads;i++)
880 desc->connect_port(ladspa->handle,oclass->srcpad_portnums[i],data);
882 desc->run(ladspa->handle, size);
884 for (i=0;i<oclass->numsrcpads;i++)
885 desc->connect_port(ladspa->handle,oclass->srcpad_portnums[i],NULL);
891 ladspa_describe_plugin(const char *pcFullFilename,
892 void *pvPluginHandle,
893 LADSPA_Descriptor_Function pfDescriptorFunction)
895 const LADSPA_Descriptor *desc;
898 GstElementDetails *details;
899 GTypeInfo typeinfo = {
900 sizeof(GstLADSPAClass),
903 (GClassInitFunc)gst_ladspa_class_init,
908 (GInstanceInitFunc)gst_ladspa_init,
911 GstElementFactory *factory;
913 /* walk through all the plugins in this pluginlibrary */
915 while ((desc = pfDescriptorFunction(i++))) {
918 /* construct the type */
919 type_name = g_strdup_printf("ladspa_%s",desc->Label);
920 g_strcanon (type_name, G_CSET_A_2_Z G_CSET_a_2_z G_CSET_DIGITS "-_+", '-');
921 /* if it's already registered, drop it */
922 if (g_type_from_name(type_name)) {
926 /* create the type now */
927 type = g_type_register_static(GST_TYPE_ELEMENT, type_name, &typeinfo, 0);
929 /* construct the element details struct */
930 details = g_new0(GstElementDetails,1);
931 details->longname = g_strdup(desc->Name);
932 details->klass = "Filter/LADSPA";
933 details->description = details->longname;
934 details->version = g_strdup_printf("%ld",desc->UniqueID);
935 details->author = g_strdup(desc->Maker);
936 details->copyright = g_strdup(desc->Copyright);
938 /* register the plugin with gstreamer */
939 factory = gst_elementfactory_new(type_name,type,details);
940 g_return_if_fail(factory != NULL);
941 gst_plugin_add_feature (ladspa_plugin, GST_PLUGIN_FEATURE (factory));
943 /* add this plugin to the hash */
944 g_hash_table_insert(ladspa_descriptors,
945 GINT_TO_POINTER(type),
949 /* only add sink padtemplate if there are sinkpads */
950 for (j=0;j<desc->PortCount;j++) {
951 if (LADSPA_IS_PORT_AUDIO(desc->PortDescriptors[j]) &&
952 LADSPA_IS_PORT_INPUT(desc->PortDescriptors[j])) {
953 sinktempl = ladspa_sink_factory();
954 gst_elementfactory_add_padtemplate (factory, sinktempl);
959 srctempl = ladspa_src_factory();
960 gst_elementfactory_add_padtemplate (factory, srctempl);
966 plugin_init (GModule *module, GstPlugin *plugin)
968 ladspa_descriptors = g_hash_table_new(NULL,NULL);
969 parent_class = g_type_class_ref(GST_TYPE_ELEMENT);
971 ladspa_plugin = plugin;
973 LADSPAPluginSearch(ladspa_describe_plugin);
975 if (! gst_library_load ("gstbytestream")) {
976 gst_info ("gstladspa: could not load support library: 'gstbytestream'\n");
983 GstPluginDesc plugin_desc = {