summaryrefslogtreecommitdiffstats
path: root/audio/filter/af_ladspa.c
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2015-09-03 23:55:36 +0200
committerwm4 <wm4@nowhere>2015-09-03 23:55:36 +0200
commit091bfa3abf2f28b37fa12cca6b4c248c31d27965 (patch)
treef5406c1b373ed91a914712e3c0d25076449df123 /audio/filter/af_ladspa.c
parente1fbd3b790b5fe1ae6efc1dd0477c2da88a5b8dc (diff)
downloadmpv-091bfa3abf2f28b37fa12cca6b4c248c31d27965.tar.bz2
mpv-091bfa3abf2f28b37fa12cca6b4c248c31d27965.tar.xz
audio/filter: remove some useless filters
All of these filters are considered not useful anymore by us. Some have replacements in libavfilter (useable through af_lavfi). af_center, af_extrastereo, af_karaoke, af_sinesuppress, af_sub, af_surround, af_sweep: pretty simple and useless filters which probably nobody ever wants. af_ladspa: has a replacement in libavfilter. af_hrtf: the algorithm doesn't work properly on most sources, and the implementation was buggy and complicated. (The filter was inherited from MPlayer; but even in mpv times we had to apply fixes that fixed major issues with added noise.) There is a ladspa filter if you still want to use it. af_export: I'm not even sure what this is supposed to do. Possibly it was meant for GUIs rendering audio visualizations, but it couldn't really work well. For example, the size of the audio depended on the samplerate (fixed number of samples only), and it couldn't retrieve the complete audio, only fragments. If this is really needed for GUIs, mpv should add native visualization, or a proper API for it.
Diffstat (limited to 'audio/filter/af_ladspa.c')
-rw-r--r--audio/filter/af_ladspa.c851
1 files changed, 0 insertions, 851 deletions
diff --git a/audio/filter/af_ladspa.c b/audio/filter/af_ladspa.c
deleted file mode 100644
index edde6a68b1..0000000000
--- a/audio/filter/af_ladspa.c
+++ /dev/null
@@ -1,851 +0,0 @@
-/*
- * LADSPA plugin loader
- *
- * Written by Ivo van Poorten <ivop@euronet.nl>
- * Copyright (C) 2004, 2005
- *
- * This file is part of mpv.
- *
- * mpv is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * mpv is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with mpv. If not, see <http://www.gnu.org/licenses/>.
- */
-
-/* ------------------------------------------------------------------------- */
-
-/* Global Includes */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include <inttypes.h>
-#include <math.h>
-#include <limits.h>
-
-#include <dlfcn.h>
-#include <ladspa.h>
-
-/* ------------------------------------------------------------------------- */
-
-/* Local Includes */
-
-#include "af.h"
-
-#define _(x) (x)
-
-/* ------------------------------------------------------------------------- */
-
-/* Filter specific data */
-
-typedef struct af_ladspa_s
-{
- int status; /**< Status of the filter.
- * Either AF_OK or AF_ERROR
- * Because MPlayer re-inits audio filters that
- * _clearly_ returned AF_ERROR anyway, I use this
- * in play() to skip the processing and return
- * the data unchanged.
- */
-
- int activated; /**< 0 or 1. Activate LADSPA filters only once, even
- * if the buffers get resized, to avoid a stuttering
- * filter.
- */
-
- char *file;
- char *label;
- char *controls;
-
- char *myname; /**< It's easy to have a concatenation of file and label */
-
- void *libhandle;
- const LADSPA_Descriptor *plugin_descriptor;
-
- int nports;
-
- int ninputs;
- int *inputs;
-
- int noutputs;
- int *outputs;
-
- int ninputcontrols;
- int *inputcontrolsmap; /**< Map input port number [0-] to actual port */
- float *inputcontrols;
-
- int noutputcontrols;
- int *outputcontrolsmap;
- float *outputcontrols;
-
- int nch; /**< number of channels */
- int bufsize;
- float **inbufs;
- float **outbufs;
- LADSPA_Handle *chhandles;
-
-} af_ladspa_t;
-
-/* ------------------------------------------------------------------------- */
-
-static int af_open(struct af_instance *af);
-static int af_ladspa_malloc_failed(char*);
-
-/* ------------------------------------------------------------------------- */
-
-#define OPT_BASE_STRUCT af_ladspa_t
-const struct af_info af_info_ladspa = {
- .info = "LADSPA plugin loader",
- .name = "ladspa",
- .open = af_open,
- .priv_size = sizeof(af_ladspa_t),
- .options = (const struct m_option[]) {
- OPT_STRING("file", file, 0),
- OPT_STRING("label", label, 0),
- OPT_STRING("controls", controls, 0),
- {0}
- },
-};
-
-/* ------------------------------------------------------------------------- */
-
-/* By lack of a better word (in my vocabulary) this is called 'parse'.
- * Feel free to suggest an alternative.
- */
-
-/** \brief Check for inputs, outputs and controls of a given filter.
- *
- * This function counts and checks all input, output and control ports
- * of the filter that was loaded. If it turns out to be a valid
- * filter for MPlayer use, it prints out a list of all controls and
- * the corresponding range of its value at message level MSGL_V.
- *
- * \param setup Current setup of the filter. Must have its
- * plugin_descriptor set!
- *
- * \return Returns AF_OK if it has a valid input/output/controls
- * configuration. Else, it returns AF_ERROR.
- */
-
-static int af_ladspa_parse_plugin(struct af_instance *af) {
- af_ladspa_t *setup = af->priv;
- int p, i;
- const LADSPA_Descriptor *pdes = setup->plugin_descriptor;
- LADSPA_PortDescriptor d;
- LADSPA_PortRangeHint hint;
-
- if (!setup->libhandle)
- return AF_ERROR; /* only call parse after a successful load */
- if (!setup->plugin_descriptor)
- return AF_ERROR; /* same as above */
-
- /* let's do it */
-
- setup->nports = pdes->PortCount;
-
- /* allocate memory for all inputs/outputs/controls */
-
- setup->inputs = calloc(setup->nports, sizeof(int));
- if (!setup->inputs) return af_ladspa_malloc_failed(setup->myname);
-
- setup->outputs = calloc(setup->nports, sizeof(int));
- if (!setup->outputs) return af_ladspa_malloc_failed(setup->myname);
-
- setup->inputcontrolsmap = calloc(setup->nports, sizeof(int));
- if (!setup->inputcontrolsmap) return af_ladspa_malloc_failed(setup->myname);
-
- setup->inputcontrols = calloc(setup->nports, sizeof(float));
- if (!setup->inputcontrols) return af_ladspa_malloc_failed(setup->myname);
-
- setup->outputcontrolsmap = calloc(setup->nports, sizeof(int));
- if (!setup->outputcontrolsmap) return af_ladspa_malloc_failed(setup->myname);
-
- setup->outputcontrols = calloc(setup->nports, sizeof(float));
- if (!setup->outputcontrols) return af_ladspa_malloc_failed(setup->myname);
-
- /* set counts to zero */
-
- setup->ninputs = 0;
- setup->noutputs = 0;
- setup->ninputcontrols = 0;
- setup->noutputcontrols = 0;
-
- /* check all ports, see what type it is and set variables according to
- * what we have found
- */
-
- for (p=0; p<setup->nports; p++) {
- d = pdes->PortDescriptors[p];
-
- if (LADSPA_IS_PORT_AUDIO(d)) {
- if (LADSPA_IS_PORT_INPUT(d)) {
- setup->inputs[setup->ninputs] = p;
- setup->ninputs++;
- } else if (LADSPA_IS_PORT_OUTPUT(d)) {
- setup->outputs[setup->noutputs] = p;
- setup->noutputs++;
- }
- }
-
- if (LADSPA_IS_PORT_CONTROL(d)) {
- if (LADSPA_IS_PORT_INPUT(d)) {
- setup->inputcontrolsmap[setup->ninputcontrols] = p;
- setup->ninputcontrols++;
- /* set control to zero. set values after reading the rest
- * of the suboptions and check LADSPA_?_HINT's later.
- */
- setup->inputcontrols[p] = 0.0f;
- } else if (LADSPA_IS_PORT_OUTPUT(d)) {
- /* read and handle these too, otherwise filters that have them
- * will sig11
- */
- setup->outputcontrolsmap[setup->noutputcontrols]=p;
- setup->noutputcontrols++;
- setup->outputcontrols[p] = 0.0f;
- }
- }
-
- }
-
- if (setup->ninputs == 0) {
- MP_WARN(af, "%s: %s\n", setup->myname,
- _("WARNING! This LADSPA plugin has no audio inputs.\n The incoming audio signal will be lost."));
- } else if (setup->ninputs == 1) {
- MP_VERBOSE(af, "%s: this is a mono effect\n", setup->myname);
- } else if (setup->ninputs == 2) {
- MP_VERBOSE(af, "%s: this is a stereo effect\n", setup->myname);
- } else {
- MP_VERBOSE(af, "%s: this is a %i-channel effect, "
- "support is experimental\n", setup->myname, setup->ninputs);
- }
-
- if (setup->noutputs == 0) {
- MP_ERR(af, "%s: %s\n", setup->myname,
- _("This LADSPA plugin has no audio outputs."));
- return AF_ERROR;
- }
-
- if (setup->noutputs != setup->ninputs ) {
- MP_ERR(af, "%s: %s\n", setup->myname,
- _("The number of audio inputs and audio outputs of the LADSPA plugin differ."));
- return AF_ERROR;
- }
-
- MP_VERBOSE(af, "%s: this plugin has %d input control(s)\n",
- setup->myname, setup->ninputcontrols);
-
- /* Print list of controls and its range of values it accepts */
-
- for (i=0; i<setup->ninputcontrols; i++) {
- p = setup->inputcontrolsmap[i];
- hint = pdes->PortRangeHints[p];
- MP_VERBOSE(af, " --- %d %s [", i, pdes->PortNames[p]);
-
- if (LADSPA_IS_HINT_BOUNDED_BELOW(hint.HintDescriptor)) {
- MP_VERBOSE(af, "%0.2f , ", hint.LowerBound);
- } else {
- MP_VERBOSE(af, "... , ");
- }
-
- if (LADSPA_IS_HINT_BOUNDED_ABOVE(hint.HintDescriptor)) {
- MP_VERBOSE(af, "%0.2f]\n", hint.UpperBound);
- } else {
- MP_VERBOSE(af, "...]\n");
- }
-
- }
-
- return AF_OK;
-}
-
-/* ------------------------------------------------------------------------- */
-
-/* This function might "slightly" look like dlopenLADSPA in the LADSPA SDK :-)
- * But, I changed a few things, because imho it was broken. It did not support
- * relative paths, only absolute paths that start with a /
- * I think ../../some/dir/foobar.so is just as valid. And if one wants to call
- * his library '...somename...so' he's crazy, but it should be allowed.
- * So, search the path first, try plain *filename later.
- * Also, try adding .so first! I like the recursion the SDK did, but it's
- * better the other way around. -af ladspa=cmt:amp_stereo:0.5 is easier to type
- * than -af ladspa=cmt.so:amp_stereo:0.5 :-))
- */
-
-/** \brief dlopen() wrapper
- *
- * This is a wrapper around dlopen(). It tries various variations of the
- * filename (with or without the addition of the .so extension) in various
- * directories specified by the LADSPA_PATH environment variable. If all fails
- * it tries the filename directly as an absolute path to the library.
- *
- * \param filename filename of the library to load.
- * \param flag see dlopen(3) for a description of the flags.
- *
- * \return returns a pointer to the loaded library on success, or
- * NULL if it fails to load.
- */
-
-static void* mydlopen(const char *filename, int flag) {
- char *buf;
- const char *end, *start, *ladspapath;
- int endsinso;
- size_t filenamelen;
- void *result = NULL;
-
-#if defined(__MINGW32__) || defined(__CYGWIN__)
- /* For Windows there's only absolute path support.
- * If you have a Windows machine, feel free to fix this.
- * (path separator, shared objects extension, et cetera). */
- MP_VERBOSE(af, "\ton windows, only absolute pathnames "
- "are supported\n");
- MP_VERBOSE(af, "\ttrying %s\n", filename);
- return dlopen(filename, flag);
-#endif
-
- filenamelen = strlen(filename);
-
- endsinso = 0;
- if (filenamelen > 3)
- endsinso = (strcmp(filename+filenamelen-3, ".so") == 0);
- if (!endsinso) {
- buf=malloc(filenamelen+4);
- strcpy(buf, filename);
- strcat(buf, ".so");
- result=mydlopen(buf, flag);
- free(buf);
- }
-
- if (result)
- return result;
-
- ladspapath=getenv("LADSPA_PATH");
-
- if (ladspapath) {
- start=ladspapath;
- while (*start != '\0') {
- int needslash;
- end=start;
- while ( (*end != ':') && (*end != '\0') )
- end++;
-
- buf=malloc(filenamelen + 2 + (end-start) );
- if (end > start)
- strncpy(buf, start, end-start);
- needslash=0;
- if (end > start)
- if (*(end-1) != '/') {
- needslash = 1;
- buf[end-start] = '/';
- }
- strcpy(buf+needslash+(end-start), filename);
-
- result=dlopen(buf, flag);
-
- free(buf);
- if (result)
- return result;
-
- start = end;
- if (*start == ':')
- start++;
- } /* end while there's still more in the path */
- } /* end if there's a ladspapath */
-
- /* last resort, just open it again, so the dlerror() message is correct */
- return dlopen(filename,flag);
-}
-
-/* ------------------------------------------------------------------------- */
-
-/** \brief Load a LADSPA Plugin
- *
- * This function loads the LADSPA plugin specified by the file and label
- * that are present in the setup variable. First, it loads the library.
- * If it fails, it returns AF_ERROR. If not, it continues to look for the
- * specified label. If it finds it, it sets the plugin_descriptor inside
- * setup and returns AF_OK. If it doesn't, it returns AF_ERROR. Special case
- * is a label called 'help'. In that case, it prints a list of all available
- * labels (filters) in the library specified by file.
- *
- * \param setup Current setup of the filter. Contains filename and label.
- *
- * \return Either AF_ERROR or AF_OK, depending on the success of the operation.
- */
-
-static int af_ladspa_load_plugin(struct af_instance *af) {
- af_ladspa_t *setup = af->priv;
- const LADSPA_Descriptor *ladspa_descriptor;
- LADSPA_Descriptor_Function descriptor_function;
- int i;
-
- /* load library */
- MP_VERBOSE(af, "%s: loading ladspa plugin library %s\n",
- setup->myname, setup->file);
-
- setup->libhandle = mydlopen(setup->file, RTLD_NOW);
-
- if (!setup->libhandle) {
- MP_ERR(af, "%s: %s %s\n\t%s\n", setup->myname,
- _("failed to load"), setup->file, dlerror() );
- return AF_ERROR;
- }
-
- MP_VERBOSE(af, "%s: library found.\n", setup->myname);
-
- /* find descriptor function */
- dlerror();
- descriptor_function = (LADSPA_Descriptor_Function) dlsym (setup->libhandle,
- "ladspa_descriptor");
-
- if (!descriptor_function) {
- MP_ERR(af, "%s: %s\n\t%s\n", setup->myname,
- _("Couldn't find ladspa_descriptor() function in the specified library file."), dlerror());
- return AF_ERROR;
- }
-
- /* if label == help, list all labels in library and exit */
-
- if (strcmp(setup->label, "help") == 0) {
- MP_INFO(af, "%s: %s %s:\n", setup->myname,
- _("available labels in"), setup->file);
- for (i=0; ; i++) {
- ladspa_descriptor = descriptor_function(i);
- if (ladspa_descriptor == NULL) {
- return AF_ERROR;
- }
- MP_INFO(af, " %-16s - %s (%lu)\n",
- ladspa_descriptor->Label,
- ladspa_descriptor->Name,
- ladspa_descriptor->UniqueID);
- }
- }
-
- MP_VERBOSE(af, "%s: looking for label\n", setup->myname);
-
- /* find label in library */
- for (i=0; ; i++) {
- ladspa_descriptor = descriptor_function(i);
- if (ladspa_descriptor == NULL) {
- MP_ERR(af, "%s: %s\n", setup->myname,
- _("Couldn't find label in plugin library."));
- return AF_ERROR;
- }
- if (strcmp(ladspa_descriptor->Label, setup->label) == 0) {
- setup->plugin_descriptor = ladspa_descriptor;
- MP_VERBOSE(af, "%s: %s found\n", setup->myname,
- setup->label);
- return AF_OK;
- }
- }
-
- return AF_OK;
-}
-
-/* ------------------------------------------------------------------------- */
-
-/** \brief Print a malloc() failed error message.
- *
- * Generic function which can be called if a call to malloc(), calloc(),
- * strdup(), et cetera, failed. It prints a message to the console and
- * returns AF_ERROR.
- *
- * \return AF_ERROR
- */
-
-static int af_ladspa_malloc_failed(char *myname) {
- return AF_ERROR;
-}
-
-/* ------------------------------------------------------------------------- */
-
-/** \brief Controls the filter.
- *
- * Control the behaviour of the filter.
- *
- * Commands:
- * CONTROL_REINIT Sets the af structure with proper values for number
- * of channels, rate, format, et cetera.
- * \param af Audio filter instance
- * \param cmd The command to execute
- * \param arg Arguments to the command
- *
- * \return Either AF_ERROR or AF_OK, depending on the succes of the
- * operation.
- */
-
-static int control(struct af_instance *af, int cmd, void *arg) {
- af_ladspa_t *setup = (af_ladspa_t*) af->priv;
-
- switch(cmd) {
- case AF_CONTROL_REINIT:
- MP_VERBOSE(af, "%s: (re)init\n", setup->myname);
-
- if (!arg) return AF_ERROR;
-
- /* accept FLOAT, let af_format do conversion */
-
- mp_audio_copy_config(af->data, (struct mp_audio*)arg);
- mp_audio_set_format(af->data, AF_FORMAT_FLOAT);
-
- return af_test_output(af, (struct mp_audio*)arg);
- }
-
- return AF_UNKNOWN;
-}
-
-/* ------------------------------------------------------------------------- */
-
-/** \brief Uninitialise the LADSPA Plugin Loader filter.
- *
- * This function deactivates the plugin(s), cleans up, frees all allocated
- * memory and exits.
- *
- * \return No return value.
- */
-
-static void uninit(struct af_instance *af) {
- if (af->priv) {
- af_ladspa_t *setup = (af_ladspa_t*) af->priv;
- const LADSPA_Descriptor *pdes = setup->plugin_descriptor;
-
- if (setup->myname) {
- MP_VERBOSE(af, "%s: cleaning up\n", setup->myname);
- free(setup->myname);
- }
-
- if (setup->chhandles) {
- for (int i = 0; i < setup->nch; i+=setup->ninputs) {
- if (pdes->deactivate) pdes->deactivate(setup->chhandles[i]);
- if (pdes->cleanup) pdes->cleanup(setup->chhandles[i]);
- }
- free(setup->chhandles);
- }
-
- free(setup->inputcontrolsmap);
- free(setup->inputcontrols);
- free(setup->outputcontrolsmap);
- free(setup->outputcontrols);
- free(setup->inputs);
- free(setup->outputs);
-
- if (setup->inbufs) {
- for(int i = 0; i < setup->nch; i++)
- free(setup->inbufs[i]);
- free(setup->inbufs);
- }
-
- if (setup->outbufs) {
- for (int i = 0; i < setup->nch; i++)
- free(setup->outbufs[i]);
- free(setup->outbufs);
- }
-
- if (setup->libhandle)
- dlclose(setup->libhandle);
- }
-}
-
-/* ------------------------------------------------------------------------- */
-
-/** \brief Process chunk of audio data through the selected LADSPA Plugin.
- *
- * \param af Pointer to audio filter instance
- * \param data Pointer to chunk of audio data
- *
- * \return Either AF_ERROR or AF_OK
- */
-
-static int filter_frame(struct af_instance *af, struct mp_audio *data)
-{
- if (!data)
- return 0;
- af_ladspa_t *setup = af->priv;
- const LADSPA_Descriptor *pdes = setup->plugin_descriptor;
- float *audio = (float*)data->planes[0];
- int nsamples = data->samples*data->nch;
- int nch = data->nch;
- int rate = data->rate;
- int i, p;
-
- if (setup->status !=AF_OK) {
- talloc_free(data);
- return -1;
- }
- if (af_make_writeable(af, data) < 0) {
- talloc_free(data);
- return -1;
- }
-
- /* See if it's the first call. If so, setup inbufs/outbufs, instantiate
- * plugin, connect ports and activate plugin
- */
-
- if ( (setup->bufsize != nsamples/nch) || (setup->nch != nch) ) {
-
- /* if setup->nch==0, it's the first call, if not, something has
- * changed and all previous mallocs have to be freed
- */
-
- if (setup->nch != 0) {
- MP_TRACE(af, "%s: bufsize change; free old buffer\n",
- setup->myname);
-
- if(setup->inbufs) {
- for(i=0; i<setup->nch; i++)
- free(setup->inbufs[i]);
- free(setup->inbufs);
- }
- if(setup->outbufs) {
- for(i=0; i<setup->nch; i++)
- free(setup->outbufs[i]);
- free(setup->outbufs);
- }
- } /* everything is freed */
-
- setup->bufsize = nsamples/nch;
- setup->nch = nch;
-
- setup->inbufs = calloc(nch, sizeof(float*));
- setup->outbufs = calloc(nch, sizeof(float*));
-
- MP_TRACE(af, "%s: bufsize = %d\n",
- setup->myname, setup->bufsize);
-
- for(i=0; i<nch; i++) {
- setup->inbufs[i] = calloc(setup->bufsize, sizeof(float));
- setup->outbufs[i] = calloc(setup->bufsize, sizeof(float));
- }
-
- /* only on the first call, there are no handles. */
-
- if (!setup->chhandles) {
- setup->chhandles = calloc(nch, sizeof(LADSPA_Handle));
-
- /* create handles
- * for stereo effects, create one handle for two channels
- */
-
- for(i=0; i<nch; i++) {
-
- if (i % setup->ninputs) { /* stereo effect */
- /* copy the handle from previous channel */
- setup->chhandles[i] = setup->chhandles[i-1];
- continue;
- }
-
- setup->chhandles[i] = pdes->instantiate(pdes, rate);
- }
- }
-
- /* connect input/output ports for each channel/filter instance
- *
- * always (re)connect ports
- */
-
- for(i=0; i<nch; i++) {
- pdes->connect_port(setup->chhandles[i],
- setup->inputs[i % setup->ninputs],
- setup->inbufs[i]);
- pdes->connect_port(setup->chhandles[i],
- setup->outputs[i % setup->ninputs],
- setup->outbufs[i]);
-
- /* connect (input) controls */
-
- for (p=0; p<setup->nports; p++) {
- LADSPA_PortDescriptor d = pdes->PortDescriptors[p];
- if (LADSPA_IS_PORT_CONTROL(d)) {
- if (LADSPA_IS_PORT_INPUT(d)) {
- pdes->connect_port(setup->chhandles[i], p,
- &(setup->inputcontrols[p]) );
- } else {
- pdes->connect_port(setup->chhandles[i], p,
- &(setup->outputcontrols[p]) );
- }
- }
- }
-
- /* Activate filter (if it isn't already :) ) */
-
- if (pdes->activate && !setup->activated && i % setup->ninputs == 0)
- pdes->activate(setup->chhandles[i]);
-
- } /* All channels/filters done! except for... */
- setup->activated = 1;
-
- /* Stereo effect with one channel left. Use same buffer for left
- * and right. connect it to the second port.
- */
-
- for (p = i; p % setup->ninputs; p++) {
- pdes->connect_port(setup->chhandles[i-1],
- setup->inputs[p % setup->ninputs],
- setup->inbufs[i-1]);
- pdes->connect_port(setup->chhandles[i-1],
- setup->outputs[p % setup->ninputs],
- setup->outbufs[i-1]);
- } /* done! */
-
- } /* setup for first call/change of bufsize is done.
- * normal playing routine follows...
- */
-
- /* Right now, I use a separate input and output buffer.
- * I could change this to in-place processing (inbuf==outbuf), but some
- * ladspa filters are broken and are not able to handle that. This seems
- * fast enough, so unless somebody complains, it stays this way :)
- */
-
- /* Fill inbufs */
-
- for (p=0; p<setup->bufsize; p++) {
- for (i=0; i<nch; i++) {
- setup->inbufs[i][p] = audio[p*nch + i];
- }
- }
-
- /* Run filter(s) */
-
- for (i=0; i<nch; i+=setup->ninputs) {
- pdes->run(setup->chhandles[i], setup->bufsize);
- }
-
- /* Extract outbufs */
-
- for (p=0; p<setup->bufsize; p++) {
- for (i=0; i<nch; i++) {
- audio[p*nch + i] = setup->outbufs[i][p];
- }
- }
-
- /* done */
-
- af_add_output_frame(af, data);
- return 0;
-}
-
-/* ------------------------------------------------------------------------- */
-
-/** \brief Open LADSPA Plugin Loader Filter
- *
- * \param af Audio Filter instance
- *
- * \return Either AF_ERROR or AF_OK
- */
-
-static int af_open(struct af_instance *af) {
-
- af->control=control;
- af->uninit=uninit;
- af->filter_frame = filter_frame;
-
- af_ladspa_t *setup = af->priv;
-
- setup->status = AF_ERROR; /* will be set to AF_OK if
- * all went OK and filter()
- * should proceed.
- */
-
- setup->myname = strdup(af_info_ladspa.name);
- if (!setup->myname)
- return af_ladspa_malloc_failed((char*)af_info_ladspa.name);
-
- if (!setup->file || !setup->file[0]) {
- MP_ERR(af, "%s: %s\n", setup->myname,
- _("No library file specified."));
- uninit(af);
- return AF_ERROR;
- }
- if (!setup->label || !setup->label[0]) {
- MP_ERR(af, "%s: %s\n", setup->myname,
- _("No filter label specified."));
- uninit(af);
- return AF_ERROR;
- }
-
- free(setup->myname);
- setup->myname = calloc(strlen(af_info_ladspa.name)+strlen(setup->file)+
- strlen(setup->label)+6, 1);
- snprintf(setup->myname, strlen(af_info_ladspa.name)+
- strlen(setup->file)+strlen(setup->label)+6, "%s: (%s:%s)",
- af_info_ladspa.name, setup->file, setup->label);
-
- /* load plugin :) */
-
- if ( af_ladspa_load_plugin(af) != AF_OK )
- return AF_ERROR;
-
- /* see what inputs, outputs and controls this plugin has */
- if ( af_ladspa_parse_plugin(af) != AF_OK )
- return AF_ERROR;
-
- /* ninputcontrols is set by now, read control values from arg */
-
- float val;
- char *line = setup->controls;
- for (int i = 0; i < setup->ninputcontrols; i++) {
- if (!line || (i != 0 && *line != ',')) {
- MP_ERR(af, "%s: %s\n", setup->myname,
- _("Not enough controls specified on the command line."));
- return AF_ERROR;
- }
- if (i != 0)
- line++;
- if (sscanf(line, "%f", &val) != 1) {
- MP_ERR(af, "%s: %s\n", setup->myname,
- _("Not enough controls specified on the command line."));
- return AF_ERROR;
- }
- setup->inputcontrols[setup->inputcontrolsmap[i]] = val;
- line = strchr(line, ',');
- }
-
- MP_VERBOSE(af, "%s: input controls: ", setup->myname);
- for (int i = 0; i < setup->ninputcontrols; i++) {
- MP_VERBOSE(af, "%0.4f ",
- setup->inputcontrols[setup->inputcontrolsmap[i]]);
- }
- MP_VERBOSE(af, "\n");
-
- /* check boundaries of inputcontrols */
-
- MP_VERBOSE(af, "%s: checking boundaries of input controls\n",
- setup->myname);
- for (int i = 0; i < setup->ninputcontrols; i++) {
- int p = setup->inputcontrolsmap[i];
- LADSPA_PortRangeHint hint =
- setup->plugin_descriptor->PortRangeHints[p];
- val = setup->inputcontrols[p];
-
- if (LADSPA_IS_HINT_BOUNDED_BELOW(hint.HintDescriptor) &&
- val < hint.LowerBound) {
- MP_ERR(af, "%s: Input control #%d is below lower boundary of %0.4f.\n",
- setup->myname, i, hint.LowerBound);
- return AF_ERROR;
- }
- if (LADSPA_IS_HINT_BOUNDED_ABOVE(hint.HintDescriptor) &&
- val > hint.UpperBound) {
- MP_ERR(af, "%s: Input control #%d is above upper boundary of %0.4f.\n",
- setup->myname, i, hint.UpperBound);
- return AF_ERROR;
- }
- }
- MP_VERBOSE(af, "%s: all controls have sane values\n",
- setup->myname);
-
- /* All is well! */
- setup->status = AF_OK;
-
- return AF_OK;
-}
-
-/* ------------------------------------------------------------------------- */