Commit 3982453b authored by David Reid's avatar David Reid

API CHANGE: Have mal_enumerate_devices() take a context object.

parent 982791b3
...@@ -341,6 +341,7 @@ typedef struct ...@@ -341,6 +341,7 @@ typedef struct
#ifdef MAL_ENABLE_WASAPI #ifdef MAL_ENABLE_WASAPI
struct struct
{ {
/*IMMDeviceEnumerator**/ mal_ptr pDeviceEnumerator;
mal_bool32 needCoUninit; // Whether or not COM needs to be uninitialized. mal_bool32 needCoUninit; // Whether or not COM needs to be uninitialized.
} wasapi; } wasapi;
#endif #endif
...@@ -490,7 +491,7 @@ struct mal_device ...@@ -490,7 +491,7 @@ struct mal_device
// //
// Effeciency: LOW // Effeciency: LOW
// This will dynamically load backends DLLs/SOs (such as dsound.dll). // This will dynamically load backends DLLs/SOs (such as dsound.dll).
mal_result mal_context_init(mal_context* pContext, mal_backend backends[], mal_uint32 backendCount); mal_result mal_context_init(mal_backend backends[], mal_uint32 backendCount, mal_context* pContext);
// Uninitializes a context. // Uninitializes a context.
// //
...@@ -517,7 +518,7 @@ mal_result mal_context_uninit(mal_context* pContext); ...@@ -517,7 +518,7 @@ mal_result mal_context_uninit(mal_context* pContext);
// //
// Efficiency: LOW // Efficiency: LOW
// This API dynamically links to backend DLLs/SOs (such as dsound.dll). // This API dynamically links to backend DLLs/SOs (such as dsound.dll).
mal_result mal_enumerate_devices(mal_device_type type, mal_uint32* pCount, mal_device_info* pInfo); mal_result mal_enumerate_devices(mal_context* pContext, mal_device_type type, mal_uint32* pCount, mal_device_info* pInfo);
// Initializes a device. // Initializes a device.
// //
...@@ -1443,8 +1444,10 @@ mal_result mal_context_uninit__null(mal_context* pContext) ...@@ -1443,8 +1444,10 @@ mal_result mal_context_uninit__null(mal_context* pContext)
return MAL_SUCCESS; return MAL_SUCCESS;
} }
static mal_result mal_enumerate_devices__null(mal_device_type type, mal_uint32* pCount, mal_device_info* pInfo) static mal_result mal_enumerate_devices__null(mal_context* pContext, mal_device_type type, mal_uint32* pCount, mal_device_info* pInfo)
{ {
(void)pContext;
mal_uint32 infoSize = *pCount; mal_uint32 infoSize = *pCount;
*pCount = 1; // There's only one "device" each for playback and recording for the null backend. *pCount = 1; // There's only one "device" each for playback and recording for the null backend.
...@@ -1684,8 +1687,20 @@ const IID g_malIID_IAudioCaptureClient_Instance = {0xC8ADBD64, 0xE71E, 0x48A0, ...@@ -1684,8 +1687,20 @@ const IID g_malIID_IAudioCaptureClient_Instance = {0xC8ADBD64, 0xE71E, 0x48A0,
mal_result mal_context_init__wasapi(mal_context* pContext) mal_result mal_context_init__wasapi(mal_context* pContext)
{ {
mal_assert(pContext != NULL); mal_assert(pContext != NULL);
pContext->wasapi.needCoUninit = MAL_FALSE;
HRESULT hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
if (hr == S_OK || hr == S_FALSE) {
pContext->wasapi.needCoUninit = MAL_TRUE;
}
// Validate the WASAPI is available by grabbing an MMDeviceEnumerator object.
hr = CoCreateInstance(g_malCLSID_MMDeviceEnumerator, NULL, CLSCTX_ALL, g_malIID_IMMDeviceEnumerator, (void**)&pContext->wasapi.pDeviceEnumerator);
if (FAILED(hr)) {
if (pContext->wasapi.needCoUninit) CoUninitialize();
return MAL_NO_BACKEND;
}
(void)pContext;
return MAL_SUCCESS; return MAL_SUCCESS;
} }
...@@ -1694,42 +1709,35 @@ mal_result mal_context_uninit__wasapi(mal_context* pContext) ...@@ -1694,42 +1709,35 @@ mal_result mal_context_uninit__wasapi(mal_context* pContext)
mal_assert(pContext != NULL); mal_assert(pContext != NULL);
mal_assert(pContext->backend == mal_backend_wasapi); mal_assert(pContext->backend == mal_backend_wasapi);
(void)pContext; if (pContext->wasapi.pDeviceEnumerator) {
((IMMDeviceEnumerator*)pContext->wasapi.pDeviceEnumerator)->lpVtbl->Release((IMMDeviceEnumerator*)pContext->wasapi.pDeviceEnumerator);
}
if (pContext->wasapi.needCoUninit) {
CoUninitialize();
}
return MAL_SUCCESS; return MAL_SUCCESS;
} }
static mal_result mal_enumerate_devices__wasapi(mal_device_type type, mal_uint32* pCount, mal_device_info* pInfo) static mal_result mal_enumerate_devices__wasapi(mal_context* pContext, mal_device_type type, mal_uint32* pCount, mal_device_info* pInfo)
{ {
mal_uint32 infoSize = *pCount; mal_uint32 infoSize = *pCount;
*pCount = 0; *pCount = 0;
mal_bool32 needCoUninit = MAL_FALSE; IMMDeviceEnumerator* pDeviceEnumerator = (IMMDeviceEnumerator*)pContext->wasapi.pDeviceEnumerator;
HRESULT hResult = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED); mal_assert(pDeviceEnumerator != NULL);
if (hResult == S_OK || hResult == S_FALSE) {
needCoUninit = MAL_TRUE;
}
IMMDeviceEnumerator* pDeviceEnumerator;
hResult = CoCreateInstance(g_malCLSID_MMDeviceEnumerator, NULL, CLSCTX_ALL, g_malIID_IMMDeviceEnumerator, (void**)&pDeviceEnumerator);
if (FAILED(hResult)) {
if (needCoUninit) CoUninitialize();
return MAL_NO_BACKEND;
}
IMMDeviceCollection* pDeviceCollection; IMMDeviceCollection* pDeviceCollection;
hResult = pDeviceEnumerator->lpVtbl->EnumAudioEndpoints(pDeviceEnumerator, (type == mal_device_type_playback) ? eRender : eCapture, DEVICE_STATE_ACTIVE, &pDeviceCollection); HRESULT hr = pDeviceEnumerator->lpVtbl->EnumAudioEndpoints(pDeviceEnumerator, (type == mal_device_type_playback) ? eRender : eCapture, DEVICE_STATE_ACTIVE, &pDeviceCollection);
if (FAILED(hResult)) { if (FAILED(hr)) {
pDeviceEnumerator->lpVtbl->Release(pDeviceEnumerator);
if (needCoUninit) CoUninitialize();
return MAL_NO_DEVICE; return MAL_NO_DEVICE;
} }
UINT count; UINT count;
hResult = pDeviceCollection->lpVtbl->GetCount(pDeviceCollection, &count); hr = pDeviceCollection->lpVtbl->GetCount(pDeviceCollection, &count);
if (FAILED(hResult)) { if (FAILED(hr)) {
pDeviceCollection->lpVtbl->Release(pDeviceCollection); pDeviceCollection->lpVtbl->Release(pDeviceCollection);
pDeviceEnumerator->lpVtbl->Release(pDeviceEnumerator);
if (needCoUninit) CoUninitialize();
return MAL_NO_DEVICE; return MAL_NO_DEVICE;
} }
...@@ -1737,12 +1745,12 @@ static mal_result mal_enumerate_devices__wasapi(mal_device_type type, mal_uint32 ...@@ -1737,12 +1745,12 @@ static mal_result mal_enumerate_devices__wasapi(mal_device_type type, mal_uint32
mal_zero_object(pInfo); mal_zero_object(pInfo);
IMMDevice* pDevice; IMMDevice* pDevice;
hResult = pDeviceCollection->lpVtbl->Item(pDeviceCollection, iDevice, &pDevice); hr = pDeviceCollection->lpVtbl->Item(pDeviceCollection, iDevice, &pDevice);
if (SUCCEEDED(hResult)) { if (SUCCEEDED(hr)) {
// ID. // ID.
LPWSTR id; LPWSTR id;
hResult = pDevice->lpVtbl->GetId(pDevice, &id); hr = pDevice->lpVtbl->GetId(pDevice, &id);
if (SUCCEEDED(hResult)) { if (SUCCEEDED(hr)) {
size_t idlen = wcslen(id); size_t idlen = wcslen(id);
if (idlen+sizeof(wchar_t) > sizeof(pInfo->id.wstr)) { if (idlen+sizeof(wchar_t) > sizeof(pInfo->id.wstr)) {
CoTaskMemFree(id); CoTaskMemFree(id);
...@@ -1758,12 +1766,12 @@ static mal_result mal_enumerate_devices__wasapi(mal_device_type type, mal_uint32 ...@@ -1758,12 +1766,12 @@ static mal_result mal_enumerate_devices__wasapi(mal_device_type type, mal_uint32
// Description / Friendly Name. // Description / Friendly Name.
IPropertyStore *pProperties; IPropertyStore *pProperties;
hResult = pDevice->lpVtbl->OpenPropertyStore(pDevice, STGM_READ, &pProperties); hr = pDevice->lpVtbl->OpenPropertyStore(pDevice, STGM_READ, &pProperties);
if (SUCCEEDED(hResult)) { if (SUCCEEDED(hr)) {
PROPVARIANT varName; PROPVARIANT varName;
PropVariantInit(&varName); PropVariantInit(&varName);
hResult = pProperties->lpVtbl->GetValue(pProperties, &g_malPKEY_Device_FriendlyName, &varName); hr = pProperties->lpVtbl->GetValue(pProperties, &g_malPKEY_Device_FriendlyName, &varName);
if (SUCCEEDED(hResult)) { if (SUCCEEDED(hr)) {
WideCharToMultiByte(CP_UTF8, 0, varName.pwszVal, -1, pInfo->name, sizeof(pInfo->name), 0, FALSE); WideCharToMultiByte(CP_UTF8, 0, varName.pwszVal, -1, pInfo->name, sizeof(pInfo->name), 0, FALSE);
PropVariantClear(&varName); PropVariantClear(&varName);
} }
...@@ -1777,8 +1785,6 @@ static mal_result mal_enumerate_devices__wasapi(mal_device_type type, mal_uint32 ...@@ -1777,8 +1785,6 @@ static mal_result mal_enumerate_devices__wasapi(mal_device_type type, mal_uint32
} }
pDeviceCollection->lpVtbl->Release(pDeviceCollection); pDeviceCollection->lpVtbl->Release(pDeviceCollection);
pDeviceEnumerator->lpVtbl->Release(pDeviceEnumerator);
if (needCoUninit) CoUninitialize();
return MAL_SUCCESS; return MAL_SUCCESS;
} }
...@@ -1804,10 +1810,6 @@ static void mal_device_uninit__wasapi(mal_device* pDevice) ...@@ -1804,10 +1810,6 @@ static void mal_device_uninit__wasapi(mal_device* pDevice)
if (pDevice->wasapi.hStopEvent) { if (pDevice->wasapi.hStopEvent) {
CloseHandle(pDevice->wasapi.hStopEvent); CloseHandle(pDevice->wasapi.hStopEvent);
} }
if (pDevice->wasapi.needCoUninit) {
CoUninitialize();
}
} }
static mal_result mal_device_init__wasapi(mal_device* pDevice, mal_device_type type, mal_device_id* pDeviceID, mal_device_config* pConfig) static mal_result mal_device_init__wasapi(mal_device* pDevice, mal_device_type type, mal_device_id* pDeviceID, mal_device_config* pConfig)
...@@ -2171,8 +2173,10 @@ static BOOL CALLBACK mal_enum_devices_callback__dsound(LPGUID lpGuid, LPCSTR lpc ...@@ -2171,8 +2173,10 @@ static BOOL CALLBACK mal_enum_devices_callback__dsound(LPGUID lpGuid, LPCSTR lpc
return TRUE; return TRUE;
} }
static mal_result mal_enumerate_devices__dsound(mal_device_type type, mal_uint32* pCount, mal_device_info* pInfo) static mal_result mal_enumerate_devices__dsound(mal_context* pContext, mal_device_type type, mal_uint32* pCount, mal_device_info* pInfo)
{ {
(void)pContext;
mal_uint32 infoSize = *pCount; mal_uint32 infoSize = *pCount;
*pCount = 0; *pCount = 0;
...@@ -3008,8 +3012,10 @@ static mal_bool32 mal_device_read__alsa(mal_device* pDevice) ...@@ -3008,8 +3012,10 @@ static mal_bool32 mal_device_read__alsa(mal_device* pDevice)
} }
static mal_result mal_enumerate_devices__alsa(mal_device_type type, mal_uint32* pCount, mal_device_info* pInfo) static mal_result mal_enumerate_devices__alsa(mal_context* pContext, mal_device_type type, mal_uint32* pCount, mal_device_info* pInfo)
{ {
(void)pContext;
mal_uint32 infoSize = *pCount; mal_uint32 infoSize = *pCount;
*pCount = 0; *pCount = 0;
...@@ -3441,8 +3447,10 @@ mal_result mal_context_uninit__sles(mal_context* pContext) ...@@ -3441,8 +3447,10 @@ mal_result mal_context_uninit__sles(mal_context* pContext)
return MAL_SUCCESS; return MAL_SUCCESS;
} }
mal_result mal_enumerate_devices__sles(mal_device_type type, mal_uint32* pCount, mal_device_info* pInfo) mal_result mal_enumerate_devices__sles(mal_context* pContext, mal_device_type type, mal_uint32* pCount, mal_device_info* pInfo)
{ {
(void)pContext;
mal_uint32 infoSize = *pCount; mal_uint32 infoSize = *pCount;
*pCount = 0; *pCount = 0;
...@@ -4089,7 +4097,7 @@ mal_bool32 mal_device__is_initialized(mal_device* pDevice) ...@@ -4089,7 +4097,7 @@ mal_bool32 mal_device__is_initialized(mal_device* pDevice)
} }
mal_result mal_context_init(mal_context* pContext, mal_backend backends[], mal_uint32 backendCount) mal_result mal_context_init(mal_backend backends[], mal_uint32 backendCount, mal_context* pContext)
{ {
if (pContext == NULL) return MAL_INVALID_ARGS; if (pContext == NULL) return MAL_INVALID_ARGS;
mal_zero_object(pContext); mal_zero_object(pContext);
...@@ -4215,34 +4223,34 @@ mal_result mal_context_uninit(mal_context* pContext) ...@@ -4215,34 +4223,34 @@ mal_result mal_context_uninit(mal_context* pContext)
} }
mal_result mal_enumerate_devices(mal_device_type type, mal_uint32* pCount, mal_device_info* pInfo) mal_result mal_enumerate_devices(mal_context* pContext, mal_device_type type, mal_uint32* pCount, mal_device_info* pInfo)
{ {
if (pCount == NULL) return mal_post_error(NULL, "mal_enumerate_devices() called with invalid arguments.", MAL_INVALID_ARGS); if (pCount == NULL) return mal_post_error(NULL, "mal_enumerate_devices() called with invalid arguments.", MAL_INVALID_ARGS);
mal_result result = MAL_NO_BACKEND; mal_result result = MAL_NO_BACKEND;
#ifdef MAL_ENABLE_WASAPI #ifdef MAL_ENABLE_WASAPI
if (result != MAL_SUCCESS) { if (result != MAL_SUCCESS) {
result = mal_enumerate_devices__wasapi(type, pCount, pInfo); result = mal_enumerate_devices__wasapi(pContext, type, pCount, pInfo);
} }
#endif #endif
#ifdef MAL_ENABLE_DSOUND #ifdef MAL_ENABLE_DSOUND
if (result != MAL_SUCCESS) { if (result != MAL_SUCCESS) {
result = mal_enumerate_devices__dsound(type, pCount, pInfo); result = mal_enumerate_devices__dsound(pContext, type, pCount, pInfo);
} }
#endif #endif
#ifdef MAL_ENABLE_ALSA #ifdef MAL_ENABLE_ALSA
if (result != MAL_SUCCESS) { if (result != MAL_SUCCESS) {
result = mal_enumerate_devices__alsa(type, pCount, pInfo); result = mal_enumerate_devices__alsa(pContext, type, pCount, pInfo);
} }
#endif #endif
#ifdef MAL_ENABLE_OPENSLES #ifdef MAL_ENABLE_OPENSLES
if (result != MAL_SUCCESS) { if (result != MAL_SUCCESS) {
result = mal_enumerate_devices__sles(type, pCount, pInfo); result = mal_enumerate_devices__sles(pContext, type, pCount, pInfo);
} }
#endif #endif
#ifdef MAL_ENABLE_NULL #ifdef MAL_ENABLE_NULL
if (result != MAL_SUCCESS) { if (result != MAL_SUCCESS) {
result = mal_enumerate_devices__null(type, pCount, pInfo); result = mal_enumerate_devices__null(pContext, type, pCount, pInfo);
} }
#endif #endif
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment