SDL_mixer: api: Replaced previous SDL_mixer API with the new SDL3_mixer!

From 05393fb923bf4af4e666246cbf7f43249838c9c7 Mon Sep 17 00:00:00 2001
From: "Ryan C. Gordon" <[EMAIL REDACTED]>
Date: Wed, 23 Jul 2025 19:14:32 -0400
Subject: [PATCH] api: Replaced previous SDL_mixer API with the new SDL3_mixer!

(The project formally known as "SDL_remixer".)

This is a completely new API, designed from scratch, which shares almost no
code with SDL2_mixer. We believe it's a better library, with more features
and an interface that is both more powerful and more pleasant to use.

Little things are going to be broken by this commit; for example, the VisualC
and Xcode projects were left in place, but have not yet been updated for the
new library. We will correct these problems over the next few commits.

Please refer to docs/README-migration.md for a migration guide to the new
API. There is no compatibility layer. However, if you need the SDL2_mixer API
in your SDL3-based app, you can use the `sdl2-api-on-sdl3` branch, which
holds the ported-to-SDL3 version of SDL2_mixer right before this new API
landed. While we will accept bug reports and pull requests for that branch,
the new API is what we will be focusing on, and we encourage you to move to it.

Revision history, etc, for this redesign up to this point are archived at:

https://github.com/icculus/SDL_remixer

