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

news/2024/7/20 22:35:53 标签: IOS, openal, alcOpenDeviceNULL

    我们项目是基于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了。于是我修改了代码,只使用一套声音引擎,就可以了。这确实是一个比较隐蔽的坑。

 

参考


http://www.niftyadmin.cn/n/1459269.html

相关文章

自定义TTF多语言版本之台湾繁体

最近做台湾的多语言差异化版本,由于一开始我们都是使用简体中文,不论是配置还是ui,所以如果全部手工去装换,处理起来工作量挺大的。在查看到网上查找了一番,发现是有字库可以把简体字转换成繁字体的,这可以…

Unity3D控制Animator播放

有一个需求,要求第一次打开一个界面触发一个动画播放,关闭界面动画播放关闭,再次打开界面继续上次到播放而不是重新开始播放,如果动画播放结束关闭打开界面入口(即无法在此进入该界面)。 有两种实现方法&am…

Cocos2dx 3.0下的C/C++和Lua通讯以及Object C与Lua通讯

网上关于Cocos2dx开发过程中Lua的使用以及原理教程已经很多了,结合我的开发经验,我在这里稍微整理下。 可以说Cocos2dx-Lua提供了一种很轻便的开发模式,省去了冗长的编译时间,同时让热更成为了很容易的一件事情,不仅仅…

Unity3D中AssetBundle的打包和加载

Unity的资源管理是一个比较复杂的模块,如果管理不好,可能导致最终包体大小偏大,程序运行时候内存居高不下,因此了解并掌握Unity的资源管理显得特别重要。 Unity中资源一般存放在两个目录下,一个是Resource目录&#x…

Unity3D引擎跨平台底层原理及为何无法在iOS平台上热更新

Unity3D引擎是一款这几年特别火爆3D游戏引擎,大家都知道Unity3D引擎是跨平台的。所谓跨平台就是说开发者只需要写一套逻辑代码,即可发布到各个平台,如Android,PC,iOS等。那为何Unity3D能够做到跨平台呢?之前…

Unity3D打包中优化iOS包大小

有过App Store提审经验的童鞋应该知道,App Store对iOS提审包有一个包体大小的限制,这个限制不仅仅是对Mach-O可执行文件大小限制,还有整包大小的限制,比如“80M”、“150M”,这些包体大小的限制会直接影响到你APP能否成…

游戏中的网络同步

在网络游戏中游戏数据和状态的同步是整个游戏的基础,而游戏中对网络同步要求最高的就是战斗状态的同步,它影响玩家的游戏体验。同时,不同类型游戏的战斗状态同步对网络同步要求又不一样,所以产生了不同的网络同步机制。网络是有延…

Unity3D中的动态字体和静态字体

Unity3D中支持动态字体和静态字体两种格式字体,动态字体即使用TTF格式字体库,静态字体则需要自己打包字体图集。动态字体和静态字体区别在于,动态字体如果出现字体库中不存在的字体,会使用系统字体,而静态字体则不会&a…