sdl2-compat: audio: Simplify audio device queueing.

From d63403e84e6a44f9cd40f2490dd488e8a04b159f Mon Sep 17 00:00:00 2001
From: "Ryan C. Gordon" <[EMAIL REDACTED]>
Date: Tue, 4 Feb 2025 10:57:41 -0500
Subject: [PATCH] audio: Simplify audio device queueing.

This used to have a callback that would transfer audio from one stream to
another on demand, but this was silly: just bind the original stream to the
device instead and cut out the middleman entirely.

Fixes #311.
---
 src/sdl2_compat.c | 59 ++++++++---------------------------------------
 src/sdl2_compat.h |  1 -
 2 files changed, 10 insertions(+), 50 deletions(-)

diff --git a/src/sdl2_compat.c b/src/sdl2_compat.c
index 91df91d..64517cb 100644
--- a/src/sdl2_compat.c
+++ b/src/sdl2_compat.c
@@ -5947,31 +5947,6 @@ static int PrepareAudiospec(const SDL2_AudioSpec *orig2, SDL2_AudioSpec *prepare
     return 1;
 }
 
-static void SDLCALL SDL2AudioDeviceQueueingCallback(void *userdata, SDL_AudioStream *stream3, int approx_amount, int total_amount)
-{
-    SDL2_AudioStream *stream2 = (SDL2_AudioStream *) userdata;
-
-    SDL_assert(stream2 != NULL);
-    SDL_assert(stream3 == stream2->stream3);
-    SDL_assert(stream2->dataqueue3 != NULL);
-
-    if (approx_amount == 0) {
-        return;  /* nothing to do right now. */
-    }
-
-    if (stream2->iscapture) {
-        const int br = SDL_AudioStreamGet(stream2, stream2->callback2_buffer, SDL_min(stream2->bytes_per_callbacks, approx_amount));
-        if (br > 0) {
-            SDL3_PutAudioStreamData(stream2->dataqueue3, stream2->callback2_buffer, br);
-        }
-    } else {
-        const int br = SDL3_GetAudioStreamData(stream2->dataqueue3, stream2->callback2_buffer, SDL_min(stream2->bytes_per_callbacks, approx_amount));
-        if (br > 0) {
-            SDL_AudioStreamPut(stream2, stream2->callback2_buffer, br);
-        }
-    }
-}
-
 static void SDLCALL SDL2AudioDeviceCallbackBridge(void *userdata, SDL_AudioStream *stream3, int approx_amount, int total_amount)
 {
     SDL2_AudioStream *stream2 = (SDL2_AudioStream *) userdata;
@@ -5982,7 +5957,7 @@ static void SDLCALL SDL2AudioDeviceCallbackBridge(void *userdata, SDL_AudioStrea
 
     SDL_assert(stream2 != NULL);
     SDL_assert(stream3 == stream2->stream3);
-    SDL_assert(stream2->dataqueue3 == NULL);
+    SDL_assert(stream2->callback2 != NULL);
 
     if (stream2->iscapture) {
         while (SDL_AudioStreamAvailable(stream2) >= stream2->bytes_per_callbacks) {
@@ -6116,19 +6091,6 @@ static SDL_AudioDeviceID OpenAudioDeviceLocked(const char *devicename, int iscap
         } else {
             SDL3_SetAudioStreamGetCallback(stream2->stream3, SDL2AudioDeviceCallbackBridge, stream2);
         }
-    } else {
-        /* SDL2 treats this as a simple data queue that doesn't convert before the audio callback gets it,
-           so just make a second audiostream with no conversion and let it work like a flexible buffer. */
-        stream2->dataqueue3 = SDL3_CreateAudioStream(&spec3, &spec3);
-        if (!stream2->dataqueue3) {
-            SDL3_CloseAudioDevice(device3);
-            SDL_FreeAudioStream(stream2);
-        }
-        if (iscapture) {
-            SDL3_SetAudioStreamPutCallback(stream2->stream3, SDL2AudioDeviceQueueingCallback, stream2);
-        } else {
-            SDL3_SetAudioStreamGetCallback(stream2->stream3, SDL2AudioDeviceQueueingCallback, stream2);
-        }
     }
 
     if (!SDL3_BindAudioStream(device3, stream2->stream3)) {
@@ -6348,7 +6310,6 @@ SDL_FreeAudioStream(SDL2_AudioStream *stream2)
 {
     if (stream2) {
         SDL3_DestroyAudioStream(stream2->stream3);
-        SDL3_DestroyAudioStream(stream2->dataqueue3);
         SDL3_free(stream2->callback2_buffer);
         SDL3_free(stream2);
     }
@@ -6407,7 +6368,7 @@ SDL_DECLSPEC Uint32 SDLCALL
 SDL_GetQueuedAudioSize(SDL_AudioDeviceID dev)
 {
     SDL2_AudioStream *stream2 = GetOpenAudioDevice(dev);
-    return (stream2 && (stream2->dataqueue3 != NULL)) ? SDL3_GetAudioStreamAvailable(stream2->dataqueue3) : 0;
+    return (stream2 && (stream2->callback2 == NULL)) ? SDL3_GetAudioStreamAvailable(stream2->stream3) : 0;
 }
 
 SDL_DECLSPEC int SDLCALL
@@ -6419,15 +6380,15 @@ SDL_QueueAudio(SDL_AudioDeviceID dev, const void *data, Uint32 len)
     } else if (stream2->iscapture) {
         SDL3_SetError("This is a capture device, queueing not allowed");
         return -1;
-    } else if (stream2->dataqueue3 == NULL) {
+    } else if (stream2->callback2 != NULL) {
         SDL3_SetError("Audio device has a callback, queueing not allowed");
         return -1;
     } else if (len == 0) {
         return 0;  /* nothing to do. */
     }
 
-    SDL_assert(stream2->dataqueue3 != NULL);
-    return SDL3_PutAudioStreamData(stream2->dataqueue3, data, len) ? 0 : -1;
+    SDL_assert(stream2->stream3 != NULL);
+    return SDL3_PutAudioStreamData(stream2->stream3, data, len) ? 0 : -1;
 }
 
 SDL_DECLSPEC Uint32 SDLCALL
@@ -6437,20 +6398,20 @@ SDL_DequeueAudio(SDL_AudioDeviceID dev, void *data, Uint32 len)
     if ((len == 0) ||                      /* nothing to do? */
         (!stream2) ||                      /* called with bogus device id */
         (!stream2->iscapture) ||           /* playback devices can't dequeue */
-        (stream2->dataqueue3 == NULL)) {   /* not set for queueing */
+        (stream2->callback2 != NULL)) {    /* not set for queueing */
         return 0;                          /* just report zero bytes dequeued. */
     }
 
-    SDL_assert(stream2->dataqueue3 != NULL);
-    return SDL3_GetAudioStreamData(stream2->dataqueue3, data, len);
+    SDL_assert(stream2->stream3 != NULL);
+    return SDL3_GetAudioStreamData(stream2->stream3, data, len);
 }
 
 SDL_DECLSPEC void SDLCALL
 SDL_ClearQueuedAudio(SDL_AudioDeviceID dev)
 {
     SDL2_AudioStream *stream2 = GetOpenAudioDevice(dev);
-    if (stream2 && stream2->dataqueue3) {
-        SDL3_ClearAudioStream(stream2->dataqueue3);
+    if (stream2 && !stream2->callback2) {
+        SDL3_ClearAudioStream(stream2->stream3);
     }
 }
 
diff --git a/src/sdl2_compat.h b/src/sdl2_compat.h
index 3333123..f81c92a 100644
--- a/src/sdl2_compat.h
+++ b/src/sdl2_compat.h
@@ -1208,7 +1208,6 @@ typedef struct SDL2_AudioStream
     void *callback2_buffer;
     SDL2_AudioCallback callback2;
     void *callback2_userdata;
-    SDL_AudioStream *dataqueue3;
     SDL2_bool iscapture;
 } SDL2_AudioStream;