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