IT filters

This commit is contained in:
minjaesong
2026-05-01 23:19:49 +09:00
parent a4adc428d0
commit fe59df18f7
7 changed files with 186 additions and 73 deletions

View File

@@ -2002,8 +2002,10 @@ Instrument bin: Registry for 256 instruments, formatted as:
Uint16 Loop Start (can be smaller than Play Start)
Uint16 Loop End
Bit8 Sample Flags
0b 0000 00pp
0b 0000 0spp
pp: loop mode. 0-no loop, 1-loop, 2-backandforth, 3-oneshot (ignores note length unless overridden by other notes)
s: loop is sustain (key-off escapes the loop)
- IT: look for sample's SusLoop flag
Bit16 Volume envelope sustain/loops and flags
* Sustain is implemented by enabling 't' flag. FastTracker has no 'Sus Loop' but only 'Sus Point'; use same value for start and end index
0b 0ut sssss pcb eeeee
@@ -2051,26 +2053,50 @@ Instrument bin: Registry for 256 instruments, formatted as:
Byte 2: Time until the next point, in seconds (3.5 Unsigned Minifloat). 0 = hold at this point indefinitely.
Uint8 Instrument Global Volume (0..255)
* ImpulseTracker has range of 0..128; multiply by (255/128) then round to int
- ImpulseTracker has samplewise default volume (0..64) and samplewise global volume (0..64), and they must be taken into account because Taud has no samplewise config, following the ImpulseTracker spec
* FastTracker2 has range of 0..64; multiply by (255/64) then round to int
Uint8 Volume Fadeout low bits (IT: 1..256; XM: 0..255)
Bit8 Fadeout and vibrato
0b dddd ffff
0b 0000 ffff
f: Volume Fadeout high bits
d: Vibrato depth
Uint8 Volume swing (0..255 full range)
Uint8 Vibrato speed
* ImpulseTracker has samplewise vibrato speed (0..64), and they must be taken into account because Taud has no samplewise config
* FastTracker2 has instrumentwise config (0..255)
* The spec follows FastTracker2, and conversion must be performed when importing from FastTracker2
Uint8 Vibrato sweep
* FastTracker2 instrument config
Uint8 Default pan value (0..255 full range)
* ImpulseTracker has samplewise default volume and samplewise global volume, and they must be taken into account because Taud has no samplewise config
Uint16 Pitch-pan centre (4096-TET note value)
Sint8 Pitch-pan separation (-128..127 full range)
Uint8 Pan swing (0..255 full range)
Uint8 Default cutoff (0..254 full range, 255 to off (-1 on IT). Effect range equals to that of ImpulseTracker -- 127 in IT is equal to 254 in Taud)
Uint8 Default resonance (0..254 full range, 255 to off (-1 on IT). Effect range equals to that of ImpulseTracker -- 127 in IT is equal to 254 in Taud)
Uint16 Sample detune (in 4096-TET unit) (XM finetune scale need to be rescaled accordingly)
Byte[6] Reserved
Bit8 Instrument Flag
0b 000 www nn
n: New note action. 00: note off, 01: note cut, 10: continue, 11: note fade (arranged differently to IT)
ww: Vibrato waveform (IT: sample config, FT2: instrument config). 00: sine, 01: ramp-down saw, 10: square, 11: random, 100: ramp-up saw (FT2 only)
Uint8 Vibrato Depth (0..255 full range)
* ImpulseTracker has range of 0..32 ON THE SAMPLE SETTINGS; multiply by (255/32) then round to int
* FastTracker2 has range of 0..16; multiply by (255/16) then round to int
Uint8 Vibrato Rate (0..255 full range)
* ImpulseTracker sample config. The spec follows ImpulseTracker precisely
Byte[3] Reserved
TODO:
* implement Instrument Flag, Vibrato Depth, Vibrato Rate, other samplewise/instrumentwise changes to it2taud
* implement sample loop sustain
* implement new note action on the audio engine (IT uses "background channels", maybe we can do the same but make "background channels" mixer-private)
* implement S6x and S7x command
* implement Vxx (set global volume) and Wxx command (global volume slide)
* Amiga mode freq shift now "underdelivers" (pitch bend not "strong" enough)
* cue and pattern compression of the Taud format (taud_common.py, taud.mjs)
* figure out how IT (8 bits) and FT2 (12 bits) handles volume fadeout numbers, and come up with a compatible Taud spec, then implement
TODO: after *2taud.py is done, extend with 25 envelopes and add Pitch/Filter features. 192 bytes per instrument granted (48k space). This is a breaking change.
TODO: use it2taud.py to implement pitch/filter -- don't delete rerender code yet
Play Data: play data are series of tracker-like instructions, visualised as:
@@ -2371,8 +2397,8 @@ prefixes:
Note: custom notations will use internal index 65535 down to 65520 (index 0 = 65535, index 15 = 65520)
Note Tuning:
1. "Base Note at C3" will be derived using "Current Tuning Base Note" and "Frequency at the Base Note" from the song table. If the values are A3,440Hz, it will be converted to C3,261.6255653Hz
2. Frequency at C4 will be (Base Note at C3) × (Interval Size)
1. "Base Note at C4" will be derived using "Current Tuning Base Note" and "Frequency at the Base Note" from the song table. If the values are A4,440Hz, it will be converted to C4,261.6255653Hz
2. Frequency at C5 will be (Base Note at C4) × (Interval Size)
3. 4096 notes will be equidistance-distributed between (Frequency at C3) and (Frequency at C4), with logarithmic pitch progression; this builds the frequency-offset table
4. Frequency-Offset Table from the previous step will be applied against the "Base Note at C3" to construct the notes within the notation. Value at index zero of the Frequency Table must be 0
5. The progress will continue outside the "root interval" (C3..C4) to build a complete note-to-frequency table