AudioRecord.cpp revision 9c5fdd83f9b9f49be35107971feb33528d60b945
1aa277f94f25f0d0eefb10d4e820ee574068f6515Torne (Richard Coles)/* 2aa277f94f25f0d0eefb10d4e820ee574068f6515Torne (Richard Coles)** 3aa277f94f25f0d0eefb10d4e820ee574068f6515Torne (Richard Coles)** Copyright 2008, The Android Open Source Project 4aa277f94f25f0d0eefb10d4e820ee574068f6515Torne (Richard Coles)** 5aa277f94f25f0d0eefb10d4e820ee574068f6515Torne (Richard Coles)** Licensed under the Apache License, Version 2.0 (the "License"); 6aa277f94f25f0d0eefb10d4e820ee574068f6515Torne (Richard Coles)** you may not use this file except in compliance with the License. 7aa277f94f25f0d0eefb10d4e820ee574068f6515Torne (Richard Coles)** You may obtain a copy of the License at 8aa277f94f25f0d0eefb10d4e820ee574068f6515Torne (Richard Coles)** 9aa277f94f25f0d0eefb10d4e820ee574068f6515Torne (Richard Coles)** http://www.apache.org/licenses/LICENSE-2.0 10aa277f94f25f0d0eefb10d4e820ee574068f6515Torne (Richard Coles)** 11aa277f94f25f0d0eefb10d4e820ee574068f6515Torne (Richard Coles)** Unless required by applicable law or agreed to in writing, software 12aa277f94f25f0d0eefb10d4e820ee574068f6515Torne (Richard Coles)** distributed under the License is distributed on an "AS IS" BASIS, 13aa277f94f25f0d0eefb10d4e820ee574068f6515Torne (Richard Coles)** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14aa277f94f25f0d0eefb10d4e820ee574068f6515Torne (Richard Coles)** See the License for the specific language governing permissions and 15aa277f94f25f0d0eefb10d4e820ee574068f6515Torne (Richard Coles)** limitations under the License. 16aa277f94f25f0d0eefb10d4e820ee574068f6515Torne (Richard Coles)*/ 17aa277f94f25f0d0eefb10d4e820ee574068f6515Torne (Richard Coles) 18aa277f94f25f0d0eefb10d4e820ee574068f6515Torne (Richard Coles)//#define LOG_NDEBUG 0 19aa277f94f25f0d0eefb10d4e820ee574068f6515Torne (Richard Coles)#define LOG_TAG "AudioRecord" 20aa277f94f25f0d0eefb10d4e820ee574068f6515Torne (Richard Coles) 21aa277f94f25f0d0eefb10d4e820ee574068f6515Torne (Richard Coles)#include <sys/resource.h> 22cbaa791850e8a0f9a8a1cfc9c88aaecbd580d3ecTorne (Richard Coles)#include <sys/types.h> 23cbaa791850e8a0f9a8a1cfc9c88aaecbd580d3ecTorne (Richard Coles) 24cbaa791850e8a0f9a8a1cfc9c88aaecbd580d3ecTorne (Richard Coles)#include <binder/IPCThreadState.h> 25cbaa791850e8a0f9a8a1cfc9c88aaecbd580d3ecTorne (Richard Coles)#include <cutils/atomic.h> 26cbaa791850e8a0f9a8a1cfc9c88aaecbd580d3ecTorne (Richard Coles)#include <cutils/compiler.h> 27cbaa791850e8a0f9a8a1cfc9c88aaecbd580d3ecTorne (Richard Coles)#include <media/AudioRecord.h> 28cbaa791850e8a0f9a8a1cfc9c88aaecbd580d3ecTorne (Richard Coles)#include <media/AudioSystem.h> 29aa277f94f25f0d0eefb10d4e820ee574068f6515Torne (Richard Coles)#include <system/audio.h> 30aa277f94f25f0d0eefb10d4e820ee574068f6515Torne (Richard Coles)#include <utils/Log.h> 31aa277f94f25f0d0eefb10d4e820ee574068f6515Torne (Richard Coles) 32aa277f94f25f0d0eefb10d4e820ee574068f6515Torne (Richard Coles)#include <private/media/AudioTrackShared.h> 33aa277f94f25f0d0eefb10d4e820ee574068f6515Torne (Richard Coles) 34aa277f94f25f0d0eefb10d4e820ee574068f6515Torne (Richard Coles)namespace android { 35aa277f94f25f0d0eefb10d4e820ee574068f6515Torne (Richard Coles)// --------------------------------------------------------------------------- 36aa277f94f25f0d0eefb10d4e820ee574068f6515Torne (Richard Coles) 37aa277f94f25f0d0eefb10d4e820ee574068f6515Torne (Richard Coles)// static 380dd72dc2dac5ee57fd597f172e5015650312a700Ignacio Sollastatus_t AudioRecord::getMinFrameCount( 390dd72dc2dac5ee57fd597f172e5015650312a700Ignacio Solla int* frameCount, 40aa277f94f25f0d0eefb10d4e820ee574068f6515Torne (Richard Coles) uint32_t sampleRate, 41aa277f94f25f0d0eefb10d4e820ee574068f6515Torne (Richard Coles) audio_format_t format, 42aa277f94f25f0d0eefb10d4e820ee574068f6515Torne (Richard Coles) audio_channel_mask_t channelMask) 43074f227d175b9e70783dc939555ee89005642977Selim Gurun{ 44aa277f94f25f0d0eefb10d4e820ee574068f6515Torne (Richard Coles) if (frameCount == NULL) return BAD_VALUE; 45aa277f94f25f0d0eefb10d4e820ee574068f6515Torne (Richard Coles) 46aa277f94f25f0d0eefb10d4e820ee574068f6515Torne (Richard Coles) // default to 0 in case of error 47aa277f94f25f0d0eefb10d4e820ee574068f6515Torne (Richard Coles) *frameCount = 0; 48aa277f94f25f0d0eefb10d4e820ee574068f6515Torne (Richard Coles) 4961afed696a71ff0a288916a9319461cd880375e2Ben Murdoch size_t size = 0; 50aa277f94f25f0d0eefb10d4e820ee574068f6515Torne (Richard Coles) if (AudioSystem::getInputBufferSize(sampleRate, format, channelMask, &size) 51aa277f94f25f0d0eefb10d4e820ee574068f6515Torne (Richard Coles) != NO_ERROR) { 5261afed696a71ff0a288916a9319461cd880375e2Ben Murdoch ALOGE("AudioSystem could not query the input buffer size."); 53aa277f94f25f0d0eefb10d4e820ee574068f6515Torne (Richard Coles) return NO_INIT; 54aa277f94f25f0d0eefb10d4e820ee574068f6515Torne (Richard Coles) } 55aa277f94f25f0d0eefb10d4e820ee574068f6515Torne (Richard Coles) 5673e77f9db2815cf820a6753e2d532557cfc5b9a2Torne (Richard Coles) if (size == 0) { 5773e77f9db2815cf820a6753e2d532557cfc5b9a2Torne (Richard Coles) ALOGE("Unsupported configuration: sampleRate %d, format %d, channelMask %#x", 5873e77f9db2815cf820a6753e2d532557cfc5b9a2Torne (Richard Coles) sampleRate, format, channelMask); 59aa277f94f25f0d0eefb10d4e820ee574068f6515Torne (Richard Coles) return BAD_VALUE; 60aa277f94f25f0d0eefb10d4e820ee574068f6515Torne (Richard Coles) } 61aa277f94f25f0d0eefb10d4e820ee574068f6515Torne (Richard Coles) 62aa277f94f25f0d0eefb10d4e820ee574068f6515Torne (Richard Coles) // We double the size of input buffer for ping pong use of record buffer. 63aa277f94f25f0d0eefb10d4e820ee574068f6515Torne (Richard Coles) size <<= 1; 64e7088bc41cfbeb3eca02b1347c61cb21e37203b4Ying Wang 65e7088bc41cfbeb3eca02b1347c61cb21e37203b4Ying Wang if (audio_is_linear_pcm(format)) { 66e7088bc41cfbeb3eca02b1347c61cb21e37203b4Ying Wang int channelCount = popcount(channelMask); 67aa277f94f25f0d0eefb10d4e820ee574068f6515Torne (Richard Coles) size /= channelCount * audio_bytes_per_sample(format); 68aa277f94f25f0d0eefb10d4e820ee574068f6515Torne (Richard Coles) } 69aa277f94f25f0d0eefb10d4e820ee574068f6515Torne (Richard Coles) 70aa277f94f25f0d0eefb10d4e820ee574068f6515Torne (Richard Coles) *frameCount = size; 71aa277f94f25f0d0eefb10d4e820ee574068f6515Torne (Richard Coles) return NO_ERROR; 72aa277f94f25f0d0eefb10d4e820ee574068f6515Torne (Richard Coles)} 73aa277f94f25f0d0eefb10d4e820ee574068f6515Torne (Richard Coles) 74aa277f94f25f0d0eefb10d4e820ee574068f6515Torne (Richard Coles)// --------------------------------------------------------------------------- 75aa277f94f25f0d0eefb10d4e820ee574068f6515Torne (Richard Coles) 76aa277f94f25f0d0eefb10d4e820ee574068f6515Torne (Richard Coles)AudioRecord::AudioRecord() 77aa277f94f25f0d0eefb10d4e820ee574068f6515Torne (Richard Coles) : mStatus(NO_INIT), mSessionId(0), 78aa277f94f25f0d0eefb10d4e820ee574068f6515Torne (Richard Coles) mPreviousPriority(ANDROID_PRIORITY_NORMAL), mPreviousSchedulingGroup(SP_DEFAULT) 79aa277f94f25f0d0eefb10d4e820ee574068f6515Torne (Richard Coles){ 80aa277f94f25f0d0eefb10d4e820ee574068f6515Torne (Richard Coles)} 81aa277f94f25f0d0eefb10d4e820ee574068f6515Torne (Richard Coles) 82aa277f94f25f0d0eefb10d4e820ee574068f6515Torne (Richard Coles)AudioRecord::AudioRecord( 83aa277f94f25f0d0eefb10d4e820ee574068f6515Torne (Richard Coles) audio_source_t inputSource, 84aa277f94f25f0d0eefb10d4e820ee574068f6515Torne (Richard Coles) uint32_t sampleRate, 85aa277f94f25f0d0eefb10d4e820ee574068f6515Torne (Richard Coles) audio_format_t format, 86aa277f94f25f0d0eefb10d4e820ee574068f6515Torne (Richard Coles) audio_channel_mask_t channelMask, 87aa277f94f25f0d0eefb10d4e820ee574068f6515Torne (Richard Coles) int frameCount, 88aa277f94f25f0d0eefb10d4e820ee574068f6515Torne (Richard Coles) callback_t cbf, 89aa277f94f25f0d0eefb10d4e820ee574068f6515Torne (Richard Coles) void* user, 90aa277f94f25f0d0eefb10d4e820ee574068f6515Torne (Richard Coles) int notificationFrames, 91aa277f94f25f0d0eefb10d4e820ee574068f6515Torne (Richard Coles) int sessionId) 92aa277f94f25f0d0eefb10d4e820ee574068f6515Torne (Richard Coles) : mStatus(NO_INIT), mSessionId(0), 93aa277f94f25f0d0eefb10d4e820ee574068f6515Torne (Richard Coles) mPreviousPriority(ANDROID_PRIORITY_NORMAL), mPreviousSchedulingGroup(SP_DEFAULT) 94aa277f94f25f0d0eefb10d4e820ee574068f6515Torne (Richard Coles){ 95aa277f94f25f0d0eefb10d4e820ee574068f6515Torne (Richard Coles) mStatus = set(inputSource, sampleRate, format, channelMask, 96aa277f94f25f0d0eefb10d4e820ee574068f6515Torne (Richard Coles) frameCount, cbf, user, notificationFrames, sessionId); 97aa277f94f25f0d0eefb10d4e820ee574068f6515Torne (Richard Coles)} 98aa277f94f25f0d0eefb10d4e820ee574068f6515Torne (Richard Coles) 99aa277f94f25f0d0eefb10d4e820ee574068f6515Torne (Richard Coles)AudioRecord::~AudioRecord() 100aa277f94f25f0d0eefb10d4e820ee574068f6515Torne (Richard Coles){ 101cbaa791850e8a0f9a8a1cfc9c88aaecbd580d3ecTorne (Richard Coles) if (mStatus == NO_ERROR) { 102cbaa791850e8a0f9a8a1cfc9c88aaecbd580d3ecTorne (Richard Coles) // Make sure that callback function exits in the case where 103 // it is looping on buffer empty condition in obtainBuffer(). 104 // Otherwise the callback thread will never exit. 105 stop(); 106 if (mAudioRecordThread != 0) { 107 mAudioRecordThread->requestExit(); // see comment in AudioRecord.h 108 mAudioRecordThread->requestExitAndWait(); 109 mAudioRecordThread.clear(); 110 } 111 mAudioRecord.clear(); 112 IPCThreadState::self()->flushCommands(); 113 AudioSystem::releaseAudioSessionId(mSessionId); 114 } 115} 116 117status_t AudioRecord::set( 118 audio_source_t inputSource, 119 uint32_t sampleRate, 120 audio_format_t format, 121 audio_channel_mask_t channelMask, 122 int frameCount, 123 callback_t cbf, 124 void* user, 125 int notificationFrames, 126 bool threadCanCallJava, 127 int sessionId) 128{ 129 130 ALOGV("set(): sampleRate %d, channelMask %#x, frameCount %d",sampleRate, channelMask, 131 frameCount); 132 133 AutoMutex lock(mLock); 134 135 if (mAudioRecord != 0) { 136 return INVALID_OPERATION; 137 } 138 139 if (inputSource == AUDIO_SOURCE_DEFAULT) { 140 inputSource = AUDIO_SOURCE_MIC; 141 } 142 143 if (sampleRate == 0) { 144 sampleRate = DEFAULT_SAMPLE_RATE; 145 } 146 // these below should probably come from the audioFlinger too... 147 if (format == AUDIO_FORMAT_DEFAULT) { 148 format = AUDIO_FORMAT_PCM_16_BIT; 149 } 150 // validate parameters 151 if (!audio_is_valid_format(format)) { 152 ALOGE("Invalid format"); 153 return BAD_VALUE; 154 } 155 156 if (!audio_is_input_channel(channelMask)) { 157 return BAD_VALUE; 158 } 159 160 int channelCount = popcount(channelMask); 161 162 if (sessionId == 0 ) { 163 mSessionId = AudioSystem::newAudioSessionId(); 164 } else { 165 mSessionId = sessionId; 166 } 167 ALOGV("set(): mSessionId %d", mSessionId); 168 169 audio_io_handle_t input = AudioSystem::getInput(inputSource, 170 sampleRate, 171 format, 172 channelMask, 173 mSessionId); 174 if (input == 0) { 175 ALOGE("Could not get audio input for record source %d", inputSource); 176 return BAD_VALUE; 177 } 178 179 // validate framecount 180 int minFrameCount = 0; 181 status_t status = getMinFrameCount(&minFrameCount, sampleRate, format, channelMask); 182 if (status != NO_ERROR) { 183 return status; 184 } 185 ALOGV("AudioRecord::set() minFrameCount = %d", minFrameCount); 186 187 if (frameCount == 0) { 188 frameCount = minFrameCount; 189 } else if (frameCount < minFrameCount) { 190 return BAD_VALUE; 191 } 192 193 if (notificationFrames == 0) { 194 notificationFrames = frameCount/2; 195 } 196 197 // create the IAudioRecord 198 status = openRecord_l(sampleRate, format, channelMask, 199 frameCount, input); 200 if (status != NO_ERROR) { 201 return status; 202 } 203 204 if (cbf != NULL) { 205 mAudioRecordThread = new AudioRecordThread(*this, threadCanCallJava); 206 mAudioRecordThread->run("AudioRecord", ANDROID_PRIORITY_AUDIO); 207 } 208 209 mStatus = NO_ERROR; 210 211 mFormat = format; 212 // Update buffer size in case it has been limited by AudioFlinger during track creation 213 mFrameCount = mCblk->frameCount; 214 mChannelCount = (uint8_t)channelCount; 215 mChannelMask = channelMask; 216 mActive = false; 217 mCbf = cbf; 218 mNotificationFrames = notificationFrames; 219 mRemainingFrames = notificationFrames; 220 mUserData = user; 221 // TODO: add audio hardware input latency here 222 mLatency = (1000*mFrameCount) / sampleRate; 223 mMarkerPosition = 0; 224 mMarkerReached = false; 225 mNewPosition = 0; 226 mUpdatePeriod = 0; 227 mInputSource = inputSource; 228 mInput = input; 229 AudioSystem::acquireAudioSessionId(mSessionId); 230 231 return NO_ERROR; 232} 233 234status_t AudioRecord::initCheck() const 235{ 236 return mStatus; 237} 238 239// ------------------------------------------------------------------------- 240 241uint32_t AudioRecord::latency() const 242{ 243 return mLatency; 244} 245 246audio_format_t AudioRecord::format() const 247{ 248 return mFormat; 249} 250 251int AudioRecord::channelCount() const 252{ 253 return mChannelCount; 254} 255 256uint32_t AudioRecord::frameCount() const 257{ 258 return mFrameCount; 259} 260 261size_t AudioRecord::frameSize() const 262{ 263 if (audio_is_linear_pcm(mFormat)) { 264 return channelCount()*audio_bytes_per_sample(mFormat); 265 } else { 266 return sizeof(uint8_t); 267 } 268} 269 270audio_source_t AudioRecord::inputSource() const 271{ 272 return mInputSource; 273} 274 275// ------------------------------------------------------------------------- 276 277status_t AudioRecord::start(AudioSystem::sync_event_t event, int triggerSession) 278{ 279 status_t ret = NO_ERROR; 280 sp<AudioRecordThread> t = mAudioRecordThread; 281 282 ALOGV("start, sync event %d trigger session %d", event, triggerSession); 283 284 AutoMutex lock(mLock); 285 // acquire a strong reference on the IAudioRecord and IMemory so that they cannot be destroyed 286 // while we are accessing the cblk 287 sp<IAudioRecord> audioRecord = mAudioRecord; 288 sp<IMemory> iMem = mCblkMemory; 289 audio_track_cblk_t* cblk = mCblk; 290 291 if (!mActive) { 292 mActive = true; 293 294 cblk->lock.lock(); 295 if (!(cblk->flags & CBLK_INVALID)) { 296 cblk->lock.unlock(); 297 ALOGV("mAudioRecord->start()"); 298 ret = mAudioRecord->start(event, triggerSession); 299 cblk->lock.lock(); 300 if (ret == DEAD_OBJECT) { 301 android_atomic_or(CBLK_INVALID, &cblk->flags); 302 } 303 } 304 if (cblk->flags & CBLK_INVALID) { 305 ret = restoreRecord_l(cblk); 306 } 307 cblk->lock.unlock(); 308 if (ret == NO_ERROR) { 309 mNewPosition = cblk->user + mUpdatePeriod; 310 cblk->bufferTimeoutMs = (event == AudioSystem::SYNC_EVENT_NONE) ? MAX_RUN_TIMEOUT_MS : 311 AudioSystem::kSyncRecordStartTimeOutMs; 312 cblk->waitTimeMs = 0; 313 if (t != 0) { 314 t->resume(); 315 } else { 316 mPreviousPriority = getpriority(PRIO_PROCESS, 0); 317 get_sched_policy(0, &mPreviousSchedulingGroup); 318 androidSetThreadPriority(0, ANDROID_PRIORITY_AUDIO); 319 } 320 } else { 321 mActive = false; 322 } 323 } 324 325 return ret; 326} 327 328void AudioRecord::stop() 329{ 330 sp<AudioRecordThread> t = mAudioRecordThread; 331 332 ALOGV("stop"); 333 334 AutoMutex lock(mLock); 335 if (mActive) { 336 mActive = false; 337 mCblk->cv.signal(); 338 mAudioRecord->stop(); 339 // the record head position will reset to 0, so if a marker is set, we need 340 // to activate it again 341 mMarkerReached = false; 342 if (t != 0) { 343 t->pause(); 344 } else { 345 setpriority(PRIO_PROCESS, 0, mPreviousPriority); 346 set_sched_policy(0, mPreviousSchedulingGroup); 347 } 348 } 349} 350 351bool AudioRecord::stopped() const 352{ 353 AutoMutex lock(mLock); 354 return !mActive; 355} 356 357uint32_t AudioRecord::getSampleRate() const 358{ 359 return mCblk->sampleRate; 360} 361 362status_t AudioRecord::setMarkerPosition(uint32_t marker) 363{ 364 if (mCbf == NULL) return INVALID_OPERATION; 365 366 AutoMutex lock(mLock); 367 mMarkerPosition = marker; 368 mMarkerReached = false; 369 370 return NO_ERROR; 371} 372 373status_t AudioRecord::getMarkerPosition(uint32_t *marker) const 374{ 375 if (marker == NULL) return BAD_VALUE; 376 377 AutoMutex lock(mLock); 378 *marker = mMarkerPosition; 379 380 return NO_ERROR; 381} 382 383status_t AudioRecord::setPositionUpdatePeriod(uint32_t updatePeriod) 384{ 385 if (mCbf == NULL) return INVALID_OPERATION; 386 387 uint32_t curPosition; 388 getPosition(&curPosition); 389 390 AutoMutex lock(mLock); 391 mNewPosition = curPosition + updatePeriod; 392 mUpdatePeriod = updatePeriod; 393 394 return NO_ERROR; 395} 396 397status_t AudioRecord::getPositionUpdatePeriod(uint32_t *updatePeriod) const 398{ 399 if (updatePeriod == NULL) return BAD_VALUE; 400 401 AutoMutex lock(mLock); 402 *updatePeriod = mUpdatePeriod; 403 404 return NO_ERROR; 405} 406 407status_t AudioRecord::getPosition(uint32_t *position) const 408{ 409 if (position == NULL) return BAD_VALUE; 410 411 AutoMutex lock(mLock); 412 *position = mCblk->user; 413 414 return NO_ERROR; 415} 416 417unsigned int AudioRecord::getInputFramesLost() const 418{ 419 // no need to check mActive, because if inactive this will return 0, which is what we want 420 return AudioSystem::getInputFramesLost(mInput); 421} 422 423// ------------------------------------------------------------------------- 424 425// must be called with mLock held 426status_t AudioRecord::openRecord_l( 427 uint32_t sampleRate, 428 audio_format_t format, 429 audio_channel_mask_t channelMask, 430 int frameCount, 431 audio_io_handle_t input) 432{ 433 status_t status; 434 const sp<IAudioFlinger>& audioFlinger = AudioSystem::get_audio_flinger(); 435 if (audioFlinger == 0) { 436 return NO_INIT; 437 } 438 439 pid_t tid = -1; 440 // FIXME see similar logic at AudioTrack 441 442 int originalSessionId = mSessionId; 443 sp<IAudioRecord> record = audioFlinger->openRecord(getpid(), input, 444 sampleRate, format, 445 channelMask, 446 frameCount, 447 IAudioFlinger::TRACK_DEFAULT, 448 tid, 449 &mSessionId, 450 &status); 451 ALOGE_IF(originalSessionId != 0 && mSessionId != originalSessionId, 452 "session ID changed from %d to %d", originalSessionId, mSessionId); 453 454 if (record == 0) { 455 ALOGE("AudioFlinger could not create record track, status: %d", status); 456 return status; 457 } 458 sp<IMemory> cblk = record->getCblk(); 459 if (cblk == 0) { 460 ALOGE("Could not get control block"); 461 return NO_INIT; 462 } 463 mAudioRecord.clear(); 464 mAudioRecord = record; 465 mCblkMemory.clear(); 466 mCblkMemory = cblk; 467 mCblk = static_cast<audio_track_cblk_t*>(cblk->pointer()); 468 mCblk->buffers = (char*)mCblk + sizeof(audio_track_cblk_t); 469 android_atomic_and(~CBLK_DIRECTION, &mCblk->flags); 470 mCblk->bufferTimeoutMs = MAX_RUN_TIMEOUT_MS; 471 mCblk->waitTimeMs = 0; 472 return NO_ERROR; 473} 474 475status_t AudioRecord::obtainBuffer(Buffer* audioBuffer, int32_t waitCount) 476{ 477 AutoMutex lock(mLock); 478 bool active; 479 status_t result = NO_ERROR; 480 audio_track_cblk_t* cblk = mCblk; 481 uint32_t framesReq = audioBuffer->frameCount; 482 uint32_t waitTimeMs = (waitCount < 0) ? cblk->bufferTimeoutMs : WAIT_PERIOD_MS; 483 484 audioBuffer->frameCount = 0; 485 audioBuffer->size = 0; 486 487 uint32_t framesReady = cblk->framesReady(); 488 489 if (framesReady == 0) { 490 cblk->lock.lock(); 491 goto start_loop_here; 492 while (framesReady == 0) { 493 active = mActive; 494 if (CC_UNLIKELY(!active)) { 495 cblk->lock.unlock(); 496 return NO_MORE_BUFFERS; 497 } 498 if (CC_UNLIKELY(!waitCount)) { 499 cblk->lock.unlock(); 500 return WOULD_BLOCK; 501 } 502 if (!(cblk->flags & CBLK_INVALID)) { 503 mLock.unlock(); 504 result = cblk->cv.waitRelative(cblk->lock, milliseconds(waitTimeMs)); 505 cblk->lock.unlock(); 506 mLock.lock(); 507 if (!mActive) { 508 return status_t(STOPPED); 509 } 510 cblk->lock.lock(); 511 } 512 if (cblk->flags & CBLK_INVALID) { 513 goto create_new_record; 514 } 515 if (CC_UNLIKELY(result != NO_ERROR)) { 516 cblk->waitTimeMs += waitTimeMs; 517 if (cblk->waitTimeMs >= cblk->bufferTimeoutMs) { 518 ALOGW( "obtainBuffer timed out (is the CPU pegged?) " 519 "user=%08x, server=%08x", cblk->user, cblk->server); 520 cblk->lock.unlock(); 521 // callback thread or sync event hasn't changed 522 result = mAudioRecord->start(AudioSystem::SYNC_EVENT_SAME, 0); 523 cblk->lock.lock(); 524 if (result == DEAD_OBJECT) { 525 android_atomic_or(CBLK_INVALID, &cblk->flags); 526create_new_record: 527 result = AudioRecord::restoreRecord_l(cblk); 528 } 529 if (result != NO_ERROR) { 530 ALOGW("obtainBuffer create Track error %d", result); 531 cblk->lock.unlock(); 532 return result; 533 } 534 cblk->waitTimeMs = 0; 535 } 536 if (--waitCount == 0) { 537 cblk->lock.unlock(); 538 return TIMED_OUT; 539 } 540 } 541 // read the server count again 542 start_loop_here: 543 framesReady = cblk->framesReady(); 544 } 545 cblk->lock.unlock(); 546 } 547 548 cblk->waitTimeMs = 0; 549 // reset time out to running value after obtaining a buffer 550 cblk->bufferTimeoutMs = MAX_RUN_TIMEOUT_MS; 551 552 if (framesReq > framesReady) { 553 framesReq = framesReady; 554 } 555 556 uint32_t u = cblk->user; 557 uint32_t bufferEnd = cblk->userBase + cblk->frameCount; 558 559 if (framesReq > bufferEnd - u) { 560 framesReq = bufferEnd - u; 561 } 562 563 audioBuffer->flags = 0; 564 audioBuffer->channelCount= mChannelCount; 565 audioBuffer->format = mFormat; 566 audioBuffer->frameCount = framesReq; 567 audioBuffer->size = framesReq*cblk->frameSize; 568 audioBuffer->raw = (int8_t*)cblk->buffer(u); 569 active = mActive; 570 return active ? status_t(NO_ERROR) : status_t(STOPPED); 571} 572 573void AudioRecord::releaseBuffer(Buffer* audioBuffer) 574{ 575 AutoMutex lock(mLock); 576 mCblk->stepUser(audioBuffer->frameCount); 577} 578 579audio_io_handle_t AudioRecord::getInput() const 580{ 581 AutoMutex lock(mLock); 582 return mInput; 583} 584 585// must be called with mLock held 586audio_io_handle_t AudioRecord::getInput_l() 587{ 588 mInput = AudioSystem::getInput(mInputSource, 589 mCblk->sampleRate, 590 mFormat, 591 mChannelMask, 592 mSessionId); 593 return mInput; 594} 595 596int AudioRecord::getSessionId() const 597{ 598 // no lock needed because session ID doesn't change after first set() 599 return mSessionId; 600} 601 602// ------------------------------------------------------------------------- 603 604ssize_t AudioRecord::read(void* buffer, size_t userSize) 605{ 606 ssize_t read = 0; 607 Buffer audioBuffer; 608 int8_t *dst = static_cast<int8_t*>(buffer); 609 610 if (ssize_t(userSize) < 0) { 611 // sanity-check. user is most-likely passing an error code. 612 ALOGE("AudioRecord::read(buffer=%p, size=%u (%d)", 613 buffer, userSize, userSize); 614 return BAD_VALUE; 615 } 616 617 mLock.lock(); 618 // acquire a strong reference on the IAudioRecord and IMemory so that they cannot be destroyed 619 // while we are accessing the cblk 620 sp<IAudioRecord> audioRecord = mAudioRecord; 621 sp<IMemory> iMem = mCblkMemory; 622 mLock.unlock(); 623 624 do { 625 626 audioBuffer.frameCount = userSize/frameSize(); 627 628 // By using a wait count corresponding to twice the timeout period in 629 // obtainBuffer() we give a chance to recover once for a read timeout 630 // (if media_server crashed for instance) before returning a length of 631 // 0 bytes read to the client 632 status_t err = obtainBuffer(&audioBuffer, ((2 * MAX_RUN_TIMEOUT_MS) / WAIT_PERIOD_MS)); 633 if (err < 0) { 634 // out of buffers, return #bytes written 635 if (err == status_t(NO_MORE_BUFFERS)) 636 break; 637 if (err == status_t(TIMED_OUT)) 638 err = 0; 639 return ssize_t(err); 640 } 641 642 size_t bytesRead = audioBuffer.size; 643 memcpy(dst, audioBuffer.i8, bytesRead); 644 645 dst += bytesRead; 646 userSize -= bytesRead; 647 read += bytesRead; 648 649 releaseBuffer(&audioBuffer); 650 } while (userSize); 651 652 return read; 653} 654 655// ------------------------------------------------------------------------- 656 657bool AudioRecord::processAudioBuffer(const sp<AudioRecordThread>& thread) 658{ 659 Buffer audioBuffer; 660 uint32_t frames = mRemainingFrames; 661 size_t readSize; 662 663 mLock.lock(); 664 // acquire a strong reference on the IAudioRecord and IMemory so that they cannot be destroyed 665 // while we are accessing the cblk 666 sp<IAudioRecord> audioRecord = mAudioRecord; 667 sp<IMemory> iMem = mCblkMemory; 668 audio_track_cblk_t* cblk = mCblk; 669 bool active = mActive; 670 uint32_t markerPosition = mMarkerPosition; 671 uint32_t newPosition = mNewPosition; 672 uint32_t user = cblk->user; 673 // determine whether a marker callback will be needed, while locked 674 bool needMarker = !mMarkerReached && (mMarkerPosition > 0) && (user >= mMarkerPosition); 675 if (needMarker) { 676 mMarkerReached = true; 677 } 678 // determine the number of new position callback(s) that will be needed, while locked 679 uint32_t updatePeriod = mUpdatePeriod; 680 uint32_t needNewPos = updatePeriod > 0 && user >= newPosition ? 681 ((user - newPosition) / updatePeriod) + 1 : 0; 682 mNewPosition = newPosition + updatePeriod * needNewPos; 683 mLock.unlock(); 684 685 // perform marker callback, while unlocked 686 if (needMarker) { 687 mCbf(EVENT_MARKER, mUserData, &markerPosition); 688 } 689 690 // perform new position callback(s), while unlocked 691 for (; needNewPos > 0; --needNewPos) { 692 uint32_t temp = newPosition; 693 mCbf(EVENT_NEW_POS, mUserData, &temp); 694 newPosition += updatePeriod; 695 } 696 697 do { 698 audioBuffer.frameCount = frames; 699 // Calling obtainBuffer() with a wait count of 1 700 // limits wait time to WAIT_PERIOD_MS. This prevents from being 701 // stuck here not being able to handle timed events (position, markers). 702 status_t err = obtainBuffer(&audioBuffer, 1); 703 if (err < NO_ERROR) { 704 if (err != TIMED_OUT) { 705 ALOGE_IF(err != status_t(NO_MORE_BUFFERS), 706 "Error obtaining an audio buffer, giving up."); 707 return false; 708 } 709 break; 710 } 711 if (err == status_t(STOPPED)) return false; 712 713 size_t reqSize = audioBuffer.size; 714 mCbf(EVENT_MORE_DATA, mUserData, &audioBuffer); 715 readSize = audioBuffer.size; 716 717 // Sanity check on returned size 718 if (ssize_t(readSize) <= 0) { 719 // The callback is done filling buffers 720 // Keep this thread going to handle timed events and 721 // still try to get more data in intervals of WAIT_PERIOD_MS 722 // but don't just loop and block the CPU, so wait 723 usleep(WAIT_PERIOD_MS*1000); 724 break; 725 } 726 if (readSize > reqSize) readSize = reqSize; 727 728 audioBuffer.size = readSize; 729 audioBuffer.frameCount = readSize/frameSize(); 730 frames -= audioBuffer.frameCount; 731 732 releaseBuffer(&audioBuffer); 733 734 } while (frames); 735 736 737 // Manage overrun callback 738 if (active && (cblk->framesAvailable() == 0)) { 739 // The value of active is stale, but we are almost sure to be active here because 740 // otherwise we would have exited when obtainBuffer returned STOPPED earlier. 741 ALOGV("Overrun user: %x, server: %x, flags %04x", cblk->user, cblk->server, cblk->flags); 742 if (!(android_atomic_or(CBLK_UNDERRUN, &cblk->flags) & CBLK_UNDERRUN)) { 743 mCbf(EVENT_OVERRUN, mUserData, NULL); 744 } 745 } 746 747 if (frames == 0) { 748 mRemainingFrames = mNotificationFrames; 749 } else { 750 mRemainingFrames = frames; 751 } 752 return true; 753} 754 755// must be called with mLock and cblk.lock held. Callers must also hold strong references on 756// the IAudioRecord and IMemory in case they are recreated here. 757// If the IAudioRecord is successfully restored, the cblk pointer is updated 758status_t AudioRecord::restoreRecord_l(audio_track_cblk_t*& cblk) 759{ 760 status_t result; 761 762 if (!(android_atomic_or(CBLK_RESTORING, &cblk->flags) & CBLK_RESTORING)) { 763 ALOGW("dead IAudioRecord, creating a new one"); 764 // signal old cblk condition so that other threads waiting for available buffers stop 765 // waiting now 766 cblk->cv.broadcast(); 767 cblk->lock.unlock(); 768 769 // if the new IAudioRecord is created, openRecord_l() will modify the 770 // following member variables: mAudioRecord, mCblkMemory and mCblk. 771 // It will also delete the strong references on previous IAudioRecord and IMemory 772 result = openRecord_l(cblk->sampleRate, mFormat, mChannelMask, 773 mFrameCount, getInput_l()); 774 if (result == NO_ERROR) { 775 // callback thread or sync event hasn't changed 776 result = mAudioRecord->start(AudioSystem::SYNC_EVENT_SAME, 0); 777 } 778 if (result != NO_ERROR) { 779 mActive = false; 780 } 781 782 // signal old cblk condition for other threads waiting for restore completion 783 android_atomic_or(CBLK_RESTORED, &cblk->flags); 784 cblk->cv.broadcast(); 785 } else { 786 if (!(cblk->flags & CBLK_RESTORED)) { 787 ALOGW("dead IAudioRecord, waiting for a new one to be created"); 788 mLock.unlock(); 789 result = cblk->cv.waitRelative(cblk->lock, milliseconds(RESTORE_TIMEOUT_MS)); 790 cblk->lock.unlock(); 791 mLock.lock(); 792 } else { 793 ALOGW("dead IAudioRecord, already restored"); 794 result = NO_ERROR; 795 cblk->lock.unlock(); 796 } 797 if (result != NO_ERROR || !mActive) { 798 result = status_t(STOPPED); 799 } 800 } 801 ALOGV("restoreRecord_l() status %d mActive %d cblk %p, old cblk %p flags %08x old flags %08x", 802 result, mActive, mCblk, cblk, mCblk->flags, cblk->flags); 803 804 if (result == NO_ERROR) { 805 // from now on we switch to the newly created cblk 806 cblk = mCblk; 807 } 808 cblk->lock.lock(); 809 810 ALOGW_IF(result != NO_ERROR, "restoreRecord_l() error %d", result); 811 812 return result; 813} 814 815// ========================================================================= 816 817AudioRecord::AudioRecordThread::AudioRecordThread(AudioRecord& receiver, bool bCanCallJava) 818 : Thread(bCanCallJava), mReceiver(receiver), mPaused(true) 819{ 820} 821 822AudioRecord::AudioRecordThread::~AudioRecordThread() 823{ 824} 825 826bool AudioRecord::AudioRecordThread::threadLoop() 827{ 828 { 829 AutoMutex _l(mMyLock); 830 if (mPaused) { 831 mMyCond.wait(mMyLock); 832 // caller will check for exitPending() 833 return true; 834 } 835 } 836 if (!mReceiver.processAudioBuffer(this)) { 837 pause(); 838 } 839 return true; 840} 841 842void AudioRecord::AudioRecordThread::requestExit() 843{ 844 // must be in this order to avoid a race condition 845 Thread::requestExit(); 846 resume(); 847} 848 849void AudioRecord::AudioRecordThread::pause() 850{ 851 AutoMutex _l(mMyLock); 852 mPaused = true; 853} 854 855void AudioRecord::AudioRecordThread::resume() 856{ 857 AutoMutex _l(mMyLock); 858 if (mPaused) { 859 mPaused = false; 860 mMyCond.signal(); 861 } 862} 863 864// ------------------------------------------------------------------------- 865 866}; // namespace android 867