SDL: Don't export SDL_AudioInit/Quit, use SDL_InitSubsystem instead (#6912)

From 47170d288ef56c0dbb19591c59e22e7052f3e434 Mon Sep 17 00:00:00 2001
From: Sylvain Becker <[EMAIL REDACTED]>
Date: Tue, 27 Dec 2022 14:22:22 +0100
Subject: [PATCH] Don't export SDL_AudioInit/Quit, use SDL_InitSubsystem
 instead (#6912)

* Don't export SDL_AudioInit/Quit, use SDL_InitSubsystem instead

* Update README

Co-authored-by: Sam Lantinga <slouken@libsdl.org>
---
 WhatsNew.txt                      |  2 ++
 docs/README-migration.md          |  3 +++
 include/SDL3/SDL_audio.h          | 43 +------------------------------
 src/SDL.c                         |  1 +
 src/audio/SDL_audio_c.h           | 22 ++++++++++++++++
 src/dynapi/SDL_dynapi.sym         |  2 --
 src/dynapi/SDL_dynapi_overrides.h |  2 --
 src/dynapi/SDL_dynapi_procs.h     |  2 --
 src/test/SDL_test_common.c        |  5 ++--
 test/testautomation_audio.c       | 34 +++++++++++++-----------
 10 files changed, 51 insertions(+), 65 deletions(-)

diff --git a/WhatsNew.txt b/WhatsNew.txt
index bd4511c820ed..2fce93b9c290 100644
--- a/WhatsNew.txt
+++ b/WhatsNew.txt
@@ -18,6 +18,8 @@ General:
 * The following functions have been renamed:
     * SDL_FreeWAV => SDL_free
 * Removed the following functions from the API, see docs/README-migration.md for details:
+    * SDL_AudioInit
+    * SDL_AudioQuit
     * SDL_CalculateGammaRamp()
     * SDL_CreateRGBSurface()
     * SDL_CreateRGBSurfaceFrom()
diff --git a/docs/README-migration.md b/docs/README-migration.md
index e782a673433e..7d5cde19000e 100644
--- a/docs/README-migration.md
+++ b/docs/README-migration.md
@@ -42,6 +42,9 @@ The vi format comments have been removed from source code. Vim users can use the
 
 ## SDL_audio.h
 
+- SDL_AudioInit() and SDL_AudioQuit() have been removed. Instead you can call SDL_InitSubSytem() and SDL_QuitSubSytem() with SDL_INIT_AUDIO, which will properly refcount the subsystems.
+  Also the hint SDL_AUDIO_DRIVER can help to choose a specific driver.
+
 The following functions have been renamed:
 * SDL_FreeWAV => SDL_free
 
diff --git a/include/SDL3/SDL_audio.h b/include/SDL3/SDL_audio.h
index 6c436f4e1fa1..5ec2f2c8907f 100644
--- a/include/SDL3/SDL_audio.h
+++ b/include/SDL3/SDL_audio.h
@@ -298,47 +298,6 @@ extern DECLSPEC int SDLCALL SDL_GetNumAudioDrivers(void);
 extern DECLSPEC const char *SDLCALL SDL_GetAudioDriver(int index);
 /* @} */
 
-/**
- *  \name Initialization and cleanup
- *
- *  \internal These functions are used internally, and should not be used unless
- *            you have a specific need to specify the audio driver you want to
- *            use.  You should normally use SDL_Init() or SDL_InitSubSystem().
- */
-/* @{ */
-
-/**
- * Use this function to initialize a particular audio driver.
- *
- * This function is used internally, and should not be used unless you have a
- * specific need to designate the audio driver you want to use. You should
- * normally use SDL_Init() or SDL_InitSubSystem().
- *
- * \param driver_name the name of the desired audio driver
- * \returns 0 on success or a negative error code on failure; call
- *          SDL_GetError() for more information.
- *
- * \since This function is available since SDL 3.0.0.
- *
- * \sa SDL_AudioQuit
- */
-extern DECLSPEC int SDLCALL SDL_AudioInit(const char *driver_name);
-
-/**
- * Use this function to shut down audio if you initialized it with
- * SDL_AudioInit().
- *
- * This function is used internally, and should not be used unless you have a
- * specific need to specify the audio driver you want to use. You should
- * normally use SDL_Quit() or SDL_QuitSubSystem().
- *
- * \since This function is available since SDL 3.0.0.
- *
- * \sa SDL_AudioInit
- */
-extern DECLSPEC void SDLCALL SDL_AudioQuit(void);
-/* @} */
-
 /**
  * Get the name of the current audio driver.
  *
@@ -353,7 +312,7 @@ extern DECLSPEC void SDLCALL SDL_AudioQuit(void);
  *
  * \since This function is available since SDL 3.0.0.
  *
- * \sa SDL_AudioInit
+ * \sa SDL_INIT_AUDIO
  */
 extern DECLSPEC const char *SDLCALL SDL_GetCurrentAudioDriver(void);
 
diff --git a/src/SDL.c b/src/SDL.c
index 9bc358d6e3a2..bf427dc5d01c 100644
--- a/src/SDL.c
+++ b/src/SDL.c
@@ -37,6 +37,7 @@
 
 #include "SDL_assert_c.h"
 #include "SDL_log_c.h"
+#include "audio/SDL_audio_c.h"
 #include "events/SDL_events_c.h"
 #include "haptic/SDL_haptic_c.h"
 #include "joystick/SDL_joystick_c.h"
diff --git a/src/audio/SDL_audio_c.h b/src/audio/SDL_audio_c.h
index 371b3756466a..2af78384ef13 100644
--- a/src/audio/SDL_audio_c.h
+++ b/src/audio/SDL_audio_c.h
@@ -71,4 +71,26 @@ extern SDL_AudioFilter SDL_Convert_F32_to_S16;
 extern SDL_AudioFilter SDL_Convert_F32_to_U16;
 extern SDL_AudioFilter SDL_Convert_F32_to_S32;
 
+/**
+ * Use this function to initialize a particular audio driver.
+ *
+ * This function is used internally, and should not be used unless you have a
+ * specific need to designate the audio driver you want to use. You should
+ * normally use SDL_Init() or SDL_InitSubSystem().
+ *
+ * \param driver_name the name of the desired audio driver
+ * \returns 0 on success or a negative error code on failure; call
+ *          SDL_GetError() for more information.
+ */
+extern int SDL_AudioInit(const char *driver_name);
+
+/**
+ * Use this function to shut down audio if you initialized it with SDL_AudioInit().
+ *
+ * This function is used internally, and should not be used unless you have a
+ * specific need to specify the audio driver you want to use. You should
+ * normally use SDL_Quit() or SDL_QuitSubSystem().
+ */
+extern void SDL_AudioQuit(void);
+
 #endif /* SDL_audio_c_h_ */
diff --git a/src/dynapi/SDL_dynapi.sym b/src/dynapi/SDL_dynapi.sym
index 6b5d565c2295..9bde88e93e25 100644
--- a/src/dynapi/SDL_dynapi.sym
+++ b/src/dynapi/SDL_dynapi.sym
@@ -34,8 +34,6 @@ SDL3_0.0.0 {
     SDL_WriteBE64;
     SDL_GetNumAudioDrivers;
     SDL_GetAudioDriver;
-    SDL_AudioInit;
-    SDL_AudioQuit;
     SDL_GetCurrentAudioDriver;
     SDL_OpenAudio;
     SDL_GetNumAudioDevices;
diff --git a/src/dynapi/SDL_dynapi_overrides.h b/src/dynapi/SDL_dynapi_overrides.h
index 35a0a662cd3a..32db5b0afb84 100644
--- a/src/dynapi/SDL_dynapi_overrides.h
+++ b/src/dynapi/SDL_dynapi_overrides.h
@@ -70,8 +70,6 @@
 #define SDL_AtomicGetPtr SDL_AtomicGetPtr_REAL
 #define SDL_GetNumAudioDrivers SDL_GetNumAudioDrivers_REAL
 #define SDL_GetAudioDriver SDL_GetAudioDriver_REAL
-#define SDL_AudioInit SDL_AudioInit_REAL
-#define SDL_AudioQuit SDL_AudioQuit_REAL
 #define SDL_GetCurrentAudioDriver SDL_GetCurrentAudioDriver_REAL
 #define SDL_OpenAudio SDL_OpenAudio_REAL
 #define SDL_GetNumAudioDevices SDL_GetNumAudioDevices_REAL
diff --git a/src/dynapi/SDL_dynapi_procs.h b/src/dynapi/SDL_dynapi_procs.h
index ce81e7f833d8..7ea26c30471d 100644
--- a/src/dynapi/SDL_dynapi_procs.h
+++ b/src/dynapi/SDL_dynapi_procs.h
@@ -97,8 +97,6 @@ SDL_DYNAPI_PROC(void*,SDL_AtomicSetPtr,(void **a, void *b),(a,b),return)
 SDL_DYNAPI_PROC(void*,SDL_AtomicGetPtr,(void **a),(a),return)
 SDL_DYNAPI_PROC(int,SDL_GetNumAudioDrivers,(void),(),return)
 SDL_DYNAPI_PROC(const char*,SDL_GetAudioDriver,(int a),(a),return)
-SDL_DYNAPI_PROC(int,SDL_AudioInit,(const char *a),(a),return)
-SDL_DYNAPI_PROC(void,SDL_AudioQuit,(void),(),)
 SDL_DYNAPI_PROC(const char*,SDL_GetCurrentAudioDriver,(void),(),return)
 SDL_DYNAPI_PROC(int,SDL_OpenAudio,(SDL_AudioSpec *a, SDL_AudioSpec *b),(a,b),return)
 SDL_DYNAPI_PROC(int,SDL_GetNumAudioDevices,(int a),(a),return)
diff --git a/src/test/SDL_test_common.c b/src/test/SDL_test_common.c
index 8b1b3ce60d2e..2e6490c1bc78 100644
--- a/src/test/SDL_test_common.c
+++ b/src/test/SDL_test_common.c
@@ -1346,7 +1346,8 @@ SDLTest_CommonInit(SDLTest_CommonState *state)
                 SDL_Log("%s\n", text);
             }
         }
