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