SoundPool.cpp revision 14d226a2cd7b39e17a3f0bfdab79e645f7146f53
1/* 2 * Copyright (C) 2007 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17//#define LOG_NDEBUG 0 18#define LOG_TAG "SoundPool" 19 20#include <inttypes.h> 21 22#include <utils/Log.h> 23 24#define USE_SHARED_MEM_BUFFER 25 26#include <media/AudioTrack.h> 27#include <media/IMediaHTTPService.h> 28#include <media/mediaplayer.h> 29#include <media/stagefright/MediaExtractor.h> 30#include "SoundPool.h" 31#include "SoundPoolThread.h" 32#include <media/AudioPolicyHelper.h> 33#include <ndk/NdkMediaCodec.h> 34#include <ndk/NdkMediaExtractor.h> 35#include <ndk/NdkMediaFormat.h> 36 37namespace android 38{ 39 40int kDefaultBufferCount = 4; 41uint32_t kMaxSampleRate = 48000; 42uint32_t kDefaultSampleRate = 44100; 43uint32_t kDefaultFrameCount = 1200; 44size_t kDefaultHeapSize = 1024 * 1024; // 1MB 45 46 47SoundPool::SoundPool(int maxChannels, const audio_attributes_t* pAttributes) 48{ 49 ALOGV("SoundPool constructor: maxChannels=%d, attr.usage=%d, attr.flags=0x%x, attr.tags=%s", 50 maxChannels, pAttributes->usage, pAttributes->flags, pAttributes->tags); 51 52 // check limits 53 mMaxChannels = maxChannels; 54 if (mMaxChannels < 1) { 55 mMaxChannels = 1; 56 } 57 else if (mMaxChannels > 32) { 58 mMaxChannels = 32; 59 } 60 ALOGW_IF(maxChannels != mMaxChannels, "App requested %d channels", maxChannels); 61 62 mQuit = false; 63 mDecodeThread = 0; 64 memcpy(&mAttributes, pAttributes, sizeof(audio_attributes_t)); 65 mAllocated = 0; 66 mNextSampleID = 0; 67 mNextChannelID = 0; 68 69 mCallback = 0; 70 mUserData = 0; 71 72 mChannelPool = new SoundChannel[mMaxChannels]; 73 for (int i = 0; i < mMaxChannels; ++i) { 74 mChannelPool[i].init(this); 75 mChannels.push_back(&mChannelPool[i]); 76 } 77 78 // start decode thread 79 startThreads(); 80} 81 82SoundPool::~SoundPool() 83{ 84 ALOGV("SoundPool destructor"); 85 mDecodeThread->quit(); 86 quit(); 87 88 Mutex::Autolock lock(&mLock); 89 90 mChannels.clear(); 91 if (mChannelPool) 92 delete [] mChannelPool; 93 // clean up samples 94 ALOGV("clear samples"); 95 mSamples.clear(); 96 97 if (mDecodeThread) 98 delete mDecodeThread; 99} 100 101void SoundPool::addToRestartList(SoundChannel* channel) 102{ 103 Mutex::Autolock lock(&mRestartLock); 104 if (!mQuit) { 105 mRestart.push_back(channel); 106 mCondition.signal(); 107 } 108} 109 110void SoundPool::addToStopList(SoundChannel* channel) 111{ 112 Mutex::Autolock lock(&mRestartLock); 113 if (!mQuit) { 114 mStop.push_back(channel); 115 mCondition.signal(); 116 } 117} 118 119int SoundPool::beginThread(void* arg) 120{ 121 SoundPool* p = (SoundPool*)arg; 122 return p->run(); 123} 124 125int SoundPool::run() 126{ 127 mRestartLock.lock(); 128 while (!mQuit) { 129 mCondition.wait(mRestartLock); 130 ALOGV("awake"); 131 if (mQuit) break; 132 133 while (!mStop.empty()) { 134 SoundChannel* channel; 135 ALOGV("Getting channel from stop list"); 136 List<SoundChannel* >::iterator iter = mStop.begin(); 137 channel = *iter; 138 mStop.erase(iter); 139 mRestartLock.unlock(); 140 if (channel != 0) { 141 Mutex::Autolock lock(&mLock); 142 channel->stop(); 143 } 144 mRestartLock.lock(); 145 if (mQuit) break; 146 } 147 148 while (!mRestart.empty()) { 149 SoundChannel* channel; 150 ALOGV("Getting channel from list"); 151 List<SoundChannel*>::iterator iter = mRestart.begin(); 152 channel = *iter; 153 mRestart.erase(iter); 154 mRestartLock.unlock(); 155 if (channel != 0) { 156 Mutex::Autolock lock(&mLock); 157 channel->nextEvent(); 158 } 159 mRestartLock.lock(); 160 if (mQuit) break; 161 } 162 } 163 164 mStop.clear(); 165 mRestart.clear(); 166 mCondition.signal(); 167 mRestartLock.unlock(); 168 ALOGV("goodbye"); 169 return 0; 170} 171 172void SoundPool::quit() 173{ 174 mRestartLock.lock(); 175 mQuit = true; 176 mCondition.signal(); 177 mCondition.wait(mRestartLock); 178 ALOGV("return from quit"); 179 mRestartLock.unlock(); 180} 181 182bool SoundPool::startThreads() 183{ 184 createThreadEtc(beginThread, this, "SoundPool"); 185 if (mDecodeThread == NULL) 186 mDecodeThread = new SoundPoolThread(this); 187 return mDecodeThread != NULL; 188} 189 190SoundChannel* SoundPool::findChannel(int channelID) 191{ 192 for (int i = 0; i < mMaxChannels; ++i) { 193 if (mChannelPool[i].channelID() == channelID) { 194 return &mChannelPool[i]; 195 } 196 } 197 return NULL; 198} 199 200SoundChannel* SoundPool::findNextChannel(int channelID) 201{ 202 for (int i = 0; i < mMaxChannels; ++i) { 203 if (mChannelPool[i].nextChannelID() == channelID) { 204 return &mChannelPool[i]; 205 } 206 } 207 return NULL; 208} 209 210int SoundPool::load(int fd, int64_t offset, int64_t length, int priority __unused) 211{ 212 ALOGV("load: fd=%d, offset=%" PRId64 ", length=%" PRId64 ", priority=%d", 213 fd, offset, length, priority); 214 Mutex::Autolock lock(&mLock); 215 sp<Sample> sample = new Sample(++mNextSampleID, fd, offset, length); 216 mSamples.add(sample->sampleID(), sample); 217 doLoad(sample); 218 return sample->sampleID(); 219} 220 221void SoundPool::doLoad(sp<Sample>& sample) 222{ 223 ALOGV("doLoad: loading sample sampleID=%d", sample->sampleID()); 224 sample->startLoad(); 225 mDecodeThread->loadSample(sample->sampleID()); 226} 227 228bool SoundPool::unload(int sampleID) 229{ 230 ALOGV("unload: sampleID=%d", sampleID); 231 Mutex::Autolock lock(&mLock); 232 return mSamples.removeItem(sampleID) >= 0; // removeItem() returns index or BAD_VALUE 233} 234 235int SoundPool::play(int sampleID, float leftVolume, float rightVolume, 236 int priority, int loop, float rate) 237{ 238 ALOGV("play sampleID=%d, leftVolume=%f, rightVolume=%f, priority=%d, loop=%d, rate=%f", 239 sampleID, leftVolume, rightVolume, priority, loop, rate); 240 sp<Sample> sample; 241 SoundChannel* channel; 242 int channelID; 243 244 Mutex::Autolock lock(&mLock); 245 246 if (mQuit) { 247 return 0; 248 } 249 // is sample ready? 250 sample = findSample(sampleID); 251 if ((sample == 0) || (sample->state() != Sample::READY)) { 252 ALOGW(" sample %d not READY", sampleID); 253 return 0; 254 } 255 256 dump(); 257 258 // allocate a channel 259 channel = allocateChannel_l(priority, sampleID); 260 261 // no channel allocated - return 0 262 if (!channel) { 263 ALOGV("No channel allocated"); 264 return 0; 265 } 266 267 channelID = ++mNextChannelID; 268 269 ALOGV("play channel %p state = %d", channel, channel->state()); 270 channel->play(sample, channelID, leftVolume, rightVolume, priority, loop, rate); 271 return channelID; 272} 273 274SoundChannel* SoundPool::allocateChannel_l(int priority, int sampleID) 275{ 276 List<SoundChannel*>::iterator iter; 277 SoundChannel* channel = NULL; 278 279 // check if channel for given sampleID still available 280 if (!mChannels.empty()) { 281 for (iter = mChannels.begin(); iter != mChannels.end(); ++iter) { 282 if (sampleID == (*iter)->getPrevSampleID() && (*iter)->state() == SoundChannel::IDLE) { 283 channel = *iter; 284 mChannels.erase(iter); 285 ALOGV("Allocated recycled channel for same sampleID"); 286 break; 287 } 288 } 289 } 290 291 // allocate any channel 292 if (!channel && !mChannels.empty()) { 293 iter = mChannels.begin(); 294 if (priority >= (*iter)->priority()) { 295 channel = *iter; 296 mChannels.erase(iter); 297 ALOGV("Allocated active channel"); 298 } 299 } 300 301 // update priority and put it back in the list 302 if (channel) { 303 channel->setPriority(priority); 304 for (iter = mChannels.begin(); iter != mChannels.end(); ++iter) { 305 if (priority < (*iter)->priority()) { 306 break; 307 } 308 } 309 mChannels.insert(iter, channel); 310 } 311 return channel; 312} 313 314// move a channel from its current position to the front of the list 315void SoundPool::moveToFront_l(SoundChannel* channel) 316{ 317 for (List<SoundChannel*>::iterator iter = mChannels.begin(); iter != mChannels.end(); ++iter) { 318 if (*iter == channel) { 319 mChannels.erase(iter); 320 mChannels.push_front(channel); 321 break; 322 } 323 } 324} 325 326void SoundPool::pause(int channelID) 327{ 328 ALOGV("pause(%d)", channelID); 329 Mutex::Autolock lock(&mLock); 330 SoundChannel* channel = findChannel(channelID); 331 if (channel) { 332 channel->pause(); 333 } 334} 335 336void SoundPool::autoPause() 337{ 338 ALOGV("autoPause()"); 339 Mutex::Autolock lock(&mLock); 340 for (int i = 0; i < mMaxChannels; ++i) { 341 SoundChannel* channel = &mChannelPool[i]; 342 channel->autoPause(); 343 } 344} 345 346void SoundPool::resume(int channelID) 347{ 348 ALOGV("resume(%d)", channelID); 349 Mutex::Autolock lock(&mLock); 350 SoundChannel* channel = findChannel(channelID); 351 if (channel) { 352 channel->resume(); 353 } 354} 355 356void SoundPool::autoResume() 357{ 358 ALOGV("autoResume()"); 359 Mutex::Autolock lock(&mLock); 360 for (int i = 0; i < mMaxChannels; ++i) { 361 SoundChannel* channel = &mChannelPool[i]; 362 channel->autoResume(); 363 } 364} 365 366void SoundPool::stop(int channelID) 367{ 368 ALOGV("stop(%d)", channelID); 369 Mutex::Autolock lock(&mLock); 370 SoundChannel* channel = findChannel(channelID); 371 if (channel) { 372 channel->stop(); 373 } else { 374 channel = findNextChannel(channelID); 375 if (channel) 376 channel->clearNextEvent(); 377 } 378} 379 380void SoundPool::setVolume(int channelID, float leftVolume, float rightVolume) 381{ 382 Mutex::Autolock lock(&mLock); 383 SoundChannel* channel = findChannel(channelID); 384 if (channel) { 385 channel->setVolume(leftVolume, rightVolume); 386 } 387} 388 389void SoundPool::setPriority(int channelID, int priority) 390{ 391 ALOGV("setPriority(%d, %d)", channelID, priority); 392 Mutex::Autolock lock(&mLock); 393 SoundChannel* channel = findChannel(channelID); 394 if (channel) { 395 channel->setPriority(priority); 396 } 397} 398 399void SoundPool::setLoop(int channelID, int loop) 400{ 401 ALOGV("setLoop(%d, %d)", channelID, loop); 402 Mutex::Autolock lock(&mLock); 403 SoundChannel* channel = findChannel(channelID); 404 if (channel) { 405 channel->setLoop(loop); 406 } 407} 408 409void SoundPool::setRate(int channelID, float rate) 410{ 411 ALOGV("setRate(%d, %f)", channelID, rate); 412 Mutex::Autolock lock(&mLock); 413 SoundChannel* channel = findChannel(channelID); 414 if (channel) { 415 channel->setRate(rate); 416 } 417} 418 419// call with lock held 420void SoundPool::done_l(SoundChannel* channel) 421{ 422 ALOGV("done_l(%d)", channel->channelID()); 423 // if "stolen", play next event 424 if (channel->nextChannelID() != 0) { 425 ALOGV("add to restart list"); 426 addToRestartList(channel); 427 } 428 429 // return to idle state 430 else { 431 ALOGV("move to front"); 432 moveToFront_l(channel); 433 } 434} 435 436void SoundPool::setCallback(SoundPoolCallback* callback, void* user) 437{ 438 Mutex::Autolock lock(&mCallbackLock); 439 mCallback = callback; 440 mUserData = user; 441} 442 443void SoundPool::notify(SoundPoolEvent event) 444{ 445 Mutex::Autolock lock(&mCallbackLock); 446 if (mCallback != NULL) { 447 mCallback(event, this, mUserData); 448 } 449} 450 451void SoundPool::dump() 452{ 453 for (int i = 0; i < mMaxChannels; ++i) { 454 mChannelPool[i].dump(); 455 } 456} 457 458 459Sample::Sample(int sampleID, int fd, int64_t offset, int64_t length) 460{ 461 init(); 462 mSampleID = sampleID; 463 mFd = dup(fd); 464 mOffset = offset; 465 mLength = length; 466 ALOGV("create sampleID=%d, fd=%d, offset=%" PRId64 " length=%" PRId64, 467 mSampleID, mFd, mLength, mOffset); 468} 469 470void Sample::init() 471{ 472 mSize = 0; 473 mRefCount = 0; 474 mSampleID = 0; 475 mState = UNLOADED; 476 mFd = -1; 477 mOffset = 0; 478 mLength = 0; 479} 480 481Sample::~Sample() 482{ 483 ALOGV("Sample::destructor sampleID=%d, fd=%d", mSampleID, mFd); 484 if (mFd > 0) { 485 ALOGV("close(%d)", mFd); 486 ::close(mFd); 487 } 488} 489 490static status_t decode(int fd, int64_t offset, int64_t length, 491 uint32_t *rate, int *numChannels, audio_format_t *audioFormat, 492 sp<MemoryHeapBase> heap, size_t *memsize) { 493 494 ALOGV("fd %d, offset %" PRId64 ", size %" PRId64, fd, offset, length); 495 AMediaExtractor *ex = AMediaExtractor_new(); 496 status_t err = AMediaExtractor_setDataSourceFd(ex, fd, offset, length); 497 498 if (err != AMEDIA_OK) { 499 AMediaExtractor_delete(ex); 500 return err; 501 } 502 503 *audioFormat = AUDIO_FORMAT_PCM_16_BIT; 504 505 size_t numTracks = AMediaExtractor_getTrackCount(ex); 506 for (size_t i = 0; i < numTracks; i++) { 507 AMediaFormat *format = AMediaExtractor_getTrackFormat(ex, i); 508 const char *mime; 509 if (!AMediaFormat_getString(format, AMEDIAFORMAT_KEY_MIME, &mime)) { 510 AMediaExtractor_delete(ex); 511 AMediaFormat_delete(format); 512 return UNKNOWN_ERROR; 513 } 514 if (strncmp(mime, "audio/", 6) == 0) { 515 516 AMediaCodec *codec = AMediaCodec_createDecoderByType(mime); 517 if (codec == NULL 518 || AMediaCodec_configure(codec, format, 519 NULL /* window */, NULL /* drm */, 0 /* flags */) != AMEDIA_OK 520 || AMediaCodec_start(codec) != AMEDIA_OK 521 || AMediaExtractor_selectTrack(ex, i) != AMEDIA_OK) { 522 AMediaExtractor_delete(ex); 523 AMediaCodec_delete(codec); 524 AMediaFormat_delete(format); 525 return UNKNOWN_ERROR; 526 } 527 528 bool sawInputEOS = false; 529 bool sawOutputEOS = false; 530 uint8_t* writePos = static_cast<uint8_t*>(heap->getBase()); 531 size_t available = heap->getSize(); 532 size_t written = 0; 533 534 AMediaFormat_delete(format); 535 format = AMediaCodec_getOutputFormat(codec); 536 537 while (!sawOutputEOS) { 538 if (!sawInputEOS) { 539 ssize_t bufidx = AMediaCodec_dequeueInputBuffer(codec, 5000); 540 ALOGV("input buffer %zd", bufidx); 541 if (bufidx >= 0) { 542 size_t bufsize; 543 uint8_t *buf = AMediaCodec_getInputBuffer(codec, bufidx, &bufsize); 544 int sampleSize = AMediaExtractor_readSampleData(ex, buf, bufsize); 545 ALOGV("read %d", sampleSize); 546 if (sampleSize < 0) { 547 sampleSize = 0; 548 sawInputEOS = true; 549 ALOGV("EOS"); 550 } 551 int64_t presentationTimeUs = AMediaExtractor_getSampleTime(ex); 552 553 AMediaCodec_queueInputBuffer(codec, bufidx, 554 0 /* offset */, sampleSize, presentationTimeUs, 555 sawInputEOS ? AMEDIACODEC_BUFFER_FLAG_END_OF_STREAM : 0); 556 AMediaExtractor_advance(ex); 557 } 558 } 559 560 AMediaCodecBufferInfo info; 561 int status = AMediaCodec_dequeueOutputBuffer(codec, &info, 1); 562 ALOGV("dequeueoutput returned: %d", status); 563 if (status >= 0) { 564 if (info.flags & AMEDIACODEC_BUFFER_FLAG_END_OF_STREAM) { 565 ALOGV("output EOS"); 566 sawOutputEOS = true; 567 } 568 ALOGV("got decoded buffer size %d", info.size); 569 570 uint8_t *buf = AMediaCodec_getOutputBuffer(codec, status, NULL /* out_size */); 571 size_t dataSize = info.size; 572 if (dataSize > available) { 573 dataSize = available; 574 } 575 memcpy(writePos, buf + info.offset, dataSize); 576 writePos += dataSize; 577 written += dataSize; 578 available -= dataSize; 579 AMediaCodec_releaseOutputBuffer(codec, status, false /* render */); 580 if (available == 0) { 581 // there might be more data, but there's no space for it 582 sawOutputEOS = true; 583 } 584 } else if (status == AMEDIACODEC_INFO_OUTPUT_BUFFERS_CHANGED) { 585 ALOGV("output buffers changed"); 586 } else if (status == AMEDIACODEC_INFO_OUTPUT_FORMAT_CHANGED) { 587 AMediaFormat_delete(format); 588 format = AMediaCodec_getOutputFormat(codec); 589 ALOGV("format changed to: %s", AMediaFormat_toString(format)); 590 } else if (status == AMEDIACODEC_INFO_TRY_AGAIN_LATER) { 591 ALOGV("no output buffer right now"); 592 } else { 593 ALOGV("unexpected info code: %d", status); 594 } 595 } 596 597 AMediaCodec_stop(codec); 598 AMediaCodec_delete(codec); 599 AMediaExtractor_delete(ex); 600 if (!AMediaFormat_getInt32(format, AMEDIAFORMAT_KEY_SAMPLE_RATE, (int32_t*) rate) || 601 !AMediaFormat_getInt32(format, AMEDIAFORMAT_KEY_CHANNEL_COUNT, numChannels)) { 602 AMediaFormat_delete(format); 603 return UNKNOWN_ERROR; 604 } 605 AMediaFormat_delete(format); 606 *memsize = written; 607 return OK; 608 } 609 AMediaFormat_delete(format); 610 } 611 AMediaExtractor_delete(ex); 612 return UNKNOWN_ERROR; 613} 614 615status_t Sample::doLoad() 616{ 617 uint32_t sampleRate; 618 int numChannels; 619 audio_format_t format; 620 status_t status; 621 mHeap = new MemoryHeapBase(kDefaultHeapSize); 622 623 ALOGV("Start decode"); 624 status = decode(mFd, mOffset, mLength, &sampleRate, &numChannels, &format, 625 mHeap, &mSize); 626 ALOGV("close(%d)", mFd); 627 ::close(mFd); 628 mFd = -1; 629 if (status != NO_ERROR) { 630 ALOGE("Unable to load sample"); 631 goto error; 632 } 633 ALOGV("pointer = %p, size = %zu, sampleRate = %u, numChannels = %d", 634 mHeap->getBase(), mSize, sampleRate, numChannels); 635 636 if (sampleRate > kMaxSampleRate) { 637 ALOGE("Sample rate (%u) out of range", sampleRate); 638 status = BAD_VALUE; 639 goto error; 640 } 641 642 if ((numChannels < 1) || (numChannels > 8)) { 643 ALOGE("Sample channel count (%d) out of range", numChannels); 644 status = BAD_VALUE; 645 goto error; 646 } 647 648 mData = new MemoryBase(mHeap, 0, mSize); 649 mSampleRate = sampleRate; 650 mNumChannels = numChannels; 651 mFormat = format; 652 mState = READY; 653 return NO_ERROR; 654 655error: 656 mHeap.clear(); 657 return status; 658} 659 660 661void SoundChannel::init(SoundPool* soundPool) 662{ 663 mSoundPool = soundPool; 664 mPrevSampleID = -1; 665} 666 667// call with sound pool lock held 668void SoundChannel::play(const sp<Sample>& sample, int nextChannelID, float leftVolume, 669 float rightVolume, int priority, int loop, float rate) 670{ 671 sp<AudioTrack> oldTrack; 672 sp<AudioTrack> newTrack; 673 status_t status = NO_ERROR; 674 675 { // scope for the lock 676 Mutex::Autolock lock(&mLock); 677 678 ALOGV("SoundChannel::play %p: sampleID=%d, channelID=%d, leftVolume=%f, rightVolume=%f," 679 " priority=%d, loop=%d, rate=%f", 680 this, sample->sampleID(), nextChannelID, leftVolume, rightVolume, 681 priority, loop, rate); 682 683 // if not idle, this voice is being stolen 684 if (mState != IDLE) { 685 ALOGV("channel %d stolen - event queued for channel %d", channelID(), nextChannelID); 686 mNextEvent.set(sample, nextChannelID, leftVolume, rightVolume, priority, loop, rate); 687 stop_l(); 688 return; 689 } 690 691 // initialize track 692 size_t afFrameCount; 693 uint32_t afSampleRate; 694 audio_stream_type_t streamType = audio_attributes_to_stream_type(mSoundPool->attributes()); 695 if (AudioSystem::getOutputFrameCount(&afFrameCount, streamType) != NO_ERROR) { 696 afFrameCount = kDefaultFrameCount; 697 } 698 if (AudioSystem::getOutputSamplingRate(&afSampleRate, streamType) != NO_ERROR) { 699 afSampleRate = kDefaultSampleRate; 700 } 701 int numChannels = sample->numChannels(); 702 uint32_t sampleRate = uint32_t(float(sample->sampleRate()) * rate + 0.5); 703 size_t frameCount = 0; 704 705 if (loop) { 706 const audio_format_t format = sample->format(); 707 const size_t frameSize = audio_is_linear_pcm(format) 708 ? numChannels * audio_bytes_per_sample(format) : 1; 709 frameCount = sample->size() / frameSize; 710 } 711 712#ifndef USE_SHARED_MEM_BUFFER 713 uint32_t totalFrames = (kDefaultBufferCount * afFrameCount * sampleRate) / afSampleRate; 714 // Ensure minimum audio buffer size in case of short looped sample 715 if(frameCount < totalFrames) { 716 frameCount = totalFrames; 717 } 718#endif 719 720 // check if the existing track has the same sample id. 721 if (mAudioTrack != 0 && mPrevSampleID == sample->sampleID()) { 722 // the sample rate may fail to change if the audio track is a fast track. 723 if (mAudioTrack->setSampleRate(sampleRate) == NO_ERROR) { 724 newTrack = mAudioTrack; 725 ALOGV("reusing track %p for sample %d", mAudioTrack.get(), sample->sampleID()); 726 } 727 } 728 if (newTrack == 0) { 729 // mToggle toggles each time a track is started on a given channel. 730 // The toggle is concatenated with the SoundChannel address and passed to AudioTrack 731 // as callback user data. This enables the detection of callbacks received from the old 732 // audio track while the new one is being started and avoids processing them with 733 // wrong audio audio buffer size (mAudioBufferSize) 734 unsigned long toggle = mToggle ^ 1; 735 void *userData = (void *)((unsigned long)this | toggle); 736 audio_channel_mask_t channelMask = audio_channel_out_mask_from_count(numChannels); 737 738 // do not create a new audio track if current track is compatible with sample parameters 739 #ifdef USE_SHARED_MEM_BUFFER 740 newTrack = new AudioTrack(streamType, sampleRate, sample->format(), 741 channelMask, sample->getIMemory(), AUDIO_OUTPUT_FLAG_FAST, callback, userData, 742 0 /*default notification frames*/, AUDIO_SESSION_ALLOCATE, 743 AudioTrack::TRANSFER_DEFAULT, 744 NULL /*offloadInfo*/, -1 /*uid*/, -1 /*pid*/, mSoundPool->attributes()); 745 #else 746 uint32_t bufferFrames = (totalFrames + (kDefaultBufferCount - 1)) / kDefaultBufferCount; 747 newTrack = new AudioTrack(streamType, sampleRate, sample->format(), 748 channelMask, frameCount, AUDIO_OUTPUT_FLAG_FAST, callback, userData, 749 bufferFrames, AUDIO_SESSION_ALLOCATE, AudioTrack::TRANSFER_DEFAULT, 750 NULL /*offloadInfo*/, -1 /*uid*/, -1 /*pid*/, mSoundPool->attributes()); 751 #endif 752 oldTrack = mAudioTrack; 753 status = newTrack->initCheck(); 754 if (status != NO_ERROR) { 755 ALOGE("Error creating AudioTrack"); 756 // newTrack goes out of scope, so reference count drops to zero 757 goto exit; 758 } 759 // From now on, AudioTrack callbacks received with previous toggle value will be ignored. 760 mToggle = toggle; 761 mAudioTrack = newTrack; 762 ALOGV("using new track %p for sample %d", newTrack.get(), sample->sampleID()); 763 } 764 newTrack->setVolume(leftVolume, rightVolume); 765 newTrack->setLoop(0, frameCount, loop); 766 mPos = 0; 767 mSample = sample; 768 mChannelID = nextChannelID; 769 mPriority = priority; 770 mLoop = loop; 771 mLeftVolume = leftVolume; 772 mRightVolume = rightVolume; 773 mNumChannels = numChannels; 774 mRate = rate; 775 clearNextEvent(); 776 mState = PLAYING; 777 mAudioTrack->start(); 778 mAudioBufferSize = newTrack->frameCount()*newTrack->frameSize(); 779 } 780 781exit: 782 ALOGV("delete oldTrack %p", oldTrack.get()); 783 if (status != NO_ERROR) { 784 mAudioTrack.clear(); 785 } 786} 787 788void SoundChannel::nextEvent() 789{ 790 sp<Sample> sample; 791 int nextChannelID; 792 float leftVolume; 793 float rightVolume; 794 int priority; 795 int loop; 796 float rate; 797 798 // check for valid event 799 { 800 Mutex::Autolock lock(&mLock); 801 nextChannelID = mNextEvent.channelID(); 802 if (nextChannelID == 0) { 803 ALOGV("stolen channel has no event"); 804 return; 805 } 806 807 sample = mNextEvent.sample(); 808 leftVolume = mNextEvent.leftVolume(); 809 rightVolume = mNextEvent.rightVolume(); 810 priority = mNextEvent.priority(); 811 loop = mNextEvent.loop(); 812 rate = mNextEvent.rate(); 813 } 814 815 ALOGV("Starting stolen channel %d -> %d", channelID(), nextChannelID); 816 play(sample, nextChannelID, leftVolume, rightVolume, priority, loop, rate); 817} 818 819void SoundChannel::callback(int event, void* user, void *info) 820{ 821 SoundChannel* channel = static_cast<SoundChannel*>((void *)((unsigned long)user & ~1)); 822 823 channel->process(event, info, (unsigned long)user & 1); 824} 825 826void SoundChannel::process(int event, void *info, unsigned long toggle) 827{ 828 //ALOGV("process(%d)", mChannelID); 829 830 Mutex::Autolock lock(&mLock); 831 832 AudioTrack::Buffer* b = NULL; 833 if (event == AudioTrack::EVENT_MORE_DATA) { 834 b = static_cast<AudioTrack::Buffer *>(info); 835 } 836 837 if (mToggle != toggle) { 838 ALOGV("process wrong toggle %p channel %d", this, mChannelID); 839 if (b != NULL) { 840 b->size = 0; 841 } 842 return; 843 } 844 845 sp<Sample> sample = mSample; 846 847// ALOGV("SoundChannel::process event %d", event); 848 849 if (event == AudioTrack::EVENT_MORE_DATA) { 850 851 // check for stop state 852 if (b->size == 0) return; 853 854 if (mState == IDLE) { 855 b->size = 0; 856 return; 857 } 858 859 if (sample != 0) { 860 // fill buffer 861 uint8_t* q = (uint8_t*) b->i8; 862 size_t count = 0; 863 864 if (mPos < (int)sample->size()) { 865 uint8_t* p = sample->data() + mPos; 866 count = sample->size() - mPos; 867 if (count > b->size) { 868 count = b->size; 869 } 870 memcpy(q, p, count); 871// ALOGV("fill: q=%p, p=%p, mPos=%u, b->size=%u, count=%d", q, p, mPos, b->size, 872// count); 873 } else if (mPos < mAudioBufferSize) { 874 count = mAudioBufferSize - mPos; 875 if (count > b->size) { 876 count = b->size; 877 } 878 memset(q, 0, count); 879// ALOGV("fill extra: q=%p, mPos=%u, b->size=%u, count=%d", q, mPos, b->size, count); 880 } 881 882 mPos += count; 883 b->size = count; 884 //ALOGV("buffer=%p, [0]=%d", b->i16, b->i16[0]); 885 } 886 } else if (event == AudioTrack::EVENT_UNDERRUN || event == AudioTrack::EVENT_BUFFER_END) { 887 ALOGV("process %p channel %d event %s", 888 this, mChannelID, (event == AudioTrack::EVENT_UNDERRUN) ? "UNDERRUN" : 889 "BUFFER_END"); 890 mSoundPool->addToStopList(this); 891 } else if (event == AudioTrack::EVENT_LOOP_END) { 892 ALOGV("End loop %p channel %d", this, mChannelID); 893 } else if (event == AudioTrack::EVENT_NEW_IAUDIOTRACK) { 894 ALOGV("process %p channel %d NEW_IAUDIOTRACK", this, mChannelID); 895 } else { 896 ALOGW("SoundChannel::process unexpected event %d", event); 897 } 898} 899 900 901// call with lock held 902bool SoundChannel::doStop_l() 903{ 904 if (mState != IDLE) { 905 setVolume_l(0, 0); 906 ALOGV("stop"); 907 mAudioTrack->stop(); 908 mPrevSampleID = mSample->sampleID(); 909 mSample.clear(); 910 mState = IDLE; 911 mPriority = IDLE_PRIORITY; 912 return true; 913 } 914 return false; 915} 916 917// call with lock held and sound pool lock held 918void SoundChannel::stop_l() 919{ 920 if (doStop_l()) { 921 mSoundPool->done_l(this); 922 } 923} 924 925// call with sound pool lock held 926void SoundChannel::stop() 927{ 928 bool stopped; 929 { 930 Mutex::Autolock lock(&mLock); 931 stopped = doStop_l(); 932 } 933 934 if (stopped) { 935 mSoundPool->done_l(this); 936 } 937} 938 939//FIXME: Pause is a little broken right now 940void SoundChannel::pause() 941{ 942 Mutex::Autolock lock(&mLock); 943 if (mState == PLAYING) { 944 ALOGV("pause track"); 945 mState = PAUSED; 946 mAudioTrack->pause(); 947 } 948} 949 950void SoundChannel::autoPause() 951{ 952 Mutex::Autolock lock(&mLock); 953 if (mState == PLAYING) { 954 ALOGV("pause track"); 955 mState = PAUSED; 956 mAutoPaused = true; 957 mAudioTrack->pause(); 958 } 959} 960 961void SoundChannel::resume() 962{ 963 Mutex::Autolock lock(&mLock); 964 if (mState == PAUSED) { 965 ALOGV("resume track"); 966 mState = PLAYING; 967 mAutoPaused = false; 968 mAudioTrack->start(); 969 } 970} 971 972void SoundChannel::autoResume() 973{ 974 Mutex::Autolock lock(&mLock); 975 if (mAutoPaused && (mState == PAUSED)) { 976 ALOGV("resume track"); 977 mState = PLAYING; 978 mAutoPaused = false; 979 mAudioTrack->start(); 980 } 981} 982 983void SoundChannel::setRate(float rate) 984{ 985 Mutex::Autolock lock(&mLock); 986 if (mAudioTrack != NULL && mSample != 0) { 987 uint32_t sampleRate = uint32_t(float(mSample->sampleRate()) * rate + 0.5); 988 mAudioTrack->setSampleRate(sampleRate); 989 mRate = rate; 990 } 991} 992 993// call with lock held 994void SoundChannel::setVolume_l(float leftVolume, float rightVolume) 995{ 996 mLeftVolume = leftVolume; 997 mRightVolume = rightVolume; 998 if (mAudioTrack != NULL) 999 mAudioTrack->setVolume(leftVolume, rightVolume); 1000} 1001 1002void SoundChannel::setVolume(float leftVolume, float rightVolume) 1003{ 1004 Mutex::Autolock lock(&mLock); 1005 setVolume_l(leftVolume, rightVolume); 1006} 1007 1008void SoundChannel::setLoop(int loop) 1009{ 1010 Mutex::Autolock lock(&mLock); 1011 if (mAudioTrack != NULL && mSample != 0) { 1012 uint32_t loopEnd = mSample->size()/mNumChannels/ 1013 ((mSample->format() == AUDIO_FORMAT_PCM_16_BIT) ? sizeof(int16_t) : sizeof(uint8_t)); 1014 mAudioTrack->setLoop(0, loopEnd, loop); 1015 mLoop = loop; 1016 } 1017} 1018 1019SoundChannel::~SoundChannel() 1020{ 1021 ALOGV("SoundChannel destructor %p", this); 1022 { 1023 Mutex::Autolock lock(&mLock); 1024 clearNextEvent(); 1025 doStop_l(); 1026 } 1027 // do not call AudioTrack destructor with mLock held as it will wait for the AudioTrack 1028 // callback thread to exit which may need to execute process() and acquire the mLock. 1029 mAudioTrack.clear(); 1030} 1031 1032void SoundChannel::dump() 1033{ 1034 ALOGV("mState = %d mChannelID=%d, mNumChannels=%d, mPos = %d, mPriority=%d, mLoop=%d", 1035 mState, mChannelID, mNumChannels, mPos, mPriority, mLoop); 1036} 1037 1038void SoundEvent::set(const sp<Sample>& sample, int channelID, float leftVolume, 1039 float rightVolume, int priority, int loop, float rate) 1040{ 1041 mSample = sample; 1042 mChannelID = channelID; 1043 mLeftVolume = leftVolume; 1044 mRightVolume = rightVolume; 1045 mPriority = priority; 1046 mLoop = loop; 1047 mRate =rate; 1048} 1049 1050} // end namespace android 1051