android_Effect.cpp revision 759687c36cbeaaa40408960eafa3ffd14e76cbc6
1/* 2 * Copyright (C) 2010 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 18#include "sles_allinclusive.h" 19#include "math.h" 20#include "utils/RefBase.h" 21#include <audio_effects/effect_bassboost.h> 22#include <audio_effects/effect_equalizer.h> 23#include <audio_effects/effect_environmentalreverb.h> 24#include <audio_effects/effect_presetreverb.h> 25#include <audio_effects/effect_virtualizer.h> 26 27#include <audio_effects/effect_aec.h> 28#include <audio_effects/effect_agc.h> 29#include <audio_effects/effect_ns.h> 30 31#include <system/audio.h> 32 33static const int EQUALIZER_PARAM_SIZE_MAX = sizeof(effect_param_t) + 2 * sizeof(int32_t) 34 + EFFECT_STRING_LEN_MAX; 35 36static const int BASSBOOST_PARAM_SIZE_MAX = sizeof(effect_param_t) + 2 * sizeof(int32_t); 37 38static const int VIRTUALIZER_PARAM_SIZE_MAX = sizeof(effect_param_t) + 2 * sizeof(int32_t); 39 40static const int ENVREVERB_PARAM_SIZE_MAX_SINGLE = sizeof(effect_param_t) + 2 * sizeof(int32_t); 41 42static const int ENVREVERB_PARAM_SIZE_MAX_ALL = sizeof(effect_param_t) + sizeof(int32_t) 43 + sizeof(s_reverb_settings); 44 45static const int PRESETREVERB_PARAM_SIZE_MAX = sizeof(effect_param_t) + 2 * sizeof(int32_t); 46 47static inline SLuint32 KEY_FROM_GUID(SLInterfaceID pUuid) { 48 return pUuid->time_low; 49} 50 51 52//----------------------------------------------------------------------------- 53uint32_t eq_paramSize(int32_t param) { 54 uint32_t size; 55 56 switch (param) { 57 case EQ_PARAM_NUM_BANDS: 58 case EQ_PARAM_LEVEL_RANGE: 59 case EQ_PARAM_CUR_PRESET: 60 case EQ_PARAM_GET_NUM_OF_PRESETS: 61 size = sizeof(int32_t); 62 break; 63 case EQ_PARAM_BAND_LEVEL: 64 case EQ_PARAM_CENTER_FREQ: 65 case EQ_PARAM_BAND_FREQ_RANGE: 66 case EQ_PARAM_GET_BAND: 67 case EQ_PARAM_GET_PRESET_NAME: 68 size = 2 * sizeof(int32_t); 69 break; 70 default: 71 size = 2 * sizeof(int32_t); 72 SL_LOGE("Trying to use an unknown EQ parameter %d", param); 73 break; 74 } 75 return size; 76} 77 78uint32_t eq_valueSize(int32_t param) { 79 uint32_t size; 80 81 switch (param) { 82 case EQ_PARAM_NUM_BANDS: 83 case EQ_PARAM_CUR_PRESET: 84 case EQ_PARAM_GET_NUM_OF_PRESETS: 85 case EQ_PARAM_BAND_LEVEL: 86 case EQ_PARAM_GET_BAND: 87 size = sizeof(int16_t); 88 break; 89 case EQ_PARAM_LEVEL_RANGE: 90 size = 2 * sizeof(int16_t); 91 break; 92 case EQ_PARAM_CENTER_FREQ: 93 size = sizeof(int32_t); 94 break; 95 case EQ_PARAM_BAND_FREQ_RANGE: 96 size = 2 * sizeof(int32_t); 97 break; 98 case EQ_PARAM_GET_PRESET_NAME: 99 size = EFFECT_STRING_LEN_MAX; 100 break; 101 default: 102 size = sizeof(int32_t); 103 SL_LOGE("Trying to access an unknown EQ parameter %d", param); 104 break; 105 } 106 return size; 107} 108 109//----------------------------------------------------------------------------- 110/** 111 * returns the size in bytes of the value of each bass boost parameter 112 */ 113uint32_t bb_valueSize(int32_t param) { 114 uint32_t size; 115 116 switch (param) { 117 case BASSBOOST_PARAM_STRENGTH_SUPPORTED: 118 size = sizeof(int32_t); 119 break; 120 case BASSBOOST_PARAM_STRENGTH: 121 size = sizeof(int16_t); 122 break; 123 default: 124 size = sizeof(int32_t); 125 SL_LOGE("Trying to access an unknown BassBoost parameter %d", param); 126 break; 127 } 128 129 return size; 130} 131 132//----------------------------------------------------------------------------- 133/** 134 * returns the size in bytes of the value of each virtualizer parameter 135 */ 136uint32_t virt_valueSize(int32_t param) { 137 uint32_t size; 138 139 switch (param) { 140 case VIRTUALIZER_PARAM_STRENGTH_SUPPORTED: 141 size = sizeof(int32_t); 142 break; 143 case VIRTUALIZER_PARAM_STRENGTH: 144 size = sizeof(int16_t); 145 break; 146 default: 147 size = sizeof(int32_t); 148 SL_LOGE("Trying to access an unknown Virtualizer parameter %d", param); 149 break; 150 } 151 152 return size; 153} 154 155//----------------------------------------------------------------------------- 156/** 157 * returns the size in bytes of the value of each environmental reverb parameter 158 */ 159uint32_t erev_valueSize(int32_t param) { 160 uint32_t size; 161 162 switch (param) { 163 case REVERB_PARAM_ROOM_LEVEL: 164 case REVERB_PARAM_ROOM_HF_LEVEL: 165 case REVERB_PARAM_REFLECTIONS_LEVEL: 166 case REVERB_PARAM_REVERB_LEVEL: 167 size = sizeof(int16_t); // millibel 168 break; 169 case REVERB_PARAM_DECAY_TIME: 170 case REVERB_PARAM_REFLECTIONS_DELAY: 171 case REVERB_PARAM_REVERB_DELAY: 172 size = sizeof(uint32_t); // milliseconds 173 break; 174 case REVERB_PARAM_DECAY_HF_RATIO: 175 case REVERB_PARAM_DIFFUSION: 176 case REVERB_PARAM_DENSITY: 177 size = sizeof(int16_t); // permille 178 break; 179 case REVERB_PARAM_PROPERTIES: 180 size = sizeof(s_reverb_settings); // struct of all reverb properties 181 break; 182 default: 183 size = sizeof(int32_t); 184 SL_LOGE("Trying to access an unknown Environmental Reverb parameter %d", param); 185 break; 186 } 187 188 return size; 189} 190 191//----------------------------------------------------------------------------- 192android::status_t android_eq_getParam(android::sp<android::AudioEffect> pFx, 193 int32_t param, int32_t param2, void *pValue) 194{ 195 android::status_t status; 196 uint32_t buf32[(EQUALIZER_PARAM_SIZE_MAX - 1) / sizeof(uint32_t) + 1]; 197 effect_param_t *p = (effect_param_t *)buf32; 198 199 p->psize = eq_paramSize(param); 200 *(int32_t *)p->data = param; 201 if (p->psize == 2 * sizeof(int32_t)) { 202 *((int32_t *)p->data + 1) = param2; 203 } 204 p->vsize = eq_valueSize(param); 205 status = pFx->getParameter(p); 206 if (android::NO_ERROR == status) { 207 status = p->status; 208 if (android::NO_ERROR == status) { 209 memcpy(pValue, p->data + p->psize, p->vsize); 210 } 211 } 212 213 return status; 214 } 215 216 217//----------------------------------------------------------------------------- 218android::status_t android_eq_setParam(android::sp<android::AudioEffect> pFx, 219 int32_t param, int32_t param2, void *pValue) 220{ 221 android::status_t status; 222 uint32_t buf32[(EQUALIZER_PARAM_SIZE_MAX - 1) / sizeof(uint32_t) + 1]; 223 effect_param_t *p = (effect_param_t *)buf32; 224 225 p->psize = eq_paramSize(param); 226 *(int32_t *)p->data = param; 227 if (p->psize == 2 * sizeof(int32_t)) { 228 *((int32_t *)p->data + 1) = param2; 229 } 230 p->vsize = eq_valueSize(param); 231 memcpy(p->data + p->psize, pValue, p->vsize); 232 status = pFx->setParameter(p); 233 if (android::NO_ERROR == status) { 234 status = p->status; 235 } 236 237 return status; 238} 239 240//----------------------------------------------------------------------------- 241android::status_t android_bb_setParam(android::sp<android::AudioEffect> pFx, 242 int32_t param, void *pValue) { 243 244 return android_fx_setParam(pFx, param, BASSBOOST_PARAM_SIZE_MAX, 245 pValue, bb_valueSize(param)); 246} 247 248//----------------------------------------------------------------------------- 249android::status_t android_bb_getParam(android::sp<android::AudioEffect> pFx, 250 int32_t param, void *pValue) { 251 252 return android_fx_getParam(pFx, param, BASSBOOST_PARAM_SIZE_MAX, 253 pValue, bb_valueSize(param)); 254} 255 256//----------------------------------------------------------------------------- 257void android_bb_init(int sessionId, IBassBoost* ibb) { 258 SL_LOGV("session %d", sessionId); 259 260 if (!android_fx_initEffectObj(sessionId, ibb->mBassBoostEffect, 261 &ibb->mBassBoostDescriptor.type)) 262 { 263 SL_LOGE("BassBoost effect initialization failed"); 264 return; 265 } 266 267 // initialize strength 268 int16_t strength; 269 if (android::NO_ERROR == android_bb_getParam(ibb->mBassBoostEffect, 270 BASSBOOST_PARAM_STRENGTH, &strength)) { 271 ibb->mStrength = (SLpermille) strength; 272 } 273} 274 275 276//----------------------------------------------------------------------------- 277void android_eq_init(int sessionId, IEqualizer* ieq) { 278 SL_LOGV("android_eq_init on session %d", sessionId); 279 280 if (!android_fx_initEffectObj(sessionId, ieq->mEqEffect, &ieq->mEqDescriptor.type)) { 281 SL_LOGE("Equalizer effect initialization failed"); 282 return; 283 } 284 285 // initialize number of bands, band level range, and number of presets 286 uint16_t num = 0; 287 if (android::NO_ERROR == android_eq_getParam(ieq->mEqEffect, EQ_PARAM_NUM_BANDS, 0, &num)) { 288 ieq->mNumBands = num; 289 } 290 int16_t range[2] = {0, 0}; 291 if (android::NO_ERROR == android_eq_getParam(ieq->mEqEffect, EQ_PARAM_LEVEL_RANGE, 0, range)) { 292 ieq->mBandLevelRangeMin = range[0]; 293 ieq->mBandLevelRangeMax = range[1]; 294 } 295 296 SL_LOGV(" EQ init: num bands = %u, band range=[%d %d]mB", num, range[0], range[1]); 297 298 // FIXME don't store presets names, they can be queried each time they're needed 299 // initialize preset number and names, store in IEngine 300 uint16_t numPresets = 0; 301 if (android::NO_ERROR == android_eq_getParam(ieq->mEqEffect, 302 EQ_PARAM_GET_NUM_OF_PRESETS, 0, &numPresets)) { 303 ieq->mThis->mEngine->mEqNumPresets = numPresets; 304 ieq->mNumPresets = numPresets; 305 } 306 307 object_lock_exclusive(&ieq->mThis->mEngine->mObject); 308 char name[EFFECT_STRING_LEN_MAX]; 309 if ((0 < numPresets) && (NULL == ieq->mThis->mEngine->mEqPresetNames)) { 310 ieq->mThis->mEngine->mEqPresetNames = (char **)new char *[numPresets]; 311 for(uint32_t i = 0 ; i < numPresets ; i++) { 312 if (android::NO_ERROR == android_eq_getParam(ieq->mEqEffect, 313 EQ_PARAM_GET_PRESET_NAME, i, name)) { 314 ieq->mThis->mEngine->mEqPresetNames[i] = new char[strlen(name) + 1]; 315 strcpy(ieq->mThis->mEngine->mEqPresetNames[i], name); 316 SL_LOGV(" EQ init: presets = %u is %s", i, ieq->mThis->mEngine->mEqPresetNames[i]); 317 } 318 } 319 } 320 object_unlock_exclusive(&ieq->mThis->mEngine->mObject); 321 322} 323 324 325//----------------------------------------------------------------------------- 326void android_virt_init(int sessionId, IVirtualizer* ivi) { 327 SL_LOGV("android_virt_init on session %d", sessionId); 328 329 if (!android_fx_initEffectObj(sessionId, ivi->mVirtualizerEffect, 330 &ivi->mVirtualizerDescriptor.type)) { 331 SL_LOGE("Virtualizer effect initialization failed"); 332 return; 333 } 334 335 // initialize strength 336 int16_t strength; 337 if (android::NO_ERROR == android_virt_getParam(ivi->mVirtualizerEffect, 338 VIRTUALIZER_PARAM_STRENGTH, &strength)) { 339 ivi->mStrength = (SLpermille) strength; 340 } 341} 342 343//----------------------------------------------------------------------------- 344android::status_t android_virt_setParam(android::sp<android::AudioEffect> pFx, 345 int32_t param, void *pValue) { 346 347 return android_fx_setParam(pFx, param, VIRTUALIZER_PARAM_SIZE_MAX, 348 pValue, virt_valueSize(param)); 349} 350 351//----------------------------------------------------------------------------- 352android::status_t android_virt_getParam(android::sp<android::AudioEffect> pFx, 353 int32_t param, void *pValue) { 354 355 return android_fx_getParam(pFx, param, VIRTUALIZER_PARAM_SIZE_MAX, 356 pValue, virt_valueSize(param)); 357} 358 359 360//----------------------------------------------------------------------------- 361void android_prev_init(IPresetReverb* ipr) { 362 SL_LOGV("session is implicitly %d (aux effect)", AUDIO_SESSION_OUTPUT_MIX); 363 364 if (!android_fx_initEffectObj(AUDIO_SESSION_OUTPUT_MIX /*sessionId*/, 365 ipr->mPresetReverbEffect, &ipr->mPresetReverbDescriptor.type)) { 366 SL_LOGE("PresetReverb effect initialization failed"); 367 return; 368 } 369 370 // initialize preset 371 uint16_t preset; 372 if (android::NO_ERROR == android_prev_getPreset(ipr->mPresetReverbEffect, &preset)) { 373 ipr->mPreset = preset; 374 // enable the effect if it has a preset loaded 375 ipr->mPresetReverbEffect->setEnabled(SL_REVERBPRESET_NONE != preset); 376 } 377} 378 379//----------------------------------------------------------------------------- 380android::status_t android_prev_setPreset(android::sp<android::AudioEffect> pFx, uint16_t preset) { 381 android::status_t status = android_fx_setParam(pFx, REVERB_PARAM_PRESET, 382 PRESETREVERB_PARAM_SIZE_MAX, &preset, sizeof(uint16_t)); 383 // enable the effect if the preset is different from SL_REVERBPRESET_NONE 384 pFx->setEnabled(SL_REVERBPRESET_NONE != preset); 385 return status; 386} 387 388//----------------------------------------------------------------------------- 389android::status_t android_prev_getPreset(android::sp<android::AudioEffect> pFx, uint16_t* preset) { 390 return android_fx_getParam(pFx, REVERB_PARAM_PRESET, PRESETREVERB_PARAM_SIZE_MAX, preset, 391 sizeof(uint16_t)); 392} 393 394 395//----------------------------------------------------------------------------- 396void android_erev_init(IEnvironmentalReverb* ier) { 397 SL_LOGV("session is implicitly %d (aux effect)", AUDIO_SESSION_OUTPUT_MIX); 398 399 if (!android_fx_initEffectObj(AUDIO_SESSION_OUTPUT_MIX /*sessionId*/, 400 ier->mEnvironmentalReverbEffect, &ier->mEnvironmentalReverbDescriptor.type)) { 401 SL_LOGE("EnvironmentalReverb effect initialization failed"); 402 return; 403 } 404 405 // enable env reverb: other SL ES effects have an explicit SetEnabled() function, and the 406 // preset reverb state depends on the selected preset. 407 ier->mEnvironmentalReverbEffect->setEnabled(true); 408 409 // initialize reverb properties 410 SLEnvironmentalReverbSettings properties; 411 if (android::NO_ERROR == android_erev_getParam(ier->mEnvironmentalReverbEffect, 412 REVERB_PARAM_PROPERTIES, &properties)) { 413 ier->mProperties = properties; 414 } 415} 416 417//----------------------------------------------------------------------------- 418android::status_t android_erev_setParam(android::sp<android::AudioEffect> pFx, 419 int32_t param, void *pValue) { 420 421 // given the size difference between a single reverb property and the whole set of reverb 422 // properties, select which max size to pass to avoid allocating too much memory 423 if (param == REVERB_PARAM_PROPERTIES) { 424 return android_fx_setParam(pFx, param, ENVREVERB_PARAM_SIZE_MAX_ALL, 425 pValue, erev_valueSize(param)); 426 } else { 427 return android_fx_setParam(pFx, param, ENVREVERB_PARAM_SIZE_MAX_SINGLE, 428 pValue, erev_valueSize(param)); 429 } 430} 431 432//----------------------------------------------------------------------------- 433android::status_t android_erev_getParam(android::sp<android::AudioEffect> pFx, 434 int32_t param, void *pValue) { 435 436 // given the size difference between a single reverb property and the whole set of reverb 437 // properties, select which max size to pass to avoid allocating too much memory 438 if (param == REVERB_PARAM_PROPERTIES) { 439 return android_fx_getParam(pFx, param, ENVREVERB_PARAM_SIZE_MAX_ALL, 440 pValue, erev_valueSize(param)); 441 } else { 442 return android_fx_getParam(pFx, param, ENVREVERB_PARAM_SIZE_MAX_SINGLE, 443 pValue, erev_valueSize(param)); 444 } 445} 446 447 448//----------------------------------------------------------------------------- 449/** 450 * pre-condition: 451 * ap != NULL 452 * for media players: 453 * ap->mAPlayer != 0 454 * ap->mAudioTrack == 0 455 * for buffer queue players: 456 * ap->mAPlayer == 0 457 * ap->mAudioTrack != 0 is optional; if no track yet then the setting is deferred 458 */ 459android::status_t android_fxSend_attach(CAudioPlayer* ap, bool attach, 460 android::sp<android::AudioEffect> pFx, SLmillibel sendLevel) { 461 462 if (pFx == 0) { 463 return android::INVALID_OPERATION; 464 } 465 466 // There are 3 cases: 467 // mAPlayer != 0 && mAudioTrack == 0 means playing decoded audio 468 // mAPlayer == 0 && mAudioTrack != 0 means playing PCM audio 469 // mAPlayer == 0 && mAudioTrack == 0 means player not fully configured yet 470 // The asserts document and verify this. 471 if (ap->mAPlayer != 0) { 472 assert(ap->mAudioTrack == 0); 473 if (attach) { 474 ap->mAPlayer->attachAuxEffect(pFx->id()); 475 ap->mAPlayer->setAuxEffectSendLevel( sles_to_android_amplification(sendLevel) ); 476 } else { 477 ap->mAPlayer->attachAuxEffect(0); 478 } 479 return android::NO_ERROR; 480 } 481 482 if (ap->mAudioTrack == 0) { 483 // the player doesn't have an AudioTrack at the moment, so store this info to use it 484 // when the AudioTrack becomes available 485 if (attach) { 486 ap->mAuxEffect = pFx; 487 } else { 488 ap->mAuxEffect.clear(); 489 } 490 // we keep track of the send level, independently of the current audio player level 491 ap->mAuxSendLevel = sendLevel - ap->mVolume.mLevel; 492 return android::NO_ERROR; 493 } 494 495 if (attach) { 496 android::status_t status = ap->mAudioTrack->attachAuxEffect(pFx->id()); 497 //SL_LOGV("attachAuxEffect(%d) returned %d", pFx->id(), status); 498 if (android::NO_ERROR == status) { 499 status = 500 ap->mAudioTrack->setAuxEffectSendLevel( sles_to_android_amplification(sendLevel) ); 501 } 502 return status; 503 } else { 504 return ap->mAudioTrack->attachAuxEffect(0); 505 } 506} 507 508//----------------------------------------------------------------------------- 509/** 510 * pre-condition: 511 * ap != NULL 512 * ap->mOutputMix != NULL 513 */ 514SLresult android_fxSend_attachToAux(CAudioPlayer* ap, SLInterfaceID pUuid, SLboolean attach, 515 SLmillibel sendLevel) { 516 COutputMix *outputMix = CAudioPlayer_GetOutputMix(ap); 517 ssize_t index = outputMix->mAndroidEffect.mEffects->indexOfKey(KEY_FROM_GUID(pUuid)); 518 519 if (0 > index) { 520 SL_LOGE("invalid effect ID: no such effect attached to the OutputMix"); 521 return SL_RESULT_PARAMETER_INVALID; 522 } 523 524 android::AudioEffect* pFx = outputMix->mAndroidEffect.mEffects->valueAt(index); 525 if (NULL == pFx) { 526 return SL_RESULT_RESOURCE_ERROR; 527 } 528 if (android::NO_ERROR == android_fxSend_attach( ap, (bool) attach, pFx, sendLevel) ) { 529 return SL_RESULT_SUCCESS; 530 } else { 531 return SL_RESULT_RESOURCE_ERROR; 532 } 533 534} 535 536//----------------------------------------------------------------------------- 537/** 538 * pre-condition: 539 * ap != NULL 540 * for media players: 541 * ap->mAPlayer != 0 542 * ap->mAudioTrack == 0 543 * for buffer queue players: 544 * ap->mAPlayer == 0 545 * ap->mAudioTrack != 0 is optional; if no track yet then the setting is deferred 546 */ 547android::status_t android_fxSend_setSendLevel(CAudioPlayer* ap, SLmillibel sendLevel) { 548 // we keep track of the send level, independently of the current audio player level 549 ap->mAuxSendLevel = sendLevel - ap->mVolume.mLevel; 550 551 if (ap->mAPlayer != 0) { 552 assert(ap->mAudioTrack == 0); 553 ap->mAPlayer->setAuxEffectSendLevel( sles_to_android_amplification(sendLevel) ); 554 return android::NO_ERROR; 555 } 556 557 if (ap->mAudioTrack == 0) { 558 return android::NO_ERROR; 559 } 560 561 return ap->mAudioTrack->setAuxEffectSendLevel( sles_to_android_amplification(sendLevel) ); 562} 563 564//----------------------------------------------------------------------------- 565android::status_t android_fx_setParam(android::sp<android::AudioEffect> pFx, 566 int32_t param, uint32_t paramSizeMax, void *pValue, uint32_t valueSize) 567{ 568 569 android::status_t status; 570 uint32_t buf32[(paramSizeMax - 1) / sizeof(uint32_t) + 1]; 571 effect_param_t *p = (effect_param_t *)buf32; 572 573 p->psize = sizeof(int32_t); 574 *(int32_t *)p->data = param; 575 p->vsize = valueSize; 576 memcpy(p->data + p->psize, pValue, p->vsize); 577 status = pFx->setParameter(p); 578 if (android::NO_ERROR == status) { 579 status = p->status; 580 } 581 return status; 582} 583 584 585//----------------------------------------------------------------------------- 586android::status_t android_fx_getParam(android::sp<android::AudioEffect> pFx, 587 int32_t param, uint32_t paramSizeMax, void *pValue, uint32_t valueSize) 588{ 589 android::status_t status; 590 uint32_t buf32[(paramSizeMax - 1) / sizeof(uint32_t) + 1]; 591 effect_param_t *p = (effect_param_t *)buf32; 592 593 p->psize = sizeof(int32_t); 594 *(int32_t *)p->data = param; 595 p->vsize = valueSize; 596 status = pFx->getParameter(p); 597 if (android::NO_ERROR == status) { 598 status = p->status; 599 if (android::NO_ERROR == status) { 600 memcpy(pValue, p->data + p->psize, p->vsize); 601 } 602 } 603 604 return status; 605} 606 607 608//----------------------------------------------------------------------------- 609SLresult android_fx_statusToResult(android::status_t status) { 610 611 if ((android::INVALID_OPERATION == status) || (android::DEAD_OBJECT == status)) { 612 return SL_RESULT_CONTROL_LOST; 613 } else { 614 return SL_RESULT_SUCCESS; 615 } 616} 617 618 619//----------------------------------------------------------------------------- 620bool android_fx_initEffectObj(int sessionId, android::sp<android::AudioEffect>& effect, 621 const effect_uuid_t *type) { 622 //SL_LOGV("android_fx_initEffectObj on session %d", sessionId); 623 624 effect = new android::AudioEffect(type, EFFECT_UUID_NULL, 625 0,// priority 626 0,// effect callback 627 0,// callback data 628 sessionId,// session ID 629 0 );// output 630 631 android::status_t status = effect->initCheck(); 632 if (android::NO_ERROR != status) { 633 effect.clear(); 634 SL_LOGE("Effect initCheck() returned %d", status); 635 return false; 636 } 637 638 return true; 639} 640 641 642//----------------------------------------------------------------------------- 643bool android_fx_initEffectDescriptor(const SLInterfaceID effectId, 644 effect_descriptor_t* fxDescrLoc) { 645 uint32_t numEffects = 0; 646 effect_descriptor_t descriptor; 647 bool foundEffect = false; 648 649 // any effects? 650 android::status_t res = android::AudioEffect::queryNumberEffects(&numEffects); 651 if (android::NO_ERROR != res) { 652 SL_LOGE("unable to find any effects."); 653 goto effectError; 654 } 655 656 // request effect in the effects? 657 for (uint32_t i=0 ; i < numEffects ; i++) { 658 res = android::AudioEffect::queryEffect(i, &descriptor); 659 if ((android::NO_ERROR == res) && 660 (0 == memcmp(effectId, &descriptor.type, sizeof(effect_uuid_t)))) { 661 SL_LOGV("found effect %d %s", i, descriptor.name); 662 foundEffect = true; 663 break; 664 } 665 } 666 if (foundEffect) { 667 memcpy(fxDescrLoc, &descriptor, sizeof(effect_descriptor_t)); 668 } else { 669 SL_LOGE("unable to find an implementation for the requested effect."); 670 goto effectError; 671 } 672 673 return true; 674 675effectError: 676 // the requested effect wasn't found 677 memset(fxDescrLoc, 0, sizeof(effect_descriptor_t)); 678 679 return false; 680} 681 682//----------------------------------------------------------------------------- 683SLresult android_genericFx_queryNumEffects(SLuint32 *pNumSupportedAudioEffects) { 684 685 if (NULL == pNumSupportedAudioEffects) { 686 return SL_RESULT_PARAMETER_INVALID; 687 } 688 689 android::status_t status = 690 android::AudioEffect::queryNumberEffects((uint32_t*)pNumSupportedAudioEffects); 691 692 SLresult result = SL_RESULT_SUCCESS; 693 switch(status) { 694 case android::NO_ERROR: 695 result = SL_RESULT_SUCCESS; 696 break; 697 case android::PERMISSION_DENIED: 698 result = SL_RESULT_PERMISSION_DENIED; 699 break; 700 case android::NO_INIT: 701 result = SL_RESULT_RESOURCE_ERROR; 702 break; 703 case android::BAD_VALUE: 704 result = SL_RESULT_PARAMETER_INVALID; 705 break; 706 default: 707 result = SL_RESULT_INTERNAL_ERROR; 708 SL_LOGE("received invalid status %d from AudioEffect::queryNumberEffects()", status); 709 break; 710 } 711 return result; 712} 713 714 715//----------------------------------------------------------------------------- 716SLresult android_genericFx_queryEffect(SLuint32 index, effect_descriptor_t* pDescriptor) { 717 718 if (NULL == pDescriptor) { 719 return SL_RESULT_PARAMETER_INVALID; 720 } 721 722 android::status_t status = 723 android::AudioEffect::queryEffect(index, pDescriptor); 724 725 SLresult result = SL_RESULT_SUCCESS; 726 if (android::NO_ERROR != status) { 727 switch(status) { 728 case android::PERMISSION_DENIED: 729 result = SL_RESULT_PERMISSION_DENIED; 730 break; 731 case android::NO_INIT: 732 case android::INVALID_OPERATION: 733 result = SL_RESULT_RESOURCE_ERROR; 734 break; 735 case android::BAD_VALUE: 736 result = SL_RESULT_PARAMETER_INVALID; 737 break; 738 default: 739 result = SL_RESULT_INTERNAL_ERROR; 740 SL_LOGE("received invalid status %d from AudioEffect::queryNumberEffects()", status); 741 break; 742 } 743 // an error occurred, reset the effect descriptor 744 memset(pDescriptor, 0, sizeof(effect_descriptor_t)); 745 } 746 747 return result; 748} 749 750 751//----------------------------------------------------------------------------- 752SLresult android_genericFx_createEffect(IAndroidEffect* iae, SLInterfaceID pUuid, int sessionId) { 753 754 SLresult result = SL_RESULT_SUCCESS; 755 756 // does this effect already exist? 757 if (0 <= iae->mEffects->indexOfKey(KEY_FROM_GUID(pUuid))) { 758 return result; 759 } 760 761 // create new effect 762 android::AudioEffect* pFx = new android::AudioEffect( 763 NULL, // not using type to create effect 764 (const effect_uuid_t*)pUuid, 765 0,// priority 766 0,// effect callback 767 0,// callback data 768 sessionId, 769 0 );// output 770 771 // verify effect was successfully created before storing it 772 android::status_t status = pFx->initCheck(); 773 if (android::NO_ERROR != status) { 774 SL_LOGE("AudioEffect initCheck() returned %d, effect will not be stored", status); 775 delete pFx; 776 result = SL_RESULT_RESOURCE_ERROR; 777 } else { 778 SL_LOGV("AudioEffect successfully created on session %d", sessionId); 779 iae->mEffects->add(KEY_FROM_GUID(pUuid), pFx); 780 } 781 782 return result; 783} 784 785 786//----------------------------------------------------------------------------- 787SLresult android_genericFx_releaseEffect(IAndroidEffect* iae, SLInterfaceID pUuid) { 788 789 ssize_t index = iae->mEffects->indexOfKey(KEY_FROM_GUID(pUuid)); 790 791 if (0 > index) { 792 return SL_RESULT_PARAMETER_INVALID; 793 } else { 794 android::AudioEffect* pFx = iae->mEffects->valueAt(index); 795 delete pFx; 796 iae->mEffects->removeItem(index); 797 return SL_RESULT_SUCCESS; 798 } 799} 800 801 802//----------------------------------------------------------------------------- 803SLresult android_genericFx_setEnabled(IAndroidEffect* iae, SLInterfaceID pUuid, SLboolean enabled) { 804 805 ssize_t index = iae->mEffects->indexOfKey(KEY_FROM_GUID(pUuid)); 806 807 if (0 > index) { 808 return SL_RESULT_PARAMETER_INVALID; 809 } else { 810 android::AudioEffect* pFx = iae->mEffects->valueAt(index); 811 android::status_t status = pFx->setEnabled(SL_BOOLEAN_TRUE == enabled); 812 return android_fx_statusToResult(status); 813 } 814} 815 816 817//----------------------------------------------------------------------------- 818SLresult android_genericFx_isEnabled(IAndroidEffect* iae, SLInterfaceID pUuid, SLboolean *pEnabled) 819{ 820 ssize_t index = iae->mEffects->indexOfKey(KEY_FROM_GUID(pUuid)); 821 822 if (0 > index) { 823 return SL_RESULT_PARAMETER_INVALID; 824 } else { 825 android::AudioEffect* pFx = iae->mEffects->valueAt(index); 826 *pEnabled = (SLboolean) pFx->getEnabled(); 827 return SL_RESULT_SUCCESS; 828 } 829} 830 831 832//----------------------------------------------------------------------------- 833SLresult android_genericFx_sendCommand(IAndroidEffect* iae, SLInterfaceID pUuid, 834 SLuint32 command, SLuint32 commandSize, void* pCommandData, 835 SLuint32 *replySize, void *pReplyData) { 836 837 ssize_t index = iae->mEffects->indexOfKey(KEY_FROM_GUID(pUuid)); 838 839 if (0 > index) { 840 return SL_RESULT_PARAMETER_INVALID; 841 } else { 842 android::AudioEffect* pFx = iae->mEffects->valueAt(index); 843 android::status_t status = pFx->command( 844 (uint32_t) command, 845 (uint32_t) commandSize, 846 pCommandData, 847 (uint32_t*)replySize, 848 pReplyData); 849 if (android::BAD_VALUE == status) { 850 return SL_RESULT_PARAMETER_INVALID; 851 } else { 852 return SL_RESULT_SUCCESS; 853 } 854 } 855} 856 857//----------------------------------------------------------------------------- 858/** 859 * returns true if the given effect id is present in the AndroidEffect interface 860 */ 861bool android_genericFx_hasEffect(IAndroidEffect* iae, SLInterfaceID pUuid) { 862 return( 0 <= iae->mEffects->indexOfKey(KEY_FROM_GUID(pUuid))); 863} 864 865//----------------------------------------------------------------------------- 866static const int AEC_PARAM_SIZE_MAX = sizeof(effect_param_t) + (2 * sizeof(int32_t)); 867/** 868 * returns the size in bytes of the value of each acoustic echo cancellation parameter 869 */ 870uint32_t aec_valueSize(int32_t param) { 871 uint32_t size; 872 switch (param) { 873 case AEC_PARAM_ECHO_DELAY: 874 size = sizeof(int32_t); 875 break; 876 default: 877 size = sizeof(int32_t); 878 SL_LOGE("Trying to access an unknown Acoustic Echo Cancellation parameter %d", param); 879 break; 880 } 881 882 return size; 883} 884 885android::status_t android_aec_setParam(android::sp<android::AudioEffect> pFx, 886 int32_t param, void *pValue) { 887 return android_fx_setParam(pFx, param, AEC_PARAM_SIZE_MAX, 888 pValue, aec_valueSize(param)); 889} 890 891android::status_t android_aec_getParam(android::sp<android::AudioEffect> pFx, 892 int32_t param, void *pValue) { 893 return android_fx_getParam(pFx, param, AEC_PARAM_SIZE_MAX, 894 pValue, aec_valueSize(param)); 895} 896 897//----------------------------------------------------------------------------- 898static const int AGC_PARAM_SIZE_MAX = sizeof(effect_param_t) + (2 * sizeof(int16_t)) + sizeof(bool); 899/** 900 * returns the size in bytes of the value of each automatic gain control parameter 901 */ 902uint32_t agc_valueSize(int32_t param) { 903 uint32_t size; 904 switch (param) { 905 case AGC_PARAM_TARGET_LEVEL: 906 case AGC_PARAM_COMP_GAIN: 907 size = sizeof(int16_t); 908 break; 909 case AGC_PARAM_LIMITER_ENA: 910 size = sizeof(bool); 911 break; 912 default: 913 size = sizeof(int32_t); 914 SL_LOGE("Trying to access an unknown Automatic Gain Control parameter %d", param); 915 break; 916 } 917 918 return size; 919} 920 921android::status_t android_agc_setParam(android::sp<android::AudioEffect> pFx, 922 int32_t param, void *pValue) { 923 return android_fx_setParam(pFx, param, AGC_PARAM_SIZE_MAX, 924 pValue, agc_valueSize(param)); 925} 926 927android::status_t android_agc_getParam(android::sp<android::AudioEffect> pFx, 928 int32_t param, void *pValue) { 929 return android_fx_getParam(pFx, param, AGC_PARAM_SIZE_MAX, 930 pValue, agc_valueSize(param)); 931} 932 933//----------------------------------------------------------------------------- 934static const int NS_PARAM_SIZE_MAX = sizeof(effect_param_t) + 2 * sizeof(int32_t); 935/** 936 * returns the size in bytes of the value of each noise suppression parameter 937 */ 938uint32_t ns_valueSize(int32_t param) { 939 uint32_t size; 940 switch (param) { 941 case NS_PARAM_LEVEL: 942 size = sizeof(int32_t); 943 break; 944 default: 945 size = sizeof(int32_t); 946 SL_LOGE("Trying to access an unknown Noise suppression parameter %d", param); 947 break; 948 } 949 950 return size; 951} 952 953android::status_t android_ns_setParam(android::sp<android::AudioEffect> pFx, 954 int32_t param, void *pValue) 955{ 956 return android_fx_setParam(pFx, param, NS_PARAM_SIZE_MAX, 957 pValue, ns_valueSize(param)); 958} 959 960android::status_t android_ns_getParam(android::sp<android::AudioEffect> pFx, 961 int32_t param, void *pValue) 962{ 963 return android_fx_getParam(pFx, param, NS_PARAM_SIZE_MAX, 964 pValue, ns_valueSize(param)); 965} 966