Merge pull request #683 from google/bigburst
oboe: use bigger burst in OpenSL ES
diff --git a/src/common/AudioStreamBuilder.cpp b/src/common/AudioStreamBuilder.cpp
index 58fc3be..401beea 100644
--- a/src/common/AudioStreamBuilder.cpp
+++ b/src/common/AudioStreamBuilder.cpp
@@ -163,7 +163,7 @@
if (optimalBufferSize >= 0) {
auto setBufferResult = streamP->setBufferSizeInFrames(optimalBufferSize);
if (!setBufferResult) {
- LOGW("Failed to set buffer size to %d. Error was %s",
+ LOGW("Failed to setBufferSizeInFrames(%d). Error was %s",
optimalBufferSize,
convertToText(setBufferResult.error()));
}
diff --git a/src/opensles/AudioInputStreamOpenSLES.cpp b/src/opensles/AudioInputStreamOpenSLES.cpp
index 6b9ac5d..3c2d79b 100644
--- a/src/opensles/AudioInputStreamOpenSLES.cpp
+++ b/src/opensles/AudioInputStreamOpenSLES.cpp
@@ -196,12 +196,17 @@
goto error;
}
+ oboeResult = configureBufferSizes();
+ if (Result::OK != oboeResult) {
+ goto error;
+ }
+
allocateFifo();
setState(StreamState::Open);
return Result::OK;
- error:
+error:
return Result::ErrorInternal; // TODO convert error from SLES to OBOE
}
diff --git a/src/opensles/AudioOutputStreamOpenSLES.cpp b/src/opensles/AudioOutputStreamOpenSLES.cpp
index b94cdf3..2312a76 100644
--- a/src/opensles/AudioOutputStreamOpenSLES.cpp
+++ b/src/opensles/AudioOutputStreamOpenSLES.cpp
@@ -221,10 +221,16 @@
goto error;
}
+ oboeResult = configureBufferSizes();
+ if (Result::OK != oboeResult) {
+ goto error;
+ }
+
allocateFifo();
setState(StreamState::Open);
return Result::OK;
+
error:
return Result::ErrorInternal; // TODO convert error from SLES to OBOE
}
diff --git a/src/opensles/AudioStreamBuffered.cpp b/src/opensles/AudioStreamBuffered.cpp
index 42a7e58..51dd4d5 100644
--- a/src/opensles/AudioStreamBuffered.cpp
+++ b/src/opensles/AudioStreamBuffered.cpp
@@ -24,7 +24,7 @@
namespace oboe {
constexpr int kDefaultBurstsPerBuffer = 16; // arbitrary, allows dynamic latency tuning
-
+constexpr int kMinFramesPerBuffer = 48 * 32; // arbitrary
/*
* AudioStream with a FifoBuffer
*/
@@ -37,13 +37,14 @@
// callback that reads data from the FIFO.
if (usingFIFO()) {
// FIFO is configured with the same format and channels as the stream.
- int32_t capacity = getBufferCapacityInFrames();
- if (capacity == oboe::kUnspecified) {
- capacity = getFramesPerBurst() * kDefaultBurstsPerBuffer;
- mBufferCapacityInFrames = capacity;
+ int32_t capacityFrames = getBufferCapacityInFrames();
+ if (capacityFrames == oboe::kUnspecified) {
+ capacityFrames = getFramesPerBurst() * kDefaultBurstsPerBuffer;
}
+ capacityFrames = std::max(kMinFramesPerBuffer, capacityFrames);
// TODO consider using std::make_unique if we require c++14
- mFifoBuffer.reset(new FifoBuffer(getBytesPerFrame(), capacity));
+ mFifoBuffer.reset(new FifoBuffer(getBytesPerFrame(), capacityFrames));
+ mBufferCapacityInFrames = capacityFrames;
}
}
@@ -72,6 +73,8 @@
}
if (framesTransferred < numFrames) {
+ LOGD("AudioStreamBuffered::%s(): xrun! framesTransferred = %d, numFrames = %d",
+ __func__, framesTransferred, numFrames);
// TODO If we do not allow FIFO to wrap then our timestamps will drift when there is an XRun!
incrementXRunCount();
}
diff --git a/src/opensles/AudioStreamOpenSLES.cpp b/src/opensles/AudioStreamOpenSLES.cpp
index e168edb..8d6b763 100644
--- a/src/opensles/AudioStreamOpenSLES.cpp
+++ b/src/opensles/AudioStreamOpenSLES.cpp
@@ -37,8 +37,9 @@
mSessionId = SessionId::None;
}
-constexpr SLuint32 kAudioChannelCountMax = 30;
-constexpr SLuint32 SL_ANDROID_UNKNOWN_CHANNELMASK = 0; // Matches name used internally.
+static constexpr int32_t kFramesPerHighLatencyBurst = 960; // typical, 20 msec at 48000
+static constexpr SLuint32 kAudioChannelCountMax = 30; // TODO Why 30?
+static constexpr SLuint32 SL_ANDROID_UNKNOWN_CHANNELMASK = 0; // Matches name used internally.
SLuint32 AudioStreamOpenSLES::channelCountToChannelMaskDefault(int channelCount) const {
if (channelCount > kAudioChannelCountMax) {
@@ -69,7 +70,7 @@
Result AudioStreamOpenSLES::open() {
LOGI("AudioStreamOpenSLES::open(chans:%d, rate:%d)",
- mChannelCount, mSampleRate);
+ mChannelCount, mSampleRate);
SLresult result = EngineOpenSLES::getInstance().open();
if (SL_RESULT_SUCCESS != result) {
@@ -88,28 +89,35 @@
mChannelCount = DefaultStreamValues::ChannelCount;
}
+ mSharingMode = SharingMode::Shared;
+
+ return Result::OK;
+}
+
+Result AudioStreamOpenSLES::configureBufferSizes() {
// Decide frames per burst based on hints from caller.
- // TODO Can we query this from OpenSL ES?
- if (mFramesPerCallback != kUnspecified) {
- mFramesPerBurst = mFramesPerCallback;
- } else if (mFramesPerBurst != kUnspecified) { // set from defaultFramesPerBurst
- mFramesPerCallback = mFramesPerBurst;
- } else {
- mFramesPerBurst = mFramesPerCallback = DefaultStreamValues::FramesPerBurst;
+ mFramesPerBurst = mFramesPerCallback;
+ if (mFramesPerBurst == kUnspecified) {
+ mFramesPerBurst = DefaultStreamValues::FramesPerBurst;
}
+ // For high latency streams, use a larger buffer size.
+ if (mPerformanceMode != PerformanceMode::LowLatency
+ && mFramesPerBurst < kFramesPerHighLatencyBurst) {
+ mFramesPerBurst = kFramesPerHighLatencyBurst;
+ LOGD("AudioStreamOpenSLES:%s() NOT low latency, set mFramesPerBurst = %d",
+ __func__, mFramesPerBurst);
+ }
+ mFramesPerCallback = mFramesPerBurst;
mBytesPerCallback = mFramesPerCallback * getBytesPerFrame();
- LOGD("AudioStreamOpenSLES(): mFramesPerCallback = %d", mFramesPerCallback);
- LOGD("AudioStreamOpenSLES(): mBytesPerCallback = %d", mBytesPerCallback);
if (mBytesPerCallback <= 0) {
- LOGE("AudioStreamOpenSLES::open() bytesPerCallback < 0, bad format?");
+ LOGE("AudioStreamOpenSLES::open() bytesPerCallback < 0 = %d, bad format?",
+ mBytesPerCallback);
return Result::ErrorInvalidFormat; // causing bytesPerFrame == 0
}
mCallbackBuffer = std::make_unique<uint8_t[]>(mBytesPerCallback);
- mSharingMode = SharingMode::Shared;
-
if (!usingFIFO()) {
mBufferCapacityInFrames = mFramesPerBurst * kBufferQueueLength;
mBufferSizeInFrames = mBufferCapacityInFrames;
@@ -170,7 +178,6 @@
SLresult result = SL_RESULT_SUCCESS;
SLuint32 performanceMode = convertPerformanceMode(getPerformanceMode());
- LOGD("SetConfiguration(SL_ANDROID_KEY_PERFORMANCE_MODE, SL %u) called", performanceMode);
result = (*configItf)->SetConfiguration(configItf, SL_ANDROID_KEY_PERFORMANCE_MODE,
&performanceMode, sizeof(performanceMode));
if (SL_RESULT_SUCCESS != result) {
diff --git a/src/opensles/AudioStreamOpenSLES.h b/src/opensles/AudioStreamOpenSLES.h
index d1f362a..40220ab 100644
--- a/src/opensles/AudioStreamOpenSLES.h
+++ b/src/opensles/AudioStreamOpenSLES.h
@@ -100,6 +100,9 @@
PerformanceMode convertPerformanceMode(SLuint32 openslMode) const;
SLuint32 convertPerformanceMode(PerformanceMode oboeMode) const;
+
+ Result configureBufferSizes();
+
/**
* Internal use only.
* Use this instead of directly setting the internal state variable.