aboutsummaryrefslogtreecommitdiff
path: root/quantum/audio
diff options
context:
space:
mode:
Diffstat (limited to 'quantum/audio')
-rw-r--r--quantum/audio/audio.c334
-rw-r--r--quantum/audio/audio.h17
-rw-r--r--quantum/audio/audio_pwm.c15
-rw-r--r--quantum/audio/luts.c16
-rw-r--r--quantum/audio/luts.h18
-rw-r--r--quantum/audio/musical_notes.h18
-rw-r--r--quantum/audio/song_list.h42
-rw-r--r--quantum/audio/voices.c137
-rw-r--r--quantum/audio/voices.h21
-rw-r--r--quantum/audio/wave.h18
10 files changed, 474 insertions, 162 deletions
diff --git a/quantum/audio/audio.c b/quantum/audio/audio.c
index ead5fbf3e..597073611 100644
--- a/quantum/audio/audio.c
+++ b/quantum/audio/audio.c
@@ -1,3 +1,18 @@
1/* Copyright 2016 Jack Humbert
2 *
3 * This program is free software: you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation, either version 2 of the License, or
6 * (at your option) any later version.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
1#include <stdio.h> 16#include <stdio.h>
2#include <string.h> 17#include <string.h>
3//#include <math.h> 18//#include <math.h>
@@ -77,6 +92,7 @@ static bool audio_initialized = false;
77audio_config_t audio_config; 92audio_config_t audio_config;
78 93
79uint16_t envelope_index = 0; 94uint16_t envelope_index = 0;
95bool glissando = true;
80 96
81void audio_init() 97void audio_init()
82{ 98{
@@ -88,15 +104,15 @@ void audio_init()
88 } 104 }
89 audio_config.raw = eeconfig_read_audio(); 105 audio_config.raw = eeconfig_read_audio();
90 106
91 // Set port PC6 (OC3A and /OC4A) as output 107 // Set port PC6 (OC3A and /OC4A) as output
92 DDRC |= _BV(PORTC6); 108 DDRC |= _BV(PORTC6);
93 109
94 DISABLE_AUDIO_COUNTER_3_ISR; 110 DISABLE_AUDIO_COUNTER_3_ISR;
95 111
96 // TCCR3A / TCCR3B: Timer/Counter #3 Control Registers 112 // TCCR3A / TCCR3B: Timer/Counter #3 Control Registers
97 // Compare Output Mode (COM3An) = 0b00 = Normal port operation, OC3A disconnected from PC6 113 // Compare Output Mode (COM3An) = 0b00 = Normal port operation, OC3A disconnected from PC6
98 // Waveform Generation Mode (WGM3n) = 0b1110 = Fast PWM Mode 14 (Period = ICR3, Duty Cycle = OCR3A) 114 // Waveform Generation Mode (WGM3n) = 0b1110 = Fast PWM Mode 14 (Period = ICR3, Duty Cycle = OCR3A)
99 // Clock Select (CS3n) = 0b010 = Clock / 8 115 // Clock Select (CS3n) = 0b010 = Clock / 8
100 TCCR3A = (0 << COM3A1) | (0 << COM3A0) | (1 << WGM31) | (0 << WGM30); 116 TCCR3A = (0 << COM3A1) | (0 << COM3A0) | (1 << WGM31) | (0 << WGM30);
101 TCCR3B = (1 << WGM33) | (1 << WGM32) | (0 << CS32) | (1 << CS31) | (0 << CS30); 117 TCCR3B = (1 << WGM33) | (1 << WGM32) | (0 << CS32) | (1 << CS31) | (0 << CS30);
102 118
@@ -105,6 +121,8 @@ void audio_init()
105 121
106void stop_all_notes() 122void stop_all_notes()
107{ 123{
124 dprintf("audio stop all notes");
125
108 if (!audio_initialized) { 126 if (!audio_initialized) {
109 audio_init(); 127 audio_init();
110 } 128 }
@@ -127,6 +145,8 @@ void stop_all_notes()
127 145
128void stop_note(float freq) 146void stop_note(float freq)
129{ 147{
148 dprintf("audio stop note freq=%d", (int)freq);
149
130 if (playing_note) { 150 if (playing_note) {
131 if (!audio_initialized) { 151 if (!audio_initialized) {
132 audio_init(); 152 audio_init();
@@ -182,155 +202,161 @@ float vibrato(float average_freq) {
182 202
183ISR(TIMER3_COMPA_vect) 203ISR(TIMER3_COMPA_vect)
184{ 204{
185 float freq; 205 float freq;
186 206
187 if (playing_note) { 207 if (playing_note) {
188 if (voices > 0) { 208 if (voices > 0) {
189 if (polyphony_rate > 0) { 209 if (polyphony_rate > 0) {
190 if (voices > 1) { 210 if (voices > 1) {
191 voice_place %= voices; 211 voice_place %= voices;
192 if (place++ > (frequencies[voice_place] / polyphony_rate / CPU_PRESCALER)) { 212 if (place++ > (frequencies[voice_place] / polyphony_rate / CPU_PRESCALER)) {
193 voice_place = (voice_place + 1) % voices; 213 voice_place = (voice_place + 1) % voices;
194 place = 0.0; 214 place = 0.0;
195 } 215 }
196 } 216 }
197 217
198 #ifdef VIBRATO_ENABLE 218 #ifdef VIBRATO_ENABLE
199 if (vibrato_strength > 0) { 219 if (vibrato_strength > 0) {
200 freq = vibrato(frequencies[voice_place]); 220 freq = vibrato(frequencies[voice_place]);
201 } else { 221 } else {
202 freq = frequencies[voice_place]; 222 freq = frequencies[voice_place];
203 } 223 }
204 #else 224 #else
205 freq = frequencies[voice_place]; 225 freq = frequencies[voice_place];
206 #endif 226 #endif
207 } else { 227 } else {
208 if (frequency != 0 && frequency < frequencies[voices - 1] && frequency < frequencies[voices - 1] * pow(2, -440/frequencies[voices - 1]/12/2)) { 228 if (glissando) {
209 frequency = frequency * pow(2, 440/frequency/12/2); 229 if (frequency != 0 && frequency < frequencies[voices - 1] && frequency < frequencies[voices - 1] * pow(2, -440/frequencies[voices - 1]/12/2)) {
210 } else if (frequency != 0 && frequency > frequencies[voices - 1] && frequency > frequencies[voices - 1] * pow(2, 440/frequencies[voices - 1]/12/2)) { 230 frequency = frequency * pow(2, 440/frequency/12/2);
211 frequency = frequency * pow(2, -440/frequency/12/2); 231 } else if (frequency != 0 && frequency > frequencies[voices - 1] && frequency > frequencies[voices - 1] * pow(2, 440/frequencies[voices - 1]/12/2)) {
212 } else { 232 frequency = frequency * pow(2, -440/frequency/12/2);
213 frequency = frequencies[voices - 1]; 233 } else {
214 } 234 frequency = frequencies[voices - 1];
215 235 }
216 #ifdef VIBRATO_ENABLE 236 } else {
217 if (vibrato_strength > 0) { 237 frequency = frequencies[voices - 1];
218 freq = vibrato(frequency); 238 }
219 } else { 239
220 freq = frequency; 240 #ifdef VIBRATO_ENABLE
221 } 241 if (vibrato_strength > 0) {
222 #else 242 freq = vibrato(frequency);
223 freq = frequency; 243 } else {
224 #endif 244 freq = frequency;
225 } 245 }
226 246 #else
227 if (envelope_index < 65535) { 247 freq = frequency;
228 envelope_index++; 248 #endif
229 } 249 }
230 250
231 freq = voice_envelope(freq); 251 if (envelope_index < 65535) {
232 252 envelope_index++;
233 if (freq < 30.517578125) { 253 }
234 freq = 30.52; 254
235 } 255 freq = voice_envelope(freq);
236 256
237 TIMER_3_PERIOD = (uint16_t)(((float)F_CPU) / (freq * CPU_PRESCALER)); 257 if (freq < 30.517578125) {
238 TIMER_3_DUTY_CYCLE = (uint16_t)((((float)F_CPU) / (freq * CPU_PRESCALER)) * note_timbre); 258 freq = 30.52;
239 } 259 }
240 } 260
241 261 TIMER_3_PERIOD = (uint16_t)(((float)F_CPU) / (freq * CPU_PRESCALER));
242 if (playing_notes) { 262 TIMER_3_DUTY_CYCLE = (uint16_t)((((float)F_CPU) / (freq * CPU_PRESCALER)) * note_timbre);
243 if (note_frequency > 0) { 263 }
244 #ifdef VIBRATO_ENABLE 264 }
245 if (vibrato_strength > 0) { 265
246 freq = vibrato(note_frequency); 266 if (playing_notes) {
247 } else { 267 if (note_frequency > 0) {
248 freq = note_frequency; 268 #ifdef VIBRATO_ENABLE
249 } 269 if (vibrato_strength > 0) {
250 #else 270 freq = vibrato(note_frequency);
251 freq = note_frequency; 271 } else {
252 #endif 272 freq = note_frequency;
253 273 }
254 if (envelope_index < 65535) { 274 #else
255 envelope_index++; 275 freq = note_frequency;
256 } 276 #endif
257 freq = voice_envelope(freq); 277
258 278 if (envelope_index < 65535) {
259 TIMER_3_PERIOD = (uint16_t)(((float)F_CPU) / (freq * CPU_PRESCALER)); 279 envelope_index++;
260 TIMER_3_DUTY_CYCLE = (uint16_t)((((float)F_CPU) / (freq * CPU_PRESCALER)) * note_timbre); 280 }
261 } else { 281 freq = voice_envelope(freq);
262 TIMER_3_PERIOD = 0; 282
263 TIMER_3_DUTY_CYCLE = 0; 283 TIMER_3_PERIOD = (uint16_t)(((float)F_CPU) / (freq * CPU_PRESCALER));
264 } 284 TIMER_3_DUTY_CYCLE = (uint16_t)((((float)F_CPU) / (freq * CPU_PRESCALER)) * note_timbre);
265 285 } else {
266 note_position++; 286 TIMER_3_PERIOD = 0;
267 bool end_of_note = false; 287 TIMER_3_DUTY_CYCLE = 0;
268 if (TIMER_3_PERIOD > 0) { 288 }
269 end_of_note = (note_position >= (note_length / TIMER_3_PERIOD * 0xFFFF)); 289
270 } else { 290 note_position++;
271 end_of_note = (note_position >= (note_length * 0x7FF)); 291 bool end_of_note = false;
272 } 292 if (TIMER_3_PERIOD > 0) {
273 293 end_of_note = (note_position >= (note_length / TIMER_3_PERIOD * 0xFFFF));
274 if (end_of_note) { 294 } else {
275 current_note++; 295 end_of_note = (note_position >= (note_length * 0x7FF));
276 if (current_note >= notes_count) { 296 }
277 if (notes_repeat) { 297
278 current_note = 0; 298 if (end_of_note) {
279 } else { 299 current_note++;
280 DISABLE_AUDIO_COUNTER_3_ISR; 300 if (current_note >= notes_count) {
281 DISABLE_AUDIO_COUNTER_3_OUTPUT; 301 if (notes_repeat) {
282 playing_notes = false; 302 current_note = 0;
283 return; 303 } else {
284 } 304 DISABLE_AUDIO_COUNTER_3_ISR;
285 } 305 DISABLE_AUDIO_COUNTER_3_OUTPUT;
286 if (!note_resting && (notes_rest > 0)) { 306 playing_notes = false;
287 note_resting = true; 307 return;
288 note_frequency = 0; 308 }
289 note_length = notes_rest; 309 }
290 current_note--; 310 if (!note_resting && (notes_rest > 0)) {
291 } else { 311 note_resting = true;
292 note_resting = false; 312 note_frequency = 0;
293 envelope_index = 0; 313 note_length = notes_rest;
294 note_frequency = (*notes_pointer)[current_note][0]; 314 current_note--;
295 note_length = ((*notes_pointer)[current_note][1] / 4) * (((float)note_tempo) / 100); 315 } else {
296 } 316 note_resting = false;
297 317 envelope_index = 0;
298 note_position = 0; 318 note_frequency = (*notes_pointer)[current_note][0];
299 } 319 note_length = ((*notes_pointer)[current_note][1] / 4) * (((float)note_tempo) / 100);
300 } 320 }
301 321
302 if (!audio_config.enable) { 322 note_position = 0;
303 playing_notes = false; 323 }
304 playing_note = false; 324 }
305 } 325
326 if (!audio_config.enable) {
327 playing_notes = false;
328 playing_note = false;
329 }
306} 330}
307 331
308void play_note(float freq, int vol) { 332void play_note(float freq, int vol) {
309 333
334 dprintf("audio play note freq=%d vol=%d", (int)freq, vol);
335
310 if (!audio_initialized) { 336 if (!audio_initialized) {
311 audio_init(); 337 audio_init();
312 } 338 }
313 339
314 if (audio_config.enable && voices < 8) { 340 if (audio_config.enable && voices < 8) {
315 DISABLE_AUDIO_COUNTER_3_ISR; 341 DISABLE_AUDIO_COUNTER_3_ISR;
316 342
317 // Cancel notes if notes are playing 343 // Cancel notes if notes are playing
318 if (playing_notes) 344 if (playing_notes)
319 stop_all_notes(); 345 stop_all_notes();
320 346
321 playing_note = true; 347 playing_note = true;
322 348
323 envelope_index = 0; 349 envelope_index = 0;
324 350
325 if (freq > 0) { 351 if (freq > 0) {
326 frequencies[voices] = freq; 352 frequencies[voices] = freq;
327 volumes[voices] = vol; 353 volumes[voices] = vol;
328 voices++; 354 voices++;
329 } 355 }
330 356
331 ENABLE_AUDIO_COUNTER_3_ISR; 357 ENABLE_AUDIO_COUNTER_3_ISR;
332 ENABLE_AUDIO_COUNTER_3_OUTPUT; 358 ENABLE_AUDIO_COUNTER_3_OUTPUT;
333 } 359 }
334 360
335} 361}
336 362
@@ -341,37 +367,37 @@ void play_notes(float (*np)[][2], uint16_t n_count, bool n_repeat, float n_rest)
341 audio_init(); 367 audio_init();
342 } 368 }
343 369
344 if (audio_config.enable) { 370 if (audio_config.enable) {
345 371
346 DISABLE_AUDIO_COUNTER_3_ISR; 372 DISABLE_AUDIO_COUNTER_3_ISR;
347 373
348 // Cancel note if a note is playing 374 // Cancel note if a note is playing
349 if (playing_note) 375 if (playing_note)
350 stop_all_notes(); 376 stop_all_notes();
351 377
352 playing_notes = true; 378 playing_notes = true;
353 379
354 notes_pointer = np; 380 notes_pointer = np;
355 notes_count = n_count; 381 notes_count = n_count;
356 notes_repeat = n_repeat; 382 notes_repeat = n_repeat;
357 notes_rest = n_rest; 383 notes_rest = n_rest;
358 384
359 place = 0; 385 place = 0;
360 current_note = 0; 386 current_note = 0;
361 387
362 note_frequency = (*notes_pointer)[current_note][0]; 388 note_frequency = (*notes_pointer)[current_note][0];
363 note_length = ((*notes_pointer)[current_note][1] / 4) * (((float)note_tempo) / 100); 389 note_length = ((*notes_pointer)[current_note][1] / 4) * (((float)note_tempo) / 100);
364 note_position = 0; 390 note_position = 0;
365 391
366 392
367 ENABLE_AUDIO_COUNTER_3_ISR; 393 ENABLE_AUDIO_COUNTER_3_ISR;
368 ENABLE_AUDIO_COUNTER_3_OUTPUT; 394 ENABLE_AUDIO_COUNTER_3_OUTPUT;
369 } 395 }
370 396
371} 397}
372 398
373bool is_playing_notes(void) { 399bool is_playing_notes(void) {
374 return playing_notes; 400 return playing_notes;
375} 401}
376 402
377bool is_audio_on(void) { 403bool is_audio_on(void) {
diff --git a/quantum/audio/audio.h b/quantum/audio/audio.h
index 47f326ea0..27fdc2ab6 100644
--- a/quantum/audio/audio.h
+++ b/quantum/audio/audio.h
@@ -1,3 +1,18 @@
1/* Copyright 2016 Jack Humbert
2 *
3 * This program is free software: you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation, either version 2 of the License, or
6 * (at your option) any later version.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
1#ifndef AUDIO_H 16#ifndef AUDIO_H
2#define AUDIO_H 17#define AUDIO_H
3 18
@@ -88,4 +103,4 @@ void play_notes(float (*np)[][2], uint16_t n_count, bool n_repeat, float n_rest)
88 103
89bool is_playing_notes(void); 104bool is_playing_notes(void);
90 105
91#endif \ No newline at end of file 106#endif
diff --git a/quantum/audio/audio_pwm.c b/quantum/audio/audio_pwm.c
index f820eec1b..ded86edee 100644
--- a/quantum/audio/audio_pwm.c
+++ b/quantum/audio/audio_pwm.c
@@ -1,3 +1,18 @@
1/* Copyright 2016 Jack Humbert
2 *
3 * This program is free software: you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation, either version 2 of the License, or
6 * (at your option) any later version.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
1#include <stdio.h> 16#include <stdio.h>
2#include <string.h> 17#include <string.h>
3//#include <math.h> 18//#include <math.h>
diff --git a/quantum/audio/luts.c b/quantum/audio/luts.c
index 9f3de9a05..57f2d5924 100644
--- a/quantum/audio/luts.c
+++ b/quantum/audio/luts.c
@@ -1,3 +1,19 @@
1/* Copyright 2016 IBNobody
2 *
3 * This program is free software: you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation, either version 2 of the License, or
6 * (at your option) any later version.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
1#include <avr/io.h> 17#include <avr/io.h>
2#include <avr/interrupt.h> 18#include <avr/interrupt.h>
3#include <avr/pgmspace.h> 19#include <avr/pgmspace.h>
diff --git a/quantum/audio/luts.h b/quantum/audio/luts.h
index 7df3078a7..155e34e88 100644
--- a/quantum/audio/luts.h
+++ b/quantum/audio/luts.h
@@ -1,3 +1,19 @@
1/* Copyright 2016 IBNobody
2 *
3 * This program is free software: you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation, either version 2 of the License, or
6 * (at your option) any later version.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
1#include <avr/io.h> 17#include <avr/io.h>
2#include <avr/interrupt.h> 18#include <avr/interrupt.h>
3#include <avr/pgmspace.h> 19#include <avr/pgmspace.h>
@@ -12,4 +28,4 @@
12extern const float vibrato_lut[VIBRATO_LUT_LENGTH]; 28extern const float vibrato_lut[VIBRATO_LUT_LENGTH];
13extern const uint16_t frequency_lut[FREQUENCY_LUT_LENGTH]; 29extern const uint16_t frequency_lut[FREQUENCY_LUT_LENGTH];
14 30
15#endif /* LUTS_H */ \ No newline at end of file 31#endif /* LUTS_H */
diff --git a/quantum/audio/musical_notes.h b/quantum/audio/musical_notes.h
index b08d16a6f..a3aaa2f19 100644
--- a/quantum/audio/musical_notes.h
+++ b/quantum/audio/musical_notes.h
@@ -1,3 +1,19 @@
1/* Copyright 2016 Jack Humbert
2 *
3 * This program is free software: you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation, either version 2 of the License, or
6 * (at your option) any later version.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
1#ifndef MUSICAL_NOTES_H 17#ifndef MUSICAL_NOTES_H
2#define MUSICAL_NOTES_H 18#define MUSICAL_NOTES_H
3 19
@@ -214,4 +230,4 @@
214#define NOTE_BF8 NOTE_AS8 230#define NOTE_BF8 NOTE_AS8
215 231
216 232
217#endif \ No newline at end of file 233#endif
diff --git a/quantum/audio/song_list.h b/quantum/audio/song_list.h
index 623f24f32..db2d1a94c 100644
--- a/quantum/audio/song_list.h
+++ b/quantum/audio/song_list.h
@@ -1,3 +1,18 @@
1/* Copyright 2016 Jack Humbert
2 *
3 * This program is free software: you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation, either version 2 of the License, or
6 * (at your option) any later version.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
1#include "musical_notes.h" 16#include "musical_notes.h"
2 17
3#ifndef SONG_LIST_H 18#ifndef SONG_LIST_H
@@ -134,4 +149,31 @@
134 E__NOTE(_E6), \ 149 E__NOTE(_E6), \
135 S__NOTE(_B5), 150 S__NOTE(_B5),
136 151
152#define COIN_SOUND \
153 E__NOTE(_A5 ), \
154 HD_NOTE(_E6 ),
155
156#define ONE_UP_SOUND \
157 Q__NOTE(_E6 ), \
158 Q__NOTE(_G6 ), \
159 Q__NOTE(_E7 ), \
160 Q__NOTE(_C7 ), \
161 Q__NOTE(_D7 ), \
162 Q__NOTE(_G7 ),
163
164#define SONIC_RING \
165 E__NOTE(_E6), \
166 E__NOTE(_G6), \
167 HD_NOTE(_C7),
168
169#define ZELDA_PUZZLE \
170 Q__NOTE(_G5), \
171 Q__NOTE(_FS5), \
172 Q__NOTE(_DS5), \
173 Q__NOTE(_A4), \
174 Q__NOTE(_GS4), \
175 Q__NOTE(_E5), \
176 Q__NOTE(_GS5), \
177 HD_NOTE(_C6),
178
137#endif 179#endif
diff --git a/quantum/audio/voices.c b/quantum/audio/voices.c
index 6d4172a06..54ebd423b 100644
--- a/quantum/audio/voices.c
+++ b/quantum/audio/voices.c
@@ -1,3 +1,18 @@
1/* Copyright 2016 Jack Humbert
2 *
3 * This program is free software: you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation, either version 2 of the License, or
6 * (at your option) any later version.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
1#include "voices.h" 16#include "voices.h"
2#include "audio.h" 17#include "audio.h"
3#include "stdlib.h" 18#include "stdlib.h"
@@ -6,6 +21,7 @@
6extern uint16_t envelope_index; 21extern uint16_t envelope_index;
7extern float note_timbre; 22extern float note_timbre;
8extern float polyphony_rate; 23extern float polyphony_rate;
24extern bool glissando;
9 25
10voice_type voice = default_voice; 26voice_type voice = default_voice;
11 27
@@ -18,20 +34,132 @@ void voice_iterate() {
18} 34}
19 35
20void voice_deiterate() { 36void voice_deiterate() {
21 voice = (voice - 1) % number_of_voices; 37 voice = (voice - 1 + number_of_voices) % number_of_voices;
22} 38}
23 39
24float voice_envelope(float frequency) { 40float voice_envelope(float frequency) {
25 // envelope_index ranges from 0 to 0xFFFF, which is preserved at 880.0 Hz 41 // envelope_index ranges from 0 to 0xFFFF, which is preserved at 880.0 Hz
42 __attribute__ ((unused))
26 uint16_t compensated_index = (uint16_t)((float)envelope_index * (880.0 / frequency)); 43 uint16_t compensated_index = (uint16_t)((float)envelope_index * (880.0 / frequency));
27 44
28 switch (voice) { 45 switch (voice) {
29 case default_voice: 46 case default_voice:
47 glissando = true;
30 note_timbre = TIMBRE_50; 48 note_timbre = TIMBRE_50;
31 polyphony_rate = 0; 49 polyphony_rate = 0;
32 break; 50 break;
33 51
52 #ifdef AUDIO_VOICES
53
54 case something:
55 glissando = false;
56 polyphony_rate = 0;
57 switch (compensated_index) {
58 case 0 ... 9:
59 note_timbre = TIMBRE_12;
60 break;
61
62 case 10 ... 19:
63 note_timbre = TIMBRE_25;
64 break;
65
66 case 20 ... 200:
67 note_timbre = .125 + .125;
68 break;
69
70 default:
71 note_timbre = .125;
72 break;
73 }
74 break;
75
76 case drums:
77 glissando = false;
78 polyphony_rate = 0;
79 // switch (compensated_index) {
80 // case 0 ... 10:
81 // note_timbre = 0.5;
82 // break;
83 // case 11 ... 20:
84 // note_timbre = 0.5 * (21 - compensated_index) / 10;
85 // break;
86 // default:
87 // note_timbre = 0;
88 // break;
89 // }
90 // frequency = (rand() % (int)(frequency * 1.2 - frequency)) + (frequency * 0.8);
91
92 if (frequency < 80.0) {
93
94 } else if (frequency < 160.0) {
95
96 // Bass drum: 60 - 100 Hz
97 frequency = (rand() % (int)(40)) + 60;
98 switch (envelope_index) {
99 case 0 ... 10:
100 note_timbre = 0.5;
101 break;
102 case 11 ... 20:
103 note_timbre = 0.5 * (21 - envelope_index) / 10;
104 break;
105 default:
106 note_timbre = 0;
107 break;
108 }
109
110 } else if (frequency < 320.0) {
111
112
113 // Snare drum: 1 - 2 KHz
114 frequency = (rand() % (int)(1000)) + 1000;
115 switch (envelope_index) {
116 case 0 ... 5:
117 note_timbre = 0.5;
118 break;
119 case 6 ... 20:
120 note_timbre = 0.5 * (21 - envelope_index) / 15;
121 break;
122 default:
123 note_timbre = 0;
124 break;
125 }
126
127 } else if (frequency < 640.0) {
128
129 // Closed Hi-hat: 3 - 5 KHz
130 frequency = (rand() % (int)(2000)) + 3000;
131 switch (envelope_index) {
132 case 0 ... 15:
133 note_timbre = 0.5;
134 break;
135 case 16 ... 20:
136 note_timbre = 0.5 * (21 - envelope_index) / 5;
137 break;
138 default:
139 note_timbre = 0;
140 break;
141 }
142
143 } else if (frequency < 1280.0) {
144
145 // Open Hi-hat: 3 - 5 KHz
146 frequency = (rand() % (int)(2000)) + 3000;
147 switch (envelope_index) {
148 case 0 ... 35:
149 note_timbre = 0.5;
150 break;
151 case 36 ... 50:
152 note_timbre = 0.5 * (51 - envelope_index) / 15;
153 break;
154 default:
155 note_timbre = 0;
156 break;
157 }
158
159 }
160 break;
34 case butts_fader: 161 case butts_fader:
162 glissando = true;
35 polyphony_rate = 0; 163 polyphony_rate = 0;
36 switch (compensated_index) { 164 switch (compensated_index) {
37 case 0 ... 9: 165 case 0 ... 9:
@@ -79,6 +207,7 @@ float voice_envelope(float frequency) {
79 207
80 case duty_osc: 208 case duty_osc:
81 // This slows the loop down a substantial amount, so higher notes may freeze 209 // This slows the loop down a substantial amount, so higher notes may freeze
210 glissando = true;
82 polyphony_rate = 0; 211 polyphony_rate = 0;
83 switch (compensated_index) { 212 switch (compensated_index) {
84 default: 213 default:
@@ -93,6 +222,7 @@ float voice_envelope(float frequency) {
93 break; 222 break;
94 223
95 case duty_octave_down: 224 case duty_octave_down:
225 glissando = true;
96 polyphony_rate = 0; 226 polyphony_rate = 0;
97 note_timbre = (envelope_index % 2) * .125 + .375 * 2; 227 note_timbre = (envelope_index % 2) * .125 + .375 * 2;
98 if ((envelope_index % 4) == 0) 228 if ((envelope_index % 4) == 0)
@@ -101,6 +231,7 @@ float voice_envelope(float frequency) {
101 note_timbre = 0; 231 note_timbre = 0;
102 break; 232 break;
103 case delayed_vibrato: 233 case delayed_vibrato:
234 glissando = true;
104 polyphony_rate = 0; 235 polyphony_rate = 0;
105 note_timbre = TIMBRE_50; 236 note_timbre = TIMBRE_50;
106 #define VOICE_VIBRATO_DELAY 150 237 #define VOICE_VIBRATO_DELAY 150
@@ -155,11 +286,11 @@ float voice_envelope(float frequency) {
155 // note_timbre = 0.25; 286 // note_timbre = 0.25;
156 // break; 287 // break;
157 288
289 #endif
290
158 default: 291 default:
159 break; 292 break;
160 } 293 }
161 294
162 return frequency; 295 return frequency;
163} 296}
164
165
diff --git a/quantum/audio/voices.h b/quantum/audio/voices.h
index b2495b23b..9403a6b5e 100644
--- a/quantum/audio/voices.h
+++ b/quantum/audio/voices.h
@@ -1,3 +1,18 @@
1/* Copyright 2016 Jack Humbert
2 *
3 * This program is free software: you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation, either version 2 of the License, or
6 * (at your option) any later version.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
1#include <stdint.h> 16#include <stdint.h>
2#include <stdbool.h> 17#include <stdbool.h>
3#include <avr/io.h> 18#include <avr/io.h>
@@ -11,6 +26,9 @@ float voice_envelope(float frequency);
11 26
12typedef enum { 27typedef enum {
13 default_voice, 28 default_voice,
29 #ifdef AUDIO_VOICES
30 something,
31 drums,
14 butts_fader, 32 butts_fader,
15 octave_crunch, 33 octave_crunch,
16 duty_osc, 34 duty_osc,
@@ -21,6 +39,7 @@ typedef enum {
21 // duty_fourth_down, 39 // duty_fourth_down,
22 // duty_third_down, 40 // duty_third_down,
23 // duty_fifth_third_down, 41 // duty_fifth_third_down,
42 #endif
24 number_of_voices // important that this is last 43 number_of_voices // important that this is last
25} voice_type; 44} voice_type;
26 45
@@ -28,4 +47,4 @@ void set_voice(voice_type v);
28void voice_iterate(void); 47void voice_iterate(void);
29void voice_deiterate(void); 48void voice_deiterate(void);
30 49
31#endif \ No newline at end of file 50#endif
diff --git a/quantum/audio/wave.h b/quantum/audio/wave.h
index 6ebc34851..f15615dd1 100644
--- a/quantum/audio/wave.h
+++ b/quantum/audio/wave.h
@@ -1,3 +1,19 @@
1/* Copyright 2016 Jack Humbert
2 *
3 * This program is free software: you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation, either version 2 of the License, or
6 * (at your option) any later version.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
1#include <avr/io.h> 17#include <avr/io.h>
2#include <avr/interrupt.h> 18#include <avr/interrupt.h>
3#include <avr/pgmspace.h> 19#include <avr/pgmspace.h>
@@ -262,4 +278,4 @@ const uint8_t sinewave[] PROGMEM= //2048 values
2620x76,0x77,0x77,0x77,0x78,0x78,0x78,0x79, 2780x76,0x77,0x77,0x77,0x78,0x78,0x78,0x79,
2630x79,0x7a,0x7a,0x7a,0x7b,0x7b,0x7c,0x7c, 2790x79,0x7a,0x7a,0x7a,0x7b,0x7b,0x7c,0x7c,
2640x7c,0x7d,0x7d,0x7e,0x7e,0x7e,0x7f,0x7f 2800x7c,0x7d,0x7d,0x7e,0x7e,0x7e,0x7f,0x7f
265}; \ No newline at end of file 281};