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