1 /*
2 * LADSPA plugin loader
3 *
4 * Written by Ivo van Poorten <ivop@euronet.nl>
5 * Copyright (C) 2004, 2005
6 *
7 * This file is part of MPlayer.
8 *
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.
13 *
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.
18 *
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.
22 */
23
24 /* ------------------------------------------------------------------------- */
25
26 /* Global Includes */
27
28 #include <stdio.h>
29 #include <stdlib.h>
30 #include <string.h>
31
32 #include <inttypes.h>
33 #include <math.h>
34 #include <limits.h>
35
36 #include <dlfcn.h>
37 #include <ladspa.h>
38
39 /* ------------------------------------------------------------------------- */
40
41 /* Local Includes */
42
43 #include "help_mp.h"
44 #include "mp_msg.h"
45 #include "af.h"
46
47 /* ------------------------------------------------------------------------- */
48
49 /* Filter specific data */
50
51 typedef struct af_ladspa_s
52 {
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.
59 */
60
61 int activated; /**< 0 or 1. Activate LADSPA filters only once, even
62 * if the buffers get resized, to avoid a stuttering
63 * filter.
64 */
65
66 char *file;
67 char *label;
68
69 char *myname; /**< It's easy to have a concatenation of file and label */
70
71 void *libhandle;
72 const LADSPA_Descriptor *plugin_descriptor;
73
74 int nports;
75
76 int ninputs;
77 int *inputs;
78
79 int noutputs;
80 int *outputs;
81
82 int ninputcontrols;
83 int *inputcontrolsmap; /**< Map input port number [0-] to actual port */
84 float *inputcontrols;
85
86 int noutputcontrols;
87 int *outputcontrolsmap;
88 float *outputcontrols;
89
90 int nch; /**< number of channels */
91 int bufsize;
92 float **inbufs;
93 float **outbufs;
94 LADSPA_Handle *chhandles;
95
96 } af_ladspa_t;
97
98 /* ------------------------------------------------------------------------- */
99
100 static int af_open(af_instance_t *af);
101 static int af_ladspa_malloc_failed(char*);
102
103 /* ------------------------------------------------------------------------- */
104
105 /* Description */
106
107 const af_info_t af_info_ladspa = {
108 "LADSPA plugin loader",
109 "ladspa",
110 "Ivo van Poorten",
111 "",
112 AF_FLAGS_REENTRANT,
113 af_open
114 };
115
116 /* ------------------------------------------------------------------------- */
117
118 /* By lack of a better word (in my vocabulary) this is called 'parse'.
119 * Feel free to suggest an alternative.
120 */
121
122 /** \brief Check for inputs, outputs and controls of a given filter.
123 *
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.
128 *
129 * \param setup Current setup of the filter. Must have its
130 * plugin_descriptor set!
131 *
132 * \return Returns AF_OK if it has a valid input/output/controls
133 * configuration. Else, it returns AF_ERROR.
134 */
135
af_ladspa_parse_plugin(af_ladspa_t * setup)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;
141
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 */
146
147 /* let's do it */
148
149 setup->nports = pdes->PortCount;
150
151 /* allocate memory for all inputs/outputs/controls */
152
153 setup->inputs = calloc(setup->nports, sizeof(int));
154 if (!setup->inputs) return af_ladspa_malloc_failed(setup->myname);
155
156 setup->outputs = calloc(setup->nports, sizeof(int));
157 if (!setup->outputs) return af_ladspa_malloc_failed(setup->myname);
158
159 setup->inputcontrolsmap = calloc(setup->nports, sizeof(int));
160 if (!setup->inputcontrolsmap) return af_ladspa_malloc_failed(setup->myname);
161
162 setup->inputcontrols = calloc(setup->nports, sizeof(float));
163 if (!setup->inputcontrols) return af_ladspa_malloc_failed(setup->myname);
164
165 setup->outputcontrolsmap = calloc(setup->nports, sizeof(int));
166 if (!setup->outputcontrolsmap) return af_ladspa_malloc_failed(setup->myname);
167
168 setup->outputcontrols = calloc(setup->nports, sizeof(float));
169 if (!setup->outputcontrols) return af_ladspa_malloc_failed(setup->myname);
170
171 /* set counts to zero */
172
173 setup->ninputs = 0;
174 setup->noutputs = 0;
175 setup->ninputcontrols = 0;
176 setup->noutputcontrols = 0;
177
178 /* check all ports, see what type it is and set variables according to
179 * what we have found
180 */
181
182 for (p=0; p<setup->nports; p++) {
183 d = pdes->PortDescriptors[p];
184
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++;
192 }
193 }
194
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.
201 */
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
206 */
207 setup->outputcontrolsmap[setup->noutputcontrols]=p;
208 setup->noutputcontrols++;
209 setup->outputcontrols[p] = 0.0f;
210 }
211 }
212
213 }
214
215 if (setup->ninputs == 0) {
216 mp_msg(MSGT_AFILTER, MSGL_WARN, "%s: %s\n", setup->myname,
217 MSGTR_AF_LADSPA_WarnNoInputs);
218 } else if (setup->ninputs == 1) {
219 mp_msg(MSGT_AFILTER, MSGL_V, "%s: this is a mono effect\n", setup->myname);
220 } else if (setup->ninputs == 2) {
221 mp_msg(MSGT_AFILTER, MSGL_V, "%s: this is a stereo effect\n", setup->myname);
222 } else {
223 mp_msg(MSGT_AFILTER, MSGL_V, "%s: this is a %i-channel effect, "
224 "support is experimental\n", setup->myname, setup->ninputs);
225 }
226
227 if (setup->noutputs == 0) {
228 mp_msg(MSGT_AFILTER, MSGL_ERR, "%s: %s\n", setup->myname,
229 MSGTR_AF_LADSPA_ErrNoOutputs);
230 return AF_ERROR;
231 }
232
233 if (setup->noutputs != setup->ninputs ) {
234 mp_msg(MSGT_AFILTER, MSGL_ERR, "%s: %s\n", setup->myname,
235 MSGTR_AF_LADSPA_ErrInOutDiff);
236 return AF_ERROR;
237 }
238
239 mp_msg(MSGT_AFILTER, MSGL_V, "%s: this plugin has %d input control(s)\n",
240 setup->myname, setup->ninputcontrols);
241
242 /* Print list of controls and its range of values it accepts */
243
244 for (i=0; i<setup->ninputcontrols; i++) {
245 p = setup->inputcontrolsmap[i];
246 hint = pdes->PortRangeHints[p];
247 mp_msg(MSGT_AFILTER, MSGL_V, " --- %d %s [", i, pdes->PortNames[p]);
248
249 if (LADSPA_IS_HINT_BOUNDED_BELOW(hint.HintDescriptor)) {
250 mp_msg(MSGT_AFILTER, MSGL_V, "%0.2f , ", hint.LowerBound);
251 } else {
252 mp_msg(MSGT_AFILTER, MSGL_V, "... , ");
253 }
254
255 if (LADSPA_IS_HINT_BOUNDED_ABOVE(hint.HintDescriptor)) {
256 mp_msg(MSGT_AFILTER, MSGL_V, "%0.2f]\n", hint.UpperBound);
257 } else {
258 mp_msg(MSGT_AFILTER, MSGL_V, "...]\n");
259 }
260
261 }
262
263 return AF_OK;
264 }
265
266 /* ------------------------------------------------------------------------- */
267
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 :-))
277 */
278
279 /** \brief dlopen() wrapper
280 *
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.
285 *
286 * \param filename filename of the library to load.
287 * \param flag see dlopen(3) for a description of the flags.
288 *
289 * \return returns a pointer to the loaded library on success, or
290 * NULL if it fails to load.
291 */
292
mydlopen(const char * filename,int flag)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;
299
300 #if defined(__MINGW32__) || defined(__CYGWIN__)
301 /* For Windows there's only absolute path support.
302 * If you have a Windows machine, feel free to fix this.
303 * (path separator, shared objects extension, et cetera). */
304 mp_msg(MSGT_AFILTER, MSGL_V, "\ton windows, only absolute pathnames "
305 "are supported\n");
306 mp_msg(MSGT_AFILTER, MSGL_V, "\ttrying %s\n", filename);
307 return dlopen(filename, flag);
308 #endif
309
310 filenamelen = strlen(filename);
311
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);
321 }
322
323 if (result)
324 return result;
325
326 ladspapath=getenv("LADSPA_PATH");
327
328 if (ladspapath) {
329
330 start=ladspapath;
331 while (*start != '\0') {
332 end=start;
333 while ( (*end != ':') && (*end != '\0') )
334 end++;
335
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] = '/';
344 }
345 strcpy(buf+needslash+(end-start), filename);
346
347 mp_msg(MSGT_AFILTER, MSGL_V, "\ttrying %s\n", buf);
348 result=dlopen(buf, flag);
349
350 free(buf);
351 if (result)
352 return result;
353
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 */
359
360 /* last resort, just open it again, so the dlerror() message is correct */
361 mp_msg(MSGT_AFILTER, MSGL_V, "\ttrying %s\n", filename);
362 return dlopen(filename,flag);
363 }
364
365 /* ------------------------------------------------------------------------- */
366
367 /** \brief Load a LADSPA Plugin
368 *
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.
376 *
377 * \param setup Current setup of the filter. Contains filename and label.
378 *
379 * \return Either AF_ERROR or AF_OK, depending on the success of the operation.
380 */
381
af_ladspa_load_plugin(af_ladspa_t * setup)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;
386
387 /* load library */
388 mp_msg(MSGT_AFILTER, MSGL_V, "%s: loading ladspa plugin library %s\n",
389 setup->myname, setup->file);
390
391 setup->libhandle = mydlopen(setup->file, RTLD_NOW);
392
393 if (!setup->libhandle) {
394 mp_msg(MSGT_AFILTER, MSGL_ERR, "%s: %s %s\n\t%s\n", setup->myname,
395 MSGTR_AF_LADSPA_ErrFailedToLoad, setup->file, dlerror() );
396 return AF_ERROR;
397 }
398
399 mp_msg(MSGT_AFILTER, MSGL_V, "%s: library found.\n", setup->myname);
400
401 /* find descriptor function */
402 dlerror();
403 descriptor_function = (LADSPA_Descriptor_Function) dlsym (setup->libhandle,
404 "ladspa_descriptor");
405
406 if (!descriptor_function) {
407 mp_msg(MSGT_AFILTER, MSGL_ERR, "%s: %s\n\t%s\n", setup->myname,
408 MSGTR_AF_LADSPA_ErrNoDescriptor, dlerror());
409 return AF_ERROR;
410 }
411
412 /* if label == help, list all labels in library and exit */
413
414 if (strcmp(setup->label, "help") == 0) {
415 mp_msg(MSGT_AFILTER, MSGL_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;
421 }
422 mp_msg(MSGT_AFILTER, MSGL_INFO, " %-16s - %s (%lu)\n",
423 ladspa_descriptor->Label,
424 ladspa_descriptor->Name,
425 ladspa_descriptor->UniqueID);
426 }
427 }
428
429 mp_msg(MSGT_AFILTER, MSGL_V, "%s: looking for label\n", setup->myname);
430
431 /* find label in library */
432 for (i=0; ; i++) {
433 ladspa_descriptor = descriptor_function(i);
434 if (ladspa_descriptor == NULL) {
435 mp_msg(MSGT_AFILTER, MSGL_ERR, "%s: %s\n", setup->myname,
436 MSGTR_AF_LADSPA_ErrLabelNotFound);
437 return AF_ERROR;
438 }
439 if (strcmp(ladspa_descriptor->Label, setup->label) == 0) {
440 setup->plugin_descriptor = ladspa_descriptor;
441 mp_msg(MSGT_AFILTER, MSGL_V, "%s: %s found\n", setup->myname,
442 setup->label);
443 return AF_OK;
444 }
445 }
446
447 return AF_OK;
448 }
449
450 /* ------------------------------------------------------------------------- */
451
452 /** \brief Print a malloc() failed error message.
453 *
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.
457 *
458 * \return AF_ERROR
459 */
460
af_ladspa_malloc_failed(char * myname)461 static int af_ladspa_malloc_failed(char *myname) {
462 mp_msg(MSGT_AFILTER, MSGL_ERR, "%s: %s", myname, MSGTR_MemAllocFailed);
463 return AF_ERROR;
464 }
465
466 /* ------------------------------------------------------------------------- */
467
468 /** \brief Controls the filter.
469 *
470 * Control the behaviour of the filter.
471 *
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.
481 *
482 * \param af Audio filter instance
483 * \param cmd The command to execute
484 * \param arg Arguments to the command
485 *
486 * \return Either AF_ERROR or AF_OK, depending on the succes of the
487 * operation.
488 */
489
control(struct af_instance_s * af,int cmd,void * arg)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;
494
495 switch(cmd) {
496 case AF_CONTROL_REINIT:
497 mp_msg(MSGT_AFILTER, MSGL_V, "%s: (re)init\n", setup->myname);
498
499 if (!arg) return AF_ERROR;
500
501 /* accept FLOAT, let af_format do conversion */
502
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;
507
508 /* arg->len is not set here yet, so init of buffers and connecting the
509 * filter, has to be done in play() :-/
510 */
511
512 return af_test_output(af, (af_data_t*)arg);
513 case AF_CONTROL_COMMAND_LINE: {
514 char *buf;
515
516 mp_msg(MSGT_AFILTER, MSGL_V, "%s: parse suboptions\n", setup->myname);
517
518 /* suboption parser here!
519 * format is (ladspa=)file:label:controls....
520 */
521
522 if (!arg) {
523 mp_msg(MSGT_AFILTER, MSGL_ERR, "%s: %s\n", setup->myname,
524 MSGTR_AF_LADSPA_ErrNoSuboptions);
525 return AF_ERROR;
526 }
527
528 buf = malloc(strlen(arg)+1);
529 if (!buf) return af_ladspa_malloc_failed(setup->myname);
530
531 /* file... */
532 buf[0] = '\0';
533 sscanf(arg, "%[^:]", buf);
534 if (buf[0] == '\0') {
535 mp_msg(MSGT_AFILTER, MSGL_ERR, "%s: %s\n", setup->myname,
536 MSGTR_AF_LADSPA_ErrNoLibFile);
537 free(buf);
538 return AF_ERROR;
539 }
540 arg += strlen(buf);
541 setup->file = strdup(buf);
542 if (!setup->file) return af_ladspa_malloc_failed(setup->myname);
543 mp_msg(MSGT_AFILTER, MSGL_V, "%s: file --> %s\n", setup->myname,
544 setup->file);
545 if (*(char*)arg != '\0') arg++; /* read ':' */
546
547 /* label... */
548 buf[0] = '\0';
549 sscanf(arg, "%[^:]", buf);
550 if (buf[0] == '\0') {
551 mp_msg(MSGT_AFILTER, MSGL_ERR, "%s: %s\n", setup->myname,
552 MSGTR_AF_LADSPA_ErrNoLabel);
553 free(buf);
554 return AF_ERROR;
555 }
556 arg += strlen(buf);
557 setup->label = strdup(buf);
558 if (!setup->label) return af_ladspa_malloc_failed(setup->myname);
559 mp_msg(MSGT_AFILTER, MSGL_V, "%s: label --> %s\n", setup->myname,
560 setup->label);
561 /* if (*(char*)arg != '0') arg++; */ /* read ':' */
562
563 free(buf); /* no longer needed */
564
565 /* set new setup->myname */
566
567 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);
573
574 /* load plugin :) */
575
576 if ( af_ladspa_load_plugin(setup) != AF_OK )
577 return AF_ERROR;
578
579 /* see what inputs, outputs and controls this plugin has */
580 if ( af_ladspa_parse_plugin(setup) != AF_OK )
581 return AF_ERROR;
582
583 /* ninputcontrols is set by now, read control values from arg */
584
585 for(i=0; i<setup->ninputcontrols; i++) {
586 if (!arg || (*(char*)arg != ':') ) {
587 mp_msg(MSGT_AFILTER, MSGL_ERR, "%s: %s\n", setup->myname,
588 MSGTR_AF_LADSPA_ErrNotEnoughControls);
589 return AF_ERROR;
590 }
591 arg++;
592 r = sscanf(arg, "%f", &val);
593 if (r!=1) {
594 mp_msg(MSGT_AFILTER, MSGL_ERR, "%s: %s\n", setup->myname,
595 MSGTR_AF_LADSPA_ErrNotEnoughControls);
596 return AF_ERROR;
597 }
598 setup->inputcontrols[setup->inputcontrolsmap[i]] = val;
599 arg = strchr(arg, ':');
600 }
601
602 mp_msg(MSGT_AFILTER, MSGL_V, "%s: input controls: ", setup->myname);
603 for(i=0; i<setup->ninputcontrols; i++) {
604 mp_msg(MSGT_AFILTER, MSGL_V, "%0.4f ",
605 setup->inputcontrols[setup->inputcontrolsmap[i]]);
606 }
607 mp_msg(MSGT_AFILTER, MSGL_V, "\n");
608
609 /* check boundaries of inputcontrols */
610
611 mp_msg(MSGT_AFILTER, MSGL_V, "%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];
618
619 if (LADSPA_IS_HINT_BOUNDED_BELOW(hint.HintDescriptor) &&
620 val < hint.LowerBound) {
621 mp_msg(MSGT_AFILTER, MSGL_ERR, MSGTR_AF_LADSPA_ErrControlBelow,
622 setup->myname, i, hint.LowerBound);
623 return AF_ERROR;
624 }
625 if (LADSPA_IS_HINT_BOUNDED_ABOVE(hint.HintDescriptor) &&
626 val > hint.UpperBound) {
627 mp_msg(MSGT_AFILTER, MSGL_ERR, MSGTR_AF_LADSPA_ErrControlAbove,
628 setup->myname, i, hint.UpperBound);
629 return AF_ERROR;
630 }
631 }
632 mp_msg(MSGT_AFILTER, MSGL_V, "%s: all controls have sane values\n",
633 setup->myname);
634
635 /* All is well! */
636 setup->status = AF_OK;
637
638 return AF_OK; }
639 }
640
641 return AF_UNKNOWN;
642 }
643
644 /* ------------------------------------------------------------------------- */
645
646 /** \brief Uninitialise the LADSPA Plugin Loader filter.
647 *
648 * This function deactivates the plugin(s), cleans up, frees all allocated
649 * memory and exits.
650 *
651 * \return No return value.
652 */
653
uninit(struct af_instance_s * af)654 static void uninit(struct af_instance_s *af) {
655 int i;
656
657 free(af->data);
658 if (af->setup) {
659 af_ladspa_t *setup = (af_ladspa_t*) af->setup;
660 const LADSPA_Descriptor *pdes = setup->plugin_descriptor;
661
662 if (setup->myname) {
663 mp_msg(MSGT_AFILTER, MSGL_V, "%s: cleaning up\n", setup->myname);
664 free(setup->myname);
665 }
666
667 if (setup->chhandles) {
668 for(i=0; i<setup->nch; i+=setup->ninputs) {
669 if (pdes->deactivate) pdes->deactivate(setup->chhandles[i]);
670 if (pdes->cleanup) pdes->cleanup(setup->chhandles[i]);
671 }
672 free(setup->chhandles);
673 }
674
675 free(setup->file);
676 free(setup->label);
677 free(setup->inputcontrolsmap);
678 free(setup->inputcontrols);
679 free(setup->outputcontrolsmap);
680 free(setup->outputcontrols);
681 free(setup->inputs);
682 free(setup->outputs);
683
684 if (setup->inbufs) {
685 for(i=0; i<setup->nch; i++)
686 free(setup->inbufs[i]);
687 free(setup->inbufs);
688 }
689
690 if (setup->outbufs) {
691 for(i=0; i<setup->nch; i++)
692 free(setup->outbufs[i]);
693 free(setup->outbufs);
694 }
695
696 if (setup->libhandle)
697 dlclose(setup->libhandle);
698
699 free(setup);
700 setup = NULL;
701 }
702 }
703
704 /* ------------------------------------------------------------------------- */
705
706 /** \brief Process chunk of audio data through the selected LADSPA Plugin.
707 *
708 * \param af Pointer to audio filter instance
709 * \param data Pointer to chunk of audio data
710 *
711 * \return Either AF_ERROR or AF_OK
712 */
713
play(struct af_instance_s * af,af_data_t * data)714 static af_data_t* play(struct af_instance_s *af, af_data_t *data) {
715 af_ladspa_t *setup = af->setup;
716 const LADSPA_Descriptor *pdes = setup->plugin_descriptor;
717 float *audio = (float*)data->audio;
718 int nsamples = data->len/4; /* /4 because it's 32-bit float */
719 int nch = data->nch;
720 int rate = data->rate;
721 int i, p;
722
723 if (setup->status !=AF_OK)
724 return data;
725
726 /* See if it's the first call. If so, setup inbufs/outbufs, instantiate
727 * plugin, connect ports and activate plugin
728 */
729
730 /* 2004-12-07: Also check if the buffersize has to be changed!
731 * data->len is not constant per se! re-init buffers.
732 */
733
734 if ( (setup->bufsize != nsamples/nch) || (setup->nch != nch) ) {
735
736 /* if setup->nch==0, it's the first call, if not, something has
737 * changed and all previous mallocs have to be freed
738 */
739
740 if (setup->nch != 0) {
741 mp_msg(MSGT_AFILTER, MSGL_DBG3, "%s: bufsize change; free old buffer\n",
742 setup->myname);
743
744 if(setup->inbufs) {
745 for(i=0; i<setup->nch; i++)
746 free(setup->inbufs[i]);
747 free(setup->inbufs);
748 }
749 if(setup->outbufs) {
750 for(i=0; i<setup->nch; i++)
751 free(setup->outbufs[i]);
752 free(setup->outbufs);
753 }
754 } /* everything is freed */
755
756 setup->bufsize = nsamples/nch;
757 setup->nch = nch;
758
759 setup->inbufs = calloc(nch, sizeof(float*));
760 setup->outbufs = calloc(nch, sizeof(float*));
761
762 mp_msg(MSGT_AFILTER, MSGL_DBG3, "%s: bufsize = %d\n",
763 setup->myname, setup->bufsize);
764
765 for(i=0; i<nch; i++) {
766 setup->inbufs[i] = calloc(setup->bufsize, sizeof(float));
767 setup->outbufs[i] = calloc(setup->bufsize, sizeof(float));
768 }
769
770 /* only on the first call, there are no handles. */
771
772 if (!setup->chhandles) {
773 setup->chhandles = calloc(nch, sizeof(LADSPA_Handle));
774
775 /* create handles
776 * for stereo effects, create one handle for two channels
777 */
778
779 for(i=0; i<nch; i++) {
780
781 if (i % setup->ninputs) { /* stereo effect */
782 /* copy the handle from previous channel */
783 setup->chhandles[i] = setup->chhandles[i-1];
784 continue;
785 }
786
787 setup->chhandles[i] = pdes->instantiate(pdes, rate);
788 }
789 }
790
791 /* connect input/output ports for each channel/filter instance
792 *
793 * always (re)connect ports
794 */
795
796 for(i=0; i<nch; i++) {
797 pdes->connect_port(setup->chhandles[i],
798 setup->inputs[i % setup->ninputs],
799 setup->inbufs[i]);
800 pdes->connect_port(setup->chhandles[i],
801 setup->outputs[i % setup->ninputs],
802 setup->outbufs[i]);
803
804 /* connect (input) controls */
805
806 for (p=0; p<setup->nports; p++) {
807 LADSPA_PortDescriptor d = pdes->PortDescriptors[p];
808 if (LADSPA_IS_PORT_CONTROL(d)) {
809 if (LADSPA_IS_PORT_INPUT(d)) {
810 pdes->connect_port(setup->chhandles[i], p,
811 &(setup->inputcontrols[p]) );
812 } else {
813 pdes->connect_port(setup->chhandles[i], p,
814 &(setup->outputcontrols[p]) );
815 }
816 }
817 }
818
819 /* Activate filter (if it isn't already :) ) */
820
821 if (pdes->activate && !setup->activated && i % setup->ninputs == 0)
822 pdes->activate(setup->chhandles[i]);
823
824 } /* All channels/filters done! except for... */
825 setup->activated = 1;
826
827 /* Stereo effect with one channel left. Use same buffer for left
828 * and right. connect it to the second port.
829 */
830
831 for (p = i; p % setup->ninputs; p++) {
832 pdes->connect_port(setup->chhandles[i-1],
833 setup->inputs[p % setup->ninputs],
834 setup->inbufs[i-1]);
835 pdes->connect_port(setup->chhandles[i-1],
836 setup->outputs[p % setup->ninputs],
837 setup->outbufs[i-1]);
838 } /* done! */
839
840 } /* setup for first call/change of bufsize is done.
841 * normal playing routine follows...
842 */
843
844 /* Right now, I use a separate input and output buffer.
845 * I could change this to in-place processing (inbuf==outbuf), but some
846 * ladspa filters are broken and are not able to handle that. This seems
847 * fast enough, so unless somebody complains, it stays this way :)
848 */
849
850 /* Fill inbufs */
851
852 for (p=0; p<setup->bufsize; p++) {
853 for (i=0; i<nch; i++) {
854 setup->inbufs[i][p] = audio[p*nch + i];
855 }
856 }
857
858 /* Run filter(s) */
859
860 for (i=0; i<nch; i+=setup->ninputs) {
861 pdes->run(setup->chhandles[i], setup->bufsize);
862 }
863
864 /* Extract outbufs */
865
866 for (p=0; p<setup->bufsize; p++) {
867 for (i=0; i<nch; i++) {
868 audio[p*nch + i] = setup->outbufs[i][p];
869 }
870 }
871
872 /* done */
873
874 return data;
875 }
876
877 /* ------------------------------------------------------------------------- */
878
879 /** \brief Open LADSPA Plugin Loader Filter
880 *
881 * \param af Audio Filter instance
882 *
883 * \return Either AF_ERROR or AF_OK
884 */
885
af_open(af_instance_t * af)886 static int af_open(af_instance_t *af) {
887
888 af->control=control;
889 af->uninit=uninit;
890 af->play=play;
891 af->mul=1;
892
893 af->data = calloc(1, sizeof(af_data_t));
894 if (af->data == NULL)
895 return af_ladspa_malloc_failed((char*)af_info_ladspa.name);
896
897 af->setup = calloc(1, sizeof(af_ladspa_t));
898 if (af->setup == NULL) {
899 free(af->data);
900 af->data=NULL;
901 return af_ladspa_malloc_failed((char*)af_info_ladspa.name);
902 }
903
904 ((af_ladspa_t*)af->setup)->status = AF_ERROR; /* will be set to AF_OK if
905 * all went OK and play()
906 * should proceed.
907 */
908
909 ((af_ladspa_t*)af->setup)->myname = strdup(af_info_ladspa.name);
910 if (!((af_ladspa_t*)af->setup)->myname)
911 return af_ladspa_malloc_failed((char*)af_info_ladspa.name);
912
913 return AF_OK;
914 }
915
916 /* ------------------------------------------------------------------------- */
917