SDL: Renamed SDL_MixAudioFormat to SDL_MixAudio, and use float volume

From b6b9d5508ed5efb1be4280127b45300e9cb366e9 Mon Sep 17 00:00:00 2001
From: Brick <[EMAIL REDACTED]>
Date: Wed, 8 May 2024 14:21:24 +0100
Subject: [PATCH] Renamed SDL_MixAudioFormat to SDL_MixAudio, and use float
 volume

---
 build-scripts/SDL_migration.cocci |  9 +++++++++
 docs/README-migration.md          |  6 +++++-
 include/SDL3/SDL_audio.h          | 20 ++++++--------------
 include/SDL3/SDL_oldnames.h       |  2 ++
 src/audio/SDL_audio.c             |  2 +-
 src/audio/SDL_mixer.c             | 20 +++++++++++---------
 src/dynapi/SDL_dynapi.sym         |  2 +-
 src/dynapi/SDL_dynapi_overrides.h |  2 +-
 src/dynapi/SDL_dynapi_procs.h     |  2 +-
 9 files changed, 37 insertions(+), 28 deletions(-)

diff --git a/build-scripts/SDL_migration.cocci b/build-scripts/SDL_migration.cocci
index a939f73241ef8..ca0bf901d4005 100644
--- a/build-scripts/SDL_migration.cocci
+++ b/build-scripts/SDL_migration.cocci
@@ -3184,3 +3184,12 @@ typedef SDL_Colour, SDL_Color;
 - SDL_SIMDGetAlignment
 + SDL_GetSIMDAlignment
   (...)
+@@
+@@
+- SDL_MixAudioFormat
++ SDL_MixAudio
+  (...)
+@@
+@@
+- SDL_MIX_MAXVOLUME
++ 1.0f
diff --git a/docs/README-migration.md b/docs/README-migration.md
index d534201affbc7..c0794c98d054e 100644
--- a/docs/README-migration.md
+++ b/docs/README-migration.md
@@ -185,7 +185,7 @@ SDL_GetAudioDeviceSpec() is removed; use SDL_GetAudioDeviceFormat() instead.
 
 SDL_GetDefaultAudioInfo() is removed; SDL_GetAudioDeviceFormat() with SDL_AUDIO_DEVICE_DEFAULT_OUTPUT or SDL_AUDIO_DEVICE_DEFAULT_CAPTURE. There is no replacement for querying the default device name; the string is no longer used to open devices, and SDL3 will migrate between physical devices on the fly if the system default changes, so if you must show this to the user, a generic name like "System default" is recommended.
 
-SDL_MixAudio() has been removed, as it relied on legacy SDL 1.2 quirks; SDL_MixAudioFormat() remains and offers the same functionality.
+SDL_MixAudioFormat() and SDL_MIX_MAXVOLUME have been removed in favour of SDL_MixAudio(), which now takes the audio format, and a float volume between 0.0 and 1.0.
 
 SDL_FreeWAV has been removed and calls can be replaced with SDL_free.
 
@@ -254,6 +254,7 @@ The following functions have been renamed:
 * SDL_AudioStreamPut() => SDL_PutAudioStreamData()
 * SDL_FreeAudioStream() => SDL_DestroyAudioStream()
 * SDL_LoadWAV_RW() => SDL_LoadWAV_IO()
+* SDL_MixAudioFormat() => SDL_MixAudio()
 * SDL_NewAudioStream() => SDL_CreateAudioStream()
 
 
@@ -294,6 +295,9 @@ The following symbols have been renamed:
 * AUDIO_S8 => SDL_AUDIO_S8
 * AUDIO_U8 => SDL_AUDIO_U8
 
+The following symbols have been removed:
+* SDL_MIX_MAXVOLUME - mixer volume is now a float between 0.0 and 1.0
+
 ## SDL_cpuinfo.h
 
 The intrinsics headers (mmintrin.h, etc.) have been moved to `<SDL3/SDL_intrin.h>` and are no longer automatically included in SDL.h.
