~ubuntu-dev/mplayer/ubuntu-feisty

« back to all changes in this revision

Viewing changes to libaf/af_ladspa.c

  • Committer: Reinhard Tartler
  • Date: 2006-07-08 08:45:33 UTC
  • Revision ID: siretart@tauware.de-20060708084533-dbc155bde7122e78
imported mplayer_0.99+1.0pre7try2+cvs20060117

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* ------------------------------------------------------------------------- */
 
2
 
 
3
/*
 
4
 * af_ladspa.c, LADSPA plugin loader
 
5
 *
 
6
 * Written by Ivo van Poorten <ivop@euronet.nl>
 
7
 * Copyright (C) 2004, 2005
 
8
 *
 
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.
 
13
 *
 
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.
 
18
 *
 
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., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 
22
 *
 
23
 *
 
24
 * Changelog
 
25
 *
 
26
 * 2005-06-21   Replaced erroneous use of mp_msg by af_msg
 
27
 * 2005-05-30   Removed int16 to float conversion; leave that to af_format
 
28
 * 2004-12-23   Added to CVS
 
29
 * 2004-12-22   Cleaned up cosmetics
 
30
 *              Made conversion loops in play() more cache-friendly
 
31
 * 2004-12-20   Fixed bug for stereo effect on mono signal
 
32
 *                  (trivial >1 to >=1 change; would segfault otherwise :-) )
 
33
 *              Removed trailing whitespace and fixed warn/err messages
 
34
 *              Have CONTROL_REINIT return a proper value
 
35
 * 2004-12-13   More Doxygen comments
 
36
 * 2004-12-12   Made af_ladspa optional (updated configure, af.c, etc.)
 
37
 * 2004-12-11   Added deactivate and cleanup to uninit.
 
38
 *              Finished Doxygen comments.
 
39
 *              Moved translatable messages to help_mp-en.h
 
40
 * 2004-12-10   Added ranges to list of controls for ease of use.
 
41
 *              Fixed sig11 bug. Implemented (dummy) outputcontrols. Some
 
42
 *              perfectly normal audio processing filters also have output
 
43
 *              controls.
 
44
 * 2004-12-08   Added support for generators (no input, one output)
 
45
 *              Added support for stereo effects
 
46
 *              Added LADSPA_PATH support!
 
47
 * 2004-12-07   Fixed changing buffersize. Now it's really working, also in
 
48
 *              real-time.
 
49
 * 2004-12-06   First working version, mono-effects (1 input --> 1 output) only
 
50
 * 2004-12-05   Started, Loading of plugin/label, Check inputs/outputs/controls
 
51
 *              Due to lack of documentation, I studied the ladspa_sdk source
 
52
 *              code and the loader code of Audacity (by Dominic Mazzoni). So,
 
53
 *              certain similarities in (small) pieces of code are not
 
54
 *              coincidental :-) No C&P jobs though!
 
55
 *
 
56
 */
 
57
 
 
58
/* ------------------------------------------------------------------------- */
 
59
 
 
60
/* Global Includes */
 
61
 
 
62
#include <stdio.h>
 
63
#include <stdlib.h>
 
64
#include <string.h>
 
65
 
 
66
#include <unistd.h>
 
67
#include <inttypes.h>
 
68
#include <math.h>
 
69
#include <limits.h>
 
70
 
 
71
#include <dlfcn.h>
 
72
#include <ladspa.h>
 
73
 
 
74
/* ------------------------------------------------------------------------- */
 
75
 
 
76
/* Local Includes */
 
77
 
 
78
#include "af.h"
 
79
#include "help_mp.h"
 
80
 
 
81
/* ------------------------------------------------------------------------- */
 
82
 
 
83
/* Filter specific data */
 
84
 
 
85
typedef struct af_ladspa_s
 
86
{
 
87
    int status;     /**< Status of the filter.
 
88
                     *   Either AF_OK or AF_ERROR
 
89
                     *   Because MPlayer re-inits audio filters that
 
90
                     *   _clearly_ returned AF_ERROR anyway, I use this
 
91
                     *   in play() to skip the processing and return
 
92
                     *   the data unchanged.
 
93
                     */
 
94
 
 
95
    int activated;  /**< 0 or 1. Activate LADSPA filters only once, even
 
96
                     *   if the buffers get resized, to avoid a stuttering
 
97
                     *   filter.
 
98
                     */
 
99
 
 
100
    char *file;
 
101
    char *label;
 
102
 
 
103
    char *myname;   /**< It's easy to have a concatenation of file and label */
 
104
 
 
105
    void *libhandle;
 
106
    const LADSPA_Descriptor *plugin_descriptor;
 
107
 
 
108
    int nports;
 
109
 
 
110
    int ninputs;
 
111
    int *inputs;
 
112
 
 
113
    int noutputs;
 
114
    int *outputs;
 
115
 
 
116
    int ninputcontrols;
 
117
    int *inputcontrolsmap;  /**< Map input port number [0-] to actual port */
 
118
    float *inputcontrols;
 
119
 
 
120
    int noutputcontrols;
 
121
    int *outputcontrolsmap;
 
122
    float *outputcontrols;
 
123
 
 
124
    int nch;                /**< number of channels */
 
125
    int bufsize;
 
126
    float **inbufs;
 
127
    float **outbufs;
 
128
    LADSPA_Handle *chhandles;
 
129
 
 
130
} af_ladspa_t;
 
131
 
 
132
/* ------------------------------------------------------------------------- */
 
133
 
 
134
static int open(af_instance_t *af);
 
