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 "SoundPool.h" 28372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen#include "SoundPoolThread.h" 29372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen#include <media/AudioPolicyHelper.h> 30c8ed45d38f3b42e06c9e0980e133a84181752b5eColin Cross#include <media/NdkMediaCodec.h> 31c8ed45d38f3b42e06c9e0980e133a84181752b5eColin Cross#include <media/NdkMediaExtractor.h> 32c8ed45d38f3b42e06c9e0980e133a84181752b5eColin Cross#include <media/NdkMediaFormat.h> 33372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen 34372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissennamespace android 35372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen{ 36372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen 37372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissenint kDefaultBufferCount = 4; 38372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissenuint32_t kMaxSampleRate = 48000; 39372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissenuint32_t kDefaultSampleRate = 44100; 40372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissenuint32_t kDefaultFrameCount = 1200; 41372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissensize_t kDefaultHeapSize = 1024 * 1024; // 1MB 42372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen 43372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen 44372be8970c6ab68c295fb74dbb878ab1d443d90eMarco NelissenSoundPool::SoundPool(int maxChannels, const audio_attributes_t* pAttributes) 45372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen{ 46372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen ALOGV("SoundPool constructor: maxChannels=%d, attr.usage=%d, attr.flags=0x%x, attr.tags=%s", 47372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen maxChannels, pAttributes->usage, pAttributes->flags, pAttributes->tags); 48372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen 49372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen // check limits 50372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen mMaxChannels = maxChannels; 51372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen if (mMaxChannels < 1) { 52372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen mMaxChannels = 1; 53372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen } 54372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen else if (mMaxChannels > 32) { 55372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen mMaxChannels = 32; 56372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen } 57372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen ALOGW_IF(maxChannels != mMaxChannels, "App requested %d channels", maxChannels); 58372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen 59372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen mQuit = false; 608e48c6939bd81dcbc596f0a4b11bfaea73aed00bJean-Michel Trivi mMuted = false; 61372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen mDecodeThread = 0; 62372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen memcpy(&mAttributes, pAttributes, sizeof(audio_attributes_t)); 63372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen mAllocated = 0; 64372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen mNextSampleID = 0; 65372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen mNextChannelID = 0; 66372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen 67372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen mCallback = 0; 68372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen mUserData = 0; 69372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen 70372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen mChannelPool = new SoundChannel[mMaxChannels]; 71372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen for (int i = 0; i < mMaxChannels; ++i) { 72372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen mChannelPool[i].init(this); 73372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen mChannels.push_back(&mChannelPool[i]); 74372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen } 75372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen 76372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen // start decode thread 77372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen startThreads(); 78372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen} 79372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen 80372be8970c6ab68c295fb74dbb878ab1d443d90eMarco NelissenSoundPool::~SoundPool() 81372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen{ 82372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen ALOGV("SoundPool destructor"); 83372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen mDecodeThread->quit(); 84372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen quit(); 85372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen 86372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen Mutex::Autolock lock(&mLock); 87372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen 88372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen mChannels.clear(); 89372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen if (mChannelPool) 90372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen delete [] mChannelPool; 91372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen // clean up samples 92372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen ALOGV("clear samples"); 93372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen mSamples.clear(); 94372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen 95372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen if (mDecodeThread) 96372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen delete mDecodeThread; 97372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen} 98372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen 99372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissenvoid SoundPool::addToRestartList(SoundChannel* channel) 100372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen{ 101372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen Mutex::Autolock lock(&mRestartLock); 102372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen if (!mQuit) { 103372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen mRestart.push_back(channel); 104372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen mCondition.signal(); 105372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen } 106372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen} 107372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen 108372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissenvoid SoundPool::addToStopList(SoundChannel* channel) 109372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen{ 110372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen Mutex::Autolock lock(&mRestartLock); 111372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen if (!mQuit) { 112372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen mStop.push_back(channel); 113372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen mCondition.signal(); 114372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen } 115372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen} 116372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen 117372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissenint SoundPool::beginThread(void* arg) 118372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen{ 119372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen SoundPool* p = (SoundPool*)arg; 120372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen return p->run(); 121372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen} 122372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen 123372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissenint SoundPool::run() 124372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen{ 125372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen mRestartLock.lock(); 126372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen while (!mQuit) { 127372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen mCondition.wait(mRestartLock); 128372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen ALOGV("awake"); 129372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen if (mQuit) break; 130372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen 131372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen while (!mStop.empty()) { 132372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen SoundChannel* channel; 133372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen ALOGV("Getting channel from stop list"); 134372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen List<SoundChannel* >::iterator iter = mStop.begin(); 135372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen channel = *iter; 136372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen mStop.erase(iter); 137372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen mRestartLock.unlock(); 138372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen if (channel != 0) { 139372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen Mutex::Autolock lock(&mLock); 140372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen channel->stop(); 141372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen } 142372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen mRestartLock.lock(); 143372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen if (mQuit) break; 144372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen } 145372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen 146372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen while (!mRestart.empty()) { 147372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen SoundChannel* channel; 148372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen ALOGV("Getting channel from list"); 149372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen List<SoundChannel*>::iterator iter = mRestart.begin(); 150372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen channel = *iter; 151372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen mRestart.erase(iter); 152372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen mRestartLock.unlock(); 153372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen if (channel != 0) { 154372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen Mutex::Autolock lock(&mLock); 155372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen channel->nextEvent(); 156372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen } 157372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen mRestartLock.lock(); 158372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen if (mQuit) break; 159372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen } 160372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen } 161372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen 162372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen mStop.clear(); 163372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen mRestart.clear(); 164372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen mCondition.signal(); 165372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen mRestartLock.unlock(); 166372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen ALOGV("goodbye"); 167372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen return 0; 168372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen} 169372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen 170372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissenvoid SoundPool::quit() 171372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen{ 172372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen mRestartLock.lock(); 173372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen mQuit = true; 174372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen mCondition.signal(); 175372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen mCondition.wait(mRestartLock); 176372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen ALOGV("return from quit"); 177372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen mRestartLock.unlock(); 178372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen} 179372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen 180372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissenbool SoundPool::startThreads() 181372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen{ 182372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen createThreadEtc(beginThread, this, "SoundPool"); 183372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen if (mDecodeThread == NULL) 184372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen mDecodeThread = new SoundPoolThread(this); 185372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen return mDecodeThread != NULL; 186372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen} 187372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen 1880275a982abecee683f16c827d405eafe51fb67aeAndy Hungsp<Sample> SoundPool::findSample(int sampleID) 1890275a982abecee683f16c827d405eafe51fb67aeAndy Hung{ 1900275a982abecee683f16c827d405eafe51fb67aeAndy Hung Mutex::Autolock lock(&mLock); 1910275a982abecee683f16c827d405eafe51fb67aeAndy Hung return findSample_l(sampleID); 1920275a982abecee683f16c827d405eafe51fb67aeAndy Hung} 1930275a982abecee683f16c827d405eafe51fb67aeAndy Hung 1940275a982abecee683f16c827d405eafe51fb67aeAndy Hungsp<Sample> SoundPool::findSample_l(int sampleID) 1950275a982abecee683f16c827d405eafe51fb67aeAndy Hung{ 1960275a982abecee683f16c827d405eafe51fb67aeAndy Hung return mSamples.valueFor(sampleID); 1970275a982abecee683f16c827d405eafe51fb67aeAndy Hung} 1980275a982abecee683f16c827d405eafe51fb67aeAndy Hung 199372be8970c6ab68c295fb74dbb878ab1d443d90eMarco NelissenSoundChannel* SoundPool::findChannel(int channelID) 200372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen{ 201372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen for (int i = 0; i < mMaxChannels; ++i) { 202372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen if (mChannelPool[i].channelID() == channelID) { 203372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen return &mChannelPool[i]; 204372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen } 205372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen } 206372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen return NULL; 207372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen} 208372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen 209372be8970c6ab68c295fb74dbb878ab1d443d90eMarco NelissenSoundChannel* SoundPool::findNextChannel(int channelID) 210372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen{ 211372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen for (int i = 0; i < mMaxChannels; ++i) { 212372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen if (mChannelPool[i].nextChannelID() == channelID) { 213372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen return &mChannelPool[i]; 214372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen } 215372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen } 216372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen return NULL; 217372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen} 218372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen 219372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissenint SoundPool::load(int fd, int64_t offset, int64_t length, int priority __unused) 220372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen{ 221372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen ALOGV("load: fd=%d, offset=%" PRId64 ", length=%" PRId64 ", priority=%d", 222372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen fd, offset, length, priority); 2230275a982abecee683f16c827d405eafe51fb67aeAndy Hung int sampleID; 2240275a982abecee683f16c827d405eafe51fb67aeAndy Hung { 2250275a982abecee683f16c827d405eafe51fb67aeAndy Hung Mutex::Autolock lock(&mLock); 2260275a982abecee683f16c827d405eafe51fb67aeAndy Hung sampleID = ++mNextSampleID; 2270275a982abecee683f16c827d405eafe51fb67aeAndy Hung sp<Sample> sample = new Sample(sampleID, fd, offset, length); 2280275a982abecee683f16c827d405eafe51fb67aeAndy Hung mSamples.add(sampleID, sample); 2290275a982abecee683f16c827d405eafe51fb67aeAndy Hung sample->startLoad(); 2300275a982abecee683f16c827d405eafe51fb67aeAndy Hung } 2310275a982abecee683f16c827d405eafe51fb67aeAndy Hung // mDecodeThread->loadSample() must be called outside of mLock. 2320275a982abecee683f16c827d405eafe51fb67aeAndy Hung // mDecodeThread->loadSample() may block on mDecodeThread message queue space; 2330275a982abecee683f16c827d405eafe51fb67aeAndy Hung // the message queue emptying may block on SoundPool::findSample(). 2340275a982abecee683f16c827d405eafe51fb67aeAndy Hung // 2350275a982abecee683f16c827d405eafe51fb67aeAndy Hung // It theoretically possible that sample loads might decode out-of-order. 2360275a982abecee683f16c827d405eafe51fb67aeAndy Hung mDecodeThread->loadSample(sampleID); 2370275a982abecee683f16c827d405eafe51fb67aeAndy Hung return sampleID; 238372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen} 239372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen 240372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissenbool SoundPool::unload(int sampleID) 241372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen{ 242372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen ALOGV("unload: sampleID=%d", sampleID); 243372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen Mutex::Autolock lock(&mLock); 244a6238ef3891bbbdb1c42d3e7954c4cd55527cef6Andy Hung return mSamples.removeItem(sampleID) >= 0; // removeItem() returns index or BAD_VALUE 245372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen} 246372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen 247372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissenint SoundPool::play(int sampleID, float leftVolume, float rightVolume, 248372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen int priority, int loop, float rate) 249372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen{ 250372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen ALOGV("play sampleID=%d, leftVolume=%f, rightVolume=%f, priority=%d, loop=%d, rate=%f", 251372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen sampleID, leftVolume, rightVolume, priority, loop, rate); 252372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen SoundChannel* channel; 253372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen int channelID; 254372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen 255372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen Mutex::Autolock lock(&mLock); 256372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen 257372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen if (mQuit) { 258372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen return 0; 259372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen } 260372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen // is sample ready? 2610275a982abecee683f16c827d405eafe51fb67aeAndy Hung sp<Sample> sample(findSample_l(sampleID)); 262372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen if ((sample == 0) || (sample->state() != Sample::READY)) { 263372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen ALOGW(" sample %d not READY", sampleID); 264372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen return 0; 265372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen } 266372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen 267372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen dump(); 268372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen 269372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen // allocate a channel 2700c4b81bd3ef3fd5eb0f7d1b8e2c6168b95020134Andy Hung channel = allocateChannel_l(priority, sampleID); 271372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen 272372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen // no channel allocated - return 0 273372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen if (!channel) { 274372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen ALOGV("No channel allocated"); 275372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen return 0; 276372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen } 277372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen 278372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen channelID = ++mNextChannelID; 279372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen 280372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen ALOGV("play channel %p state = %d", channel, channel->state()); 281372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen channel->play(sample, channelID, leftVolume, rightVolume, priority, loop, rate); 282372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen return channelID; 283372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen} 284372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen 2850c4b81bd3ef3fd5eb0f7d1b8e2c6168b95020134Andy HungSoundChannel* SoundPool::allocateChannel_l(int priority, int sampleID) 286372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen{ 287372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen List<SoundChannel*>::iterator iter; 288372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen SoundChannel* channel = NULL; 289372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen 2900c4b81bd3ef3fd5eb0f7d1b8e2c6168b95020134Andy Hung // check if channel for given sampleID still available 291372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen if (!mChannels.empty()) { 2920c4b81bd3ef3fd5eb0f7d1b8e2c6168b95020134Andy Hung for (iter = mChannels.begin(); iter != mChannels.end(); ++iter) { 2930c4b81bd3ef3fd5eb0f7d1b8e2c6168b95020134Andy Hung if (sampleID == (*iter)->getPrevSampleID() && (*iter)->state() == SoundChannel::IDLE) { 2940c4b81bd3ef3fd5eb0f7d1b8e2c6168b95020134Andy Hung channel = *iter; 2950c4b81bd3ef3fd5eb0f7d1b8e2c6168b95020134Andy Hung mChannels.erase(iter); 2960c4b81bd3ef3fd5eb0f7d1b8e2c6168b95020134Andy Hung ALOGV("Allocated recycled channel for same sampleID"); 2970c4b81bd3ef3fd5eb0f7d1b8e2c6168b95020134Andy Hung break; 2980c4b81bd3ef3fd5eb0f7d1b8e2c6168b95020134Andy Hung } 2990c4b81bd3ef3fd5eb0f7d1b8e2c6168b95020134Andy Hung } 3000c4b81bd3ef3fd5eb0f7d1b8e2c6168b95020134Andy Hung } 3010c4b81bd3ef3fd5eb0f7d1b8e2c6168b95020134Andy Hung 3020c4b81bd3ef3fd5eb0f7d1b8e2c6168b95020134Andy Hung // allocate any channel 3030c4b81bd3ef3fd5eb0f7d1b8e2c6168b95020134Andy Hung if (!channel && !mChannels.empty()) { 304372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen iter = mChannels.begin(); 305372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen if (priority >= (*iter)->priority()) { 306372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen channel = *iter; 307372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen mChannels.erase(iter); 308372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen ALOGV("Allocated active channel"); 309372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen } 310372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen } 311372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen 312372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen // update priority and put it back in the list 313372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen if (channel) { 314372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen channel->setPriority(priority); 315372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen for (iter = mChannels.begin(); iter != mChannels.end(); ++iter) { 316372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen if (priority < (*iter)->priority()) { 317372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen break; 318372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen } 319372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen } 320372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen mChannels.insert(iter, channel); 321372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen } 322372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen return channel; 323372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen} 324372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen 325372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen// move a channel from its current position to the front of the list 326372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissenvoid SoundPool::moveToFront_l(SoundChannel* channel) 327372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen{ 328372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen for (List<SoundChannel*>::iterator iter = mChannels.begin(); iter != mChannels.end(); ++iter) { 329372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen if (*iter == channel) { 330372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen mChannels.erase(iter); 331372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen mChannels.push_front(channel); 332372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen break; 333372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen } 334372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen } 335372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen} 336372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen 337372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissenvoid SoundPool::pause(int channelID) 338372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen{ 339372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen ALOGV("pause(%d)", channelID); 340372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen Mutex::Autolock lock(&mLock); 341372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen SoundChannel* channel = findChannel(channelID); 342372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen if (channel) { 343372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen channel->pause(); 344372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen } 345372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen} 346372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen 347372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissenvoid SoundPool::autoPause() 348372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen{ 349372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen ALOGV("autoPause()"); 350372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen Mutex::Autolock lock(&mLock); 351372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen for (int i = 0; i < mMaxChannels; ++i) { 352372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen SoundChannel* channel = &mChannelPool[i]; 353372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen channel->autoPause(); 354372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen } 355372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen} 356372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen 357372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissenvoid SoundPool::resume(int channelID) 358372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen{ 359372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen ALOGV("resume(%d)", channelID); 360372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen Mutex::Autolock lock(&mLock); 361372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen SoundChannel* channel = findChannel(channelID); 362372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen if (channel) { 363372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen channel->resume(); 364372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen } 365372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen} 366372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen 3678e48c6939bd81dcbc596f0a4b11bfaea73aed00bJean-Michel Trivivoid SoundPool::mute(bool muting) 3688e48c6939bd81dcbc596f0a4b11bfaea73aed00bJean-Michel Trivi{ 3698e48c6939bd81dcbc596f0a4b11bfaea73aed00bJean-Michel Trivi ALOGV("mute(%d)", muting); 3708e48c6939bd81dcbc596f0a4b11bfaea73aed00bJean-Michel Trivi Mutex::Autolock lock(&mLock); 3718e48c6939bd81dcbc596f0a4b11bfaea73aed00bJean-Michel Trivi mMuted = muting; 3728e48c6939bd81dcbc596f0a4b11bfaea73aed00bJean-Michel Trivi if (!mChannels.empty()) { 3738e48c6939bd81dcbc596f0a4b11bfaea73aed00bJean-Michel Trivi for (List<SoundChannel*>::iterator iter = mChannels.begin(); 3748e48c6939bd81dcbc596f0a4b11bfaea73aed00bJean-Michel Trivi iter != mChannels.end(); ++iter) { 3758e48c6939bd81dcbc596f0a4b11bfaea73aed00bJean-Michel Trivi (*iter)->mute(muting); 3768e48c6939bd81dcbc596f0a4b11bfaea73aed00bJean-Michel Trivi } 3778e48c6939bd81dcbc596f0a4b11bfaea73aed00bJean-Michel Trivi } 3788e48c6939bd81dcbc596f0a4b11bfaea73aed00bJean-Michel Trivi} 3798e48c6939bd81dcbc596f0a4b11bfaea73aed00bJean-Michel Trivi 380372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissenvoid SoundPool::autoResume() 381372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen{ 382372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen ALOGV("autoResume()"); 383372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen Mutex::Autolock lock(&mLock); 384372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen for (int i = 0; i < mMaxChannels; ++i) { 385372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen SoundChannel* channel = &mChannelPool[i]; 386372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen channel->autoResume(); 387372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen } 388372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen} 389372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen 390372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissenvoid SoundPool::stop(int channelID) 391372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen{ 392372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen ALOGV("stop(%d)", channelID); 393372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen Mutex::Autolock lock(&mLock); 394372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen SoundChannel* channel = findChannel(channelID); 395372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen if (channel) { 396372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen channel->stop(); 397372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen } else { 398372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen channel = findNextChannel(channelID); 399372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen if (channel) 400372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen channel->clearNextEvent(); 401372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen } 402372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen} 403372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen 404372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissenvoid SoundPool::setVolume(int channelID, float leftVolume, float rightVolume) 405372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen{ 406372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen Mutex::Autolock lock(&mLock); 407372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen SoundChannel* channel = findChannel(channelID); 408372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen if (channel) { 409372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen channel->setVolume(leftVolume, rightVolume); 410372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen } 411372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen} 412372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen 413372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissenvoid SoundPool::setPriority(int channelID, int priority) 414372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen{ 415372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen ALOGV("setPriority(%d, %d)", channelID, priority); 416372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen Mutex::Autolock lock(&mLock); 417372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen SoundChannel* channel = findChannel(channelID); 418372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen if (channel) { 419372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen channel->setPriority(priority); 420372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen } 421372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen} 422372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen 423372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissenvoid SoundPool::setLoop(int channelID, int loop) 424372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen{ 425372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen ALOGV("setLoop(%d, %d)", channelID, loop); 426372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen Mutex::Autolock lock(&mLock); 427372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen SoundChannel* channel = findChannel(channelID); 428372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen if (channel) { 429372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen channel->setLoop(loop); 430372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen } 431372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen} 432372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen 433372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissenvoid SoundPool::setRate(int channelID, float rate) 434372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen{ 435372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen ALOGV("setRate(%d, %f)", channelID, rate); 436372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen Mutex::Autolock lock(&mLock); 437372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen SoundChannel* channel = findChannel(channelID); 438372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen if (channel) { 439372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen channel->setRate(rate); 440372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen } 441372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen} 442372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen 443372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen// call with lock held 444372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissenvoid SoundPool::done_l(SoundChannel* channel) 445372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen{ 446372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen ALOGV("done_l(%d)", channel->channelID()); 447372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen // if "stolen", play next event 448372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen if (channel->nextChannelID() != 0) { 449372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen ALOGV("add to restart list"); 450372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen addToRestartList(channel); 451372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen } 452372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen 453372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen // return to idle state 454372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen else { 455372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen ALOGV("move to front"); 456372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen moveToFront_l(channel); 457372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen } 458372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen} 459372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen 460372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissenvoid SoundPool::setCallback(SoundPoolCallback* callback, void* user) 461372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen{ 462372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen Mutex::Autolock lock(&mCallbackLock); 463372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen mCallback = callback; 464372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen mUserData = user; 465372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen} 466372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen 467372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissenvoid SoundPool::notify(SoundPoolEvent event) 468372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen{ 469372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen Mutex::Autolock lock(&mCallbackLock); 470372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen if (mCallback != NULL) { 471372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen mCallback(event, this, mUserData); 472372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen } 473372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen} 474372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen 475372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissenvoid SoundPool::dump() 476372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen{ 477372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen for (int i = 0; i < mMaxChannels; ++i) { 478372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen mChannelPool[i].dump(); 479372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen } 480372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen} 481372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen 482372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen 483372be8970c6ab68c295fb74dbb878ab1d443d90eMarco NelissenSample::Sample(int sampleID, int fd, int64_t offset, int64_t length) 484372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen{ 485372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen init(); 486372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen mSampleID = sampleID; 487372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen mFd = dup(fd); 488372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen mOffset = offset; 489372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen mLength = length; 490372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen ALOGV("create sampleID=%d, fd=%d, offset=%" PRId64 " length=%" PRId64, 491372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen mSampleID, mFd, mLength, mOffset); 492372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen} 493372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen 494372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissenvoid Sample::init() 495372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen{ 496372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen mSize = 0; 497372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen mRefCount = 0; 498372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen mSampleID = 0; 499372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen mState = UNLOADED; 500372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen mFd = -1; 501372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen mOffset = 0; 502372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen mLength = 0; 503372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen} 504372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen 505372be8970c6ab68c295fb74dbb878ab1d443d90eMarco NelissenSample::~Sample() 506372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen{ 507372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen ALOGV("Sample::destructor sampleID=%d, fd=%d", mSampleID, mFd); 508372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen if (mFd > 0) { 509372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen ALOGV("close(%d)", mFd); 510372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen ::close(mFd); 511372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen } 512372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen} 513372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen 514372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissenstatic status_t decode(int fd, int64_t offset, int64_t length, 515372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen uint32_t *rate, int *numChannels, audio_format_t *audioFormat, 516372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen sp<MemoryHeapBase> heap, size_t *memsize) { 517372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen 5186cd6110773bf83638f21a76d388dc2b7037df0d8Marco Nelissen ALOGV("fd %d, offset %" PRId64 ", size %" PRId64, fd, offset, length); 519372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen AMediaExtractor *ex = AMediaExtractor_new(); 520372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen status_t err = AMediaExtractor_setDataSourceFd(ex, fd, offset, length); 521372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen 522372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen if (err != AMEDIA_OK) { 52306524dccbc35cdeed92d0b5ec96b42d43518d7edMarco Nelissen AMediaExtractor_delete(ex); 524372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen return err; 525372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen } 526372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen 527372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen *audioFormat = AUDIO_FORMAT_PCM_16_BIT; 528372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen 529372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen size_t numTracks = AMediaExtractor_getTrackCount(ex); 530372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen for (size_t i = 0; i < numTracks; i++) { 531372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen AMediaFormat *format = AMediaExtractor_getTrackFormat(ex, i); 532372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen const char *mime; 533372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen if (!AMediaFormat_getString(format, AMEDIAFORMAT_KEY_MIME, &mime)) { 534372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen AMediaExtractor_delete(ex); 535372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen AMediaFormat_delete(format); 536372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen return UNKNOWN_ERROR; 537372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen } 538372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen if (strncmp(mime, "audio/", 6) == 0) { 539372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen 540372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen AMediaCodec *codec = AMediaCodec_createDecoderByType(mime); 54126eca01c490f643fc2558be4c5477a1d433a8a07Andy Hung if (codec == NULL 54226eca01c490f643fc2558be4c5477a1d433a8a07Andy Hung || AMediaCodec_configure(codec, format, 54326eca01c490f643fc2558be4c5477a1d433a8a07Andy Hung NULL /* window */, NULL /* drm */, 0 /* flags */) != AMEDIA_OK 54426eca01c490f643fc2558be4c5477a1d433a8a07Andy Hung || AMediaCodec_start(codec) != AMEDIA_OK 54526eca01c490f643fc2558be4c5477a1d433a8a07Andy Hung || AMediaExtractor_selectTrack(ex, i) != AMEDIA_OK) { 546372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen AMediaExtractor_delete(ex); 547372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen AMediaCodec_delete(codec); 548372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen AMediaFormat_delete(format); 549372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen return UNKNOWN_ERROR; 550372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen } 551372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen 552372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen bool sawInputEOS = false; 553372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen bool sawOutputEOS = false; 554372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen uint8_t* writePos = static_cast<uint8_t*>(heap->getBase()); 555372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen size_t available = heap->getSize(); 556372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen size_t written = 0; 557372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen 558372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen AMediaFormat_delete(format); 559372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen format = AMediaCodec_getOutputFormat(codec); 560372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen 561372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen while (!sawOutputEOS) { 562372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen if (!sawInputEOS) { 563372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen ssize_t bufidx = AMediaCodec_dequeueInputBuffer(codec, 5000); 5646cd6110773bf83638f21a76d388dc2b7037df0d8Marco Nelissen ALOGV("input buffer %zd", bufidx); 565372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen if (bufidx >= 0) { 566372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen size_t bufsize; 567372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen uint8_t *buf = AMediaCodec_getInputBuffer(codec, bufidx, &bufsize); 5680474773aab24594f4f4d395bf058d6f5b16db958Andy Hung if (buf == nullptr) { 5690474773aab24594f4f4d395bf058d6f5b16db958Andy Hung ALOGE("AMediaCodec_getInputBuffer returned nullptr, short decode"); 5700474773aab24594f4f4d395bf058d6f5b16db958Andy Hung break; 5710474773aab24594f4f4d395bf058d6f5b16db958Andy Hung } 572372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen int sampleSize = AMediaExtractor_readSampleData(ex, buf, bufsize); 573372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen ALOGV("read %d", sampleSize); 574372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen if (sampleSize < 0) { 575372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen sampleSize = 0; 576372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen sawInputEOS = true; 577372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen ALOGV("EOS"); 578372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen } 579372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen int64_t presentationTimeUs = AMediaExtractor_getSampleTime(ex); 580372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen 5810474773aab24594f4f4d395bf058d6f5b16db958Andy Hung media_status_t mstatus = AMediaCodec_queueInputBuffer(codec, bufidx, 582372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen 0 /* offset */, sampleSize, presentationTimeUs, 583372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen sawInputEOS ? AMEDIACODEC_BUFFER_FLAG_END_OF_STREAM : 0); 5840474773aab24594f4f4d395bf058d6f5b16db958Andy Hung if (mstatus != AMEDIA_OK) { 5850474773aab24594f4f4d395bf058d6f5b16db958Andy Hung // AMEDIA_ERROR_UNKNOWN == { -ERANGE -EINVAL -EACCES } 5860474773aab24594f4f4d395bf058d6f5b16db958Andy Hung ALOGE("AMediaCodec_queueInputBuffer returned status %d, short decode", 5870474773aab24594f4f4d395bf058d6f5b16db958Andy Hung (int)mstatus); 5880474773aab24594f4f4d395bf058d6f5b16db958Andy Hung break; 5890474773aab24594f4f4d395bf058d6f5b16db958Andy Hung } 5900474773aab24594f4f4d395bf058d6f5b16db958Andy Hung (void)AMediaExtractor_advance(ex); 591372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen } 592372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen } 593372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen 594372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen AMediaCodecBufferInfo info; 595372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen int status = AMediaCodec_dequeueOutputBuffer(codec, &info, 1); 596372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen ALOGV("dequeueoutput returned: %d", status); 597372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen if (status >= 0) { 598372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen if (info.flags & AMEDIACODEC_BUFFER_FLAG_END_OF_STREAM) { 599372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen ALOGV("output EOS"); 600372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen sawOutputEOS = true; 601372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen } 602372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen ALOGV("got decoded buffer size %d", info.size); 603372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen 604372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen uint8_t *buf = AMediaCodec_getOutputBuffer(codec, status, NULL /* out_size */); 6050474773aab24594f4f4d395bf058d6f5b16db958Andy Hung if (buf == nullptr) { 6060474773aab24594f4f4d395bf058d6f5b16db958Andy Hung ALOGE("AMediaCodec_getOutputBuffer returned nullptr, short decode"); 6070474773aab24594f4f4d395bf058d6f5b16db958Andy Hung break; 6080474773aab24594f4f4d395bf058d6f5b16db958Andy Hung } 609372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen size_t dataSize = info.size; 610372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen if (dataSize > available) { 611372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen dataSize = available; 612372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen } 613372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen memcpy(writePos, buf + info.offset, dataSize); 614372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen writePos += dataSize; 615372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen written += dataSize; 616372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen available -= dataSize; 6170474773aab24594f4f4d395bf058d6f5b16db958Andy Hung media_status_t mstatus = AMediaCodec_releaseOutputBuffer( 6180474773aab24594f4f4d395bf058d6f5b16db958Andy Hung codec, status, false /* render */); 6190474773aab24594f4f4d395bf058d6f5b16db958Andy Hung if (mstatus != AMEDIA_OK) { 6200474773aab24594f4f4d395bf058d6f5b16db958Andy Hung // AMEDIA_ERROR_UNKNOWN == { -ERANGE -EINVAL -EACCES } 6210474773aab24594f4f4d395bf058d6f5b16db958Andy Hung ALOGE("AMediaCodec_releaseOutputBuffer returned status %d, short decode", 6220474773aab24594f4f4d395bf058d6f5b16db958Andy Hung (int)mstatus); 6230474773aab24594f4f4d395bf058d6f5b16db958Andy Hung break; 6240474773aab24594f4f4d395bf058d6f5b16db958Andy Hung } 625372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen if (available == 0) { 626372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen // there might be more data, but there's no space for it 627372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen sawOutputEOS = true; 628372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen } 629372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen } else if (status == AMEDIACODEC_INFO_OUTPUT_BUFFERS_CHANGED) { 630372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen ALOGV("output buffers changed"); 631372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen } else if (status == AMEDIACODEC_INFO_OUTPUT_FORMAT_CHANGED) { 632372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen AMediaFormat_delete(format); 633372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen format = AMediaCodec_getOutputFormat(codec); 634372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen ALOGV("format changed to: %s", AMediaFormat_toString(format)); 635372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen } else if (status == AMEDIACODEC_INFO_TRY_AGAIN_LATER) { 636372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen ALOGV("no output buffer right now"); 6372f01c806e06632f8b9db8ea127d704e13811cb8eMarco Nelissen } else if (status <= AMEDIA_ERROR_BASE) { 6382f01c806e06632f8b9db8ea127d704e13811cb8eMarco Nelissen ALOGE("decode error: %d", status); 6392f01c806e06632f8b9db8ea127d704e13811cb8eMarco Nelissen break; 640372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen } else { 641372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen ALOGV("unexpected info code: %d", status); 642372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen } 643372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen } 644372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen 6450474773aab24594f4f4d395bf058d6f5b16db958Andy Hung (void)AMediaCodec_stop(codec); 6460474773aab24594f4f4d395bf058d6f5b16db958Andy Hung (void)AMediaCodec_delete(codec); 6470474773aab24594f4f4d395bf058d6f5b16db958Andy Hung (void)AMediaExtractor_delete(ex); 648372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen if (!AMediaFormat_getInt32(format, AMEDIAFORMAT_KEY_SAMPLE_RATE, (int32_t*) rate) || 649372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen !AMediaFormat_getInt32(format, AMEDIAFORMAT_KEY_CHANNEL_COUNT, numChannels)) { 6500474773aab24594f4f4d395bf058d6f5b16db958Andy Hung (void)AMediaFormat_delete(format); 651372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen return UNKNOWN_ERROR; 652372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen } 6530474773aab24594f4f4d395bf058d6f5b16db958Andy Hung (void)AMediaFormat_delete(format); 654372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen *memsize = written; 655372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen return OK; 656372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen } 6570474773aab24594f4f4d395bf058d6f5b16db958Andy Hung (void)AMediaFormat_delete(format); 658372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen } 6590474773aab24594f4f4d395bf058d6f5b16db958Andy Hung (void)AMediaExtractor_delete(ex); 660372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen return UNKNOWN_ERROR; 661372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen} 662372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen 663372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissenstatus_t Sample::doLoad() 664372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen{ 665372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen uint32_t sampleRate; 666372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen int numChannels; 667372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen audio_format_t format; 668372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen status_t status; 669372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen mHeap = new MemoryHeapBase(kDefaultHeapSize); 670372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen 671372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen ALOGV("Start decode"); 672372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen status = decode(mFd, mOffset, mLength, &sampleRate, &numChannels, &format, 673372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen mHeap, &mSize); 674372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen ALOGV("close(%d)", mFd); 675372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen ::close(mFd); 676372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen mFd = -1; 677372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen if (status != NO_ERROR) { 678372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen ALOGE("Unable to load sample"); 679372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen goto error; 680372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen } 681372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen ALOGV("pointer = %p, size = %zu, sampleRate = %u, numChannels = %d", 682372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen mHeap->getBase(), mSize, sampleRate, numChannels); 683372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen 684372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen if (sampleRate > kMaxSampleRate) { 685372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen ALOGE("Sample rate (%u) out of range", sampleRate); 686372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen status = BAD_VALUE; 687372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen goto error; 688372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen } 689372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen 690bd2c3d65d6b62b5a359268246e7ebe96904bd851Glenn Kasten if ((numChannels < 1) || (numChannels > FCC_8)) { 691372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen ALOGE("Sample channel count (%d) out of range", numChannels); 692372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen status = BAD_VALUE; 693372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen goto error; 694372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen } 695372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen 696372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen mData = new MemoryBase(mHeap, 0, mSize); 697372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen mSampleRate = sampleRate; 698372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen mNumChannels = numChannels; 699372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen mFormat = format; 700372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen mState = READY; 701372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen return NO_ERROR; 702372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen 703372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissenerror: 704372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen mHeap.clear(); 705372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen return status; 706372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen} 707372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen 708372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen 709372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissenvoid SoundChannel::init(SoundPool* soundPool) 710372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen{ 711372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen mSoundPool = soundPool; 7120c4b81bd3ef3fd5eb0f7d1b8e2c6168b95020134Andy Hung mPrevSampleID = -1; 713372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen} 714372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen 715372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen// call with sound pool lock held 716372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissenvoid SoundChannel::play(const sp<Sample>& sample, int nextChannelID, float leftVolume, 717372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen float rightVolume, int priority, int loop, float rate) 718372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen{ 719372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen sp<AudioTrack> oldTrack; 720372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen sp<AudioTrack> newTrack; 7210c4b81bd3ef3fd5eb0f7d1b8e2c6168b95020134Andy Hung status_t status = NO_ERROR; 722372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen 723372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen { // scope for the lock 724372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen Mutex::Autolock lock(&mLock); 725372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen 726372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen ALOGV("SoundChannel::play %p: sampleID=%d, channelID=%d, leftVolume=%f, rightVolume=%f," 727372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen " priority=%d, loop=%d, rate=%f", 728372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen this, sample->sampleID(), nextChannelID, leftVolume, rightVolume, 729372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen priority, loop, rate); 730372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen 731372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen // if not idle, this voice is being stolen 732372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen if (mState != IDLE) { 733372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen ALOGV("channel %d stolen - event queued for channel %d", channelID(), nextChannelID); 734372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen mNextEvent.set(sample, nextChannelID, leftVolume, rightVolume, priority, loop, rate); 735372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen stop_l(); 736372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen return; 737372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen } 738372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen 739372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen // initialize track 740372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen size_t afFrameCount; 741372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen uint32_t afSampleRate; 742372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen audio_stream_type_t streamType = audio_attributes_to_stream_type(mSoundPool->attributes()); 743372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen if (AudioSystem::getOutputFrameCount(&afFrameCount, streamType) != NO_ERROR) { 744372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen afFrameCount = kDefaultFrameCount; 745372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen } 746372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen if (AudioSystem::getOutputSamplingRate(&afSampleRate, streamType) != NO_ERROR) { 747372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen afSampleRate = kDefaultSampleRate; 748372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen } 749372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen int numChannels = sample->numChannels(); 750372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen uint32_t sampleRate = uint32_t(float(sample->sampleRate()) * rate + 0.5); 751372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen size_t frameCount = 0; 752372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen 753372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen if (loop) { 754a1c3516a243d00428ff2b470409d47cc9f5c9523Andy Hung const audio_format_t format = sample->format(); 755a1c3516a243d00428ff2b470409d47cc9f5c9523Andy Hung const size_t frameSize = audio_is_linear_pcm(format) 756a1c3516a243d00428ff2b470409d47cc9f5c9523Andy Hung ? numChannels * audio_bytes_per_sample(format) : 1; 757a1c3516a243d00428ff2b470409d47cc9f5c9523Andy Hung frameCount = sample->size() / frameSize; 758372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen } 759372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen 760372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen#ifndef USE_SHARED_MEM_BUFFER 761372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen uint32_t totalFrames = (kDefaultBufferCount * afFrameCount * sampleRate) / afSampleRate; 762372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen // Ensure minimum audio buffer size in case of short looped sample 763372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen if(frameCount < totalFrames) { 764372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen frameCount = totalFrames; 765372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen } 766372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen#endif 767372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen 76832ccb69fdeeeb236d9c5f2a4335b44d1d0c4b042Andy Hung // check if the existing track has the same sample id. 76932ccb69fdeeeb236d9c5f2a4335b44d1d0c4b042Andy Hung if (mAudioTrack != 0 && mPrevSampleID == sample->sampleID()) { 77032ccb69fdeeeb236d9c5f2a4335b44d1d0c4b042Andy Hung // the sample rate may fail to change if the audio track is a fast track. 77132ccb69fdeeeb236d9c5f2a4335b44d1d0c4b042Andy Hung if (mAudioTrack->setSampleRate(sampleRate) == NO_ERROR) { 77232ccb69fdeeeb236d9c5f2a4335b44d1d0c4b042Andy Hung newTrack = mAudioTrack; 77332ccb69fdeeeb236d9c5f2a4335b44d1d0c4b042Andy Hung ALOGV("reusing track %p for sample %d", mAudioTrack.get(), sample->sampleID()); 77432ccb69fdeeeb236d9c5f2a4335b44d1d0c4b042Andy Hung } 77532ccb69fdeeeb236d9c5f2a4335b44d1d0c4b042Andy Hung } 77632ccb69fdeeeb236d9c5f2a4335b44d1d0c4b042Andy Hung if (newTrack == 0) { 7770c4b81bd3ef3fd5eb0f7d1b8e2c6168b95020134Andy Hung // mToggle toggles each time a track is started on a given channel. 7780c4b81bd3ef3fd5eb0f7d1b8e2c6168b95020134Andy Hung // The toggle is concatenated with the SoundChannel address and passed to AudioTrack 7790c4b81bd3ef3fd5eb0f7d1b8e2c6168b95020134Andy Hung // as callback user data. This enables the detection of callbacks received from the old 7800c4b81bd3ef3fd5eb0f7d1b8e2c6168b95020134Andy Hung // audio track while the new one is being started and avoids processing them with 7810c4b81bd3ef3fd5eb0f7d1b8e2c6168b95020134Andy Hung // wrong audio audio buffer size (mAudioBufferSize) 7820c4b81bd3ef3fd5eb0f7d1b8e2c6168b95020134Andy Hung unsigned long toggle = mToggle ^ 1; 7830c4b81bd3ef3fd5eb0f7d1b8e2c6168b95020134Andy Hung void *userData = (void *)((unsigned long)this | toggle); 7840c4b81bd3ef3fd5eb0f7d1b8e2c6168b95020134Andy Hung audio_channel_mask_t channelMask = audio_channel_out_mask_from_count(numChannels); 7850c4b81bd3ef3fd5eb0f7d1b8e2c6168b95020134Andy Hung 7860c4b81bd3ef3fd5eb0f7d1b8e2c6168b95020134Andy Hung // do not create a new audio track if current track is compatible with sample parameters 7870c4b81bd3ef3fd5eb0f7d1b8e2c6168b95020134Andy Hung #ifdef USE_SHARED_MEM_BUFFER 7880c4b81bd3ef3fd5eb0f7d1b8e2c6168b95020134Andy Hung newTrack = new AudioTrack(streamType, sampleRate, sample->format(), 7896c307879b75f3eac2179b23ac309df0e4ce9ceddJean-Michel Trivi channelMask, sample->getIMemory(), AUDIO_OUTPUT_FLAG_FAST, callback, userData, 7906c307879b75f3eac2179b23ac309df0e4ce9ceddJean-Michel Trivi 0 /*default notification frames*/, AUDIO_SESSION_ALLOCATE, 7916c307879b75f3eac2179b23ac309df0e4ce9ceddJean-Michel Trivi AudioTrack::TRANSFER_DEFAULT, 7926c307879b75f3eac2179b23ac309df0e4ce9ceddJean-Michel Trivi NULL /*offloadInfo*/, -1 /*uid*/, -1 /*pid*/, mSoundPool->attributes()); 7930c4b81bd3ef3fd5eb0f7d1b8e2c6168b95020134Andy Hung #else 7940c4b81bd3ef3fd5eb0f7d1b8e2c6168b95020134Andy Hung uint32_t bufferFrames = (totalFrames + (kDefaultBufferCount - 1)) / kDefaultBufferCount; 7950c4b81bd3ef3fd5eb0f7d1b8e2c6168b95020134Andy Hung newTrack = new AudioTrack(streamType, sampleRate, sample->format(), 7960c4b81bd3ef3fd5eb0f7d1b8e2c6168b95020134Andy Hung channelMask, frameCount, AUDIO_OUTPUT_FLAG_FAST, callback, userData, 7976c307879b75f3eac2179b23ac309df0e4ce9ceddJean-Michel Trivi bufferFrames, AUDIO_SESSION_ALLOCATE, AudioTrack::TRANSFER_DEFAULT, 7986c307879b75f3eac2179b23ac309df0e4ce9ceddJean-Michel Trivi NULL /*offloadInfo*/, -1 /*uid*/, -1 /*pid*/, mSoundPool->attributes()); 7990c4b81bd3ef3fd5eb0f7d1b8e2c6168b95020134Andy Hung #endif 8000c4b81bd3ef3fd5eb0f7d1b8e2c6168b95020134Andy Hung oldTrack = mAudioTrack; 8010c4b81bd3ef3fd5eb0f7d1b8e2c6168b95020134Andy Hung status = newTrack->initCheck(); 8020c4b81bd3ef3fd5eb0f7d1b8e2c6168b95020134Andy Hung if (status != NO_ERROR) { 8030c4b81bd3ef3fd5eb0f7d1b8e2c6168b95020134Andy Hung ALOGE("Error creating AudioTrack"); 80414d226a2cd7b39e17a3f0bfdab79e645f7146f53Glenn Kasten // newTrack goes out of scope, so reference count drops to zero 8050c4b81bd3ef3fd5eb0f7d1b8e2c6168b95020134Andy Hung goto exit; 8060c4b81bd3ef3fd5eb0f7d1b8e2c6168b95020134Andy Hung } 8070c4b81bd3ef3fd5eb0f7d1b8e2c6168b95020134Andy Hung // From now on, AudioTrack callbacks received with previous toggle value will be ignored. 8080c4b81bd3ef3fd5eb0f7d1b8e2c6168b95020134Andy Hung mToggle = toggle; 8090c4b81bd3ef3fd5eb0f7d1b8e2c6168b95020134Andy Hung mAudioTrack = newTrack; 810bc4537393b02b39433e07fed4ed57186d8e5959fAndy Hung ALOGV("using new track %p for sample %d", newTrack.get(), sample->sampleID()); 811372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen } 8129bc88b378cf2f1953a08b2df11c58223e8eb2f23Eric Laurent if (mMuted) { 8139bc88b378cf2f1953a08b2df11c58223e8eb2f23Eric Laurent newTrack->setVolume(0.0f, 0.0f); 8149bc88b378cf2f1953a08b2df11c58223e8eb2f23Eric Laurent } else { 8159bc88b378cf2f1953a08b2df11c58223e8eb2f23Eric Laurent newTrack->setVolume(leftVolume, rightVolume); 8169bc88b378cf2f1953a08b2df11c58223e8eb2f23Eric Laurent } 817372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen newTrack->setLoop(0, frameCount, loop); 818372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen mPos = 0; 819372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen mSample = sample; 820372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen mChannelID = nextChannelID; 821372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen mPriority = priority; 822372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen mLoop = loop; 823372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen mLeftVolume = leftVolume; 824372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen mRightVolume = rightVolume; 825372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen mNumChannels = numChannels; 826372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen mRate = rate; 827372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen clearNextEvent(); 828372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen mState = PLAYING; 829372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen mAudioTrack->start(); 830372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen mAudioBufferSize = newTrack->frameCount()*newTrack->frameSize(); 831372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen } 832372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen 833372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissenexit: 834372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen ALOGV("delete oldTrack %p", oldTrack.get()); 835372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen if (status != NO_ERROR) { 836372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen mAudioTrack.clear(); 837372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen } 838372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen} 839372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen 840372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissenvoid SoundChannel::nextEvent() 841372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen{ 842372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen sp<Sample> sample; 843372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen int nextChannelID; 844372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen float leftVolume; 845372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen float rightVolume; 846372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen int priority; 847372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen int loop; 848372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen float rate; 849372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen 850372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen // check for valid event 851372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen { 852372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen Mutex::Autolock lock(&mLock); 853372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen nextChannelID = mNextEvent.channelID(); 854372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen if (nextChannelID == 0) { 855372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen ALOGV("stolen channel has no event"); 856372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen return; 857372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen } 858372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen 859372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen sample = mNextEvent.sample(); 860372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen leftVolume = mNextEvent.leftVolume(); 861372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen rightVolume = mNextEvent.rightVolume(); 862372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen priority = mNextEvent.priority(); 863372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen loop = mNextEvent.loop(); 864372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen rate = mNextEvent.rate(); 865372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen } 866372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen 867372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen ALOGV("Starting stolen channel %d -> %d", channelID(), nextChannelID); 868372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen play(sample, nextChannelID, leftVolume, rightVolume, priority, loop, rate); 869372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen} 870372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen 871372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissenvoid SoundChannel::callback(int event, void* user, void *info) 872372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen{ 873372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen SoundChannel* channel = static_cast<SoundChannel*>((void *)((unsigned long)user & ~1)); 874372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen 875372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen channel->process(event, info, (unsigned long)user & 1); 876372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen} 877372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen 878372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissenvoid SoundChannel::process(int event, void *info, unsigned long toggle) 879372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen{ 880372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen //ALOGV("process(%d)", mChannelID); 881372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen 882372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen Mutex::Autolock lock(&mLock); 883372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen 884372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen AudioTrack::Buffer* b = NULL; 885372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen if (event == AudioTrack::EVENT_MORE_DATA) { 886372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen b = static_cast<AudioTrack::Buffer *>(info); 887372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen } 888372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen 889372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen if (mToggle != toggle) { 890372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen ALOGV("process wrong toggle %p channel %d", this, mChannelID); 891372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen if (b != NULL) { 892372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen b->size = 0; 893372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen } 894372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen return; 895372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen } 896372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen 897372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen sp<Sample> sample = mSample; 898372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen 899372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen// ALOGV("SoundChannel::process event %d", event); 900372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen 901372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen if (event == AudioTrack::EVENT_MORE_DATA) { 902372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen 903372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen // check for stop state 904372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen if (b->size == 0) return; 905372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen 906372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen if (mState == IDLE) { 907372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen b->size = 0; 908372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen return; 909372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen } 910372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen 911372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen if (sample != 0) { 912372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen // fill buffer 913372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen uint8_t* q = (uint8_t*) b->i8; 914372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen size_t count = 0; 915372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen 916372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen if (mPos < (int)sample->size()) { 917372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen uint8_t* p = sample->data() + mPos; 918372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen count = sample->size() - mPos; 919372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen if (count > b->size) { 920372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen count = b->size; 921372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen } 922372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen memcpy(q, p, count); 923372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen// ALOGV("fill: q=%p, p=%p, mPos=%u, b->size=%u, count=%d", q, p, mPos, b->size, 924372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen// count); 925372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen } else if (mPos < mAudioBufferSize) { 926372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen count = mAudioBufferSize - mPos; 927372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen if (count > b->size) { 928372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen count = b->size; 929372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen } 930372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen memset(q, 0, count); 931372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen// ALOGV("fill extra: q=%p, mPos=%u, b->size=%u, count=%d", q, mPos, b->size, count); 932372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen } 933372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen 934372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen mPos += count; 935372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen b->size = count; 936372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen //ALOGV("buffer=%p, [0]=%d", b->i16, b->i16[0]); 937372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen } 938372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen } else if (event == AudioTrack::EVENT_UNDERRUN || event == AudioTrack::EVENT_BUFFER_END) { 939372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen ALOGV("process %p channel %d event %s", 940372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen this, mChannelID, (event == AudioTrack::EVENT_UNDERRUN) ? "UNDERRUN" : 941372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen "BUFFER_END"); 942372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen mSoundPool->addToStopList(this); 943372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen } else if (event == AudioTrack::EVENT_LOOP_END) { 944372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen ALOGV("End loop %p channel %d", this, mChannelID); 945372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen } else if (event == AudioTrack::EVENT_NEW_IAUDIOTRACK) { 946372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen ALOGV("process %p channel %d NEW_IAUDIOTRACK", this, mChannelID); 947372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen } else { 948372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen ALOGW("SoundChannel::process unexpected event %d", event); 949372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen } 950372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen} 951372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen 952372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen 953372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen// call with lock held 954372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissenbool SoundChannel::doStop_l() 955372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen{ 956372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen if (mState != IDLE) { 957372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen setVolume_l(0, 0); 958372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen ALOGV("stop"); 959372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen mAudioTrack->stop(); 9600c4b81bd3ef3fd5eb0f7d1b8e2c6168b95020134Andy Hung mPrevSampleID = mSample->sampleID(); 961372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen mSample.clear(); 962372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen mState = IDLE; 963372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen mPriority = IDLE_PRIORITY; 964372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen return true; 965372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen } 966372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen return false; 967372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen} 968372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen 969372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen// call with lock held and sound pool lock held 970372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissenvoid SoundChannel::stop_l() 971372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen{ 972372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen if (doStop_l()) { 973372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen mSoundPool->done_l(this); 974372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen } 975372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen} 976372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen 977372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen// call with sound pool lock held 978372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissenvoid SoundChannel::stop() 979372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen{ 980372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen bool stopped; 981372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen { 982372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen Mutex::Autolock lock(&mLock); 983372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen stopped = doStop_l(); 984372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen } 985372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen 986372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen if (stopped) { 987372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen mSoundPool->done_l(this); 988372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen } 989372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen} 990372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen 991372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen//FIXME: Pause is a little broken right now 992372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissenvoid SoundChannel::pause() 993372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen{ 994372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen Mutex::Autolock lock(&mLock); 995372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen if (mState == PLAYING) { 996372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen ALOGV("pause track"); 997372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen mState = PAUSED; 998372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen mAudioTrack->pause(); 999372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen } 1000372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen} 1001372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen 1002372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissenvoid SoundChannel::autoPause() 1003372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen{ 1004372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen Mutex::Autolock lock(&mLock); 1005372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen if (mState == PLAYING) { 1006372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen ALOGV("pause track"); 1007372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen mState = PAUSED; 1008372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen mAutoPaused = true; 1009372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen mAudioTrack->pause(); 1010372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen } 1011372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen} 1012372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen 1013372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissenvoid SoundChannel::resume() 1014372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen{ 1015372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen Mutex::Autolock lock(&mLock); 1016372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen if (mState == PAUSED) { 1017372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen ALOGV("resume track"); 1018372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen mState = PLAYING; 1019372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen mAutoPaused = false; 1020372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen mAudioTrack->start(); 1021372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen } 1022372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen} 1023372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen 1024372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissenvoid SoundChannel::autoResume() 1025372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen{ 1026372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen Mutex::Autolock lock(&mLock); 1027372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen if (mAutoPaused && (mState == PAUSED)) { 1028372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen ALOGV("resume track"); 1029372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen mState = PLAYING; 1030372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen mAutoPaused = false; 1031372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen mAudioTrack->start(); 1032372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen } 1033372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen} 1034372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen 1035372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissenvoid SoundChannel::setRate(float rate) 1036372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen{ 1037372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen Mutex::Autolock lock(&mLock); 1038372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen if (mAudioTrack != NULL && mSample != 0) { 1039372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen uint32_t sampleRate = uint32_t(float(mSample->sampleRate()) * rate + 0.5); 1040372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen mAudioTrack->setSampleRate(sampleRate); 1041372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen mRate = rate; 1042372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen } 1043372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen} 1044372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen 1045372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen// call with lock held 1046372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissenvoid SoundChannel::setVolume_l(float leftVolume, float rightVolume) 1047372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen{ 1048372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen mLeftVolume = leftVolume; 1049372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen mRightVolume = rightVolume; 10508e48c6939bd81dcbc596f0a4b11bfaea73aed00bJean-Michel Trivi if (mAudioTrack != NULL && !mMuted) 1051372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen mAudioTrack->setVolume(leftVolume, rightVolume); 1052372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen} 1053372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen 1054372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissenvoid SoundChannel::setVolume(float leftVolume, float rightVolume) 1055372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen{ 1056372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen Mutex::Autolock lock(&mLock); 1057372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen setVolume_l(leftVolume, rightVolume); 1058372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen} 1059372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen 10608e48c6939bd81dcbc596f0a4b11bfaea73aed00bJean-Michel Trivivoid SoundChannel::mute(bool muting) 10618e48c6939bd81dcbc596f0a4b11bfaea73aed00bJean-Michel Trivi{ 10628e48c6939bd81dcbc596f0a4b11bfaea73aed00bJean-Michel Trivi Mutex::Autolock lock(&mLock); 10638e48c6939bd81dcbc596f0a4b11bfaea73aed00bJean-Michel Trivi mMuted = muting; 10648e48c6939bd81dcbc596f0a4b11bfaea73aed00bJean-Michel Trivi if (mAudioTrack != NULL) { 10658e48c6939bd81dcbc596f0a4b11bfaea73aed00bJean-Michel Trivi if (mMuted) { 10668e48c6939bd81dcbc596f0a4b11bfaea73aed00bJean-Michel Trivi mAudioTrack->setVolume(0.0f, 0.0f); 10678e48c6939bd81dcbc596f0a4b11bfaea73aed00bJean-Michel Trivi } else { 10688e48c6939bd81dcbc596f0a4b11bfaea73aed00bJean-Michel Trivi mAudioTrack->setVolume(mLeftVolume, mRightVolume); 10698e48c6939bd81dcbc596f0a4b11bfaea73aed00bJean-Michel Trivi } 10708e48c6939bd81dcbc596f0a4b11bfaea73aed00bJean-Michel Trivi } 10718e48c6939bd81dcbc596f0a4b11bfaea73aed00bJean-Michel Trivi} 10728e48c6939bd81dcbc596f0a4b11bfaea73aed00bJean-Michel Trivi 1073372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissenvoid SoundChannel::setLoop(int loop) 1074372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen{ 1075372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen Mutex::Autolock lock(&mLock); 1076372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen if (mAudioTrack != NULL && mSample != 0) { 1077372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen uint32_t loopEnd = mSample->size()/mNumChannels/ 1078372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen ((mSample->format() == AUDIO_FORMAT_PCM_16_BIT) ? sizeof(int16_t) : sizeof(uint8_t)); 1079372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen mAudioTrack->setLoop(0, loopEnd, loop); 1080372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen mLoop = loop; 1081372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen } 1082372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen} 1083372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen 1084372be8970c6ab68c295fb74dbb878ab1d443d90eMarco NelissenSoundChannel::~SoundChannel() 1085372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen{ 1086372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen ALOGV("SoundChannel destructor %p", this); 1087372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen { 1088372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen Mutex::Autolock lock(&mLock); 1089372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen clearNextEvent(); 1090372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen doStop_l(); 1091372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen } 1092372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen // do not call AudioTrack destructor with mLock held as it will wait for the AudioTrack 1093372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen // callback thread to exit which may need to execute process() and acquire the mLock. 1094372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen mAudioTrack.clear(); 1095372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen} 1096372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen 1097372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissenvoid SoundChannel::dump() 1098372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen{ 1099372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen ALOGV("mState = %d mChannelID=%d, mNumChannels=%d, mPos = %d, mPriority=%d, mLoop=%d", 1100372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen mState, mChannelID, mNumChannels, mPos, mPriority, mLoop); 1101372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen} 1102372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen 1103372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissenvoid SoundEvent::set(const sp<Sample>& sample, int channelID, float leftVolume, 1104372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen float rightVolume, int priority, int loop, float rate) 1105372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen{ 1106372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen mSample = sample; 1107372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen mChannelID = channelID; 1108372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen mLeftVolume = leftVolume; 1109372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen mRightVolume = rightVolume; 1110372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen mPriority = priority; 1111372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen mLoop = loop; 1112372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen mRate =rate; 1113372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen} 1114372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen 1115372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen} // end namespace android 1116