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