music.c
changeset 625 1d489d8ec2e0
parent 621 944412baab72
child 629 87c536d57d92
     1.1 --- a/music.c	Sat Jun 01 15:49:18 2013 -0700
     1.2 +++ b/music.c	Sat Jun 01 19:52:15 2013 -0700
     1.3 @@ -192,7 +192,7 @@
     1.4  
     1.5  
     1.6  /* If music isn't playing, halt it if no looping is required, restart it */
     1.7 -/* otherwhise. NOP if the music is playing */
     1.8 +/* othesrchise. NOP if the music is playing */
     1.9  static int music_halt_or_loop (void)
    1.10  {
    1.11      /* Restart music if it has to loop */
    1.12 @@ -461,17 +461,17 @@
    1.13   * actually be MOD-based.
    1.14   *
    1.15   * Returns MUS_NONE in case of errors. */
    1.16 -static Mix_MusicType detect_music_type(SDL_RWops *rw)
    1.17 +static Mix_MusicType detect_music_type(SDL_RWops *src)
    1.18  {
    1.19      Uint8 magic[5];
    1.20      Uint8 moremagic[9];
    1.21  
    1.22 -    Sint64 start = SDL_RWtell(rw);
    1.23 -    if (SDL_RWread(rw, magic, 1, 4) != 4 || SDL_RWread(rw, moremagic, 1, 8) != 8 ) {
    1.24 +    Sint64 start = SDL_RWtell(src);
    1.25 +    if (SDL_RWread(src, magic, 1, 4) != 4 || SDL_RWread(src, moremagic, 1, 8) != 8 ) {
    1.26          Mix_SetError("Couldn't read from RWops");
    1.27          return MUS_NONE;
    1.28      }
    1.29 -    SDL_RWseek(rw, start, RW_SEEK_SET);
    1.30 +    SDL_RWseek(src, start, RW_SEEK_SET);
    1.31      magic[4]='\0';
    1.32      moremagic[8] = '\0';
    1.33  
    1.34 @@ -512,7 +512,7 @@
    1.35  /* Load a music file */
    1.36  Mix_Music *Mix_LoadMUS(const char *file)
    1.37  {
    1.38 -    SDL_RWops *rw;
    1.39 +    SDL_RWops *src;
    1.40      Mix_Music *music;
    1.41      Mix_MusicType type;
    1.42      char *ext = strrchr(file, '.');
    1.43 @@ -536,8 +536,8 @@
    1.44      }
    1.45  #endif
    1.46  
    1.47 -    rw = SDL_RWFromFile(file, "rb");
    1.48 -    if ( rw == NULL ) {
    1.49 +    src = SDL_RWFromFile(file, "rb");
    1.50 +    if ( src == NULL ) {
    1.51          Mix_SetError("Couldn't open '%s'", file);
    1.52          return NULL;
    1.53      }
    1.54 @@ -567,40 +567,44 @@
    1.55          }
    1.56      }
    1.57      if ( type == MUS_NONE ) {
    1.58 -        type = detect_music_type(rw);
    1.59 +        type = detect_music_type(src);
    1.60      }
    1.61  
    1.62      /* We need to know if a specific error occurs; if not, we'll set a
    1.63       * generic one, so we clear the current one. */
    1.64      Mix_SetError("");
    1.65 -    music = Mix_LoadMUSType_RW(rw, type, SDL_TRUE);
    1.66 +    music = Mix_LoadMUSType_RW(src, type, SDL_TRUE);
    1.67      if ( music == NULL && Mix_GetError()[0] == '\0' ) {
    1.68 -        SDL_FreeRW(rw);
    1.69          Mix_SetError("Couldn't open '%s'", file);
    1.70      }
    1.71      return music;
    1.72  }
    1.73  
    1.74 -Mix_Music *Mix_LoadMUS_RW(SDL_RWops *rw)
    1.75 +Mix_Music *Mix_LoadMUS_RW(SDL_RWops *src, int freesrc)
    1.76  {
    1.77 -    return Mix_LoadMUSType_RW(rw, MUS_NONE, SDL_FALSE);
    1.78 +    return Mix_LoadMUSType_RW(src, MUS_NONE, freesrc);
    1.79  }
    1.80  
    1.81 -Mix_Music *Mix_LoadMUSType_RW(SDL_RWops *rw, Mix_MusicType type, int freesrc)
    1.82 +Mix_Music *Mix_LoadMUSType_RW(SDL_RWops *src, Mix_MusicType type, int freesrc)
    1.83  {
    1.84      Mix_Music *music;
    1.85 +    Sint64 start;
    1.86  
    1.87 -    if (!rw) {
    1.88 +    if (!src) {
    1.89          Mix_SetError("RWops pointer is NULL");
    1.90          return NULL;
    1.91      }
    1.92 +    start = SDL_RWtell(src);
    1.93  
    1.94      /* If the caller wants auto-detection, figure out what kind of file
    1.95       * this is. */
    1.96      if (type == MUS_NONE) {
    1.97 -        if ((type = detect_music_type(rw)) == MUS_NONE) {
    1.98 +        if ((type = detect_music_type(src)) == MUS_NONE) {
    1.99              /* Don't call Mix_SetError() here since detect_music_type()
   1.100               * does that. */
   1.101 +            if (freesrc) {
   1.102 +                SDL_RWclose(src);
   1.103 +            }
   1.104              return NULL;
   1.105          }
   1.106      }
   1.107 @@ -609,73 +613,66 @@
   1.108      music = (Mix_Music *)SDL_malloc(sizeof(Mix_Music));
   1.109      if (music == NULL ) {
   1.110          Mix_SetError("Out of memory");
   1.111 +        if (freesrc) {
   1.112 +            SDL_RWclose(src);
   1.113 +        }
   1.114          return NULL;
   1.115      }
   1.116 -    music->error = 0;
   1.117 +    music->error = 1;
   1.118  
   1.119      switch (type) {
   1.120  #ifdef WAV_MUSIC
   1.121      case MUS_WAV:
   1.122 -        /* The WAVE loader needs the first 4 bytes of the header */
   1.123 -        {
   1.124 -            Uint8 magic[5];
   1.125 -            Sint64 start = SDL_RWtell(rw);
   1.126 -            if (SDL_RWread(rw, magic, 1, 4) != 4) {
   1.127 -                Mix_SetError("Couldn't read from RWops");
   1.128 -                SDL_free(music);
   1.129 -                return NULL;
   1.130 -            }
   1.131 -            SDL_RWseek(rw, start, RW_SEEK_SET);
   1.132 -            magic[4] = '\0';
   1.133 -            music->type = MUS_WAV;
   1.134 -            music->data.wave = WAVStream_LoadSong_RW(rw, (char *)magic, freesrc);
   1.135 -        }
   1.136 -        if (music->data.wave == NULL) {
   1.137 -            music->error = 1;
   1.138 +        music->type = MUS_WAV;
   1.139 +        music->data.wave = WAVStream_LoadSong_RW(src, freesrc);
   1.140 +        if (music->data.wave) {
   1.141 +            music->error = 0;
   1.142          }
   1.143          break;
   1.144  #endif
   1.145  #ifdef OGG_MUSIC
   1.146      case MUS_OGG:
   1.147          music->type = MUS_OGG;
   1.148 -        music->data.ogg = OGG_new_RW(rw, freesrc);
   1.149 -        if ( music->data.ogg == NULL ) {
   1.150 -            music->error = 1;
   1.151 +        music->data.ogg = OGG_new_RW(src, freesrc);
   1.152 +        if (music->data.ogg) {
   1.153 +            music->error = 0;
   1.154          }
   1.155          break;
   1.156  #endif
   1.157  #ifdef FLAC_MUSIC
   1.158      case MUS_FLAC:
   1.159          music->type = MUS_FLAC;
   1.160 -        music->data.flac = FLAC_new_RW(rw, freesrc);
   1.161 -        if ( music->data.flac == NULL ) {
   1.162 -            music->error = 1;
   1.163 +        music->data.flac = FLAC_new_RW(src, freesrc);
   1.164 +        if (music->data.flac) {
   1.165 +            music->error = 0;
   1.166          }
   1.167          break;
   1.168  #endif
   1.169  #ifdef MP3_MUSIC
   1.170      case MUS_MP3:
   1.171 -        if ( Mix_Init(MIX_INIT_MP3) ) {
   1.172 +        if (Mix_Init(MIX_INIT_MP3)) {
   1.173              SMPEG_Info info;
   1.174              music->type = MUS_MP3;
   1.175 -            music->data.mp3 = smpeg.SMPEG_new_rwops(rw, &info, 0);
   1.176 -            if ( !info.has_audio ) {
   1.177 +            music->data.mp3 = smpeg.SMPEG_new_rwops(src, &info, freesrc, 0);
   1.178 +            if (!info.has_audio) {
   1.179                  Mix_SetError("MPEG file does not have any audio stream.");
   1.180 -                music->error = 1;
   1.181 +                smpeg.SMPEG_delete(music->data.mp3);
   1.182 +                /* Deleting the MP3 closed the source if desired */
   1.183 +                freesrc = SDL_FALSE;
   1.184              } else {
   1.185                  smpeg.SMPEG_actualSpec(music->data.mp3, &used_mixer);
   1.186 +                music->error = 0;
   1.187              }
   1.188 -        } else {
   1.189 -            music->error = 1;
   1.190          }
   1.191          break;
   1.192  #elif defined(MP3_MAD_MUSIC)
   1.193      case MUS_MP3:
   1.194          music->type = MUS_MP3_MAD;
   1.195 -        music->data.mp3_mad = mad_openFileRW(rw, &used_mixer, freesrc);
   1.196 -        if (music->data.mp3_mad == 0) {
   1.197 +        music->data.mp3_mad = mad_openFileRW(src, &used_mixer, freesrc);
   1.198 +        if (music->data.mp3_mad) {
   1.199 +            music->error = 0;
   1.200 +        } else {
   1.201              Mix_SetError("Could not initialize MPEG stream.");
   1.202 -            music->error = 1;
   1.203          }
   1.204          break;
   1.205  #endif
   1.206 @@ -683,55 +680,60 @@
   1.207      case MUS_MID:
   1.208          music->type = MUS_MID;
   1.209  #ifdef USE_NATIVE_MIDI
   1.210 -        if ( native_midi_ok ) {
   1.211 -            music->data.nativemidi = native_midi_loadsong_RW(rw, freesrc);
   1.212 -            if ( music->data.nativemidi == NULL ) {
   1.213 +        if (native_midi_ok) {
   1.214 +            SDL_RWseek(src, start, RW_SEEK_SET);
   1.215 +            music->data.nativemidi = native_midi_loadsong_RW(src, freesrc);
   1.216 +            if (music->data.nativemidi) {
   1.217 +                music->error = 0;
   1.218 +            } else {
   1.219                  Mix_SetError("%s", native_midi_error());
   1.220 -                music->error = 1;
   1.221              }
   1.222              break;
   1.223          }
   1.224  #endif
   1.225  #ifdef USE_FLUIDSYNTH_MIDI
   1.226 -        if ( fluidsynth_ok ) {
   1.227 -            music->data.fluidsynthmidi = fluidsynth_loadsong_RW(rw, freesrc);
   1.228 -            if ( music->data.fluidsynthmidi == NULL ) {
   1.229 -                music->error = 1;
   1.230 +        if (fluidsynth_ok) {
   1.231 +            SDL_RWseek(src, start, RW_SEEK_SET);
   1.232 +            music->data.fluidsynthmidi = fluidsynth_loadsong_RW(src, freesrc);
   1.233 +            if (music->data.fluidsynthmidi) {
   1.234 +                music->error = 0;
   1.235              }
   1.236              break;
   1.237          }
   1.238  #endif
   1.239  #ifdef USE_TIMIDITY_MIDI
   1.240 -        if ( timidity_ok ) {
   1.241 -            music->data.midi = Timidity_LoadSong_RW(rw, freesrc);
   1.242 -            if ( music->data.midi == NULL ) {
   1.243 +        if (timidity_ok) {
   1.244 +            SDL_RWseek(src, start, RW_SEEK_SET);
   1.245 +            music->data.midi = Timidity_LoadSong_RW(src, freesrc);
   1.246 +            if (music->data.midi) {
   1.247 +                music->error = 0;
   1.248 +            } else {
   1.249                  Mix_SetError("%s", Timidity_Error());
   1.250 -                music->error = 1;
   1.251              }
   1.252          } else {
   1.253              Mix_SetError("%s", Timidity_Error());
   1.254 -            music->error = 1;
   1.255          }
   1.256  #endif
   1.257          break;
   1.258  #endif
   1.259  #if defined(MODPLUG_MUSIC) || defined(MOD_MUSIC)
   1.260      case MUS_MOD:
   1.261 -        music->error = 1;
   1.262  #ifdef MODPLUG_MUSIC
   1.263 -        if ( music->error ) {
   1.264 +        if (music->error) {
   1.265 +            SDL_RWseek(src, start, RW_SEEK_SET);
   1.266              music->type = MUS_MODPLUG;
   1.267 -            music->data.modplug = modplug_new_RW(rw, freesrc);
   1.268 -            if ( music->data.modplug ) {
   1.269 +            music->data.modplug = modplug_new_RW(src, freesrc);
   1.270 +            if (music->data.modplug) {
   1.271                  music->error = 0;
   1.272              }
   1.273          }
   1.274  #endif
   1.275  #ifdef MOD_MUSIC
   1.276 -        if ( music->error ) {
   1.277 +        if (music->error) {
   1.278 +            SDL_RWseek(src, start, RW_SEEK_SET);
   1.279              music->type = MUS_MOD;
   1.280 -            music->data.module = MOD_new_RW(rw, freesrc);
   1.281 -            if ( music->data.module ) {
   1.282 +            music->data.module = MOD_new_RW(src, freesrc);
   1.283 +            if (music->data.module) {
   1.284                  music->error = 0;
   1.285              }
   1.286          }
   1.287 @@ -741,15 +743,19 @@
   1.288  
   1.289      default:
   1.290          Mix_SetError("Unrecognized music format");
   1.291 -        music->error=1;
   1.292 +        break;
   1.293      } /* switch (want) */
   1.294  
   1.295 -
   1.296      if (music->error) {
   1.297          SDL_free(music);
   1.298 -        music=NULL;
   1.299 +        if (freesrc) {
   1.300 +            SDL_RWclose(src);
   1.301 +        } else {
   1.302 +            SDL_RWseek(src, start, RW_SEEK_SET);
   1.303 +        }
   1.304 +        music = NULL;
   1.305      }
   1.306 -    return(music);
   1.307 +    return music;
   1.308  }
   1.309  
   1.310  /* Free a music chunk previously loaded */