From 6cb24e0186a5d3df3958be9a46445c8bafa474a2 Mon Sep 17 00:00:00 2001 From: Abramo Bagnara Date: Mon, 14 May 2001 15:44:37 +0000 Subject: [PATCH] Added embedded/anonymous slave PCM definition --- doc/asoundrc.doc | 20 +++++ src/pcm/pcm.c | 211 ++++++++++++++++++++++++++++----------------------- src/pcm/pcm_adpcm.c | 12 +-- src/pcm/pcm_alaw.c | 12 +-- src/pcm/pcm_copy.c | 16 ++-- src/pcm/pcm_file.c | 12 +-- src/pcm/pcm_linear.c | 12 +-- src/pcm/pcm_local.h | 5 +- src/pcm/pcm_meter.c | 12 +-- src/pcm/pcm_mulaw.c | 12 +-- src/pcm/pcm_multi.c | 16 ++-- src/pcm/pcm_plug.c | 12 +-- src/pcm/pcm_rate.c | 12 +-- src/pcm/pcm_route.c | 12 +-- src/pcm/pcm_share.c | 25 ++++-- 15 files changed, 197 insertions(+), 204 deletions(-) diff --git a/doc/asoundrc.doc b/doc/asoundrc.doc index 0033b5de..143a9afc 100644 --- a/doc/asoundrc.doc +++ b/doc/asoundrc.doc @@ -21,6 +21,8 @@ pcm_scope_type.NAME { # Slave PCM definition pcm_slave.NAME { pcm STR # PCM name + # or + pcm { } # PCM definition format STR # Format channels INT # Channels rate INT # Rate @@ -46,6 +48,8 @@ pcm.NAME { # 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) @@ -63,6 +67,8 @@ pcm.NAME { # or slave { # Slave definition or name pcm STR # Slave PCM name + # or + pcm { } # Slave PCM definition format STR # Slave format } @@ -72,6 +78,8 @@ pcm.NAME { # 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 } @@ -82,6 +90,8 @@ pcm.NAME { # 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) } @@ -99,6 +109,8 @@ pcm.NAME { # or N { # Slave definition for slave N pcm STR # Slave PCM name + # or + pcm { } # Slave PCM definition channels INT # Slave channels } } @@ -115,6 +127,8 @@ pcm.NAME { # or slave { # Slave definition or name pcm STR # Slave PCM name + # or + pcm { } # Slave PCM definition } file STR # File name # or @@ -127,6 +141,8 @@ pcm.NAME { # or slave { # Slave definition or name pcm STR # Slave PCM name + # or + pcm { } # Slave PCM definition } [frequency INT] # Updates per second scopes { # Scopes @@ -142,6 +158,8 @@ pcm.NAME { # 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) } @@ -165,6 +183,8 @@ pcm.NAME { # or slave { # Slave definition or name pcm STR # Slave PCM name + # or + pcm { } # Slave PCM definition } diff --git a/src/pcm/pcm.c b/src/pcm/pcm.c index 23185aeb..9890235a 100644 --- a/src/pcm/pcm.c +++ b/src/pcm/pcm.c @@ -909,31 +909,93 @@ ssize_t snd_pcm_samples_to_bytes(snd_pcm_t *pcm, int samples) 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; @@ -1005,69 +1067,37 @@ int snd_pcm_open(snd_pcm_t **pcmp, const char *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); } /** @@ -4281,7 +4311,7 @@ static const char *names[SND_PCM_HW_PARAM_LAST + 1] = { [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; @@ -4317,17 +4347,7 @@ int snd_pcm_slave_conf(snd_config_t *conf, const char **namep, 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; } @@ -4338,15 +4358,16 @@ int snd_pcm_slave_conf(snd_config_t *conf, const char **namep, 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"); @@ -4370,6 +4391,10 @@ int snd_pcm_slave_conf(snd_config_t *conf, const char **namep, 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]); diff --git a/src/pcm/pcm_adpcm.c b/src/pcm/pcm_adpcm.c index 67228155..69e25095 100644 --- a/src/pcm/pcm_adpcm.c +++ b/src/pcm/pcm_adpcm.c @@ -552,10 +552,9 @@ int _snd_pcm_adpcm_open(snd_pcm_t **pcmp, const char *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_config_for_each(i, next, conf) { snd_config_t *n = snd_config_iterator_entry(i); @@ -575,7 +574,7 @@ int _snd_pcm_adpcm_open(snd_pcm_t **pcmp, const char *name, 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; @@ -584,12 +583,7 @@ int _snd_pcm_adpcm_open(snd_pcm_t **pcmp, const char *name, 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); diff --git a/src/pcm/pcm_alaw.c b/src/pcm/pcm_alaw.c index aecd52fa..e2d57cfe 100644 --- a/src/pcm/pcm_alaw.c +++ b/src/pcm/pcm_alaw.c @@ -425,10 +425,9 @@ int _snd_pcm_alaw_open(snd_pcm_t **pcmp, const char *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_config_for_each(i, next, conf) { snd_config_t *n = snd_config_iterator_entry(i); @@ -448,7 +447,7 @@ int _snd_pcm_alaw_open(snd_pcm_t **pcmp, const char *name, 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; @@ -457,12 +456,7 @@ int _snd_pcm_alaw_open(snd_pcm_t **pcmp, const char *name, 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); diff --git a/src/pcm/pcm_copy.c b/src/pcm/pcm_copy.c index 64f33c78..a9f85b88 100644 --- a/src/pcm/pcm_copy.c +++ b/src/pcm/pcm_copy.c @@ -191,14 +191,13 @@ int snd_pcm_copy_open(snd_pcm_t **pcmp, const char *name, snd_pcm_t *slave, int } 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); @@ -217,15 +216,10 @@ int _snd_pcm_copy_open(snd_pcm_t **pcmp, const char *name, 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); diff --git a/src/pcm/pcm_file.c b/src/pcm/pcm_file.c index a979914c..9e378e0e 100644 --- a/src/pcm/pcm_file.c +++ b/src/pcm/pcm_file.c @@ -457,10 +457,9 @@ int _snd_pcm_file_open(snd_pcm_t **pcmp, const char *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; const char *fname = NULL; const char *format = NULL; long fd = -1; @@ -501,19 +500,14 @@ int _snd_pcm_file_open(snd_pcm_t **pcmp, const char *name, 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); diff --git a/src/pcm/pcm_linear.c b/src/pcm/pcm_linear.c index 3c25b6ac..d4f9cb75 100644 --- a/src/pcm/pcm_linear.c +++ b/src/pcm/pcm_linear.c @@ -330,10 +330,9 @@ int _snd_pcm_linear_open(snd_pcm_t **pcmp, const char *name, 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); @@ -353,7 +352,7 @@ int _snd_pcm_linear_open(snd_pcm_t **pcmp, const char *name, 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; @@ -361,12 +360,7 @@ int _snd_pcm_linear_open(snd_pcm_t **pcmp, const char *name, 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); diff --git a/src/pcm/pcm_local.h b/src/pcm/pcm_local.h index 2a1b5bcd..af827976 100644 --- a/src/pcm/pcm_local.h +++ b/src/pcm/pcm_local.h @@ -527,9 +527,12 @@ int snd_pcm_hw_strategy_simple_choices(snd_pcm_hw_strategy_t *strategy, int orde 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) diff --git a/src/pcm/pcm_meter.c b/src/pcm/pcm_meter.c index 01aefcf1..28bbe667 100644 --- a/src/pcm/pcm_meter.c +++ b/src/pcm/pcm_meter.c @@ -716,10 +716,9 @@ int _snd_pcm_meter_open(snd_pcm_t **pcmp, const char *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; long frequency = -1; snd_config_t *scopes = NULL; snd_config_for_each(i, next, conf) { @@ -756,15 +755,10 @@ int _snd_pcm_meter_open(snd_pcm_t **pcmp, const char *name, 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); diff --git a/src/pcm/pcm_mulaw.c b/src/pcm/pcm_mulaw.c index 9450faad..9f307937 100644 --- a/src/pcm/pcm_mulaw.c +++ b/src/pcm/pcm_mulaw.c @@ -440,10 +440,9 @@ int _snd_pcm_mulaw_open(snd_pcm_t **pcmp, const char *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_config_for_each(i, next, conf) { snd_config_t *n = snd_config_iterator_entry(i); @@ -463,7 +462,7 @@ int _snd_pcm_mulaw_open(snd_pcm_t **pcmp, const char *name, 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; @@ -472,12 +471,7 @@ int _snd_pcm_mulaw_open(snd_pcm_t **pcmp, const char *name, 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); diff --git a/src/pcm/pcm_multi.c b/src/pcm/pcm_multi.c index aa6b6326..65e0d454 100644 --- a/src/pcm/pcm_multi.c +++ b/src/pcm/pcm_multi.c @@ -655,7 +655,7 @@ int _snd_pcm_multi_open(snd_pcm_t **pcmp, const char *name, snd_config_t *conf, 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; @@ -718,7 +718,7 @@ int _snd_pcm_multi_open(snd_pcm_t **pcmp, const char *name, snd_config_t *conf, 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)); @@ -729,14 +729,12 @@ int _snd_pcm_multi_open(snd_pcm_t **pcmp, const char *name, snd_config_t *conf, 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; } @@ -807,7 +805,7 @@ int _snd_pcm_multi_open(snd_pcm_t **pcmp, const char *name, snd_config_t *conf, } 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; } @@ -821,12 +819,10 @@ _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) diff --git a/src/pcm/pcm_plug.c b/src/pcm/pcm_plug.c index c2454b15..3c18d719 100644 --- a/src/pcm/pcm_plug.c +++ b/src/pcm/pcm_plug.c @@ -715,10 +715,9 @@ int _snd_pcm_plug_open(snd_pcm_t **pcmp, const char *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_config_t *tt = NULL; snd_pcm_route_ttable_entry_t *ttable = NULL; unsigned int cused, sused; @@ -748,7 +747,7 @@ int _snd_pcm_plug_open(snd_pcm_t **pcmp, const char *name, 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) { @@ -759,12 +758,7 @@ int _snd_pcm_plug_open(snd_pcm_t **pcmp, const char *name, 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); diff --git a/src/pcm/pcm_rate.c b/src/pcm/pcm_rate.c index c87589f2..236532d8 100644 --- a/src/pcm/pcm_rate.c +++ b/src/pcm/pcm_rate.c @@ -539,10 +539,9 @@ int _snd_pcm_rate_open(snd_pcm_t **pcmp, const char *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 srate = -1; snd_config_for_each(i, next, conf) { @@ -563,7 +562,7 @@ int _snd_pcm_rate_open(snd_pcm_t **pcmp, const char *name, 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) @@ -573,12 +572,7 @@ int _snd_pcm_rate_open(snd_pcm_t **pcmp, const char *name, 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, diff --git a/src/pcm/pcm_route.c b/src/pcm/pcm_route.c index d4f33e7b..95299f55 100644 --- a/src/pcm/pcm_route.c +++ b/src/pcm/pcm_route.c @@ -843,10 +843,9 @@ int _snd_pcm_route_open(snd_pcm_t **pcmp, const char *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; @@ -882,7 +881,7 @@ int _snd_pcm_route_open(snd_pcm_t **pcmp, const char *name, 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) @@ -898,12 +897,7 @@ int _snd_pcm_route_open(snd_pcm_t **pcmp, const char *name, 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, diff --git a/src/pcm/pcm_share.c b/src/pcm/pcm_share.c index 69e78b71..c1ca99b2 100644 --- a/src/pcm/pcm_share.c +++ b/src/pcm/pcm_share.c @@ -1371,10 +1371,11 @@ int _snd_pcm_share_open(snd_pcm_t **pcmp, const char *name, snd_config_t *conf, 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; @@ -1391,7 +1392,7 @@ int _snd_pcm_share_open(snd_pcm_t **pcmp, const char *name, snd_config_t *conf, 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; @@ -1414,7 +1415,7 @@ int _snd_pcm_share_open(snd_pcm_t **pcmp, const char *name, snd_config_t *conf, 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, @@ -1422,6 +1423,14 @@ int _snd_pcm_share_open(snd_pcm_t **pcmp, const char *name, snd_config_t *conf, 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; @@ -1463,10 +1472,10 @@ int _snd_pcm_share_open(snd_pcm_t **pcmp, const char *name, snd_config_t *conf, } 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; -- 2.11.0