midi <-> ascii conversion - instructions


"crotchet" (UK English) = "quarter note" (US English). And "bar" = "measure".

ascii file format

Perhaps the easiest way to understand this is to look at examples generated by using mid2asc on midi files.

Each non-blank line is either a comment (starts with '#'), or an event.

The first item on an event line is the time the event occurs and can be determined in one of five ways:
(i) BA+CR Bar number+Crotchet within bar
(ii) CR Crotchet number from the very start
(iii) DT Delta time from previous event - native midi format
(iv) FOL[+/-crotchets] Time from end of previous note/rest on same track
(v) SIM[+crotchets] Time from start of previous note/rest on same track

In case (iii), the time is in units of 'ticks', in the other four cases the time is in units of crotchets using fractional notation, e.g., 3+5/6. The denominator must divide the overall division set at the start of the file (e.g., 384). Further time descriptions can occur in brackets after the first one and are ignored by asc2mid. They are just output by mid2asc to help to see where you are, and it is OK to edit the first time description even if this becomes inconsistent with subsequent the bracketed ones.

On the line there must be a track number between 0 and 15 specified by "TR <number>", and a channel number between 1 and 16 specified by "CH <number>". All numbers are either decimal or hexadecimal when preceeded by "&" or "0x".

After that you can either write (i) a generic midi event, (ii) a generic meta event, (iii) a generic sysex event, or (iv) an event which has been given a name. Most common events have a name: NT (play a note), Time signature, Channel volume, Instrument, End of track, Tempo, Key, Text. For example,


ST &A0 &3C &64


Meta Event   type &7F   0 0 119 14 0
(don't put in length, asc2mid counts the data bytes.)


Sysex Event   &F7   0 1 2 3
(don't put in length, asc2mid counts the data bytes.)


Channel volume 100

Time signature 4/4, clocks/mtick 96, crotchets/32ndnote 8

NT  C''          3+1/2 von=80
Turn on C two octaves above middle C, lasting 3+1/2 crotchets, with velocity 80 (asc2mid will insert the corresponding note-off event at the right time).

NT  Bb--         on
Turn on Bb one-and-a-bit octaves below middle C with velocity given by most recent von on same track.

NT  R            3
Insert a rest of 3 crotchets on this track (this doesn't actually write any midi events. Its only effect is on the next FOL or SIM).

The instrument numbers go from 1 to 128. It is up to the user to put in an "End track" at the end of every track.



mid2asc [-c] [-f,-r] [-s] midifile > textfile

The -c, -f and -r flags affect how the timing of the event lines is specified.

The default (none of -c, -f or -r) outputs BA+CR type timings (item (i) in above ascii file format description). There is a slight complication in this case, because the time signature affects the meaning of bar number, and the time signature can change at any time on any track, and should affect all tracks. This shouldn't cause any trouble, but to guide the eye when the time signature changes on some track, mid2asc outputs a comment line on every track. By the way, bar numbers start from 1 in keeping with usual conventions, but all other timing stuff starts from 0.

-c mode outputs pure CR timings (crotchet number from very start - item (ii) in above ascii file format description).

-r mode outputs DT (delta time) timings (ticks from previous event - item (iii) in above ascii file format description).

-f mode outputs FOL, SIM or SIM+number timings (relative to end or start of previous note - items (iv), (v) in above ascii file format description).

-s causes tracks to be output separately.



asc2mid textfile > midifile

Makes a midi file when given an ascii file in the format described above. It requires all lines corresponding to a given track to be in chronological order. (It's possible to drop this restriction, if all events are specified by the CR method, by presorting the lines.) Lines from different tracks can be separated or interleaved in any way.

Other stuff

The midi file format has slight redundancies so the representation is ambiguous. For example events occuring at the same time can sometimes be swapped; using running st mode is a matter of choice; using 0x8* or 0x9* for voff when velocity=0x40 is a matter of choice; there is allowed to be any junk after the end of the tracks. This means that applying mid2asc then asc2mid won't necessarily get you back to where you started. However, the choices asc2mid and mid2asc make are meant to be 'stable', so applying asc2mid, mid2asc then asc2mid should be the same as applying asc2mid. Also mid2asc asc2mid mid2asc should be the same as mid2asc.

Back up a level