Fixes #662.
---
 CHANGES.txt                                   |    4 -
 CMakeLists.txt                                |  296 +-
 README-versions.md                            |   59 -
 README.txt                                    |   59 +-
 cmake/FindSndFile.cmake                       |   44 -
 cmake/PrivateSdlFunctions.cmake               |    2 +-
 docs/README-migration.md                      |  396 ++
 examples/playmus.c                            |  312 --
 examples/playwave.c                           |  454 --
 include/SDL3_mixer/SDL_mixer.h                | 3711 +++++++++--------
 src/SDL_mixer.c                               | 2991 +++++++++++++
 src/SDL_mixer.sym                             |  179 +-
 src/SDL_mixer_internal.h                      |  295 ++
 src/SDL_mixer_loader.h                        |   85 +
 src/SDL_mixer_metadata_tags.c                 | 1344 ++++++
 src/SDL_mixer_spatialization.c                |  469 +++
 src/codecs/load_aiff.c                        |  283 --
 src/codecs/load_aiff.h                        |   33 -
 src/codecs/load_sndfile.c                     |  245 --
 src/codecs/load_sndfile.h                     |   41 -
 src/codecs/load_voc.c                         |  486 ---
 src/codecs/load_voc.h                         |   36 -
 src/codecs/mp3utils.c                         | 1174 ------
 src/codecs/mp3utils.h                         |   56 -
 src/codecs/music_drflac.c                     |  441 --
 src/codecs/music_drflac.h                     |   28 -
 src/codecs/music_drmp3.c                      |  314 --
 src/codecs/music_drmp3.h                      |   28 -
 src/codecs/music_flac.c                       |  819 ----
 src/codecs/music_flac.h                       |   26 -
 src/codecs/music_fluidsynth.c                 |  403 --
 src/codecs/music_fluidsynth.h                 |   31 -
 src/codecs/music_gme.c                        |  446 --
 src/codecs/music_gme.h                        |   26 -
 src/codecs/music_mpg123.c                     |  627 ---
 src/codecs/music_mpg123.h                     |   28 -
 src/codecs/music_nativemidi.c                 |  123 -
 src/codecs/music_nativemidi.h                 |   28 -
 src/codecs/music_ogg.c                        |  571 ---
 src/codecs/music_ogg.h                        |   28 -
 src/codecs/music_ogg_stb.c                    |  495 ---
 src/codecs/music_opus.c                       |  535 ---
 src/codecs/music_opus.h                       |   28 -
 src/codecs/music_timidity.c                   |  293 --
 src/codecs/music_timidity.h                   |   28 -
 src/codecs/music_wav.c                        | 2022 ---------
 src/codecs/music_wav.h                        |   28 -
 src/codecs/music_wavpack.c                    |  771 ----
 src/codecs/music_wavpack.h                    |   28 -
 src/codecs/music_xmp.c                        |  468 ---
 src/codecs/music_xmp.h                        |   28 -
 src/codecs/native_midi/native_midi.h          |   40 -
 src/codecs/native_midi/native_midi_common.c   |  414 --
 src/codecs/native_midi/native_midi_common.h   |   63 -
 src/codecs/native_midi/native_midi_haiku.cpp  |  295 --
 .../native_midi/native_midi_linux_alsa.c      |  901 ----
 src/codecs/native_midi/native_midi_macosx.c   |  409 --
 src/codecs/native_midi/native_midi_win32.c    |  340 --
 src/decoder_aiff.c                            |  590 +++
 src/decoder_au.c                              |  278 ++
 src/decoder_drflac.c                          |  340 ++
 src/decoder_drmp3.c                           |  203 +
 src/decoder_flac.c                            |  506 +++
 src/decoder_fluidsynth.c                      |  378 ++
 src/decoder_gme.c                             |  218 +
 src/decoder_mpg123.c                          |  458 ++
 src/decoder_opus.c                            |  358 ++
 src/decoder_raw.c                             |  144 +
 src/decoder_sinewave.c                        |  146 +
 src/decoder_stb_vorbis.c                      |  357 ++
 src/decoder_timidity.c                        |  172 +
 src/decoder_voc.c                             |  594 +++
 src/decoder_vorbis.c                          |  394 ++
 src/decoder_wav.c                             | 1590 +++++++
 src/decoder_wavpack.c                         |  633 +++
 src/decoder_xmp.c                             |  291 ++
 src/{codecs => }/dr_libs/LICENSE              |    0
 src/{codecs => }/dr_libs/README.md            |    0
 src/{codecs => }/dr_libs/dr_flac.h            |    0
 src/{codecs => }/dr_libs/dr_mp3.h             |    0
 src/effect_position.c                         | 1796 --------
 src/effect_stereoreverse.c                    |  134 -
 src/effects_internal.c                        |  114 -
 src/effects_internal.h                        |   44 -
 src/mixer.c                                   | 1782 --------
 src/mixer.h                                   |   30 -
 src/music.c                                   | 1518 -------
 src/music.h                                   |  177 -
 src/{codecs => }/stb_vorbis/README.txt        |    0
 src/{codecs => }/stb_vorbis/stb_vorbis.h      |    9 +-
 src/{codecs => }/timidity/Android.mk          |    0
 src/{codecs => }/timidity/CHANGES             |    0
 src/{codecs => }/timidity/COPYING             |    0
 src/{codecs => }/timidity/FAQ                 |    0
 src/{codecs => }/timidity/README              |    0
 src/{codecs => }/timidity/TODO                |    0
 src/{codecs => }/timidity/common.c            |    0
 src/{codecs => }/timidity/common.h            |    2 +
 src/{codecs => }/timidity/instrum.c           |    0
 src/{codecs => }/timidity/instrum.h           |    0
 src/{codecs => }/timidity/mix.c               |    0
 src/{codecs => }/timidity/mix.h               |    0
 src/{codecs => }/timidity/options.h           |    0
 src/{codecs => }/timidity/output.c            |    0
 src/{codecs => }/timidity/output.h            |    0
 src/{codecs => }/timidity/playmidi.c          |    0
 src/{codecs => }/timidity/playmidi.h          |    0
 src/{codecs => }/timidity/readmidi.c          |    0
 src/{codecs => }/timidity/readmidi.h          |    0
 src/{codecs => }/timidity/resample.c          |    0
 src/{codecs => }/timidity/resample.h          |    0
 src/{codecs => }/timidity/tables.c            |    0
 src/{codecs => }/timidity/tables.h            |    0
 src/{codecs => }/timidity/timidity.c          |    4 +-
 src/{codecs => }/timidity/timidity.h          |    2 +-
 src/utils.c                                   |   71 -
 src/utils.h                                   |   36 -
 test/testaudiodecoder.c                       |   84 +
 test/testmixer.c                              |  261 ++
 test/testspatialization.c                     |  138 +
 120 files changed, 15982 insertions(+), 22077 deletions(-)
 delete mode 100644 CHANGES.txt
 delete mode 100644 README-versions.md
 delete mode 100644 cmake/FindSndFile.cmake
 create mode 100644 docs/README-migration.md
 delete mode 100644 examples/playmus.c
 delete mode 100644 examples/playwave.c
 create mode 100644 src/SDL_mixer.c
 create mode 100644 src/SDL_mixer_internal.h
 create mode 100644 src/SDL_mixer_loader.h
 create mode 100644 src/SDL_mixer_metadata_tags.c
 create mode 100644 src/SDL_mixer_spatialization.c
 delete mode 100644 src/codecs/load_aiff.c
 delete mode 100644 src/codecs/load_aiff.h
 delete mode 100644 src/codecs/load_sndfile.c
 delete mode 100644 src/codecs/load_sndfile.h
 delete mode 100644 src/codecs/load_voc.c
 delete mode 100644 src/codecs/load_voc.h
 delete mode 100644 src/codecs/mp3utils.c
 delete mode 100644 src/codecs/mp3utils.h
 delete mode 100644 src/codecs/music_drflac.c
 delete mode 100644 src/codecs/music_drflac.h
 delete mode 100644 src/codecs/music_drmp3.c
 delete mode 100644 src/codecs/music_drmp3.h
 delete mode 100644 src/codecs/music_flac.c
 delete mode 100644 src/codecs/music_flac.h
 delete mode 100644 src/codecs/music_fluidsynth.c
 delete mode 100644 src/codecs/music_fluidsynth.h
 delete mode 100644 src/codecs/music_gme.c
 delete mode 100644 src/codecs/music_gme.h
 delete mode 100644 src/codecs/music_mpg123.c
 delete mode 100644 src/codecs/music_mpg123.h
 delete mode 100644 src/codecs/music_nativemidi.c
 delete mode 100644 src/codecs/music_nativemidi.h
 delete mode 100644 src/codecs/music_ogg.c
 delete mode 100644 src/codecs/music_ogg.h
 delete mode 100644 src/codecs/music_ogg_stb.c
 delete mode 100644 src/codecs/music_opus.c
 delete mode 100644 src/codecs/music_opus.h
 delete mode 100644 src/codecs/music_timidity.c
 delete mode 100644 src/codecs/music_timidity.h
 delete mode 100644 src/codecs/music_wav.c
 delete mode 100644 src/codecs/music_wav.h
 delete mode 100644 src/codecs/music_wavpack.c
 delete mode 100644 src/codecs/music_wavpack.h
 delete mode 100644 src/codecs/music_xmp.c
 delete mode 100644 src/codecs/music_xmp.h
 delete mode 100644 src/codecs/native_midi/native_midi.h
 delete mode 100644 src/codecs/native_midi/native_midi_common.c
 delete mode 100644 src/codecs/native_midi/native_midi_common.h
 delete mode 100644 src/codecs/native_midi/native_midi_haiku.cpp
 delete mode 100644 src/codecs/native_midi/native_midi_linux_alsa.c
 delete mode 100644 src/codecs/native_midi/native_midi_macosx.c
 delete mode 100644 src/codecs/native_midi/native_midi_win32.c
 create mode 100644 src/decoder_aiff.c
 create mode 100644 src/decoder_au.c
 create mode 100644 src/decoder_drflac.c
 create mode 100644 src/decoder_drmp3.c
 create mode 100644 src/decoder_flac.c
 create mode 100644 src/decoder_fluidsynth.c
 create mode 100644 src/decoder_gme.c
 create mode 100644 src/decoder_mpg123.c
 create mode 100644 src/decoder_opus.c
 create mode 100644 src/decoder_raw.c
 create mode 100644 src/decoder_sinewave.c
 create mode 100644 src/decoder_stb_vorbis.c
 create mode 100644 src/decoder_timidity.c
 create mode 100644 src/decoder_voc.c
 create mode 100644 src/decoder_vorbis.c
 create mode 100644 src/decoder_wav.c
 create mode 100644 src/decoder_wavpack.c
 create mode 100644 src/decoder_xmp.c
 rename src/{codecs => }/dr_libs/LICENSE (100%)
 rename src/{codecs => }/dr_libs/README.md (100%)
 rename src/{codecs => }/dr_libs/dr_flac.h (100%)
 rename src/{codecs => }/dr_libs/dr_mp3.h (100%)
 delete mode 100644 src/effect_position.c
 delete mode 100644 src/effect_stereoreverse.c
 delete mode 100644 src/effects_internal.c
 delete mode 100644 src/effects_internal.h
 delete mode 100644 src/mixer.c
 delete mode 100644 src/mixer.h
 delete mode 100644 src/music.c
 delete mode 100644 src/music.h
 rename src/{codecs => }/stb_vorbis/README.txt (100%)
 rename src/{codecs => }/stb_vorbis/stb_vorbis.h (99%)
 rename src/{codecs => }/timidity/Android.mk (100%)
 rename src/{codecs => }/timidity/CHANGES (100%)
 rename src/{codecs => }/timidity/COPYING (100%)
 rename src/{codecs => }/timidity/FAQ (100%)
 rename src/{codecs => }/timidity/README (100%)
 rename src/{codecs => }/timidity/TODO (100%)
 rename src/{codecs => }/timidity/common.c (100%)
 rename src/{codecs => }/timidity/common.h (96%)
 rename src/{codecs => }/timidity/instrum.c (100%)
 rename src/{codecs => }/timidity/instrum.h (100%)
 rename src/{codecs => }/timidity/mix.c (100%)
 rename src/{codecs => }/timidity/mix.h (100%)
 rename src/{codecs => }/timidity/options.h (100%)
 rename src/{codecs => }/timidity/output.c (100%)
 rename src/{codecs => }/timidity/output.h (100%)
 rename src/{codecs => }/timidity/playmidi.c (100%)
 rename src/{codecs => }/timidity/playmidi.h (100%)
 rename src/{codecs => }/timidity/readmidi.c (100%)
 rename src/{codecs => }/timidity/readmidi.h (100%)
 rename src/{codecs => }/timidity/resample.c (100%)
 rename src/{codecs => }/timidity/resample.h (100%)
 rename src/{codecs => }/timidity/tables.c (100%)
 rename src/{codecs => }/timidity/tables.h (100%)
 rename src/{codecs => }/timidity/timidity.c (99%)
 rename src/{codecs => }/timidity/timidity.h (98%)
 delete mode 100644 src/utils.c
 delete mode 100644 src/utils.h
 create mode 100644 test/testaudiodecoder.c
 create mode 100644 test/testmixer.c
 create mode 100644 test/testspatialization.c

