AdLib MIDI Format
The AdLib MIDI Format is an Ad Lib music format, based on the standard MIDI format. The format has a custom header, but the actual music data is in standard MIDI notation. Despite this, it appears that it was never intended to be played on a MIDI device, as the patch numbers refer to indices into a companion OPL instrument bank in AdLib Timbre Bank Format.
In this respect it is similar to the CMF Format, which also stores OPL music in MIDI notation, but unlike CMF this format keeps the instruments in a separate file.
The file is arranged like this:
|UINT8||majorVersion||Major version number (usually 1)|
|UINT8||minorVersion||Minor version number (usually 0)|
|INT32LE||tuneId||Song identification number|
|char||tuneName||Song title, null terminated|
|UINT8||tickBeat||Number of ticks per beat|
|UINT8||beatMeasure||Number of beats per measure|
|INT32LE||totalTick||Length of song, in ticks|
|INT32LE||dataSize||Length of MIDI data block, in bytes|
|INT32LE||nrCommand||Total number of MIDI events in song, including final 0xFC "stop"|
|BYTE||filler||Padding, set to zero|
|UINT8||soundMode||OPL rhythm mode: 0=melodic (off), 1=percussive (on)|
|UINT8||pitchBRange||Pitchbend range (1-12)|
|UINT16||basicTempo||Song tempo, in beats-per-minute.|
|BYTE||filler2||Padding, set to zero|
|BYTE[dataSize]||data||Song data in standard MIDI format (same content as a MIDI MTrk block, almost)|
The only known version of this format is 1.0.
The MIDI delay bytes in the song data are in units of "ticks", as per normal. The fields tickBeat and beatMeasure can be used to convert ticks into beats and measures if desired, for example when drawing a musical staff.
The basicTempo field controls the song playback speed and is measured in beats per minute. The playback frequency can be calculated as follows:
frequency = (basicTempo / 60) * tickBeat
For a song that plays at 120BPM and with 10 ticks per beat, this works out as:
frequency = (120 / 60) * 10 = 20 Hz
Therefore playback should happen at 20 ticks per second to be at the correct tempo.
If soundMode is 0, then rhythm mode is off. Valid MIDI channels are 0 to 8 inclusive.
When soundMode is 1, then rhythm mode is on. Valid MIDI channels are 0 to 10, with 0 to 5 being melodic and 6 to 10 being percussive (see table below.) The official code actually treats any nonzero value as enabling rhythm mode, however only the values 0 and 1 should be used.
Both the top cymbal and the snare drum only use the OPL carrier registers, but the values for these registers are actually stored in the file's modulator fields. The carrier fields for these instruments appear to be unused. In other words, percussive instruments always have their settings loaded from the instrument's modulator fields, even when the values are loaded into the OPL chip's carrier registers.
|MIDI channel||Percussive instrument||Operator used in file||OPL cell|
|6||Bass drum|| Modulator
| 13 - Channel 7 Modulator|
16 - Channel 7 Carrier
|7||Snare drum||Modulator||17 - Channel 8 Carrier|
|8||Tom tom||Modulator||15 - Channel 9 Modulator|
|9||Top cymbal||Modulator||18 - Channel 9 Carrier|
|10||Hi-hat||Modulator||14 - Channel 8 Modulator|
There is no indicator whether a patch is percussive or melodic, so this is controlled entirely by which MIDI channel it is used on. It is possible to use the same patch for both percussive and melodic channels.
In percussive mode, the pitch of the single-operator percussive instruments is handled specially (that is, the snare drum, tom tom, top cymbal and hi-hat. The bass drum is not considered here.) When a note is played on MIDI channel 8 (tom-tom), the pitch on the other instruments is changed also. The changes are:
|MIDI channel||Percussive instrument||Note pitch|
|7||Snare drum||7 semitones higher than the last tom-tom note on MIDI channel 8|
|8||Tom tom||Use pitch as indicated in the MIDI note-on event|
|9||Top cymbal||Use pitch from last tom-tom note on MIDI channel 8|
|10||Hi-hat||7 semitones higher than the last tom-tom note on MIDI channel 8|
The initial frequency for the tom-tom is supposed to be two octaves below middle-C according to comments in the official adlib.c, however this doesn't seem to be the case.
Differences to MIDI
One thing to be aware of is that standard MIDI messages for polyphonic key pressure (event 0xA0) contain two data bytes (the key/note and the pressure for that note.) The Vinyl Goddess From Mars music files (and presumably other songs in this format) only suppy one data byte for an 0xA0 event, so this will confuse a standard MIDI player. These events must either be removed, changed to include an extra data byte (the pressure value is supplied, but the key/note is not) or alternatively they could be changed to event 0xD0 instead, which is a channel pressure message containing only one data byte. All these methods have been tested with the Vinyl music and there seems to be no audible difference between them, so the easiest method to implement is probably the best choice.
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|
|AdLib play.exe||DOS||Yes||No||No||No||No||No||No||Part of AdLib Programmer's Guide|
|AdLib convert.exe||DOS||No||No||No||No||Yes; .rol||No||No||Part of AdLib Programmer's Guide|
|Vinyl2CMF||Windows CLI||No||No||No||Yes; .cmf||No||No||No|
- AdLib Timbre Bank Format - companion format for storing instruments for songs in this format
- http://files.mpoli.fi/software/programm/general/adlip.zip - AdLib Programmer's Guide, including source code for playing and converting files in this format
This file format was originally reverse engineered by Malvineous as the Vinyl Goddess From Mars music format, until binarymaster discovered it was the same as an early AdLib music format, and supplied the documentation on which this article is now based. 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!)