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.
This commit is contained in:
Chris Robinson
2021-01-15 18:18:07 -08:00
parent 8c4adfd752
commit 855a8c0cd9
+41 -35
View File
@@ -868,6 +868,36 @@ void OpenSLCapture::stop()
void OpenSLCapture::captureSamples(al::byte *buffer, uint samples) void OpenSLCapture::captureSamples(al::byte *buffer, uint samples)
{ {
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 rdata = mRing->getReadVector();
for(uint i{0};i < samples;)
{
const uint rem{minu(samples - i, update_size - mSplOffset)};
std::copy_n(rdata.first.buf + mSplOffset*mFrameSize, rem*mFrameSize,
buffer + i*mFrameSize);
mSplOffset += rem;
if(mSplOffset == update_size)
{
/* Finished a chunk, reset the offset and advance the read pointer. */
mSplOffset = 0;
mRing->readAdvance(1);
rdata.first.len -= 1;
if(!rdata.first.len)
rdata.first = rdata.second;
else
rdata.first.buf += chunk_size;
}
i += rem;
}
SLAndroidSimpleBufferQueueItf bufferQueue{}; SLAndroidSimpleBufferQueueItf bufferQueue{};
if LIKELY(mDevice->Connected.load(std::memory_order_acquire)) if LIKELY(mDevice->Connected.load(std::memory_order_acquire))
{ {
@@ -881,44 +911,20 @@ void OpenSLCapture::captureSamples(al::byte *buffer, uint samples)
} }
} }
const uint update_size{mDevice->UpdateSize}; if LIKELY(bufferQueue)
const uint chunk_size{update_size * mFrameSize};
/* Read the desired samples from the ring buffer then advance its read
* pointer.
*/
auto data = mRing->getReadVector();
for(uint i{0};i < samples;)
{ {
const uint rem{minu(samples - i, update_size - mSplOffset)}; SLresult result{SL_RESULT_SUCCESS};
std::copy_n(data.first.buf + mSplOffset*mFrameSize, rem*mFrameSize, buffer + i*mFrameSize); auto wdata = mRing->getWriteVector();
for(size_t i{0u};i < wdata.first.len && SL_RESULT_SUCCESS == result;i++)
mSplOffset += rem;
if(mSplOffset == update_size)
{ {
/* Finished a chunk, reset the offset and advance the read pointer. */ result = VCALL(bufferQueue,Enqueue)(wdata.first.buf + chunk_size*i, chunk_size);
mSplOffset = 0; PRINTERR(result, "bufferQueue->Enqueue");
mRing->readAdvance(1); }
for(size_t i{0u};i < wdata.second.len && SL_RESULT_SUCCESS == result;i++)
if LIKELY(bufferQueue) {
{ result = VCALL(bufferQueue,Enqueue)(wdata.second.buf + chunk_size*i, chunk_size);
const SLresult result{VCALL(bufferQueue,Enqueue)(data.first.buf, chunk_size)}; PRINTERR(result, "bufferQueue->Enqueue");
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;
else
data.first.buf += chunk_size;
} }
i += rem;
} }
} }