Looks like the documented behaviour was broken in commit 1ba513f9 in 2006, with the introduction of multiple fields.
I've chosen to match the described behaviour. Prior to this patch, using namehint could be made to work by exploiting the lack of escaping of the "name", populating the other fields:
"plug:front|DESCDo all conversions for front speakers"
rather than that which is documented and presumed to be the intention for asoundrc files:
"plug:front|Do all conversions for front speakers"
Everything seems to strongly suggest nobody is using this feature; I can find no working examples through a web search and probably someone would have hit this bug. It's not documented in configuration, only in the snd_device_name_hint() call. So it would probably clutter things to provide compatibility for the old behaviour.
I have found it to be very useful since working in Chromium, where it is the only way to expose chosen ALSA devices to web applications.
A temporary buffer is required to null-terminate the string. I see no use of alloca() in the code, presumably to avoid unbounded stack size. So memory is allocated on the heap.
Signed-off-by: Mark Hills mark@xwax.org --- src/control/namehint.c | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-)
diff --git a/src/control/namehint.c b/src/control/namehint.c index d81d3a7e..e4f696ad 100644 --- a/src/control/namehint.c +++ b/src/control/namehint.c @@ -78,6 +78,31 @@ static int hint_list_add(struct hint_list *list, return 0; }
+/** + * Add a namehint from string given in a user configuration file + */ +static int hint_list_add_custom(struct hint_list *list, + const char *entry) +{ + int err; + const char *sep; + char *name; + + assert(entry); + + sep = strchr(entry, '|'); + if (sep == NULL) + return hint_list_add(list, entry, NULL); + + name = strndup(entry, sep - entry); + if (name == NULL) + return -ENOMEM; + + err = hint_list_add(list, name, sep + 1); + free(name); + return err; +} + static void zero_handler(const char *file ATTRIBUTE_UNUSED, int line ATTRIBUTE_UNUSED, const char *function ATTRIBUTE_UNUSED, @@ -626,7 +651,7 @@ int snd_device_name_hint(int card, const char *iface, void ***hints) if (snd_config_get_string(snd_config_iterator_entry(i), &str) < 0) continue; - err = hint_list_add(&list, str, NULL); + err = hint_list_add_custom(&list, str); if (err < 0) goto __error; }