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
+39 -33
View File
@@ -868,6 +868,36 @@ void OpenSLCapture::stop()
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{};
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};
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)};
std::copy_n(data.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);
if LIKELY(bufferQueue)
{
const SLresult result{VCALL(bufferQueue,Enqueue)(data.first.buf, chunk_size)};
PRINTERR(result, "bufferQueue->Enqueue");
if UNLIKELY(SL_RESULT_SUCCESS != result)
SLresult result{SL_RESULT_SUCCESS};
auto wdata = mRing->getWriteVector();
for(size_t i{0u};i < wdata.first.len && SL_RESULT_SUCCESS == result;i++)
{
mDevice->handleDisconnect("Failed to update capture buffer: 0x%08x", result);
bufferQueue = nullptr;
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");
}
data.first.len--;
if(!data.first.len)
data.first = data.second;
else
data.first.buf += chunk_size;
}
i += rem;
}
}