SoundPool.cpp revision 9bd868fe7ae712507211fff14b30981195dc96ce
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); 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 (AMediaCodec_configure(codec, format, 518 NULL /* window */, NULL /* drm */, 0 /* flags */) != AMEDIA_OK 519 || AMediaCodec_start(codec) != AMEDIA_OK 520 || AMediaExtractor_selectTrack(ex, i) != AMEDIA_OK) { 521 AMediaExtractor_delete(ex); 522 AMediaCodec_delete(codec); 523 AMediaFormat_delete(format); 524 return UNKNOWN_ERROR; 525 } 526 527 bool sawInputEOS = false; 528 bool sawOutputEOS = false; 529 uint8_t* writePos = static_cast<uint8_t*>(heap->getBase()); 530 size_t available = heap->getSize(); 531 size_t written = 0; 532 533 AMediaFormat_delete(format); 534 format = AMediaCodec_getOutputFormat(codec); 535 536 while (!sawOutputEOS) { 537 if (!sawInputEOS) { 538 ssize_t bufidx = AMediaCodec_dequeueInputBuffer(codec, 5000); 539 ALOGV("input buffer %zd", bufidx); 540 if (bufidx >= 0) { 541 size_t bufsize; 542 uint8_t *buf = AMediaCodec_getInputBuffer(codec, bufidx, &bufsize); 543 int sampleSize = AMediaExtractor_readSampleData(ex, buf, bufsize); 544 ALOGV("read %d", sampleSize); 545 if (sampleSize < 0) { 546 sampleSize = 0; 547 sawInputEOS = true; 548 ALOGV("EOS"); 549 } 550 int64_t presentationTimeUs = AMediaExtractor_getSampleTime(ex); 551 552 AMediaCodec_queueInputBuffer(codec, bufidx, 553 0 /* offset */, sampleSize, presentationTimeUs, 554 sawInputEOS ? AMEDIACODEC_BUFFER_FLAG_END_OF_STREAM : 0); 555 AMediaExtractor_advance(ex); 556 } 557 } 558 559 AMediaCodecBufferInfo info; 560 int status = AMediaCodec_dequeueOutputBuffer(codec, &info, 1); 561 ALOGV("dequeueoutput returned: %d", status); 562 if (status >= 0) { 563 if (info.flags & AMEDIACODEC_BUFFER_FLAG_END_OF_STREAM) { 564 ALOGV("output EOS"); 565 sawOutputEOS = true; 566 } 567 ALOGV("got decoded buffer size %d", info.size); 568 569 uint8_t *buf = AMediaCodec_getOutputBuffer(codec, status, NULL /* out_size */); 570 size_t dataSize = info.size; 571 if (dataSize > available) { 572 dataSize = available; 573 } 574 memcpy(writePos, buf + info.offset, dataSize); 575 writePos += dataSize; 576 written += dataSize; 577 available -= dataSize; 578 AMediaCodec_releaseOutputBuffer(codec, status, false /* render */); 579 if (available == 0) { 580 // there might be more data, but there's no space for it 581 sawOutputEOS = true; 582 } 583 } else if (status == AMEDIACODEC_INFO_OUTPUT_BUFFERS_CHANGED) { 584 ALOGV("output buffers changed"); 585 } else if (status == AMEDIACODEC_INFO_OUTPUT_FORMAT_CHANGED) { 586 AMediaFormat_delete(format); 587 format = AMediaCodec_getOutputFormat(codec); 588 ALOGV("format changed to: %s", AMediaFormat_toString(format)); 589 } else if (status == AMEDIACODEC_INFO_TRY_AGAIN_LATER) { 590 ALOGV("no output buffer right now"); 591 } else { 592 ALOGV("unexpected info code: %d", status); 593 } 594 } 595 596 AMediaCodec_stop(codec); 597 AMediaCodec_delete(codec); 598 AMediaExtractor_delete(ex); 599 if (!AMediaFormat_getInt32(format, AMEDIAFORMAT_KEY_SAMPLE_RATE, (int32_t*) rate) || 600 !AMediaFormat_getInt32(format, AMEDIAFORMAT_KEY_CHANNEL_COUNT, numChannels)) { 601 AMediaFormat_delete(format); 602 return UNKNOWN_ERROR; 603 } 604 AMediaFormat_delete(format); 605 *memsize = written; 606 return OK; 607 } 608 AMediaFormat_delete(format); 609 } 610 AMediaExtractor_delete(ex); 611 return UNKNOWN_ERROR; 612} 613 614status_t Sample::doLoad() 615{ 616 uint32_t sampleRate; 617 int numChannels; 618 audio_format_t format; 619 status_t status; 620 mHeap = new MemoryHeapBase(kDefaultHeapSize); 621 622 ALOGV("Start decode"); 623 status = decode(mFd, mOffset, mLength, &sampleRate, &numChannels, &format, 624 mHeap, &mSize); 625 ALOGV("close(%d)", mFd); 626 ::close(mFd); 627 mFd = -1; 628 if (status != NO_ERROR) { 629 ALOGE("Unable to load sample"); 630 goto error; 631 } 632 ALOGV("pointer = %p, size = %zu, sampleRate = %u, numChannels = %d", 633 mHeap->getBase(), mSize, sampleRate, numChannels); 634 635 if (sampleRate > kMaxSampleRate) { 636 ALOGE("Sample rate (%u) out of range", sampleRate); 637 status = BAD_VALUE; 638 goto error; 639 } 640 641 if ((numChannels < 1) || (numChannels > 8)) { 642 ALOGE("Sample channel count (%d) out of range", numChannels); 643 status = BAD_VALUE; 644 goto error; 645 } 646 647 mData = new MemoryBase(mHeap, 0, mSize); 648 mSampleRate = sampleRate; 649 mNumChannels = numChannels; 650 mFormat = format; 651 mState = READY; 652 return NO_ERROR; 653 654error: 655 mHeap.clear(); 656 return status; 657} 658 659 660void SoundChannel::init(SoundPool* soundPool) 661{ 662 mSoundPool = soundPool; 663 mPrevSampleID = -1; 664} 665 666// call with sound pool lock held 667void SoundChannel::play(const sp<Sample>& sample, int nextChannelID, float leftVolume, 668 float rightVolume, int priority, int loop, float rate) 669{ 670 sp<AudioTrack> oldTrack; 671 sp<AudioTrack> newTrack; 672 status_t status = NO_ERROR; 673 674 { // scope for the lock 675 Mutex::Autolock lock(&mLock); 676 677 ALOGV("SoundChannel::play %p: sampleID=%d, channelID=%d, leftVolume=%f, rightVolume=%f," 678 " priority=%d, loop=%d, rate=%f", 679 this, sample->sampleID(), nextChannelID, leftVolume, rightVolume, 680 priority, loop, rate); 681 682 // if not idle, this voice is being stolen 683 if (mState != IDLE) { 684 ALOGV("channel %d stolen - event queued for channel %d", channelID(), nextChannelID); 685 mNextEvent.set(sample, nextChannelID, leftVolume, rightVolume, priority, loop, rate); 686 stop_l(); 687 return; 688 } 689 690 // initialize track 691 size_t afFrameCount; 692 uint32_t afSampleRate; 693 audio_stream_type_t streamType = audio_attributes_to_stream_type(mSoundPool->attributes()); 694 if (AudioSystem::getOutputFrameCount(&afFrameCount, streamType) != NO_ERROR) { 695 afFrameCount = kDefaultFrameCount; 696 } 697 if (AudioSystem::getOutputSamplingRate(&afSampleRate, streamType) != NO_ERROR) { 698 afSampleRate = kDefaultSampleRate; 699 } 700 int numChannels = sample->numChannels(); 701 uint32_t sampleRate = uint32_t(float(sample->sampleRate()) * rate + 0.5); 702 size_t frameCount = 0; 703 704 if (loop) { 705 const audio_format_t format = sample->format(); 706 const size_t frameSize = audio_is_linear_pcm(format) 707 ? numChannels * audio_bytes_per_sample(format) : 1; 708 frameCount = sample->size() / frameSize; 709 } 710 711#ifndef USE_SHARED_MEM_BUFFER 712 uint32_t totalFrames = (kDefaultBufferCount * afFrameCount * sampleRate) / afSampleRate; 713 // Ensure minimum audio buffer size in case of short looped sample 714 if(frameCount < totalFrames) { 715 frameCount = totalFrames; 716 } 717#endif 718 719 if (!mAudioTrack.get() || mPrevSampleID != sample->sampleID()) { 720 // mToggle toggles each time a track is started on a given channel. 721 // The toggle is concatenated with the SoundChannel address and passed to AudioTrack 722 // as callback user data. This enables the detection of callbacks received from the old 723 // audio track while the new one is being started and avoids processing them with 724 // wrong audio audio buffer size (mAudioBufferSize) 725 unsigned long toggle = mToggle ^ 1; 726 void *userData = (void *)((unsigned long)this | toggle); 727 audio_channel_mask_t channelMask = audio_channel_out_mask_from_count(numChannels); 728 729 // do not create a new audio track if current track is compatible with sample parameters 730 #ifdef USE_SHARED_MEM_BUFFER 731 newTrack = new AudioTrack(streamType, sampleRate, sample->format(), 732 channelMask, sample->getIMemory(), AUDIO_OUTPUT_FLAG_FAST, callback, userData); 733 #else 734 uint32_t bufferFrames = (totalFrames + (kDefaultBufferCount - 1)) / kDefaultBufferCount; 735 newTrack = new AudioTrack(streamType, sampleRate, sample->format(), 736 channelMask, frameCount, AUDIO_OUTPUT_FLAG_FAST, callback, userData, 737 bufferFrames); 738 #endif 739 oldTrack = mAudioTrack; 740 status = newTrack->initCheck(); 741 if (status != NO_ERROR) { 742 ALOGE("Error creating AudioTrack"); 743 goto exit; 744 } 745 // From now on, AudioTrack callbacks received with previous toggle value will be ignored. 746 mToggle = toggle; 747 mAudioTrack = newTrack; 748 } else { 749 newTrack = mAudioTrack; 750 ALOGV("reusing track %p for sample %d", mAudioTrack.get(), sample->sampleID()); 751 } 752 newTrack->setVolume(leftVolume, rightVolume); 753 newTrack->setLoop(0, frameCount, loop); 754 mPos = 0; 755 mSample = sample; 756 mChannelID = nextChannelID; 757 mPriority = priority; 758 mLoop = loop; 759 mLeftVolume = leftVolume; 760 mRightVolume = rightVolume; 761 mNumChannels = numChannels; 762 mRate = rate; 763 clearNextEvent(); 764 mState = PLAYING; 765 mAudioTrack->start(); 766 mAudioBufferSize = newTrack->frameCount()*newTrack->frameSize(); 767 } 768 769exit: 770 ALOGV("delete oldTrack %p", oldTrack.get()); 771 if (status != NO_ERROR) { 772 mAudioTrack.clear(); 773 } 774} 775 776void SoundChannel::nextEvent() 777{ 778 sp<Sample> sample; 779 int nextChannelID; 780 float leftVolume; 781 float rightVolume; 782 int priority; 783 int loop; 784 float rate; 785 786 // check for valid event 787 { 788 Mutex::Autolock lock(&mLock); 789 nextChannelID = mNextEvent.channelID(); 790 if (nextChannelID == 0) { 791 ALOGV("stolen channel has no event"); 792 return; 793 } 794 795 sample = mNextEvent.sample(); 796 leftVolume = mNextEvent.leftVolume(); 797 rightVolume = mNextEvent.rightVolume(); 798 priority = mNextEvent.priority(); 799 loop = mNextEvent.loop(); 800 rate = mNextEvent.rate(); 801 } 802 803 ALOGV("Starting stolen channel %d -> %d", channelID(), nextChannelID); 804 play(sample, nextChannelID, leftVolume, rightVolume, priority, loop, rate); 805} 806 807void SoundChannel::callback(int event, void* user, void *info) 808{ 809 SoundChannel* channel = static_cast<SoundChannel*>((void *)((unsigned long)user & ~1)); 810 811 channel->process(event, info, (unsigned long)user & 1); 812} 813 814void SoundChannel::process(int event, void *info, unsigned long toggle) 815{ 816 //ALOGV("process(%d)", mChannelID); 817 818 Mutex::Autolock lock(&mLock); 819 820 AudioTrack::Buffer* b = NULL; 821 if (event == AudioTrack::EVENT_MORE_DATA) { 822 b = static_cast<AudioTrack::Buffer *>(info); 823 } 824 825 if (mToggle != toggle) { 826 ALOGV("process wrong toggle %p channel %d", this, mChannelID); 827 if (b != NULL) { 828 b->size = 0; 829 } 830 return; 831 } 832 833 sp<Sample> sample = mSample; 834 835// ALOGV("SoundChannel::process event %d", event); 836 837 if (event == AudioTrack::EVENT_MORE_DATA) { 838 839 // check for stop state 840 if (b->size == 0) return; 841 842 if (mState == IDLE) { 843 b->size = 0; 844 return; 845 } 846 847 if (sample != 0) { 848 // fill buffer 849 uint8_t* q = (uint8_t*) b->i8; 850 size_t count = 0; 851 852 if (mPos < (int)sample->size()) { 853 uint8_t* p = sample->data() + mPos; 854 count = sample->size() - mPos; 855 if (count > b->size) { 856 count = b->size; 857 } 858 memcpy(q, p, count); 859// ALOGV("fill: q=%p, p=%p, mPos=%u, b->size=%u, count=%d", q, p, mPos, b->size, 860// count); 861 } else if (mPos < mAudioBufferSize) { 862 count = mAudioBufferSize - mPos; 863 if (count > b->size) { 864 count = b->size; 865 } 866 memset(q, 0, count); 867// ALOGV("fill extra: q=%p, mPos=%u, b->size=%u, count=%d", q, mPos, b->size, count); 868 } 869 870 mPos += count; 871 b->size = count; 872 //ALOGV("buffer=%p, [0]=%d", b->i16, b->i16[0]); 873 } 874 } else if (event == AudioTrack::EVENT_UNDERRUN || event == AudioTrack::EVENT_BUFFER_END) { 875 ALOGV("process %p channel %d event %s", 876 this, mChannelID, (event == AudioTrack::EVENT_UNDERRUN) ? "UNDERRUN" : 877 "BUFFER_END"); 878 mSoundPool->addToStopList(this); 879 } else if (event == AudioTrack::EVENT_LOOP_END) { 880 ALOGV("End loop %p channel %d", this, mChannelID); 881 } else if (event == AudioTrack::EVENT_NEW_IAUDIOTRACK) { 882 ALOGV("process %p channel %d NEW_IAUDIOTRACK", this, mChannelID); 883 } else { 884 ALOGW("SoundChannel::process unexpected event %d", event); 885 } 886} 887 888 889// call with lock held 890bool SoundChannel::doStop_l() 891{ 892 if (mState != IDLE) { 893 setVolume_l(0, 0); 894 ALOGV("stop"); 895 mAudioTrack->stop(); 896 mPrevSampleID = mSample->sampleID(); 897 mSample.clear(); 898 mState = IDLE; 899 mPriority = IDLE_PRIORITY; 900 return true; 901 } 902 return false; 903} 904 905// call with lock held and sound pool lock held 906void SoundChannel::stop_l() 907{ 908 if (doStop_l()) { 909 mSoundPool->done_l(this); 910 } 911} 912 913// call with sound pool lock held 914void SoundChannel::stop() 915{ 916 bool stopped; 917 { 918 Mutex::Autolock lock(&mLock); 919 stopped = doStop_l(); 920 } 921 922 if (stopped) { 923 mSoundPool->done_l(this); 924 } 925} 926 927//FIXME: Pause is a little broken right now 928void SoundChannel::pause() 929{ 930 Mutex::Autolock lock(&mLock); 931 if (mState == PLAYING) { 932 ALOGV("pause track"); 933 mState = PAUSED; 934 mAudioTrack->pause(); 935 } 936} 937 938void SoundChannel::autoPause() 939{ 940 Mutex::Autolock lock(&mLock); 941 if (mState == PLAYING) { 942 ALOGV("pause track"); 943 mState = PAUSED; 944 mAutoPaused = true; 945 mAudioTrack->pause(); 946 } 947} 948 949void SoundChannel::resume() 950{ 951 Mutex::Autolock lock(&mLock); 952 if (mState == PAUSED) { 953 ALOGV("resume track"); 954 mState = PLAYING; 955 mAutoPaused = false; 956 mAudioTrack->start(); 957 } 958} 959 960void SoundChannel::autoResume() 961{ 962 Mutex::Autolock lock(&mLock); 963 if (mAutoPaused && (mState == PAUSED)) { 964 ALOGV("resume track"); 965 mState = PLAYING; 966 mAutoPaused = false; 967 mAudioTrack->start(); 968 } 969} 970 971void SoundChannel::setRate(float rate) 972{ 973 Mutex::Autolock lock(&mLock); 974 if (mAudioTrack != NULL && mSample != 0) { 975 uint32_t sampleRate = uint32_t(float(mSample->sampleRate()) * rate + 0.5); 976 mAudioTrack->setSampleRate(sampleRate); 977 mRate = rate; 978 } 979} 980 981// call with lock held 982void SoundChannel::setVolume_l(float leftVolume, float rightVolume) 983{ 984 mLeftVolume = leftVolume; 985 mRightVolume = rightVolume; 986 if (mAudioTrack != NULL) 987 mAudioTrack->setVolume(leftVolume, rightVolume); 988} 989 990void SoundChannel::setVolume(float leftVolume, float rightVolume) 991{ 992 Mutex::Autolock lock(&mLock); 993 setVolume_l(leftVolume, rightVolume); 994} 995 996void SoundChannel::setLoop(int loop) 997{ 998 Mutex::Autolock lock(&mLock); 999 if (mAudioTrack != NULL && mSample != 0) { 1000 uint32_t loopEnd = mSample->size()/mNumChannels/ 1001 ((mSample->format() == AUDIO_FORMAT_PCM_16_BIT) ? sizeof(int16_t) : sizeof(uint8_t)); 1002 mAudioTrack->setLoop(0, loopEnd, loop); 1003 mLoop = loop; 1004 } 1005} 1006 1007SoundChannel::~SoundChannel() 1008{ 1009 ALOGV("SoundChannel destructor %p", this); 1010 { 1011 Mutex::Autolock lock(&mLock); 1012 clearNextEvent(); 1013 doStop_l(); 1014 } 1015 // do not call AudioTrack destructor with mLock held as it will wait for the AudioTrack 1016 // callback thread to exit which may need to execute process() and acquire the mLock. 1017 mAudioTrack.clear(); 1018} 1019 1020void SoundChannel::dump() 1021{ 1022 ALOGV("mState = %d mChannelID=%d, mNumChannels=%d, mPos = %d, mPriority=%d, mLoop=%d", 1023 mState, mChannelID, mNumChannels, mPos, mPriority, mLoop); 1024} 1025 1026void SoundEvent::set(const sp<Sample>& sample, int channelID, float leftVolume, 1027 float rightVolume, int priority, int loop, float rate) 1028{ 1029 mSample = sample; 1030 mChannelID = channelID; 1031 mLeftVolume = leftVolume; 1032 mRightVolume = rightVolume; 1033 mPriority = priority; 1034 mLoop = loop; 1035 mRate =rate; 1036} 1037 1038} // end namespace android 1039