AudioHardware.cpp revision 3b9744cccd99fd9f32ae3b99fbc8d6898b118a43
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
39namespace android {
40static int audpre_index, tx_iir_index;
41static void * acoustic;
42const uint32_t AudioHardware::inputSamplingRates[] = {
43        8000, 11025, 12000, 16000, 22050, 24000, 32000, 44100, 48000
44};
45// ----------------------------------------------------------------------------
46
47AudioHardware::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
137AudioHardware::~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
152status_t AudioHardware::initCheck()
153{
154    return mInit ? NO_ERROR : NO_INIT;
155}
156
157AudioStreamOut* 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
186void 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
197AudioStreamIn* 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
225void 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
239status_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
250bool AudioHardware::checkOutputStandby()
251{
252    if (mOutput)
253        if (!mOutput->checkStandby())
254            return false;
255
256    return true;
257}
258
259status_t AudioHardware::setMicMute(bool state)
260{
261    Mutex::Autolock lock(mLock);
262    return setMicMute_nosync(state);
263}
264
265// always call with mutex held
266status_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
275status_t AudioHardware::getMicMute(bool* state)
276{
277    *state = mMicMute;
278    return NO_ERROR;
279}
280
281status_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
324String8 AudioHardware::getParameters(const String8& keys)
325{
326    AudioParameter param = AudioParameter(keys);
327    return param.toString();
328}
329
330
331static 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}
346size_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
360static 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
399status_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
418status_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
435static 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
477status_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
491status_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
591status_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
601status_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
619status_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
632uint32_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
648AudioHardware::AudioStreamOutMSM72xx::AudioStreamOutMSM72xx() :
649    mHardware(0), mFd(-1), mStartCount(0), mRetryCount(0), mStandby(true), mDevices(0)
650{
651}
652
653status_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
686AudioHardware::AudioStreamOutMSM72xx::~AudioStreamOutMSM72xx()
687{
688    if (mFd >= 0) close(mFd);
689}
690
691ssize_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
760Error:
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
771status_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
782status_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
810bool AudioHardware::AudioStreamOutMSM72xx::checkStandby()
811{
812    return mStandby;
813}
814
815
816status_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
837String8 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
852status_t AudioHardware::AudioStreamOutMSM72xx::getRenderPosition(uint32_t *dspFrames)
853{
854    //TODO: enable when supported by driver
855    return INVALID_OPERATION;
856}
857
858// ----------------------------------------------------------------------------
859
860AudioHardware::AudioStreamInMSM72xx::AudioStreamInMSM72xx() :
861    mHardware(0), mFd(-1), mState(AUDIO_INPUT_CLOSED), mRetryCount(0),
862    mFormat(AUDIO_HW_IN_FORMAT), mChannels(AUDIO_HW_IN_CHANNELS),
863    mSampleRate(AUDIO_HW_IN_SAMPLERATE), mBufferSize(AUDIO_HW_IN_BUFFERSIZE),
864    mAcoustics((AudioSystem::audio_in_acoustics)0), mDevices(0)
865{
866}
867
868status_t AudioHardware::AudioStreamInMSM72xx::set(
869        AudioHardware* hw, uint32_t devices, int *pFormat, uint32_t *pChannels, uint32_t *pRate,
870        AudioSystem::audio_in_acoustics acoustic_flags)
871{
872    if (pFormat == 0 || *pFormat != AUDIO_HW_IN_FORMAT) {
873        *pFormat = AUDIO_HW_IN_FORMAT;
874        return BAD_VALUE;
875    }
876    if (pRate == 0) {
877        return BAD_VALUE;
878    }
879    uint32_t rate = hw->getInputSampleRate(*pRate);
880    if (rate != *pRate) {
881        *pRate = rate;
882        return BAD_VALUE;
883    }
884
885    if (pChannels == 0 || (*pChannels != AudioSystem::CHANNEL_IN_MONO &&
886        *pChannels != AudioSystem::CHANNEL_IN_STEREO)) {
887        *pChannels = AUDIO_HW_IN_CHANNELS;
888        return BAD_VALUE;
889    }
890
891    mHardware = hw;
892
893    LOGV("AudioStreamInMSM72xx::set(%d, %d, %u)", *pFormat, *pChannels, *pRate);
894    if (mFd >= 0) {
895        LOGE("Audio record already open");
896        return -EPERM;
897    }
898
899    // open audio input device
900    status_t status = ::open("/dev/msm_pcm_in", O_RDWR);
901    if (status < 0) {
902        LOGE("Cannot open /dev/msm_pcm_in errno: %d", errno);
903        goto Error;
904    }
905    mFd = status;
906
907    // configuration
908    LOGV("get config");
909    struct msm_audio_config config;
910    status = ioctl(mFd, AUDIO_GET_CONFIG, &config);
911    if (status < 0) {
912        LOGE("Cannot read config");
913        goto Error;
914    }
915
916    LOGV("set config");
917    config.channel_count = AudioSystem::popCount(*pChannels);
918    config.sample_rate = *pRate;
919    config.buffer_size = bufferSize();
920    config.buffer_count = 2;
921    config.codec_type = CODEC_TYPE_PCM;
922    status = ioctl(mFd, AUDIO_SET_CONFIG, &config);
923    if (status < 0) {
924        LOGE("Cannot set config");
925        if (ioctl(mFd, AUDIO_GET_CONFIG, &config) == 0) {
926            if (config.channel_count == 1) {
927                *pChannels = AudioSystem::CHANNEL_IN_MONO;
928            } else {
929                *pChannels = AudioSystem::CHANNEL_IN_STEREO;
930            }
931            *pRate = config.sample_rate;
932        }
933        goto Error;
934    }
935
936    LOGV("confirm config");
937    status = ioctl(mFd, AUDIO_GET_CONFIG, &config);
938    if (status < 0) {
939        LOGE("Cannot read config");
940        goto Error;
941    }
942    LOGV("buffer_size: %u", config.buffer_size);
943    LOGV("buffer_count: %u", config.buffer_count);
944    LOGV("channel_count: %u", config.channel_count);
945    LOGV("sample_rate: %u", config.sample_rate);
946
947    mDevices = devices;
948    mFormat = AUDIO_HW_IN_FORMAT;
949    mChannels = *pChannels;
950    mSampleRate = config.sample_rate;
951    mBufferSize = config.buffer_size;
952
953    //mHardware->setMicMute_nosync(false);
954    mState = AUDIO_INPUT_OPENED;
955
956    if (!acoustic)
957        return NO_ERROR;
958
959    audpre_index = calculate_audpre_table_index(mSampleRate);
960    tx_iir_index = (audpre_index * 2) + (hw->checkOutputStandby() ? 0 : 1);
961    LOGD("audpre_index = %d, tx_iir_index = %d\n", audpre_index, tx_iir_index);
962
963    /**
964     * If audio-preprocessing failed, we should not block record.
965     */
966    int (*msm72xx_set_audpre_params)(int, int);
967    msm72xx_set_audpre_params = (int (*)(int, int))::dlsym(acoustic, "msm72xx_set_audpre_params");
968    status = msm72xx_set_audpre_params(audpre_index, tx_iir_index);
969    if (status < 0)
970        LOGE("Cannot set audpre parameters");
971
972    int (*msm72xx_enable_audpre)(int, int, int);
973    msm72xx_enable_audpre = (int (*)(int, int, int))::dlsym(acoustic, "msm72xx_enable_audpre");
974    mAcoustics = acoustic_flags;
975    status = msm72xx_enable_audpre((int)acoustic_flags, audpre_index, tx_iir_index);
976    if (status < 0)
977        LOGE("Cannot enable audpre");
978
979    return NO_ERROR;
980
981Error:
982    if (mFd >= 0) {
983        ::close(mFd);
984        mFd = -1;
985    }
986    return status;
987}
988
989AudioHardware::AudioStreamInMSM72xx::~AudioStreamInMSM72xx()
990{
991    LOGV("AudioStreamInMSM72xx destructor");
992    standby();
993}
994
995ssize_t AudioHardware::AudioStreamInMSM72xx::read( void* buffer, ssize_t bytes)
996{
997    LOGV("AudioStreamInMSM72xx::read(%p, %ld)", buffer, bytes);
998    if (!mHardware) return -1;
999
1000    size_t count = bytes;
1001    uint8_t* p = static_cast<uint8_t*>(buffer);
1002
1003    if (mState < AUDIO_INPUT_OPENED) {
1004        Mutex::Autolock lock(mHardware->mLock);
1005        if (set(mHardware, mDevices, &mFormat, &mChannels, &mSampleRate, mAcoustics) != NO_ERROR) {
1006            return -1;
1007        }
1008    }
1009
1010    if (mState < AUDIO_INPUT_STARTED) {
1011        if (ioctl(mFd, AUDIO_START, 0)) {
1012            LOGE("Error starting record");
1013            return -1;
1014        }
1015        mState = AUDIO_INPUT_STARTED;
1016    }
1017
1018    while (count) {
1019        ssize_t bytesRead = ::read(mFd, buffer, count);
1020        if (bytesRead >= 0) {
1021            count -= bytesRead;
1022            p += bytesRead;
1023        } else {
1024            if (errno != EAGAIN) return bytesRead;
1025            mRetryCount++;
1026            LOGW("EAGAIN - retrying");
1027        }
1028    }
1029    return bytes;
1030}
1031
1032status_t AudioHardware::AudioStreamInMSM72xx::standby()
1033{
1034    if (!mHardware) return -1;
1035    if (mState > AUDIO_INPUT_CLOSED) {
1036        if (mFd >= 0) {
1037            ::close(mFd);
1038            mFd = -1;
1039        }
1040        //mHardware->checkMicMute();
1041        mState = AUDIO_INPUT_CLOSED;
1042    }
1043    return NO_ERROR;
1044}
1045
1046status_t AudioHardware::AudioStreamInMSM72xx::dump(int fd, const Vector<String16>& args)
1047{
1048    const size_t SIZE = 256;
1049    char buffer[SIZE];
1050    String8 result;
1051    result.append("AudioStreamInMSM72xx::dump\n");
1052    snprintf(buffer, SIZE, "\tsample rate: %d\n", sampleRate());
1053    result.append(buffer);
1054    snprintf(buffer, SIZE, "\tbuffer size: %d\n", bufferSize());
1055    result.append(buffer);
1056    snprintf(buffer, SIZE, "\tchannels: %d\n", channels());
1057    result.append(buffer);
1058    snprintf(buffer, SIZE, "\tformat: %d\n", format());
1059    result.append(buffer);
1060    snprintf(buffer, SIZE, "\tmHardware: %p\n", mHardware);
1061    result.append(buffer);
1062    snprintf(buffer, SIZE, "\tmFd count: %d\n", mFd);
1063    result.append(buffer);
1064    snprintf(buffer, SIZE, "\tmState: %d\n", mState);
1065    result.append(buffer);
1066    snprintf(buffer, SIZE, "\tmRetryCount: %d\n", mRetryCount);
1067    result.append(buffer);
1068    ::write(fd, result.string(), result.size());
1069    return NO_ERROR;
1070}
1071
1072status_t AudioHardware::AudioStreamInMSM72xx::setParameters(const String8& keyValuePairs)
1073{
1074    AudioParameter param = AudioParameter(keyValuePairs);
1075    String8 key = String8(AudioParameter::keyRouting);
1076    status_t status = NO_ERROR;
1077    int device;
1078    LOGV("AudioStreamInMSM72xx::setParameters() %s", keyValuePairs.string());
1079
1080    if (param.getInt(key, device) == NO_ERROR) {
1081        LOGV("set input routing %x", device);
1082        if (device & (device - 1)) {
1083            status = BAD_VALUE;
1084        } else {
1085            mDevices = device;
1086            status = mHardware->doRouting(this);
1087        }
1088        param.remove(key);
1089    }
1090
1091    if (param.size()) {
1092        status = BAD_VALUE;
1093    }
1094    return status;
1095}
1096
1097String8 AudioHardware::AudioStreamInMSM72xx::getParameters(const String8& keys)
1098{
1099    AudioParameter param = AudioParameter(keys);
1100    String8 value;
1101    String8 key = String8(AudioParameter::keyRouting);
1102
1103    if (param.get(key, value) == NO_ERROR) {
1104        LOGV("get routing %x", mDevices);
1105        param.addInt(key, (int)mDevices);
1106    }
1107
1108    LOGV("AudioStreamInMSM72xx::getParameters() %s", param.toString().string());
1109    return param.toString();
1110}
1111
1112// ----------------------------------------------------------------------------
1113
1114extern "C" AudioHardwareInterface* createAudioHardware(void) {
1115    return new AudioHardware();
1116}
1117
1118}; // namespace android
1119