AudioRecord.cpp revision e3aa659e9cee7df5c12a80d285cc29ab3b2cbb39
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 34namespace android { 35// --------------------------------------------------------------------------- 36 37// static 38status_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 if (AudioSystem::getInputBufferSize(sampleRate, format, channelMask, &size) 51 != NO_ERROR) { 52 ALOGE("AudioSystem could not query the input buffer size."); 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 76AudioRecord::AudioRecord() 77 : mStatus(NO_INIT), mSessionId(0), 78 mPreviousPriority(ANDROID_PRIORITY_NORMAL), mPreviousSchedulingGroup(SP_DEFAULT), 79 mProxy(NULL) 80{ 81} 82 83AudioRecord::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, sessionId); 100} 101 102AudioRecord::~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 121status_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 168 if (!audio_is_input_channel(channelMask)) { 169 return BAD_VALUE; 170 } 171 mChannelMask = channelMask; 172 uint32_t channelCount = popcount(channelMask); 173 mChannelCount = channelCount; 174 175 if (audio_is_linear_pcm(mFormat)) { 176 mFrameSize = channelCount * audio_bytes_per_sample(format); 177 } else { 178 mFrameSize = sizeof(uint8_t); 179 } 180 181 if (sessionId == 0 ) { 182 mSessionId = AudioSystem::newAudioSessionId(); 183 } else { 184 mSessionId = sessionId; 185 } 186 ALOGV("set(): mSessionId %d", mSessionId); 187 188 audio_io_handle_t input = AudioSystem::getInput(inputSource, 189 sampleRate, 190 format, 191 channelMask, 192 mSessionId); 193 if (input == 0) { 194 ALOGE("Could not get audio input for record source %d", inputSource); 195 return BAD_VALUE; 196 } 197 198 // validate framecount 199 size_t minFrameCount = 0; 200 status_t status = getMinFrameCount(&minFrameCount, sampleRate, format, channelMask); 201 if (status != NO_ERROR) { 202 return status; 203 } 204 ALOGV("AudioRecord::set() minFrameCount = %d", minFrameCount); 205 206 if (frameCount == 0) { 207 frameCount = minFrameCount; 208 } else if (frameCount < minFrameCount) { 209 return BAD_VALUE; 210 } 211 212 if (notificationFrames == 0) { 213 notificationFrames = frameCount/2; 214 } 215 216 // create the IAudioRecord 217 status = openRecord_l(sampleRate, format, frameCount, input); 218 if (status != NO_ERROR) { 219 return status; 220 } 221 222 if (cbf != NULL) { 223 mAudioRecordThread = new AudioRecordThread(*this, threadCanCallJava); 224 mAudioRecordThread->run("AudioRecord", ANDROID_PRIORITY_AUDIO); 225 } 226 227 mStatus = NO_ERROR; 228 229 mFormat = format; 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 251status_t AudioRecord::initCheck() const 252{ 253 return mStatus; 254} 255 256// ------------------------------------------------------------------------- 257 258uint32_t AudioRecord::latency() const 259{ 260 return mLatency; 261} 262 263audio_format_t AudioRecord::format() const 264{ 265 return mFormat; 266} 267 268uint32_t AudioRecord::channelCount() const 269{ 270 return mChannelCount; 271} 272 273size_t AudioRecord::frameCount() const 274{ 275 return mFrameCount; 276} 277 278audio_source_t AudioRecord::inputSource() const 279{ 280 return mInputSource; 281} 282 283// ------------------------------------------------------------------------- 284 285status_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 338void 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 361bool AudioRecord::stopped() const 362{ 363 AutoMutex lock(mLock); 364 return !mActive; 365} 366 367uint32_t AudioRecord::getSampleRate() const 368{ 369 return mSampleRate; 370} 371 372status_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 383status_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 393status_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 407status_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 417status_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 427unsigned 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 436status_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(getpid(), 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 490status_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); 548create_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 594void 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 602audio_io_handle_t AudioRecord::getInput() const 603{ 604 AutoMutex lock(mLock); 605 return mInput; 606} 607 608// must be called with mLock held 609audio_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 619int AudioRecord::getSessionId() const 620{ 621 // no lock needed because session ID doesn't change after first set() 622 return mSessionId; 623} 624 625// ------------------------------------------------------------------------- 626 627ssize_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 err = 0; 663 } 664 return ssize_t(err); 665 } 666 667 size_t bytesRead = audioBuffer.size; 668 memcpy(dst, audioBuffer.i8, bytesRead); 669 670 dst += bytesRead; 671 userSize -= bytesRead; 672 read += bytesRead; 673 674 releaseBuffer(&audioBuffer); 675 } while (userSize); 676 677 return read; 678} 679 680// ------------------------------------------------------------------------- 681 682bool AudioRecord::processAudioBuffer(const sp<AudioRecordThread>& thread) 683{ 684 Buffer audioBuffer; 685 uint32_t frames = mRemainingFrames; 686 size_t readSize; 687 688 mLock.lock(); 689 // acquire a strong reference on the IAudioRecord and IMemory so that they cannot be destroyed 690 // while we are accessing the cblk 691 sp<IAudioRecord> audioRecord = mAudioRecord; 692 sp<IMemory> iMem = mCblkMemory; 693 audio_track_cblk_t* cblk = mCblk; 694 bool active = mActive; 695 uint32_t markerPosition = mMarkerPosition; 696 uint32_t newPosition = mNewPosition; 697 uint32_t user = cblk->user; 698 // determine whether a marker callback will be needed, while locked 699 bool needMarker = !mMarkerReached && (mMarkerPosition > 0) && (user >= mMarkerPosition); 700 if (needMarker) { 701 mMarkerReached = true; 702 } 703 // determine the number of new position callback(s) that will be needed, while locked 704 uint32_t updatePeriod = mUpdatePeriod; 705 uint32_t needNewPos = updatePeriod > 0 && user >= newPosition ? 706 ((user - newPosition) / updatePeriod) + 1 : 0; 707 mNewPosition = newPosition + updatePeriod * needNewPos; 708 mLock.unlock(); 709 710 // perform marker callback, while unlocked 711 if (needMarker) { 712 mCbf(EVENT_MARKER, mUserData, &markerPosition); 713 } 714 715 // perform new position callback(s), while unlocked 716 for (; needNewPos > 0; --needNewPos) { 717 uint32_t temp = newPosition; 718 mCbf(EVENT_NEW_POS, mUserData, &temp); 719 newPosition += updatePeriod; 720 } 721 722 do { 723 audioBuffer.frameCount = frames; 724 // Calling obtainBuffer() with a wait count of 1 725 // limits wait time to WAIT_PERIOD_MS. This prevents from being 726 // stuck here not being able to handle timed events (position, markers). 727 status_t err = obtainBuffer(&audioBuffer, 1); 728 if (err < NO_ERROR) { 729 if (err != TIMED_OUT) { 730 ALOGE_IF(err != status_t(NO_MORE_BUFFERS), 731 "Error obtaining an audio buffer, giving up."); 732 return false; 733 } 734 break; 735 } 736 if (err == status_t(STOPPED)) return false; 737 738 size_t reqSize = audioBuffer.size; 739 mCbf(EVENT_MORE_DATA, mUserData, &audioBuffer); 740 readSize = audioBuffer.size; 741 742 // Sanity check on returned size 743 if (ssize_t(readSize) <= 0) { 744 // The callback is done filling buffers 745 // Keep this thread going to handle timed events and 746 // still try to get more data in intervals of WAIT_PERIOD_MS 747 // but don't just loop and block the CPU, so wait 748 usleep(WAIT_PERIOD_MS*1000); 749 break; 750 } 751 if (readSize > reqSize) readSize = reqSize; 752 753 audioBuffer.size = readSize; 754 audioBuffer.frameCount = readSize/frameSize(); 755 frames -= audioBuffer.frameCount; 756 757 releaseBuffer(&audioBuffer); 758 759 } while (frames); 760 761 762 // Manage overrun callback 763 if (active && (mProxy->framesAvailable() == 0)) { 764 // The value of active is stale, but we are almost sure to be active here because 765 // otherwise we would have exited when obtainBuffer returned STOPPED earlier. 766 ALOGV("Overrun user: %x, server: %x, flags %04x", cblk->user, cblk->server, cblk->flags); 767 if (!(android_atomic_or(CBLK_UNDERRUN, &cblk->flags) & CBLK_UNDERRUN)) { 768 mCbf(EVENT_OVERRUN, mUserData, NULL); 769 } 770 } 771 772 if (frames == 0) { 773 mRemainingFrames = mNotificationFrames; 774 } else { 775 mRemainingFrames = frames; 776 } 777 return true; 778} 779 780// must be called with mLock and cblk.lock held. Callers must also hold strong references on 781// the IAudioRecord and IMemory in case they are recreated here. 782// If the IAudioRecord is successfully restored, the cblk pointer is updated 783status_t AudioRecord::restoreRecord_l(audio_track_cblk_t*& refCblk) 784{ 785 status_t result; 786 787 audio_track_cblk_t* cblk = refCblk; 788 audio_track_cblk_t* newCblk = cblk; 789 ALOGW("dead IAudioRecord, creating a new one"); 790 791 // signal old cblk condition so that other threads waiting for available buffers stop 792 // waiting now 793 cblk->cv.broadcast(); 794 cblk->lock.unlock(); 795 796 // if the new IAudioRecord is created, openRecord_l() will modify the 797 // following member variables: mAudioRecord, mCblkMemory and mCblk. 798 // It will also delete the strong references on previous IAudioRecord and IMemory 799 result = openRecord_l(mSampleRate, mFormat, mFrameCount, getInput_l()); 800 if (result == NO_ERROR) { 801 newCblk = mCblk; 802 // callback thread or sync event hasn't changed 803 result = mAudioRecord->start(AudioSystem::SYNC_EVENT_SAME, 0); 804 } 805 if (result != NO_ERROR) { 806 mActive = false; 807 } 808 809 ALOGV("restoreRecord_l() status %d mActive %d cblk %p, old cblk %p flags %08x old flags %08x", 810 result, mActive, newCblk, cblk, newCblk->flags, cblk->flags); 811 812 if (result == NO_ERROR) { 813 // from now on we switch to the newly created cblk 814 refCblk = newCblk; 815 } 816 newCblk->lock.lock(); 817 818 ALOGW_IF(result != NO_ERROR, "restoreRecord_l() error %d", result); 819 820 return result; 821} 822 823// ========================================================================= 824 825AudioRecord::AudioRecordThread::AudioRecordThread(AudioRecord& receiver, bool bCanCallJava) 826 : Thread(bCanCallJava), mReceiver(receiver), mPaused(true) 827{ 828} 829 830AudioRecord::AudioRecordThread::~AudioRecordThread() 831{ 832} 833 834bool AudioRecord::AudioRecordThread::threadLoop() 835{ 836 { 837 AutoMutex _l(mMyLock); 838 if (mPaused) { 839 mMyCond.wait(mMyLock); 840 // caller will check for exitPending() 841 return true; 842 } 843 } 844 if (!mReceiver.processAudioBuffer(this)) { 845 pause(); 846 } 847 return true; 848} 849 850void AudioRecord::AudioRecordThread::requestExit() 851{ 852 // must be in this order to avoid a race condition 853 Thread::requestExit(); 854 resume(); 855} 856 857void AudioRecord::AudioRecordThread::pause() 858{ 859 AutoMutex _l(mMyLock); 860 mPaused = true; 861} 862 863void AudioRecord::AudioRecordThread::resume() 864{ 865 AutoMutex _l(mMyLock); 866 if (mPaused) { 867 mPaused = false; 868 mMyCond.signal(); 869 } 870} 871 872// ------------------------------------------------------------------------- 873 874}; // namespace android 875