filter newlines out of GST_DEBUG statements to reflect new core behavior fixes to...
[platform/upstream/gstreamer.git] / ext / ladspa / gstladspa.c
1 /* GStreamer
2  * Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
3  *               <2001> Steve Baker <stevebaker_org@yahoo.co.uk>
4  *
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.
9  *
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.
14  *
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.
19  */
20
21 #include <string.h>
22 #include <math.h>
23
24 #include "gstladspa.h"
25 #include "ladspa.h"     /* main ladspa sdk include file */
26 #include "utils.h"      /* ladspa sdk utility functions */
27
28
29 static GstPadTemplate* 
30 ladspa_src_factory (void)
31 {
32   return 
33     gst_padtemplate_new (
34     "src",
35     GST_PAD_SRC,
36     GST_PAD_ALWAYS,
37     gst_caps_new (
38     "ladspa_src",
39       "audio/raw",
40       gst_props_new (
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),
47       NULL)),
48     NULL);
49 }
50
51 static GstPadTemplate* 
52 ladspa_sink_factory (void) 
53 {
54   return 
55     gst_padtemplate_new (
56       "sink",
57       GST_PAD_SINK,
58       GST_PAD_ALWAYS,
59       gst_caps_new (
60       "float2int_sink",
61         "audio/raw",
62         gst_props_new (
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),
69       NULL)),
70     NULL);
71 }
72
73 enum {
74   ARG_0,
75   ARG_LOOP_BASED,
76   ARG_SAMPLERATE,
77   ARG_BUFFERSIZE,
78   ARG_LAST,
79 };
80
81 static void                     gst_ladspa_class_init           (GstLADSPAClass *klass);
82 static void                     gst_ladspa_init                 (GstLADSPA *ladspa);
83
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);
87
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);
90
91 static gboolean                 gst_ladspa_instantiate          (GstLADSPA *ladspa);
92 static void                     gst_ladspa_activate             (GstLADSPA *ladspa);
93 static void                     gst_ladspa_deactivate           (GstLADSPA *ladspa);
94
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);
99
100 static GstElementClass *parent_class = NULL;
101 static GstPadTemplate *srctempl, *sinktempl;
102 /* static guint gst_ladspa_signals[LAST_SIGNAL] = { 0 }; */
103
104 static GstPlugin *ladspa_plugin;
105 static GHashTable *ladspa_descriptors;
106
107 static GstBufferPool*
108 gst_ladspa_get_bufferpool (GstPad *pad)
109 {
110   gint i;
111   GstBufferPool *bp;
112   GstLADSPA *ladspa = gst_pad_get_parent (pad);
113   GstLADSPAClass *oclass = (GstLADSPAClass *) (G_OBJECT_GET_CLASS (ladspa));
114
115   if (oclass->numsrcpads > 0)
116     for (i=0;i<oclass->numsrcpads;i++)
117       if ((bp = gst_pad_get_bufferpool(ladspa->srcpads[0])) != NULL)
118         return bp;
119
120   return NULL;
121 }
122
123 static void
124 gst_ladspa_class_init (GstLADSPAClass *klass)
125 {
126   GObjectClass *gobject_class;
127   GstElementClass *gstelement_class;
128   LADSPA_Descriptor *desc;
129   gint i,current_portnum,sinkcount,srccount,controlcount;
130   gint hintdesc;
131   gint argtype,argperms;
132   GParamSpec *paramspec = NULL;
133   gchar *argname, *tempstr, *paren;
134
135   gobject_class = (GObjectClass*)klass;
136   gstelement_class = (GstElementClass*)klass;
137
138   gobject_class->set_property = gst_ladspa_set_property;
139   gobject_class->get_property = gst_ladspa_get_property;
140
141   gstelement_class->change_state = gst_ladspa_change_state;
142
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));
146
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;
150
151   klass->numports = desc->PortCount;
152
153   klass->numsinkpads = 0;
154   klass->numsrcpads = 0;
155   klass->numcontrols = 0;
156
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++;
162     }
163       
164     if (LADSPA_IS_PORT_AUDIO(desc->PortDescriptors[i]) && 
165         LADSPA_IS_PORT_OUTPUT(desc->PortDescriptors[i])){
166       klass->numsrcpads++;
167     }
168       
169     if (LADSPA_IS_PORT_CONTROL(desc->PortDescriptors[i]) && 
170         LADSPA_IS_PORT_INPUT(desc->PortDescriptors[i])){
171       klass->numcontrols++;
172     }
173   }
174
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);
178   sinkcount = 0;
179   srccount = 0;
180   controlcount = 0;
181
182   /* walk through the ports, note the portnums for srcpads, sinkpads and control
183      params */
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;
189     }
190       
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;
195     }
196       
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;
201     }
202   }
203
204   /* no sink pads - we'll use get mode and add params for samplerate and
205      buffersize */
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));
213
214   }
215   
216   /* now build the contorl info from the control ports */
217   klass->control_info = g_new0(ladspa_control_info,klass->numcontrols);
218     
219   for (i=0;i<klass->numcontrols;i++) {
220     current_portnum = klass->control_portnums[i];
221     
222     /* short name for hint descriptor */
223     hintdesc = desc->PortRangeHints[current_portnum].HintDescriptor;
224
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;
232
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;
237
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;
243     } else {
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;
246     }
247     
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;
254     } else {
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;
257     }
258
259     if (LADSPA_IS_PORT_INPUT(desc->PortDescriptors[current_portnum])) {
260       argperms = G_PARAM_READWRITE;
261       klass->control_info[i].writable = TRUE;
262     } else {
263       argperms = G_PARAM_READABLE;
264       klass->control_info[i].writable = FALSE;
265     }
266
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
270        of it */
271     paren = g_strrstr (argname, " (");
272     if (paren != NULL) {
273       *paren = '\0';
274     }
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'))) {
279       tempstr = argname;
280       argname = g_strconcat("param-", argname, NULL);
281       g_free (tempstr);
282     }
283     
284     /* check for duplicate property names */
285     if (g_object_class_find_property(G_OBJECT_CLASS(klass), argname) != NULL){
286       gint numarg=1;
287       gchar *numargname = g_strdup_printf("%s_%d",argname,numarg++);
288       while (g_object_class_find_property(G_OBJECT_CLASS(klass), numargname) != NULL){
289         g_free(numargname);
290         numargname = g_strdup_printf("%s_%d",argname,numarg++);
291       }
292       argname = numargname;
293     }
294     
295     g_print("adding arg %s from %s\n",argname, klass->control_info[i].name);
296     
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);
302     } else {
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);
306     }
307     
308     g_object_class_install_property(G_OBJECT_CLASS(klass), i+ARG_LAST, paramspec);
309   }
310 }
311
312 static void
313 gst_ladspa_init (GstLADSPA *ladspa)
314 {
315   GstLADSPAClass *oclass = (GstLADSPAClass*)(G_OBJECT_GET_CLASS(ladspa));
316   
317   LADSPA_Descriptor *desc;
318   gint i,sinkcount,srccount,controlcount;
319
320   desc = oclass->descriptor;
321   ladspa->descriptor = oclass->descriptor;
322   
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);
328
329   /* walk through the ports and add all the pads */
330   sinkcount = 0;
331   srccount = 0;
332   controlcount = 0;
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]);
339       sinkcount++;
340     }
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]);
345       srccount++;
346     }
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;
352       } else {
353         ladspa->controls[controlcount] = 0.0;
354       }
355       controlcount++;
356     }
357   }
358
359   ladspa->samplerate = 0;
360   ladspa->buffersize = 64;
361   ladspa->numbuffers = 16;
362   ladspa->newcaps = FALSE;
363   ladspa->activated = FALSE;
364   ladspa->bufpool = NULL;
365
366   /* we assume srccount > 0 because there are no LADSPA sink elements. */
367
368   if (sinkcount==0) {
369     /* get mode (no sink pads) */
370     GST_INFO (0, "get mode with %d src pads\n", srccount);
371
372     ladspa->newcaps = TRUE;
373     ladspa->samplerate = 44100;
374     ladspa->buffersize = 64;
375
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);
379     }
380   } else if (sinkcount==1 && srccount==1){
381     /* mono chain */
382     GST_INFO (0, "inplace mono chain mode\n");
383
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);
387   } else {
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);
390
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);
394     }
395
396     ladspa->loopbased = TRUE;
397     gst_element_set_loop_function (ladspa, gst_ladspa_loop);
398   }  
399
400   gst_ladspa_instantiate(ladspa);
401 }
402
403 static GstPadConnectReturn
404 gst_ladspa_connect (GstPad *pad, GstCaps *caps)
405 {
406   GstLADSPA *ladspa = (GstLADSPA *) GST_PAD_PARENT (pad);
407   GstLADSPAClass *oclass = (GstLADSPAClass *) (G_OBJECT_GET_CLASS (ladspa));
408   guint i;
409
410   g_return_val_if_fail (caps != NULL, GST_PAD_CONNECT_DELAYED);
411   g_return_val_if_fail (pad  != NULL, GST_PAD_CONNECT_DELAYED);
412
413   /* have to instantiate ladspa plugin when samplerate changes (groan) */
414   if (ladspa->samplerate != gst_caps_get_int (caps, "rate")){
415     ladspa->samplerate = gst_caps_get_int (caps, "rate");
416     if (! gst_ladspa_instantiate(ladspa))
417       return GST_PAD_CONNECT_REFUSED;
418   }
419
420   /* if the caps are fixed, we are going to try to set all srcpads using this
421      one caps object. if any of the pads barfs, we'll refuse the connection. i'm
422      not sure if this is correct. */
423   if (GST_CAPS_IS_FIXED (caps)) {
424     for (i=0;i<oclass->numsrcpads;i++) {
425       if (! gst_pad_try_set_caps (ladspa->srcpads[i], caps))
426         return GST_PAD_CONNECT_REFUSED;
427     }
428   }
429   
430   return GST_PAD_CONNECT_DELAYED;
431 }
432
433 static GstPadConnectReturn 
434 gst_ladspa_connect_get (GstPad *pad, GstCaps *caps) 
435 {
436   GstLADSPA *ladspa = (GstLADSPA*)GST_OBJECT_PARENT (pad);
437  
438   g_return_val_if_fail (caps != NULL, GST_PAD_CONNECT_DELAYED);
439   g_return_val_if_fail (pad  != NULL, GST_PAD_CONNECT_DELAYED);
440
441   if (ladspa->samplerate != gst_caps_get_int (caps, "rate")) {
442     ladspa->samplerate = gst_caps_get_int (caps, "rate");
443     if (! gst_ladspa_instantiate(ladspa))
444       return GST_PAD_CONNECT_REFUSED;
445   }
446
447   return GST_PAD_CONNECT_DELAYED;
448 }
449
450 static void
451 gst_ladspa_force_src_caps(GstLADSPA *ladspa, GstPad *pad)
452 {
453   GST_DEBUG (0, "forcing caps");
454   gst_pad_try_set_caps (pad, gst_caps_new (
455     "ladspa_src_caps",
456     "audio/raw",
457     gst_props_new (
458       "format",     GST_PROPS_STRING ("float"),
459       "layout",     GST_PROPS_STRING ("gfloat"),
460       "intercept",  GST_PROPS_FLOAT(0.0),
461       "slope",      GST_PROPS_FLOAT(1.0),
462       "rate",       GST_PROPS_INT (ladspa->samplerate),
463       "channels",   GST_PROPS_INT (1),
464       NULL
465     )
466   ));
467   ladspa->newcaps=FALSE;
468 }
469
470 static void
471 gst_ladspa_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec)
472 {
473   GstLADSPA *ladspa = (GstLADSPA*)object;
474   gint cid = prop_id - ARG_LAST;
475   GstLADSPAClass *oclass;
476   ladspa_control_info *control_info;
477   gfloat val=0.0;
478     
479   /* these are only registered in get mode */
480   switch (prop_id) {
481     case ARG_SAMPLERATE:
482       ladspa->samplerate = g_value_get_int (value);
483       ladspa->newcaps=TRUE;
484       break;
485     case ARG_BUFFERSIZE:
486       ladspa->buffersize = g_value_get_int (value);
487       break;
488   }
489   
490   /* is it a ladspa plugin arg? */
491   if (cid < 0) return;
492
493 /*
494   if (id == ARG_LOOP_BASED) {
495     * we can only do this in NULL state *
496     g_return_if_fail (GST_STATE(object) != GST_STATE_NULL);
497     ladspa->loopbased = g_value_get_boolean (value);
498     if (ladspa->loopbased) {
499       gst_element_set_loop_function (GST_ELEMENT (ladspa), gst_ladspa_loop);
500     } else {
501       gst_element_set_loop_function (GST_ELEMENT (ladspa), NULL);
502     }
503   }
504 */
505
506   oclass = (GstLADSPAClass*)(G_OBJECT_GET_CLASS (object));
507
508   /* verify it exists and is a control (not a port) */
509   g_return_if_fail(cid < oclass->numcontrols);
510   
511   control_info = &(oclass->control_info[cid]);
512   g_return_if_fail (control_info->name != NULL);
513
514   /* check to see if it's writable */
515   g_return_if_fail (control_info->writable);
516
517   /* now see what type it is */
518   if (control_info->toggled) {
519     if (g_value_get_boolean (value))
520       ladspa->controls[cid] = 1.0;
521     else
522       ladspa->controls[cid] = 0.0;
523   } else if (control_info->integer) {
524     val = (gfloat)g_value_get_int (value);
525     ladspa->controls[cid] = val;
526   } else {
527     val = g_value_get_float (value);
528     ladspa->controls[cid] = val;
529   }    
530
531   GST_DEBUG (0, "set arg %s to %f", control_info->name, ladspa->controls[cid]);
532 }
533
534 static void
535 gst_ladspa_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec)
536 {
537   GstLADSPA *ladspa = (GstLADSPA*)object;
538   gint cid = prop_id - ARG_LAST;
539   GstLADSPAClass *oclass = (GstLADSPAClass*)(G_OBJECT_GET_CLASS (object));
540   ladspa_control_info *control_info;
541
542   /* these are only registered in get mode */
543   switch (prop_id){
544     case ARG_SAMPLERATE:
545       g_value_set_int (value, ladspa->samplerate);
546       break;
547     case ARG_BUFFERSIZE:
548       g_value_set_int (value, ladspa->buffersize);
549       break;
550   }
551     
552   if (cid < 0) return;
553
554   /* verify it exists and is a control (not a port) */
555   if (cid >= oclass->numcontrols) return;
556   control_info = &(oclass->control_info[cid]);
557   if (control_info->name == NULL) return;
558
559   GST_DEBUG (0, "got arg %s as %f", control_info->name, ladspa->controls[cid]);
560
561   /* now see what type it is */
562   if (control_info->toggled) {
563     if (ladspa->controls[cid] == 1.0)
564       g_value_set_boolean (value, TRUE);
565     else
566       g_value_set_boolean (value, FALSE);
567   } else if (control_info->integer) {
568     g_value_set_int (value, (gint)ladspa->controls[cid]);
569   } else {
570     g_value_set_float (value, ladspa->controls[cid]);
571   }
572 }
573
574 static gboolean
575 gst_ladspa_instantiate (GstLADSPA *ladspa)
576 {
577   LADSPA_Descriptor *desc;
578   int i;
579   GstLADSPAClass *oclass = (GstLADSPAClass*)(G_OBJECT_GET_CLASS (ladspa));
580   gboolean was_activated;
581   
582   desc = ladspa->descriptor;
583   
584   /* check for old handle */
585   was_activated = ladspa->activated;
586   if (ladspa->handle != NULL){
587     gst_ladspa_deactivate(ladspa);
588     desc->cleanup(ladspa->handle);
589   }
590         
591   /* instantiate the plugin */ 
592   GST_DEBUG (0, "instantiating the plugin");
593   
594   ladspa->handle = desc->instantiate(desc,ladspa->samplerate);
595   g_return_val_if_fail (ladspa->handle != NULL, FALSE);
596
597   /* walk through the ports and add all the arguments */
598   for (i=0;i<oclass->numcontrols;i++) {
599     /* connect the argument to the plugin */
600     GST_DEBUG (0, "added control port %d", oclass->control_portnums[i]);
601     desc->connect_port(ladspa->handle,
602                        oclass->control_portnums[i],
603                        &(ladspa->controls[i]));
604   }
605
606   /* reactivate if it was activated before the reinstantiation */
607   if (was_activated){
608     gst_ladspa_activate(ladspa);
609   }
610   return TRUE;
611 }
612
613 static GstElementStateReturn
614 gst_ladspa_change_state (GstElement *element)
615 {
616   LADSPA_Descriptor *desc;
617   GstLADSPA *ladspa = (GstLADSPA*)element;
618   desc = ladspa->descriptor;
619
620   GST_DEBUG (0, "changing state");
621   switch (GST_STATE_TRANSITION (element)) {
622     case GST_STATE_NULL_TO_READY:
623       gst_ladspa_activate(ladspa);
624       break;
625     case GST_STATE_READY_TO_NULL:
626       gst_ladspa_deactivate(ladspa);
627       break;
628     default:
629       break;
630   }
631
632   if (GST_ELEMENT_CLASS (parent_class)->change_state)
633     return GST_ELEMENT_CLASS (parent_class)->change_state (element);
634
635   return GST_STATE_SUCCESS;
636 }
637
638 static void
639 gst_ladspa_activate(GstLADSPA *ladspa)
640 {
641   LADSPA_Descriptor *desc;
642   desc = ladspa->descriptor;
643   
644   if (ladspa->activated){
645     gst_ladspa_deactivate(ladspa);
646   }
647   
648   GST_DEBUG (0, "activating");
649
650   /* activate the plugin (function might be null) */
651   if (desc->activate != NULL) {
652     desc->activate(ladspa->handle);
653   }
654
655   ladspa->activated = TRUE;
656 }
657
658 static void
659 gst_ladspa_deactivate(GstLADSPA *ladspa)
660 {
661   LADSPA_Descriptor *desc;
662   desc = ladspa->descriptor;
663
664   GST_DEBUG (0, "deactivating");
665
666   /* deactivate the plugin (function might be null) */
667   if (ladspa->activated && (desc->deactivate != NULL)) {
668     desc->deactivate(ladspa->handle);
669   }
670
671   ladspa->activated = FALSE;
672 }
673
674 static void
675 gst_ladspa_loop (GstElement *element)
676 {
677   gint8        *raw_in, *zero_out, i, cur_buf;
678   GstBuffer   **buffers_out;
679   GstEvent     *event = NULL;
680   guint32       waiting;
681   LADSPA_Data **data_in, *data_out;
682   unsigned long size;
683
684   GstLADSPA       *ladspa = (GstLADSPA *)element;
685   GstLADSPAClass  *oclass = (GstLADSPAClass*)(G_OBJECT_GET_CLASS (ladspa));
686   LADSPA_Descriptor *desc = ladspa->descriptor;
687
688   data_in = g_new0(LADSPA_Data *, oclass->numsinkpads);
689   buffers_out = g_new0(GstBuffer *, oclass->numsrcpads);
690   
691   /* set up the bufferpool first if necessary */
692   i = 0;
693   while ((ladspa->bufpool == NULL) && (i < oclass->numsrcpads)) {
694     ladspa->bufpool = gst_pad_get_bufferpool (ladspa->srcpads[i++]);
695   }
696   if (ladspa->bufpool == NULL) {
697     ladspa->bufpool = gst_buffer_pool_get_default (sizeof (LADSPA_Data) * ladspa->buffersize,
698                                                    ladspa->numbuffers);
699   }
700
701   /* since this is a loop element, we just loop here til things fall apart. */
702   do {
703
704     /* first get all the necessary data from the input ports */
705     for (i=0;i<oclass->numsinkpads;i++){  
706       GST_DEBUG (0, "pulling %d bytes through channel %d's bytestream", i);
707       raw_in = gst_bytestream_peek_bytes (ladspa->bytestreams[i], ladspa->buffersize * sizeof (LADSPA_Data));
708
709       if (raw_in == NULL) {
710         /* we need to check for an event. */
711         gst_bytestream_get_status (ladspa->bytestreams[i], &waiting, &event);
712
713         if (event) {
714           if (GST_EVENT_TYPE(event) == GST_EVENT_EOS) {
715             /* if we get an EOS event from one of our sink pads, we assume that
716                pad's finished handling data. delete the bytestream, free up the
717                pad, and free up the memory associated with the input channel. */
718             GST_DEBUG (0, "got an EOS event on sinkpad %d", i);
719           }
720
721           /* we need to create some zeroed out data to feed to this port of the
722              ladspa filter. */
723           data_in[i] = g_new0 (LADSPA_Data, ladspa->buffersize * sizeof (LADSPA_Data));
724         } else {
725           /* copy the retrieved data and bind the ladspa src port to the data */
726           data_in[i] = (LADSPA_Data *) raw_in;
727         }
728       }
729
730       raw_in = NULL;
731       desc->connect_port (ladspa->handle, oclass->sinkpad_portnums[i], data_in[i]);
732       gst_bytestream_flush (ladspa->bytestreams[i], ladspa->buffersize * sizeof (LADSPA_Data));
733     }
734
735     /* now set up the output ports */
736     for (i=0;i<oclass->numsrcpads;i++) {
737       buffers_out[i] = (GstBuffer *) gst_buffer_new_from_pool (ladspa->bufpool, 0, 0);
738
739       if (buffers_out[i] == NULL)
740         GST_ERROR (0, "could not get new output buffer for srcpad %d !\n", i);
741
742       data_out = (LADSPA_Data *) GST_BUFFER_DATA (buffers_out[i]);
743       size = GST_BUFFER_SIZE (buffers_out[i]);
744       GST_BUFFER_TIMESTAMP (buffers_out[i]) = ladspa->timestamp;
745
746       /* initialize the output data to 0 */
747       zero_out = (gint8 *) GST_BUFFER_DATA (buffers_out[i]);
748       for (i = 0; i < size; i++)
749         zero_out[i] = 0;
750
751       desc->connect_port (ladspa->handle, oclass->srcpad_portnums[i], data_out);
752     }
753
754     /* i'm not sure if this will work ; the number of samples might be
755        nonconstant across sources and sinks ... */
756     desc->run (ladspa->handle, ladspa->buffersize);
757
758     /* now go through and reset the ladspa ports, pushing out the output buffers
759        at the same time. */
760     for (i=0;i<oclass->numsinkpads;i++) {
761       desc->connect_port (ladspa->handle, oclass->sinkpad_portnums[i], NULL);
762     }
763     for (i=0;i<oclass->numsrcpads;i++) {
764       GST_DEBUG (0, "pushing buffer (%p) on src pad %d", buffers_out[i], i);
765       gst_pad_push (ladspa->srcpads[i], buffers_out[i]);
766       buffers_out[i] = NULL;
767       desc->connect_port (ladspa->handle, oclass->srcpad_portnums[i], NULL);
768     }
769     
770     ladspa->timestamp += ladspa->buffersize * ladspa->samplerate * 10^9;
771   } while (TRUE);
772
773   g_free (buffers_out);
774 }
775
776 static void
777 gst_ladspa_chain_mono (GstPad *pad, GstBuffer *buf)
778 {
779   LADSPA_Descriptor *desc;
780   LADSPA_Data *data;
781   unsigned long num_samples;
782   
783   GstLADSPA *ladspa;
784   GstLADSPAClass *oclass;
785
786   g_return_if_fail(pad != NULL);
787   g_return_if_fail(GST_IS_PAD(pad));
788   g_return_if_fail(buf != NULL);
789
790   ladspa = (GstLADSPA *)gst_pad_get_parent (pad);
791   g_return_if_fail(ladspa != NULL);
792
793   /* this might happen if caps nego hasn't happened */
794   g_return_if_fail(ladspa->handle != NULL);
795
796   if (! GST_IS_EVENT (buf)) {
797     oclass = (GstLADSPAClass *) (G_OBJECT_GET_CLASS (ladspa));
798     data = (LADSPA_Data *) GST_BUFFER_DATA(buf);
799     num_samples = GST_BUFFER_SIZE(buf) / sizeof(gfloat);
800   
801     desc = ladspa->descriptor;
802
803     /* we know that we're dealing here with a filter that has one sink and one
804        src pad. */
805     desc->connect_port(ladspa->handle,oclass->sinkpad_portnums[0],data);
806     desc->connect_port(ladspa->handle,oclass->srcpad_portnums[0],data);
807
808     desc->run(ladspa->handle,num_samples);
809   
810     desc->connect_port(ladspa->handle,oclass->sinkpad_portnums[0],NULL);
811     desc->connect_port(ladspa->handle,oclass->srcpad_portnums[0],NULL);
812   }
813
814   gst_pad_push (ladspa->srcpads[0], buf);
815 }
816
817 static GstBuffer *
818 gst_ladspa_get(GstPad *pad)
819 {
820   LADSPA_Descriptor *desc;
821   LADSPA_Data *data;
822   
823   GstLADSPA *ladspa;
824   GstLADSPAClass *oclass;
825   GstBuffer *buf;
826
827   gint8 i, *zero_out;
828   unsigned long size;
829
830   g_return_val_if_fail(pad != NULL, NULL);
831   g_return_val_if_fail(GST_IS_PAD(pad), NULL);
832
833   ladspa = (GstLADSPA *)gst_pad_get_parent (pad);
834   g_return_val_if_fail(ladspa != NULL, NULL);
835
836   /* this might happen if caps nego hasn't happened */
837   g_return_val_if_fail(ladspa->handle != NULL, NULL);
838
839   oclass = (GstLADSPAClass*)(G_OBJECT_GET_CLASS(ladspa));
840
841   /* force all src pads to set their caps */
842   if (ladspa->newcaps) {
843     for (i=0;i<oclass->numsrcpads;i++) {
844       gst_ladspa_force_src_caps(ladspa, ladspa->srcpads[0]);
845     }
846   }
847
848   /* get a bufferpool */
849   i = 0;
850   while ((ladspa->bufpool == NULL) && (i < oclass->numsrcpads)) {
851     ladspa->bufpool = gst_pad_get_bufferpool (ladspa->srcpads[i++]);
852   }
853   if (ladspa->bufpool == NULL) {
854     ladspa->bufpool = gst_buffer_pool_get_default (sizeof (LADSPA_Data) * ladspa->buffersize,
855                                                    ladspa->numbuffers);
856   }
857   
858   buf = (GstBuffer *) gst_buffer_new_from_pool (ladspa->bufpool, 0, 0);
859   g_return_val_if_fail (buf, NULL);
860
861   /* initialize the output data to 0 */
862   zero_out = (gint8 *) GST_BUFFER_DATA (buf);      
863   for (i = 0; i < GST_BUFFER_SIZE (buf); i++)
864     zero_out[i] = 0;
865
866   data = (LADSPA_Data *) GST_BUFFER_DATA(buf);
867   size = GST_BUFFER_SIZE(buf);
868   GST_BUFFER_TIMESTAMP(buf) = ladspa->timestamp;
869   ladspa->timestamp += size * ladspa->samplerate * 10^9;
870
871   desc = ladspa->descriptor;
872
873   for (i=0;i<oclass->numsrcpads;i++)
874     desc->connect_port(ladspa->handle,oclass->srcpad_portnums[i],data);
875
876   desc->run(ladspa->handle, size);  
877
878   for (i=0;i<oclass->numsrcpads;i++)
879     desc->connect_port(ladspa->handle,oclass->srcpad_portnums[i],NULL);
880
881   return buf;
882 }
883
884 static void
885 ladspa_describe_plugin(const char *pcFullFilename,
886                        void *pvPluginHandle,
887                        LADSPA_Descriptor_Function pfDescriptorFunction)
888 {
889   const LADSPA_Descriptor *desc;
890   int i,j;
891   
892   GstElementDetails *details;
893   GTypeInfo typeinfo = {
894       sizeof(GstLADSPAClass),
895       NULL,
896       NULL,
897       (GClassInitFunc)gst_ladspa_class_init,
898       NULL,
899       NULL,
900       sizeof(GstLADSPA),
901       0,
902       (GInstanceInitFunc)gst_ladspa_init,
903   };
904   GType type;
905   GstElementFactory *factory;
906
907   /* walk through all the plugins in this pluginlibrary */
908   i = 0;
909   while ((desc = pfDescriptorFunction(i++))) {
910     gchar *type_name;
911
912     /* construct the type */
913     type_name = g_strdup_printf("ladspa_%s",desc->Label);
914     g_strcanon (type_name, G_CSET_A_2_Z G_CSET_a_2_z G_CSET_DIGITS "-_+", '-');
915     /* if it's already registered, drop it */
916     if (g_type_from_name(type_name)) {
917       g_free(type_name);
918       continue;
919     }
920     /* create the type now */
921     type = g_type_register_static(GST_TYPE_ELEMENT, type_name, &typeinfo, 0);
922
923     /* construct the element details struct */
924     details = g_new0(GstElementDetails,1);
925     details->longname = g_strdup(desc->Name);
926     details->klass = "Filter/LADSPA";
927     details->description = details->longname;
928     details->version = g_strdup_printf("%ld",desc->UniqueID);
929     details->author = g_strdup(desc->Maker);
930     details->copyright = g_strdup(desc->Copyright);
931
932     /* register the plugin with gstreamer */
933     factory = gst_elementfactory_new(type_name,type,details);
934     g_return_if_fail(factory != NULL);
935     gst_plugin_add_feature (ladspa_plugin, GST_PLUGIN_FEATURE (factory));
936
937     /* add this plugin to the hash */
938     g_hash_table_insert(ladspa_descriptors,
939                         GINT_TO_POINTER(type),
940                         (gpointer)desc);
941     
942
943     /* only add sink padtemplate if there are sinkpads */
944     for (j=0;j<desc->PortCount;j++) {
945       if (LADSPA_IS_PORT_AUDIO(desc->PortDescriptors[j]) &&
946           LADSPA_IS_PORT_INPUT(desc->PortDescriptors[j])) {
947         sinktempl = ladspa_sink_factory();
948         gst_elementfactory_add_padtemplate (factory, sinktempl);
949         break;
950       }
951     }
952   
953     srctempl = ladspa_src_factory();
954     gst_elementfactory_add_padtemplate (factory, srctempl);
955
956   }
957 }
958
959 static gboolean
960 plugin_init (GModule *module, GstPlugin *plugin)
961 {
962   ladspa_descriptors = g_hash_table_new(NULL,NULL);
963   parent_class = g_type_class_ref(GST_TYPE_ELEMENT);
964
965   ladspa_plugin = plugin;
966
967   LADSPAPluginSearch(ladspa_describe_plugin);
968
969   if (! gst_library_load ("gstbytestream")) {
970     gst_info ("gstladspa: could not load support library: 'gstbytestream'\n");
971     return FALSE;
972   }
973     
974   return TRUE;
975 }
976
977 GstPluginDesc plugin_desc = {
978   GST_VERSION_MAJOR,
979   GST_VERSION_MINOR,
980   "ladspa",
981   plugin_init
982 };
983