mad_data * mad_openFile(const char *filename, SDL_AudioSpec *mixer) { SDL_RWops *rw; rw = SDL_RWFromFile(filename, "rb"); if (rw == NULL) { return NULL; } return mad_openFileRW(rw, mixer); }
mad_data * mad_openFile(const char *filename, SDL_AudioSpec *mixer) { SDL_RWops *rw; mad_data *mp3_mad; rw = SDL_RWFromFile(filename, "rb"); if (rw == NULL) { return NULL; } mp3_mad = mad_openFileRW(rw, mixer); if (mp3_mad == NULL) { SDL_FreeRW(rw); return NULL; } mp3_mad->freerw = SDL_TRUE; return mp3_mad; }
Mix_Music *Mix_LoadMUSType_RW(SDL_RWops *rw, Mix_MusicType type, int freesrc) { Mix_Music *music; if (!rw) { Mix_SetError("RWops pointer is NULL"); return NULL; } /* If the caller wants auto-detection, figure out what kind of file * this is. */ if (type == MUS_NONE) { if ((type = detect_music_type(rw)) == MUS_NONE) { /* Don't call Mix_SetError() here since detect_music_type() * does that. */ return NULL; } } /* Allocate memory for the music structure */ music = (Mix_Music *)SDL_malloc(sizeof(Mix_Music)); if (music == NULL ) { Mix_SetError("Out of memory"); return NULL; } music->error = 0; switch (type) { #ifdef WAV_MUSIC case MUS_WAV: /* The WAVE loader needs the first 4 bytes of the header */ { Uint8 magic[5]; int start = SDL_RWtell(rw); if (SDL_RWread(rw, magic, 1, 4) != 4) { Mix_SetError("Couldn't read from RWops"); return MUS_NONE; } SDL_RWseek(rw, start, RW_SEEK_SET); magic[4] = '\0'; music->type = MUS_WAV; music->data.wave = WAVStream_LoadSong_RW(rw, (char *)magic, freesrc); } if (music->data.wave == NULL) { music->error = 1; } break; #endif #ifdef OGG_MUSIC case MUS_OGG: music->type = MUS_OGG; music->data.ogg = OGG_new_RW(rw, freesrc); if ( music->data.ogg == NULL ) { music->error = 1; } break; #endif #ifdef FLAC_MUSIC case MUS_FLAC: music->type = MUS_FLAC; music->data.flac = FLAC_new_RW(rw, freesrc); if ( music->data.flac == NULL ) { music->error = 1; } break; #endif #ifdef MP3_MUSIC case MUS_MP3: if ( Mix_Init(MIX_INIT_MP3) ) { SMPEG_Info info; music->type = MUS_MP3; music->data.mp3 = smpeg.SMPEG_new_rwops(rw, &info, 0); if ( !info.has_audio ) { Mix_SetError("MPEG file does not have any audio stream."); music->error = 1; } else { smpeg.SMPEG_actualSpec(music->data.mp3, &used_mixer); } } else { music->error = 1; } break; #elif defined(MP3_MAD_MUSIC) case MUS_MP3: music->type = MUS_MP3_MAD; music->data.mp3_mad = mad_openFileRW(rw, &used_mixer, freesrc); if (music->data.mp3_mad == 0) { Mix_SetError("Could not initialize MPEG stream."); music->error = 1; } break; #endif #ifdef MID_MUSIC case MUS_MID: music->type = MUS_MID; #ifdef USE_NATIVE_MIDI if ( native_midi_ok ) { music->data.nativemidi = native_midi_loadsong_RW(rw, freesrc); if ( music->data.nativemidi == NULL ) { Mix_SetError("%s", native_midi_error()); music->error = 1; } break; } #endif #ifdef USE_FLUIDSYNTH_MIDI if ( fluidsynth_ok ) { music->data.fluidsynthmidi = fluidsynth_loadsong_RW(rw, freesrc); if ( music->data.fluidsynthmidi == NULL ) { music->error = 1; } break; } #endif #ifdef USE_TIMIDITY_MIDI if ( timidity_ok ) { music->data.midi = Timidity_LoadSong_RW(rw, freesrc); if ( music->data.midi == NULL ) { Mix_SetError("%s", Timidity_Error()); music->error = 1; } } else { Mix_SetError("%s", Timidity_Error()); music->error = 1; } #endif break; #endif #if defined(MODPLUG_MUSIC) || defined(MOD_MUSIC) case MUS_MOD: music->error = 1; #ifdef MODPLUG_MUSIC if ( music->error ) { music->type = MUS_MODPLUG; music->data.modplug = modplug_new_RW(rw, freesrc); if ( music->data.modplug ) { music->error = 0; } } #endif #ifdef MOD_MUSIC if ( music->error ) { music->type = MUS_MOD; music->data.module = MOD_new_RW(rw, freesrc); if ( music->data.module ) { music->error = 0; } } #endif break; #endif default: Mix_SetError("Unrecognized music format"); music->error=1; } /* switch (want) */ if (music->error) { SDL_free(music); music=NULL; } return(music); }
Mix_Music *Mix_LoadMUSType_RW(SDL_RWops *src, Mix_MusicType type, int freesrc) { Mix_Music *music; Sint64 start; if (!src) { Mix_SetError("RWops pointer is NULL"); return NULL; } start = SDL_RWtell(src); /* If the caller wants auto-detection, figure out what kind of file * this is. */ if (type == MUS_NONE) { if ((type = detect_music_type(src)) == MUS_NONE) { /* Don't call Mix_SetError() here since detect_music_type() * does that. */ if (freesrc) { SDL_RWclose(src); } return NULL; } } /* Allocate memory for the music structure */ music = (Mix_Music *)SDL_malloc(sizeof(Mix_Music)); if (music == NULL ) { Mix_SetError("Out of memory"); if (freesrc) { SDL_RWclose(src); } return NULL; } music->error = 1; switch (type) { #ifdef WAV_MUSIC case MUS_WAV: music->type = MUS_WAV; music->data.wave = WAVStream_LoadSong_RW(src, freesrc); if (music->data.wave) { music->error = 0; } break; #endif #ifdef OGG_MUSIC case MUS_OGG: music->type = MUS_OGG; music->data.ogg = OGG_new_RW(src, freesrc); if (music->data.ogg) { music->error = 0; } break; #endif #ifdef FLAC_MUSIC case MUS_FLAC: music->type = MUS_FLAC; music->data.flac = FLAC_new_RW(src, freesrc); if (music->data.flac) { music->error = 0; } break; #endif #ifdef MP3_MUSIC case MUS_MP3: if (Mix_Init(MIX_INIT_MP3)) { SMPEG_Info info; music->type = MUS_MP3; music->data.mp3 = smpeg.SMPEG_new_rwops(src, &info, freesrc, 0); if (!info.has_audio) { Mix_SetError("MPEG file does not have any audio stream."); smpeg.SMPEG_delete(music->data.mp3); /* Deleting the MP3 closed the source if desired */ freesrc = SDL_FALSE; } else { smpeg.SMPEG_actualSpec(music->data.mp3, &used_mixer); music->error = 0; } } break; #elif defined(MP3_MAD_MUSIC) case MUS_MP3: music->type = MUS_MP3_MAD; music->data.mp3_mad = mad_openFileRW(src, &used_mixer, freesrc); if (music->data.mp3_mad) { music->error = 0; } else { Mix_SetError("Could not initialize MPEG stream."); } break; #endif #ifdef MID_MUSIC case MUS_MID: music->type = MUS_MID; #ifdef USE_NATIVE_MIDI if (native_midi_ok) { SDL_RWseek(src, start, RW_SEEK_SET); music->data.nativemidi = native_midi_loadsong_RW(src, freesrc); if (music->data.nativemidi) { music->error = 0; } else { Mix_SetError("%s", native_midi_error()); } break; } #endif #ifdef USE_FLUIDSYNTH_MIDI if (fluidsynth_ok) { SDL_RWseek(src, start, RW_SEEK_SET); music->data.fluidsynthmidi = fluidsynth_loadsong_RW(src, freesrc); if (music->data.fluidsynthmidi) { music->error = 0; } break; } #endif #ifdef USE_TIMIDITY_MIDI if (timidity_ok) { SDL_RWseek(src, start, RW_SEEK_SET); music->data.midi = Timidity_LoadSong_RW(src, freesrc); if (music->data.midi) { music->error = 0; } else { Mix_SetError("%s", Timidity_Error()); } } else { Mix_SetError("%s", Timidity_Error()); } #endif break; #endif #if defined(MODPLUG_MUSIC) || defined(MOD_MUSIC) case MUS_MOD: #ifdef MODPLUG_MUSIC if (music->error) { SDL_RWseek(src, start, RW_SEEK_SET); music->type = MUS_MODPLUG; music->data.modplug = modplug_new_RW(src, freesrc); if (music->data.modplug) { music->error = 0; } } #endif #ifdef MOD_MUSIC if (music->error) { SDL_RWseek(src, start, RW_SEEK_SET); music->type = MUS_MOD; music->data.module = MOD_new_RW(src, freesrc); if (music->data.module) { music->error = 0; } } #endif break; #endif default: Mix_SetError("Unrecognized music format"); break; } /* switch (want) */ if (music->error) { SDL_free(music); if (freesrc) { SDL_RWclose(src); } else { SDL_RWseek(src, start, RW_SEEK_SET); } music = NULL; } return music; }
SDL_AudioSpec *Mix_LoadMP3_RW(SDL_RWops *src, int freesrc, SDL_AudioSpec *spec, Uint8 **audio_buf, Uint32 *audio_len) { /* note: spec is initialized to mixer spec */ #if defined(MP3_MUSIC) SMPEG* mp3 = 0; SMPEG_Info info; #elif defined(MP3_MAD_MUSIC) mad_data *mp3_mad; #endif long samplesize; int read_len; const Uint32 chunk_len = 4096; int err = 0; if ((!src) || (!spec) || (!audio_buf) || (!audio_len)) { return NULL; } if (!err) { *audio_len = 0; *audio_buf = (Uint8*) SDL_malloc(chunk_len); err = (*audio_buf == NULL); } if (!err) { err = ((Mix_Init(MIX_INIT_MP3) & MIX_INIT_MP3) == 0); } if (!err) { #if defined(MP3_MUSIC) mp3 = smpeg.SMPEG_new_rwops(src, &info, freesrc, 0); err = (mp3 == NULL); #elif defined(MP3_MAD_MUSIC) mp3_mad = mad_openFileRW(src, spec, freesrc); err = (mp3_mad == NULL); #endif } #if defined(MP3_MUSIC) if (!err) { err = !info.has_audio; } #endif if (!err) { #if defined(MP3_MUSIC) smpeg.SMPEG_actualSpec(mp3, spec); smpeg.SMPEG_enableaudio(mp3, 1); smpeg.SMPEG_enablevideo(mp3, 0); smpeg.SMPEG_play(mp3); /* read once for audio length */ while ((read_len = smpeg.SMPEG_playAudio(mp3, *audio_buf, chunk_len)) > 0) { *audio_len += read_len; } smpeg.SMPEG_stop(mp3); #elif defined(MP3_MAD_MUSIC) mad_start(mp3_mad); /* read once for audio length */ while ((read_len = mad_getSamples(mp3_mad, *audio_buf, chunk_len)) > 0) { *audio_len += read_len; } mad_stop(mp3_mad); #endif err = (read_len < 0); } if (!err) { /* reallocate, if needed */ if ((*audio_len > 0) && (*audio_len != chunk_len)) { *audio_buf = (Uint8*) SDL_realloc(*audio_buf, *audio_len); err = (*audio_buf == NULL); } } if (!err) { /* read again for audio buffer, if needed */ if (*audio_len > chunk_len) { #if defined(MP3_MUSIC) smpeg.SMPEG_rewind(mp3); smpeg.SMPEG_play(mp3); err = (*audio_len != smpeg.SMPEG_playAudio(mp3, *audio_buf, *audio_len)); smpeg.SMPEG_stop(mp3); #elif defined(MP3_MAD_MUSIC) mad_seek(mp3_mad, 0); mad_start(mp3_mad); err = (*audio_len != mad_getSamples(mp3_mad, *audio_buf, *audio_len)); mad_stop(mp3_mad); #endif } } if (!err) { /* Don't return a buffer that isn't a multiple of samplesize */ samplesize = ((spec->format & 0xFF)/8)*spec->channels; *audio_len &= ~(samplesize-1); } #if defined(MP3_MUSIC) if (mp3) { smpeg.SMPEG_delete(mp3); mp3 = NULL; /* Deleting the MP3 closed the source if desired */ freesrc = SDL_FALSE; } #elif defined(MP3_MAD_MUSIC) if (mp3_mad) { mad_closeFile(mp3_mad); mp3_mad = NULL; /* Deleting the MP3 closed the source if desired */ freesrc = SDL_FALSE; } #endif if (freesrc) { SDL_RWclose(src); src = NULL; } /* handle error */ if (err) { if (*audio_buf != NULL) { SDL_free(*audio_buf); *audio_buf = NULL; } *audio_len = 0; spec = NULL; } return spec; }