s/G_MINFLOAT/G_MAXFLOAT unref the buffer pool in the loop func
[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 #include <gst/control/control.h>
24
25 #include "gstladspa.h"
26 #include "ladspa.h"     /* main ladspa sdk include file */
27 #include "utils.h"      /* ladspa sdk utility functions */
28
29
30 GST_PAD_TEMPLATE_FACTORY (ladspa_sink_factory,
31   "sink",
32   GST_PAD_SINK,
33   GST_PAD_REQUEST,
34   GST_CAPS_NEW (
35     "ladspa_sink",
36     "audio/raw",
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)
43   )
44 );
45
46 GST_PAD_TEMPLATE_FACTORY (ladspa_src_factory,
47   "src",
48   GST_PAD_SRC,
49   GST_PAD_REQUEST,
50   GST_CAPS_NEW (
51     "ladspa_src",
52     "audio/raw",
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)
59   )
60 );
61
62 static GstPadTemplate *srctempl, *sinktempl;
63
64 enum {
65   ARG_0,
66   ARG_SAMPLERATE,
67   ARG_BUFFERSIZE,
68   ARG_LAST,
69 };
70
71 static void                     gst_ladspa_class_init           (GstLADSPAClass *klass);
72 static void                     gst_ladspa_init                 (GstLADSPA *ladspa);
73
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);
78
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);
81
82 static gboolean                 gst_ladspa_instantiate          (GstLADSPA *ladspa);
83 static void                     gst_ladspa_activate             (GstLADSPA *ladspa);
84 static void                     gst_ladspa_deactivate           (GstLADSPA *ladspa);
85
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);
90
91 static GstElementClass *parent_class = NULL;
92 /* static guint gst_ladspa_signals[LAST_SIGNAL] = { 0 }; */
93
94 static GstPlugin *ladspa_plugin;
95 static GHashTable *ladspa_descriptors;
96
97 static GstBufferPool*
98 gst_ladspa_get_bufferpool (GstPad *pad)
99 {
100   gint i;
101   GstBufferPool *bp;
102   GstLADSPA *ladspa = (GstLADSPA *) gst_pad_get_parent (pad);
103   GstLADSPAClass *oclass = (GstLADSPAClass *) (G_OBJECT_GET_CLASS (ladspa));
104
105   if (oclass->numsrcpads > 0)
106     for (i=0;i<oclass->numsrcpads;i++)
107       if ((bp = gst_pad_get_bufferpool(ladspa->srcpads[i])) != NULL)
108         return bp;
109
110   return NULL;
111 }
112
113 static void
114 gst_ladspa_class_init (GstLADSPAClass *klass)
115 {
116   GObjectClass *gobject_class;
117   GstElementClass *gstelement_class;
118   LADSPA_Descriptor *desc;
119   gint i,current_portnum,sinkcount,srccount,controlcount;
120   gint hintdesc;
121   gint argtype,argperms;
122   GParamSpec *paramspec = NULL;
123   gchar *argname, *tempstr, *paren;
124
125   gobject_class = (GObjectClass*)klass;
126   gstelement_class = (GstElementClass*)klass;
127
128   gobject_class->set_property = gst_ladspa_set_property;
129   gobject_class->get_property = gst_ladspa_get_property;
130
131   gstelement_class->change_state = gst_ladspa_change_state;
132
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;
136
137   klass->numports = desc->PortCount;
138
139   klass->numsinkpads = 0;
140   klass->numsrcpads = 0;
141   klass->numcontrols = 0;
142
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++;
148     }
149       
150     if (LADSPA_IS_PORT_AUDIO(desc->PortDescriptors[i]) && 
151         LADSPA_IS_PORT_OUTPUT(desc->PortDescriptors[i])){
152       klass->numsrcpads++;
153     }
154       
155     if (LADSPA_IS_PORT_CONTROL(desc->PortDescriptors[i]) && 
156         LADSPA_IS_PORT_INPUT(desc->PortDescriptors[i])){
157       klass->numcontrols++;
158     }
159   }
160
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);
164   sinkcount = 0;
165   srccount = 0;
166   controlcount = 0;
167
168   /* walk through the ports, note the portnums for srcpads, sinkpads and control
169      params */
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;
175     }
176       
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;
181     }
182       
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;
187     }
188   }
189
190   /* no sink pads - we'll use get mode and add params for samplerate and
191      buffersize */
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));
199
200   }
201   
202   /* now build the contorl info from the control ports */
203   klass->control_info = g_new0(ladspa_control_info,klass->numcontrols);
204     
205   for (i=0;i<klass->numcontrols;i++) {
206     current_portnum = klass->control_portnums[i];
207     
208     /* short name for hint descriptor */
209     hintdesc = desc->PortRangeHints[current_portnum].HintDescriptor;
210
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;
218
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;
223
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;
229     } else {
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;
232     }
233     
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;
240     } else {
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;
243     }
244
245     if (LADSPA_IS_PORT_INPUT(desc->PortDescriptors[current_portnum])) {
246       argperms = G_PARAM_READWRITE;
247       klass->control_info[i].writable = TRUE;
248     } else {
249       argperms = G_PARAM_READABLE;
250       klass->control_info[i].writable = FALSE;
251     }
252
253     klass->control_info[i].name = g_strdup(desc->PortNames[current_portnum]);
254     argname = g_strdup(klass->control_info[i].name);
255     /* find out if there is a (unitname) at the end of the argname and get rid
256        of it */
257     paren = g_strrstr (argname, " (");
258     if (paren != NULL) {
259       *paren = '\0';
260     }
261     /* this is the same thing that param_spec_* will do */
262     g_strcanon (argname, G_CSET_A_2_Z G_CSET_a_2_z G_CSET_DIGITS "-", '-');
263     /* satisfy glib2 (argname[0] must be [A-Za-z]) */
264     if (!((argname[0] >= 'a' && argname[0] <= 'z') || (argname[0] >= 'A' && argname[0] <= 'Z'))) {
265       tempstr = argname;
266       argname = g_strconcat("param-", argname, NULL);
267       g_free (tempstr);
268     }
269     
270     /* check for duplicate property names */
271     if (g_object_class_find_property(G_OBJECT_CLASS(klass), argname) != NULL){
272       gint numarg=1;
273       gchar *numargname = g_strdup_printf("%s_%d",argname,numarg++);
274       while (g_object_class_find_property(G_OBJECT_CLASS(klass), numargname) != NULL){
275         g_free(numargname);
276         numargname = g_strdup_printf("%s_%d",argname,numarg++);
277       }
278       argname = numargname;
279     }
280     
281     klass->control_info[i].param_name = argname;
282     
283     GST_DEBUG (0, "adding arg %s from %s",argname, klass->control_info[i].name);
284     
285     if (argtype==G_TYPE_BOOLEAN){
286       paramspec = g_param_spec_boolean(argname,argname,argname, FALSE, argperms);
287     } else if (argtype==G_TYPE_INT){      
288       paramspec = g_param_spec_int(argname,argname,argname, 
289         (gint)klass->control_info[i].lowerbound, 
290         (gint)klass->control_info[i].upperbound, 
291         (gint)klass->control_info[i].lowerbound, argperms);
292     } else if (klass->control_info[i].samplerate){
293       paramspec = g_param_spec_float(argname,argname,argname, 
294         0.0, G_MAXFLOAT, 
295         0.0, argperms);
296     } else {
297       paramspec = g_param_spec_float(argname,argname,argname, 
298         klass->control_info[i].lowerbound, klass->control_info[i].upperbound, 
299         klass->control_info[i].lowerbound, argperms);
300     }
301     
302     g_object_class_install_property(G_OBJECT_CLASS(klass), i+ARG_LAST, paramspec);
303   }
304 }
305
306 static void
307 gst_ladspa_init (GstLADSPA *ladspa)
308 {
309   GstLADSPAClass *oclass = (GstLADSPAClass*)(G_OBJECT_GET_CLASS(ladspa));
310   ladspa_control_info cinfo;
311   
312   LADSPA_Descriptor *desc;
313   gint i,sinkcount,srccount,controlcount;
314
315   desc = oclass->descriptor;
316   ladspa->descriptor = oclass->descriptor;
317   
318   /* allocate the various arrays */
319   ladspa->srcpads = g_new0(GstPad*,oclass->numsrcpads);
320   ladspa->sinkpads = g_new0(GstPad*,oclass->numsinkpads);
321   ladspa->controls = g_new(gfloat,oclass->numcontrols);
322   ladspa->dpman = gst_dpman_new ("ladspa_dpman", GST_ELEMENT(ladspa));
323   
324   /* walk through the ports and add all the pads */
325   sinkcount = 0;
326   srccount = 0;
327   controlcount = 0;
328   for (i=0;i<desc->PortCount;i++) {
329     
330     if (LADSPA_IS_PORT_AUDIO(desc->PortDescriptors[i])){
331       gchar *canon_port_name = g_strdup((gchar *)desc->PortNames[i]);
332       g_strcanon (canon_port_name, G_CSET_A_2_Z G_CSET_a_2_z G_CSET_DIGITS "-", '-');
333       if (LADSPA_IS_PORT_INPUT(desc->PortDescriptors[i])) {
334         ladspa->sinkpads[sinkcount] = gst_pad_new_from_template (sinktempl, canon_port_name);
335         gst_element_add_pad(GST_ELEMENT(ladspa),ladspa->sinkpads[sinkcount]);
336         sinkcount++;
337       }
338       if (LADSPA_IS_PORT_OUTPUT(desc->PortDescriptors[i])) {
339         ladspa->srcpads[srccount] = gst_pad_new_from_template (srctempl, canon_port_name);
340         gst_element_add_pad(GST_ELEMENT(ladspa),ladspa->srcpads[srccount]);
341         srccount++;
342       }
343     }
344     if (LADSPA_IS_PORT_CONTROL(desc->PortDescriptors[i]) &&
345         LADSPA_IS_PORT_INPUT(desc->PortDescriptors[i])) {
346       cinfo = oclass->control_info[controlcount];
347       /* use the lowerbound as the default value if it exists */
348       if (cinfo.lower){
349         ladspa->controls[controlcount]=cinfo.lowerbound;
350       } else {
351         ladspa->controls[controlcount] = 0.0;
352       }
353       
354       /* set up dparams for this instance */
355       if (cinfo.toggled){
356         gst_dpman_add_required_dparam_callback (
357           ladspa->dpman, 
358           g_param_spec_int(cinfo.param_name, cinfo.name, cinfo.name,
359                            0, 1, (gint)(ladspa->controls[controlcount]), G_PARAM_READWRITE),
360           "int", gst_ladspa_update_int, &(ladspa->controls[controlcount])
361         );
362       }
363       else if (cinfo.integer){
364         gst_dpman_add_required_dparam_callback (
365           ladspa->dpman, 
366           g_param_spec_int(cinfo.param_name, cinfo.name, cinfo.name,
367                            (gint)cinfo.lowerbound, (gint)cinfo.upperbound,
368                            (gint)ladspa->controls[controlcount], G_PARAM_READWRITE),
369           "int", gst_ladspa_update_int, &(ladspa->controls[controlcount])
370         );
371       }
372       else if (cinfo.samplerate){
373         gst_dpman_add_required_dparam_direct (
374           ladspa->dpman, 
375           g_param_spec_float(cinfo.param_name, cinfo.name, cinfo.name,
376                            cinfo.lowerbound, cinfo.upperbound,
377                            ladspa->controls[controlcount], G_PARAM_READWRITE),
378           "hertz-rate-bound", &(ladspa->controls[controlcount])
379         );
380       }
381       else {
382         gst_dpman_add_required_dparam_direct (
383           ladspa->dpman, 
384           g_param_spec_float(cinfo.param_name, cinfo.name, cinfo.name,
385                            cinfo.lowerbound, cinfo.upperbound,
386                            ladspa->controls[controlcount], G_PARAM_READWRITE),
387           "float", &(ladspa->controls[controlcount])
388         );
389       }
390
391       controlcount++;
392     }
393   }
394
395   ladspa->samplerate = 0;
396   ladspa->buffersize = 64;
397   ladspa->numbuffers = 16;
398   ladspa->newcaps = FALSE;
399   ladspa->activated = FALSE;
400   ladspa->bufpool = NULL;
401
402   if (sinkcount==0 && srccount == 1) {
403     /* get mode (no sink pads) */
404     GST_DEBUG (0, "mono get mode with 1 src pad");
405
406     ladspa->newcaps = TRUE;
407     ladspa->samplerate = 44100;
408     ladspa->buffersize = 64;
409
410     gst_pad_set_connect_function (ladspa->srcpads[0], gst_ladspa_connect_get);
411     gst_pad_set_get_function (ladspa->srcpads[0], gst_ladspa_get);
412
413   } else if (sinkcount==1){
414     /* with one sink we can use the chain function */
415     GST_DEBUG (0, "chain mode");
416
417     gst_pad_set_connect_function (ladspa->sinkpads[0], gst_ladspa_connect);
418     gst_pad_set_chain_function (ladspa->sinkpads[0], gst_ladspa_chain);
419     gst_pad_set_bufferpool_function (ladspa->sinkpads[0], gst_ladspa_get_bufferpool);
420   } else if (sinkcount > 1){
421     /* more than one sink pad needs loop mode */
422     GST_DEBUG (0, "loop mode with %d sink pads and %d src pads", sinkcount, srccount);
423
424     for (i=0;i<sinkcount;i++) {
425       gst_pad_set_connect_function (ladspa->sinkpads[i], gst_ladspa_connect);
426       gst_pad_set_bufferpool_function (ladspa->sinkpads[i], gst_ladspa_get_bufferpool);
427     }
428     gst_element_set_loop_function (GST_ELEMENT (ladspa), gst_ladspa_loop);
429   } 
430   else if (sinkcount==0 && srccount == 0){
431     /* for some reason these plugins exist - we'll just ignore them */
432   } else {
433     g_warning("%d sink pads, %d src pads not yet supported", sinkcount, srccount);
434   }
435
436   gst_ladspa_instantiate(ladspa);
437 }
438
439 static void
440 gst_ladspa_update_int(const GValue *value, gpointer data)
441 {
442   gfloat *target = (gfloat*) data;
443   *target = (gfloat)g_value_get_int(value);
444 }
445
446 static GstPadConnectReturn
447 gst_ladspa_connect (GstPad *pad, GstCaps *caps)
448 {
449   GstLADSPA *ladspa = (GstLADSPA *) GST_PAD_PARENT (pad);
450   GstLADSPAClass *oclass = (GstLADSPAClass *) (G_OBJECT_GET_CLASS (ladspa));
451   guint i;
452   gint rate;
453
454   g_return_val_if_fail (caps != NULL, GST_PAD_CONNECT_DELAYED);
455   g_return_val_if_fail (pad  != NULL, GST_PAD_CONNECT_DELAYED);
456
457   if (gst_caps_get_int (caps, "rate", &rate)){
458     /* have to instantiate ladspa plugin when samplerate changes (groan) */
459     if (ladspa->samplerate != rate){
460       ladspa->samplerate = rate;
461   
462       if (! gst_ladspa_instantiate(ladspa))
463         return GST_PAD_CONNECT_REFUSED;
464     }
465   }
466
467   /* if the caps are fixed, we are going to try to set all srcpads using this
468      one caps object. if any of the pads barfs, we'll refuse the connection. i'm
469      not sure if this is correct. */
470   if (GST_CAPS_IS_FIXED (caps)) {
471     for (i=0;i<oclass->numsrcpads;i++) {
472       if (! gst_pad_try_set_caps (ladspa->srcpads[i], caps))
473         return GST_PAD_CONNECT_REFUSED;
474     }
475   }
476   
477   return GST_PAD_CONNECT_OK;
478 }
479
480 static GstPadConnectReturn 
481 gst_ladspa_connect_get (GstPad *pad, GstCaps *caps) 
482 {
483   GstLADSPA *ladspa = (GstLADSPA*)GST_OBJECT_PARENT (pad);
484   gint rate;
485  
486   g_return_val_if_fail (caps != NULL, GST_PAD_CONNECT_DELAYED);
487   g_return_val_if_fail (pad  != NULL, GST_PAD_CONNECT_DELAYED);
488   
489   if (gst_caps_get_int (caps, "rate", &rate)){
490     if (ladspa->samplerate != rate) {
491       ladspa->samplerate = rate;
492       if (! gst_ladspa_instantiate(ladspa))
493         return GST_PAD_CONNECT_REFUSED;
494     }
495   }
496
497   return GST_PAD_CONNECT_OK;
498 }
499
500 static void
501 gst_ladspa_force_src_caps(GstLADSPA *ladspa, GstPad *pad)
502 {
503   GST_DEBUG (0, "forcing caps with rate %d", ladspa->samplerate);
504   gst_pad_try_set_caps (pad, gst_caps_new (
505     "ladspa_src_caps",
506     "audio/raw",
507     gst_props_new (
508       "format",     GST_PROPS_STRING ("float"),
509       "layout",     GST_PROPS_STRING ("gfloat"),
510       "intercept",  GST_PROPS_FLOAT(0.0),
511       "slope",      GST_PROPS_FLOAT(1.0),
512       "rate",       GST_PROPS_INT (ladspa->samplerate),
513       "channels",   GST_PROPS_INT (1),
514       NULL
515     )
516   ));
517   ladspa->newcaps=FALSE;
518 }
519
520 static void
521 gst_ladspa_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec)
522 {
523   GstLADSPA *ladspa = (GstLADSPA*)object;
524   gint cid = prop_id - ARG_LAST;
525   GstLADSPAClass *oclass;
526   ladspa_control_info *control_info;
527   gfloat val=0.0;
528     
529   /* these are only registered in get mode */
530   switch (prop_id) {
531     case ARG_SAMPLERATE:
532       ladspa->samplerate = g_value_get_int (value);
533       ladspa->newcaps=TRUE;
534       break;
535     case ARG_BUFFERSIZE:
536       ladspa->buffersize = g_value_get_int (value);
537       break;
538   }
539   
540   /* is it a ladspa plugin arg? */
541   if (cid < 0) return;
542
543   oclass = (GstLADSPAClass*)(G_OBJECT_GET_CLASS (object));
544
545   /* verify it exists and is a control (not a port) */
546   g_return_if_fail(cid < oclass->numcontrols);
547   
548   control_info = &(oclass->control_info[cid]);
549   g_return_if_fail (control_info->name != NULL);
550
551   /* check to see if it's writable */
552   g_return_if_fail (control_info->writable);
553
554   /* now see what type it is */
555   if (control_info->toggled) {
556     if (g_value_get_boolean (value))
557       ladspa->controls[cid] = 1.0;
558     else
559       ladspa->controls[cid] = 0.0;
560   } else if (control_info->integer) {
561     val = (gfloat)g_value_get_int (value);
562     ladspa->controls[cid] = val;
563   } else {
564     val = g_value_get_float (value);
565     ladspa->controls[cid] = val;
566   }    
567
568   GST_DEBUG (0, "set arg %s to %f", control_info->name, ladspa->controls[cid]);
569 }
570
571 static void
572 gst_ladspa_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec)
573 {
574   GstLADSPA *ladspa = (GstLADSPA*)object;
575   gint cid = prop_id - ARG_LAST;
576   GstLADSPAClass *oclass = (GstLADSPAClass*)(G_OBJECT_GET_CLASS (object));
577   ladspa_control_info *control_info;
578
579   /* these are only registered in get mode */
580   switch (prop_id){
581     case ARG_SAMPLERATE:
582       g_value_set_int (value, ladspa->samplerate);
583       break;
584     case ARG_BUFFERSIZE:
585       g_value_set_int (value, ladspa->buffersize);
586       break;
587   }
588     
589   if (cid < 0) return;
590
591   /* verify it exists and is a control (not a port) */
592   if (cid >= oclass->numcontrols) return;
593   control_info = &(oclass->control_info[cid]);
594   if (control_info->name == NULL) return;
595
596   GST_DEBUG (0, "got arg %s as %f", control_info->name, ladspa->controls[cid]);
597
598   /* now see what type it is */
599   if (control_info->toggled) {
600     if (ladspa->controls[cid] == 1.0)
601       g_value_set_boolean (value, TRUE);
602     else
603       g_value_set_boolean (value, FALSE);
604   } else if (control_info->integer) {
605     g_value_set_int (value, (gint)ladspa->controls[cid]);
606   } else {
607     g_value_set_float (value, ladspa->controls[cid]);
608   }
609 }
610
611 static gboolean
612 gst_ladspa_instantiate (GstLADSPA *ladspa)
613 {
614   LADSPA_Descriptor *desc;
615   int i;
616   GstLADSPAClass *oclass = (GstLADSPAClass*)(G_OBJECT_GET_CLASS (ladspa));
617   gboolean was_activated;
618   
619   desc = ladspa->descriptor;
620   
621   /* check for old handle */
622   was_activated = ladspa->activated;
623   if (ladspa->handle != NULL){
624     gst_ladspa_deactivate(ladspa);
625     desc->cleanup(ladspa->handle);
626   }
627         
628   /* instantiate the plugin */ 
629   GST_DEBUG (0, "instantiating the plugin");
630   
631   ladspa->handle = desc->instantiate(desc,ladspa->samplerate);
632   g_return_val_if_fail (ladspa->handle != NULL, FALSE);
633
634   /* walk through the ports and add all the arguments */
635   for (i=0;i<oclass->numcontrols;i++) {
636     /* connect the argument to the plugin */
637     GST_DEBUG (0, "added control port %d", oclass->control_portnums[i]);
638     desc->connect_port(ladspa->handle,
639                        oclass->control_portnums[i],
640                        &(ladspa->controls[i]));
641   }
642
643   /* reactivate if it was activated before the reinstantiation */
644   if (was_activated){
645     gst_ladspa_activate(ladspa);
646   }
647   return TRUE;
648 }
649
650 static GstElementStateReturn
651 gst_ladspa_change_state (GstElement *element)
652 {
653   LADSPA_Descriptor *desc;
654   GstLADSPA *ladspa = (GstLADSPA*)element;
655   desc = ladspa->descriptor;
656
657   GST_DEBUG (0, "changing state");
658   switch (GST_STATE_TRANSITION (element)) {
659     case GST_STATE_NULL_TO_READY:
660       gst_ladspa_activate(ladspa);
661       break;
662     case GST_STATE_READY_TO_NULL:
663       gst_ladspa_deactivate(ladspa);
664       break;
665     default:
666       break;
667   }
668
669   if (GST_ELEMENT_CLASS (parent_class)->change_state)
670     return GST_ELEMENT_CLASS (parent_class)->change_state (element);
671
672   return GST_STATE_SUCCESS;
673 }
674
675 static void
676 gst_ladspa_activate(GstLADSPA *ladspa)
677 {
678   LADSPA_Descriptor *desc;
679   desc = ladspa->descriptor;
680   
681   if (ladspa->activated){
682     gst_ladspa_deactivate(ladspa);
683   }
684   
685   GST_DEBUG (0, "activating");
686
687   /* activate the plugin (function might be null) */
688   if (desc->activate != NULL) {
689     desc->activate(ladspa->handle);
690   }
691
692   ladspa->activated = TRUE;
693 }
694
695 static void
696 gst_ladspa_deactivate(GstLADSPA *ladspa)
697 {
698   LADSPA_Descriptor *desc;
699   desc = ladspa->descriptor;
700
701   GST_DEBUG (0, "deactivating");
702
703   /* deactivate the plugin (function might be null) */
704   if (ladspa->activated && (desc->deactivate != NULL)) {
705     desc->deactivate(ladspa->handle);
706   }
707
708   ladspa->activated = FALSE;
709 }
710
711 static void
712 gst_ladspa_loop(GstElement *element)
713 {
714   guint        bufferbytesize, i, numsrcpads, numsinkpads, num_empty_pads;
715   guint        num_processed, num_to_process;
716   GstEvent     *event = NULL;
717   guint32       waiting;
718   LADSPA_Data  **data_in, **data_out;
719   GstBuffer    **buffers_in, **buffers_out;
720   GstBufferPool *bufpool;
721   GstByteStream **bytestreams;
722   gboolean inplace_broken;
723  
724   GstLADSPA       *ladspa = (GstLADSPA *)element;
725   GstLADSPAClass  *oclass = (GstLADSPAClass*)(G_OBJECT_GET_CLASS (ladspa));
726   LADSPA_Descriptor *desc = ladspa->descriptor;
727
728   numsinkpads = oclass->numsinkpads;
729   numsrcpads = oclass->numsrcpads;
730   
731   data_in = g_new0(LADSPA_Data*, numsinkpads);
732   data_out = g_new0(LADSPA_Data*, numsrcpads);
733   buffers_in = g_new0(GstBuffer*, numsinkpads);
734   buffers_out = g_new0(GstBuffer*, numsrcpads);
735   bytestreams = g_new0(GstByteStream*, numsinkpads);
736   
737   bufferbytesize = sizeof (LADSPA_Data) * ladspa->buffersize;
738   
739   /* find a bufferpool */
740   bufpool = gst_buffer_pool_get_default (bufferbytesize, ladspa->numbuffers);
741
742   /* get the bytestreams for each pad */
743   for (i=0 ; i<numsinkpads ; i++){
744     bytestreams[i] = gst_bytestream_new (ladspa->sinkpads[i]);
745   }
746
747   /* since this is a loop element, we just loop here til things fall apart. */
748   do {
749     num_empty_pads = 0;
750     /* first get all the necessary data from the input ports */
751     for (i=0 ; i<numsinkpads ; i++){  
752       GST_DEBUG (0, "pulling %u bytes through channel %d'sbytestream", bufferbytesize, i);
753       buffers_in[i] = gst_bytestream_read (bytestreams[i], bufferbytesize);
754
755       if (buffers_in[i] == NULL) {
756         /* we need to check for an event. */
757         gst_bytestream_get_status (bytestreams[i], &waiting, &event);
758
759         if (event && GST_EVENT_TYPE(event) == GST_EVENT_EOS) {
760           /* if we get an EOS event from one of our sink pads, we assume that
761              pad's finished handling data. delete the bytestream, free up the
762              pad, and free up the memory associated with the input channel. */
763           GST_DEBUG (0, "got an EOS event on sinkpad %d", i);
764         }
765         /* CHECKME should maybe check for other events and try to pull more data here */
766         num_empty_pads++;
767       } else {
768         data_in[i] = (LADSPA_Data *) GST_BUFFER_DATA(buffers_in[i]);
769         GST_BUFFER_TIMESTAMP(buffers_in[i]) = ladspa->timestamp;
770       }
771     }
772
773     if (num_empty_pads > 0){
774       if (num_empty_pads < numsinkpads){
775         /* only some pads have EOS, need to create some empty buffers */
776         for (i=0 ; i<numsinkpads ; i++){
777           if (buffers_in[i] == NULL){
778             int x;
779             LADSPA_Data  *data;
780             buffers_in[i] = gst_buffer_new_from_pool (ladspa->bufpool, 0, 0);
781             GST_BUFFER_TIMESTAMP(buffers_in[i]) = ladspa->timestamp;
782             data_in[i] = data = (LADSPA_Data *) GST_BUFFER_DATA(buffers_in[i]); 
783             for (x=0 ; x < ladspa->buffersize ; x++) 
784               data[x] = 0.0F;
785
786             data_in[i] = (LADSPA_Data *) GST_BUFFER_DATA(buffers_in[i]);
787             GST_BUFFER_TIMESTAMP(buffers_in[i]) = ladspa->timestamp;
788           }
789         }
790       }
791       else {
792         /* all pads have EOS, time to quit */
793         /* CHECKME do I have to push EOS events here? */
794         GST_DEBUG (0, "All sink pads have EOS, finishing.");
795         break;
796       }
797     }
798     
799     /* we now have a full set of buffers_in.
800      * now share or create the buffers_out */
801     for (i=0 ; i<numsrcpads ; i++){
802       if (i <= numsinkpads && !inplace_broken){
803         /* we can share buffers */
804         buffers_out[i] = buffers_in[i];
805         data_out[i] = data_in[i];
806       } else {
807         buffers_out[i] = gst_buffer_new_from_pool (bufpool, 0, 0);
808         GST_BUFFER_TIMESTAMP(buffers_out[i]) = ladspa->timestamp;
809         data_out[i] = (LADSPA_Data *) GST_BUFFER_DATA(buffers_out[i]);
810       }
811     }
812
813     num_to_process = GST_DPMAN_PREPROCESS(ladspa->dpman, ladspa->buffersize, ladspa->timestamp);
814     num_processed = 0;
815
816     /* split up processing of the buffer into chunks so that dparams can
817      * be updated when required.
818      * In many cases the buffer will be processed in one chunk anyway.
819      */
820     while(GST_DPMAN_PROCESS_CHUNK(ladspa->dpman, num_to_process, num_processed)) {
821
822       for (i=0 ; i<numsinkpads ; i++){
823         desc->connect_port (ladspa->handle, oclass->sinkpad_portnums[i], data_in[i]);
824       }
825       for (i=0 ; i<numsrcpads ; i++){
826         desc->connect_port (ladspa->handle, oclass->srcpad_portnums[i], data_out[i]);
827       }
828       desc->run(ladspa->handle, num_to_process);
829       for (i=0 ; i<numsinkpads ; i++){
830         data_in[i] += num_to_process;
831       }
832       for (i=0 ; i<numsrcpads ; i++){
833         data_out[i] += num_to_process;
834       }
835
836       num_processed = num_to_process;
837       num_to_process = 0;
838     }
839     
840     for (i=0 ; i<numsrcpads ; i++) {
841       GST_DEBUG (0, "pushing buffer (%p) on src pad %d", buffers_out[i], i);
842       gst_pad_push (ladspa->srcpads[i], buffers_out[i]);
843       
844       data_out[i] = NULL;
845       buffers_out[i] = NULL;
846     }
847     for (i=0 ; i<numsinkpads ; i++) {
848       if (i > numsrcpads || inplace_broken){
849         /* we have some buffers to unref */
850         gst_buffer_unref(buffers_in[i]);
851       }
852       data_in[i] = NULL;
853       buffers_in[i] = NULL;
854     }      
855
856     ladspa->timestamp += ladspa->buffersize * 10^9 / ladspa->samplerate;
857   } while (TRUE);
858
859   gst_buffer_pool_unref(bufpool);
860
861   for (i=0 ; i<numsinkpads ; i++){
862     gst_bytestream_destroy (bytestreams[i]);
863   }
864
865   g_free (buffers_out);
866   g_free (buffers_in);
867   g_free (data_out);
868   g_free (data_in);
869   g_free (bytestreams);
870 }
871
872 static void
873 gst_ladspa_chain (GstPad *pad, GstBuffer *buf)
874 {
875   LADSPA_Descriptor *desc;
876   LADSPA_Data *data_in, **data_out;
877   GstBuffer **buffers_out;
878
879   unsigned long num_samples;
880   gboolean inplace_broken;
881   guint num_to_process, num_processed, i, numsrcpads;
882   
883   GstLADSPA *ladspa;
884   GstLADSPAClass *oclass;
885
886   g_return_if_fail(pad != NULL);
887   g_return_if_fail(GST_IS_PAD(pad));
888   g_return_if_fail(buf != NULL);
889
890   ladspa = (GstLADSPA *)gst_pad_get_parent (pad);
891   g_return_if_fail(ladspa != NULL);
892
893   /* this might happen if caps nego hasn't happened */
894   g_return_if_fail(ladspa->handle != NULL);
895
896   oclass = (GstLADSPAClass *) (G_OBJECT_GET_CLASS (ladspa));
897
898   if (GST_IS_EVENT (buf)) {    
899     /* push the event out all the src pads */
900     for (i=0 ; i<oclass->numsrcpads ; i++){
901       gst_pad_push (ladspa->srcpads[0], buf);
902     }
903     return;
904   }
905
906   data_in = (LADSPA_Data *) GST_BUFFER_DATA(buf);
907   num_samples = GST_BUFFER_SIZE(buf) / sizeof(gfloat);
908   numsrcpads = oclass->numsrcpads;
909
910   desc = ladspa->descriptor;
911
912   inplace_broken = LADSPA_IS_INPLACE_BROKEN(desc->Properties);
913   if (numsrcpads > 0){
914     guint num_created_buffers = 0; 
915     buffers_out = g_new(GstBuffer*, numsrcpads);
916     data_out = g_new(LADSPA_Data*, numsrcpads);
917
918     if (inplace_broken){
919       num_created_buffers = numsrcpads;
920     }
921     else {
922       /* we can share the buffer for input and output */
923       buffers_out[0] = buf;
924       data_out[0] = (LADSPA_Data *)GST_BUFFER_DATA(buf);
925       num_created_buffers = numsrcpads - 1;
926     }
927
928     if (num_created_buffers > 0){
929       GstBufferPool *bufpool;
930       bufpool = gst_buffer_pool_get_default (sizeof (LADSPA_Data) * GST_BUFFER_SIZE(buf), ladspa->numbuffers);
931
932       for (i = numsrcpads - num_created_buffers ; i<numsrcpads ; i++){
933         buffers_out[i] = gst_buffer_new_from_pool (ladspa->bufpool, 0, 0);
934         GST_BUFFER_TIMESTAMP(buffers_out[i]) = GST_BUFFER_TIMESTAMP(buf);
935         data_out[i] = (LADSPA_Data *) GST_BUFFER_DATA(buffers_out[i]);
936       }
937     }
938   }
939
940   num_to_process = GST_DPMAN_PREPROCESS(ladspa->dpman, num_samples, GST_BUFFER_TIMESTAMP(buf));
941   num_processed = 0;
942
943   /* split up processing of the buffer into chunks so that dparams can
944    * be updated when required.
945    * In many cases the buffer will be processed in one chunk anyway.
946    */
947   while(GST_DPMAN_PROCESS_CHUNK(ladspa->dpman, num_to_process, num_processed)) {
948     desc->connect_port(ladspa->handle,oclass->sinkpad_portnums[0],data_in);  
949     for (i=0 ; i<numsrcpads ; i++){
950       desc->connect_port(ladspa->handle,oclass->srcpad_portnums[i],data_out[i]);
951     }
952     desc->run(ladspa->handle, num_to_process);
953     
954     data_in += num_to_process;
955     for (i=0 ; i<numsrcpads ; i++){
956       data_out[i] += num_to_process;
957     }
958     num_processed += num_to_process;
959     num_to_process = 0;
960   }
961
962   if (numsrcpads > 0){
963     for (i=0 ; i<numsrcpads ; i++){
964       gst_pad_push (ladspa->srcpads[i], buffers_out[i]);
965     }
966     g_free(buffers_out);
967     g_free(data_out);
968     return;
969   }
970
971   /* if we have reached here, there are no src pads */
972   gst_buffer_unref(buf);
973 }
974
975 static GstBuffer *
976 gst_ladspa_get(GstPad *pad)
977 {  
978   GstLADSPA *ladspa;
979   GstLADSPAClass *oclass;
980
981   GstBuffer *buf;
982   LADSPA_Data *data;
983   LADSPA_Descriptor *desc;
984
985   guint num_to_process, num_processed;
986
987   g_return_val_if_fail(pad != NULL, NULL);
988   g_return_val_if_fail(GST_IS_PAD(pad), NULL);
989
990   ladspa = (GstLADSPA *)gst_pad_get_parent (pad);
991   g_return_val_if_fail(ladspa != NULL, NULL);
992
993   /* this might happen if caps nego hasn't happened */
994   g_return_val_if_fail(ladspa->handle != NULL, NULL);
995
996   oclass = (GstLADSPAClass*)(G_OBJECT_GET_CLASS(ladspa));
997
998   /* force src pad to set caps */
999   if (ladspa->newcaps) {
1000     gst_ladspa_force_src_caps(ladspa, ladspa->srcpads[0]);
1001   }
1002
1003   /* get a bufferpool */
1004   if (ladspa->bufpool == NULL) {
1005     ladspa->bufpool = gst_pad_get_bufferpool (ladspa->srcpads[0]);
1006     if (ladspa->bufpool == NULL) {
1007       ladspa->bufpool = gst_buffer_pool_get_default (sizeof (LADSPA_Data) * ladspa->buffersize, ladspa->numbuffers);
1008     }
1009   }
1010
1011   buf = gst_buffer_new_from_pool (ladspa->bufpool, 0, 0);
1012   GST_BUFFER_TIMESTAMP(buf) = ladspa->timestamp;
1013   data = (LADSPA_Data *) GST_BUFFER_DATA(buf);  
1014
1015   desc = ladspa->descriptor;
1016   num_to_process = GST_DPMAN_PREPROCESS(ladspa->dpman, ladspa->buffersize, ladspa->timestamp);
1017   num_processed = 0;
1018
1019   /* update timestamp */  
1020   ladspa->timestamp += num_to_process * 10^9 / ladspa->samplerate;
1021
1022   /* split up processing of the buffer into chunks so that dparams can
1023    * be updated when required.
1024    * In many cases the buffer will be processed in one chunk anyway.
1025    */
1026   while(GST_DPMAN_PROCESS_CHUNK(ladspa->dpman, num_to_process, num_processed)) {
1027     desc->connect_port(ladspa->handle,oclass->srcpad_portnums[0],data);  
1028     desc->run(ladspa->handle, num_to_process);
1029     
1030     data += num_to_process;
1031     num_processed = num_to_process;
1032     num_to_process = 0;
1033   }
1034   
1035   return buf;
1036 }
1037
1038 static void
1039 ladspa_describe_plugin(const char *pcFullFilename,
1040                        void *pvPluginHandle,
1041                        LADSPA_Descriptor_Function pfDescriptorFunction)
1042 {
1043   const LADSPA_Descriptor *desc;
1044   int i,j;
1045   
1046   GstElementDetails *details;
1047   GTypeInfo typeinfo = {
1048       sizeof(GstLADSPAClass),
1049       NULL,
1050       NULL,
1051       (GClassInitFunc)gst_ladspa_class_init,
1052       NULL,
1053       NULL,
1054       sizeof(GstLADSPA),
1055       0,
1056       (GInstanceInitFunc)gst_ladspa_init,
1057   };
1058   GType type;
1059   GstElementFactory *factory;
1060
1061   /* walk through all the plugins in this pluginlibrary */
1062   i = 0;
1063   while ((desc = pfDescriptorFunction(i++))) {
1064     gchar *type_name;
1065
1066     /* construct the type */
1067     type_name = g_strdup_printf("ladspa_%s",desc->Label);
1068     g_strcanon (type_name, G_CSET_A_2_Z G_CSET_a_2_z G_CSET_DIGITS "-_+", '-');
1069     /* if it's already registered, drop it */
1070     if (g_type_from_name(type_name)) {
1071       g_free(type_name);
1072       continue;
1073     }
1074     /* create the type now */
1075     type = g_type_register_static(GST_TYPE_ELEMENT, type_name, &typeinfo, 0);
1076
1077     /* construct the element details struct */
1078     details = g_new0(GstElementDetails,1);
1079     details->longname = g_strdup(desc->Name);
1080     details->klass = "Filter/LADSPA";
1081     details->description = details->longname;
1082     details->version = g_strdup_printf("%ld",desc->UniqueID);
1083     details->author = g_strdup(desc->Maker);
1084     details->copyright = g_strdup(desc->Copyright);
1085
1086     /* register the plugin with gstreamer */
1087     factory = gst_element_factory_new(type_name,type,details);
1088     g_return_if_fail(factory != NULL);
1089     gst_plugin_add_feature (ladspa_plugin, GST_PLUGIN_FEATURE (factory));
1090
1091     /* add this plugin to the hash */
1092     g_hash_table_insert(ladspa_descriptors,
1093                         GINT_TO_POINTER(type),
1094                         (gpointer)desc);
1095     
1096
1097     /* only add sink padtemplate if there are sinkpads */
1098     for (j=0;j<desc->PortCount;j++) {
1099       if (LADSPA_IS_PORT_AUDIO(desc->PortDescriptors[j]) &&
1100           LADSPA_IS_PORT_INPUT(desc->PortDescriptors[j])) {
1101         sinktempl = ladspa_sink_factory();
1102         gst_element_factory_add_pad_template (factory, sinktempl);
1103         break;
1104       }
1105     }
1106
1107     /* only add src padtemplate if there are srcpads */
1108     for (j=0;j<desc->PortCount;j++) {
1109       if (LADSPA_IS_PORT_AUDIO(desc->PortDescriptors[j]) &&
1110           LADSPA_IS_PORT_OUTPUT(desc->PortDescriptors[j])) {
1111         srctempl = ladspa_src_factory();
1112         gst_element_factory_add_pad_template (factory, srctempl);
1113         break;
1114       }
1115     }
1116
1117   }
1118 }
1119
1120 static gboolean
1121 plugin_init (GModule *module, GstPlugin *plugin)
1122 {
1123   ladspa_descriptors = g_hash_table_new(NULL,NULL);
1124   parent_class = g_type_class_ref(GST_TYPE_ELEMENT);
1125
1126   ladspa_plugin = plugin;
1127
1128   LADSPAPluginSearch(ladspa_describe_plugin);
1129
1130   if (! gst_library_load ("gstbytestream")) {
1131     gst_info ("gstladspa: could not load support library: 'gstbytestream'\n");
1132     return FALSE;
1133   }
1134   
1135   if (! gst_library_load ("gstcontrol")) {
1136     gst_info ("gstladspa: could not load support library: 'gstcontrol'\n");
1137     return FALSE;
1138   }
1139   
1140   return TRUE;
1141 }
1142
1143 GstPluginDesc plugin_desc = {
1144   GST_VERSION_MAJOR,
1145   GST_VERSION_MINOR,
1146   "ladspa",
1147   plugin_init
1148 };
1149