Wwise SoundBank (*.bnk): Difference between revisions
imported>SWTOR fan m (→STMG section: error corrected) |
imported>SWTOR fan m (→STMG section: error corrected) |
(No difference)
| |
Revision as of 15:10, 1 December 2012
On this page you can find a file format specification of the .bnk SoundBank files used by Wwise.
SoundBanks by Wwise can be used to have a great deal of control over the soundtrack of a game, including the sound effects and the score. SoundBanks contain the individual audio files as well as containers to group the files, e.g. a gun shot container that plays a random gun shot sound. Also, SoundBanks contain events which can play or pause containers or audio files. Events are the only type of object that is visible outside the SoundBanks, and developers can access these events from the game code. For example, during a very emotional scene they could call a Play_EmotionalTheme event, which will play an emotional piece, as defined by the sound designer.
Each Wwise project contains an initialization SoundBank, Init.bnk. This SoundBank contains the project settings and is loaded first. The other SoundBanks contain sounds for different parts of the game (e.g. one SoundBank for each area or level). They are loaded into memory whenever the player has reached that part of the game.
The sound files are stored via a custom Wwise encoding and have the file extension .wem (before 2011, the Wwise extension was called .wav). For converting these files to .ogg files, I recommend the command-line utility ww2ogg by Halley's Comet Software (hcs) -- see hcs64.com/vgm_ripping.html. Depending on the game, some files are not embedded in the SoundBanks but are streamed. In this case, look in the game archive for .wem files.
General format
- FOR EACH (section) {
- byte[4]: four-letter identifier of the section, e.g. BKHD or DIDX
- uint32: length of this section in bytes
- byte[]: section data (see below)
- } END FOR
-- END OF FILE --
To avoid errors when reading a .bnk file, it is recommended to always seek to the end of a section by using the byte length field. That way, even the program has reached the end of the section, it will automatically skip to the end in case it has left out something.
BKHD section
The BKHD section (Bank Header) contains the version number and the SoundBank id.
- 42 4B 48 44 -- BKHD
- uint32: length of section
- uint32: version number of this SoundBank
- uint32: id of this SoundBank
- uint32: always zero
- uint32: always zero
DIDX section
The DIDX (Data Index) section contains the references to the .wem files embedded in the SoundBank. Each sound file is described with 12 bytes, so you can get the number of embedded files by dividing the section length by 12.
- 44 49 44 58 -- DIDX
- uint32: length of section
- FOR EACH (embedded .wem file) {
- uint32: .wem file id
- uint32: offset from start of DATA section
- uint32: length in bytes of .wem file
- } END FOR
DATA section
The DATA section contains the .wem files, not encoded, and immediately following each other. It is not recommended to read this section by itself but instead to immediately jump to the correct position based on the offset given in the DIDX or HIRC section.
- 44 41 54 41 -- DATA
- uint32: length of section
- FOR EACH (embedded .wem file) {
- byte[]: the .wem file with the length as given in the DIDX section, and starting with 52 49 46 46 -- RIFF.
- } END FOR
ENVS section
The ENVS section (Environments?) section is yet to be analysed.
FXPR section
The FXPR section (Effects production?) section is yet to be analysed.
HIRC section
The HIRC section contains all the Wwise objects, including the events, the containers to group sounds, and the references to the sound files.
Format:
- 48 49 52 43 -- HIRC
- uint32: length of section
- uint32: number of objects
- FOR EACH (object) {
- byte: single byte identifying type of object
- uint32: length of object section (= 4-byte id field and additional bytes)
- uint32: id of this object
- byte[]: additional bytes, depending on type of object and section length
- } END FOR
type #2: Sound SFX
Format:
-- BEGINNING OF SECTION --
- 02 -- identifier for Sound SFX section
- uint32: length of this section
- uint32: id of this Sound SFX object
- byte[4]: four unknown bytes
- byte: whether the sound is included in the SoundBank or streamed:
- 00: embedded in the SoundBank, not streamed
- 01: is streamed
- 02: is streamed, with Zero Latency (that is, the sound data is prefetched)
- byte[3]: three unknown bytes
- uint32: id of the audio file
- uint32: id of the source:
- If this file is embedded, this will contain the SoundBank id as given in the STID section.
- If the file is being streamed, this number will be identical to the audio file id and can be used to find the .wem file to stream.
IF (file is embedded in a SoundBank) {
- uint32: offset to the position where the .wem sound file can be found in the SoundBank
- uint32: length in bytes of the .wem sound file in the SoundBank
} END IF
- byte[7]: seven unknown bytes
- uint32: id of the parent container, e.g. a Random Container
- byte[2]: two unknown bytes
- byte: number of additional properties given in this file; they are only included if they are different from their default values
- FOR EACH (property) {
- byte: the type of the property:
- 00: Volume, given as float
- 02: Pitch, given as float
- 03: Low Pass Filter (LPF), given as float
- 07: whether to Loop, given as uint32 = number of loops, or infinite if the value is 0
- byte: the type of the property:
- } END FOR
- FOR EACH (property) {
- byte[]: the value of the property, decoded based on the property type, see above
- } END FOR
- byte[21]: 21 additional bytes, yet to be decoded
-- END OF SECTION --
type #3: Event Action
Format:
- 03 -- identifier for Event Action section
- uint32: length of this section
- uint32: id of this Event Action object
- byte: The Scope of this Event Action:
- 01: Game object: Switch or Trigger
- 02: Global
- 03: Game object: see referenced object id
- 04: Game object: State
- 05: All
- 09: All Except see referenced object id
- byte: Action Type:
- 01: Stop
- 02: Pause
- 03: Resume
- 04: Play
- 05: Trigger
- 06: Mute
- 07: UnMute
- 08: Set Voice Pitch
- 09: Reset Voice Pitch
- 0A: Set Voice Volume
- 0B: Reset Voice Volume
- 0C: Set Bus Volume
- 0D: Reset Bus Volume
- 0E: Set Voice Low-pass Filter
- 0F: Reset Voice Low-pass Filter
- 10: Enable State
- 11: Disable State
- 12: Set State
- 13: Set Game Parameter
- 14: Reset Game Parameter
- 19: Set Switch
- 1A: Enable Bypass or Disable Bypass
- 1B: Reset Bypass Effect
- 1C: Break
- 1E: Seek
- uint32: id of the game object that is referenced by this Event Action, or zero if there is no game object
- byte: always 00
- byte: number of additional parameters
- FOR EACH (parameter) {
- byte: parameter type:
- 0E: Delay, given as uint32 in milliseconds
- 0F: Play: Fade in time, given as uint32 in milliseconds
- 10: Probability, given as float
- byte: parameter type:
- } END FOR
- FOR EACH (parameter) {
- byte[]: parameter value, format depending on parameter type (see above)
- } END FOR
- byte: always 00
- IF (Action Type == "Set State", 0x12) {
- uint32: State Group id
- uint32: State id
- ELSE IF (Action Type == "Set Switch", 0x19) {
- uint32: Switch Group id
- uint32: Switch id
- } END IF
-- END OF SECTION --
More information will follow.
type #4: Event
Format:
-- BEGINNING OF SECTION --
- 04 -- identifier for Event section
- uint32: length of this section
- uint32: id of this Event object
- uint32: the number of Event Actions this Event has
- FOR EACH (event action) {
- uint32: id of the Event Action
- } END FOR
-- END OF SECTION --
type #5: Random Container or Sequence Container
More information will follow.
type #6: Switch Container
More information will follow.
type #7: Actor-Mixer
More information will follow.
type #8: Audio Bus?
More information will follow.
type #10: Music Segment
More information will follow.
type #11: Music Track
More information will follow.
type #12: Music Switch Container
More information will follow.
type #13: Music Playlist Container
More information will follow.
type #14: Attenuation
More information will follow.
Music format
More information to follow.
- uint16: number of RTPCs (Real-time Parameter Controls)
- FOR EACH (RTPC) {
- uint32: id of Game Parameter on x-axis
- uint32: y-axis type:
- 00 = Voice Volume
- 03 = Voice Low-Pass Filter
- 08 = Priority
- 09 = Sound Instance Limit
- 0F = User-Defined Auxiliary Sends Volume 0
- 10 = User-Defined Auxiliary Sends Volume 1
- 11 = User-Defined Auxiliary Sends Volume 2
- 12 = User-Defined Auxiliary Sends Volume 3
- 13 = Game-Defined Auxiliary Sends Volume
- 16 = Output Bus Volume
- 17 = Output Bus Low-pass Filter
- 18 = Bypass Effect 0
- 19 = Bypass Effect 1
- 1A = Bypass Effect 2
- 1B = Bypass Effect 3
- 1C = Bypass All Effects
- 1D = Motion Volume Offset
- 1E = Motion Low Pass
- uint32: unknown id
- byte: unknown
- byte: number of points
- byte: unknown
- FOR EACH (point) {
- float: x-coordinate of point
- float: y-coordinate of point
- uint32: shape of curve following this point:
- 00 = Logarithmic (Base 3)
- 01 = Sine (Constant Power Fade In)
- 02 = Logarithmic (Base 1.41)
- 03 = Inverted S-Curve
- 04 = Linear
- 05 = S-Curve
- 06 = Exponential (Base 1.41)
- 07 = Sine (Constant Power Fade Out)
- 08 = Exponential (Base 3)
- 09 = Constant
- } END FOR
- } END FOR
STID section
The STID section (Sound Type ID?) section contains a list of all the SoundBanks referenced in the HIRC section (including the current SoundBank). In the HIRC section, only the SoundBank ids are given, so this section can be used to match an id with a SoundBank file name.
- 53 54 49 44 -- STID
- uint32: length of section
- uint32: unknown integer, always 01 00 00 00
- uint32: number of SoundBanks
- FOR EACH (SoundBank) {
- uint32: SoundBank id
- byte: length of SoundBank name
- char[]: String with given length, e.g. "music". Can be used to find the SoundBank file name: "music.bnk".
- } END FOR
STMG section
The STMG section section can only be found in the Init.bnk SoundBank. It contains the project settings as well as the Switch Groups, State Groups and Game Parameters.
- 53 54 4D 47 -- STMG
- uint32: length of section
- float: Volume Threshold
- uint16: Max Voice Instances
- uint32: number of State Groups
- FOR EACH (State Group) {
- uint32: id of State Group
- uint32: default transition time (ms)
- uint32: number of Custom Transition Times
- FOR EACH (Custom Transition Time) {
- uint32: id of "from" State
- uint32: id of "to" State
- uint32: transition time (ms)
- } END FOR
- } END FOR
- uint32: number of Switch Groups that set the current Switch based on a Game Parameter
- FOR EACH (Switch Group) {
- uint32: id of Switch Group
- uint32: id of Game Parameter that determines currently set Switch
- uint32: number of points
- FOR EACH (point) {
- float: value of Game Parameter
- uint32: id of Switch that is set when Game Parameter >= given value
- uint32: shape of curve, always 09 = Constant
- } END FOR
- uint32: number of Game Parameters
- FOR EACH (Game Parameter) {
- uint32: id of Game Parameter
- float: default value of Game Parameter
- } END FOR
-- END OF SECTION --
Further information
You can get Wwise, free for personal use, at Audiokinetic.com, to generate custom SoundBank files and train your converter/reader. Also, I recommend watching the video tutorials at www.audiokinetic.com/en/resources/videos, specifically:
- Using the interface
- Importing Audio Files
- Building Sound Hierarchies
- Creating Events
- Building SoundBanks
- Relation between Sound, Source and Audio File