135
static int af_ladspa_malloc_failed(char*);
 
136
 
 
137
/* ------------------------------------------------------------------------- */
 
138
 
 
139
/* Description */
 
140
 
 
141
af_info_t af_info_ladspa = {
 
142
    "LADSPA plugin loader",
 
143
    "ladspa",
 
144
    "Ivo van Poorten",
 
145
    "",
 
146
    AF_FLAGS_REENTRANT,
 
147
    open
 
148
};
 
149
 
 
150
/* ------------------------------------------------------------------------- */
 
151
 
 
152
/* By lack of a better word (in my vocabulary) this is called 'parse'.
 
153
 * Feel free to suggest an alternative.
 
154
 */
 
155
 
 
156
/** \brief Check for inputs, outputs and controls of a given filter.
 
157
 *
 
158
 * This function counts and checks all input, output and control ports
 
159
 * of the filter that was loaded. If it turns out to be a valid
 
160
 * filter for MPlayer use, it prints out a list of all controls and
 
161
 * the corresponding range of its value at message level  MSGL_V.
 
162
 *
 
163
 * \param setup     Current setup of the filter. Must have its
 
164
 *                  plugin_descriptor set!
 
165
 *
 
166
 * \return  Returns AF_OK if it has a valid input/output/controls
 
167
 *          configuration. Else, it returns AF_ERROR.
 
168
 */
 
169
 
 
170
static int af_ladspa_parse_plugin(af_ladspa_t *setup) {
 
171
    int p, i;
 
172
    const LADSPA_Descriptor *pdes = setup->plugin_descriptor;
 
173
    LADSPA_PortDescriptor d;
 
174
    LADSPA_PortRangeHint hint;
 
175
 
 
176
    if (!setup->libhandle)
 
177
        return AF_ERROR; /* only call parse after a succesful load */
 
178
    if (!setup->plugin_descriptor)
 
179
        return AF_ERROR; /* same as above */
 
180
 
 
181
    /* let's do it */
 
182
 
 
183
    setup->nports = pdes->PortCount;
 
184
 
 
185
    /* allocate memory for all inputs/outputs/controls */
 
186
 
 
187
    setup->inputs = calloc(setup->nports, sizeof(int));
 
188
    if (!setup->inputs) return af_ladspa_malloc_failed(setup->myname);
 
189
 
 
190
    setup->outputs = calloc(setup->nports, sizeof(int));
 
191
    if (!setup->outputs) return af_ladspa_malloc_failed(setup->myname);
 
192
 
 
193
    setup->inputcontrolsmap = calloc(setup->nports, sizeof(int));
 
194
    if (!setup->inputcontrolsmap) return af_ladspa_malloc_failed(setup->myname);
 
195
 
 
196
    setup->inputcontrols = calloc(setup->nports, sizeof(float));
 
197
    if (!setup->inputcontrols) return af_ladspa_malloc_failed(setup->myname);
 
198
 
 
199
    setup->outputcontrolsmap = calloc(setup->nports, sizeof(int));
 
200
    if (!setup->outputcontrolsmap) return af_ladspa_malloc_failed(setup->myname);
 
201
 
 
202
    setup->outputcontrols = calloc(setup->nports, sizeof(float));
 
203
    if (!setup->outputcontrols) return af_ladspa_malloc_failed(setup->myname);
 
204
 
 
205
    /* set counts to zero */
 
206
 
 
207
    setup->ninputs = 0;
 
208
    setup->noutputs = 0;
 
209
    setup->ninputcontrols = 0;
 
210
    setup->noutputcontrols = 0;
 
211
 
 
212
    /* check all ports, see what type it is and set variables according to
 
213
     * what we have found
 
214
     */
 
215
 
 
216
    for (p=0; p<setup->nports; p++) {
 
217
        d = pdes->PortDescriptors[p];
 
218
 
 
219
        if (LADSPA_IS_PORT_AUDIO(d)) {
 
220
            if (LADSPA_IS_PORT_INPUT(d)) {
 
221
                setup->inputs[setup->ninputs] = p;
 
222
                setup->ninputs++;
 
223
            } else if (LADSPA_IS_PORT_OUTPUT(d)) {
 
224
                setup->outputs[setup->noutputs] = p;
 
225
                setup->noutputs++;
 
226
            }
 
227
        }
 
228
 
 
229
        if (LADSPA_IS_PORT_CONTROL(d)) {
 
230
            if (LADSPA_IS_PORT_INPUT(d)) {
 
231
                setup->inputcontrolsmap[setup->ninputcontrols] = p;
 
232
                setup->ninputcontrols++;
 
233
                /* set control to zero. set values after reading the rest
 
234
                 * of the suboptions and check LADSPA_?_HINT's later.
 
235
                 */
 
236
                setup->inputcontrols[p] = 0.0f;
 
237
            } else if (LADSPA_IS_PORT_OUTPUT(d)) {
 
238
                /* read and handle these too, otherwise filters that have them
 
239
                 * will sig11
 
240
                 */
 
241
                setup->outputcontrolsmap[setup->noutputcontrols]=p;
 
242
                setup->noutputcontrols++;
 
243
                setup->outputcontrols[p] = 0.0f;
 
244
            }
 
245
        }
 
246
 
 
247
    }
 
248
 
 
249
    if (setup->ninputs == 0) {
 
250
        af_msg(AF_MSG_WARN, "%s: %s\n", setup->myname, 
 
251
                                                MSGTR_AF_LADSPA_WarnNoInputs);
 
252
    } else if (setup->ninputs == 1) {
 
253
        af_msg(AF_MSG_VERBOSE, "%s: this is a mono effect\n", setup->myname);
 
254
    } else if (setup->ninputs == 2) {
 
255
        af_msg(AF_MSG_VERBOSE, "%s: this is a stereo effect\n", setup->myname);
 
256
    }
 
257
 
 
258
    if (setup->ninputs > 2) {
 
259
        af_msg(AF_MSG_ERROR, "%s: %s\n", setup->myname,
 
260
                                            MSGTR_AF_LADSPA_ErrMultiChannel);
 
261
        return AF_ERROR;
 
262
    }
 
263
 
 
264
    if (setup->noutputs == 0) {
 
265
        af_msg(AF_MSG_ERROR, "%s: %s\n", setup->myname,
 
266
                                                MSGTR_AF_LADSPA_ErrNoOutputs);
 
267
        return AF_ERROR;
 
268
    }
 
269
 
 
270
    if (setup->noutputs != setup->ninputs ) {
 
271
        af_msg(AF_MSG_ERROR, "%s: %s\n", setup->myname,
 
272
                                                MSGTR_AF_LADSPA_ErrInOutDiff);
 
273
        return AF_ERROR;
 
274
    }
 
275
 
 
276
    af_msg(AF_MSG_VERBOSE, "%s: this plugin has %d input control(s)\n",
 
277
                                        setup->myname, setup->ninputcontrols);
 
278
 
 
279
    /* Print list of controls and its range of values it accepts */
 
280
 
 
281
    for (i=0; i<setup->ninputcontrols; i++) {
 
282
        p = setup->inputcontrolsmap[i];
 
283
        hint = pdes->PortRangeHints[p];
 
284
        af_msg(AF_MSG_VERBOSE, "  --- %d %s [", i, pdes->PortNames[p]);
 
285
 
 
286
        if (LADSPA_IS_HINT_BOUNDED_BELOW(hint.HintDescriptor)) {
 
287
            af_msg(AF_MSG_VERBOSE, "%0.2f , ", hint.LowerBound);
 
288
        } else {
 
289
            af_msg(AF_MSG_VERBOSE, "... , ");
 
290
        }
 
291
 
 
292
        if (LADSPA_IS_HINT_BOUNDED_ABOVE(hint.HintDescriptor)) {
 
293
            af_msg(AF_MSG_VERBOSE, "%0.2f]\n", hint.UpperBound);
 
294
        } else {
 
295
            af_msg(AF_MSG_VERBOSE, "...]\n");
 
296
        }
 
297
 
 
298
    }
 
299
 
 
300
    return AF_OK;
 
301
}
 
