AudioHardware.cpp revision 7510aaf4b3a3c545d943b09e0fb9f56ea2fc5e24
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 36#define LOG_SND_RPC 0 // Set to 1 to log sound RPC's 37 38namespace android { 39static int audpre_index, tx_iir_index; 40static void * acoustic; 41const uint32_t AudioHardware::inputSamplingRates[] = { 42 8000, 11025, 12000, 16000, 22050, 24000, 32000, 44100, 48000 43}; 44// ---------------------------------------------------------------------------- 45 46AudioHardware::AudioHardware() : 47 mInit(false), mMicMute(true), mBluetoothNrec(true), mBluetoothId(0), 48 mOutput(0), mInput(0), mSndEndpoints(NULL), 49 SND_DEVICE_CURRENT(-1), 50 SND_DEVICE_HANDSET(-1), 51 SND_DEVICE_SPEAKER(-1), 52 SND_DEVICE_BT(-1), 53 SND_DEVICE_BT_EC_OFF(-1), 54 SND_DEVICE_HEADSET(-1), 55 SND_DEVICE_HEADSET_AND_SPEAKER(-1) 56{ 57 58 int (*snd_get_num)(); 59 int (*snd_get_endpoint)(int, msm_snd_endpoint *); 60 int (*set_acoustic_parameters)(); 61 62 struct msm_snd_endpoint *ept; 63 64 acoustic = ::dlopen("/system/lib/libhtc_acoustic.so", RTLD_NOW); 65 if (acoustic == NULL ) { 66 LOGE("Could not open libhtc_acoustic.so"); 67 return; 68 } 69 70 set_acoustic_parameters = (int (*)(void))::dlsym(acoustic, "set_acoustic_parameters"); 71 if ((*set_acoustic_parameters) == 0 ) { 72 LOGE("Could not open set_acoustic_parameters()"); 73 return; 74 } 75 76 int rc = set_acoustic_parameters(); 77 if (rc < 0) { 78 LOGE("Could not set acoustic parameters to share memory: %d", rc); 79// return; 80 } 81 82 snd_get_num = (int (*)(void))::dlsym(acoustic, "snd_get_num_endpoints"); 83 if ((*snd_get_num) == 0 ) { 84 LOGE("Could not open snd_get_num()"); 85// return; 86 } 87 88 mNumSndEndpoints = snd_get_num(); 89 LOGD("mNumSndEndpoints = %d", mNumSndEndpoints); 90 mSndEndpoints = new msm_snd_endpoint[mNumSndEndpoints]; 91 mInit = true; 92 LOGV("constructed %d SND endpoints)", mNumSndEndpoints); 93 ept = mSndEndpoints; 94 snd_get_endpoint = (int (*)(int, msm_snd_endpoint *))::dlsym(acoustic, "snd_get_endpoint"); 95 if ((*snd_get_endpoint) == 0 ) { 96 LOGE("Could not open snd_get_endpoint()"); 97 return; 98 } 99 100 for (int cnt = 0; cnt < mNumSndEndpoints; cnt++, ept++) { 101 ept->id = cnt; 102 snd_get_endpoint(cnt, ept); 103#define CHECK_FOR(desc) \ 104 if (!strcmp(ept->name, #desc)) { \ 105 SND_DEVICE_##desc = ept->id; \ 106 LOGD("BT MATCH " #desc); \ 107 } else 108 CHECK_FOR(CURRENT) 109 CHECK_FOR(HANDSET) 110 CHECK_FOR(SPEAKER) 111 CHECK_FOR(BT) 112 CHECK_FOR(BT_EC_OFF) 113 CHECK_FOR(HEADSET) 114 CHECK_FOR(HEADSET_AND_SPEAKER) {} 115#undef CHECK_FOR 116 } 117} 118 119AudioHardware::~AudioHardware() 120{ 121 delete mInput; 122 delete mOutput; 123 delete [] mSndEndpoints; 124 ::dlclose(acoustic); 125 mInit = false; 126} 127 128status_t AudioHardware::initCheck() 129{ 130 return mInit ? NO_ERROR : NO_INIT; 131} 132 133AudioStreamOut* AudioHardware::openOutputStream( 134 int format, int channelCount, uint32_t sampleRate, status_t *status) 135{ 136 Mutex::Autolock lock(mLock); 137 138 // only one output stream allowed 139 if (mOutput) { 140 if (status) { 141 *status = INVALID_OPERATION; 142 } 143 return 0; 144 } 145 146 // create new output stream 147 AudioStreamOutMSM72xx* out = new AudioStreamOutMSM72xx(); 148 status_t lStatus = out->set(this, format, channelCount, sampleRate); 149 if (status) { 150 *status = lStatus; 151 } 152 if (lStatus == NO_ERROR) { 153 mOutput = out; 154 } else { 155 delete out; 156 } 157 return mOutput; 158} 159 160void AudioHardware::closeOutputStream(AudioStreamOutMSM72xx* out) { 161 Mutex::Autolock lock(mLock); 162 if (mOutput != out) { 163 LOGW("Attempt to close invalid output stream"); 164 } 165 else { 166 mOutput = 0; 167 } 168} 169 170AudioStreamIn* AudioHardware::openInputStream( 171 int format, int channelCount, uint32_t sampleRate, status_t *status, 172 AudioSystem::audio_in_acoustics acoustic_flags) 173{ 174 mLock.lock(); 175 // input stream already open? 176 if (mInput) { 177 if (status) { 178 *status = INVALID_OPERATION; 179 } 180 mLock.unlock(); 181 return 0; 182 } 183 184 AudioStreamInMSM72xx* in = new AudioStreamInMSM72xx(); 185 status_t lStatus = in->set(this, format, channelCount, sampleRate, acoustic_flags); 186 if (status) { 187 *status = lStatus; 188 } 189 if (lStatus != NO_ERROR) { 190 mLock.unlock(); 191 delete in; 192 return 0; 193 } 194 195 mInput = in; 196 mLock.unlock(); 197 198 return mInput; 199} 200 201void AudioHardware::closeInputStream(AudioStreamInMSM72xx* in) { 202 Mutex::Autolock lock(mLock); 203 if (mInput != in) { 204 LOGW("Attempt to close invalid input stream"); 205 } 206 else { 207 mInput = 0; 208 } 209} 210 211bool AudioHardware::checkOutputStandby() 212{ 213 if (mOutput) 214 if (!mOutput->checkStandby()) 215 return false; 216 217 return true; 218} 219 220status_t AudioHardware::setMicMute(bool state) 221{ 222 Mutex::Autolock lock(mLock); 223 return setMicMute_nosync(state); 224} 225 226// always call with mutex held 227status_t AudioHardware::setMicMute_nosync(bool state) 228{ 229 if (mMicMute != state) { 230 mMicMute = state; 231 return doAudioRouteOrMute(SND_DEVICE_CURRENT); 232 } 233 return NO_ERROR; 234} 235 236status_t AudioHardware::getMicMute(bool* state) 237{ 238 *state = mMicMute; 239 return NO_ERROR; 240} 241 242status_t AudioHardware::setParameter(const char *key, const char *value) 243{ 244 LOGV("%s key = %s value = %s\n", __FUNCTION__, key, value); 245 246 if (key == NULL || value == NULL) { 247 LOGE("%s called with null argument, ignoring (key = %s, value = %s", 248 __FUNCTION__, key, value); 249 return BAD_VALUE; 250 } 251 252 const char BT_NREC_KEY[] = "bt_headset_nrec"; 253 const char BT_NAME_KEY[] = "bt_headset_name"; 254 const char BT_NREC_VALUE_ON[] = "on"; 255 256 if (!strncmp(key, BT_NREC_KEY, sizeof(BT_NREC_KEY))) { 257 if (!strncmp(value, BT_NREC_VALUE_ON, sizeof(BT_NREC_VALUE_ON))) { 258 mBluetoothNrec = true; 259 } else { 260 mBluetoothNrec = false; 261 LOGI("Turning noise reduction and echo cancellation off for BT " 262 "headset"); 263 } 264 doRouting(); 265 } else if (!strncmp(key, BT_NAME_KEY, sizeof(BT_NAME_KEY))) { 266 mBluetoothId = 0; 267 for (int i = 0; i < mNumSndEndpoints; i++) { 268 if (!strcasecmp(value, mSndEndpoints[i].name)) { 269 mBluetoothId = mSndEndpoints[i].id; 270 LOGI("Using custom acoustic parameters for %s", value); 271 break; 272 } 273 } 274 if (mBluetoothId == 0) { 275 LOGI("Using default acoustic parameters " 276 "(%s not in acoustic database)", value); 277 doRouting(); 278 } 279 } 280 281 return NO_ERROR; 282} 283static unsigned calculate_audpre_table_index(unsigned index) 284{ 285 switch (index) { 286 case 48000: return SAMP_RATE_INDX_48000; 287 case 44100: return SAMP_RATE_INDX_44100; 288 case 32000: return SAMP_RATE_INDX_32000; 289 case 24000: return SAMP_RATE_INDX_24000; 290 case 22050: return SAMP_RATE_INDX_22050; 291 case 16000: return SAMP_RATE_INDX_16000; 292 case 12000: return SAMP_RATE_INDX_12000; 293 case 11025: return SAMP_RATE_INDX_11025; 294 case 8000: return SAMP_RATE_INDX_8000; 295 default: return -1; 296 } 297} 298size_t AudioHardware::getInputBufferSize(uint32_t sampleRate, int format, int channelCount) 299{ 300 if (checkInputSampleRate(sampleRate) != NO_ERROR) { 301 LOGW("getInputBufferSize bad sampling rate: %d", sampleRate); 302 return 0; 303 } 304 if (format != AudioSystem::PCM_16_BIT) { 305 LOGW("getInputBufferSize bad format: %d", format); 306 return 0; 307 } 308 if (channelCount < 1 || channelCount > 2) { 309 LOGW("getInputBufferSize bad channel count: %d", channelCount); 310 return 0; 311 } 312 313 return 2048*channelCount; 314} 315 316static status_t set_volume_rpc(uint32_t device, 317 uint32_t method, 318 uint32_t volume) 319{ 320 int fd; 321#if LOG_SND_RPC 322 LOGD("rpc_snd_set_volume(%d, %d, %d)\n", device, method, volume); 323#endif 324 325 if (device == -1UL) return NO_ERROR; 326 327 fd = open("/dev/msm_snd", O_RDWR); 328 if (fd < 0) { 329 LOGE("Can not open snd device"); 330 return -EPERM; 331 } 332 /* rpc_snd_set_volume( 333 * device, # Any hardware device enum, including 334 * # SND_DEVICE_CURRENT 335 * method, # must be SND_METHOD_VOICE to do anything useful 336 * volume, # integer volume level, in range [0,5]. 337 * # note that 0 is audible (not quite muted) 338 * ) 339 * rpc_snd_set_volume only works for in-call sound volume. 340 */ 341 struct msm_snd_volume_config args; 342 args.device = device; 343 args.method = method; 344 args.volume = volume; 345 346 if (ioctl(fd, SND_SET_VOLUME, &args) < 0) { 347 LOGE("snd_set_volume error."); 348 close(fd); 349 return -EIO; 350 } 351 close(fd); 352 return NO_ERROR; 353} 354 355status_t AudioHardware::setVoiceVolume(float v) 356{ 357 if (v < 0.0) { 358 LOGW("setVoiceVolume(%f) under 0.0, assuming 0.0\n", v); 359 v = 0.0; 360 } else if (v > 1.0) { 361 LOGW("setVoiceVolume(%f) over 1.0, assuming 1.0\n", v); 362 v = 1.0; 363 } 364 365 int vol = lrint(v * 5.0); 366 LOGD("setVoiceVolume(%f)\n", v); 367 LOGI("Setting in-call volume to %d (available range is 0 to 5)\n", vol); 368 369 set_volume_rpc(SND_DEVICE_CURRENT, SND_METHOD_VOICE, vol); 370 return NO_ERROR; 371} 372 373status_t AudioHardware::setMasterVolume(float v) 374{ 375 Mutex::Autolock lock(mLock); 376 int vol = ceil(v * 5.0); 377 LOGI("Set master volume to %d.\n", vol); 378 set_volume_rpc(SND_DEVICE_HANDSET, SND_METHOD_VOICE, vol); 379 set_volume_rpc(SND_DEVICE_SPEAKER, SND_METHOD_VOICE, vol); 380 set_volume_rpc(SND_DEVICE_BT, SND_METHOD_VOICE, vol); 381 set_volume_rpc(SND_DEVICE_HEADSET, SND_METHOD_VOICE, vol); 382 // We return an error code here to let the audioflinger do in-software 383 // volume on top of the maximum volume that we set through the SND API. 384 // return error - software mixer will handle it 385 return -1; 386} 387 388static status_t do_route_audio_rpc(uint32_t device, 389 bool ear_mute, bool mic_mute) 390{ 391 if (device == -1UL) 392 return NO_ERROR; 393 394 int fd; 395#if LOG_SND_RPC 396 LOGD("rpc_snd_set_device(%d, %d, %d)\n", device, ear_mute, mic_mute); 397#endif 398 399 fd = open("/dev/msm_snd", O_RDWR); 400 if (fd < 0) { 401 LOGE("Can not open snd device"); 402 return -EPERM; 403 } 404 // RPC call to switch audio path 405 /* rpc_snd_set_device( 406 * device, # Hardware device enum to use 407 * ear_mute, # Set mute for outgoing voice audio 408 * # this should only be unmuted when in-call 409 * mic_mute, # Set mute for incoming voice audio 410 * # this should only be unmuted when in-call or 411 * # recording. 412 * ) 413 */ 414 struct msm_snd_device_config args; 415 args.device = device; 416 args.ear_mute = ear_mute ? SND_MUTE_MUTED : SND_MUTE_UNMUTED; 417 args.mic_mute = mic_mute ? SND_MUTE_MUTED : SND_MUTE_UNMUTED; 418 419 if (ioctl(fd, SND_SET_DEVICE, &args) < 0) { 420 LOGE("snd_set_device error."); 421 close(fd); 422 return -EIO; 423 } 424 425 close(fd); 426 return NO_ERROR; 427} 428 429// always call with mutex held 430status_t AudioHardware::doAudioRouteOrMute(uint32_t device) 431{ 432 if (device == (uint32_t)SND_DEVICE_BT) { 433 if (mBluetoothId) { 434 device = mBluetoothId; 435 } else if (!mBluetoothNrec) { 436 device = SND_DEVICE_BT_EC_OFF; 437 } 438 } 439 return do_route_audio_rpc(device, 440 mMode != AudioSystem::MODE_IN_CALL, mMicMute); 441} 442 443static int count_bits(uint32_t vector) 444{ 445 int bits; 446 for (bits = 0; vector; bits++) { 447 vector &= vector - 1; 448 } 449 return bits; 450} 451 452status_t AudioHardware::doRouting() 453{ 454 Mutex::Autolock lock(mLock); 455 uint32_t routes = mRoutes[mMode]; 456 if (count_bits(routes) > 1) { 457 if (routes != 458 (AudioSystem::ROUTE_HEADSET | AudioSystem::ROUTE_SPEAKER)) { 459 LOGW("Hardware does not support requested route combination (%#X)," 460 " picking closest possible route...", routes); 461 } 462 } 463 int (*msm72xx_enable_audpp)(int); 464 msm72xx_enable_audpp = (int (*)(int))::dlsym(acoustic, "msm72xx_enable_audpp"); 465 status_t ret = NO_ERROR; 466 if (routes & AudioSystem::ROUTE_BLUETOOTH_SCO) { 467 LOGI("Routing audio to Bluetooth PCM\n"); 468 ret = doAudioRouteOrMute(SND_DEVICE_BT); 469 msm72xx_enable_audpp(ADRC_DISABLE | EQ_DISABLE | RX_IIR_DISABLE); 470 } else if ((routes & AudioSystem::ROUTE_HEADSET) && 471 (routes & AudioSystem::ROUTE_SPEAKER)) { 472 LOGI("Routing audio to Wired Headset and Speaker\n"); 473 ret = doAudioRouteOrMute(SND_DEVICE_HEADSET_AND_SPEAKER); 474 msm72xx_enable_audpp(ADRC_ENABLE | EQ_ENABLE | RX_IIR_ENABLE); 475 } else if (routes & AudioSystem::ROUTE_HEADSET) { 476 LOGI("Routing audio to Wired Headset\n"); 477 ret = doAudioRouteOrMute(SND_DEVICE_HEADSET); 478 msm72xx_enable_audpp(ADRC_DISABLE | EQ_DISABLE | RX_IIR_DISABLE); 479 } else if (routes & AudioSystem::ROUTE_SPEAKER) { 480 LOGI("Routing audio to Speakerphone\n"); 481 ret = doAudioRouteOrMute(SND_DEVICE_SPEAKER); 482 msm72xx_enable_audpp(ADRC_ENABLE | EQ_ENABLE | RX_IIR_ENABLE); 483 } else { 484 LOGI("Routing audio to Handset\n"); 485 ret = doAudioRouteOrMute(SND_DEVICE_HANDSET); 486 msm72xx_enable_audpp(ADRC_DISABLE | EQ_DISABLE | RX_IIR_DISABLE); 487 } 488 489 return ret; 490} 491 492status_t AudioHardware::checkMicMute() 493{ 494 Mutex::Autolock lock(mLock); 495 if (mMode != AudioSystem::MODE_IN_CALL) { 496 setMicMute_nosync(true); 497 } 498 499 return NO_ERROR; 500} 501 502status_t AudioHardware::dumpInternals(int fd, const Vector<String16>& args) 503{ 504 const size_t SIZE = 256; 505 char buffer[SIZE]; 506 String8 result; 507 result.append("AudioHardware::dumpInternals\n"); 508 snprintf(buffer, SIZE, "\tmInit: %s\n", mInit? "true": "false"); 509 result.append(buffer); 510 snprintf(buffer, SIZE, "\tmMicMute: %s\n", mMicMute? "true": "false"); 511 result.append(buffer); 512 snprintf(buffer, SIZE, "\tmBluetoothNrec: %s\n", mBluetoothNrec? "true": "false"); 513 result.append(buffer); 514 snprintf(buffer, SIZE, "\tmBluetoothId: %d\n", mBluetoothId); 515 result.append(buffer); 516 ::write(fd, result.string(), result.size()); 517 return NO_ERROR; 518} 519 520status_t AudioHardware::dump(int fd, const Vector<String16>& args) 521{ 522 dumpInternals(fd, args); 523 if (mInput) { 524 mInput->dump(fd, args); 525 } 526 if (mOutput) { 527 mOutput->dump(fd, args); 528 } 529 return NO_ERROR; 530} 531 532status_t AudioHardware::checkInputSampleRate(uint32_t sampleRate) 533{ 534 for (uint32_t i = 0; i < sizeof(inputSamplingRates)/sizeof(uint32_t); i++) { 535 if (sampleRate == inputSamplingRates[i]) { 536 return NO_ERROR; 537 } 538 } 539 return BAD_VALUE; 540} 541 542// ---------------------------------------------------------------------------- 543 544AudioHardware::AudioStreamOutMSM72xx::AudioStreamOutMSM72xx() : 545 mHardware(0), mFd(-1), mStartCount(0), mRetryCount(0), mStandby(true) 546{ 547} 548 549status_t AudioHardware::AudioStreamOutMSM72xx::set( 550 AudioHardware* hw, int format, int channels, uint32_t rate) 551{ 552 // fix up defaults 553 if (format == 0) format = AudioSystem::PCM_16_BIT; 554 if (channels == 0) channels = channelCount(); 555 if (rate == 0) rate = sampleRate(); 556 557 // check values 558 if ((format != AudioSystem::PCM_16_BIT) || 559 (channels != channelCount()) || 560 (rate != sampleRate())) 561 return BAD_VALUE; 562 563 mHardware = hw; 564 565 return NO_ERROR; 566} 567 568AudioHardware::AudioStreamOutMSM72xx::~AudioStreamOutMSM72xx() 569{ 570 if (mFd > 0) close(mFd); 571 mHardware->closeOutputStream(this); 572} 573 574ssize_t AudioHardware::AudioStreamOutMSM72xx::write(const void* buffer, size_t bytes) 575{ 576 // LOGD("AudioStreamOutMSM72xx::write(%p, %u)", buffer, bytes); 577 status_t status = NO_INIT; 578 size_t count = bytes; 579 const uint8_t* p = static_cast<const uint8_t*>(buffer); 580 581 if (mStandby) { 582 583 // open driver 584 LOGV("open driver"); 585 status = ::open("/dev/msm_pcm_out", O_RDWR); 586 if (status < 0) { 587 LOGE("Cannot open /dev/msm_pcm_out errno: %d", errno); 588 goto Error; 589 } 590 mFd = status; 591 592 // configuration 593 LOGV("get config"); 594 struct msm_audio_config config; 595 status = ioctl(mFd, AUDIO_GET_CONFIG, &config); 596 if (status < 0) { 597 LOGE("Cannot read config"); 598 goto Error; 599 } 600 601 LOGV("set config"); 602 config.channel_count = channelCount(); 603 config.sample_rate = sampleRate(); 604 config.buffer_size = bufferSize(); 605 config.buffer_count = AUDIO_HW_NUM_OUT_BUF; 606 config.codec_type = CODEC_TYPE_PCM; 607 status = ioctl(mFd, AUDIO_SET_CONFIG, &config); 608 if (status < 0) { 609 LOGE("Cannot set config"); 610 goto Error; 611 } 612 613 LOGV("buffer_size: %u", config.buffer_size); 614 LOGV("buffer_count: %u", config.buffer_count); 615 LOGV("channel_count: %u", config.channel_count); 616 LOGV("sample_rate: %u", config.sample_rate); 617 618 // fill 2 buffers before AUDIO_START 619 mStartCount = AUDIO_HW_NUM_OUT_BUF; 620 mStandby = false; 621 } 622 623 while (count) { 624 ssize_t written = ::write(mFd, p, count); 625 if (written >= 0) { 626 count -= written; 627 p += written; 628 } else { 629 if (errno != EAGAIN) return written; 630 mRetryCount++; 631 LOGW("EAGAIN - retry"); 632 } 633 } 634 635 // start audio after we fill 2 buffers 636 if (mStartCount) { 637 if (--mStartCount == 0) { 638 ioctl(mFd, AUDIO_START, 0); 639 } 640 } 641 return bytes; 642 643Error: 644 if (mFd > 0) { 645 ::close(mFd); 646 mFd = -1; 647 } 648 // Simulate audio output timing in case of error 649 usleep(bytes * 1000000 / frameSize() / sampleRate()); 650 651 return status; 652} 653 654status_t AudioHardware::AudioStreamOutMSM72xx::standby() 655{ 656 status_t status = NO_ERROR; 657 if (!mStandby && mFd > 0) { 658 ::close(mFd); 659 mFd = -1; 660 } 661 mStandby = true; 662 return status; 663} 664 665status_t AudioHardware::AudioStreamOutMSM72xx::dump(int fd, const Vector<String16>& args) 666{ 667 const size_t SIZE = 256; 668 char buffer[SIZE]; 669 String8 result; 670 result.append("AudioStreamOutMSM72xx::dump\n"); 671 snprintf(buffer, SIZE, "\tsample rate: %d\n", sampleRate()); 672 result.append(buffer); 673 snprintf(buffer, SIZE, "\tbuffer size: %d\n", bufferSize()); 674 result.append(buffer); 675 snprintf(buffer, SIZE, "\tchannel count: %d\n", channelCount()); 676 result.append(buffer); 677 snprintf(buffer, SIZE, "\tformat: %d\n", format()); 678 result.append(buffer); 679 snprintf(buffer, SIZE, "\tmHardware: %p\n", mHardware); 680 result.append(buffer); 681 snprintf(buffer, SIZE, "\tmFd: %d\n", mFd); 682 result.append(buffer); 683 snprintf(buffer, SIZE, "\tmStartCount: %d\n", mStartCount); 684 result.append(buffer); 685 snprintf(buffer, SIZE, "\tmRetryCount: %d\n", mRetryCount); 686 result.append(buffer); 687 snprintf(buffer, SIZE, "\tmStandby: %s\n", mStandby? "true": "false"); 688 result.append(buffer); 689 ::write(fd, result.string(), result.size()); 690 return NO_ERROR; 691} 692 693bool AudioHardware::AudioStreamOutMSM72xx::checkStandby() 694{ 695 return mStandby; 696} 697 698// ---------------------------------------------------------------------------- 699 700AudioHardware::AudioStreamInMSM72xx::AudioStreamInMSM72xx() : 701 mHardware(0), mFd(-1), mState(AUDIO_INPUT_CLOSED), mRetryCount(0), 702 mFormat(AUDIO_HW_IN_FORMAT), mChannelCount(AUDIO_HW_IN_CHANNELS), 703 mSampleRate(AUDIO_HW_IN_SAMPLERATE), mBufferSize(AUDIO_HW_IN_BUFFERSIZE), 704 mAcoustics((AudioSystem::audio_in_acoustics)0) 705{ 706} 707 708status_t AudioHardware::AudioStreamInMSM72xx::set( 709 AudioHardware* hw, int format, int channelCount, uint32_t sampleRate, 710 AudioSystem::audio_in_acoustics acoustic_flags) 711{ 712 LOGV("AudioStreamInMSM72xx::set(%d, %d, %u)", format, channelCount, sampleRate); 713 if (mFd >= 0) { 714 LOGE("Audio record already open"); 715 return -EPERM; 716 } 717 718 // open audio input device 719 status_t status = ::open("/dev/msm_pcm_in", O_RDWR); 720 if (status < 0) { 721 LOGE("Cannot open /dev/msm_pcm_in errno: %d", errno); 722 goto Error; 723 } 724 mFd = status; 725 726 // configuration 727 LOGV("get config"); 728 struct msm_audio_config config; 729 status = ioctl(mFd, AUDIO_GET_CONFIG, &config); 730 if (status < 0) { 731 LOGE("Cannot read config"); 732 goto Error; 733 } 734 735 LOGV("set config"); 736 config.channel_count = channelCount; 737 config.sample_rate = sampleRate; 738 config.buffer_size = bufferSize(); 739 config.buffer_count = 2; 740 config.codec_type = CODEC_TYPE_PCM; 741 status = ioctl(mFd, AUDIO_SET_CONFIG, &config); 742 if (status < 0) { 743 LOGE("Cannot set config"); 744 goto Error; 745 } 746 747 LOGV("confirm config"); 748 status = ioctl(mFd, AUDIO_GET_CONFIG, &config); 749 if (status < 0) { 750 LOGE("Cannot read config"); 751 goto Error; 752 } 753 LOGV("buffer_size: %u", config.buffer_size); 754 LOGV("buffer_count: %u", config.buffer_count); 755 LOGV("channel_count: %u", config.channel_count); 756 LOGV("sample_rate: %u", config.sample_rate); 757 758 mFormat = format; 759 mChannelCount = config.channel_count; 760 mSampleRate = config.sample_rate; 761 mBufferSize = config.buffer_size; 762 763 mHardware = hw; 764 mHardware->setMicMute_nosync(false); 765 mState = AUDIO_INPUT_OPENED; 766 audpre_index = calculate_audpre_table_index(sampleRate); 767 tx_iir_index = (audpre_index * 2) + (hw->checkOutputStandby() ? 0 : 1); 768 LOGD("audpre_index = %d, tx_iir_index = %d\n", audpre_index, tx_iir_index); 769 770 /** 771 * If audio-preprocessing failed, we should not block record. 772 */ 773 int (*msm72xx_set_audpre_params)(int, int); 774 msm72xx_set_audpre_params = (int (*)(int, int))::dlsym(acoustic, "msm72xx_set_audpre_params"); 775 status = msm72xx_set_audpre_params(audpre_index, tx_iir_index); 776 if (status < 0) 777 LOGE("Cannot set audpre parameters"); 778 779 int (*msm72xx_enable_audpre)(int, int, int); 780 msm72xx_enable_audpre = (int (*)(int, int, int))::dlsym(acoustic, "msm72xx_enable_audpre"); 781 mAcoustics = acoustic_flags; 782 status = msm72xx_enable_audpre((int)acoustic_flags, audpre_index, tx_iir_index); 783 if (status < 0) 784 LOGE("Cannot enable audpre"); 785 786 return NO_ERROR; 787 788Error: 789 if (mFd > 0) { 790 ::close(mFd); 791 mFd = -1; 792 } 793 return status; 794} 795 796AudioHardware::AudioStreamInMSM72xx::~AudioStreamInMSM72xx() 797{ 798 LOGV("AudioStreamInMSM72xx destructor"); 799 if (mHardware) { 800 standby(); 801 mHardware->closeInputStream(this); 802 } 803} 804 805ssize_t AudioHardware::AudioStreamInMSM72xx::read( void* buffer, ssize_t bytes) 806{ 807 LOGV("AudioStreamInMSM72xx::read(%p, %u)", buffer, bytes); 808 if (!mHardware) return -1; 809 810 size_t count = bytes; 811 uint8_t* p = static_cast<uint8_t*>(buffer); 812 813 if (mState < AUDIO_INPUT_OPENED) { 814 if (set(mHardware, mFormat, mChannelCount, mSampleRate, mAcoustics) != NO_ERROR) { 815 return -1; 816 } 817 } 818 819 if (mState < AUDIO_INPUT_STARTED) { 820 if (ioctl(mFd, AUDIO_START, 0)) { 821 LOGE("Error starting record"); 822 return -1; 823 } 824 mState = AUDIO_INPUT_STARTED; 825 } 826 827 while (count) { 828 ssize_t bytesRead = ::read(mFd, buffer, count); 829 if (bytesRead >= 0) { 830 count -= bytesRead; 831 p += bytesRead; 832 } else { 833 if (errno != EAGAIN) return bytesRead; 834 mRetryCount++; 835 LOGW("EAGAIN - retrying"); 836 } 837 } 838 return bytes; 839} 840 841status_t AudioHardware::AudioStreamInMSM72xx::standby() 842{ 843 if (!mHardware) return -1; 844 if (mState > AUDIO_INPUT_CLOSED) { 845 if (mFd > 0) { 846 ::close(mFd); 847 mFd = -1; 848 } 849 mHardware->checkMicMute(); 850 mState = AUDIO_INPUT_CLOSED; 851 } 852 return NO_ERROR; 853} 854 855status_t AudioHardware::AudioStreamInMSM72xx::dump(int fd, const Vector<String16>& args) 856{ 857 const size_t SIZE = 256; 858 char buffer[SIZE]; 859 String8 result; 860 result.append("AudioStreamInMSM72xx::dump\n"); 861 snprintf(buffer, SIZE, "\tsample rate: %d\n", sampleRate()); 862 result.append(buffer); 863 snprintf(buffer, SIZE, "\tbuffer size: %d\n", bufferSize()); 864 result.append(buffer); 865 snprintf(buffer, SIZE, "\tchannel count: %d\n", channelCount()); 866 result.append(buffer); 867 snprintf(buffer, SIZE, "\tformat: %d\n", format()); 868 result.append(buffer); 869 snprintf(buffer, SIZE, "\tmHardware: %p\n", mHardware); 870 result.append(buffer); 871 snprintf(buffer, SIZE, "\tmFd count: %d\n", mFd); 872 result.append(buffer); 873 snprintf(buffer, SIZE, "\tmState: %d\n", mState); 874 result.append(buffer); 875 snprintf(buffer, SIZE, "\tmRetryCount: %d\n", mRetryCount); 876 result.append(buffer); 877 ::write(fd, result.string(), result.size()); 878 return NO_ERROR; 879} 880 881// ---------------------------------------------------------------------------- 882 883extern "C" AudioHardwareInterface* createAudioHardware(void) { 884 return new AudioHardware(); 885} 886 887}; // namespace android 888