summaryrefslogtreecommitdiffstats
path: root/services/audioflinger/MonoPipe.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'services/audioflinger/MonoPipe.cpp')
-rw-r--r--services/audioflinger/MonoPipe.cpp58
1 files changed, 20 insertions, 38 deletions
diff --git a/services/audioflinger/MonoPipe.cpp b/services/audioflinger/MonoPipe.cpp
index fd16e92..6efb8b1 100644
--- a/services/audioflinger/MonoPipe.cpp
+++ b/services/audioflinger/MonoPipe.cpp
@@ -25,9 +25,10 @@
namespace android {
-MonoPipe::MonoPipe(size_t maxFrames, NBAIO_Format format, bool writeCanBlock) :
+MonoPipe::MonoPipe(size_t reqFrames, NBAIO_Format format, bool writeCanBlock) :
NBAIO_Sink(format),
- mMaxFrames(roundup(maxFrames)),
+ mReqFrames(reqFrames),
+ mMaxFrames(roundup(reqFrames)),
mBuffer(malloc(mMaxFrames * Format_frameSize(format))),
mFront(0),
mRear(0),
@@ -45,6 +46,7 @@ ssize_t MonoPipe::availableToWrite() const
if (CC_UNLIKELY(!mNegotiated)) {
return NEGOTIATE;
}
+ // uses mMaxFrames not mReqFrames, so allows "over-filling" the pipe beyond requested limit
ssize_t ret = mMaxFrames - (mRear - android_atomic_acquire_load(&mFront));
ALOG_ASSERT((0 <= ret) && (ret <= mMaxFrames));
return ret;
@@ -57,6 +59,7 @@ ssize_t MonoPipe::write(const void *buffer, size_t count)
}
size_t totalFramesWritten = 0;
while (count > 0) {
+ // can't return a negative value, as we already checked for !mNegotiated
size_t avail = availableToWrite();
size_t written = avail;
if (CC_LIKELY(written > count)) {
@@ -84,50 +87,29 @@ ssize_t MonoPipe::write(const void *buffer, size_t count)
count -= written;
buffer = (char *) buffer + (written << mBitShift);
// Simulate blocking I/O by sleeping at different rates, depending on a throttle.
- // The throttle tries to keep the pipe about 5/8 full on average, with a slight jitter.
- uint64_t ns;
- enum {
- THROTTLE_VERY_FAST, // pipe is (nearly) empty, fill quickly
- THROTTLE_FAST, // pipe is normal, fill at slightly faster rate
- THROTTLE_NOMINAL, // pipe is normal, fill at nominal rate
- THROTTLE_SLOW, // pipe is normal, fill at slightly slower rate
- THROTTLE_VERY_SLOW, // pipe is (nearly) full, fill slowly
- } throttle;
- avail -= written;
- // FIXME cache these values to avoid re-computation
- if (avail >= (mMaxFrames * 3) / 4) {
- throttle = THROTTLE_VERY_FAST;
- } else if (avail >= mMaxFrames / 2) {
- throttle = THROTTLE_FAST;
- } else if (avail >= (mMaxFrames * 3) / 8) {
- throttle = THROTTLE_NOMINAL;
- } else if (avail >= mMaxFrames / 4) {
- throttle = THROTTLE_SLOW;
- } else {
- throttle = THROTTLE_VERY_SLOW;
- }
+ // The throttle tries to keep the pipe about 11/16 full on average, with a slight jitter.
+ uint32_t ns;
if (written > 0) {
- // FIXME cache these values also
- switch (throttle) {
- case THROTTLE_VERY_FAST:
- default:
+ size_t filled = (mMaxFrames - avail) + written;
+ // FIXME cache these values to avoid re-computation
+ if (filled <= mReqFrames / 4) {
+ // pipe is (nearly) empty, fill quickly
ns = written * ( 500000000 / Format_sampleRate(mFormat));
- break;
- case THROTTLE_FAST:
+ } else if (filled <= mReqFrames / 2) {
+ // pipe is normal, fill at slightly faster rate
ns = written * ( 750000000 / Format_sampleRate(mFormat));
- break;
- case THROTTLE_NOMINAL:
+ } else if (filled <= (mReqFrames * 5) / 8) {
+ // pipe is normal, fill at nominal rate
ns = written * (1000000000 / Format_sampleRate(mFormat));
- break;
- case THROTTLE_SLOW:
+ } else if (filled <= (mReqFrames * 3) / 4) {
+ // pipe is normal, fill at slightly slower rate
ns = written * (1100000000 / Format_sampleRate(mFormat));
- break;
- case THROTTLE_VERY_SLOW:
+ } else {
+ // pipe is (nearly) full, fill slowly
ns = written * (1250000000 / Format_sampleRate(mFormat));
- break;
}
} else {
- ns = mMaxFrames * (250000000 / Format_sampleRate(mFormat));
+ ns = mReqFrames * (250000000 / Format_sampleRate(mFormat));
}
if (ns > 999999999) {
ns = 999999999;