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