summaryrefslogtreecommitdiff
path: root/subprojects/packagefiles/miniaudio/miniaudio_wasapi_exclusive_testing.diff
blob: 994a7500bb3a8ddd6b2bc81ce605837dc7b61b72 (plain)
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. */