Version

menu_open
Wwise SDK 2021.1.14
Creating Audio Device (Sink) Plug-ins

Audio Device Plug-in Interface Implementation

Audio device plug-ins are the endpoints of the audio processing chain. Natural Audio devices are the OS sound systems, but there can be more possible outputs if additional hardware or drivers allow it. The role of the sink plug-in is to take the final mixed audio samples and transfer them to the device, in the format the device understands.

Sound Engine Component

On the sound engine side, writing an audio device plug-in consists of implementing the AK::IAkSinkPlugin interface. Only the functions specific to this interface are covered there. Refer to Creating Sound Engine Plug-ins for information about interface components shared with other plug-in types ( AK::IAkPlugin interface). Also refer to the provided AkSink plug-in for sample code (Samples).

An audio device is always specified through the plug-in it is using (Audio Device ShareSet) and a specific device ID. This device ID has no meaning for the Wwise sound engine, it is for the sole purpose of the plug-in implementor to discriminate devices where many of the same type exists. It is passed by the game through the AkOutputSettings::idDevice parameter used in AK::SoundEngine::Init and AK::SoundEngine::AddOutput. For example, an audio device plug-in which would access Windows' audio devices could probably see many Windows' devices on a particular computer.

If your device doesn't need to discriminate between multiple devices, you can ignore that parameter. However, if you need to implement this, be aware that you MUST also support the "default device" concept, which is selected when the idDevice parameter is 0. Whether the first available device or a specific device is selected when receiving 0 is up to the plug-in programmer.

Sink plug-ins can register an extra static function to support enumeration of available audio devices. The purpose of this function is to fill the possible devices a user can select in the authoring tool as well as to allow device enumeration at run-time through calls to AK::SoundEngine::GetDeviceList. This function is optional. If not implemented, it is expected that the plug-in will initialize to a "default" output when required. If necessary, the additional static function should be provided after the plug-in parameter creation function. For more information on other static functions to provide for plug-in creation, see Creating Sound Engine Plug-ins.

Below is an example implementation of device enumeration for a fictitious sink plug-in, MyPlugin. Note that functions and classes in the MyPlugin namespace are placeholders for actual plug-in implementations.

The plug-in device enumeration will be called by Wwise with the maximum number of devices to fill and a pre-allocated array of AkDeviceDescription. The maximum length of the device name is AK_MAX_PATH (256 characters). You must modify the count (io_maxNumDevices) to reflect the number of device descriptions correctly filled. If the provided device description array pointer is null, the count should still be modified to reflect the number of device descriptions that would be filled, so that the caller can allocate an appropriate amount of memory for out_deviceDescriptions.

// ...
AKRESULT GetMyPluginDeviceList(AkUInt32& io_maxNumDevices, AkDeviceDescription* out_deviceDescriptions)
{
// For example, fetch the available devices
const AkUInt32 deviceCount = MyPlugin::GetNumberOfDevices();
const MyPlugin::Device* devices = MyPlugin::GetDevices();
// Handle device count requests:
// If out_deviceDescriptions is NULL, io_maxNumDevices should be set to the device count
// so the caller can determine how much memory to reserve.
if (out_deviceDescriptions == NULL)
{
io_maxNumDevices = deviceCount;
return AK_Success;
}
// else, fill out_deviceDescriptions
// until all available devices are filled (i == deviceCount)
// or the end of the array is reached (i == io_maxNumDevices)
int i = 0;
for (; i < deviceCount && i < io_maxNumDevices; ++i)
{
AKPLATFORM::SafeStrCpy(out_deviceDescriptions[i].deviceName, device[i]->deviceName, AK_MAX_PATH);
out_deviceDescriptions[i].idDevice = devices[i].idDevice;
out_deviceDescriptions[i].deviceStateMask = devices[i].deviceStateMask;
out_deviceDescriptions[i].isDefaultDevice = devices[i].isDefaultDevice;
}
// Set the number of devices written into the array
io_maxNumDevices = i;
return AK_Success;
}
//Static initializer object to automatically register the plug-in in the sound engine.
AK::PluginRegistration MyPluginRegistration(AkPluginTypeEffect, AKCOMPANYID_MYCOMPANY, EFFECTID_MYPLUGIN, CreateMyPlugin, CreateMyPluginParams, GetMyPluginDeviceList);
Note: This sound engine implementation replaces the previous authoring only plug-in equivalent AkGetSinkPluginDevices so that device enumeration can be implemented for all supported platforms and can be called at run-time through AK::SoundEngine::GetDeviceList.
Note: This function will be compiled on all platforms. To handle platform specific device enumeration, one should use the appropriate macros (e.g. AK_WIN, AK_LINUX, etc.) and return AK_NotImplemented on platforms for which no implementation is defined.

