alsa: more tapdancing to enumerate physical hardware devices. Apparently some systems see "hw:", some see "default:" and some see "sysdefault:" (and maybe others!). My workstation sees both "hw:" and "sysdefault:" ... Try to find a prefix we like and prioritize the prefixes we (think) we want most. If everything else fails, if there's a "default" (not a prefix) device name, list that by itself so the user gets _something_ here. If we can't find a prefix we like _and_ there's no "default" device, report no hardware found at all.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79
diff --git a/src/audio/alsa/SDL_alsa_audio.c b/src/audio/alsa/SDL_alsa_audio.c
index 8394797..f225b3b 100644
--- a/src/audio/alsa/SDL_alsa_audio.c
+++ b/src/audio/alsa/SDL_alsa_audio.c
@@ -773,23 +773,40 @@ ALSA_HotplugThread(void *arg)
ALSA_Device *unseen = devices;
ALSA_Device *seen = NULL;
ALSA_Device *prev;
- int i;
- const char *match = "default:";
- size_t match_len = strlen(match);
-
- /* determine what kind of name to match. Use "hw:" devices if they
- exist, otherwise use "default:" */
+ int i, j;
+ const char *match = NULL;
+ int bestmatch = 0xFFFF;
+ size_t match_len = 0;
+ int defaultdev = -1;
+ static const char * const prefixes[] = {
+ "hw:", "sysdefault:", "default:", NULL
+ };
+
+ /* Apparently there are several different ways that ALSA lists
+ actual hardware. It could be prefixed with "hw:" or "default:"
+ or "sysdefault:" and maybe others. Go through the list and see
+ if we can find a preferred prefix for the system. */
for (i = 0; hints[i]; i++) {
char *name = ALSA_snd_device_name_get_hint(hints[i], "NAME");
if (!name) {
continue;
}
- if (SDL_strncmp(name, "hw:", 3) == 0) {
- match = "hw:";
- match_len = strlen(match);
- free(name);
- break;
+ /* full name, not a prefix */
+ if ((defaultdev == -1) && (SDL_strcmp(name, "default") == 0)) {
+ defaultdev = i;
+ }
+
+ for (j = 0; prefixes[j]; j++) {
+ const char *prefix = prefixes[j];
+ const size_t prefixlen = strlen(prefix);
+ if (SDL_strncmp(name, prefix, prefixlen) == 0) {
+ if (j < bestmatch) {
+ bestmatch = j;
+ match = prefix;
+ match_len = prefixlen;
+ }
+ }
}
free(name);
@@ -797,13 +814,20 @@ ALSA_HotplugThread(void *arg)
/* look through the list of device names to find matches */
for (i = 0; hints[i]; i++) {
- char *name = ALSA_snd_device_name_get_hint(hints[i], "NAME");
+ char *name;
+
+ /* if we didn't find a device name prefix we like at all... */
+ if ((!match) && (defaultdev != i)) {
+ continue; /* ...skip anything that isn't the default device. */
+ }
+
+ name = ALSA_snd_device_name_get_hint(hints[i], "NAME");
if (!name) {
continue;
}
/* only want physical hardware interfaces */
- if (SDL_strncmp(name, match, match_len) == 0) {
+ if (!match || (SDL_strncmp(name, match, match_len) == 0)) {
char *ioid = ALSA_snd_device_name_get_hint(hints[i], "IOID");
const SDL_bool isoutput = (ioid == NULL) || (SDL_strcmp(ioid, "Output") == 0);
const SDL_bool isinput = (ioid == NULL) || (SDL_strcmp(ioid, "Input") == 0);