cocos2dx 音频模块分析(1)



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);
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值