1 /*
2 * Copyright (C) 2007 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 //#define LOG_NDEBUG 0
18 #define LOG_TAG "SoundPoolThread"
19 #include "utils/Log.h"
20
21 #include "SoundPoolThread.h"
22
23 namespace android {
24
write(SoundPoolMsg msg)25 void SoundPoolThread::write(SoundPoolMsg msg) {
26 Mutex::Autolock lock(&mLock);
27 while (mMsgQueue.size() >= maxMessages) {
28 mCondition.wait(mLock);
29 }
30
31 // if thread is quitting, don't add to queue
32 if (mRunning) {
33 mMsgQueue.push(msg);
34 mCondition.signal();
35 }
36 }
37
read()38 const SoundPoolMsg SoundPoolThread::read() {
39 Mutex::Autolock lock(&mLock);
40 while (mMsgQueue.size() == 0) {
41 mCondition.wait(mLock);
42 }
43 SoundPoolMsg msg = mMsgQueue[0];
44 mMsgQueue.removeAt(0);
45 mCondition.signal();
46 return msg;
47 }
48
quit()49 void SoundPoolThread::quit() {
50 Mutex::Autolock lock(&mLock);
51 if (mRunning) {
52 mRunning = false;
53 mMsgQueue.clear();
54 mMsgQueue.push(SoundPoolMsg(SoundPoolMsg::KILL, 0));
55 mCondition.signal();
56 mCondition.wait(mLock);
57 }
58 ALOGV("return from quit");
59 }
60
SoundPoolThread(SoundPool * soundPool)61 SoundPoolThread::SoundPoolThread(SoundPool* soundPool) :
62 mSoundPool(soundPool)
63 {
64 mMsgQueue.setCapacity(maxMessages);
65 if (createThreadEtc(beginThread, this, "SoundPoolThread")) {
66 mRunning = true;
67 }
68 }
69
~SoundPoolThread()70 SoundPoolThread::~SoundPoolThread()
71 {
72 quit();
73 }
74
beginThread(void * arg)75 int SoundPoolThread::beginThread(void* arg) {
76 ALOGV("beginThread");
77 SoundPoolThread* soundPoolThread = (SoundPoolThread*)arg;
78 return soundPoolThread->run();
79 }
80
run()81 int SoundPoolThread::run() {
82 ALOGV("run");
83 for (;;) {
84 SoundPoolMsg msg = read();
85 ALOGV("Got message m=%d, mData=%d", msg.mMessageType, msg.mData);
86 switch (msg.mMessageType) {
87 case SoundPoolMsg::KILL:
88 ALOGV("goodbye");
89 return NO_ERROR;
90 case SoundPoolMsg::LOAD_SAMPLE:
91 doLoadSample(msg.mData);
92 break;
93 default:
94 ALOGW("run: Unrecognized message %d\n",
95 msg.mMessageType);
96 break;
97 }
98 }
99 }
100
loadSample(int sampleID)101 void SoundPoolThread::loadSample(int sampleID) {
102 write(SoundPoolMsg(SoundPoolMsg::LOAD_SAMPLE, sampleID));
103 }
104
doLoadSample(int sampleID)105 void SoundPoolThread::doLoadSample(int sampleID) {
106 sp <Sample> sample = mSoundPool->findSample(sampleID);
107 status_t status = -1;
108 if (sample != 0) {
109 status = sample->doLoad();
110 }
111 mSoundPool->notify(SoundPoolEvent(SoundPoolEvent::SAMPLE_LOADED, sampleID, status));
112 }
113
114 } // end namespace android
115