music.c
author Stephane Peter <megastep@lokigames.com>
Mon, 01 Nov 1999 00:40:43 +0000
changeset 13 1e489d8b97d8
parent 12 f38e14b566c8
child 16 ada544ec16c6
permissions -rw-r--r--
- Massive bugfixes for pausing/resuming music (handled in a generic way)
- New functions to query the paused state of either music or channels
- Added interactive mode (-i) to playmus, to aid debugging
     1 /*
     2     MIXERLIB:  An audio mixer library based on the SDL library
     3     Copyright (C) 1997-1999  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     5635-34 Springhouse Dr.
    21     Pleasanton, CA 94588 (USA)
    22     slouken@devolution.com
    23 */
    24 
    25 #include <stdlib.h>
    26 #include <string.h>
    27 #include <SDL/SDL_endian.h>
    28 #include <SDL/SDL_audio.h>
    29 
    30 #include "mixer.h"
    31 
    32 /* The music command hack is UNIX specific */
    33 #ifndef unix
    34 #undef CMD_MUSIC
    35 #endif
    36 
    37 #ifdef CMD_MUSIC
    38 #include "music_cmd.h"
    39 #endif
    40 #ifdef WAV_MUSIC
    41 #include "wavestream.h"
    42 #endif
    43 #ifdef MOD_MUSIC
    44 #include "mikmod.h"
    45 #endif
    46 #ifdef MID_MUSIC
    47 #include "timidity.h"
    48 #endif
    49 #ifdef MP3_MUSIC
    50 #include <smpeg/smpeg.h>
    51 
    52 static SDL_AudioSpec used_mixer;
    53 #endif
    54 
    55 int music_active = 1;
    56 static int music_stopped = 0;
    57 static int music_paused = 0;
    58 static int music_loops = 0;
    59 static char *music_cmd = NULL;
    60 static int samplesize;
    61 static Mix_Music *music_playing = 0;
    62 static int music_volume;
    63 static int music_swap8;
    64 static int music_swap16;
    65 
    66 /* For fading/chaining musics */
    67 static Mix_Music *next_music = 0;
    68 static int next_period = 0, next_loops = 0;
    69 
    70 struct _Mix_Music {
    71 	enum {
    72 		MUS_CMD,
    73 		MUS_WAV,
    74 		MUS_MOD,
    75 		MUS_MID,
    76 		MUS_MP3
    77 	} type;
    78 	union {
    79 #ifdef CMD_MUSIC
    80 		MusicCMD *cmd;
    81 #endif
    82 #ifdef WAV_MUSIC
    83 		WAVStream *wave;
    84 #endif
    85 #ifdef MOD_MUSIC
    86 		UNIMOD *module;
    87 #endif
    88 #ifdef MID_MUSIC
    89 		MidiSong *midi;
    90 #endif
    91 #ifdef MP3_MUSIC
    92 		SMPEG *mp3;
    93 #endif
    94 	} data;
    95 	Mix_Fading fading;
    96 	int fade_volume;
    97 	int fade_length;
    98 	Uint32 ticks_fade;
    99 	int error;
   100 };
   101 static int timidity_ok;
   102 
   103 /* Local low-level functions prototypes */
   104 static void lowlevel_halt(void);
   105 static int  lowlevel_play(Mix_Music *music);
   106 
   107 /* Mixing function */
   108 void music_mixer(void *udata, Uint8 *stream, int len)
   109 {
   110 	int i;
   111 
   112 	if ( music_playing ) {
   113 		if ( music_stopped ) {
   114 			/* To avoid concurrency problems and the use of mutexes,
   115 			   the music is always stopped from the sound thread */
   116 			lowlevel_halt(); /* This function sets music_playing to NULL */
   117 			return;
   118 		}	
   119 		if ( music_paused ) {
   120 			return;
   121 		}
   122 		/* Handle fading */
   123 		if ( !music_stopped && music_playing->fading != MIX_NO_FADING ) {
   124 			Uint32 ticks = SDL_GetTicks() - music_playing->ticks_fade;
   125 			if( ticks > music_playing->fade_length ) {
   126 				if ( music_playing->fading == MIX_FADING_OUT ) {
   127 					music_volume = music_playing->fade_volume;
   128 					music_playing->fading = MIX_NO_FADING;
   129 					if (next_music) {
   130 						Mix_FadeInMusic(next_music,next_loops,next_period);
   131 						next_music = 0;
   132 						next_period = next_loops = 0;
   133 					} else {
   134 						lowlevel_halt();
   135 					}
   136 					return;
   137 				}
   138 				music_playing->fading = MIX_NO_FADING;
   139 			} else {
   140 				if ( music_playing->fading == MIX_FADING_OUT ) {
   141 					Mix_VolumeMusic((music_playing->fade_volume * (music_playing->fade_length-ticks)) 
   142 									/ music_playing->fade_length);
   143 				} else { /* Fading in */
   144 					Mix_VolumeMusic((music_playing->fade_volume * ticks) 
   145 									/ music_playing->fade_length);
   146 				}
   147 			}
   148 		}
   149 		/* Restart music if it has to loop */
   150 		if ( music_loops && !Mix_PlayingMusic() ) {
   151 			if ( -- music_loops ) {
   152 				Mix_RewindMusic();
   153 				if ( lowlevel_play(music_playing) < 0 ) {
   154 					fprintf(stderr,"Warning: Music restart failed.\n");
   155 					music_stopped = 1; /* Something went wrong */
   156 					music_playing->fading = MIX_NO_FADING;
   157 				}
   158 			}
   159 		}
   160 		switch (music_playing->type) {
   161 #ifdef CMD_MUSIC
   162 			case MUS_CMD:
   163 				/* The playing is done externally */
   164 				break;
   165 #endif
   166 #ifdef WAV_MUSIC
   167 			case MUS_WAV:
   168 				WAVStream_PlaySome(stream, len);
   169 				break;
   170 #endif
   171 #ifdef MOD_MUSIC
   172 			case MUS_MOD:
   173 				VC_WriteBytes((SBYTE *)stream, len);
   174 				if ( music_swap8 ) {
   175 					Uint8 *dst;
   176 
   177 					dst = stream;
   178 					for ( i=len; i; --i ) {
   179 						*dst++ ^= 0x80;
   180 					}
   181 				} else
   182 				if ( music_swap16 ) {
   183 					Uint8 *dst, tmp;
   184 
   185 					dst = stream;
   186 					for ( i=(len/2); i; --i ) {
   187 						tmp = dst[0];
   188 						dst[0] = dst[1];
   189 						dst[1] = tmp;
   190 						dst += 2;
   191 					}
   192 				}
   193 				break;
   194 #endif
   195 #ifdef MID_MUSIC
   196 			case MUS_MID:
   197 				Timidity_PlaySome(stream, len/samplesize);
   198 				break;
   199 #endif
   200 #ifdef MP3_MUSIC
   201 		    case MUS_MP3:
   202 			    SMPEG_playAudio(music_playing->data.mp3, stream, len);
   203 				break;
   204 #endif
   205 			default:
   206 				/* Unknown music type?? */
   207 				break;
   208 		}
   209 	}
   210 }
   211 
   212 /* Initialize the music players with a certain desired audio format */
   213 int open_music(SDL_AudioSpec *mixer)
   214 {
   215 	int music_error;
   216 
   217 	music_error = 0;
   218 #ifdef WAV_MUSIC
   219 	if ( WAVStream_Init(mixer) < 0 ) {
   220 		++music_error;
   221 	}
   222 #endif
   223 #ifdef MOD_MUSIC
   224 	/* Set the MikMod music format */
   225 	music_swap8 = 0;
   226 	music_swap16 = 0;
   227 	switch (mixer->format) {
   228 
   229 		case AUDIO_U8:
   230 		case AUDIO_S8: {
   231 			if ( mixer->format == AUDIO_S8 ) {
   232 				music_swap8 = 1;
   233 			}
   234 			md_mode = 0;
   235 		}
   236 		break;
   237 
   238 		case AUDIO_S16LSB:
   239 		case AUDIO_S16MSB: {
   240 			/* See if we need to correct MikMod mixing */
   241 #if SDL_BYTEORDER == SDL_LIL_ENDIAN
   242 			if ( mixer->format == AUDIO_S16MSB ) {
   243 #else
   244 			if ( mixer->format == AUDIO_S16LSB ) {
   245 #endif
   246 				music_swap16 = 1;
   247 			}
   248 			md_mode = DMODE_16BITS;
   249 		}
   250 		break;
   251 
   252 		default: {
   253 			SDL_SetError("Unknown hardware audio format");
   254 			++music_error;
   255 		}
   256 	}
   257 	if ( mixer->channels > 1 ) {
   258 		if ( mixer->channels > 2 ) {
   259 			SDL_SetError("Hardware uses more channels than mixer");
   260 			++music_error;
   261 		}
   262 		md_mode |= DMODE_STEREO;
   263 	}
   264 	samplesize     = mixer->size/mixer->samples;
   265 	md_mixfreq     = mixer->freq;
   266 	md_device      = 0;
   267 	md_volume      = 96;
   268 	md_musicvolume = 128;
   269 	md_sndfxvolume = 128;
   270 	md_pansep      = 128;
   271 	md_reverb      = 0;
   272 	MikMod_RegisterAllLoaders();
   273 	MikMod_RegisterAllDrivers();
   274 	if ( MikMod_Init() ) {
   275 		SDL_SetError("%s", _mm_errmsg[_mm_errno]);
   276 		++music_error;
   277 	}
   278 #endif
   279 #ifdef MID_MUSIC
   280 	if ( Timidity_Init(mixer->freq,
   281 			mixer->format, mixer->channels, mixer->samples) == 0 ) {
   282 		timidity_ok = 1;
   283 	} else {
   284 		timidity_ok = 0;
   285 	}
   286 #endif
   287 #ifdef MP3_MUSIC
   288 	/* Keep a copy of the mixer */
   289 	used_mixer = *mixer;
   290 #endif
   291 	music_playing = 0;
   292 	music_stopped = 0;
   293 
   294 	if ( music_error ) {
   295 		return(-1);
   296 	}
   297 	Mix_VolumeMusic(SDL_MIX_MAXVOLUME);
   298 
   299 	return(0);
   300 }
   301 
   302 /* Load a music file */
   303 Mix_Music *Mix_LoadMUS(const char *file)
   304 {
   305 	FILE *fp;
   306 	unsigned char magic[5];
   307 	Mix_Music *music;
   308 
   309 	/* Figure out what kind of file this is */
   310 	fp = fopen(file, "rb");
   311 	if ( (fp == NULL) || !fread(magic, 4, 1, fp) ) {
   312 		if ( fp != NULL ) {
   313 			fclose(fp);
   314 		}
   315 		SDL_SetError("Couldn't read from '%s'", file);
   316 		return(NULL);
   317 	}
   318 	magic[4] = '\0';
   319 	fclose(fp);
   320 
   321 	/* Allocate memory for the music structure */
   322 	music = (Mix_Music *)malloc(sizeof(Mix_Music));
   323 	if ( music == NULL ) {
   324 		SDL_SetError("Out of memory");
   325 		return(NULL);
   326 	}
   327 	music->error = 0;
   328 
   329 #ifdef CMD_MUSIC
   330 	if ( music_cmd ) {
   331 		music->type = MUS_CMD;
   332 		music->data.cmd = MusicCMD_LoadSong(music_cmd, file);
   333 		if ( music->data.cmd == NULL ) {
   334 			music->error = 1;
   335 		}
   336 	} else
   337 #endif
   338 #ifdef WAV_MUSIC
   339 	/* WAVE files have the magic four bytes "RIFF"
   340 	   AIFF files have the magic 12 bytes "FORM" XXXX "AIFF"
   341 	 */
   342 	if ( (strcmp(magic, "RIFF") == 0) || (strcmp(magic, "FORM") == 0) ) {
   343 		music->type = MUS_WAV;
   344 		music->data.wave = WAVStream_LoadSong(file, magic);
   345 		if ( music->data.wave == NULL ) {
   346 			music->error = 1;
   347 		}
   348 	} else
   349 #endif
   350 #ifdef MID_MUSIC
   351 	/* MIDI files have the magic four bytes "MThd" */
   352 	if ( strcmp(magic, "MThd") == 0 ) {
   353 		music->type = MUS_MID;
   354 		if ( timidity_ok ) {
   355 			music->data.midi = Timidity_LoadSong((char *)file);
   356 			if ( music->data.midi == NULL ) {
   357 				SDL_SetError("%s", Timidity_Error());
   358 				music->error = 1;
   359 			}
   360 		}
   361 		else {
   362 			SDL_SetError("%s", Timidity_Error());
   363 			music->error = 1;
   364 		}
   365 	} else
   366 #endif
   367 #ifdef MP3_MUSIC
   368 	if ( magic[0]==0xFF && (magic[1]&0xF0)==0xF0) {
   369 		SMPEG_Info info;
   370 		music->type = MUS_MP3;
   371 		music->data.mp3 = SMPEG_new(file, &info, 0);
   372 		if(!info.has_audio){
   373 			SDL_SetError("MPEG file does not have any audio stream.");
   374 			music->error = 1;
   375 		}else{
   376 			SMPEG_actualSpec(music->data.mp3, &used_mixer);
   377 		}
   378 	} else
   379 #endif
   380 #ifdef MOD_MUSIC
   381 	if ( 1 ) {
   382 		music->type = MUS_MOD;
   383 		music->data.module = MikMod_LoadSong((char *)file, 64);
   384 		if ( music->data.module == NULL ) {
   385 			SDL_SetError("%s", _mm_errmsg[_mm_errno]);
   386 			music->error = 1;
   387 		}
   388 	} else
   389 #endif
   390 	{
   391 		SDL_SetError("Unrecognized music format");
   392 		music->error = 1;
   393 	}
   394 	if ( music->error ) {
   395 		free(music);
   396 		music = NULL;
   397 	}
   398 	return(music);
   399 }
   400 
   401 /* Free a music chunk previously loaded */
   402 void Mix_FreeMusic(Mix_Music *music)
   403 {
   404 	if ( music ) {
   405 		/* Caution: If music is playing, mixer will crash */
   406 		if ( music == music_playing && !music_stopped ) {
   407 			if ( music->fading == MIX_FADING_OUT ) {
   408 				/* Wait for the fade out to finish */
   409 				while(music_playing && !music_stopped && music_playing->fading == MIX_FADING_OUT)
   410 					SDL_Delay(100);
   411 			} else {
   412 				Mix_HaltMusic(); /* Stop it immediately */
   413 			}
   414 		}
   415 		switch (music->type) {
   416 #ifdef CMD_MUSIC
   417 			case MUS_CMD:
   418 				MusicCMD_FreeSong(music->data.cmd);
   419 				break;
   420 #endif
   421 #ifdef WAV_MUSIC
   422 			case MUS_WAV:
   423 				WAVStream_FreeSong(music->data.wave);
   424 				break;
   425 #endif
   426 #ifdef MOD_MUSIC
   427 			case MUS_MOD:
   428 				MikMod_FreeSong(music->data.module);
   429 				break;
   430 #endif
   431 #ifdef MID_MUSIC
   432 			case MUS_MID:
   433 				Timidity_FreeSong(music->data.midi);
   434 				break;
   435 #endif
   436 #ifdef MP3_MUSIC
   437 		    case MUS_MP3:
   438 				SMPEG_delete(music->data.mp3);
   439 				break;
   440 #endif
   441 			default:
   442 				/* Unknown music type?? */
   443 				break;
   444 		}
   445 		free(music);
   446 	}
   447 }
   448 
   449 static int lowlevel_play(Mix_Music *music)
   450 {
   451 	if(!music)
   452 		return(-1);
   453 
   454 	switch (music->type) {
   455 #ifdef CMD_MUSIC
   456 		case MUS_CMD:
   457 			MusicCMD_SetVolume(music_volume);
   458 			MusicCMD_Start(music->data.cmd);
   459 			break;
   460 #endif
   461 #ifdef WAV_MUSIC
   462 		case MUS_WAV:
   463 			WAVStream_SetVolume(music_volume);
   464 			WAVStream_Start(music->data.wave);
   465 			break;
   466 #endif
   467 #ifdef MOD_MUSIC
   468 		case MUS_MOD:
   469 			Player_SetVolume(music_volume);
   470 			Player_Start(music->data.module);
   471 			Player_SetPosition(0);
   472 			break;
   473 #endif
   474 #ifdef MID_MUSIC
   475 		case MUS_MID:
   476 			Timidity_SetVolume(music_volume);
   477 			Timidity_Start(music->data.midi);
   478 			break;
   479 #endif
   480 #ifdef MP3_MUSIC
   481 	    case MUS_MP3:
   482 			SMPEG_enableaudio(music->data.mp3,1);
   483 			SMPEG_enablevideo(music->data.mp3,0);
   484 			SMPEG_setvolume(music->data.mp3,((float)music_volume/(float)MIX_MAX_VOLUME)*100.0);
   485 			SMPEG_play(music->data.mp3);
   486 			break;
   487 #endif
   488 		default:
   489 			/* Unknown music type?? */
   490 			return(-1);
   491 	}
   492 	return(0);
   493 }
   494 
   495 /* Play a music chunk.  Returns 0, or -1 if there was an error.
   496 */
   497 int Mix_PlayMusic(Mix_Music *music, int loops)
   498 {
   499 	/* Don't play null pointers :-) */
   500 	if ( music == NULL ) {
   501 		return(-1);
   502 	}
   503 	/* If the current music is fading out, wait for the fade to complete */
   504 	while ( music_playing && !music_stopped && music_playing->fading==MIX_FADING_OUT ) {
   505 		SDL_Delay(100);
   506 	}
   507 
   508 	if(lowlevel_play(music)<0)
   509 		return(-1);
   510 
   511 	music_active = 1;
   512 	music_stopped = 0;
   513 	music_loops = loops;
   514 	music_playing = music;
   515 	music_playing->fading = MIX_NO_FADING;
   516 	return(0);
   517 }
   518 
   519 /* Fade in a music over "ms" milliseconds */
   520 int Mix_FadeInMusic(Mix_Music *music, int loops, int ms)
   521 {
   522 	if ( music && music_volume > 0 ) { /* No need to fade if we can't hear it */
   523 		music->fade_volume = music_volume;
   524 		music_volume = 0;
   525 		if(Mix_PlayMusic(music,loops)<0)
   526 			return(-1);
   527 		music_playing->fading = MIX_FADING_IN;
   528 		music_playing->fade_length = ms;
   529 		music_playing->ticks_fade = SDL_GetTicks();
   530 	}
   531 	return(0);
   532 }
   533 
   534 /* Fades out the currently playing music, and progressively fades in a new music,
   535    all in the background. The 'ms' period is half for fading out the music and
   536    fading in the new one */
   537 int Mix_FadeOutInMusic(Mix_Music *music, int loops, int ms)
   538 {
   539 	if( music_stopped || !music_playing ) {
   540 		return Mix_FadeInMusic(music,loops,ms/2);
   541 	} else {
   542 		/* Set up the data for chaining the next music */
   543 		next_music = music;
   544 		next_period = ms/2;
   545 		next_loops = loops;
   546 		/* Fade out the current music */
   547 		Mix_FadeOutMusic(ms/2);
   548 	}
   549 }
   550 
   551 /* Set the music volume */
   552 int Mix_VolumeMusic(int volume)
   553 {
   554 	int prev_volume;
   555 
   556 	prev_volume = music_volume;
   557 	if ( volume < 0 ) {
   558 		volume = 0;
   559 	}
   560 	if ( volume > SDL_MIX_MAXVOLUME ) {
   561 		volume = SDL_MIX_MAXVOLUME;
   562 	}
   563 	music_volume = volume;
   564 	if ( music_playing && !music_stopped ) {
   565 		switch (music_playing->type) {
   566 #ifdef CMD_MUSIC
   567 		case MUS_CMD:
   568 			MusicCMD_SetVolume(music_volume);
   569 			break;
   570 #endif
   571 #ifdef WAV_MUSIC
   572 		case MUS_WAV:
   573 			WAVStream_SetVolume(music_volume);
   574 			break;
   575 #endif
   576 #ifdef MOD_MUSIC
   577 		case MUS_MOD:
   578 			Player_SetVolume(music_volume);
   579 			break;
   580 #endif
   581 #ifdef MID_MUSIC
   582 		case MUS_MID:
   583 			Timidity_SetVolume(music_volume);
   584 			break;
   585 #endif
   586 #ifdef MP3_MUSIC
   587 		case MUS_MP3:
   588 			SMPEG_setvolume(music_playing->data.mp3,((float)music_volume/(float)MIX_MAX_VOLUME)*100.0);
   589 			break;
   590 #endif
   591 		default:
   592 			/* Unknown music type?? */
   593 			break;
   594 		}
   595 	}
   596 	return(prev_volume);
   597 }
   598 
   599 static void lowlevel_halt(void)
   600 {
   601 	switch (music_playing->type) {
   602 #ifdef CMD_MUSIC
   603 	case MUS_CMD:
   604 		MusicCMD_Stop(music_playing->data.cmd);
   605 		break;
   606 #endif
   607 #ifdef WAV_MUSIC
   608 	case MUS_WAV:
   609 		WAVStream_Stop();
   610 		break;
   611 #endif
   612 #ifdef MOD_MUSIC
   613 	case MUS_MOD:
   614 		Player_Stop();
   615 		break;
   616 #endif
   617 #ifdef MID_MUSIC
   618 	case MUS_MID:
   619 		Timidity_Stop();
   620 		break;
   621 #endif
   622 #ifdef MP3_MUSIC
   623 	case MUS_MP3:
   624 		SMPEG_stop(music_playing->data.mp3);
   625 		break;
   626 #endif
   627 	default:
   628 		/* Unknown music type?? */
   629 		return;
   630 	}
   631 	if(music_playing->fading != MIX_NO_FADING) /* Restore volume */
   632 		music_volume = music_playing->fade_volume;
   633 	music_playing->fading = MIX_NO_FADING;
   634 	music_playing = 0;
   635 	music_active = 0;
   636 	music_loops = 0;
   637 	music_paused = 0;
   638 	music_stopped = 0;
   639 }
   640 
   641 /* Halt playing of music */
   642 int Mix_HaltMusic(void)
   643 {
   644 	if ( music_playing && !music_stopped ) {
   645 		/* Mark the music to be stopped from the sound thread */
   646 		music_stopped = 1;
   647 		/* Wait for it to be actually stopped */
   648 		while ( music_playing )
   649 			SDL_Delay(10);
   650 	}
   651 	return(0);
   652 }
   653 
   654 /* Progressively stop the music */
   655 int Mix_FadeOutMusic(int ms)
   656 {
   657 	if ( music_playing && !music_stopped && music_playing->fading==MIX_NO_FADING ) {
   658 		if ( music_volume>0 ) {
   659 			music_playing->fading = MIX_FADING_OUT;
   660 			music_playing->fade_volume = music_volume;
   661 			music_playing->fade_length = ms;
   662 			music_playing->ticks_fade = SDL_GetTicks();
   663 			return(1);
   664 		}
   665 	}
   666 	return(0);
   667 }
   668 
   669 Mix_Fading Mix_FadingMusic(void)
   670 {
   671 	if( music_playing && !music_stopped )
   672 		return music_playing->fading;
   673 	return MIX_NO_FADING;
   674 }
   675 
   676 /* Pause/Resume the music stream */
   677 void Mix_PauseMusic(void)
   678 {
   679 	if ( music_playing && music_active && !music_stopped ) {
   680 		music_active = 0;
   681 		music_paused = 1;
   682 	}
   683 }
   684 
   685 void Mix_ResumeMusic(void)
   686 {
   687 	if ( music_playing && !music_active && !music_stopped ) {
   688 		music_active = 1;
   689 		music_paused = 0;
   690 	}
   691 }
   692 
   693 void Mix_RewindMusic(void)
   694 {
   695 	if ( music_playing && !music_stopped ) {
   696 		switch ( music_playing->type ) {
   697 #ifdef MP3_MUSIC
   698 		case MUS_MP3:
   699 			SMPEG_rewind(music_playing->data.mp3);
   700 			break;
   701 #endif
   702 			/* TODO: Implement this for other music backends */
   703 		}
   704 	}
   705 }
   706 
   707 int Mix_PausedMusic(void)
   708 {
   709 	return music_paused;
   710 }
   711 
   712 /* Check the status of the music */
   713 int Mix_PlayingMusic(void)
   714 {
   715 	if ( music_playing && ! music_stopped ) {
   716 		switch (music_playing->type) {
   717 #ifdef CMD_MUSIC
   718 			case MUS_CMD:
   719 				if (!MusicCMD_Active(music_playing->data.cmd)) {
   720 					return(0);
   721 				}
   722 				break;
   723 #endif
   724 #ifdef WAV_MUSIC
   725 			case MUS_WAV:
   726 				if ( ! WAVStream_Active() ) {
   727 					return(0);
   728 				}
   729 				break;
   730 #endif
   731 #ifdef MOD_MUSIC
   732 			case MUS_MOD:
   733 				if ( ! Player_Active() ) {
   734 					return(0);
   735 				}
   736 				break;
   737 #endif
   738 #ifdef MID_MUSIC
   739 			case MUS_MID:
   740 				if ( ! Timidity_Active() ) {
   741 					return(0);
   742 				}
   743 				break;
   744 #endif
   745 #ifdef MP3_MUSIC
   746 			case MUS_MP3:
   747 				if(SMPEG_status(music_playing->data.mp3)!=SMPEG_PLAYING)
   748 					return(0);
   749 				break;
   750 #endif
   751 		}
   752 		return(1);
   753 	}
   754 	return(0);
   755 }
   756 
   757 /* Set the external music playback command */
   758 int Mix_SetMusicCMD(const char *command)
   759 {
   760 	Mix_HaltMusic();
   761 	if ( music_cmd ) {
   762 		free(music_cmd);
   763 		music_cmd = NULL;
   764 	}
   765 	if ( command ) {
   766 		music_cmd = (char *)malloc(strlen(command)+1);
   767 		if ( music_cmd == NULL ) {
   768 			return(-1);
   769 		}
   770 		strcpy(music_cmd, command);
   771 	}
   772 	return(0);
   773 }
   774 
   775 /* Uninitialize the music players */
   776 void close_music(void)
   777 {
   778 	Mix_HaltMusic();
   779 #ifdef CMD_MUSIC
   780 	Mix_SetMusicCMD(NULL);
   781 #endif
   782 #ifdef MOD_MUSIC
   783 	MikMod_Exit();
   784 #endif
   785 }
   786