Changes

Jump to navigation Jump to search
4,128 bytes added ,  04:14, 15 November 2019
Update names
Line 2: Line 2:  
== Overview ==
 
== Overview ==
   −
The BCSAR (CTR Sound ARchive) format is the 3DS's equivalent of the Wii's BRSAR  format. They're not the same structures, though, but they do have the same purpose.
+
The BCSAR (Binary CTR Sound ARchive) format is the 3DS's equivalent of the Wii's BRSAR  format. They're not the same structures, though, but they do have the same purpose.
   −
BCSAR are located in the RomFS, this is usually stored under "romfs:/sound/<name>.bcsar". This contains various audio formats, such as CSTM, CWSD, and CWAV.
+
BCSAR are located in the RomFS, this is usually stored under "romfs:/sound/<name>.bcsar". This contains various audio formats, such as CSTM, CWSD, CSEQ, and CWAV.
    
== BCSAR Header ==
 
== BCSAR Header ==
Line 23: Line 23:  
|-
 
|-
 
|  0x6
 
|  0x6
0x4
+
0x2
 
|  Length of BCSAR header
 
|  Length of BCSAR header
 
|-
 
|-
0xA
+
0x8
0x2
+
0x4
 
|  Version
 
|  Version
 
|-
 
|-
Line 40: Line 40:  
|  0x14
 
|  0x14
 
|  0x4
 
|  0x4
Partition header length [same for each partition? (ie STRG,INFO,and FILE header lengths)]
+
STRG partition reference ID? (Always 0x2000)
 
|-
 
|-
 
|  0x18
 
|  0x18
Line 52: Line 52:  
|  0x20
 
|  0x20
 
|  0x4
 
|  0x4
Unknown (always 0x01200000?)
+
INFO partition reference ID? (Always 0x2001)
 
|-
 
|-
 
|  0x24
 
|  0x24
Line 61: Line 61:  
|  0x4
 
|  0x4
 
|  Length of INFO partition
 
|  Length of INFO partition
 +
|-
 +
|  0x2C
 +
|  0x4
 +
|  Main FILE partition reference ID? (Always 0x2002)
 
|-
 
|-
 
|  0x30
 
|  0x30
Line 86: Line 90:  
STRG contains the names of the audio files in the BCSAR.
 
STRG contains the names of the audio files in the BCSAR.
   −
Header:
+
==== Header ====
 
   
{| class="wikitable" border="1"
 
{| class="wikitable" border="1"
 
|-
 
|-
Line 104: Line 107:  
|  0x8
 
|  0x8
 
|  0x4
 
|  0x4
Count of audio names (since each file should have a name you could also say this is essentially a file count)
+
String table type magic (always 0x2400)
 +
|-
 +
|  0xC
 +
|  0x4
 +
|  This + 8 points to the string table (always 0x10)
 +
|-
 +
|  0x10
 +
|  0x4
 +
|  String table lookup type magic (always 0x2401)
 +
|-
 +
|  0x14
 +
|  0x4
 +
|  This + 8 points to the string lookup table
 +
|-
 +
|  0x18
 +
|  0x4
 +
|  Filename count
 +
|-
 +
|  0x1C
 +
|  0xC * count
 +
|  String offset table
 
|-
 
|-
 
|}
 
|}
   −
Then for each name:
+
==== String offset table entry ====
    
{| class="wikitable" border="1"
 
{| class="wikitable" border="1"
Line 118: Line 141:  
|  0x0
 
|  0x0
 
|  0x4
 
|  0x4
|  Type of the file...?
+
|  Type of the node (should be 0x1F01)
 
|-
 
|-
 
|  0x4
 
|  0x4
 
|  0x4
 
|  0x4
|  Offset of the filename...?
+
|  Offset to data from the end of the STRG header (sizeof 0x18)
 
|-
 
|-
 
|  0x8
 
|  0x8
 
|  0x4
 
|  0x4
Size of the filename
+
Length of the data buffer (includes NUL terminator)
 
|-
 
|-
 
|}
 
|}
 +
 
Then every filename is rawly setted. You can set up a dictionary that contains, using a simple counter, the size of every filename in order. Then, using the same type of counter, get the values of the size of the filename in a correct order.
 
