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 /* nonzero default needed to instantiate() some plugins */
433 ladspa->samplerate = 44100;
435 ladspa->buffersize = 64;
436 ladspa->numbuffers = 16;
437 ladspa->activated = FALSE;
438 ladspa->bufpool = NULL;
439 ladspa->inplace_broken = LADSPA_IS_INPLACE_BROKEN(ladspa->descriptor->Properties);
441 if (sinkcount==0 && srccount == 1) {
442 /* get mode (no sink pads) */
443 GST_DEBUG (0, "mono get mode with 1 src pad");
445 ladspa->newcaps = TRUE;
447 gst_pad_set_connect_function (ladspa->srcpads[0], gst_ladspa_connect_get);
448 gst_pad_set_get_function (ladspa->srcpads[0], gst_ladspa_get);
449 } else if (sinkcount==1){
450 /* with one sink we can use the chain function */
451 GST_DEBUG (0, "chain mode");
453 gst_pad_set_connect_function (ladspa->sinkpads[0], gst_ladspa_connect);
454 gst_pad_set_chain_function (ladspa->sinkpads[0], gst_ladspa_chain);
455 gst_pad_set_bufferpool_function (ladspa->sinkpads[0], gst_ladspa_get_bufferpool);
456 } else if (sinkcount > 1){
457 /* more than one sink pad needs loop mode */
458 GST_DEBUG (0, "loop mode with %d sink pads and %d src pads", sinkcount, srccount);
460 for (i=0;i<sinkcount;i++) {
461 gst_pad_set_connect_function (ladspa->sinkpads[i], gst_ladspa_connect);
462 gst_pad_set_bufferpool_function (ladspa->sinkpads[i], gst_ladspa_get_bufferpool);
464 gst_element_set_loop_function (GST_ELEMENT (ladspa), gst_ladspa_loop);
466 else if (sinkcount==0 && srccount == 0){
467 /* for some reason these plugins exist - we'll just ignore them */
469 g_warning("%d sink pads, %d src pads not yet supported", sinkcount, srccount);
472 gst_ladspa_instantiate (ladspa);
476 gst_ladspa_update_int(const GValue *value, gpointer data)
478 gfloat *target = (gfloat*) data;
479 *target = (gfloat)g_value_get_int(value);
482 static GstPadConnectReturn
483 gst_ladspa_connect (GstPad *pad, GstCaps *caps)
485 GstLADSPA *ladspa = (GstLADSPA *) GST_PAD_PARENT (pad);
486 GstLADSPAClass *oclass = (GstLADSPAClass *) (G_OBJECT_GET_CLASS (ladspa));
490 g_return_val_if_fail (caps != NULL, GST_PAD_CONNECT_DELAYED);
491 g_return_val_if_fail (pad != NULL, GST_PAD_CONNECT_DELAYED);
493 if (gst_caps_get_int (caps, "rate", &rate)){
494 /* have to instantiate ladspa plugin when samplerate changes (groan) */
495 if (ladspa->samplerate != rate){
496 ladspa->samplerate = rate;
498 if (! gst_ladspa_instantiate(ladspa))
499 return GST_PAD_CONNECT_REFUSED;
503 /* if the caps are fixed, we are going to try to set all srcpads using this
504 one caps object. if any of the pads barfs, we'll refuse the connection. i'm
505 not sure if this is correct. */
506 if (GST_CAPS_IS_FIXED (caps)) {
507 for (i=0;i<oclass->numsrcpads;i++) {
508 if (gst_pad_try_set_caps (ladspa->srcpads[i], caps) <= 0)
509 return GST_PAD_CONNECT_REFUSED;
513 return GST_PAD_CONNECT_OK;
516 static GstPadConnectReturn
517 gst_ladspa_connect_get (GstPad *pad, GstCaps *caps)
519 GstLADSPA *ladspa = (GstLADSPA*)GST_OBJECT_PARENT (pad);
522 g_return_val_if_fail (caps != NULL, GST_PAD_CONNECT_DELAYED);
523 g_return_val_if_fail (pad != NULL, GST_PAD_CONNECT_DELAYED);
525 if (gst_caps_get_int (caps, "rate", &rate)){
526 if (ladspa->samplerate != rate) {
527 ladspa->samplerate = rate;
528 if (! gst_ladspa_instantiate(ladspa))
529 return GST_PAD_CONNECT_REFUSED;
533 return GST_PAD_CONNECT_OK;
537 gst_ladspa_force_src_caps(GstLADSPA *ladspa, GstPad *pad)
539 GST_DEBUG (0, "forcing caps with rate %d", ladspa->samplerate);
540 gst_pad_try_set_caps (pad, gst_caps_new (
544 "format", GST_PROPS_STRING ("float"),
545 "layout", GST_PROPS_STRING ("gfloat"),
546 "intercept", GST_PROPS_FLOAT(0.0),
547 "slope", GST_PROPS_FLOAT(1.0),
548 "rate", GST_PROPS_INT (ladspa->samplerate),
549 "channels", GST_PROPS_INT (1),
553 ladspa->newcaps=FALSE;
557 gst_ladspa_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec)
559 GstLADSPA *ladspa = (GstLADSPA*)object;
560 gint cid = prop_id - ARG_LAST;
561 GstLADSPAClass *oclass;
562 ladspa_control_info *control_info;
565 /* these are only registered in get mode */
568 ladspa->samplerate = g_value_get_int (value);
569 ladspa->newcaps=TRUE;
570 gst_ladspa_instantiate (ladspa);
573 ladspa->buffersize = g_value_get_int (value);
577 /* is it a ladspa plugin arg? */
580 oclass = (GstLADSPAClass*)(G_OBJECT_GET_CLASS (object));
582 /* verify it exists and is a control (not a port) */
583 g_return_if_fail(cid < oclass->numcontrols);
585 control_info = &(oclass->control_info[cid]);
586 g_return_if_fail (control_info->name != NULL);
588 /* check to see if it's writable */
589 g_return_if_fail (control_info->writable);
591 /* now see what type it is */
592 if (control_info->toggled) {
593 if (g_value_get_boolean (value))
594 ladspa->controls[cid] = 1.0;
596 ladspa->controls[cid] = 0.0;
597 } else if (control_info->integer) {
598 val = (gfloat)g_value_get_int (value);
599 ladspa->controls[cid] = val;
601 val = g_value_get_float (value);
602 ladspa->controls[cid] = val;
605 GST_DEBUG (0, "set arg %s to %f", control_info->name, ladspa->controls[cid]);
609 gst_ladspa_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec)
611 GstLADSPA *ladspa = (GstLADSPA*)object;
612 gint cid = prop_id - ARG_LAST;
613 GstLADSPAClass *oclass = (GstLADSPAClass*)(G_OBJECT_GET_CLASS (object));
614 ladspa_control_info *control_info;
616 /* these are only registered in get mode */
619 g_value_set_int (value, ladspa->samplerate);
622 g_value_set_int (value, ladspa->buffersize);
628 /* verify it exists and is a control (not a port) */
629 if (cid >= oclass->numcontrols) return;
630 control_info = &(oclass->control_info[cid]);
631 if (control_info->name == NULL) return;
633 GST_DEBUG (0, "got arg %s as %f", control_info->name, ladspa->controls[cid]);
635 /* now see what type it is */
636 if (control_info->toggled) {
637 if (ladspa->controls[cid] == 1.0)
638 g_value_set_boolean (value, TRUE);
640 g_value_set_boolean (value, FALSE);
641 } else if (control_info->integer) {
642 g_value_set_int (value, (gint)ladspa->controls[cid]);
644 g_value_set_float (value, ladspa->controls[cid]);
649 gst_ladspa_instantiate (GstLADSPA *ladspa)
651 LADSPA_Descriptor *desc;
653 GstLADSPAClass *oclass = (GstLADSPAClass*)(G_OBJECT_GET_CLASS (ladspa));
654 gboolean was_activated;
656 desc = ladspa->descriptor;
658 /* check for old handle */
659 was_activated = ladspa->activated;
660 if (ladspa->handle != NULL){
661 gst_ladspa_deactivate(ladspa);
662 desc->cleanup(ladspa->handle);
665 /* instantiate the plugin */
666 GST_DEBUG (0, "instantiating the plugin");
668 ladspa->handle = desc->instantiate(desc,ladspa->samplerate);
669 g_return_val_if_fail (ladspa->handle != NULL, FALSE);
671 /* walk through the ports and add all the arguments */
672 for (i=0;i<oclass->numcontrols;i++) {
673 /* connect the argument to the plugin */
674 GST_DEBUG (0, "added control port %d", oclass->control_portnums[i]);
675 desc->connect_port(ladspa->handle,
676 oclass->control_portnums[i],
677 &(ladspa->controls[i]));
680 /* reactivate if it was activated before the reinstantiation */
682 gst_ladspa_activate(ladspa);
687 static GstElementStateReturn
688 gst_ladspa_change_state (GstElement *element)
690 LADSPA_Descriptor *desc;
691 GstLADSPA *ladspa = (GstLADSPA*)element;
692 desc = ladspa->descriptor;
694 GST_DEBUG (0, "changing state");
695 switch (GST_STATE_TRANSITION (element)) {
696 case GST_STATE_NULL_TO_READY:
697 gst_ladspa_activate(ladspa);
699 case GST_STATE_READY_TO_NULL:
700 gst_ladspa_deactivate(ladspa);
706 if (GST_ELEMENT_CLASS (parent_class)->change_state)
707 return GST_ELEMENT_CLASS (parent_class)->change_state (element);
709 return GST_STATE_SUCCESS;
713 gst_ladspa_activate(GstLADSPA *ladspa)
715 LADSPA_Descriptor *desc;
716 desc = ladspa->descriptor;
718 if (ladspa->activated){
719 gst_ladspa_deactivate(ladspa);
722 GST_DEBUG (0, "activating");
724 /* activate the plugin (function might be null) */
725 if (desc->activate != NULL) {
726 desc->activate(ladspa->handle);
729 ladspa->activated = TRUE;
733 gst_ladspa_deactivate(GstLADSPA *ladspa)
735 LADSPA_Descriptor *desc;
736 desc = ladspa->descriptor;
738 GST_DEBUG (0, "deactivating");
740 /* deactivate the plugin (function might be null) */
741 if (ladspa->activated && (desc->deactivate != NULL)) {
742 desc->deactivate(ladspa->handle);
745 ladspa->activated = FALSE;
749 gst_ladspa_loop(GstElement *element)
751 guint bufferbytesize, i, numsrcpads, numsinkpads, num_empty_pads;
752 guint num_processed, num_to_process;
753 GstEvent *event = NULL;
756 LADSPA_Data **data_in, **data_out;
757 GstBuffer **buffers_in, **buffers_out;
758 GstBufferPool *bufpool;
759 GstByteStream **bytestreams;
761 GstLADSPA *ladspa = (GstLADSPA *)element;
762 GstLADSPAClass *oclass = (GstLADSPAClass*)(G_OBJECT_GET_CLASS (ladspa));
763 LADSPA_Descriptor *desc = ladspa->descriptor;
765 numsinkpads = oclass->numsinkpads;
766 numsrcpads = oclass->numsrcpads;
768 data_in = g_new0(LADSPA_Data*, numsinkpads);
769 data_out = g_new0(LADSPA_Data*, numsrcpads);
770 buffers_in = g_new0(GstBuffer*, numsinkpads);
771 buffers_out = g_new0(GstBuffer*, numsrcpads);
772 bytestreams = g_new0(GstByteStream*, numsinkpads);
774 /* find a bufferpool */
775 if (numsrcpads > 0 && (bufpool = gst_pad_get_bufferpool (ladspa->srcpads[0]))) {
776 GST_DEBUG (0, "Got bufferpool from first source pad");
778 bufferbytesize = sizeof (LADSPA_Data) * ladspa->buffersize;
779 bufpool = gst_buffer_pool_get_default (bufferbytesize, ladspa->numbuffers);
780 GST_DEBUG (0, "Created default bufferpool, %d x %d bytes", ladspa->numbuffers, bufferbytesize);
783 /* get the bytestreams for each pad */
784 for (i=0 ; i<numsinkpads ; i++){
785 bytestreams[i] = gst_bytestream_new (ladspa->sinkpads[i]);
788 /* since this is a loop element, we just loop here til things fall apart. */
790 /* we need to get the buffers_out first so we can know how many bytes to process */
791 for (i=0 ; i<numsrcpads ; i++){
792 buffers_out[i] = gst_buffer_new_from_pool (bufpool, 0, 0);
793 GST_BUFFER_TIMESTAMP(buffers_out[i]) = ladspa->timestamp;
794 data_out[i] = (LADSPA_Data *) GST_BUFFER_DATA(buffers_out[i]);
797 bufferbytesize = GST_BUFFER_SIZE (buffers_out[0]);
798 ladspa->buffersize = bufferbytesize / sizeof (LADSPA_Data);
801 /* first get all the necessary data from the input ports */
802 for (i=0 ; i<numsinkpads ; i++){
803 GST_DEBUG (0, "pulling %u bytes through channel %d's bytestream", bufferbytesize, i);
804 got_bytes = gst_bytestream_read (bytestreams[i], buffers_in + i, bufferbytesize);
806 if (got_bytes != bufferbytesize) {
807 /* we need to check for an event. */
808 gst_bytestream_get_status (bytestreams[i], &waiting, &event);
810 if (event && GST_EVENT_TYPE(event) == GST_EVENT_EOS) {
811 /* if we get an EOS event from one of our sink pads, we assume that
812 pad's finished handling data. delete the bytestream, free up the
813 pad, and free up the memory associated with the input channel. */
814 GST_DEBUG (0, "got an EOS event on sinkpad %d", i);
816 /* CHECKME should maybe check for other events and try to pull more data here */
819 data_in[i] = (LADSPA_Data *) GST_BUFFER_DATA(buffers_in[i]);
820 GST_BUFFER_TIMESTAMP(buffers_in[i]) = ladspa->timestamp;
824 if (num_empty_pads > 0){
825 if (num_empty_pads < numsinkpads){
826 /* only some pads have EOS, need to create some empty buffers */
827 for (i=0 ; i<numsinkpads ; i++){
828 if (buffers_in[i] == NULL){
831 buffers_in[i] = gst_buffer_new_from_pool (ladspa->bufpool, 0, 0);
832 GST_BUFFER_TIMESTAMP(buffers_in[i]) = ladspa->timestamp;
833 data_in[i] = data = (LADSPA_Data *) GST_BUFFER_DATA(buffers_in[i]);
834 for (x=0 ; x < ladspa->buffersize ; x++)
837 data_in[i] = (LADSPA_Data *) GST_BUFFER_DATA(buffers_in[i]);
838 GST_BUFFER_TIMESTAMP(buffers_in[i]) = ladspa->timestamp;
843 /* all pads have EOS, time to quit */
844 /* CHECKME do I have to push EOS events here? */
845 GST_DEBUG (0, "All sink pads have EOS, finishing.");
850 GST_DPMAN_PREPROCESS(ladspa->dpman, ladspa->buffersize, ladspa->timestamp);
853 /* split up processing of the buffer into chunks so that dparams can
854 * be updated when required.
855 * In many cases the buffer will be processed in one chunk anyway.
857 while(GST_DPMAN_PROCESS(ladspa->dpman, num_processed)) {
859 num_to_process = GST_DPMAN_FRAMES_TO_PROCESS(ladspa->dpman);
860 for (i=0 ; i<numsinkpads ; i++){
861 desc->connect_port (ladspa->handle, oclass->sinkpad_portnums[i], data_in[i]);
863 for (i=0 ; i<numsrcpads ; i++){
864 desc->connect_port (ladspa->handle, oclass->srcpad_portnums[i], data_out[i]);
866 desc->run(ladspa->handle, num_to_process);
867 for (i=0 ; i<numsinkpads ; i++){
868 data_in[i] += num_to_process;
870 for (i=0 ; i<numsrcpads ; i++){
871 data_out[i] += num_to_process;
874 num_processed += num_to_process;
877 for (i=0 ; i<numsrcpads ; i++) {
878 GST_DEBUG (0, "pushing buffer (%p) on src pad %d", buffers_out[i], i);
879 gst_pad_push (ladspa->srcpads[i], buffers_out[i]);
882 buffers_out[i] = NULL;
884 for (i=0 ; i<numsinkpads ; i++) {
885 gst_buffer_unref(buffers_in[i]);
887 buffers_in[i] = NULL;
890 ladspa->timestamp += ladspa->buffersize * 10^9 / ladspa->samplerate;
892 gst_element_yield (element);
895 gst_buffer_pool_unref(bufpool);
897 for (i=0 ; i<numsinkpads ; i++){
898 gst_bytestream_destroy (bytestreams[i]);
901 g_free (buffers_out);
905 g_free (bytestreams);
909 gst_ladspa_chain (GstPad *pad, GstBuffer *buf)
911 LADSPA_Descriptor *desc;
912 LADSPA_Data *data_in, **data_out = NULL;
913 GstBuffer **buffers_out = NULL;
915 unsigned long num_samples;
916 guint num_to_process, num_processed, i, numsrcpads;
919 GstLADSPAClass *oclass;
921 g_return_if_fail(pad != NULL);
922 g_return_if_fail(GST_IS_PAD(pad));
923 g_return_if_fail(buf != NULL);
925 ladspa = (GstLADSPA *)gst_pad_get_parent (pad);
926 g_return_if_fail(ladspa != NULL);
928 /* this might happen if caps nego hasn't happened */
929 g_return_if_fail(ladspa->handle != NULL);
931 oclass = (GstLADSPAClass *) (G_OBJECT_GET_CLASS (ladspa));
933 if (GST_IS_EVENT (buf)) {
934 /* push the event out all the src pads */
935 for (i=0 ; i<oclass->numsrcpads ; i++){
936 gst_pad_push (ladspa->srcpads[0], buf);
941 data_in = (LADSPA_Data *) GST_BUFFER_DATA(buf);
942 num_samples = GST_BUFFER_SIZE(buf) / sizeof(gfloat);
943 numsrcpads = oclass->numsrcpads;
945 desc = ladspa->descriptor;
948 guint num_created_buffers = 0;
949 buffers_out = g_new(GstBuffer*, numsrcpads);
950 data_out = g_new(LADSPA_Data*, numsrcpads);
952 if (ladspa->inplace_broken){
953 num_created_buffers = numsrcpads;
956 /* we can share the buffer for input and output */
957 buffers_out[0] = buf;
958 data_out[0] = (LADSPA_Data *)GST_BUFFER_DATA(buf);
959 num_created_buffers = numsrcpads - 1;
962 if (num_created_buffers > 0){
963 ladspa->bufpool = gst_buffer_pool_get_default (sizeof (LADSPA_Data) * GST_BUFFER_SIZE(buf), ladspa->numbuffers);
965 for (i = numsrcpads - num_created_buffers ; i<numsrcpads ; i++){
966 buffers_out[i] = gst_buffer_new_from_pool (ladspa->bufpool, 0, 0);
967 GST_BUFFER_TIMESTAMP(buffers_out[i]) = GST_BUFFER_TIMESTAMP(buf);
968 data_out[i] = (LADSPA_Data *) GST_BUFFER_DATA(buffers_out[i]);
973 GST_DPMAN_PREPROCESS(ladspa->dpman, num_samples, GST_BUFFER_TIMESTAMP(buf));
976 /* split up processing of the buffer into chunks so that dparams can
977 * be updated when required.
978 * In many cases the buffer will be processed in one chunk anyway.
980 while(GST_DPMAN_PROCESS(ladspa->dpman, num_processed)) {
981 num_to_process = GST_DPMAN_FRAMES_TO_PROCESS(ladspa->dpman);
983 desc->connect_port(ladspa->handle,oclass->sinkpad_portnums[0],data_in);
984 for (i=0 ; i<numsrcpads ; i++){
985 desc->connect_port(ladspa->handle,oclass->srcpad_portnums[i],data_out[i]);
987 desc->run(ladspa->handle, num_to_process);
989 data_in += num_to_process;
990 for (i=0 ; i<numsrcpads ; i++){
991 data_out[i] += num_to_process;
993 num_processed += num_to_process;
997 for (i=0 ; i<numsrcpads ; i++){
998 gst_pad_push (ladspa->srcpads[i], buffers_out[i]);
1000 g_free(buffers_out);
1005 /* if we have reached here, there are no src pads */
1006 gst_buffer_unref(buf);
1010 gst_ladspa_get(GstPad *pad)
1013 GstLADSPAClass *oclass;
1017 LADSPA_Descriptor *desc;
1019 guint num_to_process, num_processed;
1021 g_return_val_if_fail(pad != NULL, NULL);
1022 g_return_val_if_fail(GST_IS_PAD(pad), NULL);
1024 ladspa = (GstLADSPA *)gst_pad_get_parent (pad);
1025 g_return_val_if_fail(ladspa != NULL, NULL);
1027 /* this might happen if caps nego hasn't happened */
1028 g_return_val_if_fail(ladspa->handle != NULL, NULL);
1030 oclass = (GstLADSPAClass*)(G_OBJECT_GET_CLASS(ladspa));
1032 /* force src pad to set caps */
1033 if (ladspa->newcaps) {
1034 gst_ladspa_force_src_caps(ladspa, ladspa->srcpads[0]);
1037 /* get a bufferpool */
1038 if (ladspa->bufpool == NULL) {
1039 ladspa->bufpool = gst_pad_get_bufferpool (ladspa->srcpads[0]);
1040 if (ladspa->bufpool == NULL) {
1041 ladspa->bufpool = gst_buffer_pool_get_default (sizeof (LADSPA_Data) * ladspa->buffersize, ladspa->numbuffers);
1045 buf = gst_buffer_new_from_pool (ladspa->bufpool, 0, 0);
1046 GST_BUFFER_TIMESTAMP(buf) = ladspa->timestamp;
1047 data = (LADSPA_Data *) GST_BUFFER_DATA(buf);
1049 desc = ladspa->descriptor;
1050 GST_DPMAN_PREPROCESS(ladspa->dpman, GST_BUFFER_SIZE (buf) / sizeof (gfloat), ladspa->timestamp);
1053 /* split up processing of the buffer into chunks so that dparams can
1054 * be updated when required.
1055 * In many cases the buffer will be processed in one chunk anyway.
1057 while(GST_DPMAN_PROCESS(ladspa->dpman, num_processed)) {
1058 num_to_process = GST_DPMAN_FRAMES_TO_PROCESS(ladspa->dpman);
1060 /* update timestamp */
1061 ladspa->timestamp += num_to_process * GST_SECOND / ladspa->samplerate;
1063 desc->connect_port(ladspa->handle,oclass->srcpad_portnums[0],data);
1064 desc->run(ladspa->handle, num_to_process);
1066 data += num_to_process;
1067 num_processed = num_to_process;
1074 ladspa_describe_plugin(const char *pcFullFilename,
1075 void *pvPluginHandle,
1076 LADSPA_Descriptor_Function pfDescriptorFunction)
1078 const LADSPA_Descriptor *desc;
1081 GstElementDetails *details;
1082 GTypeInfo typeinfo = {
1083 sizeof(GstLADSPAClass),
1086 (GClassInitFunc)gst_ladspa_class_init,
1091 (GInstanceInitFunc)gst_ladspa_init,
1094 GstElementFactory *factory;
1096 /* walk through all the plugins in this pluginlibrary */
1098 while ((desc = pfDescriptorFunction(i++))) {
1101 /* construct the type */
1102 type_name = g_strdup_printf("ladspa_%s",desc->Label);
1103 g_strcanon (type_name, G_CSET_A_2_Z G_CSET_a_2_z G_CSET_DIGITS "-_+", '-');
1104 /* if it's already registered, drop it */
1105 if (g_type_from_name(type_name)) {
1109 /* create the type now */
1110 type = g_type_register_static(GST_TYPE_ELEMENT, type_name, &typeinfo, 0);
1112 /* construct the element details struct */
1113 details = g_new0(GstElementDetails,1);
1114 details->longname = g_strdup(desc->Name);
1115 details->klass = "Filter/Audio/LADSPA";
1116 details->license = "LGPL";
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 = {