Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package SDL3_mixer for openSUSE:Factory 
checked in at 2026-10-31 23:11:54
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/SDL3_mixer (Old)
 and      /work/SRC/openSUSE:Factory/.SDL3_mixer.new.1255 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "SDL3_mixer"

Sat Oct 31 23:11:54 2026 rev:3 rq:1394195 version:3.2.4

Changes:
--------
--- /work/SRC/openSUSE:Factory/SDL3_mixer/SDL3_mixer.changes    2026-05-12 
19:30:49.905440351 +0200
+++ /work/SRC/openSUSE:Factory/.SDL3_mixer.new.1255/SDL3_mixer.changes  
2026-10-31 23:15:01.230510467 +0100
@@ -1,0 +2,14 @@
+Sat Oct 31 15:24:22 UTC 2026 - Andrea Manzini <[email protected]>
+
+- Update to release 3.2.4:
+  * Added MIX_PROP_AUDIO_LOAD_IGNORE_LOOPS_BOOLEAN to ignore
+    looping information in an audio file's metadata.
+  * Fixed crash bug in MIX_SetTrackGroup().
+  * Fixed crash in MIX_StopTrack(t, 0) if callback destroys track.
+  * Fixed crash when MIX_PROP_PLAY_MAX_* is less than track start.
+  * Fixed unexpected decoding failures when using MIX_AudioDecoder.
+  * Fixed .OXM files being treated as Ogg Vorbis.
+  * Support custom FluidSynth string settings.
+  * Various small bug fixes and memory leaks.
+
+-------------------------------------------------------------------

Old:
----
  SDL3_mixer-3.2.2.tar.gz
  SDL3_mixer-3.2.2.tar.gz.sig

New:
----
  SDL3_mixer-3.2.4.tar.gz
  SDL3_mixer-3.2.4.tar.gz.sig

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ SDL3_mixer.spec ++++++
--- /var/tmp/diff_new_pack.HfEQgw/_old  2026-10-31 23:15:01.918538978 +0100
+++ /var/tmp/diff_new_pack.HfEQgw/_new  2026-10-31 23:15:01.920539061 +0100
@@ -19,11 +19,10 @@
 
 %define sover  0
 Name:           SDL3_mixer
-Version:        3.2.2
+Version:        3.2.4
 Release:        0
 Summary:        SDL3 sound mixer library
 License:        Zlib
-Group:          Development/Libraries/C and C++
 URL:            https://wiki.libsdl.org/SDL3_mixer
 #Git-Clone:     https://github.com/libsdl-org/SDL_mixer
 Source:         
https://github.com/libsdl-org/SDL_mixer/releases/download/release-%{version}/%{name}-%{version}.tar.gz
@@ -49,7 +48,6 @@
 
 %package -n lib%{name}%{sover}
 Summary:        Simple DirectMedia Layer 3 – Sound mixer library
-Group:          System/Libraries
 Provides:       SDL3_mixer = %{version}-%{release}
 
 %description -n lib%{name}%{sover}
@@ -59,7 +57,6 @@
 
 %package devel
 Summary:        Development files for the SDL3 sound mixer library
-Group:          Development/Libraries/C and C++
 Requires:       lib%{name}%{sover} = %{version}
 
 %description devel

++++++ SDL3_mixer-3.2.2.tar.gz -> SDL3_mixer-3.2.4.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/SDL3_mixer-3.2.2/.git-hash 
new/SDL3_mixer-3.2.4/.git-hash
--- old/SDL3_mixer-3.2.2/.git-hash      2026-05-12 00:31:34.000000000 +0200
+++ new/SDL3_mixer-3.2.4/.git-hash      2026-06-03 01:56:16.000000000 +0200
@@ -1 +1 @@
-a5e1890afc5115ffd16cefdbb4d50f74bf4970ce
+72a81869b45e249e8e67102db4e98dd2441f05a1
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/SDL3_mixer-3.2.2/CMakeLists.txt 
new/SDL3_mixer-3.2.4/CMakeLists.txt
--- old/SDL3_mixer-3.2.2/CMakeLists.txt 2026-05-12 00:31:34.000000000 +0200
+++ new/SDL3_mixer-3.2.4/CMakeLists.txt 2026-06-03 01:56:16.000000000 +0200
@@ -9,7 +9,7 @@
 # See docs/release_checklist.md
 set(MAJOR_VERSION 3)
 set(MINOR_VERSION 2)
