cocos2dx 音频模块分析(5): 音效部分
发表于2015-12-02
cocos2dx 音频模块分析(5): 音效部分
- 我们上一篇中分析的音效部分的预加载和播放函数,这一篇来分析下其他函数:
- 1、
- 暂停某个播放中的音效
- //注意这里的nSoundId不是java端的soundID,而是streamID
- //不要被参数的名字迷惑了。
- void SimpleAudioEngine::pauseEffect(unsigned int nSoundId)
- {
- pauseEffectJNI(nSoundId);
- }
- -->>
- void pauseEffectJNI(unsigned int nSoundId)
- {
- // void pauseEffect(int)
- JniMethodInfo methodInfo;
- if (! getStaticMethodInfo(methodInfo, "pauseEffect", "(I)V"))
- {
- return ;
- }
- methodInfo.env->CallStaticVoidMethod(methodInfo.classID, methodInfo.methodID, (int)nSoundId);
- methodInfo.env->DeleteLocalRef(methodInfo.classID);
- }
- ---->>//java端方法:
- //pStreamID 这个参数,是调用unsigned int SimpleAudioEngine::playEffect()放回的StreamID
- public void pauseEffect(final int pStreamID) {
- /**
- * Pause a playback stream. 暂停一个播放流
- *
- * Pause the stream specified by the streamID. This is the
- * value returned by the play() function. (这个值是play函数的返回值)If the stream is
- * playing, it will be paused. If the stream is not playing
- * (e.g. is stopped or was previously paused), calling this
- * function will have no effect.(如果处于播放状态则暂停,如果不处于播放状态,则无效)
- *
- * @param streamID a streamID returned by the play() function
- */
- this.mSoundPool.pause(pStreamID);
- }
- 2、
- 暂停所有音效
- void pauseAllEffectsJNI()
- {
- // void pauseAllEffects()
- JniMethodInfo methodInfo;
- if (! getStaticMethodInfo(methodInfo, "pauseAllEffects", "()V"))
- {
- return ;
- }
- methodInfo.env->CallStaticVoidMethod(methodInfo.classID, methodInfo.methodID);
- methodInfo.env->DeleteLocalRef(methodInfo.classID);
- }
- --->>java端
- public void pauseAllEffects() {
- /**
- * Pause all active streams. //暂停所有正在播放的音效
- *
- * Pause all streams that are currently playing. This function
- * iterates through all the active streams and pauses any that
- * are playing. It also sets a flag so that any streams that
- * are playing can be resumed by calling autoResume().
- */
- this.mSoundPool.autoPause();
- }
- 3、
- 恢复播放某个音效
- void resumeEffectJNI(unsigned int nSoundId)
- {
- // void resumeEffect(int)
- JniMethodInfo methodInfo;
- if (! getStaticMethodInfo(methodInfo, "resumeEffect", "(I)V"))
- {
- return ;
- }
- methodInfo.env->CallStaticVoidMethod(methodInfo.classID, methodInfo.methodID, (int)nSoundId);
- methodInfo.env->DeleteLocalRef(methodInfo.classID);
- }
- --->>
- public void resumeEffect(final int pStreamID) {
- /**
- * Resume a playback stream.
- * 只有处于暂停状态的stream,才可以恢复播放。
- * Resume the stream specified by the streamID. This
- * is the value returned by the play() function. If the stream
- * is paused, this will resume playback. If the stream was not
- * previously paused, calling this function will have no effect.
- *
- * @param streamID a streamID returned by the play() function
- */
- this.mSoundPool.resume(pStreamID);
- }
- 4、
- void resumeAllEffectsJNI()
- {
- // void resumeAllEffects()
- JniMethodInfo methodInfo;
- if (! getStaticMethodInfo(methodInfo, "resumeAllEffects", "()V"))
- {
- return ;
- }
- methodInfo.env->CallStaticVoidMethod(methodInfo.classID, methodInfo.methodID);
- methodInfo.env->DeleteLocalRef(methodInfo.classID);
- }
- ---->>>java端函数:
- public void resumeAllEffects() {
- // can not only invoke SoundPool.autoResume() here, because
- // it only resumes all effects paused by pauseAllEffects()
- // 这里注释的很清楚
- if (!this.mPathStreamIDsMap.isEmpty()) {
- final Iterator<entry<string, arraylist
>> iter = this.mPathStreamIDsMap.entrySet().iterator(); </entry<string, arraylist - while (iter.hasNext()) {
- final Entry<string, arraylist
> entry = iter.next(); </string, arraylist - for (final int pStreamID : entry.getValue()) {
- this.mSoundPool.resume(pStreamID);
- }
- }
- }
- }
- 5、
- 停止播放某个音效,这里的nSoundId同样是pStreamID,停止播放的音效是不能
- 通过resume恢复播放的。
- void SimpleAudioEngine::stopEffect(unsigned int nSoundId)
- {
- stopEffectJNI(nSoundId);
- }
- --->>java端:
- public void stopEffect(final int pStreamID) {
- /**
- * Stop a playback stream.
- *
- * Stop the stream specified by the streamID. This
- * is the value returned by the play() function. If the stream
- * is playing, it will be stopped. It also releases any native
- * resources associated with this stream. (会释放对应的资源)If the stream is not
- * playing, it will have no effect.
- *
- * @param streamID a streamID returned by the play() function
- */
- this.mSoundPool.stop(pStreamID);
- // remove record
- // 从记录列表中移除
- for (final String pPath : this.mPathStreamIDsMap.keySet()) {
- if (this.mPathStreamIDsMap.get(pPath).contains(pStreamID)) {
- this.mPathStreamIDsMap.get(pPath).remove(this.mPathStreamIDsMap.get(pPath).indexOf(pStreamID));
- break;
- }
- }
- }
- 6、
- void stopAllEffectsJNI()
- {
- // void stopAllEffects()
- JniMethodInfo methodInfo;
- if (! getStaticMethodInfo(methodInfo, "stopAllEffects", "()V"))
- {
- return ;
- }
- methodInfo.env->CallStaticVoidMethod(methodInfo.classID, methodInfo.methodID);
- methodInfo.env->DeleteLocalRef(methodInfo.classID);
- }
- --->>>java端
- @SuppressWarnings("unchecked")
- public void stopAllEffects() {
- // stop effects,停止所有音效的播放
- if (!this.mPathStreamIDsMap.isEmpty()) {
- final Iterator iter = this.mPathStreamIDsMap.entrySet().iterator();
- while (iter.hasNext()) {
- final Map.Entry<string, arraylist
> entry = (Map.Entry<string, arraylist >) iter.next(); </string, arraylist </string, arraylist - for (final int pStreamID : entry.getValue()) {
- this.mSoundPool.stop(pStreamID);
- }
- }
- }
- // remove records,清空播放记录
- this.mPathStreamIDsMap.clear();
- }
- 7、
- 卸载加载的音效(重要)
- //pszFilePath:音效文件名
- void SimpleAudioEngine::unloadEffect(const char* pszFilePath)
- {
- std::string fullPath = getFullPathWithoutAssetsPrefix(pszFilePath);
- unloadEffectJNI(fullPath.c_str());
- }
- --->>
- void unloadEffectJNI(const char* path)
- {
- // void unloadEffect(String)
- JniMethodInfo methodInfo;
- if (! getStaticMethodInfo(methodInfo, "unloadEffect", "(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);
- }
- --->>>
- public void unloadEffect(final String pPath) {
- // stop effects
- // 先停止
- final ArrayList
streamIDs = this.mPathStreamIDsMap.get(pPath); - if (streamIDs != null) {
- for (final Integer pStreamID : streamIDs) {
- this.mSoundPool.stop(pStreamID);
- }
- }
- this.mPathStreamIDsMap.remove(pPath);
- // unload effect
- final Integer soundID = this.mPathSoundIDMap.get(pPath);
- if(soundID != null){
- /**
- * Unload a sound from a sound ID.
- *
- * Unloads the sound specified by the soundID. This is the value
- * returned by the load() function. Returns true if the sound is
- * successfully unloaded, false if the sound was already unloaded.
- *
- * @param soundID a soundID returned by the load() function
- * @return true if just unloaded, false if previously unloaded
- */
- // 卸载音效
- this.mSoundPool.unload(soundID);
- // 从mPathSoundIDMap中移除
- this.mPathSoundIDMap.remove(pPath);
- }
- }
- /************************************************
- 总结:
- 音效部分最重要的函数是preloadEffect,unloadEffect,playEffect,stopAllEffects
- 其他的感觉不是很常用,java有两个比较重要的map,一个是:
- private final HashMap
mPathSoundIDMap = new HashMap (); - 这个是用来存放所有加载的音效文件路径和SoundID的map。
- 一个是:
- // sound path and stream ids map cocos2dx原本注释
- // 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
> mPathStreamIDsMap = new HashMap<string, arraylist >();</string, arraylist </string, arraylist - 用来存放所有播放的音效文件路径和StreamIDs的map。
- 注意:这里的SoundID和StreamID不是一个概念,一个音效文件只对应一个SoundID,而却可以对应多个StreamID,因为一个
- 音效文件可以播放多次(StreamID),但是只需要加载一次(SoundID).
- ************************************************/