Merge pull request #1455 from kcat/master

Print sound init info and preload sound buffer info
pull/292/head
scrawl 7 years ago committed by GitHub
commit 242d085da0

@ -192,12 +192,11 @@ static ALenum getALFormat(ChannelConfig chans, SampleType type)
{ AL_FORMAT_STEREO8, ChannelConfig_Stereo, SampleType_UInt8 },
}};
auto fmt = std::find_if(fmtlist.cbegin(), fmtlist.cend(),
[chans,type](const FormatEntry &fmt) -> bool
{ return fmt.chans == chans && fmt.type == type; }
);
if(fmt != fmtlist.cend())
return fmt->format;
for(auto &fmt : fmtlist)
{
if(fmt.chans == chans && fmt.type == type)
return fmt.format;
}
if(alIsExtensionPresent("AL_EXT_MCFORMATS"))
{
@ -209,18 +208,16 @@ static ALenum getALFormat(ChannelConfig chans, SampleType type)
{ "AL_FORMAT_71CHN16", ChannelConfig_7point1, SampleType_Int16 },
{ "AL_FORMAT_71CHN8", ChannelConfig_7point1, SampleType_UInt8 },
}};
ALenum format = AL_NONE;
std::find_if(mcfmtlist.cbegin(), mcfmtlist.cend(),
[&format,chans,type](const FormatEntryExt &fmt) -> bool
for(auto &fmt : mcfmtlist)
{
if(fmt.chans == chans && fmt.type == type)
{
if(fmt.chans == chans && fmt.type == type)
format = alGetEnumValue(fmt.name);
return format != 0 && format != -1;
ALenum format = alGetEnumValue(fmt.name);
if(format != 0 && format != -1)
return format;
}
);
if(format != 0 && format != -1)
return format;
}
}
if(alIsExtensionPresent("AL_EXT_FLOAT32"))
{
@ -228,18 +225,16 @@ static ALenum getALFormat(ChannelConfig chans, SampleType type)
{ "AL_FORMAT_MONO_FLOAT32", ChannelConfig_Mono, SampleType_Float32 },
{ "AL_FORMAT_STEREO_FLOAT32", ChannelConfig_Stereo, SampleType_Float32 },
}};
ALenum format = AL_NONE;
std::find_if(fltfmtlist.cbegin(), fltfmtlist.cend(),
[&format,chans,type](const FormatEntryExt &fmt) -> bool
for(auto &fmt : fltfmtlist)
{
if(fmt.chans == chans && fmt.type == type)
{
if(fmt.chans == chans && fmt.type == type)
format = alGetEnumValue(fmt.name);
return format != 0 && format != -1;
ALenum format = alGetEnumValue(fmt.name);
if(format != 0 && format != -1)
return format;
}
);
if(format != 0 && format != -1)
return format;
}
if(alIsExtensionPresent("AL_EXT_MCFORMATS"))
{
@ -249,16 +244,15 @@ static ALenum getALFormat(ChannelConfig chans, SampleType type)
{ "AL_FORMAT_71CHN32", ChannelConfig_7point1, SampleType_Float32 },
}};
std::find_if(fltmcfmtlist.cbegin(), fltmcfmtlist.cend(),
[&format,chans,type](const FormatEntryExt &fmt) -> bool
for(auto &fmt : fltmcfmtlist)
{
if(fmt.chans == chans && fmt.type == type)
{
if(fmt.chans == chans && fmt.type == type)
format = alGetEnumValue(fmt.name);
return format != 0 && format != -1;
ALenum format = alGetEnumValue(fmt.name);
if(format != 0 && format != -1)
return format;
}
);
if(format != 0 && format != -1)
return format;
}
}
}
@ -547,11 +541,11 @@ ALint OpenAL_SoundStream::refillQueue()
std::vector<char> data(mBufferSize);
for(;!mIsFinished && (ALuint)queued < mBuffers.size();++queued)
{
size_t got = mDecoder->read(&data[0], data.size());
size_t got = mDecoder->read(data.data(), data.size());
if(got < data.size())
{
mIsFinished = true;
std::memset(&data[got], mSilence, data.size()-got);
std::fill(data.begin()+got, data.end(), mSilence);
}
if(got > 0)
{
@ -559,7 +553,7 @@ ALint OpenAL_SoundStream::refillQueue()
mLoudnessAnalyzer->analyzeLoudness(data);
ALuint bufid = mBuffers[mCurrentBufIdx];
alBufferData(bufid, mFormat, &data[0], data.size(), mSampleRate);
alBufferData(bufid, mFormat, data.data(), data.size(), mSampleRate);
alSourceQueueBuffers(mSource, 1, &bufid);
mCurrentBufIdx = (mCurrentBufIdx+1) % mBuffers.size();
}
@ -594,25 +588,33 @@ bool OpenAL_Output::init(const std::string &devname, const std::string &hrtfname
{
deinit();
std::cout<< "Initializing OpenAL..." <<std::endl;
mDevice = alcOpenDevice(devname.c_str());
if(!mDevice)
if(!mDevice && !devname.empty())
{
if(devname.empty())
std::cerr<< "Failed to open default audio device" <<std::endl;
else
std::cerr<< "Failed to open \""<<devname<<"\"" <<std::endl;
return false;
std::cerr<< "Failed to open \""<<devname<<"\", trying default" <<std::endl;
mDevice = alcOpenDevice(nullptr);
}
else
if(!mDevice)
{
const ALCchar *name = NULL;
if(alcIsExtensionPresent(mDevice, "ALC_ENUMERATE_ALL_EXT"))
name = alcGetString(mDevice, ALC_ALL_DEVICES_SPECIFIER);
if(alcGetError(mDevice) != AL_NO_ERROR || !name)
name = alcGetString(mDevice, ALC_DEVICE_SPECIFIER);
std::cout << "Opened \""<<name<<"\"" << std::endl;
std::cerr<< "Failed to open default audio device" <<std::endl;
return false;
}
const ALCchar *name = nullptr;
if(alcIsExtensionPresent(mDevice, "ALC_ENUMERATE_ALL_EXT"))
name = alcGetString(mDevice, ALC_ALL_DEVICES_SPECIFIER);
if(alcGetError(mDevice) != AL_NO_ERROR || !name)
name = alcGetString(mDevice, ALC_DEVICE_SPECIFIER);
std::cout<< "Opened \""<<name<<"\"" <<std::endl;
ALCint major=0, minor=0;
alcGetIntegerv(mDevice, ALC_MAJOR_VERSION, 1, &major);
alcGetIntegerv(mDevice, ALC_MINOR_VERSION, 1, &minor);
std::cout<< " ALC Version: "<<major<<"."<<minor<<"\n"<<
" ALC Extensions: "<<alcGetString(mDevice, ALC_EXTENSIONS) <<std::endl;
ALC.EXT_EFX = alcIsExtensionPresent(mDevice, "ALC_EXT_EFX");
ALC.SOFT_HRTF = alcIsExtensionPresent(mDevice, "ALC_SOFT_HRTF");
@ -643,7 +645,7 @@ bool OpenAL_Output::init(const std::string &devname, const std::string &hrtfname
}
if(index < 0)
std::cerr<< "Failed to find HRTF name \""<<hrtfname<<"\", using default" <<std::endl;
std::cerr<< "Failed to find HRTF \""<<hrtfname<<"\", using default" <<std::endl;
else
{
attrs.push_back(ALC_HRTF_ID_SOFT);
@ -665,6 +667,11 @@ bool OpenAL_Output::init(const std::string &devname, const std::string &hrtfname
return false;
}
std::cout<< " Vendor: "<<alGetString(AL_VENDOR)<<"\n"<<
" Renderer: "<<alGetString(AL_RENDERER)<<"\n"<<
" Version: "<<alGetString(AL_VERSION)<<"\n"<<
" Extensions: "<<alGetString(AL_EXTENSIONS)<<std::endl;
if(!ALC.SOFT_HRTF)
std::cout<< "HRTF status unavailable" <<std::endl;
else
@ -698,7 +705,7 @@ bool OpenAL_Output::init(const std::string &devname, const std::string &hrtfname
{
ALuint src = 0;
alGenSources(1, &src);
if(getALError() != AL_NO_ERROR)
if(alGetError() != AL_NO_ERROR)
break;
mFreeSources.push_back(src);
}
@ -824,8 +831,8 @@ void OpenAL_Output::deinit()
{
mStreamThread->removeAll();
for(size_t i = 0;i < mFreeSources.size();i++)
alDeleteSources(1, &mFreeSources[i]);
for(ALuint source : mFreeSources)
alDeleteSources(1, &source);
mFreeSources.clear();
if(mEffectSlot)
@ -934,7 +941,7 @@ void OpenAL_Output::setHrtf(const std::string &hrtfname, HrtfMode hrtfmode)
}
Sound_Handle OpenAL_Output::loadSound(const std::string &fname)
std::pair<Sound_Handle,size_t> OpenAL_Output::loadSound(const std::string &fname)
{
getALError();
@ -959,27 +966,31 @@ Sound_Handle OpenAL_Output::loadSound(const std::string &fname)
decoder->getInfo(&srate, &chans, &type);
format = getALFormat(chans, type);
if(!format) return nullptr;
if(!format) return std::make_pair(nullptr, 0);
decoder->readAll(data);
decoder->close();
ALint size;
ALuint buf = 0;
alGenBuffers(1, &buf);
alBufferData(buf, format, &data[0], data.size(), srate);
alBufferData(buf, format, data.data(), data.size(), srate);
alGetBufferi(buf, AL_SIZE, &size);
if(getALError() != AL_NO_ERROR)
{
if(buf && alIsBuffer(buf))
alDeleteBuffers(1, &buf);
getALError();
return nullptr;
return std::make_pair(nullptr, 0);
}
return MAKE_PTRID(buf);
return std::make_pair(MAKE_PTRID(buf), size);
}
void OpenAL_Output::unloadSound(Sound_Handle data)
size_t OpenAL_Output::unloadSound(Sound_Handle data)
{
ALuint buffer = GET_PTRID(data);
if(!buffer) return 0;
// Make sure no sources are playing this buffer before unloading it.
SoundVec::const_iterator iter = mActiveSounds.begin();
for(;iter != mActiveSounds.end();++iter)
@ -996,19 +1007,11 @@ void OpenAL_Output::unloadSound(Sound_Handle data)
alSourcei(source, AL_BUFFER, 0);
}
}
alDeleteBuffers(1, &buffer);
getALError();
}
size_t OpenAL_Output::getSoundDataSize(Sound_Handle data) const
{
ALuint buffer = GET_PTRID(data);
ALint size = 0;
alGetBufferi(buffer, AL_SIZE, &size);
alDeleteBuffers(1, &buffer);
getALError();
return (ALuint)size;
return size;
}
@ -1368,23 +1371,19 @@ void OpenAL_Output::updateListener(const osg::Vec3f &pos, const osg::Vec3f &atdi
if(mWaterFilter)
{
ALuint filter = (env == Env_Underwater) ? mWaterFilter : AL_FILTER_NULL;
std::for_each(mActiveSounds.cbegin(), mActiveSounds.cend(),
[filter](const SoundVec::value_type &item) -> void
{
if(item->getUseEnv())
alSourcei(GET_PTRID(item->mHandle), AL_DIRECT_FILTER, filter);
}
);
std::for_each(mActiveStreams.cbegin(), mActiveStreams.cend(),
[filter](const StreamVec::value_type &item) -> void
{
if(item->getUseEnv())
alSourcei(
reinterpret_cast<OpenAL_SoundStream*>(item->mHandle)->mSource,
AL_DIRECT_FILTER, filter
);
}
);
for(Sound *sound : mActiveSounds)
{
if(sound->getUseEnv())
alSourcei(GET_PTRID(sound->mHandle), AL_DIRECT_FILTER, filter);
}
for(Stream *sound : mActiveStreams)
{
if(sound->getUseEnv())
alSourcei(
reinterpret_cast<OpenAL_SoundStream*>(sound->mHandle)->mSource,
AL_DIRECT_FILTER, filter
);
}
}
// Update the environment effect
if(mEffectSlot)
@ -1403,23 +1402,19 @@ void OpenAL_Output::updateListener(const osg::Vec3f &pos, const osg::Vec3f &atdi
void OpenAL_Output::pauseSounds(int types)
{
std::vector<ALuint> sources;
std::for_each(mActiveSounds.cbegin(), mActiveSounds.cend(),
[types,&sources](const SoundVec::value_type &sound) -> void
{
if(sound && sound->mHandle && (types&sound->getPlayType()))
sources.push_back(GET_PTRID(sound->mHandle));
}
);
std::for_each(mActiveStreams.cbegin(), mActiveStreams.cend(),
[types,&sources](const StreamVec::value_type &stream) -> void
for(Sound *sound : mActiveSounds)
{
if((types&sound->getPlayType()))
sources.push_back(GET_PTRID(sound->mHandle));
}
for(Stream *sound : mActiveStreams)
{
if((types&sound->getPlayType()))
{
if(stream && stream->mHandle && (types&stream->getPlayType()))
{
OpenAL_SoundStream *strm = reinterpret_cast<OpenAL_SoundStream*>(stream->mHandle);
sources.push_back(strm->mSource);
}
OpenAL_SoundStream *stream = reinterpret_cast<OpenAL_SoundStream*>(sound->mHandle);
sources.push_back(stream->mSource);
}
);
}
if(!sources.empty())
{
alSourcePausev(sources.size(), sources.data());
@ -1430,23 +1425,19 @@ void OpenAL_Output::pauseSounds(int types)
void OpenAL_Output::resumeSounds(int types)
{
std::vector<ALuint> sources;
std::for_each(mActiveSounds.cbegin(), mActiveSounds.cend(),
[types,&sources](const SoundVec::value_type &sound) -> void
{
if(sound && sound->mHandle && (types&sound->getPlayType()))
sources.push_back(GET_PTRID(sound->mHandle));
}
);
std::for_each(mActiveStreams.cbegin(), mActiveStreams.cend(),
[types,&sources](const StreamVec::value_type &stream) -> void
for(Sound *sound : mActiveSounds)
{
if((types&sound->getPlayType()))
sources.push_back(GET_PTRID(sound->mHandle));
}
for(Stream *sound : mActiveStreams)
{
if((types&sound->getPlayType()))
{
if(stream && stream->mHandle && (types&stream->getPlayType()))
{
OpenAL_SoundStream *strm = reinterpret_cast<OpenAL_SoundStream*>(stream->mHandle);
sources.push_back(strm->mSource);
}
OpenAL_SoundStream *stream = reinterpret_cast<OpenAL_SoundStream*>(sound->mHandle);
sources.push_back(stream->mSource);
}
);
}
if(!sources.empty())
{
alSourcePlayv(sources.size(), sources.data());

@ -66,9 +66,8 @@ namespace MWSound
virtual std::vector<std::string> enumerateHrtf();
virtual void setHrtf(const std::string &hrtfname, HrtfMode hrtfmode);
virtual Sound_Handle loadSound(const std::string &fname);
virtual void unloadSound(Sound_Handle data);
virtual size_t getSoundDataSize(Sound_Handle data) const;
virtual std::pair<Sound_Handle,size_t> loadSound(const std::string &fname);
virtual size_t unloadSound(Sound_Handle data);
virtual bool playSound(Sound *sound, Sound_Handle data, float offset);
virtual bool playSound3D(Sound *sound, Sound_Handle data, float offset);

@ -36,9 +36,8 @@ namespace MWSound
virtual std::vector<std::string> enumerateHrtf() = 0;
virtual void setHrtf(const std::string &hrtfname, HrtfMode hrtfmode) = 0;
virtual Sound_Handle loadSound(const std::string &fname) = 0;
virtual void unloadSound(Sound_Handle data) = 0;
virtual size_t getSoundDataSize(Sound_Handle data) const = 0;
virtual std::pair<Sound_Handle,size_t> loadSound(const std::string &fname) = 0;
virtual size_t unloadSound(Sound_Handle data) = 0;
virtual bool playSound(Sound *sound, Sound_Handle data, float offset) = 0;
virtual bool playSound3D(Sound *sound, Sound_Handle data, float offset) = 0;

@ -26,11 +26,7 @@
#include "sound.hpp"
#include "openal_output.hpp"
#define SOUND_OUT "OpenAL"
#include "ffmpeg_decoder.hpp"
#ifndef SOUND_IN
#define SOUND_IN "FFmpeg"
#endif
namespace MWSound
@ -84,45 +80,35 @@ namespace MWSound
mBufferCacheMin = std::min(mBufferCacheMin*1024*1024, mBufferCacheMax);
if(!useSound)
{
std::cout<< "Sound disabled." <<std::endl;
return;
}
std::string hrtfname = Settings::Manager::getString("hrtf", "Sound");
int hrtfstate = Settings::Manager::getInt("hrtf enable", "Sound");
HrtfMode hrtfmode = hrtfstate < 0 ? HrtfMode::Auto :
hrtfstate > 0 ? HrtfMode::Enable : HrtfMode::Disable;
std::cout << "Sound output: " << SOUND_OUT << std::endl;
std::cout << "Sound decoder: " << SOUND_IN << std::endl;
std::vector<std::string> names = mOutput->enumerate();
std::cout <<"Enumerated output devices:\n";
std::for_each(names.cbegin(), names.cend(),
[](const std::string &name) -> void
{ std::cout <<" "<<name<<"\n"; }
);
std::cout.flush();
std::string devname = Settings::Manager::getString("device", "Sound");
bool inited = mOutput->init(devname, hrtfname, hrtfmode);
if(!inited && !devname.empty())
{
std::cerr<< "Failed to initialize device \""<<devname<<"\", trying default" <<std::endl;
inited = mOutput->init(std::string(), hrtfname, hrtfmode);
}
if(!inited)
if(!mOutput->init(devname, hrtfname, hrtfmode))
{
std::cerr<< "Failed to initialize default audio device, sound disabled" <<std::endl;
std::cerr<< "Failed to initialize audio output, sound disabled" <<std::endl;
return;
}
std::vector<std::string> names = mOutput->enumerate();
std::cout <<"Enumerated output devices:\n";
for(const std::string &name : names)
std::cout <<" "<<name<<"\n";
std::cout.flush();
names = mOutput->enumerateHrtf();
if(!names.empty())
{
std::cout<< "Enumerated HRTF names:\n";
std::for_each(names.cbegin(), names.cend(),
[](const std::string &name) -> void
{ std::cout<< " "<<name<<"\n"; }
);
for(const std::string &name : names)
std::cout <<" "<<name<<"\n";
std::cout.flush();
}
}
@ -130,12 +116,11 @@ namespace MWSound
SoundManager::~SoundManager()
{
clear();
SoundBufferList::element_type::iterator sfxiter = mSoundBuffers->begin();
for(;sfxiter != mSoundBuffers->end();++sfxiter)
for(Sound_Buffer &sfx : *mSoundBuffers)
{
if(sfxiter->mHandle)
mOutput->unloadSound(sfxiter->mHandle);
sfxiter->mHandle = 0;
if(sfx.mHandle)
mOutput->unloadSound(sfx.mHandle);
sfx.mHandle = 0;
}
mUnusedBuffers.clear();
mOutput.reset();
@ -200,9 +185,23 @@ namespace MWSound
// minRange, and maxRange), and ensure it's ready for use.
Sound_Buffer *SoundManager::loadSound(const std::string &soundId)
{
#ifdef __GNUC__
#define LIKELY(x) __builtin_expect((bool)(x), true)
#define UNLIKELY(x) __builtin_expect((bool)(x), false)
#else
#define LIKELY(x) (bool)(x)
#define UNLIKELY(x) (bool)(x)
#endif
if(UNLIKELY(mBufferNameMap.empty()))
{
MWBase::World *world = MWBase::Environment::get().getWorld();
for(const ESM::Sound &sound : world->getStore().get<ESM::Sound>())
insertSound(Misc::StringUtils::lowerCase(sound.mId), &sound);
}
Sound_Buffer *sfx;
NameBufferMap::const_iterator snd = mBufferNameMap.find(soundId);
if(snd != mBufferNameMap.end())
if(LIKELY(snd != mBufferNameMap.end()))
sfx = snd->second;
else
{
@ -211,13 +210,16 @@ namespace MWSound
if(!sound) return nullptr;
sfx = insertSound(soundId, sound);
}
#undef LIKELY
#undef UNLIKELY
if(!sfx->mHandle)
{
sfx->mHandle = mOutput->loadSound(sfx->mResourceName);
size_t size;
std::tie(sfx->mHandle, size) = mOutput->loadSound(sfx->mResourceName);
if(!sfx->mHandle) return nullptr;
mBufferCacheSize += mOutput->getSoundDataSize(sfx->mHandle);
mBufferCacheSize += size;
if(mBufferCacheSize > mBufferCacheMax)
{
do {
@ -228,8 +230,8 @@ namespace MWSound
}
Sound_Buffer *unused = mUnusedBuffers.back();
mBufferCacheSize -= mOutput->getSoundDataSize(unused->mHandle);
mOutput->unloadSound(unused->mHandle);
size = mOutput->unloadSound(unused->mHandle);
mBufferCacheSize -= size;
unused->mHandle = 0;
mUnusedBuffers.pop_back();
@ -678,11 +680,10 @@ namespace MWSound
if(snditer != mActiveSounds.end())
{
Sound_Buffer *sfx = loadSound(Misc::StringUtils::lowerCase(soundId));
SoundBufferRefPairList::iterator sndidx = snditer->second.begin();
for(;sndidx != snditer->second.end();++sndidx)
for(SoundBufferRefPair &snd : snditer->second)
{
if(sndidx->second == sfx)
mOutput->finishSound(sndidx->first);
if(snd.second == sfx)
mOutput->finishSound(snd.first);
}
}
}
@ -692,33 +693,28 @@ namespace MWSound
SoundMap::iterator snditer = mActiveSounds.find(ptr);
if(snditer != mActiveSounds.end())
{
SoundBufferRefPairList::iterator sndidx = snditer->second.begin();
for(;sndidx != snditer->second.end();++sndidx)
mOutput->finishSound(sndidx->first);
for(SoundBufferRefPair &snd : snditer->second)
mOutput->finishSound(snd.first);
}
SaySoundMap::iterator sayiter = mActiveSaySounds.find(ptr);
if(sayiter != mActiveSaySounds.end())
mOutput->finishStream(sayiter->second);
}
void SoundManager::stopSound(const MWWorld::CellStore *cell)
{
SoundMap::iterator snditer = mActiveSounds.begin();
for(;snditer != mActiveSounds.end();++snditer)
for(SoundMap::value_type &snd : mActiveSounds)
{
if(snditer->first != MWWorld::ConstPtr() &&
snditer->first != MWMechanics::getPlayer() &&
snditer->first.getCell() == cell)
if(!snd.first.isEmpty() && snd.first != MWMechanics::getPlayer() && snd.first.getCell() == cell)
{
SoundBufferRefPairList::iterator sndidx = snditer->second.begin();
for(;sndidx != snditer->second.end();++sndidx)
mOutput->finishSound(sndidx->first);
for(SoundBufferRefPair &sndbuf : snd.second)
mOutput->finishSound(sndbuf.first);
}
}
SaySoundMap::iterator sayiter = mActiveSaySounds.begin();
for(;sayiter != mActiveSaySounds.end();++sayiter)
for(SaySoundMap::value_type &snd : mActiveSaySounds)
{
if(sayiter->first != MWWorld::ConstPtr() &&
sayiter->first != MWMechanics::getPlayer() &&
sayiter->first.getCell() == cell)
mOutput->finishStream(sayiter->second);
if(!snd.first.isEmpty() && snd.first != MWMechanics::getPlayer() && snd.first.getCell() == cell)
mOutput->finishStream(snd.second);
}
}
@ -728,11 +724,10 @@ namespace MWSound
if(snditer != mActiveSounds.end())
{
Sound_Buffer *sfx = loadSound(Misc::StringUtils::lowerCase(soundId));
SoundBufferRefPairList::iterator sndidx = snditer->second.begin();
for(;sndidx != snditer->second.end();++sndidx)
for(SoundBufferRefPair &sndbuf : snditer->second)
{
if(sndidx->second == sfx)
mOutput->finishSound(sndidx->first);
if(sndbuf.second == sfx)
mOutput->finishSound(sndbuf.first);
}
}
}
@ -744,11 +739,10 @@ namespace MWSound
if(snditer != mActiveSounds.end())
{
Sound_Buffer *sfx = loadSound(Misc::StringUtils::lowerCase(soundId));
SoundBufferRefPairList::iterator sndidx = snditer->second.begin();
for(;sndidx != snditer->second.end();++sndidx)
for(SoundBufferRefPair &sndbuf : snditer->second)
{
if(sndidx->second == sfx)
sndidx->first->setFadeout(duration);
if(sndbuf.second == sfx)
sndbuf.first->setFadeout(duration);
}
}
}
@ -759,12 +753,10 @@ namespace MWSound
if(snditer != mActiveSounds.end())
{
Sound_Buffer *sfx = lookupSound(Misc::StringUtils::lowerCase(soundId));
SoundBufferRefPairList::const_iterator sndidx = snditer->second.begin();
for(;sndidx != snditer->second.end();++sndidx)
{
if(sndidx->second == sfx && mOutput->isSoundPlaying(sndidx->first))
return true;
}
return std::find_if(snditer->second.cbegin(), snditer->second.cend(),
[this,sfx](const SoundBufferRefPair &snd) -> bool
{ return snd.second == sfx && mOutput->isSoundPlaying(snd.first); }
) != snditer->second.cend();
}
return false;
}
@ -823,10 +815,8 @@ namespace MWSound
if(total == 0)
{
std::for_each(regn->mSoundList.cbegin(), regn->mSoundList.cend(),
[](const ESM::Region::SoundRef &sndref) -> void
{ total += (int)sndref.mChance; }
);
for(const ESM::Region::SoundRef &sndref : regn->mSoundList)
total += (int)sndref.mChance;
if(total == 0)
return;
}
@ -834,20 +824,15 @@ namespace MWSound
int r = Misc::Rng::rollDice(total);
int pos = 0;
std::find_if_not(regn->mSoundList.cbegin(), regn->mSoundList.cend(),
[&pos, r, this](const ESM::Region::SoundRef &sndref) -> bool
for(const ESM::Region::SoundRef &sndref : regn->mSoundList)
{
if(r - pos < sndref.mChance)
{
if(r - pos < sndref.mChance)
{
playSound(sndref.mSound.toString(), 1.0f, 1.0f);
// Played this sound, stop iterating
return false;
}
pos += sndref.mChance;
// Not this sound, keep iterating
return true;
playSound(sndref.mSound.toString(), 1.0f, 1.0f);
break;
}
);
pos += sndref.mChance;
}
}
void SoundManager::updateWaterSound(float /*duration*/)
@ -1135,28 +1120,23 @@ namespace MWSound
if(!mOutput->isInitialized())
return;
mOutput->startUpdate();
SoundMap::iterator snditer = mActiveSounds.begin();
for(;snditer != mActiveSounds.end();++snditer)
for(SoundMap::value_type &snd : mActiveSounds)
{
SoundBufferRefPairList::iterator sndidx = snditer->second.begin();
for(;sndidx != snditer->second.end();++sndidx)
for(SoundBufferRefPair &sndbuf : snd.second)
{
Sound *sound = sndidx->first;
Sound *sound = sndbuf.first;
sound->setBaseVolume(volumeFromType(sound->getPlayType()));
mOutput->updateSound(sound);
}
}
SaySoundMap::iterator sayiter = mActiveSaySounds.begin();
for(;sayiter != mActiveSaySounds.end();++sayiter)
for(SaySoundMap::value_type &snd : mActiveSaySounds)
{
Stream *sound = sayiter->second;
Stream *sound = snd.second;
sound->setBaseVolume(volumeFromType(sound->getPlayType()));
mOutput->updateStream(sound);
}
TrackList::iterator trkiter = mActiveTracks.begin();
for(;trkiter != mActiveTracks.end();++trkiter)
for(Stream *sound : mActiveTracks)
{
Stream *sound = *trkiter;
sound->setBaseVolume(volumeFromType(sound->getPlayType()));
mOutput->updateStream(sound);
}
@ -1262,36 +1242,35 @@ namespace MWSound
void SoundManager::clear()
{
SoundMap::iterator snditer = mActiveSounds.begin();
for(;snditer != mActiveSounds.end();++snditer)
stopMusic();
for(SoundMap::value_type &snd : mActiveSounds)
{
SoundBufferRefPairList::iterator sndidx = snditer->second.begin();
for(;sndidx != snditer->second.end();++sndidx)
for(SoundBufferRefPair &sndbuf : snd.second)
{
mOutput->finishSound(sndidx->first);
mUnusedSounds.push_back(sndidx->first);
Sound_Buffer *sfx = sndidx->second;
mOutput->finishSound(sndbuf.first);
mUnusedSounds.push_back(sndbuf.first);
Sound_Buffer *sfx = sndbuf.second;
if(sfx->mUses-- == 1)
mUnusedBuffers.push_front(sfx);
}
}
mActiveSounds.clear();
SaySoundMap::iterator sayiter = mActiveSaySounds.begin();
for(;sayiter != mActiveSaySounds.end();++sayiter)
mUnderwaterSound = nullptr;
mNearWaterSound = nullptr;
for(SaySoundMap::value_type &snd : mActiveSaySounds)
{
mOutput->finishStream(sayiter->second);
mUnusedStreams.push_back(sayiter->second);
mOutput->finishStream(snd.second);
mUnusedStreams.push_back(snd.second);
}
mActiveSaySounds.clear();
TrackList::iterator trkiter = mActiveTracks.begin();
for(;trkiter != mActiveTracks.end();++trkiter)
for(Stream *sound : mActiveTracks)
{
mOutput->finishStream(*trkiter);
mUnusedStreams.push_back(*trkiter);
mOutput->finishStream(sound);
mUnusedStreams.push_back(sound);
}
mActiveTracks.clear();
mUnderwaterSound = nullptr;
mNearWaterSound = nullptr;
stopMusic();
}
}

Loading…
Cancel
Save