cocos2dx 音频模块分析(3): 背景音乐部分

cocos2dx 音频模块分析(3):背景音乐部分

我在(2)已经分析了背景音乐文件的预加载preloadBackgroundMusic和播放playBackgroundMusic两个函数,
这里接着分析,还是基于android平台:
1、
//暂停函数,用于音乐的暂停
void SimpleAudioEngine::pauseBackgroundMusic()
{
    //在SimpleAudioEngineJni.cpp源文件中定义
    pauseBackgroundMusicJNI();
}
//--pauseBackgroundMusicJNI--->>>
void pauseBackgroundMusicJNI()
    {
        // void pauseBackgroundMusic()

        JniMethodInfo methodInfo;

        if (! getStaticMethodInfo(methodInfo, "pauseBackgroundMusic", "()V"))
        {
            return;
        }
        //通过jni调用java端的函数,调用的是Cocos2dxHelper类中的
	/*
	public static void pauseBackgroundMusic() {
		Cocos2dxHelper.sCocos2dMusic.pauseBackgroundMusic();
	}
	*/
        methodInfo.env->CallStaticVoidMethod(methodInfo.classID, methodInfo.methodID);
        methodInfo.env->DeleteLocalRef(methodInfo.classID);
    }

    最终调用的是Cocos2dxMusic类中的
    public void pauseBackgroundMusic() {
                //mBackgroundMediaPlayer在(2)中有分析过,创建的MediaPlayer实例
		if (this.mBackgroundMediaPlayer != null && this.mBackgroundMediaPlayer.isPlaying()) {
			this.mBackgroundMediaPlayer.pause();
			this.mPaused = true;  //是否暂停标志
		}
	}

2、
恢复播放
void SimpleAudioEngine::resumeBackgroundMusic()
{
    resumeBackgroundMusicJNI();
}
其实和上面暂停的调用过程是一样的,就不分析了,直接进入java端看最终调用的函数,
public void resumeBackgroundMusic() {
                //这里只有处于暂停状态时即mPaused变量为true时,才会接着
		//上次播放的位置开始播放
		if (this.mBackgroundMediaPlayer != null && this.mPaused) {
			this.mBackgroundMediaPlayer.start();
			this.mPaused = false; //把暂停标志位设置false
		}
	}

3、
从头开始播放音乐文件
void rewindBackgroundMusicJNI()
    {
        // void rewindBackgroundMusic()

        JniMethodInfo methodInfo;

        if (! getStaticMethodInfo(methodInfo, "rewindBackgroundMusic", "()V"))
        {
            return;
        }

        methodInfo.env->CallStaticVoidMethod(methodInfo.classID, methodInfo.methodID);
        methodInfo.env->DeleteLocalRef(methodInfo.classID);
    }
    --->>//java端函数
    //这个函数最终也是会调用playBackgroundMusic函数,但是和playBackgroundMusic有一点不同,
    //playBackgroundMusic需要传入音乐文件名,可以播放和上一次一样的音乐也可以和是上一次不一样的
    //音乐,但是rewindBackgroundMusic函数只有在mBackgroundMediaPlayer不为null时才执行,
    //也就是必须播放过音乐,且播放的是上次播放的音乐,只不过这次是从头开始播放
    public void rewindBackgroundMusic() {
		if (this.mBackgroundMediaPlayer != null) {
			playBackgroundMusic(mCurrentPath, mIsLoop);
		}
	}

4、停止播放音乐文件
void stopBackgroundMusicJNI()
    {
        // void stopBackgroundMusic()

        JniMethodInfo methodInfo;

        if (! getStaticMethodInfo(methodInfo, "stopBackgroundMusic", "()V"))
        {
            return;
        }

        methodInfo.env->CallStaticVoidMethod(methodInfo.classID, methodInfo.methodID);
        methodInfo.env->DeleteLocalRef(methodInfo.classID);
    }

    --->>>//java端函数:
    public void stopBackgroundMusic() {
		if (this.mBackgroundMediaPlayer != null) {
			mBackgroundMediaPlayer.release();
			//不太明白这里为什么有从新创建了MediaPlayer实例
			//可能是一些特殊情况下会出现问题?
        	mBackgroundMediaPlayer = createMediaplayer(mCurrentPath);

			// should set the state, if not, the following sequence will be error
			// play -> pause -> stop -> resume
			//为什么设置mPaused标志,直接看上面的英文注释
			this.mPaused = false;
		}
	}