-set(MICRO_VERSION 2)
+set(MICRO_VERSION 4)
 set(SDL_REQUIRED_VERSION 3.4.0)
 
 project(SDL3_mixer
@@ -92,7 +92,7 @@
 include(PkgConfigHelper)
 
 set(PLATFORM_SUPPORTS_SHARED ON)
-if(EMSCRIPTEN OR VITA OR PSP OR PS2 OR N3DS OR RISCOS)
+if(EMSCRIPTEN OR VITA OR PSP OR PS2 OR N3DS OR RISCOS OR DOS)
   set(PLATFORM_SUPPORTS_SHARED OFF)
 endif()
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/SDL3_mixer-3.2.2/REVISION.txt 
new/SDL3_mixer-3.2.4/REVISION.txt
--- old/SDL3_mixer-3.2.2/REVISION.txt   2026-05-12 00:31:34.000000000 +0200
+++ new/SDL3_mixer-3.2.4/REVISION.txt   2026-06-03 01:56:16.000000000 +0200
@@ -1 +1 @@
-release-3.2.2-0-ga5e1890a
+release-3.2.4-0-g72a81869
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/SDL3_mixer-3.2.2/VisualC/SDL_mixer.vcxproj 
new/SDL3_mixer-3.2.4/VisualC/SDL_mixer.vcxproj
--- old/SDL3_mixer-3.2.2/VisualC/SDL_mixer.vcxproj      2026-04-25 
16:38:33.000000000 +0200
+++ new/SDL3_mixer-3.2.4/VisualC/SDL_mixer.vcxproj      2026-05-25 
20:21:55.000000000 +0200
@@ -116,7 +116,7 @@
     <ClCompile>
       <Optimization>Disabled</Optimization>
       
<AdditionalIncludeDirectories>$(ProjectDir)..\include;$(ProjectDir)..\src;$(ProjectDir)..\external\flac\include;$(ProjectDir)..\external\libxmp\include;$(ProjectDir)..\external\ogg\include;$(ProjectDir)..\external\vorbis\include;$(ProjectDir)..\external\libgme;$(ProjectDir)\external\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
-      
<PreprocessorDefinitions>DLL_EXPORT;_DEBUG;WIN32;_WINDOWS;DECODER_WAV;DECODER_AIFF;DECODER_VOC;DECODER_AU;DECODER_WAVPACK;DECODER_FLAC_DRFLAC;DECODER_MOD_XMP;XMP_DYNAMIC="libxmp.dll";DECODER_MP3_DRMP3;DECODER_OGGVORBIS_VORBISFILE;DECODER_OGGVORBIS_STB;VORBIS_DYNAMIC="libvorbisfile-3.dll";DECODER_OPUS;OPUS_DYNAMIC="libopusfile-0.dll";WAVPACK_DYNAMIC="libwavpack-1.dll";DECODER_MIDI_TIMIDITY;DECODER_GME;GME_DYNAMIC="libgme.dll";%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      
<PreprocessorDefinitions>DLL_EXPORT;_DEBUG;WIN32;_WINDOWS;DECODER_WAV;DECODER_AIFF;DECODER_VOC;DECODER_AU;DECODER_WAVPACK;DECODER_FLAC_DRFLAC;DECODER_MOD_XMP;XMP_DYNAMIC="libxmp.dll";DECODER_MP3_DRMP3;DECODER_OGGVORBIS_STB;DECODER_OPUS;OPUS_DYNAMIC="libopusfile-0.dll";WAVPACK_DYNAMIC="libwavpack-1.dll";DECODER_MIDI_TIMIDITY;DECODER_GME;GME_DYNAMIC="libgme.dll";%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
       <WarningLevel>Level3</WarningLevel>
       <DebugInformationFormat>OldStyle</DebugInformationFormat>
@@ -144,7 +144,7 @@
     <ClCompile>
       <Optimization>Disabled</Optimization>
       
<AdditionalIncludeDirectories>$(ProjectDir)..\include;$(ProjectDir)..\src;$(ProjectDir)..\external\flac\include;$(ProjectDir)..\external\libxmp\include;$(ProjectDir)..\external\ogg\include;$(ProjectDir)..\external\vorbis\include;$(ProjectDir)..\external\libgme;$(ProjectDir)\external\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
-      
<PreprocessorDefinitions>DLL_EXPORT;_DEBUG;WIN32;_WINDOWS;DECODER_WAV;DECODER_AIFF;DECODER_VOC;DECODER_AU;DECODER_WAVPACK;DECODER_FLAC_DRFLAC;DECODER_MOD_XMP;XMP_DYNAMIC="libxmp.dll";DECODER_MP3_DRMP3;DECODER_OGGVORBIS_VORBISFILE;DECODER_OGGVORBIS_STB;VORBIS_DYNAMIC="libvorbisfile-3.dll";DECODER_OPUS;OPUS_DYNAMIC="libopusfile-0.dll";WAVPACK_DYNAMIC="libwavpack-1.dll";DECODER_MIDI_TIMIDITY;DECODER_GME;GME_DYNAMIC="libgme.dll";%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      
<PreprocessorDefinitions>DLL_EXPORT;_DEBUG;WIN32;_WINDOWS;DECODER_WAV;DECODER_AIFF;DECODER_VOC;DECODER_AU;DECODER_WAVPACK;DECODER_FLAC_DRFLAC;DECODER_MOD_XMP;XMP_DYNAMIC="libxmp.dll";DECODER_MP3_DRMP3;DECODER_OGGVORBIS_STB;DECODER_OPUS;OPUS_DYNAMIC="libopusfile-0.dll";WAVPACK_DYNAMIC="libwavpack-1.dll";DECODER_MIDI_TIMIDITY;DECODER_GME;GME_DYNAMIC="libgme.dll";%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
       <WarningLevel>Level3</WarningLevel>
       <DebugInformationFormat>OldStyle</DebugInformationFormat>
@@ -170,7 +170,7 @@
     </Midl>
     <ClCompile>
       
<AdditionalIncludeDirectories>$(ProjectDir)..\include;$(ProjectDir)..\src;$(ProjectDir)..\external\flac\include;$(ProjectDir)..\external\libxmp\include;$(ProjectDir)..\external\ogg\include;$(ProjectDir)..\external\vorbis\include;$(ProjectDir)..\external\libgme;$(ProjectDir)\external\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
-      
<PreprocessorDefinitions>DLL_EXPORT;NDEBUG;WIN32;_WINDOWS;_CRT_SECURE_NO_WARNINGS;DECODER_WAV;DECODER_AIFF;DECODER_VOC;DECODER_AU;DECODER_WAVPACK;DECODER_FLAC_DRFLAC;DECODER_MOD_XMP;XMP_DYNAMIC="libxmp.dll";DECODER_MP3_DRMP3;DECODER_OGGVORBIS_VORBISFILE;DECODER_OGGVORBIS_STB;VORBIS_DYNAMIC="libvorbisfile-3.dll";DECODER_OPUS;OPUS_DYNAMIC="libopusfile-0.dll";WAVPACK_DYNAMIC="libwavpack-1.dll";DECODER_MIDI_TIMIDITY;DECODER_GME;GME_DYNAMIC="libgme.dll";%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      
<PreprocessorDefinitions>DLL_EXPORT;NDEBUG;WIN32;_WINDOWS;_CRT_SECURE_NO_WARNINGS;DECODER_WAV;DECODER_AIFF;DECODER_VOC;DECODER_AU;DECODER_WAVPACK;DECODER_FLAC_DRFLAC;DECODER_MOD_XMP;XMP_DYNAMIC="libxmp.dll";DECODER_MP3_DRMP3;DECODER_OGGVORBIS_STB;DECODER_OPUS;OPUS_DYNAMIC="libopusfile-0.dll";WAVPACK_DYNAMIC="libwavpack-1.dll";DECODER_MIDI_TIMIDITY;DECODER_GME;GME_DYNAMIC="libgme.dll";%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
       <WarningLevel>Level3</WarningLevel>
       
<EnableEnhancedInstructionSet>StreamingSIMDExtensions</EnableEnhancedInstructionSet>
@@ -197,7 +197,7 @@
     </Midl>
     <ClCompile>
       
<AdditionalIncludeDirectories>$(ProjectDir)..\include;$(ProjectDir)..\src;$(ProjectDir)..\external\flac\include;$(ProjectDir)..\external\libxmp\include;$(ProjectDir)..\external\ogg\include;$(ProjectDir)..\external\vorbis\include;$(ProjectDir)..\external\libgme;$(ProjectDir)\external\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
-      
<PreprocessorDefinitions>DLL_EXPORT;NDEBUG;WIN32;_WINDOWS;_CRT_SECURE_NO_WARNINGS;DECODER_WAV;DECODER_AIFF;DECODER_VOC;DECODER_AU;DECODER_WAVPACK;DECODER_FLAC_DRFLAC;DECODER_MOD_XMP;XMP_DYNAMIC="libxmp.dll";DECODER_MP3_DRMP3;DECODER_OGGVORBIS_VORBISFILE;DECODER_OGGVORBIS_STB;VORBIS_DYNAMIC="libvorbisfile-3.dll";DECODER_OPUS;OPUS_DYNAMIC="libopusfile-0.dll";WAVPACK_DYNAMIC="libwavpack-1.dll";DECODER_MIDI_TIMIDITY;DECODER_GME;GME_DYNAMIC="libgme.dll";%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      
<PreprocessorDefinitions>DLL_EXPORT;NDEBUG;WIN32;_WINDOWS;_CRT_SECURE_NO_WARNINGS;DECODER_WAV;DECODER_AIFF;DECODER_VOC;DECODER_AU;DECODER_WAVPACK;DECODER_FLAC_DRFLAC;DECODER_MOD_XMP;XMP_DYNAMIC="libxmp.dll";DECODER_MP3_DRMP3;DECODER_OGGVORBIS_STB;DECODER_OPUS;OPUS_DYNAMIC="libopusfile-0.dll";WAVPACK_DYNAMIC="libwavpack-1.dll";DECODER_MIDI_TIMIDITY;DECODER_GME;GME_DYNAMIC="libgme.dll";%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
       <WarningLevel>Level3</WarningLevel>
     </ClCompile>
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/SDL3_mixer-3.2.2/Xcode/Info-Framework.plist 
new/SDL3_mixer-3.2.4/Xcode/Info-Framework.plist
--- old/SDL3_mixer-3.2.2/Xcode/Info-Framework.plist     2026-05-12 
00:31:34.000000000 +0200
+++ new/SDL3_mixer-3.2.4/Xcode/Info-Framework.plist     2026-06-03 
01:56:16.000000000 +0200
@@ -15,8 +15,8 @@
        <key>CFBundlePackageType</key>
        <string>FMWK</string>
        <key>CFBundleShortVersionString</key>
-       <string>3.2.2</string>
+       <string>3.2.4</string>
        <key>CFBundleVersion</key>
-       <string>3.2.2</string>
+       <string>3.2.4</string>
 </dict>
 </plist>
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/SDL3_mixer-3.2.2/Xcode/SDL_mixer.xcodeproj/project.pbxproj 
new/SDL3_mixer-3.2.4/Xcode/SDL_mixer.xcodeproj/project.pbxproj
--- old/SDL3_mixer-3.2.2/Xcode/SDL_mixer.xcodeproj/project.pbxproj      
2026-05-12 00:31:34.000000000 +0200
+++ new/SDL3_mixer-3.2.4/Xcode/SDL_mixer.xcodeproj/project.pbxproj      
2026-06-03 01:56:16.000000000 +0200
@@ -648,7 +648,7 @@
                                DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
                                DEPLOYMENT_POSTPROCESSING = YES;
                                DYLIB_COMPATIBILITY_VERSION = 201.0.0;
-                               DYLIB_CURRENT_VERSION = 201.2.0;
+                               DYLIB_CURRENT_VERSION = 201.4.0;
                                DYLIB_INSTALL_NAME_BASE = "@rpath";
                                "FRAMEWORK_SEARCH_PATHS[sdk=appletv*]" = 
"\"$(PROJECT_DIR)/iOS\"";
                                "FRAMEWORK_SEARCH_PATHS[sdk=iphone*]" = 
"\"$(PROJECT_DIR)/iOS\"";
@@ -678,7 +678,7 @@
                                        "@loader_path/Frameworks",
                                );
                                MACOSX_DEPLOYMENT_TARGET = 10.13;
