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