Version

menu_open
Warning : Some protected information on this page is not displayed.
Ensure you are logged in if you are a licensed user for specific platforms.
Wwise SDK 2022.1.17
Integrating Secondary Outputs

In Wwise, a secondary output designates any physical audio end-point that is not the regular TV audio output. The most common secondary outputs are headsets, game controller speakers, and haptic feedback for game controllers. Haptic feedback integration is described in detail in Integrating Wwise Motion. This topic focuses on audio outputs (headsets and controller speakers).

You can use secondary outputs to define separate mixes for each of these outputs without affecting the main speaker/TV mix. The same Wwise feature set applies to the secondary outputs as for the regular mix. The only difference is that the output targets controllers instead of the speaker/TV.

Bus Routing

On the authoring side, you need to create new master busses to be able to define a different mix for an Audio Device. Then change the Audio Device ShareSet property on that new bus to point to a different device. Note that if you want to use an Audio Device plug-in created by a third party, you might need to create an Audio Device ShareSet of the right plug-in type first. Then the sounds can be routed normally to the new bus or any child bus. See Audio Devices for information on which Audio Device is available with Wwise.

Setting the Output Bus directly is the preferred method for sounds that are normally tied to only one secondary output instance. For example, player-initiated gunshots, tennis racket whacks, PDA sounds, gameplay feedback, and so on. However, you can use a User or Game Send to an Auxiliary Bus inside any other bus hierarchy. This is the preferred method if the same sound is going to be heard in multiple outputs and the TV at the same time, such as with a spy camera or announcements.

It is possible to play the same sound on multiple controllers and on TV at the same time, using the same source. On the design side, there is no knowledge of how many players might be playing the game. The bus hierarchy will be used as a template for routing for each output registered from the game. So, each output may have a different mix and Effect applied, depending on the sources played, as well as RTPC and Switch values active on the game objects. See an example of this in the Examples section below.

A note on synchronization of outputs

When outputting the same audio on many devices, such as the TV and a game controller, you will probably notice latency between the devices. This is unavoidable due to different hardware in the audio signal's path. On the controller side, the signal may have to travel through a wireless channel, which might give a different delay than for wired controllers. For the TV, once the signal is out of the console, it goes through a receiver and/or a TV, whose processors add a certain amount of delay. Since the delay produced by the AV setup is different for each system, it's not possible to synchronize sounds routed simultaneously to the speaker/TV and the game controllers. Your sound design may need to take this constraint into consideration.

Setting up devices, listeners and game objects for multiple outputs

In the case of multiple outputs of the same type (think, for example, a game controller speaker), it is necessary to discriminate between each instance of the devices. The regular Listener/GameObject concept is used because it also allows specific listener/emitter routing. See Concept: Listeners for more information. It is the responsibility of the game programmer to associate the output device with a Listener using AK::SoundEngine::AddOutput. The programmer must set the association between the listeners and game objects using AK::SoundEngine::SetActiveListeners. Don't forget, you can specify multiple listeners if multiple devices should play this sound at the same time (see example below).

Note: It is not necessary to have multiple listeners if there is only one output of a particular type (such as System, DVR). In this case, Wwise can rely on the routing specified in the Wwise project. This is also true for player-specific outputs (such as Game Controller Speaker and Communication) if the game is single-player. In other words, if there will only be one controller active in the game. Read more about listeners in Integrating Listeners.
Note: In the case of player-devices, the game code is responsible for calling AK::SoundEngine::AddOutput and AK::SoundEngine::RemoveOutput whenever a game controller is connected or disconnected from the system. Wwise can't know automatically which device to associated to which listener and, conceptually, which player. System devices (such as main output and DVR) are handled automatically by Wwise.

Examples

These examples are written for the PS4, but can apply to all other platforms. Please check the documentation for the function AK::SoundEngine::AddOutput. You can find a working example of multiple output management in the Integration Demo Sample, in the DemoMotion page (multi-player), and in the BGMDemo page (DVR/BGM management).

Note: These examples omitted the required AK::SoundEngine before the function calls, just to make it easier to read.

Code to get the UserIDs (PS4 only):

Sound on one game controller output:

Same sound on two different controllers:

Different sounds on two different controllers:

Same sound on one game controller output and on the TV:

Here's an example of adding a secondary output on Windows, namely the headphones:

Note: On Windows, all devices are "System" devices. Therefore, adding a device means it is necessary to discriminate between them (see Setting up devices, listeners and game objects for multiple outputs for information). Consequently, we need a different listener.
AkUInt64 AkGameObjectID
Game object ID.
Definition: AkTypes.h:128
AKRESULT
Standard function call result.
Definition: AkTypes.h:199
AKSOUNDENGINE_API AKRESULT RegisterGameObj(AkGameObjectID in_gameObjectID)
AKSOUNDENGINE_API AkUInt32 GetDeviceID(IMMDevice *in_pDevice)
Platform-independent initialization settings of output devices.
#define NULL
Definition: AkTypes.h:46
AkUInt32 AkUniqueID
Unique 32-bit ID.
Definition: AkTypes.h:120
AKSOUNDENGINE_API AKRESULT AddOutput(const AkOutputSettings &in_Settings, AkOutputDeviceID *out_pDeviceID=NULL, const AkGameObjectID *in_pListenerIDs=NULL, AkUInt32 in_uNumListeners=0)
AKSOUNDENGINE_API AkUInt32 GetDeviceIDFromName(wchar_t *in_szToken)
AkForceInline void SetStandard(AkUInt32 in_uChannelMask)
Set channel config as a standard configuration specified with given channel mask.
AkUniqueID audioDeviceShareset
AkChannelConfig channelConfig
AkUInt64 AkOutputDeviceID
Audio Output device ID.
Definition: AkTypes.h:153
#define AK_SPEAKER_SETUP_STEREO
2.0 setup channel mask
AKSOUNDENGINE_API AkPlayingID PostEvent(AkUniqueID in_eventID, AkGameObjectID in_gameObjectID, AkUInt32 in_uFlags=0, AkCallbackFunc in_pfnCallback=NULL, void *in_pCookie=NULL, AkUInt32 in_cExternals=0, AkExternalSourceInfo *in_pExternalSources=NULL, AkPlayingID in_PlayingID=AK_INVALID_PLAYING_ID)

Was this page helpful?

Need Support?

Questions? Problems? Need more info? Contact us, and we can help!

Visit our Support page

Tell us about your project. We're here to help.

Register your project and we'll help you get started with no strings attached!

Get started with Wwise