SoundPool.cpp revision 0c4b81bd3ef3fd5eb0f7d1b8e2c6168b95020134
1372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen/* 2372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen * Copyright (C) 2007 The Android Open Source Project 3372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen * 4372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen * Licensed under the Apache License, Version 2.0 (the "License"); 5372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen * you may not use this file except in compliance with the License. 6372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen * You may obtain a copy of the License at 7372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen * 8372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen * http://www.apache.org/licenses/LICENSE-2.0 9372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen * 10372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen * Unless required by applicable law or agreed to in writing, software 11372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen * distributed under the License is distributed on an "AS IS" BASIS, 12372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen * See the License for the specific language governing permissions and 14372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen * limitations under the License. 15372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen */ 16372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen 17372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen//#define LOG_NDEBUG 0 18372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen#define LOG_TAG "SoundPool" 19372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen 20372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen#include <inttypes.h> 21372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen 22372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen#include <utils/Log.h> 23372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen 24372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen#define USE_SHARED_MEM_BUFFER 25372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen 26372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen#include <media/AudioTrack.h> 27372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen#include <media/IMediaHTTPService.h> 28372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen#include <media/mediaplayer.h> 29372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen#include <media/stagefright/MediaExtractor.h> 30372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen#include "SoundPool.h" 31372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen#include "SoundPoolThread.h" 32372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen#include <media/AudioPolicyHelper.h> 33372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen#include <ndk/NdkMediaCodec.h> 34372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen#include <ndk/NdkMediaExtractor.h> 35372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen#include <ndk/NdkMediaFormat.h> 36372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen 37372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissennamespace android 38372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen{ 39372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen 40372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissenint kDefaultBufferCount = 4; 41372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissenuint32_t kMaxSampleRate = 48000; 42372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissenuint32_t kDefaultSampleRate = 44100; 43372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissenuint32_t kDefaultFrameCount = 1200; 44372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissensize_t kDefaultHeapSize = 1024 * 1024; // 1MB 45372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen 46372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen 47372be8970c6ab68c295fb74dbb878ab1d443d90eMarco NelissenSoundPool::SoundPool(int maxChannels, const audio_attributes_t* pAttributes) 48372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen{ 49372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen ALOGV("SoundPool constructor: maxChannels=%d, attr.usage=%d, attr.flags=0x%x, attr.tags=%s", 50372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen maxChannels, pAttributes->usage, pAttributes->flags, pAttributes->tags); 51372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen 52372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen // check limits 53372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen mMaxChannels = maxChannels; 54372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen if (mMaxChannels < 1) { 55372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen mMaxChannels = 1; 56372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen } 57372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen else if (mMaxChannels > 32) { 58372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen mMaxChannels = 32; 59372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen } 60372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen ALOGW_IF(maxChannels != mMaxChannels, "App requested %d channels", maxChannels); 61372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen 62372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen mQuit = false; 63372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen mDecodeThread = 0; 64372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen memcpy(&mAttributes, pAttributes, sizeof(audio_attributes_t)); 65372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen mAllocated = 0; 66372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen mNextSampleID = 0; 67372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen mNextChannelID = 0; 68372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen 69372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen mCallback = 0; 70372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen mUserData = 0; 71372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen 72372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen mChannelPool = new SoundChannel[mMaxChannels]; 73372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen for (int i = 0; i < mMaxChannels; ++i) { 74372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen mChannelPool[i].init(this); 75372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen mChannels.push_back(&mChannelPool[i]); 76372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen } 77372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen 78372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen // start decode thread 79372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen startThreads(); 80372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen} 81372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen 82372be8970c6ab68c295fb74dbb878ab1d443d90eMarco NelissenSoundPool::~SoundPool() 83372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen{ 84372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen ALOGV("SoundPool destructor"); 85372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen mDecodeThread->quit(); 86372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen quit(); 87372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen 88372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen Mutex::Autolock lock(&mLock); 89372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen 90372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen mChannels.clear(); 91372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen if (mChannelPool) 92372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen delete [] mChannelPool; 93372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen // clean up samples 94372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen ALOGV("clear samples"); 95372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen mSamples.clear(); 96372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen 97372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen if (mDecodeThread) 98372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen delete mDecodeThread; 99372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen} 100372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen 101372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissenvoid SoundPool::addToRestartList(SoundChannel* channel) 102372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen{ 103372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen Mutex::Autolock lock(&mRestartLock); 104372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen if (!mQuit) { 105372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen mRestart.push_back(channel); 106372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen mCondition.signal(); 107372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen } 108372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen} 109372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen 110372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissenvoid SoundPool::addToStopList(SoundChannel* channel) 111372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen{ 112372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen Mutex::Autolock lock(&mRestartLock); 113372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen if (!mQuit) { 114372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen mStop.push_back(channel); 115372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen mCondition.signal(); 116372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen } 117372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen} 118372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen 119372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissenint SoundPool::beginThread(void* arg) 120372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen{ 121372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen SoundPool* p = (SoundPool*)arg; 122372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen return p->run(); 123372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen} 124372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen 125372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissenint SoundPool::run() 126372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen{ 127372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen mRestartLock.lock(); 128372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen while (!mQuit) { 129372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen mCondition.wait(mRestartLock); 130372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen ALOGV("awake"); 131372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen if (mQuit) break; 132372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen 133372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen while (!mStop.empty()) { 134372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen SoundChannel* channel; 135372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen ALOGV("Getting channel from stop list"); 136372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen List<SoundChannel* >::iterator iter = mStop.begin(); 137372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen channel = *iter; 138372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen mStop.erase(iter); 139372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen mRestartLock.unlock(); 140372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen if (channel != 0) { 141372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen Mutex::Autolock lock(&mLock); 142372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen channel->stop(); 143372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen } 144372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen mRestartLock.lock(); 145372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen if (mQuit) break; 146372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen } 147372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen 148372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen while (!mRestart.empty()) { 149372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen SoundChannel* channel; 150372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen ALOGV("Getting channel from list"); 151372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen List<SoundChannel*>::iterator iter = mRestart.begin(); 152372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen channel = *iter; 153372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen mRestart.erase(iter); 154372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen mRestartLock.unlock(); 155372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen if (channel != 0) { 156372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen Mutex::Autolock lock(&mLock); 157372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen channel->nextEvent(); 158372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen } 159372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen mRestartLock.lock(); 160372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen if (mQuit) break; 161372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen } 162372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen } 163372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen 164372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen mStop.clear(); 165372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen mRestart.clear(); 166372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen mCondition.signal(); 167372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen mRestartLock.unlock(); 168372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen ALOGV("goodbye"); 169372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen return 0; 170372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen} 171372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen 172372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissenvoid SoundPool::quit() 173372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen{ 174372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen mRestartLock.lock(); 175372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen mQuit = true; 176372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen mCondition.signal(); 177372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen mCondition.wait(mRestartLock); 178372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen ALOGV("return from quit"); 179372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen mRestartLock.unlock(); 180372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen} 181372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen 182372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissenbool SoundPool::startThreads() 183372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen{ 184372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen createThreadEtc(beginThread, this, "SoundPool"); 185372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen if (mDecodeThread == NULL) 186372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen mDecodeThread = new SoundPoolThread(this); 187372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen return mDecodeThread != NULL; 188372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen} 189372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen 190372be8970c6ab68c295fb74dbb878ab1d443d90eMarco NelissenSoundChannel* SoundPool::findChannel(int channelID) 191372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen{ 192372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen for (int i = 0; i < mMaxChannels; ++i) { 193372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen if (mChannelPool[i].channelID() == channelID) { 194372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen return &mChannelPool[i]; 195372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen } 196372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen } 197372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen return NULL; 198372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen} 199372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen 200372be8970c6ab68c295fb74dbb878ab1d443d90eMarco NelissenSoundChannel* SoundPool::findNextChannel(int channelID) 201372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen{ 202372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen for (int i = 0; i < mMaxChannels; ++i) { 203372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen if (mChannelPool[i].nextChannelID() == channelID) { 204372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen return &mChannelPool[i]; 205372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen } 206372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen } 207372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen return NULL; 208372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen} 209372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen 210372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissenint SoundPool::load(int fd, int64_t offset, int64_t length, int priority __unused) 211372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen{ 212372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen ALOGV("load: fd=%d, offset=%" PRId64 ", length=%" PRId64 ", priority=%d", 213372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen fd, offset, length, priority); 214372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen Mutex::Autolock lock(&mLock); 215372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen sp<Sample> sample = new Sample(++mNextSampleID, fd, offset, length); 216372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen mSamples.add(sample->sampleID(), sample); 217372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen doLoad(sample); 218372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen return sample->sampleID(); 219372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen} 220372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen 221372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissenvoid SoundPool::doLoad(sp<Sample>& sample) 222372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen{ 223372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen ALOGV("doLoad: loading sample sampleID=%d", sample->sampleID()); 224372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen sample->startLoad(); 225372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen mDecodeThread->loadSample(sample->sampleID()); 226372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen} 227372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen 228372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissenbool SoundPool::unload(int sampleID) 229372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen{ 230372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen ALOGV("unload: sampleID=%d", sampleID); 231372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen Mutex::Autolock lock(&mLock); 232372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen return mSamples.removeItem(sampleID); 233372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen} 234372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen 235372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissenint SoundPool::play(int sampleID, float leftVolume, float rightVolume, 236372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen int priority, int loop, float rate) 237372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen{ 238372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen ALOGV("play sampleID=%d, leftVolume=%f, rightVolume=%f, priority=%d, loop=%d, rate=%f", 239372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen sampleID, leftVolume, rightVolume, priority, loop, rate); 240372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen sp<Sample> sample; 241372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen SoundChannel* channel; 242372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen int channelID; 243372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen 244372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen Mutex::Autolock lock(&mLock); 245372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen 246372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen if (mQuit) { 247372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen return 0; 248372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen } 249372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen // is sample ready? 250372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen sample = findSample(sampleID); 251372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen if ((sample == 0) || (sample->state() != Sample::READY)) { 252372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen ALOGW(" sample %d not READY", sampleID); 253372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen return 0; 254372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen } 255372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen 256372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen dump(); 257372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen 258372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen // allocate a channel 2590c4b81bd3ef3fd5eb0f7d1b8e2c6168b95020134Andy Hung channel = allocateChannel_l(priority, sampleID); 260372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen 261372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen // no channel allocated - return 0 262372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen if (!channel) { 263372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen ALOGV("No channel allocated"); 264372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen return 0; 265372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen } 266372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen 267372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen channelID = ++mNextChannelID; 268372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen 269372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen ALOGV("play channel %p state = %d", channel, channel->state()); 270372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen channel->play(sample, channelID, leftVolume, rightVolume, priority, loop, rate); 271372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen return channelID; 272372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen} 273372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen 2740c4b81bd3ef3fd5eb0f7d1b8e2c6168b95020134Andy HungSoundChannel* SoundPool::allocateChannel_l(int priority, int sampleID) 275372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen{ 276372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen List<SoundChannel*>::iterator iter; 277372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen SoundChannel* channel = NULL; 278372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen 2790c4b81bd3ef3fd5eb0f7d1b8e2c6168b95020134Andy Hung // check if channel for given sampleID still available 280372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen if (!mChannels.empty()) { 2810c4b81bd3ef3fd5eb0f7d1b8e2c6168b95020134Andy Hung for (iter = mChannels.begin(); iter != mChannels.end(); ++iter) { 2820c4b81bd3ef3fd5eb0f7d1b8e2c6168b95020134Andy Hung if (sampleID == (*iter)->getPrevSampleID() && (*iter)->state() == SoundChannel::IDLE) { 2830c4b81bd3ef3fd5eb0f7d1b8e2c6168b95020134Andy Hung channel = *iter; 2840c4b81bd3ef3fd5eb0f7d1b8e2c6168b95020134Andy Hung mChannels.erase(iter); 2850c4b81bd3ef3fd5eb0f7d1b8e2c6168b95020134Andy Hung ALOGV("Allocated recycled channel for same sampleID"); 2860c4b81bd3ef3fd5eb0f7d1b8e2c6168b95020134Andy Hung break; 2870c4b81bd3ef3fd5eb0f7d1b8e2c6168b95020134Andy Hung } 2880c4b81bd3ef3fd5eb0f7d1b8e2c6168b95020134Andy Hung } 2890c4b81bd3ef3fd5eb0f7d1b8e2c6168b95020134Andy Hung } 2900c4b81bd3ef3fd5eb0f7d1b8e2c6168b95020134Andy Hung 2910c4b81bd3ef3fd5eb0f7d1b8e2c6168b95020134Andy Hung // allocate any channel 2920c4b81bd3ef3fd5eb0f7d1b8e2c6168b95020134Andy Hung if (!channel && !mChannels.empty()) { 293372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen iter = mChannels.begin(); 294372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen if (priority >= (*iter)->priority()) { 295372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen channel = *iter; 296372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen mChannels.erase(iter); 297372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen ALOGV("Allocated active channel"); 298372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen } 299372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen } 300372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen 301372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen // update priority and put it back in the list 302372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen if (channel) { 303372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen channel->setPriority(priority); 304372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen for (iter = mChannels.begin(); iter != mChannels.end(); ++iter) { 305372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen if (priority < (*iter)->priority()) { 306372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen break; 307372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen } 308372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen } 309372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen mChannels.insert(iter, channel); 310372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen } 311372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen return channel; 312372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen} 313372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen 314372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen// move a channel from its current position to the front of the list 315372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissenvoid SoundPool::moveToFront_l(SoundChannel* channel) 316372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen{ 317372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen for (List<SoundChannel*>::iterator iter = mChannels.begin(); iter != mChannels.end(); ++iter) { 318372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen if (*iter == channel) { 319372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen mChannels.erase(iter); 320372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen mChannels.push_front(channel); 321372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen break; 322372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen } 323372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen } 324372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen} 325372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen 326372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissenvoid SoundPool::pause(int channelID) 327372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen{ 328372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen ALOGV("pause(%d)", channelID); 329372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen Mutex::Autolock lock(&mLock); 330372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen SoundChannel* channel = findChannel(channelID); 331372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen if (channel) { 332372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen channel->pause(); 333372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen } 334372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen} 335372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen 336372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissenvoid SoundPool::autoPause() 337372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen{ 338372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen ALOGV("autoPause()"); 339372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen Mutex::Autolock lock(&mLock); 340372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen for (int i = 0; i < mMaxChannels; ++i) { 341372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen SoundChannel* channel = &mChannelPool[i]; 342372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen channel->autoPause(); 343372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen } 344372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen} 345372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen 346372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissenvoid SoundPool::resume(int channelID) 347372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen{ 348372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen ALOGV("resume(%d)", channelID); 349372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen Mutex::Autolock lock(&mLock); 350372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen SoundChannel* channel = findChannel(channelID); 351372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen if (channel) { 352372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen channel->resume(); 353372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen } 354372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen} 355372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen 356372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissenvoid SoundPool::autoResume() 357372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen{ 358372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen ALOGV("autoResume()"); 359372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen Mutex::Autolock lock(&mLock); 360372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen for (int i = 0; i < mMaxChannels; ++i) { 361372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen SoundChannel* channel = &mChannelPool[i]; 362372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen channel->autoResume(); 363372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen } 364372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen} 365372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen 366372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissenvoid SoundPool::stop(int channelID) 367372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen{ 368372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen ALOGV("stop(%d)", channelID); 369372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen Mutex::Autolock lock(&mLock); 370372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen SoundChannel* channel = findChannel(channelID); 371372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen if (channel) { 372372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen channel->stop(); 373372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen } else { 374372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen channel = findNextChannel(channelID); 375372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen if (channel) 376372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen channel->clearNextEvent(); 377372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen } 378372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen} 379372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen 380372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissenvoid SoundPool::setVolume(int channelID, float leftVolume, float rightVolume) 381372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen{ 382372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen Mutex::Autolock lock(&mLock); 383372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen SoundChannel* channel = findChannel(channelID); 384372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen if (channel) { 385372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen channel->setVolume(leftVolume, rightVolume); 386372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen } 387372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen} 388372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen 389372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissenvoid SoundPool::setPriority(int channelID, int priority) 390372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen{ 391372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen ALOGV("setPriority(%d, %d)", channelID, priority); 392372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen Mutex::Autolock lock(&mLock); 393372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen SoundChannel* channel = findChannel(channelID); 394372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen if (channel) { 395372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen channel->setPriority(priority); 396372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen } 397372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen} 398372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen 399372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissenvoid SoundPool::setLoop(int channelID, int loop) 400372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen{ 401372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen ALOGV("setLoop(%d, %d)", channelID, loop); 402372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen Mutex::Autolock lock(&mLock); 403372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen SoundChannel* channel = findChannel(channelID); 404372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen if (channel) { 405372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen channel->setLoop(loop); 406372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen } 407372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen} 408372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen 409372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissenvoid SoundPool::setRate(int channelID, float rate) 410372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen{ 411372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen ALOGV("setRate(%d, %f)", channelID, rate); 412372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen Mutex::Autolock lock(&mLock); 413372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen SoundChannel* channel = findChannel(channelID); 414372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen if (channel) { 415372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen channel->setRate(rate); 416372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen } 417372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen} 418372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen 419372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen// call with lock held 420372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissenvoid SoundPool::done_l(SoundChannel* channel) 421372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen{ 422372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen ALOGV("done_l(%d)", channel->channelID()); 423372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen // if "stolen", play next event 424372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen if (channel->nextChannelID() != 0) { 425372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen ALOGV("add to restart list"); 426372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen addToRestartList(channel); 427372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen } 428372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen 429372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen // return to idle state 430372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen else { 431372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen ALOGV("move to front"); 432372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen moveToFront_l(channel); 433372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen } 434372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen} 435372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen 436372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissenvoid SoundPool::setCallback(SoundPoolCallback* callback, void* user) 437372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen{ 438372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen Mutex::Autolock lock(&mCallbackLock); 439372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen mCallback = callback; 440372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen mUserData = user; 441372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen} 442372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen 443372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissenvoid SoundPool::notify(SoundPoolEvent event) 444372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen{ 445372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen Mutex::Autolock lock(&mCallbackLock); 446372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen if (mCallback != NULL) { 447372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen mCallback(event, this, mUserData); 448372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen } 449372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen} 450372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen 451372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissenvoid SoundPool::dump() 452372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen{ 453372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen for (int i = 0; i < mMaxChannels; ++i) { 454372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen mChannelPool[i].dump(); 455372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen } 456372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen} 457372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen 458372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen 459372be8970c6ab68c295fb74dbb878ab1d443d90eMarco NelissenSample::Sample(int sampleID, int fd, int64_t offset, int64_t length) 460372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen{ 461372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen init(); 462372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen mSampleID = sampleID; 463372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen mFd = dup(fd); 464372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen mOffset = offset; 465372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen mLength = length; 466372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen ALOGV("create sampleID=%d, fd=%d, offset=%" PRId64 " length=%" PRId64, 467372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen mSampleID, mFd, mLength, mOffset); 468372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen} 469372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen 470372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissenvoid Sample::init() 471372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen{ 472372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen mSize = 0; 473372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen mRefCount = 0; 474372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen mSampleID = 0; 475372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen mState = UNLOADED; 476372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen mFd = -1; 477372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen mOffset = 0; 478372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen mLength = 0; 479372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen} 480372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen 481372be8970c6ab68c295fb74dbb878ab1d443d90eMarco NelissenSample::~Sample() 482372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen{ 483372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen ALOGV("Sample::destructor sampleID=%d, fd=%d", mSampleID, mFd); 484372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen if (mFd > 0) { 485372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen ALOGV("close(%d)", mFd); 486372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen ::close(mFd); 487372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen } 488372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen} 489372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen 490372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissenstatic status_t decode(int fd, int64_t offset, int64_t length, 491372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen uint32_t *rate, int *numChannels, audio_format_t *audioFormat, 492372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen sp<MemoryHeapBase> heap, size_t *memsize) { 493372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen 4946cd6110773bf83638f21a76d388dc2b7037df0d8Marco Nelissen ALOGV("fd %d, offset %" PRId64 ", size %" PRId64, fd, offset, length); 495372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen AMediaExtractor *ex = AMediaExtractor_new(); 496372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen status_t err = AMediaExtractor_setDataSourceFd(ex, fd, offset, length); 497372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen 498372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen if (err != AMEDIA_OK) { 49906524dccbc35cdeed92d0b5ec96b42d43518d7edMarco Nelissen AMediaExtractor_delete(ex); 500372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen return err; 501372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen } 502372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen 503372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen *audioFormat = AUDIO_FORMAT_PCM_16_BIT; 504372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen 505372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen size_t numTracks = AMediaExtractor_getTrackCount(ex); 506372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen for (size_t i = 0; i < numTracks; i++) { 507372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen AMediaFormat *format = AMediaExtractor_getTrackFormat(ex, i); 508372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen const char *mime; 509372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen if (!AMediaFormat_getString(format, AMEDIAFORMAT_KEY_MIME, &mime)) { 510372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen AMediaExtractor_delete(ex); 511372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen AMediaFormat_delete(format); 512372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen return UNKNOWN_ERROR; 513372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen } 514372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen if (strncmp(mime, "audio/", 6) == 0) { 515372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen 516372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen AMediaCodec *codec = AMediaCodec_createDecoderByType(mime); 517372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen if (AMediaCodec_configure(codec, format, 518372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen NULL /* window */, NULL /* drm */, 0 /* flags */) != AMEDIA_OK 519372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen || AMediaCodec_start(codec) != AMEDIA_OK 520372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen || AMediaExtractor_selectTrack(ex, i) != AMEDIA_OK) { 521372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen AMediaExtractor_delete(ex); 522372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen AMediaCodec_delete(codec); 523372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen AMediaFormat_delete(format); 524372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen return UNKNOWN_ERROR; 525372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen } 526372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen 527372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen bool sawInputEOS = false; 528372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen bool sawOutputEOS = false; 529372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen uint8_t* writePos = static_cast<uint8_t*>(heap->getBase()); 530372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen size_t available = heap->getSize(); 531372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen size_t written = 0; 532372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen 533372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen AMediaFormat_delete(format); 534372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen format = AMediaCodec_getOutputFormat(codec); 535372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen 536372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen while (!sawOutputEOS) { 537372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen if (!sawInputEOS) { 538372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen ssize_t bufidx = AMediaCodec_dequeueInputBuffer(codec, 5000); 5396cd6110773bf83638f21a76d388dc2b7037df0d8Marco Nelissen ALOGV("input buffer %zd", bufidx); 540372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen if (bufidx >= 0) { 541372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen size_t bufsize; 542372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen uint8_t *buf = AMediaCodec_getInputBuffer(codec, bufidx, &bufsize); 543372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen int sampleSize = AMediaExtractor_readSampleData(ex, buf, bufsize); 544372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen ALOGV("read %d", sampleSize); 545372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen if (sampleSize < 0) { 546372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen sampleSize = 0; 547372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen sawInputEOS = true; 548372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen ALOGV("EOS"); 549372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen } 550372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen int64_t presentationTimeUs = AMediaExtractor_getSampleTime(ex); 551372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen 552372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen AMediaCodec_queueInputBuffer(codec, bufidx, 553372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen 0 /* offset */, sampleSize, presentationTimeUs, 554372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen sawInputEOS ? AMEDIACODEC_BUFFER_FLAG_END_OF_STREAM : 0); 555372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen AMediaExtractor_advance(ex); 556372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen } 557372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen } 558372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen 559372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen AMediaCodecBufferInfo info; 560372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen int status = AMediaCodec_dequeueOutputBuffer(codec, &info, 1); 561372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen ALOGV("dequeueoutput returned: %d", status); 562372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen if (status >= 0) { 563372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen if (info.flags & AMEDIACODEC_BUFFER_FLAG_END_OF_STREAM) { 564372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen ALOGV("output EOS"); 565372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen sawOutputEOS = true; 566372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen } 567372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen ALOGV("got decoded buffer size %d", info.size); 568372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen 569372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen uint8_t *buf = AMediaCodec_getOutputBuffer(codec, status, NULL /* out_size */); 570372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen size_t dataSize = info.size; 571372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen if (dataSize > available) { 572372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen dataSize = available; 573372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen } 574372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen memcpy(writePos, buf + info.offset, dataSize); 575372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen writePos += dataSize; 576372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen written += dataSize; 577372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen available -= dataSize; 578372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen AMediaCodec_releaseOutputBuffer(codec, status, false /* render */); 579372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen if (available == 0) { 580372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen // there might be more data, but there's no space for it 581372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen sawOutputEOS = true; 582372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen } 583372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen } else if (status == AMEDIACODEC_INFO_OUTPUT_BUFFERS_CHANGED) { 584372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen ALOGV("output buffers changed"); 585372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen } else if (status == AMEDIACODEC_INFO_OUTPUT_FORMAT_CHANGED) { 586372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen AMediaFormat_delete(format); 587372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen format = AMediaCodec_getOutputFormat(codec); 588372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen ALOGV("format changed to: %s", AMediaFormat_toString(format)); 589372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen } else if (status == AMEDIACODEC_INFO_TRY_AGAIN_LATER) { 590372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen ALOGV("no output buffer right now"); 591372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen } else { 592372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen ALOGV("unexpected info code: %d", status); 593372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen } 594372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen } 595372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen 596372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen AMediaCodec_stop(codec); 597372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen AMediaCodec_delete(codec); 598372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen AMediaExtractor_delete(ex); 599372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen if (!AMediaFormat_getInt32(format, AMEDIAFORMAT_KEY_SAMPLE_RATE, (int32_t*) rate) || 600372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen !AMediaFormat_getInt32(format, AMEDIAFORMAT_KEY_CHANNEL_COUNT, numChannels)) { 601372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen AMediaFormat_delete(format); 602372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen return UNKNOWN_ERROR; 603372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen } 604372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen AMediaFormat_delete(format); 605372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen *memsize = written; 606372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen return OK; 607372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen } 608372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen AMediaFormat_delete(format); 609372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen } 610372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen AMediaExtractor_delete(ex); 611372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen return UNKNOWN_ERROR; 612372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen} 613372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen 614372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissenstatus_t Sample::doLoad() 615372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen{ 616372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen uint32_t sampleRate; 617372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen int numChannels; 618372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen audio_format_t format; 619372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen status_t status; 620372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen mHeap = new MemoryHeapBase(kDefaultHeapSize); 621372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen 622372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen ALOGV("Start decode"); 623372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen status = decode(mFd, mOffset, mLength, &sampleRate, &numChannels, &format, 624372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen mHeap, &mSize); 625372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen ALOGV("close(%d)", mFd); 626372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen ::close(mFd); 627372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen mFd = -1; 628372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen if (status != NO_ERROR) { 629372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen ALOGE("Unable to load sample"); 630372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen goto error; 631372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen } 632372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen ALOGV("pointer = %p, size = %zu, sampleRate = %u, numChannels = %d", 633372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen mHeap->getBase(), mSize, sampleRate, numChannels); 634372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen 635372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen if (sampleRate > kMaxSampleRate) { 636372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen ALOGE("Sample rate (%u) out of range", sampleRate); 637372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen status = BAD_VALUE; 638372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen goto error; 639372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen } 640372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen 641372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen if ((numChannels < 1) || (numChannels > 2)) { 642372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen ALOGE("Sample channel count (%d) out of range", numChannels); 643372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen status = BAD_VALUE; 644372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen goto error; 645372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen } 646372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen 647372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen mData = new MemoryBase(mHeap, 0, mSize); 648372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen mSampleRate = sampleRate; 649372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen mNumChannels = numChannels; 650372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen mFormat = format; 651372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen mState = READY; 652372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen return NO_ERROR; 653372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen 654372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissenerror: 655372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen mHeap.clear(); 656372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen return status; 657372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen} 658372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen 659372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen 660372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissenvoid SoundChannel::init(SoundPool* soundPool) 661372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen{ 662372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen mSoundPool = soundPool; 6630c4b81bd3ef3fd5eb0f7d1b8e2c6168b95020134Andy Hung mPrevSampleID = -1; 664372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen} 665372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen 666372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen// call with sound pool lock held 667372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissenvoid SoundChannel::play(const sp<Sample>& sample, int nextChannelID, float leftVolume, 668372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen float rightVolume, int priority, int loop, float rate) 669372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen{ 670372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen sp<AudioTrack> oldTrack; 671372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen sp<AudioTrack> newTrack; 6720c4b81bd3ef3fd5eb0f7d1b8e2c6168b95020134Andy Hung status_t status = NO_ERROR; 673372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen 674372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen { // scope for the lock 675372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen Mutex::Autolock lock(&mLock); 676372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen 677372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen ALOGV("SoundChannel::play %p: sampleID=%d, channelID=%d, leftVolume=%f, rightVolume=%f," 678372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen " priority=%d, loop=%d, rate=%f", 679372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen this, sample->sampleID(), nextChannelID, leftVolume, rightVolume, 680372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen priority, loop, rate); 681372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen 682372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen // if not idle, this voice is being stolen 683372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen if (mState != IDLE) { 684372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen ALOGV("channel %d stolen - event queued for channel %d", channelID(), nextChannelID); 685372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen mNextEvent.set(sample, nextChannelID, leftVolume, rightVolume, priority, loop, rate); 686372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen stop_l(); 687372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen return; 688372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen } 689372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen 690372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen // initialize track 691372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen size_t afFrameCount; 692372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen uint32_t afSampleRate; 693372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen audio_stream_type_t streamType = audio_attributes_to_stream_type(mSoundPool->attributes()); 694372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen if (AudioSystem::getOutputFrameCount(&afFrameCount, streamType) != NO_ERROR) { 695372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen afFrameCount = kDefaultFrameCount; 696372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen } 697372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen if (AudioSystem::getOutputSamplingRate(&afSampleRate, streamType) != NO_ERROR) { 698372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen afSampleRate = kDefaultSampleRate; 699372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen } 700372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen int numChannels = sample->numChannels(); 701372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen uint32_t sampleRate = uint32_t(float(sample->sampleRate()) * rate + 0.5); 702372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen size_t frameCount = 0; 703372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen 704372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen if (loop) { 705372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen frameCount = sample->size()/numChannels/ 706372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen ((sample->format() == AUDIO_FORMAT_PCM_16_BIT) ? sizeof(int16_t) : sizeof(uint8_t)); 707372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen } 708372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen 709372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen#ifndef USE_SHARED_MEM_BUFFER 710372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen uint32_t totalFrames = (kDefaultBufferCount * afFrameCount * sampleRate) / afSampleRate; 711372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen // Ensure minimum audio buffer size in case of short looped sample 712372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen if(frameCount < totalFrames) { 713372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen frameCount = totalFrames; 714372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen } 715372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen#endif 716372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen 7170c4b81bd3ef3fd5eb0f7d1b8e2c6168b95020134Andy Hung if (!mAudioTrack.get() || mPrevSampleID != sample->sampleID()) { 7180c4b81bd3ef3fd5eb0f7d1b8e2c6168b95020134Andy Hung // mToggle toggles each time a track is started on a given channel. 7190c4b81bd3ef3fd5eb0f7d1b8e2c6168b95020134Andy Hung // The toggle is concatenated with the SoundChannel address and passed to AudioTrack 7200c4b81bd3ef3fd5eb0f7d1b8e2c6168b95020134Andy Hung // as callback user data. This enables the detection of callbacks received from the old 7210c4b81bd3ef3fd5eb0f7d1b8e2c6168b95020134Andy Hung // audio track while the new one is being started and avoids processing them with 7220c4b81bd3ef3fd5eb0f7d1b8e2c6168b95020134Andy Hung // wrong audio audio buffer size (mAudioBufferSize) 7230c4b81bd3ef3fd5eb0f7d1b8e2c6168b95020134Andy Hung unsigned long toggle = mToggle ^ 1; 7240c4b81bd3ef3fd5eb0f7d1b8e2c6168b95020134Andy Hung void *userData = (void *)((unsigned long)this | toggle); 7250c4b81bd3ef3fd5eb0f7d1b8e2c6168b95020134Andy Hung audio_channel_mask_t channelMask = audio_channel_out_mask_from_count(numChannels); 7260c4b81bd3ef3fd5eb0f7d1b8e2c6168b95020134Andy Hung 7270c4b81bd3ef3fd5eb0f7d1b8e2c6168b95020134Andy Hung // do not create a new audio track if current track is compatible with sample parameters 7280c4b81bd3ef3fd5eb0f7d1b8e2c6168b95020134Andy Hung #ifdef USE_SHARED_MEM_BUFFER 7290c4b81bd3ef3fd5eb0f7d1b8e2c6168b95020134Andy Hung newTrack = new AudioTrack(streamType, sampleRate, sample->format(), 7300c4b81bd3ef3fd5eb0f7d1b8e2c6168b95020134Andy Hung channelMask, sample->getIMemory(), AUDIO_OUTPUT_FLAG_FAST, callback, userData); 7310c4b81bd3ef3fd5eb0f7d1b8e2c6168b95020134Andy Hung #else 7320c4b81bd3ef3fd5eb0f7d1b8e2c6168b95020134Andy Hung uint32_t bufferFrames = (totalFrames + (kDefaultBufferCount - 1)) / kDefaultBufferCount; 7330c4b81bd3ef3fd5eb0f7d1b8e2c6168b95020134Andy Hung newTrack = new AudioTrack(streamType, sampleRate, sample->format(), 7340c4b81bd3ef3fd5eb0f7d1b8e2c6168b95020134Andy Hung channelMask, frameCount, AUDIO_OUTPUT_FLAG_FAST, callback, userData, 7350c4b81bd3ef3fd5eb0f7d1b8e2c6168b95020134Andy Hung bufferFrames); 7360c4b81bd3ef3fd5eb0f7d1b8e2c6168b95020134Andy Hung #endif 7370c4b81bd3ef3fd5eb0f7d1b8e2c6168b95020134Andy Hung oldTrack = mAudioTrack; 7380c4b81bd3ef3fd5eb0f7d1b8e2c6168b95020134Andy Hung status = newTrack->initCheck(); 7390c4b81bd3ef3fd5eb0f7d1b8e2c6168b95020134Andy Hung if (status != NO_ERROR) { 7400c4b81bd3ef3fd5eb0f7d1b8e2c6168b95020134Andy Hung ALOGE("Error creating AudioTrack"); 7410c4b81bd3ef3fd5eb0f7d1b8e2c6168b95020134Andy Hung goto exit; 7420c4b81bd3ef3fd5eb0f7d1b8e2c6168b95020134Andy Hung } 7430c4b81bd3ef3fd5eb0f7d1b8e2c6168b95020134Andy Hung // From now on, AudioTrack callbacks received with previous toggle value will be ignored. 7440c4b81bd3ef3fd5eb0f7d1b8e2c6168b95020134Andy Hung mToggle = toggle; 7450c4b81bd3ef3fd5eb0f7d1b8e2c6168b95020134Andy Hung mAudioTrack = newTrack; 7460c4b81bd3ef3fd5eb0f7d1b8e2c6168b95020134Andy Hung } else { 7470c4b81bd3ef3fd5eb0f7d1b8e2c6168b95020134Andy Hung newTrack = mAudioTrack; 7480c4b81bd3ef3fd5eb0f7d1b8e2c6168b95020134Andy Hung ALOGV("reusing track %p for sample %d", mAudioTrack.get(), sample->sampleID()); 749372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen } 750372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen newTrack->setVolume(leftVolume, rightVolume); 751372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen newTrack->setLoop(0, frameCount, loop); 752372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen mPos = 0; 753372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen mSample = sample; 754372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen mChannelID = nextChannelID; 755372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen mPriority = priority; 756372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen mLoop = loop; 757372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen mLeftVolume = leftVolume; 758372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen mRightVolume = rightVolume; 759372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen mNumChannels = numChannels; 760372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen mRate = rate; 761372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen clearNextEvent(); 762372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen mState = PLAYING; 763372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen mAudioTrack->start(); 764372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen mAudioBufferSize = newTrack->frameCount()*newTrack->frameSize(); 765372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen } 766372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen 767372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissenexit: 768372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen ALOGV("delete oldTrack %p", oldTrack.get()); 769372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen if (status != NO_ERROR) { 770372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen mAudioTrack.clear(); 771372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen } 772372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen} 773372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen 774372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissenvoid SoundChannel::nextEvent() 775372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen{ 776372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen sp<Sample> sample; 777372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen int nextChannelID; 778372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen float leftVolume; 779372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen float rightVolume; 780372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen int priority; 781372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen int loop; 782372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen float rate; 783372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen 784372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen // check for valid event 785372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen { 786372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen Mutex::Autolock lock(&mLock); 787372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen nextChannelID = mNextEvent.channelID(); 788372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen if (nextChannelID == 0) { 789372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen ALOGV("stolen channel has no event"); 790372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen return; 791372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen } 792372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen 793372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen sample = mNextEvent.sample(); 794372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen leftVolume = mNextEvent.leftVolume(); 795372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen rightVolume = mNextEvent.rightVolume(); 796372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen priority = mNextEvent.priority(); 797372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen loop = mNextEvent.loop(); 798372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen rate = mNextEvent.rate(); 799372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen } 800372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen 801372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen ALOGV("Starting stolen channel %d -> %d", channelID(), nextChannelID); 802372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen play(sample, nextChannelID, leftVolume, rightVolume, priority, loop, rate); 803372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen} 804372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen 805372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissenvoid SoundChannel::callback(int event, void* user, void *info) 806372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen{ 807372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen SoundChannel* channel = static_cast<SoundChannel*>((void *)((unsigned long)user & ~1)); 808372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen 809372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen channel->process(event, info, (unsigned long)user & 1); 810372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen} 811372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen 812372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissenvoid SoundChannel::process(int event, void *info, unsigned long toggle) 813372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen{ 814372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen //ALOGV("process(%d)", mChannelID); 815372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen 816372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen Mutex::Autolock lock(&mLock); 817372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen 818372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen AudioTrack::Buffer* b = NULL; 819372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen if (event == AudioTrack::EVENT_MORE_DATA) { 820372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen b = static_cast<AudioTrack::Buffer *>(info); 821372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen } 822372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen 823372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen if (mToggle != toggle) { 824372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen ALOGV("process wrong toggle %p channel %d", this, mChannelID); 825372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen if (b != NULL) { 826372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen b->size = 0; 827372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen } 828372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen return; 829372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen } 830372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen 831372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen sp<Sample> sample = mSample; 832372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen 833372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen// ALOGV("SoundChannel::process event %d", event); 834372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen 835372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen if (event == AudioTrack::EVENT_MORE_DATA) { 836372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen 837372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen // check for stop state 838372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen if (b->size == 0) return; 839372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen 840372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen if (mState == IDLE) { 841372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen b->size = 0; 842372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen return; 843372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen } 844372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen 845372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen if (sample != 0) { 846372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen // fill buffer 847372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen uint8_t* q = (uint8_t*) b->i8; 848372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen size_t count = 0; 849372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen 850372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen if (mPos < (int)sample->size()) { 851372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen uint8_t* p = sample->data() + mPos; 852372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen count = sample->size() - mPos; 853372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen if (count > b->size) { 854372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen count = b->size; 855372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen } 856372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen memcpy(q, p, count); 857372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen// ALOGV("fill: q=%p, p=%p, mPos=%u, b->size=%u, count=%d", q, p, mPos, b->size, 858372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen// count); 859372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen } else if (mPos < mAudioBufferSize) { 860372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen count = mAudioBufferSize - mPos; 861372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen if (count > b->size) { 862372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen count = b->size; 863372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen } 864372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen memset(q, 0, count); 865372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen// ALOGV("fill extra: q=%p, mPos=%u, b->size=%u, count=%d", q, mPos, b->size, count); 866372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen } 867372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen 868372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen mPos += count; 869372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen b->size = count; 870372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen //ALOGV("buffer=%p, [0]=%d", b->i16, b->i16[0]); 871372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen } 872372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen } else if (event == AudioTrack::EVENT_UNDERRUN || event == AudioTrack::EVENT_BUFFER_END) { 873372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen ALOGV("process %p channel %d event %s", 874372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen this, mChannelID, (event == AudioTrack::EVENT_UNDERRUN) ? "UNDERRUN" : 875372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen "BUFFER_END"); 876372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen mSoundPool->addToStopList(this); 877372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen } else if (event == AudioTrack::EVENT_LOOP_END) { 878372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen ALOGV("End loop %p channel %d", this, mChannelID); 879372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen } else if (event == AudioTrack::EVENT_NEW_IAUDIOTRACK) { 880372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen ALOGV("process %p channel %d NEW_IAUDIOTRACK", this, mChannelID); 881372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen } else { 882372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen ALOGW("SoundChannel::process unexpected event %d", event); 883372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen } 884372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen} 885372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen 886372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen 887372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen// call with lock held 888372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissenbool SoundChannel::doStop_l() 889372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen{ 890372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen if (mState != IDLE) { 891372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen setVolume_l(0, 0); 892372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen ALOGV("stop"); 893372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen mAudioTrack->stop(); 8940c4b81bd3ef3fd5eb0f7d1b8e2c6168b95020134Andy Hung mPrevSampleID = mSample->sampleID(); 895372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen mSample.clear(); 896372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen mState = IDLE; 897372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen mPriority = IDLE_PRIORITY; 898372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen return true; 899372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen } 900372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen return false; 901372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen} 902372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen 903372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen// call with lock held and sound pool lock held 904372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissenvoid SoundChannel::stop_l() 905372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen{ 906372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen if (doStop_l()) { 907372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen mSoundPool->done_l(this); 908372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen } 909372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen} 910372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen 911372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen// call with sound pool lock held 912372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissenvoid SoundChannel::stop() 913372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen{ 914372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen bool stopped; 915372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen { 916372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen Mutex::Autolock lock(&mLock); 917372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen stopped = doStop_l(); 918372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen } 919372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen 920372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen if (stopped) { 921372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen mSoundPool->done_l(this); 922372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen } 923372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen} 924372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen 925372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen//FIXME: Pause is a little broken right now 926372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissenvoid SoundChannel::pause() 927372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen{ 928372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen Mutex::Autolock lock(&mLock); 929372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen if (mState == PLAYING) { 930372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen ALOGV("pause track"); 931372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen mState = PAUSED; 932372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen mAudioTrack->pause(); 933372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen } 934372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen} 935372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen 936372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissenvoid SoundChannel::autoPause() 937372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen{ 938372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen Mutex::Autolock lock(&mLock); 939372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen if (mState == PLAYING) { 940372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen ALOGV("pause track"); 941372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen mState = PAUSED; 942372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen mAutoPaused = true; 943372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen mAudioTrack->pause(); 944372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen } 945372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen} 946372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen 947372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissenvoid SoundChannel::resume() 948372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen{ 949372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen Mutex::Autolock lock(&mLock); 950372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen if (mState == PAUSED) { 951372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen ALOGV("resume track"); 952372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen mState = PLAYING; 953372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen mAutoPaused = false; 954372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen mAudioTrack->start(); 955372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen } 956372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen} 957372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen 958372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissenvoid SoundChannel::autoResume() 959372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen{ 960372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen Mutex::Autolock lock(&mLock); 961372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen if (mAutoPaused && (mState == PAUSED)) { 962372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen ALOGV("resume track"); 963372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen mState = PLAYING; 964372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen mAutoPaused = false; 965372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen mAudioTrack->start(); 966372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen } 967372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen} 968372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen 969372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissenvoid SoundChannel::setRate(float rate) 970372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen{ 971372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen Mutex::Autolock lock(&mLock); 972372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen if (mAudioTrack != NULL && mSample != 0) { 973372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen uint32_t sampleRate = uint32_t(float(mSample->sampleRate()) * rate + 0.5); 974372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen mAudioTrack->setSampleRate(sampleRate); 975372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen mRate = rate; 976372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen } 977372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen} 978372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen 979372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen// call with lock held 980372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissenvoid SoundChannel::setVolume_l(float leftVolume, float rightVolume) 981372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen{ 982372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen mLeftVolume = leftVolume; 983372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen mRightVolume = rightVolume; 984372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen if (mAudioTrack != NULL) 985372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen mAudioTrack->setVolume(leftVolume, rightVolume); 986372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen} 987372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen 988372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissenvoid SoundChannel::setVolume(float leftVolume, float rightVolume) 989372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen{ 990372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen Mutex::Autolock lock(&mLock); 991372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen setVolume_l(leftVolume, rightVolume); 992372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen} 993372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen 994372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissenvoid SoundChannel::setLoop(int loop) 995372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen{ 996372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen Mutex::Autolock lock(&mLock); 997372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen if (mAudioTrack != NULL && mSample != 0) { 998372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen uint32_t loopEnd = mSample->size()/mNumChannels/ 999372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen ((mSample->format() == AUDIO_FORMAT_PCM_16_BIT) ? sizeof(int16_t) : sizeof(uint8_t)); 1000372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen mAudioTrack->setLoop(0, loopEnd, loop); 1001372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen mLoop = loop; 1002372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen } 1003372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen} 1004372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen 1005372be8970c6ab68c295fb74dbb878ab1d443d90eMarco NelissenSoundChannel::~SoundChannel() 1006372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen{ 1007372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen ALOGV("SoundChannel destructor %p", this); 1008372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen { 1009372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen Mutex::Autolock lock(&mLock); 1010372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen clearNextEvent(); 1011372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen doStop_l(); 1012372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen } 1013372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen // do not call AudioTrack destructor with mLock held as it will wait for the AudioTrack 1014372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen // callback thread to exit which may need to execute process() and acquire the mLock. 1015372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen mAudioTrack.clear(); 1016372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen} 1017372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen 1018372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissenvoid SoundChannel::dump() 1019372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen{ 1020372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen ALOGV("mState = %d mChannelID=%d, mNumChannels=%d, mPos = %d, mPriority=%d, mLoop=%d", 1021372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen mState, mChannelID, mNumChannels, mPos, mPriority, mLoop); 1022372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen} 1023372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen 1024372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissenvoid SoundEvent::set(const sp<Sample>& sample, int channelID, float leftVolume, 1025372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen float rightVolume, int priority, int loop, float rate) 1026372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen{ 1027372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen mSample = sample; 1028372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen mChannelID = channelID; 1029372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen mLeftVolume = leftVolume; 1030372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen mRightVolume = rightVolume; 1031372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen mPriority = priority; 1032372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen mLoop = loop; 1033372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen mRate =rate; 1034372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen} 1035372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen 1036372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen} // end namespace android 1037