summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGlenn Kasten <gkasten@google.com>2011-12-19 15:06:39 -0800
committerGlenn Kasten <gkasten@google.com>2011-12-20 16:29:21 -0800
commit9c56d4ae6212c21ce5fd71ed534eb195983a07c1 (patch)
tree417c958c4fd243f4edb7bc765f4dc1e709456ddc
parentbbaf8673f1d1dd79d1b7f474ca7111da58e84aff (diff)
downloadframeworks_av-9c56d4ae6212c21ce5fd71ed534eb195983a07c1.zip
frameworks_av-9c56d4ae6212c21ce5fd71ed534eb195983a07c1.tar.gz
frameworks_av-9c56d4ae6212c21ce5fd71ed534eb195983a07c1.tar.bz2
Remove the notion of "active track" from mixer
This is a first step towards making the mixer more object-oriented. Change-Id: Ifd445d0e471023a7f5c82e934736ffc95ba1b05b
-rw-r--r--services/audioflinger/AudioFlinger.cpp32
-rw-r--r--services/audioflinger/AudioMixer.cpp124
-rw-r--r--services/audioflinger/AudioMixer.h14
3 files changed, 89 insertions, 81 deletions
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 @@ uint32_t AudioFlinger::MixerThread::prepareTracks_l(const SortedVector< wp<Track
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 @@ uint32_t AudioFlinger::MixerThread::prepareTracks_l(const SortedVector< wp<Track
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 @@ uint32_t AudioFlinger::MixerThread::prepareTracks_l(const SortedVector< wp<Track
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 @@ uint32_t AudioFlinger::MixerThread::prepareTracks_l(const SortedVector< wp<Track
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 @@ uint32_t AudioFlinger::MixerThread::prepareTracks_l(const SortedVector< wp<Track
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 @@ uint32_t AudioFlinger::MixerThread::prepareTracks_l(const SortedVector< wp<Track
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 @@ uint32_t AudioFlinger::MixerThread::prepareTracks_l(const SortedVector< wp<Track
// 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 @@ uint32_t AudioFlinger::MixerThread::prepareTracks_l(const SortedVector< wp<Track
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 @@ namespace android {
// ----------------------------------------------------------------------------
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 @@ void AudioMixer::deleteTrackName(int name)
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 @@ void AudioMixer::setParameter(int target, int name, void *value)
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::track_t::adjustVolumeRamp(bool aux)
}
-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 @@ public:
enum { // names
- // track units (MAX_NUM_TRACKS units)
+ // track names (MAX_NUM_TRACKS units)
TRACK0 = 0x1000,
// 0x2000 is unused
@@ -74,16 +74,16 @@ public:
};
+ // 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 @@ private:
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;