Merge pull request #856 from kcat/master

Fix potential sound stream leak
openmw-38
scrawl 9 years ago
commit 17069327a0

@ -915,7 +915,7 @@ void OpenAL_Output::playSound3D(MWBase::SoundPtr sound, Sound_Handle data, float
sound->mHandle = MAKE_PTRID(source); sound->mHandle = MAKE_PTRID(source);
} }
void OpenAL_Output::stopSound(MWBase::SoundPtr sound) void OpenAL_Output::finishSound(MWBase::SoundPtr sound)
{ {
if(!sound->mHandle) return; if(!sound->mHandle) return;
ALuint source = GET_PTRID(sound->mHandle); ALuint source = GET_PTRID(sound->mHandle);
@ -1012,7 +1012,7 @@ void OpenAL_Output::streamSound3D(DecoderPtr decoder, MWBase::SoundStreamPtr sou
sound->mHandle = stream; sound->mHandle = stream;
} }
void OpenAL_Output::stopStream(MWBase::SoundStreamPtr sound) void OpenAL_Output::finishStream(MWBase::SoundStreamPtr sound)
{ {
if(!sound->mHandle) return; if(!sound->mHandle) return;
OpenAL_SoundStream *stream = reinterpret_cast<OpenAL_SoundStream*>(sound->mHandle); OpenAL_SoundStream *stream = reinterpret_cast<OpenAL_SoundStream*>(sound->mHandle);

@ -58,13 +58,13 @@ namespace MWSound
virtual void playSound(MWBase::SoundPtr sound, Sound_Handle data, float offset); virtual void playSound(MWBase::SoundPtr sound, Sound_Handle data, float offset);
virtual void playSound3D(MWBase::SoundPtr sound, Sound_Handle data, float offset); virtual void playSound3D(MWBase::SoundPtr sound, Sound_Handle data, float offset);
virtual void stopSound(MWBase::SoundPtr sound); virtual void finishSound(MWBase::SoundPtr sound);
virtual bool isSoundPlaying(MWBase::SoundPtr sound); virtual bool isSoundPlaying(MWBase::SoundPtr sound);
virtual void updateSound(MWBase::SoundPtr sound); virtual void updateSound(MWBase::SoundPtr sound);
virtual void streamSound(DecoderPtr decoder, MWBase::SoundStreamPtr sound); virtual void streamSound(DecoderPtr decoder, MWBase::SoundStreamPtr sound);
virtual void streamSound3D(DecoderPtr decoder, MWBase::SoundStreamPtr sound); virtual void streamSound3D(DecoderPtr decoder, MWBase::SoundStreamPtr sound);
virtual void stopStream(MWBase::SoundStreamPtr sound); virtual void finishStream(MWBase::SoundStreamPtr sound);
virtual double getStreamDelay(MWBase::SoundStreamPtr sound); virtual double getStreamDelay(MWBase::SoundStreamPtr sound);
virtual double getStreamOffset(MWBase::SoundStreamPtr sound); virtual double getStreamOffset(MWBase::SoundStreamPtr sound);
virtual bool isStreamPlaying(MWBase::SoundStreamPtr sound); virtual bool isStreamPlaying(MWBase::SoundStreamPtr sound);

@ -37,13 +37,13 @@ namespace MWSound
virtual void playSound(MWBase::SoundPtr sound, Sound_Handle data, float offset) = 0; virtual void playSound(MWBase::SoundPtr sound, Sound_Handle data, float offset) = 0;
virtual void playSound3D(MWBase::SoundPtr sound, Sound_Handle data, float offset) = 0; virtual void playSound3D(MWBase::SoundPtr sound, Sound_Handle data, float offset) = 0;
virtual void stopSound(MWBase::SoundPtr sound) = 0; virtual void finishSound(MWBase::SoundPtr sound) = 0;
virtual bool isSoundPlaying(MWBase::SoundPtr sound) = 0; virtual bool isSoundPlaying(MWBase::SoundPtr sound) = 0;
virtual void updateSound(MWBase::SoundPtr sound) = 0; virtual void updateSound(MWBase::SoundPtr sound) = 0;
virtual void streamSound(DecoderPtr decoder, MWBase::SoundStreamPtr sound) = 0; virtual void streamSound(DecoderPtr decoder, MWBase::SoundStreamPtr sound) = 0;
virtual void streamSound3D(DecoderPtr decoder, MWBase::SoundStreamPtr sound) = 0; virtual void streamSound3D(DecoderPtr decoder, MWBase::SoundStreamPtr sound) = 0;
virtual void stopStream(MWBase::SoundStreamPtr sound) = 0; virtual void finishStream(MWBase::SoundStreamPtr sound) = 0;
virtual double getStreamDelay(MWBase::SoundStreamPtr sound) = 0; virtual double getStreamDelay(MWBase::SoundStreamPtr sound) = 0;
virtual double getStreamOffset(MWBase::SoundStreamPtr sound) = 0; virtual double getStreamOffset(MWBase::SoundStreamPtr sound) = 0;
virtual bool isStreamPlaying(MWBase::SoundStreamPtr sound) = 0; virtual bool isStreamPlaying(MWBase::SoundStreamPtr sound) = 0;

@ -309,7 +309,7 @@ namespace MWSound
void SoundManager::stopMusic() void SoundManager::stopMusic()
{ {
if(mMusic) if(mMusic)
mOutput->stopStream(mMusic); mOutput->finishStream(mMusic);
mMusic.reset(); mMusic.reset();
} }
@ -410,8 +410,10 @@ namespace MWSound
{ {
MWBase::World *world = MWBase::Environment::get().getWorld(); MWBase::World *world = MWBase::Environment::get().getWorld();
const osg::Vec3f pos = world->getActorHeadTransform(ptr).getTrans(); const osg::Vec3f pos = world->getActorHeadTransform(ptr).getTrans();
MWBase::SoundStreamPtr sound = playVoice(decoder, pos, (ptr == MWMechanics::getPlayer())); SoundLoudnessPair &old = mActiveSaySounds[ptr];
mActiveSaySounds[ptr] = std::make_pair(sound, loudness); if(old.first.get()) mOutput->finishStream(old.first);
old = std::make_pair(playVoice(decoder, pos, (ptr == MWMechanics::getPlayer())),
loudness);
} }
} }
catch(std::exception &e) catch(std::exception &e)
@ -450,8 +452,9 @@ namespace MWSound
mPendingSaySounds[MWWorld::Ptr()] = std::make_pair(decoder, loudness); mPendingSaySounds[MWWorld::Ptr()] = std::make_pair(decoder, loudness);
else else
{ {
MWBase::SoundStreamPtr sound = playVoice(decoder, osg::Vec3f(), true); SoundLoudnessPair &old = mActiveSaySounds[MWWorld::Ptr()];
mActiveSaySounds[MWWorld::Ptr()] = std::make_pair(sound, loudness); if(old.first.get()) mOutput->finishStream(old.first);
old = std::make_pair(playVoice(decoder, osg::Vec3f(), true), loudness);
} }
} }
catch(std::exception &e) catch(std::exception &e)
@ -477,7 +480,7 @@ namespace MWSound
SaySoundMap::iterator snditer = mActiveSaySounds.find(ptr); SaySoundMap::iterator snditer = mActiveSaySounds.find(ptr);
if(snditer != mActiveSaySounds.end()) if(snditer != mActiveSaySounds.end())
{ {
mOutput->stopStream(snditer->second.first); mOutput->finishStream(snditer->second.first);
mActiveSaySounds.erase(snditer); mActiveSaySounds.erase(snditer);
} }
mPendingSaySounds.erase(ptr); mPendingSaySounds.erase(ptr);
@ -506,7 +509,7 @@ namespace MWSound
void SoundManager::stopTrack(MWBase::SoundStreamPtr stream) void SoundManager::stopTrack(MWBase::SoundStreamPtr stream)
{ {
mOutput->stopStream(stream); mOutput->finishStream(stream);
TrackList::iterator iter = std::lower_bound(mActiveTracks.begin(), mActiveTracks.end(), stream); TrackList::iterator iter = std::lower_bound(mActiveTracks.begin(), mActiveTracks.end(), stream);
if(iter != mActiveTracks.end() && *iter == stream) if(iter != mActiveTracks.end() && *iter == stream)
mActiveTracks.erase(iter); mActiveTracks.erase(iter);
@ -624,7 +627,7 @@ namespace MWSound
void SoundManager::stopSound(MWBase::SoundPtr sound) void SoundManager::stopSound(MWBase::SoundPtr sound)
{ {
if (sound.get()) if (sound.get())
mOutput->stopSound(sound); mOutput->finishSound(sound);
} }
void SoundManager::stopSound3D(const MWWorld::Ptr &ptr, const std::string& soundId) void SoundManager::stopSound3D(const MWWorld::Ptr &ptr, const std::string& soundId)
@ -637,7 +640,7 @@ namespace MWSound
for(;sndidx != snditer->second.end();++sndidx) for(;sndidx != snditer->second.end();++sndidx)
{ {
if(sndidx->second == sfx) if(sndidx->second == sfx)
mOutput->stopSound(sndidx->first); mOutput->finishSound(sndidx->first);
} }
} }
} }
@ -649,7 +652,7 @@ namespace MWSound
{ {
SoundBufferRefPairList::iterator sndidx = snditer->second.begin(); SoundBufferRefPairList::iterator sndidx = snditer->second.begin();
for(;sndidx != snditer->second.end();++sndidx) for(;sndidx != snditer->second.end();++sndidx)
mOutput->stopSound(sndidx->first); mOutput->finishSound(sndidx->first);
} }
} }
@ -664,7 +667,7 @@ namespace MWSound
{ {
SoundBufferRefPairList::iterator sndidx = snditer->second.begin(); SoundBufferRefPairList::iterator sndidx = snditer->second.begin();
for(;sndidx != snditer->second.end();++sndidx) for(;sndidx != snditer->second.end();++sndidx)
mOutput->stopSound(sndidx->first); mOutput->finishSound(sndidx->first);
} }
++snditer; ++snditer;
} }
@ -675,7 +678,7 @@ namespace MWSound
sayiter->first != MWMechanics::getPlayer() && sayiter->first != MWMechanics::getPlayer() &&
sayiter->first.getCell() == cell) sayiter->first.getCell() == cell)
{ {
mOutput->stopStream(sayiter->second.first); mOutput->finishStream(sayiter->second.first);
} }
++sayiter; ++sayiter;
} }
@ -691,7 +694,7 @@ namespace MWSound
for(;sndidx != snditer->second.end();++sndidx) for(;sndidx != snditer->second.end();++sndidx)
{ {
if(sndidx->second == sfx) if(sndidx->second == sfx)
mOutput->stopSound(sndidx->first); mOutput->finishSound(sndidx->first);
} }
} }
} }
@ -829,7 +832,7 @@ namespace MWSound
env = Env_Underwater; env = Env_Underwater;
else if(mUnderwaterSound) else if(mUnderwaterSound)
{ {
mOutput->stopSound(mUnderwaterSound); mOutput->finishSound(mUnderwaterSound);
mUnderwaterSound.reset(); mUnderwaterSound.reset();
} }
@ -866,13 +869,13 @@ namespace MWSound
if(sound->getDistanceCull()) if(sound->getDistanceCull())
{ {
if((mListenerPos - objpos).length2() > 2000*2000) if((mListenerPos - objpos).length2() > 2000*2000)
mOutput->stopSound(sound); mOutput->finishSound(sound);
} }
} }
if(!mOutput->isSoundPlaying(sound)) if(!mOutput->isSoundPlaying(sound))
{ {
mOutput->stopSound(sound); mOutput->finishSound(sound);
Sound_Buffer *sfx = sndidx->second; Sound_Buffer *sfx = sndidx->second;
if(sfx->mUses-- == 1) if(sfx->mUses-- == 1)
mUnusedBuffers.push_front(sfx); mUnusedBuffers.push_front(sfx);
@ -904,16 +907,18 @@ namespace MWSound
MWBase::SoundStreamPtr sound; MWBase::SoundStreamPtr sound;
MWWorld::Ptr ptr = penditer->first; MWWorld::Ptr ptr = penditer->first;
SoundLoudnessPair &old = mActiveSaySounds[ptr];
if(old.first.get()) mOutput->finishStream(old.first);
if(ptr == MWWorld::Ptr()) if(ptr == MWWorld::Ptr())
sound = playVoice(decoder, osg::Vec3f(), true); sound = playVoice(decoder, osg::Vec3f(), true);
else else
{ {
MWBase::World *world = MWBase::Environment::get().getWorld(); MWBase::World *world = MWBase::Environment::get().getWorld();
const osg::Vec3f pos = world->getActorHeadTransform(ptr).getTrans(); const osg::Vec3f pos = world->getActorHeadTransform(ptr).getTrans();
sound = playVoice(decoder, pos, (ptr == MWMechanics::getPlayer())); sound = playVoice(decoder, pos, (ptr == MWMechanics::getPlayer()));
} }
mActiveSaySounds[ptr] = std::make_pair(sound, loudness); old = std::make_pair(sound, loudness);
} }
catch(std::exception &e) { catch(std::exception &e) {
std::cerr<< "Sound Error: "<<e.what() <<std::endl; std::cerr<< "Sound Error: "<<e.what() <<std::endl;
@ -939,13 +944,13 @@ namespace MWSound
if(sound->getDistanceCull()) if(sound->getDistanceCull())
{ {
if((mListenerPos - pos).length2() > 2000*2000) if((mListenerPos - pos).length2() > 2000*2000)
mOutput->stopStream(sound); mOutput->finishStream(sound);
} }
} }
if(!mOutput->isStreamPlaying(sound)) if(!mOutput->isStreamPlaying(sound))
{ {
mOutput->stopStream(sound); mOutput->finishStream(sound);
mActiveSaySounds.erase(sayiter++); mActiveSaySounds.erase(sayiter++);
} }
else else
@ -963,7 +968,7 @@ namespace MWSound
MWBase::SoundStreamPtr sound = *trkiter; MWBase::SoundStreamPtr sound = *trkiter;
if(!mOutput->isStreamPlaying(sound)) if(!mOutput->isStreamPlaying(sound))
{ {
mOutput->stopStream(sound); mOutput->finishStream(sound);
trkiter = mActiveTracks.erase(trkiter); trkiter = mActiveTracks.erase(trkiter);
} }
else else
@ -1143,7 +1148,7 @@ namespace MWSound
SoundBufferRefPairList::iterator sndidx = snditer->second.begin(); SoundBufferRefPairList::iterator sndidx = snditer->second.begin();
for(;sndidx != snditer->second.end();++sndidx) for(;sndidx != snditer->second.end();++sndidx)
{ {
mOutput->stopSound(sndidx->first); mOutput->finishSound(sndidx->first);
Sound_Buffer *sfx = sndidx->second; Sound_Buffer *sfx = sndidx->second;
if(sfx->mUses-- == 1) if(sfx->mUses-- == 1)
mUnusedBuffers.push_front(sfx); mUnusedBuffers.push_front(sfx);
@ -1152,11 +1157,11 @@ namespace MWSound
mActiveSounds.clear(); mActiveSounds.clear();
SaySoundMap::iterator sayiter = mActiveSaySounds.begin(); SaySoundMap::iterator sayiter = mActiveSaySounds.begin();
for(;sayiter != mActiveSaySounds.end();++sayiter) for(;sayiter != mActiveSaySounds.end();++sayiter)
mOutput->stopStream(sayiter->second.first); mOutput->finishStream(sayiter->second.first);
mActiveSaySounds.clear(); mActiveSaySounds.clear();
TrackList::iterator trkiter = mActiveTracks.begin(); TrackList::iterator trkiter = mActiveTracks.begin();
for(;trkiter != mActiveTracks.end();++trkiter) for(;trkiter != mActiveTracks.end();++trkiter)
mOutput->stopStream(*trkiter); mOutput->finishStream(*trkiter);
mActiveTracks.clear(); mActiveTracks.clear();
mPendingSaySounds.clear(); mPendingSaySounds.clear();
mUnderwaterSound.reset(); mUnderwaterSound.reset();

Loading…
Cancel
Save