AudioFlinger normal mixer uses FastMixer
Change-Id: I3131bb22d2d057e9197a2ebfa6aa1cfaab9e5321
diff --git a/services/audioflinger/AudioFlinger.h b/services/audioflinger/AudioFlinger.h
index 6b18945..23fc74d 100644
--- a/services/audioflinger/AudioFlinger.h
+++ b/services/audioflinger/AudioFlinger.h
@@ -46,6 +46,8 @@
#include <hardware/audio_policy.h>
#include "AudioBufferProvider.h"
+#include "FastMixer.h"
+#include "NBAIO.h"
#include <powermanager/IPowerManager.h>
@@ -56,6 +58,7 @@
class AudioMixer;
class AudioBuffer;
class AudioResampler;
+class FastMixer;
// ----------------------------------------------------------------------------
@@ -425,6 +428,8 @@
uint32_t mFrameCount;
// we don't really need a lock for these
track_state mState;
+ const uint32_t mSampleRate; // initial sample rate only; for tracks which
+ // support dynamic rates, the current value is in control block
const audio_format_t mFormat;
bool mStepServerFailed;
const int mSessionId;
@@ -461,7 +466,9 @@
uint32_t sampleRate() const { return mSampleRate; }
int channelCount() const { return mChannelCount; }
audio_format_t format() const { return mFormat; }
- size_t frameCount() const { return mFrameCount; }
+ // Called by AudioFlinger::frameCount(audio_io_handle_t output) and effects,
+ // and returns the normal mix buffer's frame count. No API for HAL frame count.
+ size_t frameCount() const { return mNormalFrameCount; }
void wakeUp() { mWaitWorkCV.broadcast(); }
// Should be "virtual status_t requestExitAndWait()" and override same
// method in Thread, but Thread::requestExitAndWait() is not yet virtual.
@@ -586,7 +593,8 @@
const sp<AudioFlinger> mAudioFlinger;
uint32_t mSampleRate;
- size_t mFrameCount;
+ size_t mFrameCount; // output HAL, direct output, record
+ size_t mNormalFrameCount; // normal mixer and effects
uint32_t mChannelMask;
uint16_t mChannelCount;
size_t mFrameSize;
@@ -654,7 +662,7 @@
};
// playback track
- class Track : public TrackBase {
+ class Track : public TrackBase, public VolumeProvider {
public:
Track( PlaybackThread *thread,
const sp<Client>& client,
@@ -691,8 +699,13 @@
int16_t *mainBuffer() const { return mMainBuffer; }
int auxEffectId() const { return mAuxEffectId; }
+#if 0
bool isFastTrack() const
{ return (mFlags & IAudioFlinger::TRACK_FAST) != 0; }
+#endif
+
+ // implement FastMixerState::VolumeProvider interface
+ virtual uint32_t getVolumeLR();
protected:
// for numerous
@@ -729,18 +742,19 @@
public:
virtual bool isTimedTrack() const { return false; }
+ bool isFastTrack() const { return (mFlags & IAudioFlinger::TRACK_FAST) != 0; }
protected:
// we don't really need a lock for these
volatile bool mMute;
// FILLED state is used for suppressing volume ramp at begin of playing
- enum {FS_FILLING, FS_FILLED, FS_ACTIVE};
+ enum {FS_INVALID, FS_FILLING, FS_FILLED, FS_ACTIVE};
mutable uint8_t mFillingUpStatus;
int8_t mRetryCount;
const sp<IMemory> mSharedBuffer;
bool mResetDone;
const audio_stream_type_t mStreamType;
- int mName;
+ int mName; // track name on the normal mixer
int16_t *mMainBuffer;
int32_t *mAuxBuffer;
int mAuxEffectId;
@@ -749,6 +763,10 @@
// when this track will be fully rendered
private:
IAudioFlinger::track_flags_t mFlags;
+ int mFastIndex; // index within FastMixerState::mFastTracks[] or -1
+ volatile float mCachedVolume; // combined master volume and stream type volume;
+ // 'volatile' means accessed without lock or
+ // barrier, but is read/written atomically
}; // end of Track
class TimedTrack : public Track {
@@ -899,6 +917,7 @@
virtual void threadLoop_sleepTime() = 0;
virtual void threadLoop_write();
virtual void threadLoop_standby();
+ virtual void threadLoop_removeTracks(const Vector< sp<Track> >& tracksToRemove) { }
// prepareTracks_l reads and writes mActiveTracks, and also returns the
// pending set of tracks to remove via Vector 'tracksToRemove'. The caller is
@@ -1049,6 +1068,23 @@
// DUPLICATING only
uint32_t writeFrames;
+
+ private:
+ // The HAL output sink is treated as non-blocking, but current implementation is blocking
+ sp<NBAIO_Sink> mOutputSink;
+ // If a fast mixer is present, the blocking pipe sink, otherwise clear
+ sp<NBAIO_Sink> mPipeSink;
+ // The current sink for the normal mixer to write it's (sub)mix, mOutputSink or mPipeSink
+ sp<NBAIO_Sink> mNormalSink;
+ public:
+ virtual bool hasFastMixer() const = 0;
+
+ protected:
+ // accessed by both binder threads and within threadLoop(), lock on mutex needed
+ unsigned mFastTrackAvailMask; // bit i set if fast track [i] is available
+ unsigned mFastTrackNewMask; // bit i set if fast track [i] just created
+ Track* mFastTrackNewArray[FastMixerState::kMaxFastTracks];
+
};
class MixerThread : public PlaybackThread {
@@ -1075,10 +1111,29 @@
virtual void cacheParameters_l();
// threadLoop snippets
+ virtual void threadLoop_write();
+ virtual void threadLoop_standby();
virtual void threadLoop_mix();
virtual void threadLoop_sleepTime();
+ virtual void threadLoop_removeTracks(const Vector< sp<Track> >& tracksToRemove);
- AudioMixer* mAudioMixer;
+ AudioMixer* mAudioMixer; // normal mixer
+ private:
+#ifdef SOAKER
+ Thread* mSoaker;
+#endif
+ // one-time initialization, no locks required
+ FastMixer* mFastMixer; // non-NULL if there is also a fast mixer
+
+ // contents are not guaranteed to be consistent, no locks required
+ FastMixerDumpState mFastMixerDumpState;
+
+ // accessible only within the threadLoop(), no locks required
+ // mFastMixer->sq() // for mutating and pushing state
+ int32_t mFastMixerFutex; // for cold idle
+
+ public:
+ virtual bool hasFastMixer() const { return mFastMixer != NULL; }
};
class DirectOutputThread : public PlaybackThread {
@@ -1121,6 +1176,8 @@
private:
// prepareTracks_l() tells threadLoop_mix() the name of the single active track
sp<Track> mActiveTrack;
+ public:
+ virtual bool hasFastMixer() const { return false; }
};
class DuplicatingThread : public MixerThread {
@@ -1157,6 +1214,8 @@
uint32_t mWaitTimeMs;
SortedVector < sp<OutputTrack> > outputTracks;
SortedVector < sp<OutputTrack> > mOutputTracks;
+ public:
+ virtual bool hasFastMixer() const { return false; }
};
PlaybackThread *checkPlaybackThread_l(audio_io_handle_t output) const;