diff --git a/CHANGES.txt b/CHANGES.txt
deleted file mode 100644
index 4c81ab14d..000000000
--- a/CHANGES.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-3.0.0:
- * Removed support for libmodplug as a MOD music backend.
- * Go back to using dr_mp3 as the default backend for MP3 music
- * Updated for SDL 3.0
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 5c6f6ccb7..9ad2c33c2 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -123,87 +123,50 @@ endif()
 option(SDLMIXER_SAMPLES "Build the SDL3_mixer sample program(s)" ${SDLMIXER_SAMPLES_DEFAULT})
 cmake_dependent_option(SDLMIXER_SAMPLES_INSTALL "Install the SDL3_mixer sample program(s)" OFF "SDLMIXER_SAMPLES;SDLMIXER_INSTALL" OFF)
 
-option(SDLMIXER_SNDFILE "Support loading sounds via libsndfile" OFF)
-option(SDLMIXER_SNDFILE_SHARED "Dynamically load libsndfile" "${SDLMIXER_DEPS_SHARED}")
-
-option(SDLMIXER_FLAC "Enable FLAC music" ON)
-
-cmake_dependent_option(SDLMIXER_FLAC_LIBFLAC "Enable FLAC music using libFLAC" OFF SDLMIXER_FLAC OFF)
+# These are implemented in SDL_mixer itself, not using a third-party library.
+option(SDLMIXER_AIFF "Enable AIFF audio" ON)
+option(SDLMIXER_WAVE "Enable WAVE audio" ON)
+option(SDLMIXER_VOC "Enable VOC audio" ON)
+option(SDLMIXER_AU "Enable AU audio" ON)
+
+# Decoders that use third-party dependencies, even if they are compiled in, vendored, etc.
+option(SDLMIXER_FLAC_LIBFLAC "Enable FLAC audio using libFLAC" ON)
 cmake_dependent_option(SDLMIXER_FLAC_LIBFLAC_SHARED "Dynamically load LIBFLAC" "${SDLMIXER_DEPS_SHARED}" SDLMIXER_FLAC_LIBFLAC OFF)
 
