s3m to taud fix (not emitting volcmd on note retrigger)

This commit is contained in:
minjaesong
2026-04-23 13:35:38 +09:00
parent e58eb2c12b
commit 887c2fbfba
2 changed files with 22 additions and 4 deletions

View File

@@ -660,7 +660,9 @@ def build_pattern(s3m_grid: list, ch_idx: int, default_pan: int,
inst_vols = {}
out = bytearray(PATTERN_BYTES)
rows = s3m_grid[ch_idx] if ch_idx < len(s3m_grid) else [S3MRow()] * PATTERN_ROWS
last_inst = 0 # 1-based; tracks which instrument is loaded on this channel
last_inst = 0 # 1-based; tracks which instrument is loaded on this channel
last_note = S3M_NOTE_EMPTY # last raw S3M note byte that was a real pitch
last_vol = None # last SEL_SET volume value (0-63), for retrigger recall
for r, row in enumerate(rows[:PATTERN_ROWS]):
note = encode_note(row.note)
inst = row.inst # S3M 1-based → Taud 1-based
@@ -668,6 +670,12 @@ def build_pattern(s3m_grid: list, ch_idx: int, default_pan: int,
if row.inst > 0:
last_inst = row.inst
# ── Instrument-only retrigger ──
# Instrument-only row: recall the last volume without touching the note.
retrigger = (row.inst > 0
and row.note == S3M_NOTE_EMPTY
and last_note not in (S3M_NOTE_EMPTY, S3M_NOTE_OFF))
op, arg, vol_override, pan_override = encode_effect(
row.effect, row.effect_arg, ch_idx, r)
@@ -683,11 +691,21 @@ def build_pattern(s3m_grid: list, ch_idx: int, default_pan: int,
# so prior channel-vol state doesn't bleed through.
vol_sel = SEL_SET
vol_value = inst_vols.get(last_inst, 0x3F)
elif retrigger and last_vol is not None:
# Instrument-only row: re-emit the last known volume so the sample
# restarts at the correct level without an explicit note trigger.
vol_sel, vol_value = SEL_SET, last_vol
elif vol_override is not None:
vol_sel, vol_value = vol_override
else:
vol_sel, vol_value = SEL_FINE, 0 # no-op fine slide
# Track note and volume for future retrigger lookups.
if row.note not in (S3M_NOTE_EMPTY, S3M_NOTE_OFF):
last_note = row.note
if vol_sel == SEL_SET:
last_vol = vol_value
# ── Pan column ──
if pan_override is not None:
pan_sel, pan_value = pan_override

View File

@@ -2210,9 +2210,9 @@ 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 (0-4095), assuming octave 3. C3 (the default value) is 0x4000
Float32 Frequency at the base note. Default (A440) is 261.6255653
Byte[7] Reserved for future versions
Uint16 Current Tuning base note (1-4094), 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
Taud device can queue up to 2 "playdata" in its buffer, which can be interpreted as a song.