SDL: audio: Added SDL_GetAudioStreamBinding.

From 464640440f75c3ff65c597c50cf37e397f5a4c0f Mon Sep 17 00:00:00 2001
From: "Ryan C. Gordon" <[EMAIL REDACTED]>
Date: Thu, 22 Jun 2023 01:00:12 -0400
Subject: [PATCH] audio: Added SDL_GetAudioStreamBinding.

Now you can open a device, bind a stream, and forget about the device ID
until you're ready to shutdown, where you can query the stream for it.
---
 include/SDL3/SDL_audio.h          | 25 +++++++++++++++++++++++++
 src/audio/SDL_audio.c             | 12 ++++++++++++
 src/dynapi/SDL_dynapi.sym         |  1 +
 src/dynapi/SDL_dynapi_overrides.h |  1 +
 src/dynapi/SDL_dynapi_procs.h     |  1 +
 5 files changed, 40 insertions(+)

diff --git a/include/SDL3/SDL_audio.h b/include/SDL3/SDL_audio.h
index 6962b8f3de41..58888cd8becc 100644
--- a/include/SDL3/SDL_audio.h
+++ b/include/SDL3/SDL_audio.h
@@ -542,6 +542,7 @@ extern DECLSPEC void SDLCALL SDL_CloseAudioDevice(SDL_AudioDeviceID devid);
  * \sa SDL_BindAudioStreams
  * \sa SDL_UnbindAudioStreams
  * \sa SDL_UnbindAudioStream
+ * \sa SDL_GetAudioStreamBinding
  */
 extern DECLSPEC int SDLCALL SDL_BindAudioStreams(SDL_AudioDeviceID devid, SDL_AudioStream **streams, int num_streams);
 
@@ -562,6 +563,7 @@ extern DECLSPEC int SDLCALL SDL_BindAudioStreams(SDL_AudioDeviceID devid, SDL_Au
  * \sa SDL_BindAudioStreams
  * \sa SDL_UnbindAudioStreams
  * \sa SDL_UnbindAudioStream
+ * \sa SDL_GetAudioStreamBinding
  */
 extern DECLSPEC int SDLCALL SDL_BindAudioStream(SDL_AudioDeviceID devid, SDL_AudioStream *stream);
 
@@ -584,6 +586,7 @@ extern DECLSPEC int SDLCALL SDL_BindAudioStream(SDL_AudioDeviceID devid, SDL_Aud
  * \sa SDL_BindAudioStreams
  * \sa SDL_BindAudioStream
  * \sa SDL_UnbindAudioStream
+ * \sa SDL_GetAudioStreamBinding
  */
 extern DECLSPEC void SDLCALL SDL_UnbindAudioStreams(SDL_AudioStream **streams, int num_streams);
 
@@ -602,9 +605,31 @@ extern DECLSPEC void SDLCALL SDL_UnbindAudioStreams(SDL_AudioStream **streams, i
  * \sa SDL_BindAudioStream
  * \sa SDL_BindAudioStreams
  * \sa SDL_UnbindAudioStreams
+ * \sa SDL_GetAudioStreamBinding
  */
 extern DECLSPEC void SDLCALL SDL_UnbindAudioStream(SDL_AudioStream *stream);
 
+/**
+ * Query an audio stream for its currently-bound device.
+ *
+ * This reports the audio device that an audio stream is currently bound to.
+ *
+ * If not bound, or invalid, this returns zero, which is not a valid device ID.
+ *
+ * \param stream the audio stream to query.
+ * \returns The bound audio device, or 0 if not bound or invalid.
+ *
+ * \threadsafety It is safe to call this function from any thread.
+ *
+ * \since This function is available since SDL 3.0.0.
+ *
+ * \sa SDL_BindAudioStream
+ * \sa SDL_BindAudioStreams
+ * \sa SDL_UnbindAudioStream
+ * \sa SDL_UnbindAudioStreams
+ */
+extern DECLSPEC SDL_AudioDeviceID SDLCALL SDL_GetAudioStreamBinding(SDL_AudioStream *stream);
+
 
 /**
  * Create a new audio stream.
diff --git a/src/audio/SDL_audio.c b/src/audio/SDL_audio.c
index 74a36d5f7b51..25e8ffac8320 100644
--- a/src/audio/SDL_audio.c
+++ b/src/audio/SDL_audio.c
@@ -1357,6 +1357,18 @@ void SDL_UnbindAudioStream(SDL_AudioStream *stream)
     SDL_UnbindAudioStreams(&stream, 1);
 }
 
+SDL_AudioDeviceID SDL_GetAudioStreamBinding(SDL_AudioStream *stream)
+{
+    SDL_AudioDeviceID retval = 0;
+    if (stream) {
+        SDL_LockMutex(stream->lock);
+        if (stream->bound_device) {
+            retval = stream->bound_device->instance_id;
+        }
+        SDL_UnlockMutex(stream->lock);
+    }
+    return retval;
+}
 
 SDL_AudioStream *SDL_CreateAndBindAudioStream(SDL_AudioDeviceID devid, const SDL_AudioSpec *spec)
 {
diff --git a/src/dynapi/SDL_dynapi.sym b/src/dynapi/SDL_dynapi.sym
index 7346c2e57ddf..90da7b5fa2b4 100644
--- a/src/dynapi/SDL_dynapi.sym
+++ b/src/dynapi/SDL_dynapi.sym
@@ -888,6 +888,7 @@ SDL3_0.0.0 {
     SDL_PauseAudioDevice;
     SDL_UnpauseAudioDevice;
     SDL_IsAudioDevicePaused;
+    SDL_GetAudioStreamBinding;
     # extra symbols go here (don't modify this line)
   local: *;
 };
diff --git a/src/dynapi/SDL_dynapi_overrides.h b/src/dynapi/SDL_dynapi_overrides.h
index 28066c561b82..452819fcaed1 100644
--- a/src/dynapi/SDL_dynapi_overrides.h
+++ b/src/dynapi/SDL_dynapi_overrides.h
@@ -914,3 +914,4 @@
 #define SDL_PauseAudioDevice SDL_PauseAudioDevice_REAL
 #define SDL_UnpauseAudioDevice SDL_UnpauseAudioDevice_REAL
 #define SDL_IsAudioDevicePaused SDL_IsAudioDevicePaused_REAL
+#define SDL_GetAudioStreamBinding SDL_GetAudioStreamBinding_REAL
diff --git a/src/dynapi/SDL_dynapi_procs.h b/src/dynapi/SDL_dynapi_procs.h
index 211dedbf5b5c..78eaa0409bee 100644
--- a/src/dynapi/SDL_dynapi_procs.h
+++ b/src/dynapi/SDL_dynapi_procs.h
@@ -958,3 +958,4 @@ SDL_DYNAPI_PROC(int,SDL_LoadWAV,(const char *a, SDL_AudioSpec *b, Uint8 **c, Uin
 SDL_DYNAPI_PROC(int,SDL_PauseAudioDevice,(SDL_AudioDeviceID a),(a),return)
 SDL_DYNAPI_PROC(int,SDL_UnpauseAudioDevice,(SDL_AudioDeviceID a),(a),return)
 SDL_DYNAPI_PROC(SDL_bool,SDL_IsAudioDevicePaused,(SDL_AudioDeviceID a),(a),return)
+SDL_DYNAPI_PROC(SDL_AudioDeviceID,SDL_GetAudioStreamBinding,(SDL_AudioStream *a),(a),return)