diff --git a/include/SDL3/SDL_audio.h b/include/SDL3/SDL_audio.h
index a055a6c03e15e..ae2ffb0247d5f 100644
--- a/include/SDL3/SDL_audio.h
+++ b/include/SDL3/SDL_audio.h
@@ -1557,13 +1557,6 @@ extern DECLSPEC int SDLCALL SDL_LoadWAV_IO(SDL_IOStream * src, SDL_bool closeio,
 extern DECLSPEC int SDLCALL SDL_LoadWAV(const char *path, SDL_AudioSpec * spec,
                                         Uint8 ** audio_buf, Uint32 * audio_len);
 
-/**
- * Maximum volume allowed in calls to SDL_MixAudioFormat.
- *
- * \since This macro is available since SDL 3.0.0.
- */
-#define SDL_MIX_MAXVOLUME 128
-
 /**
  * Mix audio data in a specified format.
  *
@@ -1581,7 +1574,7 @@ extern DECLSPEC int SDLCALL SDL_LoadWAV(const char *path, SDL_AudioSpec * spec,
  *
  * It is a common misconception that this function is required to write audio
  * data to an output stream in an audio callback. While you can do that,
- * SDL_MixAudioFormat() is really only needed when you're mixing a single
+ * SDL_MixAudio() is really only needed when you're mixing a single
  * audio stream with a volume adjustment.
  *
  * \param dst the destination for the mixed audio
@@ -1589,8 +1582,7 @@ extern DECLSPEC int SDLCALL SDL_LoadWAV(const char *path, SDL_AudioSpec * spec,
  * \param format the SDL_AudioFormat structure representing the desired audio
  *               format
  * \param len the length of the audio buffer in bytes
- * \param volume ranges from 0 - 128, and should be set to SDL_MIX_MAXVOLUME
- *               for full audio volume
+ * \param volume ranges from 0.0 - 1.0, and should be set to 1.0 for full audio volume
  * \returns 0 on success or a negative error code on failure; call
  *          SDL_GetError() for more information.
  *
@@ -1598,10 +1590,10 @@ extern DECLSPEC int SDLCALL SDL_LoadWAV(const char *path, SDL_AudioSpec * spec,
  *
  * \since This function is available since SDL 3.0.0.
  */
-extern DECLSPEC int SDLCALL SDL_MixAudioFormat(Uint8 * dst,
-                                               const Uint8 * src,
-                                               SDL_AudioFormat format,
-                                               Uint32 len, int volume);
+extern DECLSPEC int SDLCALL SDL_MixAudio(Uint8 * dst,
+                                         const Uint8 * src,
+                                         SDL_AudioFormat format,
+                                         Uint32 len, float volume);
 
 /**
  * Convert some audio data of one format to another format.
diff --git a/include/SDL3/SDL_oldnames.h b/include/SDL3/SDL_oldnames.h
index 1c774dfd5ab02..e20e6a154bfec 100644
--- a/include/SDL3/SDL_oldnames.h
+++ b/include/SDL3/SDL_oldnames.h
@@ -68,6 +68,7 @@
 #define SDL_FreeAudioStream SDL_DestroyAudioStream
 #define SDL_FreeWAV SDL_free
 #define SDL_LoadWAV_RW SDL_LoadWAV_IO
+#define SDL_MixAudioFormat SDL_MixAudio
 #define SDL_NewAudioStream SDL_CreateAudioStream
 
 /* ##SDL_cpuinfo.h */
@@ -584,6 +585,7 @@
 #define SDL_FreeAudioStream SDL_FreeAudioStream_renamed_SDL_DestroyAudioStream
 #define SDL_FreeWAV SDL_FreeWAV_renamed_SDL_free
 #define SDL_LoadWAV_RW SDL_LoadWAV_RW_renamed_SDL_LoadWAV_IO
+#define SDL_MixAudioFormat SDL_MixAudioFormat_renamed_SDL_MixAudio
 #define SDL_NewAudioStream SDL_NewAudioStream_renamed_SDL_CreateAudioStream
 
 /* ##SDL_cpuinfo.h */
diff --git a/src/audio/SDL_audio.c b/src/audio/SDL_audio.c
index 47ee655f5ce25..d86cf133b59da 100644
--- a/src/audio/SDL_audio.c
+++ b/src/audio/SDL_audio.c
@@ -1046,7 +1046,7 @@ void SDL_AudioThreadFinalize(SDL_AudioDevice *device)
 
 static void MixFloat32Audio(float *dst, const float *src, const int buffer_size)
 {
-    if (SDL_MixAudioFormat((Uint8 *) dst, (const Uint8 *) src, SDL_AUDIO_F32, buffer_size, SDL_MIX_MAXVOLUME) < 0) {
+    if (SDL_MixAudio((Uint8 *) dst, (const Uint8 *) src, SDL_AUDIO_F32, buffer_size, 1.0f) < 0) {
         SDL_assert(!"This shouldn't happen.");
     }
 }
diff --git a/src/audio/SDL_mixer.c b/src/audio/SDL_mixer.c
index cfa121fb70149..12568f35f1243 100644
--- a/src/audio/SDL_mixer.c
+++ b/src/audio/SDL_mixer.c
@@ -78,15 +78,19 @@ static const Uint8 mix8[] = {
 };
 
 // The volume ranges from 0 - 128
-#define ADJUST_VOLUME(type, s, v) ((s) = (type)(((s) * (v)) / SDL_MIX_MAXVOLUME))
-#define ADJUST_VOLUME_U8(s, v)    ((s) = (Uint8)(((((s) - 128) * (v)) / SDL_MIX_MAXVOLUME) + 128))
+#define MIX_MAXVOLUME 128
+#define ADJUST_VOLUME(type, s, v) ((s) = (type)(((s) * (v)) / MIX_MAXVOLUME))
+#define ADJUST_VOLUME_U8(s, v)    ((s) = (Uint8)(((((s) - 128) * (v)) / MIX_MAXVOLUME) + 128))
 
+// !!! FIXME: This needs some SIMD magic.
+// !!! FIXME: Add fast-path for volume = 1
+// !!! FIXME: Use larger scales for 16-bit/32-bit integers
 
-// !!! FIXME: this needs some SIMD magic.
-
-int SDL_MixAudioFormat(Uint8 *dst, const Uint8 *src, SDL_AudioFormat format,
-                        Uint32 len, int volume)
+int SDL_MixAudio(Uint8 *dst, const Uint8 *src, SDL_AudioFormat format,
+                 Uint32 len, float fvolume)
 {
+    int volume = (int)SDL_roundf(fvolume * MIX_MAXVOLUME);
+
     if (volume == 0) {
         return 0;
     }
@@ -231,7 +235,6 @@ int SDL_MixAudioFormat(Uint8 *dst, const Uint8 *src, SDL_AudioFormat format,
 
     case SDL_AUDIO_F32LE:
     {
-        const float fvolume = volume / ((float)SDL_MIX_MAXVOLUME);
         const float *src32 = (float *)src;
         float *dst32 = (float *)dst;
         float src1, src2;
@@ -257,7 +260,6 @@ int SDL_MixAudioFormat(Uint8 *dst, const Uint8 *src, SDL_AudioFormat format,
 
     case SDL_AUDIO_F32BE:
     {
-        const float fvolume = volume / ((float)SDL_MIX_MAXVOLUME);
         const float *src32 = (float *)src;
         float *dst32 = (float *)dst;
         float src1, src2;
@@ -282,7 +284,7 @@ int SDL_MixAudioFormat(Uint8 *dst, const Uint8 *src, SDL_AudioFormat format,
     } break;
 
     default: // If this happens... FIXME!
-        return SDL_SetError("SDL_MixAudioFormat(): unknown audio format");
+        return SDL_SetError("SDL_MixAudio(): unknown audio format");
     }
 
     return 0;
diff --git a/src/dynapi/SDL_dynapi.sym b/src/dynapi/SDL_dynapi.sym
index 21c185be54af8..bca7ca540585a 100644
--- a/src/dynapi/SDL_dynapi.sym
+++ b/src/dynapi/SDL_dynapi.sym
@@ -564,7 +564,7 @@ SDL3_0.0.0 {
     SDL_Metal_DestroyView;
     SDL_Metal_GetLayer;
     SDL_MinimizeWindow;
-    SDL_MixAudioFormat;
+    SDL_MixAudio;
     SDL_OnApplicationDidBecomeActive;
     SDL_OnApplicationDidChangeStatusBarOrientation;
     SDL_OnApplicationDidEnterBackground;
diff --git a/src/dynapi/SDL_dynapi_overrides.h b/src/dynapi/SDL_dynapi_overrides.h
index 342c0f3801fd9..ae7e584dbe1ae 100644
--- a/src/dynapi/SDL_dynapi_overrides.h
+++ b/src/dynapi/SDL_dynapi_overrides.h
@@ -589,7 +589,7 @@
 #define SDL_Metal_DestroyView SDL_Metal_DestroyView_REAL
 #define SDL_Metal_GetLayer SDL_Metal_GetLayer_REAL
 #define SDL_MinimizeWindow SDL_MinimizeWindow_REAL
-#define SDL_MixAudioFormat SDL_MixAudioFormat_REAL
+#define SDL_MixAudio SDL_MixAudio_REAL
 #define SDL_OnApplicationDidBecomeActive SDL_OnApplicationDidBecomeActive_REAL
 #define SDL_OnApplicationDidChangeStatusBarOrientation SDL_OnApplicationDidChangeStatusBarOrientation_REAL
 #define SDL_OnApplicationDidEnterBackground SDL_OnApplicationDidEnterBackground_REAL
diff --git a/src/dynapi/SDL_dynapi_procs.h b/src/dynapi/SDL_dynapi_procs.h
index 90dc1b6d04b3e..a9cd547fb7661 100644
--- a/src/dynapi/SDL_dynapi_procs.h
+++ b/src/dynapi/SDL_dynapi_procs.h
@@ -618,7 +618,7 @@ SDL_DYNAPI_PROC(SDL_MetalView,SDL_Metal_CreateView,(SDL_Window *a),(a),return)
 SDL_DYNAPI_PROC(void,SDL_Metal_DestroyView,(SDL_MetalView a),(a),)
 SDL_DYNAPI_PROC(void*,SDL_Metal_GetLayer,(SDL_MetalView a),(a),return)
 SDL_DYNAPI_PROC(int,SDL_MinimizeWindow,(SDL_Window *a),(a),return)
-SDL_DYNAPI_PROC(int,SDL_MixAudioFormat,(Uint8 *a, const Uint8 *b, SDL_AudioFormat c, Uint32 d, int e),(a,b,c,d,e),return)
+SDL_DYNAPI_PROC(int,SDL_MixAudio,(Uint8 *a, const Uint8 *b, SDL_AudioFormat c, Uint32 d, float e),(a,b,c,d,e),return)
 SDL_DYNAPI_PROC(void,SDL_OnApplicationDidBecomeActive,(void),(),)
 SDL_DYNAPI_PROC(void,SDL_OnApplicationDidChangeStatusBarOrientation,(void),(),)
 SDL_DYNAPI_PROC(void,SDL_OnApplicationDidEnterBackground,(void),(),)