Difference between revisions of "BCSTM"
Jump to navigation
Jump to search
(→Tools) |
|||
(10 intermediate revisions by 3 users not shown) | |||
Line 1: | Line 1: | ||
[[Category:File formats]] | [[Category:File formats]] | ||
This document is about the format of CTR Streams (CSTM). | This document is about the format of CTR Streams (CSTM). | ||
− | |||
− | |||
=== Overview === | === Overview === | ||
− | The structure of | + | The structure is similar to that of a [[BCWAV]], with a few differences, such as its different INFO block format, the addition of a SEEK block, and the organization of the DATA block samples into blocks. |
These files are either found in rom:\sound\stream\ or they can be inside of a CSAR. | These files are either found in rom:\sound\stream\ or they can be inside of a CSAR. | ||
− | === | + | === Header === |
+ | |||
+ | {| class="wikitable" border="1" | ||
+ | |- | ||
+ | ! OFFSET !! SIZE !! DESCRIPTION | ||
+ | |- | ||
+ | | 0x000 || 4 || Magic (CSTM) | ||
+ | |- | ||
+ | | 0x004 || 2 || Endianness (0xFEFF = little, 0xFFFE = big) | ||
+ | |- | ||
+ | | 0x006 || 2 || Header Size (0x40 due to [[#Info Block|Info Block]] alignment) | ||
+ | |- | ||
+ | | 0x008 || 4 || Version (0x02000000) | ||
+ | |- | ||
+ | | 0x00C || 4 || File Size | ||
+ | |- | ||
+ | | 0x010 || 2 || Number of Blocks (3) | ||
+ | |- | ||
+ | | 0x012 || 2 || Reserved | ||
+ | |- | ||
+ | | 0x014 || 12 || [[#Info Block|Info Block]] [[#Sized Reference|Sized Reference]] (Offset relative to start of file) | ||
+ | |- | ||
+ | | 0x020 || 12 || [[#Seek Block|Seek Block]] [[#Sized Reference|Sized Reference]] (Offset relative to start of file) | ||
+ | |- | ||
+ | | 0x02C || 12 || [[#Data Block|Data Block]] [[#Sized Reference|Sized Reference]] (Offset relative to start of file) | ||
+ | |} | ||
− | + | === Block Header === | |
{| class="wikitable" border="1" | {| class="wikitable" border="1" | ||
Line 18: | Line 41: | ||
! OFFSET !! SIZE !! DESCRIPTION | ! OFFSET !! SIZE !! DESCRIPTION | ||
|- | |- | ||
− | | 0x000 || 4 || | + | | 0x000 || 4 || Magic |
|- | |- | ||
+ | | 0x004 || 4 || Size | ||
|} | |} | ||
− | + | ==== Block Types ==== | |
+ | |||
+ | {| class="wikitable" border="1" | ||
+ | |- | ||
+ | ! MAGIC !! TYPE | ||
+ | |- | ||
+ | | INFO || [[#Info Block|Info Block]] | ||
+ | |- | ||
+ | | SEEK || [[#Seek Block|Seek Block]] | ||
+ | |- | ||
+ | | DATA || [[#Data Block|Data Block]] | ||
+ | |} | ||
+ | |||
+ | === Info Block === | ||
+ | |||
+ | {| class="wikitable" border="1" | ||
+ | |- | ||
+ | ! OFFSET !! SIZE !! DESCRIPTION | ||
+ | |- | ||
+ | | 0x000 || 8 || [[#Block Header|Block Header]] | ||
+ | |- | ||
+ | | 0x008 || 8 || [[#Stream Info|Stream Info]] [[#Reference|Reference]] (Offset relative to this field) | ||
+ | |- | ||
+ | | 0x010 || 8 || [[#Track Info|Track Info]] [[#Reference Table|Reference Table]] [[#Reference|Reference]] (Offset relative to [[#Stream Info|Stream Info]] [[#Reference|Reference]] field) | ||
+ | |- | ||
+ | | 0x018 || 8 || [[#Channel Info|Channel Info]] [[#Reference Table|Reference Table]] [[#Reference|Reference]] (Offset relative to [[#Stream Info|Stream Info]] [[#Reference|Reference]] field) | ||
+ | |- | ||
+ | | 0x020 || 56 || [[#Stream Info|Stream Info]] | ||
+ | |- | ||
+ | | 0x058 || X || [[#Track Info|Track Info]] [[#Reference Table|Reference Table]] | ||
+ | |- | ||
+ | | X || X || [[#Channel Info|Channel Info]] [[#Reference Table|Reference Table]] | ||
+ | |- | ||
+ | | X || X || [[#Track Info|Track Info]] Entries | ||
+ | |- | ||
+ | | X || X || [[#Channel Info|Channel Info]] Entries | ||
+ | |} | ||
− | + | If encoding is DSP ADPCM: | |
− | |||
− | |||
− | |||
− | + | {| class="wikitable" border="1" | |
+ | |- | ||
+ | ! OFFSET !! SIZE !! DESCRIPTION | ||
+ | |- | ||
+ | | X || X || [[#DSP ADPCM Info|DSP ADPCM Info]] Entries | ||
+ | |} | ||
− | + | If encoding is IMA ADPCM: | |
{| class="wikitable" border="1" | {| class="wikitable" border="1" | ||
Line 37: | Line 99: | ||
! OFFSET !! SIZE !! DESCRIPTION | ! OFFSET !! SIZE !! DESCRIPTION | ||
|- | |- | ||
− | | | + | | X || X || [[#IMA ADPCM Info|IMA ADPCM Info]] Entries |
+ | |} | ||
+ | |||
+ | The info block is aligned to 0x20 bytes. | ||
+ | |||
+ | ==== Encoding ==== | ||
+ | |||
+ | {| class="wikitable" border="1" | ||
+ | |- | ||
+ | ! VALUE !! DESCRIPTION | ||
+ | |- | ||
+ | | 0 || PCM8 | ||
|- | |- | ||
− | | | + | | 1 || PCM16 |
+ | |- | ||
+ | | 2 || DSP ADPCM | ||
+ | |- | ||
+ | | 3 || IMA ADPCM | ||
|} | |} | ||
+ | |||
+ | ==== Stream Info ==== | ||
+ | |||
+ | {| class="wikitable" border="1" | ||
+ | |- | ||
+ | ! OFFSET !! SIZE !! DESCRIPTION | ||
+ | |- | ||
+ | | 0x000 || 1 || [[#Encoding|Encoding]] | ||
+ | |- | ||
+ | | 0x001 || 1 || Loop (0 = don't loop, 1 = loop) | ||
+ | |- | ||
+ | | 0x002 || 1 || Channel Count | ||
+ | |- | ||
+ | | 0x003 || 1 || Padding | ||
+ | |- | ||
+ | | 0x004 || 4 || Sample Rate | ||
+ | |- | ||
+ | | 0x008 || 4 || Loop Start Frame | ||
+ | |- | ||
+ | | 0x00C || 4 || Loop End Frame | ||
+ | |- | ||
+ | | 0x010 || 4 || Sample Block Count | ||
+ | |- | ||
+ | | 0x014 || 4 || Sample Block Size | ||
+ | |- | ||
+ | | 0x018 || 4 || Sample Block Sample Count | ||
+ | |- | ||
+ | | 0x01C || 4 || Last Sample Block Size | ||
+ | |- | ||
+ | | 0x020 || 4 || Last Sample Block Sample Count | ||
+ | |- | ||
+ | | 0x024 || 4 || Last Sample Block Padded Size | ||
+ | |- | ||
+ | | 0x028 || 4 || Seek Data Size | ||
+ | |- | ||
+ | | 0x02C || 4 || Seek Interval Sample Count | ||
+ | |- | ||
+ | | 0x030 || 8 || Sample Data [[#Reference|Reference]] (Offset relative to [[#Data Block|Data Block]] Data field) | ||
+ | |} | ||
+ | |||
+ | ==== Track Info ==== | ||
+ | |||
+ | {| class="wikitable" border="1" | ||
+ | |- | ||
+ | ! OFFSET !! SIZE !! DESCRIPTION | ||
+ | |- | ||
+ | | 0x000 || 1 || Volume | ||
+ | |- | ||
+ | | 0x001 || 1 || Pan | ||
+ | |- | ||
+ | | 0x002 || 2 || Padding | ||
+ | |- | ||
+ | | 0x004 || 8 || Channel Index [[#Byte Table|Byte Table]] [[#Reference|Reference]] (Offset relative to Volume field) | ||
+ | |- | ||
+ | | 0x00C || X || Channel Index [[#Byte Table|Byte Table]] (Padded to 4 bytes) | ||
+ | |} | ||
+ | |||
+ | ===== Byte Table ===== | ||
+ | |||
+ | {| class="wikitable" border="1" | ||
+ | |- | ||
+ | ! OFFSET !! SIZE !! DESCRIPTION | ||
+ | |- | ||
+ | | 0x000 || 4 || Count | ||
+ | |- | ||
+ | | 0x004 || Count || Elements | ||
+ | |} | ||
+ | |||
+ | ==== Channel Info ==== | ||
+ | |||
+ | {| class="wikitable" border="1" | ||
+ | |- | ||
+ | ! OFFSET !! SIZE !! DESCRIPTION | ||
+ | |- | ||
+ | | 0x000 || 8 || ADPCM Info [[#Reference|Reference]] (Offset relative to this field) | ||
+ | |} | ||
+ | |||
+ | ===== DSP ADPCM Info ===== | ||
+ | |||
+ | {| class="wikitable" border="1" | ||
+ | |- | ||
+ | ! OFFSET !! SIZE !! DESCRIPTION | ||
+ | |- | ||
+ | | 0x000 || 32 || [[#DSP ADPCM Param|Param]] | ||
+ | |- | ||
+ | | 0x020 || 6 || [[#DSP ADPCM Context|Context]] | ||
+ | |- | ||
+ | | 0x026 || 6 || Loop [[#DSP ADPCM Context|Context]] | ||
+ | |- | ||
+ | | 0x02C || 2 || Padding | ||
+ | |} | ||
+ | |||
+ | ====== DSP ADPCM Param ====== | ||
+ | |||
+ | {| class="wikitable" border="1" | ||
+ | |- | ||
+ | ! OFFSET !! SIZE !! DESCRIPTION | ||
+ | |- | ||
+ | | 0x000 || 32 || 16-bit Coefficients | ||
+ | |} | ||
+ | |||
+ | ====== DSP ADPCM Context ====== | ||
+ | |||
+ | {| class="wikitable" border="1" | ||
+ | |- | ||
+ | ! OFFSET !! SIZE !! DESCRIPTION | ||
+ | |- | ||
+ | | 0x000 || 1 || 4-bit Predictor + 4-bit Scale | ||
+ | |- | ||
+ | | 0x001 || 1 || Reserved | ||
+ | |- | ||
+ | | 0x002 || 2 || Previous Sample | ||
+ | |- | ||
+ | | 0x004 || 2 || Second Previous Sample | ||
+ | |} | ||
+ | |||
+ | ===== IMA ADPCM Info ===== | ||
+ | |||
+ | {| class="wikitable" border="1" | ||
+ | |- | ||
+ | ! OFFSET !! SIZE !! DESCRIPTION | ||
+ | |- | ||
+ | | 0x000 || 4 || [[#IMA ADPCM Context|Context]] | ||
+ | |- | ||
+ | | 0x004 || 4 || Loop [[#IMA ADPCM Context|Context]] | ||
+ | |} | ||
+ | |||
+ | ====== IMA ADPCM Context ====== | ||
+ | |||
+ | {| class="wikitable" border="1" | ||
+ | |- | ||
+ | ! OFFSET !! SIZE !! DESCRIPTION | ||
+ | |- | ||
+ | | 0x000 || 2 || Data | ||
+ | |- | ||
+ | | 0x002 || 1 || Table Index | ||
+ | |- | ||
+ | | 0x003 || 1 || Padding | ||
+ | |} | ||
+ | |||
+ | === Seek Block === | ||
+ | |||
+ | {| class="wikitable" border="1" | ||
+ | |- | ||
+ | ! OFFSET !! SIZE !! DESCRIPTION | ||
+ | |- | ||
+ | | 0x000 || 8 || [[#Block Header|Block Header]] | ||
+ | |- | ||
+ | | 0x008 || [[#Block Header|Block Header]] Size Value - 8 || Data | ||
+ | |} | ||
+ | |||
+ | The seek block is aligned to 0x20 bytes. | ||
+ | |||
+ | === Data Block === | ||
+ | |||
+ | {| class="wikitable" border="1" | ||
+ | |- | ||
+ | ! OFFSET !! SIZE !! DESCRIPTION | ||
+ | |- | ||
+ | | 0x000 || 8 || [[#Block Header|Block Header]] | ||
+ | |- | ||
+ | | 0x008 || [[#Block Header|Block Header]] Size Value - 8 || Data | ||
+ | |} | ||
+ | |||
+ | The data block is aligned to 0x20 bytes, as well as the data field's actual sample data. | ||
+ | |||
+ | === Reference Table === | ||
+ | |||
+ | {| class="wikitable" border="1" | ||
+ | |- | ||
+ | ! OFFSET !! SIZE !! DESCRIPTION | ||
+ | |- | ||
+ | | 0x000 || 4 || Count | ||
+ | |- | ||
+ | | 0x004 || Count * 8 || [[#Reference|References]] (Offsets relative to Count field) | ||
+ | |} | ||
+ | |||
+ | === Sized Reference === | ||
+ | |||
+ | {| class="wikitable" border="1" | ||
+ | |- | ||
+ | ! OFFSET !! SIZE !! DESCRIPTION | ||
+ | |- | ||
+ | | 0x000 || 8 || [[#Reference|Reference]] | ||
+ | |- | ||
+ | | 0x008 || 4 || Size | ||
+ | |} | ||
+ | |||
+ | === Reference === | ||
+ | |||
+ | {| class="wikitable" border="1" | ||
+ | |- | ||
+ | ! OFFSET !! SIZE !! DESCRIPTION | ||
+ | |- | ||
+ | | 0x000 || 2 || Type ID | ||
+ | |- | ||
+ | | 0x002 || 2 || Padding | ||
+ | |- | ||
+ | | 0x004 || 4 || Offset ("null" = 0xFFFFFFFF) | ||
+ | |} | ||
+ | |||
+ | ==== Reference Types ==== | ||
+ | |||
+ | {| class="wikitable" border="1" | ||
+ | |- | ||
+ | ! ID !! TYPE | ||
+ | |- | ||
+ | | 0x0100 || [[#Byte Table|Byte Table]] | ||
+ | |- | ||
+ | | 0x0101 || [[#Reference Table|Reference Table]] | ||
+ | |- | ||
+ | | 0x0300 || [[#DSP ADPCM Info|DSP ADPCM Info]] | ||
+ | |- | ||
+ | | 0x0301 || [[#IMA ADPCM Info|IMA ADPCM Info]] | ||
+ | |- | ||
+ | | 0x1F00 || [[#Data_Block|Sample Data]] | ||
+ | |- | ||
+ | | 0x4000 || [[#Info Block|Info Block]] | ||
+ | |- | ||
+ | | 0x4001 || [[#Seek Block|Seek Block]] | ||
+ | |- | ||
+ | | 0x4002 || [[#Data Block|Data Block]] | ||
+ | |- | ||
+ | | 0x4100 || [[#Stream Info|Stream Info]] | ||
+ | |- | ||
+ | | 0x4101 || [[#Track Info|Track Info]] | ||
+ | |- | ||
+ | | 0x4102 || [[#Channel Info|Channel Info]] | ||
+ | |} | ||
+ | |||
+ | |||
+ | ==Tools== | ||
+ | The following tools can play BCSTMs and convert them to other formats: | ||
+ | * [https://gota7.github.io/Citric-Composer/ Isabelle Sound Editor] | ||
+ | * vgmstream | ||
+ | * Every File Explorer |
Latest revision as of 23:30, 9 May 2018
This document is about the format of CTR Streams (CSTM).
Overview[edit]
The structure is similar to that of a BCWAV, with a few differences, such as its different INFO block format, the addition of a SEEK block, and the organization of the DATA block samples into blocks.
These files are either found in rom:\sound\stream\ or they can be inside of a CSAR.
Header[edit]
OFFSET | SIZE | DESCRIPTION |
---|---|---|
0x000 | 4 | Magic (CSTM) |
0x004 | 2 | Endianness (0xFEFF = little, 0xFFFE = big) |
0x006 | 2 | Header Size (0x40 due to Info Block alignment) |
0x008 | 4 | Version (0x02000000) |
0x00C | 4 | File Size |
0x010 | 2 | Number of Blocks (3) |
0x012 | 2 | Reserved |
0x014 | 12 | Info Block Sized Reference (Offset relative to start of file) |
0x020 | 12 | Seek Block Sized Reference (Offset relative to start of file) |
0x02C | 12 | Data Block Sized Reference (Offset relative to start of file) |
Block Header[edit]
OFFSET | SIZE | DESCRIPTION |
---|---|---|
0x000 | 4 | Magic |
0x004 | 4 | Size |
Block Types[edit]
MAGIC | TYPE |
---|---|
INFO | Info Block |
SEEK | Seek Block |
DATA | Data Block |
Info Block[edit]
OFFSET | SIZE | DESCRIPTION |
---|---|---|
0x000 | 8 | Block Header |
0x008 | 8 | Stream Info Reference (Offset relative to this field) |
0x010 | 8 | Track Info Reference Table Reference (Offset relative to Stream Info Reference field) |
0x018 | 8 | Channel Info Reference Table Reference (Offset relative to Stream Info Reference field) |
0x020 | 56 | Stream Info |
0x058 | X | Track Info Reference Table |
X | X | Channel Info Reference Table |
X | X | Track Info Entries |
X | X | Channel Info Entries |
If encoding is DSP ADPCM:
OFFSET | SIZE | DESCRIPTION |
---|---|---|
X | X | DSP ADPCM Info Entries |
If encoding is IMA ADPCM:
OFFSET | SIZE | DESCRIPTION |
---|---|---|
X | X | IMA ADPCM Info Entries |
The info block is aligned to 0x20 bytes.
Encoding[edit]
VALUE | DESCRIPTION |
---|---|
0 | PCM8 |
1 | PCM16 |
2 | DSP ADPCM |
3 | IMA ADPCM |
Stream Info[edit]
OFFSET | SIZE | DESCRIPTION |
---|---|---|
0x000 | 1 | Encoding |
0x001 | 1 | Loop (0 = don't loop, 1 = loop) |
0x002 | 1 | Channel Count |
0x003 | 1 | Padding |
0x004 | 4 | Sample Rate |
0x008 | 4 | Loop Start Frame |
0x00C | 4 | Loop End Frame |
0x010 | 4 | Sample Block Count |
0x014 | 4 | Sample Block Size |
0x018 | 4 | Sample Block Sample Count |
0x01C | 4 | Last Sample Block Size |
0x020 | 4 | Last Sample Block Sample Count |
0x024 | 4 | Last Sample Block Padded Size |
0x028 | 4 | Seek Data Size |
0x02C | 4 | Seek Interval Sample Count |
0x030 | 8 | Sample Data Reference (Offset relative to Data Block Data field) |
Track Info[edit]
OFFSET | SIZE | DESCRIPTION |
---|---|---|
0x000 | 1 | Volume |
0x001 | 1 | Pan |
0x002 | 2 | Padding |
0x004 | 8 | Channel Index Byte Table Reference (Offset relative to Volume field) |
0x00C | X | Channel Index Byte Table (Padded to 4 bytes) |
Byte Table[edit]
OFFSET | SIZE | DESCRIPTION |
---|---|---|
0x000 | 4 | Count |
0x004 | Count | Elements |
Channel Info[edit]
OFFSET | SIZE | DESCRIPTION |
---|---|---|
0x000 | 8 | ADPCM Info Reference (Offset relative to this field) |
DSP ADPCM Info[edit]
OFFSET | SIZE | DESCRIPTION |
---|---|---|
0x000 | 32 | Param |
0x020 | 6 | Context |
0x026 | 6 | Loop Context |
0x02C | 2 | Padding |
DSP ADPCM Param[edit]
OFFSET | SIZE | DESCRIPTION |
---|---|---|
0x000 | 32 | 16-bit Coefficients |
DSP ADPCM Context[edit]
OFFSET | SIZE | DESCRIPTION |
---|---|---|
0x000 | 1 | 4-bit Predictor + 4-bit Scale |
0x001 | 1 | Reserved |
0x002 | 2 | Previous Sample |
0x004 | 2 | Second Previous Sample |
IMA ADPCM Info[edit]
OFFSET | SIZE | DESCRIPTION |
---|---|---|
0x000 | 4 | Context |
0x004 | 4 | Loop Context |
IMA ADPCM Context[edit]
OFFSET | SIZE | DESCRIPTION |
---|---|---|
0x000 | 2 | Data |
0x002 | 1 | Table Index |
0x003 | 1 | Padding |
Seek Block[edit]
OFFSET | SIZE | DESCRIPTION |
---|---|---|
0x000 | 8 | Block Header |
0x008 | Block Header Size Value - 8 | Data |
The seek block is aligned to 0x20 bytes.
Data Block[edit]
OFFSET | SIZE | DESCRIPTION |
---|---|---|
0x000 | 8 | Block Header |
0x008 | Block Header Size Value - 8 | Data |
The data block is aligned to 0x20 bytes, as well as the data field's actual sample data.
Reference Table[edit]
OFFSET | SIZE | DESCRIPTION |
---|---|---|
0x000 | 4 | Count |
0x004 | Count * 8 | References (Offsets relative to Count field) |
Sized Reference[edit]
OFFSET | SIZE | DESCRIPTION |
---|---|---|
0x000 | 8 | Reference |
0x008 | 4 | Size |
Reference[edit]
OFFSET | SIZE | DESCRIPTION |
---|---|---|
0x000 | 2 | Type ID |
0x002 | 2 | Padding |
0x004 | 4 | Offset ("null" = 0xFFFFFFFF) |
Reference Types[edit]
ID | TYPE |
---|---|
0x0100 | Byte Table |
0x0101 | Reference Table |
0x0300 | DSP ADPCM Info |
0x0301 | IMA ADPCM Info |
0x1F00 | Sample Data |
0x4000 | Info Block |
0x4001 | Seek Block |
0x4002 | Data Block |
0x4100 | Stream Info |
0x4101 | Track Info |
0x4102 | Channel Info |
Tools[edit]
The following tools can play BCSTMs and convert them to other formats:
- Isabelle Sound Editor
- vgmstream
- Every File Explorer