博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
cocos2dx 音频模块分析(4): 音效部分
阅读量:4215 次
发布时间:2019-05-26

本文共 6330 字,大约阅读时间需要 21 分钟。

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
mPathSoundIDMap = new HashMap
(); //这个是音效路径对应音效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
> mPathStreamIDsMap = new HashMap
>(); ArrayList
streamIDs = this.mPathStreamIDsMap.get(pPath); if (streamIDs == null) { streamIDs = new ArrayList
(); 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://omsmi.baihongyu.com/

你可能感兴趣的文章
【React Native】Invariant Violation: Application AwesomeProject has not been registered
查看>>
【ReactNative】真机上无法调试 could not connect to development server
查看>>
【XCode 4.6】常用快捷键 特别是格式化代码ctrl+i
查看>>
【iOS游戏开发】icon那点事 之 图标设计(三)
查看>>
【IOS游戏开发】之测试发布(Distribution)
查看>>
【IOS游戏开发】之IPA破解原理
查看>>
【一天一道LeetCode】#45. Jump Game II
查看>>
【一天一道LeetCode】#56. Merge Intervals
查看>>
【一天一道LeetCode】#59. Spiral Matrix II
查看>>
【一天一道LeetCode】#60. Permutation Sequence.
查看>>
论文浅尝 | 通过共享表示和结构化预测进行事件和事件时序关系的联合抽取
查看>>
廖雪峰Python教程 学习笔记3 hello.py
查看>>
从内核看epoll的实现(基于5.9.9)
查看>>
python与正则表达式
查看>>
Linux文件和设备编程
查看>>
文件描述符
查看>>
终端驱动程序:几个简单例子
查看>>
HTML条件注释
查看>>
内核态与用户态
查看>>
趣链 BitXHub跨链平台 (4)跨链网关“初介绍”
查看>>