From 5c98ad59606ee95b82c27bf2525383a9ec88542b Mon Sep 17 00:00:00 2001 From: IBNobody Date: Sun, 17 Apr 2016 20:14:37 -0500 Subject: Added extra songs, LED indicator notes --- quantum/audio.c | 17 +++++++- quantum/audio.h | 2 + quantum/keymap_common.c | 14 ++----- quantum/musical_notes.h | 5 +++ quantum/song_list.h | 104 ++++++++++++++++++++++++++++++++++++++++++------ 5 files changed, 117 insertions(+), 25 deletions(-) (limited to 'quantum') diff --git a/quantum/audio.c b/quantum/audio.c index 3ccd5ab9b..602366973 100644 --- a/quantum/audio.c +++ b/quantum/audio.c @@ -351,7 +351,7 @@ void play_notes(float (*np)[][2], uint8_t n_count, bool n_repeat, float n_rest) if (audio_config.enable) { - if (note) + if (note || notes) stop_all_notes(); notes_pointer = np; @@ -406,7 +406,7 @@ void play_note(double freq, int vol) { if (audio_config.enable && voices < 8) { - if (notes) + if (note || notes) stop_all_notes(); #ifdef PWM_AUDIO freq = freq / SAMPLE_RATE; @@ -471,3 +471,16 @@ void increase_tempo(uint8_t tempo_change) } } +//------------------------------------------------------------------------------ +// Override these functions in your keymap file to play different tunes on +// startup and bootloader jump +__attribute__ ((weak)) +void play_startup_tone() +{ +} + +__attribute__ ((weak)) +void play_goodbye_tone() +{ +} +//------------------------------------------------------------------------------ diff --git a/quantum/audio.h b/quantum/audio.h index 05d314c94..44cafccd6 100644 --- a/quantum/audio.h +++ b/quantum/audio.h @@ -44,5 +44,7 @@ void decrease_tempo(uint8_t tempo_change); #define NOTE_ARRAY_SIZE(x) ((int)(sizeof(x) / (sizeof(x[0])))) #define PLAY_NOTE_ARRAY(note_array, note_repeat, note_rest_style) play_notes(¬e_array, NOTE_ARRAY_SIZE((note_array)), (note_repeat), (note_rest_style)); +void play_goodbye_tone(void); +void play_startup_tone(void); #endif \ No newline at end of file diff --git a/quantum/keymap_common.c b/quantum/keymap_common.c index 2001438b9..4ee290ad0 100644 --- a/quantum/keymap_common.c +++ b/quantum/keymap_common.c @@ -34,12 +34,6 @@ extern keymap_config_t keymap_config; #include #ifdef AUDIO_ENABLE #include "audio.h" - - #ifndef TONE_GOODBYE - #define TONE_GOODBYE OLKB_GOODBYE - #endif /*! TONE_GOODBYE */ - - float tone_goodbye[][2] = SONG(TONE_GOODBYE); #endif /* AUDIO_ENABLE */ static action_t keycode_to_action(uint16_t keycode); @@ -47,7 +41,7 @@ static action_t keycode_to_action(uint16_t keycode); /* converts key to action */ action_t action_for_key(uint8_t layer, keypos_t key) { - // 16bit keycodes - important + // 16bit keycodes - important uint16_t keycode = keymap_key_to_keycode(layer, key); switch (keycode) { @@ -190,7 +184,7 @@ static action_t keycode_to_action(uint16_t keycode) case RESET: ; // RESET is 0x5000, which is why this is here clear_keyboard(); #ifdef AUDIO_ENABLE - PLAY_NOTE_ARRAY(tone_goodbye, false, 0); + play_goodbye_tone(); #endif _delay_ms(250); #ifdef ATREUS_ASTAR @@ -303,7 +297,7 @@ static action_t keycode_to_action(uint16_t keycode) /* translates key to keycode */ uint16_t keymap_key_to_keycode(uint8_t layer, keypos_t key) { - // Read entire word (16bits) + // Read entire word (16bits) return pgm_read_word(&keymaps[(layer)][(key.row)][(key.col)]); } @@ -315,7 +309,7 @@ action_t keymap_fn_to_action(uint16_t keycode) action_t keymap_func_to_action(uint16_t keycode) { - // For FUNC without 8bit limit + // For FUNC without 8bit limit return (action_t){ .code = pgm_read_word(&fn_actions[(int)keycode]) }; } diff --git a/quantum/musical_notes.h b/quantum/musical_notes.h index ccdc34f27..b08d16a6f 100644 --- a/quantum/musical_notes.h +++ b/quantum/musical_notes.h @@ -51,7 +51,10 @@ // Notes - # = Octave + #define NOTE_REST 0.00 + +/* These notes are currently bugged #define NOTE_C0 16.35 #define NOTE_CS0 17.32 #define NOTE_D0 18.35 @@ -75,6 +78,8 @@ #define NOTE_GS1 51.91 #define NOTE_A1 55.00 #define NOTE_AS1 58.27 +*/ + #define NOTE_B1 61.74 #define NOTE_C2 65.41 #define NOTE_CS2 69.30 diff --git a/quantum/song_list.h b/quantum/song_list.h index b626c3fa6..e992bd18a 100644 --- a/quantum/song_list.h +++ b/quantum/song_list.h @@ -4,20 +4,98 @@ #define SONG_LIST_H #define ODE_TO_JOY \ - Q__NOTE(_E4), Q__NOTE(_E4), Q__NOTE(_F4), Q__NOTE(_G4), \ - Q__NOTE(_G4), Q__NOTE(_F4), Q__NOTE(_E4), Q__NOTE(_D4), \ - Q__NOTE(_C4), Q__NOTE(_C4), Q__NOTE(_D4), Q__NOTE(_E4), \ - QD_NOTE(_E4), E__NOTE(_D4), H__NOTE(_D4), + Q__NOTE(_E4), Q__NOTE(_E4), Q__NOTE(_F4), Q__NOTE(_G4), \ + Q__NOTE(_G4), Q__NOTE(_F4), Q__NOTE(_E4), Q__NOTE(_D4), \ + Q__NOTE(_C4), Q__NOTE(_C4), Q__NOTE(_D4), Q__NOTE(_E4), \ + QD_NOTE(_E4), E__NOTE(_D4), H__NOTE(_D4), #define ROCK_A_BYE_BABY \ - QD_NOTE(_B4), E__NOTE(_D4), Q__NOTE(_B5), \ - H__NOTE(_A5), Q__NOTE(_G5), \ - QD_NOTE(_B4), E__NOTE(_D5), Q__NOTE(_G5), \ - H__NOTE(_FS5), - -#define OLKB_GOODBYE \ - E__NOTE(_E7), \ - E__NOTE(_A6), \ - ED_NOTE(_E6), + QD_NOTE(_B4), E__NOTE(_D4), Q__NOTE(_B5), \ + H__NOTE(_A5), Q__NOTE(_G5), \ + QD_NOTE(_B4), E__NOTE(_D5), Q__NOTE(_G5), \ + H__NOTE(_FS5), + +#define CLOSE_ENCOUNTERS_5_NOTE \ + Q__NOTE(_D5), \ + Q__NOTE(_E5), \ + Q__NOTE(_C5), \ + Q__NOTE(_C4), \ + Q__NOTE(_G4), + +#define DOE_A_DEER \ + QD_NOTE(_C4), E__NOTE(_D4), \ + QD_NOTE(_E4), E__NOTE(_C4), \ + Q__NOTE(_E4), Q__NOTE(_C4), \ + Q__NOTE(_E4), + +#define GOODBYE_SOUND \ + E__NOTE(_E7), \ + E__NOTE(_A6), \ + ED_NOTE(_E6), + +#define STARTUP_SOUND \ + ED_NOTE(_E7 ), \ + E__NOTE(_CS7), \ + E__NOTE(_E6 ), \ + E__NOTE(_A6 ), \ + M__NOTE(_CS7, 20), + +#define QWERTY_SOUND \ + E__NOTE(_GS6 ), \ + E__NOTE(_A6 ), \ + S__NOTE(_REST), \ + Q__NOTE(_E7 ), + +#define COLEMAK_SOUND \ + E__NOTE(_GS6 ), \ + E__NOTE(_A6 ), \ + S__NOTE(_REST), \ + ED_NOTE(_E7 ), \ + S__NOTE(_REST), \ + ED_NOTE(_GS7 ), + +#define DVORAK_SOUND \ + E__NOTE(_GS6 ), \ + E__NOTE(_A6 ), \ + S__NOTE(_REST), \ + E__NOTE(_E7 ), \ + S__NOTE(_REST), \ + E__NOTE(_FS7 ), \ + S__NOTE(_REST), \ + E__NOTE(_E7 ), + +#define MUSIC_SCALE_SOUND \ + E__NOTE(_A5 ), \ + E__NOTE(_B5 ), \ + E__NOTE(_CS6), \ + E__NOTE(_D6 ), \ + E__NOTE(_E6 ), \ + E__NOTE(_FS6), \ + E__NOTE(_GS6), \ + E__NOTE(_A6 ), + +#define CAPS_LOCK_ON_SOUND \ + E__NOTE(_A3), \ + E__NOTE(_B3), + +#define CAPS_LOCK_OFF_SOUND \ + E__NOTE(_B3), \ + E__NOTE(_A3), + +#define SCROLL_LOCK_ON_SOUND \ + E__NOTE(_D4), \ + E__NOTE(_E4), + +#define SCROLL_LOCK_OFF_SOUND \ + E__NOTE(_E4), \ + E__NOTE(_D4), + +#define NUM_LOCK_ON_SOUND \ + E__NOTE(_D5), \ + E__NOTE(_E5), + +#define NUM_LOCK_OFF_SOUND \ + E__NOTE(_E5), \ + E__NOTE(_D5), #endif -- cgit v1.2.3-24-g4f1b From 89a78f4a11a8f04777b3407c958dc989b4d7d884 Mon Sep 17 00:00:00 2001 From: Jack Humbert Date: Sun, 17 Apr 2016 21:26:06 -0400 Subject: audio fixes --- quantum/audio.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'quantum') diff --git a/quantum/audio.c b/quantum/audio.c index 5805da46c..69c58ca6c 100644 --- a/quantum/audio.c +++ b/quantum/audio.c @@ -351,7 +351,7 @@ void play_notes(float (*np)[][2], uint8_t n_count, bool n_repeat, float n_rest) if (audio_config.enable) { - if (note || notes) + if (note) stop_all_notes(); notes = true; @@ -406,7 +406,7 @@ void play_note(double freq, int vol) { if (audio_config.enable && voices < 8) { - if (note || notes) + if (notes) stop_all_notes(); note = true; #ifdef PWM_AUDIO -- cgit v1.2.3-24-g4f1b From ef73ab662812232f5e73c8098a059439dcb201fa Mon Sep 17 00:00:00 2001 From: IBNobody Date: Sun, 17 Apr 2016 22:08:05 -0500 Subject: Notes Bugfix --- quantum/audio.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'quantum') diff --git a/quantum/audio.c b/quantum/audio.c index 602366973..ba85e418e 100644 --- a/quantum/audio.c +++ b/quantum/audio.c @@ -351,7 +351,8 @@ void play_notes(float (*np)[][2], uint8_t n_count, bool n_repeat, float n_rest) if (audio_config.enable) { - if (note || notes) + // Cancel note if a note is playing + if (note) stop_all_notes(); notes_pointer = np; @@ -406,7 +407,8 @@ void play_note(double freq, int vol) { if (audio_config.enable && voices < 8) { - if (note || notes) + // Cancel notes if notes are playing + if (notes) stop_all_notes(); #ifdef PWM_AUDIO freq = freq / SAMPLE_RATE; -- cgit v1.2.3-24-g4f1b From e49712b5593b887c8af18aeb7196513f1c7b7bcf Mon Sep 17 00:00:00 2001 From: Jack Humbert Date: Mon, 18 Apr 2016 21:01:48 -0400 Subject: note sliding - on right now --- quantum/audio.c | 81 +++++++++++++++++++++++-------------------------- quantum/keymap_common.c | 1 + 2 files changed, 39 insertions(+), 43 deletions(-) (limited to 'quantum') diff --git a/quantum/audio.c b/quantum/audio.c index 69c58ca6c..6a5d43013 100644 --- a/quantum/audio.c +++ b/quantum/audio.c @@ -65,6 +65,7 @@ uint8_t notes_count; bool notes_repeat; float notes_rest; bool note_resting = false; +int note_flipper = 0; uint8_t current_note = 0; uint8_t rest_counter = 0; @@ -127,6 +128,9 @@ void stop_note(double freq) { voices--; if (voices < 0) voices = 0; + if (voice_place >= voices) { + voice_place = 0; + } if (voices == 0) { #ifdef PWM_AUDIO TIMSK3 &= ~_BV(OCIE3A); @@ -137,25 +141,6 @@ void stop_note(double freq) { frequency = 0; volume = 0; note = false; - } else { - double freq = frequencies[voices - 1]; - int vol = volumes[voices - 1]; - double starting_f = frequency; - if (frequency < freq) { - sliding = true; - for (double f = starting_f; f <= freq; f += ((freq - starting_f) / 2000.0)) { - frequency = f; - } - sliding = false; - } else if (frequency > freq) { - sliding = true; - for (double f = starting_f; f >= freq; f -= ((starting_f - freq) / 2000.0)) { - frequency = f; - } - sliding = false; - } - frequency = freq; - volume = vol; } } } @@ -248,16 +233,41 @@ ISR(TIMER3_COMPA_vect) { OCR4A = sum; } #else - if (frequency > 0) { + if (frequencies[voice_place] > 0) { + // if (frequencies[voice_place] > 880.0) { + // if (note_flipper == 100) { + // note_flipper = 0; + // return; + // } + // note_flipper++; + // } else { + // note_flipper = 0; + // } // ICR3 = (int)(((double)F_CPU) / frequency); // Set max to the period // OCR3A = (int)(((double)F_CPU) / frequency) >> 1; // Set compare to half the period - voice_place %= voices; - if (place > (frequencies[voice_place] / 50)) { - voice_place = (voice_place + 1) % voices; - place = 0.0; + + double freq; + if (false) { + voice_place %= voices; + if (place > (frequencies[voice_place] / 50)) { + voice_place = (voice_place + 1) % voices; + place = 0.0; + } + freq = frequencies[voice_place]; + } else { + if (frequency != 0) { + if (frequency < frequencies[voices - 1]) { + frequency = frequency * 1.01454533494; + } else if (frequency > frequencies[voices - 1]) { + frequency = frequency * 0.98566319864; + } + } else { + frequency = frequencies[voices - 1]; + } + freq = frequency; } - ICR3 = (int)(((double)F_CPU) / (frequencies[voice_place] * CPU_PRESCALER)); // Set max to the period - OCR3A = (int)((((double)F_CPU) / (frequencies[voice_place] * CPU_PRESCALER)) * note_timbre); // Set compare to half the period + ICR3 = (int)(((double)F_CPU) / (freq * CPU_PRESCALER)); // Set max to the period + OCR3A = (int)((((double)F_CPU) / (freq * CPU_PRESCALER)) * note_timbre); // Set compare to half the period //OCR3A = (int)(((double)F_CPU) / (frequencies[voice_place] * CPU_PRESCALER)) >> 1 * duty_place; // Set compare to half the period place++; // if (duty_counter > (frequencies[voice_place] / 500)) { @@ -413,23 +423,8 @@ if (audio_config.enable && voices < 8) { freq = freq / SAMPLE_RATE; #endif if (freq > 0) { - if (frequency != 0) { - double starting_f = frequency; - if (frequency < freq) { - for (double f = starting_f; f <= freq; f += ((freq - starting_f) / 2000.0)) { - frequency = f; - } - } else if (frequency > freq) { - for (double f = starting_f; f >= freq; f -= ((starting_f - freq) / 2000.0)) { - frequency = f; - } - } - } - frequency = freq; - volume = vol; - - frequencies[voices] = frequency; - volumes[voices] = volume; + frequencies[voices] = freq; + volumes[voices] = vol; voices++; } diff --git a/quantum/keymap_common.c b/quantum/keymap_common.c index 4ee290ad0..43debf4ef 100644 --- a/quantum/keymap_common.c +++ b/quantum/keymap_common.c @@ -184,6 +184,7 @@ static action_t keycode_to_action(uint16_t keycode) case RESET: ; // RESET is 0x5000, which is why this is here clear_keyboard(); #ifdef AUDIO_ENABLE + stop_all_notes(); play_goodbye_tone(); #endif _delay_ms(250); -- cgit v1.2.3-24-g4f1b From a2f31c886ff13c5e7adeccccfe672698c1c7efb9 Mon Sep 17 00:00:00 2001 From: Jack Humbert Date: Tue, 19 Apr 2016 12:58:13 -0400 Subject: getting ready for getters and setters --- quantum/audio.c | 81 +++++++++++++++++++++++-------------------- quantum/audio.h | 104 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 149 insertions(+), 36 deletions(-) (limited to 'quantum') diff --git a/quantum/audio.c b/quantum/audio.c index d8768f160..c92cb5373 100644 --- a/quantum/audio.c +++ b/quantum/audio.c @@ -34,8 +34,6 @@ int voice_place = 0; double frequency = 0; int volume = 0; long position = 0; -int duty_place = 1; -int duty_counter = 0; double frequencies[8] = {0, 0, 0, 0, 0, 0, 0, 0}; int volumes[8] = {0, 0, 0, 0, 0, 0, 0, 0}; @@ -51,7 +49,7 @@ uint16_t place_int = 0; bool repeat = true; uint8_t * sample; uint16_t sample_length = 0; - +double freq = 0; bool notes = false; bool note = false; @@ -65,11 +63,15 @@ uint8_t notes_count; bool notes_repeat; float notes_rest; bool note_resting = false; -int note_flipper = 0; uint8_t current_note = 0; uint8_t rest_counter = 0; +uint8_t vibrato_counter = 0; +float vibrato_strength = 0; + +float polyphony_rate = 0; + audio_config_t audio_config; @@ -182,6 +184,11 @@ void init_notes() { #endif } +float mod(float a, int b) +{ + float r = fmod(a, b); + return r < 0 ? r + b : r; +} ISR(TIMER3_COMPA_vect) { if (note) { @@ -233,48 +240,41 @@ ISR(TIMER3_COMPA_vect) { OCR4A = sum; } #else - if (frequencies[voice_place] > 0) { - // if (frequencies[voice_place] > 880.0) { - // if (note_flipper == 100) { - // note_flipper = 0; - // return; - // } - // note_flipper++; - // } else { - // note_flipper = 0; - // } - // ICR3 = (int)(((double)F_CPU) / frequency); // Set max to the period - // OCR3A = (int)(((double)F_CPU) / frequency) >> 1; // Set compare to half the period - - double freq; - if (false) { - voice_place %= voices; - if (place > (frequencies[voice_place] / 50)) { - voice_place = (voice_place + 1) % voices; - place = 0.0; + if (voices > 0) { + if (false && polyphony_rate > 0) { + if (voices > 1) { + voice_place %= voices; + if (place++ > (frequencies[voice_place] / polyphony_rate / CPU_PRESCALER / voices)) { + voice_place = (voice_place + 1) % voices; + place = 0.0; + } } - freq = frequencies[voice_place]; + if (vibrato_strength > 0) { + freq = frequencies[voice_place] * pow(VIBRATO_LUT[(int)vibrato_counter], vibrato_strength); + vibrato_counter = mod((vibrato_counter + 1), VIBRATO_LUT_LENGTH); + } else { + freq = frequencies[voice_place]; + } } else { if (frequency != 0) { if (frequency < frequencies[voices - 1]) { - frequency = frequency * 1.01454533494; + frequency = frequency * pow(2, 440/frequencies[voices - 1]/12/4); } else if (frequency > frequencies[voices - 1]) { - frequency = frequency * 0.98566319864; + frequency = frequency * pow(2, -440/frequencies[voices - 1]/12/4); } } else { frequency = frequencies[voices - 1]; } - freq = frequency; + + if (false && vibrato_strength > 0) { + freq = frequency * pow(VIBRATO_LUT[(int)vibrato_counter], vibrato_strength); + vibrato_counter = mod((vibrato_counter + 1 + 440/frequencies[voices - 1]), VIBRATO_LUT_LENGTH); + } else { + freq = frequency; + } } ICR3 = (int)(((double)F_CPU) / (freq * CPU_PRESCALER)); // Set max to the period OCR3A = (int)((((double)F_CPU) / (freq * CPU_PRESCALER)) * note_timbre); // Set compare to half the period - //OCR3A = (int)(((double)F_CPU) / (frequencies[voice_place] * CPU_PRESCALER)) >> 1 * duty_place; // Set compare to half the period - place++; - // if (duty_counter > (frequencies[voice_place] / 500)) { - // duty_place = (duty_place % 3) + 1; - // duty_counter = 0; - // } - // duty_counter++; } #endif } @@ -300,8 +300,17 @@ ISR(TIMER3_COMPA_vect) { place -= SINE_LENGTH; #else if (note_frequency > 0) { - ICR3 = (int)(((double)F_CPU) / (note_frequency * CPU_PRESCALER)); // Set max to the period - OCR3A = (int)((((double)F_CPU) / (note_frequency * CPU_PRESCALER)) * note_timbre); // Set compare to half the period + float freq; + + if (false && vibrato_strength > 0) { + freq = note_frequency * pow(VIBRATO_LUT[(int)vibrato_counter], vibrato_strength); + vibrato_counter = mod((vibrato_counter + 1), VIBRATO_LUT_LENGTH); + } else { + freq = note_frequency; + } + + ICR3 = (int)(((double)F_CPU) / (freq * CPU_PRESCALER)); // Set max to the period + OCR3A = (int)((((double)F_CPU) / (freq * CPU_PRESCALER)) * note_timbre); // Set compare to half the period } else { ICR3 = 0; OCR3A = 0; diff --git a/quantum/audio.h b/quantum/audio.h index 44cafccd6..f705341d7 100644 --- a/quantum/audio.h +++ b/quantum/audio.h @@ -47,4 +47,108 @@ void decrease_tempo(uint8_t tempo_change); void play_goodbye_tone(void); void play_startup_tone(void); +#define VIBRATO_LUT (float []) { \ +1.00090714186239, \ +1.00181152169061, \ +1.00270955652027, \ +1.00359767896099, \ +1.00447235162891, \ +1.00533008160601, \ +1.00616743486158, \ +1.00698105056935, \ +1.00776765525194, \ +1.00852407668313, \ +1.0092472574777, \ +1.00993426829815, \ +1.01058232060837, \ +1.01118877890462, \ +1.01175117235612, \ +1.01226720578933, \ +1.01273476995269, \ +1.01315195100182, \ +1.0135170391489, \ +1.01382853642434, \ +1.01408516350345, \ +1.01428586555648, \ +1.0144298170856, \ +1.0145164257189, \ +1.01454533493752, \ +1.0145164257189, \ +1.0144298170856, \ +1.01428586555648, \ +1.01408516350345, \ +1.01382853642434, \ +1.0135170391489, \ +1.01315195100182, \ +1.01273476995269, \ +1.01226720578933, \ +1.01175117235612, \ +1.01118877890462, \ +1.01058232060837, \ +1.00993426829815, \ +1.0092472574777, \ +1.00852407668313, \ +1.00776765525194, \ +1.00698105056935, \ +1.00616743486158, \ +1.00533008160601, \ +1.00447235162891, \ +1.00359767896099, \ +1.00270955652027, \ +1.00181152169061, \ +1.00090714186239, \ +1, \ +0.999093680298157, \ +0.998191753986265, \ +0.997297765337276, \ +0.996415217934032, \ +0.995547561242821, \ +0.99469817754036, \ +0.993870369236874, \ +0.993067346634376, \ +0.992292216155724, \ +0.991547969076588, \ +0.990837470789065, \ +0.990163450622494, \ +0.989528492243954, \ +0.988935024658062, \ +0.988385313823004, \ +0.98788145489731, \ +0.987425365129624, \ +0.987018777401739, \ +0.986663234433381, \ +0.986360083655655, \ +0.986110472758728, \ +0.985915345918143, \ +0.985775440703176, \ +0.985691285669809, \ +0.985663198640188, \ +0.985691285669809, \ +0.985775440703176, \ +0.985915345918143, \ +0.986110472758728, \ +0.986360083655655, \ +0.986663234433381, \ +0.987018777401739, \ +0.987425365129624, \ +0.98788145489731, \ +0.988385313823004, \ +0.988935024658062, \ +0.989528492243954, \ +0.990163450622494, \ +0.990837470789065, \ +0.991547969076588, \ +0.992292216155724, \ +0.993067346634376, \ +0.993870369236874, \ +0.99469817754036, \ +0.99554756124282, \ +0.996415217934032, \ +0.997297765337276, \ +0.998191753986265, \ +0.999093680298157, \ +1, \ +} +#define VIBRATO_LUT_LENGTH NOTE_ARRAY_SIZE(VIBRATO_LUT) + #endif \ No newline at end of file -- cgit v1.2.3-24-g4f1b From fd49dfe5cb686f5966447c6b890800c9cd11d281 Mon Sep 17 00:00:00 2001 From: Jack Humbert Date: Tue, 19 Apr 2016 17:00:45 -0400 Subject: vibrato and polyphony paratmeters --- quantum/audio.c | 160 ++++++++++++++++++++++++++++++++++---------------- quantum/audio.h | 140 ++++++++++--------------------------------- quantum/vibrato_lut.h | 108 ++++++++++++++++++++++++++++++++++ 3 files changed, 249 insertions(+), 159 deletions(-) create mode 100644 quantum/vibrato_lut.h (limited to 'quantum') diff --git a/quantum/audio.c b/quantum/audio.c index c92cb5373..8ea1bf6ff 100644 --- a/quantum/audio.c +++ b/quantum/audio.c @@ -10,10 +10,13 @@ #include "eeconfig.h" +#include "vibrato_lut.h" + #define PI 3.14159265 #define CPU_PRESCALER 8 +// Largely untested PWM audio mode (doesn't sound as good) // #define PWM_AUDIO #ifdef PWM_AUDIO @@ -67,10 +70,11 @@ bool note_resting = false; uint8_t current_note = 0; uint8_t rest_counter = 0; -uint8_t vibrato_counter = 0; -float vibrato_strength = 0; +float vibrato_counter = 0; +float vibrato_strength = .5; +float vibrato_rate = 0.125; -float polyphony_rate = 0; +float polyphony_rate = .5; audio_config_t audio_config; @@ -90,6 +94,81 @@ void audio_off(void) { eeconfig_write_audio(audio_config.raw); } +// Vibrato rate functions + +void set_vibrato_rate(float rate) { + vibrato_rate = rate; +} + +void increase_vibrato_rate(float change) { + vibrato_rate *= change; +} + +void decrease_vibrato_rate(float change) { + vibrato_rate /= change; +} + +#ifdef VIBRATO_STRENGTH_ENABLE + +void set_vibrato_strength(float strength) { + vibrato_strength = strength; +} + +void increase_vibrato_strength(float change) { + vibrato_strength *= change; +} + +void decrease_vibrato_strength(float change) { + vibrato_strength /= change; +} + +#endif + +// Polyphony functions + +void set_polyphony_rate(float rate) { + polyphony_rate = rate; +} + +void enable_polyphony() { + polyphony_rate = 5; +} + +void disable_polyphony() { + polyphony_rate = 0; +} + +void increase_polyphony_rate(float change) { + polyphony_rate *= change; +} + +void decrease_polyphony_rate(float change) { + polyphony_rate /= change; +} + +// Timbre function + +void set_timbre(float timbre) { + note_timbre = timbre; +} + +// Tempo functions + +void set_tempo(float tempo) { + note_tempo = tempo; +} + +void decrease_tempo(uint8_t tempo_change) { + note_tempo += (float) tempo_change; +} + +void increase_tempo(uint8_t tempo_change) { + if (note_tempo - (float) tempo_change < 10) { + note_tempo = 10; + } else { + note_tempo -= (float) tempo_change; + } +} void stop_all_notes() { voices = 0; @@ -112,6 +191,7 @@ void stop_all_notes() { void stop_note(double freq) { if (note) { + cli(); #ifdef PWM_AUDIO freq = freq / SAMPLE_RATE; #endif @@ -125,6 +205,7 @@ void stop_note(double freq) { volumes[j] = volumes[j+1]; volumes[j+1] = 0; } + break; } } voices--; @@ -144,6 +225,7 @@ void stop_note(double freq) { volume = 0; note = false; } + sei(); } } @@ -190,6 +272,16 @@ float mod(float a, int b) return r < 0 ? r + b : r; } +float vibrato(float average_freq) { + #ifdef VIBRATO_STRENGTH_ENABLE + float vibrated_freq = average_freq * pow(VIBRATO_LUT[(int)vibrato_counter], vibrato_strength); + #else + float vibrated_freq = average_freq * VIBRATO_LUT[(int)vibrato_counter]; + #endif + vibrato_counter = mod((vibrato_counter + vibrato_rate * (1.0 + 440.0/average_freq)), VIBRATO_LUT_LENGTH); + return vibrated_freq; +} + ISR(TIMER3_COMPA_vect) { if (note) { #ifdef PWM_AUDIO @@ -241,34 +333,30 @@ ISR(TIMER3_COMPA_vect) { } #else if (voices > 0) { - if (false && polyphony_rate > 0) { + if (polyphony_rate > 0) { if (voices > 1) { voice_place %= voices; - if (place++ > (frequencies[voice_place] / polyphony_rate / CPU_PRESCALER / voices)) { + if (place++ > (frequencies[voice_place] / polyphony_rate / CPU_PRESCALER)) { voice_place = (voice_place + 1) % voices; place = 0.0; } } if (vibrato_strength > 0) { - freq = frequencies[voice_place] * pow(VIBRATO_LUT[(int)vibrato_counter], vibrato_strength); - vibrato_counter = mod((vibrato_counter + 1), VIBRATO_LUT_LENGTH); + freq = vibrato(frequencies[voice_place]); } else { freq = frequencies[voice_place]; } } else { - if (frequency != 0) { - if (frequency < frequencies[voices - 1]) { - frequency = frequency * pow(2, 440/frequencies[voices - 1]/12/4); - } else if (frequency > frequencies[voices - 1]) { - frequency = frequency * pow(2, -440/frequencies[voices - 1]/12/4); - } + if (frequency != 0 && frequency < frequencies[voices - 1] && frequency < frequencies[voices - 1] * pow(2, -440/frequencies[voices - 1]/12/2)) { + frequency = frequency * pow(2, 440/frequency/12/2); + } else if (frequency != 0 && frequency > frequencies[voices - 1] && frequency > frequencies[voices - 1] * pow(2, 440/frequencies[voices - 1]/12/2)) { + frequency = frequency * pow(2, -440/frequency/12/2); } else { frequency = frequencies[voices - 1]; } - if (false && vibrato_strength > 0) { - freq = frequency * pow(VIBRATO_LUT[(int)vibrato_counter], vibrato_strength); - vibrato_counter = mod((vibrato_counter + 1 + 440/frequencies[voices - 1]), VIBRATO_LUT_LENGTH); + if (vibrato_strength > 0) { + freq = vibrato(frequency); } else { freq = frequency; } @@ -302,9 +390,8 @@ ISR(TIMER3_COMPA_vect) { if (note_frequency > 0) { float freq; - if (false && vibrato_strength > 0) { - freq = note_frequency * pow(VIBRATO_LUT[(int)vibrato_counter], vibrato_strength); - vibrato_counter = mod((vibrato_counter + 1), VIBRATO_LUT_LENGTH); + if (vibrato_strength > 0) { + freq = vibrato(note_frequency); } else { freq = note_frequency; } @@ -369,7 +456,7 @@ ISR(TIMER3_COMPA_vect) { void play_notes(float (*np)[][2], uint8_t n_count, bool n_repeat, float n_rest) { if (audio_config.enable) { - + cli(); // Cancel note if a note is playing if (note) stop_all_notes(); @@ -398,7 +485,7 @@ if (audio_config.enable) { TIMSK3 |= _BV(OCIE3A); TCCR3A |= _BV(COM3A1); #endif - + sei(); } } @@ -425,7 +512,7 @@ if (audio_config.enable) { void play_note(double freq, int vol) { if (audio_config.enable && voices < 8) { - + cli(); // Cancel notes if notes are playing if (notes) stop_all_notes(); @@ -445,36 +532,9 @@ if (audio_config.enable && voices < 8) { TIMSK3 |= _BV(OCIE3A); TCCR3A |= _BV(COM3A1); #endif - -} - -} - -void set_timbre(float timbre) -{ - note_timbre = timbre; + sei(); } -void set_tempo(float tempo) -{ - note_tempo = tempo; -} - -void decrease_tempo(uint8_t tempo_change) -{ - note_tempo += (float) tempo_change; -} - -void increase_tempo(uint8_t tempo_change) -{ - if (note_tempo - (float) tempo_change < 10) - { - note_tempo = 10; - } - else - { - note_tempo -= (float) tempo_change; - } } //------------------------------------------------------------------------------ diff --git a/quantum/audio.h b/quantum/audio.h index f705341d7..85756af9d 100644 --- a/quantum/audio.h +++ b/quantum/audio.h @@ -8,6 +8,9 @@ #ifndef AUDIO_H #define AUDIO_H +// Enable vibrato strength/amplitude - slows down ISR too much +// #define VIBRATO_STRENGTH_ENABLE + typedef union { uint8_t raw; struct { @@ -20,6 +23,34 @@ void audio_toggle(void); void audio_on(void); void audio_off(void); +// Vibrato rate functions + +void set_vibrato_rate(float rate); +void increase_vibrato_rate(float change); +void decrease_vibrato_rate(float change); + +#ifdef VIBRATO_STRENGTH_ENABLE + +void set_vibrato_strength(float strength); +void increase_vibrato_strength(float change); +void decrease_vibrato_strength(float change); + +#endif + +// Polyphony functions + +void set_polyphony_rate(float rate); +void enable_polyphony(); +void disable_polyphony(); +void increase_polyphony_rate(float change); +void decrease_polyphony_rate(float change); + +void set_timbre(float timbre); +void set_tempo(float tempo); + +void increase_tempo(uint8_t tempo_change); +void decrease_tempo(uint8_t tempo_change); + void play_sample(uint8_t * s, uint16_t l, bool r); void play_note(double freq, int vol); void stop_note(double freq); @@ -27,11 +58,6 @@ void stop_all_notes(void); void init_notes(void); void play_notes(float (*np)[][2], uint8_t n_count, bool n_repeat, float n_rest); -void set_timbre(float timbre); -void set_tempo(float tempo); -void increase_tempo(uint8_t tempo_change); -void decrease_tempo(uint8_t tempo_change); - #define SCALE (int []){ 0 + (12*0), 2 + (12*0), 4 + (12*0), 5 + (12*0), 7 + (12*0), 9 + (12*0), 11 + (12*0), \ 0 + (12*1), 2 + (12*1), 4 + (12*1), 5 + (12*1), 7 + (12*1), 9 + (12*1), 11 + (12*1), \ 0 + (12*2), 2 + (12*2), 4 + (12*2), 5 + (12*2), 7 + (12*2), 9 + (12*2), 11 + (12*2), \ @@ -47,108 +73,4 @@ void decrease_tempo(uint8_t tempo_change); void play_goodbye_tone(void); void play_startup_tone(void); -#define VIBRATO_LUT (float []) { \ -1.00090714186239, \ -1.00181152169061, \ -1.00270955652027, \ -1.00359767896099, \ -1.00447235162891, \ -1.00533008160601, \ -1.00616743486158, \ -1.00698105056935, \ -1.00776765525194, \ -1.00852407668313, \ -1.0092472574777, \ -1.00993426829815, \ -1.01058232060837, \ -1.01118877890462, \ -1.01175117235612, \ -1.01226720578933, \ -1.01273476995269, \ -1.01315195100182, \ -1.0135170391489, \ -1.01382853642434, \ -1.01408516350345, \ -1.01428586555648, \ -1.0144298170856, \ -1.0145164257189, \ -1.01454533493752, \ -1.0145164257189, \ -1.0144298170856, \ -1.01428586555648, \ -1.01408516350345, \ -1.01382853642434, \ -1.0135170391489, \ -1.01315195100182, \ -1.01273476995269, \ -1.01226720578933, \ -1.01175117235612, \ -1.01118877890462, \ -1.01058232060837, \ -1.00993426829815, \ -1.0092472574777, \ -1.00852407668313, \ -1.00776765525194, \ -1.00698105056935, \ -1.00616743486158, \ -1.00533008160601, \ -1.00447235162891, \ -1.00359767896099, \ -1.00270955652027, \ -1.00181152169061, \ -1.00090714186239, \ -1, \ -0.999093680298157, \ -0.998191753986265, \ -0.997297765337276, \ -0.996415217934032, \ -0.995547561242821, \ -0.99469817754036, \ -0.993870369236874, \ -0.993067346634376, \ -0.992292216155724, \ -0.991547969076588, \ -0.990837470789065, \ -0.990163450622494, \ -0.989528492243954, \ -0.988935024658062, \ -0.988385313823004, \ -0.98788145489731, \ -0.987425365129624, \ -0.987018777401739, \ -0.986663234433381, \ -0.986360083655655, \ -0.986110472758728, \ -0.985915345918143, \ -0.985775440703176, \ -0.985691285669809, \ -0.985663198640188, \ -0.985691285669809, \ -0.985775440703176, \ -0.985915345918143, \ -0.986110472758728, \ -0.986360083655655, \ -0.986663234433381, \ -0.987018777401739, \ -0.987425365129624, \ -0.98788145489731, \ -0.988385313823004, \ -0.988935024658062, \ -0.989528492243954, \ -0.990163450622494, \ -0.990837470789065, \ -0.991547969076588, \ -0.992292216155724, \ -0.993067346634376, \ -0.993870369236874, \ -0.99469817754036, \ -0.99554756124282, \ -0.996415217934032, \ -0.997297765337276, \ -0.998191753986265, \ -0.999093680298157, \ -1, \ -} -#define VIBRATO_LUT_LENGTH NOTE_ARRAY_SIZE(VIBRATO_LUT) - #endif \ No newline at end of file diff --git a/quantum/vibrato_lut.h b/quantum/vibrato_lut.h new file mode 100644 index 000000000..4c267a626 --- /dev/null +++ b/quantum/vibrato_lut.h @@ -0,0 +1,108 @@ +#include +#include +#include + +#define VIBRATO_LUT_LENGTH 100 + +const float VIBRATO_LUT[VIBRATO_LUT_LENGTH] = { \ +1.00045346811453, +1.00090535101508, +1.00135386178926, +1.00179722447259, +1.00223368114872, +1.0026614990145, +1.00307897737994, +1.00348445457284, +1.00387631471807, +1.00425299436105, +1.00461298890553, +1.00495485883603, +1.00527723569589, +1.00557882779254, +1.00585842560279, +1.00611490685176, +1.00634724124066, +1.00655449479987, +1.00673583384565, +1.00689052852052, +1.00701795589922, +1.00711760264454, +1.0071890671992, +1.00723206150266, +1.0072464122237, +1.00723206150266, +1.0071890671992, +1.00711760264454, +1.00701795589922, +1.00689052852052, +1.00673583384565, +1.00655449479987, +1.00634724124066, +1.00611490685176, +1.00585842560279, +1.00557882779254, +1.00527723569589, +1.00495485883603, +1.00461298890553, +1.00425299436105, +1.00387631471807, +1.00348445457284, +1.00307897737994, +1.0026614990145, +1.00223368114872, +1.00179722447259, +1.00135386178926, +1.00090535101508, +1.00045346811453, +1, +0.999546737425598, +0.999095467903976, +0.998647968674285, +0.998205999748565, +0.99777129706302, +0.997345565759612, +0.996930473622346, +0.996527644691494, +0.996138653077835, +0.99576501699778, +0.995408193048995, +0.995069570744927, +0.994750467325326, +0.994452122858643, +0.994175695650927, +0.993922257974591, +0.99369279212925, +0.993488186845591, +0.993309234042139, +0.993156625943589, +0.993030952568311, +0.99293269959154, +0.992862246589715, +0.992819865670409, +0.992805720491269, +0.992819865670409, +0.992862246589715, +0.99293269959154, +0.993030952568311, +0.993156625943589, +0.993309234042139, +0.993488186845591, +0.99369279212925, +0.993922257974591, +0.994175695650927, +0.994452122858643, +0.994750467325326, +0.995069570744927, +0.995408193048995, +0.99576501699778, +0.996138653077835, +0.996527644691494, +0.996930473622346, +0.997345565759612, +0.99777129706302, +0.998205999748565, +0.998647968674285, +0.999095467903976, +0.999546737425598, +1 +}; \ No newline at end of file -- cgit v1.2.3-24-g4f1b