Merge "Remove the notion of "active track" from mixer"
This commit is contained in:
@@ -2102,12 +2102,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:
|
||||
@@ -2133,7 +2134,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++;
|
||||
|
||||
@@ -2146,8 +2147,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());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2160,7 +2161,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
|
||||
@@ -2212,26 +2213,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());
|
||||
|
||||
@@ -2239,7 +2245,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();
|
||||
}
|
||||
@@ -2251,7 +2257,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);
|
||||
@@ -2259,7 +2265,7 @@ uint32_t AudioFlinger::MixerThread::prepareTracks_l(const SortedVector< wp<Track
|
||||
mixerStatus = MIXER_TRACKS_ENABLED;
|
||||
}
|
||||
}
|
||||
mAudioMixer->disable();
|
||||
mAudioMixer->disable(name);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -41,7 +41,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);
|
||||
@@ -140,120 +140,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;
|
||||
@@ -269,11 +269,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;
|
||||
@@ -348,9 +348,11 @@ size_t AudioMixer::getUnreleasedFrames(int name)
|
||||
return 0;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -42,7 +42,7 @@ public:
|
||||
|
||||
enum { // names
|
||||
|
||||
// track units (MAX_NUM_TRACKS units)
|
||||
// track names (MAX_NUM_TRACKS units)
|
||||
TRACK0 = 0x1000,
|
||||
|
||||
// 0x2000 is unused
|
||||
@@ -69,16 +69,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; }
|
||||
@@ -171,7 +171,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;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user