Wwise Authoring Query Language 简介

音频编程 / Wwise 技巧和工具

“Wwise 不过是张电子表格”。作为用户体验团队成员,我们经常会听到有人这样说。事实上,Wwise 不仅是款声音设计工具,Wwise 工程还保留有大量数据。各种各样的数据。如今的现实是,游戏非常地大。要想避免出现问题,最好能自如地操控数据。

好在 Wwise 提供有各种用来操控数据的工具,如 List ViewMulti EditorBatch RenameQuery Editor

WAQL_List-1

而且还有很多技巧和窍门,来完善 Wwise 工程的组织,以便高效地处理大量数据。比如,创建 Work Unit、使用命名规范、通过制表符分隔文件导入音频文件、使用自定义属性、运用批量命名工具、指派颜色等等。

另外,还可借助 SearchQuery Editor 来查找数据。不过,这些工具存在一定的限制。比方说,如何查明工程中都有哪些 Random Container 包含循环声音?或者,怎么确定某个 Event 当前引用了哪些音频源?

几年前,我们推出了 WAAPI。该编程 API 方便程序员自动处理、操控和查询 Wwise 工程。不过,WAAPI 需要用到编程语言。一般只有程序员才会使用,其他 Wwise 用户很难掌握。而且,在运行 WAAPI 脚本之前,要花一些时间来进行设置。

这里有个用 Python 编写的 WAAPI 示例,可列出 Event 当前引用的所有转码后文件。看起来不怎么好懂。

from waapi import WaapiClient
import pprint

# 连接(默认 URL)
client = WaapiClient() 

# 返回所有目标
args = {
    "from": {"path": ['\\Events\\Default Work Unit\\Play']},
    "transform": [
        {"select": ['children']}
    ]
}

options = {
    "return": ['@Target']
}
result = client.call("ak.wwise.core.object.get", args, options=options)
pprint.pprint(result)

# 返回所有来自目标的 wem 文件
args = {
    "from": {"id": list(map(lambda x: x['@Target']['id'], result['return']))},
    "transform": [
        {"select": ['descendants']},
        {"where": ['type:isIn', ['AudioFileSource']]}
    ]
}

options = {
    "return": ['name', 'id','sound:convertedWemFilePath']
}
result = client.call("ak.wwise.core.object.get", args, options=options)
pprint.pprint(result)

# 断开连接
client.disconnect()

WAQL 简介

Wwise 2021.1 首次引入了 WAQL,即 Wwise Authoring Query Language。如果是 JIRA 用户,可能对用来查询 JIRA 数据库的 JIRA Query Language (JQL) 不陌生。要是程序员,应该对 C# LINQ 或 SQL 比较熟。WAQL 跟这些语言有些相似。它允许通过数据模型来查询 Wwise 工程。说白了,就是查询 Wwise 对象及其属性。