302
 
 
303
/* ------------------------------------------------------------------------- */
 
304
 
 
305
/* This function might "slightly" look like dlopenLADSPA in the LADSPA SDK :-)
 
306
 * But, I changed a few things, because imho it was broken. It did not support
 
307
 * relative paths, only absolute paths that start with a /
 
308
 * I think ../../some/dir/foobar.so is just as valid. And if one wants to call
 
309
 * his library '...somename...so' he's crazy, but it should be allowed.
 
310
 * So, search the path first, try plain *filename later.
 
311
 * Also, try adding .so first! I like the recursion the SDK did, but it's
 
312
 * better the other way around. -af ladspa=cmt:amp_stereo:0.5 is easier to type
 
313
 * than -af ladspa=cmt.so:amp_stereo:0.5 :-))
 
314
 */
 
315
 
 
316
/** \brief dlopen() wrapper
 
317
 *
 
318
 * This is a wrapper around dlopen(). It tries various variations of the
 
319
 * filename (with or without the addition of the .so extension) in various
 
320
 * directories specified by the LADSPA_PATH environment variable. If all fails
 
321
 * it tries the filename directly as an absolute path to the library.
 
322
 * 
 
323
 * \param filename  filename of the library to load.
 
324
 * \param flag      see dlopen(3) for a description of the flags.
 
325
 *
 
326
 * \return          returns a pointer to the loaded library on success, or
 
327
 *                  NULL if it fails to load.
 
328
 */
 
