Commit 6ec93e90 authored by David Reid's avatar David Reid

DirectSound: Improve rewind latency.

parent d984e39e
...@@ -231,6 +231,7 @@ struct mal_device ...@@ -231,6 +231,7 @@ struct mal_device
/*LPDIRECTSOUNDCAPTURE8*/ mal_ptr pCapture; /*LPDIRECTSOUNDCAPTURE8*/ mal_ptr pCapture;
/*LPDIRECTSOUNDCAPTUREBUFFER8*/ mal_ptr pCaptureBuffer; /*LPDIRECTSOUNDCAPTUREBUFFER8*/ mal_ptr pCaptureBuffer;
/*HANDLE*/ mal_handle hStopEvent; /*HANDLE*/ mal_handle hStopEvent;
/*HANDLE*/ mal_handle hRewindEvent;
mal_uint32 lastProcessedFrame; // This is circular. mal_uint32 lastProcessedFrame; // This is circular.
mal_uint32 rewindTarget; // Where we want to rewind to. Set to ~0UL when it is not being rewound. mal_uint32 rewindTarget; // Where we want to rewind to. Set to ~0UL when it is not being rewound.
mal_bool32 breakFromMainLoop; mal_bool32 breakFromMainLoop;
...@@ -1436,6 +1437,9 @@ static void mal_device_uninit__dsound(mal_device* pDevice) ...@@ -1436,6 +1437,9 @@ static void mal_device_uninit__dsound(mal_device* pDevice)
mal_assert(pDevice != NULL); mal_assert(pDevice != NULL);
if (pDevice->dsound.hDSoundDLL != NULL) { if (pDevice->dsound.hDSoundDLL != NULL) {
if (pDevice->dsound.hRewindEvent) {
CloseHandle(pDevice->dsound.hRewindEvent);
}
if (pDevice->dsound.hStopEvent) { if (pDevice->dsound.hStopEvent) {
CloseHandle(pDevice->dsound.hStopEvent); CloseHandle(pDevice->dsound.hStopEvent);
} }
...@@ -1641,6 +1645,12 @@ static mal_result mal_device_init__dsound(mal_device* pDevice, mal_device_type t ...@@ -1641,6 +1645,12 @@ static mal_result mal_device_init__dsound(mal_device* pDevice, mal_device_type t
return mal_post_error(pDevice, "[DirectSound] Failed to create event for main loop break notification.", MAL_FAILED_TO_CREATE_EVENT); return mal_post_error(pDevice, "[DirectSound] Failed to create event for main loop break notification.", MAL_FAILED_TO_CREATE_EVENT);
} }
// When the device is rewound we need to signal an event to ensure the main loop can handle it ASAP.
pDevice->dsound.hRewindEvent = CreateEventA(NULL, FALSE, FALSE, NULL);
if (pDevice->dsound.hRewindEvent == NULL) {
mal_device_uninit__dsound(pDevice);
return mal_post_error(pDevice, "[DirectSound] Failed to create event for main loop rewind notification.", MAL_FAILED_TO_CREATE_EVENT);
}
return MAL_SUCCESS; return MAL_SUCCESS;
} }
...@@ -1802,10 +1812,10 @@ static mal_uint32 mal_device__wait_for_frames__dsound(mal_device* pDevice) ...@@ -1802,10 +1812,10 @@ static mal_uint32 mal_device__wait_for_frames__dsound(mal_device* pDevice)
} }
// If we get here it means we weren't able to find any frames. We'll just wait here for a bit. // If we get here it means we weren't able to find any frames. We'll just wait here for a bit.
DWORD rc = WaitForMultipleObjects(1, &pDevice->dsound.hStopEvent, FALSE, timeoutInMilliseconds); HANDLE pEvents[2];
if (rc == WAIT_OBJECT_0) { pEvents[0] = pDevice->dsound.hStopEvent;
return 0; pEvents[1] = pDevice->dsound.hRewindEvent;
} WaitForMultipleObjects(sizeof(pEvents) / sizeof(pEvents[0]), pEvents, FALSE, timeoutInMilliseconds);
} }
// We'll get here if the loop was terminated. Just return whatever's available. // We'll get here if the loop was terminated. Just return whatever's available.
...@@ -1911,6 +1921,7 @@ static mal_uint32 mal_device_rewind__dsound(mal_device* pDevice, mal_uint32 fram ...@@ -1911,6 +1921,7 @@ static mal_uint32 mal_device_rewind__dsound(mal_device* pDevice, mal_uint32 fram
mal_uint32 desiredPosition = (pDevice->dsound.lastProcessedFrame + pDevice->bufferSizeInFrames - framesToRewind) % pDevice->bufferSizeInFrames; // Wrap around. mal_uint32 desiredPosition = (pDevice->dsound.lastProcessedFrame + pDevice->bufferSizeInFrames - framesToRewind) % pDevice->bufferSizeInFrames; // Wrap around.
mal_atomic_exchange_32(&pDevice->dsound.rewindTarget, desiredPosition); mal_atomic_exchange_32(&pDevice->dsound.rewindTarget, desiredPosition);
SetEvent(pDevice->dsound.hRewindEvent); // Make sure the main loop is woken up so it can handle the rewind ASAP.
return framesToRewind; return framesToRewind;
} }
#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