From 45b612ab3bf32b98209e8a8b205bce573bd358a7 Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Fri, 16 Mar 2012 22:12:17 -0700 Subject: [PATCH] Add a skeleton output classs using OpenAL --- CMakeLists.txt | 12 +- apps/openmw/CMakeLists.txt | 2 +- apps/openmw/mwsound/openal_output.cpp | 60 ++++++++++ apps/openmw/mwsound/openal_output.hpp | 29 +++++ apps/openmw/mwsound/soundmanager.cpp | 26 +++-- apps/openmw/mwsound/soundmanager.hpp | 157 +++++++++++++++----------- 6 files changed, 199 insertions(+), 87 deletions(-) create mode 100644 apps/openmw/mwsound/openal_output.cpp create mode 100644 apps/openmw/mwsound/openal_output.hpp diff --git a/CMakeLists.txt b/CMakeLists.txt index d06085322..876ea8273 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -118,6 +118,12 @@ set(OENGINE_BULLET ${LIBDIR}/openengine/bullet/BulletShapeLoader.h ) +set(OENGINE_ALL ${OENGINE_OGRE} ${OENGINE_GUI} ${OENGINE_BULLET}) +source_group(libs\\openengine FILES ${OENGINE_ALL}) + +set(OPENMW_LIBS ${MANGLE_ALL} ${OENGINE_ALL}) +set(OPENMW_LIBS_HEADER) + # Sound setup if (USE_AUDIERE) find_package(Audiere REQUIRED) @@ -141,12 +147,6 @@ if (USE_MPG123) set(SOUND_DEFINE -DOPENMW_USE_MPG123) endif (USE_MPG123) -set(OENGINE_ALL ${OENGINE_OGRE} ${OENGINE_GUI} ${OENGINE_BULLET}) -source_group(libs\\openengine FILES ${OENGINE_ALL}) - -set(OPENMW_LIBS ${MANGLE_ALL} ${OENGINE_ALL}) -set(OPENMW_LIBS_HEADER) - # Platform specific if (WIN32) set(PLATFORM_INCLUDE_DIR "platform") diff --git a/apps/openmw/CMakeLists.txt b/apps/openmw/CMakeLists.txt index 77f465b4c..e9002f111 100644 --- a/apps/openmw/CMakeLists.txt +++ b/apps/openmw/CMakeLists.txt @@ -38,7 +38,7 @@ add_openmw_dir (mwscript ) add_openmw_dir (mwsound - soundmanager + soundmanager openal_output ) add_openmw_dir (mwworld diff --git a/apps/openmw/mwsound/openal_output.cpp b/apps/openmw/mwsound/openal_output.cpp new file mode 100644 index 000000000..59e9037c4 --- /dev/null +++ b/apps/openmw/mwsound/openal_output.cpp @@ -0,0 +1,60 @@ +#include "openal_output.hpp" + +namespace MWSound +{ + +static void fail(const std::string &msg) +{ throw std::runtime_error("OpenAL exception: " + msg); } + + +bool OpenAL_Output::Initialize(const std::string &devname) +{ + if(Context) + fail("Device already initialized"); + + Device = alcOpenDevice(devname.c_str()); + if(!Device) + { + std::cout << "Failed to open \""<Initialize()) + { + Output.reset(); + return; + } + // The music library will accept these filetypes // If none is given then it will accept all filetypes std::vector acceptableExtensions; @@ -66,13 +72,11 @@ namespace MWSound std::string anything = "anything"; // anything is better that a segfault mCurrentPlaylist = mMusicLibrary.section(anything, mFSStrict); // now points to an empty path - - std::cout << "Sound output: " << SOUND_OUT << std::endl; - std::cout << "Sound decoder: " << SOUND_IN << std::endl; } SoundManager::~SoundManager() { + Output.reset(); } // Convert a soundId to file name, and modify the volume @@ -258,7 +262,7 @@ namespace MWSound float min, max; const std::string &file = lookup(soundId, volume, min, max); if(file != "") - add(file, ptr, soundId, volume, pitch, min, max, loop, untracked); + std::cout << "Cannot play " << file << ", skipping.\n"; } void SoundManager::stopSound3D(MWWorld::Ptr ptr, const std::string& soundId) diff --git a/apps/openmw/mwsound/soundmanager.hpp b/apps/openmw/mwsound/soundmanager.hpp index 9db7fe1b7..f77222cb4 100644 --- a/apps/openmw/mwsound/soundmanager.hpp +++ b/apps/openmw/mwsound/soundmanager.hpp @@ -21,103 +21,122 @@ namespace MWWorld namespace MWSound { + class Sound_Output; + class SoundManager { + // 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 mFSStrict; - // 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 mFSStrict; + MWWorld::Environment& mEnvironment; - MWWorld::Environment& mEnvironment; + std::auto_ptr Output; - void streamMusicFull (const std::string& filename); - ///< Play a soundifle - /// \param absolute filename + void streamMusicFull(const std::string& filename); + ///< Play a soundifle + /// \param absolute filename - // A list of all sound files used to lookup paths - Files::PathContainer mSoundFiles; + // A list of all sound files used to lookup paths + Files::PathContainer mSoundFiles; - // A library of all Music file paths stored by the folder they are contained in - Files::FileLibrary mMusicLibrary; + // A library of all Music file paths stored by the folder they are contained in + Files::FileLibrary mMusicLibrary; - // Points to the current playlist of music files stored in the music library - const Files::PathContainer* mCurrentPlaylist; + // Points to the current playlist of music files stored in the music library + const Files::PathContainer* mCurrentPlaylist; - 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, bool untracked=false); - 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); + 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, bool untracked=false); + 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*, + public: + SoundManager(Ogre::Root*, Ogre::Camera*, const Files::PathContainer& dataDir, bool useSound, bool fsstrict, MWWorld::Environment& environment); - ~SoundManager(); + ~SoundManager(); - void stopMusic(); - ///< Stops music if it's playing + void stopMusic(); + ///< Stops music if it's playing - void streamMusic(const std::string& filename); - ///< Play a soundifle - /// \param filename name of a sound file in "Music/" in the data directory. + void streamMusic(const std::string& filename); + ///< Play a soundifle + /// \param filename name of a sound file in "Music/" in the data directory. - void startRandomTitle(); - ///< Starts a random track from the current playlist + void startRandomTitle(); + ///< Starts a random track from the current playlist - bool isMusicPlaying(); - ///< Returns true if music is playing + bool isMusicPlaying(); + ///< Returns true if music is playing - bool setPlaylist(std::string playlist=""); - ///< Set the playlist to an existing folder - /// \param name of the folder that contains the playlist - /// if none is set then it is set to an empty playlist - /// \return Return true if the previous playlist was the same + bool setPlaylist(std::string playlist=""); + ///< Set the playlist to an existing folder + /// \param name of the folder that contains the playlist + /// if none is set then it is set to an empty playlist + /// \return Return true if the previous playlist was the same - void playPlaylist(std::string playlist=""); - ///< Start playing music from the selected folder - /// \param name of the folder that contains the playlist - /// if none is set then it plays from the current playlist + void playPlaylist(std::string playlist=""); + ///< Start playing music from the selected folder + /// \param name of the folder that contains the playlist + /// if none is set then it plays from the current playlist - 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. + 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. - bool sayDone (MWWorld::Ptr reference) const; - ///< Is actor not speaking? + bool sayDone(MWWorld::Ptr reference) const; + ///< Is actor not speaking? - void playSound (const std::string& soundId, float volume, float pitch, bool loop=false); - ///< Play a sound, independently of 3D-position + void playSound(const std::string& soundId, float volume, float pitch, bool loop=false); + ///< Play a sound, independently of 3D-position - void playSound3D (MWWorld::Ptr reference, const std::string& soundId, - float volume, float pitch, bool loop, bool untracked=false); - ///< Play a sound from an object + void playSound3D(MWWorld::Ptr reference, const std::string& soundId, + float volume, float pitch, bool loop, + 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, If no soundId is given, + /// all sounds for this reference will stop. - void stopSound (MWWorld::Ptr::CellStore *cell); - ///< Stop all sounds for the given cell. + void stopSound(MWWorld::Ptr::CellStore *cell); + ///< Stop all sounds for the given cell. - void stopSound(const std::string& soundId); - ///< Stop a non-3d looping sound + void stopSound(const std::string& soundId); + ///< Stop a non-3d looping sound - bool getSoundPlaying (MWWorld::Ptr reference, const std::string& soundId) const; - ///< Is the given sound currently playing on the given object? + bool getSoundPlaying(MWWorld::Ptr reference, const std::string& soundId) const; + ///< Is the given sound currently playing on the given object? - void updateObject(MWWorld::Ptr reference); - ///< Update the position of all sounds connected to the given object. + void updateObject(MWWorld::Ptr reference); + ///< Update the position of all sounds connected to the given object. - void update (float duration); + void update(float duration); + }; + + class Sound_Output + { + SoundManager &mgr; + + virtual bool Initialize(const std::string &devname="") = 0; + virtual void Deinitialize() = 0; + + Sound_Output(SoundManager &mgr) : mgr(mgr) { } + + public: + virtual ~Sound_Output() { } + + friend class OpenAL_Output; + friend class SoundManager; }; }