-        if (SDL_AudioInit(state->audiodriver) < 0) {
+        SDL_SetHint("SDL_AUDIO_DRIVER", state->audiodriver);
+        if (SDL_InitSubSystem(SDL_INIT_AUDIO) < 0) {
             SDL_Log("Couldn't initialize audio driver: %s\n",
                     SDL_GetError());
             return SDL_FALSE;
@@ -2163,7 +2164,7 @@ void SDLTest_CommonQuit(SDLTest_CommonState *state)
         SDL_VideoQuit();
     }
     if (state->flags & SDL_INIT_AUDIO) {
-        SDL_AudioQuit();
+        SDL_QuitSubSystem(SDL_INIT_AUDIO);
     }
     SDL_free(state);
     SDL_Quit();
diff --git a/test/testautomation_audio.c b/test/testautomation_audio.c
index 57647dcc6293..c84ababcaba0 100644
--- a/test/testautomation_audio.c
+++ b/test/testautomation_audio.c
@@ -97,26 +97,28 @@ int audio_initQuitAudio()
         SDLTest_AssertCheck(audioDriver[0] != '\0', "Audio driver name is not empty; got: %s", audioDriver); /* NOLINT(clang-analyzer-core.NullDereference): Checked for NULL above */
 
         /* Call Init */
-        result = SDL_AudioInit(audioDriver);
-        SDLTest_AssertPass("Call to SDL_AudioInit('%s')", audioDriver);
+        SDL_SetHint("SDL_AUDIO_DRIVER", audioDriver);
+        result = SDL_InitSubSystem(SDL_INIT_AUDIO);
+        SDLTest_AssertPass("Call to SDL_InitSubSystem(SDL_INIT_AUDIO) with driver='%s'", audioDriver);
         SDLTest_AssertCheck(result == 0, "Validate result value; expected: 0 got: %d", result);
 
         /* Call Quit */
-        SDL_AudioQuit();
-        SDLTest_AssertPass("Call to SDL_AudioQuit()");
+        SDL_QuitSubSystem(SDL_INIT_AUDIO);
+        SDLTest_AssertPass("Call to SDL_QuitSubSystem(SDL_INIT_AUDIO)");
     }
 
     /* NULL driver specification */
     audioDriver = NULL;
 
     /* Call Init */
