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