1
0
Fork 1
mirror of https://github.com/TES3MP/openmw-tes3mp.git synced 2025-02-21 12:39:40 +00:00

Cache loudness vector in the buffer cache

This commit is contained in:
scrawl 2014-07-29 14:32:44 +02:00
parent 0943ff0886
commit a59620f643
2 changed files with 57 additions and 55 deletions

View file

@ -739,7 +739,7 @@ void OpenAL_Output::deinit()
mUnusedBuffers.clear(); mUnusedBuffers.clear();
while(!mBufferCache.empty()) while(!mBufferCache.empty())
{ {
alDeleteBuffers(1, &mBufferCache.begin()->second); alDeleteBuffers(1, &mBufferCache.begin()->second.mALBuffer);
mBufferCache.erase(mBufferCache.begin()); mBufferCache.erase(mBufferCache.begin());
} }
@ -755,14 +755,14 @@ void OpenAL_Output::deinit()
} }
ALuint OpenAL_Output::getBuffer(const std::string &fname, std::vector<float>* loudnessBuffer) const CachedSound& OpenAL_Output::getBuffer(const std::string &fname)
{ {
ALuint buf = 0; ALuint buf = 0;
NameMap::iterator iditer = mBufferCache.find(fname); NameMap::iterator iditer = mBufferCache.find(fname);
if(iditer != mBufferCache.end()) if(iditer != mBufferCache.end())
{ {
buf = iditer->second; buf = iditer->second.mALBuffer;
if(mBufferRefs[buf]++ == 0) if(mBufferRefs[buf]++ == 0)
{ {
IDDq::iterator iter = std::find(mUnusedBuffers.begin(), IDDq::iterator iter = std::find(mUnusedBuffers.begin(),
@ -770,12 +770,11 @@ ALuint OpenAL_Output::getBuffer(const std::string &fname, std::vector<float>* lo
if(iter != mUnusedBuffers.end()) if(iter != mUnusedBuffers.end())
mUnusedBuffers.erase(iter); mUnusedBuffers.erase(iter);
} }
return iditer->second;
} }
throwALerror(); throwALerror();
if (buf != 0 && loudnessBuffer == NULL)
return buf;
std::vector<char> data; std::vector<char> data;
ChannelConfig chans; ChannelConfig chans;
SampleType type; SampleType type;
@ -801,52 +800,49 @@ ALuint OpenAL_Output::getBuffer(const std::string &fname, std::vector<float>* lo
decoder->readAll(data); decoder->readAll(data);
decoder->close(); decoder->close();
if (loudnessBuffer != NULL) CachedSound cached;
analyzeLoudness(data, srate, chans, type, cached.mLoudnessVector, loudnessFPS);
alGenBuffers(1, &buf);
throwALerror();
alBufferData(buf, format, &data[0], data.size(), srate);
mBufferRefs[buf] = 1;
cached.mALBuffer = buf;
mBufferCache[fname] = cached;
ALint bufsize = 0;
alGetBufferi(buf, AL_SIZE, &bufsize);
mBufferCacheMemSize += bufsize;
// NOTE: Max buffer cache: 15MB
while(mBufferCacheMemSize > 15*1024*1024)
{ {
analyzeLoudness(data, srate, chans, type, *loudnessBuffer, loudnessFPS); if(mUnusedBuffers.empty())
}
if (buf == 0)
{
alGenBuffers(1, &buf);
throwALerror();
alBufferData(buf, format, &data[0], data.size(), srate);
mBufferCache[fname] = buf;
mBufferRefs[buf] = 1;
ALint bufsize = 0;
alGetBufferi(buf, AL_SIZE, &bufsize);
mBufferCacheMemSize += bufsize;
// NOTE: Max buffer cache: 15MB
while(mBufferCacheMemSize > 15*1024*1024)
{ {
if(mUnusedBuffers.empty()) std::cout <<"No more unused buffers to clear!"<< std::endl;
{ break;
std::cout <<"No more unused buffers to clear!"<< std::endl;
break;
}
ALuint oldbuf = mUnusedBuffers.front();
mUnusedBuffers.pop_front();
NameMap::iterator nameiter = mBufferCache.begin();
while(nameiter != mBufferCache.end())
{
if(nameiter->second == oldbuf)
mBufferCache.erase(nameiter++);
else
++nameiter;
}
bufsize = 0;
alGetBufferi(oldbuf, AL_SIZE, &bufsize);
alDeleteBuffers(1, &oldbuf);
mBufferCacheMemSize -= bufsize;
} }
ALuint oldbuf = mUnusedBuffers.front();
mUnusedBuffers.pop_front();
NameMap::iterator nameiter = mBufferCache.begin();
while(nameiter != mBufferCache.end())
{
if(nameiter->second.mALBuffer == oldbuf)
mBufferCache.erase(nameiter++);
else
++nameiter;
}
bufsize = 0;
alGetBufferi(oldbuf, AL_SIZE, &bufsize);
alDeleteBuffers(1, &oldbuf);
mBufferCacheMemSize -= bufsize;
} }
return buf;
return mBufferCache[fname];
} }
void OpenAL_Output::bufferFinished(ALuint buf) void OpenAL_Output::bufferFinished(ALuint buf)
@ -870,7 +866,7 @@ MWBase::SoundPtr OpenAL_Output::playSound(const std::string &fname, float vol, f
try try
{ {
buf = getBuffer(fname); buf = getBuffer(fname).mALBuffer;
sound.reset(new OpenAL_Sound(*this, src, buf, Ogre::Vector3(0.0f), vol, basevol, pitch, 1.0f, 1000.0f, flags)); sound.reset(new OpenAL_Sound(*this, src, buf, Ogre::Vector3(0.0f), vol, basevol, pitch, 1.0f, 1000.0f, flags));
} }
catch(std::exception&) catch(std::exception&)
@ -909,12 +905,12 @@ MWBase::SoundPtr OpenAL_Output::playSound3D(const std::string &fname, const Ogre
try try
{ {
std::vector<float> loudnessVector; const CachedSound& cached = getBuffer(fname);
buf = cached.mALBuffer;
buf = getBuffer(fname, extractLoudness ? &loudnessVector : NULL);
sound.reset(new OpenAL_Sound3D(*this, src, buf, pos, vol, basevol, pitch, min, max, flags)); sound.reset(new OpenAL_Sound3D(*this, src, buf, pos, vol, basevol, pitch, min, max, flags));
sound->setLoudnessVector(loudnessVector, loudnessFPS); if (extractLoudness)
sound->setLoudnessVector(cached.mLoudnessVector, loudnessFPS);
} }
catch(std::exception&) catch(std::exception&)
{ {

View file

@ -16,6 +16,12 @@ namespace MWSound
class SoundManager; class SoundManager;
class Sound; class Sound;
struct CachedSound
{
ALuint mALBuffer;
std::vector<float> mLoudnessVector;
};
class OpenAL_Output : public Sound_Output class OpenAL_Output : public Sound_Output
{ {
ALCdevice *mDevice; ALCdevice *mDevice;
@ -25,7 +31,7 @@ namespace MWSound
IDDq mFreeSources; IDDq mFreeSources;
IDDq mUnusedBuffers; IDDq mUnusedBuffers;
typedef std::map<std::string,ALuint> NameMap; typedef std::map<std::string,CachedSound> NameMap;
NameMap mBufferCache; NameMap mBufferCache;
typedef std::map<ALuint,ALuint> IDRefMap; typedef std::map<ALuint,ALuint> IDRefMap;
@ -36,7 +42,7 @@ namespace MWSound
typedef std::vector<Sound*> SoundVec; typedef std::vector<Sound*> SoundVec;
SoundVec mActiveSounds; SoundVec mActiveSounds;
ALuint getBuffer(const std::string &fname, std::vector<float>* loudnessBuffer=NULL); const CachedSound& getBuffer(const std::string &fname);
void bufferFinished(ALuint buffer); void bufferFinished(ALuint buffer);
Environment mLastEnvironment; Environment mLastEnvironment;