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-05-12 19:28:05
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/SDL3_mixer (Old)
 and      /work/SRC/openSUSE:Factory/.SDL3_mixer.new.1966 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "SDL3_mixer"

Tue May 12 19:28:05 2026 rev:2 rq:1352659 version:3.2.2

Changes:
--------
--- /work/SRC/openSUSE:Factory/SDL3_mixer/SDL3_mixer.changes    2026-03-16 
14:19:16.238121273 +0100
+++ /work/SRC/openSUSE:Factory/.SDL3_mixer.new.1966/SDL3_mixer.changes  
2026-05-12 19:30:49.905440351 +0200
@@ -1,0 +2,11 @@
+Tue May 12 07:37:54 UTC 2026 - Jan Engelhardt <[email protected]>
+
+- Update to release 3.2.2
+  * MIX_DestroyTrack may now be called from a mixer callback
+  * Fixed WAV decoding on big-endian systems
+- Deactive backends vorbis_stb, flac_drflac, mp3_drmp3,
+  since the formats are already supported via vorbis_vorbisfile,
+  flac_libflac, mp3_mpg123.
+- Switch from dlopen to have dependencies ELF-linked.
+
+-------------------------------------------------------------------

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

New:
----
  SDL3_mixer-3.2.2.tar.gz
  SDL3_mixer-3.2.2.tar.gz.sig
  _scmsync.obsinfo
  build.specials.obscpio

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

Other differences:
------------------
++++++ SDL3_mixer.spec ++++++
--- /var/tmp/diff_new_pack.92EFE7/_old  2026-05-12 19:30:50.697473177 +0200
+++ /var/tmp/diff_new_pack.92EFE7/_new  2026-05-12 19:30:50.701473343 +0200
@@ -1,7 +1,7 @@
 #
 # spec file for package SDL3_mixer
 #
-# Copyright (c) 2025 SUSE LLC
+# Copyright (c) 2026 SUSE LLC and contributors
 # Copyright (c) 2026 Andreas Stieger <[email protected]>
 #
 # All modifications and additions to the file contributed by third parties
@@ -19,7 +19,7 @@
 
 %define sover  0
 Name:           SDL3_mixer
-Version:        3.2.0
+Version:        3.2.2
 Release:        0
 Summary:        SDL3 sound mixer library
 License:        Zlib
@@ -77,7 +77,14 @@
        -DSDLMIXER_INSTALL_MAN:BOOL=ON \
        -DSDLMIXER_EXAMPLES_INSTALL:BOOL=OFF \
        -DSDLMIXER_TESTS_INSTALL:BOOL=OFF \
-       %{nil}
+       -DSDLMIXER_VORBIS_STB:BOOL=OFF \
+       -DSDLMIXER_VORBIS_VORBISFILE:BOOL=ON \
+       -DSDLMIXER_VORBIS_TREMOR:BOOL=OFF \
+       -DSDLMIXER_FLAC_LIBFLAC:BOOL=ON \
+       -DSDLMIXER_FLAC_DRFLAC:BOOL=OFF \
+       -DSDLMIXER_MP3_MPG123:BOOL=ON \
+       -DSDLMIXER_MP3_DRMP3:BOOL=OFF \
+       -DSDLMIXER_DEPS_SHARED:BOOL=OFF
 %cmake_build
 
 %install

++++++ SDL3_mixer-3.2.0.tar.gz -> SDL3_mixer-3.2.2.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/SDL3_mixer-3.2.0/.git-hash 
new/SDL3_mixer-3.2.2/.git-hash
--- old/SDL3_mixer-3.2.0/.git-hash      2026-03-09 15:18:57.000000000 +0100
+++ new/SDL3_mixer-3.2.2/.git-hash      2026-05-12 00:31:34.000000000 +0200
@@ -1 +1 @@
-cedfeef30e93db35eee6b25759117da63f8e5a4f
+a5e1890afc5115ffd16cefdbb4d50f74bf4970ce
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/SDL3_mixer-3.2.0/AGENTS.md 
new/SDL3_mixer-3.2.2/AGENTS.md
--- old/SDL3_mixer-3.2.0/AGENTS.md      1970-01-01 01:00:00.000000000 +0100
+++ new/SDL3_mixer-3.2.2/AGENTS.md      2026-05-11 03:30:35.000000000 +0200
@@ -0,0 +1,20 @@
+AI must not be used to generate code for contributions to this project.
+
+"AI" in this case means a Large Language Model ("LLM"), such as ChatGPT,
+Claude, Copilot, Grok, etc.
+
+AI-generated code is based upon sources of unknown origins and may not be
+compatible with the Zlib license, or may introduce conflicting license terms
+if they include code from other projects.
+
+AI can be used to identify issues with contributions to this project, but the
+solutions to those issues should be authored by humans.
+
+We have found that AI will frequently hallucinate issues that are not actually
+problems in practice, report incorrect information, and describe problems that
+are actually not issues at all. If AI identifies a problem with this codebase,
+please make sure you understand what it is saying and have independently
+confirmed that the issue exists before submitting a bug report or pull request.
+
+Any pull request to this project will ask you to confirm that you are the
+author and that you are contributing your changes under the Zlib license.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/SDL3_mixer-3.2.0/CLAUDE.md 
new/SDL3_mixer-3.2.2/CLAUDE.md
--- old/SDL3_mixer-3.2.0/CLAUDE.md      1970-01-01 01:00:00.000000000 +0100
+++ new/SDL3_mixer-3.2.2/CLAUDE.md      2026-05-11 03:30:35.000000000 +0200
@@ -0,0 +1,22 @@
+AI must not be used to generate code for contributions to this project.
+
+"AI" in this case means a Large Language Model ("LLM"), such as ChatGPT,
+Claude, Copilot, Grok, etc.
+
+AI-generated code is based upon sources of unknown origins and may not be
+compatible with the Zlib license, or may introduce conflicting license terms
+if they include code from other projects.
+
+AI can be used to identify issues with contributions to this project, but the
+solutions to those issues should be authored by humans.
+
+We have found that AI will frequently hallucinate issues that are not actually
+problems in practice, report incorrect information, and describe problems that
+are actually not issues at all. If AI identifies a problem with this codebase,
+please make sure you understand what it is saying and have independently
+confirmed that the issue exists before submitting a bug report or pull request.
+
+Any pull request to this project will ask you to confirm that you are the
+author and that you are contributing your changes under the Zlib license.
+
+
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/SDL3_mixer-3.2.0/CMakeLists.txt 
new/SDL3_mixer-3.2.2/CMakeLists.txt
--- old/SDL3_mixer-3.2.0/CMakeLists.txt 2026-03-09 15:18:57.000000000 +0100
+++ new/SDL3_mixer-3.2.2/CMakeLists.txt 2026-05-12 00:31:34.000000000 +0200
@@ -9,7 +9,7 @@
 # See docs/release_checklist.md
 set(MAJOR_VERSION 3)
 set(MINOR_VERSION 2)