Authoring DLL for an Audio Device Plug-in

As with any other plug-in, sink plug-ins need an authoring DLL counterpart. Please refer to Authoring Plug-in Library Format for the basic setup of the Wwise authoring component common to all plug-ins.

Note: AkGetSinkPluginDevices is now deprecated, see the Sound Engine Component section above to implement device enumeration.

Testing your Audio Device Plug-in

After implementing the Wwise part of the plug-in (Writing the Authoring Part of an Audio Plug-in) and the sound engine part, you can test your plug-in following these steps:

  • In your Wwise Project, create an Audio Device ShareSet using your new plug-in. Give the ShareSet a unique name.
  • Generate you banks.
  • Make sure your plug-in was registered in your game code. See Sound Engine Plug-ins Overview.
  • Specify your audio device ID to be used in the initialization parameters of the sound engine. The ID in the AkOutputSettings is the hash of the name of the Audio Device ShareSet in the project, as given by AK::SoundEngine::GetIDFromString.

For example:

AkInitSettings initSettings;
AkPlatformInitSettings platformInitSettings;
initSettings.settingsMainOutput.audioDeviceShareset = AK::SoundEngine::GetIDFromString("YourNewAudioDeviceSharesetNameHere");
AK::SoundEngine::Init( &initSettings, &platformInitSettings );

Alternatively, you can use your Audio Device plug-in with AK::SoundEngine::AddOutput.

AkOutputSettings outputSettings("YourNewAudioDeviceSharesetNameHere", 0 /*Default device*/)'
AK::SoundEngine::AddOutput(outputSettings);

You can test device enumeration for your plug-in with AK::SoungEngine::GetDeviceList.

const int maxNbDevices = 20;
AkDeviceDescription devices[maxNbDevices];
AkUInt32 deviceCount = maxNbDevices;
AK::SoundEngine::GetIDFromString("YourNewAudioDeviceSharesetNameHere"),
deviceCount,
devices
);

For more information, refer to the following sections:

AkOutputSettings settingsMainOutput
Main output device settings.
Definition: AkSoundEngine.h:216
AkAudioDeviceState deviceStateMask
Bitmask used to filter the device based on their state.
Definition: AkTypes.h:232
AKSOUNDENGINE_API AKRESULT Init(AkInitSettings *in_pSettings, AkPlatformInitSettings *in_pPlatformSettings)
#define AK_MAX_PATH
Maximum path length.
Definition: AkTypes.h:88
bool isDefaultDevice
Identify default device. Always false when not supported.
Definition: AkTypes.h:233
AKRESULT
Standard function call result.
Definition: AkTypes.h:132
Platform-independent initialization settings of output devices.
Definition: AkSoundEngine.h:129
#define NULL
Definition: AkTypes.h:47
@ AK_Success
The operation was successful.
Definition: AkTypes.h:134
AKSOUNDENGINE_API void GetDefaultInitSettings(AkInitSettings &out_settings)
@ AkPluginTypeEffect
Effect plug-in: applies processing to audio data.
Definition: AkTypes.h:848
AKSOUNDENGINE_API void GetDefaultPlatformInitSettings(AkPlatformInitSettings &out_platformSettings)
AkForceInline void SafeStrCpy(wchar_t *in_pDest, const wchar_t *in_pSrc, size_t in_uDestMaxNumChars)
Safe unicode string copy.
Definition: AkPlatformFuncs.h:477
AKSOUNDENGINE_API AkUInt32 GetIDFromString(const char *in_pszString)
AkUniqueID audioDeviceShareset
Definition: AkSoundEngine.h:142
uint32_t AkUInt32
Unsigned 32-bit integer.
Definition: AkTypes.h:59
AKSOUNDENGINE_API AKRESULT GetDeviceList(AkUInt32 in_ulCompanyID, AkUInt32 in_ulPluginID, AkUInt32 &io_maxNumDevices, AkDeviceDescription *out_deviceDescriptions)
AkUInt32 idDevice
Device ID for Wwise. This is the same as what is returned from AK::GetDeviceID and AK::GetDeviceIDFro...
Definition: AkTypes.h:230

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