And a 1000l for r27263, swapped a condition, thus setting size to
[mplayer/glamo.git] / libaf / af_ladspa.c
blobdadbc45548e6b19f0959cf5559e9da01ca8d3abb
1 /*
2 * af_ladspa.c, LADSPA plugin loader
4 * Written by Ivo van Poorten <ivop@euronet.nl>
5 * Copyright (C) 2004, 2005
7 * This file is part of MPlayer.
9 * MPlayer is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
14 * MPlayer 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 along
20 * with MPlayer; if not, write to the Free Software Foundation, Inc.,
21 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
24 /* ------------------------------------------------------------------------- */
26 /* Global Includes */
28 #include <stdio.h>
29 #include <stdlib.h>
30 #include <string.h>
32 #include <inttypes.h>
33 #include <math.h>
34 #include <limits.h>
36 #include <dlfcn.h>
37 #include <ladspa.h>
39 /* ------------------------------------------------------------------------- */
41 /* Local Includes */
43 #include "af.h"
44 #include "help_mp.h"
46 /* ------------------------------------------------------------------------- */
48 /* Filter specific data */
50 typedef struct af_ladspa_s
52 int status; /**< Status of the filter.
53 * Either AF_OK or AF_ERROR
54 * Because MPlayer re-inits audio filters that
55 * _clearly_ returned AF_ERROR anyway, I use this
56 * in play() to skip the processing and return
57 * the data unchanged.
60 int activated; /**< 0 or 1. Activate LADSPA filters only once, even
61 * if the buffers get resized, to avoid a stuttering
62 * filter.
65 char *file;
66 char *label;
68 char *myname; /**< It's easy to have a concatenation of file and label */
70 void *libhandle;
71 const LADSPA_Descriptor *plugin_descriptor;
73 int nports;
75 int ninputs;
76 int *inputs;
78 int noutputs;
79 int *outputs;
81 int ninputcontrols;
82 int *inputcontrolsmap; /**< Map input port number [0-] to actual port */
83 float *inputcontrols;
85 int noutputcontrols;
86 int *outputcontrolsmap;
87 float *outputcontrols;
89 int nch; /**< number of channels */
90 int bufsize;
91 float **inbufs;
92 float **outbufs;
93 LADSPA_Handle *chhandles;
95 } af_ladspa_t;
97 /* ------------------------------------------------------------------------- */
99 static int af_open(af_instance_t *af);
100 static int af_ladspa_malloc_failed(char*);
102 /* ------------------------------------------------------------------------- */
104 /* Description */
106 af_info_t af_info_ladspa = {
107 "LADSPA plugin loader",
108 "ladspa",
109 "Ivo van Poorten",
111 AF_FLAGS_REENTRANT,
112 af_open
115 /* ------------------------------------------------------------------------- */
117 /* By lack of a better word (in my vocabulary) this is called 'parse'.
118 * Feel free to suggest an alternative.
121 /** \brief Check for inputs, outputs and controls of a given filter.
123 * This function counts and checks all input, output and control ports
124 * of the filter that was loaded. If it turns out to be a valid
125 * filter for MPlayer use, it prints out a list of all controls and
126 * the corresponding range of its value at message level MSGL_V.
128 * \param setup Current setup of the filter. Must have its
129 * plugin_descriptor set!
131 * \return Returns AF_OK if it has a valid input/output/controls
132 * configuration. Else, it returns AF_ERROR.
135 static int af_ladspa_parse_plugin(af_ladspa_t *setup) {
136 int p, i;
137 const LADSPA_Descriptor *pdes = setup->plugin_descriptor;
138 LADSPA_PortDescriptor d;
139 LADSPA_PortRangeHint hint;
141 if (!setup->libhandle)
142 return AF_ERROR; /* only call parse after a succesful load */
143 if (!setup->plugin_descriptor)
144 return AF_ERROR; /* same as above */
146 /* let's do it */
148 setup->nports = pdes->PortCount;
150 /* allocate memory for all inputs/outputs/controls */
152 setup->inputs = calloc(setup->nports, sizeof(int));
153 if (!setup->inputs) return af_ladspa_malloc_failed(setup->myname);
155 setup->outputs = calloc(setup->nports, sizeof(int));
156 if (!setup->outputs) return af_ladspa_malloc_failed(setup->myname);
158 setup->inputcontrolsmap = calloc(setup->nports, sizeof(int));
159 if (!setup->inputcontrolsmap) return af_ladspa_malloc_failed(setup->myname);
161 setup->inputcontrols = calloc(setup->nports, sizeof(float));
162 if (!setup->inputcontrols) return af_ladspa_malloc_failed(setup->myname);
164 setup->outputcontrolsmap = calloc(setup->nports, sizeof(int));
165 if (!setup->outputcontrolsmap) return af_ladspa_malloc_failed(setup->myname);
167 setup->outputcontrols = calloc(setup->nports, sizeof(float));
168 if (!setup->outputcontrols) return af_ladspa_malloc_failed(setup->myname);
170 /* set counts to zero */
172 setup->ninputs = 0;
173 setup->noutputs = 0;
174 setup->ninputcontrols = 0;
175 setup->noutputcontrols = 0;
177 /* check all ports, see what type it is and set variables according to
178 * what we have found
181 for (p=0; p<setup->nports; p++) {
182 d = pdes->PortDescriptors[p];
184 if (LADSPA_IS_PORT_AUDIO(d)) {
185 if (LADSPA_IS_PORT_INPUT(d)) {
186 setup->inputs[setup->ninputs] = p;
187 setup->ninputs++;
188 } else if (LADSPA_IS_PORT_OUTPUT(d)) {
189 setup->outputs[setup->noutputs] = p;
190 setup->noutputs++;
194 if (LADSPA_IS_PORT_CONTROL(d)) {
195 if (LADSPA_IS_PORT_INPUT(d)) {
196 setup->inputcontrolsmap[setup->ninputcontrols] = p;
197 setup->ninputcontrols++;
198 /* set control to zero. set values after reading the rest
199 * of the suboptions and check LADSPA_?_HINT's later.
201 setup->inputcontrols[p] = 0.0f;
202 } else if (LADSPA_IS_PORT_OUTPUT(d)) {
203 /* read and handle these too, otherwise filters that have them
204 * will sig11
206 setup->outputcontrolsmap[setup->noutputcontrols]=p;
207 setup->noutputcontrols++;
208 setup->outputcontrols[p] = 0.0f;
214 if (setup->ninputs == 0) {
215 af_msg(AF_MSG_WARN, "%s: %s\n", setup->myname,
216 MSGTR_AF_LADSPA_WarnNoInputs);
217 } else if (setup->ninputs == 1) {
218 af_msg(AF_MSG_VERBOSE, "%s: this is a mono effect\n", setup->myname);
219 } else if (setup->ninputs == 2) {
220 af_msg(AF_MSG_VERBOSE, "%s: this is a stereo effect\n", setup->myname);
221 } else {
222 af_msg(AF_MSG_VERBOSE, "%s: this is a %i-channel effect, "
223 "support is experimental\n", setup->myname, setup->ninputs);
226 if (setup->noutputs == 0) {
227 af_msg(AF_MSG_ERROR, "%s: %s\n", setup->myname,
228 MSGTR_AF_LADSPA_ErrNoOutputs);
229 return AF_ERROR;
232 if (setup->noutputs != setup->ninputs ) {
233 af_msg(AF_MSG_ERROR, "%s: %s\n", setup->myname,
234 MSGTR_AF_LADSPA_ErrInOutDiff);
235 return AF_ERROR;
238 af_msg(AF_MSG_VERBOSE, "%s: this plugin has %d input control(s)\n",
239 setup->myname, setup->ninputcontrols);
241 /* Print list of controls and its range of values it accepts */
243 for (i=0; i<setup->ninputcontrols; i++) {
244 p = setup->inputcontrolsmap[i];
245 hint = pdes->PortRangeHints[p];
246 af_msg(AF_MSG_VERBOSE, " --- %d %s [", i, pdes->PortNames[p]);
248 if (LADSPA_IS_HINT_BOUNDED_BELOW(hint.HintDescriptor)) {
249 af_msg(AF_MSG_VERBOSE, "%0.2f , ", hint.LowerBound);
250 } else {
251 af_msg(AF_MSG_VERBOSE, "... , ");
254 if (LADSPA_IS_HINT_BOUNDED_ABOVE(hint.HintDescriptor)) {
255 af_msg(AF_MSG_VERBOSE, "%0.2f]\n", hint.UpperBound);
256 } else {
257 af_msg(AF_MSG_VERBOSE, "...]\n");
262 return AF_OK;
265 /* ------------------------------------------------------------------------- */
267 /* This function might "slightly" look like dlopenLADSPA in the LADSPA SDK :-)
268 * But, I changed a few things, because imho it was broken. It did not support
269 * relative paths, only absolute paths that start with a /
270 * I think ../../some/dir/foobar.so is just as valid. And if one wants to call
271 * his library '...somename...so' he's crazy, but it should be allowed.
272 * So, search the path first, try plain *filename later.
273 * Also, try adding .so first! I like the recursion the SDK did, but it's
274 * better the other way around. -af ladspa=cmt:amp_stereo:0.5 is easier to type
275 * than -af ladspa=cmt.so:amp_stereo:0.5 :-))
278 /** \brief dlopen() wrapper
280 * This is a wrapper around dlopen(). It tries various variations of the
281 * filename (with or without the addition of the .so extension) in various
282 * directories specified by the LADSPA_PATH environment variable. If all fails
283 * it tries the filename directly as an absolute path to the library.
285 * \param filename filename of the library to load.
286 * \param flag see dlopen(3) for a description of the flags.
288 * \return returns a pointer to the loaded library on success, or
289 * NULL if it fails to load.
292 static void* mydlopen(const char *filename, int flag) {
293 char *buf;
294 const char *end, *start, *ladspapath;
295 int endsinso, needslash;
296 size_t filenamelen;
297 void *result = NULL;
299 # ifdef WIN32 /* for windows there's only absolute path support.
300 * if you have a windows machine, feel free to fix
301 * this. (path separator, shared objects extension,
302 * et cetera).
304 af_msg(AF_MSG_VERBOSE, "\ton windows, only absolute pathnames "
305 "are supported\n");
306 af_msg(AF_MSG_VERBOSE, "\ttrying %s\n", filename);
307 return dlopen(filename, flag);
308 # endif
310 filenamelen = strlen(filename);
312 endsinso = 0;
313 if (filenamelen > 3)
314 endsinso = (strcmp(filename+filenamelen-3, ".so") == 0);
315 if (!endsinso) {
316 buf=malloc(filenamelen+4);
317 strcpy(buf, filename);
318 strcat(buf, ".so");
319 result=mydlopen(buf, flag);
320 free(buf);
323 if (result)
324 return result;
326 ladspapath=getenv("LADSPA_PATH");
328 if (ladspapath) {
330 start=ladspapath;
331 while (*start != '\0') {
332 end=start;
333 while ( (*end != ':') && (*end != '\0') )
334 end++;
336 buf=malloc(filenamelen + 2 + (end-start) );
337 if (end > start)
338 strncpy(buf, start, end-start);
339 needslash=0;
340 if (end > start)
341 if (*(end-1) != '/') {
342 needslash = 1;
343 buf[end-start] = '/';
345 strcpy(buf+needslash+(end-start), filename);
347 af_msg(AF_MSG_VERBOSE, "\ttrying %s\n", buf);
348 result=dlopen(buf, flag);
350 free(buf);
351 if (result)
352 return result;
354 start = end;
355 if (*start == ':')
356 start++;
357 } /* end while there's still more in the path */
358 } /* end if there's a ladspapath */
360 /* last resort, just open it again, so the dlerror() message is correct */
361 af_msg(AF_MSG_VERBOSE, "\ttrying %s\n", filename);
362 return dlopen(filename,flag);
365 /* ------------------------------------------------------------------------- */
367 /** \brief Load a LADSPA Plugin
369 * This function loads the LADSPA plugin specified by the file and label
370 * that are present in the setup variable. First, it loads the library.
371 * If it fails, it returns AF_ERROR. If not, it continues to look for the
372 * specified label. If it finds it, it sets the plugin_descriptor inside
373 * setup and returns AF_OK. If it doesn't, it returns AF_ERROR. Special case
374 * is a label called 'help'. In that case, it prints a list of all available
375 * labels (filters) in the library specified by file.
377 * \param setup Current setup of the filter. Contains filename and label.
379 * \return Either AF_ERROR or AF_OK, depending on the success of the operation.
382 static int af_ladspa_load_plugin(af_ladspa_t *setup) {
383 const LADSPA_Descriptor *ladspa_descriptor;
384 LADSPA_Descriptor_Function descriptor_function;
385 int i;
387 /* load library */
388 af_msg(AF_MSG_VERBOSE, "%s: loading ladspa plugin library %s\n",
389 setup->myname, setup->file);
391 setup->libhandle = mydlopen(setup->file, RTLD_NOW);
393 if (!setup->libhandle) {
394 af_msg(AF_MSG_ERROR, "%s: %s %s\n\t%s\n", setup->myname,
395 MSGTR_AF_LADSPA_ErrFailedToLoad, setup->file, dlerror() );
396 return AF_ERROR;
399 af_msg(AF_MSG_VERBOSE, "%s: library found.\n", setup->myname);
401 /* find descriptor function */
402 dlerror();
403 descriptor_function = (LADSPA_Descriptor_Function) dlsym (setup->libhandle,
404 "ladspa_descriptor");
406 if (!descriptor_function) {
407 af_msg(AF_MSG_ERROR, "%s: %s\n\t%s\n", setup->myname,
408 MSGTR_AF_LADSPA_ErrNoDescriptor, dlerror());
409 return AF_ERROR;
412 /* if label == help, list all labels in library and exit */
414 if (strcmp(setup->label, "help") == 0) {
415 af_msg(AF_MSG_INFO, "%s: %s %s:\n", setup->myname,
416 MSGTR_AF_LADSPA_AvailableLabels, setup->file);
417 for (i=0; ; i++) {
418 ladspa_descriptor = descriptor_function(i);
419 if (ladspa_descriptor == NULL) {
420 return AF_ERROR;
422 af_msg(AF_MSG_INFO, " %-16s - %s (%lu)\n",
423 ladspa_descriptor->Label,
424 ladspa_descriptor->Name,
425 ladspa_descriptor->UniqueID);
429 af_msg(AF_MSG_VERBOSE, "%s: looking for label\n", setup->myname);
431 /* find label in library */
432 for (i=0; ; i++) {
433 ladspa_descriptor = descriptor_function(i);
434 if (ladspa_descriptor == NULL) {
435 af_msg(AF_MSG_ERROR, "%s: %s\n", setup->myname,
436 MSGTR_AF_LADSPA_ErrLabelNotFound);
437 return AF_ERROR;
439 if (strcmp(ladspa_descriptor->Label, setup->label) == 0) {
440 setup->plugin_descriptor = ladspa_descriptor;
441 af_msg(AF_MSG_VERBOSE, "%s: %s found\n", setup->myname,
442 setup->label);
443 return AF_OK;
447 return AF_OK;
450 /* ------------------------------------------------------------------------- */
452 /** \brief Print a malloc() failed error message.
454 * Generic function which can be called if a call to malloc(), calloc(),
455 * strdup(), et cetera, failed. It prints a message to the console and
456 * returns AF_ERROR.
458 * \return AF_ERROR
461 static int af_ladspa_malloc_failed(char *myname) {
462 af_msg(AF_MSG_ERROR, "%s: %s", myname, MSGTR_MemAllocFailed);
463 return AF_ERROR;
466 /* ------------------------------------------------------------------------- */
468 /** \brief Controls the filter.
470 * Control the behaviour of the filter.
472 * Commands:
473 * CONTROL_REINIT Sets the af structure with proper values for number
474 * of channels, rate, format, et cetera.
475 * CONTROL_COMMAND_LINE Parses the suboptions given to this filter
476 * through arg. It first parses the filename and
477 * the label. After that, it loads the filter
478 * and finds out its proprties. Then in continues
479 * parsing the controls given on the commandline,
480 * if any are needed.
482 * \param af Audio filter instance
483 * \param cmd The command to execute
484 * \param arg Arguments to the command
486 * \return Either AF_ERROR or AF_OK, depending on the succes of the
487 * operation.
490 static int control(struct af_instance_s *af, int cmd, void *arg) {
491 af_ladspa_t *setup = (af_ladspa_t*) af->setup;
492 int i, r;
493 float val;
495 switch(cmd) {
496 case AF_CONTROL_REINIT:
497 af_msg(AF_MSG_VERBOSE, "%s: (re)init\n", setup->myname);
499 if (!arg) return AF_ERROR;
501 /* accept FLOAT, let af_format do conversion */
503 af->data->rate = ((af_data_t*)arg)->rate;
504 af->data->nch = ((af_data_t*)arg)->nch;
505 af->data->format = AF_FORMAT_FLOAT_NE;
506 af->data->bps = 4;
508 /* arg->len is not set here yet, so init of buffers and connecting the
509 * filter, has to be done in play() :-/
512 return af_test_output(af, (af_data_t*)arg);
513 case AF_CONTROL_COMMAND_LINE: {
514 char *buf;
516 af_msg(AF_MSG_VERBOSE, "%s: parse suboptions\n", setup->myname);
518 /* suboption parser here!
519 * format is (ladspa=)file:label:controls....
522 if (!arg) {
523 af_msg(AF_MSG_ERROR, "%s: %s\n", setup->myname,
524 MSGTR_AF_LADSPA_ErrNoSuboptions);
525 return AF_ERROR;
528 buf = malloc(strlen(arg)+1);
529 if (!buf) return af_ladspa_malloc_failed(setup->myname);
531 /* file... */
532 buf[0] = '\0';
533 sscanf(arg, "%[^:]", buf);
534 if (buf[0] == '\0') {
535 af_msg(AF_MSG_ERROR, "%s: %s\n", setup->myname,
536 MSGTR_AF_LADSPA_ErrNoLibFile);
537 free(buf);
538 return AF_ERROR;
540 arg += strlen(buf);
541 setup->file = strdup(buf);
542 if (!setup->file) return af_ladspa_malloc_failed(setup->myname);
543 af_msg(AF_MSG_VERBOSE, "%s: file --> %s\n", setup->myname,
544 setup->file);
545 if (*(char*)arg != '\0') arg++; /* read ':' */
547 /* label... */
548 buf[0] = '\0';
549 sscanf(arg, "%[^:]", buf);
550 if (buf[0] == '\0') {
551 af_msg(AF_MSG_ERROR, "%s: %s\n", setup->myname,
552 MSGTR_AF_LADSPA_ErrNoLabel);
553 free(buf);
554 return AF_ERROR;
556 arg += strlen(buf);
557 setup->label = strdup(buf);
558 if (!setup->label) return af_ladspa_malloc_failed(setup->myname);
559 af_msg(AF_MSG_VERBOSE, "%s: label --> %s\n", setup->myname,
560 setup->label);
561 /* if (*(char*)arg != '0') arg++; */ /* read ':' */
563 free(buf); /* no longer needed */
565 /* set new setup->myname */
567 if(setup->myname) free(setup->myname);
568 setup->myname = calloc(strlen(af_info_ladspa.name)+strlen(setup->file)+
569 strlen(setup->label)+6, 1);
570 snprintf(setup->myname, strlen(af_info_ladspa.name)+
571 strlen(setup->file)+strlen(setup->label)+6, "%s: (%s:%s)",
572 af_info_ladspa.name, setup->file, setup->label);
574 /* load plugin :) */
576 if ( af_ladspa_load_plugin(setup) != AF_OK )
577 return AF_ERROR;
579 /* see what inputs, outputs and controls this plugin has */
580 if ( af_ladspa_parse_plugin(setup) != AF_OK )
581 return AF_ERROR;
583 /* ninputcontrols is set by now, read control values from arg */
585 for(i=0; i<setup->ninputcontrols; i++) {
586 if (!arg || (*(char*)arg != ':') ) {
587 af_msg(AF_MSG_ERROR, "%s: %s\n", setup->myname,
588 MSGTR_AF_LADSPA_ErrNotEnoughControls);
589 return AF_ERROR;
591 arg++;
592 r = sscanf(arg, "%f", &val);
593 if (r!=1) {
594 af_msg(AF_MSG_ERROR, "%s: %s\n", setup->myname,
595 MSGTR_AF_LADSPA_ErrNotEnoughControls);
596 return AF_ERROR;
598 setup->inputcontrols[setup->inputcontrolsmap[i]] = val;
599 arg = strchr(arg, ':');
602 af_msg(AF_MSG_VERBOSE, "%s: input controls: ", setup->myname);
603 for(i=0; i<setup->ninputcontrols; i++) {
604 af_msg(AF_MSG_VERBOSE, "%0.4f ",
605 setup->inputcontrols[setup->inputcontrolsmap[i]]);
607 af_msg(AF_MSG_VERBOSE, "\n");
609 /* check boundaries of inputcontrols */
611 af_msg(AF_MSG_VERBOSE, "%s: checking boundaries of input controls\n",
612 setup->myname);
613 for(i=0; i<setup->ninputcontrols; i++) {
614 int p = setup->inputcontrolsmap[i];
615 LADSPA_PortRangeHint hint =
616 setup->plugin_descriptor->PortRangeHints[p];
617 val = setup->inputcontrols[p];
619 if (LADSPA_IS_HINT_BOUNDED_BELOW(hint.HintDescriptor) &&
620 val < hint.LowerBound) {
621 af_msg(AF_MSG_ERROR, MSGTR_AF_LADSPA_ErrControlBelow,
622 setup->myname, i, hint.LowerBound);
623 return AF_ERROR;
625 if (LADSPA_IS_HINT_BOUNDED_ABOVE(hint.HintDescriptor) &&
626 val > hint.UpperBound) {
627 af_msg(AF_MSG_ERROR, MSGTR_AF_LADSPA_ErrControlAbove,
628 setup->myname, i, hint.UpperBound);
629 return AF_ERROR;
632 af_msg(AF_MSG_VERBOSE, "%s: all controls have sane values\n",
633 setup->myname);
635 /* All is well! */
636 setup->status = AF_OK;
638 return AF_OK; }
641 return AF_UNKNOWN;
644 /* ------------------------------------------------------------------------- */
646 /** \brief Uninitialise the LADSPA Plugin Loader filter.
648 * This function deactivates the plugin(s), cleans up, frees all allocated
649 * memory and exits.
651 * \return No return value.
654 static void uninit(struct af_instance_s *af) {
655 int i;
657 if (af->data)
658 free(af->data);
659 if (af->setup) {
660 af_ladspa_t *setup = (af_ladspa_t*) af->setup;
661 const LADSPA_Descriptor *pdes = setup->plugin_descriptor;
663 if (setup->myname) {
664 af_msg(AF_MSG_VERBOSE, "%s: cleaning up\n", setup->myname);
665 free(setup->myname);
668 if (setup->chhandles) {
669 for(i=0; i<setup->nch; i+=setup->ninputs) {
670 if (pdes->deactivate) pdes->deactivate(setup->chhandles[i]);
671 if (pdes->cleanup) pdes->cleanup(setup->chhandles[i]);
673 free(setup->chhandles);
676 if (setup->file)
677 free(setup->file);
678 if (setup->label)
679 free(setup->label);
680 if (setup->inputcontrolsmap)
681 free(setup->inputcontrolsmap);
682 if (setup->inputcontrols)
683 free(setup->inputcontrols);
684 if (setup->outputcontrolsmap)
685 free(setup->outputcontrolsmap);
686 if (setup->outputcontrols)
687 free(setup->outputcontrols);
688 if (setup->inputs)
689 free(setup->inputs);
690 if (setup->outputs)
691 free(setup->outputs);
693 if (setup->inbufs) {
694 for(i=0; i<setup->nch; i++) {
695 if (setup->inbufs[i])
696 free(setup->inbufs[i]);
698 free(setup->inbufs);
701 if (setup->outbufs) {
702 for(i=0; i<setup->nch; i++) {
703 if (setup->outbufs[i])
704 free(setup->outbufs[i]);
706 free(setup->outbufs);
709 if (setup->libhandle)
710 dlclose(setup->libhandle);
712 free(setup);
713 setup = NULL;
717 /* ------------------------------------------------------------------------- */
719 /** \brief Process chunk of audio data through the selected LADSPA Plugin.
721 * \param af Pointer to audio filter instance
722 * \param data Pointer to chunk of audio data
724 * \return Either AF_ERROR or AF_OK
727 static af_data_t* play(struct af_instance_s *af, af_data_t *data) {
728 af_ladspa_t *setup = af->setup;
729 const LADSPA_Descriptor *pdes = setup->plugin_descriptor;
730 float *audio = (float*)data->audio;
731 int nsamples = data->len/4; /* /4 because it's 32-bit float */
732 int nch = data->nch;
733 int rate = data->rate;
734 int i, p;
736 if (setup->status !=AF_OK)
737 return data;
739 /* See if it's the first call. If so, setup inbufs/outbufs, instantiate
740 * plugin, connect ports and activate plugin
743 /* 2004-12-07: Also check if the buffersize has to be changed!
744 * data->len is not constant per se! re-init buffers.
747 if ( (setup->bufsize != nsamples/nch) || (setup->nch != nch) ) {
749 /* if setup->nch==0, it's the first call, if not, something has
750 * changed and all previous mallocs have to be freed
753 if (setup->nch != 0) {
754 af_msg(AF_MSG_DEBUG1, "%s: bufsize change; free old buffer\n",
755 setup->myname);
757 if(setup->inbufs) {
758 for(i=0; i<setup->nch; i++) {
759 if(setup->inbufs[i])
760 free(setup->inbufs[i]);
762 free(setup->inbufs);
764 if(setup->outbufs) {
765 for(i=0; i<setup->nch; i++) {
766 if(setup->outbufs[i])
767 free(setup->outbufs[i]);
769 free(setup->outbufs);
771 } /* everything is freed */
773 setup->bufsize = nsamples/nch;
774 setup->nch = nch;
776 setup->inbufs = calloc(nch, sizeof(float*));
777 setup->outbufs = calloc(nch, sizeof(float*));
779 af_msg(AF_MSG_DEBUG1, "%s: bufsize = %d\n",
780 setup->myname, setup->bufsize);
782 for(i=0; i<nch; i++) {
783 setup->inbufs[i] = calloc(setup->bufsize, sizeof(float));
784 setup->outbufs[i] = calloc(setup->bufsize, sizeof(float));
787 /* only on the first call, there are no handles. */
789 if (!setup->chhandles) {
790 setup->chhandles = calloc(nch, sizeof(LADSPA_Handle));
792 /* create handles
793 * for stereo effects, create one handle for two channels
796 for(i=0; i<nch; i++) {
798 if (i % setup->ninputs) { /* stereo effect */
799 /* copy the handle from previous channel */
800 setup->chhandles[i] = setup->chhandles[i-1];
801 continue;
804 setup->chhandles[i] = pdes->instantiate(pdes, rate);
808 /* connect input/output ports for each channel/filter instance
810 * always (re)connect ports
813 for(i=0; i<nch; i++) {
814 pdes->connect_port(setup->chhandles[i],
815 setup->inputs[i % setup->ninputs],
816 setup->inbufs[i]);
817 pdes->connect_port(setup->chhandles[i],
818 setup->outputs[i % setup->ninputs],
819 setup->outbufs[i]);
821 /* connect (input) controls */
823 for (p=0; p<setup->nports; p++) {
824 LADSPA_PortDescriptor d = pdes->PortDescriptors[p];
825 if (LADSPA_IS_PORT_CONTROL(d)) {
826 if (LADSPA_IS_PORT_INPUT(d)) {
827 pdes->connect_port(setup->chhandles[i], p,
828 &(setup->inputcontrols[p]) );
829 } else {
830 pdes->connect_port(setup->chhandles[i], p,
831 &(setup->outputcontrols[p]) );
836 /* Activate filter (if it isn't already :) ) */
838 if ( (pdes->activate) && (setup->activated == 0) ) {
839 pdes->activate(setup->chhandles[i]);
840 setup->activated = 1;
843 } /* All channels/filters done! except for... */
845 /* Stereo effect with one channel left. Use same buffer for left
846 * and right. connect it to the second port.
849 for (p = i; p % setup->ninputs; p++) {
850 pdes->connect_port(setup->chhandles[i-1],
851 setup->inputs[p % setup->ninputs],
852 setup->inbufs[i-1]);
853 pdes->connect_port(setup->chhandles[i-1],
854 setup->outputs[p % setup->ninputs],
855 setup->outbufs[i-1]);
856 } /* done! */
858 } /* setup for first call/change of bufsize is done.
859 * normal playing routine follows...
862 /* Right now, I use a separate input and output buffer.
863 * I could change this to in-place processing (inbuf==outbuf), but some
864 * ladspa filters are broken and are not able to handle that. This seems
865 * fast enough, so unless somebody complains, it stays this way :)
868 /* Fill inbufs */
870 for (p=0; p<setup->bufsize; p++) {
871 for (i=0; i<nch; i++) {
872 setup->inbufs[i][p] = audio[p*nch + i];
876 /* Run filter(s) */
878 for (i=0; i<nch; i+=setup->ninputs) {
879 pdes->run(setup->chhandles[i], setup->bufsize);
882 /* Extract outbufs */
884 for (p=0; p<setup->bufsize; p++) {
885 for (i=0; i<nch; i++) {
886 audio[p*nch + i] = setup->outbufs[i][p];
890 /* done */
892 return data;
895 /* ------------------------------------------------------------------------- */
897 /** \brief Open LADSPA Plugin Loader Filter
899 * \param af Audio Filter instance
901 * \return Either AF_ERROR or AF_OK
904 static int af_open(af_instance_t *af) {
906 af->control=control;
907 af->uninit=uninit;
908 af->play=play;
909 af->mul=1;
911 af->data = calloc(1, sizeof(af_data_t));
912 if (af->data == NULL)
913 return af_ladspa_malloc_failed((char*)af_info_ladspa.name);
915 af->setup = calloc(1, sizeof(af_ladspa_t));
916 if (af->setup == NULL) {
917 free(af->data);
918 af->data=NULL;
919 return af_ladspa_malloc_failed((char*)af_info_ladspa.name);
922 ((af_ladspa_t*)af->setup)->status = AF_ERROR; /* will be set to AF_OK if
923 * all went OK and play()
924 * should proceed.
927 ((af_ladspa_t*)af->setup)->myname = strdup(af_info_ladspa.name);
928 if (!((af_ladspa_t*)af->setup)->myname)
929 return af_ladspa_malloc_failed((char*)af_info_ladspa.name);
931 return AF_OK;
934 /* ------------------------------------------------------------------------- */