Commit 4d75af24 authored by David Reid's avatar David Reid

Improve error handling for the WASAPI backend.

parent 32da9fe5
...@@ -361,6 +361,8 @@ typedef int mal_result; ...@@ -361,6 +361,8 @@ typedef int mal_result;
#define MAL_WASAPI_FAILED_TO_ACTIVATE_DEVICE -3074 #define MAL_WASAPI_FAILED_TO_ACTIVATE_DEVICE -3074
#define MAL_WASAPI_FAILED_TO_INITIALIZE_DEVICE -3075 #define MAL_WASAPI_FAILED_TO_INITIALIZE_DEVICE -3075
#define MAL_WASAPI_FAILED_TO_FIND_BEST_FORMAT -3076 #define MAL_WASAPI_FAILED_TO_FIND_BEST_FORMAT -3076
#define MAL_WASAPI_FAILED_TO_GET_INTERNAL_BUFFER -3077
#define MAL_WASAPI_FAILED_TO_RELEASE_INTERNAL_BUFFER -3078
#define MAL_WINMM_FAILED_TO_GET_DEVICE_CAPS -4096 #define MAL_WINMM_FAILED_TO_GET_DEVICE_CAPS -4096
#define MAL_WINMM_FAILED_TO_GET_SUPPORTED_FORMATS -4097 #define MAL_WINMM_FAILED_TO_GET_SUPPORTED_FORMATS -4097
...@@ -2714,14 +2716,14 @@ static mal_result mal_enumerate_devices__wasapi(mal_context* pContext, mal_devic ...@@ -2714,14 +2716,14 @@ static mal_result mal_enumerate_devices__wasapi(mal_context* pContext, mal_devic
IMMDeviceEnumerator* pDeviceEnumerator; IMMDeviceEnumerator* pDeviceEnumerator;
HRESULT hr = mal_CoCreateInstance(pContext, g_malCLSID_MMDeviceEnumerator, NULL, CLSCTX_ALL, g_malIID_IMMDeviceEnumerator, (void**)&pDeviceEnumerator); HRESULT hr = mal_CoCreateInstance(pContext, g_malCLSID_MMDeviceEnumerator, NULL, CLSCTX_ALL, g_malIID_IMMDeviceEnumerator, (void**)&pDeviceEnumerator);
if (FAILED(hr)) { if (FAILED(hr)) {
return MAL_WASAPI_FAILED_TO_CREATE_DEVICE_ENUMERATOR; return mal_context_post_error(pContext, NULL, "[WASAPI] Failed to create device enumerator.", MAL_WASAPI_FAILED_TO_CREATE_DEVICE_ENUMERATOR);
} }
IMMDeviceCollection* pDeviceCollection; IMMDeviceCollection* pDeviceCollection;
hr = IMMDeviceEnumerator_EnumAudioEndpoints(pDeviceEnumerator, (type == mal_device_type_playback) ? eRender : eCapture, DEVICE_STATE_ACTIVE, &pDeviceCollection); hr = IMMDeviceEnumerator_EnumAudioEndpoints(pDeviceEnumerator, (type == mal_device_type_playback) ? eRender : eCapture, DEVICE_STATE_ACTIVE, &pDeviceCollection);
if (FAILED(hr)) { if (FAILED(hr)) {
IMMDeviceEnumerator_Release(pDeviceEnumerator); IMMDeviceEnumerator_Release(pDeviceEnumerator);
return MAL_NO_DEVICE; return mal_context_post_error(pContext, NULL, "[WASAPI] Failed to enumerate audio endpoints.", MAL_NO_DEVICE);
} }
IMMDeviceEnumerator_Release(pDeviceEnumerator); IMMDeviceEnumerator_Release(pDeviceEnumerator);
...@@ -2730,7 +2732,7 @@ static mal_result mal_enumerate_devices__wasapi(mal_context* pContext, mal_devic ...@@ -2730,7 +2732,7 @@ static mal_result mal_enumerate_devices__wasapi(mal_context* pContext, mal_devic
hr = IMMDeviceCollection_GetCount(pDeviceCollection, &count); hr = IMMDeviceCollection_GetCount(pDeviceCollection, &count);
if (FAILED(hr)) { if (FAILED(hr)) {
IMMDeviceCollection_Release(pDeviceCollection); IMMDeviceCollection_Release(pDeviceCollection);
return MAL_NO_DEVICE; return mal_context_post_error(pContext, NULL, "[WASAPI] Failed to get device count.", MAL_NO_DEVICE);
} }
for (mal_uint32 iDevice = 0; iDevice < infoSize && iDevice < count; ++iDevice) { for (mal_uint32 iDevice = 0; iDevice < infoSize && iDevice < count; ++iDevice) {
...@@ -3088,20 +3090,20 @@ static mal_result mal_device__start_backend__wasapi(mal_device* pDevice) ...@@ -3088,20 +3090,20 @@ static mal_result mal_device__start_backend__wasapi(mal_device* pDevice)
BYTE* pData; BYTE* pData;
HRESULT hr = IAudioRenderClient_GetBuffer(pDevice->wasapi.pRenderClient, pDevice->bufferSizeInFrames, &pData); HRESULT hr = IAudioRenderClient_GetBuffer(pDevice->wasapi.pRenderClient, pDevice->bufferSizeInFrames, &pData);
if (FAILED(hr)) { if (FAILED(hr)) {
return MAL_FAILED_TO_READ_DATA_FROM_CLIENT; return mal_post_error(pDevice, "[WASAPI] Failed to retrieve buffer from internal playback device.", MAL_WASAPI_FAILED_TO_GET_INTERNAL_BUFFER);
} }
mal_device__read_frames_from_client(pDevice, pDevice->bufferSizeInFrames, pData); mal_device__read_frames_from_client(pDevice, pDevice->bufferSizeInFrames, pData);
hr = IAudioRenderClient_ReleaseBuffer(pDevice->wasapi.pRenderClient, pDevice->bufferSizeInFrames, 0); hr = IAudioRenderClient_ReleaseBuffer(pDevice->wasapi.pRenderClient, pDevice->bufferSizeInFrames, 0);
if (FAILED(hr)) { if (FAILED(hr)) {
return MAL_FAILED_TO_READ_DATA_FROM_CLIENT; return mal_post_error(pDevice, "[WASAPI] Failed to release internal buffer for playback device.", MAL_WASAPI_FAILED_TO_RELEASE_INTERNAL_BUFFER);
} }
} }
HRESULT hr = IAudioClient_Start(pDevice->wasapi.pAudioClient); HRESULT hr = IAudioClient_Start(pDevice->wasapi.pAudioClient);
if (FAILED(hr)) { if (FAILED(hr)) {
return MAL_FAILED_TO_START_BACKEND_DEVICE; return mal_post_error(pDevice, "[WASAPI] Failed to start internal device.", MAL_FAILED_TO_START_BACKEND_DEVICE);
} }
return MAL_SUCCESS; return MAL_SUCCESS;
...@@ -3113,7 +3115,7 @@ static mal_result mal_device__stop_backend__wasapi(mal_device* pDevice) ...@@ -3113,7 +3115,7 @@ static mal_result mal_device__stop_backend__wasapi(mal_device* pDevice)
HRESULT hr = IAudioClient_Stop(pDevice->wasapi.pAudioClient); HRESULT hr = IAudioClient_Stop(pDevice->wasapi.pAudioClient);
if (FAILED(hr)) { if (FAILED(hr)) {
return MAL_FAILED_TO_STOP_BACKEND_DEVICE; return mal_post_error(pDevice, "[WASAPI] Failed to stop internal device.", MAL_FAILED_TO_STOP_BACKEND_DEVICE);
} }
return MAL_SUCCESS; return MAL_SUCCESS;
...@@ -3194,14 +3196,14 @@ static mal_result mal_device__main_loop__wasapi(mal_device* pDevice) ...@@ -3194,14 +3196,14 @@ static mal_result mal_device__main_loop__wasapi(mal_device* pDevice)
BYTE* pData; BYTE* pData;
HRESULT hr = IAudioRenderClient_GetBuffer(pDevice->wasapi.pRenderClient, framesAvailable, &pData); HRESULT hr = IAudioRenderClient_GetBuffer(pDevice->wasapi.pRenderClient, framesAvailable, &pData);
if (FAILED(hr)) { if (FAILED(hr)) {
return MAL_FAILED_TO_READ_DATA_FROM_CLIENT; return mal_post_error(pDevice, "[WASAPI] Failed to retrieve internal buffer from playback device in preparation for sending new data to the device.", MAL_WASAPI_FAILED_TO_GET_INTERNAL_BUFFER);
} }
mal_device__read_frames_from_client(pDevice, framesAvailable, pData); mal_device__read_frames_from_client(pDevice, framesAvailable, pData);
hr = IAudioRenderClient_ReleaseBuffer(pDevice->wasapi.pRenderClient, framesAvailable, 0); hr = IAudioRenderClient_ReleaseBuffer(pDevice->wasapi.pRenderClient, framesAvailable, 0);
if (FAILED(hr)) { if (FAILED(hr)) {
return MAL_FAILED_TO_READ_DATA_FROM_CLIENT; return mal_post_error(pDevice, "[WASAPI] Failed to release internal buffer from playback device in preparation for sending new data to the device.", MAL_WASAPI_FAILED_TO_RELEASE_INTERNAL_BUFFER);
} }
} else { } else {
UINT32 framesRemaining = framesAvailable; UINT32 framesRemaining = framesAvailable;
...@@ -3211,14 +3213,15 @@ static mal_result mal_device__main_loop__wasapi(mal_device* pDevice) ...@@ -3211,14 +3213,15 @@ static mal_result mal_device__main_loop__wasapi(mal_device* pDevice)
DWORD flags; DWORD flags;
HRESULT hr = IAudioCaptureClient_GetBuffer(pDevice->wasapi.pCaptureClient, &pData, &framesToSend, &flags, NULL, NULL); HRESULT hr = IAudioCaptureClient_GetBuffer(pDevice->wasapi.pCaptureClient, &pData, &framesToSend, &flags, NULL, NULL);
if (FAILED(hr)) { if (FAILED(hr)) {
mal_post_error(pDevice, "[WASAPI] WARNING: Failed to retrieve internal buffer from capture device in preparation for sending new data to the client.", MAL_WASAPI_FAILED_TO_GET_INTERNAL_BUFFER);
break; break;
} }
// NOTE: Do we need to handle the case when the AUDCLNT_BUFFERFLAGS_SILENT bit is set in <flags>?
mal_device__send_frames_to_client(pDevice, framesToSend, pData); mal_device__send_frames_to_client(pDevice, framesToSend, pData);
hr = IAudioCaptureClient_ReleaseBuffer(pDevice->wasapi.pCaptureClient, framesToSend); hr = IAudioCaptureClient_ReleaseBuffer(pDevice->wasapi.pCaptureClient, framesToSend);
if (FAILED(hr)) { if (FAILED(hr)) {
mal_post_error(pDevice, "[WASAPI] WARNING: Failed to release internal buffer from capture device in preparation for sending new data to the client.", MAL_WASAPI_FAILED_TO_RELEASE_INTERNAL_BUFFER);
break; break;
} }
......
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