1 /*
2 ** Copyright 2008, Google Inc.
3 **
4 ** Licensed under the Apache License, Version 2.0 (the "License");
5 ** you may not use this file except in compliance with the License.
6 ** You may obtain a copy of the License at
7 **
8 ** http://www.apache.org/licenses/LICENSE-2.0
9 **
10 ** Unless required by applicable law or agreed to in writing, software
11 ** distributed under the License is distributed on an "AS IS" BASIS,
12 ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 ** See the License for the specific language governing permissions and
14 ** limitations under the License.
15 */
16
17 #include <math.h>
18
19 //#define LOG_NDEBUG 0
20 #define LOG_TAG "AudioHardwareMSM72XX"
21 #include <utils/Log.h>
22 #include <utils/String8.h>
23
24 #include <stdio.h>
25 #include <unistd.h>
26 #include <sys/ioctl.h>
27 #include <sys/types.h>
28 #include <sys/stat.h>
29 #include <dlfcn.h>
30 #include <fcntl.h>
31
32 // hardware specific functions
33
34 #include "AudioHardware.h"
35 #include <media/AudioRecord.h>
36
37 #define LOG_SND_RPC 0 // Set to 1 to log sound RPC's
38
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 LOGE("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 LOGE("Could not open set_acoustic_parameters()");
84 return;
85 }
86
87 int rc = set_acoustic_parameters();
88 if (rc < 0) {
89 LOGE("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 LOGE("Could not open snd_get_num()");
96 // return;
97 }
98
99 mNumSndEndpoints = snd_get_num();
100 LOGD("mNumSndEndpoints = %d", mNumSndEndpoints);
101 mSndEndpoints = new msm_snd_endpoint[mNumSndEndpoints];
102 mInit = true;
103 LOGV("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 LOGE("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 LOGD("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 LOGW("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 LOGW("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 mCurSndDevice = -1;
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 LOGV("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 LOGI("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 LOGI("Using custom acoustic parameters for %s", value.string());
312 break;
313 }
314 }
315 if (mBluetoothId == 0) {
316 LOGI("Using default acoustic parameters "
317 "(%s not in acoustic database)", value.string());
318 doRouting(NULL);
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 LOGW("getInputBufferSize bad format: %d", format);
350 return 0;
351 }
352 if (channelCount < 1 || channelCount > 2) {
353 LOGW("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 LOGD("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 LOGE("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 LOGE("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 LOGW("setVoiceVolume(%f) under 0.0, assuming 0.0\n", v);
403 v = 0.0;
404 } else if (v > 1.0) {
405 LOGW("setVoiceVolume(%f) over 1.0, assuming 1.0\n", v);
406 v = 1.0;
407 }
408
409 int vol = lrint(v * 5.0);
410 LOGD("setVoiceVolume(%f)\n", v);
411 LOGI("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 LOGI("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 LOGD("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 LOGE("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 LOGE("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 LOGV("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(AudioStreamInMSM72xx * input)491 status_t AudioHardware::doRouting(AudioStreamInMSM72xx *input)
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 int sndDevice = -1;
504
505 if (input != NULL) {
506 uint32_t inputDevice = input->devices();
507 LOGI("do input routing device %x\n", inputDevice);
508 if (inputDevice != 0) {
509 if (inputDevice & AudioSystem::DEVICE_IN_BLUETOOTH_SCO_HEADSET) {
510 LOGI("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 LOGI("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 LOGI("Routing audio to Wired Headset\n");
520 sndDevice = SND_DEVICE_HEADSET;
521 }
522 } else {
523 if (outputDevices & AudioSystem::DEVICE_OUT_SPEAKER) {
524 LOGI("Routing audio to Speakerphone\n");
525 sndDevice = SND_DEVICE_SPEAKER;
526 audProcess = (ADRC_ENABLE | EQ_ENABLE | RX_IIR_ENABLE);
527 } else {
528 LOGI("Routing audio to Handset\n");
529 sndDevice = SND_DEVICE_HANDSET;
530 }
531 }
532 }
533 // if inputDevice == 0, restore output routing
534 }
535
536 if (sndDevice == -1) {
537 if (outputDevices & (outputDevices - 1)) {
538 if ((outputDevices & AudioSystem::DEVICE_OUT_SPEAKER) == 0) {
539 LOGW("Hardware does not support requested route combination (%#X),"
540 " picking closest possible route...", outputDevices);
541 }
542 }
543
544 if (outputDevices &
545 (AudioSystem::DEVICE_OUT_BLUETOOTH_SCO | AudioSystem::DEVICE_OUT_BLUETOOTH_SCO_HEADSET)) {
546 LOGI("Routing audio to Bluetooth PCM\n");
547 sndDevice = SND_DEVICE_BT;
548 } else if (outputDevices & AudioSystem::DEVICE_OUT_BLUETOOTH_SCO_CARKIT) {
549 LOGI("Routing audio to Bluetooth PCM\n");
550 sndDevice = SND_DEVICE_CARKIT;
551 } else if ((outputDevices & AudioSystem::DEVICE_OUT_WIRED_HEADSET) &&
552 (outputDevices & AudioSystem::DEVICE_OUT_SPEAKER)) {
553 LOGI("Routing audio to Wired Headset and Speaker\n");
554 sndDevice = SND_DEVICE_HEADSET_AND_SPEAKER;
555 audProcess = (ADRC_ENABLE | EQ_ENABLE | RX_IIR_ENABLE);
556 } else if (outputDevices & AudioSystem::DEVICE_OUT_WIRED_HEADPHONE) {
557 if (outputDevices & AudioSystem::DEVICE_OUT_SPEAKER) {
558 LOGI("Routing audio to No microphone Wired Headset and Speaker (%d,%x)\n", mMode, outputDevices);
559 sndDevice = SND_DEVICE_HEADSET_AND_SPEAKER;
560 audProcess = (ADRC_ENABLE | EQ_ENABLE | RX_IIR_ENABLE);
561 } else {
562 LOGI("Routing audio to No microphone Wired Headset (%d,%x)\n", mMode, outputDevices);
563 sndDevice = SND_DEVICE_NO_MIC_HEADSET;
564 }
565 } else if (outputDevices & AudioSystem::DEVICE_OUT_WIRED_HEADSET) {
566 LOGI("Routing audio to Wired Headset\n");
567 sndDevice = SND_DEVICE_HEADSET;
568 } else if (outputDevices & AudioSystem::DEVICE_OUT_SPEAKER) {
569 LOGI("Routing audio to Speakerphone\n");
570 sndDevice = SND_DEVICE_SPEAKER;
571 audProcess = (ADRC_ENABLE | EQ_ENABLE | RX_IIR_ENABLE);
572 } else {
573 LOGI("Routing audio to Handset\n");
574 sndDevice = SND_DEVICE_HANDSET;
575 }
576 }
577
578 if (sndDevice != -1 && sndDevice != mCurSndDevice) {
579 ret = doAudioRouteOrMute(sndDevice);
580 if ((*msm72xx_enable_audpp) == 0 ) {
581 LOGE("Could not open msm72xx_enable_audpp()");
582 } else {
583 msm72xx_enable_audpp(audProcess);
584 }
585 mCurSndDevice = sndDevice;
586 }
587
588 return ret;
589 }
590
checkMicMute()591 status_t AudioHardware::checkMicMute()
592 {
593 Mutex::Autolock lock(mLock);
594 if (mMode != AudioSystem::MODE_IN_CALL) {
595 setMicMute_nosync(true);
596 }
597
598 return NO_ERROR;
599 }
600
dumpInternals(int fd,const Vector<String16> & args)601 status_t AudioHardware::dumpInternals(int fd, const Vector<String16>& args)
602 {
603 const size_t SIZE = 256;
604 char buffer[SIZE];
605 String8 result;
606 result.append("AudioHardware::dumpInternals\n");
607 snprintf(buffer, SIZE, "\tmInit: %s\n", mInit? "true": "false");
608 result.append(buffer);
609 snprintf(buffer, SIZE, "\tmMicMute: %s\n", mMicMute? "true": "false");
610 result.append(buffer);
611 snprintf(buffer, SIZE, "\tmBluetoothNrec: %s\n", mBluetoothNrec? "true": "false");
612 result.append(buffer);
613 snprintf(buffer, SIZE, "\tmBluetoothId: %d\n", mBluetoothId);
614 result.append(buffer);
615 ::write(fd, result.string(), result.size());
616 return NO_ERROR;
617 }
618
dump(int fd,const Vector<String16> & args)619 status_t AudioHardware::dump(int fd, const Vector<String16>& args)
620 {
621 dumpInternals(fd, args);
622 for (size_t index = 0; index < mInputs.size(); index++) {
623 mInputs[index]->dump(fd, args);
624 }
625
626 if (mOutput) {
627 mOutput->dump(fd, args);
628 }
629 return NO_ERROR;
630 }
631
getInputSampleRate(uint32_t sampleRate)632 uint32_t AudioHardware::getInputSampleRate(uint32_t sampleRate)
633 {
634 uint32_t i;
635 uint32_t prevDelta;
636 uint32_t delta;
637
638 for (i = 0, prevDelta = 0xFFFFFFFF; i < sizeof(inputSamplingRates)/sizeof(uint32_t); i++, prevDelta = delta) {
639 delta = abs(sampleRate - inputSamplingRates[i]);
640 if (delta > prevDelta) break;
641 }
642 // i is always > 0 here
643 return inputSamplingRates[i-1];
644 }
645
646 // ----------------------------------------------------------------------------
647
AudioStreamOutMSM72xx()648 AudioHardware::AudioStreamOutMSM72xx::AudioStreamOutMSM72xx() :
649 mHardware(0), mFd(-1), mStartCount(0), mRetryCount(0), mStandby(true), mDevices(0)
650 {
651 }
652
set(AudioHardware * hw,uint32_t devices,int * pFormat,uint32_t * pChannels,uint32_t * pRate)653 status_t AudioHardware::AudioStreamOutMSM72xx::set(
654 AudioHardware* hw, uint32_t devices, int *pFormat, uint32_t *pChannels, uint32_t *pRate)
655 {
656 int lFormat = pFormat ? *pFormat : 0;
657 uint32_t lChannels = pChannels ? *pChannels : 0;
658 uint32_t lRate = pRate ? *pRate : 0;
659
660 mHardware = hw;
661
662 // fix up defaults
663 if (lFormat == 0) lFormat = format();
664 if (lChannels == 0) lChannels = channels();
665 if (lRate == 0) lRate = sampleRate();
666
667 // check values
668 if ((lFormat != format()) ||
669 (lChannels != channels()) ||
670 (lRate != sampleRate())) {
671 if (pFormat) *pFormat = format();
672 if (pChannels) *pChannels = channels();
673 if (pRate) *pRate = sampleRate();
674 return BAD_VALUE;
675 }
676
677 if (pFormat) *pFormat = lFormat;
678 if (pChannels) *pChannels = lChannels;
679 if (pRate) *pRate = lRate;
680
681 mDevices = devices;
682
683 return NO_ERROR;
684 }
685
~AudioStreamOutMSM72xx()686 AudioHardware::AudioStreamOutMSM72xx::~AudioStreamOutMSM72xx()
687 {
688 if (mFd >= 0) close(mFd);
689 }
690
write(const void * buffer,size_t bytes)691 ssize_t AudioHardware::AudioStreamOutMSM72xx::write(const void* buffer, size_t bytes)
692 {
693 // LOGD("AudioStreamOutMSM72xx::write(%p, %u)", buffer, bytes);
694 status_t status = NO_INIT;
695 size_t count = bytes;
696 const uint8_t* p = static_cast<const uint8_t*>(buffer);
697
698 if (mStandby) {
699
700 // open driver
701 LOGV("open driver");
702 status = ::open("/dev/msm_pcm_out", O_RDWR);
703 if (status < 0) {
704 LOGE("Cannot open /dev/msm_pcm_out errno: %d", errno);
705 goto Error;
706 }
707 mFd = status;
708
709 // configuration
710 LOGV("get config");
711 struct msm_audio_config config;
712 status = ioctl(mFd, AUDIO_GET_CONFIG, &config);
713 if (status < 0) {
714 LOGE("Cannot read config");
715 goto Error;
716 }
717
718 LOGV("set config");
719 config.channel_count = AudioSystem::popCount(channels());
720 config.sample_rate = sampleRate();
721 config.buffer_size = bufferSize();
722 config.buffer_count = AUDIO_HW_NUM_OUT_BUF;
723 config.codec_type = CODEC_TYPE_PCM;
724 status = ioctl(mFd, AUDIO_SET_CONFIG, &config);
725 if (status < 0) {
726 LOGE("Cannot set config");
727 goto Error;
728 }
729
730 LOGV("buffer_size: %u", config.buffer_size);
731 LOGV("buffer_count: %u", config.buffer_count);
732 LOGV("channel_count: %u", config.channel_count);
733 LOGV("sample_rate: %u", config.sample_rate);
734
735 // fill 2 buffers before AUDIO_START
736 mStartCount = AUDIO_HW_NUM_OUT_BUF;
737 mStandby = false;
738 }
739
740 while (count) {
741 ssize_t written = ::write(mFd, p, count);
742 if (written >= 0) {
743 count -= written;
744 p += written;
745 } else {
746 if (errno != EAGAIN) return written;
747 mRetryCount++;
748 LOGW("EAGAIN - retry");
749 }
750 }
751
752 // start audio after we fill 2 buffers
753 if (mStartCount) {
754 if (--mStartCount == 0) {
755 ioctl(mFd, AUDIO_START, 0);
756 }
757 }
758 return bytes;
759
760 Error:
761 if (mFd >= 0) {
762 ::close(mFd);
763 mFd = -1;
764 }
765 // Simulate audio output timing in case of error
766 usleep(bytes * 1000000 / frameSize() / sampleRate());
767
768 return status;
769 }
770
standby()771 status_t AudioHardware::AudioStreamOutMSM72xx::standby()
772 {
773 status_t status = NO_ERROR;
774 if (!mStandby && mFd >= 0) {
775 ::close(mFd);
776 mFd = -1;
777 }
778 mStandby = true;
779 return status;
780 }
781
dump(int fd,const Vector<String16> & args)782 status_t AudioHardware::AudioStreamOutMSM72xx::dump(int fd, const Vector<String16>& args)
783 {
784 const size_t SIZE = 256;
785 char buffer[SIZE];
786 String8 result;
787 result.append("AudioStreamOutMSM72xx::dump\n");
788 snprintf(buffer, SIZE, "\tsample rate: %d\n", sampleRate());
789 result.append(buffer);
790 snprintf(buffer, SIZE, "\tbuffer size: %d\n", bufferSize());
791 result.append(buffer);
792 snprintf(buffer, SIZE, "\tchannels: %d\n", channels());
793 result.append(buffer);
794 snprintf(buffer, SIZE, "\tformat: %d\n", format());
795 result.append(buffer);
796 snprintf(buffer, SIZE, "\tmHardware: %p\n", mHardware);
797 result.append(buffer);
798 snprintf(buffer, SIZE, "\tmFd: %d\n", mFd);
799 result.append(buffer);
800 snprintf(buffer, SIZE, "\tmStartCount: %d\n", mStartCount);
801 result.append(buffer);
802 snprintf(buffer, SIZE, "\tmRetryCount: %d\n", mRetryCount);
803 result.append(buffer);
804 snprintf(buffer, SIZE, "\tmStandby: %s\n", mStandby? "true": "false");
805 result.append(buffer);
806 ::write(fd, result.string(), result.size());
807 return NO_ERROR;
808 }
809
checkStandby()810 bool AudioHardware::AudioStreamOutMSM72xx::checkStandby()
811 {
812 return mStandby;
813 }
814
815
setParameters(const String8 & keyValuePairs)816 status_t AudioHardware::AudioStreamOutMSM72xx::setParameters(const String8& keyValuePairs)
817 {
818 AudioParameter param = AudioParameter(keyValuePairs);
819 String8 key = String8(AudioParameter::keyRouting);
820 status_t status = NO_ERROR;
821 int device;
822 LOGV("AudioStreamOutMSM72xx::setParameters() %s", keyValuePairs.string());
823
824 if (param.getInt(key, device) == NO_ERROR) {
825 mDevices = device;
826 LOGV("set output routing %x", mDevices);
827 status = mHardware->doRouting(NULL);
828 param.remove(key);
829 }
830
831 if (param.size()) {
832 status = BAD_VALUE;
833 }
834 return status;
835 }
836
getParameters(const String8 & keys)837 String8 AudioHardware::AudioStreamOutMSM72xx::getParameters(const String8& keys)
838 {
839 AudioParameter param = AudioParameter(keys);
840 String8 value;
841 String8 key = String8(AudioParameter::keyRouting);
842
843 if (param.get(key, value) == NO_ERROR) {
844 LOGV("get routing %x", mDevices);
845 param.addInt(key, (int)mDevices);
846 }
847
848 LOGV("AudioStreamOutMSM72xx::getParameters() %s", param.toString().string());
849 return param.toString();
850 }
851
852
853 // ----------------------------------------------------------------------------
854
AudioStreamInMSM72xx()855 AudioHardware::AudioStreamInMSM72xx::AudioStreamInMSM72xx() :
856 mHardware(0), mFd(-1), mState(AUDIO_INPUT_CLOSED), mRetryCount(0),
857 mFormat(AUDIO_HW_IN_FORMAT), mChannels(AUDIO_HW_IN_CHANNELS),
858 mSampleRate(AUDIO_HW_IN_SAMPLERATE), mBufferSize(AUDIO_HW_IN_BUFFERSIZE),
859 mAcoustics((AudioSystem::audio_in_acoustics)0), mDevices(0)
860 {
861 }
862
set(AudioHardware * hw,uint32_t devices,int * pFormat,uint32_t * pChannels,uint32_t * pRate,AudioSystem::audio_in_acoustics acoustic_flags)863 status_t AudioHardware::AudioStreamInMSM72xx::set(
864 AudioHardware* hw, uint32_t devices, int *pFormat, uint32_t *pChannels, uint32_t *pRate,
865 AudioSystem::audio_in_acoustics acoustic_flags)
866 {
867 if (pFormat == 0 || *pFormat != AUDIO_HW_IN_FORMAT) {
868 *pFormat = AUDIO_HW_IN_FORMAT;
869 return BAD_VALUE;
870 }
871 if (pRate == 0) {
872 return BAD_VALUE;
873 }
874 uint32_t rate = hw->getInputSampleRate(*pRate);
875 if (rate != *pRate) {
876 *pRate = rate;
877 return BAD_VALUE;
878 }
879
880 if (pChannels == 0 || (*pChannels != AudioSystem::CHANNEL_IN_MONO &&
881 *pChannels != AudioSystem::CHANNEL_IN_STEREO)) {
882 *pChannels = AUDIO_HW_IN_CHANNELS;
883 return BAD_VALUE;
884 }
885
886 mHardware = hw;
887
888 LOGV("AudioStreamInMSM72xx::set(%d, %d, %u)", *pFormat, *pChannels, *pRate);
889 if (mFd >= 0) {
890 LOGE("Audio record already open");
891 return -EPERM;
892 }
893
894 // open audio input device
895 status_t status = ::open("/dev/msm_pcm_in", O_RDWR);
896 if (status < 0) {
897 LOGE("Cannot open /dev/msm_pcm_in errno: %d", errno);
898 goto Error;
899 }
900 mFd = status;
901
902 // configuration
903 LOGV("get config");
904 struct msm_audio_config config;
905 status = ioctl(mFd, AUDIO_GET_CONFIG, &config);
906 if (status < 0) {
907 LOGE("Cannot read config");
908 goto Error;
909 }
910
911 LOGV("set config");
912 config.channel_count = AudioSystem::popCount(*pChannels);
913 config.sample_rate = *pRate;
914 config.buffer_size = bufferSize();
915 config.buffer_count = 2;
916 config.codec_type = CODEC_TYPE_PCM;
917 status = ioctl(mFd, AUDIO_SET_CONFIG, &config);
918 if (status < 0) {
919 LOGE("Cannot set config");
920 if (ioctl(mFd, AUDIO_GET_CONFIG, &config) == 0) {
921 if (config.channel_count == 1) {
922 *pChannels = AudioSystem::CHANNEL_IN_MONO;
923 } else {
924 *pChannels = AudioSystem::CHANNEL_IN_STEREO;
925 }
926 *pRate = config.sample_rate;
927 }
928 goto Error;
929 }
930
931 LOGV("confirm config");
932 status = ioctl(mFd, AUDIO_GET_CONFIG, &config);
933 if (status < 0) {
934 LOGE("Cannot read config");
935 goto Error;
936 }
937 LOGV("buffer_size: %u", config.buffer_size);
938 LOGV("buffer_count: %u", config.buffer_count);
939 LOGV("channel_count: %u", config.channel_count);
940 LOGV("sample_rate: %u", config.sample_rate);
941
942 mDevices = devices;
943 mFormat = AUDIO_HW_IN_FORMAT;
944 mChannels = *pChannels;
945 mSampleRate = config.sample_rate;
946 mBufferSize = config.buffer_size;
947
948 //mHardware->setMicMute_nosync(false);
949 mState = AUDIO_INPUT_OPENED;
950
951 if (!acoustic)
952 return NO_ERROR;
953
954 audpre_index = calculate_audpre_table_index(mSampleRate);
955 tx_iir_index = (audpre_index * 2) + (hw->checkOutputStandby() ? 0 : 1);
956 LOGD("audpre_index = %d, tx_iir_index = %d\n", audpre_index, tx_iir_index);
957
958 /**
959 * If audio-preprocessing failed, we should not block record.
960 */
961 int (*msm72xx_set_audpre_params)(int, int);
962 msm72xx_set_audpre_params = (int (*)(int, int))::dlsym(acoustic, "msm72xx_set_audpre_params");
963 status = msm72xx_set_audpre_params(audpre_index, tx_iir_index);
964 if (status < 0)
965 LOGE("Cannot set audpre parameters");
966
967 int (*msm72xx_enable_audpre)(int, int, int);
968 msm72xx_enable_audpre = (int (*)(int, int, int))::dlsym(acoustic, "msm72xx_enable_audpre");
969 mAcoustics = acoustic_flags;
970 status = msm72xx_enable_audpre((int)acoustic_flags, audpre_index, tx_iir_index);
971 if (status < 0)
972 LOGE("Cannot enable audpre");
973
974 return NO_ERROR;
975
976 Error:
977 if (mFd >= 0) {
978 ::close(mFd);
979 mFd = -1;
980 }
981 return status;
982 }
983
~AudioStreamInMSM72xx()984 AudioHardware::AudioStreamInMSM72xx::~AudioStreamInMSM72xx()
985 {
986 LOGV("AudioStreamInMSM72xx destructor");
987 standby();
988 }
989
read(void * buffer,ssize_t bytes)990 ssize_t AudioHardware::AudioStreamInMSM72xx::read( void* buffer, ssize_t bytes)
991 {
992 LOGV("AudioStreamInMSM72xx::read(%p, %ld)", buffer, bytes);
993 if (!mHardware) return -1;
994
995 size_t count = bytes;
996 uint8_t* p = static_cast<uint8_t*>(buffer);
997
998 if (mState < AUDIO_INPUT_OPENED) {
999 Mutex::Autolock lock(mHardware->mLock);
1000 if (set(mHardware, mDevices, &mFormat, &mChannels, &mSampleRate, mAcoustics) != NO_ERROR) {
1001 return -1;
1002 }
1003 }
1004
1005 if (mState < AUDIO_INPUT_STARTED) {
1006 if (ioctl(mFd, AUDIO_START, 0)) {
1007 LOGE("Error starting record");
1008 return -1;
1009 }
1010 mState = AUDIO_INPUT_STARTED;
1011 }
1012
1013 while (count) {
1014 ssize_t bytesRead = ::read(mFd, buffer, count);
1015 if (bytesRead >= 0) {
1016 count -= bytesRead;
1017 p += bytesRead;
1018 } else {
1019 if (errno != EAGAIN) return bytesRead;
1020 mRetryCount++;
1021 LOGW("EAGAIN - retrying");
1022 }
1023 }
1024 return bytes;
1025 }
1026
standby()1027 status_t AudioHardware::AudioStreamInMSM72xx::standby()
1028 {
1029 if (!mHardware) return -1;
1030 if (mState > AUDIO_INPUT_CLOSED) {
1031 if (mFd >= 0) {
1032 ::close(mFd);
1033 mFd = -1;
1034 }
1035 //mHardware->checkMicMute();
1036 mState = AUDIO_INPUT_CLOSED;
1037 }
1038 return NO_ERROR;
1039 }
1040
dump(int fd,const Vector<String16> & args)1041 status_t AudioHardware::AudioStreamInMSM72xx::dump(int fd, const Vector<String16>& args)
1042 {
1043 const size_t SIZE = 256;
1044 char buffer[SIZE];
1045 String8 result;
1046 result.append("AudioStreamInMSM72xx::dump\n");
1047 snprintf(buffer, SIZE, "\tsample rate: %d\n", sampleRate());
1048 result.append(buffer);
1049 snprintf(buffer, SIZE, "\tbuffer size: %d\n", bufferSize());
1050 result.append(buffer);
1051 snprintf(buffer, SIZE, "\tchannels: %d\n", channels());
1052 result.append(buffer);
1053 snprintf(buffer, SIZE, "\tformat: %d\n", format());
1054 result.append(buffer);
1055 snprintf(buffer, SIZE, "\tmHardware: %p\n", mHardware);
1056 result.append(buffer);
1057 snprintf(buffer, SIZE, "\tmFd count: %d\n", mFd);
1058 result.append(buffer);
1059 snprintf(buffer, SIZE, "\tmState: %d\n", mState);
1060 result.append(buffer);
1061 snprintf(buffer, SIZE, "\tmRetryCount: %d\n", mRetryCount);
1062 result.append(buffer);
1063 ::write(fd, result.string(), result.size());
1064 return NO_ERROR;
1065 }
1066
setParameters(const String8 & keyValuePairs)1067 status_t AudioHardware::AudioStreamInMSM72xx::setParameters(const String8& keyValuePairs)
1068 {
1069 AudioParameter param = AudioParameter(keyValuePairs);
1070 String8 key = String8(AudioParameter::keyRouting);
1071 status_t status = NO_ERROR;
1072 int device;
1073 LOGV("AudioStreamInMSM72xx::setParameters() %s", keyValuePairs.string());
1074
1075 if (param.getInt(key, device) == NO_ERROR) {
1076 LOGV("set input routing %x", device);
1077 if (device & (device - 1)) {
1078 status = BAD_VALUE;
1079 } else {
1080 mDevices = device;
1081 status = mHardware->doRouting(this);
1082 }
1083 param.remove(key);
1084 }
1085
1086 if (param.size()) {
1087 status = BAD_VALUE;
1088 }
1089 return status;
1090 }
1091
getParameters(const String8 & keys)1092 String8 AudioHardware::AudioStreamInMSM72xx::getParameters(const String8& keys)
1093 {
1094 AudioParameter param = AudioParameter(keys);
1095 String8 value;
1096 String8 key = String8(AudioParameter::keyRouting);
1097
1098 if (param.get(key, value) == NO_ERROR) {
1099 LOGV("get routing %x", mDevices);
1100 param.addInt(key, (int)mDevices);
1101 }
1102
1103 LOGV("AudioStreamInMSM72xx::getParameters() %s", param.toString().string());
1104 return param.toString();
1105 }
1106
1107 // ----------------------------------------------------------------------------
1108
createAudioHardware(void)1109 extern "C" AudioHardwareInterface* createAudioHardware(void) {
1110 return new AudioHardware();
1111 }
1112
1113 }; // namespace android
1114