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