Fixed bug 1252 - Added Mix_LoadMUSType_RW() so you can tell SDL_mixer what type the music is
authorSam Lantinga <slouken@libsdl.org>
Wed, 04 Jan 2012 00:16:03 -0500
changeset 5423de4970b36d4
parent 541 323b314739ef
child 543 26aaf8aea8c1
Fixed bug 1252 - Added Mix_LoadMUSType_RW() so you can tell SDL_mixer what type the music is

This involved a complete refactoring of the music loading so it's entirely rwops based and has improved music type detection code.
CHANGES
SDL_mixer.h
configure
configure.in
dynamic_mp3.c
dynamic_mp3.h
fluidsynth.c
fluidsynth.h
music.c
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/native_midi.h
native_midi/native_midi_haiku.cpp
native_midi/native_midi_mac.c
native_midi/native_midi_macosx.c
native_midi/native_midi_win32.c
timidity/playmidi.c
timidity/timidity.h
wavestream.c
wavestream.h
     1.1 --- a/CHANGES	Tue Jan 03 16:46:05 2012 -0800
     1.2 +++ b/CHANGES	Wed Jan 04 00:16:03 2012 -0500
     1.3 @@ -1,6 +1,8 @@
     1.4  1.2.12:
     1.5  Sam Lantinga - Tue Jan  3 01:36:33 EST 2012
     1.6   * The Mac OS X framework name changed to SDLmixer, to meet Apple's requirements
     1.7 +Nikos Chantziaras - 2012-01-02 17:37:36 PST
     1.8 + * Added Mix_LoadMUSType_RW() so you can tell SDL_mixer what type the music is
     1.9  Sam Lantinga - Sat Dec 31 19:11:59 EST 2011
    1.10   * Fixed dropping audio in the FLAC audio decoding
    1.11  Sam Lantinga - Sat Dec 31 18:32:05 EST 2011
     2.1 --- a/SDL_mixer.h	Tue Jan 03 16:46:05 2012 -0800
     2.2 +++ b/SDL_mixer.h	Wed Jan 04 00:16:03 2012 -0500
     2.3 @@ -154,6 +154,9 @@
     2.4     Matt Campbell (matt@campbellhome.dhs.org) April 2000 */
     2.5  extern DECLSPEC Mix_Music * SDLCALL Mix_LoadMUS_RW(SDL_RWops *rw);
     2.6  
     2.7 +/* Load a music file from an SDL_RWop object assuming a specific format */
     2.8 +extern DECLSPEC Mix_Music * SDLCALL Mix_LoadMUSType_RW(SDL_RWops *rw, Mix_MusicType type, int freesrc);
     2.9 +
    2.10  /* Load a wave file of the mixer format from a memory buffer */
    2.11  extern DECLSPEC Mix_Chunk * SDLCALL Mix_QuickLoad_WAV(Uint8 *mem);
    2.12  
     3.1 --- a/configure	Tue Jan 03 16:46:05 2012 -0800
     3.2 +++ b/configure	Wed Jan 04 00:16:03 2012 -0500
     3.3 @@ -1995,7 +1995,7 @@
     3.4  MAJOR_VERSION=1
     3.5  MINOR_VERSION=2
     3.6  MICRO_VERSION=12
     3.7 -INTERFACE_AGE=2
     3.8 +INTERFACE_AGE=0
     3.9  BINARY_AGE=12
    3.10  VERSION=$MAJOR_VERSION.$MINOR_VERSION.$MICRO_VERSION
    3.11  
     4.1 --- a/configure.in	Tue Jan 03 16:46:05 2012 -0800
     4.2 +++ b/configure.in	Wed Jan 04 00:16:03 2012 -0500
     4.3 @@ -15,7 +15,7 @@
     4.4  MAJOR_VERSION=1
     4.5  MINOR_VERSION=2
     4.6  MICRO_VERSION=12
     4.7 -INTERFACE_AGE=2
     4.8 +INTERFACE_AGE=0
     4.9  BINARY_AGE=12
    4.10  VERSION=$MAJOR_VERSION.$MINOR_VERSION.$MICRO_VERSION
    4.11  
     5.1 --- a/dynamic_mp3.c	Tue Jan 03 16:46:05 2012 -0800
     5.2 +++ b/dynamic_mp3.c	Wed Jan 04 00:16:03 2012 -0500
     5.3 @@ -65,13 +65,6 @@
     5.4  			SDL_UnloadObject(smpeg.handle);
     5.5  			return -1;
     5.6  		}
     5.7 -		smpeg.SMPEG_new =
     5.8 -			(SMPEG* (*)(const char *, SMPEG_Info*, int))
     5.9 -			SDL_LoadFunction(smpeg.handle, "SMPEG_new");
    5.10 -		if ( smpeg.SMPEG_new == NULL ) {
    5.11 -			SDL_UnloadObject(smpeg.handle);
    5.12 -			return -1;
    5.13 -		}
    5.14  		smpeg.SMPEG_new_rwops =
    5.15  			(SMPEG* (*)(SDL_RWops *, SMPEG_Info*, int))
    5.16  			SDL_LoadFunction(smpeg.handle, "SMPEG_new_rwops");
    5.17 @@ -151,7 +144,6 @@
    5.18  		smpeg.SMPEG_delete = SMPEG_delete;
    5.19  		smpeg.SMPEG_enableaudio = SMPEG_enableaudio;
    5.20  		smpeg.SMPEG_enablevideo = SMPEG_enablevideo;
    5.21 -		smpeg.SMPEG_new = SMPEG_new;
    5.22  		smpeg.SMPEG_new_rwops = SMPEG_new_rwops;
    5.23  		smpeg.SMPEG_play = SMPEG_play;
    5.24  		smpeg.SMPEG_playAudio = SMPEG_playAudio;
     6.1 --- a/dynamic_mp3.h	Tue Jan 03 16:46:05 2012 -0800
     6.2 +++ b/dynamic_mp3.h	Wed Jan 04 00:16:03 2012 -0500
     6.3 @@ -29,7 +29,6 @@
     6.4  	void (*SMPEG_delete)( SMPEG* mpeg );
     6.5  	void (*SMPEG_enableaudio)( SMPEG* mpeg, int enable );
     6.6  	void (*SMPEG_enablevideo)( SMPEG* mpeg, int enable );
     6.7 -	SMPEG* (*SMPEG_new)(const char *file, SMPEG_Info* info, int sdl_audio);
     6.8  	SMPEG* (*SMPEG_new_rwops)(SDL_RWops *src, SMPEG_Info* info, int sdl_audio);
     6.9  	void (*SMPEG_play)( SMPEG* mpeg );
    6.10  	int (*SMPEG_playAudio)( SMPEG *mpeg, Uint8 *stream, int len );
     7.1 --- a/fluidsynth.c	Tue Jan 03 16:46:05 2012 -0800
     7.2 +++ b/fluidsynth.c	Wed Jan 04 00:16:03 2012 -0500
     7.3 @@ -66,7 +66,7 @@
     7.4  	return 0;
     7.5  }
     7.6  
     7.7 -FluidSynthMidiSong *fluidsynth_loadsong_common(int (*function)(FluidSynthMidiSong*, void*), void *data)
     7.8 +static FluidSynthMidiSong *fluidsynth_loadsong_common(int (*function)(FluidSynthMidiSong*, void*), void *data)
     7.9  {
    7.10  	FluidSynthMidiSong *song;
    7.11  	fluid_settings_t *settings = NULL;
    7.12 @@ -105,19 +105,7 @@
    7.13  	return NULL;
    7.14  }
    7.15  
    7.16 -int fluidsynth_loadsong_internal(FluidSynthMidiSong *song, void *data)
    7.17 -{
    7.18 -	const char* path = (const char*) data;
    7.19 -
    7.20 -	if (fluidsynth.fluid_player_add(song->player, path) == FLUID_OK) {
    7.21 -		return 1;
    7.22 -	} else {
    7.23 -		Mix_SetError("FluidSynth failed to load %s", path);
    7.24 -		return 0;
    7.25 -	}
    7.26 -}
    7.27 -
    7.28 -int fluidsynth_loadsong_RW_internal(FluidSynthMidiSong *song, void *data)
    7.29 +static int fluidsynth_loadsong_RW_internal(FluidSynthMidiSong *song, void *data)
    7.30  {
    7.31  	off_t offset;
    7.32  	size_t size;
    7.33 @@ -146,11 +134,6 @@
    7.34  	return 0;
    7.35  }
    7.36  
    7.37 -FluidSynthMidiSong *fluidsynth_loadsong(const char *midifile)
    7.38 -{
    7.39 -	return fluidsynth_loadsong_common(fluidsynth_loadsong_internal, (void*) midifile);
    7.40 -}
    7.41 -
    7.42  FluidSynthMidiSong *fluidsynth_loadsong_RW(SDL_RWops *rw, int freerw)
    7.43  {
    7.44  	FluidSynthMidiSong *song;
     8.1 --- a/fluidsynth.h	Tue Jan 03 16:46:05 2012 -0800
     8.2 +++ b/fluidsynth.h	Wed Jan 04 00:16:03 2012 -0500
     8.3 @@ -38,7 +38,6 @@
     8.4  } FluidSynthMidiSong;
     8.5  
     8.6  int fluidsynth_init(SDL_AudioSpec *mixer);
     8.7 -FluidSynthMidiSong *fluidsynth_loadsong(const char *midifile);
     8.8  FluidSynthMidiSong *fluidsynth_loadsong_RW(SDL_RWops *rw, int freerw);
     8.9  void fluidsynth_freesong(FluidSynthMidiSong *song);
    8.10  void fluidsynth_start(FluidSynthMidiSong *song);
     9.1 --- a/music.c	Tue Jan 03 16:46:05 2012 -0800
     9.2 +++ b/music.c	Wed Jan 04 00:16:03 2012 -0500
     9.3 @@ -438,100 +438,271 @@
     9.4  	return (!*str1 && !*str2);
     9.5  }
     9.6  
     9.7 +static int detect_mp3(Uint8 *magic)
     9.8 +{
     9.9 +	if ( strncmp((char *)magic, "ID3", 3) == 0 ) {
    9.10 +		return 1;
    9.11 +	}
    9.12 +
    9.13 +	/* Detection code lifted from SMPEG */
    9.14 +	if(((magic[0] & 0xff) != 0xff) || // No sync bits
    9.15 +	   ((magic[1] & 0xf0) != 0xf0) || //
    9.16 +	   ((magic[2] & 0xf0) == 0x00) || // Bitrate is 0
    9.17 +	   ((magic[2] & 0xf0) == 0xf0) || // Bitrate is 15
    9.18 +	   ((magic[2] & 0x0c) == 0x0c) || // Frequency is 3
    9.19 +	   ((magic[1] & 0x06) == 0x00)) { // Layer is 4
    9.20 +		return(0);
    9.21 +	}
    9.22 +	return 1;
    9.23 +}
    9.24 +
    9.25 +/* MUS_MOD can't be auto-detected. If no other format was detected, MOD is
    9.26 + * assumed and MUS_MOD will be returned, meaning that the format might not
    9.27 + * actually be MOD-based.
    9.28 + *
    9.29 + * Returns MUS_NONE in case of errors. */
    9.30 +static Mix_MusicType detect_music_type(SDL_RWops *rw)
    9.31 +{
    9.32 +	Uint8 magic[5];
    9.33 +	Uint8 moremagic[9];
    9.34 +
    9.35 +	int start = SDL_RWtell(rw);
    9.36 +	if (SDL_RWread(rw, magic, 1, 4) != 4 || SDL_RWread(rw, moremagic, 1, 8) != 8 ) {
    9.37 +		Mix_SetError("Couldn't read from RWops");
    9.38 +		return MUS_NONE;
    9.39 +	}
    9.40 +	SDL_RWseek(rw, start, RW_SEEK_SET);
    9.41 +	magic[4]='\0';
    9.42 +	moremagic[8] = '\0';
    9.43 +
    9.44 +	/* WAVE files have the magic four bytes "RIFF"
    9.45 +	   AIFF files have the magic 12 bytes "FORM" XXXX "AIFF" */
    9.46 +	if (((strcmp((char *)magic, "RIFF") == 0) && (strcmp((char *)(moremagic+4), "WAVE") == 0)) ||
    9.47 +		(strcmp((char *)magic, "FORM") == 0)) {
    9.48 +		return MUS_WAV;
    9.49 +	}
    9.50 +
    9.51 +	/* Ogg Vorbis files have the magic four bytes "OggS" */
    9.52 +	if (strcmp((char *)magic, "OggS") == 0) {
    9.53 +		return MUS_OGG;
    9.54 +	}
    9.55 +
    9.56 +	/* FLAC files have the magic four bytes "fLaC" */
    9.57 +	if (strcmp((char *)magic, "fLaC") == 0) {
    9.58 +		return MUS_FLAC;
    9.59 +	}
    9.60 +
    9.61 +	/* MIDI files have the magic four bytes "MThd" */
    9.62 +	if (strcmp((char *)magic, "MThd") == 0) {
    9.63 +		return MUS_MID;
    9.64 +	}
    9.65 +
    9.66 +	if (detect_mp3(magic)) {
    9.67 +		return MUS_MP3;
    9.68 +	}
    9.69 +
    9.70 +	/* Assume MOD format.
    9.71 +	 *
    9.72 +	 * Apparently there is no way to check if the file is really a MOD,
    9.73 +	 * or there are too many formats supported by MikMod/ModPlug, or
    9.74 +	 * MikMod/ModPlug does this check by itself. */
    9.75 +	return MUS_MOD;
    9.76 +}
    9.77 +
    9.78  /* Load a music file */
    9.79  Mix_Music *Mix_LoadMUS(const char *file)
    9.80  {
    9.81 -	FILE *fp;
    9.82 -	char *ext;
    9.83 -	Uint8 magic[5], moremagic[9];
    9.84 +	SDL_RWops *rw;
    9.85 +	Mix_Music *music;
    9.86 +	Mix_MusicType type;
    9.87 +	char *ext = strrchr(file, '.');
    9.88 +
    9.89 +#ifdef CMD_MUSIC
    9.90 +	if ( music_cmd ) {
    9.91 +		/* Allocate memory for the music structure */
    9.92 +		music = (Mix_Music *)malloc(sizeof(Mix_Music));
    9.93 +		if ( music == NULL ) {
    9.94 +			Mix_SetError("Out of memory");
    9.95 +			return(NULL);
    9.96 +		}
    9.97 +		music->error = 0;
    9.98 +		music->type = MUS_CMD;
    9.99 +		music->data.cmd = MusicCMD_LoadSong(music_cmd, file);
   9.100 +		if ( music->data.cmd == NULL ) {
   9.101 +			free(music);
   9.102 +			music == NULL;
   9.103 +		}
   9.104 +		return music;
   9.105 +	}
   9.106 +#endif
   9.107 +
   9.108 +	rw = SDL_RWFromFile(file, "rb");
   9.109 +	if ( rw == NULL ) {
   9.110 +		Mix_SetError("Couldn't open '%s'", file);
   9.111 +		return NULL;
   9.112 +	}
   9.113 +
   9.114 +	/* Use the extension as a first guess on the file type */
   9.115 +	type = MUS_NONE;
   9.116 +	ext = strrchr(file, '.');
   9.117 +	/* No need to guard these with #ifdef *_MUSIC stuff,
   9.118 +	 * since we simply call Mix_LoadMUSType_RW() later */
   9.119 +	if ( ext ) {
   9.120 +		++ext; /* skip the dot in the extension */
   9.121 +		if ( MIX_string_equals(ext, "WAV") ) {
   9.122 +			type = MUS_WAV;
   9.123 +		} else if ( MIX_string_equals(ext, "MID") ||
   9.124 +		            MIX_string_equals(ext, "MIDI") ||
   9.125 +		            MIX_string_equals(ext, "KAR") ) {
   9.126 +			type = MUS_MID;
   9.127 +		} else if ( MIX_string_equals(ext, "OGG") ) {
   9.128 +			type = MUS_OGG;
   9.129 +		} else if ( MIX_string_equals(ext, "FLAC") ) {
   9.130 +			type = MUS_FLAC;
   9.131 +		} else 	if ( MIX_string_equals(ext, "MPG") ||
   9.132 +		             MIX_string_equals(ext, "MPEG") ||
   9.133 +		             MIX_string_equals(ext, "MP3") ||
   9.134 +		             MIX_string_equals(ext, "MAD") ) {
   9.135 +			type = MUS_MP3;
   9.136 +		}
   9.137 +	}
   9.138 +	if ( type == MUS_NONE ) {
   9.139 +		type = detect_music_type(rw);
   9.140 +	}
   9.141 +
   9.142 +	/* We need to know if a specific error occurs; if not, we'll set a
   9.143 +	 * generic one, so we clear the current one. */
   9.144 +	Mix_SetError("");
   9.145 +	music = Mix_LoadMUSType_RW(rw, type, SDL_TRUE);
   9.146 +	if ( music == NULL && Mix_GetError()[0] == '\0' ) {
   9.147 +		SDL_FreeRW(rw);
   9.148 +		Mix_SetError("Couldn't open '%s'", file);
   9.149 +	}
   9.150 +	return music;
   9.151 +}
   9.152 +
   9.153 +Mix_Music *Mix_LoadMUS_RW(SDL_RWops *rw)
   9.154 +{
   9.155 +	return Mix_LoadMUSType_RW(rw, MUS_NONE, SDL_FALSE);
   9.156 +}
   9.157 +
   9.158 +Mix_Music *Mix_LoadMUSType_RW(SDL_RWops *rw, Mix_MusicType type, int freesrc)
   9.159 +{
   9.160  	Mix_Music *music;
   9.161  
   9.162 -	/* Figure out what kind of file this is */
   9.163 -	fp = fopen(file, "rb");
   9.164 -	if ( (fp == NULL) || !fread(magic, 4, 1, fp) ) {
   9.165 -		if ( fp != NULL ) {
   9.166 -			fclose(fp);
   9.167 +	if (!rw) {
   9.168 +		Mix_SetError("RWops pointer is NULL");
   9.169 +		return NULL;
   9.170 +	}
   9.171 +
   9.172 +	/* If the caller wants auto-detection, figure out what kind of file
   9.173 +	 * this is. */
   9.174 +	if (type == MUS_NONE) {
   9.175 +		if ((type = detect_music_type(rw)) == MUS_NONE) {
   9.176 +			/* Don't call Mix_SetError() here since detect_music_type()
   9.177 +			 * does that. */
   9.178 +			return NULL;
   9.179  		}
   9.180 -		Mix_SetError("Couldn't read from '%s'", file);
   9.181 -		return(NULL);
   9.182  	}
   9.183 -	if (!fread(moremagic, 8, 1, fp)) {
   9.184 -		Mix_SetError("Couldn't read from '%s'", file);
   9.185 -		return(NULL);
   9.186 -	}
   9.187 -	magic[4] = '\0';
   9.188 -	moremagic[8] = '\0';
   9.189 -	fclose(fp);
   9.190 -
   9.191 -	/* Figure out the file extension, so we can determine the type */
   9.192 -	ext = strrchr(file, '.');
   9.193 -	if ( ext ) ++ext; /* skip the dot in the extension */
   9.194  
   9.195  	/* Allocate memory for the music structure */
   9.196  	music = (Mix_Music *)malloc(sizeof(Mix_Music));
   9.197 -	if ( music == NULL ) {
   9.198 +	if (music == NULL ) {
   9.199  		Mix_SetError("Out of memory");
   9.200 -		return(NULL);
   9.201 +		return NULL;
   9.202  	}
   9.203  	music->error = 0;
   9.204  
   9.205 -#ifdef CMD_MUSIC
   9.206 -	if ( music_cmd ) {
   9.207 -		music->type = MUS_CMD;
   9.208 -		music->data.cmd = MusicCMD_LoadSong(music_cmd, file);
   9.209 -		if ( music->data.cmd == NULL ) {
   9.210 +	switch (type) {
   9.211 +#ifdef WAV_MUSIC
   9.212 +	case MUS_WAV:
   9.213 +		/* The WAVE loader needs the first 4 bytes of the header */
   9.214 +		{
   9.215 +			Uint8 magic[5];
   9.216 +			int start = SDL_RWtell(rw);
   9.217 +			if (SDL_RWread(rw, magic, 1, 4) != 4) {
   9.218 +				Mix_SetError("Couldn't read from RWops");
   9.219 +				return MUS_NONE;
   9.220 +			}
   9.221 +			SDL_RWseek(rw, start, RW_SEEK_SET);
   9.222 +			magic[4] = '\0';
   9.223 +			music->type = MUS_WAV;
   9.224 +			music->data.wave = WAVStream_LoadSong_RW(rw, (char *)magic, freesrc);
   9.225 +		}
   9.226 +		if (music->data.wave == NULL) {
   9.227  			music->error = 1;
   9.228  		}
   9.229 -	} else
   9.230 +		break;
   9.231  #endif
   9.232 -#ifdef WAV_MUSIC
   9.233 -	/* WAVE files have the magic four bytes "RIFF"
   9.234 -	   AIFF files have the magic 12 bytes "FORM" XXXX "AIFF"
   9.235 -	 */
   9.236 -	if ( (ext && MIX_string_equals(ext, "WAV")) ||
   9.237 -	     ((strcmp((char *)magic, "RIFF") == 0) && (strcmp((char *)(moremagic+4), "WAVE") == 0)) ||
   9.238 -	     (strcmp((char *)magic, "FORM") == 0) ) {
   9.239 -		music->type = MUS_WAV;
   9.240 -		music->data.wave = WAVStream_LoadSong(file, (char *)magic);
   9.241 -		if ( music->data.wave == NULL ) {
   9.242 -		  	Mix_SetError("Unable to load WAV file");
   9.243 +#ifdef OGG_MUSIC
   9.244 +	case MUS_OGG:
   9.245 +		music->type = MUS_OGG;
   9.246 +		music->data.ogg = OGG_new_RW(rw, freesrc);
   9.247 +		if ( music->data.ogg == NULL ) {
   9.248  			music->error = 1;
   9.249  		}
   9.250 -	} else
   9.251 +		break;
   9.252 +#endif
   9.253 +#ifdef FLAC_MUSIC
   9.254 +	case MUS_FLAC:
   9.255 +		music->type = MUS_FLAC;
   9.256 +		music->data.flac = FLAC_new_RW(rw, freesrc);
   9.257 +		if ( music->data.flac == NULL ) {
   9.258 +			music->error = 1;
   9.259 +		}
   9.260 +		break;
   9.261 +#endif
   9.262 +#ifdef MP3_MUSIC
   9.263 +	case MUS_MP3:
   9.264 +		if ( Mix_Init(MIX_INIT_MP3) ) {
   9.265 +			SMPEG_Info info;
   9.266 +			music->type = MUS_MP3;
   9.267 +			music->data.mp3 = smpeg.SMPEG_new_rwops(rw, &info, 0);
   9.268 +			if ( !info.has_audio ) {
   9.269 +				Mix_SetError("MPEG file does not have any audio stream.");
   9.270 +				music->error = 1;
   9.271 +			} else {
   9.272 +				smpeg.SMPEG_actualSpec(music->data.mp3, &used_mixer);
   9.273 +			}
   9.274 +		} else {
   9.275 +			music->error = 1;
   9.276 +		}
   9.277 +		break;
   9.278 +#elif defined(MP3_MAD_MUSIC)
   9.279 +	case MUS_MP3:
   9.280 +		music->type = MUS_MP3_MAD;
   9.281 +		music->data.mp3_mad = mad_openFileRW(rw, &used_mixer, freesrc);
   9.282 +		if (music->data.mp3_mad == 0) {
   9.283 +			Mix_SetError("Could not initialize MPEG stream.");
   9.284 +			music->error = 1;
   9.285 +		}
   9.286 +		break;
   9.287  #endif
   9.288  #ifdef MID_MUSIC
   9.289 -	/* MIDI files have the magic four bytes "MThd" */
   9.290 -	if ( (ext && MIX_string_equals(ext, "MID")) ||
   9.291 -	     (ext && MIX_string_equals(ext, "MIDI")) ||
   9.292 -	     strcmp((char *)magic, "MThd") == 0  ||
   9.293 -	     ( strcmp((char *)magic, "RIFF") == 0  &&
   9.294 -	  	strcmp((char *)(moremagic+4), "RMID") == 0 ) ) {
   9.295 +	case MUS_MID:
   9.296  		music->type = MUS_MID;
   9.297  #ifdef USE_NATIVE_MIDI
   9.298 -  		if ( native_midi_ok ) {
   9.299 -/*printf("Native MIDI\n");*/
   9.300 -  			music->data.nativemidi = native_midi_loadsong(file);
   9.301 +		if ( native_midi_ok ) {
   9.302 +			music->data.nativemidi = native_midi_loadsong_RW(rw, freesrc);
   9.303  	  		if ( music->data.nativemidi == NULL ) {
   9.304  		  		Mix_SetError("%s", native_midi_error());
   9.305  			  	music->error = 1;
   9.306  			}
   9.307 -			goto skip;
   9.308 -	  	}
   9.309 +			break;
   9.310 +		}
   9.311  #endif
   9.312  #ifdef USE_FLUIDSYNTH_MIDI
   9.313  		if ( fluidsynth_ok ) {
   9.314 -/*printf("FluidSynth MIDI\n");*/
   9.315 -			music->data.fluidsynthmidi = fluidsynth_loadsong(file);
   9.316 +			music->data.fluidsynthmidi = fluidsynth_loadsong_RW(rw, freesrc);
   9.317  			if ( music->data.fluidsynthmidi == NULL ) {
   9.318  				music->error = 1;
   9.319  			}
   9.320 -			goto skip;
   9.321 +			break;
   9.322  		}
   9.323  #endif
   9.324  #ifdef USE_TIMIDITY_MIDI
   9.325  		if ( timidity_ok ) {
   9.326 -/*printf("Timidity MIDI\n");*/
   9.327 -			music->data.midi = Timidity_LoadSong(file);
   9.328 +			music->data.midi = Timidity_LoadSong_RW(rw, freesrc);
   9.329  			if ( music->data.midi == NULL ) {
   9.330  				Mix_SetError("%s", Timidity_Error());
   9.331  				music->error = 1;
   9.332 @@ -541,92 +712,41 @@
   9.333  			music->error = 1;
   9.334  		}
   9.335  #endif
   9.336 -	} else
   9.337 +		break;
   9.338  #endif
   9.339 -#ifdef OGG_MUSIC
   9.340 -	/* Ogg Vorbis files have the magic four bytes "OggS" */
   9.341 -	if ( (ext && MIX_string_equals(ext, "OGG")) ||
   9.342 -	     strcmp((char *)magic, "OggS") == 0 ) {
   9.343 -		music->type = MUS_OGG;
   9.344 -		music->data.ogg = OGG_new(file);
   9.345 -		if ( music->data.ogg == NULL ) {
   9.346 -			music->error = 1;
   9.347 +#if defined(MODPLUG_MUSIC) || defined(MOD_MUSIC)
   9.348 +	case MUS_MOD:
   9.349 +		music->error = 1;
   9.350 +#ifdef MODPLUG_MUSIC
   9.351 +		if ( music->error ) {
   9.352 +			music->type = MUS_MODPLUG;
   9.353 +			music->data.modplug = modplug_new_RW(rw, freesrc);
   9.354 +			if ( music->data.modplug ) {
   9.355 +				music->error = 0;
   9.356 +			}
   9.357  		}
   9.358 -	} else
   9.359 -#endif
   9.360 -#ifdef FLAC_MUSIC
   9.361 -	/* FLAC files have the magic four bytes "fLaC" */
   9.362 -	if ( (ext && MIX_string_equals(ext, "FLAC")) ||
   9.363 -		 strcmp((char *)magic, "fLaC") == 0 ) {
   9.364 -		music->type = MUS_FLAC;
   9.365 -		music->data.flac = FLAC_new(file);
   9.366 -		if ( music->data.flac == NULL ) {
   9.367 -			music->error = 1;
   9.368 -		}
   9.369 -	} else
   9.370 -#endif
   9.371 -#ifdef MP3_MUSIC
   9.372 -	if ( (ext && MIX_string_equals(ext, "MPG")) ||
   9.373 -	     (ext && MIX_string_equals(ext, "MP3")) ||
   9.374 -	     (ext && MIX_string_equals(ext, "MPEG")) ) {
   9.375 -		if ( Mix_Init(MIX_INIT_MP3) ) {
   9.376 -			SMPEG_Info info;
   9.377 -			music->type = MUS_MP3;
   9.378 -			music->data.mp3 = smpeg.SMPEG_new(file, &info, 0);
   9.379 -			if ( !info.has_audio ) {
   9.380 -				Mix_SetError("MPEG file does not have any audio stream.");
   9.381 -				music->error = 1;
   9.382 -			} else {
   9.383 -				smpeg.SMPEG_actualSpec(music->data.mp3, &used_mixer);
   9.384 -			}
   9.385 -		} else {
   9.386 -			music->error = 1;
   9.387 -		}
   9.388 -	} else
   9.389 -#endif
   9.390 -#ifdef MP3_MAD_MUSIC
   9.391 -	if ( (ext && MIX_string_equals(ext, "MPG")) ||
   9.392 -	     (ext && MIX_string_equals(ext, "MP3")) ||
   9.393 -	     (ext && MIX_string_equals(ext, "MPEG")) ||
   9.394 -	     (ext && MIX_string_equals(ext, "MAD")) ||
   9.395 -	     /* Don't check the magic. Lots of bogus but usable MP3s out there...
   9.396 -	     (magic[0] == 0xFF && (magic[1] & 0xF0) == 0xF0) ||
   9.397 -	     (strncmp((char *)magic, "ID3", 3) == 0)*/ ) {
   9.398 -		music->type = MUS_MP3_MAD;
   9.399 -		music->data.mp3_mad = mad_openFile(file, &used_mixer);
   9.400 -		if (music->data.mp3_mad == 0) {
   9.401 -		    Mix_SetError("Could not initialize MPEG stream.");
   9.402 -			music->error = 1;
   9.403 -		}
   9.404 -	} else
   9.405 -#endif
   9.406 -#ifdef MODPLUG_MUSIC
   9.407 -	if ( 1 ) {
   9.408 -		music->type = MUS_MODPLUG;
   9.409 -		music->data.modplug = modplug_new(file);
   9.410 -		if ( music->data.modplug == NULL ) {
   9.411 -			music->error = 1;
   9.412 -		}
   9.413 -	} else
   9.414  #endif
   9.415  #ifdef MOD_MUSIC
   9.416 -	if ( 1 ) {
   9.417 -		music->type = MUS_MOD;
   9.418 -		music->data.module = MOD_new(file);
   9.419 -		if ( music->data.module == NULL ) {
   9.420 -			music->error = 1;
   9.421 +		if ( music->error ) {
   9.422 +			music->type = MUS_MOD;
   9.423 +			music->data.module = MOD_new_RW(rw, freesrc);
   9.424 +			if ( music->data.module ) {
   9.425 +				music->error = 0;
   9.426 +			}
   9.427  		}
   9.428 -	} else
   9.429  #endif
   9.430 -	{
   9.431 +		break;
   9.432 +#endif
   9.433 +
   9.434 +	default:
   9.435  		Mix_SetError("Unrecognized music format");
   9.436 -		music->error = 1;
   9.437 -	}
   9.438 +		music->error=1;
   9.439 +	} /* switch (want) */
   9.440  
   9.441 -skip:
   9.442 -	if ( music->error ) {
   9.443 +
   9.444 +	if (music->error) {
   9.445  		free(music);
   9.446 -		music = NULL;
   9.447 +		music=NULL;
   9.448  	}
   9.449  	return(music);
   9.450  }
   9.451 @@ -1414,175 +1534,6 @@
   9.452  	ms_per_step = 0;
   9.453  }
   9.454  
   9.455 -Mix_Music *Mix_LoadMUS_RW(SDL_RWops *rw)
   9.456 -{
   9.457 -	Uint8 magic[5];	  /*Apparently there is no way to check if the file is really a MOD,*/
   9.458 -	/*		    or there are too many formats supported by MikMod or MikMod does */
   9.459 -	/*		    this check by itself. If someone implements other formats (e.g. MP3) */
   9.460 -	/*		    the check can be uncommented */
   9.461 -	Uint8 moremagic[9];
   9.462 -	Mix_Music *music;
   9.463 -	int start;
   9.464 -	int freerw = 0;
   9.465 -
   9.466 -	if (!rw) {
   9.467 -		Mix_SetError("RWops pointer is NULL");
   9.468 -		return NULL;
   9.469 -	}
   9.470 -
   9.471 -	/* Figure out what kind of file this is */
   9.472 -	start = SDL_RWtell(rw);
   9.473 -	if ( SDL_RWread(rw,magic,1,4) != 4 ||
   9.474 -	     SDL_RWread(rw,moremagic,1,8) != 8 ) {
   9.475 -		Mix_SetError("Couldn't read from RWops");
   9.476 -		return NULL;
   9.477 -	}
   9.478 -	SDL_RWseek(rw, start, RW_SEEK_SET);
   9.479 -	magic[4]='\0';
   9.480 -	moremagic[8] = '\0';
   9.481 -
   9.482 -	/* Allocate memory for the music structure */
   9.483 -	music=(Mix_Music *)malloc(sizeof(Mix_Music));
   9.484 -	if (music==NULL ) {
   9.485 -		Mix_SetError("Out of memory");
   9.486 -		return(NULL);
   9.487 -	}
   9.488 -	music->error = 0;
   9.489 -
   9.490 -#ifdef WAV_MUSIC
   9.491 -	/* WAVE files have the magic four bytes "RIFF"
   9.492 -	   AIFF files have the magic 12 bytes "FORM" XXXX "AIFF"
   9.493 -	 */
   9.494 -	if ( ((strcmp((char *)magic, "RIFF") == 0) && (strcmp((char *)(moremagic+4), "WAVE") == 0)) ||
   9.495 -	     (strcmp((char *)magic, "FORM") == 0) ) {
   9.496 -		music->type = MUS_WAV;
   9.497 -		music->data.wave = WAVStream_LoadSong_RW(rw, (char *)magic, freerw);
   9.498 -		if ( music->data.wave == NULL ) {
   9.499 -			music->error = 1;
   9.500 -		}
   9.501 -
   9.502 -	} else
   9.503 -#endif
   9.504 -#ifdef OGG_MUSIC
   9.505 -	/* Ogg Vorbis files have the magic four bytes "OggS" */
   9.506 -	if ( strcmp((char *)magic, "OggS") == 0 ) {
   9.507 -		music->type = MUS_OGG;
   9.508 -		music->data.ogg = OGG_new_RW(rw, freerw);
   9.509 -		if ( music->data.ogg == NULL ) {
   9.510 -			music->error = 1;
   9.511 -		}
   9.512 -	} else
   9.513 -#endif
   9.514 -#ifdef FLAC_MUSIC
   9.515 -	/* FLAC files have the magic four bytes "fLaC" */
   9.516 -	if ( strcmp((char *)magic, "fLaC") == 0 ) {
   9.517 -		music->type = MUS_FLAC;
   9.518 -		music->data.flac = FLAC_new_RW(rw, freerw);
   9.519 -		if ( music->data.flac == NULL ) {
   9.520 -			music->error = 1;
   9.521 -		}
   9.522 -	} else
   9.523 -#endif
   9.524 -#ifdef MP3_MUSIC
   9.525 -	if ( ( magic[0] == 0xFF && (magic[1] & 0xF0) == 0xF0) || ( strncmp((char *)magic, "ID3", 3) == 0 ) ) {
   9.526 -		if ( Mix_Init(MIX_INIT_MP3) ) {
   9.527 -			SMPEG_Info info;
   9.528 -			music->type = MUS_MP3;
   9.529 -			music->data.mp3 = smpeg.SMPEG_new_rwops(rw, &info, 0);
   9.530 -			if ( !info.has_audio ) {
   9.531 -				Mix_SetError("MPEG file does not have any audio stream.");
   9.532 -				music->error = 1;
   9.533 -			} else {
   9.534 -				smpeg.SMPEG_actualSpec(music->data.mp3, &used_mixer);
   9.535 -			}
   9.536 -		} else {
   9.537 -			music->error = 1;
   9.538 -		}
   9.539 -	} else
   9.540 -#endif
   9.541 -#ifdef MP3_MAD_MUSIC
   9.542 -	if ( ( magic[0] == 0xFF && (magic[1] & 0xF0) == 0xF0) || ( strncmp((char *)magic, "ID3", 3) == 0 ) ) {
   9.543 -		music->type = MUS_MP3_MAD;
   9.544 -		music->data.mp3_mad = mad_openFileRW(rw, &used_mixer, freerw);
   9.545 -		if (music->data.mp3_mad == 0) {
   9.546 -			Mix_SetError("Could not initialize MPEG stream.");
   9.547 -			music->error = 1;
   9.548 -		}
   9.549 -	} else
   9.550 -#endif
   9.551 -#ifdef MID_MUSIC
   9.552 -	/* MIDI files have the magic four bytes "MThd" */
   9.553 -	if ( strcmp((char *)magic, "MThd") == 0 ) {
   9.554 -		music->type = MUS_MID;
   9.555 -#ifdef USE_NATIVE_MIDI
   9.556 -		if ( native_midi_ok ) {
   9.557 -			music->data.nativemidi = native_midi_loadsong_RW(rw, freerw);
   9.558 -	  		if ( music->data.nativemidi == NULL ) {
   9.559 -		  		Mix_SetError("%s", native_midi_error());
   9.560 -			  	music->error = 1;
   9.561 -			}
   9.562 -			goto skip;
   9.563 -		}
   9.564 -#endif
   9.565 -#ifdef USE_FLUIDSYNTH_MIDI
   9.566 -		if ( fluidsynth_ok ) {
   9.567 -			music->data.fluidsynthmidi = fluidsynth_loadsong_RW(rw, freerw);
   9.568 -			if ( music->data.fluidsynthmidi == NULL ) {
   9.569 -				music->error = 1;
   9.570 -			}
   9.571 -			goto skip;
   9.572 -		}
   9.573 -#endif
   9.574 -#ifdef USE_TIMIDITY_MIDI
   9.575 -		if ( timidity_ok ) {
   9.576 -			music->data.midi = Timidity_LoadSong_RW(rw, freerw);
   9.577 -			if ( music->data.midi == NULL ) {
   9.578 -				Mix_SetError("%s", Timidity_Error());
   9.579 -				music->error = 1;
   9.580 -			}
   9.581 -		} else {
   9.582 -			Mix_SetError("%s", Timidity_Error());
   9.583 -			music->error = 1;
   9.584 -		}
   9.585 -#endif
   9.586 -	} else
   9.587 -#endif
   9.588 -#if defined(MODPLUG_MUSIC) || defined(MOD_MUSIC)
   9.589 -	if (1) {
   9.590 -		music->error = 1;
   9.591 -#ifdef MODPLUG_MUSIC
   9.592 -		if ( music->error ) {
   9.593 -			music->type = MUS_MODPLUG;
   9.594 -			music->data.modplug = modplug_new_RW(rw, freerw);
   9.595 -			if ( music->data.modplug ) {
   9.596 -				music->error = 0;
   9.597 -			}
   9.598 -		}
   9.599 -#endif
   9.600 -#ifdef MOD_MUSIC
   9.601 -		if ( music->error ) {
   9.602 -			music->type = MUS_MOD;
   9.603 -			music->data.module = MOD_new_RW(rw, freerw);
   9.604 -			if ( music->data.module ) {
   9.605 -				music->error = 0;
   9.606 -			}
   9.607 -		}
   9.608 -#endif
   9.609 -	} else
   9.610 -#endif /* MODPLUG_MUSIC || MOD_MUSIC */
   9.611 -	{
   9.612 -		Mix_SetError("Unrecognized music format");
   9.613 -		music->error=1;
   9.614 -	}
   9.615 -
   9.616 -skip:
   9.617 -	if (music->error) {
   9.618 -		free(music);
   9.619 -		music=NULL;
   9.620 -	}
   9.621 -	return(music);
   9.622 -}
   9.623 -
   9.624  int Mix_SetSoundFonts(const char *paths)
   9.625  {
   9.626  #ifdef MID_MUSIC
    10.1 --- a/music_flac.c	Tue Jan 03 16:46:05 2012 -0800
    10.2 +++ b/music_flac.c	Wed Jan 04 00:16:03 2012 -0500
    10.3 @@ -50,19 +50,6 @@
    10.4  	music->volume = volume;
    10.5  }
    10.6  
    10.7 -/* Load an FLAC stream from the given file */
    10.8 -FLAC_music *FLAC_new(const char *file)
    10.9 -{
   10.10 -	SDL_RWops *rw;
   10.11 -
   10.12 -	rw = SDL_RWFromFile (file, "rb");
   10.13 -	if (rw == NULL) {
   10.14 -		SDL_SetError ("Couldn't open %s", file);
   10.15 -		return NULL;
   10.16 -	}
   10.17 -	return FLAC_new_RW (rw, 1);
   10.18 -}
   10.19 -
   10.20  static FLAC__StreamDecoderReadStatus flac_read_music_cb(
   10.21  									const FLAC__StreamDecoder *decoder,
   10.22  									FLAC__byte buffer[],
    11.1 --- a/music_flac.h	Tue Jan 03 16:46:05 2012 -0800
    11.2 +++ b/music_flac.h	Wed Jan 04 00:16:03 2012 -0500
    11.3 @@ -66,9 +66,6 @@
    11.4  /* Set the volume for a FLAC stream */
    11.5  extern void FLAC_setvolume(FLAC_music *music, int volume);
    11.6  
    11.7 -/* Load a FLAC stream from the given file */
    11.8 -extern FLAC_music *FLAC_new(const char *file);
    11.9 -
   11.10  /* Load an FLAC stream from an SDL_RWops object */
   11.11  extern FLAC_music *FLAC_new_RW(SDL_RWops *rw, int freerw);
   11.12  
    12.1 --- a/music_mad.c	Tue Jan 03 16:46:05 2012 -0800
    12.2 +++ b/music_mad.c	Wed Jan 04 00:16:03 2012 -0500
    12.3 @@ -26,20 +26,6 @@
    12.4  #include "music_mad.h"
    12.5  
    12.6  mad_data *
    12.7 -mad_openFile(const char *filename, SDL_AudioSpec *mixer)
    12.8 -{
    12.9 -  SDL_RWops *rw;
   12.10 -  mad_data *mp3_mad;
   12.11 -
   12.12 -  rw = SDL_RWFromFile(filename, "rb");
   12.13 -  if (rw == NULL) {
   12.14 -	return NULL;
   12.15 -  }
   12.16 -
   12.17 -  return mad_openFileRW(rw, mixer, 1);
   12.18 -}
   12.19 -
   12.20 -mad_data *
   12.21  mad_openFileRW(SDL_RWops *rw, SDL_AudioSpec *mixer, int freerw)
   12.22  {
   12.23    mad_data *mp3_mad;
    13.1 --- a/music_mad.h	Tue Jan 03 16:46:05 2012 -0800
    13.2 +++ b/music_mad.h	Wed Jan 04 00:16:03 2012 -0500
    13.3 @@ -58,7 +58,6 @@
    13.4    unsigned char output_buffer[MAD_OUTPUT_BUFFER_SIZE];
    13.5  } mad_data;
    13.6  
    13.7 -mad_data *mad_openFile(const char *filename, SDL_AudioSpec *mixer);
    13.8  mad_data *mad_openFileRW(SDL_RWops *rw, SDL_AudioSpec *mixer, int freerw);
    13.9  void mad_closeFile(mad_data *mp3_mad);
   13.10  
    14.1 --- a/music_mod.c	Tue Jan 03 16:46:05 2012 -0800
    14.2 +++ b/music_mod.c	Wed Jan 04 00:16:03 2012 -0500
    14.3 @@ -141,21 +141,6 @@
    14.4  	mikmod.Player_SetVolume((SWORD)volume);
    14.5  }
    14.6  
    14.7 -/* Load a MOD stream from the given file */
    14.8 -MODULE *MOD_new(const char *file)
    14.9 -{
   14.10 -	SDL_RWops *rw;
   14.11 -
   14.12 -	rw = SDL_RWFromFile(file, "rb");
   14.13 -	if ( rw == NULL ) {
   14.14 -		/* FIXME: Free rw, need to free on delete */
   14.15 -		SDL_SetError("Couldn't open %s", file);
   14.16 -		return NULL;
   14.17 -	}
   14.18 -	return MOD_new_RW(rw, 1);
   14.19 -}
   14.20 -
   14.21 -
   14.22  typedef struct
   14.23  {
   14.24  	MREADER mr;
    15.1 --- a/music_mod.h	Tue Jan 03 16:46:05 2012 -0800
    15.2 +++ b/music_mod.h	Wed Jan 04 00:16:03 2012 -0500
    15.3 @@ -38,9 +38,6 @@
    15.4  /* Set the volume for a MOD stream */
    15.5  extern void MOD_setvolume(struct MODULE *music, int volume);
    15.6  
    15.7 -/* Load a MOD stream from the given file */
    15.8 -extern struct MODULE *MOD_new(const char *file);
    15.9 -
   15.10  /* Load a MOD stream from an SDL_RWops object */
   15.11  extern struct MODULE *MOD_new_RW(SDL_RWops *rw, int freerw);
   15.12  
    16.1 --- a/music_modplug.c	Tue Jan 03 16:46:05 2012 -0800
    16.2 +++ b/music_modplug.c	Wed Jan 04 00:16:03 2012 -0500
    16.3 @@ -74,21 +74,6 @@
    16.4  	ModPlug_SetMasterVolume(music->file, volume*4);
    16.5  }
    16.6  
    16.7 -/* Load a modplug stream from the given file */
    16.8 -modplug_data *modplug_new(const char *file)
    16.9 -{
   16.10 -	SDL_RWops *rw;
   16.11 -
   16.12 -	rw = SDL_RWFromFile(file, "rb");
   16.13 -	if ( rw == NULL ) {
   16.14 -		/* FIXME: Free rw, need to free on delete */
   16.15 -		SDL_SetError("Couldn't open %s", file);
   16.16 -		return NULL;
   16.17 -	}
   16.18 -	return modplug_new_RW(rw, 1);
   16.19 -
   16.20 -}
   16.21 -
   16.22  /* Load a modplug stream from an SDL_RWops object */
   16.23  modplug_data *modplug_new_RW(SDL_RWops *rw, int freerw)
   16.24  {
    17.1 --- a/music_modplug.h	Tue Jan 03 16:46:05 2012 -0800
    17.2 +++ b/music_modplug.h	Wed Jan 04 00:16:03 2012 -0500
    17.3 @@ -18,9 +18,6 @@
    17.4  /* Set the volume for a modplug stream */
    17.5  void modplug_setvolume(modplug_data *music, int volume);
    17.6  
    17.7 -/* Load a modplug stream from the given file */
    17.8 -modplug_data *modplug_new(const char *file);
    17.9 -
   17.10  /* Load a modplug stream from an SDL_RWops object */
   17.11  modplug_data *modplug_new_RW(SDL_RWops *rw, int freerw);
   17.12  
    18.1 --- a/music_ogg.c	Tue Jan 03 16:46:05 2012 -0800
    18.2 +++ b/music_ogg.c	Wed Jan 04 00:16:03 2012 -0500
    18.3 @@ -51,20 +51,6 @@
    18.4  	music->volume = volume;
    18.5  }
    18.6  
    18.7 -/* Load an OGG stream from the given file */
    18.8 -OGG_music *OGG_new(const char *file)
    18.9 -{
   18.10 -	SDL_RWops *rw;
   18.11 -
   18.12 -	rw = SDL_RWFromFile(file, "rb");
   18.13 -	if ( rw == NULL ) {
   18.14 -		SDL_SetError("Couldn't open %s", file);
   18.15 -		return NULL;
   18.16 -	}
   18.17 -	return OGG_new_RW(rw, 1);
   18.18 -}
   18.19 -
   18.20 -
   18.21  static size_t sdl_read_func(void *ptr, size_t size, size_t nmemb, void *datasource)
   18.22  {
   18.23      return SDL_RWread((SDL_RWops*)datasource, ptr, size, nmemb);
    19.1 --- a/music_ogg.h	Tue Jan 03 16:46:05 2012 -0800
    19.2 +++ b/music_ogg.h	Wed Jan 04 00:16:03 2012 -0500
    19.3 @@ -51,9 +51,6 @@
    19.4  /* Set the volume for an OGG stream */
    19.5  extern void OGG_setvolume(OGG_music *music, int volume);
    19.6  
    19.7 -/* Load an OGG stream from the given file */
    19.8 -extern OGG_music *OGG_new(const char *file);
    19.9 -
   19.10  /* Load an OGG stream from an SDL_RWops object */
   19.11  extern OGG_music *OGG_new_RW(SDL_RWops *rw, int freerw);
   19.12  
    20.1 --- a/native_midi/native_midi.h	Tue Jan 03 16:46:05 2012 -0800
    20.2 +++ b/native_midi/native_midi.h	Wed Jan 04 00:16:03 2012 -0500
    20.3 @@ -27,7 +27,6 @@
    20.4  typedef struct _NativeMidiSong NativeMidiSong;
    20.5  
    20.6  int native_midi_detect();
    20.7 -NativeMidiSong *native_midi_loadsong(const char *midifile);
    20.8  NativeMidiSong *native_midi_loadsong_RW(SDL_RWops *rw, int freerw);
    20.9  void native_midi_freesong(NativeMidiSong *song);
   20.10  void native_midi_start(NativeMidiSong *song, int loops);
    21.1 --- a/native_midi/native_midi_haiku.cpp	Tue Jan 03 16:46:05 2012 -0800
    21.2 +++ b/native_midi/native_midi_haiku.cpp	Wed Jan 04 00:16:03 2012 -0500
    21.3 @@ -238,13 +238,6 @@
    21.4    return song;
    21.5  }
    21.6  
    21.7 -NativeMidiSong *native_midi_loadsong(const char *midifile)
    21.8 -{
    21.9 -  SDL_RWops *rw = SDL_RWFromFile(midifile, "rb");
   21.10 -  if (!rw) return NULL;
   21.11 -  return native_midi_loadsong_RW(rw, 1);
   21.12 -}
   21.13 -
   21.14  void native_midi_freesong(NativeMidiSong *song)
   21.15  {
   21.16    if (song == NULL) return;
    22.1 --- a/native_midi/native_midi_mac.c	Tue Jan 03 16:46:05 2012 -0800
    22.2 +++ b/native_midi/native_midi_mac.c	Wed Jan 04 00:16:03 2012 -0500
    22.3 @@ -88,18 +88,6 @@
    22.4  	return 1;
    22.5  }
    22.6  
    22.7 -NativeMidiSong *native_midi_loadsong(const char *midifile)
    22.8 -{
    22.9 -	SDL_RWops *rw;
   22.10 -
   22.11 -	/* Attempt to load the midi file */
   22.12 -	rw = SDL_RWFromFile(midifile, "rb");
   22.13 -	if (!rw) {
   22.14 -		return NULL;
   22.15 -	}
   22.16 -	return native_midi_loadsong_RW(rw, 1);
   22.17 -}
   22.18 -
   22.19  NativeMidiSong *native_midi_loadsong_RW(SDL_RWops *rw, int freerw)
   22.20  {
   22.21  	NativeMidiSong	*song = NULL;
    23.1 --- a/native_midi/native_midi_macosx.c	Tue Jan 03 16:46:05 2012 -0800
    23.2 +++ b/native_midi/native_midi_macosx.c	Wed Jan 04 00:16:03 2012 -0500
    23.3 @@ -145,17 +145,6 @@
    23.4      return 1;  /* always available. */
    23.5  }
    23.6  
    23.7 -NativeMidiSong *native_midi_loadsong(const char *midifile)
    23.8 -{
    23.9 -    NativeMidiSong *retval = NULL;
   23.10 -    SDL_RWops *rw = SDL_RWFromFile(midifile, "rb");
   23.11 -    if (rw != NULL) {
   23.12 -        retval = native_midi_loadsong_RW(rw, 1);
   23.13 -    }
   23.14 -
   23.15 -    return retval;
   23.16 -}
   23.17 -
   23.18  NativeMidiSong *native_midi_loadsong_RW(SDL_RWops *rw, int freerw)
   23.19  {
   23.20      NativeMidiSong *retval = NULL;
    24.1 --- a/native_midi/native_midi_win32.c	Tue Jan 03 16:46:05 2012 -0800
    24.2 +++ b/native_midi/native_midi_win32.c	Wed Jan 04 00:16:03 2012 -0500
    24.3 @@ -200,18 +200,6 @@
    24.4    return 1;
    24.5  }
    24.6  
    24.7 -NativeMidiSong *native_midi_loadsong(const char *midifile)
    24.8 -{
    24.9 -	SDL_RWops *rw;
   24.10 -
   24.11 -	/* Attempt to load the midi file */
   24.12 -	rw = SDL_RWFromFile(midifile, "rb");
   24.13 -	if (!rw) {
   24.14 -		return NULL;
   24.15 -	}
   24.16 -	return native_midi_loadsong_RW(rw, 1);
   24.17 -}
   24.18 -
   24.19  NativeMidiSong *native_midi_loadsong_RW(SDL_RWops *rw, int freerw)
   24.20  {
   24.21  	NativeMidiSong *newsong;
    25.1 --- a/timidity/playmidi.c	Tue Jan 03 16:46:05 2012 -0800
    25.2 +++ b/timidity/playmidi.c	Wed Jan 04 00:16:03 2012 -0500
    25.3 @@ -1676,33 +1676,6 @@
    25.4    ctl->master_volume(amplification);
    25.5  }
    25.6  
    25.7 -MidiSong *Timidity_LoadSong(const char *midifile)
    25.8 -{
    25.9 -  MidiSong *song;
   25.10 -  int32 events;
   25.11 -  SDL_RWops *rw;
   25.12 -
   25.13 -  /* Allocate memory for the song */
   25.14 -  song = (MidiSong *)safe_malloc(sizeof(*song));
   25.15 -  memset(song, 0, sizeof(*song));
   25.16 -
   25.17 -  /* Open the file */
   25.18 -  strcpy(midi_name, midifile);
   25.19 -
   25.20 -  rw = SDL_RWFromFile(midifile, "rb");
   25.21 -  if ( rw != NULL ) {
   25.22 -    song->events=read_midi_file(rw, &events, &song->samples);
   25.23 -    SDL_RWclose(rw);
   25.24 -  }
   25.25 -
   25.26 -  /* Make sure everything is okay */
   25.27 -  if (!song->events) {
   25.28 -    free(song);
   25.29 -    song = NULL;
   25.30 -  }
   25.31 -  return(song);
   25.32 -}
   25.33 -
   25.34  MidiSong *Timidity_LoadSong_RW(SDL_RWops *rw, int freerw)
   25.35  {
   25.36    MidiSong *song;
    26.1 --- a/timidity/timidity.h	Tue Jan 03 16:46:05 2012 -0800
    26.2 +++ b/timidity/timidity.h	Wed Jan 04 00:16:03 2012 -0500
    26.3 @@ -12,7 +12,6 @@
    26.4  extern const char *Timidity_Error(void);
    26.5  extern void Timidity_SetVolume(int volume);
    26.6  extern int Timidity_PlaySome(void *stream, int samples);
    26.7 -extern MidiSong *Timidity_LoadSong(const char *midifile);
    26.8  extern MidiSong *Timidity_LoadSong_RW(SDL_RWops *rw, int freerw);
    26.9  extern void Timidity_Start(MidiSong *song);
   26.10  extern int Timidity_Active(void);
    27.1 --- a/wavestream.c	Tue Jan 03 16:46:05 2012 -0800
    27.2 +++ b/wavestream.c	Wed Jan 04 00:16:03 2012 -0500
    27.3 @@ -113,19 +113,7 @@
    27.4  	wavestream_volume = volume;
    27.5  }
    27.6  
    27.7 -WAVStream *WAVStream_LoadSong(const char *file, const char *magic)
    27.8 -{
    27.9 -	SDL_RWops *rw;
   27.10 -
   27.11 -	rw = SDL_RWFromFile(file, "rb");
   27.12 -	if ( rw == NULL ) {
   27.13 -		SDL_SetError("Couldn't open %s", file);
   27.14 -		return NULL;
   27.15 -	}
   27.16 -	return WAVStream_LoadSong_RW(rw, magic, 1);
   27.17 -}
   27.18 -
   27.19 -/* Load a WAV stream from the given file */
   27.20 +/* Load a WAV stream from the given RWops object */
   27.21  WAVStream *WAVStream_LoadSong_RW(SDL_RWops *rw, const char *magic, int freerw)
   27.22  {
   27.23  	WAVStream *wave;
    28.1 --- a/wavestream.h	Tue Jan 03 16:46:05 2012 -0800
    28.2 +++ b/wavestream.h	Wed Jan 04 00:16:03 2012 -0500
    28.3 @@ -41,9 +41,6 @@
    28.4  /* Unimplemented */
    28.5  extern void WAVStream_SetVolume(int volume);
    28.6  
    28.7 -/* Load a WAV stream from the given file */
    28.8 -extern WAVStream *WAVStream_LoadSong(const char *file, const char *magic);
    28.9 -
   28.10  /* Load a WAV stream from an SDL_RWops object */
   28.11  extern WAVStream *WAVStream_LoadSong_RW(SDL_RWops *rw, const char *magic, int freerw);
   28.12