mirror of
https://github.com/jpd002/Play-.git
synced 2025-04-28 21:57:57 +03:00
94 lines
2.2 KiB
C++
94 lines
2.2 KiB
C++
#include "SH_OpenAL.h"
|
|
#include "alloca_def.h"
|
|
#include <assert.h>
|
|
|
|
//#define LOGGING
|
|
#define SAMPLE_RATE 44100
|
|
|
|
ALCint g_attrList[] =
|
|
{
|
|
ALC_FREQUENCY, SAMPLE_RATE,
|
|
0, 0};
|
|
|
|
#define CHECK_AL_ERROR() \
|
|
{ \
|
|
assert(alGetError() == AL_NO_ERROR); \
|
|
}
|
|
|
|
CSH_OpenAL::CSH_OpenAL()
|
|
: m_context(m_device, g_attrList)
|
|
, m_lastUpdateTime(0)
|
|
, m_mustSync(true)
|
|
{
|
|
m_context.MakeCurrent();
|
|
alGenBuffers(MAX_BUFFERS, m_bufferNames);
|
|
CHECK_AL_ERROR();
|
|
Reset();
|
|
}
|
|
|
|
CSH_OpenAL::~CSH_OpenAL()
|
|
{
|
|
Reset();
|
|
alDeleteBuffers(MAX_BUFFERS, m_bufferNames);
|
|
CHECK_AL_ERROR();
|
|
}
|
|
|
|
CSoundHandler* CSH_OpenAL::HandlerFactory()
|
|
{
|
|
return new CSH_OpenAL();
|
|
}
|
|
|
|
void CSH_OpenAL::Reset()
|
|
{
|
|
m_source.Stop();
|
|
ALint sourceState = m_source.GetState();
|
|
assert(sourceState == AL_INITIAL || sourceState == AL_STOPPED);
|
|
alSourcei(m_source, AL_BUFFER, 0);
|
|
CHECK_AL_ERROR();
|
|
m_availableBuffers.clear();
|
|
m_availableBuffers.insert(m_availableBuffers.begin(), m_bufferNames, m_bufferNames + MAX_BUFFERS);
|
|
}
|
|
|
|
void CSH_OpenAL::RecycleBuffers()
|
|
{
|
|
unsigned int bufferCount = m_source.GetBuffersProcessed();
|
|
CHECK_AL_ERROR();
|
|
if(bufferCount != 0)
|
|
{
|
|
ALuint* bufferNames = reinterpret_cast<ALuint*>(alloca(sizeof(ALuint) * bufferCount));
|
|
alSourceUnqueueBuffers(m_source, bufferCount, bufferNames);
|
|
CHECK_AL_ERROR();
|
|
m_availableBuffers.insert(m_availableBuffers.begin(), bufferNames, bufferNames + bufferCount);
|
|
}
|
|
}
|
|
|
|
bool CSH_OpenAL::HasFreeBuffers()
|
|
{
|
|
return m_availableBuffers.size() != 0;
|
|
}
|
|
|
|
uint32 CSH_OpenAL::GetFreeBufferCount() const
|
|
{
|
|
return m_availableBuffers.size();
|
|
}
|
|
|
|
void CSH_OpenAL::Write(int16* samples, unsigned int sampleCount, unsigned int sampleRate)
|
|
{
|
|
assert(m_availableBuffers.size() != 0);
|
|
if(m_availableBuffers.size() == 0) return;
|
|
ALuint buffer = *m_availableBuffers.begin();
|
|
m_availableBuffers.pop_front();
|
|
|
|
alBufferData(buffer, AL_FORMAT_STEREO16, samples, sampleCount * sizeof(int16), sampleRate);
|
|
CHECK_AL_ERROR();
|
|
|
|
alSourceQueueBuffers(m_source, 1, &buffer);
|
|
CHECK_AL_ERROR();
|
|
|
|
ALint sourceState = m_source.GetState();
|
|
if(sourceState != AL_PLAYING)
|
|
{
|
|
m_source.Play();
|
|
assert(m_source.GetState() == AL_PLAYING);
|
|
}
|
|
}
|