12e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent/* 22e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent * Copyright (C) 2007 The Android Open Source Project 32e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent * 42e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent * Licensed under the Apache License, Version 2.0 (the "License"); 52e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent * you may not use this file except in compliance with the License. 62e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent * You may obtain a copy of the License at 72e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent * 82e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent * http://www.apache.org/licenses/LICENSE-2.0 92e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent * 102e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent * Unless required by applicable law or agreed to in writing, software 112e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent * distributed under the License is distributed on an "AS IS" BASIS, 122e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 132e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent * See the License for the specific language governing permissions and 142e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent * limitations under the License. 152e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent */ 162e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent 172e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent//#define LOG_NDEBUG 0 182e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent#define LOG_TAG "SoundPool" 192e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent#include <utils/Log.h> 202e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent 212e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent//#define USE_SHARED_MEM_BUFFER 222e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent 232e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent// XXX needed for timing latency 242e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent#include <utils/Timers.h> 252e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent 262e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent#include <media/AudioTrack.h> 272e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent#include <media/mediaplayer.h> 282e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent 292e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent#include <system/audio.h> 302e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent 31559bf2836f5da25b75bfb229fec0d20d540ee426James Dong#include <media/SoundPool.h> 322e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent#include "SoundPoolThread.h" 332e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent 342e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurentnamespace android 352e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent{ 362e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent 372e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurentint kDefaultBufferCount = 4; 382e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurentuint32_t kMaxSampleRate = 48000; 392e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurentuint32_t kDefaultSampleRate = 44100; 402e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurentuint32_t kDefaultFrameCount = 1200; 412e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent 422e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric LaurentSoundPool::SoundPool(int maxChannels, audio_stream_type_t streamType, int srcQuality) 432e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent{ 442e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent ALOGV("SoundPool constructor: maxChannels=%d, streamType=%d, srcQuality=%d", 452e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent maxChannels, streamType, srcQuality); 462e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent 472e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent // check limits 482e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent mMaxChannels = maxChannels; 492e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent if (mMaxChannels < 1) { 502e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent mMaxChannels = 1; 512e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent } 522e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent else if (mMaxChannels > 32) { 532e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent mMaxChannels = 32; 542e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent } 552e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent ALOGW_IF(maxChannels != mMaxChannels, "App requested %d channels", maxChannels); 562e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent 572e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent mQuit = false; 582e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent mDecodeThread = 0; 592e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent mStreamType = streamType; 602e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent mSrcQuality = srcQuality; 612e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent mAllocated = 0; 622e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent mNextSampleID = 0; 632e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent mNextChannelID = 0; 642e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent 652e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent mCallback = 0; 662e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent mUserData = 0; 672e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent 682e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent mChannelPool = new SoundChannel[mMaxChannels]; 692e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent for (int i = 0; i < mMaxChannels; ++i) { 702e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent mChannelPool[i].init(this); 712e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent mChannels.push_back(&mChannelPool[i]); 722e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent } 732e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent 742e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent // start decode thread 752e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent startThreads(); 762e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent} 772e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent 782e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric LaurentSoundPool::~SoundPool() 792e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent{ 802e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent ALOGV("SoundPool destructor"); 812e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent mDecodeThread->quit(); 822e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent quit(); 832e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent 842e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent Mutex::Autolock lock(&mLock); 852e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent 862e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent mChannels.clear(); 872e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent if (mChannelPool) 882e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent delete [] mChannelPool; 892e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent // clean up samples 902e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent ALOGV("clear samples"); 912e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent mSamples.clear(); 922e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent 932e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent if (mDecodeThread) 942e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent delete mDecodeThread; 952e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent} 962e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent 972e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurentvoid SoundPool::addToRestartList(SoundChannel* channel) 982e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent{ 992e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent Mutex::Autolock lock(&mRestartLock); 1002e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent if (!mQuit) { 1012e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent mRestart.push_back(channel); 1022e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent mCondition.signal(); 1032e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent } 1042e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent} 1052e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent 1062e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurentvoid SoundPool::addToStopList(SoundChannel* channel) 1072e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent{ 1082e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent Mutex::Autolock lock(&mRestartLock); 1092e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent if (!mQuit) { 1102e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent mStop.push_back(channel); 1112e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent mCondition.signal(); 1122e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent } 1132e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent} 1142e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent 1152e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurentint SoundPool::beginThread(void* arg) 1162e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent{ 1172e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent SoundPool* p = (SoundPool*)arg; 1182e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent return p->run(); 1192e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent} 1202e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent 1212e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurentint SoundPool::run() 1222e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent{ 1232e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent mRestartLock.lock(); 1242e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent while (!mQuit) { 1252e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent mCondition.wait(mRestartLock); 1262e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent ALOGV("awake"); 1272e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent if (mQuit) break; 1282e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent 1292e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent while (!mStop.empty()) { 1302e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent SoundChannel* channel; 1312e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent ALOGV("Getting channel from stop list"); 1322e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent List<SoundChannel* >::iterator iter = mStop.begin(); 1332e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent channel = *iter; 1342e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent mStop.erase(iter); 1352e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent mRestartLock.unlock(); 1362e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent if (channel != 0) { 1372e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent Mutex::Autolock lock(&mLock); 1382e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent channel->stop(); 1392e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent } 1402e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent mRestartLock.lock(); 1412e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent if (mQuit) break; 1422e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent } 1432e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent 1442e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent while (!mRestart.empty()) { 1452e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent SoundChannel* channel; 1462e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent ALOGV("Getting channel from list"); 1472e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent List<SoundChannel*>::iterator iter = mRestart.begin(); 1482e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent channel = *iter; 1492e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent mRestart.erase(iter); 1502e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent mRestartLock.unlock(); 1512e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent if (channel != 0) { 1522e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent Mutex::Autolock lock(&mLock); 1532e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent channel->nextEvent(); 1542e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent } 1552e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent mRestartLock.lock(); 1562e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent if (mQuit) break; 1572e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent } 1582e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent } 1592e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent 1602e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent mStop.clear(); 1612e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent mRestart.clear(); 1622e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent mCondition.signal(); 1632e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent mRestartLock.unlock(); 1642e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent ALOGV("goodbye"); 1652e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent return 0; 1662e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent} 1672e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent 1682e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurentvoid SoundPool::quit() 1692e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent{ 1702e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent mRestartLock.lock(); 1712e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent mQuit = true; 1722e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent mCondition.signal(); 1732e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent mCondition.wait(mRestartLock); 1742e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent ALOGV("return from quit"); 1752e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent mRestartLock.unlock(); 1762e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent} 1772e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent 1782e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurentbool SoundPool::startThreads() 1792e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent{ 1802e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent createThreadEtc(beginThread, this, "SoundPool"); 1812e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent if (mDecodeThread == NULL) 1822e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent mDecodeThread = new SoundPoolThread(this); 1832e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent return mDecodeThread != NULL; 1842e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent} 1852e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent 1862e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric LaurentSoundChannel* SoundPool::findChannel(int channelID) 1872e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent{ 1882e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent for (int i = 0; i < mMaxChannels; ++i) { 1892e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent if (mChannelPool[i].channelID() == channelID) { 1902e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent return &mChannelPool[i]; 1912e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent } 1922e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent } 1932e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent return NULL; 1942e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent} 1952e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent 1962e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric LaurentSoundChannel* SoundPool::findNextChannel(int channelID) 1972e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent{ 1982e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent for (int i = 0; i < mMaxChannels; ++i) { 1992e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent if (mChannelPool[i].nextChannelID() == channelID) { 2002e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent return &mChannelPool[i]; 2012e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent } 2022e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent } 2032e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent return NULL; 2042e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent} 2052e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent 2062e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurentint SoundPool::load(const char* path, int priority) 2072e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent{ 2082e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent ALOGV("load: path=%s, priority=%d", path, priority); 2092e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent Mutex::Autolock lock(&mLock); 2102e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent sp<Sample> sample = new Sample(++mNextSampleID, path); 2112e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent mSamples.add(sample->sampleID(), sample); 2122e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent doLoad(sample); 2132e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent return sample->sampleID(); 2142e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent} 2152e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent 2162e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurentint SoundPool::load(int fd, int64_t offset, int64_t length, int priority) 2172e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent{ 2182e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent ALOGV("load: fd=%d, offset=%lld, length=%lld, priority=%d", 2192e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent fd, offset, length, priority); 2202e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent Mutex::Autolock lock(&mLock); 2212e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent sp<Sample> sample = new Sample(++mNextSampleID, fd, offset, length); 2222e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent mSamples.add(sample->sampleID(), sample); 2232e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent doLoad(sample); 2242e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent return sample->sampleID(); 2252e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent} 2262e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent 2272e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurentvoid SoundPool::doLoad(sp<Sample>& sample) 2282e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent{ 2292e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent ALOGV("doLoad: loading sample sampleID=%d", sample->sampleID()); 2302e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent sample->startLoad(); 2312e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent mDecodeThread->loadSample(sample->sampleID()); 2322e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent} 2332e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent 2342e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurentbool SoundPool::unload(int sampleID) 2352e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent{ 2362e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent ALOGV("unload: sampleID=%d", sampleID); 2372e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent Mutex::Autolock lock(&mLock); 2382e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent return mSamples.removeItem(sampleID); 2392e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent} 2402e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent 2412e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurentint SoundPool::play(int sampleID, float leftVolume, float rightVolume, 2422e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent int priority, int loop, float rate) 2432e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent{ 2442e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent ALOGV("play sampleID=%d, leftVolume=%f, rightVolume=%f, priority=%d, loop=%d, rate=%f", 2452e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent sampleID, leftVolume, rightVolume, priority, loop, rate); 2462e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent sp<Sample> sample; 2472e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent SoundChannel* channel; 2482e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent int channelID; 2492e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent 2502e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent Mutex::Autolock lock(&mLock); 2512e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent 2522e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent if (mQuit) { 2532e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent return 0; 2542e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent } 2552e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent // is sample ready? 2562e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent sample = findSample(sampleID); 2572e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent if ((sample == 0) || (sample->state() != Sample::READY)) { 2582e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent ALOGW(" sample %d not READY", sampleID); 2592e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent return 0; 2602e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent } 2612e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent 2622e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent dump(); 2632e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent 2642e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent // allocate a channel 2652e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent channel = allocateChannel_l(priority); 2662e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent 2672e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent // no channel allocated - return 0 2682e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent if (!channel) { 2692e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent ALOGV("No channel allocated"); 2702e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent return 0; 2712e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent } 2722e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent 2732e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent channelID = ++mNextChannelID; 2742e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent 2752e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent ALOGV("play channel %p state = %d", channel, channel->state()); 2762e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent channel->play(sample, channelID, leftVolume, rightVolume, priority, loop, rate); 2772e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent return channelID; 2782e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent} 2792e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent 2802e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric LaurentSoundChannel* SoundPool::allocateChannel_l(int priority) 2812e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent{ 2822e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent List<SoundChannel*>::iterator iter; 2832e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent SoundChannel* channel = NULL; 2842e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent 2852e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent // allocate a channel 2862e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent if (!mChannels.empty()) { 2872e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent iter = mChannels.begin(); 2882e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent if (priority >= (*iter)->priority()) { 2892e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent channel = *iter; 2902e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent mChannels.erase(iter); 2912e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent ALOGV("Allocated active channel"); 2922e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent } 2932e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent } 2942e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent 2952e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent // update priority and put it back in the list 2962e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent if (channel) { 2972e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent channel->setPriority(priority); 2982e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent for (iter = mChannels.begin(); iter != mChannels.end(); ++iter) { 2992e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent if (priority < (*iter)->priority()) { 3002e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent break; 3012e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent } 3022e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent } 3032e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent mChannels.insert(iter, channel); 3042e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent } 3052e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent return channel; 3062e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent} 3072e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent 3082e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent// move a channel from its current position to the front of the list 3092e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurentvoid SoundPool::moveToFront_l(SoundChannel* channel) 3102e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent{ 3112e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent for (List<SoundChannel*>::iterator iter = mChannels.begin(); iter != mChannels.end(); ++iter) { 3122e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent if (*iter == channel) { 3132e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent mChannels.erase(iter); 3142e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent mChannels.push_front(channel); 3152e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent break; 3162e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent } 3172e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent } 3182e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent} 3192e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent 3202e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurentvoid SoundPool::pause(int channelID) 3212e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent{ 3222e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent ALOGV("pause(%d)", channelID); 3232e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent Mutex::Autolock lock(&mLock); 3242e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent SoundChannel* channel = findChannel(channelID); 3252e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent if (channel) { 3262e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent channel->pause(); 3272e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent } 3282e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent} 3292e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent 3302e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurentvoid SoundPool::autoPause() 3312e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent{ 3322e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent ALOGV("autoPause()"); 3332e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent Mutex::Autolock lock(&mLock); 3342e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent for (int i = 0; i < mMaxChannels; ++i) { 3352e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent SoundChannel* channel = &mChannelPool[i]; 3362e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent channel->autoPause(); 3372e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent } 3382e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent} 3392e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent 3402e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurentvoid SoundPool::resume(int channelID) 3412e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent{ 3422e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent ALOGV("resume(%d)", channelID); 3432e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent Mutex::Autolock lock(&mLock); 3442e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent SoundChannel* channel = findChannel(channelID); 3452e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent if (channel) { 3462e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent channel->resume(); 3472e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent } 3482e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent} 3492e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent 3502e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurentvoid SoundPool::autoResume() 3512e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent{ 3522e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent ALOGV("autoResume()"); 3532e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent Mutex::Autolock lock(&mLock); 3542e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent for (int i = 0; i < mMaxChannels; ++i) { 3552e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent SoundChannel* channel = &mChannelPool[i]; 3562e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent channel->autoResume(); 3572e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent } 3582e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent} 3592e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent 3602e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurentvoid SoundPool::stop(int channelID) 3612e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent{ 3622e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent ALOGV("stop(%d)", channelID); 3632e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent Mutex::Autolock lock(&mLock); 3642e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent SoundChannel* channel = findChannel(channelID); 3652e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent if (channel) { 3662e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent channel->stop(); 3672e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent } else { 3682e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent channel = findNextChannel(channelID); 3692e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent if (channel) 3702e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent channel->clearNextEvent(); 3712e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent } 3722e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent} 3732e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent 3742e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurentvoid SoundPool::setVolume(int channelID, float leftVolume, float rightVolume) 3752e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent{ 3762e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent Mutex::Autolock lock(&mLock); 3772e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent SoundChannel* channel = findChannel(channelID); 3782e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent if (channel) { 3792e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent channel->setVolume(leftVolume, rightVolume); 3802e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent } 3812e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent} 3822e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent 3832e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurentvoid SoundPool::setPriority(int channelID, int priority) 3842e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent{ 3852e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent ALOGV("setPriority(%d, %d)", channelID, priority); 3862e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent Mutex::Autolock lock(&mLock); 3872e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent SoundChannel* channel = findChannel(channelID); 3882e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent if (channel) { 3892e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent channel->setPriority(priority); 3902e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent } 3912e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent} 3922e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent 3932e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurentvoid SoundPool::setLoop(int channelID, int loop) 3942e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent{ 3952e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent ALOGV("setLoop(%d, %d)", channelID, loop); 3962e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent Mutex::Autolock lock(&mLock); 3972e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent SoundChannel* channel = findChannel(channelID); 3982e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent if (channel) { 3992e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent channel->setLoop(loop); 4002e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent } 4012e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent} 4022e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent 4032e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurentvoid SoundPool::setRate(int channelID, float rate) 4042e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent{ 4052e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent ALOGV("setRate(%d, %f)", channelID, rate); 4062e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent Mutex::Autolock lock(&mLock); 4072e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent SoundChannel* channel = findChannel(channelID); 4082e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent if (channel) { 4092e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent channel->setRate(rate); 4102e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent } 4112e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent} 4122e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent 4132e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent// call with lock held 4142e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurentvoid SoundPool::done_l(SoundChannel* channel) 4152e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent{ 4162e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent ALOGV("done_l(%d)", channel->channelID()); 4172e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent // if "stolen", play next event 4182e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent if (channel->nextChannelID() != 0) { 4192e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent ALOGV("add to restart list"); 4202e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent addToRestartList(channel); 4212e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent } 4222e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent 4232e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent // return to idle state 4242e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent else { 4252e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent ALOGV("move to front"); 4262e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent moveToFront_l(channel); 4272e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent } 4282e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent} 4292e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent 4302e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurentvoid SoundPool::setCallback(SoundPoolCallback* callback, void* user) 4312e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent{ 4322e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent Mutex::Autolock lock(&mCallbackLock); 4332e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent mCallback = callback; 4342e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent mUserData = user; 4352e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent} 4362e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent 4372e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurentvoid SoundPool::notify(SoundPoolEvent event) 4382e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent{ 4392e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent Mutex::Autolock lock(&mCallbackLock); 4402e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent if (mCallback != NULL) { 4412e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent mCallback(event, this, mUserData); 4422e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent } 4432e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent} 4442e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent 4452e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurentvoid SoundPool::dump() 4462e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent{ 4472e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent for (int i = 0; i < mMaxChannels; ++i) { 4482e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent mChannelPool[i].dump(); 4492e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent } 4502e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent} 4512e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent 4522e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent 4532e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric LaurentSample::Sample(int sampleID, const char* url) 4542e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent{ 4552e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent init(); 4562e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent mSampleID = sampleID; 4572e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent mUrl = strdup(url); 4582e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent ALOGV("create sampleID=%d, url=%s", mSampleID, mUrl); 4592e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent} 4602e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent 4612e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric LaurentSample::Sample(int sampleID, int fd, int64_t offset, int64_t length) 4622e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent{ 4632e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent init(); 4642e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent mSampleID = sampleID; 4652e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent mFd = dup(fd); 4662e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent mOffset = offset; 4672e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent mLength = length; 4682e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent ALOGV("create sampleID=%d, fd=%d, offset=%lld, length=%lld", mSampleID, mFd, mLength, mOffset); 4692e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent} 4702e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent 4712e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurentvoid Sample::init() 4722e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent{ 4732e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent mData = 0; 4742e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent mSize = 0; 4752e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent mRefCount = 0; 4762e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent mSampleID = 0; 4772e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent mState = UNLOADED; 4782e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent mFd = -1; 4792e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent mOffset = 0; 4802e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent mLength = 0; 4812e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent mUrl = 0; 4822e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent} 4832e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent 4842e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric LaurentSample::~Sample() 4852e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent{ 4862e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent ALOGV("Sample::destructor sampleID=%d, fd=%d", mSampleID, mFd); 4872e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent if (mFd > 0) { 4882e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent ALOGV("close(%d)", mFd); 4892e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent ::close(mFd); 4902e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent } 4912e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent mData.clear(); 4922e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent delete mUrl; 4932e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent} 4942e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent 4952e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurentstatus_t Sample::doLoad() 4962e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent{ 4972e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent uint32_t sampleRate; 4982e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent int numChannels; 4992e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent audio_format_t format; 5002e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent sp<IMemory> p; 5012e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent ALOGV("Start decode"); 5022e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent if (mUrl) { 5032e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent p = MediaPlayer::decode(mUrl, &sampleRate, &numChannels, &format); 5042e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent } else { 5052e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent p = MediaPlayer::decode(mFd, mOffset, mLength, &sampleRate, &numChannels, &format); 5062e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent ALOGV("close(%d)", mFd); 5072e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent ::close(mFd); 5082e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent mFd = -1; 5092e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent } 5102e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent if (p == 0) { 5112e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent ALOGE("Unable to load sample: %s", mUrl); 5122e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent return -1; 5132e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent } 5142e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent ALOGV("pointer = %p, size = %u, sampleRate = %u, numChannels = %d", 5152e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent p->pointer(), p->size(), sampleRate, numChannels); 5162e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent 5172e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent if (sampleRate > kMaxSampleRate) { 5182e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent ALOGE("Sample rate (%u) out of range", sampleRate); 5192e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent return - 1; 5202e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent } 5212e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent 5222e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent if ((numChannels < 1) || (numChannels > 2)) { 5232e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent ALOGE("Sample channel count (%d) out of range", numChannels); 5242e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent return - 1; 5252e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent } 5262e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent 5272e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent //_dumpBuffer(p->pointer(), p->size()); 5282e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent uint8_t* q = static_cast<uint8_t*>(p->pointer()) + p->size() - 10; 5292e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent //_dumpBuffer(q, 10, 10, false); 5302e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent 5312e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent mData = p; 5322e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent mSize = p->size(); 5332e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent mSampleRate = sampleRate; 5342e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent mNumChannels = numChannels; 5352e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent mFormat = format; 5362e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent mState = READY; 5372e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent return 0; 5382e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent} 5392e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent 5402e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent 5412e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurentvoid SoundChannel::init(SoundPool* soundPool) 5422e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent{ 5432e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent mSoundPool = soundPool; 5442e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent} 5452e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent 5462e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent// call with sound pool lock held 5472e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurentvoid SoundChannel::play(const sp<Sample>& sample, int nextChannelID, float leftVolume, 5482e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent float rightVolume, int priority, int loop, float rate) 5492e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent{ 5502e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent AudioTrack* oldTrack; 5512e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent AudioTrack* newTrack; 5522e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent status_t status; 5532e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent 5542e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent { // scope for the lock 5552e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent Mutex::Autolock lock(&mLock); 5562e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent 5572e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent ALOGV("SoundChannel::play %p: sampleID=%d, channelID=%d, leftVolume=%f, rightVolume=%f," 5582e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent " priority=%d, loop=%d, rate=%f", 5592e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent this, sample->sampleID(), nextChannelID, leftVolume, rightVolume, 5602e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent priority, loop, rate); 5612e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent 5622e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent // if not idle, this voice is being stolen 5632e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent if (mState != IDLE) { 5642e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent ALOGV("channel %d stolen - event queued for channel %d", channelID(), nextChannelID); 5652e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent mNextEvent.set(sample, nextChannelID, leftVolume, rightVolume, priority, loop, rate); 5662e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent stop_l(); 5672e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent return; 5682e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent } 5692e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent 5702e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent // initialize track 5712e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent int afFrameCount; 5722e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent int afSampleRate; 5732e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent audio_stream_type_t streamType = mSoundPool->streamType(); 5742e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent if (AudioSystem::getOutputFrameCount(&afFrameCount, streamType) != NO_ERROR) { 5752e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent afFrameCount = kDefaultFrameCount; 5762e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent } 5772e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent if (AudioSystem::getOutputSamplingRate(&afSampleRate, streamType) != NO_ERROR) { 5782e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent afSampleRate = kDefaultSampleRate; 5792e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent } 5802e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent int numChannels = sample->numChannels(); 5812e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent uint32_t sampleRate = uint32_t(float(sample->sampleRate()) * rate + 0.5); 5822e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent uint32_t totalFrames = (kDefaultBufferCount * afFrameCount * sampleRate) / afSampleRate; 5832e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent uint32_t bufferFrames = (totalFrames + (kDefaultBufferCount - 1)) / kDefaultBufferCount; 5842e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent uint32_t frameCount = 0; 5852e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent 5862e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent if (loop) { 5872e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent frameCount = sample->size()/numChannels/ 5882e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent ((sample->format() == AUDIO_FORMAT_PCM_16_BIT) ? sizeof(int16_t) : sizeof(uint8_t)); 5892e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent } 5902e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent 5912e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent#ifndef USE_SHARED_MEM_BUFFER 5922e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent // Ensure minimum audio buffer size in case of short looped sample 5932e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent if(frameCount < totalFrames) { 5942e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent frameCount = totalFrames; 5952e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent } 5962e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent#endif 5972e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent 5982e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent // mToggle toggles each time a track is started on a given channel. 5992e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent // The toggle is concatenated with the SoundChannel address and passed to AudioTrack 6002e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent // as callback user data. This enables the detection of callbacks received from the old 6012e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent // audio track while the new one is being started and avoids processing them with 6022e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent // wrong audio audio buffer size (mAudioBufferSize) 6032e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent unsigned long toggle = mToggle ^ 1; 6042e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent void *userData = (void *)((unsigned long)this | toggle); 6052e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent uint32_t channels = (numChannels == 2) ? 6062e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent AUDIO_CHANNEL_OUT_STEREO : AUDIO_CHANNEL_OUT_MONO; 6072e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent 6082e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent // do not create a new audio track if current track is compatible with sample parameters 6092e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent#ifdef USE_SHARED_MEM_BUFFER 6102e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent newTrack = new AudioTrack(streamType, sampleRate, sample->format(), 6110ca3cf94c0dfc173ad7886ae162c4b67067539f6Eric Laurent channels, sample->getIMemory(), AUDIO_OUTPUT_FLAG_NONE, callback, userData); 6122e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent#else 6132e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent newTrack = new AudioTrack(streamType, sampleRate, sample->format(), 6141477e92867a950016579a644e74f803ed1d90cbbGlenn Kasten channels, frameCount, AUDIO_OUTPUT_FLAG_FAST, callback, userData, 6152e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent bufferFrames); 6162e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent#endif 6172e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent oldTrack = mAudioTrack; 6182e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent status = newTrack->initCheck(); 6192e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent if (status != NO_ERROR) { 6202e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent ALOGE("Error creating AudioTrack"); 6212e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent goto exit; 6222e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent } 6232e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent ALOGV("setVolume %p", newTrack); 6242e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent newTrack->setVolume(leftVolume, rightVolume); 6252e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent newTrack->setLoop(0, frameCount, loop); 6262e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent 6272e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent // From now on, AudioTrack callbacks received with previous toggle value will be ignored. 6282e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent mToggle = toggle; 6292e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent mAudioTrack = newTrack; 6302e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent mPos = 0; 6312e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent mSample = sample; 6322e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent mChannelID = nextChannelID; 6332e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent mPriority = priority; 6342e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent mLoop = loop; 6352e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent mLeftVolume = leftVolume; 6362e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent mRightVolume = rightVolume; 6372e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent mNumChannels = numChannels; 6382e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent mRate = rate; 6392e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent clearNextEvent(); 6402e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent mState = PLAYING; 6412e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent mAudioTrack->start(); 6422e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent mAudioBufferSize = newTrack->frameCount()*newTrack->frameSize(); 6432e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent } 6442e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent 6452e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurentexit: 6462e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent ALOGV("delete oldTrack %p", oldTrack); 6472e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent delete oldTrack; 6482e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent if (status != NO_ERROR) { 6492e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent delete newTrack; 6502e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent mAudioTrack = NULL; 6512e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent } 6522e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent} 6532e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent 6542e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurentvoid SoundChannel::nextEvent() 6552e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent{ 6562e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent sp<Sample> sample; 6572e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent int nextChannelID; 6582e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent float leftVolume; 6592e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent float rightVolume; 6602e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent int priority; 6612e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent int loop; 6622e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent float rate; 6632e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent 6642e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent // check for valid event 6652e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent { 6662e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent Mutex::Autolock lock(&mLock); 6672e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent nextChannelID = mNextEvent.channelID(); 6682e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent if (nextChannelID == 0) { 6692e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent ALOGV("stolen channel has no event"); 6702e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent return; 6712e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent } 6722e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent 6732e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent sample = mNextEvent.sample(); 6742e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent leftVolume = mNextEvent.leftVolume(); 6752e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent rightVolume = mNextEvent.rightVolume(); 6762e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent priority = mNextEvent.priority(); 6772e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent loop = mNextEvent.loop(); 6782e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent rate = mNextEvent.rate(); 6792e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent } 6802e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent 6812e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent ALOGV("Starting stolen channel %d -> %d", channelID(), nextChannelID); 6822e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent play(sample, nextChannelID, leftVolume, rightVolume, priority, loop, rate); 6832e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent} 6842e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent 6852e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurentvoid SoundChannel::callback(int event, void* user, void *info) 6862e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent{ 6872e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent SoundChannel* channel = static_cast<SoundChannel*>((void *)((unsigned long)user & ~1)); 6882e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent 6892e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent channel->process(event, info, (unsigned long)user & 1); 6902e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent} 6912e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent 6922e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurentvoid SoundChannel::process(int event, void *info, unsigned long toggle) 6932e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent{ 6942e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent //ALOGV("process(%d)", mChannelID); 6952e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent 6962e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent Mutex::Autolock lock(&mLock); 6972e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent 6982e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent AudioTrack::Buffer* b = NULL; 6992e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent if (event == AudioTrack::EVENT_MORE_DATA) { 7002e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent b = static_cast<AudioTrack::Buffer *>(info); 7012e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent } 7022e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent 7032e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent if (mToggle != toggle) { 7042e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent ALOGV("process wrong toggle %p channel %d", this, mChannelID); 7052e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent if (b != NULL) { 7062e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent b->size = 0; 7072e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent } 7082e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent return; 7092e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent } 7102e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent 7112e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent sp<Sample> sample = mSample; 7122e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent 7132e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent// ALOGV("SoundChannel::process event %d", event); 7142e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent 7152e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent if (event == AudioTrack::EVENT_MORE_DATA) { 7162e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent 7172e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent // check for stop state 7182e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent if (b->size == 0) return; 7192e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent 7202e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent if (mState == IDLE) { 7212e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent b->size = 0; 7222e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent return; 7232e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent } 7242e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent 7252e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent if (sample != 0) { 7262e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent // fill buffer 7272e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent uint8_t* q = (uint8_t*) b->i8; 7282e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent size_t count = 0; 7292e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent 7302e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent if (mPos < (int)sample->size()) { 7312e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent uint8_t* p = sample->data() + mPos; 7322e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent count = sample->size() - mPos; 7332e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent if (count > b->size) { 7342e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent count = b->size; 7352e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent } 7362e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent memcpy(q, p, count); 7372e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent// ALOGV("fill: q=%p, p=%p, mPos=%u, b->size=%u, count=%d", q, p, mPos, b->size, count); 7382e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent } else if (mPos < mAudioBufferSize) { 7392e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent count = mAudioBufferSize - mPos; 7402e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent if (count > b->size) { 7412e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent count = b->size; 7422e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent } 7432e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent memset(q, 0, count); 7442e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent// ALOGV("fill extra: q=%p, mPos=%u, b->size=%u, count=%d", q, mPos, b->size, count); 7452e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent } 7462e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent 7472e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent mPos += count; 7482e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent b->size = count; 7492e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent //ALOGV("buffer=%p, [0]=%d", b->i16, b->i16[0]); 7502e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent } 7512e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent } else if (event == AudioTrack::EVENT_UNDERRUN) { 7522e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent ALOGV("process %p channel %d EVENT_UNDERRUN", this, mChannelID); 7532e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent mSoundPool->addToStopList(this); 7542e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent } else if (event == AudioTrack::EVENT_LOOP_END) { 7552e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent ALOGV("End loop %p channel %d count %d", this, mChannelID, *(int *)info); 7562e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent } 7572e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent} 7582e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent 7592e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent 7602e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent// call with lock held 7612e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurentbool SoundChannel::doStop_l() 7622e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent{ 7632e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent if (mState != IDLE) { 7642e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent setVolume_l(0, 0); 7652e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent ALOGV("stop"); 7662e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent mAudioTrack->stop(); 7672e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent mSample.clear(); 7682e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent mState = IDLE; 7692e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent mPriority = IDLE_PRIORITY; 7702e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent return true; 7712e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent } 7722e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent return false; 7732e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent} 7742e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent 7752e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent// call with lock held and sound pool lock held 7762e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurentvoid SoundChannel::stop_l() 7772e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent{ 7782e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent if (doStop_l()) { 7792e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent mSoundPool->done_l(this); 7802e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent } 7812e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent} 7822e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent 7832e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent// call with sound pool lock held 7842e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurentvoid SoundChannel::stop() 7852e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent{ 7862e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent bool stopped; 7872e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent { 7882e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent Mutex::Autolock lock(&mLock); 7892e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent stopped = doStop_l(); 7902e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent } 7912e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent 7922e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent if (stopped) { 7932e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent mSoundPool->done_l(this); 7942e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent } 7952e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent} 7962e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent 7972e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent//FIXME: Pause is a little broken right now 7982e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurentvoid SoundChannel::pause() 7992e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent{ 8002e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent Mutex::Autolock lock(&mLock); 8012e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent if (mState == PLAYING) { 8022e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent ALOGV("pause track"); 8032e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent mState = PAUSED; 8042e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent mAudioTrack->pause(); 8052e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent } 8062e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent} 8072e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent 8082e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurentvoid SoundChannel::autoPause() 8092e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent{ 8102e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent Mutex::Autolock lock(&mLock); 8112e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent if (mState == PLAYING) { 8122e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent ALOGV("pause track"); 8132e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent mState = PAUSED; 8142e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent mAutoPaused = true; 8152e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent mAudioTrack->pause(); 8162e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent } 8172e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent} 8182e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent 8192e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurentvoid SoundChannel::resume() 8202e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent{ 8212e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent Mutex::Autolock lock(&mLock); 8222e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent if (mState == PAUSED) { 8232e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent ALOGV("resume track"); 8242e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent mState = PLAYING; 8252e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent mAutoPaused = false; 8262e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent mAudioTrack->start(); 8272e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent } 8282e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent} 8292e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent 8302e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurentvoid SoundChannel::autoResume() 8312e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent{ 8322e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent Mutex::Autolock lock(&mLock); 8332e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent if (mAutoPaused && (mState == PAUSED)) { 8342e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent ALOGV("resume track"); 8352e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent mState = PLAYING; 8362e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent mAutoPaused = false; 8372e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent mAudioTrack->start(); 8382e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent } 8392e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent} 8402e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent 8412e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurentvoid SoundChannel::setRate(float rate) 8422e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent{ 8432e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent Mutex::Autolock lock(&mLock); 8442e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent if (mAudioTrack != NULL && mSample != 0) { 8452e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent uint32_t sampleRate = uint32_t(float(mSample->sampleRate()) * rate + 0.5); 8462e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent mAudioTrack->setSampleRate(sampleRate); 8472e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent mRate = rate; 8482e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent } 8492e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent} 8502e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent 8512e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent// call with lock held 8522e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurentvoid SoundChannel::setVolume_l(float leftVolume, float rightVolume) 8532e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent{ 8542e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent mLeftVolume = leftVolume; 8552e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent mRightVolume = rightVolume; 8562e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent if (mAudioTrack != NULL) 8572e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent mAudioTrack->setVolume(leftVolume, rightVolume); 8582e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent} 8592e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent 8602e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurentvoid SoundChannel::setVolume(float leftVolume, float rightVolume) 8612e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent{ 8622e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent Mutex::Autolock lock(&mLock); 8632e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent setVolume_l(leftVolume, rightVolume); 8642e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent} 8652e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent 8662e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurentvoid SoundChannel::setLoop(int loop) 8672e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent{ 8682e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent Mutex::Autolock lock(&mLock); 8692e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent if (mAudioTrack != NULL && mSample != 0) { 8702e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent uint32_t loopEnd = mSample->size()/mNumChannels/ 8712e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent ((mSample->format() == AUDIO_FORMAT_PCM_16_BIT) ? sizeof(int16_t) : sizeof(uint8_t)); 8722e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent mAudioTrack->setLoop(0, loopEnd, loop); 8732e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent mLoop = loop; 8742e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent } 8752e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent} 8762e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent 8772e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric LaurentSoundChannel::~SoundChannel() 8782e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent{ 8792e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent ALOGV("SoundChannel destructor %p", this); 8802e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent { 8812e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent Mutex::Autolock lock(&mLock); 8822e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent clearNextEvent(); 8832e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent doStop_l(); 8842e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent } 8852e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent // do not call AudioTrack destructor with mLock held as it will wait for the AudioTrack 8862e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent // callback thread to exit which may need to execute process() and acquire the mLock. 8872e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent delete mAudioTrack; 8882e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent} 8892e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent 8902e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurentvoid SoundChannel::dump() 8912e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent{ 8922e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent ALOGV("mState = %d mChannelID=%d, mNumChannels=%d, mPos = %d, mPriority=%d, mLoop=%d", 8932e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent mState, mChannelID, mNumChannels, mPos, mPriority, mLoop); 8942e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent} 8952e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent 8962e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurentvoid SoundEvent::set(const sp<Sample>& sample, int channelID, float leftVolume, 8972e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent float rightVolume, int priority, int loop, float rate) 8982e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent{ 8992e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent mSample = sample; 9002e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent mChannelID = channelID; 9012e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent mLeftVolume = leftVolume; 9022e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent mRightVolume = rightVolume; 9032e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent mPriority = priority; 9042e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent mLoop = loop; 9052e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent mRate =rate; 9062e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent} 9072e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent 9082e66a7896c9a9da3a15fc6cff9be28b4174d8719Eric Laurent} // end namespace android 909