AudioHardware.cpp revision 3b9744cccd99fd9f32ae3b99fbc8d6898b118a43
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 239status_t AudioHardware::setMode(int mode) 240{ 241 status_t status = AudioHardwareBase::setMode(mode); 242 if (status == NO_ERROR) { 243 // make sure that doAudioRouteOrMute() is called by doRouting() 244 // even if the new device selected is the same as current one. 245 mCurSndDevice = -1; 246 } 247 return status; 248} 249 250bool AudioHardware::checkOutputStandby() 251{ 252 if (mOutput) 253 if (!mOutput->checkStandby()) 254 return false; 255 256 return true; 257} 258 259status_t AudioHardware::setMicMute(bool state) 260{ 261 Mutex::Autolock lock(mLock); 262 return setMicMute_nosync(state); 263} 264 265// always call with mutex held 266status_t AudioHardware::setMicMute_nosync(bool state) 267{ 268 if (mMicMute != state) { 269 mMicMute = state; 270 return doAudioRouteOrMute(SND_DEVICE_CURRENT); 271 } 272 return NO_ERROR; 273} 274 275status_t AudioHardware::getMicMute(bool* state) 276{ 277 *state = mMicMute; 278 return NO_ERROR; 279} 280 281status_t AudioHardware::setParameters(const String8& keyValuePairs) 282{ 283 AudioParameter param = AudioParameter(keyValuePairs); 284 String8 value; 285 String8 key; 286 const char BT_NREC_KEY[] = "bt_headset_nrec"; 287 const char BT_NAME_KEY[] = "bt_headset_name"; 288 const char BT_NREC_VALUE_ON[] = "on"; 289 290 291 LOGV("setParameters() %s", keyValuePairs.string()); 292 293 if (keyValuePairs.length() == 0) return BAD_VALUE; 294 295 key = String8(BT_NREC_KEY); 296 if (param.get(key, value) == NO_ERROR) { 297 if (value == BT_NREC_VALUE_ON) { 298 mBluetoothNrec = true; 299 } else { 300 mBluetoothNrec = false; 301 LOGI("Turning noise reduction and echo cancellation off for BT " 302 "headset"); 303 } 304 } 305 key = String8(BT_NAME_KEY); 306 if (param.get(key, value) == NO_ERROR) { 307 mBluetoothId = 0; 308 for (int i = 0; i < mNumSndEndpoints; i++) { 309 if (!strcasecmp(value.string(), mSndEndpoints[i].name)) { 310 mBluetoothId = mSndEndpoints[i].id; 311 LOGI("Using custom acoustic parameters for %s", value.string()); 312 break; 313 } 314 } 315 if (mBluetoothId == 0) { 316 LOGI("Using default acoustic parameters " 317 "(%s not in acoustic database)", value.string()); 318 doRouting(NULL); 319 } 320 } 321 return NO_ERROR; 322} 323 324String8 AudioHardware::getParameters(const String8& keys) 325{ 326 AudioParameter param = AudioParameter(keys); 327 return param.toString(); 328} 329 330 331static unsigned calculate_audpre_table_index(unsigned index) 332{ 333 switch (index) { 334 case 48000: return SAMP_RATE_INDX_48000; 335 case 44100: return SAMP_RATE_INDX_44100; 336 case 32000: return SAMP_RATE_INDX_32000; 337 case 24000: return SAMP_RATE_INDX_24000; 338 case 22050: return SAMP_RATE_INDX_22050; 339 case 16000: return SAMP_RATE_INDX_16000; 340 case 12000: return SAMP_RATE_INDX_12000; 341 case 11025: return SAMP_RATE_INDX_11025; 342 case 8000: return SAMP_RATE_INDX_8000; 343 default: return -1; 344 } 345} 346size_t AudioHardware::getInputBufferSize(uint32_t sampleRate, int format, int channelCount) 347{ 348 if (format != AudioSystem::PCM_16_BIT) { 349 LOGW("getInputBufferSize bad format: %d", format); 350 return 0; 351 } 352 if (channelCount < 1 || channelCount > 2) { 353 LOGW("getInputBufferSize bad channel count: %d", channelCount); 354 return 0; 355 } 356 357 return 2048*channelCount; 358} 359 360static status_t set_volume_rpc(uint32_t device, 361 uint32_t method, 362 uint32_t volume) 363{ 364 int fd; 365#if LOG_SND_RPC 366 LOGD("rpc_snd_set_volume(%d, %d, %d)\n", device, method, volume); 367#endif 368 369 if (device == -1UL) return NO_ERROR; 370 371 fd = open("/dev/msm_snd", O_RDWR); 372 if (fd < 0) { 373 LOGE("Can not open snd device"); 374 return -EPERM; 375 } 376 /* rpc_snd_set_volume( 377 * device, # Any hardware device enum, including 378 * # SND_DEVICE_CURRENT 379 * method, # must be SND_METHOD_VOICE to do anything useful 380 * volume, # integer volume level, in range [0,5]. 381 * # note that 0 is audible (not quite muted) 382 * ) 383 * rpc_snd_set_volume only works for in-call sound volume. 384 */ 385 struct msm_snd_volume_config args; 386 args.device = device; 387 args.method = method; 388 args.volume = volume; 389 390 if (ioctl(fd, SND_SET_VOLUME, &args) < 0) { 391 LOGE("snd_set_volume error."); 392 close(fd); 393 return -EIO; 394 } 395 close(fd); 396 return NO_ERROR; 397} 398 399status_t AudioHardware::setVoiceVolume(float v) 400{ 401 if (v < 0.0) { 402 LOGW("setVoiceVolume(%f) under 0.0, assuming 0.0\n", v); 403 v = 0.0; 404 } else if (v > 1.0) { 405 LOGW("setVoiceVolume(%f) over 1.0, assuming 1.0\n", v); 406 v = 1.0; 407 } 408 409 int vol = lrint(v * 5.0); 410 LOGD("setVoiceVolume(%f)\n", v); 411 LOGI("Setting in-call volume to %d (available range is 0 to 5)\n", vol); 412 413 Mutex::Autolock lock(mLock); 414 set_volume_rpc(SND_DEVICE_CURRENT, SND_METHOD_VOICE, vol); 415 return NO_ERROR; 416} 417 418status_t AudioHardware::setMasterVolume(float v) 419{ 420 Mutex::Autolock lock(mLock); 421 int vol = ceil(v * 5.0); 422 LOGI("Set master volume to %d.\n", vol); 423 /* 424 set_volume_rpc(SND_DEVICE_HANDSET, SND_METHOD_VOICE, vol); 425 set_volume_rpc(SND_DEVICE_SPEAKER, SND_METHOD_VOICE, vol); 426 set_volume_rpc(SND_DEVICE_BT, SND_METHOD_VOICE, vol); 427 set_volume_rpc(SND_DEVICE_HEADSET, SND_METHOD_VOICE, vol); 428 */ 429 // We return an error code here to let the audioflinger do in-software 430 // volume on top of the maximum volume that we set through the SND API. 431 // return error - software mixer will handle it 432 return -1; 433} 434 435static status_t do_route_audio_rpc(uint32_t device, 436 bool ear_mute, bool mic_mute) 437{ 438 if (device == -1UL) 439 return NO_ERROR; 440 441 int fd; 442#if LOG_SND_RPC 443 LOGD("rpc_snd_set_device(%d, %d, %d)\n", device, ear_mute, mic_mute); 444#endif 445 446 fd = open("/dev/msm_snd", O_RDWR); 447 if (fd < 0) { 448 LOGE("Can not open snd device"); 449 return -EPERM; 450 } 451 // RPC call to switch audio path 452 /* rpc_snd_set_device( 453 * device, # Hardware device enum to use 454 * ear_mute, # Set mute for outgoing voice audio 455 * # this should only be unmuted when in-call 456 * mic_mute, # Set mute for incoming voice audio 457 * # this should only be unmuted when in-call or 458 * # recording. 459 * ) 460 */ 461 struct msm_snd_device_config args; 462 args.device = device; 463 args.ear_mute = ear_mute ? SND_MUTE_MUTED : SND_MUTE_UNMUTED; 464 args.mic_mute = mic_mute ? SND_MUTE_MUTED : SND_MUTE_UNMUTED; 465 466 if (ioctl(fd, SND_SET_DEVICE, &args) < 0) { 467 LOGE("snd_set_device error."); 468 close(fd); 469 return -EIO; 470 } 471 472 close(fd); 473 return NO_ERROR; 474} 475 476// always call with mutex held 477status_t AudioHardware::doAudioRouteOrMute(uint32_t device) 478{ 479 if (device == (uint32_t)SND_DEVICE_BT || device == (uint32_t)SND_DEVICE_CARKIT) { 480 if (mBluetoothId) { 481 device = mBluetoothId; 482 } else if (!mBluetoothNrec) { 483 device = SND_DEVICE_BT_EC_OFF; 484 } 485 } 486 LOGV("doAudioRouteOrMute() device %x, mMode %d, mMicMute %d", device, mMode, mMicMute); 487 return do_route_audio_rpc(device, 488 mMode != AudioSystem::MODE_IN_CALL, mMicMute); 489} 490 491status_t AudioHardware::doRouting(AudioStreamInMSM72xx *input) 492{ 493 /* currently this code doesn't work without the htc libacoustic */ 494 if (!acoustic) 495 return 0; 496 497 Mutex::Autolock lock(mLock); 498 uint32_t outputDevices = mOutput->devices(); 499 status_t ret = NO_ERROR; 500 int (*msm72xx_enable_audpp)(int); 501 msm72xx_enable_audpp = (int (*)(int))::dlsym(acoustic, "msm72xx_enable_audpp"); 502 int audProcess = (ADRC_DISABLE | EQ_DISABLE | RX_IIR_DISABLE); 503 int sndDevice = -1; 504 505 if (input != NULL) { 506 uint32_t inputDevice = input->devices(); 507 LOGI("do input routing device %x\n", inputDevice); 508 if (inputDevice != 0) { 509 if (inputDevice & AudioSystem::DEVICE_IN_BLUETOOTH_SCO_HEADSET) { 510 LOGI("Routing audio to Bluetooth PCM\n"); 511 sndDevice = SND_DEVICE_BT; 512 } else if (inputDevice & AudioSystem::DEVICE_IN_WIRED_HEADSET) { 513 if ((outputDevices & AudioSystem::DEVICE_OUT_WIRED_HEADSET) && 514 (outputDevices & AudioSystem::DEVICE_OUT_SPEAKER)) { 515 LOGI("Routing audio to Wired Headset and Speaker\n"); 516 sndDevice = SND_DEVICE_HEADSET_AND_SPEAKER; 517 audProcess = (ADRC_ENABLE | EQ_ENABLE | RX_IIR_ENABLE); 518 } else { 519 LOGI("Routing audio to Wired Headset\n"); 520 sndDevice = SND_DEVICE_HEADSET; 521 } 522 } else { 523 if (outputDevices & AudioSystem::DEVICE_OUT_SPEAKER) { 524 LOGI("Routing audio to Speakerphone\n"); 525 sndDevice = SND_DEVICE_SPEAKER; 526 audProcess = (ADRC_ENABLE | EQ_ENABLE | RX_IIR_ENABLE); 527 } else { 528 LOGI("Routing audio to Handset\n"); 529 sndDevice = SND_DEVICE_HANDSET; 530 } 531 } 532 } 533 // if inputDevice == 0, restore output routing 534 } 535 536 if (sndDevice == -1) { 537 if (outputDevices & (outputDevices - 1)) { 538 if ((outputDevices & AudioSystem::DEVICE_OUT_SPEAKER) == 0) { 539 LOGW("Hardware does not support requested route combination (%#X)," 540 " picking closest possible route...", outputDevices); 541 } 542 } 543 544 if (outputDevices & 545 (AudioSystem::DEVICE_OUT_BLUETOOTH_SCO | AudioSystem::DEVICE_OUT_BLUETOOTH_SCO_HEADSET)) { 546 LOGI("Routing audio to Bluetooth PCM\n"); 547 sndDevice = SND_DEVICE_BT; 548 } else if (outputDevices & AudioSystem::DEVICE_OUT_BLUETOOTH_SCO_CARKIT) { 549 LOGI("Routing audio to Bluetooth PCM\n"); 550 sndDevice = SND_DEVICE_CARKIT; 551 } else if ((outputDevices & AudioSystem::DEVICE_OUT_WIRED_HEADSET) && 552 (outputDevices & AudioSystem::DEVICE_OUT_SPEAKER)) { 553 LOGI("Routing audio to Wired Headset and Speaker\n"); 554 sndDevice = SND_DEVICE_HEADSET_AND_SPEAKER; 555 audProcess = (ADRC_ENABLE | EQ_ENABLE | RX_IIR_ENABLE); 556 } else if (outputDevices & AudioSystem::DEVICE_OUT_WIRED_HEADPHONE) { 557 if (outputDevices & AudioSystem::DEVICE_OUT_SPEAKER) { 558 LOGI("Routing audio to No microphone Wired Headset and Speaker (%d,%x)\n", mMode, outputDevices); 559 sndDevice = SND_DEVICE_HEADSET_AND_SPEAKER; 560 audProcess = (ADRC_ENABLE | EQ_ENABLE | RX_IIR_ENABLE); 561 } else { 562 LOGI("Routing audio to No microphone Wired Headset (%d,%x)\n", mMode, outputDevices); 563 sndDevice = SND_DEVICE_NO_MIC_HEADSET; 564 } 565 } else if (outputDevices & AudioSystem::DEVICE_OUT_WIRED_HEADSET) { 566 LOGI("Routing audio to Wired Headset\n"); 567 sndDevice = SND_DEVICE_HEADSET; 568 } else if (outputDevices & AudioSystem::DEVICE_OUT_SPEAKER) { 569 LOGI("Routing audio to Speakerphone\n"); 570 sndDevice = SND_DEVICE_SPEAKER; 571 audProcess = (ADRC_ENABLE | EQ_ENABLE | RX_IIR_ENABLE); 572 } else { 573 LOGI("Routing audio to Handset\n"); 574 sndDevice = SND_DEVICE_HANDSET; 575 } 576 } 577 578 if (sndDevice != -1 && sndDevice != mCurSndDevice) { 579 ret = doAudioRouteOrMute(sndDevice); 580 if ((*msm72xx_enable_audpp) == 0 ) { 581 LOGE("Could not open msm72xx_enable_audpp()"); 582 } else { 583 msm72xx_enable_audpp(audProcess); 584 } 585 mCurSndDevice = sndDevice; 586 } 587 588 return ret; 589} 590 591status_t AudioHardware::checkMicMute() 592{ 593 Mutex::Autolock lock(mLock); 594 if (mMode != AudioSystem::MODE_IN_CALL) { 595 setMicMute_nosync(true); 596 } 597 598 return NO_ERROR; 599} 600 601status_t AudioHardware::dumpInternals(int fd, const Vector<String16>& args) 602{ 603 const size_t SIZE = 256; 604 char buffer[SIZE]; 605 String8 result; 606 result.append("AudioHardware::dumpInternals\n"); 607 snprintf(buffer, SIZE, "\tmInit: %s\n", mInit? "true": "false"); 608 result.append(buffer); 609 snprintf(buffer, SIZE, "\tmMicMute: %s\n", mMicMute? "true": "false"); 610 result.append(buffer); 611 snprintf(buffer, SIZE, "\tmBluetoothNrec: %s\n", mBluetoothNrec? "true": "false"); 612 result.append(buffer); 613 snprintf(buffer, SIZE, "\tmBluetoothId: %d\n", mBluetoothId); 614 result.append(buffer); 615 ::write(fd, result.string(), result.size()); 616 return NO_ERROR; 617} 618 619status_t AudioHardware::dump(int fd, const Vector<String16>& args) 620{ 621 dumpInternals(fd, args); 622 for (size_t index = 0; index < mInputs.size(); index++) { 623 mInputs[index]->dump(fd, args); 624 } 625 626 if (mOutput) { 627 mOutput->dump(fd, args); 628 } 629 return NO_ERROR; 630} 631 632uint32_t AudioHardware::getInputSampleRate(uint32_t sampleRate) 633{ 634 uint32_t i; 635 uint32_t prevDelta; 636 uint32_t delta; 637 638 for (i = 0, prevDelta = 0xFFFFFFFF; i < sizeof(inputSamplingRates)/sizeof(uint32_t); i++, prevDelta = delta) { 639 delta = abs(sampleRate - inputSamplingRates[i]); 640 if (delta > prevDelta) break; 641 } 642 // i is always > 0 here 643 return inputSamplingRates[i-1]; 644} 645 646// ---------------------------------------------------------------------------- 647 648AudioHardware::AudioStreamOutMSM72xx::AudioStreamOutMSM72xx() : 649 mHardware(0), mFd(-1), mStartCount(0), mRetryCount(0), mStandby(true), mDevices(0) 650{ 651} 652 653status_t AudioHardware::AudioStreamOutMSM72xx::set( 654 AudioHardware* hw, uint32_t devices, int *pFormat, uint32_t *pChannels, uint32_t *pRate) 655{ 656 int lFormat = pFormat ? *pFormat : 0; 657 uint32_t lChannels = pChannels ? *pChannels : 0; 658 uint32_t lRate = pRate ? *pRate : 0; 659 660 mHardware = hw; 661 662 // fix up defaults 663 if (lFormat == 0) lFormat = format(); 664 if (lChannels == 0) lChannels = channels(); 665 if (lRate == 0) lRate = sampleRate(); 666 667 // check values 668 if ((lFormat != format()) || 669 (lChannels != channels()) || 670 (lRate != sampleRate())) { 671 if (pFormat) *pFormat = format(); 672 if (pChannels) *pChannels = channels(); 673 if (pRate) *pRate = sampleRate(); 674 return BAD_VALUE; 675 } 676 677 if (pFormat) *pFormat = lFormat; 678 if (pChannels) *pChannels = lChannels; 679 if (pRate) *pRate = lRate; 680 681 mDevices = devices; 682 683 return NO_ERROR; 684} 685 686AudioHardware::AudioStreamOutMSM72xx::~AudioStreamOutMSM72xx() 687{ 688 if (mFd >= 0) close(mFd); 689} 690 691ssize_t AudioHardware::AudioStreamOutMSM72xx::write(const void* buffer, size_t bytes) 692{ 693 // LOGD("AudioStreamOutMSM72xx::write(%p, %u)", buffer, bytes); 694 status_t status = NO_INIT; 695 size_t count = bytes; 696 const uint8_t* p = static_cast<const uint8_t*>(buffer); 697 698 if (mStandby) { 699 700 // open driver 701 LOGV("open driver"); 702 status = ::open("/dev/msm_pcm_out", O_RDWR); 703 if (status < 0) { 704 LOGE("Cannot open /dev/msm_pcm_out errno: %d", errno); 705 goto Error; 706 } 707 mFd = status; 708 709 // configuration 710 LOGV("get config"); 711 struct msm_audio_config config; 712 status = ioctl(mFd, AUDIO_GET_CONFIG, &config); 713 if (status < 0) { 714 LOGE("Cannot read config"); 715 goto Error; 716 } 717 718 LOGV("set config"); 719 config.channel_count = AudioSystem::popCount(channels()); 720 config.sample_rate = sampleRate(); 721 config.buffer_size = bufferSize(); 722 config.buffer_count = AUDIO_HW_NUM_OUT_BUF; 723 config.codec_type = CODEC_TYPE_PCM; 724 status = ioctl(mFd, AUDIO_SET_CONFIG, &config); 725 if (status < 0) { 726 LOGE("Cannot set config"); 727 goto Error; 728 } 729 730 LOGV("buffer_size: %u", config.buffer_size); 731 LOGV("buffer_count: %u", config.buffer_count); 732 LOGV("channel_count: %u", config.channel_count); 733 LOGV("sample_rate: %u", config.sample_rate); 734 735 // fill 2 buffers before AUDIO_START 736 mStartCount = AUDIO_HW_NUM_OUT_BUF; 737 mStandby = false; 738 } 739 740 while (count) { 741 ssize_t written = ::write(mFd, p, count); 742 if (written >= 0) { 743 count -= written; 744 p += written; 745 } else { 746 if (errno != EAGAIN) return written; 747 mRetryCount++; 748 LOGW("EAGAIN - retry"); 749 } 750 } 751 752 // start audio after we fill 2 buffers 753 if (mStartCount) { 754 if (--mStartCount == 0) { 755 ioctl(mFd, AUDIO_START, 0); 756 } 757 } 758 return bytes; 759 760Error: 761 if (mFd >= 0) { 762 ::close(mFd); 763 mFd = -1; 764 } 765 // Simulate audio output timing in case of error 766 usleep(bytes * 1000000 / frameSize() / sampleRate()); 767 768 return status; 769} 770 771status_t AudioHardware::AudioStreamOutMSM72xx::standby() 772{ 773 status_t status = NO_ERROR; 774 if (!mStandby && mFd >= 0) { 775 ::close(mFd); 776 mFd = -1; 777 } 778 mStandby = true; 779 return status; 780} 781 782status_t AudioHardware::AudioStreamOutMSM72xx::dump(int fd, const Vector<String16>& args) 783{ 784 const size_t SIZE = 256; 785 char buffer[SIZE]; 786 String8 result; 787 result.append("AudioStreamOutMSM72xx::dump\n"); 788 snprintf(buffer, SIZE, "\tsample rate: %d\n", sampleRate()); 789 result.append(buffer); 790 snprintf(buffer, SIZE, "\tbuffer size: %d\n", bufferSize()); 791 result.append(buffer); 792 snprintf(buffer, SIZE, "\tchannels: %d\n", channels()); 793 result.append(buffer); 794 snprintf(buffer, SIZE, "\tformat: %d\n", format()); 795 result.append(buffer); 796 snprintf(buffer, SIZE, "\tmHardware: %p\n", mHardware); 797 result.append(buffer); 798 snprintf(buffer, SIZE, "\tmFd: %d\n", mFd); 799 result.append(buffer); 800 snprintf(buffer, SIZE, "\tmStartCount: %d\n", mStartCount); 801 result.append(buffer); 802 snprintf(buffer, SIZE, "\tmRetryCount: %d\n", mRetryCount); 803 result.append(buffer); 804 snprintf(buffer, SIZE, "\tmStandby: %s\n", mStandby? "true": "false"); 805 result.append(buffer); 806 ::write(fd, result.string(), result.size()); 807 return NO_ERROR; 808} 809 810bool AudioHardware::AudioStreamOutMSM72xx::checkStandby() 811{ 812 return mStandby; 813} 814 815 816status_t AudioHardware::AudioStreamOutMSM72xx::setParameters(const String8& keyValuePairs) 817{ 818 AudioParameter param = AudioParameter(keyValuePairs); 819 String8 key = String8(AudioParameter::keyRouting); 820 status_t status = NO_ERROR; 821 int device; 822 LOGV("AudioStreamOutMSM72xx::setParameters() %s", keyValuePairs.string()); 823 824 if (param.getInt(key, device) == NO_ERROR) { 825 mDevices = device; 826 LOGV("set output routing %x", mDevices); 827 status = mHardware->doRouting(NULL); 828 param.remove(key); 829 } 830 831 if (param.size()) { 832 status = BAD_VALUE; 833 } 834 return status; 835} 836 837String8 AudioHardware::AudioStreamOutMSM72xx::getParameters(const String8& keys) 838{ 839 AudioParameter param = AudioParameter(keys); 840 String8 value; 841 String8 key = String8(AudioParameter::keyRouting); 842 843 if (param.get(key, value) == NO_ERROR) { 844 LOGV("get routing %x", mDevices); 845 param.addInt(key, (int)mDevices); 846 } 847 848 LOGV("AudioStreamOutMSM72xx::getParameters() %s", param.toString().string()); 849 return param.toString(); 850} 851 852status_t AudioHardware::AudioStreamOutMSM72xx::getRenderPosition(uint32_t *dspFrames) 853{ 854 //TODO: enable when supported by driver 855 return INVALID_OPERATION; 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