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