wine: Add ALSA device hints patch
This commit is contained in:
commit
665173613a
|
@ -0,0 +1,224 @@
|
||||||
|
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
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue