diff --git a/apps/openmw/mwsound/openal_output.cpp b/apps/openmw/mwsound/openal_output.cpp index b71fe4d80..381c5ba18 100644 --- a/apps/openmw/mwsound/openal_output.cpp +++ b/apps/openmw/mwsound/openal_output.cpp @@ -816,7 +816,7 @@ void OpenAL_Output::unloadSound(Sound_Handle data) MWBase::SoundPtr OpenAL_Output::playSound(Sound_Handle data, float vol, float basevol, float pitch, int flags,float offset) { boost::shared_ptr sound; - ALuint src=0; + ALuint src; if(mFreeSources.empty()) fail("No free sources"); @@ -851,7 +851,7 @@ MWBase::SoundPtr OpenAL_Output::playSound3D(Sound_Handle data, const osg::Vec3f float min, float max, int flags, float offset) { boost::shared_ptr sound; - ALuint src=0; + ALuint src; if(mFreeSources.empty()) fail("No free sources"); diff --git a/apps/openmw/mwsound/soundmanagerimp.cpp b/apps/openmw/mwsound/soundmanagerimp.cpp index 820a9841d..6e95c1116 100644 --- a/apps/openmw/mwsound/soundmanagerimp.cpp +++ b/apps/openmw/mwsound/soundmanagerimp.cpp @@ -101,6 +101,13 @@ namespace MWSound mOutput->unloadSound(sfxiter->second.mHandle); sfxiter->second.mHandle = 0; } + sfxiter = mVoiceSoundBuffers.begin(); + for(;sfxiter != mVoiceSoundBuffers.end();++sfxiter) + { + if(sfxiter->second.mHandle) + mOutput->unloadSound(sfxiter->second.mHandle); + sfxiter->second.mHandle = 0; + } } mUnderwaterSound.reset(); mActiveSounds.clear(); @@ -162,6 +169,35 @@ namespace MWSound return &sfxiter->second; } + const Sound_Buffer *SoundManager::lookupVoice(const std::string &voicefile) + { + NameBufferMap::iterator sfxiter = mVoiceSoundBuffers.find(voicefile); + if(sfxiter == mVoiceSoundBuffers.end()) + { + MWBase::World* world = MWBase::Environment::get().getWorld(); + static const float fAudioMinDistanceMult = world->getStore().get().find("fAudioMinDistanceMult")->getFloat(); + static const float fAudioMaxDistanceMult = world->getStore().get().find("fAudioMaxDistanceMult")->getFloat(); + static const float fAudioVoiceDefaultMinDistance = world->getStore().get().find("fAudioVoiceDefaultMinDistance")->getFloat(); + static const float fAudioVoiceDefaultMaxDistance = world->getStore().get().find("fAudioVoiceDefaultMaxDistance")->getFloat(); + + float minDistance = fAudioVoiceDefaultMinDistance * fAudioMinDistanceMult; + float maxDistance = fAudioVoiceDefaultMaxDistance * fAudioMaxDistanceMult; + minDistance = std::max(minDistance, 1.f); + maxDistance = std::max(minDistance, maxDistance); + + sfxiter = mVoiceSoundBuffers.insert(std::make_pair( + voicefile, Sound_Buffer("sound/"+voicefile, 1.0f, minDistance, maxDistance) + )).first; + mVFS->normalizeFilename(sfxiter->second.mResourceName); + sfxiter->second.mHandle = mOutput->loadSound(sfxiter->second.mResourceName); + } + else if(!sfxiter->second.mHandle) + sfxiter->second.mHandle = mOutput->loadSound(sfxiter->second.mResourceName); + + return &sfxiter->second; + } + + // Gets the combined volume settings for the given sound type float SoundManager::volumeFromType(PlayType type) const { @@ -286,35 +322,21 @@ namespace MWSound startRandomTitle(); } - void SoundManager::say(const MWWorld::Ptr &ptr, const std::string& filename) + void SoundManager::say(const MWWorld::Ptr &ptr, const std::string &filename) { if(!mOutput->isInitialized()) return; try { -#if 0 + const Sound_Buffer *sfx = lookupVoice(Misc::StringUtils::lowerCase(filename)); float basevol = volumeFromType(Play_TypeVoice); - std::string filePath = "sound/"+filename; const ESM::Position &pos = ptr.getRefData().getPosition(); const osg::Vec3f objpos(pos.asVec3()); - MWBase::World* world = MWBase::Environment::get().getWorld(); - static const float fAudioMinDistanceMult = world->getStore().get().find("fAudioMinDistanceMult")->getFloat(); - static const float fAudioMaxDistanceMult = world->getStore().get().find("fAudioMaxDistanceMult")->getFloat(); - static const float fAudioVoiceDefaultMinDistance = world->getStore().get().find("fAudioVoiceDefaultMinDistance")->getFloat(); - static const float fAudioVoiceDefaultMaxDistance = world->getStore().get().find("fAudioVoiceDefaultMaxDistance")->getFloat(); - - float minDistance = fAudioVoiceDefaultMinDistance * fAudioMinDistanceMult; - float maxDistance = fAudioVoiceDefaultMaxDistance * fAudioMaxDistanceMult; - minDistance = std::max(minDistance, 1.f); - maxDistance = std::max(minDistance, maxDistance); - - MWBase::SoundPtr sound = mOutput->playSound3D(filePath, objpos, 1.0f, basevol, 1.0f, - minDistance, maxDistance, Play_Normal|Play_TypeVoice, 0, true); + MWBase::SoundPtr sound = mOutput->playSound3D(sfx->mHandle, + objpos, sfx->mVolume, basevol, 1.0f, sfx->mMinDist, sfx->mMaxDist, Play_Normal|Play_TypeVoice, 0 + ); mActiveSounds[sound] = std::make_pair(ptr, std::string("_say_sound")); -#else - throw std::runtime_error("say disabled"); -#endif } catch(std::exception &e) { @@ -343,15 +365,13 @@ namespace MWSound return; try { -#if 0 + const Sound_Buffer *sfx = lookupVoice(Misc::StringUtils::lowerCase(filename)); float basevol = volumeFromType(Play_TypeVoice); - std::string filePath = "Sound/"+filename; - MWBase::SoundPtr sound = mOutput->playSound(filePath, 1.0f, basevol, 1.0f, Play_Normal|Play_TypeVoice, 0); + MWBase::SoundPtr sound = mOutput->playSound(sfx->mHandle, + sfx->mVolume, basevol, 1.0f, Play_Normal|Play_TypeVoice, 0 + ); mActiveSounds[sound] = std::make_pair(MWWorld::Ptr(), std::string("_say_sound")); -#else - throw std::runtime_error("say disabled"); -#endif } catch(std::exception &e) { diff --git a/apps/openmw/mwsound/soundmanagerimp.hpp b/apps/openmw/mwsound/soundmanagerimp.hpp index d9eb7ff3d..5d605a90f 100644 --- a/apps/openmw/mwsound/soundmanagerimp.hpp +++ b/apps/openmw/mwsound/soundmanagerimp.hpp @@ -46,6 +46,9 @@ namespace MWSound typedef std::map NameBufferMap; NameBufferMap mSoundBuffers; + // Should stream voices, but that requires handling the "lip" data + // separately from buffer loading. + NameBufferMap mVoiceSoundBuffers; boost::shared_ptr mMusic; std::string mCurrentPlaylist; @@ -64,6 +67,7 @@ namespace MWSound int mPausedSoundTypes; const Sound_Buffer *lookup(const std::string &soundId); + const Sound_Buffer *lookupVoice(const std::string &voicefile); void streamMusicFull(const std::string& filename); bool isPlaying(const MWWorld::Ptr &ptr, const std::string &id) const;