mirror of
https://github.com/TES3MP/openmw-tes3mp.git
synced 2025-01-19 23:23:52 +00:00
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.
This commit is contained in:
parent
6c3953766e
commit
f9e18cd966
2 changed files with 74 additions and 45 deletions
|
@ -118,62 +118,84 @@ namespace MWSound
|
||||||
return DecoderPtr(new DEFAULT_DECODER (mVFS));
|
return DecoderPtr(new DEFAULT_DECODER (mVFS));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SoundManager::insertSound(const std::string &soundId, const ESM::Sound *sound)
|
||||||
|
{
|
||||||
|
BufferKeyList::iterator bufkey = std::lower_bound(mBufferKeys.begin(), mBufferKeys.end(), soundId);
|
||||||
|
if(bufkey != mBufferKeys.end() && *bufkey == soundId)
|
||||||
|
{
|
||||||
|
std::cerr<< "Duplicate sound record \""<<soundId<<"\"" <<std::endl;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
min = fAudioDefaultMinDistance;
|
||||||
|
max = fAudioDefaultMaxDistance;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
min = sound->mData.mMinRange;
|
||||||
|
max = sound->mData.mMaxRange;
|
||||||
|
}
|
||||||
|
|
||||||
|
min *= fAudioMinDistanceMult;
|
||||||
|
max *= fAudioMaxDistanceMult;
|
||||||
|
min = std::max(min, 1.0f);
|
||||||
|
max = std::max(min, max);
|
||||||
|
|
||||||
|
Sound_Buffer *sfx;
|
||||||
|
bufkey = mBufferKeys.insert(bufkey, soundId);
|
||||||
|
try {
|
||||||
|
BufferKeyList::difference_type id;
|
||||||
|
id = std::distance(mBufferKeys.begin(), bufkey);
|
||||||
|
mSoundBuffers.insert(mSoundBuffers.begin()+id,
|
||||||
|
Sound_Buffer("Sound/"+sound->mSound, volume, min, max)
|
||||||
|
);
|
||||||
|
sfx = &mSoundBuffers[id];
|
||||||
|
}
|
||||||
|
catch(...) {
|
||||||
|
mBufferKeys.erase(bufkey);
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
|
||||||
|
mVFS->normalizeFilename(sfx->mResourceName);
|
||||||
|
}
|
||||||
|
|
||||||
// Lookup a soundid for its sound data (resource name, local volume,
|
// Lookup a soundid for its sound data (resource name, local volume,
|
||||||
// minRange and maxRange. The returned pointer is only valid temporarily.
|
// minRange and maxRange).
|
||||||
Sound_Buffer *SoundManager::lookup(const std::string &soundId)
|
Sound_Buffer *SoundManager::lookup(const std::string &soundId)
|
||||||
{
|
{
|
||||||
Sound_Buffer *sfx;
|
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
|
if(mBufferKeys.empty())
|
||||||
// to pre-fill a non-resizing list, which would allow subsystems to
|
|
||||||
// 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);
|
|
||||||
|
|
||||||
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)
|
|
||||||
{
|
{
|
||||||
static const float fAudioDefaultMinDistance = world->getStore().get<ESM::GameSetting>().find("fAudioDefaultMinDistance")->getFloat();
|
MWBase::World *world = MWBase::Environment::get().getWorld();
|
||||||
static const float fAudioDefaultMaxDistance = world->getStore().get<ESM::GameSetting>().find("fAudioDefaultMaxDistance")->getFloat();
|
MWWorld::Store<ESM::Sound>::iterator iter = world->getStore().get<ESM::Sound>().begin();
|
||||||
min = fAudioDefaultMinDistance;
|
MWWorld::Store<ESM::Sound>::iterator end = world->getStore().get<ESM::Sound>().end();
|
||||||
max = fAudioDefaultMaxDistance;
|
size_t storesize = world->getStore().get<ESM::Sound>().getSize();
|
||||||
}
|
mBufferKeys.reserve(storesize);
|
||||||
else
|
mSoundBuffers.reserve(storesize);
|
||||||
{
|
for(;iter != end;++iter)
|
||||||
min = snd->mData.mMinRange;
|
insertSound(Misc::StringUtils::lowerCase(iter->mId), &*iter);
|
||||||
max = snd->mData.mMaxRange;
|
|
||||||
}
|
|
||||||
|
|
||||||
static const float fAudioMinDistanceMult = world->getStore().get<ESM::GameSetting>().find("fAudioMinDistanceMult")->getFloat();
|
bufkey = std::lower_bound(mBufferKeys.begin(), mBufferKeys.end(), soundId);
|
||||||
static const float fAudioMaxDistanceMult = world->getStore().get<ESM::GameSetting>().find("fAudioMaxDistanceMult")->getFloat();
|
|
||||||
min *= fAudioMinDistanceMult;
|
|
||||||
max *= fAudioMaxDistanceMult;
|
|
||||||
min = std::max(min, 1.0f);
|
|
||||||
max = std::max(min, max);
|
|
||||||
|
|
||||||
bufkey = mBufferKeys.insert(bufkey, soundId);
|
|
||||||
try {
|
|
||||||
BufferKeyList::difference_type id;
|
|
||||||
id = std::distance(mBufferKeys.begin(), bufkey);
|
|
||||||
mSoundBuffers.insert(mSoundBuffers.begin()+id,
|
|
||||||
Sound_Buffer("Sound/"+snd->mSound, volume, min, max)
|
|
||||||
);
|
|
||||||
sfx = &mSoundBuffers[id];
|
|
||||||
}
|
}
|
||||||
catch(...) {
|
if(bufkey == mBufferKeys.end() || *bufkey != soundId)
|
||||||
mBufferKeys.erase(bufkey);
|
throw std::runtime_error("Sound "+soundId+" not found");
|
||||||
throw;
|
|
||||||
}
|
|
||||||
|
|
||||||
mVFS->normalizeFilename(sfx->mResourceName);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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…
Reference in a new issue