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

来源:互联网 发布:初级程序员培训班 编辑:程序博客网 时间:2024/06/08 20:14

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的mapInteger 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 existif (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得到音效IDInteger 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如果成功会返回一个streamIDint 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 effectreturn Cocos2dxSound.INVALID_SOUND_ID;}// only allow one playEffect at a time, or the semaphore will not work correctlysynchronized(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 mEffecToPlayWhenLoadedArrayfor ( 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 domEffecToPlayWhenLoadedArray.remove(info);break;}}} else {mStreamIdSyn = Cocos2dxSound.INVALID_SOUND_ID;}mSemaphore.release();}}*/mEffecToPlayWhenLoadedArray.add(new SoundInfoForLoadedCompleted(pPath, soundID.intValue(), pLoop));try {// wait OnloadedCompleteListener to set streamIDthis.mSemaphore.acquire();streamID = this.mStreamIdSyn;} catch(Exception e) {return Cocos2dxSound.INVALID_SOUND_ID;}}}return streamID;}


0 0
原创粉丝点击