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