Hi Rich,
thank you for your reply.
If I understood you correctly, let me point out that my concern is not about sample accurate start / stop but rather whether mWritePos is modified in a way that possibly makes it jump the first samples of the new recording.
to recap what I said, imagine these instructions to happen in sequence
-> audio thread reads mWritePos as 2000 // fine
-> audio thread writes samples from 2000 to 3024 // fine, just finish the job in this block of samples
-> GUI thread sets mWritePos to 0 // ok, that's what GUI's supposed to do
-> audio thread sets mWritePos to 1024 ( mWritePos += 1024) // wrong!
-> process() is executed again, audio thread reads mWritePos as 1024, but it should be reading 0
Probably this will hardly happen because process() will be completely executed till the end as it's got higher priority.
However, for the sake of correctness, how about this fix ? Not 100% sure it's correct though. But it looks so to me...
- size_t writePos = mWritePos;
- size_t numWriteFrames = buffer->getNumFrames();
- if ( writePos + numWriteFrames > mRecorderBuffer.getNumFrames() )
- numWriteFrames = mRecorderBuffer.getNumFrames() - writePos;
- mRecorderBuffer.copyOffset(*buffer, numWriteFrames, writePos, 0);
- if ( numWriteFrames < buffer->getNumFrames() )
- mLastOverrun = getContext()->getNumProcessedFrames();
- const size_t writePosNew = writePos + numWriteFrames;
- // now use compare_exchange to check if write position has been reset by the GUI thread
- // if not mWritePos = writePosNew
- // otherwise it means mWritePos is zero (from ::start()) so next time ::process() is executed,
- // mWritePos will be 0 and theerefore the recording will start from 0
- mWritePos.compare_exchange_strong( writePos, writePosNew );
Hope this makes sense...
thanks!