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