tightening formats

This commit is contained in:
minjaesong
2026-04-23 14:47:53 +09:00
parent bc16ffabb4
commit 44f11120d8
3 changed files with 24 additions and 23 deletions

View File

@@ -16,8 +16,8 @@ const NUM_PATTERNS_MAX = 256
const NUM_CUES = 1024
const CUE_SIZE = 32 // bytes per cue entry (packed 12-bit×20 voices + instruction + pad)
// Signature written into the file (16 bytes, space-padded)
const CAPTURE_SIGNATURE = "LibTaud/TSVM "
// Signature written into the file (14 bytes, space-padded)
const CAPTURE_SIGNATURE = "LibTaud/TSVM "
// ── Internal helpers ────────────────────────────────────────────────────────
@@ -205,8 +205,8 @@ function captureTrackerDataToFile(outFile) {
(compressedSize >>> 8) & 0xFF,
(compressedSize >>> 16) & 0xFF,
(compressedSize >>> 24) & 0xFF,
// reserved (2)
0x00, 0x00,
// reserved (4)
0x00, 0x00, 0x00, 0x00,
].concat(sigBytes) // 8 + 2 + 4 + 2 + 16 = 32 bytes
// -- 6. Build song-table row (16 bytes) -----------------------------------
@@ -219,7 +219,9 @@ function captureTrackerDataToFile(outFile) {
numPats & 0xFF, (numPats >>> 8) & 0xFF, // numPatterns Uint16 LE
bpmStored, // BPM with 24 bias
tickRate, // initial tick-rate
0,0,0,0,0,0,0, // 7 bytes padding
0x40,0, // basenote
0x13,0xd0,0x82,0x43, // basefreq
0, // padding
]
// -- 7. Write header (creates / truncates file) ---------------------------

View File

@@ -87,7 +87,7 @@ NUM_PATTERNS_MAX = 4095
NUM_CUES = 1024
CUE_SIZE = 32 # packed 12-bit×20 voices + instruction + pad
NUM_VOICES = 20
SIGNATURE = b"s3m2taud/TSVM " # 16 bytes
SIGNATURE = b"s3m2taud/TSVM " # 14 bytes
# Taud note constants
NOTE_NOP = 0xFFFF
@@ -860,13 +860,13 @@ def assemble_taud(h: S3MHeader, instruments: list, patterns: list) -> bytes:
song_offset = TAUD_HEADER_SIZE + comp_size + TAUD_SONG_ENTRY
num_taud_pats = P * C
# Header (32 bytes): magic(8)+ver(1)+numSongs(1)+compSize(4)+rsvd(2)+sig(16)
sig = (SIGNATURE + b' ' * 16)[:16]
# Header (32 bytes): magic(8)+ver(1)+numSongs(1)+compSize(4)+rsvd(4)+sig(14)
sig = (SIGNATURE + b' ' * 14)[:14]
header = (
TAUD_MAGIC +
bytes([TAUD_VERSION, 1]) +
struct.pack('<I', comp_size) +
b'\x00\x00' +
b'\x00\x00\x00\x00' +
sig
)
assert len(header) == TAUD_HEADER_SIZE
@@ -893,7 +893,7 @@ def assemble_taud(h: S3MHeader, instruments: list, patterns: list) -> bytes:
pat_bin, pat_remap, num_taud_pats = deduplicate_patterns(bytes(pat_bin), orig_count)
vprint(f" patterns: {orig_count}{num_taud_pats} unique ({orig_count - num_taud_pats} deduplicated)")
# Song table row (16 bytes): offset(4)+voices(1)+patsLo(1)+patsHi(1)+bpm(1)+tick(1)+pad(7)
# Song table row (16 bytes): offset(4)+voices(1)+patsLo(1)+patsHi(1)+bpm(1)+tick(1)+basenote(2)+basefreq(4)+pad(1)
# Built after dedup so num_taud_pats reflects the unique count.
num_taud_pats_lo = num_taud_pats & 0xFF
num_taud_pats_hi = (num_taud_pats >> 8) & 0xFF
@@ -904,7 +904,7 @@ def assemble_taud(h: S3MHeader, instruments: list, patterns: list) -> bytes:
num_taud_pats_hi,
bpm_stored,
speed,
) + b'\x00' * 7
) + b'\x40\x00' + b'\x13\xd0\x82\x43' + b'\x00'
assert len(song_table) == TAUD_SONG_ENTRY
# Cue sheet (using remapped pattern indices)

