AudioHardware.cpp revision d498a9ce9863bd979d3403473568c6e1e38b7dae
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 /* this is not really an error on non-htc devices... */ 69 mNumSndEndpoints = 0; 70 return; 71 } 72 73 set_acoustic_parameters = (int (*)(void))::dlsym(acoustic, "set_acoustic_parameters"); 74 if ((*set_acoustic_parameters) == 0 ) { 75 LOGE("Could not open set_acoustic_parameters()"); 76 return; 77 } 78 79 int rc = set_acoustic_parameters(); 80 if (rc < 0) { 81 LOGE("Could not set acoustic parameters to share memory: %d", rc); 82// return; 83 } 84 85 snd_get_num = (int (*)(void))::dlsym(acoustic, "snd_get_num_endpoints"); 86 if ((*snd_get_num) == 0 ) { 87 LOGE("Could not open snd_get_num()"); 88// return; 89 } 90 91 mNumSndEndpoints = snd_get_num(); 92 LOGD("mNumSndEndpoints = %d", mNumSndEndpoints); 93 mSndEndpoints = new msm_snd_endpoint[mNumSndEndpoints]; 94 mInit = true; 95 LOGV("constructed %d SND endpoints)", mNumSndEndpoints); 96 ept = mSndEndpoints; 97 snd_get_endpoint = (int (*)(int, msm_snd_endpoint *))::dlsym(acoustic, "snd_get_endpoint"); 98 if ((*snd_get_endpoint) == 0 ) { 99 LOGE("Could not open snd_get_endpoint()"); 100 return; 101 } 102 103 for (int cnt = 0; cnt < mNumSndEndpoints; cnt++, ept++) { 104 ept->id = cnt; 105 snd_get_endpoint(cnt, ept); 106#define CHECK_FOR(desc) \ 107 if (!strcmp(ept->name, #desc)) { \ 108 SND_DEVICE_##desc = ept->id; \ 109 LOGD("BT MATCH " #desc); \ 110 } else 111 CHECK_FOR(CURRENT) 112 CHECK_FOR(HANDSET) 113 CHECK_FOR(SPEAKER) 114 CHECK_FOR(BT) 115 CHECK_FOR(BT_EC_OFF) 116 CHECK_FOR(HEADSET) 117 CHECK_FOR(HEADSET_AND_SPEAKER) {} 118#undef CHECK_FOR 119 } 120} 121 122AudioHardware::~AudioHardware() 123{ 124 delete mInput; 125 delete mOutput; 126 delete [] mSndEndpoints; 127 if (acoustic) { 128 ::dlclose(acoustic); 129 acoustic = 0; 130 } 131 mInit = false; 132} 133 134status_t AudioHardware::initCheck() 135{ 136 return mInit ? NO_ERROR : NO_INIT; 137} 138 139AudioStreamOut* AudioHardware::openOutputStream( 140 int format, int channelCount, uint32_t sampleRate, status_t *status) 141{ 142 Mutex::Autolock lock(mLock); 143 144 // only one output stream allowed 145 if (mOutput) { 146 if (status) { 147 *status = INVALID_OPERATION; 148 } 149 return 0; 150 } 151 152 // create new output stream 153 AudioStreamOutMSM72xx* out = new AudioStreamOutMSM72xx(); 154 status_t lStatus = out->set(this, format, channelCount, sampleRate); 155 if (status) { 156 *status = lStatus; 157 } 158 if (lStatus == NO_ERROR) { 159 mOutput = out; 160 } else { 161 delete out; 162 } 163 return mOutput; 164} 165 166void AudioHardware::closeOutputStream(AudioStreamOutMSM72xx* out) { 167 Mutex::Autolock lock(mLock); 168 if (mOutput != out) { 169 LOGW("Attempt to close invalid output stream"); 170 } 171 else { 172 mOutput = 0; 173 } 174} 175 176AudioStreamIn* AudioHardware::openInputStream( 177 int inputSource, int format, int channelCount, uint32_t sampleRate, 178 status_t *status, AudioSystem::audio_in_acoustics acoustic_flags) 179{ 180 // check for valid input source 181 if ((inputSource < AudioRecord::DEFAULT_INPUT) || 182 (inputSource >= AudioRecord::NUM_INPUT_SOURCES)) { 183 return 0; 184 } 185 186 mLock.lock(); 187 // input stream already open? 188 if (mInput) { 189 if (status) { 190 *status = INVALID_OPERATION; 191 } 192 mLock.unlock(); 193 return 0; 194 } 195 196 AudioStreamInMSM72xx* in = new AudioStreamInMSM72xx(); 197 status_t lStatus = in->set(this, format, channelCount, sampleRate, acoustic_flags); 198 if (status) { 199 *status = lStatus; 200 } 201 if (lStatus != NO_ERROR) { 202 mLock.unlock(); 203 delete in; 204 return 0; 205 } 206 207 mInput = in; 208 mLock.unlock(); 209 210 return mInput; 211} 212 213void AudioHardware::closeInputStream(AudioStreamInMSM72xx* in) { 214 Mutex::Autolock lock(mLock); 215 if (mInput != in) { 216 LOGW("Attempt to close invalid input stream"); 217 } 218 else { 219 mInput = 0; 220 } 221} 222 223bool AudioHardware::checkOutputStandby() 224{ 225 if (mOutput) 226 if (!mOutput->checkStandby()) 227 return false; 228 229 return true; 230} 231 232status_t AudioHardware::setMicMute(bool state) 233{ 234 Mutex::Autolock lock(mLock); 235 return setMicMute_nosync(state); 236} 237 238// always call with mutex held 239status_t AudioHardware::setMicMute_nosync(bool state) 240{ 241 if (mMicMute != state) { 242 mMicMute = state; 243 return doAudioRouteOrMute(SND_DEVICE_CURRENT); 244 } 245 return NO_ERROR; 246} 247 248status_t AudioHardware::getMicMute(bool* state) 249{ 250 *state = mMicMute; 251 return NO_ERROR; 252} 253 254status_t AudioHardware::setParameter(const char *key, const char *value) 255{ 256 LOGV("%s key = %s value = %s\n", __FUNCTION__, key, value); 257 258 if (key == NULL || value == NULL) { 259 LOGE("%s called with null argument, ignoring (key = %s, value = %s", 260 __FUNCTION__, key, value); 261 return BAD_VALUE; 262 } 263 264 const char BT_NREC_KEY[] = "bt_headset_nrec"; 265 const char BT_NAME_KEY[] = "bt_headset_name"; 266 const char BT_NREC_VALUE_ON[] = "on"; 267 268 if (!strncmp(key, BT_NREC_KEY, sizeof(BT_NREC_KEY))) { 269 if (!strncmp(value, BT_NREC_VALUE_ON, sizeof(BT_NREC_VALUE_ON))) { 270 mBluetoothNrec = true; 271 } else { 272 mBluetoothNrec = false; 273 LOGI("Turning noise reduction and echo cancellation off for BT " 274 "headset"); 275 } 276 doRouting(); 277 } else if (!strncmp(key, BT_NAME_KEY, sizeof(BT_NAME_KEY))) { 278 mBluetoothId = 0; 279 for (int i = 0; i < mNumSndEndpoints; i++) { 280 if (!strcasecmp(value, mSndEndpoints[i].name)) { 281 mBluetoothId = mSndEndpoints[i].id; 282 LOGI("Using custom acoustic parameters for %s", value); 283 break; 284 } 285 } 286 if (mBluetoothId == 0) { 287 LOGI("Using default acoustic parameters " 288 "(%s not in acoustic database)", value); 289 doRouting(); 290 } 291 } 292 293 return NO_ERROR; 294} 295static unsigned calculate_audpre_table_index(unsigned index) 296{ 297 switch (index) { 298 case 48000: return SAMP_RATE_INDX_48000; 299 case 44100: return SAMP_RATE_INDX_44100; 300 case 32000: return SAMP_RATE_INDX_32000; 301 case 24000: return SAMP_RATE_INDX_24000; 302 case 22050: return SAMP_RATE_INDX_22050; 303 case 16000: return SAMP_RATE_INDX_16000; 304 case 12000: return SAMP_RATE_INDX_12000; 305 case 11025: return SAMP_RATE_INDX_11025; 306 case 8000: return SAMP_RATE_INDX_8000; 307 default: return -1; 308 } 309} 310size_t AudioHardware::getInputBufferSize(uint32_t sampleRate, int format, int channelCount) 311{ 312 if (checkInputSampleRate(sampleRate) != NO_ERROR) { 313 LOGW("getInputBufferSize bad sampling rate: %d", sampleRate); 314 return 0; 315 } 316 if (format != AudioSystem::PCM_16_BIT) { 317 LOGW("getInputBufferSize bad format: %d", format); 318 return 0; 319 } 320 if (channelCount < 1 || channelCount > 2) { 321 LOGW("getInputBufferSize bad channel count: %d", channelCount); 322 return 0; 323 } 324 325 return 2048*channelCount; 326} 327 328static status_t set_volume_rpc(uint32_t device, 329 uint32_t method, 330 uint32_t volume) 331{ 332 int fd; 333#if LOG_SND_RPC 334 LOGD("rpc_snd_set_volume(%d, %d, %d)\n", device, method, volume); 335#endif 336 337 if (device == -1UL) return NO_ERROR; 338 339 fd = open("/dev/msm_snd", O_RDWR); 340 if (fd < 0) { 341 LOGE("Can not open snd device"); 342 return -EPERM; 343 } 344 /* rpc_snd_set_volume( 345 * device, # Any hardware device enum, including 346 * # SND_DEVICE_CURRENT 347 * method, # must be SND_METHOD_VOICE to do anything useful 348 * volume, # integer volume level, in range [0,5]. 349 * # note that 0 is audible (not quite muted) 350 * ) 351 * rpc_snd_set_volume only works for in-call sound volume. 352 */ 353 struct msm_snd_volume_config args; 354 args.device = device; 355 args.method = method; 356 args.volume = volume; 357 358 if (ioctl(fd, SND_SET_VOLUME, &args) < 0) { 359 LOGE("snd_set_volume error."); 360 close(fd); 361 return -EIO; 362 } 363 close(fd); 364 return NO_ERROR; 365} 366 367status_t AudioHardware::setVoiceVolume(float v) 368{ 369 if (v < 0.0) { 370 LOGW("setVoiceVolume(%f) under 0.0, assuming 0.0\n", v); 371 v = 0.0; 372 } else if (v > 1.0) { 373 LOGW("setVoiceVolume(%f) over 1.0, assuming 1.0\n", v); 374 v = 1.0; 375 } 376 377 int vol = lrint(v * 5.0); 378 LOGD("setVoiceVolume(%f)\n", v); 379 LOGI("Setting in-call volume to %d (available range is 0 to 5)\n", vol); 380 381 Mutex::Autolock lock(mLock); 382 set_volume_rpc(SND_DEVICE_CURRENT, SND_METHOD_VOICE, vol); 383 return NO_ERROR; 384} 385 386status_t AudioHardware::setMasterVolume(float v) 387{ 388 Mutex::Autolock lock(mLock); 389 int vol = ceil(v * 5.0); 390 LOGI("Set master volume to %d.\n", vol); 391 set_volume_rpc(SND_DEVICE_HANDSET, SND_METHOD_VOICE, vol); 392 set_volume_rpc(SND_DEVICE_SPEAKER, SND_METHOD_VOICE, vol); 393 set_volume_rpc(SND_DEVICE_BT, SND_METHOD_VOICE, vol); 394 set_volume_rpc(SND_DEVICE_HEADSET, SND_METHOD_VOICE, vol); 395 // We return an error code here to let the audioflinger do in-software 396 // volume on top of the maximum volume that we set through the SND API. 397 // return error - software mixer will handle it 398 return -1; 399} 400 401static status_t do_route_audio_rpc(uint32_t device, 402 bool ear_mute, bool mic_mute) 403{ 404 if (device == -1UL) 405 return NO_ERROR; 406 407 int fd; 408#if LOG_SND_RPC 409 LOGD("rpc_snd_set_device(%d, %d, %d)\n", device, ear_mute, mic_mute); 410#endif 411 412 fd = open("/dev/msm_snd", O_RDWR); 413 if (fd < 0) { 414 LOGE("Can not open snd device"); 415 return -EPERM; 416 } 417 // RPC call to switch audio path 418 /* rpc_snd_set_device( 419 * device, # Hardware device enum to use 420 * ear_mute, # Set mute for outgoing voice audio 421 * # this should only be unmuted when in-call 422 * mic_mute, # Set mute for incoming voice audio 423 * # this should only be unmuted when in-call or 424 * # recording. 425 * ) 426 */ 427 struct msm_snd_device_config args; 428 args.device = device; 429 args.ear_mute = ear_mute ? SND_MUTE_MUTED : SND_MUTE_UNMUTED; 430 args.mic_mute = mic_mute ? SND_MUTE_MUTED : SND_MUTE_UNMUTED; 431 432 if (ioctl(fd, SND_SET_DEVICE, &args) < 0) { 433 LOGE("snd_set_device error."); 434 close(fd); 435 return -EIO; 436 } 437 438 close(fd); 439 return NO_ERROR; 440} 441 442// always call with mutex held 443status_t AudioHardware::doAudioRouteOrMute(uint32_t device) 444{ 445 if (device == (uint32_t)SND_DEVICE_BT) { 446 if (mBluetoothId) { 447 device = mBluetoothId; 448 } else if (!mBluetoothNrec) { 449 device = SND_DEVICE_BT_EC_OFF; 450 } 451 } 452 return do_route_audio_rpc(device, 453 mMode != AudioSystem::MODE_IN_CALL, mMicMute); 454} 455 456static int count_bits(uint32_t vector) 457{ 458 int bits; 459 for (bits = 0; vector; bits++) { 460 vector &= vector - 1; 461 } 462 return bits; 463} 464 465status_t AudioHardware::doRouting() 466{ 467 /* currently this code doesn't work without the htc libacoustic */ 468 if (!acoustic) 469 return 0; 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 784 if (!acoustic) 785 return NO_ERROR; 786 787 audpre_index = calculate_audpre_table_index(sampleRate); 788 tx_iir_index = (audpre_index * 2) + (hw->checkOutputStandby() ? 0 : 1); 789 LOGD("audpre_index = %d, tx_iir_index = %d\n", audpre_index, tx_iir_index); 790 791 /** 792 * If audio-preprocessing failed, we should not block record. 793 */ 794 int (*msm72xx_set_audpre_params)(int, int); 795 msm72xx_set_audpre_params = (int (*)(int, int))::dlsym(acoustic, "msm72xx_set_audpre_params"); 796 status = msm72xx_set_audpre_params(audpre_index, tx_iir_index); 797 if (status < 0) 798 LOGE("Cannot set audpre parameters"); 799 800 int (*msm72xx_enable_audpre)(int, int, int); 801 msm72xx_enable_audpre = (int (*)(int, int, int))::dlsym(acoustic, "msm72xx_enable_audpre"); 802 mAcoustics = acoustic_flags; 803 status = msm72xx_enable_audpre((int)acoustic_flags, audpre_index, tx_iir_index); 804 if (status < 0) 805 LOGE("Cannot enable audpre"); 806 807 return NO_ERROR; 808 809Error: 810 if (mFd > 0) { 811 ::close(mFd); 812 mFd = -1; 813 } 814 return status; 815} 816 817AudioHardware::AudioStreamInMSM72xx::~AudioStreamInMSM72xx() 818{ 819 LOGV("AudioStreamInMSM72xx destructor"); 820 if (mHardware) { 821 standby(); 822 mHardware->closeInputStream(this); 823 } 824} 825 826ssize_t AudioHardware::AudioStreamInMSM72xx::read( void* buffer, ssize_t bytes) 827{ 828 LOGV("AudioStreamInMSM72xx::read(%p, %ld)", buffer, bytes); 829 if (!mHardware) return -1; 830 831 size_t count = bytes; 832 uint8_t* p = static_cast<uint8_t*>(buffer); 833 834 if (mState < AUDIO_INPUT_OPENED) { 835 Mutex::Autolock lock(mHardware->mLock); 836 if (set(mHardware, mFormat, mChannelCount, mSampleRate, mAcoustics) != NO_ERROR) { 837 return -1; 838 } 839 } 840 841 if (mState < AUDIO_INPUT_STARTED) { 842 if (ioctl(mFd, AUDIO_START, 0)) { 843 LOGE("Error starting record"); 844 return -1; 845 } 846 mState = AUDIO_INPUT_STARTED; 847 } 848 849 while (count) { 850 ssize_t bytesRead = ::read(mFd, buffer, count); 851 if (bytesRead >= 0) { 852 count -= bytesRead; 853 p += bytesRead; 854 } else { 855 if (errno != EAGAIN) return bytesRead; 856 mRetryCount++; 857 LOGW("EAGAIN - retrying"); 858 } 859 } 860 return bytes; 861} 862 863status_t AudioHardware::AudioStreamInMSM72xx::standby() 864{ 865 if (!mHardware) return -1; 866 if (mState > AUDIO_INPUT_CLOSED) { 867 if (mFd > 0) { 868 ::close(mFd); 869 mFd = -1; 870 } 871 mHardware->checkMicMute(); 872 mState = AUDIO_INPUT_CLOSED; 873 } 874 return NO_ERROR; 875} 876 877status_t AudioHardware::AudioStreamInMSM72xx::dump(int fd, const Vector<String16>& args) 878{ 879 const size_t SIZE = 256; 880 char buffer[SIZE]; 881 String8 result; 882 result.append("AudioStreamInMSM72xx::dump\n"); 883 snprintf(buffer, SIZE, "\tsample rate: %d\n", sampleRate()); 884 result.append(buffer); 885 snprintf(buffer, SIZE, "\tbuffer size: %d\n", bufferSize()); 886 result.append(buffer); 887 snprintf(buffer, SIZE, "\tchannel count: %d\n", channelCount()); 888 result.append(buffer); 889 snprintf(buffer, SIZE, "\tformat: %d\n", format()); 890 result.append(buffer); 891 snprintf(buffer, SIZE, "\tmHardware: %p\n", mHardware); 892 result.append(buffer); 893 snprintf(buffer, SIZE, "\tmFd count: %d\n", mFd); 894 result.append(buffer); 895 snprintf(buffer, SIZE, "\tmState: %d\n", mState); 896 result.append(buffer); 897 snprintf(buffer, SIZE, "\tmRetryCount: %d\n", mRetryCount); 898 result.append(buffer); 899 ::write(fd, result.string(), result.size()); 900 return NO_ERROR; 901} 902 903// ---------------------------------------------------------------------------- 904 905extern "C" AudioHardwareInterface* createAudioHardware(void) { 906 return new AudioHardware(); 907} 908 909}; // namespace android 910