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