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