The id Software Music Format (IMF) is a raw music format that stores the actual bytes sent to the Adlib's OPL2 chip. For this reason it is a very simple format to process.
There are two versions of the IMF format: Type-0 format and Type-1 format. In a Type-0 file, the whole file is Adlib data that is played until the end of the file is reached. Type-1 files are actually ripped chunks from an AudioT Format file. No game ever actually used Type-1 IMFs that were not stored inside an AudioT file. The two initial bytes contain the size of the Adlib data (not including the two bytes themselves), so only this much data is played. This means it's possible to store arbitrary data in a Type-1 IMF file after the song data (see #Tag Data below.)
As a matter of luck, the first two data bytes in a Type-0 files are almost always 0x00 0x00, so this can be used to detect the file format version. If the first two bytes match the length of the file it is likely Type-1, but be aware that trailing data will mean this is not always true. Otherwise the only other way is to parse all the register/value pairs in the file and ensure the register is within range (e.g. registers 0xA0 to 0xA9 are valid, but 0xAA to 0xAF should never be used.) Note that 0x00 is actually an invalid register, but must be treated as valid since the files usually begin by writing 0x00 to register 0x00.
Another way to detect the type of an IMF file is to examine the first few instructions in the IMF file. The idea is that the first few IMF commands set up the AdLib registers and therefore should have no delay. Even if there is a delay, it would normally be relatively low compared to the combined 16-bit value of the (register, value) pair.
In the code given above, if the file is a chunk (Type-1), then sum1 contains the sum of all (register, value) pairs and sum2 contains the sum of all delays. If it's a plain IMF file (Type-0), the sums are swapped.
The only case in which this detection would fail is IMF data that writes a bunch of zeroes to register zero (which would be pointless since that register is undefined) and/or has very large delays (which would be pointless because it would lead to delays of up to a minute before the next IMF command would be processed, resulting in multiple minutes of silence before the song actually starts playing notes).
|UINT16LE||iLength||Song data length in bytes (Type-1 format only)|
|BYTE[iLength]||cAdlibData||Song data (see below) - |
|BYTE||cExtraData||Arbitrary data/tags (Type-1 format only, see #Tag Data below)|
Note that for Type-1 files, the initial two bytes (the "song data length") are likely to be the filesize minus two, as the two initial bytes aren't counted. The obvious exception to this is if there is trailing data at the end of the OPL data, such as an info tag.
The song data is composed of four-byte "units":
The data byte is sent to the specified register on the Adlib card, followed by a delay for the specified number of cycles. For a 560Hz IMF file, there are 560 cycles in one second (see #Timing below), so a delay of 560 would result in one second of silence (and likewise in a 700Hz IMF the delay value would need to be 700 to produce one second of silence.) A delay of 1 would wait for a single cycle, and a delay of zero means the next register/data pair should be sent immediately (so in a single 'cycle', data would be sent continuously until the next non-zero delay value is reached.)
IMF files exist at three known speeds. Unfortunately this is determined by the game, not the IMF file, so tempo cannot be determined from the music files alone. Extracted IMFs can be compared to discern their speeds. The known speeds are:
|280Hz||Duke Nukem II|
|560Hz||Bio Menace, Commander Keen, Cosmo's Cosmic Adventures, Monster Bash|
|700Hz||Blake Stone, Major Stryker, Operation Body Count, Wolfenstein 3-D|
The easiest method to tell the files apart is to treat all files with a .WLF extension as 700Hz and all .IMF files as 560Hz. Since Duke II is the odd one out, it is usually ignored since doubling the value of all the delay bytes conveniently turns it into a 560Hz .IMF.
As IMF files contain Adlib music for games that may also have Adlib sound effects, care must be taken to ensure that IMF music and any sound effects can share the OPL chip without conflict. This is done by reserving the OPL's first channel for sound effects, leaving eight remaining channels available for use in IMF files. This has been confirmed by automated inspection of the IMF files from the following games, all of which have no data on OPL channel #0 beyond 2-3 initialisation commands: Bio Menace, Blake Stone, Commander Keen 4-6, Cosmo's Cosmic Adventures, Duke Nukem II, Major Stryker, Monster Bash, Operation Body Count, Wolfenstein 3-D.
In situations where channel #0 is not reserved and is used by the IMF file, when it is placed back into the game it interferes with the sound effects causing distortion, transposition, and otherwise resulting in broken sound effects. This can happen when an IMF file is created using a utility that does not take into account the fact that channel #0 must be left unused. See the end of this page for a list of utilities that can create IMF files and whether they treat channel #0 correctly.
It is worth noting that channel #0 is unused even games such as Cosmo and Monster Bash, which do not use Adlib sound effects (Cosmo has PC speaker effects only and Monster Bash has PC speaker and digitised PCM audio.) It is also worth mentioning that some IMF songs from Monster Bash make use of the OPL's rhythm-mode, which trades three note-producing channels for five percussion channels.
In a Type-1 IMF file it's possible to store data after the end of a song (as per the length given in the first two bytes of the file.) There are a few uses for this - some games store additional (unused) data there generated when the files were added to the game's group file, and others have repurposed this area to store information about the song itself (title, artist, etc.)
The tag data was originally written to the AudioT files by Id Software's tool Muse and was probably only processed by that tool. The Wolfenstein 3D source code reads the entire chunk from the AudioT file (including any tag data), but it only ever uses the song length and the song data.
For those files which were distributed with additional data in this area, it is not entirely clear what the purpose of this data is. It was apparently added when the source IMF files were compiled into a group audio file by Muse. (They appear not to be part of the source IMF files as there are occurrences where a file consists solely of tag data.) The format appears to be the same in all games that use it (such as Bio Menace or Wolfenstein 3D) but it is not supported by any IMF players.
|char||strRemarks||Song comment/message, usually source file name.|
|char||cProg||Data from the compiler?|
It is also possible to store tags there, and this simple format is supported by most IMF players:
|char||cProg||Name of the first program that added these tags (eight bytes + terminating NULL, pad out with NULLs if necessary.)|
Note that the char strings are variable-length NULL-terminated strings. Their maximum length is 256 bytes *including* the terminating NULL, meaning the string will only ever contain 255 characters or less, plus the terminating-NULL. Of course the string will normally be much shorter, and an empty string will consist of a single 0x00 byte.
This tag format is supported by AdPlug when playing IMFs. The tag format can also be used with .raw files, but no players officially support it yet.
Note that the tags should begin directly after the IMF data, so in other words reading in the first two bytes of the file (the "song length") and then seeking forward that many bytes, should put the file pointer at the start of the tag block (so the next byte that will be read in should be 0x1A, if the tags are present.)
This format has been used in the following games:
- Bio Menace
- Blake Stone
- Catacomb 3D
- Commander Keen 4-6
- Corridor 7
- Cosmo's Cosmic Adventures
- Duke Nukem II
- Hocus Pocus
- Major Stryker
- Monster Bash
- Operation Body Count
- Realms of Chaos (beta version only)
- Wolfenstein 3-D
The following utilities work with this file format.
Convert other formats to IMF
|Channel #0 left blank for SFX|
|IMFCreator creates IMF files from MIDI files in one step and also includes a preview feature, from the WinWolf3D website||Yes||Yes||Yes||Both?||Yes|
|MIDI2MUS then MUS2IMF can be used together to make IMF files||?||?||?||?||No?|
|DRO2IMF can convert DOSBox OPL captures into IMF files||Requires recompilation||Yes||Requires recompilation||Type-1 only||No|
|CMF2IMF converts CMF files into IMF files||Yes||Yes||Yes||Both||Not yet|
Convert IMF to other formats
- DRO2MIDI converts IMF to MIDI files