-set(MICRO_VERSION 0)
+set(MICRO_VERSION 2)
 set(SDL_REQUIRED_VERSION 3.4.0)
 
 project(SDL3_mixer
@@ -724,6 +724,8 @@
     endif()
 endif()
 
+set(tgt_libxmp libxmp::xmp_shared)
+set(tgt_libxmplite libxmp-lite::xmp_lite_shared)
 list(APPEND SDLMIXER_BACKENDS MOD_XMP)
 set(SDLMIXER_MOD_XMP_ENABLED FALSE)
 if(SDLMIXER_MOD_XMP)
@@ -756,8 +758,16 @@
             find_package(libxmp-lite ${required})
             if(libxmp-lite_FOUND)
                 set(SDLMIXER_MOD_XMP_ENABLED TRUE)
+                set(SDLMIXER_MOD_XMP_LITE_ENABLED TRUE)
                 message(STATUS "Using system libxmp-lite")
-                set(tgt_xmp libxmp-lite::libxmp-lite)
+                if(TARGET libxmp-lite::xmp_lite_shared)
+                  set(tgt_xmp libxmp-lite::xmp_lite_shared)
+                elseif(TARGET libxmp-lite::xmp_lite_static)
+                  set(tgt_xmp libxmp-lite::xmp_lite_static)
+                else()
+                  set(tgt_xmp libxmp-lite::libxmp-lite)
+                endif()
+                set(tgt_libxmplite ${tgt_xmp})
                 set(xmp_name libxmp-lite)
                 if(NOT SDLMIXER_MOD_XMP_SHARED)
                     list(APPEND PC_REQUIRES libxmp-lite)
@@ -780,6 +790,7 @@
                 else()
                   set(tgt_xmp libxmp::libxmp)
                 endif()
+                set(tgt_libxmp ${tgt_xmp})
                 set(xmp_name libxmp)
                 if(NOT SDLMIXER_MOD_XMP_SHARED)
                     list(APPEND PC_REQUIRES libxmp)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/SDL3_mixer-3.2.0/REVISION.txt 
new/SDL3_mixer-3.2.2/REVISION.txt
--- old/SDL3_mixer-3.2.0/REVISION.txt   2026-03-09 15:18:57.000000000 +0100
+++ new/SDL3_mixer-3.2.2/REVISION.txt   2026-05-12 00:31:34.000000000 +0200
@@ -1 +1 @@
-release-3.2.0-0-gcedfeef3
+release-3.2.2-0-ga5e1890a
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/SDL3_mixer-3.2.0/VisualC/SDL_mixer.vcxproj 
new/SDL3_mixer-3.2.2/VisualC/SDL_mixer.vcxproj
--- old/SDL3_mixer-3.2.0/VisualC/SDL_mixer.vcxproj      2025-09-22 
00:15:55.000000000 +0200
+++ new/SDL3_mixer-3.2.2/VisualC/SDL_mixer.vcxproj      2026-04-25 
16:38:33.000000000 +0200
@@ -237,171 +237,171 @@
   <ItemGroup>
     <CustomBuild Include="external\optional\x64\libxmp.dll">
       <FileType>Document</FileType>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">copy 
"%(FullPath)" $(SolutionDir)\$(Platform)\$(Configuration)\</Command>
+      <Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">copy 
"%(FullPath)" "$(SolutionDir)\$(Platform)\$(Configuration)\"</Command>
       <Message Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Copying 
%(Filename)%(Extension)</Message>
       <Outputs 
Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(SolutionDir)\$(Platform)\$(Configuration)\%(Filename)%(Extension)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">copy 
"%(FullPath)" $(SolutionDir)\$(Platform)\$(Configuration)\</Command>
+      <Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">copy 
"%(FullPath)" "$(SolutionDir)\$(Platform)\$(Configuration)\"</Command>
       <Message 
Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Copying 
%(Filename)%(Extension)</Message>
       <Outputs 
Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(SolutionDir)\$(Platform)\$(Configuration)\%(Filename)%(Extension)</Outputs>
     </CustomBuild>
     <CustomBuild Include="external\optional\x64\libogg-0.dll">
       <FileType>Document</FileType>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">copy 
"%(FullPath)" $(SolutionDir)\$(Platform)\$(Configuration)\</Command>
+      <Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">copy 
"%(FullPath)" "$(SolutionDir)\$(Platform)\$(Configuration)\"</Command>
       <Message Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Copying 
%(Filename)%(Extension)</Message>
       <Outputs 
Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(SolutionDir)\$(Platform)\$(Configuration)\%(Filename)%(Extension)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">copy 
"%(FullPath)" $(SolutionDir)\$(Platform)\$(Configuration)\</Command>
+      <Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">copy 
"%(FullPath)" "$(SolutionDir)\$(Platform)\$(Configuration)\"</Command>
       <Message 
Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Copying 
%(Filename)%(Extension)</Message>
       <Outputs 
Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(SolutionDir)\$(Platform)\$(Configuration)\%(Filename)%(Extension)</Outputs>
     </CustomBuild>
     <CustomBuild Include="external\optional\x64\libopus-0.dll">
       <FileType>Document</FileType>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">copy 
"%(FullPath)" $(SolutionDir)\$(Platform)\$(Configuration)\</Command>
+      <Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">copy 
"%(FullPath)" "$(SolutionDir)\$(Platform)\$(Configuration)\"</Command>
       <Message Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Copying 
%(Filename)%(Extension)</Message>
       <Outputs 
Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(SolutionDir)\$(Platform)\$(Configuration)\%(Filename)%(Extension)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">copy 
"%(FullPath)" $(SolutionDir)\$(Platform)\$(Configuration)\</Command>
+      <Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">copy 
"%(FullPath)" "$(SolutionDir)\$(Platform)\$(Configuration)\"</Command>
       <Message 
Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Copying 
%(Filename)%(Extension)</Message>
       <Outputs 
Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(SolutionDir)\$(Platform)\$(Configuration)\%(Filename)%(Extension)</Outputs>
     </CustomBuild>
     <CustomBuild Include="external\optional\x64\libopusfile-0.dll">
       <FileType>Document</FileType>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">copy 
"%(FullPath)" $(SolutionDir)\$(Platform)\$(Configuration)\</Command>
+      <Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">copy 
"%(FullPath)" "$(SolutionDir)\$(Platform)\$(Configuration)\"</Command>
       <Message Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Copying 
%(Filename)%(Extension)</Message>
       <Outputs 
Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(SolutionDir)\$(Platform)\$(Configuration)\%(Filename)%(Extension)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">copy 
"%(FullPath)" $(SolutionDir)\$(Platform)\$(Configuration)\</Command>
+      <Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">copy 
"%(FullPath)" "$(SolutionDir)\$(Platform)\$(Configuration)\"</Command>
       <Message 
Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Copying 
%(Filename)%(Extension)</Message>
       <Outputs 
Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(SolutionDir)\$(Platform)\$(Configuration)\%(Filename)%(Extension)</Outputs>
     </CustomBuild>
     <CustomBuild Include="external\optional\x64\libwavpack-1.dll">
       <FileType>Document</FileType>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">copy 
"%(FullPath)" $(SolutionDir)\$(Platform)\$(Configuration)\</Command>
+      <Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">copy 
"%(FullPath)" "$(SolutionDir)\$(Platform)\$(Configuration)\"</Command>
       <Message Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Copying 
%(Filename)%(Extension)</Message>
       <Outputs 
Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(SolutionDir)\$(Platform)\$(Configuration)\%(Filename)%(Extension)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">copy 
"%(FullPath)" $(SolutionDir)\$(Platform)\$(Configuration)\</Command>
+      <Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">copy 
"%(FullPath)" "$(SolutionDir)\$(Platform)\$(Configuration)\"</Command>
       <Message 
Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Copying 
%(Filename)%(Extension)</Message>
       <Outputs 
Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(SolutionDir)\$(Platform)\$(Configuration)\%(Filename)%(Extension)</Outputs>
     </CustomBuild>
     <CustomBuild Include="external\optional\x64\LICENSE.xmp.txt">
-      <Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">copy 
"%(FullPath)" $(SolutionDir)\$(Platform)\$(Configuration)\</Command>
+      <Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">copy 
"%(FullPath)" "$(SolutionDir)\$(Platform)\$(Configuration)\"</Command>
       <Message Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Copying 
%(Filename)%(Extension)</Message>
       <Outputs 
Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(SolutionDir)\$(Platform)\$(Configuration)\%(Filename)%(Extension)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">copy 
"%(FullPath)" $(SolutionDir)\$(Platform)\$(Configuration)\</Command>
+      <Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">copy 
"%(FullPath)" "$(SolutionDir)\$(Platform)\$(Configuration)\"</Command>
       <Message 
Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Copying 
%(Filename)%(Extension)</Message>
       <Outputs 
Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(SolutionDir)\$(Platform)\$(Configuration)\%(Filename)%(Extension)</Outputs>
     </CustomBuild>
     <CustomBuild Include="external\optional\x64\LICENSE.ogg-vorbis.txt">
-      <Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">copy 
"%(FullPath)" $(SolutionDir)\$(Platform)\$(Configuration)\</Command>
+      <Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">copy 
"%(FullPath)" "$(SolutionDir)\$(Platform)\$(Configuration)\"</Command>
       <Message Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Copying 
%(Filename)%(Extension)</Message>
       <Outputs 
Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(SolutionDir)\$(Platform)\$(Configuration)\%(Filename)%(Extension)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">copy 
"%(FullPath)" $(SolutionDir)\$(Platform)\$(Configuration)\</Command>
+      <Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">copy 
"%(FullPath)" "$(SolutionDir)\$(Platform)\$(Configuration)\"</Command>
       <Message 
Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Copying 
%(Filename)%(Extension)</Message>
       <Outputs 
Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(SolutionDir)\$(Platform)\$(Configuration)\%(Filename)%(Extension)</Outputs>
     </CustomBuild>
     <CustomBuild Include="external\optional\x64\LICENSE.opus.txt">
-      <Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">copy 
"%(FullPath)" $(SolutionDir)\$(Platform)\$(Configuration)\</Command>
+      <Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">copy 
"%(FullPath)" "$(SolutionDir)\$(Platform)\$(Configuration)\"</Command>
       <Message Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Copying 
%(Filename)%(Extension)</Message>
       <Outputs 
Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(SolutionDir)\$(Platform)\$(Configuration)\%(Filename)%(Extension)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">copy 
"%(FullPath)" $(SolutionDir)\$(Platform)\$(Configuration)\</Command>
+      <Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">copy 
"%(FullPath)" "$(SolutionDir)\$(Platform)\$(Configuration)\"</Command>
       <Message 
Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Copying 
%(Filename)%(Extension)</Message>
       <Outputs 
Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(SolutionDir)\$(Platform)\$(Configuration)\%(Filename)%(Extension)</Outputs>
     </CustomBuild>
     <CustomBuild Include="external\optional\x64\LICENSE.opusfile.txt">
-      <Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">copy 
"%(FullPath)" $(SolutionDir)\$(Platform)\$(Configuration)\</Command>
+      <Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">copy 
"%(FullPath)" "$(SolutionDir)\$(Platform)\$(Configuration)\"</Command>
       <Message Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Copying 
%(Filename)%(Extension)</Message>
       <Outputs 
Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(SolutionDir)\$(Platform)\$(Configuration)\%(Filename)%(Extension)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">copy 
"%(FullPath)" $(SolutionDir)\$(Platform)\$(Configuration)\</Command>
+      <Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">copy 
"%(FullPath)" "$(SolutionDir)\$(Platform)\$(Configuration)\"</Command>
       <Message 
Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Copying 
%(Filename)%(Extension)</Message>
       <Outputs 
Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(SolutionDir)\$(Platform)\$(Configuration)\%(Filename)%(Extension)</Outputs>
     </CustomBuild>
     <CustomBuild Include="external\optional\x64\LICENSE.wavpack.txt">
-      <Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">copy 
"%(FullPath)" $(SolutionDir)\$(Platform)\$(Configuration)\</Command>
+      <Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">copy 
"%(FullPath)" "$(SolutionDir)\$(Platform)\$(Configuration)\"</Command>
       <Message Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Copying 
%(Filename)%(Extension)</Message>
       <Outputs 
Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(SolutionDir)\$(Platform)\$(Configuration)\%(Filename)%(Extension)</Outputs>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">copy 
"%(FullPath)" $(SolutionDir)\$(Platform)\$(Configuration)\</Command>
+      <Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">copy 
"%(FullPath)" "$(SolutionDir)\$(Platform)\$(Configuration)\"</Command>
       <Message 
Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Copying 
%(Filename)%(Extension)</Message>
       <Outputs 
Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(SolutionDir)\$(Platform)\$(Configuration)\%(Filename)%(Extension)</Outputs>
     </CustomBuild>
     <CustomBuild Include="external\optional\x86\libxmp.dll">
       <FileType>Document</FileType>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">copy 
"%(FullPath)" $(SolutionDir)\$(Platform)\$(Configuration)\</Command>
+      <Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">copy 
"%(FullPath)" "$(SolutionDir)\$(Platform)\$(Configuration)\"</Command>
       <Message 
Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Copying 
%(Filename)%(Extension)</Message>
       <Outputs 
Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(SolutionDir)\$(Platform)\$(Configuration)\%(Filename)%(Extension)</Outputs>
-      <Command 
Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">copy "%(FullPath)" 
$(SolutionDir)\$(Platform)\$(Configuration)\</Command>
+      <Command 
Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">copy "%(FullPath)" 
"$(SolutionDir)\$(Platform)\$(Configuration)\"</Command>
       <Message 
Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Copying 
%(Filename)%(Extension)</Message>
       <Outputs 
Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(SolutionDir)\$(Platform)\$(Configuration)\%(Filename)%(Extension)</Outputs>
     </CustomBuild>
     <CustomBuild Include="external\optional\x86\libogg-0.dll">
       <FileType>Document</FileType>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">copy 
"%(FullPath)" $(SolutionDir)\$(Platform)\$(Configuration)\</Command>
+      <Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">copy 
"%(FullPath)" "$(SolutionDir)\$(Platform)\$(Configuration)\"</Command>
       <Message 
Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Copying 
%(Filename)%(Extension)</Message>
       <Outputs 
Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(SolutionDir)\$(Platform)\$(Configuration)\%(Filename)%(Extension)</Outputs>
-      <Command 
Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">copy "%(FullPath)" 
$(SolutionDir)\$(Platform)\$(Configuration)\</Command>
+      <Command 
Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">copy "%(FullPath)" 
"$(SolutionDir)\$(Platform)\$(Configuration)\"</Command>
       <Message 
Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Copying 
%(Filename)%(Extension)</Message>
       <Outputs 
Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(SolutionDir)\$(Platform)\$(Configuration)\%(Filename)%(Extension)</Outputs>
     </CustomBuild>
     <CustomBuild Include="external\optional\x86\libopus-0.dll">
       <FileType>Document</FileType>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">copy 
"%(FullPath)" $(SolutionDir)\$(Platform)\$(Configuration)\</Command>
+      <Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">copy 
"%(FullPath)" "$(SolutionDir)\$(Platform)\$(Configuration)\"</Command>
       <Message 
Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Copying 
%(Filename)%(Extension)</Message>
       <Outputs 
Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(SolutionDir)\$(Platform)\$(Configuration)\%(Filename)%(Extension)</Outputs>
-      <Command 
Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">copy "%(FullPath)" 
$(SolutionDir)\$(Platform)\$(Configuration)\</Command>
+      <Command 
Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">copy "%(FullPath)" 
"$(SolutionDir)\$(Platform)\$(Configuration)\"</Command>
       <Message 
Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Copying 
%(Filename)%(Extension)</Message>
       <Outputs 
Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(SolutionDir)\$(Platform)\$(Configuration)\%(Filename)%(Extension)</Outputs>
     </CustomBuild>
     <CustomBuild Include="external\optional\x86\libopusfile-0.dll">
       <FileType>Document</FileType>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">copy 
"%(FullPath)" $(SolutionDir)\$(Platform)\$(Configuration)\</Command>
+      <Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">copy 
"%(FullPath)" "$(SolutionDir)\$(Platform)\$(Configuration)\"</Command>
       <Message 
Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Copying 
%(Filename)%(Extension)</Message>
       <Outputs 
Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(SolutionDir)\$(Platform)\$(Configuration)\%(Filename)%(Extension)</Outputs>
-      <Command 
Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">copy "%(FullPath)" 
$(SolutionDir)\$(Platform)\$(Configuration)\</Command>
+      <Command 
Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">copy "%(FullPath)" 
"$(SolutionDir)\$(Platform)\$(Configuration)\"</Command>
       <Message 
Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Copying 
%(Filename)%(Extension)</Message>
       <Outputs 
Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(SolutionDir)\$(Platform)\$(Configuration)\%(Filename)%(Extension)</Outputs>
     </CustomBuild>
     <CustomBuild Include="external\optional\x86\libwavpack-1.dll">
       <FileType>Document</FileType>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">copy 
"%(FullPath)" $(SolutionDir)\$(Platform)\$(Configuration)\</Command>
+      <Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">copy 
"%(FullPath)" "$(SolutionDir)\$(Platform)\$(Configuration)\"</Command>
       <Message 
Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Copying 
%(Filename)%(Extension)</Message>
       <Outputs 
Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(SolutionDir)\$(Platform)\$(Configuration)\%(Filename)%(Extension)</Outputs>
-      <Command 
Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">copy "%(FullPath)" 
$(SolutionDir)\$(Platform)\$(Configuration)\</Command>
+      <Command 
Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">copy "%(FullPath)" 
"$(SolutionDir)\$(Platform)\$(Configuration)\"</Command>
       <Message 
Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Copying 
%(Filename)%(Extension)</Message>
       <Outputs 
Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(SolutionDir)\$(Platform)\$(Configuration)\%(Filename)%(Extension)</Outputs>
     </CustomBuild>
     <CustomBuild Include="external\optional\x86\LICENSE.xmp.txt">
-      <Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">copy 
"%(FullPath)" $(SolutionDir)\$(Platform)\$(Configuration)\</Command>
+      <Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">copy 
"%(FullPath)" "$(SolutionDir)\$(Platform)\$(Configuration)\"</Command>
       <Message 
Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Copying 
%(Filename)%(Extension)</Message>
       <Outputs 
Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(SolutionDir)\$(Platform)\$(Configuration)\%(Filename)%(Extension)</Outputs>
-      <Command 
Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">copy "%(FullPath)" 
$(SolutionDir)\$(Platform)\$(Configuration)\</Command>
+      <Command 
Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">copy "%(FullPath)" 
"$(SolutionDir)\$(Platform)\$(Configuration)\"</Command>
       <Message 
Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Copying 
%(Filename)%(Extension)</Message>
       <Outputs 
Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(SolutionDir)\$(Platform)\$(Configuration)\%(Filename)%(Extension)</Outputs>
     </CustomBuild>
     <CustomBuild Include="external\optional\x86\LICENSE.ogg-vorbis.txt">
-      <Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">copy 
"%(FullPath)" $(SolutionDir)\$(Platform)\$(Configuration)\</Command>
+      <Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">copy 
"%(FullPath)" "$(SolutionDir)\$(Platform)\$(Configuration)\"</Command>
       <Message 
Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Copying 
%(Filename)%(Extension)</Message>
       <Outputs 
Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(SolutionDir)\$(Platform)\$(Configuration)\%(Filename)%(Extension)</Outputs>
-      <Command 
Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">copy "%(FullPath)" 
$(SolutionDir)\$(Platform)\$(Configuration)\</Command>
+      <Command 
Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">copy "%(FullPath)" 
"$(SolutionDir)\$(Platform)\$(Configuration)\"</Command>
       <Message 
Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Copying 
%(Filename)%(Extension)</Message>
       <Outputs 
Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(SolutionDir)\$(Platform)\$(Configuration)\%(Filename)%(Extension)</Outputs>
     </CustomBuild>
     <CustomBuild Include="external\optional\x86\LICENSE.opus.txt">
-      <Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">copy 
"%(FullPath)" $(SolutionDir)\$(Platform)\$(Configuration)\</Command>
+      <Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">copy 
"%(FullPath)" "$(SolutionDir)\$(Platform)\$(Configuration)\"</Command>
       <Message 
Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Copying 
%(Filename)%(Extension)</Message>
       <Outputs 
Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(SolutionDir)\$(Platform)\$(Configuration)\%(Filename)%(Extension)</Outputs>
-      <Command 
Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">copy "%(FullPath)" 
$(SolutionDir)\$(Platform)\$(Configuration)\</Command>
+      <Command 
Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">copy "%(FullPath)" 
"$(SolutionDir)\$(Platform)\$(Configuration)\"</Command>
       <Message 
Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Copying 
%(Filename)%(Extension)</Message>
       <Outputs 
Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(SolutionDir)\$(Platform)\$(Configuration)\%(Filename)%(Extension)</Outputs>
     </CustomBuild>
     <CustomBuild Include="external\optional\x86\LICENSE.opusfile.txt">
-      <Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">copy 
"%(FullPath)" $(SolutionDir)\$(Platform)\$(Configuration)\</Command>
+      <Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">copy 
"%(FullPath)" "$(SolutionDir)\$(Platform)\$(Configuration)\"</Command>
       <Message 
Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Copying 
%(Filename)%(Extension)</Message>
       <Outputs 
Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(SolutionDir)\$(Platform)\$(Configuration)\%(Filename)%(Extension)</Outputs>
-      <Command 
Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">copy "%(FullPath)" 
$(SolutionDir)\$(Platform)\$(Configuration)\</Command>
+      <Command 
Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">copy "%(FullPath)" 
"$(SolutionDir)\$(Platform)\$(Configuration)\"</Command>
       <Message 
Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Copying 
%(Filename)%(Extension)</Message>
       <Outputs 
Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(SolutionDir)\$(Platform)\$(Configuration)\%(Filename)%(Extension)</Outputs>
     </CustomBuild>
     <CustomBuild Include="external\optional\x86\LICENSE.wavpack.txt">
-      <Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">copy 
"%(FullPath)" $(SolutionDir)\$(Platform)\$(Configuration)\</Command>
+      <Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">copy 
"%(FullPath)" "$(SolutionDir)\$(Platform)\$(Configuration)\"</Command>
       <Message 
Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Copying 
%(Filename)%(Extension)</Message>
       <Outputs 
Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(SolutionDir)\$(Platform)\$(Configuration)\%(Filename)%(Extension)</Outputs>
-      <Command 
Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">copy "%(FullPath)" 
$(SolutionDir)\$(Platform)\$(Configuration)\</Command>
+      <Command 
Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">copy "%(FullPath)" 
"$(SolutionDir)\$(Platform)\$(Configuration)\"</Command>
       <Message 
Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Copying 
%(Filename)%(Extension)</Message>
       <Outputs 
Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(SolutionDir)\$(Platform)\$(Configuration)\%(Filename)%(Extension)</Outputs>
     </CustomBuild>
@@ -409,8 +409,8 @@
   <ItemGroup>
     <CustomBuild Include="external\optional\x64\libgme.dll">
       <FileType>Document</FileType>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">copy 
"%(FullPath)" $(SolutionDir)\$(Platform)\$(Configuration)\</Command>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">copy 
"%(FullPath)" $(SolutionDir)\$(Platform)\$(Configuration)\</Command>
+      <Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">copy 
"%(FullPath)" "$(SolutionDir)\$(Platform)\$(Configuration)\"</Command>
+      <Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">copy 
"%(FullPath)" "$(SolutionDir)\$(Platform)\$(Configuration)\"</Command>
       <Message Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Copying 
%(Filename)%(Extension)</Message>
       <Message 
Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Copying 
%(Filename)%(Extension)</Message>
       <Outputs 
Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(SolutionDir)\$(Platform)\$(Configuration)\%(Filename)%(Extension)</Outputs>
@@ -418,8 +418,8 @@
     </CustomBuild>
     <CustomBuild Include="external\optional\x86\libgme.dll">
       <FileType>Document</FileType>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">copy 
"%(FullPath)" $(SolutionDir)\$(Platform)\$(Configuration)\</Command>
-      <Command 
Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">copy "%(FullPath)" 
$(SolutionDir)\$(Platform)\$(Configuration)\</Command>
+      <Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">copy 
"%(FullPath)" "$(SolutionDir)\$(Platform)\$(Configuration)\"</Command>
+      <Command 
Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">copy "%(FullPath)" 
"$(SolutionDir)\$(Platform)\$(Configuration)\"</Command>
       <Message 
Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Copying 
%(Filename)%(Extension)</Message>
       <Message 
Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Copying 
%(Filename)%(Extension)</Message>
       <Outputs 
Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(SolutionDir)\$(Platform)\$(Configuration)\%(Filename)%(Extension)</Outputs>
@@ -428,16 +428,16 @@
   </ItemGroup>
   <ItemGroup>
     <CustomBuild Include="external\optional\x64\LICENSE.gme.txt">
-      <Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">copy 
"%(FullPath)" $(SolutionDir)\$(Platform)\$(Configuration)\</Command>
-      <Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">copy 
"%(FullPath)" $(SolutionDir)\$(Platform)\$(Configuration)\</Command>
+      <Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">copy 
"%(FullPath)" "$(SolutionDir)\$(Platform)\$(Configuration)\"</Command>
+      <Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">copy 
"%(FullPath)" "$(SolutionDir)\$(Platform)\$(Configuration)\"</Command>
       <Message Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Copying 
%(Filename)%(Extension)</Message>
       <Message 
Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Copying 
%(Filename)%(Extension)</Message>
       <Outputs 
Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(SolutionDir)\$(Platform)\$(Configuration)\%(Filename)%(Extension)</Outputs>
       <Outputs 
Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(SolutionDir)\$(Platform)\$(Configuration)\%(Filename)%(Extension)</Outputs>
     </CustomBuild>
     <CustomBuild Include="external\optional\x86\LICENSE.gme.txt">
-      <Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">copy 
"%(FullPath)" $(SolutionDir)\$(Platform)\$(Configuration)\</Command>
-      <Command 
Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">copy "%(FullPath)" 
$(SolutionDir)\$(Platform)\$(Configuration)\</Command>
+      <Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">copy 
"%(FullPath)" "$(SolutionDir)\$(Platform)\$(Configuration)\"</Command>
+      <Command 
Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">copy "%(FullPath)" 
"$(SolutionDir)\$(Platform)\$(Configuration)\"</Command>
       <Message 
Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Copying 
%(Filename)%(Extension)</Message>
       <Message 
Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Copying 
%(Filename)%(Extension)</Message>
       <Outputs 
Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(SolutionDir)\$(Platform)\$(Configuration)\%(Filename)%(Extension)</Outputs>
Binary files 
old/SDL3_mixer-3.2.0/VisualC/external/optional/x64/libopusfile-0.dll and 
new/SDL3_mixer-3.2.2/VisualC/external/optional/x64/libopusfile-0.dll differ
Binary files 
old/SDL3_mixer-3.2.0/VisualC/external/optional/x86/libopusfile-0.dll and 
new/SDL3_mixer-3.2.2/VisualC/external/optional/x86/libopusfile-0.dll differ
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/SDL3_mixer-3.2.0/Xcode/Info-Framework.plist 
new/SDL3_mixer-3.2.2/Xcode/Info-Framework.plist
--- old/SDL3_mixer-3.2.0/Xcode/Info-Framework.plist     2026-03-09 
15:18:57.000000000 +0100
+++ new/SDL3_mixer-3.2.2/Xcode/Info-Framework.plist     2026-05-12 
00:31:34.000000000 +0200
@@ -15,8 +15,8 @@
        <key>CFBundlePackageType</key>
        <string>FMWK</string>
        <key>CFBundleShortVersionString</key>
-       <string>3.2.0</string>
+       <string>3.2.2</string>
        <key>CFBundleVersion</key>
-       <string>3.2.0</string>
+       <string>3.2.2</string>
 </dict>
 </plist>
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/SDL3_mixer-3.2.0/Xcode/SDL_mixer.xcodeproj/project.pbxproj 
new/SDL3_mixer-3.2.2/Xcode/SDL_mixer.xcodeproj/project.pbxproj
--- old/SDL3_mixer-3.2.0/Xcode/SDL_mixer.xcodeproj/project.pbxproj      
2026-03-09 15:18:57.000000000 +0100
+++ new/SDL3_mixer-3.2.2/Xcode/SDL_mixer.xcodeproj/project.pbxproj      
2026-05-12 00:31:34.000000000 +0200
@@ -645,9 +645,10 @@
                                ALLOW_TARGET_PLATFORM_SPECIALIZATION = YES;
                                CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
                                CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+                               DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
                                DEPLOYMENT_POSTPROCESSING = YES;
                                DYLIB_COMPATIBILITY_VERSION = 201.0.0;
-                               DYLIB_CURRENT_VERSION = 201.0.0;
+                               DYLIB_CURRENT_VERSION = 201.2.0;
                                DYLIB_INSTALL_NAME_BASE = "@rpath";
                                "FRAMEWORK_SEARCH_PATHS[sdk=appletv*]" = 
"\"$(PROJECT_DIR)/iOS\"";
                                "FRAMEWORK_SEARCH_PATHS[sdk=iphone*]" = 
"\"$(PROJECT_DIR)/iOS\"";
@@ -677,7 +678,7 @@
                                        "@loader_path/Frameworks",
                                );
                                MACOSX_DEPLOYMENT_TARGET = 10.13;
