Table of Contents
Wwise SDK 2019.1.7
Two types of banks exist for every project: the Initialization bank and SoundBanks.
There is only one Initialization bank for each project. It is automatically created when Wwise generates the SoundBanks and is named "Init.bnk". This special bank contains general project information, including:
- Bus hierarchy
- Bus Effects
The Initialization bank is language-independent, so only one is generated for all languages.
The Initialization bank must be the first bank loaded when starting a game. If it is not loaded first, the SoundBanks may not load. The Initialization bank cannot be unloaded if any other SoundBank is still loaded. The initialization bank is loaded in the same way as the SoundBanks.
|Note: Loading the initialization bank for a project that uses source, effect, or codec plug-ins will fail if these plug-ins have not been previously registered with the sound engine. Refer to Integration Details - Plug-Ins and Integrating Codec Plug-Ins for information concerning plug-in registration.|
Each SoundBank may contain:
- Event definitions
- Sound structure information (sound, container, music object, Actor-Mixer, and so on)
- Sound data (for in-memory sounds)
- Prefetched sound data (for zero-latency streamed sounds)
- References to streamed audio files (file ID)
After the Initialization bank has been loaded, SoundBanks can be loaded and unloaded anytime during the game. It is your responsibility to ensure that the bank containing an event is loaded before the event is triggered. If an event is posted before its corresponding bank is loaded, the event will not execute.
|Caution: SoundBanks require information that is stored in the initialization bank. Therefore, your game must use an initialization bank and SoundBanks that are generated from the same Wwise project.|
The SDK provides two ways of accessing items inside a bank: using strings or using IDs. There are a few things that you should consider before deciding which option to use in your game, including:
- The importance of having reader-friendly code
- The use of strings in other areas of your development environment
- CPU usage
- Memory usage
- Makes code more readable, which makes it suitable for development.
- Appropriate for development environments that normally use strings.
- A small amount of CPU is required to convert strings to the IDs used by sound engine. However, most games will not notice the difference in CPU usage unless thousands of stings are converted per game frame.
- Strings are not stored in the sound engine, so if the strings are already used in the game engine, then no additional memory will be used. If, however, the game doesn't use strings, then some memory will be used on the game side to store the strings before they are converted.
- Code is less readable, which makes it more difficult to troubleshoot problems during development.
- Doesn't require any additional CPU usage because the sound engine uses IDs internally.
- Doesn't require any additional memory.
In most cases, you can get away with using strings; but, if your game is very squeezed in terms of memory and CPU, you might want to consider using IDs.
The IDs of all Wwise objects that are available to the game (banks, events, game syncs, and so on) are computed by hashing their lowered-case name into a 32-bit integer.
|Tip: In Wwise, selecting the "Generate SoundBank content files" option on the SoundBanks tab of the Project Settings dialog box will create a corresponding text file for each bank, which enumerates the names and IDs of all the objects that it contains. Refer to the Wwise Help for a description of the SoundBank Project Settings.|
AK::SoundEngine::GetIDFromString() performs run-time conversion of a string into an ID. It is case-insensitive; the input string is converted to lowercase, then the hashing function is applied.
Let's say that you want to post an Event that is identified by its name. You can use the overload of
AK::SoundEngine::PostEvent() that has a string as its first argument.
Note: The sound engine internally converts the Unicode string to an ID, and then calls the overload of
To work directly with IDs, without having to convert the strings into IDs at run-time, the banks should be generated with the "Generate header file" option selected. This option is located on the SoundBanks tab of the Project Settings dialog box in Wwise. The header file, named Wwise_IDs.h, contains all the required IDs and needs to be included in your game. It is updated each time the banks are generated.
For more information on generating banks in Wwise, refer to the Wwise Help.
Here is an example of a very simple header file generated by Wwise:
Header files generated by Wwise usually contain much more information than the one above, because entries are added for every bank, Event, State, Switch, and so on.
|Caution: When working with IDs, it is important to keep the .h file up-to-date when new banks are generated. Otherwise, ID mismatches and/or compilation errors may occur.|
Let's say you want to post an Event by using its ID. The generated header file "Wwise_IDs.h" must be included. Simply use the
PostEvent() overload that uses an ID as its first argument.
Like all other Wwise objects in the game, banks are identified by IDs that are generated by hashing their name. Loading and unloading banks always involves access to an I/O device at some point.
One of the
AK::SoundEngine::LoadBank() overloads uses a pointer and a size. It should be used when you want to perform I/O on your side, and then just tell the sound engine that you want it to prepare its content. The pointer must be valid until the bank is unloaded.
The bank ID is stored in banks. The memory overload of
AK::SoundEngine::LoadBank() parses it and returns it to you. You must keep it in order to unload the bank (using the ID overload of
The Wwise sound engine never accesses I/O directly. All its requests for I/O are executed through the Stream Manager, whose interface is defined as
AK::IAkStreamMgr (see Streaming / Stream Manager). This module can be overridden, but Audiokinetic's default implementation further defines an abstraction for low-level access to I/O transfers and file system, and the Low-Level IO module, whose interface is defined as
AK::IAkLowLevelIO and is specific to Audiokinetic's implementation of
AK::IAkStreamMgr. A default implementation of the Low-Level IO is provided, but it is meant to be replaced by your own, especially to resolve file location (see Low-Level I/O).
The Stream Manager and Low-Level IO define 2 overloads to open files, one by string, and another by ID. Similarly, the sound engine API provides overloads of
LoadBank() that use strings, or IDs. The version of
AK::IAkLowLevelIO::Open() that ends up being called by the sound engine depends on which overload of
LoadBank() was used by the game. It also depends on whether the SoundBanks were generated with the "Use SoundBank names" option that is located on the SoundBanks tab of the Project Settings dialog box. Refer to the Wwise Help for a description of the SoundBank Project Settings.
One of the settings available in Wwise for generating SoundBanks is the "Use SoundBank names" option. It affects how banks are loaded in the sound engine, regarding I/O and file system.
Warning: When using the default implementation of the Low-Level IO provided in the SDK (
However, when using the file package-based Low-Level IO (
When the option is not selected, Wwise generates bank files with names that have the following format:
where "ID" is a numeric, 32-bit ID generated by hashing the bank's name (see
In this mode, banks refer to other banks internally using their IDs (their names are not stored in the banks that reference them). Therefore, all calls to
AK::IAkLowLevelIO::Open() that are issued from a
PrepareEvent() command use the ID version. It is the responsibility of the Low-Level IO to resolve this ID into a valid file descriptor.
Within the ID version of
AK::IAkLowLevelIO::Open(), the default implementation of the Low-Level IO provided in the SDK (
CAkDefaultLowLevelIO, see Default Low-Level I/O Implementation) creates a string with the ID, appends ".bnk", and calls the native File Open method specific to the platform (see Basic File Location).
|Tip: The bank IDs are available in the header file Wwise_IDs.h - see section Enabling ID Usage.|
When the option is selected, Wwise generates the bank files with their original name, appending the BNK extension.
Banks store the names of other banks they reference. When the sound engine's Bank Manager needs to load another bank from I/O, following a
PrepareEvent() command, it uses the string version of
AK::IAkLowLevelIO::Open(). The string version of
AK::IAkLowLevelIO::Open() receives the name of the bank, concatenated with the ".bnk" extension. It is the responsibility of the Low-Level IO to prepend the path of the location of the bank, or to perform any transformation required, before accessing the platform's file system.
Banks generated with the Use SoundBank Names option are slightly bigger, because they must store the names of the banks they reference, not just their ID.
|Note: Generated bank names on disk, and their IDs, are enumerated in the file SoundBanksInfo.xml - see section SoundBanksInfo.xml.|
Tip: In the string overload of
When Wwise creates a language-specific SoundBank, it generates a file with the same ID/file name for every language that has language-specific data. These special language files are stored in a separate language-specific directory. However, there is no flag in the bank load methods of the sound engine API (
LoadBank()) to specify from which language-specific directory the file needs to be opened. File location is intended to be resolved by the Low-Level IO or the Stream Manager if you choose to override it.
The Stream Manager API exposes methods for creating streams (for file I/O) which include a flag that specifies language specificity. This flag is propagated down to the Low-Level IO. Refer to File System Flags for more information.
Since the sound engine's Bank Manager does not know if the SoundBanks that need to be loaded contain language-specific data, it always asks the Stream Manager to search for the file in the language-specific directory first (
True). If the process fails, the Bank Manager tries again, but this time it asks the Stream Manager to search in the common directory (
Refer to File Location Resolving for a discussion on file location. You might also want to read the section that describes the default implementation (Basic File Location) for a tip on how to avoid opening a SoundBank file in the wrong location.
Banks always store the ID of streamed audio files they reference. When the sound engine wants to start the playback of a source that is streamed, it gets the ID from the bank and calls the ID overload of the Stream Manager. This ends up calling the ID overload of
AK::IAkLowLevelIO::Open(). The default implementation of the Low-Level IO creates a string with the ID, and concatenates an extension that corresponds to the format of the file. If you want a copy of your streamed files to be created using this naming scheme and then stored in the Generated SoundBanks directory, use the "Copy Streamed Files" option on the SoundBanks tab of Project Settings dialog box. This operation is defined as a post-generation step. So, it is performed immediately following the generation of your SoundBanks. Refer to the Wwise Help for a complete description of the SoundBank project settings.
Every time banks are generated in Wwise, a file named SoundBanksInfo.xml is created for each platform, directly in the SoundBank path. It is an XML file that describes all the files needed by the sound engine for a given project.
Its content is pretty self-explanatory. The first section (StreamedFiles) enumerates all the streamed audio files, specifying their ID, their original name, their language and their full path. The second section (SoundBanks) does the same for bank files. Furthermore, each bank lists the streamed audio files it references.
For a complete description of the bank loading APIs, refer to Loading Banks.