From 0d552c10bc913771b73ca4deb38f3dbaf97477db Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Mon, 26 Mar 2012 04:10:47 -0700 Subject: [PATCH 01/11] Use an empty MWWorld::Ptr object for non-3D sounds --- apps/openmw/mwsound/soundmanager.cpp | 29 ++++++++++++---------------- apps/openmw/mwsound/soundmanager.hpp | 1 - 2 files changed, 12 insertions(+), 18 deletions(-) diff --git a/apps/openmw/mwsound/soundmanager.cpp b/apps/openmw/mwsound/soundmanager.cpp index f626ec1584..4d47e5f2cc 100644 --- a/apps/openmw/mwsound/soundmanager.cpp +++ b/apps/openmw/mwsound/soundmanager.cpp @@ -69,7 +69,6 @@ namespace MWSound SoundManager::~SoundManager() { - mLooseSounds.clear(); mActiveSounds.clear(); mMusic.reset(); mOutput.reset(); @@ -207,7 +206,7 @@ namespace MWSound { std::string file = lookup(soundId, volume, min, max); Sound *sound = mOutput->playSound(file, volume, pitch, loop); - mLooseSounds[soundId] = SoundPtr(sound); + mActiveSounds[MWWorld::Ptr()][soundId] = SoundPtr(sound); } catch(std::exception &e) { @@ -226,8 +225,7 @@ namespace MWSound std::string file = lookup(soundId, volume, min, max); SoundPtr sound(mOutput->playSound3D(file, pos.pos, volume, pitch, min, max, loop)); - if(untracked) mLooseSounds[soundId] = sound; - else mActiveSounds[ptr][soundId] = sound; + mActiveSounds[untracked?MWWorld::Ptr():ptr][soundId] = sound; } catch(std::exception &e) { @@ -272,7 +270,7 @@ namespace MWSound SoundMap::iterator snditer = mActiveSounds.begin(); while(snditer != mActiveSounds.end()) { - if(snditer->first.getCell() == cell) + if(snditer->first != MWWorld::Ptr() && snditer->first.getCell() == cell) { IDMap::iterator iditer = snditer->second.begin(); while(iditer != snditer->second.end()) @@ -289,11 +287,17 @@ namespace MWSound void SoundManager::stopSound(const std::string& soundId) { - IDMap::iterator iditer = mLooseSounds.find(soundId); - if(iditer != mLooseSounds.end()) + SoundMap::iterator snditer = mActiveSounds.find(MWWorld::Ptr()); + if(snditer == mActiveSounds.end()) + return; + + IDMap::iterator iditer = snditer->second.find(soundId); + if(iditer != snditer->second.end()) { iditer->second->stop(); - mLooseSounds.erase(iditer); + snditer->second.erase(iditer); + if(snditer->second.empty()) + mActiveSounds.erase(snditer); } } @@ -415,15 +419,6 @@ namespace MWSound else snditer++; } - - IDMap::iterator iditer = mLooseSounds.begin(); - while(iditer != mLooseSounds.end()) - { - if(!iditer->second->isPlaying()) - mLooseSounds.erase(iditer++); - else - iditer++; - } } void SoundManager::update(float duration) diff --git a/apps/openmw/mwsound/soundmanager.hpp b/apps/openmw/mwsound/soundmanager.hpp index b7c883a130..8d76ba1008 100644 --- a/apps/openmw/mwsound/soundmanager.hpp +++ b/apps/openmw/mwsound/soundmanager.hpp @@ -44,7 +44,6 @@ namespace MWSound typedef std::map IDMap; typedef std::map SoundMap; SoundMap mActiveSounds; - IDMap mLooseSounds; std::string lookup(const std::string &soundId, float &volume, float &min, float &max); From c2611d035c44faa25a008f3842d5f043148b3b30 Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Tue, 27 Mar 2012 02:50:45 -0700 Subject: [PATCH 02/11] Use a pair to match the MWWorld::Ptr object and sound ID, instead of nested maps --- apps/openmw/mwsound/soundmanager.cpp | 96 +++++++++++----------------- apps/openmw/mwsound/soundmanager.hpp | 8 +-- 2 files changed, 40 insertions(+), 64 deletions(-) diff --git a/apps/openmw/mwsound/soundmanager.cpp b/apps/openmw/mwsound/soundmanager.cpp index 4d47e5f2cc..f20bf736e1 100644 --- a/apps/openmw/mwsound/soundmanager.cpp +++ b/apps/openmw/mwsound/soundmanager.cpp @@ -114,14 +114,10 @@ namespace MWSound bool SoundManager::isPlaying(MWWorld::Ptr ptr, const std::string &id) const { - SoundMap::const_iterator snditer = mActiveSounds.find(ptr); + SoundMap::const_iterator snditer = mActiveSounds.find(std::make_pair(ptr, id)); if(snditer == mActiveSounds.end()) return false; - IDMap::const_iterator iditer = snditer->second.find(id); - if(iditer == snditer->second.end()) - return false; - return true; } @@ -185,7 +181,7 @@ namespace MWSound std::string filePath = std::string("Sound/")+filename; SoundPtr sound(mOutput->playSound3D(filePath, pos.pos, 1.0f, 1.0f, 100.0f, 20000.0f, false)); - mActiveSounds[ptr]["_say_sound"] = sound; + mActiveSounds[std::make_pair(ptr, std::string("_say_sound"))] = sound; } catch(std::exception &e) { @@ -205,8 +201,8 @@ namespace MWSound try { std::string file = lookup(soundId, volume, min, max); - Sound *sound = mOutput->playSound(file, volume, pitch, loop); - mActiveSounds[MWWorld::Ptr()][soundId] = SoundPtr(sound); + SoundPtr sound = SoundPtr(mOutput->playSound(file, volume, pitch, loop)); + mActiveSounds[std::make_pair(MWWorld::Ptr(), soundId)] = sound; } catch(std::exception &e) { @@ -225,7 +221,7 @@ namespace MWSound std::string file = lookup(soundId, volume, min, max); SoundPtr sound(mOutput->playSound3D(file, pos.pos, volume, pitch, min, max, loop)); - mActiveSounds[untracked?MWWorld::Ptr():ptr][soundId] = sound; + mActiveSounds[std::make_pair((untracked?MWWorld::Ptr():ptr), soundId)] = sound; } catch(std::exception &e) { @@ -237,30 +233,28 @@ namespace MWSound { // Stop a sound and remove it from the list. If soundId="" then // stop all its sounds. - SoundMap::iterator snditer = mActiveSounds.find(ptr); - if(snditer == mActiveSounds.end()) - return; - if(!soundId.empty()) { - IDMap::iterator iditer = snditer->second.find(soundId); - if(iditer != snditer->second.end()) - { - iditer->second->stop(); - snditer->second.erase(iditer); - if(snditer->second.empty()) - mActiveSounds.erase(snditer); - } + SoundMap::iterator snditer = mActiveSounds.find(std::make_pair(ptr, soundId)); + if(snditer == mActiveSounds.end()) + return; + + snditer->second->stop(); + mActiveSounds.erase(snditer); } else { - IDMap::iterator iditer = snditer->second.begin(); - while(iditer != snditer->second.end()) + SoundMap::iterator snditer = mActiveSounds.begin(); + while(snditer != mActiveSounds.end()) { - iditer->second->stop(); - iditer++; + if(snditer->first.first == ptr) + { + snditer->second->stop(); + mActiveSounds.erase(snditer++); + } + else + snditer++; } - mActiveSounds.erase(snditer); } } @@ -270,14 +264,10 @@ namespace MWSound SoundMap::iterator snditer = mActiveSounds.begin(); while(snditer != mActiveSounds.end()) { - if(snditer->first != MWWorld::Ptr() && snditer->first.getCell() == cell) + if(snditer->first.first != MWWorld::Ptr() && + snditer->first.first.getCell() == cell) { - IDMap::iterator iditer = snditer->second.begin(); - while(iditer != snditer->second.end()) - { - iditer->second->stop(); - iditer++; - } + snditer->second->stop(); mActiveSounds.erase(snditer++); } else @@ -287,18 +277,12 @@ namespace MWSound void SoundManager::stopSound(const std::string& soundId) { - SoundMap::iterator snditer = mActiveSounds.find(MWWorld::Ptr()); + SoundMap::iterator snditer = mActiveSounds.find(std::make_pair(MWWorld::Ptr(), soundId)); if(snditer == mActiveSounds.end()) return; - IDMap::iterator iditer = snditer->second.find(soundId); - if(iditer != snditer->second.end()) - { - iditer->second->stop(); - snditer->second.erase(iditer); - if(snditer->second.empty()) - mActiveSounds.erase(snditer); - } + snditer->second->stop(); + mActiveSounds.erase(snditer); } bool SoundManager::getSoundPlaying(MWWorld::Ptr ptr, const std::string& soundId) const @@ -308,16 +292,16 @@ namespace MWSound void SoundManager::updateObject(MWWorld::Ptr ptr) { - SoundMap::iterator snditer = mActiveSounds.find(ptr); - if(snditer == mActiveSounds.end()) - return; - - const ESM::Position &pos = ptr.getCellRef().pos; - IDMap::iterator iditer = snditer->second.begin(); - while(iditer != snditer->second.end()) + SoundMap::iterator snditer = mActiveSounds.begin(); + while(snditer != mActiveSounds.end()) { - iditer->second->update(pos.pos); - iditer++; + if(snditer->first.first == ptr) + { + snditer->second->stop(); + mActiveSounds.erase(snditer++); + } + else + snditer++; } } @@ -406,15 +390,7 @@ namespace MWSound SoundMap::iterator snditer = mActiveSounds.begin(); while(snditer != mActiveSounds.end()) { - IDMap::iterator iditer = snditer->second.begin(); - while(iditer != snditer->second.end()) - { - if(!iditer->second->isPlaying()) - snditer->second.erase(iditer++); - else - iditer++; - } - if(snditer->second.empty()) + if(!snditer->second->isPlaying()) mActiveSounds.erase(snditer++); else snditer++; diff --git a/apps/openmw/mwsound/soundmanager.hpp b/apps/openmw/mwsound/soundmanager.hpp index 8d76ba1008..b7b21b9459 100644 --- a/apps/openmw/mwsound/soundmanager.hpp +++ b/apps/openmw/mwsound/soundmanager.hpp @@ -2,11 +2,11 @@ #define GAME_SOUND_SOUNDMANAGER_H #include +#include +#include #include -#include - #include "../mwworld/ptr.hpp" @@ -41,8 +41,8 @@ namespace MWSound std::string mCurrentPlaylist; typedef boost::shared_ptr SoundPtr; - typedef std::map IDMap; - typedef std::map SoundMap; + typedef std::pair PtrIDPair; + typedef std::map SoundMap; SoundMap mActiveSounds; std::string lookup(const std::string &soundId, From 033faba9c41b45bd19240df280358d3f9aab6693 Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Tue, 27 Mar 2012 03:00:04 -0700 Subject: [PATCH 03/11] Make a function parameter const --- apps/openmw/mwsound/soundmanager.cpp | 2 +- apps/openmw/mwsound/soundmanager.hpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/openmw/mwsound/soundmanager.cpp b/apps/openmw/mwsound/soundmanager.cpp index f20bf736e1..5450c113ae 100644 --- a/apps/openmw/mwsound/soundmanager.cpp +++ b/apps/openmw/mwsound/soundmanager.cpp @@ -258,7 +258,7 @@ namespace MWSound } } - void SoundManager::stopSound(MWWorld::Ptr::CellStore *cell) + void SoundManager::stopSound(const MWWorld::Ptr::CellStore *cell) { // Remove all references to objects belonging to a given cell SoundMap::iterator snditer = mActiveSounds.begin(); diff --git a/apps/openmw/mwsound/soundmanager.hpp b/apps/openmw/mwsound/soundmanager.hpp index b7b21b9459..7f20425afb 100644 --- a/apps/openmw/mwsound/soundmanager.hpp +++ b/apps/openmw/mwsound/soundmanager.hpp @@ -99,7 +99,7 @@ namespace MWSound ///< Stop the given object from playing the given sound, If no soundId is given, /// all sounds for this reference will stop. - void stopSound(MWWorld::Ptr::CellStore *cell); + void stopSound(const MWWorld::Ptr::CellStore *cell); ///< Stop all sounds for the given cell. void stopSound(const std::string& soundId); From f0db2ab82fb928a2c955750478b0a785f2d229ea Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Tue, 27 Mar 2012 03:20:50 -0700 Subject: [PATCH 04/11] Split stopSound3D into separate functions to deal with stopping all sounds on an object --- apps/openmw/mwsound/soundmanager.cpp | 37 ++++++++++++---------------- apps/openmw/mwsound/soundmanager.hpp | 8 +++--- 2 files changed, 21 insertions(+), 24 deletions(-) diff --git a/apps/openmw/mwsound/soundmanager.cpp b/apps/openmw/mwsound/soundmanager.cpp index 5450c113ae..449b5100b0 100644 --- a/apps/openmw/mwsound/soundmanager.cpp +++ b/apps/openmw/mwsound/soundmanager.cpp @@ -231,36 +231,31 @@ namespace MWSound void SoundManager::stopSound3D(MWWorld::Ptr ptr, const std::string& soundId) { - // Stop a sound and remove it from the list. If soundId="" then - // stop all its sounds. - if(!soundId.empty()) - { - SoundMap::iterator snditer = mActiveSounds.find(std::make_pair(ptr, soundId)); - if(snditer == mActiveSounds.end()) - return; + SoundMap::iterator snditer = mActiveSounds.find(std::make_pair(ptr, soundId)); + if(snditer == mActiveSounds.end()) + return; - snditer->second->stop(); - mActiveSounds.erase(snditer); - } - else + snditer->second->stop(); + mActiveSounds.erase(snditer); + } + + void SoundManager::stopSound3D(MWWorld::Ptr ptr) + { + SoundMap::iterator snditer = mActiveSounds.begin(); + while(snditer != mActiveSounds.end()) { - SoundMap::iterator snditer = mActiveSounds.begin(); - while(snditer != mActiveSounds.end()) + if(snditer->first.first == ptr) { - if(snditer->first.first == ptr) - { - snditer->second->stop(); - mActiveSounds.erase(snditer++); - } - else - snditer++; + snditer->second->stop(); + mActiveSounds.erase(snditer++); } + else + snditer++; } } void SoundManager::stopSound(const MWWorld::Ptr::CellStore *cell) { - // Remove all references to objects belonging to a given cell SoundMap::iterator snditer = mActiveSounds.begin(); while(snditer != mActiveSounds.end()) { diff --git a/apps/openmw/mwsound/soundmanager.hpp b/apps/openmw/mwsound/soundmanager.hpp index 7f20425afb..d79aface6a 100644 --- a/apps/openmw/mwsound/soundmanager.hpp +++ b/apps/openmw/mwsound/soundmanager.hpp @@ -95,9 +95,11 @@ namespace MWSound bool untracked=false); ///< Play a sound from an object - void stopSound3D(MWWorld::Ptr reference, const std::string& soundId=""); - ///< Stop the given object from playing the given sound, If no soundId is given, - /// all sounds for this reference will stop. + void stopSound3D(MWWorld::Ptr reference, const std::string& soundId); + ///< Stop the given object from playing the given sound, + + void stopSound3D(MWWorld::Ptr reference); + ///< Stop the given object from playing all sounds. void stopSound(const MWWorld::Ptr::CellStore *cell); ///< Stop all sounds for the given cell. From c6c06f1140aadc0bfc7b5d2d109f00aedd6431d4 Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Tue, 27 Mar 2012 05:59:09 -0700 Subject: [PATCH 05/11] Return SoundPtr objects from the playSound and streamSound methods --- apps/openmw/mwsound/openal_output.cpp | 28 +++++++++++++-------------- apps/openmw/mwsound/openal_output.hpp | 12 ++++++------ apps/openmw/mwsound/sound_output.hpp | 14 ++++++++------ apps/openmw/mwsound/soundmanager.cpp | 8 ++++---- apps/openmw/mwsound/soundmanager.hpp | 2 +- 5 files changed, 33 insertions(+), 31 deletions(-) diff --git a/apps/openmw/mwsound/openal_output.cpp b/apps/openmw/mwsound/openal_output.cpp index c069474034..bb083cb8b1 100644 --- a/apps/openmw/mwsound/openal_output.cpp +++ b/apps/openmw/mwsound/openal_output.cpp @@ -559,11 +559,11 @@ void OpenAL_Output::bufferFinished(ALuint buf) } -Sound* OpenAL_Output::playSound(const std::string &fname, float volume, float pitch, bool loop) +SoundPtr OpenAL_Output::playSound(const std::string &fname, float volume, float pitch, bool loop) { throwALerror(); - std::auto_ptr sound; + boost::shared_ptr sound; ALuint src=0, buf=0; if(mFreeSources.empty()) @@ -604,15 +604,15 @@ Sound* OpenAL_Output::playSound(const std::string &fname, float volume, float pi alSourcePlay(src); throwALerror(); - return sound.release(); + return sound; } -Sound* OpenAL_Output::playSound3D(const std::string &fname, const float *pos, float volume, float pitch, - float min, float max, bool loop) +SoundPtr OpenAL_Output::playSound3D(const std::string &fname, const float *pos, float volume, float pitch, + float min, float max, bool loop) { throwALerror(); - std::auto_ptr sound; + boost::shared_ptr sound; ALuint src=0, buf=0; if(mFreeSources.empty()) @@ -653,15 +653,15 @@ Sound* OpenAL_Output::playSound3D(const std::string &fname, const float *pos, fl alSourcePlay(src); throwALerror(); - return sound.release(); + return sound; } -Sound* OpenAL_Output::streamSound(const std::string &fname, float volume, float pitch) +SoundPtr OpenAL_Output::streamSound(const std::string &fname, float volume, float pitch) { throwALerror(); - std::auto_ptr sound; + boost::shared_ptr sound; ALuint src; if(mFreeSources.empty()) @@ -697,15 +697,15 @@ Sound* OpenAL_Output::streamSound(const std::string &fname, float volume, float throwALerror(); sound->play(); - return sound.release(); + return sound; } -Sound* OpenAL_Output::streamSound3D(const std::string &fname, const float *pos, float volume, float pitch, - float min, float max) +SoundPtr OpenAL_Output::streamSound3D(const std::string &fname, const float *pos, float volume, float pitch, + float min, float max) { throwALerror(); - std::auto_ptr sound; + boost::shared_ptr sound; ALuint src; if(mFreeSources.empty()) @@ -741,7 +741,7 @@ Sound* OpenAL_Output::streamSound3D(const std::string &fname, const float *pos, throwALerror(); sound->play(); - return sound.release(); + return sound; } diff --git a/apps/openmw/mwsound/openal_output.hpp b/apps/openmw/mwsound/openal_output.hpp index e8154e9063..2b0897bdbc 100644 --- a/apps/openmw/mwsound/openal_output.hpp +++ b/apps/openmw/mwsound/openal_output.hpp @@ -42,13 +42,13 @@ namespace MWSound virtual void init(const std::string &devname=""); virtual void deinit(); - virtual Sound *playSound(const std::string &fname, float volume, float pitch, bool loop); - virtual Sound *playSound3D(const std::string &fname, const float *pos, float volume, float pitch, - float min, float max, bool loop); + virtual SoundPtr playSound(const std::string &fname, float volume, float pitch, bool loop); + virtual SoundPtr playSound3D(const std::string &fname, const float *pos, float volume, float pitch, + float min, float max, bool loop); - virtual Sound *streamSound(const std::string &fname, float volume, float pitch); - virtual Sound *streamSound3D(const std::string &fname, const float *pos, float volume, float pitch, - float min, float max); + virtual SoundPtr streamSound(const std::string &fname, float volume, float pitch); + virtual SoundPtr streamSound3D(const std::string &fname, const float *pos, float volume, float pitch, + float min, float max); virtual void updateListener(const float *pos, const float *atdir, const float *updir); diff --git a/apps/openmw/mwsound/sound_output.hpp b/apps/openmw/mwsound/sound_output.hpp index 1722165e49..794383591b 100644 --- a/apps/openmw/mwsound/sound_output.hpp +++ b/apps/openmw/mwsound/sound_output.hpp @@ -4,6 +4,8 @@ #include #include +#include "soundmanager.hpp" + #include "../mwworld/ptr.hpp" namespace MWSound @@ -20,12 +22,12 @@ namespace MWSound virtual void init(const std::string &devname="") = 0; virtual void deinit() = 0; - virtual Sound *playSound(const std::string &fname, float volume, float pitch, bool loop) = 0; - virtual Sound *playSound3D(const std::string &fname, const float *pos, float volume, float pitch, - float min, float max, bool loop) = 0; - virtual Sound *streamSound(const std::string &fname, float volume, float pitch) = 0; - virtual Sound *streamSound3D(const std::string &fname, const float *pos, float volume, float pitch, - float min, float max) = 0; + virtual SoundPtr playSound(const std::string &fname, float volume, float pitch, bool loop) = 0; + virtual SoundPtr playSound3D(const std::string &fname, const float *pos, float volume, float pitch, + float min, float max, bool loop) = 0; + virtual SoundPtr streamSound(const std::string &fname, float volume, float pitch) = 0; + virtual SoundPtr streamSound3D(const std::string &fname, const float *pos, float volume, float pitch, + float min, float max) = 0; virtual void updateListener(const float *pos, const float *atdir, const float *updir) = 0; diff --git a/apps/openmw/mwsound/soundmanager.cpp b/apps/openmw/mwsound/soundmanager.cpp index 449b5100b0..ce5f93acdb 100644 --- a/apps/openmw/mwsound/soundmanager.cpp +++ b/apps/openmw/mwsound/soundmanager.cpp @@ -136,7 +136,7 @@ namespace MWSound { if(mMusic) mMusic->stop(); - mMusic.reset(mOutput->streamSound(filename, 0.4f, 1.0f)); + mMusic = mOutput->streamSound(filename, 0.4f, 1.0f); } catch(std::exception &e) { @@ -180,7 +180,7 @@ namespace MWSound const ESM::Position &pos = ptr.getCellRef().pos; std::string filePath = std::string("Sound/")+filename; - SoundPtr sound(mOutput->playSound3D(filePath, pos.pos, 1.0f, 1.0f, 100.0f, 20000.0f, false)); + SoundPtr sound = mOutput->playSound3D(filePath, pos.pos, 1.0f, 1.0f, 100.0f, 20000.0f, false); mActiveSounds[std::make_pair(ptr, std::string("_say_sound"))] = sound; } catch(std::exception &e) @@ -201,7 +201,7 @@ namespace MWSound try { std::string file = lookup(soundId, volume, min, max); - SoundPtr sound = SoundPtr(mOutput->playSound(file, volume, pitch, loop)); + SoundPtr sound = mOutput->playSound(file, volume, pitch, loop); mActiveSounds[std::make_pair(MWWorld::Ptr(), soundId)] = sound; } catch(std::exception &e) @@ -220,7 +220,7 @@ namespace MWSound const ESM::Position &pos = ptr.getCellRef().pos; std::string file = lookup(soundId, volume, min, max); - SoundPtr sound(mOutput->playSound3D(file, pos.pos, volume, pitch, min, max, loop)); + SoundPtr sound = mOutput->playSound3D(file, pos.pos, volume, pitch, min, max, loop); mActiveSounds[std::make_pair((untracked?MWWorld::Ptr():ptr), soundId)] = sound; } catch(std::exception &e) diff --git a/apps/openmw/mwsound/soundmanager.hpp b/apps/openmw/mwsound/soundmanager.hpp index d79aface6a..539e818885 100644 --- a/apps/openmw/mwsound/soundmanager.hpp +++ b/apps/openmw/mwsound/soundmanager.hpp @@ -28,6 +28,7 @@ namespace MWSound class Sound; typedef boost::shared_ptr DecoderPtr; + typedef boost::shared_ptr SoundPtr; class SoundManager { @@ -40,7 +41,6 @@ namespace MWSound boost::shared_ptr mMusic; std::string mCurrentPlaylist; - typedef boost::shared_ptr SoundPtr; typedef std::pair PtrIDPair; typedef std::map SoundMap; SoundMap mActiveSounds; From 089c3409354dc776e7a921d4c0c34903c2322e22 Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Wed, 28 Mar 2012 03:48:51 -0700 Subject: [PATCH 06/11] Switch the map so the SoundPtr is used as a key --- apps/openmw/mwsound/soundmanager.cpp | 79 ++++++++++++++++------------ apps/openmw/mwsound/soundmanager.hpp | 2 +- 2 files changed, 47 insertions(+), 34 deletions(-) diff --git a/apps/openmw/mwsound/soundmanager.cpp b/apps/openmw/mwsound/soundmanager.cpp index ce5f93acdb..a89c34ded0 100644 --- a/apps/openmw/mwsound/soundmanager.cpp +++ b/apps/openmw/mwsound/soundmanager.cpp @@ -114,11 +114,14 @@ namespace MWSound bool SoundManager::isPlaying(MWWorld::Ptr ptr, const std::string &id) const { - SoundMap::const_iterator snditer = mActiveSounds.find(std::make_pair(ptr, id)); - if(snditer == mActiveSounds.end()) - return false; - - return true; + SoundMap::const_iterator snditer = mActiveSounds.begin(); + while(snditer != mActiveSounds.end()) + { + if(snditer->second.first == ptr && snditer->second.second == id) + return snditer->first->isPlaying(); + snditer++; + } + return false; } @@ -181,7 +184,7 @@ namespace MWSound std::string filePath = std::string("Sound/")+filename; SoundPtr sound = mOutput->playSound3D(filePath, pos.pos, 1.0f, 1.0f, 100.0f, 20000.0f, false); - mActiveSounds[std::make_pair(ptr, std::string("_say_sound"))] = sound; + mActiveSounds[sound] = std::make_pair(ptr, std::string("_say_sound")); } catch(std::exception &e) { @@ -201,8 +204,9 @@ namespace MWSound try { std::string file = lookup(soundId, volume, min, max); + SoundPtr sound = mOutput->playSound(file, volume, pitch, loop); - mActiveSounds[std::make_pair(MWWorld::Ptr(), soundId)] = sound; + mActiveSounds[sound] = std::make_pair(MWWorld::Ptr(), soundId); } catch(std::exception &e) { @@ -221,7 +225,8 @@ namespace MWSound std::string file = lookup(soundId, volume, min, max); SoundPtr sound = mOutput->playSound3D(file, pos.pos, volume, pitch, min, max, loop); - mActiveSounds[std::make_pair((untracked?MWWorld::Ptr():ptr), soundId)] = sound; + mActiveSounds[sound] = (!untracked ? std::make_pair(ptr, soundId) : + std::make_pair(MWWorld::Ptr(), std::string())); } catch(std::exception &e) { @@ -231,12 +236,17 @@ namespace MWSound void SoundManager::stopSound3D(MWWorld::Ptr ptr, const std::string& soundId) { - SoundMap::iterator snditer = mActiveSounds.find(std::make_pair(ptr, soundId)); - if(snditer == mActiveSounds.end()) - return; - - snditer->second->stop(); - mActiveSounds.erase(snditer); + SoundMap::iterator snditer = mActiveSounds.begin(); + while(snditer != mActiveSounds.end()) + { + if(snditer->second.first == ptr && snditer->second.second == soundId) + { + snditer->first->stop(); + mActiveSounds.erase(snditer++); + } + else + snditer++; + } } void SoundManager::stopSound3D(MWWorld::Ptr ptr) @@ -244,9 +254,9 @@ namespace MWSound SoundMap::iterator snditer = mActiveSounds.begin(); while(snditer != mActiveSounds.end()) { - if(snditer->first.first == ptr) + if(snditer->second.first == ptr) { - snditer->second->stop(); + snditer->first->stop(); mActiveSounds.erase(snditer++); } else @@ -259,10 +269,10 @@ namespace MWSound SoundMap::iterator snditer = mActiveSounds.begin(); while(snditer != mActiveSounds.end()) { - if(snditer->first.first != MWWorld::Ptr() && - snditer->first.first.getCell() == cell) + if(snditer->second.first != MWWorld::Ptr() && + snditer->second.first.getCell() == cell) { - snditer->second->stop(); + snditer->first->stop(); mActiveSounds.erase(snditer++); } else @@ -272,12 +282,18 @@ namespace MWSound void SoundManager::stopSound(const std::string& soundId) { - SoundMap::iterator snditer = mActiveSounds.find(std::make_pair(MWWorld::Ptr(), soundId)); - if(snditer == mActiveSounds.end()) - return; - - snditer->second->stop(); - mActiveSounds.erase(snditer); + SoundMap::iterator snditer = mActiveSounds.begin(); + while(snditer != mActiveSounds.end()) + { + if(snditer->second.first == MWWorld::Ptr() && + snditer->second.second == soundId) + { + snditer->first->stop(); + mActiveSounds.erase(snditer++); + } + else + snditer++; + } } bool SoundManager::getSoundPlaying(MWWorld::Ptr ptr, const std::string& soundId) const @@ -287,16 +303,13 @@ namespace MWSound void SoundManager::updateObject(MWWorld::Ptr ptr) { + const ESM::Position &pos = ptr.getCellRef().pos; SoundMap::iterator snditer = mActiveSounds.begin(); while(snditer != mActiveSounds.end()) { - if(snditer->first.first == ptr) - { - snditer->second->stop(); - mActiveSounds.erase(snditer++); - } - else - snditer++; + if(snditer->second.first == ptr) + snditer->first->update(pos.pos); + snditer++; } } @@ -385,7 +398,7 @@ namespace MWSound SoundMap::iterator snditer = mActiveSounds.begin(); while(snditer != mActiveSounds.end()) { - if(!snditer->second->isPlaying()) + if(!snditer->first->isPlaying()) mActiveSounds.erase(snditer++); else snditer++; diff --git a/apps/openmw/mwsound/soundmanager.hpp b/apps/openmw/mwsound/soundmanager.hpp index 539e818885..5808b01421 100644 --- a/apps/openmw/mwsound/soundmanager.hpp +++ b/apps/openmw/mwsound/soundmanager.hpp @@ -42,7 +42,7 @@ namespace MWSound std::string mCurrentPlaylist; typedef std::pair PtrIDPair; - typedef std::map SoundMap; + typedef std::map SoundMap; SoundMap mActiveSounds; std::string lookup(const std::string &soundId, From c072babd17f5cfeec9f6608ab2725e30d44507dd Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Wed, 28 Mar 2012 04:56:40 -0700 Subject: [PATCH 07/11] Better handle bad OpenAL source counts --- apps/openmw/mwsound/openal_output.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/openmw/mwsound/openal_output.cpp b/apps/openmw/mwsound/openal_output.cpp index bb083cb8b1..6e5806ee37 100644 --- a/apps/openmw/mwsound/openal_output.cpp +++ b/apps/openmw/mwsound/openal_output.cpp @@ -415,12 +415,12 @@ void OpenAL_Output::init(const std::string &devname) alDistanceModel(AL_LINEAR_DISTANCE_CLAMPED); throwALerror(); - ALCint maxmono, maxstereo; + ALCint maxmono=0, maxstereo=0; alcGetIntegerv(mDevice, ALC_MONO_SOURCES, 1, &maxmono); alcGetIntegerv(mDevice, ALC_STEREO_SOURCES, 1, &maxstereo); throwALCerror(mDevice); - mFreeSources.resize(std::min(maxmono+maxstereo, 256)); + mFreeSources.resize(std::min(maxmono+maxstereo, 256)); for(size_t i = 0;i < mFreeSources.size();i++) { ALuint src; From 7008bd2fe1e8b1e6e275bfd00d8025345af6b6f1 Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Wed, 28 Mar 2012 04:58:47 -0700 Subject: [PATCH 08/11] Store some sound properties in the Sound class --- apps/openmw/mwsound/sound.hpp | 12 +++++++++- apps/openmw/mwsound/soundmanager.cpp | 34 ++++++++++++++++++++-------- 2 files changed, 36 insertions(+), 10 deletions(-) diff --git a/apps/openmw/mwsound/sound.hpp b/apps/openmw/mwsound/sound.hpp index f9e7ab4278..a5617bc5a1 100644 --- a/apps/openmw/mwsound/sound.hpp +++ b/apps/openmw/mwsound/sound.hpp @@ -12,8 +12,18 @@ namespace MWSound Sound& operator=(const Sound &rhs); Sound(const Sound &rhs); + protected: + float mVolume; /* NOTE: Real volume = mVolume*mBaseVolume */ + float mBaseVolume; + float mMinDistance; + float mMaxDistance; + public: - Sound() { } + Sound() : mVolume(1.0f) + , mBaseVolume(1.0f) + , mMinDistance(20.0f) /* 1 * min_range_scale */ + , mMaxDistance(12750.0f) /* 255 * max_range_scale */ + { } virtual ~Sound() { } friend class OpenAL_Output; diff --git a/apps/openmw/mwsound/soundmanager.cpp b/apps/openmw/mwsound/soundmanager.cpp index a89c34ded0..8e2ef3a278 100644 --- a/apps/openmw/mwsound/soundmanager.cpp +++ b/apps/openmw/mwsound/soundmanager.cpp @@ -140,6 +140,7 @@ namespace MWSound if(mMusic) mMusic->stop(); mMusic = mOutput->streamSound(filename, 0.4f, 1.0f); + mMusic->mBaseVolume = 0.4f; } catch(std::exception &e) { @@ -180,10 +181,13 @@ namespace MWSound try { // The range values are not tested - const ESM::Position &pos = ptr.getCellRef().pos; + float basevol = 1.0f; /* TODO: volume settings */ std::string filePath = std::string("Sound/")+filename; + const ESM::Position &pos = ptr.getCellRef().pos; + + SoundPtr sound = mOutput->playSound3D(filePath, pos.pos, basevol, 1.0f, 20.0f, 12750.0f, false); + sound->mBaseVolume = basevol; - SoundPtr sound = mOutput->playSound3D(filePath, pos.pos, 1.0f, 1.0f, 100.0f, 20000.0f, false); mActiveSounds[sound] = std::make_pair(ptr, std::string("_say_sound")); } catch(std::exception &e) @@ -200,12 +204,18 @@ namespace MWSound void SoundManager::playSound(const std::string& soundId, float volume, float pitch, bool loop) { - float min, max; try { - std::string file = lookup(soundId, volume, min, max); + float basevol = 1.0f; /* TODO: volume settings */ + float min, max; + std::string file = lookup(soundId, basevol, min, max); + + SoundPtr sound = mOutput->playSound(file, volume*basevol, pitch, loop); + sound->mVolume = volume; + sound->mBaseVolume = basevol; + sound->mMinDistance = min; + sound->mMaxDistance = max; - SoundPtr sound = mOutput->playSound(file, volume, pitch, loop); mActiveSounds[sound] = std::make_pair(MWWorld::Ptr(), soundId); } catch(std::exception &e) @@ -217,16 +227,22 @@ namespace MWSound void SoundManager::playSound3D(MWWorld::Ptr ptr, const std::string& soundId, float volume, float pitch, bool loop, bool untracked) { - float min, max; try { // Look up the sound in the ESM data + float basevol = 1.0f; /* TODO: volume settings */ + float min, max; + std::string file = lookup(soundId, basevol, min, max); const ESM::Position &pos = ptr.getCellRef().pos; - std::string file = lookup(soundId, volume, min, max); - SoundPtr sound = mOutput->playSound3D(file, pos.pos, volume, pitch, min, max, loop); + SoundPtr sound = mOutput->playSound3D(file, pos.pos, volume*basevol, pitch, min, max, loop); + sound->mVolume = volume; + sound->mBaseVolume = basevol; + sound->mMinDistance = min; + sound->mMaxDistance = max; + mActiveSounds[sound] = (!untracked ? std::make_pair(ptr, soundId) : - std::make_pair(MWWorld::Ptr(), std::string())); + std::make_pair(MWWorld::Ptr(), soundId)); } catch(std::exception &e) { From a3291ef360f3d16212252005f181c49e6efcef3e Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Wed, 28 Mar 2012 05:19:35 -0700 Subject: [PATCH 09/11] Add a sound method to update the volume --- apps/openmw/mwsound/openal_output.cpp | 16 ++++++++++++++++ apps/openmw/mwsound/sound.hpp | 1 + 2 files changed, 17 insertions(+) diff --git a/apps/openmw/mwsound/openal_output.cpp b/apps/openmw/mwsound/openal_output.cpp index 6e5806ee37..032d79ab84 100644 --- a/apps/openmw/mwsound/openal_output.cpp +++ b/apps/openmw/mwsound/openal_output.cpp @@ -89,6 +89,7 @@ public: virtual void stop(); virtual bool isPlaying(); + virtual void setVolume(float volume); virtual void update(const float *pos); void play(); @@ -252,6 +253,13 @@ bool OpenAL_SoundStream::isPlaying() return !mIsFinished; } +void OpenAL_SoundStream::setVolume(float volume) +{ + alSourcef(mSource, AL_GAIN, volume*mBaseVolume); + throwALerror(); + mVolume = volume; +} + void OpenAL_SoundStream::update(const float *pos) { alSource3f(mSource, AL_POSITION, pos[0], pos[2], -pos[1]); @@ -329,6 +337,7 @@ public: virtual void stop(); virtual bool isPlaying(); + virtual void setVolume(float volume); virtual void update(const float *pos); }; @@ -361,6 +370,13 @@ bool OpenAL_Sound::isPlaying() return state==AL_PLAYING; } +void OpenAL_Sound::setVolume(float volume) +{ + alSourcef(mSource, AL_GAIN, volume*mBaseVolume); + throwALerror(); + mVolume = volume; +} + void OpenAL_Sound::update(const float *pos) { alSource3f(mSource, AL_POSITION, pos[0], pos[2], -pos[1]); diff --git a/apps/openmw/mwsound/sound.hpp b/apps/openmw/mwsound/sound.hpp index a5617bc5a1..b5d010aa00 100644 --- a/apps/openmw/mwsound/sound.hpp +++ b/apps/openmw/mwsound/sound.hpp @@ -7,6 +7,7 @@ namespace MWSound { virtual void stop() = 0; virtual bool isPlaying() = 0; + virtual void setVolume(float volume) = 0; virtual void update(const float *pos) = 0; Sound& operator=(const Sound &rhs); From 293f33914e78b8d8aeb44ff06a4cf487a194c85b Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Wed, 28 Mar 2012 05:35:51 -0700 Subject: [PATCH 10/11] Use a deque fpr OpenAL's free sources --- apps/openmw/mwsound/openal_output.cpp | 43 ++++++++++++++------------- apps/openmw/mwsound/openal_output.hpp | 8 ++--- 2 files changed, 26 insertions(+), 25 deletions(-) diff --git a/apps/openmw/mwsound/openal_output.cpp b/apps/openmw/mwsound/openal_output.cpp index 032d79ab84..ea49eb2f20 100644 --- a/apps/openmw/mwsound/openal_output.cpp +++ b/apps/openmw/mwsound/openal_output.cpp @@ -436,19 +436,22 @@ void OpenAL_Output::init(const std::string &devname) alcGetIntegerv(mDevice, ALC_STEREO_SOURCES, 1, &maxstereo); throwALCerror(mDevice); - mFreeSources.resize(std::min(maxmono+maxstereo, 256)); - for(size_t i = 0;i < mFreeSources.size();i++) + try { - ALuint src; - alGenSources(1, &src); - if(alGetError() != AL_NO_ERROR) + ALCuint maxtotal = std::min(maxmono+maxstereo, 256); + for(size_t i = 0;i < maxtotal;i++) { - mFreeSources.resize(i); - break; + ALuint src = 0; + alGenSources(1, &src); + throwALerror(); + mFreeSources.push_back(src); } - mFreeSources[i] = src; } - if(mFreeSources.size() == 0) + catch(std::exception &e) + { + std::cout <<"Error: "<removeAll(); - if(!mFreeSources.empty()) + while(!mFreeSources.empty()) { - alDeleteSources(mFreeSources.size(), mFreeSources.data()); - mFreeSources.clear(); + alDeleteSources(1, &mFreeSources.front()); + mFreeSources.pop_front(); } mBufferRefs.clear(); @@ -584,8 +587,8 @@ SoundPtr OpenAL_Output::playSound(const std::string &fname, float volume, float if(mFreeSources.empty()) fail("No free sources"); - src = mFreeSources.back(); - mFreeSources.pop_back(); + src = mFreeSources.front(); + mFreeSources.pop_front(); try { @@ -633,8 +636,8 @@ SoundPtr OpenAL_Output::playSound3D(const std::string &fname, const float *pos, if(mFreeSources.empty()) fail("No free sources"); - src = mFreeSources.back(); - mFreeSources.pop_back(); + src = mFreeSources.front(); + mFreeSources.pop_front(); try { @@ -682,8 +685,8 @@ SoundPtr OpenAL_Output::streamSound(const std::string &fname, float volume, floa if(mFreeSources.empty()) fail("No free sources"); - src = mFreeSources.back(); - mFreeSources.pop_back(); + src = mFreeSources.front(); + mFreeSources.pop_front(); try { @@ -726,8 +729,8 @@ SoundPtr OpenAL_Output::streamSound3D(const std::string &fname, const float *pos if(mFreeSources.empty()) fail("No free sources"); - src = mFreeSources.back(); - mFreeSources.pop_back(); + src = mFreeSources.front(); + mFreeSources.pop_front(); try { diff --git a/apps/openmw/mwsound/openal_output.hpp b/apps/openmw/mwsound/openal_output.hpp index 2b0897bdbc..d288a62f39 100644 --- a/apps/openmw/mwsound/openal_output.hpp +++ b/apps/openmw/mwsound/openal_output.hpp @@ -21,8 +21,9 @@ namespace MWSound ALCdevice *mDevice; ALCcontext *mContext; - typedef std::vector IDVec; - IDVec mFreeSources; + typedef std::deque IDDq; + IDDq mFreeSources; + IDDq mUnusedBuffers; typedef std::map NameMap; NameMap mBufferCache; @@ -30,9 +31,6 @@ namespace MWSound typedef std::map IDRefMap; IDRefMap mBufferRefs; - typedef std::deque IDDq; - IDDq mUnusedBuffers; - uint64_t mBufferCacheMemSize; ALuint getBuffer(const std::string &fname); From be337ef7cc99bb5230105e8f19ba943dd06cb60c Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Wed, 28 Mar 2012 06:08:25 -0700 Subject: [PATCH 11/11] Return SoundPtr objects from playSound[3D] Note that each Sound object currently contains "precious" resources even after the sound is stopped. The reference should be reliquished as soon as it's no longer needed (the SoundManager will make sure the sound continues to play until it's finished). --- apps/openmw/mwsound/sound.hpp | 7 ++++--- apps/openmw/mwsound/soundmanager.cpp | 18 ++++++++++++------ apps/openmw/mwsound/soundmanager.hpp | 8 ++++---- 3 files changed, 20 insertions(+), 13 deletions(-) diff --git a/apps/openmw/mwsound/sound.hpp b/apps/openmw/mwsound/sound.hpp index b5d010aa00..2cbd48d961 100644 --- a/apps/openmw/mwsound/sound.hpp +++ b/apps/openmw/mwsound/sound.hpp @@ -5,9 +5,6 @@ namespace MWSound { class Sound { - virtual void stop() = 0; - virtual bool isPlaying() = 0; - virtual void setVolume(float volume) = 0; virtual void update(const float *pos) = 0; Sound& operator=(const Sound &rhs); @@ -20,6 +17,10 @@ namespace MWSound float mMaxDistance; public: + virtual void stop() = 0; + virtual bool isPlaying() = 0; + virtual void setVolume(float volume) = 0; + Sound() : mVolume(1.0f) , mBaseVolume(1.0f) , mMinDistance(20.0f) /* 1 * min_range_scale */ diff --git a/apps/openmw/mwsound/soundmanager.cpp b/apps/openmw/mwsound/soundmanager.cpp index 8e2ef3a278..ad9e47f729 100644 --- a/apps/openmw/mwsound/soundmanager.cpp +++ b/apps/openmw/mwsound/soundmanager.cpp @@ -185,7 +185,8 @@ namespace MWSound std::string filePath = std::string("Sound/")+filename; const ESM::Position &pos = ptr.getCellRef().pos; - SoundPtr sound = mOutput->playSound3D(filePath, pos.pos, basevol, 1.0f, 20.0f, 12750.0f, false); + SoundPtr sound = mOutput->playSound3D(filePath, pos.pos, basevol, 1.0f, + 20.0f, 12750.0f, false); sound->mBaseVolume = basevol; mActiveSounds[sound] = std::make_pair(ptr, std::string("_say_sound")); @@ -202,15 +203,16 @@ namespace MWSound } - void SoundManager::playSound(const std::string& soundId, float volume, float pitch, bool loop) + SoundPtr SoundManager::playSound(const std::string& soundId, float volume, float pitch, bool loop) { + SoundPtr sound; try { float basevol = 1.0f; /* TODO: volume settings */ float min, max; std::string file = lookup(soundId, basevol, min, max); - SoundPtr sound = mOutput->playSound(file, volume*basevol, pitch, loop); + sound = mOutput->playSound(file, volume*basevol, pitch, loop); sound->mVolume = volume; sound->mBaseVolume = basevol; sound->mMinDistance = min; @@ -222,11 +224,14 @@ namespace MWSound { std::cout <<"Sound Error: "<playSound3D(file, pos.pos, volume*basevol, pitch, min, max, loop); + sound = mOutput->playSound3D(file, pos.pos, volume*basevol, pitch, min, max, loop); sound->mVolume = volume; sound->mBaseVolume = basevol; sound->mMinDistance = min; @@ -248,6 +253,7 @@ namespace MWSound { std::cout <<"Sound Error: "<