Then every filename is rawly setted. You can set up a dictionary that contains, using a simple counter, the size of every filename in order. Then, using the same type of counter, get the values of the size of the filename in a correct order.
 +
 +
==== String lookup table ====
 +
 +
===== Header =====
 +
 +
{| class="wikitable" border="1"
 +
|-
 +
!  OFFSET
 +
!  SIZE
 +
!  DESCRIPTION
 +
|-
 +
|  0x0
 +
|  0x4
 +
|  Index of the root entry
 +
|-
 +
|  0x4
 +
|  0x4
 +
|  Entry count
 +
|-
 +
|  0x8
 +
|  0x14 * count
 +
|  Lookup entry
 +
|-
 +
|}
 +
 +
===== Entry =====
 +
 +
{| class="wikitable" border="1"
 +
|-
 +
!  OFFSET
 +
!  SIZE
 +
!  DESCRIPTION
 +
|-
 +
|  0x0
 +
|  0x2
 +
|  Nonzero if contains data
 +
|-
 +
|  0x2
 +
|  0x2
 +
|  Bit test condition (index = (this >> 3), bit = (~this & 7)), -1 if unused
 +
|-
 +
|  0x4
 +
|  0x4
 +
|  Fail condition leaf index (-1 if unused)
 +
|-
 +
|  0x8
 +
|  0x4
 +
|  Success condition leaf index (-1 if unused)
 +
|-
 +
|  0xC
 +
|  0x4
 +
|  String lookup table index (-1 if unused)
 +
|-
 +
|  0x10
 +
|  0x3
 +
|  3-byte Resource ID, Little Endian (-1 if unused)
 +
|-
 +
|  0x13
 +
|  0x1
 +
|  Resource type (01=sound, 02=sound list, 03=sound bank, 04=sound player name?, 06=sound group, FF=unused)
 +
|-
 +
|}
    
=== INFO ===
 
=== INFO ===
Line 136: Line 222:     
For now I only know some information in the header for this partition, but I'm working on figuring the rest out.
 
For now I only know some information in the header for this partition, but I'm working on figuring the rest out.
 +
 +
==== Header ====
    
