Wwise 版本
Wwise SDK 2018.1.11
集成二路输出

在 Wwise 中,二路输出(Secondary Output)指定常规 TV 音频输出之外的任何物理音频终端。最常见的二路输出是游戏控制器扬声器和耳机。二路输出功能可用于为各个输出定义独立的混音,而主扬声器/TV 混音不受影响。适用于常规混音的Wwise 功能集对二路输出也同样适用,除输出对象是控制器而非扬声器/TV 外,无其它特殊限制。

总线通路

在设计端,需要创建新的主总线,以便为 Audio Device 定义不同的混音。然后,更改应用于新总线的 Audio Device ShareSet 属性,使其指向不同的设备。注意,若要使用第三方创建的 Audio Device 插件,则可能需要先创建对应插件类型的 Audio Device ShareSet。然后,才能将声音正常输出至新总线或其子总线。有关 Wwise 所支持 Audio Device 的信息,请参阅内置音频设备

对于仅与一个二路输出绑定的声音,最好直接设置 Output Bus。这样的声音例子有:玩家发起的枪击、网球拍重击、PDA 音效、游戏反馈等。不过,您可以将 User Send 或 Game Send 应用于其他总线层级结构内的 Auxiliary Bus。若要将同一声音同时发送至多个输出和 TV(比如使用间谍相机或广播),则最好采用这一方法。

使用同一声源可在多个控制器和 TV 上同时播放同一声音。在设计方面,无需知道有多少玩家可能在玩此游戏。此总线层级结构将用作模版在为游戏中注册的各个输出布线时使用。因此各个输出上可能会施加不同的混音和效果,具体取决于播放的声源、游戏对象上活跃的 RTPC 和 Swtich(切换开关)值。请参见下面示例部分中有关这方面的示例。

关于输出同步的说明

在许多设备(例如 TV 和游戏控制器)上输出同一音频时,您也许会发现设备之间存在延迟。这是声音信号路径的硬件差异造成的,因此无法避免。在控制器方面,此信号可能必须通过无线信道传输,无线信道造成的延迟可能不同于有线控制器。对于 TV,信号离开主机后,将进入接收器或 TV,其处理器会造成一定程度的延时。由于各个系统的 AV 设置造成的延时各有不同,因此对分别传输到扬声器/TV 和游戏控制器的声音而言,无法保证两者之间的同步。在设计声音时,可能需要考虑这一限制。

为多个输出设置设备、听者和游戏对象

若存在多个相同类型的输出(如游戏控制器扬声器),则必须对各个设备加以区分。之所以使用 Listener/GameObject 这一常规概念,是因为方便实现特定的听者/发声体通路。请参阅 概念: Listener 了解更多信息。游戏程序员要负责使用 AK::SoundEngine::AddOutput 将输出设备与听者关联起来。程序员必须使用 AK::SoundEngine::SetActiveListeners 来设置听者和游戏对象之间的关系。记住,若希望多个设备同时播放此声音,则可指定多个听者。

Note: 假如只有某一特定类型的输出(如 System、DVR),则无需设置多个听者。此时,Wwise 可使用工程中指定的通路。若为单人游戏,则对玩家专用输出(如 Game Controller Speaker 和 Communication)来说也是如此。也就是说,游戏中将只有一个激活的控制器。有关听者的详细信息,请参阅“ 集成 Listener ”。
Note: 在确定玩家与设备的关系时,只要系统连接或断开游戏控制器,游戏代码就要负责调用 AK::SoundEngine::AddOutputAK::SoundEngine::RemoveOutput。Wwise 可自动识别设备与听者之间的关系,从而确定玩家与设备的关系。系统设备(如主输出和 DVR)将由 Wwise 自动处理。

示例

以下示例专为 PS4 编写,但可应用于所有其他平台。请检查 AK::SoundEngine::AddOutput 函数的文档。如需查看多输出管理的工作示例,请参阅“soundengine_integration_samplecode”中的 DemoMotion 页面(多人设置)和 BGMDemo 页面(DVR/BGM 管理)。

Note: 为了方便阅读,这些示例省略了函数调用之前所需的 AK::SoundEngine

获取 UserID 的代码(仅限于 PS4):

SceUserServiceLoginUserIdList list;
sceUserServiceGetLoginUserIdList(&list);

一个游戏控制器输出上的声音:

// 添加二路输出,连接至扬声器终端,用于玩家 0。
AkOutputSettings outputSettings("Game Controller Speaker", list.userId[0] /*Player ID (first player)*/);
AddOutput(outputSettings);
// 播放一个事件。在 Wwise 工程中,必须将此声音连通至某条主总线,该总线的输出设备要设为“Game Controller Speaker”(或其子设备总线)。
PostEvent("Play_Pow", MY_GAME_OBJECT);

