Isaac Burns added support for loading MP3 files as sound chunks
authorSam Lantinga <slouken@libsdl.org>
Sun, 15 Sep 2013 21:53:01 -0700
changeset 662fd5af79fac03
parent 661 03370c6f1325
child 663 52764006cd23
Isaac Burns added support for loading MP3 files as sound chunks
CHANGES.txt
Makefile.in
VisualC/SDL_mixer_VS2008.vcproj
VisualC/SDL_mixer_VS2010.vcxproj
VisualC/SDL_mixer_VS2012.vcxproj
Xcode-iOS/SDL_mixer.xcodeproj/project.pbxproj
Xcode/SDL_mixer.xcodeproj/project.pbxproj
load_mp3.c
load_mp3.h
mixer.c
     1.1 --- a/CHANGES.txt	Sun Sep 15 21:50:15 2013 -0700
     1.2 +++ b/CHANGES.txt	Sun Sep 15 21:53:01 2013 -0700
     1.3 @@ -1,3 +1,7 @@
     1.4 +2.0.1:
     1.5 +Isaac Burns - Sun Sep 15 21:50:27 PDT 2013
     1.6 + * Added support for loading MP3 files as sound chunks
     1.7 +
     1.8  2.0.0:
     1.9  Sam Lantinga - Sun Jun  9 14:45:30 PDT 2013
    1.10   * Made libmodplug the default MOD player as it is now in the public domain
     2.1 --- a/Makefile.in	Sun Sep 15 21:50:15 2013 -0700
     2.2 +++ b/Makefile.in	Sun Sep 15 21:53:01 2013 -0700
     2.3 @@ -39,7 +39,7 @@
     2.4  PLAYWAVE_OBJECTS = @PLAYWAVE_OBJECTS@
     2.5  PLAYMUS_OBJECTS = @PLAYMUS_OBJECTS@
     2.6  
     2.7 -DIST = *.txt Android.mk Makefile.in SDL2_mixer.pc.in SDL_mixer.h SDL2_mixer.spec SDL2_mixer.spec.in debian VisualC Xcode Xcode-iOS acinclude autogen.sh build-scripts configure configure.in dynamic_flac.c dynamic_flac.h dynamic_fluidsynth.c dynamic_fluidsynth.h dynamic_modplug.c dynamic_modplug.h dynamic_mod.c dynamic_mod.h dynamic_mp3.c dynamic_mp3.h dynamic_ogg.c dynamic_ogg.h effect_position.c effect_stereoreverse.c effects_internal.c effects_internal.h fluidsynth.c fluidsynth.h external gcc-fat.sh libmikmod-3.1.12.zip load_aiff.c load_aiff.h load_flac.c load_flac.h load_ogg.c load_ogg.h load_voc.c load_voc.h mixer.c music.c music_cmd.c music_cmd.h music_flac.c music_flac.h music_mad.c music_mad.h music_mod.c music_mod.h music_modplug.c music_modplug.h music_ogg.c music_ogg.h native_midi playmus.c playwave.c timidity wavestream.c wavestream.h version.rc
     2.8 +DIST = *.txt Android.mk Makefile.in SDL2_mixer.pc.in SDL_mixer.h SDL2_mixer.spec SDL2_mixer.spec.in debian VisualC Xcode Xcode-iOS acinclude autogen.sh build-scripts configure configure.in dynamic_flac.c dynamic_flac.h dynamic_fluidsynth.c dynamic_fluidsynth.h dynamic_modplug.c dynamic_modplug.h dynamic_mod.c dynamic_mod.h dynamic_mp3.c dynamic_mp3.h dynamic_ogg.c dynamic_ogg.h effect_position.c effect_stereoreverse.c effects_internal.c effects_internal.h fluidsynth.c fluidsynth.h external gcc-fat.sh libmikmod-3.1.12.zip load_aiff.c load_aiff.h load_flac.c load_flac.h load_mp3.c load_mp3.h load_ogg.c load_ogg.h load_voc.c load_voc.h mixer.c music.c music_cmd.c music_cmd.h music_flac.c music_flac.h music_mad.c music_mad.h music_mod.c music_mod.h music_modplug.c music_modplug.h music_ogg.c music_ogg.h native_midi playmus.c playwave.c timidity wavestream.c wavestream.h version.rc
     2.9  
    2.10  LT_AGE      = @LT_AGE@
    2.11  LT_CURRENT  = @LT_CURRENT@
     3.1 --- a/VisualC/SDL_mixer_VS2008.vcproj	Sun Sep 15 21:50:15 2013 -0700
     3.2 +++ b/VisualC/SDL_mixer_VS2008.vcproj	Sun Sep 15 21:53:01 2013 -0700
     3.3 @@ -673,6 +673,14 @@
     3.4  			>
     3.5  		</File>
     3.6  		<File
     3.7 +			RelativePath="..\load_mp3.c"
     3.8 +			>
     3.9 +		</File>
    3.10 +		<File
    3.11 +			RelativePath="..\load_mp3.h"
    3.12 +			>
    3.13 +		</File>
    3.14 +		<File
    3.15  			RelativePath="..\load_ogg.c"
    3.16  			>
    3.17  			<FileConfiguration
     4.1 --- a/VisualC/SDL_mixer_VS2010.vcxproj	Sun Sep 15 21:50:15 2013 -0700
     4.2 +++ b/VisualC/SDL_mixer_VS2010.vcxproj	Sun Sep 15 21:53:01 2013 -0700
     4.3 @@ -250,6 +250,7 @@
     4.4      <ClCompile Include="..\fluidsynth.c" />
     4.5      <ClCompile Include="..\load_aiff.c" />
     4.6      <ClCompile Include="..\load_flac.c" />
     4.7 +    <ClCompile Include="..\load_mp3.c" />
     4.8      <ClCompile Include="..\load_ogg.c" />
     4.9      <ClCompile Include="..\load_voc.c" />
    4.10      <ClCompile Include="..\mixer.c" />
    4.11 @@ -273,6 +274,7 @@
    4.12      <ClInclude Include="..\fluidsynth.h" />
    4.13      <ClInclude Include="..\load_aiff.h" />
    4.14      <ClInclude Include="..\load_flac.h" />
    4.15 +    <ClInclude Include="..\load_mp3.h" />
    4.16      <ClInclude Include="..\load_ogg.h" />
    4.17      <ClInclude Include="..\load_voc.h" />
    4.18      <ClInclude Include="..\music_cmd.h" />
     5.1 --- a/VisualC/SDL_mixer_VS2012.vcxproj	Sun Sep 15 21:50:15 2013 -0700
     5.2 +++ b/VisualC/SDL_mixer_VS2012.vcxproj	Sun Sep 15 21:53:01 2013 -0700
     5.3 @@ -254,6 +254,7 @@
     5.4      <ClCompile Include="..\fluidsynth.c" />
     5.5      <ClCompile Include="..\load_aiff.c" />
     5.6      <ClCompile Include="..\load_flac.c" />
     5.7 +    <ClCompile Include="..\load_mp3.c" />
     5.8      <ClCompile Include="..\load_ogg.c" />
     5.9      <ClCompile Include="..\load_voc.c" />
    5.10      <ClCompile Include="..\mixer.c" />
    5.11 @@ -277,6 +278,7 @@
    5.12      <ClInclude Include="..\fluidsynth.h" />
    5.13      <ClInclude Include="..\load_aiff.h" />
    5.14      <ClInclude Include="..\load_flac.h" />
    5.15 +    <ClInclude Include="..\load_mp3.h" />
    5.16      <ClInclude Include="..\load_ogg.h" />
    5.17      <ClInclude Include="..\load_voc.h" />
    5.18      <ClInclude Include="..\music_cmd.h" />
     6.1 --- a/Xcode-iOS/SDL_mixer.xcodeproj/project.pbxproj	Sun Sep 15 21:50:15 2013 -0700
     6.2 +++ b/Xcode-iOS/SDL_mixer.xcodeproj/project.pbxproj	Sun Sep 15 21:53:01 2013 -0700
     6.3 @@ -12,6 +12,8 @@
     6.4  		00938E55108A397A0009CF19 /* dynamic_mod.c in Sources */ = {isa = PBXBuildFile; fileRef = 00938E4B108A397A0009CF19 /* dynamic_mod.c */; };
     6.5  		00938E56108A397A0009CF19 /* dynamic_mp3.h in Headers */ = {isa = PBXBuildFile; fileRef = 00938E4C108A397A0009CF19 /* dynamic_mp3.h */; };
     6.6  		00938E57108A397A0009CF19 /* dynamic_ogg.h in Headers */ = {isa = PBXBuildFile; fileRef = 00938E4D108A397A0009CF19 /* dynamic_ogg.h */; };
     6.7 +		04939B4A17E607250015E4E3 /* load_mp3.c in Sources */ = {isa = PBXBuildFile; fileRef = 04939B4817E607250015E4E3 /* load_mp3.c */; };
     6.8 +		04939B4B17E607250015E4E3 /* load_mp3.h in Headers */ = {isa = PBXBuildFile; fileRef = 04939B4917E607250015E4E3 /* load_mp3.h */; };
     6.9  		04A8FCA60A19CAEC0046373F /* dynamic_mp3.c in Sources */ = {isa = PBXBuildFile; fileRef = 04A8FCA40A19CAEC0046373F /* dynamic_mp3.c */; };
    6.10  		04A8FCAB0A19CB070046373F /* dynamic_ogg.c in Sources */ = {isa = PBXBuildFile; fileRef = 04A8FCA90A19CB070046373F /* dynamic_ogg.c */; };
    6.11  		AA5F0F0914B6A6490036992F /* dynamic_fluidsynth.c in Sources */ = {isa = PBXBuildFile; fileRef = AA5F0F0214B6A6490036992F /* dynamic_fluidsynth.c */; };
    6.12 @@ -150,6 +152,8 @@
    6.13  		00938E4B108A397A0009CF19 /* dynamic_mod.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = dynamic_mod.c; path = ../dynamic_mod.c; sourceTree = SOURCE_ROOT; };
    6.14  		00938E4C108A397A0009CF19 /* dynamic_mp3.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = dynamic_mp3.h; path = ../dynamic_mp3.h; sourceTree = SOURCE_ROOT; };
    6.15  		00938E4D108A397A0009CF19 /* dynamic_ogg.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = dynamic_ogg.h; path = ../dynamic_ogg.h; sourceTree = SOURCE_ROOT; };
    6.16 +		04939B4817E607250015E4E3 /* load_mp3.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = load_mp3.c; path = ../load_mp3.c; sourceTree = "<group>"; };
    6.17 +		04939B4917E607250015E4E3 /* load_mp3.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = load_mp3.h; path = ../load_mp3.h; sourceTree = "<group>"; };
    6.18  		04A8FCA40A19CAEC0046373F /* dynamic_mp3.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = dynamic_mp3.c; path = ../dynamic_mp3.c; sourceTree = SOURCE_ROOT; };
    6.19  		04A8FCA90A19CB070046373F /* dynamic_ogg.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = dynamic_ogg.c; path = ../dynamic_ogg.c; sourceTree = SOURCE_ROOT; };
    6.20  		1014BAEA010A4B677F000001 /* SDL_mixer.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = SDL_mixer.h; path = ../SDL_mixer.h; sourceTree = SOURCE_ROOT; };
    6.21 @@ -349,6 +353,8 @@
    6.22  				F567D64801CD88A701F3E8B9 /* load_aiff.h */,
    6.23  				00938E2B108A37800009CF19 /* load_flac.c */,
    6.24  				00938E2C108A37800009CF19 /* load_flac.h */,
    6.25 +				04939B4817E607250015E4E3 /* load_mp3.c */,
    6.26 +				04939B4917E607250015E4E3 /* load_mp3.h */,
    6.27  				B2A42D0E03FAC6A400A8000A /* load_ogg.c */,
    6.28  				B2A42D0F03FAC6A400A8000A /* load_ogg.h */,
    6.29  				F567D64901CD88A701F3E8B9 /* load_voc.c */,
    6.30 @@ -543,6 +549,7 @@
    6.31  				AA60219017653A9800662B9C /* modplug.h in Headers */,
    6.32  				AA60219617653A9800662B9C /* tables.h in Headers */,
    6.33  				AA60219A17653B8700662B9C /* dynamic_modplug.h in Headers */,
    6.34 +				04939B4B17E607250015E4E3 /* load_mp3.h in Headers */,
    6.35  			);
    6.36  			runOnlyForDeploymentPostprocessing = 0;
    6.37  		};
    6.38 @@ -692,6 +699,7 @@
    6.39  				AA60219417653A9800662B9C /* sndfile.cpp in Sources */,
    6.40  				AA60219517653A9800662B9C /* sndmix.cpp in Sources */,
    6.41  				AA60219917653B8700662B9C /* dynamic_modplug.c in Sources */,
    6.42 +				04939B4A17E607250015E4E3 /* load_mp3.c in Sources */,
    6.43  			);
    6.44  			runOnlyForDeploymentPostprocessing = 0;
    6.45  		};
     7.1 --- a/Xcode/SDL_mixer.xcodeproj/project.pbxproj	Sun Sep 15 21:50:15 2013 -0700
     7.2 +++ b/Xcode/SDL_mixer.xcodeproj/project.pbxproj	Sun Sep 15 21:53:01 2013 -0700
     7.3 @@ -27,6 +27,10 @@
     7.4  		00938E57108A397A0009CF19 /* dynamic_ogg.h in Headers */ = {isa = PBXBuildFile; fileRef = 00938E4D108A397A0009CF19 /* dynamic_ogg.h */; };
     7.5  		0448E8AE108B937A00C9D3EA /* native_midi_macosx.c in Sources */ = {isa = PBXBuildFile; fileRef = 0448E8AD108B937A00C9D3EA /* native_midi_macosx.c */; };
     7.6  		0448E8AF108B937A00C9D3EA /* native_midi_macosx.c in Sources */ = {isa = PBXBuildFile; fileRef = 0448E8AD108B937A00C9D3EA /* native_midi_macosx.c */; };
     7.7 +		04939B4E17E607F70015E4E3 /* load_mp3.c in Sources */ = {isa = PBXBuildFile; fileRef = 04939B4C17E607F70015E4E3 /* load_mp3.c */; };
     7.8 +		04939B4F17E607F70015E4E3 /* load_mp3.c in Sources */ = {isa = PBXBuildFile; fileRef = 04939B4C17E607F70015E4E3 /* load_mp3.c */; };
     7.9 +		04939B5017E607F70015E4E3 /* load_mp3.h in Headers */ = {isa = PBXBuildFile; fileRef = 04939B4D17E607F70015E4E3 /* load_mp3.h */; };
    7.10 +		04939B5117E607F70015E4E3 /* load_mp3.h in Headers */ = {isa = PBXBuildFile; fileRef = 04939B4D17E607F70015E4E3 /* load_mp3.h */; };
    7.11  		04A8FCA60A19CAEC0046373F /* dynamic_mp3.c in Sources */ = {isa = PBXBuildFile; fileRef = 04A8FCA40A19CAEC0046373F /* dynamic_mp3.c */; };
    7.12  		04A8FCA70A19CAEC0046373F /* dynamic_mp3.c in Sources */ = {isa = PBXBuildFile; fileRef = 04A8FCA40A19CAEC0046373F /* dynamic_mp3.c */; };
    7.13  		04A8FCAB0A19CB070046373F /* dynamic_ogg.c in Sources */ = {isa = PBXBuildFile; fileRef = 04A8FCA90A19CB070046373F /* dynamic_ogg.c */; };
    7.14 @@ -190,6 +194,8 @@
    7.15  		00938E4C108A397A0009CF19 /* dynamic_mp3.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = dynamic_mp3.h; path = ../dynamic_mp3.h; sourceTree = SOURCE_ROOT; };
    7.16  		00938E4D108A397A0009CF19 /* dynamic_ogg.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = dynamic_ogg.h; path = ../dynamic_ogg.h; sourceTree = SOURCE_ROOT; };
    7.17  		0448E8AD108B937A00C9D3EA /* native_midi_macosx.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = native_midi_macosx.c; sourceTree = "<group>"; };
    7.18 +		04939B4C17E607F70015E4E3 /* load_mp3.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = load_mp3.c; path = ../load_mp3.c; sourceTree = "<group>"; };
    7.19 +		04939B4D17E607F70015E4E3 /* load_mp3.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = load_mp3.h; path = ../load_mp3.h; sourceTree = "<group>"; };
    7.20  		04A8FCA40A19CAEC0046373F /* dynamic_mp3.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = dynamic_mp3.c; path = ../dynamic_mp3.c; sourceTree = SOURCE_ROOT; };
    7.21  		04A8FCA90A19CB070046373F /* dynamic_ogg.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = dynamic_ogg.c; path = ../dynamic_ogg.c; sourceTree = SOURCE_ROOT; };
    7.22  		1014BAEA010A4B677F000001 /* SDL_mixer.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = SDL_mixer.h; path = ../SDL_mixer.h; sourceTree = SOURCE_ROOT; };
    7.23 @@ -352,6 +358,8 @@
    7.24  				F567D64801CD88A701F3E8B9 /* load_aiff.h */,
    7.25  				00938E2B108A37800009CF19 /* load_flac.c */,
    7.26  				00938E2C108A37800009CF19 /* load_flac.h */,
    7.27 +				04939B4C17E607F70015E4E3 /* load_mp3.c */,
    7.28 +				04939B4D17E607F70015E4E3 /* load_mp3.h */,
    7.29  				B2A42D0E03FAC6A400A8000A /* load_ogg.c */,
    7.30  				B2A42D0F03FAC6A400A8000A /* load_ogg.h */,
    7.31  				F567D64901CD88A701F3E8B9 /* load_voc.c */,
    7.32 @@ -500,6 +508,7 @@
    7.33  				AA602142176538EB00662B9C /* dynamic_modplug.h in Headers */,
    7.34  				AA602146176538EB00662B9C /* fluidsynth.h in Headers */,
    7.35  				AA60214A176538EB00662B9C /* music_modplug.h in Headers */,
    7.36 +				04939B5017E607F70015E4E3 /* load_mp3.h in Headers */,
    7.37  			);
    7.38  			runOnlyForDeploymentPostprocessing = 0;
    7.39  		};
    7.40 @@ -534,6 +543,7 @@
    7.41  				AA602143176538EB00662B9C /* dynamic_modplug.h in Headers */,
    7.42  				AA602147176538EB00662B9C /* fluidsynth.h in Headers */,
    7.43  				AA60214B176538EB00662B9C /* music_modplug.h in Headers */,
    7.44 +				04939B5117E607F70015E4E3 /* load_mp3.h in Headers */,
    7.45  			);
    7.46  			runOnlyForDeploymentPostprocessing = 0;
    7.47  		};
    7.48 @@ -751,6 +761,7 @@
    7.49  				AA602140176538EB00662B9C /* dynamic_modplug.c in Sources */,
    7.50  				AA602144176538EB00662B9C /* fluidsynth.c in Sources */,
    7.51  				AA602148176538EB00662B9C /* music_modplug.c in Sources */,
    7.52 +				04939B4E17E607F70015E4E3 /* load_mp3.c in Sources */,
    7.53  			);
    7.54  			runOnlyForDeploymentPostprocessing = 0;
    7.55  		};
    7.56 @@ -791,6 +802,7 @@
    7.57  				AA602141176538EB00662B9C /* dynamic_modplug.c in Sources */,
    7.58  				AA602145176538EB00662B9C /* fluidsynth.c in Sources */,
    7.59  				AA602149176538EB00662B9C /* music_modplug.c in Sources */,
    7.60 +				04939B4F17E607F70015E4E3 /* load_mp3.c in Sources */,
    7.61  			);
    7.62  			runOnlyForDeploymentPostprocessing = 0;
    7.63  		};
     8.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     8.2 +++ b/load_mp3.c	Sun Sep 15 21:53:01 2013 -0700
     8.3 @@ -0,0 +1,195 @@
     8.4 +/*
     8.5 +  SDL_mixer:  An audio mixer library based on the SDL library
     8.6 +  Copyright (C) 1997-2013 Sam Lantinga <slouken@libsdl.org>
     8.7 +
     8.8 +  This software is provided 'as-is', without any express or implied
     8.9 +  warranty.  In no event will the authors be held liable for any damages
    8.10 +  arising from the use of this software.
    8.11 +
    8.12 +  Permission is granted to anyone to use this software for any purpose,
    8.13 +  including commercial applications, and to alter it and redistribute it
    8.14 +  freely, subject to the following restrictions:
    8.15 +
    8.16 +  1. The origin of this software must not be misrepresented; you must not
    8.17 +	 claim that you wrote the original software. If you use this software
    8.18 +	 in a product, an acknowledgment in the product documentation would be
    8.19 +	 appreciated but is not required.
    8.20 +  2. Altered source versions must be plainly marked as such, and must not be
    8.21 +	 misrepresented as being the original software.
    8.22 +  3. This notice may not be removed or altered from any source distribution.
    8.23 +
    8.24 +  This is the source needed to decode an MP3 into a waveform.
    8.25 +*/
    8.26 +
    8.27 +/* $Id$ */
    8.28 +
    8.29 +#if defined(MP3_MUSIC) || defined(MP3_MAD_MUSIC)
    8.30 +
    8.31 +#include "SDL_mixer.h"
    8.32 +
    8.33 +#include "load_mp3.h"
    8.34 +
    8.35 +#if defined(MP3_MUSIC)
    8.36 +#include "dynamic_mp3.h"
    8.37 +#elif defined(MP3_MAD_MUSIC)
    8.38 +#include "music_mad.h"
    8.39 +#endif
    8.40 +
    8.41 +SDL_AudioSpec *Mix_LoadMP3_RW(SDL_RWops *src, int freesrc, SDL_AudioSpec *spec, Uint8 **audio_buf, Uint32 *audio_len)
    8.42 +{
    8.43 +	/* note: spec is initialized to mixer spec */
    8.44 +
    8.45 +#if defined(MP3_MUSIC)
    8.46 +	SMPEG* mp3;
    8.47 +	SMPEG_Info info;
    8.48 +#elif defined(MP3_MAD_MUSIC)
    8.49 +	mad_data *mp3_mad;
    8.50 +#endif
    8.51 +	long samplesize;
    8.52 +	int read_len;
    8.53 +	const Uint32 chunk_len = 4096;
    8.54 +	int err = 0;
    8.55 +
    8.56 +	if ((!src) || (!spec) || (!audio_buf) || (!audio_len))
    8.57 +	{
    8.58 +		return NULL;
    8.59 +	}
    8.60 +
    8.61 +	if (!err)
    8.62 +	{
    8.63 +		*audio_len = 0;
    8.64 +		*audio_buf = (Uint8*) SDL_malloc(chunk_len);
    8.65 +		err = (*audio_buf == NULL);
    8.66 +	}
    8.67 +
    8.68 +	if (!err)
    8.69 +	{
    8.70 +		err = ((Mix_Init(MIX_INIT_MP3) & MIX_INIT_MP3) == 0);
    8.71 +	}
    8.72 +
    8.73 +	if (!err)
    8.74 +	{
    8.75 +#if defined(MP3_MUSIC)
    8.76 +		mp3 = smpeg.SMPEG_new_rwops(src, &info, freesrc, 0);
    8.77 +		err = (mp3 == NULL);
    8.78 +#elif defined(MP3_MAD_MUSIC)
    8.79 +        mp3_mad = mad_openFileRW(src, spec, freesrc);
    8.80 +		err = (mp3_mad == NULL);
    8.81 +#endif
    8.82 +	}
    8.83 +
    8.84 +#if defined(MP3_MUSIC)
    8.85 +	if (!err)
    8.86 +	{
    8.87 +		err = !info.has_audio;
    8.88 +	}
    8.89 +#endif
    8.90 +
    8.91 +	if (!err)
    8.92 +	{
    8.93 +#if defined(MP3_MUSIC)
    8.94 +
    8.95 +		smpeg.SMPEG_actualSpec(mp3, spec);
    8.96 +
    8.97 +		smpeg.SMPEG_enableaudio(mp3, 1);
    8.98 +		smpeg.SMPEG_enablevideo(mp3, 0);
    8.99 +
   8.100 +		smpeg.SMPEG_play(mp3);
   8.101 +
   8.102 +		/* read once for audio length */
   8.103 +		while ((read_len = smpeg.SMPEG_playAudio(mp3, *audio_buf, chunk_len)) > 0)
   8.104 +		{
   8.105 +			*audio_len += read_len;
   8.106 +		}
   8.107 +
   8.108 +		smpeg.SMPEG_stop(mp3);
   8.109 +
   8.110 +#elif defined(MP3_MAD_MUSIC)
   8.111 +
   8.112 +        mad_start(mp3_mad);
   8.113 +
   8.114 +		/* read once for audio length */
   8.115 +		while ((read_len = mad_getSamples(mp3_mad, *audio_buf, chunk_len)) > 0)
   8.116 +		{
   8.117 +			*audio_len += read_len;
   8.118 +		}
   8.119 +
   8.120 +		mad_stop(mp3_mad);
   8.121 +
   8.122 +#endif
   8.123 +
   8.124 +		err = (read_len < 0);
   8.125 +	}
   8.126 +
   8.127 +	if (!err)
   8.128 +	{
   8.129 +		/* reallocate, if needed */
   8.130 +		if ((*audio_len > 0) && (*audio_len != chunk_len))
   8.131 +		{
   8.132 +			*audio_buf = (Uint8*) SDL_realloc(*audio_buf, *audio_len);
   8.133 +			err = (*audio_buf == NULL);
   8.134 +		}
   8.135 +	}
   8.136 +
   8.137 +	if (!err)
   8.138 +	{
   8.139 +		/* read again for audio buffer, if needed */
   8.140 +		if (*audio_len > chunk_len)
   8.141 +		{
   8.142 +#if defined(MP3_MUSIC)
   8.143 +			smpeg.SMPEG_rewind(mp3);
   8.144 +			smpeg.SMPEG_play(mp3);
   8.145 +			err = (*audio_len != smpeg.SMPEG_playAudio(mp3, *audio_buf, *audio_len));
   8.146 +			smpeg.SMPEG_stop(mp3);
   8.147 +#elif defined(MP3_MAD_MUSIC)
   8.148 +			mad_seek(mp3_mad, 0);
   8.149 +			mad_start(mp3_mad);
   8.150 +			err = (*audio_len != mad_getSamples(mp3_mad, *audio_buf, *audio_len));
   8.151 +			mad_stop(mp3_mad);
   8.152 +#endif
   8.153 +		}
   8.154 +	}
   8.155 +
   8.156 +	if (!err)
   8.157 +	{
   8.158 +		/* Don't return a buffer that isn't a multiple of samplesize */
   8.159 +		samplesize = ((spec->format & 0xFF)/8)*spec->channels;
   8.160 +		*audio_len &= ~(samplesize-1);
   8.161 +	}
   8.162 +
   8.163 +#if defined(MP3_MUSIC)
   8.164 +	if (mp3)
   8.165 +	{
   8.166 +		smpeg.SMPEG_delete(mp3); mp3 = NULL;
   8.167 +		/* Deleting the MP3 closed the source if desired */
   8.168 +		freesrc = SDL_FALSE;
   8.169 +	}
   8.170 +#elif defined(MP3_MAD_MUSIC)
   8.171 +	if (mp3_mad)
   8.172 +	{
   8.173 +		mad_closeFile(mp3_mad); mp3_mad = NULL;
   8.174 +		/* Deleting the MP3 closed the source if desired */
   8.175 +		freesrc = SDL_FALSE;
   8.176 +	}
   8.177 +#endif
   8.178 +
   8.179 +	if (freesrc)
   8.180 +	{
   8.181 +		SDL_RWclose(src); src = NULL;
   8.182 +	}
   8.183 +
   8.184 +	/* handle error */
   8.185 +	if (err)
   8.186 +	{
   8.187 +		if (*audio_buf != NULL)
   8.188 +		{
   8.189 +			SDL_free(*audio_buf); *audio_buf = NULL;
   8.190 +		}
   8.191 +		*audio_len = 0;
   8.192 +		spec = NULL;
   8.193 +	}
   8.194 +
   8.195 +	return spec;
   8.196 +}
   8.197 +
   8.198 +#endif
     9.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     9.2 +++ b/load_mp3.h	Sun Sep 15 21:53:01 2013 -0700
     9.3 @@ -0,0 +1,30 @@
     9.4 +/*
     9.5 +  SDL_mixer:  An audio mixer library based on the SDL library
     9.6 +  Copyright (C) 1997-2013 Sam Lantinga <slouken@libsdl.org>
     9.7 +
     9.8 +  This software is provided 'as-is', without any express or implied
     9.9 +  warranty.  In no event will the authors be held liable for any damages
    9.10 +  arising from the use of this software.
    9.11 +
    9.12 +  Permission is granted to anyone to use this software for any purpose,
    9.13 +  including commercial applications, and to alter it and redistribute it
    9.14 +  freely, subject to the following restrictions:
    9.15 +
    9.16 +  1. The origin of this software must not be misrepresented; you must not
    9.17 +     claim that you wrote the original software. If you use this software
    9.18 +     in a product, an acknowledgment in the product documentation would be
    9.19 +     appreciated but is not required.
    9.20 +  2. Altered source versions must be plainly marked as such, and must not be
    9.21 +     misrepresented as being the original software.
    9.22 +  3. This notice may not be removed or altered from any source distribution.
    9.23 +
    9.24 +  This is the source needed to decode an MP3 into a waveform.
    9.25 +*/
    9.26 +
    9.27 +/* $Id$ */
    9.28 +
    9.29 +#ifdef MP3_MUSIC
    9.30 +/* Don't call this directly; use Mix_LoadWAV_RW() for now. */
    9.31 +SDL_AudioSpec *Mix_LoadMP3_RW (SDL_RWops *src, int freesrc,
    9.32 +        SDL_AudioSpec *spec, Uint8 **audio_buf, Uint32 *audio_len);
    9.33 +#endif
    10.1 --- a/mixer.c	Sun Sep 15 21:50:15 2013 -0700
    10.2 +++ b/mixer.c	Sun Sep 15 21:53:01 2013 -0700
    10.3 @@ -32,6 +32,7 @@
    10.4  #include "SDL_mixer.h"
    10.5  #include "load_aiff.h"
    10.6  #include "load_voc.h"
    10.7 +#include "load_mp3.h"
    10.8  #include "load_ogg.h"
    10.9  #include "load_flac.h"
   10.10  #include "dynamic_flac.h"
   10.11 @@ -493,6 +494,9 @@
   10.12  #ifdef FLAC_MUSIC
   10.13      add_chunk_decoder("FLAC");
   10.14  #endif
   10.15 +#if defined(MP3_MUSIC) || defined(MP3_MAD_MUSIC)
   10.16 +    add_chunk_decoder("MP3");
   10.17 +#endif
   10.18  
   10.19      audio_opened = 1;
   10.20      SDL_PauseAudio(0);
   10.21 @@ -557,6 +561,23 @@
   10.22      return(audio_opened);
   10.23  }
   10.24  
   10.25 +static int detect_mp3(Uint8 *magic)
   10.26 +{
   10.27 +    if ( strncmp((char *)magic, "ID3", 3) == 0 ) {
   10.28 +        return 1;
   10.29 +    }
   10.30 +
   10.31 +    /* Detection code lifted from SMPEG */
   10.32 +    if(((magic[0] & 0xff) != 0xff) || // No sync bits
   10.33 +       ((magic[1] & 0xf0) != 0xf0) || //
   10.34 +       ((magic[2] & 0xf0) == 0x00) || // Bitrate is 0
   10.35 +       ((magic[2] & 0xf0) == 0xf0) || // Bitrate is 15
   10.36 +       ((magic[2] & 0x0c) == 0x0c) || // Frequency is 3
   10.37 +       ((magic[1] & 0x06) == 0x00)) { // Layer is 4
   10.38 +        return(0);
   10.39 +    }
   10.40 +    return 1;
   10.41 +}
   10.42  
   10.43  /*
   10.44   * !!! FIXME: Ideally, we want a Mix_LoadSample_RW(), which will handle the
   10.45 @@ -629,6 +650,16 @@
   10.46                      (Uint8 **)&chunk->abuf, &chunk->alen);
   10.47              break;
   10.48          default:
   10.49 +#if defined(MP3_MUSIC) || defined(MP3_MAD_MUSIC)
   10.50 +			if (detect_mp3((Uint8*)&magic))
   10.51 +			{
   10.52 +				/* note: send a copy of the mixer spec */
   10.53 +				wavespec = mixer;
   10.54 +				loaded = Mix_LoadMP3_RW(src, freesrc, &wavespec,
   10.55 +						(Uint8 **)&chunk->abuf, &chunk->alen);
   10.56 +				break;
   10.57 +			}
   10.58 +#endif
   10.59              SDL_SetError("Unrecognized sound file type");
   10.60              if ( freesrc ) {
   10.61                  SDL_RWclose(src);