The open architecture of Wwise supports three kinds of plug-ins: source plug-ins, which generate sounds, effect plug-ins, which enhance sounds, and source control plug-ins, which enable the use of source control software within Wwise.
The first two kinds of plug-ins use an XML plug-in description file which allows you to quickly change some of the settings of your plug-in, including default property values, without having to recompile the code. A Wwise plug-in DLL can contain multiple plug-ins, each of which must be described in the associated XML file.
The XML description file for each Wwise plug-in DLL must have the same name as the DLL, except for the XML file extension. For example, if your DLL is named "MyPlugin.dll", then the plug-in description file must be named "MyPlugin.xml".
The XML description file contains information about several aspects of a Wwise plug-in, including:
Below is an example of a simple plug-in XML description file.
<?xml version="1.0" encoding="UTF-8"?> <!-- Copyright (C) 2006 Audiokinetic Inc. --> <PluginModule> <EffectPlugin Name="Wwise Parametric EQ" CompanyID="0" PluginID="105" EngineDllName="EQ"> <PluginInfo> <PlatformSupport> <Platform Name="Windows"> <CanBeInsertOnBusses>true</CanBeInsertOnBusses> <CanBeInsertOnAudioObjects>true</CanBeInsertOnAudioObjects> <CanBeRendered>true</CanBeRendered> <CanBeInsertForFeedback>false</CanBeInsertForFeedback> </Platform> <Platform Name="Mac"> <CanBeInsertOnBusses>true</CanBeInsertOnBusses> <CanBeInsertOnAudioObjects>true</CanBeInsertOnAudioObjects> <CanBeRendered>true</CanBeRendered> <CanBeInsertForFeedback>false</CanBeInsertForFeedback> </Platform> <Platform Name="iOS"> <CanBeInsertOnBusses>true</CanBeInsertOnBusses> <CanBeInsertOnAudioObjects>true</CanBeInsertOnAudioObjects> <CanBeRendered>true</CanBeRendered> <CanBeInsertForFeedback>false</CanBeInsertForFeedback> </Platform> <Platform Name="XboxOne"> <CanBeInsertOnBusses>true</CanBeInsertOnBusses> <CanBeInsertOnAudioObjects>true</CanBeInsertOnAudioObjects> <CanBeRendered>true</CanBeRendered> <CanBeInsertForFeedback>false</CanBeInsertForFeedback> </Platform> <Platform Name="PS4"> <CanBeInsertOnBusses>true</CanBeInsertOnBusses> <CanBeInsertOnAudioObjects>true</CanBeInsertOnAudioObjects> <CanBeRendered>true</CanBeRendered> <CanBeInsertForFeedback>false</CanBeInsertForFeedback> </Platform> </PlatformSupport> </PluginInfo> <Properties> <Property Name="OnOffBand1" Type="bool" SupportRTPCType="Exclusive" ForceRTPCCurveSegmentShape="Constant" DisplayName="Band 1 Enable"> <DefaultValue>true</DefaultValue> <AudioEnginePropertyID>4</AudioEnginePropertyID> </Property> <Property Name="FilterTypeBand1" Type="int32" SupportRTPCType="Exclusive" ForceRTPCCurveSegmentShape="Constant" DisplayName="Band 1 Filter Type"> <DefaultValue>5</DefaultValue> <AudioEnginePropertyID>10</AudioEnginePropertyID> <Restrictions> <ValueRestriction> <Enumeration Type="int32"> <Value DisplayName="Low Pass">0</Value> <Value DisplayName="High Pass">1</Value> <Value DisplayName="Band Pass">2</Value> <Value DisplayName="Notch">3</Value> <Value DisplayName="Low Shelf">4</Value> <Value DisplayName="High Shelf">5</Value> <Value DisplayName="Peaking">6</Value> </Enumeration> </ValueRestriction> </Restrictions> <Dependencies> <PropertyDependency Name="OnOffBand1" Action="Enable"> <Condition> <Enumeration Type="bool"> <Value>1</Value> </Enumeration> </Condition> </PropertyDependency> </Dependencies> </Property> <Property Name="GainBand1" Type="Real32" SupportRTPCType="Exclusive" DataMeaning="Decibels" DisplayName="Band 1 Gain"> <UserInterface Step="0.5" Fine="0.1" Decimals="1" /> <DefaultValue>0</DefaultValue> <AudioEnginePropertyID>1</AudioEnginePropertyID> <Restrictions> <ValueRestriction> <Range Type="Real32"> <Min>-24</Min> <Max>24</Max> </Range> </ValueRestriction> </Restrictions> <Dependencies> <PropertyDependency Name="OnOffBand1" Action="Enable"> <Condition> <Enumeration Type="bool"> <Value>1</Value> </Enumeration> </Condition> </PropertyDependency> </Dependencies> </Property> </Properties> </EffectPlugin> </PluginModule>
Let's look at the various parts of the XML file in detail.
Let's look at the parts of this XML file's header and discuss them in detail.
<?xml version="1.0" encoding="UTF-8"?> <!-- Copyright (C) 2006 Audiokinetic Inc. -->
The first line of any XML file defines the XML version and encoding. In this case, the XML version is 1.0, and the encoding is UTF-8
. The first line of any Wwise plug-in description file should always be exactly like the one above. The second line is an XML comment, in this case a copyright notice. You can introduce comments in various places in the XML file wherever necessary.
<PluginModule> ... </PluginModule>
The main XML element in this document is named PluginModule
, and encloses all of the information for the various plug-ins defined in the file.
<EffectPlugin Name="Wwise Parametric EQ" CompanyID="0" PluginID="105" SupportsIsSendModeEffect="false" EngineDllName="EQ"> ... </EffectPlugin>
The EffectPlugin
element is the main element for the definition of a single effect plug-in, while SourcePlugin
is the element name for source plug-ins.
These elements contain three required attributes:
Name
(mandatory): This string specifies the name of the plug-in as it will appear in Wwise. CompanyID
(mandatory): This string must represent a positive integer that respects the following ranges: PluginID
(mandatory): This string must be a positive integer in the range 0-32767. Each PluginID must be unique for a specified CompanyID. SupportsIsSendModeEffect
(optional): (Effect plug-in only) This boolean value indicates if the plug-in supports the send mode by querying AK::IAkEffectPluginContext::IsSendModeEffect() during the initialization part. When IsSendModeEffect() returns true, the plug-in should not output the dry signal and should ignore the dry level properties. EngineDllName
(optional): This string value indicates which dynamic library to load at game runtime. By default it will be the same name as the XML. Providing a DLL/so file with your plug-in is necessary to be supported in commercial game engines such as Unity and Unreal 4. Note that this is not the same DLL as the one sitting beside the XML, which contains all the Property Pages UI and you don't want to include in a game. For example, if you are developing two source plug-ins and one effect plug-in for in-house use only, you can pick any CompanyID between 64 and 255, and any three PluginIDs between 0 and 32767. The numbers need not be sequential.
|
Caution: If you base your plug-in on a sample plug-in provided by Audiokinetic (Sample Plug-ins), don't forget to change the CompanyID and PluginIDs to something appropriate. Use your assigned official CompanyID if you have one, or a number between 64 and 255 if you don't. Make sure no PluginIDs are repeated for that CompanyID. |
If two or more PluginIDs are identical for the same CompanyID, Wwise will display an error message on startup. If this happens, change the ID for the new plug-in.
|
Caution: You should never change the CompanyID or PluginID of an existing plug-in. Projects using this plug-in will no longer recognize it. The CompanyID and PluginID are persisted with each instance of a source or effect plug-in, and are used to recreate an instance of the right plug-in when the file is loaded. |
The CompanyID and PluginID attributes correspond to the parameters passed to these functions to identify plug-ins:
AkCreatePlugin()
(see Exported Functions)AK::SoundEngine::RegisterPlugin()
|
Note: If more than one plug-in is implemented in the DLL, the XML file will contain multiple EffectPlugin and/or SourcePlugin entries. |
<PlatformSupport> <Platform Name="Windows"> <CanBeInsertOnBusses>true</CanBeInsertOnBusses> <CanBeInsertOnAudioObjects>true</CanBeInsertOnAudioObjects> <CanBeRendered>true</CanBeRendered> <CanBeInsertForFeedback>false</CanBeInsertForFeedback> </Platform> <Platform Name="Mac"> <CanBeInsertOnBusses>true</CanBeInsertOnBusses> <CanBeInsertOnAudioObjects>true</CanBeInsertOnAudioObjects> <CanBeRendered>true</CanBeRendered> <CanBeInsertForFeedback>false</CanBeInsertForFeedback> </Platform> <Platform Name="iOS"> <CanBeInsertOnBusses>true</CanBeInsertOnBusses> <CanBeInsertOnAudioObjects>true</CanBeInsertOnAudioObjects> <CanBeRendered>true</CanBeRendered> <CanBeInsertForFeedback>false</CanBeInsertForFeedback> </Platform> <Platform Name="XboxOne"> <CanBeInsertOnBusses>true</CanBeInsertOnBusses> <CanBeInsertOnAudioObjects>true</CanBeInsertOnAudioObjects> <CanBeRendered>true</CanBeRendered> <CanBeInsertForFeedback>false</CanBeInsertForFeedback> </Platform> <Platform Name="PS4"> <CanBeInsertOnBusses>true</CanBeInsertOnBusses> <CanBeInsertOnAudioObjects>true</CanBeInsertOnAudioObjects> <CanBeRendered>true</CanBeRendered> <CanBeInsertForFeedback>false</CanBeInsertForFeedback> </Platform> </PlatformSupport>
The PluginInfo/PlatformSupport
section defines the platforms supported by your plug-in. It can contain one or more Platform
elements, each of them specifying the various features supported by a plug-in on each platform. The following features can be specified:
CanBeInsertOnBusses
determines whether the effect can be applied to control and master busses. Typically this will require the effect to support surround audio configuration.CanBeInsertOnAuxBusses
determines whether the effect can be applied to control and master auxilliary busses. Typically this will require the effect to support surround audio configuration. Note that if CanBeInsertOnBusses is already set, the effect is already available on Aux busses.CanBeInsertOnAudioObjects
determines whether the effect can be applied as insert to SFX (must support both mono and stereo processing).CanBeRendered
determines whether the effect can be used for offline rendering or not.Your plug-in will be available only on the specified platforms within Wwise.
Each effect or source plug-in can define properties and references. For more information about properties and references, refer to Plug-in Property and Custom Property XML Description.
The InnerTypes
section defines the possible Inner Object Types that you can instantiate and use inside your plug-in. You can define multiple InnerType
inside the InnerTypes
section. Each InnerType
must have a unique name, and plug-in ID. The InnerType
section contains a Properties
section, in which you can define properties in the exact same way you would define plug-in properties.
The Inner Types are practical whenever you need to have multiple instances of an object in your plug-in. For example, you could define the Inner Type Band
for an EQ plug-in, when you have a variable number of EQ bands. Each band would have the same property definition, with different values for each band.
<PluginModule> <EffectPlugin ...> <PluginInfo ...> ... </PluginInfo> <Properties> ... </Properties> <InnerTypes> <InnerType Name="Band" CompanyID="X" PluginID="Y"> <Properties> ... </Properties> </InnerType> </InnerTypes> </EffectPlugin>
|
Note: The properties of Inner Types do not support RTPCs. Therefore, you can't use the SupportRTPCType attribute and AudioEnginePropertyID element. |
|
Note: InnerTypes are only supported inside Source and Effect plug-ins. |
To manipulate the Inner Type instances (Inner Objects) in your plug-in code, you need to use the AK::Wwise::IPluginObjectStore
pointer provided by the framework when AK::Wwise::IAudioPlugin::SetPluginObjectStore() is called at the initialization of your plug-in. The AK::Wwise::IPluginObjectStore
interface provides functions for creating and deleting inner objects. When objects are created, they must be stored in a named list using the insertion and removal functions.
For example, you could create an inner object of type Band
, and store it in the BandList:
// Create a new band AK::Wwise::IPluginPropertySet* pBand = GetObjectStore()->CreateObject( L"Band" ); // Insert the new band in the "BandList" (at the end) GetObjectStore()->InsertObject( L"BandList", (unsigned int)-1, pBand );
|
Note: An inner object can only be stored in a single list. |
See the following topics:
When you add inner objects to the object store, the associated Undo mechanism is automatically created in Wwise. You don't need to implement the undo system on your side. However, to support undo events correctly, you need to update your user interface only at the reception of notifications from the framework. For example, after calling InsertObject
on the IPluginObjectStore
, do not update the UI right-away. Wait for the notification AK::Wwise::IAudioPlugin::NotifyInnerObjectAddedRemoved
to be called on your plug-in. This notification tells you that an object was added or removed from a list. It could come from an action from the user or from the Undo mechanism.
You may also be interested in AK::Wwise::IAudioPlugin::NotifyInnerObjectPropertyChanged
, which is called when the value of a property changes in an inner object.
The persistence in the project work units is automatically handled by Wwise. However, you must implement the serialization of the inner objects in the SoundBanks and for the Sound Engine data. You must serialize the inner objects inside AK::Wwise::IAudioPlugin::GetPluginData
and AK::Wwise::IAudioPlugin::GetBankParameters
.
Refer to the Wwise Source and Effect Plug-in Troubleshooting Guide if you run into any problems.
Questions? Problems? Need more info? Contact us, and we can help!
Visit our Support pageRegister your project and we'll help you get started with no strings attached!
Get started with Wwise