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