您的位置:首页 > 移动开发 > IOS开发

ios开发调用OpenAL的alcOpenDevice(NULL)方法返回NULL的原因之一

2015-11-16 01:28 801 查看
我们项目是基于cocos2dx 3.0开发,由于修改了cocos的底层代码,所以不能做到和cocos版本同步更新。但是最近发现我们项目在android 5.0系统上面跑起来特别卡,有些甚至掉帧很厉害。经过种种排查,最终发现是cocos2dx 3.0版本的声音引擎出了问题。

通过查看cocos2dx 3.0代码知道,cocos2dx 3.0提供的音频库接口位于CocosDenshion中,其接口由SimpleAudioEngine定义,提供了背景音乐和音效播放暂停和音量设置等基本接口。SimpleAudioEngine的实现现是夸平台的,在windows平台上调用mci相关API实现,在android平台上通过JNI,调用android sdk 中的AudioPlayer实现,在ios平台上通过调用Cocoa sdk里的Core-Audio实现。但SimpleAudioEngine并不适用于大部分游戏情境,它在Android上的实现需要直接把音乐音乐文件路径直接传给AudioPlayer,这会导致音乐文件不可以打进资源包;它是一次性解析一整个音乐文件,导致音乐播放会出现卡顿现象,它的更新是主线程更新,切换场景会导致音乐卡顿而音乐音效密集的时候会阻塞逻辑线程等等,这就是导致游戏卡顿的问题所在。

通过查看cocos2dx的升级日志我们发现,cocos2dx 在3.4版本之后新加入一个新的声音引擎,该引擎的接口定义在AudioEngine中,底层封装了OpenAL,不过接口和原先旧的接口稍微有些不同,这里并没有区分BGM和特效音乐。OpenAL本身就是跨平台的,于是我就开始手动把cocos2dx 3.4新加入的声音引擎移植到到我们的项目工程中。为了起对比作用,我只把项目中的特效接口换成了新声音引擎的接口,在windows和android上都没有啥问题,不过在ios上面就出问题了,根本听不到声音。

通过断点查看,最后发现在初始化设备连接,调用 alcOpenDevice(NULL)的时候一直返回是是NULL,询问度娘也不得其解。最后在谷歌了下,在stackoverflow上找到了答案。

My hunch is that Apple's implementation of this function only returns the correct deviceONCE for the life of the application. Every time alcOpenDevice is called after that, it returns NULL.

也就是说ios只能初始化连接设备一次,之后的连接都是返回NULL,而我的工程中使用了两个引擎,旧的引擎在初始化的时候也连接了一次声音设备,所以当我第二次去连接的时候就返回NULL了。于是我修改了代码,只使用一套声音引擎,就可以了。这确实是一个比较隐蔽的坑。

参考
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: