AudioTrack.cpp revision be916aa1267e2e6b1c148f51d11bcbbc79cb864c
15460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/* //device/extlibs/pv/android/AudioTrack.cpp 25460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao** 35460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao** Copyright 2007, The Android Open Source Project 45460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao** 55460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao** Licensed under the Apache License, Version 2.0 (the "License"); 65460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao** you may not use this file except in compliance with the License. 75460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao** You may obtain a copy of the License at 85460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao** 95460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao** http://www.apache.org/licenses/LICENSE-2.0 105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao** 115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao** Unless required by applicable law or agreed to in writing, software 125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao** distributed under the License is distributed on an "AS IS" BASIS, 135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao** See the License for the specific language governing permissions and 155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao** limitations under the License. 165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao*/ 175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//#define LOG_NDEBUG 0 20cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao#define LOG_TAG "AudioTrack" 215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <stdint.h> 235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <sys/types.h> 245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <limits.h> 255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <sched.h> 275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <sys/resource.h> 285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <private/media/AudioTrackShared.h> 305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <media/AudioSystem.h> 325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <media/AudioTrack.h> 335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 34#include <utils/Log.h> 35#include <binder/Parcel.h> 36#include <binder/IPCThreadState.h> 37#include <utils/Timers.h> 38#include <cutils/atomic.h> 39 40#define LIKELY( exp ) (__builtin_expect( (exp) != 0, true )) 41#define UNLIKELY( exp ) (__builtin_expect( (exp) != 0, false )) 42 43namespace android { 44 45// --------------------------------------------------------------------------- 46 47AudioTrack::AudioTrack() 48 : mStatus(NO_INIT) 49{ 50} 51 52AudioTrack::AudioTrack( 53 int streamType, 54 uint32_t sampleRate, 55 int format, 56 int channels, 57 int frameCount, 58 uint32_t flags, 59 callback_t cbf, 60 void* user, 61 int notificationFrames, 62 int sessionId) 63 : mStatus(NO_INIT) 64{ 65 mStatus = set(streamType, sampleRate, format, channels, 66 frameCount, flags, cbf, user, notificationFrames, 0); 67} 68 69AudioTrack::AudioTrack( 70 int streamType, 71 uint32_t sampleRate, 72 int format, 73 int channels, 74 const sp<IMemory>& sharedBuffer, 75 uint32_t flags, 76 callback_t cbf, 77 void* user, 78 int notificationFrames, 79 int sessionId) 80 : mStatus(NO_INIT) 81{ 82 mStatus = set(streamType, sampleRate, format, channels, 83 0, flags, cbf, user, notificationFrames, sharedBuffer); 84} 85 86AudioTrack::~AudioTrack() 87{ 88 LOGV_IF(mSharedBuffer != 0, "Destructor sharedBuffer: %p", mSharedBuffer->pointer()); 89 90 if (mStatus == NO_ERROR) { 91 // Make sure that callback function exits in the case where 92 // it is looping on buffer full condition in obtainBuffer(). 93 // Otherwise the callback thread will never exit. 94 stop(); 95 if (mAudioTrackThread != 0) { 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 channels, 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 int sessionId) 117{ 118 119 LOGV_IF(sharedBuffer != 0, "sharedBuffer: %p, size: %d", sharedBuffer->pointer(), sharedBuffer->size()); 120 121 if (mAudioTrack != 0) { 122 LOGE("Track already in use"); 123 return INVALID_OPERATION; 124 } 125 126 int afSampleRate; 127 if (AudioSystem::getOutputSamplingRate(&afSampleRate, streamType) != NO_ERROR) { 128 return NO_INIT; 129 } 130 uint32_t afLatency; 131 if (AudioSystem::getOutputLatency(&afLatency, streamType) != NO_ERROR) { 132 return NO_INIT; 133 } 134 135 // handle default values first. 136 if (streamType == AudioSystem::DEFAULT) { 137 streamType = AudioSystem::MUSIC; 138 } 139 if (sampleRate == 0) { 140 sampleRate = afSampleRate; 141 } 142 // these below should probably come from the audioFlinger too... 143 if (format == 0) { 144 format = AudioSystem::PCM_16_BIT; 145 } 146 if (channels == 0) { 147 channels = AudioSystem::CHANNEL_OUT_STEREO; 148 } 149 150 // validate parameters 151 if (!AudioSystem::isValidFormat(format)) { 152 LOGE("Invalid format"); 153 return BAD_VALUE; 154 } 155 156 // force direct flag if format is not linear PCM 157 if (!AudioSystem::isLinearPCM(format)) { 158 flags |= AudioSystem::OUTPUT_FLAG_DIRECT; 159 } 160 161 if (!AudioSystem::isOutputChannel(channels)) { 162 LOGE("Invalid channel mask"); 163 return BAD_VALUE; 164 } 165 uint32_t channelCount = AudioSystem::popCount(channels); 166 167 audio_io_handle_t output = AudioSystem::getOutput((AudioSystem::stream_type)streamType, 168 sampleRate, format, channels, (AudioSystem::output_flags)flags); 169 170 if (output == 0) { 171 LOGE("Could not get audio output for stream type %d", streamType); 172 return BAD_VALUE; 173 } 174 175 mVolume[LEFT] = 1.0f; 176 mVolume[RIGHT] = 1.0f; 177 mSendLevel = 0; 178 mFrameCount = frameCount; 179 mNotificationFramesReq = notificationFrames; 180 mSessionId = sessionId; 181 182 // create the IAudioTrack 183 status_t status = createTrack(streamType, sampleRate, format, channelCount, 184 frameCount, flags, sharedBuffer, output, true); 185 186 if (status != NO_ERROR) { 187 return status; 188 } 189 190 if (cbf != 0) { 191 mAudioTrackThread = new AudioTrackThread(*this, threadCanCallJava); 192 if (mAudioTrackThread == 0) { 193 LOGE("Could not create callback thread"); 194 return NO_INIT; 195 } 196 } 197 198 mStatus = NO_ERROR; 199 200 mStreamType = streamType; 201 mFormat = format; 202 mChannels = channels; 203 mChannelCount = channelCount; 204 mSharedBuffer = sharedBuffer; 205 mMuted = false; 206 mActive = 0; 207 mCbf = cbf; 208 mUserData = user; 209 mLoopCount = 0; 210 mMarkerPosition = 0; 211 mMarkerReached = false; 212 mNewPosition = 0; 213 mUpdatePeriod = 0; 214 mFlags = flags; 215 216 return NO_ERROR; 217} 218 219status_t AudioTrack::initCheck() const 220{ 221 return mStatus; 222} 223 224// ------------------------------------------------------------------------- 225 226uint32_t AudioTrack::latency() const 227{ 228 return mLatency; 229} 230 231int AudioTrack::streamType() const 232{ 233 return mStreamType; 234} 235 236int AudioTrack::format() const 237{ 238 return mFormat; 239} 240 241int AudioTrack::channelCount() const 242{ 243 return mChannelCount; 244} 245 246uint32_t AudioTrack::frameCount() const 247{ 248 return mCblk->frameCount; 249} 250 251int AudioTrack::frameSize() const 252{ 253 if (AudioSystem::isLinearPCM(mFormat)) { 254 return channelCount()*((format() == AudioSystem::PCM_8_BIT) ? sizeof(uint8_t) : sizeof(int16_t)); 255 } else { 256 return sizeof(uint8_t); 257 } 258} 259 260sp<IMemory>& AudioTrack::sharedBuffer() 261{ 262 return mSharedBuffer; 263} 264 265// ------------------------------------------------------------------------- 266 267void AudioTrack::start() 268{ 269 sp<AudioTrackThread> t = mAudioTrackThread; 270 status_t status; 271 272 LOGV("start %p", this); 273 if (t != 0) { 274 if (t->exitPending()) { 275 if (t->requestExitAndWait() == WOULD_BLOCK) { 276 LOGE("AudioTrack::start called from thread"); 277 return; 278 } 279 } 280 t->mLock.lock(); 281 } 282 283 if (android_atomic_or(1, &mActive) == 0) { 284 mNewPosition = mCblk->server + mUpdatePeriod; 285 mCblk->bufferTimeoutMs = MAX_STARTUP_TIMEOUT_MS; 286 mCblk->waitTimeMs = 0; 287 if (t != 0) { 288 t->run("AudioTrackThread", THREAD_PRIORITY_AUDIO_CLIENT); 289 } else { 290 setpriority(PRIO_PROCESS, 0, THREAD_PRIORITY_AUDIO_CLIENT); 291 } 292 293 if (mCblk->flags & CBLK_INVALID_MSK) { 294 LOGW("start() track %p invalidated, creating a new one", this); 295 // no need to clear the invalid flag as this cblk will not be used anymore 296 // force new track creation 297 status = DEAD_OBJECT; 298 } else { 299 status = mAudioTrack->start(); 300 } 301 if (status == DEAD_OBJECT) { 302 LOGV("start() dead IAudioTrack: creating a new one"); 303 status = createTrack(mStreamType, mCblk->sampleRate, mFormat, mChannelCount, 304 mFrameCount, mFlags, mSharedBuffer, getOutput(), false); 305 if (status == NO_ERROR) { 306 status = mAudioTrack->start(); 307 if (status == NO_ERROR) { 308 mNewPosition = mCblk->server + mUpdatePeriod; 309 } 310 } 311 } 312 if (status != NO_ERROR) { 313 LOGV("start() failed"); 314 android_atomic_and(~1, &mActive); 315 if (t != 0) { 316 t->requestExit(); 317 } else { 318 setpriority(PRIO_PROCESS, 0, ANDROID_PRIORITY_NORMAL); 319 } 320 } 321 } 322 323 if (t != 0) { 324 t->mLock.unlock(); 325 } 326} 327 328void AudioTrack::stop() 329{ 330 sp<AudioTrackThread> t = mAudioTrackThread; 331 332 LOGV("stop %p", this); 333 if (t != 0) { 334 t->mLock.lock(); 335 } 336 337 if (android_atomic_and(~1, &mActive) == 1) { 338 mCblk->cv.signal(); 339 mAudioTrack->stop(); 340 // Cancel loops (If we are in the middle of a loop, playback 341 // would not stop until loopCount reaches 0). 342 setLoop(0, 0, 0); 343 // the playback head position will reset to 0, so if a marker is set, we need 344 // to activate it again 345 mMarkerReached = false; 346 // Force flush if a shared buffer is used otherwise audioflinger 347 // will not stop before end of buffer is reached. 348 if (mSharedBuffer != 0) { 349 flush(); 350 } 351 if (t != 0) { 352 t->requestExit(); 353 } else { 354 setpriority(PRIO_PROCESS, 0, ANDROID_PRIORITY_NORMAL); 355 } 356 } 357 358 if (t != 0) { 359 t->mLock.unlock(); 360 } 361} 362 363bool AudioTrack::stopped() const 364{ 365 return !mActive; 366} 367 368void AudioTrack::flush() 369{ 370 LOGV("flush"); 371 372 // clear playback marker and periodic update counter 373 mMarkerPosition = 0; 374 mMarkerReached = false; 375 mUpdatePeriod = 0; 376 377 378 if (!mActive) { 379 mAudioTrack->flush(); 380 // Release AudioTrack callback thread in case it was waiting for new buffers 381 // in AudioTrack::obtainBuffer() 382 mCblk->cv.signal(); 383 } 384} 385 386void AudioTrack::pause() 387{ 388 LOGV("pause"); 389 if (android_atomic_and(~1, &mActive) == 1) { 390 mAudioTrack->pause(); 391 } 392} 393 394void AudioTrack::mute(bool e) 395{ 396 mAudioTrack->mute(e); 397 mMuted = e; 398} 399 400bool AudioTrack::muted() const 401{ 402 return mMuted; 403} 404 405status_t AudioTrack::setVolume(float left, float right) 406{ 407 if (left > 1.0f || right > 1.0f) { 408 return BAD_VALUE; 409 } 410 411 mVolume[LEFT] = left; 412 mVolume[RIGHT] = right; 413 414 // write must be atomic 415 mCblk->volumeLR = (uint32_t(uint16_t(right * 0x1000)) << 16) | uint16_t(left * 0x1000); 416 417 return NO_ERROR; 418} 419 420void AudioTrack::getVolume(float* left, float* right) 421{ 422 if (left != NULL) { 423 *left = mVolume[LEFT]; 424 } 425 if (right != NULL) { 426 *right = mVolume[RIGHT]; 427 } 428} 429 430status_t AudioTrack::setSendLevel(float level) 431{ 432 if (level > 1.0f) { 433 return BAD_VALUE; 434 } 435 436 mSendLevel = level; 437 438 mCblk->sendLevel = uint16_t(level * 0x1000); 439 440 return NO_ERROR; 441} 442 443void AudioTrack::getSendLevel(float* level) 444{ 445 if (level != NULL) { 446 *level = mSendLevel; 447 } 448} 449 450status_t AudioTrack::setSampleRate(int rate) 451{ 452 int afSamplingRate; 453 454 if (AudioSystem::getOutputSamplingRate(&afSamplingRate, mStreamType) != NO_ERROR) { 455 return NO_INIT; 456 } 457 // Resampler implementation limits input sampling rate to 2 x output sampling rate. 458 if (rate <= 0 || rate > afSamplingRate*2 ) return BAD_VALUE; 459 460 mCblk->sampleRate = rate; 461 return NO_ERROR; 462} 463 464uint32_t AudioTrack::getSampleRate() 465{ 466 return mCblk->sampleRate; 467} 468 469status_t AudioTrack::setLoop(uint32_t loopStart, uint32_t loopEnd, int loopCount) 470{ 471 audio_track_cblk_t* cblk = mCblk; 472 473 Mutex::Autolock _l(cblk->lock); 474 475 if (loopCount == 0) { 476 cblk->loopStart = UINT_MAX; 477 cblk->loopEnd = UINT_MAX; 478 cblk->loopCount = 0; 479 mLoopCount = 0; 480 return NO_ERROR; 481 } 482 483 if (loopStart >= loopEnd || 484 loopEnd - loopStart > cblk->frameCount) { 485 LOGE("setLoop invalid value: loopStart %d, loopEnd %d, loopCount %d, framecount %d, user %d", loopStart, loopEnd, loopCount, cblk->frameCount, cblk->user); 486 return BAD_VALUE; 487 } 488 489 if ((mSharedBuffer != 0) && (loopEnd > cblk->frameCount)) { 490 LOGE("setLoop invalid value: loop markers beyond data: loopStart %d, loopEnd %d, framecount %d", 491 loopStart, loopEnd, cblk->frameCount); 492 return BAD_VALUE; 493 } 494 495 cblk->loopStart = loopStart; 496 cblk->loopEnd = loopEnd; 497 cblk->loopCount = loopCount; 498 mLoopCount = loopCount; 499 500 return NO_ERROR; 501} 502 503status_t AudioTrack::getLoop(uint32_t *loopStart, uint32_t *loopEnd, int *loopCount) 504{ 505 if (loopStart != 0) { 506 *loopStart = mCblk->loopStart; 507 } 508 if (loopEnd != 0) { 509 *loopEnd = mCblk->loopEnd; 510 } 511 if (loopCount != 0) { 512 if (mCblk->loopCount < 0) { 513 *loopCount = -1; 514 } else { 515 *loopCount = mCblk->loopCount; 516 } 517 } 518 519 return NO_ERROR; 520} 521 522status_t AudioTrack::setMarkerPosition(uint32_t marker) 523{ 524 if (mCbf == 0) return INVALID_OPERATION; 525 526 mMarkerPosition = marker; 527 mMarkerReached = false; 528 529 return NO_ERROR; 530} 531 532status_t AudioTrack::getMarkerPosition(uint32_t *marker) 533{ 534 if (marker == 0) return BAD_VALUE; 535 536 *marker = mMarkerPosition; 537 538 return NO_ERROR; 539} 540 541status_t AudioTrack::setPositionUpdatePeriod(uint32_t updatePeriod) 542{ 543 if (mCbf == 0) return INVALID_OPERATION; 544 545 uint32_t curPosition; 546 getPosition(&curPosition); 547 mNewPosition = curPosition + updatePeriod; 548 mUpdatePeriod = updatePeriod; 549 550 return NO_ERROR; 551} 552 553status_t AudioTrack::getPositionUpdatePeriod(uint32_t *updatePeriod) 554{ 555 if (updatePeriod == 0) return BAD_VALUE; 556 557 *updatePeriod = mUpdatePeriod; 558 559 return NO_ERROR; 560} 561 562status_t AudioTrack::setPosition(uint32_t position) 563{ 564 Mutex::Autolock _l(mCblk->lock); 565 566 if (!stopped()) return INVALID_OPERATION; 567 568 if (position > mCblk->user) return BAD_VALUE; 569 570 mCblk->server = position; 571 mCblk->flags |= CBLK_FORCEREADY_ON; 572 573 return NO_ERROR; 574} 575 576status_t AudioTrack::getPosition(uint32_t *position) 577{ 578 if (position == 0) return BAD_VALUE; 579 580 *position = mCblk->server; 581 582 return NO_ERROR; 583} 584 585status_t AudioTrack::reload() 586{ 587 if (!stopped()) return INVALID_OPERATION; 588 589 flush(); 590 591 mCblk->stepUser(mCblk->frameCount); 592 593 return NO_ERROR; 594} 595 596audio_io_handle_t AudioTrack::getOutput() 597{ 598 return AudioSystem::getOutput((AudioSystem::stream_type)mStreamType, 599 mCblk->sampleRate, mFormat, mChannels, (AudioSystem::output_flags)mFlags); 600} 601 602int AudioTrack::getSessionId() 603{ 604 return mSessionId; 605} 606 607status_t AudioTrack::attachAuxEffect(int effectId) 608{ 609 return mAudioTrack->attachAuxEffect(effectId); 610} 611 612// ------------------------------------------------------------------------- 613 614status_t AudioTrack::createTrack( 615 int streamType, 616 uint32_t sampleRate, 617 int format, 618 int channelCount, 619 int frameCount, 620 uint32_t flags, 621 const sp<IMemory>& sharedBuffer, 622 audio_io_handle_t output, 623 bool enforceFrameCount) 624{ 625 status_t status; 626 const sp<IAudioFlinger>& audioFlinger = AudioSystem::get_audio_flinger(); 627 if (audioFlinger == 0) { 628 LOGE("Could not get audioflinger"); 629 return NO_INIT; 630 } 631 632 int afSampleRate; 633 if (AudioSystem::getOutputSamplingRate(&afSampleRate, streamType) != NO_ERROR) { 634 return NO_INIT; 635 } 636 int afFrameCount; 637 if (AudioSystem::getOutputFrameCount(&afFrameCount, streamType) != NO_ERROR) { 638 return NO_INIT; 639 } 640 uint32_t afLatency; 641 if (AudioSystem::getOutputLatency(&afLatency, streamType) != NO_ERROR) { 642 return NO_INIT; 643 } 644 645 mNotificationFramesAct = mNotificationFramesReq; 646 if (!AudioSystem::isLinearPCM(format)) { 647 if (sharedBuffer != 0) { 648 frameCount = sharedBuffer->size(); 649 } 650 } else { 651 // Ensure that buffer depth covers at least audio hardware latency 652 uint32_t minBufCount = afLatency / ((1000 * afFrameCount)/afSampleRate); 653 if (minBufCount < 2) minBufCount = 2; 654 655 int minFrameCount = (afFrameCount*sampleRate*minBufCount)/afSampleRate; 656 657 if (sharedBuffer == 0) { 658 if (frameCount == 0) { 659 frameCount = minFrameCount; 660 } 661 if (mNotificationFramesAct == 0) { 662 mNotificationFramesAct = frameCount/2; 663 } 664 // Make sure that application is notified with sufficient margin 665 // before underrun 666 if (mNotificationFramesAct > (uint32_t)frameCount/2) { 667 mNotificationFramesAct = frameCount/2; 668 } 669 if (frameCount < minFrameCount) { 670 if (enforceFrameCount) { 671 LOGE("Invalid buffer size: minFrameCount %d, frameCount %d", minFrameCount, frameCount); 672 return BAD_VALUE; 673 } else { 674 frameCount = minFrameCount; 675 } 676 } 677 } else { 678 // Ensure that buffer alignment matches channelcount 679 if (((uint32_t)sharedBuffer->pointer() & (channelCount | 1)) != 0) { 680 LOGE("Invalid buffer alignement: address %p, channelCount %d", sharedBuffer->pointer(), channelCount); 681 return BAD_VALUE; 682 } 683 frameCount = sharedBuffer->size()/channelCount/sizeof(int16_t); 684 } 685 } 686 687 sp<IAudioTrack> track = audioFlinger->createTrack(getpid(), 688 streamType, 689 sampleRate, 690 format, 691 channelCount, 692 frameCount, 693 ((uint16_t)flags) << 16, 694 sharedBuffer, 695 output, 696 &mSessionId, 697 &status); 698 699 if (track == 0) { 700 LOGE("AudioFlinger could not create track, status: %d", status); 701 return status; 702 } 703 sp<IMemory> cblk = track->getCblk(); 704 if (cblk == 0) { 705 LOGE("Could not get control block"); 706 return NO_INIT; 707 } 708 mAudioTrack.clear(); 709 mAudioTrack = track; 710 mCblkMemory.clear(); 711 mCblkMemory = cblk; 712 mCblk = static_cast<audio_track_cblk_t*>(cblk->pointer()); 713 mCblk->flags |= CBLK_DIRECTION_OUT; 714 if (sharedBuffer == 0) { 715 mCblk->buffers = (char*)mCblk + sizeof(audio_track_cblk_t); 716 } else { 717 mCblk->buffers = sharedBuffer->pointer(); 718 // Force buffer full condition as data is already present in shared memory 719 mCblk->stepUser(mCblk->frameCount); 720 } 721 722 mCblk->volumeLR = (uint32_t(uint16_t(mVolume[RIGHT] * 0x1000)) << 16) | uint16_t(mVolume[LEFT] * 0x1000); 723 mCblk->sendLevel = uint16_t(mSendLevel * 0x1000); 724 mCblk->bufferTimeoutMs = MAX_STARTUP_TIMEOUT_MS; 725 mCblk->waitTimeMs = 0; 726 mRemainingFrames = mNotificationFramesAct; 727 mLatency = afLatency + (1000*mCblk->frameCount) / sampleRate; 728 return NO_ERROR; 729} 730 731status_t AudioTrack::obtainBuffer(Buffer* audioBuffer, int32_t waitCount) 732{ 733 int active; 734 status_t result; 735 audio_track_cblk_t* cblk = mCblk; 736 uint32_t framesReq = audioBuffer->frameCount; 737 uint32_t waitTimeMs = (waitCount < 0) ? cblk->bufferTimeoutMs : WAIT_PERIOD_MS; 738 739 audioBuffer->frameCount = 0; 740 audioBuffer->size = 0; 741 742 uint32_t framesAvail = cblk->framesAvailable(); 743 744 if (framesAvail == 0) { 745 cblk->lock.lock(); 746 goto start_loop_here; 747 while (framesAvail == 0) { 748 active = mActive; 749 if (UNLIKELY(!active)) { 750 LOGV("Not active and NO_MORE_BUFFERS"); 751 cblk->lock.unlock(); 752 return NO_MORE_BUFFERS; 753 } 754 if (UNLIKELY(!waitCount)) { 755 cblk->lock.unlock(); 756 return WOULD_BLOCK; 757 } 758 if (!(cblk->flags & CBLK_INVALID_MSK)) { 759 result = cblk->cv.waitRelative(cblk->lock, milliseconds(waitTimeMs)); 760 } 761 if (cblk->flags & CBLK_INVALID_MSK) { 762 LOGW("obtainBuffer() track %p invalidated, creating a new one", this); 763 // no need to clear the invalid flag as this cblk will not be used anymore 764 cblk->lock.unlock(); 765 goto create_new_track; 766 } 767 if (__builtin_expect(result!=NO_ERROR, false)) { 768 cblk->waitTimeMs += waitTimeMs; 769 if (cblk->waitTimeMs >= cblk->bufferTimeoutMs) { 770 // timing out when a loop has been set and we have already written upto loop end 771 // is a normal condition: no need to wake AudioFlinger up. 772 if (cblk->user < cblk->loopEnd) { 773 LOGW( "obtainBuffer timed out (is the CPU pegged?) %p " 774 "user=%08x, server=%08x", this, cblk->user, cblk->server); 775 //unlock cblk mutex before calling mAudioTrack->start() (see issue #1617140) 776 cblk->lock.unlock(); 777 result = mAudioTrack->start(); 778 if (result == DEAD_OBJECT) { 779 LOGW("obtainBuffer() dead IAudioTrack: creating a new one"); 780create_new_track: 781 result = createTrack(mStreamType, cblk->sampleRate, mFormat, mChannelCount, 782 mFrameCount, mFlags, mSharedBuffer, getOutput(), false); 783 if (result == NO_ERROR) { 784 cblk = mCblk; 785 cblk->bufferTimeoutMs = MAX_RUN_TIMEOUT_MS; 786 mAudioTrack->start(); 787 } 788 } 789 cblk->lock.lock(); 790 } 791 cblk->waitTimeMs = 0; 792 } 793 794 if (--waitCount == 0) { 795 cblk->lock.unlock(); 796 return TIMED_OUT; 797 } 798 } 799 // read the server count again 800 start_loop_here: 801 framesAvail = cblk->framesAvailable_l(); 802 } 803 cblk->lock.unlock(); 804 } 805 806 cblk->waitTimeMs = 0; 807 808 if (framesReq > framesAvail) { 809 framesReq = framesAvail; 810 } 811 812 uint32_t u = cblk->user; 813 uint32_t bufferEnd = cblk->userBase + cblk->frameCount; 814 815 if (u + framesReq > bufferEnd) { 816 framesReq = bufferEnd - u; 817 } 818 819 audioBuffer->flags = mMuted ? Buffer::MUTE : 0; 820 audioBuffer->channelCount = mChannelCount; 821 audioBuffer->frameCount = framesReq; 822 audioBuffer->size = framesReq * cblk->frameSize; 823 if (AudioSystem::isLinearPCM(mFormat)) { 824 audioBuffer->format = AudioSystem::PCM_16_BIT; 825 } else { 826 audioBuffer->format = mFormat; 827 } 828 audioBuffer->raw = (int8_t *)cblk->buffer(u); 829 active = mActive; 830 return active ? status_t(NO_ERROR) : status_t(STOPPED); 831} 832 833void AudioTrack::releaseBuffer(Buffer* audioBuffer) 834{ 835 audio_track_cblk_t* cblk = mCblk; 836 cblk->stepUser(audioBuffer->frameCount); 837} 838 839// ------------------------------------------------------------------------- 840 841ssize_t AudioTrack::write(const void* buffer, size_t userSize) 842{ 843 844 if (mSharedBuffer != 0) return INVALID_OPERATION; 845 846 if (ssize_t(userSize) < 0) { 847 // sanity-check. user is most-likely passing an error code. 848 LOGE("AudioTrack::write(buffer=%p, size=%u (%d)", 849 buffer, userSize, userSize); 850 return BAD_VALUE; 851 } 852 853 LOGV("write %p: %d bytes, mActive=%d", this, userSize, mActive); 854 855 ssize_t written = 0; 856 const int8_t *src = (const int8_t *)buffer; 857 Buffer audioBuffer; 858 859 do { 860 audioBuffer.frameCount = userSize/frameSize(); 861 862 // Calling obtainBuffer() with a negative wait count causes 863 // an (almost) infinite wait time. 864 status_t err = obtainBuffer(&audioBuffer, -1); 865 if (err < 0) { 866 // out of buffers, return #bytes written 867 if (err == status_t(NO_MORE_BUFFERS)) 868 break; 869 return ssize_t(err); 870 } 871 872 size_t toWrite; 873 874 if (mFormat == AudioSystem::PCM_8_BIT && !(mFlags & AudioSystem::OUTPUT_FLAG_DIRECT)) { 875 // Divide capacity by 2 to take expansion into account 876 toWrite = audioBuffer.size>>1; 877 // 8 to 16 bit conversion 878 int count = toWrite; 879 int16_t *dst = (int16_t *)(audioBuffer.i8); 880 while(count--) { 881 *dst++ = (int16_t)(*src++^0x80) << 8; 882 } 883 } else { 884 toWrite = audioBuffer.size; 885 memcpy(audioBuffer.i8, src, toWrite); 886 src += toWrite; 887 } 888 userSize -= toWrite; 889 written += toWrite; 890 891 releaseBuffer(&audioBuffer); 892 } while (userSize); 893 894 return written; 895} 896 897// ------------------------------------------------------------------------- 898 899bool AudioTrack::processAudioBuffer(const sp<AudioTrackThread>& thread) 900{ 901 Buffer audioBuffer; 902 uint32_t frames; 903 size_t writtenSize; 904 905 // Manage underrun callback 906 if (mActive && (mCblk->framesReady() == 0)) { 907 LOGV("Underrun user: %x, server: %x, flags %04x", mCblk->user, mCblk->server, mCblk->flags); 908 if ((mCblk->flags & CBLK_UNDERRUN_MSK) == CBLK_UNDERRUN_OFF) { 909 mCbf(EVENT_UNDERRUN, mUserData, 0); 910 if (mCblk->server == mCblk->frameCount) { 911 mCbf(EVENT_BUFFER_END, mUserData, 0); 912 } 913 mCblk->flags |= CBLK_UNDERRUN_ON; 914 if (mSharedBuffer != 0) return false; 915 } 916 } 917 918 // Manage loop end callback 919 while (mLoopCount > mCblk->loopCount) { 920 int loopCount = -1; 921 mLoopCount--; 922 if (mLoopCount >= 0) loopCount = mLoopCount; 923 924 mCbf(EVENT_LOOP_END, mUserData, (void *)&loopCount); 925 } 926 927 // Manage marker callback 928 if (!mMarkerReached && (mMarkerPosition > 0)) { 929 if (mCblk->server >= mMarkerPosition) { 930 mCbf(EVENT_MARKER, mUserData, (void *)&mMarkerPosition); 931 mMarkerReached = true; 932 } 933 } 934 935 // Manage new position callback 936 if (mUpdatePeriod > 0) { 937 while (mCblk->server >= mNewPosition) { 938 mCbf(EVENT_NEW_POS, mUserData, (void *)&mNewPosition); 939 mNewPosition += mUpdatePeriod; 940 } 941 } 942 943 // If Shared buffer is used, no data is requested from client. 944 if (mSharedBuffer != 0) { 945 frames = 0; 946 } else { 947 frames = mRemainingFrames; 948 } 949 950 do { 951 952 audioBuffer.frameCount = frames; 953 954 // Calling obtainBuffer() with a wait count of 1 955 // limits wait time to WAIT_PERIOD_MS. This prevents from being 956 // stuck here not being able to handle timed events (position, markers, loops). 957 status_t err = obtainBuffer(&audioBuffer, 1); 958 if (err < NO_ERROR) { 959 if (err != TIMED_OUT) { 960 LOGE_IF(err != status_t(NO_MORE_BUFFERS), "Error obtaining an audio buffer, giving up."); 961 return false; 962 } 963 break; 964 } 965 if (err == status_t(STOPPED)) return false; 966 967 // Divide buffer size by 2 to take into account the expansion 968 // due to 8 to 16 bit conversion: the callback must fill only half 969 // of the destination buffer 970 if (mFormat == AudioSystem::PCM_8_BIT && !(mFlags & AudioSystem::OUTPUT_FLAG_DIRECT)) { 971 audioBuffer.size >>= 1; 972 } 973 974 size_t reqSize = audioBuffer.size; 975 mCbf(EVENT_MORE_DATA, mUserData, &audioBuffer); 976 writtenSize = audioBuffer.size; 977 978 // Sanity check on returned size 979 if (ssize_t(writtenSize) <= 0) { 980 // The callback is done filling buffers 981 // Keep this thread going to handle timed events and 982 // still try to get more data in intervals of WAIT_PERIOD_MS 983 // but don't just loop and block the CPU, so wait 984 usleep(WAIT_PERIOD_MS*1000); 985 break; 986 } 987 if (writtenSize > reqSize) writtenSize = reqSize; 988 989 if (mFormat == AudioSystem::PCM_8_BIT && !(mFlags & AudioSystem::OUTPUT_FLAG_DIRECT)) { 990 // 8 to 16 bit conversion 991 const int8_t *src = audioBuffer.i8 + writtenSize-1; 992 int count = writtenSize; 993 int16_t *dst = audioBuffer.i16 + writtenSize-1; 994 while(count--) { 995 *dst-- = (int16_t)(*src--^0x80) << 8; 996 } 997 writtenSize <<= 1; 998 } 999 1000 audioBuffer.size = writtenSize; 1001 // NOTE: mCblk->frameSize is not equal to AudioTrack::frameSize() for 1002 // 8 bit PCM data: in this case, mCblk->frameSize is based on a sampel size of 1003 // 16 bit. 1004 audioBuffer.frameCount = writtenSize/mCblk->frameSize; 1005 1006 frames -= audioBuffer.frameCount; 1007 1008 releaseBuffer(&audioBuffer); 1009 } 1010 while (frames); 1011 1012 if (frames == 0) { 1013 mRemainingFrames = mNotificationFramesAct; 1014 } else { 1015 mRemainingFrames = frames; 1016 } 1017 return true; 1018} 1019 1020status_t AudioTrack::dump(int fd, const Vector<String16>& args) const 1021{ 1022 1023 const size_t SIZE = 256; 1024 char buffer[SIZE]; 1025 String8 result; 1026 1027 result.append(" AudioTrack::dump\n"); 1028 snprintf(buffer, 255, " stream type(%d), left - right volume(%f, %f)\n", mStreamType, mVolume[0], mVolume[1]); 1029 result.append(buffer); 1030 snprintf(buffer, 255, " format(%d), channel count(%d), frame count(%d)\n", mFormat, mChannelCount, mCblk->frameCount); 1031 result.append(buffer); 1032 snprintf(buffer, 255, " sample rate(%d), status(%d), muted(%d)\n", (mCblk == 0) ? 0 : mCblk->sampleRate, mStatus, mMuted); 1033 result.append(buffer); 1034 snprintf(buffer, 255, " active(%d), latency (%d)\n", mActive, mLatency); 1035 result.append(buffer); 1036 ::write(fd, result.string(), result.size()); 1037 return NO_ERROR; 1038} 1039 1040// ========================================================================= 1041 1042AudioTrack::AudioTrackThread::AudioTrackThread(AudioTrack& receiver, bool bCanCallJava) 1043 : Thread(bCanCallJava), mReceiver(receiver) 1044{ 1045} 1046 1047bool AudioTrack::AudioTrackThread::threadLoop() 1048{ 1049 return mReceiver.processAudioBuffer(this); 1050} 1051 1052status_t AudioTrack::AudioTrackThread::readyToRun() 1053{ 1054 return NO_ERROR; 1055} 1056 1057void AudioTrack::AudioTrackThread::onFirstRef() 1058{ 1059} 1060 1061// ========================================================================= 1062 1063audio_track_cblk_t::audio_track_cblk_t() 1064 : lock(Mutex::SHARED), cv(Condition::SHARED), user(0), server(0), 1065 userBase(0), serverBase(0), buffers(0), frameCount(0), 1066 loopStart(UINT_MAX), loopEnd(UINT_MAX), loopCount(0), volumeLR(0), 1067 flags(0), sendLevel(0) 1068{ 1069} 1070 1071uint32_t audio_track_cblk_t::stepUser(uint32_t frameCount) 1072{ 1073 uint32_t u = this->user; 1074 1075 u += frameCount; 1076 // Ensure that user is never ahead of server for AudioRecord 1077 if (flags & CBLK_DIRECTION_MSK) { 1078 // If stepServer() has been called once, switch to normal obtainBuffer() timeout period 1079 if (bufferTimeoutMs == MAX_STARTUP_TIMEOUT_MS-1) { 1080 bufferTimeoutMs = MAX_RUN_TIMEOUT_MS; 1081 } 1082 } else if (u > this->server) { 1083 LOGW("stepServer occured after track reset"); 1084 u = this->server; 1085 } 1086 1087 if (u >= userBase + this->frameCount) { 1088 userBase += this->frameCount; 1089 } 1090 1091 this->user = u; 1092 1093 // Clear flow control error condition as new data has been written/read to/from buffer. 1094 flags &= ~CBLK_UNDERRUN_MSK; 1095 1096 return u; 1097} 1098 1099bool audio_track_cblk_t::stepServer(uint32_t frameCount) 1100{ 1101 // the code below simulates lock-with-timeout 1102 // we MUST do this to protect the AudioFlinger server 1103 // as this lock is shared with the client. 1104 status_t err; 1105 1106 err = lock.tryLock(); 1107 if (err == -EBUSY) { // just wait a bit 1108 usleep(1000); 1109 err = lock.tryLock(); 1110 } 1111 if (err != NO_ERROR) { 1112 // probably, the client just died. 1113 return false; 1114 } 1115 1116 uint32_t s = this->server; 1117 1118 s += frameCount; 1119 if (flags & CBLK_DIRECTION_MSK) { 1120 // Mark that we have read the first buffer so that next time stepUser() is called 1121 // we switch to normal obtainBuffer() timeout period 1122 if (bufferTimeoutMs == MAX_STARTUP_TIMEOUT_MS) { 1123 bufferTimeoutMs = MAX_STARTUP_TIMEOUT_MS - 1; 1124 } 1125 // It is possible that we receive a flush() 1126 // while the mixer is processing a block: in this case, 1127 // stepServer() is called After the flush() has reset u & s and 1128 // we have s > u 1129 if (s > this->user) { 1130 LOGW("stepServer occured after track reset"); 1131 s = this->user; 1132 } 1133 } 1134 1135 if (s >= loopEnd) { 1136 LOGW_IF(s > loopEnd, "stepServer: s %u > loopEnd %u", s, loopEnd); 1137 s = loopStart; 1138 if (--loopCount == 0) { 1139 loopEnd = UINT_MAX; 1140 loopStart = UINT_MAX; 1141 } 1142 } 1143 if (s >= serverBase + this->frameCount) { 1144 serverBase += this->frameCount; 1145 } 1146 1147 this->server = s; 1148 1149 cv.signal(); 1150 lock.unlock(); 1151 return true; 1152} 1153 1154void* audio_track_cblk_t::buffer(uint32_t offset) const 1155{ 1156 return (int8_t *)this->buffers + (offset - userBase) * this->frameSize; 1157} 1158 1159uint32_t audio_track_cblk_t::framesAvailable() 1160{ 1161 Mutex::Autolock _l(lock); 1162 return framesAvailable_l(); 1163} 1164 1165uint32_t audio_track_cblk_t::framesAvailable_l() 1166{ 1167 uint32_t u = this->user; 1168 uint32_t s = this->server; 1169 1170 if (flags & CBLK_DIRECTION_MSK) { 1171 uint32_t limit = (s < loopStart) ? s : loopStart; 1172 return limit + frameCount - u; 1173 } else { 1174 return frameCount + u - s; 1175 } 1176} 1177 1178uint32_t audio_track_cblk_t::framesReady() 1179{ 1180 uint32_t u = this->user; 1181 uint32_t s = this->server; 1182 1183 if (flags & CBLK_DIRECTION_MSK) { 1184 if (u < loopEnd) { 1185 return u - s; 1186 } else { 1187 Mutex::Autolock _l(lock); 1188 if (loopCount >= 0) { 1189 return (loopEnd - loopStart)*loopCount + u - s; 1190 } else { 1191 return UINT_MAX; 1192 } 1193 } 1194 } else { 1195 return s - u; 1196 } 1197} 1198 1199// ------------------------------------------------------------------------- 1200 1201}; // namespace android 1202 1203