mirror of
https://github.com/OpenMW/openmw.git
synced 2025-01-20 15:53:54 +00:00
Make the sound stream thread object per-device
This commit is contained in:
parent
2c27827e4f
commit
4698e8c0a2
2 changed files with 52 additions and 40 deletions
|
@ -3,6 +3,8 @@
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
#include <boost/thread.hpp>
|
||||||
|
|
||||||
#include "openal_output.hpp"
|
#include "openal_output.hpp"
|
||||||
#include "sound_decoder.hpp"
|
#include "sound_decoder.hpp"
|
||||||
#include "sound.hpp"
|
#include "sound.hpp"
|
||||||
|
@ -54,6 +56,8 @@ class OpenAL_SoundStream : public Sound
|
||||||
static const ALuint sNumBuffers = 4;
|
static const ALuint sNumBuffers = 4;
|
||||||
static const ALuint sBufferSize = 32768;
|
static const ALuint sBufferSize = 32768;
|
||||||
|
|
||||||
|
OpenAL_Output &mOutput;
|
||||||
|
|
||||||
ALuint mSource;
|
ALuint mSource;
|
||||||
ALuint mBuffers[sNumBuffers];
|
ALuint mBuffers[sNumBuffers];
|
||||||
|
|
||||||
|
@ -65,7 +69,7 @@ class OpenAL_SoundStream : public Sound
|
||||||
volatile bool mIsFinished;
|
volatile bool mIsFinished;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
OpenAL_SoundStream(DecoderPtr decoder);
|
OpenAL_SoundStream(OpenAL_Output &output, DecoderPtr decoder);
|
||||||
virtual ~OpenAL_SoundStream();
|
virtual ~OpenAL_SoundStream();
|
||||||
|
|
||||||
virtual void stop();
|
virtual void stop();
|
||||||
|
@ -79,60 +83,68 @@ public:
|
||||||
//
|
//
|
||||||
// A background streaming thread (keeps active streams processed)
|
// A background streaming thread (keeps active streams processed)
|
||||||
//
|
//
|
||||||
struct StreamThread {
|
struct OpenAL_Output::StreamThread {
|
||||||
typedef std::vector<OpenAL_SoundStream*> StreamVec;
|
typedef std::vector<OpenAL_SoundStream*> StreamVec;
|
||||||
static StreamVec sStreams;
|
StreamVec mStreams;
|
||||||
static boost::mutex sMutex;
|
boost::mutex mMutex;
|
||||||
|
boost::thread mThread;
|
||||||
|
|
||||||
|
StreamThread()
|
||||||
|
: mThread(boost::ref(*this))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
~StreamThread()
|
||||||
|
{
|
||||||
|
mThread.interrupt();
|
||||||
|
}
|
||||||
|
|
||||||
// boost::thread entry point
|
// boost::thread entry point
|
||||||
void operator()()
|
void operator()()
|
||||||
{
|
{
|
||||||
while(1)
|
while(1)
|
||||||
{
|
{
|
||||||
sMutex.lock();
|
mMutex.lock();
|
||||||
StreamVec::iterator iter = sStreams.begin();
|
StreamVec::iterator iter = mStreams.begin();
|
||||||
while(iter != sStreams.end())
|
while(iter != mStreams.end())
|
||||||
{
|
{
|
||||||
if((*iter)->process() == false)
|
if((*iter)->process() == false)
|
||||||
iter = sStreams.erase(iter);
|
iter = mStreams.erase(iter);
|
||||||
else
|
else
|
||||||
iter++;
|
iter++;
|
||||||
}
|
}
|
||||||
sMutex.unlock();
|
mMutex.unlock();
|
||||||
boost::this_thread::sleep(boost::posix_time::milliseconds(20));
|
boost::this_thread::sleep(boost::posix_time::milliseconds(20));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void add(OpenAL_SoundStream *stream)
|
void add(OpenAL_SoundStream *stream)
|
||||||
{
|
{
|
||||||
sMutex.lock();
|
mMutex.lock();
|
||||||
if(std::find(sStreams.begin(), sStreams.end(), stream) == sStreams.end())
|
if(std::find(mStreams.begin(), mStreams.end(), stream) == mStreams.end())
|
||||||
sStreams.push_back(stream);
|
mStreams.push_back(stream);
|
||||||
sMutex.unlock();
|
mMutex.unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void remove(OpenAL_SoundStream *stream)
|
void remove(OpenAL_SoundStream *stream)
|
||||||
{
|
{
|
||||||
sMutex.lock();
|
mMutex.lock();
|
||||||
StreamVec::iterator iter = std::find(sStreams.begin(), sStreams.end(), stream);
|
StreamVec::iterator iter = std::find(mStreams.begin(), mStreams.end(), stream);
|
||||||
if(iter != sStreams.end())
|
if(iter != mStreams.end())
|
||||||
sStreams.erase(iter);
|
mStreams.erase(iter);
|
||||||
sMutex.unlock();
|
mMutex.unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void removeAll()
|
void removeAll()
|
||||||
{
|
{
|
||||||
sMutex.lock();
|
mMutex.lock();
|
||||||
sStreams.clear();
|
mStreams.clear();
|
||||||
sMutex.unlock();
|
mMutex.unlock();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
StreamThread::StreamVec StreamThread::sStreams;
|
|
||||||
boost::mutex StreamThread::sMutex;
|
|
||||||
|
|
||||||
|
|
||||||
OpenAL_SoundStream::OpenAL_SoundStream(DecoderPtr decoder)
|
OpenAL_SoundStream::OpenAL_SoundStream(OpenAL_Output &output, DecoderPtr decoder)
|
||||||
: mDecoder(decoder), mIsFinished(true)
|
: mOutput(output), mDecoder(decoder), mIsFinished(true)
|
||||||
{
|
{
|
||||||
throwALerror();
|
throwALerror();
|
||||||
|
|
||||||
|
@ -170,7 +182,7 @@ OpenAL_SoundStream::OpenAL_SoundStream(DecoderPtr decoder)
|
||||||
}
|
}
|
||||||
OpenAL_SoundStream::~OpenAL_SoundStream()
|
OpenAL_SoundStream::~OpenAL_SoundStream()
|
||||||
{
|
{
|
||||||
StreamThread::remove(this);
|
mOutput.mStreamThread->remove(this);
|
||||||
|
|
||||||
alDeleteSources(1, &mSource);
|
alDeleteSources(1, &mSource);
|
||||||
alDeleteBuffers(sNumBuffers, mBuffers);
|
alDeleteBuffers(sNumBuffers, mBuffers);
|
||||||
|
@ -201,13 +213,13 @@ void OpenAL_SoundStream::play(float volume, float pitch)
|
||||||
alSourcePlay(mSource);
|
alSourcePlay(mSource);
|
||||||
throwALerror();
|
throwALerror();
|
||||||
|
|
||||||
StreamThread::add(this);
|
mOutput.mStreamThread->add(this);
|
||||||
mIsFinished = false;
|
mIsFinished = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void OpenAL_SoundStream::stop()
|
void OpenAL_SoundStream::stop()
|
||||||
{
|
{
|
||||||
StreamThread::remove(this);
|
mOutput.mStreamThread->remove(this);
|
||||||
mIsFinished = true;
|
mIsFinished = true;
|
||||||
|
|
||||||
alSourceStop(mSource);
|
alSourceStop(mSource);
|
||||||
|
@ -379,7 +391,8 @@ void OpenAL_Output::init(const std::string &devname)
|
||||||
|
|
||||||
void OpenAL_Output::deinit()
|
void OpenAL_Output::deinit()
|
||||||
{
|
{
|
||||||
StreamThread::removeAll();
|
if(mStreamThread.get() != 0)
|
||||||
|
mStreamThread->removeAll();
|
||||||
|
|
||||||
alcMakeContextCurrent(0);
|
alcMakeContextCurrent(0);
|
||||||
if(mContext)
|
if(mContext)
|
||||||
|
@ -496,7 +509,7 @@ Sound* OpenAL_Output::streamSound(const std::string &fname, float volume, float
|
||||||
DecoderPtr decoder = mManager.getDecoder();
|
DecoderPtr decoder = mManager.getDecoder();
|
||||||
decoder->open(fname);
|
decoder->open(fname);
|
||||||
|
|
||||||
sound.reset(new OpenAL_SoundStream(decoder));
|
sound.reset(new OpenAL_SoundStream(*this, decoder));
|
||||||
sound->play(volume, pitch);
|
sound->play(volume, pitch);
|
||||||
|
|
||||||
return sound.release();
|
return sound.release();
|
||||||
|
@ -517,13 +530,13 @@ void OpenAL_Output::updateListener(const float *pos, const float *atdir, const f
|
||||||
|
|
||||||
|
|
||||||
OpenAL_Output::OpenAL_Output(SoundManager &mgr)
|
OpenAL_Output::OpenAL_Output(SoundManager &mgr)
|
||||||
: Sound_Output(mgr), mDevice(0), mContext(0), mStreamThread(StreamThread())
|
: Sound_Output(mgr), mDevice(0), mContext(0), mStreamThread(new StreamThread)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
OpenAL_Output::~OpenAL_Output()
|
OpenAL_Output::~OpenAL_Output()
|
||||||
{
|
{
|
||||||
mStreamThread.interrupt();
|
mStreamThread.reset();
|
||||||
deinit();
|
deinit();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,8 +3,6 @@
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#include <boost/thread.hpp>
|
|
||||||
|
|
||||||
#include "alc.h"
|
#include "alc.h"
|
||||||
#include "al.h"
|
#include "al.h"
|
||||||
|
|
||||||
|
@ -13,7 +11,6 @@
|
||||||
namespace MWSound
|
namespace MWSound
|
||||||
{
|
{
|
||||||
class SoundManager;
|
class SoundManager;
|
||||||
class Sound_Decoder;
|
|
||||||
class Sound;
|
class Sound;
|
||||||
|
|
||||||
class OpenAL_Output : public Sound_Output
|
class OpenAL_Output : public Sound_Output
|
||||||
|
@ -21,8 +18,6 @@ namespace MWSound
|
||||||
ALCdevice *mDevice;
|
ALCdevice *mDevice;
|
||||||
ALCcontext *mContext;
|
ALCcontext *mContext;
|
||||||
|
|
||||||
boost::thread mStreamThread;
|
|
||||||
|
|
||||||
virtual void init(const std::string &devname="");
|
virtual void init(const std::string &devname="");
|
||||||
virtual void deinit();
|
virtual void deinit();
|
||||||
|
|
||||||
|
@ -37,6 +32,10 @@ namespace MWSound
|
||||||
OpenAL_Output(SoundManager &mgr);
|
OpenAL_Output(SoundManager &mgr);
|
||||||
virtual ~OpenAL_Output();
|
virtual ~OpenAL_Output();
|
||||||
|
|
||||||
|
class StreamThread;
|
||||||
|
std::auto_ptr<StreamThread> mStreamThread;
|
||||||
|
|
||||||
|
friend class OpenAL_SoundStream;
|
||||||
friend class SoundManager;
|
friend class SoundManager;
|
||||||
};
|
};
|
||||||
#ifndef DEFAULT_OUTPUT
|
#ifndef DEFAULT_OUTPUT
|
||||||
|
|
Loading…
Reference in a new issue