diff --git a/apps/openmw/engine.cpp b/apps/openmw/engine.cpp index ad12f910b..827966f65 100644 --- a/apps/openmw/engine.cpp +++ b/apps/openmw/engine.cpp @@ -267,6 +267,18 @@ void OMW::Engine::go() mOgre.getRoot()->addFrameListener (this); + // Play some good 'ol tunes + std::string music = (mDataDir / "Music/Explore/mx_explore_5.mp3").file_string(); + try + { + std::cout << "Playing " << music << "\n"; + mEnvironment.mSoundManager->streamMusic(music); + } + catch(std::exception &e) + { + std::cout << " Music Error: " << e.what() << "\n"; + } + // Start the main rendering loop mOgre.start(); diff --git a/apps/openmw/mwscript/soundextensions.cpp b/apps/openmw/mwscript/soundextensions.cpp index c177a87e3..58554ef16 100644 --- a/apps/openmw/mwscript/soundextensions.cpp +++ b/apps/openmw/mwscript/soundextensions.cpp @@ -32,7 +32,7 @@ namespace MWScript std::string text = runtime.getStringLiteral (runtime[0].mInteger); runtime.pop(); - context.getSoundManager().say (context.getReference(), file, text); + context.getSoundManager().say (context.getReference(), file); context.messageBox (text); } }; @@ -205,7 +205,7 @@ namespace MWScript runtime.pop(); context.getSoundManager().say (context.getWorld().getPtr (id, true), - file, text); + file); } }; diff --git a/apps/openmw/mwsound/soundmanager.cpp b/apps/openmw/mwsound/soundmanager.cpp index b1a1b54e6..4d84964c2 100644 --- a/apps/openmw/mwsound/soundmanager.cpp +++ b/apps/openmw/mwsound/soundmanager.cpp @@ -2,6 +2,8 @@ #include "soundmanager.hpp" #include +#include +#include /* Set up the sound manager to use Audiere for input (reading sound files) and OpenAL for output. @@ -16,6 +18,8 @@ */ using namespace Mangle::Sound; +typedef OEngine::Sound::SoundManager OEManager; +typedef OEngine::Sound::SoundManagerPtr OEManagerPtr; /* Set the position on a sound based on a Ptr. TODO: We do not support tracking moving objects yet, once a sound is started it stays in @@ -26,10 +30,10 @@ using namespace Mangle::Sound; frame is expensive, so there should be a special flag for sounds that need to track their attached object. */ -static void setPos(SoundPtr snd, MWWorld::Ptr ref) +static void setPos(SoundPtr snd, const MWWorld::Ptr ref) { // Get sound position from the reference - float *pos = ref.getCellRef().pos.pos; + const float *pos = ref.getCellRef().pos.pos; // Move the sound. Might need to convert coordinates, test. snd->setPos(pos[0], pos[1], pos[2]); @@ -39,20 +43,34 @@ namespace MWSound { struct SoundManager::SoundImpl { - OEngine::Sound::SoundManager mgr; + /* This is the sound manager. It loades, stores and deletes + sounds based on the sound factory it is given. + */ + OEManagerPtr mgr; + + /* 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; SoundImpl() - : mgr(SoundFactoryPtr(new SOUND_FACTORY)) + : mgr(new OEManager(SoundFactoryPtr(new SOUND_FACTORY))) + , updater(mgr) + , cameraTracker(mgr) {} - - std::map mSounds; // object, sound }; SoundManager::SoundManager(Ogre::Root *root, Ogre::Camera *camera) { mData = new SoundImpl; - // TODO: Set up updater and camera listener. + // Attach the camera to the camera tracker + mData->cameraTracker.followCamera(camera); } SoundManager::~SoundManager() @@ -60,61 +78,45 @@ namespace MWSound delete mData; } - void SoundManager::say (MWWorld::Ptr reference, const std::string& filename, - const std::string& text) + void SoundManager::say (MWWorld::Ptr reference, const std::string& filename) { - std::cout << "sound effect: " << reference.getRefData().getHandle() << " is speaking" << std::endl; - + // Play the sound at the correct position + SoundPtr snd = mData->mgr->play(filename); + setPos(snd, reference); + // TODO: We need to attach it to the reference somehow. A weak + // pointer is probably the best bet } bool SoundManager::sayDone (MWWorld::Ptr reference) const { - return false; + return true; + // TODO: Ask the reference to check its attached 'say' sound. } void SoundManager::streamMusic (const std::string& filename) { - std::cout << "sound effect: playing music" << filename << std::endl; + // Play the sound and tell it to stream, if possible. + mData->mgr->play(filename)->setStreaming(true); } void SoundManager::playSound (const std::string& soundId, float volume, float pitch) { - std::cout - << "sound effect: playing sound " << soundId - << " at volume " << volume << ", at pitch " << pitch - << std::endl; } void SoundManager::playSound3D (MWWorld::Ptr reference, const std::string& soundId, float volume, float pitch, bool loop) { - std::cout - << "sound effect: playing sound " << soundId - << " from " << reference.getRefData().getHandle() - << " at volume " << volume << ", at pitch " << pitch - << std::endl; - - mData->mSounds[reference.getRefData().getHandle()] = soundId; + // Not implemented - need both a way to find sounds by id and + // a way to attach them to the reference } void SoundManager::stopSound3D (MWWorld::Ptr reference, const std::string& soundId) { - std::cout - << "sound effect : stop playing sound " << soundId - << " from " << reference.getRefData().getHandle() << std::endl; - - mData->mSounds[reference.getRefData().getHandle()] = ""; } bool SoundManager::getSoundPlaying (MWWorld::Ptr reference, const std::string& soundId) const { - std::map::const_iterator iter = - mData->mSounds.find (reference.getRefData().getHandle()); - - if (iter==mData->mSounds.end()) - return false; - - return iter->second==soundId; + return false; } } diff --git a/apps/openmw/mwsound/soundmanager.hpp b/apps/openmw/mwsound/soundmanager.hpp index 294804d10..88cf63e1b 100644 --- a/apps/openmw/mwsound/soundmanager.hpp +++ b/apps/openmw/mwsound/soundmanager.hpp @@ -14,10 +14,6 @@ namespace Ogre namespace MWSound { - // Note: the -> script syntax is not implemented yet ( script - // instructions of the type npc_x -> say "file", "text" aren't - // working) - class SoundManager { // Hide implementation details - engine.cpp is compiling @@ -29,11 +25,9 @@ namespace MWSound SoundManager(Ogre::Root*, Ogre::Camera*); ~SoundManager(); - void say (MWWorld::Ptr reference, const std::string& filename, - const std::string& text); + 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. - /// \param text Subtitle bool sayDone (MWWorld::Ptr reference) const; ///< Is actor not speaking? diff --git a/libs/mangle b/libs/mangle index fb2d077ca..86a811c73 160000 --- a/libs/mangle +++ b/libs/mangle @@ -1 +1 @@ -Subproject commit fb2d077ca9935374dd46576e643d111feb325c90 +Subproject commit 86a811c736810ef156fd2788be74951c5416ca03