From e9addb5a5e072b28eecfa1739ae38d67b68a2b23 Mon Sep 17 00:00:00 2001 From: krzys-h Date: Sat, 28 Dec 2013 12:30:46 +0100 Subject: Added smooth transition in music - issue #205 --- src/sound/oalsound/alsound.cpp | 81 +++++++++++++++++++++++++++++++++--------- src/sound/oalsound/alsound.h | 14 ++++++-- src/sound/sound.cpp | 6 ++-- src/sound/sound.h | 8 +++-- 4 files changed, 84 insertions(+), 25 deletions(-) (limited to 'src/sound') diff --git a/src/sound/oalsound/alsound.cpp b/src/sound/oalsound/alsound.cpp index 7f325c1..ef53236 100644 --- a/src/sound/oalsound/alsound.cpp +++ b/src/sound/oalsound/alsound.cpp @@ -57,6 +57,11 @@ void ALSound::CleanUp() { delete m_currentMusic; } + + for (auto item : m_oldMusic) + { + delete item.music; + } for (auto item : m_sounds) { @@ -101,7 +106,6 @@ bool ALSound::Create() alListenerf(AL_GAIN, m_audioVolume); alDistanceModel(AL_LINEAR_DISTANCE_CLAMPED); - m_currentMusic = new Channel(); GetLogger()->Info("Done.\n"); m_enabled = true; return true; @@ -469,13 +473,15 @@ bool ALSound::MuteAll(bool bMute) } } - if (bMute) - { - m_currentMusic->SetVolume(0.0f); - } - else - { - m_currentMusic->SetVolume(m_musicVolume); + if (m_currentMusic) { + if (bMute) + { + m_currentMusic->SetVolume(0.0f); + } + else + { + m_currentMusic->SetVolume(m_musicVolume); + } } return true; } @@ -542,6 +548,22 @@ void ALSound::FrameMove(float delta) } } } + + std::list toRemove; + + for (auto& it : m_oldMusic) + { + if (it.currentTime >= it.fadeTime) { + delete it.music; + toRemove.push_back(it); + } else { + it.currentTime += delta; + it.music->SetVolume(((it.fadeTime-it.currentTime) / it.fadeTime) * m_musicVolume); + } + } + + for (auto it : toRemove) + m_oldMusic.remove(it); } @@ -557,14 +579,23 @@ void ALSound::SetListener(const Math::Vector &eye, const Math::Vector &lookat) alListenerfv(AL_ORIENTATION, orientation); } -bool ALSound::PlayMusic(int rank, bool bRepeat) +bool ALSound::PlayMusic(int rank, bool bRepeat, float fadeTime) { std::stringstream filename; filename << "music" << std::setfill('0') << std::setw(3) << rank << ".ogg"; - return PlayMusic(filename.str(), bRepeat); + return PlayMusic(filename.str(), bRepeat, fadeTime); } -bool ALSound::PlayMusic(const std::string &filename, bool bRepeat) +bool operator<(const OldMusic & l, const OldMusic & r) +{ + return l.currentTime < r.currentTime; +} +bool operator==(const OldMusic & l, const OldMusic & r) +{ + return l.currentTime == r.currentTime; +} + +bool ALSound::PlayMusic(const std::string &filename, bool bRepeat, float fadeTime) { if (!m_enabled) { @@ -573,6 +604,8 @@ bool ALSound::PlayMusic(const std::string &filename, bool bRepeat) std::stringstream file; file << m_soundPath << "/" << filename; + + Buffer *buffer; // check if we have music in cache if (m_music.find(filename) == m_music.end()) @@ -583,16 +616,26 @@ bool ALSound::PlayMusic(const std::string &filename, bool bRepeat) GetLogger()->Warn("Requested music %s was not found.\n", filename.c_str()); return false; } - Buffer *buffer = new Buffer(); + + buffer = new Buffer(); buffer->LoadFromFile(file.str(), static_cast(-1)); - m_currentMusic->SetBuffer(buffer); } else { GetLogger()->Debug("Music loaded from cache\n"); - m_currentMusic->SetBuffer(m_music[filename]); + buffer = m_music[filename]; + } + + if (m_currentMusic) { + OldMusic old; + old.music = m_currentMusic; + old.fadeTime = fadeTime; + old.currentTime = 0.0f; + m_oldMusic.push_back(old); } + m_currentMusic = new Channel(); + m_currentMusic->SetBuffer(buffer); m_currentMusic->SetVolume(m_musicVolume); m_currentMusic->SetLoop(bRepeat); m_currentMusic->Play(); @@ -613,14 +656,20 @@ bool ALSound::RestartMusic() return true; } -void ALSound::StopMusic() +void ALSound::StopMusic(float fadeTime) { if (!m_enabled || !m_currentMusic) { return; } - SuspendMusic(); + OldMusic old; + old.music = m_currentMusic; + old.fadeTime = fadeTime; + old.currentTime = 0.0f; + m_oldMusic.push_back(old); + + m_currentMusic = nullptr; } diff --git a/src/sound/oalsound/alsound.h b/src/sound/oalsound/alsound.h index 2fdcff5..cd3bdd5 100644 --- a/src/sound/oalsound/alsound.h +++ b/src/sound/oalsound/alsound.h @@ -31,10 +31,17 @@ #include #include +#include #include +struct OldMusic { + Channel* music; + float fadeTime; + float currentTime; +}; + class ALSound : public CSoundInterface { public: @@ -65,11 +72,11 @@ public: bool StopAll(); bool MuteAll(bool bMute); - bool PlayMusic(int rank, bool bRepeat); - bool PlayMusic(const std::string &filename, bool bRepeat); + bool PlayMusic(int rank, bool bRepeat, float fadeTime=5.0f); + bool PlayMusic(const std::string &filename, bool bRepeat, float fadeTime=5.0f); bool RestartMusic(); void SuspendMusic(); - void StopMusic(); + void StopMusic(float fadeTime=5.0f); bool IsPlayingMusic(); private: @@ -86,6 +93,7 @@ private: std::map m_music; std::map m_channels; Channel *m_currentMusic; + std::list m_oldMusic; Math::Vector m_eye; Math::Vector m_lookat; }; diff --git a/src/sound/sound.cpp b/src/sound/sound.cpp index d197b81..1605e2b 100644 --- a/src/sound/sound.cpp +++ b/src/sound/sound.cpp @@ -147,12 +147,12 @@ bool CSoundInterface::MuteAll(bool bMute) return true; } -bool CSoundInterface::PlayMusic(int rank, bool bRepeat) +bool CSoundInterface::PlayMusic(int rank, bool bRepeat, float fadeTime) { return true; } -bool CSoundInterface::PlayMusic(const std::string &filename, bool bRepeat) +bool CSoundInterface::PlayMusic(const std::string &filename, bool bRepeat, float fadeTime) { return true; } @@ -166,7 +166,7 @@ void CSoundInterface::SuspendMusic() { } -void CSoundInterface::StopMusic() +void CSoundInterface::StopMusic(float fadeTime) { } diff --git a/src/sound/sound.h b/src/sound/sound.h index eee0b82..d2eee9c 100644 --- a/src/sound/sound.h +++ b/src/sound/sound.h @@ -284,16 +284,18 @@ public: /** Start playing music * \param rank - track number * \param bRepeat - repeat playing + * \param fadeTime - time of transition between music * \return return true on success */ - virtual bool PlayMusic(int rank, bool bRepeat); + virtual bool PlayMusic(int rank, bool bRepeat, float fadeTime=5.0f); /** Start playing music * \param filename - name of file to play * \param bRepeat - repeat playing + * \param fadeTime - time of transition between music * \return return true on success */ - virtual bool PlayMusic(const std::string &filename, bool bRepeat); + virtual bool PlayMusic(const std::string &filename, bool bRepeat, float fadeTime=5.0f); /** Restart music * @return return true on success @@ -308,7 +310,7 @@ public: /** Stop playing music * \return return true on success */ - virtual void StopMusic(); + virtual void StopMusic(float fadeTime=5.0f); /** Check if music if playing * \return return true if music is playing -- cgit v1.2.3-1-g7c22