diff --git a/apps/openmw/mwsound/soundmanagerimp.cpp b/apps/openmw/mwsound/soundmanagerimp.cpp index be7c68e64d..3f21487bcc 100644 --- a/apps/openmw/mwsound/soundmanagerimp.cpp +++ b/apps/openmw/mwsound/soundmanagerimp.cpp @@ -885,55 +885,74 @@ namespace MWSound playSound(*next, 1.0f, 1.0f); } - void SoundManager::updateWaterSound(float /*duration*/) + void SoundManager::updateWaterSound() { MWBase::World* world = MWBase::Environment::get().getWorld(); const MWWorld::ConstPtr player = world->getPlayerPtr(); const ESM::Cell *curcell = player.getCell()->getCell(); const auto update = mWaterSoundUpdater.update(player, *world); - if (mNearWaterSound) + WaterSoundAction action; + Sound_Buffer* sfx; + std::tie(action, sfx) = getWaterSoundAction(update, curcell); + + switch (action) { - if (update.mVolume == 0.0f) - { + case WaterSoundAction::DoNothing: + break; + case WaterSoundAction::SetVolume: + mNearWaterSound->setVolume(update.mVolume * sfx->mVolume); + break; + case WaterSoundAction::FinishSound: mOutput->finishSound(mNearWaterSound); mNearWaterSound = nullptr; - } - else - { - bool soundIdChanged = false; + break; + case WaterSoundAction::PlaySound: + if (mNearWaterSound) + mOutput->finishSound(mNearWaterSound); + mNearWaterSound = playSound(update.mId, update.mVolume, 1.0f, Type::Sfx, PlayMode::Loop); + break; + } - Sound_Buffer *sfx = lookupSound(update.mId); - if (mLastCell != curcell) - { - mLastCell = curcell; - SoundMap::const_iterator snditer = mActiveSounds.find(MWWorld::Ptr()); - if(snditer != mActiveSounds.end()) - { - SoundBufferRefPairList::const_iterator pairiter = std::find_if( - snditer->second.begin(), snditer->second.end(), - [this](const SoundBufferRefPairList::value_type &item) -> bool - { return mNearWaterSound == item.first; } - ); - if (pairiter != snditer->second.end() && pairiter->second != sfx) - soundIdChanged = true; - } - } + mLastCell = curcell; + } - if(soundIdChanged) + std::pair SoundManager::getWaterSoundAction( + const WaterSoundUpdate& update, const ESM::Cell* cell) const + { + if (mNearWaterSound) + { + if (update.mVolume == 0.0f) + return {WaterSoundAction::FinishSound, nullptr}; + + bool soundIdChanged = false; + + Sound_Buffer* sfx = lookupSound(update.mId); + if (mLastCell != cell) + { + const auto snditer = mActiveSounds.find(MWWorld::ConstPtr()); + if (snditer != mActiveSounds.end()) { - mOutput->finishSound(mNearWaterSound); - mNearWaterSound = playSound(update.mId, update.mVolume, 1.0f, Type::Sfx, PlayMode::Loop); + const auto pairiter = std::find_if( + snditer->second.begin(), snditer->second.end(), + [this](const SoundBufferRefPairList::value_type &item) -> bool + { return mNearWaterSound == item.first; } + ); + if (pairiter != snditer->second.end() && pairiter->second != sfx) + soundIdChanged = true; } - else if (sfx) - mNearWaterSound->setVolume(update.mVolume * sfx->mVolume); } + + if (soundIdChanged) + return {WaterSoundAction::PlaySound, nullptr}; + + if (sfx) + return {WaterSoundAction::SetVolume, sfx}; } else if (update.mVolume > 0.0f) - { - mLastCell = curcell; - mNearWaterSound = playSound(update.mId, update.mVolume, 1.0f, Type::Sfx, PlayMode::Loop); - } + return {WaterSoundAction::PlaySound, nullptr}; + + return {WaterSoundAction::DoNothing, nullptr}; } void SoundManager::updateSounds(float duration) @@ -1115,7 +1134,7 @@ namespace MWSound MWBase::StateManager::State_NoGame) { updateRegionSound(duration); - updateWaterSound(duration); + updateWaterSound(); } } diff --git a/apps/openmw/mwsound/soundmanagerimp.hpp b/apps/openmw/mwsound/soundmanagerimp.hpp index 85aa0a3864..90bf4b12c8 100644 --- a/apps/openmw/mwsound/soundmanagerimp.hpp +++ b/apps/openmw/mwsound/soundmanagerimp.hpp @@ -138,11 +138,22 @@ namespace MWSound void updateSounds(float duration); void updateRegionSound(float duration); - void updateWaterSound(float duration); + void updateWaterSound(); void updateMusic(float duration); float volumeFromType(Type type) const; + enum class WaterSoundAction + { + DoNothing, + SetVolume, + FinishSound, + PlaySound, + }; + + std::pair getWaterSoundAction(const WaterSoundUpdate& update, + const ESM::Cell* cell) const; + SoundManager(const SoundManager &rhs); SoundManager& operator=(const SoundManager &rhs);