AudioHardware.cpp revision 2735e3b55bdaf33cfd0dbaa1b914231243933e92
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 String8 result = String8(""); 316 return result; 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) { 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 & AudioSystem::DEVICE_OUT_BLUETOOTH_SCO) { 537 LOGI("Routing audio to Bluetooth PCM\n"); 538 sndDevice = SND_DEVICE_BT; 539 } else if ((outputDevices & AudioSystem::DEVICE_OUT_WIRED_HEADSET) && 540 (outputDevices & AudioSystem::DEVICE_OUT_SPEAKER)) { 541 LOGI("Routing audio to Wired Headset and Speaker\n"); 542 sndDevice = SND_DEVICE_HEADSET_AND_SPEAKER; 543 audProcess = (ADRC_ENABLE | EQ_ENABLE | RX_IIR_ENABLE); 544 } else if (outputDevices & AudioSystem::DEVICE_OUT_FM_SPEAKER) { 545 LOGI("Routing audio to FM Speakerphone (%d,%x)\n", mMode, outputDevices); 546 sndDevice = SND_DEVICE_FM_SPEAKER; 547 audProcess = (ADRC_ENABLE | EQ_ENABLE | RX_IIR_DISABLE); 548 } else if (outputDevices & AudioSystem::DEVICE_OUT_FM_HEADPHONE) { 549 if (outputDevices & AudioSystem::DEVICE_OUT_SPEAKER) { 550 LOGI("Routing audio to FM Headset and Speaker (%d,%x)\n", mMode, outputDevices); 551 sndDevice = SND_DEVICE_HEADSET_AND_SPEAKER; 552 audProcess = (ADRC_ENABLE | EQ_ENABLE | RX_IIR_ENABLE); 553 } else { 554 LOGI("Routing audio to FM Headset (%d,%x)\n", mMode, outputDevices); 555 sndDevice = doAudioRouteOrMute(SND_DEVICE_FM_HEADSET); 556 } 557 } else if (outputDevices & AudioSystem::DEVICE_OUT_WIRED_HEADPHONE) { 558 if (outputDevices & AudioSystem::DEVICE_OUT_SPEAKER) { 559 LOGI("Routing audio to No microphone Wired Headset and Speaker (%d,%x)\n", mMode, outputDevices); 560 sndDevice = SND_DEVICE_HEADSET_AND_SPEAKER; 561 audProcess = (ADRC_ENABLE | EQ_ENABLE | RX_IIR_ENABLE); 562 } else { 563 LOGI("Routing audio to No microphone Wired Headset (%d,%x)\n", mMode, outputDevices); 564 sndDevice = SND_DEVICE_NO_MIC_HEADSET; 565 } 566 } else if (outputDevices & AudioSystem::DEVICE_OUT_WIRED_HEADSET) { 567 LOGI("Routing audio to Wired Headset\n"); 568 sndDevice = SND_DEVICE_HEADSET; 569 } else if (outputDevices & AudioSystem::DEVICE_OUT_SPEAKER) { 570 LOGI("Routing audio to Speakerphone\n"); 571 sndDevice = SND_DEVICE_SPEAKER; 572 audProcess = (ADRC_ENABLE | EQ_ENABLE | RX_IIR_ENABLE); 573 } else { 574 LOGI("Routing audio to Handset\n"); 575 sndDevice = SND_DEVICE_HANDSET; 576 } 577 } 578 579 if (sndDevice != -1 && sndDevice != mCurSndDevice) { 580 ret = doAudioRouteOrMute(sndDevice); 581 if ((*msm72xx_enable_audpp) == 0 ) { 582 LOGE("Could not open msm72xx_enable_audpp()"); 583 } else { 584 msm72xx_enable_audpp(audProcess); 585 } 586 mCurSndDevice = sndDevice; 587 } 588 589 return ret; 590} 591 592status_t AudioHardware::checkMicMute() 593{ 594 Mutex::Autolock lock(mLock); 595 if (mMode != AudioSystem::MODE_IN_CALL) { 596 setMicMute_nosync(true); 597 } 598 599 return NO_ERROR; 600} 601 602status_t AudioHardware::dumpInternals(int fd, const Vector<String16>& args) 603{ 604 const size_t SIZE = 256; 605 char buffer[SIZE]; 606 String8 result; 607 result.append("AudioHardware::dumpInternals\n"); 608 snprintf(buffer, SIZE, "\tmInit: %s\n", mInit? "true": "false"); 609 result.append(buffer); 610 snprintf(buffer, SIZE, "\tmMicMute: %s\n", mMicMute? "true": "false"); 611 result.append(buffer); 612 snprintf(buffer, SIZE, "\tmBluetoothNrec: %s\n", mBluetoothNrec? "true": "false"); 613 result.append(buffer); 614 snprintf(buffer, SIZE, "\tmBluetoothId: %d\n", mBluetoothId); 615 result.append(buffer); 616 ::write(fd, result.string(), result.size()); 617 return NO_ERROR; 618} 619 620status_t AudioHardware::dump(int fd, const Vector<String16>& args) 621{ 622 dumpInternals(fd, args); 623 for (size_t index = 0; index < mInputs.size(); index++) { 624 mInputs[index]->dump(fd, args); 625 } 626 627 if (mOutput) { 628 mOutput->dump(fd, args); 629 } 630 return NO_ERROR; 631} 632 633uint32_t AudioHardware::getInputSampleRate(uint32_t sampleRate) 634{ 635 uint32_t i; 636 uint32_t prevDelta; 637 uint32_t delta; 638 639 for (i = 0, prevDelta = 0xFFFFFFFF; i < sizeof(inputSamplingRates)/sizeof(uint32_t); i++, prevDelta = delta) { 640 delta = abs(sampleRate - inputSamplingRates[i]); 641 if (delta > prevDelta) break; 642 } 643 // i is always > 0 here 644 return inputSamplingRates[i-1]; 645} 646 647// ---------------------------------------------------------------------------- 648 649AudioHardware::AudioStreamOutMSM72xx::AudioStreamOutMSM72xx() : 650 mHardware(0), mFd(-1), mStartCount(0), mRetryCount(0), mStandby(true), mDevices(0) 651{ 652} 653 654status_t AudioHardware::AudioStreamOutMSM72xx::set( 655 AudioHardware* hw, uint32_t devices, int *pFormat, uint32_t *pChannels, uint32_t *pRate) 656{ 657 int lFormat = pFormat ? *pFormat : 0; 658 uint32_t lChannels = pChannels ? *pChannels : 0; 659 uint32_t lRate = pRate ? *pRate : 0; 660 661 mHardware = hw; 662 663 // fix up defaults 664 if (lFormat == 0) lFormat = format(); 665 if (lChannels == 0) lChannels = channels(); 666 if (lRate == 0) lRate = sampleRate(); 667 668 // check values 669 if ((lFormat != format()) || 670 (lChannels != channels()) || 671 (lRate != sampleRate())) { 672 if (pFormat) *pFormat = format(); 673 if (pChannels) *pChannels = channels(); 674 if (pRate) *pRate = sampleRate(); 675 return BAD_VALUE; 676 } 677 678 if (pFormat) *pFormat = lFormat; 679 if (pChannels) *pChannels = lChannels; 680 if (pRate) *pRate = lRate; 681 682 mDevices = devices; 683 684 return NO_ERROR; 685} 686 687AudioHardware::AudioStreamOutMSM72xx::~AudioStreamOutMSM72xx() 688{ 689 if (mFd > 0) close(mFd); 690} 691 692ssize_t AudioHardware::AudioStreamOutMSM72xx::write(const void* buffer, size_t bytes) 693{ 694 // LOGD("AudioStreamOutMSM72xx::write(%p, %u)", buffer, bytes); 695 status_t status = NO_INIT; 696 size_t count = bytes; 697 const uint8_t* p = static_cast<const uint8_t*>(buffer); 698 699 if (mStandby) { 700 701 // open driver 702 LOGV("open driver"); 703 status = ::open("/dev/msm_pcm_out", O_RDWR); 704 if (status < 0) { 705 LOGE("Cannot open /dev/msm_pcm_out errno: %d", errno); 706 goto Error; 707 } 708 mFd = status; 709 710 // configuration 711 LOGV("get config"); 712 struct msm_audio_config config; 713 status = ioctl(mFd, AUDIO_GET_CONFIG, &config); 714 if (status < 0) { 715 LOGE("Cannot read config"); 716 goto Error; 717 } 718 719 LOGV("set config"); 720 config.channel_count = AudioSystem::popCount(channels()); 721 config.sample_rate = sampleRate(); 722 config.buffer_size = bufferSize(); 723 config.buffer_count = AUDIO_HW_NUM_OUT_BUF; 724 config.codec_type = CODEC_TYPE_PCM; 725 status = ioctl(mFd, AUDIO_SET_CONFIG, &config); 726 if (status < 0) { 727 LOGE("Cannot set config"); 728 goto Error; 729 } 730 731 LOGV("buffer_size: %u", config.buffer_size); 732 LOGV("buffer_count: %u", config.buffer_count); 733 LOGV("channel_count: %u", config.channel_count); 734 LOGV("sample_rate: %u", config.sample_rate); 735 736 // fill 2 buffers before AUDIO_START 737 mStartCount = AUDIO_HW_NUM_OUT_BUF; 738 mStandby = false; 739 } 740 741 while (count) { 742 ssize_t written = ::write(mFd, p, count); 743 if (written >= 0) { 744 count -= written; 745 p += written; 746 } else { 747 if (errno != EAGAIN) return written; 748 mRetryCount++; 749 LOGW("EAGAIN - retry"); 750 } 751 } 752 753 // start audio after we fill 2 buffers 754 if (mStartCount) { 755 if (--mStartCount == 0) { 756 ioctl(mFd, AUDIO_START, 0); 757 } 758 } 759 return bytes; 760 761Error: 762 if (mFd > 0) { 763 ::close(mFd); 764 mFd = -1; 765 } 766 // Simulate audio output timing in case of error 767 usleep(bytes * 1000000 / frameSize() / sampleRate()); 768 769 return status; 770} 771 772status_t AudioHardware::AudioStreamOutMSM72xx::standby() 773{ 774 status_t status = NO_ERROR; 775 if (!mStandby && mFd > 0) { 776 ::close(mFd); 777 mFd = -1; 778 } 779 mStandby = true; 780 return status; 781} 782 783status_t AudioHardware::AudioStreamOutMSM72xx::dump(int fd, const Vector<String16>& args) 784{ 785 const size_t SIZE = 256; 786 char buffer[SIZE]; 787 String8 result; 788 result.append("AudioStreamOutMSM72xx::dump\n"); 789 snprintf(buffer, SIZE, "\tsample rate: %d\n", sampleRate()); 790 result.append(buffer); 791 snprintf(buffer, SIZE, "\tbuffer size: %d\n", bufferSize()); 792 result.append(buffer); 793 snprintf(buffer, SIZE, "\tchannels: %d\n", channels()); 794 result.append(buffer); 795 snprintf(buffer, SIZE, "\tformat: %d\n", format()); 796 result.append(buffer); 797 snprintf(buffer, SIZE, "\tmHardware: %p\n", mHardware); 798 result.append(buffer); 799 snprintf(buffer, SIZE, "\tmFd: %d\n", mFd); 800 result.append(buffer); 801 snprintf(buffer, SIZE, "\tmStartCount: %d\n", mStartCount); 802 result.append(buffer); 803 snprintf(buffer, SIZE, "\tmRetryCount: %d\n", mRetryCount); 804 result.append(buffer); 805 snprintf(buffer, SIZE, "\tmStandby: %s\n", mStandby? "true": "false"); 806 result.append(buffer); 807 ::write(fd, result.string(), result.size()); 808 return NO_ERROR; 809} 810 811bool AudioHardware::AudioStreamOutMSM72xx::checkStandby() 812{ 813 return mStandby; 814} 815 816 817status_t AudioHardware::AudioStreamOutMSM72xx::setParameters(const String8& keyValuePairs) 818{ 819 AudioParameter param = AudioParameter(keyValuePairs); 820 String8 key = String8(AudioParameter::keyRouting); 821 status_t status = NO_ERROR; 822 int device; 823 LOGV("AudioStreamOutMSM72xx::setParameters() %s", keyValuePairs.string()); 824 825 if (param.getInt(key, device) == NO_ERROR) { 826 mDevices = device; 827 LOGV("set output routing %x", mDevices); 828 status = mHardware->doRouting(NULL); 829 param.remove(key); 830 } 831 832 if (param.size()) { 833 status = BAD_VALUE; 834 } 835 return status; 836} 837 838String8 AudioHardware::AudioStreamOutMSM72xx::getParameters(const String8& keys) 839{ 840 AudioParameter param = AudioParameter(keys); 841 String8 value; 842 String8 key = String8(AudioParameter::keyRouting); 843 844 if (param.get(key, value) == NO_ERROR) { 845 LOGV("get routing %x", mDevices); 846 param.addInt(key, (int)mDevices); 847 } 848 849 LOGV("AudioStreamOutMSM72xx::getParameters() %s", param.toString().string()); 850 return param.toString(); 851} 852 853 854// ---------------------------------------------------------------------------- 855 856AudioHardware::AudioStreamInMSM72xx::AudioStreamInMSM72xx() : 857 mHardware(0), mFd(-1), mState(AUDIO_INPUT_CLOSED), mRetryCount(0), 858 mFormat(AUDIO_HW_IN_FORMAT), mChannels(AUDIO_HW_IN_CHANNELS), 859 mSampleRate(AUDIO_HW_IN_SAMPLERATE), mBufferSize(AUDIO_HW_IN_BUFFERSIZE), 860 mAcoustics((AudioSystem::audio_in_acoustics)0), mDevices(0) 861{ 862} 863 864status_t AudioHardware::AudioStreamInMSM72xx::set( 865 AudioHardware* hw, uint32_t devices, int *pFormat, uint32_t *pChannels, uint32_t *pRate, 866 AudioSystem::audio_in_acoustics acoustic_flags) 867{ 868 if (pFormat == 0 || *pFormat != AUDIO_HW_IN_FORMAT) { 869 *pFormat = AUDIO_HW_IN_FORMAT; 870 return BAD_VALUE; 871 } 872 if (pRate == 0) { 873 return BAD_VALUE; 874 } 875 uint32_t rate = hw->getInputSampleRate(*pRate); 876 if (rate != *pRate) { 877 *pRate = rate; 878 return BAD_VALUE; 879 } 880 881 if (pChannels == 0 || (*pChannels != AudioSystem::CHANNEL_IN_MONO && 882 *pChannels != AudioSystem::CHANNEL_IN_STEREO)) { 883 *pChannels = AUDIO_HW_IN_CHANNELS; 884 return BAD_VALUE; 885 } 886 887 mHardware = hw; 888 889 LOGV("AudioStreamInMSM72xx::set(%d, %d, %u)", *pFormat, *pChannels, *pRate); 890 if (mFd >= 0) { 891 LOGE("Audio record already open"); 892 return -EPERM; 893 } 894 895 // open audio input device 896 status_t status = ::open("/dev/msm_pcm_in", O_RDWR); 897 if (status < 0) { 898 LOGE("Cannot open /dev/msm_pcm_in errno: %d", errno); 899 goto Error; 900 } 901 mFd = status; 902 903 // configuration 904 LOGV("get config"); 905 struct msm_audio_config config; 906 status = ioctl(mFd, AUDIO_GET_CONFIG, &config); 907 if (status < 0) { 908 LOGE("Cannot read config"); 909 goto Error; 910 } 911 912 LOGV("set config"); 913 config.channel_count = AudioSystem::popCount(*pChannels); 914 config.sample_rate = *pRate; 915 config.buffer_size = bufferSize(); 916 config.buffer_count = 2; 917 config.codec_type = CODEC_TYPE_PCM; 918 status = ioctl(mFd, AUDIO_SET_CONFIG, &config); 919 if (status < 0) { 920 LOGE("Cannot set config"); 921 if (ioctl(mFd, AUDIO_GET_CONFIG, &config) == 0) { 922 if (config.channel_count == 1) { 923 *pChannels = AudioSystem::CHANNEL_IN_MONO; 924 } else { 925 *pChannels = AudioSystem::CHANNEL_IN_STEREO; 926 } 927 *pRate = config.sample_rate; 928 } 929 goto Error; 930 } 931 932 LOGV("confirm config"); 933 status = ioctl(mFd, AUDIO_GET_CONFIG, &config); 934 if (status < 0) { 935 LOGE("Cannot read config"); 936 goto Error; 937 } 938 LOGV("buffer_size: %u", config.buffer_size); 939 LOGV("buffer_count: %u", config.buffer_count); 940 LOGV("channel_count: %u", config.channel_count); 941 LOGV("sample_rate: %u", config.sample_rate); 942 943 mDevices = devices; 944 mFormat = AUDIO_HW_IN_FORMAT; 945 mChannels = *pChannels; 946 mSampleRate = config.sample_rate; 947 mBufferSize = config.buffer_size; 948 949 //mHardware->setMicMute_nosync(false); 950 mState = AUDIO_INPUT_OPENED; 951 952 if (!acoustic) 953 return NO_ERROR; 954 955 audpre_index = calculate_audpre_table_index(mSampleRate); 956 tx_iir_index = (audpre_index * 2) + (hw->checkOutputStandby() ? 0 : 1); 957 LOGD("audpre_index = %d, tx_iir_index = %d\n", audpre_index, tx_iir_index); 958 959 /** 960 * If audio-preprocessing failed, we should not block record. 961 */ 962 int (*msm72xx_set_audpre_params)(int, int); 963 msm72xx_set_audpre_params = (int (*)(int, int))::dlsym(acoustic, "msm72xx_set_audpre_params"); 964 status = msm72xx_set_audpre_params(audpre_index, tx_iir_index); 965 if (status < 0) 966 LOGE("Cannot set audpre parameters"); 967 968 int (*msm72xx_enable_audpre)(int, int, int); 969 msm72xx_enable_audpre = (int (*)(int, int, int))::dlsym(acoustic, "msm72xx_enable_audpre"); 970 mAcoustics = acoustic_flags; 971 status = msm72xx_enable_audpre((int)acoustic_flags, audpre_index, tx_iir_index); 972 if (status < 0) 973 LOGE("Cannot enable audpre"); 974 975 return NO_ERROR; 976 977Error: 978 if (mFd > 0) { 979 ::close(mFd); 980 mFd = -1; 981 } 982 return status; 983} 984 985AudioHardware::AudioStreamInMSM72xx::~AudioStreamInMSM72xx() 986{ 987 LOGV("AudioStreamInMSM72xx destructor"); 988 standby(); 989} 990 991ssize_t AudioHardware::AudioStreamInMSM72xx::read( void* buffer, ssize_t bytes) 992{ 993 LOGV("AudioStreamInMSM72xx::read(%p, %ld)", buffer, bytes); 994 if (!mHardware) return -1; 995 996 size_t count = bytes; 997 uint8_t* p = static_cast<uint8_t*>(buffer); 998 999 if (mState < AUDIO_INPUT_OPENED) { 1000 Mutex::Autolock lock(mHardware->mLock); 1001 if (set(mHardware, mDevices, &mFormat, &mChannels, &mSampleRate, mAcoustics) != NO_ERROR) { 1002 return -1; 1003 } 1004 } 1005 1006 if (mState < AUDIO_INPUT_STARTED) { 1007 if (ioctl(mFd, AUDIO_START, 0)) { 1008 LOGE("Error starting record"); 1009 return -1; 1010 } 1011 mState = AUDIO_INPUT_STARTED; 1012 } 1013 1014 while (count) { 1015 ssize_t bytesRead = ::read(mFd, buffer, count); 1016 if (bytesRead >= 0) { 1017 count -= bytesRead; 1018 p += bytesRead; 1019 } else { 1020 if (errno != EAGAIN) return bytesRead; 1021 mRetryCount++; 1022 LOGW("EAGAIN - retrying"); 1023 } 1024 } 1025 return bytes; 1026} 1027 1028status_t AudioHardware::AudioStreamInMSM72xx::standby() 1029{ 1030 if (!mHardware) return -1; 1031 if (mState > AUDIO_INPUT_CLOSED) { 1032 if (mFd > 0) { 1033 ::close(mFd); 1034 mFd = -1; 1035 } 1036 //mHardware->checkMicMute(); 1037 mState = AUDIO_INPUT_CLOSED; 1038 } 1039 return NO_ERROR; 1040} 1041 1042status_t AudioHardware::AudioStreamInMSM72xx::dump(int fd, const Vector<String16>& args) 1043{ 1044 const size_t SIZE = 256; 1045 char buffer[SIZE]; 1046 String8 result; 1047 result.append("AudioStreamInMSM72xx::dump\n"); 1048 snprintf(buffer, SIZE, "\tsample rate: %d\n", sampleRate()); 1049 result.append(buffer); 1050 snprintf(buffer, SIZE, "\tbuffer size: %d\n", bufferSize()); 1051 result.append(buffer); 1052 snprintf(buffer, SIZE, "\tchannels: %d\n", channels()); 1053 result.append(buffer); 1054 snprintf(buffer, SIZE, "\tformat: %d\n", format()); 1055 result.append(buffer); 1056 snprintf(buffer, SIZE, "\tmHardware: %p\n", mHardware); 1057 result.append(buffer); 1058 snprintf(buffer, SIZE, "\tmFd count: %d\n", mFd); 1059 result.append(buffer); 1060 snprintf(buffer, SIZE, "\tmState: %d\n", mState); 1061 result.append(buffer); 1062 snprintf(buffer, SIZE, "\tmRetryCount: %d\n", mRetryCount); 1063 result.append(buffer); 1064 ::write(fd, result.string(), result.size()); 1065 return NO_ERROR; 1066} 1067 1068status_t AudioHardware::AudioStreamInMSM72xx::setParameters(const String8& keyValuePairs) 1069{ 1070 AudioParameter param = AudioParameter(keyValuePairs); 1071 String8 key = String8(AudioParameter::keyRouting); 1072 status_t status = NO_ERROR; 1073 int device; 1074 LOGV("AudioStreamInMSM72xx::setParameters() %s", keyValuePairs.string()); 1075 1076 if (param.getInt(key, device) == NO_ERROR) { 1077 LOGV("set input routing %x", device); 1078 if (device & (device - 1)) { 1079 status = BAD_VALUE; 1080 } else { 1081 mDevices = device; 1082 status = mHardware->doRouting(this); 1083 } 1084 param.remove(key); 1085 } 1086 1087 if (param.size()) { 1088 status = BAD_VALUE; 1089 } 1090 return status; 1091} 1092 1093String8 AudioHardware::AudioStreamInMSM72xx::getParameters(const String8& keys) 1094{ 1095 AudioParameter param = AudioParameter(keys); 1096 String8 value; 1097 String8 key = String8(AudioParameter::keyRouting); 1098 1099 if (param.get(key, value) == NO_ERROR) { 1100 LOGV("get routing %x", mDevices); 1101 param.addInt(key, (int)mDevices); 1102 } 1103 1104 LOGV("AudioStreamInMSM72xx::getParameters() %s", param.toString().string()); 1105 return param.toString(); 1106} 1107 1108// ---------------------------------------------------------------------------- 1109 1110extern "C" AudioHardwareInterface* createAudioHardware(void) { 1111 return new AudioHardware(); 1112} 1113 1114}; // namespace android 1115