WAQL 更加方便用户操控工程内的数据。这门新语言虽然也需要学习,但跟掌握整套编程语言(如 Python、Javascript 或 C#)相比,难度要小很多。更重要的是,它可以直接通过 Wwise 设计工具来访问。本文旨在帮助大家了解 WAQL 相关基础知识。各位不妨一边阅读文章,一边在 Wwise 工程中实践。本文既是对 WAQL 的简介,同时也可是一项入门教程。

下面,先从最简单的操作说起。让我们来查找工程中所有音量小于零的对象。为此,可打开 List View,然后键入 $ where volume < 0。

WAQL_list_view

等等!我们得先弄明白这一切到底是怎么实现的。首先,在 List View 搜索栏中键入内容时,通常会针对整个工程执行文本搜索。不过,现在我们在开头键入了 $。这会告知 Wwise 要启动 WAQL 查询而非简单搜索。

然后,where 关键字指示要编写条件语句。默认情况下,在使用 where 开始查询时,会针对工程内的所有对象执行对应条件。最后,我们要编写条件语句。在本例中,我们要求将音量(Wwise 对象的属性)与数值 0 进行对比。该条件会滤掉音量不小于零的对象。

Wwise 对象和属性

接下来要说到另一个话题:Wwise 对象和属性。Wwise 对象本质上涵盖了 Project Explorer 中的所有条目,以及不同系统内隐藏或显示的其他一些对象。属性在对象内定义,并且可以存储数值。

Wwise 中设有很多属性。比如,Property Editor 内 General Settings 选项卡中 Sound 对象的各项属性:

WAQL_Markers

属性可存储以下任一类型的数据:

  • 数值(整数、实数、布尔值、字符串)。如 Volume
  • 对工程中另一对象的引用。如 OutputBus. Effect0
  • 本地对象,即 Custom。如 Effect0

有关各种 Wwise 对象及其属性的完整列表,请参阅此处

另外,大部分对象都有核心属性。比如,所有 Wwise 对象都有 Name、Notes、Path 和 ID 属性,而只有特定类型的对象有 Volume 和 Output Bus 属性。核心属性有时需要计算,有时与对象存储在一起。无论对于哪种情况,WAQL 中的属性名称都不区分大小写。 

有关核心属性的详细信息,请参阅此处。 

快速了解条件

正如前面看到的,where 语句定义有条件。条件会对赋予 where 语句的每一对象进行评估。这些条件由布尔表达式定义;语句的判定结果可为 true 或 false。

以下是几个例子:

  • $ where pitch = 1200
  • $ where volume > -10 and volume < 0
  • $ where IsLoopingEnabled or IsStreamingEnabled 
  • $ where (volume >= 0 and (lowpass > 0 or highpass > 0))

下面,我们来试着在不同场景中使用 where 条件。

另外,还可在 WAQL 中选用以下三种字符串比较运算符来搜索并比对文本:

  • $ where name = "Hello"
    等号用于对整个字符串和另一字符串进行不区分大小写的比对。若两个字符串完全相同,则返回 true。
  • $ where notes : "hell"
    冒号用于查找字符串内某个单词的开头。该操作不区分大小写。若找到单词,则返回 true。
  • $ where outputbus = /^Music\d+$/
    等号还可与常规表达式(ECMAScript 样式)一起使用。

联用对象和属性

Wwise 对象具有两种类型的属性:

返回数值的属性:

  • Volume、Pitch、Lowpass 等:通常与 Wwise 中的滑杆关联,用于存储数字值。这些属性因对象类型而异。比如,Sound 和 Random Container 便拥有不同的属性。
  • Name、Notes、ID、Path:Wwise 对象系统的核心元素,其通常存储字符串值。所有 Wwise 对象都拥有这些属性。

返回另一 Wwise 对象的属性(又称引用):

  • OutputBus、Target、UserAuxSend0、Effect0:这些属性指向另一对象,并因对象类型而异。比如,Event 和 Sound 便拥有不同的属性。
  • Parent:指向父对象 (parent)。

您可以使用点号将对象和数值结合在一起。比如:

  • $ where parent.name = "Music"
    父对象的名称为 Music。
  • $ where parent.parent.name = "Music"
    祖对象的名称为 Music。
  • $ where parent.volume < 0
    父对象的音量小于零。
  • $ where outputbus.parent.name = "Master Audio Bus"
    输出总线的父对象名称为 Master Audio Bus。
  • $ where effect0.pluginname = "Wwise Compressor"
    插槽 0 处效果器的插件名称为 Wwise Compressor。

设置不同的查询源

目前,我们都是筛选整个工程中的对象。不过有时候需要缩小搜索范围,将目标限定为一组特定的对象。为此,WAQL 还允许将查询源设为:

  • 所有指定类型的对象
  • 工程中的一个或多个特定对象
  • 原有查询对象的结果 (Query Editor)
  • 文本搜索查询的结果

示例如下:

  • $ from type sound
  • $ from type audiofilesource
  • $ from type randomsequencecontainer, switchcontainer, blendcontainer

通过直接在 from 语句中指定类型,我们可以有效地缩小搜索范围。藉此,WAQL 可将迭代限定为指定的源。同时,还可使用 where 关键字为上一查询写入筛选器。不过,执行筛选时必须查询所有工程对象,包括 Event、Bus、Sound 等等。这样的话执行速度会比较慢:

  • $ where type = "randomsequencecontainer" or type = "switchcontainer" or type = "blendcontainer"

尝试使用其他对象类型(参见此处)。

另外,也可从单个对象开始查询:

  • $ from object "\Actor-Mixer Hierarchy\Default Work Unit"
  • $ from object "{1514A4D8-1DA6-412A-A17E-75CA0C2149F3}"
  • $ from object "Event:Play_Footstep_01"7

前述查询还可省略 from object 来简写为以下形式:

  • $ "\Actor-Mixer Hierarchy\Default Work Unit"
  • $ "{1514A4D8-1DA6-412A-A17E-75CA0C2149F3}"
  • $ "Event:Play_Footstep_01"

而且,还可一次指定多个对象:

  • $ "\Actor-Mixer Hierarchy",  "\Interactive Music Hierarchy"
  • $ "{DE2B0843-131F-4E52-BC71-23C43A5324AB}", "{1514A4D8-1DA6-412A-A17E-75CA0C2149F3}"
  • $ "Event:Play_Footstep_01", "Event:Play_Footstep_02", "Event:Play_Footstep_03"

以下是其他一些使用了不同查询源的示例:

  • $ from search "foot walk"
  • $ from search "hello" where type = "sound"
  • $ from query "\Queries\Factory Queries\Audio Source\Audio Source - Format = Vorbis"

选择对象

目前,我们学习了如何使用 from 关键字指定 WAQL 查询的源,以及怎样使用 where 关键字筛选 WAQL 查询。下面我们来看看如何使用 select 关键字进一步转换结果。

通过选择对象,可从初始对象序列获取其他对象。注意,WAQL 查询的每个部分都会为下一部分馈送结果。

在 List View 中键入以下查询:

  • $ from object "\Actor-Mixer Hierarchy\Default Work Unit" select children

此查询会获取 Default Work Unit,并返回其所有的直接子对象 (children)。我们看到,该查询包含了两个部分:from 语句和 select 语句。from 语句定义从哪里开始查询(即查询的源)。select 语句则针对来自源的每一对象执行选择。

以下是其他一些选择了对象层级结构中不同元素的查询:

  • $ "\Actor-Mixer Hierarchy\Default Work Unit" select descendants
    以递归方式返回所有子对象。
  • $ "\Actor-Mixer Hierarchy\Default Work Unit" select parent
    返回直接父对象。
    $ "\Actor-Mixer Hierarchy\Default Work Unit" select parent.parent
    返回直接祖对象。
  • $ "\Actor-Mixer Hierarchy\Default Work Unit" select ancestors
    以递归方式返回所有父对象。
  • $ "\Actor-Mixer Hierarchy\Default Work Unit" select parent, children
    返回父对象及子对象。
  • $ "\Actor-Mixer Hierarchy\Default Work Unit" select this, parent, children
    返回 Default Work Unit 及其父对象和子对象。
  • $ from type sound select parent
    针对所有 Sound 对象返回所有父对象。

select 关键字不仅可以查找父对象和子对象,而且还允许基于属性来选择对象:

  • $ from type sound select effect0
    针对所有 Sound 对象返回索引 0 处添加的所有效果器。
  • $ from type sound select effect0, effect1, effect2, effect3
    针对所有 Sound 对象返回添加的所有效果器。
  • $ from type sound select outputbus
    针对所有 Sound 对象返回 Output Bus 处添加的所有总线。
  • $ from type sound select outputbus.parent
    针对所有 Sound 对象返回 Output Bus 处所添加总线的父对象。

补充练习:

  • 尝试在 select 语句之后添加 where 语句。
  • 尝试在 select 语句之前插入 where 语句。
  • 尝试使用 select referencesto

剖析复杂查询

我们来看看下面的查询,其可枚举 Event 引用的所有 Sound 对象。该查询包含五个联用的语句:

  • $ from type event select children select target select this, descendants where type = "sound"

下面是该查询的各个部分:

  • $ from type event
    首先,枚举工程中的所有 Event。
  • $ from type event select children
    然后,从 Event 对象获取 Event 动作(直接子对象)。
  • $ from type event select children select target
    然后,获取各个动作的目标(引用命名目标)。
  • $ from type event select children select target select this, descendants
    然后,获取目标本身(使用 this 关键字)及其下级对象 (descendant)。
  • $ from type event select children select target select this, descendants where type = "sound"
    最后,仅保留 Sound 对象。

下一步?

这里只是做了一些简单的介绍。WAQL 才刚刚推出,将来会有更多改进。目前,可通过 60 多种对象类型访问和查询超过 450 项不同的属性。而且,我们可以根据需要结合使用各种语句(顺序任意)。除此之外,还有其他一些本文没有提到的关键字。

各位不妨在 List View 中练习使用 WAQL,并通过 Query Editor 将 WAQL 查询保存到工程中。

WAQL_Query

如需进一步了解 WAQL 及其功能,请参阅 WAQL 参考

对于 WAAPI 用户,还可直接在 ak.wwise.core.object.get 函数内使用 WAQL。这样操作起来会更加便捷

欢迎大家分享自己的 WAQL 使用经验!

伯纳德 罗德里格 (Bernard Rodrigue)

伯纳德 罗德里格 (Bernard Rodrigue)

Audiokinetic开发总监Bernard Rodrigue 是 Audiokinetic 的开发总监。他自 2005 年加入 Audiokinetic 后,一直积极参与 Wwise 的基础研发。现在,Bernard 仍在带领团队从事 Wwise 的提升和扩展研发,比如 Interactive Music 等等。

 @decasteljau

评论

留下回复

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

更多文章

SoundSeed Grain 的开发历程

很长时间以来,由于粒子合成器在声音设计上的广泛应用,我们一直都想为 Wwise 开发一款通用的粒子合成器插件。这样就可以利用它生成各种各样的声音,来为游戏设计提供丰富灵活的支持。 我记得几年前曾在...

12.8.2019 - 作者:路易斯-扎维尔·布法尼 (Louis-Xavier Buffoni)

关于局部线性与联动控制在Wwise中的应用探讨

引言...

18.11.2019 - 作者:王润琦

五分钟入门级音轨切换挑战

来一场五分钟入门级音轨切换挑战如何?

7.7.2020 - 作者:乔治.A.桑格 (GEORGE A. SANGER)

Wwise+GME游戏语音方案:解锁更多语音玩法,让玩家“声临其境”

导语:...

4.11.2021 - 作者:腾讯云

Wwise 2023.1 对 WAAPI 的更新

Wwise 2023.1 包含自 2017 年引入 API 以来对 Wwise Authoring API (WAAPI) 最大幅度的更新。如果还没看过 Wwise 2023.1...

1.8.2023 - 作者:伯纳德 罗德里格 (Bernard Rodrigue)

教你如何选择适合自己的编解码器

9.9.2024 - 作者:马修.让(MATHIEU JEAN)

更多文章

SoundSeed Grain 的开发历程

很长时间以来,由于粒子合成器在声音设计上的广泛应用,我们一直都想为 Wwise 开发一款通用的粒子合成器插件。这样就可以利用它生成各种各样的声音,来为游戏设计提供丰富灵活的支持。 我记得几年前曾在...

关于局部线性与联动控制在Wwise中的应用探讨

引言...

五分钟入门级音轨切换挑战

来一场五分钟入门级音轨切换挑战如何?