Difference between revisions of "BCSTM"

From 3dbrew
Jump to navigation Jump to search
 
(6 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).
 
The structure is almost exact to the CTR Wave Format (CWAV).
 
  
 
=== Overview ===
 
=== Overview ===
  
The structure of the CSTM is almost exactly the CWAV, except a few differences. The formats can be easily converted between eachother.
+
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.
  
=== Format ===
+
=== 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"
 +
|-
 +
! OFFSET !! SIZE !!  DESCRIPTION
 +
|-
 +
| 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"
 +
|-
 +
! 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 ====
  
=== CSTM Header ===
+
{| 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"
 
{| class="wikitable" border="1"
Line 18: Line 181:
 
! OFFSET !! SIZE !!  DESCRIPTION
 
! OFFSET !! SIZE !!  DESCRIPTION
 
|-
 
|-
| 0x000 || 4 || MAGIC "CSTM"
+
| 0x000 || 4 || Count
 
|-
 
|-
| 0x004 || 2 || Endianess (0xFEFF=LE / 0xFFFE=BE)
+
| 0x004 || Count || Elements
 +
|}
 +
 
 +
==== Channel Info ====
 +
 
 +
{| class="wikitable" border="1"
 
|-
 
|-
| 0x00C || 4 || Filesize
+
! OFFSET !! SIZE !!  DESCRIPTION
 +
|-
 +
| 0x000 || 8 || ADPCM Info [[#Reference|Reference]]  (Offset relative to this field)
 
|}
 
|}
  
=== INFO Header ===
+
===== DSP ADPCM Info =====
  
 
{| class="wikitable" border="1"
 
{| class="wikitable" border="1"
Line 31: Line 201:
 
! OFFSET !! SIZE !!  DESCRIPTION
 
! OFFSET !! SIZE !!  DESCRIPTION
 
|-
 
|-
| 0x000 || 4 || Magic "INFO"
+
| 0x000 || 32 || [[#DSP ADPCM Param|Param]]
 
|-
 
|-
| 0x004 || 4 || Length
+
| 0x020 || 6 || [[#DSP ADPCM Context|Context]]
 
|-
 
|-
| 0x020 || 1 || Type (00 = PCM8, 01 = PCM16, 02 = DSPADPCM)
+
| 0x026 || 6 || Loop [[#DSP ADPCM Context|Context]]
 
|-
 
|-
| 0x021 || 1 || Loop Flag
+
| 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
 
|-
 
|-
| 0x022 || 2 || Total Channels
+
| 0x001 || 1 || Reserved
 
|-
 
|-
| 0x024 || 4 || Sample Rate
+
| 0x002 || 2 || Previous Sample
 
|-
 
|-
| 0x028 || 4 || Unknown
+
| 0x004 || 2 || Second Previous Sample
 +
|}
 +
 
 +
===== IMA ADPCM Info =====
 +
 
 +
{| class="wikitable" border="1"
 
|-
 
|-
| 0x02C || 4 || Total samples
+
! OFFSET !! SIZE !!  DESCRIPTION
 
|-
 
|-
| 0x030 || X || The Channels' Data Pointers
+
| 0x000 || 4 || [[#IMA ADPCM Context|Context]]
 
|-
 
|-
| X || X || The Channels' Data
+
| 0x004 || 4 || Loop [[#IMA ADPCM Context|Context]]
 
|}
 
|}
  
=== DATA Header ===
+
====== IMA ADPCM Context ======
  
 
{| class="wikitable" border="1"
 
{| class="wikitable" border="1"
Line 58: Line 251:
 
! OFFSET !! SIZE !!  DESCRIPTION
 
! OFFSET !! SIZE !!  DESCRIPTION
 
|-
 
|-
| 0x000 || 4 || Magic "DATA"
+
| 0x000 || 2 || Data
 
|-
 
|-
| 0x004 || 4 || Length
+
| 0x002 || 1 || Table Index
 
|-
 
|-
| 0x020 || X || Start of Channel Data
+
| 0x003 || 1 || Padding
 
|}
 
|}
  
Unlike CWAV, if there are 2 channels in a CSTM they alternate every 0x2000 bytes of the DATA partition starting at 0x20.
+
=== Seek Block ===
  
Additionally it introduces a new partition called SEEK which comes right before DATA, so a CSTM would be ordered like this:
+
{| 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.
  
* CSTM Header
+
=== Reference Table ===
* INFO Partition
 
* SEEK Partition
 
* DATA Partition
 
  
By default this means that 0x24-0x2B in the CSTM Partition is the SEEK position and length respectively, and DATA position and length follows it (in a CWAV 0x24-0x2B is usually the DATA position and length).
+
{| 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
 +
|}
  
=== SEEK ===
+
=== Reference ===
  
 
{| class="wikitable" border="1"
 
{| class="wikitable" border="1"
Line 82: Line 312:
 
! OFFSET !! SIZE !!  DESCRIPTION
 
! OFFSET !! SIZE !!  DESCRIPTION
 
|-
 
|-
| 0x000 || 4 || Magic (SEEK)
+
| 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]]
 
|-
 
|-
| 0x004 || 4 || Length
+
| 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: