Effects.cpp revision bfb1b832079bbb9426f72f3863199a54aefd02da
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//EL_FIXME not sure why this is needed?
597//        sp<ThreadBase> thread = mThread.promote();
598//        if (thread == 0) {
599//            return NO_ERROR;
600//        }
601//
602//        if ((thread->type() == ThreadBase::OFFLOAD) && (enabled)) {
603//            PlaybackThread *p = (PlaybackThread *)thread.get();
604//            ALOGV("setEnabled: Offload, invalidate tracks");
605//            p->invalidateTracks(AUDIO_STREAM_MUSIC);
606//        }
607    }
608    return NO_ERROR;
609}
610
611bool AudioFlinger::EffectModule::isEnabled() const
612{
613    switch (mState) {
614    case RESTART:
615    case STARTING:
616    case ACTIVE:
617        return true;
618    case IDLE:
619    case STOPPING:
620    case STOPPED:
621    case DESTROYED:
622    default:
623        return false;
624    }
625}
626
627bool AudioFlinger::EffectModule::isProcessEnabled() const
628{
629    if (mStatus != NO_ERROR) {
630        return false;
631    }
632
633    switch (mState) {
634    case RESTART:
635    case ACTIVE:
636    case STOPPING:
637    case STOPPED:
638        return true;
639    case IDLE:
640    case STARTING:
641    case DESTROYED:
642    default:
643        return false;
644    }
645}
646
647status_t AudioFlinger::EffectModule::setVolume(uint32_t *left, uint32_t *right, bool controller)
648{
649    Mutex::Autolock _l(mLock);
650    if (mStatus != NO_ERROR) {
651        return mStatus;
652    }
653    status_t status = NO_ERROR;
654    // Send volume indication if EFFECT_FLAG_VOLUME_IND is set and read back altered volume
655    // if controller flag is set (Note that controller == TRUE => EFFECT_FLAG_VOLUME_CTRL set)
656    if (isProcessEnabled() &&
657            ((mDescriptor.flags & EFFECT_FLAG_VOLUME_MASK) == EFFECT_FLAG_VOLUME_CTRL ||
658            (mDescriptor.flags & EFFECT_FLAG_VOLUME_MASK) == EFFECT_FLAG_VOLUME_IND)) {
659        status_t cmdStatus;
660        uint32_t volume[2];
661        uint32_t *pVolume = NULL;
662        uint32_t size = sizeof(volume);
663        volume[0] = *left;
664        volume[1] = *right;
665        if (controller) {
666            pVolume = volume;
667        }
668        status = (*mEffectInterface)->command(mEffectInterface,
669                                              EFFECT_CMD_SET_VOLUME,
670                                              size,
671                                              volume,
672                                              &size,
673                                              pVolume);
674        if (controller && status == NO_ERROR && size == sizeof(volume)) {
675            *left = volume[0];
676            *right = volume[1];
677        }
678    }
679    return status;
680}
681
682status_t AudioFlinger::EffectModule::setDevice(audio_devices_t device)
683{
684    if (device == AUDIO_DEVICE_NONE) {
685        return NO_ERROR;
686    }
687
688    Mutex::Autolock _l(mLock);
689    if (mStatus != NO_ERROR) {
690        return mStatus;
691    }
692    status_t status = NO_ERROR;
693    if ((mDescriptor.flags & EFFECT_FLAG_DEVICE_MASK) == EFFECT_FLAG_DEVICE_IND) {
694        status_t cmdStatus;
695        uint32_t size = sizeof(status_t);
696        uint32_t cmd = audio_is_output_devices(device) ? EFFECT_CMD_SET_DEVICE :
697                            EFFECT_CMD_SET_INPUT_DEVICE;
698        status = (*mEffectInterface)->command(mEffectInterface,
699                                              cmd,
700                                              sizeof(uint32_t),
701                                              &device,
702                                              &size,
703                                              &cmdStatus);
704    }
705    return status;
706}
707
708status_t AudioFlinger::EffectModule::setMode(audio_mode_t mode)
709{
710    Mutex::Autolock _l(mLock);
711    if (mStatus != NO_ERROR) {
712        return mStatus;
713    }
714    status_t status = NO_ERROR;
715    if ((mDescriptor.flags & EFFECT_FLAG_AUDIO_MODE_MASK) == EFFECT_FLAG_AUDIO_MODE_IND) {
716        status_t cmdStatus;
717        uint32_t size = sizeof(status_t);
718        status = (*mEffectInterface)->command(mEffectInterface,
719                                              EFFECT_CMD_SET_AUDIO_MODE,
720                                              sizeof(audio_mode_t),
721                                              &mode,
722                                              &size,
723                                              &cmdStatus);
724        if (status == NO_ERROR) {
725            status = cmdStatus;
726        }
727    }
728    return status;
729}
730
731status_t AudioFlinger::EffectModule::setAudioSource(audio_source_t source)
732{
733    Mutex::Autolock _l(mLock);
734    if (mStatus != NO_ERROR) {
735        return mStatus;
736    }
737    status_t status = NO_ERROR;
738    if ((mDescriptor.flags & EFFECT_FLAG_AUDIO_SOURCE_MASK) == EFFECT_FLAG_AUDIO_SOURCE_IND) {
739        uint32_t size = 0;
740        status = (*mEffectInterface)->command(mEffectInterface,
741                                              EFFECT_CMD_SET_AUDIO_SOURCE,
742                                              sizeof(audio_source_t),
743                                              &source,
744                                              &size,
745                                              NULL);
746    }
747    return status;
748}
749
750void AudioFlinger::EffectModule::setSuspended(bool suspended)
751{
752    Mutex::Autolock _l(mLock);
753    mSuspended = suspended;
754}
755
756bool AudioFlinger::EffectModule::suspended() const
757{
758    Mutex::Autolock _l(mLock);
759    return mSuspended;
760}
761
762bool AudioFlinger::EffectModule::purgeHandles()
763{
764    bool enabled = false;
765    Mutex::Autolock _l(mLock);
766    for (size_t i = 0; i < mHandles.size(); i++) {
767        EffectHandle *handle = mHandles[i];
768        if (handle != NULL && !handle->destroyed_l()) {
769            handle->effect().clear();
770            if (handle->hasControl()) {
771                enabled = handle->enabled();
772            }
773        }
774    }
775    return enabled;
776}
777
778void AudioFlinger::EffectModule::dump(int fd, const Vector<String16>& args)
779{
780    const size_t SIZE = 256;
781    char buffer[SIZE];
782    String8 result;
783
784    snprintf(buffer, SIZE, "\tEffect ID %d:\n", mId);
785    result.append(buffer);
786
787    bool locked = AudioFlinger::dumpTryLock(mLock);
788    // failed to lock - AudioFlinger is probably deadlocked
789    if (!locked) {
790        result.append("\t\tCould not lock Fx mutex:\n");
791    }
792
793    result.append("\t\tSession Status State Engine:\n");
794    snprintf(buffer, SIZE, "\t\t%05d   %03d    %03d   0x%08x\n",
795            mSessionId, mStatus, mState, (uint32_t)mEffectInterface);
796    result.append(buffer);
797
798    result.append("\t\tDescriptor:\n");
799    snprintf(buffer, SIZE, "\t\t- UUID: %08X-%04X-%04X-%04X-%02X%02X%02X%02X%02X%02X\n",
800            mDescriptor.uuid.timeLow, mDescriptor.uuid.timeMid, mDescriptor.uuid.timeHiAndVersion,
801            mDescriptor.uuid.clockSeq, mDescriptor.uuid.node[0], mDescriptor.uuid.node[1],
802                    mDescriptor.uuid.node[2],
803            mDescriptor.uuid.node[3],mDescriptor.uuid.node[4],mDescriptor.uuid.node[5]);
804    result.append(buffer);
805    snprintf(buffer, SIZE, "\t\t- TYPE: %08X-%04X-%04X-%04X-%02X%02X%02X%02X%02X%02X\n",
806                mDescriptor.type.timeLow, mDescriptor.type.timeMid,
807                    mDescriptor.type.timeHiAndVersion,
808                mDescriptor.type.clockSeq, mDescriptor.type.node[0], mDescriptor.type.node[1],
809                    mDescriptor.type.node[2],
810                mDescriptor.type.node[3],mDescriptor.type.node[4],mDescriptor.type.node[5]);
811    result.append(buffer);
812    snprintf(buffer, SIZE, "\t\t- apiVersion: %08X\n\t\t- flags: %08X\n",
813            mDescriptor.apiVersion,
814            mDescriptor.flags);
815    result.append(buffer);
816    snprintf(buffer, SIZE, "\t\t- name: %s\n",
817            mDescriptor.name);
818    result.append(buffer);
819    snprintf(buffer, SIZE, "\t\t- implementor: %s\n",
820            mDescriptor.implementor);
821    result.append(buffer);
822
823    result.append("\t\t- Input configuration:\n");
824    result.append("\t\t\tBuffer     Frames  Smp rate Channels Format\n");
825    snprintf(buffer, SIZE, "\t\t\t0x%08x %05d   %05d    %08x %d\n",
826            (uint32_t)mConfig.inputCfg.buffer.raw,
827            mConfig.inputCfg.buffer.frameCount,
828            mConfig.inputCfg.samplingRate,
829            mConfig.inputCfg.channels,
830            mConfig.inputCfg.format);
831    result.append(buffer);
832
833    result.append("\t\t- Output configuration:\n");
834    result.append("\t\t\tBuffer     Frames  Smp rate Channels Format\n");
835    snprintf(buffer, SIZE, "\t\t\t0x%08x %05d   %05d    %08x %d\n",
836            (uint32_t)mConfig.outputCfg.buffer.raw,
837            mConfig.outputCfg.buffer.frameCount,
838            mConfig.outputCfg.samplingRate,
839            mConfig.outputCfg.channels,
840            mConfig.outputCfg.format);
841    result.append(buffer);
842
843    snprintf(buffer, SIZE, "\t\t%d Clients:\n", mHandles.size());
844    result.append(buffer);
845    result.append("\t\t\tPid   Priority Ctrl Locked client server\n");
846    for (size_t i = 0; i < mHandles.size(); ++i) {
847        EffectHandle *handle = mHandles[i];
848        if (handle != NULL && !handle->destroyed_l()) {
849            handle->dump(buffer, SIZE);
850            result.append(buffer);
851        }
852    }
853
854    result.append("\n");
855
856    write(fd, result.string(), result.length());
857
858    if (locked) {
859        mLock.unlock();
860    }
861}
862
863// ----------------------------------------------------------------------------
864//  EffectHandle implementation
865// ----------------------------------------------------------------------------
866
867#undef LOG_TAG
868#define LOG_TAG "AudioFlinger::EffectHandle"
869
870AudioFlinger::EffectHandle::EffectHandle(const sp<EffectModule>& effect,
871                                        const sp<AudioFlinger::Client>& client,
872                                        const sp<IEffectClient>& effectClient,
873                                        int32_t priority)
874    : BnEffect(),
875    mEffect(effect), mEffectClient(effectClient), mClient(client), mCblk(NULL),
876    mPriority(priority), mHasControl(false), mEnabled(false), mDestroyed(false)
877{
878    ALOGV("constructor %p", this);
879
880    if (client == 0) {
881        return;
882    }
883    int bufOffset = ((sizeof(effect_param_cblk_t) - 1) / sizeof(int) + 1) * sizeof(int);
884    mCblkMemory = client->heap()->allocate(EFFECT_PARAM_BUFFER_SIZE + bufOffset);
885    if (mCblkMemory != 0) {
886        mCblk = static_cast<effect_param_cblk_t *>(mCblkMemory->pointer());
887
888        if (mCblk != NULL) {
889            new(mCblk) effect_param_cblk_t();
890            mBuffer = (uint8_t *)mCblk + bufOffset;
891        }
892    } else {
893        ALOGE("not enough memory for Effect size=%u", EFFECT_PARAM_BUFFER_SIZE +
894                sizeof(effect_param_cblk_t));
895        return;
896    }
897}
898
899AudioFlinger::EffectHandle::~EffectHandle()
900{
901    ALOGV("Destructor %p", this);
902
903    if (mEffect == 0) {
904        mDestroyed = true;
905        return;
906    }
907    mEffect->lock();
908    mDestroyed = true;
909    mEffect->unlock();
910    disconnect(false);
911}
912
913status_t AudioFlinger::EffectHandle::enable()
914{
915    ALOGV("enable %p", this);
916    if (!mHasControl) {
917        return INVALID_OPERATION;
918    }
919    if (mEffect == 0) {
920        return DEAD_OBJECT;
921    }
922
923    if (mEnabled) {
924        return NO_ERROR;
925    }
926
927    mEnabled = true;
928
929    sp<ThreadBase> thread = mEffect->thread().promote();
930    if (thread != 0) {
931        thread->checkSuspendOnEffectEnabled(mEffect, true, mEffect->sessionId());
932    }
933
934    // checkSuspendOnEffectEnabled() can suspend this same effect when enabled
935    if (mEffect->suspended()) {
936        return NO_ERROR;
937    }
938
939    status_t status = mEffect->setEnabled(true);
940    if (status != NO_ERROR) {
941        if (thread != 0) {
942            thread->checkSuspendOnEffectEnabled(mEffect, false, mEffect->sessionId());
943        }
944        mEnabled = false;
945    }
946    return status;
947}
948
949status_t AudioFlinger::EffectHandle::disable()
950{
951    ALOGV("disable %p", this);
952    if (!mHasControl) {
953        return INVALID_OPERATION;
954    }
955    if (mEffect == 0) {
956        return DEAD_OBJECT;
957    }
958
959    if (!mEnabled) {
960        return NO_ERROR;
961    }
962    mEnabled = false;
963
964    if (mEffect->suspended()) {
965        return NO_ERROR;
966    }
967
968    status_t status = mEffect->setEnabled(false);
969
970    sp<ThreadBase> thread = mEffect->thread().promote();
971    if (thread != 0) {
972        thread->checkSuspendOnEffectEnabled(mEffect, false, mEffect->sessionId());
973    }
974
975    return status;
976}
977
978void AudioFlinger::EffectHandle::disconnect()
979{
980    disconnect(true);
981}
982
983void AudioFlinger::EffectHandle::disconnect(bool unpinIfLast)
984{
985    ALOGV("disconnect(%s)", unpinIfLast ? "true" : "false");
986    if (mEffect == 0) {
987        return;
988    }
989    // restore suspended effects if the disconnected handle was enabled and the last one.
990    if ((mEffect->disconnect(this, unpinIfLast) == 0) && mEnabled) {
991        sp<ThreadBase> thread = mEffect->thread().promote();
992        if (thread != 0) {
993            thread->checkSuspendOnEffectEnabled(mEffect, false, mEffect->sessionId());
994        }
995    }
996
997    // release sp on module => module destructor can be called now
998    mEffect.clear();
999    if (mClient != 0) {
1000        if (mCblk != NULL) {
1001            // unlike ~TrackBase(), mCblk is never a local new, so don't delete
1002            mCblk->~effect_param_cblk_t();   // destroy our shared-structure.
1003        }
1004        mCblkMemory.clear();    // free the shared memory before releasing the heap it belongs to
1005        // Client destructor must run with AudioFlinger mutex locked
1006        Mutex::Autolock _l(mClient->audioFlinger()->mLock);
1007        mClient.clear();
1008    }
1009}
1010
1011status_t AudioFlinger::EffectHandle::command(uint32_t cmdCode,
1012                                             uint32_t cmdSize,
1013                                             void *pCmdData,
1014                                             uint32_t *replySize,
1015                                             void *pReplyData)
1016{
1017    ALOGVV("command(), cmdCode: %d, mHasControl: %d, mEffect: %p",
1018            cmdCode, mHasControl, (mEffect == 0) ? 0 : mEffect.get());
1019
1020    // only get parameter command is permitted for applications not controlling the effect
1021    if (!mHasControl && cmdCode != EFFECT_CMD_GET_PARAM) {
1022        return INVALID_OPERATION;
1023    }
1024    if (mEffect == 0) {
1025        return DEAD_OBJECT;
1026    }
1027    if (mClient == 0) {
1028        return INVALID_OPERATION;
1029    }
1030
1031    // handle commands that are not forwarded transparently to effect engine
1032    if (cmdCode == EFFECT_CMD_SET_PARAM_COMMIT) {
1033        // No need to trylock() here as this function is executed in the binder thread serving a
1034        // particular client process:  no risk to block the whole media server process or mixer
1035        // threads if we are stuck here
1036        Mutex::Autolock _l(mCblk->lock);
1037        if (mCblk->clientIndex > EFFECT_PARAM_BUFFER_SIZE ||
1038            mCblk->serverIndex > EFFECT_PARAM_BUFFER_SIZE) {
1039            mCblk->serverIndex = 0;
1040            mCblk->clientIndex = 0;
1041            return BAD_VALUE;
1042        }
1043        status_t status = NO_ERROR;
1044        while (mCblk->serverIndex < mCblk->clientIndex) {
1045            int reply;
1046            uint32_t rsize = sizeof(int);
1047            int *p = (int *)(mBuffer + mCblk->serverIndex);
1048            int size = *p++;
1049            if (((uint8_t *)p + size) > mBuffer + mCblk->clientIndex) {
1050                ALOGW("command(): invalid parameter block size");
1051                break;
1052            }
1053            effect_param_t *param = (effect_param_t *)p;
1054            if (param->psize == 0 || param->vsize == 0) {
1055                ALOGW("command(): null parameter or value size");
1056                mCblk->serverIndex += size;
1057                continue;
1058            }
1059            uint32_t psize = sizeof(effect_param_t) +
1060                             ((param->psize - 1) / sizeof(int) + 1) * sizeof(int) +
1061                             param->vsize;
1062            status_t ret = mEffect->command(EFFECT_CMD_SET_PARAM,
1063                                            psize,
1064                                            p,
1065                                            &rsize,
1066                                            &reply);
1067            // stop at first error encountered
1068            if (ret != NO_ERROR) {
1069                status = ret;
1070                *(int *)pReplyData = reply;
1071                break;
1072            } else if (reply != NO_ERROR) {
1073                *(int *)pReplyData = reply;
1074                break;
1075            }
1076            mCblk->serverIndex += size;
1077        }
1078        mCblk->serverIndex = 0;
1079        mCblk->clientIndex = 0;
1080        return status;
1081    } else if (cmdCode == EFFECT_CMD_ENABLE) {
1082        *(int *)pReplyData = NO_ERROR;
1083        return enable();
1084    } else if (cmdCode == EFFECT_CMD_DISABLE) {
1085        *(int *)pReplyData = NO_ERROR;
1086        return disable();
1087    }
1088
1089    return mEffect->command(cmdCode, cmdSize, pCmdData, replySize, pReplyData);
1090}
1091
1092void AudioFlinger::EffectHandle::setControl(bool hasControl, bool signal, bool enabled)
1093{
1094    ALOGV("setControl %p control %d", this, hasControl);
1095
1096    mHasControl = hasControl;
1097    mEnabled = enabled;
1098
1099    if (signal && mEffectClient != 0) {
1100        mEffectClient->controlStatusChanged(hasControl);
1101    }
1102}
1103
1104void AudioFlinger::EffectHandle::commandExecuted(uint32_t cmdCode,
1105                                                 uint32_t cmdSize,
1106                                                 void *pCmdData,
1107                                                 uint32_t replySize,
1108                                                 void *pReplyData)
1109{
1110    if (mEffectClient != 0) {
1111        mEffectClient->commandExecuted(cmdCode, cmdSize, pCmdData, replySize, pReplyData);
1112    }
1113}
1114
1115
1116
1117void AudioFlinger::EffectHandle::setEnabled(bool enabled)
1118{
1119    if (mEffectClient != 0) {
1120        mEffectClient->enableStatusChanged(enabled);
1121    }
1122}
1123
1124status_t AudioFlinger::EffectHandle::onTransact(
1125    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
1126{
1127    return BnEffect::onTransact(code, data, reply, flags);
1128}
1129
1130
1131void AudioFlinger::EffectHandle::dump(char* buffer, size_t size)
1132{
1133    bool locked = mCblk != NULL && AudioFlinger::dumpTryLock(mCblk->lock);
1134
1135    snprintf(buffer, size, "\t\t\t%05d %05d    %01u    %01u      %05u  %05u\n",
1136            (mClient == 0) ? getpid_cached : mClient->pid(),
1137            mPriority,
1138            mHasControl,
1139            !locked,
1140            mCblk ? mCblk->clientIndex : 0,
1141            mCblk ? mCblk->serverIndex : 0
1142            );
1143
1144    if (locked) {
1145        mCblk->lock.unlock();
1146    }
1147}
1148
1149#undef LOG_TAG
1150#define LOG_TAG "AudioFlinger::EffectChain"
1151
1152AudioFlinger::EffectChain::EffectChain(ThreadBase *thread,
1153                                        int sessionId)
1154    : mThread(thread), mSessionId(sessionId), mActiveTrackCnt(0), mTrackCnt(0), mTailBufferCount(0),
1155      mOwnInBuffer(false), mVolumeCtrlIdx(-1), mLeftVolume(UINT_MAX), mRightVolume(UINT_MAX),
1156      mNewLeftVolume(UINT_MAX), mNewRightVolume(UINT_MAX)
1157{
1158    mStrategy = AudioSystem::getStrategyForStream(AUDIO_STREAM_MUSIC);
1159    if (thread == NULL) {
1160        return;
1161    }
1162    mMaxTailBuffers = ((kProcessTailDurationMs * thread->sampleRate()) / 1000) /
1163                                    thread->frameCount();
1164}
1165
1166AudioFlinger::EffectChain::~EffectChain()
1167{
1168    if (mOwnInBuffer) {
1169        delete mInBuffer;
1170    }
1171
1172}
1173
1174// getEffectFromDesc_l() must be called with ThreadBase::mLock held
1175sp<AudioFlinger::EffectModule> AudioFlinger::EffectChain::getEffectFromDesc_l(
1176        effect_descriptor_t *descriptor)
1177{
1178    size_t size = mEffects.size();
1179
1180    for (size_t i = 0; i < size; i++) {
1181        if (memcmp(&mEffects[i]->desc().uuid, &descriptor->uuid, sizeof(effect_uuid_t)) == 0) {
1182            return mEffects[i];
1183        }
1184    }
1185    return 0;
1186}
1187
1188// getEffectFromId_l() must be called with ThreadBase::mLock held
1189sp<AudioFlinger::EffectModule> AudioFlinger::EffectChain::getEffectFromId_l(int id)
1190{
1191    size_t size = mEffects.size();
1192
1193    for (size_t i = 0; i < size; i++) {
1194        // by convention, return first effect if id provided is 0 (0 is never a valid id)
1195        if (id == 0 || mEffects[i]->id() == id) {
1196            return mEffects[i];
1197        }
1198    }
1199    return 0;
1200}
1201
1202// getEffectFromType_l() must be called with ThreadBase::mLock held
1203sp<AudioFlinger::EffectModule> AudioFlinger::EffectChain::getEffectFromType_l(
1204        const effect_uuid_t *type)
1205{
1206    size_t size = mEffects.size();
1207
1208    for (size_t i = 0; i < size; i++) {
1209        if (memcmp(&mEffects[i]->desc().type, type, sizeof(effect_uuid_t)) == 0) {
1210            return mEffects[i];
1211        }
1212    }
1213    return 0;
1214}
1215
1216void AudioFlinger::EffectChain::clearInputBuffer()
1217{
1218    Mutex::Autolock _l(mLock);
1219    sp<ThreadBase> thread = mThread.promote();
1220    if (thread == 0) {
1221        ALOGW("clearInputBuffer(): cannot promote mixer thread");
1222        return;
1223    }
1224    clearInputBuffer_l(thread);
1225}
1226
1227// Must be called with EffectChain::mLock locked
1228void AudioFlinger::EffectChain::clearInputBuffer_l(sp<ThreadBase> thread)
1229{
1230    memset(mInBuffer, 0, thread->frameCount() * thread->frameSize());
1231}
1232
1233// Must be called with EffectChain::mLock locked
1234void AudioFlinger::EffectChain::process_l()
1235{
1236    sp<ThreadBase> thread = mThread.promote();
1237    if (thread == 0) {
1238        ALOGW("process_l(): cannot promote mixer thread");
1239        return;
1240    }
1241    bool isGlobalSession = (mSessionId == AUDIO_SESSION_OUTPUT_MIX) ||
1242            (mSessionId == AUDIO_SESSION_OUTPUT_STAGE);
1243    // always process effects unless no more tracks are on the session and the effect tail
1244    // has been rendered
1245    bool doProcess = true;
1246    if (!isGlobalSession) {
1247        bool tracksOnSession = (trackCnt() != 0);
1248
1249        if (!tracksOnSession && mTailBufferCount == 0) {
1250            doProcess = false;
1251        }
1252
1253        if (activeTrackCnt() == 0) {
1254            // if no track is active and the effect tail has not been rendered,
1255            // the input buffer must be cleared here as the mixer process will not do it
1256            if (tracksOnSession || mTailBufferCount > 0) {
1257                clearInputBuffer_l(thread);
1258                if (mTailBufferCount > 0) {
1259                    mTailBufferCount--;
1260                }
1261            }
1262        }
1263    }
1264
1265    size_t size = mEffects.size();
1266    if (doProcess) {
1267        for (size_t i = 0; i < size; i++) {
1268            mEffects[i]->process();
1269        }
1270    }
1271    for (size_t i = 0; i < size; i++) {
1272        mEffects[i]->updateState();
1273    }
1274}
1275
1276// addEffect_l() must be called with PlaybackThread::mLock held
1277status_t AudioFlinger::EffectChain::addEffect_l(const sp<EffectModule>& effect)
1278{
1279    effect_descriptor_t desc = effect->desc();
1280    uint32_t insertPref = desc.flags & EFFECT_FLAG_INSERT_MASK;
1281
1282    Mutex::Autolock _l(mLock);
1283    effect->setChain(this);
1284    sp<ThreadBase> thread = mThread.promote();
1285    if (thread == 0) {
1286        return NO_INIT;
1287    }
1288    effect->setThread(thread);
1289
1290    if ((desc.flags & EFFECT_FLAG_TYPE_MASK) == EFFECT_FLAG_TYPE_AUXILIARY) {
1291        // Auxiliary effects are inserted at the beginning of mEffects vector as
1292        // they are processed first and accumulated in chain input buffer
1293        mEffects.insertAt(effect, 0);
1294
1295        // the input buffer for auxiliary effect contains mono samples in
1296        // 32 bit format. This is to avoid saturation in AudoMixer
1297        // accumulation stage. Saturation is done in EffectModule::process() before
1298        // calling the process in effect engine
1299        size_t numSamples = thread->frameCount();
1300        int32_t *buffer = new int32_t[numSamples];
1301        memset(buffer, 0, numSamples * sizeof(int32_t));
1302        effect->setInBuffer((int16_t *)buffer);
1303        // auxiliary effects output samples to chain input buffer for further processing
1304        // by insert effects
1305        effect->setOutBuffer(mInBuffer);
1306    } else {
1307        // Insert effects are inserted at the end of mEffects vector as they are processed
1308        //  after track and auxiliary effects.
1309        // Insert effect order as a function of indicated preference:
1310        //  if EFFECT_FLAG_INSERT_EXCLUSIVE, insert in first position or reject if
1311        //  another effect is present
1312        //  else if EFFECT_FLAG_INSERT_FIRST, insert in first position or after the
1313        //  last effect claiming first position
1314        //  else if EFFECT_FLAG_INSERT_LAST, insert in last position or before the
1315        //  first effect claiming last position
1316        //  else if EFFECT_FLAG_INSERT_ANY insert after first or before last
1317        // Reject insertion if an effect with EFFECT_FLAG_INSERT_EXCLUSIVE is
1318        // already present
1319
1320        size_t size = mEffects.size();
1321        size_t idx_insert = size;
1322        ssize_t idx_insert_first = -1;
1323        ssize_t idx_insert_last = -1;
1324
1325        for (size_t i = 0; i < size; i++) {
1326            effect_descriptor_t d = mEffects[i]->desc();
1327            uint32_t iMode = d.flags & EFFECT_FLAG_TYPE_MASK;
1328            uint32_t iPref = d.flags & EFFECT_FLAG_INSERT_MASK;
1329            if (iMode == EFFECT_FLAG_TYPE_INSERT) {
1330                // check invalid effect chaining combinations
1331                if (insertPref == EFFECT_FLAG_INSERT_EXCLUSIVE ||
1332                    iPref == EFFECT_FLAG_INSERT_EXCLUSIVE) {
1333                    ALOGW("addEffect_l() could not insert effect %s: exclusive conflict with %s",
1334                            desc.name, d.name);
1335                    return INVALID_OPERATION;
1336                }
1337                // remember position of first insert effect and by default
1338                // select this as insert position for new effect
1339                if (idx_insert == size) {
1340                    idx_insert = i;
1341                }
1342                // remember position of last insert effect claiming
1343                // first position
1344                if (iPref == EFFECT_FLAG_INSERT_FIRST) {
1345                    idx_insert_first = i;
1346                }
1347                // remember position of first insert effect claiming
1348                // last position
1349                if (iPref == EFFECT_FLAG_INSERT_LAST &&
1350                    idx_insert_last == -1) {
1351                    idx_insert_last = i;
1352                }
1353            }
1354        }
1355
1356        // modify idx_insert from first position if needed
1357        if (insertPref == EFFECT_FLAG_INSERT_LAST) {
1358            if (idx_insert_last != -1) {
1359                idx_insert = idx_insert_last;
1360            } else {
1361                idx_insert = size;
1362            }
1363        } else {
1364            if (idx_insert_first != -1) {
1365                idx_insert = idx_insert_first + 1;
1366            }
1367        }
1368
1369        // always read samples from chain input buffer
1370        effect->setInBuffer(mInBuffer);
1371
1372        // if last effect in the chain, output samples to chain
1373        // output buffer, otherwise to chain input buffer
1374        if (idx_insert == size) {
1375            if (idx_insert != 0) {
1376                mEffects[idx_insert-1]->setOutBuffer(mInBuffer);
1377                mEffects[idx_insert-1]->configure();
1378            }
1379            effect->setOutBuffer(mOutBuffer);
1380        } else {
1381            effect->setOutBuffer(mInBuffer);
1382        }
1383        mEffects.insertAt(effect, idx_insert);
1384
1385        ALOGV("addEffect_l() effect %p, added in chain %p at rank %d", effect.get(), this,
1386                idx_insert);
1387    }
1388    effect->configure();
1389    return NO_ERROR;
1390}
1391
1392// removeEffect_l() must be called with PlaybackThread::mLock held
1393size_t AudioFlinger::EffectChain::removeEffect_l(const sp<EffectModule>& effect)
1394{
1395    Mutex::Autolock _l(mLock);
1396    size_t size = mEffects.size();
1397    uint32_t type = effect->desc().flags & EFFECT_FLAG_TYPE_MASK;
1398
1399    for (size_t i = 0; i < size; i++) {
1400        if (effect == mEffects[i]) {
1401            // calling stop here will remove pre-processing effect from the audio HAL.
1402            // This is safe as we hold the EffectChain mutex which guarantees that we are not in
1403            // the middle of a read from audio HAL
1404            if (mEffects[i]->state() == EffectModule::ACTIVE ||
1405                    mEffects[i]->state() == EffectModule::STOPPING) {
1406                mEffects[i]->stop();
1407            }
1408            if (type == EFFECT_FLAG_TYPE_AUXILIARY) {
1409                delete[] effect->inBuffer();
1410            } else {
1411                if (i == size - 1 && i != 0) {
1412                    mEffects[i - 1]->setOutBuffer(mOutBuffer);
1413                    mEffects[i - 1]->configure();
1414                }
1415            }
1416            mEffects.removeAt(i);
1417            ALOGV("removeEffect_l() effect %p, removed from chain %p at rank %d", effect.get(),
1418                    this, i);
1419            break;
1420        }
1421    }
1422
1423    return mEffects.size();
1424}
1425
1426// setDevice_l() must be called with PlaybackThread::mLock held
1427void AudioFlinger::EffectChain::setDevice_l(audio_devices_t device)
1428{
1429    size_t size = mEffects.size();
1430    for (size_t i = 0; i < size; i++) {
1431        mEffects[i]->setDevice(device);
1432    }
1433}
1434
1435// setMode_l() must be called with PlaybackThread::mLock held
1436void AudioFlinger::EffectChain::setMode_l(audio_mode_t mode)
1437{
1438    size_t size = mEffects.size();
1439    for (size_t i = 0; i < size; i++) {
1440        mEffects[i]->setMode(mode);
1441    }
1442}
1443
1444// setAudioSource_l() must be called with PlaybackThread::mLock held
1445void AudioFlinger::EffectChain::setAudioSource_l(audio_source_t source)
1446{
1447    size_t size = mEffects.size();
1448    for (size_t i = 0; i < size; i++) {
1449        mEffects[i]->setAudioSource(source);
1450    }
1451}
1452
1453// setVolume_l() must be called with PlaybackThread::mLock held
1454bool AudioFlinger::EffectChain::setVolume_l(uint32_t *left, uint32_t *right)
1455{
1456    uint32_t newLeft = *left;
1457    uint32_t newRight = *right;
1458    bool hasControl = false;
1459    int ctrlIdx = -1;
1460    size_t size = mEffects.size();
1461
1462    // first update volume controller
1463    for (size_t i = size; i > 0; i--) {
1464        if (mEffects[i - 1]->isProcessEnabled() &&
1465            (mEffects[i - 1]->desc().flags & EFFECT_FLAG_VOLUME_MASK) == EFFECT_FLAG_VOLUME_CTRL) {
1466            ctrlIdx = i - 1;
1467            hasControl = true;
1468            break;
1469        }
1470    }
1471
1472    if (ctrlIdx == mVolumeCtrlIdx && *left == mLeftVolume && *right == mRightVolume) {
1473        if (hasControl) {
1474            *left = mNewLeftVolume;
1475            *right = mNewRightVolume;
1476        }
1477        return hasControl;
1478    }
1479
1480    mVolumeCtrlIdx = ctrlIdx;
1481    mLeftVolume = newLeft;
1482    mRightVolume = newRight;
1483
1484    // second get volume update from volume controller
1485    if (ctrlIdx >= 0) {
1486        mEffects[ctrlIdx]->setVolume(&newLeft, &newRight, true);
1487        mNewLeftVolume = newLeft;
1488        mNewRightVolume = newRight;
1489    }
1490    // then indicate volume to all other effects in chain.
1491    // Pass altered volume to effects before volume controller
1492    // and requested volume to effects after controller
1493    uint32_t lVol = newLeft;
1494    uint32_t rVol = newRight;
1495
1496    for (size_t i = 0; i < size; i++) {
1497        if ((int)i == ctrlIdx) {
1498            continue;
1499        }
1500        // this also works for ctrlIdx == -1 when there is no volume controller
1501        if ((int)i > ctrlIdx) {
1502            lVol = *left;
1503            rVol = *right;
1504        }
1505        mEffects[i]->setVolume(&lVol, &rVol, false);
1506    }
1507    *left = newLeft;
1508    *right = newRight;
1509
1510    return hasControl;
1511}
1512
1513void AudioFlinger::EffectChain::dump(int fd, const Vector<String16>& args)
1514{
1515    const size_t SIZE = 256;
1516    char buffer[SIZE];
1517    String8 result;
1518
1519    snprintf(buffer, SIZE, "Effects for session %d:\n", mSessionId);
1520    result.append(buffer);
1521
1522    bool locked = AudioFlinger::dumpTryLock(mLock);
1523    // failed to lock - AudioFlinger is probably deadlocked
1524    if (!locked) {
1525        result.append("\tCould not lock mutex:\n");
1526    }
1527
1528    result.append("\tNum fx In buffer   Out buffer   Active tracks:\n");
1529    snprintf(buffer, SIZE, "\t%02d     0x%08x  0x%08x   %d\n",
1530            mEffects.size(),
1531            (uint32_t)mInBuffer,
1532            (uint32_t)mOutBuffer,
1533            mActiveTrackCnt);
1534    result.append(buffer);
1535    write(fd, result.string(), result.size());
1536
1537    for (size_t i = 0; i < mEffects.size(); ++i) {
1538        sp<EffectModule> effect = mEffects[i];
1539        if (effect != 0) {
1540            effect->dump(fd, args);
1541        }
1542    }
1543
1544    if (locked) {
1545        mLock.unlock();
1546    }
1547}
1548
1549// must be called with ThreadBase::mLock held
1550void AudioFlinger::EffectChain::setEffectSuspended_l(
1551        const effect_uuid_t *type, bool suspend)
1552{
1553    sp<SuspendedEffectDesc> desc;
1554    // use effect type UUID timelow as key as there is no real risk of identical
1555    // timeLow fields among effect type UUIDs.
1556    ssize_t index = mSuspendedEffects.indexOfKey(type->timeLow);
1557    if (suspend) {
1558        if (index >= 0) {
1559            desc = mSuspendedEffects.valueAt(index);
1560        } else {
1561            desc = new SuspendedEffectDesc();
1562            desc->mType = *type;
1563            mSuspendedEffects.add(type->timeLow, desc);
1564            ALOGV("setEffectSuspended_l() add entry for %08x", type->timeLow);
1565        }
1566        if (desc->mRefCount++ == 0) {
1567            sp<EffectModule> effect = getEffectIfEnabled(type);
1568            if (effect != 0) {
1569                desc->mEffect = effect;
1570                effect->setSuspended(true);
1571                effect->setEnabled(false);
1572            }
1573        }
1574    } else {
1575        if (index < 0) {
1576            return;
1577        }
1578        desc = mSuspendedEffects.valueAt(index);
1579        if (desc->mRefCount <= 0) {
1580            ALOGW("setEffectSuspended_l() restore refcount should not be 0 %d", desc->mRefCount);
1581            desc->mRefCount = 1;
1582        }
1583        if (--desc->mRefCount == 0) {
1584            ALOGV("setEffectSuspended_l() remove entry for %08x", mSuspendedEffects.keyAt(index));
1585            if (desc->mEffect != 0) {
1586                sp<EffectModule> effect = desc->mEffect.promote();
1587                if (effect != 0) {
1588                    effect->setSuspended(false);
1589                    effect->lock();
1590                    EffectHandle *handle = effect->controlHandle_l();
1591                    if (handle != NULL && !handle->destroyed_l()) {
1592                        effect->setEnabled_l(handle->enabled());
1593                    }
1594                    effect->unlock();
1595                }
1596                desc->mEffect.clear();
1597            }
1598            mSuspendedEffects.removeItemsAt(index);
1599        }
1600    }
1601}
1602
1603// must be called with ThreadBase::mLock held
1604void AudioFlinger::EffectChain::setEffectSuspendedAll_l(bool suspend)
1605{
1606    sp<SuspendedEffectDesc> desc;
1607
1608    ssize_t index = mSuspendedEffects.indexOfKey((int)kKeyForSuspendAll);
1609    if (suspend) {
1610        if (index >= 0) {
1611            desc = mSuspendedEffects.valueAt(index);
1612        } else {
1613            desc = new SuspendedEffectDesc();
1614            mSuspendedEffects.add((int)kKeyForSuspendAll, desc);
1615            ALOGV("setEffectSuspendedAll_l() add entry for 0");
1616        }
1617        if (desc->mRefCount++ == 0) {
1618            Vector< sp<EffectModule> > effects;
1619            getSuspendEligibleEffects(effects);
1620            for (size_t i = 0; i < effects.size(); i++) {
1621                setEffectSuspended_l(&effects[i]->desc().type, true);
1622            }
1623        }
1624    } else {
1625        if (index < 0) {
1626            return;
1627        }
1628        desc = mSuspendedEffects.valueAt(index);
1629        if (desc->mRefCount <= 0) {
1630            ALOGW("setEffectSuspendedAll_l() restore refcount should not be 0 %d", desc->mRefCount);
1631            desc->mRefCount = 1;
1632        }
1633        if (--desc->mRefCount == 0) {
1634            Vector<const effect_uuid_t *> types;
1635            for (size_t i = 0; i < mSuspendedEffects.size(); i++) {
1636                if (mSuspendedEffects.keyAt(i) == (int)kKeyForSuspendAll) {
1637                    continue;
1638                }
1639                types.add(&mSuspendedEffects.valueAt(i)->mType);
1640            }
1641            for (size_t i = 0; i < types.size(); i++) {
1642                setEffectSuspended_l(types[i], false);
1643            }
1644            ALOGV("setEffectSuspendedAll_l() remove entry for %08x",
1645                    mSuspendedEffects.keyAt(index));
1646            mSuspendedEffects.removeItem((int)kKeyForSuspendAll);
1647        }
1648    }
1649}
1650
1651
1652// The volume effect is used for automated tests only
1653#ifndef OPENSL_ES_H_
1654static const effect_uuid_t SL_IID_VOLUME_ = { 0x09e8ede0, 0xddde, 0x11db, 0xb4f6,
1655                                            { 0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b } };
1656const effect_uuid_t * const SL_IID_VOLUME = &SL_IID_VOLUME_;
1657#endif //OPENSL_ES_H_
1658
1659bool AudioFlinger::EffectChain::isEffectEligibleForSuspend(const effect_descriptor_t& desc)
1660{
1661    // auxiliary effects and visualizer are never suspended on output mix
1662    if ((mSessionId == AUDIO_SESSION_OUTPUT_MIX) &&
1663        (((desc.flags & EFFECT_FLAG_TYPE_MASK) == EFFECT_FLAG_TYPE_AUXILIARY) ||
1664         (memcmp(&desc.type, SL_IID_VISUALIZATION, sizeof(effect_uuid_t)) == 0) ||
1665         (memcmp(&desc.type, SL_IID_VOLUME, sizeof(effect_uuid_t)) == 0))) {
1666        return false;
1667    }
1668    return true;
1669}
1670
1671void AudioFlinger::EffectChain::getSuspendEligibleEffects(
1672        Vector< sp<AudioFlinger::EffectModule> > &effects)
1673{
1674    effects.clear();
1675    for (size_t i = 0; i < mEffects.size(); i++) {
1676        if (isEffectEligibleForSuspend(mEffects[i]->desc())) {
1677            effects.add(mEffects[i]);
1678        }
1679    }
1680}
1681
1682sp<AudioFlinger::EffectModule> AudioFlinger::EffectChain::getEffectIfEnabled(
1683                                                            const effect_uuid_t *type)
1684{
1685    sp<EffectModule> effect = getEffectFromType_l(type);
1686    return effect != 0 && effect->isEnabled() ? effect : 0;
1687}
1688
1689void AudioFlinger::EffectChain::checkSuspendOnEffectEnabled(const sp<EffectModule>& effect,
1690                                                            bool enabled)
1691{
1692    ssize_t index = mSuspendedEffects.indexOfKey(effect->desc().type.timeLow);
1693    if (enabled) {
1694        if (index < 0) {
1695            // if the effect is not suspend check if all effects are suspended
1696            index = mSuspendedEffects.indexOfKey((int)kKeyForSuspendAll);
1697            if (index < 0) {
1698                return;
1699            }
1700            if (!isEffectEligibleForSuspend(effect->desc())) {
1701                return;
1702            }
1703            setEffectSuspended_l(&effect->desc().type, enabled);
1704            index = mSuspendedEffects.indexOfKey(effect->desc().type.timeLow);
1705            if (index < 0) {
1706                ALOGW("checkSuspendOnEffectEnabled() Fx should be suspended here!");
1707                return;
1708            }
1709        }
1710        ALOGV("checkSuspendOnEffectEnabled() enable suspending fx %08x",
1711            effect->desc().type.timeLow);
1712        sp<SuspendedEffectDesc> desc = mSuspendedEffects.valueAt(index);
1713        // if effect is requested to suspended but was not yet enabled, supend it now.
1714        if (desc->mEffect == 0) {
1715            desc->mEffect = effect;
1716            effect->setEnabled(false);
1717            effect->setSuspended(true);
1718        }
1719    } else {
1720        if (index < 0) {
1721            return;
1722        }
1723        ALOGV("checkSuspendOnEffectEnabled() disable restoring fx %08x",
1724            effect->desc().type.timeLow);
1725        sp<SuspendedEffectDesc> desc = mSuspendedEffects.valueAt(index);
1726        desc->mEffect.clear();
1727        effect->setSuspended(false);
1728    }
1729}
1730
1731}; // namespace android
1732