AdLib MIDI Format

From ModdingWiki
(Redirected from VGFM Music Format)
Jump to: navigation, search
AdLib MIDI Format
Format typeMusic
Notation typeMIDI
InstrumentsOPL
Max channel count9 or 11
Max track count1
Max pattern count1
Max order count0
Tags?Title
GamesVinyl Goddess From Mars

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.

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. 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.

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

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.

Tools

The following tools are able to work with files in this format.

Name PlatformPlay? Create new? Modify? Convert/export to other? Import from other? Access hidden data? Edit metadata? Notes
AdLib play.exe DOSYesNoNoNoNoNoNo Part of AdLib Programmer's Guide
AdLib convert.exe DOSNoNoNoNoYes; .rolNoNo Part of AdLib Programmer's Guide
Camoto Linux/WinYesNoNoYes; manyNoNoYes
Vinyl2CMF Windows CLINoNoNoYes; .cmfNoNoNo

See also

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!)