SDL: audio: Allow audio streams to be created when the subsystem isn't initialized.

From 2bca4671a67a3445566d50c47febf1e7bb80df8e Mon Sep 17 00:00:00 2001
From: "Ryan C. Gordon" <[EMAIL REDACTED]>
Date: Wed, 11 Oct 2023 22:42:52 -0400
Subject: [PATCH] audio: Allow audio streams to be created when the subsystem
 isn't initialized.

You are on your own to destroy them, though!
---
 src/audio/SDL_audio.c | 51 ++++++++++++++++++++++++-------------------
 1 file changed, 29 insertions(+), 22 deletions(-)

diff --git a/src/audio/SDL_audio.c b/src/audio/SDL_audio.c
index 112cb20e2187..0608de5de317 100644
--- a/src/audio/SDL_audio.c
+++ b/src/audio/SDL_audio.c
@@ -139,40 +139,47 @@ static int GetDefaultSampleFramesFromFreq(const int freq)
 
 void OnAudioStreamCreated(SDL_AudioStream *stream)
 {
-    SDL_assert(SDL_GetCurrentAudioDriver() != NULL);
     SDL_assert(stream != NULL);
 
-    // this isn't really part of the "device list" but it's a convenient lock to use here.
-    SDL_LockRWLockForWriting(current_audio.device_list_lock);
-    if (current_audio.existing_streams) {
-        current_audio.existing_streams->prev = stream;
+    // NOTE that you can create an audio stream without initializing the audio subsystem,
+    //  but it will not be automatically destroyed during a later call to SDL_Quit!
+    //  You must explicitly destroy it yourself!
+    if (current_audio.device_list_lock) {
+        // this isn't really part of the "device list" but it's a convenient lock to use here.
+        SDL_LockRWLockForWriting(current_audio.device_list_lock);
+        if (current_audio.existing_streams) {
+            current_audio.existing_streams->prev = stream;
+        }
+        stream->prev = NULL;
+        stream->next = current_audio.existing_streams;
+        current_audio.existing_streams = stream;
+        SDL_UnlockRWLock(current_audio.device_list_lock);
     }
-    stream->prev = NULL;
-    stream->next = current_audio.existing_streams;
-    current_audio.existing_streams = stream;
-    SDL_UnlockRWLock(current_audio.device_list_lock);
 }
 
 void OnAudioStreamDestroy(SDL_AudioStream *stream)
 {
-    SDL_assert(SDL_GetCurrentAudioDriver() != NULL);
     SDL_assert(stream != NULL);
 
-    // this isn't really part of the "device list" but it's a convenient lock to use here.
-    SDL_LockRWLockForWriting(current_audio.device_list_lock);
-    if (stream->prev) {
-        stream->prev->next = stream->next;
-    }
-    if (stream->next) {
-        stream->next->prev = stream->prev;
-    }
-    if (stream == current_audio.existing_streams) {
-        current_audio.existing_streams = stream->next;
+    // NOTE that you can create an audio stream without initializing the audio subsystem,
+    //  but it will not be automatically destroyed during a later call to SDL_Quit!
+    //  You must explicitly destroy it yourself!
+    if (current_audio.device_list_lock) {
+        // this isn't really part of the "device list" but it's a convenient lock to use here.
+        SDL_LockRWLockForWriting(current_audio.device_list_lock);
+        if (stream->prev) {
+            stream->prev->next = stream->next;
+        }
+        if (stream->next) {
+            stream->next->prev = stream->prev;
+        }
+        if (stream == current_audio.existing_streams) {
+            current_audio.existing_streams = stream->next;
+        }
+        SDL_UnlockRWLock(current_audio.device_list_lock);
     }
-    SDL_UnlockRWLock(current_audio.device_list_lock);
 }
 
-
 // device should be locked when calling this.
 static SDL_bool AudioDeviceCanUseSimpleCopy(SDL_AudioDevice *device)
 {