diff --git a/Android.mk b/Android.mk
index 9a5ba67a0..dd7a2e011 100644
--- a/Android.mk
+++ b/Android.mk
@@ -19,8 +19,8 @@ SUPPORT_OGG ?= false
OGG_LIBRARY_PATH := external/ogg
VORBIS_LIBRARY_PATH := external/tremor
-# Enable this if you want to support loading MP3 music via dr_mp3
-SUPPORT_MP3_DRMP3 ?= true
+# Enable this if you want to support loading MP3 music via MINIMP3
+SUPPORT_MP3_MINIMP3 ?= true
# Enable this if you want to support loading MP3 music via MPG123
SUPPORT_MP3_MPG123 ?= false
@@ -120,8 +120,8 @@ ifeq ($(SUPPORT_OGG),true)
LOCAL_STATIC_LIBRARIES += ogg vorbisidec
endif
-ifeq ($(SUPPORT_MP3_DRMP3),true)
- LOCAL_CFLAGS += -DMUSIC_MP3_DRMP3
+ifeq ($(SUPPORT_MP3_MINIMP3),true)
+ LOCAL_CFLAGS += -DMUSIC_MP3_MINIMP3
endif
# This needs to be a shared library to comply with the LGPL license
@@ -132,7 +132,7 @@ ifeq ($(SUPPORT_MP3_MPG123),true)
endif
ifeq ($(SUPPORT_WAVPACK),true)
- LOCAL_CFLAGS += -DMUSIC_WAVPACK -DWAVPACK_HEADER=\"../external/wavpack/include/wavpack.h\"
+ LOCAL_CFLAGS += -DMUSIC_WAVPACK -DMUSIC_WAVPACK_DSD -DWAVPACK_HEADER=\"../external/wavpack/include/wavpack.h\"
LOCAL_STATIC_LIBRARIES += wavpack
endif
diff --git a/CHANGES.txt b/CHANGES.txt
index daf32755a..ec551adc8 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -1,6 +1,7 @@
2.8.0:
* Added support for loading wavpack sound files (https://www.wavpack.com/)
* Added support for loading classic console sound files using Game_Music_Emu (https://github.com/libgme/game-music-emu)
+ * Use minimp3 instead of dr_mp3 as the default backend for MP3 music
* Use libxmp instead of modplug as the default backend for MOD music
To use libmodplug instead, configure using --enable-music-mod-modplug --disable-music-mod-xmp
* Added support for FLAC audio in Ogg containers
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 828aad534..dc37b28f6 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -4,8 +4,8 @@ list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/cmake")
# See docs/release_checklist.md
set(MAJOR_VERSION 2)
-set(MINOR_VERSION 7)
-set(MICRO_VERSION 1)
+set(MINOR_VERSION 8)
+set(MICRO_VERSION 0)
set(SDL_REQUIRED_VERSION 2.0.9)
include(PrivateSdlFunctions)
@@ -126,13 +126,13 @@ endif()
option(SDL2MIXER_MP3 "Enable MP3 music" ON)
-cmake_dependent_option(SDL2MIXER_MP3_DRMP3 "Support loading MP3 music via dr_mp3" ON SDL2MIXER_MP3 OFF)
+cmake_dependent_option(SDL2MIXER_MP3_MINIMP3 "Support loading MP3 music via minimp3" ON SDL2MIXER_MP3 OFF)
cmake_dependent_option(SDL2MIXER_MP3_MPG123 "Support loading MP3 music via MPG123" OFF SDL2MIXER_MP3 OFF)
cmake_dependent_option(SDL2MIXER_MP3_MPG123_SHARED "Dynamically load mpg123" "${SDL2MIXER_DEPS_SHARED}" SDL2MIXER_MP3_MPG123 OFF)
-if(SDL2MIXER_MP3 AND NOT (SDL2MIXER_MP3_DRMP3 OR SDL2MIXER_MP3_MPG123))
- message(FATAL_ERROR "MP3 support was enabled (SDL2MIXER_MP3) but neither drmp3 (SDL2MIXER_MP3_DRMP3) or mpg123 (SDL2MIXER_MP3_MPG123) were enabled.")
+if(SDL2MIXER_MP3 AND NOT (SDL2MIXER_MP3_MINIMP3 OR SDL2MIXER_MP3_MPG123))
+ message(FATAL_ERROR "MP3 support was enabled (SDL2MIXER_MP3) but neither minimp3 (SDL2MIXER_MP3_MINIMP3) or mpg123 (SDL2MIXER_MP3_MPG123) were enabled.")
endif()
option(SDL2MIXER_MIDI "Enable MIDI music" ON)
@@ -219,10 +219,10 @@ add_library(SDL2_mixer
src/codecs/mp3utils.c
src/codecs/music_cmd.c
src/codecs/music_drflac.c
- src/codecs/music_drmp3.c
src/codecs/music_flac.c
src/codecs/music_fluidsynth.c
src/codecs/music_gme.c
+ src/codecs/music_minimp3.c
src/codecs/music_modplug.c
src/codecs/music_mpg123.c
src/codecs/music_nativemidi.c
@@ -726,8 +726,8 @@ if(SDL2MIXER_MOD_XMP)
endif()
endif()
-if(SDL2MIXER_MP3_DRMP3)
- target_compile_definitions(SDL2_mixer PRIVATE MUSIC_MP3_DRMP3)
+if(SDL2MIXER_MP3_MINIMP3)
+ target_compile_definitions(SDL2_mixer PRIVATE MUSIC_MP3_MINIMP3)
endif()
if(SDL2MIXER_MP3_MPG123)
diff --git a/Makefile.os2 b/Makefile.os2
index df3fb4c4f..6f6976799 100644
--- a/Makefile.os2
+++ b/Makefile.os2
@@ -6,8 +6,8 @@
LIBNAME = SDL2mix
MAJOR_VERSION = 2
-MINOR_VERSION = 7
-MICRO_VERSION = 1
+MINOR_VERSION = 8
+MICRO_VERSION = 0
VERSION = $(MAJOR_VERSION).$(MINOR_VERSION).$(MICRO_VERSION)
TITLENAME = $(LIBNAME) $(VERSION)
@@ -33,8 +33,8 @@ USE_DRFLAC=no
USE_OPUS=yes
# mp3 music support (using mpg123)
USE_MPG123=yes
-# mp3 music support (using dr_mp3)
-USE_DRMP3=no
+# mp3 music support (using minimp3)
+USE_MINIMP3=no
# wavpack music support
USE_WAVPACK=yes
# wavpack DSD music support
@@ -60,7 +60,7 @@ SRCS = utils.c effect_position.c effects_internal.c effect_stereoreverse.c mixer
SRCS+= load_aiff.c load_voc.c music_wav.c &
music_ogg.c music_ogg_stb.c music_opus.c &
music_flac.c music_drflac.c music_wavpack.c &
- mp3utils.c music_mpg123.c music_drmp3.c &
+ mp3utils.c music_mpg123.c music_minimp3.c &
music_xmp.c music_modplug.c music_gme.c &
music_fluidsynth.c music_timidity.c
# timidity sources:
@@ -142,8 +142,8 @@ NEED_LIBOGG=yes
CFLAGS+= -DMUSIC_MP3_MPG123
LIBS+= mpg123.lib
!endif
-!ifeq USE_DRMP3 yes
-CFLAGS+= -DMUSIC_MP3_DRMP3
+!ifeq USE_MINIMP3 yes
+CFLAGS+= -DMUSIC_MP3_MINIMP3
!endif
!ifeq USE_XMP yes
@@ -199,6 +199,9 @@ $(LNKFILE):
.c.obj:
wcc386 $(CFLAGS) -fo=$^@ $<
+music_minimp3.obj: music_minimp3.c
+ wcc386 $(CFLAGS) -za99 -fo=$^@ $<
+
playmus.obj: playmus.c
wcc386 $(CFLAGS_BASE) -fo=$^@ $<
diff --git a/README.txt b/README.txt
index 2b9cca85c..80644bc1f 100644
--- a/README.txt
+++ b/README.txt
@@ -28,4 +28,4 @@ Support for software MIDI, MOD, and Opus are not included by default because of
- When building with Xcode, you can edit the config at the top of the project to enable them, and you will need to include the appropriate framework in your application.
- For Android, you can edit the config at the top of Android.mk to enable them.
-The default MP3 support is provided using dr_mp3. SDL_mixer also supports using libmpg123: you can enable it by passing --enable-music-mp3-mpg123 to configure.
+The default MP3 support is provided using minimp3. SDL_mixer also supports using libmpg123: you can enable it by passing --enable-music-mp3-mpg123 to configure.
diff --git a/SDL2_mixerConfig.cmake.in b/SDL2_mixerConfig.cmake.in
index 4bdd9f8ae..745171295 100644
--- a/SDL2_mixerConfig.cmake.in
+++ b/SDL2_mixerConfig.cmake.in
@@ -23,7 +23,7 @@ set(SDL2MIXER_MOD_XMP @SDL2MIXER_MOD_XMP@)
set(SDL2MIXER_MOD_XMP_LITE @SDL2MIXER_MOD_XMP_LITE@)
set(SDL2MIXER_MP3 @SDL2MIXER_MP3@)
-set(SDL2MIXER_MP3_DRMP3 @SDL2MIXER_MP3_DRMP3@)
+set(SDL2MIXER_MP3_MINIMP3 @SDL2MIXER_MP3_MINIMP3@)
set(SDL2MIXER_MP3_MPG123 @SDL2MIXER_MP3_MPG123@)
set(SDL2MIXER_MIDI @SDL2MIXER_MIDI@)
diff --git a/VisualC-WinRT/SDL_mixer-UWP.vcxproj b/VisualC-WinRT/SDL_mixer-UWP.vcxproj
index 326650966..7ab24e67a 100644
--- a/VisualC-WinRT/SDL_mixer-UWP.vcxproj
+++ b/VisualC-WinRT/SDL_mixer-UWP.vcxproj
@@ -38,10 +38,10 @@
-
+
@@ -69,10 +69,10 @@
-
+
@@ -202,7 +202,7 @@
NotUsing
false
..\include;..\src;..\src\codecs;..\src\codecs\timidity;..\external\ogg\include;..\external\vorbis\include;..\..\SDL\include;%(AdditionalIncludeDirectories)
- DLL_EXPORT;_CRT_SECURE_NO_WARNINGS;MUSIC_WAV;MUSIC_FLAC_DRFLAC;MUSIC_MP3_DRMP3;MUSIC_OGG;OGG_USE_STB;MUSIC_MID_TIMIDITY;%(PreprocessorDefinitions)
+ DLL_EXPORT;_CRT_SECURE_NO_WARNINGS;MUSIC_WAV;MUSIC_FLAC_DRFLAC;MUSIC_MP3_MINIMP3;MUSIC_OGG;OGG_USE_STB;MUSIC_MID_TIMIDITY;%(PreprocessorDefinitions)
Console
@@ -215,7 +215,7 @@
NotUsing
false
..\include;..\src;..\src\codecs;..\src\codecs\timidity;..\external\ogg\include;..\external\vorbis\include;..\..\SDL\include;%(AdditionalIncludeDirectories)
- DLL_EXPORT;NDEBUG;_CRT_SECURE_NO_WARNINGS;MUSIC_WAV;MUSIC_FLAC_DRFLAC;MUSIC_MP3_DRMP3;MUSIC_OGG;OGG_USE_STB;MUSIC_MID_TIMIDITY;%(PreprocessorDefinitions)
+ DLL_EXPORT;NDEBUG;_CRT_SECURE_NO_WARNINGS;MUSIC_WAV;MUSIC_FLAC_DRFLAC;MUSIC_MP3_MINIMP3;MUSIC_OGG;OGG_USE_STB;MUSIC_MID_TIMIDITY;%(PreprocessorDefinitions)
Console
@@ -228,7 +228,7 @@
NotUsing
false
..\include;..\src;..\src\codecs;..\src\codecs\timidity;..\external\ogg\include;..\external\vorbis\include;..\..\SDL\include;%(AdditionalIncludeDirectories)
- DLL_EXPORT;_CRT_SECURE_NO_WARNINGS;MUSIC_WAV;MUSIC_FLAC_DRFLAC;MUSIC_MP3_DRMP3;MUSIC_OGG;OGG_USE_STB;MUSIC_MID_TIMIDITY;%(PreprocessorDefinitions)
+ DLL_EXPORT;_CRT_SECURE_NO_WARNINGS;MUSIC_WAV;MUSIC_FLAC_DRFLAC;MUSIC_MP3_MINIMP3;MUSIC_OGG;OGG_USE_STB;MUSIC_MID_TIMIDITY;%(PreprocessorDefinitions)
Console
@@ -241,7 +241,7 @@
NotUsing
false
..\include;..\src;..\src\codecs;..\src\codecs\timidity;..\external\ogg\include;..\external\vorbis\include;..\..\SDL\include;%(AdditionalIncludeDirectories)
- DLL_EXPORT;NDEBUG;_CRT_SECURE_NO_WARNINGS;MUSIC_WAV;MUSIC_FLAC_DRFLAC;MUSIC_MP3_DRMP3;MUSIC_OGG;OGG_USE_STB;MUSIC_MID_TIMIDITY;%(PreprocessorDefinitions)
+ DLL_EXPORT;NDEBUG;_CRT_SECURE_NO_WARNINGS;MUSIC_WAV;MUSIC_FLAC_DRFLAC;MUSIC_MP3_MINIMP3;MUSIC_OGG;OGG_USE_STB;MUSIC_MID_TIMIDITY;%(PreprocessorDefinitions)
Console
@@ -254,7 +254,7 @@
NotUsing
false
..\include;..\src;..\src\codecs;..\src\codecs\timidity;..\external\ogg\include;..\external\vorbis\include;..\..\SDL\include;%(AdditionalIncludeDirectories)
- DLL_EXPORT;_CRT_SECURE_NO_WARNINGS;MUSIC_WAV;MUSIC_FLAC_DRFLAC;MUSIC_MP3_DRMP3;MUSIC_OGG;OGG_USE_STB;MUSIC_MID_TIMIDITY;%(PreprocessorDefinitions)
+ DLL_EXPORT;_CRT_SECURE_NO_WARNINGS;MUSIC_WAV;MUSIC_FLAC_DRFLAC;MUSIC_MP3_MINIMP3;MUSIC_OGG;OGG_USE_STB;MUSIC_MID_TIMIDITY;%(PreprocessorDefinitions)
Console
@@ -267,7 +267,7 @@
NotUsing
false
..\include;..\src;..\src\codecs;..\src\codecs\timidity;..\external\ogg\include;..\external\vorbis\include;..\..\SDL\include;%(AdditionalIncludeDirectories)
- DLL_EXPORT;NDEBUG;_CRT_SECURE_NO_WARNINGS;MUSIC_WAV;MUSIC_FLAC_DRFLAC;MUSIC_MP3_DRMP3;MUSIC_OGG;OGG_USE_STB;MUSIC_MID_TIMIDITY;%(PreprocessorDefinitions)
+ DLL_EXPORT;NDEBUG;_CRT_SECURE_NO_WARNINGS;MUSIC_WAV;MUSIC_FLAC_DRFLAC;MUSIC_MP3_MINIMP3;MUSIC_OGG;OGG_USE_STB;MUSIC_MID_TIMIDITY;%(PreprocessorDefinitions)
Console
diff --git a/VisualC-WinRT/SDL_mixer-UWP.vcxproj.filters b/VisualC-WinRT/SDL_mixer-UWP.vcxproj.filters
index 66fbd13af..4b602766b 100644
--- a/VisualC-WinRT/SDL_mixer-UWP.vcxproj.filters
+++ b/VisualC-WinRT/SDL_mixer-UWP.vcxproj.filters
@@ -61,9 +61,6 @@
Sources
-
- Sources
-
Sources
@@ -73,6 +70,9 @@
Sources
+
+ Sources
+
Sources
@@ -156,9 +156,6 @@
Sources
-
- Sources
-
Sources
@@ -168,6 +165,9 @@
Sources
+
+ Sources
+
Sources
@@ -207,4 +207,4 @@
{9c43d0b0-edae-4dea-bb19-5bd7972e58bc}
-
\ No newline at end of file
+
diff --git a/VisualC/SDL_mixer.vcxproj b/VisualC/SDL_mixer.vcxproj
index c3adae436..92de85f49 100644
--- a/VisualC/SDL_mixer.vcxproj
+++ b/VisualC/SDL_mixer.vcxproj
@@ -114,7 +114,7 @@
/D OGG_DYNAMIC=\"libvorbisfile-3.dll\" %(AdditionalOptions)
Disabled
..\include;..\src;..\src\codecs;..\src\codecs\timidity;..\src\codecs\native_midi;external\include;%(AdditionalIncludeDirectories)
- DLL_EXPORT;_DEBUG;WIN32;_WINDOWS;MUSIC_WAV;MUSIC_WAVPACK;MUSIC_FLAC_DRFLAC;MUSIC_MOD_XMP;XMP_DYNAMIC="libxmp.dll";MUSIC_MP3_DRMP3;MUSIC_OGG;OGG_USE_STB;MUSIC_OPUS;OPUS_DYNAMIC="libopusfile-0.dll";WAVPACK_DYNAMIC="libwavpack-1.dll";MUSIC_MID_TIMIDITY;MUSIC_MID_NATIVE
+ DLL_EXPORT;_DEBUG;WIN32;_WINDOWS;MUSIC_WAV;MUSIC_WAVPACK;MUSIC_FLAC_DRFLAC;MUSIC_MOD_XMP;XMP_DYNAMIC="libxmp.dll";MUSIC_MP3_MINIMP3;MUSIC_OGG;OGG_USE_STB;MUSIC_OPUS;OPUS_DYNAMIC="libopusfile-0.dll";WAVPACK_DYNAMIC="libwavpack-1.dll";MUSIC_MID_TIMIDITY;MUSIC_MID_NATIVE;MUSIC_GME;GME_DYNAMIC="libgme.dll"
MultiThreadedDLL
Level3
OldStyle
@@ -144,11 +144,10 @@
/D OGG_DYNAMIC=\"libvorbisfile-3.dll\" %(AdditionalOptions)
Disabled
..\include;..\src;..\src\codecs;..\src\codecs\timidity;..\src\codecs\native_midi;external\include;%(AdditionalIncludeDirectories)
- DLL_EXPORT;_DEBUG;WIN32;_WINDOWS;MUSIC_WAV;MUSIC_WAVPACK;MUSIC_FLAC_DRFLAC;MUSIC_MOD_XMP;XMP_DYNAMIC="libxmp.dll";MUSIC_MP3_DRMP3;MUSIC_OGG;OGG_USE_STB;MUSIC_OPUS;OPUS_DYNAMIC="libopusfile-0.dll";WAVPACK_DYNAMIC="libwavpack-1.dll";MUSIC_MID_TIMIDITY;MUSIC_MID_NATIVE
+ DLL_EXPORT;_DEBUG;WIN32;_WINDOWS;MUSIC_WAV;MUSIC_WAVPACK;MUSIC_FLAC_DRFLAC;MUSIC_MOD_XMP;XMP_DYNAMIC="libxmp.dll";MUSIC_MP3_MINIMP3;MUSIC_OGG;OGG_USE_STB;MUSIC_OPUS;OPUS_DYNAMIC="libopusfile-0.dll";WAVPACK_DYNAMIC="libwavpack-1.dll";MUSIC_MID_TIMIDITY;MUSIC_MID_NATIVE;MUSIC_GME;GME_DYNAMIC="libgme.dll"
MultiThreadedDLL
Level3
OldStyle
- StreamingSIMDExtensions
_DEBUG;%(PreprocessorDefinitions)
@@ -173,7 +172,7 @@
/D OGG_DYNAMIC=\"libvorbisfile-3.dll\" %(AdditionalOptions)
..\include;..\src;..\src\codecs;..\src\codecs\timidity;..\src\codecs\native_midi;external\include;%(AdditionalIncludeDirectories)
- DLL_EXPORT;NDEBUG;WIN32;_WINDOWS;_CRT_SECURE_NO_WARNINGS;MUSIC_WAVPACK;MUSIC_WAV;MUSIC_FLAC_DRFLAC;MUSIC_MOD_XMP;XMP_DYNAMIC="libxmp.dll";MUSIC_MP3_DRMP3;MUSIC_OGG;OGG_USE_STB;MUSIC_OPUS;OPUS_DYNAMIC="libopusfile-0.dll";WAVPACK_DYNAMIC="libwavpack-1.dll";MUSIC_MID_TIMIDITY;MUSIC_MID_NATIVE;%(PreprocessorDefinitions)
+ DLL_EXPORT;NDEBUG;WIN32;_WINDOWS;_CRT_SECURE_NO_WARNINGS;MUSIC_WAVPACK;MUSIC_WAV;MUSIC_FLAC_DRFLAC;MUSIC_MOD_XMP;XMP_DYNAMIC="libxmp.dll";MUSIC_MP3_MINIMP3;MUSIC_OGG;OGG_USE_STB;MUSIC_OPUS;OPUS_DYNAMIC="libopusfile-0.dll";WAVPACK_DYNAMIC="libwavpack-1.dll";MUSIC_MID_TIMIDITY;MUSIC_MID_NATIVE;MUSIC_GME;GME_DYNAMIC="libgme.dll";%(PreprocessorDefinitions)
MultiThreadedDLL
Level3
StreamingSIMDExtensions
@@ -200,10 +199,9 @@
/D OGG_DYNAMIC=\"libvorbisfile-3.dll\" %(AdditionalOptions)
..\include;..\src;..\src\codecs;..\src\codecs\timidity;..\src\codecs\native_midi;external\include;%(AdditionalIncludeDirectories)
- DLL_EXPORT;NDEBUG;WIN32;_WINDOWS;_CRT_SECURE_NO_WARNINGS;MUSIC_WAVPACK;MUSIC_WAV;MUSIC_FLAC_DRFLAC;MUSIC_MOD_XMP;XMP_DYNAMIC="libxmp.dll";MUSIC_MP3_DRMP3;MUSIC_OGG;OGG_USE_STB;MUSIC_OPUS;OPUS_DYNAMIC="libopusfile-0.dll";WAVPACK_DYNAMIC="libwavpack-1.dll";MUSIC_MID_TIMIDITY;MUSIC_MID_NATIVE;%(PreprocessorDefinitions)
+ DLL_EXPORT;NDEBUG;WIN32;_WINDOWS;_CRT_SECURE_NO_WARNINGS;MUSIC_WAVPACK;MUSIC_WAV;MUSIC_FLAC_DRFLAC;MUSIC_MOD_XMP;XMP_DYNAMIC="libxmp.dll";MUSIC_MP3_MINIMP3;MUSIC_OGG;OGG_USE_STB;MUSIC_OPUS;OPUS_DYNAMIC="libopusfile-0.dll";WAVPACK_DYNAMIC="libwavpack-1.dll";MUSIC_MID_TIMIDITY;MUSIC_MID_NATIVE;MUSIC_GME;GME_DYNAMIC="libgme.dll";%(PreprocessorDefinitions)
MultiThreadedDLL
Level3
- StreamingSIMDExtensions
NDEBUG;%(PreprocessorDefinitions)
@@ -225,10 +223,10 @@
-
+
@@ -449,10 +447,10 @@
-
+
@@ -464,7 +462,45 @@
+
+
+ Document
+ copy %(FullPath) $(SolutionDir)\$(Platform)\$(Configuration)\
+ copy %(FullPath) $(SolutionDir)\$(Platform)\$(Configuration)\
+ Copying %(Filename)%(Extension)
+ Copying %(Filename)%(Extension)
+ $(SolutionDir)\$(Platform)\$(Configuration)\%(Filename)%(Extension)
+ $(SolutionDir)\$(Platform)\$(Configuration)\%(Filename)%(Extension)
+
+
+ Document
+ copy %(FullPath) $(SolutionDir)\$(Platform)\$(Configuration)\
+ copy %(FullPath) $(SolutionDir)\$(Platform)\$(Configuration)\
+ Copying %(Filename)%(Extension)
+ Copying %(Filename)%(Extension)
+ $(SolutionDir)\$(Platform)\$(Configuration)\%(Filename)%(Extension)
+ $(SolutionDir)\$(Platform)\$(Configuration)\%(Filename)%(Extension)
+
+
+
+
+ copy %(FullPath) $(SolutionDir)\$(Platform)\$(Configuration)\
+ copy %(FullPath) $(SolutionDir)\$(Platform)\$(Configuration)\
+ Copying %(Filename)%(Extension)
+ Copying %(Filename)%(Extension)
+ $(SolutionDir)\$(Platform)\$(Configuration)\%(Filename)%(Extension)
+ $(SolutionDir)\$(Platform)\$(Configuration)\%(Filename)%(Extension)
+
+
+ copy %(FullPath) $(SolutionDir)\$(Platform)\$(Configuration)\
+ copy %(FullPath) $(SolutionDir)\$(Platform)\$(Configuration)\
+ Copying %(Filename)%(Extension)
+ Copying %(Filename)%(Extension)
+ $(SolutionDir)\$(Platform)\$(Configuration)\%(Filename)%(Extension)
+ $(SolutionDir)\$(Platform)\$(Configuration)\%(Filename)%(Extension)
+
+
-
+
\ No newline at end of file
diff --git a/VisualC/SDL_mixer.vcxproj.filters b/VisualC/SDL_mixer.vcxproj.filters
index c0c5a528f..b5bc971f5 100644
--- a/VisualC/SDL_mixer.vcxproj.filters
+++ b/VisualC/SDL_mixer.vcxproj.filters
@@ -31,9 +31,6 @@
Sources
-
- Sources
-
Sources
@@ -43,6 +40,9 @@
Sources
+
+ Sources
+
Sources
@@ -93,52 +93,43 @@
-
- x64
-
-
- x64
-
-
- x64
-
-
+
x64
-
- x64
+
+ x86
-
- x64
+
+ x86
-
- x64
+
+ x86
-
- x64
+
+ x86
-
+
x86
-
+
x86
-
+
x86
-
+
x86
-
+
x86
-
+
x86
-
+
x86
-
+
x86
@@ -176,9 +167,6 @@
Sources
-
- Sources
-
Sources
@@ -188,6 +176,9 @@
Sources
+
+ Sources
+
Sources
@@ -219,4 +210,39 @@
Sources
-
+
+
+ x64
+
+
+ x64
+
+
+ x64
+
+
+ x64
+
+
+ x64
+
+
+ x64
+
+
+ x64
+
+
+ x64
+
+
+ x64
+
+
+ x64
+
+
+ x64
+
+
+
\ No newline at end of file
diff --git a/VisualC/Version.rc b/VisualC/Version.rc
index a2a805821..bae085d81 100644
--- a/VisualC/Version.rc
+++ b/VisualC/Version.rc
@@ -28,8 +28,8 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
//
VS_VERSION_INFO VERSIONINFO
- FILEVERSION 2,7,1,0
- PRODUCTVERSION 2,7,1,0
+ FILEVERSION 2,8,0,0
+ PRODUCTVERSION 2,8,0,0
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x1L
@@ -46,12 +46,12 @@ BEGIN
BEGIN
VALUE "CompanyName", "\0"
VALUE "FileDescription", "SDL_mixer\0"
- VALUE "FileVersion", "2, 7, 1, 0\0"
+ VALUE "FileVersion", "2, 8, 0, 0\0"
VALUE "InternalName", "SDL_mixer\0"
VALUE "LegalCopyright", "Copyright (C) 2024 Sam Lantinga\0"
VALUE "OriginalFilename", "SDL_mixer.dll\0"
VALUE "ProductName", "Simple DirectMedia Layer\0"
- VALUE "ProductVersion", "2, 7, 1, 0\0"
+ VALUE "ProductVersion", "2, 8, 0, 0\0"
END
END
BLOCK "VarFileInfo"
diff --git a/VisualC/external/include/gme/gme.h b/VisualC/external/include/gme/gme.h
new file mode 100644
index 000000000..145f04a33
--- /dev/null
+++ b/VisualC/external/include/gme/gme.h
@@ -0,0 +1,302 @@
+/* Game music emulator library C interface (also usable from C++) */
+
+/* Game_Music_Emu 0.6.3 */
+#ifndef GME_H
+#define GME_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+#define GME_VERSION 0x000603 /* 1 byte major, 1 byte minor, 1 byte patch-level */
+
+/* Error string returned by library functions, or NULL if no error (success) */
+typedef const char* gme_err_t;
+
+/* First parameter of most gme_ functions is a pointer to the Music_Emu */
+typedef struct Music_Emu Music_Emu;
+
+
+/* Setup compiler defines useful for exporting required public API symbols in gme.cpp */
+#ifndef BLARGG_EXPORT
+ #if defined (_WIN32)
+ #if defined(BLARGG_BUILD_DLL)
+ #define BLARGG_EXPORT __declspec(dllexport)
+ #else
+ #define BLARGG_EXPORT /* Leave blank: friendly with both static and shared linking. */
+ #endif
+ #elif defined (LIBGME_VISIBILITY)
+ #define BLARGG_EXPORT __attribute__((visibility ("default")))
+ #else
+ #define BLARGG_EXPORT
+ #endif
+#endif
+
+
+/******** Basic operations ********/
+
+/* Create emulator and load game music file/data into it. Sets *out to new emulator. */
+BLARGG_EXPORT gme_err_t gme_open_file( const char path [], Music_Emu** out, int sample_rate );
+
+/* Number of tracks available */
+BLARGG_EXPORT int gme_track_count( Music_Emu const* );
+
+/* Start a track, where 0 is the first track */
+BLARGG_EXPORT gme_err_t gme_start_track( Music_Emu*, int index );
+
+/* Generate 'count' 16-bit signed samples info 'out'. Output is in stereo. */
+BLARGG_EXPORT gme_err_t gme_play( Music_Emu*, int count, short out [] );
+
+/* Finish using emulator and free memory */
+BLARGG_EXPORT void gme_delete( Music_Emu* );
+
+
+/******** Track position/length ********/
+
+/* Set time to start fading track out. Once fade ends track_ended() returns true.
+Fade time can be changed while track is playing. */
+BLARGG_EXPORT void gme_set_fade( Music_Emu*, int start_msec );
+
+/**
+ * If do_autoload_limit is nonzero, then automatically load track length
+ * metadata (if present) and terminate playback once the track length has been
+ * reached. Otherwise playback will continue for an arbitrary period of time
+ * until a prolonged period of silence is detected.
+ *
+ * Not all individual emulators support this setting.
+ *
+ * By default, playback limits are loaded and applied.
+ *
+ * @since 0.6.2
+ */
+BLARGG_EXPORT void gme_set_autoload_playback_limit( Music_Emu *, int do_autoload_limit );
+
+/** See gme_set_autoload_playback_limit.
+ * @since 0.6.2
+ */
+BLARGG_EXPORT int gme_autoload_playback_limit( Music_Emu const* );
+
+/* True if a track has reached its end */
+BLARGG_EXPORT int gme_track_ended( Music_Emu const* );
+
+/* Number of milliseconds (1000 = one second) played since beginning of track */
+BLARGG_EXPORT int gme_tell( Music_Emu const* );
+
+/* Number of samples generated since beginning of track */
+BLARGG_EXPORT int gme_tell_samples( Music_Emu const* );
+
+/* Seek to new time in track. Seeking backwards or far forward can take a while. */
+BLARGG_EXPORT gme_err_t gme_seek( Music_Emu*, int msec );
+
+/* Equivalent to restarting track then skipping n samples */
+BLARGG_EXPORT gme_err_t gme_seek_samples( Music_Emu*, int n );
+
+
+/******** Informational ********/
+
+/* If you only need track information from a music file, pass gme_info_only for
+sample_rate to open/load. */
+enum { gme_info_only = -1 };
+
+/* Most recent warning string, or NULL if none. Clears current warning after returning.
+Warning is also cleared when loading a file and starting a track. */
+BLARGG_EXPORT const char* gme_warning( Music_Emu* );
+
+/* Load m3u playlist file (must be done after loading music) */
+BLARGG_EXPORT gme_err_t gme_load_m3u( Music_Emu*, const char path [] );
+
+/* Clear any loaded m3u playlist and any internal playlist that the music format
+supports (NSFE for example). */
+BLARGG_EXPORT void gme_clear_playlist( Music_Emu* );
+
+/* Gets information for a particular track (length, name, author, etc.).
+Must be freed after use. */
+typedef struct gme_info_t gme_info_t;
+BLARGG_EXPORT gme_err_t gme_track_info( Music_Emu const*, gme_info_t** out, int track );
+
+/* Frees track information */
+BLARGG_EXPORT void gme_free_info( gme_info_t* );
+
+struct gme_info_t
+{
+ /* times in milliseconds; -1 if unknown */
+ int length; /* total length, if file specifies it */
+ int intro_length; /* length of song up to looping section */
+ int loop_length; /* length of looping section */
+
+ /* Length if available, otherwise intro_length+loop_length*2 if available,
+ otherwise a default of 150000 (2.5 minutes). */
+ int play_length;
+
+ int i4,i5,i6,i7,i8,i9,i10,i11,i12,i13,i14,i15; /* reserved */
+
+ /* empty string ("") if not available */
+ const char* system;
+ const char* game;
+ const char* song;
+ const char* author;
+ const char* copyright;
+ const char* comment;
+ const char* dumper;
+
+ const char *s7,*s8,*s9,*s10,*s11,*s12,*s13,*s14,*s15; /* reserved */
+};
+
+
+/******** Advanced playback ********/
+
+/* Adjust stereo echo depth, where 0.0 = off and 1.0 = maximum. Has no effect for
+GYM, SPC, and Sega Genesis VGM music */
+BLARGG_EXPORT void gme_set_stereo_depth( Music_Emu*, double depth );
+
+/* Disable automatic end-of-track detection and skipping of silence at beginning
+if ignore is true */
+BLARGG_EXPORT void gme_ignore_silence( Music_Emu*, int ignore );
+
+/* Adjust song tempo, where 1.0 = normal, 0.5 = half speed, 2.0 = double speed.
+Track length as returned by track_info() assumes a tempo of 1.0. */
+BLARGG_EXPORT void gme_set_tempo( Music_Emu*, double tempo );
+
+/* Number of voices used by currently loaded file */
+BLARGG_EXPORT int gme_voice_count( Music_Emu const* );
+
+/* Name of voice i, from 0 to gme_voice_count() - 1 */
+BLARGG_EXPORT const char* gme_voice_name( Music_Emu const*, int i );
+
+/* Mute/unmute voice i, where voice 0 is first voice */
+BLARGG_EXPORT void gme_mute_voice( Music_Emu*, int index, int mute );
+
+/* Set muting state of all voices at once using a bit mask, where -1 mutes all
+voices, 0 unmutes them all, 0x01 mutes just the first voice, etc. */
+BLARGG_EXPORT void gme_mute_voices( Music_Emu*, int muting_mask );
+
+/* Frequency equalizer parameters (see gme.txt) */
+/* Implementers: If modified, also adjust Music_Emu::make_equalizer as needed */
+typedef struct gme_equalizer_t
+{
+ double treble; /* -50.0 = muffled, 0 = flat, +5.0 = extra-crisp */
+ double bass; /* 1 = full bass, 90 = average, 16000 = almost no bass */
+
+ double d2,d3,d4,d5,d6,d7,d8,d9; /* reserved */
+} gme_equalizer_t;
+
+/* Get current frequency equalizater parameters */
+BLARGG_EXPORT void gme_equalizer( Music_Emu const*, gme_equalizer_t* out );
+
+/* Change frequency equalizer parameters */
+BLARGG_EXPORT void gme_set_equalizer( Music_Emu*, gme_equalizer_t const* eq );
+
+/* Enables/disables most accurate sound emulation options */
+BLARGG_EXPORT void gme_enable_accuracy( Music_Emu*, int enabled );
+
+
+/******** Game music types ********/
+
+/* Music file type identifier. Can also hold NULL. */
+typedef const struct gme_type_t_* gme_type_t;
+
+/* Emulator type constants for each supported file type */
+extern BLARGG_EXPORT const gme_type_t
+ gme_ay_type,
+ gme_gbs_type,
+ gme_gym_type,
+ gme_hes_type,
+ gme_kss_type,
+ gme_nsf_type,
+ gme_nsfe_type,
+ gme_sap_type,
+ gme_spc_type,
+ gme_vgm_type,
+ gme_vgz_type;
+
+/* Type of this emulator */
+BLARGG_EXPORT gme_type_t gme_type( Music_Emu const* );
+
+/* Pointer to array of all music types, with NULL entry at end. Allows a player linked
+to this library to support new music types without having to be updated. */
+BLARGG_EXPORT gme_type_t const* gme_type_list();
+
+/* Name of game system for this music file type */
+BLARGG_EXPORT const char* gme_type_system( gme_type_t );
+
+/* True if this music file type supports multiple tracks */
+BLARGG_EXPORT int gme_type_multitrack( gme_type_t );
+
+/* whether the pcm output retrieved by gme_play() will have all 8 voices rendered to their
+ * individual stereo channel or (if false) these voices get mixed into one single stereo channel
+ * @since 0.6.2 */
+BLARGG_EXPORT int gme_multi_channel( Music_Emu const* );
+
+/******** Advanced file loading ********/
+
+/* Error returned if file type is not supported */
+extern BLARGG_EXPORT const char* const gme_wrong_file_type;
+
+/* Same as gme_open_file(), but uses file data already in memory. Makes copy of data.
+ * The resulting Music_Emu object will be set to single channel mode. */
+BLARGG_EXPORT gme_err_t gme_open_data( void const* data, long size, Music_Emu** out, int sample_rate );
+
+/* Determine likely game music type based on first four bytes of file. Returns
+string containing proper file suffix (i.e. "NSF", "SPC", etc.) or "" if
+file header is not recognized. */
+BLARGG_EXPORT const char* gme_identify_header( void const* header );
+
+/* Get corresponding music type for file path or extension passed in. */
+BLARGG_EXPORT gme_type_t gme_identify_extension( const char path_or_extension [] );
+
+/**
+ * Get typical file extension for a given music type. This is not a replacement
+ * for a file content identification library (but see gme_identify_header).
+ *
+ * @since 0.6.2
+ */
+BLARGG_EXPORT const char* gme_type_extension( gme_type_t music_type );
+
+/* Determine file type based on file's extension or header (if extension isn't recognized).
+Sets *type_out to type, or 0 if unrecognized or error. */
+BLARGG_EXPORT gme_err_t gme_identify_file( const char path [], gme_type_t* type_out );
+
+/* Create new emulator and set sample rate. Returns NULL if out of memory. If you only need
+track information, pass gme_info_only for sample_rate. */
+BLARGG_EXPORT Music_Emu* gme_new_emu( gme_type_t, int sample_rate );
+
+/* Create new multichannel emulator and set sample rate. Returns NULL if out of memory.
+ * If you only need track information, pass gme_info_only for sample_rate.
+ * (see gme_multi_channel for more information on multichannel support)
+ * @since 0.6.2
+ */
+BLARGG_EXPORT Music_Emu* gme_new_emu_multi_channel( gme_type_t, int sample_rate );
+
+/* Load music file into emulator */
+BLARGG_EXPORT gme_err_t gme_load_file( Music_Emu*, const char path [] );
+
+/* Load music file from memory into emulator. Makes a copy of data passed. */
+BLARGG_EXPORT gme_err_t gme_load_data( Music_Emu*, void const* data, long size );
+
+/* Load music file using custom data reader function that will be called to
+read file data. Most emulators load the entire file in one read call. */
+typedef gme_err_t (*gme_reader_t)( void* your_data, void* out, int count );
+BLARGG_EXPORT gme_err_t gme_load_custom( Music_Emu*, gme_reader_t, long file_size, void* your_data );
+
+/* Load m3u playlist file from memory (must be done after loading music) */
+BLARGG_EXPORT gme_err_t gme_load_m3u_data( Music_Emu*, void const* data, long size );
+
+
+/******** User data ********/
+
+/* Set/get pointer to data you want to associate with this emulator.
+You can use this for whatever you want. */
+BLARGG_EXPORT void gme_set_user_data( Music_Emu*, void* new_user_data );
+BLARGG_EXPORT void* gme_user_data( Music_Emu const* );
+
+/* Register cleanup function to be called when deleting emulator, or NULL to
+clear it. Passes user_data to cleanup function. */
+typedef void (*gme_user_cleanup_t)( void* user_data );
+BLARGG_EXPORT void gme_set_user_cleanup( Music_Emu*, gme_user_cleanup_t func );
+
+
+#ifdef __cplusplus
+ }
+#endif
+
+#endif
diff --git a/VisualC/external/optional/x64/LICENSE.gme.txt b/VisualC/external/optional/x64/LICENSE.gme.txt
new file mode 100644
index 000000000..5faba9d48
--- /dev/null
+++ b/VisualC/external/optional/x64/LICENSE.gme.txt
@@ -0,0 +1,504 @@
+ GNU LESSER GENERAL PUBLIC LICENSE
+ Version 2.1, February 1999
+
+ Copyright (C) 1991, 1999 Free Software Foundation, Inc.
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+[This is the first released version of the Lesser GPL. It also counts
+ as the successor of the GNU Library Public License, version 2, hence
+ the version number 2.1.]
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+Licenses are intended to guarantee your freedom to share and change
+free software--to make sure the software is free for all its users.
+
+ This license, the Lesser General Public License, applies to some
+specially designated software packages--typically libraries--of the
+Free Software Foundation and other authors who decide to use it. You
+can use it too, but we suggest you first think carefully about whether
+this license or the ordinary General Public License is the better
+strategy to use in any particular case, based on the explanations below.
+
+ When we speak of free software, we are referring to freedom of use,
+not price. Our General Public Licenses are designed to make sure that
+you have the freedom to distribute copies of free software (and charge
+for this service if you wish); that you receive source code or can get
+it if you want it; that you can change the software and use pieces of
+it in new free programs; and that you are informed that you can do
+these things.
+
+ To protect your rights, we need to make restrictions that forbid
+distributors to deny you these rights or to ask you to surrender these
+rights. These restrictions translate to certain responsibilities for
+you if you distribute copies of the library or if you modify it.
+
+ For example, if you distribute copies of the library, whether gratis
+or for a fee, you must give the recipients all the rights that we gave
+you. You must make sure that they, too, receive or can get the source
+code. If you link other code with the library, you must provide
+complete object files to the recipients, so that they can relink them
+with the library after making changes to the library and recompiling
+it. And you must show them these terms so they know their rights.
+
+ We protect your rights with a two-step method: (1) we copyright the
+library, and (2) we offer you this license, which gives you legal
+permission to copy, distribute and/or modify the library.
+
+ To protect each distributor, we want to make it very clear that
+there is no warranty for the free library. Also, if the library is
+modified by someone else and passed on, the recipients should know
+that what they have is not the original version, so that the original
+author's reputation will not be affected by problems that might be
+introduced by others.
+
+ Finally, software patents pose a constant threat to the existence of
+any free program. We wish to make sure that a company cannot
+effectively restrict the users of a free program by obtaining a
+restrictive license from a patent holder. Therefore, we insist that
+any patent license obtained for a version of the library must be
+consistent with the full freedom of use specified in this license.
+
+ Most GNU software, including some libraries, is covered by the
+ordinary GNU General Public License. This license, the GNU Lesser
+General Public License, applies to certain designated libraries, and
+is quite different from the ordinary General Public License. We use
+this license for certain libraries in order to permit linking those
+libraries into non-free programs.
+
+ When a program is linked with a library, whether statically or using
+a shared library, the combination of the two is legally speaking a
+combined work, a derivative of the original library. The ordinary
+General Public License therefore permits such linking only if the
+entire combination fits its criteria of freedom. The Lesser General
+Public License permits more lax criteria for linking other code with
+the library.
+
+ We call this license the "Lesser" General Public License because it
+does Less to protect the user's freedom than the ordinary General
+Public License. It also provides other free software developers Less
+of an advantage over competing non-free programs. These disadvantages
+are the reason we use the ordinary General Public License for many
+libraries. However, the Lesser license provides advantages in certain
+special circumstances.
+
+ For example, on rare occasions, there may be a special need to
+encourage the widest possible use of a certain library, so that it becomes
+a de-facto standard. To achieve this, non-free programs must be
+allowed to use the library. A more frequent case is that a free
+library does the same job as widely used non-free libraries. In this
+case, there is little to gain by limiting the free library to free
+software only, so we use the Lesser General Public License.
+
+ In other cases, permission to use a particular library in non-free
+programs enables a greater number of people to use a large body of
+free software. For example, permission to use the GNU C Library in
+non-free programs enables many more people to use the whole GNU
+operating system, as well as its variant, the GNU/Linux operating
+system.
+
+ Although the Lesser General Public License is Less protective of the
+users' freedom, it does ensure that the user of a program that is
+linked with the Library has the freedom and the wherewithal to run
+that program using a modified version of the Library.
+
+ The precise terms and conditions for copying, distribution and
+modification follow. Pay close attention to the difference between a
+"work based on the library" and a "work that uses the library". The
+former contains code derived from the library, whereas the latter must
+be combined with the library in order to run.
+
+ GNU LESSER GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License Agreement applies to any software library or other
+program which contains a notice placed by the copyright holder or
+other authorized party saying it may be distributed under the terms of
+this Lesser General Public License (also called "this License").
+Each licensee is addressed as "you".
+
+ A "library" means a collection of software functions and/or data
+prepared so as to be conveniently linked with application programs
+(which use some of those functions and data) to form executables.
+
+ The "Library", below, refers to any such software library or work
+which has been distributed under these terms. A "work based on the
+Library" means either the Library or any derivative work under
+copyright law: that is to say, a work containing the Library or a
+portion of it, either verbatim or with modifications and/or translated
+straightforwardly into another language. (Hereinafter, translation is
+included without limitation in the term "modification".)
+
+ "Source code" for a work means the preferred form of the work for
+making modifications to it. For a library, complete source code means
+all the source code for all modules it contains, plus any associated
+interface definition files, plus the scripts used to control compilation
+and installation of the library.
+
+ Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running a program using the Library is not restricted, and output from
+such a program is covered only if its contents constitute a work based
+on the Library (independent of the use of the Library in a tool for
+writing it). Whether that is true depends on what the Library does
+and what the program that uses the Library does.
+
+ 1. You may copy and distribute verbatim copies of the Library's
+complete source code as you receive it, in any medium, provided that
+you conspicuously and appropriately publish on each copy an
+appropriate copyright notice and disclaimer of warranty; keep intact
+all the notices that refer to this License and to the absence of any
+warranty; and distribute a copy of this License along with the
+Library.
+
+ You may charge a fee for the physical act of transferring a copy,
+and you may at your option offer warranty protection in exchange for a
+fee.
+
+ 2. You may modify your copy or copies of the Library or any portion
+of it, thus forming a work based on the Library, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) The modified work must itself be a software library.
+
+ b) You must cause the files modified to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ c) You must cause the whole of the work to be licensed at no
+ charge to all third parties under the terms of this License.
+
+ d) If a facility in the modified Library refers to a function or a
+ table of data to be supplied by an application program that uses
+ the facility, other than as an argument passed when the facility
+ is invoked, then you must make a good faith effort to ensure that,
+ in the event an application does not supply such function or
+ table, the facility still operates, and performs whatever part of
+ its purpose remains meaningful.
+
+ (For example, a function in a library to compute square roots has
+ a purpose that is entirely well-defined independent of the
+ application. Therefore, Subsection 2d requires that any
+ application-supplied function or table used by this function must
+ be optional: if the application does not supply it, the square
+ root function must still compute square roots.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Library,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Library, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote
+it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Library.
+
+In addition, mere aggregation of another work not based on the Library
+with the Library (or with a work based on the Library) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may opt to apply the terms of the ordinary GNU General Public
+License instead of this License to a given copy of the Library. To do
+this, you must alter all the notices that refer to this License, so
+that they refer to the ordinary GNU General Public License, version 2,
+instead of to this License. (If a newer version than version 2 of the
+ordinary GNU General Public License has appeared, then you can specify
+that version instead if you wish.) Do not make any other change in
+these notices.
+
+ Once this change is made in a given copy, it is irreversible for
+that copy, so the ordinary GNU General Public License applies to all
+subsequent copies and derivative works made from that copy.
+
+ This option is useful when you wish to copy part of the code of
+the Library into a program that is not a library.
+
+ 4. You may copy and distribute the Library (or a portion or
+derivative of it, under Section 2) in object code or executable form
+under the terms of Sections 1 and 2 above provided that you accompany
+it with the complete corresponding machine-readable source code, which
+must be distributed under the terms of Sections 1 and 2 above on a
+medium customarily used for software interchange.
+
+ If distribution of object code is made by offering access to copy
+from a designated place, then offering equivalent access to copy the
+source code from the same place satisfies the requirement to
+distribute the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 5. A program that contains no derivative of any portion of the
+Library, but is designed to work with the Library by being compiled or
+linked with it, is called a "work that uses the Library". Such a
+work, in isolation, is not a derivative work of the Library, and
+therefore falls outside the scope of this License.
+
+ However, linking a "work that uses the Library" with the Library
+creates an executable that is a derivative of the Library (because it
+contains portions of the Library), rather than a "work that uses the
+library". The executable is therefore covered by this License.
+Section 6 states terms for distribution of such executables.
+
+ When a "work that uses the Library" uses material from a header file
+that is part of the Library, the object code for the work may be a
+derivative work of the Library even though the source code is not.
+Whether this is true is especially significant if the work can be
+linked without the Library, or if the work is itself a library. The
+threshold for this to be true is not precisely defined by law.
+
+ If such an object file uses only numerical parameters, data
+structure layouts and accessors, and small macros and small inline
+functions (ten lines or less in length), then the use of the object
+file is unrestricted, regardless of whether it is legally a derivative
+work. (Executables containing this object code plus portions of the
+Library will still fall under Section 6.)
+
+ Otherwise, if the work is a derivative of the Library, you may
+distribute the object code for the work under the terms of Section 6.
+Any executables containing that work also fall under Section 6,
+whether or not they are linked directly with the Library itself.
+
+ 6. As an exception to the Sections above, you may also combine or
+link a "work that uses the Library" with the Library to produce a
+work containing portions of the Library, and distribute that work
+under terms of your choice, provided that the terms permit
+modification of the work for the customer's own use and reverse
+engineering for debugging such modifications.
+
+ You must give prominent notice with each copy of the work that the
+Library is used in it and that the Library and its use are covered by
+this License. You must supply a copy of this License. If the work
+during execution displays copyright notices, you must include the
+copyright notice for the Library among them, as well as a reference
+directing the user to the copy of this License. Also, you must do one
+of these things:
+
+ a) Accompany the work with the complete corresponding
+ machine-readable source code for the Library including whatever
+ changes were used in the work (which must be distributed under
+ Sections 1 and 2 above); and, if the work is an executable linked
+ with the Library, with the complete machine-readable "work that
+ uses the Library", as object code and/or source code, so that the
+ user can modify the Library and then relink to produce a modified
+ executable containing the modified Library. (It is understood
+ that the user who changes the contents of definitions files in the
+ Library will not necessarily be able to recompile the application
+ to use the modified definitions.)
+
+ b) Use a suitable shared library mechanism for linking with the
+ Library. A suitable mechanism is one that (1) uses at run time a
+ copy of the library already present on the user's computer system,
+ rather than copying library functions into the executable, and (2)
+ will operate properly with a modified version of the library, if
+ the user installs one, as long as the modified version is
+ interface-compatible with the version that the work was made with.
+
+ c) Accompany the work with a written offer, valid for at
+ least three years, to give the same user the materials
+ specified in Subsection 6a, above, for a charge no more
+ than the cost of performing this distribution.
+
+ d) If distribution of the work is made by offering access to copy
+ from a designated place, offer equivalent access to copy the above
+ specified materials from the same place.
+
+ e) Verify that the user has already received a copy of these
+ materials or that you have already sent this user a copy.
+
+ For an executable, the required form of the "work that uses the
+Library" must include any data and utility programs needed for
+reproducing the executable from it. However, as a special exception,
+the materials to be distributed need not include anything that is
+normally distributed (in either source or binary form) with the major
+components (compiler, kernel, and so on) of the operating system on
+which the executable runs, unless that component itself accompanies
+the executable.
+
+ It may happen that this requirement contradicts the license
+restrictions of other proprietary libraries that do not normally
+accompany the operating system. Such a contradiction means you cannot
+use both them and the Library together in an executable that you
+distribute.
+
+ 7. You may place library facilities that are a work based on the
+Library side-by-side in a single library together with other library
+facilities not covered by this License, and distribute such a combined
+library, provided that the separate distribution of the work based on
+the Library and of the other library facilities is otherwise
+permitted, and provided that you do these two things:
+
+ a) Accompany the combined library with a copy of the same work
+ based on the Library, uncombined with any other library
+ facilities. This must be distributed under the terms of the
+ Sections above.
+
+ b) Give prominent notice with the combined library of the fact
+ that part of it is a work based on the Library, and explaining
+ where to find the accompanying uncombined form of the same work.
+
+ 8. You may not copy, modify, sublicense, link with, or distribute
+the Library except as expressly provided under this License. Any
+attempt otherwise to copy, modify, sublicense, link with, or
+distribute the Library is void, and will automatically terminate your
+rights under this License. However, parties who have received copies,
+or rights, from you under this License will not have their licenses
+terminated so long as such parties remain in full compliance.
+
+ 9. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Library or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Library (or any work based on the
+Library), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Library or works based on it.
+
+ 10. Each time you redistribute the Library (or any work based on the
+Library), the recipient automatically receives a license from the
+original licensor to copy, distribute, link with or modify the Library
+subject to these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties with
+this License.
+
+ 11. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Library at all. For example, if a patent
+license would not permit royalty-free redistribution of the Library by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Library.
+
+If any portion of this section is held invalid or unenforceable under any
+particular circumstance, the balance of the section is intended to apply,
+and the section as a whole is intended to apply in other circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 12. If the distribution and/or use of the Library is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Library under this License may add
+an explicit geographical distribution limitation excluding those countries,
+so that distribution is permitted only in or among countries not thus
+excluded. In such case, this License incorporates the limitation as if
+written in the body of this License.
+
+ 13. The Free Software Foundation may publish revised and/or new
+versions of the Lesser General Public License from time to time.
+Such new versions will be similar in spirit to the present version,
+but may differ in detail to address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Library
+specifies a version number of this License which applies to it and
+"any later version", you have the option of following the terms and
+conditions either of that version or of any later version published by
+the Free Software Foundation. If the Library does not specify a
+license version number, you may choose any version ever published by
+the Free Software Foundation.
+
+ 14. If you wish to incorporate parts of the Library into other free
+programs whose distribution conditions are incompatible with these,
+write to the author to ask for permission. For software which is
+copyrighted by the Free Software Foundation, write to the Free
+Software Foundation; we sometimes make exceptions for this. Our
+decision will be guided by the two goals of preserving the free status
+of all derivatives of our free software and of promoting the sharing
+and reuse of software generally.
+
+ NO WARRANTY
+
+ 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
+WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
+EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
+OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
+KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
+LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
+THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+ 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
+WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
+AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
+FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
+CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
+LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
+RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
+FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
+SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Libraries
+
+ If you develop a new library, and you want it to be of the greatest
+possible use to the public, we recommend making it free software that
+everyone can redistribute and change. You can do so by permitting
+redistribution under these terms (or, alternatively, under the terms of the
+ordinary General Public License).
+
+ To apply these terms, attach the following notices to the library. It is
+safest to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least the
+"copyright" line and a pointer to where the full notice is found.
+
+
+ Copyright (C)
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+Also add information on how to contact you by electronic and paper mail.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the library, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the
+ library `Frob' (a library for tweaking knobs) written by James Random Hacker.
+
+ , 1 April 1990
+ Ty Coon, President of Vice
+
+That's all there is to it!
+
+
diff --git a/VisualC/external/optional/x64/libgme.dll b/VisualC/external/optional/x64/libgme.dll
new file mode 100644
index 000000000..b65a191d3
Binary files /dev/null and b/VisualC/external/optional/x64/libgme.dll differ
diff --git a/VisualC/external/optional/x86/LICENSE.gme.txt b/VisualC/external/optional/x86/LICENSE.gme.txt
new file mode 100644
index 000000000..5faba9d48
--- /dev/null
+++ b/VisualC/external/optional/x86/LICENSE.gme.txt
@@ -0,0 +1,504 @@
+ GNU LESSER GENERAL PUBLIC LICENSE
+ Version 2.1, February 1999
+
+ Copyright (C) 1991, 1999 Free Software Foundation, Inc.
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+[This is the first released version of the Lesser GPL. It also counts
+ as the successor of the GNU Library Public License, version 2, hence
+ the version number 2.1.]
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+Licenses are intended to guarantee your freedom to share and change
+free software--to make sure the software is free for all its users.
+
+ This license, the Lesser General Public License, applies to some
+specially designated software packages--typically libraries--of the
+Free Software Foundation and other authors who decide to use it. You
+can use it too, but we suggest you first think carefully about whether
+this license or the ordinary General Public License is the better
+strategy to use in any particular case, based on the explanations below.
+
+ When we speak of free software, we are referring to freedom of use,
+not price. Our General Public Licenses are designed to make sure that
+you have the freedom to distribute copies of free software (and charge
+for this service if you wish); that you receive source code or can get
+it if you want it; that you can change the software and use pieces of
+it in new free programs; and that you are informed that you can do
+these things.
+
+ To protect your rights, we need to make restrictions that forbid
+distributors to deny you these rights or to ask you to surrender these
+rights. These restrictions translate to certain responsibilities for
+you if you distribute copies of the library or if you modify it.
+
+ For example, if you distribute copies of the library, whether gratis
+or for a fee, you must give the recipients all the rights that we gave
+you. You must make sure that they, too, receive or can get the source
+code. If you link other code with the library, you must provide
+complete object files to the recipients, so that they can relink them
+with the library after making changes to the library and recompiling
+it. And you must show them these terms so they know their rights.
+
+ We protect your rights with a two-step method: (1) we copyright the
+library, and (2) we offer you this license, which gives you legal
+permission to copy, distribute and/or modify the library.
+
+ To protect each distributor, we want to make it very clear that
+there is no warranty for the free library. Also, if the library is
+modified by someone else and passed on, the recipients should know
+that what they have is not the original version, so that the original
+author's reputation will not be affected by problems that might be
+introduced by others.
+
+ Finally, software patents pose a constant threat to the existence of
+any free program. We wish to make sure that a company cannot
+effectively restrict the users of a free program by obtaining a
+restrictive license from a patent holder. Therefore, we insist that
+any patent license obtained for a version of the library must be
+consistent with the full freedom of use specified in this license.
+
+ Most GNU software, including some libraries, is covered by the
+ordinary GNU General Public License. This license, the GNU Lesser
+General Public License, applies to certain designated libraries, and
+is quite different from the ordinary General Public License. We use
+this license for certain libraries in order to permit linking those
+libraries into non-free programs.
+
+ When a program is linked with a library, whether statically or using
+a shared library, the combination of the two is legally speaking a
+combined work, a derivative of the original library. The ordinary
+General Public License therefore permits such linking only if the
+entire combination fits its criteria of freedom. The Lesser General
+Public License permits more lax criteria for linking other code with
+the library.
+
+ We call this license the "Lesser" General Public License because it
+does Less to protect the user's freedom than the ordinary General
+Public License. It also provides other free software developers Less
+of an advantage over competing non-free programs. These disadvantages
+are the reason we use the ordinary General Public License for many
+libraries. However, the Lesser license provides advantages in certain
+special circumstances.
+
+ For example, on rare occasions, there may be a special need to
+encourage the widest possible use of a certain library, so that it becomes
+a de-facto standard. To achieve this, non-free programs must be
+allowed to use the library. A more frequent case is that a free
+library does the same job as widely used non-free libraries. In this
+case, there is little to gain by limiting the free library to free
+software only, so we use the Lesser General Public License.
+
+ In other cases, permission to use a particular library in non-free
+programs enables a greater number of people to use a large body of
+free software. For example, permission to use the GNU C Library in
+non-free programs enables many more people to use the whole GNU
+operating system, as well as its variant, the GNU/Linux operating
+system.
+
+ Although the Lesser General Public License is Less protective of the
+users' freedom, it does ensure that the user of a program that is
+linked with the Library has the freedom and the wherewithal to run
+that program using a modified version of the Library.
+
+ The precise terms and conditions for copying, distribution and
+modification follow. Pay close attention to the difference between a
+"work based on the library" and a "work that uses the library". The
+former contains code derived from the library, whereas the latter must
+be combined with the library in order to run.
+
+ GNU LESSER GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License Agreement applies to any software library or other
+program which contains a notice placed by the copyright holder or
+other authorized party saying it may be distributed under the terms of
+this Lesser General Public License (also called "this License").
+Each licensee is addressed as "you".
+
+ A "library" means a collection of software functions and/or data
+prepared so as to be conveniently linked with application programs
+(which use some of those functions and data) to form executables.
+
+ The "Library", below, refers to any such software library or work
+which has been distributed under these terms. A "work based on the
+Library" means either the Library or any derivative work under
+copyright law: that is to say, a work containing the Library or a
+portion of it, either verbatim or with modifications and/or translated
+straightforwardly into another language. (Hereinafter, translation is
+included without limitation in the term "modification".)
+
+ "Source code" for a work means the preferred form of the work for
+making modifications to it. For a library, complete source code means
+all the source code for all modules it contains, plus any associated
+interface definition files, plus the scripts used to control compilation
+and installation of the library.
+
+ Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running a program using the Library is not restricted, and output from
+such a program is covered only if its contents constitute a work based
+on the Library (independent of the use of the Library in a tool for
+writing it). Whether that is true depends on what the Library does
+and what the program that uses the Library does.
+
+ 1. You may copy and distribute verbatim copies of the Library's
+complete source code as you receive it, in any medium, provided that
+you conspicuously and appropriately publish on each copy an
+appropriate copyright notice and disclaimer of warranty; keep intact
+all the notices that refer to this License and to the absence of any
+warranty; and distribute a copy of this License along with the
+Library.
+
+ You may charge a fee for the physical act of transferring a copy,
+and you may at your option offer warranty protection in exchange for a
+fee.
+
+ 2. You may modify your copy or copies of the Library or any portion
+of it, thus forming a work based on the Library, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) The modified work must itself be a software library.
+
+ b) You must cause the files modified to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ c) You must cause the whole of the work to be licensed at no
+ charge to all third parties under the terms of this License.
+
+ d) If a facility in the modified Library refers to a function or a
+ table of data to be supplied by an application program that uses
+ the facility, other than as an argument passed when the facility
+ is invoked, then you must make a good faith effort to ensure that,
+ in the event an application does not supply such function or
+ table, the facility still operates, and performs whatever part of
+ its purpose remains meaningful.
+
+ (For example, a function in a library to compute square roots has
+ a purpose that is entirely well-defined independent of the
+ application. Therefore, Subsection 2d requires that any
+ application-supplied function or table used by this function must
+ be optional: if the application does not supply it, the square
+ root function must still compute square roots.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Library,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Library, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote
+it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Library.
+
+In addition, mere aggregation of another work not based on the Library
+with the Library (or with a work based on the Library) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may opt to apply the terms of the ordinary GNU General Public
+License instead of this License to a given copy of the Library. To do
+this, you must alter all the notices that refer to this License, so
+that they refer to the ordinary GNU General Public License, version 2,
+instead of to this License. (If a newer version than version 2 of the
+ordinary GNU General Public License has appeared, then you can specify
+that version instead if you wish.) Do not make any other change in
+these notices.
+
+ Once this change is made in a given copy, it is irreversible for
+that copy, so the ordinary GNU General Public License applies to all
+subsequent copies and derivative works made from that copy.
+
+ This option is useful when you wish to copy part of the code of
+the Library into a program that is not a library.
+
+ 4. You may copy and distribute the Library (or a portion or
+derivative of it, under Section 2) in object code or executable form
+under the terms of Sections 1 and 2 above provided that you accompany
+it with the complete corresponding machine-readable source code, which
+must be distributed under the terms of Sections 1 and 2 above on a
+medium customarily used for software interchange.
+
+ If distribution of object code is made by offering access to copy
+from a designated place, then offering equivalent access to copy the
+source code from the same place satisfies the requirement to
+distribute the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 5. A program that contains no derivative of any portion of the
+Library, but is designed to work with the Library by being compiled or
+linked with it, is called a "work that uses the Library". Such a
+work, in isolation, is not a derivative work of the Library, and
+therefore falls outside the scope of this License.
+
+ However, linking a "work that uses the Library" with the Library
+creates an executable that is a derivative of the Library (because it
+contains portions of the Library), rather than a "work that uses the
+library". The executable is therefore covered by this License.
+Section 6 states terms for distribution of such executables.
+
+ When a "work that uses the Library" uses material from a header file
+that is part of the Library, the object code for the work may be a
+derivative work of the Library even though the source code is not.
+Whether this is true is especially significant if the work can be
+linked without the Library, or if the work is itself a library. The
+threshold for this to be true is not precisely defined by law.
+
+ If such an object file uses only numerical parameters, data
+structure layouts and accessors, and small macros and small inline
+functions (ten lines or less in length), then the use of the object
+file is unrestricted, regardless of whether it is legally a derivative
+work. (Executables containing this object code plus portions of the
+Library will still fall under Section 6.)
+
+ Otherwise, if the work is a derivative of the Library, you may
+distribute the object code for the work under the terms of Section 6.
+Any executables containing that work also fall under Section 6,
+whether or not they are linked directly with the Library itself.
+
+ 6. As an exception to the Sections above, you may also combine or
+link a "work that uses the Library" with the Library to produce a
+work containing portions of the Library, and distribute that work
+under terms of your choice, provided that the terms permit
+modification of the work for the customer's own use and reverse
+engineering for debugging such modifications.
+
+ You must give prominent notice with each copy of the work that the
+Library is used in it and that the Library and its use are covered by
+this License. You must supply a copy of this License. If the work
+during execution displays copyright notices, you must include the
+copyright notice for the Library among them, as well as a reference
+directing the user to the copy of this License. Also, you must do one
+of these things:
+
+ a) Accompany the work with the complete corresponding
+ machine-readable source code for the Library including whatever
+ changes were used in the work (which must be distributed under
+ Sections 1 and 2 above); and, if the work is an executable linked
+ with the Library, with the complete machine-readable "work that
+ uses the Library", as object code and/or source code, so that the
+ user can modify the Library and then relink to produce a modified
+ executable containing the modified Library. (It is understood
+ that the user who changes the contents of definitions files in the
+ Library will not necessarily be able to recompile the application
+ to use the modified definitions.)
+
+ b) Use a suitable shared library mechanism for linking with the
+ Library. A suitable mechanism is one that (1) uses at run time a
+ copy of the library already present on the user's computer system,
+ rather than copying library functions into the executable, and (2)
+ will operate properly with a modified version of the library, if
+ the user installs one, as long as the modified version is
+ interface-compatible with the version that the work was made with.
+
+ c) Accompany the work with a written offer, valid for at
+ least three years, to give the same user the materials
+ specified in Subsection 6a, above, for a charge no more
+ than the cost of performing this distribution.
+
+ d) If distribution of the work is made by offering access to copy
+ from a designated place, offer equivalent access to copy the above
+ specified materials from the same place.
+
+ e) Verify that the user has already received a copy of these
+ materials or that you have already sent this user a copy.
+
+ For an executable, the required form of the "work that uses the
+Library" must include any data and utility programs needed for
+reproducing the executable from it. However, as a special exception,
+the materials to be distributed need not include anything that is
+normally distributed (in either source or binary form) with the major
+components (compiler, kernel, and so on) of the operating system on
+which the executable runs, unless that component itself accompanies
+the executable.
+
+ It may happen that this requirement contradicts the license
+restrictions of other proprietary libraries that do not normally
+accompany the operating system. Such a contradiction means you cannot
+use both them and the Library together in an executable that you
+distribute.
+
+ 7. You may place library facilities that are a work based on the
+Library side-by-side in a single library together with other library
+facilities not covered by this License, and distribute such a combined
+library, provided that the separate distribution of the work based on
+the Library and of the other library facilities is otherwise
+permitted, and provided that you do these two things:
+
+ a) Accompany the combined library with a copy of the same work
+ based on the Library, uncombined with any other library
+ facilities. This must be distributed under the terms of the
+ Sections above.
+
+ b) Give prominent notice with the combined library of the fact
+ that part of it is a work based on the Library, and explaining
+ where to find the accompanying uncombined form of the same work.
+
+ 8. You may not copy, modify, sublicense, link with, or distribute
+the Library except as expressly provided under this License. Any
+attempt otherwise to copy, modify, sublicense, link with, or
+distribute the Library is void, and will automatically terminate your
+rights under this License. However, parties who have received copies,
+or rights, from you under this License will not have their licenses
+terminated so long as such parties remain in full compliance.
+
+ 9. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Library or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Library (or any work based on the
+Library), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Library or works based on it.
+
+ 10. Each time you redistribute the Library (or any work based on the
+Library), the recipient automatically receives a license from the
+original licensor to copy, distribute, link with or modify the Library
+subject to these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties with
+this License.
+
+ 11. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Library at all. For example, if a patent
+license would not permit royalty-free redistribution of the Library by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Library.
+
+If any portion of this section is held invalid or unenforceable under any
+particular circumstance, the balance of the section is intended to apply,
+and the section as a whole is intended to apply in other circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 12. If the distribution and/or use of the Library is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Library under this License may add
+an explicit geographical distribution limitation excluding those countries,
+so that distribution is permitted only in or among countries not thus
+excluded. In such case, this License incorporates the limitation as if
+written in the body of this License.
+
+ 13. The Free Software Foundation may publish revised and/or new
+versions of the Lesser General Public License from time to time.
+Such new versions will be similar in spirit to the present version,
+but may differ in detail to address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Library
+specifies a version number of this License which applies to it and
+"any later version", you have the option of following the terms and
+conditions either of that version or of any later version published by
+the Free Software Foundation. If the Library does not specify a
+license version number, you may choose any version ever published by
+the Free Software Foundation.
+
+ 14. If you wish to incorporate parts of the Library into other free
+programs whose distribution conditions are incompatible with these,
+write to the author to ask for permission. For software which is
+copyrighted by the Free Software Foundation, write to the Free
+Software Foundation; we sometimes make exceptions for this. Our
+decision will be guided by the two goals of preserving the free status
+of all derivatives of our free software and of promoting the sharing
+and reuse of software generally.
+
+ NO WARRANTY
+
+ 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
+WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
+EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
+OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
+KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
+LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
+THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+ 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
+WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
+AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
+FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
+CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
+LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
+RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
+FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
+SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Libraries
+
+ If you develop a new library, and you want it to be of the greatest
+possible use to the public, we recommend making it free software that
+everyone can redistribute and change. You can do so by permitting
+redistribution under these terms (or, alternatively, under the terms of the
+ordinary General Public License).
+
+ To apply these terms, attach the following notices to the library. It is
+safest to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least the
+"copyright" line and a pointer to where the full notice is found.
+
+
+ Copyright (C)
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+Also add information on how to contact you by electronic and paper mail.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the library, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the
+ library `Frob' (a library for tweaking knobs) written by James Random Hacker.
+
+ , 1 April 1990
+ Ty Coon, President of Vice
+
+That's all there is to it!
+
+
diff --git a/VisualC/external/optional/x86/libgme.dll b/VisualC/external/optional/x86/libgme.dll
new file mode 100644
index 000000000..cfb9cd3c0
Binary files /dev/null and b/VisualC/external/optional/x86/libgme.dll differ
diff --git a/VisualC/pkg-support/cmake/sdl2_mixer-config.cmake b/VisualC/pkg-support/cmake/sdl2_mixer-config.cmake
index c3a3f8c4e..ca5277602 100644
--- a/VisualC/pkg-support/cmake/sdl2_mixer-config.cmake
+++ b/VisualC/pkg-support/cmake/sdl2_mixer-config.cmake
@@ -26,7 +26,7 @@ set(SDL2MIXER_MOD_XMP FALSE)
set(SDL2MIXER_MOD_XMP_LITE FALSE)
set(SDL2MIXER_MP3 TRUE)
-set(SDL2MIXER_MP3_DRMP3 TRUE)
+set(SDL2MIXER_MP3_MINIMP3 TRUE)
set(SDL2MIXER_MP3_MPG123 FALSE)
set(SDL2MIXER_MIDI TRUE)
diff --git a/Xcode/Info-Framework.plist b/Xcode/Info-Framework.plist
index 84aae2c5e..e507fd561 100644
--- a/Xcode/Info-Framework.plist
+++ b/Xcode/Info-Framework.plist
@@ -15,8 +15,8 @@
CFBundlePackageType
FMWK
CFBundleShortVersionString
- 2.7.1
+ 2.8.0
CFBundleVersion
- 2.7.1
+ 2.8.0
diff --git a/Xcode/SDL_mixer.xcodeproj/project.pbxproj b/Xcode/SDL_mixer.xcodeproj/project.pbxproj
index 2c868bd05..b46c970fe 100644
--- a/Xcode/SDL_mixer.xcodeproj/project.pbxproj
+++ b/Xcode/SDL_mixer.xcodeproj/project.pbxproj
@@ -58,11 +58,11 @@
F30240642881DF95002F32D6 /* music_xmp.h in Headers */ = {isa = PBXBuildFile; fileRef = F302405F2881DF94002F32D6 /* music_xmp.h */; };
F30240652881DF95002F32D6 /* music_xmp.c in Sources */ = {isa = PBXBuildFile; fileRef = F30240622881DF95002F32D6 /* music_xmp.c */; };
F30240662881DF95002F32D6 /* music_xmp.c in Sources */ = {isa = PBXBuildFile; fileRef = F30240622881DF95002F32D6 /* music_xmp.c */; };
+ F307A4E52B546F710012534B /* music_minimp3.c in Sources */ = {isa = PBXBuildFile; fileRef = F307A4E32B546F710012534B /* music_minimp3.c */; };
+ F307A4E62B546F710012534B /* music_minimp3.c in Sources */ = {isa = PBXBuildFile; fileRef = F307A4E32B546F710012534B /* music_minimp3.c */; };
+ F307A4E72B546F710012534B /* music_minimp3.h in Headers */ = {isa = PBXBuildFile; fileRef = F307A4E42B546F710012534B /* music_minimp3.h */; };
+ F307A4E82B546F710012534B /* music_minimp3.h in Headers */ = {isa = PBXBuildFile; fileRef = F307A4E42B546F710012534B /* music_minimp3.h */; };
F3249B39285C448100DB9B5C /* CMake in Resources */ = {isa = PBXBuildFile; fileRef = F3249B36285C448100DB9B5C /* CMake */; };
- F37A8D2D2838924900C38E95 /* music_drmp3.h in Headers */ = {isa = PBXBuildFile; fileRef = F37A8D2B2838924900C38E95 /* music_drmp3.h */; };
- F37A8D2E2838924900C38E95 /* music_drmp3.h in Headers */ = {isa = PBXBuildFile; fileRef = F37A8D2B2838924900C38E95 /* music_drmp3.h */; };
- F37A8D2F2838924900C38E95 /* music_drmp3.c in Sources */ = {isa = PBXBuildFile; fileRef = F37A8D2C2838924900C38E95 /* music_drmp3.c */; };
- F37A8D302838924900C38E95 /* music_drmp3.c in Sources */ = {isa = PBXBuildFile; fileRef = F37A8D2C2838924900C38E95 /* music_drmp3.c */; };
F37A8D4A2838A23400C38E95 /* music_drflac.h in Headers */ = {isa = PBXBuildFile; fileRef = F37A8D412838A23400C38E95 /* music_drflac.h */; };
F37A8D4B2838A23400C38E95 /* music_drflac.h in Headers */ = {isa = PBXBuildFile; fileRef = F37A8D412838A23400C38E95 /* music_drflac.h */; };
F37A8D502838A23400C38E95 /* music_drflac.c in Sources */ = {isa = PBXBuildFile; fileRef = F37A8D492838A23400C38E95 /* music_drflac.c */; };
@@ -121,6 +121,20 @@
remoteGlobalIDString = BE1FA8B407AF96B2004B6283;
remoteInfo = Framework;
};
+ F307A4732B544C0F0012534B /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = F307A46E2B544C0F0012534B /* gme.xcodeproj */;
+ proxyType = 2;
+ remoteGlobalIDString = F3F70EDA281F61B4005AA27D;
+ remoteInfo = gme;
+ };
+ F307A47A2B544C1A0012534B /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = F307A4752B544C1A0012534B /* wavpack.xcodeproj */;
+ proxyType = 2;
+ remoteGlobalIDString = F3968A21281F704800661875;
+ remoteInfo = wavpack;
+ };
F3968B96281F817E00661875 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = F3968B90281F817E00661875 /* opus.xcodeproj */;
@@ -186,9 +200,11 @@
BE1FA95807AF96B3004B6283 /* Create DMG */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = "Create DMG"; sourceTree = BUILT_PRODUCTS_DIR; };
F302405F2881DF94002F32D6 /* music_xmp.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = music_xmp.h; sourceTree = ""; };
F30240622881DF95002F32D6 /* music_xmp.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = music_xmp.c; sourceTree = ""; };
+ F307A46E2B544C0F0012534B /* gme.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = gme.xcodeproj; path = gme/gme.xcodeproj; sourceTree = ""; };
+ F307A4752B544C1A0012534B /* wavpack.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = wavpack.xcodeproj; path = wavpack/wavpack.xcodeproj; sourceTree = ""; };
+ F307A4E32B546F710012534B /* music_minimp3.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = music_minimp3.c; sourceTree = ""; };
+ F307A4E42B546F710012534B /* music_minimp3.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = music_minimp3.h; sourceTree = ""; };
F3249B36285C448100DB9B5C /* CMake */ = {isa = PBXFileReference; lastKnownFileType = folder; path = CMake; sourceTree = ""; };
- F37A8D2B2838924900C38E95 /* music_drmp3.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = music_drmp3.h; sourceTree = ""; };
- F37A8D2C2838924900C38E95 /* music_drmp3.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = music_drmp3.c; sourceTree = ""; };
F37A8D412838A23400C38E95 /* music_drflac.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = music_drflac.h; sourceTree = ""; };
F37A8D492838A23400C38E95 /* music_drflac.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = music_drflac.c; sourceTree = ""; };
F37A8DB42838AD1200C38E95 /* music_ogg_stb.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = music_ogg_stb.c; sourceTree = ""; };
@@ -198,7 +214,7 @@
F3D87C0A281DFAD4005DA540 /* AudioUnit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AudioUnit.framework; path = System/Library/Frameworks/AudioUnit.framework; sourceTree = SDKROOT; };
F3D87C0C281DFADB005DA540 /* CoreServices.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreServices.framework; path = System/Library/Frameworks/CoreServices.framework; sourceTree = SDKROOT; };
F3D87C0E281DFB02005DA540 /* SDL2.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SDL2.framework; path = macOS/SDL2.framework; sourceTree = ""; };
- F3E29D022882107B0006D108 /* xmp.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = "xmp.xcodeproj"; path = "xmp/xmp.xcodeproj"; sourceTree = ""; };
+ F3E29D022882107B0006D108 /* xmp.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = xmp.xcodeproj; path = xmp/xmp.xcodeproj; sourceTree = ""; };
F51BFB0101F724BE01D3D55B /* native_midi.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = native_midi.h; sourceTree = ""; };
F59C710300D5CB5801000001 /* ReadMe.txt */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = ReadMe.txt; sourceTree = ""; };
F59C710400D5CB5801000001 /* Welcome.txt */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = Welcome.txt; sourceTree = ""; };
@@ -251,7 +267,9 @@
isa = PBXGroup;
children = (
F3968D71281FB5E100661875 /* config.xcconfig */,
+ F307A46E2B544C0F0012534B /* gme.xcodeproj */,
F3968B90281F817E00661875 /* opus.xcodeproj */,
+ F307A4752B544C1A0012534B /* wavpack.xcodeproj */,
F3E29D022882107B0006D108 /* xmp.xcodeproj */,
F59C70FC00D5CB5801000001 /* pkg-support */,
0153844A006D81B07F000001 /* Public Headers */,
@@ -293,14 +311,14 @@
AAE405DB1F9607C200EDAF53 /* music_cmd.h */,
F37A8D492838A23400C38E95 /* music_drflac.c */,
F37A8D412838A23400C38E95 /* music_drflac.h */,
- F37A8D2C2838924900C38E95 /* music_drmp3.c */,
- F37A8D2B2838924900C38E95 /* music_drmp3.h */,
AAE405D41F9607C100EDAF53 /* music_flac.c */,
AAE405C71F9607C000EDAF53 /* music_flac.h */,
- 635731D12AD5B66A000AC38E /* music_gme.c */,
- 635731D22AD5B66A000AC38E /* music_gme.h */,
AAE405C61F9607C000EDAF53 /* music_fluidsynth.c */,
AAE405BF1F9607BF00EDAF53 /* music_fluidsynth.h */,
+ 635731D12AD5B66A000AC38E /* music_gme.c */,
+ 635731D22AD5B66A000AC38E /* music_gme.h */,
+ F307A4E32B546F710012534B /* music_minimp3.c */,
+ F307A4E42B546F710012534B /* music_minimp3.h */,
AAE405C41F9607C000EDAF53 /* music_modplug.c */,
AAE405C51F9607C000EDAF53 /* music_modplug.h */,
AAE405DF1F9607C300EDAF53 /* music_mpg123.c */,
@@ -354,6 +372,22 @@
name = Frameworks;
sourceTree = "";
};
+ F307A46F2B544C0F0012534B /* Products */ = {
+ isa = PBXGroup;
+ children = (
+ F307A4742B544C0F0012534B /* gme.framework */,
+ );
+ name = Products;
+ sourceTree = "";
+ };
+ F307A4762B544C1A0012534B /* Products */ = {
+ isa = PBXGroup;
+ children = (
+ F307A47B2B544C1A0012534B /* wavpack.framework */,
+ );
+ name = Products;
+ sourceTree = "";
+ };
F3968B91281F817E00661875 /* Products */ = {
isa = PBXGroup;
children = (
@@ -408,9 +442,9 @@
files = (
AAE405E31F9607C300EDAF53 /* music_fluidsynth.h in Headers */,
AAE405F61F9607C300EDAF53 /* load_aiff.h in Headers */,
+ F307A4E72B546F710012534B /* music_minimp3.h in Headers */,
AAE405E71F9607C300EDAF53 /* load_voc.h in Headers */,
AAE405EC1F9607C300EDAF53 /* music_wav.h in Headers */,
- F37A8D2D2838924900C38E95 /* music_drmp3.h in Headers */,
AAE405E91F9607C300EDAF53 /* music_modplug.h in Headers */,
AAE405FE1F9607C300EDAF53 /* music_nativemidi.h in Headers */,
F37A8D4A2838A23400C38E95 /* music_drflac.h in Headers */,
@@ -450,13 +484,13 @@
F3823338273195CF00F7F527 /* utils.h in Headers */,
F38233562731961C00F7F527 /* music_timidity.h in Headers */,
F38233542731961800F7F527 /* music_ogg.h in Headers */,
+ F307A4E82B546F710012534B /* music_minimp3.h in Headers */,
F382335C2731962B00F7F527 /* load_voc.h in Headers */,
F382335D2731962D00F7F527 /* music_opus.h in Headers */,
F3823342273195E900F7F527 /* mp3utils.h in Headers */,
F38233602731963800F7F527 /* native_midi.h in Headers */,
F38233502731960F00F7F527 /* music_mpg123.h in Headers */,
F3823344273195EE00F7F527 /* music_cmd.h in Headers */,
- F37A8D2E2838924900C38E95 /* music_drmp3.h in Headers */,
F38233582731962100F7F527 /* music_wav.h in Headers */,
635731D02AD5B658000AC38E /* music_wavpack.h in Headers */,
635731D62AD5B66A000AC38E /* music_gme.h in Headers */,
@@ -544,10 +578,18 @@
productRefGroup = 034768DDFF38A45A11DB9C8B /* Products */;
projectDirPath = "";
projectReferences = (
+ {
+ ProductGroup = F307A46F2B544C0F0012534B /* Products */;
+ ProjectRef = F307A46E2B544C0F0012534B /* gme.xcodeproj */;
+ },
{
ProductGroup = F3968B91281F817E00661875 /* Products */;
ProjectRef = F3968B90281F817E00661875 /* opus.xcodeproj */;
},
+ {
+ ProductGroup = F307A4762B544C1A0012534B /* Products */;
+ ProjectRef = F307A4752B544C1A0012534B /* wavpack.xcodeproj */;
+ },
{
ProductGroup = F3E29D032882107B0006D108 /* Products */;
ProjectRef = F3E29D022882107B0006D108 /* xmp.xcodeproj */;
@@ -563,6 +605,20 @@
/* End PBXProject section */
/* Begin PBXReferenceProxy section */
+ F307A4742B544C0F0012534B /* gme.framework */ = {
+ isa = PBXReferenceProxy;
+ fileType = wrapper.framework;
+ path = gme.framework;
+ remoteRef = F307A4732B544C0F0012534B /* PBXContainerItemProxy */;
+ sourceTree = BUILT_PRODUCTS_DIR;
+ };
+ F307A47B2B544C1A0012534B /* wavpack.framework */ = {
+ isa = PBXReferenceProxy;
+ fileType = wrapper.framework;
+ path = wavpack.framework;
+ remoteRef = F307A47A2B544C1A0012534B /* PBXContainerItemProxy */;
+ sourceTree = BUILT_PRODUCTS_DIR;
+ };
F3968B97281F817E00661875 /* opus.framework */ = {
isa = PBXReferenceProxy;
fileType = wrapper.framework;
@@ -629,7 +685,7 @@
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
- shellScript = "PRODUCT_NAME=SDL2_mixer\nOPTIONAL_FRAMEWORKS=\"ogg opus xmp\"\n\n# Sign framework\nif [ \"$SDL_CODESIGN_IDENTITY\" != \"\" ]; then\n codesign --force --deep --sign \"$SDL_CODESIGN_IDENTITY\" --preserve-metadata\\=identifier,entitlements,flags --generate-entitlement-der $TARGET_BUILD_DIR/$PRODUCT_NAME.framework/Versions/A || exit $?\nfi\n\n# clean up the framework, remove headers, extra files\nmkdir -p build/dmg-tmp\ncp -a $TARGET_BUILD_DIR/$PRODUCT_NAME.framework build/dmg-tmp/\ncp pkg-support/resources/ReadMe.txt build/dmg-tmp\nfor i in $OPTIONAL_FRAMEWORKS; do\n if [ -d $TARGET_BUILD_DIR/$i.framework ]; then\n if [ \"$SDL_CODESIGN_IDENTITY\" != \"\" ]; then\n codesign --force --deep --sign \"$SDL_CODESIGN_IDENTITY\" --preserve-metadata\\=identifier,entitlements,flags --generate-entitlement-der $TARGET_BUILD_DIR/$i.framework/Versions/A\n fi\n mkdir -p build/dmg-tmp/optional\n cp -a $TARGET_BUILD_DIR/$i.framework build/dmg-tmp/optional/\n fi\ndone\n\n# remove the .DS_Store files if any (we may want to provide one in the future for fancy .dmgs)\nrm -rf build/dmg-tmp/.DS_Store\n\n# create the dmg\nhdiutil create -ov -fs HFS+ -volname $PRODUCT_NAME -srcfolder build/dmg-tmp build/$PRODUCT_NAME.dmg\n\n# clean up\nrm -rf build/dmg-tmp\n";
+ shellScript = "PRODUCT_NAME=SDL2_mixer\nOPTIONAL_FRAMEWORKS=\"gme ogg opus wavpack xmp\"\n\n# Sign framework\nif [ \"$SDL_CODESIGN_IDENTITY\" != \"\" ]; then\n codesign --force --deep --sign \"$SDL_CODESIGN_IDENTITY\" --preserve-metadata\\=identifier,entitlements,flags --generate-entitlement-der $TARGET_BUILD_DIR/$PRODUCT_NAME.framework/Versions/A || exit $?\nfi\n\n# clean up the framework, remove headers, extra files\nmkdir -p build/dmg-tmp\ncp -a $TARGET_BUILD_DIR/$PRODUCT_NAME.framework build/dmg-tmp/\ncp pkg-support/resources/ReadMe.txt build/dmg-tmp\nfor i in $OPTIONAL_FRAMEWORKS; do\n if [ -d $TARGET_BUILD_DIR/$i.framework ]; then\n if [ \"$SDL_CODESIGN_IDENTITY\" != \"\" ]; then\n codesign --force --deep --sign \"$SDL_CODESIGN_IDENTITY\" --preserve-metadata\\=identifier,entitlements,flags --generate-entitlement-der $TARGET_BUILD_DIR/$i.framework/Versions/A\n fi\n mkdir -p build/dmg-tmp/optional\n cp -a $TARGET_BUILD_DIR/$i.framework build/dmg-tmp/optional/\n fi\ndone\n\n# remove the .DS_Store files if any (we may want to provide one in the future for fancy .dmgs)\nrm -rf build/dmg-tmp/.DS_Store\n\n# create the dmg\nhdiutil create -ov -fs HFS+ -volname $PRODUCT_NAME -srcfolder build/dmg-tmp build/$PRODUCT_NAME.dmg\n\n# clean up\nrm -rf build/dmg-tmp\n";
};
/* End PBXShellScriptBuildPhase section */
@@ -639,7 +695,6 @@
buildActionMask = 2147483647;
files = (
AAE405E21F9607C300EDAF53 /* load_aiff.c in Sources */,
- F37A8D2F2838924900C38E95 /* music_drmp3.c in Sources */,
AAE405F01F9607C300EDAF53 /* load_voc.c in Sources */,
AAE405EA1F9607C300EDAF53 /* music_fluidsynth.c in Sources */,
AAE405FD1F9607C300EDAF53 /* music_ogg.c in Sources */,
@@ -658,6 +713,7 @@
F30240652881DF95002F32D6 /* music_xmp.c in Sources */,
AAE405E81F9607C300EDAF53 /* music_modplug.c in Sources */,
AAE405E51F9607C300EDAF53 /* mixer.c in Sources */,
+ F307A4E52B546F710012534B /* music_minimp3.c in Sources */,
0448E8AE108B937A00C9D3EA /* native_midi_macosx.c in Sources */,
630FBD8320D52105009867AB /* music_opus.c in Sources */,
639008C82385A822009019FA /* utils.c in Sources */,
@@ -672,7 +728,6 @@
buildActionMask = 2147483647;
files = (
F38233552731961A00F7F527 /* music_timidity.c in Sources */,
- F37A8D302838924900C38E95 /* music_drmp3.c in Sources */,
F382334F2731960C00F7F527 /* music_mpg123.c in Sources */,
F382333B273195D800F7F527 /* effects_internal.c in Sources */,
0448E8AF108B937A00C9D3EA /* native_midi_macosx.c in Sources */,
@@ -691,6 +746,7 @@
F30240662881DF95002F32D6 /* music_xmp.c in Sources */,
F3823345273195F000F7F527 /* music_flac.c in Sources */,
F38233572731961F00F7F527 /* music_wav.c in Sources */,
+ F307A4E62B546F710012534B /* music_minimp3.c in Sources */,
F38233512731961100F7F527 /* music_nativemidi.c in Sources */,
F38233532731961600F7F527 /* music_ogg.c in Sources */,
F3823337273195CC00F7F527 /* utils.c in Sources */,
@@ -788,15 +844,15 @@
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
DEPLOYMENT_POSTPROCESSING = YES;
- DYLIB_COMPATIBILITY_VERSION = 702.0.0;
- DYLIB_CURRENT_VERSION = 702.0.0;
+ DYLIB_COMPATIBILITY_VERSION = 801.0.0;
+ DYLIB_CURRENT_VERSION = 801.0.0;
DYLIB_INSTALL_NAME_BASE = "@rpath";
FRAMEWORK_SEARCH_PATHS = "\"$(SRCROOT)/$(PLATFORM)\"";
GCC_GENERATE_DEBUGGING_SYMBOLS = NO;
GCC_NO_COMMON_BLOCKS = YES;
GCC_PREPROCESSOR_DEFINITIONS = (
MUSIC_FLAC_DRFLAC,
- MUSIC_MP3_DRMP3,
+ MUSIC_MP3_MINIMP3,
MUSIC_OGG,
OGG_USE_STB,
MUSIC_WAV,
@@ -837,8 +893,8 @@
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
COPY_PHASE_STRIP = NO;
- DYLIB_COMPATIBILITY_VERSION = 702.0.0;
- DYLIB_CURRENT_VERSION = 702.0.0;
+ DYLIB_COMPATIBILITY_VERSION = 801.0.0;
+ DYLIB_CURRENT_VERSION = 801.0.0;
DYLIB_INSTALL_NAME_BASE = "@rpath";
ENABLE_TESTABILITY = YES;
FRAMEWORK_SEARCH_PATHS = "\"$(SRCROOT)/$(PLATFORM)\"";
@@ -846,7 +902,7 @@
GCC_OPTIMIZATION_LEVEL = 0;
GCC_PREPROCESSOR_DEFINITIONS = (
MUSIC_FLAC_DRFLAC,
- MUSIC_MP3_DRMP3,
+ MUSIC_MP3_MINIMP3,
MUSIC_OGG,
OGG_USE_STB,
MUSIC_WAV,
diff --git a/Xcode/config.xcconfig b/Xcode/config.xcconfig
index 2edf556c1..0ef634ab3 100644
--- a/Xcode/config.xcconfig
+++ b/Xcode/config.xcconfig
@@ -1,6 +1,5 @@
//
// config.xcconfig
-// SDL_mixer
//
// Configuration settings file format documentation can be found at:
@@ -9,15 +8,28 @@
// Include any optional config for this build
#include? "build.xcconfig"
+// Uncomment these lines to enable Game_Music_Emu support
+// If you do this, you should run external/download.sh to download the decode libraries and add gme.framework to your application bundle.
+//GME_PREPROCESSOR_DEFINITIONS = MUSIC_GME
+//GME_FRAMEWORK_LDFLAGS = -weak_framework gme
+
// Uncomment these lines to enable native MIDI support on OSX
-//CONFIG_PREPROCESSOR_DEFINITIONS[sdk=mac*] = $(inherited) MUSIC_MID_NATIVE
+//MIDI_PREPROCESSOR_DEFINITIONS[sdk=macosx*] = MUSIC_MID_NATIVE
// Uncomment these lines to enable MOD support
// If you do this, you should run external/download.sh to download the decode libraries and add xmp.framework to your application bundle.
-//CONFIG_PREPROCESSOR_DEFINITIONS = $(inherited) MUSIC_MOD_XMP LIBXMP_HEADER=\"../external/libxmp/include/xmp.h\"
-//CONFIG_FRAMEWORK_LDFLAGS = $(inherited) -weak_framework xmp
+//MOD_PREPROCESSOR_DEFINITIONS = MUSIC_MOD_XMP LIBXMP_HEADER=\"../external/libxmp/include/xmp.h\"
+//MOD_FRAMEWORK_LDFLAGS = -weak_framework xmp
// Uncomment these lines to enable Opus support
// If you do this, you should run external/download.sh to download the decode libraries and add opus.framework to your application bundle.
-//CONFIG_PREPROCESSOR_DEFINITIONS = $(inherited) MUSIC_OPUS
-//CONFIG_FRAMEWORK_LDFLAGS = $(inherited) -weak_framework opus
+//OPUS_PREPROCESSOR_DEFINITIONS = MUSIC_OPUS
+//OPUS_FRAMEWORK_LDFLAGS = -weak_framework opus
+
+// Uncomment these lines to enable WavPack support
+// If you do this, you should run external/download.sh to download the decode libraries and add wavpack.framework to your application bundle.
+//WAVPACK_PREPROCESSOR_DEFINITIONS = MUSIC_WAVPACK MUSIC_WAVPACK_DSD
+//WAVPACK_FRAMEWORK_LDFLAGS = -weak_framework wavpack
+
+CONFIG_PREPROCESSOR_DEFINITIONS = $(inherited) $(GME_PREPROCESSOR_DEFINITIONS) $(MIDI_PREPROCESSOR_DEFINITIONS) $(MOD_PREPROCESSOR_DEFINITIONS) $(OPUS_PREPROCESSOR_DEFINITIONS) $(WAVPACK_PREPROCESSOR_DEFINITIONS)
+CONFIG_FRAMEWORK_LDFLAGS = $(inherited) $(GME_FRAMEWORK_LDFLAGS) $(MIDI_FRAMEWORK_LDFLAGS) $(MOD_FRAMEWORK_LDFLAGS) $(OPUS_FRAMEWORK_LDFLAGS) $(WAVPACK_FRAMEWORK_LDFLAGS)
diff --git a/Xcode/gme/gme.xcodeproj/project.pbxproj b/Xcode/gme/gme.xcodeproj/project.pbxproj
new file mode 100644
index 000000000..b1f253736
--- /dev/null
+++ b/Xcode/gme/gme.xcodeproj/project.pbxproj
@@ -0,0 +1,629 @@
+// !$*UTF8*$!
+{
+ archiveVersion = 1;
+ classes = {
+ };
+ objectVersion = 55;
+ objects = {
+
+/* Begin PBXAggregateTarget section */
+ F3B38D8F296F9773005DA6D3 /* gme.xcframework */ = {
+ isa = PBXAggregateTarget;
+ buildConfigurationList = F3B38D92296F9773005DA6D3 /* Build configuration list for PBXAggregateTarget "gme.xcframework" */;
+ buildPhases = (
+ F3B38D93296F9779005DA6D3 /* ShellScript */,
+ );
+ dependencies = (
+ );
+ name = gme.xcframework;
+ productName = xcFramework;
+ };
+/* End PBXAggregateTarget section */
+
+/* Begin PBXBuildFile section */
+ F307A27D2B5431C70012534B /* license.txt in Resources */ = {isa = PBXBuildFile; fileRef = F307A27A2B5431C70012534B /* license.txt */; };
+ F307A27E2B5431C70012534B /* gme.txt in Resources */ = {isa = PBXBuildFile; fileRef = F307A27B2B5431C70012534B /* gme.txt */; };
+ F307A27F2B5431C70012534B /* readme.txt in Resources */ = {isa = PBXBuildFile; fileRef = F307A27C2B5431C70012534B /* readme.txt */; };
+ F307A2AF2B54329C0012534B /* Ym2612_GENS.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F307A2802B54329C0012534B /* Ym2612_GENS.cpp */; };
+ F307A2B02B54329C0012534B /* Nes_Vrc6_Apu.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F307A2812B54329C0012534B /* Nes_Vrc6_Apu.cpp */; };
+ F307A2B12B54329C0012534B /* Sap_Cpu.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F307A2822B54329C0012534B /* Sap_Cpu.cpp */; };
+ F307A2B22B54329C0012534B /* Dual_Resampler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F307A2832B54329C0012534B /* Dual_Resampler.cpp */; };
+ F307A2B32B54329C0012534B /* Ym2612_MAME.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F307A2842B54329C0012534B /* Ym2612_MAME.cpp */; };
+ F307A2B42B54329C0012534B /* Nes_Namco_Apu.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F307A2852B54329C0012534B /* Nes_Namco_Apu.cpp */; };
+ F307A2B52B54329C0012534B /* M3u_Playlist.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F307A2862B54329C0012534B /* M3u_Playlist.cpp */; };
+ F307A2B62B54329C0012534B /* Vgm_Emu_Impl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F307A2872B54329C0012534B /* Vgm_Emu_Impl.cpp */; };
+ F307A2B72B54329C0012534B /* Hes_Emu.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F307A2882B54329C0012534B /* Hes_Emu.cpp */; };
+ F307A2B82B54329C0012534B /* Snes_Spc.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F307A2892B54329C0012534B /* Snes_Spc.cpp */; };
+ F307A2B92B54329C0012534B /* Kss_Cpu.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F307A28A2B54329C0012534B /* Kss_Cpu.cpp */; };
+ F307A2BA2B54329C0012534B /* Nes_Cpu.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F307A28B2B54329C0012534B /* Nes_Cpu.cpp */; };
+ F307A2BB2B54329C0012534B /* Effects_Buffer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F307A28C2B54329C0012534B /* Effects_Buffer.cpp */; };
+ F307A2BC2B54329C0012534B /* Fir_Resampler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F307A28D2B54329C0012534B /* Fir_Resampler.cpp */; };
+ F307A2BD2B54329C0012534B /* Music_Emu.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F307A28E2B54329C0012534B /* Music_Emu.cpp */; };
+ F307A2BE2B54329C0012534B /* Blip_Buffer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F307A28F2B54329C0012534B /* Blip_Buffer.cpp */; };
+ F307A2BF2B54329C0012534B /* Sap_Apu.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F307A2902B54329C0012534B /* Sap_Apu.cpp */; };
+ F307A2C02B54329C0012534B /* Sap_Emu.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F307A2912B54329C0012534B /* Sap_Emu.cpp */; };
+ F307A2C12B54329C0012534B /* Classic_Emu.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F307A2922B54329C0012534B /* Classic_Emu.cpp */; };
+ F307A2C22B54329C0012534B /* Gbs_Emu.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F307A2932B54329C0012534B /* Gbs_Emu.cpp */; };
+ F307A2C32B54329C0012534B /* Nes_Fme7_Apu.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F307A2942B54329C0012534B /* Nes_Fme7_Apu.cpp */; };
+ F307A2C42B54329C0012534B /* Sms_Apu.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F307A2952B54329C0012534B /* Sms_Apu.cpp */; };
+ F307A2C52B54329C0012534B /* Ym2413_Emu.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F307A2962B54329C0012534B /* Ym2413_Emu.cpp */; };
+ F307A2C62B54329C0012534B /* Ym2612_Nuked.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F307A2972B54329C0012534B /* Ym2612_Nuked.cpp */; };
+ F307A2C72B54329C0012534B /* Gme_File.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F307A2982B54329C0012534B /* Gme_File.cpp */; };
+ F307A2C82B54329C0012534B /* Nsfe_Emu.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F307A2992B54329C0012534B /* Nsfe_Emu.cpp */; };
+ F307A2C92B54329C0012534B /* Kss_Emu.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F307A29A2B54329C0012534B /* Kss_Emu.cpp */; };
+ F307A2CA2B54329C0012534B /* Spc_Cpu.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F307A29B2B54329C0012534B /* Spc_Cpu.cpp */; };
+ F307A2CB2B54329C0012534B /* Hes_Cpu.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F307A29C2B54329C0012534B /* Hes_Cpu.cpp */; };
+ F307A2CC2B54329C0012534B /* Gb_Cpu.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F307A29D2B54329C0012534B /* Gb_Cpu.cpp */; };
+ F307A2CD2B54329C0012534B /* Nes_Oscs.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F307A29E2B54329C0012534B /* Nes_Oscs.cpp */; };
+ F307A2CE2B54329C0012534B /* Nsf_Emu.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F307A29F2B54329C0012534B /* Nsf_Emu.cpp */; };
+ F307A2CF2B54329C0012534B /* Hes_Apu.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F307A2A02B54329C0012534B /* Hes_Apu.cpp */; };
+ F307A2D02B54329C0012534B /* Gb_Apu.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F307A2A12B54329C0012534B /* Gb_Apu.cpp */; };
+ F307A2D12B54329C0012534B /* Multi_Buffer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F307A2A22B54329C0012534B /* Multi_Buffer.cpp */; };
+ F307A2D22B54329C0012534B /* Spc_Emu.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F307A2A32B54329C0012534B /* Spc_Emu.cpp */; };
+ F307A2D32B54329C0012534B /* Ay_Cpu.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F307A2A42B54329C0012534B /* Ay_Cpu.cpp */; };
+ F307A2D42B54329C0012534B /* Ay_Emu.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F307A2A52B54329C0012534B /* Ay_Emu.cpp */; };
+ F307A2D52B54329C0012534B /* Kss_Scc_Apu.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F307A2A62B54329C0012534B /* Kss_Scc_Apu.cpp */; };
+ F307A2D62B54329C0012534B /* Ay_Apu.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F307A2A72B54329C0012534B /* Ay_Apu.cpp */; };
+ F307A2D72B54329C0012534B /* Gym_Emu.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F307A2A82B54329C0012534B /* Gym_Emu.cpp */; };
+ F307A2D82B54329C0012534B /* Data_Reader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F307A2A92B54329C0012534B /* Data_Reader.cpp */; };
+ F307A2D92B54329C0012534B /* Nes_Apu.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F307A2AA2B54329C0012534B /* Nes_Apu.cpp */; };
+ F307A2DA2B54329C0012534B /* Gb_Oscs.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F307A2AB2B54329C0012534B /* Gb_Oscs.cpp */; };
+ F307A2DB2B54329C0012534B /* Spc_Filter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F307A2AC2B54329C0012534B /* Spc_Filter.cpp */; };
+ F307A2DC2B54329C0012534B /* Spc_Dsp.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F307A2AD2B54329C0012534B /* Spc_Dsp.cpp */; };
+ F307A2DD2B54329C0012534B /* gme.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F307A2AE2B54329C0012534B /* gme.cpp */; };
+ F307A2DF2B5434FF0012534B /* Vgm_Emu.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F307A2DE2B5434FF0012534B /* Vgm_Emu.cpp */; };
+ F307A2E12B54358D0012534B /* gme.h in Headers */ = {isa = PBXBuildFile; fileRef = F307A2E02B54358D0012534B /* gme.h */; settings = {ATTRIBUTES = (Public, ); }; };
+/* End PBXBuildFile section */
+
+/* Begin PBXFileReference section */
+ F307A27A2B5431C70012534B /* license.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = license.txt; path = ../../external/libgme/license.txt; sourceTree = ""; };
+ F307A27B2B5431C70012534B /* gme.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = gme.txt; path = ../../external/libgme/gme.txt; sourceTree = ""; };
+ F307A27C2B5431C70012534B /* readme.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = readme.txt; path = ../../external/libgme/readme.txt; sourceTree = ""; };
+ F307A2802B54329C0012534B /* Ym2612_GENS.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Ym2612_GENS.cpp; path = ../../external/libgme/gme/Ym2612_GENS.cpp; sourceTree = ""; };
+ F307A2812B54329C0012534B /* Nes_Vrc6_Apu.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Nes_Vrc6_Apu.cpp; path = ../../external/libgme/gme/Nes_Vrc6_Apu.cpp; sourceTree = ""; };
+ F307A2822B54329C0012534B /* Sap_Cpu.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Sap_Cpu.cpp; path = ../../external/libgme/gme/Sap_Cpu.cpp; sourceTree = ""; };
+ F307A2832B54329C0012534B /* Dual_Resampler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Dual_Resampler.cpp; path = ../../external/libgme/gme/Dual_Resampler.cpp; sourceTree = ""; };
+ F307A2842B54329C0012534B /* Ym2612_MAME.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Ym2612_MAME.cpp; path = ../../external/libgme/gme/Ym2612_MAME.cpp; sourceTree = ""; };
+ F307A2852B54329C0012534B /* Nes_Namco_Apu.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Nes_Namco_Apu.cpp; path = ../../external/libgme/gme/Nes_Namco_Apu.cpp; sourceTree = ""; };
+ F307A2862B54329C0012534B /* M3u_Playlist.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = M3u_Playlist.cpp; path = ../../external/libgme/gme/M3u_Playlist.cpp; sourceTree = ""; };
+ F307A2872B54329C0012534B /* Vgm_Emu_Impl.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Vgm_Emu_Impl.cpp; path = ../../external/libgme/gme/Vgm_Emu_Impl.cpp; sourceTree = ""; };
+ F307A2882B54329C0012534B /* Hes_Emu.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Hes_Emu.cpp; path = ../../external/libgme/gme/Hes_Emu.cpp; sourceTree = ""; };
+ F307A2892B54329C0012534B /* Snes_Spc.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Snes_Spc.cpp; path = ../../external/libgme/gme/Snes_Spc.cpp; sourceTree = ""; };
+ F307A28A2B54329C0012534B /* Kss_Cpu.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Kss_Cpu.cpp; path = ../../external/libgme/gme/Kss_Cpu.cpp; sourceTree = ""; };
+ F307A28B2B54329C0012534B /* Nes_Cpu.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Nes_Cpu.cpp; path = ../../external/libgme/gme/Nes_Cpu.cpp; sourceTree = ""; };
+ F307A28C2B54329C0012534B /* Effects_Buffer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Effects_Buffer.cpp; path = ../../external/libgme/gme/Effects_Buffer.cpp; sourceTree = ""; };
+ F307A28D2B54329C0012534B /* Fir_Resampler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Fir_Resampler.cpp; path = ../../external/libgme/gme/Fir_Resampler.cpp; sourceTree = ""; };
+ F307A28E2B54329C0012534B /* Music_Emu.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Music_Emu.cpp; path = ../../external/libgme/gme/Music_Emu.cpp; sourceTree = ""; };
+ F307A28F2B54329C0012534B /* Blip_Buffer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Blip_Buffer.cpp; path = ../../external/libgme/gme/Blip_Buffer.cpp; sourceTree = ""; };
+ F307A2902B54329C0012534B /* Sap_Apu.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Sap_Apu.cpp; path = ../../external/libgme/gme/Sap_Apu.cpp; sourceTree = ""; };
+ F307A2912B54329C0012534B /* Sap_Emu.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Sap_Emu.cpp; path = ../../external/libgme/gme/Sap_Emu.cpp; sourceTree = ""; };
+ F307A2922B54329C0012534B /* Classic_Emu.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Classic_Emu.cpp; path = ../../external/libgme/gme/Classic_Emu.cpp; sourceTree = ""; };
+ F307A2932B54329C0012534B /* Gbs_Emu.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Gbs_Emu.cpp; path = ../../external/libgme/gme/Gbs_Emu.cpp; sourceTree = ""; };
+ F307A2942B54329C0012534B /* Nes_Fme7_Apu.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Nes_Fme7_Apu.cpp; path = ../../external/libgme/gme/Nes_Fme7_Apu.cpp; sourceTree = ""; };
+ F307A2952B54329C0012534B /* Sms_Apu.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Sms_Apu.cpp; path = ../../external/libgme/gme/Sms_Apu.cpp; sourceTree = ""; };
+ F307A2962B54329C0012534B /* Ym2413_Emu.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Ym2413_Emu.cpp; path = ../../external/libgme/gme/Ym2413_Emu.cpp; sourceTree = ""; };
+ F307A2972B54329C0012534B /* Ym2612_Nuked.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Ym2612_Nuked.cpp; path = ../../external/libgme/gme/Ym2612_Nuked.cpp; sourceTree = ""; };
+ F307A2982B54329C0012534B /* Gme_File.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Gme_File.cpp; path = ../../external/libgme/gme/Gme_File.cpp; sourceTree = ""; };
+ F307A2992B54329C0012534B /* Nsfe_Emu.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Nsfe_Emu.cpp; path = ../../external/libgme/gme/Nsfe_Emu.cpp; sourceTree = ""; };
+ F307A29A2B54329C0012534B /* Kss_Emu.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Kss_Emu.cpp; path = ../../external/libgme/gme/Kss_Emu.cpp; sourceTree = ""; };
+ F307A29B2B54329C0012534B /* Spc_Cpu.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Spc_Cpu.cpp; path = ../../external/libgme/gme/Spc_Cpu.cpp; sourceTree = ""; };
+ F307A29C2B54329C0012534B /* Hes_Cpu.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Hes_Cpu.cpp; path = ../../external/libgme/gme/Hes_Cpu.cpp; sourceTree = ""; };
+ F307A29D2B54329C0012534B /* Gb_Cpu.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Gb_Cpu.cpp; path = ../../external/libgme/gme/Gb_Cpu.cpp; sourceTree = ""; };
+ F307A29E2B54329C0012534B /* Nes_Oscs.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Nes_Oscs.cpp; path = ../../external/libgme/gme/Nes_Oscs.cpp; sourceTree = ""; };
+ F307A29F2B54329C0012534B /* Nsf_Emu.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Nsf_Emu.cpp; path = ../../external/libgme/gme/Nsf_Emu.cpp; sourceTree = ""; };
+ F307A2A02B54329C0012534B /* Hes_Apu.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Hes_Apu.cpp; path = ../../external/libgme/gme/Hes_Apu.cpp; sourceTree = ""; };
+ F307A2A12B54329C0012534B /* Gb_Apu.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Gb_Apu.cpp; path = ../../external/libgme/gme/Gb_Apu.cpp; sourceTree = ""; };
+ F307A2A22B54329C0012534B /* Multi_Buffer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Multi_Buffer.cpp; path = ../../external/libgme/gme/Multi_Buffer.cpp; sourceTree = ""; };
+ F307A2A32B54329C0012534B /* Spc_Emu.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Spc_Emu.cpp; path = ../../external/libgme/gme/Spc_Emu.cpp; sourceTree = ""; };
+ F307A2A42B54329C0012534B /* Ay_Cpu.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Ay_Cpu.cpp; path = ../../external/libgme/gme/Ay_Cpu.cpp; sourceTree = ""; };
+ F307A2A52B54329C0012534B /* Ay_Emu.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Ay_Emu.cpp; path = ../../external/libgme/gme/Ay_Emu.cpp; sourceTree = ""; };
+ F307A2A62B54329C0012534B /* Kss_Scc_Apu.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Kss_Scc_Apu.cpp; path = ../../external/libgme/gme/Kss_Scc_Apu.cpp; sourceTree = ""; };
+ F307A2A72B54329C0012534B /* Ay_Apu.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Ay_Apu.cpp; path = ../../external/libgme/gme/Ay_Apu.cpp; sourceTree = ""; };
+ F307A2A82B54329C0012534B /* Gym_Emu.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Gym_Emu.cpp; path = ../../external/libgme/gme/Gym_Emu.cpp; sourceTree = ""; };
+ F307A2A92B54329C0012534B /* Data_Reader.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Data_Reader.cpp; path = ../../external/libgme/gme/Data_Reader.cpp; sourceTree = ""; };
+ F307A2AA2B54329C0012534B /* Nes_Apu.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Nes_Apu.cpp; path = ../../external/libgme/gme/Nes_Apu.cpp; sourceTree = ""; };
+ F307A2AB2B54329C0012534B /* Gb_Oscs.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Gb_Oscs.cpp; path = ../../external/libgme/gme/Gb_Oscs.cpp; sourceTree = ""; };
+ F307A2AC2B54329C0012534B /* Spc_Filter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Spc_Filter.cpp; path = ../../external/libgme/gme/Spc_Filter.cpp; sourceTree = ""; };
+ F307A2AD2B54329C0012534B /* Spc_Dsp.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Spc_Dsp.cpp; path = ../../external/libgme/gme/Spc_Dsp.cpp; sourceTree = ""; };
+ F307A2AE2B54329C0012534B /* gme.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = gme.cpp; path = ../../external/libgme/gme/gme.cpp; sourceTree = ""; };
+ F307A2DE2B5434FF0012534B /* Vgm_Emu.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Vgm_Emu.cpp; path = ../../external/libgme/gme/Vgm_Emu.cpp; sourceTree = ""; };
+ F307A2E02B54358D0012534B /* gme.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = gme.h; path = ../../external/libgme/gme/gme.h; sourceTree = ""; };
+ F3F70EDA281F61B4005AA27D /* gme.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = gme.framework; sourceTree = BUILT_PRODUCTS_DIR; };
+/* End PBXFileReference section */
+
+/* Begin PBXFrameworksBuildPhase section */
+ F3F70ED7281F61B4005AA27D /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXFrameworksBuildPhase section */
+
+/* Begin PBXGroup section */
+ F3F70ED0281F61B4005AA27D = {
+ isa = PBXGroup;
+ children = (
+ F3F70EDB281F61B4005AA27D /* Products */,
+ F3F70EE6281F61D0005AA27D /* Resources */,
+ F3F70EE5281F61C9005AA27D /* Headers */,
+ F3F70EE4281F61C3005AA27D /* Source */,
+ );
+ sourceTree = "";
+ };
+ F3F70EDB281F61B4005AA27D /* Products */ = {
+ isa = PBXGroup;
+ children = (
+ F3F70EDA281F61B4005AA27D /* gme.framework */,
+ );
+ name = Products;
+ sourceTree = "";
+ };
+ F3F70EE4281F61C3005AA27D /* Source */ = {
+ isa = PBXGroup;
+ children = (
+ F307A2A72B54329C0012534B /* Ay_Apu.cpp */,
+ F307A2A42B54329C0012534B /* Ay_Cpu.cpp */,
+ F307A2A52B54329C0012534B /* Ay_Emu.cpp */,
+ F307A28F2B54329C0012534B /* Blip_Buffer.cpp */,
+ F307A2922B54329C0012534B /* Classic_Emu.cpp */,
+ F307A2A92B54329C0012534B /* Data_Reader.cpp */,
+ F307A2832B54329C0012534B /* Dual_Resampler.cpp */,
+ F307A28C2B54329C0012534B /* Effects_Buffer.cpp */,
+ F307A28D2B54329C0012534B /* Fir_Resampler.cpp */,
+ F307A2A12B54329C0012534B /* Gb_Apu.cpp */,
+ F307A29D2B54329C0012534B /* Gb_Cpu.cpp */,
+ F307A2AB2B54329C0012534B /* Gb_Oscs.cpp */,
+ F307A2932B54329C0012534B /* Gbs_Emu.cpp */,
+ F307A2982B54329C0012534B /* Gme_File.cpp */,
+ F307A2AE2B54329C0012534B /* gme.cpp */,
+ F307A2A82B54329C0012534B /* Gym_Emu.cpp */,
+ F307A2A02B54329C0012534B /* Hes_Apu.cpp */,
+ F307A29C2B54329C0012534B /* Hes_Cpu.cpp */,
+ F307A2882B54329C0012534B /* Hes_Emu.cpp */,
+ F307A28A2B54329C0012534B /* Kss_Cpu.cpp */,
+ F307A29A2B54329C0012534B /* Kss_Emu.cpp */,
+ F307A2A62B54329C0012534B /* Kss_Scc_Apu.cpp */,
+ F307A2862B54329C0012534B /* M3u_Playlist.cpp */,
+ F307A2A22B54329C0012534B /* Multi_Buffer.cpp */,
+ F307A28E2B54329C0012534B /* Music_Emu.cpp */,
+ F307A2AA2B54329C0012534B /* Nes_Apu.cpp */,
+ F307A28B2B54329C0012534B /* Nes_Cpu.cpp */,
+ F307A2942B54329C0012534B /* Nes_Fme7_Apu.cpp */,
+ F307A2852B54329C0012534B /* Nes_Namco_Apu.cpp */,
+ F307A29E2B54329C0012534B /* Nes_Oscs.cpp */,
+ F307A2812B54329C0012534B /* Nes_Vrc6_Apu.cpp */,
+ F307A29F2B54329C0012534B /* Nsf_Emu.cpp */,
+ F307A2992B54329C0012534B /* Nsfe_Emu.cpp */,
+ F307A2902B54329C0012534B /* Sap_Apu.cpp */,
+ F307A2822B54329C0012534B /* Sap_Cpu.cpp */,
+ F307A2912B54329C0012534B /* Sap_Emu.cpp */,
+ F307A2952B54329C0012534B /* Sms_Apu.cpp */,
+ F307A2892B54329C0012534B /* Snes_Spc.cpp */,
+ F307A29B2B54329C0012534B /* Spc_Cpu.cpp */,
+ F307A2AD2B54329C0012534B /* Spc_Dsp.cpp */,
+ F307A2A32B54329C0012534B /* Spc_Emu.cpp */,
+ F307A2AC2B54329C0012534B /* Spc_Filter.cpp */,
+ F307A2872B54329C0012534B /* Vgm_Emu_Impl.cpp */,
+ F307A2DE2B5434FF0012534B /* Vgm_Emu.cpp */,
+ F307A2962B54329C0012534B /* Ym2413_Emu.cpp */,
+ F307A2802B54329C0012534B /* Ym2612_GENS.cpp */,
+ F307A2842B54329C0012534B /* Ym2612_MAME.cpp */,
+ F307A2972B54329C0012534B /* Ym2612_Nuked.cpp */,
+ );
+ name = Source;
+ sourceTree = "";
+ };
+ F3F70EE5281F61C9005AA27D /* Headers */ = {
+ isa = PBXGroup;
+ children = (
+ F307A2E02B54358D0012534B /* gme.h */,
+ );
+ name = Headers;
+ sourceTree = "";
+ };
+ F3F70EE6281F61D0005AA27D /* Resources */ = {
+ isa = PBXGroup;
+ children = (
+ F307A27B2B5431C70012534B /* gme.txt */,
+ F307A27A2B5431C70012534B /* license.txt */,
+ F307A27C2B5431C70012534B /* readme.txt */,
+ );
+ name = Resources;
+ sourceTree = "";
+ };
+/* End PBXGroup section */
+
+/* Begin PBXHeadersBuildPhase section */
+ F3F70ED5281F61B4005AA27D /* Headers */ = {
+ isa = PBXHeadersBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ F307A2E12B54358D0012534B /* gme.h in Headers */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXHeadersBuildPhase section */
+
+/* Begin PBXNativeTarget section */
+ F3F70ED9281F61B4005AA27D /* gme */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = F3F70EE1281F61B4005AA27D /* Build configuration list for PBXNativeTarget "gme" */;
+ buildPhases = (
+ F3F70ED5281F61B4005AA27D /* Headers */,
+ F3F70ED6281F61B4005AA27D /* Sources */,
+ F3F70ED7281F61B4005AA27D /* Frameworks */,
+ F3F70ED8281F61B4005AA27D /* Resources */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ );
+ name = gme;
+ productName = gme;
+ productReference = F3F70EDA281F61B4005AA27D /* gme.framework */;
+ productType = "com.apple.product-type.framework";
+ };
+/* End PBXNativeTarget section */
+
+/* Begin PBXProject section */
+ F3F70ED1281F61B4005AA27D /* Project object */ = {
+ isa = PBXProject;
+ attributes = {
+ BuildIndependentTargetsInParallel = 1;
+ LastUpgradeCheck = 1330;
+ TargetAttributes = {
+ F3B38D8F296F9773005DA6D3 = {
+ CreatedOnToolsVersion = 14.2;
+ };
+ F3F70ED9281F61B4005AA27D = {
+ CreatedOnToolsVersion = 13.3.1;
+ };
+ };
+ };
+ buildConfigurationList = F3F70ED4281F61B4005AA27D /* Build configuration list for PBXProject "gme" */;
+ compatibilityVersion = "Xcode 13.0";
+ developmentRegion = en;
+ hasScannedForEncodings = 0;
+ knownRegions = (
+ en,
+ Base,
+ );
+ mainGroup = F3F70ED0281F61B4005AA27D;
+ productRefGroup = F3F70EDB281F61B4005AA27D /* Products */;
+ projectDirPath = "";
+ projectRoot = "";
+ targets = (
+ F3F70ED9281F61B4005AA27D /* gme */,
+ F3B38D8F296F9773005DA6D3 /* gme.xcframework */,
+ );
+ };
+/* End PBXProject section */
+
+/* Begin PBXResourcesBuildPhase section */
+ F3F70ED8281F61B4005AA27D /* Resources */ = {
+ isa = PBXResourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ F307A27F2B5431C70012534B /* readme.txt in Resources */,
+ F307A27E2B5431C70012534B /* gme.txt in Resources */,
+ F307A27D2B5431C70012534B /* license.txt in Resources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXResourcesBuildPhase section */
+
+/* Begin PBXShellScriptBuildPhase section */
+ F3B38D93296F9779005DA6D3 /* ShellScript */ = {
+ isa = PBXShellScriptBuildPhase;
+ alwaysOutOfDate = 1;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ inputFileListPaths = (
+ );
+ inputPaths = (
+ );
+ outputFileListPaths = (
+ );
+ outputPaths = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ shellPath = /bin/sh;
+ shellScript = "# Build an xcframework with both device and simulator files for all platforms.\n# Adapted from an answer in\n# https://developer.apple.com/forums/thread/666335?answerId=685927022#685927022\n\nif [ \"$XCODE_VERSION_ACTUAL\" -lt 1100 ]\nthen\n echo \"error: Building an xcframework requires Xcode 11 minimum.\"\n exit 1\nfi\n\nFRAMEWORK_NAME=\"gme\"\nPROJECT_NAME=\"gme\"\nSCHEME=\"gme\"\n\nMACOS_ARCHIVE_PATH=\"${BUILD_DIR}/${CONFIGURATION}/${FRAMEWORK_NAME}-macosx.xcarchive\"\nIOS_SIMULATOR_ARCHIVE_PATH=\"${BUILD_DIR}/${CONFIGURATION}/${FRAMEWORK_NAME}-iphonesimulator.xcarchive\"\nIOS_DEVICE_ARCHIVE_PATH=\"${BUILD_DIR}/${CONFIGURATION}/${FRAMEWORK_NAME}-iphoneos.xcarchive\"\nTVOS_SIMULATOR_ARCHIVE_PATH=\"${BUILD_DIR}/${CONFIGURATION}/${FRAMEWORK_NAME}-appletvsimulator.xcarchive\"\nTVOS_DEVICE_ARCHIVE_PATH=\"${BUILD_DIR}/${CONFIGURATION}/${FRAMEWORK_NAME}-appletvos.xcarchive\"\n\nOUTPUT_DIR=\"../build/\"\n\n# macOS\nxcodebuild archive \\\n ONLY_ACTIVE_ARCH=NO \\\n -scheme \"${SCHEME}\" \\\n -project \"${PROJECT_NAME}.xcodeproj\" \\\n -archivePath ${MACOS_ARCHIVE_PATH} \\\n -sdk macosx \\\n BUILD_LIBRARY_FOR_DISTRIBUTION=YES \\\n SKIP_INSTALL=NO || exit $?\n \n# iOS simulator\nxcodebuild archive \\\n ONLY_ACTIVE_ARCH=NO \\\n -scheme \"${SCHEME}\" \\\n -project \"${PROJECT_NAME}.xcodeproj\" \\\n -archivePath ${IOS_SIMULATOR_ARCHIVE_PATH} \\\n -sdk iphonesimulator \\\n BUILD_LIBRARY_FOR_DISTRIBUTION=YES \\\n SKIP_INSTALL=NO || exit $?\n\n# iOS device\nxcodebuild archive \\\n -scheme \"${SCHEME}\" \\\n -project \"${PROJECT_NAME}.xcodeproj\" \\\n -archivePath ${IOS_DEVICE_ARCHIVE_PATH} \\\n -sdk iphoneos \\\n BUILD_LIBRARY_FOR_DISTRIBUTION=YES \\\n SKIP_INSTALL=NO || exit $?\n\n# tvOS simulator\nxcodebuild archive \\\n ONLY_ACTIVE_ARCH=NO \\\n -scheme \"${SCHEME}\" \\\n -project \"${PROJECT_NAME}.xcodeproj\" \\\n -archivePath ${TVOS_SIMULATOR_ARCHIVE_PATH} \\\n -sdk appletvsimulator \\\n BUILD_LIBRARY_FOR_DISTRIBUTION=YES \\\n SKIP_INSTALL=NO || exit $?\n\n# tvOS device\nxcodebuild archive \\\n -scheme \"${SCHEME}\" \\\n -project \"${PROJECT_NAME}.xcodeproj\" \\\n -archivePath ${TVOS_DEVICE_ARCHIVE_PATH} \\\n -sdk appletvos \\\n BUILD_LIBRARY_FOR_DISTRIBUTION=YES \\\n SKIP_INSTALL=NO || exit $?\n\n# Clean-up any existing instance of this xcframework from the Products directory\nrm -rf \"${OUTPUT_DIR}${FRAMEWORK_NAME}.xcframework\"\n\n# Create final xcframework\nxcodebuild -create-xcframework \\\n -framework \"${MACOS_ARCHIVE_PATH}\"/Products/Library/Frameworks/${FRAMEWORK_NAME}.framework \\\n -framework \"${IOS_DEVICE_ARCHIVE_PATH}\"/Products/Library/Frameworks/${FRAMEWORK_NAME}.framework \\\n -framework \"${IOS_SIMULATOR_ARCHIVE_PATH}\"/Products/Library/Frameworks/${FRAMEWORK_NAME}.framework \\\n -framework \"${TVOS_DEVICE_ARCHIVE_PATH}\"/Products/Library/Frameworks/${FRAMEWORK_NAME}.framework \\\n -framework \"${TVOS_SIMULATOR_ARCHIVE_PATH}\"/Products/Library/Frameworks/${FRAMEWORK_NAME}.framework \\\n -output ${OUTPUT_DIR}/${FRAMEWORK_NAME}.xcframework\n\n# Ensure git doesn't pick up on our Products folder. \nrm -rf ${OUTPUT_DIR}/.gitignore\necho \"*\" >> ${OUTPUT_DIR}/.gitignore\n";
+ };
+/* End PBXShellScriptBuildPhase section */
+
+/* Begin PBXSourcesBuildPhase section */
+ F3F70ED6281F61B4005AA27D /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ F307A2C62B54329C0012534B /* Ym2612_Nuked.cpp in Sources */,
+ F307A2D42B54329C0012534B /* Ay_Emu.cpp in Sources */,
+ F307A2D82B54329C0012534B /* Data_Reader.cpp in Sources */,
+ F307A2DB2B54329C0012534B /* Spc_Filter.cpp in Sources */,
+ F307A2D92B54329C0012534B /* Nes_Apu.cpp in Sources */,
+ F307A2BE2B54329C0012534B /* Blip_Buffer.cpp in Sources */,
+ F307A2D12B54329C0012534B /* Multi_Buffer.cpp in Sources */,
+ F307A2D52B54329C0012534B /* Kss_Scc_Apu.cpp in Sources */,
+ F307A2BD2B54329C0012534B /* Music_Emu.cpp in Sources */,
+ F307A2B92B54329C0012534B /* Kss_Cpu.cpp in Sources */,
+ F307A2C52B54329C0012534B /* Ym2413_Emu.cpp in Sources */,
+ F307A2CA2B54329C0012534B /* Spc_Cpu.cpp in Sources */,
+ F307A2B42B54329C0012534B /* Nes_Namco_Apu.cpp in Sources */,
+ F307A2DD2B54329C0012534B /* gme.cpp in Sources */,
+ F307A2B12B54329C0012534B /* Sap_Cpu.cpp in Sources */,
+ F307A2B62B54329C0012534B /* Vgm_Emu_Impl.cpp in Sources */,
+ F307A2D02B54329C0012534B /* Gb_Apu.cpp in Sources */,
+ F307A2CE2B54329C0012534B /* Nsf_Emu.cpp in Sources */,
+ F307A2D72B54329C0012534B /* Gym_Emu.cpp in Sources */,
+ F307A2B72B54329C0012534B /* Hes_Emu.cpp in Sources */,
+ F307A2BB2B54329C0012534B /* Effects_Buffer.cpp in Sources */,
+ F307A2B02B54329C0012534B /* Nes_Vrc6_Apu.cpp in Sources */,
+ F307A2CB2B54329C0012534B /* Hes_Cpu.cpp in Sources */,
+ F307A2C72B54329C0012534B /* Gme_File.cpp in Sources */,
+ F307A2BC2B54329C0012534B /* Fir_Resampler.cpp in Sources */,
+ F307A2C22B54329C0012534B /* Gbs_Emu.cpp in Sources */,
+ F307A2B82B54329C0012534B /* Snes_Spc.cpp in Sources */,
+ F307A2D22B54329C0012534B /* Spc_Emu.cpp in Sources */,
+ F307A2DF2B5434FF0012534B /* Vgm_Emu.cpp in Sources */,
+ F307A2C12B54329C0012534B /* Classic_Emu.cpp in Sources */,
+ F307A2AF2B54329C0012534B /* Ym2612_GENS.cpp in Sources */,
+ F307A2C02B54329C0012534B /* Sap_Emu.cpp in Sources */,
+ F307A2D62B54329C0012534B /* Ay_Apu.cpp in Sources */,
+ F307A2B22B54329C0012534B /* Dual_Resampler.cpp in Sources */,
+ F307A2CC2B54329C0012534B /* Gb_Cpu.cpp in Sources */,
+ F307A2BA2B54329C0012534B /* Nes_Cpu.cpp in Sources */,
+ F307A2CF2B54329C0012534B /* Hes_Apu.cpp in Sources */,
+ F307A2C32B54329C0012534B /* Nes_Fme7_Apu.cpp in Sources */,
+ F307A2D32B54329C0012534B /* Ay_Cpu.cpp in Sources */,
+ F307A2CD2B54329C0012534B /* Nes_Oscs.cpp in Sources */,
+ F307A2C42B54329C0012534B /* Sms_Apu.cpp in Sources */,
+ F307A2C92B54329C0012534B /* Kss_Emu.cpp in Sources */,
+ F307A2B52B54329C0012534B /* M3u_Playlist.cpp in Sources */,
+ F307A2DA2B54329C0012534B /* Gb_Oscs.cpp in Sources */,
+ F307A2B32B54329C0012534B /* Ym2612_MAME.cpp in Sources */,
+ F307A2BF2B54329C0012534B /* Sap_Apu.cpp in Sources */,
+ F307A2DC2B54329C0012534B /* Spc_Dsp.cpp in Sources */,
+ F307A2C82B54329C0012534B /* Nsfe_Emu.cpp in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXSourcesBuildPhase section */
+
+/* Begin XCBuildConfiguration section */
+ F3B38D90296F9773005DA6D3 /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ };
+ name = Debug;
+ };
+ F3B38D91296F9773005DA6D3 /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ };
+ name = Release;
+ };
+ F3F70EDF281F61B4005AA27D /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALLOW_TARGET_PLATFORM_SPECIALIZATION = YES;
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ CLANG_ANALYZER_NONNULL = YES;
+ CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
+ CLANG_CXX_LANGUAGE_STANDARD = "gnu++17";
+ CLANG_ENABLE_MODULES = YES;
+ CLANG_ENABLE_OBJC_ARC = YES;
+ CLANG_ENABLE_OBJC_WEAK = YES;
+ CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
+ CLANG_WARN_BOOL_CONVERSION = YES;
+ CLANG_WARN_COMMA = YES;
+ CLANG_WARN_CONSTANT_CONVERSION = YES;
+ CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
+ CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
+ CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
+ CLANG_WARN_EMPTY_BODY = YES;
+ CLANG_WARN_ENUM_CONVERSION = YES;
+ CLANG_WARN_INFINITE_RECURSION = YES;
+ CLANG_WARN_INT_CONVERSION = YES;
+ CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
+ CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
+ CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
+ CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+ CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
+ CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
+ CLANG_WARN_STRICT_PROTOTYPES = YES;
+ CLANG_WARN_SUSPICIOUS_MOVE = YES;
+ CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
+ CLANG_WARN_UNREACHABLE_CODE = YES;
+ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+ COPY_PHASE_STRIP = NO;
+ CURRENT_PROJECT_VERSION = 1;
+ DEBUG_INFORMATION_FORMAT = dwarf;
+ ENABLE_STRICT_OBJC_MSGSEND = YES;
+ ENABLE_TESTABILITY = YES;
+ GCC_C_LANGUAGE_STANDARD = gnu11;
+ GCC_DYNAMIC_NO_PIC = NO;
+ GCC_NO_COMMON_BLOCKS = YES;
+ GCC_OPTIMIZATION_LEVEL = 0;
+ GCC_PREPROCESSOR_DEFINITIONS = (
+ "BLARGG_LITTLE_ENDIAN=1",
+ BLARGG_BUILD_DLL,
+ LIBGME_VISIBILITY,
+ VGM_YM2612_NUKED,
+ );
+ GCC_SYMBOLS_PRIVATE_EXTERN = YES;
+ GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+ GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
+ GCC_WARN_UNDECLARED_SELECTOR = YES;
+ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
+ GCC_WARN_UNUSED_FUNCTION = YES;
+ GCC_WARN_UNUSED_VARIABLE = YES;
+ HEADER_SEARCH_PATHS = "\"$(SRCROOT)/../../external/libgme\"";
+ IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+ MACOSX_DEPLOYMENT_TARGET = 10.11;
+ MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
+ MTL_FAST_MATH = YES;
+ ONLY_ACTIVE_ARCH = YES;
+ SUPPORTED_PLATFORMS = "watchsimulator watchos macosx iphonesimulator iphoneos driverkit appletvsimulator appletvos";
+ SUPPORTS_MACCATALYST = YES;
+ TVOS_DEPLOYMENT_TARGET = 9.0;
+ VERSIONING_SYSTEM = "apple-generic";
+ VERSION_INFO_PREFIX = "";
+ };
+ name = Debug;
+ };
+ F3F70EE0281F61B4005AA27D /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALLOW_TARGET_PLATFORM_SPECIALIZATION = YES;
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ CLANG_ANALYZER_NONNULL = YES;
+ CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
+ CLANG_CXX_LANGUAGE_STANDARD = "gnu++17";
+ CLANG_ENABLE_MODULES = YES;
+ CLANG_ENABLE_OBJC_ARC = YES;
+ CLANG_ENABLE_OBJC_WEAK = YES;
+ CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
+ CLANG_WARN_BOOL_CONVERSION = YES;
+ CLANG_WARN_COMMA = YES;
+ CLANG_WARN_CONSTANT_CONVERSION = YES;
+ CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
+ CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
+ CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
+ CLANG_WARN_EMPTY_BODY = YES;
+ CLANG_WARN_ENUM_CONVERSION = YES;
+ CLANG_WARN_INFINITE_RECURSION = YES;
+ CLANG_WARN_INT_CONVERSION = YES;
+ CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
+ CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
+ CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
+ CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+ CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
+ CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
+ CLANG_WARN_STRICT_PROTOTYPES = YES;
+ CLANG_WARN_SUSPICIOUS_MOVE = YES;
+ CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
+ CLANG_WARN_UNREACHABLE_CODE = YES;
+ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+ COPY_PHASE_STRIP = NO;
+ CURRENT_PROJECT_VERSION = 1;
+ DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
+ ENABLE_NS_ASSERTIONS = NO;
+ ENABLE_STRICT_OBJC_MSGSEND = YES;
+ GCC_C_LANGUAGE_STANDARD = gnu11;
+ GCC_NO_COMMON_BLOCKS = YES;
+ GCC_PREPROCESSOR_DEFINITIONS = (
+ "BLARGG_LITTLE_ENDIAN=1",
+ BLARGG_BUILD_DLL,
+ LIBGME_VISIBILITY,
+ VGM_YM2612_NUKED,
+ );
+ GCC_SYMBOLS_PRIVATE_EXTERN = YES;
+ GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+ GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
+ GCC_WARN_UNDECLARED_SELECTOR = YES;
+ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
+ GCC_WARN_UNUSED_FUNCTION = YES;
+ GCC_WARN_UNUSED_VARIABLE = YES;
+ HEADER_SEARCH_PATHS = "\"$(SRCROOT)/../../external/libgme\"";
+ IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+ MACOSX_DEPLOYMENT_TARGET = 10.11;
+ MTL_ENABLE_DEBUG_INFO = NO;
+ MTL_FAST_MATH = YES;
+ SUPPORTED_PLATFORMS = "watchsimulator watchos macosx iphonesimulator iphoneos driverkit appletvsimulator appletvos";
+ SUPPORTS_MACCATALYST = YES;
+ TVOS_DEPLOYMENT_TARGET = 9.0;
+ VERSIONING_SYSTEM = "apple-generic";
+ VERSION_INFO_PREFIX = "";
+ };
+ name = Release;
+ };
+ F3F70EE2281F61B4005AA27D /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ CODE_SIGN_STYLE = Automatic;
+ COMBINE_HIDPI_IMAGES = YES;
+ CURRENT_PROJECT_VERSION = 1;
+ DEFINES_MODULE = YES;
+ DYLIB_COMPATIBILITY_VERSION = 1;
+ DYLIB_CURRENT_VERSION = 1;
+ DYLIB_INSTALL_NAME_BASE = "@rpath";
+ GENERATE_INFOPLIST_FILE = YES;
+ INFOPLIST_KEY_NSHumanReadableCopyright = "";
+ INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
+ LD_RUNPATH_SEARCH_PATHS = (
+ "$(inherited)",
+ "@executable_path/Frameworks",
+ "@loader_path/Frameworks",
+ );
+ MARKETING_VERSION = 1.3.2;
+ PRODUCT_BUNDLE_IDENTIFIER = org.xiph.gme;
+ PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)";
+ SKIP_INSTALL = YES;
+ SWIFT_EMIT_LOC_STRINGS = YES;
+ };
+ name = Debug;
+ };
+ F3F70EE3281F61B4005AA27D /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ CODE_SIGN_STYLE = Automatic;
+ COMBINE_HIDPI_IMAGES = YES;
+ CURRENT_PROJECT_VERSION = 1;
+ DEFINES_MODULE = YES;
+ DYLIB_COMPATIBILITY_VERSION = 1;
+ DYLIB_CURRENT_VERSION = 1;
+ DYLIB_INSTALL_NAME_BASE = "@rpath";
+ GENERATE_INFOPLIST_FILE = YES;
+ INFOPLIST_KEY_NSHumanReadableCopyright = "";
+ INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
+ LD_RUNPATH_SEARCH_PATHS = (
+ "$(inherited)",
+ "@executable_path/Frameworks",
+ "@loader_path/Frameworks",
+ );
+ MARKETING_VERSION = 1.3.2;
+ PRODUCT_BUNDLE_IDENTIFIER = org.xiph.gme;
+ PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)";
+ SKIP_INSTALL = YES;
+ SWIFT_EMIT_LOC_STRINGS = YES;
+ };
+ name = Release;
+ };
+/* End XCBuildConfiguration section */
+
+/* Begin XCConfigurationList section */
+ F3B38D92296F9773005DA6D3 /* Build configuration list for PBXAggregateTarget "gme.xcframework" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ F3B38D90296F9773005DA6D3 /* Debug */,
+ F3B38D91296F9773005DA6D3 /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ F3F70ED4281F61B4005AA27D /* Build configuration list for PBXProject "gme" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ F3F70EDF281F61B4005AA27D /* Debug */,
+ F3F70EE0281F61B4005AA27D /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ F3F70EE1281F61B4005AA27D /* Build configuration list for PBXNativeTarget "gme" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ F3F70EE2281F61B4005AA27D /* Debug */,
+ F3F70EE3281F61B4005AA27D /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+/* End XCConfigurationList section */
+ };
+ rootObject = F3F70ED1281F61B4005AA27D /* Project object */;
+}
diff --git a/Xcode/pkg-support/resources/CMake/sdl2_mixer-config.cmake b/Xcode/pkg-support/resources/CMake/sdl2_mixer-config.cmake
index 7da21f823..a7d769079 100644
--- a/Xcode/pkg-support/resources/CMake/sdl2_mixer-config.cmake
+++ b/Xcode/pkg-support/resources/CMake/sdl2_mixer-config.cmake
@@ -27,7 +27,7 @@ set(SDL2MIXER_MOD_XMP FALSE)
set(SDL2MIXER_MOD_XMP_LITE FALSE)
set(SDL2MIXER_MP3 TRUE)
-set(SDL2MIXER_MP3_DRMP3 TRUE)
+set(SDL2MIXER_MP3_MINIMP3 TRUE)
set(SDL2MIXER_MP3_MPG123 FALSE)
set(SDL2MIXER_MIDI FALSE)
diff --git a/Xcode/playmus/playmus.xcodeproj/project.pbxproj b/Xcode/playmus/playmus.xcodeproj/project.pbxproj
index 5fda8b9cc..b0667e06f 100644
--- a/Xcode/playmus/playmus.xcodeproj/project.pbxproj
+++ b/Xcode/playmus/playmus.xcodeproj/project.pbxproj
@@ -7,6 +7,12 @@
objects = {
/* Begin PBXBuildFile section */
+ F307A4992B544CA20012534B /* gme.framework in Copy Frameworks */ = {isa = PBXBuildFile; fileRef = F307A48B2B544C880012534B /* gme.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
+ F307A49A2B544CAA0012534B /* wavpack.framework in Copy Frameworks */ = {isa = PBXBuildFile; fileRef = F307A4982B544C920012534B /* wavpack.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
+ F307A49B2B544CB90012534B /* gme.framework in Copy Frameworks */ = {isa = PBXBuildFile; fileRef = F307A48B2B544C880012534B /* gme.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
+ F307A49C2B544CBF0012534B /* wavpack.framework in Copy Frameworks */ = {isa = PBXBuildFile; fileRef = F307A4982B544C920012534B /* wavpack.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
+ F307A49D2B544CD60012534B /* gme.framework in Copy Frameworks */ = {isa = PBXBuildFile; fileRef = F307A48B2B544C880012534B /* gme.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
+ F307A49E2B544CDC0012534B /* wavpack.framework in Copy Frameworks */ = {isa = PBXBuildFile; fileRef = F307A4982B544C920012534B /* wavpack.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
F3968EBF2820392700661875 /* SDL2.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F3968EBE2820392700661875 /* SDL2.framework */; };
F3968EC1282039AC00661875 /* SDL2.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F3968EC0282039AC00661875 /* SDL2.framework */; };
F3968EC3282039BC00661875 /* SDL2.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F3968EC2282039BC00661875 /* SDL2.framework */; };
@@ -36,6 +42,20 @@
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
+ F307A48A2B544C880012534B /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = F307A4852B544C880012534B /* gme.xcodeproj */;
+ proxyType = 2;
+ remoteGlobalIDString = F3F70EDA281F61B4005AA27D;
+ remoteInfo = gme;
+ };
+ F307A4972B544C920012534B /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = F307A4922B544C920012534B /* wavpack.xcodeproj */;
+ proxyType = 2;
+ remoteGlobalIDString = F3968A21281F704800661875;
+ remoteInfo = wavpack;
+ };
F3968EA9282038E000661875 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = F3968EA5282038E000661875 /* opus.xcodeproj */;
@@ -55,7 +75,7 @@
containerPortal = F3E29D282882122B0006D108 /* xmp.xcodeproj */;
proxyType = 2;
remoteGlobalIDString = F3968D85281FBB1900661875;
- remoteInfo = "xmp";
+ remoteInfo = xmp;
};
F3ED80D3281D9ED600C33C5B /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
@@ -89,8 +109,10 @@
files = (
F3968F142820428F00661875 /* SDL2.framework in Copy Frameworks */,
F39CD44B281DC6C8006CF638 /* SDL2_mixer.framework in Copy Frameworks */,
+ F307A49D2B544CD60012534B /* gme.framework in Copy Frameworks */,
F3968F112820428F00661875 /* ogg.framework in Copy Frameworks */,
F3968F122820428F00661875 /* opus.framework in Copy Frameworks */,
+ F307A49E2B544CDC0012534B /* wavpack.framework in Copy Frameworks */,
F3E29D3D288212520006D108 /* xmp.framework in Copy Frameworks */,
);
name = "Copy Frameworks";
@@ -107,6 +129,8 @@
F3968ED328203F5800661875 /* ogg.framework in Copy Frameworks */,
F3968ED428203F5800661875 /* opus.framework in Copy Frameworks */,
F3E29D3C2882124D0006D108 /* xmp.framework in Copy Frameworks */,
+ F307A49B2B544CB90012534B /* gme.framework in Copy Frameworks */,
+ F307A49C2B544CBF0012534B /* wavpack.framework in Copy Frameworks */,
);
name = "Copy Frameworks";
runOnlyForDeploymentPostprocessing = 0;
@@ -119,8 +143,10 @@
files = (
F3968EEF2820409F00661875 /* SDL2.framework in Copy Frameworks */,
F3ED80FF281DA63000C33C5B /* SDL2_mixer.framework in Copy Frameworks */,
+ F307A4992B544CA20012534B /* gme.framework in Copy Frameworks */,
F3968EF3282040B300661875 /* ogg.framework in Copy Frameworks */,
F3968EF4282040B300661875 /* opus.framework in Copy Frameworks */,
+ F307A49A2B544CAA0012534B /* wavpack.framework in Copy Frameworks */,
F3E29D36288212480006D108 /* xmp.framework in Copy Frameworks */,
);
name = "Copy Frameworks";
@@ -129,12 +155,14 @@
/* End PBXCopyFilesBuildPhase section */
/* Begin PBXFileReference section */
+ F307A4852B544C880012534B /* gme.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = gme.xcodeproj; path = ../gme/gme.xcodeproj; sourceTree = ""; };
+ F307A4922B544C920012534B /* wavpack.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = wavpack.xcodeproj; path = ../wavpack/wavpack.xcodeproj; sourceTree = ""; };
F3968EA5282038E000661875 /* opus.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = opus.xcodeproj; path = ../opus/opus.xcodeproj; sourceTree = ""; };
F3968EB72820390500661875 /* ogg.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = ogg.xcodeproj; path = ../ogg/ogg.xcodeproj; sourceTree = ""; };
F3968EBE2820392700661875 /* SDL2.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SDL2.framework; path = ../macOS/SDL2.framework; sourceTree = ""; };
F3968EC0282039AC00661875 /* SDL2.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SDL2.framework; path = ../iOS/SDL2.framework; sourceTree = ""; };
F3968EC2282039BC00661875 /* SDL2.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SDL2.framework; path = ../tvOS/SDL2.framework; sourceTree = ""; };
- F3E29D282882122B0006D108 /* xmp.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = "xmp.xcodeproj"; path = "../xmp/xmp.xcodeproj"; sourceTree = ""; };
+ F3E29D282882122B0006D108 /* xmp.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = xmp.xcodeproj; path = ../xmp/xmp.xcodeproj; sourceTree = ""; };
F3ED80B3281D9E8900C33C5B /* playmus.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = playmus.app; sourceTree = BUILT_PRODUCTS_DIR; };
F3ED80B9281D9E8900C33C5B /* playmus.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = playmus.app; sourceTree = BUILT_PRODUCTS_DIR; };
F3ED80BB281D9E8900C33C5B /* macOS.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = macOS.entitlements; sourceTree = ""; };
@@ -175,6 +203,22 @@
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
+ F307A4862B544C880012534B /* Products */ = {
+ isa = PBXGroup;
+ children = (
+ F307A48B2B544C880012534B /* gme.framework */,
+ );
+ name = Products;
+ sourceTree = "";
+ };
+ F307A4932B544C920012534B /* Products */ = {
+ isa = PBXGroup;
+ children = (
+ F307A4982B544C920012534B /* wavpack.framework */,
+ );
+ name = Products;
+ sourceTree = "";
+ };
F3968EA6282038E000661875 /* Products */ = {
isa = PBXGroup;
children = (
@@ -236,9 +280,11 @@
F3ED80A6281D9E8800C33C5B = {
isa = PBXGroup;
children = (
+ F307A4852B544C880012534B /* gme.xcodeproj */,
F3968EB72820390500661875 /* ogg.xcodeproj */,
F3968EA5282038E000661875 /* opus.xcodeproj */,
F3E29D282882122B0006D108 /* xmp.xcodeproj */,
+ F307A4922B544C920012534B /* wavpack.xcodeproj */,
F3ED80CD281D9ED600C33C5B /* SDL_mixer.xcodeproj */,
F3ED80AB281D9E8800C33C5B /* Shared */,
F3ED80BA281D9E8900C33C5B /* macOS */,
@@ -371,6 +417,10 @@
productRefGroup = F3ED80B4281D9E8900C33C5B /* Products */;
projectDirPath = "";
projectReferences = (
+ {
+ ProductGroup = F307A4862B544C880012534B /* Products */;
+ ProjectRef = F307A4852B544C880012534B /* gme.xcodeproj */;
+ },
{
ProductGroup = F3968EB82820390500661875 /* Products */;
ProjectRef = F3968EB72820390500661875 /* ogg.xcodeproj */;
@@ -383,6 +433,10 @@
ProductGroup = F3ED80CE281D9ED600C33C5B /* Products */;
ProjectRef = F3ED80CD281D9ED600C33C5B /* SDL_mixer.xcodeproj */;
},
+ {
+ ProductGroup = F307A4932B544C920012534B /* Products */;
+ ProjectRef = F307A4922B544C920012534B /* wavpack.xcodeproj */;
+ },
{
ProductGroup = F3E29D292882122B0006D108 /* Products */;
ProjectRef = F3E29D282882122B0006D108 /* xmp.xcodeproj */;
@@ -398,6 +452,20 @@
/* End PBXProject section */
/* Begin PBXReferenceProxy section */
+ F307A48B2B544C880012534B /* gme.framework */ = {
+ isa = PBXReferenceProxy;
+ fileType = wrapper.framework;
+ path = gme.framework;
+ remoteRef = F307A48A2B544C880012534B /* PBXContainerItemProxy */;
+ sourceTree = BUILT_PRODUCTS_DIR;
+ };
+ F307A4982B544C920012534B /* wavpack.framework */ = {
+ isa = PBXReferenceProxy;
+ fileType = wrapper.framework;
+ path = wavpack.framework;
+ remoteRef = F307A4972B544C920012534B /* PBXContainerItemProxy */;
+ sourceTree = BUILT_PRODUCTS_DIR;
+ };
F3968EAA282038E000661875 /* opus.framework */ = {
isa = PBXReferenceProxy;
fileType = wrapper.framework;
diff --git a/Xcode/playwave/playwave.xcodeproj/project.pbxproj b/Xcode/playwave/playwave.xcodeproj/project.pbxproj
index f79ac1af2..a80107205 100644
--- a/Xcode/playwave/playwave.xcodeproj/project.pbxproj
+++ b/Xcode/playwave/playwave.xcodeproj/project.pbxproj
@@ -7,6 +7,12 @@
objects = {
/* Begin PBXBuildFile section */
+ F307A4C72B544D190012534B /* gme.framework in Copy Frameworks */ = {isa = PBXBuildFile; fileRef = F307A4B92B544D030012534B /* gme.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
+ F307A4C82B544D1D0012534B /* wavpack.framework in Copy Frameworks */ = {isa = PBXBuildFile; fileRef = F307A4C62B544D0C0012534B /* wavpack.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
+ F307A4C92B544D290012534B /* gme.framework in Copy Frameworks */ = {isa = PBXBuildFile; fileRef = F307A4B92B544D030012534B /* gme.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
+ F307A4CA2B544D290012534B /* wavpack.framework in Copy Frameworks */ = {isa = PBXBuildFile; fileRef = F307A4C62B544D0C0012534B /* wavpack.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
+ F307A4CB2B544D360012534B /* gme.framework in Copy Frameworks */ = {isa = PBXBuildFile; fileRef = F307A4B92B544D030012534B /* gme.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
+ F307A4CC2B544D360012534B /* wavpack.framework in Copy Frameworks */ = {isa = PBXBuildFile; fileRef = F307A4C62B544D0C0012534B /* wavpack.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
F3968EBF2820392700661875 /* SDL2.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F3968EBE2820392700661875 /* SDL2.framework */; };
F3968EC1282039AC00661875 /* SDL2.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F3968EC0282039AC00661875 /* SDL2.framework */; };
F3968EC3282039BC00661875 /* SDL2.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F3968EC2282039BC00661875 /* SDL2.framework */; };
@@ -36,6 +42,20 @@
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
+ F307A4B82B544D030012534B /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = F307A4B32B544D030012534B /* gme.xcodeproj */;
+ proxyType = 2;
+ remoteGlobalIDString = F3F70EDA281F61B4005AA27D;
+ remoteInfo = gme;
+ };
+ F307A4C52B544D0C0012534B /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = F307A4C02B544D0C0012534B /* wavpack.xcodeproj */;
+ proxyType = 2;
+ remoteGlobalIDString = F3968A21281F704800661875;
+ remoteInfo = wavpack;
+ };
F3968EA9282038E000661875 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = F3968EA5282038E000661875 /* opus.xcodeproj */;
@@ -55,7 +75,7 @@
containerPortal = F3E29D11288211A60006D108 /* xmp.xcodeproj */;
proxyType = 2;
remoteGlobalIDString = F3968D85281FBB1900661875;
- remoteInfo = "xmp";
+ remoteInfo = xmp;
};
F3ED80D3281D9ED600C33C5B /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
@@ -89,8 +109,10 @@
files = (
F3968F142820428F00661875 /* SDL2.framework in Copy Frameworks */,
F39CD44B281DC6C8006CF638 /* SDL2_mixer.framework in Copy Frameworks */,
+ F307A4CB2B544D360012534B /* gme.framework in Copy Frameworks */,
F3968F112820428F00661875 /* ogg.framework in Copy Frameworks */,
F3968F122820428F00661875 /* opus.framework in Copy Frameworks */,
+ F307A4CC2B544D360012534B /* wavpack.framework in Copy Frameworks */,
F3E29D1E288211CF0006D108 /* xmp.framework in Copy Frameworks */,
);
name = "Copy Frameworks";
@@ -104,8 +126,10 @@
files = (
F3968ECE28203E7300661875 /* SDL2.framework in Copy Frameworks */,
F3968ECF28203F3100661875 /* SDL2_mixer.framework in Copy Frameworks */,
+ F307A4C92B544D290012534B /* gme.framework in Copy Frameworks */,
F3968ED328203F5800661875 /* ogg.framework in Copy Frameworks */,
F3968ED428203F5800661875 /* opus.framework in Copy Frameworks */,
+ F307A4CA2B544D290012534B /* wavpack.framework in Copy Frameworks */,
F3E29D1C288211B90006D108 /* xmp.framework in Copy Frameworks */,
);
name = "Copy Frameworks";
@@ -119,8 +143,10 @@
files = (
F3968EEF2820409F00661875 /* SDL2.framework in Copy Frameworks */,
F3ED80FF281DA63000C33C5B /* SDL2_mixer.framework in Copy Frameworks */,
+ F307A4C72B544D190012534B /* gme.framework in Copy Frameworks */,
F3968EF3282040B300661875 /* ogg.framework in Copy Frameworks */,
F3968EF4282040B300661875 /* opus.framework in Copy Frameworks */,
+ F307A4C82B544D1D0012534B /* wavpack.framework in Copy Frameworks */,
F3E29D1D288211CA0006D108 /* xmp.framework in Copy Frameworks */,
);
name = "Copy Frameworks";
@@ -129,12 +155,14 @@
/* End PBXCopyFilesBuildPhase section */
/* Begin PBXFileReference section */
+ F307A4B32B544D030012534B /* gme.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = gme.xcodeproj; path = ../gme/gme.xcodeproj; sourceTree = ""; };
+ F307A4C02B544D0C0012534B /* wavpack.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = wavpack.xcodeproj; path = ../wavpack/wavpack.xcodeproj; sourceTree = ""; };
F3968EA5282038E000661875 /* opus.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = opus.xcodeproj; path = ../opus/opus.xcodeproj; sourceTree = ""; };
F3968EB72820390500661875 /* ogg.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = ogg.xcodeproj; path = ../ogg/ogg.xcodeproj; sourceTree = ""; };
F3968EBE2820392700661875 /* SDL2.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SDL2.framework; path = ../macOS/SDL2.framework; sourceTree = ""; };
F3968EC0282039AC00661875 /* SDL2.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SDL2.framework; path = ../iOS/SDL2.framework; sourceTree = ""; };
F3968EC2282039BC00661875 /* SDL2.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SDL2.framework; path = ../tvOS/SDL2.framework; sourceTree = ""; };
- F3E29D11288211A60006D108 /* xmp.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = "xmp.xcodeproj"; path = "../xmp/xmp.xcodeproj"; sourceTree = ""; };
+ F3E29D11288211A60006D108 /* xmp.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = xmp.xcodeproj; path = ../xmp/xmp.xcodeproj; sourceTree = ""; };
F3ED80B3281D9E8900C33C5B /* playwave.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = playwave.app; sourceTree = BUILT_PRODUCTS_DIR; };
F3ED80B9281D9E8900C33C5B /* playwave.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = playwave.app; sourceTree = BUILT_PRODUCTS_DIR; };
F3ED80BB281D9E8900C33C5B /* macOS.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = macOS.entitlements; sourceTree = ""; };
@@ -175,6 +203,22 @@
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
+ F307A4B42B544D030012534B /* Products */ = {
+ isa = PBXGroup;
+ children = (
+ F307A4B92B544D030012534B /* gme.framework */,
+ );
+ name = Products;
+ sourceTree = "";
+ };
+ F307A4C12B544D0C0012534B /* Products */ = {
+ isa = PBXGroup;
+ children = (
+ F307A4C62B544D0C0012534B /* wavpack.framework */,
+ );
+ name = Products;
+ sourceTree = "";
+ };
F3968EA6282038E000661875 /* Products */ = {
isa = PBXGroup;
children = (
@@ -236,8 +280,10 @@
F3ED80A6281D9E8800C33C5B = {
isa = PBXGroup;
children = (
+ F307A4B32B544D030012534B /* gme.xcodeproj */,
F3968EB72820390500661875 /* ogg.xcodeproj */,
F3968EA5282038E000661875 /* opus.xcodeproj */,
+ F307A4C02B544D0C0012534B /* wavpack.xcodeproj */,
F3E29D11288211A60006D108 /* xmp.xcodeproj */,
F3ED80CD281D9ED600C33C5B /* SDL_mixer.xcodeproj */,
F3ED80AB281D9E8800C33C5B /* Shared */,
@@ -371,6 +417,10 @@
productRefGroup = F3ED80B4281D9E8900C33C5B /* Products */;
projectDirPath = "";
projectReferences = (
+ {
+ ProductGroup = F307A4B42B544D030012534B /* Products */;
+ ProjectRef = F307A4B32B544D030012534B /* gme.xcodeproj */;
+ },
{
ProductGroup = F3968EB82820390500661875 /* Products */;
ProjectRef = F3968EB72820390500661875 /* ogg.xcodeproj */;
@@ -383,6 +433,10 @@
ProductGroup = F3ED80CE281D9ED600C33C5B /* Products */;
ProjectRef = F3ED80CD281D9ED600C33C5B /* SDL_mixer.xcodeproj */;
},
+ {
+ ProductGroup = F307A4C12B544D0C0012534B /* Products */;
+ ProjectRef = F307A4C02B544D0C0012534B /* wavpack.xcodeproj */;
+ },
{
ProductGroup = F3E29D12288211A60006D108 /* Products */;
ProjectRef = F3E29D11288211A60006D108 /* xmp.xcodeproj */;
@@ -398,6 +452,20 @@
/* End PBXProject section */
/* Begin PBXReferenceProxy section */
+ F307A4B92B544D030012534B /* gme.framework */ = {
+ isa = PBXReferenceProxy;
+ fileType = wrapper.framework;
+ path = gme.framework;
+ remoteRef = F307A4B82B544D030012534B /* PBXContainerItemProxy */;
+ sourceTree = BUILT_PRODUCTS_DIR;
+ };
+ F307A4C62B544D0C0012534B /* wavpack.framework */ = {
+ isa = PBXReferenceProxy;
+ fileType = wrapper.framework;
+ path = wavpack.framework;
+ remoteRef = F307A4C52B544D0C0012534B /* PBXContainerItemProxy */;
+ sourceTree = BUILT_PRODUCTS_DIR;
+ };
F3968EAA282038E000661875 /* opus.framework */ = {
isa = PBXReferenceProxy;
fileType = wrapper.framework;
diff --git a/Xcode/wavpack/config.xcconfig b/Xcode/wavpack/config.xcconfig
new file mode 100644
index 000000000..38de3d4da
--- /dev/null
+++ b/Xcode/wavpack/config.xcconfig
@@ -0,0 +1,22 @@
+//
+// sources.xcconfig
+// wavpack
+//
+
+// Configuration settings file format documentation can be found at:
+// https://help.apple.com/xcode/#/dev745c5c974
+
+ARM_SOURCES = */*_armv7*
+X86_SOURCES = */*_x86*
+X64_SOURCES = */*_x64*
+
+EXCLUDED_SOURCE_FILE_NAMES = $(ARM_SOURCES) $(X86_SOURCES) $(X64_SOURCES)
+INCLUDED_SOURCE_FILE_NAMES =
+INCLUDED_SOURCE_FILE_NAMES[arch=armv7] = $(ARM_SOURCES)
+INCLUDED_SOURCE_FILE_NAMES[arch=i386] = $(X86_SOURCES)
+INCLUDED_SOURCE_FILE_NAMES[arch=x86_64] = $(X64_SOURCES)
+
+CONFIG_PREPROCESSOR_DEFINITIONS = $(inherited)
+CONFIG_PREPROCESSOR_DEFINITIONS[arch=armv7] = $(inherited) OPT_ASM_ARM32
+CONFIG_PREPROCESSOR_DEFINITIONS[arch=i386] = $(inherited) OPT_ASM_X86
+CONFIG_PREPROCESSOR_DEFINITIONS[arch=x86_64] = $(inherited) OPT_ASM_X64
diff --git a/Xcode/wavpack/wavpack.xcodeproj/project.pbxproj b/Xcode/wavpack/wavpack.xcodeproj/project.pbxproj
new file mode 100644
index 000000000..dc6b90d51
--- /dev/null
+++ b/Xcode/wavpack/wavpack.xcodeproj/project.pbxproj
@@ -0,0 +1,567 @@
+// !$*UTF8*$!
+{
+ archiveVersion = 1;
+ classes = {
+ };
+ objectVersion = 55;
+ objects = {
+
+/* Begin PBXAggregateTarget section */
+ F3B38D49296F8DDD005DA6D3 /* wavpack.xcframework */ = {
+ isa = PBXAggregateTarget;
+ buildConfigurationList = F3B38D4D296F8DDD005DA6D3 /* Build configuration list for PBXAggregateTarget "wavpack.xcframework" */;
+ buildPhases = (
+ F3B38D4E296F8DF9005DA6D3 /* ShellScript */,
+ );
+ dependencies = (
+ );
+ name = wavpack.xcframework;
+ productName = xcFramework;
+ };
+/* End PBXAggregateTarget section */
+
+/* Begin PBXBuildFile section */
+ F307A2E32B54361B0012534B /* README.md in Resources */ = {isa = PBXBuildFile; fileRef = F307A2E22B54361B0012534B /* README.md */; };
+ F307A3042B5436B00012534B /* open_raw.c in Sources */ = {isa = PBXBuildFile; fileRef = F307A2E52B5436AF0012534B /* open_raw.c */; };
+ F307A3052B5436B00012534B /* open_utils.c in Sources */ = {isa = PBXBuildFile; fileRef = F307A2E62B5436AF0012534B /* open_utils.c */; };
+ F307A3072B5436B00012534B /* pack_x64.S in Sources */ = {isa = PBXBuildFile; fileRef = F307A2E82B5436AF0012534B /* pack_x64.S */; };
+ F307A3082B5436B00012534B /* common_utils.c in Sources */ = {isa = PBXBuildFile; fileRef = F307A2E92B5436AF0012534B /* common_utils.c */; };
+ F307A3092B5436B00012534B /* tag_utils.c in Sources */ = {isa = PBXBuildFile; fileRef = F307A2EA2B5436B00012534B /* tag_utils.c */; };
+ F307A30A2B5436B00012534B /* unpack_utils.c in Sources */ = {isa = PBXBuildFile; fileRef = F307A2EB2B5436B00012534B /* unpack_utils.c */; };
+ F307A30B2B5436B00012534B /* write_words.c in Sources */ = {isa = PBXBuildFile; fileRef = F307A2EC2B5436B00012534B /* write_words.c */; };
+ F307A30C2B5436B00012534B /* pack_x86.S in Sources */ = {isa = PBXBuildFile; fileRef = F307A2ED2B5436B00012534B /* pack_x86.S */; };
+ F307A30E2B5436B00012534B /* open_legacy.c in Sources */ = {isa = PBXBuildFile; fileRef = F307A2EF2B5436B00012534B /* open_legacy.c */; };
+ F307A30F2B5436B00012534B /* pack_dsd.c in Sources */ = {isa = PBXBuildFile; fileRef = F307A2F02B5436B00012534B /* pack_dsd.c */; };
+ F307A3102B5436B00012534B /* pack_floats.c in Sources */ = {isa = PBXBuildFile; fileRef = F307A2F12B5436B00012534B /* pack_floats.c */; };
+ F307A3112B5436B00012534B /* pack_dns.c in Sources */ = {isa = PBXBuildFile; fileRef = F307A2F22B5436B00012534B /* pack_dns.c */; };
+ F307A3122B5436B00012534B /* unpack_seek.c in Sources */ = {isa = PBXBuildFile; fileRef = F307A2F32B5436B00012534B /* unpack_seek.c */; };
+ F307A3132B5436B00012534B /* entropy_utils.c in Sources */ = {isa = PBXBuildFile; fileRef = F307A2F42B5436B00012534B /* entropy_utils.c */; };
+ F307A3142B5436B00012534B /* pack.c in Sources */ = {isa = PBXBuildFile; fileRef = F307A2F52B5436B00012534B /* pack.c */; };
+ F307A3152B5436B00012534B /* unpack_armv7.S in Sources */ = {isa = PBXBuildFile; fileRef = F307A2F62B5436B00012534B /* unpack_armv7.S */; };
+ F307A3162B5436B00012534B /* unpack_x86.S in Sources */ = {isa = PBXBuildFile; fileRef = F307A2F72B5436B00012534B /* unpack_x86.S */; };
+ F307A3172B5436B00012534B /* decorr_utils.c in Sources */ = {isa = PBXBuildFile; fileRef = F307A2F82B5436B00012534B /* decorr_utils.c */; };
+ F307A3182B5436B00012534B /* pack_utils.c in Sources */ = {isa = PBXBuildFile; fileRef = F307A2F92B5436B00012534B /* pack_utils.c */; };
+ F307A3192B5436B00012534B /* unpack_dsd.c in Sources */ = {isa = PBXBuildFile; fileRef = F307A2FA2B5436B00012534B /* unpack_dsd.c */; };
+ F307A31A2B5436B00012534B /* read_words.c in Sources */ = {isa = PBXBuildFile; fileRef = F307A2FB2B5436B00012534B /* read_words.c */; };
+ F307A31B2B5436B00012534B /* unpack_floats.c in Sources */ = {isa = PBXBuildFile; fileRef = F307A2FC2B5436B00012534B /* unpack_floats.c */; };
+ F307A31C2B5436B00012534B /* unpack_x64.S in Sources */ = {isa = PBXBuildFile; fileRef = F307A2FD2B5436B00012534B /* unpack_x64.S */; };
+ F307A31D2B5436B00012534B /* unpack.c in Sources */ = {isa = PBXBuildFile; fileRef = F307A2FE2B5436B00012534B /* unpack.c */; };
+ F307A31E2B5436B00012534B /* open_filename.c in Sources */ = {isa = PBXBuildFile; fileRef = F307A2FF2B5436B00012534B /* open_filename.c */; };
+ F307A31F2B5436B00012534B /* extra2.c in Sources */ = {isa = PBXBuildFile; fileRef = F307A3002B5436B00012534B /* extra2.c */; };
+ F307A3202B5436B00012534B /* extra1.c in Sources */ = {isa = PBXBuildFile; fileRef = F307A3012B5436B00012534B /* extra1.c */; };
+ F307A3212B5436B00012534B /* tags.c in Sources */ = {isa = PBXBuildFile; fileRef = F307A3022B5436B00012534B /* tags.c */; };
+ F3968B55281F757800661875 /* wavpack.h in Headers */ = {isa = PBXBuildFile; fileRef = F3968B50281F757800661875 /* wavpack.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ F3968B5A281F75B200661875 /* COPYING in Resources */ = {isa = PBXBuildFile; fileRef = F3968B58281F75B200661875 /* COPYING */; };
+/* End PBXBuildFile section */
+
+/* Begin PBXFileReference section */
+ F307A2E22B54361B0012534B /* README.md */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = net.daringfireball.markdown; name = README.md; path = ../../external/wavpack/README.md; sourceTree = ""; };
+ F307A2E52B5436AF0012534B /* open_raw.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = open_raw.c; path = ../../external/wavpack/src/open_raw.c; sourceTree = ""; };
+ F307A2E62B5436AF0012534B /* open_utils.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = open_utils.c; path = ../../external/wavpack/src/open_utils.c; sourceTree = ""; };
+ F307A2E82B5436AF0012534B /* pack_x64.S */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.asm; name = pack_x64.S; path = ../../external/wavpack/src/pack_x64.S; sourceTree = ""; };
+ F307A2E92B5436AF0012534B /* common_utils.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = common_utils.c; path = ../../external/wavpack/src/common_utils.c; sourceTree = ""; };
+ F307A2EA2B5436B00012534B /* tag_utils.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = tag_utils.c; path = ../../external/wavpack/src/tag_utils.c; sourceTree = ""; };
+ F307A2EB2B5436B00012534B /* unpack_utils.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = unpack_utils.c; path = ../../external/wavpack/src/unpack_utils.c; sourceTree = ""; };
+ F307A2EC2B5436B00012534B /* write_words.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = write_words.c; path = ../../external/wavpack/src/write_words.c; sourceTree = ""; };
+ F307A2ED2B5436B00012534B /* pack_x86.S */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.asm; name = pack_x86.S; path = ../../external/wavpack/src/pack_x86.S; sourceTree = ""; };
+ F307A2EF2B5436B00012534B /* open_legacy.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = open_legacy.c; path = ../../external/wavpack/src/open_legacy.c; sourceTree = ""; };
+ F307A2F02B5436B00012534B /* pack_dsd.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = pack_dsd.c; path = ../../external/wavpack/src/pack_dsd.c; sourceTree = ""; };
+ F307A2F12B5436B00012534B /* pack_floats.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = pack_floats.c; path = ../../external/wavpack/src/pack_floats.c; sourceTree = ""; };
+ F307A2F22B5436B00012534B /* pack_dns.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = pack_dns.c; path = ../../external/wavpack/src/pack_dns.c; sourceTree = ""; };
+ F307A2F32B5436B00012534B /* unpack_seek.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = unpack_seek.c; path = ../../external/wavpack/src/unpack_seek.c; sourceTree = ""; };
+ F307A2F42B5436B00012534B /* entropy_utils.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = entropy_utils.c; path = ../../external/wavpack/src/entropy_utils.c; sourceTree = ""; };
+ F307A2F52B5436B00012534B /* pack.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = pack.c; path = ../../external/wavpack/src/pack.c; sourceTree = ""; };
+ F307A2F62B5436B00012534B /* unpack_armv7.S */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.asm; name = unpack_armv7.S; path = ../../external/wavpack/src/unpack_armv7.S; sourceTree = ""; };
+ F307A2F72B5436B00012534B /* unpack_x86.S */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.asm; name = unpack_x86.S; path = ../../external/wavpack/src/unpack_x86.S; sourceTree = ""; };
+ F307A2F82B5436B00012534B /* decorr_utils.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = decorr_utils.c; path = ../../external/wavpack/src/decorr_utils.c; sourceTree = ""; };
+ F307A2F92B5436B00012534B /* pack_utils.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = pack_utils.c; path = ../../external/wavpack/src/pack_utils.c; sourceTree = ""; };
+ F307A2FA2B5436B00012534B /* unpack_dsd.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = unpack_dsd.c; path = ../../external/wavpack/src/unpack_dsd.c; sourceTree = ""; };
+ F307A2FB2B5436B00012534B /* read_words.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = read_words.c; path = ../../external/wavpack/src/read_words.c; sourceTree = ""; };
+ F307A2FC2B5436B00012534B /* unpack_floats.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = unpack_floats.c; path = ../../external/wavpack/src/unpack_floats.c; sourceTree = ""; };
+ F307A2FD2B5436B00012534B /* unpack_x64.S */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.asm; name = unpack_x64.S; path = ../../external/wavpack/src/unpack_x64.S; sourceTree = ""; };
+ F307A2FE2B5436B00012534B /* unpack.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = unpack.c; path = ../../external/wavpack/src/unpack.c; sourceTree = ""; };
+ F307A2FF2B5436B00012534B /* open_filename.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = open_filename.c; path = ../../external/wavpack/src/open_filename.c; sourceTree = ""; };
+ F307A3002B5436B00012534B /* extra2.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = extra2.c; path = ../../external/wavpack/src/extra2.c; sourceTree = ""; };
+ F307A3012B5436B00012534B /* extra1.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = extra1.c; path = ../../external/wavpack/src/extra1.c; sourceTree = ""; };
+ F307A3022B5436B00012534B /* tags.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = tags.c; path = ../../external/wavpack/src/tags.c; sourceTree = ""; };
+ F3968A21281F704800661875 /* wavpack.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = wavpack.framework; sourceTree = BUILT_PRODUCTS_DIR; };
+ F3968B50281F757800661875 /* wavpack.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = wavpack.h; path = ../../external/wavpack/include/wavpack.h; sourceTree = ""; };
+ F3968B58281F75B200661875 /* COPYING */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = COPYING; path = ../../external/wavpack/COPYING; sourceTree = ""; };
+ F3968BB5281FA13C00661875 /* config.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = config.xcconfig; sourceTree = ""; };
+/* End PBXFileReference section */
+
+/* Begin PBXFrameworksBuildPhase section */
+ F3968A1E281F704800661875 /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXFrameworksBuildPhase section */
+
+/* Begin PBXGroup section */
+ F3968A17281F704800661875 = {
+ isa = PBXGroup;
+ children = (
+ F3968BB5281FA13C00661875 /* config.xcconfig */,
+ F3968A22281F704800661875 /* Products */,
+ F3968A2D281F70E700661875 /* Resources */,
+ F3968A2C281F70DE00661875 /* Headers */,
+ F3968A2B281F70D600661875 /* Source */,
+ F3968B6A281F787F00661875 /* Frameworks */,
+ );
+ sourceTree = "";
+ };
+ F3968A22281F704800661875 /* Products */ = {
+ isa = PBXGroup;
+ children = (
+ F3968A21281F704800661875 /* wavpack.framework */,
+ );
+ name = Products;
+ sourceTree = "";
+ };
+ F3968A2B281F70D600661875 /* Source */ = {
+ isa = PBXGroup;
+ children = (
+ F307A2E92B5436AF0012534B /* common_utils.c */,
+ F307A2F82B5436B00012534B /* decorr_utils.c */,
+ F307A2F42B5436B00012534B /* entropy_utils.c */,
+ F307A3012B5436B00012534B /* extra1.c */,
+ F307A3002B5436B00012534B /* extra2.c */,
+ F307A2FF2B5436B00012534B /* open_filename.c */,
+ F307A2EF2B5436B00012534B /* open_legacy.c */,
+ F307A2E52B5436AF0012534B /* open_raw.c */,
+ F307A2E62B5436AF0012534B /* open_utils.c */,
+ F307A2F22B5436B00012534B /* pack_dns.c */,
+ F307A2F02B5436B00012534B /* pack_dsd.c */,
+ F307A2F12B5436B00012534B /* pack_floats.c */,
+ F307A2F92B5436B00012534B /* pack_utils.c */,
+ F307A2E82B5436AF0012534B /* pack_x64.S */,
+ F307A2ED2B5436B00012534B /* pack_x86.S */,
+ F307A2F52B5436B00012534B /* pack.c */,
+ F307A2FB2B5436B00012534B /* read_words.c */,
+ F307A2EA2B5436B00012534B /* tag_utils.c */,
+ F307A3022B5436B00012534B /* tags.c */,
+ F307A2F62B5436B00012534B /* unpack_armv7.S */,
+ F307A2FA2B5436B00012534B /* unpack_dsd.c */,
+ F307A2FC2B5436B00012534B /* unpack_floats.c */,
+ F307A2F32B5436B00012534B /* unpack_seek.c */,
+ F307A2EB2B5436B00012534B /* unpack_utils.c */,
+ F307A2FD2B5436B00012534B /* unpack_x64.S */,
+ F307A2F72B5436B00012534B /* unpack_x86.S */,
+ F307A2FE2B5436B00012534B /* unpack.c */,
+ F307A2EC2B5436B00012534B /* write_words.c */,
+ );
+ name = Source;
+ sourceTree = "";
+ };
+ F3968A2C281F70DE00661875 /* Headers */ = {
+ isa = PBXGroup;
+ children = (
+ F3968B50281F757800661875 /* wavpack.h */,
+ );
+ name = Headers;
+ sourceTree = "";
+ };
+ F3968A2D281F70E700661875 /* Resources */ = {
+ isa = PBXGroup;
+ children = (
+ F307A2E22B54361B0012534B /* README.md */,
+ F3968B58281F75B200661875 /* COPYING */,
+ );
+ name = Resources;
+ sourceTree = "";
+ };
+ F3968B6A281F787F00661875 /* Frameworks */ = {
+ isa = PBXGroup;
+ children = (
+ );
+ name = Frameworks;
+ sourceTree = "";
+ };
+/* End PBXGroup section */
+
+/* Begin PBXHeadersBuildPhase section */
+ F3968A1C281F704800661875 /* Headers */ = {
+ isa = PBXHeadersBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ F3968B55281F757800661875 /* wavpack.h in Headers */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXHeadersBuildPhase section */
+
+/* Begin PBXNativeTarget section */
+ F3968A20281F704800661875 /* wavpack */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = F3968A28281F704800661875 /* Build configuration list for PBXNativeTarget "wavpack" */;
+ buildPhases = (
+ F3968A1C281F704800661875 /* Headers */,
+ F3968A1D281F704800661875 /* Sources */,
+ F3968A1E281F704800661875 /* Frameworks */,
+ F3968A1F281F704800661875 /* Resources */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ );
+ name = wavpack;
+ productName = wavpack;
+ productReference = F3968A21281F704800661875 /* wavpack.framework */;
+ productType = "com.apple.product-type.framework";
+ };
+/* End PBXNativeTarget section */
+
+/* Begin PBXProject section */
+ F3968A18281F704800661875 /* Project object */ = {
+ isa = PBXProject;
+ attributes = {
+ BuildIndependentTargetsInParallel = 1;
+ LastUpgradeCheck = 1330;
+ TargetAttributes = {
+ F3968A20281F704800661875 = {
+ CreatedOnToolsVersion = 13.3.1;
+ };
+ F3B38D49296F8DDD005DA6D3 = {
+ CreatedOnToolsVersion = 14.2;
+ };
+ };
+ };
+ buildConfigurationList = F3968A1B281F704800661875 /* Build configuration list for PBXProject "wavpack" */;
+ compatibilityVersion = "Xcode 13.0";
+ developmentRegion = en;
+ hasScannedForEncodings = 0;
+ knownRegions = (
+ en,
+ Base,
+ );
+ mainGroup = F3968A17281F704800661875;
+ productRefGroup = F3968A22281F704800661875 /* Products */;
+ projectDirPath = "";
+ projectRoot = "";
+ targets = (
+ F3968A20281F704800661875 /* wavpack */,
+ F3B38D49296F8DDD005DA6D3 /* wavpack.xcframework */,
+ );
+ };
+/* End PBXProject section */
+
+/* Begin PBXResourcesBuildPhase section */
+ F3968A1F281F704800661875 /* Resources */ = {
+ isa = PBXResourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ F307A2E32B54361B0012534B /* README.md in Resources */,
+ F3968B5A281F75B200661875 /* COPYING in Resources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXResourcesBuildPhase section */
+
+/* Begin PBXShellScriptBuildPhase section */
+ F3B38D4E296F8DF9005DA6D3 /* ShellScript */ = {
+ isa = PBXShellScriptBuildPhase;
+ alwaysOutOfDate = 1;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ inputFileListPaths = (
+ );
+ inputPaths = (
+ );
+ outputFileListPaths = (
+ );
+ outputPaths = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ shellPath = /bin/sh;
+ shellScript = "# Build an xcframework with both device and simulator files for all platforms.\n# Adapted from an answer in\n# https://developer.apple.com/forums/thread/666335?answerId=685927022#685927022\n\nif [ \"$XCODE_VERSION_ACTUAL\" -lt 1100 ]\nthen\n echo \"error: Building an xcframework requires Xcode 11 minimum.\"\n exit 1\nfi\n\nFRAMEWORK_NAME=\"wavpack\"\nPROJECT_NAME=\"wavpack\"\nSCHEME=\"wavpack\"\n\nMACOS_ARCHIVE_PATH=\"${BUILD_DIR}/${CONFIGURATION}/${FRAMEWORK_NAME}-macosx.xcarchive\"\nIOS_SIMULATOR_ARCHIVE_PATH=\"${BUILD_DIR}/${CONFIGURATION}/${FRAMEWORK_NAME}-iphonesimulator.xcarchive\"\nIOS_DEVICE_ARCHIVE_PATH=\"${BUILD_DIR}/${CONFIGURATION}/${FRAMEWORK_NAME}-iphoneos.xcarchive\"\nTVOS_SIMULATOR_ARCHIVE_PATH=\"${BUILD_DIR}/${CONFIGURATION}/${FRAMEWORK_NAME}-appletvsimulator.xcarchive\"\nTVOS_DEVICE_ARCHIVE_PATH=\"${BUILD_DIR}/${CONFIGURATION}/${FRAMEWORK_NAME}-appletvos.xcarchive\"\n\nOUTPUT_DIR=\"../build/\"\n\n# macOS\nxcodebuild archive \\\n ONLY_ACTIVE_ARCH=NO \\\n -scheme \"${SCHEME}\" \\\n -project \"${PROJECT_NAME}.xcodeproj\" \\\n -archivePath ${MACOS_ARCHIVE_PATH} \\\n -sdk macosx \\\n BUILD_LIBRARY_FOR_DISTRIBUTION=YES \\\n SKIP_INSTALL=NO || exit $?\n \n# iOS simulator\nxcodebuild archive \\\n ONLY_ACTIVE_ARCH=NO \\\n -scheme \"${SCHEME}\" \\\n -project \"${PROJECT_NAME}.xcodeproj\" \\\n -archivePath ${IOS_SIMULATOR_ARCHIVE_PATH} \\\n -sdk iphonesimulator \\\n BUILD_LIBRARY_FOR_DISTRIBUTION=YES \\\n SKIP_INSTALL=NO || exit $?\n\n# iOS device\nxcodebuild archive \\\n -scheme \"${SCHEME}\" \\\n -project \"${PROJECT_NAME}.xcodeproj\" \\\n -archivePath ${IOS_DEVICE_ARCHIVE_PATH} \\\n -sdk iphoneos \\\n BUILD_LIBRARY_FOR_DISTRIBUTION=YES \\\n SKIP_INSTALL=NO || exit $?\n\n# tvOS simulator\nxcodebuild archive \\\n ONLY_ACTIVE_ARCH=NO \\\n -scheme \"${SCHEME}\" \\\n -project \"${PROJECT_NAME}.xcodeproj\" \\\n -archivePath ${TVOS_SIMULATOR_ARCHIVE_PATH} \\\n -sdk appletvsimulator \\\n BUILD_LIBRARY_FOR_DISTRIBUTION=YES \\\n SKIP_INSTALL=NO || exit $?\n\n# tvOS device\nxcodebuild archive \\\n -scheme \"${SCHEME}\" \\\n -project \"${PROJECT_NAME}.xcodeproj\" \\\n -archivePath ${TVOS_DEVICE_ARCHIVE_PATH} \\\n -sdk appletvos \\\n BUILD_LIBRARY_FOR_DISTRIBUTION=YES \\\n SKIP_INSTALL=NO || exit $?\n\n# Clean-up any existing instance of this xcframework from the Products directory\nrm -rf \"${OUTPUT_DIR}${FRAMEWORK_NAME}.xcframework\"\n\n# Create final xcframework\nxcodebuild -create-xcframework \\\n -framework \"${MACOS_ARCHIVE_PATH}\"/Products/Library/Frameworks/${FRAMEWORK_NAME}.framework \\\n -framework \"${IOS_DEVICE_ARCHIVE_PATH}\"/Products/Library/Frameworks/${FRAMEWORK_NAME}.framework \\\n -framework \"${IOS_SIMULATOR_ARCHIVE_PATH}\"/Products/Library/Frameworks/${FRAMEWORK_NAME}.framework \\\n -framework \"${TVOS_DEVICE_ARCHIVE_PATH}\"/Products/Library/Frameworks/${FRAMEWORK_NAME}.framework \\\n -framework \"${TVOS_SIMULATOR_ARCHIVE_PATH}\"/Products/Library/Frameworks/${FRAMEWORK_NAME}.framework \\\n -output ${OUTPUT_DIR}/${FRAMEWORK_NAME}.xcframework\n\n# Ensure git doesn't pick up on our Products folder. \nrm -rf ${OUTPUT_DIR}/.gitignore\necho \"*\" >> ${OUTPUT_DIR}/.gitignore\n";
+ };
+/* End PBXShellScriptBuildPhase section */
+
+/* Begin PBXSourcesBuildPhase section */
+ F3968A1D281F704800661875 /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ F307A31C2B5436B00012534B /* unpack_x64.S in Sources */,
+ F307A3182B5436B00012534B /* pack_utils.c in Sources */,
+ F307A3152B5436B00012534B /* unpack_armv7.S in Sources */,
+ F307A3042B5436B00012534B /* open_raw.c in Sources */,
+ F307A3102B5436B00012534B /* pack_floats.c in Sources */,
+ F307A30C2B5436B00012534B /* pack_x86.S in Sources */,
+ F307A30B2B5436B00012534B /* write_words.c in Sources */,
+ F307A30A2B5436B00012534B /* unpack_utils.c in Sources */,
+ F307A3072B5436B00012534B /* pack_x64.S in Sources */,
+ F307A3122B5436B00012534B /* unpack_seek.c in Sources */,
+ F307A31B2B5436B00012534B /* unpack_floats.c in Sources */,
+ F307A31D2B5436B00012534B /* unpack.c in Sources */,
+ F307A30F2B5436B00012534B /* pack_dsd.c in Sources */,
+ F307A3202B5436B00012534B /* extra1.c in Sources */,
+ F307A3212B5436B00012534B /* tags.c in Sources */,
+ F307A3052B5436B00012534B /* open_utils.c in Sources */,
+ F307A3172B5436B00012534B /* decorr_utils.c in Sources */,
+ F307A3162B5436B00012534B /* unpack_x86.S in Sources */,
+ F307A31A2B5436B00012534B /* read_words.c in Sources */,
+ F307A31F2B5436B00012534B /* extra2.c in Sources */,
+ F307A30E2B5436B00012534B /* open_legacy.c in Sources */,
+ F307A3112B5436B00012534B /* pack_dns.c in Sources */,
+ F307A3192B5436B00012534B /* unpack_dsd.c in Sources */,
+ F307A31E2B5436B00012534B /* open_filename.c in Sources */,
+ F307A3082B5436B00012534B /* common_utils.c in Sources */,
+ F307A3142B5436B00012534B /* pack.c in Sources */,
+ F307A3132B5436B00012534B /* entropy_utils.c in Sources */,
+ F307A3092B5436B00012534B /* tag_utils.c in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXSourcesBuildPhase section */
+
+/* Begin XCBuildConfiguration section */
+ F3968A26281F704800661875 /* Debug */ = {
+ isa = XCBuildConfiguration;
+ baseConfigurationReference = F3968BB5281FA13C00661875 /* config.xcconfig */;
+ buildSettings = {
+ ALLOW_TARGET_PLATFORM_SPECIALIZATION = YES;
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ CLANG_ALLOW_NON_MODULAR_INCLUDES_IN_FRAMEWORK_MODULES = YES;
+ CLANG_ANALYZER_NONNULL = YES;
+ CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
+ CLANG_CXX_LANGUAGE_STANDARD = "gnu++17";
+ CLANG_ENABLE_MODULES = YES;
+ CLANG_ENABLE_OBJC_ARC = YES;
+ CLANG_ENABLE_OBJC_WEAK = YES;
+ CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
+ CLANG_WARN_BOOL_CONVERSION = YES;
+ CLANG_WARN_COMMA = YES;
+ CLANG_WARN_CONSTANT_CONVERSION = YES;
+ CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
+ CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
+ CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
+ CLANG_WARN_EMPTY_BODY = YES;
+ CLANG_WARN_ENUM_CONVERSION = YES;
+ CLANG_WARN_INFINITE_RECURSION = YES;
+ CLANG_WARN_INT_CONVERSION = YES;
+ CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
+ CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
+ CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
+ CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+ CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
+ CLANG_WARN_STRICT_PROTOTYPES = YES;
+ CLANG_WARN_SUSPICIOUS_MOVE = YES;
+ CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
+ CLANG_WARN_UNREACHABLE_CODE = YES;
+ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+ COPY_PHASE_STRIP = NO;
+ CURRENT_PROJECT_VERSION = 1;
+ DEBUG_INFORMATION_FORMAT = dwarf;
+ ENABLE_STRICT_OBJC_MSGSEND = YES;
+ ENABLE_TESTABILITY = YES;
+ GCC_C_LANGUAGE_STANDARD = gnu11;
+ GCC_DYNAMIC_NO_PIC = NO;
+ GCC_NO_COMMON_BLOCKS = YES;
+ GCC_OPTIMIZATION_LEVEL = 0;
+ GCC_PREPROCESSOR_DEFINITIONS = (
+ "$(CONFIG_PREPROCESSOR_DEFINITIONS)",
+ ENABLE_DSD,
+ );
+ GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+ GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
+ GCC_WARN_UNDECLARED_SELECTOR = YES;
+ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
+ GCC_WARN_UNUSED_FUNCTION = YES;
+ GCC_WARN_UNUSED_VARIABLE = YES;
+ HEADER_SEARCH_PATHS = (
+ "\"$(SRCROOT)/$(CURRENT_ARCH)\"",
+ "\"$(SRCROOT)/../../external/wavpack\"",
+ "\"$(SRCROOT)/../../external/wavpack/include\"",
+ "\"$(SRCROOT)/../../external/wavpack/celt\"",
+ "\"$(SRCROOT)/../../external/wavpack/silk\"",
+ "\"$(SRCROOT)/../../external/wavpack/silk/float\"",
+ "\"$(SRCROOT)/../../external/wavpack/silk/fixed\"",
+ );
+ IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+ MACOSX_DEPLOYMENT_TARGET = 10.11;
+ MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
+ MTL_FAST_MATH = YES;
+ ONLY_ACTIVE_ARCH = YES;
+ SUPPORTED_PLATFORMS = "watchsimulator watchos macosx iphonesimulator iphoneos driverkit appletvsimulator appletvos";
+ SUPPORTS_MACCATALYST = YES;
+ TVOS_DEPLOYMENT_TARGET = 9.0;
+ VERSIONING_SYSTEM = "apple-generic";
+ VERSION_INFO_PREFIX = "";
+ };
+ name = Debug;
+ };
+ F3968A27281F704800661875 /* Release */ = {
+ isa = XCBuildConfiguration;
+ baseConfigurationReference = F3968BB5281FA13C00661875 /* config.xcconfig */;
+ buildSettings = {
+ ALLOW_TARGET_PLATFORM_SPECIALIZATION = YES;
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ CLANG_ALLOW_NON_MODULAR_INCLUDES_IN_FRAMEWORK_MODULES = YES;
+ CLANG_ANALYZER_NONNULL = YES;
+ CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
+ CLANG_CXX_LANGUAGE_STANDARD = "gnu++17";
+ CLANG_ENABLE_MODULES = YES;
+ CLANG_ENABLE_OBJC_ARC = YES;
+ CLANG_ENABLE_OBJC_WEAK = YES;
+ CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
+ CLANG_WARN_BOOL_CONVERSION = YES;
+ CLANG_WARN_COMMA = YES;
+ CLANG_WARN_CONSTANT_CONVERSION = YES;
+ CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
+ CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
+ CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
+ CLANG_WARN_EMPTY_BODY = YES;
+ CLANG_WARN_ENUM_CONVERSION = YES;
+ CLANG_WARN_INFINITE_RECURSION = YES;
+ CLANG_WARN_INT_CONVERSION = YES;
+ CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
+ CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
+ CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
+ CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+ CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
+ CLANG_WARN_STRICT_PROTOTYPES = YES;
+ CLANG_WARN_SUSPICIOUS_MOVE = YES;
+ CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
+ CLANG_WARN_UNREACHABLE_CODE = YES;
+ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+ COPY_PHASE_STRIP = NO;
+ CURRENT_PROJECT_VERSION = 1;
+ DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
+ ENABLE_NS_ASSERTIONS = NO;
+ ENABLE_STRICT_OBJC_MSGSEND = YES;
+ GCC_C_LANGUAGE_STANDARD = gnu11;
+ GCC_NO_COMMON_BLOCKS = YES;
+ GCC_PREPROCESSOR_DEFINITIONS = (
+ "$(CONFIG_PREPROCESSOR_DEFINITIONS)",
+ ENABLE_DSD,
+ );
+ GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+ GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
+ GCC_WARN_UNDECLARED_SELECTOR = YES;
+ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
+ GCC_WARN_UNUSED_FUNCTION = YES;
+ GCC_WARN_UNUSED_VARIABLE = YES;
+ HEADER_SEARCH_PATHS = (
+ "\"$(SRCROOT)/$(CURRENT_ARCH)\"",
+ "\"$(SRCROOT)/../../external/wavpack\"",
+ "\"$(SRCROOT)/../../external/wavpack/include\"",
+ "\"$(SRCROOT)/../../external/wavpack/celt\"",
+ "\"$(SRCROOT)/../../external/wavpack/silk\"",
+ "\"$(SRCROOT)/../../external/wavpack/silk/float\"",
+ "\"$(SRCROOT)/../../external/wavpack/silk/fixed\"",
+ );
+ IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+ MACOSX_DEPLOYMENT_TARGET = 10.11;
+ MTL_ENABLE_DEBUG_INFO = NO;
+ MTL_FAST_MATH = YES;
+ SUPPORTED_PLATFORMS = "watchsimulator watchos macosx iphonesimulator iphoneos driverkit appletvsimulator appletvos";
+ SUPPORTS_MACCATALYST = YES;
+ TVOS_DEPLOYMENT_TARGET = 9.0;
+ VERSIONING_SYSTEM = "apple-generic";
+ VERSION_INFO_PREFIX = "";
+ };
+ name = Release;
+ };
+ F3968A29281F704800661875 /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ CODE_SIGN_STYLE = Automatic;
+ COMBINE_HIDPI_IMAGES = YES;
+ CURRENT_PROJECT_VERSION = 1;
+ DEFINES_MODULE = YES;
+ DYLIB_COMPATIBILITY_VERSION = 1;
+ DYLIB_CURRENT_VERSION = 1;
+ DYLIB_INSTALL_NAME_BASE = "@rpath";
+ GENERATE_INFOPLIST_FILE = YES;
+ INFOPLIST_KEY_NSHumanReadableCopyright = "";
+ INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
+ LD_RUNPATH_SEARCH_PATHS = (
+ "$(inherited)",
+ "@executable_path/Frameworks",
+ "@loader_path/Frameworks",
+ );
+ MARKETING_VERSION = 1.3.1;
+ PRODUCT_BUNDLE_IDENTIFIER = org.xiph.wavpack;
+ PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)";
+ SKIP_INSTALL = YES;
+ SWIFT_EMIT_LOC_STRINGS = YES;
+ };
+ name = Debug;
+ };
+ F3968A2A281F704800661875 /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ CODE_SIGN_STYLE = Automatic;
+ COMBINE_HIDPI_IMAGES = YES;
+ CURRENT_PROJECT_VERSION = 1;
+ DEFINES_MODULE = YES;
+ DYLIB_COMPATIBILITY_VERSION = 1;
+ DYLIB_CURRENT_VERSION = 1;
+ DYLIB_INSTALL_NAME_BASE = "@rpath";
+ GENERATE_INFOPLIST_FILE = YES;
+ INFOPLIST_KEY_NSHumanReadableCopyright = "";
+ INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
+ LD_RUNPATH_SEARCH_PATHS = (
+ "$(inherited)",
+ "@executable_path/Frameworks",
+ "@loader_path/Frameworks",
+ );
+ MARKETING_VERSION = 1.3.1;
+ PRODUCT_BUNDLE_IDENTIFIER = org.xiph.wavpack;
+ PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)";
+ SKIP_INSTALL = YES;
+ SWIFT_EMIT_LOC_STRINGS = YES;
+ };
+ name = Release;
+ };
+ F3B38D4A296F8DDD005DA6D3 /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ };
+ name = Debug;
+ };
+ F3B38D4B296F8DDD005DA6D3 /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ };
+ name = Release;
+ };
+/* End XCBuildConfiguration section */
+
+/* Begin XCConfigurationList section */
+ F3968A1B281F704800661875 /* Build configuration list for PBXProject "wavpack" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ F3968A26281F704800661875 /* Debug */,
+ F3968A27281F704800661875 /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ F3968A28281F704800661875 /* Build configuration list for PBXNativeTarget "wavpack" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ F3968A29281F704800661875 /* Debug */,
+ F3968A2A281F704800661875 /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ F3B38D4D296F8DDD005DA6D3 /* Build configuration list for PBXAggregateTarget "wavpack.xcframework" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ F3B38D4A296F8DDD005DA6D3 /* Debug */,
+ F3B38D4B296F8DDD005DA6D3 /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+/* End XCConfigurationList section */
+ };
+ rootObject = F3968A18281F704800661875 /* Project object */;
+}
diff --git a/build-scripts/config.guess b/build-scripts/config.guess
index cdfc43920..f6d217a49 100755
--- a/build-scripts/config.guess
+++ b/build-scripts/config.guess
@@ -1,10 +1,10 @@
#! /bin/sh
# Attempt to guess a canonical system name.
-# Copyright 1992-2023 Free Software Foundation, Inc.
+# Copyright 1992-2024 Free Software Foundation, Inc.
# shellcheck disable=SC2006,SC2268 # see below for rationale
-timestamp='2023-08-22'
+timestamp='2024-01-01'
# This file is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by
@@ -60,7 +60,7 @@ version="\
GNU config.guess ($timestamp)
Originally written by Per Bothner.
-Copyright 1992-2023 Free Software Foundation, Inc.
+Copyright 1992-2024 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
@@ -165,6 +165,8 @@ Linux|GNU|GNU/*)
LIBC=dietlibc
#elif defined(__GLIBC__)
LIBC=gnu
+ #elif defined(__LLVM_LIBC__)
+ LIBC=llvm
#else
#include
/* First heuristic to detect musl libc. */
@@ -1593,6 +1595,9 @@ EOF
*:Unleashed:*:*)
GUESS=$UNAME_MACHINE-unknown-unleashed$UNAME_RELEASE
;;
+ *:Ironclad:*:*)
+ GUESS=$UNAME_MACHINE-unknown-ironclad
+ ;;
esac
# Do we have a guess based on uname results?
diff --git a/build-scripts/config.sub b/build-scripts/config.sub
index defe52c0c..2c6a07ab3 100755
--- a/build-scripts/config.sub
+++ b/build-scripts/config.sub
@@ -1,10 +1,10 @@
#! /bin/sh
# Configuration validation subroutine script.
-# Copyright 1992-2023 Free Software Foundation, Inc.
+# Copyright 1992-2024 Free Software Foundation, Inc.
# shellcheck disable=SC2006,SC2268 # see below for rationale
-timestamp='2023-09-19'
+timestamp='2024-01-01'
# This file is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by
@@ -76,7 +76,7 @@ Report bugs and patches to ."
version="\
GNU config.sub ($timestamp)
-Copyright 1992-2023 Free Software Foundation, Inc.
+Copyright 1992-2024 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
@@ -1222,6 +1222,7 @@ case $cpu-$vendor in
| moxie \
| mt \
| msp430 \
+ | nanomips* \
| nds32 | nds32le | nds32be \
| nfp \
| nios | nios2 | nios2eb | nios2el \
@@ -1253,6 +1254,7 @@ case $cpu-$vendor in
| ubicom32 \
| v70 | v850 | v850e | v850e1 | v850es | v850e2 | v850e2v3 \
| vax \
+ | vc4 \
| visium \
| w65 \
| wasm32 | wasm64 \
@@ -1597,7 +1599,7 @@ case $cpu-$vendor in
os=
obj=elf
;;
- mips*-*)
+ mips*-*|nanomips*-*)
os=
obj=elf
;;
@@ -1721,7 +1723,7 @@ fi
case $os in
# Sometimes we do "kernel-libc", so those need to count as OSes.
- musl* | newlib* | relibc* | uclibc*)
+ llvm* | musl* | newlib* | relibc* | uclibc*)
;;
# Likewise for "kernel-abi"
eabi* | gnueabi*)
@@ -1766,12 +1768,19 @@ case $os in
| onefs* | tirtos* | phoenix* | fuchsia* | redox* | bme* \
| midnightbsd* | amdhsa* | unleashed* | emscripten* | wasi* \
| nsk* | powerunix* | genode* | zvmoe* | qnx* | emx* | zephyr* \
- | fiwix* | mlibc* | cos* | mbr* )
+ | fiwix* | mlibc* | cos* | mbr* | ironclad* )
;;
# This one is extra strict with allowed versions
sco3.2v2 | sco3.2v[4-9]* | sco5v6*)
# Don't forget version if it is 3.2v4 or newer.
;;
+ # This refers to builds using the UEFI calling convention
+ # (which depends on the architecture) and PE file format.
+ # Note that this is both a different calling convention and
+ # different file format than that of GNU-EFI
+ # (x86_64-w64-mingw32).
+ uefi)
+ ;;
none)
;;
kernel* | msvc* )
@@ -1818,8 +1827,9 @@ esac
# As a final step for OS-related things, validate the OS-kernel combination
# (given a valid OS), if there is a kernel.
case $kernel-$os-$obj in
- linux-gnu*- | linux-dietlibc*- | linux-android*- | linux-newlib*- \
- | linux-musl*- | linux-relibc*- | linux-uclibc*- | linux-mlibc*- )
+ linux-gnu*- | linux-android*- | linux-dietlibc*- | linux-llvm*- \
+ | linux-mlibc*- | linux-musl*- | linux-newlib*- \
+ | linux-relibc*- | linux-uclibc*- )
;;
uclinux-uclibc*- )
;;
@@ -1827,7 +1837,8 @@ case $kernel-$os-$obj in
;;
windows*-msvc*-)
;;
- -dietlibc*- | -newlib*- | -musl*- | -relibc*- | -uclibc*- | -mlibc*- )
+ -dietlibc*- | -llvm*- | -mlibc*- | -musl*- | -newlib*- | -relibc*- \
+ | -uclibc*- )
# These are just libc implementations, not actual OSes, and thus
# require a kernel.
echo "Invalid configuration '$1': libc '$os' needs explicit kernel." 1>&2
diff --git a/configure b/configure
index 65198bf8c..d050102b5 100755
--- a/configure
+++ b/configure
@@ -1,6 +1,6 @@
#! /bin/sh
# Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.71 for SDL2_mixer 2.7.1.
+# Generated by GNU Autoconf 2.71 for SDL2_mixer 2.8.0.
#
# Report bugs to .
#
@@ -760,8 +760,8 @@ MAKEFLAGS=
# Identity of this package.
PACKAGE_NAME='SDL2_mixer'
PACKAGE_TARNAME='SDL2_mixer'
-PACKAGE_VERSION='2.7.1'
-PACKAGE_STRING='SDL2_mixer 2.7.1'
+PACKAGE_VERSION='2.8.0'
+PACKAGE_STRING='SDL2_mixer 2.8.0'
PACKAGE_BUGREPORT='https://github.com/libsdl-org/SDL_mixer/issues'
PACKAGE_URL=''
@@ -810,7 +810,7 @@ SDL2MIXER_MIDI_TIMIDITY
SDL2MIXER_MIDI_NATIVE
SDL2MIXER_MIDI_FLUIDSYNTH
SDL2MIXER_MP3_MPG123
-SDL2MIXER_MP3_DRMP3
+SDL2MIXER_MP3_MINIMP3
SDL2MIXER_MOD_XMP_LITE
SDL2MIXER_MOD_XMP
SDL2MIXER_MOD_MODPLUG
@@ -997,7 +997,7 @@ enable_music_flac_drflac
enable_music_flac_libflac
enable_music_flac_libflac_shared
enable_music_mp3
-enable_music_mp3_drmp3
+enable_music_mp3_minimp3
enable_music_mp3_mpg123
enable_music_mp3_mpg123_shared
enable_music_opus
@@ -1591,7 +1591,7 @@ if test "$ac_init_help" = "long"; then
# Omit some internal or obsolete options to make the list less imposing.
# This message is too long to be a string in the A/UX 3.1 sh.
cat <<_ACEOF
-\`configure' configures SDL2_mixer 2.7.1 to adapt to many kinds of systems.
+\`configure' configures SDL2_mixer 2.8.0 to adapt to many kinds of systems.
Usage: $0 [OPTION]... [VAR=VALUE]...
@@ -1657,7 +1657,7 @@ fi
if test -n "$ac_init_help"; then
case $ac_init_help in
- short | recursive ) echo "Configuration of SDL2_mixer 2.7.1:";;
+ short | recursive ) echo "Configuration of SDL2_mixer 2.8.0:";;
esac
cat <<\_ACEOF
@@ -1694,7 +1694,7 @@ Optional Features:
enable FluidSynth MIDI output [default=yes]
--enable-music-midi-fluidsynth-shared
dynamically load FluidSynth library [default=yes]
- --enable-music-gme enable Game Music Emu support [default=no]
+ --enable-music-gme enable Game Music Emu support [default=yes]
--enable-music-gme-shared
dynamically load libgme library [default=yes]
--enable-music-ogg enable Ogg Vorbis music [default=yes]
@@ -1715,8 +1715,8 @@ Optional Features:
--enable-music-flac-libflac-shared
dynamically load FLAC library [default=yes]
--enable-music-mp3 enable MP3 music [default=yes]
- --enable-music-mp3-drmp3
- enable MP3 music via dr_mp3 [default=yes]
+ --enable-music-mp3-minimp3
+ enable MP3 music via minimp3 [default=yes]
--enable-music-mp3-mpg123
enable MP3 music via mpg123 [default=no]
--enable-music-mp3-mpg123-shared
@@ -1858,7 +1858,7 @@ fi
test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then
cat <<\_ACEOF
-SDL2_mixer configure 2.7.1
+SDL2_mixer configure 2.8.0
generated by GNU Autoconf 2.71
Copyright (C) 2021 Free Software Foundation, Inc.
@@ -2243,7 +2243,7 @@ cat >config.log <<_ACEOF
This file contains any messages produced by compilers while
running configure, to aid debugging if configure makes a mistake.
-It was created by SDL2_mixer $as_me 2.7.1, which was
+It was created by SDL2_mixer $as_me 2.8.0, which was
generated by GNU Autoconf 2.71. Invocation command line was
$ $0$ac_configure_args_raw
@@ -3219,9 +3219,9 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu
MAJOR_VERSION=2
-MINOR_VERSION=7
+MINOR_VERSION=8
-MICRO_VERSION=1
+MICRO_VERSION=0
BINARY_AGE=`expr $MINOR_VERSION \* 100 + $MICRO_VERSION`
@@ -16958,6 +16958,8 @@ rm -f core conftest.err conftest.$ac_objext conftest.beam \
rm -f conf.sdltest
+CFLAGS="$CFLAGS $SDL_CFLAGS"
+LIBS="$LIBS $SDL_LIBS"
EXTRA_CFLAGS="$EXTRA_CFLAGS $SDL_CFLAGS"
EXTRA_CFLAGS="$EXTRA_CFLAGS -DSDL_BUILD_MAJOR_VERSION=$MAJOR_VERSION -DSDL_BUILD_MINOR_VERSION=$MINOR_VERSION -DSDL_BUILD_MICRO_VERSION=$MICRO_VERSION"
@@ -17873,7 +17875,7 @@ if test ${enable_music_gme+y}
then :
enableval=$enable_music_gme;
else $as_nop
- enable_music_gme=no
+ enable_music_gme=yes
fi
# Check whether --enable-music-gme-shared was given.
@@ -18869,19 +18871,19 @@ else $as_nop
fi
-SDL2MIXER_MP3_DRMP3=0
-# Check whether --enable-music-mp3-drmp3 was given.
-if test ${enable_music_mp3_drmp3+y}
+SDL2MIXER_MP3_MINIMP3=0
+# Check whether --enable-music-mp3-minimp3 was given.
+if test ${enable_music_mp3_minimp3+y}
then :
- enableval=$enable_music_mp3_drmp3;
+ enableval=$enable_music_mp3_minimp3;
else $as_nop
- enable_music_mp3_drmp3=yes
+ enable_music_mp3_minimp3=yes
fi
-if test x$enable_music_mp3 = xyes -a x$enable_music_mp3_drmp3 = xyes; then
- have_drmp3=yes
- EXTRA_CFLAGS="$EXTRA_CFLAGS -DMUSIC_MP3_DRMP3"
- SDL2MIXER_MP3_DRMP3=1
+if test x$enable_music_mp3 = xyes -a x$enable_music_mp3_minimp3 = xyes; then
+ have_minimp3=yes
+ EXTRA_CFLAGS="$EXTRA_CFLAGS -DMUSIC_MP3_MINIMP3"
+ SDL2MIXER_MP3_MINIMP3=1
fi
SDL2MIXER_MP3_MPG123=0
@@ -19103,7 +19105,7 @@ printf "%s\n" "$as_me: WARNING: *** Unable to find mpg123 library (https://www.m
fi
fi
-if test x$enable_music_mp3 = xyes -a x$have_drmp3 != xyes -a x$have_libmpg123 != xyes; then
+if test x$enable_music_mp3 = xyes -a x$have_minimp3 != xyes -a x$have_libmpg123 != xyes; then
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: MP3 support disabled" >&5
printf "%s\n" "$as_me: WARNING: MP3 support disabled" >&2;}
fi
@@ -20322,7 +20324,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
# report actual input values of CONFIG_FILES etc. instead of their
# values after options handling.
ac_log="
-This file was extended by SDL2_mixer $as_me 2.7.1, which was
+This file was extended by SDL2_mixer $as_me 2.8.0, which was
generated by GNU Autoconf 2.71. Invocation command line was
CONFIG_FILES = $CONFIG_FILES
@@ -20381,7 +20383,7 @@ ac_cs_config_escaped=`printf "%s\n" "$ac_cs_config" | sed "s/^ //; s/'/'\\\\\\\\
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
ac_cs_config='$ac_cs_config_escaped'
ac_cs_version="\\
-SDL2_mixer config.status 2.7.1
+SDL2_mixer config.status 2.8.0
configured by $0, generated by GNU Autoconf 2.71,
with options \\"\$ac_cs_config\\"
diff --git a/configure.ac b/configure.ac
index 0b508a1e1..ccec258b3 100644
--- a/configure.ac
+++ b/configure.ac
@@ -3,8 +3,8 @@ dnl Process this file with autoconf to produce a configure script.
dnl Set various version strings - taken gratefully from the GTk sources
# See release_checklist.md
m4_define([MAJOR_VERSION_MACRO], [2])
-m4_define([MINOR_VERSION_MACRO], [7])
-m4_define([MICRO_VERSION_MACRO], [1])
+m4_define([MINOR_VERSION_MACRO], [8])
+m4_define([MICRO_VERSION_MACRO], [0])
AC_INIT([SDL2_mixer],
[MAJOR_VERSION_MACRO.MINOR_VERSION_MACRO.MICRO_VERSION_MACRO],
@@ -287,6 +287,8 @@ AM_PATH_SDL2($SDL_VERSION,
:,
AC_MSG_ERROR([*** SDL version $SDL_VERSION not found!])
)
+CFLAGS="$CFLAGS $SDL_CFLAGS"
+LIBS="$LIBS $SDL_LIBS"
EXTRA_CFLAGS="$EXTRA_CFLAGS $SDL_CFLAGS"
dnl For use in static assertions
@@ -583,8 +585,8 @@ fi
SDL2MIXER_GME=0
AC_ARG_ENABLE([music-gme],
-[AS_HELP_STRING([--enable-music-gme], [enable Game Music Emu support [default=no]])],
- [], [enable_music_gme=no])
+[AS_HELP_STRING([--enable-music-gme], [enable Game Music Emu support [default=yes]])],
+ [], [enable_music_gme=yes])
AC_ARG_ENABLE([music-gme-shared],
[AS_HELP_STRING([--enable-music-gme-shared], [dynamically load libgme library [default=yes]])],
[], [enable_music_gme_shared=yes])
@@ -860,14 +862,14 @@ AC_ARG_ENABLE(music-mp3,
[AS_HELP_STRING([--enable-music-mp3], [enable MP3 music [default=yes]])],
[], enable_music_mp3=yes)
-SDL2MIXER_MP3_DRMP3=0
-AC_ARG_ENABLE(music-mp3-drmp3,
-[AS_HELP_STRING([--enable-music-mp3-drmp3], [enable MP3 music via dr_mp3 [default=yes]])],
- [], [enable_music_mp3_drmp3=yes])
-if test x$enable_music_mp3 = xyes -a x$enable_music_mp3_drmp3 = xyes; then
- have_drmp3=yes
- EXTRA_CFLAGS="$EXTRA_CFLAGS -DMUSIC_MP3_DRMP3"
- SDL2MIXER_MP3_DRMP3=1
+SDL2MIXER_MP3_MINIMP3=0
+AC_ARG_ENABLE(music-mp3-minimp3,
+[AS_HELP_STRING([--enable-music-mp3-minimp3], [enable MP3 music via minimp3 [default=yes]])],
+ [], [enable_music_mp3_minimp3=yes])
+if test x$enable_music_mp3 = xyes -a x$enable_music_mp3_minimp3 = xyes; then
+ have_minimp3=yes
+ EXTRA_CFLAGS="$EXTRA_CFLAGS -DMUSIC_MP3_MINIMP3"
+ SDL2MIXER_MP3_MINIMP3=1
fi
SDL2MIXER_MP3_MPG123=0
@@ -920,7 +922,7 @@ if test x$enable_music_mp3 = xyes -a x$enable_music_mp3_mpg123 = xyes; then
fi
fi
-if test x$enable_music_mp3 = xyes -a x$have_drmp3 != xyes -a x$have_libmpg123 != xyes; then
+if test x$enable_music_mp3 = xyes -a x$have_minimp3 != xyes -a x$have_libmpg123 != xyes; then
AC_MSG_WARN([MP3 support disabled])
fi
@@ -1136,7 +1138,7 @@ AC_SUBST(SDL2MIXER_GME)
AC_SUBST(SDL2MIXER_MOD_MODPLUG)
AC_SUBST(SDL2MIXER_MOD_XMP)
AC_SUBST(SDL2MIXER_MOD_XMP_LITE)
-AC_SUBST(SDL2MIXER_MP3_DRMP3)
+AC_SUBST(SDL2MIXER_MP3_MINIMP3)
AC_SUBST(SDL2MIXER_MP3_MPG123)
AC_SUBST(SDL2MIXER_MIDI_FLUIDSYNTH)
AC_SUBST(SDL2MIXER_MIDI_NATIVE)
diff --git a/external/libgme b/external/libgme
index 861c0c865..cdd021507 160000
--- a/external/libgme
+++ b/external/libgme
@@ -1 +1 @@
-Subproject commit 861c0c865696bb157039b2a6b48e5ae0548983be
+Subproject commit cdd021507518162a4884898bbac85cbd32ed7a77
diff --git a/include/SDL_mixer.h b/include/SDL_mixer.h
index edda65452..408b40375 100644
--- a/include/SDL_mixer.h
+++ b/include/SDL_mixer.h
@@ -45,8 +45,8 @@ extern "C" {
* Printable format: "%d.%d.%d", MAJOR, MINOR, PATCHLEVEL
*/
#define SDL_MIXER_MAJOR_VERSION 2
-#define SDL_MIXER_MINOR_VERSION 7
-#define SDL_MIXER_PATCHLEVEL 1
+#define SDL_MIXER_MINOR_VERSION 8
+#define SDL_MIXER_PATCHLEVEL 0
/**
* This macro can be used to fill a version structure with the compile-time
diff --git a/playmus.c b/playmus.c
index 17456ac8d..bd59e5c8b 100644
--- a/playmus.c
+++ b/playmus.c
@@ -75,7 +75,7 @@ void Menu(void)
printf("Available commands: (p)ause (r)esume (h)alt volume(v#) > ");
fflush(stdin);
if (scanf("%s",buf) == 1) {
- switch(buf[0]){
+ switch(buf[0]) {
#if defined(SEEK_TEST)
case '0': Mix_SetMusicPosition(0); break;
case '1': Mix_SetMusicPosition(10);break;
@@ -105,9 +105,9 @@ void Menu(void)
void IntHandler(int sig)
{
switch (sig) {
- case SIGINT:
- next_track++;
- break;
+ case SIGINT:
+ next_track++;
+ break;
}
}
#endif
@@ -139,7 +139,7 @@ int main(int argc, char *argv[])
audio_buffers = 4096;
/* Check command line usage */
- for (i=1; argv[i] && (*argv[i] == '-'); ++i) {
+ for (i = 1; argv[i] && (*argv[i] == '-'); ++i) {
if ((strcmp(argv[i], "-r") == 0) && argv[i+1]) {
++i;
audio_rate = atoi(argv[i]);
@@ -175,18 +175,18 @@ int main(int argc, char *argv[])
rwops = 1;
} else {
Usage(argv[0]);
- return(1);
+ return 1;
}
}
- if (! argv[i]) {
+ if (!argv[i]) {
Usage(argv[0]);
- return(1);
+ return 1;
}
/* Initialize the SDL library */
if (SDL_Init(SDL_INIT_AUDIO) < 0) {
SDL_Log("Couldn't initialize SDL: %s\n",SDL_GetError());
- return(255);
+ return 255;
}
#ifdef HAVE_SIGNAL_H
@@ -197,7 +197,7 @@ int main(int argc, char *argv[])
/* Open the audio device */
if (Mix_OpenAudio(audio_rate, audio_format, audio_channels, audio_buffers) < 0) {
SDL_Log("Couldn't open audio: %s\n", SDL_GetError());
- return(2);
+ return 2;
} else {
Mix_QuerySpec(&audio_rate, &audio_format, &audio_channels);
SDL_Log("Opened audio at %d Hz %d bit%s %s %d bytes audio buffer\n", audio_rate,
@@ -224,8 +224,7 @@ int main(int argc, char *argv[])
music = Mix_LoadMUS(argv[i]);
}
if (music == NULL) {
- SDL_Log("Couldn't load %s: %s\n",
- argv[i], SDL_GetError());
+ SDL_Log("Couldn't load %s: %s\n", argv[i], SDL_GetError());
CleanUp(2);
}
@@ -297,9 +296,9 @@ int main(int argc, char *argv[])
}
Mix_FadeInMusic(music,looping,2000);
while (!next_track && (Mix_PlayingMusic() || Mix_PausedMusic())) {
- if(interactive)
+ if (interactive) {
Menu();
- else {
+ } else {
current_position = Mix_GetMusicPosition(music);
if (current_position >= 0.0) {
printf("Position: %g seconds \r", current_position);
@@ -313,7 +312,9 @@ int main(int argc, char *argv[])
/* If the user presses Ctrl-C more than once, exit. */
SDL_Delay(500);
- if (next_track > 1) break;
+ if (next_track > 1) {
+ break;
+ }
i++;
}
diff --git a/playwave.c b/playwave.c
index 4b88b00af..8cb5574f2 100644
--- a/playwave.c
+++ b/playwave.c
@@ -148,9 +148,9 @@ static void SDLCALL channel_complete_callback (int chan)
static int still_playing(void)
{
#ifdef TEST_MIX_CHANNELFINISHED
- return(!channel_is_done);
+ return !channel_is_done;
#else
- return(Mix_Playing(0));
+ return Mix_Playing(0);
#endif
}
@@ -165,7 +165,7 @@ static void do_panning_update(void)
static int panningok = 1;
static Uint32 next_panning_update = 0;
- if ((panningok) && (SDL_GetTicks() >= next_panning_update)) {
+ if (panningok && (SDL_GetTicks() >= next_panning_update)) {
panningok = Mix_SetPanning(0, leftvol, rightvol);
if (!panningok) {
SDL_Log("Mix_SetPanning(0, %d, %d) failed!\n",
@@ -236,7 +236,7 @@ static void do_position_update(void)
static int positionok = 1;
static Uint32 next_position_update = 0;
- if ((positionok) && (SDL_GetTicks() >= next_position_update)) {
+ if (positionok && (SDL_GetTicks() >= next_position_update)) {
positionok = Mix_SetPosition(0, angle, (Uint8)distance);
if (!positionok) {
SDL_Log("Mix_SetPosition(0, %d, %d) failed!\n",
@@ -380,7 +380,7 @@ int main(int argc, char *argv[])
audio_channels = MIX_DEFAULT_CHANNELS;
/* Check command line usage */
- for (i=1; argv[i] && (*argv[i] == '-'); ++i) {
+ for (i = 1; argv[i] && (*argv[i] == '-'); ++i) {
if ((strcmp(argv[i], "-r") == 0) && argv[i+1]) {
++i;
audio_rate = atoi(argv[i]);
@@ -408,18 +408,18 @@ int main(int argc, char *argv[])
reverse_sample = 1;
} else {
Usage(argv[0]);
- return(1);
+ return 1;
}
}
- if (! argv[i]) {
+ if (!argv[i]) {
Usage(argv[0]);
- return(1);
+ return 1;
}
/* Initialize the SDL library */
if (SDL_Init(SDL_INIT_AUDIO) < 0) {
SDL_Log("Couldn't initialize SDL: %s\n",SDL_GetError());
- return(255);
+ return 255;
}
#ifdef HAVE_SIGNAL_H
signal(SIGINT, CleanUp);
@@ -456,8 +456,7 @@ int main(int argc, char *argv[])
/* Load the requested wave file */
wave = Mix_LoadWAV(argv[i]);
if (wave == NULL) {
- SDL_Log("Couldn't load %s: %s\n",
- argv[i], SDL_GetError());
+ SDL_Log("Couldn't load %s: %s\n", argv[i], SDL_GetError());
CleanUp(2);
}
diff --git a/sdl2_mixer-config.cmake.in b/sdl2_mixer-config.cmake.in
index 5dae59e3c..7e277397b 100644
--- a/sdl2_mixer-config.cmake.in
+++ b/sdl2_mixer-config.cmake.in
@@ -31,9 +31,9 @@ else()
set(SDL2MIXER_MOD 0)
endif()
-set(SDL2MIXER_MP3_DRMP3 @SDL2MIXER_MP3_DRMP3@)
+set(SDL2MIXER_MP3_MINIMP3 @SDL2MIXER_MP3_MINIMP3@)
set(SDL2MIXER_MP3_MPG123 @SDL2MIXER_MP3_MPG123@)
-if(SDL2MIXER_MP3_DRMP3 OR SDL2MIXER_MP3_MPG123)
+if(SDL2MIXER_MP3_MINIMP3 OR SDL2MIXER_MP3_MPG123)
set(SDL2MIXER_MP3 1)
else()
set(SDL2MIXER_MP3 0)
diff --git a/src/codecs/dr_libs/dr_mp3.h b/src/codecs/dr_libs/dr_mp3.h
deleted file mode 100644
index 84849ee4c..000000000
--- a/src/codecs/dr_libs/dr_mp3.h
+++ /dev/null
@@ -1,4834 +0,0 @@
-/*
-MP3 audio decoder. Choice of public domain or MIT-0. See license statements at the end of this file.
-dr_mp3 - v0.6.38 - 2023-11-02
-
-David Reid - mackron@gmail.com
-
-GitHub: https://github.com/mackron/dr_libs
-
-Based on minimp3 (https://github.com/lieff/minimp3) which is where the real work was done. See the bottom of this file for differences between minimp3 and dr_mp3.
-*/
-
-/*
-RELEASE NOTES - VERSION 0.6
-===========================
-Version 0.6 includes breaking changes with the configuration of decoders. The ability to customize the number of output channels and the sample rate has been
-removed. You must now use the channel count and sample rate reported by the MP3 stream itself, and all channel and sample rate conversion must be done
-yourself.
-
-
-Changes to Initialization
--------------------------
-Previously, `drmp3_init()`, etc. took a pointer to a `drmp3_config` object that allowed you to customize the output channels and sample rate. This has been
-removed. If you need the old behaviour you will need to convert the data yourself or just not upgrade. The following APIs have changed.
-
- `drmp3_init()`
- `drmp3_init_memory()`
- `drmp3_init_file()`
-
-
-Miscellaneous Changes
----------------------
-Support for loading a file from a `wchar_t` string has been added via the `drmp3_init_file_w()` API.
-*/
-
-/*
-Introducation
-=============
-dr_mp3 is a single file library. To use it, do something like the following in one .c file.
-
- ```c
- #define DR_MP3_IMPLEMENTATION
- #include "dr_mp3.h"
- ```
-
-You can then #include this file in other parts of the program as you would with any other header file. To decode audio data, do something like the following:
-
- ```c
- drmp3 mp3;
- if (!drmp3_init_file(&mp3, "MySong.mp3", NULL)) {
- // Failed to open file
- }
-
- ...
-
- drmp3_uint64 framesRead = drmp3_read_pcm_frames_f32(pMP3, framesToRead, pFrames);
- ```
-
-The drmp3 object is transparent so you can get access to the channel count and sample rate like so:
-
- ```
- drmp3_uint32 channels = mp3.channels;
- drmp3_uint32 sampleRate = mp3.sampleRate;
- ```
-
-The example above initializes a decoder from a file, but you can also initialize it from a block of memory and read and seek callbacks with
-`drmp3_init_memory()` and `drmp3_init()` respectively.
-
-You do not need to do any annoying memory management when reading PCM frames - this is all managed internally. You can request any number of PCM frames in each
-call to `drmp3_read_pcm_frames_f32()` and it will return as many PCM frames as it can, up to the requested amount.
-
-You can also decode an entire file in one go with `drmp3_open_and_read_pcm_frames_f32()`, `drmp3_open_memory_and_read_pcm_frames_f32()` and
-`drmp3_open_file_and_read_pcm_frames_f32()`.
-
-
-Build Options
-=============
-#define these options before including this file.
-
-#define DR_MP3_NO_STDIO
- Disable drmp3_init_file(), etc.
-
-#define DR_MP3_NO_SIMD
- Disable SIMD optimizations.
-*/
-
-#ifndef dr_mp3_h
-#define dr_mp3_h
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#define DRMP3_STRINGIFY(x) #x
-#define DRMP3_XSTRINGIFY(x) DRMP3_STRINGIFY(x)
-
-#define DRMP3_VERSION_MAJOR 0
-#define DRMP3_VERSION_MINOR 6
-#define DRMP3_VERSION_REVISION 38
-#define DRMP3_VERSION_STRING DRMP3_XSTRINGIFY(DRMP3_VERSION_MAJOR) "." DRMP3_XSTRINGIFY(DRMP3_VERSION_MINOR) "." DRMP3_XSTRINGIFY(DRMP3_VERSION_REVISION)
-
-#include /* For size_t. */
-
-/* Sized Types */
-typedef signed char drmp3_int8;
-typedef unsigned char drmp3_uint8;
-typedef signed short drmp3_int16;
-typedef unsigned short drmp3_uint16;
-typedef signed int drmp3_int32;
-typedef unsigned int drmp3_uint32;
-#if defined(_MSC_VER) && !defined(__clang__)
- typedef signed __int64 drmp3_int64;
- typedef unsigned __int64 drmp3_uint64;
-#else
- #if defined(__clang__) || (defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)))
- #pragma GCC diagnostic push
- #pragma GCC diagnostic ignored "-Wlong-long"
- #if defined(__clang__)
- #pragma GCC diagnostic ignored "-Wc++11-long-long"
- #endif
- #endif
- typedef signed long long drmp3_int64;
- typedef unsigned long long drmp3_uint64;
- #if defined(__clang__) || (defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)))
- #pragma GCC diagnostic pop
- #endif
-#endif
-#if defined(__LP64__) || defined(_WIN64) || (defined(__x86_64__) && !defined(__ILP32__)) || defined(_M_X64) || defined(__ia64) || defined (_M_IA64) || defined(__aarch64__) || defined(_M_ARM64) || defined(__powerpc64__)
- typedef drmp3_uint64 drmp3_uintptr;
-#else
- typedef drmp3_uint32 drmp3_uintptr;
-#endif
-typedef drmp3_uint8 drmp3_bool8;
-typedef drmp3_uint32 drmp3_bool32;
-#define DRMP3_TRUE 1
-#define DRMP3_FALSE 0
-/* End Sized Types */
-
-/* Decorations */
-#if !defined(DRMP3_API)
- #if defined(DRMP3_DLL)
- #if defined(_WIN32)
- #define DRMP3_DLL_IMPORT __declspec(dllimport)
- #define DRMP3_DLL_EXPORT __declspec(dllexport)
- #define DRMP3_DLL_PRIVATE static
- #else
- #if defined(__GNUC__) && __GNUC__ >= 4
- #define DRMP3_DLL_IMPORT __attribute__((visibility("default")))
- #define DRMP3_DLL_EXPORT __attribute__((visibility("default")))
- #define DRMP3_DLL_PRIVATE __attribute__((visibility("hidden")))
- #else
- #define DRMP3_DLL_IMPORT
- #define DRMP3_DLL_EXPORT
- #define DRMP3_DLL_PRIVATE static
- #endif
- #endif
-
- #if defined(DR_MP3_IMPLEMENTATION) || defined(DRMP3_IMPLEMENTATION)
- #define DRMP3_API DRMP3_DLL_EXPORT
- #else
- #define DRMP3_API DRMP3_DLL_IMPORT
- #endif
- #define DRMP3_PRIVATE DRMP3_DLL_PRIVATE
- #else
- #define DRMP3_API extern
- #define DRMP3_PRIVATE static
- #endif
-#endif
-/* End Decorations */
-
-/* Result Codes */
-typedef drmp3_int32 drmp3_result;
-#define DRMP3_SUCCESS 0
-#define DRMP3_ERROR -1 /* A generic error. */
-#define DRMP3_INVALID_ARGS -2
-#define DRMP3_INVALID_OPERATION -3
-#define DRMP3_OUT_OF_MEMORY -4
-#define DRMP3_OUT_OF_RANGE -5
-#define DRMP3_ACCESS_DENIED -6
-#define DRMP3_DOES_NOT_EXIST -7
-#define DRMP3_ALREADY_EXISTS -8
-#define DRMP3_TOO_MANY_OPEN_FILES -9
-#define DRMP3_INVALID_FILE -10
-#define DRMP3_TOO_BIG -11
-#define DRMP3_PATH_TOO_LONG -12
-#define DRMP3_NAME_TOO_LONG -13
-#define DRMP3_NOT_DIRECTORY -14
-#define DRMP3_IS_DIRECTORY -15
-#define DRMP3_DIRECTORY_NOT_EMPTY -16
-#define DRMP3_END_OF_FILE -17
-#define DRMP3_NO_SPACE -18
-#define DRMP3_BUSY -19
-#define DRMP3_IO_ERROR -20
-#define DRMP3_INTERRUPT -21
-#define DRMP3_UNAVAILABLE -22
-#define DRMP3_ALREADY_IN_USE -23
-#define DRMP3_BAD_ADDRESS -24
-#define DRMP3_BAD_SEEK -25
-#define DRMP3_BAD_PIPE -26
-#define DRMP3_DEADLOCK -27
-#define DRMP3_TOO_MANY_LINKS -28
-#define DRMP3_NOT_IMPLEMENTED -29
-#define DRMP3_NO_MESSAGE -30
-#define DRMP3_BAD_MESSAGE -31
-#define DRMP3_NO_DATA_AVAILABLE -32
-#define DRMP3_INVALID_DATA -33
-#define DRMP3_TIMEOUT -34
-#define DRMP3_NO_NETWORK -35
-#define DRMP3_NOT_UNIQUE -36
-#define DRMP3_NOT_SOCKET -37
-#define DRMP3_NO_ADDRESS -38
-#define DRMP3_BAD_PROTOCOL -39
-#define DRMP3_PROTOCOL_UNAVAILABLE -40
-#define DRMP3_PROTOCOL_NOT_SUPPORTED -41
-#define DRMP3_PROTOCOL_FAMILY_NOT_SUPPORTED -42
-#define DRMP3_ADDRESS_FAMILY_NOT_SUPPORTED -43
-#define DRMP3_SOCKET_NOT_SUPPORTED -44
-#define DRMP3_CONNECTION_RESET -45
-#define DRMP3_ALREADY_CONNECTED -46
-#define DRMP3_NOT_CONNECTED -47
-#define DRMP3_CONNECTION_REFUSED -48
-#define DRMP3_NO_HOST -49
-#define DRMP3_IN_PROGRESS -50
-#define DRMP3_CANCELLED -51
-#define DRMP3_MEMORY_ALREADY_MAPPED -52
-#define DRMP3_AT_END -53
-/* End Result Codes */
-
-#define DRMP3_MAX_PCM_FRAMES_PER_MP3_FRAME 1152
-#define DRMP3_MAX_SAMPLES_PER_FRAME (DRMP3_MAX_PCM_FRAMES_PER_MP3_FRAME*2)
-
-/* Inline */
-#ifdef _MSC_VER
- #define DRMP3_INLINE __forceinline
-#elif defined(__GNUC__)
- /*
- I've had a bug report where GCC is emitting warnings about functions possibly not being inlineable. This warning happens when
- the __attribute__((always_inline)) attribute is defined without an "inline" statement. I think therefore there must be some
- case where "__inline__" is not always defined, thus the compiler emitting these warnings. When using -std=c89 or -ansi on the
- command line, we cannot use the "inline" keyword and instead need to use "__inline__". In an attempt to work around this issue
- I am using "__inline__" only when we're compiling in strict ANSI mode.
- */
- #if defined(__STRICT_ANSI__)
- #define DRMP3_GNUC_INLINE_HINT __inline__
- #else
- #define DRMP3_GNUC_INLINE_HINT inline
- #endif
-
- #if (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 2)) || defined(__clang__)
- #define DRMP3_INLINE DRMP3_GNUC_INLINE_HINT __attribute__((always_inline))
- #else
- #define DRMP3_INLINE DRMP3_GNUC_INLINE_HINT
- #endif
-#elif defined(__WATCOMC__)
- #define DRMP3_INLINE __inline
-#else
- #define DRMP3_INLINE
-#endif
-/* End Inline */
-
-
-DRMP3_API void drmp3_version(drmp3_uint32* pMajor, drmp3_uint32* pMinor, drmp3_uint32* pRevision);
-DRMP3_API const char* drmp3_version_string(void);
-
-
-/* Allocation Callbacks */
-typedef struct
-{
- void* pUserData;
- void* (* onMalloc)(size_t sz, void* pUserData);
- void* (* onRealloc)(void* p, size_t sz, void* pUserData);
- void (* onFree)(void* p, void* pUserData);
-} drmp3_allocation_callbacks;
-/* End Allocation Callbacks */
-
-
-/*
-Low Level Push API
-==================
-*/
-typedef struct
-{
- int frame_bytes, channels, hz, layer, bitrate_kbps;
-} drmp3dec_frame_info;
-
-typedef struct
-{
- float mdct_overlap[2][9*32], qmf_state[15*2*32];
- int reserv, free_format_bytes;
- drmp3_uint8 header[4], reserv_buf[511];
-} drmp3dec;
-
-/* Initializes a low level decoder. */
-DRMP3_API void drmp3dec_init(drmp3dec *dec);
-
-/* Reads a frame from a low level decoder. */
-DRMP3_API int drmp3dec_decode_frame(drmp3dec *dec, const drmp3_uint8 *mp3, int mp3_bytes, void *pcm, drmp3dec_frame_info *info);
-
-/* Helper for converting between f32 and s16. */
-DRMP3_API void drmp3dec_f32_to_s16(const float *in, drmp3_int16 *out, size_t num_samples);
-
-
-
-/*
-Main API (Pull API)
-===================
-*/
-typedef enum
-{
- drmp3_seek_origin_start,
- drmp3_seek_origin_current
-} drmp3_seek_origin;
-
-typedef struct
-{
- drmp3_uint64 seekPosInBytes; /* Points to the first byte of an MP3 frame. */
- drmp3_uint64 pcmFrameIndex; /* The index of the PCM frame this seek point targets. */
- drmp3_uint16 mp3FramesToDiscard; /* The number of whole MP3 frames to be discarded before pcmFramesToDiscard. */
- drmp3_uint16 pcmFramesToDiscard; /* The number of leading samples to read and discard. These are discarded after mp3FramesToDiscard. */
-} drmp3_seek_point;
-
-/*
-Callback for when data is read. Return value is the number of bytes actually read.
-
-pUserData [in] The user data that was passed to drmp3_init(), drmp3_open() and family.
-pBufferOut [out] The output buffer.
-bytesToRead [in] The number of bytes to read.
-
-Returns the number of bytes actually read.
-
-A return value of less than bytesToRead indicates the end of the stream. Do _not_ return from this callback until
-either the entire bytesToRead is filled or you have reached the end of the stream.
-*/
-typedef size_t (* drmp3_read_proc)(void* pUserData, void* pBufferOut, size_t bytesToRead);
-
-/*
-Callback for when data needs to be seeked.
-
-pUserData [in] The user data that was passed to drmp3_init(), drmp3_open() and family.
-offset [in] The number of bytes to move, relative to the origin. Will never be negative.
-origin [in] The origin of the seek - the current position or the start of the stream.
-
-Returns whether or not the seek was successful.
-
-Whether or not it is relative to the beginning or current position is determined by the "origin" parameter which
-will be either drmp3_seek_origin_start or drmp3_seek_origin_current.
-*/
-typedef drmp3_bool32 (* drmp3_seek_proc)(void* pUserData, int offset, drmp3_seek_origin origin);
-
-typedef struct
-{
- drmp3_uint32 channels;
- drmp3_uint32 sampleRate;
-} drmp3_config;
-
-typedef struct
-{
- drmp3dec decoder;
- drmp3_uint32 channels;
- drmp3_uint32 sampleRate;
- drmp3_read_proc onRead;
- drmp3_seek_proc onSeek;
- void* pUserData;
- drmp3_allocation_callbacks allocationCallbacks;
- drmp3_uint32 mp3FrameChannels; /* The number of channels in the currently loaded MP3 frame. Internal use only. */
- drmp3_uint32 mp3FrameSampleRate; /* The sample rate of the currently loaded MP3 frame. Internal use only. */
- drmp3_uint32 pcmFramesConsumedInMP3Frame;
- drmp3_uint32 pcmFramesRemainingInMP3Frame;
- drmp3_uint8 pcmFrames[sizeof(float)*DRMP3_MAX_SAMPLES_PER_FRAME]; /* <-- Multipled by sizeof(float) to ensure there's enough room for DR_MP3_FLOAT_OUTPUT. */
- drmp3_uint64 currentPCMFrame; /* The current PCM frame, globally, based on the output sample rate. Mainly used for seeking. */
- drmp3_uint64 streamCursor; /* The current byte the decoder is sitting on in the raw stream. */
- drmp3_seek_point* pSeekPoints; /* NULL by default. Set with drmp3_bind_seek_table(). Memory is owned by the client. dr_mp3 will never attempt to free this pointer. */
- drmp3_uint32 seekPointCount; /* The number of items in pSeekPoints. When set to 0 assumes to no seek table. Defaults to zero. */
- size_t dataSize;
- size_t dataCapacity;
- size_t dataConsumed;
- drmp3_uint8* pData;
- drmp3_bool32 atEnd : 1;
- struct
- {
- const drmp3_uint8* pData;
- size_t dataSize;
- size_t currentReadPos;
- } memory; /* Only used for decoders that were opened against a block of memory. */
-} drmp3;
-
-/*
-Initializes an MP3 decoder.
-
-onRead [in] The function to call when data needs to be read from the client.
-onSeek [in] The function to call when the read position of the client data needs to move.
-pUserData [in, optional] A pointer to application defined data that will be passed to onRead and onSeek.
-
-Returns true if successful; false otherwise.
-
-Close the loader with drmp3_uninit().
-
-See also: drmp3_init_file(), drmp3_init_memory(), drmp3_uninit()
-*/
-DRMP3_API drmp3_bool32 drmp3_init(drmp3* pMP3, drmp3_read_proc onRead, drmp3_seek_proc onSeek, void* pUserData, const drmp3_allocation_callbacks* pAllocationCallbacks);
-
-/*
-Initializes an MP3 decoder from a block of memory.
-
-This does not create a copy of the data. It is up to the application to ensure the buffer remains valid for
-the lifetime of the drmp3 object.
-
-The buffer should contain the contents of the entire MP3 file.
-*/
-DRMP3_API drmp3_bool32 drmp3_init_memory(drmp3* pMP3, const void* pData, size_t dataSize, const drmp3_allocation_callbacks* pAllocationCallbacks);
-
-#ifndef DR_MP3_NO_STDIO
-/*
-Initializes an MP3 decoder from a file.
-
-This holds the internal FILE object until drmp3_uninit() is called. Keep this in mind if you're caching drmp3
-objects because the operating system may restrict the number of file handles an application can have open at
-any given time.
-*/
-DRMP3_API drmp3_bool32 drmp3_init_file(drmp3* pMP3, const char* pFilePath, const drmp3_allocation_callbacks* pAllocationCallbacks);
-DRMP3_API drmp3_bool32 drmp3_init_file_w(drmp3* pMP3, const wchar_t* pFilePath, const drmp3_allocation_callbacks* pAllocationCallbacks);
-#endif
-
-/*
-Uninitializes an MP3 decoder.
-*/
-DRMP3_API void drmp3_uninit(drmp3* pMP3);
-
-/*
-Reads PCM frames as interleaved 32-bit IEEE floating point PCM.
-
-Note that framesToRead specifies the number of PCM frames to read, _not_ the number of MP3 frames.
-*/
-DRMP3_API drmp3_uint64 drmp3_read_pcm_frames_f32(drmp3* pMP3, drmp3_uint64 framesToRead, float* pBufferOut);
-
-/*
-Reads PCM frames as interleaved signed 16-bit integer PCM.
-
-Note that framesToRead specifies the number of PCM frames to read, _not_ the number of MP3 frames.
-*/
-DRMP3_API drmp3_uint64 drmp3_read_pcm_frames_s16(drmp3* pMP3, drmp3_uint64 framesToRead, drmp3_int16* pBufferOut);
-
-/*
-Seeks to a specific frame.
-
-Note that this is _not_ an MP3 frame, but rather a PCM frame.
-*/
-DRMP3_API drmp3_bool32 drmp3_seek_to_pcm_frame(drmp3* pMP3, drmp3_uint64 frameIndex);
-
-/*
-Calculates the total number of PCM frames in the MP3 stream. Cannot be used for infinite streams such as internet
-radio. Runs in linear time. Returns 0 on error.
-*/
-DRMP3_API drmp3_uint64 drmp3_get_pcm_frame_count(drmp3* pMP3);
-
-/*
-Calculates the total number of MP3 frames in the MP3 stream. Cannot be used for infinite streams such as internet
-radio. Runs in linear time. Returns 0 on error.
-*/
-DRMP3_API drmp3_uint64 drmp3_get_mp3_frame_count(drmp3* pMP3);
-
-/*
-Calculates the total number of MP3 and PCM frames in the MP3 stream. Cannot be used for infinite streams such as internet
-radio. Runs in linear time. Returns 0 on error.
-
-This is equivalent to calling drmp3_get_mp3_frame_count() and drmp3_get_pcm_frame_count() except that it's more efficient.
-*/
-DRMP3_API drmp3_bool32 drmp3_get_mp3_and_pcm_frame_count(drmp3* pMP3, drmp3_uint64* pMP3FrameCount, drmp3_uint64* pPCMFrameCount);
-
-/*
-Calculates the seekpoints based on PCM frames. This is slow.
-
-pSeekpoint count is a pointer to a uint32 containing the seekpoint count. On input it contains the desired count.
-On output it contains the actual count. The reason for this design is that the client may request too many
-seekpoints, in which case dr_mp3 will return a corrected count.
-
-Note that seektable seeking is not quite sample exact when the MP3 stream contains inconsistent sample rates.
-*/
-DRMP3_API drmp3_bool32 drmp3_calculate_seek_points(drmp3* pMP3, drmp3_uint32* pSeekPointCount, drmp3_seek_point* pSeekPoints);
-
-/*
-Binds a seek table to the decoder.
-
-This does _not_ make a copy of pSeekPoints - it only references it. It is up to the application to ensure this
-remains valid while it is bound to the decoder.
-
-Use drmp3_calculate_seek_points() to calculate the seek points.
-*/
-DRMP3_API drmp3_bool32 drmp3_bind_seek_table(drmp3* pMP3, drmp3_uint32 seekPointCount, drmp3_seek_point* pSeekPoints);
-
-
-/*
-Opens an decodes an entire MP3 stream as a single operation.
-
-On output pConfig will receive the channel count and sample rate of the stream.
-
-Free the returned pointer with drmp3_free().
-*/
-DRMP3_API float* drmp3_open_and_read_pcm_frames_f32(drmp3_read_proc onRead, drmp3_seek_proc onSeek, void* pUserData, drmp3_config* pConfig, drmp3_uint64* pTotalFrameCount, const drmp3_allocation_callbacks* pAllocationCallbacks);
-DRMP3_API drmp3_int16* drmp3_open_and_read_pcm_frames_s16(drmp3_read_proc onRead, drmp3_seek_proc onSeek, void* pUserData, drmp3_config* pConfig, drmp3_uint64* pTotalFrameCount, const drmp3_allocation_callbacks* pAllocationCallbacks);
-
-DRMP3_API float* drmp3_open_memory_and_read_pcm_frames_f32(const void* pData, size_t dataSize, drmp3_config* pConfig, drmp3_uint64* pTotalFrameCount, const drmp3_allocation_callbacks* pAllocationCallbacks);
-DRMP3_API drmp3_int16* drmp3_open_memory_and_read_pcm_frames_s16(const void* pData, size_t dataSize, drmp3_config* pConfig, drmp3_uint64* pTotalFrameCount, const drmp3_allocation_callbacks* pAllocationCallbacks);
-
-#ifndef DR_MP3_NO_STDIO
-DRMP3_API float* drmp3_open_file_and_read_pcm_frames_f32(const char* filePath, drmp3_config* pConfig, drmp3_uint64* pTotalFrameCount, const drmp3_allocation_callbacks* pAllocationCallbacks);
-DRMP3_API drmp3_int16* drmp3_open_file_and_read_pcm_frames_s16(const char* filePath, drmp3_config* pConfig, drmp3_uint64* pTotalFrameCount, const drmp3_allocation_callbacks* pAllocationCallbacks);
-#endif
-
-/*
-Allocates a block of memory on the heap.
-*/
-DRMP3_API void* drmp3_malloc(size_t sz, const drmp3_allocation_callbacks* pAllocationCallbacks);
-
-/*
-Frees any memory that was allocated by a public drmp3 API.
-*/
-DRMP3_API void drmp3_free(void* p, const drmp3_allocation_callbacks* pAllocationCallbacks);
-
-#ifdef __cplusplus
-}
-#endif
-#endif /* dr_mp3_h */
-
-
-/************************************************************************************************************************************************************
- ************************************************************************************************************************************************************
-
- IMPLEMENTATION
-
- ************************************************************************************************************************************************************
- ************************************************************************************************************************************************************/
-#if defined(DR_MP3_IMPLEMENTATION) || defined(DRMP3_IMPLEMENTATION)
-#ifndef dr_mp3_c
-#define dr_mp3_c
-
-#include
-#include
-#include /* For INT_MAX */
-
-DRMP3_API void drmp3_version(drmp3_uint32* pMajor, drmp3_uint32* pMinor, drmp3_uint32* pRevision)
-{
- if (pMajor) {
- *pMajor = DRMP3_VERSION_MAJOR;
- }
-
- if (pMinor) {
- *pMinor = DRMP3_VERSION_MINOR;
- }
-
- if (pRevision) {
- *pRevision = DRMP3_VERSION_REVISION;
- }
-}
-
-DRMP3_API const char* drmp3_version_string(void)
-{
- return DRMP3_VERSION_STRING;
-}
-
-/* Disable SIMD when compiling with TCC for now. */
-#if defined(__TINYC__)
-#define DR_MP3_NO_SIMD
-#endif
-
-#define DRMP3_OFFSET_PTR(p, offset) ((void*)((drmp3_uint8*)(p) + (offset)))
-
-#define DRMP3_MAX_FREE_FORMAT_FRAME_SIZE 2304 /* more than ISO spec's */
-#ifndef DRMP3_MAX_FRAME_SYNC_MATCHES
-#define DRMP3_MAX_FRAME_SYNC_MATCHES 10
-#endif
-
-#define DRMP3_MAX_L3_FRAME_PAYLOAD_BYTES DRMP3_MAX_FREE_FORMAT_FRAME_SIZE /* MUST be >= 320000/8/32000*1152 = 1440 */
-
-#define DRMP3_MAX_BITRESERVOIR_BYTES 511
-#define DRMP3_SHORT_BLOCK_TYPE 2
-#define DRMP3_STOP_BLOCK_TYPE 3
-#define DRMP3_MODE_MONO 3
-#define DRMP3_MODE_JOINT_STEREO 1
-#define DRMP3_HDR_SIZE 4
-#define DRMP3_HDR_IS_MONO(h) (((h[3]) & 0xC0) == 0xC0)
-#define DRMP3_HDR_IS_MS_STEREO(h) (((h[3]) & 0xE0) == 0x60)
-#define DRMP3_HDR_IS_FREE_FORMAT(h) (((h[2]) & 0xF0) == 0)
-#define DRMP3_HDR_IS_CRC(h) (!((h[1]) & 1))
-#define DRMP3_HDR_TEST_PADDING(h) ((h[2]) & 0x2)
-#define DRMP3_HDR_TEST_MPEG1(h) ((h[1]) & 0x8)
-#define DRMP3_HDR_TEST_NOT_MPEG25(h) ((h[1]) & 0x10)
-#define DRMP3_HDR_TEST_I_STEREO(h) ((h[3]) & 0x10)
-#define DRMP3_HDR_TEST_MS_STEREO(h) ((h[3]) & 0x20)
-#define DRMP3_HDR_GET_STEREO_MODE(h) (((h[3]) >> 6) & 3)
-#define DRMP3_HDR_GET_STEREO_MODE_EXT(h) (((h[3]) >> 4) & 3)
-#define DRMP3_HDR_GET_LAYER(h) (((h[1]) >> 1) & 3)
-#define DRMP3_HDR_GET_BITRATE(h) ((h[2]) >> 4)
-#define DRMP3_HDR_GET_SAMPLE_RATE(h) (((h[2]) >> 2) & 3)
-#define DRMP3_HDR_GET_MY_SAMPLE_RATE(h) (DRMP3_HDR_GET_SAMPLE_RATE(h) + (((h[1] >> 3) & 1) + ((h[1] >> 4) & 1))*3)
-#define DRMP3_HDR_IS_FRAME_576(h) ((h[1] & 14) == 2)
-#define DRMP3_HDR_IS_LAYER_1(h) ((h[1] & 6) == 6)
-
-#define DRMP3_BITS_DEQUANTIZER_OUT -1
-#define DRMP3_MAX_SCF (255 + DRMP3_BITS_DEQUANTIZER_OUT*4 - 210)
-#define DRMP3_MAX_SCFI ((DRMP3_MAX_SCF + 3) & ~3)
-
-#define DRMP3_MIN(a, b) ((a) > (b) ? (b) : (a))
-#define DRMP3_MAX(a, b) ((a) < (b) ? (b) : (a))
-
-#if !defined(DR_MP3_NO_SIMD)
-
-#if !defined(DR_MP3_ONLY_SIMD) && (defined(_M_X64) || defined(__x86_64__) || defined(__aarch64__) || defined(_M_ARM64))
-/* x64 always have SSE2, arm64 always have neon, no need for generic code */
-#define DR_MP3_ONLY_SIMD
-#endif
-
-#if ((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__)))
-#if defined(_MSC_VER)
-#include
-#endif
-#include
-#define DRMP3_HAVE_SSE 1
-#define DRMP3_HAVE_SIMD 1
-#define DRMP3_VSTORE _mm_storeu_ps
-#define DRMP3_VLD _mm_loadu_ps
-#define DRMP3_VSET _mm_set1_ps
-#define DRMP3_VADD _mm_add_ps
-#define DRMP3_VSUB _mm_sub_ps
-#define DRMP3_VMUL _mm_mul_ps
-#define DRMP3_VMAC(a, x, y) _mm_add_ps(a, _mm_mul_ps(x, y))
-#define DRMP3_VMSB(a, x, y) _mm_sub_ps(a, _mm_mul_ps(x, y))
-#define DRMP3_VMUL_S(x, s) _mm_mul_ps(x, _mm_set1_ps(s))
-#define DRMP3_VREV(x) _mm_shuffle_ps(x, x, _MM_SHUFFLE(0, 1, 2, 3))
-typedef __m128 drmp3_f4;
-#if defined(_MSC_VER) || defined(DR_MP3_ONLY_SIMD)
-#define drmp3_cpuid __cpuid
-#else
-static __inline__ __attribute__((always_inline)) void drmp3_cpuid(int CPUInfo[], const int InfoType)
-{
-#if defined(__PIC__)
- __asm__ __volatile__(
-#if defined(__x86_64__)
- "push %%rbx\n"
- "cpuid\n"
- "xchgl %%ebx, %1\n"
- "pop %%rbx\n"
-#else
- "xchgl %%ebx, %1\n"
- "cpuid\n"
- "xchgl %%ebx, %1\n"
-#endif
- : "=a" (CPUInfo[0]), "=r" (CPUInfo[1]), "=c" (CPUInfo[2]), "=d" (CPUInfo[3])
- : "a" (InfoType));
-#else
- __asm__ __volatile__(
- "cpuid"
- : "=a" (CPUInfo[0]), "=b" (CPUInfo[1]), "=c" (CPUInfo[2]), "=d" (CPUInfo[3])
- : "a" (InfoType));
-#endif
-}
-#endif
-static int drmp3_have_simd(void)
-{
-#ifdef DR_MP3_ONLY_SIMD
- return 1;
-#else
- static int g_have_simd;
- int CPUInfo[4];
-#ifdef MINIMP3_TEST
- static int g_counter;
- if (g_counter++ > 100)
- return 0;
-#endif
- if (g_have_simd)
- goto end;
- drmp3_cpuid(CPUInfo, 0);
- if (CPUInfo[0] > 0)
- {
- drmp3_cpuid(CPUInfo, 1);
- g_have_simd = (CPUInfo[3] & (1 << 26)) + 1; /* SSE2 */
- return g_have_simd - 1;
- }
-
-end:
- return g_have_simd - 1;
-#endif
-}
-#elif defined(__ARM_NEON) || defined(__aarch64__) || defined(_M_ARM64)
-#include
-#define DRMP3_HAVE_SSE 0
-#define DRMP3_HAVE_SIMD 1
-#define DRMP3_VSTORE vst1q_f32
-#define DRMP3_VLD vld1q_f32
-#define DRMP3_VSET vmovq_n_f32
-#define DRMP3_VADD vaddq_f32
-#define DRMP3_VSUB vsubq_f32
-#define DRMP3_VMUL vmulq_f32
-#define DRMP3_VMAC(a, x, y) vmlaq_f32(a, x, y)
-#define DRMP3_VMSB(a, x, y) vmlsq_f32(a, x, y)
-#define DRMP3_VMUL_S(x, s) vmulq_f32(x, vmovq_n_f32(s))
-#define DRMP3_VREV(x) vcombine_f32(vget_high_f32(vrev64q_f32(x)), vget_low_f32(vrev64q_f32(x)))
-typedef float32x4_t drmp3_f4;
-static int drmp3_have_simd(void)
-{ /* TODO: detect neon for !DR_MP3_ONLY_SIMD */
- return 1;
-}
-#else
-#define DRMP3_HAVE_SSE 0
-#define DRMP3_HAVE_SIMD 0
-#ifdef DR_MP3_ONLY_SIMD
-#error DR_MP3_ONLY_SIMD used, but SSE/NEON not enabled
-#endif
-#endif
-
-#else
-
-#define DRMP3_HAVE_SIMD 0
-
-#endif
-
-#if defined(__ARM_ARCH) && (__ARM_ARCH >= 6) && !defined(__aarch64__) && !defined(_M_ARM64) && !defined(__ARM_ARCH_6M__)
-#define DRMP3_HAVE_ARMV6 1
-static __inline__ __attribute__((always_inline)) drmp3_int32 drmp3_clip_int16_arm(drmp3_int32 a)
-{
- drmp3_int32 x = 0;
- __asm__ ("ssat %0, #16, %1" : "=r"(x) : "r"(a));
- return x;
-}
-#else
-#define DRMP3_HAVE_ARMV6 0
-#endif
-
-
-/* Standard library stuff. */
-#ifndef DRMP3_ASSERT
-#include
-#define DRMP3_ASSERT(expression) assert(expression)
-#endif
-#ifndef DRMP3_COPY_MEMORY
-#define DRMP3_COPY_MEMORY(dst, src, sz) memcpy((dst), (src), (sz))
-#endif
-#ifndef DRMP3_MOVE_MEMORY
-#define DRMP3_MOVE_MEMORY(dst, src, sz) memmove((dst), (src), (sz))
-#endif
-#ifndef DRMP3_ZERO_MEMORY
-#define DRMP3_ZERO_MEMORY(p, sz) memset((p), 0, (sz))
-#endif
-#define DRMP3_ZERO_OBJECT(p) DRMP3_ZERO_MEMORY((p), sizeof(*(p)))
-#ifndef DRMP3_MALLOC
-#define DRMP3_MALLOC(sz) malloc((sz))
-#endif
-#ifndef DRMP3_REALLOC
-#define DRMP3_REALLOC(p, sz) realloc((p), (sz))
-#endif
-#ifndef DRMP3_FREE
-#define DRMP3_FREE(p) free((p))
-#endif
-
-typedef struct
-{
- const drmp3_uint8 *buf;
- int pos, limit;
-} drmp3_bs;
-
-typedef struct
-{
- float scf[3*64];
- drmp3_uint8 total_bands, stereo_bands, bitalloc[64], scfcod[64];
-} drmp3_L12_scale_info;
-
-typedef struct
-{
- drmp3_uint8 tab_offset, code_tab_width, band_count;
-} drmp3_L12_subband_alloc;
-
-typedef struct
-{
- const drmp3_uint8 *sfbtab;
- drmp3_uint16 part_23_length, big_values, scalefac_compress;
- drmp3_uint8 global_gain, block_type, mixed_block_flag, n_long_sfb, n_short_sfb;
- drmp3_uint8 table_select[3], region_count[3], subblock_gain[3];
- drmp3_uint8 preflag, scalefac_scale, count1_table, scfsi;
-} drmp3_L3_gr_info;
-
-typedef struct
-{
- drmp3_bs bs;
- drmp3_uint8 maindata[DRMP3_MAX_BITRESERVOIR_BYTES + DRMP3_MAX_L3_FRAME_PAYLOAD_BYTES];
- drmp3_L3_gr_info gr_info[4];
- float grbuf[2][576], scf[40], syn[18 + 15][2*32];
- drmp3_uint8 ist_pos[2][39];
-} drmp3dec_scratch;
-
-static void drmp3_bs_init(drmp3_bs *bs, const drmp3_uint8 *data, int bytes)
-{
- bs->buf = data;
- bs->pos = 0;
- bs->limit = bytes*8;
-}
-
-static drmp3_uint32 drmp3_bs_get_bits(drmp3_bs *bs, int n)
-{
- drmp3_uint32 next, cache = 0, s = bs->pos & 7;
- int shl = n + s;
- const drmp3_uint8 *p = bs->buf + (bs->pos >> 3);
- if ((bs->pos += n) > bs->limit)
- return 0;
- next = *p++ & (255 >> s);
- while ((shl -= 8) > 0)
- {
- cache |= next << shl;
- next = *p++;
- }
- return cache | (next >> -shl);
-}
-
-static int drmp3_hdr_valid(const drmp3_uint8 *h)
-{
- return h[0] == 0xff &&
- ((h[1] & 0xF0) == 0xf0 || (h[1] & 0xFE) == 0xe2) &&
- (DRMP3_HDR_GET_LAYER(h) != 0) &&
- (DRMP3_HDR_GET_BITRATE(h) != 15) &&
- (DRMP3_HDR_GET_SAMPLE_RATE(h) != 3);
-}
-
-static int drmp3_hdr_compare(const drmp3_uint8 *h1, const drmp3_uint8 *h2)
-{
- return drmp3_hdr_valid(h2) &&
- ((h1[1] ^ h2[1]) & 0xFE) == 0 &&
- ((h1[2] ^ h2[2]) & 0x0C) == 0 &&
- !(DRMP3_HDR_IS_FREE_FORMAT(h1) ^ DRMP3_HDR_IS_FREE_FORMAT(h2));
-}
-
-static unsigned drmp3_hdr_bitrate_kbps(const drmp3_uint8 *h)
-{
- static const drmp3_uint8 halfrate[2][3][15] = {
- { { 0,4,8,12,16,20,24,28,32,40,48,56,64,72,80 }, { 0,4,8,12,16,20,24,28,32,40,48,56,64,72,80 }, { 0,16,24,28,32,40,48,56,64,72,80,88,96,112,128 } },
- { { 0,16,20,24,28,32,40,48,56,64,80,96,112,128,160 }, { 0,16,24,28,32,40,48,56,64,80,96,112,128,160,192 }, { 0,16,32,48,64,80,96,112,128,144,160,176,192,208,224 } },
- };
- return 2*halfrate[!!DRMP3_HDR_TEST_MPEG1(h)][DRMP3_HDR_GET_LAYER(h) - 1][DRMP3_HDR_GET_BITRATE(h)];
-}
-
-static unsigned drmp3_hdr_sample_rate_hz(const drmp3_uint8 *h)
-{
- static const unsigned g_hz[3] = { 44100, 48000, 32000 };
- return g_hz[DRMP3_HDR_GET_SAMPLE_RATE(h)] >> (int)!DRMP3_HDR_TEST_MPEG1(h) >> (int)!DRMP3_HDR_TEST_NOT_MPEG25(h);
-}
-
-static unsigned drmp3_hdr_frame_samples(const drmp3_uint8 *h)
-{
- return DRMP3_HDR_IS_LAYER_1(h) ? 384 : (1152 >> (int)DRMP3_HDR_IS_FRAME_576(h));
-}
-
-static int drmp3_hdr_frame_bytes(const drmp3_uint8 *h, int free_format_size)
-{
- int frame_bytes = drmp3_hdr_frame_samples(h)*drmp3_hdr_bitrate_kbps(h)*125/drmp3_hdr_sample_rate_hz(h);
- if (DRMP3_HDR_IS_LAYER_1(h))
- {
- frame_bytes &= ~3; /* slot align */
- }
- return frame_bytes ? frame_bytes : free_format_size;
-}
-
-static int drmp3_hdr_padding(const drmp3_uint8 *h)
-{
- return DRMP3_HDR_TEST_PADDING(h) ? (DRMP3_HDR_IS_LAYER_1(h) ? 4 : 1) : 0;
-}
-
-#ifndef DR_MP3_ONLY_MP3
-static const drmp3_L12_subband_alloc *drmp3_L12_subband_alloc_table(const drmp3_uint8 *hdr, drmp3_L12_scale_info *sci)
-{
- const drmp3_L12_subband_alloc *alloc;
- int mode = DRMP3_HDR_GET_STEREO_MODE(hdr);
- int nbands, stereo_bands = (mode == DRMP3_MODE_MONO) ? 0 : (mode == DRMP3_MODE_JOINT_STEREO) ? (DRMP3_HDR_GET_STEREO_MODE_EXT(hdr) << 2) + 4 : 32;
-
- if (DRMP3_HDR_IS_LAYER_1(hdr))
- {
- static const drmp3_L12_subband_alloc g_alloc_L1[] = { { 76, 4, 32 } };
- alloc = g_alloc_L1;
- nbands = 32;
- } else if (!DRMP3_HDR_TEST_MPEG1(hdr))
- {
- static const drmp3_L12_subband_alloc g_alloc_L2M2[] = { { 60, 4, 4 }, { 44, 3, 7 }, { 44, 2, 19 } };
- alloc = g_alloc_L2M2;
- nbands = 30;
- } else
- {
- static const drmp3_L12_subband_alloc g_alloc_L2M1[] = { { 0, 4, 3 }, { 16, 4, 8 }, { 32, 3, 12 }, { 40, 2, 7 } };
- int sample_rate_idx = DRMP3_HDR_GET_SAMPLE_RATE(hdr);
- unsigned kbps = drmp3_hdr_bitrate_kbps(hdr) >> (int)(mode != DRMP3_MODE_MONO);
- if (!kbps) /* free-format */
- {
- kbps = 192;
- }
-
- alloc = g_alloc_L2M1;
- nbands = 27;
- if (kbps < 56)
- {
- static const drmp3_L12_subband_alloc g_alloc_L2M1_lowrate[] = { { 44, 4, 2 }, { 44, 3, 10 } };
- alloc = g_alloc_L2M1_lowrate;
- nbands = sample_rate_idx == 2 ? 12 : 8;
- } else if (kbps >= 96 && sample_rate_idx != 1)
- {
- nbands = 30;
- }
- }
-
- sci->total_bands = (drmp3_uint8)nbands;
- sci->stereo_bands = (drmp3_uint8)DRMP3_MIN(stereo_bands, nbands);
-
- return alloc;
-}
-
-static void drmp3_L12_read_scalefactors(drmp3_bs *bs, drmp3_uint8 *pba, drmp3_uint8 *scfcod, int bands, float *scf)
-{
- static const float g_deq_L12[18*3] = {
-#define DRMP3_DQ(x) 9.53674316e-07f/x, 7.56931807e-07f/x, 6.00777173e-07f/x
- DRMP3_DQ(3),DRMP3_DQ(7),DRMP3_DQ(15),DRMP3_DQ(31),DRMP3_DQ(63),DRMP3_DQ(127),DRMP3_DQ(255),DRMP3_DQ(511),DRMP3_DQ(1023),DRMP3_DQ(2047),DRMP3_DQ(4095),DRMP3_DQ(8191),DRMP3_DQ(16383),DRMP3_DQ(32767),DRMP3_DQ(65535),DRMP3_DQ(3),DRMP3_DQ(5),DRMP3_DQ(9)
- };
- int i, m;
- for (i = 0; i < bands; i++)
- {
- float s = 0;
- int ba = *pba++;
- int mask = ba ? 4 + ((19 >> scfcod[i]) & 3) : 0;
- for (m = 4; m; m >>= 1)
- {
- if (mask & m)
- {
- int b = drmp3_bs_get_bits(bs, 6);
- s = g_deq_L12[ba*3 - 6 + b % 3]*(int)(1 << 21 >> b/3);
- }
- *scf++ = s;
- }
- }
-}
-
-static void drmp3_L12_read_scale_info(const drmp3_uint8 *hdr, drmp3_bs *bs, drmp3_L12_scale_info *sci)
-{
- static const drmp3_uint8 g_bitalloc_code_tab[] = {
- 0,17, 3, 4, 5,6,7, 8,9,10,11,12,13,14,15,16,
- 0,17,18, 3,19,4,5, 6,7, 8, 9,10,11,12,13,16,
- 0,17,18, 3,19,4,5,16,
- 0,17,18,16,
- 0,17,18,19, 4,5,6, 7,8, 9,10,11,12,13,14,15,
- 0,17,18, 3,19,4,5, 6,7, 8, 9,10,11,12,13,14,
- 0, 2, 3, 4, 5,6,7, 8,9,10,11,12,13,14,15,16
- };
- const drmp3_L12_subband_alloc *subband_alloc = drmp3_L12_subband_alloc_table(hdr, sci);
-
- int i, k = 0, ba_bits = 0;
- const drmp3_uint8 *ba_code_tab = g_bitalloc_code_tab;
-
- for (i = 0; i < sci->total_bands; i++)
- {
- drmp3_uint8 ba;
- if (i == k)
- {
- k += subband_alloc->band_count;
- ba_bits = subband_alloc->code_tab_width;
- ba_code_tab = g_bitalloc_code_tab + subband_alloc->tab_offset;
- subband_alloc++;
- }
- ba = ba_code_tab[drmp3_bs_get_bits(bs, ba_bits)];
- sci->bitalloc[2*i] = ba;
- if (i < sci->stereo_bands)
- {
- ba = ba_code_tab[drmp3_bs_get_bits(bs, ba_bits)];
- }
- sci->bitalloc[2*i + 1] = sci->stereo_bands ? ba : 0;
- }
-
- for (i = 0; i < 2*sci->total_bands; i++)
- {
- sci->scfcod[i] = (drmp3_uint8)(sci->bitalloc[i] ? DRMP3_HDR_IS_LAYER_1(hdr) ? 2 : drmp3_bs_get_bits(bs, 2) : 6);
- }
-
- drmp3_L12_read_scalefactors(bs, sci->bitalloc, sci->scfcod, sci->total_bands*2, sci->scf);
-
- for (i = sci->stereo_bands; i < sci->total_bands; i++)
- {
- sci->bitalloc[2*i + 1] = 0;
- }
-}
-
-static int drmp3_L12_dequantize_granule(float *grbuf, drmp3_bs *bs, drmp3_L12_scale_info *sci, int group_size)
-{
- int i, j, k, choff = 576;
- for (j = 0; j < 4; j++)
- {
- float *dst = grbuf + group_size*j;
- for (i = 0; i < 2*sci->total_bands; i++)
- {
- int ba = sci->bitalloc[i];
- if (ba != 0)
- {
- if (ba < 17)
- {
- int half = (1 << (ba - 1)) - 1;
- for (k = 0; k < group_size; k++)
- {
- dst[k] = (float)((int)drmp3_bs_get_bits(bs, ba) - half);
- }
- } else
- {
- unsigned mod = (2 << (ba - 17)) + 1; /* 3, 5, 9 */
- unsigned code = drmp3_bs_get_bits(bs, mod + 2 - (mod >> 3)); /* 5, 7, 10 */
- for (k = 0; k < group_size; k++, code /= mod)
- {
- dst[k] = (float)((int)(code % mod - mod/2));
- }
- }
- }
- dst += choff;
- choff = 18 - choff;
- }
- }
- return group_size*4;
-}
-
-static void drmp3_L12_apply_scf_384(drmp3_L12_scale_info *sci, const float *scf, float *dst)
-{
- int i, k;
- DRMP3_COPY_MEMORY(dst + 576 + sci->stereo_bands*18, dst + sci->stereo_bands*18, (sci->total_bands - sci->stereo_bands)*18*sizeof(float));
- for (i = 0; i < sci->total_bands; i++, dst += 18, scf += 6)
- {
- for (k = 0; k < 12; k++)
- {
- dst[k + 0] *= scf[0];
- dst[k + 576] *= scf[3];
- }
- }
-}
-#endif
-
-static int drmp3_L3_read_side_info(drmp3_bs *bs, drmp3_L3_gr_info *gr, const drmp3_uint8 *hdr)
-{
- static const drmp3_uint8 g_scf_long[8][23] = {
- { 6,6,6,6,6,6,8,10,12,14,16,20,24,28,32,38,46,52,60,68,58,54,0 },
- { 12,12,12,12,12,12,16,20,24,28,32,40,48,56,64,76,90,2,2,2,2,2,0 },
- { 6,6,6,6,6,6,8,10,12,14,16,20,24,28,32,38,46,52,60,68,58,54,0 },
- { 6,6,6,6,6,6,8,10,12,14,16,18,22,26,32,38,46,54,62,70,76,36,0 },
- { 6,6,6,6,6,6,8,10,12,14,16,20,24,28,32,38,46,52,60,68,58,54,0 },
- { 4,4,4,4,4,4,6,6,8,8,10,12,16,20,24,28,34,42,50,54,76,158,0 },
- { 4,4,4,4,4,4,6,6,6,8,10,12,16,18,22,28,34,40,46,54,54,192,0 },
- { 4,4,4,4,4,4,6,6,8,10,12,16,20,24,30,38,46,56,68,84,102,26,0 }
- };
- static const drmp3_uint8 g_scf_short[8][40] = {
- { 4,4,4,4,4,4,4,4,4,6,6,6,8,8,8,10,10,10,12,12,12,14,14,14,18,18,18,24,24,24,30,30,30,40,40,40,18,18,18,0 },
- { 8,8,8,8,8,8,8,8,8,12,12,12,16,16,16,20,20,20,24,24,24,28,28,28,36,36,36,2,2,2,2,2,2,2,2,2,26,26,26,0 },
- { 4,4,4,4,4,4,4,4,4,6,6,6,6,6,6,8,8,8,10,10,10,14,14,14,18,18,18,26,26,26,32,32,32,42,42,42,18,18,18,0 },
- { 4,4,4,4,4,4,4,4,4,6,6,6,8,8,8,10,10,10,12,12,12,14,14,14,18,18,18,24,24,24,32,32,32,44,44,44,12,12,12,0 },
- { 4,4,4,4,4,4,4,4,4,6,6,6,8,8,8,10,10,10,12,12,12,14,14,14,18,18,18,24,24,24,30,30,30,40,40,40,18,18,18,0 },
- { 4,4,4,4,4,4,4,4,4,4,4,4,6,6,6,8,8,8,10,10,10,12,12,12,14,14,14,18,18,18,22,22,22,30,30,30,56,56,56,0 },
- { 4,4,4,4,4,4,4,4,4,4,4,4,6,6,6,6,6,6,10,10,10,12,12,12,14,14,14,16,16,16,20,20,20,26,26,26,66,66,66,0 },
- { 4,4,4,4,4,4,4,4,4,4,4,4,6,6,6,8,8,8,12,12,12,16,16,16,20,20,20,26,26,26,34,34,34,42,42,42,12,12,12,0 }
- };
- static const drmp3_uint8 g_scf_mixed[8][40] = {
- { 6,6,6,6,6,6,6,6,6,8,8,8,10,10,10,12,12,12,14,14,14,18,18,18,24,24,24,30,30,30,40,40,40,18,18,18,0 },
- { 12,12,12,4,4,4,8,8,8,12,12,12,16,16,16,20,20,20,24,24,24,28,28,28,36,36,36,2,2,2,2,2,2,2,2,2,26,26,26,0 },
- { 6,6,6,6,6,6,6,6,6,6,6,6,8,8,8,10,10,10,14,14,14,18,18,18,26,26,26,32,32,32,42,42,42,18,18,18,0 },
- { 6,6,6,6,6,6,6,6,6,8,8,8,10,10,10,12,12,12,14,14,14,18,18,18,24,24,24,32,32,32,44,44,44,12,12,12,0 },
- { 6,6,6,6,6,6,6,6,6,8,8,8,10,10,10,12,12,12,14,14,14,18,18,18,24,24,24,30,30,30,40,40,40,18,18,18,0 },
- { 4,4,4,4,4,4,6,6,4,4,4,6,6,6,8,8,8,10,10,10,12,12,12,14,14,14,18,18,18,22,22,22,30,30,30,56,56,56,0 },
- { 4,4,4,4,4,4,6,6,4,4,4,6,6,6,6,6,6,10,10,10,12,12,12,14,14,14,16,16,16,20,20,20,26,26,26,66,66,66,0 },
- { 4,4,4,4,4,4,6,6,4,4,4,6,6,6,8,8,8,12,12,12,16,16,16,20,20,20,26,26,26,34,34,34,42,42,42,12,12,12,0 }
- };
-
- unsigned tables, scfsi = 0;
- int main_data_begin, part_23_sum = 0;
- int gr_count = DRMP3_HDR_IS_MONO(hdr) ? 1 : 2;
- int sr_idx = DRMP3_HDR_GET_MY_SAMPLE_RATE(hdr); sr_idx -= (sr_idx != 0);
-
- if (DRMP3_HDR_TEST_MPEG1(hdr))
- {
- gr_count *= 2;
- main_data_begin = drmp3_bs_get_bits(bs, 9);
- scfsi = drmp3_bs_get_bits(bs, 7 + gr_count);
- } else
- {
- main_data_begin = drmp3_bs_get_bits(bs, 8 + gr_count) >> gr_count;
- }
-
- do
- {
- if (DRMP3_HDR_IS_MONO(hdr))
- {
- scfsi <<= 4;
- }
- gr->part_23_length = (drmp3_uint16)drmp3_bs_get_bits(bs, 12);
- part_23_sum += gr->part_23_length;
- gr->big_values = (drmp3_uint16)drmp3_bs_get_bits(bs, 9);
- if (gr->big_values > 288)
- {
- return -1;
- }
- gr->global_gain = (drmp3_uint8)drmp3_bs_get_bits(bs, 8);
- gr->scalefac_compress = (drmp3_uint16)drmp3_bs_get_bits(bs, DRMP3_HDR_TEST_MPEG1(hdr) ? 4 : 9);
- gr->sfbtab = g_scf_long[sr_idx];
- gr->n_long_sfb = 22;
- gr->n_short_sfb = 0;
- if (drmp3_bs_get_bits(bs, 1))
- {
- gr->block_type = (drmp3_uint8)drmp3_bs_get_bits(bs, 2);
- if (!gr->block_type)
- {
- return -1;
- }
- gr->mixed_block_flag = (drmp3_uint8)drmp3_bs_get_bits(bs, 1);
- gr->region_count[0] = 7;
- gr->region_count[1] = 255;
- if (gr->block_type == DRMP3_SHORT_BLOCK_TYPE)
- {
- scfsi &= 0x0F0F;
- if (!gr->mixed_block_flag)
- {
- gr->region_count[0] = 8;
- gr->sfbtab = g_scf_short[sr_idx];
- gr->n_long_sfb = 0;
- gr->n_short_sfb = 39;
- } else
- {
- gr->sfbtab = g_scf_mixed[sr_idx];
- gr->n_long_sfb = DRMP3_HDR_TEST_MPEG1(hdr) ? 8 : 6;
- gr->n_short_sfb = 30;
- }
- }
- tables = drmp3_bs_get_bits(bs, 10);
- tables <<= 5;
- gr->subblock_gain[0] = (drmp3_uint8)drmp3_bs_get_bits(bs, 3);
- gr->subblock_gain[1] = (drmp3_uint8)drmp3_bs_get_bits(bs, 3);
- gr->subblock_gain[2] = (drmp3_uint8)drmp3_bs_get_bits(bs, 3);
- } else
- {
- gr->block_type = 0;
- gr->mixed_block_flag = 0;
- tables = drmp3_bs_get_bits(bs, 15);
- gr->region_count[0] = (drmp3_uint8)drmp3_bs_get_bits(bs, 4);
- gr->region_count[1] = (drmp3_uint8)drmp3_bs_get_bits(bs, 3);
- gr->region_count[2] = 255;
- }
- gr->table_select[0] = (drmp3_uint8)(tables >> 10);
- gr->table_select[1] = (drmp3_uint8)((tables >> 5) & 31);
- gr->table_select[2] = (drmp3_uint8)((tables) & 31);
- gr->preflag = (drmp3_uint8)(DRMP3_HDR_TEST_MPEG1(hdr) ? drmp3_bs_get_bits(bs, 1) : (gr->scalefac_compress >= 500));
- gr->scalefac_scale = (drmp3_uint8)drmp3_bs_get_bits(bs, 1);
- gr->count1_table = (drmp3_uint8)drmp3_bs_get_bits(bs, 1);
- gr->scfsi = (drmp3_uint8)((scfsi >> 12) & 15);
- scfsi <<= 4;
- gr++;
- } while(--gr_count);
-
- if (part_23_sum + bs->pos > bs->limit + main_data_begin*8)
- {
- return -1;
- }
-
- return main_data_begin;
-}
-
-static void drmp3_L3_read_scalefactors(drmp3_uint8 *scf, drmp3_uint8 *ist_pos, const drmp3_uint8 *scf_size, const drmp3_uint8 *scf_count, drmp3_bs *bitbuf, int scfsi)
-{
- int i, k;
- for (i = 0; i < 4 && scf_count[i]; i++, scfsi *= 2)
- {
- int cnt = scf_count[i];
- if (scfsi & 8)
- {
- DRMP3_COPY_MEMORY(scf, ist_pos, cnt);
- } else
- {
- int bits = scf_size[i];
- if (!bits)
- {
- DRMP3_ZERO_MEMORY(scf, cnt);
- DRMP3_ZERO_MEMORY(ist_pos, cnt);
- } else
- {
- int max_scf = (scfsi < 0) ? (1 << bits) - 1 : -1;
- for (k = 0; k < cnt; k++)
- {
- int s = drmp3_bs_get_bits(bitbuf, bits);
- ist_pos[k] = (drmp3_uint8)(s == max_scf ? -1 : s);
- scf[k] = (drmp3_uint8)s;
- }
- }
- }
- ist_pos += cnt;
- scf += cnt;
- }
- scf[0] = scf[1] = scf[2] = 0;
-}
-
-static float drmp3_L3_ldexp_q2(float y, int exp_q2)
-{
- static const float g_expfrac[4] = { 9.31322575e-10f,7.83145814e-10f,6.58544508e-10f,5.53767716e-10f };
- int e;
- do
- {
- e = DRMP3_MIN(30*4, exp_q2);
- y *= g_expfrac[e & 3]*(1 << 30 >> (e >> 2));
- } while ((exp_q2 -= e) > 0);
- return y;
-}
-
-static void drmp3_L3_decode_scalefactors(const drmp3_uint8 *hdr, drmp3_uint8 *ist_pos, drmp3_bs *bs, const drmp3_L3_gr_info *gr, float *scf, int ch)
-{
- static const drmp3_uint8 g_scf_partitions[3][28] = {
- { 6,5,5, 5,6,5,5,5,6,5, 7,3,11,10,0,0, 7, 7, 7,0, 6, 6,6,3, 8, 8,5,0 },
- { 8,9,6,12,6,9,9,9,6,9,12,6,15,18,0,0, 6,15,12,0, 6,12,9,6, 6,18,9,0 },
- { 9,9,6,12,9,9,9,9,9,9,12,6,18,18,0,0,12,12,12,0,12, 9,9,6,15,12,9,0 }
- };
- const drmp3_uint8 *scf_partition = g_scf_partitions[!!gr->n_short_sfb + !gr->n_long_sfb];
- drmp3_uint8 scf_size[4], iscf[40];
- int i, scf_shift = gr->scalefac_scale + 1, gain_exp, scfsi = gr->scfsi;
- float gain;
-
- if (DRMP3_HDR_TEST_MPEG1(hdr))
- {
- static const drmp3_uint8 g_scfc_decode[16] = { 0,1,2,3, 12,5,6,7, 9,10,11,13, 14,15,18,19 };
- int part = g_scfc_decode[gr->scalefac_compress];
- scf_size[1] = scf_size[0] = (drmp3_uint8)(part >> 2);
- scf_size[3] = scf_size[2] = (drmp3_uint8)(part & 3);
- } else
- {
- static const drmp3_uint8 g_mod[6*4] = { 5,5,4,4,5,5,4,1,4,3,1,1,5,6,6,1,4,4,4,1,4,3,1,1 };
- int k, modprod, sfc, ist = DRMP3_HDR_TEST_I_STEREO(hdr) && ch;
- sfc = gr->scalefac_compress >> ist;
- for (k = ist*3*4; sfc >= 0; sfc -= modprod, k += 4)
- {
- for (modprod = 1, i = 3; i >= 0; i--)
- {
- scf_size[i] = (drmp3_uint8)(sfc / modprod % g_mod[k + i]);
- modprod *= g_mod[k + i];
- }
- }
- scf_partition += k;
- scfsi = -16;
- }
- drmp3_L3_read_scalefactors(iscf, ist_pos, scf_size, scf_partition, bs, scfsi);
-
- if (gr->n_short_sfb)
- {
- int sh = 3 - scf_shift;
- for (i = 0; i < gr->n_short_sfb; i += 3)
- {
- iscf[gr->n_long_sfb + i + 0] = (drmp3_uint8)(iscf[gr->n_long_sfb + i + 0] + (gr->subblock_gain[0] << sh));
- iscf[gr->n_long_sfb + i + 1] = (drmp3_uint8)(iscf[gr->n_long_sfb + i + 1] + (gr->subblock_gain[1] << sh));
- iscf[gr->n_long_sfb + i + 2] = (drmp3_uint8)(iscf[gr->n_long_sfb + i + 2] + (gr->subblock_gain[2] << sh));
- }
- } else if (gr->preflag)
- {
- static const drmp3_uint8 g_preamp[10] = { 1,1,1,1,2,2,3,3,3,2 };
- for (i = 0; i < 10; i++)
- {
- iscf[11 + i] = (drmp3_uint8)(iscf[11 + i] + g_preamp[i]);
- }
- }
-
- gain_exp = gr->global_gain + DRMP3_BITS_DEQUANTIZER_OUT*4 - 210 - (DRMP3_HDR_IS_MS_STEREO(hdr) ? 2 : 0);
- gain = drmp3_L3_ldexp_q2(1 << (DRMP3_MAX_SCFI/4), DRMP3_MAX_SCFI - gain_exp);
- for (i = 0; i < (int)(gr->n_long_sfb + gr->n_short_sfb); i++)
- {
- scf[i] = drmp3_L3_ldexp_q2(gain, iscf[i] << scf_shift);
- }
-}
-
-static const float g_drmp3_pow43[129 + 16] = {
- 0,-1,-2.519842f,-4.326749f,-6.349604f,-8.549880f,-10.902724f,-13.390518f,-16.000000f,-18.720754f,-21.544347f,-24.463781f,-27.473142f,-30.567351f,-33.741992f,-36.993181f,
- 0,1,2.519842f,4.326749f,6.349604f,8.549880f,10.902724f,13.390518f,16.000000f,18.720754f,21.544347f,24.463781f,27.473142f,30.567351f,33.741992f,36.993181f,40.317474f,43.711787f,47.173345f,50.699631f,54.288352f,57.937408f,61.644865f,65.408941f,69.227979f,73.100443f,77.024898f,81.000000f,85.024491f,89.097188f,93.216975f,97.382800f,101.593667f,105.848633f,110.146801f,114.487321f,118.869381f,123.292209f,127.755065f,132.257246f,136.798076f,141.376907f,145.993119f,150.646117f,155.335327f,160.060199f,164.820202f,169.614826f,174.443577f,179.305980f,184.201575f,189.129918f,194.090580f,199.083145f,204.107210f,209.162385f,214.248292f,219.364564f,224.510845f,229.686789f,234.892058f,240.126328f,245.389280f,250.680604f,256.000000f,261.347174f,266.721841f,272.123723f,277.552547f,283.008049f,288.489971f,293.998060f,299.532071f,305.091761f,310.676898f,316.287249f,321.922592f,327.582707f,333.267377f,338.976394f,344.709550f,350.466646f,356.247482f,362.051866f,367.879608f,373.730522f,379.604427f,385.501143f,391.420496f,397.362314f,403.326427f,409.312672f,415.320884f,421.350905f,427.402579f,433.475750f,439.570269f,445.685987f,451.822757f,457.980436f,464.158883f,470.357960f,476.577530f,482.817459f,489.077615f,495.357868f,501.658090f,507.978156f,514.317941f,520.677324f,527.056184f,533.454404f,539.871867f,546.308458f,552.764065f,559.238575f,565.731879f,572.243870f,578.774440f,585.323483f,591.890898f,598.476581f,605.080431f,611.702349f,618.342238f,625.000000f,631.675540f,638.368763f,645.079578f
-};
-
-static float drmp3_L3_pow_43(int x)
-{
- float frac;
- int sign, mult = 256;
-
- if (x < 129)
- {
- return g_drmp3_pow43[16 + x];
- }
-
- if (x < 1024)
- {
- mult = 16;
- x <<= 3;
- }
-
- sign = 2*x & 64;
- frac = (float)((x & 63) - sign) / ((x & ~63) + sign);
- return g_drmp3_pow43[16 + ((x + sign) >> 6)]*(1.f + frac*((4.f/3) + frac*(2.f/9)))*mult;
-}
-
-static void drmp3_L3_huffman(float *dst, drmp3_bs *bs, const drmp3_L3_gr_info *gr_info, const float *scf, int layer3gr_limit)
-{
- static const drmp3_int16 tabs[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 785,785,785,785,784,784,784,784,513,513,513,513,513,513,513,513,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,
- -255,1313,1298,1282,785,785,785,785,784,784,784,784,769,769,769,769,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,290,288,
- -255,1313,1298,1282,769,769,769,769,529,529,529,529,529,529,529,529,528,528,528,528,528,528,528,528,512,512,512,512,512,512,512,512,290,288,
- -253,-318,-351,-367,785,785,785,785,784,784,784,784,769,769,769,769,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,819,818,547,547,275,275,275,275,561,560,515,546,289,274,288,258,
- -254,-287,1329,1299,1314,1312,1057,1057,1042,1042,1026,1026,784,784,784,784,529,529,529,529,529,529,529,529,769,769,769,769,768,768,768,768,563,560,306,306,291,259,
- -252,-413,-477,-542,1298,-575,1041,1041,784,784,784,784,769,769,769,769,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,-383,-399,1107,1092,1106,1061,849,849,789,789,1104,1091,773,773,1076,1075,341,340,325,309,834,804,577,577,532,532,516,516,832,818,803,816,561,561,531,531,515,546,289,289,288,258,
- -252,-429,-493,-559,1057,1057,1042,1042,529,529,529,529,529,529,529,529,784,784,784,784,769,769,769,769,512,512,512,512,512,512,512,512,-382,1077,-415,1106,1061,1104,849,849,789,789,1091,1076,1029,1075,834,834,597,581,340,340,339,324,804,833,532,532,832,772,818,803,817,787,816,771,290,290,290,290,288,258,
- -253,-349,-414,-447,-463,1329,1299,-479,1314,1312,1057,1057,1042,1042,1026,1026,785,785,785,785,784,784,784,784,769,769,769,769,768,768,768,768,-319,851,821,-335,836,850,805,849,341,340,325,336,533,533,579,579,564,564,773,832,578,548,563,516,321,276,306,291,304,259,
- -251,-572,-733,-830,-863,-879,1041,1041,784,784,784,784,769,769,769,769,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,-511,-527,-543,1396,1351,1381,1366,1395,1335,1380,-559,1334,1138,1138,1063,1063,1350,1392,1031,1031,1062,1062,1364,1363,1120,1120,1333,1348,881,881,881,881,375,374,359,373,343,358,341,325,791,791,1123,1122,-703,1105,1045,-719,865,865,790,790,774,774,1104,1029,338,293,323,308,-799,-815,833,788,772,818,803,816,322,292,307,320,561,531,515,546,289,274,288,258,
- -251,-525,-605,-685,-765,-831,-846,1298,1057,1057,1312,1282,785,785,785,785,784,784,784,784,769,769,769,769,512,512,512,512,512,512,512,512,1399,1398,1383,1367,1382,1396,1351,-511,1381,1366,1139,1139,1079,1079,1124,1124,1364,1349,1363,1333,882,882,882,882,807,807,807,807,1094,1094,1136,1136,373,341,535,535,881,775,867,822,774,-591,324,338,-671,849,550,550,866,864,609,609,293,336,534,534,789,835,773,-751,834,804,308,307,833,788,832,772,562,562,547,547,305,275,560,515,290,290,
- -252,-397,-477,-557,-622,-653,-719,-735,-750,1329,1299,1314,1057,1057,1042,1042,1312,1282,1024,1024,785,785,785,785,784,784,784,784,769,769,769,769,-383,1127,1141,1111,1126,1140,1095,1110,869,869,883,883,1079,1109,882,882,375,374,807,868,838,881,791,-463,867,822,368,263,852,837,836,-543,610,610,550,550,352,336,534,534,865,774,851,821,850,805,593,533,579,564,773,832,578,578,548,548,577,577,307,276,306,291,516,560,259,259,
- -250,-2107,-2507,-2764,-2909,-2974,-3007,-3023,1041,1041,1040,1040,769,769,769,769,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,-767,-1052,-1213,-1277,-1358,-1405,-1469,-1535,-1550,-1582,-1614,-1647,-1662,-1694,-1726,-1759,-1774,-1807,-1822,-1854,-1886,1565,-1919,-1935,-1951,-1967,1731,1730,1580,1717,-1983,1729,1564,-1999,1548,-2015,-2031,1715,1595,-2047,1714,-2063,1610,-2079,1609,-2095,1323,1323,1457,1457,1307,1307,1712,1547,1641,1700,1699,1594,1685,1625,1442,1442,1322,1322,-780,-973,-910,1279,1278,1277,1262,1276,1261,1275,1215,1260,1229,-959,974,974,989,989,-943,735,478,478,495,463,506,414,-1039,1003,958,1017,927,942,987,957,431,476,1272,1167,1228,-1183,1256,-1199,895,895,941,941,1242,1227,1212,1135,1014,1014,490,489,503,487,910,1013,985,925,863,894,970,955,1012,847,-1343,831,755,755,984,909,428,366,754,559,-1391,752,486,457,924,997,698,698,983,893,740,740,908,877,739,739,667,667,953,938,497,287,271,271,683,606,590,712,726,574,302,302,738,736,481,286,526,725,605,711,636,724,696,651,589,681,666,710,364,467,573,695,466,466,301,465,379,379,709,604,665,679,316,316,634,633,436,436,464,269,424,394,452,332,438,363,347,408,393,448,331,422,362,407,392,421,346,406,391,376,375,359,1441,1306,-2367,1290,-2383,1337,-2399,-2415,1426,1321,-2431,1411,1336,-2447,-2463,-2479,1169,1169,1049,1049,1424,1289,1412,1352,1319,-2495,1154,1154,1064,1064,1153,1153,416,390,360,404,403,389,344,374,373,343,358,372,327,357,342,311,356,326,1395,1394,1137,1137,1047,1047,1365,1392,1287,1379,1334,1364,1349,1378,1318,1363,792,792,792,792,1152,1152,1032,1032,1121,1121,1046,1046,1120,1120,1030,1030,-2895,1106,1061,1104,849,849,789,789,1091,1076,1029,1090,1060,1075,833,833,309,324,532,532,832,772,818,803,561,561,531,560,515,546,289,274,288,258,
- -250,-1179,-1579,-1836,-1996,-2124,-2253,-2333,-2413,-2477,-2542,-2574,-2607,-2622,-2655,1314,1313,1298,1312,1282,785,785,785,785,1040,1040,1025,1025,768,768,768,768,-766,-798,-830,-862,-895,-911,-927,-943,-959,-975,-991,-1007,-1023,-1039,-1055,-1070,1724,1647,-1103,-1119,1631,1767,1662,1738,1708,1723,-1135,1780,1615,1779,1599,1677,1646,1778,1583,-1151,1777,1567,1737,1692,1765,1722,1707,1630,1751,1661,1764,1614,1736,1676,1763,1750,1645,1598,1721,1691,1762,1706,1582,1761,1566,-1167,1749,1629,767,766,751,765,494,494,735,764,719,749,734,763,447,447,748,718,477,506,431,491,446,476,461,505,415,430,475,445,504,399,460,489,414,503,383,474,429,459,502,502,746,752,488,398,501,473,413,472,486,271,480,270,-1439,-1455,1357,-1471,-1487,-1503,1341,1325,-1519,1489,1463,1403,1309,-1535,1372,1448,1418,1476,1356,1462,1387,-1551,1475,1340,1447,1402,1386,-1567,1068,1068,1474,1461,455,380,468,440,395,425,410,454,364,467,466,464,453,269,409,448,268,432,1371,1473,1432,1417,1308,1460,1355,1446,1459,1431,1083,1083,1401,1416,1458,1445,1067,1067,1370,1457,1051,1051,1291,1430,1385,1444,1354,1415,1400,1443,1082,1082,1173,1113,1186,1066,1185,1050,-1967,1158,1128,1172,1097,1171,1081,-1983,1157,1112,416,266,375,400,1170,1142,1127,1065,793,793,1169,1033,1156,1096,1141,1111,1155,1080,1126,1140,898,898,808,808,897,897,792,792,1095,1152,1032,1125,1110,1139,1079,1124,882,807,838,881,853,791,-2319,867,368,263,822,852,837,866,806,865,-2399,851,352,262,534,534,821,836,594,594,549,549,593,593,533,533,848,773,579,579,564,578,548,563,276,276,577,576,306,291,516,560,305,305,275,259,
- -251,-892,-2058,-2620,-2828,-2957,-3023,-3039,1041,1041,1040,1040,769,769,769,769,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,-511,-527,-543,-559,1530,-575,-591,1528,1527,1407,1526,1391,1023,1023,1023,1023,1525,1375,1268,1268,1103,1103,1087,1087,1039,1039,1523,-604,815,815,815,815,510,495,509,479,508,463,507,447,431,505,415,399,-734,-782,1262,-815,1259,1244,-831,1258,1228,-847,-863,1196,-879,1253,987,987,748,-767,493,493,462,477,414,414,686,669,478,446,461,445,474,429,487,458,412,471,1266,1264,1009,1009,799,799,-1019,-1276,-1452,-1581,-1677,-1757,-1821,-1886,-1933,-1997,1257,1257,1483,1468,1512,1422,1497,1406,1467,1496,1421,1510,1134,1134,1225,1225,1466,1451,1374,1405,1252,1252,1358,1480,1164,1164,1251,1251,1238,1238,1389,1465,-1407,1054,1101,-1423,1207,-1439,830,830,1248,1038,1237,1117,1223,1148,1236,1208,411,426,395,410,379,269,1193,1222,1132,1235,1221,1116,976,976,1192,1162,1177,1220,1131,1191,963,963,-1647,961,780,-1663,558,558,994,993,437,408,393,407,829,978,813,797,947,-1743,721,721,377,392,844,950,828,890,706,706,812,859,796,960,948,843,934,874,571,571,-1919,690,555,689,421,346,539,539,944,779,918,873,932,842,903,888,570,570,931,917,674,674,-2575,1562,-2591,1609,-2607,1654,1322,1322,1441,1441,1696,1546,1683,1593,1669,1624,1426,1426,1321,1321,1639,1680,1425,1425,1305,1305,1545,1668,1608,1623,1667,1592,1638,1666,1320,1320,1652,1607,1409,1409,1304,1304,1288,1288,1664,1637,1395,1395,1335,1335,1622,1636,1394,1394,1319,1319,1606,1621,1392,1392,1137,1137,1137,1137,345,390,360,375,404,373,1047,-2751,-2767,-2783,1062,1121,1046,-2799,1077,-2815,1106,1061,789,789,1105,1104,263,355,310,340,325,354,352,262,339,324,1091,1076,1029,1090,1060,1075,833,833,788,788,1088,1028,818,818,803,803,561,561,531,531,816,771,546,546,289,274,288,258,
- -253,-317,-381,-446,-478,-509,1279,1279,-811,-1179,-1451,-1756,-1900,-2028,-2189,-2253,-2333,-2414,-2445,-2511,-2526,1313,1298,-2559,1041,1041,1040,1040,1025,1025,1024,1024,1022,1007,1021,991,1020,975,1019,959,687,687,1018,1017,671,671,655,655,1016,1015,639,639,758,758,623,623,757,607,756,591,755,575,754,559,543,543,1009,783,-575,-621,-685,-749,496,-590,750,749,734,748,974,989,1003,958,988,973,1002,942,987,957,972,1001,926,986,941,971,956,1000,910,985,925,999,894,970,-1071,-1087,-1102,1390,-1135,1436,1509,1451,1374,-1151,1405,1358,1480,1420,-1167,1507,1494,1389,1342,1465,1435,1450,1326,1505,1310,1493,1373,1479,1404,1492,1464,1419,428,443,472,397,736,526,464,464,486,457,442,471,484,482,1357,1449,1434,1478,1388,1491,1341,1490,1325,1489,1463,1403,1309,1477,1372,1448,1418,1433,1476,1356,1462,1387,-1439,1475,1340,1447,1402,1474,1324,1461,1371,1473,269,448,1432,1417,1308,1460,-1711,1459,-1727,1441,1099,1099,1446,1386,1431,1401,-1743,1289,1083,1083,1160,1160,1458,1445,1067,1067,1370,1457,1307,1430,1129,1129,1098,1098,268,432,267,416,266,400,-1887,1144,1187,1082,1173,1113,1186,1066,1050,1158,1128,1143,1172,1097,1171,1081,420,391,1157,1112,1170,1142,1127,1065,1169,1049,1156,1096,1141,1111,1155,1080,1126,1154,1064,1153,1140,1095,1048,-2159,1125,1110,1137,-2175,823,823,1139,1138,807,807,384,264,368,263,868,838,853,791,867,822,852,837,866,806,865,790,-2319,851,821,836,352,262,850,805,849,-2399,533,533,835,820,336,261,578,548,563,577,532,532,832,772,562,562,547,547,305,275,560,515,290,290,288,258 };
- static const drmp3_uint8 tab32[] = { 130,162,193,209,44,28,76,140,9,9,9,9,9,9,9,9,190,254,222,238,126,94,157,157,109,61,173,205};
- static const drmp3_uint8 tab33[] = { 252,236,220,204,188,172,156,140,124,108,92,76,60,44,28,12 };
- static const drmp3_int16 tabindex[2*16] = { 0,32,64,98,0,132,180,218,292,364,426,538,648,746,0,1126,1460,1460,1460,1460,1460,1460,1460,1460,1842,1842,1842,1842,1842,1842,1842,1842 };
- static const drmp3_uint8 g_linbits[] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,2,3,4,6,8,10,13,4,5,6,7,8,9,11,13 };
-
-#define DRMP3_PEEK_BITS(n) (bs_cache >> (32 - (n)))
-#define DRMP3_FLUSH_BITS(n) { bs_cache <<= (n); bs_sh += (n); }
-#define DRMP3_CHECK_BITS while (bs_sh >= 0) { bs_cache |= (drmp3_uint32)*bs_next_ptr++ << bs_sh; bs_sh -= 8; }
-#define DRMP3_BSPOS ((bs_next_ptr - bs->buf)*8 - 24 + bs_sh)
-
- float one = 0.0f;
- int ireg = 0, big_val_cnt = gr_info->big_values;
- const drmp3_uint8 *sfb = gr_info->sfbtab;
- const drmp3_uint8 *bs_next_ptr = bs->buf + bs->pos/8;
- drmp3_uint32 bs_cache = (((bs_next_ptr[0]*256u + bs_next_ptr[1])*256u + bs_next_ptr[2])*256u + bs_next_ptr[3]) << (bs->pos & 7);
- int pairs_to_decode, np, bs_sh = (bs->pos & 7) - 8;
- bs_next_ptr += 4;
-
- while (big_val_cnt > 0)
- {
- int tab_num = gr_info->table_select[ireg];
- int sfb_cnt = gr_info->region_count[ireg++];
- const drmp3_int16 *codebook = tabs + tabindex[tab_num];
- int linbits = g_linbits[tab_num];
- if (linbits)
- {
- do
- {
- np = *sfb++ / 2;
- pairs_to_decode = DRMP3_MIN(big_val_cnt, np);
- one = *scf++;
- do
- {
- int j, w = 5;
- int leaf = codebook[DRMP3_PEEK_BITS(w)];
- while (leaf < 0)
- {
- DRMP3_FLUSH_BITS(w);
- w = leaf & 7;
- leaf = codebook[DRMP3_PEEK_BITS(w) - (leaf >> 3)];
- }
- DRMP3_FLUSH_BITS(leaf >> 8);
-
- for (j = 0; j < 2; j++, dst++, leaf >>= 4)
- {
- int lsb = leaf & 0x0F;
- if (lsb == 15)
- {
- lsb += DRMP3_PEEK_BITS(linbits);
- DRMP3_FLUSH_BITS(linbits);
- DRMP3_CHECK_BITS;
- *dst = one*drmp3_L3_pow_43(lsb)*((drmp3_int32)bs_cache < 0 ? -1: 1);
- } else
- {
- *dst = g_drmp3_pow43[16 + lsb - 16*(bs_cache >> 31)]*one;
- }
- DRMP3_FLUSH_BITS(lsb ? 1 : 0);
- }
- DRMP3_CHECK_BITS;
- } while (--pairs_to_decode);
- } while ((big_val_cnt -= np) > 0 && --sfb_cnt >= 0);
- } else
- {
- do
- {
- np = *sfb++ / 2;
- pairs_to_decode = DRMP3_MIN(big_val_cnt, np);
- one = *scf++;
- do
- {
- int j, w = 5;
- int leaf = codebook[DRMP3_PEEK_BITS(w)];
- while (leaf < 0)
- {
- DRMP3_FLUSH_BITS(w);
- w = leaf & 7;
- leaf = codebook[DRMP3_PEEK_BITS(w) - (leaf >> 3)];
- }
- DRMP3_FLUSH_BITS(leaf >> 8);
-
- for (j = 0; j < 2; j++, dst++, leaf >>= 4)
- {
- int lsb = leaf & 0x0F;
- *dst = g_drmp3_pow43[16 + lsb - 16*(bs_cache >> 31)]*one;
- DRMP3_FLUSH_BITS(lsb ? 1 : 0);
- }
- DRMP3_CHECK_BITS;
- } while (--pairs_to_decode);
- } while ((big_val_cnt -= np) > 0 && --sfb_cnt >= 0);
- }
- }
-
- for (np = 1 - big_val_cnt;; dst += 4)
- {
- const drmp3_uint8 *codebook_count1 = (gr_info->count1_table) ? tab33 : tab32;
- int leaf = codebook_count1[DRMP3_PEEK_BITS(4)];
- if (!(leaf & 8))
- {
- leaf = codebook_count1[(leaf >> 3) + (bs_cache << 4 >> (32 - (leaf & 3)))];
- }
- DRMP3_FLUSH_BITS(leaf & 7);
- if (DRMP3_BSPOS > layer3gr_limit)
- {
- break;
- }
-#define DRMP3_RELOAD_SCALEFACTOR if (!--np) { np = *sfb++/2; if (!np) break; one = *scf++; }
-#define DRMP3_DEQ_COUNT1(s) if (leaf & (128 >> s)) { dst[s] = ((drmp3_int32)bs_cache < 0) ? -one : one; DRMP3_FLUSH_BITS(1) }
- DRMP3_RELOAD_SCALEFACTOR;
- DRMP3_DEQ_COUNT1(0);
- DRMP3_DEQ_COUNT1(1);
- DRMP3_RELOAD_SCALEFACTOR;
- DRMP3_DEQ_COUNT1(2);
- DRMP3_DEQ_COUNT1(3);
- DRMP3_CHECK_BITS;
- }
-
- bs->pos = layer3gr_limit;
-}
-
-static void drmp3_L3_midside_stereo(float *left, int n)
-{
- int i = 0;
- float *right = left + 576;
-#if DRMP3_HAVE_SIMD
- if (drmp3_have_simd())
- {
- for (; i < n - 3; i += 4)
- {
- drmp3_f4 vl = DRMP3_VLD(left + i);
- drmp3_f4 vr = DRMP3_VLD(right + i);
- DRMP3_VSTORE(left + i, DRMP3_VADD(vl, vr));
- DRMP3_VSTORE(right + i, DRMP3_VSUB(vl, vr));
- }
-#ifdef __GNUC__
- /* Workaround for spurious -Waggressive-loop-optimizations warning from gcc.
- * For more info see: https://github.com/lieff/minimp3/issues/88
- */
- if (__builtin_constant_p(n % 4 == 0) && n % 4 == 0)
- return;
-#endif
- }
-#endif
- for (; i < n; i++)
- {
- float a = left[i];
- float b = right[i];
- left[i] = a + b;
- right[i] = a - b;
- }
-}
-
-static void drmp3_L3_intensity_stereo_band(float *left, int n, float kl, float kr)
-{
- int i;
- for (i = 0; i < n; i++)
- {
- left[i + 576] = left[i]*kr;
- left[i] = left[i]*kl;
- }
-}
-
-static void drmp3_L3_stereo_top_band(const float *right, const drmp3_uint8 *sfb, int nbands, int max_band[3])
-{
- int i, k;
-
- max_band[0] = max_band[1] = max_band[2] = -1;
-
- for (i = 0; i < nbands; i++)
- {
- for (k = 0; k < sfb[i]; k += 2)
- {
- if (right[k] != 0 || right[k + 1] != 0)
- {
- max_band[i % 3] = i;
- break;
- }
- }
- right += sfb[i];
- }
-}
-
-static void drmp3_L3_stereo_process(float *left, const drmp3_uint8 *ist_pos, const drmp3_uint8 *sfb, const drmp3_uint8 *hdr, int max_band[3], int mpeg2_sh)
-{
- static const float g_pan[7*2] = { 0,1,0.21132487f,0.78867513f,0.36602540f,0.63397460f,0.5f,0.5f,0.63397460f,0.36602540f,0.78867513f,0.21132487f,1,0 };
- unsigned i, max_pos = DRMP3_HDR_TEST_MPEG1(hdr) ? 7 : 64;
-
- for (i = 0; sfb[i]; i++)
- {
- unsigned ipos = ist_pos[i];
- if ((int)i > max_band[i % 3] && ipos < max_pos)
- {
- float kl, kr, s = DRMP3_HDR_TEST_MS_STEREO(hdr) ? 1.41421356f : 1;
- if (DRMP3_HDR_TEST_MPEG1(hdr))
- {
- kl = g_pan[2*ipos];
- kr = g_pan[2*ipos + 1];
- } else
- {
- kl = 1;
- kr = drmp3_L3_ldexp_q2(1, (ipos + 1) >> 1 << mpeg2_sh);
- if (ipos & 1)
- {
- kl = kr;
- kr = 1;
- }
- }
- drmp3_L3_intensity_stereo_band(left, sfb[i], kl*s, kr*s);
- } else if (DRMP3_HDR_TEST_MS_STEREO(hdr))
- {
- drmp3_L3_midside_stereo(left, sfb[i]);
- }
- left += sfb[i];
- }
-}
-
-static void drmp3_L3_intensity_stereo(float *left, drmp3_uint8 *ist_pos, const drmp3_L3_gr_info *gr, const drmp3_uint8 *hdr)
-{
- int max_band[3], n_sfb = gr->n_long_sfb + gr->n_short_sfb;
- int i, max_blocks = gr->n_short_sfb ? 3 : 1;
-
- drmp3_L3_stereo_top_band(left + 576, gr->sfbtab, n_sfb, max_band);
- if (gr->n_long_sfb)
- {
- max_band[0] = max_band[1] = max_band[2] = DRMP3_MAX(DRMP3_MAX(max_band[0], max_band[1]), max_band[2]);
- }
- for (i = 0; i < max_blocks; i++)
- {
- int default_pos = DRMP3_HDR_TEST_MPEG1(hdr) ? 3 : 0;
- int itop = n_sfb - max_blocks + i;
- int prev = itop - max_blocks;
- ist_pos[itop] = (drmp3_uint8)(max_band[i] >= prev ? default_pos : ist_pos[prev]);
- }
- drmp3_L3_stereo_process(left, ist_pos, gr->sfbtab, hdr, max_band, gr[1].scalefac_compress & 1);
-}
-
-static void drmp3_L3_reorder(float *grbuf, float *scratch, const drmp3_uint8 *sfb)
-{
- int i, len;
- float *src = grbuf, *dst = scratch;
-
- for (;0 != (len = *sfb); sfb += 3, src += 2*len)
- {
- for (i = 0; i < len; i++, src++)
- {
- *dst++ = src[0*len];
- *dst++ = src[1*len];
- *dst++ = src[2*len];
- }
- }
- DRMP3_COPY_MEMORY(grbuf, scratch, (dst - scratch)*sizeof(float));
-}
-
-static void drmp3_L3_antialias(float *grbuf, int nbands)
-{
- static const float g_aa[2][8] = {
- {0.85749293f,0.88174200f,0.94962865f,0.98331459f,0.99551782f,0.99916056f,0.99989920f,0.99999316f},
- {0.51449576f,0.47173197f,0.31337745f,0.18191320f,0.09457419f,0.04096558f,0.01419856f,0.00369997f}
- };
-
- for (; nbands > 0; nbands--, grbuf += 18)
- {
- int i = 0;
-#if DRMP3_HAVE_SIMD
- if (drmp3_have_simd()) for (; i < 8; i += 4)
- {
- drmp3_f4 vu = DRMP3_VLD(grbuf + 18 + i);
- drmp3_f4 vd = DRMP3_VLD(grbuf + 14 - i);
- drmp3_f4 vc0 = DRMP3_VLD(g_aa[0] + i);
- drmp3_f4 vc1 = DRMP3_VLD(g_aa[1] + i);
- vd = DRMP3_VREV(vd);
- DRMP3_VSTORE(grbuf + 18 + i, DRMP3_VSUB(DRMP3_VMUL(vu, vc0), DRMP3_VMUL(vd, vc1)));
- vd = DRMP3_VADD(DRMP3_VMUL(vu, vc1), DRMP3_VMUL(vd, vc0));
- DRMP3_VSTORE(grbuf + 14 - i, DRMP3_VREV(vd));
- }
-#endif
-#ifndef DR_MP3_ONLY_SIMD
- for(; i < 8; i++)
- {
- float u = grbuf[18 + i];
- float d = grbuf[17 - i];
- grbuf[18 + i] = u*g_aa[0][i] - d*g_aa[1][i];
- grbuf[17 - i] = u*g_aa[1][i] + d*g_aa[0][i];
- }
-#endif
- }
-}
-
-static void drmp3_L3_dct3_9(float *y)
-{
- float s0, s1, s2, s3, s4, s5, s6, s7, s8, t0, t2, t4;
-
- s0 = y[0]; s2 = y[2]; s4 = y[4]; s6 = y[6]; s8 = y[8];
- t0 = s0 + s6*0.5f;
- s0 -= s6;
- t4 = (s4 + s2)*0.93969262f;
- t2 = (s8 + s2)*0.76604444f;
- s6 = (s4 - s8)*0.17364818f;
- s4 += s8 - s2;
-
- s2 = s0 - s4*0.5f;
- y[4] = s4 + s0;
- s8 = t0 - t2 + s6;
- s0 = t0 - t4 + t2;
- s4 = t0 + t4 - s6;
-
- s1 = y[1]; s3 = y[3]; s5 = y[5]; s7 = y[7];
-
- s3 *= 0.86602540f;
- t0 = (s5 + s1)*0.98480775f;
- t4 = (s5 - s7)*0.34202014f;
- t2 = (s1 + s7)*0.64278761f;
- s1 = (s1 - s5 - s7)*0.86602540f;
-
- s5 = t0 - s3 - t2;
- s7 = t4 - s3 - t0;
- s3 = t4 + s3 - t2;
-
- y[0] = s4 - s7;
- y[1] = s2 + s1;
- y[2] = s0 - s3;
- y[3] = s8 + s5;
- y[5] = s8 - s5;
- y[6] = s0 + s3;
- y[7] = s2 - s1;
- y[8] = s4 + s7;
-}
-
-static void drmp3_L3_imdct36(float *grbuf, float *overlap, const float *window, int nbands)
-{
- int i, j;
- static const float g_twid9[18] = {
- 0.73727734f,0.79335334f,0.84339145f,0.88701083f,0.92387953f,0.95371695f,0.97629601f,0.99144486f,0.99904822f,0.67559021f,0.60876143f,0.53729961f,0.46174861f,0.38268343f,0.30070580f,0.21643961f,0.13052619f,0.04361938f
- };
-
- for (j = 0; j < nbands; j++, grbuf += 18, overlap += 9)
- {
- float co[9], si[9];
- co[0] = -grbuf[0];
- si[0] = grbuf[17];
- for (i = 0; i < 4; i++)
- {
- si[8 - 2*i] = grbuf[4*i + 1] - grbuf[4*i + 2];
- co[1 + 2*i] = grbuf[4*i + 1] + grbuf[4*i + 2];
- si[7 - 2*i] = grbuf[4*i + 4] - grbuf[4*i + 3];
- co[2 + 2*i] = -(grbuf[4*i + 3] + grbuf[4*i + 4]);
- }
- drmp3_L3_dct3_9(co);
- drmp3_L3_dct3_9(si);
-
- si[1] = -si[1];
- si[3] = -si[3];
- si[5] = -si[5];
- si[7] = -si[7];
-
- i = 0;
-
-#if DRMP3_HAVE_SIMD
- if (drmp3_have_simd()) for (; i < 8; i += 4)
- {
- drmp3_f4 vovl = DRMP3_VLD(overlap + i);
- drmp3_f4 vc = DRMP3_VLD(co + i);
- drmp3_f4 vs = DRMP3_VLD(si + i);
- drmp3_f4 vr0 = DRMP3_VLD(g_twid9 + i);
- drmp3_f4 vr1 = DRMP3_VLD(g_twid9 + 9 + i);
- drmp3_f4 vw0 = DRMP3_VLD(window + i);
- drmp3_f4 vw1 = DRMP3_VLD(window + 9 + i);
- drmp3_f4 vsum = DRMP3_VADD(DRMP3_VMUL(vc, vr1), DRMP3_VMUL(vs, vr0));
- DRMP3_VSTORE(overlap + i, DRMP3_VSUB(DRMP3_VMUL(vc, vr0), DRMP3_VMUL(vs, vr1)));
- DRMP3_VSTORE(grbuf + i, DRMP3_VSUB(DRMP3_VMUL(vovl, vw0), DRMP3_VMUL(vsum, vw1)));
- vsum = DRMP3_VADD(DRMP3_VMUL(vovl, vw1), DRMP3_VMUL(vsum, vw0));
- DRMP3_VSTORE(grbuf + 14 - i, DRMP3_VREV(vsum));
- }
-#endif
- for (; i < 9; i++)
- {
- float ovl = overlap[i];
- float sum = co[i]*g_twid9[9 + i] + si[i]*g_twid9[0 + i];
- overlap[i] = co[i]*g_twid9[0 + i] - si[i]*g_twid9[9 + i];
- grbuf[i] = ovl*window[0 + i] - sum*window[9 + i];
- grbuf[17 - i] = ovl*window[9 + i] + sum*window[0 + i];
- }
- }
-}
-
-static void drmp3_L3_idct3(float x0, float x1, float x2, float *dst)
-{
- float m1 = x1*0.86602540f;
- float a1 = x0 - x2*0.5f;
- dst[1] = x0 + x2;
- dst[0] = a1 + m1;
- dst[2] = a1 - m1;
-}
-
-static void drmp3_L3_imdct12(float *x, float *dst, float *overlap)
-{
- static const float g_twid3[6] = { 0.79335334f,0.92387953f,0.99144486f, 0.60876143f,0.38268343f,0.13052619f };
- float co[3], si[3];
- int i;
-
- drmp3_L3_idct3(-x[0], x[6] + x[3], x[12] + x[9], co);
- drmp3_L3_idct3(x[15], x[12] - x[9], x[6] - x[3], si);
- si[1] = -si[1];
-
- for (i = 0; i < 3; i++)
- {
- float ovl = overlap[i];
- float sum = co[i]*g_twid3[3 + i] + si[i]*g_twid3[0 + i];
- overlap[i] = co[i]*g_twid3[0 + i] - si[i]*g_twid3[3 + i];
- dst[i] = ovl*g_twid3[2 - i] - sum*g_twid3[5 - i];
- dst[5 - i] = ovl*g_twid3[5 - i] + sum*g_twid3[2 - i];
- }
-}
-
-static void drmp3_L3_imdct_short(float *grbuf, float *overlap, int nbands)
-{
- for (;nbands > 0; nbands--, overlap += 9, grbuf += 18)
- {
- float tmp[18];
- DRMP3_COPY_MEMORY(tmp, grbuf, sizeof(tmp));
- DRMP3_COPY_MEMORY(grbuf, overlap, 6*sizeof(float));
- drmp3_L3_imdct12(tmp, grbuf + 6, overlap + 6);
- drmp3_L3_imdct12(tmp + 1, grbuf + 12, overlap + 6);
- drmp3_L3_imdct12(tmp + 2, overlap, overlap + 6);
- }
-}
-
-static void drmp3_L3_change_sign(float *grbuf)
-{
- int b, i;
- for (b = 0, grbuf += 18; b < 32; b += 2, grbuf += 36)
- for (i = 1; i < 18; i += 2)
- grbuf[i] = -grbuf[i];
-}
-
-static void drmp3_L3_imdct_gr(float *grbuf, float *overlap, unsigned block_type, unsigned n_long_bands)
-{
- static const float g_mdct_window[2][18] = {
- { 0.99904822f,0.99144486f,0.97629601f,0.95371695f,0.92387953f,0.88701083f,0.84339145f,0.79335334f,0.73727734f,0.04361938f,0.13052619f,0.21643961f,0.30070580f,0.38268343f,0.46174861f,0.53729961f,0.60876143f,0.67559021f },
- { 1,1,1,1,1,1,0.99144486f,0.92387953f,0.79335334f,0,0,0,0,0,0,0.13052619f,0.38268343f,0.60876143f }
- };
- if (n_long_bands)
- {
- drmp3_L3_imdct36(grbuf, overlap, g_mdct_window[0], n_long_bands);
- grbuf += 18*n_long_bands;
- overlap += 9*n_long_bands;
- }
- if (block_type == DRMP3_SHORT_BLOCK_TYPE)
- drmp3_L3_imdct_short(grbuf, overlap, 32 - n_long_bands);
- else
- drmp3_L3_imdct36(grbuf, overlap, g_mdct_window[block_type == DRMP3_STOP_BLOCK_TYPE], 32 - n_long_bands);
-}
-
-static void drmp3_L3_save_reservoir(drmp3dec *h, drmp3dec_scratch *s)
-{
- int pos = (s->bs.pos + 7)/8u;
- int remains = s->bs.limit/8u - pos;
- if (remains > DRMP3_MAX_BITRESERVOIR_BYTES)
- {
- pos += remains - DRMP3_MAX_BITRESERVOIR_BYTES;
- remains = DRMP3_MAX_BITRESERVOIR_BYTES;
- }
- if (remains > 0)
- {
- DRMP3_MOVE_MEMORY(h->reserv_buf, s->maindata + pos, remains);
- }
- h->reserv = remains;
-}
-
-static int drmp3_L3_restore_reservoir(drmp3dec *h, drmp3_bs *bs, drmp3dec_scratch *s, int main_data_begin)
-{
- int frame_bytes = (bs->limit - bs->pos)/8;
- int bytes_have = DRMP3_MIN(h->reserv, main_data_begin);
- DRMP3_COPY_MEMORY(s->maindata, h->reserv_buf + DRMP3_MAX(0, h->reserv - main_data_begin), DRMP3_MIN(h->reserv, main_data_begin));
- DRMP3_COPY_MEMORY(s->maindata + bytes_have, bs->buf + bs->pos/8, frame_bytes);
- drmp3_bs_init(&s->bs, s->maindata, bytes_have + frame_bytes);
- return h->reserv >= main_data_begin;
-}
-
-static void drmp3_L3_decode(drmp3dec *h, drmp3dec_scratch *s, drmp3_L3_gr_info *gr_info, int nch)
-{
- int ch;
-
- for (ch = 0; ch < nch; ch++)
- {
- int layer3gr_limit = s->bs.pos + gr_info[ch].part_23_length;
- drmp3_L3_decode_scalefactors(h->header, s->ist_pos[ch], &s->bs, gr_info + ch, s->scf, ch);
- drmp3_L3_huffman(s->grbuf[ch], &s->bs, gr_info + ch, s->scf, layer3gr_limit);
- }
-
- if (DRMP3_HDR_TEST_I_STEREO(h->header))
- {
- drmp3_L3_intensity_stereo(s->grbuf[0], s->ist_pos[1], gr_info, h->header);
- } else if (DRMP3_HDR_IS_MS_STEREO(h->header))
- {
- drmp3_L3_midside_stereo(s->grbuf[0], 576);
- }
-
- for (ch = 0; ch < nch; ch++, gr_info++)
- {
- int aa_bands = 31;
- int n_long_bands = (gr_info->mixed_block_flag ? 2 : 0) << (int)(DRMP3_HDR_GET_MY_SAMPLE_RATE(h->header) == 2);
-
- if (gr_info->n_short_sfb)
- {
- aa_bands = n_long_bands - 1;
- drmp3_L3_reorder(s->grbuf[ch] + n_long_bands*18, s->syn[0], gr_info->sfbtab + gr_info->n_long_sfb);
- }
-
- drmp3_L3_antialias(s->grbuf[ch], aa_bands);
- drmp3_L3_imdct_gr(s->grbuf[ch], h->mdct_overlap[ch], gr_info->block_type, n_long_bands);
- drmp3_L3_change_sign(s->grbuf[ch]);
- }
-}
-
-static void drmp3d_DCT_II(float *grbuf, int n)
-{
- static const float g_sec[24] = {
- 10.19000816f,0.50060302f,0.50241929f,3.40760851f,0.50547093f,0.52249861f,2.05778098f,0.51544732f,0.56694406f,1.48416460f,0.53104258f,0.64682180f,1.16943991f,0.55310392f,0.78815460f,0.97256821f,0.58293498f,1.06067765f,0.83934963f,0.62250412f,1.72244716f,0.74453628f,0.67480832f,5.10114861f
- };
- int i, k = 0;
-#if DRMP3_HAVE_SIMD
- if (drmp3_have_simd()) for (; k < n; k += 4)
- {
- drmp3_f4 t[4][8], *x;
- float *y = grbuf + k;
-
- for (x = t[0], i = 0; i < 8; i++, x++)
- {
- drmp3_f4 x0 = DRMP3_VLD(&y[i*18]);
- drmp3_f4 x1 = DRMP3_VLD(&y[(15 - i)*18]);
- drmp3_f4 x2 = DRMP3_VLD(&y[(16 + i)*18]);
- drmp3_f4 x3 = DRMP3_VLD(&y[(31 - i)*18]);
- drmp3_f4 t0 = DRMP3_VADD(x0, x3);
- drmp3_f4 t1 = DRMP3_VADD(x1, x2);
- drmp3_f4 t2 = DRMP3_VMUL_S(DRMP3_VSUB(x1, x2), g_sec[3*i + 0]);
- drmp3_f4 t3 = DRMP3_VMUL_S(DRMP3_VSUB(x0, x3), g_sec[3*i + 1]);
- x[0] = DRMP3_VADD(t0, t1);
- x[8] = DRMP3_VMUL_S(DRMP3_VSUB(t0, t1), g_sec[3*i + 2]);
- x[16] = DRMP3_VADD(t3, t2);
- x[24] = DRMP3_VMUL_S(DRMP3_VSUB(t3, t2), g_sec[3*i + 2]);
- }
- for (x = t[0], i = 0; i < 4; i++, x += 8)
- {
- drmp3_f4 x0 = x[0], x1 = x[1], x2 = x[2], x3 = x[3], x4 = x[4], x5 = x[5], x6 = x[6], x7 = x[7], xt;
- xt = DRMP3_VSUB(x0, x7); x0 = DRMP3_VADD(x0, x7);
- x7 = DRMP3_VSUB(x1, x6); x1 = DRMP3_VADD(x1, x6);
- x6 = DRMP3_VSUB(x2, x5); x2 = DRMP3_VADD(x2, x5);
- x5 = DRMP3_VSUB(x3, x4); x3 = DRMP3_VADD(x3, x4);
- x4 = DRMP3_VSUB(x0, x3); x0 = DRMP3_VADD(x0, x3);
- x3 = DRMP3_VSUB(x1, x2); x1 = DRMP3_VADD(x1, x2);
- x[0] = DRMP3_VADD(x0, x1);
- x[4] = DRMP3_VMUL_S(DRMP3_VSUB(x0, x1), 0.70710677f);
- x5 = DRMP3_VADD(x5, x6);
- x6 = DRMP3_VMUL_S(DRMP3_VADD(x6, x7), 0.70710677f);
- x7 = DRMP3_VADD(x7, xt);
- x3 = DRMP3_VMUL_S(DRMP3_VADD(x3, x4), 0.70710677f);
- x5 = DRMP3_VSUB(x5, DRMP3_VMUL_S(x7, 0.198912367f)); /* rotate by PI/8 */
- x7 = DRMP3_VADD(x7, DRMP3_VMUL_S(x5, 0.382683432f));
- x5 = DRMP3_VSUB(x5, DRMP3_VMUL_S(x7, 0.198912367f));
- x0 = DRMP3_VSUB(xt, x6); xt = DRMP3_VADD(xt, x6);
- x[1] = DRMP3_VMUL_S(DRMP3_VADD(xt, x7), 0.50979561f);
- x[2] = DRMP3_VMUL_S(DRMP3_VADD(x4, x3), 0.54119611f);
- x[3] = DRMP3_VMUL_S(DRMP3_VSUB(x0, x5), 0.60134488f);
- x[5] = DRMP3_VMUL_S(DRMP3_VADD(x0, x5), 0.89997619f);
- x[6] = DRMP3_VMUL_S(DRMP3_VSUB(x4, x3), 1.30656302f);
- x[7] = DRMP3_VMUL_S(DRMP3_VSUB(xt, x7), 2.56291556f);
- }
-
- if (k > n - 3)
- {
-#if DRMP3_HAVE_SSE
-#define DRMP3_VSAVE2(i, v) _mm_storel_pi((__m64 *)(void*)&y[i*18], v)
-#else
-#define DRMP3_VSAVE2(i, v) vst1_f32((float32_t *)&y[(i)*18], vget_low_f32(v))
-#endif
- for (i = 0; i < 7; i++, y += 4*18)
- {
- drmp3_f4 s = DRMP3_VADD(t[3][i], t[3][i + 1]);
- DRMP3_VSAVE2(0, t[0][i]);
- DRMP3_VSAVE2(1, DRMP3_VADD(t[2][i], s));
- DRMP3_VSAVE2(2, DRMP3_VADD(t[1][i], t[1][i + 1]));
- DRMP3_VSAVE2(3, DRMP3_VADD(t[2][1 + i], s));
- }
- DRMP3_VSAVE2(0, t[0][7]);
- DRMP3_VSAVE2(1, DRMP3_VADD(t[2][7], t[3][7]));
- DRMP3_VSAVE2(2, t[1][7]);
- DRMP3_VSAVE2(3, t[3][7]);
- } else
- {
-#define DRMP3_VSAVE4(i, v) DRMP3_VSTORE(&y[(i)*18], v)
- for (i = 0; i < 7; i++, y += 4*18)
- {
- drmp3_f4 s = DRMP3_VADD(t[3][i], t[3][i + 1]);
- DRMP3_VSAVE4(0, t[0][i]);
- DRMP3_VSAVE4(1, DRMP3_VADD(t[2][i], s));
- DRMP3_VSAVE4(2, DRMP3_VADD(t[1][i], t[1][i + 1]));
- DRMP3_VSAVE4(3, DRMP3_VADD(t[2][1 + i], s));
- }
- DRMP3_VSAVE4(0, t[0][7]);
- DRMP3_VSAVE4(1, DRMP3_VADD(t[2][7], t[3][7]));
- DRMP3_VSAVE4(2, t[1][7]);
- DRMP3_VSAVE4(3, t[3][7]);
- }
- } else
-#endif
-#ifdef DR_MP3_ONLY_SIMD
- {} /* for HAVE_SIMD=1, MINIMP3_ONLY_SIMD=1 case we do not need non-intrinsic "else" branch */
-#else
- for (; k < n; k++)
- {
- float t[4][8], *x, *y = grbuf + k;
-
- for (x = t[0], i = 0; i < 8; i++, x++)
- {
- float x0 = y[i*18];
- float x1 = y[(15 - i)*18];
- float x2 = y[(16 + i)*18];
- float x3 = y[(31 - i)*18];
- float t0 = x0 + x3;
- float t1 = x1 + x2;
- float t2 = (x1 - x2)*g_sec[3*i + 0];
- float t3 = (x0 - x3)*g_sec[3*i + 1];
- x[0] = t0 + t1;
- x[8] = (t0 - t1)*g_sec[3*i + 2];
- x[16] = t3 + t2;
- x[24] = (t3 - t2)*g_sec[3*i + 2];
- }
- for (x = t[0], i = 0; i < 4; i++, x += 8)
- {
- float x0 = x[0], x1 = x[1], x2 = x[2], x3 = x[3], x4 = x[4], x5 = x[5], x6 = x[6], x7 = x[7], xt;
- xt = x0 - x7; x0 += x7;
- x7 = x1 - x6; x1 += x6;
- x6 = x2 - x5; x2 += x5;
- x5 = x3 - x4; x3 += x4;
- x4 = x0 - x3; x0 += x3;
- x3 = x1 - x2; x1 += x2;
- x[0] = x0 + x1;
- x[4] = (x0 - x1)*0.70710677f;
- x5 = x5 + x6;
- x6 = (x6 + x7)*0.70710677f;
- x7 = x7 + xt;
- x3 = (x3 + x4)*0.70710677f;
- x5 -= x7*0.198912367f; /* rotate by PI/8 */
- x7 += x5*0.382683432f;
- x5 -= x7*0.198912367f;
- x0 = xt - x6; xt += x6;
- x[1] = (xt + x7)*0.50979561f;
- x[2] = (x4 + x3)*0.54119611f;
- x[3] = (x0 - x5)*0.60134488f;
- x[5] = (x0 + x5)*0.89997619f;
- x[6] = (x4 - x3)*1.30656302f;
- x[7] = (xt - x7)*2.56291556f;
-
- }
- for (i = 0; i < 7; i++, y += 4*18)
- {
- y[0*18] = t[0][i];
- y[1*18] = t[2][i] + t[3][i] + t[3][i + 1];
- y[2*18] = t[1][i] + t[1][i + 1];
- y[3*18] = t[2][i + 1] + t[3][i] + t[3][i + 1];
- }
- y[0*18] = t[0][7];
- y[1*18] = t[2][7] + t[3][7];
- y[2*18] = t[1][7];
- y[3*18] = t[3][7];
- }
-#endif
-}
-
-#ifndef DR_MP3_FLOAT_OUTPUT
-typedef drmp3_int16 drmp3d_sample_t;
-
-static drmp3_int16 drmp3d_scale_pcm(float sample)
-{
- drmp3_int16 s;
-#if DRMP3_HAVE_ARMV6
- drmp3_int32 s32 = (drmp3_int32)(sample + .5f);
- s32 -= (s32 < 0);
- s = (drmp3_int16)drmp3_clip_int16_arm(s32);
-#else
- if (sample >= 32766.5) return (drmp3_int16) 32767;
- if (sample <= -32767.5) return (drmp3_int16)-32768;
- s = (drmp3_int16)(sample + .5f);
- s -= (s < 0); /* away from zero, to be compliant */
-#endif
- return s;
-}
-#else
-typedef float drmp3d_sample_t;
-
-static float drmp3d_scale_pcm(float sample)
-{
- return sample*(1.f/32768.f);
-}
-#endif
-
-static void drmp3d_synth_pair(drmp3d_sample_t *pcm, int nch, const float *z)
-{
- float a;
- a = (z[14*64] - z[ 0]) * 29;
- a += (z[ 1*64] + z[13*64]) * 213;
- a += (z[12*64] - z[ 2*64]) * 459;
- a += (z[ 3*64] + z[11*64]) * 2037;
- a += (z[10*64] - z[ 4*64]) * 5153;
- a += (z[ 5*64] + z[ 9*64]) * 6574;
- a += (z[ 8*64] - z[ 6*64]) * 37489;
- a += z[ 7*64] * 75038;
- pcm[0] = drmp3d_scale_pcm(a);
-
- z += 2;
- a = z[14*64] * 104;
- a += z[12*64] * 1567;
- a += z[10*64] * 9727;
- a += z[ 8*64] * 64019;
- a += z[ 6*64] * -9975;
- a += z[ 4*64] * -45;
- a += z[ 2*64] * 146;
- a += z[ 0*64] * -5;
- pcm[16*nch] = drmp3d_scale_pcm(a);
-}
-
-static void drmp3d_synth(float *xl, drmp3d_sample_t *dstl, int nch, float *lins)
-{
- int i;
- float *xr = xl + 576*(nch - 1);
- drmp3d_sample_t *dstr = dstl + (nch - 1);
-
- static const float g_win[] = {
- -1,26,-31,208,218,401,-519,2063,2000,4788,-5517,7134,5959,35640,-39336,74992,
- -1,24,-35,202,222,347,-581,2080,1952,4425,-5879,7640,5288,33791,-41176,74856,
- -1,21,-38,196,225,294,-645,2087,1893,4063,-6237,8092,4561,31947,-43006,74630,
- -1,19,-41,190,227,244,-711,2085,1822,3705,-6589,8492,3776,30112,-44821,74313,
- -1,17,-45,183,228,197,-779,2075,1739,3351,-6935,8840,2935,28289,-46617,73908,
- -1,16,-49,176,228,153,-848,2057,1644,3004,-7271,9139,2037,26482,-48390,73415,
- -2,14,-53,169,227,111,-919,2032,1535,2663,-7597,9389,1082,24694,-50137,72835,
- -2,13,-58,161,224,72,-991,2001,1414,2330,-7910,9592,70,22929,-51853,72169,
- -2,11,-63,154,221,36,-1064,1962,1280,2006,-8209,9750,-998,21189,-53534,71420,
- -2,10,-68,147,215,2,-1137,1919,1131,1692,-8491,9863,-2122,19478,-55178,70590,
- -3,9,-73,139,208,-29,-1210,1870,970,1388,-8755,9935,-3300,17799,-56778,69679,
- -3,8,-79,132,200,-57,-1283,1817,794,1095,-8998,9966,-4533,16155,-58333,68692,
- -4,7,-85,125,189,-83,-1356,1759,605,814,-9219,9959,-5818,14548,-59838,67629,
- -4,7,-91,117,177,-106,-1428,1698,402,545,-9416,9916,-7154,12980,-61289,66494,
- -5,6,-97,111,163,-127,-1498,1634,185,288,-9585,9838,-8540,11455,-62684,65290
- };
- float *zlin = lins + 15*64;
- const float *w = g_win;
-
- zlin[4*15] = xl[18*16];
- zlin[4*15 + 1] = xr[18*16];
- zlin[4*15 + 2] = xl[0];
- zlin[4*15 + 3] = xr[0];
-
- zlin[4*31] = xl[1 + 18*16];
- zlin[4*31 + 1] = xr[1 + 18*16];
- zlin[4*31 + 2] = xl[1];
- zlin[4*31 + 3] = xr[1];
-
- drmp3d_synth_pair(dstr, nch, lins + 4*15 + 1);
- drmp3d_synth_pair(dstr + 32*nch, nch, lins + 4*15 + 64 + 1);
- drmp3d_synth_pair(dstl, nch, lins + 4*15);
- drmp3d_synth_pair(dstl + 32*nch, nch, lins + 4*15 + 64);
-
-#if DRMP3_HAVE_SIMD
- if (drmp3_have_simd()) for (i = 14; i >= 0; i--)
- {
-#define DRMP3_VLOAD(k) drmp3_f4 w0 = DRMP3_VSET(*w++); drmp3_f4 w1 = DRMP3_VSET(*w++); drmp3_f4 vz = DRMP3_VLD(&zlin[4*i - 64*k]); drmp3_f4 vy = DRMP3_VLD(&zlin[4*i - 64*(15 - k)]);
-#define DRMP3_V0(k) { DRMP3_VLOAD(k) b = DRMP3_VADD(DRMP3_VMUL(vz, w1), DRMP3_VMUL(vy, w0)) ; a = DRMP3_VSUB(DRMP3_VMUL(vz, w0), DRMP3_VMUL(vy, w1)); }
-#define DRMP3_V1(k) { DRMP3_VLOAD(k) b = DRMP3_VADD(b, DRMP3_VADD(DRMP3_VMUL(vz, w1), DRMP3_VMUL(vy, w0))); a = DRMP3_VADD(a, DRMP3_VSUB(DRMP3_VMUL(vz, w0), DRMP3_VMUL(vy, w1))); }
-#define DRMP3_V2(k) { DRMP3_VLOAD(k) b = DRMP3_VADD(b, DRMP3_VADD(DRMP3_VMUL(vz, w1), DRMP3_VMUL(vy, w0))); a = DRMP3_VADD(a, DRMP3_VSUB(DRMP3_VMUL(vy, w1), DRMP3_VMUL(vz, w0))); }
- drmp3_f4 a, b;
- zlin[4*i] = xl[18*(31 - i)];
- zlin[4*i + 1] = xr[18*(31 - i)];
- zlin[4*i + 2] = xl[1 + 18*(31 - i)];
- zlin[4*i + 3] = xr[1 + 18*(31 - i)];
- zlin[4*i + 64] = xl[1 + 18*(1 + i)];
- zlin[4*i + 64 + 1] = xr[1 + 18*(1 + i)];
- zlin[4*i - 64 + 2] = xl[18*(1 + i)];
- zlin[4*i - 64 + 3] = xr[18*(1 + i)];
-
- DRMP3_V0(0) DRMP3_V2(1) DRMP3_V1(2) DRMP3_V2(3) DRMP3_V1(4) DRMP3_V2(5) DRMP3_V1(6) DRMP3_V2(7)
-
- {
-#ifndef DR_MP3_FLOAT_OUTPUT
-#if DRMP3_HAVE_SSE
- static const drmp3_f4 g_max = { 32767.0f, 32767.0f, 32767.0f, 32767.0f };
- static const drmp3_f4 g_min = { -32768.0f, -32768.0f, -32768.0f, -32768.0f };
- __m128i pcm8 = _mm_packs_epi32(_mm_cvtps_epi32(_mm_max_ps(_mm_min_ps(a, g_max), g_min)),
- _mm_cvtps_epi32(_mm_max_ps(_mm_min_ps(b, g_max), g_min)));
- dstr[(15 - i)*nch] = (drmp3_int16)_mm_extract_epi16(pcm8, 1);
- dstr[(17 + i)*nch] = (drmp3_int16)_mm_extract_epi16(pcm8, 5);
- dstl[(15 - i)*nch] = (drmp3_int16)_mm_extract_epi16(pcm8, 0);
- dstl[(17 + i)*nch] = (drmp3_int16)_mm_extract_epi16(pcm8, 4);
- dstr[(47 - i)*nch] = (drmp3_int16)_mm_extract_epi16(pcm8, 3);
- dstr[(49 + i)*nch] = (drmp3_int16)_mm_extract_epi16(pcm8, 7);
- dstl[(47 - i)*nch] = (drmp3_int16)_mm_extract_epi16(pcm8, 2);
- dstl[(49 + i)*nch] = (drmp3_int16)_mm_extract_epi16(pcm8, 6);
-#else
- int16x4_t pcma, pcmb;
- a = DRMP3_VADD(a, DRMP3_VSET(0.5f));
- b = DRMP3_VADD(b, DRMP3_VSET(0.5f));
- pcma = vqmovn_s32(vqaddq_s32(vcvtq_s32_f32(a), vreinterpretq_s32_u32(vcltq_f32(a, DRMP3_VSET(0)))));
- pcmb = vqmovn_s32(vqaddq_s32(vcvtq_s32_f32(b), vreinterpretq_s32_u32(vcltq_f32(b, DRMP3_VSET(0)))));
- vst1_lane_s16(dstr + (15 - i)*nch, pcma, 1);
- vst1_lane_s16(dstr + (17 + i)*nch, pcmb, 1);
- vst1_lane_s16(dstl + (15 - i)*nch, pcma, 0);
- vst1_lane_s16(dstl + (17 + i)*nch, pcmb, 0);
- vst1_lane_s16(dstr + (47 - i)*nch, pcma, 3);
- vst1_lane_s16(dstr + (49 + i)*nch, pcmb, 3);
- vst1_lane_s16(dstl + (47 - i)*nch, pcma, 2);
- vst1_lane_s16(dstl + (49 + i)*nch, pcmb, 2);
-#endif
-#else
- #if DRMP3_HAVE_SSE
- static const drmp3_f4 g_scale = { 1.0f/32768.0f, 1.0f/32768.0f, 1.0f/32768.0f, 1.0f/32768.0f };
- #else
- const drmp3_f4 g_scale = vdupq_n_f32(1.0f/32768.0f);
- #endif
- a = DRMP3_VMUL(a, g_scale);
- b = DRMP3_VMUL(b, g_scale);
-#if DRMP3_HAVE_SSE
- _mm_store_ss(dstr + (15 - i)*nch, _mm_shuffle_ps(a, a, _MM_SHUFFLE(1, 1, 1, 1)));
- _mm_store_ss(dstr + (17 + i)*nch, _mm_shuffle_ps(b, b, _MM_SHUFFLE(1, 1, 1, 1)));
- _mm_store_ss(dstl + (15 - i)*nch, _mm_shuffle_ps(a, a, _MM_SHUFFLE(0, 0, 0, 0)));
- _mm_store_ss(dstl + (17 + i)*nch, _mm_shuffle_ps(b, b, _MM_SHUFFLE(0, 0, 0, 0)));
- _mm_store_ss(dstr + (47 - i)*nch, _mm_shuffle_ps(a, a, _MM_SHUFFLE(3, 3, 3, 3)));
- _mm_store_ss(dstr + (49 + i)*nch, _mm_shuffle_ps(b, b, _MM_SHUFFLE(3, 3, 3, 3)));
- _mm_store_ss(dstl + (47 - i)*nch, _mm_shuffle_ps(a, a, _MM_SHUFFLE(2, 2, 2, 2)));
- _mm_store_ss(dstl + (49 + i)*nch, _mm_shuffle_ps(b, b, _MM_SHUFFLE(2, 2, 2, 2)));
-#else
- vst1q_lane_f32(dstr + (15 - i)*nch, a, 1);
- vst1q_lane_f32(dstr + (17 + i)*nch, b, 1);
- vst1q_lane_f32(dstl + (15 - i)*nch, a, 0);
- vst1q_lane_f32(dstl + (17 + i)*nch, b, 0);
- vst1q_lane_f32(dstr + (47 - i)*nch, a, 3);
- vst1q_lane_f32(dstr + (49 + i)*nch, b, 3);
- vst1q_lane_f32(dstl + (47 - i)*nch, a, 2);
- vst1q_lane_f32(dstl + (49 + i)*nch, b, 2);
-#endif
-#endif /* DR_MP3_FLOAT_OUTPUT */
- }
- } else
-#endif
-#ifdef DR_MP3_ONLY_SIMD
- {} /* for HAVE_SIMD=1, MINIMP3_ONLY_SIMD=1 case we do not need non-intrinsic "else" branch */
-#else
- for (i = 14; i >= 0; i--)
- {
-#define DRMP3_LOAD(k) float w0 = *w++; float w1 = *w++; float *vz = &zlin[4*i - k*64]; float *vy = &zlin[4*i - (15 - k)*64];
-#define DRMP3_S0(k) { int j; DRMP3_LOAD(k); for (j = 0; j < 4; j++) b[j] = vz[j]*w1 + vy[j]*w0, a[j] = vz[j]*w0 - vy[j]*w1; }
-#define DRMP3_S1(k) { int j; DRMP3_LOAD(k); for (j = 0; j < 4; j++) b[j] += vz[j]*w1 + vy[j]*w0, a[j] += vz[j]*w0 - vy[j]*w1; }
-#define DRMP3_S2(k) { int j; DRMP3_LOAD(k); for (j = 0; j < 4; j++) b[j] += vz[j]*w1 + vy[j]*w0, a[j] += vy[j]*w1 - vz[j]*w0; }
- float a[4], b[4];
-
- zlin[4*i] = xl[18*(31 - i)];
- zlin[4*i + 1] = xr[18*(31 - i)];
- zlin[4*i + 2] = xl[1 + 18*(31 - i)];
- zlin[4*i + 3] = xr[1 + 18*(31 - i)];
- zlin[4*(i + 16)] = xl[1 + 18*(1 + i)];
- zlin[4*(i + 16) + 1] = xr[1 + 18*(1 + i)];
- zlin[4*(i - 16) + 2] = xl[18*(1 + i)];
- zlin[4*(i - 16) + 3] = xr[18*(1 + i)];
-
- DRMP3_S0(0) DRMP3_S2(1) DRMP3_S1(2) DRMP3_S2(3) DRMP3_S1(4) DRMP3_S2(5) DRMP3_S1(6) DRMP3_S2(7)
-
- dstr[(15 - i)*nch] = drmp3d_scale_pcm(a[1]);
- dstr[(17 + i)*nch] = drmp3d_scale_pcm(b[1]);
- dstl[(15 - i)*nch] = drmp3d_scale_pcm(a[0]);
- dstl[(17 + i)*nch] = drmp3d_scale_pcm(b[0]);
- dstr[(47 - i)*nch] = drmp3d_scale_pcm(a[3]);
- dstr[(49 + i)*nch] = drmp3d_scale_pcm(b[3]);
- dstl[(47 - i)*nch] = drmp3d_scale_pcm(a[2]);
- dstl[(49 + i)*nch] = drmp3d_scale_pcm(b[2]);
- }
-#endif
-}
-
-static void drmp3d_synth_granule(float *qmf_state, float *grbuf, int nbands, int nch, drmp3d_sample_t *pcm, float *lins)
-{
- int i;
- for (i = 0; i < nch; i++)
- {
- drmp3d_DCT_II(grbuf + 576*i, nbands);
- }
-
- DRMP3_COPY_MEMORY(lins, qmf_state, sizeof(float)*15*64);
-
- for (i = 0; i < nbands; i += 2)
- {
- drmp3d_synth(grbuf + i, pcm + 32*nch*i, nch, lins + i*64);
- }
-#ifndef DR_MP3_NONSTANDARD_BUT_LOGICAL
- if (nch == 1)
- {
- for (i = 0; i < 15*64; i += 2)
- {
- qmf_state[i] = lins[nbands*64 + i];
- }
- } else
-#endif
- {
- DRMP3_COPY_MEMORY(qmf_state, lins + nbands*64, sizeof(float)*15*64);
- }
-}
-
-static int drmp3d_match_frame(const drmp3_uint8 *hdr, int mp3_bytes, int frame_bytes)
-{
- int i, nmatch;
- for (i = 0, nmatch = 0; nmatch < DRMP3_MAX_FRAME_SYNC_MATCHES; nmatch++)
- {
- i += drmp3_hdr_frame_bytes(hdr + i, frame_bytes) + drmp3_hdr_padding(hdr + i);
- if (i + DRMP3_HDR_SIZE > mp3_bytes)
- return nmatch > 0;
- if (!drmp3_hdr_compare(hdr, hdr + i))
- return 0;
- }
- return 1;
-}
-
-static int drmp3d_find_frame(const drmp3_uint8 *mp3, int mp3_bytes, int *free_format_bytes, int *ptr_frame_bytes)
-{
- int i, k;
- for (i = 0; i < mp3_bytes - DRMP3_HDR_SIZE; i++, mp3++)
- {
- if (drmp3_hdr_valid(mp3))
- {
- int frame_bytes = drmp3_hdr_frame_bytes(mp3, *free_format_bytes);
- int frame_and_padding = frame_bytes + drmp3_hdr_padding(mp3);
-
- for (k = DRMP3_HDR_SIZE; !frame_bytes && k < DRMP3_MAX_FREE_FORMAT_FRAME_SIZE && i + 2*k < mp3_bytes - DRMP3_HDR_SIZE; k++)
- {
- if (drmp3_hdr_compare(mp3, mp3 + k))
- {
- int fb = k - drmp3_hdr_padding(mp3);
- int nextfb = fb + drmp3_hdr_padding(mp3 + k);
- if (i + k + nextfb + DRMP3_HDR_SIZE > mp3_bytes || !drmp3_hdr_compare(mp3, mp3 + k + nextfb))
- continue;
- frame_and_padding = k;
- frame_bytes = fb;
- *free_format_bytes = fb;
- }
- }
-
- if ((frame_bytes && i + frame_and_padding <= mp3_bytes &&
- drmp3d_match_frame(mp3, mp3_bytes - i, frame_bytes)) ||
- (!i && frame_and_padding == mp3_bytes))
- {
- *ptr_frame_bytes = frame_and_padding;
- return i;
- }
- *free_format_bytes = 0;
- }
- }
- *ptr_frame_bytes = 0;
- return mp3_bytes;
-}
-
-DRMP3_API void drmp3dec_init(drmp3dec *dec)
-{
- dec->header[0] = 0;
-}
-
-DRMP3_API int drmp3dec_decode_frame(drmp3dec *dec, const drmp3_uint8 *mp3, int mp3_bytes, void *pcm, drmp3dec_frame_info *info)
-{
- int i = 0, igr, frame_size = 0, success = 1;
- const drmp3_uint8 *hdr;
- drmp3_bs bs_frame[1];
- drmp3dec_scratch scratch;
-
- if (mp3_bytes > 4 && dec->header[0] == 0xff && drmp3_hdr_compare(dec->header, mp3))
- {
- frame_size = drmp3_hdr_frame_bytes(mp3, dec->free_format_bytes) + drmp3_hdr_padding(mp3);
- if (frame_size != mp3_bytes && (frame_size + DRMP3_HDR_SIZE > mp3_bytes || !drmp3_hdr_compare(mp3, mp3 + frame_size)))
- {
- frame_size = 0;
- }
- }
- if (!frame_size)
- {
- DRMP3_ZERO_MEMORY(dec, sizeof(drmp3dec));
- i = drmp3d_find_frame(mp3, mp3_bytes, &dec->free_format_bytes, &frame_size);
- if (!frame_size || i + frame_size > mp3_bytes)
- {
- info->frame_bytes = i;
- return 0;
- }
- }
-
- hdr = mp3 + i;
- DRMP3_COPY_MEMORY(dec->header, hdr, DRMP3_HDR_SIZE);
- info->frame_bytes = i + frame_size;
- info->channels = DRMP3_HDR_IS_MONO(hdr) ? 1 : 2;
- info->hz = drmp3_hdr_sample_rate_hz(hdr);
- info->layer = 4 - DRMP3_HDR_GET_LAYER(hdr);
- info->bitrate_kbps = drmp3_hdr_bitrate_kbps(hdr);
-
- drmp3_bs_init(bs_frame, hdr + DRMP3_HDR_SIZE, frame_size - DRMP3_HDR_SIZE);
- if (DRMP3_HDR_IS_CRC(hdr))
- {
- drmp3_bs_get_bits(bs_frame, 16);
- }
-
- if (info->layer == 3)
- {
- int main_data_begin = drmp3_L3_read_side_info(bs_frame, scratch.gr_info, hdr);
- if (main_data_begin < 0 || bs_frame->pos > bs_frame->limit)
- {
- drmp3dec_init(dec);
- return 0;
- }
- success = drmp3_L3_restore_reservoir(dec, bs_frame, &scratch, main_data_begin);
- if (success && pcm != NULL)
- {
- for (igr = 0; igr < (DRMP3_HDR_TEST_MPEG1(hdr) ? 2 : 1); igr++, pcm = DRMP3_OFFSET_PTR(pcm, sizeof(drmp3d_sample_t)*576*info->channels))
- {
- DRMP3_ZERO_MEMORY(scratch.grbuf[0], 576*2*sizeof(float));
- drmp3_L3_decode(dec, &scratch, scratch.gr_info + igr*info->channels, info->channels);
- drmp3d_synth_granule(dec->qmf_state, scratch.grbuf[0], 18, info->channels, (drmp3d_sample_t*)pcm, scratch.syn[0]);
- }
- }
- drmp3_L3_save_reservoir(dec, &scratch);
- } else
- {
-#ifdef DR_MP3_ONLY_MP3
- return 0;
-#else
- drmp3_L12_scale_info sci[1];
-
- if (pcm == NULL) {
- return drmp3_hdr_frame_samples(hdr);
- }
-
- drmp3_L12_read_scale_info(hdr, bs_frame, sci);
-
- DRMP3_ZERO_MEMORY(scratch.grbuf[0], 576*2*sizeof(float));
- for (i = 0, igr = 0; igr < 3; igr++)
- {
- if (12 == (i += drmp3_L12_dequantize_granule(scratch.grbuf[0] + i, bs_frame, sci, info->layer | 1)))
- {
- i = 0;
- drmp3_L12_apply_scf_384(sci, sci->scf + igr, scratch.grbuf[0]);
- drmp3d_synth_granule(dec->qmf_state, scratch.grbuf[0], 12, info->channels, (drmp3d_sample_t*)pcm, scratch.syn[0]);
- DRMP3_ZERO_MEMORY(scratch.grbuf[0], 576*2*sizeof(float));
- pcm = DRMP3_OFFSET_PTR(pcm, sizeof(drmp3d_sample_t)*384*info->channels);
- }
- if (bs_frame->pos > bs_frame->limit)
- {
- drmp3dec_init(dec);
- return 0;
- }
- }
-#endif
- }
-
- return success*drmp3_hdr_frame_samples(dec->header);
-}
-
-DRMP3_API void drmp3dec_f32_to_s16(const float *in, drmp3_int16 *out, size_t num_samples)
-{
- size_t i = 0;
-#if DRMP3_HAVE_SIMD
- size_t aligned_count = num_samples & ~7;
- for(; i < aligned_count; i+=8)
- {
- drmp3_f4 scale = DRMP3_VSET(32768.0f);
- drmp3_f4 a = DRMP3_VMUL(DRMP3_VLD(&in[i ]), scale);
- drmp3_f4 b = DRMP3_VMUL(DRMP3_VLD(&in[i+4]), scale);
-#if DRMP3_HAVE_SSE
- drmp3_f4 s16max = DRMP3_VSET( 32767.0f);
- drmp3_f4 s16min = DRMP3_VSET(-32768.0f);
- __m128i pcm8 = _mm_packs_epi32(_mm_cvtps_epi32(_mm_max_ps(_mm_min_ps(a, s16max), s16min)),
- _mm_cvtps_epi32(_mm_max_ps(_mm_min_ps(b, s16max), s16min)));
- out[i ] = (drmp3_int16)_mm_extract_epi16(pcm8, 0);
- out[i+1] = (drmp3_int16)_mm_extract_epi16(pcm8, 1);
- out[i+2] = (drmp3_int16)_mm_extract_epi16(pcm8, 2);
- out[i+3] = (drmp3_int16)_mm_extract_epi16(pcm8, 3);
- out[i+4] = (drmp3_int16)_mm_extract_epi16(pcm8, 4);
- out[i+5] = (drmp3_int16)_mm_extract_epi16(pcm8, 5);
- out[i+6] = (drmp3_int16)_mm_extract_epi16(pcm8, 6);
- out[i+7] = (drmp3_int16)_mm_extract_epi16(pcm8, 7);
-#else
- int16x4_t pcma, pcmb;
- a = DRMP3_VADD(a, DRMP3_VSET(0.5f));
- b = DRMP3_VADD(b, DRMP3_VSET(0.5f));
- pcma = vqmovn_s32(vqaddq_s32(vcvtq_s32_f32(a), vreinterpretq_s32_u32(vcltq_f32(a, DRMP3_VSET(0)))));
- pcmb = vqmovn_s32(vqaddq_s32(vcvtq_s32_f32(b), vreinterpretq_s32_u32(vcltq_f32(b, DRMP3_VSET(0)))));
- vst1_lane_s16(out+i , pcma, 0);
- vst1_lane_s16(out+i+1, pcma, 1);
- vst1_lane_s16(out+i+2, pcma, 2);
- vst1_lane_s16(out+i+3, pcma, 3);
- vst1_lane_s16(out+i+4, pcmb, 0);
- vst1_lane_s16(out+i+5, pcmb, 1);
- vst1_lane_s16(out+i+6, pcmb, 2);
- vst1_lane_s16(out+i+7, pcmb, 3);
-#endif
- }
-#endif
- for(; i < num_samples; i++)
- {
- float sample = in[i] * 32768.0f;
- if (sample >= 32766.5)
- out[i] = (drmp3_int16) 32767;
- else if (sample <= -32767.5)
- out[i] = (drmp3_int16)-32768;
- else
- {
- short s = (drmp3_int16)(sample + .5f);
- s -= (s < 0); /* away from zero, to be compliant */
- out[i] = s;
- }
- }
-}
-
-
-
-/************************************************************************************************************************************************************
-
- Main Public API
-
- ************************************************************************************************************************************************************/
-/* SIZE_MAX */
-#if defined(SIZE_MAX)
- #define DRMP3_SIZE_MAX SIZE_MAX
-#else
- #if defined(_WIN64) || defined(_LP64) || defined(__LP64__)
- #define DRMP3_SIZE_MAX ((drmp3_uint64)0xFFFFFFFFFFFFFFFF)
- #else
- #define DRMP3_SIZE_MAX 0xFFFFFFFF
- #endif
-#endif
-/* End SIZE_MAX */
-
-/* Options. */
-#ifndef DRMP3_SEEK_LEADING_MP3_FRAMES
-#define DRMP3_SEEK_LEADING_MP3_FRAMES 2
-#endif
-
-#define DRMP3_MIN_DATA_CHUNK_SIZE 16384
-
-/* The size in bytes of each chunk of data to read from the MP3 stream. minimp3 recommends at least 16K, but in an attempt to reduce data movement I'm making this slightly larger. */
-#ifndef DRMP3_DATA_CHUNK_SIZE
-#define DRMP3_DATA_CHUNK_SIZE (DRMP3_MIN_DATA_CHUNK_SIZE*4)
-#endif
-
-
-#define DRMP3_COUNTOF(x) (sizeof(x) / sizeof(x[0]))
-#define DRMP3_CLAMP(x, lo, hi) (DRMP3_MAX(lo, DRMP3_MIN(x, hi)))
-
-#ifndef DRMP3_PI_D
-#define DRMP3_PI_D 3.14159265358979323846264
-#endif
-
-#define DRMP3_DEFAULT_RESAMPLER_LPF_ORDER 2
-
-static DRMP3_INLINE float drmp3_mix_f32(float x, float y, float a)
-{
- return x*(1-a) + y*a;
-}
-static DRMP3_INLINE float drmp3_mix_f32_fast(float x, float y, float a)
-{
- float r0 = (y - x);
- float r1 = r0*a;
- return x + r1;
- /*return x + (y - x)*a;*/
-}
-
-
-/*
-Greatest common factor using Euclid's algorithm iteratively.
-*/
-static DRMP3_INLINE drmp3_uint32 drmp3_gcf_u32(drmp3_uint32 a, drmp3_uint32 b)
-{
- for (;;) {
- if (b == 0) {
- break;
- } else {
- drmp3_uint32 t = a;
- a = b;
- b = t % a;
- }
- }
-
- return a;
-}
-
-
-static void* drmp3__malloc_default(size_t sz, void* pUserData)
-{
- (void)pUserData;
- return DRMP3_MALLOC(sz);
-}
-
-static void* drmp3__realloc_default(void* p, size_t sz, void* pUserData)
-{
- (void)pUserData;
- return DRMP3_REALLOC(p, sz);
-}
-
-static void drmp3__free_default(void* p, void* pUserData)
-{
- (void)pUserData;
- DRMP3_FREE(p);
-}
-
-
-static void* drmp3__malloc_from_callbacks(size_t sz, const drmp3_allocation_callbacks* pAllocationCallbacks)
-{
- if (pAllocationCallbacks == NULL) {
- return NULL;
- }
-
- if (pAllocationCallbacks->onMalloc != NULL) {
- return pAllocationCallbacks->onMalloc(sz, pAllocationCallbacks->pUserData);
- }
-
- /* Try using realloc(). */
- if (pAllocationCallbacks->onRealloc != NULL) {
- return pAllocationCallbacks->onRealloc(NULL, sz, pAllocationCallbacks->pUserData);
- }
-
- return NULL;
-}
-
-static void* drmp3__realloc_from_callbacks(void* p, size_t szNew, size_t szOld, const drmp3_allocation_callbacks* pAllocationCallbacks)
-{
- if (pAllocationCallbacks == NULL) {
- return NULL;
- }
-
- if (pAllocationCallbacks->onRealloc != NULL) {
- return pAllocationCallbacks->onRealloc(p, szNew, pAllocationCallbacks->pUserData);
- }
-
- /* Try emulating realloc() in terms of malloc()/free(). */
- if (pAllocationCallbacks->onMalloc != NULL && pAllocationCallbacks->onFree != NULL) {
- void* p2;
-
- p2 = pAllocationCallbacks->onMalloc(szNew, pAllocationCallbacks->pUserData);
- if (p2 == NULL) {
- return NULL;
- }
-
- if (p != NULL) {
- DRMP3_COPY_MEMORY(p2, p, szOld);
- pAllocationCallbacks->onFree(p, pAllocationCallbacks->pUserData);
- }
-
- return p2;
- }
-
- return NULL;
-}
-
-static void drmp3__free_from_callbacks(void* p, const drmp3_allocation_callbacks* pAllocationCallbacks)
-{
- if (p == NULL || pAllocationCallbacks == NULL) {
- return;
- }
-
- if (pAllocationCallbacks->onFree != NULL) {
- pAllocationCallbacks->onFree(p, pAllocationCallbacks->pUserData);
- }
-}
-
-
-static drmp3_allocation_callbacks drmp3_copy_allocation_callbacks_or_defaults(const drmp3_allocation_callbacks* pAllocationCallbacks)
-{
- if (pAllocationCallbacks != NULL) {
- /* Copy. */
- return *pAllocationCallbacks;
- } else {
- /* Defaults. */
- drmp3_allocation_callbacks allocationCallbacks;
- allocationCallbacks.pUserData = NULL;
- allocationCallbacks.onMalloc = drmp3__malloc_default;
- allocationCallbacks.onRealloc = drmp3__realloc_default;
- allocationCallbacks.onFree = drmp3__free_default;
- return allocationCallbacks;
- }
-}
-
-
-
-static size_t drmp3__on_read(drmp3* pMP3, void* pBufferOut, size_t bytesToRead)
-{
- size_t bytesRead = pMP3->onRead(pMP3->pUserData, pBufferOut, bytesToRead);
- pMP3->streamCursor += bytesRead;
- return bytesRead;
-}
-
-static drmp3_bool32 drmp3__on_seek(drmp3* pMP3, int offset, drmp3_seek_origin origin)
-{
- DRMP3_ASSERT(offset >= 0);
-
- if (!pMP3->onSeek(pMP3->pUserData, offset, origin)) {
- return DRMP3_FALSE;
- }
-
- if (origin == drmp3_seek_origin_start) {
- pMP3->streamCursor = (drmp3_uint64)offset;
- } else {
- pMP3->streamCursor += offset;
- }
-
- return DRMP3_TRUE;
-}
-
-static drmp3_bool32 drmp3__on_seek_64(drmp3* pMP3, drmp3_uint64 offset, drmp3_seek_origin origin)
-{
- if (offset <= 0x7FFFFFFF) {
- return drmp3__on_seek(pMP3, (int)offset, origin);
- }
-
-
- /* Getting here "offset" is too large for a 32-bit integer. We just keep seeking forward until we hit the offset. */
- if (!drmp3__on_seek(pMP3, 0x7FFFFFFF, drmp3_seek_origin_start)) {
- return DRMP3_FALSE;
- }
-
- offset -= 0x7FFFFFFF;
- while (offset > 0) {
- if (offset <= 0x7FFFFFFF) {
- if (!drmp3__on_seek(pMP3, (int)offset, drmp3_seek_origin_current)) {
- return DRMP3_FALSE;
- }
- offset = 0;
- } else {
- if (!drmp3__on_seek(pMP3, 0x7FFFFFFF, drmp3_seek_origin_current)) {
- return DRMP3_FALSE;
- }
- offset -= 0x7FFFFFFF;
- }
- }
-
- return DRMP3_TRUE;
-}
-
-
-static drmp3_uint32 drmp3_decode_next_frame_ex__callbacks(drmp3* pMP3, drmp3d_sample_t* pPCMFrames)
-{
- drmp3_uint32 pcmFramesRead = 0;
-
- DRMP3_ASSERT(pMP3 != NULL);
- DRMP3_ASSERT(pMP3->onRead != NULL);
-
- if (pMP3->atEnd) {
- return 0;
- }
-
- for (;;) {
- drmp3dec_frame_info info;
-
- /* minimp3 recommends doing data submission in chunks of at least 16K. If we don't have at least 16K bytes available, get more. */
- if (pMP3->dataSize < DRMP3_MIN_DATA_CHUNK_SIZE) {
- size_t bytesRead;
-
- /* First we need to move the data down. */
- if (pMP3->pData != NULL) {
- DRMP3_MOVE_MEMORY(pMP3->pData, pMP3->pData + pMP3->dataConsumed, pMP3->dataSize);
- }
-
- pMP3->dataConsumed = 0;
-
- if (pMP3->dataCapacity < DRMP3_DATA_CHUNK_SIZE) {
- drmp3_uint8* pNewData;
- size_t newDataCap;
-
- newDataCap = DRMP3_DATA_CHUNK_SIZE;
-
- pNewData = (drmp3_uint8*)drmp3__realloc_from_callbacks(pMP3->pData, newDataCap, pMP3->dataCapacity, &pMP3->allocationCallbacks);
- if (pNewData == NULL) {
- return 0; /* Out of memory. */
- }
-
- pMP3->pData = pNewData;
- pMP3->dataCapacity = newDataCap;
- }
-
- bytesRead = drmp3__on_read(pMP3, pMP3->pData + pMP3->dataSize, (pMP3->dataCapacity - pMP3->dataSize));
- if (bytesRead == 0) {
- if (pMP3->dataSize == 0) {
- pMP3->atEnd = DRMP3_TRUE;
- return 0; /* No data. */
- }
- }
-
- pMP3->dataSize += bytesRead;
- }
-
- if (pMP3->dataSize > INT_MAX) {
- pMP3->atEnd = DRMP3_TRUE;
- return 0; /* File too big. */
- }
-
- DRMP3_ASSERT(pMP3->pData != NULL);
- DRMP3_ASSERT(pMP3->dataCapacity > 0);
-
- /* Do a runtime check here to try silencing a false-positive from clang-analyzer. */
- if (pMP3->pData == NULL) {
- return 0;
- }
-
- pcmFramesRead = drmp3dec_decode_frame(&pMP3->decoder, pMP3->pData + pMP3->dataConsumed, (int)pMP3->dataSize, pPCMFrames, &info); /* <-- Safe size_t -> int conversion thanks to the check above. */
-
- /* Consume the data. */
- if (info.frame_bytes > 0) {
- pMP3->dataConsumed += (size_t)info.frame_bytes;
- pMP3->dataSize -= (size_t)info.frame_bytes;
- }
-
- /* pcmFramesRead will be equal to 0 if decoding failed. If it is zero and info.frame_bytes > 0 then we have successfully decoded the frame. */
- if (pcmFramesRead > 0) {
- pcmFramesRead = drmp3_hdr_frame_samples(pMP3->decoder.header);
- pMP3->pcmFramesConsumedInMP3Frame = 0;
- pMP3->pcmFramesRemainingInMP3Frame = pcmFramesRead;
- pMP3->mp3FrameChannels = info.channels;
- pMP3->mp3FrameSampleRate = info.hz;
- break;
- } else if (info.frame_bytes == 0) {
- /* Need more data. minimp3 recommends doing data submission in 16K chunks. */
- size_t bytesRead;
-
- /* First we need to move the data down. */
- DRMP3_MOVE_MEMORY(pMP3->pData, pMP3->pData + pMP3->dataConsumed, pMP3->dataSize);
- pMP3->dataConsumed = 0;
-
- if (pMP3->dataCapacity == pMP3->dataSize) {
- /* No room. Expand. */
- drmp3_uint8* pNewData;
- size_t newDataCap;
-
- newDataCap = pMP3->dataCapacity + DRMP3_DATA_CHUNK_SIZE;
-
- pNewData = (drmp3_uint8*)drmp3__realloc_from_callbacks(pMP3->pData, newDataCap, pMP3->dataCapacity, &pMP3->allocationCallbacks);
- if (pNewData == NULL) {
- return 0; /* Out of memory. */
- }
-
- pMP3->pData = pNewData;
- pMP3->dataCapacity = newDataCap;
- }
-
- /* Fill in a chunk. */
- bytesRead = drmp3__on_read(pMP3, pMP3->pData + pMP3->dataSize, (pMP3->dataCapacity - pMP3->dataSize));
- if (bytesRead == 0) {
- pMP3->atEnd = DRMP3_TRUE;
- return 0; /* Error reading more data. */
- }
-
- pMP3->dataSize += bytesRead;
- }
- };
-
- return pcmFramesRead;
-}
-
-static drmp3_uint32 drmp3_decode_next_frame_ex__memory(drmp3* pMP3, drmp3d_sample_t* pPCMFrames)
-{
- drmp3_uint32 pcmFramesRead = 0;
- drmp3dec_frame_info info;
-
- DRMP3_ASSERT(pMP3 != NULL);
- DRMP3_ASSERT(pMP3->memory.pData != NULL);
-
- if (pMP3->atEnd) {
- return 0;
- }
-
- for (;;) {
- pcmFramesRead = drmp3dec_decode_frame(&pMP3->decoder, pMP3->memory.pData + pMP3->memory.currentReadPos, (int)(pMP3->memory.dataSize - pMP3->memory.currentReadPos), pPCMFrames, &info);
- if (pcmFramesRead > 0) {
- pcmFramesRead = drmp3_hdr_frame_samples(pMP3->decoder.header);
- pMP3->pcmFramesConsumedInMP3Frame = 0;
- pMP3->pcmFramesRemainingInMP3Frame = pcmFramesRead;
- pMP3->mp3FrameChannels = info.channels;
- pMP3->mp3FrameSampleRate = info.hz;
- break;
- } else if (info.frame_bytes > 0) {
- /* No frames were read, but it looks like we skipped past one. Read the next MP3 frame. */
- pMP3->memory.currentReadPos += (size_t)info.frame_bytes;
- } else {
- /* Nothing at all was read. Abort. */
- break;
- }
- }
-
- /* Consume the data. */
- pMP3->memory.currentReadPos += (size_t)info.frame_bytes;
-
- return pcmFramesRead;
-}
-
-static drmp3_uint32 drmp3_decode_next_frame_ex(drmp3* pMP3, drmp3d_sample_t* pPCMFrames)
-{
- if (pMP3->memory.pData != NULL && pMP3->memory.dataSize > 0) {
- return drmp3_decode_next_frame_ex__memory(pMP3, pPCMFrames);
- } else {
- return drmp3_decode_next_frame_ex__callbacks(pMP3, pPCMFrames);
- }
-}
-
-static drmp3_uint32 drmp3_decode_next_frame(drmp3* pMP3)
-{
- DRMP3_ASSERT(pMP3 != NULL);
- return drmp3_decode_next_frame_ex(pMP3, (drmp3d_sample_t*)pMP3->pcmFrames);
-}
-
-#if 0
-static drmp3_uint32 drmp3_seek_next_frame(drmp3* pMP3)
-{
- drmp3_uint32 pcmFrameCount;
-
- DRMP3_ASSERT(pMP3 != NULL);
-
- pcmFrameCount = drmp3_decode_next_frame_ex(pMP3, NULL);
- if (pcmFrameCount == 0) {
- return 0;
- }
-
- /* We have essentially just skipped past the frame, so just set the remaining samples to 0. */
- pMP3->currentPCMFrame += pcmFrameCount;
- pMP3->pcmFramesConsumedInMP3Frame = pcmFrameCount;
- pMP3->pcmFramesRemainingInMP3Frame = 0;
-
- return pcmFrameCount;
-}
-#endif
-
-static drmp3_bool32 drmp3_init_internal(drmp3* pMP3, drmp3_read_proc onRead, drmp3_seek_proc onSeek, void* pUserData, const drmp3_allocation_callbacks* pAllocationCallbacks)
-{
- DRMP3_ASSERT(pMP3 != NULL);
- DRMP3_ASSERT(onRead != NULL);
-
- /* This function assumes the output object has already been reset to 0. Do not do that here, otherwise things will break. */
- drmp3dec_init(&pMP3->decoder);
-
- pMP3->onRead = onRead;
- pMP3->onSeek = onSeek;
- pMP3->pUserData = pUserData;
- pMP3->allocationCallbacks = drmp3_copy_allocation_callbacks_or_defaults(pAllocationCallbacks);
-
- if (pMP3->allocationCallbacks.onFree == NULL || (pMP3->allocationCallbacks.onMalloc == NULL && pMP3->allocationCallbacks.onRealloc == NULL)) {
- return DRMP3_FALSE; /* Invalid allocation callbacks. */
- }
-
- /* Decode the first frame to confirm that it is indeed a valid MP3 stream. */
- if (drmp3_decode_next_frame(pMP3) == 0) {
- drmp3__free_from_callbacks(pMP3->pData, &pMP3->allocationCallbacks); /* The call above may have allocated memory. Need to make sure it's freed before aborting. */
- return DRMP3_FALSE; /* Not a valid MP3 stream. */
- }
-
- pMP3->channels = pMP3->mp3FrameChannels;
- pMP3->sampleRate = pMP3->mp3FrameSampleRate;
-
- return DRMP3_TRUE;
-}
-
-DRMP3_API drmp3_bool32 drmp3_init(drmp3* pMP3, drmp3_read_proc onRead, drmp3_seek_proc onSeek, void* pUserData, const drmp3_allocation_callbacks* pAllocationCallbacks)
-{
- if (pMP3 == NULL || onRead == NULL) {
- return DRMP3_FALSE;
- }
-
- DRMP3_ZERO_OBJECT(pMP3);
- return drmp3_init_internal(pMP3, onRead, onSeek, pUserData, pAllocationCallbacks);
-}
-
-
-static size_t drmp3__on_read_memory(void* pUserData, void* pBufferOut, size_t bytesToRead)
-{
- drmp3* pMP3 = (drmp3*)pUserData;
- size_t bytesRemaining;
-
- DRMP3_ASSERT(pMP3 != NULL);
- DRMP3_ASSERT(pMP3->memory.dataSize >= pMP3->memory.currentReadPos);
-
- bytesRemaining = pMP3->memory.dataSize - pMP3->memory.currentReadPos;
- if (bytesToRead > bytesRemaining) {
- bytesToRead = bytesRemaining;
- }
-
- if (bytesToRead > 0) {
- DRMP3_COPY_MEMORY(pBufferOut, pMP3->memory.pData + pMP3->memory.currentReadPos, bytesToRead);
- pMP3->memory.currentReadPos += bytesToRead;
- }
-
- return bytesToRead;
-}
-
-static drmp3_bool32 drmp3__on_seek_memory(void* pUserData, int byteOffset, drmp3_seek_origin origin)
-{
- drmp3* pMP3 = (drmp3*)pUserData;
-
- DRMP3_ASSERT(pMP3 != NULL);
-
- if (origin == drmp3_seek_origin_current) {
- if (byteOffset > 0) {
- if (pMP3->memory.currentReadPos + byteOffset > pMP3->memory.dataSize) {
- byteOffset = (int)(pMP3->memory.dataSize - pMP3->memory.currentReadPos); /* Trying to seek too far forward. */
- }
- } else {
- if (pMP3->memory.currentReadPos < (size_t)-byteOffset) {
- byteOffset = -(int)pMP3->memory.currentReadPos; /* Trying to seek too far backwards. */
- }
- }
-
- /* This will never underflow thanks to the clamps above. */
- pMP3->memory.currentReadPos += byteOffset;
- } else {
- if ((drmp3_uint32)byteOffset <= pMP3->memory.dataSize) {
- pMP3->memory.currentReadPos = byteOffset;
- } else {
- pMP3->memory.currentReadPos = pMP3->memory.dataSize; /* Trying to seek too far forward. */
- }
- }
-
- return DRMP3_TRUE;
-}
-
-DRMP3_API drmp3_bool32 drmp3_init_memory(drmp3* pMP3, const void* pData, size_t dataSize, const drmp3_allocation_callbacks* pAllocationCallbacks)
-{
- if (pMP3 == NULL) {
- return DRMP3_FALSE;
- }
-
- DRMP3_ZERO_OBJECT(pMP3);
-
- if (pData == NULL || dataSize == 0) {
- return DRMP3_FALSE;
- }
-
- pMP3->memory.pData = (const drmp3_uint8*)pData;
- pMP3->memory.dataSize = dataSize;
- pMP3->memory.currentReadPos = 0;
-
- return drmp3_init_internal(pMP3, drmp3__on_read_memory, drmp3__on_seek_memory, pMP3, pAllocationCallbacks);
-}
-
-
-#ifndef DR_MP3_NO_STDIO
-#include
-#include /* For wcslen(), wcsrtombs() */
-
-/* Errno */
-/* drmp3_result_from_errno() is only used inside DR_MP3_NO_STDIO for now. Move this out if it's ever used elsewhere. */
-#include
-static drmp3_result drmp3_result_from_errno(int e)
-{
- switch (e)
- {
- case 0: return DRMP3_SUCCESS;
- #ifdef EPERM
- case EPERM: return DRMP3_INVALID_OPERATION;
- #endif
- #ifdef ENOENT
- case ENOENT: return DRMP3_DOES_NOT_EXIST;
- #endif
- #ifdef ESRCH
- case ESRCH: return DRMP3_DOES_NOT_EXIST;
- #endif
- #ifdef EINTR
- case EINTR: return DRMP3_INTERRUPT;
- #endif
- #ifdef EIO
- case EIO: return DRMP3_IO_ERROR;
- #endif
- #ifdef ENXIO
- case ENXIO: return DRMP3_DOES_NOT_EXIST;
- #endif
- #ifdef E2BIG
- case E2BIG: return DRMP3_INVALID_ARGS;
- #endif
- #ifdef ENOEXEC
- case ENOEXEC: return DRMP3_INVALID_FILE;
- #endif
- #ifdef EBADF
- case EBADF: return DRMP3_INVALID_FILE;
- #endif
- #ifdef ECHILD
- case ECHILD: return DRMP3_ERROR;
- #endif
- #ifdef EAGAIN
- case EAGAIN: return DRMP3_UNAVAILABLE;
- #endif
- #ifdef ENOMEM
- case ENOMEM: return DRMP3_OUT_OF_MEMORY;
- #endif
- #ifdef EACCES
- case EACCES: return DRMP3_ACCESS_DENIED;
- #endif
- #ifdef EFAULT
- case EFAULT: return DRMP3_BAD_ADDRESS;
- #endif
- #ifdef ENOTBLK
- case ENOTBLK: return DRMP3_ERROR;
- #endif
- #ifdef EBUSY
- case EBUSY: return DRMP3_BUSY;
- #endif
- #ifdef EEXIST
- case EEXIST: return DRMP3_ALREADY_EXISTS;
- #endif
- #ifdef EXDEV
- case EXDEV: return DRMP3_ERROR;
- #endif
- #ifdef ENODEV
- case ENODEV: return DRMP3_DOES_NOT_EXIST;
- #endif
- #ifdef ENOTDIR
- case ENOTDIR: return DRMP3_NOT_DIRECTORY;
- #endif
- #ifdef EISDIR
- case EISDIR: return DRMP3_IS_DIRECTORY;
- #endif
- #ifdef EINVAL
- case EINVAL: return DRMP3_INVALID_ARGS;
- #endif
- #ifdef ENFILE
- case ENFILE: return DRMP3_TOO_MANY_OPEN_FILES;
- #endif
- #ifdef EMFILE
- case EMFILE: return DRMP3_TOO_MANY_OPEN_FILES;
- #endif
- #ifdef ENOTTY
- case ENOTTY: return DRMP3_INVALID_OPERATION;
- #endif
- #ifdef ETXTBSY
- case ETXTBSY: return DRMP3_BUSY;
- #endif
- #ifdef EFBIG
- case EFBIG: return DRMP3_TOO_BIG;
- #endif
- #ifdef ENOSPC
- case ENOSPC: return DRMP3_NO_SPACE;
- #endif
- #ifdef ESPIPE
- case ESPIPE: return DRMP3_BAD_SEEK;
- #endif
- #ifdef EROFS
- case EROFS: return DRMP3_ACCESS_DENIED;
- #endif
- #ifdef EMLINK
- case EMLINK: return DRMP3_TOO_MANY_LINKS;
- #endif
- #ifdef EPIPE
- case EPIPE: return DRMP3_BAD_PIPE;
- #endif
- #ifdef EDOM
- case EDOM: return DRMP3_OUT_OF_RANGE;
- #endif
- #ifdef ERANGE
- case ERANGE: return DRMP3_OUT_OF_RANGE;
- #endif
- #ifdef EDEADLK
- case EDEADLK: return DRMP3_DEADLOCK;
- #endif
- #ifdef ENAMETOOLONG
- case ENAMETOOLONG: return DRMP3_PATH_TOO_LONG;
- #endif
- #ifdef ENOLCK
- case ENOLCK: return DRMP3_ERROR;
- #endif
- #ifdef ENOSYS
- case ENOSYS: return DRMP3_NOT_IMPLEMENTED;
- #endif
- #ifdef ENOTEMPTY
- case ENOTEMPTY: return DRMP3_DIRECTORY_NOT_EMPTY;
- #endif
- #ifdef ELOOP
- case ELOOP: return DRMP3_TOO_MANY_LINKS;
- #endif
- #ifdef ENOMSG
- case ENOMSG: return DRMP3_NO_MESSAGE;
- #endif
- #ifdef EIDRM
- case EIDRM: return DRMP3_ERROR;
- #endif
- #ifdef ECHRNG
- case ECHRNG: return DRMP3_ERROR;
- #endif
- #ifdef EL2NSYNC
- case EL2NSYNC: return DRMP3_ERROR;
- #endif
- #ifdef EL3HLT
- case EL3HLT: return DRMP3_ERROR;
- #endif
- #ifdef EL3RST
- case EL3RST: return DRMP3_ERROR;
- #endif
- #ifdef ELNRNG
- case ELNRNG: return DRMP3_OUT_OF_RANGE;
- #endif
- #ifdef EUNATCH
- case EUNATCH: return DRMP3_ERROR;
- #endif
- #ifdef ENOCSI
- case ENOCSI: return DRMP3_ERROR;
- #endif
- #ifdef EL2HLT
- case EL2HLT: return DRMP3_ERROR;
- #endif
- #ifdef EBADE
- case EBADE: return DRMP3_ERROR;
- #endif
- #ifdef EBADR
- case EBADR: return DRMP3_ERROR;
- #endif
- #ifdef EXFULL
- case EXFULL: return DRMP3_ERROR;
- #endif
- #ifdef ENOANO
- case ENOANO: return DRMP3_ERROR;
- #endif
- #ifdef EBADRQC
- case EBADRQC: return DRMP3_ERROR;
- #endif
- #ifdef EBADSLT
- case EBADSLT: return DRMP3_ERROR;
- #endif
- #ifdef EBFONT
- case EBFONT: return DRMP3_INVALID_FILE;
- #endif
- #ifdef ENOSTR
- case ENOSTR: return DRMP3_ERROR;
- #endif
- #ifdef ENODATA
- case ENODATA: return DRMP3_NO_DATA_AVAILABLE;
- #endif
- #ifdef ETIME
- case ETIME: return DRMP3_TIMEOUT;
- #endif
- #ifdef ENOSR
- case ENOSR: return DRMP3_NO_DATA_AVAILABLE;
- #endif
- #ifdef ENONET
- case ENONET: return DRMP3_NO_NETWORK;
- #endif
- #ifdef ENOPKG
- case ENOPKG: return DRMP3_ERROR;
- #endif
- #ifdef EREMOTE
- case EREMOTE: return DRMP3_ERROR;
- #endif
- #ifdef ENOLINK
- case ENOLINK: return DRMP3_ERROR;
- #endif
- #ifdef EADV
- case EADV: return DRMP3_ERROR;
- #endif
- #ifdef ESRMNT
- case ESRMNT: return DRMP3_ERROR;
- #endif
- #ifdef ECOMM
- case ECOMM: return DRMP3_ERROR;
- #endif
- #ifdef EPROTO
- case EPROTO: return DRMP3_ERROR;
- #endif
- #ifdef EMULTIHOP
- case EMULTIHOP: return DRMP3_ERROR;
- #endif
- #ifdef EDOTDOT
- case EDOTDOT: return DRMP3_ERROR;
- #endif
- #ifdef EBADMSG
- case EBADMSG: return DRMP3_BAD_MESSAGE;
- #endif
- #ifdef EOVERFLOW
- case EOVERFLOW: return DRMP3_TOO_BIG;
- #endif
- #ifdef ENOTUNIQ
- case ENOTUNIQ: return DRMP3_NOT_UNIQUE;
- #endif
- #ifdef EBADFD
- case EBADFD: return DRMP3_ERROR;
- #endif
- #ifdef EREMCHG
- case EREMCHG: return DRMP3_ERROR;
- #endif
- #ifdef ELIBACC
- case ELIBACC: return DRMP3_ACCESS_DENIED;
- #endif
- #ifdef ELIBBAD
- case ELIBBAD: return DRMP3_INVALID_FILE;
- #endif
- #ifdef ELIBSCN
- case ELIBSCN: return DRMP3_INVALID_FILE;
- #endif
- #ifdef ELIBMAX
- case ELIBMAX: return DRMP3_ERROR;
- #endif
- #ifdef ELIBEXEC
- case ELIBEXEC: return DRMP3_ERROR;
- #endif
- #ifdef EILSEQ
- case EILSEQ: return DRMP3_INVALID_DATA;
- #endif
- #ifdef ERESTART
- case ERESTART: return DRMP3_ERROR;
- #endif
- #ifdef ESTRPIPE
- case ESTRPIPE: return DRMP3_ERROR;
- #endif
- #ifdef EUSERS
- case EUSERS: return DRMP3_ERROR;
- #endif
- #ifdef ENOTSOCK
- case ENOTSOCK: return DRMP3_NOT_SOCKET;
- #endif
- #ifdef EDESTADDRREQ
- case EDESTADDRREQ: return DRMP3_NO_ADDRESS;
- #endif
- #ifdef EMSGSIZE
- case EMSGSIZE: return DRMP3_TOO_BIG;
- #endif
- #ifdef EPROTOTYPE
- case EPROTOTYPE: return DRMP3_BAD_PROTOCOL;
- #endif
- #ifdef ENOPROTOOPT
- case ENOPROTOOPT: return DRMP3_PROTOCOL_UNAVAILABLE;
- #endif
- #ifdef EPROTONOSUPPORT
- case EPROTONOSUPPORT: return DRMP3_PROTOCOL_NOT_SUPPORTED;
- #endif
- #ifdef ESOCKTNOSUPPORT
- case ESOCKTNOSUPPORT: return DRMP3_SOCKET_NOT_SUPPORTED;
- #endif
- #ifdef EOPNOTSUPP
- case EOPNOTSUPP: return DRMP3_INVALID_OPERATION;
- #endif
- #ifdef EPFNOSUPPORT
- case EPFNOSUPPORT: return DRMP3_PROTOCOL_FAMILY_NOT_SUPPORTED;
- #endif
- #ifdef EAFNOSUPPORT
- case EAFNOSUPPORT: return DRMP3_ADDRESS_FAMILY_NOT_SUPPORTED;
- #endif
- #ifdef EADDRINUSE
- case EADDRINUSE: return DRMP3_ALREADY_IN_USE;
- #endif
- #ifdef EADDRNOTAVAIL
- case EADDRNOTAVAIL: return DRMP3_ERROR;
- #endif
- #ifdef ENETDOWN
- case ENETDOWN: return DRMP3_NO_NETWORK;
- #endif
- #ifdef ENETUNREACH
- case ENETUNREACH: return DRMP3_NO_NETWORK;
- #endif
- #ifdef ENETRESET
- case ENETRESET: return DRMP3_NO_NETWORK;
- #endif
- #ifdef ECONNABORTED
- case ECONNABORTED: return DRMP3_NO_NETWORK;
- #endif
- #ifdef ECONNRESET
- case ECONNRESET: return DRMP3_CONNECTION_RESET;
- #endif
- #ifdef ENOBUFS
- case ENOBUFS: return DRMP3_NO_SPACE;
- #endif
- #ifdef EISCONN
- case EISCONN: return DRMP3_ALREADY_CONNECTED;
- #endif
- #ifdef ENOTCONN
- case ENOTCONN: return DRMP3_NOT_CONNECTED;
- #endif
- #ifdef ESHUTDOWN
- case ESHUTDOWN: return DRMP3_ERROR;
- #endif
- #ifdef ETOOMANYREFS
- case ETOOMANYREFS: return DRMP3_ERROR;
- #endif
- #ifdef ETIMEDOUT
- case ETIMEDOUT: return DRMP3_TIMEOUT;
- #endif
- #ifdef ECONNREFUSED
- case ECONNREFUSED: return DRMP3_CONNECTION_REFUSED;
- #endif
- #ifdef EHOSTDOWN
- case EHOSTDOWN: return DRMP3_NO_HOST;
- #endif
- #ifdef EHOSTUNREACH
- case EHOSTUNREACH: return DRMP3_NO_HOST;
- #endif
- #ifdef EALREADY
- case EALREADY: return DRMP3_IN_PROGRESS;
- #endif
- #ifdef EINPROGRESS
- case EINPROGRESS: return DRMP3_IN_PROGRESS;
- #endif
- #ifdef ESTALE
- case ESTALE: return DRMP3_INVALID_FILE;
- #endif
- #ifdef EUCLEAN
- case EUCLEAN: return DRMP3_ERROR;
- #endif
- #ifdef ENOTNAM
- case ENOTNAM: return DRMP3_ERROR;
- #endif
- #ifdef ENAVAIL
- case ENAVAIL: return DRMP3_ERROR;
- #endif
- #ifdef EISNAM
- case EISNAM: return DRMP3_ERROR;
- #endif
- #ifdef EREMOTEIO
- case EREMOTEIO: return DRMP3_IO_ERROR;
- #endif
- #ifdef EDQUOT
- case EDQUOT: return DRMP3_NO_SPACE;
- #endif
- #ifdef ENOMEDIUM
- case ENOMEDIUM: return DRMP3_DOES_NOT_EXIST;
- #endif
- #ifdef EMEDIUMTYPE
- case EMEDIUMTYPE: return DRMP3_ERROR;
- #endif
- #ifdef ECANCELED
- case ECANCELED: return DRMP3_CANCELLED;
- #endif
- #ifdef ENOKEY
- case ENOKEY: return DRMP3_ERROR;
- #endif
- #ifdef EKEYEXPIRED
- case EKEYEXPIRED: return DRMP3_ERROR;
- #endif
- #ifdef EKEYREVOKED
- case EKEYREVOKED: return DRMP3_ERROR;
- #endif
- #ifdef EKEYREJECTED
- case EKEYREJECTED: return DRMP3_ERROR;
- #endif
- #ifdef EOWNERDEAD
- case EOWNERDEAD: return DRMP3_ERROR;
- #endif
- #ifdef ENOTRECOVERABLE
- case ENOTRECOVERABLE: return DRMP3_ERROR;
- #endif
- #ifdef ERFKILL
- case ERFKILL: return DRMP3_ERROR;
- #endif
- #ifdef EHWPOISON
- case EHWPOISON: return DRMP3_ERROR;
- #endif
- default: return DRMP3_ERROR;
- }
-}
-/* End Errno */
-
-/* fopen */
-static drmp3_result drmp3_fopen(FILE** ppFile, const char* pFilePath, const char* pOpenMode)
-{
-#if defined(_MSC_VER) && _MSC_VER >= 1400
- errno_t err;
-#endif
-
- if (ppFile != NULL) {
- *ppFile = NULL; /* Safety. */
- }
-
- if (pFilePath == NULL || pOpenMode == NULL || ppFile == NULL) {
- return DRMP3_INVALID_ARGS;
- }
-
-#if defined(_MSC_VER) && _MSC_VER >= 1400
- err = fopen_s(ppFile, pFilePath, pOpenMode);
- if (err != 0) {
- return drmp3_result_from_errno(err);
- }
-#else
-#if defined(_WIN32) || defined(__APPLE__)
- *ppFile = fopen(pFilePath, pOpenMode);
-#else
- #if defined(_FILE_OFFSET_BITS) && _FILE_OFFSET_BITS == 64 && defined(_LARGEFILE64_SOURCE)
- *ppFile = fopen64(pFilePath, pOpenMode);
- #else
- *ppFile = fopen(pFilePath, pOpenMode);
- #endif
-#endif
- if (*ppFile == NULL) {
- drmp3_result result = drmp3_result_from_errno(errno);
- if (result == DRMP3_SUCCESS) {
- result = DRMP3_ERROR; /* Just a safety check to make sure we never ever return success when pFile == NULL. */
- }
-
- return result;
- }
-#endif
-
- return DRMP3_SUCCESS;
-}
-
-/*
-_wfopen() isn't always available in all compilation environments.
-
- * Windows only.
- * MSVC seems to support it universally as far back as VC6 from what I can tell (haven't checked further back).
- * MinGW-64 (both 32- and 64-bit) seems to support it.
- * MinGW wraps it in !defined(__STRICT_ANSI__).
- * OpenWatcom wraps it in !defined(_NO_EXT_KEYS).
-
-This can be reviewed as compatibility issues arise. The preference is to use _wfopen_s() and _wfopen() as opposed to the wcsrtombs()
-fallback, so if you notice your compiler not detecting this properly I'm happy to look at adding support.
-*/
-#if defined(_WIN32)
- #if defined(_MSC_VER) || defined(__MINGW64__) || (!defined(__STRICT_ANSI__) && !defined(_NO_EXT_KEYS))
- #define DRMP3_HAS_WFOPEN
- #endif
-#endif
-
-static drmp3_result drmp3_wfopen(FILE** ppFile, const wchar_t* pFilePath, const wchar_t* pOpenMode, const drmp3_allocation_callbacks* pAllocationCallbacks)
-{
- if (ppFile != NULL) {
- *ppFile = NULL; /* Safety. */
- }
-
- if (pFilePath == NULL || pOpenMode == NULL || ppFile == NULL) {
- return DRMP3_INVALID_ARGS;
- }
-
-#if defined(DRMP3_HAS_WFOPEN)
- {
- /* Use _wfopen() on Windows. */
- #if defined(_MSC_VER) && _MSC_VER >= 1400
- errno_t err = _wfopen_s(ppFile, pFilePath, pOpenMode);
- if (err != 0) {
- return drmp3_result_from_errno(err);
- }
- #else
- *ppFile = _wfopen(pFilePath, pOpenMode);
- if (*ppFile == NULL) {
- return drmp3_result_from_errno(errno);
- }
- #endif
- (void)pAllocationCallbacks;
- }
-#else
- /*
- Use fopen() on anything other than Windows. Requires a conversion. This is annoying because
- fopen() is locale specific. The only real way I can think of to do this is with wcsrtombs(). Note
- that wcstombs() is apparently not thread-safe because it uses a static global mbstate_t object for
- maintaining state. I've checked this with -std=c89 and it works, but if somebody get's a compiler
- error I'll look into improving compatibility.
- */
-
- /*
- Some compilers don't support wchar_t or wcsrtombs() which we're using below. In this case we just
- need to abort with an error. If you encounter a compiler lacking such support, add it to this list
- and submit a bug report and it'll be added to the library upstream.
- */
- #if defined(__DJGPP__)
- {
- /* Nothing to do here. This will fall through to the error check below. */
- }
- #else
- {
- mbstate_t mbs;
- size_t lenMB;
- const wchar_t* pFilePathTemp = pFilePath;
- char* pFilePathMB = NULL;
- char pOpenModeMB[32] = {0};
-
- /* Get the length first. */
- DRMP3_ZERO_OBJECT(&mbs);
- lenMB = wcsrtombs(NULL, &pFilePathTemp, 0, &mbs);
- if (lenMB == (size_t)-1) {
- return drmp3_result_from_errno(errno);
- }
-
- pFilePathMB = (char*)drmp3__malloc_from_callbacks(lenMB + 1, pAllocationCallbacks);
- if (pFilePathMB == NULL) {
- return DRMP3_OUT_OF_MEMORY;
- }
-
- pFilePathTemp = pFilePath;
- DRMP3_ZERO_OBJECT(&mbs);
- wcsrtombs(pFilePathMB, &pFilePathTemp, lenMB + 1, &mbs);
-
- /* The open mode should always consist of ASCII characters so we should be able to do a trivial conversion. */
- {
- size_t i = 0;
- for (;;) {
- if (pOpenMode[i] == 0) {
- pOpenModeMB[i] = '\0';
- break;
- }
-
- pOpenModeMB[i] = (char)pOpenMode[i];
- i += 1;
- }
- }
-
- *ppFile = fopen(pFilePathMB, pOpenModeMB);
-
- drmp3__free_from_callbacks(pFilePathMB, pAllocationCallbacks);
- }
- #endif
-
- if (*ppFile == NULL) {
- return DRMP3_ERROR;
- }
-#endif
-
- return DRMP3_SUCCESS;
-}
-/* End fopen */
-
-
-static size_t drmp3__on_read_stdio(void* pUserData, void* pBufferOut, size_t bytesToRead)
-{
- return fread(pBufferOut, 1, bytesToRead, (FILE*)pUserData);
-}
-
-static drmp3_bool32 drmp3__on_seek_stdio(void* pUserData, int offset, drmp3_seek_origin origin)
-{
- return fseek((FILE*)pUserData, offset, (origin == drmp3_seek_origin_current) ? SEEK_CUR : SEEK_SET) == 0;
-}
-
-DRMP3_API drmp3_bool32 drmp3_init_file(drmp3* pMP3, const char* pFilePath, const drmp3_allocation_callbacks* pAllocationCallbacks)
-{
- drmp3_bool32 result;
- FILE* pFile;
-
- if (drmp3_fopen(&pFile, pFilePath, "rb") != DRMP3_SUCCESS) {
- return DRMP3_FALSE;
- }
-
- result = drmp3_init(pMP3, drmp3__on_read_stdio, drmp3__on_seek_stdio, (void*)pFile, pAllocationCallbacks);
- if (result != DRMP3_TRUE) {
- fclose(pFile);
- return result;
- }
-
- return DRMP3_TRUE;
-}
-
-DRMP3_API drmp3_bool32 drmp3_init_file_w(drmp3* pMP3, const wchar_t* pFilePath, const drmp3_allocation_callbacks* pAllocationCallbacks)
-{
- drmp3_bool32 result;
- FILE* pFile;
-
- if (drmp3_wfopen(&pFile, pFilePath, L"rb", pAllocationCallbacks) != DRMP3_SUCCESS) {
- return DRMP3_FALSE;
- }
-
- result = drmp3_init(pMP3, drmp3__on_read_stdio, drmp3__on_seek_stdio, (void*)pFile, pAllocationCallbacks);
- if (result != DRMP3_TRUE) {
- fclose(pFile);
- return result;
- }
-
- return DRMP3_TRUE;
-}
-#endif
-
-DRMP3_API void drmp3_uninit(drmp3* pMP3)
-{
- if (pMP3 == NULL) {
- return;
- }
-
-#ifndef DR_MP3_NO_STDIO
- if (pMP3->onRead == drmp3__on_read_stdio) {
- FILE* pFile = (FILE*)pMP3->pUserData;
- if (pFile != NULL) {
- fclose(pFile);
- pMP3->pUserData = NULL; /* Make sure the file handle is cleared to NULL to we don't attempt to close it a second time. */
- }
- }
-#endif
-
- drmp3__free_from_callbacks(pMP3->pData, &pMP3->allocationCallbacks);
-}
-
-#if defined(DR_MP3_FLOAT_OUTPUT)
-static void drmp3_f32_to_s16(drmp3_int16* dst, const float* src, drmp3_uint64 sampleCount)
-{
- drmp3_uint64 i;
- drmp3_uint64 i4;
- drmp3_uint64 sampleCount4;
-
- /* Unrolled. */
- i = 0;
- sampleCount4 = sampleCount >> 2;
- for (i4 = 0; i4 < sampleCount4; i4 += 1) {
- float x0 = src[i+0];
- float x1 = src[i+1];
- float x2 = src[i+2];
- float x3 = src[i+3];
-
- x0 = ((x0 < -1) ? -1 : ((x0 > 1) ? 1 : x0));
- x1 = ((x1 < -1) ? -1 : ((x1 > 1) ? 1 : x1));
- x2 = ((x2 < -1) ? -1 : ((x2 > 1) ? 1 : x2));
- x3 = ((x3 < -1) ? -1 : ((x3 > 1) ? 1 : x3));
-
- x0 = x0 * 32767.0f;
- x1 = x1 * 32767.0f;
- x2 = x2 * 32767.0f;
- x3 = x3 * 32767.0f;
-
- dst[i+0] = (drmp3_int16)x0;
- dst[i+1] = (drmp3_int16)x1;
- dst[i+2] = (drmp3_int16)x2;
- dst[i+3] = (drmp3_int16)x3;
-
- i += 4;
- }
-
- /* Leftover. */
- for (; i < sampleCount; i += 1) {
- float x = src[i];
- x = ((x < -1) ? -1 : ((x > 1) ? 1 : x)); /* clip */
- x = x * 32767.0f; /* -1..1 to -32767..32767 */
-
- dst[i] = (drmp3_int16)x;
- }
-}
-#endif
-
-#if !defined(DR_MP3_FLOAT_OUTPUT)
-static void drmp3_s16_to_f32(float* dst, const drmp3_int16* src, drmp3_uint64 sampleCount)
-{
- drmp3_uint64 i;
- for (i = 0; i < sampleCount; i += 1) {
- float x = (float)src[i];
- x = x * 0.000030517578125f; /* -32768..32767 to -1..0.999969482421875 */
- dst[i] = x;
- }
-}
-#endif
-
-
-static drmp3_uint64 drmp3_read_pcm_frames_raw(drmp3* pMP3, drmp3_uint64 framesToRead, void* pBufferOut)
-{
- drmp3_uint64 totalFramesRead = 0;
-
- DRMP3_ASSERT(pMP3 != NULL);
- DRMP3_ASSERT(pMP3->onRead != NULL);
-
- while (framesToRead > 0) {
- drmp3_uint32 framesToConsume = (drmp3_uint32)DRMP3_MIN(pMP3->pcmFramesRemainingInMP3Frame, framesToRead);
- if (pBufferOut != NULL) {
- #if defined(DR_MP3_FLOAT_OUTPUT)
- /* f32 */
- float* pFramesOutF32 = (float*)DRMP3_OFFSET_PTR(pBufferOut, sizeof(float) * totalFramesRead * pMP3->channels);
- float* pFramesInF32 = (float*)DRMP3_OFFSET_PTR(&pMP3->pcmFrames[0], sizeof(float) * pMP3->pcmFramesConsumedInMP3Frame * pMP3->mp3FrameChannels);
- DRMP3_COPY_MEMORY(pFramesOutF32, pFramesInF32, sizeof(float) * framesToConsume * pMP3->channels);
- #else
- /* s16 */
- drmp3_int16* pFramesOutS16 = (drmp3_int16*)DRMP3_OFFSET_PTR(pBufferOut, sizeof(drmp3_int16) * totalFramesRead * pMP3->channels);
- drmp3_int16* pFramesInS16 = (drmp3_int16*)DRMP3_OFFSET_PTR(&pMP3->pcmFrames[0], sizeof(drmp3_int16) * pMP3->pcmFramesConsumedInMP3Frame * pMP3->mp3FrameChannels);
- DRMP3_COPY_MEMORY(pFramesOutS16, pFramesInS16, sizeof(drmp3_int16) * framesToConsume * pMP3->channels);
- #endif
- }
-
- pMP3->currentPCMFrame += framesToConsume;
- pMP3->pcmFramesConsumedInMP3Frame += framesToConsume;
- pMP3->pcmFramesRemainingInMP3Frame -= framesToConsume;
- totalFramesRead += framesToConsume;
- framesToRead -= framesToConsume;
-
- if (framesToRead == 0) {
- break;
- }
-
- DRMP3_ASSERT(pMP3->pcmFramesRemainingInMP3Frame == 0);
-
- /*
- At this point we have exhausted our in-memory buffer so we need to re-fill. Note that the sample rate may have changed
- at this point which means we'll also need to update our sample rate conversion pipeline.
- */
- if (drmp3_decode_next_frame(pMP3) == 0) {
- break;
- }
- }
-
- return totalFramesRead;
-}
-
-
-DRMP3_API drmp3_uint64 drmp3_read_pcm_frames_f32(drmp3* pMP3, drmp3_uint64 framesToRead, float* pBufferOut)
-{
- if (pMP3 == NULL || pMP3->onRead == NULL) {
- return 0;
- }
-
-#if defined(DR_MP3_FLOAT_OUTPUT)
- /* Fast path. No conversion required. */
- return drmp3_read_pcm_frames_raw(pMP3, framesToRead, pBufferOut);
-#else
- /* Slow path. Convert from s16 to f32. */
- {
- drmp3_int16 pTempS16[8192];
- drmp3_uint64 totalPCMFramesRead = 0;
-
- while (totalPCMFramesRead < framesToRead) {
- drmp3_uint64 framesJustRead;
- drmp3_uint64 framesRemaining = framesToRead - totalPCMFramesRead;
- drmp3_uint64 framesToReadNow = DRMP3_COUNTOF(pTempS16) / pMP3->channels;
- if (framesToReadNow > framesRemaining) {
- framesToReadNow = framesRemaining;
- }
-
- framesJustRead = drmp3_read_pcm_frames_raw(pMP3, framesToReadNow, pTempS16);
- if (framesJustRead == 0) {
- break;
- }
-
- drmp3_s16_to_f32((float*)DRMP3_OFFSET_PTR(pBufferOut, sizeof(float) * totalPCMFramesRead * pMP3->channels), pTempS16, framesJustRead * pMP3->channels);
- totalPCMFramesRead += framesJustRead;
- }
-
- return totalPCMFramesRead;
- }
-#endif
-}
-
-DRMP3_API drmp3_uint64 drmp3_read_pcm_frames_s16(drmp3* pMP3, drmp3_uint64 framesToRead, drmp3_int16* pBufferOut)
-{
- if (pMP3 == NULL || pMP3->onRead == NULL) {
- return 0;
- }
-
-#if !defined(DR_MP3_FLOAT_OUTPUT)
- /* Fast path. No conversion required. */
- return drmp3_read_pcm_frames_raw(pMP3, framesToRead, pBufferOut);
-#else
- /* Slow path. Convert from f32 to s16. */
- {
- float pTempF32[4096];
- drmp3_uint64 totalPCMFramesRead = 0;
-
- while (totalPCMFramesRead < framesToRead) {
- drmp3_uint64 framesJustRead;
- drmp3_uint64 framesRemaining = framesToRead - totalPCMFramesRead;
- drmp3_uint64 framesToReadNow = DRMP3_COUNTOF(pTempF32) / pMP3->channels;
- if (framesToReadNow > framesRemaining) {
- framesToReadNow = framesRemaining;
- }
-
- framesJustRead = drmp3_read_pcm_frames_raw(pMP3, framesToReadNow, pTempF32);
- if (framesJustRead == 0) {
- break;
- }
-
- drmp3_f32_to_s16((drmp3_int16*)DRMP3_OFFSET_PTR(pBufferOut, sizeof(drmp3_int16) * totalPCMFramesRead * pMP3->channels), pTempF32, framesJustRead * pMP3->channels);
- totalPCMFramesRead += framesJustRead;
- }
-
- return totalPCMFramesRead;
- }
-#endif
-}
-
-static void drmp3_reset(drmp3* pMP3)
-{
- DRMP3_ASSERT(pMP3 != NULL);
-
- pMP3->pcmFramesConsumedInMP3Frame = 0;
- pMP3->pcmFramesRemainingInMP3Frame = 0;
- pMP3->currentPCMFrame = 0;
- pMP3->dataSize = 0;
- pMP3->atEnd = DRMP3_FALSE;
- drmp3dec_init(&pMP3->decoder);
-}
-
-static drmp3_bool32 drmp3_seek_to_start_of_stream(drmp3* pMP3)
-{
- DRMP3_ASSERT(pMP3 != NULL);
- DRMP3_ASSERT(pMP3->onSeek != NULL);
-
- /* Seek to the start of the stream to begin with. */
- if (!drmp3__on_seek(pMP3, 0, drmp3_seek_origin_start)) {
- return DRMP3_FALSE;
- }
-
- /* Clear any cached data. */
- drmp3_reset(pMP3);
- return DRMP3_TRUE;
-}
-
-
-static drmp3_bool32 drmp3_seek_forward_by_pcm_frames__brute_force(drmp3* pMP3, drmp3_uint64 frameOffset)
-{
- drmp3_uint64 framesRead;
-
- /*
- Just using a dumb read-and-discard for now. What would be nice is to parse only the header of the MP3 frame, and then skip over leading
- frames without spending the time doing a full decode. I cannot see an easy way to do this in minimp3, however, so it may involve some
- kind of manual processing.
- */
-#if defined(DR_MP3_FLOAT_OUTPUT)
- framesRead = drmp3_read_pcm_frames_f32(pMP3, frameOffset, NULL);
-#else
- framesRead = drmp3_read_pcm_frames_s16(pMP3, frameOffset, NULL);
-#endif
- if (framesRead != frameOffset) {
- return DRMP3_FALSE;
- }
-
- return DRMP3_TRUE;
-}
-
-static drmp3_bool32 drmp3_seek_to_pcm_frame__brute_force(drmp3* pMP3, drmp3_uint64 frameIndex)
-{
- DRMP3_ASSERT(pMP3 != NULL);
-
- if (frameIndex == pMP3->currentPCMFrame) {
- return DRMP3_TRUE;
- }
-
- /*
- If we're moving foward we just read from where we're at. Otherwise we need to move back to the start of
- the stream and read from the beginning.
- */
- if (frameIndex < pMP3->currentPCMFrame) {
- /* Moving backward. Move to the start of the stream and then move forward. */
- if (!drmp3_seek_to_start_of_stream(pMP3)) {
- return DRMP3_FALSE;
- }
- }
-
- DRMP3_ASSERT(frameIndex >= pMP3->currentPCMFrame);
- return drmp3_seek_forward_by_pcm_frames__brute_force(pMP3, (frameIndex - pMP3->currentPCMFrame));
-}
-
-static drmp3_bool32 drmp3_find_closest_seek_point(drmp3* pMP3, drmp3_uint64 frameIndex, drmp3_uint32* pSeekPointIndex)
-{
- drmp3_uint32 iSeekPoint;
-
- DRMP3_ASSERT(pSeekPointIndex != NULL);
-
- *pSeekPointIndex = 0;
-
- if (frameIndex < pMP3->pSeekPoints[0].pcmFrameIndex) {
- return DRMP3_FALSE;
- }
-
- /* Linear search for simplicity to begin with while I'm getting this thing working. Once it's all working change this to a binary search. */
- for (iSeekPoint = 0; iSeekPoint < pMP3->seekPointCount; ++iSeekPoint) {
- if (pMP3->pSeekPoints[iSeekPoint].pcmFrameIndex > frameIndex) {
- break; /* Found it. */
- }
-
- *pSeekPointIndex = iSeekPoint;
- }
-
- return DRMP3_TRUE;
-}
-
-static drmp3_bool32 drmp3_seek_to_pcm_frame__seek_table(drmp3* pMP3, drmp3_uint64 frameIndex)
-{
- drmp3_seek_point seekPoint;
- drmp3_uint32 priorSeekPointIndex;
- drmp3_uint16 iMP3Frame;
- drmp3_uint64 leftoverFrames;
-
- DRMP3_ASSERT(pMP3 != NULL);
- DRMP3_ASSERT(pMP3->pSeekPoints != NULL);
- DRMP3_ASSERT(pMP3->seekPointCount > 0);
-
- /* If there is no prior seekpoint it means the target PCM frame comes before the first seek point. Just assume a seekpoint at the start of the file in this case. */
- if (drmp3_find_closest_seek_point(pMP3, frameIndex, &priorSeekPointIndex)) {
- seekPoint = pMP3->pSeekPoints[priorSeekPointIndex];
- } else {
- seekPoint.seekPosInBytes = 0;
- seekPoint.pcmFrameIndex = 0;
- seekPoint.mp3FramesToDiscard = 0;
- seekPoint.pcmFramesToDiscard = 0;
- }
-
- /* First thing to do is seek to the first byte of the relevant MP3 frame. */
- if (!drmp3__on_seek_64(pMP3, seekPoint.seekPosInBytes, drmp3_seek_origin_start)) {
- return DRMP3_FALSE; /* Failed to seek. */
- }
-
- /* Clear any cached data. */
- drmp3_reset(pMP3);
-
- /* Whole MP3 frames need to be discarded first. */
- for (iMP3Frame = 0; iMP3Frame < seekPoint.mp3FramesToDiscard; ++iMP3Frame) {
- drmp3_uint32 pcmFramesRead;
- drmp3d_sample_t* pPCMFrames;
-
- /* Pass in non-null for the last frame because we want to ensure the sample rate converter is preloaded correctly. */
- pPCMFrames = NULL;
- if (iMP3Frame == seekPoint.mp3FramesToDiscard-1) {
- pPCMFrames = (drmp3d_sample_t*)pMP3->pcmFrames;
- }
-
- /* We first need to decode the next frame. */
- pcmFramesRead = drmp3_decode_next_frame_ex(pMP3, pPCMFrames);
- if (pcmFramesRead == 0) {
- return DRMP3_FALSE;
- }
- }
-
- /* We seeked to an MP3 frame in the raw stream so we need to make sure the current PCM frame is set correctly. */
- pMP3->currentPCMFrame = seekPoint.pcmFrameIndex - seekPoint.pcmFramesToDiscard;
-
- /*
- Now at this point we can follow the same process as the brute force technique where we just skip over unnecessary MP3 frames and then
- read-and-discard at least 2 whole MP3 frames.
- */
- leftoverFrames = frameIndex - pMP3->currentPCMFrame;
- return drmp3_seek_forward_by_pcm_frames__brute_force(pMP3, leftoverFrames);
-}
-
-DRMP3_API drmp3_bool32 drmp3_seek_to_pcm_frame(drmp3* pMP3, drmp3_uint64 frameIndex)
-{
- if (pMP3 == NULL || pMP3->onSeek == NULL) {
- return DRMP3_FALSE;
- }
-
- if (frameIndex == 0) {
- return drmp3_seek_to_start_of_stream(pMP3);
- }
-
- /* Use the seek table if we have one. */
- if (pMP3->pSeekPoints != NULL && pMP3->seekPointCount > 0) {
- return drmp3_seek_to_pcm_frame__seek_table(pMP3, frameIndex);
- } else {
- return drmp3_seek_to_pcm_frame__brute_force(pMP3, frameIndex);
- }
-}
-
-DRMP3_API drmp3_bool32 drmp3_get_mp3_and_pcm_frame_count(drmp3* pMP3, drmp3_uint64* pMP3FrameCount, drmp3_uint64* pPCMFrameCount)
-{
- drmp3_uint64 currentPCMFrame;
- drmp3_uint64 totalPCMFrameCount;
- drmp3_uint64 totalMP3FrameCount;
-
- if (pMP3 == NULL) {
- return DRMP3_FALSE;
- }
-
- /*
- The way this works is we move back to the start of the stream, iterate over each MP3 frame and calculate the frame count based
- on our output sample rate, the seek back to the PCM frame we were sitting on before calling this function.
- */
-
- /* The stream must support seeking for this to work. */
- if (pMP3->onSeek == NULL) {
- return DRMP3_FALSE;
- }
-
- /* We'll need to seek back to where we were, so grab the PCM frame we're currently sitting on so we can restore later. */
- currentPCMFrame = pMP3->currentPCMFrame;
-
- if (!drmp3_seek_to_start_of_stream(pMP3)) {
- return DRMP3_FALSE;
- }
-
- totalPCMFrameCount = 0;
- totalMP3FrameCount = 0;
-
- for (;;) {
- drmp3_uint32 pcmFramesInCurrentMP3Frame;
-
- pcmFramesInCurrentMP3Frame = drmp3_decode_next_frame_ex(pMP3, NULL);
- if (pcmFramesInCurrentMP3Frame == 0) {
- break;
- }
-
- totalPCMFrameCount += pcmFramesInCurrentMP3Frame;
- totalMP3FrameCount += 1;
- }
-
- /* Finally, we need to seek back to where we were. */
- if (!drmp3_seek_to_start_of_stream(pMP3)) {
- return DRMP3_FALSE;
- }
-
- if (!drmp3_seek_to_pcm_frame(pMP3, currentPCMFrame)) {
- return DRMP3_FALSE;
- }
-
- if (pMP3FrameCount != NULL) {
- *pMP3FrameCount = totalMP3FrameCount;
- }
- if (pPCMFrameCount != NULL) {
- *pPCMFrameCount = totalPCMFrameCount;
- }
-
- return DRMP3_TRUE;
-}
-
-DRMP3_API drmp3_uint64 drmp3_get_pcm_frame_count(drmp3* pMP3)
-{
- drmp3_uint64 totalPCMFrameCount;
- if (!drmp3_get_mp3_and_pcm_frame_count(pMP3, NULL, &totalPCMFrameCount)) {
- return 0;
- }
-
- return totalPCMFrameCount;
-}
-
-DRMP3_API drmp3_uint64 drmp3_get_mp3_frame_count(drmp3* pMP3)
-{
- drmp3_uint64 totalMP3FrameCount;
- if (!drmp3_get_mp3_and_pcm_frame_count(pMP3, &totalMP3FrameCount, NULL)) {
- return 0;
- }
-
- return totalMP3FrameCount;
-}
-
-static void drmp3__accumulate_running_pcm_frame_count(drmp3* pMP3, drmp3_uint32 pcmFrameCountIn, drmp3_uint64* pRunningPCMFrameCount, float* pRunningPCMFrameCountFractionalPart)
-{
- float srcRatio;
- float pcmFrameCountOutF;
- drmp3_uint32 pcmFrameCountOut;
-
- srcRatio = (float)pMP3->mp3FrameSampleRate / (float)pMP3->sampleRate;
- DRMP3_ASSERT(srcRatio > 0);
-
- pcmFrameCountOutF = *pRunningPCMFrameCountFractionalPart + (pcmFrameCountIn / srcRatio);
- pcmFrameCountOut = (drmp3_uint32)pcmFrameCountOutF;
- *pRunningPCMFrameCountFractionalPart = pcmFrameCountOutF - pcmFrameCountOut;
- *pRunningPCMFrameCount += pcmFrameCountOut;
-}
-
-typedef struct
-{
- drmp3_uint64 bytePos;
- drmp3_uint64 pcmFrameIndex; /* <-- After sample rate conversion. */
-} drmp3__seeking_mp3_frame_info;
-
-DRMP3_API drmp3_bool32 drmp3_calculate_seek_points(drmp3* pMP3, drmp3_uint32* pSeekPointCount, drmp3_seek_point* pSeekPoints)
-{
- drmp3_uint32 seekPointCount;
- drmp3_uint64 currentPCMFrame;
- drmp3_uint64 totalMP3FrameCount;
- drmp3_uint64 totalPCMFrameCount;
-
- if (pMP3 == NULL || pSeekPointCount == NULL || pSeekPoints == NULL) {
- return DRMP3_FALSE; /* Invalid args. */
- }
-
- seekPointCount = *pSeekPointCount;
- if (seekPointCount == 0) {
- return DRMP3_FALSE; /* The client has requested no seek points. Consider this to be invalid arguments since the client has probably not intended this. */
- }
-
- /* We'll need to seek back to the current sample after calculating the seekpoints so we need to go ahead and grab the current location at the top. */
- currentPCMFrame = pMP3->currentPCMFrame;
-
- /* We never do more than the total number of MP3 frames and we limit it to 32-bits. */
- if (!drmp3_get_mp3_and_pcm_frame_count(pMP3, &totalMP3FrameCount, &totalPCMFrameCount)) {
- return DRMP3_FALSE;
- }
-
- /* If there's less than DRMP3_SEEK_LEADING_MP3_FRAMES+1 frames we just report 1 seek point which will be the very start of the stream. */
- if (totalMP3FrameCount < DRMP3_SEEK_LEADING_MP3_FRAMES+1) {
- seekPointCount = 1;
- pSeekPoints[0].seekPosInBytes = 0;
- pSeekPoints[0].pcmFrameIndex = 0;
- pSeekPoints[0].mp3FramesToDiscard = 0;
- pSeekPoints[0].pcmFramesToDiscard = 0;
- } else {
- drmp3_uint64 pcmFramesBetweenSeekPoints;
- drmp3__seeking_mp3_frame_info mp3FrameInfo[DRMP3_SEEK_LEADING_MP3_FRAMES+1];
- drmp3_uint64 runningPCMFrameCount = 0;
- float runningPCMFrameCountFractionalPart = 0;
- drmp3_uint64 nextTargetPCMFrame;
- drmp3_uint32 iMP3Frame;
- drmp3_uint32 iSeekPoint;
-
- if (seekPointCount > totalMP3FrameCount-1) {
- seekPointCount = (drmp3_uint32)totalMP3FrameCount-1;
- }
-
- pcmFramesBetweenSeekPoints = totalPCMFrameCount / (seekPointCount+1);
-
- /*
- Here is where we actually calculate the seek points. We need to start by moving the start of the stream. We then enumerate over each
- MP3 frame.
- */
- if (!drmp3_seek_to_start_of_stream(pMP3)) {
- return DRMP3_FALSE;
- }
-
- /*
- We need to cache the byte positions of the previous MP3 frames. As a new MP3 frame is iterated, we cycle the byte positions in this
- array. The value in the first item in this array is the byte position that will be reported in the next seek point.
- */
-
- /* We need to initialize the array of MP3 byte positions for the leading MP3 frames. */
- for (iMP3Frame = 0; iMP3Frame < DRMP3_SEEK_LEADING_MP3_FRAMES+1; ++iMP3Frame) {
- drmp3_uint32 pcmFramesInCurrentMP3FrameIn;
-
- /* The byte position of the next frame will be the stream's cursor position, minus whatever is sitting in the buffer. */
- DRMP3_ASSERT(pMP3->streamCursor >= pMP3->dataSize);
- mp3FrameInfo[iMP3Frame].bytePos = pMP3->streamCursor - pMP3->dataSize;
- mp3FrameInfo[iMP3Frame].pcmFrameIndex = runningPCMFrameCount;
-
- /* We need to get information about this frame so we can know how many samples it contained. */
- pcmFramesInCurrentMP3FrameIn = drmp3_decode_next_frame_ex(pMP3, NULL);
- if (pcmFramesInCurrentMP3FrameIn == 0) {
- return DRMP3_FALSE; /* This should never happen. */
- }
-
- drmp3__accumulate_running_pcm_frame_count(pMP3, pcmFramesInCurrentMP3FrameIn, &runningPCMFrameCount, &runningPCMFrameCountFractionalPart);
- }
-
- /*
- At this point we will have extracted the byte positions of the leading MP3 frames. We can now start iterating over each seek point and
- calculate them.
- */
- nextTargetPCMFrame = 0;
- for (iSeekPoint = 0; iSeekPoint < seekPointCount; ++iSeekPoint) {
- nextTargetPCMFrame += pcmFramesBetweenSeekPoints;
-
- for (;;) {
- if (nextTargetPCMFrame < runningPCMFrameCount) {
- /* The next seek point is in the current MP3 frame. */
- pSeekPoints[iSeekPoint].seekPosInBytes = mp3FrameInfo[0].bytePos;
- pSeekPoints[iSeekPoint].pcmFrameIndex = nextTargetPCMFrame;
- pSeekPoints[iSeekPoint].mp3FramesToDiscard = DRMP3_SEEK_LEADING_MP3_FRAMES;
- pSeekPoints[iSeekPoint].pcmFramesToDiscard = (drmp3_uint16)(nextTargetPCMFrame - mp3FrameInfo[DRMP3_SEEK_LEADING_MP3_FRAMES-1].pcmFrameIndex);
- break;
- } else {
- size_t i;
- drmp3_uint32 pcmFramesInCurrentMP3FrameIn;
-
- /*
- The next seek point is not in the current MP3 frame, so continue on to the next one. The first thing to do is cycle the cached
- MP3 frame info.
- */
- for (i = 0; i < DRMP3_COUNTOF(mp3FrameInfo)-1; ++i) {
- mp3FrameInfo[i] = mp3FrameInfo[i+1];
- }
-
- /* Cache previous MP3 frame info. */
- mp3FrameInfo[DRMP3_COUNTOF(mp3FrameInfo)-1].bytePos = pMP3->streamCursor - pMP3->dataSize;
- mp3FrameInfo[DRMP3_COUNTOF(mp3FrameInfo)-1].pcmFrameIndex = runningPCMFrameCount;
-
- /*
- Go to the next MP3 frame. This shouldn't ever fail, but just in case it does we just set the seek point and break. If it happens, it
- should only ever do it for the last seek point.
- */
- pcmFramesInCurrentMP3FrameIn = drmp3_decode_next_frame_ex(pMP3, NULL);
- if (pcmFramesInCurrentMP3FrameIn == 0) {
- pSeekPoints[iSeekPoint].seekPosInBytes = mp3FrameInfo[0].bytePos;
- pSeekPoints[iSeekPoint].pcmFrameIndex = nextTargetPCMFrame;
- pSeekPoints[iSeekPoint].mp3FramesToDiscard = DRMP3_SEEK_LEADING_MP3_FRAMES;
- pSeekPoints[iSeekPoint].pcmFramesToDiscard = (drmp3_uint16)(nextTargetPCMFrame - mp3FrameInfo[DRMP3_SEEK_LEADING_MP3_FRAMES-1].pcmFrameIndex);
- break;
- }
-
- drmp3__accumulate_running_pcm_frame_count(pMP3, pcmFramesInCurrentMP3FrameIn, &runningPCMFrameCount, &runningPCMFrameCountFractionalPart);
- }
- }
- }
-
- /* Finally, we need to seek back to where we were. */
- if (!drmp3_seek_to_start_of_stream(pMP3)) {
- return DRMP3_FALSE;
- }
- if (!drmp3_seek_to_pcm_frame(pMP3, currentPCMFrame)) {
- return DRMP3_FALSE;
- }
- }
-
- *pSeekPointCount = seekPointCount;
- return DRMP3_TRUE;
-}
-
-DRMP3_API drmp3_bool32 drmp3_bind_seek_table(drmp3* pMP3, drmp3_uint32 seekPointCount, drmp3_seek_point* pSeekPoints)
-{
- if (pMP3 == NULL) {
- return DRMP3_FALSE;
- }
-
- if (seekPointCount == 0 || pSeekPoints == NULL) {
- /* Unbinding. */
- pMP3->seekPointCount = 0;
- pMP3->pSeekPoints = NULL;
- } else {
- /* Binding. */
- pMP3->seekPointCount = seekPointCount;
- pMP3->pSeekPoints = pSeekPoints;
- }
-
- return DRMP3_TRUE;
-}
-
-
-static float* drmp3__full_read_and_close_f32(drmp3* pMP3, drmp3_config* pConfig, drmp3_uint64* pTotalFrameCount)
-{
- drmp3_uint64 totalFramesRead = 0;
- drmp3_uint64 framesCapacity = 0;
- float* pFrames = NULL;
- float temp[4096];
-
- DRMP3_ASSERT(pMP3 != NULL);
-
- for (;;) {
- drmp3_uint64 framesToReadRightNow = DRMP3_COUNTOF(temp) / pMP3->channels;
- drmp3_uint64 framesJustRead = drmp3_read_pcm_frames_f32(pMP3, framesToReadRightNow, temp);
- if (framesJustRead == 0) {
- break;
- }
-
- /* Reallocate the output buffer if there's not enough room. */
- if (framesCapacity < totalFramesRead + framesJustRead) {
- drmp3_uint64 oldFramesBufferSize;
- drmp3_uint64 newFramesBufferSize;
- drmp3_uint64 newFramesCap;
- float* pNewFrames;
-
- newFramesCap = framesCapacity * 2;
- if (newFramesCap < totalFramesRead + framesJustRead) {
- newFramesCap = totalFramesRead + framesJustRead;
- }
-
- oldFramesBufferSize = framesCapacity * pMP3->channels * sizeof(float);
- newFramesBufferSize = newFramesCap * pMP3->channels * sizeof(float);
- if (newFramesBufferSize > (drmp3_uint64)DRMP3_SIZE_MAX) {
- break;
- }
-
- pNewFrames = (float*)drmp3__realloc_from_callbacks(pFrames, (size_t)newFramesBufferSize, (size_t)oldFramesBufferSize, &pMP3->allocationCallbacks);
- if (pNewFrames == NULL) {
- drmp3__free_from_callbacks(pFrames, &pMP3->allocationCallbacks);
- break;
- }
-
- pFrames = pNewFrames;
- framesCapacity = newFramesCap;
- }
-
- DRMP3_COPY_MEMORY(pFrames + totalFramesRead*pMP3->channels, temp, (size_t)(framesJustRead*pMP3->channels*sizeof(float)));
- totalFramesRead += framesJustRead;
-
- /* If the number of frames we asked for is less that what we actually read it means we've reached the end. */
- if (framesJustRead != framesToReadRightNow) {
- break;
- }
- }
-
- if (pConfig != NULL) {
- pConfig->channels = pMP3->channels;
- pConfig->sampleRate = pMP3->sampleRate;
- }
-
- drmp3_uninit(pMP3);
-
- if (pTotalFrameCount) {
- *pTotalFrameCount = totalFramesRead;
- }
-
- return pFrames;
-}
-
-static drmp3_int16* drmp3__full_read_and_close_s16(drmp3* pMP3, drmp3_config* pConfig, drmp3_uint64* pTotalFrameCount)
-{
- drmp3_uint64 totalFramesRead = 0;
- drmp3_uint64 framesCapacity = 0;
- drmp3_int16* pFrames = NULL;
- drmp3_int16 temp[4096];
-
- DRMP3_ASSERT(pMP3 != NULL);
-
- for (;;) {
- drmp3_uint64 framesToReadRightNow = DRMP3_COUNTOF(temp) / pMP3->channels;
- drmp3_uint64 framesJustRead = drmp3_read_pcm_frames_s16(pMP3, framesToReadRightNow, temp);
- if (framesJustRead == 0) {
- break;
- }
-
- /* Reallocate the output buffer if there's not enough room. */
- if (framesCapacity < totalFramesRead + framesJustRead) {
- drmp3_uint64 newFramesBufferSize;
- drmp3_uint64 oldFramesBufferSize;
- drmp3_uint64 newFramesCap;
- drmp3_int16* pNewFrames;
-
- newFramesCap = framesCapacity * 2;
- if (newFramesCap < totalFramesRead + framesJustRead) {
- newFramesCap = totalFramesRead + framesJustRead;
- }
-
- oldFramesBufferSize = framesCapacity * pMP3->channels * sizeof(drmp3_int16);
- newFramesBufferSize = newFramesCap * pMP3->channels * sizeof(drmp3_int16);
- if (newFramesBufferSize > (drmp3_uint64)DRMP3_SIZE_MAX) {
- break;
- }
-
- pNewFrames = (drmp3_int16*)drmp3__realloc_from_callbacks(pFrames, (size_t)newFramesBufferSize, (size_t)oldFramesBufferSize, &pMP3->allocationCallbacks);
- if (pNewFrames == NULL) {
- drmp3__free_from_callbacks(pFrames, &pMP3->allocationCallbacks);
- break;
- }
-
- pFrames = pNewFrames;
- framesCapacity = newFramesCap;
- }
-
- DRMP3_COPY_MEMORY(pFrames + totalFramesRead*pMP3->channels, temp, (size_t)(framesJustRead*pMP3->channels*sizeof(drmp3_int16)));
- totalFramesRead += framesJustRead;
-
- /* If the number of frames we asked for is less that what we actually read it means we've reached the end. */
- if (framesJustRead != framesToReadRightNow) {
- break;
- }
- }
-
- if (pConfig != NULL) {
- pConfig->channels = pMP3->channels;
- pConfig->sampleRate = pMP3->sampleRate;
- }
-
- drmp3_uninit(pMP3);
-
- if (pTotalFrameCount) {
- *pTotalFrameCount = totalFramesRead;
- }
-
- return pFrames;
-}
-
-
-DRMP3_API float* drmp3_open_and_read_pcm_frames_f32(drmp3_read_proc onRead, drmp3_seek_proc onSeek, void* pUserData, drmp3_config* pConfig, drmp3_uint64* pTotalFrameCount, const drmp3_allocation_callbacks* pAllocationCallbacks)
-{
- drmp3 mp3;
- if (!drmp3_init(&mp3, onRead, onSeek, pUserData, pAllocationCallbacks)) {
- return NULL;
- }
-
- return drmp3__full_read_and_close_f32(&mp3, pConfig, pTotalFrameCount);
-}
-
-DRMP3_API drmp3_int16* drmp3_open_and_read_pcm_frames_s16(drmp3_read_proc onRead, drmp3_seek_proc onSeek, void* pUserData, drmp3_config* pConfig, drmp3_uint64* pTotalFrameCount, const drmp3_allocation_callbacks* pAllocationCallbacks)
-{
- drmp3 mp3;
- if (!drmp3_init(&mp3, onRead, onSeek, pUserData, pAllocationCallbacks)) {
- return NULL;
- }
-
- return drmp3__full_read_and_close_s16(&mp3, pConfig, pTotalFrameCount);
-}
-
-
-DRMP3_API float* drmp3_open_memory_and_read_pcm_frames_f32(const void* pData, size_t dataSize, drmp3_config* pConfig, drmp3_uint64* pTotalFrameCount, const drmp3_allocation_callbacks* pAllocationCallbacks)
-{
- drmp3 mp3;
- if (!drmp3_init_memory(&mp3, pData, dataSize, pAllocationCallbacks)) {
- return NULL;
- }
-
- return drmp3__full_read_and_close_f32(&mp3, pConfig, pTotalFrameCount);
-}
-
-DRMP3_API drmp3_int16* drmp3_open_memory_and_read_pcm_frames_s16(const void* pData, size_t dataSize, drmp3_config* pConfig, drmp3_uint64* pTotalFrameCount, const drmp3_allocation_callbacks* pAllocationCallbacks)
-{
- drmp3 mp3;
- if (!drmp3_init_memory(&mp3, pData, dataSize, pAllocationCallbacks)) {
- return NULL;
- }
-
- return drmp3__full_read_and_close_s16(&mp3, pConfig, pTotalFrameCount);
-}
-
-
-#ifndef DR_MP3_NO_STDIO
-DRMP3_API float* drmp3_open_file_and_read_pcm_frames_f32(const char* filePath, drmp3_config* pConfig, drmp3_uint64* pTotalFrameCount, const drmp3_allocation_callbacks* pAllocationCallbacks)
-{
- drmp3 mp3;
- if (!drmp3_init_file(&mp3, filePath, pAllocationCallbacks)) {
- return NULL;
- }
-
- return drmp3__full_read_and_close_f32(&mp3, pConfig, pTotalFrameCount);
-}
-
-DRMP3_API drmp3_int16* drmp3_open_file_and_read_pcm_frames_s16(const char* filePath, drmp3_config* pConfig, drmp3_uint64* pTotalFrameCount, const drmp3_allocation_callbacks* pAllocationCallbacks)
-{
- drmp3 mp3;
- if (!drmp3_init_file(&mp3, filePath, pAllocationCallbacks)) {
- return NULL;
- }
-
- return drmp3__full_read_and_close_s16(&mp3, pConfig, pTotalFrameCount);
-}
-#endif
-
-DRMP3_API void* drmp3_malloc(size_t sz, const drmp3_allocation_callbacks* pAllocationCallbacks)
-{
- if (pAllocationCallbacks != NULL) {
- return drmp3__malloc_from_callbacks(sz, pAllocationCallbacks);
- } else {
- return drmp3__malloc_default(sz, NULL);
- }
-}
-
-DRMP3_API void drmp3_free(void* p, const drmp3_allocation_callbacks* pAllocationCallbacks)
-{
- if (pAllocationCallbacks != NULL) {
- drmp3__free_from_callbacks(p, pAllocationCallbacks);
- } else {
- drmp3__free_default(p, NULL);
- }
-}
-
-#endif /* dr_mp3_c */
-#endif /*DR_MP3_IMPLEMENTATION*/
-
-/*
-DIFFERENCES BETWEEN minimp3 AND dr_mp3
-======================================
-- First, keep in mind that minimp3 (https://github.com/lieff/minimp3) is where all the real work was done. All of the
- code relating to the actual decoding remains mostly unmodified, apart from some namespacing changes.
-- dr_mp3 adds a pulling style API which allows you to deliver raw data via callbacks. So, rather than pushing data
- to the decoder, the decoder _pulls_ data from your callbacks.
-- In addition to callbacks, a decoder can be initialized from a block of memory and a file.
-- The dr_mp3 pull API reads PCM frames rather than whole MP3 frames.
-- dr_mp3 adds convenience APIs for opening and decoding entire files in one go.
-- dr_mp3 is fully namespaced, including the implementation section, which is more suitable when compiling projects
- as a single translation unit (aka unity builds). At the time of writing this, a unity build is not possible when
- using minimp3 in conjunction with stb_vorbis. dr_mp3 addresses this.
-*/
-
-/*
-RELEASE NOTES - v0.5.0
-=======================
-Version 0.5.0 has breaking API changes.
-
-Improved Client-Defined Memory Allocation
------------------------------------------
-The main change with this release is the addition of a more flexible way of implementing custom memory allocation routines. The
-existing system of DRMP3_MALLOC, DRMP3_REALLOC and DRMP3_FREE are still in place and will be used by default when no custom
-allocation callbacks are specified.
-
-To use the new system, you pass in a pointer to a drmp3_allocation_callbacks object to drmp3_init() and family, like this:
-
- void* my_malloc(size_t sz, void* pUserData)
- {
- return malloc(sz);
- }
- void* my_realloc(void* p, size_t sz, void* pUserData)
- {
- return realloc(p, sz);
- }
- void my_free(void* p, void* pUserData)
- {
- free(p);
- }
-
- ...
-
- drmp3_allocation_callbacks allocationCallbacks;
- allocationCallbacks.pUserData = &myData;
- allocationCallbacks.onMalloc = my_malloc;
- allocationCallbacks.onRealloc = my_realloc;
- allocationCallbacks.onFree = my_free;
- drmp3_init_file(&mp3, "my_file.mp3", NULL, &allocationCallbacks);
-
-The advantage of this new system is that it allows you to specify user data which will be passed in to the allocation routines.
-
-Passing in null for the allocation callbacks object will cause dr_mp3 to use defaults which is the same as DRMP3_MALLOC,
-DRMP3_REALLOC and DRMP3_FREE and the equivalent of how it worked in previous versions.
-
-Every API that opens a drmp3 object now takes this extra parameter. These include the following:
-
- drmp3_init()
- drmp3_init_file()
- drmp3_init_memory()
- drmp3_open_and_read_pcm_frames_f32()
- drmp3_open_and_read_pcm_frames_s16()
- drmp3_open_memory_and_read_pcm_frames_f32()
- drmp3_open_memory_and_read_pcm_frames_s16()
- drmp3_open_file_and_read_pcm_frames_f32()
- drmp3_open_file_and_read_pcm_frames_s16()
-
-Renamed APIs
-------------
-The following APIs have been renamed for consistency with other dr_* libraries and to make it clear that they return PCM frame
-counts rather than sample counts.
-
- drmp3_open_and_read_f32() -> drmp3_open_and_read_pcm_frames_f32()
- drmp3_open_and_read_s16() -> drmp3_open_and_read_pcm_frames_s16()
- drmp3_open_memory_and_read_f32() -> drmp3_open_memory_and_read_pcm_frames_f32()
- drmp3_open_memory_and_read_s16() -> drmp3_open_memory_and_read_pcm_frames_s16()
- drmp3_open_file_and_read_f32() -> drmp3_open_file_and_read_pcm_frames_f32()
- drmp3_open_file_and_read_s16() -> drmp3_open_file_and_read_pcm_frames_s16()
-*/
-
-/*
-REVISION HISTORY
-================
-v0.6.38 - 2023-11-02
- - Fix build for ARMv6-M.
-
-v0.6.37 - 2023-07-07
- - Silence a static analysis warning.
-
-v0.6.36 - 2023-06-17
- - Fix an incorrect date in revision history. No functional change.
-
-v0.6.35 - 2023-05-22
- - Minor code restructure. No functional change.
-
-v0.6.34 - 2022-09-17
- - Fix compilation with DJGPP.
- - Fix compilation when compiling with x86 with no SSE2.
- - Remove an unnecessary variable from the drmp3 structure.
-
-v0.6.33 - 2022-04-10
- - Fix compilation error with the MSVC ARM64 build.
- - Fix compilation error on older versions of GCC.
- - Remove some unused functions.
-
-v0.6.32 - 2021-12-11
- - Fix a warning with Clang.
-
-v0.6.31 - 2021-08-22
- - Fix a bug when loading from memory.
-
-v0.6.30 - 2021-08-16
- - Silence some warnings.
- - Replace memory operations with DRMP3_* macros.
-
-v0.6.29 - 2021-08-08
- - Bring up to date with minimp3.
-
-v0.6.28 - 2021-07-31
- - Fix platform detection for ARM64.
- - Fix a compilation error with C89.
-
-v0.6.27 - 2021-02-21
- - Fix a warning due to referencing _MSC_VER when it is undefined.
-
-v0.6.26 - 2021-01-31
- - Bring up to date with minimp3.
-
-v0.6.25 - 2020-12-26
- - Remove DRMP3_DEFAULT_CHANNELS and DRMP3_DEFAULT_SAMPLE_RATE which are leftovers from some removed APIs.
-
-v0.6.24 - 2020-12-07
- - Fix a typo in version date for 0.6.23.
-
-v0.6.23 - 2020-12-03
- - Fix an error where a file can be closed twice when initialization of the decoder fails.
-
-v0.6.22 - 2020-12-02
- - Fix an error where it's possible for a file handle to be left open when initialization of the decoder fails.
-
-v0.6.21 - 2020-11-28
- - Bring up to date with minimp3.
-
-v0.6.20 - 2020-11-21
- - Fix compilation with OpenWatcom.
-
-v0.6.19 - 2020-11-13
- - Minor code clean up.
-
-v0.6.18 - 2020-11-01
- - Improve compiler support for older versions of GCC.
-
-v0.6.17 - 2020-09-28
- - Bring up to date with minimp3.
-
-v0.6.16 - 2020-08-02
- - Simplify sized types.
-
-v0.6.15 - 2020-07-25
- - Fix a compilation warning.
-
-v0.6.14 - 2020-07-23
- - Fix undefined behaviour with memmove().
-
-v0.6.13 - 2020-07-06
- - Fix a bug when converting from s16 to f32 in drmp3_read_pcm_frames_f32().
-
-v0.6.12 - 2020-06-23
- - Add include guard for the implementation section.
-
-v0.6.11 - 2020-05-26
- - Fix use of uninitialized variable error.
-
-v0.6.10 - 2020-05-16
- - Add compile-time and run-time version querying.
- - DRMP3_VERSION_MINOR
- - DRMP3_VERSION_MAJOR
- - DRMP3_VERSION_REVISION
- - DRMP3_VERSION_STRING
- - drmp3_version()
- - drmp3_version_string()
-
-v0.6.9 - 2020-04-30
- - Change the `pcm` parameter of drmp3dec_decode_frame() to a `const drmp3_uint8*` for consistency with internal APIs.
-
-v0.6.8 - 2020-04-26
- - Optimizations to decoding when initializing from memory.
-
-v0.6.7 - 2020-04-25
- - Fix a compilation error with DR_MP3_NO_STDIO
- - Optimization to decoding by reducing some data movement.
-
-v0.6.6 - 2020-04-23
- - Fix a minor bug with the running PCM frame counter.
-
-v0.6.5 - 2020-04-19
- - Fix compilation error on ARM builds.
-
-v0.6.4 - 2020-04-19
- - Bring up to date with changes to minimp3.
-
-v0.6.3 - 2020-04-13
- - Fix some pedantic warnings.
-
-v0.6.2 - 2020-04-10
- - Fix a crash in drmp3_open_*_and_read_pcm_frames_*() if the output config object is NULL.
-
-v0.6.1 - 2020-04-05
- - Fix warnings.
-
-v0.6.0 - 2020-04-04
- - API CHANGE: Remove the pConfig parameter from the following APIs:
- - drmp3_init()
- - drmp3_init_memory()
- - drmp3_init_file()
- - Add drmp3_init_file_w() for opening a file from a wchar_t encoded path.
-
-v0.5.6 - 2020-02-12
- - Bring up to date with minimp3.
-
-v0.5.5 - 2020-01-29
- - Fix a memory allocation bug in high level s16 decoding APIs.
-
-v0.5.4 - 2019-12-02
- - Fix a possible null pointer dereference when using custom memory allocators for realloc().
-
-v0.5.3 - 2019-11-14
- - Fix typos in documentation.
-
-v0.5.2 - 2019-11-02
- - Bring up to date with minimp3.
-
-v0.5.1 - 2019-10-08
- - Fix a warning with GCC.
-
-v0.5.0 - 2019-10-07
- - API CHANGE: Add support for user defined memory allocation routines. This system allows the program to specify their own memory allocation
- routines with a user data pointer for client-specific contextual data. This adds an extra parameter to the end of the following APIs:
- - drmp3_init()
- - drmp3_init_file()
- - drmp3_init_memory()
- - drmp3_open_and_read_pcm_frames_f32()
- - drmp3_open_and_read_pcm_frames_s16()
- - drmp3_open_memory_and_read_pcm_frames_f32()
- - drmp3_open_memory_and_read_pcm_frames_s16()
- - drmp3_open_file_and_read_pcm_frames_f32()
- - drmp3_open_file_and_read_pcm_frames_s16()
- - API CHANGE: Renamed the following APIs:
- - drmp3_open_and_read_f32() -> drmp3_open_and_read_pcm_frames_f32()
- - drmp3_open_and_read_s16() -> drmp3_open_and_read_pcm_frames_s16()
- - drmp3_open_memory_and_read_f32() -> drmp3_open_memory_and_read_pcm_frames_f32()
- - drmp3_open_memory_and_read_s16() -> drmp3_open_memory_and_read_pcm_frames_s16()
- - drmp3_open_file_and_read_f32() -> drmp3_open_file_and_read_pcm_frames_f32()
- - drmp3_open_file_and_read_s16() -> drmp3_open_file_and_read_pcm_frames_s16()
-
-v0.4.7 - 2019-07-28
- - Fix a compiler error.
-
-v0.4.6 - 2019-06-14
- - Fix a compiler error.
-
-v0.4.5 - 2019-06-06
- - Bring up to date with minimp3.
-
-v0.4.4 - 2019-05-06
- - Fixes to the VC6 build.
-
-v0.4.3 - 2019-05-05
- - Use the channel count and/or sample rate of the first MP3 frame instead of DRMP3_DEFAULT_CHANNELS and
- DRMP3_DEFAULT_SAMPLE_RATE when they are set to 0. To use the old behaviour, just set the relevant property to
- DRMP3_DEFAULT_CHANNELS or DRMP3_DEFAULT_SAMPLE_RATE.
- - Add s16 reading APIs
- - drmp3_read_pcm_frames_s16
- - drmp3_open_memory_and_read_pcm_frames_s16
- - drmp3_open_and_read_pcm_frames_s16
- - drmp3_open_file_and_read_pcm_frames_s16
- - Add drmp3_get_mp3_and_pcm_frame_count() to the public header section.
- - Add support for C89.
- - Change license to choice of public domain or MIT-0.
-
-v0.4.2 - 2019-02-21
- - Fix a warning.
-
-v0.4.1 - 2018-12-30
- - Fix a warning.
-
-v0.4.0 - 2018-12-16
- - API CHANGE: Rename some APIs:
- - drmp3_read_f32 -> to drmp3_read_pcm_frames_f32
- - drmp3_seek_to_frame -> drmp3_seek_to_pcm_frame
- - drmp3_open_and_decode_f32 -> drmp3_open_and_read_pcm_frames_f32
- - drmp3_open_and_decode_memory_f32 -> drmp3_open_memory_and_read_pcm_frames_f32
- - drmp3_open_and_decode_file_f32 -> drmp3_open_file_and_read_pcm_frames_f32
- - Add drmp3_get_pcm_frame_count().
- - Add drmp3_get_mp3_frame_count().
- - Improve seeking performance.
-
-v0.3.2 - 2018-09-11
- - Fix a couple of memory leaks.
- - Bring up to date with minimp3.
-
-v0.3.1 - 2018-08-25
- - Fix C++ build.
-
-v0.3.0 - 2018-08-25
- - Bring up to date with minimp3. This has a minor API change: the "pcm" parameter of drmp3dec_decode_frame() has
- been changed from short* to void* because it can now output both s16 and f32 samples, depending on whether or
- not the DR_MP3_FLOAT_OUTPUT option is set.
-
-v0.2.11 - 2018-08-08
- - Fix a bug where the last part of a file is not read.
-
-v0.2.10 - 2018-08-07
- - Improve 64-bit detection.
-
-v0.2.9 - 2018-08-05
- - Fix C++ build on older versions of GCC.
- - Bring up to date with minimp3.
-
-v0.2.8 - 2018-08-02
- - Fix compilation errors with older versions of GCC.
-
-v0.2.7 - 2018-07-13
- - Bring up to date with minimp3.
-
-v0.2.6 - 2018-07-12
- - Bring up to date with minimp3.
-
-v0.2.5 - 2018-06-22
- - Bring up to date with minimp3.
-
-v0.2.4 - 2018-05-12
- - Bring up to date with minimp3.
-
-v0.2.3 - 2018-04-29
- - Fix TCC build.
-
-v0.2.2 - 2018-04-28
- - Fix bug when opening a decoder from memory.
-
-v0.2.1 - 2018-04-27
- - Efficiency improvements when the decoder reaches the end of the stream.
-
-v0.2 - 2018-04-21
- - Bring up to date with minimp3.
- - Start using major.minor.revision versioning.
-
-v0.1d - 2018-03-30
- - Bring up to date with minimp3.
-
-v0.1c - 2018-03-11
- - Fix C++ build error.
-
-v0.1b - 2018-03-07
- - Bring up to date with minimp3.
-
-v0.1a - 2018-02-28
- - Fix compilation error on GCC/Clang.
- - Fix some warnings.
-
-v0.1 - 2018-02-xx
- - Initial versioned release.
-*/
-
-/*
-This software is available as a choice of the following licenses. Choose
-whichever you prefer.
-
-===============================================================================
-ALTERNATIVE 1 - Public Domain (www.unlicense.org)
-===============================================================================
-This is free and unencumbered software released into the public domain.
-
-Anyone is free to copy, modify, publish, use, compile, sell, or distribute this
-software, either in source code form or as a compiled binary, for any purpose,
-commercial or non-commercial, and by any means.
-
-In jurisdictions that recognize copyright laws, the author or authors of this
-software dedicate any and all copyright interest in the software to the public
-domain. We make this dedication for the benefit of the public at large and to
-the detriment of our heirs and successors. We intend this dedication to be an
-overt act of relinquishment in perpetuity of all present and future rights to
-this software under copyright law.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
-ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-For more information, please refer to
-
-===============================================================================
-ALTERNATIVE 2 - MIT No Attribution
-===============================================================================
-Copyright 2023 David Reid
-
-Permission is hereby granted, free of charge, to any person obtaining a copy of
-this software and associated documentation files (the "Software"), to deal in
-the Software without restriction, including without limitation the rights to
-use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
-of the Software, and to permit persons to whom the Software is furnished to do
-so.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
-*/
-
-/*
- https://github.com/lieff/minimp3
- To the extent possible under law, the author(s) have dedicated all copyright and related and neighboring rights to this software to the public domain worldwide.
- This software is distributed without any warranty.
- See .
-*/
diff --git a/src/codecs/load_aiff.c b/src/codecs/load_aiff.c
index 4b91685a7..4bb624e5c 100644
--- a/src/codecs/load_aiff.c
+++ b/src/codecs/load_aiff.c
@@ -65,11 +65,11 @@ static Uint32 SANE_to_Uint32 (Uint8 *sanebuf)
SDL_AudioSpec *Mix_LoadAIFF_RW (SDL_RWops *src, int freesrc,
SDL_AudioSpec *spec, Uint8 **audio_buf, Uint32 *audio_len)
{
- int was_error;
int found_SSND;
int found_COMM;
int found_VHDR;
int found_BODY;
+ int was_error = 0;
Sint64 start = 0;
Uint32 chunk_type;
@@ -92,7 +92,6 @@ SDL_AudioSpec *Mix_LoadAIFF_RW (SDL_RWops *src, int freesrc,
Uint32 frequency = 0;
/* Make sure we are passed a valid data source */
- was_error = 0;
if (src == NULL) {
was_error = 1;
goto done;
@@ -124,9 +123,11 @@ SDL_AudioSpec *Mix_LoadAIFF_RW (SDL_RWops *src, int freesrc,
chunk_type = SDL_ReadLE32(src);
chunk_length = SDL_ReadBE32(src);
next_chunk = SDL_RWtell(src) + chunk_length;
+
/* Paranoia to avoid infinite loops */
- if (chunk_length == 0)
+ if (chunk_length == 0) {
break;
+ }
switch (chunk_type) {
case SSND:
@@ -223,12 +224,12 @@ SDL_AudioSpec *Mix_LoadAIFF_RW (SDL_RWops *src, int freesrc,
*audio_buf = (Uint8 *)SDL_malloc(*audio_len);
if (*audio_buf == NULL) {
Mix_OutOfMemory();
- return(NULL);
+ return NULL;
}
SDL_RWseek(src, start, RW_SEEK_SET);
if (SDL_RWread(src, *audio_buf, *audio_len, 1) != 1) {
Mix_SetError("Unable to read audio data");
- return(NULL);
+ return NULL;
}
/* Don't return a buffer that isn't a multiple of samplesize */
@@ -241,7 +242,7 @@ SDL_AudioSpec *Mix_LoadAIFF_RW (SDL_RWops *src, int freesrc,
if (was_error) {
spec = NULL;
}
- return(spec);
+ return spec;
}
/* vi: set ts=4 sw=4 expandtab: */
diff --git a/src/codecs/load_voc.c b/src/codecs/load_voc.c
index d541106f9..dc6e4e3df 100644
--- a/src/codecs/load_voc.c
+++ b/src/codecs/load_voc.c
@@ -88,24 +88,27 @@ static int voc_check_header(SDL_RWops *src)
SDL_RWseek(src, 0, RW_SEEK_SET);
- if (SDL_RWread(src, signature, sizeof (signature), 1) != 1)
- return(0);
+ if (SDL_RWread(src, signature, sizeof(signature), 1) != 1) {
+ return 0;
+ }
- if (SDL_memcmp(signature, "Creative Voice File\032", sizeof (signature)) != 0) {
- SDL_SetError("Unrecognized file type (not VOC)");
- return(0);
+ if (SDL_memcmp(signature, "Creative Voice File\032", sizeof(signature)) != 0) {
+ Mix_SetError("Unrecognized file type (not VOC)");
+ return 0;
}
- /* get the offset where the first datablock is located */
- if (SDL_RWread(src, &datablockofs, sizeof (Uint16), 1) != 1)
- return(0);
+ /* get the offset where the first datablock is located */
+ if (SDL_RWread(src, &datablockofs, sizeof(Uint16), 1) != 1) {
+ return 0;
+ }
datablockofs = SDL_SwapLE16(datablockofs);
- if (SDL_RWseek(src, datablockofs, RW_SEEK_SET) != datablockofs)
- return(0);
+ if (SDL_RWseek(src, datablockofs, RW_SEEK_SET) != datablockofs) {
+ return 0;
+ }
- return(1); /* success! */
+ return 1; /* success! */
} /* voc_check_header */
@@ -122,39 +125,38 @@ static int voc_get_block(SDL_RWops *src, vs_t *v, SDL_AudioSpec *spec)
unsigned int i;
v->silent = 0;
- while (v->rest == 0)
- {
- if (SDL_RWread(src, &block, sizeof (block), 1) != 1)
+ while (v->rest == 0) {
+ if (SDL_RWread(src, &block, sizeof(block), 1) != 1) {
return 1; /* assume that's the end of the file. */
+ }
- if (block == VOC_TERM)
+ if (block == VOC_TERM) {
return 1;
+ }
- if (SDL_RWread(src, bits24, sizeof (bits24), 1) != 1)
+ if (SDL_RWread(src, bits24, sizeof(bits24), 1) != 1) {
return 1; /* assume that's the end of the file. */
+ }
/* Size is an 24-bit value. Ugh. */
sblen = (Uint32)((bits24[0]) | (bits24[1] << 8) | (bits24[2] << 16));
- switch(block)
- {
+ switch(block) {
case VOC_DATA:
- if (SDL_RWread(src, &uc, sizeof (uc), 1) != 1)
+ if (SDL_RWread(src, &uc, sizeof(uc), 1) != 1) {
return 0;
+ }
/* When DATA block preceeded by an EXTENDED */
/* block, the DATA blocks rate value is invalid */
- if (!v->has_extended)
- {
- if (uc == 0)
- {
- SDL_SetError("VOC Sample rate is zero?");
+ if (!v->has_extended) {
+ if (uc == 0) {
+ Mix_SetError("VOC Sample rate is zero?");
return 0;
}
- if ((v->rate != VOC_BAD_RATE) && (uc != v->rate))
- {
- SDL_SetError("VOC sample rate codes differ");
+ if ((v->rate != VOC_BAD_RATE) && (uc != v->rate)) {
+ Mix_SetError("VOC sample rate codes differ");
return 0;
}
@@ -163,12 +165,12 @@ static int voc_get_block(SDL_RWops *src, vs_t *v, SDL_AudioSpec *spec)
v->channels = 1;
}
- if (SDL_RWread(src, &uc, sizeof (uc), 1) != 1)
+ if (SDL_RWread(src, &uc, sizeof(uc), 1) != 1) {
return 0;
+ }
- if (uc != 0)
- {
- SDL_SetError("VOC decoder only interprets 8-bit data");
+ if (uc != 0) {
+ Mix_SetError("VOC decoder only interprets 8-bit data");
return 0;
}
@@ -178,39 +180,40 @@ static int voc_get_block(SDL_RWops *src, vs_t *v, SDL_AudioSpec *spec)
return 1;
case VOC_DATA_16:
- if (SDL_RWread(src, &new_rate_long, sizeof (new_rate_long), 1) != 1)
+ if (SDL_RWread(src, &new_rate_long, sizeof(new_rate_long), 1) != 1) {
return 0;
+ }
new_rate_long = SDL_SwapLE32(new_rate_long);
- if (new_rate_long == 0)
- {
- SDL_SetError("VOC Sample rate is zero?");
+ if (new_rate_long == 0) {
+ Mix_SetError("VOC Sample rate is zero?");
return 0;
}
- if ((v->rate != VOC_BAD_RATE) && (new_rate_long != v->rate))
- {
- SDL_SetError("VOC sample rate codes differ");
+ if ((v->rate != VOC_BAD_RATE) && (new_rate_long != v->rate)) {
+ Mix_SetError("VOC sample rate codes differ");
return 0;
}
v->rate = new_rate_long;
spec->freq = (int)new_rate_long;
- if (SDL_RWread(src, &uc, sizeof (uc), 1) != 1)
+ if (SDL_RWread(src, &uc, sizeof(uc), 1) != 1) {
return 0;
+ }
- switch (uc)
- {
+ switch (uc) {
case 8: v->size = ST_SIZE_BYTE; break;
case 16: v->size = ST_SIZE_WORD; break;
default:
- SDL_SetError("VOC with unknown data size");
+ Mix_SetError("VOC with unknown data size");
return 0;
}
- if (SDL_RWread(src, &v->channels, sizeof (Uint8), 1) != 1)
+ if (SDL_RWread(src, &v->channels, sizeof(Uint8), 1) != 1) {
return 0;
+ }
- if (SDL_RWread(src, trash, sizeof (Uint8), 6) != 6)
+ if (SDL_RWread(src, trash, sizeof(Uint8), 6) != 6) {
return 0;
+ }
v->rest = sblen - 12;
return 1;
@@ -220,15 +223,16 @@ static int voc_get_block(SDL_RWops *src, vs_t *v, SDL_AudioSpec *spec)
return 1;
case VOC_SILENCE:
- if (SDL_RWread(src, &period, sizeof (period), 1) != 1)
+ if (SDL_RWread(src, &period, sizeof(period), 1) != 1) {
return 0;
+ }
period = SDL_SwapLE16(period);
- if (SDL_RWread(src, &uc, sizeof (uc), 1) != 1)
+ if (SDL_RWread(src, &uc, sizeof(uc), 1) != 1) {
return 0;
- if (uc == 0)
- {
- SDL_SetError("VOC silence sample rate is zero");
+ }
+ if (uc == 0) {
+ Mix_SetError("VOC silence sample rate is zero");
return 0;
}
@@ -247,10 +251,10 @@ static int voc_get_block(SDL_RWops *src, vs_t *v, SDL_AudioSpec *spec)
case VOC_LOOP:
case VOC_LOOPEND:
- for(i = 0; i < sblen; i++) /* skip repeat loops. */
- {
- if (SDL_RWread(src, trash, sizeof (Uint8), 1) != 1)
+ for (i = 0; i < sblen; i++) { /* skip repeat loops. */
+ if (SDL_RWread(src, trash, sizeof(Uint8), 1) != 1) {
return 0;
+ }
}
break;
@@ -260,60 +264,61 @@ static int voc_get_block(SDL_RWops *src, vs_t *v, SDL_AudioSpec *spec)
/* value from the extended block and not the */
/* data block. */
v->has_extended = 1;
- if (SDL_RWread(src, &new_rate_short, sizeof (new_rate_short), 1) != 1)
+ if (SDL_RWread(src, &new_rate_short, sizeof(new_rate_short), 1) != 1) {
return 0;
+ }
new_rate_short = SDL_SwapLE16(new_rate_short);
- if (new_rate_short == 0)
- {
- SDL_SetError("VOC sample rate is zero");
+ if (new_rate_short == 0) {
+ Mix_SetError("VOC sample rate is zero");
return 0;
}
- if ((v->rate != VOC_BAD_RATE) && (new_rate_short != v->rate))
- {
- SDL_SetError("VOC sample rate codes differ");
+ if ((v->rate != VOC_BAD_RATE) && (new_rate_short != v->rate)) {
+ Mix_SetError("VOC sample rate codes differ");
return 0;
}
v->rate = new_rate_short;
- if (SDL_RWread(src, &uc, sizeof (uc), 1) != 1)
+ if (SDL_RWread(src, &uc, sizeof(uc), 1) != 1) {
return 0;
+ }
- if (uc != 0)
- {
- SDL_SetError("VOC decoder only interprets 8-bit data");
+ if (uc != 0) {
+ Mix_SetError("VOC decoder only interprets 8-bit data");
return 0;
}
- if (SDL_RWread(src, &uc, sizeof (uc), 1) != 1)
+ if (SDL_RWread(src, &uc, sizeof(uc), 1) != 1) {
return 0;
+ }
- if (uc)
- spec->channels = 2; /* Stereo */
+ if (uc) /* Stereo */
+ spec->channels = 2;
/* VOC_EXTENDED may be read before spec->channels inited: */
else spec->channels = 1;
/* Needed number of channels before finishing
compute for rate */
- spec->freq = (256000000L/(65536L - v->rate))/spec->channels;
+ spec->freq = (256000000L / (65536L - v->rate)) / spec->channels;
/* An extended block must be followed by a data */
/* block to be valid so loop back to top so it */
/* can be grabed. */
continue;
case VOC_MARKER:
- if (SDL_RWread(src, trash, sizeof (Uint8), 2) != 2)
+ if (SDL_RWread(src, trash, sizeof(Uint8), 2) != 2) {
return 0;
-
+ }
/* fallthrough */
default: /* text block or other krapola. */
- for(i = 0; i < sblen; i++)
- {
- if (SDL_RWread(src, trash, sizeof (Uint8), 1) != 1)
+ for (i = 0; i < sblen; i++) {
+ if (SDL_RWread(src, trash, sizeof(Uint8), 1) != 1) {
return 0;
+ }
}
- if (block == VOC_TEXT)
+ if (block == VOC_TEXT) {
continue; /* get next block */
+ }
}
}
@@ -326,39 +331,36 @@ static Uint32 voc_read(SDL_RWops *src, vs_t *v, Uint8 *buf, SDL_AudioSpec *spec)
Uint32 done = 0;
Uint8 silence = 0x80;
- if (v->rest == 0)
- {
- if (!voc_get_block(src, v, spec))
+ if (v->rest == 0) {
+ if (!voc_get_block(src, v, spec)) {
return 0;
+ }
}
- if (v->rest == 0)
+ if (v->rest == 0) {
return 0;
+ }
- if (v->silent)
- {
- if (v->size == ST_SIZE_WORD)
+ if (v->silent) {
+ if (v->size == ST_SIZE_WORD) {
silence = 0x00;
+ }
/* Fill in silence */
SDL_memset(buf, silence, v->rest);
done = v->rest;
v->rest = 0;
}
-
- else
- {
+ else {
done = (Uint32)SDL_RWread(src, buf, 1, v->rest);
v->rest -= done;
- if (v->size == ST_SIZE_WORD)
- {
+ if (v->size == ST_SIZE_WORD) {
#if (SDL_BYTEORDER == SDL_BIG_ENDIAN)
//#ifdef __MORPHOS__
//SDL_CopyAndSwap16((APTR)buf, (APTR)buf, v->rest /2);
//#else
Uint16 *samples = (Uint16 *)buf;
- for (; v->rest > 0; v->rest -= 2)
- {
+ for (; v->rest > 0; v->rest -= 2) {
*samples = SDL_SwapLE16(*samples);
samples++;
}
@@ -382,53 +384,57 @@ SDL_AudioSpec *Mix_LoadVOC_RW (SDL_RWops *src, int freesrc,
Uint8 *fillptr;
void *ptr;
- if ((!src) || (!audio_buf) || (!audio_len)) /* sanity checks. */
+ if (!src || !audio_buf || !audio_len) { /* sanity checks. */
goto done;
+ }
- if (!voc_check_header(src))
+ if (!voc_check_header(src)) {
goto done;
+ }
- SDL_memset(&v, 0, sizeof (vs_t));
+ SDL_memset(&v, 0, sizeof(vs_t));
v.rate = VOC_BAD_RATE;
v.rest = 0;
v.has_extended = 0;
*audio_buf = NULL;
*audio_len = 0;
- SDL_memset(spec, '\0', sizeof (SDL_AudioSpec));
+ SDL_memset(spec, '\0', sizeof(SDL_AudioSpec));
- if (!voc_get_block(src, &v, spec))
+ if (!voc_get_block(src, &v, spec)) {
goto done;
+ }
if (v.rate == VOC_BAD_RATE) {
- SDL_SetError("VOC data had no sound!");
+ Mix_SetError("VOC data had no sound!");
goto done;
}
if (v.size == 0) {
- SDL_SetError("VOC data had invalid word size!");
+ Mix_SetError("VOC data had invalid word size!");
goto done;
}
spec->format = ((v.size == ST_SIZE_WORD) ? AUDIO_S16 : AUDIO_U8);
- if (spec->channels == 0)
+ if (spec->channels == 0) {
spec->channels = v.channels;
+ }
*audio_len = v.rest;
*audio_buf = (v.rest == 0) ? NULL : SDL_malloc(v.rest);
- if (*audio_buf == NULL)
+ if (*audio_buf == NULL) {
goto done;
+ }
fillptr = *audio_buf;
- while (voc_read(src, &v, fillptr, spec))
- {
- if (!voc_get_block(src, &v, spec))
+ while (voc_read(src, &v, fillptr, spec)) {
+ if (!voc_get_block(src, &v, spec)) {
goto done;
+ }
*audio_len += v.rest;
ptr = SDL_realloc(*audio_buf, *audio_len);
- if (ptr == NULL)
- {
+ if (ptr == NULL) {
SDL_free(*audio_buf);
*audio_buf = NULL;
*audio_len = 0;
@@ -451,12 +457,11 @@ SDL_AudioSpec *Mix_LoadVOC_RW (SDL_RWops *src, int freesrc,
if (freesrc && src) {
SDL_RWclose(src);
}
-
if (was_error) {
spec = NULL;
}
+ return spec;
- return(spec);
} /* Mix_LoadVOC_RW */
/* end of load_voc.c ... */
diff --git a/src/codecs/minimp3/LICENSE b/src/codecs/minimp3/LICENSE
new file mode 100644
index 000000000..2c4afabdb
--- /dev/null
+++ b/src/codecs/minimp3/LICENSE
@@ -0,0 +1,117 @@
+CC0 1.0 Universal
+
+Statement of Purpose
+
+The laws of most jurisdictions throughout the world automatically confer
+exclusive Copyright and Related Rights (defined below) upon the creator and
+subsequent owner(s) (each and all, an "owner") of an original work of
+authorship and/or a database (each, a "Work").
+
+Certain owners wish to permanently relinquish those rights to a Work for the
+purpose of contributing to a commons of creative, cultural and scientific
+works ("Commons") that the public can reliably and without fear of later
+claims of infringement build upon, modify, incorporate in other works, reuse
+and redistribute as freely as possible in any form whatsoever and for any
+purposes, including without limitation commercial purposes. These owners may
+contribute to the Commons to promote the ideal of a free culture and the
+further production of creative, cultural and scientific works, or to gain
+reputation or greater distribution for their Work in part through the use and
+efforts of others.
+
+For these and/or other purposes and motivations, and without any expectation
+of additional consideration or compensation, the person associating CC0 with a
+Work (the "Affirmer"), to the extent that he or she is an owner of Copyright
+and Related Rights in the Work, voluntarily elects to apply CC0 to the Work
+and publicly distribute the Work under its terms, with knowledge of his or her
+Copyright and Related Rights in the Work and the meaning and intended legal
+effect of CC0 on those rights.
+
+1. Copyright and Related Rights. A Work made available under CC0 may be
+protected by copyright and related or neighboring rights ("Copyright and
+Related Rights"). Copyright and Related Rights include, but are not limited
+to, the following:
+
+ i. the right to reproduce, adapt, distribute, perform, display, communicate,
+ and translate a Work;
+
+ ii. moral rights retained by the original author(s) and/or performer(s);
+
+ iii. publicity and privacy rights pertaining to a person's image or likeness
+ depicted in a Work;
+
+ iv. rights protecting against unfair competition in regards to a Work,
+ subject to the limitations in paragraph 4(a), below;
+
+ v. rights protecting the extraction, dissemination, use and reuse of data in
+ a Work;
+
+ vi. database rights (such as those arising under Directive 96/9/EC of the
+ European Parliament and of the Council of 11 March 1996 on the legal
+ protection of databases, and under any national implementation thereof,
+ including any amended or successor version of such directive); and
+
+ vii. other similar, equivalent or corresponding rights throughout the world
+ based on applicable law or treaty, and any national implementations thereof.
+
+2. Waiver. To the greatest extent permitted by, but not in contravention of,
+applicable law, Affirmer hereby overtly, fully, permanently, irrevocably and
+unconditionally waives, abandons, and surrenders all of Affirmer's Copyright
+and Related Rights and associated claims and causes of action, whether now
+known or unknown (including existing as well as future claims and causes of
+action), in the Work (i) in all territories worldwide, (ii) for the maximum
+duration provided by applicable law or treaty (including future time
+extensions), (iii) in any current or future medium and for any number of
+copies, and (iv) for any purpose whatsoever, including without limitation
+commercial, advertising or promotional purposes (the "Waiver"). Affirmer makes
+the Waiver for the benefit of each member of the public at large and to the
+detriment of Affirmer's heirs and successors, fully intending that such Waiver
+shall not be subject to revocation, rescission, cancellation, termination, or
+any other legal or equitable action to disrupt the quiet enjoyment of the Work
+by the public as contemplated by Affirmer's express Statement of Purpose.
+
+3. Public License Fallback. Should any part of the Waiver for any reason be
+judged legally invalid or ineffective under applicable law, then the Waiver
+shall be preserved to the maximum extent permitted taking into account
+Affirmer's express Statement of Purpose. In addition, to the extent the Waiver
+is so judged Affirmer hereby grants to each affected person a royalty-free,
+non transferable, non sublicensable, non exclusive, irrevocable and
+unconditional license to exercise Affirmer's Copyright and Related Rights in
+the Work (i) in all territories worldwide, (ii) for the maximum duration
+provided by applicable law or treaty (including future time extensions), (iii)
+in any current or future medium and for any number of copies, and (iv) for any
+purpose whatsoever, including without limitation commercial, advertising or
+promotional purposes (the "License"). The License shall be deemed effective as
+of the date CC0 was applied by Affirmer to the Work. Should any part of the
+License for any reason be judged legally invalid or ineffective under
+applicable law, such partial invalidity or ineffectiveness shall not
+invalidate the remainder of the License, and in such case Affirmer hereby
+affirms that he or she will not (i) exercise any of his or her remaining
+Copyright and Related Rights in the Work or (ii) assert any associated claims
+and causes of action with respect to the Work, in either case contrary to
+Affirmer's express Statement of Purpose.
+
+4. Limitations and Disclaimers.
+
+ a. No trademark or patent rights held by Affirmer are waived, abandoned,
+ surrendered, licensed or otherwise affected by this document.
+
+ b. Affirmer offers the Work as-is and makes no representations or warranties
+ of any kind concerning the Work, express, implied, statutory or otherwise,
+ including without limitation warranties of title, merchantability, fitness
+ for a particular purpose, non infringement, or the absence of latent or
+ other defects, accuracy, or the present or absence of errors, whether or not
+ discoverable, all to the greatest extent permissible under applicable law.
+
+ c. Affirmer disclaims responsibility for clearing rights of other persons
+ that may apply to the Work or any use thereof, including without limitation
+ any person's Copyright and Related Rights in the Work. Further, Affirmer
+ disclaims responsibility for obtaining any necessary consents, permissions
+ or other rights required for any use of the Work.
+
+ d. Affirmer understands and acknowledges that Creative Commons is not a
+ party to this document and has no duty or obligation with respect to this
+ CC0 or use of the Work.
+
+For more information, please see
+
+
diff --git a/src/codecs/minimp3/README.md b/src/codecs/minimp3/README.md
new file mode 100644
index 000000000..fbf9455a3
--- /dev/null
+++ b/src/codecs/minimp3/README.md
@@ -0,0 +1,310 @@
+minimp3
+==========
+
+[![Build Status](https://travis-ci.org/lieff/minimp3.svg)](https://travis-ci.org/lieff/minimp3)
+
+
+
+[![codecov](https://codecov.io/gh/lieff/minimp3/branch/master/graph/badge.svg)](https://codecov.io/gh/lieff/minimp3)
+
+Minimalistic, single-header library for decoding MP3. minimp3 is designed to be
+small, fast (with SSE and NEON support), and accurate (ISO conformant). You can
+find a rough benchmark below, measured using ``perf`` on an i7-6700K, IO
+included, no CPU heat to address speedstep:
+
+| Vector | Hz | Samples| Sec | Clockticks | Clockticks per second | PSNR | Max diff |
+| ----------- | ----- | ------ | ------ | --------- | ------ | ------ | - |
+|compl.bit | 48000 | 248832 | 5.184 | 14306684 | 2.759M | 124.22 | 1 |
+|he_32khz.bit | 32000 | 172800 | 5.4 | 8426158 | 1.560M | 139.67 | 1 |
+|he_44khz.bit | 44100 | 472320 | 10.710 | 21296300 | 1.988M | 144.04 | 1 |
+|he_48khz.bit | 48000 | 172800 | 3.6 | 8453846 | 2.348M | 139.67 | 1 |
+|hecommon.bit | 44100 | 69120 | 1.567 | 3169715 | 2.022M | 133.93 | 1 |
+|he_free.bit | 44100 | 156672 | 3.552 | 5798418 | 1.632M | 137.48 | 1 |
+|he_mode.bit | 44100 | 262656 | 5.955 | 9882314 | 1.659M | 118.00 | 1 |
+|si.bit | 44100 | 135936 | 3.082 | 7170520 | 2.326M | 120.30 | 1 |
+|si_block.bit | 44100 | 73728 | 1.671 | 4233136 | 2.533M | 125.18 | 1 |
+|si_huff.bit | 44100 | 86400 | 1.959 | 4785322 | 2.442M | 107.98 | 1 |
+|sin1k0db.bit | 44100 | 725760 | 16.457 | 24842977 | 1.509M | 111.03 | 1 |
+
+Conformance test passed on all vectors (PSNR > 96db).
+
+## Comparison with keyj's [minimp3](https://keyj.emphy.de/minimp3/)
+
+Comparison by features:
+
+| Keyj minimp3 | Current |
+| ------------ | ------- |
+| Fixed point | Floating point |
+| source: 84kb | 70kb |
+| binary: 34kb (20kb compressed) | 30kb (20kb) |
+| no vector opts | SSE/NEON intrinsics |
+| no free format | free format support |
+
+Below, you can find the benchmark and conformance test for keyj's minimp3:
+
+
+| Vector | Hz | Samples| Sec | Clockticks | Clockticks per second | PSNR | Max diff |
+| ----------- | ----- | ------ | ------ | --------- | ------ | ----- | - |
+|compl.bit | 48000 | 248832 | 5.184 | 31849373 | 6.143M | 71.50 | 41 |
+|he_32khz.bit | 32000 | 172800 | 5.4 | 26302319 | 4.870M | 71.63 | 24 |
+|he_44khz.bit | 44100 | 472320 | 10.710 | 41628861 | 3.886M | 71.63 | 24 |
+|he_48khz.bit | 48000 | 172800 | 3.6 | 25899527 | 7.194M | 71.63 | 24 |
+|hecommon.bit | 44100 | 69120 | 1.567 | 20437779 | 13.039M | 71.58 | 25 |
+|he_free.bit | 44100 | 0 | 0 | - | - | - | - |
+|he_mode.bit | 44100 | 262656 | 5.955 | 30988984 | 5.203M | 71.78 | 27 |
+|si.bit | 44100 | 135936 | 3.082 | 24096223 | 7.817M | 72.35 | 36 |
+|si_block.bit | 44100 | 73728 | 1.671 | 20722017 | 12.394M | 71.84 | 26 |
+|si_huff.bit | 44100 | 86400 | 1.959 | 21121376 | 10.780M | 27.80 | 65535 |
+|sin1k0db.bit | 44100 | 730368 | 16.561 | 55569636 | 3.355M | 0.15 | 58814 |
+
+Keyj minimp3 conformance test fails on all vectors (PSNR < 96db), and free
+format is unsupported. This caused some problems when it was used
+[here](https://github.com/lieff/lvg), and was the main motivation for this work.
+
+## Usage
+
+First, we need to initialize the decoder structure:
+
+```c
+//#define MINIMP3_ONLY_MP3
+//#define MINIMP3_ONLY_SIMD
+//#define MINIMP3_NO_SIMD
+//#define MINIMP3_NONSTANDARD_BUT_LOGICAL
+//#define MINIMP3_FLOAT_OUTPUT
+#define MINIMP3_IMPLEMENTATION
+#include "minimp3.h"
+...
+ static mp3dec_t mp3d;
+ mp3dec_init(&mp3d);
+```
+
+Note that you must define ``MINIMP3_IMPLEMENTATION`` in exactly one source file.
+You can ``#include`` ``minimp3.h`` in as many files as you like.
+Also you can use ``MINIMP3_ONLY_MP3`` define to strip MP1/MP2 decoding code.
+MINIMP3_ONLY_SIMD define controls generic (non SSE/NEON) code generation (always enabled on x64/arm64 targets).
+In case you do not want any platform-specific SIMD optimizations, you can define ``MINIMP3_NO_SIMD``.
+MINIMP3_NONSTANDARD_BUT_LOGICAL define saves some code bytes, and enforces non-standard but logical behaviour of mono-stereo transition (rare case).
+MINIMP3_FLOAT_OUTPUT makes ``mp3dec_decode_frame()`` output to be float instead of short and additional function mp3dec_f32_to_s16 will be available for float->short conversion if needed.
+
+Then. we decode the input stream frame-by-frame:
+
+```c
+ /*typedef struct
+ {
+ int frame_bytes;
+ int channels;
+ int hz;
+ int layer;
+ int bitrate_kbps;
+ } mp3dec_frame_info_t;*/
+ mp3dec_frame_info_t info;
+ short pcm[MINIMP3_MAX_SAMPLES_PER_FRAME];
+ /*unsigned char *input_buf; - input byte stream*/
+ samples = mp3dec_decode_frame(&mp3d, input_buf, buf_size, pcm, &info);
+```
+
+The ``mp3dec_decode_frame()`` function decodes one full MP3 frame from the
+input buffer, which must be large enough to hold one full frame.
+
+The decoder will analyze the input buffer to properly sync with the MP3 stream,
+and will skip ID3 data, as well as any data which is not valid. Short buffers
+may cause false sync and can produce 'squealing' artefacts. The bigger the size
+of the input buffer, the more reliable the sync procedure. We recommend having
+as many as 10 consecutive MP3 frames (~16KB) in the input buffer at a time.
+
+At end of stream just pass rest of the buffer, sync procedure should work even
+with just 1 frame in stream (except for free format and garbage at the end can
+mess things up, so id3v1 and ape tags must be removed first).
+
+For free format there minimum 3 frames needed to do proper sync: 2 frames to
+detect frame length and 1 next frame to check detect is good.
+
+The size of the consumed MP3 data is returned in the ``mp3dec_frame_info_t``
+field of the ``frame_bytes`` struct; you must remove the data corresponding to
+the ``frame_bytes`` field from the input buffer before the next decoder
+invocation.
+
+The decoding function returns the number of decoded samples. The following cases
+are possible:
+
+- **0:** No MP3 data was found in the input buffer
+- **384:** Layer 1
+- **576:** MPEG 2 Layer 3
+- **1152:** Otherwise
+
+The following is a description of the possible combinations of the number of
+samples and ``frame_bytes`` field values:
+
+- More than 0 samples and ``frame_bytes > 0``: Succesful decode
+- 0 samples and ``frame_bytes > 0``: The decoder skipped ID3 or invalid data
+- 0 samples and ``frame_bytes == 0``: Insufficient data
+
+If ``frame_bytes == 0``, the other fields may be uninitialized or unchanged; if
+``frame_bytes != 0``, the other fields are available. The application may call
+``mp3dec_init()`` when changing decode position, but this is not necessary.
+
+As a special case, the decoder supports already split MP3 streams (for example,
+after doing an MP4 demux). In this case, the input buffer must contain _exactly
+one_ non-free-format frame.
+
+## Seeking
+
+You can seek to any byte in the stream and call ``mp3dec_decode_frame``; this
+will work in almost all cases, but is not completely guaranteed. Probablility of
+sync procedure failure lowers when MAX_FRAME_SYNC_MATCHES value grows. Default
+MAX_FRAME_SYNC_MATCHES=10 and probablility of sync failure should be very low.
+If granule data is accidentally detected as a valid MP3 header, short audio artefacting is
+possible.
+
+High-level mp3dec_ex_seek function supports precise seek to sample (MP3D_SEEK_TO_SAMPLE)
+using index and binary search.
+
+## Track length detect
+
+If the file is known to be cbr, then all frames have equal size and
+lack ID3 tags, which allows us to decode the first frame and calculate all frame
+positions as ``frame_bytes * N``. However, because of padding, frames can differ
+in size even in this case.
+
+In general case whole stream scan is needed to calculate it's length. Scan can be
+omitted if vbr tag is present (added by encoders like lame and ffmpeg), which contains
+length info. High-level functions automatically use the vbr tag if present.
+
+## High-level API
+
+If you need only decode file/buffer or use precise seek, you can use optional high-level API.
+Just ``#include`` ``minimp3_ex.h`` instead and use following additional functions:
+
+```c
+#define MP3D_SEEK_TO_BYTE 0
+#define MP3D_SEEK_TO_SAMPLE 1
+
+#define MINIMP3_PREDECODE_FRAMES 2 /* frames to pre-decode and skip after seek (to fill internal structures) */
+/*#define MINIMP3_SEEK_IDX_LINEAR_SEARCH*/ /* define to use linear index search instead of binary search on seek */
+#define MINIMP3_IO_SIZE (128*1024) /* io buffer size for streaming functions, must be greater than MINIMP3_BUF_SIZE */
+#define MINIMP3_BUF_SIZE (16*1024) /* buffer which can hold minimum 10 consecutive mp3 frames (~16KB) worst case */
+#define MINIMP3_ENABLE_RING 0 /* enable hardware magic ring buffer if available, to make less input buffer memmove(s) in callback IO mode */
+
+#define MP3D_E_MEMORY -1
+#define MP3D_E_IOERROR -2
+
+typedef struct
+{
+ mp3d_sample_t *buffer;
+ size_t samples; /* channels included, byte size = samples*sizeof(mp3d_sample_t) */
+ int channels, hz, layer, avg_bitrate_kbps;
+} mp3dec_file_info_t;
+
+typedef size_t (*MP3D_READ_CB)(void *buf, size_t size, void *user_data);
+typedef int (*MP3D_SEEK_CB)(uint64_t position, void *user_data);
+
+typedef struct
+{
+ MP3D_READ_CB read;
+ void *read_data;
+ MP3D_SEEK_CB seek;
+ void *seek_data;
+} mp3dec_io_t;
+
+typedef struct
+{
+ uint64_t samples;
+ mp3dec_frame_info_t info;
+ int last_error;
+ ...
+} mp3dec_ex_t;
+
+typedef int (*MP3D_ITERATE_CB)(void *user_data, const uint8_t *frame, int frame_size, int free_format_bytes, size_t buf_size, uint64_t offset, mp3dec_frame_info_t *info);
+typedef int (*MP3D_PROGRESS_CB)(void *user_data, size_t file_size, uint64_t offset, mp3dec_frame_info_t *info);
+
+/* decode whole buffer block */
+int mp3dec_load_buf(mp3dec_t *dec, const uint8_t *buf, size_t buf_size, mp3dec_file_info_t *info, MP3D_PROGRESS_CB progress_cb, void *user_data);
+int mp3dec_load_cb(mp3dec_t *dec, mp3dec_io_t *io, uint8_t *buf, size_t buf_size, mp3dec_file_info_t *info, MP3D_PROGRESS_CB progress_cb, void *user_data);
+/* iterate through frames */
+int mp3dec_iterate_buf(const uint8_t *buf, size_t buf_size, MP3D_ITERATE_CB callback, void *user_data);
+int mp3dec_iterate_cb(mp3dec_io_t *io, uint8_t *buf, size_t buf_size, MP3D_ITERATE_CB callback, void *user_data);
+/* streaming decoder with seeking capability */
+int mp3dec_ex_open_buf(mp3dec_ex_t *dec, const uint8_t *buf, size_t buf_size, int seek_method);
+int mp3dec_ex_open_cb(mp3dec_ex_t *dec, mp3dec_io_t *io, int seek_method);
+void mp3dec_ex_close(mp3dec_ex_t *dec);
+int mp3dec_ex_seek(mp3dec_ex_t *dec, uint64_t position);
+size_t mp3dec_ex_read(mp3dec_ex_t *dec, mp3d_sample_t *buf, size_t samples);
+#ifndef MINIMP3_NO_STDIO
+/* stdio versions of file load, iterate and stream */
+int mp3dec_load(mp3dec_t *dec, const char *file_name, mp3dec_file_info_t *info, MP3D_PROGRESS_CB progress_cb, void *user_data);
+int mp3dec_iterate(const char *file_name, MP3D_ITERATE_CB callback, void *user_data);
+int mp3dec_ex_open(mp3dec_ex_t *dec, const char *file_name, int seek_method);
+#ifdef _WIN32
+int mp3dec_load_w(mp3dec_t *dec, const wchar_t *file_name, mp3dec_file_info_t *info, MP3D_PROGRESS_CB progress_cb, void *user_data);
+int mp3dec_iterate_w(const wchar_t *file_name, MP3D_ITERATE_CB callback, void *user_data);
+int mp3dec_ex_open_w(mp3dec_ex_t *dec, const wchar_t *file_name, int seek_method);
+#endif
+#endif
+```
+
+Use MINIMP3_NO_STDIO define to exclude STDIO functions.
+MINIMP3_ALLOW_MONO_STEREO_TRANSITION allows mixing mono and stereo in same file.
+In that case ``mp3dec_frame_info_t->channels = 0`` is reported on such files and correct channels number passed to progress_cb callback for each frame in mp3dec_frame_info_t structure.
+MP3D_PROGRESS_CB is optional and can be NULL, example of file decoding:
+
+```c
+ mp3dec_t mp3d;
+ mp3dec_file_info_t info;
+ if (mp3dec_load(&mp3d, input_file_name, &info, NULL, NULL))
+ {
+ /* error */
+ }
+ /* mp3dec_file_info_t contains decoded samples and info,
+ use free(info.buffer) to deallocate samples */
+```
+
+Example of file decoding with seek capability:
+
+```c
+ mp3dec_ex_t dec;
+ if (mp3dec_ex_open(&dec, input_file_name, MP3D_SEEK_TO_SAMPLE))
+ {
+ /* error */
+ }
+ /* dec.samples, dec.info.hz, dec.info.layer, dec.info.channels should be filled */
+ if (mp3dec_ex_seek(&dec, position))
+ {
+ /* error */
+ }
+ mp3d_sample_t *buffer = malloc(dec.samples*sizeof(mp3d_sample_t));
+ size_t readed = mp3dec_ex_read(&dec, buffer, dec.samples);
+ if (readed != dec.samples) /* normal eof or error condition */
+ {
+ if (dec.last_error)
+ {
+ /* error */
+ }
+ }
+```
+
+## Bindings
+
+ * https://github.com/tosone/minimp3 - go bindings
+ * https://github.com/notviri/rmp3 - rust `no_std` bindings which don't allocate.
+ * https://github.com/germangb/minimp3-rs - rust bindings
+ * https://github.com/johangu/node-minimp3 - NodeJS bindings
+ * https://github.com/pyminimp3/pyminimp3 - python bindings
+ * https://github.com/bashi/minimp3-wasm - wasm bindings
+ * https://github.com/DasZiesel/minimp3-delphi - delphi bindings
+ * https://github.com/mgeier/minimp3_ex-sys - low-level rust bindings to `minimp3_ex`
+
+## Interesting links
+
+ * https://keyj.emphy.de/minimp3/
+ * https://github.com/technosaurus/PDMP3
+ * https://github.com/technosaurus/PDMP2
+ * https://github.com/packjpg/packMP3
+ * https://sites.google.com/a/kmlager.com/www/projects
+ * https://sourceforge.net/projects/mp3dec/
+ * http://blog.bjrn.se/2008/10/lets-build-mp3-decoder.html
+ * http://www.mp3-converter.com/mp3codec/
+ * http://www.multiweb.cz/twoinches/mp3inside.htm
+ * https://www.mp3-tech.org/
+ * https://id3.org/mp3Frame
+ * https://www.datavoyage.com/mpgscript/mpeghdr.htm
diff --git a/src/codecs/minimp3/minimp3.h b/src/codecs/minimp3/minimp3.h
new file mode 100644
index 000000000..3220ae1a8
--- /dev/null
+++ b/src/codecs/minimp3/minimp3.h
@@ -0,0 +1,1865 @@
+#ifndef MINIMP3_H
+#define MINIMP3_H
+/*
+ https://github.com/lieff/minimp3
+ To the extent possible under law, the author(s) have dedicated all copyright and related and neighboring rights to this software to the public domain worldwide.
+ This software is distributed without any warranty.
+ See .
+*/
+#include
+
+#define MINIMP3_MAX_SAMPLES_PER_FRAME (1152*2)
+
+typedef struct
+{
+ int frame_bytes, frame_offset, channels, hz, layer, bitrate_kbps;
+} mp3dec_frame_info_t;
+
+typedef struct
+{
+ float mdct_overlap[2][9*32], qmf_state[15*2*32];
+ int reserv, free_format_bytes;
+ unsigned char header[4], reserv_buf[511];
+} mp3dec_t;
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+void mp3dec_init(mp3dec_t *dec);
+#ifndef MINIMP3_FLOAT_OUTPUT
+typedef int16_t mp3d_sample_t;
+#else /* MINIMP3_FLOAT_OUTPUT */
+typedef float mp3d_sample_t;
+void mp3dec_f32_to_s16(const float *in, int16_t *out, int num_samples);
+#endif /* MINIMP3_FLOAT_OUTPUT */
+int mp3dec_decode_frame(mp3dec_t *dec, const uint8_t *mp3, int mp3_bytes, mp3d_sample_t *pcm, mp3dec_frame_info_t *info);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* MINIMP3_H */
+#if defined(MINIMP3_IMPLEMENTATION) && !defined(_MINIMP3_IMPLEMENTATION_GUARD)
+#define _MINIMP3_IMPLEMENTATION_GUARD
+
+#include
+#include
+
+#define MAX_FREE_FORMAT_FRAME_SIZE 2304 /* more than ISO spec's */
+#ifndef MAX_FRAME_SYNC_MATCHES
+#define MAX_FRAME_SYNC_MATCHES 10
+#endif /* MAX_FRAME_SYNC_MATCHES */
+
+#define MAX_L3_FRAME_PAYLOAD_BYTES MAX_FREE_FORMAT_FRAME_SIZE /* MUST be >= 320000/8/32000*1152 = 1440 */
+
+#define MAX_BITRESERVOIR_BYTES 511
+#define SHORT_BLOCK_TYPE 2
+#define STOP_BLOCK_TYPE 3
+#define MODE_MONO 3
+#define MODE_JOINT_STEREO 1
+#define HDR_SIZE 4
+#define HDR_IS_MONO(h) (((h[3]) & 0xC0) == 0xC0)
+#define HDR_IS_MS_STEREO(h) (((h[3]) & 0xE0) == 0x60)
+#define HDR_IS_FREE_FORMAT(h) (((h[2]) & 0xF0) == 0)
+#define HDR_IS_CRC(h) (!((h[1]) & 1))
+#define HDR_TEST_PADDING(h) ((h[2]) & 0x2)
+#define HDR_TEST_MPEG1(h) ((h[1]) & 0x8)
+#define HDR_TEST_NOT_MPEG25(h) ((h[1]) & 0x10)
+#define HDR_TEST_I_STEREO(h) ((h[3]) & 0x10)
+#define HDR_TEST_MS_STEREO(h) ((h[3]) & 0x20)
+#define HDR_GET_STEREO_MODE(h) (((h[3]) >> 6) & 3)
+#define HDR_GET_STEREO_MODE_EXT(h) (((h[3]) >> 4) & 3)
+#define HDR_GET_LAYER(h) (((h[1]) >> 1) & 3)
+#define HDR_GET_BITRATE(h) ((h[2]) >> 4)
+#define HDR_GET_SAMPLE_RATE(h) (((h[2]) >> 2) & 3)
+#define HDR_GET_MY_SAMPLE_RATE(h) (HDR_GET_SAMPLE_RATE(h) + (((h[1] >> 3) & 1) + ((h[1] >> 4) & 1))*3)
+#define HDR_IS_FRAME_576(h) ((h[1] & 14) == 2)
+#define HDR_IS_LAYER_1(h) ((h[1] & 6) == 6)
+
+#define BITS_DEQUANTIZER_OUT -1
+#define MAX_SCF (255 + BITS_DEQUANTIZER_OUT*4 - 210)
+#define MAX_SCFI ((MAX_SCF + 3) & ~3)
+
+#define MINIMP3_MIN(a, b) ((a) > (b) ? (b) : (a))
+#define MINIMP3_MAX(a, b) ((a) < (b) ? (b) : (a))
+
+#if !defined(MINIMP3_NO_SIMD)
+
+#if !defined(MINIMP3_ONLY_SIMD) && (defined(_M_X64) || defined(__x86_64__) || defined(__aarch64__) || defined(_M_ARM64))
+/* x64 always have SSE2, arm64 always have neon, no need for generic code */
+#define MINIMP3_ONLY_SIMD
+#endif /* SIMD checks... */
+
+#if (defined(_MSC_VER) && (defined(_M_IX86) || defined(_M_X64))) || ((defined(__i386__) || defined(__x86_64__)) && defined(__SSE2__))
+#if defined(_MSC_VER)
+#include
+#endif /* defined(_MSC_VER) */
+#include
+#define HAVE_SSE 1
+#define HAVE_SIMD 1
+#define VSTORE _mm_storeu_ps
+#define VLD _mm_loadu_ps
+#define VSET _mm_set1_ps
+#define VADD _mm_add_ps
+#define VSUB _mm_sub_ps
+#define VMUL _mm_mul_ps
+#define VMAC(a, x, y) _mm_add_ps(a, _mm_mul_ps(x, y))
+#define VMSB(a, x, y) _mm_sub_ps(a, _mm_mul_ps(x, y))
+#define VMUL_S(x, s) _mm_mul_ps(x, _mm_set1_ps(s))
+#define VREV(x) _mm_shuffle_ps(x, x, _MM_SHUFFLE(0, 1, 2, 3))
+typedef __m128 f4;
+#if defined(_MSC_VER) || defined(MINIMP3_ONLY_SIMD)
+#define minimp3_cpuid __cpuid
+#else /* defined(_MSC_VER) || defined(MINIMP3_ONLY_SIMD) */
+static __inline__ __attribute__((always_inline)) void minimp3_cpuid(int CPUInfo[], const int InfoType)
+{
+#if defined(__PIC__)
+ __asm__ __volatile__(
+#if defined(__x86_64__)
+ "push %%rbx\n"
+ "cpuid\n"
+ "xchgl %%ebx, %1\n"
+ "pop %%rbx\n"
+#else /* defined(__x86_64__) */
+ "xchgl %%ebx, %1\n"
+ "cpuid\n"
+ "xchgl %%ebx, %1\n"
+#endif /* defined(__x86_64__) */
+ : "=a" (CPUInfo[0]), "=r" (CPUInfo[1]), "=c" (CPUInfo[2]), "=d" (CPUInfo[3])
+ : "a" (InfoType));
+#else /* defined(__PIC__) */
+ __asm__ __volatile__(
+ "cpuid"
+ : "=a" (CPUInfo[0]), "=b" (CPUInfo[1]), "=c" (CPUInfo[2]), "=d" (CPUInfo[3])
+ : "a" (InfoType));
+#endif /* defined(__PIC__)*/
+}
+#endif /* defined(_MSC_VER) || defined(MINIMP3_ONLY_SIMD) */
+static int have_simd(void)
+{
+#ifdef MINIMP3_ONLY_SIMD
+ return 1;
+#else /* MINIMP3_ONLY_SIMD */
+ static int g_have_simd;
+ int CPUInfo[4];
+#ifdef MINIMP3_TEST
+ static int g_counter;
+ if (g_counter++ > 100)
+ return 0;
+#endif /* MINIMP3_TEST */
+ if (g_have_simd)
+ goto end;
+ minimp3_cpuid(CPUInfo, 0);
+ g_have_simd = 1;
+ if (CPUInfo[0] > 0)
+ {
+ minimp3_cpuid(CPUInfo, 1);
+ g_have_simd = (CPUInfo[3] & (1 << 26)) + 1; /* SSE2 */
+ }
+end:
+ return g_have_simd - 1;
+#endif /* MINIMP3_ONLY_SIMD */
+}
+#elif defined(__ARM_NEON) || defined(__aarch64__) || defined(_M_ARM64)
+#include
+#define HAVE_SSE 0
+#define HAVE_SIMD 1
+#define VSTORE vst1q_f32
+#define VLD vld1q_f32
+#define VSET vmovq_n_f32
+#define VADD vaddq_f32
+#define VSUB vsubq_f32
+#define VMUL vmulq_f32
+#define VMAC(a, x, y) vmlaq_f32(a, x, y)
+#define VMSB(a, x, y) vmlsq_f32(a, x, y)
+#define VMUL_S(x, s) vmulq_f32(x, vmovq_n_f32(s))
+#define VREV(x) vcombine_f32(vget_high_f32(vrev64q_f32(x)), vget_low_f32(vrev64q_f32(x)))
+typedef float32x4_t f4;
+static int have_simd()
+{ /* TODO: detect neon for !MINIMP3_ONLY_SIMD */
+ return 1;
+}
+#else /* SIMD checks... */
+#define HAVE_SSE 0
+#define HAVE_SIMD 0
+#ifdef MINIMP3_ONLY_SIMD
+#error MINIMP3_ONLY_SIMD used, but SSE/NEON not enabled
+#endif /* MINIMP3_ONLY_SIMD */
+#endif /* SIMD checks... */
+#else /* !defined(MINIMP3_NO_SIMD) */
+#define HAVE_SIMD 0
+#endif /* !defined(MINIMP3_NO_SIMD) */
+
+#if defined(__ARM_ARCH) && (__ARM_ARCH >= 6) && !defined(__aarch64__) && !defined(_M_ARM64)
+#define HAVE_ARMV6 1
+static __inline__ __attribute__((always_inline)) int32_t minimp3_clip_int16_arm(int32_t a)
+{
+ int32_t x = 0;
+ __asm__ ("ssat %0, #16, %1" : "=r"(x) : "r"(a));
+ return x;
+}
+#else
+#define HAVE_ARMV6 0
+#endif
+
+typedef struct
+{
+ const uint8_t *buf;
+ int pos, limit;
+} bs_t;
+
+typedef struct
+{
+ float scf[3*64];
+ uint8_t total_bands, stereo_bands, bitalloc[64], scfcod[64];
+} L12_scale_info;
+
+typedef struct
+{
+ uint8_t tab_offset, code_tab_width, band_count;
+} L12_subband_alloc_t;
+
+typedef struct
+{
+ const uint8_t *sfbtab;
+ uint16_t part_23_length, big_values, scalefac_compress;
+ uint8_t global_gain, block_type, mixed_block_flag, n_long_sfb, n_short_sfb;
+ uint8_t table_select[3], region_count[3], subblock_gain[3];
+ uint8_t preflag, scalefac_scale, count1_table, scfsi;
+} L3_gr_info_t;
+
+typedef struct
+{
+ bs_t bs;
+ uint8_t maindata[MAX_BITRESERVOIR_BYTES + MAX_L3_FRAME_PAYLOAD_BYTES];
+ L3_gr_info_t gr_info[4];
+ float grbuf[2][576], scf[40], syn[18 + 15][2*32];
+ uint8_t ist_pos[2][39];
+} mp3dec_scratch_t;
+
+static void bs_init(bs_t *bs, const uint8_t *data, int bytes)
+{
+ bs->buf = data;
+ bs->pos = 0;
+ bs->limit = bytes*8;
+}
+
+static uint32_t get_bits(bs_t *bs, int n)
+{
+ uint32_t next, cache = 0, s = bs->pos & 7;
+ int shl = n + s;
+ const uint8_t *p = bs->buf + (bs->pos >> 3);
+ if ((bs->pos += n) > bs->limit)
+ return 0;
+ next = *p++ & (255 >> s);
+ while ((shl -= 8) > 0)
+ {
+ cache |= next << shl;
+ next = *p++;
+ }
+ return cache | (next >> -shl);
+}
+
+static int hdr_valid(const uint8_t *h)
+{
+ return h[0] == 0xff &&
+ ((h[1] & 0xF0) == 0xf0 || (h[1] & 0xFE) == 0xe2) &&
+ (HDR_GET_LAYER(h) != 0) &&
+ (HDR_GET_BITRATE(h) != 15) &&
+ (HDR_GET_SAMPLE_RATE(h) != 3);
+}
+
+static int hdr_compare(const uint8_t *h1, const uint8_t *h2)
+{
+ return hdr_valid(h2) &&
+ ((h1[1] ^ h2[1]) & 0xFE) == 0 &&
+ ((h1[2] ^ h2[2]) & 0x0C) == 0 &&
+ !(HDR_IS_FREE_FORMAT(h1) ^ HDR_IS_FREE_FORMAT(h2));
+}
+
+static unsigned hdr_bitrate_kbps(const uint8_t *h)
+{
+ static const uint8_t halfrate[2][3][15] = {
+ { { 0,4,8,12,16,20,24,28,32,40,48,56,64,72,80 }, { 0,4,8,12,16,20,24,28,32,40,48,56,64,72,80 }, { 0,16,24,28,32,40,48,56,64,72,80,88,96,112,128 } },
+ { { 0,16,20,24,28,32,40,48,56,64,80,96,112,128,160 }, { 0,16,24,28,32,40,48,56,64,80,96,112,128,160,192 }, { 0,16,32,48,64,80,96,112,128,144,160,176,192,208,224 } },
+ };
+ return 2*halfrate[!!HDR_TEST_MPEG1(h)][HDR_GET_LAYER(h) - 1][HDR_GET_BITRATE(h)];
+}
+
+static unsigned hdr_sample_rate_hz(const uint8_t *h)
+{
+ static const unsigned g_hz[3] = { 44100, 48000, 32000 };
+ return g_hz[HDR_GET_SAMPLE_RATE(h)] >> (int)!HDR_TEST_MPEG1(h) >> (int)!HDR_TEST_NOT_MPEG25(h);
+}
+
+static unsigned hdr_frame_samples(const uint8_t *h)
+{
+ return HDR_IS_LAYER_1(h) ? 384 : (1152 >> (int)HDR_IS_FRAME_576(h));
+}
+
+static int hdr_frame_bytes(const uint8_t *h, int free_format_size)
+{
+ int frame_bytes = hdr_frame_samples(h)*hdr_bitrate_kbps(h)*125/hdr_sample_rate_hz(h);
+ if (HDR_IS_LAYER_1(h))
+ {
+ frame_bytes &= ~3; /* slot align */
+ }
+ return frame_bytes ? frame_bytes : free_format_size;
+}
+
+static int hdr_padding(const uint8_t *h)
+{
+ return HDR_TEST_PADDING(h) ? (HDR_IS_LAYER_1(h) ? 4 : 1) : 0;
+}
+
+#ifndef MINIMP3_ONLY_MP3
+static const L12_subband_alloc_t *L12_subband_alloc_table(const uint8_t *hdr, L12_scale_info *sci)
+{
+ const L12_subband_alloc_t *alloc;
+ int mode = HDR_GET_STEREO_MODE(hdr);
+ int nbands, stereo_bands = (mode == MODE_MONO) ? 0 : (mode == MODE_JOINT_STEREO) ? (HDR_GET_STEREO_MODE_EXT(hdr) << 2) + 4 : 32;
+
+ if (HDR_IS_LAYER_1(hdr))
+ {
+ static const L12_subband_alloc_t g_alloc_L1[] = { { 76, 4, 32 } };
+ alloc = g_alloc_L1;
+ nbands = 32;
+ } else if (!HDR_TEST_MPEG1(hdr))
+ {
+ static const L12_subband_alloc_t g_alloc_L2M2[] = { { 60, 4, 4 }, { 44, 3, 7 }, { 44, 2, 19 } };
+ alloc = g_alloc_L2M2;
+ nbands = 30;
+ } else
+ {
+ static const L12_subband_alloc_t g_alloc_L2M1[] = { { 0, 4, 3 }, { 16, 4, 8 }, { 32, 3, 12 }, { 40, 2, 7 } };
+ int sample_rate_idx = HDR_GET_SAMPLE_RATE(hdr);
+ unsigned kbps = hdr_bitrate_kbps(hdr) >> (int)(mode != MODE_MONO);
+ if (!kbps) /* free-format */
+ {
+ kbps = 192;
+ }
+
+ alloc = g_alloc_L2M1;
+ nbands = 27;
+ if (kbps < 56)
+ {
+ static const L12_subband_alloc_t g_alloc_L2M1_lowrate[] = { { 44, 4, 2 }, { 44, 3, 10 } };
+ alloc = g_alloc_L2M1_lowrate;
+ nbands = sample_rate_idx == 2 ? 12 : 8;
+ } else if (kbps >= 96 && sample_rate_idx != 1)
+ {
+ nbands = 30;
+ }
+ }
+
+ sci->total_bands = (uint8_t)nbands;
+ sci->stereo_bands = (uint8_t)MINIMP3_MIN(stereo_bands, nbands);
+
+ return alloc;
+}
+
+static void L12_read_scalefactors(bs_t *bs, uint8_t *pba, uint8_t *scfcod, int bands, float *scf)
+{
+ static const float g_deq_L12[18*3] = {
+#define DQ(x) 9.53674316e-07f/x, 7.56931807e-07f/x, 6.00777173e-07f/x
+ DQ(3),DQ(7),DQ(15),DQ(31),DQ(63),DQ(127),DQ(255),DQ(511),DQ(1023),DQ(2047),DQ(4095),DQ(8191),DQ(16383),DQ(32767),DQ(65535),DQ(3),DQ(5),DQ(9)
+ };
+ int i, m;
+ for (i = 0; i < bands; i++)
+ {
+ float s = 0;
+ int ba = *pba++;
+ int mask = ba ? 4 + ((19 >> scfcod[i]) & 3) : 0;
+ for (m = 4; m; m >>= 1)
+ {
+ if (mask & m)
+ {
+ int b = get_bits(bs, 6);
+ s = g_deq_L12[ba*3 - 6 + b % 3]*(1 << 21 >> b/3);
+ }
+ *scf++ = s;
+ }
+ }
+}
+
+static void L12_read_scale_info(const uint8_t *hdr, bs_t *bs, L12_scale_info *sci)
+{
+ static const uint8_t g_bitalloc_code_tab[] = {
+ 0,17, 3, 4, 5,6,7, 8,9,10,11,12,13,14,15,16,
+ 0,17,18, 3,19,4,5, 6,7, 8, 9,10,11,12,13,16,
+ 0,17,18, 3,19,4,5,16,
+ 0,17,18,16,
+ 0,17,18,19, 4,5,6, 7,8, 9,10,11,12,13,14,15,
+ 0,17,18, 3,19,4,5, 6,7, 8, 9,10,11,12,13,14,
+ 0, 2, 3, 4, 5,6,7, 8,9,10,11,12,13,14,15,16
+ };
+ const L12_subband_alloc_t *subband_alloc = L12_subband_alloc_table(hdr, sci);
+
+ int i, k = 0, ba_bits = 0;
+ const uint8_t *ba_code_tab = g_bitalloc_code_tab;
+
+ for (i = 0; i < sci->total_bands; i++)
+ {
+ uint8_t ba;
+ if (i == k)
+ {
+ k += subband_alloc->band_count;
+ ba_bits = subband_alloc->code_tab_width;
+ ba_code_tab = g_bitalloc_code_tab + subband_alloc->tab_offset;
+ subband_alloc++;
+ }
+ ba = ba_code_tab[get_bits(bs, ba_bits)];
+ sci->bitalloc[2*i] = ba;
+ if (i < sci->stereo_bands)
+ {
+ ba = ba_code_tab[get_bits(bs, ba_bits)];
+ }
+ sci->bitalloc[2*i + 1] = sci->stereo_bands ? ba : 0;
+ }
+
+ for (i = 0; i < 2*sci->total_bands; i++)
+ {
+ sci->scfcod[i] = sci->bitalloc[i] ? HDR_IS_LAYER_1(hdr) ? 2 : get_bits(bs, 2) : 6;
+ }
+
+ L12_read_scalefactors(bs, sci->bitalloc, sci->scfcod, sci->total_bands*2, sci->scf);
+
+ for (i = sci->stereo_bands; i < sci->total_bands; i++)
+ {
+ sci->bitalloc[2*i + 1] = 0;
+ }
+}
+
+static int L12_dequantize_granule(float *grbuf, bs_t *bs, L12_scale_info *sci, int group_size)
+{
+ int i, j, k, choff = 576;
+ for (j = 0; j < 4; j++)
+ {
+ float *dst = grbuf + group_size*j;
+ for (i = 0; i < 2*sci->total_bands; i++)
+ {
+ int ba = sci->bitalloc[i];
+ if (ba != 0)
+ {
+ if (ba < 17)
+ {
+ int half = (1 << (ba - 1)) - 1;
+ for (k = 0; k < group_size; k++)
+ {
+ dst[k] = (float)((int)get_bits(bs, ba) - half);
+ }
+ } else
+ {
+ unsigned mod = (2 << (ba - 17)) + 1; /* 3, 5, 9 */
+ unsigned code = get_bits(bs, mod + 2 - (mod >> 3)); /* 5, 7, 10 */
+ for (k = 0; k < group_size; k++, code /= mod)
+ {
+ dst[k] = (float)((int)(code % mod - mod/2));
+ }
+ }
+ }
+ dst += choff;
+ choff = 18 - choff;
+ }
+ }
+ return group_size*4;
+}
+
+static void L12_apply_scf_384(L12_scale_info *sci, const float *scf, float *dst)
+{
+ int i, k;
+ memcpy(dst + 576 + sci->stereo_bands*18, dst + sci->stereo_bands*18, (sci->total_bands - sci->stereo_bands)*18*sizeof(float));
+ for (i = 0; i < sci->total_bands; i++, dst += 18, scf += 6)
+ {
+ for (k = 0; k < 12; k++)
+ {
+ dst[k + 0] *= scf[0];
+ dst[k + 576] *= scf[3];
+ }
+ }
+}
+#endif /* MINIMP3_ONLY_MP3 */
+
+static int L3_read_side_info(bs_t *bs, L3_gr_info_t *gr, const uint8_t *hdr)
+{
+ static const uint8_t g_scf_long[8][23] = {
+ { 6,6,6,6,6,6,8,10,12,14,16,20,24,28,32,38,46,52,60,68,58,54,0 },
+ { 12,12,12,12,12,12,16,20,24,28,32,40,48,56,64,76,90,2,2,2,2,2,0 },
+ { 6,6,6,6,6,6,8,10,12,14,16,20,24,28,32,38,46,52,60,68,58,54,0 },
+ { 6,6,6,6,6,6,8,10,12,14,16,18,22,26,32,38,46,54,62,70,76,36,0 },
+ { 6,6,6,6,6,6,8,10,12,14,16,20,24,28,32,38,46,52,60,68,58,54,0 },
+ { 4,4,4,4,4,4,6,6,8,8,10,12,16,20,24,28,34,42,50,54,76,158,0 },
+ { 4,4,4,4,4,4,6,6,6,8,10,12,16,18,22,28,34,40,46,54,54,192,0 },
+ { 4,4,4,4,4,4,6,6,8,10,12,16,20,24,30,38,46,56,68,84,102,26,0 }
+ };
+ static const uint8_t g_scf_short[8][40] = {
+ { 4,4,4,4,4,4,4,4,4,6,6,6,8,8,8,10,10,10,12,12,12,14,14,14,18,18,18,24,24,24,30,30,30,40,40,40,18,18,18,0 },
+ { 8,8,8,8,8,8,8,8,8,12,12,12,16,16,16,20,20,20,24,24,24,28,28,28,36,36,36,2,2,2,2,2,2,2,2,2,26,26,26,0 },
+ { 4,4,4,4,4,4,4,4,4,6,6,6,6,6,6,8,8,8,10,10,10,14,14,14,18,18,18,26,26,26,32,32,32,42,42,42,18,18,18,0 },
+ { 4,4,4,4,4,4,4,4,4,6,6,6,8,8,8,10,10,10,12,12,12,14,14,14,18,18,18,24,24,24,32,32,32,44,44,44,12,12,12,0 },
+ { 4,4,4,4,4,4,4,4,4,6,6,6,8,8,8,10,10,10,12,12,12,14,14,14,18,18,18,24,24,24,30,30,30,40,40,40,18,18,18,0 },
+ { 4,4,4,4,4,4,4,4,4,4,4,4,6,6,6,8,8,8,10,10,10,12,12,12,14,14,14,18,18,18,22,22,22,30,30,30,56,56,56,0 },
+ { 4,4,4,4,4,4,4,4,4,4,4,4,6,6,6,6,6,6,10,10,10,12,12,12,14,14,14,16,16,16,20,20,20,26,26,26,66,66,66,0 },
+ { 4,4,4,4,4,4,4,4,4,4,4,4,6,6,6,8,8,8,12,12,12,16,16,16,20,20,20,26,26,26,34,34,34,42,42,42,12,12,12,0 }
+ };
+ static const uint8_t g_scf_mixed[8][40] = {
+ { 6,6,6,6,6,6,6,6,6,8,8,8,10,10,10,12,12,12,14,14,14,18,18,18,24,24,24,30,30,30,40,40,40,18,18,18,0 },
+ { 12,12,12,4,4,4,8,8,8,12,12,12,16,16,16,20,20,20,24,24,24,28,28,28,36,36,36,2,2,2,2,2,2,2,2,2,26,26,26,0 },
+ { 6,6,6,6,6,6,6,6,6,6,6,6,8,8,8,10,10,10,14,14,14,18,18,18,26,26,26,32,32,32,42,42,42,18,18,18,0 },
+ { 6,6,6,6,6,6,6,6,6,8,8,8,10,10,10,12,12,12,14,14,14,18,18,18,24,24,24,32,32,32,44,44,44,12,12,12,0 },
+ { 6,6,6,6,6,6,6,6,6,8,8,8,10,10,10,12,12,12,14,14,14,18,18,18,24,24,24,30,30,30,40,40,40,18,18,18,0 },
+ { 4,4,4,4,4,4,6,6,4,4,4,6,6,6,8,8,8,10,10,10,12,12,12,14,14,14,18,18,18,22,22,22,30,30,30,56,56,56,0 },
+ { 4,4,4,4,4,4,6,6,4,4,4,6,6,6,6,6,6,10,10,10,12,12,12,14,14,14,16,16,16,20,20,20,26,26,26,66,66,66,0 },
+ { 4,4,4,4,4,4,6,6,4,4,4,6,6,6,8,8,8,12,12,12,16,16,16,20,20,20,26,26,26,34,34,34,42,42,42,12,12,12,0 }
+ };
+
+ unsigned tables, scfsi = 0;
+ int main_data_begin, part_23_sum = 0;
+ int sr_idx = HDR_GET_MY_SAMPLE_RATE(hdr); sr_idx -= (sr_idx != 0);
+ int gr_count = HDR_IS_MONO(hdr) ? 1 : 2;
+
+ if (HDR_TEST_MPEG1(hdr))
+ {
+ gr_count *= 2;
+ main_data_begin = get_bits(bs, 9);
+ scfsi = get_bits(bs, 7 + gr_count);
+ } else
+ {
+ main_data_begin = get_bits(bs, 8 + gr_count) >> gr_count;
+ }
+
+ do
+ {
+ if (HDR_IS_MONO(hdr))
+ {
+ scfsi <<= 4;
+ }
+ gr->part_23_length = (uint16_t)get_bits(bs, 12);
+ part_23_sum += gr->part_23_length;
+ gr->big_values = (uint16_t)get_bits(bs, 9);
+ if (gr->big_values > 288)
+ {
+ return -1;
+ }
+ gr->global_gain = (uint8_t)get_bits(bs, 8);
+ gr->scalefac_compress = (uint16_t)get_bits(bs, HDR_TEST_MPEG1(hdr) ? 4 : 9);
+ gr->sfbtab = g_scf_long[sr_idx];
+ gr->n_long_sfb = 22;
+ gr->n_short_sfb = 0;
+ if (get_bits(bs, 1))
+ {
+ gr->block_type = (uint8_t)get_bits(bs, 2);
+ if (!gr->block_type)
+ {
+ return -1;
+ }
+ gr->mixed_block_flag = (uint8_t)get_bits(bs, 1);
+ gr->region_count[0] = 7;
+ gr->region_count[1] = 255;
+ if (gr->block_type == SHORT_BLOCK_TYPE)
+ {
+ scfsi &= 0x0F0F;
+ if (!gr->mixed_block_flag)
+ {
+ gr->region_count[0] = 8;
+ gr->sfbtab = g_scf_short[sr_idx];
+ gr->n_long_sfb = 0;
+ gr->n_short_sfb = 39;
+ } else
+ {
+ gr->sfbtab = g_scf_mixed[sr_idx];
+ gr->n_long_sfb = HDR_TEST_MPEG1(hdr) ? 8 : 6;
+ gr->n_short_sfb = 30;
+ }
+ }
+ tables = get_bits(bs, 10);
+ tables <<= 5;
+ gr->subblock_gain[0] = (uint8_t)get_bits(bs, 3);
+ gr->subblock_gain[1] = (uint8_t)get_bits(bs, 3);
+ gr->subblock_gain[2] = (uint8_t)get_bits(bs, 3);
+ } else
+ {
+ gr->block_type = 0;
+ gr->mixed_block_flag = 0;
+ tables = get_bits(bs, 15);
+ gr->region_count[0] = (uint8_t)get_bits(bs, 4);
+ gr->region_count[1] = (uint8_t)get_bits(bs, 3);
+ gr->region_count[2] = 255;
+ }
+ gr->table_select[0] = (uint8_t)(tables >> 10);
+ gr->table_select[1] = (uint8_t)((tables >> 5) & 31);
+ gr->table_select[2] = (uint8_t)((tables) & 31);
+ gr->preflag = HDR_TEST_MPEG1(hdr) ? get_bits(bs, 1) : (gr->scalefac_compress >= 500);
+ gr->scalefac_scale = (uint8_t)get_bits(bs, 1);
+ gr->count1_table = (uint8_t)get_bits(bs, 1);
+ gr->scfsi = (uint8_t)((scfsi >> 12) & 15);
+ scfsi <<= 4;
+ gr++;
+ } while(--gr_count);
+
+ if (part_23_sum + bs->pos > bs->limit + main_data_begin*8)
+ {
+ return -1;
+ }
+
+ return main_data_begin;
+}
+
+static void L3_read_scalefactors(uint8_t *scf, uint8_t *ist_pos, const uint8_t *scf_size, const uint8_t *scf_count, bs_t *bitbuf, int scfsi)
+{
+ int i, k;
+ for (i = 0; i < 4 && scf_count[i]; i++, scfsi *= 2)
+ {
+ int cnt = scf_count[i];
+ if (scfsi & 8)
+ {
+ memcpy(scf, ist_pos, cnt);
+ } else
+ {
+ int bits = scf_size[i];
+ if (!bits)
+ {
+ memset(scf, 0, cnt);
+ memset(ist_pos, 0, cnt);
+ } else
+ {
+ int max_scf = (scfsi < 0) ? (1 << bits) - 1 : -1;
+ for (k = 0; k < cnt; k++)
+ {
+ int s = get_bits(bitbuf, bits);
+ ist_pos[k] = (s == max_scf ? -1 : s);
+ scf[k] = s;
+ }
+ }
+ }
+ ist_pos += cnt;
+ scf += cnt;
+ }
+ scf[0] = scf[1] = scf[2] = 0;
+}
+
+static float L3_ldexp_q2(float y, int exp_q2)
+{
+ static const float g_expfrac[4] = { 9.31322575e-10f,7.83145814e-10f,6.58544508e-10f,5.53767716e-10f };
+ int e;
+ do
+ {
+ e = MINIMP3_MIN(30*4, exp_q2);
+ y *= g_expfrac[e & 3]*(1 << 30 >> (e >> 2));
+ } while ((exp_q2 -= e) > 0);
+ return y;
+}
+
+static void L3_decode_scalefactors(const uint8_t *hdr, uint8_t *ist_pos, bs_t *bs, const L3_gr_info_t *gr, float *scf, int ch)
+{
+ static const uint8_t g_scf_partitions[3][28] = {
+ { 6,5,5, 5,6,5,5,5,6,5, 7,3,11,10,0,0, 7, 7, 7,0, 6, 6,6,3, 8, 8,5,0 },
+ { 8,9,6,12,6,9,9,9,6,9,12,6,15,18,0,0, 6,15,12,0, 6,12,9,6, 6,18,9,0 },
+ { 9,9,6,12,9,9,9,9,9,9,12,6,18,18,0,0,12,12,12,0,12, 9,9,6,15,12,9,0 }
+ };
+ const uint8_t *scf_partition = g_scf_partitions[!!gr->n_short_sfb + !gr->n_long_sfb];
+ uint8_t scf_size[4], iscf[40];
+ int i, scf_shift = gr->scalefac_scale + 1, gain_exp, scfsi = gr->scfsi;
+ float gain;
+
+ if (HDR_TEST_MPEG1(hdr))
+ {
+ static const uint8_t g_scfc_decode[16] = { 0,1,2,3, 12,5,6,7, 9,10,11,13, 14,15,18,19 };
+ int part = g_scfc_decode[gr->scalefac_compress];
+ scf_size[1] = scf_size[0] = (uint8_t)(part >> 2);
+ scf_size[3] = scf_size[2] = (uint8_t)(part & 3);
+ } else
+ {
+ static const uint8_t g_mod[6*4] = { 5,5,4,4,5,5,4,1,4,3,1,1,5,6,6,1,4,4,4,1,4,3,1,1 };
+ int k, modprod, sfc, ist = HDR_TEST_I_STEREO(hdr) && ch;
+ sfc = gr->scalefac_compress >> ist;
+ for (k = ist*3*4; sfc >= 0; sfc -= modprod, k += 4)
+ {
+ for (modprod = 1, i = 3; i >= 0; i--)
+ {
+ scf_size[i] = (uint8_t)(sfc / modprod % g_mod[k + i]);
+ modprod *= g_mod[k + i];
+ }
+ }
+ scf_partition += k;
+ scfsi = -16;
+ }
+ L3_read_scalefactors(iscf, ist_pos, scf_size, scf_partition, bs, scfsi);
+
+ if (gr->n_short_sfb)
+ {
+ int sh = 3 - scf_shift;
+ for (i = 0; i < gr->n_short_sfb; i += 3)
+ {
+ iscf[gr->n_long_sfb + i + 0] += gr->subblock_gain[0] << sh;
+ iscf[gr->n_long_sfb + i + 1] += gr->subblock_gain[1] << sh;
+ iscf[gr->n_long_sfb + i + 2] += gr->subblock_gain[2] << sh;
+ }
+ } else if (gr->preflag)
+ {
+ static const uint8_t g_preamp[10] = { 1,1,1,1,2,2,3,3,3,2 };
+ for (i = 0; i < 10; i++)
+ {
+ iscf[11 + i] += g_preamp[i];
+ }
+ }
+
+ gain_exp = gr->global_gain + BITS_DEQUANTIZER_OUT*4 - 210 - (HDR_IS_MS_STEREO(hdr) ? 2 : 0);
+ gain = L3_ldexp_q2(1 << (MAX_SCFI/4), MAX_SCFI - gain_exp);
+ for (i = 0; i < (int)(gr->n_long_sfb + gr->n_short_sfb); i++)
+ {
+ scf[i] = L3_ldexp_q2(gain, iscf[i] << scf_shift);
+ }
+}
+
+static const float g_pow43[129 + 16] = {
+ 0,-1,-2.519842f,-4.326749f,-6.349604f,-8.549880f,-10.902724f,-13.390518f,-16.000000f,-18.720754f,-21.544347f,-24.463781f,-27.473142f,-30.567351f,-33.741992f,-36.993181f,
+ 0,1,2.519842f,4.326749f,6.349604f,8.549880f,10.902724f,13.390518f,16.000000f,18.720754f,21.544347f,24.463781f,27.473142f,30.567351f,33.741992f,36.993181f,40.317474f,43.711787f,47.173345f,50.699631f,54.288352f,57.937408f,61.644865f,65.408941f,69.227979f,73.100443f,77.024898f,81.000000f,85.024491f,89.097188f,93.216975f,97.382800f,101.593667f,105.848633f,110.146801f,114.487321f,118.869381f,123.292209f,127.755065f,132.257246f,136.798076f,141.376907f,145.993119f,150.646117f,155.335327f,160.060199f,164.820202f,169.614826f,174.443577f,179.305980f,184.201575f,189.129918f,194.090580f,199.083145f,204.107210f,209.162385f,214.248292f,219.364564f,224.510845f,229.686789f,234.892058f,240.126328f,245.389280f,250.680604f,256.000000f,261.347174f,266.721841f,272.123723f,277.552547f,283.008049f,288.489971f,293.998060f,299.532071f,305.091761f,310.676898f,316.287249f,321.922592f,327.582707f,333.267377f,338.976394f,344.709550f,350.466646f,356.247482f,362.051866f,367.879608f,373.730522f,379.604427f,385.501143f,391.420496f,397.362314f,403.326427f,409.312672f,415.320884f,421.350905f,427.402579f,433.475750f,439.570269f,445.685987f,451.822757f,457.980436f,464.158883f,470.357960f,476.577530f,482.817459f,489.077615f,495.357868f,501.658090f,507.978156f,514.317941f,520.677324f,527.056184f,533.454404f,539.871867f,546.308458f,552.764065f,559.238575f,565.731879f,572.243870f,578.774440f,585.323483f,591.890898f,598.476581f,605.080431f,611.702349f,618.342238f,625.000000f,631.675540f,638.368763f,645.079578f
+};
+
+static float L3_pow_43(int x)
+{
+ float frac;
+ int sign, mult = 256;
+
+ if (x < 129)
+ {
+ return g_pow43[16 + x];
+ }
+
+ if (x < 1024)
+ {
+ mult = 16;
+ x <<= 3;
+ }
+
+ sign = 2*x & 64;
+ frac = (float)((x & 63) - sign) / ((x & ~63) + sign);
+ return g_pow43[16 + ((x + sign) >> 6)]*(1.f + frac*((4.f/3) + frac*(2.f/9)))*mult;
+}
+
+static void L3_huffman(float *dst, bs_t *bs, const L3_gr_info_t *gr_info, const float *scf, int layer3gr_limit)
+{
+ static const int16_t tabs[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 785,785,785,785,784,784,784,784,513,513,513,513,513,513,513,513,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,
+ -255,1313,1298,1282,785,785,785,785,784,784,784,784,769,769,769,769,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,290,288,
+ -255,1313,1298,1282,769,769,769,769,529,529,529,529,529,529,529,529,528,528,528,528,528,528,528,528,512,512,512,512,512,512,512,512,290,288,
+ -253,-318,-351,-367,785,785,785,785,784,784,784,784,769,769,769,769,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,819,818,547,547,275,275,275,275,561,560,515,546,289,274,288,258,
+ -254,-287,1329,1299,1314,1312,1057,1057,1042,1042,1026,1026,784,784,784,784,529,529,529,529,529,529,529,529,769,769,769,769,768,768,768,768,563,560,306,306,291,259,
+ -252,-413,-477,-542,1298,-575,1041,1041,784,784,784,784,769,769,769,769,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,-383,-399,1107,1092,1106,1061,849,849,789,789,1104,1091,773,773,1076,1075,341,340,325,309,834,804,577,577,532,532,516,516,832,818,803,816,561,561,531,531,515,546,289,289,288,258,
+ -252,-429,-493,-559,1057,1057,1042,1042,529,529,529,529,529,529,529,529,784,784,784,784,769,769,769,769,512,512,512,512,512,512,512,512,-382,1077,-415,1106,1061,1104,849,849,789,789,1091,1076,1029,1075,834,834,597,581,340,340,339,324,804,833,532,532,832,772,818,803,817,787,816,771,290,290,290,290,288,258,
+ -253,-349,-414,-447,-463,1329,1299,-479,1314,1312,1057,1057,1042,1042,1026,1026,785,785,785,785,784,784,784,784,769,769,769,769,768,768,768,768,-319,851,821,-335,836,850,805,849,341,340,325,336,533,533,579,579,564,564,773,832,578,548,563,516,321,276,306,291,304,259,
+ -251,-572,-733,-830,-863,-879,1041,1041,784,784,784,784,769,769,769,769,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,-511,-527,-543,1396,1351,1381,1366,1395,1335,1380,-559,1334,1138,1138,1063,1063,1350,1392,1031,1031,1062,1062,1364,1363,1120,1120,1333,1348,881,881,881,881,375,374,359,373,343,358,341,325,791,791,1123,1122,-703,1105,1045,-719,865,865,790,790,774,774,1104,1029,338,293,323,308,-799,-815,833,788,772,818,803,816,322,292,307,320,561,531,515,546,289,274,288,258,
+ -251,-525,-605,-685,-765,-831,-846,1298,1057,1057,1312,1282,785,785,785,785,784,784,784,784,769,769,769,769,512,512,512,512,512,512,512,512,1399,1398,1383,1367,1382,1396,1351,-511,1381,1366,1139,1139,1079,1079,1124,1124,1364,1349,1363,1333,882,882,882,882,807,807,807,807,1094,1094,1136,1136,373,341,535,535,881,775,867,822,774,-591,324,338,-671,849,550,550,866,864,609,609,293,336,534,534,789,835,773,-751,834,804,308,307,833,788,832,772,562,562,547,547,305,275,560,515,290,290,
+ -252,-397,-477,-557,-622,-653,-719,-735,-750,1329,1299,1314,1057,1057,1042,1042,1312,1282,1024,1024,785,785,785,785,784,784,784,784,769,769,769,769,-383,1127,1141,1111,1126,1140,1095,1110,869,869,883,883,1079,1109,882,882,375,374,807,868,838,881,791,-463,867,822,368,263,852,837,836,-543,610,610,550,550,352,336,534,534,865,774,851,821,850,805,593,533,579,564,773,832,578,578,548,548,577,577,307,276,306,291,516,560,259,259,
+ -250,-2107,-2507,-2764,-2909,-2974,-3007,-3023,1041,1041,1040,1040,769,769,769,769,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,-767,-1052,-1213,-1277,-1358,-1405,-1469,-1535,-1550,-1582,-1614,-1647,-1662,-1694,-1726,-1759,-1774,-1807,-1822,-1854,-1886,1565,-1919,-1935,-1951,-1967,1731,1730,1580,1717,-1983,1729,1564,-1999,1548,-2015,-2031,1715,1595,-2047,1714,-2063,1610,-2079,1609,-2095,1323,1323,1457,1457,1307,1307,1712,1547,1641,1700,1699,1594,1685,1625,1442,1442,1322,1322,-780,-973,-910,1279,1278,1277,1262,1276,1261,1275,1215,1260,1229,-959,974,974,989,989,-943,735,478,478,495,463,506,414,-1039,1003,958,1017,927,942,987,957,431,476,1272,1167,1228,-1183,1256,-1199,895,895,941,941,1242,1227,1212,1135,1014,1014,490,489,503,487,910,1013,985,925,863,894,970,955,1012,847,-1343,831,755,755,984,909,428,366,754,559,-1391,752,486,457,924,997,698,698,983,893,740,740,908,877,739,739,667,667,953,938,497,287,271,271,683,606,590,712,726,574,302,302,738,736,481,286,526,725,605,711,636,724,696,651,589,681,666,710,364,467,573,695,466,466,301,465,379,379,709,604,665,679,316,316,634,633,436,436,464,269,424,394,452,332,438,363,347,408,393,448,331,422,362,407,392,421,346,406,391,376,375,359,1441,1306,-2367,1290,-2383,1337,-2399,-2415,1426,1321,-2431,1411,1336,-2447,-2463,-2479,1169,1169,1049,1049,1424,1289,1412,1352,1319,-2495,1154,1154,1064,1064,1153,1153,416,390,360,404,403,389,344,374,373,343,358,372,327,357,342,311,356,326,1395,1394,1137,1137,1047,1047,1365,1392,1287,1379,1334,1364,1349,1378,1318,1363,792,792,792,792,1152,1152,1032,1032,1121,1121,1046,1046,1120,1120,1030,1030,-2895,1106,1061,1104,849,849,789,789,1091,1076,1029,1090,1060,1075,833,833,309,324,532,532,832,772,818,803,561,561,531,560,515,546,289,274,288,258,
+ -250,-1179,-1579,-1836,-1996,-2124,-2253,-2333,-2413,-2477,-2542,-2574,-2607,-2622,-2655,1314,1313,1298,1312,1282,785,785,785,785,1040,1040,1025,1025,768,768,768,768,-766,-798,-830,-862,-895,-911,-927,-943,-959,-975,-991,-1007,-1023,-1039,-1055,-1070,1724,1647,-1103,-1119,1631,1767,1662,1738,1708,1723,-1135,1780,1615,1779,1599,1677,1646,1778,1583,-1151,1777,1567,1737,1692,1765,1722,1707,1630,1751,1661,1764,1614,1736,1676,1763,1750,1645,1598,1721,1691,1762,1706,1582,1761,1566,-1167,1749,1629,767,766,751,765,494,494,735,764,719,749,734,763,447,447,748,718,477,506,431,491,446,476,461,505,415,430,475,445,504,399,460,489,414,503,383,474,429,459,502,502,746,752,488,398,501,473,413,472,486,271,480,270,-1439,-1455,1357,-1471,-1487,-1503,1341,1325,-1519,1489,1463,1403,1309,-1535,1372,1448,1418,1476,1356,1462,1387,-1551,1475,1340,1447,1402,1386,-1567,1068,1068,1474,1461,455,380,468,440,395,425,410,454,364,467,466,464,453,269,409,448,268,432,1371,1473,1432,1417,1308,1460,1355,1446,1459,1431,1083,1083,1401,1416,1458,1445,1067,1067,1370,1457,1051,1051,1291,1430,1385,1444,1354,1415,1400,1443,1082,1082,1173,1113,1186,1066,1185,1050,-1967,1158,1128,1172,1097,1171,1081,-1983,1157,1112,416,266,375,400,1170,1142,1127,1065,793,793,1169,1033,1156,1096,1141,1111,1155,1080,1126,1140,898,898,808,808,897,897,792,792,1095,1152,1032,1125,1110,1139,1079,1124,882,807,838,881,853,791,-2319,867,368,263,822,852,837,866,806,865,-2399,851,352,262,534,534,821,836,594,594,549,549,593,593,533,533,848,773,579,579,564,578,548,563,276,276,577,576,306,291,516,560,305,305,275,259,
+ -251,-892,-2058,-2620,-2828,-2957,-3023,-3039,1041,1041,1040,1040,769,769,769,769,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,-511,-527,-543,-559,1530,-575,-591,1528,1527,1407,1526,1391,1023,1023,1023,1023,1525,1375,1268,1268,1103,1103,1087,1087,1039,1039,1523,-604,815,815,815,815,510,495,509,479,508,463,507,447,431,505,415,399,-734,-782,1262,-815,1259,1244,-831,1258,1228,-847,-863,1196,-879,1253,987,987,748,-767,493,493,462,477,414,414,686,669,478,446,461,445,474,429,487,458,412,471,1266,1264,1009,1009,799,799,-1019,-1276,-1452,-1581,-1677,-1757,-1821,-1886,-1933,-1997,1257,1257,1483,1468,1512,1422,1497,1406,1467,1496,1421,1510,1134,1134,1225,1225,1466,1451,1374,1405,1252,1252,1358,1480,1164,1164,1251,1251,1238,1238,1389,1465,-1407,1054,1101,-1423,1207,-1439,830,830,1248,1038,1237,1117,1223,1148,1236,1208,411,426,395,410,379,269,1193,1222,1132,1235,1221,1116,976,976,1192,1162,1177,1220,1131,1191,963,963,-1647,961,780,-1663,558,558,994,993,437,408,393,407,829,978,813,797,947,-1743,721,721,377,392,844,950,828,890,706,706,812,859,796,960,948,843,934,874,571,571,-1919,690,555,689,421,346,539,539,944,779,918,873,932,842,903,888,570,570,931,917,674,674,-2575,1562,-2591,1609,-2607,1654,1322,1322,1441,1441,1696,1546,1683,1593,1669,1624,1426,1426,1321,1321,1639,1680,1425,1425,1305,1305,1545,1668,1608,1623,1667,1592,1638,1666,1320,1320,1652,1607,1409,1409,1304,1304,1288,1288,1664,1637,1395,1395,1335,1335,1622,1636,1394,1394,1319,1319,1606,1621,1392,1392,1137,1137,1137,1137,345,390,360,375,404,373,1047,-2751,-2767,-2783,1062,1121,1046,-2799,1077,-2815,1106,1061,789,789,1105,1104,263,355,310,340,325,354,352,262,339,324,1091,1076,1029,1090,1060,1075,833,833,788,788,1088,1028,818,818,803,803,561,561,531,531,816,771,546,546,289,274,288,258,
+ -253,-317,-381,-446,-478,-509,1279,1279,-811,-1179,-1451,-1756,-1900,-2028,-2189,-2253,-2333,-2414,-2445,-2511,-2526,1313,1298,-2559,1041,1041,1040,1040,1025,1025,1024,1024,1022,1007,1021,991,1020,975,1019,959,687,687,1018,1017,671,671,655,655,1016,1015,639,639,758,758,623,623,757,607,756,591,755,575,754,559,543,543,1009,783,-575,-621,-685,-749,496,-590,750,749,734,748,974,989,1003,958,988,973,1002,942,987,957,972,1001,926,986,941,971,956,1000,910,985,925,999,894,970,-1071,-1087,-1102,1390,-1135,1436,1509,1451,1374,-1151,1405,1358,1480,1420,-1167,1507,1494,1389,1342,1465,1435,1450,1326,1505,1310,1493,1373,1479,1404,1492,1464,1419,428,443,472,397,736,526,464,464,486,457,442,471,484,482,1357,1449,1434,1478,1388,1491,1341,1490,1325,1489,1463,1403,1309,1477,1372,1448,1418,1433,1476,1356,1462,1387,-1439,1475,1340,1447,1402,1474,1324,1461,1371,1473,269,448,1432,1417,1308,1460,-1711,1459,-1727,1441,1099,1099,1446,1386,1431,1401,-1743,1289,1083,1083,1160,1160,1458,1445,1067,1067,1370,1457,1307,1430,1129,1129,1098,1098,268,432,267,416,266,400,-1887,1144,1187,1082,1173,1113,1186,1066,1050,1158,1128,1143,1172,1097,1171,1081,420,391,1157,1112,1170,1142,1127,1065,1169,1049,1156,1096,1141,1111,1155,1080,1126,1154,1064,1153,1140,1095,1048,-2159,1125,1110,1137,-2175,823,823,1139,1138,807,807,384,264,368,263,868,838,853,791,867,822,852,837,866,806,865,790,-2319,851,821,836,352,262,850,805,849,-2399,533,533,835,820,336,261,578,548,563,577,532,532,832,772,562,562,547,547,305,275,560,515,290,290,288,258 };
+ static const uint8_t tab32[] = { 130,162,193,209,44,28,76,140,9,9,9,9,9,9,9,9,190,254,222,238,126,94,157,157,109,61,173,205 };
+ static const uint8_t tab33[] = { 252,236,220,204,188,172,156,140,124,108,92,76,60,44,28,12 };
+ static const int16_t tabindex[2*16] = { 0,32,64,98,0,132,180,218,292,364,426,538,648,746,0,1126,1460,1460,1460,1460,1460,1460,1460,1460,1842,1842,1842,1842,1842,1842,1842,1842 };
+ static const uint8_t g_linbits[] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,2,3,4,6,8,10,13,4,5,6,7,8,9,11,13 };
+
+#define PEEK_BITS(n) (bs_cache >> (32 - n))
+#define FLUSH_BITS(n) { bs_cache <<= (n); bs_sh += (n); }
+#define CHECK_BITS while (bs_sh >= 0) { bs_cache |= (uint32_t)*bs_next_ptr++ << bs_sh; bs_sh -= 8; }
+#define BSPOS ((bs_next_ptr - bs->buf)*8 - 24 + bs_sh)
+
+ float one = 0.0f;
+ int ireg = 0, big_val_cnt = gr_info->big_values;
+ const uint8_t *sfb = gr_info->sfbtab;
+ const uint8_t *bs_next_ptr = bs->buf + bs->pos/8;
+ uint32_t bs_cache = (((bs_next_ptr[0]*256u + bs_next_ptr[1])*256u + bs_next_ptr[2])*256u + bs_next_ptr[3]) << (bs->pos & 7);
+ int pairs_to_decode, np, bs_sh = (bs->pos & 7) - 8;
+ bs_next_ptr += 4;
+
+ while (big_val_cnt > 0)
+ {
+ int tab_num = gr_info->table_select[ireg];
+ int sfb_cnt = gr_info->region_count[ireg++];
+ const int16_t *codebook = tabs + tabindex[tab_num];
+ int linbits = g_linbits[tab_num];
+ if (linbits)
+ {
+ do
+ {
+ np = *sfb++ / 2;
+ pairs_to_decode = MINIMP3_MIN(big_val_cnt, np);
+ one = *scf++;
+ do
+ {
+ int j, w = 5;
+ int leaf = codebook[PEEK_BITS(w)];
+ while (leaf < 0)
+ {
+ FLUSH_BITS(w);
+ w = leaf & 7;
+ leaf = codebook[PEEK_BITS(w) - (leaf >> 3)];
+ }
+ FLUSH_BITS(leaf >> 8);
+
+ for (j = 0; j < 2; j++, dst++, leaf >>= 4)
+ {
+ int lsb = leaf & 0x0F;
+ if (lsb == 15)
+ {
+ lsb += PEEK_BITS(linbits);
+ FLUSH_BITS(linbits);
+ CHECK_BITS;
+ *dst = one*L3_pow_43(lsb)*((int32_t)bs_cache < 0 ? -1: 1);
+ } else
+ {
+ *dst = g_pow43[16 + lsb - 16*(bs_cache >> 31)]*one;
+ }
+ FLUSH_BITS(lsb ? 1 : 0);
+ }
+ CHECK_BITS;
+ } while (--pairs_to_decode);
+ } while ((big_val_cnt -= np) > 0 && --sfb_cnt >= 0);
+ } else
+ {
+ do
+ {
+ np = *sfb++ / 2;
+ pairs_to_decode = MINIMP3_MIN(big_val_cnt, np);
+ one = *scf++;
+ do
+ {
+ int j, w = 5;
+ int leaf = codebook[PEEK_BITS(w)];
+ while (leaf < 0)
+ {
+ FLUSH_BITS(w);
+ w = leaf & 7;
+ leaf = codebook[PEEK_BITS(w) - (leaf >> 3)];
+ }
+ FLUSH_BITS(leaf >> 8);
+
+ for (j = 0; j < 2; j++, dst++, leaf >>= 4)
+ {
+ int lsb = leaf & 0x0F;
+ *dst = g_pow43[16 + lsb - 16*(bs_cache >> 31)]*one;
+ FLUSH_BITS(lsb ? 1 : 0);
+ }
+ CHECK_BITS;
+ } while (--pairs_to_decode);
+ } while ((big_val_cnt -= np) > 0 && --sfb_cnt >= 0);
+ }
+ }
+
+ for (np = 1 - big_val_cnt;; dst += 4)
+ {
+ const uint8_t *codebook_count1 = (gr_info->count1_table) ? tab33 : tab32;
+ int leaf = codebook_count1[PEEK_BITS(4)];
+ if (!(leaf & 8))
+ {
+ leaf = codebook_count1[(leaf >> 3) + (bs_cache << 4 >> (32 - (leaf & 3)))];
+ }
+ FLUSH_BITS(leaf & 7);
+ if (BSPOS > layer3gr_limit)
+ {
+ break;
+ }
+#define RELOAD_SCALEFACTOR if (!--np) { np = *sfb++/2; if (!np) break; one = *scf++; }
+#define DEQ_COUNT1(s) if (leaf & (128 >> s)) { dst[s] = ((int32_t)bs_cache < 0) ? -one : one; FLUSH_BITS(1) }
+ RELOAD_SCALEFACTOR;
+ DEQ_COUNT1(0);
+ DEQ_COUNT1(1);
+ RELOAD_SCALEFACTOR;
+ DEQ_COUNT1(2);
+ DEQ_COUNT1(3);
+ CHECK_BITS;
+ }
+
+ bs->pos = layer3gr_limit;
+}
+
+static void L3_midside_stereo(float *left, int n)
+{
+ int i = 0;
+ float *right = left + 576;
+#if HAVE_SIMD
+ if (have_simd())
+ {
+ for (; i < n - 3; i += 4)
+ {
+ f4 vl = VLD(left + i);
+ f4 vr = VLD(right + i);
+ VSTORE(left + i, VADD(vl, vr));
+ VSTORE(right + i, VSUB(vl, vr));
+ }
+#ifdef __GNUC__
+ /* Workaround for spurious -Waggressive-loop-optimizations warning from gcc.
+ * For more info see: https://github.com/lieff/minimp3/issues/88
+ */
+ if (__builtin_constant_p(n % 4 == 0) && n % 4 == 0)
+ return;
+#endif
+ }
+#endif /* HAVE_SIMD */
+ for (; i < n; i++)
+ {
+ float a = left[i];
+ float b = right[i];
+ left[i] = a + b;
+ right[i] = a - b;
+ }
+}
+
+static void L3_intensity_stereo_band(float *left, int n, float kl, float kr)
+{
+ int i;
+ for (i = 0; i < n; i++)
+ {
+ left[i + 576] = left[i]*kr;
+ left[i] = left[i]*kl;
+ }
+}
+
+static void L3_stereo_top_band(const float *right, const uint8_t *sfb, int nbands, int max_band[3])
+{
+ int i, k;
+
+ max_band[0] = max_band[1] = max_band[2] = -1;
+
+ for (i = 0; i < nbands; i++)
+ {
+ for (k = 0; k < sfb[i]; k += 2)
+ {
+ if (right[k] != 0 || right[k + 1] != 0)
+ {
+ max_band[i % 3] = i;
+ break;
+ }
+ }
+ right += sfb[i];
+ }
+}
+
+static void L3_stereo_process(float *left, const uint8_t *ist_pos, const uint8_t *sfb, const uint8_t *hdr, int max_band[3], int mpeg2_sh)
+{
+ static const float g_pan[7*2] = { 0,1,0.21132487f,0.78867513f,0.36602540f,0.63397460f,0.5f,0.5f,0.63397460f,0.36602540f,0.78867513f,0.21132487f,1,0 };
+ unsigned i, max_pos = HDR_TEST_MPEG1(hdr) ? 7 : 64;
+
+ for (i = 0; sfb[i]; i++)
+ {
+ unsigned ipos = ist_pos[i];
+ if ((int)i > max_band[i % 3] && ipos < max_pos)
+ {
+ float kl, kr, s = HDR_TEST_MS_STEREO(hdr) ? 1.41421356f : 1;
+ if (HDR_TEST_MPEG1(hdr))
+ {
+ kl = g_pan[2*ipos];
+ kr = g_pan[2*ipos + 1];
+ } else
+ {
+ kl = 1;
+ kr = L3_ldexp_q2(1, (ipos + 1) >> 1 << mpeg2_sh);
+ if (ipos & 1)
+ {
+ kl = kr;
+ kr = 1;
+ }
+ }
+ L3_intensity_stereo_band(left, sfb[i], kl*s, kr*s);
+ } else if (HDR_TEST_MS_STEREO(hdr))
+ {
+ L3_midside_stereo(left, sfb[i]);
+ }
+ left += sfb[i];
+ }
+}
+
+static void L3_intensity_stereo(float *left, uint8_t *ist_pos, const L3_gr_info_t *gr, const uint8_t *hdr)
+{
+ int max_band[3], n_sfb = gr->n_long_sfb + gr->n_short_sfb;
+ int i, max_blocks = gr->n_short_sfb ? 3 : 1;
+
+ L3_stereo_top_band(left + 576, gr->sfbtab, n_sfb, max_band);
+ if (gr->n_long_sfb)
+ {
+ max_band[0] = max_band[1] = max_band[2] = MINIMP3_MAX(MINIMP3_MAX(max_band[0], max_band[1]), max_band[2]);
+ }
+ for (i = 0; i < max_blocks; i++)
+ {
+ int default_pos = HDR_TEST_MPEG1(hdr) ? 3 : 0;
+ int itop = n_sfb - max_blocks + i;
+ int prev = itop - max_blocks;
+ ist_pos[itop] = max_band[i] >= prev ? default_pos : ist_pos[prev];
+ }
+ L3_stereo_process(left, ist_pos, gr->sfbtab, hdr, max_band, gr[1].scalefac_compress & 1);
+}
+
+static void L3_reorder(float *grbuf, float *scratch, const uint8_t *sfb)
+{
+ int i, len;
+ float *src = grbuf, *dst = scratch;
+
+ for (;0 != (len = *sfb); sfb += 3, src += 2*len)
+ {
+ for (i = 0; i < len; i++, src++)
+ {
+ *dst++ = src[0*len];
+ *dst++ = src[1*len];
+ *dst++ = src[2*len];
+ }
+ }
+ memcpy(grbuf, scratch, (dst - scratch)*sizeof(float));
+}
+
+static void L3_antialias(float *grbuf, int nbands)
+{
+ static const float g_aa[2][8] = {
+ {0.85749293f,0.88174200f,0.94962865f,0.98331459f,0.99551782f,0.99916056f,0.99989920f,0.99999316f},
+ {0.51449576f,0.47173197f,0.31337745f,0.18191320f,0.09457419f,0.04096558f,0.01419856f,0.00369997f}
+ };
+
+ for (; nbands > 0; nbands--, grbuf += 18)
+ {
+ int i = 0;
+#if HAVE_SIMD
+ if (have_simd()) for (; i < 8; i += 4)
+ {
+ f4 vu = VLD(grbuf + 18 + i);
+ f4 vd = VLD(grbuf + 14 - i);
+ f4 vc0 = VLD(g_aa[0] + i);
+ f4 vc1 = VLD(g_aa[1] + i);
+ vd = VREV(vd);
+ VSTORE(grbuf + 18 + i, VSUB(VMUL(vu, vc0), VMUL(vd, vc1)));
+ vd = VADD(VMUL(vu, vc1), VMUL(vd, vc0));
+ VSTORE(grbuf + 14 - i, VREV(vd));
+ }
+#endif /* HAVE_SIMD */
+#ifndef MINIMP3_ONLY_SIMD
+ for(; i < 8; i++)
+ {
+ float u = grbuf[18 + i];
+ float d = grbuf[17 - i];
+ grbuf[18 + i] = u*g_aa[0][i] - d*g_aa[1][i];
+ grbuf[17 - i] = u*g_aa[1][i] + d*g_aa[0][i];
+ }
+#endif /* MINIMP3_ONLY_SIMD */
+ }
+}
+
+static void L3_dct3_9(float *y)
+{
+ float s0, s1, s2, s3, s4, s5, s6, s7, s8, t0, t2, t4;
+
+ s0 = y[0]; s2 = y[2]; s4 = y[4]; s6 = y[6]; s8 = y[8];
+ t0 = s0 + s6*0.5f;
+ s0 -= s6;
+ t4 = (s4 + s2)*0.93969262f;
+ t2 = (s8 + s2)*0.76604444f;
+ s6 = (s4 - s8)*0.17364818f;
+ s4 += s8 - s2;
+
+ s2 = s0 - s4*0.5f;
+ y[4] = s4 + s0;
+ s8 = t0 - t2 + s6;
+ s0 = t0 - t4 + t2;
+ s4 = t0 + t4 - s6;
+
+ s1 = y[1]; s3 = y[3]; s5 = y[5]; s7 = y[7];
+
+ s3 *= 0.86602540f;
+ t0 = (s5 + s1)*0.98480775f;
+ t4 = (s5 - s7)*0.34202014f;
+ t2 = (s1 + s7)*0.64278761f;
+ s1 = (s1 - s5 - s7)*0.86602540f;
+
+ s5 = t0 - s3 - t2;
+ s7 = t4 - s3 - t0;
+ s3 = t4 + s3 - t2;
+
+ y[0] = s4 - s7;
+ y[1] = s2 + s1;
+ y[2] = s0 - s3;
+ y[3] = s8 + s5;
+ y[5] = s8 - s5;
+ y[6] = s0 + s3;
+ y[7] = s2 - s1;
+ y[8] = s4 + s7;
+}
+
+static void L3_imdct36(float *grbuf, float *overlap, const float *window, int nbands)
+{
+ int i, j;
+ static const float g_twid9[18] = {
+ 0.73727734f,0.79335334f,0.84339145f,0.88701083f,0.92387953f,0.95371695f,0.97629601f,0.99144486f,0.99904822f,0.67559021f,0.60876143f,0.53729961f,0.46174861f,0.38268343f,0.30070580f,0.21643961f,0.13052619f,0.04361938f
+ };
+
+ for (j = 0; j < nbands; j++, grbuf += 18, overlap += 9)
+ {
+ float co[9], si[9];
+ co[0] = -grbuf[0];
+ si[0] = grbuf[17];
+ for (i = 0; i < 4; i++)
+ {
+ si[8 - 2*i] = grbuf[4*i + 1] - grbuf[4*i + 2];
+ co[1 + 2*i] = grbuf[4*i + 1] + grbuf[4*i + 2];
+ si[7 - 2*i] = grbuf[4*i + 4] - grbuf[4*i + 3];
+ co[2 + 2*i] = -(grbuf[4*i + 3] + grbuf[4*i + 4]);
+ }
+ L3_dct3_9(co);
+ L3_dct3_9(si);
+
+ si[1] = -si[1];
+ si[3] = -si[3];
+ si[5] = -si[5];
+ si[7] = -si[7];
+
+ i = 0;
+
+#if HAVE_SIMD
+ if (have_simd()) for (; i < 8; i += 4)
+ {
+ f4 vovl = VLD(overlap + i);
+ f4 vc = VLD(co + i);
+ f4 vs = VLD(si + i);
+ f4 vr0 = VLD(g_twid9 + i);
+ f4 vr1 = VLD(g_twid9 + 9 + i);
+ f4 vw0 = VLD(window + i);
+ f4 vw1 = VLD(window + 9 + i);
+ f4 vsum = VADD(VMUL(vc, vr1), VMUL(vs, vr0));
+ VSTORE(overlap + i, VSUB(VMUL(vc, vr0), VMUL(vs, vr1)));
+ VSTORE(grbuf + i, VSUB(VMUL(vovl, vw0), VMUL(vsum, vw1)));
+ vsum = VADD(VMUL(vovl, vw1), VMUL(vsum, vw0));
+ VSTORE(grbuf + 14 - i, VREV(vsum));
+ }
+#endif /* HAVE_SIMD */
+ for (; i < 9; i++)
+ {
+ float ovl = overlap[i];
+ float sum = co[i]*g_twid9[9 + i] + si[i]*g_twid9[0 + i];
+ overlap[i] = co[i]*g_twid9[0 + i] - si[i]*g_twid9[9 + i];
+ grbuf[i] = ovl*window[0 + i] - sum*window[9 + i];
+ grbuf[17 - i] = ovl*window[9 + i] + sum*window[0 + i];
+ }
+ }
+}
+
+static void L3_idct3(float x0, float x1, float x2, float *dst)
+{
+ float m1 = x1*0.86602540f;
+ float a1 = x0 - x2*0.5f;
+ dst[1] = x0 + x2;
+ dst[0] = a1 + m1;
+ dst[2] = a1 - m1;
+}
+
+static void L3_imdct12(float *x, float *dst, float *overlap)
+{
+ static const float g_twid3[6] = { 0.79335334f,0.92387953f,0.99144486f, 0.60876143f,0.38268343f,0.13052619f };
+ float co[3], si[3];
+ int i;
+
+ L3_idct3(-x[0], x[6] + x[3], x[12] + x[9], co);
+ L3_idct3(x[15], x[12] - x[9], x[6] - x[3], si);
+ si[1] = -si[1];
+
+ for (i = 0; i < 3; i++)
+ {
+ float ovl = overlap[i];
+ float sum = co[i]*g_twid3[3 + i] + si[i]*g_twid3[0 + i];
+ overlap[i] = co[i]*g_twid3[0 + i] - si[i]*g_twid3[3 + i];
+ dst[i] = ovl*g_twid3[2 - i] - sum*g_twid3[5 - i];
+ dst[5 - i] = ovl*g_twid3[5 - i] + sum*g_twid3[2 - i];
+ }
+}
+
+static void L3_imdct_short(float *grbuf, float *overlap, int nbands)
+{
+ for (;nbands > 0; nbands--, overlap += 9, grbuf += 18)
+ {
+ float tmp[18];
+ memcpy(tmp, grbuf, sizeof(tmp));
+ memcpy(grbuf, overlap, 6*sizeof(float));
+ L3_imdct12(tmp, grbuf + 6, overlap + 6);
+ L3_imdct12(tmp + 1, grbuf + 12, overlap + 6);
+ L3_imdct12(tmp + 2, overlap, overlap + 6);
+ }
+}
+
+static void L3_change_sign(float *grbuf)
+{
+ int b, i;
+ for (b = 0, grbuf += 18; b < 32; b += 2, grbuf += 36)
+ for (i = 1; i < 18; i += 2)
+ grbuf[i] = -grbuf[i];
+}
+
+static void L3_imdct_gr(float *grbuf, float *overlap, unsigned block_type, unsigned n_long_bands)
+{
+ static const float g_mdct_window[2][18] = {
+ { 0.99904822f,0.99144486f,0.97629601f,0.95371695f,0.92387953f,0.88701083f,0.84339145f,0.79335334f,0.73727734f,0.04361938f,0.13052619f,0.21643961f,0.30070580f,0.38268343f,0.46174861f,0.53729961f,0.60876143f,0.67559021f },
+ { 1,1,1,1,1,1,0.99144486f,0.92387953f,0.79335334f,0,0,0,0,0,0,0.13052619f,0.38268343f,0.60876143f }
+ };
+ if (n_long_bands)
+ {
+ L3_imdct36(grbuf, overlap, g_mdct_window[0], n_long_bands);
+ grbuf += 18*n_long_bands;
+ overlap += 9*n_long_bands;
+ }
+ if (block_type == SHORT_BLOCK_TYPE)
+ L3_imdct_short(grbuf, overlap, 32 - n_long_bands);
+ else
+ L3_imdct36(grbuf, overlap, g_mdct_window[block_type == STOP_BLOCK_TYPE], 32 - n_long_bands);
+}
+
+static void L3_save_reservoir(mp3dec_t *h, mp3dec_scratch_t *s)
+{
+ int pos = (s->bs.pos + 7)/8u;
+ int remains = s->bs.limit/8u - pos;
+ if (remains > MAX_BITRESERVOIR_BYTES)
+ {
+ pos += remains - MAX_BITRESERVOIR_BYTES;
+ remains = MAX_BITRESERVOIR_BYTES;
+ }
+ if (remains > 0)
+ {
+ memmove(h->reserv_buf, s->maindata + pos, remains);
+ }
+ h->reserv = remains;
+}
+
+static int L3_restore_reservoir(mp3dec_t *h, bs_t *bs, mp3dec_scratch_t *s, int main_data_begin)
+{
+ int frame_bytes = (bs->limit - bs->pos)/8;
+ int bytes_have = MINIMP3_MIN(h->reserv, main_data_begin);
+ memcpy(s->maindata, h->reserv_buf + MINIMP3_MAX(0, h->reserv - main_data_begin), MINIMP3_MIN(h->reserv, main_data_begin));
+ memcpy(s->maindata + bytes_have, bs->buf + bs->pos/8, frame_bytes);
+ bs_init(&s->bs, s->maindata, bytes_have + frame_bytes);
+ return h->reserv >= main_data_begin;
+}
+
+static void L3_decode(mp3dec_t *h, mp3dec_scratch_t *s, L3_gr_info_t *gr_info, int nch)
+{
+ int ch;
+
+ for (ch = 0; ch < nch; ch++)
+ {
+ int layer3gr_limit = s->bs.pos + gr_info[ch].part_23_length;
+ L3_decode_scalefactors(h->header, s->ist_pos[ch], &s->bs, gr_info + ch, s->scf, ch);
+ L3_huffman(s->grbuf[ch], &s->bs, gr_info + ch, s->scf, layer3gr_limit);
+ }
+
+ if (HDR_TEST_I_STEREO(h->header))
+ {
+ L3_intensity_stereo(s->grbuf[0], s->ist_pos[1], gr_info, h->header);
+ } else if (HDR_IS_MS_STEREO(h->header))
+ {
+ L3_midside_stereo(s->grbuf[0], 576);
+ }
+
+ for (ch = 0; ch < nch; ch++, gr_info++)
+ {
+ int aa_bands = 31;
+ int n_long_bands = (gr_info->mixed_block_flag ? 2 : 0) << (int)(HDR_GET_MY_SAMPLE_RATE(h->header) == 2);
+
+ if (gr_info->n_short_sfb)
+ {
+ aa_bands = n_long_bands - 1;
+ L3_reorder(s->grbuf[ch] + n_long_bands*18, s->syn[0], gr_info->sfbtab + gr_info->n_long_sfb);
+ }
+
+ L3_antialias(s->grbuf[ch], aa_bands);
+ L3_imdct_gr(s->grbuf[ch], h->mdct_overlap[ch], gr_info->block_type, n_long_bands);
+ L3_change_sign(s->grbuf[ch]);
+ }
+}
+
+static void mp3d_DCT_II(float *grbuf, int n)
+{
+ static const float g_sec[24] = {
+ 10.19000816f,0.50060302f,0.50241929f,3.40760851f,0.50547093f,0.52249861f,2.05778098f,0.51544732f,0.56694406f,1.48416460f,0.53104258f,0.64682180f,1.16943991f,0.55310392f,0.78815460f,0.97256821f,0.58293498f,1.06067765f,0.83934963f,0.62250412f,1.72244716f,0.74453628f,0.67480832f,5.10114861f
+ };
+ int i, k = 0;
+#if HAVE_SIMD
+ if (have_simd()) for (; k < n; k += 4)
+ {
+ f4 t[4][8], *x;
+ float *y = grbuf + k;
+
+ for (x = t[0], i = 0; i < 8; i++, x++)
+ {
+ f4 x0 = VLD(&y[i*18]);
+ f4 x1 = VLD(&y[(15 - i)*18]);
+ f4 x2 = VLD(&y[(16 + i)*18]);
+ f4 x3 = VLD(&y[(31 - i)*18]);
+ f4 t0 = VADD(x0, x3);
+ f4 t1 = VADD(x1, x2);
+ f4 t2 = VMUL_S(VSUB(x1, x2), g_sec[3*i + 0]);
+ f4 t3 = VMUL_S(VSUB(x0, x3), g_sec[3*i + 1]);
+ x[0] = VADD(t0, t1);
+ x[8] = VMUL_S(VSUB(t0, t1), g_sec[3*i + 2]);
+ x[16] = VADD(t3, t2);
+ x[24] = VMUL_S(VSUB(t3, t2), g_sec[3*i + 2]);
+ }
+ for (x = t[0], i = 0; i < 4; i++, x += 8)
+ {
+ f4 x0 = x[0], x1 = x[1], x2 = x[2], x3 = x[3], x4 = x[4], x5 = x[5], x6 = x[6], x7 = x[7], xt;
+ xt = VSUB(x0, x7); x0 = VADD(x0, x7);
+ x7 = VSUB(x1, x6); x1 = VADD(x1, x6);
+ x6 = VSUB(x2, x5); x2 = VADD(x2, x5);
+ x5 = VSUB(x3, x4); x3 = VADD(x3, x4);
+ x4 = VSUB(x0, x3); x0 = VADD(x0, x3);
+ x3 = VSUB(x1, x2); x1 = VADD(x1, x2);
+ x[0] = VADD(x0, x1);
+ x[4] = VMUL_S(VSUB(x0, x1), 0.70710677f);
+ x5 = VADD(x5, x6);
+ x6 = VMUL_S(VADD(x6, x7), 0.70710677f);
+ x7 = VADD(x7, xt);
+ x3 = VMUL_S(VADD(x3, x4), 0.70710677f);
+ x5 = VSUB(x5, VMUL_S(x7, 0.198912367f)); /* rotate by PI/8 */
+ x7 = VADD(x7, VMUL_S(x5, 0.382683432f));
+ x5 = VSUB(x5, VMUL_S(x7, 0.198912367f));
+ x0 = VSUB(xt, x6); xt = VADD(xt, x6);
+ x[1] = VMUL_S(VADD(xt, x7), 0.50979561f);
+ x[2] = VMUL_S(VADD(x4, x3), 0.54119611f);
+ x[3] = VMUL_S(VSUB(x0, x5), 0.60134488f);
+ x[5] = VMUL_S(VADD(x0, x5), 0.89997619f);
+ x[6] = VMUL_S(VSUB(x4, x3), 1.30656302f);
+ x[7] = VMUL_S(VSUB(xt, x7), 2.56291556f);
+ }
+
+ if (k > n - 3)
+ {
+#if HAVE_SSE
+#define VSAVE2(i, v) _mm_storel_pi((__m64 *)(void*)&y[i*18], v)
+#else /* HAVE_SSE */
+#define VSAVE2(i, v) vst1_f32((float32_t *)&y[i*18], vget_low_f32(v))
+#endif /* HAVE_SSE */
+ for (i = 0; i < 7; i++, y += 4*18)
+ {
+ f4 s = VADD(t[3][i], t[3][i + 1]);
+ VSAVE2(0, t[0][i]);
+ VSAVE2(1, VADD(t[2][i], s));
+ VSAVE2(2, VADD(t[1][i], t[1][i + 1]));
+ VSAVE2(3, VADD(t[2][1 + i], s));
+ }
+ VSAVE2(0, t[0][7]);
+ VSAVE2(1, VADD(t[2][7], t[3][7]));
+ VSAVE2(2, t[1][7]);
+ VSAVE2(3, t[3][7]);
+ } else
+ {
+#define VSAVE4(i, v) VSTORE(&y[i*18], v)
+ for (i = 0; i < 7; i++, y += 4*18)
+ {
+ f4 s = VADD(t[3][i], t[3][i + 1]);
+ VSAVE4(0, t[0][i]);
+ VSAVE4(1, VADD(t[2][i], s));
+ VSAVE4(2, VADD(t[1][i], t[1][i + 1]));
+ VSAVE4(3, VADD(t[2][1 + i], s));
+ }
+ VSAVE4(0, t[0][7]);
+ VSAVE4(1, VADD(t[2][7], t[3][7]));
+ VSAVE4(2, t[1][7]);
+ VSAVE4(3, t[3][7]);
+ }
+ } else
+#endif /* HAVE_SIMD */
+#ifdef MINIMP3_ONLY_SIMD
+ {} /* for HAVE_SIMD=1, MINIMP3_ONLY_SIMD=1 case we do not need non-intrinsic "else" branch */
+#else /* MINIMP3_ONLY_SIMD */
+ for (; k < n; k++)
+ {
+ float t[4][8], *x, *y = grbuf + k;
+
+ for (x = t[0], i = 0; i < 8; i++, x++)
+ {
+ float x0 = y[i*18];
+ float x1 = y[(15 - i)*18];
+ float x2 = y[(16 + i)*18];
+ float x3 = y[(31 - i)*18];
+ float t0 = x0 + x3;
+ float t1 = x1 + x2;
+ float t2 = (x1 - x2)*g_sec[3*i + 0];
+ float t3 = (x0 - x3)*g_sec[3*i + 1];
+ x[0] = t0 + t1;
+ x[8] = (t0 - t1)*g_sec[3*i + 2];
+ x[16] = t3 + t2;
+ x[24] = (t3 - t2)*g_sec[3*i + 2];
+ }
+ for (x = t[0], i = 0; i < 4; i++, x += 8)
+ {
+ float x0 = x[0], x1 = x[1], x2 = x[2], x3 = x[3], x4 = x[4], x5 = x[5], x6 = x[6], x7 = x[7], xt;
+ xt = x0 - x7; x0 += x7;
+ x7 = x1 - x6; x1 += x6;
+ x6 = x2 - x5; x2 += x5;
+ x5 = x3 - x4; x3 += x4;
+ x4 = x0 - x3; x0 += x3;
+ x3 = x1 - x2; x1 += x2;
+ x[0] = x0 + x1;
+ x[4] = (x0 - x1)*0.70710677f;
+ x5 = x5 + x6;
+ x6 = (x6 + x7)*0.70710677f;
+ x7 = x7 + xt;
+ x3 = (x3 + x4)*0.70710677f;
+ x5 -= x7*0.198912367f; /* rotate by PI/8 */
+ x7 += x5*0.382683432f;
+ x5 -= x7*0.198912367f;
+ x0 = xt - x6; xt += x6;
+ x[1] = (xt + x7)*0.50979561f;
+ x[2] = (x4 + x3)*0.54119611f;
+ x[3] = (x0 - x5)*0.60134488f;
+ x[5] = (x0 + x5)*0.89997619f;
+ x[6] = (x4 - x3)*1.30656302f;
+ x[7] = (xt - x7)*2.56291556f;
+
+ }
+ for (i = 0; i < 7; i++, y += 4*18)
+ {
+ y[0*18] = t[0][i];
+ y[1*18] = t[2][i] + t[3][i] + t[3][i + 1];
+ y[2*18] = t[1][i] + t[1][i + 1];
+ y[3*18] = t[2][i + 1] + t[3][i] + t[3][i + 1];
+ }
+ y[0*18] = t[0][7];
+ y[1*18] = t[2][7] + t[3][7];
+ y[2*18] = t[1][7];
+ y[3*18] = t[3][7];
+ }
+#endif /* MINIMP3_ONLY_SIMD */
+}
+
+#ifndef MINIMP3_FLOAT_OUTPUT
+static int16_t mp3d_scale_pcm(float sample)
+{
+#if HAVE_ARMV6
+ int32_t s32 = (int32_t)(sample + .5f);
+ s32 -= (s32 < 0);
+ int16_t s = (int16_t)minimp3_clip_int16_arm(s32);
+#else
+ if (sample >= 32766.5) return (int16_t) 32767;
+ if (sample <= -32767.5) return (int16_t)-32768;
+ int16_t s = (int16_t)(sample + .5f);
+ s -= (s < 0); /* away from zero, to be compliant */
+#endif
+ return s;
+}
+#else /* MINIMP3_FLOAT_OUTPUT */
+static float mp3d_scale_pcm(float sample)
+{
+ return sample*(1.f/32768.f);
+}
+#endif /* MINIMP3_FLOAT_OUTPUT */
+
+static void mp3d_synth_pair(mp3d_sample_t *pcm, int nch, const float *z)
+{
+ float a;
+ a = (z[14*64] - z[ 0]) * 29;
+ a += (z[ 1*64] + z[13*64]) * 213;
+ a += (z[12*64] - z[ 2*64]) * 459;
+ a += (z[ 3*64] + z[11*64]) * 2037;
+ a += (z[10*64] - z[ 4*64]) * 5153;
+ a += (z[ 5*64] + z[ 9*64]) * 6574;
+ a += (z[ 8*64] - z[ 6*64]) * 37489;
+ a += z[ 7*64] * 75038;
+ pcm[0] = mp3d_scale_pcm(a);
+
+ z += 2;
+ a = z[14*64] * 104;
+ a += z[12*64] * 1567;
+ a += z[10*64] * 9727;
+ a += z[ 8*64] * 64019;
+ a += z[ 6*64] * -9975;
+ a += z[ 4*64] * -45;
+ a += z[ 2*64] * 146;
+ a += z[ 0*64] * -5;
+ pcm[16*nch] = mp3d_scale_pcm(a);
+}
+
+static void mp3d_synth(float *xl, mp3d_sample_t *dstl, int nch, float *lins)
+{
+ int i;
+ float *xr = xl + 576*(nch - 1);
+ mp3d_sample_t *dstr = dstl + (nch - 1);
+
+ static const float g_win[] = {
+ -1,26,-31,208,218,401,-519,2063,2000,4788,-5517,7134,5959,35640,-39336,74992,
+ -1,24,-35,202,222,347,-581,2080,1952,4425,-5879,7640,5288,33791,-41176,74856,
+ -1,21,-38,196,225,294,-645,2087,1893,4063,-6237,8092,4561,31947,-43006,74630,
+ -1,19,-41,190,227,244,-711,2085,1822,3705,-6589,8492,3776,30112,-44821,74313,
+ -1,17,-45,183,228,197,-779,2075,1739,3351,-6935,8840,2935,28289,-46617,73908,
+ -1,16,-49,176,228,153,-848,2057,1644,3004,-7271,9139,2037,26482,-48390,73415,
+ -2,14,-53,169,227,111,-919,2032,1535,2663,-7597,9389,1082,24694,-50137,72835,
+ -2,13,-58,161,224,72,-991,2001,1414,2330,-7910,9592,70,22929,-51853,72169,
+ -2,11,-63,154,221,36,-1064,1962,1280,2006,-8209,9750,-998,21189,-53534,71420,
+ -2,10,-68,147,215,2,-1137,1919,1131,1692,-8491,9863,-2122,19478,-55178,70590,
+ -3,9,-73,139,208,-29,-1210,1870,970,1388,-8755,9935,-3300,17799,-56778,69679,
+ -3,8,-79,132,200,-57,-1283,1817,794,1095,-8998,9966,-4533,16155,-58333,68692,
+ -4,7,-85,125,189,-83,-1356,1759,605,814,-9219,9959,-5818,14548,-59838,67629,
+ -4,7,-91,117,177,-106,-1428,1698,402,545,-9416,9916,-7154,12980,-61289,66494,
+ -5,6,-97,111,163,-127,-1498,1634,185,288,-9585,9838,-8540,11455,-62684,65290
+ };
+ float *zlin = lins + 15*64;
+ const float *w = g_win;
+
+ zlin[4*15] = xl[18*16];
+ zlin[4*15 + 1] = xr[18*16];
+ zlin[4*15 + 2] = xl[0];
+ zlin[4*15 + 3] = xr[0];
+
+ zlin[4*31] = xl[1 + 18*16];
+ zlin[4*31 + 1] = xr[1 + 18*16];
+ zlin[4*31 + 2] = xl[1];
+ zlin[4*31 + 3] = xr[1];
+
+ mp3d_synth_pair(dstr, nch, lins + 4*15 + 1);
+ mp3d_synth_pair(dstr + 32*nch, nch, lins + 4*15 + 64 + 1);
+ mp3d_synth_pair(dstl, nch, lins + 4*15);
+ mp3d_synth_pair(dstl + 32*nch, nch, lins + 4*15 + 64);
+
+#if HAVE_SIMD
+ if (have_simd()) for (i = 14; i >= 0; i--)
+ {
+#define VLOAD(k) f4 w0 = VSET(*w++); f4 w1 = VSET(*w++); f4 vz = VLD(&zlin[4*i - 64*k]); f4 vy = VLD(&zlin[4*i - 64*(15 - k)]);
+#define V0(k) { VLOAD(k) b = VADD(VMUL(vz, w1), VMUL(vy, w0)) ; a = VSUB(VMUL(vz, w0), VMUL(vy, w1)); }
+#define V1(k) { VLOAD(k) b = VADD(b, VADD(VMUL(vz, w1), VMUL(vy, w0))); a = VADD(a, VSUB(VMUL(vz, w0), VMUL(vy, w1))); }
+#define V2(k) { VLOAD(k) b = VADD(b, VADD(VMUL(vz, w1), VMUL(vy, w0))); a = VADD(a, VSUB(VMUL(vy, w1), VMUL(vz, w0))); }
+ f4 a, b;
+ zlin[4*i] = xl[18*(31 - i)];
+ zlin[4*i + 1] = xr[18*(31 - i)];
+ zlin[4*i + 2] = xl[1 + 18*(31 - i)];
+ zlin[4*i + 3] = xr[1 + 18*(31 - i)];
+ zlin[4*i + 64] = xl[1 + 18*(1 + i)];
+ zlin[4*i + 64 + 1] = xr[1 + 18*(1 + i)];
+ zlin[4*i - 64 + 2] = xl[18*(1 + i)];
+ zlin[4*i - 64 + 3] = xr[18*(1 + i)];
+
+ V0(0) V2(1) V1(2) V2(3) V1(4) V2(5) V1(6) V2(7)
+
+ {
+#ifndef MINIMP3_FLOAT_OUTPUT
+#if HAVE_SSE
+ static const f4 g_max = { 32767.0f, 32767.0f, 32767.0f, 32767.0f };
+ static const f4 g_min = { -32768.0f, -32768.0f, -32768.0f, -32768.0f };
+ __m128i pcm8 = _mm_packs_epi32(_mm_cvtps_epi32(_mm_max_ps(_mm_min_ps(a, g_max), g_min)),
+ _mm_cvtps_epi32(_mm_max_ps(_mm_min_ps(b, g_max), g_min)));
+ dstr[(15 - i)*nch] = _mm_extract_epi16(pcm8, 1);
+ dstr[(17 + i)*nch] = _mm_extract_epi16(pcm8, 5);
+ dstl[(15 - i)*nch] = _mm_extract_epi16(pcm8, 0);
+ dstl[(17 + i)*nch] = _mm_extract_epi16(pcm8, 4);
+ dstr[(47 - i)*nch] = _mm_extract_epi16(pcm8, 3);
+ dstr[(49 + i)*nch] = _mm_extract_epi16(pcm8, 7);
+ dstl[(47 - i)*nch] = _mm_extract_epi16(pcm8, 2);
+ dstl[(49 + i)*nch] = _mm_extract_epi16(pcm8, 6);
+#else /* HAVE_SSE */
+ int16x4_t pcma, pcmb;
+ a = VADD(a, VSET(0.5f));
+ b = VADD(b, VSET(0.5f));
+ pcma = vqmovn_s32(vqaddq_s32(vcvtq_s32_f32(a), vreinterpretq_s32_u32(vcltq_f32(a, VSET(0)))));
+ pcmb = vqmovn_s32(vqaddq_s32(vcvtq_s32_f32(b), vreinterpretq_s32_u32(vcltq_f32(b, VSET(0)))));
+ vst1_lane_s16(dstr + (15 - i)*nch, pcma, 1);
+ vst1_lane_s16(dstr + (17 + i)*nch, pcmb, 1);
+ vst1_lane_s16(dstl + (15 - i)*nch, pcma, 0);
+ vst1_lane_s16(dstl + (17 + i)*nch, pcmb, 0);
+ vst1_lane_s16(dstr + (47 - i)*nch, pcma, 3);
+ vst1_lane_s16(dstr + (49 + i)*nch, pcmb, 3);
+ vst1_lane_s16(dstl + (47 - i)*nch, pcma, 2);
+ vst1_lane_s16(dstl + (49 + i)*nch, pcmb, 2);
+#endif /* HAVE_SSE */
+
+#else /* MINIMP3_FLOAT_OUTPUT */
+
+ static const f4 g_scale = { 1.0f/32768.0f, 1.0f/32768.0f, 1.0f/32768.0f, 1.0f/32768.0f };
+ a = VMUL(a, g_scale);
+ b = VMUL(b, g_scale);
+#if HAVE_SSE
+ _mm_store_ss(dstr + (15 - i)*nch, _mm_shuffle_ps(a, a, _MM_SHUFFLE(1, 1, 1, 1)));
+ _mm_store_ss(dstr + (17 + i)*nch, _mm_shuffle_ps(b, b, _MM_SHUFFLE(1, 1, 1, 1)));
+ _mm_store_ss(dstl + (15 - i)*nch, _mm_shuffle_ps(a, a, _MM_SHUFFLE(0, 0, 0, 0)));
+ _mm_store_ss(dstl + (17 + i)*nch, _mm_shuffle_ps(b, b, _MM_SHUFFLE(0, 0, 0, 0)));
+ _mm_store_ss(dstr + (47 - i)*nch, _mm_shuffle_ps(a, a, _MM_SHUFFLE(3, 3, 3, 3)));
+ _mm_store_ss(dstr + (49 + i)*nch, _mm_shuffle_ps(b, b, _MM_SHUFFLE(3, 3, 3, 3)));
+ _mm_store_ss(dstl + (47 - i)*nch, _mm_shuffle_ps(a, a, _MM_SHUFFLE(2, 2, 2, 2)));
+ _mm_store_ss(dstl + (49 + i)*nch, _mm_shuffle_ps(b, b, _MM_SHUFFLE(2, 2, 2, 2)));
+#else /* HAVE_SSE */
+ vst1q_lane_f32(dstr + (15 - i)*nch, a, 1);
+ vst1q_lane_f32(dstr + (17 + i)*nch, b, 1);
+ vst1q_lane_f32(dstl + (15 - i)*nch, a, 0);
+ vst1q_lane_f32(dstl + (17 + i)*nch, b, 0);
+ vst1q_lane_f32(dstr + (47 - i)*nch, a, 3);
+ vst1q_lane_f32(dstr + (49 + i)*nch, b, 3);
+ vst1q_lane_f32(dstl + (47 - i)*nch, a, 2);
+ vst1q_lane_f32(dstl + (49 + i)*nch, b, 2);
+#endif /* HAVE_SSE */
+#endif /* MINIMP3_FLOAT_OUTPUT */
+ }
+ } else
+#endif /* HAVE_SIMD */
+#ifdef MINIMP3_ONLY_SIMD
+ {} /* for HAVE_SIMD=1, MINIMP3_ONLY_SIMD=1 case we do not need non-intrinsic "else" branch */
+#else /* MINIMP3_ONLY_SIMD */
+ for (i = 14; i >= 0; i--)
+ {
+#define LOAD(k) float w0 = *w++; float w1 = *w++; float *vz = &zlin[4*i - k*64]; float *vy = &zlin[4*i - (15 - k)*64];
+#define S0(k) { int j; LOAD(k); for (j = 0; j < 4; j++) b[j] = vz[j]*w1 + vy[j]*w0, a[j] = vz[j]*w0 - vy[j]*w1; }
+#define S1(k) { int j; LOAD(k); for (j = 0; j < 4; j++) b[j] += vz[j]*w1 + vy[j]*w0, a[j] += vz[j]*w0 - vy[j]*w1; }
+#define S2(k) { int j; LOAD(k); for (j = 0; j < 4; j++) b[j] += vz[j]*w1 + vy[j]*w0, a[j] += vy[j]*w1 - vz[j]*w0; }
+ float a[4], b[4];
+
+ zlin[4*i] = xl[18*(31 - i)];
+ zlin[4*i + 1] = xr[18*(31 - i)];
+ zlin[4*i + 2] = xl[1 + 18*(31 - i)];
+ zlin[4*i + 3] = xr[1 + 18*(31 - i)];
+ zlin[4*(i + 16)] = xl[1 + 18*(1 + i)];
+ zlin[4*(i + 16) + 1] = xr[1 + 18*(1 + i)];
+ zlin[4*(i - 16) + 2] = xl[18*(1 + i)];
+ zlin[4*(i - 16) + 3] = xr[18*(1 + i)];
+
+ S0(0) S2(1) S1(2) S2(3) S1(4) S2(5) S1(6) S2(7)
+
+ dstr[(15 - i)*nch] = mp3d_scale_pcm(a[1]);
+ dstr[(17 + i)*nch] = mp3d_scale_pcm(b[1]);
+ dstl[(15 - i)*nch] = mp3d_scale_pcm(a[0]);
+ dstl[(17 + i)*nch] = mp3d_scale_pcm(b[0]);
+ dstr[(47 - i)*nch] = mp3d_scale_pcm(a[3]);
+ dstr[(49 + i)*nch] = mp3d_scale_pcm(b[3]);
+ dstl[(47 - i)*nch] = mp3d_scale_pcm(a[2]);
+ dstl[(49 + i)*nch] = mp3d_scale_pcm(b[2]);
+ }
+#endif /* MINIMP3_ONLY_SIMD */
+}
+
+static void mp3d_synth_granule(float *qmf_state, float *grbuf, int nbands, int nch, mp3d_sample_t *pcm, float *lins)
+{
+ int i;
+ for (i = 0; i < nch; i++)
+ {
+ mp3d_DCT_II(grbuf + 576*i, nbands);
+ }
+
+ memcpy(lins, qmf_state, sizeof(float)*15*64);
+
+ for (i = 0; i < nbands; i += 2)
+ {
+ mp3d_synth(grbuf + i, pcm + 32*nch*i, nch, lins + i*64);
+ }
+#ifndef MINIMP3_NONSTANDARD_BUT_LOGICAL
+ if (nch == 1)
+ {
+ for (i = 0; i < 15*64; i += 2)
+ {
+ qmf_state[i] = lins[nbands*64 + i];
+ }
+ } else
+#endif /* MINIMP3_NONSTANDARD_BUT_LOGICAL */
+ {
+ memcpy(qmf_state, lins + nbands*64, sizeof(float)*15*64);
+ }
+}
+
+static int mp3d_match_frame(const uint8_t *hdr, int mp3_bytes, int frame_bytes)
+{
+ int i, nmatch;
+ for (i = 0, nmatch = 0; nmatch < MAX_FRAME_SYNC_MATCHES; nmatch++)
+ {
+ i += hdr_frame_bytes(hdr + i, frame_bytes) + hdr_padding(hdr + i);
+ if (i + HDR_SIZE > mp3_bytes)
+ return nmatch > 0;
+ if (!hdr_compare(hdr, hdr + i))
+ return 0;
+ }
+ return 1;
+}
+
+static int mp3d_find_frame(const uint8_t *mp3, int mp3_bytes, int *free_format_bytes, int *ptr_frame_bytes)
+{
+ int i, k;
+ for (i = 0; i < mp3_bytes - HDR_SIZE; i++, mp3++)
+ {
+ if (hdr_valid(mp3))
+ {
+ int frame_bytes = hdr_frame_bytes(mp3, *free_format_bytes);
+ int frame_and_padding = frame_bytes + hdr_padding(mp3);
+
+ for (k = HDR_SIZE; !frame_bytes && k < MAX_FREE_FORMAT_FRAME_SIZE && i + 2*k < mp3_bytes - HDR_SIZE; k++)
+ {
+ if (hdr_compare(mp3, mp3 + k))
+ {
+ int fb = k - hdr_padding(mp3);
+ int nextfb = fb + hdr_padding(mp3 + k);
+ if (i + k + nextfb + HDR_SIZE > mp3_bytes || !hdr_compare(mp3, mp3 + k + nextfb))
+ continue;
+ frame_and_padding = k;
+ frame_bytes = fb;
+ *free_format_bytes = fb;
+ }
+ }
+ if ((frame_bytes && i + frame_and_padding <= mp3_bytes &&
+ mp3d_match_frame(mp3, mp3_bytes - i, frame_bytes)) ||
+ (!i && frame_and_padding == mp3_bytes))
+ {
+ *ptr_frame_bytes = frame_and_padding;
+ return i;
+ }
+ *free_format_bytes = 0;
+ }
+ }
+ *ptr_frame_bytes = 0;
+ return mp3_bytes;
+}
+
+void mp3dec_init(mp3dec_t *dec)
+{
+ dec->header[0] = 0;
+}
+
+int mp3dec_decode_frame(mp3dec_t *dec, const uint8_t *mp3, int mp3_bytes, mp3d_sample_t *pcm, mp3dec_frame_info_t *info)
+{
+ int i = 0, igr, frame_size = 0, success = 1;
+ const uint8_t *hdr;
+ bs_t bs_frame[1];
+ mp3dec_scratch_t scratch;
+
+ if (mp3_bytes > 4 && dec->header[0] == 0xff && hdr_compare(dec->header, mp3))
+ {
+ frame_size = hdr_frame_bytes(mp3, dec->free_format_bytes) + hdr_padding(mp3);
+ if (frame_size != mp3_bytes && (frame_size + HDR_SIZE > mp3_bytes || !hdr_compare(mp3, mp3 + frame_size)))
+ {
+ frame_size = 0;
+ }
+ }
+ if (!frame_size)
+ {
+ memset(dec, 0, sizeof(mp3dec_t));
+ i = mp3d_find_frame(mp3, mp3_bytes, &dec->free_format_bytes, &frame_size);
+ if (!frame_size || i + frame_size > mp3_bytes)
+ {
+ info->frame_bytes = i;
+ return 0;
+ }
+ }
+
+ hdr = mp3 + i;
+ memcpy(dec->header, hdr, HDR_SIZE);
+ info->frame_bytes = i + frame_size;
+ info->frame_offset = i;
+ info->channels = HDR_IS_MONO(hdr) ? 1 : 2;
+ info->hz = hdr_sample_rate_hz(hdr);
+ info->layer = 4 - HDR_GET_LAYER(hdr);
+ info->bitrate_kbps = hdr_bitrate_kbps(hdr);
+
+ if (!pcm)
+ {
+ return hdr_frame_samples(hdr);
+ }
+
+ bs_init(bs_frame, hdr + HDR_SIZE, frame_size - HDR_SIZE);
+ if (HDR_IS_CRC(hdr))
+ {
+ get_bits(bs_frame, 16);
+ }
+
+ if (info->layer == 3)
+ {
+ int main_data_begin = L3_read_side_info(bs_frame, scratch.gr_info, hdr);
+ if (main_data_begin < 0 || bs_frame->pos > bs_frame->limit)
+ {
+ mp3dec_init(dec);
+ return 0;
+ }
+ success = L3_restore_reservoir(dec, bs_frame, &scratch, main_data_begin);
+ if (success)
+ {
+ for (igr = 0; igr < (HDR_TEST_MPEG1(hdr) ? 2 : 1); igr++, pcm += 576*info->channels)
+ {
+ memset(scratch.grbuf[0], 0, 576*2*sizeof(float));
+ L3_decode(dec, &scratch, scratch.gr_info + igr*info->channels, info->channels);
+ mp3d_synth_granule(dec->qmf_state, scratch.grbuf[0], 18, info->channels, pcm, scratch.syn[0]);
+ }
+ }
+ L3_save_reservoir(dec, &scratch);
+ } else
+ {
+#ifdef MINIMP3_ONLY_MP3
+ return 0;
+#else /* MINIMP3_ONLY_MP3 */
+ L12_scale_info sci[1];
+ L12_read_scale_info(hdr, bs_frame, sci);
+
+ memset(scratch.grbuf[0], 0, 576*2*sizeof(float));
+ for (i = 0, igr = 0; igr < 3; igr++)
+ {
+ if (12 == (i += L12_dequantize_granule(scratch.grbuf[0] + i, bs_frame, sci, info->layer | 1)))
+ {
+ i = 0;
+ L12_apply_scf_384(sci, sci->scf + igr, scratch.grbuf[0]);
+ mp3d_synth_granule(dec->qmf_state, scratch.grbuf[0], 12, info->channels, pcm, scratch.syn[0]);
+ memset(scratch.grbuf[0], 0, 576*2*sizeof(float));
+ pcm += 384*info->channels;
+ }
+ if (bs_frame->pos > bs_frame->limit)
+ {
+ mp3dec_init(dec);
+ return 0;
+ }
+ }
+#endif /* MINIMP3_ONLY_MP3 */
+ }
+ return success*hdr_frame_samples(dec->header);
+}
+
+#ifdef MINIMP3_FLOAT_OUTPUT
+void mp3dec_f32_to_s16(const float *in, int16_t *out, int num_samples)
+{
+ int i = 0;
+#if HAVE_SIMD
+ int aligned_count = num_samples & ~7;
+ for(; i < aligned_count; i += 8)
+ {
+ static const f4 g_scale = { 32768.0f, 32768.0f, 32768.0f, 32768.0f };
+ f4 a = VMUL(VLD(&in[i ]), g_scale);
+ f4 b = VMUL(VLD(&in[i+4]), g_scale);
+#if HAVE_SSE
+ static const f4 g_max = { 32767.0f, 32767.0f, 32767.0f, 32767.0f };
+ static const f4 g_min = { -32768.0f, -32768.0f, -32768.0f, -32768.0f };
+ __m128i pcm8 = _mm_packs_epi32(_mm_cvtps_epi32(_mm_max_ps(_mm_min_ps(a, g_max), g_min)),
+ _mm_cvtps_epi32(_mm_max_ps(_mm_min_ps(b, g_max), g_min)));
+ out[i ] = _mm_extract_epi16(pcm8, 0);
+ out[i+1] = _mm_extract_epi16(pcm8, 1);
+ out[i+2] = _mm_extract_epi16(pcm8, 2);
+ out[i+3] = _mm_extract_epi16(pcm8, 3);
+ out[i+4] = _mm_extract_epi16(pcm8, 4);
+ out[i+5] = _mm_extract_epi16(pcm8, 5);
+ out[i+6] = _mm_extract_epi16(pcm8, 6);
+ out[i+7] = _mm_extract_epi16(pcm8, 7);
+#else /* HAVE_SSE */
+ int16x4_t pcma, pcmb;
+ a = VADD(a, VSET(0.5f));
+ b = VADD(b, VSET(0.5f));
+ pcma = vqmovn_s32(vqaddq_s32(vcvtq_s32_f32(a), vreinterpretq_s32_u32(vcltq_f32(a, VSET(0)))));
+ pcmb = vqmovn_s32(vqaddq_s32(vcvtq_s32_f32(b), vreinterpretq_s32_u32(vcltq_f32(b, VSET(0)))));
+ vst1_lane_s16(out+i , pcma, 0);
+ vst1_lane_s16(out+i+1, pcma, 1);
+ vst1_lane_s16(out+i+2, pcma, 2);
+ vst1_lane_s16(out+i+3, pcma, 3);
+ vst1_lane_s16(out+i+4, pcmb, 0);
+ vst1_lane_s16(out+i+5, pcmb, 1);
+ vst1_lane_s16(out+i+6, pcmb, 2);
+ vst1_lane_s16(out+i+7, pcmb, 3);
+#endif /* HAVE_SSE */
+ }
+#endif /* HAVE_SIMD */
+ for(; i < num_samples; i++)
+ {
+ float sample = in[i] * 32768.0f;
+ if (sample >= 32766.5)
+ out[i] = (int16_t) 32767;
+ else if (sample <= -32767.5)
+ out[i] = (int16_t)-32768;
+ else
+ {
+ int16_t s = (int16_t)(sample + .5f);
+ s -= (s < 0); /* away from zero, to be compliant */
+ out[i] = s;
+ }
+ }
+}
+#endif /* MINIMP3_FLOAT_OUTPUT */
+#endif /* MINIMP3_IMPLEMENTATION && !_MINIMP3_IMPLEMENTATION_GUARD */
diff --git a/src/codecs/minimp3/minimp3_ex.h b/src/codecs/minimp3/minimp3_ex.h
new file mode 100644
index 000000000..2cea33646
--- /dev/null
+++ b/src/codecs/minimp3/minimp3_ex.h
@@ -0,0 +1,1393 @@
+#ifndef MINIMP3_EXT_H
+#define MINIMP3_EXT_H
+/*
+ https://github.com/lieff/minimp3
+ To the extent possible under law, the author(s) have dedicated all copyright and related and neighboring rights to this software to the public domain worldwide.
+ This software is distributed without any warranty.
+ See .
+*/
+#include
+#include "minimp3.h"
+
+/* flags for mp3dec_ex_open_* functions */
+#define MP3D_SEEK_TO_BYTE 0 /* mp3dec_ex_seek seeks to byte in stream */
+#define MP3D_SEEK_TO_SAMPLE 1 /* mp3dec_ex_seek precisely seeks to sample using index (created during duration calculation scan or when mp3dec_ex_seek called) */
+#define MP3D_DO_NOT_SCAN 2 /* do not scan whole stream for duration if vbrtag not found, mp3dec_ex_t::samples will be filled only if mp3dec_ex_t::vbr_tag_found == 1 */
+#ifdef MINIMP3_ALLOW_MONO_STEREO_TRANSITION
+#define MP3D_ALLOW_MONO_STEREO_TRANSITION 4
+#define MP3D_FLAGS_MASK 7
+#else
+#define MP3D_FLAGS_MASK 3
+#endif
+
+/* compile-time config */
+#define MINIMP3_PREDECODE_FRAMES 2 /* frames to pre-decode and skip after seek (to fill internal structures) */
+/*#define MINIMP3_SEEK_IDX_LINEAR_SEARCH*/ /* define to use linear index search instead of binary search on seek */
+#define MINIMP3_IO_SIZE (128*1024) /* io buffer size for streaming functions, must be greater than MINIMP3_BUF_SIZE */
+#define MINIMP3_BUF_SIZE (16*1024) /* buffer which can hold minimum 10 consecutive mp3 frames (~16KB) worst case */
+/*#define MINIMP3_SCAN_LIMIT (256*1024)*/ /* how many bytes will be scanned to search first valid mp3 frame, to prevent stall on large non-mp3 files */
+#define MINIMP3_ENABLE_RING 0 /* WIP enable hardware magic ring buffer if available, to make less input buffer memmove(s) in callback IO mode */
+
+/* return error codes */
+#define MP3D_E_PARAM -1
+#define MP3D_E_MEMORY -2
+#define MP3D_E_IOERROR -3
+#define MP3D_E_USER -4 /* can be used to stop processing from callbacks without indicating specific error */
+#define MP3D_E_DECODE -5 /* decode error which can't be safely skipped, such as sample rate, layer and channels change */
+
+typedef struct
+{
+ mp3d_sample_t *buffer;
+ size_t samples; /* channels included, byte size = samples*sizeof(mp3d_sample_t) */
+ int channels, hz, layer, avg_bitrate_kbps;
+} mp3dec_file_info_t;
+
+typedef struct
+{
+ const uint8_t *buffer;
+ size_t size;
+} mp3dec_map_info_t;
+
+typedef struct
+{
+ uint64_t sample;
+ uint64_t offset;
+} mp3dec_frame_t;
+
+typedef struct
+{
+ mp3dec_frame_t *frames;
+ size_t num_frames, capacity;
+} mp3dec_index_t;
+
+typedef size_t (*MP3D_READ_CB)(void *buf, size_t size, void *user_data);
+typedef int (*MP3D_SEEK_CB)(uint64_t position, void *user_data);
+
+typedef struct
+{
+ MP3D_READ_CB read;
+ void *read_data;
+ MP3D_SEEK_CB seek;
+ void *seek_data;
+} mp3dec_io_t;
+
+typedef struct
+{
+ mp3dec_t mp3d;
+ mp3dec_map_info_t file;
+ mp3dec_io_t *io;
+ mp3dec_index_t index;
+ uint64_t offset, samples, detected_samples, cur_sample, start_offset, end_offset;
+ mp3dec_frame_info_t info;
+ mp3d_sample_t buffer[MINIMP3_MAX_SAMPLES_PER_FRAME];
+ size_t input_consumed, input_filled;
+ int is_file, flags, vbr_tag_found, indexes_built;
+ int free_format_bytes;
+ int buffer_samples, buffer_consumed, to_skip, start_delay;
+ int last_error;
+} mp3dec_ex_t;
+
+typedef int (*MP3D_ITERATE_CB)(void *user_data, const uint8_t *frame, int frame_size, int free_format_bytes, size_t buf_size, uint64_t offset, mp3dec_frame_info_t *info);
+typedef int (*MP3D_PROGRESS_CB)(void *user_data, size_t file_size, uint64_t offset, mp3dec_frame_info_t *info);
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* detect mp3/mpa format */
+int mp3dec_detect_buf(const uint8_t *buf, size_t buf_size);
+int mp3dec_detect_cb(mp3dec_io_t *io, uint8_t *buf, size_t buf_size);
+/* decode whole buffer block */
+int mp3dec_load_buf(mp3dec_t *dec, const uint8_t *buf, size_t buf_size, mp3dec_file_info_t *info, MP3D_PROGRESS_CB progress_cb, void *user_data);
+int mp3dec_load_cb(mp3dec_t *dec, mp3dec_io_t *io, uint8_t *buf, size_t buf_size, mp3dec_file_info_t *info, MP3D_PROGRESS_CB progress_cb, void *user_data);
+/* iterate through frames */
+int mp3dec_iterate_buf(const uint8_t *buf, size_t buf_size, MP3D_ITERATE_CB callback, void *user_data);
+int mp3dec_iterate_cb(mp3dec_io_t *io, uint8_t *buf, size_t buf_size, MP3D_ITERATE_CB callback, void *user_data);
+/* streaming decoder with seeking capability */
+int mp3dec_ex_open_buf(mp3dec_ex_t *dec, const uint8_t *buf, size_t buf_size, int flags);
+int mp3dec_ex_open_cb(mp3dec_ex_t *dec, mp3dec_io_t *io, int flags);
+void mp3dec_ex_close(mp3dec_ex_t *dec);
+int mp3dec_ex_seek(mp3dec_ex_t *dec, uint64_t position);
+size_t mp3dec_ex_read_frame(mp3dec_ex_t *dec, mp3d_sample_t **buf, mp3dec_frame_info_t *frame_info, size_t max_samples);
+size_t mp3dec_ex_read(mp3dec_ex_t *dec, mp3d_sample_t *buf, size_t samples);
+#ifndef MINIMP3_NO_STDIO
+/* stdio versions of file detect, load, iterate and stream */
+int mp3dec_detect(const char *file_name);
+int mp3dec_load(mp3dec_t *dec, const char *file_name, mp3dec_file_info_t *info, MP3D_PROGRESS_CB progress_cb, void *user_data);
+int mp3dec_iterate(const char *file_name, MP3D_ITERATE_CB callback, void *user_data);
+int mp3dec_ex_open(mp3dec_ex_t *dec, const char *file_name, int flags);
+#ifdef _WIN32
+int mp3dec_detect_w(const wchar_t *file_name);
+int mp3dec_load_w(mp3dec_t *dec, const wchar_t *file_name, mp3dec_file_info_t *info, MP3D_PROGRESS_CB progress_cb, void *user_data);
+int mp3dec_iterate_w(const wchar_t *file_name, MP3D_ITERATE_CB callback, void *user_data);
+int mp3dec_ex_open_w(mp3dec_ex_t *dec, const wchar_t *file_name, int flags);
+#endif
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+#endif /*MINIMP3_EXT_H*/
+
+#if defined(MINIMP3_IMPLEMENTATION) && !defined(_MINIMP3_EX_IMPLEMENTATION_GUARD)
+#define _MINIMP3_EX_IMPLEMENTATION_GUARD
+#include
+#include "minimp3.h"
+
+static void mp3dec_skip_id3v1(const uint8_t *buf, size_t *pbuf_size)
+{
+ size_t buf_size = *pbuf_size;
+#ifndef MINIMP3_NOSKIP_ID3V1
+ if (buf_size >= 128 && !memcmp(buf + buf_size - 128, "TAG", 3))
+ buf_size -= 128;
+#endif
+#ifndef MINIMP3_NOSKIP_APEV2
+ if (buf_size > 32 && !memcmp(buf + buf_size - 32, "APETAGEX", 8))
+ {
+ buf_size -= 32;
+ const uint8_t *tag = buf + buf_size + 8 + 4;
+ uint32_t tag_size = (uint32_t)(tag[3] << 24) | (tag[2] << 16) | (tag[1] << 8) | tag[0];
+ if (buf_size >= tag_size)
+ buf_size -= tag_size;
+ }
+#endif
+ *pbuf_size = buf_size;
+}
+
+static size_t mp3dec_skip_id3v2(const uint8_t *buf, size_t buf_size)
+{
+#define MINIMP3_ID3_DETECT_SIZE 10
+#ifndef MINIMP3_NOSKIP_ID3V2
+ if (buf_size >= MINIMP3_ID3_DETECT_SIZE && !memcmp(buf, "ID3", 3) && !((buf[5] & 15) || (buf[6] & 0x80) || (buf[7] & 0x80) || (buf[8] & 0x80) || (buf[9] & 0x80)))
+ {
+ size_t id3v2size = (((buf[6] & 0x7f) << 21) | ((buf[7] & 0x7f) << 14) | ((buf[8] & 0x7f) << 7) | (buf[9] & 0x7f)) + 10;
+ if ((buf[5] & 16))
+ id3v2size += 10; /* footer */
+ return id3v2size;
+ }
+#endif
+ return 0;
+}
+
+static void mp3dec_skip_id3(const uint8_t **pbuf, size_t *pbuf_size)
+{
+ uint8_t *buf = (uint8_t *)(*pbuf);
+ size_t buf_size = *pbuf_size;
+ size_t id3v2size = mp3dec_skip_id3v2(buf, buf_size);
+ if (id3v2size)
+ {
+ if (id3v2size >= buf_size)
+ id3v2size = buf_size;
+ buf += id3v2size;
+ buf_size -= id3v2size;
+ }
+ mp3dec_skip_id3v1(buf, &buf_size);
+ *pbuf = (const uint8_t *)buf;
+ *pbuf_size = buf_size;
+}
+
+static int mp3dec_check_vbrtag(const uint8_t *frame, int frame_size, uint32_t *frames, int *delay, int *padding)
+{
+ static const char g_xing_tag[4] = { 'X', 'i', 'n', 'g' };
+ static const char g_info_tag[4] = { 'I', 'n', 'f', 'o' };
+#define FRAMES_FLAG 1
+#define BYTES_FLAG 2
+#define TOC_FLAG 4
+#define VBR_SCALE_FLAG 8
+ /* Side info offsets after header:
+ / Mono Stereo
+ / MPEG1 17 32
+ / MPEG2 & 2.5 9 17*/
+ bs_t bs[1];
+ L3_gr_info_t gr_info[4];
+ bs_init(bs, frame + HDR_SIZE, frame_size - HDR_SIZE);
+ if (HDR_IS_CRC(frame))
+ get_bits(bs, 16);
+ if (L3_read_side_info(bs, gr_info, frame) < 0)
+ return 0; /* side info corrupted */
+
+ const uint8_t *tag = frame + HDR_SIZE + bs->pos/8;
+ if (memcmp(g_xing_tag, tag, 4) && memcmp(g_info_tag, tag, 4))
+ return 0;
+ int flags = tag[7];
+ if (!((flags & FRAMES_FLAG)))
+ return -1;
+ tag += 8;
+ *frames = (uint32_t)(tag[0] << 24) | (tag[1] << 16) | (tag[2] << 8) | tag[3];
+ tag += 4;
+ if (flags & BYTES_FLAG)
+ tag += 4;
+ if (flags & TOC_FLAG)
+ tag += 100;
+ if (flags & VBR_SCALE_FLAG)
+ tag += 4;
+ *delay = *padding = 0;
+ if (*tag)
+ { /* extension, LAME, Lavc, etc. Should be the same structure. */
+ tag += 21;
+ if (tag - frame + 14 >= frame_size)
+ return 0;
+ *delay = ((tag[0] << 4) | (tag[1] >> 4)) + (528 + 1);
+ *padding = (((tag[1] & 0xF) << 8) | tag[2]) - (528 + 1);
+ }
+ return 1;
+}
+
+int mp3dec_detect_buf(const uint8_t *buf, size_t buf_size)
+{
+ return mp3dec_detect_cb(0, (uint8_t *)buf, buf_size);
+}
+
+int mp3dec_detect_cb(mp3dec_io_t *io, uint8_t *buf, size_t buf_size)
+{
+ if (!buf || (size_t)-1 == buf_size || (io && buf_size < MINIMP3_BUF_SIZE))
+ return MP3D_E_PARAM;
+ size_t filled = buf_size;
+ if (io)
+ {
+ if (io->seek(0, io->seek_data))
+ return MP3D_E_IOERROR;
+ filled = io->read(buf, MINIMP3_ID3_DETECT_SIZE, io->read_data);
+ if (filled > MINIMP3_ID3_DETECT_SIZE)
+ return MP3D_E_IOERROR;
+ }
+ if (filled < MINIMP3_ID3_DETECT_SIZE)
+ return MP3D_E_USER; /* too small, can't be mp3/mpa */
+ if (mp3dec_skip_id3v2(buf, filled))
+ return 0; /* id3v2 tag is enough evidence */
+ if (io)
+ {
+ size_t readed = io->read(buf + MINIMP3_ID3_DETECT_SIZE, buf_size - MINIMP3_ID3_DETECT_SIZE, io->read_data);
+ if (readed > (buf_size - MINIMP3_ID3_DETECT_SIZE))
+ return MP3D_E_IOERROR;
+ filled += readed;
+ if (filled < MINIMP3_BUF_SIZE)
+ mp3dec_skip_id3v1(buf, &filled);
+ } else
+ {
+ mp3dec_skip_id3v1(buf, &filled);
+ if (filled > MINIMP3_BUF_SIZE)
+ filled = MINIMP3_BUF_SIZE;
+ }
+ int free_format_bytes, frame_size;
+ mp3d_find_frame(buf, filled, &free_format_bytes, &frame_size);
+ if (frame_size)
+ return 0; /* MAX_FRAME_SYNC_MATCHES consecutive frames found */
+ return MP3D_E_USER;
+}
+
+int mp3dec_load_buf(mp3dec_t *dec, const uint8_t *buf, size_t buf_size, mp3dec_file_info_t *info, MP3D_PROGRESS_CB progress_cb, void *user_data)
+{
+ return mp3dec_load_cb(dec, 0, (uint8_t *)buf, buf_size, info, progress_cb, user_data);
+}
+
+int mp3dec_load_cb(mp3dec_t *dec, mp3dec_io_t *io, uint8_t *buf, size_t buf_size, mp3dec_file_info_t *info, MP3D_PROGRESS_CB progress_cb, void *user_data)
+{
+ if (!dec || !buf || !info || (size_t)-1 == buf_size || (io && buf_size < MINIMP3_BUF_SIZE))
+ return MP3D_E_PARAM;
+ uint64_t detected_samples = 0;
+ size_t orig_buf_size = buf_size;
+ int to_skip = 0;
+ mp3dec_frame_info_t frame_info;
+ memset(info, 0, sizeof(*info));
+ memset(&frame_info, 0, sizeof(frame_info));
+
+ /* skip id3 */
+ size_t filled = 0, consumed = 0;
+ int eof = 0, ret = 0;
+ if (io)
+ {
+ if (io->seek(0, io->seek_data))
+ return MP3D_E_IOERROR;
+ filled = io->read(buf, MINIMP3_ID3_DETECT_SIZE, io->read_data);
+ if (filled > MINIMP3_ID3_DETECT_SIZE)
+ return MP3D_E_IOERROR;
+ if (MINIMP3_ID3_DETECT_SIZE != filled)
+ return 0;
+ size_t id3v2size = mp3dec_skip_id3v2(buf, filled);
+ if (id3v2size)
+ {
+ if (io->seek(id3v2size, io->seek_data))
+ return MP3D_E_IOERROR;
+ filled = io->read(buf, buf_size, io->read_data);
+ if (filled > buf_size)
+ return MP3D_E_IOERROR;
+ } else
+ {
+ size_t readed = io->read(buf + MINIMP3_ID3_DETECT_SIZE, buf_size - MINIMP3_ID3_DETECT_SIZE, io->read_data);
+ if (readed > (buf_size - MINIMP3_ID3_DETECT_SIZE))
+ return MP3D_E_IOERROR;
+ filled += readed;
+ }
+ if (filled < MINIMP3_BUF_SIZE)
+ mp3dec_skip_id3v1(buf, &filled);
+ } else
+ {
+ mp3dec_skip_id3((const uint8_t **)&buf, &buf_size);
+ if (!buf_size)
+ return 0;
+ }
+ /* try to make allocation size assumption by first frame or vbr tag */
+ mp3dec_init(dec);
+ int samples;
+ do
+ {
+ uint32_t frames;
+ int i, delay, padding, free_format_bytes = 0, frame_size = 0;
+ const uint8_t *hdr;
+ if (io)
+ {
+ if (!eof && filled - consumed < MINIMP3_BUF_SIZE)
+ { /* keep minimum 10 consecutive mp3 frames (~16KB) worst case */
+ memmove(buf, buf + consumed, filled - consumed);
+ filled -= consumed;
+ consumed = 0;
+ size_t readed = io->read(buf + filled, buf_size - filled, io->read_data);
+ if (readed > (buf_size - filled))
+ return MP3D_E_IOERROR;
+ if (readed != (buf_size - filled))
+ eof = 1;
+ filled += readed;
+ if (eof)
+ mp3dec_skip_id3v1(buf, &filled);
+ }
+ i = mp3d_find_frame(buf + consumed, filled - consumed, &free_format_bytes, &frame_size);
+ consumed += i;
+ hdr = buf + consumed;
+ } else
+ {
+ i = mp3d_find_frame(buf, buf_size, &free_format_bytes, &frame_size);
+ buf += i;
+ buf_size -= i;
+ hdr = buf;
+ }
+ if (i && !frame_size)
+ continue;
+ if (!frame_size)
+ return 0;
+ frame_info.channels = HDR_IS_MONO(hdr) ? 1 : 2;
+ frame_info.hz = hdr_sample_rate_hz(hdr);
+ frame_info.layer = 4 - HDR_GET_LAYER(hdr);
+ frame_info.bitrate_kbps = hdr_bitrate_kbps(hdr);
+ frame_info.frame_bytes = frame_size;
+ samples = hdr_frame_samples(hdr)*frame_info.channels;
+ if (3 != frame_info.layer)
+ break;
+ int ret = mp3dec_check_vbrtag(hdr, frame_size, &frames, &delay, &padding);
+ if (ret > 0)
+ {
+ padding *= frame_info.channels;
+ to_skip = delay*frame_info.channels;
+ detected_samples = samples*(uint64_t)frames;
+ if (detected_samples >= (uint64_t)to_skip)
+ detected_samples -= to_skip;
+ if (padding > 0 && detected_samples >= (uint64_t)padding)
+ detected_samples -= padding;
+ if (!detected_samples)
+ return 0;
+ }
+ if (ret)
+ {
+ if (io)
+ {
+ consumed += frame_size;
+ } else
+ {
+ buf += frame_size;
+ buf_size -= frame_size;
+ }
+ }
+ break;
+ } while(1);
+ size_t allocated = MINIMP3_MAX_SAMPLES_PER_FRAME*sizeof(mp3d_sample_t);
+ if (detected_samples)
+ allocated += detected_samples*sizeof(mp3d_sample_t);
+ else
+ allocated += (buf_size/frame_info.frame_bytes)*samples*sizeof(mp3d_sample_t);
+ info->buffer = (mp3d_sample_t*)malloc(allocated);
+ if (!info->buffer)
+ return MP3D_E_MEMORY;
+ /* save info */
+ info->channels = frame_info.channels;
+ info->hz = frame_info.hz;
+ info->layer = frame_info.layer;
+ /* decode all frames */
+ size_t avg_bitrate_kbps = 0, frames = 0;
+ do
+ {
+ if ((allocated - info->samples*sizeof(mp3d_sample_t)) < MINIMP3_MAX_SAMPLES_PER_FRAME*sizeof(mp3d_sample_t))
+ {
+ allocated *= 2;
+ mp3d_sample_t *alloc_buf = (mp3d_sample_t*)realloc(info->buffer, allocated);
+ if (!alloc_buf)
+ return MP3D_E_MEMORY;
+ info->buffer = alloc_buf;
+ }
+ if (io)
+ {
+ if (!eof && filled - consumed < MINIMP3_BUF_SIZE)
+ { /* keep minimum 10 consecutive mp3 frames (~16KB) worst case */
+ memmove(buf, buf + consumed, filled - consumed);
+ filled -= consumed;
+ consumed = 0;
+ size_t readed = io->read(buf + filled, buf_size - filled, io->read_data);
+ if (readed != (buf_size - filled))
+ eof = 1;
+ filled += readed;
+ if (eof)
+ mp3dec_skip_id3v1(buf, &filled);
+ }
+ samples = mp3dec_decode_frame(dec, buf + consumed, filled - consumed, info->buffer + info->samples, &frame_info);
+ consumed += frame_info.frame_bytes;
+ } else
+ {
+ samples = mp3dec_decode_frame(dec, buf, MINIMP3_MIN(buf_size, (size_t)INT_MAX), info->buffer + info->samples, &frame_info);
+ buf += frame_info.frame_bytes;
+ buf_size -= frame_info.frame_bytes;
+ }
+ if (samples)
+ {
+ if (info->hz != frame_info.hz || info->layer != frame_info.layer)
+ {
+ ret = MP3D_E_DECODE;
+ break;
+ }
+ if (info->channels && info->channels != frame_info.channels)
+ {
+#ifdef MINIMP3_ALLOW_MONO_STEREO_TRANSITION
+ info->channels = 0; /* mark file with mono-stereo transition */
+#else
+ ret = MP3D_E_DECODE;
+ break;
+#endif
+ }
+ samples *= frame_info.channels;
+ if (to_skip)
+ {
+ size_t skip = MINIMP3_MIN(samples, to_skip);
+ to_skip -= skip;
+ samples -= skip;
+ memmove(info->buffer, info->buffer + skip, samples*sizeof(mp3d_sample_t));
+ }
+ info->samples += samples;
+ avg_bitrate_kbps += frame_info.bitrate_kbps;
+ frames++;
+ if (progress_cb)
+ {
+ ret = progress_cb(user_data, orig_buf_size, orig_buf_size - buf_size, &frame_info);
+ if (ret)
+ break;
+ }
+ }
+ } while (frame_info.frame_bytes);
+ if (detected_samples && info->samples > detected_samples)
+ info->samples = detected_samples; /* cut padding */
+ /* reallocate to normal buffer size */
+ if (allocated != info->samples*sizeof(mp3d_sample_t))
+ {
+ mp3d_sample_t *alloc_buf = (mp3d_sample_t*)realloc(info->buffer, info->samples*sizeof(mp3d_sample_t));
+ if (!alloc_buf && info->samples)
+ return MP3D_E_MEMORY;
+ info->buffer = alloc_buf;
+ }
+ if (frames)
+ info->avg_bitrate_kbps = avg_bitrate_kbps/frames;
+ return ret;
+}
+
+int mp3dec_iterate_buf(const uint8_t *buf, size_t buf_size, MP3D_ITERATE_CB callback, void *user_data)
+{
+ const uint8_t *orig_buf = buf;
+ if (!buf || (size_t)-1 == buf_size || !callback)
+ return MP3D_E_PARAM;
+ /* skip id3 */
+ mp3dec_skip_id3(&buf, &buf_size);
+ if (!buf_size)
+ return 0;
+ mp3dec_frame_info_t frame_info;
+ memset(&frame_info, 0, sizeof(frame_info));
+ do
+ {
+ int free_format_bytes = 0, frame_size = 0, ret;
+ int i = mp3d_find_frame(buf, buf_size, &free_format_bytes, &frame_size);
+ buf += i;
+ buf_size -= i;
+ if (i && !frame_size)
+ continue;
+ if (!frame_size)
+ break;
+ const uint8_t *hdr = buf;
+ frame_info.channels = HDR_IS_MONO(hdr) ? 1 : 2;
+ frame_info.hz = hdr_sample_rate_hz(hdr);
+ frame_info.layer = 4 - HDR_GET_LAYER(hdr);
+ frame_info.bitrate_kbps = hdr_bitrate_kbps(hdr);
+ frame_info.frame_bytes = frame_size;
+
+ if (callback)
+ {
+ if ((ret = callback(user_data, hdr, frame_size, free_format_bytes, buf_size, hdr - orig_buf, &frame_info)))
+ return ret;
+ }
+ buf += frame_size;
+ buf_size -= frame_size;
+ } while (1);
+ return 0;
+}
+
+int mp3dec_iterate_cb(mp3dec_io_t *io, uint8_t *buf, size_t buf_size, MP3D_ITERATE_CB callback, void *user_data)
+{
+ if (!io || !buf || (size_t)-1 == buf_size || buf_size < MINIMP3_BUF_SIZE || !callback)
+ return MP3D_E_PARAM;
+ size_t filled = io->read(buf, MINIMP3_ID3_DETECT_SIZE, io->read_data), consumed = 0;
+ uint64_t readed = 0;
+ mp3dec_frame_info_t frame_info;
+ int eof = 0;
+ memset(&frame_info, 0, sizeof(frame_info));
+ if (filled > MINIMP3_ID3_DETECT_SIZE)
+ return MP3D_E_IOERROR;
+ if (MINIMP3_ID3_DETECT_SIZE != filled)
+ return 0;
+ size_t id3v2size = mp3dec_skip_id3v2(buf, filled);
+ if (id3v2size)
+ {
+ if (io->seek(id3v2size, io->seek_data))
+ return MP3D_E_IOERROR;
+ filled = io->read(buf, buf_size, io->read_data);
+ if (filled > buf_size)
+ return MP3D_E_IOERROR;
+ readed += id3v2size;
+ } else
+ {
+ size_t readed = io->read(buf + MINIMP3_ID3_DETECT_SIZE, buf_size - MINIMP3_ID3_DETECT_SIZE, io->read_data);
+ if (readed > (buf_size - MINIMP3_ID3_DETECT_SIZE))
+ return MP3D_E_IOERROR;
+ filled += readed;
+ }
+ if (filled < MINIMP3_BUF_SIZE)
+ mp3dec_skip_id3v1(buf, &filled);
+ do
+ {
+ int free_format_bytes = 0, frame_size = 0, ret;
+ int i = mp3d_find_frame(buf + consumed, filled - consumed, &free_format_bytes, &frame_size);
+ if (i && !frame_size)
+ {
+ consumed += i;
+ continue;
+ }
+ if (!frame_size)
+ break;
+ const uint8_t *hdr = buf + consumed + i;
+ frame_info.channels = HDR_IS_MONO(hdr) ? 1 : 2;
+ frame_info.hz = hdr_sample_rate_hz(hdr);
+ frame_info.layer = 4 - HDR_GET_LAYER(hdr);
+ frame_info.bitrate_kbps = hdr_bitrate_kbps(hdr);
+ frame_info.frame_bytes = frame_size;
+
+ readed += i;
+ if (callback)
+ {
+ if ((ret = callback(user_data, hdr, frame_size, free_format_bytes, filled - consumed, readed, &frame_info)))
+ return ret;
+ }
+ readed += frame_size;
+ consumed += i + frame_size;
+ if (!eof && filled - consumed < MINIMP3_BUF_SIZE)
+ { /* keep minimum 10 consecutive mp3 frames (~16KB) worst case */
+ memmove(buf, buf + consumed, filled - consumed);
+ filled -= consumed;
+ consumed = 0;
+ size_t readed = io->read(buf + filled, buf_size - filled, io->read_data);
+ if (readed > (buf_size - filled))
+ return MP3D_E_IOERROR;
+ if (readed != (buf_size - filled))
+ eof = 1;
+ filled += readed;
+ if (eof)
+ mp3dec_skip_id3v1(buf, &filled);
+ }
+ } while (1);
+ return 0;
+}
+
+static int mp3dec_load_index(void *user_data, const uint8_t *frame, int frame_size, int free_format_bytes, size_t buf_size, uint64_t offset, mp3dec_frame_info_t *info)
+{
+ mp3dec_frame_t *idx_frame;
+ mp3dec_ex_t *dec = (mp3dec_ex_t *)user_data;
+ if (!dec->index.frames && !dec->start_offset)
+ { /* detect VBR tag and try to avoid full scan */
+ uint32_t frames;
+ int delay, padding;
+ dec->info = *info;
+ dec->start_offset = dec->offset = offset;
+ dec->end_offset = offset + buf_size;
+ dec->free_format_bytes = free_format_bytes; /* should not change */
+ if (3 == dec->info.layer)
+ {
+ int ret = mp3dec_check_vbrtag(frame, frame_size, &frames, &delay, &padding);
+ if (ret)
+ dec->start_offset = dec->offset = offset + frame_size;
+ if (ret > 0)
+ {
+ padding *= info->channels;
+ dec->start_delay = dec->to_skip = delay*info->channels;
+ dec->samples = hdr_frame_samples(frame)*info->channels*(uint64_t)frames;
+ if (dec->samples >= (uint64_t)dec->start_delay)
+ dec->samples -= dec->start_delay;
+ if (padding > 0 && dec->samples >= (uint64_t)padding)
+ dec->samples -= padding;
+ dec->detected_samples = dec->samples;
+ dec->vbr_tag_found = 1;
+ return MP3D_E_USER;
+ } else if (ret < 0)
+ return 0;
+ }
+ }
+ if (dec->flags & MP3D_DO_NOT_SCAN)
+ return MP3D_E_USER;
+ if (dec->index.num_frames + 1 > dec->index.capacity)
+ {
+ if (!dec->index.capacity)
+ dec->index.capacity = 4096;
+ else
+ dec->index.capacity *= 2;
+ mp3dec_frame_t *alloc_buf = (mp3dec_frame_t *)realloc((void*)dec->index.frames, sizeof(mp3dec_frame_t)*dec->index.capacity);
+ if (!alloc_buf)
+ return MP3D_E_MEMORY;
+ dec->index.frames = alloc_buf;
+ }
+ idx_frame = &dec->index.frames[dec->index.num_frames++];
+ idx_frame->offset = offset;
+ idx_frame->sample = dec->samples;
+ if (!dec->buffer_samples && dec->index.num_frames < 256)
+ { /* for some cutted mp3 frames, bit-reservoir not filled and decoding can't be started from first frames */
+ /* try to decode up to 255 first frames till samples starts to decode */
+ dec->buffer_samples = mp3dec_decode_frame(&dec->mp3d, frame, MINIMP3_MIN(buf_size, (size_t)INT_MAX), dec->buffer, info);
+ dec->samples += dec->buffer_samples*info->channels;
+ } else
+ dec->samples += hdr_frame_samples(frame)*info->channels;
+ return 0;
+}
+
+int mp3dec_ex_open_buf(mp3dec_ex_t *dec, const uint8_t *buf, size_t buf_size, int flags)
+{
+ if (!dec || !buf || (size_t)-1 == buf_size || (flags & (~MP3D_FLAGS_MASK)))
+ return MP3D_E_PARAM;
+ memset(dec, 0, sizeof(*dec));
+ dec->file.buffer = buf;
+ dec->file.size = buf_size;
+ dec->flags = flags;
+ mp3dec_init(&dec->mp3d);
+ int ret = mp3dec_iterate_buf(dec->file.buffer, dec->file.size, mp3dec_load_index, dec);
+ if (ret && MP3D_E_USER != ret)
+ return ret;
+ mp3dec_init(&dec->mp3d);
+ dec->buffer_samples = 0;
+ dec->indexes_built = !(dec->vbr_tag_found || (flags & MP3D_DO_NOT_SCAN));
+ dec->flags &= (~MP3D_DO_NOT_SCAN);
+ return 0;
+}
+
+#ifndef MINIMP3_SEEK_IDX_LINEAR_SEARCH
+static size_t mp3dec_idx_binary_search(mp3dec_index_t *idx, uint64_t position)
+{
+ size_t end = idx->num_frames, start = 0, index = 0;
+ while (start <= end)
+ {
+ size_t mid = (start + end) / 2;
+ if (idx->frames[mid].sample >= position)
+ { /* move left side. */
+ if (idx->frames[mid].sample == position)
+ return mid;
+ end = mid - 1;
+ } else
+ { /* move to right side */
+ index = mid;
+ start = mid + 1;
+ if (start == idx->num_frames)
+ break;
+ }
+ }
+ return index;
+}
+#endif
+
+int mp3dec_ex_seek(mp3dec_ex_t *dec, uint64_t position)
+{
+ size_t i;
+ if (!dec)
+ return MP3D_E_PARAM;
+ if (!(dec->flags & MP3D_SEEK_TO_SAMPLE))
+ {
+ if (dec->io)
+ {
+ dec->offset = position;
+ } else
+ {
+ dec->offset = MINIMP3_MIN(position, dec->file.size);
+ }
+ dec->cur_sample = 0;
+ goto do_exit;
+ }
+ dec->cur_sample = position;
+ position += dec->start_delay;
+ if (0 == position)
+ { /* optimize seek to zero, no index needed */
+seek_zero:
+ dec->offset = dec->start_offset;
+ dec->to_skip = 0;
+ goto do_exit;
+ }
+ if (!dec->indexes_built)
+ { /* no index created yet (vbr tag used to calculate track length or MP3D_DO_NOT_SCAN open flag used) */
+ dec->indexes_built = 1;
+ dec->samples = 0;
+ dec->buffer_samples = 0;
+ if (dec->io)
+ {
+ if (dec->io->seek(dec->start_offset, dec->io->seek_data))
+ return MP3D_E_IOERROR;
+ int ret = mp3dec_iterate_cb(dec->io, (uint8_t *)dec->file.buffer, dec->file.size, mp3dec_load_index, dec);
+ if (ret && MP3D_E_USER != ret)
+ return ret;
+ } else
+ {
+ int ret = mp3dec_iterate_buf(dec->file.buffer + dec->start_offset, dec->file.size - dec->start_offset, mp3dec_load_index, dec);
+ if (ret && MP3D_E_USER != ret)
+ return ret;
+ }
+ for (i = 0; i < dec->index.num_frames; i++)
+ dec->index.frames[i].offset += dec->start_offset;
+ dec->samples = dec->detected_samples;
+ }
+ if (!dec->index.frames)
+ goto seek_zero; /* no frames in file - seek to zero */
+#ifdef MINIMP3_SEEK_IDX_LINEAR_SEARCH
+ for (i = 0; i < dec->index.num_frames; i++)
+ {
+ if (dec->index.frames[i].sample >= position)
+ break;
+ }
+#else
+ i = mp3dec_idx_binary_search(&dec->index, position);
+#endif
+ if (i)
+ {
+ int to_fill_bytes = 511;
+ int skip_frames = MINIMP3_PREDECODE_FRAMES
+#ifdef MINIMP3_SEEK_IDX_LINEAR_SEARCH
+ + ((dec->index.frames[i].sample == position) ? 0 : 1)
+#endif
+ ;
+ i -= MINIMP3_MIN(i, (size_t)skip_frames);
+ if (3 == dec->info.layer)
+ {
+ while (i && to_fill_bytes)
+ { /* make sure bit-reservoir is filled when we start decoding */
+ bs_t bs[1];
+ L3_gr_info_t gr_info[4];
+ int frame_bytes, frame_size;
+ const uint8_t *hdr;
+ if (dec->io)
+ {
+ hdr = dec->file.buffer;
+ if (dec->io->seek(dec->index.frames[i - 1].offset, dec->io->seek_data))
+ return MP3D_E_IOERROR;
+ size_t readed = dec->io->read((uint8_t *)hdr, HDR_SIZE, dec->io->read_data);
+ if (readed != HDR_SIZE)
+ return MP3D_E_IOERROR;
+ frame_size = hdr_frame_bytes(hdr, dec->free_format_bytes) + hdr_padding(hdr);
+ readed = dec->io->read((uint8_t *)hdr + HDR_SIZE, frame_size - HDR_SIZE, dec->io->read_data);
+ if (readed != (size_t)(frame_size - HDR_SIZE))
+ return MP3D_E_IOERROR;
+ bs_init(bs, hdr + HDR_SIZE, frame_size - HDR_SIZE);
+ } else
+ {
+ hdr = dec->file.buffer + dec->index.frames[i - 1].offset;
+ frame_size = hdr_frame_bytes(hdr, dec->free_format_bytes) + hdr_padding(hdr);
+ bs_init(bs, hdr + HDR_SIZE, frame_size - HDR_SIZE);
+ }
+ if (HDR_IS_CRC(hdr))
+ get_bits(bs, 16);
+ i--;
+ if (L3_read_side_info(bs, gr_info, hdr) < 0)
+ break; /* frame not decodable, we can start from here */
+ frame_bytes = (bs->limit - bs->pos)/8;
+ to_fill_bytes -= MINIMP3_MIN(to_fill_bytes, frame_bytes);
+ }
+ }
+ }
+ dec->offset = dec->index.frames[i].offset;
+ dec->to_skip = position - dec->index.frames[i].sample;
+ while ((i + 1) < dec->index.num_frames && !dec->index.frames[i].sample && !dec->index.frames[i + 1].sample)
+ { /* skip not decodable first frames */
+ const uint8_t *hdr;
+ if (dec->io)
+ {
+ hdr = dec->file.buffer;
+ if (dec->io->seek(dec->index.frames[i].offset, dec->io->seek_data))
+ return MP3D_E_IOERROR;
+ size_t readed = dec->io->read((uint8_t *)hdr, HDR_SIZE, dec->io->read_data);
+ if (readed != HDR_SIZE)
+ return MP3D_E_IOERROR;
+ } else
+ hdr = dec->file.buffer + dec->index.frames[i].offset;
+ dec->to_skip += hdr_frame_samples(hdr)*dec->info.channels;
+ i++;
+ }
+do_exit:
+ if (dec->io)
+ {
+ if (dec->io->seek(dec->offset, dec->io->seek_data))
+ return MP3D_E_IOERROR;
+ }
+ dec->buffer_samples = 0;
+ dec->buffer_consumed = 0;
+ dec->input_consumed = 0;
+ dec->input_filled = 0;
+ dec->last_error = 0;
+ mp3dec_init(&dec->mp3d);
+ return 0;
+}
+
+size_t mp3dec_ex_read_frame(mp3dec_ex_t *dec, mp3d_sample_t **buf, mp3dec_frame_info_t *frame_info, size_t max_samples)
+{
+ if (!dec || !buf || !frame_info)
+ {
+ if (dec)
+ dec->last_error = MP3D_E_PARAM;
+ return 0;
+ }
+ if (dec->detected_samples && dec->cur_sample >= dec->detected_samples)
+ return 0; /* at end of stream */
+ if (dec->last_error)
+ return 0; /* error eof state, seek can reset it */
+ *buf = NULL;
+ uint64_t end_offset = dec->end_offset ? dec->end_offset : dec->file.size;
+ int eof = 0;
+ while (dec->buffer_consumed == dec->buffer_samples)
+ {
+ const uint8_t *dec_buf;
+ if (dec->io)
+ {
+ if (!eof && (dec->input_filled - dec->input_consumed) < MINIMP3_BUF_SIZE)
+ { /* keep minimum 10 consecutive mp3 frames (~16KB) worst case */
+ memmove((uint8_t*)dec->file.buffer, (uint8_t*)dec->file.buffer + dec->input_consumed, dec->input_filled - dec->input_consumed);
+ dec->input_filled -= dec->input_consumed;
+ dec->input_consumed = 0;
+ size_t readed = dec->io->read((uint8_t*)dec->file.buffer + dec->input_filled, dec->file.size - dec->input_filled, dec->io->read_data);
+ if (readed > (dec->file.size - dec->input_filled))
+ {
+ dec->last_error = MP3D_E_IOERROR;
+ readed = 0;
+ }
+ if (readed != (dec->file.size - dec->input_filled))
+ eof = 1;
+ dec->input_filled += readed;
+ if (eof)
+ mp3dec_skip_id3v1((uint8_t*)dec->file.buffer, &dec->input_filled);
+ }
+ dec_buf = dec->file.buffer + dec->input_consumed;
+ if (!(dec->input_filled - dec->input_consumed))
+ return 0;
+ dec->buffer_samples = mp3dec_decode_frame(&dec->mp3d, dec_buf, dec->input_filled - dec->input_consumed, dec->buffer, frame_info);
+ dec->input_consumed += frame_info->frame_bytes;
+ } else
+ {
+ dec_buf = dec->file.buffer + dec->offset;
+ uint64_t buf_size = end_offset - dec->offset;
+ if (!buf_size)
+ return 0;
+ dec->buffer_samples = mp3dec_decode_frame(&dec->mp3d, dec_buf, MINIMP3_MIN(buf_size, (uint64_t)INT_MAX), dec->buffer, frame_info);
+ }
+ dec->buffer_consumed = 0;
+ if (dec->info.hz != frame_info->hz || dec->info.layer != frame_info->layer)
+ {
+return_e_decode:
+ dec->last_error = MP3D_E_DECODE;
+ return 0;
+ }
+ if (dec->buffer_samples)
+ {
+ dec->buffer_samples *= frame_info->channels;
+ if (dec->to_skip)
+ {
+ size_t skip = MINIMP3_MIN(dec->buffer_samples, dec->to_skip);
+ dec->buffer_consumed += skip;
+ dec->to_skip -= skip;
+ }
+ if (
+#ifdef MINIMP3_ALLOW_MONO_STEREO_TRANSITION
+ !(dec->flags & MP3D_ALLOW_MONO_STEREO_TRANSITION) &&
+#endif
+ dec->buffer_consumed != dec->buffer_samples && dec->info.channels != frame_info->channels)
+ {
+ goto return_e_decode;
+ }
+ } else if (dec->to_skip)
+ { /* In mp3 decoding not always can start decode from any frame because of bit reservoir,
+ count skip samples for such frames */
+ int frame_samples = hdr_frame_samples(dec_buf)*frame_info->channels;
+ dec->to_skip -= MINIMP3_MIN(frame_samples, dec->to_skip);
+ }
+ dec->offset += frame_info->frame_bytes;
+ }
+ size_t out_samples = MINIMP3_MIN((size_t)(dec->buffer_samples - dec->buffer_consumed), max_samples);
+ if (dec->detected_samples)
+ { /* count decoded samples to properly cut padding */
+ if (dec->cur_sample + out_samples >= dec->detected_samples)
+ out_samples = dec->detected_samples - dec->cur_sample;
+ }
+ dec->cur_sample += out_samples;
+ *buf = dec->buffer + dec->buffer_consumed;
+ dec->buffer_consumed += out_samples;
+ return out_samples;
+}
+
+size_t mp3dec_ex_read(mp3dec_ex_t *dec, mp3d_sample_t *buf, size_t samples)
+{
+ if (!dec || !buf)
+ {
+ if (dec)
+ dec->last_error = MP3D_E_PARAM;
+ return 0;
+ }
+ mp3dec_frame_info_t frame_info;
+ memset(&frame_info, 0, sizeof(frame_info));
+ size_t samples_requested = samples;
+ while (samples)
+ {
+ mp3d_sample_t *buf_frame = NULL;
+ size_t read_samples = mp3dec_ex_read_frame(dec, &buf_frame, &frame_info, samples);
+ if (!read_samples)
+ {
+ break;
+ }
+ memcpy(buf, buf_frame, read_samples * sizeof(mp3d_sample_t));
+ buf += read_samples;
+ samples -= read_samples;
+ }
+ return samples_requested - samples;
+}
+
+int mp3dec_ex_open_cb(mp3dec_ex_t *dec, mp3dec_io_t *io, int flags)
+{
+ if (!dec || !io || (flags & (~MP3D_FLAGS_MASK)))
+ return MP3D_E_PARAM;
+ memset(dec, 0, sizeof(*dec));
+#ifdef MINIMP3_HAVE_RING
+ int ret;
+ if (ret = mp3dec_open_ring(&dec->file, MINIMP3_IO_SIZE))
+ return ret;
+#else
+ dec->file.size = MINIMP3_IO_SIZE;
+ dec->file.buffer = (const uint8_t*)malloc(dec->file.size);
+ if (!dec->file.buffer)
+ return MP3D_E_MEMORY;
+#endif
+ dec->flags = flags;
+ dec->io = io;
+ mp3dec_init(&dec->mp3d);
+ if (io->seek(0, io->seek_data))
+ return MP3D_E_IOERROR;
+ int ret = mp3dec_iterate_cb(io, (uint8_t *)dec->file.buffer, dec->file.size, mp3dec_load_index, dec);
+ if (ret && MP3D_E_USER != ret)
+ return ret;
+ if (dec->io->seek(dec->start_offset, dec->io->seek_data))
+ return MP3D_E_IOERROR;
+ mp3dec_init(&dec->mp3d);
+ dec->buffer_samples = 0;
+ dec->indexes_built = !(dec->vbr_tag_found || (flags & MP3D_DO_NOT_SCAN));
+ dec->flags &= (~MP3D_DO_NOT_SCAN);
+ return 0;
+}
+
+
+#ifndef MINIMP3_NO_STDIO
+
+#if defined(__linux__) || defined(__FreeBSD__)
+#include
+#include
+#include
+#include
+#include
+#include
+#if !defined(_GNU_SOURCE)
+#include
+#include
+#endif
+#if !defined(MAP_POPULATE) && defined(__linux__)
+#define MAP_POPULATE 0x08000
+#elif !defined(MAP_POPULATE)
+#define MAP_POPULATE 0
+#endif
+
+static void mp3dec_close_file(mp3dec_map_info_t *map_info)
+{
+ if (map_info->buffer && MAP_FAILED != map_info->buffer)
+ munmap((void *)map_info->buffer, map_info->size);
+ map_info->buffer = 0;
+ map_info->size = 0;
+}
+
+static int mp3dec_open_file(const char *file_name, mp3dec_map_info_t *map_info)
+{
+ if (!file_name)
+ return MP3D_E_PARAM;
+ int file;
+ struct stat st;
+ memset(map_info, 0, sizeof(*map_info));
+retry_open:
+ file = open(file_name, O_RDONLY);
+ if (file < 0 && (errno == EAGAIN || errno == EINTR))
+ goto retry_open;
+ if (file < 0 || fstat(file, &st) < 0)
+ {
+ close(file);
+ return MP3D_E_IOERROR;
+ }
+
+ map_info->size = st.st_size;
+retry_mmap:
+ map_info->buffer = (const uint8_t *)mmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE | MAP_POPULATE, file, 0);
+ if (MAP_FAILED == map_info->buffer && (errno == EAGAIN || errno == EINTR))
+ goto retry_mmap;
+ close(file);
+ if (MAP_FAILED == map_info->buffer)
+ return MP3D_E_IOERROR;
+ return 0;
+}
+
+#if MINIMP3_ENABLE_RING && defined(__linux__) && defined(_GNU_SOURCE)
+#define MINIMP3_HAVE_RING
+static void mp3dec_close_ring(mp3dec_map_info_t *map_info)
+{
+#if defined(__linux__) && defined(_GNU_SOURCE)
+ if (map_info->buffer && MAP_FAILED != map_info->buffer)
+ munmap((void *)map_info->buffer, map_info->size*2);
+#else
+ if (map_info->buffer)
+ {
+ shmdt(map_info->buffer);
+ shmdt(map_info->buffer + map_info->size);
+ }
+#endif
+ map_info->buffer = 0;
+ map_info->size = 0;
+}
+
+static int mp3dec_open_ring(mp3dec_map_info_t *map_info, size_t size)
+{
+ int memfd, page_size;
+#if defined(__linux__) && defined(_GNU_SOURCE)
+ void *buffer;
+ int res;
+#endif
+ memset(map_info, 0, sizeof(*map_info));
+
+#ifdef _SC_PAGESIZE
+ page_size = sysconf(_SC_PAGESIZE);
+#else
+ page_size = getpagesize();
+#endif
+ map_info->size = (size + page_size - 1)/page_size*page_size;
+
+#if defined(__linux__) && defined(_GNU_SOURCE)
+ memfd = memfd_create("mp3_ring", 0);
+ if (memfd < 0)
+ return MP3D_E_MEMORY;
+
+retry_ftruncate:
+ res = ftruncate(memfd, map_info->size);
+ if (res && (errno == EAGAIN || errno == EINTR))
+ goto retry_ftruncate;
+ if (res)
+ goto error;
+
+retry_mmap:
+ map_info->buffer = (const uint8_t *)mmap(NULL, map_info->size*2, PROT_NONE, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
+ if (MAP_FAILED == map_info->buffer && (errno == EAGAIN || errno == EINTR))
+ goto retry_mmap;
+ if (MAP_FAILED == map_info->buffer || !map_info->buffer)
+ goto error;
+retry_mmap2:
+ buffer = mmap((void *)map_info->buffer, map_info->size, PROT_READ | PROT_WRITE, MAP_FIXED | MAP_SHARED, memfd, 0);
+ if (MAP_FAILED == map_info->buffer && (errno == EAGAIN || errno == EINTR))
+ goto retry_mmap2;
+ if (MAP_FAILED == map_info->buffer || buffer != (void *)map_info->buffer)
+ goto error;
+retry_mmap3:
+ buffer = mmap((void *)map_info->buffer + map_info->size, map_info->size, PROT_READ | PROT_WRITE, MAP_FIXED | MAP_SHARED, memfd, 0);
+ if (MAP_FAILED == map_info->buffer && (errno == EAGAIN || errno == EINTR))
+ goto retry_mmap3;
+ if (MAP_FAILED == map_info->buffer || buffer != (void *)(map_info->buffer + map_info->size))
+ goto error;
+
+ close(memfd);
+ return 0;
+error:
+ close(memfd);
+ mp3dec_close_ring(map_info);
+ return MP3D_E_MEMORY;
+#else
+ memfd = shmget(IPC_PRIVATE, map_info->size, IPC_CREAT | 0700);
+ if (memfd < 0)
+ return MP3D_E_MEMORY;
+retry_mmap:
+ map_info->buffer = (const uint8_t *)mmap(NULL, map_info->size*2, PROT_NONE, MAP_PRIVATE, -1, 0);
+ if (MAP_FAILED == map_info->buffer && (errno == EAGAIN || errno == EINTR))
+ goto retry_mmap;
+ if (MAP_FAILED == map_info->buffer)
+ goto error;
+ if (map_info->buffer != shmat(memfd, map_info->buffer, 0))
+ goto error;
+ if ((map_info->buffer + map_info->size) != shmat(memfd, map_info->buffer + map_info->size, 0))
+ goto error;
+ if (shmctl(memfd, IPC_RMID, NULL) < 0)
+ return MP3D_E_MEMORY;
+ return 0;
+error:
+ shmctl(memfd, IPC_RMID, NULL);
+ mp3dec_close_ring(map_info);
+ return MP3D_E_MEMORY;
+#endif
+}
+#endif /*MINIMP3_ENABLE_RING*/
+#elif defined(_WIN32)
+#include
+
+static void mp3dec_close_file(mp3dec_map_info_t *map_info)
+{
+ if (map_info->buffer)
+ UnmapViewOfFile(map_info->buffer);
+ map_info->buffer = 0;
+ map_info->size = 0;
+}
+
+static int mp3dec_open_file_h(HANDLE file, mp3dec_map_info_t *map_info)
+{
+ memset(map_info, 0, sizeof(*map_info));
+
+ HANDLE mapping = NULL;
+ LARGE_INTEGER s;
+ s.LowPart = GetFileSize(file, (DWORD*)&s.HighPart);
+ if (s.LowPart == INVALID_FILE_SIZE && GetLastError() != NO_ERROR)
+ goto error;
+ map_info->size = s.QuadPart;
+
+ mapping = CreateFileMapping(file, NULL, PAGE_READONLY, 0, 0, NULL);
+ if (!mapping)
+ goto error;
+ map_info->buffer = (const uint8_t*)MapViewOfFile(mapping, FILE_MAP_READ, 0, 0, s.QuadPart);
+ CloseHandle(mapping);
+ if (!map_info->buffer)
+ goto error;
+
+ CloseHandle(file);
+ return 0;
+error:
+ mp3dec_close_file(map_info);
+ CloseHandle(file);
+ return MP3D_E_IOERROR;
+}
+
+static int mp3dec_open_file(const char *file_name, mp3dec_map_info_t *map_info)
+{
+ if (!file_name)
+ return MP3D_E_PARAM;
+ HANDLE file = CreateFileA(file_name, GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0);
+ if (INVALID_HANDLE_VALUE == file)
+ return MP3D_E_IOERROR;
+ return mp3dec_open_file_h(file, map_info);
+}
+
+static int mp3dec_open_file_w(const wchar_t *file_name, mp3dec_map_info_t *map_info)
+{
+ if (!file_name)
+ return MP3D_E_PARAM;
+ HANDLE file = CreateFileW(file_name, GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0);
+ if (INVALID_HANDLE_VALUE == file)
+ return MP3D_E_IOERROR;
+ return mp3dec_open_file_h(file, map_info);
+}
+#else
+#include
+
+static void mp3dec_close_file(mp3dec_map_info_t *map_info)
+{
+ if (map_info->buffer)
+ free((void *)map_info->buffer);
+ map_info->buffer = 0;
+ map_info->size = 0;
+}
+
+static int mp3dec_open_file(const char *file_name, mp3dec_map_info_t *map_info)
+{
+ if (!file_name)
+ return MP3D_E_PARAM;
+ memset(map_info, 0, sizeof(*map_info));
+ FILE *file = fopen(file_name, "rb");
+ if (!file)
+ return MP3D_E_IOERROR;
+ int res = MP3D_E_IOERROR;
+ long size = -1;
+ if (fseek(file, 0, SEEK_END))
+ goto error;
+ size = ftell(file);
+ if (size < 0)
+ goto error;
+ map_info->size = (size_t)size;
+ if (fseek(file, 0, SEEK_SET))
+ goto error;
+ map_info->buffer = (uint8_t *)malloc(map_info->size);
+ if (!map_info->buffer)
+ {
+ res = MP3D_E_MEMORY;
+ goto error;
+ }
+ if (fread((void *)map_info->buffer, 1, map_info->size, file) != map_info->size)
+ goto error;
+ fclose(file);
+ return 0;
+error:
+ mp3dec_close_file(map_info);
+ fclose(file);
+ return res;
+}
+#endif
+
+static int mp3dec_detect_mapinfo(mp3dec_map_info_t *map_info)
+{
+ int ret = mp3dec_detect_buf(map_info->buffer, map_info->size);
+ mp3dec_close_file(map_info);
+ return ret;
+}
+
+static int mp3dec_load_mapinfo(mp3dec_t *dec, mp3dec_map_info_t *map_info, mp3dec_file_info_t *info, MP3D_PROGRESS_CB progress_cb, void *user_data)
+{
+ int ret = mp3dec_load_buf(dec, map_info->buffer, map_info->size, info, progress_cb, user_data);
+ mp3dec_close_file(map_info);
+ return ret;
+}
+
+static int mp3dec_iterate_mapinfo(mp3dec_map_info_t *map_info, MP3D_ITERATE_CB callback, void *user_data)
+{
+ int ret = mp3dec_iterate_buf(map_info->buffer, map_info->size, callback, user_data);
+ mp3dec_close_file(map_info);
+ return ret;
+}
+
+static int mp3dec_ex_open_mapinfo(mp3dec_ex_t *dec, int flags)
+{
+ int ret = mp3dec_ex_open_buf(dec, dec->file.buffer, dec->file.size, flags);
+ dec->is_file = 1;
+ if (ret)
+ mp3dec_ex_close(dec);
+ return ret;
+}
+
+int mp3dec_detect(const char *file_name)
+{
+ int ret;
+ mp3dec_map_info_t map_info;
+ if ((ret = mp3dec_open_file(file_name, &map_info)))
+ return ret;
+ return mp3dec_detect_mapinfo(&map_info);
+}
+
+int mp3dec_load(mp3dec_t *dec, const char *file_name, mp3dec_file_info_t *info, MP3D_PROGRESS_CB progress_cb, void *user_data)
+{
+ int ret;
+ mp3dec_map_info_t map_info;
+ if ((ret = mp3dec_open_file(file_name, &map_info)))
+ return ret;
+ return mp3dec_load_mapinfo(dec, &map_info, info, progress_cb, user_data);
+}
+
+int mp3dec_iterate(const char *file_name, MP3D_ITERATE_CB callback, void *user_data)
+{
+ int ret;
+ mp3dec_map_info_t map_info;
+ if ((ret = mp3dec_open_file(file_name, &map_info)))
+ return ret;
+ return mp3dec_iterate_mapinfo(&map_info, callback, user_data);
+}
+
+int mp3dec_ex_open(mp3dec_ex_t *dec, const char *file_name, int flags)
+{
+ int ret;
+ if (!dec)
+ return MP3D_E_PARAM;
+ if ((ret = mp3dec_open_file(file_name, &dec->file)))
+ return ret;
+ return mp3dec_ex_open_mapinfo(dec, flags);
+}
+
+void mp3dec_ex_close(mp3dec_ex_t *dec)
+{
+#ifdef MINIMP3_HAVE_RING
+ if (dec->io)
+ mp3dec_close_ring(&dec->file);
+#else
+ if (dec->io && dec->file.buffer)
+ free((void*)dec->file.buffer);
+#endif
+ if (dec->is_file)
+ mp3dec_close_file(&dec->file);
+ if (dec->index.frames)
+ free(dec->index.frames);
+ memset(dec, 0, sizeof(*dec));
+}
+
+#ifdef _WIN32
+int mp3dec_detect_w(const wchar_t *file_name)
+{
+ int ret;
+ mp3dec_map_info_t map_info;
+ if ((ret = mp3dec_open_file_w(file_name, &map_info)))
+ return ret;
+ return mp3dec_detect_mapinfo(&map_info);
+}
+
+int mp3dec_load_w(mp3dec_t *dec, const wchar_t *file_name, mp3dec_file_info_t *info, MP3D_PROGRESS_CB progress_cb, void *user_data)
+{
+ int ret;
+ mp3dec_map_info_t map_info;
+ if ((ret = mp3dec_open_file_w(file_name, &map_info)))
+ return ret;
+ return mp3dec_load_mapinfo(dec, &map_info, info, progress_cb, user_data);
+}
+
+int mp3dec_iterate_w(const wchar_t *file_name, MP3D_ITERATE_CB callback, void *user_data)
+{
+ int ret;
+ mp3dec_map_info_t map_info;
+ if ((ret = mp3dec_open_file_w(file_name, &map_info)))
+ return ret;
+ return mp3dec_iterate_mapinfo(&map_info, callback, user_data);
+}
+
+int mp3dec_ex_open_w(mp3dec_ex_t *dec, const wchar_t *file_name, int flags)
+{
+ int ret;
+ if ((ret = mp3dec_open_file_w(file_name, &dec->file)))
+ return ret;
+ return mp3dec_ex_open_mapinfo(dec, flags);
+}
+#endif
+#else /* MINIMP3_NO_STDIO */
+void mp3dec_ex_close(mp3dec_ex_t *dec)
+{
+#ifdef MINIMP3_HAVE_RING
+ if (dec->io)
+ mp3dec_close_ring(&dec->file);
+#else
+ if (dec->io && dec->file.buffer)
+ free((void*)dec->file.buffer);
+#endif
+ if (dec->index.frames)
+ free(dec->index.frames);
+ memset(dec, 0, sizeof(*dec));
+}
+#endif
+
+#endif /* MINIMP3_IMPLEMENTATION && !_MINIMP3_EX_IMPLEMENTATION_GUARD */
diff --git a/src/codecs/music_cmd.c b/src/codecs/music_cmd.c
index 387514679..f663050e7 100644
--- a/src/codecs/music_cmd.c
+++ b/src/codecs/music_cmd.c
@@ -123,7 +123,7 @@ static int ParseCommandLine(char *cmdline, char **argv)
if (argv) {
argv[argc] = NULL;
}
- return(argc);
+ return argc;
}
static char **parse_args(char *command, char *last_arg)
@@ -138,7 +138,7 @@ static char **parse_args(char *command, char *last_arg)
}
argv = (char **)SDL_malloc((argc+1)*(sizeof *argv));
if (argv == NULL) {
- return(NULL);
+ return NULL;
}
argc = ParseCommandLine(command, argv);
@@ -149,7 +149,7 @@ static char **parse_args(char *command, char *last_arg)
argv[argc] = NULL;
/* We're ready! */
- return(argv);
+ return argv;
}
/* Start playback of a given music stream */
@@ -168,8 +168,7 @@ static int MusicCMD_Play(void *context, int play_count)
switch(music->pid) {
/* Failed fork() system call */
case -1:
- Mix_SetError("fork() failed");
- return -1;
+ return Mix_SetError("fork() failed");
/* Child process - executes here */
case 0: {
diff --git a/src/codecs/music_drflac.c b/src/codecs/music_drflac.c
index be253a1a8..f7e3fd7af 100644
--- a/src/codecs/music_drflac.c
+++ b/src/codecs/music_drflac.c
@@ -265,8 +265,7 @@ static int DRFLAC_GetSome(void *context, void *data, int bytes, SDL_bool *done)
if (music->loop_flag) {
if (!drflac_seek_to_pcm_frame(music->dec, music->loop_start)) {
- SDL_SetError("drflac_seek_to_pcm_frame() failed");
- return -1;
+ return Mix_SetError("drflac_seek_to_pcm_frame() failed");
} else {
int play_count = -1;
if (music->play_count > 0) {
diff --git a/src/codecs/music_drmp3.c b/src/codecs/music_drmp3.c
deleted file mode 100644
index 1b2830e9c..000000000
--- a/src/codecs/music_drmp3.c
+++ /dev/null
@@ -1,297 +0,0 @@
-/*
- SDL_mixer: An audio mixer library based on the SDL library
- Copyright (C) 1997-2024 Sam Lantinga
-
- This software is provided 'as-is', without any express or implied
- warranty. In no event will the authors be held liable for any damages
- arising from the use of this software.
-
- Permission is granted to anyone to use this software for any purpose,
- including commercial applications, and to alter it and redistribute it
- freely, subject to the following restrictions:
-
- 1. The origin of this software must not be misrepresented; you must not
- claim that you wrote the original software. If you use this software
- in a product, an acknowledgment in the product documentation would be
- appreciated but is not required.
- 2. Altered source versions must be plainly marked as such, and must not be
- misrepresented as being the original software.
- 3. This notice may not be removed or altered from any source distribution.
-*/
-
-#ifdef MUSIC_MP3_DRMP3
-
-#include "music_drmp3.h"
-#include "mp3utils.h"
-#include "SDL.h"
-
-#define DR_MP3_IMPLEMENTATION
-#if defined(__GNUC__) && (__GNUC__ >= 4) && \
- !(defined(_WIN32) || defined(__EMX__))
-#define DRMP3_API __attribute__((visibility("hidden")))
-#elif defined(__APPLE__)
-#define DRMP3_API __private_extern__
-#else
-#define DRMP3_API /* just in case.. */
-#endif
-#define DR_MP3_NO_STDIO
-#define DRMP3_ASSERT(expression)
-#define DRMP3_COPY_MEMORY(dst, src, sz) SDL_memcpy((dst), (src), (sz))
-#define DRMP3_MOVE_MEMORY(dst, src, sz) SDL_memmove((dst), (src), (sz))
-#define DRMP3_ZERO_MEMORY(p, sz) SDL_memset((p), 0, (sz))
-#define DRMP3_MALLOC(sz) SDL_malloc((sz))
-#define DRMP3_REALLOC(p, sz) SDL_realloc((p), (sz))
-#define DRMP3_FREE(p) SDL_free((p))
-#include "dr_libs/dr_mp3.h"
-
-
-typedef struct {
- struct mp3file_t file;
- drmp3 dec;
- int play_count;
- int freesrc;
- int volume;
- int status;
- SDL_AudioStream *stream;
- drmp3_int16 *buffer;
- int buffer_size;
- int channels;
-
- Mix_MusicMetaTags tags;
-} DRMP3_Music;
-
-
-static size_t DRMP3_ReadCB(void *context, void *buf, size_t size)
-{
- DRMP3_Music *music = (DRMP3_Music *)context;
- return MP3_RWread(&music->file, buf, 1, size);
-}
-
-static drmp3_bool32 DRMP3_SeekCB(void *context, int offset, drmp3_seek_origin origin)
-{
- DRMP3_Music *music = (DRMP3_Music *)context;
- int whence = (origin == drmp3_seek_origin_start) ? RW_SEEK_SET : RW_SEEK_CUR;
- if (MP3_RWseek(&music->file, offset, whence) < 0) {
- return DRMP3_FALSE;
- }
- return DRMP3_TRUE;
-}
-
-static int DRMP3_Seek(void *context, double position);
-
-static void *DRMP3_CreateFromRW(SDL_RWops *src, int freesrc)
-{
- DRMP3_Music *music;
-
- music = (DRMP3_Music *)SDL_calloc(1, sizeof(DRMP3_Music));
- if (!music) {
- SDL_OutOfMemory();
- return NULL;
- }
- music->volume = MIX_MAX_VOLUME;
-
- if (MP3_RWinit(&music->file, src) < 0) {
- SDL_free(music);
- return NULL;
- }
-
- meta_tags_init(&music->tags);
- if (mp3_read_tags(&music->tags, &music->file, SDL_FALSE) < 0) {
- SDL_free(music);
- Mix_SetError("music_drmp3: corrupt mp3 file (bad tags).");
- return NULL;
- }
-
- MP3_RWseek(&music->file, 0, RW_SEEK_SET);
-
- if (!drmp3_init(&music->dec, DRMP3_ReadCB, DRMP3_SeekCB, music, NULL)) {
- SDL_free(music);
- Mix_SetError("music_drmp3: corrupt mp3 file (bad stream).");
- return NULL;
- }
-
- music->channels = music->dec.channels;
- music->stream = SDL_NewAudioStream(AUDIO_S16SYS,
- (Uint8)music->channels,
- (int)music->dec.sampleRate,
- music_spec.format,
- music_spec.channels,
- music_spec.freq);
- if (!music->stream) {
- SDL_OutOfMemory();
- drmp3_uninit(&music->dec);
- SDL_free(music);
- return NULL;
- }
-
- music->buffer_size = music_spec.samples * sizeof(drmp3_int16) * music->channels;
- music->buffer = (drmp3_int16*)SDL_calloc(1, music->buffer_size);
- if (!music->buffer) {
- drmp3_uninit(&music->dec);
- SDL_OutOfMemory();
- SDL_free(music);
- return NULL;
- }
-
- music->freesrc = freesrc;
- return music;
-}
-
-static void DRMP3_SetVolume(void *context, int volume)
-{
- DRMP3_Music *music = (DRMP3_Music *)context;
- music->volume = volume;
-}
-
-static int DRMP3_GetVolume(void *context)
-{
- DRMP3_Music *music = (DRMP3_Music *)context;
- return music->volume;
-}
-
-/* Starts the playback. */
-static int DRMP3_Play(void *context, int play_count)
-{
- DRMP3_Music *music = (DRMP3_Music *)context;
- music->play_count = play_count;
- return DRMP3_Seek(music, 0.0);
-}
-
-static void DRMP3_Stop(void *context)
-{
- DRMP3_Music *music = (DRMP3_Music *)context;
- SDL_AudioStreamClear(music->stream);
-}
-
-static int DRMP3_GetSome(void *context, void *data, int bytes, SDL_bool *done)
-{
- DRMP3_Music *music = (DRMP3_Music *)context;
- int filled;
- drmp3_uint64 amount;
-
- if (music->stream) {
- filled = SDL_AudioStreamGet(music->stream, data, bytes);
- if (filled != 0) {
- return filled;
- }
- }
-
- if (!music->play_count) {
- /* All done */
- *done = SDL_TRUE;
- return 0;
- }
-
- amount = drmp3_read_pcm_frames_s16(&music->dec, music_spec.samples, music->buffer);
- if (amount > 0) {
- if (SDL_AudioStreamPut(music->stream, music->buffer, (int)amount * sizeof(drmp3_int16) * music->channels) < 0) {
- return -1;
- }
- } else {
- if (music->play_count == 1) {
- music->play_count = 0;
- SDL_AudioStreamFlush(music->stream);
- } else {
- int play_count = -1;
- if (music->play_count > 0) {
- play_count = (music->play_count - 1);
- }
- if (DRMP3_Play(music, play_count) < 0) {
- return -1;
- }
- }
- }
-
- return 0;
-}
-
-static int DRMP3_GetAudio(void *context, void *data, int bytes)
-{
- DRMP3_Music *music = (DRMP3_Music *)context;
- return music_pcm_getaudio(context, data, bytes, music->volume, DRMP3_GetSome);
-}
-
-static int DRMP3_Seek(void *context, double position)
-{
- DRMP3_Music *music = (DRMP3_Music *)context;
- drmp3_uint64 destpos = (drmp3_uint64)(position * music->dec.sampleRate);
- drmp3_seek_to_pcm_frame(&music->dec, destpos);
- return 0;
-}
-
-static double DRMP3_Tell(void *context)
-{
- DRMP3_Music *music = (DRMP3_Music *)context;
- return (double)music->dec.currentPCMFrame / music->dec.sampleRate;
-}
-
-static double DRMP3_Duration(void *context)
-{
- DRMP3_Music *music = (DRMP3_Music *)context;
- drmp3_uint64 samples = drmp3_get_pcm_frame_count(&music->dec);
- return (double)samples / music->dec.sampleRate;
-}
-
-static const char* DRMP3_GetMetaTag(void *context, Mix_MusicMetaTag tag_type)
-{
- DRMP3_Music *music = (DRMP3_Music *)context;
- return meta_tags_get(&music->tags, tag_type);
-}
-
-static void DRMP3_Delete(void *context)
-{
- DRMP3_Music *music = (DRMP3_Music *)context;
-
- drmp3_uninit(&music->dec);
- meta_tags_clear(&music->tags);
-
- if (music->stream) {
- SDL_FreeAudioStream(music->stream);
- }
- if (music->buffer) {
- SDL_free(music->buffer);
- }
- if (music->freesrc) {
- SDL_RWclose(music->file.src);
- }
- SDL_free(music);
-}
-
-Mix_MusicInterface Mix_MusicInterface_DRMP3 =
-{
- "DRMP3",
- MIX_MUSIC_DRMP3,
- MUS_MP3,
- SDL_FALSE,
- SDL_FALSE,
-
- NULL, /* Load */
- NULL, /* Open */
- DRMP3_CreateFromRW,
- NULL, /* CreateFromFile */
- DRMP3_SetVolume,
- DRMP3_GetVolume,
- DRMP3_Play,
- NULL, /* IsPlaying */
- DRMP3_GetAudio,
- NULL, /* Jump */
- DRMP3_Seek,
- DRMP3_Tell,
- DRMP3_Duration,
- NULL, /* LoopStart */
- NULL, /* LoopEnd */
- NULL, /* LoopLength */
- DRMP3_GetMetaTag,
- NULL, /* GetNumTracks */
- NULL, /* StartTrack */
- NULL, /* Pause */
- NULL, /* Resume */
- DRMP3_Stop,
- DRMP3_Delete,
- NULL, /* Close */
- NULL /* Unload */
-};
-
-#endif /* MUSIC_MP3_DRMP3 */
-
-/* vi: set ts=4 sw=4 expandtab: */
diff --git a/src/codecs/music_flac.c b/src/codecs/music_flac.c
index 5aedb0665..347611ef9 100644
--- a/src/codecs/music_flac.c
+++ b/src/codecs/music_flac.c
@@ -197,7 +197,7 @@ static FLAC__StreamDecoderReadStatus flac_read_music_cb(
/* make sure there is something to be reading */
if (*bytes > 0) {
- *bytes = SDL_RWread (data->src, buffer, sizeof (FLAC__byte), *bytes);
+ *bytes = SDL_RWread (data->src, buffer, sizeof(FLAC__byte), *bytes);
if (*bytes == 0) { /* error or no data was read (EOF) */
return FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM;
@@ -316,7 +316,7 @@ static FLAC__StreamDecoderWriteStatus flac_write_music_cb(
shift_amount = 8;
break;
default:
- SDL_SetError("FLAC decoder doesn't support %d bits_per_sample", music->bits_per_sample);
+ Mix_SetError("FLAC decoder doesn't support %d bits_per_sample", music->bits_per_sample);
return FLAC__STREAM_DECODER_WRITE_STATUS_ABORT;
}
@@ -329,7 +329,7 @@ static FLAC__StreamDecoderWriteStatus flac_write_music_cb(
data = SDL_stack_alloc(Sint16, (frame->header.blocksize * channels));
if (!data) {
- SDL_SetError("Couldn't allocate %d bytes stack memory", (int)(frame->header.blocksize * channels * sizeof(*data)));
+ Mix_SetError("Couldn't allocate %d bytes stack memory", (int)(frame->header.blocksize * channels * sizeof(*data)));
return FLAC__STREAM_DECODER_WRITE_STATUS_ABORT;
}
if (music->channels == 3) {
@@ -485,19 +485,19 @@ static void flac_error_music_cb(
/* print an SDL error based on the error status */
switch (status) {
case FLAC__STREAM_DECODER_ERROR_STATUS_LOST_SYNC:
- SDL_SetError("Error processing the FLAC file [LOST_SYNC].");
+ Mix_SetError("Error processing the FLAC file [LOST_SYNC].");
break;
case FLAC__STREAM_DECODER_ERROR_STATUS_BAD_HEADER:
- SDL_SetError("Error processing the FLAC file [BAD_HEADER].");
+ Mix_SetError("Error processing the FLAC file [BAD_HEADER].");
break;
case FLAC__STREAM_DECODER_ERROR_STATUS_FRAME_CRC_MISMATCH:
- SDL_SetError("Error processing the FLAC file [CRC_MISMATCH].");
+ Mix_SetError("Error processing the FLAC file [CRC_MISMATCH].");
break;
case FLAC__STREAM_DECODER_ERROR_STATUS_UNPARSEABLE_STREAM:
- SDL_SetError("Error processing the FLAC file [UNPARSEABLE].");
+ Mix_SetError("Error processing the FLAC file [UNPARSEABLE].");
break;
default:
- SDL_SetError("Error processing the FLAC file [UNKNOWN].");
+ Mix_SetError("Error processing the FLAC file [UNKNOWN].");
break;
}
}
@@ -512,7 +512,7 @@ static void *FLAC_CreateFromRW(SDL_RWops *src, int freesrc)
int is_ogg_flac;
Uint8 magic[4];
if (SDL_RWread(src, magic, 1, 4) != 4) {
- SDL_SetError("Couldn't read first 4 bytes of audio data");
+ Mix_SetError("Couldn't read first 4 bytes of audio data");
return NULL;
}
SDL_RWseek(src, -4, RW_SEEK_CUR);
@@ -556,13 +556,13 @@ static void *FLAC_CreateFromRW(SDL_RWops *src, int freesrc)
if (flac.FLAC__stream_decoder_process_until_end_of_metadata(music->flac_decoder)) {
was_error = 0;
} else {
- SDL_SetError("FLAC__stream_decoder_process_until_end_of_metadata() failed");
+ Mix_SetError("FLAC__stream_decoder_process_until_end_of_metadata() failed");
}
} else {
- SDL_SetError("FLAC__stream_decoder_init_stream() failed");
+ Mix_SetError("FLAC__stream_decoder_init_stream() failed");
}
} else {
- SDL_SetError("FLAC__stream_decoder_new() failed");
+ Mix_SetError("FLAC__stream_decoder_new() failed");
}
if (was_error) {
@@ -645,17 +645,15 @@ static int FLAC_GetSome(void *context, void *data, int bytes, SDL_bool *done)
}
if (!flac.FLAC__stream_decoder_process_single(music->flac_decoder)) {
- SDL_SetError("FLAC__stream_decoder_process_single() failed");
- return -1;
+ return Mix_SetError("FLAC__stream_decoder_process_single() failed");
}
if (music->loop_flag) {
music->pcm_pos = music->loop_start;
if (flac.FLAC__stream_decoder_seek_absolute(music->flac_decoder, (FLAC__uint64)music->loop_start) ==
FLAC__STREAM_DECODER_SEEK_ERROR) {
- SDL_SetError("FLAC__stream_decoder_seek_absolute() failed");
flac.FLAC__stream_decoder_flush(music->flac_decoder);
- return -1;
+ return Mix_SetError("FLAC__stream_decoder_seek_absolute() failed");
} else {
int play_count = -1;
if (music->play_count > 0) {
@@ -704,8 +702,7 @@ static int FLAC_Seek(void *context, double position)
flac.FLAC__stream_decoder_flush(music->flac_decoder);
}
- SDL_SetError("Seeking of FLAC stream failed: libFLAC seek failed.");
- return -1;
+ return Mix_SetError("Seeking of FLAC stream failed: libFLAC seek failed.");
}
return 0;
}
diff --git a/src/codecs/music_fluidsynth.c b/src/codecs/music_fluidsynth.c
index d397bd146..7960cbaf3 100644
--- a/src/codecs/music_fluidsynth.c
+++ b/src/codecs/music_fluidsynth.c
@@ -297,8 +297,7 @@ static int FLUIDSYNTH_GetSome(void *context, void *data, int bytes, SDL_bool *do
}
if (music->synth_write(music->synth, music_spec.samples, music->buffer, 0, 2, music->buffer, 1, 2) != FLUID_OK) {
- Mix_SetError("Error generating FluidSynth audio");
- return -1;
+ return Mix_SetError("Error generating FluidSynth audio");
}
if (SDL_AudioStreamPut(music->stream, music->buffer, music->buffer_size) < 0) {
return -1;
diff --git a/src/codecs/music_gme.c b/src/codecs/music_gme.c
index 0c8d514a1..1f06522e1 100644
--- a/src/codecs/music_gme.c
+++ b/src/codecs/music_gme.c
@@ -57,7 +57,7 @@ static gme_loader gme;
#else
#define FUNCTION_LOADER(FUNC, SIG) \
gme.FUNC = FUNC; \
- if (gme.FUNC == NULL) { Mix_SetError("Missing GME.framework"); return -1; }
+ if (gme.FUNC == NULL) { Mix_SetError("Missing gme.framework"); return -1; }
#endif
static int GME_Load(void)
@@ -161,8 +161,7 @@ static int initialize_from_track_info(GME_Music *music, int track)
err = gme.gme_track_info(music->game_emu, &musInfo, track);
if (err != 0) {
- Mix_SetError("GME: %s", err);
- return -1;
+ return Mix_SetError("GME: %s", err);
}
music->track_length = musInfo->length;
@@ -236,7 +235,7 @@ static void *GME_CreateFromRW(struct SDL_RWops *src, int freesrc)
SDL_RWseek(src, 0, RW_SEEK_SET);
mem = SDL_LoadFile_RW(src, &size, SDL_FALSE);
if (mem) {
- err = gme.gme_open_data(mem, size, &music->game_emu, music_spec.freq);
+ err = gme.gme_open_data(mem, (long)size, &music->game_emu, music_spec.freq);
SDL_free(mem);
if (err != 0) {
GME_Delete(music);
@@ -266,7 +265,7 @@ static void *GME_CreateFromRW(struct SDL_RWops *src, int freesrc)
music->volume = MIX_MAX_VOLUME;
meta_tags_init(&music->tags);
- if (initialize_from_track_info(music, 0) == -1) {
+ if (initialize_from_track_info(music, 0) < 0) {
GME_Delete(music);
return NULL;
}
@@ -310,13 +309,13 @@ static int GME_GetSome(void *context, void *data, int bytes, SDL_bool *done)
return 0;
}
- err = gme.gme_play(music->game_emu, (music->buffer_size / 2), (short*)music->buffer);
+ err = gme.gme_play(music->game_emu, (int)(music->buffer_size / 2), (short*)music->buffer);
if (err != NULL) {
Mix_SetError("GME: %s", err);
return 0;
}
- if (SDL_AudioStreamPut(music->stream, music->buffer, music->buffer_size) < 0) {
+ if (SDL_AudioStreamPut(music->stream, music->buffer, (int)music->buffer_size) < 0) {
return -1;
}
return 0;
@@ -396,17 +395,12 @@ static int GME_StartTrack(void *music_p, int track)
err = gme.gme_start_track(music->game_emu, track);
if (err != 0) {
- Mix_SetError("GME: %s", err);
- return -1;
+ return Mix_SetError("GME: %s", err);
}
GME_Play(music, music->play_count);
- if (initialize_from_track_info(music, track) == -1) {
- return -1;
- }
-
- return 0;
+ return initialize_from_track_info(music, track);
}
diff --git a/src/codecs/music_minimp3.c b/src/codecs/music_minimp3.c
new file mode 100644
index 000000000..8565996cb
--- /dev/null
+++ b/src/codecs/music_minimp3.c
@@ -0,0 +1,290 @@
+/*
+ SDL_mixer: An audio mixer library based on the SDL library
+ Copyright (C) 1997-2024 Sam Lantinga
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+
+#ifdef MUSIC_MP3_MINIMP3
+
+#include "music_minimp3.h"
+#include "mp3utils.h"
+
+#define MINIMP3_IMPLEMENTATION
+#define MINIMP3_NO_STDIO
+#include "minimp3/minimp3_ex.h"
+
+
+typedef struct {
+ struct mp3file_t file;
+ int play_count;
+ int freesrc;
+ mp3dec_ex_t dec;
+ mp3dec_io_t io;
+ int volume;
+ int status;
+ SDL_AudioStream *stream;
+ mp3d_sample_t *buffer;
+ int buffer_size;
+ uint64_t second_length;
+ int channels;
+
+ Mix_MusicMetaTags tags;
+} MiniMP3_Music;
+
+
+static size_t MiniMP3_ReadCB(void *buf, size_t size, void *context)
+{
+ MiniMP3_Music *music = (MiniMP3_Music *)context;
+ return MP3_RWread(&music->file, buf, 1, size);
+}
+
+static int MiniMP3_SeekCB(uint64_t position, void *context)
+{
+ MiniMP3_Music *music = (MiniMP3_Music *)context;
+ if (MP3_RWseek(&music->file, position, RW_SEEK_SET) < 0) {
+ return -1;
+ }
+ return 0;
+}
+
+static int MINIMP3_Seek(void *context, double position);
+
+static void *MINIMP3_CreateFromRW(SDL_RWops *src, int freesrc)
+{
+ MiniMP3_Music *music;
+
+ music = (MiniMP3_Music *)SDL_calloc(1, sizeof(MiniMP3_Music));
+ if (!music) {
+ SDL_OutOfMemory();
+ return NULL;
+ }
+ music->volume = MIX_MAX_VOLUME;
+
+ if (MP3_RWinit(&music->file, src) < 0) {
+ SDL_free(music);
+ return NULL;
+ }
+
+ meta_tags_init(&music->tags);
+ if (mp3_read_tags(&music->tags, &music->file, SDL_FALSE) < 0) {
+ SDL_free(music);
+ Mix_SetError("music_minimp3: corrupt mp3 file (bad tags).");
+ return NULL;
+ }
+
+ music->io.read = MiniMP3_ReadCB;
+ music->io.read_data = music;
+ music->io.seek = MiniMP3_SeekCB;
+ music->io.seek_data = music;
+
+ MP3_RWseek(&music->file, 0, RW_SEEK_SET);
+
+ if (mp3dec_ex_open_cb(&music->dec, &music->io, MP3D_SEEK_TO_SAMPLE) != 0) {
+ mp3dec_ex_close(&music->dec);
+ SDL_free(music);
+ Mix_SetError("music_minimp3: corrupt mp3 file (bad stream).");
+ return NULL;
+ }
+
+ music->stream = SDL_NewAudioStream(AUDIO_S16SYS,
+ (Uint8)music->dec.info.channels,
+ (int)music->dec.info.hz,
+ music_spec.format,
+ music_spec.channels,
+ music_spec.freq);
+ if (!music->stream) {
+ SDL_OutOfMemory();
+ mp3dec_ex_close(&music->dec);
+ SDL_free(music);
+ return NULL;
+ }
+
+ music->channels = music->dec.info.channels;
+ music->second_length = music->channels * music->dec.info.hz;
+ music->buffer_size = music_spec.samples * sizeof(mp3d_sample_t) * music->channels;
+ music->buffer = (mp3d_sample_t*)SDL_calloc(1, music->buffer_size);
+ if (!music->buffer) {
+ mp3dec_ex_close(&music->dec);
+ SDL_OutOfMemory();
+ SDL_free(music);
+ return NULL;
+ }
+
+ music->freesrc = freesrc;
+ return music;
+}
+
+static void MINIMP3_SetVolume(void *context, int volume)
+{
+ MiniMP3_Music *music = (MiniMP3_Music *)context;
+ music->volume = volume;
+}
+
+static int MINIMP3_GetVolume(void *context)
+{
+ MiniMP3_Music *music = (MiniMP3_Music *)context;
+ return music->volume;
+}
+
+/* Starts the playback. */
+static int MINIMP3_Play(void *context, int play_count)
+{
+ MiniMP3_Music *music = (MiniMP3_Music *)context;
+ music->play_count = play_count;
+ return MINIMP3_Seek(music, 0.0);
+}
+
+static void MINIMP3_Stop(void *context)
+{
+ MiniMP3_Music *music = (MiniMP3_Music *)context;
+ SDL_AudioStreamClear(music->stream);
+}
+
+static int MINIMP3_GetSome(void *context, void *data, int bytes, SDL_bool *done)
+{
+ MiniMP3_Music *music = (MiniMP3_Music *)context;
+ int filled, amount;
+
+ if (music->stream) {
+ filled = SDL_AudioStreamGet(music->stream, data, bytes);
+ if (filled != 0) {
+ return filled;
+ }
+ }
+
+ if (!music->play_count) {
+ /* All done */
+ *done = SDL_TRUE;
+ return 0;
+ }
+
+ amount = (int)mp3dec_ex_read(&music->dec, music->buffer, music_spec.samples * music->channels);
+ if (amount > 0) {
+ if (SDL_AudioStreamPut(music->stream, music->buffer, (int)amount * sizeof(mp3d_sample_t)) < 0) {
+ return -1;
+ }
+ } else {
+ if (music->play_count == 1) {
+ music->play_count = 0;
+ SDL_AudioStreamFlush(music->stream);
+ } else {
+ int play_count = -1;
+ if (music->play_count > 0) {
+ play_count = (music->play_count - 1);
+ }
+ if (MINIMP3_Play(music, play_count) < 0) {
+ return -1;
+ }
+ }
+ }
+
+ return 0;
+}
+
+static int MINIMP3_GetAudio(void *context, void *data, int bytes)
+{
+ MiniMP3_Music *music = (MiniMP3_Music *)context;
+ return music_pcm_getaudio(context, data, bytes, music->volume, MINIMP3_GetSome);
+}
+
+static int MINIMP3_Seek(void *context, double position)
+{
+ MiniMP3_Music *music = (MiniMP3_Music *)context;
+ uint64_t destpos = (uint64_t)(position * music->second_length);
+ if (destpos % music->channels != 0) {
+ destpos -= destpos % music->channels;
+ }
+ mp3dec_ex_seek(&music->dec, destpos);
+ return 0;
+}
+
+static double MINIMP3_Tell(void *context)
+{
+ MiniMP3_Music *music = (MiniMP3_Music *)context;
+ return (double)music->dec.cur_sample / music->second_length;
+}
+
+static double MINIMP3_Duration(void *context)
+{
+ MiniMP3_Music *music = (MiniMP3_Music *)context;
+ return (double)music->dec.samples / music->second_length;
+}
+
+static const char* MINIMP3_GetMetaTag(void *context, Mix_MusicMetaTag tag_type)
+{
+ MiniMP3_Music *music = (MiniMP3_Music *)context;
+ return meta_tags_get(&music->tags, tag_type);
+}
+
+static void MINIMP3_Delete(void *context)
+{
+ MiniMP3_Music *music = (MiniMP3_Music *)context;
+
+ mp3dec_ex_close(&music->dec);
+ meta_tags_clear(&music->tags);
+
+ if (music->stream) {
+ SDL_FreeAudioStream(music->stream);
+ }
+ if (music->buffer) {
+ SDL_free(music->buffer);
+ }
+ if (music->freesrc) {
+ SDL_RWclose(music->file.src);
+ }
+ SDL_free(music);
+}
+
+Mix_MusicInterface Mix_MusicInterface_MINIMP3 =
+{
+ "MINIMP3",
+ MIX_MUSIC_MINIMP3,
+ MUS_MP3,
+ SDL_FALSE,
+ SDL_FALSE,
+
+ NULL, /* Load */
+ NULL, /* Open */
+ MINIMP3_CreateFromRW,
+ NULL, /* CreateFromFile */
+ MINIMP3_SetVolume,
+ MINIMP3_GetVolume,
+ MINIMP3_Play,
+ NULL, /* IsPlaying */
+ MINIMP3_GetAudio,
+ NULL, /* Jump */
+ MINIMP3_Seek,
+ MINIMP3_Tell,
+ MINIMP3_Duration,
+ NULL, /* LoopStart */
+ NULL, /* LoopEnd */
+ NULL, /* LoopLength */
+ MINIMP3_GetMetaTag,
+ NULL, /* GetNumTracks */
+ NULL, /* StartTrack */
+ NULL, /* Pause */
+ NULL, /* Resume */
+ MINIMP3_Stop,
+ MINIMP3_Delete,
+ NULL, /* Close */
+ NULL /* Unload */
+};
+
+#endif /* MUSIC_MP3_MINIMP3 */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/src/codecs/music_drmp3.h b/src/codecs/music_minimp3.h
similarity index 90%
rename from src/codecs/music_drmp3.h
rename to src/codecs/music_minimp3.h
index 862e09884..5de5ae580 100644
--- a/src/codecs/music_drmp3.h
+++ b/src/codecs/music_minimp3.h
@@ -19,10 +19,10 @@
3. This notice may not be removed or altered from any source distribution.
*/
-/* This file supports playing MP3 files with dr_mp3 */
+/* This file supports playing MP3 files with MiniMP3 */
#include "music.h"
-extern Mix_MusicInterface Mix_MusicInterface_DRMP3;
+extern Mix_MusicInterface Mix_MusicInterface_MINIMP3;
/* vi: set ts=4 sw=4 expandtab: */
diff --git a/src/codecs/music_mpg123.c b/src/codecs/music_mpg123.c
index a1b483df9..e7fade713 100644
--- a/src/codecs/music_mpg123.c
+++ b/src/codecs/music_mpg123.c
@@ -221,8 +221,7 @@ static int MPG123_Open(const SDL_AudioSpec *spec)
{
(void)spec;
if (mpg123.mpg123_init() != MPG123_OK) {
- Mix_SetError("mpg123_init() failed");
- return -1;
+ return Mix_SetError("mpg123_init() failed");
}
return 0;
}
@@ -392,8 +391,7 @@ static int MPG123_GetSome(void *context, void *data, int bytes, SDL_bool *done)
case MPG123_NEW_FORMAT:
result = mpg123.mpg123_getformat(music->handle, &rate, &channels, &encoding);
if (result != MPG123_OK) {
- Mix_SetError("mpg123_getformat: %s", mpg_err(music->handle, result));
- return -1;
+ return Mix_SetError("mpg123_getformat: %s", mpg_err(music->handle, result));
}
#ifdef DEBUG_MPG123
printf("MPG123 format: %s, channels: %d, rate: %ld\n",
@@ -436,8 +434,7 @@ static int MPG123_GetSome(void *context, void *data, int bytes, SDL_bool *done)
}
break;
default:
- Mix_SetError("mpg123_read: %s", mpg_err(music->handle, result));
- return -1;
+ return Mix_SetError("mpg123_read: %s", mpg_err(music->handle, result));
}
return 0;
}
diff --git a/src/codecs/music_ogg.c b/src/codecs/music_ogg.c
index 78e003ad4..2e6d29fba 100644
--- a/src/codecs/music_ogg.c
+++ b/src/codecs/music_ogg.c
@@ -34,7 +34,7 @@
#elif defined(OGG_USE_TREMOR)
#include
#else
-#if defined(__MORPHOS__)
+#if defined(__MORPHOS__)
#if defined(USE_VORBISLIB)
#include
@@ -119,7 +119,7 @@ static int OGG_Load(void)
vorbis.ov_time_tell = *(void**)((long)(VorbisFileBase) - 142);
vorbis.ov_pcm_tell = *(void**)((long)(VorbisFileBase) - 148);
vorbis.ov_time_total = *(void**)((long)(VorbisFileBase) - 100);
-
+
#else
FUNCTION_LOADER(ov_clear, int (*)(OggVorbis_File *))
FUNCTION_LOADER(ov_info, vorbis_info *(*)(OggVorbis_File *,int))
@@ -234,8 +234,7 @@ static int OGG_UpdateSection(OGG_music *music)
vi = vorbis.ov_info(&music->vf, -1);
if (!vi) {
- Mix_SetError("ov_info returned NULL");
- return -1;
+ return Mix_SetError("ov_info returned NULL");
}
if (vi->channels == music->vi.channels && vi->rate == music->vi.rate) {
@@ -295,9 +294,9 @@ static void *OGG_CreateFromRW(SDL_RWops *src, int freesrc)
#if defined(__MORPHOS__) && defined(USE_VORBISLIB)
if (vorbis.ov_open_callbacks(src, &music->vf, NULL, 0, &callbacks) < 0) {
#else
- if (vorbis.ov_open_callbacks(src, &music->vf, NULL, 0, callbacks) < 0) {
+ if (vorbis.ov_open_callbacks(src, &music->vf, NULL, 0, callbacks) < 0) {
#endif
- SDL_SetError("Not an Ogg Vorbis audio stream");
+ Mix_SetError("Not an Ogg Vorbis audio stream");
SDL_free(music);
return NULL;
}
@@ -431,8 +430,7 @@ static int OGG_GetSome(void *context, void *data, int bytes, SDL_bool *done)
amount = (int)vorbis.ov_read(&music->vf, music->buffer, music->buffer_size, SDL_BYTEORDER == SDL_BIG_ENDIAN, 2, 1, §ion);
#endif
if (amount < 0) {
- set_ov_error("ov_read", amount);
- return -1;
+ return set_ov_error("ov_read", amount);
}
if (section != music->section) {
@@ -447,8 +445,7 @@ static int OGG_GetSome(void *context, void *data, int bytes, SDL_bool *done)
amount -= (int)((pcmPos - music->loop_end) * music->vi.channels) * (int)sizeof(Sint16);
result = vorbis.ov_pcm_seek(&music->vf, music->loop_start);
if (result < 0) {
- set_ov_error("ov_pcm_seek", result);
- return -1;
+ return set_ov_error("ov_pcm_seek", result);
} else {
int play_count = -1;
if (music->play_count > 0) {
@@ -522,7 +519,7 @@ static double OGG_Duration(void *context)
#endif
}
-static double OGG_LoopStart(void *music_p)
+static double OGG_LoopStart(void *music_p)
{
OGG_music *music = (OGG_music *)music_p;
if (music->loop > 0) {
@@ -531,7 +528,7 @@ static double OGG_LoopStart(void *music_p)
return -1.0;
}
-static double OGG_LoopEnd(void *music_p)
+static double OGG_LoopEnd(void *music_p)
{
OGG_music *music = (OGG_music *)music_p;
if (music->loop > 0) {
@@ -540,7 +537,7 @@ static double OGG_LoopEnd(void *music_p)
return -1.0;
}
-static double OGG_LoopLength(void *music_p)
+static double OGG_LoopLength(void *music_p)
{
OGG_music *music = (OGG_music *)music_p;
if (music->loop > 0) {
@@ -604,4 +601,3 @@ Mix_MusicInterface Mix_MusicInterface_OGG =
};
#endif /* MUSIC_OGG */
-
diff --git a/src/codecs/music_ogg_stb.c b/src/codecs/music_ogg_stb.c
index 5fef31ded..ac96517e0 100644
--- a/src/codecs/music_ogg_stb.c
+++ b/src/codecs/music_ogg_stb.c
@@ -343,8 +343,7 @@ static int OGG_GetSome(void *context, void *data, int bytes, SDL_bool *done)
amount -= (int)((pcmPos - music->loop_end) * music->vi.channels) * (int)sizeof(float);
result = stb_vorbis_seek(music->vf, (Uint32)music->loop_start);
if (!result) {
- set_ov_error("stb_vorbis_seek", stb_vorbis_get_error(music->vf));
- return -1;
+ return set_ov_error("stb_vorbis_seek", stb_vorbis_get_error(music->vf));
} else {
int play_count = -1;
if (music->play_count > 0) {
@@ -389,8 +388,7 @@ static int OGG_Seek(void *context, double time)
result = stb_vorbis_seek(music->vf, (unsigned int)(time * music->vi.sample_rate));
if (!result) {
- set_ov_error("stb_vorbis_seek", stb_vorbis_get_error(music->vf));
- return -1;
+ return set_ov_error("stb_vorbis_seek", stb_vorbis_get_error(music->vf));
}
return 0;
}
@@ -408,7 +406,7 @@ static double OGG_Duration(void *context)
return (double)music->full_length / music->vi.sample_rate;
}
-static double OGG_LoopStart(void *music_p)
+static double OGG_LoopStart(void *music_p)
{
OGG_music *music = (OGG_music *)music_p;
if (music->loop > 0) {
@@ -417,7 +415,7 @@ static double OGG_LoopStart(void *music_p)
return -1.0;
}
-static double OGG_LoopEnd(void *music_p)
+static double OGG_LoopEnd(void *music_p)
{
OGG_music *music = (OGG_music *)music_p;
if (music->loop > 0) {
@@ -426,7 +424,7 @@ static double OGG_LoopEnd(void *music_p)
return -1.0;
}
-static double OGG_LoopLength(void *music_p)
+static double OGG_LoopLength(void *music_p)
{
OGG_music *music = (OGG_music *)music_p;
if (music->loop > 0) {
diff --git a/src/codecs/music_opus.c b/src/codecs/music_opus.c
index ec583680f..8d53401dc 100644
--- a/src/codecs/music_opus.c
+++ b/src/codecs/music_opus.c
@@ -172,8 +172,7 @@ static int OPUS_UpdateSection(OPUS_music *music)
op_info = opus.op_head(music->of, -1);
if (!op_info) {
- Mix_SetError("op_head returned NULL");
- return -1;
+ return Mix_SetError("op_head returned NULL");
}
if (music->op_info && op_info->channel_count == music->op_info->channel_count) {
@@ -232,7 +231,7 @@ static void *OPUS_CreateFromRW(SDL_RWops *src, int freesrc)
music->of = opus.op_open_callbacks(src, &callbacks, NULL, 0, &err);
if (music->of == NULL) {
/* set_op_error("op_open_callbacks", err);*/
- SDL_SetError("Not an Opus audio stream");
+ Mix_SetError("Not an Opus audio stream");
SDL_free(music);
return NULL;
}
@@ -369,8 +368,7 @@ static int OPUS_GetSome(void *context, void *data, int bytes, SDL_bool *done)
section = music->section;
samples = opus.op_read(music->of, (opus_int16 *)music->buffer, music->buffer_size / (int)sizeof(opus_int16), §ion);
if (samples < 0) {
- set_op_error("op_read", samples);
- return -1;
+ return set_op_error("op_read", samples);
}
if (section != music->section) {
@@ -385,8 +383,7 @@ static int OPUS_GetSome(void *context, void *data, int bytes, SDL_bool *done)
samples -= (int)((pcmPos - music->loop_end) * music->op_info->channel_count) * (int)sizeof(Sint16);
result = opus.op_pcm_seek(music->of, music->loop_start);
if (result < 0) {
- set_op_error("ov_pcm_seek", result);
- return -1;
+ return set_op_error("ov_pcm_seek", result);
} else {
int play_count = -1;
if (music->play_count > 0) {
diff --git a/src/codecs/music_wavpack.c b/src/codecs/music_wavpack.c
index 04fb353a4..96ee6ce17 100644
--- a/src/codecs/music_wavpack.c
+++ b/src/codecs/music_wavpack.c
@@ -66,7 +66,6 @@ typedef struct {
uint32_t libversion;
uint32_t (*WavpackGetLibraryVersion)(void);
char *(*WavpackGetErrorMessage)(WavpackContext*);
- WavpackContext *(*WavpackOpenFileInput)(const char *infilename, char *error, int flags, int norm_offset);
WavpackContext *(*WavpackOpenFileInputEx)(WavpackStreamReader *reader, void *wv_id, void *wvc_id, char *error, int flags, int norm_offset);
WavpackContext *(*WavpackCloseFile)(WavpackContext*);
int (*WavpackGetMode)(WavpackContext*);
@@ -94,7 +93,7 @@ static wavpack_loader wvpk;
#else
#define FUNCTION_LOADER(FUNC, SIG) \
wvpk.FUNC = FUNC; \
- if (wvpk.FUNC == NULL) { Mix_SetError("Missing WavPack.framework"); return -1; }
+ if (wvpk.FUNC == NULL) { Mix_SetError("Missing wavpack.framework"); return -1; }
#endif
static int WAVPACK_Load(void)
@@ -112,7 +111,6 @@ static int WAVPACK_Load(void)
#endif
FUNCTION_LOADER(WavpackGetLibraryVersion, uint32_t (*)(void));
FUNCTION_LOADER(WavpackGetErrorMessage, char *(*)(WavpackContext*));
- FUNCTION_LOADER(WavpackOpenFileInput, WavpackContext *(*)(const char*, char*, int, int));
FUNCTION_LOADER(WavpackOpenFileInputEx, WavpackContext *(*)(WavpackStreamReader*, void*, void*, char*, int, int));
FUNCTION_LOADER(WavpackCloseFile, WavpackContext *(*)(WavpackContext*));
FUNCTION_LOADER(WavpackGetMode, int (*)(WavpackContext*));
@@ -586,7 +584,7 @@ static int WAVPACK_Seek(void *context, double time)
int64_t sample = (int64_t)(time * music->samplerate);
int success = (wvpk.WavpackSeekSample64 != NULL) ?
wvpk.WavpackSeekSample64(music->ctx, sample) :
- wvpk.WavpackSeekSample(music->ctx, sample);
+ wvpk.WavpackSeekSample(music->ctx, (uint32_t)sample);
if (!success) {
return Mix_SetError("%s", wvpk.WavpackGetErrorMessage(music->ctx));
}
diff --git a/src/codecs/music_xmp.c b/src/codecs/music_xmp.c
index dc7cce7a7..6799f5b65 100644
--- a/src/codecs/music_xmp.c
+++ b/src/codecs/music_xmp.c
@@ -133,6 +133,8 @@ static void XMP_Unload(void)
typedef struct
{
+ SDL_RWops *src;
+ Sint64 src_offset;
int volume;
int play_count;
struct xmp_module_info mi;
@@ -180,14 +182,26 @@ static void libxmp_set_error(int e)
Mix_SetError("XMP: %s", msg);
}
-static unsigned long xmp_fread(void *dst, unsigned long len, unsigned long nmemb, void *src) {
- return (unsigned long)SDL_RWread((SDL_RWops*)src, dst, len, nmemb);
+static unsigned long xmp_fread(void *dst, unsigned long len, unsigned long nmemb, void *src)
+{
+ XMP_Music *music = (XMP_Music *)src;
+ return (unsigned long)SDL_RWread(music->src, dst, len, nmemb);
}
-static int xmp_fseek(void *src, long offset, int whence) {
- return (SDL_RWseek((SDL_RWops*)src, offset, whence) < 0)? -1 : 0;
+
+static int xmp_fseek(void *src, long offset, int whence)
+{
+ XMP_Music *music = (XMP_Music *)src;
+ Sint64 offset64 = (Sint64)offset;
+ if (whence == RW_SEEK_SET) {
+ offset64 += music->src_offset;
+ }
+ return (SDL_RWseek(music->src, offset64, whence) < 0) ? -1 : 0;
}
-static long xmp_ftell(void *src) {
- return (long)SDL_RWtell((SDL_RWops*)src);
+
+static long xmp_ftell(void *src)
+{
+ XMP_Music *music = (XMP_Music *)src;
+ return (long)(SDL_RWtell(music->src) - music->src_offset);
}
/* Load a libxmp stream from an SDL_RWops object */
@@ -219,7 +233,9 @@ void *XMP_CreateFromRW(SDL_RWops *src, int freesrc)
}
if (libxmp.xmp_load_module_from_callbacks) {
- err = libxmp.xmp_load_module_from_callbacks(music->ctx, src, file_callbacks);
+ music->src = src;
+ music->src_offset = SDL_RWtell(src);
+ err = libxmp.xmp_load_module_from_callbacks(music->ctx, music, file_callbacks);
} else {
size_t size;
void *mem = SDL_LoadFile_RW(src, &size, SDL_FALSE);
diff --git a/src/codecs/native_midi/native_midi_common.c b/src/codecs/native_midi/native_midi_common.c
index 4e247269c..c7996d925 100644
--- a/src/codecs/native_midi/native_midi_common.c
+++ b/src/codecs/native_midi/native_midi_common.c
@@ -58,19 +58,18 @@ typedef struct
#endif
-
/* Get Variable Length Quantity */
static int GetVLQ(MIDITrack *track, int *currentPos)
{
int l = 0;
Uint8 c;
- while(1)
- {
+ while (1) {
c = track->data[*currentPos];
(*currentPos)++;
l += (c & 0x7f);
- if (!(c & 0x80))
+ if (!(c & 0x80)) {
return l;
+ }
l <<= 7;
}
}
@@ -82,15 +81,14 @@ static MIDIEvent *CreateEvent(Uint32 time, Uint8 event, Uint8 a, Uint8 b)
newEvent = SDL_calloc(1, sizeof(MIDIEvent));
- if (newEvent)
- {
+ if (newEvent) {
newEvent->time = time;
newEvent->status = event;
newEvent->data[0] = a;
newEvent->data[1] = b;
- }
- else
+ } else {
Mix_OutOfMemory();
+ }
return newEvent;
}
@@ -108,23 +106,20 @@ static MIDIEvent *MIDITracktoStream(MIDITrack *track)
MIDIEvent *head = CreateEvent(0,0,0,0); /* dummy event to make handling the list easier */
MIDIEvent *currentEvent = head;
- while (!end)
- {
- if (currentPos >= track->len)
+ while (!end) {
+ if (currentPos >= track->len) {
break; /* End of data stream reached */
+ }
atime += GetVLQ(track, ¤tPos);
event = track->data[currentPos++];
/* Handle SysEx seperatly */
- if (((event>>4) & 0x0F) == MIDI_STATUS_SYSEX)
- {
- if (event == 0xFF)
- {
+ if (((event>>4) & 0x0F) == MIDI_STATUS_SYSEX) {
+ if (event == 0xFF) {
type = track->data[currentPos];
currentPos++;
- switch(type)
- {
+ switch(type) {
case 0x2f: /* End of data marker */
end = 1;
case 0x51: /* Tempo change */
@@ -136,33 +131,28 @@ static MIDIEvent *MIDITracktoStream(MIDITrack *track)
*/
break;
}
- }
- else
+ } else {
type = 0;
+ }
len = GetVLQ(track, ¤tPos);
/* Create an event and attach the extra data, if any */
currentEvent->next = CreateEvent(atime, event, type, 0);
currentEvent = currentEvent->next;
- if (NULL == currentEvent)
- {
+ if (NULL == currentEvent) {
FreeMIDIEventList(head);
return NULL;
}
- if (len)
- {
+ if (len) {
currentEvent->extraLen = len;
currentEvent->extraData = SDL_malloc(len);
SDL_memcpy(currentEvent->extraData, &(track->data[currentPos]), len);
currentPos += len;
}
- }
- else
- {
+ } else {
a = event;
- if (a & 0x80) /* It's a status byte */
- {
+ if (a & 0x80) { /* It's a status byte */
/* Extract channel and status information */
lastchan = a & 0x0F;
laststatus = (a>>4) & 0x0F;
@@ -170,8 +160,7 @@ static MIDIEvent *MIDITracktoStream(MIDITrack *track)
/* Read the next byte which should always be a data byte */
a = track->data[currentPos++] & 0x7F;
}
- switch(laststatus)
- {
+ switch(laststatus) {
case MIDI_STATUS_NOTE_OFF:
case MIDI_STATUS_NOTE_ON: /* Note on */
case MIDI_STATUS_AFTERTOUCH: /* Key Pressure */
@@ -180,8 +169,7 @@ static MIDIEvent *MIDITracktoStream(MIDITrack *track)
b = track->data[currentPos++] & 0x7F;
currentEvent->next = CreateEvent(atime, (Uint8)((laststatus<<4)+lastchan), a, b);
currentEvent = currentEvent->next;
- if (NULL == currentEvent)
- {
+ if (NULL == currentEvent) {
FreeMIDIEventList(head);
return NULL;
}
@@ -192,8 +180,7 @@ static MIDIEvent *MIDITracktoStream(MIDITrack *track)
a &= 0x7f;
currentEvent->next = CreateEvent(atime, (Uint8)((laststatus<<4)+lastchan), a, 0);
currentEvent = currentEvent->next;
- if (NULL == currentEvent)
- {
+ if (NULL == currentEvent) {
FreeMIDIEventList(head);
return NULL;
}
@@ -222,47 +209,45 @@ static MIDIEvent *MIDItoStream(MIDIFile *mididata)
MIDIEvent *currentEvent = head;
int trackID;
- if (NULL == head)
+ if (NULL == head) {
return NULL;
+ }
track = (MIDIEvent**) SDL_calloc(1, sizeof(MIDIEvent*) * mididata->nTracks);
- if (NULL == track)
- {
+ if (NULL == track) {
SDL_free(head);
return NULL;
}
/* First, convert all tracks to MIDIEvent lists */
- for (trackID = 0; trackID < mididata->nTracks; trackID++)
+ for (trackID = 0; trackID < mididata->nTracks; trackID++) {
track[trackID] = MIDITracktoStream(&mididata->track[trackID]);
+ }
/* Now, merge the lists. */
/* TODO */
- while(1)
- {
+ while (1) {
Uint32 lowestTime = 0x7FFFFFFF; /* INT_MAX */
int currentTrackID = -1;
/* Find the next event */
- for (trackID = 0; trackID < mididata->nTracks; trackID++)
- {
- if (track[trackID] && (track[trackID]->time < lowestTime))
- {
+ for (trackID = 0; trackID < mididata->nTracks; trackID++) {
+ if (track[trackID] && (track[trackID]->time < lowestTime)) {
currentTrackID = trackID;
lowestTime = track[currentTrackID]->time;
}
}
/* Check if we processes all events */
- if (currentTrackID == -1)
+ if (currentTrackID == -1) {
break;
+ }
currentEvent->next = track[currentTrackID];
track[currentTrackID] = track[currentTrackID]->next;
currentEvent = currentEvent->next;
-
lowestTime = 0;
}
@@ -278,16 +263,18 @@ static MIDIEvent *MIDItoStream(MIDIFile *mididata)
static int ReadMIDIFile(MIDIFile *mididata, SDL_RWops *src)
{
int i = 0;
- Uint32 ID;
- Uint32 size;
- Uint16 format;
- Uint16 tracks;
- Uint16 division;
+ Uint32 ID;
+ Uint32 size;
+ Uint16 format;
+ Uint16 tracks;
+ Uint16 division;
- if (!mididata)
+ if (!mididata) {
return 0;
- if (!src)
+ }
+ if (!src) {
return 0;
+ }
/* Make sure this is really a MIDI file */
SDL_RWread(src, &ID, 1, 4);
@@ -295,20 +282,23 @@ static int ReadMIDIFile(MIDIFile *mididata, SDL_RWops *src)
SDL_RWseek(src, 16, RW_SEEK_CUR);
SDL_RWread(src, &ID, 1, 4);
}
- if (BE_LONG(ID) != MIDI_MAGIC)
+ if (BE_LONG(ID) != MIDI_MAGIC) {
return 0;
+ }
/* Header size must be 6 */
SDL_RWread(src, &size, 1, 4);
size = BE_LONG(size);
- if (size != 6)
+ if (size != 6) {
return 0;
+ }
/* We only support format 0 and 1, but not 2 */
SDL_RWread(src, &format, 1, 2);
format = BE_SHORT(format);
- if (format != 0 && format != 1)
+ if (format != 0 && format != 1) {
return 0;
+ }
SDL_RWread(src, &tracks, 1, 2);
tracks = BE_SHORT(tracks);
@@ -316,8 +306,7 @@ static int ReadMIDIFile(MIDIFile *mididata, SDL_RWops *src)
/* Allocate tracks */
mididata->track = (MIDITrack*) SDL_calloc(1, sizeof(MIDITrack) * mididata->nTracks);
- if (NULL == mididata->track)
- {
+ if (NULL == mididata->track) {
Mix_OutOfMemory();
goto bail;
}
@@ -327,15 +316,13 @@ static int ReadMIDIFile(MIDIFile *mididata, SDL_RWops *src)
mididata->division = BE_SHORT(division);
- for (i=0; itrack[i].len = size;
mididata->track[i].data = SDL_malloc(size);
- if (NULL == mididata->track[i].data)
- {
+ if (NULL == mididata->track[i].data) {
Mix_OutOfMemory();
goto bail;
}
@@ -344,10 +331,10 @@ static int ReadMIDIFile(MIDIFile *mididata, SDL_RWops *src)
return 1;
bail:
- for(;i >= 0; i--)
- {
- if (mididata->track[i].data)
+ for (; i >= 0; i--) {
+ if (mididata->track[i].data) {
SDL_free(mididata->track[i].data);
+ }
}
SDL_free(mididata->track);
@@ -361,38 +348,35 @@ MIDIEvent *CreateMIDIEventList(SDL_RWops *src, Uint16 *division)
int trackID;
mididata = SDL_calloc(1, sizeof(MIDIFile));
- if (!mididata)
+ if (!mididata) {
return NULL;
+ }
/* Open the file */
- if ( src != NULL )
- {
+ if (src != NULL) {
/* Read in the data */
- if ( ! ReadMIDIFile(mididata, src))
- {
+ if (!ReadMIDIFile(mididata, src)) {
SDL_free(mididata);
return NULL;
}
- }
- else
- {
+ } else {
SDL_free(mididata);
return NULL;
}
- if (division)
+ if (division) {
*division = mididata->division;
+ }
eventList = MIDItoStream(mididata);
- if (eventList == NULL)
- {
+ if (eventList == NULL) {
SDL_free(mididata);
return NULL;
}
- for(trackID = 0; trackID < mididata->nTracks; trackID++)
- {
- if (mididata->track[trackID].data)
+ for (trackID = 0; trackID < mididata->nTracks; trackID++) {
+ if (mididata->track[trackID].data) {
SDL_free(mididata->track[trackID].data);
+ }
}
SDL_free(mididata->track);
SDL_free(mididata);
@@ -406,12 +390,12 @@ void FreeMIDIEventList(MIDIEvent *head)
cur = head;
- while (cur)
- {
+ while (cur) {
next = cur->next;
- if (cur->extraData)
- SDL_free (cur->extraData);
- SDL_free (cur);
+ if (cur->extraData) {
+ SDL_free(cur->extraData);
+ }
+ SDL_free(cur);
cur = next;
}
}
diff --git a/src/codecs/native_midi/native_midi_macosx.c b/src/codecs/native_midi/native_midi_macosx.c
index 5ef96ad0c..916ea21d9 100644
--- a/src/codecs/native_midi/native_midi_macosx.c
+++ b/src/codecs/native_midi/native_midi_macosx.c
@@ -21,7 +21,7 @@
#include "SDL_config.h"
-#if __MACOSX__
+#ifdef __MACOSX__
/* Mac OS X 10.6+, using Core MIDI. */
diff --git a/src/codecs/native_midi/native_midi_win32.c b/src/codecs/native_midi/native_midi_win32.c
index 1b0c2f789..522bd91e1 100644
--- a/src/codecs/native_midi/native_midi_win32.c
+++ b/src/codecs/native_midi/native_midi_win32.c
@@ -22,7 +22,7 @@
/* everything below is currently one very big bad hack ;) Proff */
-#if __WIN32__
+#ifdef __WIN32__
#define WIN32_LEAN_AND_MEAN
#include
diff --git a/src/codecs/timidity/common.c b/src/codecs/timidity/common.c
index 1096a38a0..8786c19e3 100644
--- a/src/codecs/timidity/common.c
+++ b/src/codecs/timidity/common.c
@@ -13,7 +13,7 @@
#include "options.h"
#include "common.h"
-#if defined(__WIN32__) || defined(__OS2__)
+#if defined(_WIN32) || defined(__OS2__)
#define CHAR_DIRSEP '\\'
#define is_dirsep(c) ((c) == '/' || (c) == '\\')
#define is_abspath(p) ((p)[0] == '/' || (p)[0] == '\\' || ((p)[0] && (p)[1] == ':'))
diff --git a/src/effect_position.c b/src/effect_position.c
index 4c4242a6e..1187a2ca0 100644
--- a/src/effect_position.c
+++ b/src/effect_position.c
@@ -131,7 +131,7 @@ static void SDLCALL _Eff_position_u8(int chan, void *stream, int len, void *udat
}
if (((position_args *)udata)->room_angle == 180) {
- for (i = 0; i < len; i += sizeof (Uint8) * 2) {
+ for (i = 0; i < len; i += sizeof(Uint8) * 2) {
/* must adjust the sample so that 0 is the center */
*ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128))
* right_f) * dist_f) + 128);
@@ -142,7 +142,7 @@ static void SDLCALL _Eff_position_u8(int chan, void *stream, int len, void *udat
}
}
else {
- for (i = 0; i < len; i += sizeof (Uint8) * 2) {
+ for (i = 0; i < len; i += sizeof(Uint8) * 2) {
/* must adjust the sample so that 0 is the center */
*ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128))
* left_f) * dist_f) + 128);
@@ -174,7 +174,7 @@ static void SDLCALL _Eff_position_u8_c4(int chan, void *stream, int len, void *u
}
if (args->room_angle == 0) {
- for (i = 0; i < len; i += sizeof (Uint8) * 4) {
+ for (i = 0; i < len; i += sizeof(Uint8) * 4) {
/* must adjust the sample so that 0 is the center */
*ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128))
* args->left_f) * args->distance_f) + 128);
@@ -191,7 +191,7 @@ static void SDLCALL _Eff_position_u8_c4(int chan, void *stream, int len, void *u
}
}
else if (args->room_angle == 90) {
- for (i = 0; i < len; i += sizeof (Uint8) * 4) {
+ for (i = 0; i < len; i += sizeof(Uint8) * 4) {
/* must adjust the sample so that 0 is the center */
*ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128))
* args->right_f) * args->distance_f) + 128);
@@ -208,7 +208,7 @@ static void SDLCALL _Eff_position_u8_c4(int chan, void *stream, int len, void *u
}
}
else if (args->room_angle == 180) {
- for (i = 0; i < len; i += sizeof (Uint8) * 4) {
+ for (i = 0; i < len; i += sizeof(Uint8) * 4) {
/* must adjust the sample so that 0 is the center */
*ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128))
* args->right_rear_f) * args->distance_f) + 128);
@@ -225,7 +225,7 @@ static void SDLCALL _Eff_position_u8_c4(int chan, void *stream, int len, void *u
}
}
else if (args->room_angle == 270) {
- for (i = 0; i < len; i += sizeof (Uint8) * 4) {
+ for (i = 0; i < len; i += sizeof(Uint8) * 4) {
/* must adjust the sample so that 0 is the center */
*ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128))
* args->left_rear_f) * args->distance_f) + 128);
@@ -264,7 +264,7 @@ static void SDLCALL _Eff_position_u8_c6(int chan, void *stream, int len, void *u
}
if (args->room_angle == 0) {
- for (i = 0; i < len; i += sizeof (Uint8) * 6) {
+ for (i = 0; i < len; i += sizeof(Uint8) * 6) {
/* must adjust the sample so that 0 is the center */
*ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128))
* args->left_f) * args->distance_f) + 128);
@@ -287,7 +287,7 @@ static void SDLCALL _Eff_position_u8_c6(int chan, void *stream, int len, void *u
}
}
else if (args->room_angle == 90) {
- for (i = 0; i < len; i += sizeof (Uint8) * 6) {
+ for (i = 0; i < len; i += sizeof(Uint8) * 6) {
/* must adjust the sample so that 0 is the center */
*ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128))
* args->right_f) * args->distance_f) + 128);
@@ -312,7 +312,7 @@ static void SDLCALL _Eff_position_u8_c6(int chan, void *stream, int len, void *u
}
}
else if (args->room_angle == 180) {
- for (i = 0; i < len; i += sizeof (Uint8) * 6) {
+ for (i = 0; i < len; i += sizeof(Uint8) * 6) {
/* must adjust the sample so that 0 is the center */
*ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128))
* args->right_rear_f) * args->distance_f) + 128);
@@ -337,7 +337,7 @@ static void SDLCALL _Eff_position_u8_c6(int chan, void *stream, int len, void *u
}
}
else if (args->room_angle == 270) {
- for (i = 0; i < len; i += sizeof (Uint8) * 6) {
+ for (i = 0; i < len; i += sizeof(Uint8) * 6) {
/* must adjust the sample so that 0 is the center */
*ptr = (Uint8) ((Sint8) ((((float) (Sint8) (*ptr - 128))
* args->left_rear_f) * args->distance_f) + 128);
@@ -406,7 +406,7 @@ static void SDLCALL _Eff_position_table_u8(int chan, void *stream, int len, void
p = (Uint32 *) ptr;
- for (i = 0; i < len; i += sizeof (Uint32)) {
+ for (i = 0; i < len; i += sizeof(Uint32)) {
#if (SDL_BYTEORDER == SDL_BIG_ENDIAN)
*p = (d[l[(*p & 0xFF000000) >> 24]] << 24) |
(d[r[(*p & 0x00FF0000) >> 16]] << 16) |
@@ -445,7 +445,7 @@ static void SDLCALL _Eff_position_s8(int chan, void *stream, int len, void *udat
}
if (((position_args *)udata)->room_angle == 180) {
- for (i = 0; i < len; i += sizeof (Sint8) * 2) {
+ for (i = 0; i < len; i += sizeof(Sint8) * 2) {
*ptr = (Sint8)((((float) *ptr) * right_f) * dist_f);
ptr++;
*ptr = (Sint8)((((float) *ptr) * left_f) * dist_f);
@@ -453,7 +453,7 @@ static void SDLCALL _Eff_position_s8(int chan, void *stream, int len, void *udat
}
}
else {
- for (i = 0; i < len; i += sizeof (Sint8) * 2) {
+ for (i = 0; i < len; i += sizeof(Sint8) * 2) {
*ptr = (Sint8)((((float) *ptr) * left_f) * dist_f);
ptr++;
*ptr = (Sint8)((((float) *ptr) * right_f) * dist_f);
@@ -480,7 +480,7 @@ static void SDLCALL _Eff_position_s8_c4(int chan, void *stream, int len, void *u
len--;
}
- for (i = 0; i < len; i += sizeof (Sint8) * 4) {
+ for (i = 0; i < len; i += sizeof(Sint8) * 4) {
switch (args->room_angle) {
case 0:
*ptr = (Sint8)((((float) *ptr) * args->left_f) * args->distance_f); ptr++;
@@ -529,7 +529,7 @@ static void SDLCALL _Eff_position_s8_c6(int chan, void *stream, int len, void *u
len--;
}
- for (i = 0; i < len; i += sizeof (Sint8) * 6) {
+ for (i = 0; i < len; i += sizeof(Sint8) * 6) {
switch (args->room_angle) {
case 0:
*ptr = (Sint8)((((float) *ptr) * args->left_f) * args->distance_f); ptr++;
@@ -608,7 +608,7 @@ static void SDLCALL _Eff_position_table_s8(int chan, void *stream, int len, void
p = (Uint32 *) ptr;
- for (i = 0; i < len; i += sizeof (Uint32)) {
+ for (i = 0; i < len; i += sizeof(Uint32)) {
#if (SDL_BYTEORDER == SDL_BIG_ENDIAN)
*p = (d[l[((Sint16)(Sint8)((*p & 0xFF000000) >> 24))+128]] << 24) |
(d[r[((Sint16)(Sint8)((*p & 0x00FF0000) >> 16))+128]] << 16) |
@@ -638,7 +638,7 @@ static void SDLCALL _Eff_position_u16lsb(int chan, void *stream, int len, void *
(void)chan;
- for (i = 0; i < len; i += sizeof (Uint16) * 2) {
+ for (i = 0; i < len; i += sizeof(Uint16) * 2) {
Sint16 sampl = (Sint16) (SDL_SwapLE16(*(ptr+0)) - 32768);
Sint16 sampr = (Sint16) (SDL_SwapLE16(*(ptr+1)) - 32768);
@@ -666,7 +666,7 @@ static void SDLCALL _Eff_position_u16lsb_c4(int chan, void *stream, int len, voi
(void)chan;
- for (i = 0; i < len; i += sizeof (Uint16) * 4) {
+ for (i = 0; i < len; i += sizeof(Uint16) * 4) {
Sint16 sampl = (Sint16) (SDL_SwapLE16(*(ptr+0)) - 32768);
Sint16 sampr = (Sint16) (SDL_SwapLE16(*(ptr+1)) - 32768);
Sint16 samplr = (Sint16) (SDL_SwapLE16(*(ptr+2)) - 32768);
@@ -718,7 +718,7 @@ static void SDLCALL _Eff_position_u16lsb_c6(int chan, void *stream, int len, voi
(void)chan;
- for (i = 0; i < len; i += sizeof (Uint16) * 6) {
+ for (i = 0; i < len; i += sizeof(Uint16) * 6) {
Sint16 sampl = (Sint16) (SDL_SwapLE16(*(ptr+0)) - 32768);
Sint16 sampr = (Sint16) (SDL_SwapLE16(*(ptr+1)) - 32768);
Sint16 samplr = (Sint16) (SDL_SwapLE16(*(ptr+2)) - 32768);
@@ -795,7 +795,7 @@ static void SDLCALL _Eff_position_s16lsb(int chan, void *stream, int len, void *
}
#endif
- for (i = 0; i < len; i += sizeof (Sint16) * 2) {
+ for (i = 0; i < len; i += sizeof(Sint16) * 2) {
Sint16 swapl = (Sint16) ((((float) (Sint16) SDL_SwapLE16(*(ptr+0))) *
left_f) * dist_f);
Sint16 swapr = (Sint16) ((((float) (Sint16) SDL_SwapLE16(*(ptr+1))) *
@@ -819,7 +819,7 @@ static void SDLCALL _Eff_position_s16lsb_c4(int chan, void *stream, int len, voi
(void)chan;
- for (i = 0; i < len; i += sizeof (Sint16) * 4) {
+ for (i = 0; i < len; i += sizeof(Sint16) * 4) {
Sint16 swapl = (Sint16) ((((float) (Sint16) SDL_SwapLE16(*(ptr+0))) *
args->left_f) * args->distance_f);
Sint16 swapr = (Sint16) ((((float) (Sint16) SDL_SwapLE16(*(ptr+1))) *
@@ -866,7 +866,7 @@ static void SDLCALL _Eff_position_s16lsb_c6(int chan, void *stream, int len, voi
(void)chan;
- for (i = 0; i < len; i += sizeof (Sint16) * 6) {
+ for (i = 0; i < len; i += sizeof(Sint16) * 6) {
Sint16 swapl = (Sint16) ((((float) (Sint16) SDL_SwapLE16(*(ptr+0))) *
args->left_f) * args->distance_f);
Sint16 swapr = (Sint16) ((((float) (Sint16) SDL_SwapLE16(*(ptr+1))) *
@@ -928,7 +928,7 @@ static void SDLCALL _Eff_position_u16msb(int chan, void *stream, int len, void *
(void)chan;
- for (i = 0; i < len; i += sizeof (Sint16) * 2) {
+ for (i = 0; i < len; i += sizeof(Sint16) * 2) {
Sint16 sampl = (Sint16) (SDL_SwapBE16(*(ptr+0)) - 32768);
Sint16 sampr = (Sint16) (SDL_SwapBE16(*(ptr+1)) - 32768);
@@ -957,7 +957,7 @@ static void SDLCALL _Eff_position_u16msb_c4(int chan, void *stream, int len, voi
(void)chan;
- for (i = 0; i < len; i += sizeof (Sint16) * 4) {
+ for (i = 0; i < len; i += sizeof(Sint16) * 4) {
Sint16 sampl = (Sint16) (SDL_SwapBE16(*(ptr+0)) - 32768);
Sint16 sampr = (Sint16) (SDL_SwapBE16(*(ptr+1)) - 32768);
Sint16 samplr = (Sint16) (SDL_SwapBE16(*(ptr+2)) - 32768);
@@ -1010,7 +1010,7 @@ static void SDLCALL _Eff_position_u16msb_c6(int chan, void *stream, int len, voi
(void)chan;
- for (i = 0; i < len; i += sizeof (Sint16) * 6) {
+ for (i = 0; i < len; i += sizeof(Sint16) * 6) {
Sint16 sampl = (Sint16) (SDL_SwapBE16(*(ptr+0)) - 32768);
Sint16 sampr = (Sint16) (SDL_SwapBE16(*(ptr+1)) - 32768);
Sint16 samplr = (Sint16) (SDL_SwapBE16(*(ptr+2)) - 32768);
@@ -1079,7 +1079,7 @@ static void SDLCALL _Eff_position_s16msb(int chan, void *stream, int len, void *
(void)chan;
- for (i = 0; i < len; i += sizeof (Sint16) * 2) {
+ for (i = 0; i < len; i += sizeof(Sint16) * 2) {
Sint16 swapl = (Sint16) ((((float) (Sint16) SDL_SwapBE16(*(ptr+0))) *
left_f) * dist_f);
Sint16 swapr = (Sint16) ((((float) (Sint16) SDL_SwapBE16(*(ptr+1))) *
@@ -1098,7 +1098,7 @@ static void SDLCALL _Eff_position_s16msb_c4(int chan, void *stream, int len, voi
(void)chan;
- for (i = 0; i < len; i += sizeof (Sint16) * 4) {
+ for (i = 0; i < len; i += sizeof(Sint16) * 4) {
Sint16 swapl = (Sint16) ((((float) (Sint16) SDL_SwapBE16(*(ptr+0))) *
args->left_f) * args->distance_f);
Sint16 swapr = (Sint16) ((((float) (Sint16) SDL_SwapBE16(*(ptr+1))) *
@@ -1145,7 +1145,7 @@ static void SDLCALL _Eff_position_s16msb_c6(int chan, void *stream, int len, voi
(void)chan;
- for (i = 0; i < len; i += sizeof (Sint16) * 6) {
+ for (i = 0; i < len; i += sizeof(Sint16) * 6) {
Sint16 swapl = (Sint16) ((((float) (Sint16) SDL_SwapBE16(*(ptr+0))) *
args->left_f) * args->distance_f);
Sint16 swapr = (Sint16) ((((float) (Sint16) SDL_SwapBE16(*(ptr+1))) *
@@ -1215,7 +1215,7 @@ static void SDLCALL _Eff_position_s32lsb(int chan, void *stream, int len, void *
}
#endif
- for (i = 0; i < len; i += sizeof (Sint32) * 2) {
+ for (i = 0; i < len; i += sizeof(Sint32) * 2) {
Sint32 swapl = (Sint32) ((((float) (Sint32) SDL_SwapLE32(*(ptr+0))) *
left_f) * dist_f);
Sint32 swapr = (Sint32) ((((float) (Sint32) SDL_SwapLE32(*(ptr+1))) *
@@ -1240,7 +1240,7 @@ static void SDLCALL _Eff_position_s32lsb_c4(int chan, void *stream, int len, voi
(void)chan;
- for (i = 0; i < len; i += sizeof (Sint32) * 4) {
+ for (i = 0; i < len; i += sizeof(Sint32) * 4) {
Sint32 swapl = (Sint32) ((((float) (Sint32) SDL_SwapLE32(*(ptr+0))) *
args->left_f) * args->distance_f);
Sint32 swapr = (Sint32) ((((float) (Sint32) SDL_SwapLE32(*(ptr+1))) *
@@ -1287,7 +1287,7 @@ static void SDLCALL _Eff_position_s32lsb_c6(int chan, void *stream, int len, voi
(void)chan;
- for (i = 0; i < len; i += sizeof (Sint32) * 6) {
+ for (i = 0; i < len; i += sizeof(Sint32) * 6) {
Sint32 swapl = (Sint32) ((((float) (Sint32) SDL_SwapLE32(*(ptr+0))) *
args->left_f) * args->distance_f);
Sint32 swapr = (Sint32) ((((float) (Sint32) SDL_SwapLE32(*(ptr+1))) *
@@ -1348,7 +1348,7 @@ static void SDLCALL _Eff_position_s32msb(int chan, void *stream, int len, void *
(void)chan;
- for (i = 0; i < len; i += sizeof (Sint32) * 2) {
+ for (i = 0; i < len; i += sizeof(Sint32) * 2) {
Sint32 swapl = (Sint32) ((((float) (Sint32) SDL_SwapBE32(*(ptr+0))) *
left_f) * dist_f);
Sint32 swapr = (Sint32) ((((float) (Sint32) SDL_SwapBE32(*(ptr+1))) *
@@ -1367,7 +1367,7 @@ static void SDLCALL _Eff_position_s32msb_c4(int chan, void *stream, int len, voi
(void)chan;
- for (i = 0; i < len; i += sizeof (Sint32) * 4) {
+ for (i = 0; i < len; i += sizeof(Sint32) * 4) {
Sint32 swapl = (Sint32) ((((float) (Sint32) SDL_SwapBE32(*(ptr+0))) *
args->left_f) * args->distance_f);
Sint32 swapr = (Sint32) ((((float) (Sint32) SDL_SwapBE32(*(ptr+1))) *
@@ -1414,7 +1414,7 @@ static void SDLCALL _Eff_position_s32msb_c6(int chan, void *stream, int len, voi
(void)chan;
- for (i = 0; i < len; i += sizeof (Sint32) * 6) {
+ for (i = 0; i < len; i += sizeof(Sint32) * 6) {
Sint32 swapl = (Sint32) ((((float) (Sint32) SDL_SwapBE32(*(ptr+0))) *
args->left_f) * args->distance_f);
Sint32 swapr = (Sint32) ((((float) (Sint32) SDL_SwapBE32(*(ptr+1))) *
@@ -1476,7 +1476,7 @@ static void SDLCALL _Eff_position_f32sys(int chan, void *stream, int len, void *
(void)chan;
- for (i = 0; i < len; i += sizeof (float) * 2) {
+ for (i = 0; i < len; i += sizeof(float) * 2) {
float swapl = ((*(ptr+0) * left_f) * dist_f);
float swapr = ((*(ptr+1) * right_f) * dist_f);
*(ptr++) = swapl;
@@ -1493,7 +1493,7 @@ static void SDLCALL _Eff_position_f32sys_c4(int chan, void *stream, int len, voi
(void)chan;
- for (i = 0; i < len; i += sizeof (float) * 4) {
+ for (i = 0; i < len; i += sizeof(float) * 4) {
float swapl = ((*(ptr+0) * args->left_f) * args->distance_f);
float swapr = ((*(ptr+1) * args->right_f) * args->distance_f);
float swaplr = ((*(ptr+2) * args->left_rear_f) * args->distance_f);
@@ -1536,7 +1536,7 @@ static void SDLCALL _Eff_position_f32sys_c6(int chan, void *stream, int len, voi
(void)chan;
- for (i = 0; i < len; i += sizeof (float) * 6) {
+ for (i = 0; i < len; i += sizeof(float) * 6) {
float swapl = ((*(ptr+0) * args->left_f) * args->distance_f);
float swapr = ((*(ptr+1) * args->right_f) * args->distance_f);
float swaplr = ((*(ptr+2) * args->left_rear_f) * args->distance_f);
@@ -1583,7 +1583,7 @@ static void SDLCALL _Eff_position_f32sys_c6(int chan, void *stream, int len, voi
static void init_position_args(position_args *args)
{
- SDL_memset(args, '\0', sizeof (position_args));
+ SDL_memset(args, '\0', sizeof(position_args));
args->in_use = 0;
args->room_angle = 0;
args->left_u8 = args->right_u8 = args->distance_u8 = 255;
@@ -1600,22 +1600,22 @@ static position_args *get_position_arg(int channel)
if (channel < 0) {
if (pos_args_global == NULL) {
- pos_args_global = SDL_malloc(sizeof (position_args));
+ pos_args_global = SDL_malloc(sizeof(position_args));
if (pos_args_global == NULL) {
Mix_OutOfMemory();
- return(NULL);
+ return NULL;
}
init_position_args(pos_args_global);
}
- return(pos_args_global);
+ return pos_args_global;
}
if (channel >= position_channels) {
rc = SDL_realloc(pos_args_array, (size_t)(channel + 1) * sizeof(position_args *));
if (rc == NULL) {
Mix_OutOfMemory();
- return(NULL);
+ return NULL;
}
pos_args_array = (position_args **) rc;
for (i = position_channels; i <= channel; i++) {
@@ -1628,12 +1628,12 @@ static position_args *get_position_arg(int channel)
pos_args_array[channel] = (position_args *)SDL_malloc(sizeof(position_args));
if (pos_args_array[channel] == NULL) {
Mix_OutOfMemory();
- return(NULL);
+ return NULL;
}
init_position_args(pos_args_array[channel]);
}
- return(pos_args_array[channel]);
+ return pos_args_array[channel];
}
static Mix_EffectFunc_t get_position_effect_func(Uint16 format, int channels)
@@ -1810,7 +1810,7 @@ static Mix_EffectFunc_t get_position_effect_func(Uint16 format, int channels)
break;
}
- return(f);
+ return f;
}
static Uint8 speaker_amplitude[6];
@@ -1822,8 +1822,7 @@ static void set_amplitudes(int channels, int angle, int room_angle)
/* our only caller Mix_SetPosition() already makes angle between 0 and 359. */
- if (channels == 2)
- {
+ if (channels == 2) {
/*
* We only attenuate by position if the angle falls on the far side
* of center; That is, an angle that's due north would not attenuate
@@ -1845,8 +1844,7 @@ static void set_amplitudes(int channels, int angle, int room_angle)
}
}
- if (channels == 4 || channels == 6)
- {
+ if (channels == 4 || channels == 6) {
/*
* An angle that's due north does not attenuate the center channel.
* An angle in the first quadrant, 0-90, does not attenuate the RF.
@@ -1962,7 +1960,7 @@ int Mix_SetPanning(int channel, Uint8 left, Uint8 right)
Mix_QuerySpec(NULL, &format, &channels);
if (channels != 2 && channels != 4 && channels != 6) /* it's a no-op; we call that successful. */
- return(1);
+ return 1;
if (channels > 2) {
/* left = right = 255 => angle = 0, to unregister effect as when channels = 2 */
@@ -1979,13 +1977,13 @@ int Mix_SetPanning(int channel, Uint8 left, Uint8 right)
f = get_position_effect_func(format, channels);
if (f == NULL)
- return(0);
+ return 0;
Mix_LockAudio();
args = get_position_arg(channel);
if (!args) {
Mix_UnlockAudio();
- return(0);
+ return 0;
}
/* it's a no-op; unregister the effect, if it's registered. */
@@ -1993,10 +1991,10 @@ int Mix_SetPanning(int channel, Uint8 left, Uint8 right)
if (args->in_use) {
retval = _Mix_UnregisterEffect_locked(channel, f);
Mix_UnlockAudio();
- return(retval);
+ return retval;
} else {
Mix_UnlockAudio();
- return(1);
+ return 1;
}
}
@@ -2012,7 +2010,7 @@ int Mix_SetPanning(int channel, Uint8 left, Uint8 right)
}
Mix_UnlockAudio();
- return(retval);
+ return retval;
}
@@ -2027,13 +2025,13 @@ int Mix_SetDistance(int channel, Uint8 distance)
Mix_QuerySpec(NULL, &format, &channels);
f = get_position_effect_func(format, channels);
if (f == NULL)
- return(0);
+ return 0;
Mix_LockAudio();
args = get_position_arg(channel);
if (!args) {
Mix_UnlockAudio();
- return(0);
+ return 0;
}
distance = 255 - distance; /* flip it to our scale. */
@@ -2043,10 +2041,10 @@ int Mix_SetDistance(int channel, Uint8 distance)
if (args->in_use) {
retval = _Mix_UnregisterEffect_locked(channel, f);
Mix_UnlockAudio();
- return(retval);
+ return retval;
} else {
Mix_UnlockAudio();
- return(1);
+ return 1;
}
}
@@ -2058,7 +2056,7 @@ int Mix_SetDistance(int channel, Uint8 distance)
}
Mix_UnlockAudio();
- return(retval);
+ return retval;
}
@@ -2074,7 +2072,7 @@ int Mix_SetPosition(int channel, Sint16 angle, Uint8 distance)
Mix_QuerySpec(NULL, &format, &channels);
f = get_position_effect_func(format, channels);
if (f == NULL)
- return(0);
+ return 0;
/* make angle between 0 and 359. */
angle %= 360;
@@ -2084,7 +2082,7 @@ int Mix_SetPosition(int channel, Sint16 angle, Uint8 distance)
args = get_position_arg(channel);
if (!args) {
Mix_UnlockAudio();
- return(0);
+ return 0;
}
/* it's a no-op; unregister the effect, if it's registered. */
@@ -2092,10 +2090,10 @@ int Mix_SetPosition(int channel, Sint16 angle, Uint8 distance)
if (args->in_use) {
retval = _Mix_UnregisterEffect_locked(channel, f);
Mix_UnlockAudio();
- return(retval);
+ return retval;
} else {
Mix_UnlockAudio();
- return(1);
+ return 1;
}
}
@@ -2109,7 +2107,7 @@ int Mix_SetPosition(int channel, Sint16 angle, Uint8 distance)
if (angle > 315) room_angle = 0;
else if (angle > 225) room_angle = 270;
else if (angle > 135) room_angle = 180;
- else if (angle > 45) room_angle = 90;
+ else if (angle > 45) room_angle = 90;
else room_angle = 0;
}
@@ -2138,7 +2136,7 @@ int Mix_SetPosition(int channel, Sint16 angle, Uint8 distance)
}
Mix_UnlockAudio();
- return(retval);
+ return retval;
}
/* end of effects_position.c ... */
diff --git a/src/effect_stereoreverse.c b/src/effect_stereoreverse.c
index 34dfb2b58..68104b2d6 100644
--- a/src/effect_stereoreverse.c
+++ b/src/effect_stereoreverse.c
@@ -58,7 +58,7 @@ static void SDLCALL _Eff_reversestereo32(int chan, void *stream, int len, void *
(void)chan;
(void)udata;
- for (i = 0; i < len; i += 2 * sizeof (Uint32), ptr += 2) {
+ for (i = 0; i < len; i += 2 * sizeof(Uint32), ptr += 2) {
tmp = ptr[0];
ptr[0] = ptr[1];
ptr[1] = tmp;
@@ -74,7 +74,7 @@ static void SDLCALL _Eff_reversestereo16(int chan, void *stream, int len, void *
(void)chan;
(void)udata;
- for (i = 0; i < len; i += sizeof (Uint32), ptr++) {
+ for (i = 0; i < len; i += sizeof(Uint32), ptr++) {
*ptr = (((*ptr) & 0xFFFF0000) >> 16) | (((*ptr) & 0x0000FFFF) << 16);
}
}
@@ -95,7 +95,7 @@ static void SDLCALL _Eff_reversestereo8(int chan, void *stream, int len, void *u
len -= 2;
}
- for (i = 0; i < len; i += sizeof (Uint32), ptr++) {
+ for (i = 0; i < len; i += sizeof(Uint32), ptr++) {
*ptr = (((*ptr) & 0x0000FF00) >> 8) | (((*ptr) & 0x000000FF) << 8) |
(((*ptr) & 0xFF000000) >> 8) | (((*ptr) & 0x00FF0000) << 8);
}
@@ -123,14 +123,16 @@ int Mix_SetReverseStereo(int channel, int flip)
break;
default:
Mix_SetError("Unsupported audio format");
- return(0);
+ return 0;
}
- if (!flip) return Mix_UnregisterEffect(channel, f);
- return(Mix_RegisterEffect(channel, f, NULL, NULL));
+ if (!flip) {
+ return Mix_UnregisterEffect(channel, f);
+ }
+ return Mix_RegisterEffect(channel, f, NULL, NULL);
}
Mix_SetError("Trying to reverse stereo on a non-stereo stream");
- return(0);
+ return 0;
}
/* end of effect_stereoreverse.c ... */
diff --git a/src/effects_internal.c b/src/effects_internal.c
index b26f9ec41..debd37d87 100644
--- a/src/effects_internal.c
+++ b/src/effects_internal.c
@@ -63,7 +63,7 @@ void *_Eff_build_volume_table_u8(void)
Uint8 *rc;
if (!_Mix_effects_max_speed) {
- return(NULL);
+ return NULL;
}
if (!_Eff_volume_table) {
@@ -80,7 +80,7 @@ void *_Eff_build_volume_table_u8(void)
}
}
- return(_Eff_volume_table);
+ return _Eff_volume_table;
}
@@ -110,7 +110,7 @@ void *_Eff_build_volume_table_s8(void)
}
}
- return(_Eff_volume_table);
+ return _Eff_volume_table;
}
diff --git a/src/mixer.c b/src/mixer.c
index 7076506a8..92f9b7c42 100644
--- a/src/mixer.c
+++ b/src/mixer.c
@@ -114,7 +114,7 @@ static SDL_atomic_t master_volume = { MIX_MAX_VOLUME };
int Mix_GetNumChunkDecoders(void)
{
- return(num_decoders);
+ return num_decoders;
}
const char *Mix_GetChunkDecoder(int index)
@@ -122,7 +122,7 @@ const char *Mix_GetChunkDecoder(int index)
if ((index < 0) || (index >= num_decoders)) {
return NULL;
}
- return(chunk_decoders[index]);
+ return chunk_decoders[index];
}
SDL_bool Mix_HasChunkDecoder(const char *name)
@@ -148,7 +148,7 @@ void add_chunk_decoder(const char *decoder)
}
}
- ptr = SDL_realloc((void *)chunk_decoders, (size_t)(num_decoders + 1) * sizeof (const char *));
+ ptr = SDL_realloc((void *)chunk_decoders, (size_t)(num_decoders + 1) * sizeof(const char *));
if (ptr == NULL) {
return; /* oh well, go on without it. */
}
@@ -161,7 +161,7 @@ const SDL_version *Mix_Linked_Version(void)
{
static SDL_version linked_version;
SDL_MIXER_VERSION(&linked_version);
- return(&linked_version);
+ return &linked_version;
}
/*
@@ -315,7 +315,7 @@ static void *Mix_DoEffects(int chan, void *snd, int len)
if (!posteffect) {
buf = SDL_malloc((size_t)len);
if (buf == NULL) {
- return(snd);
+ return snd;
}
SDL_memcpy(buf, snd, (size_t)len);
}
@@ -328,7 +328,7 @@ static void *Mix_DoEffects(int chan, void *snd, int len)
}
/* be sure to SDL_free() the return value if != snd ... */
- return(buf);
+ return buf;
}
@@ -372,7 +372,7 @@ mix_channels(void *udata, Uint8 *stream, int len)
/* Mix any playing channels... */
sdl_ticks = SDL_GetTicks();
- for (i=0; i 0 && mix_channel[i].expire < sdl_ticks) {
/* Expiration delay for that channel is reached */
@@ -502,7 +502,7 @@ int Mix_OpenAudioDevice(int frequency, Uint16 format, int nchannels, int chunksi
if (audio_opened) {
if (format == mixer.format && nchannels == mixer.channels) {
++audio_opened;
- return(0);
+ return 0;
}
while (audio_opened) {
Mix_CloseAudio();
@@ -523,7 +523,7 @@ int Mix_OpenAudioDevice(int frequency, Uint16 format, int nchannels, int chunksi
/* Accept nearly any audio format */
if ((audio_device = SDL_OpenAudioDevice(device, 0, &desired, &mixer, allowed_changes)) == 0) {
- return(-1);
+ return -1;
}
#ifndef __MORPHOS__
PrintFormat("Audio device", &mixer);
@@ -533,7 +533,7 @@ int Mix_OpenAudioDevice(int frequency, Uint16 format, int nchannels, int chunksi
mix_channel = (struct _Mix_Channel *) SDL_malloc(num_channels * sizeof(struct _Mix_Channel));
/* Clear out the audio channels */
- for (i=0; i num_channels) {
/* Initialize the new channels */
int i;
- for(i=num_channels; i < numchans; i++) {
+ for (i = num_channels; i < numchans; i++) {
mix_channel[i].chunk = NULL;
mix_channel[i].playing = 0;
mix_channel[i].looping = 0;
@@ -617,7 +617,7 @@ int Mix_AllocateChannels(int numchans)
}
num_channels = numchans;
Mix_UnlockAudio();
- return(num_channels);
+ return num_channels;
}
/* Return the actual mixer parameters */
@@ -634,7 +634,7 @@ int Mix_QuerySpec(int *frequency, Uint16 *format, int *channels)
*channels = mixer.channels;
}
}
- return(audio_opened);
+ return audio_opened;
}
typedef struct _MusicFragment
@@ -800,7 +800,7 @@ Mix_Chunk *Mix_LoadWAV_RW(SDL_RWops *src, int freesrc)
/* rcg06012001 Make sure src is valid */
if (!src) {
Mix_SetError("Mix_LoadWAV_RW with NULL src");
- return(NULL);
+ return NULL;
}
/* Make sure audio has been opened */
@@ -809,7 +809,7 @@ Mix_Chunk *Mix_LoadWAV_RW(SDL_RWops *src, int freesrc)
if (freesrc) {
SDL_RWclose(src);
}
- return(NULL);
+ return NULL;
}
/* Allocate the chunk memory */
@@ -819,7 +819,7 @@ Mix_Chunk *Mix_LoadWAV_RW(SDL_RWops *src, int freesrc)
if (freesrc) {
SDL_RWclose(src);
}
- return(NULL);
+ return NULL;
}
/* Find out what kind of audio file this is */
@@ -848,7 +848,7 @@ Mix_Chunk *Mix_LoadWAV_RW(SDL_RWops *src, int freesrc)
if (!loaded) {
/* The individual loaders have closed src if needed */
SDL_free(chunk);
- return(NULL);
+ return NULL;
}
#if 0
@@ -869,7 +869,7 @@ Mix_Chunk *Mix_LoadWAV_RW(SDL_RWops *src, int freesrc)
SDL_free(chunk->abuf);
}
SDL_free(chunk);
- return(NULL);
+ return NULL;
}
samplesize = ((wavespec.format & 0xFF)/8)*wavespec.channels;
wavecvt.len = chunk->alen & ~(samplesize - 1);
@@ -882,7 +882,7 @@ Mix_Chunk *Mix_LoadWAV_RW(SDL_RWops *src, int freesrc)
SDL_free(chunk->abuf);
}
SDL_free(chunk);
- return(NULL);
+ return NULL;
}
SDL_memcpy(wavecvt.buf, chunk->abuf, wavecvt.len);
if (wavfree) {
@@ -895,7 +895,7 @@ Mix_Chunk *Mix_LoadWAV_RW(SDL_RWops *src, int freesrc)
if (SDL_ConvertAudio(&wavecvt) < 0) {
SDL_free(wavecvt.buf);
SDL_free(chunk);
- return(NULL);
+ return NULL;
}
resized_buf = SDL_realloc(wavecvt.buf, wavecvt.len_cvt);
@@ -911,7 +911,7 @@ Mix_Chunk *Mix_LoadWAV_RW(SDL_RWops *src, int freesrc)
chunk->allocated = (wavfree == 0) ? 1 : 2; /* see Mix_FreeChunk() */
chunk->volume = MIX_MAX_VOLUME;
- return(chunk);
+ return chunk;
}
Mix_Chunk *Mix_LoadWAV(const char *file)
@@ -929,14 +929,14 @@ Mix_Chunk *Mix_QuickLoad_WAV(Uint8 *mem)
/* Make sure audio has been opened */
if (! audio_opened) {
Mix_SetError("Audio device hasn't been opened");
- return(NULL);
+ return NULL;
}
/* Allocate the chunk memory */
chunk = (Mix_Chunk *)SDL_calloc(1,sizeof(Mix_Chunk));
if (chunk == NULL) {
Mix_OutOfMemory();
- return(NULL);
+ return NULL;
}
/* Essentially just skip to the audio data (no error checking - fast) */
@@ -952,7 +952,7 @@ Mix_Chunk *Mix_QuickLoad_WAV(Uint8 *mem)
} while (SDL_memcmp(magic, "data", 4) != 0);
chunk->volume = MIX_MAX_VOLUME;
- return(chunk);
+ return chunk;
}
/* Load raw audio data of the mixer format from a memory buffer */
@@ -963,14 +963,14 @@ Mix_Chunk *Mix_QuickLoad_RAW(Uint8 *mem, Uint32 len)
/* Make sure audio has been opened */
if (! audio_opened) {
Mix_SetError("Audio device hasn't been opened");
- return(NULL);
+ return NULL;
}
/* Allocate the chunk memory */
chunk = (Mix_Chunk *)SDL_malloc(sizeof(Mix_Chunk));
if (chunk == NULL) {
Mix_OutOfMemory();
- return(NULL);
+ return NULL;
}
/* Essentially just point at the audio data (no error checking - fast) */
@@ -979,7 +979,7 @@ Mix_Chunk *Mix_QuickLoad_RAW(Uint8 *mem, Uint32 len)
chunk->abuf = mem;
chunk->volume = MIX_MAX_VOLUME;
- return(chunk);
+ return chunk;
}
/* MAKE SURE you hold the audio lock (Mix_LockAudio()) before calling this! */
@@ -1006,7 +1006,7 @@ void Mix_FreeChunk(Mix_Chunk *chunk)
/* Guarantee that this chunk isn't playing */
Mix_LockAudio();
if (mix_channel) {
- for (i=0; i num_channels)
num = num_channels;
reserved_channels = num;
@@ -1103,12 +1105,10 @@ int Mix_PlayChannelTimed(int which, Mix_Chunk *chunk, int loops, int ticks)
/* Don't play null pointers :-) */
if (chunk == NULL) {
- Mix_SetError("Tried to play a NULL chunk");
- return(-1);
+ return Mix_SetError("Tried to play a NULL chunk");
}
if (!checkchunkintegral(chunk)) {
- Mix_SetError("Tried to play a chunk with a bad frame");
- return(-1);
+ return Mix_SetError("Tried to play a chunk with a bad frame");
}
/* Lock the mixer while modifying the playing channels */
@@ -1116,7 +1116,7 @@ int Mix_PlayChannelTimed(int which, Mix_Chunk *chunk, int loops, int ticks)
{
/* If which is -1, play on the first free channel */
if (which == -1) {
- for (i=reserved_channels; i0) ? (SDL_GetTicks() + (Uint32)ticks) : 0;
Mix_UnlockAudio();
- ++ status;
+ ++status;
}
- return(status);
+ return status;
}
/* Fade in a sound on a channel, over ms milliseconds */
@@ -1181,11 +1181,10 @@ int Mix_FadeInChannelTimed(int which, Mix_Chunk *chunk, int loops, int ms, int t
/* Don't play null pointers :-) */
if (chunk == NULL) {
- return(-1);
+ return -1;
}
if (!checkchunkintegral(chunk)) {
- Mix_SetError("Tried to play a chunk with a bad frame");
- return(-1);
+ return Mix_SetError("Tried to play a chunk with a bad frame");
}
/* Lock the mixer while modifying the playing channels */
@@ -1193,7 +1192,7 @@ int Mix_FadeInChannelTimed(int which, Mix_Chunk *chunk, int loops, int ms, int t
{
/* If which is -1, play on the first free channel */
if (which == -1) {
- for (i=reserved_channels; ivolume;
if (volume >= 0) {
@@ -1275,7 +1274,7 @@ int Mix_VolumeChunk(Mix_Chunk *chunk, int volume)
}
chunk->volume = volume;
}
- return(prev_volume);
+ return prev_volume;
}
/* Halt playing of a particular channel */
@@ -1285,14 +1284,14 @@ int Mix_HaltChannel(int which)
Mix_LockAudio();
if (which == -1) {
- for (i=0; i 0) ||
mix_channel[i].looping)
{
@@ -1391,7 +1390,7 @@ int Mix_Playing(int which)
++status;
}
}
- return(status);
+ return status;
}
/* rcg06072001 Get the chunk associated with a channel. */
@@ -1403,7 +1402,7 @@ Mix_Chunk *Mix_GetChunk(int channel)
retval = mix_channel[channel].chunk;
}
- return(retval);
+ return retval;
}
/* Close the mixer, halting all playing audio */
@@ -1442,7 +1441,7 @@ void Mix_Pause(int which)
if (which == -1) {
int i;
- for (i=0; i 0)
+ if (mix_channel[i].expire > 0) {
mix_channel[i].expire += sdl_ticks - mix_channel[i].paused;
+ }
mix_channel[i].paused = 0;
}
}
} else if (which < num_channels) {
if (Mix_Playing(which)) {
- if (mix_channel[which].expire > 0)
+ if (mix_channel[which].expire > 0) {
mix_channel[which].expire += sdl_ticks - mix_channel[which].paused;
+ }
mix_channel[which].paused = 0;
}
}
@@ -1485,51 +1486,52 @@ int Mix_Paused(int which)
if (which < 0) {
int status = 0;
int i;
- for(i=0; i < num_channels; ++i) {
+ for (i = 0; i < num_channels; ++i) {
if (Mix_Playing(i) && mix_channel[i].paused) {
- ++ status;
+ ++status;
}
}
- return(status);
- } else if (which < num_channels) {
- return(Mix_Playing(which) && mix_channel[which].paused != 0);
- } else {
- return(0);
+ return status;
}
+ if (which < num_channels) {
+ return (Mix_Playing(which) && mix_channel[which].paused != 0);
+ }
+ return 0;
}
/* Change the group of a channel */
int Mix_GroupChannel(int which, int tag)
{
- if (which < 0 || which > num_channels)
- return(0);
+ if (which < 0 || which > num_channels) {
+ return 0;
+ }
Mix_LockAudio();
mix_channel[which].tag = tag;
Mix_UnlockAudio();
- return(1);
+ return 1;
}
/* Assign several consecutive channels to a group */
int Mix_GroupChannels(int from, int to, int tag)
{
int status = 0;
- for(; from <= to; ++ from) {
+ for (; from <= to; ++from) {
status += Mix_GroupChannel(from, tag);
}
- return(status);
+ return status;
}
/* Finds the first available channel in a group of channels */
int Mix_GroupAvailable(int tag)
{
int i;
- for(i=0; i < num_channels; i ++) {
- if (((tag == -1) || (tag == mix_channel[i].tag)) &&
- (!Mix_Playing(i)))
+ for (i = 0; i < num_channels; i++) {
+ if ((tag == -1 || tag == mix_channel[i].tag) && !Mix_Playing(i)) {
return i;
+ }
}
- return(-1);
+ return -1;
}
int Mix_GroupCount(int tag)
@@ -1541,11 +1543,12 @@ int Mix_GroupCount(int tag)
return num_channels; /* minor optimization; no need to go through the loop. */
}
- for(i=0; i < num_channels; i ++) {
- if (mix_channel[i].tag == tag)
- ++ count;
+ for (i = 0; i < num_channels; i++) {
+ if (mix_channel[i].tag == tag) {
+ ++count;
+ }
}
- return(count);
+ return count;
}
/* Finds the "oldest" sample playing in a group of channels */
@@ -1554,14 +1557,14 @@ int Mix_GroupOldest(int tag)
int chan = -1;
Uint32 mintime = SDL_GetTicks();
int i;
- for(i=0; i < num_channels; i ++) {
- if ((mix_channel[i].tag==tag || tag==-1) && Mix_Playing(i)
+ for (i = 0; i < num_channels; i++) {
+ if ((mix_channel[i].tag == tag || tag == -1) && Mix_Playing(i)
&& mix_channel[i].start_time <= mintime) {
mintime = mix_channel[i].start_time;
chan = i;
}
}
- return(chan);
+ return chan;
}
/* Finds the "most recent" (i.e. last) sample playing in a group of channels */
@@ -1570,14 +1573,14 @@ int Mix_GroupNewer(int tag)
int chan = -1;
Uint32 maxtime = 0;
int i;
- for(i=0; i < num_channels; i ++) {
- if ((mix_channel[i].tag==tag || tag==-1) && Mix_Playing(i)
+ for (i = 0; i < num_channels; i++) {
+ if ((mix_channel[i].tag == tag || tag == -1) && Mix_Playing(i)
&& mix_channel[i].start_time >= maxtime) {
maxtime = mix_channel[i].start_time;
chan = i;
}
}
- return(chan);
+ return chan;
}
@@ -1596,18 +1599,18 @@ static int _Mix_register_effect(effect_info **e, Mix_EffectFunc_t f,
if (!e) {
Mix_SetError("Internal error");
- return(0);
+ return 0;
}
if (f == NULL) {
Mix_SetError("NULL effect callback");
- return(0);
+ return 0;
}
- new_e = SDL_malloc(sizeof (effect_info));
+ new_e = SDL_malloc(sizeof(effect_info));
if (new_e == NULL) {
Mix_OutOfMemory();
- return(0);
+ return 0;
}
new_e->callback = f;
@@ -1629,7 +1632,7 @@ static int _Mix_register_effect(effect_info **e, Mix_EffectFunc_t f,
}
}
- return(1);
+ return 1;
}
@@ -1642,7 +1645,7 @@ static int _Mix_remove_effect(int channel, effect_info **e, Mix_EffectFunc_t f)
if (!e) {
Mix_SetError("Internal error");
- return(0);
+ return 0;
}
for (cur = *e; cur != NULL; cur = cur->next) {
@@ -1658,13 +1661,13 @@ static int _Mix_remove_effect(int channel, effect_info **e, Mix_EffectFunc_t f)
} else {
prev->next = next;
}
- return(1);
+ return 1;
}
prev = cur;
}
Mix_SetError("No such effect registered");
- return(0);
+ return 0;
}
@@ -1676,7 +1679,7 @@ static int _Mix_remove_all_effects(int channel, effect_info **e)
if (!e) {
Mix_SetError("Internal error");
- return(0);
+ return 0;
}
for (cur = *e; cur != NULL; cur = next) {
@@ -1688,7 +1691,7 @@ static int _Mix_remove_all_effects(int channel, effect_info **e)
}
*e = NULL;
- return(1);
+ return 1;
}
@@ -1703,7 +1706,7 @@ int _Mix_RegisterEffect_locked(int channel, Mix_EffectFunc_t f,
} else {
if ((channel < 0) || (channel >= num_channels)) {
Mix_SetError("Invalid channel number");
- return(0);
+ return 0;
}
e = &mix_channel[channel].effects;
}
@@ -1732,7 +1735,7 @@ int _Mix_UnregisterEffect_locked(int channel, Mix_EffectFunc_t f)
} else {
if ((channel < 0) || (channel >= num_channels)) {
Mix_SetError("Invalid channel number");
- return(0);
+ return 0;
}
e = &mix_channel[channel].effects;
}
@@ -1746,7 +1749,7 @@ int Mix_UnregisterEffect(int channel, Mix_EffectFunc_t f)
Mix_LockAudio();
retval = _Mix_UnregisterEffect_locked(channel, f);
Mix_UnlockAudio();
- return(retval);
+ return retval;
}
/* MAKE SURE you hold the audio lock (Mix_LockAudio()) before calling this! */
@@ -1759,7 +1762,7 @@ int _Mix_UnregisterAllEffects_locked(int channel)
} else {
if ((channel < 0) || (channel >= num_channels)) {
Mix_SetError("Invalid channel number");
- return(0);
+ return 0;
}
e = &mix_channel[channel].effects;
}
@@ -1773,7 +1776,7 @@ int Mix_UnregisterAllEffects(int channel)
Mix_LockAudio();
retval = _Mix_UnregisterAllEffects_locked(channel);
Mix_UnlockAudio();
- return(retval);
+ return retval;
}
void Mix_LockAudio(void)
@@ -1796,7 +1799,7 @@ int Mix_MasterVolume(int volume)
volume = SDL_MIX_MAXVOLUME;
}
SDL_AtomicSet(&master_volume, volume);
- return(prev_volume);
+ return prev_volume;
}
/* end of mixer.c ... */
diff --git a/src/music.c b/src/music.c
index d51be997c..5148061d9 100644
--- a/src/music.c
+++ b/src/music.c
@@ -35,7 +35,7 @@
#include "music_timidity.h"
#include "music_ogg.h"
#include "music_opus.h"
-#include "music_drmp3.h"
+#include "music_minimp3.h"
#include "music_mpg123.h"
#include "music_drflac.h"
#include "music_flac.h"
@@ -142,7 +142,7 @@ const char *meta_tags_get(Mix_MusicMetaTags *tags, Mix_MusicMetaTag type)
}
/* for music->filename */
-#if defined(__WIN32__)||defined(__OS2__)
+#if defined(_WIN32) || defined(__OS2__)
static SDL_INLINE const char *get_last_dirsep (const char *p) {
const char *p1 = SDL_strrchr(p, '/');
const char *p2 = SDL_strrchr(p, '\\');
@@ -181,8 +181,8 @@ static Mix_MusicInterface *s_music_interfaces[] =
#ifdef MUSIC_OPUS
&Mix_MusicInterface_Opus,
#endif
-#ifdef MUSIC_MP3_DRMP3
- &Mix_MusicInterface_DRMP3,
+#ifdef MUSIC_MP3_MINIMP3
+ &Mix_MusicInterface_MINIMP3,
#endif
#ifdef MUSIC_MP3_MPG123
&Mix_MusicInterface_MPG123,
@@ -219,7 +219,7 @@ Mix_MusicInterface *get_music_interface(int index)
int Mix_GetNumMusicDecoders(void)
{
- return(num_decoders);
+ return num_decoders;
}
const char *Mix_GetMusicDecoder(int index)
@@ -227,7 +227,7 @@ const char *Mix_GetMusicDecoder(int index)
if ((index < 0) || (index >= num_decoders)) {
return NULL;
}
- return(music_decoders[index]);
+ return music_decoders[index];
}
SDL_bool Mix_HasMusicDecoder(const char *name)
@@ -253,7 +253,7 @@ static void add_music_decoder(const char *decoder)
}
}
- ptr = SDL_realloc((void *)music_decoders, ((size_t)num_decoders + 1) * sizeof (const char *));
+ ptr = SDL_realloc((void *)music_decoders, ((size_t)num_decoders + 1) * sizeof(const char *));
if (ptr == NULL) {
return; /* oh well, go on without it. */
}
@@ -847,7 +847,7 @@ Mix_MusicType Mix_GetMusicType(const Mix_Music *music)
}
Mix_UnlockAudio();
}
- return(type);
+ return type;
}
static const char * get_music_tag_internal(const Mix_Music *music, Mix_MusicMetaTag tag_type)
@@ -938,7 +938,7 @@ static int music_internal_play(Mix_Music *music, int play_count, double position
music->playing = SDL_FALSE;
music_playing = NULL;
}
- return(retval);
+ return retval;
}
int Mix_FadeInMusicPos(Mix_Music *music, int loops, int ms, double position)
@@ -946,14 +946,12 @@ int Mix_FadeInMusicPos(Mix_Music *music, int loops, int ms, double position)
int retval;
if (ms_per_step == 0) {
- Mix_SetError("Audio device hasn't been opened");
- return(-1);
+ return Mix_SetError("Audio device hasn't been opened");
}
/* Don't play null pointers :-) */
if (music == NULL) {
- Mix_SetError("music parameter was NULL");
- return(-1);
+ return Mix_SetError("music parameter was NULL");
}
/* Setup the data */
@@ -982,7 +980,7 @@ int Mix_FadeInMusicPos(Mix_Music *music, int loops, int ms, double position)
music_active = (retval == 0);
Mix_UnlockAudio();
- return(retval);
+ return retval;
}
int Mix_FadeInMusic(Mix_Music *music, int loops, int ms)
{
@@ -1037,7 +1035,7 @@ int Mix_SetMusicPosition(double position)
}
Mix_UnlockAudio();
- return(retval);
+ return retval;
}
/* Set the playing music position */
@@ -1063,7 +1061,7 @@ double Mix_GetMusicPosition(Mix_Music *music)
}
Mix_UnlockAudio();
- return(retval);
+ return retval;
}
static double music_internal_duration(Mix_Music *music)
@@ -1090,7 +1088,7 @@ double Mix_MusicDuration(Mix_Music *music)
}
Mix_UnlockAudio();
- return(retval);
+ return retval;
}
/* Get Loop start position */
@@ -1116,7 +1114,7 @@ double Mix_GetMusicLoopStartTime(Mix_Music *music)
}
Mix_UnlockAudio();
- return(retval);
+ return retval;
}
/* Get Loop end position */
@@ -1142,7 +1140,7 @@ double Mix_GetMusicLoopEndTime(Mix_Music *music)
}
Mix_UnlockAudio();
- return(retval);
+ return retval;
}
/* Get Loop end position */
@@ -1168,7 +1166,7 @@ double Mix_GetMusicLoopLengthTime(Mix_Music *music)
}
Mix_UnlockAudio();
- return(retval);
+ return retval;
}
/* Set the music's initial volume */
@@ -1205,7 +1203,7 @@ int Mix_VolumeMusic(int volume)
music_internal_volume(music_volume);
}
Mix_UnlockAudio();
- return(prev_volume);
+ return prev_volume;
}
int Mix_GetMusicVolume(Mix_Music *music)
@@ -1245,7 +1243,7 @@ int Mix_HaltMusic(void)
}
Mix_UnlockAudio();
- return(0);
+ return 0;
}
/* Progressively stop the music */
@@ -1284,7 +1282,7 @@ int Mix_FadeOutMusic(int ms)
}
Mix_UnlockAudio();
- return(retval);
+ return retval;
}
Mix_Fading Mix_FadingMusic(void)
@@ -1297,7 +1295,7 @@ Mix_Fading Mix_FadingMusic(void)
}
Mix_UnlockAudio();
- return(fading);
+ return fading;
}
/* Pause/Resume the music stream */
diff --git a/src/music.h b/src/music.h
index 705e0a45b..c848c8d8b 100644
--- a/src/music.h
+++ b/src/music.h
@@ -34,7 +34,7 @@ typedef enum
MIX_MUSIC_TIMIDITY,
MIX_MUSIC_NATIVEMIDI,
MIX_MUSIC_OGG,
- MIX_MUSIC_DRMP3,
+ MIX_MUSIC_MINIMP3,
MIX_MUSIC_MPG123,
MIX_MUSIC_DRFLAC,
MIX_MUSIC_FLAC,
diff --git a/version.rc b/version.rc
index efd4dc71a..acfae7809 100644
--- a/version.rc
+++ b/version.rc
@@ -9,8 +9,8 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
//
VS_VERSION_INFO VERSIONINFO
- FILEVERSION 2,7,1,0
- PRODUCTVERSION 2,7,1,0
+ FILEVERSION 2,8,0,0
+ PRODUCTVERSION 2,8,0,0
FILEFLAGSMASK 0x3fL
FILEFLAGS 0x0L
FILEOS 0x40004L
@@ -23,12 +23,12 @@ BEGIN
BEGIN
VALUE "CompanyName", "\0"
VALUE "FileDescription", "SDL_mixer\0"
- VALUE "FileVersion", "2, 7, 1, 0\0"
+ VALUE "FileVersion", "2, 8, 0, 0\0"
VALUE "InternalName", "SDL_mixer\0"
VALUE "LegalCopyright", "Copyright (C) 2024 Sam Lantinga\0"
VALUE "OriginalFilename", "SDL_mixer.dll\0"
VALUE "ProductName", "Simple DirectMedia Layer\0"
- VALUE "ProductVersion", "2, 7, 1, 0\0"
+ VALUE "ProductVersion", "2, 8, 0, 0\0"
END
END
BLOCK "VarFileInfo"