Fixed SimpleAudioEngine::playEffect() lagged on Android 5.0.x

This commit is contained in:
WenhaiLin 2015-05-29 14:52:25 +08:00
parent 0838aa28aa
commit 9c31aafba0
3 changed files with 511 additions and 321 deletions

View File

@ -1,23 +1,6 @@
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := cocosdenshion_static
LOCAL_MODULE_FILENAME := libcocosdenshion
LOCAL_SRC_FILES := cddSimpleAudioEngine.cpp \
ccdandroidUtils.cpp \
jni/cddandroidAndroidJavaEngine.cpp
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/../include
LOCAL_C_INCLUDES := $(LOCAL_PATH)/../include \
$(LOCAL_PATH)/../.. \
$(LOCAL_PATH)/../../platform/android
include $(BUILD_STATIC_LIBRARY)
#new audio engine
#New AudioEngine
include $(CLEAR_VARS)
LOCAL_MODULE := audioengine_static
@ -36,3 +19,23 @@ LOCAL_C_INCLUDES := $(LOCAL_PATH)/../include \
$(LOCAL_PATH)/../../platform/android
include $(BUILD_STATIC_LIBRARY)
#SimpleAudioEngine
include $(CLEAR_VARS)
LOCAL_MODULE := cocosdenshion_static
LOCAL_MODULE_FILENAME := libcocosdenshion
LOCAL_SRC_FILES := cddSimpleAudioEngine.cpp \
ccdandroidUtils.cpp \
jni/cddandroidAndroidJavaEngine.cpp
LOCAL_STATIC_LIBRARIES := audioengine_static
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/../include
LOCAL_C_INCLUDES := $(LOCAL_PATH)/../include \
$(LOCAL_PATH)/../.. \
$(LOCAL_PATH)/../../platform/android
include $(BUILD_STATIC_LIBRARY)

View File

