AudioTrack.cpp revision 25658fd43d150a45fb37734a9f9f27f48bb5c133
1/* //device/extlibs/pv/android/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 <utils/MemoryDealer.h> 36#include <utils/Parcel.h> 37#include <utils/IPCThreadState.h> 38#include <utils/Timers.h> 39#include <cutils/atomic.h> 40 41#define LIKELY( exp ) (__builtin_expect( (exp) != 0, true )) 42#define UNLIKELY( exp ) (__builtin_expect( (exp) != 0, false )) 43 44namespace android { 45 46// --------------------------------------------------------------------------- 47 48AudioTrack::AudioTrack() 49 : mStatus(NO_INIT) 50{ 51} 52 53AudioTrack::AudioTrack( 54 int streamType, 55 uint32_t sampleRate, 56 int format, 57 int channelCount, 58 int frameCount, 59 uint32_t flags, 60 callback_t cbf, 61 void* user, 62 int notificationFrames) 63 : mStatus(NO_INIT) 64{ 65 mStatus = set(streamType, sampleRate, format, channelCount, 66 frameCount, flags, cbf, user, notificationFrames, 0); 67} 68 69AudioTrack::AudioTrack( 70 int streamType, 71 uint32_t sampleRate, 72 int format, 73 int channelCount, 74 const sp<IMemory>& sharedBuffer, 75 uint32_t flags, 76 callback_t cbf, 77 void* user, 78 int notificationFrames) 79 : mStatus(NO_INIT) 80{ 81 mStatus = set(streamType, sampleRate, format, channelCount, 82 0, flags, cbf, user, notificationFrames, sharedBuffer); 83} 84 85AudioTrack::~AudioTrack() 86{ 87 LOGV_IF(mSharedBuffer != 0, "Destructor sharedBuffer: %p", mSharedBuffer->pointer()); 88 89 if (mStatus == NO_ERROR) { 90 // Make sure that callback function exits in the case where 91 // it is looping on buffer full condition in obtainBuffer(). 92 // Otherwise the callback thread will never exit. 93 stop(); 94 if (mAudioTrackThread != 0) { 95 mCblk->cv.signal(); 96 mAudioTrackThread->requestExitAndWait(); 97 mAudioTrackThread.clear(); 98 } 99 mAudioTrack.clear(); 100 IPCThreadState::self()->flushCommands(); 101 } 102} 103 104status_t AudioTrack::set( 105 int streamType, 106 uint32_t sampleRate, 107 int format, 108 int channelCount, 109 int frameCount, 110 uint32_t flags, 111 callback_t cbf, 112 void* user, 113 int notificationFrames, 114 const sp<IMemory>& sharedBuffer, 115 bool threadCanCallJava) 116{ 117 118 LOGV_IF(sharedBuffer != 0, "sharedBuffer: %p, size: %d", sharedBuffer->pointer(), sharedBuffer->size()); 119 120 if (mAudioFlinger != 0) { 121 LOGE("Track already in use"); 122 return INVALID_OPERATION; 123 } 124 125 const sp<IAudioFlinger>& audioFlinger = AudioSystem::get_audio_flinger(); 126 if (audioFlinger == 0) { 127 LOGE("Could not get audioflinger"); 128 return NO_INIT; 129 } 130 int afSampleRate; 131 if (AudioSystem::getOutputSamplingRate(&afSampleRate, streamType) != NO_ERROR) { 132 return NO_INIT; 133 } 134 int afFrameCount; 135 if (AudioSystem::getOutputFrameCount(&afFrameCount, streamType) != NO_ERROR) { 136 return NO_INIT; 137 } 138 uint32_t afLatency; 139 if (AudioSystem::getOutputLatency(&afLatency, streamType) != NO_ERROR) { 140 return NO_INIT; 141 } 142 143 // handle default values first. 144 if (streamType == AudioSystem::DEFAULT) { 145 streamType = AudioSystem::MUSIC; 146 } 147 if (sampleRate == 0) { 148 sampleRate = afSampleRate; 149 } 150 // these below should probably come from the audioFlinger too... 151 if (format == 0) { 152 format = AudioSystem::PCM_16_BIT; 153 } 154 if (channelCount == 0) { 155 channelCount = 2; 156 } 157 158 // validate parameters 159 if (((format != AudioSystem::PCM_8_BIT) || sharedBuffer != 0) && 160 (format != AudioSystem::PCM_16_BIT)) { 161 LOGE("Invalid format"); 162 return BAD_VALUE; 163 } 164 if (channelCount != 1 && channelCount != 2) { 165 LOGE("Invalid channel number"); 166 return BAD_VALUE; 167 } 168 169 // Ensure that buffer depth covers at least audio hardware latency 170 uint32_t minBufCount = afLatency / ((1000 * afFrameCount)/afSampleRate); 171 // When playing from shared buffer, playback will start even if last audioflinger 172 // block is partly filled. 173 if (sharedBuffer != 0 && minBufCount > 1) { 174 minBufCount--; 175 } 176 177 int minFrameCount = (afFrameCount*sampleRate*minBufCount)/afSampleRate; 178 179 if (sharedBuffer == 0) { 180 if (frameCount == 0) { 181 frameCount = minFrameCount; 182 } 183 if (notificationFrames == 0) { 184 notificationFrames = frameCount/2; 185 } 186 // Make sure that application is notified with sufficient margin 187 // before underrun 188 if (notificationFrames > frameCount/2) { 189 notificationFrames = frameCount/2; 190 } 191 } else { 192 // Ensure that buffer alignment matches channelcount 193 if (((uint32_t)sharedBuffer->pointer() & (channelCount | 1)) != 0) { 194 LOGE("Invalid buffer alignement: address %p, channelCount %d", sharedBuffer->pointer(), channelCount); 195 return BAD_VALUE; 196 } 197 frameCount = sharedBuffer->size()/channelCount/sizeof(int16_t); 198 } 199 200 if (frameCount < minFrameCount) { 201 LOGE("Invalid buffer size: minFrameCount %d, frameCount %d", minFrameCount, frameCount); 202 return BAD_VALUE; 203 } 204 205 // create the track 206 status_t status; 207 sp<IAudioTrack> track = audioFlinger->createTrack(getpid(), 208 streamType, sampleRate, format, channelCount, frameCount, flags, sharedBuffer, &status); 209 210 if (track == 0) { 211 LOGE("AudioFlinger could not create track, status: %d", status); 212 return status; 213 } 214 sp<IMemory> cblk = track->getCblk(); 215 if (cblk == 0) { 216 LOGE("Could not get control block"); 217 return NO_INIT; 218 } 219 if (cbf != 0) { 220 mAudioTrackThread = new AudioTrackThread(*this, threadCanCallJava); 221 if (mAudioTrackThread == 0) { 222 LOGE("Could not create callback thread"); 223 return NO_INIT; 224 } 225 } 226 227 mStatus = NO_ERROR; 228 229 mAudioFlinger = audioFlinger; 230 mAudioTrack = track; 231 mCblkMemory = cblk; 232 mCblk = static_cast<audio_track_cblk_t*>(cblk->pointer()); 233 mCblk->out = 1; 234 // Update buffer size in case it has been limited by AudioFlinger during track creation 235 mFrameCount = mCblk->frameCount; 236 if (sharedBuffer == 0) { 237 mCblk->buffers = (char*)mCblk + sizeof(audio_track_cblk_t); 238 } else { 239 mCblk->buffers = sharedBuffer->pointer(); 240 // Force buffer full condition as data is already present in shared memory 241 mCblk->stepUser(mFrameCount); 242 } 243 mCblk->volume[0] = mCblk->volume[1] = 0x1000; 244 mVolume[LEFT] = 1.0f; 245 mVolume[RIGHT] = 1.0f; 246 mSampleRate = sampleRate; 247 mStreamType = streamType; 248 mFormat = format; 249 mChannelCount = channelCount; 250 mSharedBuffer = sharedBuffer; 251 mMuted = false; 252 mActive = 0; 253 mCbf = cbf; 254 mNotificationFrames = notificationFrames; 255 mRemainingFrames = notificationFrames; 256 mUserData = user; 257 mLatency = afLatency + (1000*mFrameCount) / mSampleRate; 258 mLoopCount = 0; 259 mMarkerPosition = 0; 260 mNewPosition = 0; 261 mUpdatePeriod = 0; 262 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 278int AudioTrack::streamType() const 279{ 280 return mStreamType; 281} 282 283uint32_t AudioTrack::sampleRate() const 284{ 285 return mSampleRate; 286} 287 288int AudioTrack::format() const 289{ 290 return mFormat; 291} 292 293int AudioTrack::channelCount() const 294{ 295 return mChannelCount; 296} 297 298uint32_t AudioTrack::frameCount() const 299{ 300 return mFrameCount; 301} 302 303int AudioTrack::frameSize() const 304{ 305 return channelCount()*((format() == AudioSystem::PCM_8_BIT) ? sizeof(uint8_t) : sizeof(int16_t)); 306} 307 308sp<IMemory>& AudioTrack::sharedBuffer() 309{ 310 return mSharedBuffer; 311} 312 313// ------------------------------------------------------------------------- 314 315void AudioTrack::start() 316{ 317 sp<AudioTrackThread> t = mAudioTrackThread; 318 319 LOGV("start"); 320 if (t != 0) { 321 if (t->exitPending()) { 322 if (t->requestExitAndWait() == WOULD_BLOCK) { 323 LOGE("AudioTrack::start called from thread"); 324 return; 325 } 326 } 327 t->mLock.lock(); 328 } 329 330 if (android_atomic_or(1, &mActive) == 0) { 331 mNewPosition = mCblk->server + mUpdatePeriod; 332 mCblk->bufferTimeoutMs = MAX_STARTUP_TIMEOUT_MS; 333 mCblk->waitTimeMs = 0; 334 if (t != 0) { 335 t->run("AudioTrackThread", THREAD_PRIORITY_AUDIO_CLIENT); 336 } else { 337 setpriority(PRIO_PROCESS, 0, THREAD_PRIORITY_AUDIO_CLIENT); 338 } 339 mAudioTrack->start(); 340 } 341 342 if (t != 0) { 343 t->mLock.unlock(); 344 } 345} 346 347void AudioTrack::stop() 348{ 349 sp<AudioTrackThread> t = mAudioTrackThread; 350 351 LOGV("stop"); 352 if (t != 0) { 353 t->mLock.lock(); 354 } 355 356 if (android_atomic_and(~1, &mActive) == 1) { 357 mAudioTrack->stop(); 358 // Cancel loops (If we are in the middle of a loop, playback 359 // would not stop until loopCount reaches 0). 360 setLoop(0, 0, 0); 361 // Force flush if a shared buffer is used otherwise audioflinger 362 // will not stop before end of buffer is reached. 363 if (mSharedBuffer != 0) { 364 flush(); 365 } 366 if (t != 0) { 367 t->requestExit(); 368 } else { 369 setpriority(PRIO_PROCESS, 0, ANDROID_PRIORITY_NORMAL); 370 } 371 } 372 373 if (t != 0) { 374 t->mLock.unlock(); 375 } 376} 377 378bool AudioTrack::stopped() const 379{ 380 return !mActive; 381} 382 383void AudioTrack::flush() 384{ 385 LOGV("flush"); 386 387 if (!mActive) { 388 mCblk->lock.lock(); 389 mAudioTrack->flush(); 390 // Release AudioTrack callback thread in case it was waiting for new buffers 391 // in AudioTrack::obtainBuffer() 392 mCblk->cv.signal(); 393 mCblk->lock.unlock(); 394 } 395} 396 397void AudioTrack::pause() 398{ 399 LOGV("pause"); 400 if (android_atomic_and(~1, &mActive) == 1) { 401 mActive = 0; 402 mAudioTrack->pause(); 403 } 404} 405 406void AudioTrack::mute(bool e) 407{ 408 mAudioTrack->mute(e); 409 mMuted = e; 410} 411 412bool AudioTrack::muted() const 413{ 414 return mMuted; 415} 416 417void AudioTrack::setVolume(float left, float right) 418{ 419 mVolume[LEFT] = left; 420 mVolume[RIGHT] = right; 421 422 // write must be atomic 423 mCblk->volumeLR = (int32_t(int16_t(left * 0x1000)) << 16) | int16_t(right * 0x1000); 424} 425 426void AudioTrack::getVolume(float* left, float* right) 427{ 428 *left = mVolume[LEFT]; 429 *right = mVolume[RIGHT]; 430} 431 432void AudioTrack::setSampleRate(int rate) 433{ 434 int afSamplingRate; 435 436 if (AudioSystem::getOutputSamplingRate(&afSamplingRate, mStreamType) != NO_ERROR) { 437 return; 438 } 439 // Resampler implementation limits input sampling rate to 2 x output sampling rate. 440 if (rate > afSamplingRate*2) rate = afSamplingRate*2; 441 442 if (rate > MAX_SAMPLE_RATE) rate = MAX_SAMPLE_RATE; 443 444 mCblk->sampleRate = rate; 445} 446 447uint32_t AudioTrack::getSampleRate() 448{ 449 return uint32_t(mCblk->sampleRate); 450} 451 452status_t AudioTrack::setLoop(uint32_t loopStart, uint32_t loopEnd, int loopCount) 453{ 454 audio_track_cblk_t* cblk = mCblk; 455 456 457 Mutex::Autolock _l(cblk->lock); 458 459 if (loopCount == 0) { 460 cblk->loopStart = UINT_MAX; 461 cblk->loopEnd = UINT_MAX; 462 cblk->loopCount = 0; 463 mLoopCount = 0; 464 return NO_ERROR; 465 } 466 467 if (loopStart >= loopEnd || 468 loopEnd - loopStart > mFrameCount) { 469 LOGW("setLoop invalid value: loopStart %d, loopEnd %d, loopCount %d, framecount %d, user %d", loopStart, loopEnd, loopCount, mFrameCount, cblk->user); 470 return BAD_VALUE; 471 } 472 // TODO handle shared buffer here: limit loop end to framecount 473 474 cblk->loopStart = loopStart; 475 cblk->loopEnd = loopEnd; 476 cblk->loopCount = loopCount; 477 mLoopCount = loopCount; 478 479 return NO_ERROR; 480} 481 482status_t AudioTrack::getLoop(uint32_t *loopStart, uint32_t *loopEnd, int *loopCount) 483{ 484 if (loopStart != 0) { 485 *loopStart = mCblk->loopStart; 486 } 487 if (loopEnd != 0) { 488 *loopEnd = mCblk->loopEnd; 489 } 490 if (loopCount != 0) { 491 if (mCblk->loopCount < 0) { 492 *loopCount = -1; 493 } else { 494 *loopCount = mCblk->loopCount; 495 } 496 } 497 498 return NO_ERROR; 499} 500 501status_t AudioTrack::setMarkerPosition(uint32_t marker) 502{ 503 if (mCbf == 0) return INVALID_OPERATION; 504 505 mMarkerPosition = marker; 506 507 return NO_ERROR; 508} 509 510status_t AudioTrack::getMarkerPosition(uint32_t *marker) 511{ 512 if (marker == 0) return BAD_VALUE; 513 514 *marker = mMarkerPosition; 515 516 return NO_ERROR; 517} 518 519status_t AudioTrack::setPositionUpdatePeriod(uint32_t updatePeriod) 520{ 521 if (mCbf == 0) return INVALID_OPERATION; 522 523 uint32_t curPosition; 524 getPosition(&curPosition); 525 mNewPosition = curPosition + updatePeriod; 526 mUpdatePeriod = updatePeriod; 527 528 return NO_ERROR; 529} 530 531status_t AudioTrack::getPositionUpdatePeriod(uint32_t *updatePeriod) 532{ 533 if (updatePeriod == 0) return BAD_VALUE; 534 535 *updatePeriod = mUpdatePeriod; 536 537 return NO_ERROR; 538} 539 540status_t AudioTrack::setPosition(uint32_t position) 541{ 542 Mutex::Autolock _l(mCblk->lock); 543 544 if (!stopped()) return INVALID_OPERATION; 545 546 if (position > mCblk->user) return BAD_VALUE; 547 548 mCblk->server = position; 549 mCblk->forceReady = 1; 550 551 return NO_ERROR; 552} 553 554status_t AudioTrack::getPosition(uint32_t *position) 555{ 556 if (position == 0) return BAD_VALUE; 557 558 *position = mCblk->server; 559 560 return NO_ERROR; 561} 562 563status_t AudioTrack::reload() 564{ 565 if (!stopped()) return INVALID_OPERATION; 566 567 flush(); 568 569 mCblk->stepUser(mFrameCount); 570 571 return NO_ERROR; 572} 573 574// ------------------------------------------------------------------------- 575 576status_t AudioTrack::obtainBuffer(Buffer* audioBuffer, int32_t waitCount) 577{ 578 int active; 579 int timeout = 0; 580 status_t result; 581 audio_track_cblk_t* cblk = mCblk; 582 uint32_t framesReq = audioBuffer->frameCount; 583 584 audioBuffer->frameCount = 0; 585 audioBuffer->size = 0; 586 587 uint32_t framesAvail = cblk->framesAvailable(); 588 589 if (framesAvail == 0) { 590 Mutex::Autolock _l(cblk->lock); 591 goto start_loop_here; 592 while (framesAvail == 0) { 593 active = mActive; 594 if (UNLIKELY(!active)) { 595 LOGV("Not active and NO_MORE_BUFFERS"); 596 return NO_MORE_BUFFERS; 597 } 598 if (UNLIKELY(!waitCount)) 599 return WOULD_BLOCK; 600 timeout = 0; 601 result = cblk->cv.waitRelative(cblk->lock, milliseconds(WAIT_PERIOD_MS)); 602 if (__builtin_expect(result!=NO_ERROR, false)) { 603 cblk->waitTimeMs += WAIT_PERIOD_MS; 604 if (cblk->waitTimeMs >= cblk->bufferTimeoutMs) { 605 // timing out when a loop has been set and we have already written upto loop end 606 // is a normal condition: no need to wake AudioFlinger up. 607 if (cblk->user < cblk->loopEnd) { 608 LOGW( "obtainBuffer timed out (is the CPU pegged?) " 609 "user=%08x, server=%08x", cblk->user, cblk->server); 610 mAudioFlinger->wakeUp(); 611 timeout = 1; 612 } 613 cblk->waitTimeMs = 0; 614 } 615 616 if (--waitCount == 0) { 617 return TIMED_OUT; 618 } 619 } 620 // read the server count again 621 start_loop_here: 622 framesAvail = cblk->framesAvailable_l(); 623 } 624 } 625 626 cblk->waitTimeMs = 0; 627 628 if (framesReq > framesAvail) { 629 framesReq = framesAvail; 630 } 631 632 uint32_t u = cblk->user; 633 uint32_t bufferEnd = cblk->userBase + cblk->frameCount; 634 635 if (u + framesReq > bufferEnd) { 636 framesReq = bufferEnd - u; 637 } 638 639 LOGW_IF(timeout, 640 "*** SERIOUS WARNING *** obtainBuffer() timed out " 641 "but didn't need to be locked. We recovered, but " 642 "this shouldn't happen (user=%08x, server=%08x)", cblk->user, cblk->server); 643 644 audioBuffer->flags = mMuted ? Buffer::MUTE : 0; 645 audioBuffer->channelCount= mChannelCount; 646 audioBuffer->format = AudioSystem::PCM_16_BIT; 647 audioBuffer->frameCount = framesReq; 648 audioBuffer->size = framesReq*mChannelCount*sizeof(int16_t); 649 audioBuffer->raw = (int8_t *)cblk->buffer(u); 650 active = mActive; 651 return active ? status_t(NO_ERROR) : status_t(STOPPED); 652} 653 654void AudioTrack::releaseBuffer(Buffer* audioBuffer) 655{ 656 audio_track_cblk_t* cblk = mCblk; 657 cblk->stepUser(audioBuffer->frameCount); 658} 659 660// ------------------------------------------------------------------------- 661 662ssize_t AudioTrack::write(const void* buffer, size_t userSize) 663{ 664 665 if (mSharedBuffer != 0) return INVALID_OPERATION; 666 667 if (ssize_t(userSize) < 0) { 668 // sanity-check. user is most-likely passing an error code. 669 LOGE("AudioTrack::write(buffer=%p, size=%u (%d)", 670 buffer, userSize, userSize); 671 return BAD_VALUE; 672 } 673 674 LOGV("write %d bytes, mActive=%d", userSize, mActive); 675 676 ssize_t written = 0; 677 const int8_t *src = (const int8_t *)buffer; 678 Buffer audioBuffer; 679 680 do { 681 audioBuffer.frameCount = userSize/mChannelCount; 682 if (mFormat == AudioSystem::PCM_16_BIT) { 683 audioBuffer.frameCount >>= 1; 684 } 685 // Calling obtainBuffer() with a negative wait count causes 686 // an (almost) infinite wait time. 687 status_t err = obtainBuffer(&audioBuffer, -1); 688 if (err < 0) { 689 // out of buffers, return #bytes written 690 if (err == status_t(NO_MORE_BUFFERS)) 691 break; 692 return ssize_t(err); 693 } 694 695 size_t toWrite; 696 if (mFormat == AudioSystem::PCM_8_BIT) { 697 // Divide capacity by 2 to take expansion into account 698 toWrite = audioBuffer.size>>1; 699 // 8 to 16 bit conversion 700 int count = toWrite; 701 int16_t *dst = (int16_t *)(audioBuffer.i8); 702 while(count--) { 703 *dst++ = (int16_t)(*src++^0x80) << 8; 704 } 705 }else { 706 toWrite = audioBuffer.size; 707 memcpy(audioBuffer.i8, src, toWrite); 708 src += toWrite; 709 } 710 userSize -= toWrite; 711 written += toWrite; 712 713 releaseBuffer(&audioBuffer); 714 } while (userSize); 715 716 return written; 717} 718 719// ------------------------------------------------------------------------- 720 721bool AudioTrack::processAudioBuffer(const sp<AudioTrackThread>& thread) 722{ 723 Buffer audioBuffer; 724 uint32_t frames; 725 size_t writtenSize; 726 727 // Manage underrun callback 728 if (mActive && (mCblk->framesReady() == 0)) { 729 LOGV("Underrun user: %x, server: %x, flowControlFlag %d", mCblk->user, mCblk->server, mCblk->flowControlFlag); 730 if (mCblk->flowControlFlag == 0) { 731 mCbf(EVENT_UNDERRUN, mUserData, 0); 732 if (mCblk->server == mCblk->frameCount) { 733 mCbf(EVENT_BUFFER_END, mUserData, 0); 734 } 735 mCblk->flowControlFlag = 1; 736 if (mSharedBuffer != 0) return false; 737 } 738 } 739 740 // Manage loop end callback 741 while (mLoopCount > mCblk->loopCount) { 742 int loopCount = -1; 743 mLoopCount--; 744 if (mLoopCount >= 0) loopCount = mLoopCount; 745 746 mCbf(EVENT_LOOP_END, mUserData, (void *)&loopCount); 747 } 748 749 // Manage marker callback 750 if(mMarkerPosition > 0) { 751 if (mCblk->server >= mMarkerPosition) { 752 mCbf(EVENT_MARKER, mUserData, (void *)&mMarkerPosition); 753 mMarkerPosition = 0; 754 } 755 } 756 757 // Manage new position callback 758 if(mUpdatePeriod > 0) { 759 while (mCblk->server >= mNewPosition) { 760 mCbf(EVENT_NEW_POS, mUserData, (void *)&mNewPosition); 761 mNewPosition += mUpdatePeriod; 762 } 763 } 764 765 // If Shared buffer is used, no data is requested from client. 766 if (mSharedBuffer != 0) { 767 frames = 0; 768 } else { 769 frames = mRemainingFrames; 770 } 771 772 do { 773 774 audioBuffer.frameCount = frames; 775 776 // Calling obtainBuffer() with a wait count of 1 777 // limits wait time to WAIT_PERIOD_MS. This prevents from being 778 // stuck here not being able to handle timed events (position, markers, loops). 779 status_t err = obtainBuffer(&audioBuffer, 1); 780 if (err < NO_ERROR) { 781 if (err != TIMED_OUT) { 782 LOGE("Error obtaining an audio buffer, giving up."); 783 return false; 784 } 785 break; 786 } 787 if (err == status_t(STOPPED)) return false; 788 789 // Divide buffer size by 2 to take into account the expansion 790 // due to 8 to 16 bit conversion: the callback must fill only half 791 // of the destination buffer 792 if (mFormat == AudioSystem::PCM_8_BIT) { 793 audioBuffer.size >>= 1; 794 } 795 796 size_t reqSize = audioBuffer.size; 797 mCbf(EVENT_MORE_DATA, mUserData, &audioBuffer); 798 writtenSize = audioBuffer.size; 799 800 // Sanity check on returned size 801 if (ssize_t(writtenSize) <= 0) break; 802 if (writtenSize > reqSize) writtenSize = reqSize; 803 804 if (mFormat == AudioSystem::PCM_8_BIT) { 805 // 8 to 16 bit conversion 806 const int8_t *src = audioBuffer.i8 + writtenSize-1; 807 int count = writtenSize; 808 int16_t *dst = audioBuffer.i16 + writtenSize-1; 809 while(count--) { 810 *dst-- = (int16_t)(*src--^0x80) << 8; 811 } 812 writtenSize <<= 1; 813 } 814 815 audioBuffer.size = writtenSize; 816 audioBuffer.frameCount = writtenSize/mChannelCount/sizeof(int16_t); 817 frames -= audioBuffer.frameCount; 818 819 releaseBuffer(&audioBuffer); 820 } 821 while (frames); 822 823 if (frames == 0) { 824 mRemainingFrames = mNotificationFrames; 825 } else { 826 mRemainingFrames = frames; 827 } 828 return true; 829} 830 831status_t AudioTrack::dump(int fd, const Vector<String16>& args) const 832{ 833 834 const size_t SIZE = 256; 835 char buffer[SIZE]; 836 String8 result; 837 838 result.append(" AudioTrack::dump\n"); 839 snprintf(buffer, 255, " stream type(%d), left - right volume(%f, %f)\n", mStreamType, mVolume[0], mVolume[1]); 840 result.append(buffer); 841 snprintf(buffer, 255, " format(%d), channel count(%d), frame count(%d)\n", mFormat, mChannelCount, mFrameCount); 842 result.append(buffer); 843 snprintf(buffer, 255, " sample rate(%d), status(%d), muted(%d)\n", mSampleRate, mStatus, mMuted); 844 result.append(buffer); 845 snprintf(buffer, 255, " active(%d), latency (%d)\n", mActive, mLatency); 846 result.append(buffer); 847 ::write(fd, result.string(), result.size()); 848 return NO_ERROR; 849} 850 851// ========================================================================= 852 853AudioTrack::AudioTrackThread::AudioTrackThread(AudioTrack& receiver, bool bCanCallJava) 854 : Thread(bCanCallJava), mReceiver(receiver) 855{ 856} 857 858bool AudioTrack::AudioTrackThread::threadLoop() 859{ 860 return mReceiver.processAudioBuffer(this); 861} 862 863status_t AudioTrack::AudioTrackThread::readyToRun() 864{ 865 return NO_ERROR; 866} 867 868void AudioTrack::AudioTrackThread::onFirstRef() 869{ 870} 871 872// ========================================================================= 873 874audio_track_cblk_t::audio_track_cblk_t() 875 : user(0), server(0), userBase(0), serverBase(0), buffers(0), frameCount(0), 876 loopStart(UINT_MAX), loopEnd(UINT_MAX), loopCount(0), volumeLR(0), flowControlFlag(1), forceReady(0) 877{ 878} 879 880uint32_t audio_track_cblk_t::stepUser(uint32_t frameCount) 881{ 882 uint32_t u = this->user; 883 884 u += frameCount; 885 // Ensure that user is never ahead of server for AudioRecord 886 if (out) { 887 // If stepServer() has been called once, switch to normal obtainBuffer() timeout period 888 if (bufferTimeoutMs == MAX_STARTUP_TIMEOUT_MS-1) { 889 bufferTimeoutMs = MAX_RUN_TIMEOUT_MS; 890 } 891 } else if (u > this->server) { 892 LOGW("stepServer occured after track reset"); 893 u = this->server; 894 } 895 896 if (u >= userBase + this->frameCount) { 897 userBase += this->frameCount; 898 } 899 900 this->user = u; 901 902 // Clear flow control error condition as new data has been written/read to/from buffer. 903 flowControlFlag = 0; 904 905 return u; 906} 907 908bool audio_track_cblk_t::stepServer(uint32_t frameCount) 909{ 910 // the code below simulates lock-with-timeout 911 // we MUST do this to protect the AudioFlinger server 912 // as this lock is shared with the client. 913 status_t err; 914 915 err = lock.tryLock(); 916 if (err == -EBUSY) { // just wait a bit 917 usleep(1000); 918 err = lock.tryLock(); 919 } 920 if (err != NO_ERROR) { 921 // probably, the client just died. 922 return false; 923 } 924 925 uint32_t s = this->server; 926 927 s += frameCount; 928 if (out) { 929 // Mark that we have read the first buffer so that next time stepUser() is called 930 // we switch to normal obtainBuffer() timeout period 931 if (bufferTimeoutMs == MAX_STARTUP_TIMEOUT_MS) { 932 bufferTimeoutMs = MAX_RUN_TIMEOUT_MS - 1; 933 } 934 // It is possible that we receive a flush() 935 // while the mixer is processing a block: in this case, 936 // stepServer() is called After the flush() has reset u & s and 937 // we have s > u 938 if (s > this->user) { 939 LOGW("stepServer occured after track reset"); 940 s = this->user; 941 } 942 } 943 944 if (s >= loopEnd) { 945 LOGW_IF(s > loopEnd, "stepServer: s %u > loopEnd %u", s, loopEnd); 946 s = loopStart; 947 if (--loopCount == 0) { 948 loopEnd = UINT_MAX; 949 loopStart = UINT_MAX; 950 } 951 } 952 if (s >= serverBase + this->frameCount) { 953 serverBase += this->frameCount; 954 } 955 956 this->server = s; 957 958 cv.signal(); 959 lock.unlock(); 960 return true; 961} 962 963void* audio_track_cblk_t::buffer(uint32_t offset) const 964{ 965 return (int16_t *)this->buffers + (offset-userBase)*this->channels; 966} 967 968uint32_t audio_track_cblk_t::framesAvailable() 969{ 970 Mutex::Autolock _l(lock); 971 return framesAvailable_l(); 972} 973 974uint32_t audio_track_cblk_t::framesAvailable_l() 975{ 976 uint32_t u = this->user; 977 uint32_t s = this->server; 978 979 if (out) { 980 uint32_t limit = (s < loopStart) ? s : loopStart; 981 return limit + frameCount - u; 982 } else { 983 return frameCount + u - s; 984 } 985} 986 987uint32_t audio_track_cblk_t::framesReady() 988{ 989 uint32_t u = this->user; 990 uint32_t s = this->server; 991 992 if (out) { 993 if (u < loopEnd) { 994 return u - s; 995 } else { 996 Mutex::Autolock _l(lock); 997 if (loopCount >= 0) { 998 return (loopEnd - loopStart)*loopCount + u - s; 999 } else { 1000 return UINT_MAX; 1001 } 1002 } 1003 } else { 1004 return s - u; 1005 } 1006} 1007 1008// ------------------------------------------------------------------------- 1009 1010}; // namespace android 1011 1012