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