-                               MARKETING_VERSION = 3.2.2;
+                               MARKETING_VERSION = 3.2.4;
                                PRODUCT_BUNDLE_IDENTIFIER = 
"org.libsdl.SDL3-mixer";
                                PRODUCT_NAME = SDL3_mixer;
                                SUPPORTED_PLATFORMS = "xrsimulator xros macosx 
iphonesimulator iphoneos appletvsimulator appletvos";
@@ -698,7 +698,7 @@
                                COPY_PHASE_STRIP = NO;
                                DEBUG_INFORMATION_FORMAT = dwarf;
                                DYLIB_COMPATIBILITY_VERSION = 201.0.0;
-                               DYLIB_CURRENT_VERSION = 201.2.0;
+                               DYLIB_CURRENT_VERSION = 201.4.0;
                                DYLIB_INSTALL_NAME_BASE = "@rpath";
                                ENABLE_TESTABILITY = YES;
                                "FRAMEWORK_SEARCH_PATHS[sdk=appletv*]" = 
"\"$(PROJECT_DIR)/iOS\"";
@@ -729,7 +729,7 @@
                                        "@loader_path/Frameworks",
                                );
                                MACOSX_DEPLOYMENT_TARGET = 10.13;
-                               MARKETING_VERSION = 3.2.2;
+                               MARKETING_VERSION = 3.2.4;
                                ONLY_ACTIVE_ARCH = YES;
                                PRODUCT_BUNDLE_IDENTIFIER = 
"org.libsdl.SDL3-mixer";
                                PRODUCT_NAME = SDL3_mixer;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/SDL3_mixer-3.2.2/build-scripts/test-versioning.sh 
new/SDL3_mixer-3.2.4/build-scripts/test-versioning.sh
--- old/SDL3_mixer-3.2.2/build-scripts/test-versioning.sh       2026-01-01 
21:14:23.000000000 +0100
+++ new/SDL3_mixer-3.2.4/build-scripts/test-versioning.sh       2026-05-15 
18:23:42.000000000 +0200
@@ -92,6 +92,17 @@
     not_ok "Info-Framework.plist CFBundleVersion $version disagrees with 
SDL_mixer.h $ref_version"
 fi
 
+marketing=$(sed -Ene 's/.*MARKETING_VERSION = (.*);/\1/p' 
Xcode/SDL_mixer.xcodeproj/project.pbxproj)
+
+ref="$ref_version
+$ref_version"
+
+if [ "$ref" = "$marketing" ]; then
+    ok "project.pbxproj MARKETING_VERSION is consistent"
+else
+    not_ok "project.pbxproj MARKETING_VERSION is inconsistent, expected $ref, 
got $marketing"
+fi
+
 # For simplicity this assumes we'll never break ABI before SDL 3.
 dylib_compat=$(sed -Ene 's/.*DYLIB_COMPATIBILITY_VERSION = (.*);$/\1/p' 
Xcode/SDL_mixer.xcodeproj/project.pbxproj)
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/SDL3_mixer-3.2.2/examples/CMakeLists.txt 
new/SDL3_mixer-3.2.4/examples/CMakeLists.txt
--- old/SDL3_mixer-3.2.2/examples/CMakeLists.txt        2026-02-04 
21:50:29.000000000 +0100
+++ new/SDL3_mixer-3.2.4/examples/CMakeLists.txt        2026-05-19 
21:15:51.000000000 +0200
@@ -132,6 +132,7 @@
 add_sdlmixer_example_executable(basics-metadata SOURCES 
basics/04-metadata/metadata.c DATAFILES ${CMAKE_CURRENT_SOURCE_DIR}/music.mp3)
 add_sdlmixer_example_executable(basics-sinewave SOURCES 
basics/05-sinewave/sinewave.c)
 add_sdlmixer_example_executable(basics-seeking SOURCES 
basics/06-seeking/seeking.c DATAFILES ${CMAKE_CURRENT_SOURCE_DIR}/music.mp3)
+add_sdlmixer_example_executable(advanced-tag-tracks SOURCES 
advanced/01-tag-tracks/tag-tracks.c DATAFILES 
${CMAKE_CURRENT_SOURCE_DIR}/music.mp3 ${CMAKE_CURRENT_SOURCE_DIR}/sword.wav 
${CMAKE_CURRENT_SOURCE_DIR}/spring.wav ${CMAKE_CURRENT_SOURCE_DIR}/splash.wav)
 
 # When you add an example, remember to add the Visual Studio project as well:
 # - Add a new example in examples/
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/SDL3_mixer-3.2.2/examples/README.md 
new/SDL3_mixer-3.2.4/examples/README.md
--- old/SDL3_mixer-3.2.2/examples/README.md     2026-01-26 21:52:14.000000000 
+0100
+++ new/SDL3_mixer-3.2.4/examples/README.md     2026-05-19 21:15:51.000000000 
+0200
@@ -80,3 +80,13 @@
   Original: https://freesound.org/s/27858/
   License: https://creativecommons.org/licenses/by/4.0/
 
