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
47 extern "C"
48 {
49 //
50 // Function for dlsym() to look up for creating a new AudioHardwareInterface.
51 //
createAudioHardware(void)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
67 namespace android_audio_legacy
68 {
69
70 // ----------------------------------------------------------------------------
71
create()72 AudioHardwareInterface *AudioHardwareALSA::create() {
73 return new AudioHardwareALSA();
74 }
75
AudioHardwareALSA()76 AudioHardwareALSA::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
~AudioHardwareALSA()207 AudioHardwareALSA::~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
initCheck()249 status_t AudioHardwareALSA::initCheck()
250 {
251 if (!mALSADevice)
252 return NO_INIT;
253
254 return NO_ERROR;
255 }
256
setVoiceVolume(float v)257 status_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
setFmVolume(float value)292 status_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
setMasterVolume(float volume)316 status_t AudioHardwareALSA::setMasterVolume(float volume)
317 {
318 return NO_ERROR;
319 }
320
setMode(int mode)321 status_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
setParameters(const String8 & keyValuePairs)338 status_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
getParameters(const String8 & keys)514 String8 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
closeUSBPlayback()559 void AudioHardwareALSA::closeUSBPlayback()
560 {
561 ALOGV("closeUSBPlayback, musbPlaybackState: %d", musbPlaybackState);
562 musbPlaybackState = 0;
563 mAudioUsbALSA->exitPlaybackThread(SIGNAL_EVENT_KILLTHREAD);
564 }
565
closeUSBRecording()566 void AudioHardwareALSA::closeUSBRecording()
567 {
568 ALOGV("closeUSBRecording");
569 musbRecordingState = 0;
570 mAudioUsbALSA->exitRecordingThread(SIGNAL_EVENT_KILLTHREAD);
571 }
572
closeUsbPlaybackIfNothingActive()573 void AudioHardwareALSA::closeUsbPlaybackIfNothingActive(){
574 ALOGV("closeUsbPlaybackIfNothingActive, musbPlaybackState: %d", musbPlaybackState);
575 if(!musbPlaybackState && mAudioUsbALSA != NULL) {
576 mAudioUsbALSA->exitPlaybackThread(SIGNAL_EVENT_TIMEOUT);
577 }
578 }
579
closeUsbRecordingIfNothingActive()580 void 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
startUsbPlaybackIfNotStarted()588 void 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
startUsbRecordingIfNotStarted()596 void 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
doRouting(int device)605 void 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
getVoipMode(int format)689 uint32_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
720 AudioStreamOut *
openOutputStream(uint32_t devices,int * format,uint32_t * channels,uint32_t * sampleRate,status_t * status)721 AudioHardwareALSA::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.sampleRate = *sampleRate;
783 alsa_handle.latency = VOIP_PLAYBACK_LATENCY;
784 alsa_handle.rxHandle = 0;
785 alsa_handle.ucMgr = mUcMgr;
786 mALSADevice->setVoipConfig(getVoipMode(*format), mVoipBitRate);
787 char *use_case;
788 snd_use_case_get(mUcMgr, "_verb", (const char **)&use_case);
789 if ((use_case == NULL) || (!strcmp(use_case, SND_USE_CASE_VERB_INACTIVE))) {
790 strlcpy(alsa_handle.useCase, SND_USE_CASE_VERB_IP_VOICECALL, sizeof(alsa_handle.useCase));
791 } else {
792 strlcpy(alsa_handle.useCase, SND_USE_CASE_MOD_PLAY_VOIP, sizeof(alsa_handle.useCase));
793 }
794 free(use_case);
795 mDeviceList.push_back(alsa_handle);
796 it = mDeviceList.end();
797 it--;
798 ALOGV("openoutput: mALSADevice->route useCase %s mCurDevice %d mVoipStreamCount %d mode %d", it->useCase,mCurDevice,mVoipStreamCount, mode());
799 if((mCurDevice & AudioSystem::DEVICE_OUT_ANLG_DOCK_HEADSET)||
800 (mCurDevice & AudioSystem::DEVICE_OUT_DGTL_DOCK_HEADSET)||
801 (mCurDevice & AudioSystem::DEVICE_OUT_PROXY)){
802 ALOGD("Routing to proxy for normal voip call in openOutputStream");
803 mCurDevice |= AudioSystem::DEVICE_OUT_PROXY;
804 alsa_handle.devices = AudioSystem::DEVICE_OUT_PROXY;
805 mALSADevice->route(&(*it), mCurDevice, AudioSystem::MODE_IN_COMMUNICATION);
806 ALOGD("enabling VOIP in openoutputstream, musbPlaybackState: %d", musbPlaybackState);
807 startUsbPlaybackIfNotStarted();
808 musbPlaybackState |= USBPLAYBACKBIT_VOIPCALL;
809 ALOGD("Starting recording in openoutputstream, musbRecordingState: %d", musbRecordingState);
810 startUsbRecordingIfNotStarted();
811 musbRecordingState |= USBRECBIT_VOIPCALL;
812 } else{
813 mALSADevice->route(&(*it), mCurDevice, AudioSystem::MODE_IN_COMMUNICATION);
814 }
815 if(!strcmp(it->useCase, SND_USE_CASE_VERB_IP_VOICECALL)) {
816 snd_use_case_set(mUcMgr, "_verb", SND_USE_CASE_VERB_IP_VOICECALL);
817 } else {
818 snd_use_case_set(mUcMgr, "_enamod", SND_USE_CASE_MOD_PLAY_VOIP);
819 }
820 err = mALSADevice->startVoipCall(&(*it));
821 if (err) {
822 ALOGE("Device open failed");
823 return NULL;
824 }
825 }
826 out = new AudioStreamOutALSA(this, &(*it));
827 err = out->set(format, channels, sampleRate, devices);
828 if(err == NO_ERROR) {
829 mVoipStreamCount++; //increment VoipstreamCount only if success
830 ALOGD("openoutput mVoipStreamCount %d",mVoipStreamCount);
831 }
832 if (status) *status = err;
833 return out;
834 } else
835 #endif
836 if ((flag & AUDIO_OUTPUT_FLAG_DIRECT) &&
837 (devices == AudioSystem::DEVICE_OUT_AUX_DIGITAL)) {
838 ALOGD("Multi channel PCM");
839 alsa_handle_t alsa_handle;
840 EDID_AUDIO_INFO info = { 0 };
841
842 alsa_handle.module = mALSADevice;
843 alsa_handle.devices = devices;
844 alsa_handle.handle = 0;
845 alsa_handle.format = SNDRV_PCM_FORMAT_S16_LE;
846
847 if (!AudioUtil::getHDMIAudioSinkCaps(&info)) {
848 ALOGE("openOutputStream: Failed to get HDMI sink capabilities");
849 return NULL;
850 }
851 if (0 == *channels) {
852 alsa_handle.channels = info.AudioBlocksArray[info.nAudioBlocks-1].nChannels;
853 if (alsa_handle.channels > 6) {
854 alsa_handle.channels = 6;
855 }
856 *channels = audio_channel_out_mask_from_count(alsa_handle.channels);
857 } else {
858 alsa_handle.channels = AudioSystem::popCount(*channels);
859 }
860 if (6 == alsa_handle.channels) {
861 alsa_handle.bufferSize = DEFAULT_MULTI_CHANNEL_BUF_SIZE;
862 } else {
863 alsa_handle.bufferSize = DEFAULT_BUFFER_SIZE;
864 }
865 if (0 == *sampleRate) {
866 alsa_handle.sampleRate = info.AudioBlocksArray[info.nAudioBlocks-1].nSamplingFreq;
867 *sampleRate = alsa_handle.sampleRate;
868 } else {
869 alsa_handle.sampleRate = *sampleRate;
870 }
871 alsa_handle.latency = PLAYBACK_LATENCY;
872 alsa_handle.rxHandle = 0;
873 alsa_handle.ucMgr = mUcMgr;
874 ALOGD("alsa_handle.channels %d alsa_handle.sampleRate %d",alsa_handle.channels,alsa_handle.sampleRate);
875
876 char *use_case;
877 snd_use_case_get(mUcMgr, "_verb", (const char **)&use_case);
878 if ((use_case == NULL) || (!strcmp(use_case, SND_USE_CASE_VERB_INACTIVE))) {
879 strlcpy(alsa_handle.useCase, SND_USE_CASE_VERB_HIFI2 , sizeof(alsa_handle.useCase));
880 } else {
881 strlcpy(alsa_handle.useCase, SND_USE_CASE_MOD_PLAY_MUSIC2, sizeof(alsa_handle.useCase));
882 }
883 free(use_case);
884 mDeviceList.push_back(alsa_handle);
885 ALSAHandleList::iterator it = mDeviceList.end();
886 it--;
887 ALOGD("it->useCase %s", it->useCase);
888 mALSADevice->route(&(*it), devices, mode());
889 if(!strcmp(it->useCase, SND_USE_CASE_VERB_HIFI2)) {
890 snd_use_case_set(mUcMgr, "_verb", SND_USE_CASE_VERB_HIFI2 );
891 } else {
892 snd_use_case_set(mUcMgr, "_enamod", SND_USE_CASE_MOD_PLAY_MUSIC2);
893 }
894 ALOGD("channels: %d", AudioSystem::popCount(*channels));
895 err = mALSADevice->open(&(*it));
896
897 if (err) {
898 ALOGE("Device open failed err:%d",err);
899 } else {
900 out = new AudioStreamOutALSA(this, &(*it));
901 err = out->set(format, channels, sampleRate, devices);
902 }
903 if (status) *status = err;
904 return out;
905 } else {
906
907 alsa_handle_t alsa_handle;
908 unsigned long bufferSize = DEFAULT_BUFFER_SIZE;
909
910 for (size_t b = 1; (bufferSize & ~b) != 0; b <<= 1)
911 bufferSize &= ~b;
912
913 alsa_handle.module = mALSADevice;
914 alsa_handle.bufferSize = bufferSize;
915 alsa_handle.devices = devices;
916 alsa_handle.handle = 0;
917 alsa_handle.format = SNDRV_PCM_FORMAT_S16_LE;
918 alsa_handle.channels = DEFAULT_CHANNEL_MODE;
919 alsa_handle.sampleRate = DEFAULT_SAMPLING_RATE;
920 alsa_handle.latency = PLAYBACK_LATENCY;
921 alsa_handle.rxHandle = 0;
922 alsa_handle.ucMgr = mUcMgr;
923 alsa_handle.isDeepbufferOutput = false;
924
925 char *use_case;
926 snd_use_case_get(mUcMgr, "_verb", (const char **)&use_case);
927
928 if (flag & AUDIO_OUTPUT_FLAG_DEEP_BUFFER) {
929 ALOGD("openOutputStream: DeepBuffer Output");
930 alsa_handle.isDeepbufferOutput = true;
931 if ((use_case == NULL) || (!strcmp(use_case, SND_USE_CASE_VERB_INACTIVE))) {
932 strlcpy(alsa_handle.useCase, SND_USE_CASE_VERB_HIFI, sizeof(alsa_handle.useCase));
933 } else {
934 strlcpy(alsa_handle.useCase, SND_USE_CASE_MOD_PLAY_MUSIC, sizeof(alsa_handle.useCase));
935 }
936 } else {
937 ALOGD("openOutputStream: Lowlatency Output");
938 alsa_handle.bufferSize = PLAYBACK_LOW_LATENCY_BUFFER_SIZE;
939 alsa_handle.latency = PLAYBACK_LOW_LATENCY_MEASURED;
940 if ((use_case == NULL) || (!strcmp(use_case, SND_USE_CASE_VERB_INACTIVE))) {
941 strlcpy(alsa_handle.useCase, SND_USE_CASE_VERB_HIFI_LOWLATENCY_MUSIC, sizeof(alsa_handle.useCase));
942 } else {
943 strlcpy(alsa_handle.useCase, SND_USE_CASE_MOD_PLAY_LOWLATENCY_MUSIC, sizeof(alsa_handle.useCase));
944 }
945 }
946 free(use_case);
947 mDeviceList.push_back(alsa_handle);
948 ALSAHandleList::iterator it = mDeviceList.end();
949 it--;
950 ALOGV("useCase %s", it->useCase);
951 #ifdef QCOM_USBAUDIO_ENABLED
952 if((devices & AudioSystem::DEVICE_OUT_ANLG_DOCK_HEADSET)||
953 (devices & AudioSystem::DEVICE_OUT_DGTL_DOCK_HEADSET)){
954 ALOGD("Routing to proxy for normal playback in openOutputStream");
955 devices |= AudioSystem::DEVICE_OUT_PROXY;
956 }
957 #endif
958 mALSADevice->route(&(*it), devices, mode());
959 if (flag & AUDIO_OUTPUT_FLAG_DEEP_BUFFER) {
960 if(!strcmp(it->useCase, SND_USE_CASE_VERB_HIFI)) {
961 snd_use_case_set(mUcMgr, "_verb", SND_USE_CASE_VERB_HIFI);
962 } else {
963 snd_use_case_set(mUcMgr, "_enamod", SND_USE_CASE_MOD_PLAY_MUSIC);
964 }
965 } else {
966 if(!strcmp(it->useCase, SND_USE_CASE_VERB_HIFI_LOWLATENCY_MUSIC)) {
967 snd_use_case_set(mUcMgr, "_verb", SND_USE_CASE_VERB_HIFI_LOWLATENCY_MUSIC);
968 } else {
969 snd_use_case_set(mUcMgr, "_enamod", SND_USE_CASE_MOD_PLAY_LOWLATENCY_MUSIC);
970 }
971 }
972 err = mALSADevice->open(&(*it));
973 if (err) {
974 ALOGE("Device open failed");
975 } else {
976 out = new AudioStreamOutALSA(this, &(*it));
977 err = out->set(format, channels, sampleRate, devices);
978 }
979
980 if (status) *status = err;
981 return out;
982 }
983 }
984
985 void
closeOutputStream(AudioStreamOut * out)986 AudioHardwareALSA::closeOutputStream(AudioStreamOut* out)
987 {
988 delete out;
989 }
990
991 #ifdef QCOM_TUNNEL_LPA_ENABLED
992 AudioStreamOut *
openOutputSession(uint32_t devices,int * format,status_t * status,int sessionId,uint32_t samplingRate,uint32_t channels)993 AudioHardwareALSA::openOutputSession(uint32_t devices,
994 int *format,
995 status_t *status,
996 int sessionId,
997 uint32_t samplingRate,
998 uint32_t channels)
999 {
1000 Mutex::Autolock autoLock(mLock);
1001 ALOGD("openOutputSession = %d" ,sessionId);
1002 AudioStreamOutALSA *out = 0;
1003 status_t err = BAD_VALUE;
1004
1005 alsa_handle_t alsa_handle;
1006 unsigned long bufferSize = DEFAULT_BUFFER_SIZE;
1007
1008 for (size_t b = 1; (bufferSize & ~b) != 0; b <<= 1)
1009 bufferSize &= ~b;
1010
1011 alsa_handle.module = mALSADevice;
1012 alsa_handle.bufferSize = bufferSize;
1013 alsa_handle.devices = devices;
1014 alsa_handle.handle = 0;
1015 alsa_handle.format = SNDRV_PCM_FORMAT_S16_LE;
1016 alsa_handle.channels = DEFAULT_CHANNEL_MODE;
1017 alsa_handle.sampleRate = DEFAULT_SAMPLING_RATE;
1018 alsa_handle.latency = VOICE_LATENCY;
1019 alsa_handle.rxHandle = 0;
1020 alsa_handle.ucMgr = mUcMgr;
1021
1022 char *use_case;
1023 if(sessionId == TUNNEL_SESSION_ID) {
1024 snd_use_case_get(mUcMgr, "_verb", (const char **)&use_case);
1025 if ((use_case == NULL) || (!strcmp(use_case, SND_USE_CASE_VERB_INACTIVE))) {
1026 strlcpy(alsa_handle.useCase, SND_USE_CASE_VERB_HIFI_TUNNEL, sizeof(alsa_handle.useCase));
1027 } else {
1028 strlcpy(alsa_handle.useCase, SND_USE_CASE_MOD_PLAY_TUNNEL, sizeof(alsa_handle.useCase));
1029 }
1030 } else {
1031 snd_use_case_get(mUcMgr, "_verb", (const char **)&use_case);
1032 if ((use_case == NULL) || (!strcmp(use_case, SND_USE_CASE_VERB_INACTIVE))) {
1033 strlcpy(alsa_handle.useCase, SND_USE_CASE_VERB_HIFI_LOW_POWER, sizeof(alsa_handle.useCase));
1034 } else {
1035 strlcpy(alsa_handle.useCase, SND_USE_CASE_MOD_PLAY_LPA, sizeof(alsa_handle.useCase));
1036 }
1037 }
1038 free(use_case);
1039 mDeviceList.push_back(alsa_handle);
1040 ALSAHandleList::iterator it = mDeviceList.end();
1041 it--;
1042 ALOGD("useCase %s", it->useCase);
1043 #ifdef QCOM_USBAUDIO_ENABLED
1044 if((devices & AudioSystem::DEVICE_OUT_ANLG_DOCK_HEADSET)||
1045 (devices & AudioSystem::DEVICE_OUT_DGTL_DOCK_HEADSET)){
1046 ALOGD("Routing to proxy for LPA in openOutputSession");
1047 devices |= AudioSystem::DEVICE_OUT_PROXY;
1048 mALSADevice->route(&(*it), devices, mode());
1049 devices = AudioSystem::DEVICE_OUT_ANLG_DOCK_HEADSET;
1050 ALOGD("Starting USBPlayback for LPA");
1051 startUsbPlaybackIfNotStarted();
1052 musbPlaybackState |= USBPLAYBACKBIT_LPA;
1053 } else
1054 #endif
1055 {
1056 mALSADevice->route(&(*it), devices, mode());
1057 }
1058 if(sessionId == TUNNEL_SESSION_ID) {
1059 if(!strcmp(it->useCase, SND_USE_CASE_VERB_HIFI_TUNNEL)) {
1060 snd_use_case_set(mUcMgr, "_verb", SND_USE_CASE_VERB_HIFI_TUNNEL);
1061 } else {
1062 snd_use_case_set(mUcMgr, "_enamod", SND_USE_CASE_MOD_PLAY_TUNNEL);
1063 }
1064 }
1065 else {
1066 if(!strcmp(it->useCase, SND_USE_CASE_VERB_HIFI_LOW_POWER)) {
1067 snd_use_case_set(mUcMgr, "_verb", SND_USE_CASE_VERB_HIFI_LOW_POWER);
1068 } else {
1069 snd_use_case_set(mUcMgr, "_enamod", SND_USE_CASE_MOD_PLAY_LPA);
1070 }
1071 }
1072 err = mALSADevice->open(&(*it));
1073 out = new AudioStreamOutALSA(this, &(*it));
1074
1075 if (status) *status = err;
1076 return out;
1077 }
1078
1079 void
closeOutputSession(AudioStreamOut * out)1080 AudioHardwareALSA::closeOutputSession(AudioStreamOut* out)
1081 {
1082 delete out;
1083 }
1084 #endif
1085
1086 AudioStreamIn *
openInputStream(uint32_t devices,int * format,uint32_t * channels,uint32_t * sampleRate,status_t * status,AudioSystem::audio_in_acoustics acoustics)1087 AudioHardwareALSA::openInputStream(uint32_t devices,
1088 int *format,
1089 uint32_t *channels,
1090 uint32_t *sampleRate,
1091 status_t *status,
1092 AudioSystem::audio_in_acoustics acoustics)
1093 {
1094 Mutex::Autolock autoLock(mLock);
1095 char *use_case;
1096 int newMode = mode();
1097 uint32_t route_devices;
1098
1099 status_t err = BAD_VALUE;
1100 AudioStreamInALSA *in = 0;
1101 ALSAHandleList::iterator it;
1102
1103 ALOGD("openInputStream: devices 0x%x channels %d sampleRate %d", devices, *channels, *sampleRate);
1104 if (devices & (devices - 1)) {
1105 if (status) *status = err;
1106 return in;
1107 }
1108
1109 if((devices == AudioSystem::DEVICE_IN_COMMUNICATION) &&
1110 ((*sampleRate == VOIP_SAMPLING_RATE_8K) || (*sampleRate == VOIP_SAMPLING_RATE_16K))) {
1111 bool voipstream_active = false;
1112 for(it = mDeviceList.begin();
1113 it != mDeviceList.end(); ++it) {
1114 if((!strcmp(it->useCase, SND_USE_CASE_VERB_IP_VOICECALL)) ||
1115 (!strcmp(it->useCase, SND_USE_CASE_MOD_PLAY_VOIP))) {
1116 ALOGD("openInput: it->rxHandle %p it->handle %p",it->rxHandle,it->handle);
1117 voipstream_active = true;
1118 break;
1119 }
1120 }
1121 if(voipstream_active == false) {
1122 mVoipStreamCount = 0;
1123 alsa_handle_t alsa_handle;
1124 unsigned long bufferSize;
1125 if(*sampleRate == VOIP_SAMPLING_RATE_8K) {
1126 bufferSize = VOIP_BUFFER_SIZE_8K;
1127 }
1128 else if(*sampleRate == VOIP_SAMPLING_RATE_16K) {
1129 bufferSize = VOIP_BUFFER_SIZE_16K;
1130 }
1131 else {
1132 ALOGE("unsupported samplerate %d for voip",*sampleRate);
1133 if (status) *status = err;
1134 return in;
1135 }
1136 alsa_handle.module = mALSADevice;
1137 alsa_handle.bufferSize = bufferSize;
1138 alsa_handle.devices = devices;
1139 alsa_handle.handle = 0;
1140 if(*format == AudioSystem::PCM_16_BIT)
1141 alsa_handle.format = SNDRV_PCM_FORMAT_S16_LE;
1142 else
1143 alsa_handle.format = *format;
1144 alsa_handle.channels = VOIP_DEFAULT_CHANNEL_MODE;
1145 alsa_handle.sampleRate = *sampleRate;
1146 alsa_handle.latency = VOIP_RECORD_LATENCY;
1147 alsa_handle.rxHandle = 0;
1148 alsa_handle.ucMgr = mUcMgr;
1149 mALSADevice->setVoipConfig(getVoipMode(*format), mVoipBitRate);
1150 snd_use_case_get(mUcMgr, "_verb", (const char **)&use_case);
1151 if ((use_case != NULL) && (strcmp(use_case, SND_USE_CASE_VERB_INACTIVE))) {
1152 strlcpy(alsa_handle.useCase, SND_USE_CASE_MOD_PLAY_VOIP, sizeof(alsa_handle.useCase));
1153 } else {
1154 strlcpy(alsa_handle.useCase, SND_USE_CASE_VERB_IP_VOICECALL, sizeof(alsa_handle.useCase));
1155 }
1156 free(use_case);
1157 mDeviceList.push_back(alsa_handle);
1158 it = mDeviceList.end();
1159 it--;
1160 ALOGD("mCurrDevice: %d", mCurDevice);
1161 #ifdef QCOM_USBAUDIO_ENABLED
1162 if((mCurDevice == AudioSystem::DEVICE_OUT_ANLG_DOCK_HEADSET)||
1163 (mCurDevice == AudioSystem::DEVICE_OUT_DGTL_DOCK_HEADSET)){
1164 ALOGD("Routing everything from proxy for voipcall");
1165 mALSADevice->route(&(*it), AudioSystem::DEVICE_IN_PROXY, AudioSystem::MODE_IN_COMMUNICATION);
1166 ALOGD("enabling VOIP in openInputstream, musbPlaybackState: %d", musbPlaybackState);
1167 startUsbPlaybackIfNotStarted();
1168 musbPlaybackState |= USBPLAYBACKBIT_VOIPCALL;
1169 ALOGD("Starting recording in openoutputstream, musbRecordingState: %d", musbRecordingState);
1170 startUsbRecordingIfNotStarted();
1171 musbRecordingState |= USBRECBIT_VOIPCALL;
1172 } else
1173 #endif
1174 {
1175 mALSADevice->route(&(*it),mCurDevice, AudioSystem::MODE_IN_COMMUNICATION);
1176 }
1177 if(!strcmp(it->useCase, SND_USE_CASE_VERB_IP_VOICECALL)) {
1178 snd_use_case_set(mUcMgr, "_verb", SND_USE_CASE_VERB_IP_VOICECALL);
1179 } else {
1180 snd_use_case_set(mUcMgr, "_enamod", SND_USE_CASE_MOD_PLAY_VOIP);
1181 }
1182 if(sampleRate) {
1183 it->sampleRate = *sampleRate;
1184 }
1185 if(channels)
1186 it->channels = AudioSystem::popCount(*channels);
1187 err = mALSADevice->startVoipCall(&(*it));
1188 if (err) {
1189 ALOGE("Error opening pcm input device");
1190 return NULL;
1191 }
1192 }
1193 in = new AudioStreamInALSA(this, &(*it), acoustics);
1194 err = in->set(format, channels, sampleRate, devices);
1195 if(err == NO_ERROR) {
1196 mVoipStreamCount++; //increment VoipstreamCount only if success
1197 ALOGD("OpenInput mVoipStreamCount %d",mVoipStreamCount);
1198 }
1199 ALOGD("openInput: After Get alsahandle");
1200 if (status) *status = err;
1201 return in;
1202 } else {
1203 alsa_handle_t alsa_handle;
1204 unsigned long bufferSize = MIN_CAPTURE_BUFFER_SIZE_PER_CH;
1205
1206 alsa_handle.module = mALSADevice;
1207 alsa_handle.bufferSize = bufferSize;
1208 alsa_handle.devices = devices;
1209 alsa_handle.handle = 0;
1210 alsa_handle.format = SNDRV_PCM_FORMAT_S16_LE;
1211 alsa_handle.channels = VOICE_CHANNEL_MODE;
1212 alsa_handle.sampleRate = android::AudioRecord::DEFAULT_SAMPLE_RATE;
1213 alsa_handle.latency = RECORD_LATENCY;
1214 alsa_handle.rxHandle = 0;
1215 alsa_handle.ucMgr = mUcMgr;
1216 snd_use_case_get(mUcMgr, "_verb", (const char **)&use_case);
1217 if ((use_case != NULL) && (strcmp(use_case, SND_USE_CASE_VERB_INACTIVE))) {
1218 if ((devices == AudioSystem::DEVICE_IN_VOICE_CALL) &&
1219 (newMode == AudioSystem::MODE_IN_CALL)) {
1220 ALOGD("openInputStream: into incall recording, channels %d", *channels);
1221 mIncallMode = *channels;
1222 if ((*channels & AudioSystem::CHANNEL_IN_VOICE_UPLINK) &&
1223 (*channels & AudioSystem::CHANNEL_IN_VOICE_DNLINK)) {
1224 if (mFusion3Platform) {
1225 mALSADevice->setVocRecMode(INCALL_REC_STEREO);
1226 strlcpy(alsa_handle.useCase, SND_USE_CASE_MOD_CAPTURE_VOICE,
1227 sizeof(alsa_handle.useCase));
1228 } else {
1229 strlcpy(alsa_handle.useCase, SND_USE_CASE_MOD_CAPTURE_VOICE_UL_DL,
1230 sizeof(alsa_handle.useCase));
1231 }
1232 } else if (*channels & AudioSystem::CHANNEL_IN_VOICE_DNLINK) {
1233 if (mFusion3Platform) {
1234 mALSADevice->setVocRecMode(INCALL_REC_MONO);
1235 strlcpy(alsa_handle.useCase, SND_USE_CASE_MOD_CAPTURE_VOICE,
1236 sizeof(alsa_handle.useCase));
1237 } else {
1238 strlcpy(alsa_handle.useCase, SND_USE_CASE_MOD_CAPTURE_VOICE_DL,
1239 sizeof(alsa_handle.useCase));
1240 }
1241 }
1242 #ifdef QCOM_FM_ENABLED
1243 } else if((devices == AudioSystem::DEVICE_IN_FM_RX)) {
1244 strlcpy(alsa_handle.useCase, SND_USE_CASE_MOD_CAPTURE_FM, sizeof(alsa_handle.useCase));
1245 } else if(devices == AudioSystem::DEVICE_IN_FM_RX_A2DP) {
1246 strlcpy(alsa_handle.useCase, SND_USE_CASE_MOD_CAPTURE_A2DP_FM, sizeof(alsa_handle.useCase));
1247 #endif
1248 } else {
1249 char value[128];
1250 property_get("persist.audio.lowlatency.rec",value,"0");
1251 if (!strcmp("true", value)) {
1252 strlcpy(alsa_handle.useCase, SND_USE_CASE_MOD_CAPTURE_LOWLATENCY_MUSIC, sizeof(alsa_handle.useCase));
1253 } else {
1254 strlcpy(alsa_handle.useCase, SND_USE_CASE_MOD_CAPTURE_MUSIC, sizeof(alsa_handle.useCase));
1255 }
1256 }
1257 } else {
1258 if ((devices == AudioSystem::DEVICE_IN_VOICE_CALL) &&
1259 (newMode == AudioSystem::MODE_IN_CALL)) {
1260 ALOGD("openInputStream: incall recording, channels %d", *channels);
1261 mIncallMode = *channels;
1262 if ((*channels & AudioSystem::CHANNEL_IN_VOICE_UPLINK) &&
1263 (*channels & AudioSystem::CHANNEL_IN_VOICE_DNLINK)) {
1264 if (mFusion3Platform) {
1265 mALSADevice->setVocRecMode(INCALL_REC_STEREO);
1266 strlcpy(alsa_handle.useCase, SND_USE_CASE_VERB_INCALL_REC,
1267 sizeof(alsa_handle.useCase));
1268 } else {
1269 strlcpy(alsa_handle.useCase, SND_USE_CASE_VERB_UL_DL_REC,
1270 sizeof(alsa_handle.useCase));
1271 }
1272 } else if (*channels & AudioSystem::CHANNEL_IN_VOICE_DNLINK) {
1273 if (mFusion3Platform) {
1274 mALSADevice->setVocRecMode(INCALL_REC_MONO);
1275 strlcpy(alsa_handle.useCase, SND_USE_CASE_VERB_INCALL_REC,
1276 sizeof(alsa_handle.useCase));
1277 } else {
1278 strlcpy(alsa_handle.useCase, SND_USE_CASE_VERB_DL_REC,
1279 sizeof(alsa_handle.useCase));
1280 }
1281 }
1282 #ifdef QCOM_FM_ENABLED
1283 } else if(devices == AudioSystem::DEVICE_IN_FM_RX) {
1284 strlcpy(alsa_handle.useCase, SND_USE_CASE_VERB_FM_REC, sizeof(alsa_handle.useCase));
1285 } else if (devices == AudioSystem::DEVICE_IN_FM_RX_A2DP) {
1286 strlcpy(alsa_handle.useCase, SND_USE_CASE_VERB_FM_A2DP_REC, sizeof(alsa_handle.useCase));
1287 #endif
1288 } else {
1289 char value[128];
1290 property_get("persist.audio.lowlatency.rec",value,"0");
1291 if (!strcmp("true", value)) {
1292 strlcpy(alsa_handle.useCase, SND_USE_CASE_VERB_HIFI_LOWLATENCY_REC, sizeof(alsa_handle.useCase));
1293 } else {
1294 strlcpy(alsa_handle.useCase, SND_USE_CASE_VERB_HIFI_REC, sizeof(alsa_handle.useCase));
1295 }
1296 }
1297 }
1298 free(use_case);
1299 mDeviceList.push_back(alsa_handle);
1300 ALSAHandleList::iterator it = mDeviceList.end();
1301 it--;
1302 //update channel info before do routing
1303 if(channels) {
1304 it->channels = AudioSystem::popCount((*channels) &
1305 (AudioSystem::CHANNEL_IN_STEREO
1306 | AudioSystem::CHANNEL_IN_MONO
1307 #ifdef QCOM_SSR_ENABLED
1308 | AudioSystem::CHANNEL_IN_5POINT1
1309 #endif
1310 ));
1311 ALOGV("updated channel info: channels=%d", it->channels);
1312 }
1313 if (devices == AudioSystem::DEVICE_IN_VOICE_CALL){
1314 /* Add current devices info to devices to do route */
1315 #ifdef QCOM_USBAUDIO_ENABLED
1316 if(mCurDevice == AudioSystem::DEVICE_OUT_ANLG_DOCK_HEADSET ||
1317 mCurDevice == AudioSystem::DEVICE_OUT_DGTL_DOCK_HEADSET){
1318 ALOGD("Routing everything from proxy for VOIP call");
1319 route_devices = devices | AudioSystem::DEVICE_IN_PROXY;
1320 } else
1321 #endif
1322 {
1323 route_devices = devices | mCurDevice;
1324 }
1325 mALSADevice->route(&(*it), route_devices, mode());
1326 } else {
1327 #ifdef QCOM_USBAUDIO_ENABLED
1328 if(devices & AudioSystem::DEVICE_IN_ANLG_DOCK_HEADSET ||
1329 devices & AudioSystem::DEVICE_IN_PROXY) {
1330 devices |= AudioSystem::DEVICE_IN_PROXY;
1331 ALOGD("routing everything from proxy");
1332 mALSADevice->route(&(*it), devices, mode());
1333 } else
1334 #endif
1335 {
1336 mALSADevice->route(&(*it), devices, mode());
1337 }
1338 }
1339
1340 if(!strcmp(it->useCase, SND_USE_CASE_VERB_HIFI_REC) ||
1341 !strcmp(it->useCase, SND_USE_CASE_VERB_HIFI_LOWLATENCY_REC) ||
1342 #ifdef QCOM_FM_ENABLED
1343 !strcmp(it->useCase, SND_USE_CASE_VERB_FM_REC) ||
1344 !strcmp(it->useCase, SND_USE_CASE_VERB_FM_A2DP_REC) ||
1345 #endif
1346 !strcmp(it->useCase, SND_USE_CASE_VERB_DL_REC) ||
1347 !strcmp(it->useCase, SND_USE_CASE_VERB_UL_DL_REC) ||
1348 !strcmp(it->useCase, SND_USE_CASE_VERB_INCALL_REC)) {
1349 snd_use_case_set(mUcMgr, "_verb", it->useCase);
1350 } else {
1351 snd_use_case_set(mUcMgr, "_enamod", it->useCase);
1352 }
1353 if(sampleRate) {
1354 it->sampleRate = *sampleRate;
1355 }
1356 if (!strncmp(it->useCase, SND_USE_CASE_VERB_HIFI_REC, strlen(SND_USE_CASE_VERB_HIFI_REC))
1357 || !strncmp(it->useCase, SND_USE_CASE_MOD_CAPTURE_MUSIC, strlen(SND_USE_CASE_MOD_CAPTURE_MUSIC))) {
1358 ALOGV("OpenInoutStream: Use larger buffer size for 5.1(%s) recording ", it->useCase);
1359 it->bufferSize = getInputBufferSize(it->sampleRate,*format,it->channels);
1360 }
1361 err = mALSADevice->open(&(*it));
1362 if (err) {
1363 ALOGE("Error opening pcm input device");
1364 } else {
1365 in = new AudioStreamInALSA(this, &(*it), acoustics);
1366 err = in->set(format, channels, sampleRate, devices);
1367 }
1368 if (status) *status = err;
1369 return in;
1370 }
1371 }
1372
1373 void
closeInputStream(AudioStreamIn * in)1374 AudioHardwareALSA::closeInputStream(AudioStreamIn* in)
1375 {
1376 delete in;
1377 }
1378
setMicMute(bool state)1379 status_t AudioHardwareALSA::setMicMute(bool state)
1380 {
1381 if (mMicMute != state) {
1382 mMicMute = state;
1383 ALOGD("setMicMute: mMicMute %d", mMicMute);
1384 if(mALSADevice) {
1385 mALSADevice->setMicMute(state);
1386 }
1387 }
1388 return NO_ERROR;
1389 }
1390
getMicMute(bool * state)1391 status_t AudioHardwareALSA::getMicMute(bool *state)
1392 {
1393 *state = mMicMute;
1394 return NO_ERROR;
1395 }
1396
dump(int fd,const Vector<String16> & args)1397 status_t AudioHardwareALSA::dump(int fd, const Vector<String16>& args)
1398 {
1399 return NO_ERROR;
1400 }
1401
getInputBufferSize(uint32_t sampleRate,int format,int channelCount)1402 size_t AudioHardwareALSA::getInputBufferSize(uint32_t sampleRate, int format, int channelCount)
1403 {
1404 size_t bufferSize = 0;
1405 if (format == AudioSystem::PCM_16_BIT) {
1406 if(sampleRate == 8000 || sampleRate == 16000 || sampleRate == 32000) {
1407 bufferSize = (sampleRate * channelCount * 20 * sizeof(int16_t)) / 1000;
1408 } else if (sampleRate == 11025 || sampleRate == 12000) {
1409 bufferSize = 256 * sizeof(int16_t) * channelCount;
1410 } else if (sampleRate == 22050 || sampleRate == 24000) {
1411 bufferSize = 512 * sizeof(int16_t) * channelCount;
1412 } else if (sampleRate == 44100 || sampleRate == 48000) {
1413 bufferSize = 1024 * sizeof(int16_t) * channelCount;
1414 }
1415 } else {
1416 ALOGE("getInputBufferSize bad format: %d", format);
1417 }
1418 return bufferSize;
1419 }
1420
1421 #ifdef QCOM_FM_ENABLED
handleFm(int device)1422 void AudioHardwareALSA::handleFm(int device)
1423 {
1424 int newMode = mode();
1425 if(device & AudioSystem::DEVICE_OUT_FM && mIsFmActive == 0) {
1426 // Start FM Radio on current active device
1427 unsigned long bufferSize = FM_BUFFER_SIZE;
1428 alsa_handle_t alsa_handle;
1429 char *use_case;
1430 ALOGV("Start FM");
1431 snd_use_case_get(mUcMgr, "_verb", (const char **)&use_case);
1432 if ((use_case == NULL) || (!strcmp(use_case, SND_USE_CASE_VERB_INACTIVE))) {
1433 strlcpy(alsa_handle.useCase, SND_USE_CASE_VERB_DIGITAL_RADIO, sizeof(alsa_handle.useCase));
1434 } else {
1435 strlcpy(alsa_handle.useCase, SND_USE_CASE_MOD_PLAY_FM, sizeof(alsa_handle.useCase));
1436 }
1437 free(use_case);
1438
1439 for (size_t b = 1; (bufferSize & ~b) != 0; b <<= 1)
1440 bufferSize &= ~b;
1441 alsa_handle.module = mALSADevice;
1442 alsa_handle.bufferSize = bufferSize;
1443 alsa_handle.devices = device;
1444 alsa_handle.handle = 0;
1445 alsa_handle.format = SNDRV_PCM_FORMAT_S16_LE;
1446 alsa_handle.channels = DEFAULT_CHANNEL_MODE;
1447 alsa_handle.sampleRate = DEFAULT_SAMPLING_RATE;
1448 alsa_handle.latency = VOICE_LATENCY;
1449 alsa_handle.rxHandle = 0;
1450 alsa_handle.ucMgr = mUcMgr;
1451 mIsFmActive = 1;
1452 mDeviceList.push_back(alsa_handle);
1453 ALSAHandleList::iterator it = mDeviceList.end();
1454 it--;
1455 if((device & AudioSystem::DEVICE_OUT_ANLG_DOCK_HEADSET)||
1456 (device & AudioSystem::DEVICE_OUT_DGTL_DOCK_HEADSET)){
1457 device |= AudioSystem::DEVICE_OUT_PROXY;
1458 alsa_handle.devices = AudioSystem::DEVICE_OUT_PROXY;
1459 ALOGD("Routing to proxy for FM case");
1460 }
1461 mALSADevice->route(&(*it), (uint32_t)device, newMode);
1462 if(!strcmp(it->useCase, SND_USE_CASE_VERB_DIGITAL_RADIO)) {
1463 snd_use_case_set(mUcMgr, "_verb", SND_USE_CASE_VERB_DIGITAL_RADIO);
1464 } else {
1465 snd_use_case_set(mUcMgr, "_enamod", SND_USE_CASE_MOD_PLAY_FM);
1466 }
1467 mALSADevice->startFm(&(*it));
1468 if((device & AudioSystem::DEVICE_OUT_ANLG_DOCK_HEADSET)||
1469 (device & AudioSystem::DEVICE_OUT_DGTL_DOCK_HEADSET)){
1470 ALOGD("Starting FM, musbPlaybackState %d", musbPlaybackState);
1471 startUsbPlaybackIfNotStarted();
1472 musbPlaybackState |= USBPLAYBACKBIT_FM;
1473 }
1474 } else if (!(device & AudioSystem::DEVICE_OUT_FM) && mIsFmActive == 1) {
1475 //i Stop FM Radio
1476 ALOGV("Stop FM");
1477 for(ALSAHandleList::iterator it = mDeviceList.begin();
1478 it != mDeviceList.end(); ++it) {
1479 if((!strcmp(it->useCase, SND_USE_CASE_VERB_DIGITAL_RADIO)) ||
1480 (!strcmp(it->useCase, SND_USE_CASE_MOD_PLAY_FM))) {
1481 mALSADevice->close(&(*it));
1482 //mALSADevice->route(&(*it), (uint32_t)device, newMode);
1483 mDeviceList.erase(it);
1484 break;
1485 }
1486 }
1487 mIsFmActive = 0;
1488 musbPlaybackState &= ~USBPLAYBACKBIT_FM;
1489 if((device & AudioSystem::DEVICE_OUT_ANLG_DOCK_HEADSET)||
1490 (device & AudioSystem::DEVICE_OUT_DGTL_DOCK_HEADSET)){
1491 closeUsbPlaybackIfNothingActive();
1492 }
1493 }
1494 }
1495 #endif
1496
disableVoiceCall(char * verb,char * modifier,int mode,int device)1497 void AudioHardwareALSA::disableVoiceCall(char* verb, char* modifier, int mode, int device)
1498 {
1499 for(ALSAHandleList::iterator it = mDeviceList.begin();
1500 it != mDeviceList.end(); ++it) {
1501 if((!strcmp(it->useCase, verb)) ||
1502 (!strcmp(it->useCase, modifier))) {
1503 ALOGV("Disabling voice call");
1504 mALSADevice->close(&(*it));
1505 mALSADevice->route(&(*it), (uint32_t)device, mode);
1506 mDeviceList.erase(it);
1507 break;
1508 }
1509 }
1510 #ifdef QCOM_USBAUDIO_ENABLED
1511 if(musbPlaybackState & USBPLAYBACKBIT_VOICECALL) {
1512 ALOGD("Voice call ended on USB");
1513 musbPlaybackState &= ~USBPLAYBACKBIT_VOICECALL;
1514 musbRecordingState &= ~USBRECBIT_VOICECALL;
1515 closeUsbRecordingIfNothingActive();
1516 closeUsbPlaybackIfNothingActive();
1517 }
1518 #endif
1519 }
enableVoiceCall(char * verb,char * modifier,int mode,int device)1520 void AudioHardwareALSA::enableVoiceCall(char* verb, char* modifier, int mode, int device)
1521 {
1522 // Start voice call
1523 unsigned long bufferSize = DEFAULT_VOICE_BUFFER_SIZE;
1524 alsa_handle_t alsa_handle;
1525 char *use_case;
1526 snd_use_case_get(mUcMgr, "_verb", (const char **)&use_case);
1527 if ((use_case == NULL) || (!strcmp(use_case, SND_USE_CASE_VERB_INACTIVE))) {
1528 strlcpy(alsa_handle.useCase, verb, sizeof(alsa_handle.useCase));
1529 } else {
1530 strlcpy(alsa_handle.useCase, modifier, sizeof(alsa_handle.useCase));
1531 }
1532 free(use_case);
1533
1534 for (size_t b = 1; (bufferSize & ~b) != 0; b <<= 1)
1535 bufferSize &= ~b;
1536 alsa_handle.module = mALSADevice;
1537 alsa_handle.bufferSize = bufferSize;
1538 alsa_handle.devices = device;
1539 alsa_handle.handle = 0;
1540 alsa_handle.format = SNDRV_PCM_FORMAT_S16_LE;
1541 alsa_handle.channels = VOICE_CHANNEL_MODE;
1542 alsa_handle.sampleRate = VOICE_SAMPLING_RATE;
1543 alsa_handle.latency = VOICE_LATENCY;
1544 alsa_handle.rxHandle = 0;
1545 alsa_handle.ucMgr = mUcMgr;
1546 mDeviceList.push_back(alsa_handle);
1547 ALSAHandleList::iterator it = mDeviceList.end();
1548 it--;
1549 #ifdef QCOM_USBAUDIO_ENABLED
1550 if((device & AudioSystem::DEVICE_OUT_ANLG_DOCK_HEADSET)||
1551 (device & AudioSystem::DEVICE_OUT_DGTL_DOCK_HEADSET)){
1552 device |= AudioSystem::DEVICE_OUT_PROXY;
1553 alsa_handle.devices = device;
1554 }
1555 #endif
1556 mALSADevice->route(&(*it), (uint32_t)device, mode);
1557 if (!strcmp(it->useCase, verb)) {
1558 snd_use_case_set(mUcMgr, "_verb", verb);
1559 } else {
1560 snd_use_case_set(mUcMgr, "_enamod", modifier);
1561 }
1562 mALSADevice->startVoiceCall(&(*it));
1563 #ifdef QCOM_USBAUDIO_ENABLED
1564 if((device & AudioSystem::DEVICE_OUT_ANLG_DOCK_HEADSET)||
1565 (device & AudioSystem::DEVICE_OUT_DGTL_DOCK_HEADSET)){
1566 startUsbRecordingIfNotStarted();
1567 startUsbPlaybackIfNotStarted();
1568 musbPlaybackState |= USBPLAYBACKBIT_VOICECALL;
1569 musbRecordingState |= USBRECBIT_VOICECALL;
1570 }
1571 #endif
1572 }
1573
routeVoiceCall(int device,int newMode)1574 bool AudioHardwareALSA::routeVoiceCall(int device, int newMode)
1575 {
1576 int csCallState = mCallState&0xF;
1577 bool isRouted = false;
1578 switch (csCallState) {
1579 case CS_INACTIVE:
1580 if (mCSCallActive != CS_INACTIVE) {
1581 ALOGD("doRouting: Disabling voice call");
1582 disableVoiceCall((char *)SND_USE_CASE_VERB_VOICECALL,
1583 (char *)SND_USE_CASE_MOD_PLAY_VOICE, newMode, device);
1584 isRouted = true;
1585 mCSCallActive = CS_INACTIVE;
1586 }
1587 break;
1588 case CS_ACTIVE:
1589 if (mCSCallActive == CS_INACTIVE) {
1590 ALOGD("doRouting: Enabling CS voice call ");
1591 enableVoiceCall((char *)SND_USE_CASE_VERB_VOICECALL,
1592 (char *)SND_USE_CASE_MOD_PLAY_VOICE, newMode, device);
1593 isRouted = true;
1594 mCSCallActive = CS_ACTIVE;
1595 } else if (mCSCallActive == CS_HOLD) {
1596 ALOGD("doRouting: Resume voice call from hold state");
1597 ALSAHandleList::iterator vt_it;
1598 for(vt_it = mDeviceList.begin();
1599 vt_it != mDeviceList.end(); ++vt_it) {
1600 if((!strncmp(vt_it->useCase, SND_USE_CASE_VERB_VOICECALL,
1601 strlen(SND_USE_CASE_VERB_VOICECALL))) ||
1602 (!strncmp(vt_it->useCase, SND_USE_CASE_MOD_PLAY_VOICE,
1603 strlen(SND_USE_CASE_MOD_PLAY_VOICE)))) {
1604 alsa_handle_t *handle = (alsa_handle_t *)(&(*vt_it));
1605 mCSCallActive = CS_ACTIVE;
1606 if(ioctl((int)handle->handle->fd,SNDRV_PCM_IOCTL_PAUSE,0)<0)
1607 ALOGE("VoLTE resume failed");
1608 break;
1609 }
1610 }
1611 }
1612 break;
1613 case CS_HOLD:
1614 if (mCSCallActive == CS_ACTIVE) {
1615 ALOGD("doRouting: Voice call going to Hold");
1616 ALSAHandleList::iterator vt_it;
1617 for(vt_it = mDeviceList.begin();
1618 vt_it != mDeviceList.end(); ++vt_it) {
1619 if((!strncmp(vt_it->useCase, SND_USE_CASE_VERB_VOICECALL,
1620 strlen(SND_USE_CASE_VERB_VOICECALL))) ||
1621 (!strncmp(vt_it->useCase, SND_USE_CASE_MOD_PLAY_VOICE,
1622 strlen(SND_USE_CASE_MOD_PLAY_VOICE)))) {
1623 mCSCallActive = CS_HOLD;
1624 alsa_handle_t *handle = (alsa_handle_t *)(&(*vt_it));
1625 if(ioctl((int)handle->handle->fd,SNDRV_PCM_IOCTL_PAUSE,1)<0)
1626 ALOGE("Voice pause failed");
1627 break;
1628 }
1629 }
1630 }
1631 break;
1632 }
1633 return isRouted;
1634 }
routeVoLTECall(int device,int newMode)1635 bool AudioHardwareALSA::routeVoLTECall(int device, int newMode)
1636 {
1637 int volteCallState = mCallState&0xF0;
1638 bool isRouted = false;
1639 switch (volteCallState) {
1640 case IMS_INACTIVE:
1641 if (mVolteCallActive != IMS_INACTIVE) {
1642 ALOGD("doRouting: Disabling IMS call");
1643 disableVoiceCall((char *)SND_USE_CASE_VERB_VOLTE,
1644 (char *)SND_USE_CASE_MOD_PLAY_VOLTE, newMode, device);
1645 isRouted = true;
1646 mVolteCallActive = IMS_INACTIVE;
1647 }
1648 break;
1649 case IMS_ACTIVE:
1650 if (mVolteCallActive == IMS_INACTIVE) {
1651 ALOGD("doRouting: Enabling IMS voice call ");
1652 enableVoiceCall((char *)SND_USE_CASE_VERB_VOLTE,
1653 (char *)SND_USE_CASE_MOD_PLAY_VOLTE, newMode, device);
1654 isRouted = true;
1655 mVolteCallActive = IMS_ACTIVE;
1656 } else if (mVolteCallActive == IMS_HOLD) {
1657 ALOGD("doRouting: Resume IMS call from hold state");
1658 ALSAHandleList::iterator vt_it;
1659 for(vt_it = mDeviceList.begin();
1660 vt_it != mDeviceList.end(); ++vt_it) {
1661 if((!strncmp(vt_it->useCase, SND_USE_CASE_VERB_VOLTE,
1662 strlen(SND_USE_CASE_VERB_VOLTE))) ||
1663 (!strncmp(vt_it->useCase, SND_USE_CASE_MOD_PLAY_VOLTE,
1664 strlen(SND_USE_CASE_MOD_PLAY_VOLTE)))) {
1665 alsa_handle_t *handle = (alsa_handle_t *)(&(*vt_it));
1666 mVolteCallActive = IMS_ACTIVE;
1667 if(ioctl((int)handle->handle->fd,SNDRV_PCM_IOCTL_PAUSE,0)<0)
1668 ALOGE("VoLTE resume failed");
1669 break;
1670 }
1671 }
1672 }
1673 break;
1674 case IMS_HOLD:
1675 if (mVolteCallActive == IMS_ACTIVE) {
1676 ALOGD("doRouting: IMS ACTIVE going to HOLD");
1677 ALSAHandleList::iterator vt_it;
1678 for(vt_it = mDeviceList.begin();
1679 vt_it != mDeviceList.end(); ++vt_it) {
1680 if((!strncmp(vt_it->useCase, SND_USE_CASE_VERB_VOLTE,
1681 strlen(SND_USE_CASE_VERB_VOLTE))) ||
1682 (!strncmp(vt_it->useCase, SND_USE_CASE_MOD_PLAY_VOLTE,
1683 strlen(SND_USE_CASE_MOD_PLAY_VOLTE)))) {
1684 mVolteCallActive = IMS_HOLD;
1685 alsa_handle_t *handle = (alsa_handle_t *)(&(*vt_it));
1686 if(ioctl((int)handle->handle->fd,SNDRV_PCM_IOCTL_PAUSE,1)<0)
1687 ALOGE("VoLTE Pause failed");
1688 break;
1689 }
1690 }
1691 }
1692 break;
1693 }
1694 return isRouted;
1695 }
1696
1697 } // namespace android_audio_legacy
1698