Wwise Authoring Query Language 簡介

“Wwise 不過是張電子表格”。作為用戶體驗團隊成員,我們經(jīng)常會聽到有人這樣說。事實上,Wwise 不僅是款聲音設(shè)計工具,Wwise 工程還保留有大量數(shù)據(jù)。各種各樣的數(shù)據(jù)。如今的現(xiàn)實是,游戲非常地大。要想避免出現(xiàn)問題,最好能自如地操控數(shù)據(jù)。
好在 Wwise 提供有各種用來操控數(shù)據(jù)的工具,如?List View、Multi Editor、Batch Rename?和?Query Editor。

而且還有很多技巧和竅門,來完善 Wwise 工程的組織,以便高效地處理大量數(shù)據(jù)。比如,創(chuàng)建 Work Unit、使用命名規(guī)范、通過制表符分隔文件導(dǎo)入音頻文件、使用自定義屬性、運用批量命名工具、指派顏色等等。
另外,還可借助?Search?和?Query Editor?來查找數(shù)據(jù)。不過,這些工具存在一定的限制。比方說,如何查明工程中都有哪些 Random Container 包含循環(huán)聲音?或者,怎么確定某個 Event 當前引用了哪些音頻源?
幾年前,我們推出了 WAAPI。該編程 API 方便程序員自動處理、操控和查詢 Wwise 工程。不過,WAAPI 需要用到編程語言。一般只有程序員才會使用,其他 Wwise 用戶很難掌握。而且,在運行 WAAPI 腳本之前,要花一些時間來進行設(shè)置。
這里有個用 Python 編寫的 WAAPI 示例,可列出 Event 當前引用的所有轉(zhuǎn)碼后文件??雌饋聿辉趺春枚?/p>
WAQL 簡介

