Loading media/java/android/media/SoundPool.java +104 −6 Original line number Diff line number Diff line Loading @@ -26,6 +26,10 @@ import android.content.Context; import android.content.res.AssetFileDescriptor; import java.io.IOException; import android.os.Handler; import android.os.Looper; import android.os.Message; /** * The SoundPool class manages and plays audio resources for applications. * Loading Loading @@ -103,9 +107,20 @@ public class SoundPool static { System.loadLibrary("soundpool"); } private final static String TAG = "SoundPool"; private final static boolean DEBUG = false; private int mNativeContext; // accessed by native methods private EventHandler mEventHandler; private OnLoadCompleteListener mOnLoadCompleteListener; private final Object mLock; // SoundPool messages // // must match SoundPool.h private static final int SAMPLE_LOADED = 1; /** * Constructor. Constructs a SoundPool object with the following * characteristics: Loading @@ -120,7 +135,23 @@ public class SoundPool * @return a SoundPool object, or null if creation failed */ public SoundPool(int maxStreams, int streamType, int srcQuality) { native_setup(new WeakReference<SoundPool>(this), maxStreams, streamType, srcQuality); // do native setup if (native_setup(new WeakReference(this), maxStreams, streamType, srcQuality) != 0) { throw new RuntimeException("Native setup failed"); } mLock = new Object(); // setup message handler Looper looper; if ((looper = Looper.myLooper()) != null) { mEventHandler = new EventHandler(this, looper); } else if ((looper = Looper.getMainLooper()) != null) { mEventHandler = new EventHandler(this, looper); } else { mEventHandler = null; } } /** Loading @@ -145,12 +176,11 @@ public class SoundPool ParcelFileDescriptor fd = ParcelFileDescriptor.open(f, ParcelFileDescriptor.MODE_READ_ONLY); if (fd != null) { id = _load(fd.getFileDescriptor(), 0, f.length(), priority); //Log.v(TAG, "close fd"); fd.close(); } } } catch (java.io.IOException e) { Log.d(TAG, "error loading " + path); Log.e(TAG, "error loading " + path); } return id; } Loading @@ -176,7 +206,6 @@ public class SoundPool if (afd != null) { id = _load(afd.getFileDescriptor(), afd.getStartOffset(), afd.getLength(), priority); try { //Log.v(TAG, "close fd"); afd.close(); } catch (java.io.IOException ex) { //Log.d(TAG, "close failed:", ex); Loading Loading @@ -358,6 +387,76 @@ public class SoundPool */ public native final void setRate(int streamID, float rate); /** * Interface definition for a callback to be invoked when all the * sounds are loaded. * * @hide */ public interface OnLoadCompleteListener { /** * Called when a sound has completed loading. * * @param soundPool SoundPool object from the load() method * @param soundPool the sample ID of the sound loaded. * @param status the status of the load operation (0 = success) */ public void onLoadComplete(SoundPool soundPool, int sampleId, int status); } /** * Sets the callback hook for the OnLoadCompleteListener. * * @hide */ public void setOnLoadCompleteListener(OnLoadCompleteListener listener) { synchronized(mLock) { mOnLoadCompleteListener = listener; } } private class EventHandler extends Handler { private SoundPool mSoundPool; public EventHandler(SoundPool soundPool, Looper looper) { super(looper); mSoundPool = soundPool; } @Override public void handleMessage(Message msg) { switch(msg.what) { case SAMPLE_LOADED: if (DEBUG) Log.d(TAG, "Sample " + msg.arg1 + " loaded"); synchronized(mLock) { if (mOnLoadCompleteListener != null) { mOnLoadCompleteListener.onLoadComplete(mSoundPool, msg.arg1, msg.arg2); } } break; default: Log.e(TAG, "Unknown message type " + msg.what); return; } } } // post event from native code to message handler private static void postEventFromNative(Object weakRef, int msg, int arg1, int arg2, Object obj) { SoundPool soundPool = (SoundPool)((WeakReference)weakRef).get(); if (soundPool == null) return; if (soundPool.mEventHandler != null) { Message m = soundPool.mEventHandler.obtainMessage(msg, arg1, arg2, obj); soundPool.mEventHandler.sendMessage(m); } } /** * Release the SoundPool resources. * Loading @@ -367,8 +466,7 @@ public class SoundPool */ public native final void release(); private native final void native_setup(Object mediaplayer_this, int maxStreams, int streamType, int srcQuality); private native final int native_setup(Object weakRef, int maxStreams, int streamType, int srcQuality); protected void finalize() { release(); } } media/jni/soundpool/SoundPool.cpp +24 −5 Original line number Diff line number Diff line Loading @@ -61,6 +61,9 @@ SoundPool::SoundPool(int maxChannels, int streamType, int srcQuality) mNextSampleID = 0; mNextChannelID = 0; mCallback = 0; mUserData = 0; mChannelPool = new SoundChannel[mMaxChannels]; for (int i = 0; i < mMaxChannels; ++i) { mChannelPool[i].init(this); Loading Loading @@ -141,7 +144,7 @@ void SoundPool::quit() bool SoundPool::startThreads() { createThread(beginThread, this); createThreadEtc(beginThread, this, "SoundPoolThread"); if (mDecodeThread == NULL) mDecodeThread = new SoundPoolThread(this); return mDecodeThread != NULL; Loading Loading @@ -372,6 +375,21 @@ void SoundPool::done(SoundChannel* channel) } } void SoundPool::setCallback(SoundPoolCallback* callback, void* user) { Mutex::Autolock lock(&mCallbackLock); mCallback = callback; mUserData = user; } void SoundPool::notify(SoundPoolEvent event) { Mutex::Autolock lock(&mCallbackLock); if (mCallback != NULL) { mCallback(event, this, mUserData); } } void SoundPool::dump() { for (int i = 0; i < mMaxChannels; ++i) { Loading Loading @@ -422,7 +440,7 @@ Sample::~Sample() delete mUrl; } void Sample::doLoad() status_t Sample::doLoad() { uint32_t sampleRate; int numChannels; Loading @@ -439,19 +457,19 @@ void Sample::doLoad() } if (p == 0) { LOGE("Unable to load sample: %s", mUrl); return; return -1; } LOGV("pointer = %p, size = %u, sampleRate = %u, numChannels = %d", p->pointer(), p->size(), sampleRate, numChannels); if (sampleRate > kMaxSampleRate) { LOGE("Sample rate (%u) out of range", sampleRate); return; return - 1; } if ((numChannels < 1) || (numChannels > 2)) { LOGE("Sample channel count (%d) out of range", numChannels); return; return - 1; } //_dumpBuffer(p->pointer(), p->size()); Loading @@ -464,6 +482,7 @@ void Sample::doLoad() mNumChannels = numChannels; mFormat = format; mState = READY; return 0; } Loading media/jni/soundpool/SoundPool.h +14 −5 Original line number Diff line number Diff line Loading @@ -24,8 +24,6 @@ #include <media/AudioTrack.h> #include <cutils/atomic.h> #include <nativehelper/jni.h> namespace android { static const int IDLE_PRIORITY = -1; Loading @@ -43,10 +41,11 @@ public: int mMsg; int mArg1; int mArg2; enum MessageType { INVALID, SAMPLE_LOADED }; }; // JNI for calling back Java SoundPool object extern void android_soundpool_SoundPool_notify(jobject ref, const SoundPoolEvent *event); // callback function prototype typedef void SoundPoolCallback(SoundPoolEvent event, SoundPool* soundPool, void* user); // tracks samples used by application class Sample : public RefBase { Loading @@ -62,7 +61,7 @@ public: size_t size() { return mSize; } int state() { return mState; } uint8_t* data() { return static_cast<uint8_t*>(mData->pointer()); } void doLoad(); status_t doLoad(); void startLoad() { mState = LOADING; } sp<IMemory> getIMemory() { return mData; } Loading Loading @@ -182,6 +181,10 @@ public: // called from AudioTrack thread void done(SoundChannel* channel); // callback function void setCallback(SoundPoolCallback* callback, void* user); void* getUserData() { return mUserData; } private: SoundPool() {} // no default constructor bool startThreads(); Loading @@ -191,6 +194,7 @@ private: SoundChannel* findNextChannel (int channelID); SoundChannel* allocateChannel(int priority); void moveToFront(SoundChannel* channel); void notify(SoundPoolEvent event); void dump(); // restart thread Loading @@ -214,6 +218,11 @@ private: int mNextSampleID; int mNextChannelID; bool mQuit; // callback Mutex mCallbackLock; SoundPoolCallback* mCallback; void* mUserData; }; } // end namespace android Loading media/jni/soundpool/SoundPoolThread.cpp +30 −24 Original line number Diff line number Diff line Loading @@ -22,50 +22,54 @@ namespace android { void SoundPoolThread::MessageQueue::write(SoundPoolMsg msg) { LOGV("MessageQueue::write - acquiring lock\n"); void SoundPoolThread::write(SoundPoolMsg msg) { Mutex::Autolock lock(&mLock); while (mQueue.size() >= maxMessages) { LOGV("MessageQueue::write - wait\n"); while (mMsgQueue.size() >= maxMessages) { mCondition.wait(mLock); } LOGV("MessageQueue::write - push message\n"); mQueue.push(msg); // if thread is quitting, don't add to queue if (mRunning) { mMsgQueue.push(msg); mCondition.signal(); } } const SoundPoolMsg SoundPoolThread::MessageQueue::read() { LOGV("MessageQueue::read - acquiring lock\n"); const SoundPoolMsg SoundPoolThread::read() { Mutex::Autolock lock(&mLock); while (mQueue.size() == 0) { LOGV("MessageQueue::read - wait\n"); while (mMsgQueue.size() == 0) { mCondition.wait(mLock); } SoundPoolMsg msg = mQueue[0]; LOGV("MessageQueue::read - retrieve message\n"); mQueue.removeAt(0); SoundPoolMsg msg = mMsgQueue[0]; mMsgQueue.removeAt(0); mCondition.signal(); return msg; } void SoundPoolThread::MessageQueue::quit() { void SoundPoolThread::quit() { Mutex::Autolock lock(&mLock); mQueue.clear(); mQueue.push(SoundPoolMsg(SoundPoolMsg::KILL, 0)); if (mRunning) { mRunning = false; mMsgQueue.clear(); mMsgQueue.push(SoundPoolMsg(SoundPoolMsg::KILL, 0)); mCondition.signal(); mCondition.wait(mLock); } LOGV("return from quit"); } SoundPoolThread::SoundPoolThread(SoundPool* soundPool) : mSoundPool(soundPool) { mMessages.setCapacity(maxMessages); createThread(beginThread, this); mMsgQueue.setCapacity(maxMessages); if (createThread(beginThread, this)) { mRunning = true; } } SoundPoolThread::~SoundPoolThread() { quit(); } int SoundPoolThread::beginThread(void* arg) { Loading @@ -77,7 +81,7 @@ int SoundPoolThread::beginThread(void* arg) { int SoundPoolThread::run() { LOGV("run"); for (;;) { SoundPoolMsg msg = mMessages.read(); SoundPoolMsg msg = read(); LOGV("Got message m=%d, mData=%d", msg.mMessageType, msg.mData); switch (msg.mMessageType) { case SoundPoolMsg::KILL: Loading @@ -95,14 +99,16 @@ int SoundPoolThread::run() { } void SoundPoolThread::loadSample(int sampleID) { mMessages.write(SoundPoolMsg(SoundPoolMsg::LOAD_SAMPLE, sampleID)); write(SoundPoolMsg(SoundPoolMsg::LOAD_SAMPLE, sampleID)); } void SoundPoolThread::doLoadSample(int sampleID) { sp <Sample> sample = mSoundPool->findSample(sampleID); status_t status = -1; if (sample != 0) { sample->doLoad(); status = sample->doLoad(); } mSoundPool->notify(SoundPoolEvent(SoundPoolEvent::SAMPLE_LOADED, sampleID, status)); } } // end namespace android media/jni/soundpool/SoundPoolThread.h +9 −16 Original line number Diff line number Diff line Loading @@ -27,7 +27,7 @@ namespace android { class SoundPoolMsg { public: enum MessageType { INVALID, KILL, LOAD_SAMPLE, PLAY_SAMPLE, SAMPLE_DONE }; enum MessageType { INVALID, KILL, LOAD_SAMPLE }; SoundPoolMsg() : mMessageType(INVALID), mData(0) {} SoundPoolMsg(MessageType MessageType, int data) : mMessageType(MessageType), mData(data) {} Loading @@ -45,29 +45,22 @@ public: SoundPoolThread(SoundPool* SoundPool); ~SoundPoolThread(); void loadSample(int sampleID); void quit() { mMessages.quit(); } void quit(); void write(SoundPoolMsg msg); private: static const size_t maxMessages = 5; class MessageQueue { public: void write(SoundPoolMsg msg); const SoundPoolMsg read(); void setCapacity(size_t size) { mQueue.setCapacity(size); } void quit(); private: Vector<SoundPoolMsg> mQueue; Mutex mLock; Condition mCondition; }; static int beginThread(void* arg); int run(); void doLoadSample(int sampleID); const SoundPoolMsg read(); Mutex mLock; Condition mCondition; Vector<SoundPoolMsg> mMsgQueue; SoundPool* mSoundPool; MessageQueue mMessages; bool mRunning; }; } // end namespace android Loading Loading
media/java/android/media/SoundPool.java +104 −6 Original line number Diff line number Diff line Loading @@ -26,6 +26,10 @@ import android.content.Context; import android.content.res.AssetFileDescriptor; import java.io.IOException; import android.os.Handler; import android.os.Looper; import android.os.Message; /** * The SoundPool class manages and plays audio resources for applications. * Loading Loading @@ -103,9 +107,20 @@ public class SoundPool static { System.loadLibrary("soundpool"); } private final static String TAG = "SoundPool"; private final static boolean DEBUG = false; private int mNativeContext; // accessed by native methods private EventHandler mEventHandler; private OnLoadCompleteListener mOnLoadCompleteListener; private final Object mLock; // SoundPool messages // // must match SoundPool.h private static final int SAMPLE_LOADED = 1; /** * Constructor. Constructs a SoundPool object with the following * characteristics: Loading @@ -120,7 +135,23 @@ public class SoundPool * @return a SoundPool object, or null if creation failed */ public SoundPool(int maxStreams, int streamType, int srcQuality) { native_setup(new WeakReference<SoundPool>(this), maxStreams, streamType, srcQuality); // do native setup if (native_setup(new WeakReference(this), maxStreams, streamType, srcQuality) != 0) { throw new RuntimeException("Native setup failed"); } mLock = new Object(); // setup message handler Looper looper; if ((looper = Looper.myLooper()) != null) { mEventHandler = new EventHandler(this, looper); } else if ((looper = Looper.getMainLooper()) != null) { mEventHandler = new EventHandler(this, looper); } else { mEventHandler = null; } } /** Loading @@ -145,12 +176,11 @@ public class SoundPool ParcelFileDescriptor fd = ParcelFileDescriptor.open(f, ParcelFileDescriptor.MODE_READ_ONLY); if (fd != null) { id = _load(fd.getFileDescriptor(), 0, f.length(), priority); //Log.v(TAG, "close fd"); fd.close(); } } } catch (java.io.IOException e) { Log.d(TAG, "error loading " + path); Log.e(TAG, "error loading " + path); } return id; } Loading @@ -176,7 +206,6 @@ public class SoundPool if (afd != null) { id = _load(afd.getFileDescriptor(), afd.getStartOffset(), afd.getLength(), priority); try { //Log.v(TAG, "close fd"); afd.close(); } catch (java.io.IOException ex) { //Log.d(TAG, "close failed:", ex); Loading Loading @@ -358,6 +387,76 @@ public class SoundPool */ public native final void setRate(int streamID, float rate); /** * Interface definition for a callback to be invoked when all the * sounds are loaded. * * @hide */ public interface OnLoadCompleteListener { /** * Called when a sound has completed loading. * * @param soundPool SoundPool object from the load() method * @param soundPool the sample ID of the sound loaded. * @param status the status of the load operation (0 = success) */ public void onLoadComplete(SoundPool soundPool, int sampleId, int status); } /** * Sets the callback hook for the OnLoadCompleteListener. * * @hide */ public void setOnLoadCompleteListener(OnLoadCompleteListener listener) { synchronized(mLock) { mOnLoadCompleteListener = listener; } } private class EventHandler extends Handler { private SoundPool mSoundPool; public EventHandler(SoundPool soundPool, Looper looper) { super(looper); mSoundPool = soundPool; } @Override public void handleMessage(Message msg) { switch(msg.what) { case SAMPLE_LOADED: if (DEBUG) Log.d(TAG, "Sample " + msg.arg1 + " loaded"); synchronized(mLock) { if (mOnLoadCompleteListener != null) { mOnLoadCompleteListener.onLoadComplete(mSoundPool, msg.arg1, msg.arg2); } } break; default: Log.e(TAG, "Unknown message type " + msg.what); return; } } } // post event from native code to message handler private static void postEventFromNative(Object weakRef, int msg, int arg1, int arg2, Object obj) { SoundPool soundPool = (SoundPool)((WeakReference)weakRef).get(); if (soundPool == null) return; if (soundPool.mEventHandler != null) { Message m = soundPool.mEventHandler.obtainMessage(msg, arg1, arg2, obj); soundPool.mEventHandler.sendMessage(m); } } /** * Release the SoundPool resources. * Loading @@ -367,8 +466,7 @@ public class SoundPool */ public native final void release(); private native final void native_setup(Object mediaplayer_this, int maxStreams, int streamType, int srcQuality); private native final int native_setup(Object weakRef, int maxStreams, int streamType, int srcQuality); protected void finalize() { release(); } }
media/jni/soundpool/SoundPool.cpp +24 −5 Original line number Diff line number Diff line Loading @@ -61,6 +61,9 @@ SoundPool::SoundPool(int maxChannels, int streamType, int srcQuality) mNextSampleID = 0; mNextChannelID = 0; mCallback = 0; mUserData = 0; mChannelPool = new SoundChannel[mMaxChannels]; for (int i = 0; i < mMaxChannels; ++i) { mChannelPool[i].init(this); Loading Loading @@ -141,7 +144,7 @@ void SoundPool::quit() bool SoundPool::startThreads() { createThread(beginThread, this); createThreadEtc(beginThread, this, "SoundPoolThread"); if (mDecodeThread == NULL) mDecodeThread = new SoundPoolThread(this); return mDecodeThread != NULL; Loading Loading @@ -372,6 +375,21 @@ void SoundPool::done(SoundChannel* channel) } } void SoundPool::setCallback(SoundPoolCallback* callback, void* user) { Mutex::Autolock lock(&mCallbackLock); mCallback = callback; mUserData = user; } void SoundPool::notify(SoundPoolEvent event) { Mutex::Autolock lock(&mCallbackLock); if (mCallback != NULL) { mCallback(event, this, mUserData); } } void SoundPool::dump() { for (int i = 0; i < mMaxChannels; ++i) { Loading Loading @@ -422,7 +440,7 @@ Sample::~Sample() delete mUrl; } void Sample::doLoad() status_t Sample::doLoad() { uint32_t sampleRate; int numChannels; Loading @@ -439,19 +457,19 @@ void Sample::doLoad() } if (p == 0) { LOGE("Unable to load sample: %s", mUrl); return; return -1; } LOGV("pointer = %p, size = %u, sampleRate = %u, numChannels = %d", p->pointer(), p->size(), sampleRate, numChannels); if (sampleRate > kMaxSampleRate) { LOGE("Sample rate (%u) out of range", sampleRate); return; return - 1; } if ((numChannels < 1) || (numChannels > 2)) { LOGE("Sample channel count (%d) out of range", numChannels); return; return - 1; } //_dumpBuffer(p->pointer(), p->size()); Loading @@ -464,6 +482,7 @@ void Sample::doLoad() mNumChannels = numChannels; mFormat = format; mState = READY; return 0; } Loading
media/jni/soundpool/SoundPool.h +14 −5 Original line number Diff line number Diff line Loading @@ -24,8 +24,6 @@ #include <media/AudioTrack.h> #include <cutils/atomic.h> #include <nativehelper/jni.h> namespace android { static const int IDLE_PRIORITY = -1; Loading @@ -43,10 +41,11 @@ public: int mMsg; int mArg1; int mArg2; enum MessageType { INVALID, SAMPLE_LOADED }; }; // JNI for calling back Java SoundPool object extern void android_soundpool_SoundPool_notify(jobject ref, const SoundPoolEvent *event); // callback function prototype typedef void SoundPoolCallback(SoundPoolEvent event, SoundPool* soundPool, void* user); // tracks samples used by application class Sample : public RefBase { Loading @@ -62,7 +61,7 @@ public: size_t size() { return mSize; } int state() { return mState; } uint8_t* data() { return static_cast<uint8_t*>(mData->pointer()); } void doLoad(); status_t doLoad(); void startLoad() { mState = LOADING; } sp<IMemory> getIMemory() { return mData; } Loading Loading @@ -182,6 +181,10 @@ public: // called from AudioTrack thread void done(SoundChannel* channel); // callback function void setCallback(SoundPoolCallback* callback, void* user); void* getUserData() { return mUserData; } private: SoundPool() {} // no default constructor bool startThreads(); Loading @@ -191,6 +194,7 @@ private: SoundChannel* findNextChannel (int channelID); SoundChannel* allocateChannel(int priority); void moveToFront(SoundChannel* channel); void notify(SoundPoolEvent event); void dump(); // restart thread Loading @@ -214,6 +218,11 @@ private: int mNextSampleID; int mNextChannelID; bool mQuit; // callback Mutex mCallbackLock; SoundPoolCallback* mCallback; void* mUserData; }; } // end namespace android Loading
media/jni/soundpool/SoundPoolThread.cpp +30 −24 Original line number Diff line number Diff line Loading @@ -22,50 +22,54 @@ namespace android { void SoundPoolThread::MessageQueue::write(SoundPoolMsg msg) { LOGV("MessageQueue::write - acquiring lock\n"); void SoundPoolThread::write(SoundPoolMsg msg) { Mutex::Autolock lock(&mLock); while (mQueue.size() >= maxMessages) { LOGV("MessageQueue::write - wait\n"); while (mMsgQueue.size() >= maxMessages) { mCondition.wait(mLock); } LOGV("MessageQueue::write - push message\n"); mQueue.push(msg); // if thread is quitting, don't add to queue if (mRunning) { mMsgQueue.push(msg); mCondition.signal(); } } const SoundPoolMsg SoundPoolThread::MessageQueue::read() { LOGV("MessageQueue::read - acquiring lock\n"); const SoundPoolMsg SoundPoolThread::read() { Mutex::Autolock lock(&mLock); while (mQueue.size() == 0) { LOGV("MessageQueue::read - wait\n"); while (mMsgQueue.size() == 0) { mCondition.wait(mLock); } SoundPoolMsg msg = mQueue[0]; LOGV("MessageQueue::read - retrieve message\n"); mQueue.removeAt(0); SoundPoolMsg msg = mMsgQueue[0]; mMsgQueue.removeAt(0); mCondition.signal(); return msg; } void SoundPoolThread::MessageQueue::quit() { void SoundPoolThread::quit() { Mutex::Autolock lock(&mLock); mQueue.clear(); mQueue.push(SoundPoolMsg(SoundPoolMsg::KILL, 0)); if (mRunning) { mRunning = false; mMsgQueue.clear(); mMsgQueue.push(SoundPoolMsg(SoundPoolMsg::KILL, 0)); mCondition.signal(); mCondition.wait(mLock); } LOGV("return from quit"); } SoundPoolThread::SoundPoolThread(SoundPool* soundPool) : mSoundPool(soundPool) { mMessages.setCapacity(maxMessages); createThread(beginThread, this); mMsgQueue.setCapacity(maxMessages); if (createThread(beginThread, this)) { mRunning = true; } } SoundPoolThread::~SoundPoolThread() { quit(); } int SoundPoolThread::beginThread(void* arg) { Loading @@ -77,7 +81,7 @@ int SoundPoolThread::beginThread(void* arg) { int SoundPoolThread::run() { LOGV("run"); for (;;) { SoundPoolMsg msg = mMessages.read(); SoundPoolMsg msg = read(); LOGV("Got message m=%d, mData=%d", msg.mMessageType, msg.mData); switch (msg.mMessageType) { case SoundPoolMsg::KILL: Loading @@ -95,14 +99,16 @@ int SoundPoolThread::run() { } void SoundPoolThread::loadSample(int sampleID) { mMessages.write(SoundPoolMsg(SoundPoolMsg::LOAD_SAMPLE, sampleID)); write(SoundPoolMsg(SoundPoolMsg::LOAD_SAMPLE, sampleID)); } void SoundPoolThread::doLoadSample(int sampleID) { sp <Sample> sample = mSoundPool->findSample(sampleID); status_t status = -1; if (sample != 0) { sample->doLoad(); status = sample->doLoad(); } mSoundPool->notify(SoundPoolEvent(SoundPoolEvent::SAMPLE_LOADED, sampleID, status)); } } // end namespace android
media/jni/soundpool/SoundPoolThread.h +9 −16 Original line number Diff line number Diff line Loading @@ -27,7 +27,7 @@ namespace android { class SoundPoolMsg { public: enum MessageType { INVALID, KILL, LOAD_SAMPLE, PLAY_SAMPLE, SAMPLE_DONE }; enum MessageType { INVALID, KILL, LOAD_SAMPLE }; SoundPoolMsg() : mMessageType(INVALID), mData(0) {} SoundPoolMsg(MessageType MessageType, int data) : mMessageType(MessageType), mData(data) {} Loading @@ -45,29 +45,22 @@ public: SoundPoolThread(SoundPool* SoundPool); ~SoundPoolThread(); void loadSample(int sampleID); void quit() { mMessages.quit(); } void quit(); void write(SoundPoolMsg msg); private: static const size_t maxMessages = 5; class MessageQueue { public: void write(SoundPoolMsg msg); const SoundPoolMsg read(); void setCapacity(size_t size) { mQueue.setCapacity(size); } void quit(); private: Vector<SoundPoolMsg> mQueue; Mutex mLock; Condition mCondition; }; static int beginThread(void* arg); int run(); void doLoadSample(int sampleID); const SoundPoolMsg read(); Mutex mLock; Condition mCondition; Vector<SoundPoolMsg> mMsgQueue; SoundPool* mSoundPool; MessageQueue mMessages; bool mRunning; }; } // end namespace android Loading