From: Nathan Kurz Date: Fri, 20 Jan 2006 08:17:49 +0000 (+0000) Subject: pcm_ladspa - setup control outputs all times X-Git-Tag: v1.0.11rc3~2 X-Git-Url: https://git.alsa-project.org/?a=commitdiff_plain;h=d9cfe1e9ff7a78ff75f1def27230a23061009729;p=alsa-lib.git pcm_ladspa - setup control outputs all times It turned out that plugins that had control outputs were not being set up properly if there was no corresponding "output" section. Signed-off-by: Nathan Kurz --- diff --git a/src/pcm/pcm_ladspa.c b/src/pcm/pcm_ladspa.c index 89f9dda0..03f31f76 100644 --- a/src/pcm/pcm_ladspa.c +++ b/src/pcm/pcm_ladspa.c @@ -1211,155 +1211,204 @@ static int snd_pcm_ladspa_look_for_plugin(snd_pcm_ladspa_plugin_t * const plugin return -ENOENT; } -static int snd_pcm_ladspa_parse_ioconfig(snd_pcm_ladspa_plugin_t *lplug, +static int snd_pcm_ladspa_add_default_controls(snd_pcm_ladspa_plugin_t *lplug, + snd_pcm_ladspa_plugin_io_t *io) +{ + unsigned int count = 0; + LADSPA_Data *array; + unsigned char *initialized; + unsigned long idx; + + for (idx = 0; idx < lplug->desc->PortCount; idx++) + if ((lplug->desc->PortDescriptors[idx] & (io->pdesc | LADSPA_PORT_CONTROL)) == (io->pdesc | LADSPA_PORT_CONTROL)) + count++; + array = (LADSPA_Data *)calloc(count, sizeof(LADSPA_Data)); + if (!array) + return -ENOMEM; + initialized = (unsigned char *)calloc(count, sizeof(unsigned char)); + if (!initialized) { + free(array); + return -ENOMEM; + } + io->controls_size = count; + io->controls_initialized = initialized; + io->controls = array; + + return 0; +} + +static int snd_pcm_ladspa_parse_controls(snd_pcm_ladspa_plugin_t *lplug, snd_pcm_ladspa_plugin_io_t *io, - snd_config_t *conf) + snd_config_t *controls) { snd_config_iterator_t i, next; - snd_config_t *bindings = NULL, *controls = NULL; int err; - - if (conf == NULL) - return 0; - if (snd_config_get_type(conf) != SND_CONFIG_TYPE_COMPOUND) { - SNDERR("input or output definition must be a compound"); + + if (snd_config_get_type(controls) != SND_CONFIG_TYPE_COMPOUND) { + SNDERR("controls definition must be a compound"); return -EINVAL; } - snd_config_for_each(i, next, conf) { + + snd_config_for_each(i, next, controls) { snd_config_t *n = snd_config_iterator_entry(i); const char *id; + long lval; + unsigned int port, uval; + double dval; if (snd_config_get_id(n, &id) < 0) continue; - if (strcmp(id, "bindings") == 0) { - bindings = n; - continue; + err = safe_strtol(id, &lval); + if (err >= 0) { + err = snd_pcm_ladspa_find_port(&port, lplug, io->pdesc | LADSPA_PORT_CONTROL, lval); + } else { + err = snd_pcm_ladspa_find_sport(&port, lplug, io->pdesc | LADSPA_PORT_CONTROL, id); } - if (strcmp(id, "controls") == 0) { - controls = n; - continue; + if (err < 0) { + SNDERR("Unable to find an control port (%s)", id); + return err; } + if (snd_config_get_ireal(n, &dval) < 0) { + SNDERR("Control port %s has not an float or integer value", id); + return err; + } + err = snd_pcm_ladspa_find_port_idx(&uval, lplug, io->pdesc | LADSPA_PORT_CONTROL, port); + if (err < 0) { + SNDERR("internal error"); + return err; + } + io->controls_initialized[uval] = 1; + io->controls[uval] = (LADSPA_Data)dval; } - if (bindings) { - unsigned int count = 0; - unsigned int *array; - if (snd_config_get_type(bindings) != SND_CONFIG_TYPE_COMPOUND) { - SNDERR("bindings definition must be a compound"); + + return 0; +} + +static int snd_pcm_ladspa_parse_bindings(snd_pcm_ladspa_plugin_t *lplug, + snd_pcm_ladspa_plugin_io_t *io, + snd_config_t *bindings) +{ + unsigned int count = 0; + unsigned int *array; + snd_config_iterator_t i, next; + int err; + + if (snd_config_get_type(bindings) != SND_CONFIG_TYPE_COMPOUND) { + SNDERR("bindings definition must be a compound"); + return -EINVAL; + } + snd_config_for_each(i, next, bindings) { + snd_config_t *n = snd_config_iterator_entry(i); + const char *id; + long channel; + if (snd_config_get_id(n, &id) < 0) + continue; + err = safe_strtol(id, &channel); + if (err < 0 || channel < 0) { + SNDERR("Invalid channel number: %s", id); + return -EINVAL; + } + if (lplug->policy == SND_PCM_LADSPA_POLICY_DUPLICATE && channel > 0) { + SNDERR("Wrong channel specification for duplicate policy"); return -EINVAL; } + if (count < (unsigned int)(channel + 1)) + count = (unsigned int)(channel + 1); + } + if (count > 0) { + array = (unsigned int *)calloc(count, sizeof(unsigned int)); + if (! array) + return -ENOMEM; + memset(array, 0xff, count * sizeof(unsigned int)); + io->port_bindings_size = count; + io->port_bindings = array; snd_config_for_each(i, next, bindings) { snd_config_t *n = snd_config_iterator_entry(i); - const char *id; - long channel; + const char *id, *sport; + long channel, port; if (snd_config_get_id(n, &id) < 0) continue; err = safe_strtol(id, &channel); if (err < 0 || channel < 0) { - SNDERR("Invalid channel number: %s", id); - return -EINVAL; - } - if (lplug->policy == SND_PCM_LADSPA_POLICY_DUPLICATE && channel > 0) { - SNDERR("Wrong channel specification for duplicate policy"); + assert(0); /* should never happen */ return -EINVAL; } - if (count < (unsigned int)(channel + 1)) - count = (unsigned int)(channel + 1); - } - if (count > 0) { - array = (unsigned int *)calloc(count, sizeof(unsigned int)); - if (! array) - return -ENOMEM; - memset(array, 0xff, count * sizeof(unsigned int)); - io->port_bindings_size = count; - io->port_bindings = array; - snd_config_for_each(i, next, bindings) { - snd_config_t *n = snd_config_iterator_entry(i); - const char *id, *sport; - long channel, port; - if (snd_config_get_id(n, &id) < 0) - continue; - err = safe_strtol(id, &channel); - if (err < 0 || channel < 0) { - assert(0); /* should never happen */ - return -EINVAL; - } - err = snd_config_get_integer(n, &port); - if (err >= 0) { - err = snd_pcm_ladspa_find_port(&array[channel], lplug, io->pdesc | LADSPA_PORT_AUDIO, port); - if (err < 0) { - SNDERR("Unable to find an audio port (%li) for channel %s", port, id); - return err; - } - continue; - } - err = snd_config_get_string(n, &sport); - if (err < 0) { - SNDERR("Invalid LADSPA port field type for %s", id); - return -EINVAL; - } - err = snd_pcm_ladspa_find_sport(&array[channel], lplug, io->pdesc | LADSPA_PORT_AUDIO, sport); + err = snd_config_get_integer(n, &port); + if (err >= 0) { + err = snd_pcm_ladspa_find_port(&array[channel], lplug, io->pdesc | LADSPA_PORT_AUDIO, port); if (err < 0) { - SNDERR("Unable to find an audio port (%s) for channel %s", sport, id); + SNDERR("Unable to find an audio port (%li) for channel %s", port, id); return err; } + continue; + } + err = snd_config_get_string(n, &sport); + if (err < 0) { + SNDERR("Invalid LADSPA port field type for %s", id); + return -EINVAL; + } + err = snd_pcm_ladspa_find_sport(&array[channel], lplug, io->pdesc | LADSPA_PORT_AUDIO, sport); + if (err < 0) { + SNDERR("Unable to find an audio port (%s) for channel %s", sport, id); + return err; } } } - if (1) { - unsigned int count = 0; - LADSPA_Data *array; - unsigned char *initialized; - unsigned long idx; - for (idx = 0; idx < lplug->desc->PortCount; idx++) - if ((lplug->desc->PortDescriptors[idx] & (io->pdesc | LADSPA_PORT_CONTROL)) == (io->pdesc | LADSPA_PORT_CONTROL)) - count++; - array = (LADSPA_Data *)calloc(count, sizeof(LADSPA_Data)); - if (!array) - return -ENOMEM; - initialized = (unsigned char *)calloc(count, sizeof(unsigned char)); - if (!initialized) { - free(array); - return -ENOMEM; - } - io->controls_size = count; - io->controls_initialized = initialized; - io->controls = array; - if (!(io->pdesc & LADSPA_PORT_OUTPUT)) { - if (snd_config_get_type(controls) != SND_CONFIG_TYPE_COMPOUND) { - SNDERR("controls definition must be a compound"); - return -EINVAL; - } - snd_config_for_each(i, next, controls) { - snd_config_t *n = snd_config_iterator_entry(i); - const char *id; - long lval; - unsigned int port, uval; - double dval; - if (snd_config_get_id(n, &id) < 0) - continue; - err = safe_strtol(id, &lval); - if (err >= 0) { - err = snd_pcm_ladspa_find_port(&port, lplug, io->pdesc | LADSPA_PORT_CONTROL, lval); - } else { - err = snd_pcm_ladspa_find_sport(&port, lplug, io->pdesc | LADSPA_PORT_CONTROL, id); - } - if (err < 0) { - SNDERR("Unable to find an control port (%s)", id); - return err; - } - if (snd_config_get_ireal(n, &dval) < 0) { - SNDERR("Control port %s has not an float or integer value", id); - return err; - } - err = snd_pcm_ladspa_find_port_idx(&uval, lplug, io->pdesc | LADSPA_PORT_CONTROL, port); - if (err < 0) { - SNDERR("internal error"); - return err; - } - initialized[uval] = 1; - array[uval] = (LADSPA_Data)dval; - } - } + + return 0; +} + +static int snd_pcm_ladspa_parse_ioconfig(snd_pcm_ladspa_plugin_t *lplug, + snd_pcm_ladspa_plugin_io_t *io, + snd_config_t *conf) +{ + snd_config_iterator_t i, next; + snd_config_t *bindings = NULL, *controls = NULL; + int err; + + /* always add default controls for both input and output */ + err = snd_pcm_ladspa_add_default_controls(lplug, io); + if (err < 0) { + SNDERR("error adding default controls"); + return err; } + + if (conf == NULL) { + return 0; + } + + if (snd_config_get_type(conf) != SND_CONFIG_TYPE_COMPOUND) { + SNDERR("input or output definition must be a compound"); + return -EINVAL; + } + snd_config_for_each(i, next, conf) { + snd_config_t *n = snd_config_iterator_entry(i); + const char *id; + if (snd_config_get_id(n, &id) < 0) + continue; + if (strcmp(id, "bindings") == 0) { + bindings = n; + continue; + } + if (strcmp(id, "controls") == 0) { + controls = n; + continue; + } + } + + /* ignore values of parameters for output controls */ + if (controls && !(io->pdesc & LADSPA_PORT_OUTPUT)) { + err = snd_pcm_ladspa_parse_controls(lplug, io, controls); + if (err < 0) + return err; + } + + if (bindings) { + err = snd_pcm_ladspa_parse_bindings(lplug, io, bindings); + if (err < 0) + return err; + } + + return 0; }