mirror of
https://github.com/curioustorvald/tsvm.git
synced 2026-06-06 05:28:31 +09:00
taud-related changes (docs, converter supports Y eff)
This commit is contained in:
@@ -219,8 +219,8 @@ function captureTrackerDataToFile(outFile) {
|
||||
numPats & 0xFF, (numPats >>> 8) & 0xFF, // numPatterns Uint16 LE
|
||||
bpmStored, // BPM with −24 bias
|
||||
tickRate, // initial tick-rate
|
||||
0x00,0x4C, // basenote (0x4C00 -- A3)
|
||||
0x00,0x00,0xDC,0x43, // basefreq (440 Hz)
|
||||
0x00,0x90, // basenote (0x9000 -- C8)
|
||||
0x00,0xAC,0x02,0x46, // basefreq (8363 Hz)
|
||||
0, // padding
|
||||
]
|
||||
|
||||
|
||||
18
s3m2taud.py
18
s3m2taud.py
@@ -17,8 +17,9 @@ Effect support:
|
||||
table" and "ScreamTracker 3 conversion notes". ST3 shared-memory recalls
|
||||
(D/E/F/I/J/K/L/Q/R/S with $00 arg) are eagerly resolved per channel.
|
||||
Cxx is BCD-decoded. K/L are split into H $0000 / G $0000 + volume-column
|
||||
slide. M/N/X/P fold into volume / pan columns. W (global vol slide) and
|
||||
Y (panbrello) are dropped with a -v warning.
|
||||
slide. M/N/X/P fold into volume / pan columns. W (global vol slide) is
|
||||
dropped with a -v warning. X converts to pan column. Y (panbrello) converts
|
||||
to Taud Y. S5 selects the panbrello LFO waveform.
|
||||
"""
|
||||
|
||||
import argparse
|
||||
@@ -116,6 +117,7 @@ TOP_S = 0x1C # sub-effects
|
||||
TOP_T = 0x1D # tempo set/slide
|
||||
TOP_U = 0x1E # fine vibrato
|
||||
TOP_V = 0x1F # global volume
|
||||
TOP_Y = 0x22 # panbrello
|
||||
|
||||
# Volume / pan column selectors (2-bit field, packed into top of vol/pan byte).
|
||||
SEL_SET = 0 # 6-bit value: set vol / pan
|
||||
@@ -442,10 +444,13 @@ def encode_effect(cmd: int, arg: int, ch: int = 0, row: int = 0) -> tuple:
|
||||
val = arg & 0xF
|
||||
if sub in (0x1, 0x2, 0x3, 0x4, 0xB, 0xC, 0xD, 0xE, 0xF):
|
||||
return (TOP_S, (sub << 12) | (val << 8), None, None)
|
||||
if sub == 0x5:
|
||||
# Panbrello LFO waveform — maps directly to Taud S$5x00.
|
||||
return (TOP_S, 0x5000 | (val << 8), None, None)
|
||||
if sub == 0x8:
|
||||
# Coarse pan: nibble-repeat into Taud's S $80xx full-8-bit pan.
|
||||
return (TOP_S, 0x8000 | (val * 0x11), None, None)
|
||||
# S0/S5/S6/S7/S9/SA: filter, NNA, sound-control, stereo — drop silently.
|
||||
# S0/S6/S7/S9/SA: filter, NNA, sound-control, stereo — drop silently.
|
||||
return (TOP_NONE, 0, None, None)
|
||||
|
||||
if cmd == EFF_T:
|
||||
@@ -465,8 +470,9 @@ def encode_effect(cmd: int, arg: int, ch: int = 0, row: int = 0) -> tuple:
|
||||
return (TOP_NONE, 0, None, (SEL_SET, min(arg >> 2, 0x3F)))
|
||||
|
||||
if cmd == EFF_Y:
|
||||
vprint(f" dropped Y{arg:02X} (panbrello) at ch{ch} row{row}")
|
||||
return (TOP_NONE, 0, None, None)
|
||||
hi = (arg >> 4) & 0xF
|
||||
lo = arg & 0xF
|
||||
return (TOP_Y, ((hi * 0x11) << 8) | (lo * 0x11), None, None)
|
||||
|
||||
if cmd == EFF_Z:
|
||||
return (TOP_NONE, 0, None, None)
|
||||
@@ -904,7 +910,7 @@ def assemble_taud(h: S3MHeader, instruments: list, patterns: list) -> bytes:
|
||||
num_taud_pats_hi,
|
||||
bpm_stored,
|
||||
speed,
|
||||
) + b'\x00\x4C' + b'\x00\x00\xDC\x43' + b'\x00'
|
||||
) + b'\x00\x90' + b'\x00\xAC\xD02\x46' + b'\x00'
|
||||
assert len(song_table) == TAUD_SONG_ENTRY
|
||||
|
||||
# Cue sheet (using remapped pattern indices)
|
||||
|
||||
@@ -2211,16 +2211,21 @@ Endianness: Little
|
||||
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..65533). A3 (the default value) is 0x4C00. If zero, assume the default value
|
||||
Float32 Frequency at the base note. Default (A440) is 440.0. If zero, assume the default value
|
||||
Uint16 Current Tuning base note (1..65533). A3 (western default) is 0x4C00. C8 (tracker default) is 0x9000. If zero, assume the tracker default value
|
||||
Float32 Frequency at the base note. Tracker default is 8363.0. If zero, assume the tracker default
|
||||
Byte[1] Reserved for future versions
|
||||
|
||||
Taud device can queue up to 2 "playdata" in its buffer, which can be interpreted as a song.
|
||||
|
||||
* Known standard tunings
|
||||
A440. ISO standard. Tracker default
|
||||
A440. ISO standard
|
||||
A435. Former French standard (year 1859)
|
||||
A452. Old Philharmonic pitch (19th century Britain)
|
||||
C256. Power of two
|
||||
C311. East Asian tuning (ROK National Gugak Center standard)
|
||||
C262. Modern Chinese a-ak tuning convention
|
||||
C311. Korean hyang-ak tuning standard (ROK National Gugak Center)
|
||||
|
||||
For your reference, tracker default tuning at A3 is 439.526 Hz (8363*2^(3/4) / 32)
|
||||
|
||||
## Pattern Bin and Cue Sheet
|
||||
Raw Pattern Bin/Cue Sheet images
|
||||
|
||||
Reference in New Issue
Block a user