SDL: Changed PULSEAUDIO_FlushRecording() to only flush audio present when called.

From 35544df838bf4feff4e5ffbb68c69825393e252e Mon Sep 17 00:00:00 2001
From: Petter Reinholdtsen <[EMAIL REDACTED]>
Date: Mon, 24 Feb 2025 15:07:43 +0100
Subject: [PATCH] Changed PULSEAUDIO_FlushRecording() to only flush audio
 present when called.

When the flushing is not able to keep up with the audio stream coming in, it
will end up flushing forever and block API clients from getting any audio.

The example program in #9706 get some audio with SDL 3, while do not get any
audio with SDL 2, which I suspect is because SDL 3 is quicker at flushing the audio.
A fix for the SDL 2 issue is available in #12378.
---
 src/audio/pulseaudio/SDL_pulseaudio.c | 15 ++++++++-------
 1 file changed, 8 insertions(+), 7 deletions(-)

diff --git a/src/audio/pulseaudio/SDL_pulseaudio.c b/src/audio/pulseaudio/SDL_pulseaudio.c
index 886dbd8ffdbcf..049a5ec698997 100644
--- a/src/audio/pulseaudio/SDL_pulseaudio.c
+++ b/src/audio/pulseaudio/SDL_pulseaudio.c
@@ -543,7 +543,7 @@ static void PULSEAUDIO_FlushRecording(SDL_AudioDevice *device)
 {
     struct SDL_PrivateAudioData *h = device->hidden;
     const void *data = NULL;
-    size_t nbytes = 0;
+    size_t nbytes = 0, buflen = 0;
 
     PULSEAUDIO_pa_threaded_mainloop_lock(pulseaudio_threaded_mainloop);
 
@@ -553,7 +553,8 @@ static void PULSEAUDIO_FlushRecording(SDL_AudioDevice *device)
         h->recordinglen = 0;
     }
 
-    while (!SDL_GetAtomicInt(&device->shutdown) && (PULSEAUDIO_pa_stream_readable_size(h->stream) > 0)) {
+    buflen = PULSEAUDIO_pa_stream_readable_size(h->stream);
+    while (!SDL_GetAtomicInt(&device->shutdown) && (buflen > 0)) {
         PULSEAUDIO_pa_threaded_mainloop_wait(pulseaudio_threaded_mainloop);
         if ((PULSEAUDIO_pa_context_get_state(pulseaudio_context) != PA_CONTEXT_READY) || (PULSEAUDIO_pa_stream_get_state(h->stream) != PA_STREAM_READY)) {
             //SDL_Log("PULSEAUDIO DEVICE FAILURE IN FLUSHRECORDING!");
@@ -561,11 +562,11 @@ static void PULSEAUDIO_FlushRecording(SDL_AudioDevice *device)
             break;
         }
 
-        if (PULSEAUDIO_pa_stream_readable_size(h->stream) > 0) {
-            // a new fragment is available! Just dump it.
-            PULSEAUDIO_pa_stream_peek(h->stream, &data, &nbytes);
-            PULSEAUDIO_pa_stream_drop(h->stream); // drop this fragment.
-        }
+        // a fragment of audio present before FlushCapture was call is
+        // still available! Just drop it.
+        PULSEAUDIO_pa_stream_peek(h->stream, &data, &nbytes);
+        PULSEAUDIO_pa_stream_drop(h->stream);
+        buflen -= nbytes;
     }
 
     PULSEAUDIO_pa_threaded_mainloop_unlock(pulseaudio_threaded_mainloop);