From 21e8c50bd13ebe44f3088e26c9c6df0e163c469c Mon Sep 17 00:00:00 2001 From: Glenn Kasten Date: Thu, 12 Apr 2012 09:39:42 -0700 Subject: FastMixer update Updates: - Add support for mono fast tracks - Add support for optional sample rate conversion on fast tracks - Log sample rate and frame count - Enable statistics Change-Id: Ife014edf4f452da361f3eaaae19209ef6ff6958b --- services/audioflinger/Android.mk | 2 +- services/audioflinger/FastMixer.cpp | 28 +++++++++++++++++++++++++--- services/audioflinger/FastMixer.h | 2 ++ services/audioflinger/FastMixerState.cpp | 3 ++- services/audioflinger/FastMixerState.h | 3 +++ 5 files changed, 33 insertions(+), 5 deletions(-) diff --git a/services/audioflinger/Android.mk b/services/audioflinger/Android.mk index d52ed42..4667649 100644 --- a/services/audioflinger/Android.mk +++ b/services/audioflinger/Android.mk @@ -64,7 +64,7 @@ LOCAL_MODULE:= libaudioflinger LOCAL_SRC_FILES += FastMixer.cpp FastMixerState.cpp -#LOCAL_CFLAGS += -DFAST_MIXER_STATISTICS +LOCAL_CFLAGS += -DFAST_MIXER_STATISTICS LOCAL_CFLAGS += -DSTATE_QUEUE_INSTANTIATIONS='"StateQueueInstantiations.cpp"' diff --git a/services/audioflinger/FastMixer.cpp b/services/audioflinger/FastMixer.cpp index 14954f7..841b06a 100644 --- a/services/audioflinger/FastMixer.cpp +++ b/services/audioflinger/FastMixer.cpp @@ -130,6 +130,7 @@ bool FastMixer::threadLoop() continue; case FastMixerState::COLD_IDLE: // only perform a cold idle command once + // FIXME consider checking previous state and only perform if previous != COLD_IDLE if (current->mColdGen != coldGen) { int32_t *coldFutexAddr = current->mColdFutexAddr; ALOG_ASSERT(coldFutexAddr != NULL); @@ -176,6 +177,7 @@ bool FastMixer::threadLoop() sampleRate = Format_sampleRate(format); ALOG_ASSERT(Format_channelCount(format) == 2); } + dumpState->mSampleRate = sampleRate; } if ((format != previousFormat) || (frameCount != previous->mFrameCount)) { @@ -207,6 +209,7 @@ bool FastMixer::threadLoop() // we need to reconfigure all active tracks previousTrackMask = 0; fastTracksGen = current->mFastTracksGen - 1; + dumpState->mFrameCount = frameCount; } else { previousTrackMask = previous->mTrackMask; } @@ -251,6 +254,12 @@ bool FastMixer::threadLoop() mixer->setParameter(name, AudioMixer::TRACK, AudioMixer::MAIN_BUFFER, (void *) mixBuffer); // newly allocated track names default to full scale volume + if (fastTrack->mSampleRate != 0 && fastTrack->mSampleRate != sampleRate) { + mixer->setParameter(name, AudioMixer::RESAMPLE, + AudioMixer::SAMPLE_RATE, (void*) fastTrack->mSampleRate); + } + mixer->setParameter(name, AudioMixer::TRACK, AudioMixer::CHANNEL_MASK, + (void *) fastTrack->mChannelMask); mixer->enable(name); } generations[i] = fastTrack->mGeneration; @@ -276,6 +285,16 @@ bool FastMixer::threadLoop() mixer->setParameter(name, AudioMixer::VOLUME, AudioMixer::VOLUME1, (void *)0x1000); } + if (fastTrack->mSampleRate != 0 && + fastTrack->mSampleRate != sampleRate) { + mixer->setParameter(name, AudioMixer::RESAMPLE, + AudioMixer::SAMPLE_RATE, (void*) fastTrack->mSampleRate); + } else { + mixer->setParameter(name, AudioMixer::RESAMPLE, + AudioMixer::REMOVE, NULL); + } + mixer->setParameter(name, AudioMixer::TRACK, AudioMixer::CHANNEL_MASK, + (void *) fastTrack->mChannelMask); // already enabled } generations[i] = fastTrack->mGeneration; @@ -401,7 +420,8 @@ bool FastMixer::threadLoop() FastMixerDumpState::FastMixerDumpState() : mCommand(FastMixerState::INITIAL), mWriteSequence(0), mFramesWritten(0), - mNumTracks(0), mWriteErrors(0), mUnderruns(0), mOverruns(0) + mNumTracks(0), mWriteErrors(0), mUnderruns(0), mOverruns(0), + mSampleRate(0), mFrameCount(0) #ifdef FAST_MIXER_STATISTICS , mMean(0.0), mMinimum(0.0), mMaximum(0.0), mStddev(0.0) #endif @@ -443,9 +463,11 @@ void FastMixerDumpState::dump(int fd) break; } fdprintf(fd, "FastMixer command=%s writeSequence=%u framesWritten=%u\n" - " numTracks=%u writeErrors=%u underruns=%u overruns=%u\n", + " numTracks=%u writeErrors=%u underruns=%u overruns=%u\n" + " sampleRate=%u frameCount=%u\n", string, mWriteSequence, mFramesWritten, - mNumTracks, mWriteErrors, mUnderruns, mOverruns); + mNumTracks, mWriteErrors, mUnderruns, mOverruns, + mSampleRate, mFrameCount); #ifdef FAST_MIXER_STATISTICS fdprintf(fd, " cycle time in ms: mean=%.1f min=%.1f max=%.1f stddev=%.1f\n", mMean*1e3, mMinimum*1e3, mMaximum*1e3, mStddev*1e3); diff --git a/services/audioflinger/FastMixer.h b/services/audioflinger/FastMixer.h index b24f2eb..8a8fcb8 100644 --- a/services/audioflinger/FastMixer.h +++ b/services/audioflinger/FastMixer.h @@ -58,6 +58,8 @@ struct FastMixerDumpState { uint32_t mWriteErrors; // total number of write() errors uint32_t mUnderruns; // total number of underruns uint32_t mOverruns; // total number of overruns + uint32_t mSampleRate; + size_t mFrameCount; #ifdef FAST_MIXER_STATISTICS // cycle times in seconds float mMean; diff --git a/services/audioflinger/FastMixerState.cpp b/services/audioflinger/FastMixerState.cpp index 4eacacf..139a1c8 100644 --- a/services/audioflinger/FastMixerState.cpp +++ b/services/audioflinger/FastMixerState.cpp @@ -19,7 +19,8 @@ namespace android { FastTrack::FastTrack() : - mBufferProvider(NULL), mVolumeProvider(NULL), mGeneration(0) + mBufferProvider(NULL), mVolumeProvider(NULL), mSampleRate(0), + mChannelMask(AUDIO_CHANNEL_OUT_STEREO), mGeneration(0) { } diff --git a/services/audioflinger/FastMixerState.h b/services/audioflinger/FastMixerState.h index 64171ac..83094c8 100644 --- a/services/audioflinger/FastMixerState.h +++ b/services/audioflinger/FastMixerState.h @@ -17,6 +17,7 @@ #ifndef ANDROID_AUDIO_FAST_MIXER_STATE_H #define ANDROID_AUDIO_FAST_MIXER_STATE_H +#include #include "AudioBufferProvider.h" #include "NBAIO.h" @@ -41,6 +42,8 @@ struct FastTrack { AudioBufferProvider* mBufferProvider; // must not be NULL VolumeProvider* mVolumeProvider; // optional; if NULL then full-scale + unsigned mSampleRate; // optional; if zero then use mixer sample rate + audio_channel_mask_t mChannelMask; // AUDIO_CHANNEL_OUT_MONO or AUDIO_CHANNEL_OUT_STEREO int mGeneration; // increment when any field is assigned }; -- cgit v1.1