329
 
 
330
static void* mydlopen(const char *filename, int flag) {
 
331
    char *buf;
 
332
    const char *end, *start, *ladspapath;
 
333
    int endsinso, needslash;
 
334
    size_t filenamelen;
 
335
    void *result = NULL;
 
336
 
 
337
#   ifdef WIN32         /* for windows there's only absolute path support.
 
338
                         * if you have a windows machine, feel free to fix
 
339
                         * this. (path separator, shared objects extension,
 
340
                         * et cetera).
 
341
                         */
 
342
        af_msg(AF_MSG_VERBOSE, "\ton windows, only absolute pathnames "
 
343
                "are supported\n");
 
344
        af_msg(AF_MSG_VERBOSE, "\ttrying %s\n", filename);
 
345
        return dlopen(filename, flag);
 
346
#   endif
 
347
 
 
348
    filenamelen = strlen(filename);
 
349
 
 
350
    endsinso = 0;
 
351
    if (filenamelen > 3)
 
352
        endsinso = (strcmp(filename+filenamelen-3, ".so") == 0);
 
353
    if (!endsinso) {
 
354
        buf=malloc(filenamelen+4);
 
355
        strcpy(buf, filename);
 
356
        strcat(buf, ".so");
 
357
        result=mydlopen(buf, flag);
 
358
        free(buf);
 
359
    }
 
360
 
 
361
    if (result)
 
362
        return result;
 
363
 
 
364
    ladspapath=getenv("LADSPA_PATH");
 
365
 
 
366
    if (ladspapath) {
 
367
 
 
368
        start=ladspapath;
 
369
        while (*start != '\0') {
 
370
            end=start;
 
371
            while ( (*end != ':') && (*end != '\0') )
 
372
                end++;
 
373
 
 
374
            buf=malloc(filenamelen + 2 + (end-start) );
 
375
            if (end > start)
 
376
                strncpy(buf, start, end-start);
 
377
            needslash=0;
 
378
            if (end > start)
 
379
                if (*(end-1) != '/') {
 
380
                    needslash = 1;
 
381
                    buf[end-start] = '/';
 
382
                }
 
383
            strcpy(buf+needslash+(end-start), filename);
 
384
 
 
385
            af_msg(AF_MSG_VERBOSE, "\ttrying %s\n", buf);
 
386
            result=dlopen(buf, flag);
 
387
 
 
388
            free(buf);
 
389
            if (result)
 
390
                return result;
 
391
 
 
392
            start = end;
 
393
            if (*start == ':')
 
394
                start++;
 
395
        } /* end while there's still more in the path */
 
396
    } /* end if there's a ladspapath */
 
397
 
 
398
    /* last resort, just open it again, so the dlerror() message is correct */
 
399
    af_msg(AF_MSG_VERBOSE, "\ttrying %s\n", filename);
 
400
    return dlopen(filename,flag);
 
401
}
 
402
 
 
403
/* ------------------------------------------------------------------------- */
 
404
 
 
405
/** \brief Load a LADSPA Plugin
 
406
 *
 
407
 * This function loads the LADSPA plugin specified by the file and label
 
408
 * that are present in the setup variable. First, it loads the library.
 
409
 * If it fails, it returns AF_ERROR. If not, it continues to look for the
 
410
 * specified label. If it finds it, it sets the plugin_descriptor inside
 
411
 * setup and returns AF_OK. If it doesn't, it returns AF_ERROR. Special case
 
412
 * is a label called 'help'. In that case, it prints a list of all available
 
413
 * labels (filters) in the library specified by file.
 
414
 *
 
415
 * \param setup     Current setup of the filter. Contains filename and label.
 
416
 *
 
417
 * \return  Either AF_ERROR or AF_OK, depending on the success of the operation.
 
418
 */
 
419
 
 
420
static int af_ladspa_load_plugin(af_ladspa_t *setup) {
 
421
    const LADSPA_Descriptor *ladspa_descriptor;
 
422
    LADSPA_Descriptor_Function descriptor_function;
 
423
    int i;
 
424
 
 
425
    /* load library */
 
426
    af_msg(AF_MSG_VERBOSE, "%s: loading ladspa plugin library %s\n",
 
427
                                                setup->myname, setup->file);
 
428
 
 
429
    setup->libhandle = mydlopen(setup->file, RTLD_NOW);
 
430
 
 
431
    if (!setup->libhandle) {
 
432
        af_msg(AF_MSG_ERROR, "%s: %s %s\n\t%s\n", setup->myname,
 
433
                    MSGTR_AF_LADSPA_ErrFailedToLoad, setup->file, dlerror() );
 
434
        return AF_ERROR;
 
435
    }
 
436
 
 
437
    af_msg(AF_MSG_VERBOSE, "%s: library found.\n", setup->myname);
 
438
 
 
439
    /* find descriptor function */
 
440
    dlerror();
 
441
    descriptor_function = (LADSPA_Descriptor_Function) dlsym (setup->libhandle,
 
442
                                                        "ladspa_descriptor");
 
443
 
 
444
    if (!descriptor_function) {
 
445
        af_msg(AF_MSG_ERROR, "%s: %s\n\t%s\n", setup->myname,
 
446
                                MSGTR_AF_LADSPA_ErrNoDescriptor, dlerror());
 
447
        return AF_ERROR;
 
448
    }
 
449
 
 
450
    /* if label == help, list all labels in library and exit */
 
451
 
 
452
    if (strcmp(setup->label, "help") == 0) {
 
453
        af_msg(AF_MSG_INFO, "%s: %s %s:\n", setup->myname, 
 
454
                MSGTR_AF_LADSPA_AvailableLabels, setup->file);
 
455
        for (i=0; ; i++) {
 
456
            ladspa_descriptor = descriptor_function(i);
 
457
            if (ladspa_descriptor == NULL) {
 
458
                return AF_ERROR;
 
459
            }
 
460
            af_msg(AF_MSG_INFO, "  %-16s - %s (%lu)\n",
 
461
                    ladspa_descriptor->Label,
 
462
                    ladspa_descriptor->Name,
 
463
                    ladspa_descriptor->UniqueID);
 
464
        }
 
465
    }
 
466
 
 
467
    af_msg(AF_MSG_VERBOSE, "%s: looking for label\n", setup->myname);
 
468
 
 
469
    /* find label in library */
 
470
    for (i=0; ; i++) {
 
471
        ladspa_descriptor = descriptor_function(i);
 
472
        if (ladspa_descriptor == NULL) {
 
473
            af_msg(AF_MSG_ERROR, "%s: %s\n", setup->myname,
 
474
                                            MSGTR_AF_LADSPA_ErrLabelNotFound);
 
475
            return AF_ERROR;
 
476
        }
 
477
        if (strcmp(ladspa_descriptor->Label, setup->label) == 0) {
 
478
            setup->plugin_descriptor = ladspa_descriptor;
 
479
            af_msg(AF_MSG_VERBOSE, "%s: %s found\n", setup->myname,
 
480
                                                                setup->label);
 
481
            return AF_OK;
 
482
        }
 
483
    }
 
484
 
 
485
    return AF_OK;
 
486
}
 