-cmake_dependent_option(SDLMIXER_FLAC_DRFLAC "Enable FLAC music using drflac" ON SDLMIXER_FLAC OFF)
+option(SDLMIXER_FLAC_DRFLAC "Enable FLAC audio using drflac" ON)
 
-option(SDLMIXER_GME "Support loading GME music via game-music-emu" ON)
+option(SDLMIXER_GME "Support loading GME audio via game-music-emu" ON)
 option(SDLMIXER_GME_SHARED "Dynamically load libgme" "${SDLMIXER_DEPS_SHARED}")
 
-option(SDLMIXER_MOD "Support loading MOD music" ON)
-
-cmake_dependent_option(SDLMIXER_MOD_XMP "Support loading MOD music via libxmp" ON SDLMIXER_MOD OFF)
+option(SDLMIXER_MOD_XMP "Support loading MOD audio via libxmp" ON)
 cmake_dependent_option(SDLMIXER_MOD_XMP_LITE "Use libxmp-lite instead of libxmp" OFF "SDLMIXER_MOD_XMP;NOT SDLMIXER_VENDORED" OFF)
 cmake_dependent_option(SDLMIXER_MOD_XMP_SHARED "Dynamically load libxmp(-lite)" "${SDLMIXER_DEPS_SHARED}" SDLMIXER_MOD_XMP OFF)
 
-if(SDLMIXER_MOD AND NOT SDLMIXER_MOD_XMP)
-    message(FATAL_ERROR "MOD support was enabled (SDLMIXER_MOD) but xmp (SDLMIXER_MOD_XMP) was disabled.")
-endif()
-
-option(SDLMIXER_MP3 "Enable MP3 music" ON)
-
-cmake_dependent_option(SDLMIXER_MP3_DRMP3 "Support loading MP3 music via dr_mp3" ON SDLMIXER_MP3 OFF)
-
-cmake_dependent_option(SDLMIXER_MP3_MPG123 "Support loading MP3 music via MPG123" OFF SDLMIXER_MP3 OFF)
+option(SDLMIXER_MP3_DRMP3 "Support loading MP3 audio via dr_mp3" ON)
+option(SDLMIXER_MP3_MPG123 "Support loading MP3 audio via libmpg123" ON)
 cmake_dependent_option(SDLMIXER_MP3_MPG123_SHARED "Dynamically load mpg123" "${SDLMIXER_DEPS_SHARED}" SDLMIXER_MP3_MPG123 OFF)
 
-if(SDLMIXER_MP3 AND NOT (SDLMIXER_MP3_DRMP3 OR SDLMIXER_MP3_MPG123))
-    message(FATAL_ERROR "MP3 support was enabled (SDLMIXER_MP3) but neither drmp3 (SDLMIXER_MP3_DRMP3) or mpg123 (SDLMIXER_MP3_MPG123) were enabled.")
-endif()
-
-option(SDLMIXER_MIDI "Enable MIDI music" ON)
-
-cmake_dependent_option(SDLMIXER_MIDI_FLUIDSYNTH "Support FluidSynth MIDI output" ON "SDLMIXER_MIDI;NOT SDLMIXER_VENDORED" OFF)
+cmake_dependent_option(SDLMIXER_MIDI_FLUIDSYNTH "Support FluidSynth MIDI output" ON "NOT SDLMIXER_VENDORED" OFF)
 cmake_dependent_option(SDLMIXER_MIDI_FLUIDSYNTH_SHARED "Dynamically load libfluidsynth" "${SDLMIXER_DEPS_SHARED}" SDLMIXER_MIDI_FLUIDSYNTH OFF)
 