5、
返回是否处于播放状态
 bool isBackgroundMusicPlayingJNI()
    {
        // boolean rewindBackgroundMusic()

        JniMethodInfo methodInfo;
        jboolean ret = false;

        if (! getStaticMethodInfo(methodInfo, "isBackgroundMusicPlaying", "()Z"))
        {
            return ret;
        }

        ret = methodInfo.env->CallStaticBooleanMethod(methodInfo.classID, methodInfo.methodID);
        methodInfo.env->DeleteLocalRef(methodInfo.classID);

        return ret;
    }
    --->>>//java端函数,没什么东西
    	public boolean isBackgroundMusicPlaying() {
		boolean ret = false;

		if (this.mBackgroundMediaPlayer == null) {
			ret = false;
		} else {
			ret = this.mBackgroundMediaPlayer.isPlaying();
		}

		return ret;
	}
6、获取播放声音音量值
    float getBackgroundMusicVolumeJNI()
    {
        // float getBackgroundMusicVolume()

        JniMethodInfo methodInfo;
        jfloat ret = -1.0;

        if (! getStaticMethodInfo(methodInfo, "getBackgroundMusicVolume", "()F"))
        {
            return ret;
        }

        ret = methodInfo.env->CallStaticFloatMethod(methodInfo.classID, methodInfo.methodID);
        methodInfo.env->DeleteLocalRef(methodInfo.classID);

        return ret;
    }
------->>>//java
    	public float getBackgroundVolume() {
		if (this.mBackgroundMediaPlayer != null) {
			return (this.mLeftVolume + this.mRightVolume) / 2;
		} else {
			return 0.0f;
		}
	}

 7、设置声音音量值
    void setBackgroundMusicVolumeJNI(float volume)
    {
        // void setBackgroundMusicVolume()

        JniMethodInfo methodInfo;

        if (! getStaticMethodInfo(methodInfo, "setBackgroundMusicVolume", "(F)V"))
        {
            return ;
        }

        methodInfo.env->CallStaticVoidMethod(methodInfo.classID, methodInfo.methodID, volume);
        methodInfo.env->DeleteLocalRef(methodInfo.classID);
    }
   ---->>>java
   public void setBackgroundVolume(float pVolume) {
		if (pVolume < 0.0f) {
			pVolume = 0.0f;
		}

		if (pVolume > 1.0f) {
			pVolume = 1.0f;
		}

		this.mLeftVolume = this.mRightVolume = pVolume;
		if (this.mBackgroundMediaPlayer != null) {
			this.mBackgroundMediaPlayer.setVolume(this.mLeftVolume, this.mRightVolume);
		}
	}

8、
end函数,这个一般在退出游戏是调用,关掉所有的音乐和音效。
 void endJNI()
    {
        // void end()

        JniMethodInfo methodInfo;

        if (! getStaticMethodInfo(methodInfo, "end", "()V"))
        {
            return ;
        }

        methodInfo.env->CallStaticVoidMethod(methodInfo.classID, methodInfo.methodID);
        methodInfo.env->DeleteLocalRef(methodInfo.classID);
    }
    --->>>//java端函数
    public static void end() {
		Cocos2dxHelper.sCocos2dMusic.end(); //背景音乐文件的处理
		Cocos2dxHelper.sCocos2dSound.end();
	}

    ---->>>>/////背景音乐文件的处理
	public void end() {
		if (this.mBackgroundMediaPlayer != null) {
			this.mBackgroundMediaPlayer.release();
		}
                //把所有的变量恢复初始值
		/*
		private void initData() {
		this.mLeftVolume = 0.5f;
		this.mRightVolume = 0.5f;
		this.mBackgroundMediaPlayer = null;
		this.mPaused = false;
		this.mCurrentPath = null;
		}

		*/
		this.initData();
	}
    
时间: 2024-10-08 03:23:26

cocos2dx 音频模块分析(3): 背景音乐部分的相关文章

cocos2dx 音频模块分析(2):背景音乐