487
 
 
488
/* ------------------------------------------------------------------------- */
 
489
 
 
490
/** \brief Print a malloc() failed error message.
 
491
 *
 
492
 * Generic function which can be called if a call to malloc(), calloc(),
 
493
 * strdup(), et cetera, failed. It prints a message to the console and
 
494
 * returns AF_ERROR.
 
495
 *
 
496
 * \return  AF_ERROR
 
497
 */
 
498
 
 
499
static int af_ladspa_malloc_failed(char *myname) {
 
500
    af_msg(AF_MSG_ERROR, "%s: %s", myname, MSGTR_MemAllocFailed);
 
501
    return AF_ERROR;
 
502
}
 
503
 
 
504
/* ------------------------------------------------------------------------- */
 
505
 
 
506
/** \brief Controls the filter.
 
507
 *
 
508
 * Control the behaviour of the filter.
 
509
 *
 
510
 * Commands:
 
511
 * CONTROL_REINIT   Sets the af structure with proper values for number
 
512
 *                  of channels, rate, format, et cetera.
 
513
 * CONTROL_COMMAND_LINE     Parses the suboptions given to this filter
 
514
 *                          through arg. It first parses the filename and
 
515
 *                          the label. After that, it loads the filter
 
516
 *                          and finds out its proprties. Then in continues
 
517
 *                          parsing the controls given on the commandline,
 
518
 *                          if any are needed.
 
519
 *
 
520
 * \param af    Audio filter instance
 
521
 * \param cmd   The command to execute
 
522
 * \param arg   Arguments to the command
 
523
 *
 
524
 * \return      Either AF_ERROR or AF_OK, depending on the succes of the
 
525
 *              operation.
 
526
 */
 
