This is a not very successful C program to compare MIDI files. I wrote it about 2007 and used it with great difficulty to compare some pairs of MIDI editions of some of Bach’s works. I record now (2010) some of the difficulties I encountered. This might guide efforts to extend the functions of MIDI comparators.

Some perhaps unreasonable limitations on the current code:

Some of these problems are easily overcome with even a crude graphic user interface. That would be a much bigger project however.

Meanwhile here is a crude synopsis of the program logic. There is considerable reliance on the logic described here; in particular the routine Read is used. For each MIDI file a structure of type piece is constructed. Within is a pointer to an array with an entry for each ‘time slot’. A time slot is a period of time of duration 2−(n+2) whole notes, where n is the first argument on the command line. An entry in the array becomes the head of a linked list of notes that begin in that time slot. An element of such a list is of type cn and holds a note value and duration. Most of the lists are empty.

The routine rex is called to report the first few chords of each piece. For each chord the first value is the number of whole notes from the beginning, followed by the MIDI note values of the chord. This has avoided many confusions. The scores for Bach’s works that I use, number the bars and in the common case of 4/4 time the bar number is one greater than the number of whole notes.

Then for each time slot with at least one non-empty list of notes two histograms are built, ka, kb for the two files, for that time slot. The subscript of the histogram is the note value. A report is made when the histograms disagree:

qn=  time nv = freq; nc:nc
time is the fractional whole note number at the discrepancy, freq is the MIDI note value, and the ncs are the respective histogram counts.
If you have a Mac, or run some variety of Unix, then the following steps should work. On the Mac Apple’s free development system Xcode is required. I understand that there is a system called ‘cygwin’ that is enough Unix like to do such things on Windows.

To compile and run the code put files r.c, mdif.c, and h.h in some new directory and in a command shell do:

gcc mdif.c r.c -fnested-functions -o mdif
(I suspect that the “ -fnested-functions” may be and must be omitted on some platforms.) This places an executable file mdif in the new directory that can be run thus:
./mdif 3 X.mid Y.mid
to compare two MIDI files.