cinmidi is a command-line program that displays MIDI messages as text on the computer screen as they enter in real-time from an external MIDI controller. The binary MIDI input bytes are converted to their ASCII numeric equivalents when displaying on the screen (selectable as base-2, base-10 or base-16 numbers). Cinmidi stands for "Console INput MIDI".
Here is a list of cinmidi command-line options:
|-a||display MIDI timing in absolute time instead of delta time|
|-i||don't display interpretation of MIDI message as comments|
|-d||display MIDI bytes in decimal form|
|-x||display MIDI bytes in hexadecimal form|
|-2||display MIDI bytes in binary form|
|-n||do not display note-off messages|
|-f string||filter out specified MIDI commands. For example "bc" will filter out control change ("b" command nibble) and patch change messages ("c" command nibble).|
|-c string||filter out specified MIDI channels, offset zero (e.g., "09AF", filters channels 1, 10, 11, and 16)|
|-p port||use the specified MIDI input port|
|-l||list MIDI input ports and then exit|
|-o filename||send display to file as well as to screen|
|-u string||specify a user name for the header information|
|-s||display time values in seconds|
|-k||disable keyboard input|
|--options||list all options, default values, and aliases|
Here are some example function calls to the cinmidi program:
cinmidi -f 89abcdf
cinmidi -n -f 8abcdef
Each text-line output by cinmidi displays a single MIDI message that contains three primary components. The first number on a line is the timestamp of the message. This is followed by one or more MIDI message byte and optionally followed by a comment starting with ';', which describes the meaning of the message.
The timestamp was added by the cinmidi program and was not transmitted via MIDI, but rather provided by the operating system when the MIDI message arrived. Each MIDI byte takes about 300 microseconds to transmit, and typical MIDI messages are three bytes long. That means each MIDI message takes about 1 millisecond (or 0.001 seconds) to enter the computer. Therefore, the timestamp has a resolution of one millisecond. Higher resolution would not be of much use. Also, keep in mind that humans cannot hear the order of two events which are separated by less than 10 milliseconds (in the best case), so the timestamp is more than 10 times as accurate as it needs to be for sufficient playback of the data. The default timestamp style is delta milliseconds. The default can be modified with these two options:
|cinmidi||Default behavior: display timestamps as delta times—the time (in milliseconds) since the previous message came in. Example output with delta times at the start of each line:|
|cinmidi -a||Display timestamps in absolute time rather than delta time (all time values refer to the starting time of the recording). Here is example output from cinmidi when using the -a option. The first message was played 922 milliseconds after the program started.|
|cinmidi -s||Display timestamps in seconds rather than milliseconds. The following example output from cinmidi displays the delta time stamps in seconds:|
|cinmidi -as||The -a and -s options can also be used at the same time to display absolute time stamps in seconds:
MIDI command byte
MIDI command bytes are the second number on the line after the timestamp. A MIDI command is a number in the range from 128 to 255. In hexadecimal notation the MIDI commands can be easily grouped by the most significant nibble in the command byte. Below is a table giving the primary MIDI commands (not expanding command in the 0xF0 group). The notation "0x80" is the C-programing language's notation for hexadecimal numbers. 0x80 is the hexadecimal number "80" which is equivalent to the decimal number 128. MIDI commands are grouped into sets of 16, so the most significant hex digit (nibble) is equated to a MIDI command.
|0x80-0x8F||Note-off||2 (key, off velocity)|
|0x90-0x9F||Note-on||2 (key, on velocity)|
|0xA0-0xAF||Aftertouch||2 (key, key pressure)|
|0xB0-0xBF||Continuous Controller||2 (controller #, value)|
|0xC0-0xCF||Patch Change||1 (timbre #)|
|0xD0-0xDF||Channel Pressure||1 (pressure)|
|0xE0-0xEF||Pitch Wheel||2 (lsb, msb)|
In hexadecimal notation, it is easy to see that the first character of the MIDI command byte is the command category as displayed in the table above. The channel that is affected by that command, is given in the second hexadecimal digit (always 0 in the table above). The first channel is 0 (channel 1), and the last channel is F (channel 16).
Again, "0x" is a C-programming convention for indicating a hexadecimal number. You can also signify a hexadecimal number with by an "h" following the number or a subscript 16 following the number. All of these number representations are equivalent to the decimal number 144: 0x90 = 90h = 9016. I like to see MIDI commands in hex form, and MIDI data in decimal form, so this is the default style for cinmidi. You don't have to know the hex-dec equivalences, just keep in mind that hex digits are useful for interpreting what a MIDI command byte is supposed to mean -- there is no calculation involved when displayed as a hex number, but decimal-notated MIDI command bytes are much more difficult to interpret in your head.
By default, the cinmidi program will display the MIDI command byte in C-style hex notation. You can change the display type to either binary or decimal as well. 'cinmidi -2' displays MIDI bytes as binary numbers, and 'cinmidi -d' displays MIDI bytes as decimal numbers.
MIDI data byte(s)
MIDI data bytes are in the range from 0 to 127. They are always associated with a MIDI command byte. The meaning of a MIDI data byte is determined by is position after a particular MIDI command byte. For example, a note-on command byte (a number in the range 0x90-0x9F) is followed always followed by exactly two MIDI data bytes. The first byte tells you which key is being turned on, and the second byte tells you how hard the key was pressed on the keyboard controller (the attack velocity). Most MIDI messages with a command byte less than 0xF0 have two data byte parameters following them--except for 0xc0 (Patch Change) and 0xd0 (Channel Pressure) messages. The table below lists the number of data parameter bytes expected for each category of MIDI message:
|Command nibble (hex)||Meaning||Parameter count: meaning|
|8||Note-off||2: key, velocity|
|9||Note-on||2: key, velocity|
|A||Aftertouch||2: key, value|
|B||Continuous Controller||2: controller #, value|
|C||Patch Change||1: instrument #|
|D||Channel Pressure||1: value|
|E||Pitch Wheel||2: LSB MSB|
|F||System Messages||variable, depends on least significant nibble.|
There is something called running status where data bytes are continuously sent without associated command byte. If this is the case the the last command byte that came in the MIDI stream is used as the command byte of the orphaned data parameters. The cinmidi program inserts the MIDI command bytes into their appropriate places when displaying MIDI messages to the screen, so you can't see running status MIDI messages with cinmidi.
Filtering out unwanted MIDI commands
By default, the cinmidi will filter out two types of system message: 0xf8 (timing clocking messages) and 0xfe (active sensing messages). Those two messages, if they are present, occur too fast for a human to read on the screen. If you want to filter out other command, such as all note-off commands, or filter out certain channels, the -f and -c options are useful.
To filter out generic categories of MIDI messages use the -f command which takes as an argument a string that contains a list of the types of MIDI messages to ignore. There are 8 categories of MIDI messages, each of which is represented by a single character in the -f option string:
|-f character||Command type||Meaning|
|'A', or 'a'||0xA0||Aftertouch|
|'B', or 'b'||0xB0||Continuous Controller|
|'C', or 'c'||0xC0||Patch Change|
|'D', or 'd'||0xD0||Channel Pressure|
|'E', or 'e'||0xE0||Pitch Wheel|
|'F', or 'f'||0xF0||System Messages|
So, for example, the program call 'cinmidi -f ab' would prevent the display of aftertouch or continuous controller messages. Note that 'cinmidi -fab' and 'cinmidi -f "ab"' are equivalent command-line syntaxes to the first example.
The -c command is used to filter out all MIDI messages related to a particular channel. The option takes as an argument a string which contains a list of the channels to ignore. Just to confuse you, there is exactly one character for each MIDI channel, and the numbering system starts at 0 rather than 1. Here are the channels and the string characters used in the -c option:
|-c character||MIDI channel||-c character||MIDI channel|
|'0'||MIDI channel 1||'8'||MIDI channel 9|
|'1'||MIDI channel 2||'9'||MIDI channel 10|
|'2'||MIDI channel 3||'A', or 'a'||MIDI channel 11|
|'3'||MIDI channel 4||'B', or 'b'||MIDI channel 12|
|'4'||MIDI channel 5||'C', or 'c'||MIDI channel 13|
|'5'||MIDI channel 6||'D', or 'd'||MIDI channel 14|
|'6'||MIDI channel 7||'E', or 'e'||MIDI channel 15|
|'7'||MIDI channel 8||'F', or 'f'||MIDI channel 16|
So, for example, the program call 'cinmidi -c 9F' would prevent the display of messages from MIDI channels 10 and 16. Note that cinmidi -c9F and cinmidi -c "9F" are equivalent comamnd-line syntaxes to the previous example.
Note-offs are a special consideration, because the proper method to transmit them is rarely followed by using the 0x80 set of commands. Instead 0x90 commands are often used with an attack velocity of 0 used to signify a note off. Therefore there is a separate option used to filter out all types of note-off commands: 'cinmidi -n'.
By default, every MIDI message will be accompanied with a comment on the right side of the screen that explains the current message in terms of standard General MIDI syntax. This option can be turned off by specifing the 'cinmidi -i' option.
Miscellaneous command-line options
'cinmidi -p 1' would specify that MIDI input port number one be used instead of the default 0. Use the -l option to determine how many ports are available.
'cinmidi -l' lists the ports that can be used for MIDI input. Each input port has an associated number (starting at 0) and a port name.
'cinmidi -o filename' enables you to copy the screen display to a file, you could also type 'cinmidi > filename ' which would save the output to a file, but then you couldn't see the input data on the screen.
'cinmidi -k' by default you can type text into the screen or file display as the cinmidi program is running. This option is useful to write extra comments into the file. Also, you can press the escape key to quit the program as well as control-c. With the -k option activated, the keyboard input is deactivated.
'cinmidi -u string' is useful to indicate who has recorded the MIDI data, for example, I might do: 'cinmidi -u "Craig Sapp" '
Output file format
The output file format can be played with the playascii found in the download section below. The cinmidi program generates data which can be played back by this program. Here are the specifications for the ASCII representation of MIDI data:
- Comments are started by a ';' character and last until the end of the line.
- The header starts at the first non-blank line and continues for each line which has a ';' in the first column (no leading spaces are allowed).
- a timestamp starts a line for a MIDI message. the timestamp can be delta or absolute according to the file header. The time can be either milliseconds or seconds according to the header.
- The MIDI command can be displayed with a "0x" by default or in binary, decimal or hexadecimal notation according to the header.
- The MIDI data bytes are display as decimal values by default, or also as binary or hexadecimal values.
- future additions may be as follows: MIDI-file information can be interleaved with the actual MIDI bytes. MIDI-file bytes are preceded by a ':' character which is in effect until the end of a line. MIDI header bytes would start a line with a ':' character (initial spaces allowed), while track information would start with a non-coloned absolute time/delta time associated with the given meta event.
- The preferred file extension will be '.ami' which stands for "ASCII MIDI".
Here is example asciimidi file output from cinmidi.
The output file created with the -o option can be played back if the -2 option was not used. To playback the file, save the file to the hard-coded filename "file" and run the playascii program (executable given below).
Computer geek method of compiling binasc/playascii for Linux and OS X:
- git clone https://github.com/craigsapp/improv
- cd improv