-if(WIN32 OR APPLE OR HAIKU OR "${CMAKE_SYSTEM_NAME}" MATCHES "Linux")
-    cmake_dependent_option(SDLMIXER_MIDI_NATIVE "Support native MIDI output" ON SDLMIXER_MIDI OFF)
-else()
-    set(SDLMIXER_MIDI_NATIVE OFF)
-endif()
-
-cmake_dependent_option(SDLMIXER_MIDI_TIMIDITY "Support timidity MIDI output" ON SDLMIXER_MIDI OFF)
-
-if(SDLMIXER_MIDI AND NOT (SDLMIXER_MIDI_TIMIDITY OR SDLMIXER_MIDI_NATIVE OR SDLMIXER_MIDI_FLUIDSYNTH))
-    message(FATAL_ERROR "MIDI support was enabled (SDLMIXER_MIDI) but neither FluidSynth (SDLMIXER_MIDI_FLUIDSYNTH), native (SDLMIXER_MIDI_NATIVE) or timidity (SDLMIXER_MIDI_TIMIDITY) was enabled")
-endif()
+option(SDLMIXER_MIDI_TIMIDITY "Support timidity MIDI output" ON)
 
-option(SDLMIXER_OPUS "Enable Opus music" ON)
+option(SDLMIXER_OPUS "Enable Opus audio via libopus" ON)
 cmake_dependent_option(SDLMIXER_OPUS_SHARED "Dynamically load libopus" "${SDLMIXER_DEPS_SHARED}" SDLMIXER_OPUS OFF)
 
-set(sdl3mixer_vorbis_strings STB TREMOR VORBISFILE)
-set(SDLMIXER_VORBIS "STB" CACHE STRING "Enable OGG Vorbis music")
-set_property(CACHE SDLMIXER_VORBIS PROPERTY STRINGS "${sdl3mixer_vorbis_strings}")
-if(SDLMIXER_VORBIS)
-    if(NOT SDLMIXER_VORBIS IN_LIST sdl3mixer_vorbis_strings)
-        message(FATAL_ERROR "SDLMIXER_VORBIS contains an invalid value (=${SDLMIXER_VORBIS}). It must be one of ${sdl3mixer_vorbis_strings}.")
-    endif()
-endif()
-set(SDLMIXER_VORBIS_STB OFF)
-set(SDLMIXER_VORBIS_TREMOR OFF)
-set(SDLMIXER_VORBIS_VORBISFILE OFF)
-if(SDLMIXER_VORBIS STREQUAL "STB")
-    set(SDLMIXER_VORBIS_STB ON)
-endif()
-if(SDLMIXER_VORBIS STREQUAL "TREMOR")
-    set(SDLMIXER_VORBIS_TREMOR ON)
-endif()
-if(SDLMIXER_VORBIS STREQUAL "VORBISFILE")
-    set(SDLMIXER_VORBIS_VORBISFILE ON)
+option(SDLMIXER_VORBIS_STB "Enable Ogg Vorbis audio via stb_vorbis" ON)
+option(SDLMIXER_VORBIS_VORBISFILE "Enable Ogg Vorbis audio via libvorbisfile" ON)
+option(SDLMIXER_VORBIS_TREMOR "Enable Ogg Vorbis audio via libtremor" OFF)
+
+if (SDLMIXER_VORBIS_VORBISFILE AND SDLMIXER_VORBIS_TREMOR)
+    message(FATAL_ERROR "Both SDLMIXER_VORBIS_VORBISFILE and SDLMIXER_VORBIS_TREMOR are both enabled, but only one can be used")
 endif()
-cmake_dependent_option(SDLMIXER_VORBIS_TREMOR_SHARED "Dynamically load tremor library" "${SDLMIXER_DEPS_SHARED}" SDLMIXER_VORBIS_TREMOR OFF)
-cmake_dependent_option(SDLMIXER_VORBIS_VORBISFILE_SHARED "Dynamically load vorbisfile library" "${SDLMIXER_DEPS_SHARED}" SDLMIXER_VORBIS_VORBISFILE OFF)
 
-option(SDLMIXER_WAVE "Enable streaming WAVE music" ON)
+cmake_dependent_option(SDLMIXER_VORBIS_VORBISFILE_SHARED "Dynamically load vorbisfile library" "${SDLMIXER_DEPS_SHARED}" SDLMIXER_VORBIS_VORBISFILE OFF)
+cmake_dependent_option(SDLMIXER_VORBIS_TREMOR_SHARED "Dynamically load tremor library" "${SDLMIXER_DEPS_SHARED}" SDLMIXER_VORBIS_TREMOR OFF)
 
-option(SDLMIXER_WAVPACK "Enable WavPack music" ON)
-cmake_dependent_option(SDLMIXER_WAVPACK_DSD "Enable WavPack DSD music support" OFF SDLMIXER_WAVPACK OFF)
+option(SDLMIXER_WAVPACK "Enable WavPack audio" ON)
+cmake_dependent_option(SDLMIXER_WAVPACK_DSD "Enable WavPack DSD audio support" OFF SDLMIXER_WAVPACK OFF)
 cmake_dependent_option(SDLMIXER_WAVPACK_SHARED "Dynamically load WavPack library" "${SDLMIXER_DEPS_SHARED}" SDLMIXER_WAVPACK OFF)
 
 if(SDLMIXER_VORBIS_TREMOR OR SDLMIXER_VORBIS_VORBISFILE OR SDLMIXER_FLAC_LIBFLAC OR SDLMIXER_OPUS)