-                               MARKETING_VERSION = 3.1.3;
+                               MARKETING_VERSION = 3.2.2;
                                PRODUCT_BUNDLE_IDENTIFIER = 
"org.libsdl.SDL3-mixer";
                                PRODUCT_NAME = SDL3_mixer;
                                SUPPORTED_PLATFORMS = "xrsimulator xros macosx 
iphonesimulator iphoneos appletvsimulator appletvos";
@@ -695,8 +696,9 @@
                                CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
                                CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
                                COPY_PHASE_STRIP = NO;
+                               DEBUG_INFORMATION_FORMAT = dwarf;
                                DYLIB_COMPATIBILITY_VERSION = 201.0.0;
-                               DYLIB_CURRENT_VERSION = 201.0.0;
+                               DYLIB_CURRENT_VERSION = 201.2.0;
                                DYLIB_INSTALL_NAME_BASE = "@rpath";
                                ENABLE_TESTABILITY = YES;
                                "FRAMEWORK_SEARCH_PATHS[sdk=appletv*]" = 
"\"$(PROJECT_DIR)/iOS\"";
@@ -727,7 +729,7 @@
                                        "@loader_path/Frameworks",
                                );
                                MACOSX_DEPLOYMENT_TARGET = 10.13;
-                               MARKETING_VERSION = 3.1.3;
+                               MARKETING_VERSION = 3.2.2;
                                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.0/cmake/SDL3_mixerConfig.cmake.in 
