parent
b6070573e9
commit
93b539361e
@ -1,143 +1,143 @@ |
||||
/*-------------------------------------------------------------------------------- |
||||
* |
||||
* |
||||
* 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 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] <basefilename> |
||||
* |
||||
* The <basefilename> 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 <basefilename>.log file |
||||
* |
||||
* -lg Log output bytestream generation information to the <basefilename>.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 <basefilename>.bin, instead of a |
||||
* C-language source file with the name <basefilename>.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. |
||||
* |
||||
* |
||||
* ***** 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 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). |
||||
* |
||||
* 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 |
||||
* |
||||
*----------------------------------------------------------------------------------*/ |
||||
|
||||
Update on 28 Feb 2011: I fixed a bug that caused it to stop some notes too soon. |
||||
|
||||
I also wrote a "MIDITONES_SCROLL" program that displays a miditones bytestream as a time-ordered scroll, sort of like a piano roll but with non-uniform time.This is primarily useful to debug programming errors that cause some MIDI scripts to sound strange. It reads the .bin file created from a .mid file by MIDITONES using the -b option. |
||||
|
||||
Update on 25 Apr 2011: Scott Stickeler pointed out that it doesn't work if compiled for a 64-bit environment. I'll put fixing that on my to-do list, but in the meantime the workaround is just to compile for 32 bits. (Thanks, Scott.) |
||||
|
||||
Update on 20 Nov 2011, V1.4: Added options to mask which channels (tracks) to process, and to change key by any chromatic distance. These are in support of music-playing on my Tesla Coil. |
||||
|
||||
Update on 25 Aug 2013, V1.6: I finally fixed it to compile in 64-bit environments. I didn't have a way to test that, so thanks to David Azar for doing so. |
||||
|
||||
Update on 30 Dec 2013: I added version 1.1 of MINITONES_SCROLL with a "-c" option to create annotated C source code initialization of the music bytestream. This makes it easier to manually edit the bytestream. See the beginning of the MINITONES_SCROLL source code for more details. |
||||
|
||||
Update on 7 Mar 2013: I compiled 32-bit versions for people running Windows XP and Vista. Unfortunately code.google.com no longer allows downloaded files! So I put them in a Google Drive folder here: |
||||
https://drive.google.com/folderview?id=0B1ZOnb_w5lfBQkNPeFpvRHdQNnc |
||||
|
||||
Update on 5 April 2015: Now code.google.org is going away, so I've migrated this to github. |
||||
|
||||
Update on 6 April 2015: I made the source code friendlier to more compilers. The executables are, of course, for Windows. |
||||
|
||||
/*-------------------------------------------------------------------------------- |
||||
* |
||||
* |
||||
* 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 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] <basefilename> |
||||
* |
||||
* The <basefilename> 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 <basefilename>.log file |
||||
* |
||||
* -lg Log output bytestream generation information to the <basefilename>.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 <basefilename>.bin, instead of a |
||||
* C-language source file with the name <basefilename>.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. |
||||
* |
||||
* |
||||
* ***** 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 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). |
||||
* |
||||
* 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 |
||||
* |
||||
*----------------------------------------------------------------------------------*/ |
||||
|
||||
Update on 28 Feb 2011: I fixed a bug that caused it to stop some notes too soon. |
||||
|
||||
I also wrote a "MIDITONES_SCROLL" program that displays a miditones bytestream as a time-ordered scroll, sort of like a piano roll but with non-uniform time.This is primarily useful to debug programming errors that cause some MIDI scripts to sound strange. It reads the .bin file created from a .mid file by MIDITONES using the -b option. |
||||
|
||||
Update on 25 Apr 2011: Scott Stickeler pointed out that it doesn't work if compiled for a 64-bit environment. I'll put fixing that on my to-do list, but in the meantime the workaround is just to compile for 32 bits. (Thanks, Scott.) |
||||
|
||||
Update on 20 Nov 2011, V1.4: Added options to mask which channels (tracks) to process, and to change key by any chromatic distance. These are in support of music-playing on my Tesla Coil. |
||||
|
||||
Update on 25 Aug 2013, V1.6: I finally fixed it to compile in 64-bit environments. I didn't have a way to test that, so thanks to David Azar for doing so. |
||||
|
||||
Update on 30 Dec 2013: I added version 1.1 of MINITONES_SCROLL with a "-c" option to create annotated C source code initialization of the music bytestream. This makes it easier to manually edit the bytestream. See the beginning of the MINITONES_SCROLL source code for more details. |
||||
|
||||
Update on 7 Mar 2013: I compiled 32-bit versions for people running Windows XP and Vista. Unfortunately code.google.com no longer allows downloaded files! So I put them in a Google Drive folder here: |
||||
https://drive.google.com/folderview?id=0B1ZOnb_w5lfBQkNPeFpvRHdQNnc |
||||
|
||||
Update on 5 April 2015: Now code.google.org is going away, so I've migrated this to github. |
||||
|
||||
Update on 6 April 2015: I made the source code friendlier to more compilers. The executables are, of course, for Windows. |
||||
|
||||
|
Loading…
Reference in new issue