/*-------------------------------------------------------------------------------- * * * About MIDITONES * * * MIDITONES converts a MIDI music file into a much simplified stream of commands, * so that a version of the music can be played on a synthesizer having only * tone generators without any volume or tone controls. * * Volume ("velocity") and instrument specifications in the MIDI files are generally * discarded. All the tracks are prcoessed and merged into a single time-ordered * stream of "note on", "note off", and "delay" commands. * * This was written for the "Playtune" Arduino library, which plays polyphonic music * using up to 6 tone generators run by the timers on the processor. See the separate * documentation for Playtune. But MIDITONES may prove useful for other tone * generating systems. * * The output can be either a C-language source code fragment that initializes an * array with the command bytestream, or a binary file with the bytestream itself. * * MIDITONES is written in standard ANSI C (plus strlcpy and strlcat functions), and * is meant to be executed from the command line. There is no GUI interface. * * The MIDI file format is complicated, and this has not been tested on a very * wide variety of file types. In particular, we have tested only format type "1", * which seems to be what most of them are. Let me know if you find MIDI files * that it won't digest and I'll see if I can fix it. * This has been tested only on a little-endian PC, but I think it should work on * big-endian processors too. Note that the MIDI file format is inherently * big-endian. * * * ***** The command line ***** * * To convert a MIDI file called "chopin.mid" into a command bytestream, execute * * miditones chopin * * It will create a file in the same directory called "chopin.c" which contains * the C-language statement to intiialize an array called "score" with the bytestream. * * * The general form for command line execution is this: * * miditones [-p] [-lg] [-lp] [-s1] [-tn] [-b] [-cn] [-kn] [-v] * * The is the base name, without an extension, for the input and * output files. It can contain directory path information, or not. * * The input file is the base name with the extension ".mid". The output filename(s) * are the base name with ".c", ".bin", and/or ".log" extensions. * * * The following command-line options can be specified: * * -p Only parse the MIDI file; don't generate an output file. * Tracks are processed sequentially instead of being merged into chronological order. * This is mostly useful when generating a log to debug MIDI file parsing problems. * * -lp Log input file parsing information to the .log file * * -lg Log output bytestream generation information to the .log file * * -sn Use bytestream generation strategy "n". * Two strategies are currently implemented: * 1: favor track 1 notes instead of all tracks equally * 2: try to keep each track to its own tone generator * * -tn Generate the bytestream so that at most n tone generators are used. * The default is 6 tone generators, and the maximum is 16. * The program will report how many notes had to be discarded because there * weren't enough tone generators. Note that for the Arduino Playtunes * library, it's ok to have the bytestream use more tone genreators than * exist on your processor because any extra notes will be ignored, although * it does make the file bigger than necessary . Of course, too many ignored * notes will make the music sound really strange! * * -b Generate a binary file with the name .bin, instead of a * C-language source file with the name .c. * * -cn Only process the channel numbers whose bits are on in the number "n". * For example, -c3 means "only process channels 0 and 1" * * -kn Change the musical key of the output by n chromatic notes. * -k-12 goes one octave down, -k12 goes one octave up, etc. * * -v Add velocity information to output * * * ***** The score bytestream ***** * * The generated bytestream is a series of commands that turn notes on and off, and * start delays until the next note change. Here are the details, with numbers * shown in hexadecimal. * * If the high-order bit of the byte is 1, then it is one of the following commands: * * 9t nn [vv] Start playing note nn on tone generator t. Generators are numbered * starting with 0. The notes numbers are the MIDI numbers for the chromatic * scale, with decimal 60 being Middle C, and decimal 69 being Middle A (440 Hz). * If the -v option is enabled, a second byte is added to indicate velocity. * * 8t Stop playing the note on tone generator t. * * F0 End of score: stop playing. * * E0 End of score: start playing again from the beginning. * (Shown for completeness; MIDITONES won't generate this.) * * If the high-order bit of the byte is 0, it is a command to delay for a while until * the next note change.. The other 7 bits and the 8 bits of the following byte are * interpreted as a 15-bit big-endian integer that is the number of milliseconds to * wait before processing the next command. For example, * * 07 D0 * * would cause a delay of 0x07d0 = 2000 decimal millisconds, or 2 seconds. Any tones * that were playing before the delay command will continue to play. * * * Len Shustek, 4 Feb 2011 and later * *----------------------------------------------------------------------------------*/