summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--services/audioflinger/AudioFlinger.cpp8
-rw-r--r--services/audioflinger/AudioMixer.cpp71
-rw-r--r--services/audioflinger/AudioMixer.h4
-rw-r--r--services/audioflinger/FastMixer.cpp3
4 files changed, 57 insertions, 29 deletions
diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp
index c674c24..99dcf45 100644
--- a/services/audioflinger/AudioFlinger.cpp
+++ b/services/audioflinger/AudioFlinger.cpp
@@ -2664,13 +2664,7 @@ void AudioFlinger::MixerThread::invalidateTracks(audio_stream_type_t streamType)
// getTrackName_l() must be called with ThreadBase::mLock held
int AudioFlinger::MixerThread::getTrackName_l(audio_channel_mask_t channelMask)
{
- int name = mAudioMixer->getTrackName();
- if (name >= 0) {
- mAudioMixer->setParameter(name,
- AudioMixer::TRACK,
- AudioMixer::CHANNEL_MASK, (void *)channelMask);
- }
- return name;
+ return mAudioMixer->getTrackName(channelMask);
}
// deleteTrackName_l() must be called with ThreadBase::mLock held
diff --git a/services/audioflinger/AudioMixer.cpp b/services/audioflinger/AudioMixer.cpp
index 4c9e04a..0c8b3ce 100644
--- a/services/audioflinger/AudioMixer.cpp
+++ b/services/audioflinger/AudioMixer.cpp
@@ -69,7 +69,7 @@ status_t AudioMixer::DownmixerBufferProvider::getNextBuffer(AudioBufferProvider:
res = (*mDownmixHandle)->process(mDownmixHandle,
&mDownmixConfig.inputCfg.buffer, &mDownmixConfig.outputCfg.buffer);
- ALOGV("getNextBuffer is downmixing");
+ //ALOGV("getNextBuffer is downmixing");
}
return res;
} else {
@@ -79,7 +79,7 @@ status_t AudioMixer::DownmixerBufferProvider::getNextBuffer(AudioBufferProvider:
}
void AudioMixer::DownmixerBufferProvider::releaseBuffer(AudioBufferProvider::Buffer *pBuffer) {
- ALOGV("DownmixerBufferProvider::releaseBuffer()");
+ //ALOGV("DownmixerBufferProvider::releaseBuffer()");
if (this->mTrackBufferProvider != NULL) {
mTrackBufferProvider->releaseBuffer(pBuffer);
} else {
@@ -120,6 +120,7 @@ AudioMixer::AudioMixer(size_t frameCount, uint32_t sampleRate, uint32_t maxNumTr
// FIXME redundant per track
t->localTimeFreq = lc.getLocalFreq();
t->resampler = NULL;
+ t->downmixerBufferProvider = NULL;
t++;
}
@@ -151,13 +152,14 @@ AudioMixer::~AudioMixer()
track_t* t = mState.tracks;
for (unsigned i=0 ; i < MAX_NUM_TRACKS ; i++) {
delete t->resampler;
+ delete t->downmixerBufferProvider;
t++;
}
delete [] mState.outputTemp;
delete [] mState.resampleTemp;
}
-int AudioMixer::getTrackName()
+int AudioMixer::getTrackName(audio_channel_mask_t channelMask)
{
uint32_t names = (~mTrackNames) & mConfiguredNames;
if (names != 0) {
@@ -197,7 +199,13 @@ int AudioMixer::getTrackName()
t->mainBuffer = NULL;
t->auxBuffer = NULL;
// see t->localTimeFreq in constructor above
- return TRACK0 + n;
+
+ status_t status = initTrackDownmix(&mState.tracks[n], n, channelMask);
+ if (status == OK) {
+ return TRACK0 + n;
+ }
+ ALOGE("AudioMixer::getTrackName(0x%x) failed, error preparing track for downmix",
+ channelMask);
}
return -1;
}
@@ -210,16 +218,43 @@ void AudioMixer::invalidateState(uint32_t mask)
}
}
-status_t AudioMixer::prepareTrackForDownmix(track_t* pTrack, int trackName)
+status_t AudioMixer::initTrackDownmix(track_t* pTrack, int trackNum, audio_channel_mask_t mask)
{
- ALOGV("AudioMixer::prepareTrackForDownmix(%d) with mask 0x%x", trackName, pTrack->channelMask);
+ uint32_t channelCount = popcount(mask);
+ ALOG_ASSERT((channelCount <= MAX_NUM_CHANNELS_TO_DOWNMIX) && channelCount);
+ status_t status = OK;
+ if (channelCount > MAX_NUM_CHANNELS) {
+ pTrack->channelMask = mask;
+ pTrack->channelCount = channelCount;
+ ALOGV("initTrackDownmix(track=%d, mask=0x%x) calls prepareTrackForDownmix()",
+ trackNum, mask);
+ status = prepareTrackForDownmix(pTrack, trackNum);
+ } else {
+ unprepareTrackForDownmix(pTrack, trackNum);
+ }
+ return status;
+}
+
+void AudioMixer::unprepareTrackForDownmix(track_t* pTrack, int trackName) {
+ ALOGV("AudioMixer::unprepareTrackForDownmix(%d)", trackName);
if (pTrack->downmixerBufferProvider != NULL) {
- // this track had previously been configured with a downmixer, reset it
- ALOGV("AudioMixer::prepareTrackForDownmix(%d) deleting old downmixer", trackName);
+ // this track had previously been configured with a downmixer, delete it
+ ALOGV(" deleting old downmixer");
pTrack->bufferProvider = pTrack->downmixerBufferProvider->mTrackBufferProvider;
delete pTrack->downmixerBufferProvider;
+ pTrack->downmixerBufferProvider = NULL;
+ } else {
+ ALOGV(" nothing to do, no downmixer to delete");
}
+}
+
+status_t AudioMixer::prepareTrackForDownmix(track_t* pTrack, int trackName)
+{
+ ALOGV("AudioMixer::prepareTrackForDownmix(%d) with mask 0x%x", trackName, pTrack->channelMask);
+
+ // discard the previous downmixer if there was one
+ unprepareTrackForDownmix(pTrack, trackName);
DownmixerBufferProvider* pDbp = new DownmixerBufferProvider();
int32_t status;
@@ -319,6 +354,7 @@ noDownmixForActiveTrack:
void AudioMixer::deleteTrackName(int name)
{
+ ALOGV("AudioMixer::deleteTrackName(%d)", name);
name -= TRACK0;
ALOG_ASSERT(uint32_t(name) < MAX_NUM_TRACKS, "bad track name %d", name);
ALOGV("deleteTrackName(%d)", name);
@@ -330,6 +366,9 @@ void AudioMixer::deleteTrackName(int name)
// delete the resampler
delete track.resampler;
track.resampler = NULL;
+ // delete the downmixer
+ unprepareTrackForDownmix(&mState.tracks[name], name);
+
mTrackNames &= ~(1<<name);
}
@@ -353,11 +392,6 @@ void AudioMixer::disable(int name)
track_t& track = mState.tracks[name];
if (track.enabled) {
- if (track.downmixerBufferProvider != NULL) {
- ALOGV("AudioMixer::disable(%d) deleting downmixerBufferProvider", name);
- delete track.downmixerBufferProvider;
- track.downmixerBufferProvider = NULL;
- }
track.enabled = false;
ALOGV("disable(%d)", name);
invalidateState(1 << name);
@@ -384,11 +418,8 @@ void AudioMixer::setParameter(int name, int target, int param, void *value)
ALOG_ASSERT((channelCount <= MAX_NUM_CHANNELS_TO_DOWNMIX) && channelCount);
track.channelMask = mask;
track.channelCount = channelCount;
- if (channelCount > MAX_NUM_CHANNELS) {
- ALOGV("AudioMixer::setParameter(TRACK, CHANNEL_MASK, mask=0x%x count=%d)",
- mask, channelCount);
- status_t status = prepareTrackForDownmix(&mState.tracks[name], name);
- }
+ // the mask has changed, does this track need a downmixer?
+ initTrackDownmix(&mState.tracks[name], name, mask);
ALOGV("setParameter(TRACK, CHANNEL_MASK, %x)", mask);
invalidateState(1 << name);
}
@@ -633,7 +664,7 @@ void AudioMixer::process__validate(state_t* state, int64_t pts)
resampling = true;
t.hook = track__genericResample;
ALOGV_IF((n & NEEDS_CHANNEL_COUNT__MASK) > NEEDS_CHANNEL_2,
- "Track needs downmix + resample");
+ "Track %d needs downmix + resample", i);
} else {
if ((n & NEEDS_CHANNEL_COUNT__MASK) == NEEDS_CHANNEL_1){
t.hook = track__16BitsMono;
@@ -642,7 +673,7 @@ void AudioMixer::process__validate(state_t* state, int64_t pts)
if ((n & NEEDS_CHANNEL_COUNT__MASK) >= NEEDS_CHANNEL_2){
t.hook = track__16BitsStereo;
ALOGV_IF((n & NEEDS_CHANNEL_COUNT__MASK) > NEEDS_CHANNEL_2,
- "Track needs downmix");
+ "Track %d needs downmix", i);
}
}
}
diff --git a/services/audioflinger/AudioMixer.h b/services/audioflinger/AudioMixer.h
index 9698d0c..46deae7 100644
--- a/services/audioflinger/AudioMixer.h
+++ b/services/audioflinger/AudioMixer.h
@@ -91,7 +91,7 @@ public:
// For all APIs with "name": TRACK0 <= name < TRACK0 + MAX_NUM_TRACKS
// Allocate a track name. Returns new track name if successful, -1 on failure.
- int getTrackName();
+ int getTrackName(audio_channel_mask_t channelMask);
// Free an allocated track by name
void deleteTrackName(int name);
@@ -250,7 +250,9 @@ private:
// OK to call more often than that, but unnecessary.
void invalidateState(uint32_t mask);
+ static status_t initTrackDownmix(track_t* pTrack, int trackNum, audio_channel_mask_t mask);
static status_t prepareTrackForDownmix(track_t* pTrack, int trackNum);
+ static void unprepareTrackForDownmix(track_t* pTrack, int trackName);
static void track__genericResample(track_t* t, int32_t* out, size_t numFrames, int32_t* temp, int32_t* aux);
static void track__nop(track_t* t, int32_t* out, size_t numFrames, int32_t* temp, int32_t* aux);
diff --git a/services/audioflinger/FastMixer.cpp b/services/audioflinger/FastMixer.cpp
index 1543152..14954f7 100644
--- a/services/audioflinger/FastMixer.cpp
+++ b/services/audioflinger/FastMixer.cpp
@@ -243,7 +243,8 @@ bool FastMixer::threadLoop()
AudioBufferProvider *bufferProvider = fastTrack->mBufferProvider;
ALOG_ASSERT(bufferProvider != NULL && fastTrackNames[i] == -1);
if (mixer != NULL) {
- name = mixer->getTrackName();
+ // calling getTrackName with default channel mask
+ name = mixer->getTrackName(AUDIO_CHANNEL_OUT_STEREO);
ALOG_ASSERT(name >= 0);
fastTrackNames[i] = name;
mixer->setBufferProvider(name, bufferProvider);