Andrew Eikum : winealsa.drv: Enumerate ALSA devices in a single pass.

Alexandre Julliard julliard at winehq.org
Mon Apr 9 13:09:15 CDT 2012


Module: wine
Branch: master
Commit: f461e8496d4e2861dab6183465a89e2d286a73eb
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=f461e8496d4e2861dab6183465a89e2d286a73eb

Author: Andrew Eikum <aeikum at codeweavers.com>
Date:   Mon Apr  9 09:20:31 2012 -0500

winealsa.drv: Enumerate ALSA devices in a single pass.

---

 dlls/winealsa.drv/mmdevdrv.c |   88 +++++++++++++++++++++++-------------------
 1 files changed, 48 insertions(+), 40 deletions(-)

diff --git a/dlls/winealsa.drv/mmdevdrv.c b/dlls/winealsa.drv/mmdevdrv.c
index c99186b..66e8baf 100644
--- a/dlls/winealsa.drv/mmdevdrv.c
+++ b/dlls/winealsa.drv/mmdevdrv.c
@@ -329,6 +329,8 @@ static BOOL alsa_try_open(const char *devnode, snd_pcm_stream_t stream)
     snd_pcm_t *handle;
     int err;
 
+    TRACE("devnode: %s, stream: %d\n", devnode, stream);
+
     if((err = snd_pcm_open(&handle, devnode, stream, SND_PCM_NONBLOCK)) < 0){
         WARN("The device \"%s\" failed to open: %d (%s).\n",
                 devnode, err, snd_strerror(err));
@@ -386,11 +388,13 @@ static WCHAR *construct_device_id(EDataFlow flow, const WCHAR *chunk1, const cha
     }else
         ret[copied] = 0;
 
+    TRACE("Enumerated device: %s\n", wine_dbgstr_w(ret));
+
     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,
+        WCHAR ***ids, GUID **guids, UINT *num, snd_ctl_t *ctl, int card,
         const WCHAR *cardnameW)
 {
     int err, device;
@@ -425,18 +429,24 @@ static HRESULT alsa_get_card_devices(EDataFlow flow, snd_pcm_stream_t stream,
         if(!alsa_try_open(devnode, stream))
             continue;
 
-        if(ids && guids){
-            devname = snd_pcm_info_get_name(info);
-            if(!devname){
-                WARN("Unable to get device name for card %d, device %d\n", card,
-                        device);
-                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));
+        }
 
-            ids[*num] = construct_device_id(flow, cardnameW, devname);
-            get_device_guid(flow, devnode, &guids[*num]);
+        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);
     }
 
@@ -449,8 +459,8 @@ static HRESULT alsa_get_card_devices(EDataFlow flow, snd_pcm_stream_t stream,
     return S_OK;
 }
 
-static void get_reg_devices(EDataFlow flow, snd_pcm_stream_t stream, WCHAR **ids,
-        GUID *guids, UINT *num)
+static void get_reg_devices(EDataFlow flow, snd_pcm_stream_t stream, WCHAR ***ids,
+        GUID **guids, UINT *num)
 {
     static const WCHAR ALSAOutputDevices[] = {'A','L','S','A','O','u','t','p','u','t','D','e','v','i','c','e','s',0};
     static const WCHAR ALSAInputDevices[] = {'A','L','S','A','I','n','p','u','t','D','e','v','i','c','e','s',0};
@@ -477,10 +487,15 @@ static void get_reg_devices(EDataFlow flow, snd_pcm_stream_t stream, WCHAR **ids
                 WideCharToMultiByte(CP_UNIXCP, 0, p, -1, devname, sizeof(devname), NULL, NULL);
 
                 if(alsa_try_open(devname, stream)){
-                    if(ids && guids){
-                        ids[*num] = construct_device_id(flow, p, NULL);
-                        get_device_guid(flow, devname, &guids[*num]);
+                    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, p, NULL);
+                    get_device_guid(flow, devname, &(*guids)[*num]);
                     ++*num;
                 }
 
@@ -492,7 +507,7 @@ static void get_reg_devices(EDataFlow flow, snd_pcm_stream_t stream, WCHAR **ids
     }
 }
 
-static HRESULT alsa_enum_devices(EDataFlow flow, WCHAR **ids, GUID *guids,
+static HRESULT alsa_enum_devices(EDataFlow flow, WCHAR ***ids, GUID **guids,
         UINT *num)
 {
     snd_pcm_stream_t stream = (flow == eRender ? SND_PCM_STREAM_PLAYBACK :
@@ -503,10 +518,10 @@ static HRESULT alsa_enum_devices(EDataFlow flow, WCHAR **ids, GUID *guids,
     *num = 0;
 
     if(alsa_try_open(defname, stream)){
-        if(ids && guids){
-            *ids = construct_device_id(flow, defaultW, NULL);
-            get_device_guid(flow, defname, guids);
-        }
+        *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;
     }
 
@@ -568,37 +583,30 @@ HRESULT WINAPI AUDDRV_GetEndpointIDs(EDataFlow flow, WCHAR ***ids, GUID **guids,
 
     TRACE("%d %p %p %p %p\n", flow, ids, guids, num, def_index);
 
-    hr = alsa_enum_devices(flow, NULL, NULL, num);
-    if(FAILED(hr))
-        return hr;
-
-    if(*num == 0)
-    {
-        *ids = NULL;
-        *guids = NULL;
-        return S_OK;
-    }
+    *ids = NULL;
+    *guids = NULL;
 
-    *ids = HeapAlloc(GetProcessHeap(), 0, *num * sizeof(WCHAR *));
-    *guids = HeapAlloc(GetProcessHeap(), 0, *num * sizeof(GUID));
-    if(!*ids || !*guids){
+    hr = alsa_enum_devices(flow, ids, guids, num);
+    if(FAILED(hr)){
+        UINT i;
+        for(i = 0; i < *num; ++i)
+            HeapFree(GetProcessHeap(), 0, (*ids)[i]);
         HeapFree(GetProcessHeap(), 0, *ids);
         HeapFree(GetProcessHeap(), 0, *guids);
         return E_OUTOFMEMORY;
     }
 
-    *def_index = 0;
+    TRACE("Enumerated %u devices\n", *num);
 
-    hr = alsa_enum_devices(flow, *ids, *guids, num);
-    if(FAILED(hr)){
-        int i;
-        for(i = 0; i < *num; ++i)
-            HeapFree(GetProcessHeap(), 0, (*ids)[i]);
+    if(*num == 0){
         HeapFree(GetProcessHeap(), 0, *ids);
+        *ids = NULL;
         HeapFree(GetProcessHeap(), 0, *guids);
-        return E_OUTOFMEMORY;
+        *guids = NULL;
     }
 
+    *def_index = 0;
+
     return S_OK;
 }
 




More information about the wine-cvs mailing list