Subversion Repositories Kolibri OS

Rev

Rev 8645 | Rev 9213 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed

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