fix glib2's complaining on the params of some plugins there's still some work to...
[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, *tempstr;
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     /* satisfy glib2 (argname[0] must be [A-Za-z]) */
260     if (!((argname[0] >= 'a' && argname[0] <= 'z') || (argname[0] >= 'A' && argname[0] <= 'Z'))) {
261       tempstr = argname;
262       argname = g_strconcat("param-", argname, NULL);
263       g_free (tempstr);
264     }
265     
266     /* check for duplicate property names */
267     if (g_object_class_find_property(G_OBJECT_CLASS(klass), argname) != NULL){
268       gint numarg=1;
269       gchar *numargname = g_strdup_printf("%s_%d",argname,numarg++);
270       while (g_object_class_find_property(G_OBJECT_CLASS(klass), numargname) != NULL){
271         g_free(numargname);
272         numargname = g_strdup_printf("%s_%d",argname,numarg++);
273       }
274       argname = numargname;
275     }
276     
277     g_print("adding arg %s from %s\n",argname, klass->control_info[i].name);
278     
279     if (argtype==G_TYPE_BOOLEAN){
280       paramspec = g_param_spec_boolean(argname,argname,argname, FALSE, argperms);
281     } else if (argtype==G_TYPE_INT){      
282       paramspec = g_param_spec_int(argname,argname,argname, 
283         (gint)klass->control_info[i].lowerbound, (gint)klass->control_info[i].upperbound, 0, argperms);
284     } else {
285       paramspec = g_param_spec_float(argname,argname,argname, 
286         klass->control_info[i].lowerbound, klass->control_info[i].upperbound, 
287         (klass->control_info[i].lowerbound + klass->control_info[i].upperbound) / 2.0f, argperms);
288     }
289     
290     g_object_class_install_property(G_OBJECT_CLASS(klass), i+ARG_LAST, paramspec);
291   }
292 }
293
294 static void
295 gst_ladspa_init (GstLADSPA *ladspa)
296 {
297   GstLADSPAClass *oclass = (GstLADSPAClass*)(G_OBJECT_GET_CLASS(ladspa));
298   
299   LADSPA_Descriptor *desc;
300   gint i,sinkcount,srccount,controlcount;
301
302   desc = oclass->descriptor;
303   ladspa->descriptor = oclass->descriptor;
304   
305   // allocate the various arrays
306   ladspa->srcpads = g_new0(GstPad*,oclass->numsrcpads);
307   ladspa->sinkpads = g_new0(GstPad*,oclass->numsinkpads);
308   ladspa->controls = g_new(gfloat,oclass->numcontrols);
309
310   // walk through the ports and add all the pads
311   sinkcount = 0;
312   srccount = 0;
313   controlcount = 0;
314   for (i=0;i<desc->PortCount;i++) {
315     if (LADSPA_IS_PORT_AUDIO(desc->PortDescriptors[i]) &&
316         LADSPA_IS_PORT_INPUT(desc->PortDescriptors[i])) {
317       ladspa->sinkpads[sinkcount] = gst_pad_new_from_template 
318       (sinktempl, (gchar *)desc->PortNames[i]);
319       gst_element_add_pad(GST_ELEMENT(ladspa),ladspa->sinkpads[sinkcount]);
320       sinkcount++;
321     }
322     if (LADSPA_IS_PORT_AUDIO(desc->PortDescriptors[i]) &&
323         LADSPA_IS_PORT_OUTPUT(desc->PortDescriptors[i])) {
324       ladspa->srcpads[srccount] = gst_pad_new_from_template 
325         (srctempl, (gchar *)desc->PortNames[i]);
326       gst_element_add_pad(GST_ELEMENT(ladspa),ladspa->srcpads[srccount]);
327       srccount++;
328     }
329     if (LADSPA_IS_PORT_CONTROL(desc->PortDescriptors[i]) &&
330         LADSPA_IS_PORT_INPUT(desc->PortDescriptors[i])) {
331           
332       // use the lowerbound as the default value if it exists
333       if (oclass->control_info[controlcount].lower){
334         ladspa->controls[controlcount]=oclass->control_info[controlcount].lowerbound;
335       } else {
336         ladspa->controls[controlcount] = 0.0;
337       }
338       controlcount++;
339     }
340   }
341
342   ladspa->samplerate = 0;
343   ladspa->buffersize = 0;
344   ladspa->newcaps = FALSE;
345   ladspa->activated = FALSE;
346   
347   // mono chain
348   if (sinkcount==1 && srccount==1){
349     //g_print("inplace mono chain mode\n");
350     gst_pad_set_negotiate_function (ladspa->sinkpads[0], gst_ladspa_negotiate_sink_mono);
351     gst_pad_set_chain_function(ladspa->sinkpads[0],gst_ladspa_chain_inplace_mono);
352     gst_pad_set_negotiate_function (ladspa->srcpads[0], gst_ladspa_negotiate_src_mono);
353   }
354   
355   // mono get (no sink pads)
356   if (sinkcount==0 && srccount == 1){
357     //g_print("get mode\n");
358     ladspa->newcaps = TRUE;
359     ladspa->samplerate = 44100;
360     ladspa->buffersize = 64;
361     gst_pad_set_get_function(ladspa->srcpads[0],gst_ladspa_get_mono);
362     gst_pad_set_negotiate_function (ladspa->srcpads[0], gst_ladspa_negotiate_src_get_mono);
363     gst_ladspa_instantiate(ladspa);
364   }
365   
366   // multi srcpad get
367   if (sinkcount==0 && srccount > 1){
368     //g_print("multi get mode\n");
369     ladspa->newcaps = TRUE;
370     ladspa->samplerate = 44100;
371     ladspa->buffersize = 64;
372     gst_pad_set_get_function(ladspa->srcpads[0],gst_ladspa_get);
373     gst_pad_set_negotiate_function (ladspa->srcpads[0], gst_ladspa_negotiate_src_get_mono);
374     gst_ladspa_instantiate(ladspa);
375     ladspa->buffers = g_new0(GstBuffer*,oclass->numsrcpads);
376   }
377 }
378
379 static GstPadNegotiateReturn
380 gst_ladspa_negotiate_src_mono (GstPad *pad, GstCaps **caps, gpointer *data)
381 {
382   GstLADSPA *ladspa = (GstLADSPA*)GST_OBJECT_PARENT (pad);
383   
384   // have to instantiate ladspa plugin when samplerate changes (groan)
385   if (ladspa->samplerate != gst_caps_get_int (*caps, "rate")){
386     ladspa->samplerate = gst_caps_get_int (*caps, "rate");
387     if (!gst_ladspa_instantiate(ladspa)) return GST_PAD_NEGOTIATE_FAIL;
388   }
389   return gst_pad_negotiate_proxy (pad, ladspa->sinkpads[0], caps);
390 }
391
392 static GstPadNegotiateReturn
393 gst_ladspa_negotiate_sink_mono (GstPad *pad, GstCaps **caps, gpointer *data)
394 {
395   GstLADSPA *ladspa = (GstLADSPA*)GST_OBJECT_PARENT (pad);
396   
397   // have to instantiate ladspa plugin when samplerate changes (groan)
398   if (ladspa->samplerate != gst_caps_get_int (*caps, "rate")){
399     ladspa->samplerate = gst_caps_get_int (*caps, "rate");
400     if (!gst_ladspa_instantiate(ladspa)) return GST_PAD_NEGOTIATE_FAIL;
401   }
402   return gst_pad_negotiate_proxy (pad, ladspa->srcpads[0], caps);
403 }
404
405 static GstPadNegotiateReturn 
406 gst_ladspa_negotiate_src_get_mono (GstPad *pad, GstCaps **caps, gpointer *data) 
407 {
408   GstLADSPA *ladspa;
409   //g_print("gst_ladspa_negotiate_src_get_mono\n");
410   if (*caps) {
411     g_return_val_if_fail (pad != NULL, GST_PAD_NEGOTIATE_FAIL);
412     ladspa = (GstLADSPA*)GST_OBJECT_PARENT (pad);
413     ladspa->samplerate = gst_caps_get_int (*caps, "rate");
414     if (!gst_ladspa_instantiate(ladspa)) return GST_PAD_NEGOTIATE_FAIL;
415     return GST_PAD_NEGOTIATE_AGREE;
416   }
417   return GST_PAD_NEGOTIATE_FAIL;
418 }
419
420 static void
421 gst_ladspa_force_caps(GstLADSPA *ladspa, GstPad *pad) {
422   
423   // g_print("forcing caps\n");
424   gst_pad_set_caps (pad, gst_caps_new (
425     "ladspa_src_caps",
426     "audio/raw",
427     gst_props_new (
428       "format",     GST_PROPS_STRING ("float"),
429       "layout",     GST_PROPS_STRING ("gfloat"),
430       "intercept",  GST_PROPS_FLOAT(0.0),
431       "slope",      GST_PROPS_FLOAT(1.0),
432       "rate",       GST_PROPS_INT (ladspa->samplerate),
433       "channels",   GST_PROPS_INT (1),
434       NULL
435     )
436   ));
437   ladspa->newcaps=FALSE;
438 }
439
440 static void
441 gst_ladspa_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec)
442 {
443   GstLADSPA *ladspa = (GstLADSPA*)object;
444   gint cid = prop_id - ARG_LAST;
445   GstLADSPAClass *oclass;
446   ladspa_control_info *control_info;
447   gfloat val=0.0;
448     
449   // these are only registered in get mode
450   switch (prop_id) {
451     case ARG_SAMPLERATE:
452       ladspa->samplerate = g_value_get_int (value);
453       ladspa->newcaps=TRUE;
454       break;
455     case ARG_BUFFERSIZE:
456       ladspa->buffersize = g_value_get_int (value);
457       break;
458   }
459   
460   // is it a ladspa plugin arg?
461   if (cid<0) return;
462
463 /*
464   if (id == ARG_LOOP_BASED) {
465     // we can only do this in NULL state
466     g_return_if_fail (GST_STATE(object) != GST_STATE_NULL);
467     ladspa->loopbased = g_value_get_boolean (value);
468     if (ladspa->loopbased) {
469       gst_element_set_loop_function (GST_ELEMENT (ladspa), gst_ladspa_loop);
470     } else {
471       gst_element_set_loop_function (GST_ELEMENT (ladspa), NULL);
472     }
473   }
474 */
475
476   oclass = (GstLADSPAClass*)(G_OBJECT_GET_CLASS (object));
477
478   // verify it exists and is a control (not a port)
479   g_return_if_fail(cid < oclass->numcontrols);
480   
481   control_info = &(oclass->control_info[cid]);
482   g_return_if_fail (control_info->name != NULL);
483
484   // check to see if it's writable
485   g_return_if_fail (control_info->writable);
486
487   // g_print("set arg %s to %f\n",control_info->name,ladspa->controls[cid]);
488
489   // now see what type it is
490   if (control_info->toggled) {
491     if (g_value_get_boolean (value))
492       ladspa->controls[cid] = 1.0;
493     else
494       ladspa->controls[cid] = 0.0;
495   } else if (control_info->integer) {
496     val = (gfloat)g_value_get_int (value);
497     ladspa->controls[cid] = val;
498   } else {
499     val = g_value_get_float (value);
500     ladspa->controls[cid] = val;
501   }    
502 }
503
504 static void
505 gst_ladspa_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec)
506 {
507   GstLADSPA *ladspa = (GstLADSPA*)object;
508   gint cid = prop_id - ARG_LAST;
509   GstLADSPAClass *oclass = (GstLADSPAClass*)(G_OBJECT_GET_CLASS (object));
510   ladspa_control_info *control_info;
511
512   // these are only registered in get mode
513   switch (prop_id){
514     case ARG_SAMPLERATE:
515       g_value_set_int (value, ladspa->samplerate);
516       break;
517     case ARG_BUFFERSIZE:
518       g_value_set_int (value, ladspa->buffersize);
519       break;
520   }
521     
522   if (cid<0) return;
523   // verify it exists and is a control (not a port)
524   if (cid >= oclass->numcontrols) return;
525   control_info = &(oclass->control_info[cid]);
526   if (control_info->name == NULL) return;
527
528   //g_print("got arg %s as %f\n",control_info->name,ladspa->controls[cid]);
529
530   // now see what type it is
531   if (control_info->toggled) {
532     if (ladspa->controls[cid] == 1.0)
533       g_value_set_boolean (value, TRUE);
534     else
535       g_value_set_boolean (value, FALSE);
536   } else if (control_info->integer) {
537     g_value_set_int (value, (gint)ladspa->controls[cid]);
538   } else {
539     g_value_set_float (value, ladspa->controls[cid]);
540   }
541 }
542
543 static gboolean
544 gst_ladspa_instantiate (GstLADSPA *ladspa)
545 {
546   LADSPA_Descriptor *desc;
547   int i;
548   GstLADSPAClass *oclass = (GstLADSPAClass*)(G_OBJECT_GET_CLASS (ladspa));
549   gboolean was_activated;
550   
551   desc = ladspa->descriptor;
552   
553   // check for old handle
554   was_activated = ladspa->activated;
555   if (ladspa->handle != NULL){
556     gst_ladspa_deactivate(ladspa);
557     desc->cleanup(ladspa->handle);
558   }
559         
560   // instantiate the plugin  
561   ladspa->handle = desc->instantiate(desc,ladspa->samplerate);
562   g_return_val_if_fail (ladspa->handle != NULL, FALSE);
563
564   // walk through the ports and add all the arguments
565   for (i=0;i<oclass->numcontrols;i++) {
566     // connect the argument to the plugin
567     //g_print("added control port %d\n", oclass->control_portnums[i]);
568     desc->connect_port(ladspa->handle,
569                        oclass->control_portnums[i],
570                        &(ladspa->controls[i]));
571   }
572
573   // reactivate if it was activated before the reinstantiation
574   if (was_activated){
575     gst_ladspa_activate(ladspa);
576   }
577   return TRUE;
578 }
579
580 static GstElementStateReturn
581 gst_ladspa_change_state (GstElement *element)
582 {
583   LADSPA_Descriptor *desc;
584   GstLADSPA *ladspa = (GstLADSPA*)element;
585 //  GstLADSPAClass *oclass = (GstLADSPAClass*)(G_OBJECT(ladspa)->klass);
586   desc = ladspa->descriptor;
587
588   //g_print("changing state\n");
589   switch (GST_STATE_TRANSITION (element)) {
590     case GST_STATE_NULL_TO_READY:
591       gst_ladspa_activate(ladspa);
592       break;
593     case GST_STATE_READY_TO_NULL:
594       gst_ladspa_deactivate(ladspa);
595       break;
596     default:
597       break;
598   }
599
600   if (GST_ELEMENT_CLASS (parent_class)->change_state)
601     return GST_ELEMENT_CLASS (parent_class)->change_state (element);
602
603   return GST_STATE_SUCCESS;
604 }
605
606 static void
607 gst_ladspa_activate(GstLADSPA *ladspa)
608 {
609   LADSPA_Descriptor *desc;
610   desc = ladspa->descriptor;
611   
612   if (ladspa->activated){
613     gst_ladspa_deactivate(ladspa);
614   }
615   
616   //g_print("activating\n");
617
618   // activate the plugin (function might be null)
619   if (desc->activate != NULL){
620     desc->activate(ladspa->handle);
621   }
622   
623   ladspa->activated = TRUE;
624 }
625
626 static void
627 gst_ladspa_deactivate(GstLADSPA *ladspa)
628 {
629   LADSPA_Descriptor *desc;
630   desc = ladspa->descriptor;
631
632   //g_print("deactivating\n");
633
634   // deactivate the plugin (function might be null)  
635   if (ladspa->activated && desc->deactivate != NULL){
636     desc->deactivate(ladspa->handle);
637   }
638   ladspa->activated = FALSE;
639 }
640
641 static void
642 gst_ladspa_loop (GstElement *element)
643 {
644   int i;
645   GstLADSPA *ladspa = (GstLADSPA *)element;
646   GstLADSPAClass *oclass = (GstLADSPAClass*)(G_OBJECT_GET_CLASS (ladspa));
647   LADSPA_Descriptor *desc;
648
649   desc = ladspa->descriptor;
650   printf("looping something\n");
651
652   // first get all the necessary data from the input ports
653   for (i=0;i<oclass->numsinkpads;i++){  
654     ladspa->buffers[i] = gst_pad_pull(ladspa->sinkpads[i]);
655     printf("pulling buffer %d\n", i);
656   }
657     
658   for (i=0;i<oclass->numsinkpads;i++) {
659 //      desc->connect_port(ladspa->handle,i,&(ladspa->controls[i]));
660   }
661
662   for (i=0;i<oclass->numsrcpads && i<oclass->numsinkpads;i++){
663     printf("pushing buffer %d\n", i);
664     gst_pad_push (ladspa->srcpads[i], ladspa->buffers[i]);
665     ladspa->buffers[i] = NULL;
666   }
667 }
668
669 static void
670 gst_ladspa_chain_inplace_mono (GstPad *pad,GstBuffer *buf)
671 {
672   LADSPA_Descriptor *desc;
673   LADSPA_Data *data;
674   unsigned long num_samples;
675   
676   GstLADSPA *ladspa;
677   GstLADSPAClass *oclass;
678
679   g_return_if_fail(pad != NULL);
680   g_return_if_fail(GST_IS_PAD(pad));
681   g_return_if_fail(buf != NULL);
682
683   ladspa = (GstLADSPA *)gst_pad_get_parent (pad);
684   g_return_if_fail(ladspa != NULL);
685
686   // this might happen if caps nego hasn't happened
687   g_return_if_fail(ladspa->handle != NULL);
688
689   oclass = (GstLADSPAClass*)(G_OBJECT_GET_CLASS (ladspa));
690   data=(LADSPA_Data*)GST_BUFFER_DATA(buf);
691   num_samples = GST_BUFFER_SIZE(buf) / sizeof(gfloat);
692   
693   desc = ladspa->descriptor;
694
695   desc->connect_port(ladspa->handle,oclass->sinkpad_portnums[0],data);
696   desc->connect_port(ladspa->handle,oclass->srcpad_portnums[0],data);
697
698   desc->run(ladspa->handle,num_samples);
699   
700   desc->connect_port(ladspa->handle,oclass->sinkpad_portnums[0],NULL);
701   desc->connect_port(ladspa->handle,oclass->srcpad_portnums[0],NULL);
702
703   gst_pad_push (ladspa->srcpads[0], buf);  
704 }
705
706 static GstBuffer *
707 gst_ladspa_get_mono(GstPad *pad)
708 {
709   LADSPA_Descriptor *desc;
710   LADSPA_Data *data;
711   
712   GstLADSPA *ladspa;
713   GstLADSPAClass *oclass;
714   GstBuffer *buf;
715
716   g_return_val_if_fail(pad != NULL, NULL);
717   g_return_val_if_fail(GST_IS_PAD(pad), NULL);
718
719   ladspa = (GstLADSPA *)gst_pad_get_parent (pad);
720   g_return_val_if_fail(ladspa != NULL, NULL);
721
722   // this might happen if caps nego hasn't happened
723   g_return_val_if_fail(ladspa->handle != NULL, NULL);
724
725   oclass = (GstLADSPAClass*)(G_OBJECT_GET_CLASS(ladspa));
726   
727   if (ladspa->newcaps) {
728     gst_ladspa_force_caps(ladspa, ladspa->srcpads[0]);
729   }
730   
731   buf = gst_buffer_new();
732   g_return_val_if_fail (buf, NULL);
733   data = g_new(LADSPA_Data, ladspa->buffersize);
734   GST_BUFFER_DATA(buf) = (gpointer) data;
735   GST_BUFFER_SIZE(buf) = sizeof(LADSPA_Data) * ladspa->buffersize;
736   GST_BUFFER_TIMESTAMP(buf) = ladspa->timestamp;
737
738   desc = ladspa->descriptor;
739   desc->connect_port(ladspa->handle,oclass->srcpad_portnums[0],data);
740   desc->run(ladspa->handle,(unsigned long)ladspa->buffersize);  
741   desc->connect_port(ladspa->handle,oclass->srcpad_portnums[0],NULL);
742   
743   return buf;
744 }
745
746 static GstBuffer *
747 gst_ladspa_get(GstPad *pad)
748 {
749   LADSPA_Descriptor *desc;
750   LADSPA_Data *data;
751   
752   GstLADSPA *ladspa;
753   GstLADSPAClass *oclass;
754   GstBuffer *buf;
755
756   g_return_val_if_fail(pad != NULL, NULL);
757   g_return_val_if_fail(GST_IS_PAD(pad), NULL);
758
759   ladspa = (GstLADSPA *)gst_pad_get_parent (pad);
760   g_return_val_if_fail(ladspa != NULL, NULL);
761
762   // this might happen if caps nego hasn't happened
763   g_return_val_if_fail(ladspa->handle != NULL, NULL);
764
765   oclass = (GstLADSPAClass*)(G_OBJECT_GET_CLASS(ladspa));
766   
767   if (ladspa->newcaps) {
768     gst_ladspa_force_caps(ladspa, ladspa->srcpads[0]);
769   }
770   
771   buf = gst_buffer_new();
772   g_return_val_if_fail (buf, NULL);
773   data = g_new(LADSPA_Data, ladspa->buffersize);
774   GST_BUFFER_DATA(buf) = (gpointer) data;
775   GST_BUFFER_SIZE(buf) = sizeof(LADSPA_Data) * ladspa->buffersize;
776   GST_BUFFER_TIMESTAMP(buf) = ladspa->timestamp;
777   ladspa->timestamp+= ladspa->buffersize * ladspa->samplerate * 10^9;
778
779   desc = ladspa->descriptor;
780   desc->connect_port(ladspa->handle,oclass->srcpad_portnums[0],data);
781   desc->run(ladspa->handle,(unsigned long)ladspa->buffersize);  
782   desc->connect_port(ladspa->handle,oclass->srcpad_portnums[0],NULL);
783   
784   return buf;
785 }
786
787 static void
788 ladspa_describe_plugin(const char *pcFullFilename,
789                        void *pvPluginHandle,
790                        LADSPA_Descriptor_Function pfDescriptorFunction)
791 {
792   const LADSPA_Descriptor *desc;
793   int i,j;
794   
795   GstElementDetails *details;
796   GTypeInfo typeinfo = {
797       sizeof(GstLADSPAClass),      NULL,
798       NULL,
799       (GClassInitFunc)gst_ladspa_class_init,
800       NULL,
801       NULL,
802       sizeof(GstLADSPA),
803       0,
804       (GInstanceInitFunc)gst_ladspa_init,
805   };
806   GType type;
807   GstElementFactory *factory;
808
809   // walk through all the plugins in this pluginlibrary
810   i = 0;
811   while ((desc = pfDescriptorFunction(i++))) {
812     gchar *type_name;
813
814     // construct the type
815     type_name = g_strdup_printf("ladspa_%s",desc->Label);
816     g_strcanon (type_name, G_CSET_A_2_Z G_CSET_a_2_z G_CSET_DIGITS "-_+", '-');
817     // if it's already registered, drop it
818     if (g_type_from_name(type_name)) {
819       g_free(type_name);
820       continue;
821     }
822     // create the type now
823     type = g_type_register_static(GST_TYPE_ELEMENT, type_name , &typeinfo, 0);
824
825     // construct the element details struct
826     details = g_new0(GstElementDetails,1);
827     details->longname = g_strdup(desc->Name);
828     details->klass = "Filter/LADSPA";
829     details->description = details->longname;
830     details->version = g_strdup_printf("%ld",desc->UniqueID);
831     details->author = g_strdup(desc->Maker);
832     details->copyright = g_strdup(desc->Copyright);
833
834     // register the plugin with gstreamer
835     factory = gst_elementfactory_new(type_name,type,details);
836     g_return_if_fail(factory != NULL);
837     gst_plugin_add_feature (ladspa_plugin, GST_PLUGIN_FEATURE (factory));
838
839     // add this plugin to the hash
840     g_hash_table_insert(ladspa_descriptors,
841                         GINT_TO_POINTER(type),
842                         (gpointer)desc);
843     
844
845     // only add sink padtemplate if there are sinkpads                        
846     for (j=0;j<desc->PortCount;j++) {
847       if (LADSPA_IS_PORT_AUDIO(desc->PortDescriptors[j]) &&
848           LADSPA_IS_PORT_INPUT(desc->PortDescriptors[j])) {
849         sinktempl = ladspa_sink_factory();
850         gst_elementfactory_add_padtemplate (factory, sinktempl);
851         break;
852       }
853     }
854   
855     srctempl = ladspa_src_factory();
856     gst_elementfactory_add_padtemplate (factory, srctempl);
857
858   }
859 }
860
861 static gboolean
862 plugin_init (GModule *module, GstPlugin *plugin)
863 {
864   
865   ladspa_descriptors = g_hash_table_new(NULL,NULL);
866   parent_class = g_type_class_ref(GST_TYPE_ELEMENT);
867
868   ladspa_plugin = plugin;
869
870   LADSPAPluginSearch(ladspa_describe_plugin);
871
872   return TRUE;
873 }
874
875 GstPluginDesc plugin_desc = {
876   GST_VERSION_MAJOR,
877   GST_VERSION_MINOR,
878   "ladspa",
879   plugin_init
880 };
881