added ladspa, doesn't have checks yet though
[platform/upstream/gst-plugins-good.git] / ext / ladspa / gstladspa.c
1 /* GStreamer
2  * Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
3  *               <2001> Steve Baker <stevebaker_org@yahoo.co.uk>
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Library General Public
7  * License as published by the Free Software Foundation; either
8  * version 2 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Library General Public License for more details.
14  *
15  * You should have received a copy of the GNU Library General Public
16  * License along with this library; if not, write to the
17  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18  * Boston, MA 02111-1307, USA.
19  */
20
21 #include <string.h>
22 #include <math.h>
23
24 //#define DEBUG_ENABLED
25 #include "gstladspa.h"
26 #include "ladspa.h"
27 #include "search.h"
28 #include "utils.h"
29
30
31 static GstPadTemplate* 
32 ladspa_src_factory (void)
33 {
34   return 
35     gst_padtemplate_new (
36     "src",
37     GST_PAD_SRC,
38     GST_PAD_ALWAYS,
39     gst_caps_new (
40     "ladspa_src",
41       "audio/raw",
42       gst_props_new (
43         "format",     GST_PROPS_STRING ("float"),
44         "layout",     GST_PROPS_STRING ("gfloat"),
45         "intercept",  GST_PROPS_FLOAT(0.0),
46         "slope",      GST_PROPS_FLOAT(1.0),
47         "channels",   GST_PROPS_INT (1),
48         "rate",       GST_PROPS_INT_RANGE (0,G_MAXINT),
49       NULL)),
50     NULL);
51 }
52
53 static GstPadTemplate* 
54 ladspa_sink_factory (void) 
55 {
56   return 
57     gst_padtemplate_new (
58       "sink",
59       GST_PAD_SINK,
60       GST_PAD_ALWAYS,
61       gst_caps_new (
62       "float2int_sink",
63         "audio/raw",
64         gst_props_new (
65           "format",     GST_PROPS_STRING ("float"),
66           "layout",     GST_PROPS_STRING ("gfloat"),
67           "intercept",  GST_PROPS_FLOAT(0.0),
68           "slope",      GST_PROPS_FLOAT(1.0),
69           "channels",   GST_PROPS_INT (1),
70           "rate",       GST_PROPS_INT_RANGE (0,G_MAXINT),
71       NULL)),
72     NULL);
73 }
74
75 enum {
76   ARG_0,
77   ARG_LOOP_BASED,
78   ARG_SAMPLERATE,
79   ARG_BUFFERSIZE,
80   ARG_LAST,
81 };
82
83 static GstPadTemplate *srctempl, *sinktempl;
84
85 static void                     gst_ladspa_class_init           (GstLADSPAClass *klass);
86 static void                     gst_ladspa_init                 (GstLADSPA *ladspa);
87
88 static GstPadNegotiateReturn gst_ladspa_negotiate_sink_mono (GstPad *pad, GstCaps **caps, gpointer *data);
89 static GstPadNegotiateReturn gst_ladspa_negotiate_src_mono (GstPad *pad, GstCaps **caps, gpointer *data);
90 static GstPadNegotiateReturn gst_ladspa_negotiate_src_get_mono (GstPad *pad, GstCaps **caps, gpointer *data);
91 static void gst_ladspa_force_caps(GstLADSPA *ladspa, GstPad *pad);
92
93 static void                     gst_ladspa_set_property         (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec);
94 static void                     gst_ladspa_get_property         (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec);
95
96 static gboolean gst_ladspa_instantiate (GstLADSPA *ladspa);
97 static void gst_ladspa_activate(GstLADSPA *ladspa);
98 static void gst_ladspa_deactivate(GstLADSPA *ladspa);
99
100 static GstElementStateReturn    gst_ladspa_change_state         (GstElement *element);
101 static void                     gst_ladspa_loop                 (GstElement *element);
102 static void      gst_ladspa_chain_inplace_mono (GstPad *pad,GstBuffer *buf);
103 static GstBuffer * gst_ladspa_get_mono(GstPad *pad);
104 static GstBuffer * gst_ladspa_get(GstPad *pad);
105
106 static GstElementClass *parent_class = NULL;
107 //static guint gst_ladspa_signals[LAST_SIGNAL] = { 0 };
108
109 static GstPlugin *ladspa_plugin;
110 static GHashTable *ladspa_descriptors;
111
112 static void
113 gst_ladspa_class_init (GstLADSPAClass *klass)
114 {
115   GObjectClass *gobject_class;
116   GstElementClass *gstelement_class;
117   LADSPA_Descriptor *desc;
118   gint i,current_portnum,sinkcount,srccount,controlcount;
119   gint hintdesc;
120   gint argtype,argperms;
121   GParamSpec *paramspec = NULL;
122   gchar *argname;
123
124   gobject_class = (GObjectClass*)klass;
125   gstelement_class = (GstElementClass*)klass;
126
127   gobject_class->set_property = gst_ladspa_set_property;
128   gobject_class->get_property = gst_ladspa_get_property;
129
130   gstelement_class->change_state = gst_ladspa_change_state;
131
132   g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_LOOP_BASED,
133     g_param_spec_boolean("loop-based","loop-based","loop-based",
134                          FALSE,G_PARAM_READWRITE));
135
136   // look up and store the ladspa descriptor
137   klass->descriptor = g_hash_table_lookup(ladspa_descriptors,GINT_TO_POINTER(G_TYPE_FROM_CLASS(klass)));
138   desc = klass->descriptor;
139
140   klass->numports = desc->PortCount;
141
142   klass->numsinkpads = 0;
143   klass->numsrcpads = 0;
144   klass->numcontrols = 0;
145
146   // walk through the ports, count the input, output and control ports
147   for (i=0;i<desc->PortCount;i++) {
148     if (LADSPA_IS_PORT_AUDIO(desc->PortDescriptors[i]) && 
149         LADSPA_IS_PORT_INPUT(desc->PortDescriptors[i])){
150       klass->numsinkpads++;
151     }
152       
153     if (LADSPA_IS_PORT_AUDIO(desc->PortDescriptors[i]) && 
154         LADSPA_IS_PORT_OUTPUT(desc->PortDescriptors[i])){
155       klass->numsrcpads++;
156     }
157       
158     if (LADSPA_IS_PORT_CONTROL(desc->PortDescriptors[i]) && 
159         LADSPA_IS_PORT_INPUT(desc->PortDescriptors[i])){
160       klass->numcontrols++;
161     }
162   }
163
164   klass->srcpad_portnums = g_new0(gint,klass->numsrcpads);
165   klass->sinkpad_portnums = g_new0(gint,klass->numsinkpads);
166   klass->control_portnums = g_new0(gint,klass->numcontrols);
167   sinkcount = 0;
168   srccount = 0;
169   controlcount = 0;
170
171   // walk through the ports, note the portnums for srcpads, sinkpads and control params
172   for (i=0;i<desc->PortCount;i++) {
173     if (LADSPA_IS_PORT_AUDIO(desc->PortDescriptors[i]) && 
174         LADSPA_IS_PORT_INPUT(desc->PortDescriptors[i])){
175       //g_print("input port %d\n", i);
176       klass->sinkpad_portnums[sinkcount++] = i;
177     }
178       
179     if (LADSPA_IS_PORT_AUDIO(desc->PortDescriptors[i]) && 
180         LADSPA_IS_PORT_OUTPUT(desc->PortDescriptors[i])){
181       //g_print("output port %d\n", i);
182       klass->srcpad_portnums[srccount++] = i;
183     }
184       
185     if (LADSPA_IS_PORT_CONTROL(desc->PortDescriptors[i]) && 
186         LADSPA_IS_PORT_INPUT(desc->PortDescriptors[i])){
187       //g_print("control port %d\n", i);
188       klass->control_portnums[controlcount++] = i;
189     }
190   }
191
192   // no sink pads - we'll use get mode and add params for samplerate and buffersize
193   if (klass->numsinkpads == 0 && klass->numsrcpads > 0){
194     g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_SAMPLERATE,
195       g_param_spec_int("samplerate","samplerate","samplerate",
196                       0,G_MAXINT,44100,G_PARAM_READWRITE));
197     g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_BUFFERSIZE,
198       g_param_spec_int("buffersize","buffersize","buffersize",
199                       0,G_MAXINT,64,G_PARAM_READWRITE));
200
201   }
202   
203   // now build the contorl info from the control ports
204   klass->control_info = g_new0(ladspa_control_info,klass->numcontrols);
205     
206   for (i=0;i<klass->numcontrols;i++) {
207
208     current_portnum = klass->control_portnums[i];
209     
210     // short name for hint descriptor
211     hintdesc = desc->PortRangeHints[current_portnum].HintDescriptor;
212
213     // get the various bits
214     if (LADSPA_IS_HINT_TOGGLED(hintdesc))
215       klass->control_info[i].toggled = TRUE;
216     if (LADSPA_IS_HINT_LOGARITHMIC(hintdesc))
217       klass->control_info[i].logarithmic = TRUE;
218     if (LADSPA_IS_HINT_INTEGER(hintdesc))
219       klass->control_info[i].integer = TRUE;
220
221     // figure out the argument details
222     if (klass->control_info[i].toggled) argtype = G_TYPE_BOOLEAN;
223     else if (klass->control_info[i].integer) argtype = G_TYPE_INT;
224     else argtype = G_TYPE_FLOAT;
225
226     // grab the bounds
227     if (LADSPA_IS_HINT_BOUNDED_BELOW(hintdesc)) {
228       klass->control_info[i].lower = TRUE;
229       klass->control_info[i].lowerbound =
230         desc->PortRangeHints[current_portnum].LowerBound;
231     } else {
232       if (argtype==G_TYPE_INT) klass->control_info[i].lowerbound = (gfloat)G_MININT;
233       if (argtype==G_TYPE_FLOAT) klass->control_info[i].lowerbound = G_MINFLOAT;
234     }
235     
236     if (LADSPA_IS_HINT_BOUNDED_ABOVE(hintdesc)) {
237       klass->control_info[i].upper = TRUE;
238       klass->control_info[i].upperbound =
239         desc->PortRangeHints[current_portnum].UpperBound;
240       if (LADSPA_IS_HINT_SAMPLE_RATE(hintdesc))
241         klass->control_info[i].samplerate = TRUE;
242     } else {
243       if (argtype==G_TYPE_INT) klass->control_info[i].upperbound = (gfloat)G_MAXINT;
244       if (argtype==G_TYPE_FLOAT) klass->control_info[i].upperbound = G_MAXFLOAT;
245     }
246
247     if (LADSPA_IS_PORT_INPUT(desc->PortDescriptors[current_portnum])) {
248       argperms = G_PARAM_READWRITE;
249       klass->control_info[i].writable = TRUE;
250     } else {
251       argperms = G_PARAM_READABLE;
252       klass->control_info[i].writable = FALSE;
253     }
254
255     klass->control_info[i].name = g_strdup(desc->PortNames[current_portnum]);
256     argname = g_strdup(klass->control_info[i].name);
257     // this is the same thing that param_spec_* will do
258     g_strcanon (argname, G_CSET_A_2_Z G_CSET_a_2_z G_CSET_DIGITS "-", '-');
259     
260     // check for duplicate property names
261     if (g_object_class_find_property(G_OBJECT_CLASS(klass), argname) != NULL){
262       gint numarg=1;
263       gchar *numargname = g_strdup_printf("%s_%d",argname,numarg++);
264       while (g_object_class_find_property(G_OBJECT_CLASS(klass), numargname) != NULL){
265         g_free(numargname);
266         numargname = g_strdup_printf("%s_%d",argname,numarg++);
267       }
268       argname = numargname;
269     }
270     
271     if (argtype==G_TYPE_BOOLEAN){
272       paramspec = g_param_spec_boolean(argname,argname,argname, FALSE, argperms);
273     } else if (argtype==G_TYPE_INT){      
274       paramspec = g_param_spec_int(argname,argname,argname, 
275         (gint)klass->control_info[i].lowerbound, (gint)klass->control_info[i].upperbound, 0, argperms);
276     } else {
277       paramspec = g_param_spec_float(argname,argname,argname, 
278         klass->control_info[i].lowerbound, klass->control_info[i].upperbound, 
279         (klass->control_info[i].lowerbound + klass->control_info[i].upperbound) / 2.0f, argperms);
280     }
281     g_object_class_install_property(G_OBJECT_CLASS(klass), i+ARG_LAST, paramspec);
282     
283     g_print("added arg %s from %s\n",argname, klass->control_info[i].name);
284   }
285 }
286
287 static void
288 gst_ladspa_init (GstLADSPA *ladspa)
289 {
290   GstLADSPAClass *oclass = (GstLADSPAClass*)(G_OBJECT_GET_CLASS(ladspa));
291   
292   LADSPA_Descriptor *desc;
293   gint i,sinkcount,srccount,controlcount;
294
295   desc = oclass->descriptor;
296   ladspa->descriptor = oclass->descriptor;
297   
298   // allocate the various arrays
299   ladspa->srcpads = g_new0(GstPad*,oclass->numsrcpads);
300   ladspa->sinkpads = g_new0(GstPad*,oclass->numsinkpads);
301   ladspa->controls = g_new(gfloat,oclass->numcontrols);
302
303   // walk through the ports and add all the pads
304   sinkcount = 0;
305   srccount = 0;
306   controlcount = 0;
307   for (i=0;i<desc->PortCount;i++) {
308     if (LADSPA_IS_PORT_AUDIO(desc->PortDescriptors[i]) &&
309         LADSPA_IS_PORT_INPUT(desc->PortDescriptors[i])) {
310       ladspa->sinkpads[sinkcount] = gst_pad_new_from_template 
311       (sinktempl, (gchar *)desc->PortNames[i]);
312       gst_element_add_pad(GST_ELEMENT(ladspa),ladspa->sinkpads[sinkcount]);
313       sinkcount++;
314     }
315     if (LADSPA_IS_PORT_AUDIO(desc->PortDescriptors[i]) &&
316         LADSPA_IS_PORT_OUTPUT(desc->PortDescriptors[i])) {
317       ladspa->srcpads[srccount] = gst_pad_new_from_template 
318         (srctempl, (gchar *)desc->PortNames[i]);
319       gst_element_add_pad(GST_ELEMENT(ladspa),ladspa->srcpads[srccount]);
320       srccount++;
321     }
322     if (LADSPA_IS_PORT_CONTROL(desc->PortDescriptors[i]) &&
323         LADSPA_IS_PORT_INPUT(desc->PortDescriptors[i])) {
324           
325       // use the lowerbound as the default value if it exists
326       if (oclass->control_info[controlcount].lower){
327         ladspa->controls[controlcount]=oclass->control_info[controlcount].lowerbound;
328       } else {
329         ladspa->controls[controlcount] = 0.0;
330       }
331       controlcount++;
332     }
333   }
334
335   ladspa->samplerate = 0;
336   ladspa->buffersize = 0;
337   ladspa->newcaps = FALSE;
338   ladspa->activated = FALSE;
339   
340   // mono chain
341   if (sinkcount==1 && srccount==1){
342     //g_print("inplace mono chain mode\n");
343     gst_pad_set_negotiate_function (ladspa->sinkpads[0], gst_ladspa_negotiate_sink_mono);
344     gst_pad_set_chain_function(ladspa->sinkpads[0],gst_ladspa_chain_inplace_mono);
345     gst_pad_set_negotiate_function (ladspa->srcpads[0], gst_ladspa_negotiate_src_mono);
346   }
347   
348   // mono get (no sink pads)
349   if (sinkcount==0 && srccount == 1){
350     //g_print("get mode\n");
351     ladspa->newcaps = TRUE;
352     ladspa->samplerate = 44100;
353     ladspa->buffersize = 64;
354     gst_pad_set_get_function(ladspa->srcpads[0],gst_ladspa_get_mono);
355     gst_pad_set_negotiate_function (ladspa->srcpads[0], gst_ladspa_negotiate_src_get_mono);
356     gst_ladspa_instantiate(ladspa);
357   }
358   
359   // multi srcpad get
360   if (sinkcount==0 && srccount > 1){
361     //g_print("multi get mode\n");
362     ladspa->newcaps = TRUE;
363     ladspa->samplerate = 44100;
364     ladspa->buffersize = 64;
365     gst_pad_set_get_function(ladspa->srcpads[0],gst_ladspa_get);
366     gst_pad_set_negotiate_function (ladspa->srcpads[0], gst_ladspa_negotiate_src_get_mono);
367     gst_ladspa_instantiate(ladspa);
368     ladspa->buffers = g_new0(GstBuffer*,oclass->numsrcpads);
369   }
370 }
371
372 static GstPadNegotiateReturn
373 gst_ladspa_negotiate_src_mono (GstPad *pad, GstCaps **caps, gpointer *data)
374 {
375   GstLADSPA *ladspa = (GstLADSPA*)GST_OBJECT_PARENT (pad);
376   
377   // have to instantiate ladspa plugin when samplerate changes (groan)
378   if (ladspa->samplerate != gst_caps_get_int (*caps, "rate")){
379     ladspa->samplerate = gst_caps_get_int (*caps, "rate");
380     if (!gst_ladspa_instantiate(ladspa)) return GST_PAD_NEGOTIATE_FAIL;
381   }
382   return gst_pad_negotiate_proxy (pad, ladspa->sinkpads[0], caps);
383 }
384
385 static GstPadNegotiateReturn
386 gst_ladspa_negotiate_sink_mono (GstPad *pad, GstCaps **caps, gpointer *data)
387 {
388   GstLADSPA *ladspa = (GstLADSPA*)GST_OBJECT_PARENT (pad);
389   
390   // have to instantiate ladspa plugin when samplerate changes (groan)
391   if (ladspa->samplerate != gst_caps_get_int (*caps, "rate")){
392     ladspa->samplerate = gst_caps_get_int (*caps, "rate");
393     if (!gst_ladspa_instantiate(ladspa)) return GST_PAD_NEGOTIATE_FAIL;
394   }
395   return gst_pad_negotiate_proxy (pad, ladspa->srcpads[0], caps);
396 }
397
398 static GstPadNegotiateReturn 
399 gst_ladspa_negotiate_src_get_mono (GstPad *pad, GstCaps **caps, gpointer *data) 
400 {
401   GstLADSPA *ladspa;
402   //g_print("gst_ladspa_negotiate_src_get_mono\n");
403   if (*caps) {
404     g_return_val_if_fail (pad != NULL, GST_PAD_NEGOTIATE_FAIL);
405     ladspa = (GstLADSPA*)GST_OBJECT_PARENT (pad);
406     ladspa->samplerate = gst_caps_get_int (*caps, "rate");
407     if (!gst_ladspa_instantiate(ladspa)) return GST_PAD_NEGOTIATE_FAIL;
408     return GST_PAD_NEGOTIATE_AGREE;
409   }
410   return GST_PAD_NEGOTIATE_FAIL;
411 }
412
413 static void
414 gst_ladspa_force_caps(GstLADSPA *ladspa, GstPad *pad) {
415   
416   // g_print("forcing caps\n");
417   gst_pad_set_caps (pad, gst_caps_new (
418     "ladspa_src_caps",
419     "audio/raw",
420     gst_props_new (
421       "format",     GST_PROPS_STRING ("float"),
422       "layout",     GST_PROPS_STRING ("gfloat"),
423       "intercept",  GST_PROPS_FLOAT(0.0),
424       "slope",      GST_PROPS_FLOAT(1.0),
425       "rate",       GST_PROPS_INT (ladspa->samplerate),
426       "channels",   GST_PROPS_INT (1),
427       NULL
428     )
429   ));
430   ladspa->newcaps=FALSE;
431 }
432
433 static void
434 gst_ladspa_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec)
435 {
436   GstLADSPA *ladspa = (GstLADSPA*)object;
437   gint cid = prop_id - ARG_LAST;
438   GstLADSPAClass *oclass;
439   ladspa_control_info *control_info;
440   gfloat val=0.0;
441     
442   // these are only registered in get mode
443   switch (prop_id) {
444     case ARG_SAMPLERATE:
445       ladspa->samplerate = g_value_get_int (value);
446       ladspa->newcaps=TRUE;
447       break;
448     case ARG_BUFFERSIZE:
449       ladspa->buffersize = g_value_get_int (value);
450       break;
451   }
452   
453   // is it a ladspa plugin arg?
454   if (cid<0) return;
455
456 /*
457   if (id == ARG_LOOP_BASED) {
458     // we can only do this in NULL state
459     g_return_if_fail (GST_STATE(object) != GST_STATE_NULL);
460     ladspa->loopbased = g_value_get_boolean (value);
461     if (ladspa->loopbased) {
462       gst_element_set_loop_function (GST_ELEMENT (ladspa), gst_ladspa_loop);
463     } else {
464       gst_element_set_loop_function (GST_ELEMENT (ladspa), NULL);
465     }
466   }
467 */
468
469   oclass = (GstLADSPAClass*)(G_OBJECT_GET_CLASS (object));
470
471   // verify it exists and is a control (not a port)
472   g_return_if_fail(cid < oclass->numcontrols);
473   
474   control_info = &(oclass->control_info[cid]);
475   g_return_if_fail (control_info->name != NULL);
476
477   // check to see if it's writable
478   g_return_if_fail (control_info->writable);
479
480   // g_print("set arg %s to %f\n",control_info->name,ladspa->controls[cid]);
481
482   // now see what type it is
483   if (control_info->toggled) {
484     if (g_value_get_boolean (value))
485       ladspa->controls[cid] = 1.0;
486     else
487       ladspa->controls[cid] = 0.0;
488   } else if (control_info->integer) {
489     val = (gfloat)g_value_get_int (value);
490     ladspa->controls[cid] = val;
491   } else {
492     val = g_value_get_float (value);
493     ladspa->controls[cid] = val;
494   }    
495 }
496
497 static void
498 gst_ladspa_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec)
499 {
500   GstLADSPA *ladspa = (GstLADSPA*)object;
501   gint cid = prop_id - ARG_LAST;
502   GstLADSPAClass *oclass = (GstLADSPAClass*)(G_OBJECT_GET_CLASS (object));
503   ladspa_control_info *control_info;
504
505   // these are only registered in get mode
506   switch (prop_id){
507     case ARG_SAMPLERATE:
508       g_value_set_int (value, ladspa->samplerate);
509       break;
510     case ARG_BUFFERSIZE:
511       g_value_set_int (value, ladspa->buffersize);
512       break;
513   }
514     
515   if (cid<0) return;
516   // verify it exists and is a control (not a port)
517   if (cid >= oclass->numcontrols) return;
518   control_info = &(oclass->control_info[cid]);
519   if (control_info->name == NULL) return;
520
521   //g_print("got arg %s as %f\n",control_info->name,ladspa->controls[cid]);
522
523   // now see what type it is
524   if (control_info->toggled) {
525     if (ladspa->controls[cid] == 1.0)
526       g_value_set_boolean (value, TRUE);
527     else
528       g_value_set_boolean (value, FALSE);
529   } else if (control_info->integer) {
530     g_value_set_int (value, (gint)ladspa->controls[cid]);
531   } else {
532     g_value_set_float (value, ladspa->controls[cid]);
533   }
534 }
535
536 static gboolean
537 gst_ladspa_instantiate (GstLADSPA *ladspa)
538 {
539   LADSPA_Descriptor *desc;
540   int i;
541   GstLADSPAClass *oclass = (GstLADSPAClass*)(G_OBJECT_GET_CLASS (ladspa));
542   gboolean was_activated;
543   
544   desc = ladspa->descriptor;
545   
546   // check for old handle
547   was_activated = ladspa->activated;
548   if (ladspa->handle != NULL){
549     gst_ladspa_deactivate(ladspa);
550     desc->cleanup(ladspa->handle);
551   }
552         
553   // instantiate the plugin  
554   ladspa->handle = desc->instantiate(desc,ladspa->samplerate);
555   g_return_val_if_fail (ladspa->handle != NULL, FALSE);
556
557   // walk through the ports and add all the arguments
558   for (i=0;i<oclass->numcontrols;i++) {
559     // connect the argument to the plugin
560     //g_print("added control port %d\n", oclass->control_portnums[i]);
561     desc->connect_port(ladspa->handle,
562                        oclass->control_portnums[i],
563                        &(ladspa->controls[i]));
564   }
565
566   // reactivate if it was activated before the reinstantiation
567   if (was_activated){
568     gst_ladspa_activate(ladspa);
569   }
570   return TRUE;
571 }
572
573 static GstElementStateReturn
574 gst_ladspa_change_state (GstElement *element)
575 {
576   LADSPA_Descriptor *desc;
577   GstLADSPA *ladspa = (GstLADSPA*)element;
578 //  GstLADSPAClass *oclass = (GstLADSPAClass*)(G_OBJECT(ladspa)->klass);
579   desc = ladspa->descriptor;
580
581   //g_print("changing state\n");
582   switch (GST_STATE_TRANSITION (element)) {
583     case GST_STATE_NULL_TO_READY:
584       gst_ladspa_activate(ladspa);
585       break;
586     case GST_STATE_READY_TO_NULL:
587       gst_ladspa_deactivate(ladspa);
588       break;
589     default:
590       break;
591   }
592
593   if (GST_ELEMENT_CLASS (parent_class)->change_state)
594     return GST_ELEMENT_CLASS (parent_class)->change_state (element);
595
596   return GST_STATE_SUCCESS;
597 }
598
599 static void
600 gst_ladspa_activate(GstLADSPA *ladspa)
601 {
602   LADSPA_Descriptor *desc;
603   desc = ladspa->descriptor;
604   
605   if (ladspa->activated){
606     gst_ladspa_deactivate(ladspa);
607   }
608   
609   //g_print("activating\n");
610
611   // activate the plugin (function might be null)
612   if (desc->activate != NULL){
613     desc->activate(ladspa->handle);
614   }
615   
616   ladspa->activated = TRUE;
617 }
618
619 static void
620 gst_ladspa_deactivate(GstLADSPA *ladspa)
621 {
622   LADSPA_Descriptor *desc;
623   desc = ladspa->descriptor;
624
625   //g_print("deactivating\n");
626
627   // deactivate the plugin (function might be null)  
628   if (ladspa->activated && desc->deactivate != NULL){
629     desc->deactivate(ladspa->handle);
630   }
631   ladspa->activated = FALSE;
632 }
633
634 static void
635 gst_ladspa_loop (GstElement *element)
636 {
637   int i;
638   GstLADSPA *ladspa = (GstLADSPA *)element;
639   GstLADSPAClass *oclass = (GstLADSPAClass*)(G_OBJECT_GET_CLASS (ladspa));
640   LADSPA_Descriptor *desc;
641
642   desc = ladspa->descriptor;
643   do {
644     printf("looping something\n");
645
646     // first get all the necessary data from the input ports
647     for (i=0;i<oclass->numsinkpads;i++){  
648       ladspa->buffers[i] = gst_pad_pull(ladspa->sinkpads[i]);
649       printf("pulling buffer %d\n", i);
650     }
651     
652     for (i=0;i<oclass->numsinkpads;i++) {
653 //      desc->connect_port(ladspa->handle,i,&(ladspa->controls[i]));
654     }
655
656     for (i=0;i<oclass->numsrcpads && i<oclass->numsinkpads;i++){
657       printf("pushing buffer %d\n", i);
658       gst_pad_push (ladspa->srcpads[i], ladspa->buffers[i]);
659       ladspa->buffers[i] = NULL;
660     }
661     
662   } while (!GST_ELEMENT_IS_COTHREAD_STOPPING (element));
663 }
664
665 static void
666 gst_ladspa_chain_inplace_mono (GstPad *pad,GstBuffer *buf)
667 {
668   LADSPA_Descriptor *desc;
669   LADSPA_Data *data;
670   unsigned long num_samples;
671   
672   GstLADSPA *ladspa;
673   GstLADSPAClass *oclass;
674
675   g_return_if_fail(pad != NULL);
676   g_return_if_fail(GST_IS_PAD(pad));
677   g_return_if_fail(buf != NULL);
678
679   ladspa = (GstLADSPA *)gst_pad_get_parent (pad);
680   g_return_if_fail(ladspa != NULL);
681
682   // this might happen if caps nego hasn't happened
683   g_return_if_fail(ladspa->handle != NULL);
684
685   oclass = (GstLADSPAClass*)(G_OBJECT_GET_CLASS (ladspa));
686   data=(LADSPA_Data*)GST_BUFFER_DATA(buf);
687   num_samples = GST_BUFFER_SIZE(buf) / sizeof(gfloat);
688   
689   desc = ladspa->descriptor;
690
691   desc->connect_port(ladspa->handle,oclass->sinkpad_portnums[0],data);
692   desc->connect_port(ladspa->handle,oclass->srcpad_portnums[0],data);
693
694   desc->run(ladspa->handle,num_samples);
695   
696   desc->connect_port(ladspa->handle,oclass->sinkpad_portnums[0],NULL);
697   desc->connect_port(ladspa->handle,oclass->srcpad_portnums[0],NULL);
698
699   gst_pad_push (ladspa->srcpads[0], buf);  
700 }
701
702 static GstBuffer *
703 gst_ladspa_get_mono(GstPad *pad)
704 {
705   LADSPA_Descriptor *desc;
706   LADSPA_Data *data;
707   
708   GstLADSPA *ladspa;
709   GstLADSPAClass *oclass;
710   GstBuffer *buf;
711
712   g_return_val_if_fail(pad != NULL, NULL);
713   g_return_val_if_fail(GST_IS_PAD(pad), NULL);
714
715   ladspa = (GstLADSPA *)gst_pad_get_parent (pad);
716   g_return_val_if_fail(ladspa != NULL, NULL);
717
718   // this might happen if caps nego hasn't happened
719   g_return_val_if_fail(ladspa->handle != NULL, NULL);
720
721   oclass = (GstLADSPAClass*)(G_OBJECT_GET_CLASS(ladspa));
722   
723   if (ladspa->newcaps) {
724     gst_ladspa_force_caps(ladspa, ladspa->srcpads[0]);
725   }
726   
727   buf = gst_buffer_new();
728   g_return_val_if_fail (buf, NULL);
729   data = g_new(LADSPA_Data, ladspa->buffersize);
730   GST_BUFFER_DATA(buf) = (gpointer) data;
731   GST_BUFFER_SIZE(buf) = sizeof(LADSPA_Data) * ladspa->buffersize;
732   GST_BUFFER_TIMESTAMP(buf) = ladspa->timestamp;
733
734   desc = ladspa->descriptor;
735   desc->connect_port(ladspa->handle,oclass->srcpad_portnums[0],data);
736   desc->run(ladspa->handle,(unsigned long)ladspa->buffersize);  
737   desc->connect_port(ladspa->handle,oclass->srcpad_portnums[0],NULL);
738   
739   return buf;
740 }
741
742 static GstBuffer *
743 gst_ladspa_get(GstPad *pad)
744 {
745   LADSPA_Descriptor *desc;
746   LADSPA_Data *data;
747   
748   GstLADSPA *ladspa;
749   GstLADSPAClass *oclass;
750   GstBuffer *buf;
751
752   g_return_val_if_fail(pad != NULL, NULL);
753   g_return_val_if_fail(GST_IS_PAD(pad), NULL);
754
755   ladspa = (GstLADSPA *)gst_pad_get_parent (pad);
756   g_return_val_if_fail(ladspa != NULL, NULL);
757
758   // this might happen if caps nego hasn't happened
759   g_return_val_if_fail(ladspa->handle != NULL, NULL);
760
761   oclass = (GstLADSPAClass*)(G_OBJECT_GET_CLASS(ladspa));
762   
763   if (ladspa->newcaps) {
764     gst_ladspa_force_caps(ladspa, ladspa->srcpads[0]);
765   }
766   
767   buf = gst_buffer_new();
768   g_return_val_if_fail (buf, NULL);
769   data = g_new(LADSPA_Data, ladspa->buffersize);
770   GST_BUFFER_DATA(buf) = (gpointer) data;
771   GST_BUFFER_SIZE(buf) = sizeof(LADSPA_Data) * ladspa->buffersize;
772   GST_BUFFER_TIMESTAMP(buf) = ladspa->timestamp;
773   ladspa->timestamp+= ladspa->buffersize * ladspa->samplerate * 10^9;
774
775   desc = ladspa->descriptor;
776   desc->connect_port(ladspa->handle,oclass->srcpad_portnums[0],data);
777   desc->run(ladspa->handle,(unsigned long)ladspa->buffersize);  
778   desc->connect_port(ladspa->handle,oclass->srcpad_portnums[0],NULL);
779   
780   return buf;
781 }
782
783 static void
784 ladspa_describe_plugin(const char *pcFullFilename,
785                        void *pvPluginHandle,
786                        LADSPA_Descriptor_Function pfDescriptorFunction)
787 {
788   const LADSPA_Descriptor *desc;
789   int i,j;
790   
791   GstElementDetails *details;
792   GTypeInfo typeinfo = {
793       sizeof(GstLADSPAClass),      NULL,
794       NULL,
795       (GClassInitFunc)gst_ladspa_class_init,
796       NULL,
797       NULL,
798       sizeof(GstLADSPA),
799       0,
800       (GInstanceInitFunc)gst_ladspa_init,
801   };
802   GType type;
803   GstElementFactory *factory;
804
805   // walk through all the plugins in this pluginlibrary
806   i = 0;
807   while ((desc = pfDescriptorFunction(i++))) {
808     gchar *type_name;
809
810     // construct the type
811     type_name = g_strdup_printf("ladspa_%s",desc->Label);
812     g_strcanon (type_name, G_CSET_A_2_Z G_CSET_a_2_z G_CSET_DIGITS "-_+", '-');
813     // if it's already registered, drop it
814     if (g_type_from_name(type_name)) {
815       g_free(type_name);
816       continue;
817     }
818     // create the type now
819     type = g_type_register_static(GST_TYPE_ELEMENT, type_name , &typeinfo, 0);
820
821     // construct the element details struct
822     details = g_new0(GstElementDetails,1);
823     details->longname = g_strdup(desc->Name);
824     details->klass = "Filter/LADSPA";
825     details->description = details->longname;
826     details->version = g_strdup_printf("%ld",desc->UniqueID);
827     details->author = g_strdup(desc->Maker);
828     details->copyright = g_strdup(desc->Copyright);
829
830     // register the plugin with gstreamer
831     factory = gst_elementfactory_new(type_name,type,details);
832     g_return_if_fail(factory != NULL);
833     gst_plugin_add_feature (ladspa_plugin, GST_PLUGIN_FEATURE (factory));
834
835     // add this plugin to the hash
836     g_hash_table_insert(ladspa_descriptors,
837                         GINT_TO_POINTER(type),
838                         (gpointer)desc);
839     
840
841     // only add sink padtemplate if there are sinkpads                        
842     for (j=0;j<desc->PortCount;j++) {
843       if (LADSPA_IS_PORT_AUDIO(desc->PortDescriptors[j]) &&
844           LADSPA_IS_PORT_INPUT(desc->PortDescriptors[j])) {
845         sinktempl = ladspa_sink_factory();
846         gst_elementfactory_add_padtemplate (factory, sinktempl);
847         break;
848       }
849     }
850   
851     srctempl = ladspa_src_factory();
852     gst_elementfactory_add_padtemplate (factory, srctempl);
853
854   }
855 }
856
857 static gboolean
858 plugin_init (GModule *module, GstPlugin *plugin)
859 {
860   
861   ladspa_descriptors = g_hash_table_new(NULL,NULL);
862   parent_class = g_type_class_ref(GST_TYPE_ELEMENT);
863
864   ladspa_plugin = plugin;
865
866   LADSPAPluginSearch(ladspa_describe_plugin);
867
868   return TRUE;
869 }
870
871 GstPluginDesc plugin_desc = {
872   GST_VERSION_MAJOR,
873   GST_VERSION_MINOR,
874   "ladspa",
875   plugin_init
876 };
877