@@ -246,35 +209,37 @@ SDL_DetectCMakePlatform()
 
 set(BUILD_SHARED_LIBS ${SDLMIXER_BUILD_SHARED_LIBS})
 add_library(${sdl3_mixer_target_name}
-    src/codecs/load_aiff.c
-    src/codecs/load_voc.c
-    src/codecs/load_sndfile.c
-    src/codecs/mp3utils.c
-    src/codecs/music_drflac.c
-    src/codecs/music_drmp3.c
-    src/codecs/music_flac.c
-    src/codecs/music_fluidsynth.c
-    src/codecs/music_gme.c
-    src/codecs/music_mpg123.c
-    src/codecs/music_nativemidi.c
-    src/codecs/music_ogg.c
-    src/codecs/music_ogg_stb.c
-    src/codecs/music_opus.c
-    src/codecs/music_timidity.c
-    src/codecs/music_wav.c
-    src/codecs/music_wavpack.c
-    src/codecs/music_xmp.c
-    src/effect_position.c
-    src/effect_stereoreverse.c
-    src/effects_internal.c
-    src/mixer.c
-    src/music.c
-    src/utils.c
+    src/SDL_mixer.c
+    src/SDL_mixer_metadata_tags.c
+    src/SDL_mixer_spatialization.c
+    src/decoder_aiff.c
+    src/decoder_au.c
+    src/decoder_drflac.c
+    src/decoder_drmp3.c
+    src/decoder_flac.c
+    src/decoder_fluidsynth.c
+    src/decoder_gme.c
+    src/decoder_mpg123.c
+    src/decoder_opus.c
+    src/decoder_raw.c
+    src/decoder_sinewave.c
+    src/decoder_stb_vorbis.c
+    src/decoder_timidity.c
+    src/decoder_voc.c
+    src/decoder_vorbis.c
+    src/decoder_wav.c
+    src/decoder_wavpack.c
+    src/decoder_xmp.c
 )
 add_library(SDL3_mixer::${sdl3_mixer_target_name} ALIAS ${sdl3_mixer_target_name})
 if(NOT TARGET SDL3_mixer::SDL3_mixer)
     add_library(SDL3_mixer::SDL3_mixer ALIAS ${sdl3_mixer_target_name})
 endif()
