forked from teamnwah/openmw-tes3coop
Add a skeleton output classs using OpenAL
This commit is contained in:
parent
42b445383f
commit
45b612ab3b
6 changed files with 199 additions and 87 deletions
|
@ -118,6 +118,12 @@ set(OENGINE_BULLET
|
||||||
${LIBDIR}/openengine/bullet/BulletShapeLoader.h
|
${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
|
# Sound setup
|
||||||
if (USE_AUDIERE)
|
if (USE_AUDIERE)
|
||||||
find_package(Audiere REQUIRED)
|
find_package(Audiere REQUIRED)
|
||||||
|
@ -141,12 +147,6 @@ if (USE_MPG123)
|
||||||
set(SOUND_DEFINE -DOPENMW_USE_MPG123)
|
set(SOUND_DEFINE -DOPENMW_USE_MPG123)
|
||||||
endif (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
|
# Platform specific
|
||||||
if (WIN32)
|
if (WIN32)
|
||||||
set(PLATFORM_INCLUDE_DIR "platform")
|
set(PLATFORM_INCLUDE_DIR "platform")
|
||||||
|
|
|
@ -38,7 +38,7 @@ add_openmw_dir (mwscript
|
||||||
)
|
)
|
||||||
|
|
||||||
add_openmw_dir (mwsound
|
add_openmw_dir (mwsound
|
||||||
soundmanager
|
soundmanager openal_output
|
||||||
)
|
)
|
||||||
|
|
||||||
add_openmw_dir (mwworld
|
add_openmw_dir (mwworld
|
||||||
|
|
60
apps/openmw/mwsound/openal_output.cpp
Normal file
60
apps/openmw/mwsound/openal_output.cpp
Normal file
|
@ -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();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
29
apps/openmw/mwsound/openal_output.hpp
Normal file
29
apps/openmw/mwsound/openal_output.hpp
Normal file
|
@ -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/world.hpp"
|
||||||
#include "../mwworld/player.hpp"
|
#include "../mwworld/player.hpp"
|
||||||
|
|
||||||
|
|
||||||
|
#include "openal_output.hpp"
|
||||||
|
#define SOUND_OUT "OpenAL"
|
||||||
/* Set up the sound manager to use Audiere, FFMPEG or
|
/* Set up the sound manager to use Audiere, FFMPEG or
|
||||||
MPG123/libsndfile for input. The OPENMW_USE_x macros are set in
|
MPG123/libsndfile for input. The OPENMW_USE_x macros are set in
|
||||||
CMakeLists.txt.
|
CMakeLists.txt.
|
||||||
*/
|
*/
|
||||||
#ifdef OPENMW_USE_AUDIERE
|
#ifdef OPENMW_USE_AUDIERE
|
||||||
#define SOUND_FACTORY OpenAL_Audiere_Factory
|
|
||||||
#define SOUND_OUT "OpenAL"
|
|
||||||
#define SOUND_IN "Audiere"
|
#define SOUND_IN "Audiere"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef OPENMW_USE_FFMPEG
|
#ifdef OPENMW_USE_FFMPEG
|
||||||
#define SOUND_FACTORY OpenAL_FFMpeg_Factory
|
|
||||||
#define SOUND_OUT "OpenAL"
|
|
||||||
#define SOUND_IN "FFmpeg"
|
#define SOUND_IN "FFmpeg"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef OPENMW_USE_MPG123
|
#ifdef OPENMW_USE_MPG123
|
||||||
#define SOUND_FACTORY OpenAL_SndFile_Mpg123_Factory
|
|
||||||
#define SOUND_OUT "OpenAL"
|
|
||||||
#define SOUND_IN "mpg123,sndfile"
|
#define SOUND_IN "mpg123,sndfile"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
namespace MWSound
|
namespace MWSound
|
||||||
{
|
{
|
||||||
|
|
||||||
SoundManager::SoundManager(Ogre::Root *root, Ogre::Camera *camera,
|
SoundManager::SoundManager(Ogre::Root *root, Ogre::Camera *camera,
|
||||||
const Files::PathContainer& dataDirs,
|
const Files::PathContainer& dataDirs,
|
||||||
bool useSound, bool fsstrict, MWWorld::Environment& environment)
|
bool useSound, bool fsstrict, MWWorld::Environment& environment)
|
||||||
|
@ -48,6 +44,16 @@ namespace MWSound
|
||||||
if(!useSound)
|
if(!useSound)
|
||||||
return;
|
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
|
// The music library will accept these filetypes
|
||||||
// If none is given then it will accept all filetypes
|
// If none is given then it will accept all filetypes
|
||||||
std::vector<std::string> acceptableExtensions;
|
std::vector<std::string> acceptableExtensions;
|
||||||
|
@ -66,13 +72,11 @@ namespace MWSound
|
||||||
|
|
||||||
std::string anything = "anything"; // anything is better that a segfault
|
std::string anything = "anything"; // anything is better that a segfault
|
||||||
mCurrentPlaylist = mMusicLibrary.section(anything, mFSStrict); // now points to an empty path
|
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()
|
SoundManager::~SoundManager()
|
||||||
{
|
{
|
||||||
|
Output.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Convert a soundId to file name, and modify the volume
|
// Convert a soundId to file name, and modify the volume
|
||||||
|
@ -258,7 +262,7 @@ namespace MWSound
|
||||||
float min, max;
|
float min, max;
|
||||||
const std::string &file = lookup(soundId, volume, min, max);
|
const std::string &file = lookup(soundId, volume, min, max);
|
||||||
if(file != "")
|
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)
|
void SoundManager::stopSound3D(MWWorld::Ptr ptr, const std::string& soundId)
|
||||||
|
|
|
@ -21,103 +21,122 @@ namespace MWWorld
|
||||||
|
|
||||||
namespace MWSound
|
namespace MWSound
|
||||||
{
|
{
|
||||||
|
class Sound_Output;
|
||||||
|
|
||||||
class SoundManager
|
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
|
MWWorld::Environment& mEnvironment;
|
||||||
// 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);
|
void streamMusicFull(const std::string& filename);
|
||||||
///< Play a soundifle
|
///< Play a soundifle
|
||||||
/// \param absolute filename
|
/// \param absolute filename
|
||||||
|
|
||||||
// A list of all sound files used to lookup paths
|
// A list of all sound files used to lookup paths
|
||||||
Files::PathContainer mSoundFiles;
|
Files::PathContainer mSoundFiles;
|
||||||
|
|
||||||
// A library of all Music file paths stored by the folder they are contained in
|
// A library of all Music file paths stored by the folder they are contained in
|
||||||
Files::FileLibrary mMusicLibrary;
|
Files::FileLibrary mMusicLibrary;
|
||||||
|
|
||||||
// Points to the current playlist of music files stored in the music library
|
// Points to the current playlist of music files stored in the music library
|
||||||
const Files::PathContainer* mCurrentPlaylist;
|
const Files::PathContainer* mCurrentPlaylist;
|
||||||
|
|
||||||
std::string lookup(const std::string &soundId,
|
std::string lookup(const std::string &soundId,
|
||||||
float &volume, float &min, float &max);
|
float &volume, float &min, float &max);
|
||||||
void add(const std::string &file,
|
void add(const std::string &file,
|
||||||
MWWorld::Ptr ptr, const std::string &id,
|
MWWorld::Ptr ptr, const std::string &id,
|
||||||
float volume, float pitch, float min, float max,
|
float volume, float pitch, float min, float max,
|
||||||
bool loop, bool untracked=false);
|
bool loop, bool untracked=false);
|
||||||
void remove(MWWorld::Ptr ptr, const std::string &id = "");
|
void remove(MWWorld::Ptr ptr, const std::string &id = "");
|
||||||
bool isPlaying(MWWorld::Ptr ptr, const std::string &id) const;
|
bool isPlaying(MWWorld::Ptr ptr, const std::string &id) const;
|
||||||
void removeCell(const MWWorld::Ptr::CellStore *cell);
|
void removeCell(const MWWorld::Ptr::CellStore *cell);
|
||||||
void updatePositions(MWWorld::Ptr ptr);
|
void updatePositions(MWWorld::Ptr ptr);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
SoundManager(Ogre::Root*, Ogre::Camera*,
|
||||||
SoundManager(Ogre::Root*, Ogre::Camera*,
|
|
||||||
const Files::PathContainer& dataDir, bool useSound, bool fsstrict,
|
const Files::PathContainer& dataDir, bool useSound, bool fsstrict,
|
||||||
MWWorld::Environment& environment);
|
MWWorld::Environment& environment);
|
||||||
~SoundManager();
|
~SoundManager();
|
||||||
|
|
||||||
void stopMusic();
|
void stopMusic();
|
||||||
///< Stops music if it's playing
|
///< Stops music if it's playing
|
||||||
|
|
||||||
void streamMusic(const std::string& filename);
|
void streamMusic(const std::string& filename);
|
||||||
///< Play a soundifle
|
///< Play a soundifle
|
||||||
/// \param filename name of a sound file in "Music/" in the data directory.
|
/// \param filename name of a sound file in "Music/" in the data directory.
|
||||||
|
|
||||||
void startRandomTitle();
|
void startRandomTitle();
|
||||||
///< Starts a random track from the current playlist
|
///< Starts a random track from the current playlist
|
||||||
|
|
||||||
bool isMusicPlaying();
|
bool isMusicPlaying();
|
||||||
///< Returns true if music is playing
|
///< Returns true if music is playing
|
||||||
|
|
||||||
bool setPlaylist(std::string playlist="");
|
bool setPlaylist(std::string playlist="");
|
||||||
///< Set the playlist to an existing folder
|
///< Set the playlist to an existing folder
|
||||||
/// \param name of the folder that contains the playlist
|
/// \param name of the folder that contains the playlist
|
||||||
/// if none is set then it is set to an empty playlist
|
/// if none is set then it is set to an empty playlist
|
||||||
/// \return Return true if the previous playlist was the same
|
/// \return Return true if the previous playlist was the same
|
||||||
|
|
||||||
void playPlaylist(std::string playlist="");
|
void playPlaylist(std::string playlist="");
|
||||||
///< Start playing music from the selected folder
|
///< Start playing music from the selected folder
|
||||||
/// \param name of the folder that contains the playlist
|
/// \param name of the folder that contains the playlist
|
||||||
/// if none is set then it plays from the current playlist
|
/// if none is set then it plays from the current playlist
|
||||||
|
|
||||||
void say (MWWorld::Ptr reference, const std::string& filename);
|
void say(MWWorld::Ptr reference, const std::string& filename);
|
||||||
///< Make an actor say some text.
|
///< Make an actor say some text.
|
||||||
/// \param filename name of a sound file in "Sound/Vo/" in the data directory.
|
/// \param filename name of a sound file in "Sound/Vo/" in the data directory.
|
||||||
|
|
||||||
bool sayDone (MWWorld::Ptr reference) const;
|
bool sayDone(MWWorld::Ptr reference) const;
|
||||||
///< Is actor not speaking?
|
///< Is actor not speaking?
|
||||||
|
|
||||||
void playSound (const std::string& soundId, float volume, float pitch, bool loop=false);
|
void playSound(const std::string& soundId, float volume, float pitch, bool loop=false);
|
||||||
///< Play a sound, independently of 3D-position
|
///< Play a sound, independently of 3D-position
|
||||||
|
|
||||||
void playSound3D (MWWorld::Ptr reference, const std::string& soundId,
|
void playSound3D(MWWorld::Ptr reference, const std::string& soundId,
|
||||||
float volume, float pitch, bool loop, bool untracked=false);
|
float volume, float pitch, bool loop,
|
||||||
///< Play a sound from an object
|
bool untracked=false);
|
||||||
|
///< Play a sound from an object
|
||||||
|
|
||||||
void stopSound3D (MWWorld::Ptr reference, const std::string& soundId = "");
|
void stopSound3D(MWWorld::Ptr reference, const std::string& soundId="");
|
||||||
///< Stop the given object from playing the given sound, If no soundId is given,
|
///< Stop the given object from playing the given sound, If no soundId is given,
|
||||||
/// all sounds for this reference will stop.
|
/// all sounds for this reference will stop.
|
||||||
|
|
||||||
void stopSound (MWWorld::Ptr::CellStore *cell);
|
void stopSound(MWWorld::Ptr::CellStore *cell);
|
||||||
///< Stop all sounds for the given cell.
|
///< Stop all sounds for the given cell.
|
||||||
|
|
||||||
void stopSound(const std::string& soundId);
|
void stopSound(const std::string& soundId);
|
||||||
///< Stop a non-3d looping sound
|
///< Stop a non-3d looping sound
|
||||||
|
|
||||||
bool getSoundPlaying (MWWorld::Ptr reference, const std::string& soundId) const;
|
bool getSoundPlaying(MWWorld::Ptr reference, const std::string& soundId) const;
|
||||||
///< Is the given sound currently playing on the given object?
|
///< Is the given sound currently playing on the given object?
|
||||||
|
|
||||||
void updateObject(MWWorld::Ptr reference);
|
void updateObject(MWWorld::Ptr reference);
|
||||||
///< Update the position of all sounds connected to the given object.
|
///< 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;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue