2008-12-24 02:03:58 +00:00
|
|
|
#include "SH_OpenAL.h"
|
|
|
|
#include "alloca_def.h"
|
|
|
|
#include <assert.h>
|
|
|
|
|
|
|
|
//#define LOGGING
|
|
|
|
#define SAMPLE_RATE 44100
|
|
|
|
|
2018-04-30 21:01:23 +01:00
|
|
|
ALCint g_attrList[] =
|
|
|
|
{
|
|
|
|
ALC_FREQUENCY, SAMPLE_RATE,
|
|
|
|
0, 0};
|
2008-12-24 02:03:58 +00:00
|
|
|
|
2018-04-30 21:01:23 +01:00
|
|
|
#define CHECK_AL_ERROR() \
|
|
|
|
{ \
|
|
|
|
assert(alGetError() == AL_NO_ERROR); \
|
|
|
|
}
|
2013-08-24 05:56:08 +00:00
|
|
|
|
2018-04-30 21:01:23 +01:00
|
|
|
CSH_OpenAL::CSH_OpenAL()
|
|
|
|
: m_context(m_device, g_attrList)
|
|
|
|
, m_lastUpdateTime(0)
|
|
|
|
, m_mustSync(true)
|
2008-12-24 02:03:58 +00:00
|
|
|
{
|
|
|
|
m_context.MakeCurrent();
|
2013-09-05 05:01:33 +00:00
|
|
|
alGenBuffers(MAX_BUFFERS, m_bufferNames);
|
2013-08-24 05:56:08 +00:00
|
|
|
CHECK_AL_ERROR();
|
2013-09-05 05:01:33 +00:00
|
|
|
Reset();
|
2008-12-24 02:03:58 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
CSH_OpenAL::~CSH_OpenAL()
|
|
|
|
{
|
2013-09-05 05:01:33 +00:00
|
|
|
Reset();
|
|
|
|
alDeleteBuffers(MAX_BUFFERS, m_bufferNames);
|
|
|
|
CHECK_AL_ERROR();
|
2008-12-24 02:03:58 +00:00
|
|
|
}
|
|
|
|
|
2009-11-08 22:26:39 +00:00
|
|
|
CSoundHandler* CSH_OpenAL::HandlerFactory()
|
2009-01-09 23:43:44 +00:00
|
|
|
{
|
|
|
|
return new CSH_OpenAL();
|
|
|
|
}
|
|
|
|
|
2008-12-24 02:03:58 +00:00
|
|
|
void CSH_OpenAL::Reset()
|
|
|
|
{
|
|
|
|
m_source.Stop();
|
2013-08-24 05:56:08 +00:00
|
|
|
ALint sourceState = m_source.GetState();
|
|
|
|
assert(sourceState == AL_INITIAL || sourceState == AL_STOPPED);
|
2013-09-05 05:01:33 +00:00
|
|
|
alSourcei(m_source, AL_BUFFER, 0);
|
|
|
|
CHECK_AL_ERROR();
|
|
|
|
m_availableBuffers.clear();
|
|
|
|
m_availableBuffers.insert(m_availableBuffers.begin(), m_bufferNames, m_bufferNames + MAX_BUFFERS);
|
2008-12-24 02:03:58 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void CSH_OpenAL::RecycleBuffers()
|
|
|
|
{
|
|
|
|
unsigned int bufferCount = m_source.GetBuffersProcessed();
|
2013-09-05 05:01:33 +00:00
|
|
|
CHECK_AL_ERROR();
|
2008-12-24 02:03:58 +00:00
|
|
|
if(bufferCount != 0)
|
|
|
|
{
|
|
|
|
ALuint* bufferNames = reinterpret_cast<ALuint*>(alloca(sizeof(ALuint) * bufferCount));
|
|
|
|
alSourceUnqueueBuffers(m_source, bufferCount, bufferNames);
|
2013-08-24 05:56:08 +00:00
|
|
|
CHECK_AL_ERROR();
|
2008-12-24 02:03:58 +00:00
|
|
|
m_availableBuffers.insert(m_availableBuffers.begin(), bufferNames, bufferNames + bufferCount);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
bool CSH_OpenAL::HasFreeBuffers()
|
|
|
|
{
|
|
|
|
return m_availableBuffers.size() != 0;
|
|
|
|
}
|
|
|
|
|
2021-10-25 10:08:59 -04:00
|
|
|
uint32 CSH_OpenAL::GetFreeBufferCount() const
|
|
|
|
{
|
|
|
|
return m_availableBuffers.size();
|
|
|
|
}
|
|
|
|
|
2009-11-08 22:26:39 +00:00
|
|
|
void CSH_OpenAL::Write(int16* samples, unsigned int sampleCount, unsigned int sampleRate)
|
2008-12-24 02:03:58 +00:00
|
|
|
{
|
|
|
|
assert(m_availableBuffers.size() != 0);
|
2009-11-08 22:26:39 +00:00
|
|
|
if(m_availableBuffers.size() == 0) return;
|
2012-11-09 06:52:00 +00:00
|
|
|
ALuint buffer = *m_availableBuffers.begin();
|
2008-12-24 02:03:58 +00:00
|
|
|
m_availableBuffers.pop_front();
|
|
|
|
|
|
|
|
alBufferData(buffer, AL_FORMAT_STEREO16, samples, sampleCount * sizeof(int16), sampleRate);
|
2013-08-24 05:56:08 +00:00
|
|
|
CHECK_AL_ERROR();
|
2018-04-30 21:01:23 +01:00
|
|
|
|
2008-12-24 02:03:58 +00:00
|
|
|
alSourceQueueBuffers(m_source, 1, &buffer);
|
2013-08-24 05:56:08 +00:00
|
|
|
CHECK_AL_ERROR();
|
2018-04-30 21:01:23 +01:00
|
|
|
|
2016-04-04 11:48:19 -04:00
|
|
|
ALint sourceState = m_source.GetState();
|
|
|
|
if(sourceState != AL_PLAYING)
|
2008-12-24 02:03:58 +00:00
|
|
|
{
|
2016-04-04 11:48:19 -04:00
|
|
|
m_source.Play();
|
|
|
|
assert(m_source.GetState() == AL_PLAYING);
|
2008-12-24 02:03:58 +00:00
|
|
|
}
|
|
|
|
}
|