版本
menu_open

Understanding how SoundBanks are loaded in a game

在学习如何在 Wwise 中创建、填充和生成 SoundBank 之前,要先了解游戏加载和管理 SoundBank 信息的不同方式。最佳方式取决于各种不同的因素,包括开发的游戏类型、运行游戏的平台以及项目团队设定的限制。

为了提高灵活性和满足几乎所有游戏类型的需求,Wwise 提供了多种将音频和振动加载到游戏中的方法,包括以下几种:

Loading full SoundBanks

加载 SoundBank 的传统方法使用同时包含事件数据、对象结构数据和媒体的 SoundBank。这些 SoundBank 的全部内容在游戏的特定时刻加载和卸载,确保事件数据和相关媒体在被触发时就可以播放。

下图演示在游戏中使用传统方法创建的 SoundBank 如何在玩家从 1 级升级到 2 级时加载到平台内存和从平台内存中卸载。

由于特定 SoundBank 的所有数据和媒体同时加载到内存中,因此这种方法不仅确保所有数据和媒体可以在需要时播放,而且在游戏中需要执行极少的磁盘寻址,从而将磁盘腾出来执行对磁盘需求较大的其它任务。

此方法的主要缺点是在 SoundBank 的整个加载期间将占用大量的内存,使您无法灵活地处理复杂的大型游戏。此方法还显式加载 SoundBank 中的所有内容,而不验证媒体文件是否已经加载到内存。这可能会导致同一媒体文件被多次加载到内存中。尽管此传统方法有上述缺点,但是在许多情况下仍非常有用。例如,用于所有数据和媒体必须随时可用的经典弹珠游戏。

Preparing SoundBanks (all content)

为了克服 LoadBank() 机制的一些缺点,您可以先采用 Prepare 操作来"预备" SoundBank 而不是使用 AkBankContent_All() 加载它们(译注:为了突出 Prepare 是一种 API 调用,文档尽量用英语原文来代表这种预备操作,而不做通篇翻译)。在使用此方法时,SoundBank(音频包)仍可包含所有内容类型(Event、结构数据和媒体文件);不过,此方法不会立即加载媒体文件,而是借助 PrepareEvent() 机制将所有媒体加载到内存中。通过使用此机制加载媒体,Wwise 首先查看媒体文件是否已经存在内存中,然后再加载它。这可以避免内存中出现媒体文件重复,从而将内存占用保持在最低水平。

除了可以节省内存外,此方法还可以保证顺序访问磁盘,这将避免在使用 PrepareEvent() 中一次 Prepare 一个 Event 时可能发生的随机磁盘寻址。

下图演示了"Prepare Bank(All Content)"(预备 SoundBank(全部内容))机制如何将元数据和内容加载到平台内存中。

在加载包含 Vorbis 编码或 WEM Opus 编码媒体的 SoundBank 时,可利用 Preparation_LoadAndDecode 预备类型将这些媒体文件解码为非压缩 PCM 文件。这会使 SoundBank 体积变大,但当事件调用媒体文件时,将立即播放而无需进行解码。

Prepare 动作事件

PrepareEvent() 方法只有在绝对需要时才会动态加载媒体。使用此方法时,动作事件元数据必须位于 SoundBank 中,相关媒体文件必须位于文件系统中可访问的位置。相应结构元数据可包含于事件所在的同一 SoundBank 中,也可包含于单独的 SoundBank 中。在使用此方法时,包含动作事件元数据的 SoundBank 使用 LoadBank() 加载并保留在内存中。在动作事件被游戏调用前,声音引擎先 Prepare(预备)这些事件。Prepare 事件时将从文件系统中加载所有被引用的媒体文件,如果所有被引用的结构元数据尚未加载,则还将从 SoundBank 中加载这些结构元数据。当动作事件不再需要时,可将它 Unprepare(解除预备),相应媒体文件于是将从内存中被清除掉。为了将内存占用保持在最低水平并避免内存中出现媒体文件重复,Wwise 在加载媒体文件前会先确认它不存在于内存中。

[备注]备注

只有动作 Event 可事先 Prepare。"PrepareEvent()"方法不适用于对话事件。

下图说明如何事先 Preapre Event,以便只将必需的媒体文件加载到内存中。

当元数据(又称结构)未存储在 Event 所在的同一 SoundBank 时,Wwise 需要一种方法来找到位于另一 SoundBank 中的相应数据。为此,Wwise 加入了对其它 SoundBanks 中存储的相应内容的引用。Wwise 可以使用名称或 ID 来引用其它 SoundBank。To use the SoundBank name in the sound engine, you must select the Use SoundBank Names option on the SoundBanks tab of the Project Settings dialog. 要使用 ID,则取消勾选该选项。要了解详细信息,请参阅“SoundBanks 选项卡”一节

被 SoundBank 引用的媒体必须作为松散文件存储在磁盘中,否则必须能够被底层 IO(Low-Level IO)解析(例如在 File Package 中)。

此方法在内存利用方面总体来说非常高效,但需要额外执行磁盘寻址。在已经通过磁盘流传输大量文件时,这种方法可能不太合适。另外,在游戏使用了 State 和 Switch 的情况下,不需要的媒体文件可能会被白白加载到内存中。例如,您针对游戏中人群的不同情绪或能量级别设置了不同的人群声音,如果游戏的特定区域中只有“愤怒“ Switch 声音有效时,则所有级别的人群声还是都会被加载到内存中来,而这样您是不会愿意的。为了克服这一问题,您还可以 Prepare 特定的 State 或 Switch,只加载与 Prepare 的 State 或 Switch 相关的媒体文件。

下图显示了如何提前 Prepare Switch,以进一步限制在游戏任何特定时刻加载到内存中的媒体量。

虽然提前 Prepare Game Sync 可以优化内存占用,但注意,这也会降低媒体加载到内存中的速度。读取时间延长是因为声音引擎需要搜索磁盘,以查找与 Prepare 的 Game Sync 相对应的声音。

通过动态地只加载必需的音频文件,第二种方法可以为您处理以下情况提供更大的灵活性:处理具有大量声音的超大区域或关卡,或者以非常有限的内存量来存储事件数据、结构数据和媒体。

您可以看到,每种方法各有长短。最佳方式取决于游戏的特定场景、要求和限制。在确定策略后(使用一种方法还是同时使用多种方法),您可以开始相应地填充和优化您的 SoundBank。

[备注]备注

LoadBankAkBankContent_AllPrepareEventPrepareGameSyncsAkBankContent_StructureOnly 函数均可通过 Wwise API 访问。有关加载 SoundBank 和 Prepare 事件或 Game Sync 的详细信息,请参阅 Wwise SDK 的《集成 SoundBanks》一节。

有关可用于管理 SoundBank 的不同方法的详细概述,请参阅“Strategies for managing SoundBanks”一节


此页面对您是否有帮助?

需要技术支持?

仍有疑问?或者问题?需要更多信息?欢迎联系我们,我们可以提供帮助!

查看我们的“技术支持”页面

介绍一下自己的项目。我们会竭力为您提供帮助。

来注册自己的项目,我们帮您快速入门,不带任何附加条件!

开始 Wwise 之旅