* Remove erroneous snd_config_delete calls that cause later calls to snd_pcm_open to fail.
* Don't list card-independent PCM devices ("null" or PulseAudio, for example) more than once even if multiple sound cards are installed.
* Add "ctl" to the list of device types that snd_device_name_hint can search for.
* Cache the path to libasound.so within snd_dlopen rather than looking it up with dladdr every call.
For a longer explanation: http://mailman.alsa-project.org/pipermail/alsa-devel/2009-October/022505.htm...
Signed-off-by: John Lindgren john.lindgren@tds.net
------
src/conf.c | 2 -- src/control/namehint.c | 34 +++++++++++++++++++++++++++------- src/dlmisc.c | 10 +++++++--- 3 files changed, 34 insertions(+), 12 deletions(-)
------
diff --git a/src/conf.c b/src/conf.c index 570c90f..52a477c 100644 --- a/src/conf.c +++ b/src/conf.c @@ -1132,7 +1132,6 @@ static int parse_def(snd_config_t *parent, input_t *input, int skip, int overrid free(id); continue; } - snd_config_delete(n); } if (mode == MERGE) { SNDERR("%s does not exists", id); @@ -1156,7 +1155,6 @@ static int parse_def(snd_config_t *parent, input_t *input, int skip, int overrid skip = 1; n = NULL; } else if (mode == OVERRIDE) { - snd_config_delete(n); n = NULL; } } else { diff --git a/src/control/namehint.c b/src/control/namehint.c index e878f83..ec9d04f 100644 --- a/src/control/namehint.c +++ b/src/control/namehint.c @@ -328,7 +328,6 @@ static int try_config(struct hint_list *list, if (snd_config_search(cfg1, "slave", &cfg) >= 0 && snd_config_search(cfg, base, &cfg1) >= 0) goto __hint; - snd_config_delete(res); res = NULL; if (strchr(buf, ':') != NULL) goto __ok; @@ -379,8 +378,6 @@ static int try_config(struct hint_list *list, err = hint_list_add(list, buf, buf1); } __skip_add: - if (res) - snd_config_delete(res); if (buf1) free(buf1); free(buf); @@ -450,13 +447,10 @@ static int add_card(struct hint_list *list, int card) if (err == -EXDEV) continue; if (err < 0) { + list->card = card; list->device = -1; err = try_config(list, list->siface, str); } - if (err < 0) { - list->card = -1; - err = try_config(list, list->siface, str); - } if (err == -ENOMEM) goto __error; } @@ -466,6 +460,29 @@ static int add_card(struct hint_list *list, int card) return err; }
+static int add_software_devices(struct hint_list *list) +{ + int err; + snd_config_t *conf, *n; + snd_config_iterator_t i, next; + const char *str; + + err = snd_config_search(snd_config, list->siface, &conf); + if (err < 0) + return err; + snd_config_for_each(i, next, conf) { + n = snd_config_iterator_entry(i); + if (snd_config_get_id(n, &str) < 0) + continue; + list->card = -1; + list->device = -1; + err = try_config(list, list->siface, str); + if (err == -ENOMEM) + return -ENOMEM; + } + return 0; +} + static int get_card_name(struct hint_list *list, int card) { char scard[16], *s; @@ -532,6 +549,8 @@ int snd_device_name_hint(int card, const char *iface, void ***hints) list.iface = SND_CTL_ELEM_IFACE_SEQUENCER; else if (strcmp(iface, "hwdep") == 0) list.iface = SND_CTL_ELEM_IFACE_HWDEP; + else if (strcmp(iface, "ctl") == 0) + list.iface = SND_CTL_ELEM_IFACE_MIXER; else return -EINVAL; list.show_all = 0; @@ -543,6 +562,7 @@ int snd_device_name_hint(int card, const char *iface, void ***hints) if (err >= 0) err = add_card(&list, card); } else { + add_software_devices(&list); err = snd_card_next(&card); if (err < 0) goto __error; diff --git a/src/dlmisc.c b/src/dlmisc.c index c882cdc..3cca0f0 100644 --- a/src/dlmisc.c +++ b/src/dlmisc.c @@ -54,9 +54,13 @@ void *snd_dlopen(const char *name, int mode) #else #ifdef HAVE_LIBDL if (name == NULL) { - Dl_info dlinfo; - if (dladdr(snd_dlopen, &dlinfo) > 0) - name = dlinfo.dli_fname; + static const char * self = NULL; + if (self == NULL) { + Dl_info dlinfo; + if (dladdr(snd_dlopen, &dlinfo) > 0) + self = dlinfo.dli_fname; + } + name = self; } #endif #endif