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), mInput(0), mSndEndpoints(NULL),
50 SND_DEVICE_CURRENT(-1),
51 SND_DEVICE_HANDSET(-1),
52 SND_DEVICE_SPEAKER(-1),
53 SND_DEVICE_BT(-1),
54 SND_DEVICE_BT_EC_OFF(-1),
55 SND_DEVICE_HEADSET(-1),
56 SND_DEVICE_HEADSET_AND_SPEAKER(-1)
57 {
58
59 int (*snd_get_num)();
60 int (*snd_get_endpoint)(int, msm_snd_endpoint *);
61 int (*set_acoustic_parameters)();
62
63 struct msm_snd_endpoint *ept;
64
65 acoustic = ::dlopen("/system/lib/libhtc_acoustic.so", RTLD_NOW);
66 if (acoustic == NULL ) {
67 LOGE("Could not open libhtc_acoustic.so");
68 return;
69 }
70
71 set_acoustic_parameters = (int (*)(void))::dlsym(acoustic, "set_acoustic_parameters");
72 if ((*set_acoustic_parameters) == 0 ) {
73 LOGE("Could not open set_acoustic_parameters()");
74 return;
75 }
76
77 int rc = set_acoustic_parameters();
78 if (rc < 0) {
79 LOGE("Could not set acoustic parameters to share memory: %d", rc);
80 // return;
81 }
82
83 snd_get_num = (int (*)(void))::dlsym(acoustic, "snd_get_num_endpoints");
84 if ((*snd_get_num) == 0 ) {
85 LOGE("Could not open snd_get_num()");
86 // return;
87 }
88
89 mNumSndEndpoints = snd_get_num();
90 LOGD("mNumSndEndpoints = %d", mNumSndEndpoints);
91 mSndEndpoints = new msm_snd_endpoint[mNumSndEndpoints];
92 mInit = true;
93 LOGV("constructed %d SND endpoints)", mNumSndEndpoints);
94 ept = mSndEndpoints;
95 snd_get_endpoint = (int (*)(int, msm_snd_endpoint *))::dlsym(acoustic, "snd_get_endpoint");
96 if ((*snd_get_endpoint) == 0 ) {
97 LOGE("Could not open snd_get_endpoint()");
98 return;
99 }
100
101 for (int cnt = 0; cnt < mNumSndEndpoints; cnt++, ept++) {
102 ept->id = cnt;
103 snd_get_endpoint(cnt, ept);
104 #define CHECK_FOR(desc) \
105 if (!strcmp(ept->name, #desc)) { \
106 SND_DEVICE_##desc = ept->id; \
107 LOGD("BT MATCH " #desc); \
108 } else
109 CHECK_FOR(CURRENT)
110 CHECK_FOR(HANDSET)
111 CHECK_FOR(SPEAKER)
112 CHECK_FOR(BT)
113 CHECK_FOR(BT_EC_OFF)
114 CHECK_FOR(HEADSET)
115 CHECK_FOR(HEADSET_AND_SPEAKER) {}
116 #undef CHECK_FOR
117 }
118 }
119
~AudioHardware()120 AudioHardware::~AudioHardware()
121 {
122 delete mInput;
123 delete mOutput;
124 delete [] mSndEndpoints;
125 ::dlclose(acoustic);
126 mInit = false;
127 }
128
initCheck()129 status_t AudioHardware::initCheck()
130 {
131 return mInit ? NO_ERROR : NO_INIT;
132 }
133
openOutputStream(int format,int channelCount,uint32_t sampleRate,status_t * status)134 AudioStreamOut* AudioHardware::openOutputStream(
135 int format, int channelCount, uint32_t sampleRate, status_t *status)
136 {
137 Mutex::Autolock lock(mLock);
138
139 // only one output stream allowed
140 if (mOutput) {
141 if (status) {
142 *status = INVALID_OPERATION;
143 }
144 return 0;
145 }
146
147 // create new output stream
148 AudioStreamOutMSM72xx* out = new AudioStreamOutMSM72xx();
149 status_t lStatus = out->set(this, format, channelCount, sampleRate);
150 if (status) {
151 *status = lStatus;
152 }
153 if (lStatus == NO_ERROR) {
154 mOutput = out;
155 } else {
156 delete out;
157 }
158 return mOutput;
159 }
160
closeOutputStream(AudioStreamOutMSM72xx * out)161 void AudioHardware::closeOutputStream(AudioStreamOutMSM72xx* out) {
162 Mutex::Autolock lock(mLock);
163 if (mOutput != out) {
164 LOGW("Attempt to close invalid output stream");
165 }
166 else {
167 mOutput = 0;
168 }
169 }
170
openInputStream(int inputSource,int format,int channelCount,uint32_t sampleRate,status_t * status,AudioSystem::audio_in_acoustics acoustic_flags)171 AudioStreamIn* AudioHardware::openInputStream(
172 int inputSource, int format, int channelCount, uint32_t sampleRate,
173 status_t *status, AudioSystem::audio_in_acoustics acoustic_flags)
174 {
175 // check for valid input source
176 if ((inputSource < AudioRecord::DEFAULT_INPUT) ||
177 (inputSource >= AudioRecord::NUM_INPUT_SOURCES)) {
178 return 0;
179 }
180
181 mLock.lock();
182 // input stream already open?
183 if (mInput) {
184 if (status) {
185 *status = INVALID_OPERATION;
186 }
187 mLock.unlock();
188 return 0;
189 }
190
191 AudioStreamInMSM72xx* in = new AudioStreamInMSM72xx();
192 status_t lStatus = in->set(this, format, channelCount, sampleRate, acoustic_flags);
193 if (status) {
194 *status = lStatus;
195 }
196 if (lStatus != NO_ERROR) {
197 mLock.unlock();
198 delete in;
199 return 0;
200 }
201
202 mInput = in;
203 mLock.unlock();
204
205 return mInput;
206 }
207
closeInputStream(AudioStreamInMSM72xx * in)208 void AudioHardware::closeInputStream(AudioStreamInMSM72xx* in) {
209 Mutex::Autolock lock(mLock);
210 if (mInput != in) {
211 LOGW("Attempt to close invalid input stream");
212 }
213 else {
214 mInput = 0;
215 }
216 }
217
checkOutputStandby()218 bool AudioHardware::checkOutputStandby()
219 {
220 if (mOutput)
221 if (!mOutput->checkStandby())
222 return false;
223
224 return true;
225 }
226
setMicMute(bool state)227 status_t AudioHardware::setMicMute(bool state)
228 {
229 Mutex::Autolock lock(mLock);
230 return setMicMute_nosync(state);
231 }
232
233 // always call with mutex held
setMicMute_nosync(bool state)234 status_t AudioHardware::setMicMute_nosync(bool state)
235 {
236 if (mMicMute != state) {
237 mMicMute = state;
238 return doAudioRouteOrMute(SND_DEVICE_CURRENT);
239 }
240 return NO_ERROR;
241 }
242
getMicMute(bool * state)243 status_t AudioHardware::getMicMute(bool* state)
244 {
245 *state = mMicMute;
246 return NO_ERROR;
247 }
248
setParameter(const char * key,const char * value)249 status_t AudioHardware::setParameter(const char *key, const char *value)
250 {
251 LOGV("%s key = %s value = %s\n", __FUNCTION__, key, value);
252
253 if (key == NULL || value == NULL) {
254 LOGE("%s called with null argument, ignoring (key = %s, value = %s",
255 __FUNCTION__, key, value);
256 return BAD_VALUE;
257 }
258
259 const char BT_NREC_KEY[] = "bt_headset_nrec";
260 const char BT_NAME_KEY[] = "bt_headset_name";
261 const char BT_NREC_VALUE_ON[] = "on";
262
263 if (!strncmp(key, BT_NREC_KEY, sizeof(BT_NREC_KEY))) {
264 if (!strncmp(value, BT_NREC_VALUE_ON, sizeof(BT_NREC_VALUE_ON))) {
265 mBluetoothNrec = true;
266 } else {
267 mBluetoothNrec = false;
268 LOGI("Turning noise reduction and echo cancellation off for BT "
269 "headset");
270 }
271 doRouting();
272 } else if (!strncmp(key, BT_NAME_KEY, sizeof(BT_NAME_KEY))) {
273 mBluetoothId = 0;
274 for (int i = 0; i < mNumSndEndpoints; i++) {
275 if (!strcasecmp(value, mSndEndpoints[i].name)) {
276 mBluetoothId = mSndEndpoints[i].id;
277 LOGI("Using custom acoustic parameters for %s", value);
278 break;
279 }
280 }
281 if (mBluetoothId == 0) {
282 LOGI("Using default acoustic parameters "
283 "(%s not in acoustic database)", value);
284 doRouting();
285 }
286 }
287
288 return NO_ERROR;
289 }
calculate_audpre_table_index(unsigned index)290 static unsigned calculate_audpre_table_index(unsigned index)
291 {
292 switch (index) {
293 case 48000: return SAMP_RATE_INDX_48000;
294 case 44100: return SAMP_RATE_INDX_44100;
295 case 32000: return SAMP_RATE_INDX_32000;
296 case 24000: return SAMP_RATE_INDX_24000;
297 case 22050: return SAMP_RATE_INDX_22050;
298 case 16000: return SAMP_RATE_INDX_16000;
299 case 12000: return SAMP_RATE_INDX_12000;
300 case 11025: return SAMP_RATE_INDX_11025;
301 case 8000: return SAMP_RATE_INDX_8000;
302 default: return -1;
303 }
304 }
getInputBufferSize(uint32_t sampleRate,int format,int channelCount)305 size_t AudioHardware::getInputBufferSize(uint32_t sampleRate, int format, int channelCount)
306 {
307 if (checkInputSampleRate(sampleRate) != NO_ERROR) {
308 LOGW("getInputBufferSize bad sampling rate: %d", sampleRate);
309 return 0;
310 }
311 if (format != AudioSystem::PCM_16_BIT) {
312 LOGW("getInputBufferSize bad format: %d", format);
313 return 0;
314 }
315 if (channelCount < 1 || channelCount > 2) {
316 LOGW("getInputBufferSize bad channel count: %d", channelCount);
317 return 0;
318 }
319
320 return 2048*channelCount;
321 }
322
set_volume_rpc(uint32_t device,uint32_t method,uint32_t volume)323 static status_t set_volume_rpc(uint32_t device,
324 uint32_t method,
325 uint32_t volume)
326 {
327 int fd;
328 #if LOG_SND_RPC
329 LOGD("rpc_snd_set_volume(%d, %d, %d)\n", device, method, volume);
330 #endif
331
332 if (device == -1UL) return NO_ERROR;
333
334 fd = open("/dev/msm_snd", O_RDWR);
335 if (fd < 0) {
336 LOGE("Can not open snd device");
337 return -EPERM;
338 }
339 /* rpc_snd_set_volume(
340 * device, # Any hardware device enum, including
341 * # SND_DEVICE_CURRENT
342 * method, # must be SND_METHOD_VOICE to do anything useful
343 * volume, # integer volume level, in range [0,5].
344 * # note that 0 is audible (not quite muted)
345 * )
346 * rpc_snd_set_volume only works for in-call sound volume.
347 */
348 struct msm_snd_volume_config args;
349 args.device = device;
350 args.method = method;
351 args.volume = volume;
352
353 if (ioctl(fd, SND_SET_VOLUME, &args) < 0) {
354 LOGE("snd_set_volume error.");
355 close(fd);
356 return -EIO;
357 }
358 close(fd);
359 return NO_ERROR;
360 }
361
setVoiceVolume(float v)362 status_t AudioHardware::setVoiceVolume(float v)
363 {
364 if (v < 0.0) {
365 LOGW("setVoiceVolume(%f) under 0.0, assuming 0.0\n", v);
366 v = 0.0;
367 } else if (v > 1.0) {
368 LOGW("setVoiceVolume(%f) over 1.0, assuming 1.0\n", v);
369 v = 1.0;
370 }
371
372 int vol = lrint(v * 5.0);
373 LOGD("setVoiceVolume(%f)\n", v);
374 LOGI("Setting in-call volume to %d (available range is 0 to 5)\n", vol);
375
376 Mutex::Autolock lock(mLock);
377 set_volume_rpc(SND_DEVICE_CURRENT, SND_METHOD_VOICE, vol);
378 return NO_ERROR;
379 }
380
setMasterVolume(float v)381 status_t AudioHardware::setMasterVolume(float v)
382 {
383 Mutex::Autolock lock(mLock);
384 int vol = ceil(v * 5.0);
385 LOGI("Set master volume to %d.\n", vol);
386 set_volume_rpc(SND_DEVICE_HANDSET, SND_METHOD_VOICE, vol);
387 set_volume_rpc(SND_DEVICE_SPEAKER, SND_METHOD_VOICE, vol);
388 set_volume_rpc(SND_DEVICE_BT, SND_METHOD_VOICE, vol);
389 set_volume_rpc(SND_DEVICE_HEADSET, SND_METHOD_VOICE, vol);
390 // We return an error code here to let the audioflinger do in-software
391 // volume on top of the maximum volume that we set through the SND API.
392 // return error - software mixer will handle it
393 return -1;
394 }
395
do_route_audio_rpc(uint32_t device,bool ear_mute,bool mic_mute)396 static status_t do_route_audio_rpc(uint32_t device,
397 bool ear_mute, bool mic_mute)
398 {
399 if (device == -1UL)
400 return NO_ERROR;
401
402 int fd;
403 #if LOG_SND_RPC
404 LOGD("rpc_snd_set_device(%d, %d, %d)\n", device, ear_mute, mic_mute);
405 #endif
406
407 fd = open("/dev/msm_snd", O_RDWR);
408 if (fd < 0) {
409 LOGE("Can not open snd device");
410 return -EPERM;
411 }
412 // RPC call to switch audio path
413 /* rpc_snd_set_device(
414 * device, # Hardware device enum to use
415 * ear_mute, # Set mute for outgoing voice audio
416 * # this should only be unmuted when in-call
417 * mic_mute, # Set mute for incoming voice audio
418 * # this should only be unmuted when in-call or
419 * # recording.
420 * )
421 */
422 struct msm_snd_device_config args;
423 args.device = device;
424 args.ear_mute = ear_mute ? SND_MUTE_MUTED : SND_MUTE_UNMUTED;
425 args.mic_mute = mic_mute ? SND_MUTE_MUTED : SND_MUTE_UNMUTED;
426
427 if (ioctl(fd, SND_SET_DEVICE, &args) < 0) {
428 LOGE("snd_set_device error.");
429 close(fd);
430 return -EIO;
431 }
432
433 close(fd);
434 return NO_ERROR;
435 }
436
437 // always call with mutex held
doAudioRouteOrMute(uint32_t device)438 status_t AudioHardware::doAudioRouteOrMute(uint32_t device)
439 {
440 if (device == (uint32_t)SND_DEVICE_BT) {
441 if (mBluetoothId) {
442 device = mBluetoothId;
443 } else if (!mBluetoothNrec) {
444 device = SND_DEVICE_BT_EC_OFF;
445 }
446 }
447 return do_route_audio_rpc(device,
448 mMode != AudioSystem::MODE_IN_CALL, mMicMute);
449 }
450
count_bits(uint32_t vector)451 static int count_bits(uint32_t vector)
452 {
453 int bits;
454 for (bits = 0; vector; bits++) {
455 vector &= vector - 1;
456 }
457 return bits;
458 }
459
doRouting()460 status_t AudioHardware::doRouting()
461 {
462 Mutex::Autolock lock(mLock);
463 uint32_t routes = mRoutes[mMode];
464 if (count_bits(routes) > 1) {
465 if (routes !=
466 (AudioSystem::ROUTE_HEADSET | AudioSystem::ROUTE_SPEAKER)) {
467 LOGW("Hardware does not support requested route combination (%#X),"
468 " picking closest possible route...", routes);
469 }
470 }
471 int (*msm72xx_enable_audpp)(int);
472 msm72xx_enable_audpp = (int (*)(int))::dlsym(acoustic, "msm72xx_enable_audpp");
473 status_t ret = NO_ERROR;
474 if (routes & AudioSystem::ROUTE_BLUETOOTH_SCO) {
475 LOGI("Routing audio to Bluetooth PCM\n");
476 ret = doAudioRouteOrMute(SND_DEVICE_BT);
477 msm72xx_enable_audpp(ADRC_DISABLE | EQ_DISABLE | RX_IIR_DISABLE);
478 } else if ((routes & AudioSystem::ROUTE_HEADSET) &&
479 (routes & AudioSystem::ROUTE_SPEAKER)) {
480 LOGI("Routing audio to Wired Headset and Speaker\n");
481 ret = doAudioRouteOrMute(SND_DEVICE_HEADSET_AND_SPEAKER);
482 msm72xx_enable_audpp(ADRC_ENABLE | EQ_ENABLE | RX_IIR_ENABLE);
483 } else if (routes & AudioSystem::ROUTE_HEADSET) {
484 LOGI("Routing audio to Wired Headset\n");
485 ret = doAudioRouteOrMute(SND_DEVICE_HEADSET);
486 msm72xx_enable_audpp(ADRC_DISABLE | EQ_DISABLE | RX_IIR_DISABLE);
487 } else if (routes & AudioSystem::ROUTE_SPEAKER) {
488 LOGI("Routing audio to Speakerphone\n");
489 ret = doAudioRouteOrMute(SND_DEVICE_SPEAKER);
490 msm72xx_enable_audpp(ADRC_ENABLE | EQ_ENABLE | RX_IIR_ENABLE);
491 } else {
492 LOGI("Routing audio to Handset\n");
493 ret = doAudioRouteOrMute(SND_DEVICE_HANDSET);
494 msm72xx_enable_audpp(ADRC_DISABLE | EQ_DISABLE | RX_IIR_DISABLE);
495 }
496
497 return ret;
498 }
499
checkMicMute()500 status_t AudioHardware::checkMicMute()
501 {
502 Mutex::Autolock lock(mLock);
503 if (mMode != AudioSystem::MODE_IN_CALL) {
504 setMicMute_nosync(true);
505 }
506
507 return NO_ERROR;
508 }
509
dumpInternals(int fd,const Vector<String16> & args)510 status_t AudioHardware::dumpInternals(int fd, const Vector<String16>& args)
511 {
512 const size_t SIZE = 256;
513 char buffer[SIZE];
514 String8 result;
515 result.append("AudioHardware::dumpInternals\n");
516 snprintf(buffer, SIZE, "\tmInit: %s\n", mInit? "true": "false");
517 result.append(buffer);
518 snprintf(buffer, SIZE, "\tmMicMute: %s\n", mMicMute? "true": "false");
519 result.append(buffer);
520 snprintf(buffer, SIZE, "\tmBluetoothNrec: %s\n", mBluetoothNrec? "true": "false");
521 result.append(buffer);
522 snprintf(buffer, SIZE, "\tmBluetoothId: %d\n", mBluetoothId);
523 result.append(buffer);
524 ::write(fd, result.string(), result.size());
525 return NO_ERROR;
526 }
527
dump(int fd,const Vector<String16> & args)528 status_t AudioHardware::dump(int fd, const Vector<String16>& args)
529 {
530 dumpInternals(fd, args);
531 if (mInput) {
532 mInput->dump(fd, args);
533 }
534 if (mOutput) {
535 mOutput->dump(fd, args);
536 }
537 return NO_ERROR;
538 }
539
checkInputSampleRate(uint32_t sampleRate)540 status_t AudioHardware::checkInputSampleRate(uint32_t sampleRate)
541 {
542 for (uint32_t i = 0; i < sizeof(inputSamplingRates)/sizeof(uint32_t); i++) {
543 if (sampleRate == inputSamplingRates[i]) {
544 return NO_ERROR;
545 }
546 }
547 return BAD_VALUE;
548 }
549
550 // ----------------------------------------------------------------------------
551
AudioStreamOutMSM72xx()552 AudioHardware::AudioStreamOutMSM72xx::AudioStreamOutMSM72xx() :
553 mHardware(0), mFd(-1), mStartCount(0), mRetryCount(0), mStandby(true)
554 {
555 }
556
set(AudioHardware * hw,int format,int channels,uint32_t rate)557 status_t AudioHardware::AudioStreamOutMSM72xx::set(
558 AudioHardware* hw, int format, int channels, uint32_t rate)
559 {
560 // fix up defaults
561 if (format == 0) format = AudioSystem::PCM_16_BIT;
562 if (channels == 0) channels = channelCount();
563 if (rate == 0) rate = sampleRate();
564
565 // check values
566 if ((format != AudioSystem::PCM_16_BIT) ||
567 (channels != channelCount()) ||
568 (rate != sampleRate()))
569 return BAD_VALUE;
570
571 mHardware = hw;
572
573 return NO_ERROR;
574 }
575
~AudioStreamOutMSM72xx()576 AudioHardware::AudioStreamOutMSM72xx::~AudioStreamOutMSM72xx()
577 {
578 if (mFd > 0) close(mFd);
579 mHardware->closeOutputStream(this);
580 }
581
write(const void * buffer,size_t bytes)582 ssize_t AudioHardware::AudioStreamOutMSM72xx::write(const void* buffer, size_t bytes)
583 {
584 // LOGD("AudioStreamOutMSM72xx::write(%p, %u)", buffer, bytes);
585 status_t status = NO_INIT;
586 size_t count = bytes;
587 const uint8_t* p = static_cast<const uint8_t*>(buffer);
588
589 if (mStandby) {
590
591 // open driver
592 LOGV("open driver");
593 status = ::open("/dev/msm_pcm_out", O_RDWR);
594 if (status < 0) {
595 LOGE("Cannot open /dev/msm_pcm_out errno: %d", errno);
596 goto Error;
597 }
598 mFd = status;
599
600 // configuration
601 LOGV("get config");
602 struct msm_audio_config config;
603 status = ioctl(mFd, AUDIO_GET_CONFIG, &config);
604 if (status < 0) {
605 LOGE("Cannot read config");
606 goto Error;
607 }
608
609 LOGV("set config");
610 config.channel_count = channelCount();
611 config.sample_rate = sampleRate();
612 config.buffer_size = bufferSize();
613 config.buffer_count = AUDIO_HW_NUM_OUT_BUF;
614 config.codec_type = CODEC_TYPE_PCM;
615 status = ioctl(mFd, AUDIO_SET_CONFIG, &config);
616 if (status < 0) {
617 LOGE("Cannot set config");
618 goto Error;
619 }
620
621 LOGV("buffer_size: %u", config.buffer_size);
622 LOGV("buffer_count: %u", config.buffer_count);
623 LOGV("channel_count: %u", config.channel_count);
624 LOGV("sample_rate: %u", config.sample_rate);
625
626 // fill 2 buffers before AUDIO_START
627 mStartCount = AUDIO_HW_NUM_OUT_BUF;
628 mStandby = false;
629 }
630
631 while (count) {
632 ssize_t written = ::write(mFd, p, count);
633 if (written >= 0) {
634 count -= written;
635 p += written;
636 } else {
637 if (errno != EAGAIN) return written;
638 mRetryCount++;
639 LOGW("EAGAIN - retry");
640 }
641 }
642
643 // start audio after we fill 2 buffers
644 if (mStartCount) {
645 if (--mStartCount == 0) {
646 ioctl(mFd, AUDIO_START, 0);
647 }
648 }
649 return bytes;
650
651 Error:
652 if (mFd > 0) {
653 ::close(mFd);
654 mFd = -1;
655 }
656 // Simulate audio output timing in case of error
657 usleep(bytes * 1000000 / frameSize() / sampleRate());
658
659 return status;
660 }
661
standby()662 status_t AudioHardware::AudioStreamOutMSM72xx::standby()
663 {
664 status_t status = NO_ERROR;
665 if (!mStandby && mFd > 0) {
666 ::close(mFd);
667 mFd = -1;
668 }
669 mStandby = true;
670 return status;
671 }
672
dump(int fd,const Vector<String16> & args)673 status_t AudioHardware::AudioStreamOutMSM72xx::dump(int fd, const Vector<String16>& args)
674 {
675 const size_t SIZE = 256;
676 char buffer[SIZE];
677 String8 result;
678 result.append("AudioStreamOutMSM72xx::dump\n");
679 snprintf(buffer, SIZE, "\tsample rate: %d\n", sampleRate());
680 result.append(buffer);
681 snprintf(buffer, SIZE, "\tbuffer size: %d\n", bufferSize());
682 result.append(buffer);
683 snprintf(buffer, SIZE, "\tchannel count: %d\n", channelCount());
684 result.append(buffer);
685 snprintf(buffer, SIZE, "\tformat: %d\n", format());
686 result.append(buffer);
687 snprintf(buffer, SIZE, "\tmHardware: %p\n", mHardware);
688 result.append(buffer);
689 snprintf(buffer, SIZE, "\tmFd: %d\n", mFd);
690 result.append(buffer);
691 snprintf(buffer, SIZE, "\tmStartCount: %d\n", mStartCount);
692 result.append(buffer);
693 snprintf(buffer, SIZE, "\tmRetryCount: %d\n", mRetryCount);
694 result.append(buffer);
695 snprintf(buffer, SIZE, "\tmStandby: %s\n", mStandby? "true": "false");
696 result.append(buffer);
697 ::write(fd, result.string(), result.size());
698 return NO_ERROR;
699 }
700
checkStandby()701 bool AudioHardware::AudioStreamOutMSM72xx::checkStandby()
702 {
703 return mStandby;
704 }
705
706 // ----------------------------------------------------------------------------
707
AudioStreamInMSM72xx()708 AudioHardware::AudioStreamInMSM72xx::AudioStreamInMSM72xx() :
709 mHardware(0), mFd(-1), mState(AUDIO_INPUT_CLOSED), mRetryCount(0),
710 mFormat(AUDIO_HW_IN_FORMAT), mChannelCount(AUDIO_HW_IN_CHANNELS),
711 mSampleRate(AUDIO_HW_IN_SAMPLERATE), mBufferSize(AUDIO_HW_IN_BUFFERSIZE),
712 mAcoustics((AudioSystem::audio_in_acoustics)0)
713 {
714 }
715
set(AudioHardware * hw,int format,int channelCount,uint32_t sampleRate,AudioSystem::audio_in_acoustics acoustic_flags)716 status_t AudioHardware::AudioStreamInMSM72xx::set(
717 AudioHardware* hw, int format, int channelCount, uint32_t sampleRate,
718 AudioSystem::audio_in_acoustics acoustic_flags)
719 {
720 LOGV("AudioStreamInMSM72xx::set(%d, %d, %u)", format, channelCount, sampleRate);
721 if (mFd >= 0) {
722 LOGE("Audio record already open");
723 return -EPERM;
724 }
725
726 // open audio input device
727 status_t status = ::open("/dev/msm_pcm_in", O_RDWR);
728 if (status < 0) {
729 LOGE("Cannot open /dev/msm_pcm_in errno: %d", errno);
730 goto Error;
731 }
732 mFd = status;
733
734 // configuration
735 LOGV("get config");
736 struct msm_audio_config config;
737 status = ioctl(mFd, AUDIO_GET_CONFIG, &config);
738 if (status < 0) {
739 LOGE("Cannot read config");
740 goto Error;
741 }
742
743 LOGV("set config");
744 config.channel_count = channelCount;
745 config.sample_rate = sampleRate;
746 config.buffer_size = bufferSize();
747 config.buffer_count = 2;
748 config.codec_type = CODEC_TYPE_PCM;
749 status = ioctl(mFd, AUDIO_SET_CONFIG, &config);
750 if (status < 0) {
751 LOGE("Cannot set config");
752 goto Error;
753 }
754
755 LOGV("confirm config");
756 status = ioctl(mFd, AUDIO_GET_CONFIG, &config);
757 if (status < 0) {
758 LOGE("Cannot read config");
759 goto Error;
760 }
761 LOGV("buffer_size: %u", config.buffer_size);
762 LOGV("buffer_count: %u", config.buffer_count);
763 LOGV("channel_count: %u", config.channel_count);
764 LOGV("sample_rate: %u", config.sample_rate);
765
766 mFormat = format;
767 mChannelCount = config.channel_count;
768 mSampleRate = config.sample_rate;
769 mBufferSize = config.buffer_size;
770
771 mHardware = hw;
772 mHardware->setMicMute_nosync(false);
773 mState = AUDIO_INPUT_OPENED;
774 audpre_index = calculate_audpre_table_index(sampleRate);
775 tx_iir_index = (audpre_index * 2) + (hw->checkOutputStandby() ? 0 : 1);
776 LOGD("audpre_index = %d, tx_iir_index = %d\n", audpre_index, tx_iir_index);
777
778 /**
779 * If audio-preprocessing failed, we should not block record.
780 */
781 int (*msm72xx_set_audpre_params)(int, int);
782 msm72xx_set_audpre_params = (int (*)(int, int))::dlsym(acoustic, "msm72xx_set_audpre_params");
783 status = msm72xx_set_audpre_params(audpre_index, tx_iir_index);
784 if (status < 0)
785 LOGE("Cannot set audpre parameters");
786
787 int (*msm72xx_enable_audpre)(int, int, int);
788 msm72xx_enable_audpre = (int (*)(int, int, int))::dlsym(acoustic, "msm72xx_enable_audpre");
789 mAcoustics = acoustic_flags;
790 status = msm72xx_enable_audpre((int)acoustic_flags, audpre_index, tx_iir_index);
791 if (status < 0)
792 LOGE("Cannot enable audpre");
793
794 return NO_ERROR;
795
796 Error:
797 if (mFd > 0) {
798 ::close(mFd);
799 mFd = -1;
800 }
801 return status;
802 }
803
~AudioStreamInMSM72xx()804 AudioHardware::AudioStreamInMSM72xx::~AudioStreamInMSM72xx()
805 {
806 LOGV("AudioStreamInMSM72xx destructor");
807 if (mHardware) {
808 standby();
809 mHardware->closeInputStream(this);
810 }
811 }
812
read(void * buffer,ssize_t bytes)813 ssize_t AudioHardware::AudioStreamInMSM72xx::read( void* buffer, ssize_t bytes)
814 {
815 LOGV("AudioStreamInMSM72xx::read(%p, %ld)", buffer, bytes);
816 if (!mHardware) return -1;
817
818 size_t count = bytes;
819 uint8_t* p = static_cast<uint8_t*>(buffer);
820
821 if (mState < AUDIO_INPUT_OPENED) {
822 Mutex::Autolock lock(mHardware->mLock);
823 if (set(mHardware, mFormat, mChannelCount, mSampleRate, mAcoustics) != NO_ERROR) {
824 return -1;
825 }
826 }
827
828 if (mState < AUDIO_INPUT_STARTED) {
829 if (ioctl(mFd, AUDIO_START, 0)) {
830 LOGE("Error starting record");
831 return -1;
832 }
833 mState = AUDIO_INPUT_STARTED;
834 }
835
836 while (count) {
837 ssize_t bytesRead = ::read(mFd, buffer, count);
838 if (bytesRead >= 0) {
839 count -= bytesRead;
840 p += bytesRead;
841 } else {
842 if (errno != EAGAIN) return bytesRead;
843 mRetryCount++;
844 LOGW("EAGAIN - retrying");
845 }
846 }
847 return bytes;
848 }
849
standby()850 status_t AudioHardware::AudioStreamInMSM72xx::standby()
851 {
852 if (!mHardware) return -1;
853 if (mState > AUDIO_INPUT_CLOSED) {
854 if (mFd > 0) {
855 ::close(mFd);
856 mFd = -1;
857 }
858 mHardware->checkMicMute();
859 mState = AUDIO_INPUT_CLOSED;
860 }
861 return NO_ERROR;
862 }
863
dump(int fd,const Vector<String16> & args)864 status_t AudioHardware::AudioStreamInMSM72xx::dump(int fd, const Vector<String16>& args)
865 {
866 const size_t SIZE = 256;
867 char buffer[SIZE];
868 String8 result;
869 result.append("AudioStreamInMSM72xx::dump\n");
870 snprintf(buffer, SIZE, "\tsample rate: %d\n", sampleRate());
871 result.append(buffer);
872 snprintf(buffer, SIZE, "\tbuffer size: %d\n", bufferSize());
873 result.append(buffer);
874 snprintf(buffer, SIZE, "\tchannel count: %d\n", channelCount());
875 result.append(buffer);
876 snprintf(buffer, SIZE, "\tformat: %d\n", format());
877 result.append(buffer);
878 snprintf(buffer, SIZE, "\tmHardware: %p\n", mHardware);
879 result.append(buffer);
880 snprintf(buffer, SIZE, "\tmFd count: %d\n", mFd);
881 result.append(buffer);
882 snprintf(buffer, SIZE, "\tmState: %d\n", mState);
883 result.append(buffer);
884 snprintf(buffer, SIZE, "\tmRetryCount: %d\n", mRetryCount);
885 result.append(buffer);
886 ::write(fd, result.string(), result.size());
887 return NO_ERROR;
888 }
889
890 // ----------------------------------------------------------------------------
891
createAudioHardware(void)892 extern "C" AudioHardwareInterface* createAudioHardware(void) {
893 return new AudioHardware();
894 }
895
896 }; // namespace android
897