From 665173613aadfdb71e8e6a8b9c00c39ca33c0c0c Mon Sep 17 00:00:00 2001 From: Les De Ridder Date: Tue, 18 Jul 2017 20:03:22 +0200 Subject: [PATCH] wine: Add ALSA device hints patch --- wine/0001-Use-ALSA-device-hints.patch | 224 ++++++++++++++++++++++++++ 1 file changed, 224 insertions(+) create mode 100644 wine/0001-Use-ALSA-device-hints.patch diff --git a/wine/0001-Use-ALSA-device-hints.patch b/wine/0001-Use-ALSA-device-hints.patch new file mode 100644 index 0000000..21ef7a2 --- /dev/null +++ b/wine/0001-Use-ALSA-device-hints.patch @@ -0,0 +1,224 @@ +From e5d60d9f04c284e286dc0774e192bc7ccce1830f Mon Sep 17 00:00:00 2001 +From: Les De Ridder +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 + +