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