new/SDL3_mixer-3.2.2/cmake/SDL3_mixerConfig.cmake.in
--- old/SDL3_mixer-3.2.0/cmake/SDL3_mixerConfig.cmake.in        2026-01-21 
18:30:57.000000000 +0100
+++ new/SDL3_mixer-3.2.2/cmake/SDL3_mixerConfig.cmake.in        2026-05-06 
00:01:40.000000000 +0200
@@ -20,7 +20,7 @@
 
 set(SDLMIXER_MOD                   @SDLMIXER_MOD_ENABLED@)
 set(SDLMIXER_MOD_XMP               @SDLMIXER_MOD_XMP_ENABLED@)
-set(SDLMIXER_MOD_XMP_LITE          @SDLMIXER_MOD_XMP_ENABLED@)
+set(SDLMIXER_MOD_XMP_LITE          @SDLMIXER_MOD_XMP_LITE_ENABLED@)
 
 set(SDLMIXER_MP3                   @SDLMIXER_MP3_ENABLED@)
 set(SDLMIXER_MP3_DRMP3             @SDLMIXER_MP3_DRMP3_ENABLED@)
@@ -81,12 +81,16 @@
             endif()
         endif()
 
-        if(SDLMIXER_MOD_XMP AND NOT TARGET libxmp::libxmp)
-            find_dependency(libxmp)
-        endif()
-
-        if(SDLMIXER_MOD_XMP_LITE AND NOT TARGET libxmp-lite::libxmp-lite)
-            find_dependency(libxmp-lite)
+        if(SDLMIXER_MOD_XMP)
+            if(SDLMIXER_MOD_XMP_LITE)
+                if(NOT TARGET @tgt_libxmplite@)
+                    find_dependency(libxmp-lite)
+                endif()
+            else()
+                if(NOT TARGET @tgt_libxmp@)
+                    find_dependency(libxmp)
+                endif()
+            endif()
         endif()
 
         if(SDLMIXER_MP3_MPG123 AND NOT TARGET MPG123::mpg123)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/SDL3_mixer-3.2.0/docs/README-migration.md 
new/SDL3_mixer-3.2.2/docs/README-migration.md
--- old/SDL3_mixer-3.2.0/docs/README-migration.md       2026-03-05 
14:47:27.000000000 +0100
+++ new/SDL3_mixer-3.2.2/docs/README-migration.md       2026-03-10 
22:58:33.000000000 +0100
@@ -17,8 +17,8 @@
 There are a lot of things that don't have simple replacements that can be
 changed mechanically to migrate to SDL3_mixer. The new API is in many ways
 more powerful, but also much simpler. For example, there's no equivalent of
-Mix_ModMusicJumpToOrder(), because messing with the specifics
-of MOD files in the public API is both uncommon and generally pretty messy.
+Mix_GetNumTracks(), because messing with the specifics of MOD files in the
+public API is both uncommon and generally pretty messy.
 
 This migration guide will attempt to walk through the important details but
 it's possible that some things can't be done the same way. Feel free to open
@@ -34,10 +34,8 @@
   and packaged it as a separate library that can be used alongside SDL3_mixer,
   or without SDL_mixer at all: https://github.com/libsdl-org/SDL_native_midi
 
-- Mix_GetNumTracks(), Mix_StartTrack(), and Mix_ModMusicJumpToOrder() have
-  been removed; these were decoder-specific APIs.
-
-- Mix_SetSoundFonts(), Mix_GetSoundFonts(), Mix_EachSoundFont(),
+- Mix_GetNumTracks(), Mix_StartTrack(), Mix_ModMusicJumpToOrder(),
+  Mix_SetSoundFonts(), Mix_GetSoundFonts(), Mix_EachSoundFont(),
   Mix_SetTimidityCfg(), Mix_GetTimidityCfg(): these have been removed, but
   decoder-specific settings can be passed on in a generic way in SDL3_mixer,
   using SDL properties.
@@ -392,7 +390,7 @@
 - Mix_ResumeMusic => MIX_ResumeTrack
 - Mix_RewindMusic => MIX_SetTrackPlaybackPosition(track, 0)
 - Mix_PausedMusic => MIX_TrackPaused
-- Mix_ModMusicJumpToOrder => no equivalent in SDL3_mixer.
+- Mix_ModMusicJumpToOrder => MIX_PlayTrack with 
MIX_PROP_PLAY_START_ORDER_NUMBER property set.
 - Mix_StartTrack => no equivalent in SDL3_mixer.
 - Mix_GetNumTracks => no equivalent in SDL3_mixer.
 - Mix_SetMusicPosition => MIX_SetTrackPlaybackPosition
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/SDL3_mixer-3.2.0/include/SDL3_mixer/SDL_mixer.h 
new/SDL3_mixer-3.2.2/include/SDL3_mixer/SDL_mixer.h
--- old/SDL3_mixer-3.2.0/include/SDL3_mixer/SDL_mixer.h 2026-03-09 
15:18:57.000000000 +0100
+++ new/SDL3_mixer-3.2.2/include/SDL3_mixer/SDL_mixer.h 2026-05-12 
00:31:34.000000000 +0200
@@ -217,7 +217,7 @@
  *
  * \since This macro is available since SDL_mixer 3.0.0.
  */
