Effects.cpp revision 377b2ec9a2885f9b6405b07ba900a9e3f4349c38
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
19#define LOG_TAG "AudioFlinger"
20//#define LOG_NDEBUG 0
21
22#include "Configuration.h"
23#include <utils/Log.h>
24#include <audio_effects/effect_visualizer.h>
25#include <audio_utils/primitives.h>
26#include <private/media/AudioEffectShared.h>
27#include <media/EffectsFactoryApi.h>
28
29#include "AudioFlinger.h"
30#include "ServiceUtilities.h"
31
32// ----------------------------------------------------------------------------
33
34// Note: the following macro is used for extremely verbose logging message.  In
35// order to run with ALOG_ASSERT turned on, we need to have LOG_NDEBUG set to
36// 0; but one side effect of this is to turn all LOGV's as well.  Some messages
37// are so verbose that we want to suppress them even when we have ALOG_ASSERT
38// turned on.  Do not uncomment the #def below unless you really know what you
39// are doing and want to see all of the extremely verbose messages.
40//#define VERY_VERY_VERBOSE_LOGGING
41#ifdef VERY_VERY_VERBOSE_LOGGING
42#define ALOGVV ALOGV
43#else
44#define ALOGVV(a...) do { } while(0)
45#endif
46
47namespace android {
48
49// ----------------------------------------------------------------------------
50//  EffectModule implementation
51// ----------------------------------------------------------------------------
52
53#undef LOG_TAG
54#define LOG_TAG "AudioFlinger::EffectModule"
55
56AudioFlinger::EffectModule::EffectModule(ThreadBase *thread,
57                                        const wp<AudioFlinger::EffectChain>& chain,
58                                        effect_descriptor_t *desc,
59                                        int id,
60                                        int sessionId)
61    : mPinned(sessionId > AUDIO_SESSION_OUTPUT_MIX),
62      mThread(thread), mChain(chain), mId(id), mSessionId(sessionId),
63      mDescriptor(*desc),
64      // mConfig is set by configure() and not used before then
65      mEffectInterface(NULL),
66      mStatus(NO_INIT), mState(IDLE),
67      // mMaxDisableWaitCnt is set by configure() and not used before then
68      // mDisableWaitCnt is set by process() and updateState() and not used before then
69      mSuspended(false)
70{
71    ALOGV("Constructor %p", this);
72    int lStatus;
73
74    // create effect engine from effect factory
75    mStatus = EffectCreate(&desc->uuid, sessionId, thread->id(), &mEffectInterface);
76
77    if (mStatus != NO_ERROR) {
78        return;
79    }
80    lStatus = init();
81    if (lStatus < 0) {
82        mStatus = lStatus;
83        goto Error;
84    }
85
86    ALOGV("Constructor success name %s, Interface %p", mDescriptor.name, mEffectInterface);
87    return;
88Error:
89    EffectRelease(mEffectInterface);
90    mEffectInterface = NULL;
91    ALOGV("Constructor Error %d", mStatus);
92}
93
94AudioFlinger::EffectModule::~EffectModule()
95{
96    ALOGV("Destructor %p", this);
97    if (mEffectInterface != NULL) {
98        remove_effect_from_hal_l();
99        // release effect engine
100        EffectRelease(mEffectInterface);
101    }
102}
103
104status_t AudioFlinger::EffectModule::addHandle(EffectHandle *handle)
105{
106    status_t status;
107
108    Mutex::Autolock _l(mLock);
109    int priority = handle->priority();
110    size_t size = mHandles.size();
111    EffectHandle *controlHandle = NULL;
112    size_t i;
113    for (i = 0; i < size; i++) {
114        EffectHandle *h = mHandles[i];
115        if (h == NULL || h->destroyed_l()) {
116            continue;
117        }
118        // first non destroyed handle is considered in control
119        if (controlHandle == NULL)
120            controlHandle = h;
121        if (h->priority() <= priority) {
122            break;
123        }
124    }
125    // if inserted in first place, move effect control from previous owner to this handle
126    if (i == 0) {
127        bool enabled = false;
128        if (controlHandle != NULL) {
129            enabled = controlHandle->enabled();
130            controlHandle->setControl(false/*hasControl*/, true /*signal*/, enabled /*enabled*/);
131        }
132        handle->setControl(true /*hasControl*/, false /*signal*/, enabled /*enabled*/);
133        status = NO_ERROR;
134    } else {
135        status = ALREADY_EXISTS;
136    }
137    ALOGV("addHandle() %p added handle %p in position %d", this, handle, i);
138    mHandles.insertAt(handle, i);
139    return status;
140}
141
142size_t AudioFlinger::EffectModule::removeHandle(EffectHandle *handle)
143{
144    Mutex::Autolock _l(mLock);
145    size_t size = mHandles.size();
146    size_t i;
147    for (i = 0; i < size; i++) {
148        if (mHandles[i] == handle) {
149            break;
150        }
151    }
152    if (i == size) {
153        return size;
154    }
155    ALOGV("removeHandle() %p removed handle %p in position %d", this, handle, i);
156
157    mHandles.removeAt(i);
158    // if removed from first place, move effect control from this handle to next in line
159    if (i == 0) {
160        EffectHandle *h = controlHandle_l();
161        if (h != NULL) {
162            h->setControl(true /*hasControl*/, true /*signal*/ , handle->enabled() /*enabled*/);
163        }
164    }
165
166    // Prevent calls to process() and other functions on effect interface from now on.
167    // The effect engine will be released by the destructor when the last strong reference on
168    // this object is released which can happen after next process is called.
169    if (mHandles.size() == 0 && !mPinned) {
170        mState = DESTROYED;
171    }
172
173    return mHandles.size();
174}
175
176// must be called with EffectModule::mLock held
177AudioFlinger::EffectHandle *AudioFlinger::EffectModule::controlHandle_l()
178{
179    // the first valid handle in the list has control over the module
180    for (size_t i = 0; i < mHandles.size(); i++) {
181        EffectHandle *h = mHandles[i];
182        if (h != NULL && !h->destroyed_l()) {
183            return h;
184        }
185    }
186
187    return NULL;
188}
189
190size_t AudioFlinger::EffectModule::disconnect(EffectHandle *handle, bool unpinIfLast)
191{
192    ALOGV("disconnect() %p handle %p", this, handle);
193    // keep a strong reference on this EffectModule to avoid calling the
194    // destructor before we exit
195    sp<EffectModule> keep(this);
196    {
197        sp<ThreadBase> thread = mThread.promote();
198        if (thread != 0) {
199            thread->disconnectEffect(keep, handle, unpinIfLast);
200        }
201    }
202    return mHandles.size();
203}
204
205void AudioFlinger::EffectModule::updateState() {
206    Mutex::Autolock _l(mLock);
207
208    switch (mState) {
209    case RESTART:
210        reset_l();
211        // FALL THROUGH
212
213    case STARTING:
214        // clear auxiliary effect input buffer for next accumulation
215        if ((mDescriptor.flags & EFFECT_FLAG_TYPE_MASK) == EFFECT_FLAG_TYPE_AUXILIARY) {
216            memset(mConfig.inputCfg.buffer.raw,
217                   0,
218                   mConfig.inputCfg.buffer.frameCount*sizeof(int32_t));
219        }
220        if (start_l() == NO_ERROR) {
221            mState = ACTIVE;
222        } else {
223            mState = IDLE;
224        }
225        break;
226    case STOPPING:
227        if (stop_l() == NO_ERROR) {
228            mDisableWaitCnt = mMaxDisableWaitCnt;
229        } else {
230            mDisableWaitCnt = 1; // will cause immediate transition to IDLE
231        }
232        mState = STOPPED;
233        break;
234    case STOPPED:
235        // mDisableWaitCnt is forced to 1 by process() when the engine indicates the end of the
236        // turn off sequence.
237        if (--mDisableWaitCnt == 0) {
238            reset_l();
239            mState = IDLE;
240        }
241        break;
242    default: //IDLE , ACTIVE, DESTROYED
243        break;
244    }
245}
246
247void AudioFlinger::EffectModule::process()
248{
249    Mutex::Autolock _l(mLock);
250
251    if (mState == DESTROYED || mEffectInterface == NULL ||
252            mConfig.inputCfg.buffer.raw == NULL ||
253            mConfig.outputCfg.buffer.raw == NULL) {
254        return;
255    }
256
257    if (isProcessEnabled()) {
258        // do 32 bit to 16 bit conversion for auxiliary effect input buffer
259        if ((mDescriptor.flags & EFFECT_FLAG_TYPE_MASK) == EFFECT_FLAG_TYPE_AUXILIARY) {
260            ditherAndClamp(mConfig.inputCfg.buffer.s32,
261                                        mConfig.inputCfg.buffer.s32,
262                                        mConfig.inputCfg.buffer.frameCount/2);
263        }
264
265        // do the actual processing in the effect engine
266        int ret = (*mEffectInterface)->process(mEffectInterface,
267                                               &mConfig.inputCfg.buffer,
268                                               &mConfig.outputCfg.buffer);
269
270        // force transition to IDLE state when engine is ready
271        if (mState == STOPPED && ret == -ENODATA) {
272            mDisableWaitCnt = 1;
273        }
274
275        // clear auxiliary effect input buffer for next accumulation
276        if ((mDescriptor.flags & EFFECT_FLAG_TYPE_MASK) == EFFECT_FLAG_TYPE_AUXILIARY) {
277            memset(mConfig.inputCfg.buffer.raw, 0,
278                   mConfig.inputCfg.buffer.frameCount*sizeof(int32_t));
279        }
280    } else if ((mDescriptor.flags & EFFECT_FLAG_TYPE_MASK) == EFFECT_FLAG_TYPE_INSERT &&
281                mConfig.inputCfg.buffer.raw != mConfig.outputCfg.buffer.raw) {
282        // If an insert effect is idle and input buffer is different from output buffer,
283        // accumulate input onto output
284        sp<EffectChain> chain = mChain.promote();
285        if (chain != 0 && chain->activeTrackCnt() != 0) {
286            size_t frameCnt = mConfig.inputCfg.buffer.frameCount * 2;  //always stereo here
287            int16_t *in = mConfig.inputCfg.buffer.s16;
288            int16_t *out = mConfig.outputCfg.buffer.s16;
289            for (size_t i = 0; i < frameCnt; i++) {
290                out[i] = clamp16((int32_t)out[i] + (int32_t)in[i]);
291            }
292        }
293    }
294}
295
296void AudioFlinger::EffectModule::reset_l()
297{
298    if (mStatus != NO_ERROR || mEffectInterface == NULL) {
299        return;
300    }
301    (*mEffectInterface)->command(mEffectInterface, EFFECT_CMD_RESET, 0, NULL, 0, NULL);
302}
303
304status_t AudioFlinger::EffectModule::configure()
305{
306    status_t status;
307    sp<ThreadBase> thread;
308    uint32_t size;
309    audio_channel_mask_t channelMask;
310
311    if (mEffectInterface == NULL) {
312        status = NO_INIT;
313        goto exit;
314    }
315
316    thread = mThread.promote();
317    if (thread == 0) {
318        status = DEAD_OBJECT;
319        goto exit;
320    }
321
322    // TODO: handle configuration of effects replacing track process
323    channelMask = thread->channelMask();
324
325    if ((mDescriptor.flags & EFFECT_FLAG_TYPE_MASK) == EFFECT_FLAG_TYPE_AUXILIARY) {
326        mConfig.inputCfg.channels = AUDIO_CHANNEL_OUT_MONO;
327    } else {
328        mConfig.inputCfg.channels = channelMask;
329    }
330    mConfig.outputCfg.channels = channelMask;
331    mConfig.inputCfg.format = AUDIO_FORMAT_PCM_16_BIT;
332    mConfig.outputCfg.format = AUDIO_FORMAT_PCM_16_BIT;
333    mConfig.inputCfg.samplingRate = thread->sampleRate();
334    mConfig.outputCfg.samplingRate = mConfig.inputCfg.samplingRate;
335    mConfig.inputCfg.bufferProvider.cookie = NULL;
336    mConfig.inputCfg.bufferProvider.getBuffer = NULL;
337    mConfig.inputCfg.bufferProvider.releaseBuffer = NULL;
338    mConfig.outputCfg.bufferProvider.cookie = NULL;
339    mConfig.outputCfg.bufferProvider.getBuffer = NULL;
340    mConfig.outputCfg.bufferProvider.releaseBuffer = NULL;
341    mConfig.inputCfg.accessMode = EFFECT_BUFFER_ACCESS_READ;
342    // Insert effect:
343    // - in session AUDIO_SESSION_OUTPUT_MIX or AUDIO_SESSION_OUTPUT_STAGE,
344    // always overwrites output buffer: input buffer == output buffer
345    // - in other sessions:
346    //      last effect in the chain accumulates in output buffer: input buffer != output buffer
347    //      other effect: overwrites output buffer: input buffer == output buffer
348    // Auxiliary effect:
349    //      accumulates in output buffer: input buffer != output buffer
350    // Therefore: accumulate <=> input buffer != output buffer
351    if (mConfig.inputCfg.buffer.raw != mConfig.outputCfg.buffer.raw) {
352        mConfig.outputCfg.accessMode = EFFECT_BUFFER_ACCESS_ACCUMULATE;
353    } else {
354        mConfig.outputCfg.accessMode = EFFECT_BUFFER_ACCESS_WRITE;
355    }
356    mConfig.inputCfg.mask = EFFECT_CONFIG_ALL;
357    mConfig.outputCfg.mask = EFFECT_CONFIG_ALL;
358    mConfig.inputCfg.buffer.frameCount = thread->frameCount();
359    mConfig.outputCfg.buffer.frameCount = mConfig.inputCfg.buffer.frameCount;
360
361    ALOGV("configure() %p thread %p buffer %p framecount %d",
362            this, thread.get(), mConfig.inputCfg.buffer.raw, mConfig.inputCfg.buffer.frameCount);
363
364    status_t cmdStatus;
365    size = sizeof(int);
366    status = (*mEffectInterface)->command(mEffectInterface,
367                                                   EFFECT_CMD_SET_CONFIG,
368                                                   sizeof(effect_config_t),
369                                                   &mConfig,
370                                                   &size,
371                                                   &cmdStatus);
372    if (status == 0) {
373        status = cmdStatus;
374    }
375
376    if (status == 0 &&
377            (memcmp(&mDescriptor.type, SL_IID_VISUALIZATION, sizeof(effect_uuid_t)) == 0)) {
378        uint32_t buf32[sizeof(effect_param_t) / sizeof(uint32_t) + 2];
379        effect_param_t *p = (effect_param_t *)buf32;
380
381        p->psize = sizeof(uint32_t);
382        p->vsize = sizeof(uint32_t);
383        size = sizeof(int);
384        *(int32_t *)p->data = VISUALIZER_PARAM_LATENCY;
385
386        uint32_t latency = 0;
387        PlaybackThread *pbt = thread->mAudioFlinger->checkPlaybackThread_l(thread->mId);
388        if (pbt != NULL) {
389            latency = pbt->latency_l();
390        }
391
392        *((int32_t *)p->data + 1)= latency;
393        (*mEffectInterface)->command(mEffectInterface,
394                                     EFFECT_CMD_SET_PARAM,
395                                     sizeof(effect_param_t) + 8,
396                                     &buf32,
397                                     &size,
398                                     &cmdStatus);
399    }
400
401    mMaxDisableWaitCnt = (MAX_DISABLE_TIME_MS * mConfig.outputCfg.samplingRate) /
402            (1000 * mConfig.outputCfg.buffer.frameCount);
403
404exit:
405    mStatus = status;
406    return status;
407}
408
409status_t AudioFlinger::EffectModule::init()
410{
411    Mutex::Autolock _l(mLock);
412    if (mEffectInterface == NULL) {
413        return NO_INIT;
414    }
415    status_t cmdStatus;
416    uint32_t size = sizeof(status_t);
417    status_t status = (*mEffectInterface)->command(mEffectInterface,
418                                                   EFFECT_CMD_INIT,
419                                                   0,
420                                                   NULL,
421                                                   &size,
422                                                   &cmdStatus);
423    if (status == 0) {
424        status = cmdStatus;
425    }
426    return status;
427}
428
429status_t AudioFlinger::EffectModule::start()
430{
431    Mutex::Autolock _l(mLock);
432    return start_l();
433}
434
435status_t AudioFlinger::EffectModule::start_l()
436{
437    if (mEffectInterface == NULL) {
438        return NO_INIT;
439    }
440    if (mStatus != NO_ERROR) {
441        return mStatus;
442    }
443    status_t cmdStatus;
444    uint32_t size = sizeof(status_t);
445    status_t status = (*mEffectInterface)->command(mEffectInterface,
446                                                   EFFECT_CMD_ENABLE,
447                                                   0,
448                                                   NULL,
449                                                   &size,
450                                                   &cmdStatus);
451    if (status == 0) {
452        status = cmdStatus;
453    }
454    if (status == 0 &&
455            ((mDescriptor.flags & EFFECT_FLAG_TYPE_MASK) == EFFECT_FLAG_TYPE_PRE_PROC ||
456             (mDescriptor.flags & EFFECT_FLAG_TYPE_MASK) == EFFECT_FLAG_TYPE_POST_PROC)) {
457        sp<ThreadBase> thread = mThread.promote();
458        if (thread != 0) {
459            audio_stream_t *stream = thread->stream();
460            if (stream != NULL) {
461                stream->add_audio_effect(stream, mEffectInterface);
462            }
463        }
464    }
465    return status;
466}
467
468status_t AudioFlinger::EffectModule::stop()
469{
470    Mutex::Autolock _l(mLock);
471    return stop_l();
472}
473
474status_t AudioFlinger::EffectModule::stop_l()
475{
476    if (mEffectInterface == NULL) {
477        return NO_INIT;
478    }
479    if (mStatus != NO_ERROR) {
480        return mStatus;
481    }
482    status_t cmdStatus = NO_ERROR;
483    uint32_t size = sizeof(status_t);
484    status_t status = (*mEffectInterface)->command(mEffectInterface,
485                                                   EFFECT_CMD_DISABLE,
486                                                   0,
487                                                   NULL,
488                                                   &size,
489                                                   &cmdStatus);
490    if (status == NO_ERROR) {
491        status = cmdStatus;
492    }
493    if (status == NO_ERROR) {
494        status = remove_effect_from_hal_l();
495    }
496    return status;
497}
498
499status_t AudioFlinger::EffectModule::remove_effect_from_hal_l()
500{
501    if ((mDescriptor.flags & EFFECT_FLAG_TYPE_MASK) == EFFECT_FLAG_TYPE_PRE_PROC ||
502             (mDescriptor.flags & EFFECT_FLAG_TYPE_MASK) == EFFECT_FLAG_TYPE_POST_PROC) {
503        sp<ThreadBase> thread = mThread.promote();
504        if (thread != 0) {
505            audio_stream_t *stream = thread->stream();
506            if (stream != NULL) {
507                stream->remove_audio_effect(stream, mEffectInterface);
508            }
509        }
510    }
511    return NO_ERROR;
512}
513
514status_t AudioFlinger::EffectModule::command(uint32_t cmdCode,
515                                             uint32_t cmdSize,
516                                             void *pCmdData,
517                                             uint32_t *replySize,
518                                             void *pReplyData)
519{
520    Mutex::Autolock _l(mLock);
521    ALOGVV("command(), cmdCode: %d, mEffectInterface: %p", cmdCode, mEffectInterface);
522
523    if (mState == DESTROYED || mEffectInterface == NULL) {
524        return NO_INIT;
525    }
526    if (mStatus != NO_ERROR) {
527        return mStatus;
528    }
529    status_t status = (*mEffectInterface)->command(mEffectInterface,
530                                                   cmdCode,
531                                                   cmdSize,
532                                                   pCmdData,
533                                                   replySize,
534                                                   pReplyData);
535    if (cmdCode != EFFECT_CMD_GET_PARAM && status == NO_ERROR) {
536        uint32_t size = (replySize == NULL) ? 0 : *replySize;
537        for (size_t i = 1; i < mHandles.size(); i++) {
538            EffectHandle *h = mHandles[i];
539            if (h != NULL && !h->destroyed_l()) {
540                h->commandExecuted(cmdCode, cmdSize, pCmdData, size, pReplyData);
541            }
542        }
543    }
544    return status;
545}
546
547status_t AudioFlinger::EffectModule::setEnabled(bool enabled)
548{
549    Mutex::Autolock _l(mLock);
550    return setEnabled_l(enabled);
551}
552
553// must be called with EffectModule::mLock held
554status_t AudioFlinger::EffectModule::setEnabled_l(bool enabled)
555{
556
557    ALOGV("setEnabled %p enabled %d", this, enabled);
558
559    if (enabled != isEnabled()) {
560        status_t status = AudioSystem::setEffectEnabled(mId, enabled);
561        if (enabled && status != NO_ERROR) {
562            return status;
563        }
564
565        switch (mState) {
566        // going from disabled to enabled
567        case IDLE:
568            mState = STARTING;
569            break;
570        case STOPPED:
571            mState = RESTART;
572            break;
573        case STOPPING:
574            mState = ACTIVE;
575            break;
576
577        // going from enabled to disabled
578        case RESTART:
579            mState = STOPPED;
580            break;
581        case STARTING:
582            mState = IDLE;
583            break;
584        case ACTIVE:
585            mState = STOPPING;
586            break;
587        case DESTROYED:
588            return NO_ERROR; // simply ignore as we are being destroyed
589        }
590        for (size_t i = 1; i < mHandles.size(); i++) {
591            EffectHandle *h = mHandles[i];
592            if (h != NULL && !h->destroyed_l()) {
593                h->setEnabled(enabled);
594            }
595        }
596    }
597    return NO_ERROR;
598}
599
600bool AudioFlinger::EffectModule::isEnabled() const
601{
602    switch (mState) {
603    case RESTART:
604    case STARTING:
605    case ACTIVE:
606        return true;
607    case IDLE:
608    case STOPPING:
609    case STOPPED:
610    case DESTROYED:
611    default:
612        return false;
613    }
614}
615
616bool AudioFlinger::EffectModule::isProcessEnabled() const
617{
618    if (mStatus != NO_ERROR) {
619        return false;
620    }
621
622    switch (mState) {
623    case RESTART:
624    case ACTIVE:
625    case STOPPING:
626    case STOPPED:
627        return true;
628    case IDLE:
629    case STARTING:
630    case DESTROYED:
631    default:
632        return false;
633    }
634}
635
636status_t AudioFlinger::EffectModule::setVolume(uint32_t *left, uint32_t *right, bool controller)
637{
638    Mutex::Autolock _l(mLock);
639    if (mStatus != NO_ERROR) {
640        return mStatus;
641    }
642    status_t status = NO_ERROR;
643    // Send volume indication if EFFECT_FLAG_VOLUME_IND is set and read back altered volume
644    // if controller flag is set (Note that controller == TRUE => EFFECT_FLAG_VOLUME_CTRL set)
645    if (isProcessEnabled() &&
646            ((mDescriptor.flags & EFFECT_FLAG_VOLUME_MASK) == EFFECT_FLAG_VOLUME_CTRL ||
647            (mDescriptor.flags & EFFECT_FLAG_VOLUME_MASK) == EFFECT_FLAG_VOLUME_IND)) {
648        status_t cmdStatus;
649        uint32_t volume[2];
650        uint32_t *pVolume = NULL;
651        uint32_t size = sizeof(volume);
652        volume[0] = *left;
653        volume[1] = *right;
654        if (controller) {
655            pVolume = volume;
656        }
657        status = (*mEffectInterface)->command(mEffectInterface,
658                                              EFFECT_CMD_SET_VOLUME,
659                                              size,
660                                              volume,
661                                              &size,
662                                              pVolume);
663        if (controller && status == NO_ERROR && size == sizeof(volume)) {
664            *left = volume[0];
665            *right = volume[1];
666        }
667    }
668    return status;
669}
670
671status_t AudioFlinger::EffectModule::setDevice(audio_devices_t device)
672{
673    if (device == AUDIO_DEVICE_NONE) {
674        return NO_ERROR;
675    }
676
677    Mutex::Autolock _l(mLock);
678    if (mStatus != NO_ERROR) {
679        return mStatus;
680    }
681    status_t status = NO_ERROR;
682    if ((mDescriptor.flags & EFFECT_FLAG_DEVICE_MASK) == EFFECT_FLAG_DEVICE_IND) {
683        status_t cmdStatus;
684        uint32_t size = sizeof(status_t);
685        uint32_t cmd = audio_is_output_devices(device) ? EFFECT_CMD_SET_DEVICE :
686                            EFFECT_CMD_SET_INPUT_DEVICE;
687        status = (*mEffectInterface)->command(mEffectInterface,
688                                              cmd,
689                                              sizeof(uint32_t),
690                                              &device,
691                                              &size,
692                                              &cmdStatus);
693    }
694    return status;
695}
696
697status_t AudioFlinger::EffectModule::setMode(audio_mode_t mode)
698{
699    Mutex::Autolock _l(mLock);
700    if (mStatus != NO_ERROR) {
701        return mStatus;
702    }
703    status_t status = NO_ERROR;
704    if ((mDescriptor.flags & EFFECT_FLAG_AUDIO_MODE_MASK) == EFFECT_FLAG_AUDIO_MODE_IND) {
705        status_t cmdStatus;
706        uint32_t size = sizeof(status_t);
707        status = (*mEffectInterface)->command(mEffectInterface,
708                                              EFFECT_CMD_SET_AUDIO_MODE,
709                                              sizeof(audio_mode_t),
710                                              &mode,
711                                              &size,
712                                              &cmdStatus);
713        if (status == NO_ERROR) {
714            status = cmdStatus;
715        }
716    }
717    return status;
718}
719
720status_t AudioFlinger::EffectModule::setAudioSource(audio_source_t source)
721{
722    Mutex::Autolock _l(mLock);
723    if (mStatus != NO_ERROR) {
724        return mStatus;
725    }
726    status_t status = NO_ERROR;
727    if ((mDescriptor.flags & EFFECT_FLAG_AUDIO_SOURCE_MASK) == EFFECT_FLAG_AUDIO_SOURCE_IND) {
728        uint32_t size = 0;
729        status = (*mEffectInterface)->command(mEffectInterface,
730                                              EFFECT_CMD_SET_AUDIO_SOURCE,
731                                              sizeof(audio_source_t),
732                                              &source,
733                                              &size,
734                                              NULL);
735    }
736    return status;
737}
738
739void AudioFlinger::EffectModule::setSuspended(bool suspended)
740{
741    Mutex::Autolock _l(mLock);
742    mSuspended = suspended;
743}
744
745bool AudioFlinger::EffectModule::suspended() const
746{
747    Mutex::Autolock _l(mLock);
748    return mSuspended;
749}
750
751bool AudioFlinger::EffectModule::purgeHandles()
752{
753    bool enabled = false;
754    Mutex::Autolock _l(mLock);
755    for (size_t i = 0; i < mHandles.size(); i++) {
756        EffectHandle *handle = mHandles[i];
757        if (handle != NULL && !handle->destroyed_l()) {
758            handle->effect().clear();
759            if (handle->hasControl()) {
760                enabled = handle->enabled();
761            }
762        }
763    }
764    return enabled;
765}
766
767status_t AudioFlinger::EffectModule::setOffloaded(bool offloaded, audio_io_handle_t io)
768{
769    Mutex::Autolock _l(mLock);
770    if (mStatus != NO_ERROR) {
771        return mStatus;
772    }
773    status_t status = NO_ERROR;
774    if ((mDescriptor.flags & EFFECT_FLAG_OFFLOAD_SUPPORTED) != 0) {
775        status_t cmdStatus;
776        uint32_t size = sizeof(status_t);
777        effect_offload_param_t cmd;
778
779        cmd.isOffload = offloaded;
780        cmd.ioHandle = io;
781        status = (*mEffectInterface)->command(mEffectInterface,
782                                              EFFECT_CMD_OFFLOAD,
783                                              sizeof(effect_offload_param_t),
784                                              &cmd,
785                                              &size,
786                                              &cmdStatus);
787        if (status == NO_ERROR) {
788            status = cmdStatus;
789        }
790        mOffloaded = (status == NO_ERROR) ? offloaded : false;
791    } else {
792        if (offloaded) {
793            status = INVALID_OPERATION;
794        }
795        mOffloaded = false;
796    }
797    ALOGV("setOffloaded() offloaded %d io %d status %d", offloaded, io, status);
798    return status;
799}
800
801bool AudioFlinger::EffectModule::isOffloaded() const
802{
803    Mutex::Autolock _l(mLock);
804    return mOffloaded;
805}
806
807void AudioFlinger::EffectModule::dump(int fd, const Vector<String16>& args)
808{
809    const size_t SIZE = 256;
810    char buffer[SIZE];
811    String8 result;
812
813    snprintf(buffer, SIZE, "\tEffect ID %d:\n", mId);
814    result.append(buffer);
815
816    bool locked = AudioFlinger::dumpTryLock(mLock);
817    // failed to lock - AudioFlinger is probably deadlocked
818    if (!locked) {
819        result.append("\t\tCould not lock Fx mutex:\n");
820    }
821
822    result.append("\t\tSession Status State Engine:\n");
823    snprintf(buffer, SIZE, "\t\t%05d   %03d    %03d   %p\n",
824            mSessionId, mStatus, mState, mEffectInterface);
825    result.append(buffer);
826
827    result.append("\t\tDescriptor:\n");
828    snprintf(buffer, SIZE, "\t\t- UUID: %08X-%04X-%04X-%04X-%02X%02X%02X%02X%02X%02X\n",
829            mDescriptor.uuid.timeLow, mDescriptor.uuid.timeMid, mDescriptor.uuid.timeHiAndVersion,
830            mDescriptor.uuid.clockSeq, mDescriptor.uuid.node[0], mDescriptor.uuid.node[1],
831                    mDescriptor.uuid.node[2],
832            mDescriptor.uuid.node[3],mDescriptor.uuid.node[4],mDescriptor.uuid.node[5]);
833    result.append(buffer);
834    snprintf(buffer, SIZE, "\t\t- TYPE: %08X-%04X-%04X-%04X-%02X%02X%02X%02X%02X%02X\n",
835                mDescriptor.type.timeLow, mDescriptor.type.timeMid,
836                    mDescriptor.type.timeHiAndVersion,
837                mDescriptor.type.clockSeq, mDescriptor.type.node[0], mDescriptor.type.node[1],
838                    mDescriptor.type.node[2],
839                mDescriptor.type.node[3],mDescriptor.type.node[4],mDescriptor.type.node[5]);
840    result.append(buffer);
841    snprintf(buffer, SIZE, "\t\t- apiVersion: %08X\n\t\t- flags: %08X\n",
842            mDescriptor.apiVersion,
843            mDescriptor.flags);
844    result.append(buffer);
845    snprintf(buffer, SIZE, "\t\t- name: %s\n",
846            mDescriptor.name);
847    result.append(buffer);
848    snprintf(buffer, SIZE, "\t\t- implementor: %s\n",
849            mDescriptor.implementor);
850    result.append(buffer);
851
852    result.append("\t\t- Input configuration:\n");
853    result.append("\t\t\tFrames  Smp rate Channels Format Buffer\n");
854    snprintf(buffer, SIZE, "\t\t\t%05zu   %05d    %08x %6d %p\n",
855            mConfig.inputCfg.buffer.frameCount,
856            mConfig.inputCfg.samplingRate,
857            mConfig.inputCfg.channels,
858            mConfig.inputCfg.format,
859            mConfig.inputCfg.buffer.raw);
860    result.append(buffer);
861
862    result.append("\t\t- Output configuration:\n");
863    result.append("\t\t\tBuffer     Frames  Smp rate Channels Format\n");
864    snprintf(buffer, SIZE, "\t\t\t%p %05zu   %05d    %08x %d\n",
865            mConfig.outputCfg.buffer.raw,
866            mConfig.outputCfg.buffer.frameCount,
867            mConfig.outputCfg.samplingRate,
868            mConfig.outputCfg.channels,
869            mConfig.outputCfg.format);
870    result.append(buffer);
871
872    snprintf(buffer, SIZE, "\t\t%zu Clients:\n", mHandles.size());
873    result.append(buffer);
874    result.append("\t\t\tPid   Priority Ctrl Locked client server\n");
875    for (size_t i = 0; i < mHandles.size(); ++i) {
876        EffectHandle *handle = mHandles[i];
877        if (handle != NULL && !handle->destroyed_l()) {
878            handle->dump(buffer, SIZE);
879            result.append(buffer);
880        }
881    }
882
883    result.append("\n");
884
885    write(fd, result.string(), result.length());
886
887    if (locked) {
888        mLock.unlock();
889    }
890}
891
892// ----------------------------------------------------------------------------
893//  EffectHandle implementation
894// ----------------------------------------------------------------------------
895
896#undef LOG_TAG
897#define LOG_TAG "AudioFlinger::EffectHandle"
898
899AudioFlinger::EffectHandle::EffectHandle(const sp<EffectModule>& effect,
900                                        const sp<AudioFlinger::Client>& client,
901                                        const sp<IEffectClient>& effectClient,
902                                        int32_t priority)
903    : BnEffect(),
904    mEffect(effect), mEffectClient(effectClient), mClient(client), mCblk(NULL),
905    mPriority(priority), mHasControl(false), mEnabled(false), mDestroyed(false)
906{
907    ALOGV("constructor %p", this);
908
909    if (client == 0) {
910        return;
911    }
912    int bufOffset = ((sizeof(effect_param_cblk_t) - 1) / sizeof(int) + 1) * sizeof(int);
913    mCblkMemory = client->heap()->allocate(EFFECT_PARAM_BUFFER_SIZE + bufOffset);
914    if (mCblkMemory != 0) {
915        mCblk = static_cast<effect_param_cblk_t *>(mCblkMemory->pointer());
916
917        if (mCblk != NULL) {
918            new(mCblk) effect_param_cblk_t();
919            mBuffer = (uint8_t *)mCblk + bufOffset;
920        }
921    } else {
922        ALOGE("not enough memory for Effect size=%u", EFFECT_PARAM_BUFFER_SIZE +
923                sizeof(effect_param_cblk_t));
924        return;
925    }
926}
927
928AudioFlinger::EffectHandle::~EffectHandle()
929{
930    ALOGV("Destructor %p", this);
931
932    if (mEffect == 0) {
933        mDestroyed = true;
934        return;
935    }
936    mEffect->lock();
937    mDestroyed = true;
938    mEffect->unlock();
939    disconnect(false);
940}
941
942status_t AudioFlinger::EffectHandle::enable()
943{
944    ALOGV("enable %p", this);
945    if (!mHasControl) {
946        return INVALID_OPERATION;
947    }
948    if (mEffect == 0) {
949        return DEAD_OBJECT;
950    }
951
952    if (mEnabled) {
953        return NO_ERROR;
954    }
955
956    mEnabled = true;
957
958    sp<ThreadBase> thread = mEffect->thread().promote();
959    if (thread != 0) {
960        thread->checkSuspendOnEffectEnabled(mEffect, true, mEffect->sessionId());
961    }
962
963    // checkSuspendOnEffectEnabled() can suspend this same effect when enabled
964    if (mEffect->suspended()) {
965        return NO_ERROR;
966    }
967
968    status_t status = mEffect->setEnabled(true);
969    if (status != NO_ERROR) {
970        if (thread != 0) {
971            thread->checkSuspendOnEffectEnabled(mEffect, false, mEffect->sessionId());
972        }
973        mEnabled = false;
974    } else {
975        if (thread != 0) {
976            if (thread->type() == ThreadBase::OFFLOAD) {
977                PlaybackThread *t = (PlaybackThread *)thread.get();
978                Mutex::Autolock _l(t->mLock);
979                t->broadcast_l();
980            }
981            if (!mEffect->isOffloadable()) {
982                if (thread->type() == ThreadBase::OFFLOAD) {
983                    PlaybackThread *t = (PlaybackThread *)thread.get();
984                    t->invalidateTracks(AUDIO_STREAM_MUSIC);
985                }
986                if (mEffect->sessionId() == AUDIO_SESSION_OUTPUT_MIX) {
987                    thread->mAudioFlinger->onNonOffloadableGlobalEffectEnable();
988                }
989            }
990        }
991    }
992    return status;
993}
994
995status_t AudioFlinger::EffectHandle::disable()
996{
997    ALOGV("disable %p", this);
998    if (!mHasControl) {
999        return INVALID_OPERATION;
1000    }
1001    if (mEffect == 0) {
1002        return DEAD_OBJECT;
1003    }
1004
1005    if (!mEnabled) {
1006        return NO_ERROR;
1007    }
1008    mEnabled = false;
1009
1010    if (mEffect->suspended()) {
1011        return NO_ERROR;
1012    }
1013
1014    status_t status = mEffect->setEnabled(false);
1015
1016    sp<ThreadBase> thread = mEffect->thread().promote();
1017    if (thread != 0) {
1018        thread->checkSuspendOnEffectEnabled(mEffect, false, mEffect->sessionId());
1019        if (thread->type() == ThreadBase::OFFLOAD) {
1020            PlaybackThread *t = (PlaybackThread *)thread.get();
1021            Mutex::Autolock _l(t->mLock);
1022            t->broadcast_l();
1023        }
1024    }
1025
1026    return status;
1027}
1028
1029void AudioFlinger::EffectHandle::disconnect()
1030{
1031    disconnect(true);
1032}
1033
1034void AudioFlinger::EffectHandle::disconnect(bool unpinIfLast)
1035{
1036    ALOGV("disconnect(%s)", unpinIfLast ? "true" : "false");
1037    if (mEffect == 0) {
1038        return;
1039    }
1040    // restore suspended effects if the disconnected handle was enabled and the last one.
1041    if ((mEffect->disconnect(this, unpinIfLast) == 0) && mEnabled) {
1042        sp<ThreadBase> thread = mEffect->thread().promote();
1043        if (thread != 0) {
1044            thread->checkSuspendOnEffectEnabled(mEffect, false, mEffect->sessionId());
1045        }
1046    }
1047
1048    // release sp on module => module destructor can be called now
1049    mEffect.clear();
1050    if (mClient != 0) {
1051        if (mCblk != NULL) {
1052            // unlike ~TrackBase(), mCblk is never a local new, so don't delete
1053            mCblk->~effect_param_cblk_t();   // destroy our shared-structure.
1054        }
1055        mCblkMemory.clear();    // free the shared memory before releasing the heap it belongs to
1056        // Client destructor must run with AudioFlinger mutex locked
1057        Mutex::Autolock _l(mClient->audioFlinger()->mLock);
1058        mClient.clear();
1059    }
1060}
1061
1062status_t AudioFlinger::EffectHandle::command(uint32_t cmdCode,
1063                                             uint32_t cmdSize,
1064                                             void *pCmdData,
1065                                             uint32_t *replySize,
1066                                             void *pReplyData)
1067{
1068    ALOGVV("command(), cmdCode: %d, mHasControl: %d, mEffect: %p",
1069            cmdCode, mHasControl, (mEffect == 0) ? 0 : mEffect.get());
1070
1071    // only get parameter command is permitted for applications not controlling the effect
1072    if (!mHasControl && cmdCode != EFFECT_CMD_GET_PARAM) {
1073        return INVALID_OPERATION;
1074    }
1075    if (mEffect == 0) {
1076        return DEAD_OBJECT;
1077    }
1078    if (mClient == 0) {
1079        return INVALID_OPERATION;
1080    }
1081
1082    // handle commands that are not forwarded transparently to effect engine
1083    if (cmdCode == EFFECT_CMD_SET_PARAM_COMMIT) {
1084        // No need to trylock() here as this function is executed in the binder thread serving a
1085        // particular client process:  no risk to block the whole media server process or mixer
1086        // threads if we are stuck here
1087        Mutex::Autolock _l(mCblk->lock);
1088        if (mCblk->clientIndex > EFFECT_PARAM_BUFFER_SIZE ||
1089            mCblk->serverIndex > EFFECT_PARAM_BUFFER_SIZE) {
1090            mCblk->serverIndex = 0;
1091            mCblk->clientIndex = 0;
1092            return BAD_VALUE;
1093        }
1094        status_t status = NO_ERROR;
1095        while (mCblk->serverIndex < mCblk->clientIndex) {
1096            int reply;
1097            uint32_t rsize = sizeof(int);
1098            int *p = (int *)(mBuffer + mCblk->serverIndex);
1099            int size = *p++;
1100            if (((uint8_t *)p + size) > mBuffer + mCblk->clientIndex) {
1101                ALOGW("command(): invalid parameter block size");
1102                break;
1103            }
1104            effect_param_t *param = (effect_param_t *)p;
1105            if (param->psize == 0 || param->vsize == 0) {
1106                ALOGW("command(): null parameter or value size");
1107                mCblk->serverIndex += size;
1108                continue;
1109            }
1110            uint32_t psize = sizeof(effect_param_t) +
1111                             ((param->psize - 1) / sizeof(int) + 1) * sizeof(int) +
1112                             param->vsize;
1113            status_t ret = mEffect->command(EFFECT_CMD_SET_PARAM,
1114                                            psize,
1115                                            p,
1116                                            &rsize,
1117                                            &reply);
1118            // stop at first error encountered
1119            if (ret != NO_ERROR) {
1120                status = ret;
1121                *(int *)pReplyData = reply;
1122                break;
1123            } else if (reply != NO_ERROR) {
1124                *(int *)pReplyData = reply;
1125                break;
1126            }
1127            mCblk->serverIndex += size;
1128        }
1129        mCblk->serverIndex = 0;
1130        mCblk->clientIndex = 0;
1131        return status;
1132    } else if (cmdCode == EFFECT_CMD_ENABLE) {
1133        *(int *)pReplyData = NO_ERROR;
1134        return enable();
1135    } else if (cmdCode == EFFECT_CMD_DISABLE) {
1136        *(int *)pReplyData = NO_ERROR;
1137        return disable();
1138    }
1139
1140    return mEffect->command(cmdCode, cmdSize, pCmdData, replySize, pReplyData);
1141}
1142
1143void AudioFlinger::EffectHandle::setControl(bool hasControl, bool signal, bool enabled)
1144{
1145    ALOGV("setControl %p control %d", this, hasControl);
1146
1147    mHasControl = hasControl;
1148    mEnabled = enabled;
1149
1150    if (signal && mEffectClient != 0) {
1151        mEffectClient->controlStatusChanged(hasControl);
1152    }
1153}
1154
1155void AudioFlinger::EffectHandle::commandExecuted(uint32_t cmdCode,
1156                                                 uint32_t cmdSize,
1157                                                 void *pCmdData,
1158                                                 uint32_t replySize,
1159                                                 void *pReplyData)
1160{
1161    if (mEffectClient != 0) {
1162        mEffectClient->commandExecuted(cmdCode, cmdSize, pCmdData, replySize, pReplyData);
1163    }
1164}
1165
1166
1167
1168void AudioFlinger::EffectHandle::setEnabled(bool enabled)
1169{
1170    if (mEffectClient != 0) {
1171        mEffectClient->enableStatusChanged(enabled);
1172    }
1173}
1174
1175status_t AudioFlinger::EffectHandle::onTransact(
1176    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
1177{
1178    return BnEffect::onTransact(code, data, reply, flags);
1179}
1180
1181
1182void AudioFlinger::EffectHandle::dump(char* buffer, size_t size)
1183{
1184    bool locked = mCblk != NULL && AudioFlinger::dumpTryLock(mCblk->lock);
1185
1186    snprintf(buffer, size, "\t\t\t%05d %05d    %01u    %01u      %05u  %05u\n",
1187            (mClient == 0) ? getpid_cached : mClient->pid(),
1188            mPriority,
1189            mHasControl,
1190            !locked,
1191            mCblk ? mCblk->clientIndex : 0,
1192            mCblk ? mCblk->serverIndex : 0
1193            );
1194
1195    if (locked) {
1196        mCblk->lock.unlock();
1197    }
1198}
1199
1200#undef LOG_TAG
1201#define LOG_TAG "AudioFlinger::EffectChain"
1202
1203AudioFlinger::EffectChain::EffectChain(ThreadBase *thread,
1204                                        int sessionId)
1205    : mThread(thread), mSessionId(sessionId), mActiveTrackCnt(0), mTrackCnt(0), mTailBufferCount(0),
1206      mOwnInBuffer(false), mVolumeCtrlIdx(-1), mLeftVolume(UINT_MAX), mRightVolume(UINT_MAX),
1207      mNewLeftVolume(UINT_MAX), mNewRightVolume(UINT_MAX)
1208{
1209    mStrategy = AudioSystem::getStrategyForStream(AUDIO_STREAM_MUSIC);
1210    if (thread == NULL) {
1211        return;
1212    }
1213    mMaxTailBuffers = ((kProcessTailDurationMs * thread->sampleRate()) / 1000) /
1214                                    thread->frameCount();
1215}
1216
1217AudioFlinger::EffectChain::~EffectChain()
1218{
1219    if (mOwnInBuffer) {
1220        delete mInBuffer;
1221    }
1222
1223}
1224
1225// getEffectFromDesc_l() must be called with ThreadBase::mLock held
1226sp<AudioFlinger::EffectModule> AudioFlinger::EffectChain::getEffectFromDesc_l(
1227        effect_descriptor_t *descriptor)
1228{
1229    size_t size = mEffects.size();
1230
1231    for (size_t i = 0; i < size; i++) {
1232        if (memcmp(&mEffects[i]->desc().uuid, &descriptor->uuid, sizeof(effect_uuid_t)) == 0) {
1233            return mEffects[i];
1234        }
1235    }
1236    return 0;
1237}
1238
1239// getEffectFromId_l() must be called with ThreadBase::mLock held
1240sp<AudioFlinger::EffectModule> AudioFlinger::EffectChain::getEffectFromId_l(int id)
1241{
1242    size_t size = mEffects.size();
1243
1244    for (size_t i = 0; i < size; i++) {
1245        // by convention, return first effect if id provided is 0 (0 is never a valid id)
1246        if (id == 0 || mEffects[i]->id() == id) {
1247            return mEffects[i];
1248        }
1249    }
1250    return 0;
1251}
1252
1253// getEffectFromType_l() must be called with ThreadBase::mLock held
1254sp<AudioFlinger::EffectModule> AudioFlinger::EffectChain::getEffectFromType_l(
1255        const effect_uuid_t *type)
1256{
1257    size_t size = mEffects.size();
1258
1259    for (size_t i = 0; i < size; i++) {
1260        if (memcmp(&mEffects[i]->desc().type, type, sizeof(effect_uuid_t)) == 0) {
1261            return mEffects[i];
1262        }
1263    }
1264    return 0;
1265}
1266
1267void AudioFlinger::EffectChain::clearInputBuffer()
1268{
1269    Mutex::Autolock _l(mLock);
1270    sp<ThreadBase> thread = mThread.promote();
1271    if (thread == 0) {
1272        ALOGW("clearInputBuffer(): cannot promote mixer thread");
1273        return;
1274    }
1275    clearInputBuffer_l(thread);
1276}
1277
1278// Must be called with EffectChain::mLock locked
1279void AudioFlinger::EffectChain::clearInputBuffer_l(sp<ThreadBase> thread)
1280{
1281    memset(mInBuffer, 0, thread->frameCount() * thread->frameSize());
1282}
1283
1284// Must be called with EffectChain::mLock locked
1285void AudioFlinger::EffectChain::process_l()
1286{
1287    sp<ThreadBase> thread = mThread.promote();
1288    if (thread == 0) {
1289        ALOGW("process_l(): cannot promote mixer thread");
1290        return;
1291    }
1292    bool isGlobalSession = (mSessionId == AUDIO_SESSION_OUTPUT_MIX) ||
1293            (mSessionId == AUDIO_SESSION_OUTPUT_STAGE);
1294    // never process effects when:
1295    // - on an OFFLOAD thread
1296    // - no more tracks are on the session and the effect tail has been rendered
1297    bool doProcess = (thread->type() != ThreadBase::OFFLOAD);
1298    if (!isGlobalSession) {
1299        bool tracksOnSession = (trackCnt() != 0);
1300
1301        if (!tracksOnSession && mTailBufferCount == 0) {
1302            doProcess = false;
1303        }
1304
1305        if (activeTrackCnt() == 0) {
1306            // if no track is active and the effect tail has not been rendered,
1307            // the input buffer must be cleared here as the mixer process will not do it
1308            if (tracksOnSession || mTailBufferCount > 0) {
1309                clearInputBuffer_l(thread);
1310                if (mTailBufferCount > 0) {
1311                    mTailBufferCount--;
1312                }
1313            }
1314        }
1315    }
1316
1317    size_t size = mEffects.size();
1318    if (doProcess) {
1319        for (size_t i = 0; i < size; i++) {
1320            mEffects[i]->process();
1321        }
1322    }
1323    for (size_t i = 0; i < size; i++) {
1324        mEffects[i]->updateState();
1325    }
1326}
1327
1328// addEffect_l() must be called with PlaybackThread::mLock held
1329status_t AudioFlinger::EffectChain::addEffect_l(const sp<EffectModule>& effect)
1330{
1331    effect_descriptor_t desc = effect->desc();
1332    uint32_t insertPref = desc.flags & EFFECT_FLAG_INSERT_MASK;
1333
1334    Mutex::Autolock _l(mLock);
1335    effect->setChain(this);
1336    sp<ThreadBase> thread = mThread.promote();
1337    if (thread == 0) {
1338        return NO_INIT;
1339    }
1340    effect->setThread(thread);
1341
1342    if ((desc.flags & EFFECT_FLAG_TYPE_MASK) == EFFECT_FLAG_TYPE_AUXILIARY) {
1343        // Auxiliary effects are inserted at the beginning of mEffects vector as
1344        // they are processed first and accumulated in chain input buffer
1345        mEffects.insertAt(effect, 0);
1346
1347        // the input buffer for auxiliary effect contains mono samples in
1348        // 32 bit format. This is to avoid saturation in AudoMixer
1349        // accumulation stage. Saturation is done in EffectModule::process() before
1350        // calling the process in effect engine
1351        size_t numSamples = thread->frameCount();
1352        int32_t *buffer = new int32_t[numSamples];
1353        memset(buffer, 0, numSamples * sizeof(int32_t));
1354        effect->setInBuffer((int16_t *)buffer);
1355        // auxiliary effects output samples to chain input buffer for further processing
1356        // by insert effects
1357        effect->setOutBuffer(mInBuffer);
1358    } else {
1359        // Insert effects are inserted at the end of mEffects vector as they are processed
1360        //  after track and auxiliary effects.
1361        // Insert effect order as a function of indicated preference:
1362        //  if EFFECT_FLAG_INSERT_EXCLUSIVE, insert in first position or reject if
1363        //  another effect is present
1364        //  else if EFFECT_FLAG_INSERT_FIRST, insert in first position or after the
1365        //  last effect claiming first position
1366        //  else if EFFECT_FLAG_INSERT_LAST, insert in last position or before the
1367        //  first effect claiming last position
1368        //  else if EFFECT_FLAG_INSERT_ANY insert after first or before last
1369        // Reject insertion if an effect with EFFECT_FLAG_INSERT_EXCLUSIVE is
1370        // already present
1371
1372        size_t size = mEffects.size();
1373        size_t idx_insert = size;
1374        ssize_t idx_insert_first = -1;
1375        ssize_t idx_insert_last = -1;
1376
1377        for (size_t i = 0; i < size; i++) {
1378            effect_descriptor_t d = mEffects[i]->desc();
1379            uint32_t iMode = d.flags & EFFECT_FLAG_TYPE_MASK;
1380            uint32_t iPref = d.flags & EFFECT_FLAG_INSERT_MASK;
1381            if (iMode == EFFECT_FLAG_TYPE_INSERT) {
1382                // check invalid effect chaining combinations
1383                if (insertPref == EFFECT_FLAG_INSERT_EXCLUSIVE ||
1384                    iPref == EFFECT_FLAG_INSERT_EXCLUSIVE) {
1385                    ALOGW("addEffect_l() could not insert effect %s: exclusive conflict with %s",
1386                            desc.name, d.name);
1387                    return INVALID_OPERATION;
1388                }
1389                // remember position of first insert effect and by default
1390                // select this as insert position for new effect
1391                if (idx_insert == size) {
1392                    idx_insert = i;
1393                }
1394                // remember position of last insert effect claiming
1395                // first position
1396                if (iPref == EFFECT_FLAG_INSERT_FIRST) {
1397                    idx_insert_first = i;
1398                }
1399                // remember position of first insert effect claiming
1400                // last position
1401                if (iPref == EFFECT_FLAG_INSERT_LAST &&
1402                    idx_insert_last == -1) {
1403                    idx_insert_last = i;
1404                }
1405            }
1406        }
1407
1408        // modify idx_insert from first position if needed
1409        if (insertPref == EFFECT_FLAG_INSERT_LAST) {
1410            if (idx_insert_last != -1) {
1411                idx_insert = idx_insert_last;
1412            } else {
1413                idx_insert = size;
1414            }
1415        } else {
1416            if (idx_insert_first != -1) {
1417                idx_insert = idx_insert_first + 1;
1418            }
1419        }
1420
1421        // always read samples from chain input buffer
1422        effect->setInBuffer(mInBuffer);
1423
1424        // if last effect in the chain, output samples to chain
1425        // output buffer, otherwise to chain input buffer
1426        if (idx_insert == size) {
1427            if (idx_insert != 0) {
1428                mEffects[idx_insert-1]->setOutBuffer(mInBuffer);
1429                mEffects[idx_insert-1]->configure();
1430            }
1431            effect->setOutBuffer(mOutBuffer);
1432        } else {
1433            effect->setOutBuffer(mInBuffer);
1434        }
1435        mEffects.insertAt(effect, idx_insert);
1436
1437        ALOGV("addEffect_l() effect %p, added in chain %p at rank %d", effect.get(), this,
1438                idx_insert);
1439    }
1440    effect->configure();
1441    return NO_ERROR;
1442}
1443
1444// removeEffect_l() must be called with PlaybackThread::mLock held
1445size_t AudioFlinger::EffectChain::removeEffect_l(const sp<EffectModule>& effect)
1446{
1447    Mutex::Autolock _l(mLock);
1448    size_t size = mEffects.size();
1449    uint32_t type = effect->desc().flags & EFFECT_FLAG_TYPE_MASK;
1450
1451    for (size_t i = 0; i < size; i++) {
1452        if (effect == mEffects[i]) {
1453            // calling stop here will remove pre-processing effect from the audio HAL.
1454            // This is safe as we hold the EffectChain mutex which guarantees that we are not in
1455            // the middle of a read from audio HAL
1456            if (mEffects[i]->state() == EffectModule::ACTIVE ||
1457                    mEffects[i]->state() == EffectModule::STOPPING) {
1458                mEffects[i]->stop();
1459            }
1460            if (type == EFFECT_FLAG_TYPE_AUXILIARY) {
1461                delete[] effect->inBuffer();
1462            } else {
1463                if (i == size - 1 && i != 0) {
1464                    mEffects[i - 1]->setOutBuffer(mOutBuffer);
1465                    mEffects[i - 1]->configure();
1466                }
1467            }
1468            mEffects.removeAt(i);
1469            ALOGV("removeEffect_l() effect %p, removed from chain %p at rank %d", effect.get(),
1470                    this, i);
1471            break;
1472        }
1473    }
1474
1475    return mEffects.size();
1476}
1477
1478// setDevice_l() must be called with PlaybackThread::mLock held
1479void AudioFlinger::EffectChain::setDevice_l(audio_devices_t device)
1480{
1481    size_t size = mEffects.size();
1482    for (size_t i = 0; i < size; i++) {
1483        mEffects[i]->setDevice(device);
1484    }
1485}
1486
1487// setMode_l() must be called with PlaybackThread::mLock held
1488void AudioFlinger::EffectChain::setMode_l(audio_mode_t mode)
1489{
1490    size_t size = mEffects.size();
1491    for (size_t i = 0; i < size; i++) {
1492        mEffects[i]->setMode(mode);
1493    }
1494}
1495
1496// setAudioSource_l() must be called with PlaybackThread::mLock held
1497void AudioFlinger::EffectChain::setAudioSource_l(audio_source_t source)
1498{
1499    size_t size = mEffects.size();
1500    for (size_t i = 0; i < size; i++) {
1501        mEffects[i]->setAudioSource(source);
1502    }
1503}
1504
1505// setVolume_l() must be called with PlaybackThread::mLock held
1506bool AudioFlinger::EffectChain::setVolume_l(uint32_t *left, uint32_t *right)
1507{
1508    uint32_t newLeft = *left;
1509    uint32_t newRight = *right;
1510    bool hasControl = false;
1511    int ctrlIdx = -1;
1512    size_t size = mEffects.size();
1513
1514    // first update volume controller
1515    for (size_t i = size; i > 0; i--) {
1516        if (mEffects[i - 1]->isProcessEnabled() &&
1517            (mEffects[i - 1]->desc().flags & EFFECT_FLAG_VOLUME_MASK) == EFFECT_FLAG_VOLUME_CTRL) {
1518            ctrlIdx = i - 1;
1519            hasControl = true;
1520            break;
1521        }
1522    }
1523
1524    if (ctrlIdx == mVolumeCtrlIdx && *left == mLeftVolume && *right == mRightVolume) {
1525        if (hasControl) {
1526            *left = mNewLeftVolume;
1527            *right = mNewRightVolume;
1528        }
1529        return hasControl;
1530    }
1531
1532    mVolumeCtrlIdx = ctrlIdx;
1533    mLeftVolume = newLeft;
1534    mRightVolume = newRight;
1535
1536    // second get volume update from volume controller
1537    if (ctrlIdx >= 0) {
1538        mEffects[ctrlIdx]->setVolume(&newLeft, &newRight, true);
1539        mNewLeftVolume = newLeft;
1540        mNewRightVolume = newRight;
1541    }
1542    // then indicate volume to all other effects in chain.
1543    // Pass altered volume to effects before volume controller
1544    // and requested volume to effects after controller
1545    uint32_t lVol = newLeft;
1546    uint32_t rVol = newRight;
1547
1548    for (size_t i = 0; i < size; i++) {
1549        if ((int)i == ctrlIdx) {
1550            continue;
1551        }
1552        // this also works for ctrlIdx == -1 when there is no volume controller
1553        if ((int)i > ctrlIdx) {
1554            lVol = *left;
1555            rVol = *right;
1556        }
1557        mEffects[i]->setVolume(&lVol, &rVol, false);
1558    }
1559    *left = newLeft;
1560    *right = newRight;
1561
1562    return hasControl;
1563}
1564
1565void AudioFlinger::EffectChain::dump(int fd, const Vector<String16>& args)
1566{
1567    const size_t SIZE = 256;
1568    char buffer[SIZE];
1569    String8 result;
1570
1571    snprintf(buffer, SIZE, "Effects for session %d:\n", mSessionId);
1572    result.append(buffer);
1573
1574    bool locked = AudioFlinger::dumpTryLock(mLock);
1575    // failed to lock - AudioFlinger is probably deadlocked
1576    if (!locked) {
1577        result.append("\tCould not lock mutex:\n");
1578    }
1579
1580    result.append("\tNum fx In buffer   Out buffer   Active tracks:\n");
1581    snprintf(buffer, SIZE, "\t%02zu     %p  %p   %d\n",
1582            mEffects.size(),
1583            mInBuffer,
1584            mOutBuffer,
1585            mActiveTrackCnt);
1586    result.append(buffer);
1587    write(fd, result.string(), result.size());
1588
1589    for (size_t i = 0; i < mEffects.size(); ++i) {
1590        sp<EffectModule> effect = mEffects[i];
1591        if (effect != 0) {
1592            effect->dump(fd, args);
1593        }
1594    }
1595
1596    if (locked) {
1597        mLock.unlock();
1598    }
1599}
1600
1601// must be called with ThreadBase::mLock held
1602void AudioFlinger::EffectChain::setEffectSuspended_l(
1603        const effect_uuid_t *type, bool suspend)
1604{
1605    sp<SuspendedEffectDesc> desc;
1606    // use effect type UUID timelow as key as there is no real risk of identical
1607    // timeLow fields among effect type UUIDs.
1608    ssize_t index = mSuspendedEffects.indexOfKey(type->timeLow);
1609    if (suspend) {
1610        if (index >= 0) {
1611            desc = mSuspendedEffects.valueAt(index);
1612        } else {
1613            desc = new SuspendedEffectDesc();
1614            desc->mType = *type;
1615            mSuspendedEffects.add(type->timeLow, desc);
1616            ALOGV("setEffectSuspended_l() add entry for %08x", type->timeLow);
1617        }
1618        if (desc->mRefCount++ == 0) {
1619            sp<EffectModule> effect = getEffectIfEnabled(type);
1620            if (effect != 0) {
1621                desc->mEffect = effect;
1622                effect->setSuspended(true);
1623                effect->setEnabled(false);
1624            }
1625        }
1626    } else {
1627        if (index < 0) {
1628            return;
1629        }
1630        desc = mSuspendedEffects.valueAt(index);
1631        if (desc->mRefCount <= 0) {
1632            ALOGW("setEffectSuspended_l() restore refcount should not be 0 %d", desc->mRefCount);
1633            desc->mRefCount = 1;
1634        }
1635        if (--desc->mRefCount == 0) {
1636            ALOGV("setEffectSuspended_l() remove entry for %08x", mSuspendedEffects.keyAt(index));
1637            if (desc->mEffect != 0) {
1638                sp<EffectModule> effect = desc->mEffect.promote();
1639                if (effect != 0) {
1640                    effect->setSuspended(false);
1641                    effect->lock();
1642                    EffectHandle *handle = effect->controlHandle_l();
1643                    if (handle != NULL && !handle->destroyed_l()) {
1644                        effect->setEnabled_l(handle->enabled());
1645                    }
1646                    effect->unlock();
1647                }
1648                desc->mEffect.clear();
1649            }
1650            mSuspendedEffects.removeItemsAt(index);
1651        }
1652    }
1653}
1654
1655// must be called with ThreadBase::mLock held
1656void AudioFlinger::EffectChain::setEffectSuspendedAll_l(bool suspend)
1657{
1658    sp<SuspendedEffectDesc> desc;
1659
1660    ssize_t index = mSuspendedEffects.indexOfKey((int)kKeyForSuspendAll);
1661    if (suspend) {
1662        if (index >= 0) {
1663            desc = mSuspendedEffects.valueAt(index);
1664        } else {
1665            desc = new SuspendedEffectDesc();
1666            mSuspendedEffects.add((int)kKeyForSuspendAll, desc);
1667            ALOGV("setEffectSuspendedAll_l() add entry for 0");
1668        }
1669        if (desc->mRefCount++ == 0) {
1670            Vector< sp<EffectModule> > effects;
1671            getSuspendEligibleEffects(effects);
1672            for (size_t i = 0; i < effects.size(); i++) {
1673                setEffectSuspended_l(&effects[i]->desc().type, true);
1674            }
1675        }
1676    } else {
1677        if (index < 0) {
1678            return;
1679        }
1680        desc = mSuspendedEffects.valueAt(index);
1681        if (desc->mRefCount <= 0) {
1682            ALOGW("setEffectSuspendedAll_l() restore refcount should not be 0 %d", desc->mRefCount);
1683            desc->mRefCount = 1;
1684        }
1685        if (--desc->mRefCount == 0) {
1686            Vector<const effect_uuid_t *> types;
1687            for (size_t i = 0; i < mSuspendedEffects.size(); i++) {
1688                if (mSuspendedEffects.keyAt(i) == (int)kKeyForSuspendAll) {
1689                    continue;
1690                }
1691                types.add(&mSuspendedEffects.valueAt(i)->mType);
1692            }
1693            for (size_t i = 0; i < types.size(); i++) {
1694                setEffectSuspended_l(types[i], false);
1695            }
1696            ALOGV("setEffectSuspendedAll_l() remove entry for %08x",
1697                    mSuspendedEffects.keyAt(index));
1698            mSuspendedEffects.removeItem((int)kKeyForSuspendAll);
1699        }
1700    }
1701}
1702
1703
1704// The volume effect is used for automated tests only
1705#ifndef OPENSL_ES_H_
1706static const effect_uuid_t SL_IID_VOLUME_ = { 0x09e8ede0, 0xddde, 0x11db, 0xb4f6,
1707                                            { 0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b } };
1708const effect_uuid_t * const SL_IID_VOLUME = &SL_IID_VOLUME_;
1709#endif //OPENSL_ES_H_
1710
1711bool AudioFlinger::EffectChain::isEffectEligibleForSuspend(const effect_descriptor_t& desc)
1712{
1713    // auxiliary effects and visualizer are never suspended on output mix
1714    if ((mSessionId == AUDIO_SESSION_OUTPUT_MIX) &&
1715        (((desc.flags & EFFECT_FLAG_TYPE_MASK) == EFFECT_FLAG_TYPE_AUXILIARY) ||
1716         (memcmp(&desc.type, SL_IID_VISUALIZATION, sizeof(effect_uuid_t)) == 0) ||
1717         (memcmp(&desc.type, SL_IID_VOLUME, sizeof(effect_uuid_t)) == 0))) {
1718        return false;
1719    }
1720    return true;
1721}
1722
1723void AudioFlinger::EffectChain::getSuspendEligibleEffects(
1724        Vector< sp<AudioFlinger::EffectModule> > &effects)
1725{
1726    effects.clear();
1727    for (size_t i = 0; i < mEffects.size(); i++) {
1728        if (isEffectEligibleForSuspend(mEffects[i]->desc())) {
1729            effects.add(mEffects[i]);
1730        }
1731    }
1732}
1733
1734sp<AudioFlinger::EffectModule> AudioFlinger::EffectChain::getEffectIfEnabled(
1735                                                            const effect_uuid_t *type)
1736{
1737    sp<EffectModule> effect = getEffectFromType_l(type);
1738    return effect != 0 && effect->isEnabled() ? effect : 0;
1739}
1740
1741void AudioFlinger::EffectChain::checkSuspendOnEffectEnabled(const sp<EffectModule>& effect,
1742                                                            bool enabled)
1743{
1744    ssize_t index = mSuspendedEffects.indexOfKey(effect->desc().type.timeLow);
1745    if (enabled) {
1746        if (index < 0) {
1747            // if the effect is not suspend check if all effects are suspended
1748            index = mSuspendedEffects.indexOfKey((int)kKeyForSuspendAll);
1749            if (index < 0) {
1750                return;
1751            }
1752            if (!isEffectEligibleForSuspend(effect->desc())) {
1753                return;
1754            }
1755            setEffectSuspended_l(&effect->desc().type, enabled);
1756            index = mSuspendedEffects.indexOfKey(effect->desc().type.timeLow);
1757            if (index < 0) {
1758                ALOGW("checkSuspendOnEffectEnabled() Fx should be suspended here!");
1759                return;
1760            }
1761        }
1762        ALOGV("checkSuspendOnEffectEnabled() enable suspending fx %08x",
1763            effect->desc().type.timeLow);
1764        sp<SuspendedEffectDesc> desc = mSuspendedEffects.valueAt(index);
1765        // if effect is requested to suspended but was not yet enabled, supend it now.
1766        if (desc->mEffect == 0) {
1767            desc->mEffect = effect;
1768            effect->setEnabled(false);
1769            effect->setSuspended(true);
1770        }
1771    } else {
1772        if (index < 0) {
1773            return;
1774        }
1775        ALOGV("checkSuspendOnEffectEnabled() disable restoring fx %08x",
1776            effect->desc().type.timeLow);
1777        sp<SuspendedEffectDesc> desc = mSuspendedEffects.valueAt(index);
1778        desc->mEffect.clear();
1779        effect->setSuspended(false);
1780    }
1781}
1782
1783bool AudioFlinger::EffectChain::isNonOffloadableEnabled()
1784{
1785    Mutex::Autolock _l(mLock);
1786    size_t size = mEffects.size();
1787    for (size_t i = 0; i < size; i++) {
1788        if (mEffects[i]->isEnabled() && !mEffects[i]->isOffloadable()) {
1789            return true;
1790        }
1791    }
1792    return false;
1793}
1794
1795}; // namespace android
1796