目录

Wwise SDK 2018.1.11
集成详情——环境和游戏定义的辅助发送

简介

Wwise 的 Game-defined Auxiliary Sends(游戏定义的辅助发送)是根据游戏中声音的位置将若干个环境效果器作用于声音的便捷方式。在对象或者其可以继承的上层对象中必须已经设置了选项“Use game-defined auxiliary sends”。

通过使用 Wwise,声音设计师可以定义多个环境来用于游戏中。例如,这些环境可以是:

  • 飞机库
  • 隧道
  • 或游戏中可使用的任何其它环境。

每个环境可代表有不同参数组合的环境混响效果器。然后每个环境将由 Wwise 工程中的 Auxiliary Bus(辅助总线)来表示。

开始时,每个游戏对象应该处于没有定义任何环境的位置上。 当声音不在环境中(未连通到任何辅助总线)时会正常播放。换句话说,声音不带任何环境效果器。

处于同一辅助总线上的所有声音先混合在一起,然后再施加效果器。 各个游戏对象可以设置不同的音量。

Note: API 中采用的值域是 0 到 1,代表最高音量的百分比。0 代表 0,1 代表 100。当多个地方应用音量时,各结果值会相乘。例如,如果 GAME_OBJECT_ID_HUMAN 游戏对象在辅助总线“飞机库”中是 50,而辅助总线“飞机库”衰减了 90,那么此游戏对象发出的声音将以 45(0.50f * 0.90)进入它的效果器。

使用以下函数处理游戏定义的辅助发送:

动态辅助总线通路: 动态发送到辅助总线。

辅助发送和听者游戏对象

Wwise 声音引擎中总线的每个实例都关联了游戏对象。当我们创建辅助发送时,我们就在声音引擎中创建了一条听者与发声体间的关联,辅助发送以一条辅助总线作为目标。发声体和听者游戏对象的位置用在源目标音频节点中,以便空间化声音(如果声音在设计工具中设置为 3D)。当定义辅助发送时,通常最好让目标辅助总线使用与源音频节点的直接输出上指派的相同听者——也就是已通过 SetListeners() or SetDefaultListeners() 指派的听者。方便起见,为了避免需要花力气记住哪个游戏对象已经关联到了哪个听者,我们只要将 AK_INVALID_GAME_OBJECT 作为 listenerID 传递即可。

Note:AkAuxSendValue 结构中填写 listenerID 字段是很重要的。如果没有将其初始化,会导致未定义的行为。

使用 ID 或字符串(Unicode 或 ANSI)

SDK 为您提供两种访问 SoundBank 内项目的方式:一是使用字符串,二是使用 ID。使用字符串可提高代码的可读性,适合在开发期间或者在通常使用字符串的环境中使用。使用 ID 后,Wwise 就无需在运行时散列名称了。

启用 ID

要使用 ID的话,生成 SoundBank 时必须选中 Wwise 中 Generate SoundBanks 对话框上的“Generate header file”选项。名为 Wwise_IDs.h 的定义文件中包含所有必要的 ID。每次生成 SoundBank 时都会更新此文件。

有关在 Wwise 中生成 SoundBank 的详情,请参阅 Wwise 帮助。

使用 ID

Caution: 如果使用了 ID,则要在生成新 SoundBank 时持续更新 .h 文件,这点很重要。否则可能发生 ID 不匹配或编译错误。

以下是 Wwise 生成的一个非常简单的头文件示例:

必须校正代码片段。

/////////////////////////////////////////////////////////////////////////////////////////////////////
//
// Audiokinetic Wwise 已生成 include 文件。请勿编辑。
//
/////////////////////////////////////////////////////////////////////////////////////////////////////
#ifndef __WWISE_IDS_H__
#define __WWISE_IDS_H__
namespace AK
{
namespace EVENTS
{
enum
{
PLAY_ENGINE = 7,
PLAY_FOOTSTEP = 3,
PLAY_HELLO = 6,
PLAY_MARKERS_TEST = 1007392764,
STOP_ENGINE = 8,
};
} // 名字空间 EVENTS
namespace AUX_BUSSES
{
static const AkUniqueID HANGAR_ENV = 2112490296U;
static const AkUniqueID TUNNEL_ENV = 2112490296U;
} // 名字空间 AUX_BUSSES
} // namespace AK
#endif // __WWISE_IDS_H__

除上述内容外,Wwise 生成的头文件通常还包含更多内容。这是因为每个事件、状态、切换开关、总线等都会有条目。

另外还可以综合使用这两种方法。例如,您可以主要使用字符串,但可以运用 ID 来访问环境。

示例:字符串转换(Unicode 版本)

以下方法在运行时把 unicode 字符串转换成 ID。您可以在字符串表中根据环境进行一次性查询,然后使用 ID。

AkAuxBusID AK::SoundEngine::GetIDFromString( const wchar_t * in_pszString );

动态发送到辅助总线。

动态驱动辅助总线通路通过使用 AK::SoundEngine::SetGameObjectAuxSendValues() 函数来完成。 此函数的第一个参数是游戏定义的辅助总线通路所应用到的游戏对象 ID。第二个和第三个参数代表 AkAuxSendValue 类型的结构数组和要发送到的 Auxiliary Bus 的数量。 如果声音没有启用选项“Use game-defined auxiliary sends”,则不会对此游戏对象应用任何环境。对于每条接收游戏对象发送的 Auxiliary Bus,必须设置代表环境作用百分比的控制值。控制值的值域为 0.0f 到 1.0f,其中 0 代表无发送,1 代表 100% 发送。

