diff --git a/apps/openmw/engine.cpp b/apps/openmw/engine.cpp index 4765ceadc5..89cda8f7c9 100644 --- a/apps/openmw/engine.cpp +++ b/apps/openmw/engine.cpp @@ -341,7 +341,6 @@ void OMW::Engine::go() // Create sound system mEnvironment.mSoundManager = new MWSound::SoundManager(mOgre->getRoot(), mOgre->getCamera(), - mEnvironment.mWorld->getStore(), mDataDirs, mUseSound, mFSStrict, mEnvironment); diff --git a/apps/openmw/mwsound/soundmanager.cpp b/apps/openmw/mwsound/soundmanager.cpp index 6795eff195..c269c02368 100644 --- a/apps/openmw/mwsound/soundmanager.cpp +++ b/apps/openmw/mwsound/soundmanager.cpp @@ -45,7 +45,7 @@ using namespace Mangle::Sound; typedef OEngine::Sound::SoundManager OEManager; -typedef OEngine::Sound::SoundManagerPtr OEManagerPtr; +////typedef OEngine::Sound::SoundManagerPtr OEManagerPtr; // Set the position on a sound based on a Ptr. static void setPos(SoundPtr &snd, const MWWorld::Ptr ref) @@ -60,73 +60,53 @@ static void setPos(SoundPtr &snd, const MWWorld::Ptr ref) namespace MWSound { - struct SoundManager::SoundImpl - { - /* This is the sound manager. It loades, stores and deletes - sounds based on the sound factory it is given. - */ - OEManagerPtr mgr; - SoundPtr music; - - /* This class calls update() on the sound manager each frame - using and Ogre::FrameListener - */ - Mangle::Sound::OgreOutputUpdater updater; - - /* This class tracks the movement of an Ogre::Camera and moves - a sound listener automatically to follow it. - */ - Mangle::Sound::OgreListenerMover cameraTracker; - - const ESMS::ESMStore &store; - - typedef std::map IDMap; - typedef std::map PtrMap; - PtrMap sounds; - - // This is used for case insensitive and slash-type agnostic file - // finding. It takes DOS paths (any case, \\ slashes or / slashes) - // relative to the sound dir, and translates them into full paths - // of existing files in the filesystem, if they exist. - bool FSstrict; - FileFinder::LessTreeFileFinder files; - FileFinder::StrictTreeFileFinder strict; - FileFinder::LessTreeFileFinder musicpath; - FileFinder::StrictTreeFileFinder musicpathStrict; - - SoundImpl(Ogre::Root *root, Ogre::Camera *camera, const ESMS::ESMStore &str, - const Files::PathContainer& soundDir, - const Files::PathContainer& musicDir, - bool fsstrict) - : mgr(new OEManager(SoundFactoryPtr(new SOUND_FACTORY))) - , updater(mgr) - , cameraTracker(mgr) - , store(str) - , FSstrict(fsstrict) - , files(soundDir) - , strict(soundDir) - , musicpath(musicDir) - , musicpathStrict(musicDir) + + SoundManager::SoundManager(Ogre::Root *root, Ogre::Camera *camera, + const Files::PathContainer& dataDirs, + bool useSound, bool fsstrict, MWWorld::Environment& environment) + : fsStrict(fsstrict) + , mEnvironment(environment) + , mgr(new OEManager(SoundFactoryPtr(new SOUND_FACTORY))) + , updater(mgr) + , cameraTracker(mgr) { + for (Files::PathContainer::const_iterator it = dataDirs.begin(); it != dataDirs.end(); ++it) + { + MP3Lookup((*it) / "Music/Explore/"); + } - std::cout << "Sound output: " << SOUND_OUT << std::endl; - std::cout << "Sound decoder: " << SOUND_IN << std::endl; - // Attach the camera to the camera tracker - cameraTracker.followCamera(camera); + if(useSound) + { + Files::PathContainer soundDirs;; + for (Files::PathContainer::const_iterator it = dataDirs.begin(); it != dataDirs.end(); ++it) + { + soundDirs.push_back( *it / std::string("Sound")); + } + soundfiles = soundDirs; + strict = soundDirs; + musicpath = dataDirs; + musicpathStrict = dataDirs; + std::cout << "Sound output: " << SOUND_OUT << std::endl; + std::cout << "Sound decoder: " << SOUND_IN << std::endl; + // Attach the camera to the camera tracker + cameraTracker.followCamera(camera); + + // Tell Ogre to update the sound system each frame + root->addFrameListener(&updater); + } - // Tell Ogre to update the sound system each frame - root->addFrameListener(&updater); - } + test.name = ""; + total = 0; + } - ~SoundImpl() + SoundManager::~SoundManager() { Ogre::Root::getSingleton().removeFrameListener(&updater); cameraTracker.unfollowCamera(); } - - static std::string toMp3(std::string str) + static std::string SoundManager::toMp3(std::string str) { std::string::size_type i = str.rfind('.'); if(str.find('/', i) == std::string::npos && @@ -137,10 +117,10 @@ namespace MWSound return str; } - bool hasFile(const std::string &str, bool music = false) + bool SoundManager::hasFile(const std::string &str, bool music) { bool found = false; - if(!FSstrict) + if(!fsStrict) { if(music) { @@ -153,10 +133,10 @@ namespace MWSound } else { - found = files.has(str); + found = soundfiles.has(str); if (!found) { - found = files.has(toMp3(str)); + found = soundfiles.has(toMp3(str)); } } } @@ -186,22 +166,22 @@ namespace MWSound // Convert a Morrowind sound path (eg. Fx\funny.wav) to full path // with proper slash conversion (eg. datadir/Sound/Fx/funny.wav) - std::string convertPath(const std::string &str, bool music = false) + std::string SoundManager::convertPath(const std::string &str, bool music) { - if(FSstrict == false) + if(fsStrict == false) { // Search and return if(music && musicpath.has(str)) return musicpath.lookup(str); - else if(files.has(str)) - return files.lookup(str); + else if(soundfiles.has(str)) + return soundfiles.lookup(str); // Try mp3 if the wav wasn't found std::string mp3 = toMp3(str); if(music && musicpath.has(mp3)) return musicpath.lookup(mp3); - else if(files.has(mp3)) - return files.lookup(mp3); + else if(soundfiles.has(mp3)) + return soundfiles.lookup(mp3); } else { @@ -225,10 +205,10 @@ namespace MWSound // Convert a soundId to file name, and modify the volume // according to the sounds local volume setting, minRange and // maxRange. - std::string lookup(const std::string &soundId, + std::string SoundManager::lookup(const std::string &soundId, float &volume, float &min, float &max) { - const ESM::Sound *snd = store.sounds.search(soundId); + const ESM::Sound *snd = mEnvironment.mWorld->getStore().sounds.search(soundId); if(snd == NULL) return ""; if(snd->data.volume == 0) @@ -253,7 +233,7 @@ namespace MWSound } // Add a sound to the list and play it - void add(const std::string &file, + void SoundManager::add(const std::string &file, MWWorld::Ptr ptr, const std::string &id, float volume, float pitch, @@ -280,7 +260,7 @@ namespace MWSound // Clears all the sub-elements of a given iterator, and then // removes it from 'sounds'. - void clearAll(PtrMap::iterator& it) + void SoundManager::clearAll(PtrMap::iterator& it) { IDMap::iterator sit = it->second.begin(); @@ -301,7 +281,7 @@ namespace MWSound // Stop a sound and remove it from the list. If id="" then // remove the entire object and stop all its sounds. - void remove(MWWorld::Ptr ptr, const std::string &id = "") + void SoundManager::remove(MWWorld::Ptr ptr, const std::string &id) { PtrMap::iterator it = sounds.find(ptr); if(it != sounds.end()) @@ -324,7 +304,7 @@ namespace MWSound } } - bool isPlaying(MWWorld::Ptr ptr, const std::string &id) const + bool SoundManager::isPlaying(MWWorld::Ptr ptr, const std::string &id) const { PtrMap::const_iterator it = sounds.find(ptr); if(it != sounds.end()) @@ -348,7 +328,7 @@ namespace MWSound } // Remove all references to objects belonging to a given cell - void removeCell(const MWWorld::Ptr::CellStore *cell) + void SoundManager::removeCell(const MWWorld::Ptr::CellStore *cell) { PtrMap::iterator it2, it = sounds.begin(); while(it != sounds.end()) @@ -360,7 +340,7 @@ namespace MWSound } } - void updatePositions(MWWorld::Ptr ptr) + void SoundManager::updatePositions(MWWorld::Ptr ptr) { // Find the reference (if any) PtrMap::iterator it = sounds.find(ptr); @@ -378,61 +358,27 @@ namespace MWSound } } } - }; /* SoundImpl */ + void SoundManager::streamMusicFull(const std::string& filename) { - if(!mData) return; - // Play the sound and tell it to stream, if possible. TODO: // Store the reference, the jukebox will need to check status, // control volume etc. - if (mData->music) - mData->music->stop(); - mData->music = mData->mgr->load(filename); - mData->music->setStreaming(true); - mData->music->setVolume(0.4); - mData->music->play(); + if (music) + music->stop(); + music = mgr->load(filename); + music->setStreaming(true); + music->setVolume(0.4); + music->play(); } - SoundManager::SoundManager(Ogre::Root *root, Ogre::Camera *camera, - const ESMS::ESMStore &store, const Files::PathContainer& dataDirs, - bool useSound, bool fsstrict, MWWorld::Environment& environment) - : mData(NULL) - , fsStrict(fsstrict) - , mEnvironment(environment) - { - for (Files::PathContainer::const_iterator it = dataDirs.begin(); it != dataDirs.end(); ++it) - { - MP3Lookup((*it) / "Music/Explore/"); - } - - if(useSound) - { - Files::PathContainer soundDirs;; - for (Files::PathContainer::const_iterator it = dataDirs.begin(); it != dataDirs.end(); ++it) - { - soundDirs.push_back( *it / std::string("Sound")); - } - mData = new SoundImpl(root, camera, store, soundDirs /* Sound */, dataDirs /* Music */, fsstrict); - } - - test.name = ""; - total = 0; - } - - SoundManager::~SoundManager() - { - if(mData) - delete mData; - } - void SoundManager::streamMusic(const std::string& filename) { - if(mData->hasFile(filename, true)) + if(hasFile(filename, true)) { - streamMusicFull(mData->convertPath(filename, true)); + streamMusicFull(convertPath(filename, true)); } } @@ -476,45 +422,36 @@ namespace MWSound bool SoundManager::isMusicPlaying() { bool test = false; - if(mData && mData->music) + if(music) { - test = mData->music->isPlaying(); + test = music->isPlaying(); } return test; } - SoundManager::SoundImpl SoundManager::getMData() - { - // bool test = mData->music->isPlaying(); - return *mData; - } - void SoundManager::say (MWWorld::Ptr ptr, const std::string& filename) { // The range values are not tested - if(!mData) return; - if(mData->hasFile(filename)) - mData->add(mData->convertPath(filename), ptr, "_say_sound", 1, 1, 100, 20000, false); + if(hasFile(filename)) + add(convertPath(filename), ptr, "_say_sound", 1, 1, 100, 20000, false); else std::cout << "Sound file " << filename << " not found, skipping.\n"; } bool SoundManager::sayDone (MWWorld::Ptr ptr) const { - if(!mData) return false; - return !mData->isPlaying(ptr, "_say_sound"); + return !isPlaying(ptr, "_say_sound"); } void SoundManager::playSound(const std::string& soundId, float volume, float pitch) { - if(!mData) return; // Play and forget float min, max; - const std::string &file = mData->lookup(soundId, volume, min, max); + const std::string &file = ookup(soundId, volume, min, max); if (file != "") { - SoundPtr snd = mData->mgr->load(file); + SoundPtr snd = mgr->load(file); snd->setVolume(volume); snd->setRange(min,max); snd->setPitch(pitch); @@ -525,42 +462,34 @@ namespace MWSound void SoundManager::playSound3D (MWWorld::Ptr ptr, const std::string& soundId, float volume, float pitch, bool loop) { - if(!mData) return; - // Look up the sound in the ESM data float min, max; - const std::string &file = mData->lookup(soundId, volume, min, max); + const std::string &file = lookup(soundId, volume, min, max); if (file != "") - mData->add(file, ptr, soundId, volume, pitch, min, max, loop); + add(file, ptr, soundId, volume, pitch, min, max, loop); } void SoundManager::stopSound3D (MWWorld::Ptr ptr, const std::string& soundId) { - if(!mData) return; - mData->remove(ptr, soundId); + remove(ptr, soundId); } void SoundManager::stopSound (MWWorld::Ptr::CellStore *cell) { - if(!mData) return; - mData->removeCell(cell); + removeCell(cell); } bool SoundManager::getSoundPlaying (MWWorld::Ptr ptr, const std::string& soundId) const { // Mark all sounds as playing, otherwise the scripts will just // keep trying to play them every frame. - if(!mData) return true; - return mData->isPlaying(ptr, soundId); + return isPlaying(ptr, soundId); } void SoundManager::updateObject(MWWorld::Ptr ptr) { - if (mData != NULL) - { - mData->updatePositions(ptr); - } + updatePositions(ptr); } void SoundManager::update (float duration) diff --git a/apps/openmw/mwsound/soundmanager.hpp b/apps/openmw/mwsound/soundmanager.hpp index 5c3f473f2e..cde8475e94 100644 --- a/apps/openmw/mwsound/soundmanager.hpp +++ b/apps/openmw/mwsound/soundmanager.hpp @@ -6,10 +6,14 @@ #include #include -#include "../mwworld/ptr.hpp" +#include +#include + #include #include +#include +#include "../mwworld/ptr.hpp" namespace Ogre @@ -18,6 +22,17 @@ namespace Ogre class Camera; } +namespace Mangle +{ + namespace Sound + { + typedef boost::shared_ptr SoundPtr; + //struct OgreOutputUpdater; + } +} + +typedef OEngine::Sound::SoundManagerPtr OEManagerPtr; + namespace ESMS { struct ESMStore; @@ -30,14 +45,8 @@ namespace MWWorld namespace MWSound { - //SoundPtr *music; class SoundManager { - // Hide implementation details - engine.cpp is compiling - // enough as it is. - struct SoundImpl; - - SoundImpl *mData; Files::PathContainer files; bool fsStrict; MWWorld::Environment& mEnvironment; @@ -50,9 +59,54 @@ namespace MWSound ///< Play a soundifle /// \param absolute filename + /* This is the sound manager. It loades, stores and deletes + sounds based on the sound factory it is given. + */ + OEManagerPtr mgr; + Mangle::Sound::SoundPtr music; + + /* This class calls update() on the sound manager each frame + using and Ogre::FrameListener + */ + Mangle::Sound::OgreOutputUpdater updater; + + /* This class tracks the movement of an Ogre::Camera and moves + a sound listener automatically to follow it. + */ + Mangle::Sound::OgreListenerMover cameraTracker; + + typedef std::map IDMap; + typedef std::map PtrMap; + PtrMap sounds; + + // This is used for case insensitive and slash-type agnostic file + // finding. It takes DOS paths (any case, \\ slashes or / slashes) + // relative to the sound dir, and translates them into full paths + // of existing files in the filesystem, if they exist. + bool FSstrict; + FileFinder::LessTreeFileFinder soundfiles; + FileFinder::StrictTreeFileFinder strict; + FileFinder::LessTreeFileFinder musicpath; + FileFinder::StrictTreeFileFinder musicpathStrict; + + static std::string toMp3(std::string str); + bool hasFile(const std::string &str, bool music = false); + std::string convertPath(const std::string &str, bool music = false); + std::string lookup(const std::string &soundId, + float &volume, float &min, float &max); + void add(const std::string &file, + MWWorld::Ptr ptr, const std::string &id, + float volume, float pitch, float min, float max, + bool loop); + void clearAll(PtrMap::iterator& it); + void remove(MWWorld::Ptr ptr, const std::string &id = ""); + bool isPlaying(MWWorld::Ptr ptr, const std::string &id) const; + void removeCell(const MWWorld::Ptr::CellStore *cell); + void updatePositions(MWWorld::Ptr ptr); + public: - SoundManager(Ogre::Root*, Ogre::Camera*, const ESMS::ESMStore &store, + SoundManager(Ogre::Root*, Ogre::Camera*, const Files::PathContainer& dataDir, bool useSound, bool fsstrict, MWWorld::Environment& environment); ~SoundManager(); @@ -66,8 +120,6 @@ namespace MWSound bool isMusicPlaying(); - SoundImpl getMData(); - void say (MWWorld::Ptr reference, const std::string& filename); ///< Make an actor say some text. /// \param filename name of a sound file in "Sound/Vo/" in the data directory.