I am trying to write a buffer for an audio system with Oboe, the do and don'ts are
Callback do's and don'ts You should never perform an operation which could block inside
onAudioReady
. Examples of blocking operations include:allocate memory using, for example,
malloc()
or new;file operations such as opening, closing, reading or writing;
network operations such as streaming;
use mutexes or other synchronization primitives sleep
stop or close the stream
Call
read()
orwrite()
on the stream which invoked it
Audio thread reads from my buffer and decoder thread writes to it and as you can imagine its all good until threading issues kicks in. My main problem is I can just use a mutex to overcome this issue but if i do so I will be blocking one of the threads and if audio thread is blocked then the sound basically not played resulting in "popcorn" sound. (A Sound that is so disturbing to listen to)
I play the sound through a callback where I feed the data to it.
DataCallbackResult
OboeStreamCallback::onAudioReady(AudioStream *audioStream, void *audioData, int32_t numFrames) {
// fill data here
return DataCallbackResult::Continue;
}
So my main issue is how may I solve read data from audio thread also not block audio thread so it can still play audio?
This sounds impossible to me. How may one can assure thread safety without a mutex? How does oboe expect you to not use mutex for dynamic audio decoding?
You can use a thread-safe lock-free queue for reading/writing data. This will avoid the need for mutexes, will be much faster and should fix your "popcorn" issues.
An example implementation can be found here: https://github.com/google/oboe/blob/master/samples/RhythmGame/src/main/cpp/utils/LockFreeQueue.h