View File

@@ -2200,8 +2200,8 @@ Endianness: Little
Uint8 Format version (always 1)
Uint8 Number of songs in SONG TABLE
Uint32 Compressed size of SAMPLE+INST section (used to calculate offset to SONG TABLE)
Uint16 Reserved for future versions
Byte[16]Tracker/Converter signature
Uint32 Reserved for Taud Project Format. Fill with zero
Byte[14]Tracker/Converter signature
## SONG TABLE
Rows of 16 bytes:
@@ -2210,7 +2210,7 @@ Rows of 16 bytes:
Uint16 Number of patterns (0 is invalid. pattern bin length = numPats * 8 bytes)
Uint8 Initial BPM (bias of -24. 0x00=24, 0xFF=279)
Uint8 Initial Tickrate (0 is invalid)
Uint16 Current Tuning base note (1-4094), assuming octave 3. C3 (the default value) is 0x4000. If zero, assume the default value
Uint16 Current Tuning base note (1..65533), assuming octave 3. C3 (the default value) is 0x4000. If zero, assume the default value
Float32 Frequency at the base note. Default (A440) is 261.6255653. If zero, assume the default value
Byte[1] Reserved for future versions
@@ -2239,12 +2239,11 @@ Endianness: Little
## Header
Byte[8] Magic
Uint8 Format version (always 129)
Uint8 Format version (always 129; high-bit set and number 0x01)
Uint8 Number of songs in SONG TABLE
Uint32 Compressed size of SAMPLE+INST section (used to calculate offset to SONG TABLE)
Uint16 Offset to Project Data (low twobyte)
Uint32 Offset to Project Data (low twobyte)
Byte[14]Tracker/Converter signature
Uint16 Offset to Project Data (high twobyte)
## Project Data
Byte[8] Magic (\x1E T a u d P r J)
@@ -2268,11 +2267,11 @@ prefixes:
* PCpr. Project copyright string. Encoding: UTF-8
* PNam. Project name. Encoding: UTF-8
* INam. Instrument name table. Strings separated by comma
* INam. Instrument name table. Strings separated by 0x1E
* pNam. Pattern name table. Strings separated by comma
* pNam. Pattern name table. Strings separated by 0x1E
* SNam. Sample name table. Strings separated by comma
* SNam. Sample name table. Strings separated by 0x1E
* sMet. Song metadata table
* Repetition of:
@@ -2288,15 +2287,15 @@ prefixes:
Uint8 Notation index (starting from zero) used by songs
Uint32 Size of this notation following this field
Uint8 Flags
0b nnnn 000t
0b 0000 000t
t: NOT using interval system (you are responsible for defining every notes expressible)
Uint8 Reserved
Float32 Interval size (octave system = 2.0f). If Flag 't' is set, this must be NaN. 0f and Infinity are considered illegal
Uint16 Notes between interval MINUS ONE (or octave); 12-TET will have value 11. 0 is considered illegal
Byte[8] Reserved
Byte[*] Name, null terminated. Encoding: UTF-8
Byte[*] Notation table. Comma-separated and null-terminated. Encoding: raw bytes
Uint16[*] Frequency table. Size of the table is defined by "Notes between interval MINUS ONE". All relative to the base note (Song table will be referred), in 4096-TET note number. Index zero of this table will be 0x0 if you read the spec right
Byte[*] Notation table. 0xFF-separated and null-terminated. Encoding: raw bytes
Uint16[*] Frequency table. Size of the table is defined by "Notes between interval MINUS ONE". This is a lookup table of relative pitch offsets (against the base tuning note) in 4096-TET space. Index zero of this table will be 0x0 if you read the spec right
Note: custom notations will use internal index 65535 down to 65520 (index 0 = 65535, index 15 = 65520)