synced with r26729
[mplayer/greg.git] / libaf / af_ladspa.c
blob3acba312e26abdd43276c9ed94355d49a87a66c1
1 /* ------------------------------------------------------------------------- */
3 /*
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
25 /* ------------------------------------------------------------------------- */
27 /* Global Includes */
29 #include <stdio.h>
30 #include <stdlib.h>
31 #include <string.h>
33 #include <inttypes.h>
34 #include <math.h>
35 #include <limits.h>
37 #include <dlfcn.h>
38 #include <ladspa.h>
40 /* ------------------------------------------------------------------------- */
42 /* Local Includes */
44 #include "af.h"
45 #include "help_mp.h"
47 /* ------------------------------------------------------------------------- */
49 /* Filter specific data */
51 typedef struct af_ladspa_s
53 int status; /**< Status of the filter.
54 * Either AF_OK or AF_ERROR
55 * Because MPlayer re-inits audio filters that
56 * _clearly_ returned AF_ERROR anyway, I use this
57 * in play() to skip the processing and return
58 * the data unchanged.
61 int activated; /**< 0 or 1. Activate LADSPA filters only once, even
62 * if the buffers get resized, to avoid a stuttering
63 * filter.
66 char *file;
67 char *label;
69 char *myname; /**< It's easy to have a concatenation of file and label */
71 void *libhandle;
72 const LADSPA_Descriptor *plugin_descriptor;
74 int nports;
76 int ninputs;
77 int *inputs;
79 int noutputs;
80 int *outputs;
82 int ninputcontrols;
83 int *inputcontrolsmap; /**< Map input port number [0-] to actual port */
84 float *inputcontrols;
86 int noutputcontrols;
87 int *outputcontrolsmap;
88 float *outputcontrols;
90 int nch; /**< number of channels */
91 int bufsize;
92 float **inbufs;
93 float **outbufs;
94 LADSPA_Handle *chhandles;
96 } af_ladspa_t;
98 /* ------------------------------------------------------------------------- */
100 static int af_open(af_instance_t *af);
101 static int af_ladspa_malloc_failed(char*);
103 /* ------------------------------------------------------------------------- */
105 /* Description */
107 af_info_t af_info_ladspa = {
108 "LADSPA plugin loader",
109 "ladspa",
110 "Ivo van Poorten",
112 AF_FLAGS_REENTRANT,
113 af_open
116 /* ------------------------------------------------------------------------- */
118 /* By lack of a better word (in my vocabulary) this is called 'parse'.
119 * Feel free to suggest an alternative.
122 /** \brief Check for inputs, outputs and controls of a given filter.
124 * This function counts and checks all input, output and control ports
125 * of the filter that was loaded. If it turns out to be a valid
126 * filter for MPlayer use, it prints out a list of all controls and
127 * the corresponding range of its value at message level MSGL_V.
129 * \param setup Current setup of the filter. Must have its
130 * plugin_descriptor set!
132 * \return Returns AF_OK if it has a valid input/output/controls
133 * configuration. Else, it returns AF_ERROR.
136 static int af_ladspa_parse_plugin(af_ladspa_t *setup) {
137 int p, i;
138 const LADSPA_Descriptor *pdes = setup->plugin_descriptor;
139 LADSPA_PortDescriptor d;
140 LADSPA_PortRangeHint hint;
142 if (!setup->libhandle)
143 return AF_ERROR; /* only call parse after a succesful load */
144 if (!setup->plugin_descriptor)
145 return AF_ERROR; /* same as above */
147 /* let's do it */
149 setup->nports = pdes->PortCount;
151 /* allocate memory for all inputs/outputs/controls */
153 setup->inputs = calloc(setup->nports, sizeof(int));
154 if (!setup->inputs) return af_ladspa_malloc_failed(setup->myname);
156 setup->outputs = calloc(setup->nports, sizeof(int));
157 if (!setup->outputs) return af_ladspa_malloc_failed(setup->myname);
159 setup->inputcontrolsmap = calloc(setup->nports, sizeof(int));
160 if (!setup->inputcontrolsmap) return af_ladspa_malloc_failed(setup->myname);
162 setup->inputcontrols = calloc(setup->nports, sizeof(float));
163 if (!setup->inputcontrols) return af_ladspa_malloc_failed(setup->myname);
165 setup->outputcontrolsmap = calloc(setup->nports, sizeof(int));
166 if (!setup->outputcontrolsmap) return af_ladspa_malloc_failed(setup->myname);
168 setup->outputcontrols = calloc(setup->nports, sizeof(float));
169 if (!setup->outputcontrols) return af_ladspa_malloc_failed(setup->myname);
171 /* set counts to zero */
173 setup->ninputs = 0;
174 setup->noutputs = 0;
175 setup->ninputcontrols = 0;
176 setup->noutputcontrols = 0;
178 /* check all ports, see what type it is and set variables according to
179 * what we have found
182 for (p=0; p<setup->nports; p++) {
183 d = pdes->PortDescriptors[p];
185 if (LADSPA_IS_PORT_AUDIO(d)) {
186 if (LADSPA_IS_PORT_INPUT(d)) {
187 setup->inputs[setup->ninputs] = p;
188 setup->ninputs++;
189 } else if (LADSPA_IS_PORT_OUTPUT(d)) {
190 setup->outputs[setup->noutputs] = p;
191 setup->noutputs++;
195 if (LADSPA_IS_PORT_CONTROL(d)) {
196 if (LADSPA_IS_PORT_INPUT(d)) {
197 setup->inputcontrolsmap[setup->ninputcontrols] = p;
198 setup->ninputcontrols++;
199 /* set control to zero. set values after reading the rest
200 * of the suboptions and check LADSPA_?_HINT's later.
202 setup->inputcontrols[p] = 0.0f;
203 } else if (LADSPA_IS_PORT_OUTPUT(d)) {
204 /* read and handle these too, otherwise filters that have them
205 * will sig11
207 setup->outputcontrolsmap[setup->noutputcontrols]=p;
208 setup->noutputcontrols++;
209 setup->outputcontrols[p] = 0.0f;
215 if (setup->ninputs == 0) {
216 af_msg(AF_MSG_WARN, "%s: %s\n", setup->myname,
217 MSGTR_AF_LADSPA_WarnNoInputs);
218 } else if (setup->ninputs == 1) {
219 af_msg(AF_MSG_VERBOSE, "%s: this is a mono effect\n", setup->myname);
220 } else if (setup->ninputs == 2) {
221 af_msg(AF_MSG_VERBOSE, "%s: this is a stereo effect\n", setup->myname);
222 } else {
223 af_msg(AF_MSG_VERBOSE, "%s: this is a %i-channel effect, "
224 "support is experimental\n", setup->myname, setup->ninputs);
227 if (setup->noutputs == 0) {
228 af_msg(AF_MSG_ERROR, "%s: %s\n", setup->myname,
229 MSGTR_AF_LADSPA_ErrNoOutputs);
230 return AF_ERROR;
233 if (setup->noutputs != setup->ninputs ) {
234 af_msg(AF_MSG_ERROR, "%s: %s\n", setup->myname,
235 MSGTR_AF_LADSPA_ErrInOutDiff);
236 return AF_ERROR;
239 af_msg(AF_MSG_VERBOSE, "%s: this plugin has %d input control(s)\n",
240 setup->myname, setup->ninputcontrols);
242 /* Print list of controls and its range of values it accepts */
244 for (i=0; i<setup->ninputcontrols; i++) {
245 p = setup->inputcontrolsmap[i];
246 hint = pdes->PortRangeHints[p];
247 af_msg(AF_MSG_VERBOSE, " --- %d %s [", i, pdes->PortNames[p]);
249 if (LADSPA_IS_HINT_BOUNDED_BELOW(hint.HintDescriptor)) {
250 af_msg(AF_MSG_VERBOSE, "%0.2f , ", hint.LowerBound);
251 } else {
252 af_msg(AF_MSG_VERBOSE, "... , ");
255 if (LADSPA_IS_HINT_BOUNDED_ABOVE(hint.HintDescriptor)) {
256 af_msg(AF_MSG_VERBOSE, "%0.2f]\n", hint.UpperBound);
257 } else {
258 af_msg(AF_MSG_VERBOSE, "...]\n");
263 return AF_OK;
266 /* ------------------------------------------------------------------------- */
268 /* This function might "slightly" look like dlopenLADSPA in the LADSPA SDK :-)
269 * But, I changed a few things, because imho it was broken. It did not support
270 * relative paths, only absolute paths that start with a /
271 * I think ../../some/dir/foobar.so is just as valid. And if one wants to call
272 * his library '...somename...so' he's crazy, but it should be allowed.
273 * So, search the path first, try plain *filename later.
274 * Also, try adding .so first! I like the recursion the SDK did, but it's
275 * better the other way around. -af ladspa=cmt:amp_stereo:0.5 is easier to type
276 * than -af ladspa=cmt.so:amp_stereo:0.5 :-))
279 /** \brief dlopen() wrapper
281 * This is a wrapper around dlopen(). It tries various variations of the
282 * filename (with or without the addition of the .so extension) in various
283 * directories specified by the LADSPA_PATH environment variable. If all fails
284 * it tries the filename directly as an absolute path to the library.
286 * \param filename filename of the library to load.
287 * \param flag see dlopen(3) for a description of the flags.
289 * \return returns a pointer to the loaded library on success, or
290 * NULL if it fails to load.
293 static void* mydlopen(const char *filename, int flag) {
294 char *buf;
295 const char *end, *start, *ladspapath;
296 int endsinso, needslash;
297 size_t filenamelen;
298 void *result = NULL;
300 # ifdef WIN32 /* for windows there's only absolute path support.
301 * if you have a windows machine, feel free to fix
302 * this. (path separator, shared objects extension,
303 * et cetera).
305 af_msg(AF_MSG_VERBOSE, "\ton windows, only absolute pathnames "
306 "are supported\n");
307 af_msg(AF_MSG_VERBOSE, "\ttrying %s\n", filename);
308 return dlopen(filename, flag);
309 # endif
311 filenamelen = strlen(filename);
313 endsinso = 0;
314 if (filenamelen > 3)
315 endsinso = (strcmp(filename+filenamelen-3, ".so") == 0);
316 if (!endsinso) {
317 buf=malloc(filenamelen+4);
318 strcpy(buf, filename);
319 strcat(buf, ".so");
320 result=mydlopen(buf, flag);
321 free(buf);
324 if (result)
325 return result;
327 ladspapath=getenv("LADSPA_PATH");
329 if (ladspapath) {
331 start=ladspapath;
332 while (*start != '\0') {
333 end=start;
334 while ( (*end != ':') && (*end != '\0') )
335 end++;
337 buf=malloc(filenamelen + 2 + (end-start) );
338 if (end > start)
339 strncpy(buf, start, end-start);
340 needslash=0;
341 if (end > start)
342 if (*(end-1) != '/') {
343 needslash = 1;
344 buf[end-start] = '/';
346 strcpy(buf+needslash+(end-start), filename);
348 af_msg(AF_MSG_VERBOSE, "\ttrying %s\n", buf);
349 result=dlopen(buf, flag);
351 free(buf);
352 if (result)
353 return result;
355 start = end;
356 if (*start == ':')
357 start++;
358 } /* end while there's still more in the path */
359 } /* end if there's a ladspapath */
361 /* last resort, just open it again, so the dlerror() message is correct */
362 af_msg(AF_MSG_VERBOSE, "\ttrying %s\n", filename);
363 return dlopen(filename,flag);
366 /* ------------------------------------------------------------------------- */
368 /** \brief Load a LADSPA Plugin
370 * This function loads the LADSPA plugin specified by the file and label
371 * that are present in the setup variable. First, it loads the library.
372 * If it fails, it returns AF_ERROR. If not, it continues to look for the
373 * specified label. If it finds it, it sets the plugin_descriptor inside
374 * setup and returns AF_OK. If it doesn't, it returns AF_ERROR. Special case
375 * is a label called 'help'. In that case, it prints a list of all available
376 * labels (filters) in the library specified by file.
378 * \param setup Current setup of the filter. Contains filename and label.
380 * \return Either AF_ERROR or AF_OK, depending on the success of the operation.
383 static int af_ladspa_load_plugin(af_ladspa_t *setup) {
384 const LADSPA_Descriptor *ladspa_descriptor;
385 LADSPA_Descriptor_Function descriptor_function;
386 int i;
388 /* load library */
389 af_msg(AF_MSG_VERBOSE, "%s: loading ladspa plugin library %s\n",
390 setup->myname, setup->file);
392 setup->libhandle = mydlopen(setup->file, RTLD_NOW);
394 if (!setup->libhandle) {
395 af_msg(AF_MSG_ERROR, "%s: %s %s\n\t%s\n", setup->myname,
396 MSGTR_AF_LADSPA_ErrFailedToLoad, setup->file, dlerror() );
397 return AF_ERROR;
400 af_msg(AF_MSG_VERBOSE, "%s: library found.\n", setup->myname);
402 /* find descriptor function */
403 dlerror();
404 descriptor_function = (LADSPA_Descriptor_Function) dlsym (setup->libhandle,
405 "ladspa_descriptor");
407 if (!descriptor_function) {
408 af_msg(AF_MSG_ERROR, "%s: %s\n\t%s\n", setup->myname,
409 MSGTR_AF_LADSPA_ErrNoDescriptor, dlerror());
410 return AF_ERROR;
413 /* if label == help, list all labels in library and exit */
415 if (strcmp(setup->label, "help") == 0) {
416 af_msg(AF_MSG_INFO, "%s: %s %s:\n", setup->myname,
417 MSGTR_AF_LADSPA_AvailableLabels, setup->file);
418 for (i=0; ; i++) {
419 ladspa_descriptor = descriptor_function(i);
420 if (ladspa_descriptor == NULL) {
421 return AF_ERROR;
423 af_msg(AF_MSG_INFO, " %-16s - %s (%lu)\n",
424 ladspa_descriptor->Label,
425 ladspa_descriptor->Name,
426 ladspa_descriptor->UniqueID);
430 af_msg(AF_MSG_VERBOSE, "%s: looking for label\n", setup->myname);
432 /* find label in library */
433 for (i=0; ; i++) {
434 ladspa_descriptor = descriptor_function(i);
435 if (ladspa_descriptor == NULL) {
436 af_msg(AF_MSG_ERROR, "%s: %s\n", setup->myname,
437 MSGTR_AF_LADSPA_ErrLabelNotFound);
438 return AF_ERROR;
440 if (strcmp(ladspa_descriptor->Label, setup->label) == 0) {
441 setup->plugin_descriptor = ladspa_descriptor;
442 af_msg(AF_MSG_VERBOSE, "%s: %s found\n", setup->myname,
443 setup->label);
444 return AF_OK;
448 return AF_OK;
451 /* ------------------------------------------------------------------------- */
453 /** \brief Print a malloc() failed error message.
455 * Generic function which can be called if a call to malloc(), calloc(),
456 * strdup(), et cetera, failed. It prints a message to the console and
457 * returns AF_ERROR.
459 * \return AF_ERROR
462 static int af_ladspa_malloc_failed(char *myname) {
463 af_msg(AF_MSG_ERROR, "%s: %s", myname, MSGTR_MemAllocFailed);
464 return AF_ERROR;
467 /* ------------------------------------------------------------------------- */
469 /** \brief Controls the filter.
471 * Control the behaviour of the filter.
473 * Commands:
474 * CONTROL_REINIT Sets the af structure with proper values for number
475 * of channels, rate, format, et cetera.
476 * CONTROL_COMMAND_LINE Parses the suboptions given to this filter
477 * through arg. It first parses the filename and
478 * the label. After that, it loads the filter
479 * and finds out its proprties. Then in continues
480 * parsing the controls given on the commandline,
481 * if any are needed.
483 * \param af Audio filter instance
484 * \param cmd The command to execute
485 * \param arg Arguments to the command
487 * \return Either AF_ERROR or AF_OK, depending on the succes of the
488 * operation.
491 static int control(struct af_instance_s *af, int cmd, void *arg) {
492 af_ladspa_t *setup = (af_ladspa_t*) af->setup;
493 int i, r;
494 float val;
496 switch(cmd) {
497 case AF_CONTROL_REINIT:
498 af_msg(AF_MSG_VERBOSE, "%s: (re)init\n", setup->myname);
500 if (!arg) return AF_ERROR;
502 /* accept FLOAT, let af_format do conversion */
504 af->data->rate = ((af_data_t*)arg)->rate;
505 af->data->nch = ((af_data_t*)arg)->nch;
506 af->data->format = AF_FORMAT_FLOAT_NE;
507 af->data->bps = 4;
509 /* arg->len is not set here yet, so init of buffers and connecting the
510 * filter, has to be done in play() :-/
513 return af_test_output(af, (af_data_t*)arg);
514 case AF_CONTROL_COMMAND_LINE: {
515 char *buf;
517 af_msg(AF_MSG_VERBOSE, "%s: parse suboptions\n", setup->myname);
519 /* suboption parser here!
520 * format is (ladspa=)file:label:controls....
523 if (!arg) {
524 af_msg(AF_MSG_ERROR, "%s: %s\n", setup->myname,
525 MSGTR_AF_LADSPA_ErrNoSuboptions);
526 return AF_ERROR;
529 buf = malloc(strlen(arg)+1);
530 if (!buf) return af_ladspa_malloc_failed(setup->myname);
532 /* file... */
533 buf[0] = '\0';
534 sscanf(arg, "%[^:]", buf);
535 if (buf[0] == '\0') {
536 af_msg(AF_MSG_ERROR, "%s: %s\n", setup->myname,
537 MSGTR_AF_LADSPA_ErrNoLibFile);
538 free(buf);
539 return AF_ERROR;
541 arg += strlen(buf);
542 setup->file = strdup(buf);
543 if (!setup->file) return af_ladspa_malloc_failed(setup->myname);
544 af_msg(AF_MSG_VERBOSE, "%s: file --> %s\n", setup->myname,
545 setup->file);
546 if (*(char*)arg != '\0') arg++; /* read ':' */
548 /* label... */
549 buf[0] = '\0';
550 sscanf(arg, "%[^:]", buf);
551 if (buf[0] == '\0') {
552 af_msg(AF_MSG_ERROR, "%s: %s\n", setup->myname,
553 MSGTR_AF_LADSPA_ErrNoLabel);
554 free(buf);
555 return AF_ERROR;
557 arg += strlen(buf);
558 setup->label = strdup(buf);
559 if (!setup->label) return af_ladspa_malloc_failed(setup->myname);
560 af_msg(AF_MSG_VERBOSE, "%s: label --> %s\n", setup->myname,
561 setup->label);
562 /* if (*(char*)arg != '0') arg++; */ /* read ':' */
564 free(buf); /* no longer needed */
566 /* set new setup->myname */
568 if(setup->myname) free(setup->myname);
569 setup->myname = calloc(strlen(af_info_ladspa.name)+strlen(setup->file)+
570 strlen(setup->label)+6, 1);
571 snprintf(setup->myname, strlen(af_info_ladspa.name)+
572 strlen(setup->file)+strlen(setup->label)+6, "%s: (%s:%s)",
573 af_info_ladspa.name, setup->file, setup->label);
575 /* load plugin :) */
577 if ( af_ladspa_load_plugin(setup) != AF_OK )
578 return AF_ERROR;
580 /* see what inputs, outputs and controls this plugin has */
581 if ( af_ladspa_parse_plugin(setup) != AF_OK )
582 return AF_ERROR;
584 /* ninputcontrols is set by now, read control values from arg */
586 for(i=0; i<setup->ninputcontrols; i++) {
587 if (!arg || (*(char*)arg != ':') ) {
588 af_msg(AF_MSG_ERROR, "%s: %s\n", setup->myname,
589 MSGTR_AF_LADSPA_ErrNotEnoughControls);
590 return AF_ERROR;
592 arg++;
593 r = sscanf(arg, "%f", &val);
594 if (r!=1) {
595 af_msg(AF_MSG_ERROR, "%s: %s\n", setup->myname,
596 MSGTR_AF_LADSPA_ErrNotEnoughControls);
597 return AF_ERROR;
599 setup->inputcontrols[setup->inputcontrolsmap[i]] = val;
600 arg = strchr(arg, ':');
603 af_msg(AF_MSG_VERBOSE, "%s: input controls: ", setup->myname);
604 for(i=0; i<setup->ninputcontrols; i++) {
605 af_msg(AF_MSG_VERBOSE, "%0.4f ",
606 setup->inputcontrols[setup->inputcontrolsmap[i]]);
608 af_msg(AF_MSG_VERBOSE, "\n");
610 /* check boundaries of inputcontrols */
612 af_msg(AF_MSG_VERBOSE, "%s: checking boundaries of input controls\n",
613 setup->myname);
614 for(i=0; i<setup->ninputcontrols; i++) {
615 int p = setup->inputcontrolsmap[i];
616 LADSPA_PortRangeHint hint =
617 setup->plugin_descriptor->PortRangeHints[p];
618 val = setup->inputcontrols[p];
620 if (LADSPA_IS_HINT_BOUNDED_BELOW(hint.HintDescriptor) &&
621 val < hint.LowerBound) {
622 af_msg(AF_MSG_ERROR, MSGTR_AF_LADSPA_ErrControlBelow,
623 setup->myname, i, hint.LowerBound);
624 return AF_ERROR;
626 if (LADSPA_IS_HINT_BOUNDED_ABOVE(hint.HintDescriptor) &&
627 val > hint.UpperBound) {
628 af_msg(AF_MSG_ERROR, MSGTR_AF_LADSPA_ErrControlAbove,
629 setup->myname, i, hint.UpperBound);
630 return AF_ERROR;
633 af_msg(AF_MSG_VERBOSE, "%s: all controls have sane values\n",
634 setup->myname);
636 /* All is well! */
637 setup->status = AF_OK;
639 return AF_OK; }
642 return AF_UNKNOWN;
645 /* ------------------------------------------------------------------------- */
647 /** \brief Uninitialise the LADSPA Plugin Loader filter.
649 * This function deactivates the plugin(s), cleans up, frees all allocated
650 * memory and exits.
652 * \return No return value.
655 static void uninit(struct af_instance_s *af) {
656 int i;
658 if (af->data)
659 free(af->data);
660 if (af->setup) {
661 af_ladspa_t *setup = (af_ladspa_t*) af->setup;
662 const LADSPA_Descriptor *pdes = setup->plugin_descriptor;
664 if (setup->myname) {
665 af_msg(AF_MSG_VERBOSE, "%s: cleaning up\n", setup->myname);
666 free(setup->myname);
669 if (setup->chhandles) {
670 for(i=0; i<setup->nch; i+=setup->ninputs) {
671 if (pdes->deactivate) pdes->deactivate(setup->chhandles[i]);
672 if (pdes->cleanup) pdes->cleanup(setup->chhandles[i]);
674 free(setup->chhandles);
677 if (setup->file)
678 free(setup->file);
679 if (setup->label)
680 free(setup->label);
681 if (setup->inputcontrolsmap)
682 free(setup->inputcontrolsmap);
683 if (setup->inputcontrols)
684 free(setup->inputcontrols);
685 if (setup->outputcontrolsmap)
686 free(setup->outputcontrolsmap);
687 if (setup->outputcontrols)
688 free(setup->outputcontrols);
689 if (setup->inputs)
690 free(setup->inputs);
691 if (setup->outputs)
692 free(setup->outputs);
694 if (setup->inbufs) {
695 for(i=0; i<setup->nch; i++) {
696 if (setup->inbufs[i])
697 free(setup->inbufs[i]);
699 free(setup->inbufs);
702 if (setup->outbufs) {
703 for(i=0; i<setup->nch; i++) {
704 if (setup->outbufs[i])
705 free(setup->outbufs[i]);
707 free(setup->outbufs);
710 if (setup->libhandle)
711 dlclose(setup->libhandle);
713 free(setup);
714 setup = NULL;
718 /* ------------------------------------------------------------------------- */
720 /** \brief Process chunk of audio data through the selected LADSPA Plugin.
722 * \param af Pointer to audio filter instance
723 * \param data Pointer to chunk of audio data
725 * \return Either AF_ERROR or AF_OK
728 static af_data_t* play(struct af_instance_s *af, af_data_t *data) {
729 af_ladspa_t *setup = af->setup;
730 const LADSPA_Descriptor *pdes = setup->plugin_descriptor;
731 float *audio = (float*)data->audio;
732 int nsamples = data->len/4; /* /4 because it's 32-bit float */
733 int nch = data->nch;
734 int rate = data->rate;
735 int i, p;
737 if (setup->status !=AF_OK)
738 return data;
740 /* See if it's the first call. If so, setup inbufs/outbufs, instantiate
741 * plugin, connect ports and activate plugin
744 /* 2004-12-07: Also check if the buffersize has to be changed!
745 * data->len is not constant per se! re-init buffers.
748 if ( (setup->bufsize != nsamples/nch) || (setup->nch != nch) ) {
750 /* if setup->nch==0, it's the first call, if not, something has
751 * changed and all previous mallocs have to be freed
754 if (setup->nch != 0) {
755 af_msg(AF_MSG_DEBUG1, "%s: bufsize change; free old buffer\n",
756 setup->myname);
758 if(setup->inbufs) {
759 for(i=0; i<setup->nch; i++) {
760 if(setup->inbufs[i])
761 free(setup->inbufs[i]);
763 free(setup->inbufs);
765 if(setup->outbufs) {
766 for(i=0; i<setup->nch; i++) {
767 if(setup->outbufs[i])
768 free(setup->outbufs[i]);
770 free(setup->outbufs);
772 } /* everything is freed */
774 setup->bufsize = nsamples/nch;
775 setup->nch = nch;
777 setup->inbufs = calloc(nch, sizeof(float*));
778 setup->outbufs = calloc(nch, sizeof(float*));
780 af_msg(AF_MSG_DEBUG1, "%s: bufsize = %d\n",
781 setup->myname, setup->bufsize);
783 for(i=0; i<nch; i++) {
784 setup->inbufs[i] = calloc(setup->bufsize, sizeof(float));
785 setup->outbufs[i] = calloc(setup->bufsize, sizeof(float));
788 /* only on the first call, there are no handles. */
790 if (!setup->chhandles) {
791 setup->chhandles = calloc(nch, sizeof(LADSPA_Handle));
793 /* create handles
794 * for stereo effects, create one handle for two channels
797 for(i=0; i<nch; i++) {
799 if (i % setup->ninputs) { /* stereo effect */
800 /* copy the handle from previous channel */
801 setup->chhandles[i] = setup->chhandles[i-1];
802 continue;
805 setup->chhandles[i] = pdes->instantiate(pdes, rate);
809 /* connect input/output ports for each channel/filter instance
811 * always (re)connect ports
814 for(i=0; i<nch; i++) {
815 pdes->connect_port(setup->chhandles[i],
816 setup->inputs[i % setup->ninputs],
817 setup->inbufs[i]);
818 pdes->connect_port(setup->chhandles[i],
819 setup->outputs[i % setup->ninputs],
820 setup->outbufs[i]);
822 /* connect (input) controls */
824 for (p=0; p<setup->nports; p++) {
825 LADSPA_PortDescriptor d = pdes->PortDescriptors[p];
826 if (LADSPA_IS_PORT_CONTROL(d)) {
827 if (LADSPA_IS_PORT_INPUT(d)) {
828 pdes->connect_port(setup->chhandles[i], p,
829 &(setup->inputcontrols[p]) );
830 } else {
831 pdes->connect_port(setup->chhandles[i], p,
832 &(setup->outputcontrols[p]) );
837 /* Activate filter (if it isn't already :) ) */
839 if ( (pdes->activate) && (setup->activated == 0) ) {
840 pdes->activate(setup->chhandles[i]);
841 setup->activated = 1;
844 } /* All channels/filters done! except for... */
846 /* Stereo effect with one channel left. Use same buffer for left
847 * and right. connect it to the second port.
850 for (p = i; p % setup->ninputs; p++) {
851 pdes->connect_port(setup->chhandles[i-1],
852 setup->inputs[p % setup->ninputs],
853 setup->inbufs[i-1]);
854 pdes->connect_port(setup->chhandles[i-1],
855 setup->outputs[p % setup->ninputs],
856 setup->outbufs[i-1]);
857 } /* done! */
859 } /* setup for first call/change of bufsize is done.
860 * normal playing routine follows...
863 /* Right now, I use a separate input and output buffer.
864 * I could change this to in-place processing (inbuf==outbuf), but some
865 * ladspa filters are broken and are not able to handle that. This seems
866 * fast enough, so unless somebody complains, it stays this way :)
869 /* Fill inbufs */
871 for (p=0; p<setup->bufsize; p++) {
872 for (i=0; i<nch; i++) {
873 setup->inbufs[i][p] = audio[p*nch + i];
877 /* Run filter(s) */
879 for (i=0; i<nch; i+=setup->ninputs) {
880 pdes->run(setup->chhandles[i], setup->bufsize);
883 /* Extract outbufs */
885 for (p=0; p<setup->bufsize; p++) {
886 for (i=0; i<nch; i++) {
887 audio[p*nch + i] = setup->outbufs[i][p];
891 /* done */
893 return data;
896 /* ------------------------------------------------------------------------- */
898 /** \brief Open LADSPA Plugin Loader Filter
900 * \param af Audio Filter instance
902 * \return Either AF_ERROR or AF_OK
905 static int af_open(af_instance_t *af) {
907 af->control=control;
908 af->uninit=uninit;
909 af->play=play;
910 af->mul=1;
912 af->data = calloc(1, sizeof(af_data_t));
913 if (af->data == NULL)
914 return af_ladspa_malloc_failed((char*)af_info_ladspa.name);
916 af->setup = calloc(1, sizeof(af_ladspa_t));
917 if (af->setup == NULL) {
918 free(af->data);
919 af->data=NULL;
920 return af_ladspa_malloc_failed((char*)af_info_ladspa.name);
923 ((af_ladspa_t*)af->setup)->status = AF_ERROR; /* will be set to AF_OK if
924 * all went OK and play()
925 * should proceed.
928 ((af_ladspa_t*)af->setup)->myname = strdup(af_info_ladspa.name);
929 if (!((af_ladspa_t*)af->setup)->myname)
930 return af_ladspa_malloc_failed((char*)af_info_ladspa.name);
932 return AF_OK;
935 /* ------------------------------------------------------------------------- */