EBP管线概述

音频编程 / 游戏音频

EBP是什么?

前不久Wwise 2019.2版本的UE4 Integration推出了一条新的管线,叫做Event-Based Packaging,简称EBP。相比于传统的SoundBank管线,这条新管线的特点是基于事件打包,也就是每一个事件的资源会被打包成一个SoundBank

为什么要这么做?原因是在Wwise传统的管线中,如何组织SoundBank是交给用户自己决定的。在规模较大的项目中,这个组织工作往往需要花费大量时间。而且因为是手动组织管理,加载资源时,冗余也在所难免。而新的EBP流程中,每个事件对应的资源都将被自动打包成SoundBank,而且隐藏在事件的.uasset中,无需用户管理。调用事件时,只有包含相应媒体资源会被加载,这样就实现了需要多少资源就加载多少的机制,根本上杜绝了资源冗余的发生。而且由于每个SoundBank中只包含一个事件的资源,因此可以灵活卸载它们,而无需担心其他的事件无法播放。

本文会介绍一些EBP管线中的关键资源及其加载过程,这样能更好地帮助大家理解这条新的管线。

EBP与WAAPI

要实现在UE中基于事件自动打包,就需要获取Event以及Event与声音媒体的对应关系。这个过程中,EBP管线极度依赖WAAPIWAAPI的全称是Wwise Authoring API,是一套允许外部应用程序跟Wwise创作工具通信的API。用户可以通过调用这些API控制Wwise创作工具,因此也可以把它理解为连接UE4Wwise创作工具之间的桥梁。

当你在Wwise创作工具内创建了一个EventUE4通过注册的回调函数接收到该操作指令后,将自动创建对应的事件.uasset。同样,当用户在UE中的WAAPIPicker面板内点击Generate Sound Data按键时,Wwise创作工具中也会执行Generate SoundBanks操作。在EPB流程中,WAAPI可以保证UEWwise创作工具始终保持同步。

通过WAAPI连接Wwise以生成SoundBank是首选的方式,但并不是唯一的生成SoundBank的方式。如果项目无法通过WAAPI连接到Wwise Authoring工具,则可以通过单击Wwise Picker窗口中的Generate Sound Data按钮以使用Wwise Console启动生成过程。与WAAPI相比,生成速度较慢,因为它使用更多的系统I/O调用,但是生成的结果是相同的。您还可以点击Build菜单中的Audiokinetic分进入Generate Sound Data对话框。

UE中的Wwise资源

声音研发过程中,用户可以利用Wwise中的 Event, State, Switch, RTPC, Bank, Auxiliary Bus, Media资源在项目中构建和编织声音世界。在UE中,这些资源均以.uasset的形式存在,默认情况下存储在Content/WwiseAudio/文件夹中。项目的Wwise资源的位置可以在UE4项目设置的Wwise集成设置部分配置,通过修改“Wwise声音数据文件夹设置。

下面的表格列出了Wwise资源相应的类,以及它们在UE中的保存位置:

EBP


Wwise
资源的反序列化

上述资源都派生自Uobject类,这些派生类都需要通过反序列化,把自己变为对象。反序列化是指将一个字节流转换为内存中的一个对象的过程。下图是所有的Wwise资源的类图,可以看到所有资源的派生关系:

image001

在游戏中,开发者可以通过资源引用和C++代码加载这些资源。对于在场景中拖放的对象,或通过Component属性来引用的资源,当Compnent所在对象实例化时,其中的Wwise资源也会被加载。此外,也可以通过在UE中调用LoadObject()来加载这些资源。

而在编辑器中,加载派生自UAKAudioType类资源的工作由AkAssetDatabase类来完成,它的构造函数会注册onAssetAddedonAssetRemovedonAssetRenamed这三个事件。其中onAssetAdded负责处理所有资源的加载。实际上在打开UE4引擎编辑器时,当前场景中的Wwise资源都会被加载。

媒体.uasset的加载则是随着事件.uasset实例化进行的,后文的加载过程介绍中,我们将会具体探讨。接下来,我们看看最重要的两种资源,也就是事件.uasset和媒体.uasset中到底包含了哪些内容。

事件.uasset中的内容

用户使用最多的资源就是游戏中的各种事件,创作工具中的事件与UE中的事件.uasset资源,是一对一的关系。用户可以使用事件来执行播放、暂停、设置SwitchState等动作。在EBP中,每个事件.uasset都保存了所有平台的事件内容。其中很关键的信息是事件依赖的SoundBank与媒体资源路径。这里的SoundBank中只有EventStructure,不包含媒体资源本身,因此事件.uasset文件大小只有几KB。媒体资源路径则是寻找并加载媒体资源的依据。

媒体.uasset中的内容

不同的Event中有时会引用相同的音频文件,这种情况很常见,但容易造成资源冗余。为了实现事件.uasset之间共享声音文件,所有的媒体都从SoundBank中剥离了出来,单独保存在Content\WwiseAudio\Media\文件夹下。按照创作工具中的组织方式,事件依赖的每一个Audio Soucre都会对应一个媒体.uasset文件。它和事件.uasset一样,会在一个文件中保存所有平台的内容。当用户添加新的平台,该文件体积将会增大。

image002

媒体资源以ID命名,如果想要查找对应的MediaName,可以在UEContent Browser中浏览Content\WwiseAudio\Media,并以Columns的方式来显示。

Wwise主要资源的加载过程

