diff --git a/desktop_version/src/Music.cpp b/desktop_version/src/Music.cpp index b725940c..9b4d37a6 100644 --- a/desktop_version/src/Music.cpp +++ b/desktop_version/src/Music.cpp @@ -372,9 +372,20 @@ float SoundTrack::volume = 0.0f; class MusicTrack { public: - MusicTrack(SDL_RWops *rw) + MusicTrack(SDL_RWops *rw, bool autoload = true) { SDL_zerop(this); + this->rw = rw; + this->autoload = autoload; + if (autoload) + { + Load(); + } + } + + void Load(void) + { + loaded = true; read_buf = (Uint8*) SDL_malloc(rw->size(rw)); SDL_RWread(rw, read_buf, rw->size(rw), 1); int err; @@ -385,7 +396,7 @@ public: { vlog_error("Unable to create Vorbis handle, error %d", err); VVV_free(read_buf); - goto end; + return; } vorbis_info = stb_vorbis_get_info(vorbis); format.wFormatTag = FAUDIO_FORMAT_IEEE_FLOAT; @@ -407,25 +418,54 @@ public: vorbis_comment = stb_vorbis_get_comment(vorbis); parseComments(this, vorbis_comment.comment_list, vorbis_comment.comment_list_length); valid = true; - -end: - SDL_RWclose(rw); } - void Dispose(void) + void Unload(void) { + if (!loaded) + { + return; + } VVV_freefunc(stb_vorbis_close, vorbis); VVV_free(read_buf); VVV_free(decoded_buf_playing); VVV_free(decoded_buf_reserve); + /* The song might get loaded again, so reset the read cursor */ + SDL_RWseek(rw, 0, RW_SEEK_SET); + loaded = false; + } + + void Dispose(void) + { + if (loaded) + { + Unload(); + } if (!IsHalted()) { VVV_freefunc(FAudioVoice_DestroyVoice, musicVoice); } + SDL_RWclose(rw); } bool Play(bool loop) { + Halt(); + + if (currentTrack != this) + { + if (currentTrack && !currentTrack->autoload) + { + currentTrack->Unload(); + } + currentTrack = this; + } + + if (!loaded) + { + Load(); + } + if (!valid) { return false; @@ -435,8 +475,6 @@ end: sample_pos = 0; stb_vorbis_seek_start(vorbis); - Halt(); - SDL_zero(callbacks); callbacks.OnBufferStart = &MusicTrack::refillReserve; callbacks.OnBufferEnd = &MusicTrack::swapBuffers; @@ -513,6 +551,7 @@ end: } } + SDL_RWops *rw; stb_vorbis* vorbis; int channels; Uint32 size; @@ -527,9 +566,12 @@ end: Uint8* decoded_buf_reserve; Uint8* read_buf; bool shouldloop; + bool loaded; bool valid; + bool autoload; static bool paused; + static MusicTrack *currentTrack; static FAudioSourceVoice* musicVoice; static void refillReserve(FAudioVoiceCallback* callback, void* ctx) @@ -709,6 +751,7 @@ end: }; bool MusicTrack::paused = false; FAudioSourceVoice* MusicTrack::musicVoice = NULL; +MusicTrack* MusicTrack::currentTrack = NULL; musicclass::musicclass(void) { @@ -833,7 +876,7 @@ void musicclass::init(void) } \ else \ { \ - musicTracks.push_back(MusicTrack(rw)); \ + musicTracks.push_back(MusicTrack(rw, false)); \ } TRACK_NAMES(_)