AudioRecord.cpp revision 089e87201522c8979ac8f00fa729e907f54c790b
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 <binder/IPCThreadState.h> 23#include <media/AudioRecord.h> 24#include <utils/Log.h> 25#include <private/media/AudioTrackShared.h> 26#include <media/IAudioFlinger.h> 27 28#define WAIT_PERIOD_MS 10 29 30namespace android { 31// --------------------------------------------------------------------------- 32 33// static 34status_t AudioRecord::getMinFrameCount( 35 size_t* frameCount, 36 uint32_t sampleRate, 37 audio_format_t format, 38 audio_channel_mask_t channelMask) 39{ 40 if (frameCount == NULL) { 41 return BAD_VALUE; 42 } 43 44 // default to 0 in case of error 45 *frameCount = 0; 46 47 size_t size = 0; 48 status_t status = AudioSystem::getInputBufferSize(sampleRate, format, channelMask, &size); 49 if (status != NO_ERROR) { 50 ALOGE("AudioSystem could not query the input buffer size; status %d", status); 51 return NO_INIT; 52 } 53 54 if (size == 0) { 55 ALOGE("Unsupported configuration: sampleRate %u, format %#x, channelMask %#x", 56 sampleRate, format, channelMask); 57 return BAD_VALUE; 58 } 59 60 // We double the size of input buffer for ping pong use of record buffer. 61 size <<= 1; 62 63 // Assumes audio_is_linear_pcm(format) 64 uint32_t channelCount = popcount(channelMask); 65 size /= channelCount * audio_bytes_per_sample(format); 66 67 *frameCount = size; 68 return NO_ERROR; 69} 70 71// --------------------------------------------------------------------------- 72 73AudioRecord::AudioRecord() 74 : mStatus(NO_INIT), mSessionId(AUDIO_SESSION_ALLOCATE), 75 mPreviousPriority(ANDROID_PRIORITY_NORMAL), mPreviousSchedulingGroup(SP_DEFAULT) 76{ 77} 78 79AudioRecord::AudioRecord( 80 audio_source_t inputSource, 81 uint32_t sampleRate, 82 audio_format_t format, 83 audio_channel_mask_t channelMask, 84 int frameCount, 85 callback_t cbf, 86 void* user, 87 int notificationFrames, 88 int sessionId, 89 transfer_type transferType, 90 audio_input_flags_t flags __unused) 91 : mStatus(NO_INIT), mSessionId(AUDIO_SESSION_ALLOCATE), 92 mPreviousPriority(ANDROID_PRIORITY_NORMAL), 93 mPreviousSchedulingGroup(SP_DEFAULT), 94 mProxy(NULL) 95{ 96 mStatus = set(inputSource, sampleRate, format, channelMask, frameCount, cbf, user, 97 notificationFrames, false /*threadCanCallJava*/, sessionId, transferType); 98} 99 100AudioRecord::~AudioRecord() 101{ 102 if (mStatus == NO_ERROR) { 103 // Make sure that callback function exits in the case where 104 // it is looping on buffer empty condition in obtainBuffer(). 105 // Otherwise the callback thread will never exit. 106 stop(); 107 if (mAudioRecordThread != 0) { 108 mProxy->interrupt(); 109 mAudioRecordThread->requestExit(); // see comment in AudioRecord.h 110 mAudioRecordThread->requestExitAndWait(); 111 mAudioRecordThread.clear(); 112 } 113 mAudioRecord->asBinder()->unlinkToDeath(mDeathNotifier, this); 114 mAudioRecord.clear(); 115 IPCThreadState::self()->flushCommands(); 116 AudioSystem::releaseAudioSessionId(mSessionId, -1); 117 } 118} 119 120status_t AudioRecord::set( 121 audio_source_t inputSource, 122 uint32_t sampleRate, 123 audio_format_t format, 124 audio_channel_mask_t channelMask, 125 int frameCountInt, 126 callback_t cbf, 127 void* user, 128 int notificationFrames, 129 bool threadCanCallJava, 130 int sessionId, 131 transfer_type transferType, 132 audio_input_flags_t flags) 133{ 134 ALOGV("set(): inputSource %d, sampleRate %u, format %#x, channelMask %#x, frameCount %d, " 135 "notificationFrames %d, sessionId %d, transferType %d, flags %#x", 136 inputSource, sampleRate, format, channelMask, frameCountInt, notificationFrames, 137 sessionId, transferType, flags); 138 139 switch (transferType) { 140 case TRANSFER_DEFAULT: 141 if (cbf == NULL || threadCanCallJava) { 142 transferType = TRANSFER_SYNC; 143 } else { 144 transferType = TRANSFER_CALLBACK; 145 } 146 break; 147 case TRANSFER_CALLBACK: 148 if (cbf == NULL) { 149 ALOGE("Transfer type TRANSFER_CALLBACK but cbf == NULL"); 150 return BAD_VALUE; 151 } 152 break; 153 case TRANSFER_OBTAIN: 154 case TRANSFER_SYNC: 155 break; 156 default: 157 ALOGE("Invalid transfer type %d", transferType); 158 return BAD_VALUE; 159 } 160 mTransfer = transferType; 161 162 // FIXME "int" here is legacy and will be replaced by size_t later 163 if (frameCountInt < 0) { 164 ALOGE("Invalid frame count %d", frameCountInt); 165 return BAD_VALUE; 166 } 167 size_t frameCount = frameCountInt; 168 169 AutoMutex lock(mLock); 170 171 // invariant that mAudioRecord != 0 is true only after set() returns successfully 172 if (mAudioRecord != 0) { 173 ALOGE("Track already in use"); 174 return INVALID_OPERATION; 175 } 176 177 // handle default values first. 178 if (inputSource == AUDIO_SOURCE_DEFAULT) { 179 inputSource = AUDIO_SOURCE_MIC; 180 } 181 mInputSource = inputSource; 182 183 if (sampleRate == 0) { 184 ALOGE("Invalid sample rate %u", sampleRate); 185 return BAD_VALUE; 186 } 187 mSampleRate = sampleRate; 188 189 // these below should probably come from the audioFlinger too... 190 if (format == AUDIO_FORMAT_DEFAULT) { 191 format = AUDIO_FORMAT_PCM_16_BIT; 192 } 193 194 // validate parameters 195 if (!audio_is_valid_format(format)) { 196 ALOGE("Invalid format %#x", format); 197 return BAD_VALUE; 198 } 199 // Temporary restriction: AudioFlinger currently supports 16-bit PCM only 200 if (format != AUDIO_FORMAT_PCM_16_BIT) { 201 ALOGE("Format %#x is not supported", format); 202 return BAD_VALUE; 203 } 204 mFormat = format; 205 206 if (!audio_is_input_channel(channelMask)) { 207 ALOGE("Invalid channel mask %#x", channelMask); 208 return BAD_VALUE; 209 } 210 mChannelMask = channelMask; 211 uint32_t channelCount = popcount(channelMask); 212 mChannelCount = channelCount; 213 214 if (audio_is_linear_pcm(format)) { 215 mFrameSize = channelCount * audio_bytes_per_sample(format); 216 } else { 217 mFrameSize = sizeof(uint8_t); 218 } 219 220 // validate framecount 221 size_t minFrameCount = 0; 222 status_t status = AudioRecord::getMinFrameCount(&minFrameCount, 223 sampleRate, format, channelMask); 224 if (status != NO_ERROR) { 225 ALOGE("getMinFrameCount() failed; status %d", status); 226 return status; 227 } 228 ALOGV("AudioRecord::set() minFrameCount = %d", minFrameCount); 229 230 if (frameCount == 0) { 231 frameCount = minFrameCount; 232 } else if (frameCount < minFrameCount) { 233 ALOGE("frameCount %u < minFrameCount %u", frameCount, minFrameCount); 234 return BAD_VALUE; 235 } 236 // mFrameCount is initialized in openRecord_l 237 mReqFrameCount = frameCount; 238 239 mNotificationFramesReq = notificationFrames; 240 mNotificationFramesAct = 0; 241 242 if (sessionId == AUDIO_SESSION_ALLOCATE) { 243 mSessionId = AudioSystem::newAudioSessionId(); 244 } else { 245 mSessionId = sessionId; 246 } 247 ALOGV("set(): mSessionId %d", mSessionId); 248 249 mFlags = flags; 250 251 // create the IAudioRecord 252 status = openRecord_l(0 /*epoch*/); 253 if (status != NO_ERROR) { 254 return status; 255 } 256 257 if (cbf != NULL) { 258 mAudioRecordThread = new AudioRecordThread(*this, threadCanCallJava); 259 mAudioRecordThread->run("AudioRecord", ANDROID_PRIORITY_AUDIO); 260 } 261 262 mStatus = NO_ERROR; 263 264 mActive = false; 265 mCbf = cbf; 266 mRefreshRemaining = true; 267 mUserData = user; 268 // TODO: add audio hardware input latency here 269 mLatency = (1000*mFrameCount) / sampleRate; 270 mMarkerPosition = 0; 271 mMarkerReached = false; 272 mNewPosition = 0; 273 mUpdatePeriod = 0; 274 AudioSystem::acquireAudioSessionId(mSessionId, -1); 275 mSequence = 1; 276 mObservedSequence = mSequence; 277 mInOverrun = false; 278 279 return NO_ERROR; 280} 281 282// ------------------------------------------------------------------------- 283 284status_t AudioRecord::start(AudioSystem::sync_event_t event, int triggerSession) 285{ 286 ALOGV("start, sync event %d trigger session %d", event, triggerSession); 287 288 AutoMutex lock(mLock); 289 if (mActive) { 290 return NO_ERROR; 291 } 292 293 // reset current position as seen by client to 0 294 mProxy->setEpoch(mProxy->getEpoch() - mProxy->getPosition()); 295 // force refresh of remaining frames by processAudioBuffer() as last 296 // read before stop could be partial. 297 mRefreshRemaining = true; 298 299 mNewPosition = mProxy->getPosition() + mUpdatePeriod; 300 int32_t flags = android_atomic_acquire_load(&mCblk->mFlags); 301 302 status_t status = NO_ERROR; 303 if (!(flags & CBLK_INVALID)) { 304 ALOGV("mAudioRecord->start()"); 305 status = mAudioRecord->start(event, triggerSession); 306 if (status == DEAD_OBJECT) { 307 flags |= CBLK_INVALID; 308 } 309 } 310 if (flags & CBLK_INVALID) { 311 status = restoreRecord_l("start"); 312 } 313 314 if (status != NO_ERROR) { 315 ALOGE("start() status %d", status); 316 } else { 317 mActive = true; 318 sp<AudioRecordThread> t = mAudioRecordThread; 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 } 327 328 return status; 329} 330 331void AudioRecord::stop() 332{ 333 AutoMutex lock(mLock); 334 if (!mActive) { 335 return; 336 } 337 338 mActive = false; 339 mProxy->interrupt(); 340 mAudioRecord->stop(); 341 // the record head position will reset to 0, so if a marker is set, we need 342 // to activate it again 343 mMarkerReached = false; 344 sp<AudioRecordThread> t = mAudioRecordThread; 345 if (t != 0) { 346 t->pause(); 347 } else { 348 setpriority(PRIO_PROCESS, 0, mPreviousPriority); 349 set_sched_policy(0, mPreviousSchedulingGroup); 350 } 351} 352 353bool AudioRecord::stopped() const 354{ 355 AutoMutex lock(mLock); 356 return !mActive; 357} 358 359status_t AudioRecord::setMarkerPosition(uint32_t marker) 360{ 361 // The only purpose of setting marker position is to get a callback 362 if (mCbf == NULL) { 363 return INVALID_OPERATION; 364 } 365 366 AutoMutex lock(mLock); 367 mMarkerPosition = marker; 368 mMarkerReached = false; 369 370 return NO_ERROR; 371} 372 373status_t AudioRecord::getMarkerPosition(uint32_t *marker) const 374{ 375 if (marker == NULL) { 376 return BAD_VALUE; 377 } 378 379 AutoMutex lock(mLock); 380 *marker = mMarkerPosition; 381 382 return NO_ERROR; 383} 384 385status_t AudioRecord::setPositionUpdatePeriod(uint32_t updatePeriod) 386{ 387 // The only purpose of setting position update period is to get a callback 388 if (mCbf == NULL) { 389 return INVALID_OPERATION; 390 } 391 392 AutoMutex lock(mLock); 393 mNewPosition = mProxy->getPosition() + updatePeriod; 394 mUpdatePeriod = updatePeriod; 395 396 return NO_ERROR; 397} 398 399status_t AudioRecord::getPositionUpdatePeriod(uint32_t *updatePeriod) const 400{ 401 if (updatePeriod == NULL) { 402 return BAD_VALUE; 403 } 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) { 414 return BAD_VALUE; 415 } 416 417 AutoMutex lock(mLock); 418 *position = mProxy->getPosition(); 419 420 return NO_ERROR; 421} 422 423uint32_t 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(getInput()); 427} 428 429// ------------------------------------------------------------------------- 430 431// must be called with mLock held 432status_t AudioRecord::openRecord_l(size_t epoch) 433{ 434 status_t status; 435 const sp<IAudioFlinger>& audioFlinger = AudioSystem::get_audio_flinger(); 436 if (audioFlinger == 0) { 437 ALOGE("Could not get audioflinger"); 438 return NO_INIT; 439 } 440 441 IAudioFlinger::track_flags_t trackFlags = IAudioFlinger::TRACK_DEFAULT; 442 pid_t tid = -1; 443 444 // Client can only express a preference for FAST. Server will perform additional tests. 445 // The only supported use case for FAST is callback transfer mode. 446 if (mFlags & AUDIO_INPUT_FLAG_FAST) { 447 if ((mTransfer != TRANSFER_CALLBACK) || (mAudioRecordThread == 0)) { 448 ALOGW("AUDIO_INPUT_FLAG_FAST denied by client"); 449 // once denied, do not request again if IAudioRecord is re-created 450 mFlags = (audio_input_flags_t) (mFlags & ~AUDIO_INPUT_FLAG_FAST); 451 } else { 452 trackFlags |= IAudioFlinger::TRACK_FAST; 453 tid = mAudioRecordThread->getTid(); 454 } 455 } 456 457 mNotificationFramesAct = mNotificationFramesReq; 458 size_t frameCount = mReqFrameCount; 459 460 if (!(mFlags & AUDIO_INPUT_FLAG_FAST)) { 461 // Make sure that application is notified with sufficient margin before overrun 462 if (mNotificationFramesAct == 0 || mNotificationFramesAct > frameCount/2) { 463 mNotificationFramesAct = frameCount/2; 464 } 465 } 466 467 audio_io_handle_t input = AudioSystem::getInput(mInputSource, mSampleRate, mFormat, 468 mChannelMask, mSessionId); 469 if (input == 0) { 470 ALOGE("Could not get audio input for record source %d, sample rate %u, format %#x, " 471 "channel mask %#x, session %d", 472 mInputSource, mSampleRate, mFormat, mChannelMask, mSessionId); 473 return BAD_VALUE; 474 } 475 { 476 // Now that we have a reference to an I/O handle and have not yet handed it off to AudioFlinger, 477 // we must release it ourselves if anything goes wrong. 478 479 size_t temp = frameCount; // temp may be replaced by a revised value of frameCount, 480 // but we will still need the original value also 481 int originalSessionId = mSessionId; 482 sp<IAudioRecord> record = audioFlinger->openRecord(input, 483 mSampleRate, mFormat, 484 mChannelMask, 485 &temp, 486 &trackFlags, 487 tid, 488 &mSessionId, 489 &status); 490 ALOGE_IF(originalSessionId != AUDIO_SESSION_ALLOCATE && mSessionId != originalSessionId, 491 "session ID changed from %d to %d", originalSessionId, mSessionId); 492 493 if (record == 0 || status != NO_ERROR) { 494 ALOGE("AudioFlinger could not create record track, status: %d", status); 495 goto release; 496 } 497 // AudioFlinger now owns the reference to the I/O handle, 498 // so we are no longer responsible for releasing it. 499 500 sp<IMemory> iMem = record->getCblk(); 501 if (iMem == 0) { 502 ALOGE("Could not get control block"); 503 return NO_INIT; 504 } 505 void *iMemPointer = iMem->pointer(); 506 if (iMemPointer == NULL) { 507 ALOGE("Could not get control block pointer"); 508 return NO_INIT; 509 } 510 // invariant that mAudioRecord != 0 is true only after set() returns successfully 511 if (mAudioRecord != 0) { 512 mAudioRecord->asBinder()->unlinkToDeath(mDeathNotifier, this); 513 mDeathNotifier.clear(); 514 } 515 516 // We retain a copy of the I/O handle, but don't own the reference 517 mInput = input; 518 mAudioRecord = record; 519 mCblkMemory = iMem; 520 audio_track_cblk_t* cblk = static_cast<audio_track_cblk_t*>(iMemPointer); 521 mCblk = cblk; 522 // note that temp is the (possibly revised) value of frameCount 523 if (temp < frameCount || (frameCount == 0 && temp == 0)) { 524 ALOGW("Requested frameCount %u but received frameCount %u", frameCount, temp); 525 } 526 frameCount = temp; 527 528 // FIXME missing fast track frameCount logic 529 mAwaitBoost = false; 530 if (mFlags & AUDIO_INPUT_FLAG_FAST) { 531 if (trackFlags & IAudioFlinger::TRACK_FAST) { 532 ALOGV("AUDIO_INPUT_FLAG_FAST successful; frameCount %u", mFrameCount); 533 mAwaitBoost = true; 534 // double-buffering is not required for fast tracks, due to tighter scheduling 535 if (mNotificationFramesAct == 0 || mNotificationFramesAct > mFrameCount) { 536 mNotificationFramesAct = mFrameCount; 537 } 538 } else { 539 ALOGV("AUDIO_INPUT_FLAG_FAST denied by server; frameCount %u", mFrameCount); 540 // once denied, do not request again if IAudioRecord is re-created 541 mFlags = (audio_input_flags_t) (mFlags & ~AUDIO_INPUT_FLAG_FAST); 542 if (mNotificationFramesAct == 0 || mNotificationFramesAct > mFrameCount/2) { 543 mNotificationFramesAct = mFrameCount/2; 544 } 545 } 546 } 547 548 // starting address of buffers in shared memory 549 void *buffers = (char*)cblk + sizeof(audio_track_cblk_t); 550 551 mFrameCount = frameCount; 552 // If IAudioRecord is re-created, don't let the requested frameCount 553 // decrease. This can confuse clients that cache frameCount(). 554 if (frameCount > mReqFrameCount) { 555 mReqFrameCount = frameCount; 556 } 557 558 // update proxy 559 mProxy = new AudioRecordClientProxy(cblk, buffers, mFrameCount, mFrameSize); 560 mProxy->setEpoch(epoch); 561 mProxy->setMinimum(mNotificationFramesAct); 562 563 mDeathNotifier = new DeathNotifier(this); 564 mAudioRecord->asBinder()->linkToDeath(mDeathNotifier, this); 565 566 return NO_ERROR; 567 } 568 569release: 570 AudioSystem::releaseInput(input); 571 if (status == NO_ERROR) { 572 status = NO_INIT; 573 } 574 return status; 575} 576 577status_t AudioRecord::obtainBuffer(Buffer* audioBuffer, int32_t waitCount) 578{ 579 if (audioBuffer == NULL) { 580 return BAD_VALUE; 581 } 582 if (mTransfer != TRANSFER_OBTAIN) { 583 audioBuffer->frameCount = 0; 584 audioBuffer->size = 0; 585 audioBuffer->raw = NULL; 586 return INVALID_OPERATION; 587 } 588 589 const struct timespec *requested; 590 struct timespec timeout; 591 if (waitCount == -1) { 592 requested = &ClientProxy::kForever; 593 } else if (waitCount == 0) { 594 requested = &ClientProxy::kNonBlocking; 595 } else if (waitCount > 0) { 596 long long ms = WAIT_PERIOD_MS * (long long) waitCount; 597 timeout.tv_sec = ms / 1000; 598 timeout.tv_nsec = (int) (ms % 1000) * 1000000; 599 requested = &timeout; 600 } else { 601 ALOGE("%s invalid waitCount %d", __func__, waitCount); 602 requested = NULL; 603 } 604 return obtainBuffer(audioBuffer, requested); 605} 606 607status_t AudioRecord::obtainBuffer(Buffer* audioBuffer, const struct timespec *requested, 608 struct timespec *elapsed, size_t *nonContig) 609{ 610 // previous and new IAudioRecord sequence numbers are used to detect track re-creation 611 uint32_t oldSequence = 0; 612 uint32_t newSequence; 613 614 Proxy::Buffer buffer; 615 status_t status = NO_ERROR; 616 617 static const int32_t kMaxTries = 5; 618 int32_t tryCounter = kMaxTries; 619 620 do { 621 // obtainBuffer() is called with mutex unlocked, so keep extra references to these fields to 622 // keep them from going away if another thread re-creates the track during obtainBuffer() 623 sp<AudioRecordClientProxy> proxy; 624 sp<IMemory> iMem; 625 { 626 // start of lock scope 627 AutoMutex lock(mLock); 628 629 newSequence = mSequence; 630 // did previous obtainBuffer() fail due to media server death or voluntary invalidation? 631 if (status == DEAD_OBJECT) { 632 // re-create track, unless someone else has already done so 633 if (newSequence == oldSequence) { 634 status = restoreRecord_l("obtainBuffer"); 635 if (status != NO_ERROR) { 636 buffer.mFrameCount = 0; 637 buffer.mRaw = NULL; 638 buffer.mNonContig = 0; 639 break; 640 } 641 } 642 } 643 oldSequence = newSequence; 644 645 // Keep the extra references 646 proxy = mProxy; 647 iMem = mCblkMemory; 648 649 // Non-blocking if track is stopped 650 if (!mActive) { 651 requested = &ClientProxy::kNonBlocking; 652 } 653 654 } // end of lock scope 655 656 buffer.mFrameCount = audioBuffer->frameCount; 657 // FIXME starts the requested timeout and elapsed over from scratch 658 status = proxy->obtainBuffer(&buffer, requested, elapsed); 659 660 } while ((status == DEAD_OBJECT) && (tryCounter-- > 0)); 661 662 audioBuffer->frameCount = buffer.mFrameCount; 663 audioBuffer->size = buffer.mFrameCount * mFrameSize; 664 audioBuffer->raw = buffer.mRaw; 665 if (nonContig != NULL) { 666 *nonContig = buffer.mNonContig; 667 } 668 return status; 669} 670 671void AudioRecord::releaseBuffer(Buffer* audioBuffer) 672{ 673 // all TRANSFER_* are valid 674 675 size_t stepCount = audioBuffer->size / mFrameSize; 676 if (stepCount == 0) { 677 return; 678 } 679 680 Proxy::Buffer buffer; 681 buffer.mFrameCount = stepCount; 682 buffer.mRaw = audioBuffer->raw; 683 684 AutoMutex lock(mLock); 685 mInOverrun = false; 686 mProxy->releaseBuffer(&buffer); 687 688 // the server does not automatically disable recorder on overrun, so no need to restart 689} 690 691audio_io_handle_t AudioRecord::getInput() const 692{ 693 AutoMutex lock(mLock); 694 return mInput; 695} 696 697// ------------------------------------------------------------------------- 698 699ssize_t AudioRecord::read(void* buffer, size_t userSize) 700{ 701 if (mTransfer != TRANSFER_SYNC) { 702 return INVALID_OPERATION; 703 } 704 705 if (ssize_t(userSize) < 0 || (buffer == NULL && userSize != 0)) { 706 // sanity-check. user is most-likely passing an error code, and it would 707 // make the return value ambiguous (actualSize vs error). 708 ALOGE("AudioRecord::read(buffer=%p, size=%u (%d)", buffer, userSize, userSize); 709 return BAD_VALUE; 710 } 711 712 ssize_t read = 0; 713 Buffer audioBuffer; 714 715 while (userSize >= mFrameSize) { 716 audioBuffer.frameCount = userSize / mFrameSize; 717 718 status_t err = obtainBuffer(&audioBuffer, &ClientProxy::kForever); 719 if (err < 0) { 720 if (read > 0) { 721 break; 722 } 723 return ssize_t(err); 724 } 725 726 size_t bytesRead = audioBuffer.size; 727 memcpy(buffer, audioBuffer.i8, bytesRead); 728 buffer = ((char *) buffer) + bytesRead; 729 userSize -= bytesRead; 730 read += bytesRead; 731 732 releaseBuffer(&audioBuffer); 733 } 734 735 return read; 736} 737 738// ------------------------------------------------------------------------- 739 740nsecs_t AudioRecord::processAudioBuffer() 741{ 742 mLock.lock(); 743 if (mAwaitBoost) { 744 mAwaitBoost = false; 745 mLock.unlock(); 746 static const int32_t kMaxTries = 5; 747 int32_t tryCounter = kMaxTries; 748 uint32_t pollUs = 10000; 749 do { 750 int policy = sched_getscheduler(0); 751 if (policy == SCHED_FIFO || policy == SCHED_RR) { 752 break; 753 } 754 usleep(pollUs); 755 pollUs <<= 1; 756 } while (tryCounter-- > 0); 757 if (tryCounter < 0) { 758 ALOGE("did not receive expected priority boost on time"); 759 } 760 // Run again immediately 761 return 0; 762 } 763 764 // Can only reference mCblk while locked 765 int32_t flags = android_atomic_and(~CBLK_OVERRUN, &mCblk->mFlags); 766 767 // Check for track invalidation 768 if (flags & CBLK_INVALID) { 769 (void) restoreRecord_l("processAudioBuffer"); 770 mLock.unlock(); 771 // Run again immediately, but with a new IAudioRecord 772 return 0; 773 } 774 775 bool active = mActive; 776 777 // Manage overrun callback, must be done under lock to avoid race with releaseBuffer() 778 bool newOverrun = false; 779 if (flags & CBLK_OVERRUN) { 780 if (!mInOverrun) { 781 mInOverrun = true; 782 newOverrun = true; 783 } 784 } 785 786 // Get current position of server 787 size_t position = mProxy->getPosition(); 788 789 // Manage marker callback 790 bool markerReached = false; 791 size_t markerPosition = mMarkerPosition; 792 // FIXME fails for wraparound, need 64 bits 793 if (!mMarkerReached && (markerPosition > 0) && (position >= markerPosition)) { 794 mMarkerReached = markerReached = true; 795 } 796 797 // Determine the number of new position callback(s) that will be needed, while locked 798 size_t newPosCount = 0; 799 size_t newPosition = mNewPosition; 800 uint32_t updatePeriod = mUpdatePeriod; 801 // FIXME fails for wraparound, need 64 bits 802 if (updatePeriod > 0 && position >= newPosition) { 803 newPosCount = ((position - newPosition) / updatePeriod) + 1; 804 mNewPosition += updatePeriod * newPosCount; 805 } 806 807 // Cache other fields that will be needed soon 808 size_t notificationFrames = mNotificationFramesAct; 809 if (mRefreshRemaining) { 810 mRefreshRemaining = false; 811 mRemainingFrames = notificationFrames; 812 mRetryOnPartialBuffer = false; 813 } 814 size_t misalignment = mProxy->getMisalignment(); 815 uint32_t sequence = mSequence; 816 817 // These fields don't need to be cached, because they are assigned only by set(): 818 // mTransfer, mCbf, mUserData, mSampleRate, mFrameSize 819 820 mLock.unlock(); 821 822 // perform callbacks while unlocked 823 if (newOverrun) { 824 mCbf(EVENT_OVERRUN, mUserData, NULL); 825 } 826 if (markerReached) { 827 mCbf(EVENT_MARKER, mUserData, &markerPosition); 828 } 829 while (newPosCount > 0) { 830 size_t temp = newPosition; 831 mCbf(EVENT_NEW_POS, mUserData, &temp); 832 newPosition += updatePeriod; 833 newPosCount--; 834 } 835 if (mObservedSequence != sequence) { 836 mObservedSequence = sequence; 837 mCbf(EVENT_NEW_IAUDIORECORD, mUserData, NULL); 838 } 839 840 // if inactive, then don't run me again until re-started 841 if (!active) { 842 return NS_INACTIVE; 843 } 844 845 // Compute the estimated time until the next timed event (position, markers) 846 uint32_t minFrames = ~0; 847 if (!markerReached && position < markerPosition) { 848 minFrames = markerPosition - position; 849 } 850 if (updatePeriod > 0 && updatePeriod < minFrames) { 851 minFrames = updatePeriod; 852 } 853 854 // If > 0, poll periodically to recover from a stuck server. A good value is 2. 855 static const uint32_t kPoll = 0; 856 if (kPoll > 0 && mTransfer == TRANSFER_CALLBACK && kPoll * notificationFrames < minFrames) { 857 minFrames = kPoll * notificationFrames; 858 } 859 860 // Convert frame units to time units 861 nsecs_t ns = NS_WHENEVER; 862 if (minFrames != (uint32_t) ~0) { 863 // This "fudge factor" avoids soaking CPU, and compensates for late progress by server 864 static const nsecs_t kFudgeNs = 10000000LL; // 10 ms 865 ns = ((minFrames * 1000000000LL) / mSampleRate) + kFudgeNs; 866 } 867 868 // If not supplying data by EVENT_MORE_DATA, then we're done 869 if (mTransfer != TRANSFER_CALLBACK) { 870 return ns; 871 } 872 873 struct timespec timeout; 874 const struct timespec *requested = &ClientProxy::kForever; 875 if (ns != NS_WHENEVER) { 876 timeout.tv_sec = ns / 1000000000LL; 877 timeout.tv_nsec = ns % 1000000000LL; 878 ALOGV("timeout %ld.%03d", timeout.tv_sec, (int) timeout.tv_nsec / 1000000); 879 requested = &timeout; 880 } 881 882 while (mRemainingFrames > 0) { 883 884 Buffer audioBuffer; 885 audioBuffer.frameCount = mRemainingFrames; 886 size_t nonContig; 887 status_t err = obtainBuffer(&audioBuffer, requested, NULL, &nonContig); 888 LOG_ALWAYS_FATAL_IF((err != NO_ERROR) != (audioBuffer.frameCount == 0), 889 "obtainBuffer() err=%d frameCount=%u", err, audioBuffer.frameCount); 890 requested = &ClientProxy::kNonBlocking; 891 size_t avail = audioBuffer.frameCount + nonContig; 892 ALOGV("obtainBuffer(%u) returned %u = %u + %u err %d", 893 mRemainingFrames, avail, audioBuffer.frameCount, nonContig, err); 894 if (err != NO_ERROR) { 895 if (err == TIMED_OUT || err == WOULD_BLOCK || err == -EINTR) { 896 break; 897 } 898 ALOGE("Error %d obtaining an audio buffer, giving up.", err); 899 return NS_NEVER; 900 } 901 902 if (mRetryOnPartialBuffer) { 903 mRetryOnPartialBuffer = false; 904 if (avail < mRemainingFrames) { 905 int64_t myns = ((mRemainingFrames - avail) * 906 1100000000LL) / mSampleRate; 907 if (ns < 0 || myns < ns) { 908 ns = myns; 909 } 910 return ns; 911 } 912 } 913 914 size_t reqSize = audioBuffer.size; 915 mCbf(EVENT_MORE_DATA, mUserData, &audioBuffer); 916 size_t readSize = audioBuffer.size; 917 918 // Sanity check on returned size 919 if (ssize_t(readSize) < 0 || readSize > reqSize) { 920 ALOGE("EVENT_MORE_DATA requested %u bytes but callback returned %d bytes", 921 reqSize, (int) readSize); 922 return NS_NEVER; 923 } 924 925 if (readSize == 0) { 926 // The callback is done consuming buffers 927 // Keep this thread going to handle timed events and 928 // still try to provide more data in intervals of WAIT_PERIOD_MS 929 // but don't just loop and block the CPU, so wait 930 return WAIT_PERIOD_MS * 1000000LL; 931 } 932 933 size_t releasedFrames = readSize / mFrameSize; 934 audioBuffer.frameCount = releasedFrames; 935 mRemainingFrames -= releasedFrames; 936 if (misalignment >= releasedFrames) { 937 misalignment -= releasedFrames; 938 } else { 939 misalignment = 0; 940 } 941 942 releaseBuffer(&audioBuffer); 943 944 // FIXME here is where we would repeat EVENT_MORE_DATA again on same advanced buffer 945 // if callback doesn't like to accept the full chunk 946 if (readSize < reqSize) { 947 continue; 948 } 949 950 // There could be enough non-contiguous frames available to satisfy the remaining request 951 if (mRemainingFrames <= nonContig) { 952 continue; 953 } 954 955#if 0 956 // This heuristic tries to collapse a series of EVENT_MORE_DATA that would total to a 957 // sum <= notificationFrames. It replaces that series by at most two EVENT_MORE_DATA 958 // that total to a sum == notificationFrames. 959 if (0 < misalignment && misalignment <= mRemainingFrames) { 960 mRemainingFrames = misalignment; 961 return (mRemainingFrames * 1100000000LL) / mSampleRate; 962 } 963#endif 964 965 } 966 mRemainingFrames = notificationFrames; 967 mRetryOnPartialBuffer = true; 968 969 // A lot has transpired since ns was calculated, so run again immediately and re-calculate 970 return 0; 971} 972 973status_t AudioRecord::restoreRecord_l(const char *from) 974{ 975 ALOGW("dead IAudioRecord, creating a new one from %s()", from); 976 ++mSequence; 977 status_t result; 978 979 // if the new IAudioRecord is created, openRecord_l() will modify the 980 // following member variables: mAudioRecord, mCblkMemory and mCblk. 981 // It will also delete the strong references on previous IAudioRecord and IMemory 982 size_t position = mProxy->getPosition(); 983 mNewPosition = position + mUpdatePeriod; 984 result = openRecord_l(position); 985 if (result == NO_ERROR) { 986 if (mActive) { 987 // callback thread or sync event hasn't changed 988 // FIXME this fails if we have a new AudioFlinger instance 989 result = mAudioRecord->start(AudioSystem::SYNC_EVENT_SAME, 0); 990 } 991 } 992 if (result != NO_ERROR) { 993 ALOGW("restoreRecord_l() failed status %d", result); 994 mActive = false; 995 } 996 997 return result; 998} 999 1000// ========================================================================= 1001 1002void AudioRecord::DeathNotifier::binderDied(const wp<IBinder>& who __unused) 1003{ 1004 sp<AudioRecord> audioRecord = mAudioRecord.promote(); 1005 if (audioRecord != 0) { 1006 AutoMutex lock(audioRecord->mLock); 1007 audioRecord->mProxy->binderDied(); 1008 } 1009} 1010 1011// ========================================================================= 1012 1013AudioRecord::AudioRecordThread::AudioRecordThread(AudioRecord& receiver, bool bCanCallJava) 1014 : Thread(bCanCallJava), mReceiver(receiver), mPaused(true), mPausedInt(false), mPausedNs(0LL), 1015 mIgnoreNextPausedInt(false) 1016{ 1017} 1018 1019AudioRecord::AudioRecordThread::~AudioRecordThread() 1020{ 1021} 1022 1023bool AudioRecord::AudioRecordThread::threadLoop() 1024{ 1025 { 1026 AutoMutex _l(mMyLock); 1027 if (mPaused) { 1028 mMyCond.wait(mMyLock); 1029 // caller will check for exitPending() 1030 return true; 1031 } 1032 if (mIgnoreNextPausedInt) { 1033 mIgnoreNextPausedInt = false; 1034 mPausedInt = false; 1035 } 1036 if (mPausedInt) { 1037 if (mPausedNs > 0) { 1038 (void) mMyCond.waitRelative(mMyLock, mPausedNs); 1039 } else { 1040 mMyCond.wait(mMyLock); 1041 } 1042 mPausedInt = false; 1043 return true; 1044 } 1045 } 1046 nsecs_t ns = mReceiver.processAudioBuffer(); 1047 switch (ns) { 1048 case 0: 1049 return true; 1050 case NS_INACTIVE: 1051 pauseInternal(); 1052 return true; 1053 case NS_NEVER: 1054 return false; 1055 case NS_WHENEVER: 1056 // FIXME increase poll interval, or make event-driven 1057 ns = 1000000000LL; 1058 // fall through 1059 default: 1060 LOG_ALWAYS_FATAL_IF(ns < 0, "processAudioBuffer() returned %lld", ns); 1061 pauseInternal(ns); 1062 return true; 1063 } 1064} 1065 1066void AudioRecord::AudioRecordThread::requestExit() 1067{ 1068 // must be in this order to avoid a race condition 1069 Thread::requestExit(); 1070 resume(); 1071} 1072 1073void AudioRecord::AudioRecordThread::pause() 1074{ 1075 AutoMutex _l(mMyLock); 1076 mPaused = true; 1077} 1078 1079void AudioRecord::AudioRecordThread::resume() 1080{ 1081 AutoMutex _l(mMyLock); 1082 mIgnoreNextPausedInt = true; 1083 if (mPaused || mPausedInt) { 1084 mPaused = false; 1085 mPausedInt = false; 1086 mMyCond.signal(); 1087 } 1088} 1089 1090void AudioRecord::AudioRecordThread::pauseInternal(nsecs_t ns) 1091{ 1092 AutoMutex _l(mMyLock); 1093 mPausedInt = true; 1094 mPausedNs = ns; 1095} 1096 1097// ------------------------------------------------------------------------- 1098 1099}; // namespace android 1100