-#define SDL_MIXER_MICRO_VERSION   0
+#define SDL_MIXER_MICRO_VERSION   2
 
 /**
  * This is the current version number macro of the SDL_mixer headers.
@@ -551,7 +551,7 @@
  * locked until the final matching unlock call.
  *
  * Do not lock the mixer for significant amounts of time, or it can cause
- * audio dropouts. Just do simply things quickly and unlock again.
+ * audio dropouts. Just do simple things quickly and unlock again.
  *
  * Locking a NULL mixer is a safe no-op.
  *
@@ -1115,7 +1115,10 @@
  * MIX_SetTrackStoppedCallback(), it will _not_ be called.
  *
  * If the mixer is currently mixing in another thread, this will block until
- * it finishes.
+ * it finishes. Destroying a track from the mixer thread itself (during a
+ * callback) will cause it to be destroyed as soon as this iteration of the
+ * mixer thread is not using it; in this scenario, destroying a track and then
+ * making futher changes to it is considered undefined behavior.
  *
  * Destroying a NULL MIX_Track is a legal no-op.
  *
@@ -1885,6 +1888,14 @@
  *   possible. Note that a track is not consider exhausted until all its loops
  *   and appended silence have been mixed (and also, that loops don't mean
  *   anything when the input is an AudioStream). Default true.
+ * - `MIX_PROP_PLAY_START_ORDER_NUMBER`: This is a special-case property that
+ *   most apps can ignore. For mod file formats, start mixing from a specific
+ *   "order" index instead of the start of the file. A value < 0 will cause
+ *   this property to be ignored. If the decoder doesn't support this
+ *   property, it will also be ignored. If this property is _not_ ignored, the
+ *   MIX_PROP_PLAY_START_FRAME_NUMBER and
+ *   MIX_PROP_PLAY_START_MILLISECOND_NUMBER properties will be ignored
+ *   instead. Default -1. Since SDL_mixer 3.2.2.
  *
  * If this function fails, mixing of this track will not start (or restart, if
  * it was already started).
@@ -1910,6 +1921,7 @@
 #define MIX_PROP_PLAY_MAX_MILLISECONDS_NUMBER "SDL_mixer.play.max_milliseconds"
 #define MIX_PROP_PLAY_START_FRAME_NUMBER "SDL_mixer.play.start_frame"
 #define MIX_PROP_PLAY_START_MILLISECOND_NUMBER 
"SDL_mixer.play.start_millisecond"
+#define MIX_PROP_PLAY_START_ORDER_NUMBER "SDL_mixer.play.start_order"
 #define MIX_PROP_PLAY_LOOP_START_FRAME_NUMBER "SDL_mixer.play.loop_start_frame"
 #define MIX_PROP_PLAY_LOOP_START_MILLISECOND_NUMBER 
"SDL_mixer.play.loop_start_millisecond"
 #define MIX_PROP_PLAY_FADE_IN_FRAMES_NUMBER "SDL_mixer.play.fade_in_frames"
@@ -2037,8 +2049,12 @@
  *
  * Once a track has completed any fadeout and come to a stop, it will call its
  * MIX_TrackStoppedCallback, if any. It is legal to assign the track a new
- * input and/or restart it during this callback. This function does not
- * prevent new play requests from being made.
+ * input and/or restart it during this callback.
+ *
+ * This function does not prevent new play requests from being made; it’s
+ * legal to use this function to begin fading all playing tracks but then
+ * start other tracks playing normally while those fade-outs are still in
+ * progress.
  *
  * \param mixer the mixer on which to stop all tracks.
  * \param fade_out_ms the number of milliseconds to spend fading out to
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/SDL3_mixer-3.2.0/src/SDL_mixer.c 
new/SDL3_mixer-3.2.2/src/SDL_mixer.c
--- old/SDL3_mixer-3.2.0/src/SDL_mixer.c        2026-03-05 14:47:27.000000000 
+0100
+++ new/SDL3_mixer-3.2.2/src/SDL_mixer.c        2026-04-16 20:28:48.000000000 
+0200
@@ -575,6 +575,9 @@
         MIX_Track *next_track = NULL;
         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;
+
             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);
             if (br > 0) {
@@ -606,6 +609,11 @@
                         break;
                 }
             }
+
+            track->currently_mixing = false;
+            if (track->destroy_requested) {  // callback asked to destroy the 
track while we were still using it.
+                MIX_DestroyTrack(track);  // actually kill it now.
+            }
         }
 
         if (group_bytes > mixer->actual_mixed_bytes) {
@@ -1503,6 +1511,16 @@
     MIX_Mixer *mixer = track->mixer;
 
     LockMixer(mixer);
+
+    // 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) {
+        track->destroy_requested = true;
+        UnlockMixer(mixer);
+        return;
+    }
+
     if (track->prev) {
         track->prev->next = track->next;
     } else {
@@ -2242,6 +2260,7 @@
     Sint64 loop_start = 0;
     Sint64 fade_in = 0;
     Sint64 append_silence_frames = 0;
+    int start_order = -1;
     float fade_start_gain = 0.0f;
     bool halt_when_exhausted = true;
 
@@ -2255,6 +2274,7 @@
         fade_start_gain = SDL_GetFloatProperty(options, 
MIX_PROP_PLAY_FADE_IN_START_GAIN_FLOAT, fade_start_gain);
         append_silence_frames = GetTrackOptionFramesOrTicks(track, options, 
MIX_PROP_PLAY_APPEND_SILENCE_FRAMES_NUMBER, 
MIX_PROP_PLAY_APPEND_SILENCE_MILLISECONDS_NUMBER, append_silence_frames);
         halt_when_exhausted = SDL_GetBooleanProperty(options, 
MIX_PROP_PLAY_HALT_WHEN_EXHAUSTED_BOOLEAN, halt_when_exhausted);
+        start_order = (int) SDL_GetNumberProperty(options, 
MIX_PROP_PLAY_START_ORDER_NUMBER, start_order);
 
         if (start_pos < 0) {
             start_pos = 0;
@@ -2271,7 +2291,14 @@
         fade_start_gain = SDL_clamp(fade_start_gain, 0.0f, 1.0f);
     }
 
-    if (track->input_audio && 
(!track->input_audio->decoder->seek(track->decoder_userdata, start_pos))) {
+    if ((start_order >= 0) && (!track->input_audio || 
!track->input_audio->decoder->jump_to_order)) {
+        start_order = -1;  // ignore this option, it doesn't mean anything on 
this decoder.
+    }
+
+    if ((start_order >= 0) && 
!track->input_audio->decoder->jump_to_order(track->decoder_userdata, 
start_order)) {
+        UnlockTrack(track);
+        return false;
+    } else if (track->input_audio && 
(!track->input_audio->decoder->seek(track->decoder_userdata, start_pos))) {
         UnlockTrack(track);
         return false;
     } else if (!track->input_audio && (start_pos != 0)) {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/SDL3_mixer-3.2.0/src/SDL_mixer_internal.h 
new/SDL3_mixer-3.2.2/src/SDL_mixer_internal.h
--- old/SDL3_mixer-3.2.0/src/SDL_mixer_internal.h       2026-03-05 
06:06:54.000000000 +0100
+++ new/SDL3_mixer-3.2.2/src/SDL_mixer_internal.h       2026-04-16 
20:28:48.000000000 +0200
@@ -105,6 +105,7 @@
     bool (SDLCALL *init_track)(void *audio_userdata, SDL_IOStream *io, const 
SDL_AudioSpec *spec, SDL_PropertiesID props, void **track_userdata);  // init 
decoder instance data for a single track.
     bool (SDLCALL *decode)(void *track_userdata, SDL_AudioStream *stream);
     bool (SDLCALL *seek)(void *track_userdata, Uint64 frame);
+    bool (SDLCALL *jump_to_order)(void *track_userdata, int order);
     void (SDLCALL *quit_track)(void *track_userdata);
     void (SDLCALL *quit_audio)(void *audio_userdata);
     void (SDLCALL *quit)(void);   // deinitialize the decoder (unload external 
libraries, etc).
@@ -147,6 +148,8 @@
     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 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.
     SDL_AudioStream *input_stream;  // used for both MIX_SetTrackAudio and 
MIX_SetTrackAudioStream. Maybe not owned by SDL_mixer!
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/SDL3_mixer-3.2.0/src/decoder_aiff.c 
new/SDL3_mixer-3.2.2/src/decoder_aiff.c
--- old/SDL3_mixer-3.2.0/src/decoder_aiff.c     2026-01-01 20:20:48.000000000 
+0100
+++ new/SDL3_mixer-3.2.2/src/decoder_aiff.c     2026-03-10 22:58:33.000000000 
+0100
@@ -381,6 +381,7 @@
     adata->framesize = channels * (samplesize / 8);
     adata->stop = adata->start + channels * numsamples * (samplesize / 8);
     adata->fetch = FetchPCM;
+    adata->num_pcm_frames = (Sint64) numsamples;
 
     // Decode the audio data format
     spec->freq = (int)frequency;
@@ -499,7 +500,6 @@
         return false;
     }
 
-    adata->num_pcm_frames = MIX_DURATION_UNKNOWN;  // !!! FIXME: 
AIFF_init_audio_internal needs to set this.
     const bool rc = AIFF_init_audio_internal(adata, io, spec, props);
     if (!rc) {
         SDL_free(adata);
@@ -581,6 +581,7 @@
     AIFF_init_track,
     AIFF_decode,
     AIFF_seek,
+    NULL,  // jump_to_order
     AIFF_quit_track,
     AIFF_quit_audio,
     NULL  // quit
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/SDL3_mixer-3.2.0/src/decoder_au.c 
new/SDL3_mixer-3.2.2/src/decoder_au.c
--- old/SDL3_mixer-3.2.0/src/decoder_au.c       2026-01-01 20:20:48.000000000 
+0100
+++ new/SDL3_mixer-3.2.2/src/decoder_au.c       2026-03-10 22:58:33.000000000 
+0100
@@ -269,6 +269,7 @@
     AU_init_track,
     AU_decode,
     AU_seek,
+    NULL,  // jump_to_order
     AU_quit_track,
     AU_quit_audio,
     NULL  // quit
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/SDL3_mixer-3.2.0/src/decoder_drflac.c 
new/SDL3_mixer-3.2.2/src/decoder_drflac.c
--- old/SDL3_mixer-3.2.0/src/decoder_drflac.c   2026-02-28 17:44:53.000000000 
+0100
+++ new/SDL3_mixer-3.2.2/src/decoder_drflac.c   2026-03-10 22:58:33.000000000 
+0100
@@ -331,6 +331,7 @@
     DRFLAC_init_track,
     DRFLAC_decode,
     DRFLAC_seek,
+    NULL,  // jump_to_order
     DRFLAC_quit_track,
     DRFLAC_quit_audio,
     NULL  // quit
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/SDL3_mixer-3.2.0/src/decoder_drmp3.c 
new/SDL3_mixer-3.2.2/src/decoder_drmp3.c
--- old/SDL3_mixer-3.2.0/src/decoder_drmp3.c    2026-01-01 20:20:48.000000000 
+0100
+++ new/SDL3_mixer-3.2.2/src/decoder_drmp3.c    2026-03-10 22:58:33.000000000 
+0100
@@ -195,6 +195,7 @@
     DRMP3_init_track,
     DRMP3_decode,
     DRMP3_seek,
+    NULL,  // jump_to_order
     DRMP3_quit_track,
     DRMP3_quit_audio,
     NULL  // quit
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/SDL3_mixer-3.2.0/src/decoder_flac.c 
new/SDL3_mixer-3.2.2/src/decoder_flac.c
--- old/SDL3_mixer-3.2.0/src/decoder_flac.c     2026-01-08 23:45:55.000000000 
+0100
+++ new/SDL3_mixer-3.2.2/src/decoder_flac.c     2026-03-10 22:58:33.000000000 
+0100
@@ -507,6 +507,7 @@
     FLAC_init_track,
     FLAC_decode,
     FLAC_seek,
+    NULL,  // jump_to_order
     FLAC_quit_track,
     FLAC_quit_audio,
     FLAC_quit
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/SDL3_mixer-3.2.0/src/decoder_fluidsynth.c 
new/SDL3_mixer-3.2.2/src/decoder_fluidsynth.c
--- old/SDL3_mixer-3.2.0/src/decoder_fluidsynth.c       2026-02-28 
17:44:53.000000000 +0100
+++ new/SDL3_mixer-3.2.2/src/decoder_fluidsynth.c       2026-03-10 
22:58:33.000000000 +0100
@@ -451,6 +451,7 @@
     FLUIDSYNTH_init_track,
     FLUIDSYNTH_decode,
     FLUIDSYNTH_seek,
+    NULL,  // jump_to_order
     FLUIDSYNTH_quit_track,
     FLUIDSYNTH_quit_audio,
     FLUIDSYNTH_quit
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/SDL3_mixer-3.2.0/src/decoder_gme.c 
new/SDL3_mixer-3.2.2/src/decoder_gme.c
--- old/SDL3_mixer-3.2.0/src/decoder_gme.c      2026-02-28 17:44:53.000000000 
+0100
+++ new/SDL3_mixer-3.2.2/src/decoder_gme.c      2026-03-10 22:58:33.000000000 
+0100
@@ -222,6 +222,7 @@
     GME_init_track,
     GME_decode,
     GME_seek,
+    NULL,  // jump_to_order
     GME_quit_track,
     GME_quit_audio,
     GME_quit
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/SDL3_mixer-3.2.0/src/decoder_mpg123.c 
new/SDL3_mixer-3.2.2/src/decoder_mpg123.c
--- old/SDL3_mixer-3.2.0/src/decoder_mpg123.c   2026-01-01 20:20:48.000000000 
+0100
+++ new/SDL3_mixer-3.2.2/src/decoder_mpg123.c   2026-03-10 22:58:33.000000000 
+0100
@@ -459,6 +459,7 @@
     MPG123_init_track,
     MPG123_decode,
     MPG123_seek,
+    NULL,  // jump_to_order
     MPG123_quit_track,
     MPG123_quit_audio,
     MPG123_quit
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/SDL3_mixer-3.2.0/src/decoder_opus.c 
new/SDL3_mixer-3.2.2/src/decoder_opus.c
--- old/SDL3_mixer-3.2.0/src/decoder_opus.c     2026-01-08 23:31:07.000000000 
+0100
+++ new/SDL3_mixer-3.2.2/src/decoder_opus.c     2026-03-10 22:58:33.000000000 
+0100
@@ -357,6 +357,7 @@
     OPUS_init_track,
     OPUS_decode,
     OPUS_seek,
+    NULL,  // jump_to_order
     OPUS_quit_track,
     OPUS_quit_audio,
     OPUS_quit
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/SDL3_mixer-3.2.0/src/decoder_raw.c 
new/SDL3_mixer-3.2.2/src/decoder_raw.c
--- old/SDL3_mixer-3.2.0/src/decoder_raw.c      2026-01-01 20:20:48.000000000 
+0100
+++ new/SDL3_mixer-3.2.2/src/decoder_raw.c      2026-03-10 22:58:33.000000000 
+0100
@@ -137,6 +137,7 @@
     RAW_init_track,
     RAW_decode,
     RAW_seek,
+    NULL,  // jump_to_order
     RAW_quit_track,
     RAW_quit_audio,
     NULL  // quit
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/SDL3_mixer-3.2.0/src/decoder_sinewave.c 
new/SDL3_mixer-3.2.2/src/decoder_sinewave.c
--- old/SDL3_mixer-3.2.0/src/decoder_sinewave.c 2026-01-14 23:20:24.000000000 
+0100
+++ new/SDL3_mixer-3.2.2/src/decoder_sinewave.c 2026-03-10 22:58:33.000000000 
+0100
@@ -160,6 +160,7 @@
     SINEWAVE_init_track,
     SINEWAVE_decode,
     SINEWAVE_seek,
+    NULL,  // jump_to_order
     SINEWAVE_quit_track,
     SINEWAVE_quit_audio,
     NULL  // quit
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/SDL3_mixer-3.2.0/src/decoder_stb_vorbis.c 
new/SDL3_mixer-3.2.2/src/decoder_stb_vorbis.c
--- old/SDL3_mixer-3.2.0/src/decoder_stb_vorbis.c       2026-01-08 
23:31:07.000000000 +0100
+++ new/SDL3_mixer-3.2.2/src/decoder_stb_vorbis.c       2026-03-10 
22:58:33.000000000 +0100
@@ -349,6 +349,7 @@
     STBVORBIS_init_track,
     STBVORBIS_decode,
     STBVORBIS_seek,
+    NULL,  // jump_to_order
     STBVORBIS_quit_track,
     STBVORBIS_quit_audio,
     STBVORBIS_quit
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/SDL3_mixer-3.2.0/src/decoder_timidity.c 
new/SDL3_mixer-3.2.2/src/decoder_timidity.c
--- old/SDL3_mixer-3.2.0/src/decoder_timidity.c 2026-02-28 17:44:53.000000000 
+0100
+++ new/SDL3_mixer-3.2.2/src/decoder_timidity.c 2026-03-10 22:58:33.000000000 
+0100
@@ -169,6 +169,7 @@
     TIMIDITY_init_track,
     TIMIDITY_decode,
     TIMIDITY_seek,
+    NULL,  // jump_to_order
     TIMIDITY_quit_track,
     TIMIDITY_quit_audio,
     TIMIDITY_quit
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/SDL3_mixer-3.2.0/src/decoder_voc.c 
new/SDL3_mixer-3.2.2/src/decoder_voc.c
--- old/SDL3_mixer-3.2.0/src/decoder_voc.c      2026-01-08 23:31:07.000000000 
+0100
+++ new/SDL3_mixer-3.2.2/src/decoder_voc.c      2026-03-10 22:58:33.000000000 
+0100
@@ -127,9 +127,9 @@
         Uint8 block;
         Uint32 blen = 0;
         if (SDL_ReadIO(io, &block, 1) != 1) {
-            return true;   // assume that's the end of the file.
+            break;   // assume that's the end of the file.
         } else if (block == VOC_TERM) {
-            return true;  // that's the (optional) end.
+            break;  // that's the (optional) end.
         } else if (block != VOC_LOOPEND) {  // TERM and LOOPEND don't have a 
size field.
             Uint8 bits24[3];
             if (SDL_ReadIO(io, bits24, sizeof(bits24)) != sizeof(bits24)) {
@@ -590,6 +590,7 @@
     VOC_init_track,
     VOC_decode,
     VOC_seek,
+    NULL,  // jump_to_order
     VOC_quit_track,
     VOC_quit_audio,
     NULL  // quit
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/SDL3_mixer-3.2.0/src/decoder_vorbis.c 
new/SDL3_mixer-3.2.2/src/decoder_vorbis.c
--- old/SDL3_mixer-3.2.0/src/decoder_vorbis.c   2026-02-06 16:21:15.000000000 
+0100
+++ new/SDL3_mixer-3.2.2/src/decoder_vorbis.c   2026-03-10 22:58:33.000000000 
+0100
@@ -439,6 +439,7 @@
     VORBIS_init_track,
     VORBIS_decode,
     VORBIS_seek,
+    NULL,  // jump_to_order
     VORBIS_quit_track,
     VORBIS_quit_audio,
     VORBIS_quit
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/SDL3_mixer-3.2.0/src/decoder_wav.c 
new/SDL3_mixer-3.2.2/src/decoder_wav.c
--- old/SDL3_mixer-3.2.0/src/decoder_wav.c      2026-03-02 22:39:10.000000000 
+0100
+++ new/SDL3_mixer-3.2.2/src/decoder_wav.c      2026-03-10 22:58:33.000000000 
+0100
@@ -874,7 +874,7 @@
         adata->encoding = (Uint16)SDL_Swap32LE(fmt.subencoding);
         adata->channelmask = SDL_Swap32LE(fmt.channelsmask);
     } else {
-        adata->channelmask = StandardSDLWavChannelMask(fmt.format.channels);
+        adata->channelmask = StandardSDLWavChannelMask((int) 
SDL_Swap16LE(fmt.format.channels));
     }
 
     // Decode the audio data format
@@ -934,7 +934,7 @@
             break;
         case 16:
             switch(adata->encoding) {
-            case PCM_CODE: spec->format = SDL_AUDIO_S16; break;
+            case PCM_CODE: spec->format = SDL_AUDIO_S16LE; break;
             default: unknown_bits = true; break;
             }
             break;
@@ -949,8 +949,8 @@
             break;
         case 32:
             switch(adata->encoding) {
-            case PCM_CODE:   spec->format = SDL_AUDIO_S32; break;
-            case IEEE_FLOAT_CODE: spec->format = SDL_AUDIO_F32; break;
+            case PCM_CODE:   spec->format = SDL_AUDIO_S32LE; break;
+            case IEEE_FLOAT_CODE: spec->format = SDL_AUDIO_F32LE; break;
             default: unknown_bits = true; break;
             }
             break;
@@ -1785,6 +1785,7 @@
     WAV_init_track,
     WAV_decode,
     WAV_seek,
+    NULL,  // jump_to_order
     WAV_quit_track,
     WAV_quit_audio,
     NULL  // quit
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/SDL3_mixer-3.2.0/src/decoder_wavpack.c 
new/SDL3_mixer-3.2.2/src/decoder_wavpack.c
--- old/SDL3_mixer-3.2.0/src/decoder_wavpack.c  2026-01-01 20:20:48.000000000 
+0100
+++ new/SDL3_mixer-3.2.2/src/decoder_wavpack.c  2026-03-10 22:58:33.000000000 
+0100
@@ -633,6 +633,7 @@
     WAVPACK_init_track,
     WAVPACK_decode,
     WAVPACK_seek,
+    NULL,  // jump_to_order
     WAVPACK_quit_track,
     WAVPACK_quit_audio,
     WAVPACK_quit
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/SDL3_mixer-3.2.0/src/decoder_xmp.c 
new/SDL3_mixer-3.2.2/src/decoder_xmp.c
--- old/SDL3_mixer-3.2.0/src/decoder_xmp.c      2026-02-28 17:44:53.000000000 
+0100
+++ new/SDL3_mixer-3.2.2/src/decoder_xmp.c      2026-03-11 12:05:10.000000000 
+0100
@@ -65,6 +65,7 @@
     MIX_LOADER_FUNCTION(true,int,xmp_play_frame,(xmp_context)) \
     MIX_LOADER_FUNCTION(true,int,xmp_play_buffer,(xmp_context, void *, int, 
int)) \
     MIX_LOADER_FUNCTION(true,int,xmp_seek_time,(xmp_context, int)) \
+    MIX_LOADER_FUNCTION(true,int,xmp_set_position,(xmp_context, int)) \
     MIX_LOADER_FUNCTION(true,void,xmp_get_frame_info,(xmp_context, struct 
xmp_frame_info *)) \
     MIX_LOADER_FUNCTION(true,void,xmp_stop_module,(xmp_context)) \
     MIX_LOADER_FUNCTION(true,void,xmp_release_module,(xmp_context)) \
@@ -278,6 +279,18 @@
     return err < 0 ? SetLibXmpError("xmp_seek_time", err) : true;
 }
 
+static bool SDLCALL XMP_jump_to_order(void *track_userdata, int order)
+{
+    XMP_TrackData *tdata = (XMP_TrackData *) track_userdata;
+    int err = libxmp.xmp_set_position(tdata->ctx, order);
+    switch (err) {
+    case -XMP_ERROR_STATE:
+    case -XMP_ERROR_INVALID:
+        return SetLibXmpError("xmp_set_position", err);
+    }
+    return true;
+}
+
 static void SDLCALL XMP_quit_track(void *track_userdata)
 {
     XMP_TrackData *tdata = (XMP_TrackData *) track_userdata;
@@ -300,6 +313,7 @@
     XMP_init_track,
     XMP_decode,
     XMP_seek,
+    XMP_jump_to_order,
     XMP_quit_track,
     XMP_quit_audio,
     XMP_quit
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/SDL3_mixer-3.2.0/src/dr_libs/dr_flac.h 
new/SDL3_mixer-3.2.2/src/dr_libs/dr_flac.h
--- old/SDL3_mixer-3.2.0/src/dr_libs/dr_flac.h  2026-01-17 03:10:10.000000000 
+0100
+++ new/SDL3_mixer-3.2.2/src/dr_libs/dr_flac.h  2026-05-11 20:39:32.000000000 
+0200
@@ -1,6 +1,6 @@
 /*
 FLAC audio decoder. Choice of public domain or MIT-0. See license statements 
at the end of this file.
-dr_flac - v0.13.3 - 2026-01-17
+dr_flac - v0.13.4 - TBD
 
 David Reid - [email protected]
 
@@ -126,7 +126,7 @@
 
 #define DRFLAC_VERSION_MAJOR     0
 #define DRFLAC_VERSION_MINOR     13
-#define DRFLAC_VERSION_REVISION  3
+#define DRFLAC_VERSION_REVISION  4
 #define DRFLAC_VERSION_STRING    DRFLAC_XSTRINGIFY(DRFLAC_VERSION_MAJOR) "." 
DRFLAC_XSTRINGIFY(DRFLAC_VERSION_MINOR) "." 
DRFLAC_XSTRINGIFY(DRFLAC_VERSION_REVISION)
 
 #include <stddef.h> /* For size_t. */
