a hack to work around intltool's brokenness a current check for mpeg2dec details...
[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   ladspa->inplace_broken = LADSPA_IS_INPLACE_BROKEN(ladspa->descriptor->Properties);
402
403   if (sinkcount==0 && srccount == 1) {
404     /* get mode (no sink pads) */
405     GST_DEBUG (0, "mono get mode with 1 src pad");
406
407     ladspa->newcaps = TRUE;
408     ladspa->samplerate = 44100;
409     ladspa->buffersize = 64;
410
411     gst_pad_set_connect_function (ladspa->srcpads[0], gst_ladspa_connect_get);
412     gst_pad_set_get_function (ladspa->srcpads[0], gst_ladspa_get);
413
414   } else if (sinkcount==1){
415     /* with one sink we can use the chain function */
416     GST_DEBUG (0, "chain mode");
417
418     gst_pad_set_connect_function (ladspa->sinkpads[0], gst_ladspa_connect);
419     gst_pad_set_chain_function (ladspa->sinkpads[0], gst_ladspa_chain);
420     gst_pad_set_bufferpool_function (ladspa->sinkpads[0], gst_ladspa_get_bufferpool);
421   } else if (sinkcount > 1){
422     /* more than one sink pad needs loop mode */
423     GST_DEBUG (0, "loop mode with %d sink pads and %d src pads", sinkcount, srccount);
424
425     for (i=0;i<sinkcount;i++) {
426       gst_pad_set_connect_function (ladspa->sinkpads[i], gst_ladspa_connect);
427       gst_pad_set_bufferpool_function (ladspa->sinkpads[i], gst_ladspa_get_bufferpool);
428     }
429     gst_element_set_loop_function (GST_ELEMENT (ladspa), gst_ladspa_loop);
430   } 
431   else if (sinkcount==0 && srccount == 0){
432     /* for some reason these plugins exist - we'll just ignore them */
433   } else {
434     g_warning("%d sink pads, %d src pads not yet supported", sinkcount, srccount);
435   }
436
437   gst_ladspa_instantiate(ladspa);
438 }
439
440 static void
441 gst_ladspa_update_int(const GValue *value, gpointer data)
442 {
443   gfloat *target = (gfloat*) data;
444   *target = (gfloat)g_value_get_int(value);
445 }
446
447 static GstPadConnectReturn
448 gst_ladspa_connect (GstPad *pad, GstCaps *caps)
449 {
450   GstLADSPA *ladspa = (GstLADSPA *) GST_PAD_PARENT (pad);
451   GstLADSPAClass *oclass = (GstLADSPAClass *) (G_OBJECT_GET_CLASS (ladspa));
452   guint i;
453   gint rate;
454
455   g_return_val_if_fail (caps != NULL, GST_PAD_CONNECT_DELAYED);
456   g_return_val_if_fail (pad  != NULL, GST_PAD_CONNECT_DELAYED);
457
458   if (gst_caps_get_int (caps, "rate", &rate)){
459     /* have to instantiate ladspa plugin when samplerate changes (groan) */
460     if (ladspa->samplerate != rate){
461       ladspa->samplerate = rate;
462   
463       if (! gst_ladspa_instantiate(ladspa))
464         return GST_PAD_CONNECT_REFUSED;
465     }
466   }
467
468   /* if the caps are fixed, we are going to try to set all srcpads using this
469      one caps object. if any of the pads barfs, we'll refuse the connection. i'm
470      not sure if this is correct. */
471   if (GST_CAPS_IS_FIXED (caps)) {
472     for (i=0;i<oclass->numsrcpads;i++) {
473       if (! gst_pad_try_set_caps (ladspa->srcpads[i], caps))
474         return GST_PAD_CONNECT_REFUSED;
475     }
476   }
477   
478   return GST_PAD_CONNECT_OK;
479 }
480
481 static GstPadConnectReturn 
482 gst_ladspa_connect_get (GstPad *pad, GstCaps *caps) 
483 {
484   GstLADSPA *ladspa = (GstLADSPA*)GST_OBJECT_PARENT (pad);
485   gint rate;
486  
487   g_return_val_if_fail (caps != NULL, GST_PAD_CONNECT_DELAYED);
488   g_return_val_if_fail (pad  != NULL, GST_PAD_CONNECT_DELAYED);
489   
490   if (gst_caps_get_int (caps, "rate", &rate)){
491     if (ladspa->samplerate != rate) {
492       ladspa->samplerate = rate;
493       if (! gst_ladspa_instantiate(ladspa))
494         return GST_PAD_CONNECT_REFUSED;
495     }
496   }
497
498   return GST_PAD_CONNECT_OK;
499 }
500
501 static void
502 gst_ladspa_force_src_caps(GstLADSPA *ladspa, GstPad *pad)
503 {
504   GST_DEBUG (0, "forcing caps with rate %d", ladspa->samplerate);
505   gst_pad_try_set_caps (pad, gst_caps_new (
506     "ladspa_src_caps",
507     "audio/raw",
508     gst_props_new (
509       "format",     GST_PROPS_STRING ("float"),
510       "layout",     GST_PROPS_STRING ("gfloat"),
511       "intercept",  GST_PROPS_FLOAT(0.0),
512       "slope",      GST_PROPS_FLOAT(1.0),
513       "rate",       GST_PROPS_INT (ladspa->samplerate),
514       "channels",   GST_PROPS_INT (1),
515       NULL
516     )
517   ));
518   ladspa->newcaps=FALSE;
519 }
520
521 static void
522 gst_ladspa_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec)
523 {
524   GstLADSPA *ladspa = (GstLADSPA*)object;
525   gint cid = prop_id - ARG_LAST;
526   GstLADSPAClass *oclass;
527   ladspa_control_info *control_info;
528   gfloat val=0.0;
529     
530   /* these are only registered in get mode */
531   switch (prop_id) {
532     case ARG_SAMPLERATE:
533       ladspa->samplerate = g_value_get_int (value);
534       ladspa->newcaps=TRUE;
535       break;
536     case ARG_BUFFERSIZE:
537       ladspa->buffersize = g_value_get_int (value);
538       break;
539   }
540   
541   /* is it a ladspa plugin arg? */
542   if (cid < 0) return;
543
544   oclass = (GstLADSPAClass*)(G_OBJECT_GET_CLASS (object));
545
546   /* verify it exists and is a control (not a port) */
547   g_return_if_fail(cid < oclass->numcontrols);
548   
549   control_info = &(oclass->control_info[cid]);
550   g_return_if_fail (control_info->name != NULL);
551
552   /* check to see if it's writable */
553   g_return_if_fail (control_info->writable);
554
555   /* now see what type it is */
556   if (control_info->toggled) {
557     if (g_value_get_boolean (value))
558       ladspa->controls[cid] = 1.0;
559     else
560       ladspa->controls[cid] = 0.0;
561   } else if (control_info->integer) {
562     val = (gfloat)g_value_get_int (value);
563     ladspa->controls[cid] = val;
564   } else {
565     val = g_value_get_float (value);
566     ladspa->controls[cid] = val;
567   }    
568
569   GST_DEBUG (0, "set arg %s to %f", control_info->name, ladspa->controls[cid]);
570 }
571
572 static void
573 gst_ladspa_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec)
574 {
575   GstLADSPA *ladspa = (GstLADSPA*)object;
576   gint cid = prop_id - ARG_LAST;
577   GstLADSPAClass *oclass = (GstLADSPAClass*)(G_OBJECT_GET_CLASS (object));
578   ladspa_control_info *control_info;
579
580   /* these are only registered in get mode */
581   switch (prop_id){
582     case ARG_SAMPLERATE:
583       g_value_set_int (value, ladspa->samplerate);
584       break;
585     case ARG_BUFFERSIZE:
586       g_value_set_int (value, ladspa->buffersize);
587       break;
588   }
589     
590   if (cid < 0) return;
591
592   /* verify it exists and is a control (not a port) */
593   if (cid >= oclass->numcontrols) return;
594   control_info = &(oclass->control_info[cid]);
595   if (control_info->name == NULL) return;
596
597   GST_DEBUG (0, "got arg %s as %f", control_info->name, ladspa->controls[cid]);
598
599   /* now see what type it is */
600   if (control_info->toggled) {
601     if (ladspa->controls[cid] == 1.0)
602       g_value_set_boolean (value, TRUE);
603     else
604       g_value_set_boolean (value, FALSE);
605   } else if (control_info->integer) {
606     g_value_set_int (value, (gint)ladspa->controls[cid]);
607   } else {
608     g_value_set_float (value, ladspa->controls[cid]);
609   }
610 }
611
612 static gboolean
613 gst_ladspa_instantiate (GstLADSPA *ladspa)
614 {
615   LADSPA_Descriptor *desc;
616   int i;
617   GstLADSPAClass *oclass = (GstLADSPAClass*)(G_OBJECT_GET_CLASS (ladspa));
618   gboolean was_activated;
619   
620   desc = ladspa->descriptor;
621   
622   /* check for old handle */
623   was_activated = ladspa->activated;
624   if (ladspa->handle != NULL){
625     gst_ladspa_deactivate(ladspa);
626     desc->cleanup(ladspa->handle);
627   }
628         
629   /* instantiate the plugin */ 
630   GST_DEBUG (0, "instantiating the plugin");
631   
632   ladspa->handle = desc->instantiate(desc,ladspa->samplerate);
633   g_return_val_if_fail (ladspa->handle != NULL, FALSE);
634
635   /* walk through the ports and add all the arguments */
636   for (i=0;i<oclass->numcontrols;i++) {
637     /* connect the argument to the plugin */
638     GST_DEBUG (0, "added control port %d", oclass->control_portnums[i]);
639     desc->connect_port(ladspa->handle,
640                        oclass->control_portnums[i],
641                        &(ladspa->controls[i]));
642   }
643
644   /* reactivate if it was activated before the reinstantiation */
645   if (was_activated){
646     gst_ladspa_activate(ladspa);
647   }
648   return TRUE;
649 }
650
651 static GstElementStateReturn
652 gst_ladspa_change_state (GstElement *element)
653 {
654   LADSPA_Descriptor *desc;
655   GstLADSPA *ladspa = (GstLADSPA*)element;
656   desc = ladspa->descriptor;
657
658   GST_DEBUG (0, "changing state");
659   switch (GST_STATE_TRANSITION (element)) {
660     case GST_STATE_NULL_TO_READY:
661       gst_ladspa_activate(ladspa);
662       break;
663     case GST_STATE_READY_TO_NULL:
664       gst_ladspa_deactivate(ladspa);
665       break;
666     default:
667       break;
668   }
669
670   if (GST_ELEMENT_CLASS (parent_class)->change_state)
671     return GST_ELEMENT_CLASS (parent_class)->change_state (element);
672
673   return GST_STATE_SUCCESS;
674 }
675
676 static void
677 gst_ladspa_activate(GstLADSPA *ladspa)
678 {
679   LADSPA_Descriptor *desc;
680   desc = ladspa->descriptor;
681   
682   if (ladspa->activated){
683     gst_ladspa_deactivate(ladspa);
684   }
685   
686   GST_DEBUG (0, "activating");
687
688   /* activate the plugin (function might be null) */
689   if (desc->activate != NULL) {
690     desc->activate(ladspa->handle);
691   }
692
693   ladspa->activated = TRUE;
694 }
695
696 static void
697 gst_ladspa_deactivate(GstLADSPA *ladspa)
698 {
699   LADSPA_Descriptor *desc;
700   desc = ladspa->descriptor;
701
702   GST_DEBUG (0, "deactivating");
703
704   /* deactivate the plugin (function might be null) */
705   if (ladspa->activated && (desc->deactivate != NULL)) {
706     desc->deactivate(ladspa->handle);
707   }
708
709   ladspa->activated = FALSE;
710 }
711
712 static void
713 gst_ladspa_loop(GstElement *element)
714 {
715   guint        bufferbytesize, i, numsrcpads, numsinkpads, num_empty_pads;
716   guint        num_processed, num_to_process;
717   GstEvent     *event = NULL;
718   guint32       waiting;
719   LADSPA_Data  **data_in, **data_out;
720   GstBuffer    **buffers_in, **buffers_out;
721   GstBufferPool *bufpool;
722   GstByteStream **bytestreams;
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 && !ladspa->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 || ladspa->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 = NULL;
877   GstBuffer **buffers_out = NULL;
878
879   unsigned long num_samples;
880   guint num_to_process, num_processed, i, numsrcpads;
881   
882   GstLADSPA *ladspa;
883   GstLADSPAClass *oclass;
884
885   g_return_if_fail(pad != NULL);
886   g_return_if_fail(GST_IS_PAD(pad));
887   g_return_if_fail(buf != NULL);
888
889   ladspa = (GstLADSPA *)gst_pad_get_parent (pad);
890   g_return_if_fail(ladspa != NULL);
891
892   /* this might happen if caps nego hasn't happened */
893   g_return_if_fail(ladspa->handle != NULL);
894
895   oclass = (GstLADSPAClass *) (G_OBJECT_GET_CLASS (ladspa));
896
897   if (GST_IS_EVENT (buf)) {    
898     /* push the event out all the src pads */
899     for (i=0 ; i<oclass->numsrcpads ; i++){
900       gst_pad_push (ladspa->srcpads[0], buf);
901     }
902     return;
903   }
904
905   data_in = (LADSPA_Data *) GST_BUFFER_DATA(buf);
906   num_samples = GST_BUFFER_SIZE(buf) / sizeof(gfloat);
907   numsrcpads = oclass->numsrcpads;
908
909   desc = ladspa->descriptor;
910
911   if (numsrcpads > 0){
912     guint num_created_buffers = 0; 
913     buffers_out = g_new(GstBuffer*, numsrcpads);
914     data_out = g_new(LADSPA_Data*, numsrcpads);
915
916     if (ladspa->inplace_broken){
917       num_created_buffers = numsrcpads;
918     }
919     else {
920       /* we can share the buffer for input and output */
921       buffers_out[0] = buf;
922       data_out[0] = (LADSPA_Data *)GST_BUFFER_DATA(buf);
923       num_created_buffers = numsrcpads - 1;
924     }
925
926     if (num_created_buffers > 0){
927       GstBufferPool *bufpool;
928       bufpool = gst_buffer_pool_get_default (sizeof (LADSPA_Data) * GST_BUFFER_SIZE(buf), ladspa->numbuffers);
929
930       for (i = numsrcpads - num_created_buffers ; i<numsrcpads ; i++){
931         buffers_out[i] = gst_buffer_new_from_pool (ladspa->bufpool, 0, 0);
932         GST_BUFFER_TIMESTAMP(buffers_out[i]) = GST_BUFFER_TIMESTAMP(buf);
933         data_out[i] = (LADSPA_Data *) GST_BUFFER_DATA(buffers_out[i]);
934       }
935     }
936   }
937
938   num_to_process = GST_DPMAN_PREPROCESS(ladspa->dpman, num_samples, GST_BUFFER_TIMESTAMP(buf));
939   num_processed = 0;
940
941   /* split up processing of the buffer into chunks so that dparams can
942    * be updated when required.
943    * In many cases the buffer will be processed in one chunk anyway.
944    */
945   while(GST_DPMAN_PROCESS_CHUNK(ladspa->dpman, num_to_process, num_processed)) {
946     desc->connect_port(ladspa->handle,oclass->sinkpad_portnums[0],data_in);  
947     for (i=0 ; i<numsrcpads ; i++){
948       desc->connect_port(ladspa->handle,oclass->srcpad_portnums[i],data_out[i]);
949     }
950     desc->run(ladspa->handle, num_to_process);
951     
952     data_in += num_to_process;
953     for (i=0 ; i<numsrcpads ; i++){
954       data_out[i] += num_to_process;
955     }
956     num_processed += num_to_process;
957     num_to_process = 0;
958   }
959
960   if (numsrcpads > 0){
961     for (i=0 ; i<numsrcpads ; i++){
962       gst_pad_push (ladspa->srcpads[i], buffers_out[i]);
963     }
964     g_free(buffers_out);
965     g_free(data_out);
966     return;
967   }
968
969   /* if we have reached here, there are no src pads */
970   gst_buffer_unref(buf);
971 }
972
973 static GstBuffer *
974 gst_ladspa_get(GstPad *pad)
975 {  
976   GstLADSPA *ladspa;
977   GstLADSPAClass *oclass;
978
979   GstBuffer *buf;
980   LADSPA_Data *data;
981   LADSPA_Descriptor *desc;
982
983   guint num_to_process, num_processed;
984
985   g_return_val_if_fail(pad != NULL, NULL);
986   g_return_val_if_fail(GST_IS_PAD(pad), NULL);
987
988   ladspa = (GstLADSPA *)gst_pad_get_parent (pad);
989   g_return_val_if_fail(ladspa != NULL, NULL);
990
991   /* this might happen if caps nego hasn't happened */
992   g_return_val_if_fail(ladspa->handle != NULL, NULL);
993
994   oclass = (GstLADSPAClass*)(G_OBJECT_GET_CLASS(ladspa));
995
996   /* force src pad to set caps */
997   if (ladspa->newcaps) {
998     gst_ladspa_force_src_caps(ladspa, ladspa->srcpads[0]);
999   }
1000
1001   /* get a bufferpool */
1002   if (ladspa->bufpool == NULL) {
1003     ladspa->bufpool = gst_pad_get_bufferpool (ladspa->srcpads[0]);
1004     if (ladspa->bufpool == NULL) {
1005       ladspa->bufpool = gst_buffer_pool_get_default (sizeof (LADSPA_Data) * ladspa->buffersize, ladspa->numbuffers);
1006     }
1007   }
1008
1009   buf = gst_buffer_new_from_pool (ladspa->bufpool, 0, 0);
1010   GST_BUFFER_TIMESTAMP(buf) = ladspa->timestamp;
1011   data = (LADSPA_Data *) GST_BUFFER_DATA(buf);  
1012
1013   desc = ladspa->descriptor;
1014   num_to_process = GST_DPMAN_PREPROCESS(ladspa->dpman, ladspa->buffersize, ladspa->timestamp);
1015   num_processed = 0;
1016
1017   /* update timestamp */  
1018   ladspa->timestamp += num_to_process * 10^9 / ladspa->samplerate;
1019
1020   /* split up processing of the buffer into chunks so that dparams can
1021    * be updated when required.
1022    * In many cases the buffer will be processed in one chunk anyway.
1023    */
1024   while(GST_DPMAN_PROCESS_CHUNK(ladspa->dpman, num_to_process, num_processed)) {
1025     desc->connect_port(ladspa->handle,oclass->srcpad_portnums[0],data);  
1026     desc->run(ladspa->handle, num_to_process);
1027     
1028     data += num_to_process;
1029     num_processed = num_to_process;
1030     num_to_process = 0;
1031   }
1032   
1033   return buf;
1034 }
1035
1036 static void
1037 ladspa_describe_plugin(const char *pcFullFilename,
1038                        void *pvPluginHandle,
1039                        LADSPA_Descriptor_Function pfDescriptorFunction)
1040 {
1041   const LADSPA_Descriptor *desc;
1042   int i,j;
1043   
1044   GstElementDetails *details;
1045   GTypeInfo typeinfo = {
1046       sizeof(GstLADSPAClass),
1047       NULL,
1048       NULL,
1049       (GClassInitFunc)gst_ladspa_class_init,
1050       NULL,
1051       NULL,
1052       sizeof(GstLADSPA),
1053       0,
1054       (GInstanceInitFunc)gst_ladspa_init,
1055   };
1056   GType type;
1057   GstElementFactory *factory;
1058
1059   /* walk through all the plugins in this pluginlibrary */
1060   i = 0;
1061   while ((desc = pfDescriptorFunction(i++))) {
1062     gchar *type_name;
1063
1064     /* construct the type */
1065     type_name = g_strdup_printf("ladspa_%s",desc->Label);
1066     g_strcanon (type_name, G_CSET_A_2_Z G_CSET_a_2_z G_CSET_DIGITS "-_+", '-');
1067     /* if it's already registered, drop it */
1068     if (g_type_from_name(type_name)) {
1069       g_free(type_name);
1070       continue;
1071     }
1072     /* create the type now */
1073     type = g_type_register_static(GST_TYPE_ELEMENT, type_name, &typeinfo, 0);
1074
1075     /* construct the element details struct */
1076     details = g_new0(GstElementDetails,1);
1077     details->longname = g_strdup(desc->Name);
1078     details->klass = "Filter/Audio/LADSPA";
1079     details->description = details->longname;
1080     details->version = g_strdup_printf("%ld",desc->UniqueID);
1081     details->author = g_strdup(desc->Maker);
1082     details->copyright = g_strdup(desc->Copyright);
1083
1084     /* register the plugin with gstreamer */
1085     factory = gst_element_factory_new(type_name,type,details);
1086     g_return_if_fail(factory != NULL);
1087     gst_plugin_add_feature (ladspa_plugin, GST_PLUGIN_FEATURE (factory));
1088
1089     /* add this plugin to the hash */
1090     g_hash_table_insert(ladspa_descriptors,
1091                         GINT_TO_POINTER(type),
1092                         (gpointer)desc);
1093     
1094
1095     /* only add sink padtemplate if there are sinkpads */
1096     for (j=0;j<desc->PortCount;j++) {
1097       if (LADSPA_IS_PORT_AUDIO(desc->PortDescriptors[j]) &&
1098           LADSPA_IS_PORT_INPUT(desc->PortDescriptors[j])) {
1099         sinktempl = ladspa_sink_factory();
1100         gst_element_factory_add_pad_template (factory, sinktempl);
1101         break;
1102       }
1103     }
1104
1105     /* only add src padtemplate if there are srcpads */
1106     for (j=0;j<desc->PortCount;j++) {
1107       if (LADSPA_IS_PORT_AUDIO(desc->PortDescriptors[j]) &&
1108           LADSPA_IS_PORT_OUTPUT(desc->PortDescriptors[j])) {
1109         srctempl = ladspa_src_factory();
1110         gst_element_factory_add_pad_template (factory, srctempl);
1111         break;
1112       }
1113     }
1114
1115   }
1116 }
1117
1118 static gboolean
1119 plugin_init (GModule *module, GstPlugin *plugin)
1120 {
1121   ladspa_descriptors = g_hash_table_new(NULL,NULL);
1122   parent_class = g_type_class_ref(GST_TYPE_ELEMENT);
1123
1124   ladspa_plugin = plugin;
1125
1126   LADSPAPluginSearch(ladspa_describe_plugin);
1127
1128   if (! gst_library_load ("gstbytestream")) {
1129     gst_info ("gstladspa: could not load support library: 'gstbytestream'\n");
1130     return FALSE;
1131   }
1132   
1133   if (! gst_library_load ("gstcontrol")) {
1134     gst_info ("gstladspa: could not load support library: 'gstcontrol'\n");
1135     return FALSE;
1136   }
1137   
1138   return TRUE;
1139 }
1140
1141 GstPluginDesc plugin_desc = {
1142   GST_VERSION_MAJOR,
1143   GST_VERSION_MINOR,
1144   "ladspa",
1145   plugin_init
1146 };
1147