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