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