AudioHardware.cpp revision a3a947cc7e1bfaf7b5cfc85b71f602edf562836d
1/* 2** Copyright 2008, Google Inc. 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 <math.h> 18 19// #define LOG_NDEBUG 0 20#define LOG_TAG "AudioHardwareMSM72XX" 21#include <utils/Log.h> 22#include <utils/String8.h> 23 24#include <stdio.h> 25#include <unistd.h> 26#include <sys/ioctl.h> 27#include <sys/types.h> 28#include <sys/stat.h> 29#include <dlfcn.h> 30#include <fcntl.h> 31 32// hardware specific functions 33 34#include "BluetoothHeadsetTable.h" 35#include "AudioHardware.h" 36 37#define LOG_SND_RPC 0 // Set to 1 to log sound RPC's 38 39namespace android { 40 41/* When this macro is non-zero, we initialize playback and recording 42 * only once--when we construct the AudioHardwareMSM72xx class--and 43 * deinitialize them in this class' destructor. When the macro is 44 * set to zero, we initialize playback and recording before we start 45 * the respective operation, and deinitialize them after we stop that 46 * operation. 47 */ 48#define INIT_AUDIO_ONCE (0) 49static int get_audpp_filter(void); 50static int msm72xx_enable_audpp(uint16_t enable_mask); 51 52static uint16_t adrc_flag; 53static uint16_t eq_flag; 54static uint16_t rx_iir_flag; 55static bool audpp_filter_inited = false; 56 57// ---------------------------------------------------------------------------- 58 59AudioHardware::AudioHardware() : 60 mInit(false), mStandby(false), mOutputStandby(true), 61 mMicMute(true), mBluetoothNrec(true), mBluetoothId(0), mOutput(0), 62 mInput(0), mSndEndpoints(NULL), 63 SND_DEVICE_CURRENT(-1), 64 SND_DEVICE_HANDSET(-1), 65 SND_DEVICE_SPEAKER(-1), 66 SND_DEVICE_BT(-1), 67 SND_DEVICE_BT_EC_OFF(-1), 68 SND_DEVICE_HEADSET(-1), 69 SND_DEVICE_HEADSET_AND_SPEAKER(-1) 70{ 71 if (get_audpp_filter() == 0) 72 audpp_filter_inited = true; 73 74#if INIT_AUDIO_ONCE 75 if (msm72xx_init_record()) 76 LOGE("msm72xx_init_record failed"); 77 else 78#endif 79 { 80 int fd = open("/dev/msm_snd", O_RDWR); 81 if (fd >= 0) { 82 int rc = ioctl(fd, SND_GET_ENDPOINTS, NULL); 83 rc /= sizeof(snd_endpoint); 84 if (rc >= 0) { 85 mSndEndpoints = new snd_endpoint[rc]; 86 mNumSndEndpoints = rc; 87 LOGI("++++ NUMBER OF ENDPOINTS: %d", rc); 88 if (ioctl(fd, SND_GET_ENDPOINTS, mSndEndpoints) < 0) { 89 LOGE("Could not retrieve MSM SND endpoints."); 90 } 91 else { 92 mInit = true; 93 LOGV("constructed"); 94 struct snd_endpoint *ept = mSndEndpoints; 95 for (int cnt = 0; cnt < mNumSndEndpoints; cnt++, ept++) { 96 LOGI("[%s] [%d]", ept->name, ept->id); 97#define CHECK_FOR(desc) \ 98do { \ 99 if (!strcmp(ept->name, #desc)) { \ 100 LOGI("++++ [%s] [%d] HIT", ept->name, ept->id); \ 101 SND_DEVICE_##desc = ept->id; \ 102 } \ 103} while(0) 104 CHECK_FOR(CURRENT); 105 CHECK_FOR(HANDSET); 106 CHECK_FOR(SPEAKER); 107 CHECK_FOR(BT); 108 CHECK_FOR(BT_EC_OFF); 109 CHECK_FOR(HEADSET); 110 CHECK_FOR(HEADSET_AND_SPEAKER); 111#undef CHECK_FOR 112 mBluetoothId = 0; 113 for (unsigned hs = 0; 114 hs < sizeof(KNOWN_HEADSETS) / 115 sizeof(KNOWN_HEADSETS[0]); 116 hs++) { 117 if (KNOWN_HEADSETS[hs].id < 0 && 118 !strcmp(ept->name, 119 KNOWN_HEADSETS[hs].probe)) { 120 LOGI("++BT [%s] [%d] HIT", ept->name, ept->id); 121 KNOWN_HEADSETS[hs].id = ept->id; 122 } 123 } 124 } 125 } 126 } 127 else LOGE("Could not retrieve number of MSM SND endpoints."); 128 close(fd); 129 } 130 else LOGE("Could not open MSM SND driver."); 131 } 132} 133 134AudioHardware::~AudioHardware() 135{ 136 delete mInput; 137 delete mOutput; 138 delete [] mSndEndpoints; 139 140#if INIT_AUDIO_ONCE 141 msm72xx_deinit_record(); 142#endif 143 mInit = false; 144} 145 146status_t AudioHardware::initCheck() 147{ 148 return mInit ? NO_ERROR : NO_INIT; 149} 150 151AudioStreamOut* AudioHardware::openOutputStream( 152 int format, int channelCount, uint32_t sampleRate) 153{ 154 Mutex::Autolock lock(mLock); 155 156 // only one output stream allowed 157 if (mOutput) return 0; 158 159 // create new output stream 160 AudioStreamOutMSM72xx* out = new AudioStreamOutMSM72xx(); 161 if (out->set(this, format, channelCount, sampleRate) == NO_ERROR) { 162 mOutput = out; 163 standby_nosync(); 164 } else { 165 delete out; 166 } 167 return mOutput; 168} 169 170void AudioHardware::closeOutputStream(AudioStreamOutMSM72xx* out) { 171 Mutex::Autolock lock(mLock); 172 if (mOutput != out) { 173 LOGW("Attempt to close invalid output stream"); 174 } 175 else { 176 mOutput = 0; 177 } 178} 179 180AudioStreamIn* AudioHardware::openInputStream( 181 int format, int channelCount, uint32_t sampleRate) 182{ 183 Mutex::Autolock lock(mLock); 184 185 // input stream already open? 186 if (mInput) return 0; 187 188 AudioStreamInMSM72xx* in = new AudioStreamInMSM72xx(); 189 if (in->set(this, format, channelCount, sampleRate) != NO_ERROR) { 190 delete in; 191 return 0; 192 } 193 194 mInput = in; 195 return mInput; 196} 197 198void AudioHardware::closeInputStream(AudioStreamInMSM72xx* in) { 199 Mutex::Autolock lock(mLock); 200 if (mInput != in) { 201 LOGW("Attempt to close invalid input stream"); 202 } 203 else { 204 mInput = 0; 205 } 206} 207 208// always call this with mutex held 209status_t AudioHardware::standby_nosync() 210{ 211 if (mStandby == false) { 212 LOGD("Going to standby"); 213 mStandby = true; 214 return mOutput->standby(); 215 } 216 return NO_ERROR; 217} 218 219// always call with mutex held 220status_t AudioHardware::checkStandby() 221{ 222 // don't go into standby if audio is active 223 if (!mOutputStandby) return NO_ERROR; 224 return standby_nosync(); 225} 226 227status_t AudioHardware::standby() 228{ 229 Mutex::Autolock lock(mLock); 230 mOutputStandby = true; 231 return checkStandby(); 232} 233 234status_t AudioHardware::setMicMute(bool state) 235{ 236 Mutex::Autolock lock(mLock); 237 return setMicMute_nosync(state); 238} 239 240// always call with mutex held 241status_t AudioHardware::setMicMute_nosync(bool state) 242{ 243 if (mMicMute != state) { 244 mMicMute = state; 245 return doAudioRouteOrMute(SND_DEVICE_CURRENT); 246 } 247 return NO_ERROR; 248} 249 250status_t AudioHardware::getMicMute(bool* state) 251{ 252 *state = mMicMute; 253 return NO_ERROR; 254} 255 256status_t AudioHardware::setParameter(const char *key, const char *value) 257{ 258 LOGV("%s key = %s value = %s\n", __FUNCTION__, key, value); 259 260 if (key == NULL || value == NULL) { 261 LOGE("%s called with null argument, ignoring (key = %s, value = %s", 262 __FUNCTION__, key, value); 263 return BAD_VALUE; 264 } 265 266 const char BT_NREC_KEY[] = "bt_headset_nrec"; 267 const char BT_NAME_KEY[] = "bt_headset_name"; 268 const char BT_NREC_VALUE_ON[] = "on"; 269 270 if (!strncmp(key, BT_NREC_KEY, sizeof(BT_NREC_KEY))) { 271 if (!strncmp(value, BT_NREC_VALUE_ON, sizeof(BT_NREC_VALUE_ON))) { 272 mBluetoothNrec = true; 273 } else { 274 mBluetoothNrec = false; 275 LOGI("Turning noise reduction and echo cancellation off for BT " 276 "headset"); 277 } 278 doRouting(); 279 } else if (!strncmp(key, BT_NAME_KEY, sizeof(BT_NAME_KEY))) { 280 mBluetoothId = 0; 281 for (uint32_t i = 0; i < sizeof(KNOWN_HEADSETS) / sizeof(KNOWN_HEADSETS[0]); 282 i++) { 283 if (!strncasecmp(value, KNOWN_HEADSETS[i].name, 284 sizeof(KNOWN_HEADSETS[i].name)) && 285 KNOWN_HEADSETS[i].id >= 0) { 286 mBluetoothId = KNOWN_HEADSETS[i].id; 287 LOGI("Using custom acoustic parameters for %s", value); 288 break; 289 } 290 } 291 if (mBluetoothId == 0) { 292 LOGI("Using default acoustic parameters " 293 "(%s not in acoustic database)", value); 294 doRouting(); 295 } 296 } 297 298 return NO_ERROR; 299} 300 301int check_and_set_audpp_parameters(char *buf, int size) 302{ 303 char *p, *ps; 304 static const char *const seps = ","; 305 int table_num; 306 int i, j; 307 uint16_t adrc_filter[8]; 308 eq_filter_type eq[12]; 309 rx_iir_filter iir_cfg; 310 eqalizer eqalizer; 311 int fd; 312 void *audioeq; 313 void *(*eq_cal)(int32_t, int32_t, int32_t, uint16_t, int32_t, int32_t *, int32_t *, uint16_t *); 314 uint16_t numerator[6]; 315 uint16_t denominator[4]; 316 uint16_t shift[2]; 317 318 fd = open("/dev/msm_pcm_ctl", O_RDWR); 319 if (fd < 0) { 320 LOGE("Cannot open audio device"); 321 return -EPERM; 322 } 323 if (buf[0] == 'A' && buf[1] == '1') { 324 /* IIR filter */ 325 if (!(p = strtok(buf, ","))) 326 goto token_err; 327 328 /* Table header */ 329 table_num = strtol(p + 1, &ps, 10); 330 if (!(p = strtok(NULL, seps))) 331 goto token_err; 332 /* Table description */ 333 if (!(p = strtok(NULL, seps))) 334 goto token_err; 335 336 for (i = 0; i < 48; i++) { 337 j = (i >= 40)? i : ((i % 2)? (i - 1) : (i + 1)); 338 iir_cfg.iir_params[j] = (uint16_t)strtol(p, &ps, 16); 339 if (!(p = strtok(NULL, seps))) 340 goto token_err; 341 } 342 rx_iir_flag = (uint16_t)strtol(p, &ps, 16); 343 if (!(p = strtok(NULL, seps))) 344 goto token_err; 345 iir_cfg.num_bands = (uint16_t)strtol(p, &ps, 16); 346 347 if (ioctl(fd, AUDIO_SET_RX_IIR, &iir_cfg) < 0) { 348 LOGE("set rx iir filter error."); 349 return -EIO; 350 } 351 } else if (buf[0] == 'B' && buf[1] == '1') { 352 /* This is the ADRC record we are looking for. Tokenize it */ 353 if (!(p = strtok(buf, ","))) 354 goto token_err; 355 356 /* Table header */ 357 table_num = strtol(p + 1, &ps, 10); 358 if (!(p = strtok(NULL, seps))) 359 goto token_err; 360 361 /* Table description */ 362 if (!(p = strtok(NULL, seps))) 363 goto token_err; 364 adrc_flag = (uint16_t)strtol(p, &ps, 16); 365 366 if (!(p = strtok(NULL, seps))) 367 goto token_err; 368 adrc_filter[0] = (uint16_t)strtol(p, &ps, 16); 369 370 if (!(p = strtok(NULL, seps))) 371 goto token_err; 372 adrc_filter[1] = (uint16_t)strtol(p, &ps, 16); 373 374 if (!(p = strtok(NULL, seps))) 375 goto token_err; 376 adrc_filter[2] = (uint16_t)strtol(p, &ps, 16); 377 378 if (!(p = strtok(NULL, seps))) 379 goto token_err; 380 adrc_filter[3] = (uint16_t)strtol(p, &ps, 16); 381 382 if (!(p = strtok(NULL, seps))) 383 goto token_err; 384 adrc_filter[4] = (uint16_t)strtol(p, &ps, 16); 385 386 if (!(p = strtok(NULL, seps))) 387 goto token_err; 388 adrc_filter[5] = (uint16_t)strtol(p, &ps, 16); 389 390 if (!(p = strtok(NULL, seps))) 391 goto token_err; 392 adrc_filter[6] = (uint16_t)strtol(p, &ps, 16); 393 394 if (!(p = strtok(NULL, seps))) 395 goto token_err; 396 adrc_filter[7] = (uint16_t)strtol(p, &ps, 16); 397 398 if (!(p = strtok(NULL, seps))) 399 goto token_err; 400 401 LOGI("ADRC Filter ADRC FLAG = %02x.", adrc_flag); 402 LOGI("ADRC Filter COMP THRESHOLD = %02x.", adrc_filter[0]); 403 LOGI("ADRC Filter COMP SLOPE = %02x.", adrc_filter[1]); 404 LOGI("ADRC Filter COMP RMS TIME = %02x.", adrc_filter[2]); 405 LOGI("ADRC Filter COMP ATTACK[0] = %02x.", adrc_filter[3]); 406 LOGI("ADRC Filter COMP ATTACK[1] = %02x.", adrc_filter[4]); 407 LOGI("ADRC Filter COMP RELEASE[0] = %02x.", adrc_filter[5]); 408 LOGI("ADRC Filter COMP RELEASE[1] = %02x.", adrc_filter[6]); 409 LOGI("ADRC Filter COMP DELAY = %02x.", adrc_filter[7]); 410 411 if (ioctl(fd, AUDIO_SET_ADRC, &adrc_filter) < 0) { 412 LOGE("set adrc filter error."); 413 return -EIO; 414 } 415 } else if (buf[0] == 'C' && buf[1] == '1') { 416 /* This is the EQ record we are looking for. Tokenize it */ 417 if (!(p = strtok(buf, ","))) 418 goto token_err; 419 420 /* Table header */ 421 table_num = strtol(p + 1, &ps, 10); 422 if (!(p = strtok(NULL, seps))) 423 goto token_err; 424 /* Table description */ 425 if (!(p = strtok(NULL, seps))) 426 goto token_err; 427 428 eq_flag = (uint16_t)strtol(p, &ps, 16); 429 if (!(p = strtok(NULL, seps))) 430 goto token_err; 431 LOGI("EQ flag = %02x.", eq_flag); 432 433 audioeq = ::dlopen("/system/lib/libaudioeq.so", RTLD_NOW); 434 if (audioeq == NULL) { 435 LOGE("audioeq library open failure"); 436 return -1; 437 } 438 eq_cal = (void *(*) (int32_t, int32_t, int32_t, uint16_t, int32_t, int32_t *, int32_t *, uint16_t *))::dlsym(audioeq, "audioeq_calccoefs"); 439 memset(&eqalizer, 0, sizeof(eqalizer)); 440 /* Temp add the bands here */ 441 eqalizer.bands = 8; 442 for (i = 0; i < eqalizer.bands; i++) { 443 444 eq[i].gain = (uint16_t)strtol(p, &ps, 16); 445 446 if (!(p = strtok(NULL, seps))) 447 goto token_err; 448 eq[i].freq = (uint16_t)strtol(p, &ps, 16); 449 450 if (!(p = strtok(NULL, seps))) 451 goto token_err; 452 eq[i].type = (uint16_t)strtol(p, &ps, 16); 453 454 if (!(p = strtok(NULL, seps))) 455 goto token_err; 456 eq[i].qf = (uint16_t)strtol(p, &ps, 16); 457 458 if (!(p = strtok(NULL, seps))) 459 goto token_err; 460 //LOGI("gain[%d] = %d", i, eq[i].gain); 461 //LOGI("freq[%d] = %d", i, eq[i].freq); 462 //LOGI("type[%d] = %d", i, eq[i].type); 463 //LOGI(" qf[%d] = %d", i, eq[i].qf); 464 eq_cal(eq[i].gain, eq[i].freq, 48000, eq[i].type, eq[i].qf, (int32_t*)numerator, (int32_t *)denominator, shift); 465 for (j = 0; j < 6; j++) { 466 eqalizer.params[ ( i * 6) + j] = numerator[j]; 467 } 468 for (j = 0; j < 4; j++) { 469 eqalizer.params[(eqalizer.bands * 6) + (i * 4) + j] = denominator[j]; 470 } 471 eqalizer.params[(eqalizer.bands * 10) + i] = shift[0]; 472 } 473 ::dlclose(audioeq); 474 475 if (ioctl(fd, AUDIO_SET_EQ, &eqalizer) < 0) { 476 LOGE("set Equalizer error."); 477 return -EIO; 478 } 479 } 480 close(fd); 481 return 0; 482 483token_err: 484 LOGE("malformatted pcm control buffer"); 485 return -EINVAL; 486} 487 488static int get_audpp_filter(void) 489{ 490 struct stat st; 491 char *read_buf; 492 char *next_str, *current_str; 493 int csvfd; 494 495 LOGI("get_audpp_filter"); 496 static const char *const path = 497 "/system/etc/AudioFilter.csv"; 498 csvfd = open(path, O_RDONLY); 499 if (csvfd < 0) { 500 /* failed to open normal acoustic file ... */ 501 LOGE("failed to open AUDIO_NORMAL_FILTER %s: %s (%d).", 502 path, strerror(errno), errno); 503 return -1; 504 } else LOGI("open %s success.", path); 505 506 if (fstat(csvfd, &st) < 0) { 507 LOGE("failed to stat %s: %s (%d).", 508 path, strerror(errno), errno); 509 close(csvfd); 510 return -1; 511 } 512 513 read_buf = (char *) mmap(0, st.st_size, 514 PROT_READ | PROT_WRITE, 515 MAP_PRIVATE, 516 csvfd, 0); 517 518 if (read_buf == MAP_FAILED) { 519 LOGE("failed to mmap parameters file: %s (%d)", 520 strerror(errno), errno); 521 close(csvfd); 522 return -1; 523 } 524 525 current_str = read_buf; 526 527 while (1) { 528 int len; 529 next_str = strchr(current_str, '\n'); 530 if (!next_str) 531 break; 532 len = next_str - current_str; 533 *next_str++ = '\0'; 534 if (check_and_set_audpp_parameters(current_str, len)) { 535 LOGI("failed to set audpp parameters, exiting."); 536 munmap(read_buf, st.st_size); 537 close(csvfd); 538 return -1; 539 } 540 current_str = next_str; 541 } 542 543 munmap(read_buf, st.st_size); 544 close(csvfd); 545 return 0; 546} 547 548static int msm72xx_enable_audpp(uint16_t enable_mask) 549{ 550 int fd; 551 552 if (!audpp_filter_inited) return -EINVAL; 553 554 fd = open("/dev/msm_pcm_ctl", O_RDWR); 555 if (fd < 0) { 556 LOGE("Cannot open audio device"); 557 return -EPERM; 558 } 559 560 if (adrc_flag == 0 && (enable_mask & ADRC_ENABLE)) 561 enable_mask &= ~ADRC_ENABLE; 562 if (eq_flag == 0 && (enable_mask & EQ_ENABLE)) 563 enable_mask &= ~EQ_ENABLE; 564 if (rx_iir_flag == 0 && (enable_mask & IIR_ENABLE)) 565 enable_mask &= ~IIR_ENABLE; 566 567 LOGD("msm72xx_enable_audpp: 0x%04x", enable_mask); 568 if (ioctl(fd, AUDIO_ENABLE_AUDPP, &enable_mask) < 0) { 569 LOGE("enable audpp error"); 570 close(fd); 571 return -EPERM; 572 } 573 574 close(fd); 575 return 0; 576} 577 578static status_t set_volume_rpc(uint32_t device, 579 uint32_t method, 580 uint32_t volume) 581{ 582 int fd; 583#if LOG_SND_RPC 584 LOGD("rpc_snd_set_volume(%d, %d, %d)\n", device, method, volume); 585#endif 586 587 if (device == -1UL) return NO_ERROR; 588 589 fd = open("/dev/msm_snd", O_RDWR); 590 if (fd < 0) { 591 LOGE("Can not open snd device"); 592 return -EPERM; 593 } 594 /* rpc_snd_set_volume( 595 * device, # Any hardware device enum, including 596 * # SND_DEVICE_CURRENT 597 * method, # must be SND_METHOD_VOICE to do anything useful 598 * volume, # integer volume level, in range [0,5]. 599 * # note that 0 is audible (not quite muted) 600 * ) 601 * rpc_snd_set_volume only works for in-call sound volume. 602 */ 603 struct snd_volume_config args; 604 args.device = device; 605 args.method = method; 606 args.volume = volume; 607 608 if (ioctl(fd, SND_SET_VOLUME, &args) < 0) { 609 LOGE("snd_set_volume error."); 610 close(fd); 611 return -EIO; 612 } 613 614 close(fd); 615 return NO_ERROR; 616} 617 618status_t AudioHardware::setVoiceVolume(float v) 619{ 620 if (v < 0.0) { 621 LOGW("setVoiceVolume(%f) under 0.0, assuming 0.0\n", v); 622 v = 0.0; 623 } else if (v > 1.0) { 624 LOGW("setVoiceVolume(%f) over 1.0, assuming 1.0\n", v); 625 v = 1.0; 626 } 627 628 int vol = lrint(v * 5.0); 629 LOGD("setVoiceVolume(%f)\n", v); 630 LOGI("Setting in-call volume to %d (available range is 0 to 5)\n", vol); 631 632 set_volume_rpc(SND_DEVICE_CURRENT, SND_METHOD_VOICE, vol); 633 return NO_ERROR; 634} 635 636status_t AudioHardware::setMasterVolume(float v) 637{ 638 Mutex::Autolock lock(mLock); 639 int vol = ceil(v * 5.0); 640 LOGI("Set master volume to %d.\n", vol); 641 642 set_volume_rpc(SND_DEVICE_HANDSET, SND_METHOD_VOICE, vol); 643 set_volume_rpc(SND_DEVICE_SPEAKER, SND_METHOD_VOICE, vol); 644 set_volume_rpc(SND_DEVICE_BT, SND_METHOD_VOICE, vol); 645 set_volume_rpc(SND_DEVICE_HEADSET, SND_METHOD_VOICE, vol); 646 // We return an error code here to let the audioflinger do in-software 647 // volume on top of the maximum volume that we set through the SND API. 648 // return error - software mixer will handle it 649 return -1; 650} 651 652static status_t do_route_audio_rpc(uint32_t device, 653 bool ear_mute, bool mic_mute) 654{ 655 if (device == -1UL) 656 return NO_ERROR; 657 658 int fd; 659#if LOG_SND_RPC 660 LOGD("rpc_snd_set_device(%d, %d, %d)\n", device, ear_mute, mic_mute); 661#endif 662 663 fd = open("/dev/msm_snd", O_RDWR); 664 if (fd < 0) { 665 LOGE("Can not open snd device"); 666 return -EPERM; 667 } 668 // RPC call to switch audio path 669 /* rpc_snd_set_device( 670 * device, # Hardware device enum to use 671 * ear_mute, # Set mute for outgoing voice audio 672 * # this should only be unmuted when in-call 673 * mic_mute, # Set mute for incoming voice audio 674 * # this should only be unmuted when in-call or 675 * # recording. 676 * ) 677 */ 678 struct snd_device_config args; 679 args.device = device; 680 args.ear_mute = ear_mute ? SND_MUTE_MUTED : SND_MUTE_UNMUTED; 681 args.mic_mute = mic_mute ? SND_MUTE_MUTED : SND_MUTE_UNMUTED; 682 683 if (ioctl(fd, SND_SET_DEVICE, &args) < 0) { 684 LOGE("snd_set_device error."); 685 close(fd); 686 return -EIO; 687 } 688 689 close(fd); 690 return NO_ERROR; 691} 692 693// always call with mutex held 694status_t AudioHardware::doAudioRouteOrMute(uint32_t device) 695{ 696 if (device == (uint32_t)SND_DEVICE_BT) { 697 if (mBluetoothId) { 698 device = mBluetoothId; 699 } else if (!mBluetoothNrec) { 700 device = SND_DEVICE_BT_EC_OFF; 701 } 702 } 703 return do_route_audio_rpc(device, 704 mMode != AudioSystem::MODE_IN_CALL, mMicMute); 705} 706 707static int count_bits(uint32_t vector) 708{ 709 int bits; 710 for (bits = 0; vector; bits++) { 711 vector &= vector - 1; 712 } 713 return bits; 714} 715 716status_t AudioHardware::doRouting() 717{ 718 Mutex::Autolock lock(mLock); 719 uint32_t routes = mRoutes[mMode]; 720 if (count_bits(routes) > 1) { 721 if (routes != 722 (AudioSystem::ROUTE_HEADSET | AudioSystem::ROUTE_SPEAKER)) { 723 LOGW("Hardware does not support requested route combination (%#X)," 724 " picking closest possible route...", routes); 725 } 726 } 727 728 status_t ret = NO_ERROR; 729 if (routes & AudioSystem::ROUTE_BLUETOOTH) { 730 LOGI("Routing audio to Bluetooth PCM\n"); 731 ret = doAudioRouteOrMute(SND_DEVICE_BT); 732 msm72xx_enable_audpp(ADRC_DISABLE | EQ_DISABLE | IIR_DISABLE); 733 } else if ((routes & AudioSystem::ROUTE_HEADSET) && 734 (routes & AudioSystem::ROUTE_SPEAKER)) { 735 LOGI("Routing audio to Wired Headset and Speaker\n"); 736 ret = doAudioRouteOrMute(SND_DEVICE_HEADSET_AND_SPEAKER); 737 msm72xx_enable_audpp(ADRC_ENABLE | EQ_ENABLE | IIR_ENABLE); 738 } else if (routes & AudioSystem::ROUTE_HEADSET) { 739 LOGI("Routing audio to Wired Headset\n"); 740 ret = doAudioRouteOrMute(SND_DEVICE_HEADSET); 741 msm72xx_enable_audpp(ADRC_DISABLE | EQ_DISABLE | IIR_DISABLE); 742 } else if (routes & AudioSystem::ROUTE_SPEAKER) { 743 LOGI("Routing audio to Speakerphone\n"); 744 ret = doAudioRouteOrMute(SND_DEVICE_SPEAKER); 745 msm72xx_enable_audpp(ADRC_ENABLE | EQ_ENABLE | IIR_ENABLE); 746 } else { 747 LOGI("Routing audio to Handset\n"); 748 ret = doAudioRouteOrMute(SND_DEVICE_HANDSET); 749 msm72xx_enable_audpp(ADRC_DISABLE | EQ_DISABLE | IIR_DISABLE); 750 } 751 752 // check for standby 753 checkStandby(); 754 755 return ret; 756} 757 758status_t AudioHardware::checkMicMute() 759{ 760 Mutex::Autolock lock(mLock); 761 if (mMode != AudioSystem::MODE_IN_CALL) { 762 setMicMute_nosync(true); 763 } 764 765 return NO_ERROR; 766} 767 768status_t AudioHardware::dumpInternals(int fd, const Vector<String16>& args) 769{ 770 const size_t SIZE = 256; 771 char buffer[SIZE]; 772 String8 result; 773 result.append("AudioHardware::dumpInternals\n"); 774 snprintf(buffer, SIZE, "\tmInit: %s\n", mInit? "true": "false"); 775 result.append(buffer); 776 snprintf(buffer, SIZE, "\tmStandby: %s\n", mStandby? "true": "false"); 777 result.append(buffer); 778 snprintf(buffer, SIZE, "\tmOutputStandby: %s\n", mOutputStandby? "true": "false"); 779 result.append(buffer); 780 snprintf(buffer, SIZE, "\tmMicMute: %s\n", mMicMute? "true": "false"); 781 result.append(buffer); 782 snprintf(buffer, SIZE, "\tmBluetoothNrec: %s\n", mBluetoothNrec? "true": "false"); 783 result.append(buffer); 784 snprintf(buffer, SIZE, "\tmBluetoothId: %d\n", mBluetoothId); 785 result.append(buffer); 786 ::write(fd, result.string(), result.size()); 787 return NO_ERROR; 788} 789 790status_t AudioHardware::dump(int fd, const Vector<String16>& args) 791{ 792 dumpInternals(fd, args); 793 if (mInput) { 794 mInput->dump(fd, args); 795 } 796 if (mOutput) { 797 mOutput->dump(fd, args); 798 } 799 return NO_ERROR; 800} 801 802// ---------------------------------------------------------------------------- 803 804AudioHardware::AudioStreamOutMSM72xx::AudioStreamOutMSM72xx() : 805 mHardware(0), mFd(-1), mStartCount(0), mRetryCount(0) 806{ 807} 808 809status_t AudioHardware::AudioStreamOutMSM72xx::set( 810 AudioHardware* hw, int format, int channels, uint32_t rate) 811{ 812 // fix up defaults 813 if (format == 0) format = AudioSystem::PCM_16_BIT; 814 if (channels == 0) channels = channelCount(); 815 if (rate == 0) rate = sampleRate(); 816 817 // check values 818 if ((format != AudioSystem::PCM_16_BIT) || 819 (channels != channelCount()) || 820 (rate != sampleRate())) 821 return BAD_VALUE; 822 823 mHardware = hw; 824 825 return NO_ERROR; 826} 827 828AudioHardware::AudioStreamOutMSM72xx::~AudioStreamOutMSM72xx() 829{ 830 if (!mHardware->mStandby) { 831 if (mFd > 0) close(mFd); 832 } 833 mHardware->closeOutputStream(this); 834} 835 836ssize_t AudioHardware::AudioStreamOutMSM72xx::write(const void* buffer, size_t bytes) 837{ 838 // LOGD("AudioStreamOutMSM72xx::write(%p, %u)", buffer, bytes); 839 status_t status = NO_INIT; 840 size_t count = bytes; 841 const uint8_t* p = static_cast<const uint8_t*>(buffer); 842 843 mHardware->mOutputStandby = false; 844 if (mHardware->mStandby) { 845 846 // open driver 847 LOGV("open driver"); 848 status = ::open("/dev/msm_pcm_out", O_RDWR); 849 if (status < 0) { 850 LOGE("Cannot open audio device"); 851 goto Error; 852 } 853 mFd = status; 854 855 // configuration 856 LOGV("get config"); 857 struct msm_audio_config config; 858 status = ioctl(mFd, AUDIO_GET_CONFIG, &config); 859 if (status < 0) { 860 LOGE("Cannot read config"); 861 goto Error; 862 } 863 864 LOGV("set config"); 865 config.channel_count = channelCount(); 866 config.sample_rate = sampleRate(); 867 config.buffer_size = bufferSize(); 868 config.buffer_count = 2; 869 config.codec_type = CODEC_TYPE_PCM; 870 status = ioctl(mFd, AUDIO_SET_CONFIG, &config); 871 if (status < 0) { 872 LOGE("Cannot set config"); 873 goto Error; 874 } 875 876 LOGV("buffer_size: %u", config.buffer_size); 877 LOGV("buffer_count: %u", config.buffer_count); 878 LOGV("channel_count: %u", config.channel_count); 879 LOGV("sample_rate: %u", config.sample_rate); 880 881 // fill 2 buffers before AUDIO_START 882 mStartCount = 2; 883 mHardware->mStandby = false; 884 } 885 886 while (count) { 887 ssize_t written = ::write(mFd, p, count); 888 if (written >= 0) { 889 count -= written; 890 p += written; 891 } else { 892 if (errno != EAGAIN) return written; 893 mRetryCount++; 894 LOGW("EAGAIN - retry"); 895 } 896 } 897 898 // start audio after we fill 2 buffers 899 if (mStartCount) { 900 if (--mStartCount == 0) { 901 ioctl(mFd, AUDIO_START, 0); 902 } 903 } 904 return bytes; 905 906Error: 907 if (mFd > 0) { 908 ::close(mFd); 909 mFd = -1; 910 } 911 // Simulate audio output timing in case of error 912 usleep(bytes * 1000000 / sizeof(int16_t) / channelCount() / sampleRate()); 913 914 return status; 915} 916 917status_t AudioHardware::AudioStreamOutMSM72xx::standby() 918{ 919 status_t status = NO_ERROR; 920 if (mFd > 0) { 921 ::close(mFd); 922 mFd = -1; 923 } 924 mHardware->mStandby = true; 925 return status; 926} 927 928status_t AudioHardware::AudioStreamOutMSM72xx::dump(int fd, const Vector<String16>& args) 929{ 930 const size_t SIZE = 256; 931 char buffer[SIZE]; 932 String8 result; 933 result.append("AudioStreamOutMSM72xx::dump\n"); 934 snprintf(buffer, SIZE, "\tsample rate: %d\n", sampleRate()); 935 result.append(buffer); 936 snprintf(buffer, SIZE, "\tbuffer size: %d\n", bufferSize()); 937 result.append(buffer); 938 snprintf(buffer, SIZE, "\tchannel count: %d\n", channelCount()); 939 result.append(buffer); 940 snprintf(buffer, SIZE, "\tformat: %d\n", format()); 941 result.append(buffer); 942 snprintf(buffer, SIZE, "\tmHardware: %p\n", mHardware); 943 result.append(buffer); 944 snprintf(buffer, SIZE, "\tmFd: %d\n", mFd); 945 result.append(buffer); 946 snprintf(buffer, SIZE, "\tmStartCount: %d\n", mStartCount); 947 result.append(buffer); 948 snprintf(buffer, SIZE, "\tmRetryCount: %d\n", mRetryCount); 949 result.append(buffer); 950 ::write(fd, result.string(), result.size()); 951 return NO_ERROR; 952} 953 954// ---------------------------------------------------------------------------- 955 956AudioHardware::AudioStreamInMSM72xx::AudioStreamInMSM72xx() : 957 mHardware(0), mFd(-1), mRecordEnabled(false), mRetryCount(0) 958{ 959} 960 961status_t AudioHardware::AudioStreamInMSM72xx::set( 962 AudioHardware* hw, int format, int channelCount, uint32_t sampleRate) 963{ 964 LOGV("AudioStreamInMSM72xx::set(%d, %d, %u)", format, channelCount, sampleRate); 965 if (mFd >= 0) { 966 LOGE("Audio record already open"); 967 return -EPERM; 968 } 969 970 // open audio input device 971 status_t status = ::open("/dev/msm_pcm_in", O_RDWR); 972 if (status < 0) { 973 LOGE("Cannot open audio device"); 974 goto Error; 975 } 976 mFd = status; 977 978 // configuration 979 LOGV("get config"); 980 struct msm_audio_config config; 981 status = ioctl(mFd, AUDIO_GET_CONFIG, &config); 982 if (status < 0) { 983 LOGE("Cannot read config"); 984 goto Error; 985 } 986 987 LOGV("set config"); 988 config.channel_count = channelCount; 989 config.sample_rate = sampleRate; 990 config.buffer_size = bufferSize(); 991 config.buffer_count = 2; 992 config.codec_type = CODEC_TYPE_PCM; 993 status = ioctl(mFd, AUDIO_SET_CONFIG, &config); 994 if (status < 0) { 995 LOGE("Cannot set config"); 996 goto Error; 997 } 998 999 LOGV("confirm config"); 1000 status = ioctl(mFd, AUDIO_GET_CONFIG, &config); 1001 if (status < 0) { 1002 LOGE("Cannot read config"); 1003 goto Error; 1004 } 1005 LOGV("buffer_size: %u", config.buffer_size); 1006 LOGV("buffer_count: %u", config.buffer_count); 1007 LOGV("channel_count: %u", config.channel_count); 1008 LOGV("sample_rate: %u", config.sample_rate); 1009 1010 mHardware = hw; 1011 mHardware->setMicMute_nosync(false); 1012 mRecordEnabled = false; 1013 return NO_ERROR; 1014 1015Error: 1016 if (mFd > 0) { 1017 ::close(mFd); 1018 mFd = -1; 1019 } 1020 return status; 1021} 1022 1023AudioHardware::AudioStreamInMSM72xx::~AudioStreamInMSM72xx() 1024{ 1025 LOGV("AudioHardware::closeRecord"); 1026 if (mFd < 0) return; 1027 mHardware->checkMicMute(); 1028 ::close(mFd); 1029 mRecordEnabled = false; 1030 mHardware->closeInputStream(this); 1031} 1032 1033ssize_t AudioHardware::AudioStreamInMSM72xx::read( void* buffer, ssize_t bytes) 1034{ 1035 LOGV("AudioStreamInMSM72xx::read(%p, %u)", buffer, bytes); 1036 if (mFd < 0) return NO_INIT; 1037 1038 size_t count = bytes; 1039 uint8_t* p = static_cast<uint8_t*>(buffer); 1040 1041 if (!mRecordEnabled) { 1042 if (ioctl(mFd, AUDIO_START, 0)) { 1043 LOGE("Error starting record"); 1044 return -1; 1045 } 1046 mRecordEnabled = 1; 1047 } 1048 1049 while (count) { 1050 ssize_t bytesRead = ::read(mFd, buffer, count); 1051 if (bytesRead >= 0) { 1052 count -= bytesRead; 1053 p += bytesRead; 1054 } else { 1055 if (errno != EAGAIN) return bytesRead; 1056 mRetryCount++; 1057 LOGW("EAGAIN - retrying"); 1058 } 1059 } 1060 return bytes; 1061} 1062 1063status_t AudioHardware::AudioStreamInMSM72xx::dump(int fd, const Vector<String16>& args) 1064{ 1065 const size_t SIZE = 256; 1066 char buffer[SIZE]; 1067 String8 result; 1068 result.append("AudioStreamInMSM72xx::dump\n"); 1069 snprintf(buffer, SIZE, "\tsample rate: %d\n", sampleRate()); 1070 result.append(buffer); 1071 snprintf(buffer, SIZE, "\tbuffer size: %d\n", bufferSize()); 1072 result.append(buffer); 1073 snprintf(buffer, SIZE, "\tchannel count: %d\n", channelCount()); 1074 result.append(buffer); 1075 snprintf(buffer, SIZE, "\tformat: %d\n", format()); 1076 result.append(buffer); 1077 snprintf(buffer, SIZE, "\tmHardware: %p\n", mHardware); 1078 result.append(buffer); 1079 snprintf(buffer, SIZE, "\tmFd count: %d\n", mFd); 1080 result.append(buffer); 1081 snprintf(buffer, SIZE, "\tmRecordEnabled: %s\n", mRecordEnabled? "true": "false"); 1082 result.append(buffer); 1083 snprintf(buffer, SIZE, "\tmRetryCount: %d\n", mRetryCount); 1084 result.append(buffer); 1085 ::write(fd, result.string(), result.size()); 1086 return NO_ERROR; 1087} 1088 1089// ---------------------------------------------------------------------------- 1090 1091extern "C" AudioHardwareInterface* createAudioHardware(void) { 1092 return new AudioHardware(); 1093} 1094 1095}; // namespace android 1096