1 /*
2 ** Copyright 2008, The Android Open-Source Project
3 **
4 ** Licensed under the Apache License, Version 2.0 (the "License");
5 ** you may not use this file except in compliance with the License.
6 ** You may obtain a copy of the License at
7 **
8 ** http://www.apache.org/licenses/LICENSE-2.0
9 **
10 ** Unless required by applicable law or agreed to in writing, software
11 ** distributed under the License is distributed on an "AS IS" BASIS,
12 ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 ** See the License for the specific language governing permissions and
14 ** limitations under the License.
15 */
16
17 #include <math.h>
18
19 //#define LOG_NDEBUG 0
20 #define LOG_TAG "AudioHardwareMSM72XX"
21 #include <utils/Log.h>
22 #include <utils/String8.h>
23
24 #include <stdio.h>
25 #include <unistd.h>
26 #include <sys/ioctl.h>
27 #include <sys/types.h>
28 #include <sys/stat.h>
29 #include <dlfcn.h>
30 #include <fcntl.h>
31
32 // hardware specific functions
33
34 #include "AudioHardware.h"
35 #include <media/AudioRecord.h>
36
37 #define LOG_SND_RPC 0 // Set to 1 to log sound RPC's
38
39 namespace android {
40 static int audpre_index, tx_iir_index;
41 static void * acoustic;
42 const uint32_t AudioHardware::inputSamplingRates[] = {
43 8000, 11025, 12000, 16000, 22050, 24000, 32000, 44100, 48000
44 };
45 // ----------------------------------------------------------------------------
46
AudioHardware()47 AudioHardware::AudioHardware() :
48 mInit(false), mMicMute(true), mBluetoothNrec(true), mBluetoothId(0),
49 mOutput(0), mSndEndpoints(NULL), mCurSndDevice(-1),
50 SND_DEVICE_CURRENT(-1),
51 SND_DEVICE_HANDSET(-1),
52 SND_DEVICE_SPEAKER(-1),
53 SND_DEVICE_HEADSET(-1),
54 SND_DEVICE_BT(-1),
55 SND_DEVICE_CARKIT(-1),
56 SND_DEVICE_TTY_FULL(-1),
57 SND_DEVICE_TTY_VCO(-1),
58 SND_DEVICE_TTY_HCO(-1),
59 SND_DEVICE_NO_MIC_HEADSET(-1),
60 SND_DEVICE_FM_HEADSET(-1),
61 SND_DEVICE_HEADSET_AND_SPEAKER(-1),
62 SND_DEVICE_FM_SPEAKER(-1),
63 SND_DEVICE_BT_EC_OFF(-1)
64 {
65
66 int (*snd_get_num)();
67 int (*snd_get_endpoint)(int, msm_snd_endpoint *);
68 int (*set_acoustic_parameters)();
69
70 struct msm_snd_endpoint *ept;
71
72 acoustic = ::dlopen("/system/lib/libhtc_acoustic.so", RTLD_NOW);
73 if (acoustic == NULL ) {
74 ALOGE("Could not open libhtc_acoustic.so");
75 /* this is not really an error on non-htc devices... */
76 mNumSndEndpoints = 0;
77 mInit = true;
78 return;
79 }
80
81 set_acoustic_parameters = (int (*)(void))::dlsym(acoustic, "set_acoustic_parameters");
82 if ((*set_acoustic_parameters) == 0 ) {
83 ALOGE("Could not open set_acoustic_parameters()");
84 return;
85 }
86
87 int rc = set_acoustic_parameters();
88 if (rc < 0) {
89 ALOGE("Could not set acoustic parameters to share memory: %d", rc);
90 // return;
91 }
92
93 snd_get_num = (int (*)(void))::dlsym(acoustic, "snd_get_num_endpoints");
94 if ((*snd_get_num) == 0 ) {
95 ALOGE("Could not open snd_get_num()");
96 // return;
97 }
98
99 mNumSndEndpoints = snd_get_num();
100 ALOGD("mNumSndEndpoints = %d", mNumSndEndpoints);
101 mSndEndpoints = new msm_snd_endpoint[mNumSndEndpoints];
102 mInit = true;
103 ALOGV("constructed %d SND endpoints)", mNumSndEndpoints);
104 ept = mSndEndpoints;
105 snd_get_endpoint = (int (*)(int, msm_snd_endpoint *))::dlsym(acoustic, "snd_get_endpoint");
106 if ((*snd_get_endpoint) == 0 ) {
107 ALOGE("Could not open snd_get_endpoint()");
108 return;
109 }
110
111 for (int cnt = 0; cnt < mNumSndEndpoints; cnt++, ept++) {
112 ept->id = cnt;
113 snd_get_endpoint(cnt, ept);
114 #define CHECK_FOR(desc) \
115 if (!strcmp(ept->name, #desc)) { \
116 SND_DEVICE_##desc = ept->id; \
117 ALOGD("BT MATCH " #desc); \
118 } else
119 CHECK_FOR(CURRENT)
120 CHECK_FOR(HANDSET)
121 CHECK_FOR(SPEAKER)
122 CHECK_FOR(BT)
123 CHECK_FOR(BT_EC_OFF)
124 CHECK_FOR(HEADSET)
125 CHECK_FOR(CARKIT)
126 CHECK_FOR(TTY_FULL)
127 CHECK_FOR(TTY_VCO)
128 CHECK_FOR(TTY_HCO)
129 CHECK_FOR(NO_MIC_HEADSET)
130 CHECK_FOR(FM_HEADSET)
131 CHECK_FOR(FM_SPEAKER)
132 CHECK_FOR(HEADSET_AND_SPEAKER) {}
133 #undef CHECK_FOR
134 }
135 }
136
~AudioHardware()137 AudioHardware::~AudioHardware()
138 {
139 for (size_t index = 0; index < mInputs.size(); index++) {
140 closeInputStream((AudioStreamIn*)mInputs[index]);
141 }
142 mInputs.clear();
143 closeOutputStream((AudioStreamOut*)mOutput);
144 delete [] mSndEndpoints;
145 if (acoustic) {
146 ::dlclose(acoustic);
147 acoustic = 0;
148 }
149 mInit = false;
150 }
151
initCheck()152 status_t AudioHardware::initCheck()
153 {
154 return mInit ? NO_ERROR : NO_INIT;
155 }
156
openOutputStream(uint32_t devices,int * format,uint32_t * channels,uint32_t * sampleRate,status_t * status)157 AudioStreamOut* AudioHardware::openOutputStream(
158 uint32_t devices, int *format, uint32_t *channels, uint32_t *sampleRate, status_t *status)
159 {
160 { // scope for the lock
161 Mutex::Autolock lock(mLock);
162
163 // only one output stream allowed
164 if (mOutput) {
165 if (status) {
166 *status = INVALID_OPERATION;
167 }
168 return 0;
169 }
170
171 // create new output stream
172 AudioStreamOutMSM72xx* out = new AudioStreamOutMSM72xx();
173 status_t lStatus = out->set(this, devices, format, channels, sampleRate);
174 if (status) {
175 *status = lStatus;
176 }
177 if (lStatus == NO_ERROR) {
178 mOutput = out;
179 } else {
180 delete out;
181 }
182 }
183 return mOutput;
184 }
185
closeOutputStream(AudioStreamOut * out)186 void AudioHardware::closeOutputStream(AudioStreamOut* out) {
187 Mutex::Autolock lock(mLock);
188 if (mOutput == 0 || mOutput != out) {
189 ALOGW("Attempt to close invalid output stream");
190 }
191 else {
192 delete mOutput;
193 mOutput = 0;
194 }
195 }
196
openInputStream(uint32_t devices,int * format,uint32_t * channels,uint32_t * sampleRate,status_t * status,AudioSystem::audio_in_acoustics acoustic_flags)197 AudioStreamIn* AudioHardware::openInputStream(
198 uint32_t devices, int *format, uint32_t *channels, uint32_t *sampleRate, status_t *status,
199 AudioSystem::audio_in_acoustics acoustic_flags)
200 {
201 // check for valid input source
202 if (!AudioSystem::isInputDevice((AudioSystem::audio_devices)devices)) {
203 return 0;
204 }
205
206 mLock.lock();
207
208 AudioStreamInMSM72xx* in = new AudioStreamInMSM72xx();
209 status_t lStatus = in->set(this, devices, format, channels, sampleRate, acoustic_flags);
210 if (status) {
211 *status = lStatus;
212 }
213 if (lStatus != NO_ERROR) {
214 mLock.unlock();
215 delete in;
216 return 0;
217 }
218
219 mInputs.add(in);
220 mLock.unlock();
221
222 return in;
223 }
224
closeInputStream(AudioStreamIn * in)225 void AudioHardware::closeInputStream(AudioStreamIn* in) {
226 Mutex::Autolock lock(mLock);
227
228 ssize_t index = mInputs.indexOf((AudioStreamInMSM72xx *)in);
229 if (index < 0) {
230 ALOGW("Attempt to close invalid input stream");
231 } else {
232 mLock.unlock();
233 delete mInputs[index];
234 mLock.lock();
235 mInputs.removeAt(index);
236 }
237 }
238
setMode(int mode)239 status_t AudioHardware::setMode(int mode)
240 {
241 status_t status = AudioHardwareBase::setMode(mode);
242 if (status == NO_ERROR) {
243 // make sure that doAudioRouteOrMute() is called by doRouting()
244 // even if the new device selected is the same as current one.
245 clearCurDevice();
246 }
247 return status;
248 }
249
checkOutputStandby()250 bool AudioHardware::checkOutputStandby()
251 {
252 if (mOutput)
253 if (!mOutput->checkStandby())
254 return false;
255
256 return true;
257 }
258
setMicMute(bool state)259 status_t AudioHardware::setMicMute(bool state)
260 {
261 Mutex::Autolock lock(mLock);
262 return setMicMute_nosync(state);
263 }
264
265 // always call with mutex held
setMicMute_nosync(bool state)266 status_t AudioHardware::setMicMute_nosync(bool state)
267 {
268 if (mMicMute != state) {
269 mMicMute = state;
270 return doAudioRouteOrMute(SND_DEVICE_CURRENT);
271 }
272 return NO_ERROR;
273 }
274
getMicMute(bool * state)275 status_t AudioHardware::getMicMute(bool* state)
276 {
277 *state = mMicMute;
278 return NO_ERROR;
279 }
280
setParameters(const String8 & keyValuePairs)281 status_t AudioHardware::setParameters(const String8& keyValuePairs)
282 {
283 AudioParameter param = AudioParameter(keyValuePairs);
284 String8 value;
285 String8 key;
286 const char BT_NREC_KEY[] = "bt_headset_nrec";
287 const char BT_NAME_KEY[] = "bt_headset_name";
288 const char BT_NREC_VALUE_ON[] = "on";
289
290
291 ALOGV("setParameters() %s", keyValuePairs.string());
292
293 if (keyValuePairs.length() == 0) return BAD_VALUE;
294
295 key = String8(BT_NREC_KEY);
296 if (param.get(key, value) == NO_ERROR) {
297 if (value == BT_NREC_VALUE_ON) {
298 mBluetoothNrec = true;
299 } else {
300 mBluetoothNrec = false;
301 ALOGI("Turning noise reduction and echo cancellation off for BT "
302 "headset");
303 }
304 }
305 key = String8(BT_NAME_KEY);
306 if (param.get(key, value) == NO_ERROR) {
307 mBluetoothId = 0;
308 for (int i = 0; i < mNumSndEndpoints; i++) {
309 if (!strcasecmp(value.string(), mSndEndpoints[i].name)) {
310 mBluetoothId = mSndEndpoints[i].id;
311 ALOGI("Using custom acoustic parameters for %s", value.string());
312 break;
313 }
314 }
315 if (mBluetoothId == 0) {
316 ALOGI("Using default acoustic parameters "
317 "(%s not in acoustic database)", value.string());
318 doRouting();
319 }
320 }
321 return NO_ERROR;
322 }
323
getParameters(const String8 & keys)324 String8 AudioHardware::getParameters(const String8& keys)
325 {
326 AudioParameter param = AudioParameter(keys);
327 return param.toString();
328 }
329
330
calculate_audpre_table_index(unsigned index)331 static unsigned calculate_audpre_table_index(unsigned index)
332 {
333 switch (index) {
334 case 48000: return SAMP_RATE_INDX_48000;
335 case 44100: return SAMP_RATE_INDX_44100;
336 case 32000: return SAMP_RATE_INDX_32000;
337 case 24000: return SAMP_RATE_INDX_24000;
338 case 22050: return SAMP_RATE_INDX_22050;
339 case 16000: return SAMP_RATE_INDX_16000;
340 case 12000: return SAMP_RATE_INDX_12000;
341 case 11025: return SAMP_RATE_INDX_11025;
342 case 8000: return SAMP_RATE_INDX_8000;
343 default: return -1;
344 }
345 }
getInputBufferSize(uint32_t sampleRate,int format,int channelCount)346 size_t AudioHardware::getInputBufferSize(uint32_t sampleRate, int format, int channelCount)
347 {
348 if (format != AudioSystem::PCM_16_BIT) {
349 ALOGW("getInputBufferSize bad format: %d", format);
350 return 0;
351 }
352 if (channelCount < 1 || channelCount > 2) {
353 ALOGW("getInputBufferSize bad channel count: %d", channelCount);
354 return 0;
355 }
356
357 return 2048*channelCount;
358 }
359
set_volume_rpc(uint32_t device,uint32_t method,uint32_t volume)360 static status_t set_volume_rpc(uint32_t device,
361 uint32_t method,
362 uint32_t volume)
363 {
364 int fd;
365 #if LOG_SND_RPC
366 ALOGD("rpc_snd_set_volume(%d, %d, %d)\n", device, method, volume);
367 #endif
368
369 if (device == -1UL) return NO_ERROR;
370
371 fd = open("/dev/msm_snd", O_RDWR);
372 if (fd < 0) {
373 ALOGE("Can not open snd device");
374 return -EPERM;
375 }
376 /* rpc_snd_set_volume(
377 * device, # Any hardware device enum, including
378 * # SND_DEVICE_CURRENT
379 * method, # must be SND_METHOD_VOICE to do anything useful
380 * volume, # integer volume level, in range [0,5].
381 * # note that 0 is audible (not quite muted)
382 * )
383 * rpc_snd_set_volume only works for in-call sound volume.
384 */
385 struct msm_snd_volume_config args;
386 args.device = device;
387 args.method = method;
388 args.volume = volume;
389
390 if (ioctl(fd, SND_SET_VOLUME, &args) < 0) {
391 ALOGE("snd_set_volume error.");
392 close(fd);
393 return -EIO;
394 }
395 close(fd);
396 return NO_ERROR;
397 }
398
setVoiceVolume(float v)399 status_t AudioHardware::setVoiceVolume(float v)
400 {
401 if (v < 0.0) {
402 ALOGW("setVoiceVolume(%f) under 0.0, assuming 0.0\n", v);
403 v = 0.0;
404 } else if (v > 1.0) {
405 ALOGW("setVoiceVolume(%f) over 1.0, assuming 1.0\n", v);
406 v = 1.0;
407 }
408
409 int vol = lrint(v * 5.0);
410 ALOGD("setVoiceVolume(%f)\n", v);
411 ALOGI("Setting in-call volume to %d (available range is 0 to 5)\n", vol);
412
413 Mutex::Autolock lock(mLock);
414 set_volume_rpc(SND_DEVICE_CURRENT, SND_METHOD_VOICE, vol);
415 return NO_ERROR;
416 }
417
setMasterVolume(float v)418 status_t AudioHardware::setMasterVolume(float v)
419 {
420 Mutex::Autolock lock(mLock);
421 int vol = ceil(v * 5.0);
422 ALOGI("Set master volume to %d.\n", vol);
423 /*
424 set_volume_rpc(SND_DEVICE_HANDSET, SND_METHOD_VOICE, vol);
425 set_volume_rpc(SND_DEVICE_SPEAKER, SND_METHOD_VOICE, vol);
426 set_volume_rpc(SND_DEVICE_BT, SND_METHOD_VOICE, vol);
427 set_volume_rpc(SND_DEVICE_HEADSET, SND_METHOD_VOICE, vol);
428 */
429 // We return an error code here to let the audioflinger do in-software
430 // volume on top of the maximum volume that we set through the SND API.
431 // return error - software mixer will handle it
432 return -1;
433 }
434
do_route_audio_rpc(uint32_t device,bool ear_mute,bool mic_mute)435 static status_t do_route_audio_rpc(uint32_t device,
436 bool ear_mute, bool mic_mute)
437 {
438 if (device == -1UL)
439 return NO_ERROR;
440
441 int fd;
442 #if LOG_SND_RPC
443 ALOGD("rpc_snd_set_device(%d, %d, %d)\n", device, ear_mute, mic_mute);
444 #endif
445
446 fd = open("/dev/msm_snd", O_RDWR);
447 if (fd < 0) {
448 ALOGE("Can not open snd device");
449 return -EPERM;
450 }
451 // RPC call to switch audio path
452 /* rpc_snd_set_device(
453 * device, # Hardware device enum to use
454 * ear_mute, # Set mute for outgoing voice audio
455 * # this should only be unmuted when in-call
456 * mic_mute, # Set mute for incoming voice audio
457 * # this should only be unmuted when in-call or
458 * # recording.
459 * )
460 */
461 struct msm_snd_device_config args;
462 args.device = device;
463 args.ear_mute = ear_mute ? SND_MUTE_MUTED : SND_MUTE_UNMUTED;
464 args.mic_mute = mic_mute ? SND_MUTE_MUTED : SND_MUTE_UNMUTED;
465
466 if (ioctl(fd, SND_SET_DEVICE, &args) < 0) {
467 ALOGE("snd_set_device error.");
468 close(fd);
469 return -EIO;
470 }
471
472 close(fd);
473 return NO_ERROR;
474 }
475
476 // always call with mutex held
doAudioRouteOrMute(uint32_t device)477 status_t AudioHardware::doAudioRouteOrMute(uint32_t device)
478 {
479 if (device == (uint32_t)SND_DEVICE_BT || device == (uint32_t)SND_DEVICE_CARKIT) {
480 if (mBluetoothId) {
481 device = mBluetoothId;
482 } else if (!mBluetoothNrec) {
483 device = SND_DEVICE_BT_EC_OFF;
484 }
485 }
486 ALOGV("doAudioRouteOrMute() device %x, mMode %d, mMicMute %d", device, mMode, mMicMute);
487 return do_route_audio_rpc(device,
488 mMode != AudioSystem::MODE_IN_CALL, mMicMute);
489 }
490
doRouting()491 status_t AudioHardware::doRouting()
492 {
493 /* currently this code doesn't work without the htc libacoustic */
494 if (!acoustic)
495 return 0;
496
497 Mutex::Autolock lock(mLock);
498 uint32_t outputDevices = mOutput->devices();
499 status_t ret = NO_ERROR;
500 int (*msm72xx_enable_audpp)(int);
501 msm72xx_enable_audpp = (int (*)(int))::dlsym(acoustic, "msm72xx_enable_audpp");
502 int audProcess = (ADRC_DISABLE | EQ_DISABLE | RX_IIR_DISABLE);
503 AudioStreamInMSM72xx *input = getActiveInput_l();
504 uint32_t inputDevice = (input == NULL) ? 0 : input->devices();
505 int sndDevice = -1;
506
507 if (inputDevice != 0) {
508 ALOGI("do input routing device %x\n", inputDevice);
509 if (inputDevice & AudioSystem::DEVICE_IN_BLUETOOTH_SCO_HEADSET) {
510 ALOGI("Routing audio to Bluetooth PCM\n");
511 sndDevice = SND_DEVICE_BT;
512 } else if (inputDevice & AudioSystem::DEVICE_IN_WIRED_HEADSET) {
513 if ((outputDevices & AudioSystem::DEVICE_OUT_WIRED_HEADSET) &&
514 (outputDevices & AudioSystem::DEVICE_OUT_SPEAKER)) {
515 ALOGI("Routing audio to Wired Headset and Speaker\n");
516 sndDevice = SND_DEVICE_HEADSET_AND_SPEAKER;
517 audProcess = (ADRC_ENABLE | EQ_ENABLE | RX_IIR_ENABLE);
518 } else {
519 ALOGI("Routing audio to Wired Headset\n");
520 sndDevice = SND_DEVICE_HEADSET;
521 }
522 } else {
523 if (outputDevices & AudioSystem::DEVICE_OUT_SPEAKER) {
524 ALOGI("Routing audio to Speakerphone\n");
525 sndDevice = SND_DEVICE_SPEAKER;
526 audProcess = (ADRC_ENABLE | EQ_ENABLE | RX_IIR_ENABLE);
527 } else {
528 ALOGI("Routing audio to Handset\n");
529 sndDevice = SND_DEVICE_HANDSET;
530 }
531 }
532 }
533 // if inputDevice == 0, restore output routing
534
535 if (sndDevice == -1) {
536 if (outputDevices & (outputDevices - 1)) {
537 if ((outputDevices & AudioSystem::DEVICE_OUT_SPEAKER) == 0) {
538 ALOGW("Hardware does not support requested route combination (%#X),"
539 " picking closest possible route...", outputDevices);
540 }
541 }
542
543 if (outputDevices &
544 (AudioSystem::DEVICE_OUT_BLUETOOTH_SCO | AudioSystem::DEVICE_OUT_BLUETOOTH_SCO_HEADSET)) {
545 ALOGI("Routing audio to Bluetooth PCM\n");
546 sndDevice = SND_DEVICE_BT;
547 } else if (outputDevices & AudioSystem::DEVICE_OUT_BLUETOOTH_SCO_CARKIT) {
548 ALOGI("Routing audio to Bluetooth PCM\n");
549 sndDevice = SND_DEVICE_CARKIT;
550 } else if ((outputDevices & AudioSystem::DEVICE_OUT_WIRED_HEADSET) &&
551 (outputDevices & AudioSystem::DEVICE_OUT_SPEAKER)) {
552 ALOGI("Routing audio to Wired Headset and Speaker\n");
553 sndDevice = SND_DEVICE_HEADSET_AND_SPEAKER;
554 audProcess = (ADRC_ENABLE | EQ_ENABLE | RX_IIR_ENABLE);
555 } else if (outputDevices & AudioSystem::DEVICE_OUT_WIRED_HEADPHONE) {
556 if (outputDevices & AudioSystem::DEVICE_OUT_SPEAKER) {
557 ALOGI("Routing audio to No microphone Wired Headset and Speaker (%d,%x)\n", mMode, outputDevices);
558 sndDevice = SND_DEVICE_HEADSET_AND_SPEAKER;
559 audProcess = (ADRC_ENABLE | EQ_ENABLE | RX_IIR_ENABLE);
560 } else {
561 ALOGI("Routing audio to No microphone Wired Headset (%d,%x)\n", mMode, outputDevices);
562 sndDevice = SND_DEVICE_NO_MIC_HEADSET;
563 }
564 } else if (outputDevices & AudioSystem::DEVICE_OUT_WIRED_HEADSET) {
565 ALOGI("Routing audio to Wired Headset\n");
566 sndDevice = SND_DEVICE_HEADSET;
567 } else if (outputDevices & AudioSystem::DEVICE_OUT_SPEAKER) {
568 ALOGI("Routing audio to Speakerphone\n");
569 sndDevice = SND_DEVICE_SPEAKER;
570 audProcess = (ADRC_ENABLE | EQ_ENABLE | RX_IIR_ENABLE);
571 } else {
572 ALOGI("Routing audio to Handset\n");
573 sndDevice = SND_DEVICE_HANDSET;
574 }
575 }
576
577 if (sndDevice != -1 && sndDevice != mCurSndDevice) {
578 ret = doAudioRouteOrMute(sndDevice);
579 if ((*msm72xx_enable_audpp) == 0 ) {
580 ALOGE("Could not open msm72xx_enable_audpp()");
581 } else {
582 msm72xx_enable_audpp(audProcess);
583 }
584 mCurSndDevice = sndDevice;
585 }
586
587 return ret;
588 }
589
checkMicMute()590 status_t AudioHardware::checkMicMute()
591 {
592 Mutex::Autolock lock(mLock);
593 if (mMode != AudioSystem::MODE_IN_CALL) {
594 setMicMute_nosync(true);
595 }
596
597 return NO_ERROR;
598 }
599
dumpInternals(int fd,const Vector<String16> & args)600 status_t AudioHardware::dumpInternals(int fd, const Vector<String16>& args)
601 {
602 const size_t SIZE = 256;
603 char buffer[SIZE];
604 String8 result;
605 result.append("AudioHardware::dumpInternals\n");
606 snprintf(buffer, SIZE, "\tmInit: %s\n", mInit? "true": "false");
607 result.append(buffer);
608 snprintf(buffer, SIZE, "\tmMicMute: %s\n", mMicMute? "true": "false");
609 result.append(buffer);
610 snprintf(buffer, SIZE, "\tmBluetoothNrec: %s\n", mBluetoothNrec? "true": "false");
611 result.append(buffer);
612 snprintf(buffer, SIZE, "\tmBluetoothId: %d\n", mBluetoothId);
613 result.append(buffer);
614 ::write(fd, result.string(), result.size());
615 return NO_ERROR;
616 }
617
dump(int fd,const Vector<String16> & args)618 status_t AudioHardware::dump(int fd, const Vector<String16>& args)
619 {
620 dumpInternals(fd, args);
621 for (size_t index = 0; index < mInputs.size(); index++) {
622 mInputs[index]->dump(fd, args);
623 }
624
625 if (mOutput) {
626 mOutput->dump(fd, args);
627 }
628 return NO_ERROR;
629 }
630
getInputSampleRate(uint32_t sampleRate)631 uint32_t AudioHardware::getInputSampleRate(uint32_t sampleRate)
632 {
633 uint32_t i;
634 uint32_t prevDelta;
635 uint32_t delta;
636
637 for (i = 0, prevDelta = 0xFFFFFFFF; i < sizeof(inputSamplingRates)/sizeof(uint32_t); i++, prevDelta = delta) {
638 delta = abs(sampleRate - inputSamplingRates[i]);
639 if (delta > prevDelta) break;
640 }
641 // i is always > 0 here
642 return inputSamplingRates[i-1];
643 }
644
645 // getActiveInput_l() must be called with mLock held
getActiveInput_l()646 AudioHardware::AudioStreamInMSM72xx *AudioHardware::getActiveInput_l()
647 {
648 for (size_t i = 0; i < mInputs.size(); i++) {
649 // return first input found not being in standby mode
650 // as only one input can be in this state
651 if (mInputs[i]->state() > AudioStreamInMSM72xx::AUDIO_INPUT_CLOSED) {
652 return mInputs[i];
653 }
654 }
655
656 return NULL;
657 }
658 // ----------------------------------------------------------------------------
659
AudioStreamOutMSM72xx()660 AudioHardware::AudioStreamOutMSM72xx::AudioStreamOutMSM72xx() :
661 mHardware(0), mFd(-1), mStartCount(0), mRetryCount(0), mStandby(true), mDevices(0)
662 {
663 }
664
set(AudioHardware * hw,uint32_t devices,int * pFormat,uint32_t * pChannels,uint32_t * pRate)665 status_t AudioHardware::AudioStreamOutMSM72xx::set(
666 AudioHardware* hw, uint32_t devices, int *pFormat, uint32_t *pChannels, uint32_t *pRate)
667 {
668 int lFormat = pFormat ? *pFormat : 0;
669 uint32_t lChannels = pChannels ? *pChannels : 0;
670 uint32_t lRate = pRate ? *pRate : 0;
671
672 mHardware = hw;
673
674 // fix up defaults
675 if (lFormat == 0) lFormat = format();
676 if (lChannels == 0) lChannels = channels();
677 if (lRate == 0) lRate = sampleRate();
678
679 // check values
680 if ((lFormat != format()) ||
681 (lChannels != channels()) ||
682 (lRate != sampleRate())) {
683 if (pFormat) *pFormat = format();
684 if (pChannels) *pChannels = channels();
685 if (pRate) *pRate = sampleRate();
686 return BAD_VALUE;
687 }
688
689 if (pFormat) *pFormat = lFormat;
690 if (pChannels) *pChannels = lChannels;
691 if (pRate) *pRate = lRate;
692
693 mDevices = devices;
694
695 return NO_ERROR;
696 }
697
~AudioStreamOutMSM72xx()698 AudioHardware::AudioStreamOutMSM72xx::~AudioStreamOutMSM72xx()
699 {
700 if (mFd >= 0) close(mFd);
701 }
702
write(const void * buffer,size_t bytes)703 ssize_t AudioHardware::AudioStreamOutMSM72xx::write(const void* buffer, size_t bytes)
704 {
705 // ALOGD("AudioStreamOutMSM72xx::write(%p, %u)", buffer, bytes);
706 status_t status = NO_INIT;
707 size_t count = bytes;
708 const uint8_t* p = static_cast<const uint8_t*>(buffer);
709
710 if (mStandby) {
711
712 // open driver
713 ALOGV("open driver");
714 status = ::open("/dev/msm_pcm_out", O_RDWR);
715 if (status < 0) {
716 ALOGE("Cannot open /dev/msm_pcm_out errno: %d", errno);
717 goto Error;
718 }
719 mFd = status;
720
721 // configuration
722 ALOGV("get config");
723 struct msm_audio_config config;
724 status = ioctl(mFd, AUDIO_GET_CONFIG, &config);
725 if (status < 0) {
726 ALOGE("Cannot read config");
727 goto Error;
728 }
729
730 ALOGV("set config");
731 config.channel_count = AudioSystem::popCount(channels());
732 config.sample_rate = sampleRate();
733 config.buffer_size = bufferSize();
734 config.buffer_count = AUDIO_HW_NUM_OUT_BUF;
735 config.codec_type = CODEC_TYPE_PCM;
736 status = ioctl(mFd, AUDIO_SET_CONFIG, &config);
737 if (status < 0) {
738 ALOGE("Cannot set config");
739 goto Error;
740 }
741
742 ALOGV("buffer_size: %u", config.buffer_size);
743 ALOGV("buffer_count: %u", config.buffer_count);
744 ALOGV("channel_count: %u", config.channel_count);
745 ALOGV("sample_rate: %u", config.sample_rate);
746
747 // fill 2 buffers before AUDIO_START
748 mStartCount = AUDIO_HW_NUM_OUT_BUF;
749 mStandby = false;
750 }
751
752 while (count) {
753 ssize_t written = ::write(mFd, p, count);
754 if (written >= 0) {
755 count -= written;
756 p += written;
757 } else {
758 if (errno != EAGAIN) return written;
759 mRetryCount++;
760 ALOGW("EAGAIN - retry");
761 }
762 }
763
764 // start audio after we fill 2 buffers
765 if (mStartCount) {
766 if (--mStartCount == 0) {
767 ioctl(mFd, AUDIO_START, 0);
768 }
769 }
770 return bytes;
771
772 Error:
773 if (mFd >= 0) {
774 ::close(mFd);
775 mFd = -1;
776 }
777 // Simulate audio output timing in case of error
778 usleep(bytes * 1000000 / frameSize() / sampleRate());
779
780 return status;
781 }
782
standby()783 status_t AudioHardware::AudioStreamOutMSM72xx::standby()
784 {
785 status_t status = NO_ERROR;
786 if (!mStandby && mFd >= 0) {
787 ::close(mFd);
788 mFd = -1;
789 }
790 mStandby = true;
791 return status;
792 }
793
dump(int fd,const Vector<String16> & args)794 status_t AudioHardware::AudioStreamOutMSM72xx::dump(int fd, const Vector<String16>& args)
795 {
796 const size_t SIZE = 256;
797 char buffer[SIZE];
798 String8 result;
799 result.append("AudioStreamOutMSM72xx::dump\n");
800 snprintf(buffer, SIZE, "\tsample rate: %d\n", sampleRate());
801 result.append(buffer);
802 snprintf(buffer, SIZE, "\tbuffer size: %d\n", bufferSize());
803 result.append(buffer);
804 snprintf(buffer, SIZE, "\tchannels: %d\n", channels());
805 result.append(buffer);
806 snprintf(buffer, SIZE, "\tformat: %d\n", format());
807 result.append(buffer);
808 snprintf(buffer, SIZE, "\tmHardware: %p\n", mHardware);
809 result.append(buffer);
810 snprintf(buffer, SIZE, "\tmFd: %d\n", mFd);
811 result.append(buffer);
812 snprintf(buffer, SIZE, "\tmStartCount: %d\n", mStartCount);
813 result.append(buffer);
814 snprintf(buffer, SIZE, "\tmRetryCount: %d\n", mRetryCount);
815 result.append(buffer);
816 snprintf(buffer, SIZE, "\tmStandby: %s\n", mStandby? "true": "false");
817 result.append(buffer);
818 ::write(fd, result.string(), result.size());
819 return NO_ERROR;
820 }
821
checkStandby()822 bool AudioHardware::AudioStreamOutMSM72xx::checkStandby()
823 {
824 return mStandby;
825 }
826
827
setParameters(const String8 & keyValuePairs)828 status_t AudioHardware::AudioStreamOutMSM72xx::setParameters(const String8& keyValuePairs)
829 {
830 AudioParameter param = AudioParameter(keyValuePairs);
831 String8 key = String8(AudioParameter::keyRouting);
832 status_t status = NO_ERROR;
833 int device;
834 ALOGV("AudioStreamOutMSM72xx::setParameters() %s", keyValuePairs.string());
835
836 if (param.getInt(key, device) == NO_ERROR) {
837 mDevices = device;
838 ALOGV("set output routing %x", mDevices);
839 status = mHardware->doRouting();
840 param.remove(key);
841 }
842
843 if (param.size()) {
844 status = BAD_VALUE;
845 }
846 return status;
847 }
848
getParameters(const String8 & keys)849 String8 AudioHardware::AudioStreamOutMSM72xx::getParameters(const String8& keys)
850 {
851 AudioParameter param = AudioParameter(keys);
852 String8 value;
853 String8 key = String8(AudioParameter::keyRouting);
854
855 if (param.get(key, value) == NO_ERROR) {
856 ALOGV("get routing %x", mDevices);
857 param.addInt(key, (int)mDevices);
858 }
859
860 ALOGV("AudioStreamOutMSM72xx::getParameters() %s", param.toString().string());
861 return param.toString();
862 }
863
getRenderPosition(uint32_t * dspFrames)864 status_t AudioHardware::AudioStreamOutMSM72xx::getRenderPosition(uint32_t *dspFrames)
865 {
866 //TODO: enable when supported by driver
867 return INVALID_OPERATION;
868 }
869
870 // ----------------------------------------------------------------------------
871
AudioStreamInMSM72xx()872 AudioHardware::AudioStreamInMSM72xx::AudioStreamInMSM72xx() :
873 mHardware(0), mFd(-1), mState(AUDIO_INPUT_CLOSED), mRetryCount(0),
874 mFormat(AUDIO_HW_IN_FORMAT), mChannels(AUDIO_HW_IN_CHANNELS),
875 mSampleRate(AUDIO_HW_IN_SAMPLERATE), mBufferSize(AUDIO_HW_IN_BUFFERSIZE),
876 mAcoustics((AudioSystem::audio_in_acoustics)0), mDevices(0)
877 {
878 }
879
set(AudioHardware * hw,uint32_t devices,int * pFormat,uint32_t * pChannels,uint32_t * pRate,AudioSystem::audio_in_acoustics acoustic_flags)880 status_t AudioHardware::AudioStreamInMSM72xx::set(
881 AudioHardware* hw, uint32_t devices, int *pFormat, uint32_t *pChannels, uint32_t *pRate,
882 AudioSystem::audio_in_acoustics acoustic_flags)
883 {
884 if (pFormat == 0 || *pFormat != AUDIO_HW_IN_FORMAT) {
885 *pFormat = AUDIO_HW_IN_FORMAT;
886 return BAD_VALUE;
887 }
888 if (pRate == 0) {
889 return BAD_VALUE;
890 }
891 uint32_t rate = hw->getInputSampleRate(*pRate);
892 if (rate != *pRate) {
893 *pRate = rate;
894 return BAD_VALUE;
895 }
896
897 if (pChannels == 0 || (*pChannels != AudioSystem::CHANNEL_IN_MONO &&
898 *pChannels != AudioSystem::CHANNEL_IN_STEREO)) {
899 *pChannels = AUDIO_HW_IN_CHANNELS;
900 return BAD_VALUE;
901 }
902
903 mHardware = hw;
904
905 ALOGV("AudioStreamInMSM72xx::set(%d, %d, %u)", *pFormat, *pChannels, *pRate);
906 if (mFd >= 0) {
907 ALOGE("Audio record already open");
908 return -EPERM;
909 }
910
911 // open audio input device
912 status_t status = ::open("/dev/msm_pcm_in", O_RDWR);
913 if (status < 0) {
914 ALOGE("Cannot open /dev/msm_pcm_in errno: %d", errno);
915 goto Error;
916 }
917 mFd = status;
918
919 // configuration
920 ALOGV("get config");
921 struct msm_audio_config config;
922 status = ioctl(mFd, AUDIO_GET_CONFIG, &config);
923 if (status < 0) {
924 ALOGE("Cannot read config");
925 goto Error;
926 }
927
928 ALOGV("set config");
929 config.channel_count = AudioSystem::popCount(*pChannels);
930 config.sample_rate = *pRate;
931 config.buffer_size = bufferSize();
932 config.buffer_count = 2;
933 config.codec_type = CODEC_TYPE_PCM;
934 status = ioctl(mFd, AUDIO_SET_CONFIG, &config);
935 if (status < 0) {
936 ALOGE("Cannot set config");
937 if (ioctl(mFd, AUDIO_GET_CONFIG, &config) == 0) {
938 if (config.channel_count == 1) {
939 *pChannels = AudioSystem::CHANNEL_IN_MONO;
940 } else {
941 *pChannels = AudioSystem::CHANNEL_IN_STEREO;
942 }
943 *pRate = config.sample_rate;
944 }
945 goto Error;
946 }
947
948 ALOGV("confirm config");
949 status = ioctl(mFd, AUDIO_GET_CONFIG, &config);
950 if (status < 0) {
951 ALOGE("Cannot read config");
952 goto Error;
953 }
954 ALOGV("buffer_size: %u", config.buffer_size);
955 ALOGV("buffer_count: %u", config.buffer_count);
956 ALOGV("channel_count: %u", config.channel_count);
957 ALOGV("sample_rate: %u", config.sample_rate);
958
959 mDevices = devices;
960 mFormat = AUDIO_HW_IN_FORMAT;
961 mChannels = *pChannels;
962 mSampleRate = config.sample_rate;
963 mBufferSize = config.buffer_size;
964
965 //mHardware->setMicMute_nosync(false);
966 mState = AUDIO_INPUT_OPENED;
967
968 if (!acoustic)
969 return NO_ERROR;
970
971 audpre_index = calculate_audpre_table_index(mSampleRate);
972 tx_iir_index = (audpre_index * 2) + (hw->checkOutputStandby() ? 0 : 1);
973 ALOGD("audpre_index = %d, tx_iir_index = %d\n", audpre_index, tx_iir_index);
974
975 /**
976 * If audio-preprocessing failed, we should not block record.
977 */
978 int (*msm72xx_set_audpre_params)(int, int);
979 msm72xx_set_audpre_params = (int (*)(int, int))::dlsym(acoustic, "msm72xx_set_audpre_params");
980 status = msm72xx_set_audpre_params(audpre_index, tx_iir_index);
981 if (status < 0)
982 ALOGE("Cannot set audpre parameters");
983
984 int (*msm72xx_enable_audpre)(int, int, int);
985 msm72xx_enable_audpre = (int (*)(int, int, int))::dlsym(acoustic, "msm72xx_enable_audpre");
986 mAcoustics = acoustic_flags;
987 status = msm72xx_enable_audpre((int)acoustic_flags, audpre_index, tx_iir_index);
988 if (status < 0)
989 ALOGE("Cannot enable audpre");
990
991 return NO_ERROR;
992
993 Error:
994 if (mFd >= 0) {
995 ::close(mFd);
996 mFd = -1;
997 }
998 return status;
999 }
1000
~AudioStreamInMSM72xx()1001 AudioHardware::AudioStreamInMSM72xx::~AudioStreamInMSM72xx()
1002 {
1003 ALOGV("AudioStreamInMSM72xx destructor");
1004 standby();
1005 }
1006
read(void * buffer,ssize_t bytes)1007 ssize_t AudioHardware::AudioStreamInMSM72xx::read( void* buffer, ssize_t bytes)
1008 {
1009 ALOGV("AudioStreamInMSM72xx::read(%p, %ld)", buffer, bytes);
1010 if (!mHardware) return -1;
1011
1012 size_t count = bytes;
1013 uint8_t* p = static_cast<uint8_t*>(buffer);
1014
1015 if (mState < AUDIO_INPUT_OPENED) {
1016 Mutex::Autolock lock(mHardware->mLock);
1017 if (set(mHardware, mDevices, &mFormat, &mChannels, &mSampleRate, mAcoustics) != NO_ERROR) {
1018 return -1;
1019 }
1020 }
1021
1022 if (mState < AUDIO_INPUT_STARTED) {
1023 mState = AUDIO_INPUT_STARTED;
1024 // force routing to input device
1025 mHardware->clearCurDevice();
1026 mHardware->doRouting();
1027 if (ioctl(mFd, AUDIO_START, 0)) {
1028 ALOGE("Error starting record");
1029 standby();
1030 return -1;
1031 }
1032 }
1033
1034 while (count) {
1035 ssize_t bytesRead = ::read(mFd, buffer, count);
1036 if (bytesRead >= 0) {
1037 count -= bytesRead;
1038 p += bytesRead;
1039 } else {
1040 if (errno != EAGAIN) return bytesRead;
1041 mRetryCount++;
1042 ALOGW("EAGAIN - retrying");
1043 }
1044 }
1045 return bytes;
1046 }
1047
standby()1048 status_t AudioHardware::AudioStreamInMSM72xx::standby()
1049 {
1050 if (mState > AUDIO_INPUT_CLOSED) {
1051 if (mFd >= 0) {
1052 ::close(mFd);
1053 mFd = -1;
1054 }
1055 mState = AUDIO_INPUT_CLOSED;
1056 }
1057 if (!mHardware) return -1;
1058 // restore output routing if necessary
1059 mHardware->clearCurDevice();
1060 mHardware->doRouting();
1061 return NO_ERROR;
1062 }
1063
dump(int fd,const Vector<String16> & args)1064 status_t AudioHardware::AudioStreamInMSM72xx::dump(int fd, const Vector<String16>& args)
1065 {
1066 const size_t SIZE = 256;
1067 char buffer[SIZE];
1068 String8 result;
1069 result.append("AudioStreamInMSM72xx::dump\n");
1070 snprintf(buffer, SIZE, "\tsample rate: %d\n", sampleRate());
1071 result.append(buffer);
1072 snprintf(buffer, SIZE, "\tbuffer size: %d\n", bufferSize());
1073 result.append(buffer);
1074 snprintf(buffer, SIZE, "\tchannels: %d\n", channels());
1075 result.append(buffer);
1076 snprintf(buffer, SIZE, "\tformat: %d\n", format());
1077 result.append(buffer);
1078 snprintf(buffer, SIZE, "\tmHardware: %p\n", mHardware);
1079 result.append(buffer);
1080 snprintf(buffer, SIZE, "\tmFd count: %d\n", mFd);
1081 result.append(buffer);
1082 snprintf(buffer, SIZE, "\tmState: %d\n", mState);
1083 result.append(buffer);
1084 snprintf(buffer, SIZE, "\tmRetryCount: %d\n", mRetryCount);
1085 result.append(buffer);
1086 ::write(fd, result.string(), result.size());
1087 return NO_ERROR;
1088 }
1089
setParameters(const String8 & keyValuePairs)1090 status_t AudioHardware::AudioStreamInMSM72xx::setParameters(const String8& keyValuePairs)
1091 {
1092 AudioParameter param = AudioParameter(keyValuePairs);
1093 String8 key = String8(AudioParameter::keyRouting);
1094 status_t status = NO_ERROR;
1095 int device;
1096 ALOGV("AudioStreamInMSM72xx::setParameters() %s", keyValuePairs.string());
1097
1098 if (param.getInt(key, device) == NO_ERROR) {
1099 ALOGV("set input routing %x", device);
1100 if (device & (device - 1)) {
1101 status = BAD_VALUE;
1102 } else {
1103 mDevices = device;
1104 status = mHardware->doRouting();
1105 }
1106 param.remove(key);
1107 }
1108
1109 if (param.size()) {
1110 status = BAD_VALUE;
1111 }
1112 return status;
1113 }
1114
getParameters(const String8 & keys)1115 String8 AudioHardware::AudioStreamInMSM72xx::getParameters(const String8& keys)
1116 {
1117 AudioParameter param = AudioParameter(keys);
1118 String8 value;
1119 String8 key = String8(AudioParameter::keyRouting);
1120
1121 if (param.get(key, value) == NO_ERROR) {
1122 ALOGV("get routing %x", mDevices);
1123 param.addInt(key, (int)mDevices);
1124 }
1125
1126 ALOGV("AudioStreamInMSM72xx::getParameters() %s", param.toString().string());
1127 return param.toString();
1128 }
1129
1130 // ----------------------------------------------------------------------------
1131
createAudioHardware(void)1132 extern "C" AudioHardwareInterface* createAudioHardware(void) {
1133 return new AudioHardware();
1134 }
1135
1136 }; // namespace android
1137