+if("c_std_99" IN_LIST CMAKE_C_COMPILE_FEATURES)
+    target_compile_features(${sdl3_mixer_target_name} PRIVATE c_std_99)
+else()
+    message(WARNING "target_compile_features does not know c_std_99 for C compiler")
+endif()
 target_include_directories(${sdl3_mixer_target_name}
     PUBLIC
         "$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>"
@@ -359,44 +324,6 @@ set(PC_LIBS)
 set(PC_REQUIRES)
 set(SDLMIXER_BACKENDS)
 
-list(APPEND SDLMIXER_BACKENDS SNDFILE)
-set(SDLMIXER_SNDFILE_ENABLED FALSE)
-if(SDLMIXER_SNDFILE)
-    if(SDLMIXER_VENDORED)
-        message(STATUS "Using vendored libsndfile")
-        message(${fatal_error} "libsndfile is not vendored.")
-    else()
-        find_package(SndFile ${required})
-        if(SndFile_FOUND)
-            set(SDLMIXER_SNDFILE_ENABLED TRUE)
-            message(STATUS "Using system libsndfile")
-            if(NOT SDLMIXER_SNDFILE_SHARED)
-                list(APPEND PC_REQUIRES sndfile)
-            endif()
-        else()
-            message(${fatal_error} "libsndfile NOT found")
-        endif()
-    endif()
-    if(SDLMIXER_SNDFILE_ENABLED)
-        target_compile_definitions(${sdl3_mixer_target_name} PRIVATE LOAD_SNDFILE)
-        if(SDLMIXER_SNDFILE_SHARED)
-            target_include_directories(${sdl3_mixer_target_name} PRIVATE
-                $<TARGET_PROPERTY:SndFile::sndfile,INCLUDE_DIRECTORIES>
-                $<TARGET_PROPERTY:SndFile::sndfile,INTERFACE_INCLUDE_DIRECTORIES>
-                $<TARGET_PROPERTY:SndFile::sndfile,INTERFACE_SYSTEM_INCLUDE_DIRECTORIES>
-            )
-            target_get_dynamic_library(dynamic_sndfile SndFile::sndfile)
-            message(STATUS "Dynamic libsndfile: ${dynamic_sndfile}")
-            target_compile_definitions(${sdl3_mixer_target_name} PRIVATE "SNDFILE_DYNAMIC=\"${dynamic_sndfile}\"")
-            if(SDLMIXER_VENDORED)
-                add_dependencies(${sdl3_mixer_target_name} SndFile::sndfile)
-            endif()
-        else()
-            target_link_libraries(${sdl3_mixer_target_name} PRIVATE SndFile::sndfile)
-        endif()
-    endif()
-endif()
-
 if(SDLMIXER_OGG)
     # libogg is a requirement of libflac, libtremor and libvorbisfile, so only need this library when vendoring
     if(SDLMIXER_VENDORED)
@@ -467,7 +394,7 @@ if(SDLMIXER_OPUS)
         endif()
     endif()
     if(SDLMIXER_OPUS_ENABLED)
-        target_compile_definitions(${sdl3_mixer_target_name} PRIVATE MUSIC_OPUS)
+        target_compile_definitions(${sdl3_mixer_target_name} PRIVATE DECODER_OPUS)
         if(SDLMIXER_OPUS_SHARED)
             target_include_directories(${sdl3_mixer_target_name} PRIVATE
                 $<TARGET_PROPERTY:OpusFile::opusfile,INCLUDE_DIRECTORIES>
@@ -490,9 +417,7 @@ list(APPEND SDLMIXER_BACKENDS VORBIS_STB)
 set(SDLMIXER_VORBIS_STB_ENABLED FALSE)
 if(SDLMIXER_VORBIS_STB)
     set(SDLMIXER_VORBIS_STB_ENABLED TRUE)
-    message(STATUS "Enabled ogg music: using stb_vorbis")
-    target_compile_definitions(${sdl3_mixer_target_name} PRIVATE MUSIC_OGG)
-    target_compile_definitions(${sdl3_mixer_target_name} PRIVATE OGG_USE_STB)
+    target_compile_definitions(${sdl3_mixer_target_name} PRIVATE DECODER_OGGVORBIS_STB)
 endif()
 
 list(APPEND SDLMIXER_BACKENDS VORBIS_TREMOR)
@@ -537,7 +462,7 @@ if(SDLMIXER_VORBIS_TREMOR)
         endif()
     endif()
     if(SDLMIXER_VORBIS_TREMOR_ENABLED)
-        target_compile_definitions(${sdl3_mixer_target_name} PRIVATE MUSIC_OGG OGG_USE_TREMOR)
+        target_compile_definitions(${sdl3_mixer_target_name} PRIVATE DECODER_OGGVORBIS_VORBISFILE VORBIS_USE_TREMOR)
         if(SDLMIXER_VORBIS_TREMOR_SHARED)
             target_include_directories(${sdl3_mixer_target_name} PRIVATE
                 $<TARGET_PROPERTY:tremor::tremor,INCLUDE_DIRECTORIES>
@@ -546,7 +471,7 @@ if(SDLMIXER_VORBIS_TREMOR)
             )
             target_get_dynamic_library(dynamic_tremor tremor::tremor)
             message(STATUS "Dynamic vorbis (tremor): ${dynamic_tremor}")
-            target_compile_definitions(${sdl3_mixer_target_name} PRIVATE "OGG_DYNAMIC=\"${dynamic_tremor}\"")
+            target_compile_definitions(${sdl3_mixer_target_name} PRIVATE "VORBIS_DYNAMIC=\"${dynamic_tremor}\"")
             if(SDLMIXER_VENDORED)
                 add_dependencies(${sdl3_mixer_target_name} tremor::tremor)
             endif()
@@ -591,7 +516,7 @@ if(SDLMIXER_VORBIS_VORBISFILE)
         endif()
     endif()
     if(SDLMIXER_VORBIS_VORBISFILE_ENABLED)
-        target_compile_definitions(${sdl3_mixer_target_name} PRIVATE MUSIC_OGG)
+        target_compile_definitions(${sdl3_mixer_target_name} PRIVATE DECODER_OGGVORBIS_VORBISFILE)
         if(SDLMIXER_VORBIS_VORBISFILE_SHARED)
             target_include_directories(${sdl3_mixer_target_name} PRIVATE
                 $<TARGET_PROPERTY:Vorbis::vorbisfile,INCLUDE_DIRECTORIES>
@@ -600,7 +525,7 @@ if(SDLMIXER_VORBIS_VORBISFILE)
             )
             target_get_dynamic_library(dynamic_vorbisfile Vorbis::vorbisfile)
             message(STATUS "Dynamic vorbisfile: ${dynamic_vorbisfile}")
-            target_compile_definitions(${sdl3_mixer_target_name} PRIVATE "OGG_DYNAMIC=\"${dynamic_vorbisfile}\"")
+            target_compile_definitions(${sdl3_mixer_target_name} PRIVATE "VORBIS_DYNAMIC=\"${dynamic_vorbisfile}\"")
             if(SDLMIXER_VENDORED)
                 add_dependencies(${sdl3_mixer_target_name} Vorbis::vorbisfile)
             endif()
@@ -654,7 +579,7 @@ if(SDLMIXER_FLAC_LIBFLAC)
         endif()
     endif()
     if(SDLMIXER_FLAC_LIBFLAC_ENABLED)
-        target_compile_definitions(${sdl3_mixer_target_name} PRIVATE MUSIC_FLAC_LIBFLAC)
+        target_compile_definitions(${sdl3_mixer_target_name} PRIVATE DECODER_FLAC_LIBFLAC)
         if(SDLMIXER_FLAC_LIBFLAC_SHARED)
             target_include_directories(${sdl3_mixer_target_name} PRIVATE
                 $<TARGET_PROPERTY:FLAC::FLAC,INCLUDE_DIRECTORIES>
@@ -677,7 +602,7 @@ list(APPEND SDLMIXER_BACKENDS FLAC_DRFLAC)
 set(SDLMIXER_FLAC_DRFLAC_ENABLED FALSE)
 if(SDLMIXER_FLAC_DRFLAC)
     set(SDLMIXER_FLAC_DRFLAC_ENABLED TRUE)
-    target_compile_definitions(${sdl3_mixer_target_name} PRIVATE MUSIC_FLAC_DRFLAC)
+    target_compile_definitions(${sdl3_mixer_target_name} PRIVATE DECODER_FLAC_DRFLAC)
 endif()
 
 set(SDLMIXER_FLAC_ENABLED FALSE)
@@ -696,7 +621,7 @@ if(SDLMIXER_GME)
             set(tgt_gme gme_shared)
         else()
             set(GME_BUILD_STATIC ON)
-            set(tgt_gme gme_static gme_deps)
+            set(tgt_gme gme_static)
         endif()
         set(GME_BUILD_FRAMEWORK OFF)
         set(GME_BUILD_TESTING OFF)
@@ -726,7 +651,7 @@ if(SDLMIXER_GME)
         endif()
     endif()
     if(SDLMIXER_GME_ENABLED)
-        target_compile_definitions(${sdl3_mixer_target_name} PRIVATE MUSIC_GME)
+        target_compile_definitions(${sdl3_mixer_target_name} PRIVATE DECODER_GME)
         if(SDLMIXER_GME_SHARED)
             target_include_directories(${sdl3_mixer_target_name} PRIVATE
                 $<TARGET_PROPERTY:gme::gme,INCLUDE_DIRECTORIES>
@@ -807,7 +732,7 @@ if(SDLMIXER_MOD_XMP)
         endif()
     endif()
     if(SDLMIXER_MOD_XMP_ENABLED)
-        target_compile_definitions(${sdl3_mixer_target_name} PRIVATE MUSIC_MOD_XMP)
+        target_compile_definitions(${sdl3_mixer_target_name} PRIVATE DECODER_MOD_XMP)
         if(SDLMIXER_MOD_XMP_SHARED)
             target_include_directories(${sdl3_mixer_target_name} PRIVATE
                 $<TARGET_PROPERTY:${tgt_xmp},INCLUDE_DIRECTORIES>
@@ -835,7 +760,7 @@ list(APPEND SDLMIXER_BACKENDS MP3_DRMP3)
 set(SDLMIXER_MP3_DRMP3_ENABLED FALSE)
 if(SDLMIXER_MP3_DRMP3)
     set(SDLMIXER_MP3_DRMP3_ENABLED TRUE)
-    target_compile_definitions(${sdl3_mixer_target_name} PRIVATE MUSIC_MP3_DRMP3)
+    target_compile_definitions(${sdl3_mixer_target_name} PRIVATE DECODER_MP3_DRMP3)
 endif()
 
 list(APPEND SDLMIXER_BACKENDS MP3_MPG123)
@@ -871,7 +796,7 @@ if(SDLMIXER_MP3_MPG123)
         endif()
     endif()
     if(SDLMIXER_MP3_MPG123_ENABLED)
-        target_compile_definitions(${sdl3_mixer_target_name} PRIVATE MUSIC_MP3_MPG123)
+        target_compile_definitions(${sdl3_mixer_target_name} PRIVATE DECODER_MP3_MPG123)
         if(SDLMIXER_MP3_MPG123_SHARED)
             target_include_directories(${sdl3_mixer_target_name} PRIVATE
                 $<TARGET_PROPERTY:MPG123::libmpg123,INCLUDE_DIRECTORIES>
@@ -915,7 +840,7 @@ if(SDLMIXER_MIDI_FLUIDSYNTH)
         endif()
     endif()
     if(SDLMIXER_MIDI_FLUIDSYNTH_ENABLED)
-        target_compile_definitions(${sdl3_mixer_target_name} PRIVATE MUSIC_MID_FLUIDSYNTH)
+        target_compile_definitions(${sdl3_mixer_target_name} PRIVATE DECODER_MIDI_FLUIDSYNTH)
         if(SDLMIXER_MIDI_FLUIDSYNTH_SHARED)
             target_include_directories(${sdl3_mixer_target_name} PRIVATE
                 $<TARGET_PROPERTY:FluidSynth::libfluidsynth,INCLUDE_DIRECTORIES>
@@ -934,66 +859,50 @@ if(SDLMIXER_MIDI_FLUIDSYNTH)
     endif()
 endif()
 
-list(APPEND SDLMIXER_BACKENDS MIDI_NATIVE)
-list(APPEND SDLMIXER_MIDI_NATIVE_ENABLED FALSE)
-if(SDLMIXER_MIDI_NATIVE)
-    set(midi_common_sources
-        src/codecs/native_midi/native_midi_common.c
-        src/codecs/native_midi/native_midi_common.h
-    )
-    if(WIN32)
-        list(APPEND SDLMIXER_MIDI_NATIVE_ENABLED TRUE)
-        target_sources(${sdl3_mixer_target_name} PRIVATE src/codecs/native_midi/native_midi_win32.c ${midi_common_sources})
-        target_link_libraries(${sdl3_mixer_target_name} PRIVATE winmm)
-    elseif(APPLE)
-        list(APPEND SDLMIXER_MIDI_NATIVE_ENABLED TRUE)
-        target_sources(${sdl3_mixer

(Patch may be truncated, please check the link at the top of this post.)