aboutsummaryrefslogtreecommitdiffstats
path: root/Alc/backends/opensl.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Alc/backends/opensl.cpp')
-rw-r--r--Alc/backends/opensl.cpp440
1 files changed, 183 insertions, 257 deletions
diff --git a/Alc/backends/opensl.cpp b/Alc/backends/opensl.cpp
index b0e51441..4f2e07be 100644
--- a/Alc/backends/opensl.cpp
+++ b/Alc/backends/opensl.cpp
@@ -42,14 +42,15 @@
namespace {
/* Helper macros */
+#define EXTRACT_VCALL_ARGS(...) __VA_ARGS__))
#define VCALL(obj, func) ((*(obj))->func((obj), EXTRACT_VCALL_ARGS
#define VCALL0(obj, func) ((*(obj))->func((obj) EXTRACT_VCALL_ARGS
-static const ALCchar opensl_device[] = "OpenSL";
+constexpr ALCchar opensl_device[] = "OpenSL";
-static SLuint32 GetChannelMask(DevFmtChannels chans)
+SLuint32 GetChannelMask(DevFmtChannels chans)
{
switch(chans)
{
@@ -78,7 +79,7 @@ static SLuint32 GetChannelMask(DevFmtChannels chans)
}
#ifdef SL_DATAFORMAT_PCM_EX
-static SLuint32 GetTypeRepresentation(DevFmtType type)
+SLuint32 GetTypeRepresentation(DevFmtType type)
{
switch(type)
{
@@ -97,7 +98,7 @@ static SLuint32 GetTypeRepresentation(DevFmtType type)
}
#endif
-static const char *res_str(SLresult result)
+const char *res_str(SLresult result)
{
switch(result)
{
@@ -132,20 +133,26 @@ static const char *res_str(SLresult result)
}
#define PRINTERR(x, s) do { \
- if((x) != SL_RESULT_SUCCESS) \
+ if(UNLIKELY((x) != SL_RESULT_SUCCESS)) \
ERR("%s: %s\n", (s), res_str((x))); \
} while(0)
-struct ALCopenslPlayback final : public ALCbackend {
- ALCopenslPlayback(ALCdevice *device) noexcept : ALCbackend{device} { }
- ~ALCopenslPlayback() override;
+struct OpenSLPlayback final : public BackendBase {
+ OpenSLPlayback(ALCdevice *device) noexcept : BackendBase{device} { }
+ ~OpenSLPlayback() override;
static void processC(SLAndroidSimpleBufferQueueItf bq, void *context);
void process(SLAndroidSimpleBufferQueueItf bq);
int mixerProc();
+ ALCenum open(const ALCchar *name) override;
+ ALCboolean reset() override;
+ ALCboolean start() override;
+ void stop() override;
+ ClockLatency getClockLatency() override;
+
/* engine interfaces */
SLObjectItf mEngineObj{nullptr};
SLEngineItf mEngine{nullptr};
@@ -163,34 +170,12 @@ struct ALCopenslPlayback final : public ALCbackend {
std::atomic<ALenum> mKillNow{AL_TRUE};
std::thread mThread;
-};
-
-static void ALCopenslPlayback_Construct(ALCopenslPlayback *self, ALCdevice *device);
-static void ALCopenslPlayback_Destruct(ALCopenslPlayback *self);
-static ALCenum ALCopenslPlayback_open(ALCopenslPlayback *self, const ALCchar *name);
-static ALCboolean ALCopenslPlayback_reset(ALCopenslPlayback *self);
-static ALCboolean ALCopenslPlayback_start(ALCopenslPlayback *self);
-static void ALCopenslPlayback_stop(ALCopenslPlayback *self);
-static DECLARE_FORWARD2(ALCopenslPlayback, ALCbackend, ALCenum, captureSamples, void*, ALCuint)
-static DECLARE_FORWARD(ALCopenslPlayback, ALCbackend, ALCuint, availableSamples)
-static ClockLatency ALCopenslPlayback_getClockLatency(ALCopenslPlayback *self);
-static DECLARE_FORWARD(ALCopenslPlayback, ALCbackend, void, lock)
-static DECLARE_FORWARD(ALCopenslPlayback, ALCbackend, void, unlock)
-DECLARE_DEFAULT_ALLOCATORS(ALCopenslPlayback)
-DEFINE_ALCBACKEND_VTABLE(ALCopenslPlayback);
-
-
-static void ALCopenslPlayback_Construct(ALCopenslPlayback *self, ALCdevice *device)
-{
- new (self) ALCopenslPlayback{device};
- SET_VTABLE2(ALCopenslPlayback, ALCbackend, self);
-}
-
-static void ALCopenslPlayback_Destruct(ALCopenslPlayback* self)
-{ self->~ALCopenslPlayback(); }
+ static constexpr inline const char *CurrentPrefix() noexcept { return "OpenSLPlayback::"; }
+ DEF_NEWDEL(OpenSLPlayback)
+};
-ALCopenslPlayback::~ALCopenslPlayback()
+OpenSLPlayback::~OpenSLPlayback()
{
if(mBufferQueueObj)
VCALL0(mBufferQueueObj,Destroy)();
@@ -208,10 +193,10 @@ ALCopenslPlayback::~ALCopenslPlayback()
/* this callback handler is called every time a buffer finishes playing */
-void ALCopenslPlayback::processC(SLAndroidSimpleBufferQueueItf bq, void *context)
-{ static_cast<ALCopenslPlayback*>(context)->process(bq); }
+void OpenSLPlayback::processC(SLAndroidSimpleBufferQueueItf bq, void *context)
+{ static_cast<OpenSLPlayback*>(context)->process(bq); }
-void ALCopenslPlayback::process(SLAndroidSimpleBufferQueueItf UNUSED(bq))
+void OpenSLPlayback::process(SLAndroidSimpleBufferQueueItf UNUSED(bq))
{
/* A note on the ringbuffer usage: The buffer queue seems to hold on to the
* pointer passed to the Enqueue method, rather than copying the audio.
@@ -226,7 +211,7 @@ void ALCopenslPlayback::process(SLAndroidSimpleBufferQueueItf UNUSED(bq))
mSem.post();
}
-int ALCopenslPlayback::mixerProc()
+int OpenSLPlayback::mixerProc()
{
SetRTPriority();
althrd_setname(MIXER_THREAD_NAME);
@@ -242,7 +227,7 @@ int ALCopenslPlayback::mixerProc()
PRINTERR(result, "bufferQueue->GetInterface SL_IID_PLAY");
}
- ALCopenslPlayback_lock(this);
+ lock();
if(SL_RESULT_SUCCESS != result)
aluHandleDisconnect(mDevice, "Failed to get playback buffer: 0x%08x", result);
@@ -251,7 +236,7 @@ int ALCopenslPlayback::mixerProc()
{
if(mRing->writeSpace() == 0)
{
- SLuint32 state = 0;
+ SLuint32 state{0};
result = VCALL(player,GetPlayState)(&state);
PRINTERR(result, "player->GetPlayState");
@@ -268,9 +253,9 @@ int ALCopenslPlayback::mixerProc()
if(mRing->writeSpace() == 0)
{
- ALCopenslPlayback_unlock(this);
+ unlock();
mSem.wait();
- ALCopenslPlayback_lock(this);
+ lock();
continue;
}
}
@@ -304,67 +289,63 @@ int ALCopenslPlayback::mixerProc()
data.first.buf += mDevice->UpdateSize*mFrameSize;
}
}
- ALCopenslPlayback_unlock(this);
+ unlock();
return 0;
}
-static ALCenum ALCopenslPlayback_open(ALCopenslPlayback *self, const ALCchar *name)
+ALCenum OpenSLPlayback::open(const ALCchar *name)
{
- ALCdevice *device{self->mDevice};
- SLresult result;
-
if(!name)
name = opensl_device;
else if(strcmp(name, opensl_device) != 0)
return ALC_INVALID_VALUE;
// create engine
- result = slCreateEngine(&self->mEngineObj, 0, NULL, 0, NULL, NULL);
+ SLresult result{slCreateEngine(&mEngineObj, 0, NULL, 0, NULL, NULL)};
PRINTERR(result, "slCreateEngine");
if(SL_RESULT_SUCCESS == result)
{
- result = VCALL(self->mEngineObj,Realize)(SL_BOOLEAN_FALSE);
+ result = VCALL(mEngineObj,Realize)(SL_BOOLEAN_FALSE);
PRINTERR(result, "engine->Realize");
}
if(SL_RESULT_SUCCESS == result)
{
- result = VCALL(self->mEngineObj,GetInterface)(SL_IID_ENGINE, &self->mEngine);
+ result = VCALL(mEngineObj,GetInterface)(SL_IID_ENGINE, &mEngine);
PRINTERR(result, "engine->GetInterface");
}
if(SL_RESULT_SUCCESS == result)
{
- result = VCALL(self->mEngine,CreateOutputMix)(&self->mOutputMix, 0, NULL, NULL);
+ result = VCALL(mEngine,CreateOutputMix)(&mOutputMix, 0, NULL, NULL);
PRINTERR(result, "engine->CreateOutputMix");
}
if(SL_RESULT_SUCCESS == result)
{
- result = VCALL(self->mOutputMix,Realize)(SL_BOOLEAN_FALSE);
+ result = VCALL(mOutputMix,Realize)(SL_BOOLEAN_FALSE);
PRINTERR(result, "outputMix->Realize");
}
if(SL_RESULT_SUCCESS != result)
{
- if(self->mOutputMix != NULL)
- VCALL0(self->mOutputMix,Destroy)();
- self->mOutputMix = NULL;
+ if(mOutputMix)
+ VCALL0(mOutputMix,Destroy)();
+ mOutputMix = NULL;
- if(self->mEngineObj != NULL)
- VCALL0(self->mEngineObj,Destroy)();
- self->mEngineObj = NULL;
- self->mEngine = NULL;
+ if(mEngineObj)
+ VCALL0(mEngineObj,Destroy)();
+ mEngineObj = NULL;
+ mEngine = NULL;
return ALC_INVALID_VALUE;
}
- device->DeviceName = name;
+ mDevice->DeviceName = name;
return ALC_NO_ERROR;
}
-static ALCboolean ALCopenslPlayback_reset(ALCopenslPlayback *self)
+ALCboolean OpenSLPlayback::reset()
{
- ALCdevice *device{self->mDevice};
SLDataLocator_AndroidSimpleBufferQueue loc_bufq;
SLDataLocator_OutputMix loc_outmix;
SLDataSource audioSrc;
@@ -374,15 +355,15 @@ static ALCboolean ALCopenslPlayback_reset(ALCopenslPlayback *self)
SLboolean reqs[2];
SLresult result;
- if(self->mBufferQueueObj != NULL)
- VCALL0(self->mBufferQueueObj,Destroy)();
- self->mBufferQueueObj = NULL;
+ if(mBufferQueueObj)
+ VCALL0(mBufferQueueObj,Destroy)();
+ mBufferQueueObj = NULL;
- self->mRing = nullptr;
+ mRing = nullptr;
- sampleRate = device->Frequency;
+ sampleRate = mDevice->Frequency;
#if 0
- if(!(device->Flags&DEVICE_FREQUENCY_REQUEST))
+ if(!(mDevice->Flags&DEVICE_FREQUENCY_REQUEST))
{
/* FIXME: Disabled until I figure out how to get the Context needed for
* the getSystemService call.
@@ -449,43 +430,43 @@ static ALCboolean ALCopenslPlayback_reset(ALCopenslPlayback *self)
}
#endif
- if(sampleRate != device->Frequency)
+ if(sampleRate != mDevice->Frequency)
{
- device->NumUpdates = (device->NumUpdates*sampleRate + (device->Frequency>>1)) /
- device->Frequency;
- device->NumUpdates = maxu(device->NumUpdates, 2);
- device->Frequency = sampleRate;
+ mDevice->NumUpdates = (mDevice->NumUpdates*sampleRate + (mDevice->Frequency>>1)) /
+ mDevice->Frequency;
+ mDevice->NumUpdates = maxu(mDevice->NumUpdates, 2);
+ mDevice->Frequency = sampleRate;
}
- device->FmtChans = DevFmtStereo;
- device->FmtType = DevFmtShort;
+ mDevice->FmtChans = DevFmtStereo;
+ mDevice->FmtType = DevFmtShort;
- SetDefaultWFXChannelOrder(device);
- self->mFrameSize = device->frameSizeFromFmt();
+ SetDefaultWFXChannelOrder(mDevice);
+ mFrameSize = mDevice->frameSizeFromFmt();
loc_bufq.locatorType = SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE;
- loc_bufq.numBuffers = device->NumUpdates;
+ loc_bufq.numBuffers = mDevice->NumUpdates;
#ifdef SL_DATAFORMAT_PCM_EX
SLDataFormat_PCM_EX format_pcm;
format_pcm.formatType = SL_DATAFORMAT_PCM_EX;
- format_pcm.numChannels = device->channelsFromFmt();
- format_pcm.sampleRate = device->Frequency * 1000;
- format_pcm.bitsPerSample = device->bytesFromFmt() * 8;
+ format_pcm.numChannels = mDevice->channelsFromFmt();
+ format_pcm.sampleRate = mDevice->Frequency * 1000;
+ format_pcm.bitsPerSample = mDevice->bytesFromFmt() * 8;
format_pcm.containerSize = format_pcm.bitsPerSample;
- format_pcm.channelMask = GetChannelMask(device->FmtChans);
+ format_pcm.channelMask = GetChannelMask(mDevice->FmtChans);
format_pcm.endianness = IS_LITTLE_ENDIAN ? SL_BYTEORDER_LITTLEENDIAN :
SL_BYTEORDER_BIGENDIAN;
- format_pcm.representation = GetTypeRepresentation(device->FmtType);
+ format_pcm.representation = GetTypeRepresentation(mDevice->FmtType);
#else
SLDataFormat_PCM format_pcm;
format_pcm.formatType = SL_DATAFORMAT_PCM;
- format_pcm.numChannels = device->channelsFromFmt();
- format_pcm.samplesPerSec = device->Frequency * 1000;
- format_pcm.bitsPerSample = device->bytesFromFmt() * 8;
+ format_pcm.numChannels = mDevice->channelsFromFmt();
+ format_pcm.samplesPerSec = mDevice->Frequency * 1000;
+ format_pcm.bitsPerSample = mDevice->bytesFromFmt() * 8;
format_pcm.containerSize = format_pcm.bitsPerSample;
- format_pcm.channelMask = GetChannelMask(device->FmtChans);
+ format_pcm.channelMask = GetChannelMask(mDevice->FmtChans);
format_pcm.endianness = IS_LITTLE_ENDIAN ? SL_BYTEORDER_LITTLEENDIAN :
SL_BYTEORDER_BIGENDIAN;
#endif
@@ -494,7 +475,7 @@ static ALCboolean ALCopenslPlayback_reset(ALCopenslPlayback *self)
audioSrc.pFormat = &format_pcm;
loc_outmix.locatorType = SL_DATALOCATOR_OUTPUTMIX;
- loc_outmix.outputMix = self->mOutputMix;
+ loc_outmix.outputMix = mOutputMix;
audioSnk.pLocator = &loc_outmix;
audioSnk.pFormat = NULL;
@@ -504,22 +485,20 @@ static ALCboolean ALCopenslPlayback_reset(ALCopenslPlayback *self)
ids[1] = SL_IID_ANDROIDCONFIGURATION;
reqs[1] = SL_BOOLEAN_FALSE;
- result = VCALL(self->mEngine,CreateAudioPlayer)(&self->mBufferQueueObj,
- &audioSrc, &audioSnk, COUNTOF(ids), ids, reqs
- );
+ result = VCALL(mEngine,CreateAudioPlayer)(&mBufferQueueObj, &audioSrc, &audioSnk, COUNTOF(ids),
+ ids, reqs);
PRINTERR(result, "engine->CreateAudioPlayer");
if(SL_RESULT_SUCCESS == result)
{
/* Set the stream type to "media" (games, music, etc), if possible. */
SLAndroidConfigurationItf config;
- result = VCALL(self->mBufferQueueObj,GetInterface)(SL_IID_ANDROIDCONFIGURATION, &config);
+ result = VCALL(mBufferQueueObj,GetInterface)(SL_IID_ANDROIDCONFIGURATION, &config);
PRINTERR(result, "bufferQueue->GetInterface SL_IID_ANDROIDCONFIGURATION");
if(SL_RESULT_SUCCESS == result)
{
SLint32 streamType = SL_ANDROID_STREAM_MEDIA;
- result = VCALL(config,SetConfiguration)(SL_ANDROID_KEY_STREAM_TYPE,
- &streamType, sizeof(streamType)
- );
+ result = VCALL(config,SetConfiguration)(SL_ANDROID_KEY_STREAM_TYPE, &streamType,
+ sizeof(streamType));
PRINTERR(result, "config->SetConfiguration");
}
@@ -528,26 +507,25 @@ static ALCboolean ALCopenslPlayback_reset(ALCopenslPlayback *self)
}
if(SL_RESULT_SUCCESS == result)
{
- result = VCALL(self->mBufferQueueObj,Realize)(SL_BOOLEAN_FALSE);
+ result = VCALL(mBufferQueueObj,Realize)(SL_BOOLEAN_FALSE);
PRINTERR(result, "bufferQueue->Realize");
}
if(SL_RESULT_SUCCESS == result)
{
- self->mRing = CreateRingBuffer(device->NumUpdates,
- self->mFrameSize*device->UpdateSize, true);
- if(!self->mRing)
+ mRing = CreateRingBuffer(mDevice->NumUpdates, mFrameSize*mDevice->UpdateSize, true);
+ if(!mRing)
{
- ERR("Out of memory allocating ring buffer %ux%u %u\n", device->UpdateSize,
- device->NumUpdates, self->mFrameSize);
+ ERR("Out of memory allocating ring buffer %ux%u %u\n", mDevice->UpdateSize,
+ mDevice->NumUpdates, mFrameSize);
result = SL_RESULT_MEMORY_FAILURE;
}
}
if(SL_RESULT_SUCCESS != result)
{
- if(self->mBufferQueueObj != NULL)
- VCALL0(self->mBufferQueueObj,Destroy)();
- self->mBufferQueueObj = NULL;
+ if(mBufferQueueObj)
+ VCALL0(mBufferQueueObj,Destroy)();
+ mBufferQueueObj = NULL;
return ALC_FALSE;
}
@@ -555,26 +533,24 @@ static ALCboolean ALCopenslPlayback_reset(ALCopenslPlayback *self)
return ALC_TRUE;
}
-static ALCboolean ALCopenslPlayback_start(ALCopenslPlayback *self)
+ALCboolean OpenSLPlayback::start()
{
- RingBuffer *ring{self->mRing.get()};
-
- ring->reset();
+ mRing->reset();
SLAndroidSimpleBufferQueueItf bufferQueue;
- SLresult result{VCALL(self->mBufferQueueObj,GetInterface)(SL_IID_ANDROIDSIMPLEBUFFERQUEUE,
+ SLresult result{VCALL(mBufferQueueObj,GetInterface)(SL_IID_ANDROIDSIMPLEBUFFERQUEUE,
&bufferQueue)};
PRINTERR(result, "bufferQueue->GetInterface");
if(SL_RESULT_SUCCESS != result)
return ALC_FALSE;
- result = VCALL(bufferQueue,RegisterCallback)(&ALCopenslPlayback::processC, self);
+ result = VCALL(bufferQueue,RegisterCallback)(&OpenSLPlayback::processC, this);
PRINTERR(result, "bufferQueue->RegisterCallback");
if(SL_RESULT_SUCCESS != result) return ALC_FALSE;
try {
- self->mKillNow.store(AL_FALSE);
- self->mThread = std::thread(std::mem_fn(&ALCopenslPlayback::mixerProc), self);
+ mKillNow.store(AL_FALSE);
+ mThread = std::thread(std::mem_fn(&OpenSLPlayback::mixerProc), this);
return ALC_TRUE;
}
catch(std::exception& e) {
@@ -585,20 +561,16 @@ static ALCboolean ALCopenslPlayback_start(ALCopenslPlayback *self)
return ALC_FALSE;
}
-
-static void ALCopenslPlayback_stop(ALCopenslPlayback *self)
+void OpenSLPlayback::stop()
{
- SLAndroidSimpleBufferQueueItf bufferQueue;
- SLPlayItf player;
- SLresult result;
-
- if(self->mKillNow.exchange(AL_TRUE) || !self->mThread.joinable())
+ if(mKillNow.exchange(AL_TRUE) || !mThread.joinable())
return;
- self->mSem.post();
- self->mThread.join();
+ mSem.post();
+ mThread.join();
- result = VCALL(self->mBufferQueueObj,GetInterface)(SL_IID_PLAY, &player);
+ SLPlayItf player;
+ SLresult result{VCALL(mBufferQueueObj,GetInterface)(SL_IID_PLAY, &player)};
PRINTERR(result, "bufferQueue->GetInterface");
if(SL_RESULT_SUCCESS == result)
{
@@ -606,8 +578,8 @@ static void ALCopenslPlayback_stop(ALCopenslPlayback *self)
PRINTERR(result, "player->SetPlayState");
}
- result = VCALL(self->mBufferQueueObj,GetInterface)(SL_IID_ANDROIDSIMPLEBUFFERQUEUE,
- &bufferQueue);
+ SLAndroidSimpleBufferQueueItf bufferQueue;
+ result = VCALL(mBufferQueueObj,GetInterface)(SL_IID_ANDROIDSIMPLEBUFFERQUEUE, &bufferQueue);
PRINTERR(result, "bufferQueue->GetInterface");
if(SL_RESULT_SUCCESS == result)
{
@@ -630,29 +602,33 @@ static void ALCopenslPlayback_stop(ALCopenslPlayback *self)
}
}
-static ClockLatency ALCopenslPlayback_getClockLatency(ALCopenslPlayback *self)
+ClockLatency OpenSLPlayback::getClockLatency()
{
- ALCdevice *device{self->mDevice};
- RingBuffer *ring{self->mRing.get()};
ClockLatency ret;
- ALCopenslPlayback_lock(self);
- ret.ClockTime = GetDeviceClockTime(device);
- ret.Latency = std::chrono::seconds{ring->readSpace() * device->UpdateSize};
- ret.Latency /= device->Frequency;
- ALCopenslPlayback_unlock(self);
+ lock();
+ ret.ClockTime = GetDeviceClockTime(mDevice);
+ ret.Latency = std::chrono::seconds{mRing->readSpace() * mDevice->UpdateSize};
+ ret.Latency /= mDevice->Frequency;
+ unlock();
return ret;
}
-struct ALCopenslCapture final : public ALCbackend {
- ALCopenslCapture(ALCdevice *device) noexcept : ALCbackend{device} { }
- ~ALCopenslCapture() override;
+struct OpenSLCapture final : public BackendBase {
+ OpenSLCapture(ALCdevice *device) noexcept : BackendBase{device} { }
+ ~OpenSLCapture() override;
static void processC(SLAndroidSimpleBufferQueueItf bq, void *context);
void process(SLAndroidSimpleBufferQueueItf bq);
+ ALCenum open(const ALCchar *name) override;
+ ALCboolean start() override;
+ void stop() override;
+ ALCenum captureSamples(void *buffer, ALCuint samples) override;
+ ALCuint availableSamples() override;
+
/* engine interfaces */
SLObjectItf mEngineObj{nullptr};
SLEngineItf mEngine;
@@ -664,33 +640,12 @@ struct ALCopenslCapture final : public ALCbackend {
ALCuint mSplOffset{0u};
ALsizei mFrameSize{0};
-};
-static void ALCopenslCapture_Construct(ALCopenslCapture *self, ALCdevice *device);
-static void ALCopenslCapture_Destruct(ALCopenslCapture *self);
-static ALCenum ALCopenslCapture_open(ALCopenslCapture *self, const ALCchar *name);
-static DECLARE_FORWARD(ALCopenslCapture, ALCbackend, ALCboolean, reset)
-static ALCboolean ALCopenslCapture_start(ALCopenslCapture *self);
-static void ALCopenslCapture_stop(ALCopenslCapture *self);
-static ALCenum ALCopenslCapture_captureSamples(ALCopenslCapture *self, ALCvoid *buffer, ALCuint samples);
-static ALCuint ALCopenslCapture_availableSamples(ALCopenslCapture *self);
-static DECLARE_FORWARD(ALCopenslCapture, ALCbackend, ClockLatency, getClockLatency)
-static DECLARE_FORWARD(ALCopenslCapture, ALCbackend, void, lock)
-static DECLARE_FORWARD(ALCopenslCapture, ALCbackend, void, unlock)
-DECLARE_DEFAULT_ALLOCATORS(ALCopenslCapture)
-DEFINE_ALCBACKEND_VTABLE(ALCopenslCapture);
-
-
-static void ALCopenslCapture_Construct(ALCopenslCapture *self, ALCdevice *device)
-{
- new (self) ALCopenslCapture{device};
- SET_VTABLE2(ALCopenslCapture, ALCbackend, self);
-}
-
-static void ALCopenslCapture_Destruct(ALCopenslCapture *self)
-{ self->~ALCopenslCapture(); }
+ static constexpr inline const char *CurrentPrefix() noexcept { return "OpenSLCapture::"; }
+ DEF_NEWDEL(OpenSLCapture)
+};
-ALCopenslCapture::~ALCopenslCapture()
+OpenSLCapture::~OpenSLCapture()
{
if(mRecordObj)
VCALL0(mRecordObj,Destroy)();
@@ -703,19 +658,18 @@ ALCopenslCapture::~ALCopenslCapture()
}
-void ALCopenslCapture::processC(SLAndroidSimpleBufferQueueItf bq, void *context)
-{ static_cast<ALCopenslCapture*>(context)->process(bq); }
+void OpenSLCapture::processC(SLAndroidSimpleBufferQueueItf bq, void *context)
+{ static_cast<OpenSLCapture*>(context)->process(bq); }
-void ALCopenslCapture::process(SLAndroidSimpleBufferQueueItf UNUSED(bq))
+void OpenSLCapture::process(SLAndroidSimpleBufferQueueItf UNUSED(bq))
{
/* A new chunk has been written into the ring buffer, advance it. */
mRing->writeAdvance(1);
}
-static ALCenum ALCopenslCapture_open(ALCopenslCapture *self, const ALCchar *name)
+ALCenum OpenSLCapture::open(const ALCchar* name)
{
- ALCdevice *device{self->mDevice};
SLDataLocator_AndroidSimpleBufferQueue loc_bq;
SLAndroidSimpleBufferQueueItf bufferQueue;
SLDataLocator_IODevice loc_dev;
@@ -728,32 +682,30 @@ static ALCenum ALCopenslCapture_open(ALCopenslCapture *self, const ALCchar *name
else if(strcmp(name, opensl_device) != 0)
return ALC_INVALID_VALUE;
- result = slCreateEngine(&self->mEngineObj, 0, NULL, 0, NULL, NULL);
+ result = slCreateEngine(&mEngineObj, 0, NULL, 0, NULL, NULL);
PRINTERR(result, "slCreateEngine");
if(SL_RESULT_SUCCESS == result)
{
- result = VCALL(self->mEngineObj,Realize)(SL_BOOLEAN_FALSE);
+ result = VCALL(mEngineObj,Realize)(SL_BOOLEAN_FALSE);
PRINTERR(result, "engine->Realize");
}
if(SL_RESULT_SUCCESS == result)
{
- result = VCALL(self->mEngineObj,GetInterface)(SL_IID_ENGINE, &self->mEngine);
+ result = VCALL(mEngineObj,GetInterface)(SL_IID_ENGINE, &mEngine);
PRINTERR(result, "engine->GetInterface");
}
if(SL_RESULT_SUCCESS == result)
{
/* Ensure the total length is at least 100ms */
- ALsizei length = maxi(device->NumUpdates * device->UpdateSize,
- device->Frequency / 10);
+ ALsizei length{maxi(mDevice->NumUpdates*mDevice->UpdateSize, mDevice->Frequency/10)};
/* Ensure the per-chunk length is at least 10ms, and no more than 50ms. */
- ALsizei update_len = clampi(device->NumUpdates*device->UpdateSize / 3,
- device->Frequency / 100,
- device->Frequency / 100 * 5);
+ ALsizei update_len{clampi(mDevice->NumUpdates*mDevice->UpdateSize / 3,
+ mDevice->Frequency/100, mDevice->Frequency/100*5)};
- device->UpdateSize = update_len;
- device->NumUpdates = (length+update_len-1) / update_len;
+ mDevice->UpdateSize = update_len;
+ mDevice->NumUpdates = (length+update_len-1) / update_len;
- self->mFrameSize = device->frameSizeFromFmt();
+ mFrameSize = mDevice->frameSizeFromFmt();
}
loc_dev.locatorType = SL_DATALOCATOR_IODEVICE;
loc_dev.deviceType = SL_IODEVICE_AUDIOINPUT;
@@ -764,27 +716,27 @@ static ALCenum ALCopenslCapture_open(ALCopenslCapture *self, const ALCchar *name
audioSrc.pFormat = NULL;
loc_bq.locatorType = SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE;
- loc_bq.numBuffers = device->NumUpdates;
+ loc_bq.numBuffers = mDevice->NumUpdates;
#ifdef SL_DATAFORMAT_PCM_EX
SLDataFormat_PCM_EX format_pcm;
format_pcm.formatType = SL_DATAFORMAT_PCM_EX;
- format_pcm.numChannels = device->channelsFromFmt();
- format_pcm.sampleRate = device->Frequency * 1000;
- format_pcm.bitsPerSample = device->bytesFromFmt() * 8;
+ format_pcm.numChannels = mDevice->channelsFromFmt();
+ format_pcm.sampleRate = mDevice->Frequency * 1000;
+ format_pcm.bitsPerSample = mDevice->bytesFromFmt() * 8;
format_pcm.containerSize = format_pcm.bitsPerSample;
- format_pcm.channelMask = GetChannelMask(device->FmtChans);
+ format_pcm.channelMask = GetChannelMask(mDevice->FmtChans);
format_pcm.endianness = IS_LITTLE_ENDIAN ? SL_BYTEORDER_LITTLEENDIAN :
SL_BYTEORDER_BIGENDIAN;
- format_pcm.representation = GetTypeRepresentation(device->FmtType);
+ format_pcm.representation = GetTypeRepresentation(mDevice->FmtType);
#else
SLDataFormat_PCM format_pcm;
format_pcm.formatType = SL_DATAFORMAT_PCM;
- format_pcm.numChannels = device->channelsFromFmt();
- format_pcm.samplesPerSec = device->Frequency * 1000;
- format_pcm.bitsPerSample = device->bytesFromFmt() * 8;
+ format_pcm.numChannels = mDevice->channelsFromFmt();
+ format_pcm.samplesPerSec = mDevice->Frequency * 1000;
+ format_pcm.bitsPerSample = mDevice->bytesFromFmt() * 8;
format_pcm.containerSize = format_pcm.bitsPerSample;
- format_pcm.channelMask = GetChannelMask(device->FmtChans);
+ format_pcm.channelMask = GetChannelMask(mDevice->FmtChans);
format_pcm.endianness = IS_LITTLE_ENDIAN ? SL_BYTEORDER_LITTLEENDIAN :
SL_BYTEORDER_BIGENDIAN;
#endif
@@ -797,23 +749,21 @@ static ALCenum ALCopenslCapture_open(ALCopenslCapture *self, const ALCchar *name
const SLInterfaceID ids[2] = { SL_IID_ANDROIDSIMPLEBUFFERQUEUE, SL_IID_ANDROIDCONFIGURATION };
const SLboolean reqs[2] = { SL_BOOLEAN_TRUE, SL_BOOLEAN_FALSE };
- result = VCALL(self->mEngine,CreateAudioRecorder)(&self->mRecordObj,
- &audioSrc, &audioSnk, COUNTOF(ids), ids, reqs
- );
+ result = VCALL(mEngine,CreateAudioRecorder)(&mRecordObj, &audioSrc, &audioSnk,
+ COUNTOF(ids), ids, reqs);
PRINTERR(result, "engine->CreateAudioRecorder");
}
if(SL_RESULT_SUCCESS == result)
{
/* Set the record preset to "generic", if possible. */
SLAndroidConfigurationItf config;
- result = VCALL(self->mRecordObj,GetInterface)(SL_IID_ANDROIDCONFIGURATION, &config);
+ result = VCALL(mRecordObj,GetInterface)(SL_IID_ANDROIDCONFIGURATION, &config);
PRINTERR(result, "recordObj->GetInterface SL_IID_ANDROIDCONFIGURATION");
if(SL_RESULT_SUCCESS == result)
{
SLuint32 preset = SL_ANDROID_RECORDING_PRESET_GENERIC;
- result = VCALL(config,SetConfiguration)(SL_ANDROID_KEY_RECORDING_PRESET,
- &preset, sizeof(preset)
- );
+ result = VCALL(config,SetConfiguration)(SL_ANDROID_KEY_RECORDING_PRESET, &preset,
+ sizeof(preset));
PRINTERR(result, "config->SetConfiguration");
}
@@ -822,31 +772,28 @@ static ALCenum ALCopenslCapture_open(ALCopenslCapture *self, const ALCchar *name
}
if(SL_RESULT_SUCCESS == result)
{
- result = VCALL(self->mRecordObj,Realize)(SL_BOOLEAN_FALSE);
+ result = VCALL(mRecordObj,Realize)(SL_BOOLEAN_FALSE);
PRINTERR(result, "recordObj->Realize");
}
if(SL_RESULT_SUCCESS == result)
{
- self->mRing = CreateRingBuffer(device->NumUpdates,
- device->UpdateSize*self->mFrameSize, false);
+ mRing = CreateRingBuffer(mDevice->NumUpdates, mDevice->UpdateSize*mFrameSize, false);
- result = VCALL(self->mRecordObj,GetInterface)(SL_IID_ANDROIDSIMPLEBUFFERQUEUE,
- &bufferQueue);
+ result = VCALL(mRecordObj,GetInterface)(SL_IID_ANDROIDSIMPLEBUFFERQUEUE, &bufferQueue);
PRINTERR(result, "recordObj->GetInterface");
}
if(SL_RESULT_SUCCESS == result)
{
- result = VCALL(bufferQueue,RegisterCallback)(&ALCopenslCapture::processC, self);
+ result = VCALL(bufferQueue,RegisterCallback)(&OpenSLCapture::processC, this);
PRINTERR(result, "bufferQueue->RegisterCallback");
}
if(SL_RESULT_SUCCESS == result)
{
- RingBuffer *ring{self->mRing.get()};
- ALsizei chunk_size = device->UpdateSize * self->mFrameSize;
+ ALsizei chunk_size = mDevice->UpdateSize * mFrameSize;
size_t i;
- auto data = ring->getWriteVector();
+ auto data = mRing->getWriteVector();
for(i = 0;i < data.first.len && SL_RESULT_SUCCESS == result;i++)
{
result = VCALL(bufferQueue,Enqueue)(data.first.buf + chunk_size*i, chunk_size);
@@ -861,28 +808,26 @@ static ALCenum ALCopenslCapture_open(ALCopenslCapture *self, const ALCchar *name
if(SL_RESULT_SUCCESS != result)
{
- if(self->mRecordObj != NULL)
- VCALL0(self->mRecordObj,Destroy)();
- self->mRecordObj = NULL;
+ if(mRecordObj)
+ VCALL0(mRecordObj,Destroy)();
+ mRecordObj = nullptr;
- if(self->mEngineObj != NULL)
- VCALL0(self->mEngineObj,Destroy)();
- self->mEngineObj = NULL;
- self->mEngine = NULL;
+ if(mEngineObj)
+ VCALL0(mEngineObj,Destroy)();
+ mEngineObj = nullptr;
+ mEngine = nullptr;
return ALC_INVALID_VALUE;
}
- device->DeviceName = name;
+ mDevice->DeviceName = name;
return ALC_NO_ERROR;
}
-static ALCboolean ALCopenslCapture_start(ALCopenslCapture *self)
+ALCboolean OpenSLCapture::start()
{
SLRecordItf record;
- SLresult result;
-
- result = VCALL(self->mRecordObj,GetInterface)(SL_IID_RECORD, &record);
+ SLresult result{VCALL(mRecordObj,GetInterface)(SL_IID_RECORD, &record)};
PRINTERR(result, "recordObj->GetInterface");
if(SL_RESULT_SUCCESS == result)
@@ -893,21 +838,19 @@ static ALCboolean ALCopenslCapture_start(ALCopenslCapture *self)
if(SL_RESULT_SUCCESS != result)
{
- ALCopenslCapture_lock(self);
- aluHandleDisconnect(self->mDevice, "Failed to start capture: 0x%08x", result);
- ALCopenslCapture_unlock(self);
+ lock();
+ aluHandleDisconnect(mDevice, "Failed to start capture: 0x%08x", result);
+ unlock();
return ALC_FALSE;
}
return ALC_TRUE;
}
-static void ALCopenslCapture_stop(ALCopenslCapture *self)
+void OpenSLCapture::stop()
{
SLRecordItf record;
- SLresult result;
-
- result = VCALL(self->mRecordObj,GetInterface)(SL_IID_RECORD, &record);
+ SLresult result{VCALL(mRecordObj,GetInterface)(SL_IID_RECORD, &record)};
PRINTERR(result, "recordObj->GetInterface");
if(SL_RESULT_SUCCESS == result)
@@ -917,37 +860,33 @@ static void ALCopenslCapture_stop(ALCopenslCapture *self)
}
}
-static ALCenum ALCopenslCapture_captureSamples(ALCopenslCapture *self, ALCvoid *buffer, ALCuint samples)
+ALCenum OpenSLCapture::captureSamples(void* buffer, ALCuint samples)
{
- ALCdevice *device{self->mDevice};
- RingBuffer *ring{self->mRing.get()};
- ALsizei chunk_size = device->UpdateSize * self->mFrameSize;
+ ALsizei chunk_size = mDevice->UpdateSize * mFrameSize;
SLAndroidSimpleBufferQueueItf bufferQueue;
SLresult result;
ALCuint i;
- result = VCALL(self->mRecordObj,GetInterface)(SL_IID_ANDROIDSIMPLEBUFFERQUEUE,
- &bufferQueue);
+ result = VCALL(mRecordObj,GetInterface)(SL_IID_ANDROIDSIMPLEBUFFERQUEUE, &bufferQueue);
PRINTERR(result, "recordObj->GetInterface");
/* Read the desired samples from the ring buffer then advance its read
* pointer.
*/
- auto data = ring->getReadVector();
+ auto data = mRing->getReadVector();
for(i = 0;i < samples;)
{
- ALCuint rem = minu(samples - i, device->UpdateSize - self->mSplOffset);
- memcpy((ALCbyte*)buffer + i*self->mFrameSize,
- data.first.buf + self->mSplOffset*self->mFrameSize,
- rem * self->mFrameSize);
+ ALCuint rem{minu(samples - i, mDevice->UpdateSize - mSplOffset)};
+ memcpy((ALCbyte*)buffer + i*mFrameSize, data.first.buf + mSplOffset*mFrameSize,
+ rem * mFrameSize);
- self->mSplOffset += rem;
- if(self->mSplOffset == device->UpdateSize)
+ mSplOffset += rem;
+ if(mSplOffset == mDevice->UpdateSize)
{
/* Finished a chunk, reset the offset and advance the read pointer. */
- self->mSplOffset = 0;
+ mSplOffset = 0;
- ring->readAdvance(1);
+ mRing->readAdvance(1);
result = VCALL(bufferQueue,Enqueue)(data.first.buf, chunk_size);
PRINTERR(result, "bufferQueue->Enqueue");
if(SL_RESULT_SUCCESS != result) break;
@@ -964,21 +903,17 @@ static ALCenum ALCopenslCapture_captureSamples(ALCopenslCapture *self, ALCvoid *
if(SL_RESULT_SUCCESS != result)
{
- ALCopenslCapture_lock(self);
- aluHandleDisconnect(device, "Failed to update capture buffer: 0x%08x", result);
- ALCopenslCapture_unlock(self);
+ lock();
+ aluHandleDisconnect(mDevice, "Failed to update capture buffer: 0x%08x", result);
+ unlock();
return ALC_INVALID_DEVICE;
}
return ALC_NO_ERROR;
}
-static ALCuint ALCopenslCapture_availableSamples(ALCopenslCapture *self)
-{
- ALCdevice *device{self->mDevice};
- RingBuffer *ring{self->mRing.get()};
- return ring->readSpace() * device->UpdateSize;
-}
+ALCuint OpenSLCapture::availableSamples()
+{ return mRing->readSpace()*mDevice->UpdateSize - mSplOffset; }
} // namespace
@@ -999,21 +934,12 @@ void OSLBackendFactory::probe(DevProbe type, std::string *outnames)
}
}
-ALCbackend *OSLBackendFactory::createBackend(ALCdevice *device, ALCbackend_Type type)
+BackendBase *OSLBackendFactory::createBackend(ALCdevice *device, ALCbackend_Type type)
{
if(type == ALCbackend_Playback)
- {
- ALCopenslPlayback *backend;
- NEW_OBJ(backend, ALCopenslPlayback)(device);
- return backend;
- }
+ return new OpenSLPlayback{device};
if(type == ALCbackend_Capture)
- {
- ALCopenslCapture *backend;
- NEW_OBJ(backend, ALCopenslCapture)(device);
- return backend;
- }
-
+ return new OpenSLCapture{device};
return nullptr;
}