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;
}