展会信息港展会大全

cocos2dx 音频模块分析(4): 音效部分,cocos2dx音效
来源:互联网   发布日期:2015-09-28 11:21:17   浏览:2587次  

导读: cocos2dx 音频模块分析(4): 音效部分,cocos2dx音效 cocos2dx 音频模块分析(4): 音效部分 我们上面几篇分析了cocos2dx音频模块的音乐部分,从这篇开始,...

cocos2dx 音频模块分析(4): 音效部分,cocos2dx音效

cocos2dx 音频模块分析(4): 音效部分

我们上面几篇分析了cocos2dx音频模块的音乐部分,从这篇开始,

我们分析下音效部分:

1、

//预加载音效文件:pszFilePath 音效文件名

void SimpleAudioEngine::preloadEffect(const char* pszFilePath)

{

//获取音效文件的全路径,如果是apk包里的路径,则不包含assets/

std::string fullPath = getFullPathWithoutAssetsPrefix(pszFilePath);

preloadEffectJNI(fullPath.c_str());

}

--->>>// 这里通过jni调用java端的方法

void preloadEffectJNI(const char *path)

{

// void preloadEffect(String)

JniMethodInfo methodInfo;

if (! getStaticMethodInfo(methodInfo, "preloadEffect", "(Ljava/lang/String;)V"))

{

return ;

}

jstring stringArg = methodInfo.env->NewStringUTF(path);

methodInfo.env->CallStaticVoidMethod(methodInfo.classID, methodInfo.methodID, stringArg);

methodInfo.env->DeleteLocalRef(stringArg);

methodInfo.env->DeleteLocalRef(methodInfo.classID);

}

----->>>//Cocos2dxHelper类中的方法:

public static void preloadEffect(final String path) {

//Cocos2dxSound类是专门处理音效的类

Cocos2dxHelper.sCocos2dSound.preloadEffect(path);

}

--->>>//Cocos2dxSound类的方法:

public int preloadEffect(final String pPath) {

//private final HashMap<String, Integer> mPathSoundIDMap = new HashMap<String, Integer>();

//这个是音效路径对应音效ID的map

Integer soundID = this.mPathSoundIDMap.get(pPath);

if (soundID == null) {

//

soundID = this.createSoundIDFromAsset(pPath);

// save value just in case if file is really loaded

// 如果createSoundIDFromAsset函数调用成功,则添加到mPathSoundIDMap中。

if (soundID != Cocos2dxSound.INVALID_SOUND_ID) {

this.mPathSoundIDMap.put(pPath, soundID);

}

}

return soundID;

}

----->>>>根据我们传入的音效文件路径,加载音效

public int createSoundIDFromAsset(final String pPath) {

int soundID = Cocos2dxSound.INVALID_SOUND_ID;

try {

//根据传入的路径不同,做不同处理,一个是绝对路径一个是包里的路径,加载音效文件

//The SoundPool class manages and plays audio resources for applications.

//private SoundPool mSoundPool;音效缓存池

if (pPath.startsWith("/")) {

soundID = this.mSoundPool.load(pPath, 0);

} else {

soundID = this.mSoundPool.load(this.mContext.getAssets().openFd(pPath), 0);

}

} catch (final Exception e) {

soundID = Cocos2dxSound.INVALID_SOUND_ID;

Log.e(Cocos2dxSound.TAG, "error: " + e.getMessage(), e);

}

// mSoundPool.load returns 0 if something goes wrong, for example a file does not exist

if (soundID == 0) {

soundID = Cocos2dxSound.INVALID_SOUND_ID;

}

return soundID;

}

2、

播放音效文件。

pszFilePath:音效文件名;bLoop 是否循环播放

unsigned int SimpleAudioEngine::playEffect(const char* pszFilePath, bool bLoop)

{

std::string fullPath = getFullPathWithoutAssetsPrefix(pszFilePath);

return playEffectJNI(fullPath.c_str(), bLoop);

}

----->>>playEffectJNI:

unsigned int playEffectJNI(const char* path, bool bLoop)

{

// int playEffect(String)

JniMethodInfo methodInfo;

int ret = 0;

if (! getStaticMethodInfo(methodInfo, "playEffect", "(Ljava/lang/String;Z)I"))

{

return ret;

}

jstring stringArg = methodInfo.env->NewStringUTF(path);

ret = methodInfo.env->CallStaticIntMethod(methodInfo.classID, methodInfo.methodID, stringArg, bLoop);

methodInfo.env->DeleteLocalRef(stringArg);

methodInfo.env->DeleteLocalRef(methodInfo.classID);

return (unsigned int)ret;

}

------>>>>playEffect:

