spudec: Simplify creation of color/alpha map
[mplayer/glamo.git] / libaf / af_ladspa.c
blobace8302b541beb5c8c1a24361a6250f0eba1de2f
1 /*
2 * 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"
45 /* ------------------------------------------------------------------------- */
47 /* Filter specific data */
49 typedef struct af_ladspa_s
51 int status; /**< Status of the filter.
52 * Either AF_OK or AF_ERROR
53 * Because MPlayer re-inits audio filters that
54 * _clearly_ returned AF_ERROR anyway, I use this
55 * in play() to skip the processing and return
56 * the data unchanged.
59 int activated; /**< 0 or 1. Activate LADSPA filters only once, even
60 * if the buffers get resized, to avoid a stuttering
61 * filter.
64 char *file;
65 char *label;
67 char *myname; /**< It's easy to have a concatenation of file and label */
69 void *libhandle;
70 const LADSPA_Descriptor *plugin_descriptor;
72 int nports;
74 int ninputs;
75 int *inputs;
77 int noutputs;
78 int *outputs;
80 int ninputcontrols;
81 int *inputcontrolsmap; /**< Map input port number [0-] to actual port */
82 float *inputcontrols;
84 int noutputcontrols;
85 int *outputcontrolsmap;
86 float *outputcontrols;
88 int nch; /**< number of channels */
89 int bufsize;
90 float **inbufs;
91 float **outbufs;
92 LADSPA_Handle *chhandles;
94 } af_ladspa_t;
96 /* ------------------------------------------------------------------------- */
98 static int af_open(af_instance_t *af);
99 static int af_ladspa_malloc_failed(char*);
101 /* ------------------------------------------------------------------------- */
103 /* Description */
105 af_info_t af_info_ladspa = {
106 "LADSPA plugin loader",
107 "ladspa",
108 "Ivo van Poorten",
110 AF_FLAGS_REENTRANT,
111 af_open
114 /* ------------------------------------------------------------------------- */
116 /* By lack of a better word (in my vocabulary) this is called 'parse'.
117 * Feel free to suggest an alternative.
120 /** \brief Check for inputs, outputs and controls of a given filter.
122 * This function counts and checks all input, output and control ports
123 * of the filter that was loaded. If it turns out to be a valid
124 * filter for MPlayer use, it prints out a list of all controls and
125 * the corresponding range of its value at message level MSGL_V.
127 * \param setup Current setup of the filter. Must have its
128 * plugin_descriptor set!
130 * \return Returns AF_OK if it has a valid input/output/controls
131 * configuration. Else, it returns AF_ERROR.
134 static int af_ladspa_parse_plugin(af_ladspa_t *setup) {
135 int p, i;
136 const LADSPA_Descriptor *pdes = setup->plugin_descriptor;
137 LADSPA_PortDescriptor d;
138 LADSPA_PortRangeHint hint;
140 if (!setup->libhandle)
141 return AF_ERROR; /* only call parse after a succesful load */
142 if (!setup->plugin_descriptor)
143 return AF_ERROR; /* same as above */
145 /* let's do it */
147 setup->nports = pdes->PortCount;
149 /* allocate memory for all inputs/outputs/controls */
151 setup->inputs = calloc(setup->nports, sizeof(int));
152 if (!setup->inputs) return af_ladspa_malloc_failed(setup->myname);
154 setup->outputs = calloc(setup->nports, sizeof(int));
155 if (!setup->outputs) return af_ladspa_malloc_failed(setup->myname);
157 setup->inputcontrolsmap = calloc(setup->nports, sizeof(int));
158 if (!setup->inputcontrolsmap) return af_ladspa_malloc_failed(setup->myname);
160 setup->inputcontrols = calloc(setup->nports, sizeof(float));
161 if (!setup->inputcontrols) return af_ladspa_malloc_failed(setup->myname);
163 setup->outputcontrolsmap = calloc(setup->nports, sizeof(int));
164 if (!setup->outputcontrolsmap) return af_ladspa_malloc_failed(setup->myname);
166 setup->outputcontrols = calloc(setup->nports, sizeof(float));
167 if (!setup->outputcontrols) return af_ladspa_malloc_failed(setup->myname);
169 /* set counts to zero */
171 setup->ninputs = 0;
172 setup->noutputs = 0;
173 setup->ninputcontrols = 0;
174 setup->noutputcontrols = 0;
176 /* check all ports, see what type it is and set variables according to
177 * what we have found
180 for (p=0; p<setup->nports; p++) {
181 d = pdes->PortDescriptors[p];
183 if (LADSPA_IS_PORT_AUDIO(d)) {
184 if (LADSPA_IS_PORT_INPUT(d)) {
185 setup->inputs[setup->ninputs] = p;
186 setup->ninputs++;
187 } else if (LADSPA_IS_PORT_OUTPUT(d)) {
188 setup->outputs[setup->noutputs] = p;
189 setup->noutputs++;
193 if (LADSPA_IS_PORT_CONTROL(d)) {
194 if (LADSPA_IS_PORT_INPUT(d)) {
195 setup->inputcontrolsmap[setup->ninputcontrols] = p;
196 setup->ninputcontrols++;
197 /* set control to zero. set values after reading the rest
198 * of the suboptions and check LADSPA_?_HINT's later.
200 setup->inputcontrols[p] = 0.0f;
201 } else if (LADSPA_IS_PORT_OUTPUT(d)) {
202 /* read and handle these too, otherwise filters that have them
203 * will sig11
205 setup->outputcontrolsmap[setup->noutputcontrols]=p;
206 setup->noutputcontrols++;
207 setup->outputcontrols[p] = 0.0f;
213 if (setup->ninputs == 0) {
214 mp_msg(MSGT_AFILTER, MSGL_WARN, "%s: %s\n", setup->myname,
215 _("WARNING! This LADSPA plugin has no audio inputs.\n The incoming audio signal will be lost."));
216 } else if (setup->ninputs == 1) {
217 mp_msg(MSGT_AFILTER, MSGL_V, "%s: this is a mono effect\n", setup->myname);
218 } else if (setup->ninputs == 2) {
219 mp_msg(MSGT_AFILTER, MSGL_V, "%s: this is a stereo effect\n", setup->myname);
220 } else {
221 mp_msg(MSGT_AFILTER, MSGL_V, "%s: this is a %i-channel effect, "
222 "support is experimental\n", setup->myname, setup->ninputs);
225 if (setup->noutputs == 0) {
226 mp_msg(MSGT_AFILTER, MSGL_ERR, "%s: %s\n", setup->myname,
227 _("This LADSPA plugin has no audio outputs."));
228 return AF_ERROR;
231 if (setup->noutputs != setup->ninputs ) {
232 mp_msg(MSGT_AFILTER, MSGL_ERR, "%s: %s\n", setup->myname,
233 _("The number of audio inputs and audio outputs of the LADSPA plugin differ."));
234 return AF_ERROR;
237 mp_msg(MSGT_AFILTER, MSGL_V, "%s: this plugin has %d input control(s)\n",
238 setup->myname, setup->ninputcontrols);
240 /* Print list of controls and its range of values it accepts */
242 for (i=0; i<setup->ninputcontrols; i++) {
243 p = setup->inputcontrolsmap[i];
244 hint = pdes->PortRangeHints[p];
245 mp_msg(MSGT_AFILTER, MSGL_V, " --- %d %s [", i, pdes->PortNames[p]);
247 if (LADSPA_IS_HINT_BOUNDED_BELOW(hint.HintDescriptor)) {
248 mp_msg(MSGT_AFILTER, MSGL_V, "%0.2f , ", hint.LowerBound);
249 } else {
250 mp_msg(MSGT_AFILTER, MSGL_V, "... , ");
253 if (LADSPA_IS_HINT_BOUNDED_ABOVE(hint.HintDescriptor)) {
254 mp_msg(MSGT_AFILTER, MSGL_V, "%0.2f]\n", hint.UpperBound);
255 } else {
256 mp_msg(MSGT_AFILTER, MSGL_V, "...]\n");
261 return AF_OK;
264 /* ------------------------------------------------------------------------- */
266 /* This function might "slightly" look like dlopenLADSPA in the LADSPA SDK :-)
267 * But, I changed a few things, because imho it was broken. It did not support
268 * relative paths, only absolute paths that start with a /
269 * I think ../../some/dir/foobar.so is just as valid. And if one wants to call
270 * his library '...somename...so' he's crazy, but it should be allowed.
271 * So, search the path first, try plain *filename later.
272 * Also, try adding .so first! I like the recursion the SDK did, but it's
273 * better the other way around. -af ladspa=cmt:amp_stereo:0.5 is easier to type
274 * than -af ladspa=cmt.so:amp_stereo:0.5 :-))
277 /** \brief dlopen() wrapper
279 * This is a wrapper around dlopen(). It tries various variations of the
280 * filename (with or without the addition of the .so extension) in various
281 * directories specified by the LADSPA_PATH environment variable. If all fails
282 * it tries the filename directly as an absolute path to the library.
284 * \param filename filename of the library to load.
285 * \param flag see dlopen(3) for a description of the flags.
287 * \return returns a pointer to the loaded library on success, or
288 * NULL if it fails to load.
291 static void* mydlopen(const char *filename, int flag) {
292 char *buf;
293 const char *end, *start, *ladspapath;
294 int endsinso, needslash;
295 size_t filenamelen;
296 void *result = NULL;
298 #if defined(__MINGW32__) || defined(__CYGWIN__)
299 /* For Windows there's only absolute path support.
300 * If you have a Windows machine, feel free to fix this.
301 * (path separator, shared objects extension, et cetera). */
302 mp_msg(MSGT_AFILTER, MSGL_V, "\ton windows, only absolute pathnames "
303 "are supported\n");
304 mp_msg(MSGT_AFILTER, MSGL_V, "\ttrying %s\n", filename);
305 return dlopen(filename, flag);
306 #endif
308 filenamelen = strlen(filename);
310 endsinso = 0;
311 if (filenamelen > 3)
312 endsinso = (strcmp(filename+filenamelen-3, ".so") == 0);
313 if (!endsinso) {
314 buf=malloc(filenamelen+4);
315 strcpy(buf, filename);
316 strcat(buf, ".so");
317 result=mydlopen(buf, flag);
318 free(buf);
321 if (result)
322 return result;
324 ladspapath=getenv("LADSPA_PATH");
326 if (ladspapath) {
328 start=ladspapath;
329 while (*start != '\0') {
330 end=start;
331 while ( (*end != ':') && (*end != '\0') )
332 end++;
334 buf=malloc(filenamelen + 2 + (end-start) );
335 if (end > start)
336 strncpy(buf, start, end-start);
337 needslash=0;
338 if (end > start)
339 if (*(end-1) != '/') {
340 needslash = 1;
341 buf[end-start] = '/';
343 strcpy(buf+needslash+(end-start), filename);
345 mp_msg(MSGT_AFILTER, MSGL_V, "\ttrying %s\n", buf);
346 result=dlopen(buf, flag);
348 free(buf);
349 if (result)
350 return result;
352 start = end;
353 if (*start == ':')
354 start++;
355 } /* end while there's still more in the path */
356 } /* end if there's a ladspapath */
358 /* last resort, just open it again, so the dlerror() message is correct */
359 mp_msg(MSGT_AFILTER, MSGL_V, "\ttrying %s\n", filename);
360 return dlopen(filename,flag);
363 /* ------------------------------------------------------------------------- */
365 /** \brief Load a LADSPA Plugin
367 * This function loads the LADSPA plugin specified by the file and label
368 * that are present in the setup variable. First, it loads the library.
369 * If it fails, it returns AF_ERROR. If not, it continues to look for the
370 * specified label. If it finds it, it sets the plugin_descriptor inside
371 * setup and returns AF_OK. If it doesn't, it returns AF_ERROR. Special case
372 * is a label called 'help'. In that case, it prints a list of all available
373 * labels (filters) in the library specified by file.
375 * \param setup Current setup of the filter. Contains filename and label.
377 * \return Either AF_ERROR or AF_OK, depending on the success of the operation.
380 static int af_ladspa_load_plugin(af_ladspa_t *setup) {
381 const LADSPA_Descriptor *ladspa_descriptor;
382 LADSPA_Descriptor_Function descriptor_function;
383 int i;
385 /* load library */
386 mp_msg(MSGT_AFILTER, MSGL_V, "%s: loading ladspa plugin library %s\n",
387 setup->myname, setup->file);
389 setup->libhandle = mydlopen(setup->file, RTLD_NOW);
391 if (!setup->libhandle) {
392 mp_msg(MSGT_AFILTER, MSGL_ERR, "%s: %s %s\n\t%s\n", setup->myname,
393 _("failed to load"), setup->file, dlerror() );
394 return AF_ERROR;
397 mp_msg(MSGT_AFILTER, MSGL_V, "%s: library found.\n", setup->myname);
399 /* find descriptor function */
400 dlerror();
401 descriptor_function = (LADSPA_Descriptor_Function) dlsym (setup->libhandle,
402 "ladspa_descriptor");
404 if (!descriptor_function) {
405 mp_msg(MSGT_AFILTER, MSGL_ERR, "%s: %s\n\t%s\n", setup->myname,
406 _("Couldn't find ladspa_descriptor() function in the specified library file."), dlerror());
407 return AF_ERROR;
410 /* if label == help, list all labels in library and exit */
412 if (strcmp(setup->label, "help") == 0) {
413 mp_msg(MSGT_AFILTER, MSGL_INFO, "%s: %s %s:\n", setup->myname,
414 _("available labels in"), setup->file);
415 for (i=0; ; i++) {
416 ladspa_descriptor = descriptor_function(i);
417 if (ladspa_descriptor == NULL) {
418 return AF_ERROR;
420 mp_msg(MSGT_AFILTER, MSGL_INFO, " %-16s - %s (%lu)\n",
421 ladspa_descriptor->Label,
422 ladspa_descriptor->Name,
423 ladspa_descriptor->UniqueID);
427 mp_msg(MSGT_AFILTER, MSGL_V, "%s: looking for label\n", setup->myname);
429 /* find label in library */
430 for (i=0; ; i++) {
431 ladspa_descriptor = descriptor_function(i);
432 if (ladspa_descriptor == NULL) {
433 mp_msg(MSGT_AFILTER, MSGL_ERR, "%s: %s\n", setup->myname,
434 _("Couldn't find label in plugin library."));
435 return AF_ERROR;
437 if (strcmp(ladspa_descriptor->Label, setup->label) == 0) {
438 setup->plugin_descriptor = ladspa_descriptor;
439 mp_msg(MSGT_AFILTER, MSGL_V, "%s: %s found\n", setup->myname,
440 setup->label);
441 return AF_OK;
445 return AF_OK;
448 /* ------------------------------------------------------------------------- */
450 /** \brief Print a malloc() failed error message.
452 * Generic function which can be called if a call to malloc(), calloc(),
453 * strdup(), et cetera, failed. It prints a message to the console and
454 * returns AF_ERROR.
456 * \return AF_ERROR
459 static int af_ladspa_malloc_failed(char *myname) {
460 mp_msg(MSGT_AFILTER, MSGL_ERR, "%s: %s", myname, "Memory allocation failed.\n");
461 return AF_ERROR;
464 /* ------------------------------------------------------------------------- */
466 /** \brief Controls the filter.
468 * Control the behaviour of the filter.
470 * Commands:
471 * CONTROL_REINIT Sets the af structure with proper values for number
472 * of channels, rate, format, et cetera.
473 * CONTROL_COMMAND_LINE Parses the suboptions given to this filter
474 * through arg. It first parses the filename and
475 * the label. After that, it loads the filter
476 * and finds out its proprties. Then in continues
477 * parsing the controls given on the commandline,
478 * if any are needed.
480 * \param af Audio filter instance
481 * \param cmd The command to execute
482 * \param arg Arguments to the command
484 * \return Either AF_ERROR or AF_OK, depending on the succes of the
485 * operation.
488 static int control(struct af_instance_s *af, int cmd, void *arg) {
489 af_ladspa_t *setup = (af_ladspa_t*) af->setup;
490 int i, r;
491 float val;
493 switch(cmd) {
494 case AF_CONTROL_REINIT:
495 mp_msg(MSGT_AFILTER, MSGL_V, "%s: (re)init\n", setup->myname);
497 if (!arg) return AF_ERROR;
499 /* accept FLOAT, let af_format do conversion */
501 af->data->rate = ((af_data_t*)arg)->rate;
502 af->data->nch = ((af_data_t*)arg)->nch;
503 af->data->format = AF_FORMAT_FLOAT_NE;
504 af->data->bps = 4;
506 /* arg->len is not set here yet, so init of buffers and connecting the
507 * filter, has to be done in play() :-/
510 return af_test_output(af, (af_data_t*)arg);
511 case AF_CONTROL_COMMAND_LINE: {
512 char *buf;
514 mp_msg(MSGT_AFILTER, MSGL_V, "%s: parse suboptions\n", setup->myname);
516 /* suboption parser here!
517 * format is (ladspa=)file:label:controls....
520 if (!arg) {
521 mp_msg(MSGT_AFILTER, MSGL_ERR, "%s: %s\n", setup->myname,
522 _("No suboptions specified."));
523 return AF_ERROR;
526 buf = malloc(strlen(arg)+1);
527 if (!buf) return af_ladspa_malloc_failed(setup->myname);
529 /* file... */
530 buf[0] = '\0';
531 sscanf(arg, "%[^:]", buf);
532 if (buf[0] == '\0') {
533 mp_msg(MSGT_AFILTER, MSGL_ERR, "%s: %s\n", setup->myname,
534 _("No library file specified."));
535 free(buf);
536 return AF_ERROR;
538 arg += strlen(buf);
539 setup->file = strdup(buf);
540 if (!setup->file) return af_ladspa_malloc_failed(setup->myname);
541 mp_msg(MSGT_AFILTER, MSGL_V, "%s: file --> %s\n", setup->myname,
542 setup->file);
543 if (*(char*)arg != '\0') arg++; /* read ':' */
545 /* label... */
546 buf[0] = '\0';
547 sscanf(arg, "%[^:]", buf);
548 if (buf[0] == '\0') {
549 mp_msg(MSGT_AFILTER, MSGL_ERR, "%s: %s\n", setup->myname,
550 _("No filter label specified."));
551 free(buf);
552 return AF_ERROR;
554 arg += strlen(buf);
555 setup->label = strdup(buf);
556 if (!setup->label) return af_ladspa_malloc_failed(setup->myname);
557 mp_msg(MSGT_AFILTER, MSGL_V, "%s: label --> %s\n", setup->myname,
558 setup->label);
559 /* if (*(char*)arg != '0') arg++; */ /* read ':' */
561 free(buf); /* no longer needed */
563 /* set new setup->myname */
565 if(setup->myname) free(setup->myname);
566 setup->myname = calloc(strlen(af_info_ladspa.name)+strlen(setup->file)+
567 strlen(setup->label)+6, 1);
568 snprintf(setup->myname, strlen(af_info_ladspa.name)+
569 strlen(setup->file)+strlen(setup->label)+6, "%s: (%s:%s)",
570 af_info_ladspa.name, setup->file, setup->label);
572 /* load plugin :) */
574 if ( af_ladspa_load_plugin(setup) != AF_OK )
575 return AF_ERROR;
577 /* see what inputs, outputs and controls this plugin has */
578 if ( af_ladspa_parse_plugin(setup) != AF_OK )
579 return AF_ERROR;
581 /* ninputcontrols is set by now, read control values from arg */
583 for(i=0; i<setup->ninputcontrols; i++) {
584 if (!arg || (*(char*)arg != ':') ) {
585 mp_msg(MSGT_AFILTER, MSGL_ERR, "%s: %s\n", setup->myname,
586 _("Not enough controls specified on the command line."));
587 return AF_ERROR;
589 arg++;
590 r = sscanf(arg, "%f", &val);
591 if (r!=1) {
592 mp_msg(MSGT_AFILTER, MSGL_ERR, "%s: %s\n", setup->myname,
593 _("Not enough controls specified on the command line."));
594 return AF_ERROR;
596 setup->inputcontrols[setup->inputcontrolsmap[i]] = val;
597 arg = strchr(arg, ':');
600 mp_msg(MSGT_AFILTER, MSGL_V, "%s: input controls: ", setup->myname);
601 for(i=0; i<setup->ninputcontrols; i++) {
602 mp_msg(MSGT_AFILTER, MSGL_V, "%0.4f ",
603 setup->inputcontrols[setup->inputcontrolsmap[i]]);
605 mp_msg(MSGT_AFILTER, MSGL_V, "\n");
607 /* check boundaries of inputcontrols */
609 mp_msg(MSGT_AFILTER, MSGL_V, "%s: checking boundaries of input controls\n",
610 setup->myname);
611 for(i=0; i<setup->ninputcontrols; i++) {
612 int p = setup->inputcontrolsmap[i];
613 LADSPA_PortRangeHint hint =
614 setup->plugin_descriptor->PortRangeHints[p];
615 val = setup->inputcontrols[p];
617 if (LADSPA_IS_HINT_BOUNDED_BELOW(hint.HintDescriptor) &&
618 val < hint.LowerBound) {
619 mp_tmsg(MSGT_AFILTER, MSGL_ERR, "%s: Input control #%d is below lower boundary of %0.4f.\n",
620 setup->myname, i, hint.LowerBound);
621 return AF_ERROR;
623 if (LADSPA_IS_HINT_BOUNDED_ABOVE(hint.HintDescriptor) &&
624 val > hint.UpperBound) {
625 mp_tmsg(MSGT_AFILTER, MSGL_ERR, "%s: Input control #%d is above upper boundary of %0.4f.\n",
626 setup->myname, i, hint.UpperBound);
627 return AF_ERROR;
630 mp_msg(MSGT_AFILTER, MSGL_V, "%s: all controls have sane values\n",
631 setup->myname);
633 /* All is well! */
634 setup->status = AF_OK;
636 return AF_OK; }
639 return AF_UNKNOWN;
642 /* ------------------------------------------------------------------------- */
644 /** \brief Uninitialise the LADSPA Plugin Loader filter.
646 * This function deactivates the plugin(s), cleans up, frees all allocated
647 * memory and exits.
649 * \return No return value.
652 static void uninit(struct af_instance_s *af) {
653 int i;
655 if (af->data)
656 free(af->data);
657 if (af->setup) {
658 af_ladspa_t *setup = (af_ladspa_t*) af->setup;
659 const LADSPA_Descriptor *pdes = setup->plugin_descriptor;
661 if (setup->myname) {
662 mp_msg(MSGT_AFILTER, MSGL_V, "%s: cleaning up\n", setup->myname);
663 free(setup->myname);
666 if (setup->chhandles) {
667 for(i=0; i<setup->nch; i+=setup->ninputs) {
668 if (pdes->deactivate) pdes->deactivate(setup->chhandles[i]);
669 if (pdes->cleanup) pdes->cleanup(setup->chhandles[i]);
671 free(setup->chhandles);
674 if (setup->file)
675 free(setup->file);
676 if (setup->label)
677 free(setup->label);
678 if (setup->inputcontrolsmap)
679 free(setup->inputcontrolsmap);
680 if (setup->inputcontrols)
681 free(setup->inputcontrols);
682 if (setup->outputcontrolsmap)
683 free(setup->outputcontrolsmap);
684 if (setup->outputcontrols)
685 free(setup->outputcontrols);
686 if (setup->inputs)
687 free(setup->inputs);
688 if (setup->outputs)
689 free(setup->outputs);
691 if (setup->inbufs) {
692 for(i=0; i<setup->nch; i++) {
693 if (setup->inbufs[i])
694 free(setup->inbufs[i]);
696 free(setup->inbufs);
699 if (setup->outbufs) {
700 for(i=0; i<setup->nch; i++) {
701 if (setup->outbufs[i])
702 free(setup->outbufs[i]);
704 free(setup->outbufs);
707 if (setup->libhandle)
708 dlclose(setup->libhandle);
710 free(setup);
711 setup = NULL;
715 /* ------------------------------------------------------------------------- */
717 /** \brief Process chunk of audio data through the selected LADSPA Plugin.
719 * \param af Pointer to audio filter instance
720 * \param data Pointer to chunk of audio data
722 * \return Either AF_ERROR or AF_OK
725 static af_data_t* play(struct af_instance_s *af, af_data_t *data) {
726 af_ladspa_t *setup = af->setup;
727 const LADSPA_Descriptor *pdes = setup->plugin_descriptor;
728 float *audio = (float*)data->audio;
729 int nsamples = data->len/4; /* /4 because it's 32-bit float */
730 int nch = data->nch;
731 int rate = data->rate;
732 int i, p;
734 if (setup->status !=AF_OK)
735 return data;
737 /* See if it's the first call. If so, setup inbufs/outbufs, instantiate
738 * plugin, connect ports and activate plugin
741 /* 2004-12-07: Also check if the buffersize has to be changed!
742 * data->len is not constant per se! re-init buffers.
745 if ( (setup->bufsize != nsamples/nch) || (setup->nch != nch) ) {
747 /* if setup->nch==0, it's the first call, if not, something has
748 * changed and all previous mallocs have to be freed
751 if (setup->nch != 0) {
752 mp_msg(MSGT_AFILTER, MSGL_DBG3, "%s: bufsize change; free old buffer\n",
753 setup->myname);
755 if(setup->inbufs) {
756 for(i=0; i<setup->nch; i++) {
757 if(setup->inbufs[i])
758 free(setup->inbufs[i]);
760 free(setup->inbufs);
762 if(setup->outbufs) {
763 for(i=0; i<setup->nch; i++) {
764 if(setup->outbufs[i])
765 free(setup->outbufs[i]);
767 free(setup->outbufs);
769 } /* everything is freed */
771 setup->bufsize = nsamples/nch;
772 setup->nch = nch;
774 setup->inbufs = calloc(nch, sizeof(float*));
775 setup->outbufs = calloc(nch, sizeof(float*));
777 mp_msg(MSGT_AFILTER, MSGL_DBG3, "%s: bufsize = %d\n",
778 setup->myname, setup->bufsize);
780 for(i=0; i<nch; i++) {
781 setup->inbufs[i] = calloc(setup->bufsize, sizeof(float));
782 setup->outbufs[i] = calloc(setup->bufsize, sizeof(float));
785 /* only on the first call, there are no handles. */
787 if (!setup->chhandles) {
788 setup->chhandles = calloc(nch, sizeof(LADSPA_Handle));
790 /* create handles
791 * for stereo effects, create one handle for two channels
794 for(i=0; i<nch; i++) {
796 if (i % setup->ninputs) { /* stereo effect */
797 /* copy the handle from previous channel */
798 setup->chhandles[i] = setup->chhandles[i-1];
799 continue;
802 setup->chhandles[i] = pdes->instantiate(pdes, rate);
806 /* connect input/output ports for each channel/filter instance
808 * always (re)connect ports
811 for(i=0; i<nch; i++) {
812 pdes->connect_port(setup->chhandles[i],
813 setup->inputs[i % setup->ninputs],
814 setup->inbufs[i]);
815 pdes->connect_port(setup->chhandles[i],
816 setup->outputs[i % setup->ninputs],
817 setup->outbufs[i]);
819 /* connect (input) controls */
821 for (p=0; p<setup->nports; p++) {
822 LADSPA_PortDescriptor d = pdes->PortDescriptors[p];
823 if (LADSPA_IS_PORT_CONTROL(d)) {
824 if (LADSPA_IS_PORT_INPUT(d)) {
825 pdes->connect_port(setup->chhandles[i], p,
826 &(setup->inputcontrols[p]) );
827 } else {
828 pdes->connect_port(setup->chhandles[i], p,
829 &(setup->outputcontrols[p]) );
834 /* Activate filter (if it isn't already :) ) */
836 if (pdes->activate && !setup->activated && i % setup->ninputs == 0)
837 pdes->activate(setup->chhandles[i]);
839 } /* All channels/filters done! except for... */
840 setup->activated = 1;
842 /* Stereo effect with one channel left. Use same buffer for left
843 * and right. connect it to the second port.
846 for (p = i; p % setup->ninputs; p++) {
847 pdes->connect_port(setup->chhandles[i-1],
848 setup->inputs[p % setup->ninputs],
849 setup->inbufs[i-1]);
850 pdes->connect_port(setup->chhandles[i-1],
851 setup->outputs[p % setup->ninputs],
852 setup->outbufs[i-1]);
853 } /* done! */
855 } /* setup for first call/change of bufsize is done.
856 * normal playing routine follows...
859 /* Right now, I use a separate input and output buffer.
860 * I could change this to in-place processing (inbuf==outbuf), but some
861 * ladspa filters are broken and are not able to handle that. This seems
862 * fast enough, so unless somebody complains, it stays this way :)
865 /* Fill inbufs */
867 for (p=0; p<setup->bufsize; p++) {
868 for (i=0; i<nch; i++) {
869 setup->inbufs[i][p] = audio[p*nch + i];
873 /* Run filter(s) */
875 for (i=0; i<nch; i+=setup->ninputs) {
876 pdes->run(setup->chhandles[i], setup->bufsize);
879 /* Extract outbufs */
881 for (p=0; p<setup->bufsize; p++) {
882 for (i=0; i<nch; i++) {
883 audio[p*nch + i] = setup->outbufs[i][p];
887 /* done */
889 return data;
892 /* ------------------------------------------------------------------------- */
894 /** \brief Open LADSPA Plugin Loader Filter
896 * \param af Audio Filter instance
898 * \return Either AF_ERROR or AF_OK
901 static int af_open(af_instance_t *af) {
903 af->control=control;
904 af->uninit=uninit;
905 af->play=play;
906 af->mul=1;
908 af->data = calloc(1, sizeof(af_data_t));
909 if (af->data == NULL)
910 return af_ladspa_malloc_failed((char*)af_info_ladspa.name);
912 af->setup = calloc(1, sizeof(af_ladspa_t));
913 if (af->setup == NULL) {
914 free(af->data);
915 af->data=NULL;
916 return af_ladspa_malloc_failed((char*)af_info_ladspa.name);
919 ((af_ladspa_t*)af->setup)->status = AF_ERROR; /* will be set to AF_OK if
920 * all went OK and play()
921 * should proceed.
924 ((af_ladspa_t*)af->setup)->myname = strdup(af_info_ladspa.name);
925 if (!((af_ladspa_t*)af->setup)->myname)
926 return af_ladspa_malloc_failed((char*)af_info_ladspa.name);
928 return AF_OK;
931 /* ------------------------------------------------------------------------- */