taut.js: fxNames update

This commit is contained in:
minjaesong
2026-05-04 02:14:19 +09:00
parent 9524bf36e0
commit 517d0ad9a7
5 changed files with 52 additions and 22 deletions

View File

@@ -116,17 +116,17 @@ P:"UNIMPLEMENTED", // IT: panning slide. Use PanEff instead
Q:"Retrigger ",
R:"Tremolo ",
S:"Special ",
S0:"UNIMPLEMENTED", // PT: Set audio filter.
S0:"UNIMPLEMENTED", // PT: Set audio filter
S1:"Gliss. ctrl ",
S2:"Sample tune ",
S3:"Vibrato LFO ",
S4:"Tremolo LFO ",
S5:"Panbrello LFO",
S6:"UNIMPLEMENTED", // IT: Fine pattern delay.
S7:"UNIMPLEMENTED", // IT: misc. functions
S8:"Channel pan ", // Taud: 8-bit channel panning.
S9:"UNIMPLEMENTED", // IT: Sound control.
SA:"UNIMPLEMENTED", // SC3: Stereo control. IT: Sample offset high twobyte.
S6:"Fine delay ",
S7:"Note action ",
S8:"Channel pan ", // Taud: 8-bit channel panning
S9:"UNIMPLEMENTED", // IT: Sound control
SA:"UNIMPLEMENTED", // SC3: Stereo control. IT: Sample offset high twobyte (not applicable because Taud has 64k limit)
SB:"Pattern loop ",
SC:"Note cut ",
SD:"Note delay ",
@@ -135,10 +135,10 @@ SF:"Funk it ",
T:"Tempo ",
U:"Fine vibrato ",
V:"Global volume",
W:"UNIMPLEMENTED", // IT: Global volume slide.
X:"UNIMPLEMENTED", // IT: 8-bit channel panning. Use PanEff or S80xx instead
W:"G.Vol Slide ",
X:"UNIMPLEMENTED", // IT: 8-bit channel panning. Use S80xx instead
Y:"Panbrello ",
Z:"UNIMPLEMENTED", // IT: MIDI macro.
Z:"UNIMPLEMENTED", // IT: MIDI macro
}
const panFxNames = {
0:"Set to",

View File

@@ -52,7 +52,7 @@ from taud_common import (
EFF_K, EFF_L, EFF_M, EFF_N, EFF_O, EFF_P, EFF_Q, EFF_R, EFF_S, EFF_T,
EFF_U, EFF_V, EFF_W, EFF_X, EFF_Y, EFF_Z,
J_SEMI_TABLE,
d_arg_to_col, resample_linear, encode_cue, deduplicate_patterns,
d_arg_to_col, resample_linear, rescale_offset_effects, encode_cue, deduplicate_patterns,
normalise_sample, encode_song_entry,
)
@@ -1314,7 +1314,7 @@ def build_sample_inst_bin_it(samples_or_proxy: list,
vprint(f" instrument[{taud_idx}] '{s.name}' ptr:{ptr} c5spd:{s.c5_speed}")
return bytes(sample_bin) + bytes(inst_bin), offsets
return bytes(sample_bin) + bytes(inst_bin), offsets, ratio
# ── Pattern builder ───────────────────────────────────────────────────────────
@@ -1682,7 +1682,7 @@ def assemble_taud(h: ITHeader, samples: list, instruments: list,
'dct': inst.dct,
'dca': inst.dca,
}
sampleinst_raw, _ = build_sample_inst_bin_it(proxy, instr_data_by_slot)
sampleinst_raw, _, sample_ratio = build_sample_inst_bin_it(proxy, instr_data_by_slot)
else:
# Samples referenced directly; proxy is samples list (0-based, slot 0 unused)
proxy = [None] + list(samples)
@@ -1691,7 +1691,7 @@ def assemble_taud(h: ITHeader, samples: list, instruments: list,
for i, s in enumerate(samples)
if s is not None
}
sampleinst_raw, _ = build_sample_inst_bin_it(proxy)
sampleinst_raw, _, sample_ratio = build_sample_inst_bin_it(proxy)
assert len(sampleinst_raw) == SAMPLEINST_SIZE
@@ -1723,8 +1723,11 @@ def assemble_taud(h: ITHeader, samples: list, instruments: list,
pat_bin += build_pattern_it(cg, ch, default_pans[vi], inst_vols,
amiga_mode=not h.linear_slides)
# Rescale TOP_O sample-offset args if samples were globally downsampled.
pat_bin = rescale_offset_effects(bytes(pat_bin), sample_ratio)
orig_count = len(taud_cue_list) * C
pat_bin, pat_remap, num_taud_pats = deduplicate_patterns(bytes(pat_bin), orig_count)
pat_bin, pat_remap, num_taud_pats = deduplicate_patterns(pat_bin, orig_count)
vprint(f" patterns: {orig_count}{num_taud_pats} unique "
f"({orig_count - num_taud_pats} deduplicated)")

View File

@@ -39,7 +39,7 @@ from taud_common import (
TOP_J, TOP_K, TOP_L, TOP_O, TOP_Q, TOP_R, TOP_S, TOP_T, TOP_U, TOP_V, TOP_Y,
SEL_SET, SEL_UP, SEL_DOWN, SEL_FINE,
J_SEMI_TABLE,
d_arg_to_col, resample_linear, encode_cue, deduplicate_patterns,
d_arg_to_col, resample_linear, rescale_offset_effects, encode_cue, deduplicate_patterns,
encode_song_entry,
)
@@ -546,7 +546,7 @@ def build_sample_inst_bin(samples: list) -> tuple:
vprint(f" instrument[{taud_idx}] '{s.name}' ptr={ptr} c2spd={s.c2spd} "
f"vol={s.volume} loop=({ls},{le},{'on' if loop_mode else 'off'})")
return bytes(sample_bin) + bytes(inst_bin), offsets
return bytes(sample_bin) + bytes(inst_bin), offsets, ratio
# ── Pattern build ────────────────────────────────────────────────────────────
@@ -704,7 +704,7 @@ def assemble_taud(mod: dict) -> bytes:
relocate_late_note_delays(patterns, order_list, n_channels, init_speed)
vprint(" building sample/instrument bin…")
sampleinst_raw, _offsets = build_sample_inst_bin(samples)
sampleinst_raw, _offsets, sample_ratio = build_sample_inst_bin(samples)
assert len(sampleinst_raw) == SAMPLEINST_SIZE
compressed = gzip.compress(sampleinst_raw, compresslevel=9, mtime=0)
@@ -742,9 +742,12 @@ def assemble_taud(mod: dict) -> bytes:
pat_bin += build_pattern(grid, ch, default_pan, inst_vols)
assert len(pat_bin) == n_patterns * n_channels * PATTERN_BYTES
# Rescale TOP_O sample-offset args if samples were globally downsampled.
pat_bin = rescale_offset_effects(bytes(pat_bin), sample_ratio)
vprint(" deduplicating patterns…")
orig_count = n_patterns * n_channels
pat_bin, pat_remap, num_taud_pats = deduplicate_patterns(bytes(pat_bin), orig_count)
pat_bin, pat_remap, num_taud_pats = deduplicate_patterns(pat_bin, orig_count)
vprint(f" patterns: {orig_count}{num_taud_pats} unique "
f"({orig_count - num_taud_pats} deduplicated)")

View File

@@ -43,7 +43,7 @@ from taud_common import (
EFF_K, EFF_L, EFF_M, EFF_N, EFF_O, EFF_P, EFF_Q, EFF_R, EFF_S, EFF_T,
EFF_U, EFF_V, EFF_W, EFF_X, EFF_Y, EFF_Z,
J_SEMI_TABLE,
d_arg_to_col, resample_linear, encode_cue, deduplicate_patterns,
d_arg_to_col, resample_linear, rescale_offset_effects, encode_cue, deduplicate_patterns,
normalise_sample, encode_song_entry,
)
@@ -528,7 +528,7 @@ def build_sample_inst_bin(instruments: list) -> tuple:
if inst.c2spd > 65535:
vprint(f" warning: sampling rate of '{inst.name}' exceeds 65535 (got '{inst.c2spd}')")
return bytes(sample_bin) + bytes(inst_bin), offsets
return bytes(sample_bin) + bytes(inst_bin), offsets, ratio
def _default_channel_pan(ch_setting: int) -> int:
@@ -740,7 +740,7 @@ def assemble_taud(h: S3MHeader, instruments: list, patterns: list) -> bytes:
# Build sample+instrument bin
vprint(" building sample/instrument bin…")
sampleinst_raw, _offsets = build_sample_inst_bin(instruments)
sampleinst_raw, _offsets, sample_ratio = build_sample_inst_bin(instruments)
assert len(sampleinst_raw) == SAMPLEINST_SIZE
# Compress
@@ -787,10 +787,13 @@ def assemble_taud(h: S3MHeader, instruments: list, patterns: list) -> bytes:
inst_vols, amiga_mode=not h.linear_slides)
assert len(pat_bin) == num_taud_pats * PATTERN_BYTES
# Rescale TOP_O sample-offset args if samples were globally downsampled.
pat_bin = rescale_offset_effects(bytes(pat_bin), sample_ratio)
# Deduplicate identical patterns
vprint(" deduplicating patterns…")
orig_count = num_taud_pats
pat_bin, pat_remap, num_taud_pats = deduplicate_patterns(bytes(pat_bin), orig_count)
pat_bin, pat_remap, num_taud_pats = deduplicate_patterns(pat_bin, orig_count)
vprint(f" patterns: {orig_count}{num_taud_pats} unique ({orig_count - num_taud_pats} deduplicated)")
# Cue sheet (using remapped pattern indices)

View File

@@ -131,6 +131,27 @@ def resample_linear(data: bytes, ratio: float) -> bytes:
return bytes(out)
def rescale_offset_effects(pat_bin: bytes, ratio: float) -> bytes:
"""Scale TOP_O sample-offset args in raw pattern bytes by `ratio`.
Each row is 8 bytes; byte 5 is the effect opcode, bytes 6-7 are the
little-endian 16-bit arg (= byte offset into the sample). When the
sample bin overflows and every sample is downsampled globally, the
offset commands must shrink the same amount or O-jumps land past
the new end of sample.
"""
if ratio == 1.0 or not pat_bin:
return pat_bin
out = bytearray(pat_bin)
for i in range(0, len(out) - 7, 8):
if out[i + 5] == TOP_O:
arg = out[i + 6] | (out[i + 7] << 8)
arg = max(0, min(0xFFFF, int(arg * ratio + 0.5)))
out[i + 6] = arg & 0xFF
out[i + 7] = (arg >> 8) & 0xFF
return bytes(out)
def encode_cue(patterns12: list, instruction: int) -> bytearray:
"""Encode a 32-byte cue entry for up to 20 voices with 12-bit pattern numbers."""
pats = list(patterns12) + [0xFFF] * NUM_VOICES