• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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