1/* AudioHardwareALSA.cpp 2 ** 3 ** Copyright 2008-2010 Wind River Systems 4 ** Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved. 5 ** 6 ** Licensed under the Apache License, Version 2.0 (the "License"); 7 ** you may not use this file except in compliance with the License. 8 ** You may obtain a copy of the License at 9 ** 10 ** http://www.apache.org/licenses/LICENSE-2.0 11 ** 12 ** Unless required by applicable law or agreed to in writing, software 13 ** distributed under the License is distributed on an "AS IS" BASIS, 14 ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 ** See the License for the specific language governing permissions and 16 ** limitations under the License. 17 */ 18 19#include <errno.h> 20#include <stdarg.h> 21#include <sys/stat.h> 22#include <fcntl.h> 23#include <stdlib.h> 24#include <unistd.h> 25#include <dlfcn.h> 26#include <math.h> 27 28#define LOG_TAG "AudioHardwareALSA" 29//#define LOG_NDEBUG 0 30#define LOG_NDDEBUG 0 31#include <utils/Log.h> 32#include <utils/String8.h> 33#include <sys/prctl.h> 34#include <sys/resource.h> 35#include <sys/poll.h> 36#include <sys/ioctl.h> 37#include <cutils/properties.h> 38#include <media/AudioRecord.h> 39#include <hardware_legacy/power.h> 40 41#include "AudioHardwareALSA.h" 42#ifdef QCOM_USBAUDIO_ENABLED 43#include "AudioUsbALSA.h" 44#endif 45#include "AudioUtil.h" 46 47extern "C" 48{ 49 // 50 // Function for dlsym() to look up for creating a new AudioHardwareInterface. 51 // 52 android_audio_legacy::AudioHardwareInterface *createAudioHardware(void) { 53 return android_audio_legacy::AudioHardwareALSA::create(); 54 } 55#ifdef QCOM_ACDB_ENABLED 56 static int (*acdb_init)(); 57 static void (*acdb_deallocate)(); 58#endif 59#ifdef QCOM_CSDCLIENT_ENABLED 60 static int (*csd_client_init)(); 61 static int (*csd_client_deinit)(); 62 static int (*csd_start_playback)(); 63 static int (*csd_stop_playback)(); 64#endif 65} // extern "C" 66 67namespace android_audio_legacy 68{ 69 70// ---------------------------------------------------------------------------- 71 72AudioHardwareInterface *AudioHardwareALSA::create() { 73 return new AudioHardwareALSA(); 74} 75 76AudioHardwareALSA::AudioHardwareALSA() : 77 mALSADevice(0),mVoipStreamCount(0),mVoipBitRate(0) 78 ,mCallState(0),mAcdbHandle(NULL),mCsdHandle(NULL),mMicMute(0) 79{ 80 FILE *fp; 81 char soundCardInfo[200]; 82 hw_module_t *module; 83 char platform[128], baseband[128]; 84 int err = hw_get_module(ALSA_HARDWARE_MODULE_ID, 85 (hw_module_t const**)&module); 86 int codec_rev = 2; 87 ALOGD("hw_get_module(ALSA_HARDWARE_MODULE_ID) returned err %d", err); 88 if (err == 0) { 89 hw_device_t* device; 90 err = module->methods->open(module, ALSA_HARDWARE_NAME, &device); 91 if (err == 0) { 92 mALSADevice = (alsa_device_t *)device; 93 mALSADevice->init(mALSADevice, mDeviceList); 94 mCSCallActive = 0; 95 mVolteCallActive = 0; 96 mIsFmActive = 0; 97 mDevSettingsFlag = 0; 98#ifdef QCOM_USBAUDIO_ENABLED 99 mAudioUsbALSA = new AudioUsbALSA(); 100 musbPlaybackState = 0; 101 musbRecordingState = 0; 102#endif 103#ifdef USES_FLUENCE_INCALL 104 mDevSettingsFlag |= TTY_OFF | DMIC_FLAG; 105#else 106 mDevSettingsFlag |= TTY_OFF; 107#endif 108 mBluetoothVGS = false; 109 mFusion3Platform = false; 110 111#ifdef QCOM_ACDB_ENABLED 112 mAcdbHandle = ::dlopen("/system/lib/libacdbloader.so", RTLD_NOW); 113 if (mAcdbHandle == NULL) { 114 ALOGE("AudioHardware: DLOPEN not successful for ACDBLOADER"); 115 } else { 116 ALOGD("AudioHardware: DLOPEN successful for ACDBLOADER"); 117 acdb_init = (int (*)())::dlsym(mAcdbHandle,"acdb_loader_init_ACDB"); 118 if (acdb_init == NULL) { 119 ALOGE("dlsym:Error:%s Loading acdb_loader_init_ACDB", dlerror()); 120 }else { 121 acdb_init(); 122 acdb_deallocate = (void (*)())::dlsym(mAcdbHandle,"acdb_loader_deallocate_ACDB"); 123 } 124 } 125#endif 126 127#ifdef QCOM_CSDCLIENT_ENABLED 128 mCsdHandle = ::dlopen("/system/lib/libcsd-client.so", RTLD_NOW); 129 if (mCsdHandle == NULL) { 130 ALOGE("AudioHardware: DLOPEN not successful for CSD CLIENT"); 131 } else { 132 ALOGD("AudioHardware: DLOPEN successful for CSD CLIENT"); 133 csd_client_init = (int (*)())::dlsym(mCsdHandle,"csd_client_init"); 134 csd_client_deinit = (int (*)())::dlsym(mCsdHandle,"csd_client_deinit"); 135 csd_start_playback = (int (*)())::dlsym(mCsdHandle,"csd_client_start_playback"); 136 csd_stop_playback = (int (*)())::dlsym(mCsdHandle,"csd_client_stop_playback"); 137 138 if (csd_client_init == NULL) { 139 ALOGE("dlsym: Error:%s Loading csd_client_init", dlerror()); 140 } else { 141 csd_client_init(); 142 } 143 } 144 mALSADevice->setCsdHandle(mCsdHandle); 145#endif 146 if((fp = fopen("/proc/asound/cards","r")) == NULL) { 147 ALOGE("Cannot open /proc/asound/cards file to get sound card info"); 148 } else { 149 while((fgets(soundCardInfo, sizeof(soundCardInfo), fp) != NULL)) { 150 ALOGV("SoundCardInfo %s", soundCardInfo); 151 if (strstr(soundCardInfo, "msm8960-tabla1x-snd-card")) { 152 codec_rev = 1; 153 break; 154 } else if (strstr(soundCardInfo, "msm-snd-card")) { 155 codec_rev = 2; 156 break; 157 } else if (strstr(soundCardInfo, "msm8930-sitar-snd-card")) { 158 codec_rev = 3; 159 break; 160 } 161 } 162 fclose(fp); 163 } 164 165 if (codec_rev == 1) { 166 ALOGV("Detected tabla 1.x sound card"); 167 snd_use_case_mgr_open(&mUcMgr, "snd_soc_msm"); 168 } else if (codec_rev == 3) { 169 ALOGV("Detected sitar 1.x sound card"); 170 snd_use_case_mgr_open(&mUcMgr, "snd_soc_msm_Sitar"); 171 } else { 172 property_get("ro.board.platform", platform, ""); 173 property_get("ro.baseband", baseband, ""); 174 if (!strcmp("msm8960", platform) && !strcmp("mdm", baseband)) { 175 ALOGV("Detected Fusion tabla 2.x"); 176 mFusion3Platform = true; 177 snd_use_case_mgr_open(&mUcMgr, "snd_soc_msm_2x_Fusion3"); 178 } else { 179 ALOGV("Detected tabla 2.x sound card"); 180 snd_use_case_mgr_open(&mUcMgr, "snd_soc_msm_2x"); 181 } 182 } 183 184 if (mUcMgr < 0) { 185 ALOGE("Failed to open ucm instance: %d", errno); 186 } else { 187 ALOGI("ucm instance opened: %u", (unsigned)mUcMgr); 188 mUcMgr->acdb_handle = NULL; 189#ifdef QCOM_ACDB_ENABLED 190 if (mAcdbHandle) { 191 mUcMgr->acdb_handle = static_cast<void*> (mAcdbHandle); 192 if (mFusion3Platform) 193 mUcMgr->isFusion3Platform = true; 194 else 195 mUcMgr->isFusion3Platform = false; 196 } 197#endif 198 } 199 } else { 200 ALOGE("ALSA Module could not be opened!!!"); 201 } 202 } else { 203 ALOGE("ALSA Module not found!!!"); 204 } 205} 206 207AudioHardwareALSA::~AudioHardwareALSA() 208{ 209 if (mUcMgr != NULL) { 210 ALOGV("closing ucm instance: %u", (unsigned)mUcMgr); 211 snd_use_case_mgr_close(mUcMgr); 212 } 213 if (mALSADevice) { 214 mALSADevice->common.close(&mALSADevice->common); 215 } 216 for(ALSAHandleList::iterator it = mDeviceList.begin(); 217 it != mDeviceList.end(); ++it) { 218 it->useCase[0] = 0; 219 mDeviceList.erase(it); 220 } 221#ifdef QCOM_ACDB_ENABLED 222 if (acdb_deallocate == NULL) { 223 ALOGE("dlsym: Error:%s Loading acdb_deallocate_ACDB", dlerror()); 224 } else { 225 acdb_deallocate(); 226 } 227 if (mAcdbHandle) { 228 ::dlclose(mAcdbHandle); 229 mAcdbHandle = NULL; 230 } 231#endif 232#ifdef QCOM_USBAUDIO_ENABLED 233 delete mAudioUsbALSA; 234#endif 235 236#ifdef QCOM_CSDCLEINT_ENABLED 237 if (mCsdHandle) { 238 if (csd_client_deinit == NULL) { 239 ALOGE("dlsym: Error:%s Loading csd_client_deinit", dlerror()); 240 } else { 241 csd_client_deinit(); 242 } 243 ::dlclose(mCsdHandle); 244 mCsdHandle = NULL; 245 } 246#endif 247} 248 249status_t AudioHardwareALSA::initCheck() 250{ 251 if (!mALSADevice) 252 return NO_INIT; 253 254 return NO_ERROR; 255} 256 257status_t AudioHardwareALSA::setVoiceVolume(float v) 258{ 259 ALOGV("setVoiceVolume(%f)\n", v); 260 if (v < 0.0) { 261 ALOGW("setVoiceVolume(%f) under 0.0, assuming 0.0\n", v); 262 v = 0.0; 263 } else if (v > 1.0) { 264 ALOGW("setVoiceVolume(%f) over 1.0, assuming 1.0\n", v); 265 v = 1.0; 266 } 267 268 int newMode = mode(); 269 ALOGV("setVoiceVolume newMode %d",newMode); 270 int vol = lrint(v * 100.0); 271 272 // Voice volume levels from android are mapped to driver volume levels as follows. 273 // 0 -> 5, 20 -> 4, 40 ->3, 60 -> 2, 80 -> 1, 100 -> 0 274 // So adjust the volume to get the correct volume index in driver 275 vol = 100 - vol; 276 277 if (mALSADevice) { 278 if(newMode == AudioSystem::MODE_IN_COMMUNICATION) { 279 mALSADevice->setVoipVolume(vol); 280 } else if (newMode == AudioSystem::MODE_IN_CALL){ 281 if (mCSCallActive == CS_ACTIVE) 282 mALSADevice->setVoiceVolume(vol); 283 if (mVolteCallActive == IMS_ACTIVE) 284 mALSADevice->setVoLTEVolume(vol); 285 } 286 } 287 288 return NO_ERROR; 289} 290 291#ifdef QCOM_FM_ENABLED 292status_t AudioHardwareALSA::setFmVolume(float value) 293{ 294 status_t status = NO_ERROR; 295 296 int vol; 297 298 if (value < 0.0) { 299 ALOGW("setFmVolume(%f) under 0.0, assuming 0.0\n", value); 300 value = 0.0; 301 } else if (value > 1.0) { 302 ALOGW("setFmVolume(%f) over 1.0, assuming 1.0\n", value); 303 value = 1.0; 304 } 305 vol = lrint((value * 0x2000) + 0.5); 306 307 ALOGV("setFmVolume(%f)\n", value); 308 ALOGV("Setting FM volume to %d (available range is 0 to 0x2000)\n", vol); 309 310 mALSADevice->setFmVolume(vol); 311 312 return status; 313} 314#endif 315 316status_t AudioHardwareALSA::setMasterVolume(float volume) 317{ 318 return NO_ERROR; 319} 320 321status_t AudioHardwareALSA::setMode(int mode) 322{ 323 status_t status = NO_ERROR; 324 325 if (mode != mMode) { 326 status = AudioHardwareBase::setMode(mode); 327 } 328 329 if (mode == AudioSystem::MODE_IN_CALL) { 330 mCallState = CS_ACTIVE; 331 }else if (mode == AudioSystem::MODE_NORMAL) { 332 mCallState = 0; 333 } 334 335 return status; 336} 337 338status_t AudioHardwareALSA::setParameters(const String8& keyValuePairs) 339{ 340 AudioParameter param = AudioParameter(keyValuePairs); 341 String8 key; 342 String8 value; 343 status_t status = NO_ERROR; 344 int device; 345 int btRate; 346 int state; 347 ALOGV("setParameters() %s", keyValuePairs.string()); 348 349 key = String8(TTY_MODE_KEY); 350 if (param.get(key, value) == NO_ERROR) { 351 mDevSettingsFlag &= TTY_CLEAR; 352 if (value == "tty_full") { 353 mDevSettingsFlag |= TTY_FULL; 354 } else if (value == "tty_hco") { 355 mDevSettingsFlag |= TTY_HCO; 356 } else if (value == "tty_vco") { 357 mDevSettingsFlag |= TTY_VCO; 358 } else { 359 mDevSettingsFlag |= TTY_OFF; 360 } 361 ALOGI("Changed TTY Mode=%s", value.string()); 362 mALSADevice->setFlags(mDevSettingsFlag); 363 if(mMode != AudioSystem::MODE_IN_CALL){ 364 return NO_ERROR; 365 } 366 doRouting(0); 367 } 368 369 key = String8(FLUENCE_KEY); 370 if (param.get(key, value) == NO_ERROR) { 371 if (value == "quadmic") { 372 mDevSettingsFlag |= QMIC_FLAG; 373 mDevSettingsFlag &= (~DMIC_FLAG); 374 ALOGV("Fluence quadMic feature Enabled"); 375 } else if (value == "dualmic") { 376 mDevSettingsFlag |= DMIC_FLAG; 377 mDevSettingsFlag &= (~QMIC_FLAG); 378 ALOGV("Fluence dualmic feature Enabled"); 379 } else if (value == "none") { 380 mDevSettingsFlag &= (~DMIC_FLAG); 381 mDevSettingsFlag &= (~QMIC_FLAG); 382 ALOGV("Fluence feature Disabled"); 383 } 384 mALSADevice->setFlags(mDevSettingsFlag); 385 doRouting(0); 386 } 387 388#ifdef QCOM_CSDCLIENT_ENABLED 389 if (mFusion3Platform) { 390 key = String8(INCALLMUSIC_KEY); 391 if (param.get(key, value) == NO_ERROR) { 392 if (value == "true") { 393 ALOGV("Enabling Incall Music setting in the setparameter\n"); 394 if (csd_start_playback == NULL) { 395 ALOGE("dlsym: Error:%s Loading csd_client_start_playback", dlerror()); 396 } else { 397 csd_start_playback(); 398 } 399 } else { 400 ALOGV("Disabling Incall Music setting in the setparameter\n"); 401 if (csd_stop_playback == NULL) { 402 ALOGE("dlsym: Error:%s Loading csd_client_stop_playback", dlerror()); 403 } else { 404 csd_stop_playback(); 405 } 406 } 407 } 408 } 409#endif 410 411 key = String8(ANC_KEY); 412 if (param.get(key, value) == NO_ERROR) { 413 if (value == "true") { 414 ALOGV("Enabling ANC setting in the setparameter\n"); 415 mDevSettingsFlag |= ANC_FLAG; 416 } else { 417 ALOGV("Disabling ANC setting in the setparameter\n"); 418 mDevSettingsFlag &= (~ANC_FLAG); 419 } 420 mALSADevice->setFlags(mDevSettingsFlag); 421 doRouting(0); 422 } 423 424 key = String8(AudioParameter::keyRouting); 425 if (param.getInt(key, device) == NO_ERROR) { 426 // Ignore routing if device is 0. 427 if(device) { 428 doRouting(device); 429 } 430 param.remove(key); 431 } 432 433 key = String8(BT_SAMPLERATE_KEY); 434 if (param.getInt(key, btRate) == NO_ERROR) { 435 mALSADevice->setBtscoRate(btRate); 436 param.remove(key); 437 } 438 439 key = String8(BTHEADSET_VGS); 440 if (param.get(key, value) == NO_ERROR) { 441 if (value == "on") { 442 mBluetoothVGS = true; 443 } else { 444 mBluetoothVGS = false; 445 } 446 } 447 448 key = String8(WIDEVOICE_KEY); 449 if (param.get(key, value) == NO_ERROR) { 450 bool flag = false; 451 if (value == "true") { 452 flag = true; 453 } 454 if(mALSADevice) { 455 mALSADevice->enableWideVoice(flag); 456 } 457 param.remove(key); 458 } 459 460 key = String8(VOIPRATE_KEY); 461 if (param.get(key, value) == NO_ERROR) { 462 mVoipBitRate = atoi(value); 463 param.remove(key); 464 } 465 466 key = String8(FENS_KEY); 467 if (param.get(key, value) == NO_ERROR) { 468 bool flag = false; 469 if (value == "true") { 470 flag = true; 471 } 472 if(mALSADevice) { 473 mALSADevice->enableFENS(flag); 474 } 475 param.remove(key); 476 } 477 478#ifdef QCOM_FM_ENABLED 479 key = String8(AudioParameter::keyHandleFm); 480 if (param.getInt(key, device) == NO_ERROR) { 481 // Ignore if device is 0 482 if(device) { 483 handleFm(device); 484 } 485 param.remove(key); 486 } 487#endif 488 489 key = String8(ST_KEY); 490 if (param.get(key, value) == NO_ERROR) { 491 bool flag = false; 492 if (value == "true") { 493 flag = true; 494 } 495 if(mALSADevice) { 496 mALSADevice->enableSlowTalk(flag); 497 } 498 param.remove(key); 499 } 500 key = String8(MODE_CALL_KEY); 501 if (param.getInt(key,state) == NO_ERROR) { 502 if (mCallState != state) { 503 mCallState = state; 504 doRouting(0); 505 } 506 mCallState = state; 507 } 508 if (param.size()) { 509 status = BAD_VALUE; 510 } 511 return status; 512} 513 514String8 AudioHardwareALSA::getParameters(const String8& keys) 515{ 516 AudioParameter param = AudioParameter(keys); 517 String8 value; 518 519 String8 key = String8(DUALMIC_KEY); 520 if (param.get(key, value) == NO_ERROR) { 521 value = String8("false"); 522 param.add(key, value); 523 } 524 525 key = String8(FLUENCE_KEY); 526 if (param.get(key, value) == NO_ERROR) { 527 if ((mDevSettingsFlag & QMIC_FLAG) && 528 (mDevSettingsFlag & ~DMIC_FLAG)) 529 value = String8("quadmic"); 530 else if ((mDevSettingsFlag & DMIC_FLAG) && 531 (mDevSettingsFlag & ~QMIC_FLAG)) 532 value = String8("dualmic"); 533 else if ((mDevSettingsFlag & ~DMIC_FLAG) && 534 (mDevSettingsFlag & ~QMIC_FLAG)) 535 value = String8("none"); 536 param.add(key, value); 537 } 538 539#ifdef QCOM_FM_ENABLED 540 key = String8("Fm-radio"); 541 if ( param.get(key,value) == NO_ERROR ) { 542 if ( mIsFmActive ) { 543 param.addInt(String8("isFMON"), true ); 544 } 545 } 546#endif 547 548 key = String8(BTHEADSET_VGS); 549 if (param.get(key, value) == NO_ERROR) { 550 if(mBluetoothVGS) 551 param.addInt(String8("isVGS"), true); 552 } 553 554 ALOGV("AudioHardwareALSA::getParameters() %s", param.toString().string()); 555 return param.toString(); 556} 557 558#ifdef QCOM_USBAUDIO_ENABLED 559void AudioHardwareALSA::closeUSBPlayback() 560{ 561 ALOGV("closeUSBPlayback, musbPlaybackState: %d", musbPlaybackState); 562 musbPlaybackState = 0; 563 mAudioUsbALSA->exitPlaybackThread(SIGNAL_EVENT_KILLTHREAD); 564} 565 566void AudioHardwareALSA::closeUSBRecording() 567{ 568 ALOGV("closeUSBRecording"); 569 musbRecordingState = 0; 570 mAudioUsbALSA->exitRecordingThread(SIGNAL_EVENT_KILLTHREAD); 571} 572 573void AudioHardwareALSA::closeUsbPlaybackIfNothingActive(){ 574 ALOGV("closeUsbPlaybackIfNothingActive, musbPlaybackState: %d", musbPlaybackState); 575 if(!musbPlaybackState && mAudioUsbALSA != NULL) { 576 mAudioUsbALSA->exitPlaybackThread(SIGNAL_EVENT_TIMEOUT); 577 } 578} 579 580void AudioHardwareALSA::closeUsbRecordingIfNothingActive(){ 581 ALOGV("closeUsbRecordingIfNothingActive, musbRecordingState: %d", musbRecordingState); 582 if(!musbRecordingState && mAudioUsbALSA != NULL) { 583 ALOGD("Closing USB Recording Session as no stream is active"); 584 mAudioUsbALSA->setkillUsbRecordingThread(true); 585 } 586} 587 588void AudioHardwareALSA::startUsbPlaybackIfNotStarted(){ 589 ALOGV("Starting the USB playback %d kill %d", musbPlaybackState, 590 mAudioUsbALSA->getkillUsbPlaybackThread()); 591 if((!musbPlaybackState) || (mAudioUsbALSA->getkillUsbPlaybackThread() == true)) { 592 mAudioUsbALSA->startPlayback(); 593 } 594} 595 596void AudioHardwareALSA::startUsbRecordingIfNotStarted(){ 597 ALOGV("Starting the recording musbRecordingState: %d killUsbRecordingThread %d", 598 musbRecordingState, mAudioUsbALSA->getkillUsbRecordingThread()); 599 if((!musbRecordingState) || (mAudioUsbALSA->getkillUsbRecordingThread() == true)) { 600 mAudioUsbALSA->startRecording(); 601 } 602} 603#endif 604 605void AudioHardwareALSA::doRouting(int device) 606{ 607 Mutex::Autolock autoLock(mLock); 608 int newMode = mode(); 609 bool isRouted = false; 610 611 if ((device == AudioSystem::DEVICE_IN_VOICE_CALL) 612#ifdef QCOM_FM_ENABLED 613 || (device == AudioSystem::DEVICE_IN_FM_RX) 614 || (device == AudioSystem::DEVICE_OUT_DIRECTOUTPUT) 615 || (device == AudioSystem::DEVICE_IN_FM_RX_A2DP) 616#endif 617 || (device == AudioSystem::DEVICE_IN_COMMUNICATION) 618 ) { 619 ALOGV("Ignoring routing for FM/INCALL/VOIP recording"); 620 return; 621 } 622 if (device == 0) 623 device = mCurDevice; 624 ALOGV("doRouting: device %d newMode %d mCSCallActive %d mVolteCallActive %d" 625 "mIsFmActive %d", device, newMode, mCSCallActive, mVolteCallActive, 626 mIsFmActive); 627 628 isRouted = routeVoLTECall(device, newMode); 629 isRouted |= routeVoiceCall(device, newMode); 630 631 if(!isRouted) { 632#ifdef QCOM_USBAUDIO_ENABLED 633 if(!(device & AudioSystem::DEVICE_OUT_ANLG_DOCK_HEADSET) && 634 !(device & AudioSystem::DEVICE_OUT_DGTL_DOCK_HEADSET) && 635 !(device & AudioSystem::DEVICE_IN_ANLG_DOCK_HEADSET) && 636 (musbPlaybackState)){ 637 //USB unplugged 638 device &= ~ AudioSystem::DEVICE_OUT_PROXY; 639 device &= ~ AudioSystem::DEVICE_IN_PROXY; 640 ALSAHandleList::iterator it = mDeviceList.end(); 641 it--; 642 mALSADevice->route(&(*it), (uint32_t)device, newMode); 643 ALOGD("USB UNPLUGGED, setting musbPlaybackState to 0"); 644 musbPlaybackState = 0; 645 musbRecordingState = 0; 646 closeUSBRecording(); 647 closeUSBPlayback(); 648 } else if((device & AudioSystem::DEVICE_OUT_ANLG_DOCK_HEADSET)|| 649 (device & AudioSystem::DEVICE_OUT_DGTL_DOCK_HEADSET)){ 650 ALOGD("Routing everything to prox now"); 651 ALSAHandleList::iterator it = mDeviceList.end(); 652 it--; 653 mALSADevice->route(&(*it), AudioSystem::DEVICE_OUT_PROXY, 654 newMode); 655 for(it = mDeviceList.begin(); it != mDeviceList.end(); ++it) { 656 if((!strcmp(it->useCase, SND_USE_CASE_VERB_HIFI_LOW_POWER)) || 657 (!strcmp(it->useCase, SND_USE_CASE_MOD_PLAY_LPA))) { 658 ALOGV("doRouting: LPA device switch to proxy"); 659 startUsbPlaybackIfNotStarted(); 660 musbPlaybackState |= USBPLAYBACKBIT_LPA; 661 break; 662 } else if((!strcmp(it->useCase, SND_USE_CASE_VERB_VOICECALL)) || 663 (!strcmp(it->useCase, SND_USE_CASE_MOD_PLAY_VOICE))) { 664 ALOGV("doRouting: VOICE device switch to proxy"); 665 startUsbRecordingIfNotStarted(); 666 startUsbPlaybackIfNotStarted(); 667 musbPlaybackState |= USBPLAYBACKBIT_VOICECALL; 668 musbRecordingState |= USBPLAYBACKBIT_VOICECALL; 669 break; 670 }else if((!strcmp(it->useCase, SND_USE_CASE_VERB_DIGITAL_RADIO)) || 671 (!strcmp(it->useCase, SND_USE_CASE_MOD_PLAY_FM))) { 672 ALOGV("doRouting: FM device switch to proxy"); 673 startUsbPlaybackIfNotStarted(); 674 musbPlaybackState |= USBPLAYBACKBIT_FM; 675 break; 676 } 677 } 678 } else 679#endif 680 { 681 ALSAHandleList::iterator it = mDeviceList.end(); 682 it--; 683 mALSADevice->route(&(*it), (uint32_t)device, newMode); 684 } 685 } 686 mCurDevice = device; 687} 688 689uint32_t AudioHardwareALSA::getVoipMode(int format) 690{ 691 switch(format) { 692 case AudioSystem::PCM_16_BIT: 693 return MODE_PCM; 694 break; 695 case AudioSystem::AMR_NB: 696 return MODE_AMR; 697 break; 698 case AudioSystem::AMR_WB: 699 return MODE_AMR_WB; 700 break; 701 702#ifdef QCOM_QCHAT_ENABLED 703 case AudioSystem::EVRC: 704 return MODE_IS127; 705 break; 706 707 case AudioSystem::EVRCB: 708 return MODE_4GV_NB; 709 break; 710 case AudioSystem::EVRCWB: 711 return MODE_4GV_WB; 712 break; 713#endif 714 715 default: 716 return MODE_PCM; 717 } 718} 719 720AudioStreamOut * 721AudioHardwareALSA::openOutputStream(uint32_t devices, 722 int *format, 723 uint32_t *channels, 724 uint32_t *sampleRate, 725 status_t *status) 726{ 727 Mutex::Autolock autoLock(mLock); 728 ALOGV("openOutputStream: devices 0x%x channels %d sampleRate %d", 729 devices, *channels, *sampleRate); 730 731 audio_output_flags_t flag = static_cast<audio_output_flags_t> (*status); 732 733 status_t err = BAD_VALUE; 734 *status = NO_ERROR; 735 AudioStreamOutALSA *out = 0; 736 ALSAHandleList::iterator it; 737 738 if (devices & (devices - 1)) { 739 if (status) *status = err; 740 ALOGE("openOutputStream called with bad devices"); 741 return out; 742 } 743 744 745# if 0 746 if((devices == AudioSystem::DEVICE_OUT_DIRECTOUTPUT) && 747 ((*sampleRate == VOIP_SAMPLING_RATE_8K) || (*sampleRate == VOIP_SAMPLING_RATE_16K))) { 748 bool voipstream_active = false; 749 for(it = mDeviceList.begin(); 750 it != mDeviceList.end(); ++it) { 751 if((!strcmp(it->useCase, SND_USE_CASE_VERB_IP_VOICECALL)) || 752 (!strcmp(it->useCase, SND_USE_CASE_MOD_PLAY_VOIP))) { 753 ALOGD("openOutput: it->rxHandle %d it->handle %d",it->rxHandle,it->handle); 754 voipstream_active = true; 755 break; 756 } 757 } 758 if(voipstream_active == false) { 759 mVoipStreamCount = 0; 760 alsa_handle_t alsa_handle; 761 unsigned long bufferSize; 762 if(*sampleRate == VOIP_SAMPLING_RATE_8K) { 763 bufferSize = VOIP_BUFFER_SIZE_8K; 764 } 765 else if(*sampleRate == VOIP_SAMPLING_RATE_16K) { 766 bufferSize = VOIP_BUFFER_SIZE_16K; 767 } 768 else { 769 ALOGE("unsupported samplerate %d for voip",*sampleRate); 770 if (status) *status = err; 771 return out; 772 } 773 alsa_handle.module = mALSADevice; 774 alsa_handle.bufferSize = bufferSize; 775 alsa_handle.devices = devices; 776 alsa_handle.handle = 0; 777 if(*format == AudioSystem::PCM_16_BIT) 778 alsa_handle.format = SNDRV_PCM_FORMAT_S16_LE; 779 else 780 alsa_handle.format = *format; 781 alsa_handle.channels = VOIP_DEFAULT_CHANNEL_MODE; 782 alsa_handle.channelMask = AUDIO_CHANNEL_IN_MONO; 783 alsa_handle.sampleRate = *sampleRate; 784 alsa_handle.latency = VOIP_PLAYBACK_LATENCY; 785 alsa_handle.rxHandle = 0; 786 alsa_handle.ucMgr = mUcMgr; 787 mALSADevice->setVoipConfig(getVoipMode(*format), mVoipBitRate); 788 char *use_case; 789 snd_use_case_get(mUcMgr, "_verb", (const char **)&use_case); 790 if ((use_case == NULL) || (!strcmp(use_case, SND_USE_CASE_VERB_INACTIVE))) { 791 strlcpy(alsa_handle.useCase, SND_USE_CASE_VERB_IP_VOICECALL, sizeof(alsa_handle.useCase)); 792 } else { 793 strlcpy(alsa_handle.useCase, SND_USE_CASE_MOD_PLAY_VOIP, sizeof(alsa_handle.useCase)); 794 } 795 free(use_case); 796 mDeviceList.push_back(alsa_handle); 797 it = mDeviceList.end(); 798 it--; 799 ALOGV("openoutput: mALSADevice->route useCase %s mCurDevice %d mVoipStreamCount %d mode %d", it->useCase,mCurDevice,mVoipStreamCount, mode()); 800 if((mCurDevice & AudioSystem::DEVICE_OUT_ANLG_DOCK_HEADSET)|| 801 (mCurDevice & AudioSystem::DEVICE_OUT_DGTL_DOCK_HEADSET)|| 802 (mCurDevice & AudioSystem::DEVICE_OUT_PROXY)){ 803 ALOGD("Routing to proxy for normal voip call in openOutputStream"); 804 mCurDevice |= AudioSystem::DEVICE_OUT_PROXY; 805 alsa_handle.devices = AudioSystem::DEVICE_OUT_PROXY; 806 mALSADevice->route(&(*it), mCurDevice, AudioSystem::MODE_IN_COMMUNICATION); 807 ALOGD("enabling VOIP in openoutputstream, musbPlaybackState: %d", musbPlaybackState); 808 startUsbPlaybackIfNotStarted(); 809 musbPlaybackState |= USBPLAYBACKBIT_VOIPCALL; 810 ALOGD("Starting recording in openoutputstream, musbRecordingState: %d", musbRecordingState); 811 startUsbRecordingIfNotStarted(); 812 musbRecordingState |= USBRECBIT_VOIPCALL; 813 } else{ 814 mALSADevice->route(&(*it), mCurDevice, AudioSystem::MODE_IN_COMMUNICATION); 815 } 816 if(!strcmp(it->useCase, SND_USE_CASE_VERB_IP_VOICECALL)) { 817 snd_use_case_set(mUcMgr, "_verb", SND_USE_CASE_VERB_IP_VOICECALL); 818 } else { 819 snd_use_case_set(mUcMgr, "_enamod", SND_USE_CASE_MOD_PLAY_VOIP); 820 } 821 err = mALSADevice->startVoipCall(&(*it)); 822 if (err) { 823 ALOGE("Device open failed"); 824 return NULL; 825 } 826 } 827 out = new AudioStreamOutALSA(this, &(*it)); 828 err = out->set(format, channels, sampleRate, devices); 829 if(err == NO_ERROR) { 830 mVoipStreamCount++; //increment VoipstreamCount only if success 831 ALOGD("openoutput mVoipStreamCount %d",mVoipStreamCount); 832 } 833 if (status) *status = err; 834 return out; 835 } else 836#endif 837 if ((flag & AUDIO_OUTPUT_FLAG_DIRECT) && 838 (devices == AudioSystem::DEVICE_OUT_AUX_DIGITAL)) { 839 ALOGD("Multi channel PCM"); 840 alsa_handle_t alsa_handle; 841 EDID_AUDIO_INFO info = { 0 }; 842 843 alsa_handle.module = mALSADevice; 844 alsa_handle.devices = devices; 845 alsa_handle.handle = 0; 846 alsa_handle.format = SNDRV_PCM_FORMAT_S16_LE; 847 848 if (!AudioUtil::getHDMIAudioSinkCaps(&info)) { 849 ALOGE("openOutputStream: Failed to get HDMI sink capabilities"); 850 return NULL; 851 } 852 if (0 == *channels) { 853 alsa_handle.channels = info.AudioBlocksArray[info.nAudioBlocks-1].nChannels; 854 if (alsa_handle.channels > 6) { 855 alsa_handle.channels = 6; 856 } 857 *channels = audio_channel_out_mask_from_count(alsa_handle.channels); 858 } else { 859 alsa_handle.channels = AudioSystem::popCount(*channels); 860 } 861 alsa_handle.channelMask = *channels; 862 863 if (6 == alsa_handle.channels) { 864 alsa_handle.bufferSize = DEFAULT_MULTI_CHANNEL_BUF_SIZE; 865 } else { 866 alsa_handle.bufferSize = DEFAULT_BUFFER_SIZE; 867 } 868 if (0 == *sampleRate) { 869 alsa_handle.sampleRate = info.AudioBlocksArray[info.nAudioBlocks-1].nSamplingFreq; 870 *sampleRate = alsa_handle.sampleRate; 871 } else { 872 alsa_handle.sampleRate = *sampleRate; 873 } 874 alsa_handle.latency = PLAYBACK_LATENCY; 875 alsa_handle.rxHandle = 0; 876 alsa_handle.ucMgr = mUcMgr; 877 ALOGD("alsa_handle.channels %d alsa_handle.sampleRate %d",alsa_handle.channels,alsa_handle.sampleRate); 878 879 char *use_case; 880 snd_use_case_get(mUcMgr, "_verb", (const char **)&use_case); 881 if ((use_case == NULL) || (!strcmp(use_case, SND_USE_CASE_VERB_INACTIVE))) { 882 strlcpy(alsa_handle.useCase, SND_USE_CASE_VERB_HIFI2 , sizeof(alsa_handle.useCase)); 883 } else { 884 strlcpy(alsa_handle.useCase, SND_USE_CASE_MOD_PLAY_MUSIC2, sizeof(alsa_handle.useCase)); 885 } 886 free(use_case); 887 mDeviceList.push_back(alsa_handle); 888 ALSAHandleList::iterator it = mDeviceList.end(); 889 it--; 890 ALOGD("it->useCase %s", it->useCase); 891 mALSADevice->route(&(*it), devices, mode()); 892 if(!strcmp(it->useCase, SND_USE_CASE_VERB_HIFI2)) { 893 snd_use_case_set(mUcMgr, "_verb", SND_USE_CASE_VERB_HIFI2 ); 894 } else { 895 snd_use_case_set(mUcMgr, "_enamod", SND_USE_CASE_MOD_PLAY_MUSIC2); 896 } 897 ALOGD("channels: %d", AudioSystem::popCount(*channels)); 898 err = mALSADevice->open(&(*it)); 899 900 if (err) { 901 ALOGE("Device open failed err:%d",err); 902 } else { 903 out = new AudioStreamOutALSA(this, &(*it)); 904 err = out->set(format, channels, sampleRate, devices); 905 } 906 if (status) *status = err; 907 return out; 908 } else { 909 910 alsa_handle_t alsa_handle; 911 unsigned long bufferSize = DEFAULT_BUFFER_SIZE; 912 913 for (size_t b = 1; (bufferSize & ~b) != 0; b <<= 1) 914 bufferSize &= ~b; 915 916 alsa_handle.module = mALSADevice; 917 alsa_handle.bufferSize = bufferSize; 918 alsa_handle.devices = devices; 919 alsa_handle.handle = 0; 920 alsa_handle.format = SNDRV_PCM_FORMAT_S16_LE; 921 alsa_handle.channels = DEFAULT_CHANNEL_MODE; 922 alsa_handle.channelMask = AUDIO_CHANNEL_OUT_STEREO; 923 alsa_handle.sampleRate = DEFAULT_SAMPLING_RATE; 924 alsa_handle.latency = PLAYBACK_LATENCY; 925 alsa_handle.rxHandle = 0; 926 alsa_handle.ucMgr = mUcMgr; 927 alsa_handle.isDeepbufferOutput = false; 928 929 char *use_case; 930 snd_use_case_get(mUcMgr, "_verb", (const char **)&use_case); 931 932 if (flag & AUDIO_OUTPUT_FLAG_DEEP_BUFFER) { 933 ALOGD("openOutputStream: DeepBuffer Output"); 934 alsa_handle.isDeepbufferOutput = true; 935 if ((use_case == NULL) || (!strcmp(use_case, SND_USE_CASE_VERB_INACTIVE))) { 936 strlcpy(alsa_handle.useCase, SND_USE_CASE_VERB_HIFI, sizeof(alsa_handle.useCase)); 937 } else { 938 strlcpy(alsa_handle.useCase, SND_USE_CASE_MOD_PLAY_MUSIC, sizeof(alsa_handle.useCase)); 939 } 940 } else { 941 ALOGD("openOutputStream: Lowlatency Output"); 942 alsa_handle.bufferSize = PLAYBACK_LOW_LATENCY_BUFFER_SIZE; 943 alsa_handle.latency = PLAYBACK_LOW_LATENCY_MEASURED; 944 if ((use_case == NULL) || (!strcmp(use_case, SND_USE_CASE_VERB_INACTIVE))) { 945 strlcpy(alsa_handle.useCase, SND_USE_CASE_VERB_HIFI_LOWLATENCY_MUSIC, sizeof(alsa_handle.useCase)); 946 } else { 947 strlcpy(alsa_handle.useCase, SND_USE_CASE_MOD_PLAY_LOWLATENCY_MUSIC, sizeof(alsa_handle.useCase)); 948 } 949 } 950 free(use_case); 951 mDeviceList.push_back(alsa_handle); 952 ALSAHandleList::iterator it = mDeviceList.end(); 953 it--; 954 ALOGV("useCase %s", it->useCase); 955#ifdef QCOM_USBAUDIO_ENABLED 956 if((devices & AudioSystem::DEVICE_OUT_ANLG_DOCK_HEADSET)|| 957 (devices & AudioSystem::DEVICE_OUT_DGTL_DOCK_HEADSET)){ 958 ALOGD("Routing to proxy for normal playback in openOutputStream"); 959 devices |= AudioSystem::DEVICE_OUT_PROXY; 960 } 961#endif 962 mALSADevice->route(&(*it), devices, mode()); 963 if (flag & AUDIO_OUTPUT_FLAG_DEEP_BUFFER) { 964 if(!strcmp(it->useCase, SND_USE_CASE_VERB_HIFI)) { 965 snd_use_case_set(mUcMgr, "_verb", SND_USE_CASE_VERB_HIFI); 966 } else { 967 snd_use_case_set(mUcMgr, "_enamod", SND_USE_CASE_MOD_PLAY_MUSIC); 968 } 969 } else { 970 if(!strcmp(it->useCase, SND_USE_CASE_VERB_HIFI_LOWLATENCY_MUSIC)) { 971 snd_use_case_set(mUcMgr, "_verb", SND_USE_CASE_VERB_HIFI_LOWLATENCY_MUSIC); 972 } else { 973 snd_use_case_set(mUcMgr, "_enamod", SND_USE_CASE_MOD_PLAY_LOWLATENCY_MUSIC); 974 } 975 } 976 err = mALSADevice->open(&(*it)); 977 if (err) { 978 ALOGE("Device open failed"); 979 } else { 980 out = new AudioStreamOutALSA(this, &(*it)); 981 err = out->set(format, channels, sampleRate, devices); 982 } 983 984 if (status) *status = err; 985 return out; 986 } 987} 988 989void 990AudioHardwareALSA::closeOutputStream(AudioStreamOut* out) 991{ 992 delete out; 993} 994 995#ifdef QCOM_TUNNEL_LPA_ENABLED 996AudioStreamOut * 997AudioHardwareALSA::openOutputSession(uint32_t devices, 998 int *format, 999 status_t *status, 1000 int sessionId, 1001 uint32_t samplingRate, 1002 uint32_t channels) 1003{ 1004 Mutex::Autolock autoLock(mLock); 1005 ALOGD("openOutputSession = %d" ,sessionId); 1006 AudioStreamOutALSA *out = 0; 1007 status_t err = BAD_VALUE; 1008 1009 alsa_handle_t alsa_handle; 1010 unsigned long bufferSize = DEFAULT_BUFFER_SIZE; 1011 1012 for (size_t b = 1; (bufferSize & ~b) != 0; b <<= 1) 1013 bufferSize &= ~b; 1014 1015 alsa_handle.module = mALSADevice; 1016 alsa_handle.bufferSize = bufferSize; 1017 alsa_handle.devices = devices; 1018 alsa_handle.handle = 0; 1019 alsa_handle.format = SNDRV_PCM_FORMAT_S16_LE; 1020 alsa_handle.channels = DEFAULT_CHANNEL_MODE; 1021 alsa_handle.channelMask = AUDIO_CHANNEL_OUT_STEREO; 1022 alsa_handle.sampleRate = DEFAULT_SAMPLING_RATE; 1023 alsa_handle.latency = VOICE_LATENCY; 1024 alsa_handle.rxHandle = 0; 1025 alsa_handle.ucMgr = mUcMgr; 1026 1027 char *use_case; 1028 if(sessionId == TUNNEL_SESSION_ID) { 1029 snd_use_case_get(mUcMgr, "_verb", (const char **)&use_case); 1030 if ((use_case == NULL) || (!strcmp(use_case, SND_USE_CASE_VERB_INACTIVE))) { 1031 strlcpy(alsa_handle.useCase, SND_USE_CASE_VERB_HIFI_TUNNEL, sizeof(alsa_handle.useCase)); 1032 } else { 1033 strlcpy(alsa_handle.useCase, SND_USE_CASE_MOD_PLAY_TUNNEL, sizeof(alsa_handle.useCase)); 1034 } 1035 } else { 1036 snd_use_case_get(mUcMgr, "_verb", (const char **)&use_case); 1037 if ((use_case == NULL) || (!strcmp(use_case, SND_USE_CASE_VERB_INACTIVE))) { 1038 strlcpy(alsa_handle.useCase, SND_USE_CASE_VERB_HIFI_LOW_POWER, sizeof(alsa_handle.useCase)); 1039 } else { 1040 strlcpy(alsa_handle.useCase, SND_USE_CASE_MOD_PLAY_LPA, sizeof(alsa_handle.useCase)); 1041 } 1042 } 1043 free(use_case); 1044 mDeviceList.push_back(alsa_handle); 1045 ALSAHandleList::iterator it = mDeviceList.end(); 1046 it--; 1047 ALOGD("useCase %s", it->useCase); 1048#ifdef QCOM_USBAUDIO_ENABLED 1049 if((devices & AudioSystem::DEVICE_OUT_ANLG_DOCK_HEADSET)|| 1050 (devices & AudioSystem::DEVICE_OUT_DGTL_DOCK_HEADSET)){ 1051 ALOGD("Routing to proxy for LPA in openOutputSession"); 1052 devices |= AudioSystem::DEVICE_OUT_PROXY; 1053 mALSADevice->route(&(*it), devices, mode()); 1054 devices = AudioSystem::DEVICE_OUT_ANLG_DOCK_HEADSET; 1055 ALOGD("Starting USBPlayback for LPA"); 1056 startUsbPlaybackIfNotStarted(); 1057 musbPlaybackState |= USBPLAYBACKBIT_LPA; 1058 } else 1059#endif 1060 { 1061 mALSADevice->route(&(*it), devices, mode()); 1062 } 1063 if(sessionId == TUNNEL_SESSION_ID) { 1064 if(!strcmp(it->useCase, SND_USE_CASE_VERB_HIFI_TUNNEL)) { 1065 snd_use_case_set(mUcMgr, "_verb", SND_USE_CASE_VERB_HIFI_TUNNEL); 1066 } else { 1067 snd_use_case_set(mUcMgr, "_enamod", SND_USE_CASE_MOD_PLAY_TUNNEL); 1068 } 1069 } 1070 else { 1071 if(!strcmp(it->useCase, SND_USE_CASE_VERB_HIFI_LOW_POWER)) { 1072 snd_use_case_set(mUcMgr, "_verb", SND_USE_CASE_VERB_HIFI_LOW_POWER); 1073 } else { 1074 snd_use_case_set(mUcMgr, "_enamod", SND_USE_CASE_MOD_PLAY_LPA); 1075 } 1076 } 1077 err = mALSADevice->open(&(*it)); 1078 out = new AudioStreamOutALSA(this, &(*it)); 1079 1080 if (status) *status = err; 1081 return out; 1082} 1083 1084void 1085AudioHardwareALSA::closeOutputSession(AudioStreamOut* out) 1086{ 1087 delete out; 1088} 1089#endif 1090 1091AudioStreamIn * 1092AudioHardwareALSA::openInputStream(uint32_t devices, 1093 int *format, 1094 uint32_t *channels, 1095 uint32_t *sampleRate, 1096 status_t *status, 1097 AudioSystem::audio_in_acoustics acoustics) 1098{ 1099 Mutex::Autolock autoLock(mLock); 1100 char *use_case; 1101 int newMode = mode(); 1102 uint32_t route_devices; 1103 1104 status_t err = BAD_VALUE; 1105 AudioStreamInALSA *in = 0; 1106 ALSAHandleList::iterator it; 1107 1108 ALOGD("openInputStream: devices 0x%x channels %d sampleRate %d", devices, *channels, *sampleRate); 1109 if (devices & (devices - 1)) { 1110 if (status) *status = err; 1111 return in; 1112 } 1113 1114 if((devices == AudioSystem::DEVICE_IN_COMMUNICATION) && 1115 ((*sampleRate == VOIP_SAMPLING_RATE_8K) || (*sampleRate == VOIP_SAMPLING_RATE_16K))) { 1116 bool voipstream_active = false; 1117 for(it = mDeviceList.begin(); 1118 it != mDeviceList.end(); ++it) { 1119 if((!strcmp(it->useCase, SND_USE_CASE_VERB_IP_VOICECALL)) || 1120 (!strcmp(it->useCase, SND_USE_CASE_MOD_PLAY_VOIP))) { 1121 ALOGD("openInput: it->rxHandle %p it->handle %p",it->rxHandle,it->handle); 1122 voipstream_active = true; 1123 break; 1124 } 1125 } 1126 if(voipstream_active == false) { 1127 mVoipStreamCount = 0; 1128 alsa_handle_t alsa_handle; 1129 unsigned long bufferSize; 1130 if(*sampleRate == VOIP_SAMPLING_RATE_8K) { 1131 bufferSize = VOIP_BUFFER_SIZE_8K; 1132 } 1133 else if(*sampleRate == VOIP_SAMPLING_RATE_16K) { 1134 bufferSize = VOIP_BUFFER_SIZE_16K; 1135 } 1136 else { 1137 ALOGE("unsupported samplerate %d for voip",*sampleRate); 1138 if (status) *status = err; 1139 return in; 1140 } 1141 alsa_handle.module = mALSADevice; 1142 alsa_handle.bufferSize = bufferSize; 1143 alsa_handle.devices = devices; 1144 alsa_handle.handle = 0; 1145 if(*format == AudioSystem::PCM_16_BIT) 1146 alsa_handle.format = SNDRV_PCM_FORMAT_S16_LE; 1147 else 1148 alsa_handle.format = *format; 1149 alsa_handle.channels = VOIP_DEFAULT_CHANNEL_MODE; 1150 alsa_handle.channelMask = AUDIO_CHANNEL_IN_MONO; 1151 alsa_handle.sampleRate = *sampleRate; 1152 alsa_handle.latency = VOIP_RECORD_LATENCY; 1153 alsa_handle.rxHandle = 0; 1154 alsa_handle.ucMgr = mUcMgr; 1155 mALSADevice->setVoipConfig(getVoipMode(*format), mVoipBitRate); 1156 snd_use_case_get(mUcMgr, "_verb", (const char **)&use_case); 1157 if ((use_case != NULL) && (strcmp(use_case, SND_USE_CASE_VERB_INACTIVE))) { 1158 strlcpy(alsa_handle.useCase, SND_USE_CASE_MOD_PLAY_VOIP, sizeof(alsa_handle.useCase)); 1159 } else { 1160 strlcpy(alsa_handle.useCase, SND_USE_CASE_VERB_IP_VOICECALL, sizeof(alsa_handle.useCase)); 1161 } 1162 free(use_case); 1163 mDeviceList.push_back(alsa_handle); 1164 it = mDeviceList.end(); 1165 it--; 1166 ALOGD("mCurrDevice: %d", mCurDevice); 1167#ifdef QCOM_USBAUDIO_ENABLED 1168 if((mCurDevice == AudioSystem::DEVICE_OUT_ANLG_DOCK_HEADSET)|| 1169 (mCurDevice == AudioSystem::DEVICE_OUT_DGTL_DOCK_HEADSET)){ 1170 ALOGD("Routing everything from proxy for voipcall"); 1171 mALSADevice->route(&(*it), AudioSystem::DEVICE_IN_PROXY, AudioSystem::MODE_IN_COMMUNICATION); 1172 ALOGD("enabling VOIP in openInputstream, musbPlaybackState: %d", musbPlaybackState); 1173 startUsbPlaybackIfNotStarted(); 1174 musbPlaybackState |= USBPLAYBACKBIT_VOIPCALL; 1175 ALOGD("Starting recording in openoutputstream, musbRecordingState: %d", musbRecordingState); 1176 startUsbRecordingIfNotStarted(); 1177 musbRecordingState |= USBRECBIT_VOIPCALL; 1178 } else 1179#endif 1180 { 1181 mALSADevice->route(&(*it),mCurDevice, AudioSystem::MODE_IN_COMMUNICATION); 1182 } 1183 if(!strcmp(it->useCase, SND_USE_CASE_VERB_IP_VOICECALL)) { 1184 snd_use_case_set(mUcMgr, "_verb", SND_USE_CASE_VERB_IP_VOICECALL); 1185 } else { 1186 snd_use_case_set(mUcMgr, "_enamod", SND_USE_CASE_MOD_PLAY_VOIP); 1187 } 1188 if(sampleRate) { 1189 it->sampleRate = *sampleRate; 1190 } 1191 if(channels) 1192 it->channels = AudioSystem::popCount(*channels); 1193 err = mALSADevice->startVoipCall(&(*it)); 1194 if (err) { 1195 ALOGE("Error opening pcm input device"); 1196 return NULL; 1197 } 1198 } 1199 in = new AudioStreamInALSA(this, &(*it), acoustics); 1200 err = in->set(format, channels, sampleRate, devices); 1201 if(err == NO_ERROR) { 1202 mVoipStreamCount++; //increment VoipstreamCount only if success 1203 ALOGD("OpenInput mVoipStreamCount %d",mVoipStreamCount); 1204 } 1205 ALOGD("openInput: After Get alsahandle"); 1206 if (status) *status = err; 1207 return in; 1208 } else { 1209 alsa_handle_t alsa_handle; 1210 unsigned long bufferSize = MIN_CAPTURE_BUFFER_SIZE_PER_CH; 1211 1212 alsa_handle.module = mALSADevice; 1213 alsa_handle.bufferSize = bufferSize; 1214 alsa_handle.devices = devices; 1215 alsa_handle.handle = 0; 1216 alsa_handle.format = SNDRV_PCM_FORMAT_S16_LE; 1217 alsa_handle.channels = VOICE_CHANNEL_MODE; 1218 alsa_handle.channelMask = AUDIO_CHANNEL_IN_MONO; 1219 alsa_handle.sampleRate = android::AudioRecord::DEFAULT_SAMPLE_RATE; 1220 alsa_handle.latency = RECORD_LATENCY; 1221 alsa_handle.rxHandle = 0; 1222 alsa_handle.ucMgr = mUcMgr; 1223 snd_use_case_get(mUcMgr, "_verb", (const char **)&use_case); 1224 if ((use_case != NULL) && (strcmp(use_case, SND_USE_CASE_VERB_INACTIVE))) { 1225 if ((devices == AudioSystem::DEVICE_IN_VOICE_CALL) && 1226 (newMode == AudioSystem::MODE_IN_CALL)) { 1227 ALOGD("openInputStream: into incall recording, channels %d", *channels); 1228 mIncallMode = *channels; 1229 if ((*channels & AudioSystem::CHANNEL_IN_VOICE_UPLINK) && 1230 (*channels & AudioSystem::CHANNEL_IN_VOICE_DNLINK)) { 1231 if (mFusion3Platform) { 1232 mALSADevice->setVocRecMode(INCALL_REC_STEREO); 1233 strlcpy(alsa_handle.useCase, SND_USE_CASE_MOD_CAPTURE_VOICE, 1234 sizeof(alsa_handle.useCase)); 1235 } else { 1236 strlcpy(alsa_handle.useCase, SND_USE_CASE_MOD_CAPTURE_VOICE_UL_DL, 1237 sizeof(alsa_handle.useCase)); 1238 } 1239 } else if (*channels & AudioSystem::CHANNEL_IN_VOICE_DNLINK) { 1240 if (mFusion3Platform) { 1241 mALSADevice->setVocRecMode(INCALL_REC_MONO); 1242 strlcpy(alsa_handle.useCase, SND_USE_CASE_MOD_CAPTURE_VOICE, 1243 sizeof(alsa_handle.useCase)); 1244 } else { 1245 strlcpy(alsa_handle.useCase, SND_USE_CASE_MOD_CAPTURE_VOICE_DL, 1246 sizeof(alsa_handle.useCase)); 1247 } 1248 } 1249#ifdef QCOM_FM_ENABLED 1250 } else if((devices == AudioSystem::DEVICE_IN_FM_RX)) { 1251 strlcpy(alsa_handle.useCase, SND_USE_CASE_MOD_CAPTURE_FM, sizeof(alsa_handle.useCase)); 1252 } else if(devices == AudioSystem::DEVICE_IN_FM_RX_A2DP) { 1253 strlcpy(alsa_handle.useCase, SND_USE_CASE_MOD_CAPTURE_A2DP_FM, sizeof(alsa_handle.useCase)); 1254#endif 1255 } else { 1256 char value[128]; 1257 property_get("persist.audio.lowlatency.rec",value,"0"); 1258 if (!strcmp("true", value)) { 1259 strlcpy(alsa_handle.useCase, SND_USE_CASE_MOD_CAPTURE_LOWLATENCY_MUSIC, sizeof(alsa_handle.useCase)); 1260 } else { 1261 strlcpy(alsa_handle.useCase, SND_USE_CASE_MOD_CAPTURE_MUSIC, sizeof(alsa_handle.useCase)); 1262 } 1263 } 1264 } else { 1265 if ((devices == AudioSystem::DEVICE_IN_VOICE_CALL) && 1266 (newMode == AudioSystem::MODE_IN_CALL)) { 1267 ALOGD("openInputStream: incall recording, channels %d", *channels); 1268 mIncallMode = *channels; 1269 if ((*channels & AudioSystem::CHANNEL_IN_VOICE_UPLINK) && 1270 (*channels & AudioSystem::CHANNEL_IN_VOICE_DNLINK)) { 1271 if (mFusion3Platform) { 1272 mALSADevice->setVocRecMode(INCALL_REC_STEREO); 1273 strlcpy(alsa_handle.useCase, SND_USE_CASE_VERB_INCALL_REC, 1274 sizeof(alsa_handle.useCase)); 1275 } else { 1276 strlcpy(alsa_handle.useCase, SND_USE_CASE_VERB_UL_DL_REC, 1277 sizeof(alsa_handle.useCase)); 1278 } 1279 } else if (*channels & AudioSystem::CHANNEL_IN_VOICE_DNLINK) { 1280 if (mFusion3Platform) { 1281 mALSADevice->setVocRecMode(INCALL_REC_MONO); 1282 strlcpy(alsa_handle.useCase, SND_USE_CASE_VERB_INCALL_REC, 1283 sizeof(alsa_handle.useCase)); 1284 } else { 1285 strlcpy(alsa_handle.useCase, SND_USE_CASE_VERB_DL_REC, 1286 sizeof(alsa_handle.useCase)); 1287 } 1288 } 1289#ifdef QCOM_FM_ENABLED 1290 } else if(devices == AudioSystem::DEVICE_IN_FM_RX) { 1291 strlcpy(alsa_handle.useCase, SND_USE_CASE_VERB_FM_REC, sizeof(alsa_handle.useCase)); 1292 } else if (devices == AudioSystem::DEVICE_IN_FM_RX_A2DP) { 1293 strlcpy(alsa_handle.useCase, SND_USE_CASE_VERB_FM_A2DP_REC, sizeof(alsa_handle.useCase)); 1294#endif 1295 } else { 1296 char value[128]; 1297 property_get("persist.audio.lowlatency.rec",value,"0"); 1298 if (!strcmp("true", value)) { 1299 strlcpy(alsa_handle.useCase, SND_USE_CASE_VERB_HIFI_LOWLATENCY_REC, sizeof(alsa_handle.useCase)); 1300 } else { 1301 strlcpy(alsa_handle.useCase, SND_USE_CASE_VERB_HIFI_REC, sizeof(alsa_handle.useCase)); 1302 } 1303 } 1304 } 1305 free(use_case); 1306 mDeviceList.push_back(alsa_handle); 1307 ALSAHandleList::iterator it = mDeviceList.end(); 1308 it--; 1309 //update channel info before do routing 1310 if(channels) { 1311 it->channels = AudioSystem::popCount((*channels) & 1312 (AudioSystem::CHANNEL_IN_STEREO 1313 | AudioSystem::CHANNEL_IN_MONO 1314#ifdef QCOM_SSR_ENABLED 1315 | AudioSystem::CHANNEL_IN_5POINT1 1316#endif 1317 | AUDIO_CHANNEL_IN_FRONT_BACK)); 1318 it->channelMask = *channels; 1319 ALOGV("updated channel info: channels=%d channelMask %08x", 1320 it->channels, it->channelMask); 1321 } 1322 if (devices == AudioSystem::DEVICE_IN_VOICE_CALL){ 1323 /* Add current devices info to devices to do route */ 1324#ifdef QCOM_USBAUDIO_ENABLED 1325 if(mCurDevice == AudioSystem::DEVICE_OUT_ANLG_DOCK_HEADSET || 1326 mCurDevice == AudioSystem::DEVICE_OUT_DGTL_DOCK_HEADSET){ 1327 ALOGD("Routing everything from proxy for VOIP call"); 1328 route_devices = devices | AudioSystem::DEVICE_IN_PROXY; 1329 } else 1330#endif 1331 { 1332 route_devices = devices | mCurDevice; 1333 } 1334 mALSADevice->route(&(*it), route_devices, mode()); 1335 } else { 1336#ifdef QCOM_USBAUDIO_ENABLED 1337 if(devices & AudioSystem::DEVICE_IN_ANLG_DOCK_HEADSET || 1338 devices & AudioSystem::DEVICE_IN_PROXY) { 1339 devices |= AudioSystem::DEVICE_IN_PROXY; 1340 ALOGD("routing everything from proxy"); 1341 mALSADevice->route(&(*it), devices, mode()); 1342 } else 1343#endif 1344 { 1345 mALSADevice->route(&(*it), devices, mode()); 1346 } 1347 } 1348 if(!strcmp(it->useCase, SND_USE_CASE_VERB_HIFI_REC) || 1349 !strcmp(it->useCase, SND_USE_CASE_VERB_HIFI_LOWLATENCY_REC) || 1350#ifdef QCOM_FM_ENABLED 1351 !strcmp(it->useCase, SND_USE_CASE_VERB_FM_REC) || 1352 !strcmp(it->useCase, SND_USE_CASE_VERB_FM_A2DP_REC) || 1353#endif 1354 !strcmp(it->useCase, SND_USE_CASE_VERB_DL_REC) || 1355 !strcmp(it->useCase, SND_USE_CASE_VERB_UL_DL_REC) || 1356 !strcmp(it->useCase, SND_USE_CASE_VERB_INCALL_REC)) { 1357 snd_use_case_set(mUcMgr, "_verb", it->useCase); 1358 } else { 1359 snd_use_case_set(mUcMgr, "_enamod", it->useCase); 1360 } 1361 if(sampleRate) { 1362 it->sampleRate = *sampleRate; 1363 } 1364 if (!strncmp(it->useCase, SND_USE_CASE_VERB_HIFI_REC, strlen(SND_USE_CASE_VERB_HIFI_REC)) 1365 || !strncmp(it->useCase, SND_USE_CASE_MOD_CAPTURE_MUSIC, strlen(SND_USE_CASE_MOD_CAPTURE_MUSIC))) { 1366 ALOGV("OpenInoutStream: Use larger buffer size for 5.1(%s) recording ", it->useCase); 1367 it->bufferSize = getInputBufferSize(it->sampleRate,*format,it->channels); 1368 } 1369 err = mALSADevice->open(&(*it)); 1370 if (err) { 1371 ALOGE("Error opening pcm input device"); 1372 } else { 1373 in = new AudioStreamInALSA(this, &(*it), acoustics); 1374 err = in->set(format, channels, sampleRate, devices); 1375 } 1376 if (status) *status = err; 1377 return in; 1378 } 1379} 1380 1381void 1382AudioHardwareALSA::closeInputStream(AudioStreamIn* in) 1383{ 1384 delete in; 1385} 1386 1387status_t AudioHardwareALSA::setMicMute(bool state) 1388{ 1389 if (mMicMute != state) { 1390 mMicMute = state; 1391 ALOGD("setMicMute: mMicMute %d", mMicMute); 1392 if(mALSADevice) { 1393 mALSADevice->setMicMute(state); 1394 } 1395 } 1396 return NO_ERROR; 1397} 1398 1399status_t AudioHardwareALSA::getMicMute(bool *state) 1400{ 1401 *state = mMicMute; 1402 return NO_ERROR; 1403} 1404 1405status_t AudioHardwareALSA::dump(int fd, const Vector<String16>& args) 1406{ 1407 return NO_ERROR; 1408} 1409 1410size_t AudioHardwareALSA::getInputBufferSize(uint32_t sampleRate, int format, int channelCount) 1411{ 1412 size_t bufferSize = 0; 1413 if (format == AudioSystem::PCM_16_BIT) { 1414 if(sampleRate == 8000 || sampleRate == 16000 || sampleRate == 32000) { 1415 bufferSize = (sampleRate * channelCount * 20 * sizeof(int16_t)) / 1000; 1416 } else if (sampleRate == 11025 || sampleRate == 12000) { 1417 bufferSize = 256 * sizeof(int16_t) * channelCount; 1418 } else if (sampleRate == 22050 || sampleRate == 24000) { 1419 bufferSize = 512 * sizeof(int16_t) * channelCount; 1420 } else if (sampleRate == 44100 || sampleRate == 48000) { 1421 bufferSize = 1024 * sizeof(int16_t) * channelCount; 1422 } 1423 } else { 1424 ALOGE("getInputBufferSize bad format: %d", format); 1425 } 1426 return bufferSize; 1427} 1428 1429#ifdef QCOM_FM_ENABLED 1430void AudioHardwareALSA::handleFm(int device) 1431{ 1432int newMode = mode(); 1433 if(device & AudioSystem::DEVICE_OUT_FM && mIsFmActive == 0) { 1434 // Start FM Radio on current active device 1435 unsigned long bufferSize = FM_BUFFER_SIZE; 1436 alsa_handle_t alsa_handle; 1437 char *use_case; 1438 ALOGV("Start FM"); 1439 snd_use_case_get(mUcMgr, "_verb", (const char **)&use_case); 1440 if ((use_case == NULL) || (!strcmp(use_case, SND_USE_CASE_VERB_INACTIVE))) { 1441 strlcpy(alsa_handle.useCase, SND_USE_CASE_VERB_DIGITAL_RADIO, sizeof(alsa_handle.useCase)); 1442 } else { 1443 strlcpy(alsa_handle.useCase, SND_USE_CASE_MOD_PLAY_FM, sizeof(alsa_handle.useCase)); 1444 } 1445 free(use_case); 1446 1447 for (size_t b = 1; (bufferSize & ~b) != 0; b <<= 1) 1448 bufferSize &= ~b; 1449 alsa_handle.module = mALSADevice; 1450 alsa_handle.bufferSize = bufferSize; 1451 alsa_handle.devices = device; 1452 alsa_handle.handle = 0; 1453 alsa_handle.format = SNDRV_PCM_FORMAT_S16_LE; 1454 alsa_handle.channels = DEFAULT_CHANNEL_MODE; 1455 alsa_handle.channelMask = AUDIO_CHANNEL_OUT_STEREO; 1456 alsa_handle.sampleRate = DEFAULT_SAMPLING_RATE; 1457 alsa_handle.latency = VOICE_LATENCY; 1458 alsa_handle.rxHandle = 0; 1459 alsa_handle.ucMgr = mUcMgr; 1460 mIsFmActive = 1; 1461 mDeviceList.push_back(alsa_handle); 1462 ALSAHandleList::iterator it = mDeviceList.end(); 1463 it--; 1464 if((device & AudioSystem::DEVICE_OUT_ANLG_DOCK_HEADSET)|| 1465 (device & AudioSystem::DEVICE_OUT_DGTL_DOCK_HEADSET)){ 1466 device |= AudioSystem::DEVICE_OUT_PROXY; 1467 alsa_handle.devices = AudioSystem::DEVICE_OUT_PROXY; 1468 ALOGD("Routing to proxy for FM case"); 1469 } 1470 mALSADevice->route(&(*it), (uint32_t)device, newMode); 1471 if(!strcmp(it->useCase, SND_USE_CASE_VERB_DIGITAL_RADIO)) { 1472 snd_use_case_set(mUcMgr, "_verb", SND_USE_CASE_VERB_DIGITAL_RADIO); 1473 } else { 1474 snd_use_case_set(mUcMgr, "_enamod", SND_USE_CASE_MOD_PLAY_FM); 1475 } 1476 mALSADevice->startFm(&(*it)); 1477 if((device & AudioSystem::DEVICE_OUT_ANLG_DOCK_HEADSET)|| 1478 (device & AudioSystem::DEVICE_OUT_DGTL_DOCK_HEADSET)){ 1479 ALOGD("Starting FM, musbPlaybackState %d", musbPlaybackState); 1480 startUsbPlaybackIfNotStarted(); 1481 musbPlaybackState |= USBPLAYBACKBIT_FM; 1482 } 1483 } else if (!(device & AudioSystem::DEVICE_OUT_FM) && mIsFmActive == 1) { 1484 //i Stop FM Radio 1485 ALOGV("Stop FM"); 1486 for(ALSAHandleList::iterator it = mDeviceList.begin(); 1487 it != mDeviceList.end(); ++it) { 1488 if((!strcmp(it->useCase, SND_USE_CASE_VERB_DIGITAL_RADIO)) || 1489 (!strcmp(it->useCase, SND_USE_CASE_MOD_PLAY_FM))) { 1490 mALSADevice->close(&(*it)); 1491 //mALSADevice->route(&(*it), (uint32_t)device, newMode); 1492 mDeviceList.erase(it); 1493 break; 1494 } 1495 } 1496 mIsFmActive = 0; 1497 musbPlaybackState &= ~USBPLAYBACKBIT_FM; 1498 if((device & AudioSystem::DEVICE_OUT_ANLG_DOCK_HEADSET)|| 1499 (device & AudioSystem::DEVICE_OUT_DGTL_DOCK_HEADSET)){ 1500 closeUsbPlaybackIfNothingActive(); 1501 } 1502 } 1503} 1504#endif 1505 1506void AudioHardwareALSA::disableVoiceCall(char* verb, char* modifier, int mode, int device) 1507{ 1508 for(ALSAHandleList::iterator it = mDeviceList.begin(); 1509 it != mDeviceList.end(); ++it) { 1510 if((!strcmp(it->useCase, verb)) || 1511 (!strcmp(it->useCase, modifier))) { 1512 ALOGV("Disabling voice call"); 1513 mALSADevice->close(&(*it)); 1514 mALSADevice->route(&(*it), (uint32_t)device, mode); 1515 mDeviceList.erase(it); 1516 break; 1517 } 1518 } 1519#ifdef QCOM_USBAUDIO_ENABLED 1520 if(musbPlaybackState & USBPLAYBACKBIT_VOICECALL) { 1521 ALOGD("Voice call ended on USB"); 1522 musbPlaybackState &= ~USBPLAYBACKBIT_VOICECALL; 1523 musbRecordingState &= ~USBRECBIT_VOICECALL; 1524 closeUsbRecordingIfNothingActive(); 1525 closeUsbPlaybackIfNothingActive(); 1526 } 1527#endif 1528} 1529void AudioHardwareALSA::enableVoiceCall(char* verb, char* modifier, int mode, int device) 1530{ 1531// Start voice call 1532unsigned long bufferSize = DEFAULT_VOICE_BUFFER_SIZE; 1533alsa_handle_t alsa_handle; 1534char *use_case; 1535 snd_use_case_get(mUcMgr, "_verb", (const char **)&use_case); 1536 if ((use_case == NULL) || (!strcmp(use_case, SND_USE_CASE_VERB_INACTIVE))) { 1537 strlcpy(alsa_handle.useCase, verb, sizeof(alsa_handle.useCase)); 1538 } else { 1539 strlcpy(alsa_handle.useCase, modifier, sizeof(alsa_handle.useCase)); 1540 } 1541 free(use_case); 1542 1543 for (size_t b = 1; (bufferSize & ~b) != 0; b <<= 1) 1544 bufferSize &= ~b; 1545 alsa_handle.module = mALSADevice; 1546 alsa_handle.bufferSize = bufferSize; 1547 alsa_handle.devices = device; 1548 alsa_handle.handle = 0; 1549 alsa_handle.format = SNDRV_PCM_FORMAT_S16_LE; 1550 alsa_handle.channels = VOICE_CHANNEL_MODE; 1551 alsa_handle.channelMask = AUDIO_CHANNEL_IN_MONO; 1552 alsa_handle.sampleRate = VOICE_SAMPLING_RATE; 1553 alsa_handle.latency = VOICE_LATENCY; 1554 alsa_handle.rxHandle = 0; 1555 alsa_handle.ucMgr = mUcMgr; 1556 mDeviceList.push_back(alsa_handle); 1557 ALSAHandleList::iterator it = mDeviceList.end(); 1558 it--; 1559#ifdef QCOM_USBAUDIO_ENABLED 1560 if((device & AudioSystem::DEVICE_OUT_ANLG_DOCK_HEADSET)|| 1561 (device & AudioSystem::DEVICE_OUT_DGTL_DOCK_HEADSET)){ 1562 device |= AudioSystem::DEVICE_OUT_PROXY; 1563 alsa_handle.devices = device; 1564 } 1565#endif 1566 mALSADevice->route(&(*it), (uint32_t)device, mode); 1567 if (!strcmp(it->useCase, verb)) { 1568 snd_use_case_set(mUcMgr, "_verb", verb); 1569 } else { 1570 snd_use_case_set(mUcMgr, "_enamod", modifier); 1571 } 1572 mALSADevice->startVoiceCall(&(*it)); 1573#ifdef QCOM_USBAUDIO_ENABLED 1574 if((device & AudioSystem::DEVICE_OUT_ANLG_DOCK_HEADSET)|| 1575 (device & AudioSystem::DEVICE_OUT_DGTL_DOCK_HEADSET)){ 1576 startUsbRecordingIfNotStarted(); 1577 startUsbPlaybackIfNotStarted(); 1578 musbPlaybackState |= USBPLAYBACKBIT_VOICECALL; 1579 musbRecordingState |= USBRECBIT_VOICECALL; 1580 } 1581#endif 1582} 1583 1584bool AudioHardwareALSA::routeVoiceCall(int device, int newMode) 1585{ 1586int csCallState = mCallState&0xF; 1587 bool isRouted = false; 1588 switch (csCallState) { 1589 case CS_INACTIVE: 1590 if (mCSCallActive != CS_INACTIVE) { 1591 ALOGD("doRouting: Disabling voice call"); 1592 disableVoiceCall((char *)SND_USE_CASE_VERB_VOICECALL, 1593 (char *)SND_USE_CASE_MOD_PLAY_VOICE, newMode, device); 1594 isRouted = true; 1595 mCSCallActive = CS_INACTIVE; 1596 } 1597 break; 1598 case CS_ACTIVE: 1599 if (mCSCallActive == CS_INACTIVE) { 1600 ALOGD("doRouting: Enabling CS voice call "); 1601 enableVoiceCall((char *)SND_USE_CASE_VERB_VOICECALL, 1602 (char *)SND_USE_CASE_MOD_PLAY_VOICE, newMode, device); 1603 isRouted = true; 1604 mCSCallActive = CS_ACTIVE; 1605 } else if (mCSCallActive == CS_HOLD) { 1606 ALOGD("doRouting: Resume voice call from hold state"); 1607 ALSAHandleList::iterator vt_it; 1608 for(vt_it = mDeviceList.begin(); 1609 vt_it != mDeviceList.end(); ++vt_it) { 1610 if((!strncmp(vt_it->useCase, SND_USE_CASE_VERB_VOICECALL, 1611 strlen(SND_USE_CASE_VERB_VOICECALL))) || 1612 (!strncmp(vt_it->useCase, SND_USE_CASE_MOD_PLAY_VOICE, 1613 strlen(SND_USE_CASE_MOD_PLAY_VOICE)))) { 1614 alsa_handle_t *handle = (alsa_handle_t *)(&(*vt_it)); 1615 mCSCallActive = CS_ACTIVE; 1616 if(ioctl((int)handle->handle->fd,SNDRV_PCM_IOCTL_PAUSE,0)<0) 1617 ALOGE("VoLTE resume failed"); 1618 break; 1619 } 1620 } 1621 } 1622 break; 1623 case CS_HOLD: 1624 if (mCSCallActive == CS_ACTIVE) { 1625 ALOGD("doRouting: Voice call going to Hold"); 1626 ALSAHandleList::iterator vt_it; 1627 for(vt_it = mDeviceList.begin(); 1628 vt_it != mDeviceList.end(); ++vt_it) { 1629 if((!strncmp(vt_it->useCase, SND_USE_CASE_VERB_VOICECALL, 1630 strlen(SND_USE_CASE_VERB_VOICECALL))) || 1631 (!strncmp(vt_it->useCase, SND_USE_CASE_MOD_PLAY_VOICE, 1632 strlen(SND_USE_CASE_MOD_PLAY_VOICE)))) { 1633 mCSCallActive = CS_HOLD; 1634 alsa_handle_t *handle = (alsa_handle_t *)(&(*vt_it)); 1635 if(ioctl((int)handle->handle->fd,SNDRV_PCM_IOCTL_PAUSE,1)<0) 1636 ALOGE("Voice pause failed"); 1637 break; 1638 } 1639 } 1640 } 1641 break; 1642 } 1643 return isRouted; 1644} 1645bool AudioHardwareALSA::routeVoLTECall(int device, int newMode) 1646{ 1647int volteCallState = mCallState&0xF0; 1648bool isRouted = false; 1649switch (volteCallState) { 1650 case IMS_INACTIVE: 1651 if (mVolteCallActive != IMS_INACTIVE) { 1652 ALOGD("doRouting: Disabling IMS call"); 1653 disableVoiceCall((char *)SND_USE_CASE_VERB_VOLTE, 1654 (char *)SND_USE_CASE_MOD_PLAY_VOLTE, newMode, device); 1655 isRouted = true; 1656 mVolteCallActive = IMS_INACTIVE; 1657 } 1658 break; 1659 case IMS_ACTIVE: 1660 if (mVolteCallActive == IMS_INACTIVE) { 1661 ALOGD("doRouting: Enabling IMS voice call "); 1662 enableVoiceCall((char *)SND_USE_CASE_VERB_VOLTE, 1663 (char *)SND_USE_CASE_MOD_PLAY_VOLTE, newMode, device); 1664 isRouted = true; 1665 mVolteCallActive = IMS_ACTIVE; 1666 } else if (mVolteCallActive == IMS_HOLD) { 1667 ALOGD("doRouting: Resume IMS call from hold state"); 1668 ALSAHandleList::iterator vt_it; 1669 for(vt_it = mDeviceList.begin(); 1670 vt_it != mDeviceList.end(); ++vt_it) { 1671 if((!strncmp(vt_it->useCase, SND_USE_CASE_VERB_VOLTE, 1672 strlen(SND_USE_CASE_VERB_VOLTE))) || 1673 (!strncmp(vt_it->useCase, SND_USE_CASE_MOD_PLAY_VOLTE, 1674 strlen(SND_USE_CASE_MOD_PLAY_VOLTE)))) { 1675 alsa_handle_t *handle = (alsa_handle_t *)(&(*vt_it)); 1676 mVolteCallActive = IMS_ACTIVE; 1677 if(ioctl((int)handle->handle->fd,SNDRV_PCM_IOCTL_PAUSE,0)<0) 1678 ALOGE("VoLTE resume failed"); 1679 break; 1680 } 1681 } 1682 } 1683 break; 1684 case IMS_HOLD: 1685 if (mVolteCallActive == IMS_ACTIVE) { 1686 ALOGD("doRouting: IMS ACTIVE going to HOLD"); 1687 ALSAHandleList::iterator vt_it; 1688 for(vt_it = mDeviceList.begin(); 1689 vt_it != mDeviceList.end(); ++vt_it) { 1690 if((!strncmp(vt_it->useCase, SND_USE_CASE_VERB_VOLTE, 1691 strlen(SND_USE_CASE_VERB_VOLTE))) || 1692 (!strncmp(vt_it->useCase, SND_USE_CASE_MOD_PLAY_VOLTE, 1693 strlen(SND_USE_CASE_MOD_PLAY_VOLTE)))) { 1694 mVolteCallActive = IMS_HOLD; 1695 alsa_handle_t *handle = (alsa_handle_t *)(&(*vt_it)); 1696 if(ioctl((int)handle->handle->fd,SNDRV_PCM_IOCTL_PAUSE,1)<0) 1697 ALOGE("VoLTE Pause failed"); 1698 break; 1699 } 1700 } 1701 } 1702 break; 1703 } 1704 return isRouted; 1705} 1706 1707} // namespace android_audio_legacy 1708