BFSTM (File Format)

From Wexos's Wiki
Revision as of 21:30, 25 September 2024 by Atlas (talk | contribs) (→‎Version List)
Jump to navigationJump to search

The BFSTM (Binary caFe STreaM) file format is used for storing music streams on Wii U and Nintendo Switch. It is a direct update from its predecessors, BRSTM and BCSTM, and is therefore very similar to them. It is also similar to BFWAV. The file consists of a header along with three sections, INFO, SEEK and DATA. All offsets in the file may be 0xFFFFFFFF if it links to nothing.

File Format

Header

The file starts with a 0x40 byte long header as follows:

Offset Type Description
0x00 Char[4] File magic. Always FSTM in ASCII.
0x04 UInt16 Byte-order-mark. FE FF for big endian, FF FE for little endian.
0x06 UInt16 Header size. Always 0x40.
0x08 UInt32 Version number.
0x0C UInt32 Size of the file in bytes.
0x10 UInt16 Number of data blocks in the file. Always 3 (INFO, SEEK and DATA).
0x12 UInt16 Padding.
0x14 UInt16 INFO section flag. Always 0x4000.
0x16 UInt16 Padding.
0x18 Int32 INFO offset.
0x1C UInt32 INFO size.
0x20 UInt16 SEEK section flag. Always 0x4001.
0x22 UInt16 Padding.
0x24 Int32 SEEK offset.
0x28 UInt32 SEEK size.
0x2C UInt16 DATA section flag. Always 0x4002.
0x2E UInt16 Padding.
0x30 Int32 DATA offset.
0x34 UInt32 DATA size.
0x38 Byte[8] Padding.
0x40 End of file header

Reference Table

A reference table is used to reference multiple structures. It has the following structure:

Offset Type Description
0x00 UInt32 Number of references.

The following structure follows. The amount is specified above.

Offset Type Description
0x00 UInt16 Section flag, to identify what structure it links to.
0x02 UInt16 Padding.
0x04 Int32 Offset to a structure, relative to the start of the header structure.

INFO

The INFO section contains general information about the stream.

Offset Type Description
0x00 Char[4] Section magic. Always INFO in ASCII.
0x04 UInt32 Size of this section in bytes.
0x08 UInt16 Stream info flag. Always 0x4100.
0x0A UInt16 Padding.
0x0C Int32 Stream info offset, relative to 0x08 in this structure.
0x10 UInt16 Track info flag. Often not used and therefore set to 0.
0x12 UInt16 Padding.
0x14 Int32 Track info offset, relative to 0x08 in this structure.
0x18 UInt16 Channel info flag. Always 0x0101.
0x1A UInt16 Padding.
0x1C Int32 Channel info offset, relative to 0x08 in this structure.

Stream Info

Offset Type Description
0x00 Byte Sound encoding. 0 = PCM8, 1 = PCM16, 2 = DSP ADPCM, 3 = IMA ADPCM.
0x01 Byte Loop. 1 if it loops.
0x02 Byte Number of channels.
0x03 Byte Number of regions.
0x04 UInt32 Sample rate.
0x08 UInt32 Loop start.
0x0C UInt32 Loop end.
0x10 UInt32 The total number of blocks, including the padded one. If this field is N, S is the size of one block and P is the size of a last padded block, then the size of one channel is (N - 1) * S + P.
0x14 UInt32 Size of one block in bytes.
0x18 UInt32 Size of one block in samples.
0x1C UInt32 Size of the last block without padding in bytes.
0x20 UInt32 Size of the last block without padding in samples.
0x24 UInt32 Size of the last block with padding in bytes. The last block is always aligned. PCM8 audio is aligned by 0x20 and PCM16 audio is aligned by 0x04.
0x28 UInt32 Size of one channel's seek info for one block, which should be 4, given the History Info should be 4 bytes long in almost all cases.
0x2C UInt32 SEEK sample interval. The number of samples between each history sample into the SEEK block.
0x30 UInt16 Sample data flag. Always 0x1F00.
0x32 UInt16 Padding.
0x34 Int32 Sample data offset, relative to 0x08 into the DATA block. Offset to the sample data of the first channel.
0x38 UInt16 Size of each region info in bytes. Always 0x100, even when unused.
0x3A UInt16 Padding.
0x3C UInt16 Region info flag. Always 0, even when offset is used.
0x3E UInt16 Padding.
0x40 Int32 Region info offset, relative to 0x08 into the REGN block.
If version ≥ 0.4.0.0
0x44 UInt32 Original loop start.
0x48 UInt32 Original loop end.
If version ≥ 0.5.0.0
0x4C UInt32 CRC-32 checksum of the whole file with this field set to 0. It is used to match BFSTM and BFSTP when using prefetch.

