1 /* ------------------------------------------------------------------------- */
4 * af_ladspa.c, LADSPA plugin loader
6 * Written by Ivo van Poorten <ivop@euronet.nl>
7 * Copyright (C) 2004, 2005
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License
11 * as published by the Free Software Foundation; either version 2
12 * of the License, or (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
25 /* ------------------------------------------------------------------------- */
40 /* ------------------------------------------------------------------------- */
47 /* ------------------------------------------------------------------------- */
49 /* Filter specific data */
51 typedef struct af_ladspa_s
53 int status
; /**< Status of the filter.
54 * Either AF_OK or AF_ERROR
55 * Because MPlayer re-inits audio filters that
56 * _clearly_ returned AF_ERROR anyway, I use this
57 * in play() to skip the processing and return
61 int activated
; /**< 0 or 1. Activate LADSPA filters only once, even
62 * if the buffers get resized, to avoid a stuttering
69 char *myname
; /**< It's easy to have a concatenation of file and label */
72 const LADSPA_Descriptor
*plugin_descriptor
;
83 int *inputcontrolsmap
; /**< Map input port number [0-] to actual port */
87 int *outputcontrolsmap
;
88 float *outputcontrols
;
90 int nch
; /**< number of channels */
94 LADSPA_Handle
*chhandles
;
98 /* ------------------------------------------------------------------------- */
100 static int af_open(af_instance_t
*af
);
101 static int af_ladspa_malloc_failed(char*);
103 /* ------------------------------------------------------------------------- */
107 af_info_t af_info_ladspa
= {
108 "LADSPA plugin loader",
116 /* ------------------------------------------------------------------------- */
118 /* By lack of a better word (in my vocabulary) this is called 'parse'.
119 * Feel free to suggest an alternative.
122 /** \brief Check for inputs, outputs and controls of a given filter.
124 * This function counts and checks all input, output and control ports
125 * of the filter that was loaded. If it turns out to be a valid
126 * filter for MPlayer use, it prints out a list of all controls and
127 * the corresponding range of its value at message level MSGL_V.
129 * \param setup Current setup of the filter. Must have its
130 * plugin_descriptor set!
132 * \return Returns AF_OK if it has a valid input/output/controls
133 * configuration. Else, it returns AF_ERROR.
136 static int af_ladspa_parse_plugin(af_ladspa_t
*setup
) {
138 const LADSPA_Descriptor
*pdes
= setup
->plugin_descriptor
;
139 LADSPA_PortDescriptor d
;
140 LADSPA_PortRangeHint hint
;
142 if (!setup
->libhandle
)
143 return AF_ERROR
; /* only call parse after a succesful load */
144 if (!setup
->plugin_descriptor
)
145 return AF_ERROR
; /* same as above */
149 setup
->nports
= pdes
->PortCount
;
151 /* allocate memory for all inputs/outputs/controls */
153 setup
->inputs
= calloc(setup
->nports
, sizeof(int));
154 if (!setup
->inputs
) return af_ladspa_malloc_failed(setup
->myname
);
156 setup
->outputs
= calloc(setup
->nports
, sizeof(int));
157 if (!setup
->outputs
) return af_ladspa_malloc_failed(setup
->myname
);
159 setup
->inputcontrolsmap
= calloc(setup
->nports
, sizeof(int));
160 if (!setup
->inputcontrolsmap
) return af_ladspa_malloc_failed(setup
->myname
);
162 setup
->inputcontrols
= calloc(setup
->nports
, sizeof(float));
163 if (!setup
->inputcontrols
) return af_ladspa_malloc_failed(setup
->myname
);
165 setup
->outputcontrolsmap
= calloc(setup
->nports
, sizeof(int));
166 if (!setup
->outputcontrolsmap
) return af_ladspa_malloc_failed(setup
->myname
);
168 setup
->outputcontrols
= calloc(setup
->nports
, sizeof(float));
169 if (!setup
->outputcontrols
) return af_ladspa_malloc_failed(setup
->myname
);
171 /* set counts to zero */
175 setup
->ninputcontrols
= 0;
176 setup
->noutputcontrols
= 0;
178 /* check all ports, see what type it is and set variables according to
182 for (p
=0; p
<setup
->nports
; p
++) {
183 d
= pdes
->PortDescriptors
[p
];
185 if (LADSPA_IS_PORT_AUDIO(d
)) {
186 if (LADSPA_IS_PORT_INPUT(d
)) {
187 setup
->inputs
[setup
->ninputs
] = p
;
189 } else if (LADSPA_IS_PORT_OUTPUT(d
)) {
190 setup
->outputs
[setup
->noutputs
] = p
;
195 if (LADSPA_IS_PORT_CONTROL(d
)) {
196 if (LADSPA_IS_PORT_INPUT(d
)) {
197 setup
->inputcontrolsmap
[setup
->ninputcontrols
] = p
;
198 setup
->ninputcontrols
++;
199 /* set control to zero. set values after reading the rest
200 * of the suboptions and check LADSPA_?_HINT's later.
202 setup
->inputcontrols
[p
] = 0.0f
;
203 } else if (LADSPA_IS_PORT_OUTPUT(d
)) {
204 /* read and handle these too, otherwise filters that have them
207 setup
->outputcontrolsmap
[setup
->noutputcontrols
]=p
;
208 setup
->noutputcontrols
++;
209 setup
->outputcontrols
[p
] = 0.0f
;
215 if (setup
->ninputs
== 0) {
216 af_msg(AF_MSG_WARN
, "%s: %s\n", setup
->myname
,
217 MSGTR_AF_LADSPA_WarnNoInputs
);
218 } else if (setup
->ninputs
== 1) {
219 af_msg(AF_MSG_VERBOSE
, "%s: this is a mono effect\n", setup
->myname
);
220 } else if (setup
->ninputs
== 2) {
221 af_msg(AF_MSG_VERBOSE
, "%s: this is a stereo effect\n", setup
->myname
);
223 af_msg(AF_MSG_VERBOSE
, "%s: this is a %i-channel effect, "
224 "support is experimental\n", setup
->myname
, setup
->ninputs
);
227 if (setup
->noutputs
== 0) {
228 af_msg(AF_MSG_ERROR
, "%s: %s\n", setup
->myname
,
229 MSGTR_AF_LADSPA_ErrNoOutputs
);
233 if (setup
->noutputs
!= setup
->ninputs
) {
234 af_msg(AF_MSG_ERROR
, "%s: %s\n", setup
->myname
,
235 MSGTR_AF_LADSPA_ErrInOutDiff
);
239 af_msg(AF_MSG_VERBOSE
, "%s: this plugin has %d input control(s)\n",
240 setup
->myname
, setup
->ninputcontrols
);
242 /* Print list of controls and its range of values it accepts */
244 for (i
=0; i
<setup
->ninputcontrols
; i
++) {
245 p
= setup
->inputcontrolsmap
[i
];
246 hint
= pdes
->PortRangeHints
[p
];
247 af_msg(AF_MSG_VERBOSE
, " --- %d %s [", i
, pdes
->PortNames
[p
]);
249 if (LADSPA_IS_HINT_BOUNDED_BELOW(hint
.HintDescriptor
)) {
250 af_msg(AF_MSG_VERBOSE
, "%0.2f , ", hint
.LowerBound
);
252 af_msg(AF_MSG_VERBOSE
, "... , ");
255 if (LADSPA_IS_HINT_BOUNDED_ABOVE(hint
.HintDescriptor
)) {
256 af_msg(AF_MSG_VERBOSE
, "%0.2f]\n", hint
.UpperBound
);
258 af_msg(AF_MSG_VERBOSE
, "...]\n");
266 /* ------------------------------------------------------------------------- */
268 /* This function might "slightly" look like dlopenLADSPA in the LADSPA SDK :-)
269 * But, I changed a few things, because imho it was broken. It did not support
270 * relative paths, only absolute paths that start with a /
271 * I think ../../some/dir/foobar.so is just as valid. And if one wants to call
272 * his library '...somename...so' he's crazy, but it should be allowed.
273 * So, search the path first, try plain *filename later.
274 * Also, try adding .so first! I like the recursion the SDK did, but it's
275 * better the other way around. -af ladspa=cmt:amp_stereo:0.5 is easier to type
276 * than -af ladspa=cmt.so:amp_stereo:0.5 :-))
279 /** \brief dlopen() wrapper
281 * This is a wrapper around dlopen(). It tries various variations of the
282 * filename (with or without the addition of the .so extension) in various
283 * directories specified by the LADSPA_PATH environment variable. If all fails
284 * it tries the filename directly as an absolute path to the library.
286 * \param filename filename of the library to load.
287 * \param flag see dlopen(3) for a description of the flags.
289 * \return returns a pointer to the loaded library on success, or
290 * NULL if it fails to load.
293 static void* mydlopen(const char *filename
, int flag
) {
295 const char *end
, *start
, *ladspapath
;
296 int endsinso
, needslash
;
300 # ifdef WIN32 /* for windows there's only absolute path support.
301 * if you have a windows machine, feel free to fix
302 * this. (path separator, shared objects extension,
305 af_msg(AF_MSG_VERBOSE
, "\ton windows, only absolute pathnames "
307 af_msg(AF_MSG_VERBOSE
, "\ttrying %s\n", filename
);
308 return dlopen(filename
, flag
);
311 filenamelen
= strlen(filename
);
315 endsinso
= (strcmp(filename
+filenamelen
-3, ".so") == 0);
317 buf
=malloc(filenamelen
+4);
318 strcpy(buf
, filename
);
320 result
=mydlopen(buf
, flag
);
327 ladspapath
=getenv("LADSPA_PATH");
332 while (*start
!= '\0') {
334 while ( (*end
!= ':') && (*end
!= '\0') )
337 buf
=malloc(filenamelen
+ 2 + (end
-start
) );
339 strncpy(buf
, start
, end
-start
);
342 if (*(end
-1) != '/') {
344 buf
[end
-start
] = '/';
346 strcpy(buf
+needslash
+(end
-start
), filename
);
348 af_msg(AF_MSG_VERBOSE
, "\ttrying %s\n", buf
);
349 result
=dlopen(buf
, flag
);
358 } /* end while there's still more in the path */
359 } /* end if there's a ladspapath */
361 /* last resort, just open it again, so the dlerror() message is correct */
362 af_msg(AF_MSG_VERBOSE
, "\ttrying %s\n", filename
);
363 return dlopen(filename
,flag
);
366 /* ------------------------------------------------------------------------- */
368 /** \brief Load a LADSPA Plugin
370 * This function loads the LADSPA plugin specified by the file and label
371 * that are present in the setup variable. First, it loads the library.
372 * If it fails, it returns AF_ERROR. If not, it continues to look for the
373 * specified label. If it finds it, it sets the plugin_descriptor inside
374 * setup and returns AF_OK. If it doesn't, it returns AF_ERROR. Special case
375 * is a label called 'help'. In that case, it prints a list of all available
376 * labels (filters) in the library specified by file.
378 * \param setup Current setup of the filter. Contains filename and label.
380 * \return Either AF_ERROR or AF_OK, depending on the success of the operation.
383 static int af_ladspa_load_plugin(af_ladspa_t
*setup
) {
384 const LADSPA_Descriptor
*ladspa_descriptor
;
385 LADSPA_Descriptor_Function descriptor_function
;
389 af_msg(AF_MSG_VERBOSE
, "%s: loading ladspa plugin library %s\n",
390 setup
->myname
, setup
->file
);
392 setup
->libhandle
= mydlopen(setup
->file
, RTLD_NOW
);
394 if (!setup
->libhandle
) {
395 af_msg(AF_MSG_ERROR
, "%s: %s %s\n\t%s\n", setup
->myname
,
396 MSGTR_AF_LADSPA_ErrFailedToLoad
, setup
->file
, dlerror() );
400 af_msg(AF_MSG_VERBOSE
, "%s: library found.\n", setup
->myname
);
402 /* find descriptor function */
404 descriptor_function
= (LADSPA_Descriptor_Function
) dlsym (setup
->libhandle
,
405 "ladspa_descriptor");
407 if (!descriptor_function
) {
408 af_msg(AF_MSG_ERROR
, "%s: %s\n\t%s\n", setup
->myname
,
409 MSGTR_AF_LADSPA_ErrNoDescriptor
, dlerror());
413 /* if label == help, list all labels in library and exit */
415 if (strcmp(setup
->label
, "help") == 0) {
416 af_msg(AF_MSG_INFO
, "%s: %s %s:\n", setup
->myname
,
417 MSGTR_AF_LADSPA_AvailableLabels
, setup
->file
);
419 ladspa_descriptor
= descriptor_function(i
);
420 if (ladspa_descriptor
== NULL
) {
423 af_msg(AF_MSG_INFO
, " %-16s - %s (%lu)\n",
424 ladspa_descriptor
->Label
,
425 ladspa_descriptor
->Name
,
426 ladspa_descriptor
->UniqueID
);
430 af_msg(AF_MSG_VERBOSE
, "%s: looking for label\n", setup
->myname
);
432 /* find label in library */
434 ladspa_descriptor
= descriptor_function(i
);
435 if (ladspa_descriptor
== NULL
) {
436 af_msg(AF_MSG_ERROR
, "%s: %s\n", setup
->myname
,
437 MSGTR_AF_LADSPA_ErrLabelNotFound
);
440 if (strcmp(ladspa_descriptor
->Label
, setup
->label
) == 0) {
441 setup
->plugin_descriptor
= ladspa_descriptor
;
442 af_msg(AF_MSG_VERBOSE
, "%s: %s found\n", setup
->myname
,
451 /* ------------------------------------------------------------------------- */
453 /** \brief Print a malloc() failed error message.
455 * Generic function which can be called if a call to malloc(), calloc(),
456 * strdup(), et cetera, failed. It prints a message to the console and
462 static int af_ladspa_malloc_failed(char *myname
) {
463 af_msg(AF_MSG_ERROR
, "%s: %s", myname
, MSGTR_MemAllocFailed
);
467 /* ------------------------------------------------------------------------- */
469 /** \brief Controls the filter.
471 * Control the behaviour of the filter.
474 * CONTROL_REINIT Sets the af structure with proper values for number
475 * of channels, rate, format, et cetera.
476 * CONTROL_COMMAND_LINE Parses the suboptions given to this filter
477 * through arg. It first parses the filename and
478 * the label. After that, it loads the filter
479 * and finds out its proprties. Then in continues
480 * parsing the controls given on the commandline,
483 * \param af Audio filter instance
484 * \param cmd The command to execute
485 * \param arg Arguments to the command
487 * \return Either AF_ERROR or AF_OK, depending on the succes of the
491 static int control(struct af_instance_s
*af
, int cmd
, void *arg
) {
492 af_ladspa_t
*setup
= (af_ladspa_t
*) af
->setup
;
497 case AF_CONTROL_REINIT
:
498 af_msg(AF_MSG_VERBOSE
, "%s: (re)init\n", setup
->myname
);
500 if (!arg
) return AF_ERROR
;
502 /* accept FLOAT, let af_format do conversion */
504 af
->data
->rate
= ((af_data_t
*)arg
)->rate
;
505 af
->data
->nch
= ((af_data_t
*)arg
)->nch
;
506 af
->data
->format
= AF_FORMAT_FLOAT_NE
;
509 /* arg->len is not set here yet, so init of buffers and connecting the
510 * filter, has to be done in play() :-/
513 return af_test_output(af
, (af_data_t
*)arg
);
514 case AF_CONTROL_COMMAND_LINE
: {
517 af_msg(AF_MSG_VERBOSE
, "%s: parse suboptions\n", setup
->myname
);
519 /* suboption parser here!
520 * format is (ladspa=)file:label:controls....
524 af_msg(AF_MSG_ERROR
, "%s: %s\n", setup
->myname
,
525 MSGTR_AF_LADSPA_ErrNoSuboptions
);
529 buf
= malloc(strlen(arg
)+1);
530 if (!buf
) return af_ladspa_malloc_failed(setup
->myname
);
534 sscanf(arg
, "%[^:]", buf
);
535 if (buf
[0] == '\0') {
536 af_msg(AF_MSG_ERROR
, "%s: %s\n", setup
->myname
,
537 MSGTR_AF_LADSPA_ErrNoLibFile
);
542 setup
->file
= strdup(buf
);
543 if (!setup
->file
) return af_ladspa_malloc_failed(setup
->myname
);
544 af_msg(AF_MSG_VERBOSE
, "%s: file --> %s\n", setup
->myname
,
546 if (*(char*)arg
!= '\0') arg
++; /* read ':' */
550 sscanf(arg
, "%[^:]", buf
);
551 if (buf
[0] == '\0') {
552 af_msg(AF_MSG_ERROR
, "%s: %s\n", setup
->myname
,
553 MSGTR_AF_LADSPA_ErrNoLabel
);
558 setup
->label
= strdup(buf
);
559 if (!setup
->label
) return af_ladspa_malloc_failed(setup
->myname
);
560 af_msg(AF_MSG_VERBOSE
, "%s: label --> %s\n", setup
->myname
,
562 /* if (*(char*)arg != '0') arg++; */ /* read ':' */
564 free(buf
); /* no longer needed */
566 /* set new setup->myname */
568 if(setup
->myname
) free(setup
->myname
);
569 setup
->myname
= calloc(strlen(af_info_ladspa
.name
)+strlen(setup
->file
)+
570 strlen(setup
->label
)+6, 1);
571 snprintf(setup
->myname
, strlen(af_info_ladspa
.name
)+
572 strlen(setup
->file
)+strlen(setup
->label
)+6, "%s: (%s:%s)",
573 af_info_ladspa
.name
, setup
->file
, setup
->label
);
577 if ( af_ladspa_load_plugin(setup
) != AF_OK
)
580 /* see what inputs, outputs and controls this plugin has */
581 if ( af_ladspa_parse_plugin(setup
) != AF_OK
)
584 /* ninputcontrols is set by now, read control values from arg */
586 for(i
=0; i
<setup
->ninputcontrols
; i
++) {
587 if (!arg
|| (*(char*)arg
!= ':') ) {
588 af_msg(AF_MSG_ERROR
, "%s: %s\n", setup
->myname
,
589 MSGTR_AF_LADSPA_ErrNotEnoughControls
);
593 r
= sscanf(arg
, "%f", &val
);
595 af_msg(AF_MSG_ERROR
, "%s: %s\n", setup
->myname
,
596 MSGTR_AF_LADSPA_ErrNotEnoughControls
);
599 setup
->inputcontrols
[setup
->inputcontrolsmap
[i
]] = val
;
600 arg
= strchr(arg
, ':');
603 af_msg(AF_MSG_VERBOSE
, "%s: input controls: ", setup
->myname
);
604 for(i
=0; i
<setup
->ninputcontrols
; i
++) {
605 af_msg(AF_MSG_VERBOSE
, "%0.4f ",
606 setup
->inputcontrols
[setup
->inputcontrolsmap
[i
]]);
608 af_msg(AF_MSG_VERBOSE
, "\n");
610 /* check boundaries of inputcontrols */
612 af_msg(AF_MSG_VERBOSE
, "%s: checking boundaries of input controls\n",
614 for(i
=0; i
<setup
->ninputcontrols
; i
++) {
615 int p
= setup
->inputcontrolsmap
[i
];
616 LADSPA_PortRangeHint hint
=
617 setup
->plugin_descriptor
->PortRangeHints
[p
];
618 val
= setup
->inputcontrols
[p
];
620 if (LADSPA_IS_HINT_BOUNDED_BELOW(hint
.HintDescriptor
) &&
621 val
< hint
.LowerBound
) {
622 af_msg(AF_MSG_ERROR
, MSGTR_AF_LADSPA_ErrControlBelow
,
623 setup
->myname
, i
, hint
.LowerBound
);
626 if (LADSPA_IS_HINT_BOUNDED_ABOVE(hint
.HintDescriptor
) &&
627 val
> hint
.UpperBound
) {
628 af_msg(AF_MSG_ERROR
, MSGTR_AF_LADSPA_ErrControlAbove
,
629 setup
->myname
, i
, hint
.UpperBound
);
633 af_msg(AF_MSG_VERBOSE
, "%s: all controls have sane values\n",
637 setup
->status
= AF_OK
;
645 /* ------------------------------------------------------------------------- */
647 /** \brief Uninitialise the LADSPA Plugin Loader filter.
649 * This function deactivates the plugin(s), cleans up, frees all allocated
652 * \return No return value.
655 static void uninit(struct af_instance_s
*af
) {
661 af_ladspa_t
*setup
= (af_ladspa_t
*) af
->setup
;
662 const LADSPA_Descriptor
*pdes
= setup
->plugin_descriptor
;
665 af_msg(AF_MSG_VERBOSE
, "%s: cleaning up\n", setup
->myname
);
669 if (setup
->chhandles
) {
670 for(i
=0; i
<setup
->nch
; i
+=setup
->ninputs
) {
671 if (pdes
->deactivate
) pdes
->deactivate(setup
->chhandles
[i
]);
672 if (pdes
->cleanup
) pdes
->cleanup(setup
->chhandles
[i
]);
674 free(setup
->chhandles
);
681 if (setup
->inputcontrolsmap
)
682 free(setup
->inputcontrolsmap
);
683 if (setup
->inputcontrols
)
684 free(setup
->inputcontrols
);
685 if (setup
->outputcontrolsmap
)
686 free(setup
->outputcontrolsmap
);
687 if (setup
->outputcontrols
)
688 free(setup
->outputcontrols
);
692 free(setup
->outputs
);
695 for(i
=0; i
<setup
->nch
; i
++) {
696 if (setup
->inbufs
[i
])
697 free(setup
->inbufs
[i
]);
702 if (setup
->outbufs
) {
703 for(i
=0; i
<setup
->nch
; i
++) {
704 if (setup
->outbufs
[i
])
705 free(setup
->outbufs
[i
]);
707 free(setup
->outbufs
);
710 if (setup
->libhandle
)
711 dlclose(setup
->libhandle
);
718 /* ------------------------------------------------------------------------- */
720 /** \brief Process chunk of audio data through the selected LADSPA Plugin.
722 * \param af Pointer to audio filter instance
723 * \param data Pointer to chunk of audio data
725 * \return Either AF_ERROR or AF_OK
728 static af_data_t
* play(struct af_instance_s
*af
, af_data_t
*data
) {
729 af_ladspa_t
*setup
= af
->setup
;
730 const LADSPA_Descriptor
*pdes
= setup
->plugin_descriptor
;
731 float *audio
= (float*)data
->audio
;
732 int nsamples
= data
->len
/4; /* /4 because it's 32-bit float */
734 int rate
= data
->rate
;
737 if (setup
->status
!=AF_OK
)
740 /* See if it's the first call. If so, setup inbufs/outbufs, instantiate
741 * plugin, connect ports and activate plugin
744 /* 2004-12-07: Also check if the buffersize has to be changed!
745 * data->len is not constant per se! re-init buffers.
748 if ( (setup
->bufsize
!= nsamples
/nch
) || (setup
->nch
!= nch
) ) {
750 /* if setup->nch==0, it's the first call, if not, something has
751 * changed and all previous mallocs have to be freed
754 if (setup
->nch
!= 0) {
755 af_msg(AF_MSG_DEBUG1
, "%s: bufsize change; free old buffer\n",
759 for(i
=0; i
<setup
->nch
; i
++) {
761 free(setup
->inbufs
[i
]);
766 for(i
=0; i
<setup
->nch
; i
++) {
767 if(setup
->outbufs
[i
])
768 free(setup
->outbufs
[i
]);
770 free(setup
->outbufs
);
772 } /* everything is freed */
774 setup
->bufsize
= nsamples
/nch
;
777 setup
->inbufs
= calloc(nch
, sizeof(float*));
778 setup
->outbufs
= calloc(nch
, sizeof(float*));
780 af_msg(AF_MSG_DEBUG1
, "%s: bufsize = %d\n",
781 setup
->myname
, setup
->bufsize
);
783 for(i
=0; i
<nch
; i
++) {
784 setup
->inbufs
[i
] = calloc(setup
->bufsize
, sizeof(float));
785 setup
->outbufs
[i
] = calloc(setup
->bufsize
, sizeof(float));
788 /* only on the first call, there are no handles. */
790 if (!setup
->chhandles
) {
791 setup
->chhandles
= calloc(nch
, sizeof(LADSPA_Handle
));
794 * for stereo effects, create one handle for two channels
797 for(i
=0; i
<nch
; i
++) {
799 if (i
% setup
->ninputs
) { /* stereo effect */
800 /* copy the handle from previous channel */
801 setup
->chhandles
[i
] = setup
->chhandles
[i
-1];
805 setup
->chhandles
[i
] = pdes
->instantiate(pdes
, rate
);
809 /* connect input/output ports for each channel/filter instance
811 * always (re)connect ports
814 for(i
=0; i
<nch
; i
++) {
815 pdes
->connect_port(setup
->chhandles
[i
],
816 setup
->inputs
[i
% setup
->ninputs
],
818 pdes
->connect_port(setup
->chhandles
[i
],
819 setup
->outputs
[i
% setup
->ninputs
],
822 /* connect (input) controls */
824 for (p
=0; p
<setup
->nports
; p
++) {
825 LADSPA_PortDescriptor d
= pdes
->PortDescriptors
[p
];
826 if (LADSPA_IS_PORT_CONTROL(d
)) {
827 if (LADSPA_IS_PORT_INPUT(d
)) {
828 pdes
->connect_port(setup
->chhandles
[i
], p
,
829 &(setup
->inputcontrols
[p
]) );
831 pdes
->connect_port(setup
->chhandles
[i
], p
,
832 &(setup
->outputcontrols
[p
]) );
837 /* Activate filter (if it isn't already :) ) */
839 if ( (pdes
->activate
) && (setup
->activated
== 0) ) {
840 pdes
->activate(setup
->chhandles
[i
]);
841 setup
->activated
= 1;
844 } /* All channels/filters done! except for... */
846 /* Stereo effect with one channel left. Use same buffer for left
847 * and right. connect it to the second port.
850 for (p
= i
; p
% setup
->ninputs
; p
++) {
851 pdes
->connect_port(setup
->chhandles
[i
-1],
852 setup
->inputs
[p
% setup
->ninputs
],
854 pdes
->connect_port(setup
->chhandles
[i
-1],
855 setup
->outputs
[p
% setup
->ninputs
],
856 setup
->outbufs
[i
-1]);
859 } /* setup for first call/change of bufsize is done.
860 * normal playing routine follows...
863 /* Right now, I use a separate input and output buffer.
864 * I could change this to in-place processing (inbuf==outbuf), but some
865 * ladspa filters are broken and are not able to handle that. This seems
866 * fast enough, so unless somebody complains, it stays this way :)
871 for (p
=0; p
<setup
->bufsize
; p
++) {
872 for (i
=0; i
<nch
; i
++) {
873 setup
->inbufs
[i
][p
] = audio
[p
*nch
+ i
];
879 for (i
=0; i
<nch
; i
+=setup
->ninputs
) {
880 pdes
->run(setup
->chhandles
[i
], setup
->bufsize
);
883 /* Extract outbufs */
885 for (p
=0; p
<setup
->bufsize
; p
++) {
886 for (i
=0; i
<nch
; i
++) {
887 audio
[p
*nch
+ i
] = setup
->outbufs
[i
][p
];
896 /* ------------------------------------------------------------------------- */
898 /** \brief Open LADSPA Plugin Loader Filter
900 * \param af Audio Filter instance
902 * \return Either AF_ERROR or AF_OK
905 static int af_open(af_instance_t
*af
) {
912 af
->data
= calloc(1, sizeof(af_data_t
));
913 if (af
->data
== NULL
)
914 return af_ladspa_malloc_failed((char*)af_info_ladspa
.name
);
916 af
->setup
= calloc(1, sizeof(af_ladspa_t
));
917 if (af
->setup
== NULL
) {
920 return af_ladspa_malloc_failed((char*)af_info_ladspa
.name
);
923 ((af_ladspa_t
*)af
->setup
)->status
= AF_ERROR
; /* will be set to AF_OK if
924 * all went OK and play()
928 ((af_ladspa_t
*)af
->setup
)->myname
= strdup(af_info_ladspa
.name
);
929 if (!((af_ladspa_t
*)af
->setup
)->myname
)
930 return af_ladspa_malloc_failed((char*)af_info_ladspa
.name
);
935 /* ------------------------------------------------------------------------- */