Play-/tools/PsfPlayer/Source/SH_OpenAL.cpp
Jean-Philip Desjardins 3d4904d744 Improved audio proxy.
Sound is much smoother now.
2022-02-08 18:47:53 -05:00

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);
}
}