forked from LenShustek/miditones
-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathREADME.txt
More file actions
236 lines (236 loc) · 11.2 KB
/
README.txt
File metadata and controls
236 lines (236 loc) · 11.2 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
/*********************************************************************************************
*
* 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.
*********************************************************************************************/