cocos2dx 音频模块分析(2): 背景音乐部分 我在(1)已经分析了一些东西,这里接着分析,这一篇我们主要分析背景音乐文件的播放, 还是基于android平台: 1. 这里只是背景音乐的预加载,为什么要进行预加载呢? 主要是加载音乐文件是比较耗时的,如果我们没有预加载就直接播放也是可以的, 但是会有一定的延时,因为如果没有预加载,就直接播放,也是会先进行加载音乐文件, 然后进行播放. void SimpleAudioEngine::preloadBackgroundMusic(const

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

我们上面几篇分析了cocos2dx音频模块的音乐部分,从这篇开始, 我们分析下音效部分: 1. //预加载音效文件:pszFilePath 音效文件名 void SimpleAudioEngine::preloadEffect(const char* pszFilePath) { //获取音效文件的全路径,如果是apk包里的路径,则不包含assets/ std::string fullPath = getFullPathWithoutAssetsPrefix(pszFilePath); prel

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

我们上一篇中分析的音效部分的预加载和播放函数,这一篇来分析下其他函数: 1. 暂停某个播放中的音效 //注意这里的nSoundId不是java端的soundID,而是streamID //不要被参数的名字迷惑了. void SimpleAudioEngine::pauseEffect(unsigned int nSoundId) { pauseEffectJNI(nSoundId); } -->> void pauseEffectJNI(unsigned int nSoundId) { //

WebRTC源码分析:音频模块结构分析

一.概要介绍WebRTC的音频处理流程,见下图: webRTC将音频会话抽象为一个通道Channel,譬如A与B进行音频通话,则A需要建立一个Channel与B进行音频数据传输.上图中有三个Channel,每个Channel包含编解码和RTP/RTCP发送功能. 以一个Channel而言,应用程序中将包含三个活动线程,录音线程,音频接收线程和播放线程. 1)录音线程:负责麦克风音频的采集,见图中红色路径,采集到音频后,缓存到一定长度,进行音频处理,主要包括EC,AGC和NS等.然后送到Chann

css扁平化博客学习总结(一)模块分析

一.模块分析 1.每开发一个项目之前,首先要对项目进行一个大致规划,它到底要做什么功能,它有什么具体需求. 2.所以需要进行模块化分析,把这些东西具象化,把一个问题模块化,对需求有一个宏观的了解. 3.有一个模块的概念后,把模块进行细分,细分成更小的模块,然后逐一击破. 不进行模块分析的恶劣影响: 不做模块分析,一上手就想到哪儿做到哪儿,很容易一叶障目,不能看到全貌,你会发现做着做着就失控了.因为有些地方出现了矛盾,你会发现要修改的成本很高,还不如推倒重写. 新手很容易着眼于细节,首先不应该从细

学生信息管理系统(四)——模块分析

学生信息管理系统已经敲完了,也进行了第一次验收,结果不是太理想.之前的总结也没有及时发表.现在重新复习一遍,把它发表. 从今天开始,我们就进入了代码分析阶段.现在我们就来分析一下模块中的几个函数. Public Function ExecuteSQL(ByVal SQL As String, MsgString As String) As ADODB.Recordset 'executes SQL and returns Recordset Dim cnn As ADODB.Connection

cocos2d-x 源码分析 : control 源码分析 ( 控制类组件 controlButton)

源码版本来自3.1rc 转载请注明 cocos2d-x源码分析总目录 http://blog.csdn.net/u011225840/article/details/31743129 1.继承结构 control的设计整体感觉挺美的,在父类control定义了整个控制事件的基础以及管理,虽然其继承了Layer,但其本身和UI组件的实现并没有关联.在子类(controlButton,controlSwitch,controlStepper等中实现不同的UI组件).下面通过源码来分析control与

ABP之模块分析

ABP之模块分析 本篇作为我ABP介绍的第三篇文章,这次想讲下模块的,ABP文档已经有模块这方面的介绍,但是它只讲到如何使用模块,我想详细讲解下它模块的设计思路. ABP 框架提供了创建和组装模块的基础,一个模块能够依赖于另一个模块.在通常情况 下,一个程序集就可以看成是一个模块.在 ABP 框架中,一个模块通过一个类来定义,而这 个类要继承自 AbpModule. 其实它的设计思路很简单: 1.加载bin目录下的所有dll 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15

cocos2D-X源码分析之从cocos2D-X学习OpenGL(3)----BATCH_COMMAND

个人原创,欢迎转载,转载请注明原文地址http://blog.csdn.net/bill_man 上一篇介绍了QUAD_COMMAND渲染命令,顺带介绍了VAO和VBO,这一篇介绍批处理渲染命令BatchCommand,批处理命令的处理在Render中比较简单 else if(commandType == RenderCommand::Type:: BATCH_COMMAND) { //将之前缓存的绘制 flush(); auto cmd = static_cast<BatchCommand*>