1
/* ------------------------------------------------------------------------- */
4
* af_ladspa.c, LADSPA plugin loader
6
* Written by Ivo van Poorten <ivop@euronet.nl>
7
* Copyright (C) 2004, 2005
9
* This program is free software; you can redistribute it and/or
10
* modify it under the terms of the GNU General Public License
11
* as published by the Free Software Foundation; either version 2
12
* of the License, or (at your option) any later version.
14
* This program is distributed in the hope that it will be useful,
15
* but WITHOUT ANY WARRANTY; without even the implied warranty of
16
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17
* GNU General Public License for more details.
19
* You should have received a copy of the GNU General Public License
20
* along with this program; if not, write to the Free Software
21
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
26
* 2005-06-21 Replaced erroneous use of mp_msg by af_msg
27
* 2005-05-30 Removed int16 to float conversion; leave that to af_format
28
* 2004-12-23 Added to CVS
29
* 2004-12-22 Cleaned up cosmetics
30
* Made conversion loops in play() more cache-friendly
31
* 2004-12-20 Fixed bug for stereo effect on mono signal
32
* (trivial >1 to >=1 change; would segfault otherwise :-) )
33
* Removed trailing whitespace and fixed warn/err messages
34
* Have CONTROL_REINIT return a proper value
35
* 2004-12-13 More Doxygen comments
36
* 2004-12-12 Made af_ladspa optional (updated configure, af.c, etc.)
37
* 2004-12-11 Added deactivate and cleanup to uninit.
38
* Finished Doxygen comments.
39
* Moved translatable messages to help_mp-en.h
40
* 2004-12-10 Added ranges to list of controls for ease of use.
41
* Fixed sig11 bug. Implemented (dummy) outputcontrols. Some
42
* perfectly normal audio processing filters also have output
44
* 2004-12-08 Added support for generators (no input, one output)
45
* Added support for stereo effects
46
* Added LADSPA_PATH support!
47
* 2004-12-07 Fixed changing buffersize. Now it's really working, also in
49
* 2004-12-06 First working version, mono-effects (1 input --> 1 output) only
50
* 2004-12-05 Started, Loading of plugin/label, Check inputs/outputs/controls
51
* Due to lack of documentation, I studied the ladspa_sdk source
52
* code and the loader code of Audacity (by Dominic Mazzoni). So,
53
* certain similarities in (small) pieces of code are not
54
* coincidental :-) No C&P jobs though!
58
/* ------------------------------------------------------------------------- */
74
/* ------------------------------------------------------------------------- */
81
/* ------------------------------------------------------------------------- */
83
/* Filter specific data */
85
typedef struct af_ladspa_s
87
int status; /**< Status of the filter.
88
* Either AF_OK or AF_ERROR
89
* Because MPlayer re-inits audio filters that
90
* _clearly_ returned AF_ERROR anyway, I use this
91
* in play() to skip the processing and return
95
int activated; /**< 0 or 1. Activate LADSPA filters only once, even
96
* if the buffers get resized, to avoid a stuttering
103
char *myname; /**< It's easy to have a concatenation of file and label */
106
const LADSPA_Descriptor *plugin_descriptor;
117
int *inputcontrolsmap; /**< Map input port number [0-] to actual port */
118
float *inputcontrols;
121
int *outputcontrolsmap;
122
float *outputcontrols;
124
int nch; /**< number of channels */
128
LADSPA_Handle *chhandles;
132
/* ------------------------------------------------------------------------- */
134
static int open(af_instance_t *af);
135
static int af_ladspa_malloc_failed(char*);
137
/* ------------------------------------------------------------------------- */
141
af_info_t af_info_ladspa = {
142
"LADSPA plugin loader",
150
/* ------------------------------------------------------------------------- */
152
/* By lack of a better word (in my vocabulary) this is called 'parse'.
153
* Feel free to suggest an alternative.
156
/** \brief Check for inputs, outputs and controls of a given filter.
158
* This function counts and checks all input, output and control ports
159
* of the filter that was loaded. If it turns out to be a valid
160
* filter for MPlayer use, it prints out a list of all controls and
161
* the corresponding range of its value at message level MSGL_V.
163
* \param setup Current setup of the filter. Must have its
164
* plugin_descriptor set!
166
* \return Returns AF_OK if it has a valid input/output/controls
167
* configuration. Else, it returns AF_ERROR.
170
static int af_ladspa_parse_plugin(af_ladspa_t *setup) {
172
const LADSPA_Descriptor *pdes = setup->plugin_descriptor;
173
LADSPA_PortDescriptor d;
174
LADSPA_PortRangeHint hint;
176
if (!setup->libhandle)
177
return AF_ERROR; /* only call parse after a succesful load */
178
if (!setup->plugin_descriptor)
179
return AF_ERROR; /* same as above */
183
setup->nports = pdes->PortCount;
185
/* allocate memory for all inputs/outputs/controls */
187
setup->inputs = calloc(setup->nports, sizeof(int));
188
if (!setup->inputs) return af_ladspa_malloc_failed(setup->myname);
190
setup->outputs = calloc(setup->nports, sizeof(int));
191
if (!setup->outputs) return af_ladspa_malloc_failed(setup->myname);
193
setup->inputcontrolsmap = calloc(setup->nports, sizeof(int));
194
if (!setup->inputcontrolsmap) return af_ladspa_malloc_failed(setup->myname);
196
setup->inputcontrols = calloc(setup->nports, sizeof(float));
197
if (!setup->inputcontrols) return af_ladspa_malloc_failed(setup->myname);
199
setup->outputcontrolsmap = calloc(setup->nports, sizeof(int));
200
if (!setup->outputcontrolsmap) return af_ladspa_malloc_failed(setup->myname);
202
setup->outputcontrols = calloc(setup->nports, sizeof(float));
203
if (!setup->outputcontrols) return af_ladspa_malloc_failed(setup->myname);
205
/* set counts to zero */
209
setup->ninputcontrols = 0;
210
setup->noutputcontrols = 0;
212
/* check all ports, see what type it is and set variables according to
216
for (p=0; p<setup->nports; p++) {
217
d = pdes->PortDescriptors[p];
219
if (LADSPA_IS_PORT_AUDIO(d)) {
220
if (LADSPA_IS_PORT_INPUT(d)) {
221
setup->inputs[setup->ninputs] = p;
223
} else if (LADSPA_IS_PORT_OUTPUT(d)) {
224
setup->outputs[setup->noutputs] = p;
229
if (LADSPA_IS_PORT_CONTROL(d)) {
230
if (LADSPA_IS_PORT_INPUT(d)) {
231
setup->inputcontrolsmap[setup->ninputcontrols] = p;
232
setup->ninputcontrols++;
233
/* set control to zero. set values after reading the rest
234
* of the suboptions and check LADSPA_?_HINT's later.
236
setup->inputcontrols[p] = 0.0f;
237
} else if (LADSPA_IS_PORT_OUTPUT(d)) {
238
/* read and handle these too, otherwise filters that have them
241
setup->outputcontrolsmap[setup->noutputcontrols]=p;
242
setup->noutputcontrols++;
243
setup->outputcontrols[p] = 0.0f;
249
if (setup->ninputs == 0) {
250
af_msg(AF_MSG_WARN, "%s: %s\n", setup->myname,
251
MSGTR_AF_LADSPA_WarnNoInputs);
252
} else if (setup->ninputs == 1) {
253
af_msg(AF_MSG_VERBOSE, "%s: this is a mono effect\n", setup->myname);
254
} else if (setup->ninputs == 2) {
255
af_msg(AF_MSG_VERBOSE, "%s: this is a stereo effect\n", setup->myname);
258
if (setup->ninputs > 2) {
259
af_msg(AF_MSG_ERROR, "%s: %s\n", setup->myname,
260
MSGTR_AF_LADSPA_ErrMultiChannel);
264
if (setup->noutputs == 0) {
265
af_msg(AF_MSG_ERROR, "%s: %s\n", setup->myname,
266
MSGTR_AF_LADSPA_ErrNoOutputs);
270
if (setup->noutputs != setup->ninputs ) {
271
af_msg(AF_MSG_ERROR, "%s: %s\n", setup->myname,
272
MSGTR_AF_LADSPA_ErrInOutDiff);
276
af_msg(AF_MSG_VERBOSE, "%s: this plugin has %d input control(s)\n",
277
setup->myname, setup->ninputcontrols);
279
/* Print list of controls and its range of values it accepts */
281
for (i=0; i<setup->ninputcontrols; i++) {
282
p = setup->inputcontrolsmap[i];
283
hint = pdes->PortRangeHints[p];
284
af_msg(AF_MSG_VERBOSE, " --- %d %s [", i, pdes->PortNames[p]);
286
if (LADSPA_IS_HINT_BOUNDED_BELOW(hint.HintDescriptor)) {
287
af_msg(AF_MSG_VERBOSE, "%0.2f , ", hint.LowerBound);
289
af_msg(AF_MSG_VERBOSE, "... , ");
292
if (LADSPA_IS_HINT_BOUNDED_ABOVE(hint.HintDescriptor)) {
293
af_msg(AF_MSG_VERBOSE, "%0.2f]\n", hint.UpperBound);
295
af_msg(AF_MSG_VERBOSE, "...]\n");
303
/* ------------------------------------------------------------------------- */
305
/* This function might "slightly" look like dlopenLADSPA in the LADSPA SDK :-)
306
* But, I changed a few things, because imho it was broken. It did not support
307
* relative paths, only absolute paths that start with a /
308
* I think ../../some/dir/foobar.so is just as valid. And if one wants to call
309
* his library '...somename...so' he's crazy, but it should be allowed.
310
* So, search the path first, try plain *filename later.
311
* Also, try adding .so first! I like the recursion the SDK did, but it's
312
* better the other way around. -af ladspa=cmt:amp_stereo:0.5 is easier to type
313
* than -af ladspa=cmt.so:amp_stereo:0.5 :-))
316
/** \brief dlopen() wrapper
318
* This is a wrapper around dlopen(). It tries various variations of the
319
* filename (with or without the addition of the .so extension) in various
320
* directories specified by the LADSPA_PATH environment variable. If all fails
321
* it tries the filename directly as an absolute path to the library.
323
* \param filename filename of the library to load.
324
* \param flag see dlopen(3) for a description of the flags.
326
* \return returns a pointer to the loaded library on success, or
327
* NULL if it fails to load.
330
static void* mydlopen(const char *filename, int flag) {
332
const char *end, *start, *ladspapath;
333
int endsinso, needslash;
337
# ifdef WIN32 /* for windows there's only absolute path support.
338
* if you have a windows machine, feel free to fix
339
* this. (path separator, shared objects extension,
342
af_msg(AF_MSG_VERBOSE, "\ton windows, only absolute pathnames "
344
af_msg(AF_MSG_VERBOSE, "\ttrying %s\n", filename);
345
return dlopen(filename, flag);
348
filenamelen = strlen(filename);
352
endsinso = (strcmp(filename+filenamelen-3, ".so") == 0);
354
buf=malloc(filenamelen+4);
355
strcpy(buf, filename);
357
result=mydlopen(buf, flag);
364
ladspapath=getenv("LADSPA_PATH");
369
while (*start != '\0') {
371
while ( (*end != ':') && (*end != '\0') )
374
buf=malloc(filenamelen + 2 + (end-start) );
376
strncpy(buf, start, end-start);
379
if (*(end-1) != '/') {
381
buf[end-start] = '/';
383
strcpy(buf+needslash+(end-start), filename);
385
af_msg(AF_MSG_VERBOSE, "\ttrying %s\n", buf);
386
result=dlopen(buf, flag);
395
} /* end while there's still more in the path */
396
} /* end if there's a ladspapath */
398
/* last resort, just open it again, so the dlerror() message is correct */
399
af_msg(AF_MSG_VERBOSE, "\ttrying %s\n", filename);
400
return dlopen(filename,flag);
403
/* ------------------------------------------------------------------------- */
405
/** \brief Load a LADSPA Plugin
407
* This function loads the LADSPA plugin specified by the file and label
408
* that are present in the setup variable. First, it loads the library.
409
* If it fails, it returns AF_ERROR. If not, it continues to look for the
410
* specified label. If it finds it, it sets the plugin_descriptor inside
411
* setup and returns AF_OK. If it doesn't, it returns AF_ERROR. Special case
412
* is a label called 'help'. In that case, it prints a list of all available
413
* labels (filters) in the library specified by file.
415
* \param setup Current setup of the filter. Contains filename and label.
417
* \return Either AF_ERROR or AF_OK, depending on the success of the operation.
420
static int af_ladspa_load_plugin(af_ladspa_t *setup) {
421
const LADSPA_Descriptor *ladspa_descriptor;
422
LADSPA_Descriptor_Function descriptor_function;
426
af_msg(AF_MSG_VERBOSE, "%s: loading ladspa plugin library %s\n",
427
setup->myname, setup->file);
429
setup->libhandle = mydlopen(setup->file, RTLD_NOW);
431
if (!setup->libhandle) {
432
af_msg(AF_MSG_ERROR, "%s: %s %s\n\t%s\n", setup->myname,
433
MSGTR_AF_LADSPA_ErrFailedToLoad, setup->file, dlerror() );
437
af_msg(AF_MSG_VERBOSE, "%s: library found.\n", setup->myname);
439
/* find descriptor function */
441
descriptor_function = (LADSPA_Descriptor_Function) dlsym (setup->libhandle,
442
"ladspa_descriptor");
444
if (!descriptor_function) {
445
af_msg(AF_MSG_ERROR, "%s: %s\n\t%s\n", setup->myname,
446
MSGTR_AF_LADSPA_ErrNoDescriptor, dlerror());
450
/* if label == help, list all labels in library and exit */
452
if (strcmp(setup->label, "help") == 0) {
453
af_msg(AF_MSG_INFO, "%s: %s %s:\n", setup->myname,
454
MSGTR_AF_LADSPA_AvailableLabels, setup->file);
456
ladspa_descriptor = descriptor_function(i);
457
if (ladspa_descriptor == NULL) {
460
af_msg(AF_MSG_INFO, " %-16s - %s (%lu)\n",
461
ladspa_descriptor->Label,
462
ladspa_descriptor->Name,
463
ladspa_descriptor->UniqueID);
467
af_msg(AF_MSG_VERBOSE, "%s: looking for label\n", setup->myname);
469
/* find label in library */
471
ladspa_descriptor = descriptor_function(i);
472
if (ladspa_descriptor == NULL) {
473
af_msg(AF_MSG_ERROR, "%s: %s\n", setup->myname,
474
MSGTR_AF_LADSPA_ErrLabelNotFound);
477
if (strcmp(ladspa_descriptor->Label, setup->label) == 0) {
478
setup->plugin_descriptor = ladspa_descriptor;
479
af_msg(AF_MSG_VERBOSE, "%s: %s found\n", setup->myname,
488
/* ------------------------------------------------------------------------- */
490
/** \brief Print a malloc() failed error message.
492
* Generic function which can be called if a call to malloc(), calloc(),
493
* strdup(), et cetera, failed. It prints a message to the console and
499
static int af_ladspa_malloc_failed(char *myname) {
500
af_msg(AF_MSG_ERROR, "%s: %s", myname, MSGTR_MemAllocFailed);
504
/* ------------------------------------------------------------------------- */
506
/** \brief Controls the filter.
508
* Control the behaviour of the filter.
511
* CONTROL_REINIT Sets the af structure with proper values for number
512
* of channels, rate, format, et cetera.
513
* CONTROL_COMMAND_LINE Parses the suboptions given to this filter
514
* through arg. It first parses the filename and
515
* the label. After that, it loads the filter
516
* and finds out its proprties. Then in continues
517
* parsing the controls given on the commandline,
520
* \param af Audio filter instance
521
* \param cmd The command to execute
522
* \param arg Arguments to the command
524
* \return Either AF_ERROR or AF_OK, depending on the succes of the
528
static int control(struct af_instance_s *af, int cmd, void *arg) {
529
af_ladspa_t *setup = (af_ladspa_t*) af->setup;
534
case AF_CONTROL_REINIT:
535
af_msg(AF_MSG_VERBOSE, "%s: (re)init\n", setup->myname);
537
if (!arg) return AF_ERROR;
539
/* accept FLOAT, let af_format do conversion */
541
af->data->rate = ((af_data_t*)arg)->rate;
542
af->data->nch = ((af_data_t*)arg)->nch;
543
af->data->format = AF_FORMAT_FLOAT_NE;
546
/* arg->len is not set here yet, so init of buffers and connecting the
547
* filter, has to be done in play() :-/
550
return af_test_output(af, (af_data_t*)arg);
551
case AF_CONTROL_COMMAND_LINE: {
554
af_msg(AF_MSG_VERBOSE, "%s: parse suboptions\n", setup->myname);
556
/* suboption parser here!
557
* format is (ladspa=)file:label:controls....
561
af_msg(AF_MSG_ERROR, "%s: %s\n", setup->myname,
562
MSGTR_AF_LADSPA_ErrNoSuboptions);
566
buf = malloc(strlen(arg)+1);
567
if (!buf) return af_ladspa_malloc_failed(setup->myname);
571
sscanf(arg, "%[^:]", buf);
572
if (buf[0] == '\0') {
573
af_msg(AF_MSG_ERROR, "%s: %s\n", setup->myname,
574
MSGTR_AF_LADSPA_ErrNoLibFile);
579
setup->file = strdup(buf);
580
if (!setup->file) return af_ladspa_malloc_failed(setup->myname);
581
af_msg(AF_MSG_VERBOSE, "%s: file --> %s\n", setup->myname,
583
if (*(char*)arg != '\0') arg++; /* read ':' */
587
sscanf(arg, "%[^:]", buf);
588
if (buf[0] == '\0') {
589
af_msg(AF_MSG_ERROR, "%s: %s\n", setup->myname,
590
MSGTR_AF_LADSPA_ErrNoLabel);
595
setup->label = strdup(buf);
596
if (!setup->label) return af_ladspa_malloc_failed(setup->myname);
597
af_msg(AF_MSG_VERBOSE, "%s: label --> %s\n", setup->myname,
599
/* if (*(char*)arg != '0') arg++; */ /* read ':' */
601
free(buf); /* no longer needed */
603
/* set new setup->myname */
605
if(setup->myname) free(setup->myname);
606
setup->myname = calloc(strlen(af_info_ladspa.name)+strlen(setup->file)+
607
strlen(setup->label)+6, 1);
608
snprintf(setup->myname, strlen(af_info_ladspa.name)+
609
strlen(setup->file)+strlen(setup->label)+6, "%s: (%s:%s)",
610
af_info_ladspa.name, setup->file, setup->label);
614
if ( af_ladspa_load_plugin(setup) != AF_OK )
617
/* see what inputs, outputs and controls this plugin has */
618
if ( af_ladspa_parse_plugin(setup) != AF_OK )
621
/* ninputcontrols is set by now, read control values from arg */
623
for(i=0; i<setup->ninputcontrols; i++) {
624
if (!arg || (*(char*)arg != ':') ) {
625
af_msg(AF_MSG_ERROR, "%s: %s\n", setup->myname,
626
MSGTR_AF_LADSPA_ErrNotEnoughControls);
630
r = sscanf(arg, "%f", &val);
632
af_msg(AF_MSG_ERROR, "%s: %s\n", setup->myname,
633
MSGTR_AF_LADSPA_ErrNotEnoughControls);
636
setup->inputcontrols[setup->inputcontrolsmap[i]] = val;
637
arg = strchr(arg, ':');
640
af_msg(AF_MSG_VERBOSE, "%s: input controls: ", setup->myname);
641
for(i=0; i<setup->ninputcontrols; i++) {
642
af_msg(AF_MSG_VERBOSE, "%0.4f ",
643
setup->inputcontrols[setup->inputcontrolsmap[i]]);
645
af_msg(AF_MSG_VERBOSE, "\n");
647
/* check boundaries of inputcontrols */
649
af_msg(AF_MSG_VERBOSE, "%s: checking boundaries of input controls\n",
651
for(i=0; i<setup->ninputcontrols; i++) {
652
int p = setup->inputcontrolsmap[i];
653
LADSPA_PortRangeHint hint =
654
setup->plugin_descriptor->PortRangeHints[p];
655
val = setup->inputcontrols[p];
657
if (LADSPA_IS_HINT_BOUNDED_BELOW(hint.HintDescriptor) &&
658
val < hint.LowerBound) {
659
af_msg(AF_MSG_ERROR, MSGTR_AF_LADSPA_ErrControlBelow,
660
setup->myname, i, hint.LowerBound);
663
if (LADSPA_IS_HINT_BOUNDED_ABOVE(hint.HintDescriptor) &&
664
val > hint.UpperBound) {
665
af_msg(AF_MSG_ERROR, MSGTR_AF_LADSPA_ErrControlAbove,
666
setup->myname, i, hint.UpperBound);
670
af_msg(AF_MSG_VERBOSE, "%s: all controls have sane values\n",
674
setup->status = AF_OK;
682
/* ------------------------------------------------------------------------- */
684
/** \brief Uninitialise the LADSPA Plugin Loader filter.
686
* This function deactivates the plugin(s), cleans up, frees all allocated
689
* \return No return value.
692
static void uninit(struct af_instance_s *af) {
698
af_ladspa_t *setup = (af_ladspa_t*) af->setup;
699
const LADSPA_Descriptor *pdes = setup->plugin_descriptor;
702
af_msg(AF_MSG_VERBOSE, "%s: cleaning up\n", setup->myname);
706
if (setup->chhandles) {
707
for(i=0; i<setup->nch; i++) {
708
if ( (setup->ninputs == 2) && (i & 1) ) { /* stereo effect */
712
if (pdes->deactivate) pdes->deactivate(setup->chhandles[i]);
713
if (pdes->cleanup) pdes->cleanup(setup->chhandles[i]);
715
free(setup->chhandles);
722
if (setup->inputcontrolsmap)
723
free(setup->inputcontrolsmap);
724
if (setup->inputcontrols)
725
free(setup->inputcontrols);
726
if (setup->outputcontrolsmap)
727
free(setup->outputcontrolsmap);
728
if (setup->outputcontrols)
729
free(setup->outputcontrols);
733
free(setup->outputs);
736
for(i=0; i<setup->nch; i++) {
737
if (setup->inbufs[i])
738
free(setup->inbufs[i]);
743
if (setup->outbufs) {
744
for(i=0; i<setup->nch; i++) {
745
if (setup->outbufs[i])
746
free(setup->outbufs[i]);
748
free(setup->outbufs);
751
if (setup->libhandle)
752
dlclose(setup->libhandle);
759
/* ------------------------------------------------------------------------- */
761
/** \brief Process chunk of audio data through the selected LADSPA Plugin.
763
* \param af Pointer to audio filter instance
764
* \param data Pointer to chunk of audio data
766
* \return Either AF_ERROR or AF_OK
769
static af_data_t* play(struct af_instance_s *af, af_data_t *data) {
770
af_ladspa_t *setup = af->setup;
771
const LADSPA_Descriptor *pdes = setup->plugin_descriptor;
772
float *audio = (float*)data->audio;
773
int nsamples = data->len/4; /* /4 because it's 32-bit float */
775
int rate = data->rate;
778
if (setup->status !=AF_OK)
781
/* See if it's the first call. If so, setup inbufs/outbufs, instantiate
782
* plugin, connect ports and activate plugin
785
/* 2004-12-07: Also check if the buffersize has to be changed!
786
* data->len is not constant per se! re-init buffers.
789
if ( (setup->bufsize != nsamples/nch) || (setup->nch != nch) ) {
791
/* if setup->nch==0, it's the first call, if not, something has
792
* changed and all previous mallocs have to be freed
795
if (setup->nch != 0) {
796
af_msg(AF_MSG_DEBUG1, "%s: bufsize change; free old buffer\n",
800
for(i=0; i<setup->nch; i++) {
802
free(setup->inbufs[i]);
807
for(i=0; i<setup->nch; i++) {
808
if(setup->outbufs[i])
809
free(setup->outbufs[i]);
811
free(setup->outbufs);
813
} /* everything is freed */
815
setup->bufsize = nsamples/nch;
818
setup->inbufs = calloc(nch, sizeof(float*));
819
setup->outbufs = calloc(nch, sizeof(float*));
821
af_msg(AF_MSG_DEBUG1, "%s: bufsize = %d\n",
822
setup->myname, setup->bufsize);
824
for(i=0; i<nch; i++) {
825
setup->inbufs[i] = calloc(setup->bufsize, sizeof(float));
826
setup->outbufs[i] = calloc(setup->bufsize, sizeof(float));
829
/* only on the first call, there are no handles. */
831
if (!setup->chhandles) {
832
setup->chhandles = calloc(nch, sizeof(LADSPA_Handle));
835
* for stereo effects, create one handle for two channels
838
for(i=0; i<nch; i++) {
840
if ( (setup->ninputs == 2) && (i & 1) ) { /* stereo effect */
841
/* copy the handle from previous channel */
842
setup->chhandles[i] = setup->chhandles[i-1];
846
setup->chhandles[i] = pdes->instantiate(pdes, rate);
850
/* connect input/output ports for each channel/filter instance
852
* always (re)connect ports
855
for(i=0; i<nch; i++) {
856
pdes->connect_port(setup->chhandles[i],
857
setup->inputs[ (setup->ninputs==2) ? i&1 : 0 ],
859
pdes->connect_port(setup->chhandles[i],
860
setup->outputs[ (setup->ninputs==2) ? i&1 : 0 ],
863
/* connect (input) controls */
865
for (p=0; p<setup->nports; p++) {
866
LADSPA_PortDescriptor d = pdes->PortDescriptors[p];
867
if (LADSPA_IS_PORT_CONTROL(d)) {
868
if (LADSPA_IS_PORT_INPUT(d)) {
869
pdes->connect_port(setup->chhandles[i], p,
870
&(setup->inputcontrols[p]) );
872
pdes->connect_port(setup->chhandles[i], p,
873
&(setup->outputcontrols[p]) );
878
/* Activate filter (if it isn't already :) ) */
880
if ( (pdes->activate) && (setup->activated == 0) ) {
881
pdes->activate(setup->chhandles[i]);
882
setup->activated = 1;
885
} /* All channels/filters done! except for... */
887
/* Stereo effect with one channel left. Use same buffer for left
888
* and right. connect it to the second port.
891
if( (setup->ninputs == 2) && (i&1) && (i >= 1) ) {
892
pdes->connect_port(setup->chhandles[i-1],
893
setup->inputs[ (setup->ninputs==2) ? i&1 : 0 ],
895
pdes->connect_port(setup->chhandles[i-1],
896
setup->outputs[ (setup->ninputs==2) ? i&1 : 0 ],
897
setup->outbufs[i-1]);
900
} /* setup for first call/change of bufsize is done.
901
* normal playing routine follows...
904
/* Right now, I use a separate input and output buffer.
905
* I could change this to in-place processing (inbuf==outbuf), but some
906
* ladspa filters are broken and are not able to handle that. This seems
907
* fast enough, so unless somebody complains, it stays this way :)
912
for (p=0; p<setup->bufsize; p++) {
913
for (i=0; i<nch; i++) {
914
setup->inbufs[i][p] = audio[p*nch + i];
920
for (i=0; i<nch; i++) {
921
pdes->run(setup->chhandles[i], setup->bufsize);
922
if (setup->ninputs==2) // stereo effect just ran
926
/* Extract outbufs */
928
for (p=0; p<setup->bufsize; p++) {
929
for (i=0; i<nch; i++) {
930
audio[p*nch + i] = setup->outbufs[i][p];
939
/* ------------------------------------------------------------------------- */
941
/** \brief Open LADSPA Plugin Loader Filter
943
* \param af Audio Filter instance
945
* \return Either AF_ERROR or AF_OK
948
static int open(af_instance_t *af) {
956
af->data = calloc(1, sizeof(af_data_t));
957
if (af->data == NULL)
958
return af_ladspa_malloc_failed((char*)af_info_ladspa.name);
960
af->setup = calloc(1, sizeof(af_ladspa_t));
961
if (af->setup == NULL) {
964
return af_ladspa_malloc_failed((char*)af_info_ladspa.name);
967
((af_ladspa_t*)af->setup)->status = AF_ERROR; /* will be set to AF_OK if
968
* all went OK and play()
972
((af_ladspa_t*)af->setup)->myname = strdup(af_info_ladspa.name);
973
if (!((af_ladspa_t*)af->setup)->myname)
974
return af_ladspa_malloc_failed((char*)af_info_ladspa.name);
979
/* ------------------------------------------------------------------------- */