{| class="wikitable" border="1"
 
{| class="wikitable" border="1"
Line 150: Line 238:  
|  0x4
 
|  0x4
 
|  Length of INFO partition (also in CSAR header)
 
|  Length of INFO partition (also in CSAR header)
 +
|-
 +
|  0x8
 +
|  0x4
 +
|  Audio Table Reference ID (0x2100)
 +
|-
 +
|  0xC
 +
|  0x4
 +
|  This + 8 points to the Audio Table
 +
|-
 +
|  0x10
 +
|  0x4
 +
|  Set Table Reference ID (0x2104)
 +
|-
 +
|  0x14
 +
|  0x4
 +
|  This + 8 points to the Set Table
 +
|-
 +
|  0x18
 +
|  0x4
 +
|  Bank Table Reference ID (0x2101)
 +
|-
 +
|  0x1C
 +
|  0x4
 +
|  This + 8 points to the Bank Table
 +
|-
 +
|  0x20
 +
|  0x4
 +
|  WAV Archive Table Reference ID (0x2103)
 +
|-
 +
|  0x24
 +
|  0x4
 +
|  This + 8 points to the WAV Archive Table
 +
|-
 +
|  0x28
 +
|  0x4
 +
|  Group Table Reference ID (0x2105)
 +
|-
 +
|  0x2C
 +
|  0x4
 +
|  This + 8 points to the Group Table
 +
|-
 +
|  0x30
 +
|  0x4
 +
|  Player Table Reference ID (0x2102)
 +
|-
 +
|  0x34
 +
|  0x4
 +
|  This + 8 points to Player Table
 +
|-
 +
|  0x38
 +
|  0x4
 +
|  FILE Table Reference ID (0x2106)
 +
|-
 +
|  0x3C
 +
|  0x4
 +
|  This + 8 points to the FILE Table
 +
|-
 +
|  0x40
 +
|  0x4
 +
|  Unknown Table Reference ID (0x220B)
 +
|-
 +
|  0x44
 +
|  0x4
 +
|  This + 8 points to unknown
 +
|-
 +
|}
 +
 +
==== Blocks ====
 +
 +
Every offset in the header points to data similar to this:
 +
* 4byte length
 +
* length array of the below struct
 +
** u32 type
 +
** u32 offset relative to the address of the length field (beginning of the block)
 +
 +
The data the offset points to is dependent on the type of the above struct:
 +
 +
===== 0x2200 =====
 +
 +
{| class="wikitable" border="1"
 +
|-
 +
!  OFFSET
 +
!  SIZE
 +
!  DESCRIPTION
 +
|-
 +
|  0x0
 +
|  0x4
 +
|  Unknown
 +
|-
 +
|  0x4
 +
|  0x4
 +
|  Sound player ID
 +
|-
 +
|  0x8
 +
|  0x4
 +
|  Unknown
 +
|-
 +
|  0xC
 +
|  0x4
 +
|  Type of the extended info
 +
|-
 +
|  0x10
 +
|  0x4
 +
|  Offset to extended info *relative to the beginning of this struct*
 +
|-
 +
|  0x14
 +
|  ???
 +
|  Unknown...
 +
|-
 +
|}
 +
 +
===== 0x2204 =====
 +
 +
{| class="wikitable" border="1"
 +
|-
 +
!  OFFSET
 +
!  SIZE
 +
!  DESCRIPTION
 +
|-
 +
|  0x0
 +
|  0x4
 +
|  First Sound ID in this sequence set
 +
|-
 +
|  0x4
 +
|  0x4
 +
|  Last Sound ID in this sequence set
 +
|-
 +
|  0x8
 +
|  0x4
 +
|  Type of the extended info
 +
|-
 +
|  0xC
 +
|  0x4
 +
|  Offset to extended info *relative to the beginning of this struct*
 +
|-
 +
|  0x10
 +
|  0x4
 +
|  Type of the extended info
 +
|-
 +
|  0x14
 +
|  0x4
 +
|  Offset to extended info *relative to the beginning of this struct*
 +
|-
 +
|  0x18
 +
|  0x4
 +
|  Unknown
 +
|-
 +
|  0x1C
 +
|  0x4
 +
|  Unknown
 +
|-
 +
|}
 +
 +
===== 0x2206 =====
 +
 +
{| class="wikitable" border="1"
 +
|-
 +
!  OFFSET
 +
!  SIZE
 +
!  DESCRIPTION
 +
|-
 +
|  0x0
 +
|  0x4
 +
|  Unknown
 +
|-
 +
|  0x4
 +
|  0x4
 +
|  Type of the extended info
 +
|-
 +
|  0x8
 +
|  0x4
 +
|  Offset to extended info *relative to the beginning of this struct*
 +
|-
 +
|  0xC
 +
|  0x4
 +
|  Unknown
 +
|-
 +
|  0x10
 +
|  0x4
 +
|  Unknown
 +
|-
 +
|}
 +
 +
===== Table IDs =====
 +
 +
{| class="wikitable" border="1"
 +
|-
 +
!  ID
 +
!  NAME
 +
|-
 +
|  0x2200
 +
|  Audio Table
 +
|-
 +
|  0x2204
 +
|  Set Table
 +
|-
 +
|  0x2206
 +
|  Bank Table
 +
|-
 +
|  0x2207
 +
|  WAV Archive Table
 +
|-
 +
|  0x2208
 +
|  Group Table
 +
|-
 +
|  0x2208
 +
|  Player Table
 +
|-
 +
|  0x220A
 +
|  FILE Table
 
|-
 
|-
 
|}
 
|}
Line 178: Line 476:     
After some more research, there are multiple FILE partitions, but only 1 of them is the 'main' FILE partition (it's the one you get from the BCSAR header). The 'main' FILE partition contains all of the other sub FILE partitions.
 
After some more research, there are multiple FILE partitions, but only 1 of them is the 'main' FILE partition (it's the one you get from the BCSAR header). The 'main' FILE partition contains all of the other sub FILE partitions.
 +
 +
== Tools ==
 +
* vgmtoolbox's Advanced Cutter/Offset Finder tool can extract BCWAVs without filenames
 +
* [https://github.com/soneek/3DSUSoundArchiveTool 3DSUSoundArchiveTool] reference implementation of CSAR extraction
35

edits

Navigation menu