ATMEGA328を搭載した Arduino Duemilanove 互換機で音をPWM D/A変換出力するシンセサイザーライブラリです。
Revision | 48db01878cadbd04fb8b4272dbfdd9f3c6401d02 (tree) |
---|---|
Zeit | 2017-05-11 00:00:36 |
Autor | Akiyoshi Kamide <kamide@yk.r...> |
Commiter | Akiyoshi Kamide |
スケッチの例をCAmiDionのスケッチから抜粋して大幅拡充
@@ -1,6 +1,5 @@ | ||
1 | 1 | // |
2 | -// A simple MIDI synthesizer | |
3 | -// using MIDI library + PWM DAC Synth library | |
2 | +// Example of MIDI synthesizer using MIDI library + PWM DAC Synth library | |
4 | 3 | // |
5 | 4 | #include <MIDI.h> |
6 | 5 | MIDI_CREATE_DEFAULT_INSTANCE(); |
@@ -9,12 +8,250 @@ MIDI_CREATE_DEFAULT_INSTANCE(); | ||
9 | 8 | #define PWMDAC_OUTPUT_PIN 3 |
10 | 9 | #include <PWMDAC_Synth.h> |
11 | 10 | |
11 | +#define DRUM_MIDI_CHANNEL 10 | |
12 | + | |
12 | 13 | PWMDAC_CREATE_WAVETABLE(sineWavetable, PWMDAC_SINE_WAVE); |
14 | +PWMDAC_CREATE_WAVETABLE(sawtoothWavetable, PWMDAC_SAWTOOTH_WAVE); | |
15 | +PWMDAC_CREATE_WAVETABLE(squareWavetable, PWMDAC_SQUARE_WAVE); | |
16 | +PWMDAC_CREATE_WAVETABLE(triangleWavetable, PWMDAC_TRIANGLE_WAVE); | |
17 | + | |
18 | +PROGMEM const byte guitarWavetable[] = { | |
19 | +23, 24, 24, 25, 25, 25, 26, 26, | |
20 | +26, 27, 27, 28, 29, 30, 32, 33, | |
21 | +34, 35, 36, 36, 36, 36, 36, 37, | |
22 | +37, 37, 38, 39, 39, 40, 40, 40, | |
23 | +40, 40, 39, 39, 40, 40, 40, 41, | |
24 | +41, 41, 41, 40, 41, 41, 41, 41, | |
25 | +42, 42, 42, 42, 41, 41, 41, 41, | |
26 | +42, 41, 41, 40, 40, 40, 39, 39, | |
27 | +38, 37, 37, 37, 37, 36, 36, 36, | |
28 | +35, 34, 33, 32, 31, 30, 30, 30, | |
29 | +30, 30, 30, 30, 30, 29, 28, 27, | |
30 | +27, 27, 26, 26, 26, 26, 25, 24, | |
31 | +24, 23, 23, 23, 23, 22, 22, 22, | |
32 | +22, 21, 21, 21, 21, 21, 21, 21, | |
33 | +20, 21, 20, 20, 19, 19, 18, 18, | |
34 | +18, 18, 18, 18, 18, 18, 17, 16, | |
35 | +16, 15, 14, 14, 15, 15, 16, 16, | |
36 | +16, 16, 17, 17, 17, 17, 17, 17, | |
37 | +18, 18, 18, 18, 17, 17, 17, 17, | |
38 | +17, 17, 18, 18, 17, 17, 16, 15, | |
39 | +15, 14, 14, 15, 15, 15, 16, 16, | |
40 | +16, 16, 16, 16, 16, 16, 16, 16, | |
41 | +16, 16, 16, 15, 15, 15, 15, 15, | |
42 | +14, 14, 13, 12, 11, 10, 9, 9, | |
43 | +9, 9, 8, 8, 8, 7, 6, 6, | |
44 | +5, 4, 3, 2, 2, 3, 3, 3, | |
45 | +3, 4, 4, 4, 4, 4, 3, 3, | |
46 | +2, 2, 2, 2, 2, 1, 2, 2, | |
47 | +3, 4, 4, 4, 5, 5, 5, 6, | |
48 | +6, 7, 9, 10, 11, 11, 12, 12, | |
49 | +13, 13, 14, 14, 14, 15, 15, 16, | |
50 | +17, 17, 18, 19, 20, 21, 21, 22, | |
51 | +}; | |
52 | + | |
53 | +PROGMEM const byte randomWavetable[] = { | |
54 | +39, 22, 21, 9, 23, 13, 28, 31, | |
55 | +15, 30, 40, 8, 29, 26, 27, 8, | |
56 | +34, 30, 4, 22, 39, 25, 35, 33, | |
57 | +38, 17, 7, 38, 18, 24, 12, 9, | |
58 | +8, 36, 27, 17, 33, 0, 13, 35, | |
59 | +20, 15, 34, 0, 34, 6, 29, 38, | |
60 | +30, 20, 16, 39, 26, 18, 28, 28, | |
61 | +24, 38, 27, 31, 25, 14, 9, 25, | |
62 | +31, 13, 3, 17, 29, 23, 18, 6, | |
63 | +12, 20, 30, 27, 1, 40, 9, 19, | |
64 | +26, 21, 4, 25, 1, 16, 11, 18, | |
65 | +15, 23, 30, 7, 37, 23, 11, 19, | |
66 | +30, 36, 7, 9, 17, 27, 8, 41, | |
67 | +4, 9, 26, 0, 24, 18, 6, 15, | |
68 | +30, 23, 7, 9, 9, 41, 1, 0, | |
69 | +33, 9, 34, 18, 19, 22, 25, 16, | |
70 | +22, 31, 41, 21, 27, 35, 38, 32, | |
71 | +17, 16, 10, 39, 36, 9, 37, 13, | |
72 | +16, 12, 10, 14, 21, 12, 19, 12, | |
73 | +11, 19, 0, 32, 13, 27, 32, 10, | |
74 | +18, 5, 22, 9, 6, 33, 29, 2, | |
75 | +4, 2, 17, 0, 38, 14, 18, 16, | |
76 | +25, 10, 8, 3, 3, 39, 3, 5, | |
77 | +7, 22, 6, 11, 16, 23, 23, 5, | |
78 | +3, 23, 22, 25, 17, 7, 19, 29, | |
79 | +41, 0, 10, 15, 14, 41, 6, 40, | |
80 | +8, 0, 19, 16, 30, 18, 2, 24, | |
81 | +17, 37, 11, 6, 1, 33, 10, 31, | |
82 | +33, 19, 20, 23, 24, 41, 4, 40, | |
83 | +29, 12, 4, 11, 38, 17, 41, 8, | |
84 | +15, 37, 19, 34, 36, 8, 19, 10, | |
85 | +32, 14, 19, 1, 1, 35, 35, 3, | |
86 | +}; | |
87 | + | |
88 | +PROGMEM const Instrument DRUM_INSTRUMENT = {randomWavetable, {5, 0, 5, 0}}; | |
13 | 89 | |
14 | 90 | // {wavetableArray, {release, sustain, decay, attack}} |
15 | -PROGMEM const Instrument instrument = {sineWavetable, {9, 128, 8, 3}}; | |
91 | +PROGMEM const Instrument INSTRUMENTS[] = { | |
92 | +// General MIDI instruments | |
93 | + // Piano | |
94 | + {sawtoothWavetable, {9, 0, 11, 4}}, | |
95 | + {sawtoothWavetable, {9, 0, 11, 4}}, | |
96 | + {sawtoothWavetable, {9, 0, 11, 4}}, | |
97 | + {sawtoothWavetable, {9, 0, 11, 4}}, | |
98 | + {guitarWavetable, {9, 0, 11, 4}}, | |
99 | + {sawtoothWavetable, {9, 0, 10, 4}}, | |
100 | + {sawtoothWavetable, {9, 0, 11, 4}}, | |
101 | + {sawtoothWavetable, {8, 0, 10, 4}}, | |
102 | + | |
103 | + // Chromatic Percussion | |
104 | + {sawtoothWavetable, {9, 0, 10, 4}}, | |
105 | + {sineWavetable, {9, 0, 11, 4}}, | |
106 | + {sineWavetable, {9, 0, 10, 3}}, | |
107 | + {sineWavetable, {9, 0, 11, 4}}, | |
108 | + {sineWavetable, {8, 0, 8, 4}}, | |
109 | + {sineWavetable, {7, 0, 7, 4}}, | |
110 | + {sawtoothWavetable, {9, 0, 11, 4}}, | |
111 | + {sawtoothWavetable, {9, 0, 9, 4}}, | |
112 | + | |
113 | + // Organ | |
114 | + {guitarWavetable, {9, 255, 11, 4}}, | |
115 | + {sawtoothWavetable, {9, 255, 11, 4}}, | |
116 | + {guitarWavetable, {9, 255, 11, 4}}, | |
117 | + {sawtoothWavetable, {9, 255, 11, 4}}, | |
118 | + {sawtoothWavetable, {9, 255, 11, 6}}, | |
119 | + {sawtoothWavetable, {9, 255, 11, 8}}, | |
120 | + {sawtoothWavetable, {9, 255, 11, 6}}, | |
121 | + {sawtoothWavetable, {9, 255, 11, 6}}, | |
122 | + | |
123 | + // Guitar | |
124 | + {guitarWavetable, {9, 0, 11, 4}}, | |
125 | + {sawtoothWavetable, {9, 0, 11, 4}}, | |
126 | + {guitarWavetable, {9, 0, 11, 4}}, | |
127 | + {sawtoothWavetable, {9, 0, 11, 4}}, | |
128 | + {guitarWavetable, {9, 0, 11, 4}}, | |
129 | + {sawtoothWavetable, {9, 0, 10, 4}}, | |
130 | + {sawtoothWavetable, {9, 0, 11, 4}}, | |
131 | + {randomWavetable, {9, 8, 10, 4}}, | |
132 | + | |
133 | + // Bass | |
134 | + {guitarWavetable, {9, 0, 11, 4}}, | |
135 | + {guitarWavetable, {9, 0, 11, 4}}, | |
136 | + {guitarWavetable, {9, 192, 9, 3}}, | |
137 | + {guitarWavetable, {9, 192, 9, 6}}, | |
138 | + {sawtoothWavetable, {9, 0, 11, 4}}, | |
139 | + {sawtoothWavetable, {9, 0, 11, 4}}, | |
140 | + {sawtoothWavetable, {9, 128, 10, 4}}, | |
141 | + {sawtoothWavetable, {9, 192, 11, 4}}, | |
142 | + | |
143 | + // Strings | |
144 | + {sawtoothWavetable, {9, 255, 10, 6}}, | |
145 | + {sawtoothWavetable, {9, 255, 10, 6}}, | |
146 | + {sawtoothWavetable, {9, 255, 10, 6}}, | |
147 | + {sawtoothWavetable, {9, 255, 10, 6}}, | |
148 | + {guitarWavetable, {9, 255, 11, 6}}, | |
149 | + {sawtoothWavetable, {8, 0, 8, 4}}, | |
150 | + {sineWavetable, {9, 0, 11, 4}}, | |
151 | + {randomWavetable, {9, 0, 10, 3}}, | |
152 | + | |
153 | + // Ensemble | |
154 | + {triangleWavetable, {9, 255, 11, 6}}, | |
155 | + {triangleWavetable, {9, 255, 11, 9}}, | |
156 | + {triangleWavetable, {9, 255, 11, 6}}, | |
157 | + {triangleWavetable, {9, 255, 11, 7}}, | |
158 | + {guitarWavetable, {9, 255, 11, 4}}, | |
159 | + {sawtoothWavetable, {9, 128, 9, 4}}, | |
160 | + {sineWavetable, {9, 255, 11, 4}}, | |
161 | + {squareWavetable, {8, 0, 9, 3}}, | |
162 | + | |
163 | + // Brass | |
164 | + {sawtoothWavetable, {9, 255, 11, 6}}, | |
165 | + {sawtoothWavetable, {9, 255, 11, 6}}, | |
166 | + {sawtoothWavetable, {9, 255, 11, 6}}, | |
167 | + {sawtoothWavetable, {9, 255, 11, 6}}, | |
168 | + {guitarWavetable, {9, 255, 11, 7}}, | |
169 | + {sawtoothWavetable, {9, 128, 9, 5}}, | |
170 | + {sawtoothWavetable, {9, 192, 9, 5}}, | |
171 | + {guitarWavetable, {9, 192, 10, 5}}, | |
172 | + | |
173 | + // Reed | |
174 | + {guitarWavetable, {9, 255, 11, 6}}, | |
175 | + {sawtoothWavetable, {9, 255, 11, 6}}, | |
176 | + {sawtoothWavetable, {9, 255, 11, 6}}, | |
177 | + {sawtoothWavetable, {9, 255, 11, 6}}, | |
178 | + {sawtoothWavetable, {9, 255, 11, 6}}, | |
179 | + {sawtoothWavetable, {9, 255, 11, 4}}, | |
180 | + {sawtoothWavetable, {9, 255, 11, 4}}, | |
181 | + {triangleWavetable, {9, 255, 11, 5}}, | |
182 | + | |
183 | + // Pipe | |
184 | + {guitarWavetable, {9, 255, 11, 6}}, | |
185 | + {guitarWavetable, {9, 255, 11, 7}}, | |
186 | + {sineWavetable, {9, 255, 11, 6}}, | |
187 | + {triangleWavetable, {9, 255, 11, 7}}, | |
188 | + {randomWavetable, {9, 128, 10, 6}}, | |
189 | + {triangleWavetable, {9, 255, 11, 7}}, | |
190 | + {sineWavetable, {9, 255, 11, 7}}, | |
191 | + {sineWavetable, {9, 255, 11, 7}}, | |
192 | + | |
193 | + // Synth Lead | |
194 | + {squareWavetable, {9, 255, 11, 3}}, | |
195 | + {sawtoothWavetable, {9, 255, 11, 3}}, | |
196 | + {triangleWavetable, {9, 255, 11, 5}}, | |
197 | + {triangleWavetable, {9, 128, 8, 6}}, | |
198 | + {sawtoothWavetable, {9, 192, 8, 5}}, | |
199 | + {sawtoothWavetable, {9, 192, 8, 5}}, | |
200 | + {guitarWavetable, {9, 192, 11, 5}}, | |
201 | + {sawtoothWavetable, {9, 255, 11, 3}}, | |
202 | + | |
203 | + // Synth Pad | |
204 | + {guitarWavetable, {9, 255, 11, 5}}, | |
205 | + {guitarWavetable, {9, 255, 11, 9}}, | |
206 | + {guitarWavetable, {4, 192, 9, 4}}, | |
207 | + {guitarWavetable, {9, 255, 11, 6}}, | |
208 | + {guitarWavetable, {9, 192, 10, 8}}, | |
209 | + {sawtoothWavetable, {9, 255, 11, 10}}, | |
210 | + {guitarWavetable, {9, 255, 11, 8}}, | |
211 | + {sawtoothWavetable, {9, 255, 11, 10}}, | |
212 | + | |
213 | + // Synth Effects | |
214 | + {guitarWavetable, {9, 128, 9, 4}}, | |
215 | + {sawtoothWavetable, {9, 128, 10, 10}}, | |
216 | + {triangleWavetable, {9, 192, 8, 4}}, | |
217 | + {guitarWavetable, {9, 0, 11, 4}}, | |
218 | + {sawtoothWavetable, {10, 0, 11, 3}}, | |
219 | + {triangleWavetable, {9, 0, 11, 10}}, | |
220 | + {guitarWavetable, {9, 255, 11, 4}}, | |
221 | + {sawtoothWavetable, {9, 255, 11, 6}}, | |
16 | 222 | |
17 | -PWMDAC_CREATE_INSTANCE(&instrument); | |
223 | + // Ethnic | |
224 | + {sawtoothWavetable, {9, 0, 11, 4}}, | |
225 | + {sawtoothWavetable, {9, 0, 11, 4}}, | |
226 | + {sawtoothWavetable, {9, 0, 9, 4}}, | |
227 | + {sawtoothWavetable, {9, 0, 11, 4}}, | |
228 | + {sawtoothWavetable, {8, 0, 8, 4}}, | |
229 | + {sawtoothWavetable, {9, 255, 11, 6}}, | |
230 | + {sawtoothWavetable, {9, 255, 11, 6}}, | |
231 | + {sawtoothWavetable, {9, 255, 11, 6}}, | |
232 | + | |
233 | + // Percussive | |
234 | + {squareWavetable, {9, 64, 9, 4}}, | |
235 | + {sawtoothWavetable, {8, 0, 8, 4}}, | |
236 | + {guitarWavetable, {9, 0, 11, 5}}, | |
237 | + {sineWavetable, {8, 0, 8, 4}}, | |
238 | + {randomWavetable, {8, 0, 8, 4}}, | |
239 | + {triangleWavetable, {8, 0, 8, 4}}, | |
240 | + {randomWavetable, {8, 0, 8, 4}}, | |
241 | + {randomWavetable, {8, 255, 7, 12}}, | |
242 | + | |
243 | + // Sound Effects | |
244 | + {randomWavetable, {8, 0, 8, 4}}, | |
245 | + {randomWavetable, {8, 0, 8, 4}}, | |
246 | + {randomWavetable, {10, 64, 12, 12}}, | |
247 | + {sineWavetable, {9, 255, 11, 4}}, | |
248 | + {randomWavetable, {9, 255, 11, 4}}, | |
249 | + {randomWavetable, {9, 255, 11, 12}}, | |
250 | + {randomWavetable, {10, 255, 10, 11}}, | |
251 | + {randomWavetable, {9, 0, 10, 3}}, | |
252 | +}; | |
253 | + | |
254 | +PWMDAC_CREATE_INSTANCE(INSTRUMENTS); | |
18 | 255 | |
19 | 256 | void HandleNoteOn(byte channel, byte pitch, byte velocity) { |
20 | 257 | if( velocity == 0 ) { |
@@ -24,22 +261,66 @@ void HandleNoteOn(byte channel, byte pitch, byte velocity) { | ||
24 | 261 | PWMDACSynth::noteOn(channel,pitch,velocity); |
25 | 262 | } |
26 | 263 | |
264 | +void HandleProgramChange(byte channel, byte number) { | |
265 | + if( channel == DRUM_MIDI_CHANNEL ) return; | |
266 | + PWMDACSynth::getChannel(channel)->programChange(INSTRUMENTS + number); | |
267 | +} | |
268 | + | |
269 | +void HandleSystemReset() { | |
270 | + PWMDACSynth::systemReset(); | |
271 | + // In PWMDAC Synth lib, All MIDI channel will be reset to same waveform/envelope even ch#10. | |
272 | + // So ensure to set drum instrument to ch#10. | |
273 | + PWMDACSynth::getChannel(DRUM_MIDI_CHANNEL)->programChange(&DRUM_INSTRUMENT); | |
274 | +} | |
275 | + | |
276 | +// System Exclusive to reset, without first byte(0xF0)/last byte(0xF7) | |
277 | +PROGMEM const byte GM_SYSTEM_ON[] = { | |
278 | + 0x7E, // Universal | |
279 | + 0x7F, 0x09, 0x01 | |
280 | +}; | |
281 | +PROGMEM const byte GS_SYSTEM_ON[] = { | |
282 | + 0x41, // Roland | |
283 | + 0x00, 0x42, 0x12, 0x40, 0x00, 0x7F, 0x00, 0x41 | |
284 | +}; | |
285 | +PROGMEM const byte XG_SYSTEM_ON[] = { | |
286 | + 0x43, // YAMAHA | |
287 | + 0x10, 0x4C, 0x00, 0x00, 0x7E, 0x00 | |
288 | +}; | |
289 | +void HandleSystemExclusive(byte *array, unsigned size) { | |
290 | + array++; size -= 2; | |
291 | + if( memcmp_P(array, GM_SYSTEM_ON, size) == 0 ) { | |
292 | + HandleSystemReset(); return; | |
293 | + } | |
294 | + array[1] &= 0xF0; // Clear lower 4-bits of device ID (0x1n -> 0x10) | |
295 | + if( memcmp_P(array, XG_SYSTEM_ON, size) == 0 ) { | |
296 | + HandleSystemReset(); return; | |
297 | + } | |
298 | + array[1] = 0; // Clear device ID (0xnn -> 0x00) | |
299 | + if( memcmp_P(array, GS_SYSTEM_ON, size) == 0 ) { | |
300 | + HandleSystemReset(); return; | |
301 | + } | |
302 | +} | |
303 | + | |
27 | 304 | void setup() { |
28 | 305 | PWMDACSynth::setup(); |
29 | - MIDI.begin(MIDI_CHANNEL_OMNI); // receives all MIDI channels | |
30 | - MIDI.turnThruOff(); // Disable MIDI IN -> MIDI OUT mirroring | |
31 | 306 | MIDI.setHandleNoteOff(PWMDACSynth::noteOff); |
32 | 307 | MIDI.setHandleNoteOn(HandleNoteOn); |
33 | 308 | MIDI.setHandlePitchBend(PWMDACSynth::pitchBend); |
34 | 309 | MIDI.setHandleControlChange(PWMDACSynth::controlChange); |
310 | + MIDI.setHandleSystemReset(HandleSystemReset); | |
311 | + MIDI.setHandleProgramChange(HandleProgramChange); | |
312 | + MIDI.setHandleSystemExclusive(HandleSystemExclusive); | |
313 | + MIDI.begin(MIDI_CHANNEL_OMNI); // receives all MIDI channels | |
314 | + MIDI.turnThruOff(); // Disable MIDI IN -> MIDI OUT mirroring | |
35 | 315 | pinMode(MIDI_ENABLE_PIN,OUTPUT); |
36 | 316 | digitalWrite(MIDI_ENABLE_PIN,HIGH); // enable MIDI port |
317 | + PWMDACSynth::getChannel(DRUM_MIDI_CHANNEL)->programChange(&DRUM_INSTRUMENT); | |
37 | 318 | } |
38 | 319 | |
39 | 320 | void loop() { |
40 | 321 | static byte tick=0; |
41 | 322 | MIDI.read(); |
42 | - if( ++tick >= 16 ) { | |
323 | + if( ++tick >= 8 ) { | |
43 | 324 | tick = 0; |
44 | 325 | PWMDACSynth::update(); |
45 | 326 | } |