aboutsummaryrefslogtreecommitdiffstats
path: root/alc/backends
diff options
context:
space:
mode:
authorChris Robinson <[email protected]>2021-01-15 18:18:07 -0800
committerChris Robinson <[email protected]>2021-01-15 18:18:07 -0800
commit855a8c0cd9c79d3e708d037811b04a821f95a5bc (patch)
treeb131f6871039daa4fc0cf3e7e26d04da77d01ff1 /alc/backends
parent8c4adfd752aa25a4d6d49db870f88287858bc5fc (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')
-rw-r--r--alc/backends/opensl.cpp66
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()