1 /* 2 ** 3 ** Copyright 2012, The Android Open Source Project 4 ** 5 ** Licensed under the Apache License, Version 2.0 (the "License"); 6 ** you may not use this file except in compliance with the License. 7 ** You may obtain a copy of the License at 8 ** 9 ** http://www.apache.org/licenses/LICENSE-2.0 10 ** 11 ** Unless required by applicable law or agreed to in writing, software 12 ** distributed under the License is distributed on an "AS IS" BASIS, 13 ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 ** See the License for the specific language governing permissions and 15 ** limitations under the License. 16 */ 17 18 #ifndef INCLUDING_FROM_AUDIOFLINGER_H 19 #error This header file should only be included from AudioFlinger.h 20 #endif 21 22 //--- Audio Effect Management 23 24 // EffectModule and EffectChain classes both have their own mutex to protect 25 // state changes or resource modifications. Always respect the following order 26 // if multiple mutexes must be acquired to avoid cross deadlock: 27 // AudioFlinger -> ThreadBase -> EffectChain -> EffectModule 28 // AudioHandle -> ThreadBase -> EffectChain -> EffectModule 29 // In addition, methods that lock the AudioPolicyService mutex (getOutputForEffect(), 30 // startOutput(), getInputForAttr(), releaseInput()...) should never be called with AudioFlinger or 31 // Threadbase mutex locked to avoid cross deadlock with other clients calling AudioPolicyService 32 // methods that in turn call AudioFlinger thus locking the same mutexes in the reverse order. 33 34 // The EffectModule class is a wrapper object controlling the effect engine implementation 35 // in the effect library. It prevents concurrent calls to process() and command() functions 36 // from different client threads. It keeps a list of EffectHandle objects corresponding 37 // to all client applications using this effect and notifies applications of effect state, 38 // control or parameter changes. It manages the activation state machine to send appropriate 39 // reset, enable, disable commands to effect engine and provide volume 40 // ramping when effects are activated/deactivated. 41 // When controlling an auxiliary effect, the EffectModule also provides an input buffer used by 42 // the attached track(s) to accumulate their auxiliary channel. 43 class EffectModule : public RefBase { 44 public: 45 EffectModule(ThreadBase *thread, 46 const wp<AudioFlinger::EffectChain>& chain, 47 effect_descriptor_t *desc, 48 int id, 49 audio_session_t sessionId, 50 bool pinned); 51 virtual ~EffectModule(); 52 53 enum effect_state { 54 IDLE, 55 RESTART, 56 STARTING, 57 ACTIVE, 58 STOPPING, 59 STOPPED, 60 DESTROYED 61 }; 62 id()63 int id() const { return mId; } 64 void process(); 65 bool updateState(); 66 status_t command(uint32_t cmdCode, 67 uint32_t cmdSize, 68 void *pCmdData, 69 uint32_t *replySize, 70 void *pReplyData); 71 72 void reset_l(); 73 status_t configure(); 74 status_t init(); state()75 effect_state state() const { 76 return mState; 77 } status()78 uint32_t status() { 79 return mStatus; 80 } sessionId()81 audio_session_t sessionId() const { 82 return mSessionId; 83 } 84 status_t setEnabled(bool enabled); 85 status_t setEnabled_l(bool enabled); 86 bool isEnabled() const; 87 bool isProcessEnabled() const; 88 89 void setInBuffer(const sp<EffectBufferHalInterface>& buffer); inBuffer()90 int16_t *inBuffer() const { 91 return mInBuffer != 0 ? reinterpret_cast<int16_t*>(mInBuffer->ptr()) : NULL; 92 } 93 void setOutBuffer(const sp<EffectBufferHalInterface>& buffer); outBuffer()94 int16_t *outBuffer() const { 95 return mOutBuffer != 0 ? reinterpret_cast<int16_t*>(mOutBuffer->ptr()) : NULL; 96 } setChain(const wp<EffectChain> & chain)97 void setChain(const wp<EffectChain>& chain) { mChain = chain; } setThread(const wp<ThreadBase> & thread)98 void setThread(const wp<ThreadBase>& thread) { mThread = thread; } thread()99 const wp<ThreadBase>& thread() { return mThread; } 100 101 status_t addHandle(EffectHandle *handle); 102 ssize_t disconnectHandle(EffectHandle *handle, bool unpinIfLast); 103 ssize_t removeHandle(EffectHandle *handle); 104 ssize_t removeHandle_l(EffectHandle *handle); 105 desc()106 const effect_descriptor_t& desc() const { return mDescriptor; } chain()107 wp<EffectChain>& chain() { return mChain; } 108 109 status_t setDevice(audio_devices_t device); 110 status_t setVolume(uint32_t *left, uint32_t *right, bool controller); 111 status_t setMode(audio_mode_t mode); 112 status_t setAudioSource(audio_source_t source); 113 status_t start(); 114 status_t stop(); 115 void setSuspended(bool suspended); 116 bool suspended() const; 117 118 EffectHandle* controlHandle_l(); 119 isPinned()120 bool isPinned() const { return mPinned; } unPin()121 void unPin() { mPinned = false; } 122 bool purgeHandles(); lock()123 void lock() { mLock.lock(); } unlock()124 void unlock() { mLock.unlock(); } isOffloadable()125 bool isOffloadable() const 126 { return (mDescriptor.flags & EFFECT_FLAG_OFFLOAD_SUPPORTED) != 0; } isImplementationSoftware()127 bool isImplementationSoftware() const 128 { return (mDescriptor.flags & EFFECT_FLAG_HW_ACC_MASK) == 0; } isProcessImplemented()129 bool isProcessImplemented() const 130 { return (mDescriptor.flags & EFFECT_FLAG_NO_PROCESS) == 0; } 131 status_t setOffloaded(bool offloaded, audio_io_handle_t io); 132 bool isOffloaded() const; 133 void addEffectToHal_l(); 134 void release_l(); 135 136 void dump(int fd, const Vector<String16>& args); 137 138 private: 139 friend class AudioFlinger; // for mHandles 140 bool mPinned; 141 142 // Maximum time allocated to effect engines to complete the turn off sequence 143 static const uint32_t MAX_DISABLE_TIME_MS = 10000; 144 145 DISALLOW_COPY_AND_ASSIGN(EffectModule); 146 147 status_t start_l(); 148 status_t stop_l(); 149 status_t remove_effect_from_hal_l(); 150 151 mutable Mutex mLock; // mutex for process, commands and handles list protection 152 wp<ThreadBase> mThread; // parent thread 153 wp<EffectChain> mChain; // parent effect chain 154 const int mId; // this instance unique ID 155 const audio_session_t mSessionId; // audio session ID 156 const effect_descriptor_t mDescriptor;// effect descriptor received from effect engine 157 effect_config_t mConfig; // input and output audio configuration 158 sp<EffectHalInterface> mEffectInterface; // Effect module HAL 159 sp<EffectBufferHalInterface> mInBuffer; // Buffers for interacting with HAL 160 sp<EffectBufferHalInterface> mOutBuffer; 161 status_t mStatus; // initialization status 162 effect_state mState; // current activation state 163 Vector<EffectHandle *> mHandles; // list of client handles 164 // First handle in mHandles has highest priority and controls the effect module 165 uint32_t mMaxDisableWaitCnt; // maximum grace period before forcing an effect off after 166 // sending disable command. 167 uint32_t mDisableWaitCnt; // current process() calls count during disable period. 168 bool mSuspended; // effect is suspended: temporarily disabled by framework 169 bool mOffloaded; // effect is currently offloaded to the audio DSP 170 wp<AudioFlinger> mAudioFlinger; 171 }; 172 173 // The EffectHandle class implements the IEffect interface. It provides resources 174 // to receive parameter updates, keeps track of effect control 175 // ownership and state and has a pointer to the EffectModule object it is controlling. 176 // There is one EffectHandle object for each application controlling (or using) 177 // an effect module. 178 // The EffectHandle is obtained by calling AudioFlinger::createEffect(). 179 class EffectHandle: public android::BnEffect { 180 public: 181 182 EffectHandle(const sp<EffectModule>& effect, 183 const sp<AudioFlinger::Client>& client, 184 const sp<IEffectClient>& effectClient, 185 int32_t priority); 186 virtual ~EffectHandle(); 187 virtual status_t initCheck(); 188 189 // IEffect 190 virtual status_t enable(); 191 virtual status_t disable(); 192 virtual status_t command(uint32_t cmdCode, 193 uint32_t cmdSize, 194 void *pCmdData, 195 uint32_t *replySize, 196 void *pReplyData); 197 virtual void disconnect(); 198 private: 199 void disconnect(bool unpinIfLast); 200 public: getCblk()201 virtual sp<IMemory> getCblk() const { return mCblkMemory; } 202 virtual status_t onTransact(uint32_t code, const Parcel& data, 203 Parcel* reply, uint32_t flags); 204 205 206 // Give or take control of effect module 207 // - hasControl: true if control is given, false if removed 208 // - signal: true client app should be signaled of change, false otherwise 209 // - enabled: state of the effect when control is passed 210 void setControl(bool hasControl, bool signal, bool enabled); 211 void commandExecuted(uint32_t cmdCode, 212 uint32_t cmdSize, 213 void *pCmdData, 214 uint32_t replySize, 215 void *pReplyData); 216 void setEnabled(bool enabled); enabled()217 bool enabled() const { return mEnabled; } 218 219 // Getters effect()220 wp<EffectModule> effect() const { return mEffect; } id()221 int id() const { 222 sp<EffectModule> effect = mEffect.promote(); 223 if (effect == 0) { 224 return 0; 225 } 226 return effect->id(); 227 } priority()228 int priority() const { return mPriority; } hasControl()229 bool hasControl() const { return mHasControl; } disconnected()230 bool disconnected() const { return mDisconnected; } 231 232 void dumpToBuffer(char* buffer, size_t size); 233 234 private: 235 friend class AudioFlinger; // for mEffect, mHasControl, mEnabled 236 DISALLOW_COPY_AND_ASSIGN(EffectHandle); 237 238 Mutex mLock; // protects IEffect method calls 239 wp<EffectModule> mEffect; // pointer to controlled EffectModule 240 sp<IEffectClient> mEffectClient; // callback interface for client notifications 241 /*const*/ sp<Client> mClient; // client for shared memory allocation, see disconnect() 242 sp<IMemory> mCblkMemory; // shared memory for control block 243 effect_param_cblk_t* mCblk; // control block for deferred parameter setting via 244 // shared memory 245 uint8_t* mBuffer; // pointer to parameter area in shared memory 246 int mPriority; // client application priority to control the effect 247 bool mHasControl; // true if this handle is controlling the effect 248 bool mEnabled; // cached enable state: needed when the effect is 249 // restored after being suspended 250 bool mDisconnected; // Set to true by disconnect() 251 }; 252 253 // the EffectChain class represents a group of effects associated to one audio session. 254 // There can be any number of EffectChain objects per output mixer thread (PlaybackThread). 255 // The EffectChain with session ID AUDIO_SESSION_OUTPUT_MIX contains global effects applied 256 // to the output mix. 257 // Effects in this chain can be insert or auxiliary. Effects in other chains (attached to 258 // tracks) are insert only. The EffectChain maintains an ordered list of effect module, the 259 // order corresponding in the effect process order. When attached to a track (session ID != 260 // AUDIO_SESSION_OUTPUT_MIX), 261 // it also provide it's own input buffer used by the track as accumulation buffer. 262 class EffectChain : public RefBase { 263 public: 264 EffectChain(const wp<ThreadBase>& wThread, audio_session_t sessionId); 265 EffectChain(ThreadBase *thread, audio_session_t sessionId); 266 virtual ~EffectChain(); 267 268 // special key used for an entry in mSuspendedEffects keyed vector 269 // corresponding to a suspend all request. 270 static const int kKeyForSuspendAll = 0; 271 272 // minimum duration during which we force calling effect process when last track on 273 // a session is stopped or removed to allow effect tail to be rendered 274 static const int kProcessTailDurationMs = 1000; 275 276 void process_l(); 277 lock()278 void lock() { 279 mLock.lock(); 280 } unlock()281 void unlock() { 282 mLock.unlock(); 283 } 284 285 status_t createEffect_l(sp<EffectModule>& effect, 286 ThreadBase *thread, 287 effect_descriptor_t *desc, 288 int id, 289 audio_session_t sessionId, 290 bool pinned); 291 status_t addEffect_l(const sp<EffectModule>& handle); 292 status_t addEffect_ll(const sp<EffectModule>& handle); 293 size_t removeEffect_l(const sp<EffectModule>& handle, bool release = false); 294 sessionId()295 audio_session_t sessionId() const { return mSessionId; } setSessionId(audio_session_t sessionId)296 void setSessionId(audio_session_t sessionId) { mSessionId = sessionId; } 297 298 sp<EffectModule> getEffectFromDesc_l(effect_descriptor_t *descriptor); 299 sp<EffectModule> getEffectFromId_l(int id); 300 sp<EffectModule> getEffectFromType_l(const effect_uuid_t *type); 301 // FIXME use float to improve the dynamic range 302 bool setVolume_l(uint32_t *left, uint32_t *right, bool force = false); 303 void resetVolume_l(); 304 void setDevice_l(audio_devices_t device); 305 void setMode_l(audio_mode_t mode); 306 void setAudioSource_l(audio_source_t source); 307 setInBuffer(const sp<EffectBufferHalInterface> & buffer)308 void setInBuffer(const sp<EffectBufferHalInterface>& buffer) { 309 mInBuffer = buffer; 310 } inBuffer()311 int16_t *inBuffer() const { 312 return mInBuffer != 0 ? reinterpret_cast<int16_t*>(mInBuffer->ptr()) : NULL; 313 } setOutBuffer(const sp<EffectBufferHalInterface> & buffer)314 void setOutBuffer(const sp<EffectBufferHalInterface>& buffer) { 315 mOutBuffer = buffer; 316 } outBuffer()317 int16_t *outBuffer() const { 318 return mOutBuffer != 0 ? reinterpret_cast<int16_t*>(mOutBuffer->ptr()) : NULL; 319 } 320 incTrackCnt()321 void incTrackCnt() { android_atomic_inc(&mTrackCnt); } decTrackCnt()322 void decTrackCnt() { android_atomic_dec(&mTrackCnt); } trackCnt()323 int32_t trackCnt() const { return android_atomic_acquire_load(&mTrackCnt); } 324 incActiveTrackCnt()325 void incActiveTrackCnt() { android_atomic_inc(&mActiveTrackCnt); 326 mTailBufferCount = mMaxTailBuffers; } decActiveTrackCnt()327 void decActiveTrackCnt() { android_atomic_dec(&mActiveTrackCnt); } activeTrackCnt()328 int32_t activeTrackCnt() const { return android_atomic_acquire_load(&mActiveTrackCnt); } 329 strategy()330 uint32_t strategy() const { return mStrategy; } setStrategy(uint32_t strategy)331 void setStrategy(uint32_t strategy) 332 { mStrategy = strategy; } 333 334 // suspend or restore effects of the specified type. The number of suspend requests is counted 335 // and restore occurs once all suspend requests are cancelled. 336 void setEffectSuspended_l(const effect_uuid_t *type, 337 bool suspend); 338 // suspend all eligible effects 339 void setEffectSuspendedAll_l(bool suspend); 340 // check if effects should be suspend or restored when a given effect is enable or disabled 341 void checkSuspendOnEffectEnabled(const sp<EffectModule>& effect, 342 bool enabled); 343 344 void clearInputBuffer(); 345 346 // At least one non offloadable effect in the chain is enabled 347 bool isNonOffloadableEnabled(); 348 349 void syncHalEffectsState(); 350 351 // flags is an ORed set of audio_output_flags_t which is updated on return. 352 void checkOutputFlagCompatibility(audio_output_flags_t *flags) const; 353 354 // flags is an ORed set of audio_input_flags_t which is updated on return. 355 void checkInputFlagCompatibility(audio_input_flags_t *flags) const; 356 357 // Is this EffectChain compatible with the RAW audio flag. 358 bool isRawCompatible() const; 359 360 // Is this EffectChain compatible with the FAST audio flag. 361 bool isFastCompatible() const; 362 363 // isCompatibleWithThread_l() must be called with thread->mLock held 364 bool isCompatibleWithThread_l(const sp<ThreadBase>& thread) const; 365 366 void dump(int fd, const Vector<String16>& args); 367 368 private: 369 friend class AudioFlinger; // for mThread, mEffects 370 DISALLOW_COPY_AND_ASSIGN(EffectChain); 371 372 class SuspendedEffectDesc : public RefBase { 373 public: SuspendedEffectDesc()374 SuspendedEffectDesc() : mRefCount(0) {} 375 376 int mRefCount; // > 0 when suspended 377 effect_uuid_t mType; 378 wp<EffectModule> mEffect; 379 }; 380 381 // get a list of effect modules to suspend when an effect of the type 382 // passed is enabled. 383 void getSuspendEligibleEffects(Vector< sp<EffectModule> > &effects); 384 385 // get an effect module if it is currently enable 386 sp<EffectModule> getEffectIfEnabled(const effect_uuid_t *type); 387 // true if the effect whose descriptor is passed can be suspended 388 // OEMs can modify the rules implemented in this method to exclude specific effect 389 // types or implementations from the suspend/restore mechanism. 390 bool isEffectEligibleForSuspend(const effect_descriptor_t& desc); 391 392 static bool isEffectEligibleForBtNrecSuspend(const effect_uuid_t *type); 393 394 void clearInputBuffer_l(const sp<ThreadBase>& thread); 395 396 void setThread(const sp<ThreadBase>& thread); 397 398 wp<ThreadBase> mThread; // parent mixer thread 399 mutable Mutex mLock; // mutex protecting effect list 400 Vector< sp<EffectModule> > mEffects; // list of effect modules 401 audio_session_t mSessionId; // audio session ID 402 sp<EffectBufferHalInterface> mInBuffer; // chain input buffer 403 sp<EffectBufferHalInterface> mOutBuffer; // chain output buffer 404 405 // 'volatile' here means these are accessed with atomic operations instead of mutex 406 volatile int32_t mActiveTrackCnt; // number of active tracks connected 407 volatile int32_t mTrackCnt; // number of tracks connected 408 409 int32_t mTailBufferCount; // current effect tail buffer count 410 int32_t mMaxTailBuffers; // maximum effect tail buffers 411 int mVolumeCtrlIdx; // index of insert effect having control over volume 412 uint32_t mLeftVolume; // previous volume on left channel 413 uint32_t mRightVolume; // previous volume on right channel 414 uint32_t mNewLeftVolume; // new volume on left channel 415 uint32_t mNewRightVolume; // new volume on right channel 416 uint32_t mStrategy; // strategy for this effect chain 417 // mSuspendedEffects lists all effects currently suspended in the chain. 418 // Use effect type UUID timelow field as key. There is no real risk of identical 419 // timeLow fields among effect type UUIDs. 420 // Updated by setEffectSuspended_l() and setEffectSuspendedAll_l() only. 421 KeyedVector< int, sp<SuspendedEffectDesc> > mSuspendedEffects; 422 }; 423