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 klass->control_info[i].def = klass->control_info[i].lowerbound;
247 #ifdef LADSPA_IS_HINT_HAS_DEFAULT
248 /* figure out the defaults */
249 if (LADSPA_IS_HINT_HAS_DEFAULT (hintdesc)) {
250 if (LADSPA_IS_HINT_DEFAULT_MINIMUM (hintdesc))
251 klass->control_info[i].def = klass->control_info[i].lowerbound;
252 else if (LADSPA_IS_HINT_DEFAULT_LOW (hintdesc))
253 if (LADSPA_IS_HINT_LOGARITHMIC (hintdesc))
254 klass->control_info[i].def = exp (0.75*log(klass->control_info[i].lowerbound) +
255 0.25*log(klass->control_info[i].upperbound));
257 klass->control_info[i].def = (0.75*klass->control_info[i].lowerbound +
258 0.25*klass->control_info[i].upperbound);
259 else if (LADSPA_IS_HINT_DEFAULT_MIDDLE (hintdesc))
260 if (LADSPA_IS_HINT_LOGARITHMIC (hintdesc))
261 klass->control_info[i].def = exp (0.5*log(klass->control_info[i].lowerbound) +
262 0.5*log(klass->control_info[i].upperbound));
264 klass->control_info[i].def = (0.5*klass->control_info[i].lowerbound +
265 0.5*klass->control_info[i].upperbound);
266 else if (LADSPA_IS_HINT_DEFAULT_HIGH (hintdesc))
267 if (LADSPA_IS_HINT_LOGARITHMIC (hintdesc))
268 klass->control_info[i].def = exp (0.25*log(klass->control_info[i].lowerbound) +
269 0.75*log(klass->control_info[i].upperbound));
271 klass->control_info[i].def = (0.25*klass->control_info[i].lowerbound +
272 0.75*klass->control_info[i].upperbound);
273 else if (LADSPA_IS_HINT_DEFAULT_MAXIMUM (hintdesc))
274 klass->control_info[i].def = klass->control_info[i].upperbound;
275 else if (LADSPA_IS_HINT_DEFAULT_0 (hintdesc))
276 klass->control_info[i].def = 0.0;
277 else if (LADSPA_IS_HINT_DEFAULT_1 (hintdesc))
278 klass->control_info[i].def = 1.0;
279 else if (LADSPA_IS_HINT_DEFAULT_100 (hintdesc))
280 klass->control_info[i].def = 100.0;
281 else if (LADSPA_IS_HINT_DEFAULT_440 (hintdesc))
282 klass->control_info[i].def = 440.0;
284 #endif /* LADSPA_IS_HINT_HAS_DEFAULT */
286 if (LADSPA_IS_PORT_INPUT(desc->PortDescriptors[current_portnum])) {
287 argperms = G_PARAM_READWRITE;
288 klass->control_info[i].writable = TRUE;
290 argperms = G_PARAM_READABLE;
291 klass->control_info[i].writable = FALSE;
294 klass->control_info[i].name = g_strdup(desc->PortNames[current_portnum]);
295 argname = g_strdup(klass->control_info[i].name);
296 /* find out if there is a (unitname) at the end of the argname and get rid
298 paren = g_strrstr (argname, " (");
302 /* this is the same thing that param_spec_* will do */
303 g_strcanon (argname, G_CSET_A_2_Z G_CSET_a_2_z G_CSET_DIGITS "-", '-');
304 /* satisfy glib2 (argname[0] must be [A-Za-z]) */
305 if (!((argname[0] >= 'a' && argname[0] <= 'z') || (argname[0] >= 'A' && argname[0] <= 'Z'))) {
307 argname = g_strconcat("param-", argname, NULL);
311 /* check for duplicate property names */
312 if (g_object_class_find_property(G_OBJECT_CLASS(klass), argname) != NULL){
314 gchar *numargname = g_strdup_printf("%s_%d",argname,numarg++);
315 while (g_object_class_find_property(G_OBJECT_CLASS(klass), numargname) != NULL){
317 numargname = g_strdup_printf("%s_%d",argname,numarg++);
319 argname = numargname;
322 klass->control_info[i].param_name = argname;
324 GST_DEBUG (0, "adding arg %s from %s",argname, klass->control_info[i].name);
326 if (argtype==G_TYPE_BOOLEAN){
327 paramspec = g_param_spec_boolean(argname,argname,argname, FALSE, argperms);
328 } else if (argtype==G_TYPE_INT){
329 paramspec = g_param_spec_int(argname,argname,argname,
330 (gint)klass->control_info[i].lowerbound,
331 (gint)klass->control_info[i].upperbound,
332 (gint)klass->control_info[i].def, argperms);
333 } else if (klass->control_info[i].samplerate){
334 paramspec = g_param_spec_float(argname,argname,argname,
338 paramspec = g_param_spec_float(argname,argname,argname,
339 klass->control_info[i].lowerbound, klass->control_info[i].upperbound,
340 klass->control_info[i].def, argperms);
343 g_object_class_install_property(G_OBJECT_CLASS(klass), i+ARG_LAST, paramspec);
348 gst_ladspa_init (GstLADSPA *ladspa)
350 GstLADSPAClass *oclass = (GstLADSPAClass*)(G_OBJECT_GET_CLASS(ladspa));
351 ladspa_control_info cinfo;
353 LADSPA_Descriptor *desc;
354 gint i,sinkcount,srccount,controlcount;
356 desc = oclass->descriptor;
357 ladspa->descriptor = oclass->descriptor;
359 /* allocate the various arrays */
360 ladspa->srcpads = g_new0(GstPad*,oclass->numsrcpads);
361 ladspa->sinkpads = g_new0(GstPad*,oclass->numsinkpads);
362 ladspa->controls = g_new(gfloat,oclass->numcontrols);
363 ladspa->dpman = gst_dpman_new ("ladspa_dpman", GST_ELEMENT(ladspa));
365 /* walk through the ports and add all the pads */
369 for (i=0;i<desc->PortCount;i++) {
371 if (LADSPA_IS_PORT_AUDIO(desc->PortDescriptors[i])){
372 gchar *canon_port_name = g_strdup((gchar *)desc->PortNames[i]);
373 g_strcanon (canon_port_name, G_CSET_A_2_Z G_CSET_a_2_z G_CSET_DIGITS "-", '-');
374 if (LADSPA_IS_PORT_INPUT(desc->PortDescriptors[i])) {
375 ladspa->sinkpads[sinkcount] = gst_pad_new_from_template (sinktempl, canon_port_name);
376 gst_element_add_pad(GST_ELEMENT(ladspa),ladspa->sinkpads[sinkcount]);
379 if (LADSPA_IS_PORT_OUTPUT(desc->PortDescriptors[i])) {
380 ladspa->srcpads[srccount] = gst_pad_new_from_template (srctempl, canon_port_name);
381 gst_element_add_pad(GST_ELEMENT(ladspa),ladspa->srcpads[srccount]);
385 if (LADSPA_IS_PORT_CONTROL(desc->PortDescriptors[i]) &&
386 LADSPA_IS_PORT_INPUT(desc->PortDescriptors[i])) {
387 cinfo = oclass->control_info[controlcount];
388 /* use the lowerbound as the default value if it exists */
389 ladspa->controls[controlcount]=cinfo.def;
391 /* set up dparams for this instance */
393 gst_dpman_add_required_dparam_callback (
395 g_param_spec_int(cinfo.param_name, cinfo.name, cinfo.name,
396 0, 1, (gint)(ladspa->controls[controlcount]), G_PARAM_READWRITE),
397 "int", gst_ladspa_update_int, &(ladspa->controls[controlcount])
400 else if (cinfo.integer){
401 gst_dpman_add_required_dparam_callback (
403 g_param_spec_int(cinfo.param_name, cinfo.name, cinfo.name,
404 (gint)cinfo.lowerbound, (gint)cinfo.upperbound,
405 (gint)ladspa->controls[controlcount], G_PARAM_READWRITE),
406 "int", gst_ladspa_update_int, &(ladspa->controls[controlcount])
409 else if (cinfo.samplerate){
410 gst_dpman_add_required_dparam_direct (
412 g_param_spec_float(cinfo.param_name, cinfo.name, cinfo.name,
413 cinfo.lowerbound, cinfo.upperbound,
414 ladspa->controls[controlcount], G_PARAM_READWRITE),
415 "hertz-rate-bound", &(ladspa->controls[controlcount])
419 gst_dpman_add_required_dparam_direct (
421 g_param_spec_float(cinfo.param_name, cinfo.name, cinfo.name,
422 cinfo.lowerbound, cinfo.upperbound,
423 ladspa->controls[controlcount], G_PARAM_READWRITE),
424 "float", &(ladspa->controls[controlcount])
432 ladspa->samplerate = 0;
433 ladspa->buffersize = 64;
434 ladspa->numbuffers = 16;
435 ladspa->newcaps = FALSE;
436 ladspa->activated = FALSE;
437 ladspa->bufpool = NULL;
438 ladspa->inplace_broken = LADSPA_IS_INPLACE_BROKEN(ladspa->descriptor->Properties);
440 if (sinkcount==0 && srccount == 1) {
441 /* get mode (no sink pads) */
442 GST_DEBUG (0, "mono get mode with 1 src pad");
444 ladspa->newcaps = TRUE;
445 ladspa->samplerate = 44100;
446 ladspa->buffersize = 64;
448 gst_pad_set_connect_function (ladspa->srcpads[0], gst_ladspa_connect_get);
449 gst_pad_set_get_function (ladspa->srcpads[0], gst_ladspa_get);
451 } else if (sinkcount==1){
452 /* with one sink we can use the chain function */
453 GST_DEBUG (0, "chain mode");
455 gst_pad_set_connect_function (ladspa->sinkpads[0], gst_ladspa_connect);
456 gst_pad_set_chain_function (ladspa->sinkpads[0], gst_ladspa_chain);
457 gst_pad_set_bufferpool_function (ladspa->sinkpads[0], gst_ladspa_get_bufferpool);
458 } else if (sinkcount > 1){
459 /* more than one sink pad needs loop mode */
460 GST_DEBUG (0, "loop mode with %d sink pads and %d src pads", sinkcount, srccount);
462 for (i=0;i<sinkcount;i++) {
463 gst_pad_set_connect_function (ladspa->sinkpads[i], gst_ladspa_connect);
464 gst_pad_set_bufferpool_function (ladspa->sinkpads[i], gst_ladspa_get_bufferpool);
466 gst_element_set_loop_function (GST_ELEMENT (ladspa), gst_ladspa_loop);
468 else if (sinkcount==0 && srccount == 0){
469 /* for some reason these plugins exist - we'll just ignore them */
471 g_warning("%d sink pads, %d src pads not yet supported", sinkcount, srccount);
474 gst_ladspa_instantiate(ladspa);
478 gst_ladspa_update_int(const GValue *value, gpointer data)
480 gfloat *target = (gfloat*) data;
481 *target = (gfloat)g_value_get_int(value);
484 static GstPadConnectReturn
485 gst_ladspa_connect (GstPad *pad, GstCaps *caps)
487 GstLADSPA *ladspa = (GstLADSPA *) GST_PAD_PARENT (pad);
488 GstLADSPAClass *oclass = (GstLADSPAClass *) (G_OBJECT_GET_CLASS (ladspa));
492 g_return_val_if_fail (caps != NULL, GST_PAD_CONNECT_DELAYED);
493 g_return_val_if_fail (pad != NULL, GST_PAD_CONNECT_DELAYED);
495 if (gst_caps_get_int (caps, "rate", &rate)){
496 /* have to instantiate ladspa plugin when samplerate changes (groan) */
497 if (ladspa->samplerate != rate){
498 ladspa->samplerate = rate;
500 if (! gst_ladspa_instantiate(ladspa))
501 return GST_PAD_CONNECT_REFUSED;
505 /* if the caps are fixed, we are going to try to set all srcpads using this
506 one caps object. if any of the pads barfs, we'll refuse the connection. i'm
507 not sure if this is correct. */
508 if (GST_CAPS_IS_FIXED (caps)) {
509 for (i=0;i<oclass->numsrcpads;i++) {
510 if (gst_pad_try_set_caps (ladspa->srcpads[i], caps) <= 0)
511 return GST_PAD_CONNECT_REFUSED;
515 return GST_PAD_CONNECT_OK;
518 static GstPadConnectReturn
519 gst_ladspa_connect_get (GstPad *pad, GstCaps *caps)
521 GstLADSPA *ladspa = (GstLADSPA*)GST_OBJECT_PARENT (pad);
524 g_return_val_if_fail (caps != NULL, GST_PAD_CONNECT_DELAYED);
525 g_return_val_if_fail (pad != NULL, GST_PAD_CONNECT_DELAYED);
527 if (gst_caps_get_int (caps, "rate", &rate)){
528 if (ladspa->samplerate != rate) {
529 ladspa->samplerate = rate;
530 if (! gst_ladspa_instantiate(ladspa))
531 return GST_PAD_CONNECT_REFUSED;
535 return GST_PAD_CONNECT_OK;
539 gst_ladspa_force_src_caps(GstLADSPA *ladspa, GstPad *pad)
541 GST_DEBUG (0, "forcing caps with rate %d", ladspa->samplerate);
542 gst_pad_try_set_caps (pad, gst_caps_new (
546 "format", GST_PROPS_STRING ("float"),
547 "layout", GST_PROPS_STRING ("gfloat"),
548 "intercept", GST_PROPS_FLOAT(0.0),
549 "slope", GST_PROPS_FLOAT(1.0),
550 "rate", GST_PROPS_INT (ladspa->samplerate),
551 "channels", GST_PROPS_INT (1),
555 ladspa->newcaps=FALSE;
559 gst_ladspa_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec)
561 GstLADSPA *ladspa = (GstLADSPA*)object;
562 gint cid = prop_id - ARG_LAST;
563 GstLADSPAClass *oclass;
564 ladspa_control_info *control_info;
567 /* these are only registered in get mode */
570 ladspa->samplerate = g_value_get_int (value);
571 ladspa->newcaps=TRUE;
574 ladspa->buffersize = g_value_get_int (value);
578 /* is it a ladspa plugin arg? */
581 oclass = (GstLADSPAClass*)(G_OBJECT_GET_CLASS (object));
583 /* verify it exists and is a control (not a port) */
584 g_return_if_fail(cid < oclass->numcontrols);
586 control_info = &(oclass->control_info[cid]);
587 g_return_if_fail (control_info->name != NULL);
589 /* check to see if it's writable */
590 g_return_if_fail (control_info->writable);
592 /* now see what type it is */
593 if (control_info->toggled) {
594 if (g_value_get_boolean (value))
595 ladspa->controls[cid] = 1.0;
597 ladspa->controls[cid] = 0.0;
598 } else if (control_info->integer) {
599 val = (gfloat)g_value_get_int (value);
600 ladspa->controls[cid] = val;
602 val = g_value_get_float (value);
603 ladspa->controls[cid] = val;
606 GST_DEBUG (0, "set arg %s to %f", control_info->name, ladspa->controls[cid]);
610 gst_ladspa_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec)
612 GstLADSPA *ladspa = (GstLADSPA*)object;
613 gint cid = prop_id - ARG_LAST;
614 GstLADSPAClass *oclass = (GstLADSPAClass*)(G_OBJECT_GET_CLASS (object));
615 ladspa_control_info *control_info;
617 /* these are only registered in get mode */
620 g_value_set_int (value, ladspa->samplerate);
623 g_value_set_int (value, ladspa->buffersize);
629 /* verify it exists and is a control (not a port) */
630 if (cid >= oclass->numcontrols) return;
631 control_info = &(oclass->control_info[cid]);
632 if (control_info->name == NULL) return;
634 GST_DEBUG (0, "got arg %s as %f", control_info->name, ladspa->controls[cid]);
636 /* now see what type it is */
637 if (control_info->toggled) {
638 if (ladspa->controls[cid] == 1.0)
639 g_value_set_boolean (value, TRUE);
641 g_value_set_boolean (value, FALSE);
642 } else if (control_info->integer) {
643 g_value_set_int (value, (gint)ladspa->controls[cid]);
645 g_value_set_float (value, ladspa->controls[cid]);
650 gst_ladspa_instantiate (GstLADSPA *ladspa)
652 LADSPA_Descriptor *desc;
654 GstLADSPAClass *oclass = (GstLADSPAClass*)(G_OBJECT_GET_CLASS (ladspa));
655 gboolean was_activated;
657 desc = ladspa->descriptor;
659 /* check for old handle */
660 was_activated = ladspa->activated;
661 if (ladspa->handle != NULL){
662 gst_ladspa_deactivate(ladspa);
663 desc->cleanup(ladspa->handle);
666 /* instantiate the plugin */
667 GST_DEBUG (0, "instantiating the plugin");
669 ladspa->handle = desc->instantiate(desc,ladspa->samplerate);
670 g_return_val_if_fail (ladspa->handle != NULL, FALSE);
672 /* walk through the ports and add all the arguments */
673 for (i=0;i<oclass->numcontrols;i++) {
674 /* connect the argument to the plugin */
675 GST_DEBUG (0, "added control port %d", oclass->control_portnums[i]);
676 desc->connect_port(ladspa->handle,
677 oclass->control_portnums[i],
678 &(ladspa->controls[i]));
681 /* reactivate if it was activated before the reinstantiation */
683 gst_ladspa_activate(ladspa);
688 static GstElementStateReturn
689 gst_ladspa_change_state (GstElement *element)
691 LADSPA_Descriptor *desc;
692 GstLADSPA *ladspa = (GstLADSPA*)element;
693 desc = ladspa->descriptor;
695 GST_DEBUG (0, "changing state");
696 switch (GST_STATE_TRANSITION (element)) {
697 case GST_STATE_NULL_TO_READY:
698 gst_ladspa_activate(ladspa);
700 case GST_STATE_READY_TO_NULL:
701 gst_ladspa_deactivate(ladspa);
707 if (GST_ELEMENT_CLASS (parent_class)->change_state)
708 return GST_ELEMENT_CLASS (parent_class)->change_state (element);
710 return GST_STATE_SUCCESS;
714 gst_ladspa_activate(GstLADSPA *ladspa)
716 LADSPA_Descriptor *desc;
717 desc = ladspa->descriptor;
719 if (ladspa->activated){
720 gst_ladspa_deactivate(ladspa);
723 GST_DEBUG (0, "activating");
725 /* activate the plugin (function might be null) */
726 if (desc->activate != NULL) {
727 desc->activate(ladspa->handle);
730 ladspa->activated = TRUE;
734 gst_ladspa_deactivate(GstLADSPA *ladspa)
736 LADSPA_Descriptor *desc;
737 desc = ladspa->descriptor;
739 GST_DEBUG (0, "deactivating");
741 /* deactivate the plugin (function might be null) */
742 if (ladspa->activated && (desc->deactivate != NULL)) {
743 desc->deactivate(ladspa->handle);
746 ladspa->activated = FALSE;
750 gst_ladspa_loop(GstElement *element)
752 guint bufferbytesize, i, numsrcpads, numsinkpads, num_empty_pads;
753 guint num_processed, num_to_process;
754 GstEvent *event = NULL;
757 LADSPA_Data **data_in, **data_out;
758 GstBuffer **buffers_in, **buffers_out;
759 GstBufferPool *bufpool;
760 GstByteStream **bytestreams;
762 GstLADSPA *ladspa = (GstLADSPA *)element;
763 GstLADSPAClass *oclass = (GstLADSPAClass*)(G_OBJECT_GET_CLASS (ladspa));
764 LADSPA_Descriptor *desc = ladspa->descriptor;
766 numsinkpads = oclass->numsinkpads;
767 numsrcpads = oclass->numsrcpads;
769 data_in = g_new0(LADSPA_Data*, numsinkpads);
770 data_out = g_new0(LADSPA_Data*, numsrcpads);
771 buffers_in = g_new0(GstBuffer*, numsinkpads);
772 buffers_out = g_new0(GstBuffer*, numsrcpads);
773 bytestreams = g_new0(GstByteStream*, numsinkpads);
775 /* find a bufferpool */
776 if (numsrcpads > 0 && (bufpool = gst_pad_get_bufferpool (ladspa->srcpads[0]))) {
777 GST_DEBUG (0, "Got bufferpool from first source pad");
779 bufferbytesize = sizeof (LADSPA_Data) * ladspa->buffersize;
780 bufpool = gst_buffer_pool_get_default (bufferbytesize, ladspa->numbuffers);
781 GST_DEBUG (0, "Created default bufferpool, %d x %d bytes", ladspa->numbuffers, bufferbytesize);
784 /* get the bytestreams for each pad */
785 for (i=0 ; i<numsinkpads ; i++){
786 bytestreams[i] = gst_bytestream_new (ladspa->sinkpads[i]);
789 /* since this is a loop element, we just loop here til things fall apart. */
791 /* we need to get the buffers_out first so we can know how many bytes to process */
792 for (i=0 ; i<numsrcpads ; i++){
793 buffers_out[i] = gst_buffer_new_from_pool (bufpool, 0, 0);
794 GST_BUFFER_TIMESTAMP(buffers_out[i]) = ladspa->timestamp;
795 data_out[i] = (LADSPA_Data *) GST_BUFFER_DATA(buffers_out[i]);
798 bufferbytesize = GST_BUFFER_SIZE (buffers_out[0]);
799 ladspa->buffersize = bufferbytesize / sizeof (LADSPA_Data);
802 /* first get all the necessary data from the input ports */
803 for (i=0 ; i<numsinkpads ; i++){
804 GST_DEBUG (0, "pulling %u bytes through channel %d's bytestream", bufferbytesize, i);
805 got_bytes = gst_bytestream_read (bytestreams[i], buffers_in + i, bufferbytesize);
807 if (got_bytes != bufferbytesize) {
808 /* we need to check for an event. */
809 gst_bytestream_get_status (bytestreams[i], &waiting, &event);
811 if (event && GST_EVENT_TYPE(event) == GST_EVENT_EOS) {
812 /* if we get an EOS event from one of our sink pads, we assume that
813 pad's finished handling data. delete the bytestream, free up the
814 pad, and free up the memory associated with the input channel. */
815 GST_DEBUG (0, "got an EOS event on sinkpad %d", i);
817 /* CHECKME should maybe check for other events and try to pull more data here */
820 data_in[i] = (LADSPA_Data *) GST_BUFFER_DATA(buffers_in[i]);
821 GST_BUFFER_TIMESTAMP(buffers_in[i]) = ladspa->timestamp;
825 if (num_empty_pads > 0){
826 if (num_empty_pads < numsinkpads){
827 /* only some pads have EOS, need to create some empty buffers */
828 for (i=0 ; i<numsinkpads ; i++){
829 if (buffers_in[i] == NULL){
832 buffers_in[i] = gst_buffer_new_from_pool (ladspa->bufpool, 0, 0);
833 GST_BUFFER_TIMESTAMP(buffers_in[i]) = ladspa->timestamp;
834 data_in[i] = data = (LADSPA_Data *) GST_BUFFER_DATA(buffers_in[i]);
835 for (x=0 ; x < ladspa->buffersize ; x++)
838 data_in[i] = (LADSPA_Data *) GST_BUFFER_DATA(buffers_in[i]);
839 GST_BUFFER_TIMESTAMP(buffers_in[i]) = ladspa->timestamp;
844 /* all pads have EOS, time to quit */
845 /* CHECKME do I have to push EOS events here? */
846 GST_DEBUG (0, "All sink pads have EOS, finishing.");
851 GST_DPMAN_PREPROCESS(ladspa->dpman, ladspa->buffersize, ladspa->timestamp);
854 /* split up processing of the buffer into chunks so that dparams can
855 * be updated when required.
856 * In many cases the buffer will be processed in one chunk anyway.
858 while(GST_DPMAN_PROCESS(ladspa->dpman, num_processed)) {
860 num_to_process = GST_DPMAN_FRAMES_TO_PROCESS(ladspa->dpman);
861 for (i=0 ; i<numsinkpads ; i++){
862 desc->connect_port (ladspa->handle, oclass->sinkpad_portnums[i], data_in[i]);
864 for (i=0 ; i<numsrcpads ; i++){
865 desc->connect_port (ladspa->handle, oclass->srcpad_portnums[i], data_out[i]);
867 desc->run(ladspa->handle, num_to_process);
868 for (i=0 ; i<numsinkpads ; i++){
869 data_in[i] += num_to_process;
871 for (i=0 ; i<numsrcpads ; i++){
872 data_out[i] += num_to_process;
875 num_processed += num_to_process;
878 for (i=0 ; i<numsrcpads ; i++) {
879 GST_DEBUG (0, "pushing buffer (%p) on src pad %d", buffers_out[i], i);
880 gst_pad_push (ladspa->srcpads[i], buffers_out[i]);
883 buffers_out[i] = NULL;
885 for (i=0 ; i<numsinkpads ; i++) {
886 gst_buffer_unref(buffers_in[i]);
888 buffers_in[i] = NULL;
891 ladspa->timestamp += ladspa->buffersize * 10^9 / ladspa->samplerate;
893 gst_element_yield (element);
896 gst_buffer_pool_unref(bufpool);
898 for (i=0 ; i<numsinkpads ; i++){
899 gst_bytestream_destroy (bytestreams[i]);
902 g_free (buffers_out);
906 g_free (bytestreams);
910 gst_ladspa_chain (GstPad *pad, GstBuffer *buf)
912 LADSPA_Descriptor *desc;
913 LADSPA_Data *data_in, **data_out = NULL;
914 GstBuffer **buffers_out = NULL;
916 unsigned long num_samples;
917 guint num_to_process, num_processed, i, numsrcpads;
920 GstLADSPAClass *oclass;
922 g_return_if_fail(pad != NULL);
923 g_return_if_fail(GST_IS_PAD(pad));
924 g_return_if_fail(buf != NULL);
926 ladspa = (GstLADSPA *)gst_pad_get_parent (pad);
927 g_return_if_fail(ladspa != NULL);
929 /* this might happen if caps nego hasn't happened */
930 g_return_if_fail(ladspa->handle != NULL);
932 oclass = (GstLADSPAClass *) (G_OBJECT_GET_CLASS (ladspa));
934 if (GST_IS_EVENT (buf)) {
935 /* push the event out all the src pads */
936 for (i=0 ; i<oclass->numsrcpads ; i++){
937 gst_pad_push (ladspa->srcpads[0], buf);
942 data_in = (LADSPA_Data *) GST_BUFFER_DATA(buf);
943 num_samples = GST_BUFFER_SIZE(buf) / sizeof(gfloat);
944 numsrcpads = oclass->numsrcpads;
946 desc = ladspa->descriptor;
949 guint num_created_buffers = 0;
950 buffers_out = g_new(GstBuffer*, numsrcpads);
951 data_out = g_new(LADSPA_Data*, numsrcpads);
953 if (ladspa->inplace_broken){
954 num_created_buffers = numsrcpads;
957 /* we can share the buffer for input and output */
958 buffers_out[0] = buf;
959 data_out[0] = (LADSPA_Data *)GST_BUFFER_DATA(buf);
960 num_created_buffers = numsrcpads - 1;
963 if (num_created_buffers > 0){
964 ladspa->bufpool = gst_buffer_pool_get_default (sizeof (LADSPA_Data) * GST_BUFFER_SIZE(buf), ladspa->numbuffers);
966 for (i = numsrcpads - num_created_buffers ; i<numsrcpads ; i++){
967 buffers_out[i] = gst_buffer_new_from_pool (ladspa->bufpool, 0, 0);
968 GST_BUFFER_TIMESTAMP(buffers_out[i]) = GST_BUFFER_TIMESTAMP(buf);
969 data_out[i] = (LADSPA_Data *) GST_BUFFER_DATA(buffers_out[i]);
974 GST_DPMAN_PREPROCESS(ladspa->dpman, num_samples, GST_BUFFER_TIMESTAMP(buf));
977 /* split up processing of the buffer into chunks so that dparams can
978 * be updated when required.
979 * In many cases the buffer will be processed in one chunk anyway.
981 while(GST_DPMAN_PROCESS(ladspa->dpman, num_processed)) {
982 num_to_process = GST_DPMAN_FRAMES_TO_PROCESS(ladspa->dpman);
984 desc->connect_port(ladspa->handle,oclass->sinkpad_portnums[0],data_in);
985 for (i=0 ; i<numsrcpads ; i++){
986 desc->connect_port(ladspa->handle,oclass->srcpad_portnums[i],data_out[i]);
988 desc->run(ladspa->handle, num_to_process);
990 data_in += num_to_process;
991 for (i=0 ; i<numsrcpads ; i++){
992 data_out[i] += num_to_process;
994 num_processed += num_to_process;
998 for (i=0 ; i<numsrcpads ; i++){
999 gst_pad_push (ladspa->srcpads[i], buffers_out[i]);
1001 g_free(buffers_out);
1006 /* if we have reached here, there are no src pads */
1007 gst_buffer_unref(buf);
1011 gst_ladspa_get(GstPad *pad)
1014 GstLADSPAClass *oclass;
1018 LADSPA_Descriptor *desc;
1020 guint num_to_process, num_processed;
1022 g_return_val_if_fail(pad != NULL, NULL);
1023 g_return_val_if_fail(GST_IS_PAD(pad), NULL);
1025 ladspa = (GstLADSPA *)gst_pad_get_parent (pad);
1026 g_return_val_if_fail(ladspa != NULL, NULL);
1028 /* this might happen if caps nego hasn't happened */
1029 g_return_val_if_fail(ladspa->handle != NULL, NULL);
1031 oclass = (GstLADSPAClass*)(G_OBJECT_GET_CLASS(ladspa));
1033 /* force src pad to set caps */
1034 if (ladspa->newcaps) {
1035 gst_ladspa_force_src_caps(ladspa, ladspa->srcpads[0]);
1038 /* get a bufferpool */
1039 if (ladspa->bufpool == NULL) {
1040 ladspa->bufpool = gst_pad_get_bufferpool (ladspa->srcpads[0]);
1041 if (ladspa->bufpool == NULL) {
1042 ladspa->bufpool = gst_buffer_pool_get_default (sizeof (LADSPA_Data) * ladspa->buffersize, ladspa->numbuffers);
1046 buf = gst_buffer_new_from_pool (ladspa->bufpool, 0, 0);
1047 GST_BUFFER_TIMESTAMP(buf) = ladspa->timestamp;
1048 data = (LADSPA_Data *) GST_BUFFER_DATA(buf);
1050 desc = ladspa->descriptor;
1051 GST_DPMAN_PREPROCESS(ladspa->dpman, ladspa->buffersize, ladspa->timestamp);
1054 /* split up processing of the buffer into chunks so that dparams can
1055 * be updated when required.
1056 * In many cases the buffer will be processed in one chunk anyway.
1058 while(GST_DPMAN_PROCESS(ladspa->dpman, num_processed)) {
1059 num_to_process = GST_DPMAN_FRAMES_TO_PROCESS(ladspa->dpman);
1061 /* update timestamp */
1062 ladspa->timestamp += num_to_process * GST_SECOND / ladspa->samplerate;
1064 desc->connect_port(ladspa->handle,oclass->srcpad_portnums[0],data);
1065 desc->run(ladspa->handle, num_to_process);
1067 data += num_to_process;
1068 num_processed = num_to_process;
1075 ladspa_describe_plugin(const char *pcFullFilename,
1076 void *pvPluginHandle,
1077 LADSPA_Descriptor_Function pfDescriptorFunction)
1079 const LADSPA_Descriptor *desc;
1082 GstElementDetails *details;
1083 GTypeInfo typeinfo = {
1084 sizeof(GstLADSPAClass),
1087 (GClassInitFunc)gst_ladspa_class_init,
1092 (GInstanceInitFunc)gst_ladspa_init,
1095 GstElementFactory *factory;
1097 /* walk through all the plugins in this pluginlibrary */
1099 while ((desc = pfDescriptorFunction(i++))) {
1102 /* construct the type */
1103 type_name = g_strdup_printf("ladspa_%s",desc->Label);
1104 g_strcanon (type_name, G_CSET_A_2_Z G_CSET_a_2_z G_CSET_DIGITS "-_+", '-');
1105 /* if it's already registered, drop it */
1106 if (g_type_from_name(type_name)) {
1110 /* create the type now */
1111 type = g_type_register_static(GST_TYPE_ELEMENT, type_name, &typeinfo, 0);
1113 /* construct the element details struct */
1114 details = g_new0(GstElementDetails,1);
1115 details->longname = g_strdup(desc->Name);
1116 details->klass = "Filter/Audio/LADSPA";
1117 details->description = details->longname;
1118 details->version = g_strdup_printf("%ld",desc->UniqueID);
1119 details->author = g_strdup(desc->Maker);
1120 details->copyright = g_strdup(desc->Copyright);
1122 /* register the plugin with gstreamer */
1123 factory = gst_element_factory_new(type_name,type,details);
1124 g_return_if_fail(factory != NULL);
1125 gst_plugin_add_feature (ladspa_plugin, GST_PLUGIN_FEATURE (factory));
1127 /* add this plugin to the hash */
1128 g_hash_table_insert(ladspa_descriptors,
1129 GINT_TO_POINTER(type),
1133 /* only add sink padtemplate if there are sinkpads */
1134 for (j=0;j<desc->PortCount;j++) {
1135 if (LADSPA_IS_PORT_AUDIO(desc->PortDescriptors[j]) &&
1136 LADSPA_IS_PORT_INPUT(desc->PortDescriptors[j])) {
1137 sinktempl = ladspa_sink_factory();
1138 gst_element_factory_add_pad_template (factory, sinktempl);
1143 /* only add src padtemplate if there are srcpads */
1144 for (j=0;j<desc->PortCount;j++) {
1145 if (LADSPA_IS_PORT_AUDIO(desc->PortDescriptors[j]) &&
1146 LADSPA_IS_PORT_OUTPUT(desc->PortDescriptors[j])) {
1147 srctempl = ladspa_src_factory();
1148 gst_element_factory_add_pad_template (factory, srctempl);
1157 plugin_init (GModule *module, GstPlugin *plugin)
1159 ladspa_descriptors = g_hash_table_new(NULL,NULL);
1160 parent_class = g_type_class_ref(GST_TYPE_ELEMENT);
1162 ladspa_plugin = plugin;
1164 LADSPAPluginSearch(ladspa_describe_plugin);
1166 if (! gst_library_load ("gstbytestream"))
1169 /* initialize dparam support library */
1170 gst_control_init(NULL,NULL);
1175 GstPluginDesc plugin_desc = {