527
 
 
528
static int control(struct af_instance_s *af, int cmd, void *arg) {
 
529
    af_ladspa_t *setup = (af_ladspa_t*) af->setup;
 
530
    int i, r;
 
531
    float val;
 
532
 
 
533
    switch(cmd) {
 
534
    case AF_CONTROL_REINIT:
 
535
        af_msg(AF_MSG_VERBOSE, "%s: (re)init\n", setup->myname);
 
536
 
 
537
        if (!arg) return AF_ERROR;
 
538
 
 
539
        /* accept FLOAT, let af_format do conversion */
 
540
 
 
541
        af->data->rate   = ((af_data_t*)arg)->rate;
 
542
        af->data->nch    = ((af_data_t*)arg)->nch;
 
543
        af->data->format = AF_FORMAT_FLOAT_NE;
 
544
        af->data->bps    = 4;
 
545
 
 
546
        /* arg->len is not set here yet, so init of buffers and connecting the
 
547
         * filter, has to be done in play() :-/
 
548
         */
 
549
 
 
550
        return af_test_output(af, (af_data_t*)arg);
 
551
    case AF_CONTROL_COMMAND_LINE: {
 
552
        char *buf;
 
553
 
 
554
        af_msg(AF_MSG_VERBOSE, "%s: parse suboptions\n", setup->myname);
 
555
 
 
556
        /* suboption parser here!
 
557
         * format is (ladspa=)file:label:controls....
 
558
         */
 
559
 
 
560
        if (!arg) {
 
561
            af_msg(AF_MSG_ERROR, "%s: %s\n", setup->myname,
 
562
                                            MSGTR_AF_LADSPA_ErrNoSuboptions);
 
563
            return AF_ERROR;
 
564
        }
 
565
 
 
566
        buf = malloc(strlen(arg)+1);
 
567
        if (!buf) return af_ladspa_malloc_failed(setup->myname);
 
568
 
 
569
        /* file... */
 
570
        buf[0] = '\0';
 
571
        sscanf(arg, "%[^:]", buf);
 
572
        if (buf[0] == '\0') {
 
573
            af_msg(AF_MSG_ERROR, "%s: %s\n", setup->myname,
 
574
                                                MSGTR_AF_LADSPA_ErrNoLibFile);
 
575
            free(buf);
 
576
            return AF_ERROR;
 
577
        }
 
578
        arg += strlen(buf);
 
579
        setup->file = strdup(buf);
 
580
        if (!setup->file) return af_ladspa_malloc_failed(setup->myname);
 
581
        af_msg(AF_MSG_VERBOSE, "%s: file --> %s\n", setup->myname,
 
582
                                                        setup->file);
 
583
        if (*(char*)arg != '\0') arg++; /* read ':' */
 
584
 
 
585
        /* label... */
 
586
        buf[0] = '\0';
 
587
        sscanf(arg, "%[^:]", buf);
 
588
        if (buf[0] == '\0') {
 
589
            af_msg(AF_MSG_ERROR, "%s: %s\n", setup->myname,
 
590
                                                MSGTR_AF_LADSPA_ErrNoLabel);
 
591
            free(buf);
 
592
            return AF_ERROR;
 
593
        }
 
594
        arg += strlen(buf);
 
595
        setup->label = strdup(buf);
 
596
        if (!setup->label) return af_ladspa_malloc_failed(setup->myname);
 
597
        af_msg(AF_MSG_VERBOSE, "%s: label --> %s\n", setup->myname,
 
598
                                                                setup->label);
 
599
/*        if (*(char*)arg != '0') arg++; */ /* read ':' */
 
600
 
 
601
        free(buf); /* no longer needed */
 
602
 
 
603
        /* set new setup->myname */
 
604
 
 
605
        if(setup->myname) free(setup->myname);
 
606
        setup->myname = calloc(strlen(af_info_ladspa.name)+strlen(setup->file)+
 
607
                                                    strlen(setup->label)+6, 1);
 
608
        snprintf(setup->myname, strlen(af_info_ladspa.name)+
 
609
                strlen(setup->file)+strlen(setup->label)+6, "%s: (%s:%s)",
 
610
                            af_info_ladspa.name, setup->file, setup->label);
 
611
 
 
612
        /* load plugin :) */
 
613
 
 
614
        if ( af_ladspa_load_plugin(setup) != AF_OK )
 
615
            return AF_ERROR;
 
616
 
 
617
        /* see what inputs, outputs and controls this plugin has */
 
618
        if ( af_ladspa_parse_plugin(setup) != AF_OK )
 
619
            return AF_ERROR;
 
620
 
 
621
        /* ninputcontrols is set by now, read control values from arg */
 
622
 
 
623
        for(i=0; i<setup->ninputcontrols; i++) {
 
624
            if (!arg || (*(char*)arg != ':') ) {
 
625
                af_msg(AF_MSG_ERROR, "%s: %s\n", setup->myname,
 
626
                                        MSGTR_AF_LADSPA_ErrNotEnoughControls);
 
627
                return AF_ERROR;
 
628
            }
 
629
            arg++;
 
630
            r = sscanf(arg, "%f", &val);
 
631
            if (r!=1) {
 
632
                af_msg(AF_MSG_ERROR, "%s: %s\n", setup->myname,
 
633
                                        MSGTR_AF_LADSPA_ErrNotEnoughControls);
 
634
                return AF_ERROR;
 
635
            }
 
636
            setup->inputcontrols[setup->inputcontrolsmap[i]] = val;
 
637
            arg = strchr(arg, ':');
 
638
        }
 
639
 
 
640
        af_msg(AF_MSG_VERBOSE, "%s: input controls: ", setup->myname);
 
641
        for(i=0; i<setup->ninputcontrols; i++) {
 
642
            af_msg(AF_MSG_VERBOSE, "%0.4f ",
 
643
                            setup->inputcontrols[setup->inputcontrolsmap[i]]);
 
644
        }
 
645
        af_msg(AF_MSG_VERBOSE, "\n");
 
646
 
 
647
        /* check boundaries of inputcontrols */
 
648
 
 
649
        af_msg(AF_MSG_VERBOSE, "%s: checking boundaries of input controls\n",
 
650
                                                                setup->myname);
 
651
        for(i=0; i<setup->ninputcontrols; i++) {
 
652
            int p = setup->inputcontrolsmap[i];
 
653
            LADSPA_PortRangeHint hint =
 
654
                                setup->plugin_descriptor->PortRangeHints[p];
 
655
            val = setup->inputcontrols[p];
 
656
 
 
657
            if (LADSPA_IS_HINT_BOUNDED_BELOW(hint.HintDescriptor) &&
 
658
                    val < hint.LowerBound) {
 
659
                af_msg(AF_MSG_ERROR, MSGTR_AF_LADSPA_ErrControlBelow,
 
660
                                            setup->myname, i, hint.LowerBound);
 
661
                return AF_ERROR;
 
662
            }
 
663
            if (LADSPA_IS_HINT_BOUNDED_ABOVE(hint.HintDescriptor) &&
 
664
                    val > hint.UpperBound) {
 
665
                af_msg(AF_MSG_ERROR, MSGTR_AF_LADSPA_ErrControlAbove,
 
666
                                            setup->myname, i, hint.UpperBound);
 
667
                return AF_ERROR;
 
668
            }
 
669
        }
 
670
        af_msg(AF_MSG_VERBOSE, "%s: all controls have sane values\n",
 
671
                                                                setup->myname);
 
672
 
 
673
        /* All is well! */
 
674
        setup->status = AF_OK;
 
675
 
 
676
        return AF_OK; }
 
677
    }
 
678
 
 
679
    return AF_UNKNOWN;
 
680
}
 
681
 
 
682
/* ------------------------------------------------------------------------- */
 
683
 
 
684
/** \brief Uninitialise the LADSPA Plugin Loader filter.
 
685
 *
 
686
 * This function deactivates the plugin(s), cleans up, frees all allocated
 
687
 * memory and exits.
 
688
 *
 
689
 * \return  No return value.
 
690
 */
 
