Play-/Source/ui_android/SH_OpenSL.cpp

146 lines
4.1 KiB
C++
Raw Permalink Normal View History

2016-03-25 12:19:34 -04:00
#include <cassert>
#include "SH_OpenSL.h"
CSH_OpenSL::CSH_OpenSL()
{
SLresult result = SL_RESULT_SUCCESS;
2018-04-30 21:01:23 +01:00
2016-03-25 12:19:34 -04:00
result = slCreateEngine(&m_engineObject, 0, nullptr, 0, nullptr, nullptr);
assert(result == SL_RESULT_SUCCESS);
2018-04-30 21:01:23 +01:00
2016-03-25 12:19:34 -04:00
result = (*m_engineObject)->Realize(m_engineObject, SL_BOOLEAN_FALSE);
assert(result == SL_RESULT_SUCCESS);
2018-04-30 21:01:23 +01:00
2016-03-25 12:19:34 -04:00
result = (*m_engineObject)->GetInterface(m_engineObject, SL_IID_ENGINE, &m_engine);
assert(result == SL_RESULT_SUCCESS);
2018-04-30 21:01:23 +01:00
2016-03-30 20:36:01 -04:00
CreateOutputMix();
CreateAudioPlayer();
2016-03-25 12:19:34 -04:00
}
CSH_OpenSL::~CSH_OpenSL()
{
Reset();
2016-03-30 20:36:01 -04:00
(*m_playerObject)->Destroy(m_playerObject);
(*m_outputMixObject)->Destroy(m_outputMixObject);
2016-03-25 12:19:34 -04:00
(*m_engineObject)->Destroy(m_engineObject);
}
CSoundHandler* CSH_OpenSL::HandlerFactory()
{
return new CSH_OpenSL();
}
2016-03-30 20:36:01 -04:00
void CSH_OpenSL::CreateOutputMix()
{
assert(m_outputMixObject == nullptr);
2018-04-30 21:01:23 +01:00
2016-03-30 20:36:01 -04:00
SLresult result = SL_RESULT_SUCCESS;
2018-04-30 21:01:23 +01:00
static const SLInterfaceID interfaceIds[] = {SL_IID_VOLUME};
static const SLboolean required[] = {SL_BOOLEAN_FALSE};
2016-03-30 20:36:01 -04:00
result = (*m_engine)->CreateOutputMix(m_engine, &m_outputMixObject, 1, interfaceIds, required);
assert(result == SL_RESULT_SUCCESS);
2018-04-30 21:01:23 +01:00
2016-03-30 20:36:01 -04:00
result = (*m_outputMixObject)->Realize(m_outputMixObject, SL_BOOLEAN_FALSE);
assert(result == SL_RESULT_SUCCESS);
}
void CSH_OpenSL::CreateAudioPlayer()
{
assert(m_playerObject == nullptr);
2018-04-30 21:01:23 +01:00
2016-03-30 20:36:01 -04:00
SLresult result = SL_RESULT_SUCCESS;
2018-04-30 21:01:23 +01:00
2016-03-30 20:36:01 -04:00
SLDataLocator_AndroidSimpleBufferQueue bufferQueueLocator = {};
bufferQueueLocator.locatorType = SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE;
2018-04-30 21:01:23 +01:00
bufferQueueLocator.numBuffers = BUFFER_COUNT;
2016-03-30 20:36:01 -04:00
SLDataFormat_PCM dataFormat = {};
2018-04-30 21:01:23 +01:00
dataFormat.formatType = SL_DATAFORMAT_PCM;
dataFormat.numChannels = 2;
2016-03-30 20:36:01 -04:00
dataFormat.samplesPerSec = SL_SAMPLINGRATE_44_1;
dataFormat.bitsPerSample = SL_PCMSAMPLEFORMAT_FIXED_16;
dataFormat.containerSize = SL_PCMSAMPLEFORMAT_FIXED_16;
2018-04-30 21:01:23 +01:00
dataFormat.channelMask = SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT;
dataFormat.endianness = SL_BYTEORDER_LITTLEENDIAN;
2016-03-30 20:36:01 -04:00
SLDataSource dataSource = {};
dataSource.pLocator = &bufferQueueLocator;
2018-04-30 21:01:23 +01:00
dataSource.pFormat = &dataFormat;
2016-03-30 20:36:01 -04:00
SLDataLocator_OutputMix outputMixLocator = {};
outputMixLocator.locatorType = SL_DATALOCATOR_OUTPUTMIX;
2018-04-30 21:01:23 +01:00
outputMixLocator.outputMix = m_outputMixObject;
2016-03-30 20:36:01 -04:00
SLDataSink dataSink = {};
dataSink.pLocator = &outputMixLocator;
2018-04-30 21:01:23 +01:00
static const SLInterfaceID interfaceIds[] = {SL_IID_ANDROIDSIMPLEBUFFERQUEUE};
static const SLboolean required[] = {SL_BOOLEAN_TRUE};
result = (*m_engine)->CreateAudioPlayer(m_engine, &m_playerObject, &dataSource, &dataSink,
1, interfaceIds, required);
2016-03-30 20:36:01 -04:00
assert(result == SL_RESULT_SUCCESS);
2018-04-30 21:01:23 +01:00
2016-03-30 20:36:01 -04:00
result = (*m_playerObject)->Realize(m_playerObject, SL_BOOLEAN_FALSE);
assert(result == SL_RESULT_SUCCESS);
2018-04-30 21:01:23 +01:00
2016-03-30 20:36:01 -04:00
result = (*m_playerObject)->GetInterface(m_playerObject, SL_IID_PLAY, &m_playerPlay);
assert(result == SL_RESULT_SUCCESS);
2018-04-30 21:01:23 +01:00
2016-03-30 20:36:01 -04:00
result = (*m_playerObject)->GetInterface(m_playerObject, SL_IID_ANDROIDSIMPLEBUFFERQUEUE, &m_playerQueue);
assert(result == SL_RESULT_SUCCESS);
2018-04-30 21:01:23 +01:00
2016-03-31 00:28:23 -04:00
result = (*m_playerQueue)->RegisterCallback(m_playerQueue, &CSH_OpenSL::QueueCallback, this);
assert(result == SL_RESULT_SUCCESS);
2018-04-30 21:01:23 +01:00
2016-03-31 00:28:23 -04:00
result = (*m_playerPlay)->SetPlayState(m_playerPlay, SL_PLAYSTATE_PLAYING);
assert(result == SL_RESULT_SUCCESS);
}
void CSH_OpenSL::QueueCallback(SLAndroidSimpleBufferQueueItf, void* context)
{
reinterpret_cast<CSH_OpenSL*>(context)->QueueCallbackImpl();
}
void CSH_OpenSL::QueueCallbackImpl()
{
assert(m_bufferCount != BUFFER_COUNT);
m_bufferCount++;
2016-03-30 20:36:01 -04:00
}
2016-03-25 12:19:34 -04:00
void CSH_OpenSL::Reset()
{
2016-03-30 20:36:01 -04:00
assert(m_playerQueue != nullptr);
2018-04-30 21:01:23 +01:00
2016-03-30 20:36:01 -04:00
SLresult result = SL_RESULT_SUCCESS;
2018-04-30 21:01:23 +01:00
2016-03-30 20:36:01 -04:00
result = (*m_playerQueue)->Clear(m_playerQueue);
assert(result == SL_RESULT_SUCCESS);
2018-04-30 21:01:23 +01:00
2016-03-31 00:28:23 -04:00
m_bufferCount = BUFFER_COUNT;
2016-03-25 12:19:34 -04:00
}
2016-03-30 20:36:01 -04:00
void CSH_OpenSL::Write(int16* buffer, unsigned int sampleCount, unsigned int)
2016-03-25 12:19:34 -04:00
{
2016-03-31 00:28:23 -04:00
if(m_bufferCount == 0) return;
2018-04-30 21:01:23 +01:00
2016-03-30 20:36:01 -04:00
assert(m_playerQueue != nullptr);
2018-04-30 21:01:23 +01:00
2016-03-30 20:36:01 -04:00
SLresult result = SL_RESULT_SUCCESS;
2018-04-30 21:01:23 +01:00
2016-03-30 20:36:01 -04:00
result = (*m_playerQueue)->Enqueue(m_playerQueue, buffer, sampleCount * sizeof(int16));
assert(result == SL_RESULT_SUCCESS);
2018-04-30 21:01:23 +01:00
2016-03-31 00:28:23 -04:00
m_bufferCount--;
2016-03-25 12:19:34 -04:00
}
bool CSH_OpenSL::HasFreeBuffers()
{
return false;
}
void CSH_OpenSL::RecycleBuffers()
{
}