public int playEffect(final String pPath, final boolean pLoop) {

//从mPathSoundIDMap中,根据音效path得到音效ID

Integer soundID = this.mPathSoundIDMap.get(pPath);

int streamID = Cocos2dxSound.INVALID_STREAM_ID;

if (soundID != null) {

// play sound

// 如果音效ID存在,则表明我们已经预先加载过这个音效文件,则调用mSoundPool.play直接播放

/*

private int doPlayEffect(final String pPath, final int soundId, final boolean pLoop) {

// play sound

// Play a sound from a sound ID.

// return non-zero streamID if successful, zero if failed如果成功会返回一个streamID

int streamID = this.mSoundPool.play(soundId, this.mLeftVolume, this.mRightVolume, Cocos2dxSound.SOUND_PRIORITY, pLoop ? -1 : 0, Cocos2dxSound.SOUND_RATE);

// record stream id

// 记录上面调用mSoundPool.play返回的streamID,至于为什么需要这样,看下面源码的说明:

// sound path and stream ids map

// a file may be played many times at the same time

// so there is an array map to a file path

// private final HashMap<String, ArrayList<Integer>> mPathStreamIDsMap = new HashMap<String, ArrayList<Integer>>();

ArrayList<Integer> streamIDs = this.mPathStreamIDsMap.get(pPath);

if (streamIDs == null) {

streamIDs = new ArrayList<Integer>();

this.mPathStreamIDsMap.put(pPath, streamIDs);

}

streamIDs.add(streamID);

return streamID;

}

*/

streamID = this.doPlayEffect(pPath, soundID.intValue(), pLoop);

} else {

// the effect is not prepared,如果音效没有预先加载,则需要先加载

soundID = this.preloadEffect(pPath); //加载音效文件

if (soundID == Cocos2dxSound.INVALID_SOUND_ID) {

// can not preload effect

return Cocos2dxSound.INVALID_SOUND_ID;

}

// only allow one playEffect at a time, or the semaphore will not work correctly

synchronized(this.mSoundPool) {

// add this effect into mEffecToPlayWhenLoadedArray, and it will be played when loaded completely

// 这个应该和mSoundPool加载音效文件有关,我也不是很明白

/*

不过在初始化时设置了一个:this.mSoundPool.setOnLoadCompleteListener(new OnLoadCompletedListener());

//加载完成回调函数,应该和这个有关,这里我们就不关心了。 只需要知道如果我们提前加载音效文件

//也可以直接调用play函数,在调用play函数时会调用加载函数,并放入加载队列中,加载完成后进行播放。

//这样做会有一些延时,所以我们还是最好先加载,然后在播放。这个延时只在第一次播放时有,以后就不会了,

//不过最好还是先加载。

*/

/*

@Override

//加载完成回调函数。

public void onLoadComplete(SoundPool soundPool, int sampleId, int status) {

if (status == 0)

{

// only play effect that are in mEffecToPlayWhenLoadedArray

for ( SoundInfoForLoadedCompleted info : mEffecToPlayWhenLoadedArray) {

if (sampleId == info.soundID) {

// set the stream id which will be returned by playEffect()

// 加载完成后调用doPlayEffect进行播放,并从mEffecToPlayWhenLoadedArray加载列表中

// 移除。

mStreamIdSyn = doPlayEffect(info.path, info.soundID, info.isLoop);

// remove it from array, because we will break here

// so it is safe to do

mEffecToPlayWhenLoadedArray.remove(info);

break;

}

}

} else {

mStreamIdSyn = Cocos2dxSound.INVALID_SOUND_ID;

}

mSemaphore.release();

}

}

*/

mEffecToPlayWhenLoadedArray.add(new SoundInfoForLoadedCompleted(pPath, soundID.intValue(), pLoop));

try {

// wait OnloadedCompleteListener to set streamID

this.mSemaphore.acquire();

streamID = this.mStreamIdSyn;

} catch(Exception e) {

return Cocos2dxSound.INVALID_SOUND_ID;

}

}

}

return streamID;

}

http://www.bkjia.com/Androidjc/1005763.htmlwww.bkjia.comtruehttp://www.bkjia.com/Androidjc/1005763.htmlTechArticlecocos2dx 音频模块分析(4): 音效部分,cocos2dx音效 cocos2dx 音频模块分析(4): 音效部分 我们上面几篇分析了cocos2dx音频模块的音乐部分,从这篇开...

赞助本站

人工智能实验室

相关热词: android开发 android教程

相关内容
AiLab云推荐
展开

热门栏目HotCates

Copyright © 2010-2024 AiLab Team. 人工智能实验室 版权所有    关于我们 | 联系我们 | 广告服务 | 公司动态 | 免责声明 | 隐私条款 | 工作机会 | 展会港