现在我们了解了事件.uasset和媒体.uasset这两个最重要的资源的内容,下面就来看看加载它们的步骤。由于SoundBank和媒体已经分开存放,加载资源时就需要先加载SoundBank,再加载它引用的媒体。

加载文件内的Soundbank

使用Wwise时,在PostEvent之前必须加载该事件依赖的SoundBankEBP中也是如此。事件.uasset加载的过程中,会自动加载其中的SoundBank,也就是所有EventStructure都会被加载。需要注意的一点是,在EBP中,事件.uasset实例化时,SoundBank已经被加载到内存中,这就意味着加载的SoundBank位于UE的保留内存,而不是Wwise本身的保留内存。声音引擎会通过接受内存地址的AK::SoundEngine::LoadBankMemoryView()函数加载SoundBank

加载依赖的Media

完成SoundBank加载后,媒体.uasset也将被加载,下一步将会通过保存在事件.uasset内部的媒体资源路径去加载媒体。因此它与SoundBank一样位于UE的保留内存中。

EBP管线没有采用PrepareEvent的方式加载媒体,而是通过调用接受内存地址的SetMedia()函数来获取资源告诉声音引擎该媒体资源所在的内存位置。每个媒体.uasset只会被实例化一次因此无需担心数据会被重复加载。

小结

本文简要介绍了EBP管线中的主要资源内容以及它们的加载过程,希望可以帮助读者理解这条管线的组织方式。EBP管线相对比较新,因此随着后续发布版本不断更新完善,本文所述的内容可能也会发生细节上的变化。但笔者相信,自动化管理SoundBank的方式可以为游戏音频研发流程节省可观的时间成本。期待它在不久的将来能够更加成熟稳定,为更多的游戏研发团队带来效益上的提升。

本文能和读者见面,离不开我在Audiokinetic的同事们的帮助,在此衷心感谢 Guillaume Renaud Julie Delisle 严谨而富有建设性的建议和指正!

范润鹏

大中华区技术支持工程师

Audiokinetic

范润鹏

大中华区技术支持工程师

Audiokinetic

热衷于研究游戏中间件的使用和开发管线的优化,以提供可行性高的解决方案为己任。同时也一位执迷于烹饪的技术支持工程师,认为技术和美食一样需要分享。

评论

ming fang

January 11, 2021 at 10:44 pm

你好,请问基于EPB时,如果单个Event对应的媒体资源很大,但是又不想拆分event时,event需要的媒体资源是否可以进行异步加载呢

ming fang

January 11, 2021 at 10:44 pm

你好,请问基于EPB时,如果单个Event对应的媒体资源很大,但是又不想拆分event时,event需要的媒体资源是否可以进行异步加载呢

ming fang

January 11, 2021 at 10:44 pm

你好,请问基于EPB时,如果单个Event对应的媒体资源很大,但是又不想拆分event时,event需要的媒体资源是否可以进行异步加载呢

ming fang

January 11, 2021 at 10:44 pm

你好,请问基于EPB时,如果单个Event对应的媒体资源很大,但是又不想拆分event时,event需要的媒体资源是否可以进行异步加载呢

留下回复

您的电子邮件地址将不会被公布。

更多文章

《NieR: Automata》的空间声学设计以及如何借助 Wwise 实现对多种游戏玩法的支持 – 第 2 部分

请阅读本文第 1 部分。 利用 Wwise 控件为各种游戏玩法提供支持...

25.3.2019 - 作者:PlatinumGames Inc.

《Murderous Pursuits》的对白和对话设计 – 第 1 部分

大家好,我是杰米·克罗斯,目前在 Blazing Griffin 的游戏团队担任音频设计师。2018年,我们发布了《Murderous...

26.8.2019 - 作者:杰米·克罗斯 (Jaime Cross)

《Clocker》的声音设计 - Part 1

大家好,我是谭宇,来自一罐盐声音工作室(Salt Sound Studio)。下面将通过这篇博客跟大家分享一下我们的项目...

23.9.2019 - 作者:谭宇

Wwise Unreal 音频整合指南

在此跟大家介绍一下由我们在 Game Audio Resource 的朋友制作的 Wwise 2019.1.4 Unreal 4 音频整合指南。...

10.9.2020 - 作者:Game Audio Resource

人人都能用 WAAPI(一)概述

大家好,我是溪夜。 去年下半年我接触到了 WAAPI(Wwise Authoring API),作为头脑不怎么灵光的非专业程序员,看到 WAMP、JSON...

29.9.2020 - 作者:汪洋

人人都能用 WAAPI(二)wwise.core 分支

大家好,我是溪夜。 在《人人都能用 WAAPI(一)概述》中,我们用思维导图对 WAAPI 进行了重新归纳,并在配置好开发环境后,一起用 Python 写了几个简单的小程序,体验了 WAAPI...

29.10.2020 - 作者:汪洋

更多文章

《NieR: Automata》的空间声学设计以及如何借助 Wwise 实现对多种游戏玩法的支持 – 第 2 部分

请阅读本文第 1 部分。 利用 Wwise 控件为各种游戏玩法提供支持...

《Murderous Pursuits》的对白和对话设计 – 第 1 部分

大家好,我是杰米·克罗斯,目前在 Blazing Griffin 的游戏团队担任音频设计师。2018年,我们发布了《Murderous...

《Clocker》的声音设计 - Part 1

大家好,我是谭宇,来自一罐盐声音工作室(Salt Sound Studio)。下面将通过这篇博客跟大家分享一下我们的项目...