Imported Upstream version 0.2.4
[platform/upstream/remix.git] / src / plugins / ladspa / remix_ladspa.c
1 /*
2  * LADSPA wrapper plugin for libremix
3  *
4  * Copyright (C) 2000 Conrad Parker
5  * Copyright (C) 2001 Commonwealth Scientific and Industrial Research
6  * Organisation (CSIRO), Australia.
7  *
8  * This library is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Lesser General Public
10  * License as published by the Free Software Foundation; either
11  * version 2 of the License, or (at your option) any later version.
12  *
13  * This library is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  * Lesser General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with this library; if not, write to the Free Software
20  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
21  *
22  */
23
24 /*
25  * This file assumes that both LADSPA and libremix are built with
26  * an audio datatype of 'float'.
27  */
28
29 #include "config.h"
30
31 #include <stdlib.h>
32 #include <stdio.h>
33 #include <sys/types.h>
34 #include <dirent.h>
35 #include <string.h>
36 #include <math.h> /* for ceil() */
37
38 #include <dlfcn.h>
39 #include <sys/stat.h>
40
41 #define __REMIX_PLUGIN__
42 #include <remix/remix.h>
43
44 #include "ladspa.h"
45
46 #define PATH_LEN 1024
47
48 /* Compile in support for inplace processing? */
49 #define _PROCESS_INPLACE
50
51 #ifdef _PROCESS_INPLACE
52 #define LADSPA_WRAPPER_IS_INPLACE_BROKEN(x) LADSPA_IS_INPLACE_BROKEN(x)
53 #else
54 #define LADSPA_WRAPPER_IS_INPLACE_BROKEN(x) (1L)
55 #endif
56
57 #define LADSPA_IS_CONTROL_INPUT(x) (LADSPA_IS_PORT_INPUT(x) && LADSPA_IS_PORT_CONTROL(x))
58 #define LADSPA_IS_AUDIO_INPUT(x) (LADSPA_IS_PORT_INPUT(x) && LADSPA_IS_PORT_AUDIO(x))
59 #define LADSPA_IS_CONTROL_OUTPUT(x) (LADSPA_IS_PORT_OUTPUT(x) && LADSPA_IS_PORT_CONTROL(x))
60 #define LADSPA_IS_AUDIO_OUTPUT(x) (LADSPA_IS_PORT_OUTPUT(x) && LADSPA_IS_PORT_AUDIO(x))
61
62 #define LADSPA_frames_to_bytes(f) (f * sizeof(LADSPA_Data))
63
64 static char * default_ladspa_path = "/usr/lib/ladspa:/usr/local/lib/ladspa:/opt/ladspa/lib";
65
66 #ifndef WIN32
67 #  define remix_stat_regular(mode) (S_ISREG((mode)) || S_ISLNK((mode)))
68 #else
69 #  define remix_stat_regular(mode) ((mode) & S_IFREG)
70 #endif
71
72 /* Dummy control output, used to connect all LADSPA control outputs to */
73 static LADSPA_Data dummy_control_output;
74
75 static CDList * modules_list = CD_EMPTY_LIST;
76 static int ladspa_wrapper_initialised = FALSE;
77
78
79 typedef struct _RemixLADSPA RemixLADSPA;
80
81 struct _RemixLADSPA {
82   unsigned long samplerate; /* samplerate initialised at */
83   LADSPA_Descriptor * d;
84   LADSPA_Handle * handle;
85   LADSPA_Data * control_inputs;
86 };
87
88 static RemixBase * remix_ladspa_optimise (RemixEnv * env, RemixBase * base);
89
90 /*
91  * is_usable (d)
92  *
93  * Determine if a LADSPA_Descriptor * d is usable by this remix ladspa
94  * wrapper plugin. Currently this means that there is not more than 1
95  * audio input or more than 1 audio output.
96  */
97 static int
98 is_usable(const LADSPA_Descriptor * d)
99 {
100   LADSPA_PortDescriptor pd;
101   int i;
102   int
103     nr_ai=0, /* audio inputs */
104     nr_ao=0; /* audio outputs */
105
106   for (i=0; i < d->PortCount; i++) {
107     pd = d->PortDescriptors[i];
108     if (LADSPA_IS_AUDIO_INPUT(pd))
109       nr_ai++;
110     if (LADSPA_IS_AUDIO_OUTPUT(pd))
111       nr_ao++;
112   }
113
114   /* Sanity checks */
115   if (! d->run) return FALSE; /* plugin does nothing! */
116   if (! d->instantiate) return FALSE; /* plugin cannot be instantiated */
117   if (! d->connect_port) return FALSE; /* plugin cannot be wired up */
118
119   if (nr_ao == 1 && nr_ai == 1) return TRUE;
120   if (nr_ao == 0 && nr_ai == 1) return TRUE;
121   if (nr_ao == 1 && nr_ai == 0) return TRUE;
122
123   return FALSE;
124 }
125
126 static RemixParameterType
127 convert_type (const LADSPA_PortRangeHintDescriptor prhd)
128 {
129   if (LADSPA_IS_HINT_TOGGLED(prhd))
130     return REMIX_TYPE_BOOL;
131   else if (LADSPA_IS_HINT_INTEGER(prhd))
132     return REMIX_TYPE_INT;
133   else
134     return REMIX_TYPE_FLOAT;
135 }
136
137 static RemixFlags
138 get_valid_mask (const LADSPA_PortRangeHintDescriptor prhd)
139 {
140   RemixFlags ret = 0;
141
142   if (LADSPA_IS_HINT_BOUNDED_BELOW(prhd))
143     ret &= REMIX_RANGE_LOWER_BOUND_VALID;
144   if (LADSPA_IS_HINT_BOUNDED_ABOVE(prhd))
145     ret &= REMIX_RANGE_UPPER_BOUND_VALID;
146
147   return ret;
148 }
149
150 static RemixParameterRange *
151 convert_constraint (const LADSPA_PortRangeHint * prh)
152 {
153   RemixParameterRange * pr;
154   LADSPA_PortRangeHintDescriptor prhd = prh->HintDescriptor;
155
156   if (LADSPA_IS_HINT_TOGGLED(prhd))
157     return NULL;
158
159   pr = malloc (sizeof (*pr));
160
161   pr->valid_mask = get_valid_mask (prhd);
162
163   if (LADSPA_IS_HINT_INTEGER(prhd)) {
164     if (LADSPA_IS_HINT_BOUNDED_BELOW(prhd))
165       pr->lower.s_int = (int)prh->LowerBound;
166     if (LADSPA_IS_HINT_BOUNDED_ABOVE(prhd))
167       pr->upper.s_int = (int)prh->UpperBound;
168   } else {
169     if (LADSPA_IS_HINT_BOUNDED_BELOW(prhd))
170       pr->lower.s_float = (float)prh->LowerBound;
171     if (LADSPA_IS_HINT_BOUNDED_ABOVE(prhd))
172       pr->upper.s_float = (float)prh->UpperBound;
173   }
174
175   return pr;
176 }
177
178 static RemixBase *
179 remix_ladspa_replace_handle (RemixEnv * env, RemixBase * base)
180 {
181   RemixPlugin * plugin = remix_base_get_plugin (env, base);
182   RemixLADSPA * al = (RemixLADSPA *) remix_base_get_instance_data (env, base);
183   LADSPA_Descriptor * d;
184
185   if (al == NULL) {
186     remix_set_error (env, REMIX_ERROR_NOENTITY);
187     return RemixNone;
188   }
189
190   if (al->d != NULL)
191     if (al->d->deactivate) al->d->deactivate (al->handle);
192
193   al->samplerate = (unsigned long) remix_get_samplerate (env);
194
195   al->d = d = (LADSPA_Descriptor *) plugin->plugin_data;
196
197   if (d != NULL) {
198     al->handle = d->instantiate (d, al->samplerate);
199     if (d->activate) d->activate (al->handle);
200   }
201
202   return base;
203 }
204
205 static RemixBase *
206 remix_ladspa_init (RemixEnv * env, RemixBase * base, CDSet * parameters)
207 {
208   RemixLADSPA * al = malloc (sizeof (*al));
209
210   remix_base_set_instance_data (env, base, al);
211   al->d = NULL; /* let this get set in replace_handle() */
212
213   remix_ladspa_replace_handle (env, base);
214   remix_ladspa_optimise (env, base);
215   return base;
216 }
217
218 static RemixBase *
219 remix_ladspa_clone (RemixEnv * env, RemixBase * base)
220 {
221   /* XXX: Most of this should really be handled in remix_base.c */
222   RemixPlugin * plugin = remix_base_get_plugin (env, base);
223   RemixBase * new_base = remix_base_new (env);
224   remix_base_set_plugin (env, new_base, plugin);
225   remix_ladspa_init (env, new_base, CD_EMPTY_SET);
226   return new_base;
227 }
228
229 static int
230 remix_ladspa_destroy (RemixEnv * env, RemixBase * base)
231 {
232   RemixLADSPA * al = (RemixLADSPA *) remix_base_get_instance_data (env, base);
233
234   if (al->d) {
235     if (al->d->deactivate) al->d->deactivate (al->handle);
236   }
237
238   free (al->control_inputs);
239   free (al);
240   free (base);
241
242   return 0;
243 }
244
245 static int
246 remix_ladspa_ready (RemixEnv * env, RemixBase * base)
247 {
248   unsigned long samplerate = (unsigned long)remix_get_samplerate (env);
249   RemixLADSPA * al = (RemixLADSPA *) remix_base_get_instance_data (env, base);
250   return (samplerate == al->samplerate);
251 }
252
253 static RemixBase *
254 remix_ladspa_prepare (RemixEnv * env, RemixBase * base)
255 {
256   remix_ladspa_replace_handle (env, base);
257   return base;
258
259 }
260
261 /*
262  * remix_ladspa_1_0:
263  * A RemixChunkChunkFunc for a mono LADSPA sound consumer.
264  */
265 static RemixCount
266 remix_ladspa_1_0 (RemixEnv * env, RemixChunk * chunk, RemixCount offset,
267                RemixCount count, int channelname, void * data)
268 {
269   RemixLADSPA * al = (RemixLADSPA *) data;
270   LADSPA_Descriptor * d;
271   LADSPA_PortDescriptor pd;
272   unsigned long port_i;
273
274   d = al->d;
275
276   /* Connect audio input */
277   for (port_i = 0; port_i < d->PortCount; port_i++) {
278     pd = d->PortDescriptors[(int)port_i];
279     if (LADSPA_IS_AUDIO_INPUT(pd)) {
280       d->connect_port (al->handle, port_i, &chunk->data[offset]);
281     }
282   }
283
284   d->run (al->handle, count);
285
286   return count;
287 }
288
289 /*
290  * remix_ladspa_0_1:
291  * A RemixChunkChunkFunc for a mono LADSPA sound generator.
292  */
293 static RemixCount
294 remix_ladspa_0_1 (RemixEnv * env, RemixChunk * chunk, RemixCount offset,
295                RemixCount count, int channelname, void * data)
296 {
297   RemixLADSPA * al = (RemixLADSPA *) data;
298   LADSPA_Descriptor * d;
299   LADSPA_PortDescriptor pd;
300   unsigned long port_i;
301
302   d = al->d;
303   
304   /* Connect audio output */
305   for (port_i = 0; port_i < d->PortCount; port_i++) {
306     pd = d->PortDescriptors[(int)port_i];
307     if (LADSPA_IS_AUDIO_OUTPUT(pd)) {
308       d->connect_port (al->handle, port_i, &chunk->data[offset]);
309     }
310   }
311
312   d->run (al->handle, count);
313
314   return count;
315 }
316
317 /*
318  * remix_ladspa_1_1:
319  * A RemixChunkChunkFunc for filtering with a mono LADSPA plugin.
320  */
321 static RemixCount
322 remix_ladspa_1_1 (RemixEnv * env, RemixChunk * src, RemixCount src_offset,
323                   RemixChunk * dest, RemixCount dest_offset,
324                   RemixCount count, int channelname, void * data)
325 {
326   RemixLADSPA * al = (RemixLADSPA *) data;
327   LADSPA_Descriptor * d;
328   LADSPA_PortDescriptor pd;
329   unsigned long port_i;
330
331   d = al->d;
332
333   if (al == NULL) {
334     remix_set_error (env, REMIX_ERROR_INVALID);
335     return -1;
336   }
337
338   for (port_i = 0; port_i < d->PortCount; port_i++) {
339     pd = d->PortDescriptors[(int)port_i];
340     if (LADSPA_IS_AUDIO_INPUT(pd)) {
341       d->connect_port (al->handle, port_i, &src->data[src_offset]);
342     }
343     if (LADSPA_IS_AUDIO_OUTPUT(pd)) {
344       d->connect_port (al->handle, port_i, &dest->data[dest_offset]);
345     }
346   }
347
348   d->run (al->handle, count);
349
350   return count;
351 }
352
353
354 #if 0
355 static void
356 ladspa_wrapper_apply_region (RemixEnv * env, gpointer pcmdata, sw_format * format,
357                              gint nr_frames,
358                              sw_param_set pset, void * custom_data)
359 {
360   lm_custom * lm = (lm_custom *)custom_data;
361   const LADSPA_Descriptor * d = lm->d;
362   sw_param_spec * param_specs = lm->param_specs;
363
364   LADSPA_Handle * handle;
365   LADSPA_Data ** input_buffers, ** output_buffers;
366   LADSPA_Data * mono_input_buffer=NULL;
367   LADSPA_Data * p;
368   LADSPA_Data * control_inputs;
369   LADSPA_Data dummy_control_output;
370   LADSPA_PortDescriptor pd;
371   long length_b;
372   unsigned long port_i; /* counter for iterating over ports */
373   int i, j, n;
374
375   /* The number of times the plugin will be run; ie. if the number of
376    * channels in the input pcmdata is greater than the number of
377    * audio ports on the ladspa plugin, the plugin will be run
378    * multiple times until enough output channels have been calculated.
379    */
380   gint iterations;
381
382   /* Enumerate the numbers of each type of port on the ladspa plugin */
383   gint
384     nr_ci=0, /* control inputs */
385     nr_ai=0, /* audio inputs */
386     nr_co=0, /* control outputs */
387     nr_ao=0; /* audio outputs */
388
389   /* The number of audio channels to be processed */
390   gint nr_channels = format->channels;
391
392   /* The number of input and output buffers to use */
393   gint nr_i=0, nr_o=0;
394
395   /* Counters for allocating input and output buffers */
396   gint ibi=0, obi=0;
397
398
399   /* instantiate the ladspa plugin */
400   handle = d->instantiate (d, (long)format->rate);
401
402   /* Cache how many of each type of port this ladspa plugin has */
403   for (port_i=0; port_i < d->PortCount; port_i++) {
404     pd = d->PortDescriptors[(int)port_i];
405     if (LADSPA_IS_CONTROL_INPUT(pd))
406       nr_ci++;
407     if (LADSPA_IS_AUDIO_INPUT(pd))
408       nr_ai++;
409     if (LADSPA_IS_CONTROL_OUTPUT(pd))
410       nr_co++;
411     if (LADSPA_IS_AUDIO_OUTPUT(pd))
412       nr_ao++;
413   }
414
415   /* Basic assumption of this wrapper plugin, which was
416    * checked above in is_usable(); nb. for future expansion
417    * much of this routine is written to accomodate this
418    * assumption being incorrect.
419    */
420   g_assert (nr_ai == nr_ao);
421
422   /* Basic assumption that this plugin has audio output.
423    * Also important as we are about to divide by nr_ao.
424    */
425   g_assert (nr_ao > 0);
426
427   iterations = (gint) ceil(((double)nr_channels) / ((double)nr_ao));
428
429   /* Numbers of input and output buffers: ensure
430    * nr_i >= nr_channels && nr_o >= nr_channels
431    */
432   nr_i = iterations * nr_ai;
433   nr_o = iterations * nr_ao;
434
435   if ((nr_channels == 1) && (nr_ai == 1) && (nr_ao >= 1)) {
436     /*
437      * Processing a mono sample with a mono filter.
438      * Attempt to do this in place.
439      */
440
441     /* Copy PCM data if this ladspa plugin cannot work inplace */
442     if (LADSPA_WRAPPER_IS_INPLACE_BROKEN(d->Properties)) {
443       length_b = frames_to_bytes (format, nr_frames);
444       mono_input_buffer = g_malloc (length_b);
445       input_buffers = &mono_input_buffer;
446     } else {
447       input_buffers = (LADSPA_Data **)&pcmdata;
448     }
449     
450     output_buffers = (LADSPA_Data **)&pcmdata;
451
452   } else {
453     length_b = LADSPA_frames_to_bytes (nr_frames);
454
455     /* Allocate zeroed input buffers; these will remain zeroed
456      * if there aren't enough channels in the input pcmdata
457      * to use them.
458      */
459     input_buffers = g_malloc (sizeof(LADSPA_Data *) * nr_i);
460     for (i=0; i < nr_i; i++) {
461       input_buffers[i] = g_malloc0 (length_b);
462     }
463
464     output_buffers = g_malloc(sizeof(LADSPA_Data *) * nr_o);
465
466     /* Create separate output buffers if this ladspa plugin cannot
467      * work inplace */
468     if (LADSPA_WRAPPER_IS_INPLACE_BROKEN(d->Properties)) {
469       for (i=0; i < nr_o; i++) {
470         output_buffers[i] = g_malloc (length_b);
471       }
472     } else {
473       /* Re-use the input buffers, directly mapping them to
474        * corresponding output buffers
475        */
476       for (i=0; i < MIN(nr_i, nr_o); i++) {
477         output_buffers[i] = input_buffers[i];
478       }
479       /* Create some extra output buffers if nr_o > nr_i */
480       for (; i < nr_o; i++) {
481         output_buffers[i] = g_malloc (length_b);
482       }
483     }
484   }
485
486   /* Copy data into input buffers */
487   if (nr_channels == 1) {
488     if (!LADSPA_WRAPPER_IS_INPLACE_BROKEN(d->Properties)) {
489       length_b = frames_to_bytes (format, nr_frames);
490       memcpy (input_buffers[0], pcmdata, length_b);
491     } /* else we're processing in-place, so we haven't needed to set
492        * up a separate input buffer; input_buffers[0] actually
493        * points to pcmdata hence we don't do any copying here.
494        */
495   } else {
496     /* de-interleave multichannel data */
497
498     p = (LADSPA_Data *)pcmdata;
499
500     for (n=0; n < nr_channels; n++) {
501       for (i=0; i < nr_frames; i++) {
502         input_buffers[n][i] = *p++;
503       }
504     }
505   }
506
507   /* connect control ports */
508   control_inputs = g_malloc (nr_ci * sizeof(LADSPA_Data));
509   j=0;
510   for (port_i=0; port_i < d->PortCount; port_i++) {
511     pd = d->PortDescriptors[(int)port_i];
512     if (LADSPA_IS_CONTROL_INPUT(pd)) {
513       /* do something with pset! */
514       switch (param_specs[j].type) {
515       case SWEEP_TYPE_BOOL:
516         /* from ladspa.h:
517          * Data less than or equal to zero should be considered
518          * `off' or `false,'
519          * and data above zero should be considered `on' or `true.'
520          */
521         control_inputs[j] = pset[j].b ? 1.0 : 0.0;
522         break;
523       case SWEEP_TYPE_INT:
524         control_inputs[j] = (LADSPA_Data)pset[j].i;
525         break;
526       case SWEEP_TYPE_FLOAT:
527         control_inputs[j] = pset[j].f;
528         break;
529       default:
530         /* This plugin should produce no other types */
531         g_assert_not_reached ();
532         break;
533       }
534       d->connect_port (handle, port_i, &control_inputs[j]);
535       j++;
536     }
537     if (LADSPA_IS_CONTROL_OUTPUT(pd)) {
538       d->connect_port (handle, port_i, &dummy_control_output);
539     }
540   }
541
542   /* run the plugin as many times as necessary */
543   while (iterations--) {
544
545     /* connect input and output audio buffers to the
546      * audio ports of the ladspa plugin */
547     for (port_i=0; port_i < d->PortCount; port_i++) {
548       pd = d->PortDescriptors[(int)port_i];
549       if (LADSPA_IS_AUDIO_INPUT(pd)) {
550         d->connect_port (handle, port_i, input_buffers[ibi++]);
551       }
552       if (LADSPA_IS_AUDIO_OUTPUT(pd)) {
553         d->connect_port (handle, port_i, output_buffers[obi++]);
554       }
555     }
556
557     /* activate the ladspa plugin */
558     if (d->activate)
559       d->activate (handle);
560
561     /* run the ladspa plugin */
562     d->run (handle, nr_frames);
563
564     /* deactivate the ladspa plugin */
565     if (d->deactivate)
566       d->deactivate (handle);
567   }
568
569   /* re-interleave data */
570   if (nr_channels > 1) {
571     p = (LADSPA_Data *)pcmdata;
572
573     for (n=0; n < nr_channels; n++) {
574       for (i=0; i < nr_frames; i++) {
575         *p++ = output_buffers[n][i];
576       }
577     }
578   }
579
580   /* let the ladspa plugin clean up after itself */
581   if (d->cleanup)
582     d->cleanup (handle);
583
584   /* free the input and output buffers */
585   if (control_inputs) g_free (control_inputs);
586
587   if ((nr_channels == 1) && (nr_ai == 1) && (nr_ao >= 1)) {
588     if (LADSPA_WRAPPER_IS_INPLACE_BROKEN(d->Properties)) {
589       g_free (mono_input_buffer);
590     }
591   } else {
592
593     /* free the output buffers */
594     for (i=0; i < nr_o; i++) {
595       g_free (output_buffers[i]);
596     }
597     g_free (output_buffers);
598
599     /* free the input buffers, if we created some */
600     if (LADSPA_WRAPPER_IS_INPLACE_BROKEN(d->Properties)) {
601       for (i=0; i < nr_i; i++) {
602         g_free (input_buffers[i]);
603       }
604     } else {
605       /* inplace worked, but if (nr_i > nr_o), then
606        * we still need to free the last input buffers
607        */
608       for (i=nr_o; i < nr_i; i++) {
609         g_free (input_buffers[i]);
610       }
611     }
612     g_free (input_buffers);  
613   }
614 }
615 #endif
616
617 static RemixBase *
618 remix_ladspa_connect_control_inputs (RemixEnv * env, RemixBase * base)
619 {
620   RemixLADSPA * al = (RemixLADSPA *) remix_base_get_instance_data (env, base);
621   LADSPA_Descriptor * d;
622   LADSPA_PortDescriptor pd;
623   RemixParameter parameter;
624   RemixParameterType type;
625   int j;
626   unsigned long port_i;
627
628   d = al->d;
629
630   if (d == NULL) {
631     remix_set_error (env, REMIX_ERROR_NOENTITY);
632     return RemixNone;
633   }
634
635   j=0;
636   for (port_i=0; port_i < d->PortCount; port_i++) {
637     pd = d->PortDescriptors[(int)port_i];
638     if (LADSPA_IS_CONTROL_INPUT(pd)) {
639       type = remix_get_parameter_type (env, base, j);
640       parameter = remix_get_parameter (env, base, j);
641       switch (type) {
642       case REMIX_TYPE_BOOL:
643         /* from ladspa.h:
644          * Data less than or equal to zero should be considered
645          * `off' or `false,'
646          * and data above zero should be considered `on' or `true.'
647          */
648         al->control_inputs[j] = parameter.s_bool ? 1.0 : 0.0;
649         break;
650       case REMIX_TYPE_INT:
651         al->control_inputs[j] = (LADSPA_Data)parameter.s_int;
652         break;
653       case REMIX_TYPE_FLOAT:
654         al->control_inputs[j] = parameter.s_float;
655         break;
656       default:
657         /* This plugin should produce no other types */
658         break;
659       }
660       d->connect_port (al->handle, port_i, &al->control_inputs[j]);
661       j++;
662     }
663     if (LADSPA_IS_CONTROL_OUTPUT(pd)) {
664       d->connect_port (al->handle, port_i, &dummy_control_output);
665     }
666   }
667
668   return base;
669 }
670
671 static RemixCount
672 remix_ladspa_1_0_process (RemixEnv * env, RemixBase * base, RemixCount count,
673                           RemixStream * input, RemixStream * output)
674 {
675   RemixLADSPA * al = remix_base_get_instance_data (env, base);
676   remix_ladspa_connect_control_inputs (env, base);
677   return remix_stream_chunkfuncify (env, input, count, remix_ladspa_1_0, al);
678 }
679
680 static RemixCount
681 remix_ladspa_0_1_process (RemixEnv * env, RemixBase * base, RemixCount count,
682                           RemixStream * input, RemixStream * output)
683 {
684   RemixLADSPA * al = remix_base_get_instance_data (env, base);
685   remix_ladspa_connect_control_inputs (env, base);
686   return remix_stream_chunkfuncify (env, output, count, remix_ladspa_0_1, al);
687 }
688
689 static RemixCount
690 remix_ladspa_1_1_process (RemixEnv * env, RemixBase * base, RemixCount count,
691                           RemixStream * input, RemixStream * output)
692 {
693   RemixLADSPA * al = remix_base_get_instance_data (env, base);
694   remix_ladspa_connect_control_inputs (env, base);
695   return remix_stream_chunkchunkfuncify (env, input, output, count,
696                                          remix_ladspa_1_1, al);
697 }
698
699 static RemixCount
700 remix_ladspa_process (RemixEnv * env, RemixBase * base, RemixCount count,
701                       RemixStream * input, RemixStream * output)
702 {
703   RemixPlugin * plugin = remix_base_get_plugin (env, base);
704   RemixLADSPA * al;
705   LADSPA_PortDescriptor pd;
706   unsigned long port_i; /* counter for iterating over ports */
707
708   /* Enumerate the numbers of each type of port on the ladspa plugin */
709   int
710     nr_ci=0, /* control inputs */
711     nr_ai=0, /* audio inputs */
712     nr_co=0, /* control outputs */
713     nr_ao=0; /* audio outputs */
714
715   if (plugin == RemixNone) {
716     remix_set_error (env, REMIX_ERROR_NOENTITY);
717     return -1;
718   }
719
720   remix_ladspa_connect_control_inputs (env, base);
721
722   al = remix_base_get_instance_data (env, base);
723
724   /* Cache how many of each type of port this ladspa plugin has */
725   for (port_i=0; port_i < al->d->PortCount; port_i++) {
726     pd = al->d->PortDescriptors[(int)port_i];
727     if (LADSPA_IS_CONTROL_INPUT(pd))
728       nr_ci++;
729     if (LADSPA_IS_AUDIO_INPUT(pd))
730       nr_ai++;
731     if (LADSPA_IS_CONTROL_OUTPUT(pd))
732       nr_co++;
733     if (LADSPA_IS_AUDIO_OUTPUT(pd))
734       nr_ao++;
735   }
736
737   if (nr_ai == 1 && nr_ao == 1) {
738     return remix_stream_chunkchunkfuncify (env, input, output, count,
739                                         remix_ladspa_1_1, al);
740   } else if (nr_ai == 1 && nr_ao == 0) {
741     return remix_stream_chunkfuncify (env, input, count, remix_ladspa_1_0, al);
742   } else if (nr_ai == 0 && nr_ao == 1) {
743     return remix_stream_chunkfuncify (env, output, count, remix_ladspa_0_1, al);
744   } else {
745     remix_set_error (env, REMIX_ERROR_INVALID);
746     return -1;
747   }
748 }
749
750 static RemixCount
751 remix_ladspa_length (RemixEnv * env, RemixBase * base)
752 {
753   return REMIX_COUNT_INFINITE;
754 }
755
756 static struct _RemixMethods _remix_ladspa_1_0_methods = {
757   remix_ladspa_clone,
758   remix_ladspa_destroy,
759   remix_ladspa_ready, /* ready */
760   remix_ladspa_prepare, /* prepare */
761   remix_ladspa_1_0_process,
762   remix_ladspa_length,
763   NULL, /* seek */
764   NULL, /* flush */
765 };
766
767 static struct _RemixMethods _remix_ladspa_0_1_methods = {
768   remix_ladspa_clone,
769   remix_ladspa_destroy,
770   remix_ladspa_ready, /* ready */
771   remix_ladspa_prepare, /* prepare */
772   remix_ladspa_0_1_process,
773   remix_ladspa_length,
774   NULL, /* seek */
775   NULL, /* flush */
776 };
777
778 static struct _RemixMethods _remix_ladspa_1_1_methods = {
779   remix_ladspa_clone,
780   remix_ladspa_destroy,
781   remix_ladspa_ready, /* ready */
782   remix_ladspa_prepare, /* prepare */
783   remix_ladspa_1_1_process,
784   remix_ladspa_length,
785   NULL, /* seek */
786   NULL, /* flush */
787 };
788
789
790 static struct _RemixMethods _remix_ladspa_methods = {
791   remix_ladspa_clone,
792   remix_ladspa_destroy,
793   remix_ladspa_ready, /* ready */
794   remix_ladspa_prepare, /* prepare */
795   remix_ladspa_process,
796   remix_ladspa_length,
797   NULL, /* seek */
798   NULL, /* flush */
799 };
800
801 static RemixBase *
802 remix_ladspa_optimise (RemixEnv * env, RemixBase * base)
803 {
804   RemixLADSPA * al = remix_base_get_instance_data (env, base);
805   LADSPA_Descriptor * d;
806   LADSPA_PortDescriptor pd;
807   unsigned long port_i; /* counter for iterating over ports */
808
809   /* Enumerate the numbers of each type of port on the ladspa plugin */
810   int
811     nr_ci=0, /* control inputs */
812     nr_ai=0, /* audio inputs */
813     nr_co=0, /* control outputs */
814     nr_ao=0; /* audio outputs */
815
816   if (al == NULL) {
817     remix_set_error (env, REMIX_ERROR_NOENTITY);
818     return RemixNone;
819   }
820
821   d = al->d;
822
823   if (d == NULL) {
824     remix_set_error (env, REMIX_ERROR_NOENTITY);
825     return RemixNone;
826   }
827
828   /* Cache how many of each type of port this ladspa plugin has */
829   for (port_i=0; port_i < d->PortCount; port_i++) {
830     pd = d->PortDescriptors[(int)port_i];
831     if (LADSPA_IS_CONTROL_INPUT(pd))
832       nr_ci++;
833     if (LADSPA_IS_AUDIO_INPUT(pd))
834       nr_ai++;
835     if (LADSPA_IS_CONTROL_OUTPUT(pd))
836       nr_co++;
837     if (LADSPA_IS_AUDIO_OUTPUT(pd))
838       nr_ao++;
839   }
840
841   al->control_inputs = malloc (nr_ci * sizeof (LADSPA_Data));
842
843   if (nr_ai == 1 && nr_ao == 1) {
844     remix_base_set_methods (env, base, &_remix_ladspa_1_1_methods);
845   } else if (nr_ai == 1 && nr_ao == 0) {
846     remix_base_set_methods (env, base, &_remix_ladspa_1_0_methods);
847   } else if (nr_ai == 0 && nr_ao == 1) {
848     remix_base_set_methods (env, base, &_remix_ladspa_0_1_methods);
849   } else { 
850     remix_base_set_methods (env, base, &_remix_ladspa_methods);
851   }
852
853   return base;
854 }
855
856
857 /*
858  * ladspa_wrapper_load_plugins (dir, name, gl)
859  *
860  * form RemixPlugins to describe the ladspa plugin functions that
861  * are in the shared library file "dir/name"
862  */
863 static CDList *
864 ladspa_wrapper_load_plugins (RemixEnv * env, char * dir, char * name)
865 {
866   char path[PATH_LEN];
867   void * module;
868   LADSPA_Descriptor_Function desc_func;
869   const LADSPA_Descriptor * d;
870   LADSPA_PortDescriptor pd;
871   int i, j, k;
872   int valid_mask;
873   RemixPlugin * plugin;
874   RemixMetaText * mt;
875   RemixParameterScheme * scheme;
876   CDList * l, * plugins = CD_EMPTY_LIST;
877 #define BUF_LEN 256
878   static char buf[BUF_LEN];
879   struct stat statbuf;
880
881   snprintf (path, PATH_LEN, "%s/%s", dir, name);
882
883   if (stat (path, &statbuf) == -1) return CD_EMPTY_LIST;
884   if (!remix_stat_regular (statbuf.st_mode)) return CD_EMPTY_LIST;
885
886   module = dlopen (path, RTLD_NOW);
887   if (!module) return CD_EMPTY_LIST;
888
889   /* Check that this module has not already been loaded (eg. if it is
890    * a symlink etc.) */
891   for (l = modules_list; l; l = l->next) {
892     if (l->data.s_pointer == module) {
893       dlclose (module);
894       return CD_EMPTY_LIST;
895     }
896   }
897
898   modules_list = cd_list_append (env, modules_list, CD_POINTER(module));
899
900   if ((desc_func = dlsym (module, "ladspa_descriptor"))) {
901     for (i=0; (d = desc_func (i)) != NULL; i++) {
902
903       if (!is_usable(d))
904         continue;
905
906       remix_dprintf ("[ladspa_wrapper_load_plugins] adding %s [%lu] by %s\n",
907                   d->Name, d->UniqueID, d->Maker);
908
909       plugin = malloc (sizeof (*plugin));
910       
911       mt = remix_meta_text_new (env);
912
913       snprintf (buf, BUF_LEN, "ladspa::%lu", d->UniqueID);
914       remix_meta_text_set_identifier (env, mt, strdup (buf));
915
916       snprintf (buf, BUF_LEN, "Miscellaneous::%s", d->Name);
917       remix_meta_text_set_category (env, mt, strdup (buf));
918
919       remix_meta_text_set_copyright (env, mt, (char *)d->Copyright);
920       remix_meta_text_add_author (env, mt, (char *)d->Maker, NULL);
921
922       plugin->metatext = mt;
923
924       plugin->init_scheme = CD_EMPTY_SET;
925       plugin->process_scheme = CD_EMPTY_SET;
926
927       k=0;
928       for (j=0; j < d->PortCount; j++) {
929         pd = d->PortDescriptors[j];
930         if (LADSPA_IS_CONTROL_INPUT(pd)) {
931           scheme = malloc (sizeof (*scheme));
932
933           scheme->name = (char *)d->PortNames[j];
934           scheme->description = (char *)d->PortNames[j];
935           scheme->type = convert_type (d->PortRangeHints[j].HintDescriptor);
936           valid_mask = get_valid_mask (d->PortRangeHints[j].HintDescriptor);
937           if (valid_mask == 0) {
938             scheme->constraint_type = REMIX_CONSTRAINT_TYPE_NONE;
939           } else {
940             scheme->constraint_type = REMIX_CONSTRAINT_TYPE_RANGE;
941             scheme->constraint.range =
942               convert_constraint (&d->PortRangeHints[j]);
943           }
944           plugin->process_scheme = cd_set_insert (env, plugin->process_scheme,
945                                                   k, CD_POINTER(scheme));
946           k++;
947         }
948       }
949
950       plugin->init = remix_ladspa_init;
951
952       plugin->plugin_data = (void *)d;
953
954       plugin->destroy = NULL;
955
956       plugins = cd_list_append (env, plugins, CD_POINTER(plugin));
957     }
958   }
959
960   return plugins;
961
962 #undef BUF_LEN
963 }
964
965 /*
966  * ladspa_wrapper_load_dir (dir, gl)
967  *
968  * scan a directory "dirname" for LADSPA plugins, and attempt to load
969  * each of them.
970  */
971 static CDList *
972 ladspa_wrapper_load_dir (RemixEnv * env, char * dirname)
973 {
974   DIR * dir;
975   struct dirent * dirent;
976   CDList * plugins = CD_EMPTY_LIST, * l;
977
978   if (!dirname) return plugins;
979
980   dir = opendir (dirname);
981   if (!dir) {
982     return plugins;
983   }
984
985   while ((dirent = readdir (dir)) != NULL) {
986     l = ladspa_wrapper_load_plugins (env, dirname, dirent->d_name);
987     plugins = cd_list_join (env, plugins, l);
988   }
989
990   closedir (dir);
991
992   return plugins;
993 }
994
995 CDList *
996 remix_load (RemixEnv * env)
997 {
998   CDList * plugins = CD_EMPTY_LIST, * l;
999   char * ladspa_path=NULL;
1000   char * next_sep=NULL;
1001   char * saved_lp=NULL;
1002
1003   /* If this ladspa_wrapper module has already been initialised, don't
1004    * initialise again until cleaned up.
1005    */
1006   if (ladspa_wrapper_initialised)
1007     return CD_EMPTY_LIST;
1008
1009   ladspa_path = getenv ("LADSPA_PATH");
1010   if (!ladspa_path)
1011     ladspa_path = saved_lp = strdup(default_ladspa_path);
1012
1013   do {
1014     next_sep = strchr (ladspa_path, ':');
1015     if (next_sep != NULL) *next_sep = '\0';
1016     
1017     l = ladspa_wrapper_load_dir (env, ladspa_path);
1018     plugins = cd_list_join (env, plugins, l);
1019
1020     if (next_sep != NULL) ladspa_path = ++next_sep;
1021
1022   } while ((next_sep != NULL) && (*next_sep != '\0'));
1023
1024   ladspa_wrapper_initialised = TRUE;
1025
1026   /* free string if dup'd for ladspa_path */
1027   if (saved_lp != NULL) free(saved_lp);
1028
1029   return plugins;
1030 }
1031
1032 void
1033 remix_unload (RemixEnv * env)
1034 {
1035   CDList * l;
1036
1037   if (!ladspa_wrapper_initialised) return;
1038
1039   for (l = modules_list; l; l = l->next) {
1040     dlclose(l->data.s_pointer);
1041   }
1042
1043   modules_list = NULL;
1044 }
1045