Merge "Rename (IF_)LOGI(_IF) to (IF_)ALOGI(_IF)  DO NOT MERGE"
diff --git a/media/libeffects/testlibs/AudioBiquadFilter.cpp b/media/libeffects/testlibs/AudioBiquadFilter.cpp
index 72917a3..16dd1c5 100644
--- a/media/libeffects/testlibs/AudioBiquadFilter.cpp
+++ b/media/libeffects/testlibs/AudioBiquadFilter.cpp
@@ -17,12 +17,10 @@
 
 #include <string.h>
 #include <assert.h>
+#include <cutils/compiler.h>
 
 #include "AudioBiquadFilter.h"
 
-#define LIKELY( exp )       (__builtin_expect( (exp) != 0, true  ))
-#define UNLIKELY( exp )     (__builtin_expect( (exp) != 0, false ))
-
 namespace android {
 
 const audio_coef_t AudioBiquadFilter::IDENTITY_COEFS[AudioBiquadFilter::NUM_COEFS] = { AUDIO_COEF_ONE, 0, 0, 0, 0 };
@@ -55,7 +53,7 @@
 void AudioBiquadFilter::setCoefs(const audio_coef_t coefs[NUM_COEFS], bool immediate) {
     memcpy(mTargetCoefs, coefs, sizeof(mTargetCoefs));
     if (mState & STATE_ENABLED_MASK) {
-        if (UNLIKELY(immediate)) {
+        if (CC_UNLIKELY(immediate)) {
             memcpy(mCoefs, coefs, sizeof(mCoefs));
             setState(STATE_NORMAL);
         } else {
@@ -70,7 +68,7 @@
 }
 
 void AudioBiquadFilter::enable(bool immediate) {
-    if (UNLIKELY(immediate)) {
+    if (CC_UNLIKELY(immediate)) {
         memcpy(mCoefs, mTargetCoefs, sizeof(mCoefs));
         setState(STATE_NORMAL);
     } else {
@@ -79,7 +77,7 @@
 }
 
 void AudioBiquadFilter::disable(bool immediate) {
-    if (UNLIKELY(immediate)) {
+    if (CC_UNLIKELY(immediate)) {
         memcpy(mCoefs, IDENTITY_COEFS, sizeof(mCoefs));
         setState(STATE_BYPASS);
     } else {
@@ -142,7 +140,7 @@
                                        audio_sample_t * out,
                                        int frameCount) {
     // The common case is in-place processing, because this is what the EQ does.
-    if (UNLIKELY(in != out)) {
+    if (CC_UNLIKELY(in != out)) {
         memcpy(out, in, frameCount * mNumChannels * sizeof(audio_sample_t));
     }
 }
diff --git a/media/libeffects/testlibs/AudioCoefInterpolator.cpp b/media/libeffects/testlibs/AudioCoefInterpolator.cpp
index 039ab9f..6b56922 100644
--- a/media/libeffects/testlibs/AudioCoefInterpolator.cpp
+++ b/media/libeffects/testlibs/AudioCoefInterpolator.cpp
@@ -16,10 +16,10 @@
  */
 
 #include <string.h>
-#include "AudioCoefInterpolator.h"
 
-#define LIKELY( exp )       (__builtin_expect( (exp) != 0, true  ))
-#define UNLIKELY( exp )     (__builtin_expect( (exp) != 0, false ))
+#include <cutils/compiler.h>
+
+#include "AudioCoefInterpolator.h"
 
 namespace android {
 
@@ -44,9 +44,9 @@
     size_t index = 0;
     size_t dim = mNumInDims;
     while (dim-- > 0) {
-        if (UNLIKELY(intCoord[dim] < 0)) {
+        if (CC_UNLIKELY(intCoord[dim] < 0)) {
             fracCoord[dim] = 0;
-        } else if (UNLIKELY(intCoord[dim] >= (int)mInDims[dim] - 1)) {
+        } else if (CC_UNLIKELY(intCoord[dim] >= (int)mInDims[dim] - 1)) {
             fracCoord[dim] = 0;
             index += mInDimOffsets[dim] * (mInDims[dim] - 1);
         } else {
@@ -63,7 +63,7 @@
         memcpy(out, mTable + index, mNumOutDims * sizeof(audio_coef_t));
     } else {
         getCoefRecurse(index, fracCoord, out, dim + 1);
-        if (LIKELY(fracCoord != 0)) {
+        if (CC_LIKELY(fracCoord != 0)) {
            audio_coef_t tempCoef[MAX_OUT_DIMS];
            getCoefRecurse(index + mInDimOffsets[dim], fracCoord, tempCoef,
                            dim + 1);
diff --git a/media/libeffects/testlibs/AudioCommon.h b/media/libeffects/testlibs/AudioCommon.h
index 444f93a..e8080dc 100644
--- a/media/libeffects/testlibs/AudioCommon.h
+++ b/media/libeffects/testlibs/AudioCommon.h
@@ -20,6 +20,7 @@
 
 #include <stdint.h>
 #include <stddef.h>
+#include <cutils/compiler.h>
 
 namespace android {
 
@@ -76,9 +77,9 @@
 // Convert a audio_sample_t sample to S15 (with clipping)
 inline int16_t audio_sample_t_to_s15_clip(audio_sample_t sample) {
     // TODO: optimize for targets supporting this as an atomic operation.
-    if (__builtin_expect(sample >= (0x7FFF << 9), 0)) {
+    if (CC_UNLIKELY(sample >= (0x7FFF << 9))) {
         return 0x7FFF;
-    } else if (__builtin_expect(sample <= -(0x8000 << 9), 0)) {
+    } else if (CC_UNLIKELY(sample <= -(0x8000 << 9))) {
         return 0x8000;
     } else {
         return audio_sample_t_to_s15(sample);
diff --git a/media/libeffects/testlibs/AudioPeakingFilter.cpp b/media/libeffects/testlibs/AudioPeakingFilter.cpp
index 60fefe6..99323ac 100644
--- a/media/libeffects/testlibs/AudioPeakingFilter.cpp
+++ b/media/libeffects/testlibs/AudioPeakingFilter.cpp
@@ -21,9 +21,7 @@
 
 #include <new>
 #include <assert.h>
-
-#define LIKELY( exp )       (__builtin_expect( (exp) != 0, true  ))
-#define UNLIKELY( exp )     (__builtin_expect( (exp) != 0, false ))
+#include <cutils/compiler.h>
 
 namespace android {
 // Format of the coefficient table:
@@ -66,12 +64,12 @@
 
 void AudioPeakingFilter::setFrequency(uint32_t millihertz) {
     mNominalFrequency = millihertz;
-    if (UNLIKELY(millihertz > mNiquistFreq / 2)) {
+    if (CC_UNLIKELY(millihertz > mNiquistFreq / 2)) {
         millihertz = mNiquistFreq / 2;
     }
     uint32_t normFreq = static_cast<uint32_t>(
             (static_cast<uint64_t>(millihertz) * mFrequencyFactor) >> 10);
-    if (LIKELY(normFreq > (1 << 23))) {
+    if (CC_LIKELY(normFreq > (1 << 23))) {
         mFrequency = (Effects_log2(normFreq) - ((32-9) << 15)) << (FREQ_PRECISION_BITS - 15);
     } else {
         mFrequency = 0;
@@ -107,11 +105,11 @@
     int32_t halfBW = (((mBandwidth + 1) / 2) << 15) / 1200;
 
     low = static_cast<uint32_t>((static_cast<uint64_t>(mNominalFrequency) * Effects_exp2(-halfBW + (16 << 15))) >> 16);
-    if (UNLIKELY(halfBW >= (16 << 15))) {
+    if (CC_UNLIKELY(halfBW >= (16 << 15))) {
         high = mNiquistFreq;
     } else {
         high = static_cast<uint32_t>((static_cast<uint64_t>(mNominalFrequency) * Effects_exp2(halfBW + (16 << 15))) >> 16);
-        if (UNLIKELY(high > mNiquistFreq)) {
+        if (CC_UNLIKELY(high > mNiquistFreq)) {
             high = mNiquistFreq;
         }
     }
diff --git a/media/libeffects/testlibs/AudioShelvingFilter.cpp b/media/libeffects/testlibs/AudioShelvingFilter.cpp
index b8650ba..e031287 100644
--- a/media/libeffects/testlibs/AudioShelvingFilter.cpp
+++ b/media/libeffects/testlibs/AudioShelvingFilter.cpp
@@ -21,9 +21,7 @@
 
 #include <new>
 #include <assert.h>
-
-#define LIKELY( exp )       (__builtin_expect( (exp) != 0, true  ))
-#define UNLIKELY( exp )     (__builtin_expect( (exp) != 0, false ))
+#include <cutils/compiler.h>
 
 namespace android {
 // Format of the coefficient tables:
@@ -71,13 +69,13 @@
 
 void AudioShelvingFilter::setFrequency(uint32_t millihertz) {
     mNominalFrequency = millihertz;
-    if (UNLIKELY(millihertz > mNiquistFreq / 2)) {
+    if (CC_UNLIKELY(millihertz > mNiquistFreq / 2)) {
         millihertz = mNiquistFreq / 2;
     }
     uint32_t normFreq = static_cast<uint32_t>(
             (static_cast<uint64_t>(millihertz) * mFrequencyFactor) >> 10);
     uint32_t log2minFreq = (mType == kLowShelf ? (32-10) : (32-2));
-    if (LIKELY(normFreq > (1U << log2minFreq))) {
+    if (CC_LIKELY(normFreq > (1U << log2minFreq))) {
         mFrequency = (Effects_log2(normFreq) - (log2minFreq << 15)) << (FREQ_PRECISION_BITS - 15);
     } else {
         mFrequency = 0;
diff --git a/media/libmedia/AudioRecord.cpp b/media/libmedia/AudioRecord.cpp
index 1d8e15b..dd1c6a5 100644
--- a/media/libmedia/AudioRecord.cpp
+++ b/media/libmedia/AudioRecord.cpp
@@ -39,9 +39,7 @@
 
 #include <system/audio.h>
 #include <cutils/bitops.h>
-
-#define LIKELY( exp )       (__builtin_expect( (exp) != 0, true  ))
-#define UNLIKELY( exp )     (__builtin_expect( (exp) != 0, false ))
+#include <cutils/compiler.h>
 
 namespace android {
 // ---------------------------------------------------------------------------
@@ -513,11 +511,11 @@
         goto start_loop_here;
         while (framesReady == 0) {
             active = mActive;
-            if (UNLIKELY(!active)) {
+            if (CC_UNLIKELY(!active)) {
                 cblk->lock.unlock();
                 return NO_MORE_BUFFERS;
             }
-            if (UNLIKELY(!waitCount)) {
+            if (CC_UNLIKELY(!waitCount)) {
                 cblk->lock.unlock();
                 return WOULD_BLOCK;
             }
@@ -534,7 +532,7 @@
             if (cblk->flags & CBLK_INVALID_MSK) {
                 goto create_new_record;
             }
-            if (__builtin_expect(result!=NO_ERROR, false)) {
+            if (CC_UNLIKELY(result != NO_ERROR)) {
                 cblk->waitTimeMs += waitTimeMs;
                 if (cblk->waitTimeMs >= cblk->bufferTimeoutMs) {
                     LOGW(   "obtainBuffer timed out (is the CPU pegged?) "
diff --git a/media/libmedia/AudioTrack.cpp b/media/libmedia/AudioTrack.cpp
index 6868d99..e0c6ca5 100644
--- a/media/libmedia/AudioTrack.cpp
+++ b/media/libmedia/AudioTrack.cpp
@@ -38,13 +38,11 @@
 #include <utils/Atomic.h>
 
 #include <cutils/bitops.h>
+#include <cutils/compiler.h>
 
 #include <system/audio.h>
 #include <system/audio_policy.h>
 
-#define LIKELY( exp )       (__builtin_expect( (exp) != 0, true  ))
-#define UNLIKELY( exp )     (__builtin_expect( (exp) != 0, false ))
-
 namespace android {
 // ---------------------------------------------------------------------------
 
@@ -856,12 +854,12 @@
         goto start_loop_here;
         while (framesAvail == 0) {
             active = mActive;
-            if (UNLIKELY(!active)) {
+            if (CC_UNLIKELY(!active)) {
                 ALOGV("Not active and NO_MORE_BUFFERS");
                 cblk->lock.unlock();
                 return NO_MORE_BUFFERS;
             }
-            if (UNLIKELY(!waitCount)) {
+            if (CC_UNLIKELY(!waitCount)) {
                 cblk->lock.unlock();
                 return WOULD_BLOCK;
             }
@@ -879,7 +877,7 @@
             if (cblk->flags & CBLK_INVALID_MSK) {
                 goto create_new_track;
             }
-            if (__builtin_expect(result!=NO_ERROR, false)) {
+            if (CC_UNLIKELY(result != NO_ERROR)) {
                 cblk->waitTimeMs += waitTimeMs;
                 if (cblk->waitTimeMs >= cblk->bufferTimeoutMs) {
                     // timing out when a loop has been set and we have already written upto loop end
diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp
index a893cf2..ab94bb8 100644
--- a/services/audioflinger/AudioFlinger.cpp
+++ b/services/audioflinger/AudioFlinger.cpp
@@ -35,6 +35,7 @@
 
 #include <cutils/bitops.h>
 #include <cutils/properties.h>
+#include <cutils/compiler.h>
 
 #include <media/AudioTrack.h>
 #include <media/AudioRecord.h>
@@ -1930,8 +1931,8 @@
             const SortedVector< wp<Track> >& activeTracks = mActiveTracks;
 
             // put audio hardware into standby after short delay
-            if UNLIKELY((!activeTracks.size() && systemTime() > standbyTime) ||
-                        mSuspended) {
+            if (CC_UNLIKELY((!activeTracks.size() && systemTime() > standbyTime) ||
+                        mSuspended)) {
                 if (!mStandby) {
                     ALOGV("Audio hardware entering standby, mixer %p, mSuspended %d\n", this, mSuspended);
                     mOutput->stream->common.standby(&mOutput->stream->common);
@@ -1976,7 +1977,7 @@
             lockEffectChains_l(effectChains);
         }
 
-        if (LIKELY(mixerStatus == MIXER_TRACKS_READY)) {
+        if (CC_LIKELY(mixerStatus == MIXER_TRACKS_READY)) {
             // mix buffers...
             mAudioMixer->process();
             sleepTime = 0;
@@ -2101,12 +2102,13 @@
         sp<Track> t = activeTracks[i].promote();
         if (t == 0) continue;
 
+        // this const just means the local variable doesn't change
         Track* const track = t.get();
         audio_track_cblk_t* cblk = track->cblk();
 
         // The first time a track is added we wait
         // for all its buffers to be filled before processing it
-        mAudioMixer->setActiveTrack(track->name());
+        int name = track->name();
         // make sure that we have enough frames to mix one full buffer.
         // enforce this condition only once to enable draining the buffer in case the client
         // app does not call stop() and relies on underrun to stop:
@@ -2118,13 +2120,21 @@
             if (t->sampleRate() == (int)mSampleRate) {
                 minFrames = mFrameCount;
             } else {
-                minFrames = (mFrameCount * t->sampleRate()) / mSampleRate + 1;
+                // +1 for rounding and +1 for additional sample needed for interpolation
+                minFrames = (mFrameCount * t->sampleRate()) / mSampleRate + 1 + 1;
+                // add frames already consumed but not yet released by the resampler
+                // because cblk->framesReady() will  include these frames
+                minFrames += mAudioMixer->getUnreleasedFrames(track->name());
+                // the minimum track buffer size is normally twice the number of frames necessary
+                // to fill one buffer and the resampler should not leave more than one buffer worth
+                // of unreleased frames after each pass, but just in case...
+                LOG_ASSERT(minFrames <= cblk->frameCount);
             }
         }
         if ((cblk->framesReady() >= minFrames) && track->isReady() &&
                 !track->isPaused() && !track->isTerminated())
         {
-            //ALOGV("track %d u=%08x, s=%08x [OK] on thread %p", track->name(), cblk->user, cblk->server, this);
+            //ALOGV("track %d u=%08x, s=%08x [OK] on thread %p", name, cblk->user, cblk->server, this);
 
             mixedTracks++;
 
@@ -2137,8 +2147,8 @@
                 if (chain != 0) {
                     tracksWithEffect++;
                 } else {
-                    LOGW("prepareTracks_l(): track %08x attached to effect but no chain found on session %d",
-                            track->name(), track->sessionId());
+                    LOGW("prepareTracks_l(): track %d attached to effect but no chain found on session %d",
+                            name, track->sessionId());
                 }
             }
 
@@ -2151,7 +2161,7 @@
                     track->mState = TrackBase::ACTIVE;
                     param = AudioMixer::RAMP_VOLUME;
                 }
-                mAudioMixer->setParameter(AudioMixer::RESAMPLE, AudioMixer::RESET, NULL);
+                mAudioMixer->setParameter(name, AudioMixer::RESAMPLE, AudioMixer::RESET, NULL);
             } else if (cblk->server != 0) {
                 // If the track is stopped before the first frame was mixed,
                 // do not apply ramp
@@ -2203,26 +2213,31 @@
             aux = int16_t(va);
 
             // XXX: these things DON'T need to be done each time
-            mAudioMixer->setBufferProvider(track);
-            mAudioMixer->enable();
+            mAudioMixer->setBufferProvider(name, track);
+            mAudioMixer->enable(name);
 
-            mAudioMixer->setParameter(param, AudioMixer::VOLUME0, (void *)left);
-            mAudioMixer->setParameter(param, AudioMixer::VOLUME1, (void *)right);
-            mAudioMixer->setParameter(param, AudioMixer::AUXLEVEL, (void *)aux);
+            mAudioMixer->setParameter(name, param, AudioMixer::VOLUME0, (void *)left);
+            mAudioMixer->setParameter(name, param, AudioMixer::VOLUME1, (void *)right);
+            mAudioMixer->setParameter(name, param, AudioMixer::AUXLEVEL, (void *)aux);
             mAudioMixer->setParameter(
+                name,
                 AudioMixer::TRACK,
                 AudioMixer::FORMAT, (void *)track->format());
             mAudioMixer->setParameter(
+                name,
                 AudioMixer::TRACK,
                 AudioMixer::CHANNEL_MASK, (void *)track->channelMask());
             mAudioMixer->setParameter(
+                name,
                 AudioMixer::RESAMPLE,
                 AudioMixer::SAMPLE_RATE,
                 (void *)(cblk->sampleRate));
             mAudioMixer->setParameter(
+                name,
                 AudioMixer::TRACK,
                 AudioMixer::MAIN_BUFFER, (void *)track->mainBuffer());
             mAudioMixer->setParameter(
+                name,
                 AudioMixer::TRACK,
                 AudioMixer::AUX_BUFFER, (void *)track->auxBuffer());
 
@@ -2230,7 +2245,7 @@
             track->mRetryCount = kMaxTrackRetries;
             mixerStatus = MIXER_TRACKS_READY;
         } else {
-            //ALOGV("track %d u=%08x, s=%08x [NOT READY] on thread %p", track->name(), cblk->user, cblk->server, this);
+            //ALOGV("track %d u=%08x, s=%08x [NOT READY] on thread %p", name, cblk->user, cblk->server, this);
             if (track->isStopped()) {
                 track->reset();
             }
@@ -2242,7 +2257,7 @@
                 // No buffers for this track. Give it a few chances to
                 // fill a buffer, then remove it from active list.
                 if (--(track->mRetryCount) <= 0) {
-                    ALOGV("BUFFER TIMEOUT: remove(%d) from active list on thread %p", track->name(), this);
+                    ALOGV("BUFFER TIMEOUT: remove(%d) from active list on thread %p", name, this);
                     tracksToRemove->add(track);
                     // indicate to client process that the track was disabled because of underrun
                     android_atomic_or(CBLK_DISABLED_ON, &cblk->flags);
@@ -2250,13 +2265,13 @@
                     mixerStatus = MIXER_TRACKS_ENABLED;
                 }
             }
-            mAudioMixer->disable();
+            mAudioMixer->disable(name);
         }
     }
 
     // remove all the tracks that need to be...
     count = tracksToRemove->size();
-    if (UNLIKELY(count)) {
+    if (CC_UNLIKELY(count)) {
         for (size_t i=0 ; i<count ; i++) {
             const sp<Track>& track = tracksToRemove->itemAt(i);
             mActiveTracks.remove(track);
@@ -2591,8 +2606,8 @@
             }
 
             // put audio hardware into standby after short delay
-            if UNLIKELY((!mActiveTracks.size() && systemTime() > standbyTime) ||
-                        mSuspended) {
+            if (CC_UNLIKELY((!mActiveTracks.size() && systemTime() > standbyTime) ||
+                        mSuspended)) {
                 // wait until we have something to do...
                 if (!mStandby) {
                     ALOGV("Audio hardware entering standby, mixer %p\n", this);
@@ -2742,7 +2757,7 @@
             }
 
             // remove all the tracks that need to be...
-            if (UNLIKELY(trackToRemove != 0)) {
+            if (CC_UNLIKELY(trackToRemove != 0)) {
                 mActiveTracks.remove(trackToRemove);
                 if (!effectChains.isEmpty()) {
                     ALOGV("stopping track on chain %p for session Id: %d", effectChains[0].get(),
@@ -2757,7 +2772,7 @@
             lockEffectChains_l(effectChains);
        }
 
-        if (LIKELY(mixerStatus == MIXER_TRACKS_READY)) {
+        if (CC_LIKELY(mixerStatus == MIXER_TRACKS_READY)) {
             AudioBufferProvider::Buffer buffer;
             size_t frameCount = mFrameCount;
             curBuf = (int8_t *)mMixBuffer;
@@ -2765,7 +2780,7 @@
             while (frameCount) {
                 buffer.frameCount = frameCount;
                 activeTrack->getNextBuffer(&buffer);
-                if (UNLIKELY(buffer.raw == NULL)) {
+                if (CC_UNLIKELY(buffer.raw == NULL)) {
                     memset(curBuf, 0, frameCount * mFrameSize);
                     break;
                 }
@@ -2984,8 +2999,8 @@
             }
 
             // put audio hardware into standby after short delay
-            if UNLIKELY((!activeTracks.size() && systemTime() > standbyTime) ||
-                         mSuspended) {
+            if (CC_UNLIKELY((!activeTracks.size() && systemTime() > standbyTime) ||
+                         mSuspended)) {
                 if (!mStandby) {
                     for (size_t i = 0; i < outputTracks.size(); i++) {
                         outputTracks[i]->stop();
@@ -3030,7 +3045,7 @@
             lockEffectChains_l(effectChains);
         }
 
-        if (LIKELY(mixerStatus == MIXER_TRACKS_READY)) {
+        if (CC_LIKELY(mixerStatus == MIXER_TRACKS_READY)) {
             // mix buffers...
             if (outputsReady(outputTracks)) {
                 mAudioMixer->process();
@@ -3443,7 +3458,7 @@
 
      framesReady = cblk->framesReady();
 
-     if (LIKELY(framesReady)) {
+     if (CC_LIKELY(framesReady)) {
         uint32_t s = cblk->server;
         uint32_t bufferEnd = cblk->serverBase + cblk->frameCount;
 
@@ -3692,7 +3707,7 @@
 
     framesAvail = cblk->framesAvailable_l();
 
-    if (LIKELY(framesAvail)) {
+    if (CC_LIKELY(framesAvail)) {
         uint32_t s = cblk->server;
         uint32_t bufferEnd = cblk->serverBase + cblk->frameCount;
 
@@ -3945,7 +3960,7 @@
         goto start_loop_here;
         while (framesAvail == 0) {
             active = mActive;
-            if (UNLIKELY(!active)) {
+            if (CC_UNLIKELY(!active)) {
                 ALOGV("Not active and NO_MORE_BUFFERS");
                 return AudioTrack::NO_MORE_BUFFERS;
             }
@@ -4323,7 +4338,7 @@
             }
 
             buffer.frameCount = mFrameCount;
-            if (LIKELY(mActiveTrack->getNextBuffer(&buffer) == NO_ERROR)) {
+            if (CC_LIKELY(mActiveTrack->getNextBuffer(&buffer) == NO_ERROR)) {
                 size_t framesOut = buffer.frameCount;
                 if (mResampler == NULL) {
                     // no resampling
diff --git a/services/audioflinger/AudioFlinger.h b/services/audioflinger/AudioFlinger.h
index 9707cf4..7baa8fc 100644
--- a/services/audioflinger/AudioFlinger.h
+++ b/services/audioflinger/AudioFlinger.h
@@ -55,12 +55,6 @@
 
 // ----------------------------------------------------------------------------
 
-#define LIKELY( exp )       (__builtin_expect( (exp) != 0, true  ))
-#define UNLIKELY( exp )     (__builtin_expect( (exp) != 0, false ))
-
-
-// ----------------------------------------------------------------------------
-
 static const nsecs_t kStandbyTimeInNsecs = seconds(3);
 
 class AudioFlinger :
diff --git a/services/audioflinger/AudioMixer.cpp b/services/audioflinger/AudioMixer.cpp
index dc1d1a7..c9c61a5 100644
--- a/services/audioflinger/AudioMixer.cpp
+++ b/services/audioflinger/AudioMixer.cpp
@@ -28,6 +28,7 @@
 #include <utils/Log.h>
 
 #include <cutils/bitops.h>
+#include <cutils/compiler.h>
 
 #include <system/audio.h>
 
@@ -40,7 +41,7 @@
 // ----------------------------------------------------------------------------
 
 AudioMixer::AudioMixer(size_t frameCount, uint32_t sampleRate)
-    :   mActiveTrack(0), mTrackNames(0), mSampleRate(sampleRate)
+    :   mTrackNames(0), mSampleRate(sampleRate)
 {
     // AudioMixer is not yet capable of multi-channel beyond stereo
     assert(2 == MAX_NUM_CHANNELS);
@@ -139,120 +140,120 @@
     mTrackNames &= ~(1<<name);
 }
 
-void AudioMixer::enable()
+void AudioMixer::enable(int name)
 {
-    if (mState.tracks[ mActiveTrack ].enabled != 1) {
-        mState.tracks[ mActiveTrack ].enabled = 1;
-        ALOGV("enable(%d)", mActiveTrack);
-        invalidateState(1<<mActiveTrack);
+    name -= TRACK0;
+    assert(uint32_t(name) < MAX_NUM_TRACKS);
+    track_t& track = mState.tracks[name];
+
+    if (track.enabled != 1) {
+        track.enabled = 1;
+        ALOGV("enable(%d)", name);
+        invalidateState(1 << name);
     }
 }
 
-void AudioMixer::disable()
+void AudioMixer::disable(int name)
 {
-    if (mState.tracks[ mActiveTrack ].enabled != 0) {
-        mState.tracks[ mActiveTrack ].enabled = 0;
-        ALOGV("disable(%d)", mActiveTrack);
-        invalidateState(1<<mActiveTrack);
+    name -= TRACK0;
+    assert(uint32_t(name) < MAX_NUM_TRACKS);
+    track_t& track = mState.tracks[name];
+
+    if (track.enabled != 0) {
+        track.enabled = 0;
+        ALOGV("disable(%d)", name);
+        invalidateState(1 << name);
     }
 }
 
-void AudioMixer::setActiveTrack(int track)
+void AudioMixer::setParameter(int name, int target, int param, void *value)
 {
-    // this also catches track < TRACK0
-    track -= TRACK0;
-    assert(uint32_t(track) < MAX_NUM_TRACKS);
-    mActiveTrack = track;
-}
+    name -= TRACK0;
+    assert(uint32_t(name) < MAX_NUM_TRACKS);
+    track_t& track = mState.tracks[name];
 
-void AudioMixer::setParameter(int target, int name, void *value)
-{
     int valueInt = (int)value;
     int32_t *valueBuf = (int32_t *)value;
 
     switch (target) {
 
     case TRACK:
-        switch (name) {
+        switch (param) {
         case CHANNEL_MASK: {
             uint32_t mask = (uint32_t)value;
-            if (mState.tracks[ mActiveTrack ].channelMask != mask) {
+            if (track.channelMask != mask) {
                 uint8_t channelCount = popcount(mask);
                 assert((channelCount <= MAX_NUM_CHANNELS) && (channelCount));
-                mState.tracks[ mActiveTrack ].channelMask = mask;
-                mState.tracks[ mActiveTrack ].channelCount = channelCount;
+                track.channelMask = mask;
+                track.channelCount = channelCount;
                 ALOGV("setParameter(TRACK, CHANNEL_MASK, %x)", mask);
-                invalidateState(1<<mActiveTrack);
+                invalidateState(1 << name);
             }
             } break;
         case MAIN_BUFFER:
-            if (mState.tracks[ mActiveTrack ].mainBuffer != valueBuf) {
-                mState.tracks[ mActiveTrack ].mainBuffer = valueBuf;
+            if (track.mainBuffer != valueBuf) {
+                track.mainBuffer = valueBuf;
                 ALOGV("setParameter(TRACK, MAIN_BUFFER, %p)", valueBuf);
-                invalidateState(1<<mActiveTrack);
+                invalidateState(1 << name);
             }
             break;
         case AUX_BUFFER:
-            if (mState.tracks[ mActiveTrack ].auxBuffer != valueBuf) {
-                mState.tracks[ mActiveTrack ].auxBuffer = valueBuf;
+            if (track.auxBuffer != valueBuf) {
+                track.auxBuffer = valueBuf;
                 ALOGV("setParameter(TRACK, AUX_BUFFER, %p)", valueBuf);
-                invalidateState(1<<mActiveTrack);
+                invalidateState(1 << name);
             }
             break;
         default:
-            // bad name
+            // bad param
             assert(false);
         }
         break;
 
     case RESAMPLE:
-        switch (name) {
-        case SAMPLE_RATE: {
+        switch (param) {
+        case SAMPLE_RATE:
             assert(valueInt > 0);
-            track_t& track = mState.tracks[ mActiveTrack ];
             if (track.setResampler(uint32_t(valueInt), mSampleRate)) {
                 ALOGV("setParameter(RESAMPLE, SAMPLE_RATE, %u)",
                         uint32_t(valueInt));
-                invalidateState(1<<mActiveTrack);
+                invalidateState(1 << name);
             }
-            } break;
-        case RESET: {
-            track_t& track = mState.tracks[ mActiveTrack ];
+            break;
+        case RESET:
             track.resetResampler();
-            invalidateState(1<<mActiveTrack);
-            } break;
+            invalidateState(1 << name);
+            break;
         default:
-            // bad name
+            // bad param
             assert(false);
         }
         break;
 
     case RAMP_VOLUME:
     case VOLUME:
-        switch (name) {
+        switch (param) {
         case VOLUME0:
-        case VOLUME1: {
-            track_t& track = mState.tracks[ mActiveTrack ];
-            if (track.volume[name-VOLUME0] != valueInt) {
+        case VOLUME1:
+            if (track.volume[param-VOLUME0] != valueInt) {
                 ALOGV("setParameter(VOLUME, VOLUME0/1: %04x)", valueInt);
-                track.prevVolume[name-VOLUME0] = track.volume[name-VOLUME0] << 16;
-                track.volume[name-VOLUME0] = valueInt;
+                track.prevVolume[param-VOLUME0] = track.volume[param-VOLUME0] << 16;
+                track.volume[param-VOLUME0] = valueInt;
                 if (target == VOLUME) {
-                    track.prevVolume[name-VOLUME0] = valueInt << 16;
-                    track.volumeInc[name-VOLUME0] = 0;
+                    track.prevVolume[param-VOLUME0] = valueInt << 16;
+                    track.volumeInc[param-VOLUME0] = 0;
                 } else {
-                    int32_t d = (valueInt<<16) - track.prevVolume[name-VOLUME0];
+                    int32_t d = (valueInt<<16) - track.prevVolume[param-VOLUME0];
                     int32_t volInc = d / int32_t(mState.frameCount);
-                    track.volumeInc[name-VOLUME0] = volInc;
+                    track.volumeInc[param-VOLUME0] = volInc;
                     if (volInc == 0) {
-                        track.prevVolume[name-VOLUME0] = valueInt << 16;
+                        track.prevVolume[param-VOLUME0] = valueInt << 16;
                     }
                 }
-                invalidateState(1<<mActiveTrack);
+                invalidateState(1 << name);
             }
-            } break;
-        case AUXLEVEL: {
-            track_t& track = mState.tracks[ mActiveTrack ];
+            break;
+        case AUXLEVEL:
             if (track.auxLevel != valueInt) {
                 ALOGV("setParameter(VOLUME, AUXLEVEL: %04x)", valueInt);
                 track.prevAuxLevel = track.auxLevel << 16;
@@ -268,11 +269,11 @@
                         track.prevAuxLevel = valueInt << 16;
                     }
                 }
-                invalidateState(1<<mActiveTrack);
+                invalidateState(1 << name);
             }
-            } break;
+            break;
         default:
-            // bad name
+            // bad param
             assert(false);
         }
         break;
@@ -329,10 +330,29 @@
     }
 }
 
-
-void AudioMixer::setBufferProvider(AudioBufferProvider* buffer)
+size_t AudioMixer::track_t::getUnreleasedFrames()
 {
-    mState.tracks[ mActiveTrack ].bufferProvider = buffer;
+    if (resampler != NULL) {
+        return resampler->getUnreleasedFrames();
+    }
+    return 0;
+}
+
+size_t AudioMixer::getUnreleasedFrames(int name)
+{
+    name -= TRACK0;
+    if (uint32_t(name) < MAX_NUM_TRACKS) {
+        track_t& track(mState.tracks[name]);
+        return track.getUnreleasedFrames();
+    }
+    return 0;
+}
+
+void AudioMixer::setBufferProvider(int name, AudioBufferProvider* buffer)
+{
+    name -= TRACK0;
+    assert(uint32_t(name) < MAX_NUM_TRACKS);
+    mState.tracks[name].bufferProvider = buffer;
 }
 
 
@@ -489,13 +509,13 @@
         t->resampler->setVolume(UNITY_GAIN, UNITY_GAIN);
         memset(temp, 0, outFrameCount * MAX_NUM_CHANNELS * sizeof(int32_t));
         t->resampler->resample(temp, outFrameCount, t->bufferProvider);
-        if UNLIKELY(t->volumeInc[0]|t->volumeInc[1]|t->auxInc) {
+        if (CC_UNLIKELY(t->volumeInc[0]|t->volumeInc[1]|t->auxInc)) {
             volumeRampStereo(t, out, outFrameCount, temp, aux);
         } else {
             volumeStereo(t, out, outFrameCount, temp, aux);
         }
     } else {
-        if UNLIKELY(t->volumeInc[0]|t->volumeInc[1]) {
+        if (CC_UNLIKELY(t->volumeInc[0]|t->volumeInc[1])) {
             t->resampler->setVolume(UNITY_GAIN, UNITY_GAIN);
             memset(temp, 0, outFrameCount * MAX_NUM_CHANNELS * sizeof(int32_t));
             t->resampler->resample(temp, outFrameCount, t->bufferProvider);
@@ -526,7 +546,7 @@
     //       (vl + vlInc*frameCount)/65536.0f, frameCount);
 
     // ramp volume
-    if UNLIKELY(aux != NULL) {
+    if (CC_UNLIKELY(aux != NULL)) {
         int32_t va = t->prevAuxLevel;
         const int32_t vaInc = t->auxInc;
         int32_t l;
@@ -561,7 +581,7 @@
     const int16_t vl = t->volume[0];
     const int16_t vr = t->volume[1];
 
-    if UNLIKELY(aux != NULL) {
+    if (CC_UNLIKELY(aux != NULL)) {
         const int16_t va = (int16_t)t->auxLevel;
         do {
             int16_t l = (int16_t)(*temp++ >> 12);
@@ -588,11 +608,11 @@
 {
     int16_t const *in = static_cast<int16_t const *>(t->in);
 
-    if UNLIKELY(aux != NULL) {
+    if (CC_UNLIKELY(aux != NULL)) {
         int32_t l;
         int32_t r;
         // ramp gain
-        if UNLIKELY(t->volumeInc[0]|t->volumeInc[1]|t->auxInc) {
+        if (CC_UNLIKELY(t->volumeInc[0]|t->volumeInc[1]|t->auxInc)) {
             int32_t vl = t->prevVolume[0];
             int32_t vr = t->prevVolume[1];
             int32_t va = t->prevAuxLevel;
@@ -637,7 +657,7 @@
         }
     } else {
         // ramp gain
-        if UNLIKELY(t->volumeInc[0]|t->volumeInc[1]) {
+        if (CC_UNLIKELY(t->volumeInc[0]|t->volumeInc[1])) {
             int32_t vl = t->prevVolume[0];
             int32_t vr = t->prevVolume[1];
             const int32_t vlInc = t->volumeInc[0];
@@ -678,9 +698,9 @@
 {
     int16_t const *in = static_cast<int16_t const *>(t->in);
 
-    if UNLIKELY(aux != NULL) {
+    if (CC_UNLIKELY(aux != NULL)) {
         // ramp gain
-        if UNLIKELY(t->volumeInc[0]|t->volumeInc[1]|t->auxInc) {
+        if (CC_UNLIKELY(t->volumeInc[0]|t->volumeInc[1]|t->auxInc)) {
             int32_t vl = t->prevVolume[0];
             int32_t vr = t->prevVolume[1];
             int32_t va = t->prevAuxLevel;
@@ -723,7 +743,7 @@
         }
     } else {
         // ramp gain
-        if UNLIKELY(t->volumeInc[0]|t->volumeInc[1]) {
+        if (CC_UNLIKELY(t->volumeInc[0]|t->volumeInc[1])) {
             int32_t vl = t->prevVolume[0];
             int32_t vr = t->prevVolume[1];
             const int32_t vlInc = t->volumeInc[0];
@@ -776,7 +796,7 @@
             i = 31 - __builtin_clz(e2);
             e2 &= ~(1<<i);
             track_t& t2 = state->tracks[i];
-            if UNLIKELY(t2.mainBuffer != t1.mainBuffer) {
+            if (CC_UNLIKELY(t2.mainBuffer != t1.mainBuffer)) {
                 e1 &= ~(1<<i);
             }
         }
@@ -834,7 +854,7 @@
             j = 31 - __builtin_clz(e2);
             e2 &= ~(1<<j);
             track_t& t2 = state->tracks[j];
-            if UNLIKELY(t2.mainBuffer != t1.mainBuffer) {
+            if (CC_UNLIKELY(t2.mainBuffer != t1.mainBuffer)) {
                 e1 &= ~(1<<j);
             }
         }
@@ -851,7 +871,7 @@
                 track_t& t = state->tracks[i];
                 size_t outFrames = BLOCKSIZE;
                 int32_t *aux = NULL;
-                if UNLIKELY((t.needs & NEEDS_AUX__MASK) == NEEDS_AUX_ENABLED) {
+                if (CC_UNLIKELY((t.needs & NEEDS_AUX__MASK) == NEEDS_AUX_ENABLED)) {
                     aux = t.auxBuffer + numFrames;
                 }
                 while (outFrames) {
@@ -860,7 +880,7 @@
                         (t.hook)(&t, outTemp + (BLOCKSIZE-outFrames)*MAX_NUM_CHANNELS, inFrames, state->resampleTemp, aux);
                         t.frameCount -= inFrames;
                         outFrames -= inFrames;
-                        if UNLIKELY(aux != NULL) {
+                        if (CC_UNLIKELY(aux != NULL)) {
                             aux += inFrames;
                         }
                     }
@@ -915,7 +935,7 @@
             j = 31 - __builtin_clz(e2);
             e2 &= ~(1<<j);
             track_t& t2 = state->tracks[j];
-            if UNLIKELY(t2.mainBuffer != t1.mainBuffer) {
+            if (CC_UNLIKELY(t2.mainBuffer != t1.mainBuffer)) {
                 e1 &= ~(1<<j);
             }
         }
@@ -927,7 +947,7 @@
             e1 &= ~(1<<i);
             track_t& t = state->tracks[i];
             int32_t *aux = NULL;
-            if UNLIKELY((t.needs & NEEDS_AUX__MASK) == NEEDS_AUX_ENABLED) {
+            if (CC_UNLIKELY((t.needs & NEEDS_AUX__MASK) == NEEDS_AUX_ENABLED)) {
                 aux = t.auxBuffer;
             }
 
@@ -948,7 +968,7 @@
                     // been enabled for mixing.
                     if (t.in == NULL) break;
 
-                    if UNLIKELY(aux != NULL) {
+                    if (CC_UNLIKELY(aux != NULL)) {
                         aux += outFrames;
                     }
                     (t.hook)(&t, outTemp + outFrames*MAX_NUM_CHANNELS, t.buffer.frameCount, state->resampleTemp, aux);
@@ -990,7 +1010,7 @@
         }
         size_t outFrames = b.frameCount;
 
-        if (UNLIKELY(uint32_t(vl) > UNITY_GAIN || uint32_t(vr) > UNITY_GAIN)) {
+        if (CC_UNLIKELY(uint32_t(vl) > UNITY_GAIN || uint32_t(vr) > UNITY_GAIN)) {
             // volume is boosted, so we might need to clamp even though
             // we process only one track.
             do {
diff --git a/services/audioflinger/AudioMixer.h b/services/audioflinger/AudioMixer.h
index 70464fc..4ba6845 100644
--- a/services/audioflinger/AudioMixer.h
+++ b/services/audioflinger/AudioMixer.h
@@ -28,11 +28,6 @@
 
 // ----------------------------------------------------------------------------
 
-#define LIKELY( exp )       (__builtin_expect( (exp) != 0, true  ))
-#define UNLIKELY( exp )     (__builtin_expect( (exp) != 0, false ))
-
-// ----------------------------------------------------------------------------
-
 class AudioMixer
 {
 public:
@@ -47,7 +42,7 @@
 
     enum { // names
 
-        // track units (MAX_NUM_TRACKS units)
+        // track names (MAX_NUM_TRACKS units)
         TRACK0          = 0x1000,
 
         // 0x2000 is unused
@@ -74,20 +69,22 @@
     };
 
 
+    // For all APIs with "name": TRACK0 <= name < TRACK0 + MAX_NUM_TRACKS
     int         getTrackName();
     void        deleteTrackName(int name);
 
-    void        enable();
-    void        disable();
+    void        enable(int name);
+    void        disable(int name);
 
-    void        setActiveTrack(int track);
-    void        setParameter(int target, int name, void *value);
+    void        setParameter(int name, int target, int param, void *value);
 
-    void        setBufferProvider(AudioBufferProvider* bufferProvider);
+    void        setBufferProvider(int name, AudioBufferProvider* bufferProvider);
     void        process();
 
     uint32_t    trackNames() const { return mTrackNames; }
 
+    size_t      getUnreleasedFrames(int name);
+
 private:
 
     enum {
@@ -159,6 +156,7 @@
         bool        doesResample() const;
         void        resetResampler();
         void        adjustVolumeRamp(bool aux);
+        size_t      getUnreleasedFrames();
     };
 
     // pad to 32-bytes to fill cache line
@@ -173,7 +171,7 @@
         track_t         tracks[MAX_NUM_TRACKS]; __attribute__((aligned(32)));
     };
 
-    int             mActiveTrack;
+    // bitmask of allocated track names, where bit 0 corresponds to TRACK0 etc.
     uint32_t        mTrackNames;
     const uint32_t  mSampleRate;
 
diff --git a/services/audioflinger/AudioResampler.h b/services/audioflinger/AudioResampler.h
index 9f06c1c..ffa690a 100644
--- a/services/audioflinger/AudioResampler.h
+++ b/services/audioflinger/AudioResampler.h
@@ -54,6 +54,7 @@
             AudioBufferProvider* provider) = 0;
 
     virtual void reset();
+    virtual size_t getUnreleasedFrames() { return mInputIndex; }
 
 protected:
     // number of bits for phase fraction - 30 bits allows nearly 2x downsampling