From 9aab39b5202168d3940f2356b80b63a2868241c8 Mon Sep 17 00:00:00 2001 From: jiabin Date: Thu, 15 Apr 2021 17:38:10 +0000 Subject: [PATCH 1/3] Use an array of callback buffer for OpenSL ES. --- src/opensles/AudioStreamOpenSLES.cpp | 15 ++++++++++++--- src/opensles/AudioStreamOpenSLES.h | 6 +++++- 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/src/opensles/AudioStreamOpenSLES.cpp b/src/opensles/AudioStreamOpenSLES.cpp index b99568ae6..cd59dd049 100644 --- a/src/opensles/AudioStreamOpenSLES.cpp +++ b/src/opensles/AudioStreamOpenSLES.cpp @@ -130,7 +130,9 @@ Result AudioStreamOpenSLES::configureBufferSizes(int32_t sampleRate) { return Result::ErrorInvalidFormat; // causing bytesPerFrame == 0 } - mCallbackBuffer = std::make_unique(mBytesPerCallback); + for (int i = 0; i < kBufferQueueLength; ++i) { + mCallbackBuffer[i] = std::make_unique(mBytesPerCallback); + } if (!usingFIFO()) { mBufferCapacityInFrames = mFramesPerBurst * kBufferQueueLength; @@ -291,8 +293,14 @@ Result AudioStreamOpenSLES::close_l() { return Result::OK; } +uint8_t* AudioStreamOpenSLES::getBufferToProcess(int* bufferIdx) { + uint8_t* bufferToProcess = mCallbackBuffer[*bufferIdx].get(); + *bufferIdx = (*bufferIdx + 1) % kBufferQueueLength; + return bufferToProcess; +} + SLresult AudioStreamOpenSLES::enqueueCallbackBuffer(SLAndroidSimpleBufferQueueItf bq) { - return (*bq)->Enqueue(bq, mCallbackBuffer.get(), mBytesPerCallback); + return (*bq)->Enqueue(bq, getBufferToProcess(&mCallbackBufferIdxOpenSLES), mBytesPerCallback); } int32_t AudioStreamOpenSLES::getBufferDepth(SLAndroidSimpleBufferQueueItf bq) { @@ -304,7 +312,8 @@ int32_t AudioStreamOpenSLES::getBufferDepth(SLAndroidSimpleBufferQueueItf bq) { void AudioStreamOpenSLES::processBufferCallback(SLAndroidSimpleBufferQueueItf bq) { bool stopStream = false; // Ask the app callback to process the buffer. - DataCallbackResult result = fireDataCallback(mCallbackBuffer.get(), mFramesPerCallback); + DataCallbackResult result = + fireDataCallback(getBufferToProcess(&mCallbackBufferIdxApp), mFramesPerCallback); if (result == DataCallbackResult::Continue) { // Pass the buffer to OpenSLES. SLresult enqueueResult = enqueueCallbackBuffer(bq); diff --git a/src/opensles/AudioStreamOpenSLES.h b/src/opensles/AudioStreamOpenSLES.h index ebed3e546..3b0da673c 100644 --- a/src/opensles/AudioStreamOpenSLES.h +++ b/src/opensles/AudioStreamOpenSLES.h @@ -121,7 +121,11 @@ class AudioStreamOpenSLES : public AudioStreamBuffered { MonotonicCounter mPositionMillis; // for tracking OpenSL ES service position private: - std::unique_ptr mCallbackBuffer; + uint8_t* getBufferToProcess(int* bufferIdx); + + std::unique_ptr mCallbackBuffer[kBufferQueueLength]; + int mCallbackBufferIdxApp = 0; + int mCallbackBufferIdxOpenSLES = 0; std::atomic mState{StreamState::Uninitialized}; }; From ca20ebb6b78d3d0e9dde10691aee259dfe816bf0 Mon Sep 17 00:00:00 2001 From: jiabin Date: Thu, 22 Apr 2021 21:57:53 +0000 Subject: [PATCH 2/3] Fixes #1165. --- src/opensles/AudioInputStreamOpenSLES.cpp | 6 ++++-- src/opensles/AudioOutputStreamOpenSLES.cpp | 6 ++++-- src/opensles/AudioStreamOpenSLES.cpp | 14 ++++++-------- src/opensles/AudioStreamOpenSLES.h | 5 +---- 4 files changed, 15 insertions(+), 16 deletions(-) diff --git a/src/opensles/AudioInputStreamOpenSLES.cpp b/src/opensles/AudioInputStreamOpenSLES.cpp index b07b0ccdd..70d636616 100644 --- a/src/opensles/AudioInputStreamOpenSLES.cpp +++ b/src/opensles/AudioInputStreamOpenSLES.cpp @@ -273,9 +273,11 @@ Result AudioInputStreamOpenSLES::requestStart() { Result result = setRecordState_l(SL_RECORDSTATE_RECORDING); if (result == Result::OK) { setState(StreamState::Started); - // Enqueue the first buffer to start the streaming. + // Enqueue the first `kBufferQueueLength` buffer to start the streaming. // This does not call the callback function. - enqueueCallbackBuffer(mSimpleBufferQueueInterface); + for (size_t i = 0; i < kBufferQueueLength; ++i) { + enqueueCallbackBuffer(mSimpleBufferQueueInterface); + } } else { setState(initialState); } diff --git a/src/opensles/AudioOutputStreamOpenSLES.cpp b/src/opensles/AudioOutputStreamOpenSLES.cpp index 5791b5ec5..dbc119c5f 100644 --- a/src/opensles/AudioOutputStreamOpenSLES.cpp +++ b/src/opensles/AudioOutputStreamOpenSLES.cpp @@ -302,9 +302,11 @@ Result AudioOutputStreamOpenSLES::requestStart() { setState(StreamState::Started); mLock.unlock(); if (getBufferDepth(mSimpleBufferQueueInterface) == 0) { - // Enqueue the first buffer if needed to start the streaming. + // Enqueue the first `kBufferQueueLength` buffer if needed to start the streaming. // This might call requestStop() so try to avoid a recursive lock. - processBufferCallback(mSimpleBufferQueueInterface); + for (size_t i = 0; i < kBufferQueueLength; ++i) { + processBufferCallback(mSimpleBufferQueueInterface); + } } } else { setState(initialState); diff --git a/src/opensles/AudioStreamOpenSLES.cpp b/src/opensles/AudioStreamOpenSLES.cpp index cd59dd049..bc9e2c349 100644 --- a/src/opensles/AudioStreamOpenSLES.cpp +++ b/src/opensles/AudioStreamOpenSLES.cpp @@ -293,14 +293,11 @@ Result AudioStreamOpenSLES::close_l() { return Result::OK; } -uint8_t* AudioStreamOpenSLES::getBufferToProcess(int* bufferIdx) { - uint8_t* bufferToProcess = mCallbackBuffer[*bufferIdx].get(); - *bufferIdx = (*bufferIdx + 1) % kBufferQueueLength; - return bufferToProcess; -} - SLresult AudioStreamOpenSLES::enqueueCallbackBuffer(SLAndroidSimpleBufferQueueItf bq) { - return (*bq)->Enqueue(bq, getBufferToProcess(&mCallbackBufferIdxOpenSLES), mBytesPerCallback); + SLresult result = (*bq)->Enqueue( + bq, mCallbackBuffer[mCallbackBufferIndex].get(), mBytesPerCallback); + mCallbackBufferIndex = (mCallbackBufferIndex + 1) % kBufferQueueLength; + return result; } int32_t AudioStreamOpenSLES::getBufferDepth(SLAndroidSimpleBufferQueueItf bq) { @@ -313,7 +310,7 @@ void AudioStreamOpenSLES::processBufferCallback(SLAndroidSimpleBufferQueueItf bq bool stopStream = false; // Ask the app callback to process the buffer. DataCallbackResult result = - fireDataCallback(getBufferToProcess(&mCallbackBufferIdxApp), mFramesPerCallback); + fireDataCallback(mCallbackBuffer[mCallbackBufferIndex].get(), mFramesPerCallback); if (result == DataCallbackResult::Continue) { // Pass the buffer to OpenSLES. SLresult enqueueResult = enqueueCallbackBuffer(bq); @@ -336,6 +333,7 @@ void AudioStreamOpenSLES::processBufferCallback(SLAndroidSimpleBufferQueueItf bq } if (stopStream) { requestStop(); + mCallbackBufferIndex = 0; } } diff --git a/src/opensles/AudioStreamOpenSLES.h b/src/opensles/AudioStreamOpenSLES.h index 3b0da673c..18a13d0d3 100644 --- a/src/opensles/AudioStreamOpenSLES.h +++ b/src/opensles/AudioStreamOpenSLES.h @@ -121,11 +121,8 @@ class AudioStreamOpenSLES : public AudioStreamBuffered { MonotonicCounter mPositionMillis; // for tracking OpenSL ES service position private: - uint8_t* getBufferToProcess(int* bufferIdx); - std::unique_ptr mCallbackBuffer[kBufferQueueLength]; - int mCallbackBufferIdxApp = 0; - int mCallbackBufferIdxOpenSLES = 0; + int mCallbackBufferIndex = 0; std::atomic mState{StreamState::Uninitialized}; }; From e01181860cb1cd3d20f52f059c608085fee82e85 Mon Sep 17 00:00:00 2001 From: jiabin Date: Thu, 29 Jul 2021 18:32:39 +0000 Subject: [PATCH 3/3] Fixes #1165 --- src/opensles/AudioInputStreamOpenSLES.cpp | 6 ++---- src/opensles/AudioOutputStreamOpenSLES.cpp | 6 ++---- 2 files changed, 4 insertions(+), 8 deletions(-) diff --git a/src/opensles/AudioInputStreamOpenSLES.cpp b/src/opensles/AudioInputStreamOpenSLES.cpp index 70d636616..b07b0ccdd 100644 --- a/src/opensles/AudioInputStreamOpenSLES.cpp +++ b/src/opensles/AudioInputStreamOpenSLES.cpp @@ -273,11 +273,9 @@ Result AudioInputStreamOpenSLES::requestStart() { Result result = setRecordState_l(SL_RECORDSTATE_RECORDING); if (result == Result::OK) { setState(StreamState::Started); - // Enqueue the first `kBufferQueueLength` buffer to start the streaming. + // Enqueue the first buffer to start the streaming. // This does not call the callback function. - for (size_t i = 0; i < kBufferQueueLength; ++i) { - enqueueCallbackBuffer(mSimpleBufferQueueInterface); - } + enqueueCallbackBuffer(mSimpleBufferQueueInterface); } else { setState(initialState); } diff --git a/src/opensles/AudioOutputStreamOpenSLES.cpp b/src/opensles/AudioOutputStreamOpenSLES.cpp index dbc119c5f..5791b5ec5 100644 --- a/src/opensles/AudioOutputStreamOpenSLES.cpp +++ b/src/opensles/AudioOutputStreamOpenSLES.cpp @@ -302,11 +302,9 @@ Result AudioOutputStreamOpenSLES::requestStart() { setState(StreamState::Started); mLock.unlock(); if (getBufferDepth(mSimpleBufferQueueInterface) == 0) { - // Enqueue the first `kBufferQueueLength` buffer if needed to start the streaming. + // Enqueue the first buffer if needed to start the streaming. // This might call requestStop() so try to avoid a recursive lock. - for (size_t i = 0; i < kBufferQueueLength; ++i) { - processBufferCallback(mSimpleBufferQueueInterface); - } + processBufferCallback(mSimpleBufferQueueInterface); } } else { setState(initialState);