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