• Home
  • History
  • Annotate
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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, built %s", __DATE__);
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