/********************************************************************************************* * * MIDI2TONES: Convert a MIDI file into a simple bytestream of notes * * This is a fork of MIDITONES as it stood on September 27, 2016 * Copyright (c) 2011,2013,2015,2016, Len Shustek * https://github.com/LenShustek/miditones * * The purpose of the fork was to add an alternate output format. * * MIDI2TONES converts a MIDI music file into a much simplified stream of commands, so that * the music can easily be played on a small microcontroller-based synthesizer that has * only simple tone generators. This is on GitHub at * https://github.com/MLXXXp/midi2tones * * This was written for the "Playtune" series of Arduino and Teensy microcontroller * synthesizers. See the separate documentation for the various Playtune players at * https://github.com/LenShustek/arduino-playtune * https://github.com/LenShustek/ATtiny-playtune * https://github.com/LenShustek/Playtune_poll * https://github.com/LenShustek/Playtune_samp * and also the ArduboyPlaytune library derived from arduino-playtune * https://github.com/Arduboy/ArduboyPlaytune * * MIDI2TONES may also prove useful for other simple music synthesizers. * * Volume ("velocity") and instrument information in the MIDI file can either be * discarded or kept. All the tracks are processed and merged into a single time-ordered * stream of "note on", "note off", "change instrument" and "delay" commands. * * An alternate output format can be specified, which consists of a single monotonic * stream of frequency/duration pairs of 16 bit values. The specified frequency can * also include a flag to indicate that the note is to be played at a higher volume, * if the velocity of the MIDI note is above a certain value. * This format is suitable for use with the ArduboyTones library, which is on GitHub at * https://github.com/MLXXXp/ArduboyTones * * 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. * * MIDI2TONES is written in standard ANSI C 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 all of its * variations. 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. * * There is a companion program in the same repository called Miditones_scroll that * can convert the Playtune bytestream generated by MIDI2TONES into a piano-player * like listing for debugging or annotation. See the documentation in the * beginning of its source code. * * * ***** The MIDI2TONES command line ***** * * To convert a MIDI file called "chopin.mid" into a command bytestream, execute * * midi2tones 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: * * midi2tones <options> <basefilename> * * Options must be specified individually, each with its own "-" lead-in, and separated * with spaces. A forward slash "/" can be used instead of a dash "-" for option lead-ins. * * 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 <basefilename>.mid The output filename(s) * are the base file name with .c, .bin, and/or .log extensions. * * * The following commonly-used command-line options can be specified: * * -on Generate output format "n". * Two formats are available: * 1: The Playtune format (which is the default if this option isn't given). * 2: The frequency/duration pair format, as used by ArduboyTones. * * -v Add velocity (volume) information to the output bytestream. * * -vn For the alternate format, "n" specifies the minimum velocity value that will * produce a high volume tone. Without this option all tones will be * normal volume. * * -i Add instrument change commands to the output bytestream. * * -pt Translate notes in the MIDI percussion track to note numbers 128..255 * and assign them to a tone generator as usual. * * -d Generate a self-describing file header that says which optional bytestream * fields are present. This is highly recommended if you are using later * Playtune players that can check the header to know what data to expect. * * -b Generate a binary file with the name <basefilename>.bin, instead of a * C-language source file with the name <basefilename>.c. * * -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. * * * The following are lesser-used command-line options: * * -p Only parse the MIDI file, and don't generate an output file. * Tracks are processed sequentially instead of being merged into chronological order. * This is mostly useful for debugging 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. * * -nx Put about "x" items on each line of the C file output. * * -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. * * -cn Only process the channel numbers whose bits are on in the number "n". * For example, -c3 means "only process channels 0 and 1". In addition to decimal, * "n" can be also specified in hex using a 0x prefix or octal with a 0 prefix. * For the alternate output format, only the lowest bit will be used to specify * the single channel to be processed, and without this option channel 0 will * be used. * * -kn Change the musical key of the output by n chromatic notes. * -k-12 goes one octave down, -k12 goes one octave up, etc. * * -pi Ignore notes in the MIDI percussion track 9 (also called 10 by some). * * -dp Generate IDE-dependent C code to define PROGMEM. * * -fx For the alternate output format, instead of using defined note names, * output actual frequency values in decimal format depending on "x": * -fa: For high volume notes use format "<freq>+TONE_HIGH_VOLUME". * -fb: For high volume notes just add 0x8000 to the frequency value. * * -r Terminate the output file with a "restart" command instead of a "stop" command. * * -h Give command-line help. * * * ***** The score bytestream ***** * * The generated bytestream is a series of commands that turn notes on and off, * maybe change instruments, and begin 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, replacing any previous note. * Generators are numbered starting with 0. The note numbers are the MIDI * numbers for the chromatic scale, with decimal 69 being Middle A (440 Hz). * If the -v option was given, a second byte is added to indicate note volume. * * 8t Stop playing the note on tone generator t. * * Ct ii Change tone generator t to play instrument ii from now on. This will only * be generated if the -i option was given. * * F0 End of score; stop playing. * * E0 End of score; start playing again from the beginning. Will be generated if * the -r option was given. * * 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. * * If the -d option is specified, the bytestream begins with a little header that tells * what optional information will be in the data. This makes the file more self-describing, * and allows music players to adapt to different kinds of files. The later Playtune * players do that. The header looks like this: * * 'Pt' Two ascii characters that signal the presence of the header * nn The length (in one byte) of the entire header, 6..255 * ff1 A byte of flag bits, three of which are currently defined: * 80 velocity information is present * 40 instrument change information is present * 20 translated percussion notes are present * ff2 Another byte of flags, currently undefined * tt The number (in one byte) of tone generators actually used in this music. * * Any subsequent header bytes covered by the count, if present, are currently undefined * and should be ignored by players. * * ***** The alternate frequency/duration pair output format ***** * * The generated stream is a series of frequency/duration value pairs. The frequency * is in Hz and the duration is in milliseconds. Each value is 16 bits. For a binary * file the values are stored high byte first. The ArduboyTones player supports * frequencies from 16 Hz to 32767 Hz but MIDI2TONES converts MIDI note numbers in the * range from note 12 (16.352 Hz rounded to 16 Hz) to note 127 (12543.9 Hz rounded * to 12544 Hz). * * Periods of silence are represented by a frequency/duration pair with a frequency * value of 0. * * Since the output is monotonic, only one MIDI channel is processed. The lowest bit * set in the -cn option's mask will indicate the channel to be used. If the -cn option * isn't given, channel 0 will be used. * * Tones can be specified to play at either normal or high volume. High volume is * indicated by setting the high bit of the frequency value (i.e. adding 0x8000 to the * desired frequency). A note will be set to high volume if the -vn option is used and * the MIDI velocity of the note is equal to or greater than the option value. * * For the C output format, frequencies will be output as note names, as defined in the * ArduboyTones library's ArduboyTonesPitches.h file. If the -f option is given, * the actual frequency, in decimal, will be used instead. Durations will be output * in decimal. * * Output files are terminated with a single 16 bit value of 0x8000 to indicate * end of score - stop playing. A file can instead be terminated with 0x8001 to indicate * end of score - start playing again from the beginning, which is specified using the * -r option. * * Len Shustek, 4 Feb 2011 and later. * Frequency/duration pair output format and other changes: * Scott Allen, 27 Sept 2016 and later. *********************************************************************************************/
unwiredben/midi2tones
Fork of MIDITONES - Convert MIDI files to a simplified time-ordered sequence of note commands
CNOASSERTION