summaryrefslogtreecommitdiffstats
path: root/Alc/backends
diff options
context:
space:
mode:
Diffstat (limited to 'Alc/backends')
-rw-r--r--Alc/backends/mmdevapi.c170
1 files changed, 77 insertions, 93 deletions
diff --git a/Alc/backends/mmdevapi.c b/Alc/backends/mmdevapi.c
index 5af500d1..18feab02 100644
--- a/Alc/backends/mmdevapi.c
+++ b/Alc/backends/mmdevapi.c
@@ -80,11 +80,24 @@ typedef struct {
al_string name;
WCHAR *devid;
} DevMap;
+DECL_VECTOR(DevMap)
-static DevMap *PlaybackDeviceList;
-static ALuint NumPlaybackDevices;
-static DevMap *CaptureDeviceList;
-static ALuint NumCaptureDevices;
+static void clear_devlist(vector_DevMap *list)
+{
+ DevMap *iter, *end;
+
+ iter = VECTOR_ITER_BEGIN(*list);
+ end = VECTOR_ITER_END(*list);
+ for(;iter != end;iter++)
+ {
+ AL_STRING_DEINIT(iter->name);
+ free(iter->devid);
+ }
+ VECTOR_RESIZE(*list, 0);
+}
+
+static vector_DevMap PlaybackDevices;
+static vector_DevMap CaptureDevices;
static HANDLE ThreadHdl;
@@ -144,58 +157,58 @@ static void get_device_name(IMMDevice *device, al_string *name)
IPropertyStore_Release(ps);
}
-static void add_device(IMMDevice *device, DevMap *devmap)
+static void add_device(IMMDevice *device, vector_DevMap *list)
{
LPWSTR devid;
HRESULT hr;
- AL_STRING_INIT(devmap->name);
-
hr = IMMDevice_GetId(device, &devid);
- if(FAILED(hr))
- devmap->devid = calloc(sizeof(WCHAR), 1);
- else
+ if(SUCCEEDED(hr))
{
- devmap->devid = strdupW(devid);
- get_device_name(device, &devmap->name);
- TRACE("Got device \"%s\", \"%ls\"\n", al_string_get_cstr(devmap->name), devmap->devid);
+ DevMap entry;
+ AL_STRING_INIT(entry.name);
+
+ entry.devid = strdupW(devid);
+ get_device_name(device, &entry.name);
+
CoTaskMemFree(devid);
+
+ TRACE("Got device \"%s\", \"%ls\"\n", al_string_get_cstr(entry.name), entry.devid);
+ VECTOR_PUSH_BACK(*list, entry);
}
}
-static DevMap *ProbeDevices(IMMDeviceEnumerator *devenum, EDataFlow flowdir, ALuint *numdevs)
+static HRESULT ProbeDevices(IMMDeviceEnumerator *devenum, EDataFlow flowdir, vector_DevMap *list)
{
IMMDeviceCollection *coll;
IMMDevice *defdev = NULL;
- DevMap *devlist = NULL;
HRESULT hr;
UINT count;
- UINT idx;
UINT i;
hr = IMMDeviceEnumerator_EnumAudioEndpoints(devenum, flowdir, DEVICE_STATE_ACTIVE, &coll);
if(FAILED(hr))
{
ERR("Failed to enumerate audio endpoints: 0x%08lx\n", hr);
- return NULL;
+ return hr;
}
- idx = count = 0;
+ count = 0;
hr = IMMDeviceCollection_GetCount(coll, &count);
if(SUCCEEDED(hr) && count > 0)
{
- devlist = calloc(count+1, sizeof(*devlist));
- if(!devlist)
+ clear_devlist(list);
+ if(!VECTOR_RESERVE(*list, count+1))
{
IMMDeviceCollection_Release(coll);
- return NULL;
+ return E_OUTOFMEMORY;
}
hr = IMMDeviceEnumerator_GetDefaultAudioEndpoint(devenum, flowdir,
eMultimedia, &defdev);
}
if(SUCCEEDED(hr) && defdev != NULL)
- add_device(defdev, &devlist[idx++]);
+ add_device(defdev, list);
for(i = 0;i < count;++i)
{
@@ -205,7 +218,7 @@ static DevMap *ProbeDevices(IMMDeviceEnumerator *devenum, EDataFlow flowdir, ALu
continue;
if(device != defdev)
- add_device(device, &devlist[idx++]);
+ add_device(device, list);
IMMDevice_Release(device);
}
@@ -213,8 +226,7 @@ static DevMap *ProbeDevices(IMMDeviceEnumerator *devenum, EDataFlow flowdir, ALu
if(defdev) IMMDevice_Release(defdev);
IMMDeviceCollection_Release(coll);
- *numdevs = idx;
- return devlist;
+ return S_OK;
}
@@ -623,8 +635,7 @@ static DWORD CALLBACK MMDevApiMsgProc(void *ptr)
PeekMessage(&msg, NULL, WM_USER, WM_USER, PM_NOREMOVE);
TRACE("Message thread initialization complete\n");
- req->result = S_OK;
- SetEvent(req->FinishedEvt);
+ ReturnMsgResponse(req, S_OK);
TRACE("Starting message loop\n");
while(GetMessage(&msg, NULL, WM_USER_First, WM_USER_Last))
@@ -759,35 +770,12 @@ static DWORD CALLBACK MMDevApiMsgProc(void *ptr)
hr = CoCreateInstance(&CLSID_MMDeviceEnumerator, NULL, CLSCTX_INPROC_SERVER, &IID_IMMDeviceEnumerator, &ptr);
if(SUCCEEDED(hr))
{
- EDataFlow flowdir;
- DevMap **devlist;
- ALuint *numdevs;
- ALuint i;
-
Enumerator = ptr;
- if(msg.lParam == CAPTURE_DEVICE_PROBE)
- {
- flowdir = eCapture;
- devlist = &CaptureDeviceList;
- numdevs = &NumCaptureDevices;
- }
- else
- {
- flowdir = eRender;
- devlist = &PlaybackDeviceList;
- numdevs = &NumPlaybackDevices;
- }
- for(i = 0;i < *numdevs;i++)
- {
- AL_STRING_DEINIT((*devlist)[i].name);
- free((*devlist)[i].devid);
- }
- free(*devlist);
- *devlist = NULL;
- *numdevs = 0;
-
- *devlist = ProbeDevices(Enumerator, flowdir, numdevs);
+ if(msg.lParam == ALL_DEVICE_PROBE)
+ hr = ProbeDevices(Enumerator, eRender, &PlaybackDevices);
+ else if(msg.lParam == CAPTURE_DEVICE_PROBE)
+ hr = ProbeDevices(Enumerator, eCapture, &CaptureDevices);
IMMDeviceEnumerator_Release(Enumerator);
Enumerator = NULL;
@@ -796,7 +784,7 @@ static DWORD CALLBACK MMDevApiMsgProc(void *ptr)
if(--deviceCount == 0 && SUCCEEDED(cohr))
CoUninitialize();
- ReturnMsgResponse(req, S_OK);
+ ReturnMsgResponse(req, hr);
continue;
default:
@@ -857,9 +845,9 @@ static ALCenum MMDevApiOpenPlayback(ALCdevice *device, const ALCchar *deviceName
{
if(deviceName)
{
- ALuint i;
+ const DevMap *iter, *end;
- if(!PlaybackDeviceList)
+ if(VECTOR_SIZE(PlaybackDevices) == 0)
{
ThreadRequest req = { data->MsgEvent, 0 };
if(PostThreadMessage(ThreadID, WM_USER_Enumerate, (WPARAM)&req, ALL_DEVICE_PROBE))
@@ -867,11 +855,13 @@ static ALCenum MMDevApiOpenPlayback(ALCdevice *device, const ALCchar *deviceName
}
hr = E_FAIL;
- for(i = 0;i < NumPlaybackDevices;i++)
+ iter = VECTOR_ITER_BEGIN(PlaybackDevices);
+ end = VECTOR_ITER_END(PlaybackDevices);
+ for(;iter != end;iter++)
{
- if(al_string_cmp_cstr(PlaybackDeviceList[i].name, deviceName) == 0)
+ if(al_string_cmp_cstr(iter->name, deviceName) == 0)
{
- data->devid = strdupW(PlaybackDeviceList[i].devid);
+ data->devid = strdupW(iter->devid);
hr = S_OK;
break;
}
@@ -995,6 +985,9 @@ static const BackendFuncs MMDevApiFuncs = {
ALCboolean alcMMDevApiInit(BackendFuncs *FuncList)
{
+ VECTOR_INIT(PlaybackDevices);
+ VECTOR_INIT(CaptureDevices);
+
if(!MMDevApiLoad())
return ALC_FALSE;
*FuncList = MMDevApiFuncs;
@@ -1003,25 +996,11 @@ ALCboolean alcMMDevApiInit(BackendFuncs *FuncList)
void alcMMDevApiDeinit(void)
{
- ALuint i;
+ clear_devlist(&PlaybackDevices);
+ VECTOR_DEINIT(PlaybackDevices);
- for(i = 0;i < NumPlaybackDevices;i++)
- {
- AL_STRING_DEINIT(PlaybackDeviceList[i].name);
- free(PlaybackDeviceList[i].devid);
- }
- free(PlaybackDeviceList);
- PlaybackDeviceList = NULL;
- NumPlaybackDevices = 0;
-
- for(i = 0;i < NumCaptureDevices;i++)
- {
- AL_STRING_DEINIT(CaptureDeviceList[i].name);
- free(CaptureDeviceList[i].devid);
- }
- free(CaptureDeviceList);
- CaptureDeviceList = NULL;
- NumCaptureDevices = 0;
+ clear_devlist(&CaptureDevices);
+ VECTOR_DEINIT(CaptureDevices);
if(ThreadHdl)
{
@@ -1035,28 +1014,33 @@ void alcMMDevApiDeinit(void)
void alcMMDevApiProbe(enum DevProbe type)
{
ThreadRequest req = { NULL, 0 };
+ const DevMap *iter, *end;
HRESULT hr = E_FAIL;
- switch(type)
+ req.FinishedEvt = CreateEvent(NULL, FALSE, FALSE, NULL);
+ if(req.FinishedEvt == NULL)
+ ERR("Failed to create event: %lu\n", GetLastError());
+ else
{
+ if(PostThreadMessage(ThreadID, WM_USER_Enumerate, (WPARAM)&req, type))
+ hr = WaitForResponse(&req);
+ if(SUCCEEDED(hr)) switch(type)
+ {
case ALL_DEVICE_PROBE:
- req.FinishedEvt = CreateEvent(NULL, FALSE, FALSE, NULL);
- if(req.FinishedEvt == NULL)
- ERR("Failed to create event: %lu\n", GetLastError());
- else if(PostThreadMessage(ThreadID, WM_USER_Enumerate, (WPARAM)&req, type))
- hr = WaitForResponse(&req);
- if(SUCCEEDED(hr))
- {
- ALuint i;
- for(i = 0;i < NumPlaybackDevices;i++)
- AppendAllDevicesList(al_string_get_cstr(PlaybackDeviceList[i].name));
- }
+ iter = VECTOR_ITER_BEGIN(PlaybackDevices);
+ end = VECTOR_ITER_END(PlaybackDevices);
+ for(;iter != end;iter++)
+ AppendAllDevicesList(al_string_get_cstr(iter->name));
break;
case CAPTURE_DEVICE_PROBE:
+ iter = VECTOR_ITER_BEGIN(CaptureDevices);
+ end = VECTOR_ITER_END(CaptureDevices);
+ for(;iter != end;iter++)
+ AppendCaptureDeviceList(al_string_get_cstr(iter->name));
break;
- }
- if(req.FinishedEvt != NULL)
+ }
CloseHandle(req.FinishedEvt);
- req.FinishedEvt = NULL;
+ req.FinishedEvt = NULL;
+ }
}