diff options
Diffstat (limited to 'Alc/backends/opensl.cpp')
-rw-r--r-- | Alc/backends/opensl.cpp | 440 |
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; } |