From 53535919d3cf62f97bc9fee28ee31e4f577d2700 Mon Sep 17 00:00:00 2001 From: Andrei Karas Date: Tue, 24 Jan 2012 22:59:25 +0300 Subject: Based on commit b856e8b47ab2dfd393e3c2720c5647eb66393931 Author: Thorbjørn Lindeijer Date: Tue Jan 24 19:14:24 2012 +0100 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Stream music files directly from the archives Use Mix_LoadMUS_RW to stream music files directly from PhysFS. I kept around ResourceManager:copyFile for now, since it may have other uses. --- src/resources/music.cpp | 46 ++++++------------------ src/resources/music.h | 17 ++++----- src/sound.cpp | 93 +++++++++++++++++-------------------------------- src/sound.h | 23 ++++++------ 4 files changed, 60 insertions(+), 119 deletions(-) diff --git a/src/resources/music.cpp b/src/resources/music.cpp index 7bdd51d36..b13812f18 100644 --- a/src/resources/music.cpp +++ b/src/resources/music.cpp @@ -26,27 +26,21 @@ #include "debug.h" -Music::Music(Mix_Chunk *music): - mChunk(music), - mChannel(-1) +Music::Music(Mix_Music *music) : + mMusic(music) { } Music::~Music() { - //Mix_FreeMusic(music); - Mix_FreeChunk(mChunk); + Mix_FreeMusic(mMusic); } Resource *Music::load(SDL_RWops *rw) { - // Use Mix_LoadMUS to load the raw music data - //Mix_Music* music = Mix_LoadMUS_RW(rw); Need to be implemeted - Mix_Chunk *tmpMusic = Mix_LoadWAV_RW(rw, 1); - - if (tmpMusic) + if (Mix_Music *music = Mix_LoadMUS_RW(rw)) { - return new Music(tmpMusic); + return new Music(music); } else { @@ -55,30 +49,10 @@ Resource *Music::load(SDL_RWops *rw) } } -bool Music::play(int loops) +bool Music::play(int loops, int fadeIn) { - /* - * Warning: loops should be always set to -1 (infinite) with current - * implementation to avoid halting the playback of other samples - */ - - /*if (Mix_PlayMusic(music, loops)) - return true;*/ - Mix_VolumeChunk(mChunk, 120); - mChannel = Mix_PlayChannel(-1, mChunk, loops); - - return mChannel != -1; -} - -void Music::stop() -{ - /* - * Warning: very dungerous trick, it could try to stop channels occupied - * by samples rather than the current music file - */ - - //Mix_HaltMusic(); - - if (mChannel != -1) - Mix_HaltChannel(mChannel); + if (fadeIn > 0) + return Mix_FadeInMusic(mMusic, loops, fadeIn); + else + return Mix_PlayMusic(mMusic, loops); } diff --git a/src/resources/music.h b/src/resources/music.h index 6df63b2ac..88cc752bc 100644 --- a/src/resources/music.h +++ b/src/resources/music.h @@ -51,27 +51,22 @@ class Music : public Resource /** * Plays the music. * - * @param loops Number of times to repeat the playback. + * @param loops Number of times to repeat the playback (-1 means + * forever). + * @param fadeIn Duration in milliseconds to fade in the music. * * @return true if the playback started properly * false otherwise. */ - virtual bool play(int loops); - - /** - * Stops the music. - */ - virtual void stop(); + bool play(int loops = -1, int fadeIn = 0); protected: /** * Constructor. */ - Music(Mix_Chunk *music); + Music(Mix_Music *music); - //Mix_Music *music; - Mix_Chunk *mChunk; - int mChannel; + Mix_Music *mMusic; }; #endif diff --git a/src/sound.cpp b/src/sound.cpp index 123a66567..fb6958e25 100644 --- a/src/sound.cpp +++ b/src/sound.cpp @@ -27,6 +27,7 @@ #include "logger.h" #include "sound.h" +#include "resources/music.h" #include "resources/resourcemanager.h" #include "resources/soundeffect.h" @@ -184,84 +185,49 @@ void Sound::setSfxVolume(int volume) Mix_Volume(-1, mSfxVolume); } -static Mix_Music *loadMusic(const std::string &filename) +static Music *loadMusic(const std::string &fileName) { ResourceManager *resman = ResourceManager::getInstance(); - std::string path = resman->getPath( - paths.getStringValue("music") + filename); - - if (path.find(".zip/") != std::string::npos || - path.find(".zip\\") != std::string::npos) - { - // Music file is a virtual file inside a zip archive - we have to copy - // it to a temporary physical file so that SDL_mixer can stream it. - logger->log("Loading music \"%s\" from temporary file tempMusic.ogg", - path.c_str()); - bool success = resman->copyFile(paths.getStringValue("music") - + filename, "tempMusic.ogg"); - if (success) - path = resman->getPath("tempMusic.ogg"); - else - return nullptr; - } - else - { - logger->log("Loading music \"%s\"", path.c_str()); - } - - if (path.empty()) - return nullptr; - - Mix_Music *music = Mix_LoadMUS(path.c_str()); - - if (!music) - { - logger->log("Mix_LoadMUS() Error loading '%s': %s", path.c_str(), - Mix_GetError()); - } - - return music; + return resman->getMusic(paths.getStringValue("music") + fileName); } -void Sound::playMusic(const std::string &filename) +void Sound::playMusic(const std::string &fileName) { - mCurrentMusicFile = filename; + mCurrentMusicFile = fileName; if (!mInstalled || !mPlayMusic) return; haltMusic(); - if (!filename.empty() && (mMusic = loadMusic(filename))) - Mix_PlayMusic(mMusic, -1); // Loop forever + if (!fileName.empty()) + { + mMusic = loadMusic(fileName); + if (mMusic) + mMusic->play(); + } } void Sound::stopMusic() { - if (!mInstalled) - return; - - logger->log1("Sound::stopMusic()"); - - if (mMusic) - { - Mix_HaltMusic(); - Mix_FreeMusic(mMusic); - mMusic = nullptr; - } + haltMusic(); } -void Sound::fadeInMusic(const std::string &path, int ms) +void Sound::fadeInMusic(const std::string &fileName, int ms) { - mCurrentMusicFile = path; + mCurrentMusicFile = fileName; if (!mInstalled || !mPlayMusic) return; haltMusic(); - if ((mMusic = loadMusic(path.c_str()))) - Mix_FadeInMusic(mMusic, -1, ms); // Loop forever + if (!fileName.empty()) + { + mMusic = loadMusic(fileName); + if (mMusic) + mMusic->play(-1, ms); + } } void Sound::fadeOutMusic(int ms) @@ -285,9 +251,9 @@ void Sound::fadeOutMusic(int ms) } } -void Sound::fadeOutAndPlayMusic(const std::string &path, int ms) +void Sound::fadeOutAndPlayMusic(const std::string &fileName, int ms) { - mNextMusicPath = path; + mNextMusicFile = fileName; fadeOutMusic(ms); } @@ -297,15 +263,15 @@ void Sound::logic() { if (mMusic) { - Mix_FreeMusic(mMusic); + mMusic->decRef(); mMusic = nullptr; } sFadingOutEnded = false; - if (!mNextMusicPath.empty()) + if (!mNextMusicFile.empty()) { - playMusic(mNextMusicPath); - mNextMusicPath.clear(); + playMusic(mNextMusicFile); + mNextMusicFile.clear(); } } } @@ -383,8 +349,11 @@ void Sound::haltMusic() return; Mix_HaltMusic(); - Mix_FreeMusic(mMusic); - mMusic = nullptr; + if (mMusic) + { + mMusic->decRef(); + mMusic = nullptr; + } } void Sound::changeAudio() diff --git a/src/sound.h b/src/sound.h index 6ac361cac..869f136da 100644 --- a/src/sound.h +++ b/src/sound.h @@ -29,6 +29,8 @@ #include +class Music; + /** Sound engine * * \ingroup CORE @@ -54,9 +56,9 @@ class Sound : public ConfigListener /** * Starts background music. * - * @param path The full path to the music file. + * @param fileName The name of the music file. */ - void playMusic(const std::string &path); + void playMusic(const std::string &fileName); /** * Stops currently running background music track. @@ -66,10 +68,10 @@ class Sound : public ConfigListener /** * Fades in background music. * - * @param path The full path to the music file. - * @param ms Duration of fade-in effect (ms) + * @param fileName The name of the music file. + * @param ms Duration of fade-in effect (ms) */ - void fadeInMusic(const std::string &path, int ms = 1000); + void fadeInMusic(const std::string &fileName, int ms = 1000); /** * Fades out currently running background music track. @@ -81,15 +83,16 @@ class Sound : public ConfigListener /** * Fades out a background music and play a new one. * - * @param path The full path to the fade in music file. - * @param ms Duration of fade-out effect (ms) + * @param fileName The name of the music file. + * @param ms Duration of fade-out effect (ms) */ - void fadeOutAndPlayMusic(const std::string &path, int ms = 1000); + void fadeOutAndPlayMusic(const std::string &fileName, int ms = 1000); int getMaxVolume() const { return MIX_MAX_VOLUME; } void setMusicVolume(int volume); + void setSfxVolume(int volume); /** @@ -133,7 +136,7 @@ class Sound : public ConfigListener * When calling fadeOutAndPlayMusic(), * the music file below will then be played */ - std::string mNextMusicPath; + std::string mNextMusicFile; bool mInstalled; @@ -141,7 +144,7 @@ class Sound : public ConfigListener int mMusicVolume; std::string mCurrentMusicFile; - Mix_Music *mMusic; + Music *mMusic; bool mPlayBattle; bool mPlayGui; bool mPlayMusic; -- cgit v1.2.3-60-g2f50