music.c
author Sam Lantinga <slouken@libsdl.org>
Fri, 06 Nov 2009 03:37:57 +0000
changeset 467 4b52401dda92
parent 466 d3d060cb94a6
child 470 5cebd6c5be2d
permissions -rw-r--r--
Fixed bug #877

Mike Frysinger 2009-11-05 09:11:43 PST

the current code assumes "unix" means fork() exists. this doesnt work for
no-mmu linux systems as fork() cant be implemented.

simple enough to add fork/vfork tests to configure and let the rest of the code
key off of CMD_MUSIC like normal -- no more needing to hardcode unix/mac-os-x
defines in the source.
     1 /*
     2     SDL_mixer:  An audio mixer library based on the SDL library
     3     Copyright (C) 1997-2009 Sam Lantinga
     4 
     5     This library is free software; you can redistribute it and/or
     6     modify it under the terms of the GNU Library General Public
     7     License as published by the Free Software Foundation; either
     8     version 2 of the License, or (at your option) any later version.
     9 
    10     This library is distributed in the hope that it will be useful,
    11     but WITHOUT ANY WARRANTY; without even the implied warranty of
    12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    13     Library General Public License for more details.
    14 
    15     You should have received a copy of the GNU Library General Public
    16     License along with this library; if not, write to the Free
    17     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    18 
    19     Sam Lantinga
    20     slouken@libsdl.org
    21 */
    22 
    23 /* $Id$ */
    24 
    25 #include <stdlib.h>
    26 #include <string.h>
    27 #include <ctype.h>
    28 #include <assert.h>
    29 #include "SDL_endian.h"
    30 #include "SDL_audio.h"
    31 #include "SDL_timer.h"
    32 
    33 #include "SDL_mixer.h"
    34 
    35 #ifdef CMD_MUSIC
    36 #include "music_cmd.h"
    37 #endif
    38 #ifdef WAV_MUSIC
    39 #include "wavestream.h"
    40 #endif
    41 #ifdef MOD_MUSIC
    42 #include "music_mod.h"
    43 #endif
    44 #ifdef MID_MUSIC
    45 #  ifdef USE_TIMIDITY_MIDI
    46 #    include "timidity.h"
    47 #  endif
    48 #  ifdef USE_NATIVE_MIDI
    49 #    include "native_midi.h"
    50 #  endif
    51 #  if defined(USE_TIMIDITY_MIDI) && defined(USE_NATIVE_MIDI)
    52 #    define MIDI_ELSE	else
    53 #  else
    54 #    define MIDI_ELSE
    55 #  endif
    56 #endif
    57 #ifdef OGG_MUSIC
    58 #include "music_ogg.h"
    59 #endif
    60 #ifdef MP3_MUSIC
    61 #include "dynamic_mp3.h"
    62 #endif
    63 #ifdef MP3_MAD_MUSIC
    64 #include "music_mad.h"
    65 #endif
    66 #ifdef FLAC_MUSIC
    67 #include "music_flac.h"
    68 #endif
    69 
    70 #if defined(MP3_MUSIC) || defined(MP3_MAD_MUSIC)
    71 static SDL_AudioSpec used_mixer;
    72 #endif
    73 
    74 
    75 int volatile music_active = 1;
    76 static int volatile music_stopped = 0;
    77 static int music_loops = 0;
    78 static char *music_cmd = NULL;
    79 static Mix_Music * volatile music_playing = NULL;
    80 static int music_volume = MIX_MAX_VOLUME;
    81 
    82 struct _Mix_Music {
    83 	Mix_MusicType type;
    84 	union {
    85 #ifdef CMD_MUSIC
    86 		MusicCMD *cmd;
    87 #endif
    88 #ifdef WAV_MUSIC
    89 		WAVStream *wave;
    90 #endif
    91 #ifdef MOD_MUSIC
    92 		struct MODULE *module;
    93 #endif
    94 #ifdef MID_MUSIC
    95 #ifdef USE_TIMIDITY_MIDI
    96 		MidiSong *midi;
    97 #endif
    98 #ifdef USE_NATIVE_MIDI
    99 		NativeMidiSong *nativemidi;
   100 #endif
   101 #endif
   102 #ifdef OGG_MUSIC
   103 		OGG_music *ogg;
   104 #endif
   105 #ifdef MP3_MUSIC
   106 		SMPEG *mp3;
   107 #endif
   108 #ifdef MP3_MAD_MUSIC
   109 		mad_data *mp3_mad;
   110 #endif
   111 #ifdef FLAC_MUSIC
   112 		FLAC_music *flac;
   113 #endif
   114 	} data;
   115 	Mix_Fading fading;
   116 	int fade_step;
   117 	int fade_steps;
   118 	int error;
   119 };
   120 #ifdef MID_MUSIC
   121 #ifdef USE_TIMIDITY_MIDI
   122 static int timidity_ok;
   123 static int samplesize;
   124 #endif
   125 #ifdef USE_NATIVE_MIDI
   126 static int native_midi_ok;
   127 #endif
   128 #endif
   129 
   130 /* Used to calculate fading steps */
   131 static int ms_per_step;
   132 
   133 /* rcg06042009 report available decoders at runtime. */
   134 static const char **music_decoders = NULL;
   135 static int num_decoders = 0;
   136 
   137 int Mix_GetNumMusicDecoders(void)
   138 {
   139 	return(num_decoders);
   140 }
   141 
   142 const char *Mix_GetMusicDecoder(int index)
   143 {
   144 	if ((index < 0) || (index >= num_decoders)) {
   145 		return NULL;
   146 	}
   147 	return(music_decoders[index]);
   148 }
   149 
   150 static void add_music_decoder(const char *decoder)
   151 {
   152 	void *ptr = realloc(music_decoders, (num_decoders + 1) * sizeof (const char **));
   153 	if (ptr == NULL) {
   154 		return;  /* oh well, go on without it. */
   155 	}
   156 	music_decoders = (const char **) ptr;
   157 	music_decoders[num_decoders++] = decoder;
   158 }
   159 
   160 /* Local low-level functions prototypes */
   161 static void music_internal_initialize_volume(void);
   162 static void music_internal_volume(int volume);
   163 static int  music_internal_play(Mix_Music *music, double position);
   164 static int  music_internal_position(double position);
   165 static int  music_internal_playing();
   166 static void music_internal_halt(void);
   167 
   168 
   169 /* Support for hooking when the music has finished */
   170 static void (*music_finished_hook)(void) = NULL;
   171 
   172 void Mix_HookMusicFinished(void (*music_finished)(void))
   173 {
   174 	SDL_LockAudio();
   175 	music_finished_hook = music_finished;
   176 	SDL_UnlockAudio();
   177 }
   178 
   179 
   180 /* If music isn't playing, halt it if no looping is required, restart it */
   181 /* otherwhise. NOP if the music is playing */
   182 static int music_halt_or_loop (void)
   183 {
   184 	/* Restart music if it has to loop */
   185 	
   186 	if (!music_internal_playing()) 
   187 	{
   188 		/* Restart music if it has to loop at a high level */
   189 		if (music_loops && --music_loops)
   190 		{
   191 			Mix_Fading current_fade = music_playing->fading;
   192 			music_internal_play(music_playing, 0.0);
   193 			music_playing->fading = current_fade;
   194 		} 
   195 		else 
   196 		{
   197 			music_internal_halt();
   198 			if (music_finished_hook)
   199 				music_finished_hook();
   200 			
   201 			return 0;
   202 		}
   203 	}
   204 	
   205 	return 1;
   206 }
   207 
   208 
   209 
   210 /* Mixing function */
   211 void music_mixer(void *udata, Uint8 *stream, int len)
   212 {
   213 	int left = 0;
   214 
   215 	if ( music_playing && music_active ) {
   216 		/* Handle fading */
   217 		if ( music_playing->fading != MIX_NO_FADING ) {
   218 			if ( music_playing->fade_step++ < music_playing->fade_steps ) {
   219 				int volume;
   220 				int fade_step = music_playing->fade_step;
   221 				int fade_steps = music_playing->fade_steps;
   222 
   223 				if ( music_playing->fading == MIX_FADING_OUT ) {
   224 					volume = (music_volume * (fade_steps-fade_step)) / fade_steps;
   225 				} else { /* Fading in */
   226 					volume = (music_volume * fade_step) / fade_steps;
   227 				}
   228 				music_internal_volume(volume);
   229 			} else {
   230 				if ( music_playing->fading == MIX_FADING_OUT ) {
   231 					music_internal_halt();
   232 					if ( music_finished_hook ) {
   233 						music_finished_hook();
   234 					}
   235 					return;
   236 				}
   237 				music_playing->fading = MIX_NO_FADING;
   238 			}
   239 		}
   240 		
   241 		if (music_halt_or_loop() == 0)
   242 			return;
   243 		
   244 		
   245 		switch (music_playing->type) {
   246 #ifdef CMD_MUSIC
   247 			case MUS_CMD:
   248 				/* The playing is done externally */
   249 				break;
   250 #endif
   251 #ifdef WAV_MUSIC
   252 			case MUS_WAV:
   253 				left = WAVStream_PlaySome(stream, len);
   254 				break;
   255 #endif
   256 #ifdef MOD_MUSIC
   257 			case MUS_MOD:
   258 				left = MOD_playAudio(music_playing->data.module, stream, len);
   259 				break;
   260 #endif
   261 #ifdef MID_MUSIC
   262 #ifdef USE_TIMIDITY_MIDI
   263 			case MUS_MID:
   264 				if ( timidity_ok ) {
   265 					int samples = len / samplesize;
   266   					Timidity_PlaySome(stream, samples);
   267 				}
   268 				break;
   269 #endif
   270 #endif
   271 #ifdef OGG_MUSIC
   272 			case MUS_OGG:
   273 				
   274 				left = OGG_playAudio(music_playing->data.ogg, stream, len);
   275 				break;
   276 #endif
   277 #ifdef FLAC_MUSIC
   278 			case MUS_FLAC:
   279 				left = FLAC_playAudio(music_playing->data.flac, stream, len);
   280 				break;
   281 #endif
   282 #ifdef MP3_MUSIC
   283 			case MUS_MP3:
   284 				left = (len - smpeg.SMPEG_playAudio(music_playing->data.mp3, stream, len));
   285 				break;
   286 #endif
   287 #ifdef MP3_MAD_MUSIC
   288 			case MUS_MP3_MAD:
   289 				left = mad_getSamples(music_playing->data.mp3_mad, stream, len);
   290 				break;
   291 #endif
   292 			default:
   293 				/* Unknown music type?? */
   294 				break;
   295 		}
   296 	}
   297 
   298 	/* Handle seamless music looping */
   299 	if (left > 0 && left < len && music_halt_or_loop()) {
   300 		music_mixer(udata, stream+(len-left), left);
   301 	}
   302 }
   303 
   304 /* Initialize the music players with a certain desired audio format */
   305 int open_music(SDL_AudioSpec *mixer)
   306 {
   307 	int music_error = 0;
   308 
   309 #ifdef WAV_MUSIC
   310 	if ( WAVStream_Init(mixer) < 0 ) {
   311 		++music_error;
   312 	} else {
   313 		add_music_decoder("WAVE");
   314 	}
   315 #endif
   316 #ifdef MOD_MUSIC
   317 	if ( MOD_init(mixer) < 0 ) {
   318 		++music_error;
   319 	} else {
   320 		add_music_decoder("MIKMOD");
   321 	}
   322 #endif
   323 #ifdef MID_MUSIC
   324 #ifdef USE_TIMIDITY_MIDI
   325 	samplesize = mixer->size / mixer->samples;
   326 	if ( Timidity_Init(mixer->freq, mixer->format,
   327 	                    mixer->channels, mixer->samples) == 0 ) {
   328 		timidity_ok = 1;
   329 		add_music_decoder("TIMIDITY");
   330 	} else {
   331 		timidity_ok = 0;
   332 	}
   333 #endif
   334 #ifdef USE_NATIVE_MIDI
   335 #ifdef USE_TIMIDITY_MIDI
   336 	native_midi_ok = !timidity_ok;
   337 	if ( !native_midi_ok ) {
   338 		native_midi_ok = (getenv("SDL_NATIVE_MUSIC") != NULL);
   339 	}
   340 	if ( native_midi_ok )
   341 #endif
   342 		native_midi_ok = native_midi_detect();
   343 	if ( native_midi_ok )
   344 		add_music_decoder("NATIVEMIDI");
   345 #endif
   346 #endif
   347 #ifdef OGG_MUSIC
   348 	if ( OGG_init(mixer) < 0 ) {
   349 		++music_error;
   350 	} else {
   351 		add_music_decoder("OGG");
   352 	}
   353 #endif
   354 #ifdef FLAC_MUSIC
   355 	if ( FLAC_init(mixer) < 0 ) {
   356 		++music_error;
   357 	} else {
   358 		add_music_decoder("FLAC");
   359 	}
   360 #endif
   361 #if defined(MP3_MUSIC) || defined(MP3_MAD_MUSIC)
   362 	/* Keep a copy of the mixer */
   363 	used_mixer = *mixer;
   364 	add_music_decoder("MP3");
   365 #endif
   366 
   367 	music_playing = NULL;
   368 	music_stopped = 0;
   369 	if ( music_error ) {
   370 		return(-1);
   371 	}
   372 	Mix_VolumeMusic(SDL_MIX_MAXVOLUME);
   373 
   374 	/* Calculate the number of ms for each callback */
   375 	ms_per_step = (int) (((float)mixer->samples * 1000.0) / mixer->freq);
   376 
   377 	return(0);
   378 }
   379 
   380 /* Portable case-insensitive string compare function */
   381 int MIX_string_equals(const char *str1, const char *str2)
   382 {
   383 	while ( *str1 && *str2 ) {
   384 		if ( toupper((unsigned char)*str1) !=
   385 		     toupper((unsigned char)*str2) )
   386 			break;
   387 		++str1;
   388 		++str2;
   389 	}
   390 	return (!*str1 && !*str2);
   391 }
   392 
   393 /* Load a music file */
   394 Mix_Music *Mix_LoadMUS(const char *file)
   395 {
   396 	FILE *fp;
   397 	char *ext;
   398 	Uint8 magic[5], moremagic[9];
   399 	Mix_Music *music;
   400 
   401 	/* Figure out what kind of file this is */
   402 	fp = fopen(file, "rb");
   403 	if ( (fp == NULL) || !fread(magic, 4, 1, fp) ) {
   404 		if ( fp != NULL ) {
   405 			fclose(fp);
   406 		}
   407 		Mix_SetError("Couldn't read from '%s'", file);
   408 		return(NULL);
   409 	}
   410 	if (!fread(moremagic, 8, 1, fp)) {
   411 		Mix_SetError("Couldn't read from '%s'", file);
   412 		return(NULL);
   413 	}
   414 	magic[4] = '\0';
   415 	moremagic[8] = '\0';
   416 	fclose(fp);
   417 
   418 	/* Figure out the file extension, so we can determine the type */
   419 	ext = strrchr(file, '.');
   420 	if ( ext ) ++ext; /* skip the dot in the extension */
   421 
   422 	/* Allocate memory for the music structure */
   423 	music = (Mix_Music *)malloc(sizeof(Mix_Music));
   424 	if ( music == NULL ) {
   425 		Mix_SetError("Out of memory");
   426 		return(NULL);
   427 	}
   428 	music->error = 0;
   429 
   430 #ifdef CMD_MUSIC
   431 	if ( music_cmd ) {
   432 		music->type = MUS_CMD;
   433 		music->data.cmd = MusicCMD_LoadSong(music_cmd, file);
   434 		if ( music->data.cmd == NULL ) {
   435 			music->error = 1;
   436 		}
   437 	} else
   438 #endif
   439 #ifdef WAV_MUSIC
   440 	/* WAVE files have the magic four bytes "RIFF"
   441 	   AIFF files have the magic 12 bytes "FORM" XXXX "AIFF"
   442 	 */
   443 	if ( (ext && MIX_string_equals(ext, "WAV")) ||
   444 	     ((strcmp((char *)magic, "RIFF") == 0) && (strcmp((char *)(moremagic+4), "WAVE") == 0)) ||
   445 	     (strcmp((char *)magic, "FORM") == 0) ) {
   446 		music->type = MUS_WAV;
   447 		music->data.wave = WAVStream_LoadSong(file, (char *)magic);
   448 		if ( music->data.wave == NULL ) {
   449 		  	Mix_SetError("Unable to load WAV file");
   450 			music->error = 1;
   451 		}
   452 	} else
   453 #endif
   454 #ifdef MID_MUSIC
   455 	/* MIDI files have the magic four bytes "MThd" */
   456 	if ( (ext && MIX_string_equals(ext, "MID")) ||
   457 	     (ext && MIX_string_equals(ext, "MIDI")) ||
   458 	     strcmp((char *)magic, "MThd") == 0  ||
   459 	     ( strcmp((char *)magic, "RIFF") == 0  &&
   460 	  	strcmp((char *)(moremagic+4), "RMID") == 0 ) ) {
   461 		music->type = MUS_MID;
   462 #ifdef USE_NATIVE_MIDI
   463   		if ( native_midi_ok ) {
   464   			music->data.nativemidi = native_midi_loadsong(file);
   465 	  		if ( music->data.nativemidi == NULL ) {
   466 		  		Mix_SetError("%s", native_midi_error());
   467 			  	music->error = 1;
   468 			}
   469 	  	} MIDI_ELSE
   470 #endif
   471 #ifdef USE_TIMIDITY_MIDI
   472 		if ( timidity_ok ) {
   473 			music->data.midi = Timidity_LoadSong(file);
   474 			if ( music->data.midi == NULL ) {
   475 				Mix_SetError("%s", Timidity_Error());
   476 				music->error = 1;
   477 			}
   478 		} else {
   479 			Mix_SetError("%s", Timidity_Error());
   480 			music->error = 1;
   481 		}
   482 #endif
   483 	} else
   484 #endif
   485 #ifdef OGG_MUSIC
   486 	/* Ogg Vorbis files have the magic four bytes "OggS" */
   487 	if ( (ext && MIX_string_equals(ext, "OGG")) ||
   488 	     strcmp((char *)magic, "OggS") == 0 ) {
   489 		music->type = MUS_OGG;
   490 		music->data.ogg = OGG_new(file);
   491 		if ( music->data.ogg == NULL ) {
   492 			music->error = 1;
   493 		}
   494 	} else
   495 #endif
   496 #ifdef FLAC_MUSIC
   497 	/* FLAC files have the magic four bytes "fLaC" */
   498 	if ( (ext && MIX_string_equals(ext, "FLAC")) ||
   499 		 strcmp((char *)magic, "fLaC") == 0 ) {
   500 		music->type = MUS_FLAC;
   501 		music->data.flac = FLAC_new(file);
   502 		if ( music->data.flac == NULL ) {
   503 			music->error = 1;
   504 		}
   505 	} else
   506 #endif
   507 #ifdef MP3_MUSIC
   508 	if ( (ext && MIX_string_equals(ext, "MPG")) ||
   509 	     (ext && MIX_string_equals(ext, "MP3")) ||
   510 	     (ext && MIX_string_equals(ext, "MPEG")) ||
   511 	     (magic[0] == 0xFF && (magic[1] & 0xF0) == 0xF0) ||
   512 	     (strncmp((char *)magic, "ID3", 3) == 0) ) {
   513 		if ( Mix_InitMP3() == 0 ) {
   514 			SMPEG_Info info;
   515 			music->type = MUS_MP3;
   516 			music->data.mp3 = smpeg.SMPEG_new(file, &info, 0);
   517 			if ( !info.has_audio ) {
   518 				Mix_SetError("MPEG file does not have any audio stream.");
   519 				music->error = 1;
   520 			} else {
   521 				smpeg.SMPEG_actualSpec(music->data.mp3, &used_mixer);
   522 			}
   523 		} else {
   524 			music->error = 1;
   525 		}
   526 	} else
   527 #endif
   528 #ifdef MP3_MAD_MUSIC
   529 	if ( (ext && MIX_string_equals(ext, "MPG")) ||
   530 	     (ext && MIX_string_equals(ext, "MP3")) ||
   531 	     (ext && MIX_string_equals(ext, "MPEG")) ||
   532 	     (ext && MIX_string_equals(ext, "MAD")) ||
   533 	     (magic[0] == 0xFF && (magic[1] & 0xF0) == 0xF0) ||
   534 	     (strncmp((char *)magic, "ID3", 3) == 0) ) {
   535 		music->type = MUS_MP3_MAD;
   536 		music->data.mp3_mad = mad_openFile(file, &used_mixer);
   537 		if (music->data.mp3_mad == 0) {
   538 		    Mix_SetError("Could not initialize MPEG stream.");
   539 			music->error = 1;
   540 		}
   541 	} else
   542 #endif
   543 #ifdef MOD_MUSIC
   544 	if ( 1 ) {
   545 		music->type = MUS_MOD;
   546 		music->data.module = MOD_new(file);
   547 		if ( music->data.module == NULL ) {
   548 			music->error = 1;
   549 		}
   550 	} else
   551 #endif
   552 	{
   553 		Mix_SetError("Unrecognized music format");
   554 		music->error = 1;
   555 	}
   556 	if ( music->error ) {
   557 		free(music);
   558 		music = NULL;
   559 	}
   560 	return(music);
   561 }
   562 
   563 /* Free a music chunk previously loaded */
   564 void Mix_FreeMusic(Mix_Music *music)
   565 {
   566 	if ( music ) {
   567 		/* Stop the music if it's currently playing */
   568 		SDL_LockAudio();
   569 		if ( music == music_playing ) {
   570 			/* Wait for any fade out to finish */
   571 			while ( music->fading == MIX_FADING_OUT ) {
   572 				SDL_UnlockAudio();
   573 				SDL_Delay(100);
   574 				SDL_LockAudio();
   575 			}
   576 			if ( music == music_playing ) {
   577 				music_internal_halt();
   578 			}
   579 		}
   580 		SDL_UnlockAudio();
   581 		switch (music->type) {
   582 #ifdef CMD_MUSIC
   583 			case MUS_CMD:
   584 				MusicCMD_FreeSong(music->data.cmd);
   585 				break;
   586 #endif
   587 #ifdef WAV_MUSIC
   588 			case MUS_WAV:
   589 				WAVStream_FreeSong(music->data.wave);
   590 				break;
   591 #endif
   592 #ifdef MOD_MUSIC
   593 			case MUS_MOD:
   594 				MOD_delete(music->data.module);
   595 				break;
   596 #endif
   597 #ifdef MID_MUSIC
   598 			case MUS_MID:
   599 #ifdef USE_NATIVE_MIDI
   600   				if ( native_midi_ok ) {
   601 					native_midi_freesong(music->data.nativemidi);
   602 				} MIDI_ELSE
   603 #endif
   604 #ifdef USE_TIMIDITY_MIDI
   605 				if ( timidity_ok ) {
   606 					Timidity_FreeSong(music->data.midi);
   607 				}
   608 #endif
   609 				break;
   610 #endif
   611 #ifdef OGG_MUSIC
   612 			case MUS_OGG:
   613 				OGG_delete(music->data.ogg);
   614 				break;
   615 #endif
   616 #ifdef FLAC_MUSIC
   617 			case MUS_FLAC:
   618 				FLAC_delete(music->data.flac);
   619 				break;
   620 #endif
   621 #ifdef MP3_MUSIC
   622 			case MUS_MP3:
   623 				smpeg.SMPEG_delete(music->data.mp3);
   624 				Mix_QuitMP3();
   625 				break;
   626 #endif
   627 #ifdef MP3_MAD_MUSIC
   628 			case MUS_MP3_MAD:
   629 				mad_closeFile(music->data.mp3_mad);
   630 				break;
   631 #endif
   632 			default:
   633 				/* Unknown music type?? */
   634 				break;
   635 		}
   636 		free(music);
   637 	}
   638 }
   639 
   640 /* Find out the music format of a mixer music, or the currently playing
   641    music, if 'music' is NULL.
   642 */
   643 Mix_MusicType Mix_GetMusicType(const Mix_Music *music)
   644 {
   645 	Mix_MusicType type = MUS_NONE;
   646 
   647 	if ( music ) {
   648 		type = music->type;
   649 	} else {
   650 		SDL_LockAudio();
   651 		if ( music_playing ) {
   652 			type = music_playing->type;
   653 		}
   654 		SDL_UnlockAudio();
   655 	}
   656 	return(type);
   657 }
   658 
   659 /* Play a music chunk.  Returns 0, or -1 if there was an error.
   660  */
   661 static int music_internal_play(Mix_Music *music, double position)
   662 {
   663 	int retval = 0;
   664 
   665 	/* Note the music we're playing */
   666 	if ( music_playing ) {
   667 		music_internal_halt();
   668 	}
   669 	music_playing = music;
   670 
   671 	/* Set the initial volume */
   672 	if ( music->type != MUS_MOD ) {
   673 		music_internal_initialize_volume();
   674 	}
   675 
   676 	/* Set up for playback */
   677 	switch (music->type) {
   678 #ifdef CMD_MUSIC
   679 	    case MUS_CMD:
   680 		MusicCMD_Start(music->data.cmd);
   681 		break;
   682 #endif
   683 #ifdef WAV_MUSIC
   684 	    case MUS_WAV:
   685 		WAVStream_Start(music->data.wave);
   686 		break;
   687 #endif
   688 #ifdef MOD_MUSIC
   689 	    case MUS_MOD:
   690 		MOD_play(music->data.module);
   691 		/* Player_SetVolume() does nothing before Player_Start() */
   692 		music_internal_initialize_volume();
   693 		break;
   694 #endif
   695 #ifdef MID_MUSIC
   696 	    case MUS_MID:
   697 #ifdef USE_NATIVE_MIDI
   698 		if ( native_midi_ok ) {
   699 			native_midi_start(music->data.nativemidi);
   700 		} MIDI_ELSE
   701 #endif
   702 #ifdef USE_TIMIDITY_MIDI
   703 		if ( timidity_ok ) {
   704 			Timidity_Start(music->data.midi);
   705 		}
   706 #endif
   707 		break;
   708 #endif
   709 #ifdef OGG_MUSIC
   710 	    case MUS_OGG:
   711 		OGG_play(music->data.ogg);
   712 		break;
   713 #endif
   714 #ifdef FLAC_MUSIC
   715 	    case MUS_FLAC:
   716 		FLAC_play(music->data.flac);
   717 		break;
   718 #endif
   719 #ifdef MP3_MUSIC
   720 	    case MUS_MP3:
   721 		smpeg.SMPEG_enableaudio(music->data.mp3,1);
   722 		smpeg.SMPEG_enablevideo(music->data.mp3,0);
   723 		smpeg.SMPEG_play(music_playing->data.mp3);
   724 		break;
   725 #endif
   726 #ifdef MP3_MAD_MUSIC
   727 	    case MUS_MP3_MAD:
   728 		mad_start(music->data.mp3_mad);
   729 		break;
   730 #endif
   731 	    default:
   732 		Mix_SetError("Can't play unknown music type");
   733 		retval = -1;
   734 		break;
   735 	}
   736 
   737 	/* Set the playback position, note any errors if an offset is used */
   738 	if ( retval == 0 ) {
   739 		if ( position > 0.0 ) {
   740 			if ( music_internal_position(position) < 0 ) {
   741 				Mix_SetError("Position not implemented for music type");
   742 				retval = -1;
   743 			}
   744 		} else {
   745 			music_internal_position(0.0);
   746 		}
   747 	}
   748 
   749 	/* If the setup failed, we're not playing any music anymore */
   750 	if ( retval < 0 ) {
   751 		music_playing = NULL;
   752 	}
   753 	return(retval);
   754 }
   755 int Mix_FadeInMusicPos(Mix_Music *music, int loops, int ms, double position)
   756 {
   757 	int retval;
   758 
   759 	/* Don't play null pointers :-) */
   760 	if ( music == NULL ) {
   761 		Mix_SetError("music parameter was NULL");
   762 		return(-1);
   763 	}
   764 
   765 	/* Setup the data */
   766 	if ( ms ) {
   767 		music->fading = MIX_FADING_IN;
   768 	} else {
   769 		music->fading = MIX_NO_FADING;
   770 	}
   771 	music->fade_step = 0;
   772 	music->fade_steps = ms/ms_per_step;
   773 
   774 	/* Play the puppy */
   775 	SDL_LockAudio();
   776 	/* If the current music is fading out, wait for the fade to complete */
   777 	while ( music_playing && (music_playing->fading == MIX_FADING_OUT) ) {
   778 		SDL_UnlockAudio();
   779 		SDL_Delay(100);
   780 		SDL_LockAudio();
   781 	}
   782 	music_active = 1;
   783 	music_loops = loops;
   784 	retval = music_internal_play(music, position);
   785 	SDL_UnlockAudio();
   786 
   787 	return(retval);
   788 }
   789 int Mix_FadeInMusic(Mix_Music *music, int loops, int ms)
   790 {
   791 	return Mix_FadeInMusicPos(music, loops, ms, 0.0);
   792 }
   793 int Mix_PlayMusic(Mix_Music *music, int loops)
   794 {
   795 	return Mix_FadeInMusicPos(music, loops, 0, 0.0);
   796 }
   797 
   798 /* Set the playing music position */
   799 int music_internal_position(double position)
   800 {
   801 	int retval = 0;
   802 
   803 	switch (music_playing->type) {
   804 #ifdef MOD_MUSIC
   805 	    case MUS_MOD:
   806 		MOD_jump_to_time(music_playing->data.module, position);
   807 		break;
   808 #endif
   809 #ifdef OGG_MUSIC
   810 	    case MUS_OGG:
   811 		OGG_jump_to_time(music_playing->data.ogg, position);
   812 		break;
   813 #endif
   814 #ifdef FLAC_MUSIC
   815 	    case MUS_FLAC:
   816 		FLAC_jump_to_time(music_playing->data.flac, position);
   817 		break;
   818 #endif
   819 #ifdef MP3_MUSIC
   820 	    case MUS_MP3:
   821 		if ( position > 0.0 ) {
   822 			smpeg.SMPEG_skip(music_playing->data.mp3, (float)position);
   823 		} else {
   824 			smpeg.SMPEG_rewind(music_playing->data.mp3);
   825 			smpeg.SMPEG_play(music_playing->data.mp3);
   826 		}
   827 		break;
   828 #endif
   829 #ifdef MP3_MAD_MUSIC
   830 	    case MUS_MP3_MAD:
   831 		mad_seek(music_playing->data.mp3_mad, position);
   832 		break;
   833 #endif
   834 	    default:
   835 		/* TODO: Implement this for other music backends */
   836 		retval = -1;
   837 		break;
   838 	}
   839 	return(retval);
   840 }
   841 int Mix_SetMusicPosition(double position)
   842 {
   843 	int retval;
   844 
   845 	SDL_LockAudio();
   846 	if ( music_playing ) {
   847 		retval = music_internal_position(position);
   848 		if ( retval < 0 ) {
   849 			Mix_SetError("Position not implemented for music type");
   850 		}
   851 	} else {
   852 		Mix_SetError("Music isn't playing");
   853 		retval = -1;
   854 	}
   855 	SDL_UnlockAudio();
   856 
   857 	return(retval);
   858 }
   859 
   860 /* Set the music's initial volume */
   861 static void music_internal_initialize_volume(void)
   862 {
   863 	if ( music_playing->fading == MIX_FADING_IN ) {
   864 		music_internal_volume(0);
   865 	} else {
   866 		music_internal_volume(music_volume);
   867 	}
   868 }
   869 
   870 /* Set the music volume */
   871 static void music_internal_volume(int volume)
   872 {
   873 	switch (music_playing->type) {
   874 #ifdef CMD_MUSIC
   875 	    case MUS_CMD:
   876 		MusicCMD_SetVolume(volume);
   877 		break;
   878 #endif
   879 #ifdef WAV_MUSIC
   880 	    case MUS_WAV:
   881 		WAVStream_SetVolume(volume);
   882 		break;
   883 #endif
   884 #ifdef MOD_MUSIC
   885 	    case MUS_MOD:
   886 		MOD_setvolume(music_playing->data.module, volume);
   887 		break;
   888 #endif
   889 #ifdef MID_MUSIC
   890 	    case MUS_MID:
   891 #ifdef USE_NATIVE_MIDI
   892 		if ( native_midi_ok ) {
   893 			native_midi_setvolume(volume);
   894 		} MIDI_ELSE
   895 #endif
   896 #ifdef USE_TIMIDITY_MIDI
   897 		if ( timidity_ok ) {
   898 			Timidity_SetVolume(volume);
   899 		}
   900 #endif
   901 		break;
   902 #endif
   903 #ifdef OGG_MUSIC
   904 	    case MUS_OGG:
   905 		OGG_setvolume(music_playing->data.ogg, volume);
   906 		break;
   907 #endif
   908 #ifdef FLAC_MUSIC
   909 	    case MUS_FLAC:
   910 		FLAC_setvolume(music_playing->data.flac, volume);
   911 		break;
   912 #endif
   913 #ifdef MP3_MUSIC
   914 	    case MUS_MP3:
   915 		smpeg.SMPEG_setvolume(music_playing->data.mp3,(int)(((float)volume/(float)MIX_MAX_VOLUME)*100.0));
   916 		break;
   917 #endif
   918 #ifdef MP3_MAD_MUSIC
   919 	    case MUS_MP3_MAD:
   920 		mad_setVolume(music_playing->data.mp3_mad, volume);
   921 		break;
   922 #endif
   923 	    default:
   924 		/* Unknown music type?? */
   925 		break;
   926 	}
   927 }
   928 int Mix_VolumeMusic(int volume)
   929 {
   930 	int prev_volume;
   931 
   932 	prev_volume = music_volume;
   933 	if ( volume < 0 ) {
   934 		return prev_volume;
   935 	}
   936 	if ( volume > SDL_MIX_MAXVOLUME ) {
   937 		volume = SDL_MIX_MAXVOLUME;
   938 	}
   939 	music_volume = volume;
   940 	SDL_LockAudio();
   941 	if ( music_playing ) {
   942 		music_internal_volume(music_volume);
   943 	}
   944 	SDL_UnlockAudio();
   945 	return(prev_volume);
   946 }
   947 
   948 /* Halt playing of music */
   949 static void music_internal_halt(void)
   950 {
   951 	switch (music_playing->type) {
   952 #ifdef CMD_MUSIC
   953 	    case MUS_CMD:
   954 		MusicCMD_Stop(music_playing->data.cmd);
   955 		break;
   956 #endif
   957 #ifdef WAV_MUSIC
   958 	    case MUS_WAV:
   959 		WAVStream_Stop();
   960 		break;
   961 #endif
   962 #ifdef MOD_MUSIC
   963 	    case MUS_MOD:
   964 		MOD_stop(music_playing->data.module);
   965 		break;
   966 #endif
   967 #ifdef MID_MUSIC
   968 	    case MUS_MID:
   969 #ifdef USE_NATIVE_MIDI
   970 		if ( native_midi_ok ) {
   971 			native_midi_stop();
   972 		} MIDI_ELSE
   973 #endif
   974 #ifdef USE_TIMIDITY_MIDI
   975 		if ( timidity_ok ) {
   976 			Timidity_Stop();
   977 		}
   978 #endif
   979 		break;
   980 #endif
   981 #ifdef OGG_MUSIC
   982 	    case MUS_OGG:
   983 		OGG_stop(music_playing->data.ogg);
   984 		break;
   985 #endif
   986 #ifdef FLAC_MUSIC
   987 	    case MUS_FLAC:
   988 		FLAC_stop(music_playing->data.flac);
   989 		break;
   990 #endif
   991 #ifdef MP3_MUSIC
   992 	    case MUS_MP3:
   993 		smpeg.SMPEG_stop(music_playing->data.mp3);
   994 		break;
   995 #endif
   996 #ifdef MP3_MAD_MUSIC
   997 	    case MUS_MP3_MAD:
   998 		mad_stop(music_playing->data.mp3_mad);
   999 		break;
  1000 #endif
  1001 	    default:
  1002 		/* Unknown music type?? */
  1003 		return;
  1004 	}
  1005 	music_playing->fading = MIX_NO_FADING;
  1006 	music_playing = NULL;
  1007 }
  1008 int Mix_HaltMusic(void)
  1009 {
  1010 	SDL_LockAudio();
  1011 	if ( music_playing ) {
  1012 		music_internal_halt();
  1013 	}
  1014 	SDL_UnlockAudio();
  1015 
  1016 	return(0);
  1017 }
  1018 
  1019 /* Progressively stop the music */
  1020 int Mix_FadeOutMusic(int ms)
  1021 {
  1022 	int retval = 0;
  1023 
  1024 	if (ms <= 0) {  /* just halt immediately. */
  1025 		Mix_HaltMusic();
  1026 		return 1;
  1027 	}
  1028 
  1029 	SDL_LockAudio();
  1030 	if ( music_playing) {
  1031                 int fade_steps = (ms + ms_per_step - 1)/ms_per_step;
  1032                 if ( music_playing->fading == MIX_NO_FADING ) {
  1033 	        	music_playing->fade_step = 0;
  1034                 } else {
  1035                         int step;
  1036                         int old_fade_steps = music_playing->fade_steps;
  1037                         if ( music_playing->fading == MIX_FADING_OUT ) {
  1038                                 step = music_playing->fade_step;
  1039                         } else {
  1040                                 step = old_fade_steps
  1041                                         - music_playing->fade_step + 1;
  1042                         }
  1043                         music_playing->fade_step = (step * fade_steps)
  1044                                 / old_fade_steps;
  1045                 }
  1046 		music_playing->fading = MIX_FADING_OUT;
  1047 		music_playing->fade_steps = fade_steps;
  1048 		retval = 1;
  1049 	}
  1050 	SDL_UnlockAudio();
  1051 
  1052 	return(retval);
  1053 }
  1054 
  1055 Mix_Fading Mix_FadingMusic(void)
  1056 {
  1057 	Mix_Fading fading = MIX_NO_FADING;
  1058 
  1059 	SDL_LockAudio();
  1060 	if ( music_playing ) {
  1061 		fading = music_playing->fading;
  1062 	}
  1063 	SDL_UnlockAudio();
  1064 
  1065 	return(fading);
  1066 }
  1067 
  1068 /* Pause/Resume the music stream */
  1069 void Mix_PauseMusic(void)
  1070 {
  1071 	music_active = 0;
  1072 }
  1073 
  1074 void Mix_ResumeMusic(void)
  1075 {
  1076 	music_active = 1;
  1077 }
  1078 
  1079 void Mix_RewindMusic(void)
  1080 {
  1081 	Mix_SetMusicPosition(0.0);
  1082 }
  1083 
  1084 int Mix_PausedMusic(void)
  1085 {
  1086 	return (music_active == 0);
  1087 }
  1088 
  1089 /* Check the status of the music */
  1090 static int music_internal_playing()
  1091 {
  1092 	int playing = 1;
  1093 	switch (music_playing->type) {
  1094 #ifdef CMD_MUSIC
  1095 	    case MUS_CMD:
  1096 		if (!MusicCMD_Active(music_playing->data.cmd)) {
  1097 			playing = 0;
  1098 		}
  1099 		break;
  1100 #endif
  1101 #ifdef WAV_MUSIC
  1102 	    case MUS_WAV:
  1103 		if ( ! WAVStream_Active() ) {
  1104 			playing = 0;
  1105 		}
  1106 		break;
  1107 #endif
  1108 #ifdef MOD_MUSIC
  1109 	    case MUS_MOD:
  1110 		if ( ! MOD_playing(music_playing->data.module) ) {
  1111 			playing = 0;
  1112 		}
  1113 		break;
  1114 #endif
  1115 #ifdef MID_MUSIC
  1116 	    case MUS_MID:
  1117 #ifdef USE_NATIVE_MIDI
  1118 		if ( native_midi_ok ) {
  1119 			if ( ! native_midi_active() )
  1120 				playing = 0;
  1121 		} MIDI_ELSE
  1122 #endif
  1123 #ifdef USE_TIMIDITY_MIDI
  1124 		if ( timidity_ok ) {
  1125 			if ( ! Timidity_Active() )
  1126 				playing = 0;
  1127 		}
  1128 #endif
  1129 		break;
  1130 #endif
  1131 #ifdef OGG_MUSIC
  1132 	    case MUS_OGG:
  1133 		if ( ! OGG_playing(music_playing->data.ogg) ) {
  1134 			playing = 0;
  1135 		}
  1136 		break;
  1137 #endif
  1138 #ifdef FLAC_MUSIC
  1139 	    case MUS_FLAC:
  1140 		if ( ! FLAC_playing(music_playing->data.flac) ) {
  1141 			playing = 0;
  1142 		}
  1143 		break;
  1144 #endif
  1145 #ifdef MP3_MUSIC
  1146 	    case MUS_MP3:
  1147 		if ( smpeg.SMPEG_status(music_playing->data.mp3) != SMPEG_PLAYING )
  1148 			playing = 0;
  1149 		break;
  1150 #endif
  1151 #ifdef MP3_MAD_MUSIC
  1152 	    case MUS_MP3_MAD:
  1153 		if (!mad_isPlaying(music_playing->data.mp3_mad)) {
  1154 			playing = 0;
  1155 		}
  1156 		break;
  1157 #endif
  1158 	    default:
  1159 		playing = 0;
  1160 		break;
  1161 	}
  1162 	return(playing);
  1163 }
  1164 int Mix_PlayingMusic(void)
  1165 {
  1166 	int playing = 0;
  1167 
  1168 	SDL_LockAudio();
  1169 	if ( music_playing ) {
  1170 		playing = music_internal_playing();
  1171 	}
  1172 	SDL_UnlockAudio();
  1173 
  1174 	return(playing);
  1175 }
  1176 
  1177 /* Set the external music playback command */
  1178 int Mix_SetMusicCMD(const char *command)
  1179 {
  1180 	Mix_HaltMusic();
  1181 	if ( music_cmd ) {
  1182 		free(music_cmd);
  1183 		music_cmd = NULL;
  1184 	}
  1185 	if ( command ) {
  1186 		music_cmd = (char *)malloc(strlen(command)+1);
  1187 		if ( music_cmd == NULL ) {
  1188 			return(-1);
  1189 		}
  1190 		strcpy(music_cmd, command);
  1191 	}
  1192 	return(0);
  1193 }
  1194 
  1195 int Mix_SetSynchroValue(int i)
  1196 {
  1197 	/* Not supported by any players at this time */
  1198 	return(-1);
  1199 }
  1200 
  1201 int Mix_GetSynchroValue(void)
  1202 {
  1203 	/* Not supported by any players at this time */
  1204 	return(-1);
  1205 }
  1206 
  1207 
  1208 /* Uninitialize the music players */
  1209 void close_music(void)
  1210 {
  1211 	Mix_HaltMusic();
  1212 #ifdef CMD_MUSIC
  1213 	Mix_SetMusicCMD(NULL);
  1214 #endif
  1215 #ifdef MOD_MUSIC
  1216 	MOD_exit();
  1217 #endif
  1218 #ifdef MID_MUSIC
  1219 # ifdef USE_TIMIDITY_MIDI
  1220 	Timidity_Close();
  1221 # endif
  1222 #endif
  1223 
  1224 	/* rcg06042009 report available decoders at runtime. */
  1225 	free(music_decoders);
  1226 	music_decoders = NULL;
  1227 	num_decoders = 0;
  1228 }
  1229 
  1230 Mix_Music *Mix_LoadMUS_RW(SDL_RWops *rw)
  1231 {
  1232 	Uint8 magic[5];	  /*Apparently there is no way to check if the file is really a MOD,*/
  1233 	/*		    or there are too many formats supported by MikMod or MikMod does */
  1234 	/*		    this check by itself. If someone implements other formats (e.g. MP3) */
  1235 	/*		    the check can be uncommented */
  1236 	Uint8 moremagic[9];
  1237 	Mix_Music *music;
  1238 	int start;
  1239 
  1240 	if (!rw) {
  1241 		Mix_SetError("RWops pointer is NULL");
  1242 		return NULL;
  1243 	}
  1244 
  1245 	/* Figure out what kind of file this is */
  1246 	start = SDL_RWtell(rw);
  1247 	if ( SDL_RWread(rw,magic,1,4) != 4 ||
  1248 	     SDL_RWread(rw,moremagic,1,8) != 8 ) {
  1249 		Mix_SetError("Couldn't read from RWops");
  1250 		return NULL;
  1251 	}
  1252 	SDL_RWseek(rw, start, SEEK_SET);
  1253 	magic[4]='\0';
  1254 	moremagic[8] = '\0';
  1255 
  1256 	/* Allocate memory for the music structure */
  1257 	music=(Mix_Music *)malloc(sizeof(Mix_Music));
  1258 	if (music==NULL ) {
  1259 		Mix_SetError("Out of memory");
  1260 		return(NULL);
  1261 	}
  1262 	music->error = 0;
  1263 
  1264 #ifdef WAV_MUSIC
  1265 	/* WAVE files have the magic four bytes "RIFF"
  1266 	   AIFF files have the magic 12 bytes "FORM" XXXX "AIFF"
  1267 	 */
  1268 	if ( ((strcmp((char *)magic, "RIFF") == 0) && (strcmp((char *)(moremagic+4), "WAVE") == 0)) ||
  1269 	     (strcmp((char *)magic, "FORM") == 0) ) {
  1270 		music->type = MUS_WAV;
  1271 		music->data.wave = WAVStream_LoadSong_RW(rw, (char *)magic);
  1272 		if ( music->data.wave == NULL ) {
  1273 			music->error = 1;
  1274 		}
  1275 
  1276 	} else
  1277 #endif
  1278 #ifdef OGG_MUSIC
  1279 	/* Ogg Vorbis files have the magic four bytes "OggS" */
  1280 	if ( strcmp((char *)magic, "OggS") == 0 ) {
  1281 		music->type = MUS_OGG;
  1282 		music->data.ogg = OGG_new_RW(rw);
  1283 		if ( music->data.ogg == NULL ) {
  1284 			music->error = 1;
  1285 		}
  1286 	} else
  1287 #endif
  1288 #ifdef FLAC_MUSIC
  1289 	/* FLAC files have the magic four bytes "fLaC" */
  1290 	if ( strcmp((char *)magic, "fLaC") == 0 ) {
  1291 		music->type = MUS_FLAC;
  1292 		music->data.flac = FLAC_new_RW(rw);
  1293 		if ( music->data.flac == NULL ) {
  1294 			music->error = 1;
  1295 		}
  1296 	} else
  1297 #endif
  1298 #ifdef MP3_MUSIC
  1299 	if ( ( magic[0] == 0xFF && (magic[1] & 0xF0) == 0xF0) || ( strncmp((char *)magic, "ID3", 3) == 0 ) ) {
  1300 		if ( Mix_InitMP3() == 0 ) {
  1301 			SMPEG_Info info;
  1302 			music->type = MUS_MP3;
  1303 			music->data.mp3 = smpeg.SMPEG_new_rwops(rw, &info, 0);
  1304 			if ( !info.has_audio ) {
  1305 				Mix_SetError("MPEG file does not have any audio stream.");
  1306 				music->error = 1;
  1307 			} else {
  1308 				smpeg.SMPEG_actualSpec(music->data.mp3, &used_mixer);
  1309 			}
  1310 		} else {
  1311 			music->error = 1;
  1312 		}
  1313 	} else
  1314 #endif
  1315 #ifdef MP3_MAD_MUSIC
  1316 	if ( ( magic[0] == 0xFF && (magic[1] & 0xF0) == 0xF0) || ( strncmp((char *)magic, "ID3", 3) == 0 ) ) {
  1317 		music->type = MUS_MP3_MAD;
  1318 		music->data.mp3_mad = mad_openFileRW(rw, &used_mixer);
  1319 		if (music->data.mp3_mad == 0) {
  1320 			Mix_SetError("Could not initialize MPEG stream.");
  1321 			music->error = 1;
  1322 		}
  1323 	} else
  1324 #endif
  1325 #ifdef MID_MUSIC
  1326 	/* MIDI files have the magic four bytes "MThd" */
  1327 	if ( strcmp((char *)magic, "MThd") == 0 ) {
  1328 		music->type = MUS_MID;
  1329 #ifdef USE_NATIVE_MIDI
  1330 		if ( native_midi_ok ) {
  1331 			music->data.nativemidi = native_midi_loadsong_RW(rw);
  1332 	  		if ( music->data.nativemidi == NULL ) {
  1333 		  		Mix_SetError("%s", native_midi_error());
  1334 			  	music->error = 1;
  1335 			}
  1336 		} MIDI_ELSE
  1337 #endif
  1338 #ifdef USE_TIMIDITY_MIDI
  1339 		if ( timidity_ok ) {
  1340 			music->data.midi = Timidity_LoadSong_RW(rw);
  1341 			if ( music->data.midi == NULL ) {
  1342 				Mix_SetError("%s", Timidity_Error());
  1343 				music->error = 1;
  1344 			}
  1345 		} else {
  1346 			Mix_SetError("%s", Timidity_Error());
  1347 			music->error = 1;
  1348 		}
  1349 #endif
  1350 	} else
  1351 #endif
  1352 #ifdef MOD_MUSIC
  1353 	if (1) {
  1354 		music->type=MUS_MOD;
  1355 		music->data.module = MOD_new_RW(rw);
  1356 		if ( music->data.module == NULL ) {
  1357 			music->error = 1;
  1358 		}
  1359 	} else
  1360 #endif
  1361 	{
  1362 		Mix_SetError("Unrecognized music format");
  1363 		music->error=1;
  1364 	}
  1365 	if (music->error) {
  1366 		free(music);
  1367 		music=NULL;
  1368 	}
  1369 	return(music);
  1370 }