diff options
Diffstat (limited to 'quantum')
| -rw-r--r-- | quantum/audio.c | 59 | ||||
| -rw-r--r-- | quantum/audio.h | 7 | ||||
| -rw-r--r-- | quantum/keymap_common.c | 15 | ||||
| -rw-r--r-- | quantum/musical_notes.h | 49 | ||||
| -rw-r--r-- | quantum/song_list.h | 23 |
5 files changed, 118 insertions, 35 deletions
diff --git a/quantum/audio.c b/quantum/audio.c index 6bd6532a3..e0413051a 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,15 +347,16 @@ 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 | ||
| 351 | if (note) | 354 | if (note) |
| 352 | stop_all_notes(); | 355 | stop_all_notes(); |
| 356 | notes = true; | ||
| 353 | 357 | ||
| 354 | notes_pointer = np; | 358 | notes_pointer = np; |
| 355 | notes_length = n_length; | 359 | notes_count = n_count; |
| 356 | notes_repeat = n_repeat; | 360 | notes_repeat = n_repeat; |
| 357 | notes_rest = n_rest; | 361 | notes_rest = n_rest; |
| 358 | 362 | ||
| @@ -360,10 +364,10 @@ if (audio_config.enable) { | |||
| 360 | current_note = 0; | 364 | current_note = 0; |
| 361 | #ifdef PWM_AUDIO | 365 | #ifdef PWM_AUDIO |
| 362 | note_frequency = (*notes_pointer)[current_note][0] / SAMPLE_RATE; | 366 | note_frequency = (*notes_pointer)[current_note][0] / SAMPLE_RATE; |
| 363 | note_length = (*notes_pointer)[current_note][1]; | 367 | note_length = (*notes_pointer)[current_note][1] * (note_tempo / 100); |
| 364 | #else | 368 | #else |
| 365 | note_frequency = (*notes_pointer)[current_note][0]; | 369 | note_frequency = (*notes_pointer)[current_note][0]; |
| 366 | note_length = (*notes_pointer)[current_note][1] / 4; | 370 | note_length = ((*notes_pointer)[current_note][1] / 4) * (note_tempo / 100); |
| 367 | #endif | 371 | #endif |
| 368 | note_position = 0; | 372 | note_position = 0; |
| 369 | 373 | ||
| @@ -375,7 +379,6 @@ if (audio_config.enable) { | |||
| 375 | TCCR3A |= _BV(COM3A1); | 379 | TCCR3A |= _BV(COM3A1); |
| 376 | #endif | 380 | #endif |
| 377 | 381 | ||
| 378 | notes = true; | ||
| 379 | } | 382 | } |
| 380 | 383 | ||
| 381 | } | 384 | } |
| @@ -405,6 +408,7 @@ if (audio_config.enable && voices < 8) { | |||
| 405 | 408 | ||
| 406 | if (notes) | 409 | if (notes) |
| 407 | stop_all_notes(); | 410 | stop_all_notes(); |
| 411 | note = true; | ||
| 408 | #ifdef PWM_AUDIO | 412 | #ifdef PWM_AUDIO |
| 409 | freq = freq / SAMPLE_RATE; | 413 | freq = freq / SAMPLE_RATE; |
| 410 | #endif | 414 | #endif |
| @@ -436,7 +440,34 @@ if (audio_config.enable && voices < 8) { | |||
| 436 | TCCR3A |= _BV(COM3A1); | 440 | TCCR3A |= _BV(COM3A1); |
| 437 | #endif | 441 | #endif |
| 438 | 442 | ||
| 439 | 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..05d314c94 100644 --- a/quantum/audio.h +++ b/quantum/audio.h | |||
| @@ -3,6 +3,7 @@ | |||
| 3 | #include <avr/io.h> | 3 | #include <avr/io.h> |
| 4 | #include <util/delay.h> | 4 | #include <util/delay.h> |
| 5 | #include "musical_notes.h" | 5 | #include "musical_notes.h" |
| 6 | #include "song_list.h" | ||
| 6 | 7 | ||
| 7 | #ifndef AUDIO_H | 8 | #ifndef AUDIO_H |
| 8 | #define AUDIO_H | 9 | #define AUDIO_H |
| @@ -24,8 +25,12 @@ void play_note(double freq, int vol); | |||
| 24 | void stop_note(double freq); | 25 | void stop_note(double freq); |
| 25 | void stop_all_notes(void); | 26 | void stop_all_notes(void); |
| 26 | void init_notes(void); | 27 | void init_notes(void); |
| 27 | void play_notes(float (*np)[][2], uint8_t n_length, bool n_repeat, float n_rest); | 28 | void play_notes(float (*np)[][2], uint8_t n_count, bool n_repeat, float n_rest); |
| 28 | 29 | ||
| 30 | void set_timbre(float timbre); | ||
| 31 | void set_tempo(float tempo); | ||
| 32 | void increase_tempo(uint8_t tempo_change); | ||
| 33 | void decrease_tempo(uint8_t tempo_change); | ||
| 29 | 34 | ||
| 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), \ | 35 | #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), \ | 36 | 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..2001438b9 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 | ||
| @@ -33,15 +34,13 @@ extern keymap_config_t keymap_config; | |||
| 33 | #include <inttypes.h> | 34 | #include <inttypes.h> |
| 34 | #ifdef AUDIO_ENABLE | 35 | #ifdef AUDIO_ENABLE |
| 35 | #include "audio.h" | 36 | #include "audio.h" |
| 37 | |||
| 36 | #ifndef TONE_GOODBYE | 38 | #ifndef TONE_GOODBYE |
| 37 | #define TONE_GOODBYE { \ | 39 | #define TONE_GOODBYE OLKB_GOODBYE |
| 38 | {440.0*pow(2.0,(31)/12.0), 8}, \ | 40 | #endif /*! TONE_GOODBYE */ |
| 39 | {440.0*pow(2.0,(24)/12.0), 8}, \ | 41 | |
| 40 | {440.0*pow(2.0,(19)/12.0), 12}, \ | 42 | float tone_goodbye[][2] = SONG(TONE_GOODBYE); |
| 41 | } | 43 | #endif /* AUDIO_ENABLE */ |
| 42 | #endif | ||
| 43 | float tone_goodbye[][2] = TONE_GOODBYE; | ||
| 44 | #endif | ||
| 45 | 44 | ||
| 46 | static action_t keycode_to_action(uint16_t keycode); | 45 | static action_t keycode_to_action(uint16_t keycode); |
| 47 | 46 | ||
diff --git a/quantum/musical_notes.h b/quantum/musical_notes.h index 837f6a069..ccdc34f27 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) EIGHTH_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..b626c3fa6 --- /dev/null +++ b/quantum/song_list.h | |||
| @@ -0,0 +1,23 @@ | |||
| 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 | #define OLKB_GOODBYE \ | ||
| 19 | E__NOTE(_E7), \ | ||
| 20 | E__NOTE(_A6), \ | ||
| 21 | ED_NOTE(_E6), | ||
| 22 | |||
| 23 | #endif | ||
