Store sound buffer references by index instead of string

openmw-38
Chris Robinson 9 years ago
parent f7218f5a25
commit 24f8c78fca

@ -169,32 +169,45 @@ namespace MWSound
mVFS->normalizeFilename(sfx->mResourceName); mVFS->normalizeFilename(sfx->mResourceName);
} }
// Lookup a soundid for its sound data (resource name, local volume, size_t SoundManager::lookupId(const std::string &soundId)
// minRange and maxRange).
Sound_Buffer *SoundManager::lookup(const std::string &soundId)
{ {
Sound_Buffer *sfx;
BufferKeyList::iterator bufkey = std::lower_bound(mBufferKeys.begin(), mBufferKeys.end(), soundId); BufferKeyList::iterator bufkey = std::lower_bound(mBufferKeys.begin(), mBufferKeys.end(), soundId);
if(bufkey == mBufferKeys.end() || *bufkey != soundId) if(bufkey != mBufferKeys.end() && *bufkey == soundId)
return std::distance(mBufferKeys.begin(), bufkey);
if(mBufferKeys.empty())
{ {
if(mBufferKeys.empty()) MWBase::World *world = MWBase::Environment::get().getWorld();
{ MWWorld::Store<ESM::Sound>::iterator iter = world->getStore().get<ESM::Sound>().begin();
MWBase::World *world = MWBase::Environment::get().getWorld(); MWWorld::Store<ESM::Sound>::iterator end = world->getStore().get<ESM::Sound>().end();
MWWorld::Store<ESM::Sound>::iterator iter = world->getStore().get<ESM::Sound>().begin(); size_t storesize = world->getStore().get<ESM::Sound>().getSize();
MWWorld::Store<ESM::Sound>::iterator end = world->getStore().get<ESM::Sound>().end(); mBufferKeys.reserve(storesize);
size_t storesize = world->getStore().get<ESM::Sound>().getSize(); mSoundBuffers.reserve(storesize);
mBufferKeys.reserve(storesize); for(;iter != end;++iter)
mSoundBuffers.reserve(storesize); insertSound(Misc::StringUtils::lowerCase(iter->mId), &*iter);
for(;iter != end;++iter)
insertSound(Misc::StringUtils::lowerCase(iter->mId), &*iter); bufkey = std::lower_bound(mBufferKeys.begin(), mBufferKeys.end(), soundId);
if(bufkey != mBufferKeys.end() && *bufkey == soundId)
bufkey = std::lower_bound(mBufferKeys.begin(), mBufferKeys.end(), soundId); return std::distance(mBufferKeys.begin(), bufkey);
}
if(bufkey == mBufferKeys.end() || *bufkey != soundId)
throw std::runtime_error("Sound "+soundId+" not found");
} }
sfx = &mSoundBuffers[std::distance(mBufferKeys.begin(), bufkey)]; throw std::runtime_error("Sound "+soundId+" not found");
}
size_t SoundManager::lookupId(const std::string& soundId) const
{
BufferKeyList::const_iterator bufkey = std::lower_bound(mBufferKeys.begin(), mBufferKeys.end(), soundId);
if(bufkey != mBufferKeys.end() && *bufkey == soundId)
return std::distance(mBufferKeys.begin(), bufkey);
throw std::runtime_error("Sound "+soundId+" not found");
}
// Lookup a sfxid for its sound data (resource name, local volume,
// minRange, and maxRange).
Sound_Buffer *SoundManager::lookup(size_t sfxid)
{
Sound_Buffer *sfx = &mSoundBuffers[sfxid];
if(!sfx->mHandle) if(!sfx->mHandle)
{ {
@ -210,18 +223,24 @@ namespace MWSound
break; break;
} }
SoundSet::iterator iter = mUnusedBuffers.begin(); SoundSet::iterator iter = mUnusedBuffers.begin();
bufkey = std::lower_bound(mBufferKeys.begin(), mBufferKeys.end(), *iter); Sound_Buffer *unused = &mSoundBuffers[*iter];
Sound_Buffer *unused = &mSoundBuffers[std::distance(mBufferKeys.begin(), bufkey)];
mBufferCacheSize -= mOutput->getSoundDataSize(unused->mHandle); mBufferCacheSize -= mOutput->getSoundDataSize(unused->mHandle);
mOutput->unloadSound(unused->mHandle); mOutput->unloadSound(unused->mHandle);
mUnusedBuffers.erase(iter); mUnusedBuffers.erase(iter);
} }
mUnusedBuffers.insert(soundId); mUnusedBuffers.insert(sfxid);
} }
return sfx; return sfx;
} }
// Lookup a soundid for its sound data (resource name, local volume,
// minRange, and maxRange).
Sound_Buffer *SoundManager::lookup(const std::string &soundId)
{
return lookup(lookupId(soundId));
}
void SoundManager::loadVoice(const std::string &voicefile) void SoundManager::loadVoice(const std::string &voicefile)
{ {
NameLoudnessMap::iterator lipiter = mVoiceLipBuffers.find(voicefile); NameLoudnessMap::iterator lipiter = mVoiceLipBuffers.find(voicefile);
@ -491,16 +510,16 @@ namespace MWSound
return sound; return sound;
try try
{ {
std::string soundid = Misc::StringUtils::lowerCase(soundId); size_t sfxid = lookupId(Misc::StringUtils::lowerCase(soundId));
Sound_Buffer *sfx = lookup(soundid); Sound_Buffer *sfx = lookup(sfxid);
float basevol = volumeFromType(type); float basevol = volumeFromType(type);
sound = mOutput->playSound(sfx->mHandle, sound = mOutput->playSound(sfx->mHandle,
volume * sfx->mVolume, basevol, pitch, mode|type, offset volume * sfx->mVolume, basevol, pitch, mode|type, offset
); );
if(sfx->mReferences++ == 0) if(sfx->mReferences++ == 0)
mUnusedBuffers.erase(soundid); mUnusedBuffers.erase(sfxid);
mActiveSounds[MWWorld::Ptr()].push_back(std::make_pair(sound, soundid)); mActiveSounds[MWWorld::Ptr()].push_back(std::make_pair(sound, sfxid));
} }
catch(std::exception&) catch(std::exception&)
{ {
@ -518,8 +537,8 @@ namespace MWSound
try try
{ {
// Look up the sound in the ESM data // Look up the sound in the ESM data
std::string soundid = Misc::StringUtils::lowerCase(soundId); size_t sfxid = lookupId(Misc::StringUtils::lowerCase(soundId));
Sound_Buffer *sfx = lookup(soundid); Sound_Buffer *sfx = lookup(sfxid);
float basevol = volumeFromType(type); float basevol = volumeFromType(type);
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());
@ -531,11 +550,11 @@ namespace MWSound
objpos, volume * sfx->mVolume, basevol, pitch, sfx->mMinDist, sfx->mMaxDist, mode|type, offset objpos, volume * sfx->mVolume, basevol, pitch, sfx->mMinDist, sfx->mMaxDist, mode|type, offset
); );
if(sfx->mReferences++ == 0) if(sfx->mReferences++ == 0)
mUnusedBuffers.erase(soundid); mUnusedBuffers.erase(sfxid);
if((mode&Play_NoTrack)) if((mode&Play_NoTrack))
mActiveSounds[MWWorld::Ptr()].push_back(std::make_pair(sound, soundid)); mActiveSounds[MWWorld::Ptr()].push_back(std::make_pair(sound, sfxid));
else else
mActiveSounds[ptr].push_back(std::make_pair(sound, soundid)); mActiveSounds[ptr].push_back(std::make_pair(sound, sfxid));
} }
catch(std::exception&) catch(std::exception&)
{ {
@ -553,16 +572,16 @@ namespace MWSound
try try
{ {
// Look up the sound in the ESM data // Look up the sound in the ESM data
std::string soundid = Misc::StringUtils::lowerCase(soundId); size_t sfxid = lookupId(Misc::StringUtils::lowerCase(soundId));
Sound_Buffer *sfx = lookup(soundid); Sound_Buffer *sfx = lookup(sfxid);
float basevol = volumeFromType(type); float basevol = volumeFromType(type);
sound = mOutput->playSound3D(sfx->mHandle, sound = mOutput->playSound3D(sfx->mHandle,
initialPos, volume * sfx->mVolume, basevol, pitch, sfx->mMinDist, sfx->mMaxDist, mode|type, offset initialPos, volume * sfx->mVolume, basevol, pitch, sfx->mMinDist, sfx->mMaxDist, mode|type, offset
); );
if(sfx->mReferences++ == 0) if(sfx->mReferences++ == 0)
mUnusedBuffers.erase(soundid); mUnusedBuffers.erase(sfxid);
mActiveSounds[MWWorld::Ptr()].push_back(std::make_pair(sound, soundid)); mActiveSounds[MWWorld::Ptr()].push_back(std::make_pair(sound, sfxid));
} }
catch(std::exception &) catch(std::exception &)
{ {
@ -581,13 +600,13 @@ namespace MWSound
SoundMap::iterator snditer = mActiveSounds.find(ptr); SoundMap::iterator snditer = mActiveSounds.find(ptr);
if(snditer != mActiveSounds.end()) if(snditer != mActiveSounds.end())
{ {
std::string soundid = Misc::StringUtils::lowerCase(soundId); size_t sfxid = lookupId(Misc::StringUtils::lowerCase(soundId));
SoundNamePairList::iterator sndname = snditer->second.begin(); SoundIndexPairList::iterator sndidx = snditer->second.begin();
for(;sndname != snditer->second.end();++sndname) for(;sndidx != snditer->second.end();++sndidx)
{ {
if(sndname->second != soundid) if(sndidx->second != sfxid)
continue; continue;
sndname->first->stop(); sndidx->first->stop();
return; return;
} }
} }
@ -598,9 +617,9 @@ namespace MWSound
SoundMap::iterator snditer = mActiveSounds.find(ptr); SoundMap::iterator snditer = mActiveSounds.find(ptr);
if(snditer != mActiveSounds.end()) if(snditer != mActiveSounds.end())
{ {
SoundNamePairList::iterator sndname = snditer->second.begin(); SoundIndexPairList::iterator sndidx = snditer->second.begin();
for(;sndname != snditer->second.end();++sndname) for(;sndidx != snditer->second.end();++sndidx)
sndname->first->stop(); sndidx->first->stop();
} }
} }
@ -613,9 +632,9 @@ namespace MWSound
snditer->first != MWMechanics::getPlayer() && snditer->first != MWMechanics::getPlayer() &&
snditer->first.getCell() == cell) snditer->first.getCell() == cell)
{ {
SoundNamePairList::iterator sndname = snditer->second.begin(); SoundIndexPairList::iterator sndidx = snditer->second.begin();
for(;sndname != snditer->second.end();++sndname) for(;sndidx != snditer->second.end();++sndidx)
sndname->first->stop(); sndidx->first->stop();
} }
++snditer; ++snditer;
} }
@ -637,14 +656,12 @@ namespace MWSound
SoundMap::iterator snditer = mActiveSounds.find(MWWorld::Ptr()); SoundMap::iterator snditer = mActiveSounds.find(MWWorld::Ptr());
if(snditer != mActiveSounds.end()) if(snditer != mActiveSounds.end())
{ {
std::string soundid = Misc::StringUtils::lowerCase(soundId); size_t sfxid = lookupId(Misc::StringUtils::lowerCase(soundId));
SoundNamePairList::iterator sndname = snditer->second.begin(); SoundIndexPairList::iterator sndidx = snditer->second.begin();
for(;sndname != snditer->second.end();++sndname) for(;sndidx != snditer->second.end();++sndidx)
{ {
if(sndname->second != soundid) if(sndidx->second == sfxid)
continue; sndidx->first->stop();
sndname->first->stop();
return;
} }
} }
} }
@ -655,12 +672,12 @@ namespace MWSound
SoundMap::iterator snditer = mActiveSounds.find(ptr); SoundMap::iterator snditer = mActiveSounds.find(ptr);
if(snditer != mActiveSounds.end()) if(snditer != mActiveSounds.end())
{ {
std::string soundid = Misc::StringUtils::lowerCase(soundId); size_t sfxid = lookupId(Misc::StringUtils::lowerCase(soundId));
SoundNamePairList::iterator sndname = snditer->second.begin(); SoundIndexPairList::iterator sndidx = snditer->second.begin();
for(;sndname != snditer->second.end();++sndname) for(;sndidx != snditer->second.end();++sndidx)
{ {
if(sndname->second == soundid) if(sndidx->second == sfxid)
sndname->first->setFadeout(duration); sndidx->first->setFadeout(duration);
} }
} }
} }
@ -670,11 +687,11 @@ namespace MWSound
SoundMap::const_iterator snditer = mActiveSounds.find(ptr); SoundMap::const_iterator snditer = mActiveSounds.find(ptr);
if(snditer != mActiveSounds.end()) if(snditer != mActiveSounds.end())
{ {
std::string soundid = Misc::StringUtils::lowerCase(soundId); size_t sfxid = lookupId(Misc::StringUtils::lowerCase(soundId));
SoundNamePairList::const_iterator sndname = snditer->second.begin(); SoundIndexPairList::const_iterator sndidx = snditer->second.begin();
for(;sndname != snditer->second.end();++sndname) for(;sndidx != snditer->second.end();++sndidx)
{ {
if(sndname->second == soundid && sndname->first->isPlaying()) if(sndidx->second == sfxid && sndidx->first->isPlaying())
return true; return true;
} }
} }
@ -804,20 +821,18 @@ namespace MWSound
SoundMap::iterator snditer = mActiveSounds.begin(); SoundMap::iterator snditer = mActiveSounds.begin();
while(snditer != mActiveSounds.end()) while(snditer != mActiveSounds.end())
{ {
SoundNamePairList::iterator sndname = snditer->second.begin(); SoundIndexPairList::iterator sndidx = snditer->second.begin();
while(sndname != snditer->second.end()) while(sndidx != snditer->second.end())
{ {
if(!updateSound(sndname->first, snditer->first, duration)) if(!updateSound(sndidx->first, snditer->first, duration))
{ {
BufferKeyList::iterator bufkey = std::lower_bound(mBufferKeys.begin(), mBufferKeys.end(), Sound_Buffer *sfx = &mSoundBuffers[sndidx->second];
sndname->second);
Sound_Buffer *sfx = &mSoundBuffers[std::distance(mBufferKeys.begin(), bufkey)];
if(sfx->mReferences-- == 1) if(sfx->mReferences-- == 1)
mUnusedBuffers.insert(sndname->second); mUnusedBuffers.insert(sndidx->second);
sndname = snditer->second.erase(sndname); sndidx = snditer->second.erase(sndidx);
} }
else else
++sndname; ++sndidx;
} }
if(snditer->second.empty()) if(snditer->second.empty())
mActiveSounds.erase(snditer++); mActiveSounds.erase(snditer++);
@ -893,10 +908,10 @@ namespace MWSound
SoundMap::iterator snditer = mActiveSounds.begin(); SoundMap::iterator snditer = mActiveSounds.begin();
for(;snditer != mActiveSounds.end();++snditer) for(;snditer != mActiveSounds.end();++snditer)
{ {
SoundNamePairList::iterator sndname = snditer->second.begin(); SoundIndexPairList::iterator sndidx = snditer->second.begin();
for(;sndname != snditer->second.end();++sndname) for(;sndidx != snditer->second.end();++sndidx)
{ {
MWBase::SoundPtr sound = sndname->first; MWBase::SoundPtr sound = sndidx->first;
sound->mBaseVolume = volumeFromType(sound->getPlayType()); sound->mBaseVolume = volumeFromType(sound->getPlayType());
sound->update(); sound->update();
} }
@ -932,7 +947,7 @@ namespace MWSound
SoundMap::iterator snditer = mActiveSounds.find(old); SoundMap::iterator snditer = mActiveSounds.find(old);
if(snditer != mActiveSounds.end()) if(snditer != mActiveSounds.end())
{ {
SoundNamePairList sndlist = snditer->second; SoundIndexPairList sndlist = snditer->second;
mActiveSounds.erase(snditer); mActiveSounds.erase(snditer);
mActiveSounds[updated] = sndlist; mActiveSounds[updated] = sndlist;
} }
@ -1015,15 +1030,13 @@ namespace MWSound
SoundMap::iterator snditer = mActiveSounds.begin(); SoundMap::iterator snditer = mActiveSounds.begin();
for(;snditer != mActiveSounds.end();++snditer) for(;snditer != mActiveSounds.end();++snditer)
{ {
SoundNamePairList::iterator sndname = snditer->second.begin(); SoundIndexPairList::iterator sndidx = snditer->second.begin();
for(;sndname != snditer->second.end();++sndname) for(;sndidx != snditer->second.end();++sndidx)
{ {
sndname->first->stop(); sndidx->first->stop();
BufferKeyList::iterator bufkey = std::lower_bound(mBufferKeys.begin(), mBufferKeys.end(), Sound_Buffer *sfx = &mSoundBuffers[sndidx->second];
sndname->second);
Sound_Buffer *sfx = &mSoundBuffers[std::distance(mBufferKeys.begin(), bufkey)];
if(sfx->mReferences-- == 1) if(sfx->mReferences-- == 1)
mUnusedBuffers.insert(sndname->second); mUnusedBuffers.insert(sndidx->second);
} }
} }
mActiveSounds.clear(); mActiveSounds.clear();

@ -62,17 +62,18 @@ namespace MWSound
typedef std::map<std::string,Sound_Loudness> NameLoudnessMap; typedef std::map<std::string,Sound_Loudness> NameLoudnessMap;
NameLoudnessMap mVoiceLipBuffers; NameLoudnessMap mVoiceLipBuffers;
typedef std::set<std::string> SoundSet; typedef std::set<size_t> SoundSet;
SoundSet mUnusedBuffers; SoundSet mUnusedBuffers;
boost::shared_ptr<Sound> mMusic; boost::shared_ptr<Sound> mMusic;
std::string mCurrentPlaylist; std::string mCurrentPlaylist;
typedef std::pair<MWBase::SoundPtr,std::string> SoundNamePair; typedef std::pair<MWBase::SoundPtr,size_t> SoundIndexPair;
typedef std::vector<SoundNamePair> SoundNamePairList; typedef std::vector<SoundIndexPair> SoundIndexPairList;
typedef std::map<MWWorld::Ptr,SoundNamePairList> SoundMap; typedef std::map<MWWorld::Ptr,SoundIndexPairList> SoundMap;
SoundMap mActiveSounds; SoundMap mActiveSounds;
typedef std::pair<MWBase::SoundPtr,std::string> SoundNamePair;
typedef std::map<MWWorld::Ptr,SoundNamePair> SaySoundMap; typedef std::map<MWWorld::Ptr,SoundNamePair> SaySoundMap;
SaySoundMap mActiveSaySounds; SaySoundMap mActiveSaySounds;
@ -87,7 +88,11 @@ namespace MWSound
void insertSound(const std::string &soundId, const ESM::Sound *sound); void insertSound(const std::string &soundId, const ESM::Sound *sound);
size_t lookupId(const std::string &soundId);
size_t lookupId(const std::string &soundId) const;
Sound_Buffer *lookup(size_t sfxid);
Sound_Buffer *lookup(const std::string &soundId); Sound_Buffer *lookup(const std::string &soundId);
// Ensure the loudness/"lip" data is loaded // Ensure the loudness/"lip" data is loaded
void loadVoice(const std::string &voicefile); void loadVoice(const std::string &voicefile);

Loading…
Cancel
Save