• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
47 namespace android {
48 
49 // ----------------------------------------------------------------------------
50 //  EffectModule implementation
51 // ----------------------------------------------------------------------------
52 
53 #undef LOG_TAG
54 #define LOG_TAG "AudioFlinger::EffectModule"
55 
EffectModule(ThreadBase * thread,const wp<AudioFlinger::EffectChain> & chain,effect_descriptor_t * desc,int id,int sessionId)56 AudioFlinger::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;
88 Error:
89     EffectRelease(mEffectInterface);
90     mEffectInterface = NULL;
91     ALOGV("Constructor Error %d", mStatus);
92 }
93 
~EffectModule()94 AudioFlinger::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 
addHandle(EffectHandle * handle)104 status_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 
removeHandle(EffectHandle * handle)142 size_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
controlHandle_l()177 AudioFlinger::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 
disconnect(EffectHandle * handle,bool unpinIfLast)190 size_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 
updateState()205 void 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 
process()247 void 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 
reset_l()296 void 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 
configure()304 status_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 
404 exit:
405     mStatus = status;
406     return status;
407 }
408 
init()409 status_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 
start()429 status_t AudioFlinger::EffectModule::start()
430 {
431     Mutex::Autolock _l(mLock);
432     return start_l();
433 }
434 
start_l()435 status_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 
stop()468 status_t AudioFlinger::EffectModule::stop()
469 {
470     Mutex::Autolock _l(mLock);
471     return stop_l();
472 }
473 
stop_l()474 status_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 
remove_effect_from_hal_l()499 status_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 
command(uint32_t cmdCode,uint32_t cmdSize,void * pCmdData,uint32_t * replySize,void * pReplyData)514 status_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 
setEnabled(bool enabled)547 status_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
setEnabled_l(bool enabled)554 status_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 
isEnabled() const600 bool 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 
isProcessEnabled() const616 bool 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 
setVolume(uint32_t * left,uint32_t * right,bool controller)636 status_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 
setDevice(audio_devices_t device)671 status_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 
setMode(audio_mode_t mode)697 status_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 
setAudioSource(audio_source_t source)720 status_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 
setSuspended(bool suspended)739 void AudioFlinger::EffectModule::setSuspended(bool suspended)
740 {
741     Mutex::Autolock _l(mLock);
742     mSuspended = suspended;
743 }
744 
suspended() const745 bool AudioFlinger::EffectModule::suspended() const
746 {
747     Mutex::Autolock _l(mLock);
748     return mSuspended;
749 }
750 
purgeHandles()751 bool 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 
setOffloaded(bool offloaded,audio_io_handle_t io)767 status_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 
isOffloaded() const801 bool AudioFlinger::EffectModule::isOffloaded() const
802 {
803     Mutex::Autolock _l(mLock);
804     return mOffloaded;
805 }
806 
dump(int fd,const Vector<String16> & args)807 void 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   0x%08x\n",
824             mSessionId, mStatus, mState, (uint32_t)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\tBuffer     Frames  Smp rate Channels Format\n");
854     snprintf(buffer, SIZE, "\t\t\t0x%08x %05d   %05d    %08x %d\n",
855             (uint32_t)mConfig.inputCfg.buffer.raw,
856             mConfig.inputCfg.buffer.frameCount,
857             mConfig.inputCfg.samplingRate,
858             mConfig.inputCfg.channels,
859             mConfig.inputCfg.format);
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\t0x%08x %05d   %05d    %08x %d\n",
865             (uint32_t)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%d 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 
EffectHandle(const sp<EffectModule> & effect,const sp<AudioFlinger::Client> & client,const sp<IEffectClient> & effectClient,int32_t priority)899 AudioFlinger::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 
~EffectHandle()928 AudioFlinger::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 
enable()942 status_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 
disable()995 status_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 
disconnect()1029 void AudioFlinger::EffectHandle::disconnect()
1030 {
1031     disconnect(true);
1032 }
1033 
disconnect(bool unpinIfLast)1034 void 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 
command(uint32_t cmdCode,uint32_t cmdSize,void * pCmdData,uint32_t * replySize,void * pReplyData)1062 status_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 
setControl(bool hasControl,bool signal,bool enabled)1143 void 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 
commandExecuted(uint32_t cmdCode,uint32_t cmdSize,void * pCmdData,uint32_t replySize,void * pReplyData)1155 void 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 
setEnabled(bool enabled)1168 void AudioFlinger::EffectHandle::setEnabled(bool enabled)
1169 {
1170     if (mEffectClient != 0) {
1171         mEffectClient->enableStatusChanged(enabled);
1172     }
1173 }
1174 
onTransact(uint32_t code,const Parcel & data,Parcel * reply,uint32_t flags)1175 status_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 
dump(char * buffer,size_t size)1182 void 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 
EffectChain(ThreadBase * thread,int sessionId)1203 AudioFlinger::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 
~EffectChain()1217 AudioFlinger::EffectChain::~EffectChain()
1218 {
1219     if (mOwnInBuffer) {
1220         delete mInBuffer;
1221     }
1222 
1223 }
1224 
1225 // getEffectFromDesc_l() must be called with ThreadBase::mLock held
getEffectFromDesc_l(effect_descriptor_t * descriptor)1226 sp<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
getEffectFromId_l(int id)1240 sp<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
getEffectFromType_l(const effect_uuid_t * type)1254 sp<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 
clearInputBuffer()1267 void 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
clearInputBuffer_l(sp<ThreadBase> thread)1279 void 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
process_l()1285 void 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
addEffect_l(const sp<EffectModule> & effect)1329 status_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
removeEffect_l(const sp<EffectModule> & effect)1445 size_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
setDevice_l(audio_devices_t device)1479 void 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
setMode_l(audio_mode_t mode)1488 void 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
setAudioSource_l(audio_source_t source)1497 void 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
setVolume_l(uint32_t * left,uint32_t * right)1506 bool 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 
dump(int fd,const Vector<String16> & args)1565 void 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%02d     0x%08x  0x%08x   %d\n",
1582             mEffects.size(),
1583             (uint32_t)mInBuffer,
1584             (uint32_t)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
setEffectSuspended_l(const effect_uuid_t * type,bool suspend)1602 void 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
setEffectSuspendedAll_l(bool suspend)1656 void 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_
1706 static const effect_uuid_t SL_IID_VOLUME_ = { 0x09e8ede0, 0xddde, 0x11db, 0xb4f6,
1707                                             { 0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b } };
1708 const effect_uuid_t * const SL_IID_VOLUME = &SL_IID_VOLUME_;
1709 #endif //OPENSL_ES_H_
1710 
isEffectEligibleForSuspend(const effect_descriptor_t & desc)1711 bool 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 
getSuspendEligibleEffects(Vector<sp<AudioFlinger::EffectModule>> & effects)1723 void 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 
getEffectIfEnabled(const effect_uuid_t * type)1734 sp<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 
checkSuspendOnEffectEnabled(const sp<EffectModule> & effect,bool enabled)1741 void 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 
isNonOffloadableEnabled()1783 bool 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