1/* 2** Copyright 2008, The Android Open-Source Project 3** 4** Licensed under the Apache License, Version 2.0 (the "License"); 5** you may not use this file except in compliance with the License. 6** You may obtain a copy of the License at 7** 8** http://www.apache.org/licenses/LICENSE-2.0 9** 10** Unless required by applicable law or agreed to in writing, software 11** distributed under the License is distributed on an "AS IS" BASIS, 12** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13** See the License for the specific language governing permissions and 14** limitations under the License. 15*/ 16 17#include <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 ALOGE("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 ALOGE("Could not open set_acoustic_parameters()"); 84 return; 85 } 86 87 int rc = set_acoustic_parameters(); 88 if (rc < 0) { 89 ALOGE("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 ALOGE("Could not open snd_get_num()"); 96// return; 97 } 98 99 mNumSndEndpoints = snd_get_num(); 100 ALOGD("mNumSndEndpoints = %d", mNumSndEndpoints); 101 mSndEndpoints = new msm_snd_endpoint[mNumSndEndpoints]; 102 mInit = true; 103 ALOGV("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 ALOGE("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 ALOGD("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 ALOGW("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 ALOGW("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 clearCurDevice(); 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 ALOGV("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 ALOGI("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 ALOGI("Using custom acoustic parameters for %s", value.string()); 312 break; 313 } 314 } 315 if (mBluetoothId == 0) { 316 ALOGI("Using default acoustic parameters " 317 "(%s not in acoustic database)", value.string()); 318 doRouting(); 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 ALOGW("getInputBufferSize bad format: %d", format); 350 return 0; 351 } 352 if (channelCount < 1 || channelCount > 2) { 353 ALOGW("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 ALOGD("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 ALOGE("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 ALOGE("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 ALOGW("setVoiceVolume(%f) under 0.0, assuming 0.0\n", v); 403 v = 0.0; 404 } else if (v > 1.0) { 405 ALOGW("setVoiceVolume(%f) over 1.0, assuming 1.0\n", v); 406 v = 1.0; 407 } 408 409 int vol = lrint(v * 5.0); 410 ALOGD("setVoiceVolume(%f)\n", v); 411 ALOGI("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 ALOGI("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 ALOGD("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 ALOGE("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 ALOGE("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 ALOGV("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() 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 AudioStreamInMSM72xx *input = getActiveInput_l(); 504 uint32_t inputDevice = (input == NULL) ? 0 : input->devices(); 505 int sndDevice = -1; 506 507 if (inputDevice != 0) { 508 ALOGI("do input routing device %x\n", inputDevice); 509 if (inputDevice & AudioSystem::DEVICE_IN_BLUETOOTH_SCO_HEADSET) { 510 ALOGI("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 ALOGI("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 ALOGI("Routing audio to Wired Headset\n"); 520 sndDevice = SND_DEVICE_HEADSET; 521 } 522 } else { 523 if (outputDevices & AudioSystem::DEVICE_OUT_SPEAKER) { 524 ALOGI("Routing audio to Speakerphone\n"); 525 sndDevice = SND_DEVICE_SPEAKER; 526 audProcess = (ADRC_ENABLE | EQ_ENABLE | RX_IIR_ENABLE); 527 } else { 528 ALOGI("Routing audio to Handset\n"); 529 sndDevice = SND_DEVICE_HANDSET; 530 } 531 } 532 } 533 // if inputDevice == 0, restore output routing 534 535 if (sndDevice == -1) { 536 if (outputDevices & (outputDevices - 1)) { 537 if ((outputDevices & AudioSystem::DEVICE_OUT_SPEAKER) == 0) { 538 ALOGW("Hardware does not support requested route combination (%#X)," 539 " picking closest possible route...", outputDevices); 540 } 541 } 542 543 if (outputDevices & 544 (AudioSystem::DEVICE_OUT_BLUETOOTH_SCO | AudioSystem::DEVICE_OUT_BLUETOOTH_SCO_HEADSET)) { 545 ALOGI("Routing audio to Bluetooth PCM\n"); 546 sndDevice = SND_DEVICE_BT; 547 } else if (outputDevices & AudioSystem::DEVICE_OUT_BLUETOOTH_SCO_CARKIT) { 548 ALOGI("Routing audio to Bluetooth PCM\n"); 549 sndDevice = SND_DEVICE_CARKIT; 550 } else if ((outputDevices & AudioSystem::DEVICE_OUT_WIRED_HEADSET) && 551 (outputDevices & AudioSystem::DEVICE_OUT_SPEAKER)) { 552 ALOGI("Routing audio to Wired Headset and Speaker\n"); 553 sndDevice = SND_DEVICE_HEADSET_AND_SPEAKER; 554 audProcess = (ADRC_ENABLE | EQ_ENABLE | RX_IIR_ENABLE); 555 } else if (outputDevices & AudioSystem::DEVICE_OUT_WIRED_HEADPHONE) { 556 if (outputDevices & AudioSystem::DEVICE_OUT_SPEAKER) { 557 ALOGI("Routing audio to No microphone Wired Headset and Speaker (%d,%x)\n", mMode, outputDevices); 558 sndDevice = SND_DEVICE_HEADSET_AND_SPEAKER; 559 audProcess = (ADRC_ENABLE | EQ_ENABLE | RX_IIR_ENABLE); 560 } else { 561 ALOGI("Routing audio to No microphone Wired Headset (%d,%x)\n", mMode, outputDevices); 562 sndDevice = SND_DEVICE_NO_MIC_HEADSET; 563 } 564 } else if (outputDevices & AudioSystem::DEVICE_OUT_WIRED_HEADSET) { 565 ALOGI("Routing audio to Wired Headset\n"); 566 sndDevice = SND_DEVICE_HEADSET; 567 } else if (outputDevices & AudioSystem::DEVICE_OUT_SPEAKER) { 568 ALOGI("Routing audio to Speakerphone\n"); 569 sndDevice = SND_DEVICE_SPEAKER; 570 audProcess = (ADRC_ENABLE | EQ_ENABLE | RX_IIR_ENABLE); 571 } else { 572 ALOGI("Routing audio to Handset\n"); 573 sndDevice = SND_DEVICE_HANDSET; 574 } 575 } 576 577 if (sndDevice != -1 && sndDevice != mCurSndDevice) { 578 ret = doAudioRouteOrMute(sndDevice); 579 if ((*msm72xx_enable_audpp) == 0 ) { 580 ALOGE("Could not open msm72xx_enable_audpp()"); 581 } else { 582 msm72xx_enable_audpp(audProcess); 583 } 584 mCurSndDevice = sndDevice; 585 } 586 587 return ret; 588} 589 590status_t AudioHardware::checkMicMute() 591{ 592 Mutex::Autolock lock(mLock); 593 if (mMode != AudioSystem::MODE_IN_CALL) { 594 setMicMute_nosync(true); 595 } 596 597 return NO_ERROR; 598} 599 600status_t AudioHardware::dumpInternals(int fd, const Vector<String16>& args) 601{ 602 const size_t SIZE = 256; 603 char buffer[SIZE]; 604 String8 result; 605 result.append("AudioHardware::dumpInternals\n"); 606 snprintf(buffer, SIZE, "\tmInit: %s\n", mInit? "true": "false"); 607 result.append(buffer); 608 snprintf(buffer, SIZE, "\tmMicMute: %s\n", mMicMute? "true": "false"); 609 result.append(buffer); 610 snprintf(buffer, SIZE, "\tmBluetoothNrec: %s\n", mBluetoothNrec? "true": "false"); 611 result.append(buffer); 612 snprintf(buffer, SIZE, "\tmBluetoothId: %d\n", mBluetoothId); 613 result.append(buffer); 614 ::write(fd, result.string(), result.size()); 615 return NO_ERROR; 616} 617 618status_t AudioHardware::dump(int fd, const Vector<String16>& args) 619{ 620 dumpInternals(fd, args); 621 for (size_t index = 0; index < mInputs.size(); index++) { 622 mInputs[index]->dump(fd, args); 623 } 624 625 if (mOutput) { 626 mOutput->dump(fd, args); 627 } 628 return NO_ERROR; 629} 630 631uint32_t AudioHardware::getInputSampleRate(uint32_t sampleRate) 632{ 633 uint32_t i; 634 uint32_t prevDelta; 635 uint32_t delta; 636 637 for (i = 0, prevDelta = 0xFFFFFFFF; i < sizeof(inputSamplingRates)/sizeof(uint32_t); i++, prevDelta = delta) { 638 delta = abs(sampleRate - inputSamplingRates[i]); 639 if (delta > prevDelta) break; 640 } 641 // i is always > 0 here 642 return inputSamplingRates[i-1]; 643} 644 645// getActiveInput_l() must be called with mLock held 646AudioHardware::AudioStreamInMSM72xx *AudioHardware::getActiveInput_l() 647{ 648 for (size_t i = 0; i < mInputs.size(); i++) { 649 // return first input found not being in standby mode 650 // as only one input can be in this state 651 if (mInputs[i]->state() > AudioStreamInMSM72xx::AUDIO_INPUT_CLOSED) { 652 return mInputs[i]; 653 } 654 } 655 656 return NULL; 657} 658// ---------------------------------------------------------------------------- 659 660AudioHardware::AudioStreamOutMSM72xx::AudioStreamOutMSM72xx() : 661 mHardware(0), mFd(-1), mStartCount(0), mRetryCount(0), mStandby(true), mDevices(0) 662{ 663} 664 665status_t AudioHardware::AudioStreamOutMSM72xx::set( 666 AudioHardware* hw, uint32_t devices, int *pFormat, uint32_t *pChannels, uint32_t *pRate) 667{ 668 int lFormat = pFormat ? *pFormat : 0; 669 uint32_t lChannels = pChannels ? *pChannels : 0; 670 uint32_t lRate = pRate ? *pRate : 0; 671 672 mHardware = hw; 673 674 // fix up defaults 675 if (lFormat == 0) lFormat = format(); 676 if (lChannels == 0) lChannels = channels(); 677 if (lRate == 0) lRate = sampleRate(); 678 679 // check values 680 if ((lFormat != format()) || 681 (lChannels != channels()) || 682 (lRate != sampleRate())) { 683 if (pFormat) *pFormat = format(); 684 if (pChannels) *pChannels = channels(); 685 if (pRate) *pRate = sampleRate(); 686 return BAD_VALUE; 687 } 688 689 if (pFormat) *pFormat = lFormat; 690 if (pChannels) *pChannels = lChannels; 691 if (pRate) *pRate = lRate; 692 693 mDevices = devices; 694 695 return NO_ERROR; 696} 697 698AudioHardware::AudioStreamOutMSM72xx::~AudioStreamOutMSM72xx() 699{ 700 if (mFd >= 0) close(mFd); 701} 702 703ssize_t AudioHardware::AudioStreamOutMSM72xx::write(const void* buffer, size_t bytes) 704{ 705 // ALOGD("AudioStreamOutMSM72xx::write(%p, %u)", buffer, bytes); 706 status_t status = NO_INIT; 707 size_t count = bytes; 708 const uint8_t* p = static_cast<const uint8_t*>(buffer); 709 710 if (mStandby) { 711 712 // open driver 713 ALOGV("open driver"); 714 status = ::open("/dev/msm_pcm_out", O_RDWR); 715 if (status < 0) { 716 ALOGE("Cannot open /dev/msm_pcm_out errno: %d", errno); 717 goto Error; 718 } 719 mFd = status; 720 721 // configuration 722 ALOGV("get config"); 723 struct msm_audio_config config; 724 status = ioctl(mFd, AUDIO_GET_CONFIG, &config); 725 if (status < 0) { 726 ALOGE("Cannot read config"); 727 goto Error; 728 } 729 730 ALOGV("set config"); 731 config.channel_count = AudioSystem::popCount(channels()); 732 config.sample_rate = sampleRate(); 733 config.buffer_size = bufferSize(); 734 config.buffer_count = AUDIO_HW_NUM_OUT_BUF; 735 config.codec_type = CODEC_TYPE_PCM; 736 status = ioctl(mFd, AUDIO_SET_CONFIG, &config); 737 if (status < 0) { 738 ALOGE("Cannot set config"); 739 goto Error; 740 } 741 742 ALOGV("buffer_size: %u", config.buffer_size); 743 ALOGV("buffer_count: %u", config.buffer_count); 744 ALOGV("channel_count: %u", config.channel_count); 745 ALOGV("sample_rate: %u", config.sample_rate); 746 747 // fill 2 buffers before AUDIO_START 748 mStartCount = AUDIO_HW_NUM_OUT_BUF; 749 mStandby = false; 750 } 751 752 while (count) { 753 ssize_t written = ::write(mFd, p, count); 754 if (written >= 0) { 755 count -= written; 756 p += written; 757 } else { 758 if (errno != EAGAIN) return written; 759 mRetryCount++; 760 ALOGW("EAGAIN - retry"); 761 } 762 } 763 764 // start audio after we fill 2 buffers 765 if (mStartCount) { 766 if (--mStartCount == 0) { 767 ioctl(mFd, AUDIO_START, 0); 768 } 769 } 770 return bytes; 771 772Error: 773 if (mFd >= 0) { 774 ::close(mFd); 775 mFd = -1; 776 } 777 // Simulate audio output timing in case of error 778 usleep(bytes * 1000000 / frameSize() / sampleRate()); 779 780 return status; 781} 782 783status_t AudioHardware::AudioStreamOutMSM72xx::standby() 784{ 785 status_t status = NO_ERROR; 786 if (!mStandby && mFd >= 0) { 787 ::close(mFd); 788 mFd = -1; 789 } 790 mStandby = true; 791 return status; 792} 793 794status_t AudioHardware::AudioStreamOutMSM72xx::dump(int fd, const Vector<String16>& args) 795{ 796 const size_t SIZE = 256; 797 char buffer[SIZE]; 798 String8 result; 799 result.append("AudioStreamOutMSM72xx::dump\n"); 800 snprintf(buffer, SIZE, "\tsample rate: %d\n", sampleRate()); 801 result.append(buffer); 802 snprintf(buffer, SIZE, "\tbuffer size: %d\n", bufferSize()); 803 result.append(buffer); 804 snprintf(buffer, SIZE, "\tchannels: %d\n", channels()); 805 result.append(buffer); 806 snprintf(buffer, SIZE, "\tformat: %d\n", format()); 807 result.append(buffer); 808 snprintf(buffer, SIZE, "\tmHardware: %p\n", mHardware); 809 result.append(buffer); 810 snprintf(buffer, SIZE, "\tmFd: %d\n", mFd); 811 result.append(buffer); 812 snprintf(buffer, SIZE, "\tmStartCount: %d\n", mStartCount); 813 result.append(buffer); 814 snprintf(buffer, SIZE, "\tmRetryCount: %d\n", mRetryCount); 815 result.append(buffer); 816 snprintf(buffer, SIZE, "\tmStandby: %s\n", mStandby? "true": "false"); 817 result.append(buffer); 818 ::write(fd, result.string(), result.size()); 819 return NO_ERROR; 820} 821 822bool AudioHardware::AudioStreamOutMSM72xx::checkStandby() 823{ 824 return mStandby; 825} 826 827 828status_t AudioHardware::AudioStreamOutMSM72xx::setParameters(const String8& keyValuePairs) 829{ 830 AudioParameter param = AudioParameter(keyValuePairs); 831 String8 key = String8(AudioParameter::keyRouting); 832 status_t status = NO_ERROR; 833 int device; 834 ALOGV("AudioStreamOutMSM72xx::setParameters() %s", keyValuePairs.string()); 835 836 if (param.getInt(key, device) == NO_ERROR) { 837 mDevices = device; 838 ALOGV("set output routing %x", mDevices); 839 status = mHardware->doRouting(); 840 param.remove(key); 841 } 842 843 if (param.size()) { 844 status = BAD_VALUE; 845 } 846 return status; 847} 848 849String8 AudioHardware::AudioStreamOutMSM72xx::getParameters(const String8& keys) 850{ 851 AudioParameter param = AudioParameter(keys); 852 String8 value; 853 String8 key = String8(AudioParameter::keyRouting); 854 855 if (param.get(key, value) == NO_ERROR) { 856 ALOGV("get routing %x", mDevices); 857 param.addInt(key, (int)mDevices); 858 } 859 860 ALOGV("AudioStreamOutMSM72xx::getParameters() %s", param.toString().string()); 861 return param.toString(); 862} 863 864status_t AudioHardware::AudioStreamOutMSM72xx::getRenderPosition(uint32_t *dspFrames) 865{ 866 //TODO: enable when supported by driver 867 return INVALID_OPERATION; 868} 869 870// ---------------------------------------------------------------------------- 871 872AudioHardware::AudioStreamInMSM72xx::AudioStreamInMSM72xx() : 873 mHardware(0), mFd(-1), mState(AUDIO_INPUT_CLOSED), mRetryCount(0), 874 mFormat(AUDIO_HW_IN_FORMAT), mChannels(AUDIO_HW_IN_CHANNELS), 875 mSampleRate(AUDIO_HW_IN_SAMPLERATE), mBufferSize(AUDIO_HW_IN_BUFFERSIZE), 876 mAcoustics((AudioSystem::audio_in_acoustics)0), mDevices(0) 877{ 878} 879 880status_t AudioHardware::AudioStreamInMSM72xx::set( 881 AudioHardware* hw, uint32_t devices, int *pFormat, uint32_t *pChannels, uint32_t *pRate, 882 AudioSystem::audio_in_acoustics acoustic_flags) 883{ 884 if (pFormat == 0 || *pFormat != AUDIO_HW_IN_FORMAT) { 885 *pFormat = AUDIO_HW_IN_FORMAT; 886 return BAD_VALUE; 887 } 888 if (pRate == 0) { 889 return BAD_VALUE; 890 } 891 uint32_t rate = hw->getInputSampleRate(*pRate); 892 if (rate != *pRate) { 893 *pRate = rate; 894 return BAD_VALUE; 895 } 896 897 if (pChannels == 0 || (*pChannels != AudioSystem::CHANNEL_IN_MONO && 898 *pChannels != AudioSystem::CHANNEL_IN_STEREO)) { 899 *pChannels = AUDIO_HW_IN_CHANNELS; 900 return BAD_VALUE; 901 } 902 903 mHardware = hw; 904 905 ALOGV("AudioStreamInMSM72xx::set(%d, %d, %u)", *pFormat, *pChannels, *pRate); 906 if (mFd >= 0) { 907 ALOGE("Audio record already open"); 908 return -EPERM; 909 } 910 911 // open audio input device 912 status_t status = ::open("/dev/msm_pcm_in", O_RDWR); 913 if (status < 0) { 914 ALOGE("Cannot open /dev/msm_pcm_in errno: %d", errno); 915 goto Error; 916 } 917 mFd = status; 918 919 // configuration 920 ALOGV("get config"); 921 struct msm_audio_config config; 922 status = ioctl(mFd, AUDIO_GET_CONFIG, &config); 923 if (status < 0) { 924 ALOGE("Cannot read config"); 925 goto Error; 926 } 927 928 ALOGV("set config"); 929 config.channel_count = AudioSystem::popCount(*pChannels); 930 config.sample_rate = *pRate; 931 config.buffer_size = bufferSize(); 932 config.buffer_count = 2; 933 config.codec_type = CODEC_TYPE_PCM; 934 status = ioctl(mFd, AUDIO_SET_CONFIG, &config); 935 if (status < 0) { 936 ALOGE("Cannot set config"); 937 if (ioctl(mFd, AUDIO_GET_CONFIG, &config) == 0) { 938 if (config.channel_count == 1) { 939 *pChannels = AudioSystem::CHANNEL_IN_MONO; 940 } else { 941 *pChannels = AudioSystem::CHANNEL_IN_STEREO; 942 } 943 *pRate = config.sample_rate; 944 } 945 goto Error; 946 } 947 948 ALOGV("confirm config"); 949 status = ioctl(mFd, AUDIO_GET_CONFIG, &config); 950 if (status < 0) { 951 ALOGE("Cannot read config"); 952 goto Error; 953 } 954 ALOGV("buffer_size: %u", config.buffer_size); 955 ALOGV("buffer_count: %u", config.buffer_count); 956 ALOGV("channel_count: %u", config.channel_count); 957 ALOGV("sample_rate: %u", config.sample_rate); 958 959 mDevices = devices; 960 mFormat = AUDIO_HW_IN_FORMAT; 961 mChannels = *pChannels; 962 mSampleRate = config.sample_rate; 963 mBufferSize = config.buffer_size; 964 965 //mHardware->setMicMute_nosync(false); 966 mState = AUDIO_INPUT_OPENED; 967 968 if (!acoustic) 969 return NO_ERROR; 970 971 audpre_index = calculate_audpre_table_index(mSampleRate); 972 tx_iir_index = (audpre_index * 2) + (hw->checkOutputStandby() ? 0 : 1); 973 ALOGD("audpre_index = %d, tx_iir_index = %d\n", audpre_index, tx_iir_index); 974 975 /** 976 * If audio-preprocessing failed, we should not block record. 977 */ 978 int (*msm72xx_set_audpre_params)(int, int); 979 msm72xx_set_audpre_params = (int (*)(int, int))::dlsym(acoustic, "msm72xx_set_audpre_params"); 980 status = msm72xx_set_audpre_params(audpre_index, tx_iir_index); 981 if (status < 0) 982 ALOGE("Cannot set audpre parameters"); 983 984 int (*msm72xx_enable_audpre)(int, int, int); 985 msm72xx_enable_audpre = (int (*)(int, int, int))::dlsym(acoustic, "msm72xx_enable_audpre"); 986 mAcoustics = acoustic_flags; 987 status = msm72xx_enable_audpre((int)acoustic_flags, audpre_index, tx_iir_index); 988 if (status < 0) 989 ALOGE("Cannot enable audpre"); 990 991 return NO_ERROR; 992 993Error: 994 if (mFd >= 0) { 995 ::close(mFd); 996 mFd = -1; 997 } 998 return status; 999} 1000 1001AudioHardware::AudioStreamInMSM72xx::~AudioStreamInMSM72xx() 1002{ 1003 ALOGV("AudioStreamInMSM72xx destructor"); 1004 standby(); 1005} 1006 1007ssize_t AudioHardware::AudioStreamInMSM72xx::read( void* buffer, ssize_t bytes) 1008{ 1009 ALOGV("AudioStreamInMSM72xx::read(%p, %ld)", buffer, bytes); 1010 if (!mHardware) return -1; 1011 1012 size_t count = bytes; 1013 uint8_t* p = static_cast<uint8_t*>(buffer); 1014 1015 if (mState < AUDIO_INPUT_OPENED) { 1016 Mutex::Autolock lock(mHardware->mLock); 1017 if (set(mHardware, mDevices, &mFormat, &mChannels, &mSampleRate, mAcoustics) != NO_ERROR) { 1018 return -1; 1019 } 1020 } 1021 1022 if (mState < AUDIO_INPUT_STARTED) { 1023 mState = AUDIO_INPUT_STARTED; 1024 // force routing to input device 1025 mHardware->clearCurDevice(); 1026 mHardware->doRouting(); 1027 if (ioctl(mFd, AUDIO_START, 0)) { 1028 ALOGE("Error starting record"); 1029 standby(); 1030 return -1; 1031 } 1032 } 1033 1034 while (count) { 1035 ssize_t bytesRead = ::read(mFd, buffer, count); 1036 if (bytesRead >= 0) { 1037 count -= bytesRead; 1038 p += bytesRead; 1039 } else { 1040 if (errno != EAGAIN) return bytesRead; 1041 mRetryCount++; 1042 ALOGW("EAGAIN - retrying"); 1043 } 1044 } 1045 return bytes; 1046} 1047 1048status_t AudioHardware::AudioStreamInMSM72xx::standby() 1049{ 1050 if (mState > AUDIO_INPUT_CLOSED) { 1051 if (mFd >= 0) { 1052 ::close(mFd); 1053 mFd = -1; 1054 } 1055 mState = AUDIO_INPUT_CLOSED; 1056 } 1057 if (!mHardware) return -1; 1058 // restore output routing if necessary 1059 mHardware->clearCurDevice(); 1060 mHardware->doRouting(); 1061 return NO_ERROR; 1062} 1063 1064status_t AudioHardware::AudioStreamInMSM72xx::dump(int fd, const Vector<String16>& args) 1065{ 1066 const size_t SIZE = 256; 1067 char buffer[SIZE]; 1068 String8 result; 1069 result.append("AudioStreamInMSM72xx::dump\n"); 1070 snprintf(buffer, SIZE, "\tsample rate: %d\n", sampleRate()); 1071 result.append(buffer); 1072 snprintf(buffer, SIZE, "\tbuffer size: %d\n", bufferSize()); 1073 result.append(buffer); 1074 snprintf(buffer, SIZE, "\tchannels: %d\n", channels()); 1075 result.append(buffer); 1076 snprintf(buffer, SIZE, "\tformat: %d\n", format()); 1077 result.append(buffer); 1078 snprintf(buffer, SIZE, "\tmHardware: %p\n", mHardware); 1079 result.append(buffer); 1080 snprintf(buffer, SIZE, "\tmFd count: %d\n", mFd); 1081 result.append(buffer); 1082 snprintf(buffer, SIZE, "\tmState: %d\n", mState); 1083 result.append(buffer); 1084 snprintf(buffer, SIZE, "\tmRetryCount: %d\n", mRetryCount); 1085 result.append(buffer); 1086 ::write(fd, result.string(), result.size()); 1087 return NO_ERROR; 1088} 1089 1090status_t AudioHardware::AudioStreamInMSM72xx::setParameters(const String8& keyValuePairs) 1091{ 1092 AudioParameter param = AudioParameter(keyValuePairs); 1093 String8 key = String8(AudioParameter::keyRouting); 1094 status_t status = NO_ERROR; 1095 int device; 1096 ALOGV("AudioStreamInMSM72xx::setParameters() %s", keyValuePairs.string()); 1097 1098 if (param.getInt(key, device) == NO_ERROR) { 1099 ALOGV("set input routing %x", device); 1100 if (device & (device - 1)) { 1101 status = BAD_VALUE; 1102 } else { 1103 mDevices = device; 1104 status = mHardware->doRouting(); 1105 } 1106 param.remove(key); 1107 } 1108 1109 if (param.size()) { 1110 status = BAD_VALUE; 1111 } 1112 return status; 1113} 1114 1115String8 AudioHardware::AudioStreamInMSM72xx::getParameters(const String8& keys) 1116{ 1117 AudioParameter param = AudioParameter(keys); 1118 String8 value; 1119 String8 key = String8(AudioParameter::keyRouting); 1120 1121 if (param.get(key, value) == NO_ERROR) { 1122 ALOGV("get routing %x", mDevices); 1123 param.addInt(key, (int)mDevices); 1124 } 1125 1126 ALOGV("AudioStreamInMSM72xx::getParameters() %s", param.toString().string()); 1127 return param.toString(); 1128} 1129 1130// ---------------------------------------------------------------------------- 1131 1132extern "C" AudioHardwareInterface* createAudioHardware(void) { 1133 return new AudioHardware(); 1134} 1135 1136}; // namespace android 1137