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