@@ -1547,6 +1547,8 @@
 #define DRFLAC_ZERO_OBJECT(p)               DRFLAC_ZERO_MEMORY((p), 
sizeof(*(p)))
 #endif
 
+#define DRFLAC_MIN(a, b)                    (((a) < (b)) ? (a) : (b))
+
 #define DRFLAC_MAX_SIMD_VECTOR_SIZE                     64  /* 64 for AVX-512 
in the future. */
 
 /* Result Codes */
@@ -5980,8 +5982,6 @@
                     break;  /* Failed to seek to FLAC frame. */
                 }
             } else {
-                const float approxCompressionRatio = 
(drflac_int64)(lastSuccessfulSeekOffset - pFlac->firstFLACFramePosInBytes) / 
((drflac_int64)(pcmRangeLo * pFlac->channels * pFlac->bitsPerSample)/8.0f);
-
                 if (pcmRangeLo > pcmFrameIndex) {
                     /* We seeked too far forward. We need to move our target 
byte backward and try again. */
                     byteRangeHi = lastSuccessfulSeekOffset;
@@ -6004,12 +6004,14 @@
                             break;  /* Failed to seek to FLAC frame. */
                         }
                     } else {
+                        const double approxCompressionRatio = 
(drflac_int64)(lastSuccessfulSeekOffset - pFlac->firstFLACFramePosInBytes) / 
((drflac_int64)(pcmRangeLo * pFlac->channels * pFlac->bitsPerSample)/8.0);
+
                         byteRangeLo = lastSuccessfulSeekOffset;
                         if (byteRangeHi < byteRangeLo) {
                             byteRangeHi = byteRangeLo;
                         }
 
-                        targetByte = lastSuccessfulSeekOffset + 
(drflac_uint64)(((drflac_int64)((pcmFrameIndex-pcmRangeLo) * pFlac->channels * 
pFlac->bitsPerSample)/8.0f) * approxCompressionRatio);
+                        targetByte = lastSuccessfulSeekOffset + 
(drflac_uint64)(((drflac_int64)((pcmFrameIndex-pcmRangeLo) * pFlac->channels * 
pFlac->bitsPerSample)/8.0) * approxCompressionRatio);
                         if (targetByte > byteRangeHi) {
                             targetByte = byteRangeHi;
                         }
@@ -6402,7 +6404,7 @@
         }
 
         if (p != NULL) {
-            DRFLAC_COPY_MEMORY(p2, p, szOld);
+            DRFLAC_COPY_MEMORY(p2, p, DRFLAC_MIN(szNew, szOld));
             pAllocationCallbacks->onFree(p, pAllocationCallbacks->pUserData);
         }
 
