ReaWwise 有个大家可能不太知道的功能,就是将原始 WAAPI 函数暴露给 REAPER。藉此,用户可在自己的 ReaScript 中使用这些函数。在本文中,我们将探讨如何使用 WAAPI 在 ReaScript Development Environment 中轻松实现一些与 Wwise 相关的基本功能。
前提要求
WAAPI 和 Lua
在阅读接下来的章节之前,建议先对 WAAPI、Lua 和 ReaScript 做一个基本的了解。这里有一些学习资源,感兴趣的话不妨看下:
ReaWwise
要在 ReaScript 内运行 WAAPI 命令,必须安装 ReaWwise。
快速入门
The ReaScript Development Environment
要进入 ReaScript Development Environment,请先打开 REAPER。然后,在 REAPER 菜单中依次选择 Actions > Show action list...。接着,在 Actions 对话框右下角依次单击 New action... > New ReaScript...。这时会提示保存文件。对 ReaScript 文件进行命名,然后单击 Save。在保存之后,便会打开 ReaScript Development Environment。我们将在此编写代码。
Hello World
-- Waapi Hello World.lua
if(reaper.AK_Waapi_Connect("127.0.0.1", 8080)) then
reaper.ShowConsoleMsg("Successfully connected to Wwise!")
reaper.AK_Waapi_Disconnect()
end
在上面的代码段中,我们首先调用 AK_Waapi_Connect。此函数会获取 WAAPI 与 Wwise 通信所用的 IP 和 PORT。它会返回一个布尔值:若连接成功,则返回 true;否则,返回 false。在 if 语句末尾,确保通过调用 AK_Waapi_Disconnect 来终止连接。若脚本运行成功,REAPER console output 窗口会弹出以下消息:
基本示例 (Get Selected Objects)
在以下示例中,我们来看看如何在 Wwise 中查询当前选定的对象。
-- Get Selected Objects.lua
if(reaper.AK_Waapi_Connect("127.0.0.1", 8080)) then
local fieldsToReturn = reaper.AK_AkJson_Array()
reaper.AK_AkJson_Array_Add(fieldsToReturn, reaper.AK_AkVariant_String("path"))
local options = reaper.AK_AkJson_Map()
reaper.AK_AkJson_Map_Set(options, "return", fieldsToReturn)
local result = reaper.AK_Waapi_Call("ak.wwise.ui.getSelectedObjects",
reaper.AK_AkJson_Map(), options)
local status = reaper.AK_AkJson_GetStatus(result)
if(status) then
local objects = reaper.AK_AkJson_Map_Get(result, "objects")
local numObjects = reaper.AK_AkJson_Array_Size(objects)
for i=0, numObjects - 1 do
local item = reaper.AK_AkJson_Array_Get(objects, i)
local path = reaper.AK_AkJson_Map_Get(item, "path")
local pathStr = reaper.AK_AkVariant_GetString(path)
reaper.ShowConsoleMsg(pathStr .. "\n")
end
end
reaper.AK_AkJson_ClearAll()
reaper.AK_Waapi_Disconnect()
end
AkJson
为了方便创建 JSON 对象,ReaWwise 导出了各种辅助函数。藉此,ReaScript 可根据脚本编写者的需求动态创建 JSON 对象。
调用 WAAPI 需要三个元素:参数、选项和命令字符串。在本例中,命名字符串为 ak.wwise.ui.getSelectedObjects。有关 WAAPI 命令的详尽列表,请参阅 WAAPI 参考。
对于这个命令,WAAPI 会将空映射作为参数。在此,我们只需设置 options 映射即可。
我们要创建的 options 映射就跟下面一样:
{
"return": [
"path"
]
}
由于 REAPER 的 Lua 上下文和 ReaWwise 后端之间只能传递值类型和指针,所以需要分多个步骤来创建 options 映射。
首先,创建 fieldsToReturn 数组:
local fieldsToReturn = reaper.AK_AkJson_Array()
fieldsToReturn 变量会返回指向 ReaWwise 后端中数组的指针。利用该指针,我们可以对数组进行操作。
然后,将 path 字符串作为元素添加到 fieldsToReturn:
reaper.AK_AkJson_Array_Add(fieldsToReturn, reaper
.AK_AkVariant_String("path"))
最后,创建 options 映射并将 fieldsToReturn 数组添加为键值为 return 的值:
local options = reaper.AK_AkJson_Map()
reaper.AK_AkJson_Map_Set(options, "return", fieldsToReturn)
调用 WAAPI
在创建全部所需参数后,将其用作调用 WAAPI 时的输入:
local result = reaper.AK_Waapi_Call("ak.wwise.ui.getSelectedObjects",
reaper.AK_AkJson_Map(), options)
然后,便可察看结果以确认对 WAAPI 的调用是否成功。注意,复杂的数据结构无法直接从 ReaWwise 后端传递到 Lua 上下文。在这里,结果变量是一个指针。
我们可以查询 status:
local status = reaper.AK_AkJson_GetStatus(result)
若 status 为 true,就可继续查询调用 WAAPI 时返回的实际数据:
local objects = reaper.AK_AkJson_Map_Get(result, "objects")
local numObjects = reaper.AK_AkJson_Array_Size(objects)
然后,遍历 numObjects 并提取所需的数据:
for i=0, numObjects - 1 do
...
end
每个对象都表示为映射。要访问对象的特定属性,可使用 ReaWwise 后端提供的辅助函数。
要从 objects 数组获取单个对象,需要使用 objects 指针和索引值:
local item = reaper.AK_AkJson_Array_Get(objects, i)
变量 item 是指向映射对象的指针。该对象代表 objects 数组中的单个对象。然后,便可提取 path 变量:
local path = reaper.AK_AkJson_Map_Get(item, "path")
映射和数组值在内部存储为变体对象。要提取最终值,得知道该值代表什么数据。在本例中,我们知道应该获取字符串。为此,使用以下辅助函数从变体数据类型获取字符串:
local pathStr = reaper.AK_AkVariant_GetString(path)
变量 pathStr 是个常规 Lua 字符串,在后续的脚本代码中都可以使用。脚本会直接将 pathStr 输出到 REAPER 控制台。
reaper.ShowConsoleMsg(pathStr .. "\n")
由于 ReaWwise 后端需要追踪整个 Lua 代码中使用的引用类型对象,所以在不再需要这些对象时必须予以清除:
reaper.AK_AkJson_ClearAll()
Advanced Example (Import)
在下一示例中,我们会做一些更复杂的操作。比如,把音频文件从 REAPER 渲染目录传输到 Wwise 中。在此,每个音频文件都将作为 Sound SFX 导入到已在脚本中硬编码的导入目标下。此处要使用的底层 WAAPI 命令为 ak.wwise.core.audio.import。
对于这个示例,我不会详细阐释每行代码的作用,因为有关 API 的大部分概念已经在上一示例中说过了。不过,我会大致介绍一下各段代码的作用。
第 3-13 行:连接到 WAAPI,设置 importDestination,然后得出渲染目录。在此脚本中,我们假定渲染目录与工程文件的父目录相同。
第 15-41 行:构建所有要作为输入传给 AK_Waapi_Call 函数的 AkJson 结构。
第 44-70 行:遍历渲染目录并将遇到的所有 WAV 文件添加到要导入的音频文件列表。
第 74-101 行:执行 AK_WAAPI_Call 函数并在 REAPER 控制台中显示结果。这些代码行还包含在遇到错误时从结果中提取错误信息的逻辑。
结语
在本文中,我们查看了几个直接在 Lua ReaScript 中使用 WAAPI 的示例。从与 Wwise 的基本连接到查询 Wwise,再到导入音频文件等较为复杂的操作。希望此 API 能在工作流程当中给大家带来帮助。同时,期待看到各位在 ReaScript 中灵活运用 WAAPI。
评论