背景描述:
我们的游戏采用cocos2dx2.2.2版本开发,ios端 ,声音引擎是simple那个,发生了诡异的问题,比如切后台,再回来,背景音乐得等一段时间才有声音,或者音效没声音了,找了半天无解,看到3.x以后采用了新的AudioEngine,于是拿cocos2dx3.8版本声音引擎做了替换。并进行了简单的修改(3.x和2.x中类型名字不同等),解决编译问题和引入c++11。(我们的音效,背景音乐,都使用的caf格式)
我这里有个自己实现的外部播放管理类,来进行音乐,音效关于是不是可以覆盖,可以循环加以控制。
发现bug描述:
1.在ios端,采用新引擎,确实解决了之前simple引擎遇到的诡异问题,但是在播放背景音乐时候(AudioEngine都是用的一个播放机制,这里区分背景音乐与音效是用音频的长短,我们的音效大概<=1s,音乐30s~1min),并且这个音乐播放时候设置为可以循环的,有很大几率在播放完成一次的时候循环这个声音,没有声音了,但是看代码,AudioPlayer::rotateBufferThread,中,这个线程依然一直存在,播放短的音频,却可以一直循环出声,未解
我使用了一种方式,规避了这个bug,不采用引擎中的循环,在上一个背景音乐播完之后,在外部自己写逻辑中重新播这个文件。
2.在android端,比如类似,点按钮,或者游戏中逻辑相关的需要同时或者可能同时播放多个音效,会出现线程锁死的问题,整个游戏都卡住了,
04-13 19:41:39.978 11842-14678/com.anansimobile.pnk.base E/libOpenSLES: frameworks/wilhelm/src/android/AudioPlayer_to_android.cpp:412: pthread_mutex_lock_timeout_np returned 110
04-13 19:41:40.078 11842-14678/com.anansimobile.pnk.base E/libOpenSLES: frameworks/wilhelm/src/android/AudioPlayer_to_android.cpp:412: pthread_mutex_lock_timeout_np returned 110
ios上是cocos2dx中实现的多线程,然后用openal播声音,android上是直接用opensles,里面自己多线程吗,
尝试找相关问题,https://github.com/cocos2d/cocos2d-x/pull/11762,这里的解决方案,跟github上最新的代码是一致的,我把它导过来了,依然是会有几率出现锁死。并没有解决。
3.在android端,同样是同时播放多个声音,有比较大几率会出现AudioEngine 中_audioIDInfoMap.size() 这个map的数量会被加上去,但是没有减回来(使用的是github上最新的说是解决了死锁问题的代码),在 AudioEngineImpl::update 中,_audioPlayers 的数量也没有减下来,并且一直存在的那几个,他们的状态一直也没有变成_playOver , 一直在update里循环着。。。。在外部有个与这个map逻辑数量相对应的链表,跟它的数量一样,这样就会导致,过一会,_audioIDInfoMap.size()就会超过24个,新的声音就不会再播放了,。
和ios上比外部代码都一样,但是ios就不会出现这个问题。这个问题我觉得可能也是其他人说的播声音播着播着越来越卡,内存没释放外加opensl里起了多个线程?
上传个附件,是我在外面写的控制具体播放逻辑的代码,大概意思是,区分音乐和音效,都是可以delay一段时间播放,也可以马上播放,音效区分同一个音乐文件同时播放时是覆盖还是不覆盖,如果覆盖的话,将之前已经播放的声音stop掉(很有可能是这个逻辑导致的线程死锁?),里面用的数组是对应的音频文件的名字
最后ios上遇到的问题,通过规避的方式,没有出现其他问题了。
但是android上这个实在没法规避,也没google到合适的解决方案。自己调查也是能力有限,只能先分析成这样,希望有遇到同样问题解决了的船友帮忙看下。。我们的小船不能说翻就翻啊~~~~~~~
出现问题的测试机器,Nexus6 , Android 6.0