@ -1,6 +1,6 @@
/****************************************************************************
Copyright (c) 2010-2012 cocos2d-x.org
Copyright (c) 2013-2014 Chukong Technologies Inc.
Copyright (c) 2013-2015 Chukong Technologies Inc.
http://www.cocos2d-x.org
@ -24,10 +24,13 @@ THE SOFTWARE.
****************************************************************************/
#include "cddandroidAndroidJavaEngine.h"
#include "platform/android/jni/JniHelper.h"
#include "ccdandroidUtils.h"
#include <stdlib.h>
#include <android/log.h>
#include <jni.h>
#include <sys/system_properties.h>
#include "platform/android/jni/JniHelper.h"
#include "ccdandroidUtils.h"
#include "audio/include/AudioEngine.h"
// logging
#define LOG_TAG "cocosdenshion::android::AndroidJavaEngine"
@ -36,10 +39,10 @@ THE SOFTWARE.
// Java class
#define CLASS_NAME "org/cocos2dx/lib/Cocos2dxHelper"
namespace CocosDenshion {
namespace android {
using namespace cocos2d::experimental;
using namespace CocosDenshion::android;
bool AndroidJavaEngine::getJNIStaticMethodInfo(cocos2d::JniMethodInfo &methodinfo,
static inline bool getJNIStaticMethodInfo(cocos2d::JniMethodInfo &methodinfo,
const char *methodName,
const char *paramCode) {
return cocos2d::JniHelper::getStaticMethodInfo(methodinfo,
@ -48,6 +51,27 @@ namespace CocosDenshion {
paramCode);
}
AndroidJavaEngine::AndroidJavaEngine()
: _implementBaseOnAudioEngine(false)
, _effectVolume(1.f)
{
char sdk_ver_str[PROP_VALUE_MAX] = "0";
auto len = __system_property_get("ro.build.version.sdk", sdk_ver_str);
if (len > 0)
{
auto sdk_ver = atoi(sdk_ver_str);
__android_log_print(ANDROID_LOG_DEBUG, "cocos2d", "android build version:%d", sdk_ver);
if (sdk_ver == 21)
{
_implementBaseOnAudioEngine = true;
}
}
else
{
__android_log_print(ANDROID_LOG_DEBUG, "cocos2d", "%s", "Fail to get android build version.");
}
}
AndroidJavaEngine::~AndroidJavaEngine() {
cocos2d::JniMethodInfo methodInfo;
@ -59,8 +83,8 @@ namespace CocosDenshion {
methodInfo.env->DeleteLocalRef(methodInfo.classID);
}
void AndroidJavaEngine::preloadBackgroundMusic(const char* pszFilePath) {
std::string fullPath = CocosDenshion::android::getFullPathWithoutAssetsPrefix(pszFilePath);
void AndroidJavaEngine::preloadBackgroundMusic(const char* filePath) {
std::string fullPath = CocosDenshion::android::getFullPathWithoutAssetsPrefix(filePath);
// void playBackgroundMusic(String,boolean)
cocos2d::JniMethodInfo methodInfo;
@ -75,8 +99,8 @@ namespace CocosDenshion {
methodInfo.env->DeleteLocalRef(methodInfo.classID);
}
void AndroidJavaEngine::playBackgroundMusic(const char* pszFilePath, bool bLoop) {
std::string fullPath = CocosDenshion::android::getFullPathWithoutAssetsPrefix(pszFilePath);
void AndroidJavaEngine::playBackgroundMusic(const char* filePath, bool loop) {
std::string fullPath = CocosDenshion::android::getFullPathWithoutAssetsPrefix(filePath);
cocos2d::JniMethodInfo methodInfo;
@ -85,12 +109,12 @@ namespace CocosDenshion {
}
jstring stringArg = methodInfo.env->NewStringUTF(fullPath.c_str());
methodInfo.env->CallStaticVoidMethod(methodInfo.classID, methodInfo.methodID, stringArg, bLoop);
methodInfo.env->CallStaticVoidMethod(methodInfo.classID, methodInfo.methodID, stringArg, loop);
methodInfo.env->DeleteLocalRef(stringArg);
methodInfo.env->DeleteLocalRef(methodInfo.classID);
}
void AndroidJavaEngine::stopBackgroundMusic(bool bReleaseData) {
void AndroidJavaEngine::stopBackgroundMusic(bool releaseData) {
cocos2d::JniMethodInfo methodInfo;
if (!getJNIStaticMethodInfo(methodInfo, "stopBackgroundMusic", "()V")) {
@ -134,7 +158,6 @@ namespace CocosDenshion {
methodInfo.env->DeleteLocalRef(methodInfo.classID);
}
bool AndroidJavaEngine::willPlayBackgroundMusic() {
return true;
}
@ -178,7 +201,8 @@ namespace CocosDenshion {
methodInfo.env->DeleteLocalRef(methodInfo.classID);
}
float AndroidJavaEngine::getEffectsVolume() {
static float _jni_getEffectsVolume() {
cocos2d::JniMethodInfo methodInfo;
jfloat ret = -1.0;
@ -192,7 +216,7 @@ namespace CocosDenshion {
return ret;
}
void AndroidJavaEngine::setEffectsVolume(float volume) {
static void _jni_setEffectsVolume(float volume) {
cocos2d::JniMethodInfo methodInfo;
if (!getJNIStaticMethodInfo(methodInfo, "setEffectsVolume", "(F)V")) {
@ -203,11 +227,11 @@ namespace CocosDenshion {
methodInfo.env->DeleteLocalRef(methodInfo.classID);
}
unsigned int AndroidJavaEngine::playEffect(const char* pszFilePath, bool bLoop,
float pitch, float pan, float gain) {
static unsigned int _jni_playEffect(const char* filePath, bool loop, float pitch, float pan, float gain)
{
cocos2d::JniMethodInfo methodInfo;
int ret = 0;
std::string fullPath = CocosDenshion::android::getFullPathWithoutAssetsPrefix(pszFilePath);
std::string fullPath = CocosDenshion::android::getFullPathWithoutAssetsPrefix(filePath);
if (!getJNIStaticMethodInfo(methodInfo, "playEffect", "(Ljava/lang/String;ZFFF)I")) {
return ret;
@ -217,7 +241,7 @@ namespace CocosDenshion {
ret = methodInfo.env->CallStaticIntMethod(methodInfo.classID,
methodInfo.methodID,
stringArg,
bLoop,
loop,
pitch, pan, gain);
methodInfo.env->DeleteLocalRef(stringArg);
methodInfo.env->DeleteLocalRef(methodInfo.classID);
@ -225,18 +249,18 @@ namespace CocosDenshion {
return (unsigned int)ret;
}
void AndroidJavaEngine::pauseEffect(unsigned int nSoundId) {
static void _jni_pauseEffect(unsigned int soundId) {
cocos2d::JniMethodInfo methodInfo;
if (!getJNIStaticMethodInfo(methodInfo, "pauseEffect", "(I)V")) {
return;
}
methodInfo.env->CallStaticVoidMethod(methodInfo.classID, methodInfo.methodID, (int)nSoundId);
methodInfo.env->CallStaticVoidMethod(methodInfo.classID, methodInfo.methodID, (int)soundId);
methodInfo.env->DeleteLocalRef(methodInfo.classID);
}
void AndroidJavaEngine::pauseAllEffects() {
static void _jni_pauseAllEffects() {
cocos2d::JniMethodInfo methodInfo;
if (!getJNIStaticMethodInfo(methodInfo, "pauseAllEffects", "()V")) {
@ -247,18 +271,18 @@ namespace CocosDenshion {
methodInfo.env->DeleteLocalRef(methodInfo.classID);
}
void AndroidJavaEngine::resumeEffect(unsigned int nSoundId) {
static void _jni_resumeEffect(unsigned int soundId) {
cocos2d::JniMethodInfo methodInfo;
if (!getJNIStaticMethodInfo(methodInfo, "resumeEffect", "(I)V")) {
return;
}
methodInfo.env->CallStaticVoidMethod(methodInfo.classID, methodInfo.methodID, (int)nSoundId);
methodInfo.env->CallStaticVoidMethod(methodInfo.classID, methodInfo.methodID, (int)soundId);
methodInfo.env->DeleteLocalRef(methodInfo.classID);
}
void AndroidJavaEngine::resumeAllEffects() {
static void _jni_resumeAllEffects() {
cocos2d::JniMethodInfo methodInfo;
if (!getJNIStaticMethodInfo(methodInfo, "resumeAllEffects", "()V")) {
@ -269,18 +293,18 @@ namespace CocosDenshion {
methodInfo.env->DeleteLocalRef(methodInfo.classID);
}
void AndroidJavaEngine::stopEffect(unsigned int nSoundId) {
static void _jni_stopEffect(unsigned int soundId) {
cocos2d::JniMethodInfo methodInfo;
if (!getJNIStaticMethodInfo(methodInfo, "stopEffect", "(I)V")) {
return;
}
methodInfo.env->CallStaticVoidMethod(methodInfo.classID, methodInfo.methodID, (int)nSoundId);
methodInfo.env->CallStaticVoidMethod(methodInfo.classID, methodInfo.methodID, (int)soundId);
methodInfo.env->DeleteLocalRef(methodInfo.classID);
}
void AndroidJavaEngine::stopAllEffects() {
static void _jni_stopAllEffects() {
cocos2d::JniMethodInfo methodInfo;
if (!getJNIStaticMethodInfo(methodInfo, "stopAllEffects", "()V")) {
@ -291,9 +315,9 @@ namespace CocosDenshion {
methodInfo.env->DeleteLocalRef(methodInfo.classID);
}
static void loadEffect(const char* pszFilePath, char* loadEffectName) {
static void loadEffect(const char* filePath, char* loadEffectName) {
cocos2d::JniMethodInfo methodInfo;
std::string fullPath = CocosDenshion::android::getFullPathWithoutAssetsPrefix(pszFilePath);
std::string fullPath = CocosDenshion::android::getFullPathWithoutAssetsPrefix(filePath);
if (!cocos2d::JniHelper::getStaticMethodInfo(methodInfo, CLASS_NAME, loadEffectName, "(Ljava/lang/String;)V")) {
return;
@ -305,13 +329,173 @@ namespace CocosDenshion {
methodInfo.env->DeleteLocalRef(methodInfo.classID);
}
void AndroidJavaEngine::preloadEffect(const char* pszFilePath) {
loadEffect(pszFilePath, "preloadEffect");
static void _jni_preloadEffect(const char* filePath) {
loadEffect(filePath, "preloadEffect");
}
void AndroidJavaEngine::unloadEffect(const char* pszFilePath) {
loadEffect(pszFilePath, "unloadEffect");
static void _jni_unloadEffect(const char* filePath) {
loadEffect(filePath, "unloadEffect");
}
float AndroidJavaEngine::getEffectsVolume()
{
if (_implementBaseOnAudioEngine)
{
return _effectVolume;
}
else
{
return _jni_getEffectsVolume();
}
}
void AndroidJavaEngine::setEffectsVolume(float volume)
{
if (_implementBaseOnAudioEngine)
{
if (volume > 1.f)
{
volume = 1.f;
}
else if (volume < 0.f)
{
volume = 0.f;
}
if (_effectVolume != volume)
{
_effectVolume = volume;
for (auto& it : _soundIDs)
{
AudioEngine::setVolume(it.first, volume);
}
}
}
else
{
_jni_setEffectsVolume(volume);
}
}
unsigned int AndroidJavaEngine::playEffect(const char* filePath, bool loop,
float pitch, float pan, float gain)
{
if (_implementBaseOnAudioEngine)
{
auto soundID = AudioEngine::play2d(filePath, loop, _effectVolume);
if (soundID != AudioEngine::INVALID_AUDIO_ID)
{
_soundIDs[soundID] = soundID;
AudioEngine::setFinishCallback(soundID, [this](int id, const std::string& filePath){
_soundIDs.erase(id);
});
}
return soundID;
}
else
{
return _jni_playEffect(filePath, loop, pitch, pan, gain);
}
}
void AndroidJavaEngine::pauseEffect(unsigned int soundID)
{
if (_implementBaseOnAudioEngine)
{
AudioEngine::pause(soundID);
}
else
{
_jni_pauseEffect(soundID);
}
}
void AndroidJavaEngine::resumeEffect(unsigned int soundID)
{
if (_implementBaseOnAudioEngine)
{
AudioEngine::resume(soundID);
}
else
{
_jni_resumeEffect(soundID);
}
}
void AndroidJavaEngine::stopEffect(unsigned int soundID)
{
if (_implementBaseOnAudioEngine)
{
AudioEngine::stop(soundID);
_soundIDs.erase(soundID);
}
else
{
_jni_stopEffect(soundID);
}
}
void AndroidJavaEngine::pauseAllEffects()
{
if (_implementBaseOnAudioEngine)
{
for (auto& it : _soundIDs)
{
AudioEngine::pause(it.first);
}
}
else
{
_jni_pauseAllEffects();
}
}
void AndroidJavaEngine::resumeAllEffects()
{
if (_implementBaseOnAudioEngine)
{
for (auto& it : _soundIDs)
{
AudioEngine::resume(it.first);
}
}
else
{
_jni_resumeAllEffects();
}
}
void AndroidJavaEngine::stopAllEffects()
{
if (_implementBaseOnAudioEngine)
{
for (auto& it : _soundIDs)
{
AudioEngine::stop(it.first);
}
_soundIDs.clear();
}
else
{
_jni_stopAllEffects();
}
}
void AndroidJavaEngine::preloadEffect(const char* filePath)
{
if (!_implementBaseOnAudioEngine)
{
_jni_preloadEffect(filePath);
}
}
void AndroidJavaEngine::unloadEffect(const char* filePath)
{
if (!_implementBaseOnAudioEngine)
{
_jni_unloadEffect(filePath);
}
}

View File

@ -1,6 +1,6 @@
/****************************************************************************
Copyright (c) 2010-2012 cocos2d-x.org
Copyright (c) 2013-2014 Chukong Technologies Inc.
Copyright (c) 2013-2015 Chukong Technologies Inc.
http://www.cocos2d-x.org
@ -27,39 +27,42 @@ THE SOFTWARE.
#include "SimpleAudioEngine.h"
#include "platform/android/jni/JniHelper.h"
#include <unordered_map>
namespace CocosDenshion {
namespace android {
class AndroidJavaEngine : public SimpleAudioEngine {
public:
AndroidJavaEngine();
~AndroidJavaEngine();
void preloadBackgroundMusic(const char* pszFilePath);
void playBackgroundMusic(const char* pszFilePath, bool bLoop);
void stopBackgroundMusic(bool bReleaseData);
void pauseBackgroundMusic();
void resumeBackgroundMusic();
void rewindBackgroundMusic();
bool willPlayBackgroundMusic();
bool isBackgroundMusicPlaying();
float getBackgroundMusicVolume();
void setBackgroundMusicVolume(float volume);
float getEffectsVolume();
void setEffectsVolume(float volume);
unsigned int playEffect(const char* pszFilePath, bool bLoop = false,
virtual void preloadBackgroundMusic(const char* filePath);
virtual void playBackgroundMusic(const char* filePath, bool loop);
virtual void stopBackgroundMusic(bool releaseData);
virtual void pauseBackgroundMusic();
virtual void resumeBackgroundMusic();
virtual void rewindBackgroundMusic();
virtual bool willPlayBackgroundMusic();
virtual bool isBackgroundMusicPlaying();
virtual float getBackgroundMusicVolume();
virtual void setBackgroundMusicVolume(float volume);
virtual float getEffectsVolume();
virtual void setEffectsVolume(float volume);
virtual unsigned int playEffect(const char* filePath, bool loop = false,
float pitch = 1.0f, float pan = 0.0f, float gain = 1.0f);
void pauseEffect(unsigned int nSoundId);
void pauseAllEffects();
void resumeEffect(unsigned int nSoundId);
void resumeAllEffects();
void stopEffect(unsigned int nSoundId);
void stopAllEffects();
void preloadEffect(const char* pszFilePath);
void unloadEffect(const char* pszFilePath);
virtual void pauseEffect(unsigned int soundId);
virtual void pauseAllEffects();
virtual void resumeEffect(unsigned int soundId);
virtual void resumeAllEffects();
virtual void stopEffect(unsigned int soundId);
virtual void stopAllEffects();
virtual void preloadEffect(const char* filePath);
virtual void unloadEffect(const char* filePath);
private :
static bool getJNIStaticMethodInfo(cocos2d::JniMethodInfo &methodinfo,
const char *methodName,
const char *paramCode);
bool _implementBaseOnAudioEngine;
float _effectVolume;
std::unordered_map<int, int> _soundIDs;
};
}
}