Difference between revisions of "BRSTM (File Format)"

From Custom Mario Kart
Jump to navigation Jump to search
m
(https://youtu.be/__nioTv19bQ)
 
Line 1: Line 1:
 
== Overview ==
 
== Overview ==
This article describes the '''BRSTM''' format, which is the music format used by [[Mario Kart Wii]] and other games such as [[Super Smash Bros. Brawl]].
+
A '''BRSTM''' ('''B'''inary '''R'''evolution '''ST'''rea'''M''') is the music format used by [[Mario Kart Wii]] and other games such as [[Super Smash Bros. Brawl]].
  
 
== File Header ==
 
== File Header ==
The file begins with the header, which is 0x64 bytes. All lengths are written in hexadecimal.
 
 
{| class="wikitable"
 
{| class="wikitable"
! Offset
+
! Offset !! Type !! Description
! Size
 
! Description
 
 
|-
 
|-
| 0x00
+
| 0x00 || String || '''File magic'''. ''RSTM'' in ASCII.
| 4
 
| '''File magic'''. ''RSTM'' in ASCII.
 
 
|-
 
|-
| 0x04
+
| 0x04 || UInt16 || {{BOM}}
| 2
 
| {{BOM}}
 
 
|-
 
|-
| 0x06
+
| 0x06 || UInt16 || '''Version'''. Always 0x0100.
| 2
 
| {{Unknown-left|'''Unknown'''.}} Usually 01 00.
 
 
|-
 
|-
| 0x08
+
| 0x08 || UInt32 || File size.
| 4
 
| Length of the file in bytes.
 
 
|-
 
|-
| 0x0c
+
| 0x0c || UInt16 || '''Header size'''. Always 0x40.
| 2
 
| Length of header in bytes (always 00 40).
 
 
|-
 
|-
| 0x0e
+
| 0x0e || UInt16 || '''Section count'''. (Excluding HEAD).
| 2
 
| {{Unknown-left|'''Unknown'''.}} 00 02 in most files.
 
 
|-
 
|-
| 0x10
+
| 0x10 || UInt32 || Offset to HEAD section.
| 4
 
| Offset location of the HEAD section (usually 00 00 00 40).
 
 
|-
 
|-
| 0x14
+
| 0x14 || UInt32 || Size of HEAD section.
| 4
 
| Size of HEAD section in bytes.
 
 
|-
 
|-
| 0x18
+
| 0x18 || UInt32 || Offset to ADPC section.
| 4
 
| Offset location of ADPC section in bytes.  
 
 
|-
 
|-
| 0x1c
+
| 0x1c || UInt32 || Size of ADPC section.
| 4
 
| Size of ADPC section in bytes.  
 
 
|-
 
|-
| 0x20
+
| 0x20 || UInt32 || Offset to DATA section.
| 4
 
| Offset location of DATA section in bytes.  
 
 
|-
 
|-
| 0x24
+
| 0x24 || UInt32 || Size of DATA section.
| 4
+
|}
| Size of DATA section in bytes.  
+
 
 +
== HEAD ==
 +
Offsets are relative to 0x08 of this header.
 +
{| class="wikitable"
 +
! Offset !! Type !! Description
 +
|-
 +
| 0x00 || String || '''Section magic'''. Always ''HEAD'' in ASCII.
 +
|-
 +
| 0x04 || UInt32 || Size of the section.
 +
|-
 +
| 0x08 || [[#Data Reference|DataRef]] || Reference to '''[[#Stream Data Info|Stream Data Info]]'''.
 +
|-
 +
| 0x10 || [[#Data Reference|DataRef]] || Reference to '''[[#Track Table|Track Table]]'''.
 +
|-
 +
| 0x18 || [[#Data Reference|DataRef]] || Reference to '''[[#Channel Table|Channel Table]]'''.
 +
|-
 +
|}
 +
 
 +
===Stream Data Info===
 +
{| class="wikitable"
 +
! Offset !! Type !! Description
 +
|-
 +
| 0x00 || Byte || Format.
 +
  {| class="wikitable"
 +
  ! Enum !! Description
 +
  |-
 +
  | 0x0 || PCM8
 +
  |-
 +
  | 0x1 || PCM16
 +
  |-
 +
  | 0x2 || ADPCM
 +
  |-
 +
  |}
 +
|-
 +
| 0x01 || Byte || Loop Flag
 +
|-
 +
| 0x02 || Byte || Number of channels
 +
|-
 +
| 0x03 || UInt24 || Sample rate.
 +
|-
 +
| 0x06 || UInt16 || {{Unknown-left|Offset to block header? Always 0.}}
 +
|-
 +
| 0x08 || UInt32 || Loop start sample.
 
|-
 
|-
| 0x28
+
| 0x0C || UInt32 || Loop end sample.
| 18
+
|-
| {{Unknown-left|'''Unknown'''.}} Probably padding.
+
| 0x10 || UInt32 || Actual data offset.
 +
|-
 +
| 0x14 || UInt32 || Block count.
 +
|-
 +
| 0x18 || UInt32 || Block size.
 +
|-
 +
| 0x1C || UInt32 || Block samples.
 +
|-
 +
| 0x20 || UInt32 || Final block size.
 +
|-
 +
| 0x24 || UInt32 || Final block samples.
 +
|-
 +
| 0x28 || UInt32 || Final block size with padding.
 +
|-
 +
| 0x2C || UInt32 || The interval (sample count) for writing data to the ADPC block.
 +
|-
 +
| 0x30 || UInt32 || Size per channel for each interval where data is written to the ADPC.
 
|-
 
|-
| colspan=3 {{unknown|End of header}}
 
 
|}
 
|}
  
== Sections ==
+
===Track Table===
The rest of the file is written like an [[wikipedia:Adaptive differential pulse-code modulation|Adaptive differential pulse-code modulation]] (ADPCM) file.
+
{| class="wikitable"
 +
! Offset !! Type !! Description
 +
|-
 +
| 0x00 || Byte || '''N''' = Track count.
 +
|-
 +
| 0x01 || Byte || Track Info type. (0 = [[#Track Info (Simple)|Simple]], 1 = [[#Track Info (Extended)|Extended]]).
 +
|-
 +
| 0x02 || Byte[2] || {{Unknown-left|Padding.}}
 +
|-
 +
| 0x04 || [[#Data Reference|DataRef]]['''N'''] || Reference to Track Info. '''Data type''' needs to match '''Track Info type'''.
 +
|-
 +
|}
 +
====Track Info (Simple)====
 +
With "simple" track info Track Volume is set to 127.
 +
{| class="wikitable"
 +
! Offset !! Type !! Description
 +
|-
 +
| 0x00 || Byte || '''N''' = Channel count.
 +
|-
 +
| 0x01 || Byte['''N'''] || Channel index info.
 +
|-
 +
|}
  
=== HEAD ===
+
====Track Info (Extended)====
The '''HEAD''' section is typically 256 bytes long.
+
{| class="wikitable"
 +
! Offset !! Type !! Description
 +
|-
 +
| 0x00 || Byte || Track volume (0-127).
 +
|-
 +
| 0x01 || Byte || Pan (0-127).
 +
|-
 +
| 0x02 || Byte[2] || {{Unknown-left|Padding.}}
 +
|-
 +
| 0x04 || UInt32 || {{Unknown-left|Reserved.}}
 +
|-
 +
| 0x08 || Byte || '''N''' = Channel count.
 +
|-
 +
| 0x09 || Byte['''N'''] || Channel index info.
 +
|-
 +
|}
  
It contains what appears to be a ADPCM table, followed by a a YN1 & YN2 twice, which may control looping.
+
=== Channel Table ===
The byte at 0x23 describes the number of channels. The rest is unknown.
+
{| class="wikitable"
 +
! Offset !! Type !! Description
 +
|-
 +
| 0x00 || Byte || '''N''' = Channel count.
 +
|-
 +
| 0x01 || Byte[3] || {{Unknown-left|Padding.}}
 +
|-
 +
| 0x04 || [[#Data Reference|DataRef]]['''N'''] || References to another [[#Data Reference|DataRef]] referencing [[#ADPCM Parameters Set|ADPCM Parameters Set]].<br>Value of 0 is second DataRef means no data.
 +
|-
 +
|}
  
=== ADPC ===
+
=== ADPCM Parameters Set===
The '''ADPC''' section contains another type of table.
+
This data is only available if '''ADPCM''' encoding is used.
 
{| class="wikitable"
 
{| class="wikitable"
! Offset
+
! Offset !! Type !! Description
! Size
 
! Description
 
 
|-
 
|-
| 0x00
+
| 0x00 || UInt16[16] || Coefficients.
| 4
 
| '''Section magic'''. ''ADPC'' in ASCII.
 
 
|-
 
|-
| 0x04
+
| 0x2C || UInt16 || Gain.
| 4
 
| Length of section in bytes (typically 00 00 21 60).
 
 
|-
 
|-
| 0x08
+
| 0x2E || UInt16 || Predictor + Scale.
| 2158
+
|-
| {{Unknown-left|'''Unknown'''.}} Most likely padding.
+
| 0x30 || UInt16 || YN1. (Sample - 1).
 +
|-
 +
| 0x32 || UInt16 || YN2. (Sample - 2).
 +
|-
 +
| 0x34 || UInt16 || Loop Predictor + Scale.
 +
|-
 +
| 0x36 || UInt16 || Loop YN1. (Sample - 1).
 +
|-
 +
| 0x38 || UInt16 || Loop YN2. (Sample - 2).
 
|-
 
|-
| colspan=3 {{unknown|End of section}}
 
 
|}
 
|}
  
=== DATA ===
+
== ADPC ==
 +
This section is only available if '''ADPCM''' encoding is used.<br>
 +
The ADPC chunk contains 2 PCM history samples per channel for every entry in the table. (UInt16)<br>
 +
The number of samples per entry is specified in the HEAD section.<br>
 +
Each entry in the table contains the final two samples from the preceding block.<br>
 +
{| class="wikitable"
 +
! Offset !! Type !! Description
 +
|-
 +
| 0x00 || String || '''Section magic'''. ''ADPC'' in ASCII.
 +
|-
 +
| 0x04 || UInt32 || Size of the section.
 +
|}
 +
 
 +
== DATA ==
 
The '''DATA''' section contains the ADPCM data, the sounds the file makes.
 
The '''DATA''' section contains the ADPCM data, the sounds the file makes.
 
{| class="wikitable"
 
{| class="wikitable"
! Offset
+
! Offset !! Type !! Description
! Size
+
|-
! Description
 
 
|-
 
|-
| 0x00
+
| 0x00 || String || '''Section magic'''. ''DATA'' in ASCII.
| 4
 
| '''Section magic'''. ''DATA'' in ASCII.
 
 
|-
 
|-
| 0x04
+
| 0x04 || UInt16 || Size of the section.
| 4
 
| Length of section in bytes ('''L''' = Section Length).
 
 
|-
 
|-
| 0x08
+
| 0x08 || UInt32 || Offset to actual data.
| 4
+
|}
| {{Unknown-left|'''Unknown'''.}} Number of sub-sections in the ADPCM data?
+
Data needs to be 0x20 aligned and it's splitted in blocks.<br>
 +
Data stored with channel alternating every block unlike WAV format, where channels alternate every sample.<br>
 +
(Channel 0 Block 0 -> Channel 1 Block 0 -> Channel 0 Block 1 -> ...)
 +
 
 +
=== Data Reference ===
 +
The '''Data Reference''' structure is used to point to other data types.
 +
{| class="wikitable"
 
|-
 
|-
| 0x0b
+
! Offset !! Type !! Description
| 14
 
| Padding.
 
 
|-
 
|-
| 0x20
+
| 0x00 || Byte || '''Reference type'''. (0 = Address, 1 = Offset).
| '''L'''
 
| ADPCM data.
 
 
|-
 
|-
| 0x30 + '''L'''
+
| 0x01 || Byte || Data type.  
| 0A
 
| Padding.
 
 
|-
 
|-
| colspan=3 {{Unknown|End of section}}
+
| 0x02 || UInt16 || {{Unknown-left|Reserved.}}
 
|-
 
|-
| colspan=3 {{Unknown|End of file}}
+
| 0x04 || UInt32 || Value.
 
|}
 
|}
  
 
[[Category:File Format/Wii]]
 
[[Category:File Format/Wii]]

Latest revision as of 18:24, 8 June 2023

Overview

A BRSTM (Binary Revolution STreaM) is the music format used by Mario Kart Wii and other games such as Super Smash Bros. Brawl.

File Header

Offset Type Description
0x00 String File magic. RSTM in ASCII.
0x04 UInt16 Byte order mark (BOM): The value is always 0xFEFF. If value 0xFFFE is read, then the false endian is used. Mario Kart Wii uses nearly always big endian (bytes 0xFE,0xFF).
0x06 UInt16 Version. Always 0x0100.
0x08 UInt32 File size.
0x0c UInt16 Header size. Always 0x40.
0x0e UInt16 Section count. (Excluding HEAD).
0x10 UInt32 Offset to HEAD section.
0x14 UInt32 Size of HEAD section.
0x18 UInt32 Offset to ADPC section.
0x1c UInt32 Size of ADPC section.
0x20 UInt32 Offset to DATA section.
0x24 UInt32 Size of DATA section.

HEAD

Offsets are relative to 0x08 of this header.

Offset Type Description
0x00 String Section magic. Always HEAD in ASCII.
0x04 UInt32 Size of the section.
0x08 DataRef Reference to Stream Data Info.
0x10 DataRef Reference to Track Table.
0x18 DataRef Reference to Channel Table.

Stream Data Info

Offset Type Description
0x00 Byte Format.
Enum Description
0x0 PCM8
0x1 PCM16
0x2 ADPCM
0x01 Byte Loop Flag
0x02 Byte Number of channels
0x03 UInt24 Sample rate.
0x06 UInt16 Offset to block header? Always 0.
0x08 UInt32 Loop start sample.
0x0C UInt32 Loop end sample.
0x10 UInt32 Actual data offset.
0x14 UInt32 Block count.
0x18 UInt32 Block size.
0x1C UInt32 Block samples.
0x20 UInt32 Final block size.
0x24 UInt32 Final block samples.
0x28 UInt32 Final block size with padding.
0x2C UInt32 The interval (sample count) for writing data to the ADPC block.
0x30 UInt32 Size per channel for each interval where data is written to the ADPC.

Track Table

Offset Type Description
0x00 Byte N = Track count.
0x01 Byte Track Info type. (0 = Simple, 1 = Extended).
0x02 Byte[2] Padding.
0x04 DataRef[N] Reference to Track Info. Data type needs to match Track Info type.

Track Info (Simple)

With "simple" track info Track Volume is set to 127.

Offset Type Description
0x00 Byte N = Channel count.
0x01 Byte[N] Channel index info.

Track Info (Extended)

Offset Type Description
0x00 Byte Track volume (0-127).
0x01 Byte Pan (0-127).
0x02 Byte[2] Padding.
0x04 UInt32 Reserved.
0x08 Byte N = Channel count.
0x09 Byte[N] Channel index info.

Channel Table

Offset Type Description
0x00 Byte N = Channel count.
0x01 Byte[3] Padding.
0x04 DataRef[N] References to another DataRef referencing ADPCM Parameters Set.
Value of 0 is second DataRef means no data.

ADPCM Parameters Set

This data is only available if ADPCM encoding is used.

Offset Type Description
0x00 UInt16[16] Coefficients.
0x2C UInt16 Gain.
0x2E UInt16 Predictor + Scale.
0x30 UInt16 YN1. (Sample - 1).
0x32 UInt16 YN2. (Sample - 2).
0x34 UInt16 Loop Predictor + Scale.
0x36 UInt16 Loop YN1. (Sample - 1).
0x38 UInt16 Loop YN2. (Sample - 2).

ADPC

This section is only available if ADPCM encoding is used.
The ADPC chunk contains 2 PCM history samples per channel for every entry in the table. (UInt16)
The number of samples per entry is specified in the HEAD section.
Each entry in the table contains the final two samples from the preceding block.

Offset Type Description
0x00 String Section magic. ADPC in ASCII.
0x04 UInt32 Size of the section.

DATA

The DATA section contains the ADPCM data, the sounds the file makes.

Offset Type Description
0x00 String Section magic. DATA in ASCII.
0x04 UInt16 Size of the section.
0x08 UInt32 Offset to actual data.

Data needs to be 0x20 aligned and it's splitted in blocks.
Data stored with channel alternating every block unlike WAV format, where channels alternate every sample.
(Channel 0 Block 0 -> Channel 1 Block 0 -> Channel 0 Block 1 -> ...)

Data Reference

The Data Reference structure is used to point to other data types.

Offset Type Description
0x00 Byte Reference type. (0 = Address, 1 = Offset).
0x01 Byte Data type.
0x02 UInt16 Reserved.
0x04 UInt32 Value.