AudioTrack.cpp revision b1cf75c4935001f61057989ee3cf27bbf09ecd9c
1/* frameworks/base/media/libmedia/AudioTrack.cpp 2** 3** Copyright 2007, 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 19//#define LOG_NDEBUG 0 20#define LOG_TAG "AudioTrack" 21 22#include <stdint.h> 23#include <sys/types.h> 24#include <limits.h> 25 26#include <sched.h> 27#include <sys/resource.h> 28 29#include <private/media/AudioTrackShared.h> 30 31#include <media/AudioSystem.h> 32#include <media/AudioTrack.h> 33 34#include <utils/Log.h> 35#include <binder/Parcel.h> 36#include <binder/IPCThreadState.h> 37#include <utils/Timers.h> 38#include <utils/Atomic.h> 39 40#include <cutils/bitops.h> 41#include <cutils/compiler.h> 42 43#include <system/audio.h> 44#include <system/audio_policy.h> 45 46namespace android { 47// --------------------------------------------------------------------------- 48 49// static 50status_t AudioTrack::getMinFrameCount( 51 int* frameCount, 52 audio_stream_type_t streamType, 53 uint32_t sampleRate) 54{ 55 int afSampleRate; 56 if (AudioSystem::getOutputSamplingRate(&afSampleRate, streamType) != NO_ERROR) { 57 return NO_INIT; 58 } 59 int afFrameCount; 60 if (AudioSystem::getOutputFrameCount(&afFrameCount, streamType) != NO_ERROR) { 61 return NO_INIT; 62 } 63 uint32_t afLatency; 64 if (AudioSystem::getOutputLatency(&afLatency, streamType) != NO_ERROR) { 65 return NO_INIT; 66 } 67 68 // Ensure that buffer depth covers at least audio hardware latency 69 uint32_t minBufCount = afLatency / ((1000 * afFrameCount) / afSampleRate); 70 if (minBufCount < 2) minBufCount = 2; 71 72 *frameCount = (sampleRate == 0) ? afFrameCount * minBufCount : 73 afFrameCount * minBufCount * sampleRate / afSampleRate; 74 return NO_ERROR; 75} 76 77// --------------------------------------------------------------------------- 78 79AudioTrack::AudioTrack() 80 : mStatus(NO_INIT), 81 mPreviousPriority(ANDROID_PRIORITY_NORMAL), mPreviousSchedulingGroup(ANDROID_TGROUP_DEFAULT) 82{ 83} 84 85AudioTrack::AudioTrack( 86 audio_stream_type_t streamType, 87 uint32_t sampleRate, 88 audio_format_t format, 89 int channelMask, 90 int frameCount, 91 uint32_t flags, 92 callback_t cbf, 93 void* user, 94 int notificationFrames, 95 int sessionId) 96 : mStatus(NO_INIT), 97 mPreviousPriority(ANDROID_PRIORITY_NORMAL), mPreviousSchedulingGroup(ANDROID_TGROUP_DEFAULT) 98{ 99 mStatus = set(streamType, sampleRate, format, channelMask, 100 frameCount, flags, cbf, user, notificationFrames, 101 0, false, sessionId); 102} 103 104AudioTrack::AudioTrack( 105 audio_stream_type_t streamType, 106 uint32_t sampleRate, 107 audio_format_t format, 108 int channelMask, 109 const sp<IMemory>& sharedBuffer, 110 uint32_t flags, 111 callback_t cbf, 112 void* user, 113 int notificationFrames, 114 int sessionId) 115 : mStatus(NO_INIT), 116 mPreviousPriority(ANDROID_PRIORITY_NORMAL), mPreviousSchedulingGroup(ANDROID_TGROUP_DEFAULT) 117{ 118 mStatus = set(streamType, sampleRate, format, channelMask, 119 0, flags, cbf, user, notificationFrames, 120 sharedBuffer, false, sessionId); 121} 122 123AudioTrack::~AudioTrack() 124{ 125 ALOGV_IF(mSharedBuffer != 0, "Destructor sharedBuffer: %p", mSharedBuffer->pointer()); 126 127 if (mStatus == NO_ERROR) { 128 // Make sure that callback function exits in the case where 129 // it is looping on buffer full condition in obtainBuffer(). 130 // Otherwise the callback thread will never exit. 131 stop(); 132 if (mAudioTrackThread != 0) { 133 mAudioTrackThread->requestExitAndWait(); 134 mAudioTrackThread.clear(); 135 } 136 mAudioTrack.clear(); 137 IPCThreadState::self()->flushCommands(); 138 AudioSystem::releaseAudioSessionId(mSessionId); 139 } 140} 141 142status_t AudioTrack::set( 143 audio_stream_type_t streamType, 144 uint32_t sampleRate, 145 audio_format_t format, 146 int channelMask, 147 int frameCount, 148 uint32_t flags, 149 callback_t cbf, 150 void* user, 151 int notificationFrames, 152 const sp<IMemory>& sharedBuffer, 153 bool threadCanCallJava, 154 int sessionId) 155{ 156 157 ALOGV_IF(sharedBuffer != 0, "sharedBuffer: %p, size: %d", sharedBuffer->pointer(), sharedBuffer->size()); 158 159 AutoMutex lock(mLock); 160 if (mAudioTrack != 0) { 161 ALOGE("Track already in use"); 162 return INVALID_OPERATION; 163 } 164 165 int afSampleRate; 166 if (AudioSystem::getOutputSamplingRate(&afSampleRate, streamType) != NO_ERROR) { 167 return NO_INIT; 168 } 169 uint32_t afLatency; 170 if (AudioSystem::getOutputLatency(&afLatency, streamType) != NO_ERROR) { 171 return NO_INIT; 172 } 173 174 // handle default values first. 175 if (streamType == AUDIO_STREAM_DEFAULT) { 176 streamType = AUDIO_STREAM_MUSIC; 177 } 178 if (sampleRate == 0) { 179 sampleRate = afSampleRate; 180 } 181 // these below should probably come from the audioFlinger too... 182 if (format == AUDIO_FORMAT_DEFAULT) { 183 format = AUDIO_FORMAT_PCM_16_BIT; 184 } 185 if (channelMask == 0) { 186 channelMask = AUDIO_CHANNEL_OUT_STEREO; 187 } 188 189 // validate parameters 190 if (!audio_is_valid_format(format)) { 191 ALOGE("Invalid format"); 192 return BAD_VALUE; 193 } 194 195 // force direct flag if format is not linear PCM 196 if (!audio_is_linear_pcm(format)) { 197 flags |= AUDIO_POLICY_OUTPUT_FLAG_DIRECT; 198 } 199 200 if (!audio_is_output_channel(channelMask)) { 201 ALOGE("Invalid channel mask"); 202 return BAD_VALUE; 203 } 204 uint32_t channelCount = popcount(channelMask); 205 206 audio_io_handle_t output = AudioSystem::getOutput( 207 streamType, 208 sampleRate, format, channelMask, 209 (audio_policy_output_flags_t)flags); 210 211 if (output == 0) { 212 ALOGE("Could not get audio output for stream type %d", streamType); 213 return BAD_VALUE; 214 } 215 216 mVolume[LEFT] = 1.0f; 217 mVolume[RIGHT] = 1.0f; 218 mSendLevel = 0.0f; 219 mFrameCount = frameCount; 220 mNotificationFramesReq = notificationFrames; 221 mSessionId = sessionId; 222 mAuxEffectId = 0; 223 224 // create the IAudioTrack 225 status_t status = createTrack_l(streamType, 226 sampleRate, 227 format, 228 (uint32_t)channelMask, 229 frameCount, 230 flags, 231 sharedBuffer, 232 output, 233 true); 234 235 if (status != NO_ERROR) { 236 return status; 237 } 238 239 if (cbf != 0) { 240 mAudioTrackThread = new AudioTrackThread(*this, threadCanCallJava); 241 } 242 243 mStatus = NO_ERROR; 244 245 mStreamType = streamType; 246 mFormat = format; 247 mChannelMask = (uint32_t)channelMask; 248 mChannelCount = channelCount; 249 mSharedBuffer = sharedBuffer; 250 mMuted = false; 251 mActive = false; 252 mCbf = cbf; 253 mUserData = user; 254 mLoopCount = 0; 255 mMarkerPosition = 0; 256 mMarkerReached = false; 257 mNewPosition = 0; 258 mUpdatePeriod = 0; 259 mFlushed = false; 260 mFlags = flags; 261 AudioSystem::acquireAudioSessionId(mSessionId); 262 mRestoreStatus = NO_ERROR; 263 return NO_ERROR; 264} 265 266status_t AudioTrack::initCheck() const 267{ 268 return mStatus; 269} 270 271// ------------------------------------------------------------------------- 272 273uint32_t AudioTrack::latency() const 274{ 275 return mLatency; 276} 277 278audio_stream_type_t AudioTrack::streamType() const 279{ 280 return mStreamType; 281} 282 283audio_format_t AudioTrack::format() const 284{ 285 return mFormat; 286} 287 288int AudioTrack::channelCount() const 289{ 290 return mChannelCount; 291} 292 293uint32_t AudioTrack::frameCount() const 294{ 295 return mCblk->frameCount; 296} 297 298size_t AudioTrack::frameSize() const 299{ 300 if (audio_is_linear_pcm(mFormat)) { 301 return channelCount()*audio_bytes_per_sample(mFormat); 302 } else { 303 return sizeof(uint8_t); 304 } 305} 306 307sp<IMemory>& AudioTrack::sharedBuffer() 308{ 309 return mSharedBuffer; 310} 311 312// ------------------------------------------------------------------------- 313 314void AudioTrack::start() 315{ 316 sp<AudioTrackThread> t = mAudioTrackThread; 317 status_t status = NO_ERROR; 318 319 ALOGV("start %p", this); 320 if (t != 0) { 321 if (t->exitPending()) { 322 if (t->requestExitAndWait() == WOULD_BLOCK) { 323 ALOGE("AudioTrack::start called from thread"); 324 return; 325 } 326 } 327 t->mLock.lock(); 328 } 329 330 AutoMutex lock(mLock); 331 // acquire a strong reference on the IMemory and IAudioTrack so that they cannot be destroyed 332 // while we are accessing the cblk 333 sp <IAudioTrack> audioTrack = mAudioTrack; 334 sp <IMemory> iMem = mCblkMemory; 335 audio_track_cblk_t* cblk = mCblk; 336 337 if (!mActive) { 338 mFlushed = false; 339 mActive = true; 340 mNewPosition = cblk->server + mUpdatePeriod; 341 cblk->lock.lock(); 342 cblk->bufferTimeoutMs = MAX_STARTUP_TIMEOUT_MS; 343 cblk->waitTimeMs = 0; 344 android_atomic_and(~CBLK_DISABLED_ON, &cblk->flags); 345 if (t != 0) { 346 t->run("AudioTrackThread", ANDROID_PRIORITY_AUDIO); 347 } else { 348 mPreviousPriority = getpriority(PRIO_PROCESS, 0); 349 mPreviousSchedulingGroup = androidGetThreadSchedulingGroup(0); 350 androidSetThreadPriority(0, ANDROID_PRIORITY_AUDIO); 351 } 352 353 ALOGV("start %p before lock cblk %p", this, mCblk); 354 if (!(cblk->flags & CBLK_INVALID_MSK)) { 355 cblk->lock.unlock(); 356 status = mAudioTrack->start(); 357 cblk->lock.lock(); 358 if (status == DEAD_OBJECT) { 359 android_atomic_or(CBLK_INVALID_ON, &cblk->flags); 360 } 361 } 362 if (cblk->flags & CBLK_INVALID_MSK) { 363 status = restoreTrack_l(cblk, true); 364 } 365 cblk->lock.unlock(); 366 if (status != NO_ERROR) { 367 ALOGV("start() failed"); 368 mActive = false; 369 if (t != 0) { 370 t->requestExit(); 371 } else { 372 setpriority(PRIO_PROCESS, 0, mPreviousPriority); 373 androidSetThreadSchedulingGroup(0, mPreviousSchedulingGroup); 374 } 375 } 376 } 377 378 if (t != 0) { 379 t->mLock.unlock(); 380 } 381} 382 383void AudioTrack::stop() 384{ 385 sp<AudioTrackThread> t = mAudioTrackThread; 386 387 ALOGV("stop %p", this); 388 if (t != 0) { 389 t->mLock.lock(); 390 } 391 392 AutoMutex lock(mLock); 393 if (mActive) { 394 mActive = false; 395 mCblk->cv.signal(); 396 mAudioTrack->stop(); 397 // Cancel loops (If we are in the middle of a loop, playback 398 // would not stop until loopCount reaches 0). 399 setLoop_l(0, 0, 0); 400 // the playback head position will reset to 0, so if a marker is set, we need 401 // to activate it again 402 mMarkerReached = false; 403 // Force flush if a shared buffer is used otherwise audioflinger 404 // will not stop before end of buffer is reached. 405 if (mSharedBuffer != 0) { 406 flush_l(); 407 } 408 if (t != 0) { 409 t->requestExit(); 410 } else { 411 setpriority(PRIO_PROCESS, 0, mPreviousPriority); 412 androidSetThreadSchedulingGroup(0, mPreviousSchedulingGroup); 413 } 414 } 415 416 if (t != 0) { 417 t->mLock.unlock(); 418 } 419} 420 421bool AudioTrack::stopped() const 422{ 423 AutoMutex lock(mLock); 424 return stopped_l(); 425} 426 427void AudioTrack::flush() 428{ 429 AutoMutex lock(mLock); 430 flush_l(); 431} 432 433// must be called with mLock held 434void AudioTrack::flush_l() 435{ 436 ALOGV("flush"); 437 438 // clear playback marker and periodic update counter 439 mMarkerPosition = 0; 440 mMarkerReached = false; 441 mUpdatePeriod = 0; 442 443 if (!mActive) { 444 mFlushed = true; 445 mAudioTrack->flush(); 446 // Release AudioTrack callback thread in case it was waiting for new buffers 447 // in AudioTrack::obtainBuffer() 448 mCblk->cv.signal(); 449 } 450} 451 452void AudioTrack::pause() 453{ 454 ALOGV("pause"); 455 AutoMutex lock(mLock); 456 if (mActive) { 457 mActive = false; 458 mAudioTrack->pause(); 459 } 460} 461 462void AudioTrack::mute(bool e) 463{ 464 mAudioTrack->mute(e); 465 mMuted = e; 466} 467 468bool AudioTrack::muted() const 469{ 470 return mMuted; 471} 472 473status_t AudioTrack::setVolume(float left, float right) 474{ 475 if (left < 0.0f || left > 1.0f || right < 0.0f || right > 1.0f) { 476 return BAD_VALUE; 477 } 478 479 AutoMutex lock(mLock); 480 mVolume[LEFT] = left; 481 mVolume[RIGHT] = right; 482 483 mCblk->volumeLR = (uint32_t(uint16_t(right * 0x1000)) << 16) | uint16_t(left * 0x1000); 484 485 return NO_ERROR; 486} 487 488void AudioTrack::getVolume(float* left, float* right) 489{ 490 if (left != NULL) { 491 *left = mVolume[LEFT]; 492 } 493 if (right != NULL) { 494 *right = mVolume[RIGHT]; 495 } 496} 497 498status_t AudioTrack::setAuxEffectSendLevel(float level) 499{ 500 ALOGV("setAuxEffectSendLevel(%f)", level); 501 if (level < 0.0f || level > 1.0f) { 502 return BAD_VALUE; 503 } 504 AutoMutex lock(mLock); 505 506 mSendLevel = level; 507 508 mCblk->setSendLevel(level); 509 510 return NO_ERROR; 511} 512 513void AudioTrack::getAuxEffectSendLevel(float* level) 514{ 515 if (level != NULL) { 516 *level = mSendLevel; 517 } 518} 519 520status_t AudioTrack::setSampleRate(int rate) 521{ 522 int afSamplingRate; 523 524 if (AudioSystem::getOutputSamplingRate(&afSamplingRate, mStreamType) != NO_ERROR) { 525 return NO_INIT; 526 } 527 // Resampler implementation limits input sampling rate to 2 x output sampling rate. 528 if (rate <= 0 || rate > afSamplingRate*2 ) return BAD_VALUE; 529 530 AutoMutex lock(mLock); 531 mCblk->sampleRate = rate; 532 return NO_ERROR; 533} 534 535uint32_t AudioTrack::getSampleRate() 536{ 537 AutoMutex lock(mLock); 538 return mCblk->sampleRate; 539} 540 541status_t AudioTrack::setLoop(uint32_t loopStart, uint32_t loopEnd, int loopCount) 542{ 543 AutoMutex lock(mLock); 544 return setLoop_l(loopStart, loopEnd, loopCount); 545} 546 547// must be called with mLock held 548status_t AudioTrack::setLoop_l(uint32_t loopStart, uint32_t loopEnd, int loopCount) 549{ 550 audio_track_cblk_t* cblk = mCblk; 551 552 Mutex::Autolock _l(cblk->lock); 553 554 if (loopCount == 0) { 555 cblk->loopStart = UINT_MAX; 556 cblk->loopEnd = UINT_MAX; 557 cblk->loopCount = 0; 558 mLoopCount = 0; 559 return NO_ERROR; 560 } 561 562 if (loopStart >= loopEnd || 563 loopEnd - loopStart > cblk->frameCount || 564 cblk->server > loopStart) { 565 ALOGE("setLoop invalid value: loopStart %d, loopEnd %d, loopCount %d, framecount %d, user %d", loopStart, loopEnd, loopCount, cblk->frameCount, cblk->user); 566 return BAD_VALUE; 567 } 568 569 if ((mSharedBuffer != 0) && (loopEnd > cblk->frameCount)) { 570 ALOGE("setLoop invalid value: loop markers beyond data: loopStart %d, loopEnd %d, framecount %d", 571 loopStart, loopEnd, cblk->frameCount); 572 return BAD_VALUE; 573 } 574 575 cblk->loopStart = loopStart; 576 cblk->loopEnd = loopEnd; 577 cblk->loopCount = loopCount; 578 mLoopCount = loopCount; 579 580 return NO_ERROR; 581} 582 583status_t AudioTrack::getLoop(uint32_t *loopStart, uint32_t *loopEnd, int *loopCount) 584{ 585 AutoMutex lock(mLock); 586 if (loopStart != 0) { 587 *loopStart = mCblk->loopStart; 588 } 589 if (loopEnd != 0) { 590 *loopEnd = mCblk->loopEnd; 591 } 592 if (loopCount != 0) { 593 if (mCblk->loopCount < 0) { 594 *loopCount = -1; 595 } else { 596 *loopCount = mCblk->loopCount; 597 } 598 } 599 600 return NO_ERROR; 601} 602 603status_t AudioTrack::setMarkerPosition(uint32_t marker) 604{ 605 if (mCbf == 0) return INVALID_OPERATION; 606 607 mMarkerPosition = marker; 608 mMarkerReached = false; 609 610 return NO_ERROR; 611} 612 613status_t AudioTrack::getMarkerPosition(uint32_t *marker) 614{ 615 if (marker == 0) return BAD_VALUE; 616 617 *marker = mMarkerPosition; 618 619 return NO_ERROR; 620} 621 622status_t AudioTrack::setPositionUpdatePeriod(uint32_t updatePeriod) 623{ 624 if (mCbf == 0) return INVALID_OPERATION; 625 626 uint32_t curPosition; 627 getPosition(&curPosition); 628 mNewPosition = curPosition + updatePeriod; 629 mUpdatePeriod = updatePeriod; 630 631 return NO_ERROR; 632} 633 634status_t AudioTrack::getPositionUpdatePeriod(uint32_t *updatePeriod) 635{ 636 if (updatePeriod == 0) return BAD_VALUE; 637 638 *updatePeriod = mUpdatePeriod; 639 640 return NO_ERROR; 641} 642 643status_t AudioTrack::setPosition(uint32_t position) 644{ 645 AutoMutex lock(mLock); 646 647 if (!stopped_l()) return INVALID_OPERATION; 648 649 Mutex::Autolock _l(mCblk->lock); 650 651 if (position > mCblk->user) return BAD_VALUE; 652 653 mCblk->server = position; 654 android_atomic_or(CBLK_FORCEREADY_ON, &mCblk->flags); 655 656 return NO_ERROR; 657} 658 659status_t AudioTrack::getPosition(uint32_t *position) 660{ 661 if (position == 0) return BAD_VALUE; 662 AutoMutex lock(mLock); 663 *position = mFlushed ? 0 : mCblk->server; 664 665 return NO_ERROR; 666} 667 668status_t AudioTrack::reload() 669{ 670 AutoMutex lock(mLock); 671 672 if (!stopped_l()) return INVALID_OPERATION; 673 674 flush_l(); 675 676 mCblk->stepUser(mCblk->frameCount); 677 678 return NO_ERROR; 679} 680 681audio_io_handle_t AudioTrack::getOutput() 682{ 683 AutoMutex lock(mLock); 684 return getOutput_l(); 685} 686 687// must be called with mLock held 688audio_io_handle_t AudioTrack::getOutput_l() 689{ 690 return AudioSystem::getOutput(mStreamType, 691 mCblk->sampleRate, mFormat, mChannelMask, (audio_policy_output_flags_t)mFlags); 692} 693 694int AudioTrack::getSessionId() 695{ 696 return mSessionId; 697} 698 699status_t AudioTrack::attachAuxEffect(int effectId) 700{ 701 ALOGV("attachAuxEffect(%d)", effectId); 702 status_t status = mAudioTrack->attachAuxEffect(effectId); 703 if (status == NO_ERROR) { 704 mAuxEffectId = effectId; 705 } 706 return status; 707} 708 709// ------------------------------------------------------------------------- 710 711// must be called with mLock held 712status_t AudioTrack::createTrack_l( 713 audio_stream_type_t streamType, 714 uint32_t sampleRate, 715 audio_format_t format, 716 uint32_t channelMask, 717 int frameCount, 718 uint32_t flags, 719 const sp<IMemory>& sharedBuffer, 720 audio_io_handle_t output, 721 bool enforceFrameCount) 722{ 723 status_t status; 724 const sp<IAudioFlinger>& audioFlinger = AudioSystem::get_audio_flinger(); 725 if (audioFlinger == 0) { 726 ALOGE("Could not get audioflinger"); 727 return NO_INIT; 728 } 729 730 int afSampleRate; 731 if (AudioSystem::getOutputSamplingRate(&afSampleRate, streamType) != NO_ERROR) { 732 return NO_INIT; 733 } 734 int afFrameCount; 735 if (AudioSystem::getOutputFrameCount(&afFrameCount, streamType) != NO_ERROR) { 736 return NO_INIT; 737 } 738 uint32_t afLatency; 739 if (AudioSystem::getOutputLatency(&afLatency, streamType) != NO_ERROR) { 740 return NO_INIT; 741 } 742 743 mNotificationFramesAct = mNotificationFramesReq; 744 if (!audio_is_linear_pcm(format)) { 745 if (sharedBuffer != 0) { 746 frameCount = sharedBuffer->size(); 747 } 748 } else { 749 // Ensure that buffer depth covers at least audio hardware latency 750 uint32_t minBufCount = afLatency / ((1000 * afFrameCount)/afSampleRate); 751 if (minBufCount < 2) minBufCount = 2; 752 753 int minFrameCount = (afFrameCount*sampleRate*minBufCount)/afSampleRate; 754 755 if (sharedBuffer == 0) { 756 if (frameCount == 0) { 757 frameCount = minFrameCount; 758 } 759 if (mNotificationFramesAct == 0) { 760 mNotificationFramesAct = frameCount/2; 761 } 762 // Make sure that application is notified with sufficient margin 763 // before underrun 764 if (mNotificationFramesAct > (uint32_t)frameCount/2) { 765 mNotificationFramesAct = frameCount/2; 766 } 767 if (frameCount < minFrameCount) { 768 if (enforceFrameCount) { 769 ALOGE("Invalid buffer size: minFrameCount %d, frameCount %d", minFrameCount, frameCount); 770 return BAD_VALUE; 771 } else { 772 frameCount = minFrameCount; 773 } 774 } 775 } else { 776 // Ensure that buffer alignment matches channelcount 777 int channelCount = popcount(channelMask); 778 if (((uint32_t)sharedBuffer->pointer() & (channelCount | 1)) != 0) { 779 ALOGE("Invalid buffer alignement: address %p, channelCount %d", sharedBuffer->pointer(), channelCount); 780 return BAD_VALUE; 781 } 782 frameCount = sharedBuffer->size()/channelCount/sizeof(int16_t); 783 } 784 } 785 786 sp<IAudioTrack> track = audioFlinger->createTrack(getpid(), 787 streamType, 788 sampleRate, 789 format, 790 channelMask, 791 frameCount, 792 ((uint16_t)flags) << 16, 793 sharedBuffer, 794 output, 795 &mSessionId, 796 &status); 797 798 if (track == 0) { 799 ALOGE("AudioFlinger could not create track, status: %d", status); 800 return status; 801 } 802 sp<IMemory> cblk = track->getCblk(); 803 if (cblk == 0) { 804 ALOGE("Could not get control block"); 805 return NO_INIT; 806 } 807 mAudioTrack = track; 808 mCblkMemory = cblk; 809 mCblk = static_cast<audio_track_cblk_t*>(cblk->pointer()); 810 android_atomic_or(CBLK_DIRECTION_OUT, &mCblk->flags); 811 if (sharedBuffer == 0) { 812 mCblk->buffers = (char*)mCblk + sizeof(audio_track_cblk_t); 813 } else { 814 mCblk->buffers = sharedBuffer->pointer(); 815 // Force buffer full condition as data is already present in shared memory 816 mCblk->stepUser(mCblk->frameCount); 817 } 818 819 mCblk->volumeLR = (uint32_t(uint16_t(mVolume[RIGHT] * 0x1000)) << 16) | uint16_t(mVolume[LEFT] * 0x1000); 820 mCblk->setSendLevel(mSendLevel); 821 mAudioTrack->attachAuxEffect(mAuxEffectId); 822 mCblk->bufferTimeoutMs = MAX_STARTUP_TIMEOUT_MS; 823 mCblk->waitTimeMs = 0; 824 mRemainingFrames = mNotificationFramesAct; 825 mLatency = afLatency + (1000*mCblk->frameCount) / sampleRate; 826 return NO_ERROR; 827} 828 829status_t AudioTrack::obtainBuffer(Buffer* audioBuffer, int32_t waitCount) 830{ 831 AutoMutex lock(mLock); 832 bool active; 833 status_t result = NO_ERROR; 834 audio_track_cblk_t* cblk = mCblk; 835 uint32_t framesReq = audioBuffer->frameCount; 836 uint32_t waitTimeMs = (waitCount < 0) ? cblk->bufferTimeoutMs : WAIT_PERIOD_MS; 837 838 audioBuffer->frameCount = 0; 839 audioBuffer->size = 0; 840 841 uint32_t framesAvail = cblk->framesAvailable(); 842 843 cblk->lock.lock(); 844 if (cblk->flags & CBLK_INVALID_MSK) { 845 goto create_new_track; 846 } 847 cblk->lock.unlock(); 848 849 if (framesAvail == 0) { 850 cblk->lock.lock(); 851 goto start_loop_here; 852 while (framesAvail == 0) { 853 active = mActive; 854 if (CC_UNLIKELY(!active)) { 855 ALOGV("Not active and NO_MORE_BUFFERS"); 856 cblk->lock.unlock(); 857 return NO_MORE_BUFFERS; 858 } 859 if (CC_UNLIKELY(!waitCount)) { 860 cblk->lock.unlock(); 861 return WOULD_BLOCK; 862 } 863 if (!(cblk->flags & CBLK_INVALID_MSK)) { 864 mLock.unlock(); 865 result = cblk->cv.waitRelative(cblk->lock, milliseconds(waitTimeMs)); 866 cblk->lock.unlock(); 867 mLock.lock(); 868 if (!mActive) { 869 return status_t(STOPPED); 870 } 871 cblk->lock.lock(); 872 } 873 874 if (cblk->flags & CBLK_INVALID_MSK) { 875 goto create_new_track; 876 } 877 if (CC_UNLIKELY(result != NO_ERROR)) { 878 cblk->waitTimeMs += waitTimeMs; 879 if (cblk->waitTimeMs >= cblk->bufferTimeoutMs) { 880 // timing out when a loop has been set and we have already written upto loop end 881 // is a normal condition: no need to wake AudioFlinger up. 882 if (cblk->user < cblk->loopEnd) { 883 ALOGW( "obtainBuffer timed out (is the CPU pegged?) %p " 884 "user=%08x, server=%08x", this, cblk->user, cblk->server); 885 //unlock cblk mutex before calling mAudioTrack->start() (see issue #1617140) 886 cblk->lock.unlock(); 887 result = mAudioTrack->start(); 888 cblk->lock.lock(); 889 if (result == DEAD_OBJECT) { 890 android_atomic_or(CBLK_INVALID_ON, &cblk->flags); 891create_new_track: 892 result = restoreTrack_l(cblk, false); 893 } 894 if (result != NO_ERROR) { 895 ALOGW("obtainBuffer create Track error %d", result); 896 cblk->lock.unlock(); 897 return result; 898 } 899 } 900 cblk->waitTimeMs = 0; 901 } 902 903 if (--waitCount == 0) { 904 cblk->lock.unlock(); 905 return TIMED_OUT; 906 } 907 } 908 // read the server count again 909 start_loop_here: 910 framesAvail = cblk->framesAvailable_l(); 911 } 912 cblk->lock.unlock(); 913 } 914 915 // restart track if it was disabled by audioflinger due to previous underrun 916 if (mActive && (cblk->flags & CBLK_DISABLED_MSK)) { 917 android_atomic_and(~CBLK_DISABLED_ON, &cblk->flags); 918 ALOGW("obtainBuffer() track %p disabled, restarting", this); 919 mAudioTrack->start(); 920 } 921 922 cblk->waitTimeMs = 0; 923 924 if (framesReq > framesAvail) { 925 framesReq = framesAvail; 926 } 927 928 uint32_t u = cblk->user; 929 uint32_t bufferEnd = cblk->userBase + cblk->frameCount; 930 931 if (u + framesReq > bufferEnd) { 932 framesReq = bufferEnd - u; 933 } 934 935 audioBuffer->flags = mMuted ? Buffer::MUTE : 0; 936 audioBuffer->channelCount = mChannelCount; 937 audioBuffer->frameCount = framesReq; 938 audioBuffer->size = framesReq * cblk->frameSize; 939 if (audio_is_linear_pcm(mFormat)) { 940 audioBuffer->format = AUDIO_FORMAT_PCM_16_BIT; 941 } else { 942 audioBuffer->format = mFormat; 943 } 944 audioBuffer->raw = (int8_t *)cblk->buffer(u); 945 active = mActive; 946 return active ? status_t(NO_ERROR) : status_t(STOPPED); 947} 948 949void AudioTrack::releaseBuffer(Buffer* audioBuffer) 950{ 951 AutoMutex lock(mLock); 952 mCblk->stepUser(audioBuffer->frameCount); 953} 954 955// ------------------------------------------------------------------------- 956 957ssize_t AudioTrack::write(const void* buffer, size_t userSize) 958{ 959 960 if (mSharedBuffer != 0) return INVALID_OPERATION; 961 962 if (ssize_t(userSize) < 0) { 963 // sanity-check. user is most-likely passing an error code. 964 ALOGE("AudioTrack::write(buffer=%p, size=%u (%d)", 965 buffer, userSize, userSize); 966 return BAD_VALUE; 967 } 968 969 ALOGV("write %p: %d bytes, mActive=%d", this, userSize, mActive); 970 971 // acquire a strong reference on the IMemory and IAudioTrack so that they cannot be destroyed 972 // while we are accessing the cblk 973 mLock.lock(); 974 sp <IAudioTrack> audioTrack = mAudioTrack; 975 sp <IMemory> iMem = mCblkMemory; 976 mLock.unlock(); 977 978 ssize_t written = 0; 979 const int8_t *src = (const int8_t *)buffer; 980 Buffer audioBuffer; 981 size_t frameSz = frameSize(); 982 983 do { 984 audioBuffer.frameCount = userSize/frameSz; 985 986 // Calling obtainBuffer() with a negative wait count causes 987 // an (almost) infinite wait time. 988 status_t err = obtainBuffer(&audioBuffer, -1); 989 if (err < 0) { 990 // out of buffers, return #bytes written 991 if (err == status_t(NO_MORE_BUFFERS)) 992 break; 993 return ssize_t(err); 994 } 995 996 size_t toWrite; 997 998 if (mFormat == AUDIO_FORMAT_PCM_8_BIT && !(mFlags & AUDIO_POLICY_OUTPUT_FLAG_DIRECT)) { 999 // Divide capacity by 2 to take expansion into account 1000 toWrite = audioBuffer.size>>1; 1001 // 8 to 16 bit conversion 1002 int count = toWrite; 1003 int16_t *dst = (int16_t *)(audioBuffer.i8); 1004 while(count--) { 1005 *dst++ = (int16_t)(*src++^0x80) << 8; 1006 } 1007 } else { 1008 toWrite = audioBuffer.size; 1009 memcpy(audioBuffer.i8, src, toWrite); 1010 src += toWrite; 1011 } 1012 userSize -= toWrite; 1013 written += toWrite; 1014 1015 releaseBuffer(&audioBuffer); 1016 } while (userSize >= frameSz); 1017 1018 return written; 1019} 1020 1021// ------------------------------------------------------------------------- 1022 1023bool AudioTrack::processAudioBuffer(const sp<AudioTrackThread>& thread) 1024{ 1025 Buffer audioBuffer; 1026 uint32_t frames; 1027 size_t writtenSize; 1028 1029 mLock.lock(); 1030 // acquire a strong reference on the IMemory and IAudioTrack so that they cannot be destroyed 1031 // while we are accessing the cblk 1032 sp <IAudioTrack> audioTrack = mAudioTrack; 1033 sp <IMemory> iMem = mCblkMemory; 1034 audio_track_cblk_t* cblk = mCblk; 1035 bool active = mActive; 1036 mLock.unlock(); 1037 1038 // Manage underrun callback 1039 if (active && (cblk->framesAvailable() == cblk->frameCount)) { 1040 ALOGV("Underrun user: %x, server: %x, flags %04x", cblk->user, cblk->server, cblk->flags); 1041 if (!(android_atomic_or(CBLK_UNDERRUN_ON, &cblk->flags) & CBLK_UNDERRUN_MSK)) { 1042 mCbf(EVENT_UNDERRUN, mUserData, 0); 1043 if (cblk->server == cblk->frameCount) { 1044 mCbf(EVENT_BUFFER_END, mUserData, 0); 1045 } 1046 if (mSharedBuffer != 0) return false; 1047 } 1048 } 1049 1050 // Manage loop end callback 1051 while (mLoopCount > cblk->loopCount) { 1052 int loopCount = -1; 1053 mLoopCount--; 1054 if (mLoopCount >= 0) loopCount = mLoopCount; 1055 1056 mCbf(EVENT_LOOP_END, mUserData, (void *)&loopCount); 1057 } 1058 1059 // Manage marker callback 1060 if (!mMarkerReached && (mMarkerPosition > 0)) { 1061 if (cblk->server >= mMarkerPosition) { 1062 mCbf(EVENT_MARKER, mUserData, (void *)&mMarkerPosition); 1063 mMarkerReached = true; 1064 } 1065 } 1066 1067 // Manage new position callback 1068 if (mUpdatePeriod > 0) { 1069 while (cblk->server >= mNewPosition) { 1070 mCbf(EVENT_NEW_POS, mUserData, (void *)&mNewPosition); 1071 mNewPosition += mUpdatePeriod; 1072 } 1073 } 1074 1075 // If Shared buffer is used, no data is requested from client. 1076 if (mSharedBuffer != 0) { 1077 frames = 0; 1078 } else { 1079 frames = mRemainingFrames; 1080 } 1081 1082 int32_t waitCount = -1; 1083 if (mUpdatePeriod || (!mMarkerReached && mMarkerPosition) || mLoopCount) { 1084 waitCount = 1; 1085 } 1086 1087 do { 1088 1089 audioBuffer.frameCount = frames; 1090 1091 // Calling obtainBuffer() with a wait count of 1 1092 // limits wait time to WAIT_PERIOD_MS. This prevents from being 1093 // stuck here not being able to handle timed events (position, markers, loops). 1094 status_t err = obtainBuffer(&audioBuffer, waitCount); 1095 if (err < NO_ERROR) { 1096 if (err != TIMED_OUT) { 1097 ALOGE_IF(err != status_t(NO_MORE_BUFFERS), "Error obtaining an audio buffer, giving up."); 1098 return false; 1099 } 1100 break; 1101 } 1102 if (err == status_t(STOPPED)) return false; 1103 1104 // Divide buffer size by 2 to take into account the expansion 1105 // due to 8 to 16 bit conversion: the callback must fill only half 1106 // of the destination buffer 1107 if (mFormat == AUDIO_FORMAT_PCM_8_BIT && !(mFlags & AUDIO_POLICY_OUTPUT_FLAG_DIRECT)) { 1108 audioBuffer.size >>= 1; 1109 } 1110 1111 size_t reqSize = audioBuffer.size; 1112 mCbf(EVENT_MORE_DATA, mUserData, &audioBuffer); 1113 writtenSize = audioBuffer.size; 1114 1115 // Sanity check on returned size 1116 if (ssize_t(writtenSize) <= 0) { 1117 // The callback is done filling buffers 1118 // Keep this thread going to handle timed events and 1119 // still try to get more data in intervals of WAIT_PERIOD_MS 1120 // but don't just loop and block the CPU, so wait 1121 usleep(WAIT_PERIOD_MS*1000); 1122 break; 1123 } 1124 if (writtenSize > reqSize) writtenSize = reqSize; 1125 1126 if (mFormat == AUDIO_FORMAT_PCM_8_BIT && !(mFlags & AUDIO_POLICY_OUTPUT_FLAG_DIRECT)) { 1127 // 8 to 16 bit conversion 1128 const int8_t *src = audioBuffer.i8 + writtenSize-1; 1129 int count = writtenSize; 1130 int16_t *dst = audioBuffer.i16 + writtenSize-1; 1131 while(count--) { 1132 *dst-- = (int16_t)(*src--^0x80) << 8; 1133 } 1134 writtenSize <<= 1; 1135 } 1136 1137 audioBuffer.size = writtenSize; 1138 // NOTE: mCblk->frameSize is not equal to AudioTrack::frameSize() for 1139 // 8 bit PCM data: in this case, mCblk->frameSize is based on a sample size of 1140 // 16 bit. 1141 audioBuffer.frameCount = writtenSize/mCblk->frameSize; 1142 1143 frames -= audioBuffer.frameCount; 1144 1145 releaseBuffer(&audioBuffer); 1146 } 1147 while (frames); 1148 1149 if (frames == 0) { 1150 mRemainingFrames = mNotificationFramesAct; 1151 } else { 1152 mRemainingFrames = frames; 1153 } 1154 return true; 1155} 1156 1157// must be called with mLock and cblk.lock held. Callers must also hold strong references on 1158// the IAudioTrack and IMemory in case they are recreated here. 1159// If the IAudioTrack is successfully restored, the cblk pointer is updated 1160status_t AudioTrack::restoreTrack_l(audio_track_cblk_t*& cblk, bool fromStart) 1161{ 1162 status_t result; 1163 1164 if (!(android_atomic_or(CBLK_RESTORING_ON, &cblk->flags) & CBLK_RESTORING_MSK)) { 1165 ALOGW("dead IAudioTrack, creating a new one from %s TID %d", 1166 fromStart ? "start()" : "obtainBuffer()", gettid()); 1167 1168 // signal old cblk condition so that other threads waiting for available buffers stop 1169 // waiting now 1170 cblk->cv.broadcast(); 1171 cblk->lock.unlock(); 1172 1173 // refresh the audio configuration cache in this process to make sure we get new 1174 // output parameters in getOutput_l() and createTrack_l() 1175 AudioSystem::clearAudioConfigCache(); 1176 1177 // if the new IAudioTrack is created, createTrack_l() will modify the 1178 // following member variables: mAudioTrack, mCblkMemory and mCblk. 1179 // It will also delete the strong references on previous IAudioTrack and IMemory 1180 result = createTrack_l(mStreamType, 1181 cblk->sampleRate, 1182 mFormat, 1183 mChannelMask, 1184 mFrameCount, 1185 mFlags, 1186 mSharedBuffer, 1187 getOutput_l(), 1188 false); 1189 1190 if (result == NO_ERROR) { 1191 uint32_t user = cblk->user; 1192 uint32_t server = cblk->server; 1193 // restore write index and set other indexes to reflect empty buffer status 1194 mCblk->user = user; 1195 mCblk->server = user; 1196 mCblk->userBase = user; 1197 mCblk->serverBase = user; 1198 // restore loop: this is not guaranteed to succeed if new frame count is not 1199 // compatible with loop length 1200 setLoop_l(cblk->loopStart, cblk->loopEnd, cblk->loopCount); 1201 if (!fromStart) { 1202 mCblk->bufferTimeoutMs = MAX_RUN_TIMEOUT_MS; 1203 // Make sure that a client relying on callback events indicating underrun or 1204 // the actual amount of audio frames played (e.g SoundPool) receives them. 1205 if (mSharedBuffer == 0) { 1206 uint32_t frames = 0; 1207 if (user > server) { 1208 frames = ((user - server) > mCblk->frameCount) ? 1209 mCblk->frameCount : (user - server); 1210 memset(mCblk->buffers, 0, frames * mCblk->frameSize); 1211 } 1212 // restart playback even if buffer is not completely filled. 1213 android_atomic_or(CBLK_FORCEREADY_ON, &mCblk->flags); 1214 // stepUser() clears CBLK_UNDERRUN_ON flag enabling underrun callbacks to 1215 // the client 1216 mCblk->stepUser(frames); 1217 } 1218 } 1219 if (mActive) { 1220 result = mAudioTrack->start(); 1221 ALOGW_IF(result != NO_ERROR, "restoreTrack_l() start() failed status %d", result); 1222 } 1223 if (fromStart && result == NO_ERROR) { 1224 mNewPosition = mCblk->server + mUpdatePeriod; 1225 } 1226 } 1227 if (result != NO_ERROR) { 1228 android_atomic_and(~CBLK_RESTORING_ON, &cblk->flags); 1229 ALOGW_IF(result != NO_ERROR, "restoreTrack_l() failed status %d", result); 1230 } 1231 mRestoreStatus = result; 1232 // signal old cblk condition for other threads waiting for restore completion 1233 android_atomic_or(CBLK_RESTORED_ON, &cblk->flags); 1234 cblk->cv.broadcast(); 1235 } else { 1236 if (!(cblk->flags & CBLK_RESTORED_MSK)) { 1237 ALOGW("dead IAudioTrack, waiting for a new one TID %d", gettid()); 1238 mLock.unlock(); 1239 result = cblk->cv.waitRelative(cblk->lock, milliseconds(RESTORE_TIMEOUT_MS)); 1240 if (result == NO_ERROR) { 1241 result = mRestoreStatus; 1242 } 1243 cblk->lock.unlock(); 1244 mLock.lock(); 1245 } else { 1246 ALOGW("dead IAudioTrack, already restored TID %d", gettid()); 1247 result = mRestoreStatus; 1248 cblk->lock.unlock(); 1249 } 1250 } 1251 ALOGV("restoreTrack_l() status %d mActive %d cblk %p, old cblk %p flags %08x old flags %08x", 1252 result, mActive, mCblk, cblk, mCblk->flags, cblk->flags); 1253 1254 if (result == NO_ERROR) { 1255 // from now on we switch to the newly created cblk 1256 cblk = mCblk; 1257 } 1258 cblk->lock.lock(); 1259 1260 ALOGW_IF(result != NO_ERROR, "restoreTrack_l() error %d TID %d", result, gettid()); 1261 1262 return result; 1263} 1264 1265status_t AudioTrack::dump(int fd, const Vector<String16>& args) const 1266{ 1267 1268 const size_t SIZE = 256; 1269 char buffer[SIZE]; 1270 String8 result; 1271 1272 result.append(" AudioTrack::dump\n"); 1273 snprintf(buffer, 255, " stream type(%d), left - right volume(%f, %f)\n", mStreamType, mVolume[0], mVolume[1]); 1274 result.append(buffer); 1275 snprintf(buffer, 255, " format(%d), channel count(%d), frame count(%d)\n", mFormat, mChannelCount, mCblk->frameCount); 1276 result.append(buffer); 1277 snprintf(buffer, 255, " sample rate(%d), status(%d), muted(%d)\n", (mCblk == 0) ? 0 : mCblk->sampleRate, mStatus, mMuted); 1278 result.append(buffer); 1279 snprintf(buffer, 255, " active(%d), latency (%d)\n", mActive, mLatency); 1280 result.append(buffer); 1281 ::write(fd, result.string(), result.size()); 1282 return NO_ERROR; 1283} 1284 1285// ========================================================================= 1286 1287AudioTrack::AudioTrackThread::AudioTrackThread(AudioTrack& receiver, bool bCanCallJava) 1288 : Thread(bCanCallJava), mReceiver(receiver) 1289{ 1290} 1291 1292bool AudioTrack::AudioTrackThread::threadLoop() 1293{ 1294 return mReceiver.processAudioBuffer(this); 1295} 1296 1297status_t AudioTrack::AudioTrackThread::readyToRun() 1298{ 1299 return NO_ERROR; 1300} 1301 1302void AudioTrack::AudioTrackThread::onFirstRef() 1303{ 1304} 1305 1306// ========================================================================= 1307 1308 1309audio_track_cblk_t::audio_track_cblk_t() 1310 : lock(Mutex::SHARED), cv(Condition::SHARED), user(0), server(0), 1311 userBase(0), serverBase(0), buffers(0), frameCount(0), 1312 loopStart(UINT_MAX), loopEnd(UINT_MAX), loopCount(0), volumeLR(0), 1313 mSendLevel(0), flags(0) 1314{ 1315} 1316 1317uint32_t audio_track_cblk_t::stepUser(uint32_t frameCount) 1318{ 1319 uint32_t u = user; 1320 1321 u += frameCount; 1322 // Ensure that user is never ahead of server for AudioRecord 1323 if (flags & CBLK_DIRECTION_MSK) { 1324 // If stepServer() has been called once, switch to normal obtainBuffer() timeout period 1325 if (bufferTimeoutMs == MAX_STARTUP_TIMEOUT_MS-1) { 1326 bufferTimeoutMs = MAX_RUN_TIMEOUT_MS; 1327 } 1328 } else if (u > server) { 1329 ALOGW("stepServer occurred after track reset"); 1330 u = server; 1331 } 1332 1333 if (u >= userBase + this->frameCount) { 1334 userBase += this->frameCount; 1335 } 1336 1337 user = u; 1338 1339 // Clear flow control error condition as new data has been written/read to/from buffer. 1340 if (flags & CBLK_UNDERRUN_MSK) { 1341 android_atomic_and(~CBLK_UNDERRUN_MSK, &flags); 1342 } 1343 1344 return u; 1345} 1346 1347bool audio_track_cblk_t::stepServer(uint32_t frameCount) 1348{ 1349 if (!tryLock()) { 1350 ALOGW("stepServer() could not lock cblk"); 1351 return false; 1352 } 1353 1354 uint32_t s = server; 1355 1356 s += frameCount; 1357 if (flags & CBLK_DIRECTION_MSK) { 1358 // Mark that we have read the first buffer so that next time stepUser() is called 1359 // we switch to normal obtainBuffer() timeout period 1360 if (bufferTimeoutMs == MAX_STARTUP_TIMEOUT_MS) { 1361 bufferTimeoutMs = MAX_STARTUP_TIMEOUT_MS - 1; 1362 } 1363 // It is possible that we receive a flush() 1364 // while the mixer is processing a block: in this case, 1365 // stepServer() is called After the flush() has reset u & s and 1366 // we have s > u 1367 if (s > user) { 1368 ALOGW("stepServer occurred after track reset"); 1369 s = user; 1370 } 1371 } 1372 1373 if (s >= loopEnd) { 1374 ALOGW_IF(s > loopEnd, "stepServer: s %u > loopEnd %u", s, loopEnd); 1375 s = loopStart; 1376 if (--loopCount == 0) { 1377 loopEnd = UINT_MAX; 1378 loopStart = UINT_MAX; 1379 } 1380 } 1381 if (s >= serverBase + this->frameCount) { 1382 serverBase += this->frameCount; 1383 } 1384 1385 server = s; 1386 1387 if (!(flags & CBLK_INVALID_MSK)) { 1388 cv.signal(); 1389 } 1390 lock.unlock(); 1391 return true; 1392} 1393 1394void* audio_track_cblk_t::buffer(uint32_t offset) const 1395{ 1396 return (int8_t *)buffers + (offset - userBase) * frameSize; 1397} 1398 1399uint32_t audio_track_cblk_t::framesAvailable() 1400{ 1401 Mutex::Autolock _l(lock); 1402 return framesAvailable_l(); 1403} 1404 1405uint32_t audio_track_cblk_t::framesAvailable_l() 1406{ 1407 uint32_t u = user; 1408 uint32_t s = server; 1409 1410 if (flags & CBLK_DIRECTION_MSK) { 1411 uint32_t limit = (s < loopStart) ? s : loopStart; 1412 return limit + frameCount - u; 1413 } else { 1414 return frameCount + u - s; 1415 } 1416} 1417 1418uint32_t audio_track_cblk_t::framesReady() 1419{ 1420 uint32_t u = user; 1421 uint32_t s = server; 1422 1423 if (flags & CBLK_DIRECTION_MSK) { 1424 if (u < loopEnd) { 1425 return u - s; 1426 } else { 1427 // do not block on mutex shared with client on AudioFlinger side 1428 if (!tryLock()) { 1429 ALOGW("framesReady() could not lock cblk"); 1430 return 0; 1431 } 1432 uint32_t frames = UINT_MAX; 1433 if (loopCount >= 0) { 1434 frames = (loopEnd - loopStart)*loopCount + u - s; 1435 } 1436 lock.unlock(); 1437 return frames; 1438 } 1439 } else { 1440 return s - u; 1441 } 1442} 1443 1444bool audio_track_cblk_t::tryLock() 1445{ 1446 // the code below simulates lock-with-timeout 1447 // we MUST do this to protect the AudioFlinger server 1448 // as this lock is shared with the client. 1449 status_t err; 1450 1451 err = lock.tryLock(); 1452 if (err == -EBUSY) { // just wait a bit 1453 usleep(1000); 1454 err = lock.tryLock(); 1455 } 1456 if (err != NO_ERROR) { 1457 // probably, the client just died. 1458 return false; 1459 } 1460 return true; 1461} 1462 1463// ------------------------------------------------------------------------- 1464 1465}; // namespace android 1466