AdLib MIDI Format
Format type | Music |
---|---|
Notation type | MIDI |
Instruments | OPL |
Max channel count | 9 or 11 |
Max track count | 1 |
Max pattern count | 1 |
Max order count | 0 |
Tags? | Title |
Games |
The AdLib MIDI Format is an Ad Lib music format, based on the standard MIDI format. It is derived from ROL Format and have compatible specification for playback. The format has a custom header, but the actual music data mostly 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.
File format
The file is arranged like this:
Data type | Name | Description |
---|---|---|
UINT8 | majorVersion | Major version number (usually 1) |
UINT8 | minorVersion | Minor version number (usually 0) |
INT32LE | tuneId | Song identification number |
char[30] | 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[8] | 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[8] | 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.
Timing
The MIDI delay bytes in the song data are in units of "ticks", as per normal. Timing bytes vary from 0 to 0xFE and precede every command. A timing byte of 0xF8 means timing overflow with a value of 240. An overflow byte is always followed by another overflow byte or timing byte.
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.
Also the song speed can be controlled during playback, see #Tempo multiplier event.
Rhythm mode
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 |
---|---|---|---|
0-5 | Melodic | Modulator Carrier |
Modulator Carrier |
6 | Bass drum | Modulator Carrier |
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
Polyphonic key pressure
According to MIDI specification, event 0xA# should have two byte parameters (the key/note and the pressure for that note), however this format provides only one byte parameter.
It is used to control channel volume. It frequently appears in the beginning of MIDI stream. Also it may be used for dynamic volume control of currently played note (for example: fade in, fade out, or tremolo effects).
Velocity parameter
This parameter goes with Note On and Note Off events. Since the format is inherited from ROL, it doesn't have note velocity specification.
It also changes current channel volume, same as event previously described.
If "Note On" event has velocity parameter equal to 0, it is treated as "Note Off" event, and channel volume is not changed.
Tempo multiplier
This event is structured like System Exclusive event, beginning with bytes 0xF0 0x7F and ending with 0xF7 byte.
By default, it does have fixed length of 6 bytes (including status bytes), and is used to change song speed during playback. It consists of an integer and a fractional part, in 1/128.
Byte | Description |
---|---|
0xF0 | SysEx Status Byte |
0x7F | Universal Realtime Command |
0x00 | Reserved |
XX | Integer part |
YY | Fractional part 1/128 |
0xF7 | End of SysEx |
So the actual frequency calculated like this:
multiplier = XX + YY / 128 frequency = (basicTempo / 60) * tickBeat * multiplier
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 |
---|---|---|---|---|---|---|---|---|---|
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 |
Camoto | Linux/Win | Yes | No | No | Yes; many | No | No | Yes | |
Vinyl2CMF | Windows CLI | No | No | No | Yes; .cmf | No | No | No |
See also
- 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
Credits
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!)