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