# Slave PCM definition
pcm_slave.NAME {
pcm STR # PCM name
+ # or
+ pcm { } # PCM definition
format STR # Format
channels INT # Channels
rate INT # Rate
# or
slave { # Slave definition or name
pcm STR # Slave PCM name
+ # or
+ pcm { } # Slave PCM definition
}
ttable { # Transfer table (bidimensional compound of
# cchannels * schannels numbers)
# or
slave { # Slave definition or name
pcm STR # Slave PCM name
+ # or
+ pcm { } # Slave PCM definition
format STR # Slave format
}
# or
slave { # Slave definition or name
pcm STR # Slave PCM name
+ # or
+ pcm { } # Slave PCM definition
[format STR] # Slave format (default client format)
rate INT # Slave rate
}
# or
slave { # Slave definition or name
pcm STR # Slave PCM name
+ # or
+ pcm { } # Slave PCM definition
[format STR] # Slave format (default client format)
[channels INT] # Slave channels (default client channels)
}
# or
N { # Slave definition for slave N
pcm STR # Slave PCM name
+ # or
+ pcm { } # Slave PCM definition
channels INT # Slave channels
}
}
# or
slave { # Slave definition or name
pcm STR # Slave PCM name
+ # or
+ pcm { } # Slave PCM definition
}
file STR # File name
# or
# or
slave { # Slave definition or name
pcm STR # Slave PCM name
+ # or
+ pcm { } # Slave PCM definition
}
[frequency INT] # Updates per second
scopes { # Scopes
# or
slave { # Slave definition or name
pcm STR # Slave PCM name
+ # or
+ pcm { } # Slave PCM definition
[format STR] # Slave format (default client format)
[channels INT] # Slave channels (default client channels)
}
# or
slave { # Slave definition or name
pcm STR # Slave PCM name
+ # or
+ pcm { } # Slave PCM definition
}
return samples * pcm->sample_bits / 8;
}
-/**
- * \brief Opens a PCM
- * \param pcmp Returned PCM handle
- * \param name ASCII identifier of the PCM handle
- * \param stream Wanted stream
- * \param mode Open mode (see #SND_PCM_NONBLOCK, #SND_PCM_ASYNC)
- * \return 0 on success otherwise a negative error code
- */
-int snd_pcm_open(snd_pcm_t **pcmp, const char *name,
- snd_pcm_stream_t stream, int mode)
+static int snd_pcm_open_conf(snd_pcm_t **pcmp, const char *name,
+ snd_config_t *pcm_conf,
+ snd_pcm_stream_t stream, int mode)
{
const char *str;
char buf[256];
int err;
- snd_config_t *pcm_conf, *conf, *type_conf = NULL;
+ snd_config_t *conf, *type_conf = NULL;
snd_config_iterator_t i, next;
const char *lib = NULL, *open_name = NULL;
int (*open_func)(snd_pcm_t **, const char *, snd_config_t *,
snd_pcm_stream_t, int);
void *h;
- const char *name1;
- assert(pcmp && name);
- err = snd_config_update();
- if (err < 0)
+ if (snd_config_get_type(pcm_conf) != SND_CONFIG_TYPE_COMPOUND) {
+ if (name)
+ SNDERR("Invalid type for PCM %s definition", name);
+ else
+ SNDERR("Invalid type for PCM definition");
+ return -EINVAL;
+ }
+ err = snd_config_search(pcm_conf, "type", &conf);
+ if (err < 0) {
+ SNDERR("type is not defined");
+ return err;
+ }
+ err = snd_config_get_string(conf, &str);
+ if (err < 0) {
+ SNDERR("Invalid type for %s", snd_config_get_id(conf));
return err;
+ }
+ err = snd_config_search_alias(snd_config, "pcm_type", str, &type_conf);
+ if (err >= 0) {
+ if (snd_config_get_type(type_conf) != SND_CONFIG_TYPE_COMPOUND) {
+ SNDERR("Invalid type for PCM type %s definition", str);
+ return -EINVAL;
+ }
+ snd_config_for_each(i, next, type_conf) {
+ snd_config_t *n = snd_config_iterator_entry(i);
+ const char *id = snd_config_get_id(n);
+ if (strcmp(id, "comment") == 0)
+ continue;
+ if (strcmp(id, "lib") == 0) {
+ err = snd_config_get_string(n, &lib);
+ if (err < 0) {
+ SNDERR("Invalid type for %s", id);
+ return -EINVAL;
+ }
+ continue;
+ }
+ if (strcmp(id, "open") == 0) {
+ err = snd_config_get_string(n, &open_name);
+ if (err < 0) {
+ SNDERR("Invalid type for %s", id);
+ return -EINVAL;
+ }
+ continue;
+ }
+ SNDERR("Unknown field %s", id);
+ return -EINVAL;
+ }
+ }
+ if (!open_name) {
+ open_name = buf;
+ snprintf(buf, sizeof(buf), "_snd_pcm_%s_open", str);
+ }
+ if (!lib)
+ lib = "libasound.so";
+ h = dlopen(lib, RTLD_NOW);
+ if (!h) {
+ SNDERR("Cannot open shared library %s", lib);
+ return -ENOENT;
+ }
+ open_func = dlsym(h, open_name);
+ if (!open_func) {
+ SNDERR("symbol %s is not defined inside %s", open_name, lib);
+ dlclose(h);
+ return -ENXIO;
+ }
+ return open_func(pcmp, name, pcm_conf, stream, mode);
+}
+
+static int snd_pcm_open_noupdate(snd_pcm_t **pcmp, const char *name,
+ snd_pcm_stream_t stream, int mode)
+{
+ int err;
+ snd_config_t *pcm_conf;
+ const char *name1;
err = snd_config_search_alias(snd_config, "pcm", name, &pcm_conf);
name1 = name;
SNDERR("Unknown PCM %s", name1);
return -ENOENT;
}
- if (snd_config_get_type(pcm_conf) != SND_CONFIG_TYPE_COMPOUND) {
- SNDERR("Invalid type for PCM %s definition", name1);
- return -EINVAL;
- }
- err = snd_config_search(pcm_conf, "type", &conf);
- if (err < 0) {
- SNDERR("type is not defined");
- return err;
- }
- err = snd_config_get_string(conf, &str);
- if (err < 0) {
- SNDERR("Invalid type for %s", snd_config_get_id(conf));
+ return snd_pcm_open_conf(pcmp, name, pcm_conf, stream, mode);
+}
+
+#ifndef DOC_HIDDEN
+int snd_pcm_open_slave(snd_pcm_t **pcmp, snd_config_t *conf,
+ snd_pcm_stream_t stream, int mode)
+{
+ const char *str;
+ if (snd_config_get_string(conf, &str) >= 0)
+ return snd_pcm_open_noupdate(pcmp, str, stream, mode);
+ return snd_pcm_open_conf(pcmp, NULL, conf, stream, mode);
+}
+#endif
+
+/**
+ * \brief Opens a PCM
+ * \param pcmp Returned PCM handle
+ * \param name ASCII identifier of the PCM handle
+ * \param stream Wanted stream
+ * \param mode Open mode (see #SND_PCM_NONBLOCK, #SND_PCM_ASYNC)
+ * \return 0 on success otherwise a negative error code
+ */
+int snd_pcm_open(snd_pcm_t **pcmp, const char *name,
+ snd_pcm_stream_t stream, int mode)
+{
+ int err;
+ assert(pcmp && name);
+ err = snd_config_update();
+ if (err < 0)
return err;
- }
- err = snd_config_search_alias(snd_config, "pcm_type", str, &type_conf);
- if (err >= 0) {
- if (snd_config_get_type(type_conf) != SND_CONFIG_TYPE_COMPOUND) {
- SNDERR("Invalid type for PCM type %s definition", str);
- return -EINVAL;
- }
- snd_config_for_each(i, next, type_conf) {
- snd_config_t *n = snd_config_iterator_entry(i);
- const char *id = snd_config_get_id(n);
- if (strcmp(id, "comment") == 0)
- continue;
- if (strcmp(id, "lib") == 0) {
- err = snd_config_get_string(n, &lib);
- if (err < 0) {
- SNDERR("Invalid type for %s", id);
- return -EINVAL;
- }
- continue;
- }
- if (strcmp(id, "open") == 0) {
- err = snd_config_get_string(n, &open_name);
- if (err < 0) {
- SNDERR("Invalid type for %s", id);
- return -EINVAL;
- }
- continue;
- }
- SNDERR("Unknown field %s", id);
- return -EINVAL;
- }
- }
- if (!open_name) {
- open_name = buf;
- snprintf(buf, sizeof(buf), "_snd_pcm_%s_open", str);
- }
- if (!lib)
- lib = "libasound.so";
- h = dlopen(lib, RTLD_NOW);
- if (!h) {
- SNDERR("Cannot open shared library %s", lib);
- return -ENOENT;
- }
- open_func = dlsym(h, open_name);
- if (!open_func) {
- SNDERR("symbol %s is not defined inside %s", open_name, lib);
- dlclose(h);
- return -ENXIO;
- }
- return open_func(pcmp, name, pcm_conf, stream, mode);
+ return snd_pcm_open_noupdate(pcmp, name, stream, mode);
}
/**
[SND_PCM_HW_PARAM_BUFFER_TIME] = "buffer_time"
};
-int snd_pcm_slave_conf(snd_config_t *conf, const char **namep,
+int snd_pcm_slave_conf(snd_config_t *conf, snd_config_t **pcm_conf,
unsigned int count, ...)
{
snd_config_iterator_t i, next;
if (strcmp(id, "comment") == 0)
continue;
if (strcmp(id, "pcm") == 0) {
- if (pcm_valid) {
- _duplicated:
- SNDERR("duplicated %s", id);
- return -EINVAL;
- }
- err = snd_config_get_string(n, namep);
- if (err < 0) {
- _invalid:
- SNDERR("invalid type for %s", id);
- return err;
- }
+ *pcm_conf = n;
pcm_valid = 1;
continue;
}
assert(names[idx]);
if (strcmp(id, names[idx]) != 0)
continue;
- if (fields[k].valid)
- goto _duplicated;
switch (idx) {
case SND_PCM_HW_PARAM_FORMAT:
{
snd_pcm_format_t f;
err = snd_config_get_string(n, &str);
- if (err < 0)
- goto _invalid;
+ if (err < 0) {
+ _invalid:
+ SNDERR("invalid type for %s", id);
+ return err;
+ }
f = snd_pcm_format_value(str);
if (f == SND_PCM_FORMAT_UNKNOWN) {
SNDERR("unknown format");
SNDERR("Unknown field %s", id);
return -EINVAL;
}
+ if (!pcm_valid) {
+ SNDERR("missing field pcm");
+ return -EINVAL;
+ }
for (k = 0; k < count; ++k) {
if (fields[k].mandatory && !fields[k].valid) {
SNDERR("missing field %s", names[fields[k].index]);
snd_pcm_stream_t stream, int mode)
{
snd_config_iterator_t i, next;
- const char *sname = NULL;
int err;
snd_pcm_t *spcm;
- snd_config_t *slave = NULL;
+ snd_config_t *slave = NULL, *sconf;
snd_pcm_format_t sformat;
snd_config_for_each(i, next, conf) {
snd_config_t *n = snd_config_iterator_entry(i);
SNDERR("slave is not defined");
return -EINVAL;
}
- err = snd_pcm_slave_conf(slave, &sname, 1,
+ err = snd_pcm_slave_conf(slave, &sconf, 1,
SND_PCM_HW_PARAM_FORMAT, 1, &sformat);
if (err < 0)
return err;
SNDERR("invalid slave format");
return -EINVAL;
}
- /* This is needed cause snd_config_update may destroy config */
- sname = strdup(sname);
- if (!sname)
- return -ENOMEM;
- err = snd_pcm_open(&spcm, sname, stream, mode);
- free((void *) sname);
+ err = snd_pcm_open_slave(&spcm, sconf, stream, mode);
if (err < 0)
return err;
err = snd_pcm_adpcm_open(pcmp, name, sformat, spcm, 1);
snd_pcm_stream_t stream, int mode)
{
snd_config_iterator_t i, next;
- const char *sname = NULL;
int err;
snd_pcm_t *spcm;
- snd_config_t *slave = NULL;
+ snd_config_t *slave = NULL, *sconf;
snd_pcm_format_t sformat;
snd_config_for_each(i, next, conf) {
snd_config_t *n = snd_config_iterator_entry(i);
SNDERR("slave is not defined");
return -EINVAL;
}
- err = snd_pcm_slave_conf(slave, &sname, 1,
+ err = snd_pcm_slave_conf(slave, &sconf, 1,
SND_PCM_HW_PARAM_FORMAT, 1, &sformat);
if (err < 0)
return err;
SNDERR("invalid slave format");
return -EINVAL;
}
- /* This is needed cause snd_config_update may destroy config */
- sname = strdup(sname);
- if (!sname)
- return -ENOMEM;
- err = snd_pcm_open(&spcm, sname, stream, mode);
- free((void *) sname);
+ err = snd_pcm_open_slave(&spcm, sconf, stream, mode);
if (err < 0)
return err;
err = snd_pcm_alaw_open(pcmp, name, sformat, spcm, 1);
}
int _snd_pcm_copy_open(snd_pcm_t **pcmp, const char *name,
- snd_config_t *conf,
- snd_pcm_stream_t stream, int mode)
+ snd_config_t *conf,
+ snd_pcm_stream_t stream, int mode)
{
snd_config_iterator_t i, next;
- const char *sname = NULL;
int err;
snd_pcm_t *spcm;
- snd_config_t *slave = NULL;
+ snd_config_t *slave = NULL, *sconf;
snd_config_for_each(i, next, conf) {
snd_config_t *n = snd_config_iterator_entry(i);
const char *id = snd_config_get_id(n);
SNDERR("slave is not defined");
return -EINVAL;
}
- err = snd_pcm_slave_conf(slave, &sname, 0);
+ err = snd_pcm_slave_conf(slave, &sconf, 0);
if (err < 0)
return err;
- /* This is needed cause snd_config_update may destroy config */
- sname = strdup(sname);
- if (!sname)
- return -ENOMEM;
- err = snd_pcm_open(&spcm, sname, stream, mode);
- free((void *) sname);
+ err = snd_pcm_open_slave(&spcm, sconf, stream, mode);
if (err < 0)
return err;
err = snd_pcm_copy_open(pcmp, name, spcm, 1);
snd_pcm_stream_t stream, int mode)
{
snd_config_iterator_t i, next;
- const char *sname = NULL;
int err;
snd_pcm_t *spcm;
- snd_config_t *slave = NULL;
+ snd_config_t *slave = NULL, *sconf;
const char *fname = NULL;
const char *format = NULL;
long fd = -1;
SNDERR("slave is not defined");
return -EINVAL;
}
- err = snd_pcm_slave_conf(slave, &sname, 0);
+ err = snd_pcm_slave_conf(slave, &sconf, 0);
if (err < 0)
return err;
if (!fname && fd < 0) {
SNDERR("file is not defined");
return -EINVAL;
}
- /* This is needed cause snd_config_update may destroy config */
- sname = strdup(sname);
- if (!sname)
- return -ENOMEM;
- err = snd_pcm_open(&spcm, sname, stream, mode);
- free((void *) sname);
+ err = snd_pcm_open_slave(&spcm, sconf, stream, mode);
if (err < 0)
return err;
err = snd_pcm_file_open(pcmp, name, fname, fd, format, spcm, 1);
snd_pcm_stream_t stream, int mode)
{
snd_config_iterator_t i, next;
- const char *sname;
int err;
snd_pcm_t *spcm;
- snd_config_t *slave = NULL;
+ snd_config_t *slave = NULL, *sconf;
snd_pcm_format_t sformat;
snd_config_for_each(i, next, conf) {
snd_config_t *n = snd_config_iterator_entry(i);
SNDERR("slave is not defined");
return -EINVAL;
}
- err = snd_pcm_slave_conf(slave, &sname, 1,
+ err = snd_pcm_slave_conf(slave, &sconf, 1,
SND_PCM_HW_PARAM_FORMAT, 1, &sformat);
if (err < 0)
return err;
SNDERR("slave format is not linear");
return -EINVAL;
}
- /* This is needed cause snd_config_update may destroy config */
- sname = strdup(sname);
- if (!sname)
- return -ENOMEM;
- err = snd_pcm_open(&spcm, sname, stream, mode);
- free((void *) sname);
+ err = snd_pcm_open_slave(&spcm, sconf, stream, mode);
if (err < 0)
return err;
err = snd_pcm_linear_open(pcmp, name, sformat, spcm, 1);
snd_pcm_hw_strategy_simple_choices_list_t *choices);
#endif
-int snd_pcm_slave_conf(snd_config_t *conf, const char **namep,
+int snd_pcm_slave_conf(snd_config_t *conf, snd_config_t **pcm_conf,
unsigned int count, ...);
+int snd_pcm_open_slave(snd_pcm_t **pcmp, snd_config_t *conf,
+ snd_pcm_stream_t stream, int mode);
+
#define SND_PCM_HW_PARBIT_ACCESS (1U << SND_PCM_HW_PARAM_ACCESS)
#define SND_PCM_HW_PARBIT_FORMAT (1U << SND_PCM_HW_PARAM_FORMAT)
#define SND_PCM_HW_PARBIT_SUBFORMAT (1U << SND_PCM_HW_PARAM_SUBFORMAT)
snd_pcm_stream_t stream, int mode)
{
snd_config_iterator_t i, next;
- const char *sname = NULL;
int err;
snd_pcm_t *spcm;
- snd_config_t *slave = NULL;
+ snd_config_t *slave = NULL, *sconf;
long frequency = -1;
snd_config_t *scopes = NULL;
snd_config_for_each(i, next, conf) {
SNDERR("slave is not defined");
return -EINVAL;
}
- err = snd_pcm_slave_conf(slave, &sname, 0);
+ err = snd_pcm_slave_conf(slave, &sconf, 0);
if (err < 0)
return err;
- /* This is needed cause snd_config_update may destroy config */
- sname = strdup(sname);
- if (!sname)
- return -ENOMEM;
- err = snd_pcm_open(&spcm, sname, stream, mode);
- free((void *) sname);
+ err = snd_pcm_open_slave(&spcm, sconf, stream, mode);
if (err < 0)
return err;
err = snd_pcm_meter_open(pcmp, name, frequency > 0 ? (unsigned int) frequency : FREQUENCY, spcm, 1);
snd_pcm_stream_t stream, int mode)
{
snd_config_iterator_t i, next;
- const char *sname = NULL;
int err;
snd_pcm_t *spcm;
- snd_config_t *slave = NULL;
+ snd_config_t *slave = NULL, *sconf;
snd_pcm_format_t sformat;
snd_config_for_each(i, next, conf) {
snd_config_t *n = snd_config_iterator_entry(i);
SNDERR("slave is not defined");
return -EINVAL;
}
- err = snd_pcm_slave_conf(slave, &sname, 1,
+ err = snd_pcm_slave_conf(slave, &sconf, 1,
SND_PCM_HW_PARAM_FORMAT, 1, &sformat);
if (err < 0)
return err;
SNDERR("invalid slave format");
return -EINVAL;
}
- /* This is needed cause snd_config_update may destroy config */
- sname = strdup(sname);
- if (!sname)
- return -ENOMEM;
- err = snd_pcm_open(&spcm, sname, stream, mode);
- free((void *) sname);
+ err = snd_pcm_open_slave(&spcm, sconf, stream, mode);
if (err < 0)
return err;
err = snd_pcm_mulaw_open(pcmp, name, sformat, spcm, 1);
int err;
unsigned int idx;
const char **slaves_id = NULL;
- char **slaves_name = NULL;
+ snd_config_t **slaves_conf = NULL;
snd_pcm_t **slaves_pcm = NULL;
unsigned int *slaves_channels = NULL;
int *channels_sidx = NULL;
return -EINVAL;
}
slaves_id = calloc(slaves_count, sizeof(*slaves_id));
- slaves_name = calloc(slaves_count, sizeof(*slaves_name));
+ slaves_conf = calloc(slaves_count, sizeof(*slaves_conf));
slaves_pcm = calloc(slaves_count, sizeof(*slaves_pcm));
slaves_channels = calloc(slaves_count, sizeof(*slaves_channels));
channels_sidx = calloc(channels_count, sizeof(*channels_sidx));
idx = 0;
snd_config_for_each(i, inext, slaves) {
snd_config_t *m = snd_config_iterator_entry(i);
- const char *n;
int channels;
slaves_id[idx] = snd_config_get_id(m);
- err = snd_pcm_slave_conf(m, &n, 1,
+ err = snd_pcm_slave_conf(m, &slaves_conf[idx], 1,
SND_PCM_HW_PARAM_CHANNELS, 1, &channels);
if (err < 0)
goto _free;
- slaves_name[idx] = strdup(n);
slaves_channels[idx] = channels;
++idx;
}
}
for (idx = 0; idx < slaves_count; ++idx) {
- err = snd_pcm_open(&slaves_pcm[idx], slaves_name[idx], stream, mode);
+ err = snd_pcm_open_slave(&slaves_pcm[idx], slaves_conf[idx], stream, mode);
if (err < 0)
goto _free;
}
for (idx = 0; idx < slaves_count; ++idx) {
if (slaves_pcm[idx])
snd_pcm_close(slaves_pcm[idx]);
- if (slaves_name[idx])
- free(slaves_name[idx]);
}
}
- if (slaves_name)
- free(slaves_name);
+ if (slaves_conf)
+ free(slaves_conf);
if (slaves_pcm)
free(slaves_pcm);
if (slaves_channels)
snd_pcm_stream_t stream, int mode)
{
snd_config_iterator_t i, next;
- const char *sname = NULL;
int err;
snd_pcm_t *spcm;
- snd_config_t *slave = NULL;
+ snd_config_t *slave = NULL, *sconf;
snd_config_t *tt = NULL;
snd_pcm_route_ttable_entry_t *ttable = NULL;
unsigned int cused, sused;
SNDERR("slave is not defined");
return -EINVAL;
}
- err = snd_pcm_slave_conf(slave, &sname, 0);
+ err = snd_pcm_slave_conf(slave, &sconf, 0);
if (err < 0)
return err;
if (tt) {
return err;
}
- /* This is needed cause snd_config_update may destroy config */
- sname = strdup(sname);
- if (!sname)
- return -ENOMEM;
- err = snd_pcm_open(&spcm, sname, stream, mode);
- free((void *) sname);
+ err = snd_pcm_open_slave(&spcm, sconf, stream, mode);
if (err < 0)
return err;
err = snd_pcm_plug_open(pcmp, name, ttable, MAX_CHANNELS, cused, sused, spcm, 1);
snd_pcm_stream_t stream, int mode)
{
snd_config_iterator_t i, next;
- const char *sname = NULL;
int err;
snd_pcm_t *spcm;
- snd_config_t *slave = NULL;
+ snd_config_t *slave = NULL, *sconf;
snd_pcm_format_t sformat = SND_PCM_FORMAT_UNKNOWN;
int srate = -1;
snd_config_for_each(i, next, conf) {
SNDERR("slave is not defined");
return -EINVAL;
}
- err = snd_pcm_slave_conf(slave, &sname, 2,
+ err = snd_pcm_slave_conf(slave, &sconf, 2,
SND_PCM_HW_PARAM_FORMAT, 0, &sformat,
SND_PCM_HW_PARAM_RATE, 1, &srate);
if (err < 0)
SNDERR("slave format is not linear");
return -EINVAL;
}
- /* This is needed cause snd_config_update may destroy config */
- sname = strdup(sname);
- if (!sname)
- return -ENOMEM;
- err = snd_pcm_open(&spcm, sname, stream, mode);
- free((void *) sname);
+ err = snd_pcm_open_slave(&spcm, sconf, stream, mode);
if (err < 0)
return err;
err = snd_pcm_rate_open(pcmp, name,
snd_pcm_stream_t stream, int mode)
{
snd_config_iterator_t i, next;
- const char *sname = NULL;
int err;
snd_pcm_t *spcm;
- snd_config_t *slave = NULL;
+ snd_config_t *slave = NULL, *sconf;
snd_pcm_format_t sformat = SND_PCM_FORMAT_UNKNOWN;
int schannels = -1;
snd_config_t *tt = NULL;
SNDERR("ttable is not defined");
return -EINVAL;
}
- err = snd_pcm_slave_conf(slave, &sname, 2,
+ err = snd_pcm_slave_conf(slave, &sconf, 2,
SND_PCM_HW_PARAM_FORMAT, 0, &sformat,
SND_PCM_HW_PARAM_CHANNELS, 0, &schannels);
if (err < 0)
if (err < 0)
return err;
- /* This is needed cause snd_config_update may destroy config */
- sname = strdup(sname);
- if (!sname)
- return -ENOMEM;
- err = snd_pcm_open(&spcm, sname, stream, mode);
- free((void *) sname);
+ err = snd_pcm_open_slave(&spcm, sconf, stream, mode);
if (err < 0)
return err;
err = snd_pcm_route_open(pcmp, name, sformat, schannels,
snd_pcm_stream_t stream, int mode)
{
snd_config_iterator_t i, next;
- const char *sname = NULL;
+ const char *slave_name = NULL;
+ const char *sname;
snd_config_t *bindings = NULL;
int err;
- snd_config_t *slave = NULL;
+ snd_config_t *slave = NULL, *sconf;
unsigned int *channels_map;
unsigned int channels = 0;
snd_pcm_format_t sformat = SND_PCM_FORMAT_UNKNOWN;
if (strcmp(id, "type") == 0)
continue;
if (strcmp(id, "slave") == 0) {
- err = snd_config_get_string(n, &sname);
+ err = snd_config_get_string(n, &slave_name);
if (err < 0) {
SNDERR("Invalid type for %s", id);
return -EINVAL;
SNDERR("slave is not defined");
return -EINVAL;
}
- err = snd_pcm_slave_conf(slave, &sname, 5,
+ err = snd_pcm_slave_conf(slave, &sconf, 5,
SND_PCM_HW_PARAM_CHANNELS, 0, &schannels,
SND_PCM_HW_PARAM_FORMAT, 0, &sformat,
SND_PCM_HW_PARAM_RATE, 0, &srate,
SND_PCM_HW_PARAM_BUFFER_TIME, 0, &sbuffer_time);
if (err < 0)
return err;
+
+ /* FIXME: nothing strictly forces to have named definition */
+ err = snd_config_get_string(sconf, &sname);
+ if (err < 0) {
+ SNDERR("slave.pcm is not a string");
+ return err;
+ }
+
if (!bindings) {
SNDERR("bindings is not defined");
return -EINVAL;
}
if (schannels <= 0)
schannels = schannel_max + 1;
- err = snd_pcm_share_open(pcmp, name, sname, sformat, srate,
- (unsigned int) schannels,
- speriod_time, sbuffer_time,
- channels, channels_map, stream, mode);
+ err = snd_pcm_share_open(pcmp, name, sname, sformat, srate,
+ (unsigned int) schannels,
+ speriod_time, sbuffer_time,
+ channels, channels_map, stream, mode);
_free:
free(channels_map);
return err;