AudioHardware.cpp revision 2735e3b55bdaf33cfd0dbaa1b914231243933e92
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
239bool AudioHardware::checkOutputStandby()
240{
241    if (mOutput)
242        if (!mOutput->checkStandby())
243            return false;
244
245    return true;
246}
247
248status_t AudioHardware::setMicMute(bool state)
249{
250    Mutex::Autolock lock(mLock);
251    return setMicMute_nosync(state);
252}
253
254// always call with mutex held
255status_t AudioHardware::setMicMute_nosync(bool state)
256{
257    if (mMicMute != state) {
258        mMicMute = state;
259        return doAudioRouteOrMute(SND_DEVICE_CURRENT);
260    }
261    return NO_ERROR;
262}
263
264status_t AudioHardware::getMicMute(bool* state)
265{
266    *state = mMicMute;
267    return NO_ERROR;
268}
269
270status_t AudioHardware::setParameters(const String8& keyValuePairs)
271{
272    AudioParameter param = AudioParameter(keyValuePairs);
273    String8 value;
274    String8 key;
275    const char BT_NREC_KEY[] = "bt_headset_nrec";
276    const char BT_NAME_KEY[] = "bt_headset_name";
277    const char BT_NREC_VALUE_ON[] = "on";
278
279
280    LOGV("setParameters() %s", keyValuePairs.string());
281
282    if (keyValuePairs.length() == 0) return BAD_VALUE;
283
284    key = String8(BT_NREC_KEY);
285    if (param.get(key, value) == NO_ERROR) {
286        if (value == BT_NREC_VALUE_ON) {
287            mBluetoothNrec = true;
288        } else {
289            mBluetoothNrec = false;
290            LOGI("Turning noise reduction and echo cancellation off for BT "
291                 "headset");
292        }
293    }
294    key = String8(BT_NAME_KEY);
295    if (param.get(key, value) == NO_ERROR) {
296        mBluetoothId = 0;
297        for (int i = 0; i < mNumSndEndpoints; i++) {
298            if (!strcasecmp(value.string(), mSndEndpoints[i].name)) {
299                mBluetoothId = mSndEndpoints[i].id;
300                LOGI("Using custom acoustic parameters for %s", value.string());
301                break;
302            }
303        }
304        if (mBluetoothId == 0) {
305            LOGI("Using default acoustic parameters "
306                 "(%s not in acoustic database)", value.string());
307            doRouting(NULL);
308        }
309    }
310    return NO_ERROR;
311}
312
313String8 AudioHardware::getParameters(const String8& keys)
314{
315    String8 result = String8("");
316    return result;
317}
318
319
320static unsigned calculate_audpre_table_index(unsigned index)
321{
322    switch (index) {
323        case 48000:    return SAMP_RATE_INDX_48000;
324        case 44100:    return SAMP_RATE_INDX_44100;
325        case 32000:    return SAMP_RATE_INDX_32000;
326        case 24000:    return SAMP_RATE_INDX_24000;
327        case 22050:    return SAMP_RATE_INDX_22050;
328        case 16000:    return SAMP_RATE_INDX_16000;
329        case 12000:    return SAMP_RATE_INDX_12000;
330        case 11025:    return SAMP_RATE_INDX_11025;
331        case 8000:    return SAMP_RATE_INDX_8000;
332        default:     return -1;
333    }
334}
335size_t AudioHardware::getInputBufferSize(uint32_t sampleRate, int format, int channelCount)
336{
337    if (format != AudioSystem::PCM_16_BIT) {
338        LOGW("getInputBufferSize bad format: %d", format);
339        return 0;
340    }
341    if (channelCount < 1 || channelCount > 2) {
342        LOGW("getInputBufferSize bad channel count: %d", channelCount);
343        return 0;
344    }
345
346    return 2048*channelCount;
347}
348
349static status_t set_volume_rpc(uint32_t device,
350                               uint32_t method,
351                               uint32_t volume)
352{
353    int fd;
354#if LOG_SND_RPC
355    LOGD("rpc_snd_set_volume(%d, %d, %d)\n", device, method, volume);
356#endif
357
358    if (device == -1UL) return NO_ERROR;
359
360    fd = open("/dev/msm_snd", O_RDWR);
361    if (fd < 0) {
362        LOGE("Can not open snd device");
363        return -EPERM;
364    }
365    /* rpc_snd_set_volume(
366     *     device,            # Any hardware device enum, including
367     *                        # SND_DEVICE_CURRENT
368     *     method,            # must be SND_METHOD_VOICE to do anything useful
369     *     volume,            # integer volume level, in range [0,5].
370     *                        # note that 0 is audible (not quite muted)
371     *  )
372     * rpc_snd_set_volume only works for in-call sound volume.
373     */
374     struct msm_snd_volume_config args;
375     args.device = device;
376     args.method = method;
377     args.volume = volume;
378
379     if (ioctl(fd, SND_SET_VOLUME, &args) < 0) {
380         LOGE("snd_set_volume error.");
381         close(fd);
382         return -EIO;
383     }
384     close(fd);
385     return NO_ERROR;
386}
387
388status_t AudioHardware::setVoiceVolume(float v)
389{
390    if (v < 0.0) {
391        LOGW("setVoiceVolume(%f) under 0.0, assuming 0.0\n", v);
392        v = 0.0;
393    } else if (v > 1.0) {
394        LOGW("setVoiceVolume(%f) over 1.0, assuming 1.0\n", v);
395        v = 1.0;
396    }
397
398    int vol = lrint(v * 5.0);
399    LOGD("setVoiceVolume(%f)\n", v);
400    LOGI("Setting in-call volume to %d (available range is 0 to 5)\n", vol);
401
402    Mutex::Autolock lock(mLock);
403    set_volume_rpc(SND_DEVICE_CURRENT, SND_METHOD_VOICE, vol);
404    return NO_ERROR;
405}
406
407status_t AudioHardware::setMasterVolume(float v)
408{
409    Mutex::Autolock lock(mLock);
410    int vol = ceil(v * 5.0);
411    LOGI("Set master volume to %d.\n", vol);
412    /*
413    set_volume_rpc(SND_DEVICE_HANDSET, SND_METHOD_VOICE, vol);
414    set_volume_rpc(SND_DEVICE_SPEAKER, SND_METHOD_VOICE, vol);
415    set_volume_rpc(SND_DEVICE_BT,      SND_METHOD_VOICE, vol);
416    set_volume_rpc(SND_DEVICE_HEADSET, SND_METHOD_VOICE, vol);
417    */
418    // We return an error code here to let the audioflinger do in-software
419    // volume on top of the maximum volume that we set through the SND API.
420    // return error - software mixer will handle it
421    return -1;
422}
423
424static status_t do_route_audio_rpc(uint32_t device,
425                                   bool ear_mute, bool mic_mute)
426{
427    if (device == -1UL)
428        return NO_ERROR;
429
430    int fd;
431#if LOG_SND_RPC
432    LOGD("rpc_snd_set_device(%d, %d, %d)\n", device, ear_mute, mic_mute);
433#endif
434
435    fd = open("/dev/msm_snd", O_RDWR);
436    if (fd < 0) {
437        LOGE("Can not open snd device");
438        return -EPERM;
439    }
440    // RPC call to switch audio path
441    /* rpc_snd_set_device(
442     *     device,            # Hardware device enum to use
443     *     ear_mute,          # Set mute for outgoing voice audio
444     *                        # this should only be unmuted when in-call
445     *     mic_mute,          # Set mute for incoming voice audio
446     *                        # this should only be unmuted when in-call or
447     *                        # recording.
448     *  )
449     */
450    struct msm_snd_device_config args;
451    args.device = device;
452    args.ear_mute = ear_mute ? SND_MUTE_MUTED : SND_MUTE_UNMUTED;
453    args.mic_mute = mic_mute ? SND_MUTE_MUTED : SND_MUTE_UNMUTED;
454
455    if (ioctl(fd, SND_SET_DEVICE, &args) < 0) {
456        LOGE("snd_set_device error.");
457        close(fd);
458        return -EIO;
459    }
460
461    close(fd);
462    return NO_ERROR;
463}
464
465// always call with mutex held
466status_t AudioHardware::doAudioRouteOrMute(uint32_t device)
467{
468    if (device == (uint32_t)SND_DEVICE_BT) {
469        if (mBluetoothId) {
470            device = mBluetoothId;
471        } else if (!mBluetoothNrec) {
472            device = SND_DEVICE_BT_EC_OFF;
473        }
474    }
475    LOGV("doAudioRouteOrMute() device %x, mMode %d, mMicMute %d", device, mMode, mMicMute);
476    return do_route_audio_rpc(device,
477                              mMode != AudioSystem::MODE_IN_CALL, mMicMute);
478}
479
480status_t AudioHardware::doRouting(AudioStreamInMSM72xx *input)
481{
482    /* currently this code doesn't work without the htc libacoustic */
483    if (!acoustic)
484        return 0;
485
486    Mutex::Autolock lock(mLock);
487    uint32_t outputDevices = mOutput->devices();
488    status_t ret = NO_ERROR;
489    int (*msm72xx_enable_audpp)(int);
490    msm72xx_enable_audpp = (int (*)(int))::dlsym(acoustic, "msm72xx_enable_audpp");
491    int audProcess = (ADRC_DISABLE | EQ_DISABLE | RX_IIR_DISABLE);
492    int sndDevice = -1;
493
494    if (input != NULL) {
495        uint32_t inputDevice = input->devices();
496        LOGI("do input routing device %x\n", inputDevice);
497        if (inputDevice != 0) {
498            if (inputDevice & AudioSystem::DEVICE_IN_BLUETOOTH_SCO_HEADSET) {
499                LOGI("Routing audio to Bluetooth PCM\n");
500                sndDevice = SND_DEVICE_BT;
501            } else if (inputDevice & AudioSystem::DEVICE_IN_WIRED_HEADSET) {
502                if ((outputDevices & AudioSystem::DEVICE_OUT_WIRED_HEADSET) &&
503                    (outputDevices & AudioSystem::DEVICE_OUT_SPEAKER)) {
504                    LOGI("Routing audio to Wired Headset and Speaker\n");
505                    sndDevice = SND_DEVICE_HEADSET_AND_SPEAKER;
506                    audProcess = (ADRC_ENABLE | EQ_ENABLE | RX_IIR_ENABLE);
507                } else {
508                    LOGI("Routing audio to Wired Headset\n");
509                    sndDevice = SND_DEVICE_HEADSET;
510                }
511            } else {
512                if (outputDevices & AudioSystem::DEVICE_OUT_SPEAKER) {
513                    LOGI("Routing audio to Speakerphone\n");
514                    sndDevice = SND_DEVICE_SPEAKER;
515                    audProcess = (ADRC_ENABLE | EQ_ENABLE | RX_IIR_ENABLE);
516                } else {
517                    LOGI("Routing audio to Handset\n");
518                    sndDevice = SND_DEVICE_HANDSET;
519                }
520            }
521        }
522        // if inputDevice == 0, restore output routing
523    }
524
525    if (sndDevice == -1) {
526        if (outputDevices & (outputDevices - 1)) {
527            if ((outputDevices & AudioSystem::DEVICE_OUT_SPEAKER) == 0) {
528                LOGW("Hardware does not support requested route combination (%#X),"
529                     " picking closest possible route...", outputDevices);
530            }
531        }
532
533        if (outputDevices & AudioSystem::DEVICE_OUT_TTY) {
534                LOGI("Routing audio to TTY\n");
535                sndDevice = SND_DEVICE_TTY_FULL;
536        } else if (outputDevices & AudioSystem::DEVICE_OUT_BLUETOOTH_SCO) {
537            LOGI("Routing audio to Bluetooth PCM\n");
538            sndDevice = SND_DEVICE_BT;
539        } else if ((outputDevices & AudioSystem::DEVICE_OUT_WIRED_HEADSET) &&
540                   (outputDevices & AudioSystem::DEVICE_OUT_SPEAKER)) {
541            LOGI("Routing audio to Wired Headset and Speaker\n");
542            sndDevice = SND_DEVICE_HEADSET_AND_SPEAKER;
543            audProcess = (ADRC_ENABLE | EQ_ENABLE | RX_IIR_ENABLE);
544        } else if (outputDevices & AudioSystem::DEVICE_OUT_FM_SPEAKER) {
545            LOGI("Routing audio to FM Speakerphone (%d,%x)\n", mMode, outputDevices);
546            sndDevice = SND_DEVICE_FM_SPEAKER;
547            audProcess = (ADRC_ENABLE | EQ_ENABLE | RX_IIR_DISABLE);
548        } else if (outputDevices & AudioSystem::DEVICE_OUT_FM_HEADPHONE) {
549            if (outputDevices & AudioSystem::DEVICE_OUT_SPEAKER) {
550                LOGI("Routing audio to FM Headset and Speaker (%d,%x)\n", mMode, outputDevices);
551                sndDevice = SND_DEVICE_HEADSET_AND_SPEAKER;
552                audProcess = (ADRC_ENABLE | EQ_ENABLE | RX_IIR_ENABLE);
553            } else {
554                LOGI("Routing audio to FM Headset (%d,%x)\n", mMode, outputDevices);
555                sndDevice = doAudioRouteOrMute(SND_DEVICE_FM_HEADSET);
556            }
557        } else if (outputDevices & AudioSystem::DEVICE_OUT_WIRED_HEADPHONE) {
558            if (outputDevices & AudioSystem::DEVICE_OUT_SPEAKER) {
559                LOGI("Routing audio to No microphone Wired Headset and Speaker (%d,%x)\n", mMode, outputDevices);
560                sndDevice = SND_DEVICE_HEADSET_AND_SPEAKER;
561                audProcess = (ADRC_ENABLE | EQ_ENABLE | RX_IIR_ENABLE);
562            } else {
563                LOGI("Routing audio to No microphone Wired Headset (%d,%x)\n", mMode, outputDevices);
564                sndDevice = SND_DEVICE_NO_MIC_HEADSET;
565            }
566        } else if (outputDevices & AudioSystem::DEVICE_OUT_WIRED_HEADSET) {
567            LOGI("Routing audio to Wired Headset\n");
568            sndDevice = SND_DEVICE_HEADSET;
569        } else if (outputDevices & AudioSystem::DEVICE_OUT_SPEAKER) {
570            LOGI("Routing audio to Speakerphone\n");
571            sndDevice = SND_DEVICE_SPEAKER;
572            audProcess = (ADRC_ENABLE | EQ_ENABLE | RX_IIR_ENABLE);
573        } else {
574            LOGI("Routing audio to Handset\n");
575            sndDevice = SND_DEVICE_HANDSET;
576        }
577    }
578
579    if (sndDevice != -1 && sndDevice != mCurSndDevice) {
580        ret = doAudioRouteOrMute(sndDevice);
581        if ((*msm72xx_enable_audpp) == 0 ) {
582            LOGE("Could not open msm72xx_enable_audpp()");
583        } else {
584            msm72xx_enable_audpp(audProcess);
585        }
586        mCurSndDevice = sndDevice;
587    }
588
589    return ret;
590}
591
592status_t AudioHardware::checkMicMute()
593{
594    Mutex::Autolock lock(mLock);
595    if (mMode != AudioSystem::MODE_IN_CALL) {
596        setMicMute_nosync(true);
597    }
598
599    return NO_ERROR;
600}
601
602status_t AudioHardware::dumpInternals(int fd, const Vector<String16>& args)
603{
604    const size_t SIZE = 256;
605    char buffer[SIZE];
606    String8 result;
607    result.append("AudioHardware::dumpInternals\n");
608    snprintf(buffer, SIZE, "\tmInit: %s\n", mInit? "true": "false");
609    result.append(buffer);
610    snprintf(buffer, SIZE, "\tmMicMute: %s\n", mMicMute? "true": "false");
611    result.append(buffer);
612    snprintf(buffer, SIZE, "\tmBluetoothNrec: %s\n", mBluetoothNrec? "true": "false");
613    result.append(buffer);
614    snprintf(buffer, SIZE, "\tmBluetoothId: %d\n", mBluetoothId);
615    result.append(buffer);
616    ::write(fd, result.string(), result.size());
617    return NO_ERROR;
618}
619
620status_t AudioHardware::dump(int fd, const Vector<String16>& args)
621{
622    dumpInternals(fd, args);
623    for (size_t index = 0; index < mInputs.size(); index++) {
624        mInputs[index]->dump(fd, args);
625    }
626
627    if (mOutput) {
628        mOutput->dump(fd, args);
629    }
630    return NO_ERROR;
631}
632
633uint32_t AudioHardware::getInputSampleRate(uint32_t sampleRate)
634{
635    uint32_t i;
636    uint32_t prevDelta;
637    uint32_t delta;
638
639    for (i = 0, prevDelta = 0xFFFFFFFF; i < sizeof(inputSamplingRates)/sizeof(uint32_t); i++, prevDelta = delta) {
640        delta = abs(sampleRate - inputSamplingRates[i]);
641        if (delta > prevDelta) break;
642    }
643    // i is always > 0 here
644    return inputSamplingRates[i-1];
645}
646
647// ----------------------------------------------------------------------------
648
649AudioHardware::AudioStreamOutMSM72xx::AudioStreamOutMSM72xx() :
650    mHardware(0), mFd(-1), mStartCount(0), mRetryCount(0), mStandby(true), mDevices(0)
651{
652}
653
654status_t AudioHardware::AudioStreamOutMSM72xx::set(
655        AudioHardware* hw, uint32_t devices, int *pFormat, uint32_t *pChannels, uint32_t *pRate)
656{
657    int lFormat = pFormat ? *pFormat : 0;
658    uint32_t lChannels = pChannels ? *pChannels : 0;
659    uint32_t lRate = pRate ? *pRate : 0;
660
661    mHardware = hw;
662
663    // fix up defaults
664    if (lFormat == 0) lFormat = format();
665    if (lChannels == 0) lChannels = channels();
666    if (lRate == 0) lRate = sampleRate();
667
668    // check values
669    if ((lFormat != format()) ||
670        (lChannels != channels()) ||
671        (lRate != sampleRate())) {
672        if (pFormat) *pFormat = format();
673        if (pChannels) *pChannels = channels();
674        if (pRate) *pRate = sampleRate();
675        return BAD_VALUE;
676    }
677
678    if (pFormat) *pFormat = lFormat;
679    if (pChannels) *pChannels = lChannels;
680    if (pRate) *pRate = lRate;
681
682    mDevices = devices;
683
684    return NO_ERROR;
685}
686
687AudioHardware::AudioStreamOutMSM72xx::~AudioStreamOutMSM72xx()
688{
689    if (mFd > 0) close(mFd);
690}
691
692ssize_t AudioHardware::AudioStreamOutMSM72xx::write(const void* buffer, size_t bytes)
693{
694    // LOGD("AudioStreamOutMSM72xx::write(%p, %u)", buffer, bytes);
695    status_t status = NO_INIT;
696    size_t count = bytes;
697    const uint8_t* p = static_cast<const uint8_t*>(buffer);
698
699    if (mStandby) {
700
701        // open driver
702        LOGV("open driver");
703        status = ::open("/dev/msm_pcm_out", O_RDWR);
704        if (status < 0) {
705            LOGE("Cannot open /dev/msm_pcm_out errno: %d", errno);
706            goto Error;
707        }
708        mFd = status;
709
710        // configuration
711        LOGV("get config");
712        struct msm_audio_config config;
713        status = ioctl(mFd, AUDIO_GET_CONFIG, &config);
714        if (status < 0) {
715            LOGE("Cannot read config");
716            goto Error;
717        }
718
719        LOGV("set config");
720        config.channel_count = AudioSystem::popCount(channels());
721        config.sample_rate = sampleRate();
722        config.buffer_size = bufferSize();
723        config.buffer_count = AUDIO_HW_NUM_OUT_BUF;
724        config.codec_type = CODEC_TYPE_PCM;
725        status = ioctl(mFd, AUDIO_SET_CONFIG, &config);
726        if (status < 0) {
727            LOGE("Cannot set config");
728            goto Error;
729        }
730
731        LOGV("buffer_size: %u", config.buffer_size);
732        LOGV("buffer_count: %u", config.buffer_count);
733        LOGV("channel_count: %u", config.channel_count);
734        LOGV("sample_rate: %u", config.sample_rate);
735
736        // fill 2 buffers before AUDIO_START
737        mStartCount = AUDIO_HW_NUM_OUT_BUF;
738        mStandby = false;
739    }
740
741    while (count) {
742        ssize_t written = ::write(mFd, p, count);
743        if (written >= 0) {
744            count -= written;
745            p += written;
746        } else {
747            if (errno != EAGAIN) return written;
748            mRetryCount++;
749            LOGW("EAGAIN - retry");
750        }
751    }
752
753    // start audio after we fill 2 buffers
754    if (mStartCount) {
755        if (--mStartCount == 0) {
756            ioctl(mFd, AUDIO_START, 0);
757        }
758    }
759    return bytes;
760
761Error:
762    if (mFd > 0) {
763        ::close(mFd);
764        mFd = -1;
765    }
766    // Simulate audio output timing in case of error
767    usleep(bytes * 1000000 / frameSize() / sampleRate());
768
769    return status;
770}
771
772status_t AudioHardware::AudioStreamOutMSM72xx::standby()
773{
774    status_t status = NO_ERROR;
775    if (!mStandby && mFd > 0) {
776        ::close(mFd);
777        mFd = -1;
778    }
779    mStandby = true;
780    return status;
781}
782
783status_t AudioHardware::AudioStreamOutMSM72xx::dump(int fd, const Vector<String16>& args)
784{
785    const size_t SIZE = 256;
786    char buffer[SIZE];
787    String8 result;
788    result.append("AudioStreamOutMSM72xx::dump\n");
789    snprintf(buffer, SIZE, "\tsample rate: %d\n", sampleRate());
790    result.append(buffer);
791    snprintf(buffer, SIZE, "\tbuffer size: %d\n", bufferSize());
792    result.append(buffer);
793    snprintf(buffer, SIZE, "\tchannels: %d\n", channels());
794    result.append(buffer);
795    snprintf(buffer, SIZE, "\tformat: %d\n", format());
796    result.append(buffer);
797    snprintf(buffer, SIZE, "\tmHardware: %p\n", mHardware);
798    result.append(buffer);
799    snprintf(buffer, SIZE, "\tmFd: %d\n", mFd);
800    result.append(buffer);
801    snprintf(buffer, SIZE, "\tmStartCount: %d\n", mStartCount);
802    result.append(buffer);
803    snprintf(buffer, SIZE, "\tmRetryCount: %d\n", mRetryCount);
804    result.append(buffer);
805    snprintf(buffer, SIZE, "\tmStandby: %s\n", mStandby? "true": "false");
806    result.append(buffer);
807    ::write(fd, result.string(), result.size());
808    return NO_ERROR;
809}
810
811bool AudioHardware::AudioStreamOutMSM72xx::checkStandby()
812{
813    return mStandby;
814}
815
816
817status_t AudioHardware::AudioStreamOutMSM72xx::setParameters(const String8& keyValuePairs)
818{
819    AudioParameter param = AudioParameter(keyValuePairs);
820    String8 key = String8(AudioParameter::keyRouting);
821    status_t status = NO_ERROR;
822    int device;
823    LOGV("AudioStreamOutMSM72xx::setParameters() %s", keyValuePairs.string());
824
825    if (param.getInt(key, device) == NO_ERROR) {
826        mDevices = device;
827        LOGV("set output routing %x", mDevices);
828        status = mHardware->doRouting(NULL);
829        param.remove(key);
830    }
831
832    if (param.size()) {
833        status = BAD_VALUE;
834    }
835    return status;
836}
837
838String8 AudioHardware::AudioStreamOutMSM72xx::getParameters(const String8& keys)
839{
840    AudioParameter param = AudioParameter(keys);
841    String8 value;
842    String8 key = String8(AudioParameter::keyRouting);
843
844    if (param.get(key, value) == NO_ERROR) {
845        LOGV("get routing %x", mDevices);
846        param.addInt(key, (int)mDevices);
847    }
848
849    LOGV("AudioStreamOutMSM72xx::getParameters() %s", param.toString().string());
850    return param.toString();
851}
852
853
854// ----------------------------------------------------------------------------
855
856AudioHardware::AudioStreamInMSM72xx::AudioStreamInMSM72xx() :
857    mHardware(0), mFd(-1), mState(AUDIO_INPUT_CLOSED), mRetryCount(0),
858    mFormat(AUDIO_HW_IN_FORMAT), mChannels(AUDIO_HW_IN_CHANNELS),
859    mSampleRate(AUDIO_HW_IN_SAMPLERATE), mBufferSize(AUDIO_HW_IN_BUFFERSIZE),
860    mAcoustics((AudioSystem::audio_in_acoustics)0), mDevices(0)
861{
862}
863
864status_t AudioHardware::AudioStreamInMSM72xx::set(
865        AudioHardware* hw, uint32_t devices, int *pFormat, uint32_t *pChannels, uint32_t *pRate,
866        AudioSystem::audio_in_acoustics acoustic_flags)
867{
868    if (pFormat == 0 || *pFormat != AUDIO_HW_IN_FORMAT) {
869        *pFormat = AUDIO_HW_IN_FORMAT;
870        return BAD_VALUE;
871    }
872    if (pRate == 0) {
873        return BAD_VALUE;
874    }
875    uint32_t rate = hw->getInputSampleRate(*pRate);
876    if (rate != *pRate) {
877        *pRate = rate;
878        return BAD_VALUE;
879    }
880
881    if (pChannels == 0 || (*pChannels != AudioSystem::CHANNEL_IN_MONO &&
882        *pChannels != AudioSystem::CHANNEL_IN_STEREO)) {
883        *pChannels = AUDIO_HW_IN_CHANNELS;
884        return BAD_VALUE;
885    }
886
887    mHardware = hw;
888
889    LOGV("AudioStreamInMSM72xx::set(%d, %d, %u)", *pFormat, *pChannels, *pRate);
890    if (mFd >= 0) {
891        LOGE("Audio record already open");
892        return -EPERM;
893    }
894
895    // open audio input device
896    status_t status = ::open("/dev/msm_pcm_in", O_RDWR);
897    if (status < 0) {
898        LOGE("Cannot open /dev/msm_pcm_in errno: %d", errno);
899        goto Error;
900    }
901    mFd = status;
902
903    // configuration
904    LOGV("get config");
905    struct msm_audio_config config;
906    status = ioctl(mFd, AUDIO_GET_CONFIG, &config);
907    if (status < 0) {
908        LOGE("Cannot read config");
909        goto Error;
910    }
911
912    LOGV("set config");
913    config.channel_count = AudioSystem::popCount(*pChannels);
914    config.sample_rate = *pRate;
915    config.buffer_size = bufferSize();
916    config.buffer_count = 2;
917    config.codec_type = CODEC_TYPE_PCM;
918    status = ioctl(mFd, AUDIO_SET_CONFIG, &config);
919    if (status < 0) {
920        LOGE("Cannot set config");
921        if (ioctl(mFd, AUDIO_GET_CONFIG, &config) == 0) {
922            if (config.channel_count == 1) {
923                *pChannels = AudioSystem::CHANNEL_IN_MONO;
924            } else {
925                *pChannels = AudioSystem::CHANNEL_IN_STEREO;
926            }
927            *pRate = config.sample_rate;
928        }
929        goto Error;
930    }
931
932    LOGV("confirm config");
933    status = ioctl(mFd, AUDIO_GET_CONFIG, &config);
934    if (status < 0) {
935        LOGE("Cannot read config");
936        goto Error;
937    }
938    LOGV("buffer_size: %u", config.buffer_size);
939    LOGV("buffer_count: %u", config.buffer_count);
940    LOGV("channel_count: %u", config.channel_count);
941    LOGV("sample_rate: %u", config.sample_rate);
942
943    mDevices = devices;
944    mFormat = AUDIO_HW_IN_FORMAT;
945    mChannels = *pChannels;
946    mSampleRate = config.sample_rate;
947    mBufferSize = config.buffer_size;
948
949    //mHardware->setMicMute_nosync(false);
950    mState = AUDIO_INPUT_OPENED;
951
952    if (!acoustic)
953        return NO_ERROR;
954
955    audpre_index = calculate_audpre_table_index(mSampleRate);
956    tx_iir_index = (audpre_index * 2) + (hw->checkOutputStandby() ? 0 : 1);
957    LOGD("audpre_index = %d, tx_iir_index = %d\n", audpre_index, tx_iir_index);
958
959    /**
960     * If audio-preprocessing failed, we should not block record.
961     */
962    int (*msm72xx_set_audpre_params)(int, int);
963    msm72xx_set_audpre_params = (int (*)(int, int))::dlsym(acoustic, "msm72xx_set_audpre_params");
964    status = msm72xx_set_audpre_params(audpre_index, tx_iir_index);
965    if (status < 0)
966        LOGE("Cannot set audpre parameters");
967
968    int (*msm72xx_enable_audpre)(int, int, int);
969    msm72xx_enable_audpre = (int (*)(int, int, int))::dlsym(acoustic, "msm72xx_enable_audpre");
970    mAcoustics = acoustic_flags;
971    status = msm72xx_enable_audpre((int)acoustic_flags, audpre_index, tx_iir_index);
972    if (status < 0)
973        LOGE("Cannot enable audpre");
974
975    return NO_ERROR;
976
977Error:
978    if (mFd > 0) {
979        ::close(mFd);
980        mFd = -1;
981    }
982    return status;
983}
984
985AudioHardware::AudioStreamInMSM72xx::~AudioStreamInMSM72xx()
986{
987    LOGV("AudioStreamInMSM72xx destructor");
988    standby();
989}
990
991ssize_t AudioHardware::AudioStreamInMSM72xx::read( void* buffer, ssize_t bytes)
992{
993    LOGV("AudioStreamInMSM72xx::read(%p, %ld)", buffer, bytes);
994    if (!mHardware) return -1;
995
996    size_t count = bytes;
997    uint8_t* p = static_cast<uint8_t*>(buffer);
998
999    if (mState < AUDIO_INPUT_OPENED) {
1000        Mutex::Autolock lock(mHardware->mLock);
1001        if (set(mHardware, mDevices, &mFormat, &mChannels, &mSampleRate, mAcoustics) != NO_ERROR) {
1002            return -1;
1003        }
1004    }
1005
1006    if (mState < AUDIO_INPUT_STARTED) {
1007        if (ioctl(mFd, AUDIO_START, 0)) {
1008            LOGE("Error starting record");
1009            return -1;
1010        }
1011        mState = AUDIO_INPUT_STARTED;
1012    }
1013
1014    while (count) {
1015        ssize_t bytesRead = ::read(mFd, buffer, count);
1016        if (bytesRead >= 0) {
1017            count -= bytesRead;
1018            p += bytesRead;
1019        } else {
1020            if (errno != EAGAIN) return bytesRead;
1021            mRetryCount++;
1022            LOGW("EAGAIN - retrying");
1023        }
1024    }
1025    return bytes;
1026}
1027
1028status_t AudioHardware::AudioStreamInMSM72xx::standby()
1029{
1030    if (!mHardware) return -1;
1031    if (mState > AUDIO_INPUT_CLOSED) {
1032        if (mFd > 0) {
1033            ::close(mFd);
1034            mFd = -1;
1035        }
1036        //mHardware->checkMicMute();
1037        mState = AUDIO_INPUT_CLOSED;
1038    }
1039    return NO_ERROR;
1040}
1041
1042status_t AudioHardware::AudioStreamInMSM72xx::dump(int fd, const Vector<String16>& args)
1043{
1044    const size_t SIZE = 256;
1045    char buffer[SIZE];
1046    String8 result;
1047    result.append("AudioStreamInMSM72xx::dump\n");
1048    snprintf(buffer, SIZE, "\tsample rate: %d\n", sampleRate());
1049    result.append(buffer);
1050    snprintf(buffer, SIZE, "\tbuffer size: %d\n", bufferSize());
1051    result.append(buffer);
1052    snprintf(buffer, SIZE, "\tchannels: %d\n", channels());
1053    result.append(buffer);
1054    snprintf(buffer, SIZE, "\tformat: %d\n", format());
1055    result.append(buffer);
1056    snprintf(buffer, SIZE, "\tmHardware: %p\n", mHardware);
1057    result.append(buffer);
1058    snprintf(buffer, SIZE, "\tmFd count: %d\n", mFd);
1059    result.append(buffer);
1060    snprintf(buffer, SIZE, "\tmState: %d\n", mState);
1061    result.append(buffer);
1062    snprintf(buffer, SIZE, "\tmRetryCount: %d\n", mRetryCount);
1063    result.append(buffer);
1064    ::write(fd, result.string(), result.size());
1065    return NO_ERROR;
1066}
1067
1068status_t AudioHardware::AudioStreamInMSM72xx::setParameters(const String8& keyValuePairs)
1069{
1070    AudioParameter param = AudioParameter(keyValuePairs);
1071    String8 key = String8(AudioParameter::keyRouting);
1072    status_t status = NO_ERROR;
1073    int device;
1074    LOGV("AudioStreamInMSM72xx::setParameters() %s", keyValuePairs.string());
1075
1076    if (param.getInt(key, device) == NO_ERROR) {
1077        LOGV("set input routing %x", device);
1078        if (device & (device - 1)) {
1079            status = BAD_VALUE;
1080        } else {
1081            mDevices = device;
1082            status = mHardware->doRouting(this);
1083        }
1084        param.remove(key);
1085    }
1086
1087    if (param.size()) {
1088        status = BAD_VALUE;
1089    }
1090    return status;
1091}
1092
1093String8 AudioHardware::AudioStreamInMSM72xx::getParameters(const String8& keys)
1094{
1095    AudioParameter param = AudioParameter(keys);
1096    String8 value;
1097    String8 key = String8(AudioParameter::keyRouting);
1098
1099    if (param.get(key, value) == NO_ERROR) {
1100        LOGV("get routing %x", mDevices);
1101        param.addInt(key, (int)mDevices);
1102    }
1103
1104    LOGV("AudioStreamInMSM72xx::getParameters() %s", param.toString().string());
1105    return param.toString();
1106}
1107
1108// ----------------------------------------------------------------------------
1109
1110extern "C" AudioHardwareInterface* createAudioHardware(void) {
1111    return new AudioHardware();
1112}
1113
1114}; // namespace android
1115