+- splash.wav:
+  SPLASH.wav by petenice
+  Original: https://freesound.org/s/9508/
+  License: https://creativecommons.org/publicdomain/zero/1.0/
+
+- spring.wav:
+  Game Over Arcade.wav by myfox14
+  Original: https://freesound.org/s/382310/
+  License: https://creativecommons.org/publicdomain/zero/1.0/
+
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/SDL3_mixer-3.2.2/examples/advanced/01-tag-tracks/README.txt 
new/SDL3_mixer-3.2.4/examples/advanced/01-tag-tracks/README.txt
--- old/SDL3_mixer-3.2.2/examples/advanced/01-tag-tracks/README.txt     
1970-01-01 01:00:00.000000000 +0100
+++ new/SDL3_mixer-3.2.4/examples/advanced/01-tag-tracks/README.txt     
2026-05-19 21:15:51.000000000 +0200
@@ -0,0 +1,7 @@
+This example code creates a mixer, plays sounds, and tags them into groups.
+
+We'll play a background music track, and tag the other sounds as "in-game".
+So when you click the "pause" button, (what would be) your game sounds can
+all pause at once, but the background music can continue on.
+
+(Remember that web browsers won't make sound until you click on the page!)
Binary files 
old/SDL3_mixer-3.2.2/examples/advanced/01-tag-tracks/onmouseover.webp and 
new/SDL3_mixer-3.2.4/examples/advanced/01-tag-tracks/onmouseover.webp differ
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/SDL3_mixer-3.2.2/examples/advanced/01-tag-tracks/tag-tracks.c 
new/SDL3_mixer-3.2.4/examples/advanced/01-tag-tracks/tag-tracks.c
--- old/SDL3_mixer-3.2.2/examples/advanced/01-tag-tracks/tag-tracks.c   
1970-01-01 01:00:00.000000000 +0100
+++ new/SDL3_mixer-3.2.4/examples/advanced/01-tag-tracks/tag-tracks.c   
2026-05-19 21:15:51.000000000 +0200
@@ -0,0 +1,199 @@
+/*
+ * This example code creates a mixer, plays sounds, and tags them into groups.
+ *
+ * We'll play a background music track, and tag the other sounds as "in-game".
+ * So when you click the "pause" button, (what would be) your game sounds can
+ * all pause at once, but the background music can continue on.
+ *
+ * This code is public domain. Feel free to use it for any purpose!
+ */
+
+#define SDL_MAIN_USE_CALLBACKS 1  /* use the callbacks instead of main() */
+#include <SDL3/SDL.h>
+#include <SDL3/SDL_main.h>
+#include <SDL3_mixer/SDL_mixer.h>
+
+#define TAG_INGAME "in-game"
+
+/* We will use this renderer to draw into this window every frame. */
+static SDL_Window *window = NULL;
+static SDL_Renderer *renderer = NULL;
+
+static MIX_Mixer *mixer = NULL;
+static MIX_Track *tracks[32];
+
+static Uint64 next_play_ticks = 0;  /* next time we will start a sound effect. 
*/
+static size_t next_play_track = 1;  /* next track we'll use when we start a 
sound effect. */
+static bool paused = false;  /* whether our fake game is paused at the moment. 
*/
+
+static struct {
+    const char *filename;
+    MIX_Audio *audio;
+} loaded_audio[] = {
+    { "music.mp3", NULL },
+    { "sword.wav", NULL },
+    { "splash.wav", NULL },
+    { "spring.wav", NULL }
+};
+
+static MIX_Audio *load_audio(const char *fname)
+{
+    char *path = NULL;
+    MIX_Audio *audio;
+    SDL_asprintf(&path, "%s%s", SDL_GetBasePath(), fname);  /* allocate a 
string of the full file path */
+    audio = MIX_LoadAudio(mixer, path, false);
+    if (!audio) {
+        SDL_Log("Couldn't load %s: %s", path, SDL_GetError());
+    }
+
+    SDL_free(path);  /* done with this. */
+    return audio;
+}
+
+/* This function runs once at startup. */
+SDL_AppResult SDL_AppInit(void **appstate, int argc, char *argv[])
+{
+    SDL_PropertiesID options = 0;
+    int i;
+
+    SDL_SetAppMetadata("Example Tagging Tracks", "1.0", 
"com.example.tagging-tracks");
+
+    if (!SDL_Init(SDL_INIT_VIDEO)) {
+        SDL_Log("Couldn't initialize SDL: %s", SDL_GetError());
+        return SDL_APP_FAILURE;
+    }
+
+    if (!SDL_CreateWindowAndRenderer("examples/advanced/tagging-tracks", 640, 
480, SDL_WINDOW_RESIZABLE, &window, &renderer)) {
+        SDL_Log("Couldn't create window/renderer: %s", SDL_GetError());
+        return SDL_APP_FAILURE;
+    }
+
+    if (!MIX_Init()) {
+        SDL_Log("Couldn't init SDL_mixer library: %s", SDL_GetError());
+        return SDL_APP_FAILURE;
+    }
+
+    /* Create a mixer on the default audio device. Don't care about the 
specific audio format. */
+    mixer = MIX_CreateMixerDevice(SDL_AUDIO_DEVICE_DEFAULT_PLAYBACK, NULL);
+    if (!mixer) {
+        SDL_Log("Couldn't create mixer on default device: %s", SDL_GetError());
+        return SDL_APP_FAILURE;
+    }
+
+    /* load our audio files. Note that you can use any supported file format! 
*/
+    for (i = 0; i < (int) SDL_arraysize(loaded_audio); i++) {
+        loaded_audio[i].audio = load_audio(loaded_audio[i].filename);
+        if (!loaded_audio[i].audio) {
+            return SDL_APP_FAILURE;  /* we reported the error in load_audio */
+        }
+    }
+
+    /* we need tracks on the mixer to play the audio. Each track has audio
+       assigned to it, and all playing tracks are mixed together for the final
+       output. */
+    for (i = 0; i < (int) SDL_arraysize(tracks); i++) {
+        tracks[i] = MIX_CreateTrack(mixer);
+        if (!tracks[i]) {
+            SDL_Log("Couldn't create a mixer track: %s", SDL_GetError());
+            return SDL_APP_FAILURE;
+        }
+        if (i > 0) {  /* everything but the background music is tagged as 
in-game for this example. */
+            if (!MIX_TagTrack(tracks[i], TAG_INGAME)) {
+                SDL_Log("Couldn't tag mixer track #%d: %s", i, SDL_GetError());
+                return SDL_APP_FAILURE;
+            }
+        }
+    }
+
+    /* Put the music (first thing we loaded) on track[0], for simplicity here. 
*/
+    MIX_SetTrackAudio(tracks[0], loaded_audio[0].audio);
+
+    options = SDL_CreateProperties();
+    if (!options) {
+        SDL_Log("Couldn't create play options: %s", SDL_GetError());
+        return SDL_APP_FAILURE;
+    }
+    SDL_SetNumberProperty(options, MIX_PROP_PLAY_LOOPS_NUMBER, -1);  /* loop 
forever. */
+
+    /* start the music playing! it loops forever. */
+    MIX_PlayTrack(tracks[0], options);
+    SDL_DestroyProperties(options);  /* MIX_PlayTrack makes a copy of the 
options, so this can go away. */
+
+    return SDL_APP_CONTINUE;  /* carry on with the program! */
+}
+
+/* This function runs when a new event (mouse input, keypresses, etc) occurs. 
*/
+SDL_AppResult SDL_AppEvent(void *appstate, SDL_Event *event)
+{
+    if (event->type == SDL_EVENT_QUIT) {
+        return SDL_APP_SUCCESS;  /* end the program, reporting success to the 
OS. */
+    } else if ((event->type == SDL_EVENT_KEY_DOWN) && (event->key.key == 
SDLK_SPACE)) {
+        paused = !paused;
+        if (paused) {
+            MIX_PauseTag(mixer, TAG_INGAME);
+        } else {
+            MIX_ResumeTag(mixer, TAG_INGAME);
+        }
+    }
+    return SDL_APP_CONTINUE;  /* carry on with the program! */
+}
+
+static void draw_centered_text(SDL_Renderer *renderer, const int rw, int *y, 
const char *str)
+{
+    const int x = (rw - (((int) SDL_strlen(str)) * 
SDL_DEBUG_TEXT_FONT_CHARACTER_SIZE)) / 2;
+    SDL_RenderDebugText(renderer, (float) x, (float) *y, str);
+    *y += SDL_DEBUG_TEXT_FONT_CHARACTER_SIZE * 2;
+}
+
+/* This function runs once per frame, and is the heart of the program. */
+SDL_AppResult SDL_AppIterate(void *appstate)
+{
+    const Uint64 now = SDL_GetTicks();
+    int rw, rh, y;
+
+    if (!paused && (now >= next_play_ticks)) {   /* simulate video game sounds 
by starting a new one every now and then, with some randomness. */
+        MIX_Track *track = tracks[next_play_track];
+        /* these sounds are short enough that the tracks will finish playing 
before we reuse them */
+        MIX_SetTrackAudio(track, 
loaded_audio[SDL_rand(SDL_arraysize(loaded_audio) - 1) + 1].audio);  /* pick a 
random not-music audio sound. */
+        MIX_PlayTrack(track, 0);
+        next_play_track++;
+        if (next_play_track >= SDL_arraysize(tracks)) {
+            next_play_track = 1;  /* tracks[0] is the music, skip it. */
+        }
+        next_play_ticks = now + SDL_rand(1000);
+    }
+
+    SDL_GetCurrentRenderOutputSize(renderer, &rw, &rh);
+    SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);  /* clear to black */
+    SDL_RenderClear(renderer);
+
+    y = SDL_DEBUG_TEXT_FONT_CHARACTER_SIZE * 8;
+    SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255);  /* white text */
+    draw_centered_text(renderer, rw, &y, "PRETEND THIS IS A VIDEO GAME.");
+    draw_centered_text(renderer, rw, &y, "THERE ARE SOUND EFFECTS AND 
BACKGROUND MUSIC.");
+    draw_centered_text(renderer, rw, &y, "THE EFFECTS ARE ON TRACKS TAGGED AS 
\"in-game\".");
+    draw_centered_text(renderer, rw, &y, "PRESS SPACE TO PAUSE/UNPAUSE THE 
GAME.");
+    draw_centered_text(renderer, rw, &y, "THE IN-GAME SOUNDS WILL PAUSE.");
+    draw_centered_text(renderer, rw, &y, "THE MUSIC TRACK, NOT TAGGED, WILL 
NOT.");
+
+    y += SDL_DEBUG_TEXT_FONT_CHARACTER_SIZE * 8;
+    if (paused) {
+        SDL_SetRenderDrawColor(renderer, 255, 0, 0, 255);  /* red text */
+        draw_centered_text(renderer, rw, &y, "[ CURRENTLY PAUSED ]");
+    } else {
+        SDL_SetRenderDrawColor(renderer, 0, 255, 0, 255);  /* green text */
+        draw_centered_text(renderer, rw, &y, "[ CURRENTLY UNPAUSED ]");
+    }
+
+    SDL_RenderPresent(renderer);
+
+    return SDL_APP_CONTINUE;  /* carry on with the program! */
+}
+
+/* This function runs once at shutdown. */
+void SDL_AppQuit(void *appstate, SDL_AppResult result)
+{
+    /* SDL will clean up the window/renderer for us, MIX_Quit() destroys any 
mixer objects we made. */
+    MIX_Quit();
+}
+
Binary files old/SDL3_mixer-3.2.2/examples/advanced/01-tag-tracks/thumbnail.png 
and new/SDL3_mixer-3.2.4/examples/advanced/01-tag-tracks/thumbnail.png differ
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/SDL3_mixer-3.2.2/examples/categories.txt 
new/SDL3_mixer-3.2.4/examples/categories.txt
--- old/SDL3_mixer-3.2.2/examples/categories.txt        1970-01-01 
01:00:00.000000000 +0100
+++ new/SDL3_mixer-3.2.4/examples/categories.txt        2026-05-19 
22:53:12.000000000 +0200
@@ -0,0 +1,8 @@
+# Blank lines and lines that start with '#' in this file are ignored.
+
+# Categories, by directory name, go in here, in the order they should be
+# listed on the main page. If this file is missing, it'll assume any
+# subdirectory is a category and sort them alphabetically.
+
+basics
+advanced
Binary files old/SDL3_mixer-3.2.2/examples/splash.wav and 
new/SDL3_mixer-3.2.4/examples/splash.wav differ
Binary files old/SDL3_mixer-3.2.2/examples/spring.wav and 
new/SDL3_mixer-3.2.4/examples/spring.wav differ
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/SDL3_mixer-3.2.2/include/SDL3_mixer/SDL_mixer.h 
new/SDL3_mixer-3.2.4/include/SDL3_mixer/SDL_mixer.h
--- old/SDL3_mixer-3.2.2/include/SDL3_mixer/SDL_mixer.h 2026-05-12 
00:31:34.000000000 +0200
+++ new/SDL3_mixer-3.2.4/include/SDL3_mixer/SDL_mixer.h 2026-06-03 
01:56:16.000000000 +0200
@@ -217,7 +217,7 @@
  *
  * \since This macro is available since SDL_mixer 3.0.0.
  */
-#define SDL_MIXER_MICRO_VERSION   2
+#define SDL_MIXER_MICRO_VERSION   4
 
 /**
  * This is the current version number macro of the SDL_mixer headers.
@@ -747,7 +747,6 @@
  * SDL_PropertiesID are discussed in
  * [SDL's documentation](https://wiki.libsdl.org/SDL3/CategoryProperties)
  * .
- *
  * These are the supported properties:
  *
  * - `MIX_PROP_AUDIO_LOAD_IOSTREAM_POINTER`: a pointer to an SDL_IOStream to
@@ -763,6 +762,11 @@
  *   metadata tags, like ID3 and APE tags. This can be used to speed up
  *   loading _if the data definitely doesn't have these tags_. Some decoders
  *   will fail if these tags are present when this property is true.
+ * - `MIX_PROP_AUDIO_LOAD_IGNORE_LOOPS_BOOLEAN`: true to ignore metadata in
+ *   the audio data specifying loop points. This will make a file decode from
+ *   start to finish without looping, even if the file specified it should
+ *   have. This audio can still be looped at playback time via MIX_Track loop
+ *   settings, regardless of this setting. Default false.
  * - `MIX_PROP_AUDIO_DECODER_STRING`: the name of the decoder to use for this
  *   data. Optional. If not specified, SDL_mixer will examine the data and
  *   choose the best decoder. These names are the same returned from
@@ -791,6 +795,7 @@
 #define MIX_PROP_AUDIO_LOAD_PREDECODE_BOOLEAN "SDL_mixer.audio.load.predecode"
 #define MIX_PROP_AUDIO_LOAD_PREFERRED_MIXER_POINTER 
"SDL_mixer.audio.load.preferred_mixer"
 #define MIX_PROP_AUDIO_LOAD_SKIP_METADATA_TAGS_BOOLEAN 
"SDL_mixer.audio.load.skip_metadata_tags"
+#define MIX_PROP_AUDIO_LOAD_IGNORE_LOOPS_BOOLEAN 
"SDL_mixer.audio.load.ignore_loops"
 #define MIX_PROP_AUDIO_DECODER_STRING "SDL_mixer.audio.decoder"
 
 /**
@@ -3244,8 +3249,9 @@
  *
  * This function allows properties to be specified. This is intended to supply
  * file-specific settings, such as where to find SoundFonts for a MIDI file,
- * etc. In most cases, the caller should pass a zero to specify no extra
- * properties.
+ * etc. Most of the properties available to MIX_LoadAudioWithProperties()
+ * apply here, too. In most cases, the caller should pass a zero to specify no
+ * extra properties.
  *
  * If `closeio` is true, then `io` will be closed when this decoder is done
  * with it. If this function fails and `closeio` is true, then `io` will be
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/SDL3_mixer-3.2.2/src/SDL_mixer.c 
new/SDL3_mixer-3.2.4/src/SDL_mixer.c
--- old/SDL3_mixer-3.2.2/src/SDL_mixer.c        2026-04-16 20:28:48.000000000 
+0200
+++ new/SDL3_mixer-3.2.4/src/SDL_mixer.c        2026-06-02 23:39:50.000000000 
+0200
@@ -242,6 +242,8 @@
 
 static void ApplyFade(MIX_Track *track, int channels, float *pcm, int frames)
 {
+    SDL_assert(frames >= 0);
+
     // !!! FIXME: this is probably pretty naive.
 
     if (track->fade_direction == 0) {
@@ -412,6 +414,9 @@
                 const Sint64 newpos = (Sint64)(track->position + frames_read);
                 if (newpos >= maxpos) {  // we read past the end of the fade 
out or maxframes, we need to clamp.
                     br -= (int)(((newpos - maxpos) * raw_channels) * 
sizeof(float));
+                    if (br < 0) {
+                        br = 0;
+                    }
                     frames_read = br / (sizeof (float) * raw_channels);
                     end_of_audio = true;
                 }
@@ -576,7 +581,7 @@
         for (MIX_Track *track = group->tracks; track; track = next_track) {
             next_track = track->group_next;  // this won't save you from a 
callback going totally rogue, but it'll deal with the current track leaving the 
group.
 
-            track->currently_mixing = true;
+            track->currently_inuse = true;
 
             const int to_be_read = (additional_amount / 
SDL_AUDIO_FRAMESIZE(mixer->spec)) * SDL_AUDIO_FRAMESIZE(track->output_spec);
             const int br = SDL_GetAudioStreamData(track->output_stream, 
getbuf, to_be_read);
@@ -610,7 +615,7 @@
                 }
             }
 
-            track->currently_mixing = false;
+            track->currently_inuse = false;
             if (track->destroy_requested) {  // callback asked to destroy the 
track while we were still using it.
                 MIX_DestroyTrack(track);  // actually kill it now.
             }
@@ -720,14 +725,15 @@
     }
 
     // actually shutting down now.
-    while (all_audiodecoders) {
-        MIX_DestroyAudioDecoder(all_audiodecoders);
-    }
 
     while (all_mixers) {
         MIX_DestroyMixer(all_mixers);
     }
 
+    while (all_audiodecoders) {
+        MIX_DestroyAudioDecoder(all_audiodecoders);
+    }
+
     while (all_audios) {
         MIX_DestroyAudio(all_audios);
     }
@@ -1515,7 +1521,7 @@
     // handle the case where someone destroys a track during a mixer callback. 
 :O
     //  tracks are not currently reference-counted like MIX_Audio objects are, 
but
     //  we'll catch this specific case for now.
-    if (track->currently_mixing) {
+    if (track->currently_inuse) {
         track->destroy_requested = true;
         UnlockMixer(mixer);
         return;
@@ -2399,7 +2405,9 @@
             if (track->internal_stream) {
                 SDL_ClearAudioStream(track->internal_stream);  // make sure we 
don't leave old data hanging around.
             }
+            track->currently_inuse = true;
             TrackStopped(track);
+            track->currently_inuse = false;
         } else {
             track->total_fade_frames = fadeOut;
             track->fade_frames = fadeOut;
@@ -2408,6 +2416,10 @@
         }
     }
     UnlockTrack(track);
+
+    if (track->destroy_requested) {  // callback asked to destroy the track 
while we were still touching it.
+        MIX_DestroyTrack(track);  // actually kill it now.
+    }
 }
 
 bool MIX_StopTrack(MIX_Track *track, Sint64 fade_out_frames)
@@ -2999,17 +3011,17 @@
     MIX_Group *oldgroup = track->group;
     if (group != oldgroup) {
         if (oldgroup) {   // remove from current group, if in one.
+            if (track->group_next) {
+                track->group_next->group_prev = track->group_prev;
+            }
             if (track->group_prev) {
                 track->group_prev->group_next = track->group_next;
-                track->group_prev = NULL;
             } else {
                 oldgroup->tracks = track->group_next;
             }
-            if (track->group_next) {
-                track->group_next->group_prev = track->group_prev;
-            }
         }
 
+        track->group_prev = NULL;
         track->group_next = group->tracks;
         if (group->tracks) {
             group->tracks->group_prev = track;
@@ -3085,16 +3097,16 @@
     if (!audiodecoder->audio) {
         SDL_free(audiodecoder);
         return NULL;
-    }
-
-    if 
(!audiodecoder->audio->decoder->init_track(audiodecoder->audio->decoder_userdata,
 io, &audiodecoder->audio->spec, audiodecoder->audio->props, 
&audiodecoder->track_userdata)) {
+    } else if 
(!audiodecoder->audio->decoder->init_track(audiodecoder->audio->decoder_userdata,
 io, &audiodecoder->audio->spec, audiodecoder->audio->props, 
&audiodecoder->track_userdata)) {
         MIX_DestroyAudio(audiodecoder->audio);
         SDL_free(audiodecoder);
         return NULL;
-    }
-
-    audiodecoder->stream = SDL_CreateAudioStream(&audiodecoder->audio->spec, 
&audiodecoder->audio->spec);
-    if (!audiodecoder->stream) {
+    } else if 
(!audiodecoder->audio->decoder->seek(audiodecoder->track_userdata, 0)) {
+        audiodecoder->audio->decoder->quit_track(audiodecoder->track_userdata);
+        MIX_DestroyAudio(audiodecoder->audio);
+        SDL_free(audiodecoder);
+        return NULL;
+    } else if ((audiodecoder->stream = 
SDL_CreateAudioStream(&audiodecoder->audio->spec, &audiodecoder->audio->spec)) 
== NULL) {
         audiodecoder->audio->decoder->quit_track(audiodecoder->track_userdata);
         MIX_DestroyAudio(audiodecoder->audio);
         SDL_free(audiodecoder);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/SDL3_mixer-3.2.2/src/SDL_mixer_internal.h 
new/SDL3_mixer-3.2.4/src/SDL_mixer_internal.h
--- old/SDL3_mixer-3.2.2/src/SDL_mixer_internal.h       2026-04-16 
20:28:48.000000000 +0200
+++ new/SDL3_mixer-3.2.4/src/SDL_mixer_internal.h       2026-05-19 
04:46:46.000000000 +0200
@@ -148,7 +148,7 @@
     MIX_Audio *input_audio;    // non-NULL if used with 
MIX_SetTrackAudioStream. Holds a reference.
     SDL_IOStream *io;  // used for MIX_SetTrackAudio and MIX_SetTrackIOStream. 
Might be owned by us (SDL_IOFromConstMem of MIX_Audio::precache), or owned by 
the app.
     MIX_IoClamp ioclamp;  // used for MIX_SetTrackAudio and 
MIX_SetTrackIOStream.
-    bool currently_mixing;  // true when the mixer is running on this track.
+    bool currently_inuse;  // true when we want to delay an app's 
MIX_DestroyTrack request (they destroyed it from a mixer callback).
     bool destroy_requested;  // true if MIX_DestroyTrack called while the 
track is actively mixing.
     bool closeio;  // true if we should close `io` when changing track data.
     bool halt_when_exhausted;  // true if we should stop the track when input 
runs out.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/SDL3_mixer-3.2.2/src/SDL_mixer_metadata_tags.c 
new/SDL3_mixer-3.2.4/src/SDL_mixer_metadata_tags.c
--- old/SDL3_mixer-3.2.2/src/SDL_mixer_metadata_tags.c  2026-02-28 
17:44:53.000000000 +0100
+++ new/SDL3_mixer-3.2.4/src/SDL_mixer_metadata_tags.c  2026-05-19 
16:21:29.000000000 +0200
@@ -118,8 +118,10 @@
 {
     if (!SDL_HasProperty(props, key)) {  // in case there are multiple ID3v1 
tags appended to a file, we'll take the last one, since we parse backwards from 
the end of file.
         char *src_buf = parse_id3v1_ansi_string(buffer, len);
-        if (src_buf && *src_buf) {
-            SDL_SetStringProperty(props, key, src_buf);
+        if (src_buf) {
+            if (*src_buf) {
+                SDL_SetStringProperty(props, key, src_buf);
+            }
             SDL_free(src_buf);
         }
     }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/SDL3_mixer-3.2.2/src/decoder_drflac.c 
new/SDL3_mixer-3.2.4/src/decoder_drflac.c
--- old/SDL3_mixer-3.2.2/src/decoder_drflac.c   2026-03-10 22:58:33.000000000 
+0100
+++ new/SDL3_mixer-3.2.4/src/decoder_drflac.c   2026-05-17 01:17:05.000000000 
+0200
@@ -176,7 +176,8 @@
 
     adata->framesize = SDL_AUDIO_FRAMESIZE(*spec);
 
-    if (adata->loop.end > (Sint64)decoder->totalPCMFrameCount) {
+    const bool ignore_loops = SDL_GetBooleanProperty(props, 
MIX_PROP_AUDIO_LOAD_IGNORE_LOOPS_BOOLEAN, false);
+    if (ignore_loops || (adata->loop.end > 
(Sint64)decoder->totalPCMFrameCount)) {
         adata->loop.active = false;
     }
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/SDL3_mixer-3.2.2/src/decoder_flac.c 
new/SDL3_mixer-3.2.4/src/decoder_flac.c
--- old/SDL3_mixer-3.2.2/src/decoder_flac.c     2026-03-10 22:58:33.000000000 
+0100
+++ new/SDL3_mixer-3.2.4/src/decoder_flac.c     2026-05-17 01:17:05.000000000 
+0200
@@ -376,7 +376,8 @@
 
     SDL_copyp(spec, &tdata.spec);
 
-    if (adata->loop.end > total_frames) {
+    const bool ignore_loops = SDL_GetBooleanProperty(props, 
MIX_PROP_AUDIO_LOAD_IGNORE_LOOPS_BOOLEAN, false);
+    if (ignore_loops || (adata->loop.end > total_frames)) {
         adata->loop.active = false;
     }
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/SDL3_mixer-3.2.2/src/decoder_fluidsynth.c 
new/SDL3_mixer-3.2.4/src/decoder_fluidsynth.c
--- old/SDL3_mixer-3.2.2/src/decoder_fluidsynth.c       2026-03-10 
22:58:33.000000000 +0100
+++ new/SDL3_mixer-3.2.4/src/decoder_fluidsynth.c       2026-06-01 
19:19:34.000000000 +0200
@@ -50,6 +50,7 @@
     MIX_LOADER_FUNCTION(true,int,fluid_player_get_total_ticks,(fluid_player_t 
*)) \
     MIX_LOADER_FUNCTION(true,int,fluid_settings_setint,(fluid_settings_t*, 
const char*, int)) \
     MIX_LOADER_FUNCTION(true,int,fluid_settings_setnum,(fluid_settings_t*, 
const char*, double)) \
+    MIX_LOADER_FUNCTION(true,int,fluid_settings_setstr,(fluid_settings_t*, 
const char*, const char *)) \
     MIX_LOADER_FUNCTION(true,int,fluid_settings_getnum,(fluid_settings_t*, 
const char*, double*)) \
     
MIX_LOADER_FUNCTION(true,int,fluid_sfloader_set_callbacks,(fluid_sfloader_t 
*,fluid_sfloader_callback_open_t,fluid_sfloader_callback_read_t,fluid_sfloader_callback_seek_t,fluid_sfloader_callback_tell_t,fluid_sfloader_callback_close_t))
 \
     MIX_LOADER_FUNCTION(true,void,fluid_synth_add_sfloader,(fluid_synth_t *, 
fluid_sfloader_t *)) \
@@ -129,10 +130,16 @@
         }
     }
 
-    #ifdef SDL_PLATFORM_UNIX  // this happens to be where Ubuntu stores a 
usable soundfont, at least on my laptop. Try it if nothing else worked out.
-    if (!sfio) {
+    #ifdef SDL_PLATFORM_UNIX
+    if (!sfio) {  // this happens to be where Ubuntu stores a usable 
soundfont, at least on my laptop. Try it if nothing else worked out.
         sfio = SDL_IOFromFile("/usr/share/sounds/sf2/default-GM.sf2", "rb");
     }
+    if (!sfio) { // Fedora is storing it here.
+        sfio = SDL_IOFromFile("/usr/share/soundfonts/default.sf2", "rb");
+    }
+    if (!sfio) { // Fedora is _also_ storing it here. Both are symlinks to the 
same thing elsewhere, but try both in case one was an older path.
+        sfio = SDL_IOFromFile("/usr/share/sounds/sf2/default.sf2", "rb");
+    }
     #endif
 
     // !!! FIXME: should we fail if there's no soundfont? It's not going to 
generate sound without one, unless there's a system-provided one in some 
cases...?
@@ -253,6 +260,9 @@
         case SDL_PROPERTY_TYPE_FLOAT:
             fluidsynth.fluid_settings_setnum(tdata->settings, name, (double) 
SDL_GetFloatProperty(props, name, 0.0f));
             break;
+        case SDL_PROPERTY_TYPE_STRING:
+            fluidsynth.fluid_settings_setstr(tdata->settings, name, 
SDL_GetStringProperty(props, name, ""));
+            break;
         default: break;  // oh well.
     }
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/SDL3_mixer-3.2.2/src/decoder_opus.c 
new/SDL3_mixer-3.2.4/src/decoder_opus.c
--- old/SDL3_mixer-3.2.2/src/decoder_opus.c     2026-03-10 22:58:33.000000000 
+0100
+++ new/SDL3_mixer-3.2.4/src/decoder_opus.c     2026-05-17 01:17:05.000000000 
+0200
@@ -179,7 +179,8 @@
     opus.op_raw_seek(of, 0);  // !!! FIXME: it's not clear if this seek is 
necessary, but https://stackoverflow.com/a/72482773 suggests it might be, at 
least on older libvorbisfile releases...
     const Sint64 full_length = (Sint64) opus.op_pcm_total(of, -1);
 
-    if (adata->loop.end > full_length) {
+    const bool ignore_loops = SDL_GetBooleanProperty(props, 
MIX_PROP_AUDIO_LOAD_IGNORE_LOOPS_BOOLEAN, false);
+    if (ignore_loops || (adata->loop.end > full_length)) {
         adata->loop.active = false;
     }
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/SDL3_mixer-3.2.2/src/decoder_voc.c 
new/SDL3_mixer-3.2.4/src/decoder_voc.c
--- old/SDL3_mixer-3.2.2/src/decoder_voc.c      2026-03-10 22:58:33.000000000 
+0100
+++ new/SDL3_mixer-3.2.4/src/decoder_voc.c      2026-05-17 01:17:05.000000000 
+0200
@@ -106,6 +106,7 @@
 // this runs during VOC_audio_init to walk the whole .VOC for metadata and 
sanity checks.
 static bool ParseVocFile(SDL_IOStream *io, VOC_AudioData *adata, 
SDL_PropertiesID props, SDL_AudioSpec *spec, Sint64 *duration_frames)
 {
+    const bool ignore_loops = SDL_GetBooleanProperty(props, 
MIX_PROP_AUDIO_LOAD_IGNORE_LOOPS_BOOLEAN, false);
     Sint64 total_frames = 0;
     VOC_Block *loop_start = NULL;
     int loop_start_loop_count = 0;
@@ -255,6 +256,10 @@
             }
 
             case VOC_LOOP: {
+                if (ignore_loops) {
+                    break;  // technically this can make a file with bogus 
loops load where it wouldn't otherwise, but good enough.
+                }
+
                 Uint16 iterations = 0;
 
                 // !!! FIXME: can LOOP/LOOPEND sections nest? 
https://moddingwiki.shikadi.net/wiki/VOC_Format suggests no, saying LOOPEND 
goes back to _most recent_ LOOP start.
@@ -286,6 +291,10 @@
             }
 
             case VOC_LOOPEND: {
+                if (ignore_loops) {
+                    break;  // technically this can make a file with bogus 
loops load where it wouldn't otherwise, but good enough.
+                }
+
                 if (!loop_start) {
                     return SDL_SetError("VOC has a LOOPEND without a matching 
LOOP");
                 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/SDL3_mixer-3.2.2/src/decoder_vorbis.c 
new/SDL3_mixer-3.2.4/src/decoder_vorbis.c
--- old/SDL3_mixer-3.2.2/src/decoder_vorbis.c   2026-03-10 22:58:33.000000000 
+0100
+++ new/SDL3_mixer-3.2.4/src/decoder_vorbis.c   2026-05-19 16:46:25.000000000 
+0200
@@ -159,8 +159,20 @@
 
 static bool SDLCALL VORBIS_init_audio(SDL_IOStream *io, SDL_AudioSpec *spec, 
SDL_PropertiesID props, Sint64 *duration_frames, void **audio_userdata)
 {
+    Uint8 buffer[17];
+    if (SDL_ReadIO(io, buffer, sizeof (buffer)) != sizeof (buffer)) {
+        return false;
+    } else if (SDL_memcmp(buffer, "Extended Module: ", 17) == 0) {  // this is 
an XM file that _might_ be OXM and we would incorrectly claim it. Drop out now.
+        return SDL_SetError("Not an Ogg Vorbis audio stream");
+    }
+
+    // Go back and let ov_test_callbacks() take a run at it, too.
+    if (SDL_SeekIO(io, 0, SDL_IO_SEEK_SET) < 0) {
+        return false;
+    }
+
     // just load the bare minimum from the IOStream to verify it's an Ogg 
Vorbis file.
-    // !!! FIXME: is ov_open_callbacks going to return more slowly if this 
isn't an Opus file? It's probably better to just do the full open.
+    // !!! FIXME: is ov_open_callbacks going to return more slowly if this 
isn't a Vorbis file? It's probably better to just do the full open.
     OggVorbis_File vf;
     if (vorbis.ov_test_callbacks(io, &vf, NULL, 0, VORBIS_IoCallbacks) < 0) {
         return SDL_SetError("Not an Ogg Vorbis audio stream");
@@ -205,7 +217,8 @@
     vorbis.ov_raw_seek(&vf, 0);  // !!! FIXME: it's not clear if this seek is 
necessary, but https://stackoverflow.com/a/72482773 suggests it might be, at 
least on older libvorbisfile releases...
     const Sint64 full_length = (Sint64) vorbis.ov_pcm_total(&vf, -1);
 
-    if (adata->loop.end > full_length) {
+    const bool ignore_loops = SDL_GetBooleanProperty(props, 
MIX_PROP_AUDIO_LOAD_IGNORE_LOOPS_BOOLEAN, false);
+    if (ignore_loops || (adata->loop.end > full_length)) {
         adata->loop.active = false;
     }
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/SDL3_mixer-3.2.2/src/decoder_wav.c 
new/SDL3_mixer-3.2.4/src/decoder_wav.c
--- old/SDL3_mixer-3.2.2/src/decoder_wav.c      2026-03-10 22:58:33.000000000 
+0100
+++ new/SDL3_mixer-3.2.4/src/decoder_wav.c      2026-05-17 01:17:05.000000000 
+0200
@@ -1242,6 +1242,7 @@
 
 static bool WAV_init_audio_internal(WAV_AudioData *adata, SDL_IOStream *io, 
SDL_AudioSpec *spec, SDL_PropertiesID props)
 {
+    const bool ignore_loops = SDL_GetBooleanProperty(props, 
MIX_PROP_AUDIO_LOAD_IGNORE_LOOPS_BOOLEAN, false);
     Sint64 flen = SDL_GetIOSize(io);
     bool found_FMT = false;
     bool found_DATA = false;
@@ -1299,7 +1300,9 @@
             chunk_okay = ParseDATA(adata, io, chunk_length);
             break;
         case SMPL:
-            chunk_okay = ParseSMPL(adata, io, chunk_length);
+            if (!ignore_loops) {
+                chunk_okay = ParseSMPL(adata, io, chunk_length);
+            }
             break;
         case LIST:
             chunk_okay = ParseLIST(adata, io, props, chunk_length);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/SDL3_mixer-3.2.2/src/version.rc 
new/SDL3_mixer-3.2.4/src/version.rc
--- old/SDL3_mixer-3.2.2/src/version.rc 2026-05-12 00:31:34.000000000 +0200
+++ new/SDL3_mixer-3.2.4/src/version.rc 2026-06-03 01:56:16.000000000 +0200
@@ -9,8 +9,8 @@
 //
 
 VS_VERSION_INFO VERSIONINFO
- FILEVERSION 3,2,2,0
- PRODUCTVERSION 3,2,2,0
+ FILEVERSION 3,2,4,0
+ PRODUCTVERSION 3,2,4,0
  FILEFLAGSMASK 0x3fL
  FILEFLAGS 0x0L
  FILEOS 0x40004L
@@ -23,12 +23,12 @@
         BEGIN
             VALUE "CompanyName", "\0"
             VALUE "FileDescription", "SDL_mixer\0"
-            VALUE "FileVersion", "3, 2, 2, 0\0"
+            VALUE "FileVersion", "3, 2, 4, 0\0"
             VALUE "InternalName", "SDL_mixer\0"
             VALUE "LegalCopyright", "Copyright (C) 2026 Sam Lantinga\0"
             VALUE "OriginalFilename", "SDL3_mixer.dll\0"
             VALUE "ProductName", "Simple DirectMedia Layer\0"
-            VALUE "ProductVersion", "3, 2, 2, 0\0"
+            VALUE "ProductVersion", "3, 2, 4, 0\0"
         END
     END
     BLOCK "VarFileInfo"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/SDL3_mixer-3.2.2/test/testaudiodecoder.c 
new/SDL3_mixer-3.2.4/test/testaudiodecoder.c
--- old/SDL3_mixer-3.2.2/test/testaudiodecoder.c        2026-03-05 
14:54:35.000000000 +0100
+++ new/SDL3_mixer-3.2.4/test/testaudiodecoder.c        2026-06-02 
20:35:18.000000000 +0200
@@ -24,22 +24,20 @@
 #include <SDL3/SDL_main.h>
 #include "SDL3_mixer/SDL_mixer.h"
 
-static bool done = false;
+static SDL_AudioStream *stream = NULL;
+static SDL_AtomicInt done;  /* the device callback happens in another thread, 
so use an atomic int for this flag. */
 static SDL_AudioSpec spec;
 
 static void SDLCALL AudioDeviceCallback(void *userdata, SDL_AudioStream 
*stream, int additional_amount, int total_amount)
 {
     MIX_AudioDecoder *audiodecoder = (MIX_AudioDecoder *) userdata;
-    if (!additional_amount) {
-        return;
-    }
-
     Uint8 buffer[1024];
+
     while (additional_amount > 0) {
         const int needed = SDL_min((int)sizeof(buffer), additional_amount);
         const int br = MIX_DecodeAudio(audiodecoder, buffer, needed, &spec);
         if (br <= 0) {
-            done = true;
+            SDL_SetAtomicInt(&done, 1);
             break;
         }
 
@@ -74,7 +72,7 @@
         return SDL_APP_FAILURE;
     }
 
-    SDL_AudioStream *stream = 
SDL_OpenAudioDeviceStream(SDL_AUDIO_DEVICE_DEFAULT_PLAYBACK, NULL, 
AudioDeviceCallback, audiodecoder);
+    stream = SDL_OpenAudioDeviceStream(SDL_AUDIO_DEVICE_DEFAULT_PLAYBACK, 
NULL, AudioDeviceCallback, audiodecoder);
     if (!stream) {
         SDL_Log("Failed to open audio device: %s", SDL_GetError());
         return SDL_APP_FAILURE;
@@ -84,6 +82,8 @@
 
     SDL_ResumeAudioStreamDevice(stream);
 
+    SDL_SetAtomicInt(&done, 0);
+
     return SDL_APP_CONTINUE;
 }
 
@@ -97,12 +97,15 @@
 
 SDL_AppResult SDL_AppIterate(void *appstate)
 {
-    return done ? SDL_APP_SUCCESS : SDL_APP_CONTINUE;
+    return SDL_GetAtomicInt(&done) ? SDL_APP_SUCCESS : SDL_APP_CONTINUE;
 }
 
 void SDL_AppQuit(void *appstate, SDL_AppResult result)
 {
-    // SDL will clean up the audio device for us.
+    // SDL and MIX_Quit will normally clean up everything we used here, but
+    //  we need to make sure the callback doesn't fire while MIX_Quit is
+    //  destroying things, so we destroy the audio stream manually.
+    SDL_DestroyAudioStream(stream);
     MIX_Quit();    // SDL_mixer will clean up the audiodecoder.
 }
 


++++++ _scmsync.obsinfo ++++++
--- /var/tmp/diff_new_pack.HfEQgw/_old  2026-10-31 23:15:02.414559532 +0100
+++ /var/tmp/diff_new_pack.HfEQgw/_new  2026-10-31 23:15:02.420559780 +0100
@@ -1,5 +1,5 @@
-mtime: 1778577151
-commit: 446562d8d6efce73e6b6aa3d347c6a451e6951ddf9b04c5338be397b1bc2fb42
+mtime: 1793465846
+commit: 1697888247f83f951e49a730843df44dc07f58dfd8e848626d50efb42241500d
 url: https://src.opensuse.org/jengelh/SDL3_mixer
 revision: master
 

++++++ build.specials.obscpio ++++++

++++++ build.specials.obscpio ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/.gitignore new/.gitignore
--- old/.gitignore      1970-01-01 01:00:00.000000000 +0100
+++ new/.gitignore      2026-10-31 17:57:26.000000000 +0100
@@ -0,0 +1 @@
+.osc

Reply via email to