From 21bb2e9314c68f49ca4fae9ec51c29957540252b Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Fri, 27 Nov 2015 01:58:13 -0800 Subject: [PATCH] Use a deque for loudness buffers with a map lookup Similar to Sound_Buffer, this allows individual Sound_Loudness objects to retain a constant pointer when new ones are inserted on to the end. --- apps/openmw/mwsound/soundmanagerimp.cpp | 45 +++++++++++++++---------- apps/openmw/mwsound/soundmanagerimp.hpp | 13 ++++--- 2 files changed, 35 insertions(+), 23 deletions(-) diff --git a/apps/openmw/mwsound/soundmanagerimp.cpp b/apps/openmw/mwsound/soundmanagerimp.cpp index 5ae8243931..0cdaddfd25 100644 --- a/apps/openmw/mwsound/soundmanagerimp.cpp +++ b/apps/openmw/mwsound/soundmanagerimp.cpp @@ -212,7 +212,7 @@ namespace MWSound return sfx; } - DecoderPtr SoundManager::loadVoice(const std::string &voicefile) + DecoderPtr SoundManager::loadVoice(const std::string &voicefile, Sound_Loudness **lipdata) { DecoderPtr decoder = getDecoder(); // Workaround: Bethesda at some point converted some of the files to mp3, but the references were kept as .wav. @@ -227,8 +227,12 @@ namespace MWSound decoder->open(file); } - NameLoudnessMap::iterator lipiter = mVoiceLipBuffers.find(voicefile); - if(lipiter != mVoiceLipBuffers.end()) return decoder; + NameLoudnessRefMap::iterator lipiter = mVoiceLipNameMap.find(voicefile); + if(lipiter != mVoiceLipNameMap.end()) + { + *lipdata = lipiter->second; + return decoder; + } ChannelConfig chans; SampleType type; @@ -241,9 +245,13 @@ namespace MWSound Sound_Loudness loudness; loudness.analyzeLoudness(data, srate, chans, type, static_cast(sLoudnessFPS)); - mVoiceLipBuffers.insert(std::make_pair(voicefile, loudness)); + mVoiceLipBuffers.insert(mVoiceLipBuffers.end(), loudness); + lipiter = mVoiceLipNameMap.insert( + std::make_pair(voicefile, &mVoiceLipBuffers.back()) + ).first; decoder->rewind(); + *lipdata = lipiter->second; return decoder; } @@ -375,17 +383,19 @@ namespace MWSound static float minDistance = std::max(fAudioVoiceDefaultMinDistance * fAudioMinDistanceMult, 1.0f); static float maxDistance = std::max(fAudioVoiceDefaultMaxDistance * fAudioMaxDistanceMult, minDistance); - std::string voicefile = "sound/"+Misc::StringUtils::lowerCase(filename); + std::string voicefile = "Sound/"+filename; float basevol = volumeFromType(Play_TypeVoice); const ESM::Position &pos = ptr.getRefData().getPosition(); const osg::Vec3f objpos(pos.asVec3()); - DecoderPtr decoder = loadVoice(voicefile); + Sound_Loudness *loudness; + mVFS->normalizeFilename(voicefile); + DecoderPtr decoder = loadVoice(voicefile, &loudness); MWBase::SoundPtr sound = mOutput->streamSound3D(decoder, objpos, 1.0f, basevol, 1.0f, minDistance, maxDistance, Play_Normal|Play_TypeVoice ); - mActiveSaySounds[ptr] = std::make_pair(sound, voicefile); + mActiveSaySounds[ptr] = std::make_pair(sound, loudness); } catch(std::exception &e) { @@ -399,13 +409,10 @@ namespace MWSound if(snditer != mActiveSaySounds.end()) { MWBase::SoundPtr sound = snditer->second.first; - NameLoudnessMap::const_iterator lipiter = mVoiceLipBuffers.find(snditer->second.second); - if(lipiter != mVoiceLipBuffers.end()) - { - float sec = sound->getTimeOffset(); - if(sound->isPlaying()) - return lipiter->second.getLoudnessAtTime(sec); - } + Sound_Loudness *loudness = snditer->second.second; + float sec = sound->getTimeOffset(); + if(sound->isPlaying()) + return loudness->getLoudnessAtTime(sec); } return 0.0f; @@ -417,15 +424,17 @@ namespace MWSound return; try { - std::string voicefile = "sound/"+Misc::StringUtils::lowerCase(filename); + std::string voicefile = "Sound/"+filename; float basevol = volumeFromType(Play_TypeVoice); - DecoderPtr decoder = loadVoice(voicefile); + Sound_Loudness *loudness; + mVFS->normalizeFilename(voicefile); + DecoderPtr decoder = loadVoice(voicefile, &loudness); MWBase::SoundPtr sound = mOutput->streamSound(decoder, basevol, 1.0f, Play_Normal|Play_TypeVoice ); - mActiveSaySounds[MWWorld::Ptr()] = std::make_pair(sound, voicefile); + mActiveSaySounds[MWWorld::Ptr()] = std::make_pair(sound, loudness); } catch(std::exception &e) { @@ -927,7 +936,7 @@ namespace MWSound SaySoundMap::iterator sayiter = mActiveSaySounds.find(old); if(sayiter != mActiveSaySounds.end()) { - SoundNamePair sndlist = sayiter->second; + SoundLoudnessPair sndlist = sayiter->second; mActiveSaySounds.erase(sayiter); mActiveSaySounds[updated] = sndlist; } diff --git a/apps/openmw/mwsound/soundmanagerimp.hpp b/apps/openmw/mwsound/soundmanagerimp.hpp index fa855646d6..e12fe16fc4 100644 --- a/apps/openmw/mwsound/soundmanagerimp.hpp +++ b/apps/openmw/mwsound/soundmanagerimp.hpp @@ -68,8 +68,11 @@ namespace MWSound typedef std::map NameBufferMap; NameBufferMap mBufferNameMap; - typedef std::map NameLoudnessMap; - NameLoudnessMap mVoiceLipBuffers; + typedef std::deque LoudnessList; + LoudnessList mVoiceLipBuffers; + + typedef std::map NameLoudnessRefMap; + NameLoudnessRefMap mVoiceLipNameMap; // NOTE: unused buffers are stored in front-newest order. typedef std::deque SoundList; @@ -83,8 +86,8 @@ namespace MWSound typedef std::map SoundMap; SoundMap mActiveSounds; - typedef std::pair SoundNamePair; - typedef std::map SaySoundMap; + typedef std::pair SoundLoudnessPair; + typedef std::map SaySoundMap; SaySoundMap mActiveSaySounds; MWBase::SoundPtr mUnderwaterSound; @@ -103,7 +106,7 @@ namespace MWSound // Ensures the loudness/"lip" data is loaded, and returns a decoder to // start streaming - DecoderPtr loadVoice(const std::string &voicefile); + DecoderPtr loadVoice(const std::string &voicefile, Sound_Loudness **lipdata); void streamMusicFull(const std::string& filename); bool updateSound(MWBase::SoundPtr sound, const MWWorld::Ptr &ptr, float duration);