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