2 * LADSPA wrapper plugin for libremix
4 * Copyright (C) 2000 Conrad Parker
5 * Copyright (C) 2001 Commonwealth Scientific and Industrial Research
6 * Organisation (CSIRO), Australia.
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.
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.
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
25 * This file assumes that both LADSPA and libremix are built with
26 * an audio datatype of 'float'.
33 #include <sys/types.h>
36 #include <math.h> /* for ceil() */
41 #define __REMIX_PLUGIN__
42 #include <remix/remix.h>
48 /* Compile in support for inplace processing? */
49 #define _PROCESS_INPLACE
51 #ifdef _PROCESS_INPLACE
52 #define LADSPA_WRAPPER_IS_INPLACE_BROKEN(x) LADSPA_IS_INPLACE_BROKEN(x)
54 #define LADSPA_WRAPPER_IS_INPLACE_BROKEN(x) (1L)
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))
62 #define LADSPA_frames_to_bytes(f) (f * sizeof(LADSPA_Data))
64 static char * default_ladspa_path = "/usr/lib/ladspa:/usr/local/lib/ladspa:/opt/ladspa/lib";
67 # define remix_stat_regular(mode) (S_ISREG((mode)) || S_ISLNK((mode)))
69 # define remix_stat_regular(mode) ((mode) & S_IFREG)
72 /* Dummy control output, used to connect all LADSPA control outputs to */
73 static LADSPA_Data dummy_control_output;
75 static CDList * modules_list = CD_EMPTY_LIST;
76 static int ladspa_wrapper_initialised = FALSE;
79 typedef struct _RemixLADSPA RemixLADSPA;
82 unsigned long samplerate; /* samplerate initialised at */
83 LADSPA_Descriptor * d;
84 LADSPA_Handle * handle;
85 LADSPA_Data * control_inputs;
88 static RemixBase * remix_ladspa_optimise (RemixEnv * env, RemixBase * base);
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.
98 is_usable(const LADSPA_Descriptor * d)
100 LADSPA_PortDescriptor pd;
103 nr_ai=0, /* audio inputs */
104 nr_ao=0; /* audio outputs */
106 for (i=0; i < d->PortCount; i++) {
107 pd = d->PortDescriptors[i];
108 if (LADSPA_IS_AUDIO_INPUT(pd))
110 if (LADSPA_IS_AUDIO_OUTPUT(pd))
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 */
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;
126 static RemixParameterType
127 convert_type (const LADSPA_PortRangeHintDescriptor prhd)
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;
134 return REMIX_TYPE_FLOAT;
138 get_valid_mask (const LADSPA_PortRangeHintDescriptor prhd)
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;
150 static RemixParameterRange *
151 convert_constraint (const LADSPA_PortRangeHint * prh)
153 RemixParameterRange * pr;
154 LADSPA_PortRangeHintDescriptor prhd = prh->HintDescriptor;
156 if (LADSPA_IS_HINT_TOGGLED(prhd))
159 pr = malloc (sizeof (*pr));
161 pr->valid_mask = get_valid_mask (prhd);
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;
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;
179 remix_ladspa_replace_handle (RemixEnv * env, RemixBase * base)
181 RemixPlugin * plugin = remix_base_get_plugin (env, base);
182 RemixLADSPA * al = (RemixLADSPA *) remix_base_get_instance_data (env, base);
183 LADSPA_Descriptor * d;
186 remix_set_error (env, REMIX_ERROR_NOENTITY);
191 if (al->d->deactivate) al->d->deactivate (al->handle);
193 al->samplerate = (unsigned long) remix_get_samplerate (env);
195 al->d = d = (LADSPA_Descriptor *) plugin->plugin_data;
198 al->handle = d->instantiate (d, al->samplerate);
199 if (d->activate) d->activate (al->handle);
206 remix_ladspa_init (RemixEnv * env, RemixBase * base, CDSet * parameters)
208 RemixLADSPA * al = malloc (sizeof (*al));
210 remix_base_set_instance_data (env, base, al);
211 al->d = NULL; /* let this get set in replace_handle() */
213 remix_ladspa_replace_handle (env, base);
214 remix_ladspa_optimise (env, base);
219 remix_ladspa_clone (RemixEnv * env, RemixBase * base)
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);
230 remix_ladspa_destroy (RemixEnv * env, RemixBase * base)
232 RemixLADSPA * al = (RemixLADSPA *) remix_base_get_instance_data (env, base);
235 if (al->d->deactivate) al->d->deactivate (al->handle);
238 free (al->control_inputs);
246 remix_ladspa_ready (RemixEnv * env, RemixBase * base)
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);
254 remix_ladspa_prepare (RemixEnv * env, RemixBase * base)
256 remix_ladspa_replace_handle (env, base);
263 * A RemixChunkChunkFunc for a mono LADSPA sound consumer.
266 remix_ladspa_1_0 (RemixEnv * env, RemixChunk * chunk, RemixCount offset,
267 RemixCount count, int channelname, void * data)
269 RemixLADSPA * al = (RemixLADSPA *) data;
270 LADSPA_Descriptor * d;
271 LADSPA_PortDescriptor pd;
272 unsigned long port_i;
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]);
284 d->run (al->handle, count);
291 * A RemixChunkChunkFunc for a mono LADSPA sound generator.
294 remix_ladspa_0_1 (RemixEnv * env, RemixChunk * chunk, RemixCount offset,
295 RemixCount count, int channelname, void * data)
297 RemixLADSPA * al = (RemixLADSPA *) data;
298 LADSPA_Descriptor * d;
299 LADSPA_PortDescriptor pd;
300 unsigned long port_i;
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]);
312 d->run (al->handle, count);
319 * A RemixChunkChunkFunc for filtering with a mono LADSPA plugin.
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)
326 RemixLADSPA * al = (RemixLADSPA *) data;
327 LADSPA_Descriptor * d;
328 LADSPA_PortDescriptor pd;
329 unsigned long port_i;
334 remix_set_error (env, REMIX_ERROR_INVALID);
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]);
343 if (LADSPA_IS_AUDIO_OUTPUT(pd)) {
344 d->connect_port (al->handle, port_i, &dest->data[dest_offset]);
348 d->run (al->handle, count);
356 ladspa_wrapper_apply_region (RemixEnv * env, gpointer pcmdata, sw_format * format,
358 sw_param_set pset, void * custom_data)
360 lm_custom * lm = (lm_custom *)custom_data;
361 const LADSPA_Descriptor * d = lm->d;
362 sw_param_spec * param_specs = lm->param_specs;
364 LADSPA_Handle * handle;
365 LADSPA_Data ** input_buffers, ** output_buffers;
366 LADSPA_Data * mono_input_buffer=NULL;
368 LADSPA_Data * control_inputs;
369 LADSPA_Data dummy_control_output;
370 LADSPA_PortDescriptor pd;
372 unsigned long port_i; /* counter for iterating over ports */
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.
382 /* Enumerate the numbers of each type of port on the ladspa plugin */
384 nr_ci=0, /* control inputs */
385 nr_ai=0, /* audio inputs */
386 nr_co=0, /* control outputs */
387 nr_ao=0; /* audio outputs */
389 /* The number of audio channels to be processed */
390 gint nr_channels = format->channels;
392 /* The number of input and output buffers to use */
395 /* Counters for allocating input and output buffers */
399 /* instantiate the ladspa plugin */
400 handle = d->instantiate (d, (long)format->rate);
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))
407 if (LADSPA_IS_AUDIO_INPUT(pd))
409 if (LADSPA_IS_CONTROL_OUTPUT(pd))
411 if (LADSPA_IS_AUDIO_OUTPUT(pd))
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.
420 g_assert (nr_ai == nr_ao);
422 /* Basic assumption that this plugin has audio output.
423 * Also important as we are about to divide by nr_ao.
425 g_assert (nr_ao > 0);
427 iterations = (gint) ceil(((double)nr_channels) / ((double)nr_ao));
429 /* Numbers of input and output buffers: ensure
430 * nr_i >= nr_channels && nr_o >= nr_channels
432 nr_i = iterations * nr_ai;
433 nr_o = iterations * nr_ao;
435 if ((nr_channels == 1) && (nr_ai == 1) && (nr_ao >= 1)) {
437 * Processing a mono sample with a mono filter.
438 * Attempt to do this in place.
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;
447 input_buffers = (LADSPA_Data **)&pcmdata;
450 output_buffers = (LADSPA_Data **)&pcmdata;
453 length_b = LADSPA_frames_to_bytes (nr_frames);
455 /* Allocate zeroed input buffers; these will remain zeroed
456 * if there aren't enough channels in the input pcmdata
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);
464 output_buffers = g_malloc(sizeof(LADSPA_Data *) * nr_o);
466 /* Create separate output buffers if this ladspa plugin cannot
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);
473 /* Re-use the input buffers, directly mapping them to
474 * corresponding output buffers
476 for (i=0; i < MIN(nr_i, nr_o); i++) {
477 output_buffers[i] = input_buffers[i];
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);
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.
496 /* de-interleave multichannel data */
498 p = (LADSPA_Data *)pcmdata;
500 for (n=0; n < nr_channels; n++) {
501 for (i=0; i < nr_frames; i++) {
502 input_buffers[n][i] = *p++;
507 /* connect control ports */
508 control_inputs = g_malloc (nr_ci * sizeof(LADSPA_Data));
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:
517 * Data less than or equal to zero should be considered
519 * and data above zero should be considered `on' or `true.'
521 control_inputs[j] = pset[j].b ? 1.0 : 0.0;
524 control_inputs[j] = (LADSPA_Data)pset[j].i;
526 case SWEEP_TYPE_FLOAT:
527 control_inputs[j] = pset[j].f;
530 /* This plugin should produce no other types */
531 g_assert_not_reached ();
534 d->connect_port (handle, port_i, &control_inputs[j]);
537 if (LADSPA_IS_CONTROL_OUTPUT(pd)) {
538 d->connect_port (handle, port_i, &dummy_control_output);
542 /* run the plugin as many times as necessary */
543 while (iterations--) {
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++]);
552 if (LADSPA_IS_AUDIO_OUTPUT(pd)) {
553 d->connect_port (handle, port_i, output_buffers[obi++]);
557 /* activate the ladspa plugin */
559 d->activate (handle);
561 /* run the ladspa plugin */
562 d->run (handle, nr_frames);
564 /* deactivate the ladspa plugin */
566 d->deactivate (handle);
569 /* re-interleave data */
570 if (nr_channels > 1) {
571 p = (LADSPA_Data *)pcmdata;
573 for (n=0; n < nr_channels; n++) {
574 for (i=0; i < nr_frames; i++) {
575 *p++ = output_buffers[n][i];
580 /* let the ladspa plugin clean up after itself */
584 /* free the input and output buffers */
585 if (control_inputs) g_free (control_inputs);
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);
593 /* free the output buffers */
594 for (i=0; i < nr_o; i++) {
595 g_free (output_buffers[i]);
597 g_free (output_buffers);
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]);
605 /* inplace worked, but if (nr_i > nr_o), then
606 * we still need to free the last input buffers
608 for (i=nr_o; i < nr_i; i++) {
609 g_free (input_buffers[i]);
612 g_free (input_buffers);
618 remix_ladspa_connect_control_inputs (RemixEnv * env, RemixBase * base)
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;
626 unsigned long port_i;
631 remix_set_error (env, REMIX_ERROR_NOENTITY);
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);
642 case REMIX_TYPE_BOOL:
644 * Data less than or equal to zero should be considered
646 * and data above zero should be considered `on' or `true.'
648 al->control_inputs[j] = parameter.s_bool ? 1.0 : 0.0;
651 al->control_inputs[j] = (LADSPA_Data)parameter.s_int;
653 case REMIX_TYPE_FLOAT:
654 al->control_inputs[j] = parameter.s_float;
657 /* This plugin should produce no other types */
660 d->connect_port (al->handle, port_i, &al->control_inputs[j]);
663 if (LADSPA_IS_CONTROL_OUTPUT(pd)) {
664 d->connect_port (al->handle, port_i, &dummy_control_output);
672 remix_ladspa_1_0_process (RemixEnv * env, RemixBase * base, RemixCount count,
673 RemixStream * input, RemixStream * output)
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);
681 remix_ladspa_0_1_process (RemixEnv * env, RemixBase * base, RemixCount count,
682 RemixStream * input, RemixStream * output)
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);
690 remix_ladspa_1_1_process (RemixEnv * env, RemixBase * base, RemixCount count,
691 RemixStream * input, RemixStream * output)
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);
700 remix_ladspa_process (RemixEnv * env, RemixBase * base, RemixCount count,
701 RemixStream * input, RemixStream * output)
703 RemixPlugin * plugin = remix_base_get_plugin (env, base);
705 LADSPA_PortDescriptor pd;
706 unsigned long port_i; /* counter for iterating over ports */
708 /* Enumerate the numbers of each type of port on the ladspa plugin */
710 nr_ci=0, /* control inputs */
711 nr_ai=0, /* audio inputs */
712 nr_co=0, /* control outputs */
713 nr_ao=0; /* audio outputs */
715 if (plugin == RemixNone) {
716 remix_set_error (env, REMIX_ERROR_NOENTITY);
720 remix_ladspa_connect_control_inputs (env, base);
722 al = remix_base_get_instance_data (env, base);
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))
729 if (LADSPA_IS_AUDIO_INPUT(pd))
731 if (LADSPA_IS_CONTROL_OUTPUT(pd))
733 if (LADSPA_IS_AUDIO_OUTPUT(pd))
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);
745 remix_set_error (env, REMIX_ERROR_INVALID);
751 remix_ladspa_length (RemixEnv * env, RemixBase * base)
753 return REMIX_COUNT_INFINITE;
756 static struct _RemixMethods _remix_ladspa_1_0_methods = {
758 remix_ladspa_destroy,
759 remix_ladspa_ready, /* ready */
760 remix_ladspa_prepare, /* prepare */
761 remix_ladspa_1_0_process,
767 static struct _RemixMethods _remix_ladspa_0_1_methods = {
769 remix_ladspa_destroy,
770 remix_ladspa_ready, /* ready */
771 remix_ladspa_prepare, /* prepare */
772 remix_ladspa_0_1_process,
778 static struct _RemixMethods _remix_ladspa_1_1_methods = {
780 remix_ladspa_destroy,
781 remix_ladspa_ready, /* ready */
782 remix_ladspa_prepare, /* prepare */
783 remix_ladspa_1_1_process,
790 static struct _RemixMethods _remix_ladspa_methods = {
792 remix_ladspa_destroy,
793 remix_ladspa_ready, /* ready */
794 remix_ladspa_prepare, /* prepare */
795 remix_ladspa_process,
802 remix_ladspa_optimise (RemixEnv * env, RemixBase * base)
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 */
809 /* Enumerate the numbers of each type of port on the ladspa plugin */
811 nr_ci=0, /* control inputs */
812 nr_ai=0, /* audio inputs */
813 nr_co=0, /* control outputs */
814 nr_ao=0; /* audio outputs */
817 remix_set_error (env, REMIX_ERROR_NOENTITY);
824 remix_set_error (env, REMIX_ERROR_NOENTITY);
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))
833 if (LADSPA_IS_AUDIO_INPUT(pd))
835 if (LADSPA_IS_CONTROL_OUTPUT(pd))
837 if (LADSPA_IS_AUDIO_OUTPUT(pd))
841 al->control_inputs = malloc (nr_ci * sizeof (LADSPA_Data));
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);
850 remix_base_set_methods (env, base, &_remix_ladspa_methods);
858 * ladspa_wrapper_load_plugins (dir, name, gl)
860 * form RemixPlugins to describe the ladspa plugin functions that
861 * are in the shared library file "dir/name"
864 ladspa_wrapper_load_plugins (RemixEnv * env, char * dir, char * name)
868 LADSPA_Descriptor_Function desc_func;
869 const LADSPA_Descriptor * d;
870 LADSPA_PortDescriptor pd;
873 RemixPlugin * plugin;
875 RemixParameterScheme * scheme;
876 CDList * l, * plugins = CD_EMPTY_LIST;
878 static char buf[BUF_LEN];
881 snprintf (path, PATH_LEN, "%s/%s", dir, name);
883 if (stat (path, &statbuf) == -1) return CD_EMPTY_LIST;
884 if (!remix_stat_regular (statbuf.st_mode)) return CD_EMPTY_LIST;
886 module = dlopen (path, RTLD_NOW);
887 if (!module) return CD_EMPTY_LIST;
889 /* Check that this module has not already been loaded (eg. if it is
891 for (l = modules_list; l; l = l->next) {
892 if (l->data.s_pointer == module) {
894 return CD_EMPTY_LIST;
898 modules_list = cd_list_append (env, modules_list, CD_POINTER(module));
900 if ((desc_func = dlsym (module, "ladspa_descriptor"))) {
901 for (i=0; (d = desc_func (i)) != NULL; i++) {
906 remix_dprintf ("[ladspa_wrapper_load_plugins] adding %s [%lu] by %s\n",
907 d->Name, d->UniqueID, d->Maker);
909 plugin = malloc (sizeof (*plugin));
911 mt = remix_meta_text_new (env);
913 snprintf (buf, BUF_LEN, "ladspa::%lu", d->UniqueID);
914 remix_meta_text_set_identifier (env, mt, strdup (buf));
916 snprintf (buf, BUF_LEN, "Miscellaneous::%s", d->Name);
917 remix_meta_text_set_category (env, mt, strdup (buf));
919 remix_meta_text_set_copyright (env, mt, (char *)d->Copyright);
920 remix_meta_text_add_author (env, mt, (char *)d->Maker, NULL);
922 plugin->metatext = mt;
924 plugin->init_scheme = CD_EMPTY_SET;
925 plugin->process_scheme = CD_EMPTY_SET;
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));
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;
940 scheme->constraint_type = REMIX_CONSTRAINT_TYPE_RANGE;
941 scheme->constraint.range =
942 convert_constraint (&d->PortRangeHints[j]);
944 plugin->process_scheme = cd_set_insert (env, plugin->process_scheme,
945 k, CD_POINTER(scheme));
950 plugin->init = remix_ladspa_init;
952 plugin->plugin_data = (void *)d;
954 plugin->destroy = NULL;
956 plugins = cd_list_append (env, plugins, CD_POINTER(plugin));
966 * ladspa_wrapper_load_dir (dir, gl)
968 * scan a directory "dirname" for LADSPA plugins, and attempt to load
972 ladspa_wrapper_load_dir (RemixEnv * env, char * dirname)
975 struct dirent * dirent;
976 CDList * plugins = CD_EMPTY_LIST, * l;
978 if (!dirname) return plugins;
980 dir = opendir (dirname);
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);
996 remix_load (RemixEnv * env)
998 CDList * plugins = CD_EMPTY_LIST, * l;
999 char * ladspa_path=NULL;
1000 char * next_sep=NULL;
1001 char * saved_lp=NULL;
1003 /* If this ladspa_wrapper module has already been initialised, don't
1004 * initialise again until cleaned up.
1006 if (ladspa_wrapper_initialised)
1007 return CD_EMPTY_LIST;
1009 ladspa_path = getenv ("LADSPA_PATH");
1011 ladspa_path = saved_lp = strdup(default_ladspa_path);
1014 next_sep = strchr (ladspa_path, ':');
1015 if (next_sep != NULL) *next_sep = '\0';
1017 l = ladspa_wrapper_load_dir (env, ladspa_path);
1018 plugins = cd_list_join (env, plugins, l);
1020 if (next_sep != NULL) ladspa_path = ++next_sep;
1022 } while ((next_sep != NULL) && (*next_sep != '\0'));
1024 ladspa_wrapper_initialised = TRUE;
1026 /* free string if dup'd for ladspa_path */
1027 if (saved_lp != NULL) free(saved_lp);
1033 remix_unload (RemixEnv * env)
1037 if (!ladspa_wrapper_initialised) return;
1039 for (l = modules_list; l; l = l->next) {
1040 dlclose(l->data.s_pointer);
1043 modules_list = NULL;