From 6db23faa44e8c35dc6c6dd58ea5b330f9f3c89cd Mon Sep 17 00:00:00 2001
From: Sam Lantinga <[EMAIL REDACTED]>
Date: Sun, 2 Nov 2025 09:50:16 -0800
Subject: [PATCH] Clamp the audio drain delay to 100 ms
Fixes https://github.com/libsdl-org/SDL/issues/9829
(cherry picked from commit 08826230923dfb70e4558a41179ac0744e69fdb8)
---
src/audio/SDL_audio.c | 11 ++++++++---
src/audio/alsa/SDL_alsa_audio.c | 3 +++
2 files changed, 11 insertions(+), 3 deletions(-)
diff --git a/src/audio/SDL_audio.c b/src/audio/SDL_audio.c
index 1ab847aa490ea..75e89797d4b33 100644
--- a/src/audio/SDL_audio.c
+++ b/src/audio/SDL_audio.c
@@ -678,6 +678,7 @@ static int SDLCALL SDL_RunAudio(void *userdata)
int data_len = 0;
Uint8 *data;
Uint8 *device_buf_keepsafe = NULL;
+ Uint32 delay;
SDL_assert(!device->iscapture);
@@ -761,7 +762,7 @@ static int SDLCALL SDL_RunAudio(void *userdata)
SDL_assert((got <= 0) || (got == device->spec.size));
if (data == NULL) { /* device is having issues... */
- const Uint32 delay = ((device->spec.samples * 1000) / device->spec.freq);
+ delay = ((device->spec.samples * 1000) / device->spec.freq);
SDL_Delay(delay); /* wait for as long as this buffer would have played. Maybe device recovers later? */
} else {
if (got != device->spec.size) {
@@ -781,7 +782,7 @@ static int SDLCALL SDL_RunAudio(void *userdata)
}
} else if (data == device->work_buffer) {
/* nothing to do; pause like we queued a buffer to play. */
- const Uint32 delay = ((device->spec.samples * 1000) / device->spec.freq);
+ delay = ((device->spec.samples * 1000) / device->spec.freq);
SDL_Delay(delay);
} else { /* writing directly to the device. */
/* queue this buffer and wait for it to finish playing. */
@@ -791,7 +792,11 @@ static int SDLCALL SDL_RunAudio(void *userdata)
}
/* Wait for the audio to drain. */
- SDL_Delay(((device->spec.samples * 1000) / device->spec.freq) * 2);
+ delay = ((device->spec.samples * 1000) / device->spec.freq) * 2;
+ if (delay > 100) {
+ delay = 100;
+ }
+ SDL_Delay(delay);
current_audio.impl.ThreadDeinit(device);
diff --git a/src/audio/alsa/SDL_alsa_audio.c b/src/audio/alsa/SDL_alsa_audio.c
index b7d3edfaeb132..120244ab0060a 100644
--- a/src/audio/alsa/SDL_alsa_audio.c
+++ b/src/audio/alsa/SDL_alsa_audio.c
@@ -472,6 +472,9 @@ static void ALSA_CloseDevice(_THIS)
ALSA_snd_pcm_drop() can hang, so don't use that.
*/
Uint32 delay = ((this->spec.samples * 1000) / this->spec.freq) * 2;
+ if (delay > 100) {
+ delay = 100;
+ }
SDL_Delay(delay);
ALSA_snd_pcm_close(this->hidden->pcm_handle);