1
0
mirror of https://gitlab.com/OpenMW/openmw.git synced 2025-02-21 09:39:56 +00:00

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.
This commit is contained in:
Chris Robinson 2015-11-27 01:58:13 -08:00
parent 5f8a09df97
commit 21bb2e9314
2 changed files with 35 additions and 23 deletions

View File

@ -212,7 +212,7 @@ namespace MWSound
return sfx; return sfx;
} }
DecoderPtr SoundManager::loadVoice(const std::string &voicefile) DecoderPtr SoundManager::loadVoice(const std::string &voicefile, Sound_Loudness **lipdata)
{ {
DecoderPtr decoder = getDecoder(); DecoderPtr decoder = getDecoder();
// Workaround: Bethesda at some point converted some of the files to mp3, but the references were kept as .wav. // 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); decoder->open(file);
} }
NameLoudnessMap::iterator lipiter = mVoiceLipBuffers.find(voicefile); NameLoudnessRefMap::iterator lipiter = mVoiceLipNameMap.find(voicefile);
if(lipiter != mVoiceLipBuffers.end()) return decoder; if(lipiter != mVoiceLipNameMap.end())
{
*lipdata = lipiter->second;
return decoder;
}
ChannelConfig chans; ChannelConfig chans;
SampleType type; SampleType type;
@ -241,9 +245,13 @@ namespace MWSound
Sound_Loudness loudness; Sound_Loudness loudness;
loudness.analyzeLoudness(data, srate, chans, type, static_cast<float>(sLoudnessFPS)); loudness.analyzeLoudness(data, srate, chans, type, static_cast<float>(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(); decoder->rewind();
*lipdata = lipiter->second;
return decoder; return decoder;
} }
@ -375,17 +383,19 @@ namespace MWSound
static float minDistance = std::max(fAudioVoiceDefaultMinDistance * fAudioMinDistanceMult, 1.0f); static float minDistance = std::max(fAudioVoiceDefaultMinDistance * fAudioMinDistanceMult, 1.0f);
static float maxDistance = std::max(fAudioVoiceDefaultMaxDistance * fAudioMaxDistanceMult, minDistance); 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); float basevol = volumeFromType(Play_TypeVoice);
const ESM::Position &pos = ptr.getRefData().getPosition(); const ESM::Position &pos = ptr.getRefData().getPosition();
const osg::Vec3f objpos(pos.asVec3()); 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, MWBase::SoundPtr sound = mOutput->streamSound3D(decoder,
objpos, 1.0f, basevol, 1.0f, minDistance, maxDistance, Play_Normal|Play_TypeVoice 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) catch(std::exception &e)
{ {
@ -399,13 +409,10 @@ namespace MWSound
if(snditer != mActiveSaySounds.end()) if(snditer != mActiveSaySounds.end())
{ {
MWBase::SoundPtr sound = snditer->second.first; MWBase::SoundPtr sound = snditer->second.first;
NameLoudnessMap::const_iterator lipiter = mVoiceLipBuffers.find(snditer->second.second); Sound_Loudness *loudness = snditer->second.second;
if(lipiter != mVoiceLipBuffers.end()) float sec = sound->getTimeOffset();
{ if(sound->isPlaying())
float sec = sound->getTimeOffset(); return loudness->getLoudnessAtTime(sec);
if(sound->isPlaying())
return lipiter->second.getLoudnessAtTime(sec);
}
} }
return 0.0f; return 0.0f;
@ -417,15 +424,17 @@ namespace MWSound
return; return;
try try
{ {
std::string voicefile = "sound/"+Misc::StringUtils::lowerCase(filename); std::string voicefile = "Sound/"+filename;
float basevol = volumeFromType(Play_TypeVoice); 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, MWBase::SoundPtr sound = mOutput->streamSound(decoder,
basevol, 1.0f, Play_Normal|Play_TypeVoice 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) catch(std::exception &e)
{ {
@ -927,7 +936,7 @@ namespace MWSound
SaySoundMap::iterator sayiter = mActiveSaySounds.find(old); SaySoundMap::iterator sayiter = mActiveSaySounds.find(old);
if(sayiter != mActiveSaySounds.end()) if(sayiter != mActiveSaySounds.end())
{ {
SoundNamePair sndlist = sayiter->second; SoundLoudnessPair sndlist = sayiter->second;
mActiveSaySounds.erase(sayiter); mActiveSaySounds.erase(sayiter);
mActiveSaySounds[updated] = sndlist; mActiveSaySounds[updated] = sndlist;
} }

View File

@ -68,8 +68,11 @@ namespace MWSound
typedef std::map<std::string,Sound_Buffer*> NameBufferMap; typedef std::map<std::string,Sound_Buffer*> NameBufferMap;
NameBufferMap mBufferNameMap; NameBufferMap mBufferNameMap;
typedef std::map<std::string,Sound_Loudness> NameLoudnessMap; typedef std::deque<Sound_Loudness> LoudnessList;
NameLoudnessMap mVoiceLipBuffers; LoudnessList mVoiceLipBuffers;
typedef std::map<std::string,Sound_Loudness*> NameLoudnessRefMap;
NameLoudnessRefMap mVoiceLipNameMap;
// NOTE: unused buffers are stored in front-newest order. // NOTE: unused buffers are stored in front-newest order.
typedef std::deque<Sound_Buffer*> SoundList; typedef std::deque<Sound_Buffer*> SoundList;
@ -83,8 +86,8 @@ namespace MWSound
typedef std::map<MWWorld::Ptr,SoundBufferRefPairList> SoundMap; typedef std::map<MWWorld::Ptr,SoundBufferRefPairList> SoundMap;
SoundMap mActiveSounds; SoundMap mActiveSounds;
typedef std::pair<MWBase::SoundPtr,std::string> SoundNamePair; typedef std::pair<MWBase::SoundPtr,Sound_Loudness*> SoundLoudnessPair;
typedef std::map<MWWorld::Ptr,SoundNamePair> SaySoundMap; typedef std::map<MWWorld::Ptr,SoundLoudnessPair> SaySoundMap;
SaySoundMap mActiveSaySounds; SaySoundMap mActiveSaySounds;
MWBase::SoundPtr mUnderwaterSound; MWBase::SoundPtr mUnderwaterSound;
@ -103,7 +106,7 @@ namespace MWSound
// Ensures the loudness/"lip" data is loaded, and returns a decoder to // Ensures the loudness/"lip" data is loaded, and returns a decoder to
// start streaming // start streaming
DecoderPtr loadVoice(const std::string &voicefile); DecoderPtr loadVoice(const std::string &voicefile, Sound_Loudness **lipdata);
void streamMusicFull(const std::string& filename); void streamMusicFull(const std::string& filename);
bool updateSound(MWBase::SoundPtr sound, const MWWorld::Ptr &ptr, float duration); bool updateSound(MWBase::SoundPtr sound, const MWWorld::Ptr &ptr, float duration);