fix a problem in ladspa -- i think...
[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   guint32       got_bytes;
720   LADSPA_Data  **data_in, **data_out;
721   GstBuffer    **buffers_in, **buffers_out;
722   GstBufferPool *bufpool;
723   GstByteStream **bytestreams;
724  
725   GstLADSPA       *ladspa = (GstLADSPA *)element;
726   GstLADSPAClass  *oclass = (GstLADSPAClass*)(G_OBJECT_GET_CLASS (ladspa));
727   LADSPA_Descriptor *desc = ladspa->descriptor;
728
729   numsinkpads = oclass->numsinkpads;
730   numsrcpads = oclass->numsrcpads;
731   
732   data_in = g_new0(LADSPA_Data*, numsinkpads);
733   data_out = g_new0(LADSPA_Data*, numsrcpads);
734   buffers_in = g_new0(GstBuffer*, numsinkpads);
735   buffers_out = g_new0(GstBuffer*, numsrcpads);
736   bytestreams = g_new0(GstByteStream*, numsinkpads);
737   
738   bufferbytesize = sizeof (LADSPA_Data) * ladspa->buffersize;
739   
740   /* find a bufferpool */
741   bufpool = gst_buffer_pool_get_default (bufferbytesize, ladspa->numbuffers);
742
743   /* get the bytestreams for each pad */
744   for (i=0 ; i<numsinkpads ; i++){
745     bytestreams[i] = gst_bytestream_new (ladspa->sinkpads[i]);
746   }
747
748   /* since this is a loop element, we just loop here til things fall apart. */
749   do {
750     num_empty_pads = 0;
751     /* first get all the necessary data from the input ports */
752     for (i=0 ; i<numsinkpads ; i++){  
753       GST_DEBUG (0, "pulling %u bytes through channel %d'sbytestream", bufferbytesize, i);
754       got_bytes = gst_bytestream_read (bytestreams[i], buffers_in + i, bufferbytesize);
755
756       if (got_bytes != bufferbytesize) {
757         /* we need to check for an event. */
758         gst_bytestream_get_status (bytestreams[i], &waiting, &event);
759
760         if (event && GST_EVENT_TYPE(event) == GST_EVENT_EOS) {
761           /* if we get an EOS event from one of our sink pads, we assume that
762              pad's finished handling data. delete the bytestream, free up the
763              pad, and free up the memory associated with the input channel. */
764           GST_DEBUG (0, "got an EOS event on sinkpad %d", i);
765         }
766         /* CHECKME should maybe check for other events and try to pull more data here */
767         num_empty_pads++;
768       } else {
769         data_in[i] = (LADSPA_Data *) GST_BUFFER_DATA(buffers_in[i]);
770         GST_BUFFER_TIMESTAMP(buffers_in[i]) = ladspa->timestamp;
771       }
772     }
773
774     if (num_empty_pads > 0){
775       if (num_empty_pads < numsinkpads){
776         /* only some pads have EOS, need to create some empty buffers */
777         for (i=0 ; i<numsinkpads ; i++){
778           if (buffers_in[i] == NULL){
779             int x;
780             LADSPA_Data  *data;
781             buffers_in[i] = gst_buffer_new_from_pool (ladspa->bufpool, 0, 0);
782             GST_BUFFER_TIMESTAMP(buffers_in[i]) = ladspa->timestamp;
783             data_in[i] = data = (LADSPA_Data *) GST_BUFFER_DATA(buffers_in[i]); 
784             for (x=0 ; x < ladspa->buffersize ; x++) 
785               data[x] = 0.0F;
786
787             data_in[i] = (LADSPA_Data *) GST_BUFFER_DATA(buffers_in[i]);
788             GST_BUFFER_TIMESTAMP(buffers_in[i]) = ladspa->timestamp;
789           }
790         }
791       }
792       else {
793         /* all pads have EOS, time to quit */
794         /* CHECKME do I have to push EOS events here? */
795         GST_DEBUG (0, "All sink pads have EOS, finishing.");
796         break;
797       }
798     }
799     
800     /* we now have a full set of buffers_in.
801      * now share or create the buffers_out */
802     for (i=0 ; i<numsrcpads ; i++){
803       if (i <= numsinkpads && !ladspa->inplace_broken){
804         /* we can share buffers */
805         buffers_out[i] = buffers_in[i];
806         data_out[i] = data_in[i];
807       } else {
808         buffers_out[i] = gst_buffer_new_from_pool (bufpool, 0, 0);
809         GST_BUFFER_TIMESTAMP(buffers_out[i]) = ladspa->timestamp;
810         data_out[i] = (LADSPA_Data *) GST_BUFFER_DATA(buffers_out[i]);
811       }
812     }
813
814     GST_DPMAN_PREPROCESS(ladspa->dpman, ladspa->buffersize, ladspa->timestamp);
815     num_processed = 0;
816
817     /* split up processing of the buffer into chunks so that dparams can
818      * be updated when required.
819      * In many cases the buffer will be processed in one chunk anyway.
820      */
821     while(GST_DPMAN_PROCESS(ladspa->dpman, num_processed)) {
822
823       num_to_process = GST_DPMAN_FRAMES_TO_PROCESS(ladspa->dpman);
824       for (i=0 ; i<numsinkpads ; i++){
825         desc->connect_port (ladspa->handle, oclass->sinkpad_portnums[i], data_in[i]);
826       }
827       for (i=0 ; i<numsrcpads ; i++){
828         desc->connect_port (ladspa->handle, oclass->srcpad_portnums[i], data_out[i]);
829       }
830       desc->run(ladspa->handle, num_to_process);
831       for (i=0 ; i<numsinkpads ; i++){
832         data_in[i] += num_to_process;
833       }
834       for (i=0 ; i<numsrcpads ; i++){
835         data_out[i] += num_to_process;
836       }
837
838       num_processed += num_to_process;
839     }
840     
841     for (i=0 ; i<numsrcpads ; i++) {
842       GST_DEBUG (0, "pushing buffer (%p) on src pad %d", buffers_out[i], i);
843       gst_pad_push (ladspa->srcpads[i], buffers_out[i]);
844       
845       data_out[i] = NULL;
846       buffers_out[i] = NULL;
847     }
848     for (i=0 ; i<numsinkpads ; i++) {
849       if (i > numsrcpads || ladspa->inplace_broken){
850         /* we have some buffers to unref */
851         gst_buffer_unref(buffers_in[i]);
852       }
853       data_in[i] = NULL;
854       buffers_in[i] = NULL;
855     }      
856
857     ladspa->timestamp += ladspa->buffersize * 10^9 / ladspa->samplerate;
858   } while (TRUE);
859
860   gst_buffer_pool_unref(bufpool);
861
862   for (i=0 ; i<numsinkpads ; i++){
863     gst_bytestream_destroy (bytestreams[i]);
864   }
865
866   g_free (buffers_out);
867   g_free (buffers_in);
868   g_free (data_out);
869   g_free (data_in);
870   g_free (bytestreams);
871 }
872
873 static void
874 gst_ladspa_chain (GstPad *pad, GstBuffer *buf)
875 {
876   LADSPA_Descriptor *desc;
877   LADSPA_Data *data_in, **data_out = NULL;
878   GstBuffer **buffers_out = NULL;
879
880   unsigned long num_samples;
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   if (numsrcpads > 0){
913     guint num_created_buffers = 0; 
914     buffers_out = g_new(GstBuffer*, numsrcpads);
915     data_out = g_new(LADSPA_Data*, numsrcpads);
916
917     if (ladspa->inplace_broken){
918       num_created_buffers = numsrcpads;
919     }
920     else {
921       /* we can share the buffer for input and output */
922       buffers_out[0] = buf;
923       data_out[0] = (LADSPA_Data *)GST_BUFFER_DATA(buf);
924       num_created_buffers = numsrcpads - 1;
925     }
926
927     if (num_created_buffers > 0){
928       GstBufferPool *bufpool;
929       bufpool = gst_buffer_pool_get_default (sizeof (LADSPA_Data) * GST_BUFFER_SIZE(buf), ladspa->numbuffers);
930
931       for (i = numsrcpads - num_created_buffers ; i<numsrcpads ; i++){
932         buffers_out[i] = gst_buffer_new_from_pool (ladspa->bufpool, 0, 0);
933         GST_BUFFER_TIMESTAMP(buffers_out[i]) = GST_BUFFER_TIMESTAMP(buf);
934         data_out[i] = (LADSPA_Data *) GST_BUFFER_DATA(buffers_out[i]);
935       }
936     }
937   }
938
939   GST_DPMAN_PREPROCESS(ladspa->dpman, num_samples, GST_BUFFER_TIMESTAMP(buf));
940   num_processed = 0;
941
942   /* split up processing of the buffer into chunks so that dparams can
943    * be updated when required.
944    * In many cases the buffer will be processed in one chunk anyway.
945    */
946   while(GST_DPMAN_PROCESS(ladspa->dpman, num_processed)) {
947     num_to_process = GST_DPMAN_FRAMES_TO_PROCESS(ladspa->dpman);
948
949     desc->connect_port(ladspa->handle,oclass->sinkpad_portnums[0],data_in);  
950     for (i=0 ; i<numsrcpads ; i++){
951       desc->connect_port(ladspa->handle,oclass->srcpad_portnums[i],data_out[i]);
952     }
953     desc->run(ladspa->handle, num_to_process);
954     
955     data_in += num_to_process;
956     for (i=0 ; i<numsrcpads ; i++){
957       data_out[i] += num_to_process;
958     }
959     num_processed += num_to_process;
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   GST_DPMAN_PREPROCESS(ladspa->dpman, ladspa->buffersize, ladspa->timestamp);
1017   num_processed = 0;
1018
1019   /* split up processing of the buffer into chunks so that dparams can
1020    * be updated when required.
1021    * In many cases the buffer will be processed in one chunk anyway.
1022    */
1023   while(GST_DPMAN_PROCESS(ladspa->dpman, num_processed)) {
1024     num_to_process = GST_DPMAN_FRAMES_TO_PROCESS(ladspa->dpman);
1025
1026     /* update timestamp */  
1027     ladspa->timestamp += num_to_process * GST_SECOND / ladspa->samplerate;
1028
1029     desc->connect_port(ladspa->handle,oclass->srcpad_portnums[0],data);  
1030     desc->run(ladspa->handle, num_to_process);
1031     
1032     data += num_to_process;
1033     num_processed = num_to_process;
1034   }
1035   
1036   return buf;
1037 }
1038
1039 static void
1040 ladspa_describe_plugin(const char *pcFullFilename,
1041                        void *pvPluginHandle,
1042                        LADSPA_Descriptor_Function pfDescriptorFunction)
1043 {
1044   const LADSPA_Descriptor *desc;
1045   int i,j;
1046   
1047   GstElementDetails *details;
1048   GTypeInfo typeinfo = {
1049       sizeof(GstLADSPAClass),
1050       NULL,
1051       NULL,
1052       (GClassInitFunc)gst_ladspa_class_init,
1053       NULL,
1054       NULL,
1055       sizeof(GstLADSPA),
1056       0,
1057       (GInstanceInitFunc)gst_ladspa_init,
1058   };
1059   GType type;
1060   GstElementFactory *factory;
1061
1062   /* walk through all the plugins in this pluginlibrary */
1063   i = 0;
1064   while ((desc = pfDescriptorFunction(i++))) {
1065     gchar *type_name;
1066
1067     /* construct the type */
1068     type_name = g_strdup_printf("ladspa_%s",desc->Label);
1069     g_strcanon (type_name, G_CSET_A_2_Z G_CSET_a_2_z G_CSET_DIGITS "-_+", '-');
1070     /* if it's already registered, drop it */
1071     if (g_type_from_name(type_name)) {
1072       g_free(type_name);
1073       continue;
1074     }
1075     /* create the type now */
1076     type = g_type_register_static(GST_TYPE_ELEMENT, type_name, &typeinfo, 0);
1077
1078     /* construct the element details struct */
1079     details = g_new0(GstElementDetails,1);
1080     details->longname = g_strdup(desc->Name);
1081     details->klass = "Filter/Audio/LADSPA";
1082     details->description = details->longname;
1083     details->version = g_strdup_printf("%ld",desc->UniqueID);
1084     details->author = g_strdup(desc->Maker);
1085     details->copyright = g_strdup(desc->Copyright);
1086
1087     /* register the plugin with gstreamer */
1088     factory = gst_element_factory_new(type_name,type,details);
1089     g_return_if_fail(factory != NULL);
1090     gst_plugin_add_feature (ladspa_plugin, GST_PLUGIN_FEATURE (factory));
1091
1092     /* add this plugin to the hash */
1093     g_hash_table_insert(ladspa_descriptors,
1094                         GINT_TO_POINTER(type),
1095                         (gpointer)desc);
1096     
1097
1098     /* only add sink padtemplate if there are sinkpads */
1099     for (j=0;j<desc->PortCount;j++) {
1100       if (LADSPA_IS_PORT_AUDIO(desc->PortDescriptors[j]) &&
1101           LADSPA_IS_PORT_INPUT(desc->PortDescriptors[j])) {
1102         sinktempl = ladspa_sink_factory();
1103         gst_element_factory_add_pad_template (factory, sinktempl);
1104         break;
1105       }
1106     }
1107
1108     /* only add src padtemplate if there are srcpads */
1109     for (j=0;j<desc->PortCount;j++) {
1110       if (LADSPA_IS_PORT_AUDIO(desc->PortDescriptors[j]) &&
1111           LADSPA_IS_PORT_OUTPUT(desc->PortDescriptors[j])) {
1112         srctempl = ladspa_src_factory();
1113         gst_element_factory_add_pad_template (factory, srctempl);
1114         break;
1115       }
1116     }
1117
1118   }
1119 }
1120
1121 static gboolean
1122 plugin_init (GModule *module, GstPlugin *plugin)
1123 {
1124   ladspa_descriptors = g_hash_table_new(NULL,NULL);
1125   parent_class = g_type_class_ref(GST_TYPE_ELEMENT);
1126
1127   ladspa_plugin = plugin;
1128
1129   LADSPAPluginSearch(ladspa_describe_plugin);
1130
1131   if (! gst_library_load ("gstbytestream")) {
1132     gst_info ("gstladspa: could not load support library: 'gstbytestream'\n");
1133     return FALSE;
1134   }
1135   
1136   if (! gst_library_load ("gstcontrol")) {
1137     gst_info ("gstladspa: could not load support library: 'gstcontrol'\n");
1138     return FALSE;
1139   }
1140   
1141   return TRUE;
1142 }
1143
1144 GstPluginDesc plugin_desc = {
1145   GST_VERSION_MAJOR,
1146   GST_VERSION_MINOR,
1147   "ladspa",
1148   plugin_init
1149 };
1150