mirror of
https://github.com/curioustorvald/tsvm.git
synced 2026-06-06 13:38:30 +09:00
taut inst: global volume
This commit is contained in:
@@ -675,7 +675,7 @@ function drawStatusBar() {
|
|||||||
|
|
||||||
// beat indicator
|
// beat indicator
|
||||||
let beatCursorRow = cursorRow
|
let beatCursorRow = cursorRow
|
||||||
while (beatCursorRow > beatDivSecondary) { beatCursorRow -= beatDivSecondary } // test this behaviour with primary=4, secondary=22 or something
|
while (beatCursorRow >= beatDivSecondary) { beatCursorRow -= beatDivSecondary }
|
||||||
let beatInd = (playbackMode != PLAYMODE_NONE && beatCursorRow % beatDivPrimary < (beatDivPrimary >>> 1)) ?
|
let beatInd = (playbackMode != PLAYMODE_NONE && beatCursorRow % beatDivPrimary < (beatDivPrimary >>> 1)) ?
|
||||||
((beatCursorRow % beatDivSecondary < (beatDivPrimary >>> 1)) ? '\u00846u' : '\u00847u') :
|
((beatCursorRow % beatDivSecondary < (beatDivPrimary >>> 1)) ? '\u00846u' : '\u00847u') :
|
||||||
''
|
''
|
||||||
|
|||||||
41
it2taud.py
41
it2taud.py
@@ -559,12 +559,13 @@ def _parse_it_envelope(data: bytes, env_ptr: int, is_pan: bool,
|
|||||||
|
|
||||||
Returns (points_list, sustain_byte) where points_list is a list of
|
Returns (points_list, sustain_byte) where points_list is a list of
|
||||||
8 (value, minifloat_idx) tuples, or None if envelope not enabled.
|
8 (value, minifloat_idx) tuples, or None if envelope not enabled.
|
||||||
sustain_byte: bit7=enabled, bits[5:3]=end_idx, bits[2:0]=start_idx; 0=disabled.
|
sustain_byte: bit7=enabled (u), bit6=sustain (t: 1=breaks on key-off,
|
||||||
|
0=loops forever), bits[5:3]=end_idx, bits[2:0]=start_idx; 0=disabled.
|
||||||
|
|
||||||
IT has two loop types: envelope loop (always on) and sustain loop (breaks on
|
IT has two loop types: envelope loop (continues forever) and sustain loop
|
||||||
key-off). Taud only has sustain loop semantics. Priority: sustain > env loop.
|
(breaks on key-off). Taud distinguishes them via the 't' flag. Priority
|
||||||
When slb==sle the AudioAdapter holds at that node (no cycling); for slb!=sle
|
when both exist: sustain (because IT plays sustain while held, then env
|
||||||
it cycles between them.
|
loop after release; Taud can only express one).
|
||||||
"""
|
"""
|
||||||
if env_ptr + 82 > len(data):
|
if env_ptr + 82 > len(data):
|
||||||
return None, 0
|
return None, 0
|
||||||
@@ -580,17 +581,20 @@ def _parse_it_envelope(data: bytes, env_ptr: int, is_pan: bool,
|
|||||||
has_env_loop = bool(flags & 0x02)
|
has_env_loop = bool(flags & 0x02)
|
||||||
has_sus_loop = bool(flags & 0x04)
|
has_sus_loop = bool(flags & 0x04)
|
||||||
|
|
||||||
# Choose which IT loop to map to Taud sustain (priority: sus > env)
|
# Choose which IT loop to map to Taud (priority: sus > env). The 't' flag
|
||||||
|
# distinguishes them: t=1 for sustain (breaks on key-off), t=0 for env loop.
|
||||||
if has_sus_loop:
|
if has_sus_loop:
|
||||||
use_lb, use_le = it_slb, it_sle
|
use_lb, use_le = it_slb, it_sle
|
||||||
has_loop = True
|
has_loop = True
|
||||||
|
is_sustain = True
|
||||||
elif has_env_loop:
|
elif has_env_loop:
|
||||||
use_lb, use_le = it_lpb, it_lpe
|
use_lb, use_le = it_lpb, it_lpe
|
||||||
has_loop = True
|
has_loop = True
|
||||||
vprint(f" envelope loop mapped as sustain loop (approximation: breaks on key-off)")
|
is_sustain = False
|
||||||
else:
|
else:
|
||||||
use_lb = use_le = -1
|
use_lb = use_le = -1
|
||||||
has_loop = False
|
has_loop = False
|
||||||
|
is_sustain = False
|
||||||
|
|
||||||
# Read IT nodes: (int8 value, uint16 tick_pos LE)
|
# Read IT nodes: (int8 value, uint16 tick_pos LE)
|
||||||
nodes = []
|
nodes = []
|
||||||
@@ -640,10 +644,12 @@ def _parse_it_envelope(data: bytes, env_ptr: int, is_pan: bool,
|
|||||||
mf_idx = 0
|
mf_idx = 0
|
||||||
points.append((taud_val, mf_idx))
|
points.append((taud_val, mf_idx))
|
||||||
|
|
||||||
# Build sustain byte: bit7=enabled, bits[5:3]=end_idx, bits[2:0]=start_idx.
|
# Build sustain byte: bit7=enable (u), bit6=sustain (t), bits[5:3]=end,
|
||||||
# 0 = disabled (no bit7). All (slb, sle) pairs including (0,0) are valid when bit7=1.
|
# bits[2:0]=start. 0=disabled. t=1 → breaks on key-off (IT sustain loop);
|
||||||
|
# t=0 → loops forever (IT envelope loop).
|
||||||
if taud_slb >= 0 and taud_sle >= 0:
|
if taud_slb >= 0 and taud_sle >= 0:
|
||||||
sus_byte = 0x80 | ((taud_sle & 7) << 3) | (taud_slb & 7)
|
t_bit = 0x40 if is_sustain else 0x00
|
||||||
|
sus_byte = 0x80 | t_bit | ((taud_sle & 7) << 3) | (taud_slb & 7)
|
||||||
else:
|
else:
|
||||||
sus_byte = 0
|
sus_byte = 0
|
||||||
|
|
||||||
@@ -1126,8 +1132,9 @@ def build_sample_inst_bin_it(samples_or_proxy: list,
|
|||||||
envelopes_by_slot: dict = None) -> tuple:
|
envelopes_by_slot: dict = None) -> tuple:
|
||||||
"""samples_or_proxy: list of ITSample | None, indexed 1-based (index 0 unused).
|
"""samples_or_proxy: list of ITSample | None, indexed 1-based (index 0 unused).
|
||||||
|
|
||||||
envelopes_by_slot: optional dict mapping taud_slot → (vol_env, vol_sus, pan_env, pan_sus)
|
envelopes_by_slot: optional dict mapping taud_slot → (vol_env, vol_sus, pan_env, pan_sus, inst_gv)
|
||||||
where vol_env/pan_env are lists of 8 (value, minifloat_idx) tuples (or None).
|
where vol_env/pan_env are lists of 8 (value, minifloat_idx) tuples (or None),
|
||||||
|
and inst_gv is instrument global volume (0..255, byte 15).
|
||||||
|
|
||||||
Returns (bin_bytes[SAMPLEINST_SIZE], offsets_dict).
|
Returns (bin_bytes[SAMPLEINST_SIZE], offsets_dict).
|
||||||
"""
|
"""
|
||||||
@@ -1194,9 +1201,10 @@ def build_sample_inst_bin_it(samples_or_proxy: list,
|
|||||||
# Write envelope data (new 8-point format)
|
# Write envelope data (new 8-point format)
|
||||||
env_data = envelopes_by_slot.get(taud_idx) if envelopes_by_slot else None
|
env_data = envelopes_by_slot.get(taud_idx) if envelopes_by_slot else None
|
||||||
if env_data and env_data[0]:
|
if env_data and env_data[0]:
|
||||||
vol_env, vol_sus, pan_env, pan_sus = env_data
|
vol_env, vol_sus, pan_env, pan_sus, inst_gv = env_data
|
||||||
inst_bin[base + 13] = vol_sus & 0xFF
|
inst_bin[base + 13] = vol_sus & 0xFF
|
||||||
inst_bin[base + 14] = pan_sus & 0xFF
|
inst_bin[base + 14] = pan_sus & 0xFF
|
||||||
|
inst_bin[base + 15] = inst_gv & 0xFF
|
||||||
for k, (val, mf) in enumerate(vol_env[:8]):
|
for k, (val, mf) in enumerate(vol_env[:8]):
|
||||||
inst_bin[base + 16 + k*2] = val & 0xFF
|
inst_bin[base + 16 + k*2] = val & 0xFF
|
||||||
inst_bin[base + 16 + k*2 + 1] = mf & 0xFF
|
inst_bin[base + 16 + k*2 + 1] = mf & 0xFF
|
||||||
@@ -1209,7 +1217,9 @@ def build_sample_inst_bin_it(samples_or_proxy: list,
|
|||||||
inst_bin[base + 32 + k*2] = 0x80 # pan centre
|
inst_bin[base + 32 + k*2] = 0x80 # pan centre
|
||||||
inst_bin[base + 32 + k*2 + 1] = 0x00 # hold
|
inst_bin[base + 32 + k*2 + 1] = 0x00 # hold
|
||||||
else:
|
else:
|
||||||
# No instrument envelope: single-point vol, neutral pan
|
# No instrument envelope: single-point vol, neutral pan, full gv
|
||||||
|
inst_gv = env_data[4] if env_data else 255
|
||||||
|
inst_bin[base + 15] = inst_gv & 0xFF
|
||||||
inst_bin[base + 16] = min(s.vol, 63) # value 0-63
|
inst_bin[base + 16] = min(s.vol, 63) # value 0-63
|
||||||
inst_bin[base + 17] = 0 # offset 0 = hold
|
inst_bin[base + 17] = 0 # offset 0 = hold
|
||||||
for k in range(8):
|
for k in range(8):
|
||||||
@@ -1484,9 +1494,12 @@ def assemble_taud(h: ITHeader, samples: list, instruments: list,
|
|||||||
proxy[taud_slot] = samples[si]
|
proxy[taud_slot] = samples[si]
|
||||||
vol64 = min(inst.canonical_volume, 64)
|
vol64 = min(inst.canonical_volume, 64)
|
||||||
inst_vols[taud_slot] = min(vol64, 0x3F)
|
inst_vols[taud_slot] = min(vol64, 0x3F)
|
||||||
|
# IT global volume range is 0..128; rescale to Taud's 0..255.
|
||||||
|
inst_gv_255 = min(255, round(inst.gv * 255 / 128))
|
||||||
envelopes_by_slot[taud_slot] = (
|
envelopes_by_slot[taud_slot] = (
|
||||||
inst.vol_envelope, inst.vol_env_sustain,
|
inst.vol_envelope, inst.vol_env_sustain,
|
||||||
inst.pan_envelope, inst.pan_env_sustain,
|
inst.pan_envelope, inst.pan_env_sustain,
|
||||||
|
inst_gv_255,
|
||||||
)
|
)
|
||||||
sampleinst_raw, _ = build_sample_inst_bin_it(proxy, envelopes_by_slot)
|
sampleinst_raw, _ = build_sample_inst_bin_it(proxy, envelopes_by_slot)
|
||||||
else:
|
else:
|
||||||
|
|||||||
@@ -624,6 +624,7 @@ def build_sample_inst_bin(instruments: list) -> tuple:
|
|||||||
struct.pack_into('<H', inst_bin, base + 8, ls)
|
struct.pack_into('<H', inst_bin, base + 8, ls)
|
||||||
struct.pack_into('<H', inst_bin, base + 10, le)
|
struct.pack_into('<H', inst_bin, base + 10, le)
|
||||||
inst_bin[base + 12] = flags_byte
|
inst_bin[base + 12] = flags_byte
|
||||||
|
inst_bin[base + 15] = 0xFF # instrument global volume (S3M has none → full)
|
||||||
# Volume envelope: hold at instrument volume (clamped to 0x3F)
|
# Volume envelope: hold at instrument volume (clamped to 0x3F)
|
||||||
env_vol = min(inst.volume, 63)
|
env_vol = min(inst.volume, 63)
|
||||||
inst_bin[base + 16] = env_vol # volume
|
inst_bin[base + 16] = env_vol # volume
|
||||||
|
|||||||
@@ -2005,17 +2005,23 @@ Instrument bin: Registry for 256 instruments, formatted as:
|
|||||||
0b hhhh 00pp
|
0b hhhh 00pp
|
||||||
h: sample pointer high bit
|
h: sample pointer high bit
|
||||||
pp: loop mode. 0-no loop, 1-loop, 2-backandforth, 3-oneshot (ignores note length unless overridden by other notes)
|
pp: loop mode. 0-no loop, 1-loop, 2-backandforth, 3-oneshot (ignores note length unless overridden by other notes)
|
||||||
Bit8 Volume envelope sustain loops
|
Bit8 Volume envelope sustain/loops
|
||||||
0b u0 eee sss
|
* Sustain is implemented by enabling 't' flag. FastTracker has no 'Sus Loop' but only 'Sus Point'; use same value for start and end index
|
||||||
s: sustain loop start index
|
0b ut eee sss
|
||||||
e: sustain loop end index
|
s: sustain/loop start index
|
||||||
u: set to enable the loop
|
e: sustain/loop end index
|
||||||
Bit8 Panning envelope sustain loops
|
t: the loop must sustain (key-off escapes the loop)
|
||||||
0b u0 eee sss
|
u: set to enable the sustain/loop
|
||||||
s: sustain loop start index
|
Bit8 Panning envelope sustain/loops
|
||||||
e: sustain loop end index
|
* Sustain is implemented by enabling 't' flag
|
||||||
u: set to enable the loop
|
0b ut eee sss
|
||||||
Bit8 Reserved
|
s: sustain/loop start index
|
||||||
|
e: sustain/loop end index
|
||||||
|
t: the loop must sustain (key-off escapes the loop)
|
||||||
|
u: set to enable the sustain/loop
|
||||||
|
Uint8 Instrument Global Volume (0..255)
|
||||||
|
* ImpulseTracker has range of 0..128; multiply by (255/128) then round to int
|
||||||
|
* FastTracker2 has range of 0..64; multiply by (255/64) then round to int
|
||||||
Bit16x8 Volume envelopes
|
Bit16x8 Volume envelopes
|
||||||
Byte 1: Volume (00..3F)
|
Byte 1: Volume (00..3F)
|
||||||
Byte 2: Time until the next point, in seconds (3.5 Unsigned Minifloat). 0 = hold at this point indefinitely.
|
Byte 2: Time until the next point, in seconds (3.5 Unsigned Minifloat). 0 = hold at this point indefinitely.
|
||||||
|
|||||||
@@ -1184,17 +1184,26 @@ class AudioAdapter(val vm: VM) : PeriBase(VM.PERITYPE_SOUND) {
|
|||||||
|
|
||||||
private fun advanceEnvelope(voice: Voice, inst: TaudInst, tickSec: Double) {
|
private fun advanceEnvelope(voice: Voice, inst: TaudInst, tickSec: Double) {
|
||||||
// Volume envelope
|
// Volume envelope
|
||||||
// sustain byte: bit7=enabled, bits[5:3]=end_idx, bits[2:0]=start_idx
|
// sustain byte: bit7=enable (u), bit6=sustain (t: 1=breaks on key-off,
|
||||||
val vSus = inst.volEnvSustain
|
// 0=loops forever), bits[5:3]=end_idx, bits[2:0]=start_idx
|
||||||
val vSusOn = (vSus and 0x80) != 0 && !voice.keyOff
|
val vSus = inst.volEnvSustain
|
||||||
val vSusStart = vSus and 7
|
val vEnabled = (vSus and 0x80) != 0
|
||||||
val vSusEnd = (vSus ushr 3) and 7
|
val vIsSustain = (vSus and 0x40) != 0
|
||||||
|
// Loop is "active" when enabled AND (it's a forever-loop OR key not yet released)
|
||||||
|
val vSusOn = vEnabled && (!vIsSustain || !voice.keyOff)
|
||||||
|
val vSusStart = vSus and 7
|
||||||
|
val vSusEnd = (vSus ushr 3) and 7
|
||||||
|
|
||||||
if (voice.envIndex >= 7) {
|
if (vSusOn && voice.envIndex == vSusEnd && vSusStart == vSusEnd) {
|
||||||
voice.envVolume = (inst.volEnvelopes[7].value / 63.0).coerceIn(0.0, 1.0)
|
|
||||||
} else if (vSusOn && voice.envIndex == vSusEnd && vSusStart == vSusEnd) {
|
|
||||||
// slb == sle: hold at this node until key-off (no cycling)
|
// slb == sle: hold at this node until key-off (no cycling)
|
||||||
voice.envVolume = (inst.volEnvelopes[voice.envIndex].value / 63.0).coerceIn(0.0, 1.0)
|
voice.envVolume = (inst.volEnvelopes[voice.envIndex].value / 63.0).coerceIn(0.0, 1.0)
|
||||||
|
} else if (vSusOn && voice.envIndex == vSusEnd) {
|
||||||
|
// At sustain-loop end: snap back to start regardless of stored offset.
|
||||||
|
voice.envTimeSec = 0.0
|
||||||
|
voice.envIndex = vSusStart
|
||||||
|
voice.envVolume = (inst.volEnvelopes[voice.envIndex].value / 63.0).coerceIn(0.0, 1.0)
|
||||||
|
} else if (voice.envIndex >= 7) {
|
||||||
|
voice.envVolume = (inst.volEnvelopes[7].value / 63.0).coerceIn(0.0, 1.0)
|
||||||
} else {
|
} else {
|
||||||
val vOffset = inst.volEnvelopes[voice.envIndex].offset.toDouble()
|
val vOffset = inst.volEnvelopes[voice.envIndex].offset.toDouble()
|
||||||
if (vOffset == 0.0) {
|
if (vOffset == 0.0) {
|
||||||
@@ -1217,16 +1226,24 @@ class AudioAdapter(val vm: VM) : PeriBase(VM.PERITYPE_SOUND) {
|
|||||||
|
|
||||||
// Pan envelope (only when active for this instrument)
|
// Pan envelope (only when active for this instrument)
|
||||||
if (!voice.hasPanEnv) return
|
if (!voice.hasPanEnv) return
|
||||||
val pSus = inst.panEnvSustain
|
val pSus = inst.panEnvSustain
|
||||||
val pSusOn = (pSus and 0x80) != 0 && !voice.keyOff
|
val pEnabled = (pSus and 0x80) != 0
|
||||||
val pSusStart = pSus and 7
|
val pIsSustain = (pSus and 0x40) != 0
|
||||||
val pSusEnd = (pSus ushr 3) and 7
|
val pSusOn = pEnabled && (!pIsSustain || !voice.keyOff)
|
||||||
|
val pSusStart = pSus and 7
|
||||||
|
val pSusEnd = (pSus ushr 3) and 7
|
||||||
|
|
||||||
if (voice.envPanIndex >= 7) {
|
if (pSusOn && voice.envPanIndex == pSusEnd && pSusStart == pSusEnd) {
|
||||||
voice.envPan = inst.panEnvelopes[7].value / 255.0
|
|
||||||
} else if (pSusOn && voice.envPanIndex == pSusEnd && pSusStart == pSusEnd) {
|
|
||||||
// slb == sle: hold at this pan node until key-off
|
// slb == sle: hold at this pan node until key-off
|
||||||
voice.envPan = inst.panEnvelopes[voice.envPanIndex].value / 255.0
|
voice.envPan = inst.panEnvelopes[voice.envPanIndex].value / 255.0
|
||||||
|
} else if (pSusOn && voice.envPanIndex == pSusEnd) {
|
||||||
|
// At sustain-loop end: snap back to start regardless of stored offset
|
||||||
|
// (encoder writes mf=0 on the last node by convention).
|
||||||
|
voice.envPanTimeSec = 0.0
|
||||||
|
voice.envPanIndex = pSusStart
|
||||||
|
voice.envPan = inst.panEnvelopes[voice.envPanIndex].value / 255.0
|
||||||
|
} else if (voice.envPanIndex >= 7) {
|
||||||
|
voice.envPan = inst.panEnvelopes[7].value / 255.0
|
||||||
} else {
|
} else {
|
||||||
val pOffset = inst.panEnvelopes[voice.envPanIndex].offset.toDouble()
|
val pOffset = inst.panEnvelopes[voice.envPanIndex].offset.toDouble()
|
||||||
if (pOffset == 0.0) {
|
if (pOffset == 0.0) {
|
||||||
@@ -1816,8 +1833,10 @@ class AudioAdapter(val vm: VM) : PeriBase(VM.PERITYPE_SOUND) {
|
|||||||
val gvol = playhead.globalVolume / 255.0
|
val gvol = playhead.globalVolume / 255.0
|
||||||
for (voice in ts.voices) {
|
for (voice in ts.voices) {
|
||||||
if (!voice.active || voice.muted) continue
|
if (!voice.active || voice.muted) continue
|
||||||
val s = fetchTrackerSample(voice, instruments[voice.instrumentId])
|
val voiceInst = instruments[voice.instrumentId]
|
||||||
val vol = voice.envVolume * voice.rowVolume / 63.0 * gvol * playhead.masterVolume / 255.0
|
val s = fetchTrackerSample(voice, voiceInst)
|
||||||
|
val instGv = voiceInst.instGlobalVolume / 255.0
|
||||||
|
val vol = voice.envVolume * voice.rowVolume / 63.0 * gvol * instGv * playhead.masterVolume / 255.0
|
||||||
val pan = if (voice.hasPanEnv) {
|
val pan = if (voice.hasPanEnv) {
|
||||||
val envPanRaw = (voice.envPan * 255.0).roundToInt().coerceIn(0, 255)
|
val envPanRaw = (voice.envPan * 255.0).roundToInt().coerceIn(0, 255)
|
||||||
(voice.channelPan + envPanRaw - 128).coerceIn(0, 255)
|
(voice.channelPan + envPanRaw - 128).coerceIn(0, 255)
|
||||||
@@ -2314,12 +2333,13 @@ class AudioAdapter(val vm: VM) : PeriBase(VM.PERITYPE_SOUND) {
|
|||||||
var sampleLoopEnd: Int,
|
var sampleLoopEnd: Int,
|
||||||
// flags
|
// flags
|
||||||
var loopMode: Int,
|
var loopMode: Int,
|
||||||
var volEnvSustain: Int, // byte 13: 00 eee sss (0 = no sustain loop)
|
var volEnvSustain: Int, // byte 13: ut eee sss (u=enable, t=sustain (1=breaks on key-off, 0=loops forever))
|
||||||
var panEnvSustain: Int, // byte 14: 00 eee sss (0 = no sustain loop)
|
var panEnvSustain: Int, // byte 14: ut eee sss (u=enable, t=sustain (1=breaks on key-off, 0=loops forever))
|
||||||
|
var instGlobalVolume: Int, // byte 15: instrument global volume (0..255, 255 = unity)
|
||||||
var volEnvelopes: Array<TaudInstEnvPoint>, // 8 points, value 0x00-0x3F
|
var volEnvelopes: Array<TaudInstEnvPoint>, // 8 points, value 0x00-0x3F
|
||||||
var panEnvelopes: Array<TaudInstEnvPoint> // 8 points, value 0x00-0xFF (0x80 = centre)
|
var panEnvelopes: Array<TaudInstEnvPoint> // 8 points, value 0x00-0xFF (0x80 = centre)
|
||||||
) {
|
) {
|
||||||
constructor(index: Int) : this(index, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
constructor(index: Int) : this(index, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xFF,
|
||||||
Array(8) { TaudInstEnvPoint(0x3F, ThreeFiveMiniUfloat(0)) },
|
Array(8) { TaudInstEnvPoint(0x3F, ThreeFiveMiniUfloat(0)) },
|
||||||
Array(8) { TaudInstEnvPoint(0x80, ThreeFiveMiniUfloat(0)) })
|
Array(8) { TaudInstEnvPoint(0x80, ThreeFiveMiniUfloat(0)) })
|
||||||
|
|
||||||
@@ -2361,7 +2381,7 @@ class AudioAdapter(val vm: VM) : PeriBase(VM.PERITYPE_SOUND) {
|
|||||||
12 -> (samplePtr.ushr(16).and(15).shl(4) or loopMode.and(3)).toByte()
|
12 -> (samplePtr.ushr(16).and(15).shl(4) or loopMode.and(3)).toByte()
|
||||||
13 -> volEnvSustain.toByte()
|
13 -> volEnvSustain.toByte()
|
||||||
14 -> panEnvSustain.toByte()
|
14 -> panEnvSustain.toByte()
|
||||||
15 -> 0
|
15 -> instGlobalVolume.toByte()
|
||||||
in 16..30 step 2 -> volEnvelopes[(offset - 16) / 2].value.toByte()
|
in 16..30 step 2 -> volEnvelopes[(offset - 16) / 2].value.toByte()
|
||||||
in 17..31 step 2 -> volEnvelopes[(offset - 17) / 2].offset.index.toByte()
|
in 17..31 step 2 -> volEnvelopes[(offset - 17) / 2].offset.index.toByte()
|
||||||
in 32..46 step 2 -> panEnvelopes[(offset - 32) / 2].value.toByte()
|
in 32..46 step 2 -> panEnvelopes[(offset - 32) / 2].value.toByte()
|
||||||
@@ -2396,7 +2416,7 @@ class AudioAdapter(val vm: VM) : PeriBase(VM.PERITYPE_SOUND) {
|
|||||||
}
|
}
|
||||||
13 -> { volEnvSustain = byte }
|
13 -> { volEnvSustain = byte }
|
||||||
14 -> { panEnvSustain = byte }
|
14 -> { panEnvSustain = byte }
|
||||||
15 -> {}
|
15 -> { instGlobalVolume = byte and 0xFF }
|
||||||
|
|
||||||
in 16..30 step 2 -> volEnvelopes[(offset - 16) / 2].value = byte
|
in 16..30 step 2 -> volEnvelopes[(offset - 16) / 2].value = byte
|
||||||
in 17..31 step 2 -> volEnvelopes[(offset - 17) / 2].offset = ThreeFiveMiniUfloat(byte)
|
in 17..31 step 2 -> volEnvelopes[(offset - 17) / 2].offset = ThreeFiveMiniUfloat(byte)
|
||||||
|
|||||||
Reference in New Issue
Block a user