1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
|
diff --git a/miniaudio.h b/miniaudio.h
index 22b0e4f..49ecd9a 100644
--- a/miniaudio.h
+++ b/miniaudio.h
@@ -23061,6 +23061,26 @@ static ma_result ma_device_start__wasapi_nolock(ma_device* pDevice)
}
if (pDevice->type == ma_device_type_playback || pDevice->type == ma_device_type_duplex) {
+ ma_uint32 bufferSizeInFrames;
+ if (pDevice->playback.shareMode == ma_share_mode_exclusive) {
+ bufferSizeInFrames = pDevice->wasapi.actualBufferSizeInFramesPlayback;
+ } else {
+ bufferSizeInFrames = pDevice->wasapi.periodSizeInFramesPlayback;
+ }
+ hr = ma_IAudioRenderClient_GetBuffer((ma_IAudioRenderClient*)pDevice->wasapi.pRenderClient, bufferSizeInFrames, (BYTE**)&pDevice->wasapi.pMappedBufferPlayback);
+ if (FAILED(hr)) {
+ return ma_result_from_HRESULT(hr);
+ }
+ pDevice->wasapi.mappedBufferPlaybackCap = bufferSizeInFrames;
+ pDevice->wasapi.mappedBufferPlaybackLen = 0;
+
+ ma_device__read_frames_from_client(pDevice, bufferSizeInFrames, pDevice->wasapi.pMappedBufferPlayback);
+
+ ma_IAudioRenderClient_ReleaseBuffer((ma_IAudioRenderClient*)pDevice->wasapi.pRenderClient, pDevice->wasapi.mappedBufferPlaybackCap, 0);
+ pDevice->wasapi.pMappedBufferPlayback = NULL;
+ pDevice->wasapi.mappedBufferPlaybackCap = 0;
+ pDevice->wasapi.mappedBufferPlaybackLen = 0;
+
hr = ma_IAudioClient_Start((ma_IAudioClient*)pDevice->wasapi.pAudioClientPlayback);
if (FAILED(hr)) {
ma_log_postf(ma_device_get_log(pDevice), MA_LOG_LEVEL_ERROR, "[WASAPI] Failed to start internal playback device. HRESULT = %d.", (int)hr);
@@ -23136,6 +23156,7 @@ static ma_result ma_device_stop__wasapi_nolock(ma_device* pDevice)
DWORD waitTime = pDevice->wasapi.actualBufferSizeInFramesPlayback / (pDevice->playback.internalSampleRate / 1000);
if (pDevice->playback.shareMode == ma_share_mode_exclusive) {
+ ResetEvent((HANDLE)pDevice->wasapi.hEventPlayback);
WaitForSingleObject((HANDLE)pDevice->wasapi.hEventPlayback, waitTime);
} else {
ma_uint32 prevFramesAvailablePlayback = (ma_uint32)-1;
@@ -23415,7 +23436,23 @@ static ma_result ma_device_write__wasapi(ma_device* pDevice, const void* pFrames
ma_uint32 totalFramesProcessed = 0;
/* Keep writing to the device until it's stopped or we've consumed all of our input. */
- while (ma_device_get_state(pDevice) == ma_device_state_started && totalFramesProcessed < frameCount) {
+ while (totalFramesProcessed < frameCount) {
+ if (pDevice->playback.shareMode == ma_share_mode_exclusive && pDevice->wasapi.pMappedBufferPlayback == NULL) {
+ /*
+ In exclusive mode we need to wait here. Exclusive mode is weird because GetBuffer() never
+ seems to return AUDCLNT_E_BUFFER_TOO_LARGE, which is what we normally use to determine
+ whether or not we need to wait for more data.
+ */
+ if (WaitForSingleObject((HANDLE)pDevice->wasapi.hEventPlayback, MA_WASAPI_WAIT_TIMEOUT_MILLISECONDS) != WAIT_OBJECT_0) {
+ result = MA_ERROR;
+ break; /* Wait failed. Probably timed out. */
+ }
+ }
+
+ if (ma_device_get_state(pDevice) != ma_device_state_started) {
+ break;
+ }
+
ma_uint32 framesRemaining = frameCount - totalFramesProcessed;
/*
@@ -23448,18 +23485,6 @@ static ma_result ma_device_write__wasapi(ma_device* pDevice, const void* pFrames
pDevice->wasapi.pMappedBufferPlayback = NULL;
pDevice->wasapi.mappedBufferPlaybackCap = 0;
pDevice->wasapi.mappedBufferPlaybackLen = 0;
-
- /*
- In exclusive mode we need to wait here. Exclusive mode is weird because GetBuffer() never
- seems to return AUDCLNT_E_BUFFER_TOO_LARGE, which is what we normally use to determine
- whether or not we need to wait for more data.
- */
- if (pDevice->playback.shareMode == ma_share_mode_exclusive) {
- if (WaitForSingleObject((HANDLE)pDevice->wasapi.hEventPlayback, MA_WASAPI_WAIT_TIMEOUT_MILLISECONDS) != WAIT_OBJECT_0) {
- result = MA_ERROR;
- break; /* Wait failed. Probably timed out. */
- }
- }
}
} else {
/* We don't have a mapped data buffer so we'll need to get one. */
|