use new bytestream api
[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     num_to_process = 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_CHUNK(ladspa->dpman, num_to_process, num_processed)) {
822
823       for (i=0 ; i<numsinkpads ; i++){
824         desc->connect_port (ladspa->handle, oclass->sinkpad_portnums[i], data_in[i]);
825       }
826       for (i=0 ; i<numsrcpads ; i++){
827         desc->connect_port (ladspa->handle, oclass->srcpad_portnums[i], data_out[i]);
828       }
829       desc->run(ladspa->handle, num_to_process);
830       for (i=0 ; i<numsinkpads ; i++){
831         data_in[i] += num_to_process;
832       }
833       for (i=0 ; i<numsrcpads ; i++){
834         data_out[i] += num_to_process;
835       }
836
837       num_processed = num_to_process;
838       num_to_process = 0;
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   num_to_process = 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_CHUNK(ladspa->dpman, num_to_process, num_processed)) {
947     desc->connect_port(ladspa->handle,oclass->sinkpad_portnums[0],data_in);  
948     for (i=0 ; i<numsrcpads ; i++){
949       desc->connect_port(ladspa->handle,oclass->srcpad_portnums[i],data_out[i]);
950     }
951     desc->run(ladspa->handle, num_to_process);
952     
953     data_in += num_to_process;
954     for (i=0 ; i<numsrcpads ; i++){
955       data_out[i] += num_to_process;
956     }
957     num_processed += num_to_process;
958     num_to_process = 0;
959   }
960
961   if (numsrcpads > 0){
962     for (i=0 ; i<numsrcpads ; i++){
963       gst_pad_push (ladspa->srcpads[i], buffers_out[i]);
964     }
965     g_free(buffers_out);
966     g_free(data_out);
967     return;
968   }
969
970   /* if we have reached here, there are no src pads */
971   gst_buffer_unref(buf);
972 }
973
974 static GstBuffer *
975 gst_ladspa_get(GstPad *pad)
976 {  
977   GstLADSPA *ladspa;
978   GstLADSPAClass *oclass;
979
980   GstBuffer *buf;
981   LADSPA_Data *data;
982   LADSPA_Descriptor *desc;
983
984   guint num_to_process, num_processed;
985
986   g_return_val_if_fail(pad != NULL, NULL);
987   g_return_val_if_fail(GST_IS_PAD(pad), NULL);
988
989   ladspa = (GstLADSPA *)gst_pad_get_parent (pad);
990   g_return_val_if_fail(ladspa != NULL, NULL);
991
992   /* this might happen if caps nego hasn't happened */
993   g_return_val_if_fail(ladspa->handle != NULL, NULL);
994
995   oclass = (GstLADSPAClass*)(G_OBJECT_GET_CLASS(ladspa));
996
997   /* force src pad to set caps */
998   if (ladspa->newcaps) {
999     gst_ladspa_force_src_caps(ladspa, ladspa->srcpads[0]);
1000   }
1001
1002   /* get a bufferpool */
1003   if (ladspa->bufpool == NULL) {
1004     ladspa->bufpool = gst_pad_get_bufferpool (ladspa->srcpads[0]);
1005     if (ladspa->bufpool == NULL) {
1006       ladspa->bufpool = gst_buffer_pool_get_default (sizeof (LADSPA_Data) * ladspa->buffersize, ladspa->numbuffers);
1007     }
1008   }
1009
1010   buf = gst_buffer_new_from_pool (ladspa->bufpool, 0, 0);
1011   GST_BUFFER_TIMESTAMP(buf) = ladspa->timestamp;
1012   data = (LADSPA_Data *) GST_BUFFER_DATA(buf);  
1013
1014   desc = ladspa->descriptor;
1015   num_to_process = GST_DPMAN_PREPROCESS(ladspa->dpman, ladspa->buffersize, ladspa->timestamp);
1016   num_processed = 0;
1017
1018   /* update timestamp */  
1019   ladspa->timestamp += num_to_process * 10^9 / ladspa->samplerate;
1020
1021   /* split up processing of the buffer into chunks so that dparams can
1022    * be updated when required.
1023    * In many cases the buffer will be processed in one chunk anyway.
1024    */
1025   while(GST_DPMAN_PROCESS_CHUNK(ladspa->dpman, num_to_process, num_processed)) {
1026     desc->connect_port(ladspa->handle,oclass->srcpad_portnums[0],data);  
1027     desc->run(ladspa->handle, num_to_process);
1028     
1029     data += num_to_process;
1030     num_processed = num_to_process;
1031     num_to_process = 0;
1032   }
1033   
1034   return buf;
1035 }
1036
1037 static void
1038 ladspa_describe_plugin(const char *pcFullFilename,
1039                        void *pvPluginHandle,
1040                        LADSPA_Descriptor_Function pfDescriptorFunction)
1041 {
1042   const LADSPA_Descriptor *desc;
1043   int i,j;
1044   
1045   GstElementDetails *details;
1046   GTypeInfo typeinfo = {
1047       sizeof(GstLADSPAClass),
1048       NULL,
1049       NULL,
1050       (GClassInitFunc)gst_ladspa_class_init,
1051       NULL,
1052       NULL,
1053       sizeof(GstLADSPA),
1054       0,
1055       (GInstanceInitFunc)gst_ladspa_init,
1056   };
1057   GType type;
1058   GstElementFactory *factory;
1059
1060   /* walk through all the plugins in this pluginlibrary */
1061   i = 0;
1062   while ((desc = pfDescriptorFunction(i++))) {
1063     gchar *type_name;
1064
1065     /* construct the type */
1066     type_name = g_strdup_printf("ladspa_%s",desc->Label);
1067     g_strcanon (type_name, G_CSET_A_2_Z G_CSET_a_2_z G_CSET_DIGITS "-_+", '-');
1068     /* if it's already registered, drop it */
1069     if (g_type_from_name(type_name)) {
1070       g_free(type_name);
1071       continue;
1072     }
1073     /* create the type now */
1074     type = g_type_register_static(GST_TYPE_ELEMENT, type_name, &typeinfo, 0);
1075
1076     /* construct the element details struct */
1077     details = g_new0(GstElementDetails,1);
1078     details->longname = g_strdup(desc->Name);
1079     details->klass = "Filter/Audio/LADSPA";
1080     details->description = details->longname;
1081     details->version = g_strdup_printf("%ld",desc->UniqueID);
1082     details->author = g_strdup(desc->Maker);
1083     details->copyright = g_strdup(desc->Copyright);
1084
1085     /* register the plugin with gstreamer */
1086     factory = gst_element_factory_new(type_name,type,details);
1087     g_return_if_fail(factory != NULL);
1088     gst_plugin_add_feature (ladspa_plugin, GST_PLUGIN_FEATURE (factory));
1089
1090     /* add this plugin to the hash */
1091     g_hash_table_insert(ladspa_descriptors,
1092                         GINT_TO_POINTER(type),
1093                         (gpointer)desc);
1094     
1095
1096     /* only add sink padtemplate if there are sinkpads */
1097     for (j=0;j<desc->PortCount;j++) {
1098       if (LADSPA_IS_PORT_AUDIO(desc->PortDescriptors[j]) &&
1099           LADSPA_IS_PORT_INPUT(desc->PortDescriptors[j])) {
1100         sinktempl = ladspa_sink_factory();
1101         gst_element_factory_add_pad_template (factory, sinktempl);
1102         break;
1103       }
1104     }
1105
1106     /* only add src padtemplate if there are srcpads */
1107     for (j=0;j<desc->PortCount;j++) {
1108       if (LADSPA_IS_PORT_AUDIO(desc->PortDescriptors[j]) &&
1109           LADSPA_IS_PORT_OUTPUT(desc->PortDescriptors[j])) {
1110         srctempl = ladspa_src_factory();
1111         gst_element_factory_add_pad_template (factory, srctempl);
1112         break;
1113       }
1114     }
1115
1116   }
1117 }
1118
1119 static gboolean
1120 plugin_init (GModule *module, GstPlugin *plugin)
1121 {
1122   ladspa_descriptors = g_hash_table_new(NULL,NULL);
1123   parent_class = g_type_class_ref(GST_TYPE_ELEMENT);
1124
1125   ladspa_plugin = plugin;
1126
1127   LADSPAPluginSearch(ladspa_describe_plugin);
1128
1129   if (! gst_library_load ("gstbytestream")) {
1130     gst_info ("gstladspa: could not load support library: 'gstbytestream'\n");
1131     return FALSE;
1132   }
1133   
1134   if (! gst_library_load ("gstcontrol")) {
1135     gst_info ("gstladspa: could not load support library: 'gstcontrol'\n");
1136     return FALSE;
1137   }
1138   
1139   return TRUE;
1140 }
1141
1142 GstPluginDesc plugin_desc = {
1143   GST_VERSION_MAJOR,
1144   GST_VERSION_MINOR,
1145   "ladspa",
1146   plugin_init
1147 };
1148