Cinmidi

From CCARH Wiki
Jump to navigation Jump to search

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

Options

Here is a list of cinmidi command-line options:

Option Meaning
-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:

  • Display MIDI input data in binary form:
cinmidi -2
  • Don't display note-off messages:
cinmidi -n
  • Don't display pitchbend data:
cinmidi -fe
  • Display only pitchbend data:
cinmidi -f 89abcdf
  • Display only note-on messages:
cinmidi -n -f 8abcdef

Timing information

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:

Command Meaning
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:
;;
;; Style:          default
;; Timing:         delta milliseconds
;; Message format: delta-time, MIDI command-byte, MIDI parameter-byte(s)
;; Format:         asciimidi 1.0
;; Command-line:   C:\Users\ccarh\Downloads\cinmidi.exe
;; Input Port:     0: Q49
;;

0       0x90  48  89            ; NOTE chan:1 key:C3 vel:89
125     0x80  48  64            ; NOTEOFF chan: 1 key:C3 vel: 64
47      0x90  50 100            ; NOTE chan:1 key:D3 vel:100
93      0x80  50  64            ; NOTEOFF chan: 1 key:D3 vel: 64
47      0x90  52 100            ; NOTE chan:1 key:E3 vel:100
110     0x80  52  64            ; NOTEOFF chan: 1 key:E3 vel: 64
62      0x90  53 102            ; NOTE chan:1 key:F3 vel:102
94      0x80  53  64            ; NOTEOFF chan: 1 key:F3 vel: 64
109     0x90  55 110            ; NOTE chan:1 key:G3 vel:110
172     0x80  55  64            ; NOTEOFF chan: 1 key:G3 vel: 64
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.
;;
;; Style:          default
;; Timing:         absolute milliseconds
;; Message format: received-time, command-byte, parameter-byte(s)
;; Format:         asciimidi 1.0
;; Command-line:   C:\Users\ccarh\Downloads\cinmidi.exe -a
;; Input Port:     0: Q49
;;

922     0x90  48  97            ; NOTE chan:1 key:C3 vel:97
1047    0x80  48  64            ; NOTEOFF chan: 1 key:C3 vel: 64
1125    0x90  50 107            ; NOTE chan:1 key:D3 vel:107
1219    0x80  50  64            ; NOTEOFF chan: 1 key:D3 vel: 64
1297    0x90  52 106            ; NOTE chan:1 key:E3 vel:106
1375    0x80  52  64            ; NOTEOFF chan: 1 key:E3 vel: 64
1469    0x90  53 104            ; NOTE chan:1 key:F3 vel:104
1547    0x80  53  64            ; NOTEOFF chan: 1 key:F3 vel: 64
1703    0x90  55 110            ; NOTE chan:1 key:G3 vel:110
1844    0x80  55  64            ; NOTEOFF chan: 1 key:G3 vel: 64
cinmidi -s Display timestamps in seconds rather than milliseconds. The following example output from cinmidi displays the delta time stamps in seconds:
;;
;; Style:          default
;; Timing:         delta seconds
;; Message format: delta-time, MIDI command-byte, MIDI parameter-byte(s)
;; Format:         asciimidi 1.0
;; Command-line:   C:\Users\ccarh\Downloads\cinmidi.exe -s
;; Input Port:     0: Q49
;;

0       0x90  48  92            ; NOTE chan:1 key:C3 vel:92
0.157   0x80  48  64            ; NOTEOFF chan: 1 key:C3 vel: 64
0.203   0x90  50 102            ; NOTE chan:1 key:D3 vel:102
0.109   0x80  50  64            ; NOTEOFF chan: 1 key:D3 vel: 64
0.203   0x90  52 100            ; NOTE chan:1 key:E3 vel:100
0.094   0x80  52  64            ; NOTEOFF chan: 1 key:E3 vel: 64
0.25    0x90  53 104            ; NOTE chan:1 key:F3 vel:104
0.109   0x80  53  64            ; NOTEOFF chan: 1 key:F3 vel: 64
0.282   0x90  55 108            ; NOTE chan:1 key:G3 vel:108
0.109   0x80  55  64            ; NOTEOFF chan: 1 key:G3 vel: 64
cinmidi -as The -a and -s options can also be used at the same time to display absolute time stamps in seconds:
;;
;; Style:          default
;; Timing:         absolute seconds
;; Message format: received-time, command-byte, parameter-byte(s)
;; Format:         asciimidi 1.0
;; Command-line:   C:\Users\ccarh\Downloads\cinmidi.exe -as
;; Input Port:     0: Q49
;;

0.906   0x90  48  99            ; NOTE chan:1 key:C3 vel:99
1.047   0x80  48  64            ; NOTEOFF chan: 1 key:C3 vel: 64
1.156   0x90  50 108            ; NOTE chan:1 key:D3 vel:108
1.234   0x80  50  64            ; NOTEOFF chan: 1 key:D3 vel: 64
1.39    0x90  52 104            ; NOTE chan:1 key:E3 vel:104
1.469   0x80  52  64            ; NOTEOFF chan: 1 key:E3 vel: 64
1.609   0x90  53 104            ; NOTE chan:1 key:F3 vel:104
1.703   0x80  53  64            ; NOTEOFF chan: 1 key:F3 vel: 64
1.875   0x90  55 108            ; NOTE chan:1 key:G3 vel:108
2.031   0x80  55  64            ; NOTEOFF chan: 1 key:G3 vel: 64

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.

Command byte Meaning Parameters
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)
0xF0-0xFF System Messages variable

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
'8' 0x80 Note-off
'9' 0x90 Note-on
'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'.

Interpretation comments

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

Download

Executable Source Code
Windows cinmidi.exe cinmidi.cpp
playascii.exe playascii.cpp
OS X cinmidi.osx cinmidi.cpp
playascii.osx playascii.cpp

Computer geek method of compiling binasc/playascii for Linux and OS X:

  1. git clone https://github.com/craigsapp/improv
  2. cd improv
  3. make
  4. bin/cinmidi