AudioRecord.cpp revision 73493688f4190f790ee15d9ca54831cd64f4e195
15460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/* 25460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao** 35460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao** Copyright 2008, The Android Open Source Project 45460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao** 55460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao** Licensed under the Apache License, Version 2.0 (the "License"); 65460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao** you may not use this file except in compliance with the License. 75460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao** You may obtain a copy of the License at 85460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao** 922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao** http://www.apache.org/licenses/LICENSE-2.0 1022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao** 1122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao** Unless required by applicable law or agreed to in writing, software 1222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao** distributed under the License is distributed on an "AS IS" BASIS, 1322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao** See the License for the specific language governing permissions and 1522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao** limitations under the License. 165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao*/ 175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//#define LOG_NDEBUG 0 195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#define LOG_TAG "AudioRecord" 205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <sys/resource.h> 2222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <binder/IPCThreadState.h> 2322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <media/AudioRecord.h> 2422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <utils/Log.h> 2522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <private/media/AudioTrackShared.h> 2622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <media/IAudioFlinger.h> 2722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 2822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#define WAIT_PERIOD_MS 10 2922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 3022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaonamespace android { 3122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao// --------------------------------------------------------------------------- 3222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 3322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao// static 3422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaostatus_t AudioRecord::getMinFrameCount( 3522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao size_t* frameCount, 3622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao uint32_t sampleRate, 3722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao audio_format_t format, 3822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao audio_channel_mask_t channelMask) 3922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{ 4022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (frameCount == NULL) { 4122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return BAD_VALUE; 4222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 4322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 4422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // default to 0 in case of error 4522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao *frameCount = 0; 4622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 4722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao size_t size = 0; 4822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao status_t status = AudioSystem::getInputBufferSize(sampleRate, format, channelMask, &size); 4922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (status != NO_ERROR) { 5022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao ALOGE("AudioSystem could not query the input buffer size; status %d", status); 5122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return NO_INIT; 5222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 5322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 5422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (size == 0) { 5522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao ALOGE("Unsupported configuration: sampleRate %u, format %d, channelMask %#x", 5622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao sampleRate, format, channelMask); 5722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return BAD_VALUE; 5822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 5922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 6022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // We double the size of input buffer for ping pong use of record buffer. 6122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao size <<= 1; 6222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 6322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (audio_is_linear_pcm(format)) { 6422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao uint32_t channelCount = popcount(channelMask); 6522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao size /= channelCount * audio_bytes_per_sample(format); 6622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 6722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 6822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao *frameCount = size; 6922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return NO_ERROR; 7022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao} 7122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 7222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao// --------------------------------------------------------------------------- 7322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 7422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei LiaoAudioRecord::AudioRecord() 7522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao : mStatus(NO_INIT), mSessionId(0), 7622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao mPreviousPriority(ANDROID_PRIORITY_NORMAL), mPreviousSchedulingGroup(SP_DEFAULT) 7722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{ 7822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao} 7922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 8022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei LiaoAudioRecord::AudioRecord( 8122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao audio_source_t inputSource, 8222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao uint32_t sampleRate, 8322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao audio_format_t format, 8422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao audio_channel_mask_t channelMask, 8522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao int frameCount, 8622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao callback_t cbf, 8722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao void* user, 8822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao int notificationFrames, 8922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao int sessionId, 9022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao transfer_type transferType, 9122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao audio_input_flags_t flags) 9222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao : mStatus(NO_INIT), mSessionId(0), 9322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao mPreviousPriority(ANDROID_PRIORITY_NORMAL), 9422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao mPreviousSchedulingGroup(SP_DEFAULT), 9522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao mProxy(NULL) 9622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{ 9722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao mStatus = set(inputSource, sampleRate, format, channelMask, frameCount, cbf, user, 9822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao notificationFrames, false /*threadCanCallJava*/, sessionId, transferType); 9922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao} 10022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 10122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei LiaoAudioRecord::~AudioRecord() 10222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{ 10322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (mStatus == NO_ERROR) { 10422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // Make sure that callback function exits in the case where 10522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // it is looping on buffer empty condition in obtainBuffer(). 10622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao // Otherwise the callback thread will never exit. 10722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao stop(); 10822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (mAudioRecordThread != 0) { 10922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao mAudioRecordThread->requestExit(); // see comment in AudioRecord.h 11022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao mAudioRecordThread->requestExitAndWait(); 11122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao mAudioRecordThread.clear(); 11222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 11322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (mAudioRecord != 0) { 11422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao mAudioRecord->asBinder()->unlinkToDeath(mDeathNotifier, this); 11522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao mAudioRecord.clear(); 11622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 11722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao IPCThreadState::self()->flushCommands(); 11822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao AudioSystem::releaseAudioSessionId(mSessionId); 11922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 12022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao} 12122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 12222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaostatus_t AudioRecord::set( 12322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao audio_source_t inputSource, 12422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao uint32_t sampleRate, 12522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao audio_format_t format, 12622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao audio_channel_mask_t channelMask, 12722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao int frameCountInt, 12822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao callback_t cbf, 12922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao void* user, 13022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao int notificationFrames, 13122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao bool threadCanCallJava, 13222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao int sessionId, 13322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao transfer_type transferType, 13422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao audio_input_flags_t flags) 13522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{ 13622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao switch (transferType) { 13722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao case TRANSFER_DEFAULT: 13822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (cbf == NULL || threadCanCallJava) { 13922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao transferType = TRANSFER_SYNC; 14022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } else { 14122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao transferType = TRANSFER_CALLBACK; 14222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 14322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao break; 14422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao case TRANSFER_CALLBACK: 14522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (cbf == NULL) { 14622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao ALOGE("Transfer type TRANSFER_CALLBACK but cbf == NULL"); 14722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao return BAD_VALUE; 14822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 149 break; 150 case TRANSFER_OBTAIN: 151 case TRANSFER_SYNC: 152 break; 153 default: 154 ALOGE("Invalid transfer type %d", transferType); 155 return BAD_VALUE; 156 } 157 mTransfer = transferType; 158 159 // FIXME "int" here is legacy and will be replaced by size_t later 160 if (frameCountInt < 0) { 161 ALOGE("Invalid frame count %d", frameCountInt); 162 return BAD_VALUE; 163 } 164 size_t frameCount = frameCountInt; 165 166 ALOGV("set(): sampleRate %u, channelMask %#x, frameCount %u", sampleRate, channelMask, 167 frameCount); 168 169 AutoMutex lock(mLock); 170 171 if (mAudioRecord != 0) { 172 ALOGE("Track already in use"); 173 return INVALID_OPERATION; 174 } 175 176 if (inputSource == AUDIO_SOURCE_DEFAULT) { 177 inputSource = AUDIO_SOURCE_MIC; 178 } 179 180 if (sampleRate == 0) { 181 sampleRate = DEFAULT_SAMPLE_RATE; 182 } 183 mSampleRate = sampleRate; 184 185 // these below should probably come from the audioFlinger too... 186 if (format == AUDIO_FORMAT_DEFAULT) { 187 format = AUDIO_FORMAT_PCM_16_BIT; 188 } 189 190 // validate parameters 191 if (!audio_is_valid_format(format)) { 192 ALOGE("Invalid format %d", format); 193 return BAD_VALUE; 194 } 195 // Temporary restriction: AudioFlinger currently supports 16-bit PCM only 196 if (format != AUDIO_FORMAT_PCM_16_BIT) { 197 ALOGE("Format %d is not supported", format); 198 return BAD_VALUE; 199 } 200 mFormat = format; 201 202 if (!audio_is_input_channel(channelMask)) { 203 ALOGE("Invalid channel mask %#x", channelMask); 204 return BAD_VALUE; 205 } 206 mChannelMask = channelMask; 207 uint32_t channelCount = popcount(channelMask); 208 mChannelCount = channelCount; 209 210 if (audio_is_linear_pcm(format)) { 211 mFrameSize = channelCount * audio_bytes_per_sample(format); 212 } else { 213 mFrameSize = sizeof(uint8_t); 214 } 215 216 if (sessionId == 0 ) { 217 mSessionId = AudioSystem::newAudioSessionId(); 218 } else { 219 mSessionId = sessionId; 220 } 221 ALOGV("set(): mSessionId %d", mSessionId); 222 223 mFlags = flags; 224 225 audio_io_handle_t input = AudioSystem::getInput(inputSource, 226 sampleRate, 227 format, 228 channelMask, 229 mSessionId); 230 if (input == 0) { 231 ALOGE("Could not get audio input for record source %d", inputSource); 232 return BAD_VALUE; 233 } 234 235 // validate framecount 236 size_t minFrameCount = 0; 237 status_t status = getMinFrameCount(&minFrameCount, sampleRate, format, channelMask); 238 if (status != NO_ERROR) { 239 ALOGE("getMinFrameCount() failed; status %d", status); 240 return status; 241 } 242 ALOGV("AudioRecord::set() minFrameCount = %d", minFrameCount); 243 244 if (frameCount == 0) { 245 frameCount = minFrameCount; 246 } else if (frameCount < minFrameCount) { 247 ALOGE("frameCount %u < minFrameCount %u", frameCount, minFrameCount); 248 return BAD_VALUE; 249 } 250 251 if (notificationFrames == 0) { 252 notificationFrames = frameCount/2; 253 } 254 255 // create the IAudioRecord 256 status = openRecord_l(sampleRate, format, frameCount, mFlags, input, 0 /*epoch*/); 257 if (status != NO_ERROR) { 258 return status; 259 } 260 261 if (cbf != NULL) { 262 mAudioRecordThread = new AudioRecordThread(*this, threadCanCallJava); 263 mAudioRecordThread->run("AudioRecord", ANDROID_PRIORITY_AUDIO); 264 } 265 266 mStatus = NO_ERROR; 267 268 // Update buffer size in case it has been limited by AudioFlinger during track creation 269 mFrameCount = mCblk->frameCount_; 270 271 mActive = false; 272 mCbf = cbf; 273 mNotificationFrames = notificationFrames; 274 mRefreshRemaining = true; 275 mUserData = user; 276 // TODO: add audio hardware input latency here 277 mLatency = (1000*mFrameCount) / sampleRate; 278 mMarkerPosition = 0; 279 mMarkerReached = false; 280 mNewPosition = 0; 281 mUpdatePeriod = 0; 282 mInputSource = inputSource; 283 mInput = input; 284 AudioSystem::acquireAudioSessionId(mSessionId); 285 mSequence = 1; 286 mObservedSequence = mSequence; 287 mInOverrun = false; 288 289 return NO_ERROR; 290} 291 292// ------------------------------------------------------------------------- 293 294status_t AudioRecord::start(AudioSystem::sync_event_t event, int triggerSession) 295{ 296 ALOGV("start, sync event %d trigger session %d", event, triggerSession); 297 298 AutoMutex lock(mLock); 299 if (mActive) { 300 return NO_ERROR; 301 } 302 303 // reset current position as seen by client to 0 304 mProxy->setEpoch(mProxy->getEpoch() - mProxy->getPosition()); 305 306 mNewPosition = mProxy->getPosition() + mUpdatePeriod; 307 int32_t flags = android_atomic_acquire_load(&mCblk->mFlags); 308 309 status_t status = NO_ERROR; 310 if (!(flags & CBLK_INVALID)) { 311 ALOGV("mAudioRecord->start()"); 312 status = mAudioRecord->start(event, triggerSession); 313 if (status == DEAD_OBJECT) { 314 flags |= CBLK_INVALID; 315 } 316 } 317 if (flags & CBLK_INVALID) { 318 status = restoreRecord_l("start"); 319 } 320 321 if (status != NO_ERROR) { 322 ALOGE("start() status %d", status); 323 } else { 324 mActive = true; 325 sp<AudioRecordThread> t = mAudioRecordThread; 326 if (t != 0) { 327 t->resume(); 328 } else { 329 mPreviousPriority = getpriority(PRIO_PROCESS, 0); 330 get_sched_policy(0, &mPreviousSchedulingGroup); 331 androidSetThreadPriority(0, ANDROID_PRIORITY_AUDIO); 332 } 333 } 334 335 return status; 336} 337 338void AudioRecord::stop() 339{ 340 AutoMutex lock(mLock); 341 if (!mActive) { 342 return; 343 } 344 345 mActive = false; 346 mProxy->interrupt(); 347 mAudioRecord->stop(); 348 // the record head position will reset to 0, so if a marker is set, we need 349 // to activate it again 350 mMarkerReached = false; 351 sp<AudioRecordThread> t = mAudioRecordThread; 352 if (t != 0) { 353 t->pause(); 354 } else { 355 setpriority(PRIO_PROCESS, 0, mPreviousPriority); 356 set_sched_policy(0, mPreviousSchedulingGroup); 357 } 358} 359 360bool AudioRecord::stopped() const 361{ 362 AutoMutex lock(mLock); 363 return !mActive; 364} 365 366status_t AudioRecord::setMarkerPosition(uint32_t marker) 367{ 368 if (mCbf == NULL) { 369 return INVALID_OPERATION; 370 } 371 372 AutoMutex lock(mLock); 373 mMarkerPosition = marker; 374 mMarkerReached = false; 375 376 return NO_ERROR; 377} 378 379status_t AudioRecord::getMarkerPosition(uint32_t *marker) const 380{ 381 if (marker == NULL) { 382 return BAD_VALUE; 383 } 384 385 AutoMutex lock(mLock); 386 *marker = mMarkerPosition; 387 388 return NO_ERROR; 389} 390 391status_t AudioRecord::setPositionUpdatePeriod(uint32_t updatePeriod) 392{ 393 if (mCbf == NULL) { 394 return INVALID_OPERATION; 395 } 396 397 AutoMutex lock(mLock); 398 mNewPosition = mProxy->getPosition() + updatePeriod; 399 mUpdatePeriod = updatePeriod; 400 401 return NO_ERROR; 402} 403 404status_t AudioRecord::getPositionUpdatePeriod(uint32_t *updatePeriod) const 405{ 406 if (updatePeriod == NULL) { 407 return BAD_VALUE; 408 } 409 410 AutoMutex lock(mLock); 411 *updatePeriod = mUpdatePeriod; 412 413 return NO_ERROR; 414} 415 416status_t AudioRecord::getPosition(uint32_t *position) const 417{ 418 if (position == NULL) { 419 return BAD_VALUE; 420 } 421 422 AutoMutex lock(mLock); 423 *position = mProxy->getPosition(); 424 425 return NO_ERROR; 426} 427 428unsigned int AudioRecord::getInputFramesLost() const 429{ 430 // no need to check mActive, because if inactive this will return 0, which is what we want 431 return AudioSystem::getInputFramesLost(getInput()); 432} 433 434// ------------------------------------------------------------------------- 435 436// must be called with mLock held 437status_t AudioRecord::openRecord_l( 438 uint32_t sampleRate, 439 audio_format_t format, 440 size_t frameCount, 441 audio_input_flags_t flags, 442 audio_io_handle_t input, 443 size_t epoch) 444{ 445 status_t status; 446 const sp<IAudioFlinger>& audioFlinger = AudioSystem::get_audio_flinger(); 447 if (audioFlinger == 0) { 448 ALOGE("Could not get audioflinger"); 449 return NO_INIT; 450 } 451 452 pid_t tid = -1; 453 // FIXME see similar logic at AudioTrack for tid 454 455 IAudioFlinger::track_flags_t trackFlags = IAudioFlinger::TRACK_DEFAULT; 456 int originalSessionId = mSessionId; 457 sp<IAudioRecord> record = audioFlinger->openRecord(input, 458 sampleRate, format, 459 mChannelMask, 460 frameCount, 461 &trackFlags, 462 tid, 463 &mSessionId, 464 &status); 465 ALOGE_IF(originalSessionId != 0 && mSessionId != originalSessionId, 466 "session ID changed from %d to %d", originalSessionId, mSessionId); 467 468 if (record == 0) { 469 ALOGE("AudioFlinger could not create record track, status: %d", status); 470 return status; 471 } 472 sp<IMemory> iMem = record->getCblk(); 473 if (iMem == 0) { 474 ALOGE("Could not get control block"); 475 return NO_INIT; 476 } 477 if (mAudioRecord != 0) { 478 mAudioRecord->asBinder()->unlinkToDeath(mDeathNotifier, this); 479 mDeathNotifier.clear(); 480 } 481 mAudioRecord = record; 482 mCblkMemory = iMem; 483 audio_track_cblk_t* cblk = static_cast<audio_track_cblk_t*>(iMem->pointer()); 484 mCblk = cblk; 485 486 // starting address of buffers in shared memory 487 void *buffers = (char*)cblk + sizeof(audio_track_cblk_t); 488 489 // update proxy 490 mProxy = new AudioRecordClientProxy(cblk, buffers, frameCount, mFrameSize); 491 mProxy->setEpoch(epoch); 492 mProxy->setMinimum(mNotificationFrames); 493 494 mDeathNotifier = new DeathNotifier(this); 495 mAudioRecord->asBinder()->linkToDeath(mDeathNotifier, this); 496 497 return NO_ERROR; 498} 499 500status_t AudioRecord::obtainBuffer(Buffer* audioBuffer, int32_t waitCount) 501{ 502 if (audioBuffer == NULL) { 503 return BAD_VALUE; 504 } 505 if (mTransfer != TRANSFER_OBTAIN) { 506 audioBuffer->frameCount = 0; 507 audioBuffer->size = 0; 508 audioBuffer->raw = NULL; 509 return INVALID_OPERATION; 510 } 511 512 const struct timespec *requested; 513 if (waitCount == -1) { 514 requested = &ClientProxy::kForever; 515 } else if (waitCount == 0) { 516 requested = &ClientProxy::kNonBlocking; 517 } else if (waitCount > 0) { 518 long long ms = WAIT_PERIOD_MS * (long long) waitCount; 519 struct timespec timeout; 520 timeout.tv_sec = ms / 1000; 521 timeout.tv_nsec = (int) (ms % 1000) * 1000000; 522 requested = &timeout; 523 } else { 524 ALOGE("%s invalid waitCount %d", __func__, waitCount); 525 requested = NULL; 526 } 527 return obtainBuffer(audioBuffer, requested); 528} 529 530status_t AudioRecord::obtainBuffer(Buffer* audioBuffer, const struct timespec *requested, 531 struct timespec *elapsed, size_t *nonContig) 532{ 533 // previous and new IAudioRecord sequence numbers are used to detect track re-creation 534 uint32_t oldSequence = 0; 535 uint32_t newSequence; 536 537 Proxy::Buffer buffer; 538 status_t status = NO_ERROR; 539 540 static const int32_t kMaxTries = 5; 541 int32_t tryCounter = kMaxTries; 542 543 do { 544 // obtainBuffer() is called with mutex unlocked, so keep extra references to these fields to 545 // keep them from going away if another thread re-creates the track during obtainBuffer() 546 sp<AudioRecordClientProxy> proxy; 547 sp<IMemory> iMem; 548 { 549 // start of lock scope 550 AutoMutex lock(mLock); 551 552 newSequence = mSequence; 553 // did previous obtainBuffer() fail due to media server death or voluntary invalidation? 554 if (status == DEAD_OBJECT) { 555 // re-create track, unless someone else has already done so 556 if (newSequence == oldSequence) { 557 status = restoreRecord_l("obtainBuffer"); 558 if (status != NO_ERROR) { 559 break; 560 } 561 } 562 } 563 oldSequence = newSequence; 564 565 // Keep the extra references 566 proxy = mProxy; 567 iMem = mCblkMemory; 568 569 // Non-blocking if track is stopped 570 if (!mActive) { 571 requested = &ClientProxy::kNonBlocking; 572 } 573 574 } // end of lock scope 575 576 buffer.mFrameCount = audioBuffer->frameCount; 577 // FIXME starts the requested timeout and elapsed over from scratch 578 status = proxy->obtainBuffer(&buffer, requested, elapsed); 579 580 } while ((status == DEAD_OBJECT) && (tryCounter-- > 0)); 581 582 audioBuffer->frameCount = buffer.mFrameCount; 583 audioBuffer->size = buffer.mFrameCount * mFrameSize; 584 audioBuffer->raw = buffer.mRaw; 585 if (nonContig != NULL) { 586 *nonContig = buffer.mNonContig; 587 } 588 return status; 589} 590 591void AudioRecord::releaseBuffer(Buffer* audioBuffer) 592{ 593 // all TRANSFER_* are valid 594 595 size_t stepCount = audioBuffer->size / mFrameSize; 596 if (stepCount == 0) { 597 return; 598 } 599 600 Proxy::Buffer buffer; 601 buffer.mFrameCount = stepCount; 602 buffer.mRaw = audioBuffer->raw; 603 604 AutoMutex lock(mLock); 605 mInOverrun = false; 606 mProxy->releaseBuffer(&buffer); 607 608 // the server does not automatically disable recorder on overrun, so no need to restart 609} 610 611audio_io_handle_t AudioRecord::getInput() const 612{ 613 AutoMutex lock(mLock); 614 return mInput; 615} 616 617// must be called with mLock held 618audio_io_handle_t AudioRecord::getInput_l() 619{ 620 mInput = AudioSystem::getInput(mInputSource, 621 mSampleRate, 622 mFormat, 623 mChannelMask, 624 mSessionId); 625 return mInput; 626} 627 628// ------------------------------------------------------------------------- 629 630ssize_t AudioRecord::read(void* buffer, size_t userSize) 631{ 632 if (mTransfer != TRANSFER_SYNC) { 633 return INVALID_OPERATION; 634 } 635 636 if (ssize_t(userSize) < 0 || (buffer == NULL && userSize != 0)) { 637 // sanity-check. user is most-likely passing an error code, and it would 638 // make the return value ambiguous (actualSize vs error). 639 ALOGE("AudioRecord::read(buffer=%p, size=%u (%d)", buffer, userSize, userSize); 640 return BAD_VALUE; 641 } 642 643 ssize_t read = 0; 644 Buffer audioBuffer; 645 646 while (userSize >= mFrameSize) { 647 audioBuffer.frameCount = userSize / mFrameSize; 648 649 status_t err = obtainBuffer(&audioBuffer, &ClientProxy::kForever); 650 if (err < 0) { 651 if (read > 0) { 652 break; 653 } 654 return ssize_t(err); 655 } 656 657 size_t bytesRead = audioBuffer.size; 658 memcpy(buffer, audioBuffer.i8, bytesRead); 659 buffer = ((char *) buffer) + bytesRead; 660 userSize -= bytesRead; 661 read += bytesRead; 662 663 releaseBuffer(&audioBuffer); 664 } 665 666 return read; 667} 668 669// ------------------------------------------------------------------------- 670 671nsecs_t AudioRecord::processAudioBuffer(const sp<AudioRecordThread>& thread) 672{ 673 mLock.lock(); 674 if (mAwaitBoost) { 675 mAwaitBoost = false; 676 mLock.unlock(); 677 static const int32_t kMaxTries = 5; 678 int32_t tryCounter = kMaxTries; 679 uint32_t pollUs = 10000; 680 do { 681 int policy = sched_getscheduler(0); 682 if (policy == SCHED_FIFO || policy == SCHED_RR) { 683 break; 684 } 685 usleep(pollUs); 686 pollUs <<= 1; 687 } while (tryCounter-- > 0); 688 if (tryCounter < 0) { 689 ALOGE("did not receive expected priority boost on time"); 690 } 691 // Run again immediately 692 return 0; 693 } 694 695 // Can only reference mCblk while locked 696 int32_t flags = android_atomic_and(~CBLK_OVERRUN, &mCblk->mFlags); 697 698 // Check for track invalidation 699 if (flags & CBLK_INVALID) { 700 (void) restoreRecord_l("processAudioBuffer"); 701 mLock.unlock(); 702 // Run again immediately, but with a new IAudioRecord 703 return 0; 704 } 705 706 bool active = mActive; 707 708 // Manage overrun callback, must be done under lock to avoid race with releaseBuffer() 709 bool newOverrun = false; 710 if (flags & CBLK_OVERRUN) { 711 if (!mInOverrun) { 712 mInOverrun = true; 713 newOverrun = true; 714 } 715 } 716 717 // Get current position of server 718 size_t position = mProxy->getPosition(); 719 720 // Manage marker callback 721 bool markerReached = false; 722 size_t markerPosition = mMarkerPosition; 723 // FIXME fails for wraparound, need 64 bits 724 if (!mMarkerReached && (markerPosition > 0) && (position >= markerPosition)) { 725 mMarkerReached = markerReached = true; 726 } 727 728 // Determine the number of new position callback(s) that will be needed, while locked 729 size_t newPosCount = 0; 730 size_t newPosition = mNewPosition; 731 uint32_t updatePeriod = mUpdatePeriod; 732 // FIXME fails for wraparound, need 64 bits 733 if (updatePeriod > 0 && position >= newPosition) { 734 newPosCount = ((position - newPosition) / updatePeriod) + 1; 735 mNewPosition += updatePeriod * newPosCount; 736 } 737 738 // Cache other fields that will be needed soon 739 size_t notificationFrames = mNotificationFrames; 740 if (mRefreshRemaining) { 741 mRefreshRemaining = false; 742 mRemainingFrames = notificationFrames; 743 mRetryOnPartialBuffer = false; 744 } 745 size_t misalignment = mProxy->getMisalignment(); 746 int32_t sequence = mSequence; 747 748 // These fields don't need to be cached, because they are assigned only by set(): 749 // mTransfer, mCbf, mUserData, mSampleRate 750 751 mLock.unlock(); 752 753 // perform callbacks while unlocked 754 if (newOverrun) { 755 mCbf(EVENT_OVERRUN, mUserData, NULL); 756 } 757 if (markerReached) { 758 mCbf(EVENT_MARKER, mUserData, &markerPosition); 759 } 760 while (newPosCount > 0) { 761 size_t temp = newPosition; 762 mCbf(EVENT_NEW_POS, mUserData, &temp); 763 newPosition += updatePeriod; 764 newPosCount--; 765 } 766 if (mObservedSequence != sequence) { 767 mObservedSequence = sequence; 768 mCbf(EVENT_NEW_IAUDIORECORD, mUserData, NULL); 769 } 770 771 // if inactive, then don't run me again until re-started 772 if (!active) { 773 return NS_INACTIVE; 774 } 775 776 // Compute the estimated time until the next timed event (position, markers) 777 uint32_t minFrames = ~0; 778 if (!markerReached && position < markerPosition) { 779 minFrames = markerPosition - position; 780 } 781 if (updatePeriod > 0 && updatePeriod < minFrames) { 782 minFrames = updatePeriod; 783 } 784 785 // If > 0, poll periodically to recover from a stuck server. A good value is 2. 786 static const uint32_t kPoll = 0; 787 if (kPoll > 0 && mTransfer == TRANSFER_CALLBACK && kPoll * notificationFrames < minFrames) { 788 minFrames = kPoll * notificationFrames; 789 } 790 791 // Convert frame units to time units 792 nsecs_t ns = NS_WHENEVER; 793 if (minFrames != (uint32_t) ~0) { 794 // This "fudge factor" avoids soaking CPU, and compensates for late progress by server 795 static const nsecs_t kFudgeNs = 10000000LL; // 10 ms 796 ns = ((minFrames * 1000000000LL) / mSampleRate) + kFudgeNs; 797 } 798 799 // If not supplying data by EVENT_MORE_DATA, then we're done 800 if (mTransfer != TRANSFER_CALLBACK) { 801 return ns; 802 } 803 804 struct timespec timeout; 805 const struct timespec *requested = &ClientProxy::kForever; 806 if (ns != NS_WHENEVER) { 807 timeout.tv_sec = ns / 1000000000LL; 808 timeout.tv_nsec = ns % 1000000000LL; 809 ALOGV("timeout %ld.%03d", timeout.tv_sec, (int) timeout.tv_nsec / 1000000); 810 requested = &timeout; 811 } 812 813 while (mRemainingFrames > 0) { 814 815 Buffer audioBuffer; 816 audioBuffer.frameCount = mRemainingFrames; 817 size_t nonContig; 818 status_t err = obtainBuffer(&audioBuffer, requested, NULL, &nonContig); 819 LOG_ALWAYS_FATAL_IF((err != NO_ERROR) != (audioBuffer.frameCount == 0), 820 "obtainBuffer() err=%d frameCount=%u", err, audioBuffer.frameCount); 821 requested = &ClientProxy::kNonBlocking; 822 size_t avail = audioBuffer.frameCount + nonContig; 823 ALOGV("obtainBuffer(%u) returned %u = %u + %u", 824 mRemainingFrames, avail, audioBuffer.frameCount, nonContig); 825 if (err != NO_ERROR) { 826 if (err == TIMED_OUT || err == WOULD_BLOCK || err == -EINTR) { 827 break; 828 } 829 ALOGE("Error %d obtaining an audio buffer, giving up.", err); 830 return NS_NEVER; 831 } 832 833 if (mRetryOnPartialBuffer) { 834 mRetryOnPartialBuffer = false; 835 if (avail < mRemainingFrames) { 836 int64_t myns = ((mRemainingFrames - avail) * 837 1100000000LL) / mSampleRate; 838 if (ns < 0 || myns < ns) { 839 ns = myns; 840 } 841 return ns; 842 } 843 } 844 845 size_t reqSize = audioBuffer.size; 846 mCbf(EVENT_MORE_DATA, mUserData, &audioBuffer); 847 size_t readSize = audioBuffer.size; 848 849 // Sanity check on returned size 850 if (ssize_t(readSize) < 0 || readSize > reqSize) { 851 ALOGE("EVENT_MORE_DATA requested %u bytes but callback returned %d bytes", 852 reqSize, (int) readSize); 853 return NS_NEVER; 854 } 855 856 if (readSize == 0) { 857 // The callback is done consuming buffers 858 // Keep this thread going to handle timed events and 859 // still try to provide more data in intervals of WAIT_PERIOD_MS 860 // but don't just loop and block the CPU, so wait 861 return WAIT_PERIOD_MS * 1000000LL; 862 } 863 864 size_t releasedFrames = readSize / mFrameSize; 865 audioBuffer.frameCount = releasedFrames; 866 mRemainingFrames -= releasedFrames; 867 if (misalignment >= releasedFrames) { 868 misalignment -= releasedFrames; 869 } else { 870 misalignment = 0; 871 } 872 873 releaseBuffer(&audioBuffer); 874 875 // FIXME here is where we would repeat EVENT_MORE_DATA again on same advanced buffer 876 // if callback doesn't like to accept the full chunk 877 if (readSize < reqSize) { 878 continue; 879 } 880 881 // There could be enough non-contiguous frames available to satisfy the remaining request 882 if (mRemainingFrames <= nonContig) { 883 continue; 884 } 885 886#if 0 887 // This heuristic tries to collapse a series of EVENT_MORE_DATA that would total to a 888 // sum <= notificationFrames. It replaces that series by at most two EVENT_MORE_DATA 889 // that total to a sum == notificationFrames. 890 if (0 < misalignment && misalignment <= mRemainingFrames) { 891 mRemainingFrames = misalignment; 892 return (mRemainingFrames * 1100000000LL) / mSampleRate; 893 } 894#endif 895 896 } 897 mRemainingFrames = notificationFrames; 898 mRetryOnPartialBuffer = true; 899 900 // A lot has transpired since ns was calculated, so run again immediately and re-calculate 901 return 0; 902} 903 904status_t AudioRecord::restoreRecord_l(const char *from) 905{ 906 ALOGW("dead IAudioRecord, creating a new one from %s()", from); 907 ++mSequence; 908 status_t result; 909 910 // if the new IAudioRecord is created, openRecord_l() will modify the 911 // following member variables: mAudioRecord, mCblkMemory and mCblk. 912 // It will also delete the strong references on previous IAudioRecord and IMemory 913 size_t position = mProxy->getPosition(); 914 mNewPosition = position + mUpdatePeriod; 915 result = openRecord_l(mSampleRate, mFormat, mFrameCount, mFlags, getInput_l(), position); 916 if (result == NO_ERROR) { 917 if (mActive) { 918 // callback thread or sync event hasn't changed 919 // FIXME this fails if we have a new AudioFlinger instance 920 result = mAudioRecord->start(AudioSystem::SYNC_EVENT_SAME, 0); 921 } 922 } 923 if (result != NO_ERROR) { 924 ALOGW("restoreRecord_l() failed status %d", result); 925 mActive = false; 926 } 927 928 return result; 929} 930 931// ========================================================================= 932 933void AudioRecord::DeathNotifier::binderDied(const wp<IBinder>& who) 934{ 935 sp<AudioRecord> audioRecord = mAudioRecord.promote(); 936 if (audioRecord != 0) { 937 AutoMutex lock(audioRecord->mLock); 938 audioRecord->mProxy->binderDied(); 939 } 940} 941 942// ========================================================================= 943 944AudioRecord::AudioRecordThread::AudioRecordThread(AudioRecord& receiver, bool bCanCallJava) 945 : Thread(bCanCallJava), mReceiver(receiver), mPaused(true), mResumeLatch(false) 946{ 947} 948 949AudioRecord::AudioRecordThread::~AudioRecordThread() 950{ 951} 952 953bool AudioRecord::AudioRecordThread::threadLoop() 954{ 955 { 956 AutoMutex _l(mMyLock); 957 if (mPaused) { 958 mMyCond.wait(mMyLock); 959 // caller will check for exitPending() 960 return true; 961 } 962 } 963 nsecs_t ns = mReceiver.processAudioBuffer(this); 964 switch (ns) { 965 case 0: 966 return true; 967 case NS_WHENEVER: 968 sleep(1); 969 return true; 970 case NS_INACTIVE: 971 pauseConditional(); 972 return true; 973 case NS_NEVER: 974 return false; 975 default: 976 LOG_ALWAYS_FATAL_IF(ns < 0, "processAudioBuffer() returned %lld", ns); 977 struct timespec req; 978 req.tv_sec = ns / 1000000000LL; 979 req.tv_nsec = ns % 1000000000LL; 980 nanosleep(&req, NULL /*rem*/); 981 return true; 982 } 983} 984 985void AudioRecord::AudioRecordThread::requestExit() 986{ 987 // must be in this order to avoid a race condition 988 Thread::requestExit(); 989 resume(); 990} 991 992void AudioRecord::AudioRecordThread::pause() 993{ 994 AutoMutex _l(mMyLock); 995 mPaused = true; 996 mResumeLatch = false; 997} 998 999void AudioRecord::AudioRecordThread::pauseConditional() 1000{ 1001 AutoMutex _l(mMyLock); 1002 if (mResumeLatch) { 1003 mResumeLatch = false; 1004 } else { 1005 mPaused = true; 1006 } 1007} 1008 1009void AudioRecord::AudioRecordThread::resume() 1010{ 1011 AutoMutex _l(mMyLock); 1012 if (mPaused) { 1013 mPaused = false; 1014 mResumeLatch = false; 1015 mMyCond.signal(); 1016 } else { 1017 mResumeLatch = true; 1018 } 1019} 1020 1021// ------------------------------------------------------------------------- 1022 1023}; // namespace android 1024