This is an archive that contains all sound effects and music streams used in the game.
Block pointers are looked up with their identifier. This may not be necessary, but to be safe, I'd still place them in the documented order.
Some General Data Structures
These structures are used in multiple places throughout the bfsar.
File Header
0x0 - 0x4 | Magic number |
0x4 - 0x6 | BOM; always 0xFEFF (big-endian) |
0x6 - 0x8 | Header length |
0x8 - 0xC | Version number, must be 0x20000 in NSMBU. Observed values in other games: 0x20000 , 0x20100 , 0x20200 . Probably 1 byte pad, 1 byte major version, 1 byte minor version, 1 byte patch version. |
0xC - 0x10 | Filesize |
0x10 - 0x12 | Number of sections |
0x12 - 0x14 | Padding |
0x14 - ... | Block pointers |
Block Pointer
Offset is relative to the start of the file.
0x0 - 0x2 | Identifier |
0x2 - 0x4 | Padding |
0x4 - 0x8 | Offset to block body |
0x8 - 0xC | Size of block body |
Block Header
0x0 - 0x4 | Ascii identifier |
0x4 - 0x8 | Block size |
Offset With Identifier
0x0 - 0x2 | Identifier |
0x2 - 0x4 | Padding |
0x4 - 0x8 | Offset |
Item ID
An item id consists of both file type and file id:
0x0 | File type: 1=Sound (SE/WSD/STRM), 2=Sound group (WSDSET/SEQSET), 3=Bank (BANK), 4=Player (PLAYER), 5=Wave archive (WAR), 6=Group (GROUP) |
0x1 - 0x4 | Index into info reference table |
Sound Archive (BFSAR)
BFSAR Header
Magic number | "FSAR" |
String block pointer (STRG) | 0x2000 |
Info block pointer (INFO) | 0x2001 |
File block pointer (FILE) | 0x2002 |
String Block (STRG)
The string block contains a string table and a search tree that's used to look up files by name. The search tree is similar to the search tree found in BFRES files.
0x0 - 0x8 | Block header |
0x8 - 0x10 | Offset to string table (0x2400) |
0x10 - 0x18 | Offset to search tree (0x2401) |
String Table
0x0 - 0x4 | String count |
0x4 - 0x4 + count * 0xC | String pointers |
String Pointer
Offsets are relative to the start of the string table.
0x0 - 0x8 | Offset structure (id = 0x1F01) |
0x8 - 0xC | Length of string, including a null terminator |
Search Tree
This is a patricia tree, similar to the binary search tree in BFRES files.
0x0 - 0x4 | Index of root node |
0x4 - 0x8 | Amount of tree nodes |
Tree Nodes
0x0 - 0x2 | A flag that's 1 if this is a leaf node |
0x2 - 0x4 | Search value, basically the bit index from the left |
0x4 - 0x8 | Left index, go here when the bit is 0 |
0x8 - 0xC | Right index, go here when the bit is 1 |
0xC - 0x10 | String table index |
0x10 - 0x14 | Item id |
Info Block (INFO)
0x0 - 0x8 | Block header |
0x8 - 0x10 | Offset to sound info reference table (0x2100) |
0x10 - 0x18 | Offset to sound group info reference table (0x2104) |
0x18 - 0x20 | Offset to bank info reference table (0x2101) |
0x20 - 0x28 | Offset to wave archive info reference table (0x2103) |
0x28 - 0x30 | Offset to group info reference table (0x2105) |
0x30 - 0x38 | Offset to player info reference table (0x2102) |
0x38 - 0x40 | Offset to file info reference table (0x2106) |
0x40 - 0x48 | Offset to sound archive player info (0x220B) |
Info Reference Table
Offsets are relative to start of info reference table.
0x0 - 0x4 | Count |
0x4 - 0x4 + count * 8 | Offset structures:
Sound info: 0x2200
Sound group info: 0x2204
Bank info: 0x2206
Wave archive: 0x2207
Group info: 0x2208
Player info: 0x2209
File info: 0x220A
|
Offsets are relative to the start of the info structure. Depending on the flags, there may be more values behind the structures documented here. The optional fields are always 4 bytes long.
Sound Info
"actor player id" is unrelated to the player files in the bfsar.
0x0 - 0x4 | Index of FSTM, FWSD or FSEQ file in the file table |
0x4 - 0x8 | Player info table index |
0x8 | Initial volume |
0x9 | Remote filter |
0xA - 0xC | Padding |
0xC - 0x14 | Offset to stream (STRM; 0x2201), wave (WSD; 0x2202) or sequence (SE; 0x2203) info |
0x14 - 0x18 | Flags |
... | Flags & 1: String index |
... | Flags & 2: 0x0000XXYY, XX = pan curve, YY = pan mode |
... | Flags & 4: 0x0000XXYY, XX = actor player id, YY = player priority |
... | Flags & 0x100: Offset to 3d info |
... | Flags & 0x20000: Is front bypass |
... | Flags & 0x10000000: User param |
... | Flags & 0x20000000: User param |
... | Flags & 0x40000000: User param |
... | Flags & 0x80000000: User param |
Sound 3D Info
0x0 - 0x4 | Flags |
0x4 - 0x8 | Unknown, float |
0x8 | Unknown |
0x9 | Unknown |
Stream Sound Info
There can be up to 8 tracks.
0x0 - 0x2 | Bitmask, I think this defines which tracks are enabled. Only the lower byte is read. |
0x2 - 0x4 | Number of channels (up to 16) |
0x4 - 0xC | Offset structure to track info table (id=0x0101) |
Stream Track Info Table
0x0 - 0x4 | Count |
0x4 - 0x4 + count * 8 | Offset structures (0x220E) |
Stream Track Info
0x0 | Unknown |
0x1 | Unknown |
0x2 | Unknown |
0x3 | Unknown |
0x4 - 0xC | Offset structure to mono/stereo information |
Mono/Stereo Information
0x0 - 0x4 | Number of channels (up to 2) |
0x4 | Unknown byte for channel 1 |
0x5 | Unknown byte for channel 2 |
Wave Sound Info
0x0 - 0x4 | Wave index in wave archive |
0x4 - 0x8 | Unknown |
0x8 - 0xC | Flags |
0xC - 0x10 | Flags & 1: 0x0000XXYY, XX = Is release priority fix, YY = Channel priority |
Sequence Sound Info
0x0 - 0x8 | Offset to bank id table |
0x8 - 0xC | Bitmask, I think this one is similar to the bitmask in stream sound info. |
0xC - 0x10 | Flags |
0x10 - 0x14 | Flags & 1: Start offset |
0x14 - 0x18 | Flags & 2: 0x0000XXYY, XX = Is release priority fix, YY = Channel priority |
Bank ID Table
0x0 - 0x4 | Count (up to 4) |
0x4 - 0x4 + count * 4 | Bank item ids |
Bank Info
0x0 - 0x4 | Index of FBNK file in the file table |
0x4 - 0xC | Offset to wave archive id table |
0xC - 0x10 | Flags |
... | Flags & 1: String index |
Wave Archive ID Table
0x0 - 0x4 | Count |
0x4 - 0x4 + count * 4 | Wave archive item ids |
Wave Archive Info
0x0 - 0x4 | Index of FWAR file in the file table |
0x4 | Boolean, might be related to individual wave files? |
0x5 - 0x8 | Padding |
0x8 - 0xC | Flags |
... | Flags & 1: String index |
... | Flags & 2: Wave count |
Sound Group Info
I couldn't find code that uses the offsets described here, so I can't figure out the size of the structures they're pointing to.
0x0 - 0x4 | Item id of first sound |
0x4 - 0x8 | Item id of last sound |
0x8 - 0x10 | Offset to something |
0x10 - 0x18 | Offset structure to unknown thing (0x2205) |
0x18 - 0x1C | Flags |
... | Flags & 1: String index |
Sound Group Unknown Thing
Group Info
0x0 - 0x4 | Index of FGRP file in the file table |
0x4 - 0x8 | Flags |
... | Flags & 1: String index |
Player Info
0x0 - 0x4 | Playable sound limit |
0x4 - 0x8 | Flags |
... | Flags & 1: String index |
... | Flags & 2: Player heap size |
File Info
These structures are aligned to 0x4.
0x0 - 0x2 | File location: 0x220C = internal, 0x220D = external |
0x2 - 0x4 | Padding |
0x4 - 0x8 | Offset to internal file info if internal, or to null-terminated filename string if external |
Internal File Info
0x0 - 0x8 | Offset into FILE block body |
0x8 - 0xC | Filesize |
Sound Archive Player Info
This is used to calculate the required memory size for some classes.
0x0 - 0x2 | Unknown |
0x2 - 0x4 | Unknown |
0x4 - 0x6 | Unknown |
0x6 - 0x8 | Unknown |
0x8 - 0xA | Unknown |
0xA - 0xC | Unknown |
0xC - 0xE | Unknown |
0xE - 0x10 | Padding in 2.0.0 and 2.1.0 BFSARs; normally 0x100 in 2.2.0 BFSARs |
File Block (FILE)
This block contains the actual subfiles.
Wave Sound Files (WSD)
WSD Header
Magic number | "FWSD" |
Info block pointer (INFO) | 0x6800 |
Info Block (INFO)
0x0 - 0x8 | Block header |
0x8 - 0xC | Unknown |
0xC - 0x10 | Offset to wave sound data reference table |
Wave Sound Data Reference Table
0x0 - 0x4 | Count |
0x4 - 0x4 + count * 8 | Offsets to wave sound datas (0x4900) |
Wave Sound Data
0x0 - 0x4 | Unknown |
0x4 - 0x8 | Offset to wave sound info |
0x8 - 0x14 | Unknown |
0x14 - 0x18 | Offset to note info reference table |
Wave Sound Info
0x0 - 0x4 | Flags |
... | Flags & 1: 0x0000XXYY, XX = Surround pan, YY = Pan |
... | Flags & 2: Pitch (float) |
... | Flags & 4: 0x00XXYYZZ, XX = Biquad value, YY = Biquad type, ZZ = Low-pass filter frequency |
... | Flags & 0x100: Offset to weird send-value related thing |
... | Flags & 0x200: Offset to "AdshrCurve"-related structure |
Sequence Sound Files (SE)
SEQ Header
Magic number | "FSEQ" |
Data block pointer (DATA) | 0x5000 |
Label block pointer (LABL) | 0x5001 |
Label Block (LABL)
0x0 - 0x4 | Count |
0x4 - 0x4 + count * 8 | Offsets to label info |
Label Info
0x0 - 0x4 | Unknown |
0x4 - 0x8 | Offset into data block |
0x8 - 0xC | Unknown |
0xC - ... | Label name |
Bank Files (BANK)
BANK Header
Magic number | "FBNK" |
Info block pointer (INFO) | 0x5800 |
Info Block (INFO)
0x0 - 0x8 | Offset to wave id table |
0x8 - 0x10 | Offset to instrument reference table |
Wave ID Table
0x0 - 0x4 | Count |
0x4 - 0x4 + count * 8 | Wave ids |
Wave ID
0x0 - 0x4 | Wave archive item id |
0x4 - 0x8 | Wave index in wave archive |
Wave Archive Files (WAR)
WAR Header
Magic number | "FWAR" |
Info block pointer | 0x6800 |
File block pointer | 0x6801 |
Info Block
0x0 - 0x8 | Block header |
0x8 - 0xC | Wave file count |
0xC - 0xC + count * 12 | Wave file info |
Wave File Info
0x0 - 0x8 | Offset into file block |
0x8 - 0xC | File size |
Group Files (GROUP)
When the offset field of the BFSAR file info structure is -1, or when the file info structure is not found in the BFSAR info block, the game tries to find the subfile in the GROUP files.
GROUP Header
Magic number | "FGRP" |
Info block pointer (INFO) | 0x7800 |
File block pointer (FILE) | 0x7801 |
InfoEx block pointer (INFX) | 0x7802 |
Info Block (INFO)
0x0 - 0x8 | Block header |
0x8 - 0xC | Group item location info count |
0xC - 0xC + count * 8 | Offset structures to group item location info |
Group Item Location Info
0x0 - 0x4 | File id |
0x4 - 0x8 | Unknown |
0x8 - 0xC | Offset into file block |