Track Info

The INFO section links to a reference table which points to this structure. Since v0.2.0.0, this structure is no longer exported and is therefore useless.

Offset Type Description
0x00 Byte Volume.
0x01 Byte Pan.
0x02 Byte Span.
0x03 Byte Flags.
ID Type
0x00 Monaural
0x01 Stereo
0x02 Surround
0x03 Dpl2
0x04 UInt16 Global channel index table flag.
0x06 UInt16 Padding.
0x08 Int32 Offset to the global channel index table.

Global Channel Index Table

The Global Channel Index Table is used to bundle the local channel index in the track with the global channel index for the overall stream. It has the following structure:

Offset Type Description
0x00 UInt32 C = Count.
0x04 Byte[C] Items.

Channel Info

The INFO section links to a reference table which points to the following structure. The section flag is set to 0x4102.

Offset Type Description
0x00 UInt16 Section flag. Always 0x0300.
0x02 UInt16 Padding.
0x04 Int32 Offset to DSP ADPCM channel info, relative to the start of this structure.

DSP ADPCM Channel Info

Offset Type Description
0x00 UInt16[8][2] 16-bit Coefficients.
0x20 UInt16 Pred scale.
0x22 UInt16 Yn 1.
0x24 UInt16 Yn 2.
0x26 UInt16 Loop Pred Scale.
0x28 UInt16 Loop Yn 1.
0x2A UInt16 Loop Yn 2.
0x2C UInt16 Padding.

SEEK

The SEEK section is only used for DSP ADPCM audio. It contains information about midstream playback. It contains info about history samples mid-playback in case the game needs to skip to a certain section of the song. The history samples for the first block in each channel is always 0.

Offset Type Description
0x00 Char[4] Section magic. Always SEEK in ASCII.
0x04 UInt32 Size of this section in bytes (S).
0x08 HistoryInfo[Number of blocks][Number of channels] History information.

History Info:

Offset Type Description
0x00 Int16 History sample 1. The index to the sample in PCM16 data is the Seek Interval * Block Number - 1.
0x02 Int16 History sample 2. The index to the sample in PCM16 data is the Seek Interval * Block Number - 2.

REGN

The REGN section devides the data into different regions. It starts with the following structure:

Offset Type Description
0x00 Char[4] Section magic. Always REGN in ASCII.
0x04 UInt32 Size of this section in bytes.

Region

The number of regions is specified in the stream info into the INFO block. Each entry consists of the following:

Offset Type Description
0x00 UInt32 Start of the region in samples.
0x04 UInt32 End of the region in samples.

After comes 16 entries, representing up to 16 channel loop context. Unused entries are filled with 0. Each entry has the following structure:

Offset Type Description
0x00 UInt16 Loop Pred Scale.
0x02 UInt16 Loop Yn 1.
0x04 UInt16 Loop Yn 2.

0x98 bytes of padding are placed to align each region to be 0x100 bytes long.

DATA

The DATA section holds all the data for the stream. It has the following structure:

Offset Type Description
0x00 Char[4] Section magic. Always DATA in ASCII.
0x04 UInt32 Size of this section in bytes (S).
0x08 Byte[S - 8] Sound data.

Version List

Version Found in
0.3.0.0
0.4.0.0
0.5.0.0
0.6.1.0
0.6.3.0
0.6.4.0
2.0.0.0
2.0.1.0

Tools

The following tools can handle BFSTM files: