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 "SoundPoolThread"
19372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen#include "utils/Log.h"
20372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen
21372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen#include "SoundPoolThread.h"
22372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen
23372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissennamespace android {
24372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen
25372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissenvoid SoundPoolThread::write(SoundPoolMsg msg) {
26372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen    Mutex::Autolock lock(&mLock);
27372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen    while (mMsgQueue.size() >= maxMessages) {
28372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen        mCondition.wait(mLock);
29372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen    }
30372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen
31372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen    // if thread is quitting, don't add to queue
32372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen    if (mRunning) {
33372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen        mMsgQueue.push(msg);
34372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen        mCondition.signal();
35372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen    }
36372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen}
37372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen
38372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissenconst SoundPoolMsg SoundPoolThread::read() {
39372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen    Mutex::Autolock lock(&mLock);
40372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen    while (mMsgQueue.size() == 0) {
41372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen        mCondition.wait(mLock);
42372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen    }
43372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen    SoundPoolMsg msg = mMsgQueue[0];
44372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen    mMsgQueue.removeAt(0);
45372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen    mCondition.signal();
46372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen    return msg;
47372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen}
48372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen
49372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissenvoid SoundPoolThread::quit() {
50372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen    Mutex::Autolock lock(&mLock);
51372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen    if (mRunning) {
52372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen        mRunning = false;
53372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen        mMsgQueue.clear();
54372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen        mMsgQueue.push(SoundPoolMsg(SoundPoolMsg::KILL, 0));
55372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen        mCondition.signal();
56372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen        mCondition.wait(mLock);
57372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen    }
58372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen    ALOGV("return from quit");
59372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen}
60372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen
61372be8970c6ab68c295fb74dbb878ab1d443d90eMarco NelissenSoundPoolThread::SoundPoolThread(SoundPool* soundPool) :
62372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen    mSoundPool(soundPool)
63372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen{
64372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen    mMsgQueue.setCapacity(maxMessages);
65372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen    if (createThreadEtc(beginThread, this, "SoundPoolThread")) {
66372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen        mRunning = true;
67372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen    }
68372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen}
69372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen
70372be8970c6ab68c295fb74dbb878ab1d443d90eMarco NelissenSoundPoolThread::~SoundPoolThread()
71372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen{
72372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen    quit();
73372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen}
74372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen
75372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissenint SoundPoolThread::beginThread(void* arg) {
76372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen    ALOGV("beginThread");
77372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen    SoundPoolThread* soundPoolThread = (SoundPoolThread*)arg;
78372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen    return soundPoolThread->run();
79372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen}
80372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen
81372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissenint SoundPoolThread::run() {
82372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen    ALOGV("run");
83372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen    for (;;) {
84372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen        SoundPoolMsg msg = read();
85372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen        ALOGV("Got message m=%d, mData=%d", msg.mMessageType, msg.mData);
86372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen        switch (msg.mMessageType) {
87372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen        case SoundPoolMsg::KILL:
88372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen            ALOGV("goodbye");
89372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen            return NO_ERROR;
90372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen        case SoundPoolMsg::LOAD_SAMPLE:
91372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen            doLoadSample(msg.mData);
92372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen            break;
93372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen        default:
94372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen            ALOGW("run: Unrecognized message %d\n",
95372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen                    msg.mMessageType);
96372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen            break;
97372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen        }
98372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen    }
99372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen}
100372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen
101372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissenvoid SoundPoolThread::loadSample(int sampleID) {
102372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen    write(SoundPoolMsg(SoundPoolMsg::LOAD_SAMPLE, sampleID));
103372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen}
104372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen
105372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissenvoid SoundPoolThread::doLoadSample(int sampleID) {
106372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen    sp <Sample> sample = mSoundPool->findSample(sampleID);
107372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen    status_t status = -1;
108372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen    if (sample != 0) {
109372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen        status = sample->doLoad();
110372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen    }
111372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen    mSoundPool->notify(SoundPoolEvent(SoundPoolEvent::SAMPLE_LOADED, sampleID, status));
112372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen}
113372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen
114372be8970c6ab68c295fb74dbb878ab1d443d90eMarco Nelissen} // end namespace android
115