在两个不同控制器上播放同一声音:

// 添加二路输出,连接至扬声器输出,用于玩家 0,与听者 #1 关联。
AkOutputSettings outputSettings1("Game Controller Speaker", list.userId[0] /*Player ID (first player)*/);
AddOutput(outputSettings1, NULL, listenerArray1, 1);
// 添加二路输出,连接至扬声器输出,用于玩家 1,与听者 #2 关联。。
AkOutputSettings outputSettings2("Game Controller Speaker", list.userId[1] /*Player ID (first player)*/);
AddOutput(outputSettings2, NULL, listenerArray2, 1);
// 设置将声音发送给听者 1(玩家 0)和 2(玩家 1)的游戏对象。
SetActiveListeners(EXISTING_GAME_OBJECT, listenerArrayBoth, 2);
// 播放一个事件。在 Wwise 工程中,必须将此声音连通至某条主总线,该总线的输出设备要设为“Game Controller Speaker”(或其子设备总线)。
PostEvent("Play_Pow", EXISTING_GAME_OBJECT);

在两个不同控制器上播放不同声音:

// 添加二路输出,连接至扬声器输出,用于玩家 0,与听者 #1 关联。
AkOutputSettings outputSettings1("Game Controller Speaker", list.userId[0] /*Player ID (first player)*/);
AddOutput(outputSettings1, NULL, listenerArray1, 1);
AkOutputSettings outputSettings2("Game Controller Speaker", list.userId[1] /*Player ID (first player)*/);
AddOutput(outputSettings2, NULL, listenerArray2, 1);
// 设置将声音发送到相应听者的游戏对象
RegisterGameObj(MY_GAME_OBJECT1, listenerArray1, 1);
SetActiveListeners(MY_GAME_OBJECT1, listenerArray1, 1);
RegisterGameObj(MY_GAME_OBJECT2, listenerArray2, 1);
SetActiveListeners(MY_GAME_OBJECT2, listenerArray2, 1);
// 播放一个事件。在 Wwise 工程中,必须将此声音连通至某条主总线,该总线的输出设备要设为“Game Controller Speaker”(或其子设备总线)。
PostEvent("Play_Pow", MY_GAME_OBJECT1);
PostEvent("Play_Pif", MY_GAME_OBJECT2);

在游戏控制器输出和 TV 上播放同一声音:

// 添加二路输出,连接至扬声器输出,用于玩家 0,与听者 #1 关联。
AkOutputSettings outputSettings1("Game Controller Speaker", list.userId[0] /*Player ID (first player)*/);
AddOutput(outputSettings1, NULL, listenerArray1, 1);
// 设置将声音发送到听者 0(TV)和 1(对于玩家 0,发送到控制器)的游戏对象。
AkGameObjectID [] listenerArrayWithDefault = {MY_MAIN_LISTENER, MY_LISTENER1}; // 通常,会将 MY_MAIN_LISTENER 用作听者(具体由 AK::SoundEngine::SetDefaultListeners 定义)。
RegisterGameObj(MY_GAME_OBJECT);
SetActiveListeners(MY_GAME_OBJECT, listenerArrayWithDefault, 2);
// 播放一个事件。
// 在 Wwise 工程中,必须将此声音连通至某条主总线,该总线的输出设备要设为“Game Controller Speaker”(或其子设备总线)。
// 同时,还要将该声音的 Auxiliary Send 连至 Master Audio Bus。
PostEvent("Play_Pow", MY_GAME_OBJECT);

以下例子阐述了如何在 Windows 上添加二路输出(即耳机):

Note: 在 Windows 上,所有设备均为 System 设备。之所以添加设备,是为了区分这些设备(详见“ 为多个输出设置设备、听者和游戏对象 ”)。添加二路输出,连接至之前所发现设备,与听者 #1 关联。所以,我们需要不同的听者。
// 将搜索名称中包含 Headphones 的设备。
uDeviceID = AK::GetDeviceIDFromName("Headphones");
// 添加二路输出,连接至之前所发现设备,与听者 #1 关联。
AkOutputSettings outputSettings1("System", uDeviceID);
AddOutput(uoutputSettings1, NULL, listenerArray1, 1);
// 注册仅与 listener1 关联的游戏对象。
RegisterGameObj(MY_GAME_OBJECT, listenerArray1, 1);
// 播放一个事件。在 Wwise 工程中,必须将此声音连通至某条主总线,该总线的输出设备要设为“System”(或其子设备总线)。
PostEvent("Play_Pow", MY_GAME_OBJECT);
参见