Add a skeleton output classs using OpenAL

pull/21/head
Chris Robinson 13 years ago
parent 42b445383f
commit 45b612ab3b

@ -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")

@ -38,7 +38,7 @@ add_openmw_dir (mwscript
)
add_openmw_dir (mwsound
soundmanager
soundmanager openal_output
)
add_openmw_dir (mwworld

@ -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 \""<<devname<<"\"" << std::endl;
return false;
}
std::cout << "Opened \""<<alcGetString(Device, ALC_DEVICE_SPECIFIER)<<"\"" << std::endl;
Context = alcCreateContext(Device, NULL);
if(!Context || alcMakeContextCurrent(Context) == ALC_FALSE)
{
std::cout << "Failed to setup device context" << std::endl;
if(Context)
alcDestroyContext(Context);
Context = 0;
alcCloseDevice(Device);
Device = 0;
return false;
}
return true;
}
void OpenAL_Output::Deinitialize()
{
alcMakeContextCurrent(0);
if(Context)
alcDestroyContext(Context);
Context = 0;
if(Device)
alcCloseDevice(Device);
Device = 0;
}
OpenAL_Output::OpenAL_Output(SoundManager &mgr)
: Sound_Output(mgr), Device(0), Context(0)
{
}
OpenAL_Output::~OpenAL_Output()
{
Deinitialize();
}
}

@ -0,0 +1,29 @@
#ifndef GAME_SOUND_OPENAL_OUTPUT_H
#define GAME_SOUND_OPENAL_OUTPUT_H
#include "soundmanager.hpp"
#include "alc.h"
#include "al.h"
namespace MWSound
{
class OpenAL_Output : public Sound_Output
{
ALCdevice *Device;
ALCcontext *Context;
virtual bool Initialize(const std::string &devname="");
virtual void Deinitialize();
OpenAL_Output(SoundManager &mgr);
virtual ~OpenAL_Output();
friend class SoundManager;
};
#ifndef DEFAULT_OUTPUT
#define DEFAULT_OUTPUT OpenAL_Output
#endif
};
#endif

@ -12,32 +12,28 @@
#include "../mwworld/world.hpp"
#include "../mwworld/player.hpp"
#include "openal_output.hpp"
#define SOUND_OUT "OpenAL"
/* Set up the sound manager to use Audiere, FFMPEG or
MPG123/libsndfile for input. The OPENMW_USE_x macros are set in
CMakeLists.txt.
*/
#ifdef OPENMW_USE_AUDIERE
#define SOUND_FACTORY OpenAL_Audiere_Factory
#define SOUND_OUT "OpenAL"
#define SOUND_IN "Audiere"
#endif
#ifdef OPENMW_USE_FFMPEG
#define SOUND_FACTORY OpenAL_FFMpeg_Factory
#define SOUND_OUT "OpenAL"
#define SOUND_IN "FFmpeg"
#endif
#ifdef OPENMW_USE_MPG123
#define SOUND_FACTORY OpenAL_SndFile_Mpg123_Factory
#define SOUND_OUT "OpenAL"
#define SOUND_IN "mpg123,sndfile"
#endif
namespace MWSound
{
SoundManager::SoundManager(Ogre::Root *root, Ogre::Camera *camera,
const Files::PathContainer& dataDirs,
bool useSound, bool fsstrict, MWWorld::Environment& environment)
@ -48,6 +44,16 @@ namespace MWSound
if(!useSound)
return;
std::cout << "Sound output: " << SOUND_OUT << std::endl;
std::cout << "Sound decoder: " << SOUND_IN << std::endl;
Output.reset(new DEFAULT_OUTPUT(*this));
if(!Output->Initialize())
{
Output.reset();
return;
}
// The music library will accept these filetypes
// If none is given then it will accept all filetypes
std::vector<std::string> 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)

@ -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;
MWWorld::Environment& mEnvironment;
std::auto_ptr<Sound_Output> Output;
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 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;
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*,
const Files::PathContainer& dataDir, bool useSound, bool fsstrict,
MWWorld::Environment& environment);
~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;
MWWorld::Environment& mEnvironment;
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 library of all Music file paths stored by the folder they are contained in
Files::FileLibrary mMusicLibrary;
void stopMusic();
///< Stops music if it's playing
// Points to the current playlist of music files stored in the music library
const Files::PathContainer* mCurrentPlaylist;
void streamMusic(const std::string& filename);
///< Play a soundifle
/// \param filename name of a sound file in "Music/" in the data directory.
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);
void startRandomTitle();
///< Starts a random track from the current playlist
public:
bool isMusicPlaying();
///< Returns true if music is playing
SoundManager(Ogre::Root*, Ogre::Camera*,
const Files::PathContainer& dataDir, bool useSound, bool fsstrict,
MWWorld::Environment& environment);
~SoundManager();
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 stopMusic();
///< Stops music if it's playing
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 streamMusic(const std::string& filename);
///< Play a soundifle
/// \param filename name of a sound file in "Music/" 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.
void startRandomTitle();
///< Starts a random track from the current playlist
bool sayDone(MWWorld::Ptr reference) const;
///< Is actor not speaking?
bool isMusicPlaying();
///< Returns true if music is playing
void playSound(const std::string& soundId, float volume, float pitch, bool loop=false);
///< Play a sound, independently of 3D-position
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 playSound3D(MWWorld::Ptr reference, const std::string& soundId,
float volume, float pitch, bool loop,
bool untracked=false);
///< Play a sound from an object
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 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 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 stopSound(MWWorld::Ptr::CellStore *cell);
///< Stop all sounds for the given cell.
bool sayDone (MWWorld::Ptr reference) const;
///< Is actor not speaking?
void stopSound(const std::string& soundId);
///< Stop a non-3d looping sound
void playSound (const std::string& soundId, float volume, float pitch, bool loop=false);
///< Play a sound, independently of 3D-position
bool getSoundPlaying(MWWorld::Ptr reference, const std::string& soundId) const;
///< Is the given sound currently playing on the given 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 updateObject(MWWorld::Ptr reference);
///< Update the position of all sounds connected to the given 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 update(float duration);
};
void stopSound (MWWorld::Ptr::CellStore *cell);
///< Stop all sounds for the given cell.
class Sound_Output
{
SoundManager &mgr;
void stopSound(const std::string& soundId);
///< Stop a non-3d looping sound
virtual bool Initialize(const std::string &devname="") = 0;
virtual void Deinitialize() = 0;
bool getSoundPlaying (MWWorld::Ptr reference, const std::string& soundId) const;
///< Is the given sound currently playing on the given object?
Sound_Output(SoundManager &mgr) : mgr(mgr) { }
void updateObject(MWWorld::Ptr reference);
///< Update the position of all sounds connected to the given object.
public:
virtual ~Sound_Output() { }
void update (float duration);
friend class OpenAL_Output;
friend class SoundManager;
};
}

Loading…
Cancel
Save