691
 
 
692
static void uninit(struct af_instance_s *af) {
 
693
    int i;
 
694
 
 
695
    if (af->data)
 
696
        free(af->data);
 
697
    if (af->setup) {
 
698
        af_ladspa_t *setup = (af_ladspa_t*) af->setup;
 
699
        const LADSPA_Descriptor *pdes = setup->plugin_descriptor;
 
700
 
 
701
        if (setup->myname) {
 
702
            af_msg(AF_MSG_VERBOSE, "%s: cleaning up\n", setup->myname);
 
703
            free(setup->myname);
 
704
        }
 
705
 
 
706
        if (setup->chhandles) {
 
707
            for(i=0; i<setup->nch; i++) {
 
708
                if ( (setup->ninputs == 2) && (i & 1) ) { /* stereo effect */
 
709
                    i++;
 
710
                    continue;
 
711
                }
 
712
                if (pdes->deactivate) pdes->deactivate(setup->chhandles[i]);
 
713
                if (pdes->cleanup) pdes->cleanup(setup->chhandles[i]);
 
714
            }
 
715
            free(setup->chhandles);
 
716
        }
 
717
 
 
718
        if (setup->file)
 
719
            free(setup->file);
 
720
        if (setup->label)
 
721
            free(setup->label);
 
722
        if (setup->inputcontrolsmap)
 
723
            free(setup->inputcontrolsmap);
 
724
        if (setup->inputcontrols)
 
725
            free(setup->inputcontrols);
 
726
        if (setup->outputcontrolsmap)
 
727
            free(setup->outputcontrolsmap);
 
728
        if (setup->outputcontrols)
 
729
            free(setup->outputcontrols);
 
730
        if (setup->inputs)
 
731
            free(setup->inputs);
 
732
        if (setup->outputs)
 
733
            free(setup->outputs);
 
734
 
 
735
        if (setup->inbufs) {
 
736
            for(i=0; i<setup->nch; i++) {
 
737
                if (setup->inbufs[i])
 
738
                    free(setup->inbufs[i]);
 
739
            }
 
740
            free(setup->inbufs);
 
741
        }
 
742
 
 
743
        if (setup->outbufs) {
 
744
            for(i=0; i<setup->nch; i++) {
 
745
                if (setup->outbufs[i])
 
746
                    free(setup->outbufs[i]);
 
747
            }
 
748
            free(setup->outbufs);
 
749
        }
 
750
 
 
751
        if (setup->libhandle)
 
752
            dlclose(setup->libhandle);
 
753
 
 
754
        free(setup);
 
755
        setup = NULL;
 
756
    }
 
757
}
 
758
 
 
759
/* ------------------------------------------------------------------------- */
 
760
 
 
761
/** \brief Process chunk of audio data through the selected LADSPA Plugin.
 
762
 * 
 
763
 * \param af    Pointer to audio filter instance
 
764
 * \param data  Pointer to chunk of audio data
 
765
 *
 
766
 * \return      Either AF_ERROR or AF_OK
 
767
 */
 
