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