1 /* 2 * Copyright (C) 2012 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 #include <errno.h> 18 #include <fcntl.h> 19 20 #define LOG_TAG "eS305VoiceProcessing" 21 //#define LOG_NDEBUG 0 22 #include <cutils/log.h> 23 24 #include "eS305VoiceProcessing.h" 25 #include <audio_effects/effect_aec.h> 26 #include <audio_effects/effect_ns.h> 27 #include <audio_effects/effect_agc.h> 28 29 extern "C" { 30 31 //------------------------------------------------------------------------------ 32 // local definitions 33 //------------------------------------------------------------------------------ 34 35 // number of sessions this effect bundle can be used for 36 #define ADNC_PFX_NUM_SESSION 8 37 38 // types of pre processing modules 39 enum adnc_pfx_id 40 { 41 PFX_ID_AEC = 0, // Acoustic Echo Cancellation 42 PFX_ID_NS, // Noise Suppression 43 PFX_ID_AGC, // Automatic Gain Control 44 PFX_ID_CNT 45 }; 46 47 // Session state 48 enum adnc_pfx_session_state { 49 PFX_SESSION_STATE_INIT, // initialized 50 PFX_SESSION_STATE_CONFIG // configuration received 51 }; 52 53 // Effect/Preprocessor state 54 enum adnc_pfx_effect_state { 55 PFX_EFFECT_STATE_INIT, // initialized 56 PFX_EFFECT_STATE_CREATED, // effect created 57 PFX_EFFECT_STATE_CONFIG, // configuration received/disabled 58 PFX_EFFECT_STATE_ACTIVE // active/enabled 59 }; 60 61 typedef struct adnc_pfx_session_s adnc_pfx_session_t; 62 typedef struct adnc_pfx_effect_s adnc_pfx_effect_t; 63 typedef struct adnc_pfx_ops_s adnc_pfx_ops_t; 64 65 // Effect operation table. Functions for all pre processors are declared in sPreProcOps[] table. 66 // Function pointer can be null if no action required. 67 struct adnc_pfx_ops_s { 68 int (* create)(adnc_pfx_effect_t *fx); 69 int (* init)(adnc_pfx_effect_t *fx); 70 int (* reset)(adnc_pfx_effect_t *fx); 71 void (* enable)(adnc_pfx_effect_t *fx); 72 void (* disable)(adnc_pfx_effect_t *fx); 73 int (* set_parameter)(adnc_pfx_effect_t *fx, void *param, void *value); 74 int (* get_parameter)(adnc_pfx_effect_t *fx, void *param, size_t *size, void *value); 75 int (* set_device)(adnc_pfx_effect_t *fx, uint32_t device); 76 }; 77 78 // Effect context 79 struct adnc_pfx_effect_s { 80 const struct effect_interface_s *itfe; 81 uint32_t procId; // type of pre processor (enum adnc_pfx_id) 82 uint32_t state; // current state (enum adnc_pfx_effect_state) 83 adnc_pfx_session_t *session; // session the effect is on 84 const adnc_pfx_ops_t *ops; // effect ops table 85 }; 86 87 // Session context 88 struct adnc_pfx_session_s { 89 uint32_t state; // current state (enum adnc_pfx_session_state) 90 audio_source_t audioSource; 91 // FIXME not used, delete? 92 //int audioSessionId; // audio session ID 93 int ioHandle; // handle of input stream this session is on 94 uint32_t createdMsk; // bit field containing IDs of created pre processors 95 uint32_t activeMsk; // bit field containing IDs of pre processors currently active 96 struct adnc_pfx_effect_s effects[PFX_ID_CNT]; // effects in this session 97 98 // effect settings 99 // none controllable from public API here 100 }; 101 102 //----------------------------------------- 103 // forward declarations 104 //----------------------------------------- 105 int Adnc_SetNoiseSuppressionInt_l(bool); 106 int Adnc_SetAutomaticGainControlInt_l(bool); 107 int Adnc_SetEchoCancellationInt_l(bool); 108 int Adnc_ReevaluateUsageInt_l(audio_io_handle_t); 109 int Adnc_SleepInt_l(); 110 111 //------------------------------------------------------------------------------ 112 // eS305 control 113 //------------------------------------------------------------------------------ 114 #define ES305_SYSFS_PATH "/sys/class/i2c-dev/i2c-4/device/4-003e/" 115 #define ES305_VOICE_PROCESSING_PATH ES305_SYSFS_PATH "voice_processing" 116 #define ES305_PRESET_PATH ES305_SYSFS_PATH "preset" 117 #define ES305_TX_NS_LEVEL_PATH ES305_SYSFS_PATH "tx_ns_level" 118 #define ES305_TX_AGC_ENABLE_PATH ES305_SYSFS_PATH "tx_agc_enable" 119 #define ES305_AEC_ENABLE_PATH ES305_SYSFS_PATH "aec_enable" 120 #define ES305_SLEEP_PATH ES305_SYSFS_PATH "sleep" 121 122 enum eS305_controls { 123 ES305_CTRL_VOICE_PROCESSING = 0, 124 ES305_CTRL_PRESET, 125 ES305_CTRL_TX_NS_LEVEL, 126 ES305_CTRL_TX_AGC_ENABLE, 127 ES305_CTRL_AEC_ENABLE, 128 ES305_CTRL_SLEEP, 129 ES305_NUM_CTRL 130 }; 131 132 struct eS305_ctrl_s { 133 int fd[ES305_NUM_CTRL]; 134 int current_preset; 135 int requested_preset; 136 int ioHandle; 137 }; 138 typedef struct eS305_ctrl_s eS305_ctrl_t; 139 140 static eS305_ctrl_t eS305_ctrl = { 141 { -1/*vp*/, -1/*preset*/, -1/*ns*/, -1/*agc*/, -1/*aec*/, -1/*sleep*/}, 142 ES305_PRESET_OFF /*current_preset*/, 143 ES305_PRESET_INIT /*requested_preset, an invalid preset, different from current_preset*/, 144 ES305_IO_HANDLE_NONE 145 }; 146 147 //------------------------------------------------------------------------------ 148 // Effect descriptors 149 //------------------------------------------------------------------------------ 150 151 // UUIDs for effect types have been generated from http://www.itu.int/ITU-T/asn1/uuid.html 152 // as the pre processing effects are not defined by OpenSL ES 153 154 // Acoustic Echo Cancellation 155 static const effect_descriptor_t aec_descriptor = { 156 FX_IID_AEC_, // type 157 { 0xfd90ff00, 0x0b55, 0x11e2, 0x892e, { 0x08, 0x00, 0x20, 0x0c, 0x9a, 0x66 } }, // uuid 158 EFFECT_CONTROL_API_VERSION, 159 (EFFECT_FLAG_TYPE_PRE_PROC|EFFECT_FLAG_DEVICE_IND), 160 0, //FIXME indicate CPU load 161 0, //FIXME indicate memory usage 162 "Acoustic Echo Canceler", 163 "Audience" 164 }; 165 166 // Noise suppression 167 static const effect_descriptor_t ns_descriptor = { 168 FX_IID_NS_, // type 169 { 0x08fa98b0, 0x0b56, 0x11e2, 0x892e, { 0x08, 0x00, 0x20, 0x0c, 0x9a, 0x66 } }, // uuid 170 EFFECT_CONTROL_API_VERSION, 171 (EFFECT_FLAG_TYPE_PRE_PROC|EFFECT_FLAG_DEVICE_IND), 172 0, //FIXME indicate CPU load 173 0, //FIXME indicate memory usage 174 "Noise Suppression", 175 "Audience" 176 }; 177 178 // Automatic Gain Control 179 static const effect_descriptor_t agc_descriptor = { 180 FX_IID_AGC_, // type 181 { 0xe9e87eb0, 0x0b55, 0x11e2, 0x892e, { 0x08, 0x00, 0x20, 0x0c, 0x9a, 0x66 } }, // uuid 182 EFFECT_CONTROL_API_VERSION, 183 (EFFECT_FLAG_TYPE_PRE_PROC|EFFECT_FLAG_DEVICE_IND), 184 0, //FIXME indicate CPU load 185 0, //FIXME indicate memory usage 186 "Automatic Gain Control", 187 "Audience" 188 }; 189 190 static const effect_descriptor_t *adnc_pfx_descriptors[PFX_ID_CNT] = { 191 &aec_descriptor, 192 &ns_descriptor, 193 &agc_descriptor 194 }; 195 196 197 //------------------------------------------------------------------------------ 198 // Helper functions 199 //------------------------------------------------------------------------------ 200 static const effect_uuid_t * const sAdncUuidTable[PFX_ID_CNT] = { 201 FX_IID_AEC, 202 FX_IID_NS, 203 FX_IID_AGC 204 }; 205 206 const effect_uuid_t * Adnc_ProcIdToUuid(int procId) 207 { 208 if (procId >= PFX_ID_CNT) { 209 return EFFECT_UUID_NULL; 210 } 211 return sAdncUuidTable[procId]; 212 } 213 214 uint32_t Adnc_UuidToProcId(const effect_uuid_t * uuid) 215 { 216 size_t i; 217 for (i = 0; i < PFX_ID_CNT; i++) { 218 if (memcmp(uuid, sAdncUuidTable[i], sizeof(*uuid)) == 0) { 219 break; 220 } 221 } 222 return i; 223 } 224 225 226 //------------------------------------------------------------------------------ 227 // Acoustic Echo Canceler (AEC) 228 //------------------------------------------------------------------------------ 229 int aec_init (adnc_pfx_effect_t *effect) 230 { 231 ALOGV("aec_init [noop]"); 232 return 0; 233 } 234 235 int aec_create(adnc_pfx_effect_t *effect) 236 { 237 ALOGV("aec_create [noop]"); 238 return aec_init (effect); 239 } 240 241 int aec_reset(adnc_pfx_effect_t *effect) 242 { 243 ALOGV("aec_reset [noop]"); 244 return 0; 245 } 246 247 int aec_get_parameter(adnc_pfx_effect_t *effect, 248 void *pParam, 249 size_t *pValueSize, 250 void *pValue) 251 { 252 int status = 0; 253 uint32_t param = *(uint32_t *)pParam; 254 255 if (*pValueSize < sizeof(uint32_t)) { 256 return -EINVAL; 257 } 258 /* NOT SUPPORTED 259 switch (param) { 260 case AEC_PARAM_ECHO_DELAY: 261 case AEC_PARAM_PROPERTIES: 262 break; 263 default: 264 ALOGW("aec_get_parameter() unknown param %08x value %08x", param, *(uint32_t *)pValue); 265 status = -EINVAL; 266 break; 267 } 268 return status; 269 */ 270 return -EINVAL; 271 } 272 273 int aec_set_parameter (adnc_pfx_effect_t *effect, void *pParam, void *pValue) 274 { 275 int status = 0; 276 uint32_t param = *(uint32_t *)pParam; 277 uint32_t value = *(uint32_t *)pValue; 278 279 /* NOT SUPPORTED 280 switch (param) { 281 case AEC_PARAM_ECHO_DELAY: 282 case AEC_PARAM_PROPERTIES: 283 ALOGV("aec_setParameter() echo delay %d us, status %d", value, status); 284 break; 285 default: 286 ALOGW("aec_setParameter() unknown param %08x value %08x", param, *(uint32_t *)pValue); 287 status = -EINVAL; 288 break; 289 } 290 */ 291 return status; 292 } 293 294 void aec_enable(adnc_pfx_effect_t *effect) 295 { 296 ALOGV("aec_enable [noop]"); 297 } 298 299 void aec_disable(adnc_pfx_effect_t *effect) 300 { 301 ALOGV("aec_disable [noop]"); 302 } 303 304 int aec_set_device(adnc_pfx_effect_t *effect, uint32_t device) 305 { 306 ALOGV("aec_set_device(device=%08x) [noop]", device); 307 308 /* 309 switch(device) { 310 case AUDIO_DEVICE_OUT_EARPIECE: 311 break; 312 case AUDIO_DEVICE_OUT_SPEAKER: 313 break; 314 case AUDIO_DEVICE_OUT_WIRED_HEADSET: 315 case AUDIO_DEVICE_OUT_WIRED_HEADPHONE: 316 default: 317 break; 318 } 319 */ 320 321 return 0; 322 } 323 324 static const adnc_pfx_ops_t aec_ops = { 325 aec_create, 326 aec_init, 327 aec_reset, 328 aec_enable, 329 aec_disable, 330 aec_set_parameter, 331 aec_get_parameter, 332 aec_set_device, 333 }; 334 335 336 //------------------------------------------------------------------------------ 337 // Noise Suppression (NS) 338 //------------------------------------------------------------------------------ 339 int ns_init (adnc_pfx_effect_t *effect) 340 { 341 ALOGV("ns_init [noop]"); 342 343 return 0; 344 } 345 346 int ns_create(adnc_pfx_effect_t *effect) 347 { 348 ALOGV("ns_create %p", effect); 349 350 return ns_init (effect); 351 } 352 353 int ns_get_parameter(adnc_pfx_effect_t *effect, 354 void *pParam, 355 size_t *pValueSize, 356 void *pValue) 357 { 358 int status = 0; 359 return status; 360 } 361 362 int ns_set_parameter(adnc_pfx_effect_t *effect, void *pParam, void *pValue) 363 { 364 int status = 0; 365 return status; 366 } 367 368 void ns_enable(adnc_pfx_effect_t *effect) 369 { 370 ALOGV("ns_enable [noop]"); 371 } 372 373 void ns_disable(adnc_pfx_effect_t *effect) 374 { 375 ALOGV("ns_disable [noop]"); 376 } 377 378 static const adnc_pfx_ops_t ns_ops = { 379 ns_create, 380 ns_init, 381 NULL, 382 ns_enable, 383 ns_disable, 384 ns_set_parameter, 385 ns_get_parameter, 386 NULL, 387 }; 388 389 390 //------------------------------------------------------------------------------ 391 // Automatic Gain Control (AGC) 392 //------------------------------------------------------------------------------ 393 int agc_init (adnc_pfx_effect_t *effect) 394 { 395 ALOGV("agc_init [noop]"); 396 397 return 0; 398 } 399 400 int agc_create(adnc_pfx_effect_t *effect) 401 { 402 ALOGV("agc_create %p", effect); 403 404 return agc_init (effect); 405 } 406 407 int agc_get_parameter(adnc_pfx_effect_t *effect, 408 void *pParam, 409 size_t *pValueSize, 410 void *pValue) 411 { 412 int status = 0; 413 return status; 414 } 415 416 int agc_set_parameter(adnc_pfx_effect_t *effect, void *pParam, void *pValue) 417 { 418 int status = 0; 419 return status; 420 } 421 422 void agc_enable(adnc_pfx_effect_t *effect) 423 { 424 ALOGV("agc_enable [noop]"); 425 } 426 427 void agc_disable(adnc_pfx_effect_t *effect) 428 { 429 ALOGV("agc_disable [noop]"); 430 } 431 432 static const adnc_pfx_ops_t agc_ops = { 433 agc_create, 434 agc_init, 435 NULL, 436 agc_enable, 437 agc_disable, 438 agc_set_parameter, 439 agc_get_parameter, 440 NULL, 441 }; 442 443 //------------------------------------------------------------------------------ 444 // 445 //------------------------------------------------------------------------------ 446 static const adnc_pfx_ops_t *sPreProcOps[PFX_ID_CNT] = { 447 &aec_ops, 448 &ns_ops, 449 &agc_ops 450 }; 451 452 //------------------------------------------------------------------------------ 453 // Pre-processing effect functions 454 //------------------------------------------------------------------------------ 455 extern const struct effect_interface_s sEffectInterface; 456 457 #define BAD_STATE_ABORT(from, to) \ 458 LOG_ALWAYS_FATAL("Bad state transition from %d to %d", from, to); 459 460 void AdncSession_SetProcEnabled(adnc_pfx_session_t *session, uint32_t procId, bool enabled); 461 462 int AdncPreProFx_SetState(adnc_pfx_effect_t *effect, uint32_t state) 463 { 464 int status = 0; 465 ALOGV("AdncPreProFx_SetState procId %d, new %d old %d", effect->procId, state, effect->state); 466 switch(state) { 467 case PFX_EFFECT_STATE_INIT: 468 switch(effect->state) { 469 case PFX_EFFECT_STATE_ACTIVE: 470 effect->ops->disable(effect); 471 AdncSession_SetProcEnabled(effect->session, effect->procId, false); 472 case PFX_EFFECT_STATE_CONFIG: 473 case PFX_EFFECT_STATE_CREATED: 474 case PFX_EFFECT_STATE_INIT: 475 break; 476 default: 477 BAD_STATE_ABORT(effect->state, state); 478 } 479 break; 480 case PFX_EFFECT_STATE_CREATED: 481 switch(effect->state) { 482 case PFX_EFFECT_STATE_INIT: 483 status = effect->ops->create(effect); 484 break; 485 case PFX_EFFECT_STATE_CREATED: 486 case PFX_EFFECT_STATE_ACTIVE: 487 case PFX_EFFECT_STATE_CONFIG: 488 ALOGE("Effect_SetState invalid transition"); 489 status = -ENOSYS; 490 break; 491 default: 492 BAD_STATE_ABORT(effect->state, state); 493 } 494 break; 495 case PFX_EFFECT_STATE_CONFIG: 496 switch(effect->state) { 497 case PFX_EFFECT_STATE_INIT: 498 ALOGE("Effect_SetState invalid transition"); 499 status = -ENOSYS; 500 break; 501 case PFX_EFFECT_STATE_ACTIVE: 502 effect->ops->disable(effect); 503 AdncSession_SetProcEnabled(effect->session, effect->procId, false); 504 break; 505 case PFX_EFFECT_STATE_CREATED: 506 case PFX_EFFECT_STATE_CONFIG: 507 break; 508 default: 509 BAD_STATE_ABORT(effect->state, state); 510 } 511 break; 512 case PFX_EFFECT_STATE_ACTIVE: 513 switch(effect->state) { 514 case PFX_EFFECT_STATE_INIT: 515 case PFX_EFFECT_STATE_CREATED: 516 ALOGE("Effect_SetState invalid transition"); 517 status = -ENOSYS; 518 break; 519 case PFX_EFFECT_STATE_ACTIVE: 520 // enabling an already enabled effect is just ignored 521 break; 522 case PFX_EFFECT_STATE_CONFIG: 523 effect->ops->enable(effect); 524 AdncSession_SetProcEnabled(effect->session, effect->procId, true); 525 break; 526 default: 527 BAD_STATE_ABORT(effect->state, state); 528 } 529 break; 530 default: 531 BAD_STATE_ABORT(effect->state, state); 532 } 533 if (status == 0) { 534 effect->state = state; 535 } 536 return status; 537 } 538 539 int AdncPreProFx_Init(adnc_pfx_effect_t *effect, uint32_t procId) 540 { 541 ALOGV(" AdncPreProFx_Init(procId=%d)", procId); 542 effect->itfe = &sEffectInterface; 543 effect->ops = sPreProcOps[procId]; 544 effect->procId = procId; 545 effect->state = PFX_EFFECT_STATE_INIT; 546 return 0; 547 } 548 549 int AdncPreProFx_Create(adnc_pfx_effect_t *effect, 550 adnc_pfx_session_t *session, 551 effect_handle_t *interface) 552 { 553 ALOGV(" AdncPreProFx_Create(effect=%p)", effect); 554 effect->session = session; 555 *interface = (effect_handle_t)&effect->itfe; 556 return AdncPreProFx_SetState(effect, PFX_EFFECT_STATE_CREATED); 557 } 558 559 int AdncPreProFx_Release(adnc_pfx_effect_t *effect) 560 { 561 return AdncPreProFx_SetState(effect, PFX_EFFECT_STATE_INIT); 562 } 563 564 565 //------------------------------------------------------------------------------ 566 // Session functions 567 //------------------------------------------------------------------------------ 568 /* 569 * Initialize a session context. 570 * Must be called with a lock on sAdncBundleLock. 571 */ 572 int AdncSession_Init_l(adnc_pfx_session_t *session) 573 { 574 ALOGV("AdncSession_Init()"); 575 size_t i; 576 int status = 0; 577 578 session->state = PFX_SESSION_STATE_INIT; 579 session->audioSource = AUDIO_SOURCE_DEFAULT; 580 //session->audioSessionId = ES305_SESSION_ID_NONE; // FIXME not used delete? 581 session->ioHandle = ES305_IO_HANDLE_NONE; 582 session->createdMsk = 0; 583 session->activeMsk = 0; 584 // initialize each effect for this session context 585 for (i = 0; i < PFX_ID_CNT && status == 0; i++) { 586 status = AdncPreProFx_Init(&session->effects[i], i); 587 } 588 return status; 589 } 590 591 /* 592 * Must be called with a lock on sAdncBundleLock. 593 */ 594 int AdncSession_CreateEffect_l(adnc_pfx_session_t *session, 595 int32_t procId, 596 effect_handle_t *interface) 597 { 598 int status = -ENOMEM; 599 ALOGV("AdncSession_CreateEffect handle=%d procId %d, old createdMsk %08x", 600 session->ioHandle, procId, session->createdMsk); 601 602 status = AdncPreProFx_Create(&session->effects[procId], session, interface); 603 if (status >= 0) { 604 ALOGV(" AdncSession_CreateEffect OK"); 605 session->createdMsk |= (1 << procId); 606 } 607 return status; 608 } 609 610 int AdncSession_SetConfig(adnc_pfx_session_t *session, effect_config_t *config) 611 { 612 ALOGV("AdncSession_SetConfig [noop]"); 613 return 0; 614 } 615 616 void AdncSession_GetConfig(adnc_pfx_session_t *session, effect_config_t *config) 617 { 618 ALOGV("AdncSession_GetConfig [noop]"); 619 } 620 621 int AdncSession_SetReverseConfig(adnc_pfx_session_t *session, effect_config_t *config) 622 { 623 ALOGV("AdncSession_SetReverseConfig [noop]"); 624 return 0; 625 } 626 627 void AdncSession_GetReverseConfig(adnc_pfx_session_t *session, effect_config_t *config) 628 { 629 ALOGV("AdncSession_GetReverseConfig [noop]"); 630 } 631 632 void AdncSession_SetProcEnabled(adnc_pfx_session_t *session, uint32_t procId, bool enabled) 633 { 634 ALOGV("AdncSession_SetProcEnabled [noop] proc %d, enabled %d", procId, enabled); 635 //no need to reevaluate session settings, if recording is currently ongoing, we'll reevaluate 636 // through eS305_AddEffect() 637 } 638 639 int AdncSession_SetSource(adnc_pfx_session_t *session, audio_source_t source) 640 { 641 session->audioSource = source; 642 return 0; 643 } 644 645 //------------------------------------------------------------------------------ 646 // Bundle functions 647 //------------------------------------------------------------------------------ 648 #define ADNC_BUNDLE_NO_INIT 1 649 static int sAdncBundleInitStatus = ADNC_BUNDLE_NO_INIT; 650 static adnc_pfx_session_t sAdncSessions[ADNC_PFX_NUM_SESSION]; 651 static pthread_mutex_t sAdncBundleLock; 652 653 /* Returns a session context for the given IO handle 654 * Returns an existing session context if the IO handle matches, initializes a new one otherwise. 655 * Returns NULL if no more session contexts are available 656 * Must be called with a lock on sAdncBundleLock 657 */ 658 adnc_pfx_session_t *AdncBundle_GetSession_l(int32_t procId, int32_t sessionId, int32_t ioId) 659 { 660 size_t i; 661 for (i = 0; i < ADNC_PFX_NUM_SESSION; i++) { 662 if (sAdncSessions[i].ioHandle == ioId) { 663 return &sAdncSessions[i]; 664 } 665 } 666 for (i = 0; i < ADNC_PFX_NUM_SESSION; i++) { 667 if (sAdncSessions[i].ioHandle == ES305_IO_HANDLE_NONE) { 668 //sAdncSessions[i].audioSessionId = sessionId; // FIXME not used delete? 669 sAdncSessions[i].ioHandle = ioId; 670 return &sAdncSessions[i]; 671 } 672 } 673 ALOGV("AdncBundle_GetSession_l"); 674 return NULL; 675 } 676 677 /* 678 * Must be called with a lock on sAdncBundleLock. 679 */ 680 int AdncBundle_Init_l() { 681 size_t i; 682 int status = 0; 683 684 if (sAdncBundleInitStatus <= 0) { 685 return sAdncBundleInitStatus; 686 } 687 // initialize all the session contexts that this bundle supports 688 for (i = 0; i < ADNC_PFX_NUM_SESSION && status == 0; i++) { 689 status = AdncSession_Init_l(&sAdncSessions[i]); 690 } 691 sAdncBundleInitStatus = status; 692 return sAdncBundleInitStatus; 693 } 694 695 /* 696 * Must be called with a lock on sAdncBundleLock. 697 */ 698 int AdncBundle_Release_l() { 699 ALOGV("AdncBundle_Release_l()"); 700 701 Adnc_SleepInt_l(); 702 703 for (int i = 0 ; i < ES305_NUM_CTRL ; i++) { 704 if (eS305_ctrl.fd[i] >= 0) { 705 close(eS305_ctrl.fd[i]); 706 } 707 eS305_ctrl.fd[i] = -1; 708 } 709 return 0; 710 } 711 712 const effect_descriptor_t *AdncBundle_GetDescriptor(const effect_uuid_t *uuid) 713 { 714 size_t i; 715 for (i = 0; i < PFX_ID_CNT; i++) { 716 if (memcmp(&adnc_pfx_descriptors[i]->uuid, uuid, sizeof(effect_uuid_t)) == 0) { 717 return adnc_pfx_descriptors[i]; 718 } 719 } 720 return NULL; 721 } 722 723 /* 724 * Debug only: display session contexts 725 */ 726 void AdncBundle_logv_dumpSessions() { 727 ALOGV("Sessions:"); 728 for (int i=0 ; i<ADNC_PFX_NUM_SESSION ; i++) { 729 ALOGV(" session %d handle=%d cre=%2x act=%2x", 730 i, sAdncSessions[i].ioHandle, sAdncSessions[i].createdMsk, sAdncSessions[i].activeMsk); 731 } 732 } 733 734 //------------------------------------------------------------------------------ 735 // Effect Control Interface Implementation 736 //------------------------------------------------------------------------------ 737 int AdncVoiceProcessingFx_Command(effect_handle_t self, 738 uint32_t cmdCode, 739 uint32_t cmdSize, 740 void *pCmdData, 741 uint32_t *replySize, 742 void *pReplyData) 743 { 744 adnc_pfx_effect_t * effect = (adnc_pfx_effect_t *) self; 745 int retsize; 746 int status; 747 748 if (effect == NULL){ 749 return -EINVAL; 750 } 751 752 ALOGV("AdncVoiceProcessingFx_Command: command %d cmdSize %d",cmdCode, cmdSize); 753 754 switch (cmdCode){ 755 case EFFECT_CMD_INIT: 756 if (pReplyData == NULL || *replySize != sizeof(int)){ 757 return -EINVAL; 758 } 759 if (effect->ops->init) { 760 effect->ops->init(effect); 761 } 762 *(int *)pReplyData = 0; 763 break; 764 765 case EFFECT_CMD_SET_CONFIG: { 766 if (pCmdData == NULL|| 767 cmdSize != sizeof(effect_config_t)|| 768 pReplyData == NULL|| 769 *replySize != sizeof(int)){ 770 ALOGV("AdncVoiceProcessingFx_Command cmdCode Case: " 771 "EFFECT_CMD_SET_CONFIG: ERROR"); 772 return -EINVAL; 773 } 774 775 *(int *)pReplyData = AdncSession_SetConfig(effect->session, (effect_config_t *)pCmdData); 776 777 if (*(int *)pReplyData != 0) { 778 break; 779 } 780 if (effect->state != PFX_EFFECT_STATE_ACTIVE) { 781 *(int *)pReplyData = AdncPreProFx_SetState(effect, PFX_EFFECT_STATE_CONFIG); 782 } 783 } break; 784 785 case EFFECT_CMD_GET_CONFIG: 786 if (pReplyData == NULL || 787 *replySize != sizeof(effect_config_t)) { 788 ALOGV("\tLVM_ERROR : AdncVoiceProcessingFx_Command cmdCode Case: " 789 "EFFECT_CMD_GET_CONFIG: ERROR"); 790 return -EINVAL; 791 } 792 793 AdncSession_GetConfig(effect->session, (effect_config_t *)pReplyData); 794 break; 795 796 case EFFECT_CMD_SET_CONFIG_REVERSE: 797 if (pCmdData == NULL || 798 cmdSize != sizeof(effect_config_t) || 799 pReplyData == NULL || 800 *replySize != sizeof(int)) { 801 ALOGV("AdncVoiceProcessingFx_Command cmdCode Case: " 802 "EFFECT_CMD_SET_CONFIG_REVERSE: ERROR"); 803 return -EINVAL; 804 } 805 *(int *)pReplyData = AdncSession_SetReverseConfig(effect->session, 806 (effect_config_t *)pCmdData); 807 if (*(int *)pReplyData != 0) { 808 break; 809 } 810 break; 811 812 case EFFECT_CMD_GET_CONFIG_REVERSE: 813 if (pReplyData == NULL || 814 *replySize != sizeof(effect_config_t)){ 815 ALOGV("AdncVoiceProcessingFx_Command cmdCode Case: " 816 "EFFECT_CMD_GET_CONFIG_REVERSE: ERROR"); 817 return -EINVAL; 818 } 819 AdncSession_GetReverseConfig(effect->session, (effect_config_t *)pCmdData); 820 break; 821 822 case EFFECT_CMD_RESET: 823 if (effect->ops->reset) { 824 effect->ops->reset(effect); 825 } 826 break; 827 828 case EFFECT_CMD_GET_PARAM:{ 829 if (pCmdData == NULL || 830 cmdSize < (int)sizeof(effect_param_t) || 831 pReplyData == NULL || 832 *replySize < (int)sizeof(effect_param_t)){ 833 ALOGV("AdncVoiceProcessingFx_Command cmdCode Case: " 834 "EFFECT_CMD_GET_PARAM: ERROR"); 835 return -EINVAL; 836 } 837 effect_param_t *p = (effect_param_t *)pCmdData; 838 839 memcpy(pReplyData, pCmdData, sizeof(effect_param_t) + p->psize); 840 841 p = (effect_param_t *)pReplyData; 842 843 int voffset = ((p->psize - 1) / sizeof(int32_t) + 1) * sizeof(int32_t); 844 845 if (effect->ops->get_parameter) { 846 p->status = effect->ops->get_parameter(effect, p->data, 847 (size_t *)&p->vsize, 848 p->data + voffset); 849 *replySize = sizeof(effect_param_t) + voffset + p->vsize; 850 } 851 } break; 852 853 case EFFECT_CMD_SET_PARAM:{ 854 if (pCmdData == NULL|| 855 cmdSize < (int)sizeof(effect_param_t) || 856 pReplyData == NULL || 857 *replySize != sizeof(int32_t)){ 858 ALOGV("AdncVoiceProcessingFx_Command cmdCode Case: " 859 "EFFECT_CMD_SET_PARAM: ERROR"); 860 return -EINVAL; 861 } 862 effect_param_t *p = (effect_param_t *) pCmdData; 863 864 if (p->psize != sizeof(int32_t)){ 865 ALOGV("AdncVoiceProcessingFx_Command cmdCode Case: " 866 "EFFECT_CMD_SET_PARAM: ERROR, psize is not sizeof(int32_t)"); 867 return -EINVAL; 868 } 869 if (effect->ops->set_parameter) { 870 *(int *)pReplyData = effect->ops->set_parameter(effect, 871 (void *)p->data, 872 p->data + p->psize); 873 } 874 } break; 875 876 case EFFECT_CMD_ENABLE: 877 if (pReplyData == NULL || *replySize != sizeof(int)){ 878 ALOGV("AdncVoiceProcessingFx_Command cmdCode Case: EFFECT_CMD_ENABLE: ERROR"); 879 return -EINVAL; 880 } 881 *(int *)pReplyData = AdncPreProFx_SetState(effect, PFX_EFFECT_STATE_ACTIVE); 882 break; 883 884 case EFFECT_CMD_DISABLE: 885 if (pReplyData == NULL || *replySize != sizeof(int)){ 886 ALOGV("AdncVoiceProcessingFx_Command cmdCode Case: EFFECT_CMD_DISABLE: ERROR"); 887 return -EINVAL; 888 } 889 *(int *)pReplyData = AdncPreProFx_SetState(effect, PFX_EFFECT_STATE_CONFIG); 890 break; 891 892 case EFFECT_CMD_SET_DEVICE: 893 case EFFECT_CMD_SET_INPUT_DEVICE: 894 if (pCmdData == NULL || 895 cmdSize != sizeof(uint32_t)) { 896 ALOGV("AdncVoiceProcessingFx_Command cmdCode Case: EFFECT_CMD_SET_DEVICE: ERROR"); 897 return -EINVAL; 898 } 899 900 if (effect->ops->set_device) { 901 effect->ops->set_device(effect, *(uint32_t *)pCmdData); 902 } 903 break; 904 905 case EFFECT_CMD_SET_VOLUME: 906 case EFFECT_CMD_SET_AUDIO_MODE: 907 case EFFECT_CMD_SET_FEATURE_CONFIG: 908 break; 909 910 case EFFECT_CMD_SET_AUDIO_SOURCE: 911 if (pCmdData == NULL || 912 cmdSize != sizeof(uint32_t)) { 913 ALOGV("AdncVoiceProcessingFx_Command cmdCode Case: EFFECT_CMD_SET_AUDIO_SOURCE: ERROR"); 914 return -EINVAL; 915 } 916 return AdncSession_SetSource(effect->session, (audio_source_t) *(uint32_t *)pCmdData); 917 break; 918 919 default: 920 return -EINVAL; 921 } 922 return 0; 923 } 924 925 926 int AdncVoiceProcessingFx_GetDescriptor(effect_handle_t self, 927 effect_descriptor_t *pDescriptor) 928 { 929 adnc_pfx_effect_t * effect = (adnc_pfx_effect_t *) self; 930 931 if (effect == NULL || pDescriptor == NULL) { 932 return -EINVAL; 933 } 934 935 memcpy(pDescriptor, adnc_pfx_descriptors[effect->procId], sizeof(effect_descriptor_t)); 936 937 return 0; 938 } 939 940 941 // effect_handle_t interface implementation for effect 942 const struct effect_interface_s sEffectInterface = { 943 NULL, /* Process */ 944 AdncVoiceProcessingFx_Command, 945 AdncVoiceProcessingFx_GetDescriptor, 946 NULL 947 }; 948 //------------------------------------------------------------------------------ 949 // Effect Library Interface Implementation 950 //------------------------------------------------------------------------------ 951 952 int adnc_create(const effect_uuid_t *uuid, 953 int32_t sessionId, 954 int32_t ioId, 955 effect_handle_t *pInterface) 956 { 957 ALOGV("adnc_create: uuid: %08x session %d IO: %d", uuid->timeLow, sessionId, ioId); 958 959 int status = 0; 960 const effect_descriptor_t *desc; 961 adnc_pfx_session_t *session; 962 uint32_t procId; 963 964 pthread_mutex_lock(&sAdncBundleLock); 965 966 if (AdncBundle_Init_l() != 0) { 967 status = sAdncBundleInitStatus; 968 goto exit; 969 } 970 971 desc = AdncBundle_GetDescriptor(uuid); 972 if (desc == NULL) { 973 ALOGW(" adnc_create: fx not found uuid: %08x", uuid->timeLow); 974 status = -EINVAL; 975 goto exit; 976 } 977 procId = Adnc_UuidToProcId(&desc->type); 978 979 session = AdncBundle_GetSession_l(procId, sessionId, ioId); 980 if (session == NULL) { 981 ALOGW(" adnc_create: no more session available"); 982 status = -EINVAL; 983 goto exit; 984 } 985 986 status = AdncSession_CreateEffect_l(session, procId, pInterface); 987 988 if (status < 0 && session->createdMsk == 0) { 989 session->ioHandle = ES305_IO_HANDLE_NONE; 990 } 991 992 exit: 993 pthread_mutex_unlock(&sAdncBundleLock); 994 return status; 995 } 996 997 int adnc_release(effect_handle_t interface) 998 { 999 int i, status = 0; 1000 ALOGV("adnc_release %p", interface); 1001 1002 // the effect handle comes from the effect framework, ok to cast 1003 const adnc_pfx_effect_t * fx = (adnc_pfx_effect_t *) interface; 1004 1005 const uint32_t removalMsk = ~(1 << fx->procId); 1006 1007 pthread_mutex_lock(&sAdncBundleLock); 1008 1009 if (AdncBundle_Init_l() != 0) { 1010 status = sAdncBundleInitStatus; 1011 goto exit; 1012 } 1013 1014 if (fx->session->ioHandle == 0) { 1015 status = -EINVAL; 1016 goto exit; 1017 } 1018 1019 // effect is released, flag it as inactive and not created 1020 fx->session->createdMsk &= removalMsk; 1021 fx->session->activeMsk &= removalMsk; 1022 1023 // configuration has changed, reevaluate 1024 status = Adnc_ReevaluateUsageInt_l(fx->session->ioHandle); 1025 // not checking the return status here: if there was an error, 1026 // we still need to free the session and wouldn't exit here 1027 1028 // free session if it has no more effects 1029 if (fx->session->createdMsk == 0) { 1030 ALOGV(" resetting session on handle %d after effect release", fx->session->ioHandle); 1031 const int statusInit = AdncSession_Init_l(fx->session); 1032 if (status == 0) { 1033 status = statusInit; 1034 } 1035 } 1036 1037 exit: 1038 pthread_mutex_unlock(&sAdncBundleLock); 1039 return status; 1040 } 1041 1042 int adnc_get_descriptor(const effect_uuid_t *uuid, effect_descriptor_t *pDescriptor) { 1043 if (pDescriptor == NULL || uuid == NULL){ 1044 ALOGV("adnc_get_descriptor() invalid params"); 1045 return -EINVAL; 1046 } 1047 1048 const effect_descriptor_t *desc = AdncBundle_GetDescriptor(uuid); 1049 if (desc == NULL) { 1050 ALOGV("adnc_get_descriptor() not found"); 1051 return -EINVAL; 1052 } 1053 1054 ALOGV("adnc_get_descriptor() got fx %s", desc->name); 1055 1056 memcpy(pDescriptor, desc, sizeof(effect_descriptor_t)); 1057 return 0; 1058 } 1059 1060 audio_effect_library_t AUDIO_EFFECT_LIBRARY_INFO_SYM = { 1061 tag : AUDIO_EFFECT_LIBRARY_TAG, 1062 version : EFFECT_LIBRARY_API_VERSION, 1063 name : "Audience Voice Preprocessing Library", 1064 implementor : "The Android Open Source Project", 1065 create_effect : adnc_create, 1066 release_effect : adnc_release, 1067 get_descriptor : adnc_get_descriptor 1068 }; 1069 1070 //------------------------------------------------------- 1071 // eS305 control interface 1072 //------------------------------------------------------- 1073 int Adnc_SetAutomaticGainControlInt_l(bool agc_on) 1074 { 1075 ALOGV("Adnc_SetAutomaticGainControlInt_l(%d)", agc_on); 1076 1077 if (eS305_ctrl.fd[ES305_CTRL_TX_AGC_ENABLE] < 0) { 1078 ALOGV(" opening eS305 path for agc"); 1079 eS305_ctrl.fd[ES305_CTRL_TX_AGC_ENABLE] = open(ES305_TX_AGC_ENABLE_PATH, O_RDWR); 1080 if (eS305_ctrl.fd[ES305_CTRL_TX_AGC_ENABLE] < 0) { 1081 ALOGE(" Cannot open eS305 path for agc: %s", strerror(errno)); 1082 return -ENODEV; 1083 } 1084 } 1085 1086 if (agc_on) { 1087 write(eS305_ctrl.fd[ES305_CTRL_TX_AGC_ENABLE], ES305_AGC_ON, strlen(ES305_AGC_ON)); 1088 } else { 1089 write(eS305_ctrl.fd[ES305_CTRL_TX_AGC_ENABLE], ES305_AEC_OFF, strlen(ES305_AGC_OFF)); 1090 } 1091 return 0; 1092 } 1093 1094 int Adnc_SetEchoCancellationInt_l(bool aec_on) 1095 { 1096 ALOGV("Adnc_SetEchoCancellationInt_l(%d)", aec_on); 1097 1098 if (eS305_ctrl.fd[ES305_CTRL_AEC_ENABLE] < 0) { 1099 ALOGV(" opening eS305 path for aec"); 1100 eS305_ctrl.fd[ES305_CTRL_AEC_ENABLE] = open(ES305_AEC_ENABLE_PATH, O_RDWR); 1101 if (eS305_ctrl.fd[ES305_CTRL_AEC_ENABLE] < 0) { 1102 ALOGE(" Cannot open eS305 path for aec: %s", strerror(errno)); 1103 return -ENODEV; 1104 } 1105 } 1106 1107 if (aec_on) { 1108 write(eS305_ctrl.fd[ES305_CTRL_AEC_ENABLE], ES305_AEC_ON, strlen(ES305_AEC_ON)); 1109 } else { 1110 write(eS305_ctrl.fd[ES305_CTRL_AEC_ENABLE], ES305_AEC_OFF, strlen(ES305_AEC_OFF)); 1111 } 1112 return 0; 1113 } 1114 1115 int Adnc_SetNoiseSuppressionInt_l(bool ns_on) 1116 { 1117 ALOGV("Adnc_SetNoiseSuppressionInt(%d)", ns_on); 1118 1119 if (eS305_ctrl.fd[ES305_CTRL_TX_NS_LEVEL] < 0) { 1120 ALOGV(" opening eS305 path for ns"); 1121 eS305_ctrl.fd[ES305_CTRL_TX_NS_LEVEL] = open(ES305_TX_NS_LEVEL_PATH, O_RDWR); 1122 if (eS305_ctrl.fd[ES305_CTRL_TX_NS_LEVEL] < 0) { 1123 ALOGE(" Cannot open eS305 path for ns: %s", strerror(errno)); 1124 return -ENODEV; 1125 } 1126 } 1127 1128 if (ns_on) { 1129 if (eS305_ctrl.requested_preset == ES305_PRESET_ASRA_HANDHELD) { 1130 ALOGV(" setting ns to %s", ES305_NS_VOICE_REC_HANDHELD_ON); 1131 write(eS305_ctrl.fd[ES305_CTRL_TX_NS_LEVEL], 1132 ES305_NS_VOICE_REC_HANDHELD_ON, strlen(ES305_NS_VOICE_REC_HANDHELD_ON)); 1133 } else if ((eS305_ctrl.requested_preset == ES305_PRESET_ASRA_DESKTOP) 1134 || (eS305_ctrl.requested_preset == ES305_PRESET_ASRA_HEADSET)) { 1135 ALOGV(" setting ns to %s", ES305_NS_VOICE_REC_SINGLE_MIC_ON); 1136 write(eS305_ctrl.fd[ES305_CTRL_TX_NS_LEVEL], 1137 ES305_NS_VOICE_REC_SINGLE_MIC_ON, strlen(ES305_NS_VOICE_REC_SINGLE_MIC_ON)); 1138 } else { 1139 ALOGV(" setting ns to %s", ES305_NS_DEFAULT_ON); 1140 write(eS305_ctrl.fd[ES305_CTRL_TX_NS_LEVEL], 1141 ES305_NS_DEFAULT_ON, strlen(ES305_NS_DEFAULT_ON)); 1142 } 1143 } else { 1144 ALOGV(" setting ns to %s", ES305_NS_OFF); 1145 write(eS305_ctrl.fd[ES305_CTRL_TX_NS_LEVEL], ES305_NS_OFF, strlen(ES305_NS_OFF)); 1146 } 1147 return 0; 1148 } 1149 1150 int Adnc_SetVoiceProcessingInt_l(bool vp_on) 1151 { 1152 if (eS305_ctrl.fd[ES305_CTRL_VOICE_PROCESSING] < 0) { 1153 ALOGV(" opening eS305 path for VP"); 1154 eS305_ctrl.fd[ES305_CTRL_VOICE_PROCESSING] = open(ES305_VOICE_PROCESSING_PATH, O_RDWR); 1155 if (eS305_ctrl.fd[ES305_CTRL_VOICE_PROCESSING] < 0) { 1156 ALOGE(" cannot open eS305 path for VP: %s", strerror(errno)); 1157 return -ENODEV; 1158 } 1159 } 1160 if (vp_on) { 1161 write(eS305_ctrl.fd[ES305_CTRL_VOICE_PROCESSING], ES305_ON, strlen(ES305_ON)); 1162 } else { 1163 write(eS305_ctrl.fd[ES305_CTRL_VOICE_PROCESSING], ES305_OFF, strlen(ES305_OFF)); 1164 } 1165 return 0; 1166 } 1167 1168 /* 1169 * Put the eS305 to sleep 1170 * Post condition when no error: eS305_ctrl.current_preset == ES305_PRESET_OFF 1171 */ 1172 int Adnc_SleepInt_l() 1173 { 1174 if (eS305_ctrl.current_preset == ES305_PRESET_OFF) { 1175 return 0; 1176 } 1177 1178 ALOGV(" Adnc_SleepInt()_l setting VP off + sleep 1"); 1179 1180 Adnc_SetVoiceProcessingInt_l(false /*vp_on*/); 1181 1182 ALOGV(" Adnc_SetSleepInt_l"); 1183 if (eS305_ctrl.fd[ES305_CTRL_SLEEP] < 0) { 1184 ALOGV(" opening eS305 path for sleep"); 1185 eS305_ctrl.fd[ES305_CTRL_SLEEP] = open(ES305_SLEEP_PATH, O_RDWR); 1186 if (eS305_ctrl.fd[ES305_CTRL_SLEEP] < 0) { 1187 ALOGE(" cannot open eS305 path for sleep: %s", strerror(errno)); 1188 return -ENODEV; 1189 } 1190 } 1191 1192 write(eS305_ctrl.fd[ES305_CTRL_SLEEP], ES305_ON, strlen(ES305_ON)); 1193 1194 eS305_ctrl.current_preset = ES305_PRESET_OFF; 1195 1196 return 0; 1197 } 1198 1199 /* 1200 * Apply the eS305_ctrl.requested_preset preset after turning VP on 1201 * Post condition when no error: eS305_ctrl.current_preset == eS305_ctrl.requested_preset 1202 */ 1203 int Adnc_ApplyPresetInt_l() 1204 { 1205 ALOGV("Adnc_ApplyPresetInt() current_preset=%d, requested_preset=%d", 1206 eS305_ctrl.current_preset, eS305_ctrl.requested_preset); 1207 1208 if (eS305_ctrl.requested_preset == eS305_ctrl.current_preset) { 1209 ALOGV(" nothing to do, preset %d is current", eS305_ctrl.requested_preset); 1210 return 0; 1211 } 1212 1213 // preset off implies going to sleep 1214 if (eS305_ctrl.requested_preset == ES305_PRESET_OFF) { 1215 return Adnc_SleepInt_l(); 1216 } 1217 1218 // voice processing must be on before setting the preset 1219 if ((eS305_ctrl.current_preset == ES305_PRESET_OFF) 1220 || (eS305_ctrl.current_preset == ES305_PRESET_INIT)) { 1221 const int status = Adnc_SetVoiceProcessingInt_l(true /*vp_on*/); 1222 if (status != 0) { 1223 return status; 1224 } 1225 } 1226 1227 if (eS305_ctrl.fd[ES305_CTRL_PRESET] < 0) { 1228 ALOGV(" opening eS305 path for PRESET"); 1229 eS305_ctrl.fd[ES305_CTRL_PRESET] = open(ES305_PRESET_PATH, O_RDWR); 1230 } 1231 if (eS305_ctrl.fd[ES305_CTRL_PRESET] < 0) { 1232 ALOGE(" Cannot open eS305 path for PRESET: %s", strerror(errno)); 1233 return -ENODEV; 1234 } 1235 1236 char str[8]; 1237 sprintf(str, "%d", eS305_ctrl.requested_preset); 1238 write(eS305_ctrl.fd[ES305_CTRL_PRESET], str, strlen(str)); 1239 1240 eS305_ctrl.current_preset = eS305_ctrl.requested_preset; 1241 1242 return 0; 1243 } 1244 1245 1246 /* 1247 * Apply the settings of given the session context 1248 */ 1249 int Adnc_ApplySettingsFromSessionContextInt_l(adnc_pfx_session_t * session) 1250 { 1251 ALOGV("Adnc_ApplySettingsFromSessionContextInt_l cre=%2x ac=%2x handle=%d", 1252 session->createdMsk, session->activeMsk, session->ioHandle); 1253 int status = 0; 1254 1255 if (session->ioHandle != eS305_ctrl.ioHandle) { 1256 return status; 1257 } 1258 1259 // NS: special case of noise suppression, always reset according to effect state 1260 // as default desirable value might differ from the preset 1261 const bool ns_on = ((session->activeMsk & (1 << PFX_ID_NS)) != 0); 1262 status = Adnc_SetNoiseSuppressionInt_l(ns_on /*ns_on*/); 1263 1264 // AEC 1265 if (session->createdMsk & (1 << PFX_ID_AEC)) { /* the effect has been created */ 1266 const bool aec_on = ((session->activeMsk & (1 << PFX_ID_AEC)) != 0); 1267 int aec_status = Adnc_SetEchoCancellationInt_l(aec_on /*aec_on*/); 1268 if (status == 0) { 1269 status = aec_status; 1270 } 1271 } 1272 1273 // AGC 1274 if (session->createdMsk & (1 << PFX_ID_AGC)) { /* the effect has been created */ 1275 const bool agc_on = ((session->activeMsk & (1 << PFX_ID_AGC)) != 0); 1276 int agc_status = Adnc_SetAutomaticGainControlInt_l(agc_on /*agc_on*/); 1277 if (status == 0) { 1278 status = agc_status; 1279 } 1280 } 1281 1282 return status; 1283 } 1284 1285 /* 1286 * Return a value between 0 and ADNC_PFX_NUM_SESSION-1 if a session context has the given handle, 1287 * -1 if the handle isn't in handled by one of the sessions. 1288 * Must be called with a lock on sAdncBundleLock 1289 */ 1290 int Adnc_SessionNumberForHandle_l(audio_io_handle_t handle) 1291 { 1292 for (int i = 0 ; i < ADNC_PFX_NUM_SESSION ; i++) { 1293 if (sAdncSessions[i].ioHandle == handle) { 1294 return i; 1295 } 1296 } 1297 return -1; 1298 } 1299 1300 1301 /* 1302 * Apply the settings of the session matching the given IO handle. 1303 * Must be called with a lock on sAdncBundleLock 1304 */ 1305 int Adnc_ApplySettingsForHandleInt_l(audio_io_handle_t handle) 1306 { 1307 ALOGV(" Adnc_ApplySettingsForHandleInt_l(handle=%d)", handle); 1308 // indicates whether this effect bundle currently has a session context for this IO handle 1309 bool hasSession = false; 1310 int status = 0; 1311 int i; 1312 1313 if (sAdncBundleInitStatus != 0) { 1314 // This assumes that the default config of the eS305 after setting a preset 1315 // is the correct configuration. 1316 ALOGV(" no effect settings to apply for IO handle %d, no effect bundle", handle); 1317 return status; 1318 } 1319 1320 const int sessionId = Adnc_SessionNumberForHandle_l(handle); 1321 if (sessionId >= 0) { 1322 ALOGV(" applying settings from session num %d", sessionId); 1323 status = Adnc_ApplySettingsFromSessionContextInt_l( &sAdncSessions[sessionId] ); 1324 } 1325 else { 1326 ALOGV(" no session found for handle %d", handle); 1327 } 1328 1329 return status; 1330 } 1331 1332 /* 1333 * Reevaluate the usage of the eS305 based on the given IO handle. 1334 * Must be called with a lock on sAdncBundleLock 1335 */ 1336 int Adnc_ReevaluateUsageInt_l(audio_io_handle_t handle) 1337 { 1338 ALOGV(" Adnc_ReevaluateUsageInt_l(handle=%d) current_preset=%d requested_preset=%d", 1339 handle, eS305_ctrl.current_preset, eS305_ctrl.requested_preset); 1340 int status = 0; 1341 if ((eS305_ctrl.requested_preset == ES305_PRESET_OFF) || (handle == ES305_IO_HANDLE_NONE)) { 1342 status = Adnc_SleepInt_l(); 1343 } else { 1344 const int sessionId = Adnc_SessionNumberForHandle_l(handle); 1345 if (sessionId >= 0) { 1346 // recording active, use the preset only if there is an effect, 1347 // reset preset to off otherwise 1348 if (sAdncSessions[sessionId].activeMsk != 0) { 1349 status = Adnc_ApplyPresetInt_l(); 1350 if (status == 0) { 1351 //apply the settings of the session associated with the handle (if any) 1352 status = Adnc_ApplySettingsForHandleInt_l(handle); 1353 } 1354 } else { 1355 status = Adnc_SleepInt_l(); 1356 } 1357 } 1358 } 1359 return status; 1360 } 1361 1362 1363 //------------------------------------------------------- 1364 // eS305 public control interface from HAL 1365 //------------------------------------------------------- 1366 int eS305_UsePreset(int preset) 1367 { 1368 ALOGV("eS305_UsePreset(%d) current=%d handle=%d", 1369 preset, eS305_ctrl.current_preset, eS305_ctrl.ioHandle); 1370 1371 int status = 0; 1372 1373 pthread_mutex_lock(&sAdncBundleLock); 1374 1375 //if (preset != -1) { AdncBundle_logv_dumpSessions(); } 1376 1377 // allow preset transition from any preset to any other during recording, 1378 // except from one ASRA preset to another 1379 if (eS305_ctrl.ioHandle != ES305_IO_HANDLE_NONE) { 1380 switch(eS305_ctrl.current_preset) { 1381 case ES305_PRESET_ASRA_HANDHELD: 1382 case ES305_PRESET_ASRA_DESKTOP: 1383 case ES305_PRESET_ASRA_HEADSET: 1384 switch(preset) { 1385 case ES305_PRESET_ASRA_HANDHELD: 1386 case ES305_PRESET_ASRA_DESKTOP: 1387 case ES305_PRESET_ASRA_HEADSET: 1388 ALOGV(" not switching from ASRA preset %d to %d during voice recognition", 1389 eS305_ctrl.current_preset, preset); 1390 status = -EINVAL; 1391 goto exit; 1392 default: 1393 // transitioning from ASRA to non-ASRA: valid 1394 break; 1395 } 1396 break; 1397 default: 1398 // transitioning from non-ASRA: valid 1399 break; 1400 } 1401 } 1402 1403 eS305_ctrl.requested_preset = preset; 1404 1405 status = AdncBundle_Init_l(); 1406 if (status != 0) { 1407 ALOGE(" error applying preset, bundle failed to initialize"); 1408 goto exit; 1409 } 1410 1411 status = Adnc_ReevaluateUsageInt_l(eS305_ctrl.ioHandle); 1412 1413 exit: 1414 pthread_mutex_unlock(&sAdncBundleLock); 1415 return status; 1416 } 1417 1418 1419 int eS305_SetActiveIoHandle(audio_io_handle_t handle) 1420 { 1421 ALOGV("eS305_SetActiveIoHandle(%d)", handle); 1422 1423 pthread_mutex_lock(&sAdncBundleLock); 1424 1425 int status = AdncBundle_Init_l(); 1426 if (status != 0) { 1427 ALOGE(" error setting active handle, bundle failed to initialize"); 1428 pthread_mutex_unlock(&sAdncBundleLock); 1429 return status; 1430 } 1431 1432 status = Adnc_ReevaluateUsageInt_l(handle); 1433 1434 if (status == 0) { 1435 eS305_ctrl.ioHandle = handle; 1436 } else { 1437 ALOGE(" failed to update for new handle %d (current preset = %d)", 1438 handle, eS305_ctrl.current_preset); 1439 } 1440 1441 pthread_mutex_unlock(&sAdncBundleLock); 1442 1443 return status; 1444 } 1445 1446 1447 int eS305_AddEffect(effect_descriptor_t * descr, audio_io_handle_t handle) 1448 { 1449 ALOGV("eS305_AddEffect(handle=%d)", handle); 1450 1451 pthread_mutex_lock(&sAdncBundleLock); 1452 1453 int status = AdncBundle_Init_l(); 1454 if (status != 0) { 1455 ALOGE(" error setting adding effect, bundle failed to initialize"); 1456 pthread_mutex_unlock(&sAdncBundleLock); 1457 return status; 1458 } 1459 1460 if (descr == NULL){ 1461 ALOGV(" eS305_AddEffect() ERROR effect descriptor is NULL"); 1462 pthread_mutex_unlock(&sAdncBundleLock); 1463 return -EINVAL; 1464 } 1465 1466 uint32_t procId = Adnc_UuidToProcId(&descr->type); 1467 1468 adnc_pfx_session_t * session = AdncBundle_GetSession_l( 1469 procId, ES305_SESSION_ID_NONE, handle/*ioId*/); 1470 1471 if (session != NULL) { 1472 // mark the effect as active 1473 session->activeMsk |= (1 << procId); 1474 1475 // update settings if necessary 1476 Adnc_ReevaluateUsageInt_l(session->ioHandle); 1477 } 1478 1479 pthread_mutex_unlock(&sAdncBundleLock); 1480 1481 return status; 1482 } 1483 1484 1485 int eS305_RemoveEffect(effect_descriptor_t * descr, audio_io_handle_t handle) 1486 { 1487 ALOGV("eS305_RemoveEffect()"); 1488 1489 pthread_mutex_lock(&sAdncBundleLock); 1490 1491 int status = AdncBundle_Init_l(); 1492 if (status != 0) { 1493 ALOGE(" error setting removing effect, bundle failed to initialize"); 1494 pthread_mutex_unlock(&sAdncBundleLock); 1495 return status; 1496 } 1497 1498 if (descr == NULL){ 1499 ALOGV(" eS305_AddEffect() ERROR effect descriptor is NULL"); 1500 pthread_mutex_unlock(&sAdncBundleLock); 1501 return -EINVAL; 1502 } 1503 1504 uint32_t procId = Adnc_UuidToProcId(&descr->type); 1505 1506 adnc_pfx_session_t * session = AdncBundle_GetSession_l( 1507 procId, ES305_SESSION_ID_NONE, handle/*ioId*/); 1508 1509 if (session != NULL) { 1510 // mark the effect as inactive 1511 session->activeMsk &= ~(1 << procId); 1512 1513 // update settings if necessary 1514 Adnc_ReevaluateUsageInt_l(session->ioHandle); 1515 } 1516 1517 pthread_mutex_unlock(&sAdncBundleLock); 1518 1519 return status; 1520 } 1521 1522 1523 int eS305_Release() { 1524 ALOGV("eS305_Release()"); 1525 1526 pthread_mutex_lock(&sAdncBundleLock); 1527 1528 AdncBundle_Release_l(); 1529 1530 pthread_mutex_unlock(&sAdncBundleLock); 1531 1532 return 0; 1533 } 1534 1535 } // extern "C" 1536