DirectSound: Attempted fix for an error when switching devices.

Public issue https://github.com/mackron/miniaudio/issues/779
This commit is contained in:
David Reid
2024-01-08 12:50:20 +10:00
parent bdab2fc3e0
commit 10f9ef05a2
+23
View File
@@ -23680,6 +23680,13 @@ DirectSound Backend
#define MA_DSBPLAY_TERMINATEBY_DISTANCE 0x00000010 #define MA_DSBPLAY_TERMINATEBY_DISTANCE 0x00000010
#define MA_DSBPLAY_TERMINATEBY_PRIORITY 0x00000020 #define MA_DSBPLAY_TERMINATEBY_PRIORITY 0x00000020
#define MA_DSBSTATUS_PLAYING 0x00000001
#define MA_DSBSTATUS_BUFFERLOST 0x00000002
#define MA_DSBSTATUS_LOOPING 0x00000004
#define MA_DSBSTATUS_LOCHARDWARE 0x00000008
#define MA_DSBSTATUS_LOCSOFTWARE 0x00000010
#define MA_DSBSTATUS_TERMINATED 0x00000020
#define MA_DSCBSTART_LOOPING 0x00000001 #define MA_DSCBSTART_LOOPING 0x00000001
typedef struct typedef struct
@@ -24842,6 +24849,7 @@ static ma_result ma_device_data_loop__dsound(ma_device* pDevice)
ma_bool32 isPlaybackDeviceStarted = MA_FALSE; ma_bool32 isPlaybackDeviceStarted = MA_FALSE;
ma_uint32 framesWrittenToPlaybackDevice = 0; /* For knowing whether or not the playback device needs to be started. */ ma_uint32 framesWrittenToPlaybackDevice = 0; /* For knowing whether or not the playback device needs to be started. */
ma_uint32 waitTimeInMilliseconds = 1; ma_uint32 waitTimeInMilliseconds = 1;
DWORD playbackBufferStatus = 0;
MA_ASSERT(pDevice != NULL); MA_ASSERT(pDevice != NULL);
@@ -25170,6 +25178,21 @@ static ma_result ma_device_data_loop__dsound(ma_device* pDevice)
break; break;
} }
hr = ma_IDirectSoundBuffer_GetStatus((ma_IDirectSoundBuffer*)pDevice->dsound.pPlaybackBuffer, &playbackBufferStatus);
if (SUCCEEDED(hr) && (playbackBufferStatus & MA_DSBSTATUS_PLAYING) == 0 && isPlaybackDeviceStarted)
{
ma_log_postf(ma_device_get_log(pDevice), MA_LOG_LEVEL_INFO, "[DirectSound] Attempting to resume audio due to state: %d.", (int)playbackBufferStatus);
hr = ma_IDirectSoundBuffer_Play((ma_IDirectSoundBuffer*)pDevice->dsound.pPlaybackBuffer, 0, 0, MA_DSBPLAY_LOOPING);
if (FAILED(hr)) {
ma_log_postf(ma_device_get_log(pDevice), MA_LOG_LEVEL_ERROR, "[DirectSound] IDirectSoundBuffer_Play() failed after attempting to resume from state %d.", (int)playbackBufferStatus);
return ma_result_from_HRESULT(hr);
}
isPlaybackDeviceStarted = MA_TRUE;
ma_sleep(waitTimeInMilliseconds);
continue;
}
if (physicalPlayCursorInBytes < prevPlayCursorInBytesPlayback) { if (physicalPlayCursorInBytes < prevPlayCursorInBytesPlayback) {
physicalPlayCursorLoopFlagPlayback = !physicalPlayCursorLoopFlagPlayback; physicalPlayCursorLoopFlagPlayback = !physicalPlayCursorLoopFlagPlayback;
} }