SoundPool的play方法用于播放音效文件,代码如下:
//frameworks/base/media/java/android/media/SoundPool.java
public class SoundPool extends PlayerBase {
public final int play(int soundID, float leftVolume, float rightVolume,
int priority, int loop, float rate) {
// FIXME: b/174876164 implement device id for soundpool
baseStart(0);
return _play(soundID, leftVolume, rightVolume, priority, loop, rate);
}
}
调用_play方法,_play是一个native方法,实现代码如下:
//frameworks/base/media/jni/soundpool/android_media_soundPool.cpp
static jint
android_media_SoundPool_play(JNIEnv *env, jobject thiz, jint sampleID,
jfloat leftVolume, jfloat rightVolume, jint priority, jint loop,
jfloat rate)
{
ALOGV("android_media_SoundPool_play\n");
auto soundPool = getSoundPool(env, thiz);
if (soundPool == nullptr) return 0;
return (jint) soundPool->play(sampleID, leftVolume, rightVolume, priority, loop, rate);
}
上面方法处理如下:
1、调用getSoundPool方法,获取SoundPool对象
2、调用SoundPool的play方法进行音效声音play
下面分别进行分析:
getSoundPool
调用getSoundPool方法,获取SoundPool对象:
//frameworks/base/media/jni/soundpool/android_media_soundPool.cpp
inline auto getSoundPool(JNIEnv *env, jobject thiz) {
return getSoundPoolManager().get(env, thiz);
}
调用getSoundPoolManager方法:
//frameworks/base/media/jni/soundpool/android_media_soundPool.cpp
auto& getSoundPoolManager() {
static ObjectManager<std::shared_ptr<SoundPool>> soundPoolManager(fields.mNativeContext);
return soundPoolManager;
}
SoundPool play
调用SoundPool的play方法进行音效声音play:
//frameworks/base/media/jni/SoundPool/SoundPool.cpp
int32_t SoundPool::play(int32_t soundID, float leftVolume, float rightVolume,
int32_t priority, int32_t loop, float rate)
{
ALOGV("%s(soundID=%d, leftVolume=%f, rightVolume=%f, priority=%d, loop=%d, rate=%f)",
__func__, soundID, leftVolume, rightVolume, priority, loop, rate);
// New for R: check arguments to ensure track can be created.
// If SoundPool defers the creation of the AudioTrack to the StreamManager thread,
// the failure to create may not be visible to the caller, so this precheck is needed.
if (checkVolume(&leftVolume, &rightVolume)
|| checkPriority(&priority)
|| checkLoop(&loop)
|| checkRate(&rate)) return 0;
auto apiLock = kUseApiLock ? std::make_unique<std::lock_guard<std::mutex>>(mApiLock) : nullptr;
const std::shared_ptr<soundpool::Sound> sound = mSoundManager.findSound(soundID); //通过soundID获取sound 对象
if (sound == nullptr || sound->getState() != soundpool::Sound::READY) { //判断sound状态
ALOGW("%s soundID %d not READY", __func__, soundID);
return 0;
}
const int32_t streamID = mStreamManager.queueForPlay(
sound, soundID, leftVolume, rightVolume, priority, loop, rate);
ALOGV("%s returned %d", __func__, streamID);
return streamID;
}
调用StreamManager的queueForPlay方法:
//frameworks/base/media/jni/SoundPool/StreamManager.cpp
int32_t StreamManager::queueForPlay(const std::shared_ptr<Sound> &sound,
int32_t soundID, float leftVolume, float r