by Larry Herzberg
Larry Herzberg is a freelance musician, writer and MIDI programmer who has been based in Los Angeles for the last ten years.
MIDIMON provides a detailed, easy-to-understand analysis of the MIDI data output from any synthesizer, drum machine, sequencer or similar controller. A necessity for MIDI programmers, a problem-solver for musicians, MIDIMON is also a fun and friendly program for anyone caring to unravel the mysteries of MIDI. Due to this program's large size, it's available only on this month's disk version or on the ST-Log SIG on Delphi.
A few words about MIDI
Have you ever wondered what was really coming out of the MIDI port of your synthesizer, drum machine or sequencer? Although in recent years there has been a great deal of progress in standardizing MIDI (which, in case you don't know by now, is an acronym for Musical Instrument Digital Interface), there are still wide gaps in the transmission and reception capabilities of various instruments. For instance, some synthesizers read "aftertouch" information—the changes in key pressure after a note has been triggered—while others don't. And some transmit variations in velocity data—just how quickly (or hard) a note has been hit—while others can't.
Sometimes such incompatibilities create performance problems for musicians who need to play several synthesizers with one physical keyboard. As a matter of fact, many synthesizers today have no keyboard of their own, and can only be played via MIDI, either from a "remote" keyboard or some other external controlling device (sequencer, MIDI guitar, MIDI drum pad or MIDI wind instrument; the list just keeps on growing). It can often be useful to determine which controls on the controlling device output MIDI data and which don't, and when they do, what controller numbers they have been assigned. Then, if the receiving synthesizers are flexible enough, they can be configured accordingly.
There are basically three types of MIDI information: Channel, System Common/Real Time and System Exclusive. Channel messages include note-on, note-off, control change, program change, pitch wheel, poly key pressure and channel pressure. Let's take a closer look at these kinds of messages and see how MIDIMON can be helpful in clearing up some of the more common problems associated with them.
Note-on and note-off messages both include velocity data, but many synthesizers don't transmit note-off messages at all. Instead, they turn a note off by transmitting a note-on message with zero velocity. This doesn't matter in most cases, but if you're trying to play a sound on a synthesizer sensitive to release velocity from a controller which doesn't transmit actual note-off commands (with their added capability of variable release velocities), you're not going to hear all the expressive possibilities programmed into the last part of the sound. MIDIMON can quickly alert you to this problem.
Control changes include events associated with levers, sliders, pedals and buttons. Sometimes controls will surprise you. I have an older Yamaha DX-7 which I use as my main keyboard. It would be handy if its volume pedal output some kind of controller information, but I've discovered with MIDIMON that it does not output MIDI data of any sort. On the other hand, the "YES" and "NO" buttons have been assigned MIDI controller numbers of their own (#96 and #97, both outputting a value of 127 when pressed). Although this might be useful when programming other Yamaha synths from the DX-7, it is of limited utility when dealing with different brands of synthesizers.
Patch changes often yield unexpected results as well. For instance, when I press patch button #1 on my DX-7, it outputs a patch #0 message through MIDI. In other words, it's "off by one" (as far as MIDI is concerned) throughout its entire patch range. Other synths, with multiple banks of sounds, sometimes assign non-consecutive patch numbers to adjacent banks. Fortunately, MIDIMON can help you map the patch layout of each of your synths so you can coordinate patch changes efficiently.
Illustration by Brent Watts
Pitch wheel data is different from other controller data in that its center (no-effect) position should have a decimal value of 8192. Going sharp increases this value, while going flat decreases it. Check your pitch wheel with MIDIMON to make sure it conforms to this MIDI standard. You can tell by looking at the last value the pitch wheel outputs as it returns to its home position.
Poly key pressure and channel pressure are two ways of transmitting aftertouch information. The difference is that poly key pressure transmits separate values for each note played, whereas channel pressure does not. MIDIMON will tell you which kind of aftertouch your synth outputs.
Finally, Channel Mode Select messages—Omni on and off, Poly and Mono—all concern the relationship between MIDI'S 16 channels and the synthesizer's voice assignments. When Omni is on, for instance, the synth can receive messages over any channel, rather than just its basic channel (which can usually be set by the user). The way in which Poly and Mono interact with Omni gets a little complicated, and depends in part upon whether the synth is transmitting or receiving; we'll leave such details to another article. What you should know, however, is that these messages, along with Local Control on and off, are handled as control changes by MIDI; that is, they do not have separate status bytes of their own (see below), but instead are identified by control numbers 122 thru 127. MIDIMON identifies all control changes by their assigned controller numbers and specifies the values they are outputting, but identifies these special Channel Mode Select messages by their "proper" names as well.
The second category of MIDI information, System Common/Real Time, differs from Channel in one important respect. Whereas Channel messages affect only those instruments set to a particular channel (or to all channels when Omni is on), a System Common / System Real Time message affects all instruments in the system capable of responding to it, regardless of their channel or mode setting. Song position pointer, song select and tune request are all System Common messages, while timing clock, start, continue, stop, active sensing and system reset are System Real Time. Timing clock is output by most drum machines and some sequencers to synchronize output. Active sensing is simply a byte (hex FE) which is output every 300 milliseconds by some synthesizers when nothing else is happening. Over the years, active sensing has been found to be of limited utility, and has now been dropped from many instruments. MIDIMON filters out active sensing bytes by default, but allows you to turn the filter off.
There are two other messages that can be properly thought of as System Common, but which really function only as "bookends" for the third category of MIDI information: System Exclusive. Although there is no standardization of System Exclusive data, it is always headed by an $F0 byte and tailed by an $F7 (End Of Exclusive) byte. In between can be any number of data bytes, but the first byte after $F0 should always contain the manufacturer's ID number. This ID number is what allows you to single out a particular instrument in a chain for System Exclusive operations ($F0 and $F7 being channel-independent messages). On a synthesizer, System Exclusive data usually includes the values the instrument assigns to its internal components in order to produce a given sound. This is how synthesizers of the same make (or model) can send and receive patches or whole banks of patches; not just the patch numbers, but the actual sounds themselves. On a drum machine, System Exclusive data generally includes the coding by which it remembers patterns or songs. MIDIMON accepts System Exclusive data, and properly identifies it as such, but to analyze all the data in detail it is necessary to consult your particular instrument's System Exclusive specifications.
MIDI data formats
In its simplest form, MIDI data is output in packets of one, two or three bytes. It's most easily readable in hexadecimal form, each byte consisting of two hex digits. Any byte with a value greater than or equal to $80 (128 in decimal) is called a "status" byte. Status bytes identify the type of operation which the instrument is being called on to perform. For example, when a synthesizer receives the value $90 through its MIDI-In port, it recognizes this value as a note-on command for all synths set to receive information on channel #1 (the second nibble of the status byte in a Channel message is always the channel number minus one; this convention limits MIDI to 16 channels). However, it does not yet know which note to turn on or how loudly to play it. The following two bytes—known as data bytes—give it this information in values ranging from $00 to $7F (0 to 127). The second byte of the packet is the note number, the third its velocity (loudness). Program change and channel pressure messages are transmitted in packets of only two bytes, while most System Common / Real Time messages need only one byte to get their points across. I'm not going to go into much detail on this subject; there's plenty of information available if you wish to delve further into the mechanics of MIDI, and you'll be able to learn almost everything you need to know just by observing how MIDIMON interprets MIDI output. The important thing to understand here is that the meaning of data bytes depends entirely upon the status byte which precedes them.
So far so simple, right? Well, not quite. Suppose you play a couple of notes into MIDIMON. When you look at the MIDIMON analysis screen, on the far left side where the raw data is listed you might see a series of 3-byte packets, but you might also see one 3-byte packet followed by a bunch of 2-byte packets. Don't let that throw you; it only means that your synthesizer outputs MIDI data in the "running status" format. This means that once a status byte is output, it need not be output again as long as the same kind of MIDI event follows. This is a faster, more efficient way of transmitting MIDI data, and seems to be gaining in popularity. Some instruments use a combination of standard / running status formats. In any case, all instruments should be able to correctly interpret both.
Make sure your computer's MIDI-In is connected to the synthesizer's MIDI-Out, and vice-versa. Turn the synthesizer on first, then run MIDIMON off the desktop like you would any other program. After the title is displayed you'll be asked whether you want to filter out active sensing bytes or not. Unless you have some reason for wanting to see them, I recommend that you do filter them out. Now you're in capture mode; as soon as you play a note or fiddle with any MIDI-transmitting controller, it will show up on the capture screen. Although the capture screen clears after you fill it up each time, don't worry about losing the data; it's all being stored in a buffer as large as the free memory in your computer.
All the functions available from capture mode are listed on the menu line at the bottom of the screen. When you want to enter analysis mode, simply hit "A." An analysis will then be printed to the screen, and the menu line will show you which keys to press in order to page back and forth through the analyzed data, return to capture mode or quit. The analysis includes the raw data in hexadecimal form, packet by packet, a description of each status byte, channel number if appropriate, and whatever details are relevant. If you return to capture mode, the buffer will remain intact unless you formally clear it with the "C"lear Capture command.
Do you want to print the analysis to a printer or disk file? Just strike "P," and you will be prompted as to which device to print to. Printouts to the printer can be aborted by striking "A" at any time.
In order to send a string of bytes to the synthesizer, press "S." You can then enter a series of up to 32 bytes (64 hex nibbles) in hexadecimal form. Any characters other than hex digits (except spaces) will not be accepted, and since it takes two hex digits to make a byte, odd numbers of hex digits will not be transmitted. Spaces are not transmitted, but are counted as characters in the send buffer.
Here's an example. To turn on middle "C" (note #60, decimal) with a velocity value of 64 (decimal), you would enter:
90 3C 40
To turn it off, you could use the note-on, zero-velocity method by sending:
90 3C 00
Alternately, you could send a formal note-off (a status byte of $80 on Channel 1) and experiment with a release velocity of, say, 32 (decimal):
80 3C 20
Or if you wanted to see how your synth reacts to "running status," you might try turning off the note with no immediate status byte at all:
It's probably a good idea to first learn how your synthesizer handles MIDI by analyzing some of its output. Then you'll know the best way to communicate with it. In regards to sending your synthesizer System Exclusive commands, remember that you must preface all such messages with an $F0 byte followed by the manufacturer's System Exclusive ID number. If you initiate a patch dump from the synthesizer itself, MIDIMON will analyze this ID number for you. The model ID number is also necessary sometimes, as is an $F7 at the end of the command.
A note about MIDIMON's Echo feature You can toggle this function on and off by pressing "E" in capture mode. When you press it the screen will clear, and the letter next to "E"cho on the menu line will switch from "N" to "Y" or back again. "N" means no echo; "Y" means, yes, the echo feature is on. While it is on, everything entering the computer's MIDI-In port is immediately echoed to its MIDI-Out port. This acts like a simple Thru box, and can be quite handy for checking synthesizer compatibilities while monitoring input. Remember, however, that if the synth you are playing is also receiving data from the computer's MIDI-Out port (along with the synth you intend to echo to), notes on the transmitting synth will be triggered twice, once from the keyboard and again from the computer. This can create strange, "out of phase" sounding effects. There is an easy way to remedy this problem, however. Reconfigure the keyboard to receive on a different channel than it's transmitting on.