CDFM Format
Format type | Music |
---|---|
Notation type | Custom |
Instruments | OPL, PCM |
Max channel count | 13 |
Max track count | 1 |
Max pattern count | 128 |
Max order count | 256 |
Tags? | None |
Games |
CDFM Format (alternatively: 670 Format) was developed by the demogroup Renaissance for their Amnesia demo, and was later used in their game Zone 66. It consists of either nine Adlib channels (for Adlib hardware), nine OPL and four PCM channels (for Sound Blaster hardware) or patches to be played as MIDI instruments (for GUS hardware.)
In Zone 66, most songs have hardware-specific versions, even where the SB song could drop the PCM channels and be played on Adlib. In these cases the PCM drum channels have been replaced with OPL instruments.
File format
The file begins with a header. Those fields marked [GUS only] are missing entirely in SoundBlaster/AdLib songs, and those fields marked [AdLib/SB only] are missing entirely in the GUS variant of the song format.
Data type | Name | Description |
---|---|---|
UINT32LE | sampleOffset | [GUS only] Offset of instrument samples from start of file |
BYTE | tempo | [Adlib/SB only] Playback speed, larger is slower [GUS only] Unknown, always 0x66, changing has no effect |
BYTE | patternListSize | Size of pattern list |
BYTE | numPatterns | Number of patterns in song |
BYTE | numDigInst | Number of PCM or GUS instruments in song |
BYTE | numOPLInst | [Adlib/SB only] Number of OPL instruments in song |
BYTE | loopDest | Index into patternOrder for next pattern to play after the final one when looping the song |
UINT32LE | sampleOffset | [Adlib/SB only] Offset of instrument samples from start of file |
UINT8[patternListSize] | patternOrder | Order of patterns in the song, patternListSize bytes in length |
UINT32LE[numPatterns] | patternOffset | Offset of each pattern's data, relative to the start of the pattern data |
PCM_INST[numDigInst] | pcmInst | [Adlib/SB only] 16 bytes of info for each digital (PCM) instrument |
OPL_INST[numOPLInst] | oplInst | [Adlib/SB only] 11-byte instrument patch for each FM (OPL) instrument |
GUS_INST[numDigInst] | gusInst | [GUS only] 11 bytes of info for each GUS patch |
The pattern data immediately follows. The patternOffset values are relative to this position, so a value of 0x00000000 corresponds to the first byte here.
PCM_INST is:
Data type | Name | Description |
---|---|---|
UINT32LE | address_ptr | Used to place address of sample start in memory - ignore when reading, write as 0x00000000 |
UINT32LE | length | Length of sample, in bytes |
UINT32LE | loopStart | Offset of loop return, in bytes, relative to start of sample |
UINT32LE | loopEnd | Offset of loop trigger, in bytes, relative to start of sample. Use 0x00FFFFFF for no loop. |
The PCM instruments begin at sampleOffset and are raw (no header) 8-bit unsigned PCM data. If the sample loops, as soon as playback reaches loopEnd (which could be before the end of the sample), playback will immediately jump to loopStart. The middle-C frequency for all PCM instruments is fixed at 8287 Hz (ProTracker standard).
OPL_INST is:
Data type | Name | OPL base register | Description |
---|---|---|---|
UINT8 | iFeedback | 0xC0 | Feedback/connection |
UINT8 | iModChar | 0x20 | Modulator characteristic (Mult, KSR, EG, VIB and AM flags) |
UINT8 | iModScale | 0x40 | Modulator key scaling/output level |
UINT8 | iModAttack | 0x60 | Modulator attack/decay level |
UINT8 | iModSustain | 0x80 | Modulator sustain/release level |
UINT8 | iModWaveSel | 0xE0 | Modulator wave select |
UINT8 | iCarChar | 0x23 | Carrier characteristic (Mult, KSR, EG, VIB and AM flags) |
UINT8 | iCarScale | 0x43 | Carrier key scaling/output level |
UINT8 | iCarAttack | 0x63 | Carrier attack/decay level |
UINT8 | iCarSustain | 0x83 | Carrier sustain/release level |
UINT8 | iCarWaveSel | 0xE3 | Carrier wave select |
The OPL base registers in this list are for the two operators controlling the first OPL channel. Adjust them accordingly for the relevant OPL channel.
GUS_INST is:
Data type | Name | Description |
---|---|---|
UINT8 | flags | Bitfield: 1=! Makes pitch higher, 2=loop, 16=! unknown - mutes instrument |
UINT16LE | rate | Playback sampling rate for pitch to be middle-C |
UINT32LE | loopStart | Sample offset, in bytes, of loop start |
UINT32LE | length | Length of sample, in bytes |
All sample data is 8-bit signed. If the loop bit is set (i.e. flags & 2) then when the end of the sample is reached playback jumps immediately to the byte offset indicated by loopStart.
Tempo
All songs use the standard module speed/tempo system. The tempo is fixed at 144, and the speed can be changed per song. For SB/AdLib songs, the speed is set once with the value obtained from the file header, while GUS songs include a 'set speed' command at the start of each pattern.
Pattern data (SB/AdLib)
The musical score data for SoundBlaster/AdLib files consists of a sequence of variable-length commands, in the following format:
0x00-0x0C: Play note
Command | Byte 2 | Byte 3 |
---|---|---|
0x00 | jfffnnnn | iiiivvvv |
Play a note on the given channel.
- The command byte is 0x00 through 0x0C. The value controls the channel used for the note:
- 0x00: digital 1
- 0x03: digital 4
- 0x04: FM 1
- 0x0C: FM 9
- 0x0D-0x0F: Invalid
- j: High (fifth) bit of instrument number.
- fff: The octave of the note to play. Middle-C is within octave 2 for digital channels (they have 4 octaves). FM channels have 7 octaves, and the middle-C is in octave 4.
- nnnn: The number of the note to play within the octave (0-11).
- iiii: The lower four bits of the instrument to use. A value of zero uses the first instrument. This is the first PCM instrument on a digital channel, and the first OPL instrument on an FM channel.
- vvvv: Note volume/velocity. 0x0 is almost silent, 0xF is full volume. Notes can be played with zero velocity and then faded in with subsequent volume change commands. Volume is linear for both digital and FM channels, which needs to be translated for FM channels (the OPL chip has a logarithmic volume curve).
Note that for FM channels, the channel number modulo 4 is added to the resulting FNUM OPL parameter. This causes the note to be slightly detuned, which is used in the Zone 66 soundtrack to fatten some sounds by playing them on two neighbouring FM channels.
0x20-0x2C: Set volume
Command | Byte 2 |
---|---|
0x20 | 0000vvvv |
Set the volume of the playing note on the given channel.
- The command byte is 0x20 through 0x2C, with the lower four bits representing the channel number as with playing a note.
- vvvv: Note volume/velocity. 0x0 is silent, 0xF is full volume.
0x40: Delay
Command | Byte 2 |
---|---|
0x40 | tttttttt |
Delay for the given number of ticks before continuing with the next event.
- tttttttt: Number of ticks to wait
0x60: End of pattern
Command |
---|
0x60 |
This must be the last command in each pattern. Playback will jump to the next pattern in the sequence specified in the song header.
0x80: Unknown
This command is not used in any known files and crashes Zone 66. Its purpose, or perhaps incomplete intended purpose, is unknown.
Pattern data (GUS)
The musical score data for GUS files also consists of a sequence of variable-length commands, however the commands are different from the ones used in SB/AdLib files. The commands are in the following format:
0x00: Delay
Command | Byte 2 |
---|---|
0x01 | tttttttt |
Delay for the given number of ticks before continuing with the next event.
- tttttttt: Number of ticks to wait
0x01: Set speed
Command | Byte 2 |
---|---|
0x01 | ssssssss |
Adjust the song playback speed.
- ssssssss: New speed. This is the same as the 'speed' in standard .mod files (i.e. the number of frames per row), with the module tempo fixed at 144.
0x02: End of pattern
Command |
---|
0x02 |
This must be the last command in each pattern. Playback will jump to the next pattern in the sequence specified in the song header.
0x40-0x4F: Play note
Command | Byte 2 | Byte 3 | Byte 4 |
---|---|---|---|
0x00 | ffffffff | ppppvvvv | iiiiiiii |
Play a note on the given channel.
- The command byte is always 0x40 through 0x4F. The value controls the channel used for the note:
- 0x00: GUS channel 1
- 0x01: GUS channel 2
- 0x0F: GUS channel 16 ! Assumed, please confirm
- ffffffff: Note. Add 25 to this value (i.e. transpose up by two octaves and one note) to obtain standard MIDI note numbers.
- pppp: Panning, 0=centre, 1=full right, 15=full left
- vvvv: Velocity, logarithmic, 0=silent, 1=1%, 2=4%, 3=7% ... 12=49.8%, 13=60%, 14=74.9%, 15=100%
- iiiiiiii: Instrument, 0=first, 1=second, etc.
0x80-0x8F: Set volume
Command | Byte 2 |
---|---|
0x80 | ppppvvvv |
Set the volume of the playing note on the given channel.
- The command byte is 0x80 through 0x8F, with the lower four bits representing the channel number as with playing a note.
- pppp: ! Assumed pan value, same as for note-on
- vvvv: Note volume/velocity. 0x0 is silent, 0xF is full volume.
Tools
The following tools are able to work with files in this format.
Name | Platform | Play? | Create new? | Modify? | Convert/export to other? | Import from other? | Access hidden data? | Edit metadata? | Notes |
---|---|---|---|---|---|---|---|---|---|
Camoto | Linux/Win | Yes | Yes; except GUS | Yes; except GUS | Yes | Yes; except GUS | N/A | N/A | Only supports 670 format as used in games. |
CDFM Tracker | DOS | Yes | Yes | Yes | No | No | N/A | N/A | Cannot not directly edit 670 files. However, it comes with a tool to convert them back into editable C67 files. |
OpenMPT (source) | DOS | Yes | No | No | No | No | N/A | N/A | Cannot not directly play 670 files, only C67 variant. Can use tools that come with CDFM Tracker to convert. |
Credits
This file format was reverse engineered by Malvineous. If you find this information helpful in a project you're working on, please give credit where credit is due. (A link back to this wiki would be nice too!)