Remove the notion of "active track" from mixer

This is a first step towards making the mixer more object-oriented.

Change-Id: Ifd445d0e471023a7f5c82e934736ffc95ba1b05b
diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp
index 2090f1b..c6be9be 100644
--- a/services/audioflinger/AudioFlinger.cpp
+++ b/services/audioflinger/AudioFlinger.cpp
@@ -2101,12 +2101,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:
@@ -2124,7 +2125,7 @@
         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 +2138,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 +2152,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 +2204,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 +2236,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 +2248,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,7 +2256,7 @@
                     mixerStatus = MIXER_TRACKS_ENABLED;
                 }
             }
-            mAudioMixer->disable();
+            mAudioMixer->disable(name);
         }
     }
 
diff --git a/services/audioflinger/AudioMixer.cpp b/services/audioflinger/AudioMixer.cpp
index f5fdee7..3b2771b 100644
--- a/services/audioflinger/AudioMixer.cpp
+++ b/services/audioflinger/AudioMixer.cpp
@@ -40,7 +40,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 +139,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 +268,11 @@
                         track.prevAuxLevel = valueInt << 16;
                     }
                 }
-                invalidateState(1<<mActiveTrack);
+                invalidateState(1 << name);
             }
-            } break;
+            break;
         default:
-            // bad name
+            // bad param
             assert(false);
         }
         break;
@@ -330,9 +330,11 @@
 }
 
 
-void AudioMixer::setBufferProvider(AudioBufferProvider* buffer)
+void AudioMixer::setBufferProvider(int name, AudioBufferProvider* buffer)
 {
-    mState.tracks[ mActiveTrack ].bufferProvider = buffer;
+    name -= TRACK0;
+    assert(uint32_t(name) < MAX_NUM_TRACKS);
+    mState.tracks[name].bufferProvider = buffer;
 }
 
 
diff --git a/services/audioflinger/AudioMixer.h b/services/audioflinger/AudioMixer.h
index 39af103..45365be 100644
--- a/services/audioflinger/AudioMixer.h
+++ b/services/audioflinger/AudioMixer.h
@@ -47,7 +47,7 @@
 
     enum { // names
 
-        // track units (MAX_NUM_TRACKS units)
+        // track names (MAX_NUM_TRACKS units)
         TRACK0          = 0x1000,
 
         // 0x2000 is unused
@@ -74,16 +74,16 @@
     };
 
 
+    // 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; }
@@ -178,7 +178,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;