Prepare all Sound_Buffer objects when one is needed

This simply sets up the Sound record data to be used by the sound output. The
actual audio buffers, stored in the Sound_Handle, are still loaded on-demand.
openmw-38
Chris Robinson 9 years ago
parent 6c3953766e
commit f9e18cd966

@ -118,51 +118,46 @@ namespace MWSound
return DecoderPtr(new DEFAULT_DECODER (mVFS)); return DecoderPtr(new DEFAULT_DECODER (mVFS));
} }
// Lookup a soundid for its sound data (resource name, local volume, void SoundManager::insertSound(const std::string &soundId, const ESM::Sound *sound)
// minRange and maxRange. The returned pointer is only valid temporarily.
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)
sfx = &mSoundBuffers[std::distance(mBufferKeys.begin(), bufkey)];
else
{ {
// TODO: We could process all available ESM::Sound records on init std::cerr<< "Duplicate sound record \""<<soundId<<"\"" <<std::endl;
// to pre-fill a non-resizing list, which would allow subsystems to return;
// reference sounds by index instead of string. }
MWBase::World* world = MWBase::Environment::get().getWorld();
const ESM::Sound *snd = world->getStore().get<ESM::Sound>().find(soundId);
MWBase::World* world = MWBase::Environment::get().getWorld();
static const float fAudioDefaultMinDistance = world->getStore().get<ESM::GameSetting>().find("fAudioDefaultMinDistance")->getFloat();
static const float fAudioDefaultMaxDistance = world->getStore().get<ESM::GameSetting>().find("fAudioDefaultMaxDistance")->getFloat();
static const float fAudioMinDistanceMult = world->getStore().get<ESM::GameSetting>().find("fAudioMinDistanceMult")->getFloat();
static const float fAudioMaxDistanceMult = world->getStore().get<ESM::GameSetting>().find("fAudioMaxDistanceMult")->getFloat();
float volume, min, max; float volume, min, max;
volume = static_cast<float>(pow(10.0, (snd->mData.mVolume / 255.0*3348.0 - 3348.0) / 2000.0));
if(snd->mData.mMinRange == 0 && snd->mData.mMaxRange == 0) volume = static_cast<float>(pow(10.0, (sound->mData.mVolume / 255.0*3348.0 - 3348.0) / 2000.0));
if(sound->mData.mMinRange == 0 && sound->mData.mMaxRange == 0)
{ {
static const float fAudioDefaultMinDistance = world->getStore().get<ESM::GameSetting>().find("fAudioDefaultMinDistance")->getFloat();
static const float fAudioDefaultMaxDistance = world->getStore().get<ESM::GameSetting>().find("fAudioDefaultMaxDistance")->getFloat();
min = fAudioDefaultMinDistance; min = fAudioDefaultMinDistance;
max = fAudioDefaultMaxDistance; max = fAudioDefaultMaxDistance;
} }
else else
{ {
min = snd->mData.mMinRange; min = sound->mData.mMinRange;
max = snd->mData.mMaxRange; max = sound->mData.mMaxRange;
} }
static const float fAudioMinDistanceMult = world->getStore().get<ESM::GameSetting>().find("fAudioMinDistanceMult")->getFloat();
static const float fAudioMaxDistanceMult = world->getStore().get<ESM::GameSetting>().find("fAudioMaxDistanceMult")->getFloat();
min *= fAudioMinDistanceMult; min *= fAudioMinDistanceMult;
max *= fAudioMaxDistanceMult; max *= fAudioMaxDistanceMult;
min = std::max(min, 1.0f); min = std::max(min, 1.0f);
max = std::max(min, max); max = std::max(min, max);
Sound_Buffer *sfx;
bufkey = mBufferKeys.insert(bufkey, soundId); bufkey = mBufferKeys.insert(bufkey, soundId);
try { try {
BufferKeyList::difference_type id; BufferKeyList::difference_type id;
id = std::distance(mBufferKeys.begin(), bufkey); id = std::distance(mBufferKeys.begin(), bufkey);
mSoundBuffers.insert(mSoundBuffers.begin()+id, mSoundBuffers.insert(mSoundBuffers.begin()+id,
Sound_Buffer("Sound/"+snd->mSound, volume, min, max) Sound_Buffer("Sound/"+sound->mSound, volume, min, max)
); );
sfx = &mSoundBuffers[id]; sfx = &mSoundBuffers[id];
} }
@ -174,6 +169,33 @@ namespace MWSound
mVFS->normalizeFilename(sfx->mResourceName); mVFS->normalizeFilename(sfx->mResourceName);
} }
// Lookup a soundid for its sound data (resource name, local volume,
// 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);
if(bufkey == mBufferKeys.end() || *bufkey != soundId)
{
if(mBufferKeys.empty())
{
MWBase::World *world = MWBase::Environment::get().getWorld();
MWWorld::Store<ESM::Sound>::iterator iter = world->getStore().get<ESM::Sound>().begin();
MWWorld::Store<ESM::Sound>::iterator end = world->getStore().get<ESM::Sound>().end();
size_t storesize = world->getStore().get<ESM::Sound>().getSize();
mBufferKeys.reserve(storesize);
mSoundBuffers.reserve(storesize);
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)
throw std::runtime_error("Sound "+soundId+" not found");
}
sfx = &mSoundBuffers[std::distance(mBufferKeys.begin(), bufkey)];
if(!sfx->mHandle) if(!sfx->mHandle)
{ {
sfx->mHandle = mOutput->loadSound(sfx->mResourceName); sfx->mHandle = mOutput->loadSound(sfx->mResourceName);

@ -17,6 +17,11 @@ namespace VFS
class Manager; class Manager;
} }
namespace ESM
{
struct Sound;
}
namespace MWSound namespace MWSound
{ {
class Sound_Output; class Sound_Output;
@ -80,6 +85,8 @@ namespace MWSound
int mPausedSoundTypes; int mPausedSoundTypes;
void insertSound(const std::string &soundId, const ESM::Sound *sound);
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