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