move tag skip and SDL_RW with bookkeeping code into separate mp3utils.c
authorOzkan Sezer
Tue, 10 Dec 2019 17:55:03 +0300
changeset 1070db2d266f592e
parent 1069 8d8ebc200fd4
child 1071 322880726dd9
move tag skip and SDL_RW with bookkeeping code into separate mp3utils.c

it is currently used by music_mad.c. if it gets used in music_mpg123.c,
remember to adjust the ifdef guard.
Makefile.in
VisualC-WinRT/UWP_VS2015/SDL_mixer-UWP.vcxproj
VisualC-WinRT/UWP_VS2015/SDL_mixer-UWP.vcxproj.filters
VisualC-WinRT/WinPhone80_VS2012/SDL_mixer-WinPhone80.vcxproj
VisualC-WinRT/WinPhone80_VS2012/SDL_mixer-WinPhone80.vcxproj.filters
VisualC-WinRT/WinPhone81_VS2013/SDL_mixer-WinPhone81.vcxproj
VisualC-WinRT/WinPhone81_VS2013/SDL_mixer-WinPhone81.vcxproj.filters
VisualC-WinRT/WinRT80_VS2012/SDL_mixer-WinRT80.vcxproj
VisualC-WinRT/WinRT80_VS2012/SDL_mixer-WinRT80.vcxproj.filters
VisualC-WinRT/WinRT81_VS2013/SDL_mixer-WinRT81.vcxproj
VisualC-WinRT/WinRT81_VS2013/SDL_mixer-WinRT81.vcxproj.filters
VisualC/SDL_mixer.vcxproj
VisualC/SDL_mixer.vcxproj.filters
Xcode-iOS/SDL_mixer.xcodeproj/project.pbxproj
Xcode/SDL_mixer.xcodeproj/project.pbxproj
src/codecs/mp3utils.c
src/codecs/mp3utils.h
src/codecs/music_mad.c
     1.1 --- a/Makefile.in	Sun Dec 08 20:10:40 2019 +0300
     1.2 +++ b/Makefile.in	Tue Dec 10 17:55:03 2019 +0300
     1.3 @@ -38,7 +38,7 @@
     1.4  PLAYWAVE_OBJECTS = @PLAYWAVE_OBJECTS@
     1.5  PLAYMUS_OBJECTS = @PLAYMUS_OBJECTS@
     1.6  
     1.7 -DIST = *.txt Android.mk Makefile.in SDL2_mixer.pc.in SDL2_mixer.spec.in include/SDL_mixer.h VisualC VisualC-WinRT Xcode Xcode-iOS acinclude aclocal.m4 autogen.sh build-scripts configure configure.in debian external gcc-fat.sh src/compat.c src/compat.h src/effect_position.c src/effect_stereoreverse.c src/effects_internal.c src/effects_internal.h src/codecs/load_aiff.c src/codecs/load_aiff.h src/codecs/load_voc.c src/codecs/load_voc.h src/mixer.c src/mixer.h src/music.c src/music.h src/codecs/music_cmd.c src/codecs/music_cmd.h src/codecs/music_flac.c src/codecs/music_flac.h src/codecs/music_fluidsynth.c src/codecs/music_fluidsynth.h src/codecs/music_mad.c src/codecs/music_mad.h src/codecs/music_mikmod.c src/codecs/music_mikmod.h src/codecs/music_modplug.c src/codecs/music_modplug.h src/codecs/music_mpg123.c src/codecs/music_mpg123.h src/codecs/music_nativemidi.c src/codecs/music_nativemidi.h src/codecs/music_ogg.c src/codecs/music_ogg.h src/codecs/music_opus.c src/codecs/music_opus.h src/codecs/music_timidity.c src/codecs/music_timidity.h src/codecs/music_wav.c src/codecs/music_wav.h src/codecs/native_midi playmus.c playwave.c src/codecs/timidity version.rc
     1.8 +DIST = *.txt Android.mk Makefile.in SDL2_mixer.pc.in SDL2_mixer.spec.in include/SDL_mixer.h VisualC VisualC-WinRT Xcode Xcode-iOS acinclude aclocal.m4 autogen.sh build-scripts configure configure.in debian external gcc-fat.sh src/compat.c src/compat.h src/effect_position.c src/effect_stereoreverse.c src/effects_internal.c src/effects_internal.h src/codecs/load_aiff.c src/codecs/load_aiff.h src/codecs/load_voc.c src/codecs/load_voc.h src/codecs/mp3utils.c src/codecs/mp3utils.h src/mixer.c src/mixer.h src/music.c src/music.h src/codecs/music_cmd.c src/codecs/music_cmd.h src/codecs/music_flac.c src/codecs/music_flac.h src/codecs/music_fluidsynth.c src/codecs/music_fluidsynth.h src/codecs/music_mad.c src/codecs/music_mad.h src/codecs/music_mikmod.c src/codecs/music_mikmod.h src/codecs/music_modplug.c src/codecs/music_modplug.h src/codecs/music_mpg123.c src/codecs/music_mpg123.h src/codecs/music_nativemidi.c src/codecs/music_nativemidi.h src/codecs/music_ogg.c src/codecs/music_ogg.h src/codecs/music_opus.c src/codecs/music_opus.h src/codecs/music_timidity.c src/codecs/music_timidity.h src/codecs/music_wav.c src/codecs/music_wav.h src/codecs/native_midi playmus.c playwave.c src/codecs/timidity version.rc
     1.9  
    1.10  LT_AGE      = @LT_AGE@
    1.11  LT_CURRENT  = @LT_CURRENT@
     2.1 --- a/VisualC-WinRT/UWP_VS2015/SDL_mixer-UWP.vcxproj	Sun Dec 08 20:10:40 2019 +0300
     2.2 +++ b/VisualC-WinRT/UWP_VS2015/SDL_mixer-UWP.vcxproj	Tue Dec 10 17:55:03 2019 +0300
     2.3 @@ -35,6 +35,7 @@
     2.4      <ClCompile Include="..\..\src\music.c" />
     2.5      <ClCompile Include="..\..\src\codecs\load_aiff.c" />
     2.6      <ClCompile Include="..\..\src\codecs\load_voc.c" />
     2.7 +    <ClCompile Include="..\..\src\codecs\mp3utils.c" />
     2.8      <ClCompile Include="..\..\src\codecs\music_cmd.c" />
     2.9      <ClCompile Include="..\..\src\codecs\music_flac.c" />
    2.10      <ClCompile Include="..\..\src\codecs\music_fluidsynth.c" />
     3.1 --- a/VisualC-WinRT/UWP_VS2015/SDL_mixer-UWP.vcxproj.filters	Sun Dec 08 20:10:40 2019 +0300
     3.2 +++ b/VisualC-WinRT/UWP_VS2015/SDL_mixer-UWP.vcxproj.filters	Tue Dec 10 17:55:03 2019 +0300
     3.3 @@ -9,6 +9,7 @@
     3.4      <ClCompile Include="..\..\src\music.c" />
     3.5      <ClCompile Include="..\..\src\codecs\load_aiff.c" />
     3.6      <ClCompile Include="..\..\src\codecs\load_voc.c" />
     3.7 +    <ClCompile Include="..\..\src\codecs\mp3utils.c" />
     3.8      <ClCompile Include="..\..\src\codecs\music_cmd.c" />
     3.9      <ClCompile Include="..\..\src\codecs\music_flac.c" />
    3.10      <ClCompile Include="..\..\src\codecs\music_fluidsynth.c" />
     4.1 --- a/VisualC-WinRT/WinPhone80_VS2012/SDL_mixer-WinPhone80.vcxproj	Sun Dec 08 20:10:40 2019 +0300
     4.2 +++ b/VisualC-WinRT/WinPhone80_VS2012/SDL_mixer-WinPhone80.vcxproj	Tue Dec 10 17:55:03 2019 +0300
     4.3 @@ -172,6 +172,7 @@
     4.4      <ClCompile Include="..\..\src\music.c" />
     4.5      <ClCompile Include="..\..\src\codecs\load_aiff.c" />
     4.6      <ClCompile Include="..\..\src\codecs\load_voc.c" />
     4.7 +    <ClCompile Include="..\..\src\codecs\mp3utils.c" />
     4.8      <ClCompile Include="..\..\src\codecs\music_cmd.c" />
     4.9      <ClCompile Include="..\..\src\codecs\music_flac.c" />
    4.10      <ClCompile Include="..\..\src\codecs\music_fluidsynth.c" />
    4.11 @@ -202,6 +203,7 @@
    4.12      <ClInclude Include="..\..\src\music.h" />
    4.13      <ClInclude Include="..\..\src\codecs\load_aiff.h" />
    4.14      <ClInclude Include="..\..\src\codecs\load_voc.h" />
    4.15 +    <ClInclude Include="..\..\src\codecs\mp3utils.h" />
    4.16      <ClInclude Include="..\..\src\codecs\music_cmd.h" />
    4.17      <ClInclude Include="..\..\src\codecs\music_flac.h" />
    4.18      <ClInclude Include="..\..\src\codecs\music_fluidsynth.h" />
     5.1 --- a/VisualC-WinRT/WinPhone80_VS2012/SDL_mixer-WinPhone80.vcxproj.filters	Sun Dec 08 20:10:40 2019 +0300
     5.2 +++ b/VisualC-WinRT/WinPhone80_VS2012/SDL_mixer-WinPhone80.vcxproj.filters	Tue Dec 10 17:55:03 2019 +0300
     5.3 @@ -9,6 +9,7 @@
     5.4      <ClCompile Include="..\..\src\music.c" />
     5.5      <ClCompile Include="..\..\src\codecs\load_aiff.c" />
     5.6      <ClCompile Include="..\..\src\codecs\load_voc.c" />
     5.7 +    <ClCompile Include="..\..\src\codecs\mp3utils.c" />
     5.8      <ClCompile Include="..\..\src\codecs\music_cmd.c" />
     5.9      <ClCompile Include="..\..\src\codecs\music_flac.c" />
    5.10      <ClCompile Include="..\..\src\codecs\music_fluidsynth.c" />
    5.11 @@ -57,6 +58,7 @@
    5.12      <ClInclude Include="..\..\src\music.h" />
    5.13      <ClInclude Include="..\..\src\codecs\load_aiff.h" />
    5.14      <ClInclude Include="..\..\src\codecs\load_voc.h" />
    5.15 +    <ClInclude Include="..\..\src\codecs\mp3utils.h" />
    5.16      <ClInclude Include="..\..\src\codecs\music_cmd.h" />
    5.17      <ClInclude Include="..\..\src\codecs\music_flac.h" />
    5.18      <ClInclude Include="..\..\src\codecs\music_fluidsynth.h" />
     6.1 --- a/VisualC-WinRT/WinPhone81_VS2013/SDL_mixer-WinPhone81.vcxproj	Sun Dec 08 20:10:40 2019 +0300
     6.2 +++ b/VisualC-WinRT/WinPhone81_VS2013/SDL_mixer-WinPhone81.vcxproj	Tue Dec 10 17:55:03 2019 +0300
     6.3 @@ -41,6 +41,7 @@
     6.4      <ClCompile Include="..\..\src\music.c" />
     6.5      <ClCompile Include="..\..\src\codecs\load_aiff.c" />
     6.6      <ClCompile Include="..\..\src\codecs\load_voc.c" />
     6.7 +    <ClCompile Include="..\..\src\codecs\mp3utils.c" />
     6.8      <ClCompile Include="..\..\src\codecs\music_cmd.c" />
     6.9      <ClCompile Include="..\..\src\codecs\music_flac.c" />
    6.10      <ClCompile Include="..\..\src\codecs\music_fluidsynth.c" />
    6.11 @@ -71,6 +72,7 @@
    6.12      <ClInclude Include="..\..\src\music.h" />
    6.13      <ClInclude Include="..\..\src\codecs\load_aiff.h" />
    6.14      <ClInclude Include="..\..\src\codecs\load_voc.h" />
    6.15 +    <ClInclude Include="..\..\src\codecs\mp3utils.h" />
    6.16      <ClInclude Include="..\..\src\codecs\music_cmd.h" />
    6.17      <ClInclude Include="..\..\src\codecs\music_flac.h" />
    6.18      <ClInclude Include="..\..\src\codecs\music_fluidsynth.h" />
     7.1 --- a/VisualC-WinRT/WinPhone81_VS2013/SDL_mixer-WinPhone81.vcxproj.filters	Sun Dec 08 20:10:40 2019 +0300
     7.2 +++ b/VisualC-WinRT/WinPhone81_VS2013/SDL_mixer-WinPhone81.vcxproj.filters	Tue Dec 10 17:55:03 2019 +0300
     7.3 @@ -9,6 +9,7 @@
     7.4      <ClCompile Include="..\..\src\music.c" />
     7.5      <ClCompile Include="..\..\src\codecs\load_aiff.c" />
     7.6      <ClCompile Include="..\..\src\codecs\load_voc.c" />
     7.7 +    <ClCompile Include="..\..\src\codecs\mp3utils.c" />
     7.8      <ClCompile Include="..\..\src\codecs\music_cmd.c" />
     7.9      <ClCompile Include="..\..\src\codecs\music_flac.c" />
    7.10      <ClCompile Include="..\..\src\codecs\music_fluidsynth.c" />
    7.11 @@ -57,6 +58,7 @@
    7.12      <ClInclude Include="..\..\src\music.h" />
    7.13      <ClInclude Include="..\..\src\codecs\load_aiff.h" />
    7.14      <ClInclude Include="..\..\src\codecs\load_voc.h" />
    7.15 +    <ClInclude Include="..\..\src\codecs\mp3utils.h" />
    7.16      <ClInclude Include="..\..\src\codecs\music_cmd.h" />
    7.17      <ClInclude Include="..\..\src\codecs\music_flac.h" />
    7.18      <ClInclude Include="..\..\src\codecs\music_fluidsynth.h" />
     8.1 --- a/VisualC-WinRT/WinRT80_VS2012/SDL_mixer-WinRT80.vcxproj	Sun Dec 08 20:10:40 2019 +0300
     8.2 +++ b/VisualC-WinRT/WinRT80_VS2012/SDL_mixer-WinRT80.vcxproj	Tue Dec 10 17:55:03 2019 +0300
     8.3 @@ -49,6 +49,7 @@
     8.4      <ClCompile Include="..\..\src\music.c" />
     8.5      <ClCompile Include="..\..\src\codecs\load_aiff.c" />
     8.6      <ClCompile Include="..\..\src\codecs\load_voc.c" />
     8.7 +    <ClCompile Include="..\..\src\codecs\mp3utils.c" />
     8.8      <ClCompile Include="..\..\src\codecs\music_cmd.c" />
     8.9      <ClCompile Include="..\..\src\codecs\music_flac.c" />
    8.10      <ClCompile Include="..\..\src\codecs\music_fluidsynth.c" />
    8.11 @@ -79,6 +80,7 @@
    8.12      <ClInclude Include="..\..\src\music.h" />
    8.13      <ClInclude Include="..\..\src\codecs\load_aiff.h" />
    8.14      <ClInclude Include="..\..\src\codecs\load_voc.h" />
    8.15 +    <ClInclude Include="..\..\src\codecs\mp3utils.h" />
    8.16      <ClInclude Include="..\..\src\codecs\music_cmd.h" />
    8.17      <ClInclude Include="..\..\src\codecs\music_flac.h" />
    8.18      <ClInclude Include="..\..\src\codecs\music_fluidsynth.h" />
     9.1 --- a/VisualC-WinRT/WinRT80_VS2012/SDL_mixer-WinRT80.vcxproj.filters	Sun Dec 08 20:10:40 2019 +0300
     9.2 +++ b/VisualC-WinRT/WinRT80_VS2012/SDL_mixer-WinRT80.vcxproj.filters	Tue Dec 10 17:55:03 2019 +0300
     9.3 @@ -8,6 +8,7 @@
     9.4      <ClCompile Include="..\..\src\music.c" />
     9.5      <ClCompile Include="..\..\src\codecs\load_aiff.c" />
     9.6      <ClCompile Include="..\..\src\codecs\load_voc.c" />
     9.7 +    <ClCompile Include="..\..\src\codecs\mp3utils.c" />
     9.8      <ClCompile Include="..\..\src\codecs\music_cmd.c" />
     9.9      <ClCompile Include="..\..\src\codecs\music_flac.c" />
    9.10      <ClCompile Include="..\..\src\codecs\music_fluidsynth.c" />
    9.11 @@ -55,6 +56,7 @@
    9.12      <ClInclude Include="..\..\src\music.h" />
    9.13      <ClInclude Include="..\..\src\codecs\load_aiff.h" />
    9.14      <ClInclude Include="..\..\src\codecs\load_voc.h" />
    9.15 +    <ClInclude Include="..\..\src\codecs\mp3utils.h" />
    9.16      <ClInclude Include="..\..\src\codecs\music_cmd.h" />
    9.17      <ClInclude Include="..\..\src\codecs\music_flac.h" />
    9.18      <ClInclude Include="..\..\src\codecs\music_fluidsynth.h" />
    10.1 --- a/VisualC-WinRT/WinRT81_VS2013/SDL_mixer-WinRT81.vcxproj	Sun Dec 08 20:10:40 2019 +0300
    10.2 +++ b/VisualC-WinRT/WinRT81_VS2013/SDL_mixer-WinRT81.vcxproj	Tue Dec 10 17:55:03 2019 +0300
    10.3 @@ -49,6 +49,7 @@
    10.4      <ClCompile Include="..\..\src\music.c" />
    10.5      <ClCompile Include="..\..\src\codecs\load_aiff.c" />
    10.6      <ClCompile Include="..\..\src\codecs\load_voc.c" />
    10.7 +    <ClCompile Include="..\..\src\codecs\mp3utils.c" />
    10.8      <ClCompile Include="..\..\src\codecs\music_cmd.c" />
    10.9      <ClCompile Include="..\..\src\codecs\music_flac.c" />
   10.10      <ClCompile Include="..\..\src\codecs\music_fluidsynth.c" />
   10.11 @@ -79,6 +80,7 @@
   10.12      <ClInclude Include="..\..\src\music.h" />
   10.13      <ClInclude Include="..\..\src\codecs\load_aiff.h" />
   10.14      <ClInclude Include="..\..\src\codecs\load_voc.h" />
   10.15 +    <ClInclude Include="..\..\src\codecs\mp3utils.h" />
   10.16      <ClInclude Include="..\..\src\codecs\music_cmd.h" />
   10.17      <ClInclude Include="..\..\src\codecs\music_flac.h" />
   10.18      <ClInclude Include="..\..\src\codecs\music_fluidsynth.h" />
    11.1 --- a/VisualC-WinRT/WinRT81_VS2013/SDL_mixer-WinRT81.vcxproj.filters	Sun Dec 08 20:10:40 2019 +0300
    11.2 +++ b/VisualC-WinRT/WinRT81_VS2013/SDL_mixer-WinRT81.vcxproj.filters	Tue Dec 10 17:55:03 2019 +0300
    11.3 @@ -8,6 +8,7 @@
    11.4      <ClCompile Include="..\..\src\music.c" />
    11.5      <ClCompile Include="..\..\src\codecs\load_aiff.c" />
    11.6      <ClCompile Include="..\..\src\codecs\load_voc.c" />
    11.7 +    <ClCompile Include="..\..\src\codecs\mp3utils.c" />
    11.8      <ClCompile Include="..\..\src\codecs\music_cmd.c" />
    11.9      <ClCompile Include="..\..\src\codecs\music_flac.c" />
   11.10      <ClCompile Include="..\..\src\codecs\music_fluidsynth.c" />
   11.11 @@ -55,6 +56,7 @@
   11.12      <ClInclude Include="..\..\src\music.h" />
   11.13      <ClInclude Include="..\..\src\codecs\load_aiff.h" />
   11.14      <ClInclude Include="..\..\src\codecs\load_voc.h" />
   11.15 +    <ClInclude Include="..\..\src\codecs\mp3utils.h" />
   11.16      <ClInclude Include="..\..\src\codecs\music_cmd.h" />
   11.17      <ClInclude Include="..\..\src\codecs\music_flac.h" />
   11.18      <ClInclude Include="..\..\src\codecs\music_fluidsynth.h" />
    12.1 --- a/VisualC/SDL_mixer.vcxproj	Sun Dec 08 20:10:40 2019 +0300
    12.2 +++ b/VisualC/SDL_mixer.vcxproj	Tue Dec 10 17:55:03 2019 +0300
    12.3 @@ -201,6 +201,7 @@
    12.4      <ClInclude Include="..\src\music.h" />
    12.5      <ClInclude Include="..\src\codecs\load_aiff.h" />
    12.6      <ClInclude Include="..\src\codecs\load_voc.h" />
    12.7 +    <ClInclude Include="..\src\codecs\mp3utils.h" />
    12.8      <ClInclude Include="..\src\codecs\music_cmd.h" />
    12.9      <ClInclude Include="..\src\codecs\music_flac.h" />
   12.10      <ClInclude Include="..\src\codecs\music_fluidsynth.h" />
   12.11 @@ -457,6 +458,7 @@
   12.12      <ClCompile Include="..\src\music.c" />
   12.13      <ClCompile Include="..\src\codecs\load_aiff.c" />
   12.14      <ClCompile Include="..\src\codecs\load_voc.c" />
   12.15 +    <ClCompile Include="..\src\codecs\mp3utils.c" />
   12.16      <ClCompile Include="..\src\codecs\music_cmd.c" />
   12.17      <ClCompile Include="..\src\codecs\music_flac.c" />
   12.18      <ClCompile Include="..\src\codecs\music_fluidsynth.c" />
    13.1 --- a/VisualC/SDL_mixer.vcxproj.filters	Sun Dec 08 20:10:40 2019 +0300
    13.2 +++ b/VisualC/SDL_mixer.vcxproj.filters	Tue Dec 10 17:55:03 2019 +0300
    13.3 @@ -22,6 +22,9 @@
    13.4      <ClInclude Include="..\src\codecs\load_voc.h">
    13.5        <Filter>Sources</Filter>
    13.6      </ClInclude>
    13.7 +    <ClInclude Include="..\src\codecs\mp3utils.h">
    13.8 +      <Filter>Sources</Filter>
    13.9 +    </ClInclude>
   13.10      <ClInclude Include="..\src\codecs\music_cmd.h">
   13.11        <Filter>Sources</Filter>
   13.12      </ClInclude>
   13.13 @@ -194,6 +197,9 @@
   13.14      <ClCompile Include="..\src\codecs\load_voc.c">
   13.15        <Filter>Sources</Filter>
   13.16      </ClCompile>
   13.17 +    <ClCompile Include="..\src\codecs\mp3utils.c">
   13.18 +      <Filter>Sources</Filter>
   13.19 +    </ClCompile>
   13.20      <ClCompile Include="..\src\codecs\music_cmd.c">
   13.21        <Filter>Sources</Filter>
   13.22      </ClCompile>
    14.1 --- a/Xcode-iOS/SDL_mixer.xcodeproj/project.pbxproj	Sun Dec 08 20:10:40 2019 +0300
    14.2 +++ b/Xcode-iOS/SDL_mixer.xcodeproj/project.pbxproj	Tue Dec 10 17:55:03 2019 +0300
    14.3 @@ -36,6 +36,10 @@
    14.4  		639008DF2385A84C009019FA /* compat.h in Headers */ = {isa = PBXBuildFile; fileRef = 639008DD2385A84C009019FA /* compat.h */; };
    14.5  		639008E02385A84C009019FA /* compat.c in Sources */ = {isa = PBXBuildFile; fileRef = 639008DC2385A84C009019FA /* compat.c */; };
    14.6  		639008E12385A84C009019FA /* compat.h in Headers */ = {isa = PBXBuildFile; fileRef = 639008DD2385A84C009019FA /* compat.h */; };
    14.7 +		6391980C239FE6AE00F1D8F8 /* mp3utils.c in Sources */ = {isa = PBXBuildFile; fileRef = 6391980A239FE6AE00F1D8F8 /* mp3utils.c */; };
    14.8 +		6391980D239FE6AE00F1D8F8 /* mp3utils.h in Headers */ = {isa = PBXBuildFile; fileRef = 6391980B239FE6AE00F1D8F8 /* mp3utils.h */; };
    14.9 +		6391980E239FE6AE00F1D8F8 /* mp3utils.c in Sources */ = {isa = PBXBuildFile; fileRef = 6391980A239FE6AE00F1D8F8 /* mp3utils.c */; };
   14.10 +		6391980F239FE6AE00F1D8F8 /* mp3utils.h in Headers */ = {isa = PBXBuildFile; fileRef = 6391980B239FE6AE00F1D8F8 /* mp3utils.h */; };
   14.11  		AA1C71151F9BC66000A6BC31 /* effect_position.c in Sources */ = {isa = PBXBuildFile; fileRef = AA1C71131F9BC66000A6BC31 /* effect_position.c */; };
   14.12  		AA1C71161F9BC66000A6BC31 /* effect_stereoreverse.c in Sources */ = {isa = PBXBuildFile; fileRef = AA1C71141F9BC66000A6BC31 /* effect_stereoreverse.c */; };
   14.13  		AA1C71191F9BC67200A6BC31 /* effects_internal.h in Headers */ = {isa = PBXBuildFile; fileRef = AA1C71171F9BC67100A6BC31 /* effects_internal.h */; };
   14.14 @@ -344,6 +348,8 @@
   14.15  		1014BAEA010A4B677F000001 /* SDL_mixer.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = SDL_mixer.h; sourceTree = "<group>"; };
   14.16  		639008DC2385A84C009019FA /* compat.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = compat.c; sourceTree = "<group>"; };
   14.17  		639008DD2385A84C009019FA /* compat.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = compat.h; sourceTree = "<group>"; };
   14.18 +		6391980A239FE6AE00F1D8F8 /* mp3utils.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = mp3utils.c; sourceTree = "<group>"; };
   14.19 +		6391980B239FE6AE00F1D8F8 /* mp3utils.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = mp3utils.h; sourceTree = "<group>"; };
   14.20  		AA1C71131F9BC66000A6BC31 /* effect_position.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = effect_position.c; sourceTree = "<group>"; };
   14.21  		AA1C71141F9BC66000A6BC31 /* effect_stereoreverse.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = effect_stereoreverse.c; sourceTree = "<group>"; };
   14.22  		AA1C71171F9BC67100A6BC31 /* effects_internal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = effects_internal.h; sourceTree = "<group>"; };
   14.23 @@ -596,6 +602,8 @@
   14.24  		63FD69EC23853AB000C3C961 /* codecs */ = {
   14.25  			isa = PBXGroup;
   14.26  			children = (
   14.27 +				6391980A239FE6AE00F1D8F8 /* mp3utils.c */,
   14.28 +				6391980B239FE6AE00F1D8F8 /* mp3utils.h */,
   14.29  				AAE406061F9609B900EDAF53 /* load_aiff.c */,
   14.30  				AAE406181F9609BA00EDAF53 /* load_aiff.h */,
   14.31  				AAE406141F9609BA00EDAF53 /* load_voc.c */,
   14.32 @@ -820,6 +828,7 @@
   14.33  				AA53147E1FE0FE2E0025C9BE /* tables.h in Headers */,
   14.34  				AA53147F1FE0FE2E0025C9BE /* music_wav.h in Headers */,
   14.35  				639008E12385A84C009019FA /* compat.h in Headers */,
   14.36 +				6391980F239FE6AE00F1D8F8 /* mp3utils.h in Headers */,
   14.37  			);
   14.38  			runOnlyForDeploymentPostprocessing = 0;
   14.39  		};
   14.40 @@ -873,6 +882,7 @@
   14.41  				AA60219617653A9800662B9C /* tables.h in Headers */,
   14.42  				AAE406301F9609BD00EDAF53 /* music_wav.h in Headers */,
   14.43  				639008DF2385A84C009019FA /* compat.h in Headers */,
   14.44 +				6391980D239FE6AE00F1D8F8 /* mp3utils.h in Headers */,
   14.45  			);
   14.46  			runOnlyForDeploymentPostprocessing = 0;
   14.47  		};
   14.48 @@ -1120,6 +1130,7 @@
   14.49  				AA5314EA1FE0FE2E0025C9BE /* sndfile.cpp in Sources */,
   14.50  				AA5314EB1FE0FE2E0025C9BE /* sndmix.cpp in Sources */,
   14.51  				639008E02385A84C009019FA /* compat.c in Sources */,
   14.52 +				6391980E239FE6AE00F1D8F8 /* mp3utils.c in Sources */,
   14.53  			);
   14.54  			runOnlyForDeploymentPostprocessing = 0;
   14.55  		};
   14.56 @@ -1234,6 +1245,7 @@
   14.57  				AA60219417653A9800662B9C /* sndfile.cpp in Sources */,
   14.58  				AA60219517653A9800662B9C /* sndmix.cpp in Sources */,
   14.59  				639008DE2385A84C009019FA /* compat.c in Sources */,
   14.60 +				6391980C239FE6AE00F1D8F8 /* mp3utils.c in Sources */,
   14.61  			);
   14.62  			runOnlyForDeploymentPostprocessing = 0;
   14.63  		};
    15.1 --- a/Xcode/SDL_mixer.xcodeproj/project.pbxproj	Sun Dec 08 20:10:40 2019 +0300
    15.2 +++ b/Xcode/SDL_mixer.xcodeproj/project.pbxproj	Tue Dec 10 17:55:03 2019 +0300
    15.3 @@ -13,6 +13,8 @@
    15.4  		630FBD8520D5211F009867AB /* music_opus.h in Headers */ = {isa = PBXBuildFile; fileRef = 630FBD8420D5211F009867AB /* music_opus.h */; };
    15.5  		639008C82385A822009019FA /* compat.c in Sources */ = {isa = PBXBuildFile; fileRef = 639008C62385A822009019FA /* compat.c */; };
    15.6  		639008C92385A822009019FA /* compat.h in Headers */ = {isa = PBXBuildFile; fileRef = 639008C72385A822009019FA /* compat.h */; };
    15.7 +		639197F1239FE66700F1D8F8 /* mp3utils.c in Sources */ = {isa = PBXBuildFile; fileRef = 639197EF239FE66700F1D8F8 /* mp3utils.c */; };
    15.8 +		639197F2239FE66700F1D8F8 /* mp3utils.h in Headers */ = {isa = PBXBuildFile; fileRef = 639197F0239FE66700F1D8F8 /* mp3utils.h */; };
    15.9  		63CD6ADC20D52DE20096FB34 /* Opus.framework in Copy Frameworks */ = {isa = PBXBuildFile; fileRef = 630FBD7620D52063009867AB /* Opus.framework */; };
   15.10  		63CD6ADD20D52DE90096FB34 /* OpusFile.framework in Copy Frameworks */ = {isa = PBXBuildFile; fileRef = 630FBD7C20D5206E009867AB /* OpusFile.framework */; };
   15.11  		AA6021301765383B00662B9C /* modplug.framework in Copy Frameworks */ = {isa = PBXBuildFile; fileRef = AA60212F1765382200662B9C /* modplug.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; };
   15.12 @@ -119,6 +121,8 @@
   15.13  		630FBD8420D5211F009867AB /* music_opus.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = music_opus.h; sourceTree = "<group>"; };
   15.14  		639008C62385A822009019FA /* compat.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = compat.c; sourceTree = "<group>"; };
   15.15  		639008C72385A822009019FA /* compat.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = compat.h; sourceTree = "<group>"; };
   15.16 +		639197EF239FE66700F1D8F8 /* mp3utils.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = mp3utils.c; sourceTree = "<group>"; };
   15.17 +		639197F0239FE66700F1D8F8 /* mp3utils.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = mp3utils.h; sourceTree = "<group>"; };
   15.18  		AA60212F1765382200662B9C /* modplug.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = modplug.framework; path = Frameworks/modplug.framework; sourceTree = "<group>"; };
   15.19  		AA64428E175AA7A500A2125A /* mpg123.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = mpg123.framework; path = Frameworks/mpg123.framework; sourceTree = "<group>"; };
   15.20  		AA6442D0175B181300A2125A /* AudioToolbox.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AudioToolbox.framework; path = System/Library/Frameworks/AudioToolbox.framework; sourceTree = SDKROOT; };
   15.21 @@ -294,6 +298,8 @@
   15.22  		6398B0BB238528360024EEA1 /* codecs */ = {
   15.23  			isa = PBXGroup;
   15.24  			children = (
   15.25 +				639197EF239FE66700F1D8F8 /* mp3utils.c */,
   15.26 +				639197F0239FE66700F1D8F8 /* mp3utils.h */,
   15.27  				AAE405DE1F9607C300EDAF53 /* music_cmd.c */,
   15.28  				AAE405DB1F9607C200EDAF53 /* music_cmd.h */,
   15.29  				AAE405D41F9607C100EDAF53 /* music_flac.c */,
   15.30 @@ -435,6 +441,7 @@
   15.31  				AAE405F51F9607C300EDAF53 /* music_ogg.h in Headers */,
   15.32  				630FBD8520D5211F009867AB /* music_opus.h in Headers */,
   15.33  				639008C92385A822009019FA /* compat.h in Headers */,
   15.34 +				639197F2239FE66700F1D8F8 /* mp3utils.h in Headers */,
   15.35  			);
   15.36  			runOnlyForDeploymentPostprocessing = 0;
   15.37  		};
   15.38 @@ -638,6 +645,7 @@
   15.39  				0448E8AE108B937A00C9D3EA /* native_midi_macosx.c in Sources */,
   15.40  				630FBD8320D52105009867AB /* music_opus.c in Sources */,
   15.41  				639008C82385A822009019FA /* compat.c in Sources */,
   15.42 +				639197F1239FE66700F1D8F8 /* mp3utils.c in Sources */,
   15.43  			);
   15.44  			runOnlyForDeploymentPostprocessing = 0;
   15.45  		};
    16.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    16.2 +++ b/src/codecs/mp3utils.c	Tue Dec 10 17:55:03 2019 +0300
    16.3 @@ -0,0 +1,255 @@
    16.4 +/*
    16.5 +  SDL_mixer:  An audio mixer library based on the SDL library
    16.6 +  Copyright (C) 1997-2019 Sam Lantinga <slouken@libsdl.org>
    16.7 +
    16.8 +  This software is provided 'as-is', without any express or implied
    16.9 +  warranty.  In no event will the authors be held liable for any damages
   16.10 +  arising from the use of this software.
   16.11 +
   16.12 +  Permission is granted to anyone to use this software for any purpose,
   16.13 +  including commercial applications, and to alter it and redistribute it
   16.14 +  freely, subject to the following restrictions:
   16.15 +
   16.16 +  1. The origin of this software must not be misrepresented; you must not
   16.17 +     claim that you wrote the original software. If you use this software
   16.18 +     in a product, an acknowledgment in the product documentation would be
   16.19 +     appreciated but is not required.
   16.20 +  2. Altered source versions must be plainly marked as such, and must not be
   16.21 +     misrepresented as being the original software.
   16.22 +  3. This notice may not be removed or altered from any source distribution.
   16.23 +*/
   16.24 +
   16.25 +#include "SDL_stdinc.h"
   16.26 +#include "SDL_rwops.h"
   16.27 +
   16.28 +#include "mp3utils.h"
   16.29 +
   16.30 +#if defined(MUSIC_MP3_MAD) /*|| defined(MUSIC_MP3_MPG123)*/
   16.31 +
   16.32 +/*********************** SDL_RW WITH BOOKKEEPING ************************/
   16.33 +
   16.34 +size_t MP3_RWread(struct mp3file_t *fil, void *ptr, size_t size, size_t maxnum) {
   16.35 +    size_t remaining = (size_t)(fil->length - fil->pos);
   16.36 +    size_t ret;
   16.37 +    maxnum *= size;
   16.38 +    if (maxnum > remaining) maxnum = remaining;
   16.39 +    ret = SDL_RWread(fil->src, ptr, 1, maxnum);
   16.40 +    fil->pos += (Sint64)ret;
   16.41 +    return ret;
   16.42 +}
   16.43 +
   16.44 +Sint64 MP3_RWseek(struct mp3file_t *fil, Sint64 offset, int whence) {
   16.45 +    Sint64 ret;
   16.46 +    switch (whence) { /* assumes a legal whence value */
   16.47 +    case RW_SEEK_CUR:
   16.48 +        offset += fil->pos;
   16.49 +        break;
   16.50 +    case RW_SEEK_END:
   16.51 +        offset = fil->length + offset;
   16.52 +        break;
   16.53 +    }
   16.54 +    if (offset < 0) return -1;
   16.55 +    if (offset > fil->length)
   16.56 +        offset = fil->length;
   16.57 +    ret = SDL_RWseek(fil->src, fil->start + offset, RW_SEEK_SET);
   16.58 +    if (ret < 0) return ret;
   16.59 +    fil->pos = offset;
   16.60 +    return (fil->pos - fil->start);
   16.61 +}
   16.62 +
   16.63 +
   16.64 +/*************************** TAG HANDLING: ******************************/
   16.65 +
   16.66 +static SDL_INLINE SDL_bool is_id3v1(const unsigned char *data, size_t length)
   16.67 +{
   16.68 +    /* http://id3.org/ID3v1 :  3 bytes "TAG" identifier and 125 bytes tag data */
   16.69 +    if (length < 3 || SDL_memcmp(data,"TAG",3) != 0) {
   16.70 +        return SDL_FALSE;
   16.71 +    }
   16.72 +    return SDL_TRUE;
   16.73 +}
   16.74 +static SDL_INLINE SDL_bool is_id3v2(const unsigned char *data, size_t length)
   16.75 +{
   16.76 +    /* ID3v2 header is 10 bytes:  http://id3.org/id3v2.4.0-structure */
   16.77 +    /* bytes 0-2: "ID3" identifier */
   16.78 +    if (length < 10 || SDL_memcmp(data,"ID3",3) != 0) {
   16.79 +        return SDL_FALSE;
   16.80 +    }
   16.81 +    /* bytes 3-4: version num (major,revision), each byte always less than 0xff. */
   16.82 +    if (data[3] == 0xff || data[4] == 0xff) {
   16.83 +        return SDL_FALSE;
   16.84 +    }
   16.85 +    /* bytes 6-9 are the ID3v2 tag size: a 32 bit 'synchsafe' integer, i.e. the
   16.86 +     * highest bit 7 in each byte zeroed.  i.e.: 7 bit information in each byte ->
   16.87 +     * effectively a 28 bit value.  */
   16.88 +    if (data[6] >= 0x80 || data[7] >= 0x80 || data[8] >= 0x80 || data[9] >= 0x80) {
   16.89 +        return SDL_FALSE;
   16.90 +    }
   16.91 +    return SDL_TRUE;
   16.92 +}
   16.93 +static SDL_INLINE long get_id3v2_len(const unsigned char *data, long length)
   16.94 +{
   16.95 +    /* size is a 'synchsafe' integer (see above) */
   16.96 +    long size = (long)((data[6]<<21) + (data[7]<<14) + (data[8]<<7) + data[9]);
   16.97 +    size += 10; /* header size */
   16.98 +    /* ID3v2 header[5] is flags (bits 4-7 only, 0-3 are zero).
   16.99 +     * bit 4 set: footer is present (a copy of the header but
  16.100 +     * with "3DI" as ident.)  */
  16.101 +    if (data[5] & 0x10) {
  16.102 +        size += 10; /* footer size */
  16.103 +    }
  16.104 +    /* optional padding (always zeroes) */
  16.105 +    while (size < length && data[size] == 0) {
  16.106 +        ++size;
  16.107 +    }
  16.108 +    return size;
  16.109 +}
  16.110 +static SDL_INLINE SDL_bool is_apetag(const unsigned char *data, size_t length)
  16.111 +{
  16.112 +   /* http://wiki.hydrogenaud.io/index.php?title=APEv2_specification
  16.113 +    * Header/footer is 32 bytes: bytes 0-7 ident, bytes 8-11 version,
  16.114 +    * bytes 12-17 size. bytes 24-31 are reserved: must be all zeroes. */
  16.115 +    Uint32 v;
  16.116 +
  16.117 +    if (length < 32 || SDL_memcmp(data,"APETAGEX",8) != 0) {
  16.118 +        return SDL_FALSE;
  16.119 +    }
  16.120 +    v = (Uint32)((data[11]<<24) | (data[10]<<16) | (data[9]<<8) | data[8]); /* version */
  16.121 +    if (v != 2000U && v != 1000U) {
  16.122 +        return SDL_FALSE;
  16.123 +    }
  16.124 +    v = 0; /* reserved bits : */
  16.125 +    if (SDL_memcmp(&data[24],&v,4) != 0 || SDL_memcmp(&data[28],&v,4) != 0) {
  16.126 +        return SDL_FALSE;
  16.127 +    }
  16.128 +    return SDL_TRUE;
  16.129 +}
  16.130 +static SDL_INLINE long get_ape_len(const unsigned char *data)
  16.131 +{
  16.132 +    Uint32 flags, version;
  16.133 +    long size = (long)((data[15]<<24) | (data[14]<<16) | (data[13]<<8) | data[12]);
  16.134 +    version = (Uint32)((data[11]<<24) | (data[10]<<16) | (data[9]<<8) | data[8]);
  16.135 +    flags = (Uint32)((data[23]<<24) | (data[22]<<16) | (data[21]<<8) | data[20]);
  16.136 +    if (version == 2000U && (flags & (1U<<31))) size += 32; /* header present. */
  16.137 +    return size;
  16.138 +}
  16.139 +static SDL_INLINE int is_lyrics3tag(const unsigned char *data, long length) {
  16.140 +    /* http://id3.org/Lyrics3
  16.141 +     * http://id3.org/Lyrics3v2 */
  16.142 +    if (length < 15) return 0;
  16.143 +    if (SDL_memcmp(data+6,"LYRICS200",9) == 0) return 2; /* v2 */
  16.144 +    if (SDL_memcmp(data+6,"LYRICSEND",9) == 0) return 1; /* v1 */
  16.145 +    return 0;
  16.146 +}
  16.147 +static SDL_INLINE long get_lyrics3v1_len(struct mp3file_t *m) {
  16.148 +    const char *p; long i, len;
  16.149 +    char buf[5104];
  16.150 +    /* needs manual search:  http://id3.org/Lyrics3 */
  16.151 +    if (m->length < 20) return -1;
  16.152 +    len = (m->length > 5109)? 5109 : (long)m->length;
  16.153 +    MP3_RWseek(m, -len, RW_SEEK_END);
  16.154 +    MP3_RWread(m, buf, 1, (len -= 9)); /* exclude footer */
  16.155 +    MP3_RWseek(m, 0, RW_SEEK_SET);
  16.156 +    /* strstr() won't work here. */
  16.157 +    for (i = len - 11, p = buf; i >= 0; --i, ++p) {
  16.158 +        if (SDL_memcmp(p, "LYRICSBEGIN", 11) == 0)
  16.159 +            break;
  16.160 +    }
  16.161 +    if (i < 0) return -1;
  16.162 +    return len - (long)(p - buf) + 9 /* footer */;
  16.163 +}
  16.164 +static SDL_INLINE long get_lyrics3v2_len(const unsigned char *data, long length) {
  16.165 +    /* 6 bytes before the end marker is size in decimal format -
  16.166 +     * does not include the 9 bytes end marker and size field. */
  16.167 +    if (length != 6) return 0;
  16.168 +    return SDL_strtol((const char *)data, NULL, 10) + 15;
  16.169 +}
  16.170 +static SDL_INLINE SDL_bool verify_lyrics3v2(const unsigned char *data, long length) {
  16.171 +    if (length < 11) return SDL_FALSE;
  16.172 +    if (SDL_memcmp(data,"LYRICSBEGIN",11) == 0) return SDL_TRUE;
  16.173 +    return SDL_FALSE;
  16.174 +}
  16.175 +
  16.176 +int mp3_skiptags(struct mp3file_t *fil)
  16.177 +{
  16.178 +    unsigned char buf[128];
  16.179 +    long len; size_t readsize;
  16.180 +
  16.181 +    readsize = MP3_RWread(fil, buf, 1, 128);
  16.182 +    if (!readsize) return -1;
  16.183 +
  16.184 +    /* ID3v2 tag is at the start */
  16.185 +    if (is_id3v2(buf, readsize)) {
  16.186 +        len = get_id3v2_len(buf, (long)readsize);
  16.187 +        if (len >= fil->length) return -1;
  16.188 +        fil->start += len;
  16.189 +        fil->length -= len;
  16.190 +        MP3_RWseek(fil, 0, RW_SEEK_SET);
  16.191 +    }
  16.192 +    /* APE tag _might_ be at the start (discouraged
  16.193 +     * but not forbidden, either.)  read the header. */
  16.194 +    else if (is_apetag(buf, readsize)) {
  16.195 +        len = get_ape_len(buf);
  16.196 +        if (len >= fil->length) return -1;
  16.197 +        fil->start += len;
  16.198 +        fil->length -= len;
  16.199 +        MP3_RWseek(fil, 0, RW_SEEK_SET);
  16.200 +    }
  16.201 +
  16.202 +    /* ID3v1 tag is at the end */
  16.203 +    if (fil->length < 128) goto ape;
  16.204 +    MP3_RWseek(fil, -128, RW_SEEK_END);
  16.205 +    readsize = MP3_RWread(fil, buf, 1, 128);
  16.206 +    MP3_RWseek(fil, 0, RW_SEEK_SET);
  16.207 +    if (readsize != 128) return -1;
  16.208 +    if (is_id3v1(buf, 128)) {
  16.209 +        fil->length -= 128;
  16.210 +
  16.211 +        /* FIXME: handle possible double-ID3v1 tags?? */
  16.212 +    }
  16.213 +
  16.214 +    /* do we know whether ape or lyrics3 is the first?
  16.215 +     * well, we don't: we need to handle that later... */
  16.216 +
  16.217 +    ape: /* APE tag may be at the end: read the footer */
  16.218 +    if (fil->length >= 32) {
  16.219 +        MP3_RWseek(fil, -32, RW_SEEK_END);
  16.220 +        readsize = MP3_RWread(fil, buf, 1, 32);
  16.221 +        MP3_RWseek(fil, 0, RW_SEEK_SET);
  16.222 +        if (readsize != 32) return -1;
  16.223 +        if (is_apetag(buf, 32)) {
  16.224 +            len = get_ape_len(buf);
  16.225 +            if (len >= fil->length) return -1;
  16.226 +            fil->length -= len;
  16.227 +        }
  16.228 +    }
  16.229 +
  16.230 +    if (fil->length >= 15) {
  16.231 +        MP3_RWseek(fil, -15, RW_SEEK_END);
  16.232 +        readsize = MP3_RWread(fil, buf, 1, 15);
  16.233 +        MP3_RWseek(fil, 0, RW_SEEK_SET);
  16.234 +        if (readsize != 15) return -1;
  16.235 +        len = is_lyrics3tag(buf, 15);
  16.236 +        if (len == 2) {
  16.237 +            len = get_lyrics3v2_len(buf, 6);
  16.238 +            if (len >= fil->length) return -1;
  16.239 +            if (len < 15) return -1;
  16.240 +            MP3_RWseek(fil, -len, RW_SEEK_END);
  16.241 +            readsize = MP3_RWread(fil, buf, 1, 11);
  16.242 +            MP3_RWseek(fil, 0, RW_SEEK_SET);
  16.243 +            if (readsize != 11) return -1;
  16.244 +            if (!verify_lyrics3v2(buf, 11)) return -1;
  16.245 +            fil->length -= len;
  16.246 +        }
  16.247 +        else if (len == 1) {
  16.248 +            len = get_lyrics3v1_len(fil);
  16.249 +            if (len < 0) return -1;
  16.250 +            fil->length -= len;
  16.251 +        }
  16.252 +    }
  16.253 +
  16.254 +    return (fil->length > 0)? 0: -1;
  16.255 +}
  16.256 +#endif /* MUSIC_MP3_????? */
  16.257 +
  16.258 +/* vi: set ts=4 sw=4 expandtab: */
    17.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    17.2 +++ b/src/codecs/mp3utils.h	Tue Dec 10 17:55:03 2019 +0300
    17.3 @@ -0,0 +1,36 @@
    17.4 +/*
    17.5 +  SDL_mixer:  An audio mixer library based on the SDL library
    17.6 +  Copyright (C) 1997-2019 Sam Lantinga <slouken@libsdl.org>
    17.7 +
    17.8 +  This software is provided 'as-is', without any express or implied
    17.9 +  warranty.  In no event will the authors be held liable for any damages
   17.10 +  arising from the use of this software.
   17.11 +
   17.12 +  Permission is granted to anyone to use this software for any purpose,
   17.13 +  including commercial applications, and to alter it and redistribute it
   17.14 +  freely, subject to the following restrictions:
   17.15 +
   17.16 +  1. The origin of this software must not be misrepresented; you must not
   17.17 +     claim that you wrote the original software. If you use this software
   17.18 +     in a product, an acknowledgment in the product documentation would be
   17.19 +     appreciated but is not required.
   17.20 +  2. Altered source versions must be plainly marked as such, and must not be
   17.21 +     misrepresented as being the original software.
   17.22 +  3. This notice may not be removed or altered from any source distribution.
   17.23 +*/
   17.24 +
   17.25 +#ifndef MIX_MP3UTILS_H
   17.26 +#define MIX_MP3UTILS_H
   17.27 +
   17.28 +struct mp3file_t {
   17.29 +    SDL_RWops *src;
   17.30 +    Sint64 start, length, pos;
   17.31 +};
   17.32 +
   17.33 +extern int  mp3_skiptags(struct mp3file_t *fil);
   17.34 +extern size_t MP3_RWread(struct mp3file_t *fil, void *ptr, size_t size, size_t maxnum);
   17.35 +extern Sint64 MP3_RWseek(struct mp3file_t *fil, Sint64 offset, int whence);
   17.36 +
   17.37 +#endif /* MIX_MP3UTILS_H */
   17.38 +
   17.39 +/* vi: set ts=4 sw=4 expandtab: */
    18.1 --- a/src/codecs/music_mad.c	Sun Dec 08 20:10:40 2019 +0300
    18.2 +++ b/src/codecs/music_mad.c	Tue Dec 10 17:55:03 2019 +0300
    18.3 @@ -22,6 +22,7 @@
    18.4  #ifdef MUSIC_MP3_MAD
    18.5  
    18.6  #include "music_mad.h"
    18.7 +#include "mp3utils.h"
    18.8  
    18.9  #include "mad.h"
   18.10  
   18.11 @@ -136,9 +137,8 @@
   18.12  };
   18.13  
   18.14  typedef struct {
   18.15 +    struct mp3file_t mp3file;
   18.16      int play_count;
   18.17 -    SDL_RWops *src;
   18.18 -    Sint64 start, length, pos;
   18.19      int freesrc;
   18.20      struct mad_stream stream;
   18.21      struct mad_frame frame;
   18.22 @@ -152,38 +152,7 @@
   18.23  } MAD_Music;
   18.24  
   18.25  
   18.26 -static size_t MAD_RWread(MAD_Music *music, void *ptr, size_t size, size_t maxnum) {
   18.27 -    size_t remaining = (size_t)(music->length - music->pos);
   18.28 -    size_t ret;
   18.29 -    maxnum *= size;
   18.30 -    if (maxnum > remaining) maxnum = remaining;
   18.31 -    ret = SDL_RWread(music->src, ptr, 1, maxnum);
   18.32 -    music->pos += (Sint64)ret;
   18.33 -    return ret;
   18.34 -}
   18.35 -
   18.36 -static Sint64 MAD_RWseek(MAD_Music *music, Sint64 offset, int whence) {
   18.37 -    Sint64 ret;
   18.38 -    switch (whence) { /* assumes a legal whence value */
   18.39 -    case RW_SEEK_CUR:
   18.40 -        offset += music->pos;
   18.41 -        break;
   18.42 -    case RW_SEEK_END:
   18.43 -        offset = music->length + offset;
   18.44 -        break;
   18.45 -    }
   18.46 -    if (offset < 0) return -1;
   18.47 -    if (offset > music->length)
   18.48 -        offset = music->length;
   18.49 -    ret = SDL_RWseek(music->src, music->start + offset, RW_SEEK_SET);
   18.50 -    if (ret < 0) return ret;
   18.51 -    music->pos = offset;
   18.52 -    return (music->pos - music->start);
   18.53 -}
   18.54 -
   18.55 -
   18.56  static int MAD_Seek(void *context, double position);
   18.57 -static int skip_tags(MAD_Music *music);
   18.58  
   18.59  static void *MAD_CreateFromRW(SDL_RWops *src, int freesrc)
   18.60  {
   18.61 @@ -194,11 +163,11 @@
   18.62          SDL_OutOfMemory();
   18.63          return NULL;
   18.64      }
   18.65 -    music->src = src;
   18.66 +    music->mp3file.src = src;
   18.67      music->volume = MIX_MAX_VOLUME;
   18.68  
   18.69 -    music->length = SDL_RWsize(src);
   18.70 -    if (skip_tags(music) < 0) {
   18.71 +    music->mp3file.length = SDL_RWsize(src);
   18.72 +    if (mp3_skiptags(&music->mp3file) < 0) {
   18.73          SDL_free(music);
   18.74          Mix_SetError("music_mad: corrupt mp3 file.");
   18.75          return NULL;
   18.76 @@ -228,198 +197,6 @@
   18.77  }
   18.78  
   18.79  
   18.80 -/*************************** TAG HANDLING: ******************************/
   18.81 -
   18.82 -static SDL_INLINE SDL_bool is_id3v1(const unsigned char *data, size_t length)
   18.83 -{
   18.84 -    /* http://id3.org/ID3v1 :  3 bytes "TAG" identifier and 125 bytes tag data */
   18.85 -    if (length < 3 || SDL_memcmp(data,"TAG",3) != 0) {
   18.86 -        return SDL_FALSE;
   18.87 -    }
   18.88 -    return SDL_TRUE;
   18.89 -}
   18.90 -static SDL_INLINE SDL_bool is_id3v2(const unsigned char *data, size_t length)
   18.91 -{
   18.92 -    /* ID3v2 header is 10 bytes:  http://id3.org/id3v2.4.0-structure */
   18.93 -    /* bytes 0-2: "ID3" identifier */
   18.94 -    if (length < 10 || SDL_memcmp(data,"ID3",3) != 0) {
   18.95 -        return SDL_FALSE;
   18.96 -    }
   18.97 -    /* bytes 3-4: version num (major,revision), each byte always less than 0xff. */
   18.98 -    if (data[3] == 0xff || data[4] == 0xff) {
   18.99 -        return SDL_FALSE;
  18.100 -    }
  18.101 -    /* bytes 6-9 are the ID3v2 tag size: a 32 bit 'synchsafe' integer, i.e. the
  18.102 -     * highest bit 7 in each byte zeroed.  i.e.: 7 bit information in each byte ->
  18.103 -     * effectively a 28 bit value.  */
  18.104 -    if (data[6] >= 0x80 || data[7] >= 0x80 || data[8] >= 0x80 || data[9] >= 0x80) {
  18.105 -        return SDL_FALSE;
  18.106 -    }
  18.107 -    return SDL_TRUE;
  18.108 -}
  18.109 -static SDL_INLINE long get_id3v2_len(const unsigned char *data, long length)
  18.110 -{
  18.111 -    /* size is a 'synchsafe' integer (see above) */
  18.112 -    long size = (long)((data[6]<<21) + (data[7]<<14) + (data[8]<<7) + data[9]);
  18.113 -    size += 10; /* header size */
  18.114 -    /* ID3v2 header[5] is flags (bits 4-7 only, 0-3 are zero).
  18.115 -     * bit 4 set: footer is present (a copy of the header but
  18.116 -     * with "3DI" as ident.)  */
  18.117 -    if (data[5] & 0x10) {
  18.118 -        size += 10; /* footer size */
  18.119 -    }
  18.120 -    /* optional padding (always zeroes) */
  18.121 -    while (size < length && data[size] == 0) {
  18.122 -        ++size;
  18.123 -    }
  18.124 -    return size;
  18.125 -}
  18.126 -static SDL_INLINE SDL_bool is_apetag(const unsigned char *data, size_t length)
  18.127 -{
  18.128 -   /* http://wiki.hydrogenaud.io/index.php?title=APEv2_specification
  18.129 -    * Header/footer is 32 bytes: bytes 0-7 ident, bytes 8-11 version,
  18.130 -    * bytes 12-17 size. bytes 24-31 are reserved: must be all zeroes. */
  18.131 -    Uint32 v;
  18.132 -
  18.133 -    if (length < 32 || SDL_memcmp(data,"APETAGEX",8) != 0) {
  18.134 -        return SDL_FALSE;
  18.135 -    }
  18.136 -    v = (Uint32)((data[11]<<24) | (data[10]<<16) | (data[9]<<8) | data[8]); /* version */
  18.137 -    if (v != 2000U && v != 1000U) {
  18.138 -        return SDL_FALSE;
  18.139 -    }
  18.140 -    v = 0; /* reserved bits : */
  18.141 -    if (SDL_memcmp(&data[24],&v,4) != 0 || SDL_memcmp(&data[28],&v,4) != 0) {
  18.142 -        return SDL_FALSE;
  18.143 -    }
  18.144 -    return SDL_TRUE;
  18.145 -}
  18.146 -static SDL_INLINE long get_ape_len(const unsigned char *data)
  18.147 -{
  18.148 -    Uint32 flags, version;
  18.149 -    long size = (long)((data[15]<<24) | (data[14]<<16) | (data[13]<<8) | data[12]);
  18.150 -    version = (Uint32)((data[11]<<24) | (data[10]<<16) | (data[9]<<8) | data[8]);
  18.151 -    flags = (Uint32)((data[23]<<24) | (data[22]<<16) | (data[21]<<8) | data[20]);
  18.152 -    if (version == 2000U && (flags & (1U<<31))) size += 32; /* header present. */
  18.153 -    return size;
  18.154 -}
  18.155 -static SDL_INLINE int is_lyrics3tag(const unsigned char *data, long length) {
  18.156 -    /* http://id3.org/Lyrics3
  18.157 -     * http://id3.org/Lyrics3v2 */
  18.158 -    if (length < 15) return 0;
  18.159 -    if (SDL_memcmp(data+6,"LYRICS200",9) == 0) return 2; /* v2 */
  18.160 -    if (SDL_memcmp(data+6,"LYRICSEND",9) == 0) return 1; /* v1 */
  18.161 -    return 0;
  18.162 -}
  18.163 -static SDL_INLINE long get_lyrics3v1_len(MAD_Music *m) {
  18.164 -    const char *p; long i, len;
  18.165 -    /* needs manual search:  http://id3.org/Lyrics3 */
  18.166 -    /* this relies on the input_buffer size >= 5100 */
  18.167 -    if (m->length < 20) return -1;
  18.168 -    len = (m->length > 5109)? 5109 : (long)m->length;
  18.169 -    MAD_RWseek(m, -len, RW_SEEK_END);
  18.170 -    MAD_RWread(m, m->input_buffer, 1, (len -= 9)); /* exclude footer */
  18.171 -    MAD_RWseek(m, 0, RW_SEEK_SET);
  18.172 -    /* strstr() won't work here. */
  18.173 -    for (i = len - 11, p = (const char*)m->input_buffer; i >= 0; --i, ++p) {
  18.174 -        if (SDL_memcmp(p, "LYRICSBEGIN", 11) == 0)
  18.175 -            break;
  18.176 -    }
  18.177 -    if (i < 0) return -1;
  18.178 -    return len - (long)(p - (const char*)m->input_buffer) + 9 /* footer */;
  18.179 -}
  18.180 -static SDL_INLINE long get_lyrics3v2_len(const unsigned char *data, long length) {
  18.181 -    /* 6 bytes before the end marker is size in decimal format -
  18.182 -     * does not include the 9 bytes end marker and size field. */
  18.183 -    if (length != 6) return 0;
  18.184 -    return SDL_strtol((const char *)data, NULL, 10) + 15;
  18.185 -}
  18.186 -static SDL_INLINE SDL_bool verify_lyrics3v2(const unsigned char *data, long length) {
  18.187 -    if (length < 11) return SDL_FALSE;
  18.188 -    if (SDL_memcmp(data,"LYRICSBEGIN",11) == 0) return SDL_TRUE;
  18.189 -    return SDL_FALSE;
  18.190 -}
  18.191 -
  18.192 -static int skip_tags(MAD_Music *music)
  18.193 -{
  18.194 -    long len; size_t readsize;
  18.195 -
  18.196 -    readsize = MAD_RWread(music, music->input_buffer, 1, MAD_INPUT_BUFFER_SIZE);
  18.197 -    if (!readsize) return -1;
  18.198 -
  18.199 -    /* ID3v2 tag is at the start */
  18.200 -    if (is_id3v2(music->input_buffer, readsize)) {
  18.201 -        len = get_id3v2_len(music->input_buffer, (long)readsize);
  18.202 -        if (len >= music->length) return -1;
  18.203 -        music->start += len;
  18.204 -        music->length -= len;
  18.205 -        MAD_RWseek(music, 0, RW_SEEK_SET);
  18.206 -    }
  18.207 -    /* APE tag _might_ be at the start (discouraged
  18.208 -     * but not forbidden, either.)  read the header. */
  18.209 -    else if (is_apetag(music->input_buffer, readsize)) {
  18.210 -        len = get_ape_len(music->input_buffer);
  18.211 -        if (len >= music->length) return -1;
  18.212 -        music->start += len;
  18.213 -        music->length -= len;
  18.214 -        MAD_RWseek(music, 0, RW_SEEK_SET);
  18.215 -    }
  18.216 -
  18.217 -    /* ID3v1 tag is at the end */
  18.218 -    if (music->length < 128) goto ape;
  18.219 -    MAD_RWseek(music, -128, RW_SEEK_END);
  18.220 -    readsize = MAD_RWread(music, music->input_buffer, 1, 128);
  18.221 -    MAD_RWseek(music, 0, RW_SEEK_SET);
  18.222 -    if (readsize != 128) return -1;
  18.223 -    if (is_id3v1(music->input_buffer, 128)) {
  18.224 -        music->length -= 128;
  18.225 -
  18.226 -        /* FIXME: handle possible double-ID3v1 tags?? */
  18.227 -    }
  18.228 -
  18.229 -    /* do we know whether ape or lyrics3 is the first?
  18.230 -     * well, we don't: we need to handle that later... */
  18.231 -
  18.232 -    ape: /* APE tag may be at the end: read the footer */
  18.233 -    if (music->length >= 32) {
  18.234 -        MAD_RWseek(music, -32, RW_SEEK_END);
  18.235 -        readsize = MAD_RWread(music, music->input_buffer, 1, 32);
  18.236 -        MAD_RWseek(music, 0, RW_SEEK_SET);
  18.237 -        if (readsize != 32) return -1;
  18.238 -        if (is_apetag(music->input_buffer, 32)) {
  18.239 -            len = get_ape_len(music->input_buffer);
  18.240 -            if (len >= music->length) return -1;
  18.241 -            music->length -= len;
  18.242 -        }
  18.243 -    }
  18.244 -
  18.245 -    if (music->length >= 15) {
  18.246 -        MAD_RWseek(music, -15, RW_SEEK_END);
  18.247 -        readsize = MAD_RWread(music, music->input_buffer, 1, 15);
  18.248 -        MAD_RWseek(music, 0, RW_SEEK_SET);
  18.249 -        if (readsize != 15) return -1;
  18.250 -        len = is_lyrics3tag(music->input_buffer, 15);
  18.251 -        if (len == 2) {
  18.252 -            len = get_lyrics3v2_len(music->input_buffer, 6);
  18.253 -            if (len >= music->length) return -1;
  18.254 -            if (len < 15) return -1;
  18.255 -            MAD_RWseek(music, -len, RW_SEEK_END);
  18.256 -            readsize = MAD_RWread(music, music->input_buffer, 1, 11);
  18.257 -            MAD_RWseek(music, 0, RW_SEEK_SET);
  18.258 -            if (readsize != 11) return -1;
  18.259 -            if (!verify_lyrics3v2(music->input_buffer, 11)) return -1;
  18.260 -            music->length -= len;
  18.261 -        }
  18.262 -        else if (len == 1) {
  18.263 -            len = get_lyrics3v1_len(music);
  18.264 -            if (len < 0) return -1;
  18.265 -            music->length -= len;
  18.266 -        }
  18.267 -    }
  18.268 -
  18.269 -    return (music->length > 0)? 0: -1;
  18.270 -}
  18.271 -
  18.272  /* Reads the next frame from the file.
  18.273     Returns true on success or false on failure.
  18.274   */
  18.275 @@ -447,7 +224,7 @@
  18.276          }
  18.277  
  18.278          /* Now read additional bytes from the input file. */
  18.279 -        read_size = MAD_RWread(music, read_start, 1, read_size);
  18.280 +        read_size = MP3_RWread(&music->mp3file, read_start, 1, read_size);
  18.281  
  18.282          if (read_size == 0) {
  18.283              if ((music->status & (MS_input_eof | MS_input_error)) == 0) {
  18.284 @@ -596,6 +373,7 @@
  18.285      }
  18.286      return 0;
  18.287  }
  18.288 +
  18.289  static int MAD_GetAudio(void *context, void *data, int bytes)
  18.290  {
  18.291      MAD_Music *music = (MAD_Music *)context;
  18.292 @@ -621,7 +399,7 @@
  18.293          mad_timer_reset(&music->next_frame_start);
  18.294          music->status &= ~MS_error_flags;
  18.295  
  18.296 -        MAD_RWseek(music, 0, RW_SEEK_SET);
  18.297 +        MP3_RWseek(&music->mp3file, 0, RW_SEEK_SET);
  18.298      }
  18.299  
  18.300      /* Now we have to skip frames until we come to the right one.
  18.301 @@ -655,7 +433,7 @@
  18.302          SDL_FreeAudioStream(music->audiostream);
  18.303      }
  18.304      if (music->freesrc) {
  18.305 -        SDL_RWclose(music->src);
  18.306 +        SDL_RWclose(music->mp3file.src);
  18.307      }
  18.308      SDL_free(music);
  18.309  }