mirror of
https://github.com/mackron/miniaudio.git
synced 2026-04-23 16:54:03 +02:00
WASAPI: A few tweaks for handling device changes.
This commit is contained in:
+23
-23
@@ -11911,7 +11911,7 @@ static HRESULT STDMETHODCALLTYPE ma_IMMNotificationClient_OnDeviceStateChanged(m
|
|||||||
ma_bool32 isThisDevice = MA_FALSE;
|
ma_bool32 isThisDevice = MA_FALSE;
|
||||||
|
|
||||||
#ifdef MA_DEBUG_OUTPUT
|
#ifdef MA_DEBUG_OUTPUT
|
||||||
printf("IMMNotificationClient_OnDeviceStateChanged(pDeviceID=%S, dwNewState=%u)\n", (pDeviceID != NULL) ? pDeviceID : L"(NULL)", (unsigned int)dwNewState);
|
/*printf("IMMNotificationClient_OnDeviceStateChanged(pDeviceID=%S, dwNewState=%u)\n", (pDeviceID != NULL) ? pDeviceID : L"(NULL)", (unsigned int)dwNewState);*/
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if ((dwNewState & MA_MM_DEVICE_STATE_ACTIVE) != 0) {
|
if ((dwNewState & MA_MM_DEVICE_STATE_ACTIVE) != 0) {
|
||||||
@@ -11922,13 +11922,13 @@ static HRESULT STDMETHODCALLTYPE ma_IMMNotificationClient_OnDeviceStateChanged(m
|
|||||||
There have been reports of a hang when a playback device is disconnected. The idea with this code is to explicitly stop the device if we detect
|
There have been reports of a hang when a playback device is disconnected. The idea with this code is to explicitly stop the device if we detect
|
||||||
that the device is disabled or has been unplugged.
|
that the device is disabled or has been unplugged.
|
||||||
*/
|
*/
|
||||||
if (pThis->pDevice->type == ma_device_type_capture || pThis->pDevice->type == ma_device_type_duplex || pThis->pDevice->type == ma_device_type_loopback) {
|
if (pThis->pDevice->wasapi.allowCaptureAutoStreamRouting && (pThis->pDevice->type == ma_device_type_capture || pThis->pDevice->type == ma_device_type_duplex || pThis->pDevice->type == ma_device_type_loopback)) {
|
||||||
if (wcscmp(pThis->pDevice->capture.id.wasapi, pDeviceID) == 0) {
|
if (wcscmp(pThis->pDevice->capture.id.wasapi, pDeviceID) == 0) {
|
||||||
isThisDevice = MA_TRUE;
|
isThisDevice = MA_TRUE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pThis->pDevice->type == ma_device_type_playback || pThis->pDevice->type == ma_device_type_duplex) {
|
if (pThis->pDevice->wasapi.allowPlaybackAutoStreamRouting && (pThis->pDevice->type == ma_device_type_playback || pThis->pDevice->type == ma_device_type_duplex)) {
|
||||||
if (wcscmp(pThis->pDevice->playback.id.wasapi, pDeviceID) == 0) {
|
if (wcscmp(pThis->pDevice->playback.id.wasapi, pDeviceID) == 0) {
|
||||||
isThisDevice = MA_TRUE;
|
isThisDevice = MA_TRUE;
|
||||||
}
|
}
|
||||||
@@ -13233,6 +13233,8 @@ static ma_result ma_device_reinit__wasapi(ma_device* pDevice, ma_device_type dev
|
|||||||
static ma_result ma_device_init__wasapi(ma_context* pContext, const ma_device_config* pConfig, ma_device* pDevice)
|
static ma_result ma_device_init__wasapi(ma_context* pContext, const ma_device_config* pConfig, ma_device* pDevice)
|
||||||
{
|
{
|
||||||
ma_result result = MA_SUCCESS;
|
ma_result result = MA_SUCCESS;
|
||||||
|
HRESULT hr;
|
||||||
|
ma_IMMDeviceEnumerator* pDeviceEnumerator;
|
||||||
|
|
||||||
(void)pContext;
|
(void)pContext;
|
||||||
|
|
||||||
@@ -13401,38 +13403,36 @@ static ma_result ma_device_init__wasapi(ma_context* pContext, const ma_device_co
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
We need to get notifications of when the default device changes. We do this through a device enumerator by
|
We need to register a notification client to detect when the device has been disabled, unplugged or re-routed (when the default device changes). When
|
||||||
registering a IMMNotificationClient with it. We only care about this if it's the default device.
|
we are connecting to the default device we want to do automatic stream routing when the device is disabled or unplugged. Otherwise we want to just
|
||||||
|
stop the device outright and let the application handle it.
|
||||||
*/
|
*/
|
||||||
#ifdef MA_WIN32_DESKTOP
|
#ifdef MA_WIN32_DESKTOP
|
||||||
if (pConfig->wasapi.noAutoStreamRouting == MA_FALSE) {
|
if (pConfig->wasapi.noAutoStreamRouting == MA_FALSE) {
|
||||||
ma_IMMDeviceEnumerator* pDeviceEnumerator;
|
|
||||||
HRESULT hr;
|
|
||||||
|
|
||||||
if ((pConfig->deviceType == ma_device_type_capture || pConfig->deviceType == ma_device_type_duplex) && pConfig->capture.pDeviceID == NULL) {
|
if ((pConfig->deviceType == ma_device_type_capture || pConfig->deviceType == ma_device_type_duplex) && pConfig->capture.pDeviceID == NULL) {
|
||||||
pDevice->wasapi.allowCaptureAutoStreamRouting = MA_TRUE;
|
pDevice->wasapi.allowCaptureAutoStreamRouting = MA_TRUE;
|
||||||
}
|
}
|
||||||
if ((pConfig->deviceType == ma_device_type_playback || pConfig->deviceType == ma_device_type_duplex) && pConfig->playback.pDeviceID == NULL) {
|
if ((pConfig->deviceType == ma_device_type_playback || pConfig->deviceType == ma_device_type_duplex) && pConfig->playback.pDeviceID == NULL) {
|
||||||
pDevice->wasapi.allowPlaybackAutoStreamRouting = MA_TRUE;
|
pDevice->wasapi.allowPlaybackAutoStreamRouting = MA_TRUE;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
hr = ma_CoCreateInstance(pContext, MA_CLSID_MMDeviceEnumerator, NULL, CLSCTX_ALL, MA_IID_IMMDeviceEnumerator, (void**)&pDeviceEnumerator);
|
hr = ma_CoCreateInstance(pContext, MA_CLSID_MMDeviceEnumerator, NULL, CLSCTX_ALL, MA_IID_IMMDeviceEnumerator, (void**)&pDeviceEnumerator);
|
||||||
if (FAILED(hr)) {
|
if (FAILED(hr)) {
|
||||||
ma_device_uninit__wasapi(pDevice);
|
ma_device_uninit__wasapi(pDevice);
|
||||||
return ma_post_error(pDevice, MA_LOG_LEVEL_ERROR, "[WASAPI] Failed to create device enumerator.", ma_result_from_HRESULT(hr));
|
return ma_post_error(pDevice, MA_LOG_LEVEL_ERROR, "[WASAPI] Failed to create device enumerator.", ma_result_from_HRESULT(hr));
|
||||||
}
|
}
|
||||||
|
|
||||||
pDevice->wasapi.notificationClient.lpVtbl = (void*)&g_maNotificationCientVtbl;
|
pDevice->wasapi.notificationClient.lpVtbl = (void*)&g_maNotificationCientVtbl;
|
||||||
pDevice->wasapi.notificationClient.counter = 1;
|
pDevice->wasapi.notificationClient.counter = 1;
|
||||||
pDevice->wasapi.notificationClient.pDevice = pDevice;
|
pDevice->wasapi.notificationClient.pDevice = pDevice;
|
||||||
|
|
||||||
hr = pDeviceEnumerator->lpVtbl->RegisterEndpointNotificationCallback(pDeviceEnumerator, &pDevice->wasapi.notificationClient);
|
hr = pDeviceEnumerator->lpVtbl->RegisterEndpointNotificationCallback(pDeviceEnumerator, &pDevice->wasapi.notificationClient);
|
||||||
if (SUCCEEDED(hr)) {
|
if (SUCCEEDED(hr)) {
|
||||||
pDevice->wasapi.pDeviceEnumerator = (ma_ptr)pDeviceEnumerator;
|
pDevice->wasapi.pDeviceEnumerator = (ma_ptr)pDeviceEnumerator;
|
||||||
} else {
|
} else {
|
||||||
/* Not the end of the world if we fail to register the notification callback. We just won't support automatic stream routing. */
|
/* Not the end of the world if we fail to register the notification callback. We just won't support automatic stream routing. */
|
||||||
ma_IMMDeviceEnumerator_Release(pDeviceEnumerator);
|
ma_IMMDeviceEnumerator_Release(pDeviceEnumerator);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user