summaryrefslogtreecommitdiffstats
path: root/services/audioflinger/AudioFlinger.h
diff options
context:
space:
mode:
Diffstat (limited to 'services/audioflinger/AudioFlinger.h')
-rw-r--r--services/audioflinger/AudioFlinger.h1592
1 files changed, 37 insertions, 1555 deletions
diff --git a/services/audioflinger/AudioFlinger.h b/services/audioflinger/AudioFlinger.h
index 2541b15..46a8e0f 100644
--- a/services/audioflinger/AudioFlinger.h
+++ b/services/audioflinger/AudioFlinger.h
@@ -75,6 +75,11 @@ class FastMixer;
static const nsecs_t kDefaultStandbyTimeInNsecs = seconds(3);
+#define MAX_GAIN 4096.0f
+#define MAX_GAIN_INT 0x1000
+
+#define INCLUDING_FROM_AUDIOFLINGER_H
+
class AudioFlinger :
public BinderService<AudioFlinger>,
public BnAudioFlinger
@@ -283,7 +288,14 @@ private:
// ro.audio.flinger_standbytime_ms or defaults to kDefaultStandbyTimeInNsecs
static nsecs_t mStandbyTimeInNsecs;
+ // incremented by 2 when screen state changes, bit 0 == 1 means "off"
+ // AudioFlinger::setParameters() updates, other threads read w/o lock
+ static uint32_t mScreenState;
+
// Internal dump utilities.
+ static const int kDumpLockRetries = 50;
+ static const int kDumpLockSleepUs = 20000;
+ static bool dumpTryLock(Mutex& mutex);
void dumpPermissionDenial(int fd, const Vector<String16>& args);
void dumpClients(int fd, const Vector<String16>& args);
void dumpInternals(int fd, const Vector<String16>& args);
@@ -348,419 +360,6 @@ private:
struct AudioStreamOut;
struct AudioStreamIn;
- class ThreadBase : public Thread {
- public:
-
- enum type_t {
- MIXER, // Thread class is MixerThread
- DIRECT, // Thread class is DirectOutputThread
- DUPLICATING, // Thread class is DuplicatingThread
- RECORD // Thread class is RecordThread
- };
-
- ThreadBase(const sp<AudioFlinger>& audioFlinger, audio_io_handle_t id,
- audio_devices_t outDevice, audio_devices_t inDevice, type_t type);
- virtual ~ThreadBase();
-
- void dumpBase(int fd, const Vector<String16>& args);
- void dumpEffectChains(int fd, const Vector<String16>& args);
-
- void clearPowerManager();
-
- // base for record and playback
- class TrackBase : public ExtendedAudioBufferProvider, public RefBase {
-
- public:
- enum track_state {
- IDLE,
- TERMINATED,
- FLUSHED,
- STOPPED,
- // next 2 states are currently used for fast tracks only
- STOPPING_1, // waiting for first underrun
- STOPPING_2, // waiting for presentation complete
- RESUMING,
- ACTIVE,
- PAUSING,
- PAUSED
- };
-
- TrackBase(ThreadBase *thread,
- const sp<Client>& client,
- uint32_t sampleRate,
- audio_format_t format,
- audio_channel_mask_t channelMask,
- size_t frameCount,
- const sp<IMemory>& sharedBuffer,
- int sessionId);
- virtual ~TrackBase();
-
- virtual status_t start(AudioSystem::sync_event_t event,
- int triggerSession) = 0;
- virtual void stop() = 0;
- sp<IMemory> getCblk() const { return mCblkMemory; }
- audio_track_cblk_t* cblk() const { return mCblk; }
- int sessionId() const { return mSessionId; }
- virtual status_t setSyncEvent(const sp<SyncEvent>& event);
-
- protected:
- TrackBase(const TrackBase&);
- TrackBase& operator = (const TrackBase&);
-
- // AudioBufferProvider interface
- virtual status_t getNextBuffer(AudioBufferProvider::Buffer* buffer, int64_t pts) = 0;
- virtual void releaseBuffer(AudioBufferProvider::Buffer* buffer);
-
- // ExtendedAudioBufferProvider interface is only needed for Track,
- // but putting it in TrackBase avoids the complexity of virtual inheritance
- virtual size_t framesReady() const { return SIZE_MAX; }
-
- audio_format_t format() const {
- return mFormat;
- }
-
- uint32_t channelCount() const { return mChannelCount; }
-
- audio_channel_mask_t channelMask() const { return mChannelMask; }
-
- uint32_t sampleRate() const; // FIXME inline after cblk sr moved
-
- // Return a pointer to the start of a contiguous slice of the track buffer.
- // Parameter 'offset' is the requested start position, expressed in
- // monotonically increasing frame units relative to the track epoch.
- // Parameter 'frames' is the requested length, also in frame units.
- // Always returns non-NULL. It is the caller's responsibility to
- // verify that this will be successful; the result of calling this
- // function with invalid 'offset' or 'frames' is undefined.
- void* getBuffer(uint32_t offset, uint32_t frames) const;
-
- bool isStopped() const {
- return (mState == STOPPED || mState == FLUSHED);
- }
-
- // for fast tracks only
- bool isStopping() const {
- return mState == STOPPING_1 || mState == STOPPING_2;
- }
- bool isStopping_1() const {
- return mState == STOPPING_1;
- }
- bool isStopping_2() const {
- return mState == STOPPING_2;
- }
-
- bool isTerminated() const {
- return mState == TERMINATED;
- }
-
- bool step(); // mStepCount is an implicit input
- void reset();
-
- virtual bool isOut() const = 0; // true for Track and TimedTrack, false for RecordTrack,
- // this could be a track type if needed later
-
- const wp<ThreadBase> mThread;
- /*const*/ sp<Client> mClient; // see explanation at ~TrackBase() why not const
- sp<IMemory> mCblkMemory;
- audio_track_cblk_t* mCblk;
- void* mBuffer; // start of track buffer, typically in shared memory
- void* mBufferEnd; // &mBuffer[mFrameCount * frameSize], where frameSize
- // is based on mChannelCount and 16-bit samples
- uint32_t mStepCount; // saves AudioBufferProvider::Buffer::frameCount as of
- // time of releaseBuffer() for later use by step()
- // 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;
- const audio_channel_mask_t mChannelMask;
- const uint8_t mChannelCount;
- const size_t mFrameSize; // AudioFlinger's view of frame size in shared memory,
- // where for AudioTrack (but not AudioRecord),
- // 8-bit PCM samples are stored as 16-bit
- const size_t mFrameCount;// size of track buffer given at createTrack() or
- // openRecord(), and then adjusted as needed
- bool mStepServerFailed;
- const int mSessionId;
- Vector < sp<SyncEvent> >mSyncEvents;
- };
-
- enum {
- CFG_EVENT_IO,
- CFG_EVENT_PRIO
- };
-
- class ConfigEvent {
- public:
- ConfigEvent(int type) : mType(type) {}
- virtual ~ConfigEvent() {}
-
- int type() const { return mType; }
-
- virtual void dump(char *buffer, size_t size) = 0;
-
- private:
- const int mType;
- };
-
- class IoConfigEvent : public ConfigEvent {
- public:
- IoConfigEvent(int event, int param) :
- ConfigEvent(CFG_EVENT_IO), mEvent(event), mParam(event) {}
- virtual ~IoConfigEvent() {}
-
- int event() const { return mEvent; }
- int param() const { return mParam; }
-
- virtual void dump(char *buffer, size_t size) {
- snprintf(buffer, size, "IO event: event %d, param %d\n", mEvent, mParam);
- }
-
- private:
- const int mEvent;
- const int mParam;
- };
-
- class PrioConfigEvent : public ConfigEvent {
- public:
- PrioConfigEvent(pid_t pid, pid_t tid, int32_t prio) :
- ConfigEvent(CFG_EVENT_PRIO), mPid(pid), mTid(tid), mPrio(prio) {}
- virtual ~PrioConfigEvent() {}
-
- pid_t pid() const { return mPid; }
- pid_t tid() const { return mTid; }
- int32_t prio() const { return mPrio; }
-
- virtual void dump(char *buffer, size_t size) {
- snprintf(buffer, size, "Prio event: pid %d, tid %d, prio %d\n", mPid, mTid, mPrio);
- }
-
- private:
- const pid_t mPid;
- const pid_t mTid;
- const int32_t mPrio;
- };
-
-
- class PMDeathRecipient : public IBinder::DeathRecipient {
- public:
- PMDeathRecipient(const wp<ThreadBase>& thread) : mThread(thread) {}
- virtual ~PMDeathRecipient() {}
-
- // IBinder::DeathRecipient
- virtual void binderDied(const wp<IBinder>& who);
-
- private:
- PMDeathRecipient(const PMDeathRecipient&);
- PMDeathRecipient& operator = (const PMDeathRecipient&);
-
- wp<ThreadBase> mThread;
- };
-
- virtual status_t initCheck() const = 0;
-
- // static externally-visible
- type_t type() const { return mType; }
- audio_io_handle_t id() const { return mId;}
-
- // dynamic externally-visible
- uint32_t sampleRate() const { return mSampleRate; }
- uint32_t channelCount() const { return mChannelCount; }
- audio_channel_mask_t channelMask() const { return mChannelMask; }
- audio_format_t format() const { return mFormat; }
- // Called by AudioFlinger::frameCount(audio_io_handle_t output) and effects,
- // and returns the normal mix buffer's frame count.
- size_t frameCount() const { return mNormalFrameCount; }
- // Return's the HAL's frame count i.e. fast mixer buffer size.
- size_t frameCountHAL() const { return mFrameCount; }
-
- // Should be "virtual status_t requestExitAndWait()" and override same
- // method in Thread, but Thread::requestExitAndWait() is not yet virtual.
- void exit();
- virtual bool checkForNewParameters_l() = 0;
- virtual status_t setParameters(const String8& keyValuePairs);
- virtual String8 getParameters(const String8& keys) = 0;
- virtual void audioConfigChanged_l(int event, int param = 0) = 0;
- void sendIoConfigEvent(int event, int param = 0);
- void sendIoConfigEvent_l(int event, int param = 0);
- void sendPrioConfigEvent_l(pid_t pid, pid_t tid, int32_t prio);
- void processConfigEvents();
-
- // see note at declaration of mStandby, mOutDevice and mInDevice
- bool standby() const { return mStandby; }
- audio_devices_t outDevice() const { return mOutDevice; }
- audio_devices_t inDevice() const { return mInDevice; }
-
- virtual audio_stream_t* stream() const = 0;
-
- sp<EffectHandle> createEffect_l(
- const sp<AudioFlinger::Client>& client,
- const sp<IEffectClient>& effectClient,
- int32_t priority,
- int sessionId,
- effect_descriptor_t *desc,
- int *enabled,
- status_t *status);
- void disconnectEffect(const sp< EffectModule>& effect,
- EffectHandle *handle,
- bool unpinIfLast);
-
- // return values for hasAudioSession (bit field)
- enum effect_state {
- EFFECT_SESSION = 0x1, // the audio session corresponds to at least one
- // effect
- TRACK_SESSION = 0x2 // the audio session corresponds to at least one
- // track
- };
-
- // get effect chain corresponding to session Id.
- sp<EffectChain> getEffectChain(int sessionId);
- // same as getEffectChain() but must be called with ThreadBase mutex locked
- sp<EffectChain> getEffectChain_l(int sessionId) const;
- // add an effect chain to the chain list (mEffectChains)
- virtual status_t addEffectChain_l(const sp<EffectChain>& chain) = 0;
- // remove an effect chain from the chain list (mEffectChains)
- virtual size_t removeEffectChain_l(const sp<EffectChain>& chain) = 0;
- // lock all effect chains Mutexes. Must be called before releasing the
- // ThreadBase mutex before processing the mixer and effects. This guarantees the
- // integrity of the chains during the process.
- // Also sets the parameter 'effectChains' to current value of mEffectChains.
- void lockEffectChains_l(Vector< sp<EffectChain> >& effectChains);
- // unlock effect chains after process
- void unlockEffectChains(const Vector< sp<EffectChain> >& effectChains);
- // set audio mode to all effect chains
- void setMode(audio_mode_t mode);
- // get effect module with corresponding ID on specified audio session
- sp<AudioFlinger::EffectModule> getEffect(int sessionId, int effectId);
- sp<AudioFlinger::EffectModule> getEffect_l(int sessionId, int effectId);
- // add and effect module. Also creates the effect chain is none exists for
- // the effects audio session
- status_t addEffect_l(const sp< EffectModule>& effect);
- // remove and effect module. Also removes the effect chain is this was the last
- // effect
- void removeEffect_l(const sp< EffectModule>& effect);
- // detach all tracks connected to an auxiliary effect
- virtual void detachAuxEffect_l(int effectId) {}
- // returns either EFFECT_SESSION if effects on this audio session exist in one
- // chain, or TRACK_SESSION if tracks on this audio session exist, or both
- virtual uint32_t hasAudioSession(int sessionId) const = 0;
- // the value returned by default implementation is not important as the
- // strategy is only meaningful for PlaybackThread which implements this method
- virtual uint32_t getStrategyForSession_l(int sessionId) { return 0; }
-
- // suspend or restore effect according to the type of effect passed. a NULL
- // type pointer means suspend all effects in the session
- void setEffectSuspended(const effect_uuid_t *type,
- bool suspend,
- int sessionId = AUDIO_SESSION_OUTPUT_MIX);
- // check if some effects must be suspended/restored when an effect is enabled
- // or disabled
- void checkSuspendOnEffectEnabled(const sp<EffectModule>& effect,
- bool enabled,
- int sessionId = AUDIO_SESSION_OUTPUT_MIX);
- void checkSuspendOnEffectEnabled_l(const sp<EffectModule>& effect,
- bool enabled,
- int sessionId = AUDIO_SESSION_OUTPUT_MIX);
-
- virtual status_t setSyncEvent(const sp<SyncEvent>& event) = 0;
- virtual bool isValidSyncEvent(const sp<SyncEvent>& event) const = 0;
-
-
- mutable Mutex mLock;
-
- protected:
-
- // entry describing an effect being suspended in mSuspendedSessions keyed vector
- class SuspendedSessionDesc : public RefBase {
- public:
- SuspendedSessionDesc() : mRefCount(0) {}
-
- int mRefCount; // number of active suspend requests
- effect_uuid_t mType; // effect type UUID
- };
-
- void acquireWakeLock();
- void acquireWakeLock_l();
- void releaseWakeLock();
- void releaseWakeLock_l();
- void setEffectSuspended_l(const effect_uuid_t *type,
- bool suspend,
- int sessionId);
- // updated mSuspendedSessions when an effect suspended or restored
- void updateSuspendedSessions_l(const effect_uuid_t *type,
- bool suspend,
- int sessionId);
- // check if some effects must be suspended when an effect chain is added
- void checkSuspendOnAddEffectChain_l(const sp<EffectChain>& chain);
-
- virtual void preExit() { }
-
- friend class AudioFlinger; // for mEffectChains
-
- const type_t mType;
-
- // Used by parameters, config events, addTrack_l, exit
- Condition mWaitWorkCV;
-
- const sp<AudioFlinger> mAudioFlinger;
- uint32_t mSampleRate;
- size_t mFrameCount; // output HAL, direct output, record
- size_t mNormalFrameCount; // normal mixer and effects
- audio_channel_mask_t mChannelMask;
- uint16_t mChannelCount;
- size_t mFrameSize;
- audio_format_t mFormat;
-
- // Parameter sequence by client: binder thread calling setParameters():
- // 1. Lock mLock
- // 2. Append to mNewParameters
- // 3. mWaitWorkCV.signal
- // 4. mParamCond.waitRelative with timeout
- // 5. read mParamStatus
- // 6. mWaitWorkCV.signal
- // 7. Unlock
- //
- // Parameter sequence by server: threadLoop calling checkForNewParameters_l():
- // 1. Lock mLock
- // 2. If there is an entry in mNewParameters proceed ...
- // 2. Read first entry in mNewParameters
- // 3. Process
- // 4. Remove first entry from mNewParameters
- // 5. Set mParamStatus
- // 6. mParamCond.signal
- // 7. mWaitWorkCV.wait with timeout (this is to avoid overwriting mParamStatus)
- // 8. Unlock
- Condition mParamCond;
- Vector<String8> mNewParameters;
- status_t mParamStatus;
-
- Vector<ConfigEvent *> mConfigEvents;
-
- // These fields are written and read by thread itself without lock or barrier,
- // and read by other threads without lock or barrier via standby() , outDevice()
- // and inDevice().
- // Because of the absence of a lock or barrier, any other thread that reads
- // these fields must use the information in isolation, or be prepared to deal
- // with possibility that it might be inconsistent with other information.
- bool mStandby; // Whether thread is currently in standby.
- audio_devices_t mOutDevice; // output device
- audio_devices_t mInDevice; // input device
- audio_source_t mAudioSource; // (see audio.h, audio_source_t)
-
- const audio_io_handle_t mId;
- Vector< sp<EffectChain> > mEffectChains;
-
- static const int kNameLength = 16; // prctl(PR_SET_NAME) limit
- char mName[kNameLength];
- sp<IPowerManager> mPowerManager;
- sp<IBinder> mWakeLockToken;
- const sp<PMDeathRecipient> mDeathRecipient;
- // list of suspended effects per session and per type. The first vector is
- // keyed by session ID, the second by type UUID timeLow field
- KeyedVector< int, KeyedVector< int, sp<SuspendedSessionDesc> > >
- mSuspendedSessions;
- };
-
struct stream_type_t {
stream_type_t()
: volume(1.0f),
@@ -772,658 +371,10 @@ private:
};
// --- PlaybackThread ---
- class PlaybackThread : public ThreadBase {
- public:
-
- enum mixer_state {
- MIXER_IDLE, // no active tracks
- MIXER_TRACKS_ENABLED, // at least one active track, but no track has any data ready
- MIXER_TRACKS_READY // at least one active track, and at least one track has data
- // standby mode does not have an enum value
- // suspend by audio policy manager is orthogonal to mixer state
- };
-
- // playback track
- class Track : public TrackBase, public VolumeProvider {
- public:
- Track( PlaybackThread *thread,
- const sp<Client>& client,
- audio_stream_type_t streamType,
- uint32_t sampleRate,
- audio_format_t format,
- audio_channel_mask_t channelMask,
- size_t frameCount,
- const sp<IMemory>& sharedBuffer,
- int sessionId,
- IAudioFlinger::track_flags_t flags);
- virtual ~Track();
-
- static void appendDumpHeader(String8& result);
- void dump(char* buffer, size_t size);
- virtual status_t start(AudioSystem::sync_event_t event =
- AudioSystem::SYNC_EVENT_NONE,
- int triggerSession = 0);
- virtual void stop();
- void pause();
-
- void flush();
- void destroy();
- void mute(bool);
- int name() const { return mName; }
-
- audio_stream_type_t streamType() const {
- return mStreamType;
- }
- status_t attachAuxEffect(int EffectId);
- void setAuxBuffer(int EffectId, int32_t *buffer);
- int32_t *auxBuffer() const { return mAuxBuffer; }
- void setMainBuffer(int16_t *buffer) { mMainBuffer = buffer; }
- int16_t *mainBuffer() const { return mMainBuffer; }
- int auxEffectId() const { return mAuxEffectId; }
-
- // implement FastMixerState::VolumeProvider interface
- virtual uint32_t getVolumeLR();
-
- virtual status_t setSyncEvent(const sp<SyncEvent>& event);
-
- protected:
- // for numerous
- friend class PlaybackThread;
- friend class MixerThread;
- friend class DirectOutputThread;
-
- Track(const Track&);
- Track& operator = (const Track&);
-
- // AudioBufferProvider interface
- virtual status_t getNextBuffer(AudioBufferProvider::Buffer* buffer,
- int64_t pts = kInvalidPTS);
- // releaseBuffer() not overridden
-
- virtual size_t framesReady() const;
-
- bool isMuted() const { return mMute; }
- bool isPausing() const {
- return mState == PAUSING;
- }
- bool isPaused() const {
- return mState == PAUSED;
- }
- bool isResuming() const {
- return mState == RESUMING;
- }
- bool isReady() const;
- void setPaused() { mState = PAUSED; }
- void reset();
-
- bool isOutputTrack() const {
- return (mStreamType == AUDIO_STREAM_CNT);
- }
-
- sp<IMemory> sharedBuffer() const { return mSharedBuffer; }
-
- // framesWritten is cumulative, never reset, and is shared all tracks
- // audioHalFrames is derived from output latency
- // FIXME parameters not needed, could get them from the thread
- bool presentationComplete(size_t framesWritten, size_t audioHalFrames);
-
- public:
- void triggerEvents(AudioSystem::sync_event_t type);
- virtual bool isTimedTrack() const { return false; }
- bool isFastTrack() const { return (mFlags & IAudioFlinger::TRACK_FAST) != 0; }
- virtual bool isOut() const;
-
- protected:
-
- // written by Track::mute() called by binder thread(s), without a mutex or barrier.
- // read by Track::isMuted() called by playback thread, also without a mutex or barrier.
- // The lack of mutex or barrier is safe because the mute status is only used by itself.
- bool mMute;
-
- // FILLED state is used for suppressing volume ramp at begin of playing
- 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; // track name on the normal mixer,
- // allocated statically at track creation time,
- // and is even allocated (though unused) for fast tracks
- // FIXME don't allocate track name for fast tracks
- int16_t *mMainBuffer;
- int32_t *mAuxBuffer;
- int mAuxEffectId;
- bool mHasVolumeController;
- size_t mPresentationCompleteFrames; // number of frames written to the
- // audio HAL when this track will be fully rendered
- // zero means not monitoring
- private:
- IAudioFlinger::track_flags_t mFlags;
-
- // The following fields are only for fast tracks, and should be in a subclass
- int mFastIndex; // index within FastMixerState::mFastTracks[];
- // either mFastIndex == -1 if not isFastTrack()
- // or 0 < mFastIndex < FastMixerState::kMaxFast because
- // index 0 is reserved for normal mixer's submix;
- // index is allocated statically at track creation time
- // but the slot is only used if track is active
- FastTrackUnderruns mObservedUnderruns; // Most recently observed value of
- // mFastMixerDumpState.mTracks[mFastIndex].mUnderruns
- uint32_t mUnderrunCount; // Counter of total number of underruns, never reset
- 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 {
- public:
- static sp<TimedTrack> create(PlaybackThread *thread,
- const sp<Client>& client,
- audio_stream_type_t streamType,
- uint32_t sampleRate,
- audio_format_t format,
- audio_channel_mask_t channelMask,
- size_t frameCount,
- const sp<IMemory>& sharedBuffer,
- int sessionId);
- virtual ~TimedTrack();
-
- class TimedBuffer {
- public:
- TimedBuffer();
- TimedBuffer(const sp<IMemory>& buffer, int64_t pts);
- const sp<IMemory>& buffer() const { return mBuffer; }
- int64_t pts() const { return mPTS; }
- uint32_t position() const { return mPosition; }
- void setPosition(uint32_t pos) { mPosition = pos; }
- private:
- sp<IMemory> mBuffer;
- int64_t mPTS;
- uint32_t mPosition;
- };
-
- // Mixer facing methods.
- virtual bool isTimedTrack() const { return true; }
- virtual size_t framesReady() const;
-
- // AudioBufferProvider interface
- virtual status_t getNextBuffer(AudioBufferProvider::Buffer* buffer,
- int64_t pts);
- virtual void releaseBuffer(AudioBufferProvider::Buffer* buffer);
-
- // Client/App facing methods.
- status_t allocateTimedBuffer(size_t size,
- sp<IMemory>* buffer);
- status_t queueTimedBuffer(const sp<IMemory>& buffer,
- int64_t pts);
- status_t setMediaTimeTransform(const LinearTransform& xform,
- TimedAudioTrack::TargetTimeline target);
-
- private:
- TimedTrack(PlaybackThread *thread,
- const sp<Client>& client,
- audio_stream_type_t streamType,
- uint32_t sampleRate,
- audio_format_t format,
- audio_channel_mask_t channelMask,
- size_t frameCount,
- const sp<IMemory>& sharedBuffer,
- int sessionId);
-
- void timedYieldSamples_l(AudioBufferProvider::Buffer* buffer);
- void timedYieldSilence_l(uint32_t numFrames,
- AudioBufferProvider::Buffer* buffer);
- void trimTimedBufferQueue_l();
- void trimTimedBufferQueueHead_l(const char* logTag);
- void updateFramesPendingAfterTrim_l(const TimedBuffer& buf,
- const char* logTag);
-
- uint64_t mLocalTimeFreq;
- LinearTransform mLocalTimeToSampleTransform;
- LinearTransform mMediaTimeToSampleTransform;
- sp<MemoryDealer> mTimedMemoryDealer;
-
- Vector<TimedBuffer> mTimedBufferQueue;
- bool mQueueHeadInFlight;
- bool mTrimQueueHeadOnRelease;
- uint32_t mFramesPendingInQueue;
-
- uint8_t* mTimedSilenceBuffer;
- uint32_t mTimedSilenceBufferSize;
- mutable Mutex mTimedBufferQueueLock;
- bool mTimedAudioOutputOnTime;
- CCHelper mCCHelper;
-
- Mutex mMediaTimeTransformLock;
- LinearTransform mMediaTimeTransform;
- bool mMediaTimeTransformValid;
- TimedAudioTrack::TargetTimeline mMediaTimeTransformTarget;
- };
-
-
- // playback track, used by DuplicatingThread
- class OutputTrack : public Track {
- public:
-
- class Buffer : public AudioBufferProvider::Buffer {
- public:
- int16_t *mBuffer;
- };
-
- OutputTrack(PlaybackThread *thread,
- DuplicatingThread *sourceThread,
- uint32_t sampleRate,
- audio_format_t format,
- audio_channel_mask_t channelMask,
- size_t frameCount);
- virtual ~OutputTrack();
-
- virtual status_t start(AudioSystem::sync_event_t event =
- AudioSystem::SYNC_EVENT_NONE,
- int triggerSession = 0);
- virtual void stop();
- bool write(int16_t* data, uint32_t frames);
- bool bufferQueueEmpty() const { return mBufferQueue.size() == 0; }
- bool isActive() const { return mActive; }
- const wp<ThreadBase>& thread() const { return mThread; }
-
- private:
-
- enum {
- NO_MORE_BUFFERS = 0x80000001, // same in AudioTrack.h, ok to be different value
- };
-
- status_t obtainBuffer(AudioBufferProvider::Buffer* buffer,
- uint32_t waitTimeMs);
- void clearBufferQueue();
-
- // Maximum number of pending buffers allocated by OutputTrack::write()
- static const uint8_t kMaxOverFlowBuffers = 10;
-
- Vector < Buffer* > mBufferQueue;
- AudioBufferProvider::Buffer mOutBuffer;
- bool mActive;
- DuplicatingThread* const mSourceThread; // for waitTimeMs() in write()
- void* mBuffers; // starting address of buffers in plain memory
- }; // end of OutputTrack
-
- PlaybackThread(const sp<AudioFlinger>& audioFlinger, AudioStreamOut* output,
- audio_io_handle_t id, audio_devices_t device, type_t type);
- virtual ~PlaybackThread();
-
- void dump(int fd, const Vector<String16>& args);
-
- // Thread virtuals
- virtual status_t readyToRun();
- virtual bool threadLoop();
-
- // RefBase
- virtual void onFirstRef();
-
-protected:
- // Code snippets that were lifted up out of threadLoop()
- virtual void threadLoop_mix() = 0;
- 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 returns
- // the pending set of tracks to remove via Vector 'tracksToRemove'. The caller
- // is responsible for clearing or destroying this Vector later on, when it
- // is safe to do so. That will drop the final ref count and destroy the tracks.
- virtual mixer_state prepareTracks_l(Vector< sp<Track> > *tracksToRemove) = 0;
-
- // ThreadBase virtuals
- virtual void preExit();
-
-public:
-
- virtual status_t initCheck() const { return (mOutput == NULL) ? NO_INIT : NO_ERROR; }
-
- // return estimated latency in milliseconds, as reported by HAL
- uint32_t latency() const;
- // same, but lock must already be held
- uint32_t latency_l() const;
-
- void setMasterVolume(float value);
- void setMasterMute(bool muted);
-
- void setStreamVolume(audio_stream_type_t stream, float value);
- void setStreamMute(audio_stream_type_t stream, bool muted);
-
- float streamVolume(audio_stream_type_t stream) const;
-
- sp<Track> createTrack_l(
- const sp<AudioFlinger::Client>& client,
- audio_stream_type_t streamType,
- uint32_t sampleRate,
- audio_format_t format,
- audio_channel_mask_t channelMask,
- size_t frameCount,
- const sp<IMemory>& sharedBuffer,
- int sessionId,
- IAudioFlinger::track_flags_t *flags,
- pid_t tid,
- status_t *status);
-
- AudioStreamOut* getOutput() const;
- AudioStreamOut* clearOutput();
- virtual audio_stream_t* stream() const;
-
- // a very large number of suspend() will eventually wraparound, but unlikely
- void suspend() { (void) android_atomic_inc(&mSuspended); }
- void restore()
- {
- // if restore() is done without suspend(), get back into
- // range so that the next suspend() will operate correctly
- if (android_atomic_dec(&mSuspended) <= 0) {
- android_atomic_release_store(0, &mSuspended);
- }
- }
- bool isSuspended() const
- { return android_atomic_acquire_load(&mSuspended) > 0; }
-
- virtual String8 getParameters(const String8& keys);
- virtual void audioConfigChanged_l(int event, int param = 0);
- status_t getRenderPosition(size_t *halFrames, size_t *dspFrames);
- int16_t *mixBuffer() const { return mMixBuffer; };
-
- virtual void detachAuxEffect_l(int effectId);
- status_t attachAuxEffect(const sp<AudioFlinger::PlaybackThread::Track> track,
- int EffectId);
- status_t attachAuxEffect_l(const sp<AudioFlinger::PlaybackThread::Track> track,
- int EffectId);
-
- virtual status_t addEffectChain_l(const sp<EffectChain>& chain);
- virtual size_t removeEffectChain_l(const sp<EffectChain>& chain);
- virtual uint32_t hasAudioSession(int sessionId) const;
- virtual uint32_t getStrategyForSession_l(int sessionId);
-
-
- virtual status_t setSyncEvent(const sp<SyncEvent>& event);
- virtual bool isValidSyncEvent(const sp<SyncEvent>& event) const;
- void invalidateTracks(audio_stream_type_t streamType);
-
-
- protected:
- int16_t* mMixBuffer;
-
- // suspend count, > 0 means suspended. While suspended, the thread continues to pull from
- // tracks and mix, but doesn't write to HAL. A2DP and SCO HAL implementations can't handle
- // concurrent use of both of them, so Audio Policy Service suspends one of the threads to
- // workaround that restriction.
- // 'volatile' means accessed via atomic operations and no lock.
- volatile int32_t mSuspended;
-
- // FIXME overflows every 6+ hours at 44.1 kHz stereo 16-bit samples
- // mFramesWritten would be better, or 64-bit even better
- size_t mBytesWritten;
- private:
- // mMasterMute is in both PlaybackThread and in AudioFlinger. When a
- // PlaybackThread needs to find out if master-muted, it checks it's local
- // copy rather than the one in AudioFlinger. This optimization saves a lock.
- bool mMasterMute;
- void setMasterMute_l(bool muted) { mMasterMute = muted; }
- protected:
- SortedVector< wp<Track> > mActiveTracks; // FIXME check if this could be sp<>
-
- // Allocate a track name for a given channel mask.
- // Returns name >= 0 if successful, -1 on failure.
- virtual int getTrackName_l(audio_channel_mask_t channelMask, int sessionId) = 0;
- virtual void deleteTrackName_l(int name) = 0;
-
- // Time to sleep between cycles when:
- virtual uint32_t activeSleepTimeUs() const; // mixer state MIXER_TRACKS_ENABLED
- virtual uint32_t idleSleepTimeUs() const = 0; // mixer state MIXER_IDLE
- virtual uint32_t suspendSleepTimeUs() const = 0; // audio policy manager suspended us
- // No sleep when mixer state == MIXER_TRACKS_READY; relies on audio HAL stream->write()
- // No sleep in standby mode; waits on a condition
-
- // Code snippets that are temporarily lifted up out of threadLoop() until the merge
- void checkSilentMode_l();
-
- // Non-trivial for DUPLICATING only
- virtual void saveOutputTracks() { }
- virtual void clearOutputTracks() { }
-
- // Cache various calculated values, at threadLoop() entry and after a parameter change
- virtual void cacheParameters_l();
-
- virtual uint32_t correctLatency_l(uint32_t latency) const;
-
- private:
-
- friend class AudioFlinger; // for numerous
-
- PlaybackThread(const Client&);
- PlaybackThread& operator = (const PlaybackThread&);
-
- status_t addTrack_l(const sp<Track>& track);
- void destroyTrack_l(const sp<Track>& track);
- void removeTrack_l(const sp<Track>& track);
-
- void readOutputParameters();
-
- virtual void dumpInternals(int fd, const Vector<String16>& args);
- void dumpTracks(int fd, const Vector<String16>& args);
-
- SortedVector< sp<Track> > mTracks;
- // mStreamTypes[] uses 1 additional stream type internally for the OutputTrack used by
- // DuplicatingThread
- stream_type_t mStreamTypes[AUDIO_STREAM_CNT + 1];
- AudioStreamOut *mOutput;
-
- float mMasterVolume;
- nsecs_t mLastWriteTime;
- int mNumWrites;
- int mNumDelayedWrites;
- bool mInWrite;
-
- // FIXME rename these former local variables of threadLoop to standard "m" names
- nsecs_t standbyTime;
- size_t mixBufferSize;
-
- // cached copies of activeSleepTimeUs() and idleSleepTimeUs() made by cacheParameters_l()
- uint32_t activeSleepTime;
- uint32_t idleSleepTime;
-
- uint32_t sleepTime;
-
- // mixer status returned by prepareTracks_l()
- mixer_state mMixerStatus; // current cycle
- // previous cycle when in prepareTracks_l()
- mixer_state mMixerStatusIgnoringFastTracks;
- // FIXME or a separate ready state per track
-
- // FIXME move these declarations into the specific sub-class that needs them
- // MIXER only
- uint32_t sleepTimeShift;
-
- // same as AudioFlinger::mStandbyTimeInNsecs except for DIRECT which uses a shorter value
- nsecs_t standbyDelay;
-
- // MIXER only
- nsecs_t maxPeriod;
-
- // 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;
- // For dumpsys
- sp<NBAIO_Sink> mTeeSink;
- sp<NBAIO_Source> mTeeSource;
- uint32_t mScreenState; // cached copy of gScreenState
- public:
- virtual bool hasFastMixer() const = 0;
- virtual FastTrackUnderruns getFastTrackUnderruns(size_t fastIndex) const
- { FastTrackUnderruns dummy; return dummy; }
-
- protected:
- // accessed by both binder threads and within threadLoop(), lock on mutex needed
- unsigned mFastTrackAvailMask; // bit i set if fast track [i] is available
-
- };
-
- class MixerThread : public PlaybackThread {
- public:
- MixerThread(const sp<AudioFlinger>& audioFlinger,
- AudioStreamOut* output,
- audio_io_handle_t id,
- audio_devices_t device,
- type_t type = MIXER);
- virtual ~MixerThread();
-
- // Thread virtuals
-
- virtual bool checkForNewParameters_l();
- virtual void dumpInternals(int fd, const Vector<String16>& args);
-
- protected:
- virtual mixer_state prepareTracks_l(Vector< sp<Track> > *tracksToRemove);
- virtual int getTrackName_l(audio_channel_mask_t channelMask, int sessionId);
- virtual void deleteTrackName_l(int name);
- virtual uint32_t idleSleepTimeUs() const;
- virtual uint32_t suspendSleepTimeUs() const;
- 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);
- virtual uint32_t correctLatency_l(uint32_t latency) const;
-
- AudioMixer* mAudioMixer; // normal mixer
- private:
- // one-time initialization, no locks required
- FastMixer* mFastMixer; // non-NULL if there is also a fast mixer
- sp<AudioWatchdog> mAudioWatchdog; // non-0 if there is an audio watchdog thread
-
- // contents are not guaranteed to be consistent, no locks required
- FastMixerDumpState mFastMixerDumpState;
-#ifdef STATE_QUEUE_DUMP
- StateQueueObserverDump mStateQueueObserverDump;
- StateQueueMutatorDump mStateQueueMutatorDump;
-#endif
- AudioWatchdogDump mAudioWatchdogDump;
-
- // 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; }
- virtual FastTrackUnderruns getFastTrackUnderruns(size_t fastIndex) const {
- ALOG_ASSERT(fastIndex < FastMixerState::kMaxFastTracks);
- return mFastMixerDumpState.mTracks[fastIndex].mUnderruns;
- }
- };
-
- class DirectOutputThread : public PlaybackThread {
- public:
-
- DirectOutputThread(const sp<AudioFlinger>& audioFlinger, AudioStreamOut* output,
- audio_io_handle_t id, audio_devices_t device);
- virtual ~DirectOutputThread();
-
- // Thread virtuals
-
- virtual bool checkForNewParameters_l();
-
- protected:
- virtual int getTrackName_l(audio_channel_mask_t channelMask, int sessionId);
- virtual void deleteTrackName_l(int name);
- virtual uint32_t activeSleepTimeUs() const;
- virtual uint32_t idleSleepTimeUs() const;
- virtual uint32_t suspendSleepTimeUs() const;
- virtual void cacheParameters_l();
-
- // threadLoop snippets
- virtual mixer_state prepareTracks_l(Vector< sp<Track> > *tracksToRemove);
- virtual void threadLoop_mix();
- virtual void threadLoop_sleepTime();
-
- private:
- // volumes last sent to audio HAL with stream->set_volume()
- float mLeftVolFloat;
- float mRightVolFloat;
-
- // 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 {
- public:
- DuplicatingThread(const sp<AudioFlinger>& audioFlinger, MixerThread* mainThread,
- audio_io_handle_t id);
- virtual ~DuplicatingThread();
-
- // Thread virtuals
- void addOutputTrack(MixerThread* thread);
- void removeOutputTrack(MixerThread* thread);
- uint32_t waitTimeMs() const { return mWaitTimeMs; }
- protected:
- virtual uint32_t activeSleepTimeUs() const;
-
- private:
- bool outputsReady(const SortedVector< sp<OutputTrack> > &outputTracks);
- protected:
- // threadLoop snippets
- virtual void threadLoop_mix();
- virtual void threadLoop_sleepTime();
- virtual void threadLoop_write();
- virtual void threadLoop_standby();
- virtual void cacheParameters_l();
-
- private:
- // called from threadLoop, addOutputTrack, removeOutputTrack
- virtual void updateWaitTime_l();
- protected:
- virtual void saveOutputTracks();
- virtual void clearOutputTracks();
- private:
-
- 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;
- MixerThread *checkMixerThread_l(audio_io_handle_t output) const;
- RecordThread *checkRecordThread_l(audio_io_handle_t input) const;
- // no range check, AudioFlinger::mLock held
- bool streamMute_l(audio_stream_type_t stream) const
- { return mStreamTypes[stream].mute; }
- // no range check, doesn't check per-thread stream volume, AudioFlinger::mLock held
- float streamVolume_l(audio_stream_type_t stream) const
- { return mStreamTypes[stream].volume; }
- void audioConfigChanged_l(int event, audio_io_handle_t ioHandle, const void *param2);
-
- // allocate an audio_io_handle_t, session ID, or effect ID
- uint32_t nextUniqueId();
- status_t moveEffectChain_l(int sessionId,
- PlaybackThread *srcThread,
- PlaybackThread *dstThread,
- bool reRegister);
- // return thread associated with primary hardware device, or NULL
- PlaybackThread *primaryPlaybackThread_l() const;
- audio_devices_t primaryOutputDevice_l() const;
+#include "Threads.h"
- sp<PlaybackThread> getEffectThread_l(int sessionId, int EffectId);
+#include "Effects.h"
// server side of the client's IAudioTrack
class TrackHandle : public android::BnAudioTrack {
@@ -1449,165 +400,6 @@ public:
const sp<PlaybackThread::Track> mTrack;
};
- void removeClient_l(pid_t pid);
- void removeNotificationClient(pid_t pid);
-
-
- // record thread
- class RecordThread : public ThreadBase, public AudioBufferProvider
- // derives from AudioBufferProvider interface for use by resampler
- {
- public:
-
- // record track
- class RecordTrack : public TrackBase {
- public:
- RecordTrack(RecordThread *thread,
- const sp<Client>& client,
- uint32_t sampleRate,
- audio_format_t format,
- audio_channel_mask_t channelMask,
- size_t frameCount,
- int sessionId);
- virtual ~RecordTrack();
-
- virtual status_t start(AudioSystem::sync_event_t event, int triggerSession);
- virtual void stop();
-
- void destroy();
-
- // clear the buffer overflow flag
- void clearOverflow() { mOverflow = false; }
- // set the buffer overflow flag and return previous value
- bool setOverflow() { bool tmp = mOverflow; mOverflow = true;
- return tmp; }
-
- static void appendDumpHeader(String8& result);
- void dump(char* buffer, size_t size);
-
- virtual bool isOut() const;
-
- private:
- friend class AudioFlinger; // for mState
-
- RecordTrack(const RecordTrack&);
- RecordTrack& operator = (const RecordTrack&);
-
- // AudioBufferProvider interface
- virtual status_t getNextBuffer(AudioBufferProvider::Buffer* buffer,
- int64_t pts = kInvalidPTS);
- // releaseBuffer() not overridden
-
- bool mOverflow; // overflow on most recent attempt to fill client buffer
- };
-
- RecordThread(const sp<AudioFlinger>& audioFlinger,
- AudioStreamIn *input,
- uint32_t sampleRate,
- audio_channel_mask_t channelMask,
- audio_io_handle_t id,
- audio_devices_t device,
- const sp<NBAIO_Sink>& teeSink);
- virtual ~RecordThread();
-
- // no addTrack_l ?
- void destroyTrack_l(const sp<RecordTrack>& track);
- void removeTrack_l(const sp<RecordTrack>& track);
-
- void dumpInternals(int fd, const Vector<String16>& args);
- void dumpTracks(int fd, const Vector<String16>& args);
-
- // Thread virtuals
- virtual bool threadLoop();
- virtual status_t readyToRun();
-
- // RefBase
- virtual void onFirstRef();
-
- virtual status_t initCheck() const { return (mInput == NULL) ? NO_INIT : NO_ERROR; }
- sp<AudioFlinger::RecordThread::RecordTrack> createRecordTrack_l(
- const sp<AudioFlinger::Client>& client,
- uint32_t sampleRate,
- audio_format_t format,
- audio_channel_mask_t channelMask,
- size_t frameCount,
- int sessionId,
- IAudioFlinger::track_flags_t flags,
- pid_t tid,
- status_t *status);
-
- status_t start(RecordTrack* recordTrack,
- AudioSystem::sync_event_t event,
- int triggerSession);
-
- // ask the thread to stop the specified track, and
- // return true if the caller should then do it's part of the stopping process
- bool stop_l(RecordTrack* recordTrack);
-
- void dump(int fd, const Vector<String16>& args);
- AudioStreamIn* clearInput();
- virtual audio_stream_t* stream() const;
-
- // AudioBufferProvider interface
- virtual status_t getNextBuffer(AudioBufferProvider::Buffer* buffer, int64_t pts);
- virtual void releaseBuffer(AudioBufferProvider::Buffer* buffer);
-
- virtual bool checkForNewParameters_l();
- virtual String8 getParameters(const String8& keys);
- virtual void audioConfigChanged_l(int event, int param = 0);
- void readInputParameters();
- virtual unsigned int getInputFramesLost();
-
- virtual status_t addEffectChain_l(const sp<EffectChain>& chain);
- virtual size_t removeEffectChain_l(const sp<EffectChain>& chain);
- virtual uint32_t hasAudioSession(int sessionId) const;
-
- // Return the set of unique session IDs across all tracks.
- // The keys are the session IDs, and the associated values are meaningless.
- // FIXME replace by Set [and implement Bag/Multiset for other uses].
- KeyedVector<int, bool> sessionIds() const;
-
- virtual status_t setSyncEvent(const sp<SyncEvent>& event);
- virtual bool isValidSyncEvent(const sp<SyncEvent>& event) const;
-
- static void syncStartEventCallback(const wp<SyncEvent>& event);
- void handleSyncStartEvent(const sp<SyncEvent>& event);
-
- private:
- void clearSyncStartEvent();
-
- // Enter standby if not already in standby, and set mStandby flag
- void standby();
-
- // Call the HAL standby method unconditionally, and don't change mStandby flag
- void inputStandBy();
-
- AudioStreamIn *mInput;
- SortedVector < sp<RecordTrack> > mTracks;
- // mActiveTrack has dual roles: it indicates the current active track, and
- // is used together with mStartStopCond to indicate start()/stop() progress
- sp<RecordTrack> mActiveTrack;
- Condition mStartStopCond;
- AudioResampler *mResampler;
- int32_t *mRsmpOutBuffer;
- int16_t *mRsmpInBuffer;
- size_t mRsmpInIndex;
- size_t mInputBytes;
- const uint32_t mReqChannelCount;
- const uint32_t mReqSampleRate;
- ssize_t mBytesRead;
- // sync event triggering actual audio capture. Frames read before this event will
- // be dropped and therefore not read by the application.
- sp<SyncEvent> mSyncStartEvent;
- // number of captured frames to drop after the start sync event has been received.
- // when < 0, maximum frames to drop before starting capture even if sync event is
- // not received
- ssize_t mFramestoDrop;
-
- // For dumpsys
- const sp<NBAIO_Sink> mTeeSink;
- };
-
// server side of the client's IAudioRecord
class RecordHandle : public android::BnAudioRecord {
public:
@@ -1625,344 +417,33 @@ public:
void stop_nonvirtual();
};
- //--- Audio Effect Management
-
- // EffectModule and EffectChain classes both have their own mutex to protect
- // state changes or resource modifications. Always respect the following order
- // if multiple mutexes must be acquired to avoid cross deadlock:
- // AudioFlinger -> ThreadBase -> EffectChain -> EffectModule
-
- // The EffectModule class is a wrapper object controlling the effect engine implementation
- // in the effect library. It prevents concurrent calls to process() and command() functions
- // from different client threads. It keeps a list of EffectHandle objects corresponding
- // to all client applications using this effect and notifies applications of effect state,
- // control or parameter changes. It manages the activation state machine to send appropriate
- // reset, enable, disable commands to effect engine and provide volume
- // ramping when effects are activated/deactivated.
- // When controlling an auxiliary effect, the EffectModule also provides an input buffer used by
- // the attached track(s) to accumulate their auxiliary channel.
- class EffectModule : public RefBase {
- public:
- EffectModule(ThreadBase *thread,
- const wp<AudioFlinger::EffectChain>& chain,
- effect_descriptor_t *desc,
- int id,
- int sessionId);
- virtual ~EffectModule();
-
- enum effect_state {
- IDLE,
- RESTART,
- STARTING,
- ACTIVE,
- STOPPING,
- STOPPED,
- DESTROYED
- };
-
- int id() const { return mId; }
- void process();
- void updateState();
- status_t command(uint32_t cmdCode,
- uint32_t cmdSize,
- void *pCmdData,
- uint32_t *replySize,
- void *pReplyData);
-
- void reset_l();
- status_t configure();
- status_t init();
- effect_state state() const {
- return mState;
- }
- uint32_t status() {
- return mStatus;
- }
- int sessionId() const {
- return mSessionId;
- }
- status_t setEnabled(bool enabled);
- status_t setEnabled_l(bool enabled);
- bool isEnabled() const;
- bool isProcessEnabled() const;
-
- void setInBuffer(int16_t *buffer) { mConfig.inputCfg.buffer.s16 = buffer; }
- int16_t *inBuffer() { return mConfig.inputCfg.buffer.s16; }
- void setOutBuffer(int16_t *buffer) { mConfig.outputCfg.buffer.s16 = buffer; }
- int16_t *outBuffer() { return mConfig.outputCfg.buffer.s16; }
- void setChain(const wp<EffectChain>& chain) { mChain = chain; }
- void setThread(const wp<ThreadBase>& thread) { mThread = thread; }
- const wp<ThreadBase>& thread() { return mThread; }
-
- status_t addHandle(EffectHandle *handle);
- size_t disconnect(EffectHandle *handle, bool unpinIfLast);
- size_t removeHandle(EffectHandle *handle);
-
- const effect_descriptor_t& desc() const { return mDescriptor; }
- wp<EffectChain>& chain() { return mChain; }
-
- status_t setDevice(audio_devices_t device);
- status_t setVolume(uint32_t *left, uint32_t *right, bool controller);
- status_t setMode(audio_mode_t mode);
- status_t setAudioSource(audio_source_t source);
- status_t start();
- status_t stop();
- void setSuspended(bool suspended);
- bool suspended() const;
-
- EffectHandle* controlHandle_l();
-
- bool isPinned() const { return mPinned; }
- void unPin() { mPinned = false; }
- bool purgeHandles();
- void lock() { mLock.lock(); }
- void unlock() { mLock.unlock(); }
-
- void dump(int fd, const Vector<String16>& args);
-
- protected:
- friend class AudioFlinger; // for mHandles
- bool mPinned;
-
- // Maximum time allocated to effect engines to complete the turn off sequence
- static const uint32_t MAX_DISABLE_TIME_MS = 10000;
-
- EffectModule(const EffectModule&);
- EffectModule& operator = (const EffectModule&);
-
- status_t start_l();
- status_t stop_l();
-
-mutable Mutex mLock; // mutex for process, commands and handles list protection
- wp<ThreadBase> mThread; // parent thread
- wp<EffectChain> mChain; // parent effect chain
- const int mId; // this instance unique ID
- const int mSessionId; // audio session ID
- const effect_descriptor_t mDescriptor;// effect descriptor received from effect engine
- effect_config_t mConfig; // input and output audio configuration
- effect_handle_t mEffectInterface; // Effect module C API
- status_t mStatus; // initialization status
- effect_state mState; // current activation state
- Vector<EffectHandle *> mHandles; // list of client handles
- // First handle in mHandles has highest priority and controls the effect module
- uint32_t mMaxDisableWaitCnt; // maximum grace period before forcing an effect off after
- // sending disable command.
- uint32_t mDisableWaitCnt; // current process() calls count during disable period.
- bool mSuspended; // effect is suspended: temporarily disabled by framework
- };
-
- // The EffectHandle class implements the IEffect interface. It provides resources
- // to receive parameter updates, keeps track of effect control
- // ownership and state and has a pointer to the EffectModule object it is controlling.
- // There is one EffectHandle object for each application controlling (or using)
- // an effect module.
- // The EffectHandle is obtained by calling AudioFlinger::createEffect().
- class EffectHandle: public android::BnEffect {
- public:
-
- EffectHandle(const sp<EffectModule>& effect,
- const sp<AudioFlinger::Client>& client,
- const sp<IEffectClient>& effectClient,
- int32_t priority);
- virtual ~EffectHandle();
-
- // IEffect
- virtual status_t enable();
- virtual status_t disable();
- virtual status_t command(uint32_t cmdCode,
- uint32_t cmdSize,
- void *pCmdData,
- uint32_t *replySize,
- void *pReplyData);
- virtual void disconnect();
- private:
- void disconnect(bool unpinIfLast);
- public:
- virtual sp<IMemory> getCblk() const { return mCblkMemory; }
- virtual status_t onTransact(uint32_t code, const Parcel& data,
- Parcel* reply, uint32_t flags);
-
-
- // Give or take control of effect module
- // - hasControl: true if control is given, false if removed
- // - signal: true client app should be signaled of change, false otherwise
- // - enabled: state of the effect when control is passed
- void setControl(bool hasControl, bool signal, bool enabled);
- void commandExecuted(uint32_t cmdCode,
- uint32_t cmdSize,
- void *pCmdData,
- uint32_t replySize,
- void *pReplyData);
- void setEnabled(bool enabled);
- bool enabled() const { return mEnabled; }
-
- // Getters
- int id() const { return mEffect->id(); }
- int priority() const { return mPriority; }
- bool hasControl() const { return mHasControl; }
- sp<EffectModule> effect() const { return mEffect; }
- // destroyed_l() must be called with the associated EffectModule mLock held
- bool destroyed_l() const { return mDestroyed; }
-
- void dump(char* buffer, size_t size);
-
- protected:
- friend class AudioFlinger; // for mEffect, mHasControl, mEnabled
- EffectHandle(const EffectHandle&);
- EffectHandle& operator =(const EffectHandle&);
-
- sp<EffectModule> mEffect; // pointer to controlled EffectModule
- sp<IEffectClient> mEffectClient; // callback interface for client notifications
- /*const*/ sp<Client> mClient; // client for shared memory allocation, see disconnect()
- sp<IMemory> mCblkMemory; // shared memory for control block
- effect_param_cblk_t* mCblk; // control block for deferred parameter setting via
- // shared memory
- uint8_t* mBuffer; // pointer to parameter area in shared memory
- int mPriority; // client application priority to control the effect
- bool mHasControl; // true if this handle is controlling the effect
- bool mEnabled; // cached enable state: needed when the effect is
- // restored after being suspended
- bool mDestroyed; // Set to true by destructor. Access with EffectModule
- // mLock held
- };
-
- // the EffectChain class represents a group of effects associated to one audio session.
- // There can be any number of EffectChain objects per output mixer thread (PlaybackThread).
- // The EffecChain with session ID 0 contains global effects applied to the output mix.
- // Effects in this chain can be insert or auxiliary. Effects in other chains (attached to
- // tracks) are insert only. The EffectChain maintains an ordered list of effect module, the
- // order corresponding in the effect process order. When attached to a track (session ID != 0),
- // it also provide it's own input buffer used by the track as accumulation buffer.
- class EffectChain : public RefBase {
- public:
- EffectChain(const wp<ThreadBase>& wThread, int sessionId);
- EffectChain(ThreadBase *thread, int sessionId);
- virtual ~EffectChain();
-
- // special key used for an entry in mSuspendedEffects keyed vector
- // corresponding to a suspend all request.
- static const int kKeyForSuspendAll = 0;
-
- // minimum duration during which we force calling effect process when last track on
- // a session is stopped or removed to allow effect tail to be rendered
- static const int kProcessTailDurationMs = 1000;
-
- void process_l();
-
- void lock() {
- mLock.lock();
- }
- void unlock() {
- mLock.unlock();
- }
-
- status_t addEffect_l(const sp<EffectModule>& handle);
- size_t removeEffect_l(const sp<EffectModule>& handle);
-
- int sessionId() const { return mSessionId; }
- void setSessionId(int sessionId) { mSessionId = sessionId; }
-
- sp<EffectModule> getEffectFromDesc_l(effect_descriptor_t *descriptor);
- sp<EffectModule> getEffectFromId_l(int id);
- sp<EffectModule> getEffectFromType_l(const effect_uuid_t *type);
- bool setVolume_l(uint32_t *left, uint32_t *right);
- void setDevice_l(audio_devices_t device);
- void setMode_l(audio_mode_t mode);
- void setAudioSource_l(audio_source_t source);
-
- void setInBuffer(int16_t *buffer, bool ownsBuffer = false) {
- mInBuffer = buffer;
- mOwnInBuffer = ownsBuffer;
- }
- int16_t *inBuffer() const {
- return mInBuffer;
- }
- void setOutBuffer(int16_t *buffer) {
- mOutBuffer = buffer;
- }
- int16_t *outBuffer() const {
- return mOutBuffer;
- }
-
- void incTrackCnt() { android_atomic_inc(&mTrackCnt); }
- void decTrackCnt() { android_atomic_dec(&mTrackCnt); }
- int32_t trackCnt() const { return android_atomic_acquire_load(&mTrackCnt); }
-
- void incActiveTrackCnt() { android_atomic_inc(&mActiveTrackCnt);
- mTailBufferCount = mMaxTailBuffers; }
- void decActiveTrackCnt() { android_atomic_dec(&mActiveTrackCnt); }
- int32_t activeTrackCnt() const { return android_atomic_acquire_load(&mActiveTrackCnt); }
-
- uint32_t strategy() const { return mStrategy; }
- void setStrategy(uint32_t strategy)
- { mStrategy = strategy; }
-
- // suspend effect of the given type
- void setEffectSuspended_l(const effect_uuid_t *type,
- bool suspend);
- // suspend all eligible effects
- void setEffectSuspendedAll_l(bool suspend);
- // check if effects should be suspend or restored when a given effect is enable or disabled
- void checkSuspendOnEffectEnabled(const sp<EffectModule>& effect,
- bool enabled);
-
- void clearInputBuffer();
+ PlaybackThread *checkPlaybackThread_l(audio_io_handle_t output) const;
+ MixerThread *checkMixerThread_l(audio_io_handle_t output) const;
+ RecordThread *checkRecordThread_l(audio_io_handle_t input) const;
+ // no range check, AudioFlinger::mLock held
+ bool streamMute_l(audio_stream_type_t stream) const
+ { return mStreamTypes[stream].mute; }
+ // no range check, doesn't check per-thread stream volume, AudioFlinger::mLock held
+ float streamVolume_l(audio_stream_type_t stream) const
+ { return mStreamTypes[stream].volume; }
+ void audioConfigChanged_l(int event, audio_io_handle_t ioHandle, const void *param2);
- void dump(int fd, const Vector<String16>& args);
+ // allocate an audio_io_handle_t, session ID, or effect ID
+ uint32_t nextUniqueId();
- protected:
- friend class AudioFlinger; // for mThread, mEffects
- EffectChain(const EffectChain&);
- EffectChain& operator =(const EffectChain&);
+ status_t moveEffectChain_l(int sessionId,
+ PlaybackThread *srcThread,
+ PlaybackThread *dstThread,
+ bool reRegister);
+ // return thread associated with primary hardware device, or NULL
+ PlaybackThread *primaryPlaybackThread_l() const;
+ audio_devices_t primaryOutputDevice_l() const;
- class SuspendedEffectDesc : public RefBase {
- public:
- SuspendedEffectDesc() : mRefCount(0) {}
+ sp<PlaybackThread> getEffectThread_l(int sessionId, int EffectId);
- int mRefCount;
- effect_uuid_t mType;
- wp<EffectModule> mEffect;
- };
- // get a list of effect modules to suspend when an effect of the type
- // passed is enabled.
- void getSuspendEligibleEffects(Vector< sp<EffectModule> > &effects);
-
- // get an effect module if it is currently enable
- sp<EffectModule> getEffectIfEnabled(const effect_uuid_t *type);
- // true if the effect whose descriptor is passed can be suspended
- // OEMs can modify the rules implemented in this method to exclude specific effect
- // types or implementations from the suspend/restore mechanism.
- bool isEffectEligibleForSuspend(const effect_descriptor_t& desc);
-
- void clearInputBuffer_l(sp<ThreadBase> thread);
-
- wp<ThreadBase> mThread; // parent mixer thread
- Mutex mLock; // mutex protecting effect list
- Vector< sp<EffectModule> > mEffects; // list of effect modules
- int mSessionId; // audio session ID
- int16_t *mInBuffer; // chain input buffer
- int16_t *mOutBuffer; // chain output buffer
-
- // 'volatile' here means these are accessed with atomic operations instead of mutex
- volatile int32_t mActiveTrackCnt; // number of active tracks connected
- volatile int32_t mTrackCnt; // number of tracks connected
-
- int32_t mTailBufferCount; // current effect tail buffer count
- int32_t mMaxTailBuffers; // maximum effect tail buffers
- bool mOwnInBuffer; // true if the chain owns its input buffer
- int mVolumeCtrlIdx; // index of insert effect having control over volume
- uint32_t mLeftVolume; // previous volume on left channel
- uint32_t mRightVolume; // previous volume on right channel
- uint32_t mNewLeftVolume; // new volume on left channel
- uint32_t mNewRightVolume; // new volume on right channel
- uint32_t mStrategy; // strategy for this effect chain
- // mSuspendedEffects lists all effects currently suspended in the chain.
- // Use effect type UUID timelow field as key. There is no real risk of identical
- // timeLow fields among effect type UUIDs.
- // Updated by updateSuspendedSessions_l() only.
- KeyedVector< int, sp<SuspendedEffectDesc> > mSuspendedEffects;
- };
+ void removeClient_l(pid_t pid);
+ void removeNotificationClient(pid_t pid);
class AudioHwDevice {
public:
@@ -2108,6 +589,7 @@ public:
static void dumpTee(int fd, const sp<NBAIO_Source>& source, audio_io_handle_t id = 0);
};
+#undef INCLUDING_FROM_AUDIOFLINGER_H
// ----------------------------------------------------------------------------