1/*
2**
3** Copyright 2012, The Android Open Source Project
4**
5** Licensed under the Apache License, Version 2.0 (the "License");
6** you may not use this file except in compliance with the License.
7** You may obtain a copy of the License at
8**
9**     http://www.apache.org/licenses/LICENSE-2.0
10**
11** Unless required by applicable law or agreed to in writing, software
12** distributed under the License is distributed on an "AS IS" BASIS,
13** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14** See the License for the specific language governing permissions and
15** limitations under the License.
16*/
17
18#define LOG_TAG "AudioHAL:AudioStreamIn"
19#include <utils/Log.h>
20
21#include "AudioStreamIn.h"
22#include "AudioHardwareInput.h"
23
24#include <assert.h>
25#include <stdio.h>
26#include <string.h>
27#include <unistd.h>
28#include <sys/types.h>
29#include <sys/stat.h>
30#include <fcntl.h>
31
32#include <utils/String8.h>
33#include <media/AudioParameter.h>
34
35// for turning Remote mic on/off
36#ifdef REMOTE_CONTROL_INTERFACE
37#include <IRemoteControlService.h>
38#endif
39
40namespace android {
41
42const audio_format_t AudioStreamIn::kAudioFormat = AUDIO_FORMAT_PCM_16_BIT;
43const uint32_t AudioStreamIn::kChannelMask = AUDIO_CHANNEL_IN_MONO;
44
45// number of periods in the ALSA buffer
46const int AudioStreamIn::kPeriodCount = 32;
47
48AudioStreamIn::AudioStreamIn(AudioHardwareInput& owner)
49    : mOwnerHAL(owner)
50    , mCurrentDeviceInfo(NULL)
51    , mRequestedSampleRate(0)
52    , mStandby(true)
53    , mDisabled(false)
54    , mPcm(NULL)
55    , mResampler(NULL)
56    , mBuffer(NULL)
57    , mBufferSize(0)
58    , mInputSource(AUDIO_SOURCE_DEFAULT)
59    , mReadStatus(0)
60    , mFramesIn(0)
61    , mLastReadFinishedNs(-1)
62    , mLastBytesRead(0)
63    , mMinAllowedReadTimeNs(0)
64{
65    struct resampler_buffer_provider& provider =
66            mResamplerProviderWrapper.provider;
67    provider.get_next_buffer = getNextBufferThunk;
68    provider.release_buffer = releaseBufferThunk;
69    mResamplerProviderWrapper.thiz = this;
70}
71
72AudioStreamIn::~AudioStreamIn()
73{
74    Mutex::Autolock _l(mLock);
75    standby_l();
76}
77
78// Perform stream initialization that may fail.
79// Must only be called once at construction time.
80status_t AudioStreamIn::set(audio_format_t *pFormat, uint32_t *pChannelMask,
81                            uint32_t *pRate)
82{
83    Mutex::Autolock _l(mLock);
84
85    assert(mRequestedSampleRate == 0);
86
87    // Respond with a request for mono if a different format is given.
88    if (*pChannelMask != kChannelMask) {
89        *pChannelMask = kChannelMask;
90        return BAD_VALUE;
91    }
92
93    if (*pFormat != kAudioFormat) {
94        *pFormat = kAudioFormat;
95        return BAD_VALUE;
96    }
97
98    mRequestedSampleRate = *pRate;
99
100    return NO_ERROR;
101}
102
103uint32_t AudioStreamIn::getSampleRate()
104{
105    Mutex::Autolock _l(mLock);
106    return mRequestedSampleRate;
107}
108
109status_t AudioStreamIn::setSampleRate(uint32_t rate)
110{
111    (void) rate;
112    // this is a no-op in other audio HALs
113    return NO_ERROR;
114}
115
116size_t AudioStreamIn::getBufferSize()
117{
118    Mutex::Autolock _l(mLock);
119
120    size_t size = AudioHardwareInput::calculateInputBufferSize(
121        mRequestedSampleRate, kAudioFormat, getChannelCount());
122    return size;
123}
124
125uint32_t AudioStreamIn::getChannelMask()
126{
127    return kChannelMask;
128}
129
130audio_format_t AudioStreamIn::getFormat()
131{
132    return kAudioFormat;
133}
134
135status_t AudioStreamIn::setFormat(audio_format_t format)
136{
137    (void) format;
138    // other audio HALs fail any call to this API (even if the format matches
139    // the current format)
140    return INVALID_OPERATION;
141}
142
143status_t AudioStreamIn::standby()
144{
145    Mutex::Autolock _l(mLock);
146    return standby_l();
147}
148
149status_t AudioStreamIn::standby_l()
150{
151    if (mStandby) {
152        return NO_ERROR;
153    }
154    if (mPcm) {
155        ALOGD("AudioStreamIn::standby_l, call pcm_close()");
156        pcm_close(mPcm);
157        mPcm = NULL;
158    }
159
160    // Turn OFF Remote MIC if we were recording from Remote.
161    if (mCurrentDeviceInfo != NULL) {
162        if (mCurrentDeviceInfo->forVoiceRecognition) {
163            setRemoteControlMicEnabled(false);
164        }
165    }
166
167    if (mResampler) {
168        release_resampler(mResampler);
169        mResampler = NULL;
170    }
171    if (mBuffer) {
172        delete [] mBuffer;
173        mBuffer = NULL;
174    }
175
176    mCurrentDeviceInfo = NULL;
177    mStandby = true;
178    mDisabled = false;
179
180    return NO_ERROR;
181}
182
183#define DUMP(a...) \
184    snprintf(buffer, SIZE, a); \
185    buffer[SIZE - 1] = 0; \
186    result.append(buffer);
187
188status_t AudioStreamIn::dump(int fd)
189{
190    const size_t SIZE = 256;
191    char buffer[SIZE];
192    String8 result;
193    DUMP("\n AudioStreamIn::dump\n");
194
195    {
196        DUMP("\toutput sample rate: %d\n", mRequestedSampleRate);
197        if (mPcm) {
198            DUMP("\tinput sample rate: %d\n", mPcmConfig.rate);
199            DUMP("\tinput channels: %d\n", mPcmConfig.channels);
200        }
201    }
202
203    ::write(fd, result.string(), result.size());
204
205    return NO_ERROR;
206}
207
208status_t AudioStreamIn::setParameters(struct audio_stream* stream,
209                                      const char* kvpairs)
210{
211    (void) stream;
212    AudioParameter param = AudioParameter(String8(kvpairs));
213    status_t status = NO_ERROR;
214    String8 keySource = String8(AudioParameter::keyInputSource);
215    int intVal;
216
217    if (param.getInt(keySource, intVal) == NO_ERROR) {
218        ALOGI("AudioStreamIn::setParameters, mInputSource set to %d", intVal);
219        mInputSource = intVal;
220    }
221
222    return status;
223}
224
225char* AudioStreamIn::getParameters(const char* keys)
226{
227    (void) keys;
228    return strdup("");
229}
230
231status_t AudioStreamIn::setGain(float gain)
232{
233    (void) gain;
234    // In other HALs, this is a no-op and returns success.
235    return NO_ERROR;
236}
237
238uint32_t AudioStreamIn::getInputFramesLost()
239{
240    return 0;
241}
242
243status_t AudioStreamIn::addAudioEffect(effect_handle_t effect)
244{
245    (void) effect;
246    // In other HALs, this is a no-op and returns success.
247    return 0;
248}
249
250status_t AudioStreamIn::removeAudioEffect(effect_handle_t effect)
251{
252    (void) effect;
253    // In other HALs, this is a no-op and returns success.
254    return 0;
255}
256
257ssize_t AudioStreamIn::read(void* buffer, size_t bytes)
258{
259    Mutex::Autolock _l(mLock);
260
261    status_t status = NO_ERROR;
262
263    if (mStandby) {
264        status = startInputStream_l();
265        // Only try to start once to prevent pointless spew.
266        // If mic is not available then read will return silence.
267        // This is needed to prevent apps from hanging.
268        mStandby = false;
269        if (status != NO_ERROR) {
270            mDisabled = true;
271        }
272    }
273
274    if ((status == NO_ERROR) && !mDisabled) {
275        int ret = readFrames_l(buffer, bytes / getFrameSize());
276        status = (ret < 0) ? INVALID_OPERATION : NO_ERROR;
277    }
278
279    if ((status != NO_ERROR) || mDisabled) {
280        memset(buffer, 0, bytes);
281
282        // TODO: This code needs to project a timeline based on the number
283        // of audio frames synthesized from the last time we returned data
284        // from an actual audio device (or establish a fake timeline to obey
285        // if we have never returned any data from an actual device and need
286        // to synth on the first call to read)
287        usleep(bytes * 1000000 / getFrameSize() / mRequestedSampleRate);
288        mLastReadFinishedNs = -1;
289    } else {
290        bool mute;
291        mOwnerHAL.getMicMute(&mute);
292        if (mute) {
293            memset(buffer, 0, bytes);
294        }
295
296        nsecs_t now = systemTime();
297
298        if (mLastReadFinishedNs != -1) {
299            const nsecs_t kMinsleeptimeNs = 1000000; // don't sleep less than 1ms
300            const nsecs_t deltaNs = now - mLastReadFinishedNs;
301
302            if (bytes != mLastBytesRead) {
303                mMinAllowedReadTimeNs =
304                        (((nsecs_t)bytes * 1000000000) / getFrameSize()) / mRequestedSampleRate / 2;
305                mLastBytesRead = bytes;
306            }
307
308            // Make sure total read time is at least the duration corresponding to half the amount
309            // of data requested.
310            // Note: deltaNs is always > 0 here
311            if (mMinAllowedReadTimeNs > deltaNs + kMinsleeptimeNs) {
312                usleep((mMinAllowedReadTimeNs - deltaNs) / 1000);
313                // Throttle must be attributed to the previous read time to allow
314                // back-to-back throttling.
315                now = systemTime();
316            }
317        }
318        mLastReadFinishedNs = now;
319    }
320
321    return bytes;
322}
323
324void AudioStreamIn::setRemoteControlMicEnabled(bool flag)
325{
326#ifdef REMOTE_CONTROL_INTERFACE
327    sp<IRemoteControlService> service = IRemoteControlService::getInstance();
328    if (service == NULL) {
329        ALOGE("%s: No RemoteControl service detected, ignoring\n", __func__);
330        return;
331    }
332    service->setMicEnabled(flag);
333#else
334    (void)flag;
335#endif
336}
337
338status_t AudioStreamIn::startInputStream_l()
339{
340
341    ALOGI("AudioStreamIn::startInputStream_l, entry");
342
343    // Get the most appropriate device for the given input source, eg VOICE_RECOGNITION
344    const AudioHotplugThread::DeviceInfo *deviceInfo = mOwnerHAL.getBestDevice(mInputSource);
345    if (deviceInfo == NULL) {
346        return INVALID_OPERATION;
347    }
348
349    memset(&mPcmConfig, 0, sizeof(mPcmConfig));
350
351    unsigned int requestedChannelCount = getChannelCount();
352
353    // Clip to min/max available.
354    if (requestedChannelCount < deviceInfo->minChannelCount ) {
355        mPcmConfig.channels = deviceInfo->minChannelCount;
356    } else if (requestedChannelCount > deviceInfo->maxChannelCount ) {
357        mPcmConfig.channels = deviceInfo->maxChannelCount;
358    } else {
359        mPcmConfig.channels = requestedChannelCount;
360    }
361
362    ALOGD("AudioStreamIn::startInputStream_l, mRequestedSampleRate = %d",
363        mRequestedSampleRate);
364
365    // Clip to min/max available from driver.
366    uint32_t chosenSampleRate = mRequestedSampleRate;
367    if (chosenSampleRate < deviceInfo->minSampleRate) {
368        chosenSampleRate = deviceInfo->minSampleRate;
369    } else if (chosenSampleRate > deviceInfo->maxSampleRate) {
370        chosenSampleRate = deviceInfo->maxSampleRate;
371    }
372
373    // Turn on RemoteControl MIC if we are recording from it.
374    if (deviceInfo->forVoiceRecognition) {
375        setRemoteControlMicEnabled(true);
376    }
377
378    mPcmConfig.rate = chosenSampleRate;
379
380    mPcmConfig.period_size =
381            AudioHardwareInput::kPeriodMsec * mPcmConfig.rate / 1000;
382    mPcmConfig.period_count = kPeriodCount;
383    mPcmConfig.format = PCM_FORMAT_S16_LE;
384
385    ALOGD("AudioStreamIn::startInputStream_l, call pcm_open()");
386    struct pcm* pcm = pcm_open(deviceInfo->pcmCard, deviceInfo->pcmDevice,
387                               PCM_IN, &mPcmConfig);
388
389    if (!pcm_is_ready(pcm)) {
390        ALOGE("ERROR AudioStreamIn::startInputStream_l, pcm_open failed");
391        pcm_close(pcm);
392        if (deviceInfo->forVoiceRecognition) {
393            setRemoteControlMicEnabled(false);
394        }
395        return NO_MEMORY;
396    }
397
398    mCurrentDeviceInfo = deviceInfo;
399
400    mBufferSize = pcm_frames_to_bytes(pcm, mPcmConfig.period_size);
401    if (mBuffer) {
402        delete [] mBuffer;
403    }
404    mBuffer = new int16_t[mBufferSize / sizeof(uint16_t)];
405
406    mLastReadFinishedNs = -1;
407    mLastBytesRead = 0;
408
409    if (mResampler) {
410        release_resampler(mResampler);
411        mResampler = NULL;
412    }
413    if (mPcmConfig.rate != mRequestedSampleRate) {
414        ALOGD("AudioStreamIn::startInputStream_l, call create_resampler( %d  to %d)",
415            mPcmConfig.rate, mRequestedSampleRate);
416        int ret = create_resampler(mPcmConfig.rate,
417                                   mRequestedSampleRate,
418                                   1,
419                                   RESAMPLER_QUALITY_DEFAULT,
420                                   &mResamplerProviderWrapper.provider,
421                                   &mResampler);
422        if (ret != 0) {
423            ALOGW("AudioStreamIn: unable to create resampler");
424            pcm_close(pcm);
425            return static_cast<status_t>(ret);
426        }
427    }
428
429    mPcm = pcm;
430
431    return NO_ERROR;
432}
433
434// readFrames() reads frames from kernel driver, down samples to the capture
435// rate if necessary and outputs the number of frames requested to the buffer
436// specified
437ssize_t AudioStreamIn::readFrames_l(void* buffer, ssize_t frames)
438{
439    ssize_t framesWr = 0;
440    size_t frameSize = getFrameSize();
441
442    while (framesWr < frames) {
443        size_t framesRd = frames - framesWr;
444        if (mResampler) {
445            char* outFrame = static_cast<char*>(buffer) +
446                    (framesWr * frameSize);
447            mResampler->resample_from_provider(
448                mResampler,
449                reinterpret_cast<int16_t*>(outFrame),
450                &framesRd);
451        } else {
452            struct resampler_buffer buf;
453            buf.raw = NULL;
454            buf.frame_count = framesRd;
455
456            getNextBuffer(&buf);
457            if (buf.raw != NULL) {
458                memcpy(static_cast<char*>(buffer) + (framesWr * frameSize),
459                       buf.raw,
460                       buf.frame_count * frameSize);
461                framesRd = buf.frame_count;
462            }
463            releaseBuffer(&buf);
464        }
465        // mReadStatus is updated by getNextBuffer(), which is called by the
466        // resampler
467        if (mReadStatus != 0)
468            return mReadStatus;
469
470        framesWr += framesRd;
471    }
472    return framesWr;
473}
474
475int AudioStreamIn::getNextBufferThunk(
476        struct resampler_buffer_provider* bufferProvider,
477        struct resampler_buffer* buffer)
478{
479    ResamplerBufferProviderWrapper* wrapper =
480            reinterpret_cast<ResamplerBufferProviderWrapper*>(
481                reinterpret_cast<char*>(bufferProvider) -
482                offsetof(ResamplerBufferProviderWrapper, provider));
483
484    return wrapper->thiz->getNextBuffer(buffer);
485}
486
487void AudioStreamIn::releaseBufferThunk(
488        struct resampler_buffer_provider* bufferProvider,
489        struct resampler_buffer* buffer)
490{
491    ResamplerBufferProviderWrapper* wrapper =
492            reinterpret_cast<ResamplerBufferProviderWrapper*>(
493                reinterpret_cast<char*>(bufferProvider) -
494                offsetof(ResamplerBufferProviderWrapper, provider));
495
496    wrapper->thiz->releaseBuffer(buffer);
497}
498
499// called while holding mLock
500int AudioStreamIn::getNextBuffer(struct resampler_buffer* buffer)
501{
502    if (buffer == NULL) {
503        return -EINVAL;
504    }
505
506    if (mPcm == NULL) {
507        buffer->raw = NULL;
508        buffer->frame_count = 0;
509        mReadStatus = -ENODEV;
510        return -ENODEV;
511    }
512
513    if (mFramesIn == 0) {
514        mReadStatus = pcm_read(mPcm, mBuffer, mBufferSize);
515        if (mReadStatus) {
516            ALOGE("get_next_buffer() pcm_read error %d", mReadStatus);
517            buffer->raw = NULL;
518            buffer->frame_count = 0;
519            return mReadStatus;
520        }
521
522        mFramesIn = mPcmConfig.period_size;
523        if (mPcmConfig.channels == 2) {
524            // Discard the right channel.
525            // TODO: this is what other HALs are doing to handle stereo input
526            // devices.  Need to verify if this is appropriate for ATV Remote.
527            for (unsigned int i = 1; i < mFramesIn; i++) {
528                mBuffer[i] = mBuffer[i * 2];
529            }
530        }
531    }
532
533    buffer->frame_count = (buffer->frame_count > mFramesIn) ?
534            mFramesIn : buffer->frame_count;
535    buffer->i16 = mBuffer + (mPcmConfig.period_size - mFramesIn);
536
537    return mReadStatus;
538}
539
540// called while holding mLock
541void AudioStreamIn::releaseBuffer(struct resampler_buffer* buffer)
542{
543    if (buffer == NULL) {
544        return;
545    }
546
547    mFramesIn -= buffer->frame_count;
548}
549
550}; // namespace android
551