I started writing some code to read MIDI files out of frustration at having three programs on my machine that claim to edit MIDI files and yet being unable to do what I want.
Having now written some MIDI code I have more sympathy with writers of MIDI editors.
I have as yet no clear idea what I want the program to be when it grows up.
The original impetus was to modify the voice (= timbre, = “program”) of various tracks.
Perhaps the program will become merely a framework on which to add simple function as the need arises.
In that case I must document it a bit.
Here, is the code and some documentation that resulted from the plans that began below.
I keep the stuff below as a source of new ideas.
Building a MIDI editor has the same problems as an html editor:
There is a tension between doing everything the editor’s way and leaving alone what is unedited.
I see no principled compromise.
This is perhaps the origin of my troubles with other editors.
There are at least the following useful concepts of locating an element in a MIDI file:
I suppose that I will select a subset of these formats as a typical Unix utility would.
- Where in the file: given as a hex offset from beginning, as 0x1a6
- Time in ticks, as 399t
- Bars plus quarter notes, as 21b2
- Wall clock time, considering provided or default tempo.
Here is a scheme that seems attractive.
Transform the pieces into a new clean format.
The transformation would strip gremlins from the current source and put it in a more convenient form.
Then write a cgi program that would emit standard MIDI parameterized by requester.
It is not yet clear to me whether to separate the tracks as does MIDI.
I will assume that first.
A possible format for a voice:
1 byte note number (frequency code); 1 byte duration; 1 optional (per track) intensity (velocity in MIDI talk).
This ignores polyphony.
There is a great deal of music I want to do where within one voice (track) one note almost always starts just as the previous finishes.
Polyphony is vital however.
code => Frere Jacques
This variation makes this MIDI file and I think illustrates a bug in Apple’s QuickTime interpretation.
The issue is whether voice selection for a channel in one track should interfere with the same channel number of another track.
I think it should not.
I have just come across Lilypond which is an ascii notation which may be compiled to nicely printed sheet music.
It concentrates on what is necessary for the printed image.
Nonetheless it is able to produce serviceable MIDI output.
Its form permits omission of information to be supplied by defaults upon compilation.
I am unhappy with pot luck formats.
I can see the reasons however.
This code reads and parses a MIDI file.
It emits a few comments but discards most of the information.
It is a framework.
Here is a general plan that might be useful.
I thought of putting the MIDI information into a relational data base so as to make SQL available to edit the music.
I gave this up when it seemed to require me to become a sysadmin in order to install any data base system that supported SQL.
Later it occurred to me to invent an immutable note object and write the following routines:
A bag is like a set but allows duplicates.
Perhaps we should exclude duplicates—they are expressible in MIDI but bollix some performers and make others sound bad.
We should at least warn of duplicates, even two notes that are alike in voice, time and voice.
The note structure includes
- convert a MIDI file to a bag of notes.
- convert a bag of notes to a MIDI file.
- call a user supplied routine for each note in a bag providing as a parameter, a routine
to accept notes to be placed in a new bag.
Other things besides notes that come at particular times are
- a start time in quarter notes or some such ideal time rather than real time,
- a note value (frequency),
- a note duration,
- a velocity (amplitude)
- a voice (or part as in many part music)
Atemporal things include
- rhythm changes which change the real time occupied by a quarter note.
- Mystery data which the system attempts to preserve in the output.
- an element mapping voice values to selections of commonly available voices
- An initial file format indicator.
The plan is to enable programmers to do flexible things with MIDI files, either
I concentrate initially on file to file which would include file to CGI output.
I think I will use C as the least common denominator.
Java and C++ each have substantially more entry cost.
If OO becomes a real advantage I will rethink.
- file to file
- file to perform
- perform to file
Standard MIDI Files;
David’s MIDI Spec;
Voices = Patches = Program; Unexplored Java stuff
Current Code Fragments
This code, b.c merely verifies grossest features of a MIDI file.
It counts the tracks.
peek.c goes much further and provides a running commentary on what it finds.
It checks some easily checked format problems.
By and large it is necessary to read the code to find out what it is complaining about.
Here is a Forth program to report on MIDI file contents.
m.c is a simple program to produce a MIDI file for