Note: 在更改对象的辅助发送时,声音引擎会在多个环境间插值以避免出现不连续。如此一来,便可在某一给定帧将对象连接至更多 Auxiliary Bus。

示例:使用 Unicode 字符串设置主人公的环境

将飞机库辅助总线设为 100。

const AkGameObjectID GAME_OBJECT_ID_HUMAN = 200;
#define NUM_ENVIRONMENT 1
AkAuxSendValue aEnv[NUM_ENVIRONMENT];
aEnv[0].listenerID = AK_INVALID_GAME_OBJECT; // 使用通过 SetListeners/SetDefaultListeners API 指派的同样一组听者。
aEnv[0].auxBusID = GetIDFromString( L"Hangar" );
aEnv[0].fControlValue = 1.0f; // 1.0f 代表 100%,控制值值域在 0 到 1之间。
AK::SoundEngine::SetGameObjectAuxSendValues( GAME_OBJECT_ID_HUMAN, aEnv, NUM_ENVIRONMENT );

示例:使用 ID 设置主人公的环境,将飞机库设为 75%,隧道设为 25%。

const AkGameObjectID GAME_OBJECT_ID_HUMAN = 200;
#define NUM_ENVIRONMENT 2
AkAuxSendValue aEnv[NUM_ENVIRONMENT];
aEnv[0].listenerID = AK_INVALID_GAME_OBJECT; // 使用通过 SetListeners/SetDefaultListeners API 指派的同样一组听者。
aEnv[0].auxBusID = AK::AUX_BUSSES::HANGAR_ENV;
aEnv[1].auxBusID = AK::AUX_BUSSES::TUNNEL_ENV;
aEnv[0].fControlValue = 0.75f; // 0.75 代表 75%,控制值值域在 0 到 1 之间。
aEnv[1].fControlValue = 0.25f; // 0.25 代表 25%,控制值值域在 0 到 1 之间。
AK::SoundEngine::SetGameObjectAuxSendValues( GAME_OBJECT_ID_HUMAN, aEnv, NUM_ENVIRONMENT );

通过使用控制值,可以让声音流畅地从一个环境切换到另一个环境。

示例:设置无辅助发送。

const AkGameObjectID GAME_OBJECT_ID_HUMAN = 200;
Tip: 辅助发送的总值不必等于 100。例如,只对游戏对象设置较轻的环境效果时,您可以将游戏对象上在该环境中的值设置为 25。
Caution: Wwise 声音引擎不限制一次可发送到多少条 Auxiliary Bus。这意味着可请求同时处理大量环境效果。某些环境效果器会占用大量 CPU,同时运行太多环境效果器可能会导致性能下降。因此,您应负责防止诸如同时播放 64 个声音(每个都有自己的环境)之类的情况的发生。

示例:将辅助发送指派到备用听者游戏对象来模拟声学门户

在以下示例中,我们注册了一个游戏对象,它是用来在 3D 空间中模拟声学门户的。该游戏对象代表一个其中既没有声音也没有主听者存在的环境。 将 listenerID 字段设置为有效的游戏对象 ID,这样做会以类似 SetListeners() 的方式创建一个发声体-听者关联,但是它是从音频节点应用于辅助输出,而 SetListeners() 是应用于直接输出。发送音频的音频节点是通过在设计工具中设置“Use game-defined auxiliary sends”标志来控制的。设置 listenerID 会创建出游戏对象 listenerIDauxBusID 指定的总线实例,为了可视化该过程,请查看 Wwise 设计工具高级性能分析器(Advanced Profiler)中的声部图。

const AkGameObjectID GAME_OBJECT_ID_HUMAN = 200;
const AkGameObjectID GAME_OBJECT_ID_PORTAL = 201;
#define NUM_ENVIRONMENT 1
AkAuxSendValue aEnv[NUM_ENVIRONMENT];
aEnv[0].listenerID = GAME_OBJECT_ID_PORTAL; // 该辅助发送的目标游戏对象 ID。
aEnv[0].auxBusID = AK::AUX_BUSSES::TUNNEL_ENV_PORTAL; // 该辅助发送的目标辅助总线 ID。
aEnv[0].fControlValue = 1.0f;
AK::SoundEngine::SetGameObjectAuxSendValues( GAME_OBJECT_ID_HUMAN, aEnv, NUM_ENVIRONMENT );

在该示例中,AK::AUX_BUSSES::TUNNEL_ENV_PORTAL 辅助总线应在 Wwise 设计工具中设置为“Enable Positioning(启用定位)”并且定位类型设置为 3D,以便让它在 3D 模拟中依然能够发出声音。

设置主输出电平(或者干声级别)

除更改游戏对象所属的 Auxiliary Bus 外,您还可以使用 AK::SoundEngine::SetGameObjectOutputBusVolume() 函数来减少其干声成分。此函数可用来模拟声障。 每个游戏对象初始都有一个设为 100% (1.0f) 的干声级别(除非声音对象属性中另有明确指定)。

示例:设置主人公声音主输出电平为 45%

const AkGameObjectID GAME_OBJECT_ID_HUMAN = 200;
// 针对所有关联听者将主角声音的干声电平设为 45%。
Tip: 模拟一个由于听者距离太远而只能听到混响的声音的方法是,将干声级别设为 0。

设置辅助总线音量

辅助总线输出端音量与其它所有总线音量一样,都可使用设计工具中的音量滑块、状态、RTPC 等来驱动。

参见