- Extension: it
it would be interesting to find out how the MIDI/timestamp stuff after the pointer list works... the other TODOs I (GM) know about
IT214 sample compression
If bit 3 (0x08 compressed samples) is set, the sample is compressed.
- Compression is split into blocks, where the uncompressed size is 0x8000 bytes (0x4000 samples for 16-bit, and 0x8000 otherwise).
- Once a block is decompressed (or at least fails to decompress), the data is then delta decoded.
- The sample conversion flags are applied per-block rather than for the whole sample. These are probably applied after delta decoding.
- IT215 samples are IT214-compressed samples with the "Delta" flag (not the "Byte Delta" flag) set in the conversion flags.
- Each compressed block starts with a 16-bit length field, and then the bitstream is encoded in little-endian binary (LSB up).
- There is a "bit width" initially set to 9 for 8-bit samples, and 17 for 16-bit samples.
- The "bit width" is changed by special values inside their respective types. If such a special value is not triggered, the values are read as signed values, and unpacked
- There are three types of blocks, which we will call A, B, and C.
- Type A: Bit widths 1 through 6. Special value is 1 in the top bit and 0s for the rest. If such a value is triggered, it then reads 3 (8-bit) or 4 (16-bit) bits for calculating the new bit width (see below).
- Type B: Bit widths 7 through n, where n is 8 for 8-bit samples and 16 for 16-bit. Special values are 0...0100 through 1...1011 for 8-bit and 0...01000 through 1...10111 for 16-bit. If such a value is triggered, subtract 0...0100 (8-bit) or 0...01000 (16-bit) and use that to calculate the new bit width (see below).
- Type C: Bit width n+1. If the top bit is set, the lower 8 bits plus 1 are the new bit width.
- Barring type C, the new width selected is (v+1), except where v+1 >= the previous bit width, in which case the new width is v+1.
- If an invalid bit width is selected (only possible in type C), the decompressor terminates and leaves all the remaining values as 0 before delta decoding.
- The defacto standard for compressed stereo samples (as set by XMPlay) is to decompress the left channel entirely separately from the right channel (where the data follows immediately afterwards), rather than decompress them together and separate afterwards.
if this is a bit too messy, feel free to tidy it up
The resonant filter (added in 2.14p3) uses the following formula:
- K[n] = a * S[n] + b * K[n-1] + c * K[n-2]
- K[n] is the outputted value at time n
- S[n] is the input value at time n
- a = 1/(1+d+e)
- b = (d+2e) / (1+d+e)
- c = -e / (1+d+e)
- d = 2pr+2p-1
- e = r^2
- r = playback_frequency * (2.0*PI*110.0*(2.0^0.25)) / (2^(cutoff/24.0))
- p = 10^((-resonance*24.0)/(128.0f*20.0f))
Some formulae can be simplified:
- d = (2p)(r+1)-1
- b = (d+2e)*a
- c = -e*a
IT uses a table for 2p, and calculates r on the fly. The number "(2.0*PI*110.0*(2.0^0.25))" is precalculated.
For more information:
Set song speed.
Jump to Order.
- If this comes after an SBx loop command, the effect is done as-is.
Break to row.
- If this comes after an SBx loop command, the effect is ignored. TODO: look into how this information is relayed
Pitch slide down.
Pitch slide up.
Slide to note.
Vibrato with speed x*4, depth y*4.
This behaves in a very weird way, and virtually nothing does it right (though most do it "acceptably close").
Vibrato retriggers in the following situations:
- When the last time vibrato was used, it was on a different instrument and/or sample (TODO: confirm which)
Vibrato does NOT retrigger on:
- New note
- New instrument/sample, barring the exception given above
TODO: look into "random waveform".
- Pre-add the vibrato speed to the vibrato offset, except when Old Effects is enabled and this is tick 0.
- Load the value "v" from the selected vibrato table (available in ITTECH.TXT)
- Note that "random" does NOT use a table, but actually spits out a random number.
- Multiply v by the vibrato depth.
- If old effects are enabled, v = ~(v<<1) (in other words, v = -(v*2+1)).
- If negative, do a one's compliment negation of v (that is, v = -(v+1)), and use the slide down tables (or for Amiga slides, just remember to slide down instead of up). Otherwise, use the slide up tables.
- v = (v+32)>>6 (that is, v = (v+32)/64). Yes, this is rounded.
- If using linear slides, check if v < 16. If so, do a fine slide by v. Otherwise, do a normal slide by v>>2 (that is, v/4). It only does one or the other.
- Otherwise, just do a fine Amiga slide by v.
Tremor with ontime x and offtime y.
Dual command: H00 & Dxx
Dual command: G00 & Dxx
Set channel volume.
- If xx is > 0x40, the effect is ignored.
Channel volume slide.
Set sample offset.
Tremolo with speed x, depth y.
Sxy - Miscellaneous effects
Set filter. Not implemented in Impulse Tracker.
- S00 - repeats the last nonzero Sxx effect for the channel.
Set glissando control. Not implemented in Impulse Tracker.
Set finetune. Not Implemented in Impulse Tracker.
Set vibrato waveform.
Values for x:
- 0: Sine wave
- 1: Ramp down
- 2: Square wave
- 3: Random wave
- If x > 3, the effect is ignored.
Set tremolo waveform.
Uses the same waveform table as S3x. If x > 3, the effect is ignored.
Set panbrello waveform.
Uses the same waveform table as S3x.
- If x > 3, the effect is ignored.
- This effect retriggers the panbrello waveform position.
Pattern delay for x ticks.
Past note cut.
Past note off.
Past note fade.
Set NNA to note cut.
Set NNA to continue.
Set NNA to note off.
Set NNA to note fade.
Turn off volume envelope.
Turn on volume envelope.
Turn off panning envelope.
Turn on panning envelope.
Turn off pitch envelope.
Turn on pitch envelope.
Set panning position.
Set surround sound.
Set high value of sample offset yxx00h
Note cut after x ticks.
Note delay for x ticks.
Pattern delay for x rows
Set parameterised MIDI macro.
Fine vibrato with speed x*4, depth y.
Set global volume.
- If xx is > 0x80, the effect is ignored.
Global volume slide.
- IT versions < 1.06 had a bug where a slide up would clip to 0 instead of 128.
Set panning position. Sets panning to (xx + 2) div 4
Panbrello with speed x, depth y.
- If the panbrello waveform is set to 'Random', then the speed is interpreted as a delay.