/* Set the playing music position */ int music_internal_position(double position) { int retval = 0; switch (music_playing->type) { #ifdef MODPLUG_MUSIC case MUS_MODPLUG: modplug_jump_to_time(music_playing->data.modplug, position); break; #endif #ifdef MOD_MUSIC case MUS_MOD: MOD_jump_to_time(music_playing->data.module, position); break; #endif #ifdef OGG_MUSIC case MUS_OGG: OGG_jump_to_time(music_playing->data.ogg, position); break; #endif #ifdef FLAC_MUSIC case MUS_FLAC: FLAC_jump_to_time(music_playing->data.flac, position); break; #endif #ifdef MP3_MUSIC case MUS_MP3: smpeg.SMPEG_rewind(music_playing->data.mp3); smpeg.SMPEG_play(music_playing->data.mp3); if ( position > 0.0 ) { smpeg.SMPEG_skip(music_playing->data.mp3, (float)position); } break; #endif #ifdef MP3_MAD_MUSIC case MUS_MP3_MAD: mad_seek(music_playing->data.mp3_mad, position); break; #endif default: /* TODO: Implement this for other music backends */ retval = -1; break; } return(retval); }
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; }