加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

cocos2dx 音频模块分析(1)

发布时间:2020-12-14 20:45:05 所属栏目:百科 来源:网络整理
导读:cocos2dx音效的实现分析: 上面那个图是cocos2dx音效部分的实现结构图,总体的思想是: 使用同一个SimpleAudioEngine.h头文件,然后在不同平台下对应不同 的实现文件,不同平台编译不同的实现文件,这就要求这个类的函数定义 成员在各个平台下统一。其实这也


cocos2dx音效的实现分析:


上面那个图是cocos2dx音效部分的实现结构图,总体的思想是:
使用同一个SimpleAudioEngine.h头文件,然后在不同平台下对应不同
的实现文件,不同平台编译不同的实现文件,这就要求这个类的函数定义
成员在各个平台下统一。其实这也可以理解为一种跨平台的实现方式。


这里分析android部分:

1、预加载背景音乐
void SimpleAudioEngine::preloadBackgroundMusic(const char* pszFilePath)
{
    std::string fullPath = getFullPathWithoutAssetsPrefix(pszFilePath);
    preloadBackgroundMusicJNI(fullPath.c_str());
}

-->>
//得到音乐文件的路径,如果是包里的文件,则去掉assets/前缀
static std::string getFullPathWithoutAssetsPrefix(const char* pszFilename)
{
    // Changing file path to full path
    //获取文件的路径,以后有时间会分析下CCFileUtils这个类的实现
    std::string fullPath = CCFileUtils::sharedFileUtils()->fullPathForFilename(pszFilename);
    // Removing `assets` since it isn't needed for the API of playing sound.
    size_t pos = fullPath.find("assets/");
    if (pos == 0)
    {
        fullPath = fullPath.substr(strlen("assets/"));
    }
    return fullPath;
}

-->>
preloadBackgroundMusicJNI:
//这里其实就是调用jni的方法:
void preloadBackgroundMusicJNI(const char *path)
    {
        // void playBackgroundMusic(String,boolean)
        JniMethodInfo methodInfo;
        
        if (! getStaticMethodInfo(methodInfo,"preloadBackgroundMusic","(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);
    }
-->>java端的代码:
public static void preloadBackgroundMusic(final String pPath) {
		Cocos2dxHelper.sCocos2dMusic.preloadBackgroundMusic(pPath);
	}
-->>
public void preloadBackgroundMusic(final String pPath) {
		if ((this.mCurrentPath == null) || (!this.mCurrentPath.equals(pPath))) {
			// preload new background music

			// release old resource and create a new one
			if (this.mBackgroundMediaPlayer != null) {
				this.mBackgroundMediaPlayer.release();
			}

			this.mBackgroundMediaPlayer = this.createMediaplayer(pPath);

			// record the path
			this.mCurrentPath = pPath;
		}
	}
-->>
	private MediaPlayer createMediaplayer(final String pPath) {
	//其实就是创建了一个android下的MediaPlayer媒体播放实例,后面的播放,暂停之类
	//的,都是这个实例去控制。
		MediaPlayer mediaPlayer = new MediaPlayer(); 

		try {
			if (pPath.startsWith("/")) {
				final FileInputStream fis = new FileInputStream(pPath);
				mediaPlayer.setDataSource(fis.getFD());
				fis.close();
			} else {
				final AssetFileDescriptor assetFileDescritor = this.mContext.getAssets().openFd(pPath);
				mediaPlayer.setDataSource(assetFileDescritor.getFileDescriptor(),assetFileDescritor.getStartOffset(),assetFileDescritor.getLength());
			}

			mediaPlayer.prepare();

			mediaPlayer.setVolume(this.mLeftVolume,this.mRightVolume);
		} catch (final Exception e) {
			mediaPlayer = null;
			Log.e(Cocos2dxMusic.TAG,"error: " + e.getMessage(),e);
		}

		return mediaPlayer;
	}

-->>播放背景音乐,这里可以不用预先加载,就直接播放。
void SimpleAudioEngine::playBackgroundMusic(const char* pszFilePath,bool bLoop)
{
    std::string fullPath = getFullPathWithoutAssetsPrefix(pszFilePath);
    playBackgroundMusicJNI(fullPath.c_str(),bLoop);
}

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读