diff options
Diffstat (limited to 'quantum')
-rw-r--r-- | quantum/audio.c | 55 | ||||
-rw-r--r-- | quantum/audio.h | 6 | ||||
-rw-r--r-- | quantum/keymap_common.c | 1 | ||||
-rw-r--r-- | quantum/musical_notes.h | 49 | ||||
-rw-r--r-- | quantum/song_list.h | 18 |
5 files changed, 104 insertions, 25 deletions
diff --git a/quantum/audio.c b/quantum/audio.c index 6bd6532a3..3ccd5ab9b 100644 --- a/quantum/audio.c +++ b/quantum/audio.c | |||
@@ -4,7 +4,7 @@ | |||
4 | #include <avr/pgmspace.h> | 4 | #include <avr/pgmspace.h> |
5 | #include <avr/interrupt.h> | 5 | #include <avr/interrupt.h> |
6 | #include <avr/io.h> | 6 | #include <avr/io.h> |
7 | 7 | #include "print.h" | |
8 | #include "audio.h" | 8 | #include "audio.h" |
9 | #include "keymap_common.h" | 9 | #include "keymap_common.h" |
10 | 10 | ||
@@ -57,9 +57,11 @@ bool notes = false; | |||
57 | bool note = false; | 57 | bool note = false; |
58 | float note_frequency = 0; | 58 | float note_frequency = 0; |
59 | float note_length = 0; | 59 | float note_length = 0; |
60 | float note_tempo = TEMPO_DEFAULT; | ||
61 | float note_timbre = TIMBRE_DEFAULT; | ||
60 | uint16_t note_position = 0; | 62 | uint16_t note_position = 0; |
61 | float (* notes_pointer)[][2]; | 63 | float (* notes_pointer)[][2]; |
62 | uint8_t notes_length; | 64 | uint8_t notes_count; |
63 | bool notes_repeat; | 65 | bool notes_repeat; |
64 | float notes_rest; | 66 | float notes_rest; |
65 | bool note_resting = false; | 67 | bool note_resting = false; |
@@ -255,7 +257,8 @@ ISR(TIMER3_COMPA_vect) { | |||
255 | place = 0.0; | 257 | place = 0.0; |
256 | } | 258 | } |
257 | ICR3 = (int)(((double)F_CPU) / (frequencies[voice_place] * CPU_PRESCALER)); // Set max to the period | 259 | ICR3 = (int)(((double)F_CPU) / (frequencies[voice_place] * CPU_PRESCALER)); // Set max to the period |
258 | OCR3A = (int)(((double)F_CPU) / (frequencies[voice_place] * CPU_PRESCALER)) >> 1 * duty_place; // Set compare to half the period | 260 | OCR3A = (int)((((double)F_CPU) /(frequencies[voice_place] * CPU_PRESCALER)) * note_timbre); // Set compare to half the period |
261 | //OCR3A = (int)(((double)F_CPU) / (frequencies[voice_place] * CPU_PRESCALER)) >> 1 * duty_place; // Set compare to half the period | ||
259 | place++; | 262 | place++; |
260 | // if (duty_counter > (frequencies[voice_place] / 500)) { | 263 | // if (duty_counter > (frequencies[voice_place] / 500)) { |
261 | // duty_place = (duty_place % 3) + 1; | 264 | // duty_place = (duty_place % 3) + 1; |
@@ -288,7 +291,7 @@ ISR(TIMER3_COMPA_vect) { | |||
288 | #else | 291 | #else |
289 | if (note_frequency > 0) { | 292 | if (note_frequency > 0) { |
290 | ICR3 = (int)(((double)F_CPU) / (note_frequency * CPU_PRESCALER)); // Set max to the period | 293 | ICR3 = (int)(((double)F_CPU) / (note_frequency * CPU_PRESCALER)); // Set max to the period |
291 | OCR3A = (int)(((double)F_CPU) / (note_frequency * CPU_PRESCALER)) >> 1; // Set compare to half the period | 294 | OCR3A = (int)((((double)F_CPU) / (note_frequency * CPU_PRESCALER)) * note_timbre); // Set compare to half the period |
292 | } else { | 295 | } else { |
293 | ICR3 = 0; | 296 | ICR3 = 0; |
294 | OCR3A = 0; | 297 | OCR3A = 0; |
@@ -304,7 +307,7 @@ ISR(TIMER3_COMPA_vect) { | |||
304 | end_of_note = (note_position >= (note_length * 0x7FF)); | 307 | end_of_note = (note_position >= (note_length * 0x7FF)); |
305 | if (end_of_note) { | 308 | if (end_of_note) { |
306 | current_note++; | 309 | current_note++; |
307 | if (current_note >= notes_length) { | 310 | if (current_note >= notes_count) { |
308 | if (notes_repeat) { | 311 | if (notes_repeat) { |
309 | current_note = 0; | 312 | current_note = 0; |
310 | } else { | 313 | } else { |
@@ -327,10 +330,10 @@ ISR(TIMER3_COMPA_vect) { | |||
327 | note_resting = false; | 330 | note_resting = false; |
328 | #ifdef PWM_AUDIO | 331 | #ifdef PWM_AUDIO |
329 | note_frequency = (*notes_pointer)[current_note][0] / SAMPLE_RATE; | 332 | note_frequency = (*notes_pointer)[current_note][0] / SAMPLE_RATE; |
330 | note_length = (*notes_pointer)[current_note][1]; | 333 | note_length = (*notes_pointer)[current_note][1] * (note_tempo / 100); |
331 | #else | 334 | #else |
332 | note_frequency = (*notes_pointer)[current_note][0]; | 335 | note_frequency = (*notes_pointer)[current_note][0]; |
333 | note_length = (*notes_pointer)[current_note][1] / 4; | 336 | note_length = ((*notes_pointer)[current_note][1] / 4) * (note_tempo / 100); |
334 | #endif | 337 | #endif |
335 | } | 338 | } |
336 | note_position = 0; | 339 | note_position = 0; |
@@ -344,7 +347,7 @@ ISR(TIMER3_COMPA_vect) { | |||
344 | } | 347 | } |
345 | } | 348 | } |
346 | 349 | ||
347 | void play_notes(float (*np)[][2], uint8_t n_length, bool n_repeat, float n_rest) { | 350 | void play_notes(float (*np)[][2], uint8_t n_count, bool n_repeat, float n_rest) { |
348 | 351 | ||
349 | if (audio_config.enable) { | 352 | if (audio_config.enable) { |
350 | 353 | ||
@@ -352,7 +355,7 @@ if (audio_config.enable) { | |||
352 | stop_all_notes(); | 355 | stop_all_notes(); |
353 | 356 | ||
354 | notes_pointer = np; | 357 | notes_pointer = np; |
355 | notes_length = n_length; | 358 | notes_count = n_count; |
356 | notes_repeat = n_repeat; | 359 | notes_repeat = n_repeat; |
357 | notes_rest = n_rest; | 360 | notes_rest = n_rest; |
358 | 361 | ||
@@ -360,10 +363,10 @@ if (audio_config.enable) { | |||
360 | current_note = 0; | 363 | current_note = 0; |
361 | #ifdef PWM_AUDIO | 364 | #ifdef PWM_AUDIO |
362 | note_frequency = (*notes_pointer)[current_note][0] / SAMPLE_RATE; | 365 | note_frequency = (*notes_pointer)[current_note][0] / SAMPLE_RATE; |
363 | note_length = (*notes_pointer)[current_note][1]; | 366 | note_length = (*notes_pointer)[current_note][1] * (note_tempo / 100); |
364 | #else | 367 | #else |
365 | note_frequency = (*notes_pointer)[current_note][0]; | 368 | note_frequency = (*notes_pointer)[current_note][0]; |
366 | note_length = (*notes_pointer)[current_note][1] / 4; | 369 | note_length = ((*notes_pointer)[current_note][1] / 4) * (note_tempo / 100); |
367 | #endif | 370 | #endif |
368 | note_position = 0; | 371 | note_position = 0; |
369 | 372 | ||
@@ -439,4 +442,32 @@ if (audio_config.enable && voices < 8) { | |||
439 | note = true; | 442 | note = true; |
440 | } | 443 | } |
441 | 444 | ||
442 | } \ No newline at end of file | 445 | } |
446 | |||
447 | void set_timbre(float timbre) | ||
448 | { | ||
449 | note_timbre = timbre; | ||
450 | } | ||
451 | |||
452 | void set_tempo(float tempo) | ||
453 | { | ||
454 | note_tempo = tempo; | ||
455 | } | ||
456 | |||
457 | void decrease_tempo(uint8_t tempo_change) | ||
458 | { | ||
459 | note_tempo += (float) tempo_change; | ||
460 | } | ||
461 | |||
462 | void increase_tempo(uint8_t tempo_change) | ||
463 | { | ||
464 | if (note_tempo - (float) tempo_change < 10) | ||
465 | { | ||
466 | note_tempo = 10; | ||
467 | } | ||
468 | else | ||
469 | { | ||
470 | note_tempo -= (float) tempo_change; | ||
471 | } | ||
472 | } | ||
473 | |||
diff --git a/quantum/audio.h b/quantum/audio.h index e1bc23ffe..3aba8370a 100644 --- a/quantum/audio.h +++ b/quantum/audio.h | |||
@@ -24,8 +24,12 @@ void play_note(double freq, int vol); | |||
24 | void stop_note(double freq); | 24 | void stop_note(double freq); |
25 | void stop_all_notes(void); | 25 | void stop_all_notes(void); |
26 | void init_notes(void); | 26 | void init_notes(void); |
27 | void play_notes(float (*np)[][2], uint8_t n_length, bool n_repeat, float n_rest); | 27 | void play_notes(float (*np)[][2], uint8_t n_count, bool n_repeat, float n_rest); |
28 | 28 | ||
29 | void set_timbre(float timbre); | ||
30 | void set_tempo(float tempo); | ||
31 | void increase_tempo(uint8_t tempo_change); | ||
32 | void decrease_tempo(uint8_t tempo_change); | ||
29 | 33 | ||
30 | #define SCALE (int []){ 0 + (12*0), 2 + (12*0), 4 + (12*0), 5 + (12*0), 7 + (12*0), 9 + (12*0), 11 + (12*0), \ | 34 | #define SCALE (int []){ 0 + (12*0), 2 + (12*0), 4 + (12*0), 5 + (12*0), 7 + (12*0), 9 + (12*0), 11 + (12*0), \ |
31 | 0 + (12*1), 2 + (12*1), 4 + (12*1), 5 + (12*1), 7 + (12*1), 9 + (12*1), 11 + (12*1), \ | 35 | 0 + (12*1), 2 + (12*1), 4 + (12*1), 5 + (12*1), 7 + (12*1), 9 + (12*1), 11 + (12*1), \ |
diff --git a/quantum/keymap_common.c b/quantum/keymap_common.c index d38e6fdb2..c705b7a73 100644 --- a/quantum/keymap_common.c +++ b/quantum/keymap_common.c | |||
@@ -26,6 +26,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. | |||
26 | #include "backlight.h" | 26 | #include "backlight.h" |
27 | #include "keymap_midi.h" | 27 | #include "keymap_midi.h" |
28 | #include "bootloader.h" | 28 | #include "bootloader.h" |
29 | #include "eeconfig.h" | ||
29 | 30 | ||
30 | extern keymap_config_t keymap_config; | 31 | extern keymap_config_t keymap_config; |
31 | 32 | ||
diff --git a/quantum/musical_notes.h b/quantum/musical_notes.h index 837f6a069..2170f3f18 100644 --- a/quantum/musical_notes.h +++ b/quantum/musical_notes.h | |||
@@ -2,22 +2,38 @@ | |||
2 | #define MUSICAL_NOTES_H | 2 | #define MUSICAL_NOTES_H |
3 | 3 | ||
4 | // Tempo Placeholder | 4 | // Tempo Placeholder |
5 | #define TEMPO 120 | 5 | #define TEMPO_DEFAULT 100 |
6 | |||
7 | |||
8 | #define SONG(notes...) { notes } | ||
6 | 9 | ||
7 | 10 | ||
8 | // Note Types | 11 | // Note Types |
9 | #define WHOLE_NOTE(note) {(NOTE##note), 64} | 12 | #define MUSICAL_NOTE(note, duration) {(NOTE##note), duration} |
10 | #define HALF_NOTE(note) {(NOTE##note), 32} | 13 | #define WHOLE_NOTE(note) MUSICAL_NOTE(note, 64) |
11 | #define QUARTER_NOTE(note) {(NOTE##note), 16} | 14 | #define HALF_NOTE(note) MUSICAL_NOTE(note, 32) |
12 | #define EIGHTH_NOTE(note) {(NOTE##note), 8} | 15 | #define QUARTER_NOTE(note) MUSICAL_NOTE(note, 16) |
13 | #define SIXTEENTH_NOTE(note) {(NOTE##note), 4} | 16 | #define EIGHTH_NOTE(note) MUSICAL_NOTE(note, 8) |
17 | #define SIXTEENTH_NOTE(note) MUSICAL_NOTE(note, 4) | ||
18 | |||
19 | #define WHOLE_DOT_NOTE(note) MUSICAL_NOTE(note, 64+32) | ||
20 | #define HALF_DOT_NOTE(note) MUSICAL_NOTE(note, 32+16) | ||
21 | #define QUARTER_DOT_NOTE(note) MUSICAL_NOTE(note, 16+8) | ||
22 | #define EIGHTH_DOT_NOTE(note) MUSICAL_NOTE(note, 8+4) | ||
23 | #define SIXTEENTH_DOT_NOTE(note) MUSICAL_NOTE(note, 4+2) | ||
14 | 24 | ||
15 | // Note Types Short | 25 | // Note Type Shortcuts |
16 | #define W_NOTE(n) WHOLE_NOTE(n) | 26 | #define M__NOTE(note, duration) MUSICAL_NOTE(note, duration) |
17 | #define H_NOTE(n) HALF_NOTE(n) | 27 | #define W__NOTE(n) WHOLE_NOTE(n) |
18 | #define Q_NOTE(n) QUARTER_NOTE(n) | 28 | #define H__NOTE(n) HALF_NOTE(n) |
19 | #define E_NOTE(n) EIGTH_NOTE(n) | 29 | #define Q__NOTE(n) QUARTER_NOTE(n) |
20 | #define S_NOTE(n) SIXTEENTH_NOTE(n) | 30 | #define E__NOTE(n) EIGHTH_NOTE(n) |
31 | #define S__NOTE(n) SIXTEENTH_NOTE(n) | ||
32 | #define WD_NOTE(n) WHOLE_DOT_NOTE(n) | ||
33 | #define HD_NOTE(n) HALF_DOT_NOTE(n) | ||
34 | #define QD_NOTE(n) QUARTER_DOT_NOTE(n) | ||
35 | #define ED_NOTE(n) EIGTH_DOT_NOTE(n) | ||
36 | #define SD_NOTE(n) SIXTEENTH_DOT_NOTE(n) | ||
21 | 37 | ||
22 | // Note Styles | 38 | // Note Styles |
23 | // Staccato makes sure there is a rest between each note. Think: TA TA TA | 39 | // Staccato makes sure there is a rest between each note. Think: TA TA TA |
@@ -25,6 +41,15 @@ | |||
25 | #define STACCATO 0.01 | 41 | #define STACCATO 0.01 |
26 | #define LEGATO 0 | 42 | #define LEGATO 0 |
27 | 43 | ||
44 | // Note Timbre | ||
45 | // Changes how the notes sound | ||
46 | #define TIMBRE_12 0.125 | ||
47 | #define TIMBRE_25 0.250 | ||
48 | #define TIMBRE_50 0.500 | ||
49 | #define TIMBRE_75 0.750 | ||
50 | #define TIMBRE_DEFAULT TIMBRE_50 | ||
51 | |||
52 | |||
28 | // Notes - # = Octave | 53 | // Notes - # = Octave |
29 | #define NOTE_REST 0.00 | 54 | #define NOTE_REST 0.00 |
30 | #define NOTE_C0 16.35 | 55 | #define NOTE_C0 16.35 |
diff --git a/quantum/song_list.h b/quantum/song_list.h new file mode 100644 index 000000000..ef36a1cdd --- /dev/null +++ b/quantum/song_list.h | |||
@@ -0,0 +1,18 @@ | |||
1 | #include "musical_notes.h" | ||
2 | |||
3 | #ifndef SONG_LIST_H | ||
4 | #define SONG_LIST_H | ||
5 | |||
6 | #define ODE_TO_JOY \ | ||
7 | Q__NOTE(_E4), Q__NOTE(_E4), Q__NOTE(_F4), Q__NOTE(_G4), \ | ||
8 | Q__NOTE(_G4), Q__NOTE(_F4), Q__NOTE(_E4), Q__NOTE(_D4), \ | ||
9 | Q__NOTE(_C4), Q__NOTE(_C4), Q__NOTE(_D4), Q__NOTE(_E4), \ | ||
10 | QD_NOTE(_E4), E__NOTE(_D4), H__NOTE(_D4), | ||
11 | |||
12 | #define ROCK_A_BYE_BABY \ | ||
13 | QD_NOTE(_B4), E__NOTE(_D4), Q__NOTE(_B5), \ | ||
14 | H__NOTE(_A5), Q__NOTE(_G5), \ | ||
15 | QD_NOTE(_B4), E__NOTE(_D5), Q__NOTE(_G5), \ | ||
16 | H__NOTE(_FS5), | ||
17 | |||
18 | #endif \ No newline at end of file | ||