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 #ifdef FLOAT_EFFECT_CHAIN 173 bool mSupportsFloat; // effect supports float processing 174 sp<EffectBufferHalInterface> mInConversionBuffer; // Buffers for HAL conversion if needed. 175 sp<EffectBufferHalInterface> mOutConversionBuffer; 176 uint32_t mInChannelCountRequested; 177 uint32_t mOutChannelCountRequested; 178 #endif 179 }; 180 181 // The EffectHandle class implements the IEffect interface. It provides resources 182 // to receive parameter updates, keeps track of effect control 183 // ownership and state and has a pointer to the EffectModule object it is controlling. 184 // There is one EffectHandle object for each application controlling (or using) 185 // an effect module. 186 // The EffectHandle is obtained by calling AudioFlinger::createEffect(). 187 class EffectHandle: public android::BnEffect { 188 public: 189 190 EffectHandle(const sp<EffectModule>& effect, 191 const sp<AudioFlinger::Client>& client, 192 const sp<IEffectClient>& effectClient, 193 int32_t priority); 194 virtual ~EffectHandle(); 195 virtual status_t initCheck(); 196 197 // IEffect 198 virtual status_t enable(); 199 virtual status_t disable(); 200 virtual status_t command(uint32_t cmdCode, 201 uint32_t cmdSize, 202 void *pCmdData, 203 uint32_t *replySize, 204 void *pReplyData); 205 virtual void disconnect(); 206 private: 207 void disconnect(bool unpinIfLast); 208 public: getCblk()209 virtual sp<IMemory> getCblk() const { return mCblkMemory; } 210 virtual status_t onTransact(uint32_t code, const Parcel& data, 211 Parcel* reply, uint32_t flags); 212 213 214 // Give or take control of effect module 215 // - hasControl: true if control is given, false if removed 216 // - signal: true client app should be signaled of change, false otherwise 217 // - enabled: state of the effect when control is passed 218 void setControl(bool hasControl, bool signal, bool enabled); 219 void commandExecuted(uint32_t cmdCode, 220 uint32_t cmdSize, 221 void *pCmdData, 222 uint32_t replySize, 223 void *pReplyData); 224 void setEnabled(bool enabled); enabled()225 bool enabled() const { return mEnabled; } 226 227 // Getters effect()228 wp<EffectModule> effect() const { return mEffect; } id()229 int id() const { 230 sp<EffectModule> effect = mEffect.promote(); 231 if (effect == 0) { 232 return 0; 233 } 234 return effect->id(); 235 } priority()236 int priority() const { return mPriority; } hasControl()237 bool hasControl() const { return mHasControl; } disconnected()238 bool disconnected() const { return mDisconnected; } 239 240 void dumpToBuffer(char* buffer, size_t size); 241 242 private: 243 friend class AudioFlinger; // for mEffect, mHasControl, mEnabled 244 DISALLOW_COPY_AND_ASSIGN(EffectHandle); 245 246 Mutex mLock; // protects IEffect method calls 247 wp<EffectModule> mEffect; // pointer to controlled EffectModule 248 sp<IEffectClient> mEffectClient; // callback interface for client notifications 249 /*const*/ sp<Client> mClient; // client for shared memory allocation, see disconnect() 250 sp<IMemory> mCblkMemory; // shared memory for control block 251 effect_param_cblk_t* mCblk; // control block for deferred parameter setting via 252 // shared memory 253 uint8_t* mBuffer; // pointer to parameter area in shared memory 254 int mPriority; // client application priority to control the effect 255 bool mHasControl; // true if this handle is controlling the effect 256 bool mEnabled; // cached enable state: needed when the effect is 257 // restored after being suspended 258 bool mDisconnected; // Set to true by disconnect() 259 }; 260 261 // the EffectChain class represents a group of effects associated to one audio session. 262 // There can be any number of EffectChain objects per output mixer thread (PlaybackThread). 263 // The EffectChain with session ID AUDIO_SESSION_OUTPUT_MIX contains global effects applied 264 // to the output mix. 265 // Effects in this chain can be insert or auxiliary. Effects in other chains (attached to 266 // tracks) are insert only. The EffectChain maintains an ordered list of effect module, the 267 // order corresponding in the effect process order. When attached to a track (session ID != 268 // AUDIO_SESSION_OUTPUT_MIX), 269 // it also provide it's own input buffer used by the track as accumulation buffer. 270 class EffectChain : public RefBase { 271 public: 272 EffectChain(const wp<ThreadBase>& wThread, audio_session_t sessionId); 273 EffectChain(ThreadBase *thread, audio_session_t sessionId); 274 virtual ~EffectChain(); 275 276 // special key used for an entry in mSuspendedEffects keyed vector 277 // corresponding to a suspend all request. 278 static const int kKeyForSuspendAll = 0; 279 280 // minimum duration during which we force calling effect process when last track on 281 // a session is stopped or removed to allow effect tail to be rendered 282 static const int kProcessTailDurationMs = 1000; 283 284 void process_l(); 285 lock()286 void lock() { 287 mLock.lock(); 288 } unlock()289 void unlock() { 290 mLock.unlock(); 291 } 292 293 status_t createEffect_l(sp<EffectModule>& effect, 294 ThreadBase *thread, 295 effect_descriptor_t *desc, 296 int id, 297 audio_session_t sessionId, 298 bool pinned); 299 status_t addEffect_l(const sp<EffectModule>& handle); 300 status_t addEffect_ll(const sp<EffectModule>& handle); 301 size_t removeEffect_l(const sp<EffectModule>& handle, bool release = false); 302 sessionId()303 audio_session_t sessionId() const { return mSessionId; } setSessionId(audio_session_t sessionId)304 void setSessionId(audio_session_t sessionId) { mSessionId = sessionId; } 305 306 sp<EffectModule> getEffectFromDesc_l(effect_descriptor_t *descriptor); 307 sp<EffectModule> getEffectFromId_l(int id); 308 sp<EffectModule> getEffectFromType_l(const effect_uuid_t *type); 309 // FIXME use float to improve the dynamic range 310 bool setVolume_l(uint32_t *left, uint32_t *right, bool force = false); 311 void resetVolume_l(); 312 void setDevice_l(audio_devices_t device); 313 void setMode_l(audio_mode_t mode); 314 void setAudioSource_l(audio_source_t source); 315 setInBuffer(const sp<EffectBufferHalInterface> & buffer)316 void setInBuffer(const sp<EffectBufferHalInterface>& buffer) { 317 mInBuffer = buffer; 318 } inBuffer()319 effect_buffer_t *inBuffer() const { 320 return mInBuffer != 0 ? reinterpret_cast<effect_buffer_t*>(mInBuffer->ptr()) : NULL; 321 } setOutBuffer(const sp<EffectBufferHalInterface> & buffer)322 void setOutBuffer(const sp<EffectBufferHalInterface>& buffer) { 323 mOutBuffer = buffer; 324 } outBuffer()325 effect_buffer_t *outBuffer() const { 326 return mOutBuffer != 0 ? reinterpret_cast<effect_buffer_t*>(mOutBuffer->ptr()) : NULL; 327 } 328 incTrackCnt()329 void incTrackCnt() { android_atomic_inc(&mTrackCnt); } decTrackCnt()330 void decTrackCnt() { android_atomic_dec(&mTrackCnt); } trackCnt()331 int32_t trackCnt() const { return android_atomic_acquire_load(&mTrackCnt); } 332 incActiveTrackCnt()333 void incActiveTrackCnt() { android_atomic_inc(&mActiveTrackCnt); 334 mTailBufferCount = mMaxTailBuffers; } decActiveTrackCnt()335 void decActiveTrackCnt() { android_atomic_dec(&mActiveTrackCnt); } activeTrackCnt()336 int32_t activeTrackCnt() const { return android_atomic_acquire_load(&mActiveTrackCnt); } 337 strategy()338 uint32_t strategy() const { return mStrategy; } setStrategy(uint32_t strategy)339 void setStrategy(uint32_t strategy) 340 { mStrategy = strategy; } 341 342 // suspend or restore effects of the specified type. The number of suspend requests is counted 343 // and restore occurs once all suspend requests are cancelled. 344 void setEffectSuspended_l(const effect_uuid_t *type, 345 bool suspend); 346 // suspend all eligible effects 347 void setEffectSuspendedAll_l(bool suspend); 348 // check if effects should be suspend or restored when a given effect is enable or disabled 349 void checkSuspendOnEffectEnabled(const sp<EffectModule>& effect, 350 bool enabled); 351 352 void clearInputBuffer(); 353 354 // At least one non offloadable effect in the chain is enabled 355 bool isNonOffloadableEnabled(); 356 357 void syncHalEffectsState(); 358 359 // flags is an ORed set of audio_output_flags_t which is updated on return. 360 void checkOutputFlagCompatibility(audio_output_flags_t *flags) const; 361 362 // flags is an ORed set of audio_input_flags_t which is updated on return. 363 void checkInputFlagCompatibility(audio_input_flags_t *flags) const; 364 365 // Is this EffectChain compatible with the RAW audio flag. 366 bool isRawCompatible() const; 367 368 // Is this EffectChain compatible with the FAST audio flag. 369 bool isFastCompatible() const; 370 371 // isCompatibleWithThread_l() must be called with thread->mLock held 372 bool isCompatibleWithThread_l(const sp<ThreadBase>& thread) const; 373 374 void dump(int fd, const Vector<String16>& args); 375 376 private: 377 friend class AudioFlinger; // for mThread, mEffects 378 DISALLOW_COPY_AND_ASSIGN(EffectChain); 379 380 class SuspendedEffectDesc : public RefBase { 381 public: SuspendedEffectDesc()382 SuspendedEffectDesc() : mRefCount(0) {} 383 384 int mRefCount; // > 0 when suspended 385 effect_uuid_t mType; 386 wp<EffectModule> mEffect; 387 }; 388 389 // get a list of effect modules to suspend when an effect of the type 390 // passed is enabled. 391 void getSuspendEligibleEffects(Vector< sp<EffectModule> > &effects); 392 393 // get an effect module if it is currently enable 394 sp<EffectModule> getEffectIfEnabled(const effect_uuid_t *type); 395 // true if the effect whose descriptor is passed can be suspended 396 // OEMs can modify the rules implemented in this method to exclude specific effect 397 // types or implementations from the suspend/restore mechanism. 398 bool isEffectEligibleForSuspend(const effect_descriptor_t& desc); 399 400 static bool isEffectEligibleForBtNrecSuspend(const effect_uuid_t *type); 401 402 void clearInputBuffer_l(const sp<ThreadBase>& thread); 403 404 void setThread(const sp<ThreadBase>& thread); 405 406 wp<ThreadBase> mThread; // parent mixer thread 407 mutable Mutex mLock; // mutex protecting effect list 408 Vector< sp<EffectModule> > mEffects; // list of effect modules 409 audio_session_t mSessionId; // audio session ID 410 sp<EffectBufferHalInterface> mInBuffer; // chain input buffer 411 sp<EffectBufferHalInterface> mOutBuffer; // chain output buffer 412 413 // 'volatile' here means these are accessed with atomic operations instead of mutex 414 volatile int32_t mActiveTrackCnt; // number of active tracks connected 415 volatile int32_t mTrackCnt; // number of tracks connected 416 417 int32_t mTailBufferCount; // current effect tail buffer count 418 int32_t mMaxTailBuffers; // maximum effect tail buffers 419 int mVolumeCtrlIdx; // index of insert effect having control over volume 420 uint32_t mLeftVolume; // previous volume on left channel 421 uint32_t mRightVolume; // previous volume on right channel 422 uint32_t mNewLeftVolume; // new volume on left channel 423 uint32_t mNewRightVolume; // new volume on right channel 424 uint32_t mStrategy; // strategy for this effect chain 425 // mSuspendedEffects lists all effects currently suspended in the chain. 426 // Use effect type UUID timelow field as key. There is no real risk of identical 427 // timeLow fields among effect type UUIDs. 428 // Updated by setEffectSuspended_l() and setEffectSuspendedAll_l() only. 429 KeyedVector< int, sp<SuspendedEffectDesc> > mSuspendedEffects; 430 }; 431