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