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