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