@@ -6430,11 +6432,22 @@
     We want to keep track of the byte position in the stream of the seektable. 
At the time of calling this function we know that
     we'll be sitting on byte 42.
     */
-    drflac_uint64 runningFilePos = 42;
-    drflac_uint64 seektablePos   = 0;
-    drflac_uint32 seektableSize  = 0;
+    drflac_uint64 runningFilePos   = 42;
+    drflac_uint64 seektablePos     = 0;
+    drflac_uint32 seektableSize    = 0;
+    drflac_int64  fileSize         = 0;
+    drflac_bool32 hasKnownFileSize = DRFLAC_FALSE;
+
+    /* We'll be doing some memory allocations here against untrusted data. 
We'll do a basic validation check that they don't exceed the size of the file. 
*/
+    if (onTell != NULL && onSeek != NULL) {
+        if (onSeek(pUserData, 0, DRFLAC_SEEK_END)) {
+            if (onTell(pUserData, &fileSize)) {
+                hasKnownFileSize = DRFLAC_TRUE;
+            }
 
-    (void)onTell;
+            onSeek(pUserData, runningFilePos, DRFLAC_SEEK_SET);
+        }
+    }
 
     for (;;) {
         drflac_metadata metadata;
@@ -6444,6 +6457,11 @@
         if (drflac__read_and_decode_block_header(onRead, pUserData, 
&isLastBlock, &blockType, &blockSize) == DRFLAC_FALSE) {
             return DRFLAC_FALSE;
         }
+
+        if (hasKnownFileSize && (blockSize > ((drflac_uint64)fileSize - 
runningFilePos))) {
+            return DRFLAC_FALSE;    /* Block size exceeds the size of the 
file. */
+        }
+
         runningFilePos += 4;
 
         metadata.type = blockType;
@@ -6559,7 +6577,7 @@
                         drflac__free_from_callbacks(pRawData, 
pAllocationCallbacks);
                         return DRFLAC_FALSE;
                     }
-                    metadata.data.vorbis_comment.vendor       = pRunningData;  
                                          pRunningData += 
metadata.data.vorbis_comment.vendorLength;
+                    metadata.data.vorbis_comment.vendor       = pRunningData;  
                                 pRunningData += 
metadata.data.vorbis_comment.vendorLength;
                     metadata.data.vorbis_comment.commentCount = 
drflac__le2host_32_ptr_unaligned(pRunningData); pRunningData += 4;
 
                     /* Need space for 'commentCount' comments after the block, 
which at minimum is a drflac_uint32 per comment */
@@ -6747,13 +6765,18 @@
                     blockSizeRemaining -= 4;
                     metadata.data.picture.mimeLength = 
drflac__be2host_32(metadata.data.picture.mimeLength);
 
+                    if (blockSizeRemaining < metadata.data.picture.mimeLength) 
{
+                        result = DRFLAC_FALSE;
+                        goto done_flac;
+                    }
+
                     pMime = 
(char*)drflac__malloc_from_callbacks(metadata.data.picture.mimeLength + 1, 
pAllocationCallbacks); /* +1 for null terminator. */
                     if (pMime == NULL) {
                         result = DRFLAC_FALSE;
                         goto done_flac;
                     }
 
-                    if (blockSizeRemaining < metadata.data.picture.mimeLength 
|| onRead(pUserData, pMime, metadata.data.picture.mimeLength) != 
metadata.data.picture.mimeLength) {
+                    if (onRead(pUserData, pMime, 
metadata.data.picture.mimeLength) != metadata.data.picture.mimeLength) {
                         result = DRFLAC_FALSE;
                         goto done_flac;
                     }
@@ -6769,13 +6792,18 @@
                     blockSizeRemaining -= 4;
                     metadata.data.picture.descriptionLength = 
drflac__be2host_32(metadata.data.picture.descriptionLength);
 
+                    if (blockSizeRemaining < 
metadata.data.picture.descriptionLength) {
+                        result = DRFLAC_FALSE;
+                        goto done_flac;
+                    }
+
                     pDescription = 
(char*)drflac__malloc_from_callbacks(metadata.data.picture.descriptionLength + 
1, pAllocationCallbacks); /* +1 for null terminator. */
                     if (pDescription == NULL) {
                         result = DRFLAC_FALSE;
                         goto done_flac;
                     }
 
-                    if (blockSizeRemaining < 
metadata.data.picture.descriptionLength || onRead(pUserData, pDescription, 
metadata.data.picture.descriptionLength) != 
metadata.data.picture.descriptionLength) {
+                    if (onRead(pUserData, pDescription, 
metadata.data.picture.descriptionLength) != 
metadata.data.picture.descriptionLength) {
                         result = DRFLAC_FALSE;
                         goto done_flac;
                     }
@@ -8094,11 +8122,17 @@
             return NULL;
         }
 
+        if ((0xFFFFFFFF - (seekpointCount * sizeof(drflac_seekpoint))) < 
allocationSize) {
+        #ifndef DR_FLAC_NO_OGG
+            drflac__free_from_callbacks(pOggbs, &allocationCallbacks);
+        #endif
+            return NULL;
+        }
+
         allocationSize += seekpointCount * sizeof(drflac_seekpoint);
     }
 
-
-    pFlac = (drflac*)drflac__malloc_from_callbacks(allocationSize, 
&allocationCallbacks);
+    pFlac = (drflac*)drflac__malloc_from_callbacks((size_t)allocationSize, 
&allocationCallbacks);
     if (pFlac == NULL) {
     #ifndef DR_FLAC_NO_OGG
         drflac__free_from_callbacks(pOggbs, &allocationCallbacks);
@@ -12169,6 +12203,10 @@
 /*
 REVISION HISTORY
 ================
+v0.13.4 - TBD
+  - Add a bounds check when allocating memory during metadata processing.
+  - Fix a possible overflow error when parsing picture metadata.
+
 v0.13.3 - 2026-01-17
   - Fix a compiler compatibility issue with some inlined assembly.
   - Fix a compilation warning.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/SDL3_mixer-3.2.0/src/dr_libs/dr_mp3.h 
new/SDL3_mixer-3.2.2/src/dr_libs/dr_mp3.h
--- old/SDL3_mixer-3.2.0/src/dr_libs/dr_mp3.h   2026-01-17 03:10:10.000000000 
+0100
+++ new/SDL3_mixer-3.2.2/src/dr_libs/dr_mp3.h   2026-05-11 20:39:32.000000000 
+0200
@@ -1,6 +1,6 @@
 /*
 MP3 audio decoder. Choice of public domain or MIT-0. See license statements at 
the end of this file.
-dr_mp3 - v0.7.3 - 2026-01-17
+dr_mp3 - v0.7.4 - TBD
 
 David Reid - [email protected]
 
@@ -72,7 +72,7 @@
 
 #define DRMP3_VERSION_MAJOR     0
 #define DRMP3_VERSION_MINOR     7
-#define DRMP3_VERSION_REVISION  3
+#define DRMP3_VERSION_REVISION  4
 #define DRMP3_VERSION_STRING    DRMP3_XSTRINGIFY(DRMP3_VERSION_MAJOR) "." 
DRMP3_XSTRINGIFY(DRMP3_VERSION_MINOR) "." 
DRMP3_XSTRINGIFY(DRMP3_VERSION_REVISION)
 
 #include <stddef.h> /* For size_t. */
@@ -657,8 +657,10 @@
 
 #if !defined(DR_MP3_NO_SIMD)
 
-#if !defined(DR_MP3_ONLY_SIMD) && (defined(_M_X64) || defined(__x86_64__) || 
defined(__aarch64__) || defined(_M_ARM64) || defined(_M_ARM64EC))
-/* x64 always have SSE2, arm64 always have neon, no need for generic code */
+#if !defined(DR_MP3_ONLY_SIMD) && ((defined(_MSC_VER) && _MSC_VER >= 1400) && 
defined(_M_X64)) || ((defined(__i386) || defined(_M_IX86) || defined(__i386__) 
|| defined(__x86_64__)) && ((defined(_M_IX86_FP) && _M_IX86_FP == 2) || 
defined(__SSE2__)))
+#define DR_MP3_ONLY_SIMD
+#endif
+#if !defined(DR_MP3_ONLY_SIMD) && (defined(__ARM_NEON) || defined(__aarch64__) 
|| defined(_M_ARM64) || defined(_M_ARM64EC))
 #define DR_MP3_ONLY_SIMD
 #endif
 
