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