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.
This commit is contained in:
Petter Reinholdtsen 2025-02-24 15:07:43 +01:00 committed by Sam Lantinga
parent deadfe0c98
commit 35544df838
1 changed files with 8 additions and 7 deletions

View File

@ -543,7 +543,7 @@ static void PULSEAUDIO_FlushRecording(SDL_AudioDevice *device)
{ {
struct SDL_PrivateAudioData *h = device->hidden; struct SDL_PrivateAudioData *h = device->hidden;
const void *data = NULL; const void *data = NULL;
size_t nbytes = 0; size_t nbytes = 0, buflen = 0;
PULSEAUDIO_pa_threaded_mainloop_lock(pulseaudio_threaded_mainloop); PULSEAUDIO_pa_threaded_mainloop_lock(pulseaudio_threaded_mainloop);
@ -553,7 +553,8 @@ static void PULSEAUDIO_FlushRecording(SDL_AudioDevice *device)
h->recordinglen = 0; 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); 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)) { 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!"); //SDL_Log("PULSEAUDIO DEVICE FAILURE IN FLUSHRECORDING!");
@ -561,11 +562,11 @@ static void PULSEAUDIO_FlushRecording(SDL_AudioDevice *device)
break; break;
} }
if (PULSEAUDIO_pa_stream_readable_size(h->stream) > 0) { // a fragment of audio present before FlushCapture was call is
// a new fragment is available! Just dump it. // still available! Just drop it.
PULSEAUDIO_pa_stream_peek(h->stream, &data, &nbytes); PULSEAUDIO_pa_stream_peek(h->stream, &data, &nbytes);
PULSEAUDIO_pa_stream_drop(h->stream); // drop this fragment. PULSEAUDIO_pa_stream_drop(h->stream);
} buflen -= nbytes;
} }
PULSEAUDIO_pa_threaded_mainloop_unlock(pulseaudio_threaded_mainloop); PULSEAUDIO_pa_threaded_mainloop_unlock(pulseaudio_threaded_mainloop);