diff options
author | Chris Robinson <[email protected]> | 2021-01-15 18:18:07 -0800 |
---|---|---|
committer | Chris Robinson <[email protected]> | 2021-01-15 18:18:07 -0800 |
commit | 855a8c0cd9c79d3e708d037811b04a821f95a5bc (patch) | |
tree | b131f6871039daa4fc0cf3e7e26d04da77d01ff1 /alc/backends/opensl.cpp | |
parent | 8c4adfd752aa25a4d6d49db870f88287858bc5fc (diff) |
Don't assume the ring buffer's read vector is the next writable space
This is untrue since the ring buffer leaves one element unwritten, so there's
one extra element to be written once a readable element is read.
Diffstat (limited to 'alc/backends/opensl.cpp')
-rw-r--r-- | alc/backends/opensl.cpp | 66 |
1 files changed, 36 insertions, 30 deletions
diff --git a/alc/backends/opensl.cpp b/alc/backends/opensl.cpp index 8d966fca..f6e7fddb 100644 --- a/alc/backends/opensl.cpp +++ b/alc/backends/opensl.cpp @@ -868,30 +868,18 @@ void OpenSLCapture::stop() void OpenSLCapture::captureSamples(al::byte *buffer, uint samples) { - SLAndroidSimpleBufferQueueItf bufferQueue{}; - if LIKELY(mDevice->Connected.load(std::memory_order_acquire)) - { - const SLresult result{VCALL(mRecordObj,GetInterface)(SL_IID_ANDROIDSIMPLEBUFFERQUEUE, - &bufferQueue)}; - PRINTERR(result, "recordObj->GetInterface"); - if UNLIKELY(SL_RESULT_SUCCESS != result) - { - mDevice->handleDisconnect("Failed to get capture buffer queue: 0x%08x", result); - bufferQueue = nullptr; - } - } - const uint update_size{mDevice->UpdateSize}; const uint chunk_size{update_size * mFrameSize}; /* Read the desired samples from the ring buffer then advance its read * pointer. */ - auto data = mRing->getReadVector(); + auto rdata = mRing->getReadVector(); for(uint i{0};i < samples;) { const uint rem{minu(samples - i, update_size - mSplOffset)}; - std::copy_n(data.first.buf + mSplOffset*mFrameSize, rem*mFrameSize, buffer + i*mFrameSize); + std::copy_n(rdata.first.buf + mSplOffset*mFrameSize, rem*mFrameSize, + buffer + i*mFrameSize); mSplOffset += rem; if(mSplOffset == update_size) @@ -900,26 +888,44 @@ void OpenSLCapture::captureSamples(al::byte *buffer, uint samples) mSplOffset = 0; mRing->readAdvance(1); - if LIKELY(bufferQueue) - { - const SLresult result{VCALL(bufferQueue,Enqueue)(data.first.buf, chunk_size)}; - PRINTERR(result, "bufferQueue->Enqueue"); - if UNLIKELY(SL_RESULT_SUCCESS != result) - { - mDevice->handleDisconnect("Failed to update capture buffer: 0x%08x", result); - bufferQueue = nullptr; - } - } - - data.first.len--; - if(!data.first.len) - data.first = data.second; + rdata.first.len -= 1; + if(!rdata.first.len) + rdata.first = rdata.second; else - data.first.buf += chunk_size; + rdata.first.buf += chunk_size; } i += rem; } + + SLAndroidSimpleBufferQueueItf bufferQueue{}; + if LIKELY(mDevice->Connected.load(std::memory_order_acquire)) + { + const SLresult result{VCALL(mRecordObj,GetInterface)(SL_IID_ANDROIDSIMPLEBUFFERQUEUE, + &bufferQueue)}; + PRINTERR(result, "recordObj->GetInterface"); + if UNLIKELY(SL_RESULT_SUCCESS != result) + { + mDevice->handleDisconnect("Failed to get capture buffer queue: 0x%08x", result); + bufferQueue = nullptr; + } + } + + if LIKELY(bufferQueue) + { + SLresult result{SL_RESULT_SUCCESS}; + auto wdata = mRing->getWriteVector(); + for(size_t i{0u};i < wdata.first.len && SL_RESULT_SUCCESS == result;i++) + { + result = VCALL(bufferQueue,Enqueue)(wdata.first.buf + chunk_size*i, chunk_size); + PRINTERR(result, "bufferQueue->Enqueue"); + } + for(size_t i{0u};i < wdata.second.len && SL_RESULT_SUCCESS == result;i++) + { + result = VCALL(bufferQueue,Enqueue)(wdata.second.buf + chunk_size*i, chunk_size); + PRINTERR(result, "bufferQueue->Enqueue"); + } + } } uint OpenSLCapture::availableSamples() |