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