GstPadTemplate <-> gst_pad_template <-> GST_PAD_TEMPLATE same with *factory and typefind.
[platform/upstream/gst-plugins-good.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_pad_template_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_pad_template_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 = (GstLADSPA *) 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 (GST_ELEMENT (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   gint rate;
410
411   g_return_val_if_fail (caps != NULL, GST_PAD_CONNECT_DELAYED);
412   g_return_val_if_fail (pad  != NULL, GST_PAD_CONNECT_DELAYED);
413
414   gst_caps_get_int (caps, "rate", &rate);
415   /* have to instantiate ladspa plugin when samplerate changes (groan) */
416   if (ladspa->samplerate != rate){
417     ladspa->samplerate = rate;
418     if (! gst_ladspa_instantiate(ladspa))
419       return GST_PAD_CONNECT_REFUSED;
420   }
421
422   /* if the caps are fixed, we are going to try to set all srcpads using this
423      one caps object. if any of the pads barfs, we'll refuse the connection. i'm
424      not sure if this is correct. */
425   if (GST_CAPS_IS_FIXED (caps)) {
426     for (i=0;i<oclass->numsrcpads;i++) {
427       if (! gst_pad_try_set_caps (ladspa->srcpads[i], caps))
428         return GST_PAD_CONNECT_REFUSED;
429     }
430   }
431   
432   return GST_PAD_CONNECT_DELAYED;
433 }
434
435 static GstPadConnectReturn 
436 gst_ladspa_connect_get (GstPad *pad, GstCaps *caps) 
437 {
438   GstLADSPA *ladspa = (GstLADSPA*)GST_OBJECT_PARENT (pad);
439   gint rate;
440  
441   g_return_val_if_fail (caps != NULL, GST_PAD_CONNECT_DELAYED);
442   g_return_val_if_fail (pad  != NULL, GST_PAD_CONNECT_DELAYED);
443
444   gst_caps_get_int (caps, "rate", &rate);
445
446   if (ladspa->samplerate != rate) {
447     ladspa->samplerate = rate;
448     if (! gst_ladspa_instantiate(ladspa))
449       return GST_PAD_CONNECT_REFUSED;
450   }
451
452   return GST_PAD_CONNECT_DELAYED;
453 }
454
455 static void
456 gst_ladspa_force_src_caps(GstLADSPA *ladspa, GstPad *pad)
457 {
458   GST_DEBUG (0, "forcing caps");
459   gst_pad_try_set_caps (pad, gst_caps_new (
460     "ladspa_src_caps",
461     "audio/raw",
462     gst_props_new (
463       "format",     GST_PROPS_STRING ("float"),
464       "layout",     GST_PROPS_STRING ("gfloat"),
465       "intercept",  GST_PROPS_FLOAT(0.0),
466       "slope",      GST_PROPS_FLOAT(1.0),
467       "rate",       GST_PROPS_INT (ladspa->samplerate),
468       "channels",   GST_PROPS_INT (1),
469       NULL
470     )
471   ));
472   ladspa->newcaps=FALSE;
473 }
474
475 static void
476 gst_ladspa_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec)
477 {
478   GstLADSPA *ladspa = (GstLADSPA*)object;
479   gint cid = prop_id - ARG_LAST;
480   GstLADSPAClass *oclass;
481   ladspa_control_info *control_info;
482   gfloat val=0.0;
483     
484   /* these are only registered in get mode */
485   switch (prop_id) {
486     case ARG_SAMPLERATE:
487       ladspa->samplerate = g_value_get_int (value);
488       ladspa->newcaps=TRUE;
489       break;
490     case ARG_BUFFERSIZE:
491       ladspa->buffersize = g_value_get_int (value);
492       break;
493   }
494   
495   /* is it a ladspa plugin arg? */
496   if (cid < 0) return;
497
498 /*
499   if (id == ARG_LOOP_BASED) {
500     * we can only do this in NULL state *
501     g_return_if_fail (GST_STATE(object) != GST_STATE_NULL);
502     ladspa->loopbased = g_value_get_boolean (value);
503     if (ladspa->loopbased) {
504       gst_element_set_loop_function (GST_ELEMENT (ladspa), gst_ladspa_loop);
505     } else {
506       gst_element_set_loop_function (GST_ELEMENT (ladspa), NULL);
507     }
508   }
509 */
510
511   oclass = (GstLADSPAClass*)(G_OBJECT_GET_CLASS (object));
512
513   /* verify it exists and is a control (not a port) */
514   g_return_if_fail(cid < oclass->numcontrols);
515   
516   control_info = &(oclass->control_info[cid]);
517   g_return_if_fail (control_info->name != NULL);
518
519   /* check to see if it's writable */
520   g_return_if_fail (control_info->writable);
521
522   /* now see what type it is */
523   if (control_info->toggled) {
524     if (g_value_get_boolean (value))
525       ladspa->controls[cid] = 1.0;
526     else
527       ladspa->controls[cid] = 0.0;
528   } else if (control_info->integer) {
529     val = (gfloat)g_value_get_int (value);
530     ladspa->controls[cid] = val;
531   } else {
532     val = g_value_get_float (value);
533     ladspa->controls[cid] = val;
534   }    
535
536   GST_DEBUG (0, "set arg %s to %f", control_info->name, ladspa->controls[cid]);
537 }
538
539 static void
540 gst_ladspa_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec)
541 {
542   GstLADSPA *ladspa = (GstLADSPA*)object;
543   gint cid = prop_id - ARG_LAST;
544   GstLADSPAClass *oclass = (GstLADSPAClass*)(G_OBJECT_GET_CLASS (object));
545   ladspa_control_info *control_info;
546
547   /* these are only registered in get mode */
548   switch (prop_id){
549     case ARG_SAMPLERATE:
550       g_value_set_int (value, ladspa->samplerate);
551       break;
552     case ARG_BUFFERSIZE:
553       g_value_set_int (value, ladspa->buffersize);
554       break;
555   }
556     
557   if (cid < 0) return;
558
559   /* verify it exists and is a control (not a port) */
560   if (cid >= oclass->numcontrols) return;
561   control_info = &(oclass->control_info[cid]);
562   if (control_info->name == NULL) return;
563
564   GST_DEBUG (0, "got arg %s as %f", control_info->name, ladspa->controls[cid]);
565
566   /* now see what type it is */
567   if (control_info->toggled) {
568     if (ladspa->controls[cid] == 1.0)
569       g_value_set_boolean (value, TRUE);
570     else
571       g_value_set_boolean (value, FALSE);
572   } else if (control_info->integer) {
573     g_value_set_int (value, (gint)ladspa->controls[cid]);
574   } else {
575     g_value_set_float (value, ladspa->controls[cid]);
576   }
577 }
578
579 static gboolean
580 gst_ladspa_instantiate (GstLADSPA *ladspa)
581 {
582   LADSPA_Descriptor *desc;
583   int i;
584   GstLADSPAClass *oclass = (GstLADSPAClass*)(G_OBJECT_GET_CLASS (ladspa));
585   gboolean was_activated;
586   
587   desc = ladspa->descriptor;
588   
589   /* check for old handle */
590   was_activated = ladspa->activated;
591   if (ladspa->handle != NULL){
592     gst_ladspa_deactivate(ladspa);
593     desc->cleanup(ladspa->handle);
594   }
595         
596   /* instantiate the plugin */ 
597   GST_DEBUG (0, "instantiating the plugin");
598   
599   ladspa->handle = desc->instantiate(desc,ladspa->samplerate);
600   g_return_val_if_fail (ladspa->handle != NULL, FALSE);
601
602   /* walk through the ports and add all the arguments */
603   for (i=0;i<oclass->numcontrols;i++) {
604     /* connect the argument to the plugin */
605     GST_DEBUG (0, "added control port %d", oclass->control_portnums[i]);
606     desc->connect_port(ladspa->handle,
607                        oclass->control_portnums[i],
608                        &(ladspa->controls[i]));
609   }
610
611   /* reactivate if it was activated before the reinstantiation */
612   if (was_activated){
613     gst_ladspa_activate(ladspa);
614   }
615   return TRUE;
616 }
617
618 static GstElementStateReturn
619 gst_ladspa_change_state (GstElement *element)
620 {
621   LADSPA_Descriptor *desc;
622   GstLADSPA *ladspa = (GstLADSPA*)element;
623   desc = ladspa->descriptor;
624
625   GST_DEBUG (0, "changing state");
626   switch (GST_STATE_TRANSITION (element)) {
627     case GST_STATE_NULL_TO_READY:
628       gst_ladspa_activate(ladspa);
629       break;
630     case GST_STATE_READY_TO_NULL:
631       gst_ladspa_deactivate(ladspa);
632       break;
633     default:
634       break;
635   }
636
637   if (GST_ELEMENT_CLASS (parent_class)->change_state)
638     return GST_ELEMENT_CLASS (parent_class)->change_state (element);
639
640   return GST_STATE_SUCCESS;
641 }
642
643 static void
644 gst_ladspa_activate(GstLADSPA *ladspa)
645 {
646   LADSPA_Descriptor *desc;
647   desc = ladspa->descriptor;
648   
649   if (ladspa->activated){
650     gst_ladspa_deactivate(ladspa);
651   }
652   
653   GST_DEBUG (0, "activating");
654
655   /* activate the plugin (function might be null) */
656   if (desc->activate != NULL) {
657     desc->activate(ladspa->handle);
658   }
659
660   ladspa->activated = TRUE;
661 }
662
663 static void
664 gst_ladspa_deactivate(GstLADSPA *ladspa)
665 {
666   LADSPA_Descriptor *desc;
667   desc = ladspa->descriptor;
668
669   GST_DEBUG (0, "deactivating");
670
671   /* deactivate the plugin (function might be null) */
672   if (ladspa->activated && (desc->deactivate != NULL)) {
673     desc->deactivate(ladspa->handle);
674   }
675
676   ladspa->activated = FALSE;
677 }
678
679 static void
680 gst_ladspa_loop (GstElement *element)
681 {
682   gint8        *raw_in, *zero_out, i;
683   GstBuffer   **buffers_out;
684   GstEvent     *event = NULL;
685   guint32       waiting;
686   LADSPA_Data **data_in, *data_out;
687   unsigned long size;
688
689   GstLADSPA       *ladspa = (GstLADSPA *)element;
690   GstLADSPAClass  *oclass = (GstLADSPAClass*)(G_OBJECT_GET_CLASS (ladspa));
691   LADSPA_Descriptor *desc = ladspa->descriptor;
692
693   data_in = g_new0(LADSPA_Data *, oclass->numsinkpads);
694   buffers_out = g_new0(GstBuffer *, oclass->numsrcpads);
695   
696   /* set up the bufferpool first if necessary */
697   i = 0;
698   while ((ladspa->bufpool == NULL) && (i < oclass->numsrcpads)) {
699     ladspa->bufpool = gst_pad_get_bufferpool (ladspa->srcpads[i++]);
700   }
701   if (ladspa->bufpool == NULL) {
702     ladspa->bufpool = gst_buffer_pool_get_default (sizeof (LADSPA_Data) * ladspa->buffersize,
703                                                    ladspa->numbuffers);
704   }
705
706   /* since this is a loop element, we just loop here til things fall apart. */
707   do {
708
709     /* first get all the necessary data from the input ports */
710     for (i=0;i<oclass->numsinkpads;i++){  
711       GST_DEBUG (0, "pulling %d bytes through channel %d'sbytestream\n", 
712                       ladspa->buffersize * sizeof (LADSPA_Data), i);
713       raw_in = gst_bytestream_peek_bytes (ladspa->bytestreams[i], ladspa->buffersize * sizeof (LADSPA_Data));
714
715       if (raw_in == NULL) {
716         /* we need to check for an event. */
717         gst_bytestream_get_status (ladspa->bytestreams[i], &waiting, &event);
718
719         if (event) {
720           if (GST_EVENT_TYPE(event) == GST_EVENT_EOS) {
721             /* if we get an EOS event from one of our sink pads, we assume that
722                pad's finished handling data. delete the bytestream, free up the
723                pad, and free up the memory associated with the input channel. */
724             GST_DEBUG (0, "got an EOS event on sinkpad %d", i);
725           }
726
727           /* we need to create some zeroed out data to feed to this port of the
728              ladspa filter. */
729           data_in[i] = g_new0 (LADSPA_Data, ladspa->buffersize * sizeof (LADSPA_Data));
730         } else {
731           /* copy the retrieved data and bind the ladspa src port to the data */
732           data_in[i] = (LADSPA_Data *) raw_in;
733         }
734       }
735
736       raw_in = NULL;
737       desc->connect_port (ladspa->handle, oclass->sinkpad_portnums[i], data_in[i]);
738       gst_bytestream_flush (ladspa->bytestreams[i], ladspa->buffersize * sizeof (LADSPA_Data));
739     }
740
741     /* now set up the output ports */
742     for (i=0;i<oclass->numsrcpads;i++) {
743       buffers_out[i] = (GstBuffer *) gst_buffer_new_from_pool (ladspa->bufpool, 0, 0);
744
745       if (buffers_out[i] == NULL)
746         GST_ERROR (0, "could not get new output buffer for srcpad %d !\n", i);
747
748       data_out = (LADSPA_Data *) GST_BUFFER_DATA (buffers_out[i]);
749       size = GST_BUFFER_SIZE (buffers_out[i]);
750       GST_BUFFER_TIMESTAMP (buffers_out[i]) = ladspa->timestamp;
751
752       /* initialize the output data to 0 */
753       zero_out = (gint8 *) GST_BUFFER_DATA (buffers_out[i]);
754       for (i = 0; i < size; i++)
755         zero_out[i] = 0;
756
757       desc->connect_port (ladspa->handle, oclass->srcpad_portnums[i], data_out);
758     }
759
760     /* i'm not sure if this will work ; the number of samples might be
761        nonconstant across sources and sinks ... */
762     desc->run (ladspa->handle, ladspa->buffersize);
763
764     /* now go through and reset the ladspa ports, pushing out the output buffers
765        at the same time. */
766     for (i=0;i<oclass->numsinkpads;i++) {
767       desc->connect_port (ladspa->handle, oclass->sinkpad_portnums[i], NULL);
768     }
769     for (i=0;i<oclass->numsrcpads;i++) {
770       GST_DEBUG (0, "pushing buffer (%p) on src pad %d", buffers_out[i], i);
771       gst_pad_push (ladspa->srcpads[i], buffers_out[i]);
772       buffers_out[i] = NULL;
773       desc->connect_port (ladspa->handle, oclass->srcpad_portnums[i], NULL);
774     }
775     
776     ladspa->timestamp += ladspa->buffersize * ladspa->samplerate * 10^9;
777   } while (TRUE);
778
779   g_free (buffers_out);
780 }
781
782 static void
783 gst_ladspa_chain_mono (GstPad *pad, GstBuffer *buf)
784 {
785   LADSPA_Descriptor *desc;
786   LADSPA_Data *data;
787   unsigned long num_samples;
788   
789   GstLADSPA *ladspa;
790   GstLADSPAClass *oclass;
791
792   g_return_if_fail(pad != NULL);
793   g_return_if_fail(GST_IS_PAD(pad));
794   g_return_if_fail(buf != NULL);
795
796   ladspa = (GstLADSPA *)gst_pad_get_parent (pad);
797   g_return_if_fail(ladspa != NULL);
798
799   /* this might happen if caps nego hasn't happened */
800   g_return_if_fail(ladspa->handle != NULL);
801
802   if (! GST_IS_EVENT (buf)) {
803     oclass = (GstLADSPAClass *) (G_OBJECT_GET_CLASS (ladspa));
804     data = (LADSPA_Data *) GST_BUFFER_DATA(buf);
805     num_samples = GST_BUFFER_SIZE(buf) / sizeof(gfloat);
806   
807     desc = ladspa->descriptor;
808
809     /* we know that we're dealing here with a filter that has one sink and one
810        src pad. */
811     desc->connect_port(ladspa->handle,oclass->sinkpad_portnums[0],data);
812     desc->connect_port(ladspa->handle,oclass->srcpad_portnums[0],data);
813
814     desc->run(ladspa->handle,num_samples);
815   
816     desc->connect_port(ladspa->handle,oclass->sinkpad_portnums[0],NULL);
817     desc->connect_port(ladspa->handle,oclass->srcpad_portnums[0],NULL);
818   }
819
820   gst_pad_push (ladspa->srcpads[0], buf);
821 }
822
823 static GstBuffer *
824 gst_ladspa_get(GstPad *pad)
825 {
826   LADSPA_Descriptor *desc;
827   LADSPA_Data *data;
828   
829   GstLADSPA *ladspa;
830   GstLADSPAClass *oclass;
831   GstBuffer *buf;
832
833   gint8 i, *zero_out;
834   unsigned long size;
835
836   g_return_val_if_fail(pad != NULL, NULL);
837   g_return_val_if_fail(GST_IS_PAD(pad), NULL);
838
839   ladspa = (GstLADSPA *)gst_pad_get_parent (pad);
840   g_return_val_if_fail(ladspa != NULL, NULL);
841
842   /* this might happen if caps nego hasn't happened */
843   g_return_val_if_fail(ladspa->handle != NULL, NULL);
844
845   oclass = (GstLADSPAClass*)(G_OBJECT_GET_CLASS(ladspa));
846
847   /* force all src pads to set their caps */
848   if (ladspa->newcaps) {
849     for (i=0;i<oclass->numsrcpads;i++) {
850       gst_ladspa_force_src_caps(ladspa, ladspa->srcpads[0]);
851     }
852   }
853
854   /* get a bufferpool */
855   i = 0;
856   while ((ladspa->bufpool == NULL) && (i < oclass->numsrcpads)) {
857     ladspa->bufpool = gst_pad_get_bufferpool (ladspa->srcpads[i++]);
858   }
859   if (ladspa->bufpool == NULL) {
860     ladspa->bufpool = gst_buffer_pool_get_default (sizeof (LADSPA_Data) * ladspa->buffersize,
861                                                    ladspa->numbuffers);
862   }
863   
864   buf = (GstBuffer *) gst_buffer_new_from_pool (ladspa->bufpool, 0, 0);
865   g_return_val_if_fail (buf, NULL);
866
867   /* initialize the output data to 0 */
868   zero_out = (gint8 *) GST_BUFFER_DATA (buf);      
869   for (i = 0; i < GST_BUFFER_SIZE (buf); i++)
870     zero_out[i] = 0;
871
872   data = (LADSPA_Data *) GST_BUFFER_DATA(buf);
873   size = GST_BUFFER_SIZE(buf);
874   GST_BUFFER_TIMESTAMP(buf) = ladspa->timestamp;
875   ladspa->timestamp += size * ladspa->samplerate * 10^9;
876
877   desc = ladspa->descriptor;
878
879   for (i=0;i<oclass->numsrcpads;i++)
880     desc->connect_port(ladspa->handle,oclass->srcpad_portnums[i],data);
881
882   desc->run(ladspa->handle, size);  
883
884   for (i=0;i<oclass->numsrcpads;i++)
885     desc->connect_port(ladspa->handle,oclass->srcpad_portnums[i],NULL);
886
887   return buf;
888 }
889
890 static void
891 ladspa_describe_plugin(const char *pcFullFilename,
892                        void *pvPluginHandle,
893                        LADSPA_Descriptor_Function pfDescriptorFunction)
894 {
895   const LADSPA_Descriptor *desc;
896   int i,j;
897   
898   GstElementDetails *details;
899   GTypeInfo typeinfo = {
900       sizeof(GstLADSPAClass),
901       NULL,
902       NULL,
903       (GClassInitFunc)gst_ladspa_class_init,
904       NULL,
905       NULL,
906       sizeof(GstLADSPA),
907       0,
908       (GInstanceInitFunc)gst_ladspa_init,
909   };
910   GType type;
911   GstElementFactory *factory;
912
913   /* walk through all the plugins in this pluginlibrary */
914   i = 0;
915   while ((desc = pfDescriptorFunction(i++))) {
916     gchar *type_name;
917
918     /* construct the type */
919     type_name = g_strdup_printf("ladspa_%s",desc->Label);
920     g_strcanon (type_name, G_CSET_A_2_Z G_CSET_a_2_z G_CSET_DIGITS "-_+", '-');
921     /* if it's already registered, drop it */
922     if (g_type_from_name(type_name)) {
923       g_free(type_name);
924       continue;
925     }
926     /* create the type now */
927     type = g_type_register_static(GST_TYPE_ELEMENT, type_name, &typeinfo, 0);
928
929     /* construct the element details struct */
930     details = g_new0(GstElementDetails,1);
931     details->longname = g_strdup(desc->Name);
932     details->klass = "Filter/LADSPA";
933     details->description = details->longname;
934     details->version = g_strdup_printf("%ld",desc->UniqueID);
935     details->author = g_strdup(desc->Maker);
936     details->copyright = g_strdup(desc->Copyright);
937
938     /* register the plugin with gstreamer */
939     factory = gst_element_factory_new(type_name,type,details);
940     g_return_if_fail(factory != NULL);
941     gst_plugin_add_feature (ladspa_plugin, GST_PLUGIN_FEATURE (factory));
942
943     /* add this plugin to the hash */
944     g_hash_table_insert(ladspa_descriptors,
945                         GINT_TO_POINTER(type),
946                         (gpointer)desc);
947     
948
949     /* only add sink padtemplate if there are sinkpads */
950     for (j=0;j<desc->PortCount;j++) {
951       if (LADSPA_IS_PORT_AUDIO(desc->PortDescriptors[j]) &&
952           LADSPA_IS_PORT_INPUT(desc->PortDescriptors[j])) {
953         sinktempl = ladspa_sink_factory();
954         gst_element_factory_add_pad_template (factory, sinktempl);
955         break;
956       }
957     }
958   
959     srctempl = ladspa_src_factory();
960     gst_element_factory_add_pad_template (factory, srctempl);
961
962   }
963 }
964
965 static gboolean
966 plugin_init (GModule *module, GstPlugin *plugin)
967 {
968   ladspa_descriptors = g_hash_table_new(NULL,NULL);
969   parent_class = g_type_class_ref(GST_TYPE_ELEMENT);
970
971   ladspa_plugin = plugin;
972
973   LADSPAPluginSearch(ladspa_describe_plugin);
974
975   if (! gst_library_load ("gstbytestream")) {
976     gst_info ("gstladspa: could not load support library: 'gstbytestream'\n");
977     return FALSE;
978   }
979     
980   return TRUE;
981 }
982
983 GstPluginDesc plugin_desc = {
984   GST_VERSION_MAJOR,
985   GST_VERSION_MINOR,
986   "ladspa",
987   plugin_init
988 };
989