SoundPool.cpp revision 06524dccbc35cdeed92d0b5ec96b42d43518d7ed
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); 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) 275{ 276 List<SoundChannel*>::iterator iter; 277 SoundChannel* channel = NULL; 278 279 // allocate a channel 280 if (!mChannels.empty()) { 281 iter = mChannels.begin(); 282 if (priority >= (*iter)->priority()) { 283 channel = *iter; 284 mChannels.erase(iter); 285 ALOGV("Allocated active channel"); 286 } 287 } 288 289 // update priority and put it back in the list 290 if (channel) { 291 channel->setPriority(priority); 292 for (iter = mChannels.begin(); iter != mChannels.end(); ++iter) { 293 if (priority < (*iter)->priority()) { 294 break; 295 } 296 } 297 mChannels.insert(iter, channel); 298 } 299 return channel; 300} 301 302// move a channel from its current position to the front of the list 303void SoundPool::moveToFront_l(SoundChannel* channel) 304{ 305 for (List<SoundChannel*>::iterator iter = mChannels.begin(); iter != mChannels.end(); ++iter) { 306 if (*iter == channel) { 307 mChannels.erase(iter); 308 mChannels.push_front(channel); 309 break; 310 } 311 } 312} 313 314void SoundPool::pause(int channelID) 315{ 316 ALOGV("pause(%d)", channelID); 317 Mutex::Autolock lock(&mLock); 318 SoundChannel* channel = findChannel(channelID); 319 if (channel) { 320 channel->pause(); 321 } 322} 323 324void SoundPool::autoPause() 325{ 326 ALOGV("autoPause()"); 327 Mutex::Autolock lock(&mLock); 328 for (int i = 0; i < mMaxChannels; ++i) { 329 SoundChannel* channel = &mChannelPool[i]; 330 channel->autoPause(); 331 } 332} 333 334void SoundPool::resume(int channelID) 335{ 336 ALOGV("resume(%d)", channelID); 337 Mutex::Autolock lock(&mLock); 338 SoundChannel* channel = findChannel(channelID); 339 if (channel) { 340 channel->resume(); 341 } 342} 343 344void SoundPool::autoResume() 345{ 346 ALOGV("autoResume()"); 347 Mutex::Autolock lock(&mLock); 348 for (int i = 0; i < mMaxChannels; ++i) { 349 SoundChannel* channel = &mChannelPool[i]; 350 channel->autoResume(); 351 } 352} 353 354void SoundPool::stop(int channelID) 355{ 356 ALOGV("stop(%d)", channelID); 357 Mutex::Autolock lock(&mLock); 358 SoundChannel* channel = findChannel(channelID); 359 if (channel) { 360 channel->stop(); 361 } else { 362 channel = findNextChannel(channelID); 363 if (channel) 364 channel->clearNextEvent(); 365 } 366} 367 368void SoundPool::setVolume(int channelID, float leftVolume, float rightVolume) 369{ 370 Mutex::Autolock lock(&mLock); 371 SoundChannel* channel = findChannel(channelID); 372 if (channel) { 373 channel->setVolume(leftVolume, rightVolume); 374 } 375} 376 377void SoundPool::setPriority(int channelID, int priority) 378{ 379 ALOGV("setPriority(%d, %d)", channelID, priority); 380 Mutex::Autolock lock(&mLock); 381 SoundChannel* channel = findChannel(channelID); 382 if (channel) { 383 channel->setPriority(priority); 384 } 385} 386 387void SoundPool::setLoop(int channelID, int loop) 388{ 389 ALOGV("setLoop(%d, %d)", channelID, loop); 390 Mutex::Autolock lock(&mLock); 391 SoundChannel* channel = findChannel(channelID); 392 if (channel) { 393 channel->setLoop(loop); 394 } 395} 396 397void SoundPool::setRate(int channelID, float rate) 398{ 399 ALOGV("setRate(%d, %f)", channelID, rate); 400 Mutex::Autolock lock(&mLock); 401 SoundChannel* channel = findChannel(channelID); 402 if (channel) { 403 channel->setRate(rate); 404 } 405} 406 407// call with lock held 408void SoundPool::done_l(SoundChannel* channel) 409{ 410 ALOGV("done_l(%d)", channel->channelID()); 411 // if "stolen", play next event 412 if (channel->nextChannelID() != 0) { 413 ALOGV("add to restart list"); 414 addToRestartList(channel); 415 } 416 417 // return to idle state 418 else { 419 ALOGV("move to front"); 420 moveToFront_l(channel); 421 } 422} 423 424void SoundPool::setCallback(SoundPoolCallback* callback, void* user) 425{ 426 Mutex::Autolock lock(&mCallbackLock); 427 mCallback = callback; 428 mUserData = user; 429} 430 431void SoundPool::notify(SoundPoolEvent event) 432{ 433 Mutex::Autolock lock(&mCallbackLock); 434 if (mCallback != NULL) { 435 mCallback(event, this, mUserData); 436 } 437} 438 439void SoundPool::dump() 440{ 441 for (int i = 0; i < mMaxChannels; ++i) { 442 mChannelPool[i].dump(); 443 } 444} 445 446 447Sample::Sample(int sampleID, int fd, int64_t offset, int64_t length) 448{ 449 init(); 450 mSampleID = sampleID; 451 mFd = dup(fd); 452 mOffset = offset; 453 mLength = length; 454 ALOGV("create sampleID=%d, fd=%d, offset=%" PRId64 " length=%" PRId64, 455 mSampleID, mFd, mLength, mOffset); 456} 457 458void Sample::init() 459{ 460 mSize = 0; 461 mRefCount = 0; 462 mSampleID = 0; 463 mState = UNLOADED; 464 mFd = -1; 465 mOffset = 0; 466 mLength = 0; 467} 468 469Sample::~Sample() 470{ 471 ALOGV("Sample::destructor sampleID=%d, fd=%d", mSampleID, mFd); 472 if (mFd > 0) { 473 ALOGV("close(%d)", mFd); 474 ::close(mFd); 475 } 476} 477 478static status_t decode(int fd, int64_t offset, int64_t length, 479 uint32_t *rate, int *numChannels, audio_format_t *audioFormat, 480 sp<MemoryHeapBase> heap, size_t *memsize) { 481 482 ALOGV("fd %d, offset %" PRId64 ", size %" PRId64, fd, offset, length); 483 AMediaExtractor *ex = AMediaExtractor_new(); 484 status_t err = AMediaExtractor_setDataSourceFd(ex, fd, offset, length); 485 486 if (err != AMEDIA_OK) { 487 AMediaExtractor_delete(ex); 488 return err; 489 } 490 491 *audioFormat = AUDIO_FORMAT_PCM_16_BIT; 492 493 size_t numTracks = AMediaExtractor_getTrackCount(ex); 494 for (size_t i = 0; i < numTracks; i++) { 495 AMediaFormat *format = AMediaExtractor_getTrackFormat(ex, i); 496 const char *mime; 497 if (!AMediaFormat_getString(format, AMEDIAFORMAT_KEY_MIME, &mime)) { 498 AMediaExtractor_delete(ex); 499 AMediaFormat_delete(format); 500 return UNKNOWN_ERROR; 501 } 502 if (strncmp(mime, "audio/", 6) == 0) { 503 504 AMediaCodec *codec = AMediaCodec_createDecoderByType(mime); 505 if (AMediaCodec_configure(codec, format, 506 NULL /* window */, NULL /* drm */, 0 /* flags */) != AMEDIA_OK 507 || AMediaCodec_start(codec) != AMEDIA_OK 508 || AMediaExtractor_selectTrack(ex, i) != AMEDIA_OK) { 509 AMediaExtractor_delete(ex); 510 AMediaCodec_delete(codec); 511 AMediaFormat_delete(format); 512 return UNKNOWN_ERROR; 513 } 514 515 bool sawInputEOS = false; 516 bool sawOutputEOS = false; 517 uint8_t* writePos = static_cast<uint8_t*>(heap->getBase()); 518 size_t available = heap->getSize(); 519 size_t written = 0; 520 521 AMediaFormat_delete(format); 522 format = AMediaCodec_getOutputFormat(codec); 523 524 while (!sawOutputEOS) { 525 if (!sawInputEOS) { 526 ssize_t bufidx = AMediaCodec_dequeueInputBuffer(codec, 5000); 527 ALOGV("input buffer %zd", bufidx); 528 if (bufidx >= 0) { 529 size_t bufsize; 530 uint8_t *buf = AMediaCodec_getInputBuffer(codec, bufidx, &bufsize); 531 int sampleSize = AMediaExtractor_readSampleData(ex, buf, bufsize); 532 ALOGV("read %d", sampleSize); 533 if (sampleSize < 0) { 534 sampleSize = 0; 535 sawInputEOS = true; 536 ALOGV("EOS"); 537 } 538 int64_t presentationTimeUs = AMediaExtractor_getSampleTime(ex); 539 540 AMediaCodec_queueInputBuffer(codec, bufidx, 541 0 /* offset */, sampleSize, presentationTimeUs, 542 sawInputEOS ? AMEDIACODEC_BUFFER_FLAG_END_OF_STREAM : 0); 543 AMediaExtractor_advance(ex); 544 } 545 } 546 547 AMediaCodecBufferInfo info; 548 int status = AMediaCodec_dequeueOutputBuffer(codec, &info, 1); 549 ALOGV("dequeueoutput returned: %d", status); 550 if (status >= 0) { 551 if (info.flags & AMEDIACODEC_BUFFER_FLAG_END_OF_STREAM) { 552 ALOGV("output EOS"); 553 sawOutputEOS = true; 554 } 555 ALOGV("got decoded buffer size %d", info.size); 556 557 uint8_t *buf = AMediaCodec_getOutputBuffer(codec, status, NULL /* out_size */); 558 size_t dataSize = info.size; 559 if (dataSize > available) { 560 dataSize = available; 561 } 562 memcpy(writePos, buf + info.offset, dataSize); 563 writePos += dataSize; 564 written += dataSize; 565 available -= dataSize; 566 AMediaCodec_releaseOutputBuffer(codec, status, false /* render */); 567 if (available == 0) { 568 // there might be more data, but there's no space for it 569 sawOutputEOS = true; 570 } 571 } else if (status == AMEDIACODEC_INFO_OUTPUT_BUFFERS_CHANGED) { 572 ALOGV("output buffers changed"); 573 } else if (status == AMEDIACODEC_INFO_OUTPUT_FORMAT_CHANGED) { 574 AMediaFormat_delete(format); 575 format = AMediaCodec_getOutputFormat(codec); 576 ALOGV("format changed to: %s", AMediaFormat_toString(format)); 577 } else if (status == AMEDIACODEC_INFO_TRY_AGAIN_LATER) { 578 ALOGV("no output buffer right now"); 579 } else { 580 ALOGV("unexpected info code: %d", status); 581 } 582 } 583 584 AMediaCodec_stop(codec); 585 AMediaCodec_delete(codec); 586 AMediaExtractor_delete(ex); 587 if (!AMediaFormat_getInt32(format, AMEDIAFORMAT_KEY_SAMPLE_RATE, (int32_t*) rate) || 588 !AMediaFormat_getInt32(format, AMEDIAFORMAT_KEY_CHANNEL_COUNT, numChannels)) { 589 AMediaFormat_delete(format); 590 return UNKNOWN_ERROR; 591 } 592 AMediaFormat_delete(format); 593 *memsize = written; 594 return OK; 595 } 596 AMediaFormat_delete(format); 597 } 598 AMediaExtractor_delete(ex); 599 return UNKNOWN_ERROR; 600} 601 602status_t Sample::doLoad() 603{ 604 uint32_t sampleRate; 605 int numChannels; 606 audio_format_t format; 607 status_t status; 608 mHeap = new MemoryHeapBase(kDefaultHeapSize); 609 610 ALOGV("Start decode"); 611 status = decode(mFd, mOffset, mLength, &sampleRate, &numChannels, &format, 612 mHeap, &mSize); 613 ALOGV("close(%d)", mFd); 614 ::close(mFd); 615 mFd = -1; 616 if (status != NO_ERROR) { 617 ALOGE("Unable to load sample"); 618 goto error; 619 } 620 ALOGV("pointer = %p, size = %zu, sampleRate = %u, numChannels = %d", 621 mHeap->getBase(), mSize, sampleRate, numChannels); 622 623 if (sampleRate > kMaxSampleRate) { 624 ALOGE("Sample rate (%u) out of range", sampleRate); 625 status = BAD_VALUE; 626 goto error; 627 } 628 629 if ((numChannels < 1) || (numChannels > 2)) { 630 ALOGE("Sample channel count (%d) out of range", numChannels); 631 status = BAD_VALUE; 632 goto error; 633 } 634 635 mData = new MemoryBase(mHeap, 0, mSize); 636 mSampleRate = sampleRate; 637 mNumChannels = numChannels; 638 mFormat = format; 639 mState = READY; 640 return NO_ERROR; 641 642error: 643 mHeap.clear(); 644 return status; 645} 646 647 648void SoundChannel::init(SoundPool* soundPool) 649{ 650 mSoundPool = soundPool; 651} 652 653// call with sound pool lock held 654void SoundChannel::play(const sp<Sample>& sample, int nextChannelID, float leftVolume, 655 float rightVolume, int priority, int loop, float rate) 656{ 657 sp<AudioTrack> oldTrack; 658 sp<AudioTrack> newTrack; 659 status_t status; 660 661 { // scope for the lock 662 Mutex::Autolock lock(&mLock); 663 664 ALOGV("SoundChannel::play %p: sampleID=%d, channelID=%d, leftVolume=%f, rightVolume=%f," 665 " priority=%d, loop=%d, rate=%f", 666 this, sample->sampleID(), nextChannelID, leftVolume, rightVolume, 667 priority, loop, rate); 668 669 // if not idle, this voice is being stolen 670 if (mState != IDLE) { 671 ALOGV("channel %d stolen - event queued for channel %d", channelID(), nextChannelID); 672 mNextEvent.set(sample, nextChannelID, leftVolume, rightVolume, priority, loop, rate); 673 stop_l(); 674 return; 675 } 676 677 // initialize track 678 size_t afFrameCount; 679 uint32_t afSampleRate; 680 audio_stream_type_t streamType = audio_attributes_to_stream_type(mSoundPool->attributes()); 681 if (AudioSystem::getOutputFrameCount(&afFrameCount, streamType) != NO_ERROR) { 682 afFrameCount = kDefaultFrameCount; 683 } 684 if (AudioSystem::getOutputSamplingRate(&afSampleRate, streamType) != NO_ERROR) { 685 afSampleRate = kDefaultSampleRate; 686 } 687 int numChannels = sample->numChannels(); 688 uint32_t sampleRate = uint32_t(float(sample->sampleRate()) * rate + 0.5); 689 size_t frameCount = 0; 690 691 if (loop) { 692 frameCount = sample->size()/numChannels/ 693 ((sample->format() == AUDIO_FORMAT_PCM_16_BIT) ? sizeof(int16_t) : sizeof(uint8_t)); 694 } 695 696#ifndef USE_SHARED_MEM_BUFFER 697 uint32_t totalFrames = (kDefaultBufferCount * afFrameCount * sampleRate) / afSampleRate; 698 // Ensure minimum audio buffer size in case of short looped sample 699 if(frameCount < totalFrames) { 700 frameCount = totalFrames; 701 } 702#endif 703 704 // mToggle toggles each time a track is started on a given channel. 705 // The toggle is concatenated with the SoundChannel address and passed to AudioTrack 706 // as callback user data. This enables the detection of callbacks received from the old 707 // audio track while the new one is being started and avoids processing them with 708 // wrong audio audio buffer size (mAudioBufferSize) 709 unsigned long toggle = mToggle ^ 1; 710 void *userData = (void *)((unsigned long)this | toggle); 711 audio_channel_mask_t channelMask = audio_channel_out_mask_from_count(numChannels); 712 713 // do not create a new audio track if current track is compatible with sample parameters 714#ifdef USE_SHARED_MEM_BUFFER 715 newTrack = new AudioTrack(streamType, sampleRate, sample->format(), 716 channelMask, sample->getIMemory(), AUDIO_OUTPUT_FLAG_FAST, callback, userData); 717#else 718 uint32_t bufferFrames = (totalFrames + (kDefaultBufferCount - 1)) / kDefaultBufferCount; 719 newTrack = new AudioTrack(streamType, sampleRate, sample->format(), 720 channelMask, frameCount, AUDIO_OUTPUT_FLAG_FAST, callback, userData, 721 bufferFrames); 722#endif 723 oldTrack = mAudioTrack; 724 status = newTrack->initCheck(); 725 if (status != NO_ERROR) { 726 ALOGE("Error creating AudioTrack"); 727 goto exit; 728 } 729 ALOGV("setVolume %p", newTrack.get()); 730 newTrack->setVolume(leftVolume, rightVolume); 731 newTrack->setLoop(0, frameCount, loop); 732 733 // From now on, AudioTrack callbacks received with previous toggle value will be ignored. 734 mToggle = toggle; 735 mAudioTrack = newTrack; 736 mPos = 0; 737 mSample = sample; 738 mChannelID = nextChannelID; 739 mPriority = priority; 740 mLoop = loop; 741 mLeftVolume = leftVolume; 742 mRightVolume = rightVolume; 743 mNumChannels = numChannels; 744 mRate = rate; 745 clearNextEvent(); 746 mState = PLAYING; 747 mAudioTrack->start(); 748 mAudioBufferSize = newTrack->frameCount()*newTrack->frameSize(); 749 } 750 751exit: 752 ALOGV("delete oldTrack %p", oldTrack.get()); 753 if (status != NO_ERROR) { 754 mAudioTrack.clear(); 755 } 756} 757 758void SoundChannel::nextEvent() 759{ 760 sp<Sample> sample; 761 int nextChannelID; 762 float leftVolume; 763 float rightVolume; 764 int priority; 765 int loop; 766 float rate; 767 768 // check for valid event 769 { 770 Mutex::Autolock lock(&mLock); 771 nextChannelID = mNextEvent.channelID(); 772 if (nextChannelID == 0) { 773 ALOGV("stolen channel has no event"); 774 return; 775 } 776 777 sample = mNextEvent.sample(); 778 leftVolume = mNextEvent.leftVolume(); 779 rightVolume = mNextEvent.rightVolume(); 780 priority = mNextEvent.priority(); 781 loop = mNextEvent.loop(); 782 rate = mNextEvent.rate(); 783 } 784 785 ALOGV("Starting stolen channel %d -> %d", channelID(), nextChannelID); 786 play(sample, nextChannelID, leftVolume, rightVolume, priority, loop, rate); 787} 788 789void SoundChannel::callback(int event, void* user, void *info) 790{ 791 SoundChannel* channel = static_cast<SoundChannel*>((void *)((unsigned long)user & ~1)); 792 793 channel->process(event, info, (unsigned long)user & 1); 794} 795 796void SoundChannel::process(int event, void *info, unsigned long toggle) 797{ 798 //ALOGV("process(%d)", mChannelID); 799 800 Mutex::Autolock lock(&mLock); 801 802 AudioTrack::Buffer* b = NULL; 803 if (event == AudioTrack::EVENT_MORE_DATA) { 804 b = static_cast<AudioTrack::Buffer *>(info); 805 } 806 807 if (mToggle != toggle) { 808 ALOGV("process wrong toggle %p channel %d", this, mChannelID); 809 if (b != NULL) { 810 b->size = 0; 811 } 812 return; 813 } 814 815 sp<Sample> sample = mSample; 816 817// ALOGV("SoundChannel::process event %d", event); 818 819 if (event == AudioTrack::EVENT_MORE_DATA) { 820 821 // check for stop state 822 if (b->size == 0) return; 823 824 if (mState == IDLE) { 825 b->size = 0; 826 return; 827 } 828 829 if (sample != 0) { 830 // fill buffer 831 uint8_t* q = (uint8_t*) b->i8; 832 size_t count = 0; 833 834 if (mPos < (int)sample->size()) { 835 uint8_t* p = sample->data() + mPos; 836 count = sample->size() - mPos; 837 if (count > b->size) { 838 count = b->size; 839 } 840 memcpy(q, p, count); 841// ALOGV("fill: q=%p, p=%p, mPos=%u, b->size=%u, count=%d", q, p, mPos, b->size, 842// count); 843 } else if (mPos < mAudioBufferSize) { 844 count = mAudioBufferSize - mPos; 845 if (count > b->size) { 846 count = b->size; 847 } 848 memset(q, 0, count); 849// ALOGV("fill extra: q=%p, mPos=%u, b->size=%u, count=%d", q, mPos, b->size, count); 850 } 851 852 mPos += count; 853 b->size = count; 854 //ALOGV("buffer=%p, [0]=%d", b->i16, b->i16[0]); 855 } 856 } else if (event == AudioTrack::EVENT_UNDERRUN || event == AudioTrack::EVENT_BUFFER_END) { 857 ALOGV("process %p channel %d event %s", 858 this, mChannelID, (event == AudioTrack::EVENT_UNDERRUN) ? "UNDERRUN" : 859 "BUFFER_END"); 860 mSoundPool->addToStopList(this); 861 } else if (event == AudioTrack::EVENT_LOOP_END) { 862 ALOGV("End loop %p channel %d", this, mChannelID); 863 } else if (event == AudioTrack::EVENT_NEW_IAUDIOTRACK) { 864 ALOGV("process %p channel %d NEW_IAUDIOTRACK", this, mChannelID); 865 } else { 866 ALOGW("SoundChannel::process unexpected event %d", event); 867 } 868} 869 870 871// call with lock held 872bool SoundChannel::doStop_l() 873{ 874 if (mState != IDLE) { 875 setVolume_l(0, 0); 876 ALOGV("stop"); 877 mAudioTrack->stop(); 878 mSample.clear(); 879 mState = IDLE; 880 mPriority = IDLE_PRIORITY; 881 return true; 882 } 883 return false; 884} 885 886// call with lock held and sound pool lock held 887void SoundChannel::stop_l() 888{ 889 if (doStop_l()) { 890 mSoundPool->done_l(this); 891 } 892} 893 894// call with sound pool lock held 895void SoundChannel::stop() 896{ 897 bool stopped; 898 { 899 Mutex::Autolock lock(&mLock); 900 stopped = doStop_l(); 901 } 902 903 if (stopped) { 904 mSoundPool->done_l(this); 905 } 906} 907 908//FIXME: Pause is a little broken right now 909void SoundChannel::pause() 910{ 911 Mutex::Autolock lock(&mLock); 912 if (mState == PLAYING) { 913 ALOGV("pause track"); 914 mState = PAUSED; 915 mAudioTrack->pause(); 916 } 917} 918 919void SoundChannel::autoPause() 920{ 921 Mutex::Autolock lock(&mLock); 922 if (mState == PLAYING) { 923 ALOGV("pause track"); 924 mState = PAUSED; 925 mAutoPaused = true; 926 mAudioTrack->pause(); 927 } 928} 929 930void SoundChannel::resume() 931{ 932 Mutex::Autolock lock(&mLock); 933 if (mState == PAUSED) { 934 ALOGV("resume track"); 935 mState = PLAYING; 936 mAutoPaused = false; 937 mAudioTrack->start(); 938 } 939} 940 941void SoundChannel::autoResume() 942{ 943 Mutex::Autolock lock(&mLock); 944 if (mAutoPaused && (mState == PAUSED)) { 945 ALOGV("resume track"); 946 mState = PLAYING; 947 mAutoPaused = false; 948 mAudioTrack->start(); 949 } 950} 951 952void SoundChannel::setRate(float rate) 953{ 954 Mutex::Autolock lock(&mLock); 955 if (mAudioTrack != NULL && mSample != 0) { 956 uint32_t sampleRate = uint32_t(float(mSample->sampleRate()) * rate + 0.5); 957 mAudioTrack->setSampleRate(sampleRate); 958 mRate = rate; 959 } 960} 961 962// call with lock held 963void SoundChannel::setVolume_l(float leftVolume, float rightVolume) 964{ 965 mLeftVolume = leftVolume; 966 mRightVolume = rightVolume; 967 if (mAudioTrack != NULL) 968 mAudioTrack->setVolume(leftVolume, rightVolume); 969} 970 971void SoundChannel::setVolume(float leftVolume, float rightVolume) 972{ 973 Mutex::Autolock lock(&mLock); 974 setVolume_l(leftVolume, rightVolume); 975} 976 977void SoundChannel::setLoop(int loop) 978{ 979 Mutex::Autolock lock(&mLock); 980 if (mAudioTrack != NULL && mSample != 0) { 981 uint32_t loopEnd = mSample->size()/mNumChannels/ 982 ((mSample->format() == AUDIO_FORMAT_PCM_16_BIT) ? sizeof(int16_t) : sizeof(uint8_t)); 983 mAudioTrack->setLoop(0, loopEnd, loop); 984 mLoop = loop; 985 } 986} 987 988SoundChannel::~SoundChannel() 989{ 990 ALOGV("SoundChannel destructor %p", this); 991 { 992 Mutex::Autolock lock(&mLock); 993 clearNextEvent(); 994 doStop_l(); 995 } 996 // do not call AudioTrack destructor with mLock held as it will wait for the AudioTrack 997 // callback thread to exit which may need to execute process() and acquire the mLock. 998 mAudioTrack.clear(); 999} 1000 1001void SoundChannel::dump() 1002{ 1003 ALOGV("mState = %d mChannelID=%d, mNumChannels=%d, mPos = %d, mPriority=%d, mLoop=%d", 1004 mState, mChannelID, mNumChannels, mPos, mPriority, mLoop); 1005} 1006 1007void SoundEvent::set(const sp<Sample>& sample, int channelID, float leftVolume, 1008 float rightVolume, int priority, int loop, float rate) 1009{ 1010 mSample = sample; 1011 mChannelID = channelID; 1012 mLeftVolume = leftVolume; 1013 mRightVolume = rightVolume; 1014 mPriority = priority; 1015 mLoop = loop; 1016 mRate =rate; 1017} 1018 1019} // end namespace android 1020