patches/wine/0001-Use-ALSA-device-hints....

225 lines
7.7 KiB
Diff

From e5d60d9f04c284e286dc0774e192bc7ccce1830f Mon Sep 17 00:00:00 2001
From: Les De Ridder <les@lesderid.net>
Date: Mon, 16 Jan 2017 02:27:49 +0100
Subject: [PATCH] Use ALSA device hints instead of enumerating normally
---
dlls/winealsa.drv/mmdevdrv.c | 172 +++++++++++++------------------------------
1 file changed, 52 insertions(+), 120 deletions(-)
diff --git a/dlls/winealsa.drv/mmdevdrv.c b/dlls/winealsa.drv/mmdevdrv.c
index 2ecb111..6a090ea 100644
--- a/dlls/winealsa.drv/mmdevdrv.c
+++ b/dlls/winealsa.drv/mmdevdrv.c
@@ -160,9 +160,6 @@ static CRITICAL_SECTION_DEBUG g_sessions_lock_debug =
static CRITICAL_SECTION g_sessions_lock = { &g_sessions_lock_debug, -1, 0, 0, 0, 0 };
static struct list g_sessions = LIST_INIT(g_sessions);
-static const WCHAR defaultW[] = {'d','e','f','a','u','l','t',0};
-static const char defname[] = "default";
-
static const WCHAR drv_keyW[] = {'S','o','f','t','w','a','r','e','\\',
'W','i','n','e','\\','D','r','i','v','e','r','s','\\',
'w','i','n','e','a','l','s','a','.','d','r','v',0};
@@ -407,72 +404,6 @@ static WCHAR *construct_device_id(EDataFlow flow, const WCHAR *chunk1, const cha
return ret;
}
-static HRESULT alsa_get_card_devices(EDataFlow flow, snd_pcm_stream_t stream,
- WCHAR ***ids, GUID **guids, UINT *num, snd_ctl_t *ctl, int card,
- const WCHAR *cardnameW)
-{
- int err, device;
- snd_pcm_info_t *info;
-
- info = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, snd_pcm_info_sizeof());
- if(!info)
- return E_OUTOFMEMORY;
-
- snd_pcm_info_set_subdevice(info, 0);
- snd_pcm_info_set_stream(info, stream);
-
- device = -1;
- for(err = snd_ctl_pcm_next_device(ctl, &device); device != -1 && err >= 0;
- err = snd_ctl_pcm_next_device(ctl, &device)){
- const char *devname;
- char devnode[32];
-
- snd_pcm_info_set_device(info, device);
-
- if((err = snd_ctl_pcm_info(ctl, info)) < 0){
- if(err == -ENOENT)
- /* This device doesn't have the right stream direction */
- continue;
-
- WARN("Failed to get info for card %d, device %d: %d (%s)\n",
- card, device, err, snd_strerror(err));
- continue;
- }
-
- sprintf(devnode, "plughw:%d,%d", card, device);
- if(!alsa_try_open(devnode, stream))
- continue;
-
- if(*num){
- *ids = HeapReAlloc(GetProcessHeap(), 0, *ids, sizeof(WCHAR *) * (*num + 1));
- *guids = HeapReAlloc(GetProcessHeap(), 0, *guids, sizeof(GUID) * (*num + 1));
- }else{
- *ids = HeapAlloc(GetProcessHeap(), 0, sizeof(WCHAR *));
- *guids = HeapAlloc(GetProcessHeap(), 0, sizeof(GUID));
- }
-
- devname = snd_pcm_info_get_name(info);
- if(!devname){
- WARN("Unable to get device name for card %d, device %d\n", card,
- device);
- continue;
- }
-
- (*ids)[*num] = construct_device_id(flow, cardnameW, devname);
- get_device_guid(flow, devnode, &(*guids)[*num]);
-
- ++(*num);
- }
-
- HeapFree(GetProcessHeap(), 0, info);
-
- if(err != 0)
- WARN("Got a failure during device enumeration on card %d: %d (%s)\n",
- card, err, snd_strerror(err));
-
- return S_OK;
-}
-
static void get_reg_devices(EDataFlow flow, snd_pcm_stream_t stream, WCHAR ***ids,
GUID **guids, UINT *num)
{
@@ -521,71 +452,72 @@ static void get_reg_devices(EDataFlow flow, snd_pcm_stream_t stream, WCHAR ***id
}
}
-static HRESULT alsa_enum_devices(EDataFlow flow, WCHAR ***ids, GUID **guids,
- UINT *num)
+static void get_hint_devices(EDataFlow flow, snd_pcm_stream_t stream, WCHAR ***ids,
+ GUID **guids, UINT *num)
{
- snd_pcm_stream_t stream = (flow == eRender ? SND_PCM_STREAM_PLAYBACK :
- SND_PCM_STREAM_CAPTURE);
- int err, card;
+ void** hints;
+ int i;
- card = -1;
- *num = 0;
+ const char* ioType = (stream == SND_PCM_STREAM_PLAYBACK) ? "Output" : "Input";
- if(alsa_try_open(defname, stream)){
- *ids = HeapAlloc(GetProcessHeap(), 0, sizeof(WCHAR *));
- (*ids)[0] = construct_device_id(flow, defaultW, NULL);
- *guids = HeapAlloc(GetProcessHeap(), 0, sizeof(GUID));
- get_device_guid(flow, defname, &(*guids)[0]);
- ++*num;
- }
+ if(snd_device_name_hint(-1, "pcm", &hints) < 0) {
+ ERR("Could not get a set of ALSA device hints\n");
+ return;
+ }
- get_reg_devices(flow, stream, ids, guids, num);
+ for(i = 0; hints[i] != NULL; i++) {
+ DWORD len;
+ WCHAR* descriptionW;
+ char *name, *description, *ioId;
- for(err = snd_card_next(&card); card != -1 && err >= 0;
- err = snd_card_next(&card)){
- char cardpath[64];
- char *cardname;
- WCHAR *cardnameW;
- snd_ctl_t *ctl;
- DWORD len;
+ name = snd_device_name_get_hint(hints[i], "NAME");
+ description = snd_device_name_get_hint(hints[i], "DESC");
+ ioId = snd_device_name_get_hint(hints[i], "IOID");
- sprintf(cardpath, "hw:%u", card);
+ if(ioId != NULL && strcmp(ioId, ioType) != 0) {
+ continue;
+ }
- if((err = snd_ctl_open(&ctl, cardpath, 0)) < 0){
- WARN("Unable to open ctl for ALSA device %s: %d (%s)\n", cardpath,
- err, snd_strerror(err));
- continue;
+ len = MultiByteToWideChar(CP_UNIXCP, 0, description, -1, NULL, 0);
+ descriptionW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
+ MultiByteToWideChar(CP_UNIXCP, 0, description, -1, descriptionW, len);
+
+ if(alsa_try_open(name, stream)) {
+ if(*num) {
+ *ids = HeapReAlloc(GetProcessHeap(), 0, *ids, sizeof(WCHAR *) * (*num + 1));
+ *guids = HeapReAlloc(GetProcessHeap(), 0, *guids, sizeof(GUID) * (*num + 1));
+ } else {
+ *ids = HeapAlloc(GetProcessHeap(), 0, sizeof(WCHAR *));
+ *guids = HeapAlloc(GetProcessHeap(), 0, sizeof(GUID));
+ }
+
+ (*ids)[*num] = construct_device_id(flow, descriptionW /* cardNameW */, NULL /* devNameW */);
+ get_device_guid(flow, name, &(*guids)[*num]);
+
+ ++(*num);
}
- if(snd_card_get_name(card, &cardname) < 0) {
- /* FIXME: Should be localized */
- static const WCHAR nameW[] = {'U','n','k','n','o','w','n',' ','s','o','u','n','d','c','a','r','d',0};
- WARN("Unable to get card name for ALSA device %s: %d (%s)\n",
- cardpath, err, snd_strerror(err));
- alsa_get_card_devices(flow, stream, ids, guids, num, ctl, card, nameW);
- }else{
- len = MultiByteToWideChar(CP_UNIXCP, 0, cardname, -1, NULL, 0);
- cardnameW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
+ free(name);
+ free(description);
+ free(ioId);
+ }
- if(!cardnameW){
- free(cardname);
- snd_ctl_close(ctl);
- return E_OUTOFMEMORY;
- }
- MultiByteToWideChar(CP_UNIXCP, 0, cardname, -1, cardnameW, len);
+ if(snd_device_name_free_hint(hints) < 0) {
+ ERR("Could not free list of ALSA device hints\n");
+ }
+}
- alsa_get_card_devices(flow, stream, ids, guids, num, ctl, card, cardnameW);
+static HRESULT alsa_enum_devices(EDataFlow flow, WCHAR ***ids, GUID **guids,
+ UINT *num)
+{
+ snd_pcm_stream_t stream = (flow == eRender ? SND_PCM_STREAM_PLAYBACK :
+ SND_PCM_STREAM_CAPTURE);
- HeapFree(GetProcessHeap(), 0, cardnameW);
- free(cardname);
- }
+ *num = 0;
- snd_ctl_close(ctl);
- }
+ get_reg_devices(flow, stream, ids, guids, num);
- if(err != 0)
- WARN("Got a failure during card enumeration: %d (%s)\n",
- err, snd_strerror(err));
+ get_hint_devices(flow, stream, ids, guids, num);
return S_OK;
}
--
2.10.0.478.g3ef7618