768
 
 
769
static af_data_t* play(struct af_instance_s *af, af_data_t *data) {
 
770
    af_ladspa_t *setup = af->setup;
 
771
    const LADSPA_Descriptor *pdes = setup->plugin_descriptor;
 
772
    float *audio = (float*)data->audio;
 
773
    int nsamples = data->len/4; /* /4 because it's 32-bit float */
 
774
    int nch = data->nch;
 
775
    int rate = data->rate;
 
776
    int i, p; 
 
777
 
 
778
    if (setup->status !=AF_OK)
 
779
        return data;
 
780
 
 
781
    /* See if it's the first call. If so, setup inbufs/outbufs, instantiate
 
782
     * plugin, connect ports and activate plugin
 
783
     */
 
784
 
 
785
    /* 2004-12-07: Also check if the buffersize has to be changed!
 
786
     *             data->len is not constant per se! re-init buffers.
 
787
     */
 
788
 
 
789
    if ( (setup->bufsize != nsamples/nch) || (setup->nch != nch) ) {
 
790
 
 
791
        /* if setup->nch==0, it's the first call, if not, something has
 
792
         * changed and all previous mallocs have to be freed
 
793
         */
 
794
 
 
795
        if (setup->nch != 0) {
 
796
            af_msg(AF_MSG_DEBUG1, "%s: bufsize change; free old buffer\n",
 
797
                                                                setup->myname);
 
798
 
 
799
            if(setup->inbufs) {
 
800
                for(i=0; i<setup->nch; i++) {
 
801
                    if(setup->inbufs[i])
 
802
                        free(setup->inbufs[i]);
 
803
                }
 
804
                free(setup->inbufs);
 
805
            }
 
806
            if(setup->outbufs) {
 
807
                for(i=0; i<setup->nch; i++) {
 
808
                    if(setup->outbufs[i])
 
809
                        free(setup->outbufs[i]);
 
810
                }
 
811
                free(setup->outbufs);
 
812
            }
 
813
        } /* everything is freed */
 
814
 
 
815
        setup->bufsize = nsamples/nch;
 
816
        setup->nch = nch;
 
817
 
 
818
        setup->inbufs = calloc(nch, sizeof(float*));
 
819
        setup->outbufs = calloc(nch, sizeof(float*));
 
820
 
 
821
        af_msg(AF_MSG_DEBUG1, "%s: bufsize = %d\n",
 
822
                                        setup->myname, setup->bufsize);
 
823
 
 
824
        for(i=0; i<nch; i++) {
 
825
            setup->inbufs[i] = calloc(setup->bufsize, sizeof(float));
 
826
            setup->outbufs[i] = calloc(setup->bufsize, sizeof(float));
 
827
        }
 
828
 
 
829
        /* only on the first call, there are no handles. */
 
830
 
 
831
        if (!setup->chhandles) {
 
832
            setup->chhandles = calloc(nch, sizeof(LADSPA_Handle));
 
833
 
 
834
            /* create handles
 
835
             * for stereo effects, create one handle for two channels
 
836
             */
 
837
 
 
838
            for(i=0; i<nch; i++) {
 
839
 
 
840
                if ( (setup->ninputs == 2) && (i & 1) ) { /* stereo effect */
 
841
                    /* copy the handle from previous channel */
 
842
                    setup->chhandles[i] = setup->chhandles[i-1];
 
843
                    continue;
 
844
                }
 
845
 
 
846
                setup->chhandles[i] = pdes->instantiate(pdes, rate);
 
847
            }
 
848
        }
 
849
 
 
850
        /* connect input/output ports for each channel/filter instance
 
851
         *
 
852
         * always (re)connect ports
 
853
         */
 
854
 
 
855
        for(i=0; i<nch; i++) {
 
856
            pdes->connect_port(setup->chhandles[i],
 
857
                               setup->inputs[ (setup->ninputs==2) ? i&1 : 0 ],
 
858
                               setup->inbufs[i]);
 
859
            pdes->connect_port(setup->chhandles[i],
 
860
                               setup->outputs[ (setup->ninputs==2) ? i&1 : 0 ],
 
861
                               setup->outbufs[i]);
 
862
 
 
863
            /* connect (input) controls */
 
864
 
 
865
            for (p=0; p<setup->nports; p++) {
 
866
                LADSPA_PortDescriptor d = pdes->PortDescriptors[p];
 
867
                if (LADSPA_IS_PORT_CONTROL(d)) {
 
868
                    if (LADSPA_IS_PORT_INPUT(d)) {
 
869
                        pdes->connect_port(setup->chhandles[i], p,
 
870
                                                &(setup->inputcontrols[p]) );
 
871
                    } else {
 
872
                        pdes->connect_port(setup->chhandles[i], p,
 
873
                                                &(setup->outputcontrols[p]) );
 
874
                    }
 
875
                }
 
876
            }
 
877
 
 
878
            /* Activate filter (if it isn't already :) ) */
 
879
 
 
880
            if ( (pdes->activate) && (setup->activated == 0) ) {
 
881
                pdes->activate(setup->chhandles[i]);
 
882
                setup->activated = 1;
 
883
            }
 
884
 
 
885
        } /* All channels/filters done! except for... */
 
886
 
 
887
        /* Stereo effect with one channel left. Use same buffer for left
 
888
         * and right. connect it to the second port.
 
889
         */
 
890
 
 
891
        if( (setup->ninputs == 2) && (i&1) && (i >= 1) ) { 
 
892
            pdes->connect_port(setup->chhandles[i-1],
 
893
                               setup->inputs[ (setup->ninputs==2) ? i&1 : 0 ],
 
894
                               setup->inbufs[i-1]);
 
895
            pdes->connect_port(setup->chhandles[i-1],
 
896
                               setup->outputs[ (setup->ninputs==2) ? i&1 : 0 ],
 
897
                               setup->outbufs[i-1]);
 
898
        } /* done! */
 
899
 
 
900
    } /* setup for first call/change of bufsize is done.
 
901
       * normal playing routine follows...
 
902
       */
 
903
 
 
904
    /* Right now, I use a separate input and output buffer.
 
905
     * I could change this to in-place processing (inbuf==outbuf), but some
 
906
     * ladspa filters are broken and are not able to handle that. This seems
 
907
     * fast enough, so unless somebody complains, it stays this way :)
 
908
     */
 
909
 
 
910
    /* Fill inbufs */
 
911
 
 
912
    for (p=0; p<setup->bufsize; p++) {
 
913
        for (i=0; i<nch; i++) {
 
914
            setup->inbufs[i][p] = audio[p*nch + i];
 
915
        }
 
916
    }
 
917
 
 
918
    /* Run filter(s) */
 
919
 
 
920
    for (i=0; i<nch; i++) {
 
921
        pdes->run(setup->chhandles[i], setup->bufsize);
 
922
        if (setup->ninputs==2) // stereo effect just ran
 
923
            i++;
 
924
    }
 
925
 
 
926
    /* Extract outbufs */
 
927
 
 
928
    for (p=0; p<setup->bufsize; p++) {
 
929
        for (i=0; i<nch; i++) {
 
930
            audio[p*nch + i] = setup->outbufs[i][p];
 
931
        }
 
932
    }
 
933
 
 
934
    /* done */
 
935
 
 
936
    return data;
 
937
}
 
938
 
 
939
/* ------------------------------------------------------------------------- */
 
940
 
 
941
/** \brief Open LADSPA Plugin Loader Filter
 
942
 *
 
943
 * \param af    Audio Filter instance
 
944
 *
 
945
 * \return      Either AF_ERROR or AF_OK
 
946
 */
 
947
 
 
948
static int open(af_instance_t *af) {
 
949
 
 
950
    af->control=control;
 
951
    af->uninit=uninit;
 
952
    af->play=play;
 
953
    af->mul.n=1;
 
954
    af->mul.d=1;
 
955
 
 
956
    af->data = calloc(1, sizeof(af_data_t));
 
957
    if (af->data == NULL)
 
958
        return af_ladspa_malloc_failed((char*)af_info_ladspa.name);
 
959
 
 
960
    af->setup = calloc(1, sizeof(af_ladspa_t));
 
961
    if (af->setup == NULL) {
 
962
        free(af->data);
 
963
        af->data=NULL;
 
964
        return af_ladspa_malloc_failed((char*)af_info_ladspa.name);
 
965
    }
 
966
 
 
967
    ((af_ladspa_t*)af->setup)->status = AF_ERROR; /* will be set to AF_OK if
 
968
                                                   * all went OK and play()
 
969
                                                   * should proceed.
 
970
                                                   */
 
971
 
 
972
    ((af_ladspa_t*)af->setup)->myname = strdup(af_info_ladspa.name);
 
973
    if (!((af_ladspa_t*)af->setup)->myname)
 
974
        return af_ladspa_malloc_failed((char*)af_info_ladspa.name);
 
975
 
 
976
    return AF_OK;
 
977
}
 
978
 
 
979
/* ------------------------------------------------------------------------- */