@@ -3186,6 +3188,10 @@
                 pTagDataBeg = pFirstFrameData + DRMP3_HDR_SIZE + (bs.pos/8);
                 pTagData    = pTagDataBeg;
 
+                if (firstFrameInfo.frame_bytes - (size_t)(pTagData - 
pFirstFrameData) < 8) {
+                    goto done_xing_info;    /* Frame too small for a Xing/Info 
tag. */
+                }
+
                 /* Check for both "Xing" and "Info" identifiers. */
                 isXing = (pTagData[0] == 'X' && pTagData[1] == 'i' && 
pTagData[2] == 'n' && pTagData[3] == 'g');
                 isInfo = (pTagData[0] == 'I' && pTagData[1] == 'n' && 
pTagData[2] == 'f' && pTagData[3] == 'o');
@@ -3197,42 +3203,60 @@
                     pTagData += 8;  /* Skip past the ID and flags. */
 
                     if (flags & 0x01) { /* FRAMES flag. */
+                        if (firstFrameInfo.frame_bytes - (size_t)(pTagData - 
pFirstFrameData) < 4) {
+                            goto done_xing_info;    /* Invalid Xing/Info tag. 
*/
+                        }
+
                         detectedMP3FrameCount = (drmp3_uint32)pTagData[0] << 
24 | (drmp3_uint32)pTagData[1] << 16 | (drmp3_uint32)pTagData[2] << 8 | 
(drmp3_uint32)pTagData[3];
                         pTagData += 4;
                     }
 
                     if (flags & 0x02) { /* BYTES flag. */
+                        if (firstFrameInfo.frame_bytes - (size_t)(pTagData - 
pFirstFrameData) < 4) {
+                            goto done_xing_info;    /* Invalid Xing/Info tag. 
*/
+                        }
+
                         bytes  = (drmp3_uint32)pTagData[0] << 24 | 
(drmp3_uint32)pTagData[1] << 16 | (drmp3_uint32)pTagData[2] << 8 | 
(drmp3_uint32)pTagData[3];
                         (void)bytes;    /* <-- Just to silence a warning about 
`bytes` being assigned but unused. Want to leave this here in case I want to 
make use of it later. */
                         pTagData += 4;
                     }
 
                     if (flags & 0x04) { /* TOC flag. */
+                        if (firstFrameInfo.frame_bytes - (size_t)(pTagData - 
pFirstFrameData) < 100) {
+                            goto done_xing_info;    /* Invalid Xing/Info tag. 
*/
+                        }
+
                         /* TODO: Extract and bind seek points. */
                         pTagData += 100;
                     }
 
                     if (flags & 0x08) { /* SCALE flag. */
+                        if (firstFrameInfo.frame_bytes - (size_t)(pTagData - 
pFirstFrameData) < 4) {
+                            goto done_xing_info;    /* Invalid Xing/Info tag. 
*/
+                        }
+                        
                         pTagData += 4;
                     }
 
                     /* At this point we're done with the Xing/Info header. Now 
we can look at the LAME data. */
                     if (pTagData[0]) {
+                        int delayInPCMFrames;
+                        int paddingInPCMFrames;
+
+                        if (firstFrameInfo.frame_bytes - (size_t)(pTagData - 
pFirstFrameData) < 36) {
+                            goto done_xing_info;    /* Invalid Xing/Info tag. 
*/
+                        }
+
                         pTagData += 21;
 
-                        if (pTagData - pFirstFrameData + 14 < 
firstFrameInfo.frame_bytes) {
-                            int delayInPCMFrames;
-                            int paddingInPCMFrames;
-
-                            delayInPCMFrames   = (( (drmp3_uint32)pTagData[0]  
      << 4) | ((drmp3_uint32)pTagData[1] >> 4)) + (528 + 1);
-                            paddingInPCMFrames = ((((drmp3_uint32)pTagData[1] 
& 0xF) << 8) | ((drmp3_uint32)pTagData[2]     )) - (528 + 1);
-                            if (paddingInPCMFrames < 0) {
-                                paddingInPCMFrames = 0; /* Padding cannot be 
negative. Probably a malformed file. Ignore. */
-                            }
-                            
-                            pMP3->delayInPCMFrames   = 
(drmp3_uint32)delayInPCMFrames;
-                            pMP3->paddingInPCMFrames = 
(drmp3_uint32)paddingInPCMFrames;
+                        delayInPCMFrames   = (( (drmp3_uint32)pTagData[0]      
  << 4) | ((drmp3_uint32)pTagData[1] >> 4)) + (528 + 1);
+                        paddingInPCMFrames = ((((drmp3_uint32)pTagData[1] & 
0xF) << 8) | ((drmp3_uint32)pTagData[2]     )) - (528 + 1);
+                        if (paddingInPCMFrames < 0) {
+                            paddingInPCMFrames = 0; /* Padding cannot be 
negative. Probably a malformed file. Ignore. */
                         }
+                        
+                        pMP3->delayInPCMFrames   = 
(drmp3_uint32)delayInPCMFrames;
+                        pMP3->paddingInPCMFrames = 
(drmp3_uint32)paddingInPCMFrames;
                     }
 
                     /*
@@ -3271,6 +3295,8 @@
                     */
                     drmp3dec_init(&pMP3->decoder);
                 }
+
+                done_xing_info:;
             } else {
                 /* Failed to read the side info. */
             }
@@ -3283,7 +3309,7 @@
     }
 
     if (detectedMP3FrameCount != 0xFFFFFFFF) {
-        pMP3->totalPCMFrameCount = detectedMP3FrameCount * 
firstFramePCMFrameCount;
+        pMP3->totalPCMFrameCount = (drmp3_uint64)detectedMP3FrameCount * 
firstFramePCMFrameCount;
     }
 
     pMP3->channels   = pMP3->mp3FrameChannels;
@@ -4245,7 +4271,7 @@
 #else
     /* Slow path. Convert from s16 to f32. */
     {
-        drmp3_int16 pTempS16[8192];
+        drmp3_int16 pTempS16[1152*2];   /* MP3 frames have a maximum 
per-channel sample count of 1152. Times 2 to account for stereo. */
         drmp3_uint64 totalPCMFramesRead = 0;
 
         while (totalPCMFramesRead < framesToRead) {
@@ -4282,7 +4308,7 @@
 #else
     /* Slow path. Convert from f32 to s16. */
     {
-        float pTempF32[4096];
+        float pTempF32[1152*2];   /* MP3 frames have a maximum per-channel 
sample count of 1152. Times 2 to account for stereo. */
         drmp3_uint64 totalPCMFramesRead = 0;
 
         while (totalPCMFramesRead < framesToRead) {
@@ -4770,7 +4796,7 @@
     drmp3_uint64 totalFramesRead = 0;
     drmp3_uint64 framesCapacity = 0;
     float* pFrames = NULL;
-    float temp[4096];
+    float temp[1152*2];   /* MP3 frames have a maximum per-channel sample 
count of 1152. Times 2 to account for stereo. */
 
     DRMP3_ASSERT(pMP3 != NULL);
 
@@ -4839,7 +4865,7 @@
     drmp3_uint64 totalFramesRead = 0;
     drmp3_uint64 framesCapacity = 0;
     drmp3_int16* pFrames = NULL;
-    drmp3_int16 temp[4096];
+    drmp3_int16 temp[1152*2];   /* MP3 frames have a maximum per-channel 
sample count of 1152. Times 2 to account for stereo. */
 
     DRMP3_ASSERT(pMP3 != NULL);
 
@@ -5007,6 +5033,12 @@
 /*
 REVISION HISTORY
 ================
+v0.7.4 - TBD
+  - Fix an overflow error with "Xing" and "Info" tag parsing.
+  - Add some validation checks for "Xing" and "Info" tag parsing.
+  - Reduce size of some stack allocations.
+  - Improvements to SIMD detection.
+
 v0.7.3 - 2026-01-17
   - Fix an error in drmp3_open_and_read_pcm_frames_s16() and family when 
memory allocation fails.
   - Fix some compilation warnings.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/SDL3_mixer-3.2.0/src/version.rc 
new/SDL3_mixer-3.2.2/src/version.rc
--- old/SDL3_mixer-3.2.0/src/version.rc 2026-03-09 15:18:57.000000000 +0100
+++ new/SDL3_mixer-3.2.2/src/version.rc 2026-05-12 00:31:34.000000000 +0200
@@ -9,8 +9,8 @@
 //
 
 VS_VERSION_INFO VERSIONINFO
- FILEVERSION 3,2,0,0
- PRODUCTVERSION 3,2,0,0
+ FILEVERSION 3,2,2,0
+ PRODUCTVERSION 3,2,2,0
  FILEFLAGSMASK 0x3fL
  FILEFLAGS 0x0L
  FILEOS 0x40004L
@@ -23,12 +23,12 @@
         BEGIN
             VALUE "CompanyName", "\0"
             VALUE "FileDescription", "SDL_mixer\0"
-            VALUE "FileVersion", "3, 2, 0, 0\0"
+            VALUE "FileVersion", "3, 2, 2, 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, 0, 0\0"
+            VALUE "ProductVersion", "3, 2, 2, 0\0"
         END
     END
     BLOCK "VarFileInfo"


++++++ _scmsync.obsinfo ++++++
mtime: 1778577151
commit: 446562d8d6efce73e6b6aa3d347c6a451e6951ddf9b04c5338be397b1bc2fb42
url: https://src.opensuse.org/jengelh/SDL3_mixer
revision: master

++++++ 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-05-12 11:12:31.000000000 +0200
@@ -0,0 +1 @@
+.osc

Reply via email to