-    result = SDL_AudioInit(audioDriver);
+    SDL_SetHint("SDL_AUDIO_DRIVER", audioDriver);
+    result = SDL_InitSubSystem(SDL_INIT_AUDIO);
     SDLTest_AssertPass("Call to SDL_AudioInit(NULL)");
     SDLTest_AssertCheck(result == 0, "Validate result value; expected: 0 got: %d", result);
 
     /* Call Quit */
-    SDL_AudioQuit();
-    SDLTest_AssertPass("Call to SDL_AudioQuit()");
+    SDL_QuitSubSystem(SDL_INIT_AUDIO);
+    SDLTest_AssertPass("Call to SDL_QuitSubSystem(SDL_INIT_AUDIO)");
 
     /* Restart audio again */
     _audioSetUp(NULL);
@@ -157,8 +159,9 @@ int audio_initOpenCloseQuitAudio()
         for (j = 0; j < 2; j++) {
 
             /* Call Init */
-            result = SDL_AudioInit(audioDriver);
-            SDLTest_AssertPass("Call to SDL_AudioInit('%s')", audioDriver);
+            SDL_SetHint("SDL_AUDIO_DRIVER", audioDriver);
+            result = SDL_InitSubSystem(SDL_INIT_AUDIO);
+            SDLTest_AssertPass("Call to SDL_InitSubSystem(SDL_INIT_AUDIO) with driver='%s'", audioDriver);
             SDLTest_AssertCheck(result == 0, "Validate result value; expected: 0 got: %d", result);
 
             /* Set spec */
@@ -200,8 +203,8 @@ int audio_initOpenCloseQuitAudio()
 
             /* Call Quit (maybe multiple times) */
             for (k = 0; k <= j; k++) {
-                SDL_AudioQuit();
-                SDLTest_AssertPass("Call to SDL_AudioQuit(), call %d", k + 1);
+                SDL_QuitSubSystem(SDL_INIT_AUDIO);
+                SDLTest_AssertPass("Call to SDL_QuitSubSystem(SDL_INIT_AUDIO), call %d", k + 1);
             }
 
         } /* spec loop */
@@ -246,8 +249,9 @@ int audio_pauseUnpauseAudio()
         for (j = 0; j < 2; j++) {
 
             /* Call Init */
-            result = SDL_AudioInit(audioDriver);
-            SDLTest_AssertPass("Call to SDL_AudioInit('%s')", audioDriver);
+            SDL_SetHint("SDL_AUDIO_DRIVER", audioDriver);
+            result = SDL_InitSubSystem(SDL_INIT_AUDIO);
+            SDLTest_AssertPass("Call to SDL_InitSubSystem(SDL_INIT_AUDIO) with driver='%s'", audioDriver);
             SDLTest_AssertCheck(result == 0, "Validate result value; expected: 0 got: %d", result);
 
             /* Set spec */
@@ -320,8 +324,8 @@ int audio_pauseUnpauseAudio()
             SDLTest_AssertPass("Call to SDL_CloseAudio()");
 
             /* Call Quit */
-            SDL_AudioQuit();
-            SDLTest_AssertPass("Call to SDL_AudioQuit()");
+            SDL_QuitSubSystem(SDL_INIT_AUDIO);
+            SDLTest_AssertPass("Call to SDL_QuitSubSystem(SDL_INIT_AUDIO)");
 
         } /* spec loop */
     }     /* driver loop */