directsound: Cleaned up WaitDevice.

This should retry until GetCurrentPosition succeeds. Otherwise, we would be
going on to the next iteration too soon.

Also generally streamlined the code while I was in here.
This commit is contained in:
Ryan C. Gordon 2023-10-03 09:54:30 -04:00
parent 6c33a05bdb
commit a0820ed833
No known key found for this signature in database
GPG Key ID: FA148B892AB48044
1 changed files with 16 additions and 42 deletions

View File

@ -227,61 +227,35 @@ static void DSOUND_DetectDevices(SDL_AudioDevice **default_output, SDL_AudioDevi
static void DSOUND_WaitDevice(SDL_AudioDevice *device)
{
DWORD status = 0;
DWORD cursor = 0;
DWORD junk = 0;
HRESULT result = DS_OK;
/* Semi-busy wait, since we have no way of getting play notification
on a primary mixing buffer located in hardware (DirectX 5.0)
*/
result = IDirectSoundBuffer_GetCurrentPosition(device->hidden->mixbuf,
&junk, &cursor);
if (result != DS_OK) {
if (result == DSERR_BUFFERLOST) {
IDirectSoundBuffer_Restore(device->hidden->mixbuf);
}
#ifdef DEBUG_SOUND
SetDSerror("DirectSound GetCurrentPosition", result);
#endif
return;
}
while ((cursor / device->buffer_size) == device->hidden->lastchunk) {
if (SDL_AtomicGet(&device->shutdown)) {
return;
}
SDL_Delay(1);
while (!SDL_AtomicGet(&device->shutdown)) {
DWORD status = 0;
DWORD cursor = 0;
DWORD junk = 0;
HRESULT result = DS_OK;
// Try to restore a lost sound buffer
IDirectSoundBuffer_GetStatus(device->hidden->mixbuf, &status);
if (status & DSBSTATUS_BUFFERLOST) {
IDirectSoundBuffer_Restore(device->hidden->mixbuf);
IDirectSoundBuffer_GetStatus(device->hidden->mixbuf, &status);
if (status & DSBSTATUS_BUFFERLOST) {
break;
} else if (!(status & DSBSTATUS_PLAYING)) {
result = IDirectSoundBuffer_Play(device->hidden->mixbuf, 0, 0, DSBPLAY_LOOPING);
} else {
// Find out where we are playing
result = IDirectSoundBuffer_GetCurrentPosition(device->hidden->mixbuf, &junk, &cursor);
if ((result == DS_OK) && ((cursor / device->buffer_size) != device->hidden->lastchunk)) {
break; // ready for next chunk!
}
}
if (!(status & DSBSTATUS_PLAYING)) {
result = IDirectSoundBuffer_Play(device->hidden->mixbuf, 0, 0,
DSBPLAY_LOOPING);
if (result == DS_OK) {
continue;
}
#ifdef DEBUG_SOUND
SetDSerror("DirectSound Play", result);
#endif
if ((result != DS_OK) && (result != DSERR_BUFFERLOST)) {
SDL_AudioDeviceDisconnected(device);
return;
}
// Find out where we are playing
result = IDirectSoundBuffer_GetCurrentPosition(device->hidden->mixbuf,
&junk, &cursor);
if (result != DS_OK) {
SetDSerror("DirectSound GetCurrentPosition", result);
return;
}
SDL_Delay(1); // not ready yet; sleep a bit.
}
}