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