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