作者:Simon Yeung

简介

每一款游戏都应该拥有一个音频系统。在我自己的引擎中共有两种类型的声音:3D音效和背景音乐(BGM)。之所以区分了这两种声音类型是因为我们能够在硬件上解码BGM。使用iOS上的音频序列(Audio Queue)便能在一个简单的项目中播放BGM。

音效

通过使用OpenAL(与OpenGL类似的一种API)能够播放出音效。引擎中有一个音频线程,所有的OpenAL声音都是通过这条线呈现出来,并且它将通过指令缓冲区(与图形编程中的缓冲区类似)与主线联系在一起。举个例子来说,在主线更新期间,游戏逻辑也许需要一个爆破音,然后下达一个音频指令,并将其推送到指令缓冲区中。当音频线发现缓冲区中有一个指令时,它便会开始执行这一指令并激活OpenAL 调用。因为考虑到OpenAL调用可能会拖延调用线的运行,我配置了音频缓冲器和音频线。

BGM

iPhone有能够使用苹果音频序列API解码音频的硬件。通过这一API,你可以使用AudioQueueNewOutput()创造出一个音频输出序列而播放出声音,并提供如抽样率等相关的音频文件描述。你可以调用AudioFileOpenURL()函数获得这种描述。不幸的是我的项目却不适合使用这种方法,因为当游戏世界的区块流动传输时,我的音频文件也已经加载到内存中,所以我不希望只是为了获得音频文件的相关描述而调用AudioFileOpenURL()再次开启音频文件。所以我便决定自己收集数据,并以AAC压缩方法获取苹果CAF文件格式,因为它是一种开放格式,并且苹果的Mac设备带有一种命令行工具,能够将其它格式的文件转换成该格式。(dApps注:在iPhone中,音频序列只能够使用硬件解码压缩1首歌。而如果你想要播放更多音频,就需要再次使用软件解码的方法。)

CAF文件格式

与WAV文件格式一样,CAF文件格式也被划分为不同区块,如描述块(储存抽样率,每帧的频道等)以及数据块(储存音频样本数据)。我们需要获得CAF文件内部的数据并使用AudioQueue播放BGM。

样本截图

样本截图

苹果音频序列

为了使用音频序列API播放音频,我们需要经历以下几个步骤:
1.使用AudioQueueNewOutput()创造音频输出。
2.通过AudioQueueSetProperty()——它提供了音频格式所需要的Magic cookie属性,为新创建序列设置属性。
3.使用AudioQueueAddPropertyListener()创造“属性监听器”以掌握音频序列中任何变化,如完成播放等。
4.通过AudioQueueAllocateBufferWithPacketDescriptions()重新分配音频序列的储存器,以包含数据包描述内容。
5.在设立了描述块后,通过AudioQueueEnqueueBuffer()将音频样本数据整合进音频序列中。
6.随后,我们需要通过AudioQueuePrime()让硬件去解码音频样本。
7.最后便可以使用AudioQueueStart()播放音频。
停止音频序列也需要3大步骤:
1.调用AudioQueueStop()停止播放。
2.通过AudioQueueRemovePropertyListener()删除上述第三个步骤所设立的“属性监听器”。
3.最后,调用AudioQueueDispose()释放所有音频序列资源。
在iPhone上使用OpenAL播放3D音效其实与其它平台上的做法差不多,而播放BGM却比较麻烦,因为来自苹果的样本代码只提供了一个特定的文件路径(告诉我们如何播放一个音频),而不是加载于内存中的音频文件,所以我便需要自己想办法获取音频文件描述。
性能对于游戏来说非常重要,它能够有效地维持游戏中不断变化的频率。所以我将在此谈论的是如何追踪游戏性能。然而因为我的游戏还未完成,所以我只能用样本占位符资产配置引擎,而且我现在所描述的数据可能跟成品游戏有所出入。不管怎样,我都会努力阐述我第一次的引擎配置尝试(dApps注:以下所有的数据取自iPhone 3G)。

分析XCode OpenGL ES

伴随Xcode4的OpenGL ES分析器能够用于分析iPhone上的图像性能。它能够察觉到多余的状态改变并提供适当的建议以完善渲染性能。除此之外它也能够帮助发现一些漏洞,如忘记设定纹理状态以使用mip-map。

分析器

分析器


在使用分析器后,我发现了2种能够有效完善引擎渲染性能的方法。第一种便是在渲染每个画面后使用“EXT_discard_framebuffer”扩展。
DiscardFB

DiscardFB


在使用分析器之前我甚至不知道iPhone拥有OpenGL扩展功能;它能够帮助我们将帧率从20.8毫秒每帧提高到19.2毫秒每帧。而第二种方法便是使用后备缓冲格式以降低填充率。
CompactFB

CompactFB


设置了后备缓冲区格式(从RGBA8888变化到RGB565)后,每一帧所需要的时间从19.2毫秒减少到18.52毫秒。

性能图表

性能图表

性能图表


我也创造了一个性能图表以呈现引擎中每个子系统所使用的时间。创造关于游戏的波浪曲线图很简单,并且我可以在此观察子系统的变化。

结论

使用上述两种方法能够帮助我们有效地追踪性能问题并提高帧率。
dApps注:原文发表于2011年9-10月,所涉事件及数据以当时为准。