Skip to content

Wave Bank Format

Robert Jordan edited this page Jun 12, 2020 · 4 revisions

This page is a work-in-progress. And only intended for use by developers/programmers.

File Format

Filesize Note: The 3 different wavebank formats: Compact, Standard, and Streaming each have different requirements on total filesize and how audio wave data is aligned.

Xbox Note: Xbox WaveBanks Have all data written in Big Endian format, opposite of Windows, stored in little endian. You may determine which format a file is in by comparing the order of the signature characters. "WBND" for Windows, "DNBW" for Xbox.

Header

Data Type Value Description
char[4] "WBND" File Signature
uint32 ContentVersion Version of this file format (46)
uint32 ToolVersion Version of XACT toolset that wrote this format? (44)
Segment[5] Segments Offset/Length pairs to different data in the wave bank beyond this point

Segment

Data Type Value Description
uint32 Offset Absolute offset to data
uint32 Length Length of data at offset

* Note: A segment length of 0 is considered valid even when the offset is non-zero. In these cases, the segment is not read.

Segment Types

The index of each segment determines what type of data is pointed to.

# Name Details
0 BankData Extended information of this wave bank file (required)
1 EntryMetadata Table of fixed-length structures describing each Wave in the Wave Bank (required)
2 SeekTables Table of variable-length arrays for each entry with preprocessed? offsets used for seeking (optional)
3 EntryNames Table of fixed-length names for each entry (optional)
4 EntryWaveData Table of raw audio data pointed to by structures in EntryMetadata (required)

BankData Segment

Data Type Value Description
uint32 Flags WaveBank flags...
uint32 EntryCount Number of Waves
char[64] BankName Name of wave bank
uint32 EntryMetadataSize Fixed size of each metadata structure in EntryMetadata
uint32 EntryNameSize Fixed size of each entry name in EntryNames
uint32 Alignment Alignment of entry audio data in EntryWaveData
uint32 CompactFormat Format for all Waves when Compact flag
uint64 BuildTime Build FILETIME of the wave bank

BankData Flags

Value Flag Description
0x1 Streaming Streaming wave data format
0x10000 EntryNames EntryNames segment is defined
0x20000 Compact Compact wave bank entry format
0x40000 SyncDisabled Audition Sync is disabled*??*
0x80000 SeekTables SeekTables segment is defined

* Note: Some versions of XNA/Xact3(?) have shown to fail when attempting to read wave banks with both EntryNames | SeekTables flags, (only when both segments have a non-zero length). Because of this, it is required to turn off the EntryNames flag when writing xWMA or XMA formats to the wavebank.

* Extended Note: A non-zero segment length is accepted as long as the associated flag is not set. Most available WaveBank readers present on the web either ignore the EntryNames segment altogether, or ignore the flag and read the segment when it's length is non-zero. Meaning this is a generally safe approach if you want to preserve this information.

EntryMetadata Segment

N = BankData.EntryCount;
compact = (BankData.Flags & Compact);
typeof(Entry) = (compact ? EntryFull : EntryCompact);
sizeof(Entry) = BankData.EntryMetadataSize;
Data Type Value Description
Entry[N] Entries Table of Wave Entry metadata

EntryFull

Data Type Value Description
uint32 FlagsAndDuration EntryFlags and duration (in total samples)
uint32 Format Individual entry mini wave format
uint32 PlayOffset Offset to raw audio data (in bytes) relative to EntryWaveData
uint32 PlayLength Length of raw audio data (in bytes)
uint32 LoopStart The start sample position for looped audio
uint32 LoopDuration The duration in samples of the looped audio region
Data Bits Value Description
bits[ 0:4] Flags (value & 0xf)
bits[4:32] Duration (value >> 4) & 0x0fffffff

Entry Flags

It seems these flags only specify how to handle entry data, and not how to read/extract it.

Value Flag Description
0x1 ReadAhead Enable stream read-ahead
0x2 LoopCache One or more looping sounds use this wave
0x4 RemoveLoopTail Remove data after the end of the loop region
0x8 IgnoreLoop Used internally when the loop region can't be used

* Note: Flag descriptions taken directly from DirectXTK/xwbtool.cpp

EntryCompact

Data Type Value Description
uint32 OffsetAndLengthDeviation Combined PlayOffset/PlayLength of entry audio data
Data Bits Value Description
bits[ 0:21] CompactOffset (value & 0x1fffff)
bits[21:32] LengthDeviation (value >> 21) & 0x7ff
UInt32 value = reader.ReadUInt32();
CompactOffset = (value & 0x1fffff);
// Deviation in data length to account for BankData.Alignment
LengthDeviation = (value >> 21) & 0x7ff;

PlayOffset = CompactOffset * BankData.Alignment;

UInt32 nextOff;
if (i+1 < BankData.EntryCount)
  nextOff = Entries[i+1].PlayOffset;
else
  nextOff = Header.Segments[4].Length; //EntryWaveData
PlayLength = (nextOff - PlayOffset) - LengthDeviation;

SeekTables Segment

N = BankData.EntryCount;
SeekTablesStart = N * 4; //sizeof(UInt32)
Data Type Value Description
uint32[N] Offsets Offset in bytes to entry seek table relative to Tables field
EntrySeekTable[>] Tables Entry seek table data pointed to by Offsets

EntrySeekTable

Skip the current entry seek table if Offsets[i] == 0xffffffff

Position = Offsets[i] + Header.Segments[2]; /*SeekTables*/ + (BankData.EntryCount * 4); //sizeof(UInt32)
Data Type Value Description
uint32 Count Number of values
uint32[Count] SeekTable Entry Wave seek table indices

EntryNames Segment

N = BankData.EntryCount;
Len = BankData.EntryNameSize;
Data Type Value Description
char[N][Len] Names Fixed length name of each Wave entry

EntryWaveData Segment

Data Type Value Description
bytes RawData Raw audio data pointed to by Entry metadatas' PlayOffset and PlayLength

* Note: Streaming wave data format will align the beginning of all audio data to the disk block size. As observed: this seems to be 2048, and not 4096.

See Also

Clone this wiki locally