Wwise 2021.1?首次引入了 WAQL,即 Wwise Authoring Query Language。如果是 JIRA 用戶,可能對用來查詢 JIRA 數(shù)據(jù)庫的 JIRA Query Language (JQL) 不陌生。要是程序員,應(yīng)該對 C# LINQ 或 SQL 比較熟。WAQL 跟這些語言有些相似。它允許通過數(shù)據(jù)模型來查詢 Wwise 工程。說白了,就是查詢 Wwise 對象及其屬性。
WAQL 更加方便用戶操控工程內(nèi)的數(shù)據(jù)。這門新語言雖然也需要學(xué)習(xí),但跟掌握整套編程語言(如 Python、Javascript 或 C#)相比,難度要小很多。更重要的是,它可以直接通過 Wwise 設(shè)計工具來訪問。本文旨在幫助大家了解 WAQL 相關(guān)基礎(chǔ)知識。各位不妨一邊閱讀文章,一邊在 Wwise 工程中實踐。本文既是對 WAQL 的簡介,同時也可是一項入門教程。
下面,先從最簡單的操作說起。讓我們來查找工程中所有音量小于零的對象。為此,可打開?List View,然后鍵入 $ where volume < 0。

等等!我們得先弄明白這一切到底是怎么實現(xiàn)的。首先,在 List View 搜索欄中鍵入內(nèi)容時,通常會針對整個工程執(zhí)行文本搜索。不過,現(xiàn)在我們在開頭鍵入了 $。這會告知 Wwise 要啟動 WAQL 查詢而非簡單搜索。
然后,where?關(guān)鍵字指示要編寫條件語句。默認情況下,在使用?where?開始查詢時,會針對工程內(nèi)的所有對象執(zhí)行對應(yīng)條件。最后,我們要編寫條件語句。在本例中,我們要求將音量(Wwise 對象的屬性)與數(shù)值 0 進行對比。該條件會濾掉音量不小于零的對象。
Wwise 對象和屬性

接下來要說到另一個話題:Wwise 對象和屬性。Wwise 對象本質(zhì)上涵蓋了 Project Explorer 中的所有條目,以及不同系統(tǒng)內(nèi)隱藏或顯示的其他一些對象。屬性在對象內(nèi)定義,并且可以存儲數(shù)值。
Wwise 中設(shè)有很多屬性。比如,Property Editor 內(nèi) General Settings 選項卡中 Sound 對象的各項屬性:

屬性可存儲以下任一類型的數(shù)據(jù):
數(shù)值(整數(shù)、實數(shù)、布爾值、字符串)。如 Volume
對工程中另一對象的引用。如 OutputBus. Effect0
本地對象,即 Custom。如 Effect0
有關(guān)各種 Wwise 對象及其屬性的完整列表,請參閱此處(https://www.audiokinetic.com/zh/library/edge/?source=SDK&id=wobjects_index.html)。
另外,大部分對象都有核心屬性。比如,所有 Wwise 對象都有 Name、Notes、Path 和 ID 屬性,而只有特定類型的對象有 Volume 和 Output Bus 屬性。核心屬性有時需要計算,有時與對象存儲在一起。無論對于哪種情況,WAQL 中的屬性名稱都不區(qū)分大小寫。?
有關(guān)核心屬性的詳細信息,請參閱此處(https://www.audiokinetic.com/zh/library/edge/?source=SDK&id=waql_reference.html)。?
快速了解條件

正如前面看到的,where?語句定義有條件。條件會對賦予?where?語句的每一對象進行評估。這些條件由布爾表達式定義;語句的判定結(jié)果可為 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"
等號用于對整個字符串和另一字符串進行不區(qū)分大小寫的比對。若兩個字符串完全相同,則返回 true。$ where notes : "hell"
冒號用于查找字符串內(nèi)某個單詞的開頭。該操作不區(qū)分大小寫。若找到單詞,則返回 true。$ where outputbus = /^Music\d+$/
等號還可與常規(guī)表達式(ECMAScript 樣式)一起使用。
聯(lián)用對象和屬性

Wwise 對象具有兩種類型的屬性:
返回數(shù)值的屬性:
Volume、Pitch、Lowpass?等:通常與 Wwise 中的滑桿關(guān)聯(lián),用于存儲數(shù)字值。這些屬性因?qū)ο箢愋投?。比如,Sound 和 Random Container 便擁有不同的屬性。
Name、Notes、ID、Path:Wwise 對象系統(tǒng)的核心元素,其通常存儲字符串值。所有 Wwise 對象都擁有這些屬性。
返回另一 Wwise 對象的屬性(又稱引用):
OutputBus、Target、UserAuxSend0、Effect0:這些屬性指向另一對象,并因?qū)ο箢愋投悺1热?,Event 和 Sound 便擁有不同的屬性。
Parent:指向父對象 (parent)。
您可以使用點號將對象和數(shù)值結(jié)合在一起。比如:
$?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。
設(shè)置不同的查詢源

目前,我們都是篩選整個工程中的對象。不過有時候需要縮小搜索范圍,將目標限定為一組特定的對象。為此,WAQL 還允許將查詢源設(shè)為:
所有指定類型的對象
工程中的一個或多個特定對象
原有查詢對象的結(jié)果 (Query Editor)
文本搜索查詢的結(jié)果
示例如下:
$?from?type sound
$?from?type audiofilesource
$?from?type randomsequencecontainer, switchcontainer, blendcontainer
通過直接在?from?語句中指定類型,我們可以有效地縮小搜索范圍。藉此,WAQL 可將迭代限定為指定的源。同時,還可使用?where?關(guān)鍵字為上一查詢寫入篩選器。不過,執(zhí)行篩選時必須查詢所有工程對象,包括 Event、Bus、Sound 等等。這樣的話執(zhí)行速度會比較慢:
$ where type = "randomsequencecontainer" or type = "switchcontainer" or type = "blendcontainer"
嘗試使用其他對象類型(參見此處https://www.audiokinetic.com/zh/library/edge/?source=SDK&id=wobjects_index.html)。
另外,也可從單個對象開始查詢:
$?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"
選擇對象

目前,我們學(xué)習(xí)了如何使用?from?關(guān)鍵字指定 WAQL 查詢的源,以及怎樣使用?where?關(guān)鍵字篩選 WAQL 查詢。下面我們來看看如何使用?select?關(guān)鍵字進一步轉(zhuǎn)換結(jié)果。
通過選擇對象,可從初始對象序列獲取其他對象。注意,WAQL 查詢的每個部分都會為下一部分饋送結(jié)果。
在 List View 中鍵入以下查詢:
$?from?object "\Actor-Mixer Hierarchy\Default Work Unit"?select?children
此查詢會獲取 Default Work Unit,并返回其所有的直接子對象 (children)。我們看到,該查詢包含了兩個部分:from?語句和?select?語句。from?語句定義從哪里開始查詢(即查詢的源)。select?語句則針對來自源的每一對象執(zhí)行選擇。
以下是其他一些選擇了對象層級結(jié)構(gòu)中不同元素的查詢:
$ "\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?關(guān)鍵字不僅可以查找父對象和子對象,而且還允許基于屬性來選擇對象:
$ 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 處所添加總線的父對象。
補充練習(xí):
嘗試在?select?語句之后添加?where?語句。
嘗試在?select?語句之前插入?where?語句。
嘗試使用?select referencesto。
剖析復(fù)雜查詢

我們來看看下面的查詢,其可枚舉 Event 引用的所有 Sound 對象。該查詢包含五個聯(lián)用的語句:
$?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 關(guān)鍵字)及其下級對象 (descendant)。$ from type event select children select target select this, descendants?where type = "sound"
最后,僅保留 Sound 對象。
下一步?

這里只是做了一些簡單的介紹。WAQL 才剛剛推出,將來會有更多改進。目前,可通過 60 多種對象類型訪問和查詢超過 450 項不同的屬性。而且,我們可以根據(jù)需要結(jié)合使用各種語句(順序任意)。除此之外,還有其他一些本文沒有提到的關(guān)鍵字。
各位不妨在?List View?中練習(xí)使用 WAQL,并通過?Query Editor?將 WAQL 查詢保存到工程中。

如需進一步了解 WAQL 及其功能,請參閱 WAQL 參考。
對于 WAAPI 用戶,還可直接在 ak.wwise.core.object.get 函數(shù)內(nèi)使用 WAQL。這樣操作起來會更加便捷(https://www.audiokinetic.com/zh/library/edge/?source=SDK&id=ak_wwise_core_object_get.html)。
歡迎大家分享自己的 WAQL 使用經(jīng)驗!
本文作者

伯納德 羅德里格 (BERNARD RODRIGUE)
開發(fā)總監(jiān)
Audiokinetic
Bernard Rodrigue 是 Audiokinetic 的開發(fā)總監(jiān)。他自 2005 年加入 Audiokinetic 后,一直積極參與 Wwise 的基礎(chǔ)研發(fā)?,F(xiàn)在,Bernard 仍在帶領(lǐng)團隊從事 Wwise 的提升和擴展研發(fā),比如 Interactive Music 等等。
