271 lines
9.6 KiB
Plaintext
271 lines
9.6 KiB
Plaintext
|
|
The XM module format description for XM files version $0104.
|
|
|
|
By Mr.H of Triton in 1994.
|
|
|
|
- Be prepared! Are you sure you want to know? :-)
|
|
|
|
============================================================================
|
|
|
|
|
|
******************************
|
|
* The XM file structure: *
|
|
******************************
|
|
|
|
Offset Length Type
|
|
|
|
0 17 (char) ID text: 'Extended module: '
|
|
17 20 (char) Module name, padded with zeroes
|
|
37 1 (char) $1a
|
|
38 20 (char) Tracker name
|
|
58 2 (word) Version number, hi-byte major and low-byte minor
|
|
The current format is version $0103
|
|
|
|
60 4 (dword) Header size
|
|
+4 2 (word) Song length (in patten order table)
|
|
+6 2 (word) Restart position
|
|
+8 2 (word) Number of channels (2,4,6,8,10,...,32)
|
|
+10 2 (word) Number of patterns (max 256)
|
|
+12 2 (word) Number of instruments (max 128)
|
|
+14 2 (word) Flags: bit 0: 0 = Amiga frequency table (see below);
|
|
1 = Linear frequency table
|
|
+16 2 (word) Default tempo
|
|
+18 2 (word) Default BPM
|
|
+20 256 (byte) Pattern order table
|
|
|
|
Patterns:
|
|
---------
|
|
|
|
? 4 (dword) Pattern header length
|
|
+4 1 (byte) Packing type (always 0)
|
|
+5 2 (word) Number of rows in pattern (1..256)
|
|
+7 2 (word) Packed patterndata size
|
|
|
|
? ? Packed pattern data
|
|
|
|
Instruments:
|
|
------------
|
|
|
|
? 4 (dword) Instrument size
|
|
+4 22 (char) Instrument name
|
|
+26 1 (byte) Instrument type (always 0)
|
|
+27 2 (word) Number of samples in instrument
|
|
|
|
If the number of samples > 0, then the this will follow:
|
|
|
|
! +29 4 (dword) Sample header size
|
|
! +33 96 (byte) Sample number for all notes
|
|
! +129 48 (byte) Points for volume envelope
|
|
! +177 48 (byte) Points for panning envelope
|
|
! +225 1 (byte) Number of volume points
|
|
! +226 1 (byte) Number of panning points
|
|
! +227 1 (byte) Volume sustain point
|
|
! +228 1 (byte) Volume loop start point
|
|
! +229 1 (byte) Volume loop end point
|
|
! +230 1 (byte) Panning sustain point
|
|
! +231 1 (byte) Panning loop start point
|
|
! +232 1 (byte) Panning loop end point
|
|
! +233 1 (byte) Volume type: bit 0: On; 1: Sustain; 2: Loop
|
|
! +234 1 (byte) Panning type: bit 0: On; 1: Sustain; 2: Loop
|
|
! +235 1 (byte) Vibrato type
|
|
! +236 1 (byte) Vibrato sweep
|
|
! +237 1 (byte) Vibrato depth
|
|
! +238 1 (byte) Vibrato rate
|
|
! +239 2 (word) Volume fadeout
|
|
! +241 2 (word) Reserved
|
|
!
|
|
! Sample headers:
|
|
! ---------------
|
|
!
|
|
! ? 4 (dword) Sample length
|
|
! +4 4 (dword) Sample loop start
|
|
! +8 4 (dword) Sample loop length
|
|
! +12 1 (byte) Volume
|
|
! +13 1 (byte) Finetune (signed byte -16..+15)
|
|
! +14 1 (byte) Type: Bit 0-1: 0 = No loop, 1 = Forward loop,
|
|
! 2 = Ping-pong loop;
|
|
! 4: 16-bit sampledata
|
|
! +15 1 (byte) Panning (0-255)
|
|
! +16 1 (byte) Relative note number (signed byte)
|
|
! +17 1 (byte) Reserved
|
|
! +18 22 (char) Sample name
|
|
!
|
|
! Sample data:
|
|
! ------------
|
|
!
|
|
! ? ? Sample data (signed): The samples are stored
|
|
! as delta values. To convert to real data:
|
|
!
|
|
! old=0;
|
|
! for i=1 to len
|
|
! new=sample[i]+old;
|
|
! sample[i]=new;
|
|
! old=new;
|
|
|
|
|
|
|
|
***********************
|
|
* Pattern format: *
|
|
***********************
|
|
|
|
The patterns are stored as ordinary MOD patterns, except that each
|
|
note is stored as 5 bytes:
|
|
|
|
? 1 (byte) Note (0-71, 0 = C-0)
|
|
+1 1 (byte) Instrument (0-128)
|
|
+2 1 (byte) Volume column byte (see below)
|
|
+3 1 (byte) Effect type
|
|
+4 1 (byte) Effect parameter
|
|
|
|
A simle packing scheme is also adopted, so that the patterns not become
|
|
TOO large: Since the MSB in the note value is never used, if is used for
|
|
the compression. If the bit is set, then the other bits are interpreted
|
|
as follows:
|
|
|
|
bit 0 set: Note follows
|
|
1 set: Instrument follows
|
|
2 set: Volume column byte follows
|
|
3 set: Effect follows
|
|
4 set: Guess what!
|
|
|
|
It is very simple, but far from optimal. If you want a better,
|
|
you can always repack the patterns in your loader.
|
|
|
|
|
|
|
|
******************************
|
|
* Volumes and envelopes: *
|
|
******************************
|
|
|
|
The volume formula:
|
|
|
|
FinalVol=(FadeOutVol/65536)*(EnvelopeVol/64)*(GlobalVol/64)*(Vol/64)*Scale;
|
|
|
|
The panning formula:
|
|
|
|
FinalPan=Pan+(EnvelopePan-32)*(128-Abs(Pan-128))/32;
|
|
|
|
Envelope:
|
|
---------
|
|
|
|
The envelopes are processed once per frame, instead of every frame where
|
|
no new notes are read. This is also true for the instrument vibrato and
|
|
the fadeout. Since I am so lazy and the tracker is rather self-explaining
|
|
I am not going to write any more for the moment.
|
|
|
|
|
|
********************************
|
|
* Periods and frequencies: *
|
|
********************************
|
|
|
|
PatternNote = 0..95 (0 = C-0, 95 = B-7)
|
|
|
|
FineTune = -128..+127 (-128 = -1 halftone, +127 = +127/128 halftones)
|
|
RelativeTone = -96..95 (0 => C-4 = C-4)
|
|
|
|
RealNote = PatternNote + RelativeTone; (0..118, 0 = C-0, 118 = A#9)
|
|
|
|
Linear frequence table:
|
|
-----------------------
|
|
|
|
Period = 10*12*16*4 - Note*16*4 - FineTune/2;
|
|
Frequency = 8363*2^((6*12*16*4 - Period) / (12*16*4));
|
|
|
|
Amiga frequence table:
|
|
----------------------
|
|
|
|
Period = (PeriodTab[(Note MOD 12)*8 + FineTune/16]*(1-Frac(FineTune/16)) +
|
|
PeriodTab[(Note MOD 12)*8 + FineTune/16]*(Frac(FineTune/16)))
|
|
*16/2^(Note DIV 12);
|
|
(The period is interpolated for finer finetune values)
|
|
Frequency = 8363*1712/Period;
|
|
|
|
PeriodTab = Array[0..12*8-1] of Word = (
|
|
907,900,894,887,881,875,868,862,856,850,844,838,832,826,820,814,
|
|
808,802,796,791,785,779,774,768,762,757,752,746,741,736,730,725,
|
|
720,715,709,704,699,694,689,684,678,675,670,665,660,655,651,646,
|
|
640,636,632,628,623,619,614,610,604,601,597,592,588,584,580,575,
|
|
570,567,563,559,555,551,547,543,538,535,532,528,524,520,516,513,
|
|
508,505,502,498,494,491,487,484,480,477,474,470,467,463,460,457);
|
|
|
|
|
|
*************************
|
|
* Standard effects: *
|
|
*************************
|
|
|
|
0 Appregio
|
|
1 (*) Porta up
|
|
2 (*) Porta down
|
|
3 (*) Tone porta
|
|
4 (*) Vibrato
|
|
5 (*) Tone porta+Volume slide
|
|
6 (*) Vibrato+Volume slide
|
|
7 (*) Tremolo
|
|
8 Set panning
|
|
9 Sample offset
|
|
A (*) Volume slide
|
|
B Position jump
|
|
C Set volume
|
|
D Pattern break
|
|
E1 (*) Fine porta up
|
|
E2 (*) Fine porta down
|
|
E3 Set gliss control
|
|
E4 Set vibrato control
|
|
E5 Set finetune
|
|
E6 Set loop begin/loop
|
|
E7 Set tremolo control
|
|
E9 Retrig note
|
|
EA (*) Fine volume slide up
|
|
EB (*) Fine volume slide down
|
|
EC Note cut
|
|
ED Note delay
|
|
EE Pattern delay
|
|
F Set tempo/BPM
|
|
G Set global volume
|
|
H (*) Global volume slide
|
|
K Key off
|
|
L Set envelope position
|
|
P (*) Panning slide
|
|
R (*) Multi retrig note
|
|
T Tremor
|
|
X1 (*) Extra fine porta up
|
|
X2 (*) Extra fine porta down
|
|
|
|
(*) = If the command byte is zero, the last nonzero byte for the
|
|
command should be used.
|
|
|
|
*********************************
|
|
* Effects in volume column: *
|
|
*********************************
|
|
|
|
All effects in the volume column should work as the standard effects.
|
|
The volume column is interpreted before the standard effects, so
|
|
some standard effects may override volume column effects.
|
|
|
|
Value Meaning
|
|
|
|
0 Do nothing
|
|
$10-$50 Set volume Value-$10
|
|
: : :
|
|
: : :
|
|
$60-$6f Volume slide down
|
|
$70-$7f Volume slide up
|
|
$80-$8f Fine volume slide down
|
|
$90-$9f Fine volume slide up
|
|
$a0-$af Set vibrato speed
|
|
$b0-$bf Vibrato
|
|
$c0-$cf Set panning
|
|
$d0-$df Panning slide left
|
|
$e0-$ef Panning slide right
|
|
$f0-$ff Tone porta
|
|
|
|
|
|
============================================================================
|
|
|
|
This should be just about everything (I hope?). You will probably need
|
|
some information about the MOD format and maybe about S3M.
|
|
|
|
Have fun!
|
|
|
|
Fredrik Huss / Mr.H of Triton
|