
This is the documentation of the DMF file format versions 6 and up, as used by the original DOS xtracker and xtracker32.
- Versions up to 7 where only used in beta version of xtracker. Still there are quite a few songs available that use these versions.
- The xtracker final version used file format version 8
- xtracker32 extensions are marked as file format version 10.
DDMF (D-lusion digital music format) is a IFF-like chunk-orientated format which should be really easy to use. The following chunks exist:
- [DDMF] Format identifier
- [INFO] reserved
- [CMSG] Song message
- [SEQU] Sequencer, order to play patterns in
- [PATT] Patterndata
- [INST] Instrument data, reserved
- [SMPI] Sample-Information
- [SMPD] Sample-Data. Must be saved after [SMPI] chunk
- [SMPJ] Sample Jump Positions. Must be saved after [SMPI] chunk (v10+)
- [ENDE] EOF marker
| DDMF chunk - Format identifier |
| Offset | Description | Type |
| 00h | Chunk ID ('DDMF') | 4 Chars |
| 04h | File version | 1 Byte |
| 05h | Tracker software name | 8 Chars |
| 05h | Tracker software name | 8 Chars |
| 0dh | Song name - fill unused chars with 0 | 30 Chars |
| 2bh | Composer name - fill unused chars with 0 | 20 Chars |
| 3fh | Creation date - one byte for day, month, year+1900 | 3 Bytes |
| CMSG chunk - Song message |
| Offset | Description | Type |
| 00h | Chunk ID ('CMSG') | 4 Chars |
| 04h | Blocklength - Offset to start of next block. This does NOT include the Chunk ID or the blocklength field itself (so blocklength is the length of the current chunk - 8) | 1 dword |
| 08h | Filler - reservered (0) | 1 byte |
| 09h | Message - ASCII-Text with fixed length of 40 chars per line. Length of Message is blocklength-1 bytes | x chars |
| SEQU chunk - sequencer data |
| Offset | Description | Type |
| 00h | Chunk ID ('SEQU') | 4 Chars |
| 04h | Blocklength - (see above) | 1 dword |
| 08h | Sequencer loop start | 1 word |
| 0ah | Sequencer loop end | 1 word |
| 0ch | Sequencer data - every word represents one entry in the sequencer. Length is blocklength-4 ((blocklength-4)/2 sequencer entries) | x words |
| PATT chunk - pattern data |
| Offset | Description | Type |
| 00h | Chunk ID ('PATT') | 4 Chars |
| 04h | Blocklength - (see above) | 1 dword |
| 08h | Pattern entries (1-1024) - number of patterns in this song | 1 word |
| 0ah | Max tracks (1-32) - highest number of tracks used in all patterns | 1 byte |
| 0bh | Patterns - the following structure is repeated 'pattern entries' times | |
| Pattoffs. | Description | Type |
| 00h | Track entries (1-32) - number of tracks in this pattern | 1 Byte |
| 01h | Beat - the lower nibble of this byte is reserved. The upper nibble holds the number of rows per beat. A value of 64 in this field would result in every 4th row beeing highlighted (64 shr 4 = 4) | 1 Byte |
| 02h | Row entries - number of rows in this pattern | 1 Word |
| 04h | Patternlength - Length of the following pattern data in bytes = offset to begin of next pattern | 1 DWord |
| 08h | Patterndata - Compressed stream of pattern data. Sorry, now it's getting a bit more complex ;) The following structure is repeated 'Row entries' times: (Attention: If the last rows of the pattern are completely empty, then they won't be saved) | x Bytes |
|
[GLOBAL TRACK] ([TRACK] * [TRACK ENTRIES])
|
GLOBAL TRACK:
INFO - 1 Byte
(COUNTER) - 1 Byte
(DATA) - 1 Byte
INFO = zyxxxxxx
xxxxxx (lowest 6 bits) = Global track effect
y = reserved
z = counter saved (pack indicator)
In case the pack indicator is set, then the next byte in the stream will be COUNTER.
COUNTER is a (guess what ;) counter that is count down for every note row. There is no
global track information saved until counter is 0 again. At the begin of a pattern,
COUNTER always starts with 0.
If the pack indicator isn't set then no COUNTER is saved, instead you have to assume COUNTER beeing 0 which means that the next row will have a global track again.
If the global track effect is > 0, then a DATA byte containing the effect data is saved in the stream. Else there is no DATA byte.
|
TRACK:
INFO - 1 Byte
(COUNTER) - 1 Byte
(INSTRUMENT) - 1 Byte
(NOTE) - 1 Byte
(VOLUME) - 1 Byte
(INSTRUMENT EFFECT) - 2 Bytes
(NOTE EFFECT) - 2 Bytes
(VOLUME EFFECT) - 2 Bytes
INFO = 76543210
bit 0: reserved
bit 1: 1=volume effect saved
bit 2: 1=note effect saved
bit 3: 1=instrumend effect saved
bit 4: 1=volume saved
bit 5: 1=note saved
bit 6: 1=instrument saved
bit 7: 1=counter saved (pack indicator)
The following values are only saved if the corresponding bits in INFO are set.
COUNTER
See above - COUNTER is counted down for each row until it is zero. There is no data saved in this track until counter reaches zero. If the pack indicator isn't set, then there is no counter saved which means that the next row will have track data again.
INSTRUMENT
Instrument/Sample to play
NOTE
0 = No change
1-108 = Note in halfnote-steps, C0=1 up to H8=108.
109-128 = undefined
129-236 = This note is saved into the notebuffer, the current playing note won't be changed. The Notebuffer is used as a second parameter for effects like "portamento to note", where the effect parameter byte is already in use.
237-254 = undefined
255 = Note Off, sets the notes frequency to 0 hz
VOLUME
0 = undefined
1-255 = new volume, linear scaling
INSTRUMENT EFFECT
1. Byte: Instrument effect nr.
2. Byte: Instrument effect data
NOTE EFFECT
1. Byte: Note effect nr.
2. Byte: Note effect data
VOLUME EFFECT
1. Byte: Volume effect nr.
2. Byte: Volume effekt data
|
|
|
|
|
| SMPI chunk - Sample-Information |
| Offset | Description | Type |
| 00h | Chunk ID ('SMPI') | 4 Chars |
| 04h | Blocklength - (see above) | 1 dword |
| 08h | Sample entries - number of samples saved in the song | 1 Byte |
| 09h | Samples - the following structure is repeated 'Sample entries' times | Bytes |
| Sampleoff. | Description | Type |
| 00h | Samplename length (0-30) - number chars of samplename | 1 Byte |
| 01h | Samplename - the name of the sample | x Chars |
| x + 01h | Sample length - length of sample in bytes. Attention: This is the final length of the depacked sample (unlike the sample length in the SMPD chunk, which stores the packed length) | 1 Dword |
| x + 05h | Sample loop start - position of sample loop start in bytes | 1 Dword |
| x + 09h | Sample loop end - position of sample loop end in bytes | 1 Dword |
| x + 0dh | c3 frequency - frequency in hz of the sample at the note c-3. Valid range is 1000-45000 Hz | 1 Word |
| x + 0fh | Volume - Sample volume, 0 = not set, 1-255 = volume in linear scale | 1 Byte |
| x + 10h | Sample Type - Different flags that define the sample
xxxxxxx0 = no loop
xxxxxxx1 = sample is played looping. The sample plays from its beginning on until it reaches 'Sample loop end' and then repeats the range from 'Sample loop start' to 'Sample loop end'
xxxxxx0x = 8BIT Sample
xxxxxx1x = 16BIT Sample
xxxxXXxx = Compression type
xxxx00xx = Uncompressed signed PCM
xxxx01xx = Compression type 0 - modified huffmann
xxxx10xx = Compression type 1 - mp3
xxxx11xx = Compression type 2 - currently undefined
xxx0xxxx = mono sample
xxx1xxxx = stereo sample
xXXxxxxx = reserved
0xxxxxxx = sampledata is saved in SMPD chunk
1xxxxxxx = sampledata is saved in external libary
| 1 Byte |
| x + 11h | Library Name - library name in which the sample is stored. Fill with 0 if unused. ATTENTION: This field only exists in version 8 and above. (With xtracker32 it's unused for now) | 8 Bytes |
| x + 19h | Filler - reserved | 1 Byte |
| x + 1bh | CRC32 - crc32 over sampledata | 1 DWord |
|
| SMPD chunk - Sample-Data |
| Offset | Description | Type |
| 00h | Chunk ID ('SMPD') | 4 Chars |
| 04h | Blocklength - (see above) | 1 dword |
| 08h | Sample data - the following structure is repeated 'Sample entries' (from SMPI) times | Bytes |
| Sampleoff. | Description | Type |
| 00h | Sample data length - length of sample data stream in bytes. This is the real length of the possibly compressed data. For the real final length, see SMPI chunk. If this sample is empty or saved in a library file, then this field is set to 0 | 1 Dword |
| 04h | Sample data stream | x Bytes |
|
SMPJ chunk - Sample Jump points (This chunk exists from dmf version 10 and up) |
| Offset | Description | Type |
| 00h | Chunk ID ('SMPJ') | 4 Chars |
| 04h | Blocklength - (see above) | 1 dword |
| 08h | Sample jump points - the following structure is repeated 'Sample entries' (from SMPI) times | Bytes |
| Offset | Description | Type |
| 00h | Count of jump points following. 0=No jump points for this sample | 1 Byte |
| 01h | Jump points. This is the sample-offset in bytes (not samples!) to jump to if the JMP command is issued in a track. These are 32 bit signed integers. A value of -1 means that a jump-point is undefined. In this case the JMP command should be ignored. | x Integers |
|
| ENDE chunk - end of DDMF |
| Offset | Description | Type |
| 00h | Chunk ID ('ENDE') | 4 Chars |
|
|