music.c
changeset 616 7ead8213dfb0
parent 613 6fa075aa693e
child 621 944412baab72
equal deleted inserted replaced
615:4c87c4fabeb5 616:7ead8213dfb0
    78 static char *music_cmd = NULL;
    78 static char *music_cmd = NULL;
    79 static Mix_Music * volatile music_playing = NULL;
    79 static Mix_Music * volatile music_playing = NULL;
    80 static int music_volume = MIX_MAX_VOLUME;
    80 static int music_volume = MIX_MAX_VOLUME;
    81 
    81 
    82 struct _Mix_Music {
    82 struct _Mix_Music {
    83 	Mix_MusicType type;
    83     Mix_MusicType type;
    84 	union {
    84     union {
    85 #ifdef CMD_MUSIC
    85 #ifdef CMD_MUSIC
    86 		MusicCMD *cmd;
    86         MusicCMD *cmd;
    87 #endif
    87 #endif
    88 #ifdef WAV_MUSIC
    88 #ifdef WAV_MUSIC
    89 		WAVStream *wave;
    89         WAVStream *wave;
    90 #endif
    90 #endif
    91 #ifdef MODPLUG_MUSIC
    91 #ifdef MODPLUG_MUSIC
    92 		modplug_data *modplug;
    92         modplug_data *modplug;
    93 #endif
    93 #endif
    94 #ifdef MOD_MUSIC
    94 #ifdef MOD_MUSIC
    95 		struct MODULE *module;
    95         struct MODULE *module;
    96 #endif
    96 #endif
    97 #ifdef MID_MUSIC
    97 #ifdef MID_MUSIC
    98 #ifdef USE_TIMIDITY_MIDI
    98 #ifdef USE_TIMIDITY_MIDI
    99 		MidiSong *midi;
    99         MidiSong *midi;
   100 #endif
   100 #endif
   101 #ifdef USE_FLUIDSYNTH_MIDI
   101 #ifdef USE_FLUIDSYNTH_MIDI
   102 		FluidSynthMidiSong *fluidsynthmidi;
   102         FluidSynthMidiSong *fluidsynthmidi;
   103 #endif
   103 #endif
   104 #ifdef USE_NATIVE_MIDI
   104 #ifdef USE_NATIVE_MIDI
   105 		NativeMidiSong *nativemidi;
   105         NativeMidiSong *nativemidi;
   106 #endif
   106 #endif
   107 #endif
   107 #endif
   108 #ifdef OGG_MUSIC
   108 #ifdef OGG_MUSIC
   109 		OGG_music *ogg;
   109         OGG_music *ogg;
   110 #endif
   110 #endif
   111 #ifdef MP3_MUSIC
   111 #ifdef MP3_MUSIC
   112 		SMPEG *mp3;
   112         SMPEG *mp3;
   113 #endif
   113 #endif
   114 #ifdef MP3_MAD_MUSIC
   114 #ifdef MP3_MAD_MUSIC
   115 		mad_data *mp3_mad;
   115         mad_data *mp3_mad;
   116 #endif
   116 #endif
   117 #ifdef FLAC_MUSIC
   117 #ifdef FLAC_MUSIC
   118 		FLAC_music *flac;
   118         FLAC_music *flac;
   119 #endif
   119 #endif
   120 	} data;
   120     } data;
   121 	Mix_Fading fading;
   121     Mix_Fading fading;
   122 	int fade_step;
   122     int fade_step;
   123 	int fade_steps;
   123     int fade_steps;
   124 	int error;
   124     int error;
   125 };
   125 };
   126 #ifdef MID_MUSIC
   126 #ifdef MID_MUSIC
   127 #ifdef USE_TIMIDITY_MIDI
   127 #ifdef USE_TIMIDITY_MIDI
   128 static int timidity_ok;
   128 static int timidity_ok;
   129 static int samplesize;
   129 static int samplesize;
   148 char* soundfont_paths = NULL;
   148 char* soundfont_paths = NULL;
   149 #endif
   149 #endif
   150 
   150 
   151 int Mix_GetNumMusicDecoders(void)
   151 int Mix_GetNumMusicDecoders(void)
   152 {
   152 {
   153 	return(num_decoders);
   153     return(num_decoders);
   154 }
   154 }
   155 
   155 
   156 const char *Mix_GetMusicDecoder(int index)
   156 const char *Mix_GetMusicDecoder(int index)
   157 {
   157 {
   158 	if ((index < 0) || (index >= num_decoders)) {
   158     if ((index < 0) || (index >= num_decoders)) {
   159 		return NULL;
   159         return NULL;
   160 	}
   160     }
   161 	return(music_decoders[index]);
   161     return(music_decoders[index]);
   162 }
   162 }
   163 
   163 
   164 static void add_music_decoder(const char *decoder)
   164 static void add_music_decoder(const char *decoder)
   165 {
   165 {
   166 	void *ptr = SDL_realloc(music_decoders, (num_decoders + 1) * sizeof (const char **));
   166     void *ptr = SDL_realloc(music_decoders, (num_decoders + 1) * sizeof (const char **));
   167 	if (ptr == NULL) {
   167     if (ptr == NULL) {
   168 		return;  /* oh well, go on without it. */
   168         return;  /* oh well, go on without it. */
   169 	}
   169     }
   170 	music_decoders = (const char **) ptr;
   170     music_decoders = (const char **) ptr;
   171 	music_decoders[num_decoders++] = decoder;
   171     music_decoders[num_decoders++] = decoder;
   172 }
   172 }
   173 
   173 
   174 /* Local low-level functions prototypes */
   174 /* Local low-level functions prototypes */
   175 static void music_internal_initialize_volume(void);
   175 static void music_internal_initialize_volume(void);
   176 static void music_internal_volume(int volume);
   176 static void music_internal_volume(int volume);
   183 /* Support for hooking when the music has finished */
   183 /* Support for hooking when the music has finished */
   184 static void (*music_finished_hook)(void) = NULL;
   184 static void (*music_finished_hook)(void) = NULL;
   185 
   185 
   186 void Mix_HookMusicFinished(void (*music_finished)(void))
   186 void Mix_HookMusicFinished(void (*music_finished)(void))
   187 {
   187 {
   188 	SDL_LockAudio();
   188     SDL_LockAudio();
   189 	music_finished_hook = music_finished;
   189     music_finished_hook = music_finished;
   190 	SDL_UnlockAudio();
   190     SDL_UnlockAudio();
   191 }
   191 }
   192 
   192 
   193 
   193 
   194 /* If music isn't playing, halt it if no looping is required, restart it */
   194 /* If music isn't playing, halt it if no looping is required, restart it */
   195 /* otherwhise. NOP if the music is playing */
   195 /* otherwhise. NOP if the music is playing */
   196 static int music_halt_or_loop (void)
   196 static int music_halt_or_loop (void)
   197 {
   197 {
   198 	/* Restart music if it has to loop */
   198     /* Restart music if it has to loop */
   199 	
   199 
   200 	if (!music_internal_playing()) 
   200     if (!music_internal_playing())
   201 	{
   201     {
   202 #ifdef USE_NATIVE_MIDI
   202 #ifdef USE_NATIVE_MIDI
   203 		/* Native MIDI handles looping internally */
   203         /* Native MIDI handles looping internally */
   204 		if (music_playing->type == MUS_MID && native_midi_ok) {
   204         if (music_playing->type == MUS_MID && native_midi_ok) {
   205 			music_loops = 0;
   205             music_loops = 0;
   206 		}
   206         }
   207 #endif
   207 #endif
   208 
   208 
   209 		/* Restart music if it has to loop at a high level */
   209         /* Restart music if it has to loop at a high level */
   210 		if (music_loops)
   210         if (music_loops)
   211 		{
   211         {
   212 			Mix_Fading current_fade;
   212             Mix_Fading current_fade;
   213 			--music_loops;
   213             --music_loops;
   214 			current_fade = music_playing->fading;
   214             current_fade = music_playing->fading;
   215 			music_internal_play(music_playing, 0.0);
   215             music_internal_play(music_playing, 0.0);
   216 			music_playing->fading = current_fade;
   216             music_playing->fading = current_fade;
   217 		} 
   217         }
   218 		else 
   218         else
   219 		{
   219         {
   220 			music_internal_halt();
   220             music_internal_halt();
   221 			if (music_finished_hook)
   221             if (music_finished_hook)
   222 				music_finished_hook();
   222                 music_finished_hook();
   223 			
   223 
   224 			return 0;
   224             return 0;
   225 		}
   225         }
   226 	}
   226     }
   227 	
   227 
   228 	return 1;
   228     return 1;
   229 }
   229 }
   230 
   230 
   231 
   231 
   232 
   232 
   233 /* Mixing function */
   233 /* Mixing function */
   234 void music_mixer(void *udata, Uint8 *stream, int len)
   234 void music_mixer(void *udata, Uint8 *stream, int len)
   235 {
   235 {
   236 	int left = 0;
   236     int left = 0;
   237 
   237 
   238 	if ( music_playing && music_active ) {
   238     if ( music_playing && music_active ) {
   239 		/* Handle fading */
   239         /* Handle fading */
   240 		if ( music_playing->fading != MIX_NO_FADING ) {
   240         if ( music_playing->fading != MIX_NO_FADING ) {
   241 			if ( music_playing->fade_step++ < music_playing->fade_steps ) {
   241             if ( music_playing->fade_step++ < music_playing->fade_steps ) {
   242 				int volume;
   242                 int volume;
   243 				int fade_step = music_playing->fade_step;
   243                 int fade_step = music_playing->fade_step;
   244 				int fade_steps = music_playing->fade_steps;
   244                 int fade_steps = music_playing->fade_steps;
   245 
   245 
   246 				if ( music_playing->fading == MIX_FADING_OUT ) {
   246                 if ( music_playing->fading == MIX_FADING_OUT ) {
   247 					volume = (music_volume * (fade_steps-fade_step)) / fade_steps;
   247                     volume = (music_volume * (fade_steps-fade_step)) / fade_steps;
   248 				} else { /* Fading in */
   248                 } else { /* Fading in */
   249 					volume = (music_volume * fade_step) / fade_steps;
   249                     volume = (music_volume * fade_step) / fade_steps;
   250 				}
   250                 }
   251 				music_internal_volume(volume);
   251                 music_internal_volume(volume);
   252 			} else {
   252             } else {
   253 				if ( music_playing->fading == MIX_FADING_OUT ) {
   253                 if ( music_playing->fading == MIX_FADING_OUT ) {
   254 					music_internal_halt();
   254                     music_internal_halt();
   255 					if ( music_finished_hook ) {
   255                     if ( music_finished_hook ) {
   256 						music_finished_hook();
   256                         music_finished_hook();
   257 					}
   257                     }
   258 					return;
   258                     return;
   259 				}
   259                 }
   260 				music_playing->fading = MIX_NO_FADING;
   260                 music_playing->fading = MIX_NO_FADING;
   261 			}
   261             }
   262 		}
   262         }
   263 		
   263 
   264 		music_halt_or_loop();
   264         music_halt_or_loop();
   265 		if (!music_internal_playing())
   265         if (!music_internal_playing())
   266 			return;
   266             return;
   267 
   267 
   268 		switch (music_playing->type) {
   268         switch (music_playing->type) {
   269 #ifdef CMD_MUSIC
   269 #ifdef CMD_MUSIC
   270 			case MUS_CMD:
   270             case MUS_CMD:
   271 				/* The playing is done externally */
   271                 /* The playing is done externally */
   272 				break;
   272                 break;
   273 #endif
   273 #endif
   274 #ifdef WAV_MUSIC
   274 #ifdef WAV_MUSIC
   275 			case MUS_WAV:
   275             case MUS_WAV:
   276 				left = WAVStream_PlaySome(stream, len);
   276                 left = WAVStream_PlaySome(stream, len);
   277 				break;
   277                 break;
   278 #endif
   278 #endif
   279 #ifdef MODPLUG_MUSIC
   279 #ifdef MODPLUG_MUSIC
   280 			case MUS_MODPLUG:
   280             case MUS_MODPLUG:
   281 				left = modplug_playAudio(music_playing->data.modplug, stream, len);
   281                 left = modplug_playAudio(music_playing->data.modplug, stream, len);
   282 				break;
   282                 break;
   283 #endif
   283 #endif
   284 #ifdef MOD_MUSIC
   284 #ifdef MOD_MUSIC
   285 			case MUS_MOD:
   285             case MUS_MOD:
   286 				left = MOD_playAudio(music_playing->data.module, stream, len);
   286                 left = MOD_playAudio(music_playing->data.module, stream, len);
   287 				break;
   287                 break;
   288 #endif
   288 #endif
   289 #ifdef MID_MUSIC
   289 #ifdef MID_MUSIC
   290 			case MUS_MID:
   290             case MUS_MID:
   291 #ifdef USE_NATIVE_MIDI
   291 #ifdef USE_NATIVE_MIDI
   292   				if ( native_midi_ok ) {
   292                 if ( native_midi_ok ) {
   293 					/* Native midi is handled asynchronously */
   293                     /* Native midi is handled asynchronously */
   294 					goto skip;
   294                     goto skip;
   295 	  			}
   295                 }
   296 #endif
   296 #endif
   297 #ifdef USE_FLUIDSYNTH_MIDI
   297 #ifdef USE_FLUIDSYNTH_MIDI
   298 				if ( fluidsynth_ok ) {
   298                 if ( fluidsynth_ok ) {
   299 					fluidsynth_playsome(music_playing->data.fluidsynthmidi, stream, len);
   299                     fluidsynth_playsome(music_playing->data.fluidsynthmidi, stream, len);
   300 					goto skip;
   300                     goto skip;
   301 				}
   301                 }
   302 #endif
   302 #endif
   303 #ifdef USE_TIMIDITY_MIDI
   303 #ifdef USE_TIMIDITY_MIDI
   304 				if ( timidity_ok ) {
   304                 if ( timidity_ok ) {
   305 					int samples = len / samplesize;
   305                     int samples = len / samplesize;
   306   					Timidity_PlaySome(stream, samples);
   306                     Timidity_PlaySome(stream, samples);
   307 					goto skip;
   307                     goto skip;
   308 				}
   308                 }
   309 #endif
   309 #endif
   310 				break;
   310                 break;
   311 #endif
   311 #endif
   312 #ifdef OGG_MUSIC
   312 #ifdef OGG_MUSIC
   313 			case MUS_OGG:
   313             case MUS_OGG:
   314 				
   314 
   315 				left = OGG_playAudio(music_playing->data.ogg, stream, len);
   315                 left = OGG_playAudio(music_playing->data.ogg, stream, len);
   316 				break;
   316                 break;
   317 #endif
   317 #endif
   318 #ifdef FLAC_MUSIC
   318 #ifdef FLAC_MUSIC
   319 			case MUS_FLAC:
   319             case MUS_FLAC:
   320 				left = FLAC_playAudio(music_playing->data.flac, stream, len);
   320                 left = FLAC_playAudio(music_playing->data.flac, stream, len);
   321 				break;
   321                 break;
   322 #endif
   322 #endif
   323 #ifdef MP3_MUSIC
   323 #ifdef MP3_MUSIC
   324 			case MUS_MP3:
   324             case MUS_MP3:
   325 				left = (len - smpeg.SMPEG_playAudio(music_playing->data.mp3, stream, len));
   325                 left = (len - smpeg.SMPEG_playAudio(music_playing->data.mp3, stream, len));
   326 				break;
   326                 break;
   327 #endif
   327 #endif
   328 #ifdef MP3_MAD_MUSIC
   328 #ifdef MP3_MAD_MUSIC
   329 			case MUS_MP3_MAD:
   329             case MUS_MP3_MAD:
   330 				left = mad_getSamples(music_playing->data.mp3_mad, stream, len);
   330                 left = mad_getSamples(music_playing->data.mp3_mad, stream, len);
   331 				break;
   331                 break;
   332 #endif
   332 #endif
   333 			default:
   333             default:
   334 				/* Unknown music type?? */
   334                 /* Unknown music type?? */
   335 				break;
   335                 break;
   336 		}
   336         }
   337 	}
   337     }
   338 
   338 
   339 skip:
   339 skip:
   340 	/* Handle seamless music looping */
   340     /* Handle seamless music looping */
   341 	if (left > 0 && left < len) {
   341     if (left > 0 && left < len) {
   342 		music_halt_or_loop();
   342         music_halt_or_loop();
   343 		if (music_internal_playing())
   343         if (music_internal_playing())
   344 			music_mixer(udata, stream+(len-left), left);
   344             music_mixer(udata, stream+(len-left), left);
   345 	}
   345     }
   346 }
   346 }
   347 
   347 
   348 /* Initialize the music players with a certain desired audio format */
   348 /* Initialize the music players with a certain desired audio format */
   349 int open_music(SDL_AudioSpec *mixer)
   349 int open_music(SDL_AudioSpec *mixer)
   350 {
   350 {
   351 #ifdef WAV_MUSIC
   351 #ifdef WAV_MUSIC
   352 	if ( WAVStream_Init(mixer) == 0 ) {
   352     if ( WAVStream_Init(mixer) == 0 ) {
   353 		add_music_decoder("WAVE");
   353         add_music_decoder("WAVE");
   354 	}
   354     }
   355 #endif
   355 #endif
   356 #ifdef MODPLUG_MUSIC
   356 #ifdef MODPLUG_MUSIC
   357 	if ( modplug_init(mixer) == 0 ) {
   357     if ( modplug_init(mixer) == 0 ) {
   358 		add_music_decoder("MODPLUG");
   358         add_music_decoder("MODPLUG");
   359 	}
   359     }
   360 #endif
   360 #endif
   361 #ifdef MOD_MUSIC
   361 #ifdef MOD_MUSIC
   362 	if ( MOD_init(mixer) == 0 ) {
   362     if ( MOD_init(mixer) == 0 ) {
   363 		add_music_decoder("MIKMOD");
   363         add_music_decoder("MIKMOD");
   364 	}
   364     }
   365 #endif
   365 #endif
   366 #ifdef MID_MUSIC
   366 #ifdef MID_MUSIC
   367 #ifdef USE_TIMIDITY_MIDI
   367 #ifdef USE_TIMIDITY_MIDI
   368 	samplesize = mixer->size / mixer->samples;
   368     samplesize = mixer->size / mixer->samples;
   369 	if ( Timidity_Init(mixer->freq, mixer->format,
   369     if ( Timidity_Init(mixer->freq, mixer->format,
   370 	                    mixer->channels, mixer->samples) == 0 ) {
   370                         mixer->channels, mixer->samples) == 0 ) {
   371 		timidity_ok = 1;
   371         timidity_ok = 1;
   372 		add_music_decoder("TIMIDITY");
   372         add_music_decoder("TIMIDITY");
   373 	} else {
   373     } else {
   374 		timidity_ok = 0;
   374         timidity_ok = 0;
   375 	}
   375     }
   376 #endif
   376 #endif
   377 #ifdef USE_FLUIDSYNTH_MIDI
   377 #ifdef USE_FLUIDSYNTH_MIDI
   378 	if ( fluidsynth_init(mixer) == 0 ) {
   378     if ( fluidsynth_init(mixer) == 0 ) {
   379 		fluidsynth_ok = 1;
   379         fluidsynth_ok = 1;
   380 		add_music_decoder("FLUIDSYNTH");
   380         add_music_decoder("FLUIDSYNTH");
   381 	} else {
   381     } else {
   382 		fluidsynth_ok = 0;
   382         fluidsynth_ok = 0;
   383 	}
   383     }
   384 #endif
   384 #endif
   385 #ifdef USE_NATIVE_MIDI
   385 #ifdef USE_NATIVE_MIDI
   386 #ifdef USE_FLUIDSYNTH_MIDI
   386 #ifdef USE_FLUIDSYNTH_MIDI
   387 	native_midi_ok = !fluidsynth_ok;
   387     native_midi_ok = !fluidsynth_ok;
   388 	if ( native_midi_ok )
   388     if ( native_midi_ok )
   389 #endif
   389 #endif
   390 #ifdef USE_TIMIDITY_MIDI
   390 #ifdef USE_TIMIDITY_MIDI
   391 		native_midi_ok = !timidity_ok;
   391         native_midi_ok = !timidity_ok;
   392 	if ( !native_midi_ok ) {
   392     if ( !native_midi_ok ) {
   393 		native_midi_ok = (getenv("SDL_NATIVE_MUSIC") != NULL);
   393         native_midi_ok = (getenv("SDL_NATIVE_MUSIC") != NULL);
   394 	}
   394     }
   395 	if ( native_midi_ok )
   395     if ( native_midi_ok )
   396 #endif
   396 #endif
   397 		native_midi_ok = native_midi_detect();
   397         native_midi_ok = native_midi_detect();
   398 	if ( native_midi_ok )
   398     if ( native_midi_ok )
   399 		add_music_decoder("NATIVEMIDI");
   399         add_music_decoder("NATIVEMIDI");
   400 #endif
   400 #endif
   401 #endif
   401 #endif
   402 #ifdef OGG_MUSIC
   402 #ifdef OGG_MUSIC
   403 	if ( OGG_init(mixer) == 0 ) {
   403     if ( OGG_init(mixer) == 0 ) {
   404 		add_music_decoder("OGG");
   404         add_music_decoder("OGG");
   405 	}
   405     }
   406 #endif
   406 #endif
   407 #ifdef FLAC_MUSIC
   407 #ifdef FLAC_MUSIC
   408 	if ( FLAC_init(mixer) == 0 ) {
   408     if ( FLAC_init(mixer) == 0 ) {
   409 		add_music_decoder("FLAC");
   409         add_music_decoder("FLAC");
   410 	}
   410     }
   411 #endif
   411 #endif
   412 #if defined(MP3_MUSIC) || defined(MP3_MAD_MUSIC)
   412 #if defined(MP3_MUSIC) || defined(MP3_MAD_MUSIC)
   413 	/* Keep a copy of the mixer */
   413     /* Keep a copy of the mixer */
   414 	used_mixer = *mixer;
   414     used_mixer = *mixer;
   415 	add_music_decoder("MP3");
   415     add_music_decoder("MP3");
   416 #endif
   416 #endif
   417 
   417 
   418 	music_playing = NULL;
   418     music_playing = NULL;
   419 	music_stopped = 0;
   419     music_stopped = 0;
   420 	Mix_VolumeMusic(SDL_MIX_MAXVOLUME);
   420     Mix_VolumeMusic(SDL_MIX_MAXVOLUME);
   421 
   421 
   422 	/* Calculate the number of ms for each callback */
   422     /* Calculate the number of ms for each callback */
   423 	ms_per_step = (int) (((float)mixer->samples * 1000.0) / mixer->freq);
   423     ms_per_step = (int) (((float)mixer->samples * 1000.0) / mixer->freq);
   424 
   424 
   425 	return(0);
   425     return(0);
   426 }
   426 }
   427 
   427 
   428 /* Portable case-insensitive string compare function */
   428 /* Portable case-insensitive string compare function */
   429 int MIX_string_equals(const char *str1, const char *str2)
   429 int MIX_string_equals(const char *str1, const char *str2)
   430 {
   430 {
   431 	while ( *str1 && *str2 ) {
   431     while ( *str1 && *str2 ) {
   432 		if ( toupper((unsigned char)*str1) !=
   432         if ( toupper((unsigned char)*str1) !=
   433 		     toupper((unsigned char)*str2) )
   433              toupper((unsigned char)*str2) )
   434 			break;
   434             break;
   435 		++str1;
   435         ++str1;
   436 		++str2;
   436         ++str2;
   437 	}
   437     }
   438 	return (!*str1 && !*str2);
   438     return (!*str1 && !*str2);
   439 }
   439 }
   440 
   440 
   441 static int detect_mp3(Uint8 *magic)
   441 static int detect_mp3(Uint8 *magic)
   442 {
   442 {
   443 	if ( strncmp((char *)magic, "ID3", 3) == 0 ) {
   443     if ( strncmp((char *)magic, "ID3", 3) == 0 ) {
   444 		return 1;
   444         return 1;
   445 	}
   445     }
   446 
   446 
   447 	/* Detection code lifted from SMPEG */
   447     /* Detection code lifted from SMPEG */
   448 	if(((magic[0] & 0xff) != 0xff) || // No sync bits
   448     if(((magic[0] & 0xff) != 0xff) || // No sync bits
   449 	   ((magic[1] & 0xf0) != 0xf0) || //
   449        ((magic[1] & 0xf0) != 0xf0) || //
   450 	   ((magic[2] & 0xf0) == 0x00) || // Bitrate is 0
   450        ((magic[2] & 0xf0) == 0x00) || // Bitrate is 0
   451 	   ((magic[2] & 0xf0) == 0xf0) || // Bitrate is 15
   451        ((magic[2] & 0xf0) == 0xf0) || // Bitrate is 15
   452 	   ((magic[2] & 0x0c) == 0x0c) || // Frequency is 3
   452        ((magic[2] & 0x0c) == 0x0c) || // Frequency is 3
   453 	   ((magic[1] & 0x06) == 0x00)) { // Layer is 4
   453        ((magic[1] & 0x06) == 0x00)) { // Layer is 4
   454 		return(0);
   454         return(0);
   455 	}
   455     }
   456 	return 1;
   456     return 1;
   457 }
   457 }
   458 
   458 
   459 /* MUS_MOD can't be auto-detected. If no other format was detected, MOD is
   459 /* MUS_MOD can't be auto-detected. If no other format was detected, MOD is
   460  * assumed and MUS_MOD will be returned, meaning that the format might not
   460  * assumed and MUS_MOD will be returned, meaning that the format might not
   461  * actually be MOD-based.
   461  * actually be MOD-based.
   462  *
   462  *
   463  * Returns MUS_NONE in case of errors. */
   463  * Returns MUS_NONE in case of errors. */
   464 static Mix_MusicType detect_music_type(SDL_RWops *rw)
   464 static Mix_MusicType detect_music_type(SDL_RWops *rw)
   465 {
   465 {
   466 	Uint8 magic[5];
   466     Uint8 magic[5];
   467 	Uint8 moremagic[9];
   467     Uint8 moremagic[9];
   468 
   468 
   469 	int start = SDL_RWtell(rw);
   469     int start = SDL_RWtell(rw);
   470 	if (SDL_RWread(rw, magic, 1, 4) != 4 || SDL_RWread(rw, moremagic, 1, 8) != 8 ) {
   470     if (SDL_RWread(rw, magic, 1, 4) != 4 || SDL_RWread(rw, moremagic, 1, 8) != 8 ) {
   471 		Mix_SetError("Couldn't read from RWops");
   471         Mix_SetError("Couldn't read from RWops");
   472 		return MUS_NONE;
   472         return MUS_NONE;
   473 	}
   473     }
   474 	SDL_RWseek(rw, start, RW_SEEK_SET);
   474     SDL_RWseek(rw, start, RW_SEEK_SET);
   475 	magic[4]='\0';
   475     magic[4]='\0';
   476 	moremagic[8] = '\0';
   476     moremagic[8] = '\0';
   477 
   477 
   478 	/* WAVE files have the magic four bytes "RIFF"
   478     /* WAVE files have the magic four bytes "RIFF"
   479 	   AIFF files have the magic 12 bytes "FORM" XXXX "AIFF" */
   479        AIFF files have the magic 12 bytes "FORM" XXXX "AIFF" */
   480 	if (((strcmp((char *)magic, "RIFF") == 0) && (strcmp((char *)(moremagic+4), "WAVE") == 0)) ||
   480     if (((strcmp((char *)magic, "RIFF") == 0) && (strcmp((char *)(moremagic+4), "WAVE") == 0)) ||
   481 		(strcmp((char *)magic, "FORM") == 0)) {
   481         (strcmp((char *)magic, "FORM") == 0)) {
   482 		return MUS_WAV;
   482         return MUS_WAV;
   483 	}
   483     }
   484 
   484 
   485 	/* Ogg Vorbis files have the magic four bytes "OggS" */
   485     /* Ogg Vorbis files have the magic four bytes "OggS" */
   486 	if (strcmp((char *)magic, "OggS") == 0) {
   486     if (strcmp((char *)magic, "OggS") == 0) {
   487 		return MUS_OGG;
   487         return MUS_OGG;
   488 	}
   488     }
   489 
   489 
   490 	/* FLAC files have the magic four bytes "fLaC" */
   490     /* FLAC files have the magic four bytes "fLaC" */
   491 	if (strcmp((char *)magic, "fLaC") == 0) {
   491     if (strcmp((char *)magic, "fLaC") == 0) {
   492 		return MUS_FLAC;
   492         return MUS_FLAC;
   493 	}
   493     }
   494 
   494 
   495 	/* MIDI files have the magic four bytes "MThd" */
   495     /* MIDI files have the magic four bytes "MThd" */
   496 	if (strcmp((char *)magic, "MThd") == 0) {
   496     if (strcmp((char *)magic, "MThd") == 0) {
   497 		return MUS_MID;
   497         return MUS_MID;
   498 	}
   498     }
   499 
   499 
   500 	if (detect_mp3(magic)) {
   500     if (detect_mp3(magic)) {
   501 		return MUS_MP3;
   501         return MUS_MP3;
   502 	}
   502     }
   503 
   503 
   504 	/* Assume MOD format.
   504     /* Assume MOD format.
   505 	 *
   505      *
   506 	 * Apparently there is no way to check if the file is really a MOD,
   506      * Apparently there is no way to check if the file is really a MOD,
   507 	 * or there are too many formats supported by MikMod/ModPlug, or
   507      * or there are too many formats supported by MikMod/ModPlug, or
   508 	 * MikMod/ModPlug does this check by itself. */
   508      * MikMod/ModPlug does this check by itself. */
   509 	return MUS_MOD;
   509     return MUS_MOD;
   510 }
   510 }
   511 
   511 
   512 /* Load a music file */
   512 /* Load a music file */
   513 Mix_Music *Mix_LoadMUS(const char *file)
   513 Mix_Music *Mix_LoadMUS(const char *file)
   514 {
   514 {
   515 	SDL_RWops *rw;
   515     SDL_RWops *rw;
   516 	Mix_Music *music;
   516     Mix_Music *music;
   517 	Mix_MusicType type;
   517     Mix_MusicType type;
   518 	char *ext = strrchr(file, '.');
   518     char *ext = strrchr(file, '.');
   519 
   519 
   520 #ifdef CMD_MUSIC
   520 #ifdef CMD_MUSIC
   521 	if ( music_cmd ) {
   521     if ( music_cmd ) {
   522 		/* Allocate memory for the music structure */
   522         /* Allocate memory for the music structure */
   523 		music = (Mix_Music *)SDL_malloc(sizeof(Mix_Music));
   523         music = (Mix_Music *)SDL_malloc(sizeof(Mix_Music));
   524 		if ( music == NULL ) {
   524         if ( music == NULL ) {
   525 			Mix_SetError("Out of memory");
   525             Mix_SetError("Out of memory");
   526 			return(NULL);
   526             return(NULL);
   527 		}
   527         }
   528 		music->error = 0;
   528         music->error = 0;
   529 		music->type = MUS_CMD;
   529         music->type = MUS_CMD;
   530 		music->data.cmd = MusicCMD_LoadSong(music_cmd, file);
   530         music->data.cmd = MusicCMD_LoadSong(music_cmd, file);
   531 		if ( music->data.cmd == NULL ) {
   531         if ( music->data.cmd == NULL ) {
   532 			SDL_free(music);
   532             SDL_free(music);
   533 			music = NULL;
   533             music = NULL;
   534 		}
   534         }
   535 		return music;
   535         return music;
   536 	}
   536     }
   537 #endif
   537 #endif
   538 
   538 
   539 	rw = SDL_RWFromFile(file, "rb");
   539     rw = SDL_RWFromFile(file, "rb");
   540 	if ( rw == NULL ) {
   540     if ( rw == NULL ) {
   541 		Mix_SetError("Couldn't open '%s'", file);
   541         Mix_SetError("Couldn't open '%s'", file);
   542 		return NULL;
   542         return NULL;
   543 	}
   543     }
   544 
   544 
   545 	/* Use the extension as a first guess on the file type */
   545     /* Use the extension as a first guess on the file type */
   546 	type = MUS_NONE;
   546     type = MUS_NONE;
   547 	ext = strrchr(file, '.');
   547     ext = strrchr(file, '.');
   548 	/* No need to guard these with #ifdef *_MUSIC stuff,
   548     /* No need to guard these with #ifdef *_MUSIC stuff,
   549 	 * since we simply call Mix_LoadMUSType_RW() later */
   549      * since we simply call Mix_LoadMUSType_RW() later */
   550 	if ( ext ) {
   550     if ( ext ) {
   551 		++ext; /* skip the dot in the extension */
   551         ++ext; /* skip the dot in the extension */
   552 		if ( MIX_string_equals(ext, "WAV") ) {
   552         if ( MIX_string_equals(ext, "WAV") ) {
   553 			type = MUS_WAV;
   553             type = MUS_WAV;
   554 		} else if ( MIX_string_equals(ext, "MID") ||
   554         } else if ( MIX_string_equals(ext, "MID") ||
   555 		            MIX_string_equals(ext, "MIDI") ||
   555                     MIX_string_equals(ext, "MIDI") ||
   556 		            MIX_string_equals(ext, "KAR") ) {
   556                     MIX_string_equals(ext, "KAR") ) {
   557 			type = MUS_MID;
   557             type = MUS_MID;
   558 		} else if ( MIX_string_equals(ext, "OGG") ) {
   558         } else if ( MIX_string_equals(ext, "OGG") ) {
   559 			type = MUS_OGG;
   559             type = MUS_OGG;
   560 		} else if ( MIX_string_equals(ext, "FLAC") ) {
   560         } else if ( MIX_string_equals(ext, "FLAC") ) {
   561 			type = MUS_FLAC;
   561             type = MUS_FLAC;
   562 		} else 	if ( MIX_string_equals(ext, "MPG") ||
   562         } else  if ( MIX_string_equals(ext, "MPG") ||
   563 		             MIX_string_equals(ext, "MPEG") ||
   563                      MIX_string_equals(ext, "MPEG") ||
   564 		             MIX_string_equals(ext, "MP3") ||
   564                      MIX_string_equals(ext, "MP3") ||
   565 		             MIX_string_equals(ext, "MAD") ) {
   565                      MIX_string_equals(ext, "MAD") ) {
   566 			type = MUS_MP3;
   566             type = MUS_MP3;
   567 		}
   567         }
   568 	}
   568     }
   569 	if ( type == MUS_NONE ) {
   569     if ( type == MUS_NONE ) {
   570 		type = detect_music_type(rw);
   570         type = detect_music_type(rw);
   571 	}
   571     }
   572 
   572 
   573 	/* We need to know if a specific error occurs; if not, we'll set a
   573     /* We need to know if a specific error occurs; if not, we'll set a
   574 	 * generic one, so we clear the current one. */
   574      * generic one, so we clear the current one. */
   575 	Mix_SetError("");
   575     Mix_SetError("");
   576 	music = Mix_LoadMUSType_RW(rw, type, SDL_TRUE);
   576     music = Mix_LoadMUSType_RW(rw, type, SDL_TRUE);
   577 	if ( music == NULL && Mix_GetError()[0] == '\0' ) {
   577     if ( music == NULL && Mix_GetError()[0] == '\0' ) {
   578 		SDL_FreeRW(rw);
   578         SDL_FreeRW(rw);
   579 		Mix_SetError("Couldn't open '%s'", file);
   579         Mix_SetError("Couldn't open '%s'", file);
   580 	}
   580     }
   581 	return music;
   581     return music;
   582 }
   582 }
   583 
   583 
   584 Mix_Music *Mix_LoadMUS_RW(SDL_RWops *rw)
   584 Mix_Music *Mix_LoadMUS_RW(SDL_RWops *rw)
   585 {
   585 {
   586 	return Mix_LoadMUSType_RW(rw, MUS_NONE, SDL_FALSE);
   586     return Mix_LoadMUSType_RW(rw, MUS_NONE, SDL_FALSE);
   587 }
   587 }
   588 
   588 
   589 Mix_Music *Mix_LoadMUSType_RW(SDL_RWops *rw, Mix_MusicType type, int freesrc)
   589 Mix_Music *Mix_LoadMUSType_RW(SDL_RWops *rw, Mix_MusicType type, int freesrc)
   590 {
   590 {
   591 	Mix_Music *music;
   591     Mix_Music *music;
   592 
   592 
   593 	if (!rw) {
   593     if (!rw) {
   594 		Mix_SetError("RWops pointer is NULL");
   594         Mix_SetError("RWops pointer is NULL");
   595 		return NULL;
   595         return NULL;
   596 	}
   596     }
   597 
   597 
   598 	/* If the caller wants auto-detection, figure out what kind of file
   598     /* If the caller wants auto-detection, figure out what kind of file
   599 	 * this is. */
   599      * this is. */
   600 	if (type == MUS_NONE) {
   600     if (type == MUS_NONE) {
   601 		if ((type = detect_music_type(rw)) == MUS_NONE) {
   601         if ((type = detect_music_type(rw)) == MUS_NONE) {
   602 			/* Don't call Mix_SetError() here since detect_music_type()
   602             /* Don't call Mix_SetError() here since detect_music_type()
   603 			 * does that. */
   603              * does that. */
   604 			return NULL;
   604             return NULL;
   605 		}
   605         }
   606 	}
   606     }
   607 
   607 
   608 	/* Allocate memory for the music structure */
   608     /* Allocate memory for the music structure */
   609 	music = (Mix_Music *)SDL_malloc(sizeof(Mix_Music));
   609     music = (Mix_Music *)SDL_malloc(sizeof(Mix_Music));
   610 	if (music == NULL ) {
   610     if (music == NULL ) {
   611 		Mix_SetError("Out of memory");
   611         Mix_SetError("Out of memory");
   612 		return NULL;
   612         return NULL;
   613 	}
   613     }
   614 	music->error = 0;
   614     music->error = 0;
   615 
   615 
   616 	switch (type) {
   616     switch (type) {
   617 #ifdef WAV_MUSIC
   617 #ifdef WAV_MUSIC
   618 	case MUS_WAV:
   618     case MUS_WAV:
   619 		/* The WAVE loader needs the first 4 bytes of the header */
   619         /* The WAVE loader needs the first 4 bytes of the header */
   620 		{
   620         {
   621 			Uint8 magic[5];
   621             Uint8 magic[5];
   622 			int start = SDL_RWtell(rw);
   622             int start = SDL_RWtell(rw);
   623 			if (SDL_RWread(rw, magic, 1, 4) != 4) {
   623             if (SDL_RWread(rw, magic, 1, 4) != 4) {
   624 				Mix_SetError("Couldn't read from RWops");
   624                 Mix_SetError("Couldn't read from RWops");
   625 				return MUS_NONE;
   625                 SDL_free(music);
   626 			}
   626                 return MUS_NONE;
   627 			SDL_RWseek(rw, start, RW_SEEK_SET);
   627             }
   628 			magic[4] = '\0';
   628             SDL_RWseek(rw, start, RW_SEEK_SET);
   629 			music->type = MUS_WAV;
   629             magic[4] = '\0';
   630 			music->data.wave = WAVStream_LoadSong_RW(rw, (char *)magic, freesrc);
   630             music->type = MUS_WAV;
   631 		}
   631             music->data.wave = WAVStream_LoadSong_RW(rw, (char *)magic, freesrc);
   632 		if (music->data.wave == NULL) {
   632         }
   633 			music->error = 1;
   633         if (music->data.wave == NULL) {
   634 		}
   634             music->error = 1;
   635 		break;
   635         }
       
   636         break;
   636 #endif
   637 #endif
   637 #ifdef OGG_MUSIC
   638 #ifdef OGG_MUSIC
   638 	case MUS_OGG:
   639     case MUS_OGG:
   639 		music->type = MUS_OGG;
   640         music->type = MUS_OGG;
   640 		music->data.ogg = OGG_new_RW(rw, freesrc);
   641         music->data.ogg = OGG_new_RW(rw, freesrc);
   641 		if ( music->data.ogg == NULL ) {
   642         if ( music->data.ogg == NULL ) {
   642 			music->error = 1;
   643             music->error = 1;
   643 		}
   644         }
   644 		break;
   645         break;
   645 #endif
   646 #endif
   646 #ifdef FLAC_MUSIC
   647 #ifdef FLAC_MUSIC
   647 	case MUS_FLAC:
   648     case MUS_FLAC:
   648 		music->type = MUS_FLAC;
   649         music->type = MUS_FLAC;
   649 		music->data.flac = FLAC_new_RW(rw, freesrc);
   650         music->data.flac = FLAC_new_RW(rw, freesrc);
   650 		if ( music->data.flac == NULL ) {
   651         if ( music->data.flac == NULL ) {
   651 			music->error = 1;
   652             music->error = 1;
   652 		}
   653         }
   653 		break;
   654         break;
   654 #endif
   655 #endif
   655 #ifdef MP3_MUSIC
   656 #ifdef MP3_MUSIC
   656 	case MUS_MP3:
   657     case MUS_MP3:
   657 		if ( Mix_Init(MIX_INIT_MP3) ) {
   658         if ( Mix_Init(MIX_INIT_MP3) ) {
   658 			SMPEG_Info info;
   659             SMPEG_Info info;
   659 			music->type = MUS_MP3;
   660             music->type = MUS_MP3;
   660 			music->data.mp3 = smpeg.SMPEG_new_rwops(rw, &info, 0);
   661             music->data.mp3 = smpeg.SMPEG_new_rwops(rw, &info, 0);
   661 			if ( !info.has_audio ) {
   662             if ( !info.has_audio ) {
   662 				Mix_SetError("MPEG file does not have any audio stream.");
   663                 Mix_SetError("MPEG file does not have any audio stream.");
   663 				music->error = 1;
   664                 music->error = 1;
   664 			} else {
   665             } else {
   665 				smpeg.SMPEG_actualSpec(music->data.mp3, &used_mixer);
   666                 smpeg.SMPEG_actualSpec(music->data.mp3, &used_mixer);
   666 			}
   667             }
   667 		} else {
   668         } else {
   668 			music->error = 1;
   669             music->error = 1;
   669 		}
   670         }
   670 		break;
   671         break;
   671 #elif defined(MP3_MAD_MUSIC)
   672 #elif defined(MP3_MAD_MUSIC)
   672 	case MUS_MP3:
   673     case MUS_MP3:
   673 		music->type = MUS_MP3_MAD;
   674         music->type = MUS_MP3_MAD;
   674 		music->data.mp3_mad = mad_openFileRW(rw, &used_mixer, freesrc);
   675         music->data.mp3_mad = mad_openFileRW(rw, &used_mixer, freesrc);
   675 		if (music->data.mp3_mad == 0) {
   676         if (music->data.mp3_mad == 0) {
   676 			Mix_SetError("Could not initialize MPEG stream.");
   677             Mix_SetError("Could not initialize MPEG stream.");
   677 			music->error = 1;
   678             music->error = 1;
   678 		}
   679         }
   679 		break;
   680         break;
   680 #endif
   681 #endif
   681 #ifdef MID_MUSIC
   682 #ifdef MID_MUSIC
   682 	case MUS_MID:
   683     case MUS_MID:
   683 		music->type = MUS_MID;
   684         music->type = MUS_MID;
   684 #ifdef USE_NATIVE_MIDI
   685 #ifdef USE_NATIVE_MIDI
   685 		if ( native_midi_ok ) {
   686         if ( native_midi_ok ) {
   686 			music->data.nativemidi = native_midi_loadsong_RW(rw, freesrc);
   687             music->data.nativemidi = native_midi_loadsong_RW(rw, freesrc);
   687 	  		if ( music->data.nativemidi == NULL ) {
   688             if ( music->data.nativemidi == NULL ) {
   688 		  		Mix_SetError("%s", native_midi_error());
   689                 Mix_SetError("%s", native_midi_error());
   689 			  	music->error = 1;
   690                 music->error = 1;
   690 			}
   691             }
   691 			break;
   692             break;
   692 		}
   693         }
   693 #endif
   694 #endif
   694 #ifdef USE_FLUIDSYNTH_MIDI
   695 #ifdef USE_FLUIDSYNTH_MIDI
   695 		if ( fluidsynth_ok ) {
   696         if ( fluidsynth_ok ) {
   696 			music->data.fluidsynthmidi = fluidsynth_loadsong_RW(rw, freesrc);
   697             music->data.fluidsynthmidi = fluidsynth_loadsong_RW(rw, freesrc);
   697 			if ( music->data.fluidsynthmidi == NULL ) {
   698             if ( music->data.fluidsynthmidi == NULL ) {
   698 				music->error = 1;
   699                 music->error = 1;
   699 			}
   700             }
   700 			break;
   701             break;
   701 		}
   702         }
   702 #endif
   703 #endif
   703 #ifdef USE_TIMIDITY_MIDI
   704 #ifdef USE_TIMIDITY_MIDI
   704 		if ( timidity_ok ) {
   705         if ( timidity_ok ) {
   705 			music->data.midi = Timidity_LoadSong_RW(rw, freesrc);
   706             music->data.midi = Timidity_LoadSong_RW(rw, freesrc);
   706 			if ( music->data.midi == NULL ) {
   707             if ( music->data.midi == NULL ) {
   707 				Mix_SetError("%s", Timidity_Error());
   708                 Mix_SetError("%s", Timidity_Error());
   708 				music->error = 1;
   709                 music->error = 1;
   709 			}
   710             }
   710 		} else {
   711         } else {
   711 			Mix_SetError("%s", Timidity_Error());
   712             Mix_SetError("%s", Timidity_Error());
   712 			music->error = 1;
   713             music->error = 1;
   713 		}
   714         }
   714 #endif
   715 #endif
   715 		break;
   716         break;
   716 #endif
   717 #endif
   717 #if defined(MODPLUG_MUSIC) || defined(MOD_MUSIC)
   718 #if defined(MODPLUG_MUSIC) || defined(MOD_MUSIC)
   718 	case MUS_MOD:
   719     case MUS_MOD:
   719 		music->error = 1;
   720         music->error = 1;
   720 #ifdef MODPLUG_MUSIC
   721 #ifdef MODPLUG_MUSIC
   721 		if ( music->error ) {
   722         if ( music->error ) {
   722 			music->type = MUS_MODPLUG;
   723             music->type = MUS_MODPLUG;
   723 			music->data.modplug = modplug_new_RW(rw, freesrc);
   724             music->data.modplug = modplug_new_RW(rw, freesrc);
   724 			if ( music->data.modplug ) {
   725             if ( music->data.modplug ) {
   725 				music->error = 0;
   726                 music->error = 0;
   726 			}
   727             }
   727 		}
   728         }
   728 #endif
   729 #endif
   729 #ifdef MOD_MUSIC
   730 #ifdef MOD_MUSIC
   730 		if ( music->error ) {
   731         if ( music->error ) {
   731 			music->type = MUS_MOD;
   732             music->type = MUS_MOD;
   732 			music->data.module = MOD_new_RW(rw, freesrc);
   733             music->data.module = MOD_new_RW(rw, freesrc);
   733 			if ( music->data.module ) {
   734             if ( music->data.module ) {
   734 				music->error = 0;
   735                 music->error = 0;
   735 			}
   736             }
   736 		}
   737         }
   737 #endif
   738 #endif
   738 		break;
   739         break;
   739 #endif
   740 #endif
   740 
   741 
   741 	default:
   742     default:
   742 		Mix_SetError("Unrecognized music format");
   743         Mix_SetError("Unrecognized music format");
   743 		music->error=1;
   744         music->error=1;
   744 	} /* switch (want) */
   745     } /* switch (want) */
   745 
   746 
   746 
   747 
   747 	if (music->error) {
   748     if (music->error) {
   748 		SDL_free(music);
   749         SDL_free(music);
   749 		music=NULL;
   750         music=NULL;
   750 	}
   751     }
   751 	return(music);
   752     return(music);
   752 }
   753 }
   753 
   754 
   754 /* Free a music chunk previously loaded */
   755 /* Free a music chunk previously loaded */
   755 void Mix_FreeMusic(Mix_Music *music)
   756 void Mix_FreeMusic(Mix_Music *music)
   756 {
   757 {
   757 	if ( music ) {
   758     if ( music ) {
   758 		/* Stop the music if it's currently playing */
   759         /* Stop the music if it's currently playing */
   759 		SDL_LockAudio();
   760         SDL_LockAudio();
   760 		if ( music == music_playing ) {
   761         if ( music == music_playing ) {
   761 			/* Wait for any fade out to finish */
   762             /* Wait for any fade out to finish */
   762 			while ( music->fading == MIX_FADING_OUT ) {
   763             while ( music->fading == MIX_FADING_OUT ) {
   763 				SDL_UnlockAudio();
   764                 SDL_UnlockAudio();
   764 				SDL_Delay(100);
   765                 SDL_Delay(100);
   765 				SDL_LockAudio();
   766                 SDL_LockAudio();
   766 			}
   767             }
   767 			if ( music == music_playing ) {
   768             if ( music == music_playing ) {
   768 				music_internal_halt();
   769                 music_internal_halt();
   769 			}
   770             }
   770 		}
   771         }
   771 		SDL_UnlockAudio();
   772         SDL_UnlockAudio();
   772 		switch (music->type) {
   773         switch (music->type) {
   773 #ifdef CMD_MUSIC
   774 #ifdef CMD_MUSIC
   774 			case MUS_CMD:
   775             case MUS_CMD:
   775 				MusicCMD_FreeSong(music->data.cmd);
   776                 MusicCMD_FreeSong(music->data.cmd);
   776 				break;
   777                 break;
   777 #endif
   778 #endif
   778 #ifdef WAV_MUSIC
   779 #ifdef WAV_MUSIC
   779 			case MUS_WAV:
   780             case MUS_WAV:
   780 				WAVStream_FreeSong(music->data.wave);
   781                 WAVStream_FreeSong(music->data.wave);
   781 				break;
   782                 break;
   782 #endif
   783 #endif
   783 #ifdef MODPLUG_MUSIC
   784 #ifdef MODPLUG_MUSIC
   784 			case MUS_MODPLUG:
   785             case MUS_MODPLUG:
   785 				modplug_delete(music->data.modplug);
   786                 modplug_delete(music->data.modplug);
   786 				break;
   787                 break;
   787 #endif
   788 #endif
   788 #ifdef MOD_MUSIC
   789 #ifdef MOD_MUSIC
   789 			case MUS_MOD:
   790             case MUS_MOD:
   790 				MOD_delete(music->data.module);
   791                 MOD_delete(music->data.module);
   791 				break;
   792                 break;
   792 #endif
   793 #endif
   793 #ifdef MID_MUSIC
   794 #ifdef MID_MUSIC
   794 			case MUS_MID:
   795             case MUS_MID:
   795 #ifdef USE_NATIVE_MIDI
   796 #ifdef USE_NATIVE_MIDI
   796   				if ( native_midi_ok ) {
   797                 if ( native_midi_ok ) {
   797 					native_midi_freesong(music->data.nativemidi);
   798                     native_midi_freesong(music->data.nativemidi);
   798 					goto skip;
   799                     goto skip;
   799 				}
   800                 }
   800 #endif
   801 #endif
   801 #ifdef USE_FLUIDSYNTH_MIDI
   802 #ifdef USE_FLUIDSYNTH_MIDI
   802 				if ( fluidsynth_ok ) {
   803                 if ( fluidsynth_ok ) {
   803 					fluidsynth_freesong(music->data.fluidsynthmidi);
   804                     fluidsynth_freesong(music->data.fluidsynthmidi);
   804 					goto skip;
   805                     goto skip;
   805 				}
   806                 }
   806 #endif
   807 #endif
   807 #ifdef USE_TIMIDITY_MIDI
   808 #ifdef USE_TIMIDITY_MIDI
   808 				if ( timidity_ok ) {
   809                 if ( timidity_ok ) {
   809 					Timidity_FreeSong(music->data.midi);
   810                     Timidity_FreeSong(music->data.midi);
   810 					goto skip;
   811                     goto skip;
   811 				}
   812                 }
   812 #endif
   813 #endif
   813 				break;
   814                 break;
   814 #endif
   815 #endif
   815 #ifdef OGG_MUSIC
   816 #ifdef OGG_MUSIC
   816 			case MUS_OGG:
   817             case MUS_OGG:
   817 				OGG_delete(music->data.ogg);
   818                 OGG_delete(music->data.ogg);
   818 				break;
   819                 break;
   819 #endif
   820 #endif
   820 #ifdef FLAC_MUSIC
   821 #ifdef FLAC_MUSIC
   821 			case MUS_FLAC:
   822             case MUS_FLAC:
   822 				FLAC_delete(music->data.flac);
   823                 FLAC_delete(music->data.flac);
   823 				break;
   824                 break;
   824 #endif
   825 #endif
   825 #ifdef MP3_MUSIC
   826 #ifdef MP3_MUSIC
   826 			case MUS_MP3:
   827             case MUS_MP3:
   827 				smpeg.SMPEG_delete(music->data.mp3);
   828                 smpeg.SMPEG_delete(music->data.mp3);
   828 				break;
   829                 break;
   829 #endif
   830 #endif
   830 #ifdef MP3_MAD_MUSIC
   831 #ifdef MP3_MAD_MUSIC
   831 			case MUS_MP3_MAD:
   832             case MUS_MP3_MAD:
   832 				mad_closeFile(music->data.mp3_mad);
   833                 mad_closeFile(music->data.mp3_mad);
   833 				break;
   834                 break;
   834 #endif
   835 #endif
   835 			default:
   836             default:
   836 				/* Unknown music type?? */
   837                 /* Unknown music type?? */
   837 				break;
   838                 break;
   838 		}
   839         }
   839 
   840 
   840     skip:
   841     skip:
   841 		SDL_free(music);
   842         SDL_free(music);
   842 	}
   843     }
   843 }
   844 }
   844 
   845 
   845 /* Find out the music format of a mixer music, or the currently playing
   846 /* Find out the music format of a mixer music, or the currently playing
   846    music, if 'music' is NULL.
   847    music, if 'music' is NULL.
   847 */
   848 */
   848 Mix_MusicType Mix_GetMusicType(const Mix_Music *music)
   849 Mix_MusicType Mix_GetMusicType(const Mix_Music *music)
   849 {
   850 {
   850 	Mix_MusicType type = MUS_NONE;
   851     Mix_MusicType type = MUS_NONE;
   851 
   852 
   852 	if ( music ) {
   853     if ( music ) {
   853 		type = music->type;
   854         type = music->type;
   854 	} else {
   855     } else {
   855 		SDL_LockAudio();
   856         SDL_LockAudio();
   856 		if ( music_playing ) {
   857         if ( music_playing ) {
   857 			type = music_playing->type;
   858             type = music_playing->type;
   858 		}
   859         }
   859 		SDL_UnlockAudio();
   860         SDL_UnlockAudio();
   860 	}
   861     }
   861 	return(type);
   862     return(type);
   862 }
   863 }
   863 
   864 
   864 /* Play a music chunk.  Returns 0, or -1 if there was an error.
   865 /* Play a music chunk.  Returns 0, or -1 if there was an error.
   865  */
   866  */
   866 static int music_internal_play(Mix_Music *music, double position)
   867 static int music_internal_play(Mix_Music *music, double position)
   867 {
   868 {
   868 	int retval = 0;
   869     int retval = 0;
   869 
   870 
   870 #if defined(__MACOSX__) && defined(USE_NATIVE_MIDI)
   871 #if defined(__MACOSX__) && defined(USE_NATIVE_MIDI)
   871 	/* This fixes a bug with native MIDI on Mac OS X, where you
   872     /* This fixes a bug with native MIDI on Mac OS X, where you
   872 	   can't really stop and restart MIDI from the audio callback.
   873        can't really stop and restart MIDI from the audio callback.
   873 	*/
   874     */
   874 	if ( music == music_playing && music->type == MUS_MID && native_midi_ok ) {
   875     if ( music == music_playing && music->type == MUS_MID && native_midi_ok ) {
   875 		/* Just a seek suffices to restart playing */
   876         /* Just a seek suffices to restart playing */
   876 		music_internal_position(position);
   877         music_internal_position(position);
   877 		return 0;
   878         return 0;
   878 	}
   879     }
   879 #endif
   880 #endif
   880 
   881 
   881 	/* Note the music we're playing */
   882     /* Note the music we're playing */
   882 	if ( music_playing ) {
   883     if ( music_playing ) {
   883 		music_internal_halt();
   884         music_internal_halt();
   884 	}
   885     }
   885 	music_playing = music;
   886     music_playing = music;
   886 
   887 
   887 	/* Set the initial volume */
   888     /* Set the initial volume */
   888 	if ( music->type != MUS_MOD ) {
   889     if ( music->type != MUS_MOD ) {
   889 		music_internal_initialize_volume();
   890         music_internal_initialize_volume();
   890 	}
   891     }
   891 
   892 
   892 	/* Set up for playback */
   893     /* Set up for playback */
   893 	switch (music->type) {
   894     switch (music->type) {
   894 #ifdef CMD_MUSIC
   895 #ifdef CMD_MUSIC
   895 	    case MUS_CMD:
   896         case MUS_CMD:
   896 		MusicCMD_Start(music->data.cmd);
   897         MusicCMD_Start(music->data.cmd);
   897 		break;
   898         break;
   898 #endif
   899 #endif
   899 #ifdef WAV_MUSIC
   900 #ifdef WAV_MUSIC
   900 	    case MUS_WAV:
   901         case MUS_WAV:
   901 		WAVStream_Start(music->data.wave);
   902         WAVStream_Start(music->data.wave);
   902 		break;
   903         break;
   903 #endif
   904 #endif
   904 #ifdef MODPLUG_MUSIC
   905 #ifdef MODPLUG_MUSIC
   905 	    case MUS_MODPLUG:
   906         case MUS_MODPLUG:
   906 		/* can't set volume until file is loaded, so finally set it now */
   907         /* can't set volume until file is loaded, so finally set it now */
   907 		music_internal_initialize_volume();
   908         music_internal_initialize_volume();
   908 		modplug_play(music->data.modplug);
   909         modplug_play(music->data.modplug);
   909 		break;
   910         break;
   910 #endif
   911 #endif
   911 #ifdef MOD_MUSIC
   912 #ifdef MOD_MUSIC
   912 	    case MUS_MOD:
   913         case MUS_MOD:
   913 		MOD_play(music->data.module);
   914         MOD_play(music->data.module);
   914 		/* Player_SetVolume() does nothing before Player_Start() */
   915         /* Player_SetVolume() does nothing before Player_Start() */
   915 		music_internal_initialize_volume();
   916         music_internal_initialize_volume();
   916 		break;
   917         break;
   917 #endif
   918 #endif
   918 #ifdef MID_MUSIC
   919 #ifdef MID_MUSIC
   919 	    case MUS_MID:
   920         case MUS_MID:
   920 #ifdef USE_NATIVE_MIDI
   921 #ifdef USE_NATIVE_MIDI
   921 		if ( native_midi_ok ) {
   922         if ( native_midi_ok ) {
   922 			native_midi_start(music->data.nativemidi, music_loops);
   923             native_midi_start(music->data.nativemidi, music_loops);
   923 			goto skip;
   924             goto skip;
   924 		}
   925         }
   925 #endif
   926 #endif
   926 #ifdef USE_FLUIDSYNTH_MIDI
   927 #ifdef USE_FLUIDSYNTH_MIDI
   927 		if (fluidsynth_ok ) {
   928         if (fluidsynth_ok ) {
   928 			fluidsynth_start(music->data.fluidsynthmidi);
   929             fluidsynth_start(music->data.fluidsynthmidi);
   929 			goto skip;
   930             goto skip;
   930 		}
   931         }
   931 #endif
   932 #endif
   932 #ifdef USE_TIMIDITY_MIDI
   933 #ifdef USE_TIMIDITY_MIDI
   933 		if ( timidity_ok ) {
   934         if ( timidity_ok ) {
   934 			Timidity_Start(music->data.midi);
   935             Timidity_Start(music->data.midi);
   935 			goto skip;
   936             goto skip;
   936 		}
   937         }
   937 #endif
   938 #endif
   938 		break;
   939         break;
   939 #endif
   940 #endif
   940 #ifdef OGG_MUSIC
   941 #ifdef OGG_MUSIC
   941 	    case MUS_OGG:
   942         case MUS_OGG:
   942 		OGG_play(music->data.ogg);
   943         OGG_play(music->data.ogg);
   943 		break;
   944         break;
   944 #endif
   945 #endif
   945 #ifdef FLAC_MUSIC
   946 #ifdef FLAC_MUSIC
   946 	    case MUS_FLAC:
   947         case MUS_FLAC:
   947 		FLAC_play(music->data.flac);
   948         FLAC_play(music->data.flac);
   948 		break;
   949         break;
   949 #endif
   950 #endif
   950 #ifdef MP3_MUSIC
   951 #ifdef MP3_MUSIC
   951 	    case MUS_MP3:
   952         case MUS_MP3:
   952 		smpeg.SMPEG_enableaudio(music->data.mp3,1);
   953         smpeg.SMPEG_enableaudio(music->data.mp3,1);
   953 		smpeg.SMPEG_enablevideo(music->data.mp3,0);
   954         smpeg.SMPEG_enablevideo(music->data.mp3,0);
   954 		smpeg.SMPEG_play(music_playing->data.mp3);
   955         smpeg.SMPEG_play(music_playing->data.mp3);
   955 		break;
   956         break;
   956 #endif
   957 #endif
   957 #ifdef MP3_MAD_MUSIC
   958 #ifdef MP3_MAD_MUSIC
   958 	    case MUS_MP3_MAD:
   959         case MUS_MP3_MAD:
   959 		mad_start(music->data.mp3_mad);
   960         mad_start(music->data.mp3_mad);
   960 		break;
   961         break;
   961 #endif
   962 #endif
   962 	    default:
   963         default:
   963 		Mix_SetError("Can't play unknown music type");
   964         Mix_SetError("Can't play unknown music type");
   964 		retval = -1;
   965         retval = -1;
   965 		break;
   966         break;
   966 	}
   967     }
   967 
   968 
   968 skip:
   969 skip:
   969 	/* Set the playback position, note any errors if an offset is used */
   970     /* Set the playback position, note any errors if an offset is used */
   970 	if ( retval == 0 ) {
   971     if ( retval == 0 ) {
   971 		if ( position > 0.0 ) {
   972         if ( position > 0.0 ) {
   972 			if ( music_internal_position(position) < 0 ) {
   973             if ( music_internal_position(position) < 0 ) {
   973 				Mix_SetError("Position not implemented for music type");
   974                 Mix_SetError("Position not implemented for music type");
   974 				retval = -1;
   975                 retval = -1;
   975 			}
   976             }
   976 		} else {
   977         } else {
   977 			music_internal_position(0.0);
   978             music_internal_position(0.0);
   978 		}
   979         }
   979 	}
   980     }
   980 
   981 
   981 	/* If the setup failed, we're not playing any music anymore */
   982     /* If the setup failed, we're not playing any music anymore */
   982 	if ( retval < 0 ) {
   983     if ( retval < 0 ) {
   983 		music_playing = NULL;
   984         music_playing = NULL;
   984 	}
   985     }
   985 	return(retval);
   986     return(retval);
   986 }
   987 }
   987 int Mix_FadeInMusicPos(Mix_Music *music, int loops, int ms, double position)
   988 int Mix_FadeInMusicPos(Mix_Music *music, int loops, int ms, double position)
   988 {
   989 {
   989 	int retval;
   990     int retval;
   990 
   991 
   991 	if ( ms_per_step == 0 ) {
   992     if ( ms_per_step == 0 ) {
   992 		SDL_SetError("Audio device hasn't been opened");
   993         SDL_SetError("Audio device hasn't been opened");
   993 		return(-1);
   994         return(-1);
   994 	}
   995     }
   995 
   996 
   996 	/* Don't play null pointers :-) */
   997     /* Don't play null pointers :-) */
   997 	if ( music == NULL ) {
   998     if ( music == NULL ) {
   998 		Mix_SetError("music parameter was NULL");
   999         Mix_SetError("music parameter was NULL");
   999 		return(-1);
  1000         return(-1);
  1000 	}
  1001     }
  1001 
  1002 
  1002 	/* Setup the data */
  1003     /* Setup the data */
  1003 	if ( ms ) {
  1004     if ( ms ) {
  1004 		music->fading = MIX_FADING_IN;
  1005         music->fading = MIX_FADING_IN;
  1005 	} else {
  1006     } else {
  1006 		music->fading = MIX_NO_FADING;
  1007         music->fading = MIX_NO_FADING;
  1007 	}
  1008     }
  1008 	music->fade_step = 0;
  1009     music->fade_step = 0;
  1009 	music->fade_steps = ms/ms_per_step;
  1010     music->fade_steps = ms/ms_per_step;
  1010 
  1011 
  1011 	/* Play the puppy */
  1012     /* Play the puppy */
  1012 	SDL_LockAudio();
  1013     SDL_LockAudio();
  1013 	/* If the current music is fading out, wait for the fade to complete */
  1014     /* If the current music is fading out, wait for the fade to complete */
  1014 	while ( music_playing && (music_playing->fading == MIX_FADING_OUT) ) {
  1015     while ( music_playing && (music_playing->fading == MIX_FADING_OUT) ) {
  1015 		SDL_UnlockAudio();
  1016         SDL_UnlockAudio();
  1016 		SDL_Delay(100);
  1017         SDL_Delay(100);
  1017 		SDL_LockAudio();
  1018         SDL_LockAudio();
  1018 	}
  1019     }
  1019 	music_active = 1;
  1020     music_active = 1;
  1020 	if (loops == 1) {
  1021     if (loops == 1) {
  1021 		/* Loop is the number of times to play the audio */
  1022         /* Loop is the number of times to play the audio */
  1022 		loops = 0;
  1023         loops = 0;
  1023 	}
  1024     }
  1024 	music_loops = loops;
  1025     music_loops = loops;
  1025 	retval = music_internal_play(music, position);
  1026     retval = music_internal_play(music, position);
  1026 	SDL_UnlockAudio();
  1027     SDL_UnlockAudio();
  1027 
  1028 
  1028 	return(retval);
  1029     return(retval);
  1029 }
  1030 }
  1030 int Mix_FadeInMusic(Mix_Music *music, int loops, int ms)
  1031 int Mix_FadeInMusic(Mix_Music *music, int loops, int ms)
  1031 {
  1032 {
  1032 	return Mix_FadeInMusicPos(music, loops, ms, 0.0);
  1033     return Mix_FadeInMusicPos(music, loops, ms, 0.0);
  1033 }
  1034 }
  1034 int Mix_PlayMusic(Mix_Music *music, int loops)
  1035 int Mix_PlayMusic(Mix_Music *music, int loops)
  1035 {
  1036 {
  1036 	return Mix_FadeInMusicPos(music, loops, 0, 0.0);
  1037     return Mix_FadeInMusicPos(music, loops, 0, 0.0);
  1037 }
  1038 }
  1038 
  1039 
  1039 /* Set the playing music position */
  1040 /* Set the playing music position */
  1040 int music_internal_position(double position)
  1041 int music_internal_position(double position)
  1041 {
  1042 {
  1042 	int retval = 0;
  1043     int retval = 0;
  1043 
  1044 
  1044 	switch (music_playing->type) {
  1045     switch (music_playing->type) {
  1045 #ifdef MODPLUG_MUSIC
  1046 #ifdef MODPLUG_MUSIC
  1046 	    case MUS_MODPLUG:
  1047         case MUS_MODPLUG:
  1047 		modplug_jump_to_time(music_playing->data.modplug, position);
  1048         modplug_jump_to_time(music_playing->data.modplug, position);
  1048 		break;
  1049         break;
  1049 #endif
  1050 #endif
  1050 #ifdef MOD_MUSIC
  1051 #ifdef MOD_MUSIC
  1051 	    case MUS_MOD:
  1052         case MUS_MOD:
  1052 		MOD_jump_to_time(music_playing->data.module, position);
  1053         MOD_jump_to_time(music_playing->data.module, position);
  1053 		break;
  1054         break;
  1054 #endif
  1055 #endif
  1055 #ifdef OGG_MUSIC
  1056 #ifdef OGG_MUSIC
  1056 	    case MUS_OGG:
  1057         case MUS_OGG:
  1057 		OGG_jump_to_time(music_playing->data.ogg, position);
  1058         OGG_jump_to_time(music_playing->data.ogg, position);
  1058 		break;
  1059         break;
  1059 #endif
  1060 #endif
  1060 #ifdef FLAC_MUSIC
  1061 #ifdef FLAC_MUSIC
  1061 	    case MUS_FLAC:
  1062         case MUS_FLAC:
  1062 		FLAC_jump_to_time(music_playing->data.flac, position);
  1063         FLAC_jump_to_time(music_playing->data.flac, position);
  1063 		break;
  1064         break;
  1064 #endif
  1065 #endif
  1065 #ifdef MP3_MUSIC
  1066 #ifdef MP3_MUSIC
  1066 	    case MUS_MP3:
  1067         case MUS_MP3:
  1067 		smpeg.SMPEG_rewind(music_playing->data.mp3);
  1068         smpeg.SMPEG_rewind(music_playing->data.mp3);
  1068 		smpeg.SMPEG_play(music_playing->data.mp3);
  1069         smpeg.SMPEG_play(music_playing->data.mp3);
  1069 		if ( position > 0.0 ) {
  1070         if ( position > 0.0 ) {
  1070 			smpeg.SMPEG_skip(music_playing->data.mp3, (float)position);
  1071             smpeg.SMPEG_skip(music_playing->data.mp3, (float)position);
  1071 		}
  1072         }
  1072 		break;
  1073         break;
  1073 #endif
  1074 #endif
  1074 #ifdef MP3_MAD_MUSIC
  1075 #ifdef MP3_MAD_MUSIC
  1075 	    case MUS_MP3_MAD:
  1076         case MUS_MP3_MAD:
  1076 		mad_seek(music_playing->data.mp3_mad, position);
  1077         mad_seek(music_playing->data.mp3_mad, position);
  1077 		break;
  1078         break;
  1078 #endif
  1079 #endif
  1079 	    default:
  1080         default:
  1080 		/* TODO: Implement this for other music backends */
  1081         /* TODO: Implement this for other music backends */
  1081 		retval = -1;
  1082         retval = -1;
  1082 		break;
  1083         break;
  1083 	}
  1084     }
  1084 	return(retval);
  1085     return(retval);
  1085 }
  1086 }
  1086 int Mix_SetMusicPosition(double position)
  1087 int Mix_SetMusicPosition(double position)
  1087 {
  1088 {
  1088 	int retval;
  1089     int retval;
  1089 
  1090 
  1090 	SDL_LockAudio();
  1091     SDL_LockAudio();
  1091 	if ( music_playing ) {
  1092     if ( music_playing ) {
  1092 		retval = music_internal_position(position);
  1093         retval = music_internal_position(position);
  1093 		if ( retval < 0 ) {
  1094         if ( retval < 0 ) {
  1094 			Mix_SetError("Position not implemented for music type");
  1095             Mix_SetError("Position not implemented for music type");
  1095 		}
  1096         }
  1096 	} else {
  1097     } else {
  1097 		Mix_SetError("Music isn't playing");
  1098         Mix_SetError("Music isn't playing");
  1098 		retval = -1;
  1099         retval = -1;
  1099 	}
  1100     }
  1100 	SDL_UnlockAudio();
  1101     SDL_UnlockAudio();
  1101 
  1102 
  1102 	return(retval);
  1103     return(retval);
  1103 }
  1104 }
  1104 
  1105 
  1105 /* Set the music's initial volume */
  1106 /* Set the music's initial volume */
  1106 static void music_internal_initialize_volume(void)
  1107 static void music_internal_initialize_volume(void)
  1107 {
  1108 {
  1108 	if ( music_playing->fading == MIX_FADING_IN ) {
  1109     if ( music_playing->fading == MIX_FADING_IN ) {
  1109 		music_internal_volume(0);
  1110         music_internal_volume(0);
  1110 	} else {
  1111     } else {
  1111 		music_internal_volume(music_volume);
  1112         music_internal_volume(music_volume);
  1112 	}
  1113     }
  1113 }
  1114 }
  1114 
  1115 
  1115 /* Set the music volume */
  1116 /* Set the music volume */
  1116 static void music_internal_volume(int volume)
  1117 static void music_internal_volume(int volume)
  1117 {
  1118 {
  1118 	switch (music_playing->type) {
  1119     switch (music_playing->type) {
  1119 #ifdef CMD_MUSIC
  1120 #ifdef CMD_MUSIC
  1120 	    case MUS_CMD:
  1121         case MUS_CMD:
  1121 		MusicCMD_SetVolume(volume);
  1122         MusicCMD_SetVolume(volume);
  1122 		break;
  1123         break;
  1123 #endif
  1124 #endif
  1124 #ifdef WAV_MUSIC
  1125 #ifdef WAV_MUSIC
  1125 	    case MUS_WAV:
  1126         case MUS_WAV:
  1126 		WAVStream_SetVolume(volume);
  1127         WAVStream_SetVolume(volume);
  1127 		break;
  1128         break;
  1128 #endif
  1129 #endif
  1129 #ifdef MODPLUG_MUSIC
  1130 #ifdef MODPLUG_MUSIC
  1130 	    case MUS_MODPLUG:
  1131         case MUS_MODPLUG:
  1131 		modplug_setvolume(music_playing->data.modplug, volume);
  1132         modplug_setvolume(music_playing->data.modplug, volume);
  1132 		break;
  1133         break;
  1133 #endif
  1134 #endif
  1134 #ifdef MOD_MUSIC
  1135 #ifdef MOD_MUSIC
  1135 	    case MUS_MOD:
  1136         case MUS_MOD:
  1136 		MOD_setvolume(music_playing->data.module, volume);
  1137         MOD_setvolume(music_playing->data.module, volume);
  1137 		break;
  1138         break;
  1138 #endif
  1139 #endif
  1139 #ifdef MID_MUSIC
  1140 #ifdef MID_MUSIC
  1140 	    case MUS_MID:
  1141         case MUS_MID:
  1141 #ifdef USE_NATIVE_MIDI
  1142 #ifdef USE_NATIVE_MIDI
  1142 		if ( native_midi_ok ) {
  1143         if ( native_midi_ok ) {
  1143 			native_midi_setvolume(volume);
  1144             native_midi_setvolume(volume);
  1144 			return;
  1145             return;
  1145 		}
  1146         }
  1146 #endif
  1147 #endif
  1147 #ifdef USE_FLUIDSYNTH_MIDI
  1148 #ifdef USE_FLUIDSYNTH_MIDI
  1148 		if ( fluidsynth_ok ) {
  1149         if ( fluidsynth_ok ) {
  1149 			fluidsynth_setvolume(music_playing->data.fluidsynthmidi, volume);
  1150             fluidsynth_setvolume(music_playing->data.fluidsynthmidi, volume);
  1150 			return;
  1151             return;
  1151 		}
  1152         }
  1152 #endif
  1153 #endif
  1153 #ifdef USE_TIMIDITY_MIDI
  1154 #ifdef USE_TIMIDITY_MIDI
  1154 		if ( timidity_ok ) {
  1155         if ( timidity_ok ) {
  1155 			Timidity_SetVolume(volume);
  1156             Timidity_SetVolume(volume);
  1156 			return;
  1157             return;
  1157 		}
  1158         }
  1158 #endif
  1159 #endif
  1159 		break;
  1160         break;
  1160 #endif
  1161 #endif
  1161 #ifdef OGG_MUSIC
  1162 #ifdef OGG_MUSIC
  1162 	    case MUS_OGG:
  1163         case MUS_OGG:
  1163 		OGG_setvolume(music_playing->data.ogg, volume);
  1164         OGG_setvolume(music_playing->data.ogg, volume);
  1164 		break;
  1165         break;
  1165 #endif
  1166 #endif
  1166 #ifdef FLAC_MUSIC
  1167 #ifdef FLAC_MUSIC
  1167 	    case MUS_FLAC:
  1168         case MUS_FLAC:
  1168 		FLAC_setvolume(music_playing->data.flac, volume);
  1169         FLAC_setvolume(music_playing->data.flac, volume);
  1169 		break;
  1170         break;
  1170 #endif
  1171 #endif
  1171 #ifdef MP3_MUSIC
  1172 #ifdef MP3_MUSIC
  1172 	    case MUS_MP3:
  1173         case MUS_MP3:
  1173 		smpeg.SMPEG_setvolume(music_playing->data.mp3,(int)(((float)volume/(float)MIX_MAX_VOLUME)*100.0));
  1174         smpeg.SMPEG_setvolume(music_playing->data.mp3,(int)(((float)volume/(float)MIX_MAX_VOLUME)*100.0));
  1174 		break;
  1175         break;
  1175 #endif
  1176 #endif
  1176 #ifdef MP3_MAD_MUSIC
  1177 #ifdef MP3_MAD_MUSIC
  1177 	    case MUS_MP3_MAD:
  1178         case MUS_MP3_MAD:
  1178 		mad_setVolume(music_playing->data.mp3_mad, volume);
  1179         mad_setVolume(music_playing->data.mp3_mad, volume);
  1179 		break;
  1180         break;
  1180 #endif
  1181 #endif
  1181 	    default:
  1182         default:
  1182 		/* Unknown music type?? */
  1183         /* Unknown music type?? */
  1183 		break;
  1184         break;
  1184 	}
  1185     }
  1185 }
  1186 }
  1186 int Mix_VolumeMusic(int volume)
  1187 int Mix_VolumeMusic(int volume)
  1187 {
  1188 {
  1188 	int prev_volume;
  1189     int prev_volume;
  1189 
  1190 
  1190 	prev_volume = music_volume;
  1191     prev_volume = music_volume;
  1191 	if ( volume < 0 ) {
  1192     if ( volume < 0 ) {
  1192 		return prev_volume;
  1193         return prev_volume;
  1193 	}
  1194     }
  1194 	if ( volume > SDL_MIX_MAXVOLUME ) {
  1195     if ( volume > SDL_MIX_MAXVOLUME ) {
  1195 		volume = SDL_MIX_MAXVOLUME;
  1196         volume = SDL_MIX_MAXVOLUME;
  1196 	}
  1197     }
  1197 	music_volume = volume;
  1198     music_volume = volume;
  1198 	SDL_LockAudio();
  1199     SDL_LockAudio();
  1199 	if ( music_playing ) {
  1200     if ( music_playing ) {
  1200 		music_internal_volume(music_volume);
  1201         music_internal_volume(music_volume);
  1201 	}
  1202     }
  1202 	SDL_UnlockAudio();
  1203     SDL_UnlockAudio();
  1203 	return(prev_volume);
  1204     return(prev_volume);
  1204 }
  1205 }
  1205 
  1206 
  1206 /* Halt playing of music */
  1207 /* Halt playing of music */
  1207 static void music_internal_halt(void)
  1208 static void music_internal_halt(void)
  1208 {
  1209 {
  1209 	switch (music_playing->type) {
  1210     switch (music_playing->type) {
  1210 #ifdef CMD_MUSIC
  1211 #ifdef CMD_MUSIC
  1211 	    case MUS_CMD:
  1212         case MUS_CMD:
  1212 		MusicCMD_Stop(music_playing->data.cmd);
  1213         MusicCMD_Stop(music_playing->data.cmd);
  1213 		break;
  1214         break;
  1214 #endif
  1215 #endif
  1215 #ifdef WAV_MUSIC
  1216 #ifdef WAV_MUSIC
  1216 	    case MUS_WAV:
  1217         case MUS_WAV:
  1217 		WAVStream_Stop();
  1218         WAVStream_Stop();
  1218 		break;
  1219         break;
  1219 #endif
  1220 #endif
  1220 #ifdef MODPLUG_MUSIC
  1221 #ifdef MODPLUG_MUSIC
  1221 	    case MUS_MODPLUG:
  1222         case MUS_MODPLUG:
  1222 		modplug_stop(music_playing->data.modplug);
  1223         modplug_stop(music_playing->data.modplug);
  1223 		break;
  1224         break;
  1224 #endif
  1225 #endif
  1225 #ifdef MOD_MUSIC
  1226 #ifdef MOD_MUSIC
  1226 	    case MUS_MOD:
  1227         case MUS_MOD:
  1227 		MOD_stop(music_playing->data.module);
  1228         MOD_stop(music_playing->data.module);
  1228 		break;
  1229         break;
  1229 #endif
  1230 #endif
  1230 #ifdef MID_MUSIC
  1231 #ifdef MID_MUSIC
  1231 	    case MUS_MID:
  1232         case MUS_MID:
  1232 #ifdef USE_NATIVE_MIDI
  1233 #ifdef USE_NATIVE_MIDI
  1233 		if ( native_midi_ok ) {
  1234         if ( native_midi_ok ) {
  1234 			native_midi_stop();
  1235             native_midi_stop();
  1235 			goto skip;
  1236             goto skip;
  1236 		}
  1237         }
  1237 #endif
  1238 #endif
  1238 #ifdef USE_FLUIDSYNTH_MIDI
  1239 #ifdef USE_FLUIDSYNTH_MIDI
  1239 		if ( fluidsynth_ok ) {
  1240         if ( fluidsynth_ok ) {
  1240 			fluidsynth_stop(music_playing->data.fluidsynthmidi);
  1241             fluidsynth_stop(music_playing->data.fluidsynthmidi);
  1241 			goto skip;
  1242             goto skip;
  1242 		}
  1243         }
  1243 #endif
  1244 #endif
  1244 #ifdef USE_TIMIDITY_MIDI
  1245 #ifdef USE_TIMIDITY_MIDI
  1245 		if ( timidity_ok ) {
  1246         if ( timidity_ok ) {
  1246 			Timidity_Stop();
  1247             Timidity_Stop();
  1247 			goto skip;
  1248             goto skip;
  1248 		}
  1249         }
  1249 #endif
  1250 #endif
  1250 		break;
  1251         break;
  1251 #endif
  1252 #endif
  1252 #ifdef OGG_MUSIC
  1253 #ifdef OGG_MUSIC
  1253 	    case MUS_OGG:
  1254         case MUS_OGG:
  1254 		OGG_stop(music_playing->data.ogg);
  1255         OGG_stop(music_playing->data.ogg);
  1255 		break;
  1256         break;
  1256 #endif
  1257 #endif
  1257 #ifdef FLAC_MUSIC
  1258 #ifdef FLAC_MUSIC
  1258 	    case MUS_FLAC:
  1259         case MUS_FLAC:
  1259 		FLAC_stop(music_playing->data.flac);
  1260         FLAC_stop(music_playing->data.flac);
  1260 		break;
  1261         break;
  1261 #endif
  1262 #endif
  1262 #ifdef MP3_MUSIC
  1263 #ifdef MP3_MUSIC
  1263 	    case MUS_MP3:
  1264         case MUS_MP3:
  1264 		smpeg.SMPEG_stop(music_playing->data.mp3);
  1265         smpeg.SMPEG_stop(music_playing->data.mp3);
  1265 		break;
  1266         break;
  1266 #endif
  1267 #endif
  1267 #ifdef MP3_MAD_MUSIC
  1268 #ifdef MP3_MAD_MUSIC
  1268 	    case MUS_MP3_MAD:
  1269         case MUS_MP3_MAD:
  1269 		mad_stop(music_playing->data.mp3_mad);
  1270         mad_stop(music_playing->data.mp3_mad);
  1270 		break;
  1271         break;
  1271 #endif
  1272 #endif
  1272 	    default:
  1273         default:
  1273 		/* Unknown music type?? */
  1274         /* Unknown music type?? */
  1274 		return;
  1275         return;
  1275 	}
  1276     }
  1276 
  1277 
  1277 skip:
  1278 skip:
  1278 	music_playing->fading = MIX_NO_FADING;
  1279     music_playing->fading = MIX_NO_FADING;
  1279 	music_playing = NULL;
  1280     music_playing = NULL;
  1280 }
  1281 }
  1281 int Mix_HaltMusic(void)
  1282 int Mix_HaltMusic(void)
  1282 {
  1283 {
  1283 	SDL_LockAudio();
  1284     SDL_LockAudio();
  1284 	if ( music_playing ) {
  1285     if ( music_playing ) {
  1285 		music_internal_halt();
  1286         music_internal_halt();
  1286 		if ( music_finished_hook ) {
  1287         if ( music_finished_hook ) {
  1287 			music_finished_hook();
  1288             music_finished_hook();
  1288 		}
  1289         }
  1289 	}
  1290     }
  1290 	SDL_UnlockAudio();
  1291     SDL_UnlockAudio();
  1291 
  1292 
  1292 	return(0);
  1293     return(0);
  1293 }
  1294 }
  1294 
  1295 
  1295 /* Progressively stop the music */
  1296 /* Progressively stop the music */
  1296 int Mix_FadeOutMusic(int ms)
  1297 int Mix_FadeOutMusic(int ms)
  1297 {
  1298 {
  1298 	int retval = 0;
  1299     int retval = 0;
  1299 
  1300 
  1300 	if ( ms_per_step == 0 ) {
  1301     if ( ms_per_step == 0 ) {
  1301 		SDL_SetError("Audio device hasn't been opened");
  1302         SDL_SetError("Audio device hasn't been opened");
  1302 		return 0;
  1303         return 0;
  1303 	}
  1304     }
  1304 
  1305 
  1305 	if (ms <= 0) {  /* just halt immediately. */
  1306     if (ms <= 0) {  /* just halt immediately. */
  1306 		Mix_HaltMusic();
  1307         Mix_HaltMusic();
  1307 		return 1;
  1308         return 1;
  1308 	}
  1309     }
  1309 
  1310 
  1310 	SDL_LockAudio();
  1311     SDL_LockAudio();
  1311 	if ( music_playing) {
  1312     if ( music_playing) {
  1312                 int fade_steps = (ms + ms_per_step - 1)/ms_per_step;
  1313                 int fade_steps = (ms + ms_per_step - 1)/ms_per_step;
  1313                 if ( music_playing->fading == MIX_NO_FADING ) {
  1314                 if ( music_playing->fading == MIX_NO_FADING ) {
  1314 	        	music_playing->fade_step = 0;
  1315                 music_playing->fade_step = 0;
  1315                 } else {
  1316                 } else {
  1316                         int step;
  1317                         int step;
  1317                         int old_fade_steps = music_playing->fade_steps;
  1318                         int old_fade_steps = music_playing->fade_steps;
  1318                         if ( music_playing->fading == MIX_FADING_OUT ) {
  1319                         if ( music_playing->fading == MIX_FADING_OUT ) {
  1319                                 step = music_playing->fade_step;
  1320                                 step = music_playing->fade_step;
  1322                                         - music_playing->fade_step + 1;
  1323                                         - music_playing->fade_step + 1;
  1323                         }
  1324                         }
  1324                         music_playing->fade_step = (step * fade_steps)
  1325                         music_playing->fade_step = (step * fade_steps)
  1325                                 / old_fade_steps;
  1326                                 / old_fade_steps;
  1326                 }
  1327                 }
  1327 		music_playing->fading = MIX_FADING_OUT;
  1328         music_playing->fading = MIX_FADING_OUT;
  1328 		music_playing->fade_steps = fade_steps;
  1329         music_playing->fade_steps = fade_steps;
  1329 		retval = 1;
  1330         retval = 1;
  1330 	}
  1331     }
  1331 	SDL_UnlockAudio();
  1332     SDL_UnlockAudio();
  1332 
  1333 
  1333 	return(retval);
  1334     return(retval);
  1334 }
  1335 }
  1335 
  1336 
  1336 Mix_Fading Mix_FadingMusic(void)
  1337 Mix_Fading Mix_FadingMusic(void)
  1337 {
  1338 {
  1338 	Mix_Fading fading = MIX_NO_FADING;
  1339     Mix_Fading fading = MIX_NO_FADING;
  1339 
  1340 
  1340 	SDL_LockAudio();
  1341     SDL_LockAudio();
  1341 	if ( music_playing ) {
  1342     if ( music_playing ) {
  1342 		fading = music_playing->fading;
  1343         fading = music_playing->fading;
  1343 	}
  1344     }
  1344 	SDL_UnlockAudio();
  1345     SDL_UnlockAudio();
  1345 
  1346 
  1346 	return(fading);
  1347     return(fading);
  1347 }
  1348 }
  1348 
  1349 
  1349 /* Pause/Resume the music stream */
  1350 /* Pause/Resume the music stream */
  1350 void Mix_PauseMusic(void)
  1351 void Mix_PauseMusic(void)
  1351 {
  1352 {
  1352 	music_active = 0;
  1353     music_active = 0;
  1353 }
  1354 }
  1354 
  1355 
  1355 void Mix_ResumeMusic(void)
  1356 void Mix_ResumeMusic(void)
  1356 {
  1357 {
  1357 	music_active = 1;
  1358     music_active = 1;
  1358 }
  1359 }
  1359 
  1360 
  1360 void Mix_RewindMusic(void)
  1361 void Mix_RewindMusic(void)
  1361 {
  1362 {
  1362 	Mix_SetMusicPosition(0.0);
  1363     Mix_SetMusicPosition(0.0);
  1363 }
  1364 }
  1364 
  1365 
  1365 int Mix_PausedMusic(void)
  1366 int Mix_PausedMusic(void)
  1366 {
  1367 {
  1367 	return (music_active == 0);
  1368     return (music_active == 0);
  1368 }
  1369 }
  1369 
  1370 
  1370 /* Check the status of the music */
  1371 /* Check the status of the music */
  1371 static int music_internal_playing()
  1372 static int music_internal_playing()
  1372 {
  1373 {
  1373 	int playing = 1;
  1374     int playing = 1;
  1374 
  1375 
  1375 	if (music_playing == NULL) {
  1376     if (music_playing == NULL) {
  1376 		return 0;
  1377         return 0;
  1377 	}
  1378     }
  1378 
  1379 
  1379 	switch (music_playing->type) {
  1380     switch (music_playing->type) {
  1380 #ifdef CMD_MUSIC
  1381 #ifdef CMD_MUSIC
  1381 	    case MUS_CMD:
  1382         case MUS_CMD:
  1382 		if (!MusicCMD_Active(music_playing->data.cmd)) {
  1383         if (!MusicCMD_Active(music_playing->data.cmd)) {
  1383 			playing = 0;
  1384             playing = 0;
  1384 		}
  1385         }
  1385 		break;
  1386         break;
  1386 #endif
  1387 #endif
  1387 #ifdef WAV_MUSIC
  1388 #ifdef WAV_MUSIC
  1388 	    case MUS_WAV:
  1389         case MUS_WAV:
  1389 		if ( ! WAVStream_Active() ) {
  1390         if ( ! WAVStream_Active() ) {
  1390 			playing = 0;
  1391             playing = 0;
  1391 		}
  1392         }
  1392 		break;
  1393         break;
  1393 #endif
  1394 #endif
  1394 #ifdef MODPLUG_MUSIC
  1395 #ifdef MODPLUG_MUSIC
  1395 	    case MUS_MODPLUG:
  1396         case MUS_MODPLUG:
  1396 		if ( ! modplug_playing(music_playing->data.modplug) ) {
  1397         if ( ! modplug_playing(music_playing->data.modplug) ) {
  1397 			playing = 0;
  1398             playing = 0;
  1398 		}
  1399         }
  1399 		break;
  1400         break;
  1400 #endif
  1401 #endif
  1401 #ifdef MOD_MUSIC
  1402 #ifdef MOD_MUSIC
  1402 	    case MUS_MOD:
  1403         case MUS_MOD:
  1403 		if ( ! MOD_playing(music_playing->data.module) ) {
  1404         if ( ! MOD_playing(music_playing->data.module) ) {
  1404 			playing = 0;
  1405             playing = 0;
  1405 		}
  1406         }
  1406 		break;
  1407         break;
  1407 #endif
  1408 #endif
  1408 #ifdef MID_MUSIC
  1409 #ifdef MID_MUSIC
  1409 	    case MUS_MID:
  1410         case MUS_MID:
  1410 #ifdef USE_NATIVE_MIDI
  1411 #ifdef USE_NATIVE_MIDI
  1411 		if ( native_midi_ok ) {
  1412         if ( native_midi_ok ) {
  1412 			if ( ! native_midi_active() )
  1413             if ( ! native_midi_active() )
  1413 				playing = 0;
  1414                 playing = 0;
  1414 			goto skip;
  1415             goto skip;
  1415 		}
  1416         }
  1416 #endif
  1417 #endif
  1417 #ifdef USE_FLUIDSYNTH_MIDI
  1418 #ifdef USE_FLUIDSYNTH_MIDI
  1418 		if ( fluidsynth_ok ) {
  1419         if ( fluidsynth_ok ) {
  1419 			if ( ! fluidsynth_active(music_playing->data.fluidsynthmidi) )
  1420             if ( ! fluidsynth_active(music_playing->data.fluidsynthmidi) )
  1420 				playing = 0;
  1421                 playing = 0;
  1421 			goto skip;
  1422             goto skip;
  1422 		}
  1423         }
  1423 #endif
  1424 #endif
  1424 #ifdef USE_TIMIDITY_MIDI
  1425 #ifdef USE_TIMIDITY_MIDI
  1425 		if ( timidity_ok ) {
  1426         if ( timidity_ok ) {
  1426 			if ( ! Timidity_Active() )
  1427             if ( ! Timidity_Active() )
  1427 				playing = 0;
  1428                 playing = 0;
  1428 			goto skip;
  1429             goto skip;
  1429 		}
  1430         }
  1430 #endif
  1431 #endif
  1431 		break;
  1432         break;
  1432 #endif
  1433 #endif
  1433 #ifdef OGG_MUSIC
  1434 #ifdef OGG_MUSIC
  1434 	    case MUS_OGG:
  1435         case MUS_OGG:
  1435 		if ( ! OGG_playing(music_playing->data.ogg) ) {
  1436         if ( ! OGG_playing(music_playing->data.ogg) ) {
  1436 			playing = 0;
  1437             playing = 0;
  1437 		}
  1438         }
  1438 		break;
  1439         break;
  1439 #endif
  1440 #endif
  1440 #ifdef FLAC_MUSIC
  1441 #ifdef FLAC_MUSIC
  1441 	    case MUS_FLAC:
  1442         case MUS_FLAC:
  1442 		if ( ! FLAC_playing(music_playing->data.flac) ) {
  1443         if ( ! FLAC_playing(music_playing->data.flac) ) {
  1443 			playing = 0;
  1444             playing = 0;
  1444 		}
  1445         }
  1445 		break;
  1446         break;
  1446 #endif
  1447 #endif
  1447 #ifdef MP3_MUSIC
  1448 #ifdef MP3_MUSIC
  1448 	    case MUS_MP3:
  1449         case MUS_MP3:
  1449 		if ( smpeg.SMPEG_status(music_playing->data.mp3) != SMPEG_PLAYING )
  1450         if ( smpeg.SMPEG_status(music_playing->data.mp3) != SMPEG_PLAYING )
  1450 			playing = 0;
  1451             playing = 0;
  1451 		break;
  1452         break;
  1452 #endif
  1453 #endif
  1453 #ifdef MP3_MAD_MUSIC
  1454 #ifdef MP3_MAD_MUSIC
  1454 	    case MUS_MP3_MAD:
  1455         case MUS_MP3_MAD:
  1455 		if (!mad_isPlaying(music_playing->data.mp3_mad)) {
  1456         if (!mad_isPlaying(music_playing->data.mp3_mad)) {
  1456 			playing = 0;
  1457             playing = 0;
  1457 		}
  1458         }
  1458 		break;
  1459         break;
  1459 #endif
  1460 #endif
  1460 	    default:
  1461         default:
  1461 		playing = 0;
  1462         playing = 0;
  1462 		break;
  1463         break;
  1463 	}
  1464     }
  1464 
  1465 
  1465 skip:
  1466 skip:
  1466 	return(playing);
  1467     return(playing);
  1467 }
  1468 }
  1468 int Mix_PlayingMusic(void)
  1469 int Mix_PlayingMusic(void)
  1469 {
  1470 {
  1470 	int playing = 0;
  1471     int playing = 0;
  1471 
  1472 
  1472 	SDL_LockAudio();
  1473     SDL_LockAudio();
  1473 	if ( music_playing ) {
  1474     if ( music_playing ) {
  1474 		playing = music_loops || music_internal_playing();
  1475         playing = music_loops || music_internal_playing();
  1475 	}
  1476     }
  1476 	SDL_UnlockAudio();
  1477     SDL_UnlockAudio();
  1477 
  1478 
  1478 	return(playing);
  1479     return(playing);
  1479 }
  1480 }
  1480 
  1481 
  1481 /* Set the external music playback command */
  1482 /* Set the external music playback command */
  1482 int Mix_SetMusicCMD(const char *command)
  1483 int Mix_SetMusicCMD(const char *command)
  1483 {
  1484 {
  1484 	Mix_HaltMusic();
  1485     Mix_HaltMusic();
  1485 	if ( music_cmd ) {
  1486     if ( music_cmd ) {
  1486 		SDL_free(music_cmd);
  1487         SDL_free(music_cmd);
  1487 		music_cmd = NULL;
  1488         music_cmd = NULL;
  1488 	}
  1489     }
  1489 	if ( command ) {
  1490     if ( command ) {
  1490 		music_cmd = (char *)SDL_malloc(strlen(command)+1);
  1491         music_cmd = (char *)SDL_malloc(strlen(command)+1);
  1491 		if ( music_cmd == NULL ) {
  1492         if ( music_cmd == NULL ) {
  1492 			return(-1);
  1493             return(-1);
  1493 		}
  1494         }
  1494 		strcpy(music_cmd, command);
  1495         strcpy(music_cmd, command);
  1495 	}
  1496     }
  1496 	return(0);
  1497     return(0);
  1497 }
  1498 }
  1498 
  1499 
  1499 int Mix_SetSynchroValue(int i)
  1500 int Mix_SetSynchroValue(int i)
  1500 {
  1501 {
  1501 	/* Not supported by any players at this time */
  1502     /* Not supported by any players at this time */
  1502 	return(-1);
  1503     return(-1);
  1503 }
  1504 }
  1504 
  1505 
  1505 int Mix_GetSynchroValue(void)
  1506 int Mix_GetSynchroValue(void)
  1506 {
  1507 {
  1507 	/* Not supported by any players at this time */
  1508     /* Not supported by any players at this time */
  1508 	return(-1);
  1509     return(-1);
  1509 }
  1510 }
  1510 
  1511 
  1511 
  1512 
  1512 /* Uninitialize the music players */
  1513 /* Uninitialize the music players */
  1513 void close_music(void)
  1514 void close_music(void)
  1514 {
  1515 {
  1515 	Mix_HaltMusic();
  1516     Mix_HaltMusic();
  1516 #ifdef CMD_MUSIC
  1517 #ifdef CMD_MUSIC
  1517 	Mix_SetMusicCMD(NULL);
  1518     Mix_SetMusicCMD(NULL);
  1518 #endif
  1519 #endif
  1519 #ifdef MODPLUG_MUSIC
  1520 #ifdef MODPLUG_MUSIC
  1520 	modplug_exit();
  1521     modplug_exit();
  1521 #endif
  1522 #endif
  1522 #ifdef MOD_MUSIC
  1523 #ifdef MOD_MUSIC
  1523 	MOD_exit();
  1524     MOD_exit();
  1524 #endif
  1525 #endif
  1525 #ifdef MID_MUSIC
  1526 #ifdef MID_MUSIC
  1526 # ifdef USE_TIMIDITY_MIDI
  1527 # ifdef USE_TIMIDITY_MIDI
  1527 	Timidity_Close();
  1528     Timidity_Close();
  1528 # endif
  1529 # endif
  1529 #endif
  1530 #endif
  1530 
  1531 
  1531 	/* rcg06042009 report available decoders at runtime. */
  1532     /* rcg06042009 report available decoders at runtime. */
  1532 	SDL_free(music_decoders);
  1533     SDL_free(music_decoders);
  1533 	music_decoders = NULL;
  1534     music_decoders = NULL;
  1534 	num_decoders = 0;
  1535     num_decoders = 0;
  1535 
  1536 
  1536 	ms_per_step = 0;
  1537     ms_per_step = 0;
  1537 }
  1538 }
  1538 
  1539 
  1539 int Mix_SetSoundFonts(const char *paths)
  1540 int Mix_SetSoundFonts(const char *paths)
  1540 {
  1541 {
  1541 #ifdef MID_MUSIC
  1542 #ifdef MID_MUSIC
  1542 	if (soundfont_paths) {
  1543     if (soundfont_paths) {
  1543 		SDL_free(soundfont_paths);
  1544         SDL_free(soundfont_paths);
  1544 		soundfont_paths = NULL;
  1545         soundfont_paths = NULL;
  1545 	}
  1546     }
  1546 
  1547 
  1547 	if (paths) {
  1548     if (paths) {
  1548 		if (!(soundfont_paths = SDL_strdup(paths))) {
  1549         if (!(soundfont_paths = SDL_strdup(paths))) {
  1549 			Mix_SetError("Insufficient memory to set SoundFonts");
  1550             Mix_SetError("Insufficient memory to set SoundFonts");
  1550 			return 0;
  1551             return 0;
  1551 		}
  1552         }
  1552 	}
  1553     }
  1553 #endif
  1554 #endif
  1554 	return 1;
  1555     return 1;
  1555 }
  1556 }
  1556 
  1557 
  1557 #ifdef MID_MUSIC
  1558 #ifdef MID_MUSIC
  1558 const char* Mix_GetSoundFonts(void)
  1559 const char* Mix_GetSoundFonts(void)
  1559 {
  1560 {
  1560 	const char* force = getenv("SDL_FORCE_SOUNDFONTS");
  1561     const char* force = getenv("SDL_FORCE_SOUNDFONTS");
  1561 
  1562 
  1562 	if (!soundfont_paths || (force && force[0] == '1')) {
  1563     if (!soundfont_paths || (force && force[0] == '1')) {
  1563 		return getenv("SDL_SOUNDFONTS");
  1564         return getenv("SDL_SOUNDFONTS");
  1564 	} else {
  1565     } else {
  1565 		return soundfont_paths;
  1566         return soundfont_paths;
  1566 	}
  1567     }
  1567 }
  1568 }
  1568 
  1569 
  1569 int Mix_EachSoundFont(int (*function)(const char*, void*), void *data)
  1570 int Mix_EachSoundFont(int (*function)(const char*, void*), void *data)
  1570 {
  1571 {
  1571 	char *context, *path, *paths;
  1572     char *context, *path, *paths;
  1572 	const char* cpaths = Mix_GetSoundFonts();
  1573     const char* cpaths = Mix_GetSoundFonts();
  1573 
  1574 
  1574 	if (!cpaths) {
  1575     if (!cpaths) {
  1575 		Mix_SetError("No SoundFonts have been requested");
  1576         Mix_SetError("No SoundFonts have been requested");
  1576 		return 0;
  1577         return 0;
  1577 	}
  1578     }
  1578 
  1579 
  1579 	if (!(paths = SDL_strdup(cpaths))) {
  1580     if (!(paths = SDL_strdup(cpaths))) {
  1580 		Mix_SetError("Insufficient memory to iterate over SoundFonts");
  1581         Mix_SetError("Insufficient memory to iterate over SoundFonts");
  1581 		return 0;
  1582         return 0;
  1582 	}
  1583     }
  1583 
  1584 
  1584 #if defined(__MINGW32__) || defined(__MINGW64__)
  1585 #if defined(__MINGW32__) || defined(__MINGW64__)
  1585 	for (path = strtok(paths, ";"); path; path = strtok(NULL, ";")) {
  1586     for (path = strtok(paths, ";"); path; path = strtok(NULL, ";")) {
  1586 #elif defined(_WIN32)
  1587 #elif defined(_WIN32)
  1587 	for (path = strtok_s(paths, ";", &context); path; path = strtok_s(NULL, ";", &context)) {
  1588     for (path = strtok_s(paths, ";", &context); path; path = strtok_s(NULL, ";", &context)) {
  1588 #else
  1589 #else
  1589 	for (path = strtok_r(paths, ":;", &context); path; path = strtok_r(NULL, ":;", &context)) {
  1590     for (path = strtok_r(paths, ":;", &context); path; path = strtok_r(NULL, ":;", &context)) {
  1590 #endif
  1591 #endif
  1591 		if (!function(path, data)) {
  1592         if (!function(path, data)) {
  1592 			SDL_free(paths);
  1593             SDL_free(paths);
  1593 			return 0;
  1594             return 0;
  1594 		}
  1595         }
  1595 	}
  1596     }
  1596 
  1597 
  1597 	SDL_free(paths);
  1598     SDL_free(paths);
  1598 	return 1;
  1599     return 1;
  1599 }
  1600 }
  1600 #endif
  1601 #endif