To illustrate how best to use various Meta-Events when you save a MIDI file, let's consider an example sequencer track.

Assume that the user has created a sequencer track that he named "My track". He is using a Roland JV-1080 to play this track. His JV-1080 is connected to the third MIDI Out port on his computer's MIDI interface (which supports multiple MIDI Outs -- for more than 16 MIDI channels). The operating system lists this port with a name of "MIDI Out 3". He has picked out a patch on his JV-1080 called "Gonzo Harp". This is not a General MIDI patch. It happens to be in the third bank of patches, and is patch number 0. This track will play on the JV-1080's MIDI channel 1.

How would you write out an MTrk for this sequencer track?

First, you would start off with a Sequence/Track Name Meta-Event. The text for this event would be "My track". (Note that you do not need to nul-terminate text in a Meta-Event. The Meta-Event's variable quantity length tells how many characters are in the name). You would put this at a delta-time of zero. So let's examine our MTrk chunk so far, as if we were using a hex editor:

4D 54 72 6B     MTrk ID
00 00 00 0C     Length of the MTrk chunk so far.

                Our Track Name Meta-Event
00              Delta-time is 0.
FF              A Meta-Event.
03              Track Name type.
08              Length of "My track"
4D              ASCII 'M'
79              ASCII 'y'
20              ASCII ' '
74              ASCII 't'
72              ASCII 'r'
61              ASCII 'a'
63              ASCII 'c'
6B              ASCII 'k'
Next, you may choose to put an Instrument Name Meta-Event (although this isn't as important as other events, and you may skip it if your software neither knows, nor cares, what specific MIDI module is playing the track). The text for this event would be "Roland JV-1080".
                Our Instrument Name Meta-Event
00              Delta-time is 0.
FF              A Meta-Event.
04              Instrument Name type.
0E              Length of "Roland JV-1080"
52              ASCII 'R'
6F              ASCII 'o'
6C              ASCII 'l'
61              ASCII 'a'
6E              ASCII 'n'
64              ASCII 'd'
20              ASCII ' '
4A              ASCII 'J'
56              ASCII 'V'
2D              ASCII '-'
31              ASCII '1'
30              ASCII '0'
38              ASCII '8'
30              ASCII '0'
Next, you would put a Device (Port) Name Meta-Event. The text for this event would be "MIDI Out 3".
                Our Device (Port) Name Meta-Event
00              Delta-time is 0.
FF              A Meta-Event.
09              Device (Port) Name type.
0A              Length of "MIDI Out 3"
4D              ASCII 'M'
49              ASCII 'I'
44              ASCII 'D'
49              ASCII 'I'
20              ASCII ' '
4F              ASCII 'O'
75              ASCII 'u'
74              ASCII 't'
20              ASCII ' '
33              ASCII '3'
Next, you would put an Program (Patch) Name Meta-Event to indicate the name of the patch being used. The text for this event would be "Gonzo Harp".
                Our Program (Patch) Name Meta-Event
00              Delta-time is 0.
FF              A Meta-Event.
08              Program (Patch) Name type.
0A              Length of "Gonzo Harp"
47              ASCII 'G'
6F              ASCII 'o'
6E              ASCII 'n'
7A              ASCII 'z'
6F              ASCII 'o'
20              ASCII ' '
48              ASCII 'H'
61              ASCII 'a'
72              ASCII 'r'
70              ASCII 'p'
Next, you need to put the MIDI Bank Select Controller events and the MIDI Program Change event that select the desired patch ("Gonzo Harp") on the JV-1080. Let's assume that the Bank Select values will be 0 for MSB controller and 3 for LSB. We already said that the patch number is 0.
                Bank Select MSB
00              Delta-time is 0.
B0              Controller on channel 1.
00              Bank Select MSB.
00              MSB = 0
                Bank Select LSB
00              Delta-time is 0.
B0              Controller on channel 1.
20              Bank Select LSB.
03              LSB = 3
                Program Change
00              Delta-time is 0.
C0              Program Change on channel 1.
00              Patch = 0

After this, you would put other data for the track, such as MIDI Note-on, Note-off, etc, and other Meta-Events.


Now let's examine loading that same file created above.

First, you'll encounter the Track Name event. Use this to set the name for the sequencer track which will store this MTrk's data.

Next, you'll encounter the Instrument Name. If your program keeps a database of instruments that are "installed" on the computer, this could come in useful for several reasons. First, if your database lists which instruments are attached to which MIDI ports on the system, then you could ignore any Device (Port) Name event (just in case it happens to refer to someone else's MIDI port that isn't applicable on your system). You'll know which MIDI port to use for this MTrk based solely upon the Instrument Name and your own database. Secondly, if you have that instrument listed in your database, then you choose to forego any patch remapping. (ie, You may choose not to check that the values in any Bank Select and Program Change messages are correct, under the assumption that the desired patch is already located where it should be). At least, it may make any patch remapping easier.

Next, you'll encounter the Device (Port) Name event. If you weren't able to use the Instrument Name to deduce which MIDI port to use on your system, then you should check this port name. If it exists on your system, use that port. If not, use a default port.

Next, you'll encounter the Program Name event. You can use this to implement patch remapping. If your instrument database also lists what patches are available upon each instrument, then you can check for the existence of this patch in your database. (If you were able to use the Instrument Name, then you already know upon what instrument that patch should be found). Once you find that patch in your database, hopefully your database will contain the correct Bank Select and Program Change values needed to select that patch. In that case, you could ignore the next Bank Select and Program Change events you encounter in the MTrk. What you've effectively done is remap a patch change. So for example, if the MTrk was created upon an instrument with a unique arrangement of patches (and therefore its Bank Select and Program Change events have the wrong values when played upon a different instrument), you've remapped it to play the correct patch on another instrument.

Finally, you'll encounter the Bank Select and Program Change events. If you weren't able to use the Instrument and Program Name Meta-Events to deduce the correct Bank Select and Program Change values, then you may use these events verbatim.


A free Dynamic Link Library called "GenMidi" is available to programmers writing MIDI software. This DLL can be used to maintain a database of Instrument names, and the names of all patches on those instruments (including which Bank Select and Program Change values select each patch). Included with the DLL is a tool that allows a user to create a database of such.

By using this DLL in your program, you can more easily implement patch remapping, and better coordinate with other programs that also use this DLL. Plus, you don't have to develop your own tools to allow users to create such databases.

The DLL is downloadable from the Software Programs page.