/* SDL_RWops compatibility */ Mix_Music *Mix_LoadMUS_RW(SDL_RWops *rw) { //Sanity check: only MOD! if (detect_music_type(rw) != MUS_MOD){ printf("Error: format not supported.\n"); return NULL; } MODULE *module; struct MREADER* reader = _mm_new_rwops_reader (rw); if (reader) { module = Player_LoadGeneric(reader,64,0); if(reader) free(reader); return (Mix_Music *) module; } else { printf("Could not load module, reason: %s\n", MikMod_strerror(MikMod_errno)); } return NULL; }
/* Load a music file */ Mix_Music *Mix_LoadMUS(const char *file) { SDL_RWops *rw; Mix_Music *music; Mix_MusicType type; char *ext = strrchr(file, '.'); #ifdef CMD_MUSIC if ( music_cmd ) { /* 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; music->type = MUS_CMD; music->data.cmd = MusicCMD_LoadSong(music_cmd, file); if ( music->data.cmd == NULL ) { SDL_free(music); music == NULL; } return music; } #endif rw = SDL_RWFromFile(file, "rb"); if ( rw == NULL ) { Mix_SetError("Couldn't open '%s'", file); return NULL; } /* Use the extension as a first guess on the file type */ type = MUS_NONE; ext = strrchr(file, '.'); /* No need to guard these with #ifdef *_MUSIC stuff, * since we simply call Mix_LoadMUSType_RW() later */ if ( ext ) { ++ext; /* skip the dot in the extension */ if ( MIX_string_equals(ext, "WAV") ) { type = MUS_WAV; } else if ( MIX_string_equals(ext, "MID") || MIX_string_equals(ext, "MIDI") || MIX_string_equals(ext, "KAR") ) { type = MUS_MID; } else if ( MIX_string_equals(ext, "OGG") ) { type = MUS_OGG; } else if ( MIX_string_equals(ext, "FLAC") ) { type = MUS_FLAC; } else if ( MIX_string_equals(ext, "MPG") || MIX_string_equals(ext, "MPEG") || MIX_string_equals(ext, "MP3") || MIX_string_equals(ext, "MAD") ) { type = MUS_MP3; } } if ( type == MUS_NONE ) { type = detect_music_type(rw); } /* We need to know if a specific error occurs; if not, we'll set a * generic one, so we clear the current one. */ Mix_SetError(""); music = Mix_LoadMUSType_RW(rw, type, SDL_TRUE); if ( music == NULL && Mix_GetError()[0] == '\0' ) { SDL_FreeRW(rw); Mix_SetError("Couldn't open '%s'", file); } return music; }
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; }