AudioHardware.cpp revision 16327daa90dffd97f03d24c59ec0a4d38aa94b90
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 "AudioHardware.h" 35#include <media/AudioRecord.h> 36 37#define LOG_SND_RPC 0 // Set to 1 to log sound RPC's 38 39namespace android { 40static int audpre_index, tx_iir_index; 41static void * acoustic; 42const uint32_t AudioHardware::inputSamplingRates[] = { 43 8000, 11025, 12000, 16000, 22050, 24000, 32000, 44100, 48000 44}; 45// ---------------------------------------------------------------------------- 46 47AudioHardware::AudioHardware() : 48 mInit(false), mMicMute(true), mBluetoothNrec(true), mBluetoothId(0), 49 mOutput(0), mSndEndpoints(NULL), mCurSndDevice(-1), 50 SND_DEVICE_CURRENT(-1), 51 SND_DEVICE_HANDSET(-1), 52 SND_DEVICE_SPEAKER(-1), 53 SND_DEVICE_HEADSET(-1), 54 SND_DEVICE_BT(-1), 55 SND_DEVICE_CARKIT(-1), 56 SND_DEVICE_TTY_FULL(-1), 57 SND_DEVICE_TTY_VCO(-1), 58 SND_DEVICE_TTY_HCO(-1), 59 SND_DEVICE_NO_MIC_HEADSET(-1), 60 SND_DEVICE_FM_HEADSET(-1), 61 SND_DEVICE_HEADSET_AND_SPEAKER(-1), 62 SND_DEVICE_FM_SPEAKER(-1), 63 SND_DEVICE_BT_EC_OFF(-1) 64{ 65 66 int (*snd_get_num)(); 67 int (*snd_get_endpoint)(int, msm_snd_endpoint *); 68 int (*set_acoustic_parameters)(); 69 70 struct msm_snd_endpoint *ept; 71 72 acoustic = ::dlopen("/system/lib/libhtc_acoustic.so", RTLD_NOW); 73 if (acoustic == NULL ) { 74 LOGE("Could not open libhtc_acoustic.so"); 75 /* this is not really an error on non-htc devices... */ 76 mNumSndEndpoints = 0; 77 mInit = true; 78 return; 79 } 80 81 set_acoustic_parameters = (int (*)(void))::dlsym(acoustic, "set_acoustic_parameters"); 82 if ((*set_acoustic_parameters) == 0 ) { 83 LOGE("Could not open set_acoustic_parameters()"); 84 return; 85 } 86 87 int rc = set_acoustic_parameters(); 88 if (rc < 0) { 89 LOGE("Could not set acoustic parameters to share memory: %d", rc); 90// return; 91 } 92 93 snd_get_num = (int (*)(void))::dlsym(acoustic, "snd_get_num_endpoints"); 94 if ((*snd_get_num) == 0 ) { 95 LOGE("Could not open snd_get_num()"); 96// return; 97 } 98 99 mNumSndEndpoints = snd_get_num(); 100 LOGD("mNumSndEndpoints = %d", mNumSndEndpoints); 101 mSndEndpoints = new msm_snd_endpoint[mNumSndEndpoints]; 102 mInit = true; 103 LOGV("constructed %d SND endpoints)", mNumSndEndpoints); 104 ept = mSndEndpoints; 105 snd_get_endpoint = (int (*)(int, msm_snd_endpoint *))::dlsym(acoustic, "snd_get_endpoint"); 106 if ((*snd_get_endpoint) == 0 ) { 107 LOGE("Could not open snd_get_endpoint()"); 108 return; 109 } 110 111 for (int cnt = 0; cnt < mNumSndEndpoints; cnt++, ept++) { 112 ept->id = cnt; 113 snd_get_endpoint(cnt, ept); 114#define CHECK_FOR(desc) \ 115 if (!strcmp(ept->name, #desc)) { \ 116 SND_DEVICE_##desc = ept->id; \ 117 LOGD("BT MATCH " #desc); \ 118 } else 119 CHECK_FOR(CURRENT) 120 CHECK_FOR(HANDSET) 121 CHECK_FOR(SPEAKER) 122 CHECK_FOR(BT) 123 CHECK_FOR(BT_EC_OFF) 124 CHECK_FOR(HEADSET) 125 CHECK_FOR(CARKIT) 126 CHECK_FOR(TTY_FULL) 127 CHECK_FOR(TTY_VCO) 128 CHECK_FOR(TTY_HCO) 129 CHECK_FOR(NO_MIC_HEADSET) 130 CHECK_FOR(FM_HEADSET) 131 CHECK_FOR(FM_SPEAKER) 132 CHECK_FOR(HEADSET_AND_SPEAKER) {} 133#undef CHECK_FOR 134 } 135} 136 137AudioHardware::~AudioHardware() 138{ 139 for (size_t index = 0; index < mInputs.size(); index++) { 140 closeInputStream((AudioStreamIn*)mInputs[index]); 141 } 142 mInputs.clear(); 143 closeOutputStream((AudioStreamOut*)mOutput); 144 delete [] mSndEndpoints; 145 if (acoustic) { 146 ::dlclose(acoustic); 147 acoustic = 0; 148 } 149 mInit = false; 150} 151 152status_t AudioHardware::initCheck() 153{ 154 return mInit ? NO_ERROR : NO_INIT; 155} 156 157AudioStreamOut* AudioHardware::openOutputStream( 158 uint32_t devices, int *format, uint32_t *channels, uint32_t *sampleRate, status_t *status) 159{ 160 { // scope for the lock 161 Mutex::Autolock lock(mLock); 162 163 // only one output stream allowed 164 if (mOutput) { 165 if (status) { 166 *status = INVALID_OPERATION; 167 } 168 return 0; 169 } 170 171 // create new output stream 172 AudioStreamOutMSM72xx* out = new AudioStreamOutMSM72xx(); 173 status_t lStatus = out->set(this, devices, format, channels, sampleRate); 174 if (status) { 175 *status = lStatus; 176 } 177 if (lStatus == NO_ERROR) { 178 mOutput = out; 179 } else { 180 delete out; 181 } 182 } 183 return mOutput; 184} 185 186void AudioHardware::closeOutputStream(AudioStreamOut* out) { 187 Mutex::Autolock lock(mLock); 188 if (mOutput == 0 || mOutput != out) { 189 LOGW("Attempt to close invalid output stream"); 190 } 191 else { 192 delete mOutput; 193 mOutput = 0; 194 } 195} 196 197AudioStreamIn* AudioHardware::openInputStream( 198 uint32_t devices, int *format, uint32_t *channels, uint32_t *sampleRate, status_t *status, 199 AudioSystem::audio_in_acoustics acoustic_flags) 200{ 201 // check for valid input source 202 if (!AudioSystem::isInputDevice((AudioSystem::audio_devices)devices)) { 203 return 0; 204 } 205 206 mLock.lock(); 207 208 AudioStreamInMSM72xx* in = new AudioStreamInMSM72xx(); 209 status_t lStatus = in->set(this, devices, format, channels, sampleRate, acoustic_flags); 210 if (status) { 211 *status = lStatus; 212 } 213 if (lStatus != NO_ERROR) { 214 mLock.unlock(); 215 delete in; 216 return 0; 217 } 218 219 mInputs.add(in); 220 mLock.unlock(); 221 222 return in; 223} 224 225void AudioHardware::closeInputStream(AudioStreamIn* in) { 226 Mutex::Autolock lock(mLock); 227 228 ssize_t index = mInputs.indexOf((AudioStreamInMSM72xx *)in); 229 if (index < 0) { 230 LOGW("Attempt to close invalid input stream"); 231 } else { 232 mLock.unlock(); 233 delete mInputs[index]; 234 mLock.lock(); 235 mInputs.removeAt(index); 236 } 237} 238 239bool AudioHardware::checkOutputStandby() 240{ 241 if (mOutput) 242 if (!mOutput->checkStandby()) 243 return false; 244 245 return true; 246} 247 248status_t AudioHardware::setMicMute(bool state) 249{ 250 Mutex::Autolock lock(mLock); 251 return setMicMute_nosync(state); 252} 253 254// always call with mutex held 255status_t AudioHardware::setMicMute_nosync(bool state) 256{ 257 if (mMicMute != state) { 258 mMicMute = state; 259 return doAudioRouteOrMute(SND_DEVICE_CURRENT); 260 } 261 return NO_ERROR; 262} 263 264status_t AudioHardware::getMicMute(bool* state) 265{ 266 *state = mMicMute; 267 return NO_ERROR; 268} 269 270status_t AudioHardware::setParameters(const String8& keyValuePairs) 271{ 272 AudioParameter param = AudioParameter(keyValuePairs); 273 String8 value; 274 String8 key; 275 const char BT_NREC_KEY[] = "bt_headset_nrec"; 276 const char BT_NAME_KEY[] = "bt_headset_name"; 277 const char BT_NREC_VALUE_ON[] = "on"; 278 279 280 LOGV("setParameters() %s", keyValuePairs.string()); 281 282 if (keyValuePairs.length() == 0) return BAD_VALUE; 283 284 key = String8(BT_NREC_KEY); 285 if (param.get(key, value) == NO_ERROR) { 286 if (value == BT_NREC_VALUE_ON) { 287 mBluetoothNrec = true; 288 } else { 289 mBluetoothNrec = false; 290 LOGI("Turning noise reduction and echo cancellation off for BT " 291 "headset"); 292 } 293 } 294 key = String8(BT_NAME_KEY); 295 if (param.get(key, value) == NO_ERROR) { 296 mBluetoothId = 0; 297 for (int i = 0; i < mNumSndEndpoints; i++) { 298 if (!strcasecmp(value.string(), mSndEndpoints[i].name)) { 299 mBluetoothId = mSndEndpoints[i].id; 300 LOGI("Using custom acoustic parameters for %s", value.string()); 301 break; 302 } 303 } 304 if (mBluetoothId == 0) { 305 LOGI("Using default acoustic parameters " 306 "(%s not in acoustic database)", value.string()); 307 doRouting(NULL); 308 } 309 } 310 return NO_ERROR; 311} 312 313String8 AudioHardware::getParameters(const String8& keys) 314{ 315 AudioParameter param = AudioParameter(keys); 316 return param.toString(); 317} 318 319 320static unsigned calculate_audpre_table_index(unsigned index) 321{ 322 switch (index) { 323 case 48000: return SAMP_RATE_INDX_48000; 324 case 44100: return SAMP_RATE_INDX_44100; 325 case 32000: return SAMP_RATE_INDX_32000; 326 case 24000: return SAMP_RATE_INDX_24000; 327 case 22050: return SAMP_RATE_INDX_22050; 328 case 16000: return SAMP_RATE_INDX_16000; 329 case 12000: return SAMP_RATE_INDX_12000; 330 case 11025: return SAMP_RATE_INDX_11025; 331 case 8000: return SAMP_RATE_INDX_8000; 332 default: return -1; 333 } 334} 335size_t AudioHardware::getInputBufferSize(uint32_t sampleRate, int format, int channelCount) 336{ 337 if (format != AudioSystem::PCM_16_BIT) { 338 LOGW("getInputBufferSize bad format: %d", format); 339 return 0; 340 } 341 if (channelCount < 1 || channelCount > 2) { 342 LOGW("getInputBufferSize bad channel count: %d", channelCount); 343 return 0; 344 } 345 346 return 2048*channelCount; 347} 348 349static status_t set_volume_rpc(uint32_t device, 350 uint32_t method, 351 uint32_t volume) 352{ 353 int fd; 354#if LOG_SND_RPC 355 LOGD("rpc_snd_set_volume(%d, %d, %d)\n", device, method, volume); 356#endif 357 358 if (device == -1UL) return NO_ERROR; 359 360 fd = open("/dev/msm_snd", O_RDWR); 361 if (fd < 0) { 362 LOGE("Can not open snd device"); 363 return -EPERM; 364 } 365 /* rpc_snd_set_volume( 366 * device, # Any hardware device enum, including 367 * # SND_DEVICE_CURRENT 368 * method, # must be SND_METHOD_VOICE to do anything useful 369 * volume, # integer volume level, in range [0,5]. 370 * # note that 0 is audible (not quite muted) 371 * ) 372 * rpc_snd_set_volume only works for in-call sound volume. 373 */ 374 struct msm_snd_volume_config args; 375 args.device = device; 376 args.method = method; 377 args.volume = volume; 378 379 if (ioctl(fd, SND_SET_VOLUME, &args) < 0) { 380 LOGE("snd_set_volume error."); 381 close(fd); 382 return -EIO; 383 } 384 close(fd); 385 return NO_ERROR; 386} 387 388status_t AudioHardware::setVoiceVolume(float v) 389{ 390 if (v < 0.0) { 391 LOGW("setVoiceVolume(%f) under 0.0, assuming 0.0\n", v); 392 v = 0.0; 393 } else if (v > 1.0) { 394 LOGW("setVoiceVolume(%f) over 1.0, assuming 1.0\n", v); 395 v = 1.0; 396 } 397 398 int vol = lrint(v * 5.0); 399 LOGD("setVoiceVolume(%f)\n", v); 400 LOGI("Setting in-call volume to %d (available range is 0 to 5)\n", vol); 401 402 Mutex::Autolock lock(mLock); 403 set_volume_rpc(SND_DEVICE_CURRENT, SND_METHOD_VOICE, vol); 404 return NO_ERROR; 405} 406 407status_t AudioHardware::setMasterVolume(float v) 408{ 409 Mutex::Autolock lock(mLock); 410 int vol = ceil(v * 5.0); 411 LOGI("Set master volume to %d.\n", vol); 412 /* 413 set_volume_rpc(SND_DEVICE_HANDSET, SND_METHOD_VOICE, vol); 414 set_volume_rpc(SND_DEVICE_SPEAKER, SND_METHOD_VOICE, vol); 415 set_volume_rpc(SND_DEVICE_BT, SND_METHOD_VOICE, vol); 416 set_volume_rpc(SND_DEVICE_HEADSET, SND_METHOD_VOICE, vol); 417 */ 418 // We return an error code here to let the audioflinger do in-software 419 // volume on top of the maximum volume that we set through the SND API. 420 // return error - software mixer will handle it 421 return -1; 422} 423 424static status_t do_route_audio_rpc(uint32_t device, 425 bool ear_mute, bool mic_mute) 426{ 427 if (device == -1UL) 428 return NO_ERROR; 429 430 int fd; 431#if LOG_SND_RPC 432 LOGD("rpc_snd_set_device(%d, %d, %d)\n", device, ear_mute, mic_mute); 433#endif 434 435 fd = open("/dev/msm_snd", O_RDWR); 436 if (fd < 0) { 437 LOGE("Can not open snd device"); 438 return -EPERM; 439 } 440 // RPC call to switch audio path 441 /* rpc_snd_set_device( 442 * device, # Hardware device enum to use 443 * ear_mute, # Set mute for outgoing voice audio 444 * # this should only be unmuted when in-call 445 * mic_mute, # Set mute for incoming voice audio 446 * # this should only be unmuted when in-call or 447 * # recording. 448 * ) 449 */ 450 struct msm_snd_device_config args; 451 args.device = device; 452 args.ear_mute = ear_mute ? SND_MUTE_MUTED : SND_MUTE_UNMUTED; 453 args.mic_mute = mic_mute ? SND_MUTE_MUTED : SND_MUTE_UNMUTED; 454 455 if (ioctl(fd, SND_SET_DEVICE, &args) < 0) { 456 LOGE("snd_set_device error."); 457 close(fd); 458 return -EIO; 459 } 460 461 close(fd); 462 return NO_ERROR; 463} 464 465// always call with mutex held 466status_t AudioHardware::doAudioRouteOrMute(uint32_t device) 467{ 468 if (device == (uint32_t)SND_DEVICE_BT || device == (uint32_t)SND_DEVICE_CARKIT) { 469 if (mBluetoothId) { 470 device = mBluetoothId; 471 } else if (!mBluetoothNrec) { 472 device = SND_DEVICE_BT_EC_OFF; 473 } 474 } 475 LOGV("doAudioRouteOrMute() device %x, mMode %d, mMicMute %d", device, mMode, mMicMute); 476 return do_route_audio_rpc(device, 477 mMode != AudioSystem::MODE_IN_CALL, mMicMute); 478} 479 480status_t AudioHardware::doRouting(AudioStreamInMSM72xx *input) 481{ 482 /* currently this code doesn't work without the htc libacoustic */ 483 if (!acoustic) 484 return 0; 485 486 Mutex::Autolock lock(mLock); 487 uint32_t outputDevices = mOutput->devices(); 488 status_t ret = NO_ERROR; 489 int (*msm72xx_enable_audpp)(int); 490 msm72xx_enable_audpp = (int (*)(int))::dlsym(acoustic, "msm72xx_enable_audpp"); 491 int audProcess = (ADRC_DISABLE | EQ_DISABLE | RX_IIR_DISABLE); 492 int sndDevice = -1; 493 494 if (input != NULL) { 495 uint32_t inputDevice = input->devices(); 496 LOGI("do input routing device %x\n", inputDevice); 497 if (inputDevice != 0) { 498 if (inputDevice & AudioSystem::DEVICE_IN_BLUETOOTH_SCO_HEADSET) { 499 LOGI("Routing audio to Bluetooth PCM\n"); 500 sndDevice = SND_DEVICE_BT; 501 } else if (inputDevice & AudioSystem::DEVICE_IN_WIRED_HEADSET) { 502 if ((outputDevices & AudioSystem::DEVICE_OUT_WIRED_HEADSET) && 503 (outputDevices & AudioSystem::DEVICE_OUT_SPEAKER)) { 504 LOGI("Routing audio to Wired Headset and Speaker\n"); 505 sndDevice = SND_DEVICE_HEADSET_AND_SPEAKER; 506 audProcess = (ADRC_ENABLE | EQ_ENABLE | RX_IIR_ENABLE); 507 } else { 508 LOGI("Routing audio to Wired Headset\n"); 509 sndDevice = SND_DEVICE_HEADSET; 510 } 511 } else { 512 if (outputDevices & AudioSystem::DEVICE_OUT_SPEAKER) { 513 LOGI("Routing audio to Speakerphone\n"); 514 sndDevice = SND_DEVICE_SPEAKER; 515 audProcess = (ADRC_ENABLE | EQ_ENABLE | RX_IIR_ENABLE); 516 } else { 517 LOGI("Routing audio to Handset\n"); 518 sndDevice = SND_DEVICE_HANDSET; 519 } 520 } 521 } 522 // if inputDevice == 0, restore output routing 523 } 524 525 if (sndDevice == -1) { 526 if (outputDevices & (outputDevices - 1)) { 527 if ((outputDevices & AudioSystem::DEVICE_OUT_SPEAKER) == 0) { 528 LOGW("Hardware does not support requested route combination (%#X)," 529 " picking closest possible route...", outputDevices); 530 } 531 } 532 533 if (outputDevices & AudioSystem::DEVICE_OUT_TTY) { 534 LOGI("Routing audio to TTY\n"); 535 sndDevice = SND_DEVICE_TTY_FULL; 536 } else if (outputDevices & 537 (AudioSystem::DEVICE_OUT_BLUETOOTH_SCO | AudioSystem::DEVICE_OUT_BLUETOOTH_SCO_HEADSET)) { 538 LOGI("Routing audio to Bluetooth PCM\n"); 539 sndDevice = SND_DEVICE_BT; 540 } else if (outputDevices & AudioSystem::DEVICE_OUT_BLUETOOTH_SCO_CARKIT) { 541 LOGI("Routing audio to Bluetooth PCM\n"); 542 sndDevice = SND_DEVICE_CARKIT; 543 } else if ((outputDevices & AudioSystem::DEVICE_OUT_WIRED_HEADSET) && 544 (outputDevices & AudioSystem::DEVICE_OUT_SPEAKER)) { 545 LOGI("Routing audio to Wired Headset and Speaker\n"); 546 sndDevice = SND_DEVICE_HEADSET_AND_SPEAKER; 547 audProcess = (ADRC_ENABLE | EQ_ENABLE | RX_IIR_ENABLE); 548 } else if (outputDevices & AudioSystem::DEVICE_OUT_FM_SPEAKER) { 549 LOGI("Routing audio to FM Speakerphone (%d,%x)\n", mMode, outputDevices); 550 sndDevice = SND_DEVICE_FM_SPEAKER; 551 audProcess = (ADRC_ENABLE | EQ_ENABLE | RX_IIR_DISABLE); 552 } else if (outputDevices & AudioSystem::DEVICE_OUT_FM_HEADPHONE) { 553 if (outputDevices & AudioSystem::DEVICE_OUT_SPEAKER) { 554 LOGI("Routing audio to FM Headset and Speaker (%d,%x)\n", mMode, outputDevices); 555 sndDevice = SND_DEVICE_HEADSET_AND_SPEAKER; 556 audProcess = (ADRC_ENABLE | EQ_ENABLE | RX_IIR_ENABLE); 557 } else { 558 LOGI("Routing audio to FM Headset (%d,%x)\n", mMode, outputDevices); 559 sndDevice = SND_DEVICE_FM_HEADSET; 560 } 561 } else if (outputDevices & AudioSystem::DEVICE_OUT_WIRED_HEADPHONE) { 562 if (outputDevices & AudioSystem::DEVICE_OUT_SPEAKER) { 563 LOGI("Routing audio to No microphone Wired Headset and Speaker (%d,%x)\n", mMode, outputDevices); 564 sndDevice = SND_DEVICE_HEADSET_AND_SPEAKER; 565 audProcess = (ADRC_ENABLE | EQ_ENABLE | RX_IIR_ENABLE); 566 } else { 567 LOGI("Routing audio to No microphone Wired Headset (%d,%x)\n", mMode, outputDevices); 568 sndDevice = SND_DEVICE_NO_MIC_HEADSET; 569 } 570 } else if (outputDevices & AudioSystem::DEVICE_OUT_WIRED_HEADSET) { 571 LOGI("Routing audio to Wired Headset\n"); 572 sndDevice = SND_DEVICE_HEADSET; 573 } else if (outputDevices & AudioSystem::DEVICE_OUT_SPEAKER) { 574 LOGI("Routing audio to Speakerphone\n"); 575 sndDevice = SND_DEVICE_SPEAKER; 576 audProcess = (ADRC_ENABLE | EQ_ENABLE | RX_IIR_ENABLE); 577 } else { 578 LOGI("Routing audio to Handset\n"); 579 sndDevice = SND_DEVICE_HANDSET; 580 } 581 } 582 583 if (sndDevice != -1 && sndDevice != mCurSndDevice) { 584 ret = doAudioRouteOrMute(sndDevice); 585 if ((*msm72xx_enable_audpp) == 0 ) { 586 LOGE("Could not open msm72xx_enable_audpp()"); 587 } else { 588 msm72xx_enable_audpp(audProcess); 589 } 590 mCurSndDevice = sndDevice; 591 } 592 593 return ret; 594} 595 596status_t AudioHardware::checkMicMute() 597{ 598 Mutex::Autolock lock(mLock); 599 if (mMode != AudioSystem::MODE_IN_CALL) { 600 setMicMute_nosync(true); 601 } 602 603 return NO_ERROR; 604} 605 606status_t AudioHardware::dumpInternals(int fd, const Vector<String16>& args) 607{ 608 const size_t SIZE = 256; 609 char buffer[SIZE]; 610 String8 result; 611 result.append("AudioHardware::dumpInternals\n"); 612 snprintf(buffer, SIZE, "\tmInit: %s\n", mInit? "true": "false"); 613 result.append(buffer); 614 snprintf(buffer, SIZE, "\tmMicMute: %s\n", mMicMute? "true": "false"); 615 result.append(buffer); 616 snprintf(buffer, SIZE, "\tmBluetoothNrec: %s\n", mBluetoothNrec? "true": "false"); 617 result.append(buffer); 618 snprintf(buffer, SIZE, "\tmBluetoothId: %d\n", mBluetoothId); 619 result.append(buffer); 620 ::write(fd, result.string(), result.size()); 621 return NO_ERROR; 622} 623 624status_t AudioHardware::dump(int fd, const Vector<String16>& args) 625{ 626 dumpInternals(fd, args); 627 for (size_t index = 0; index < mInputs.size(); index++) { 628 mInputs[index]->dump(fd, args); 629 } 630 631 if (mOutput) { 632 mOutput->dump(fd, args); 633 } 634 return NO_ERROR; 635} 636 637uint32_t AudioHardware::getInputSampleRate(uint32_t sampleRate) 638{ 639 uint32_t i; 640 uint32_t prevDelta; 641 uint32_t delta; 642 643 for (i = 0, prevDelta = 0xFFFFFFFF; i < sizeof(inputSamplingRates)/sizeof(uint32_t); i++, prevDelta = delta) { 644 delta = abs(sampleRate - inputSamplingRates[i]); 645 if (delta > prevDelta) break; 646 } 647 // i is always > 0 here 648 return inputSamplingRates[i-1]; 649} 650 651// ---------------------------------------------------------------------------- 652 653AudioHardware::AudioStreamOutMSM72xx::AudioStreamOutMSM72xx() : 654 mHardware(0), mFd(-1), mStartCount(0), mRetryCount(0), mStandby(true), mDevices(0) 655{ 656} 657 658status_t AudioHardware::AudioStreamOutMSM72xx::set( 659 AudioHardware* hw, uint32_t devices, int *pFormat, uint32_t *pChannels, uint32_t *pRate) 660{ 661 int lFormat = pFormat ? *pFormat : 0; 662 uint32_t lChannels = pChannels ? *pChannels : 0; 663 uint32_t lRate = pRate ? *pRate : 0; 664 665 mHardware = hw; 666 667 // fix up defaults 668 if (lFormat == 0) lFormat = format(); 669 if (lChannels == 0) lChannels = channels(); 670 if (lRate == 0) lRate = sampleRate(); 671 672 // check values 673 if ((lFormat != format()) || 674 (lChannels != channels()) || 675 (lRate != sampleRate())) { 676 if (pFormat) *pFormat = format(); 677 if (pChannels) *pChannels = channels(); 678 if (pRate) *pRate = sampleRate(); 679 return BAD_VALUE; 680 } 681 682 if (pFormat) *pFormat = lFormat; 683 if (pChannels) *pChannels = lChannels; 684 if (pRate) *pRate = lRate; 685 686 mDevices = devices; 687 688 return NO_ERROR; 689} 690 691AudioHardware::AudioStreamOutMSM72xx::~AudioStreamOutMSM72xx() 692{ 693 if (mFd > 0) close(mFd); 694} 695 696ssize_t AudioHardware::AudioStreamOutMSM72xx::write(const void* buffer, size_t bytes) 697{ 698 // LOGD("AudioStreamOutMSM72xx::write(%p, %u)", buffer, bytes); 699 status_t status = NO_INIT; 700 size_t count = bytes; 701 const uint8_t* p = static_cast<const uint8_t*>(buffer); 702 703 if (mStandby) { 704 705 // open driver 706 LOGV("open driver"); 707 status = ::open("/dev/msm_pcm_out", O_RDWR); 708 if (status < 0) { 709 LOGE("Cannot open /dev/msm_pcm_out errno: %d", errno); 710 goto Error; 711 } 712 mFd = status; 713 714 // configuration 715 LOGV("get config"); 716 struct msm_audio_config config; 717 status = ioctl(mFd, AUDIO_GET_CONFIG, &config); 718 if (status < 0) { 719 LOGE("Cannot read config"); 720 goto Error; 721 } 722 723 LOGV("set config"); 724 config.channel_count = AudioSystem::popCount(channels()); 725 config.sample_rate = sampleRate(); 726 config.buffer_size = bufferSize(); 727 config.buffer_count = AUDIO_HW_NUM_OUT_BUF; 728 config.codec_type = CODEC_TYPE_PCM; 729 status = ioctl(mFd, AUDIO_SET_CONFIG, &config); 730 if (status < 0) { 731 LOGE("Cannot set config"); 732 goto Error; 733 } 734 735 LOGV("buffer_size: %u", config.buffer_size); 736 LOGV("buffer_count: %u", config.buffer_count); 737 LOGV("channel_count: %u", config.channel_count); 738 LOGV("sample_rate: %u", config.sample_rate); 739 740 // fill 2 buffers before AUDIO_START 741 mStartCount = AUDIO_HW_NUM_OUT_BUF; 742 mStandby = false; 743 } 744 745 while (count) { 746 ssize_t written = ::write(mFd, p, count); 747 if (written >= 0) { 748 count -= written; 749 p += written; 750 } else { 751 if (errno != EAGAIN) return written; 752 mRetryCount++; 753 LOGW("EAGAIN - retry"); 754 } 755 } 756 757 // start audio after we fill 2 buffers 758 if (mStartCount) { 759 if (--mStartCount == 0) { 760 ioctl(mFd, AUDIO_START, 0); 761 } 762 } 763 return bytes; 764 765Error: 766 if (mFd > 0) { 767 ::close(mFd); 768 mFd = -1; 769 } 770 // Simulate audio output timing in case of error 771 usleep(bytes * 1000000 / frameSize() / sampleRate()); 772 773 return status; 774} 775 776status_t AudioHardware::AudioStreamOutMSM72xx::standby() 777{ 778 status_t status = NO_ERROR; 779 if (!mStandby && mFd > 0) { 780 ::close(mFd); 781 mFd = -1; 782 } 783 mStandby = true; 784 return status; 785} 786 787status_t AudioHardware::AudioStreamOutMSM72xx::dump(int fd, const Vector<String16>& args) 788{ 789 const size_t SIZE = 256; 790 char buffer[SIZE]; 791 String8 result; 792 result.append("AudioStreamOutMSM72xx::dump\n"); 793 snprintf(buffer, SIZE, "\tsample rate: %d\n", sampleRate()); 794 result.append(buffer); 795 snprintf(buffer, SIZE, "\tbuffer size: %d\n", bufferSize()); 796 result.append(buffer); 797 snprintf(buffer, SIZE, "\tchannels: %d\n", channels()); 798 result.append(buffer); 799 snprintf(buffer, SIZE, "\tformat: %d\n", format()); 800 result.append(buffer); 801 snprintf(buffer, SIZE, "\tmHardware: %p\n", mHardware); 802 result.append(buffer); 803 snprintf(buffer, SIZE, "\tmFd: %d\n", mFd); 804 result.append(buffer); 805 snprintf(buffer, SIZE, "\tmStartCount: %d\n", mStartCount); 806 result.append(buffer); 807 snprintf(buffer, SIZE, "\tmRetryCount: %d\n", mRetryCount); 808 result.append(buffer); 809 snprintf(buffer, SIZE, "\tmStandby: %s\n", mStandby? "true": "false"); 810 result.append(buffer); 811 ::write(fd, result.string(), result.size()); 812 return NO_ERROR; 813} 814 815bool AudioHardware::AudioStreamOutMSM72xx::checkStandby() 816{ 817 return mStandby; 818} 819 820 821status_t AudioHardware::AudioStreamOutMSM72xx::setParameters(const String8& keyValuePairs) 822{ 823 AudioParameter param = AudioParameter(keyValuePairs); 824 String8 key = String8(AudioParameter::keyRouting); 825 status_t status = NO_ERROR; 826 int device; 827 LOGV("AudioStreamOutMSM72xx::setParameters() %s", keyValuePairs.string()); 828 829 if (param.getInt(key, device) == NO_ERROR) { 830 mDevices = device; 831 LOGV("set output routing %x", mDevices); 832 status = mHardware->doRouting(NULL); 833 param.remove(key); 834 } 835 836 if (param.size()) { 837 status = BAD_VALUE; 838 } 839 return status; 840} 841 842String8 AudioHardware::AudioStreamOutMSM72xx::getParameters(const String8& keys) 843{ 844 AudioParameter param = AudioParameter(keys); 845 String8 value; 846 String8 key = String8(AudioParameter::keyRouting); 847 848 if (param.get(key, value) == NO_ERROR) { 849 LOGV("get routing %x", mDevices); 850 param.addInt(key, (int)mDevices); 851 } 852 853 LOGV("AudioStreamOutMSM72xx::getParameters() %s", param.toString().string()); 854 return param.toString(); 855} 856 857 858// ---------------------------------------------------------------------------- 859 860AudioHardware::AudioStreamInMSM72xx::AudioStreamInMSM72xx() : 861 mHardware(0), mFd(-1), mState(AUDIO_INPUT_CLOSED), mRetryCount(0), 862 mFormat(AUDIO_HW_IN_FORMAT), mChannels(AUDIO_HW_IN_CHANNELS), 863 mSampleRate(AUDIO_HW_IN_SAMPLERATE), mBufferSize(AUDIO_HW_IN_BUFFERSIZE), 864 mAcoustics((AudioSystem::audio_in_acoustics)0), mDevices(0) 865{ 866} 867 868status_t AudioHardware::AudioStreamInMSM72xx::set( 869 AudioHardware* hw, uint32_t devices, int *pFormat, uint32_t *pChannels, uint32_t *pRate, 870 AudioSystem::audio_in_acoustics acoustic_flags) 871{ 872 if (pFormat == 0 || *pFormat != AUDIO_HW_IN_FORMAT) { 873 *pFormat = AUDIO_HW_IN_FORMAT; 874 return BAD_VALUE; 875 } 876 if (pRate == 0) { 877 return BAD_VALUE; 878 } 879 uint32_t rate = hw->getInputSampleRate(*pRate); 880 if (rate != *pRate) { 881 *pRate = rate; 882 return BAD_VALUE; 883 } 884 885 if (pChannels == 0 || (*pChannels != AudioSystem::CHANNEL_IN_MONO && 886 *pChannels != AudioSystem::CHANNEL_IN_STEREO)) { 887 *pChannels = AUDIO_HW_IN_CHANNELS; 888 return BAD_VALUE; 889 } 890 891 mHardware = hw; 892 893 LOGV("AudioStreamInMSM72xx::set(%d, %d, %u)", *pFormat, *pChannels, *pRate); 894 if (mFd >= 0) { 895 LOGE("Audio record already open"); 896 return -EPERM; 897 } 898 899 // open audio input device 900 status_t status = ::open("/dev/msm_pcm_in", O_RDWR); 901 if (status < 0) { 902 LOGE("Cannot open /dev/msm_pcm_in errno: %d", errno); 903 goto Error; 904 } 905 mFd = status; 906 907 // configuration 908 LOGV("get config"); 909 struct msm_audio_config config; 910 status = ioctl(mFd, AUDIO_GET_CONFIG, &config); 911 if (status < 0) { 912 LOGE("Cannot read config"); 913 goto Error; 914 } 915 916 LOGV("set config"); 917 config.channel_count = AudioSystem::popCount(*pChannels); 918 config.sample_rate = *pRate; 919 config.buffer_size = bufferSize(); 920 config.buffer_count = 2; 921 config.codec_type = CODEC_TYPE_PCM; 922 status = ioctl(mFd, AUDIO_SET_CONFIG, &config); 923 if (status < 0) { 924 LOGE("Cannot set config"); 925 if (ioctl(mFd, AUDIO_GET_CONFIG, &config) == 0) { 926 if (config.channel_count == 1) { 927 *pChannels = AudioSystem::CHANNEL_IN_MONO; 928 } else { 929 *pChannels = AudioSystem::CHANNEL_IN_STEREO; 930 } 931 *pRate = config.sample_rate; 932 } 933 goto Error; 934 } 935 936 LOGV("confirm config"); 937 status = ioctl(mFd, AUDIO_GET_CONFIG, &config); 938 if (status < 0) { 939 LOGE("Cannot read config"); 940 goto Error; 941 } 942 LOGV("buffer_size: %u", config.buffer_size); 943 LOGV("buffer_count: %u", config.buffer_count); 944 LOGV("channel_count: %u", config.channel_count); 945 LOGV("sample_rate: %u", config.sample_rate); 946 947 mDevices = devices; 948 mFormat = AUDIO_HW_IN_FORMAT; 949 mChannels = *pChannels; 950 mSampleRate = config.sample_rate; 951 mBufferSize = config.buffer_size; 952 953 //mHardware->setMicMute_nosync(false); 954 mState = AUDIO_INPUT_OPENED; 955 956 if (!acoustic) 957 return NO_ERROR; 958 959 audpre_index = calculate_audpre_table_index(mSampleRate); 960 tx_iir_index = (audpre_index * 2) + (hw->checkOutputStandby() ? 0 : 1); 961 LOGD("audpre_index = %d, tx_iir_index = %d\n", audpre_index, tx_iir_index); 962 963 /** 964 * If audio-preprocessing failed, we should not block record. 965 */ 966 int (*msm72xx_set_audpre_params)(int, int); 967 msm72xx_set_audpre_params = (int (*)(int, int))::dlsym(acoustic, "msm72xx_set_audpre_params"); 968 status = msm72xx_set_audpre_params(audpre_index, tx_iir_index); 969 if (status < 0) 970 LOGE("Cannot set audpre parameters"); 971 972 int (*msm72xx_enable_audpre)(int, int, int); 973 msm72xx_enable_audpre = (int (*)(int, int, int))::dlsym(acoustic, "msm72xx_enable_audpre"); 974 mAcoustics = acoustic_flags; 975 status = msm72xx_enable_audpre((int)acoustic_flags, audpre_index, tx_iir_index); 976 if (status < 0) 977 LOGE("Cannot enable audpre"); 978 979 return NO_ERROR; 980 981Error: 982 if (mFd > 0) { 983 ::close(mFd); 984 mFd = -1; 985 } 986 return status; 987} 988 989AudioHardware::AudioStreamInMSM72xx::~AudioStreamInMSM72xx() 990{ 991 LOGV("AudioStreamInMSM72xx destructor"); 992 standby(); 993} 994 995ssize_t AudioHardware::AudioStreamInMSM72xx::read( void* buffer, ssize_t bytes) 996{ 997 LOGV("AudioStreamInMSM72xx::read(%p, %ld)", buffer, bytes); 998 if (!mHardware) return -1; 999 1000 size_t count = bytes; 1001 uint8_t* p = static_cast<uint8_t*>(buffer); 1002 1003 if (mState < AUDIO_INPUT_OPENED) { 1004 Mutex::Autolock lock(mHardware->mLock); 1005 if (set(mHardware, mDevices, &mFormat, &mChannels, &mSampleRate, mAcoustics) != NO_ERROR) { 1006 return -1; 1007 } 1008 } 1009 1010 if (mState < AUDIO_INPUT_STARTED) { 1011 if (ioctl(mFd, AUDIO_START, 0)) { 1012 LOGE("Error starting record"); 1013 return -1; 1014 } 1015 mState = AUDIO_INPUT_STARTED; 1016 } 1017 1018 while (count) { 1019 ssize_t bytesRead = ::read(mFd, buffer, count); 1020 if (bytesRead >= 0) { 1021 count -= bytesRead; 1022 p += bytesRead; 1023 } else { 1024 if (errno != EAGAIN) return bytesRead; 1025 mRetryCount++; 1026 LOGW("EAGAIN - retrying"); 1027 } 1028 } 1029 return bytes; 1030} 1031 1032status_t AudioHardware::AudioStreamInMSM72xx::standby() 1033{ 1034 if (!mHardware) return -1; 1035 if (mState > AUDIO_INPUT_CLOSED) { 1036 if (mFd > 0) { 1037 ::close(mFd); 1038 mFd = -1; 1039 } 1040 //mHardware->checkMicMute(); 1041 mState = AUDIO_INPUT_CLOSED; 1042 } 1043 return NO_ERROR; 1044} 1045 1046status_t AudioHardware::AudioStreamInMSM72xx::dump(int fd, const Vector<String16>& args) 1047{ 1048 const size_t SIZE = 256; 1049 char buffer[SIZE]; 1050 String8 result; 1051 result.append("AudioStreamInMSM72xx::dump\n"); 1052 snprintf(buffer, SIZE, "\tsample rate: %d\n", sampleRate()); 1053 result.append(buffer); 1054 snprintf(buffer, SIZE, "\tbuffer size: %d\n", bufferSize()); 1055 result.append(buffer); 1056 snprintf(buffer, SIZE, "\tchannels: %d\n", channels()); 1057 result.append(buffer); 1058 snprintf(buffer, SIZE, "\tformat: %d\n", format()); 1059 result.append(buffer); 1060 snprintf(buffer, SIZE, "\tmHardware: %p\n", mHardware); 1061 result.append(buffer); 1062 snprintf(buffer, SIZE, "\tmFd count: %d\n", mFd); 1063 result.append(buffer); 1064 snprintf(buffer, SIZE, "\tmState: %d\n", mState); 1065 result.append(buffer); 1066 snprintf(buffer, SIZE, "\tmRetryCount: %d\n", mRetryCount); 1067 result.append(buffer); 1068 ::write(fd, result.string(), result.size()); 1069 return NO_ERROR; 1070} 1071 1072status_t AudioHardware::AudioStreamInMSM72xx::setParameters(const String8& keyValuePairs) 1073{ 1074 AudioParameter param = AudioParameter(keyValuePairs); 1075 String8 key = String8(AudioParameter::keyRouting); 1076 status_t status = NO_ERROR; 1077 int device; 1078 LOGV("AudioStreamInMSM72xx::setParameters() %s", keyValuePairs.string()); 1079 1080 if (param.getInt(key, device) == NO_ERROR) { 1081 LOGV("set input routing %x", device); 1082 if (device & (device - 1)) { 1083 status = BAD_VALUE; 1084 } else { 1085 mDevices = device; 1086 status = mHardware->doRouting(this); 1087 } 1088 param.remove(key); 1089 } 1090 1091 if (param.size()) { 1092 status = BAD_VALUE; 1093 } 1094 return status; 1095} 1096 1097String8 AudioHardware::AudioStreamInMSM72xx::getParameters(const String8& keys) 1098{ 1099 AudioParameter param = AudioParameter(keys); 1100 String8 value; 1101 String8 key = String8(AudioParameter::keyRouting); 1102 1103 if (param.get(key, value) == NO_ERROR) { 1104 LOGV("get routing %x", mDevices); 1105 param.addInt(key, (int)mDevices); 1106 } 1107 1108 LOGV("AudioStreamInMSM72xx::getParameters() %s", param.toString().string()); 1109 return param.toString(); 1110} 1111 1112// ---------------------------------------------------------------------------- 1113 1114extern "C" AudioHardwareInterface* createAudioHardware(void) { 1115 return new AudioHardware(); 1116} 1117 1118}; // namespace android 1119