diff options
author | Olivier <olivier@gid0.org> | 2016-04-30 16:03:52 +0200 |
---|---|---|
committer | Olivier <olivier@gid0.org> | 2016-04-30 16:03:52 +0200 |
commit | 09ea12f9ca96fa89a500a5965bf074c4347d300d (patch) | |
tree | 747caedcbd529d068d6794a72e65a5bef274ed8e /quantum | |
parent | 9d48ba9713d17a8ebae99ef42bc7838402fc532f (diff) | |
parent | e7d56215deb253b44b190d12288076d03b206bdf (diff) | |
download | qmk_firmware-09ea12f9ca96fa89a500a5965bf074c4347d300d.tar.gz |
Merge https://github.com/jackhumbert/qmk_firmware
Diffstat (limited to 'quantum')
-rw-r--r-- | quantum/audio/audio.c (renamed from quantum/audio.c) | 449 | ||||
-rw-r--r-- | quantum/audio/audio.h (renamed from quantum/audio.h) | 58 | ||||
-rw-r--r-- | quantum/audio/frequency_lut.h | 357 | ||||
-rw-r--r-- | quantum/audio/musical_notes.h (renamed from quantum/musical_notes.h) | 56 | ||||
-rw-r--r-- | quantum/audio/song_list.h | 117 | ||||
-rw-r--r-- | quantum/audio/vibrato_lut.h | 28 | ||||
-rw-r--r-- | quantum/audio/voices.c | 163 | ||||
-rw-r--r-- | quantum/audio/voices.h | 32 | ||||
-rw-r--r-- | quantum/audio/wave.h (renamed from quantum/wave.h) | 0 | ||||
-rw-r--r-- | quantum/keymap_common.c | 22 | ||||
-rw-r--r-- | quantum/keymap_common.h | 6 | ||||
-rw-r--r-- | quantum/keymap_extras/keymap_german_osx.h | 4 | ||||
-rw-r--r-- | quantum/keymap_extras/keymap_plover.h | 32 | ||||
-rw-r--r-- | quantum/led.c | 1 | ||||
-rw-r--r-- | quantum/quantum.mk | 3 | ||||
-rw-r--r-- | quantum/rgblight.c | 26 | ||||
-rw-r--r-- | quantum/rgblight.h | 4 | ||||
-rw-r--r-- | quantum/template/Makefile | 46 | ||||
-rw-r--r-- | quantum/template/template.c | 61 | ||||
-rw-r--r-- | quantum/template/template.h | 5 |
20 files changed, 1259 insertions, 211 deletions
diff --git a/quantum/audio.c b/quantum/audio/audio.c index 6bd6532a3..e85370d95 100644 --- a/quantum/audio.c +++ b/quantum/audio/audio.c @@ -4,23 +4,29 @@ #include <avr/pgmspace.h> #include <avr/interrupt.h> #include <avr/io.h> - +#include "print.h" #include "audio.h" #include "keymap_common.h" #include "eeconfig.h" +#ifdef VIBRATO_ENABLE + #include "vibrato_lut.h" +#endif + #define PI 3.14159265 #define CPU_PRESCALER 8 -// #define PWM_AUDIO - #ifdef PWM_AUDIO #include "wave.h" #define SAMPLE_DIVIDER 39 #define SAMPLE_RATE (2000000.0/SAMPLE_DIVIDER/2048) // Resistor value of 1/ (2 * PI * 10nF * (2000000 hertz / SAMPLE_DIVIDER / 10)) for 10nF cap + + float places[8] = {0, 0, 0, 0, 0, 0, 0, 0}; + uint16_t place_int = 0; + bool repeat = true; #endif void delay_us(int count) { @@ -31,35 +37,31 @@ void delay_us(int count) { int voices = 0; int voice_place = 0; -double frequency = 0; +float 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}; +float frequencies[8] = {0, 0, 0, 0, 0, 0, 0, 0}; int volumes[8] = {0, 0, 0, 0, 0, 0, 0, 0}; bool sliding = false; int max = 0xFF; float sum = 0; -int value = 128; float place = 0; -float places[8] = {0, 0, 0, 0, 0, 0, 0, 0}; -uint16_t place_int = 0; -bool repeat = true; uint8_t * sample; uint16_t sample_length = 0; - +// float freq = 0; bool notes = false; bool note = false; float note_frequency = 0; float note_length = 0; +float note_tempo = TEMPO_DEFAULT; +float note_timbre = TIMBRE_DEFAULT; uint16_t note_position = 0; float (* notes_pointer)[][2]; -uint8_t notes_length; +uint16_t notes_count; bool notes_repeat; float notes_rest; bool note_resting = false; @@ -67,26 +69,157 @@ bool note_resting = false; uint8_t current_note = 0; uint8_t rest_counter = 0; +#ifdef VIBRATO_ENABLE +float vibrato_counter = 0; +float vibrato_strength = .5; +float vibrato_rate = 0.125; +#endif + +float polyphony_rate = 0; + +bool inited = false; + audio_config_t audio_config; +uint16_t envelope_index = 0; void audio_toggle(void) { audio_config.enable ^= 1; - eeconfig_write_audio(audio_config.raw); + eeconfig_update_audio(audio_config.raw); } void audio_on(void) { audio_config.enable = 1; - eeconfig_write_audio(audio_config.raw); + eeconfig_update_audio(audio_config.raw); } void audio_off(void) { audio_config.enable = 0; - eeconfig_write_audio(audio_config.raw); + eeconfig_update_audio(audio_config.raw); +} + +#ifdef VIBRATO_ENABLE +// 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 + +#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 audio_init() { + + /* check signature */ + if (!eeconfig_is_enabled()) { + eeconfig_init(); + } + audio_config.raw = eeconfig_read_audio(); + + #ifdef PWM_AUDIO + PLLFRQ = _BV(PDIV2); + PLLCSR = _BV(PLLE); + while(!(PLLCSR & _BV(PLOCK))); + PLLFRQ |= _BV(PLLTM0); /* PCK 48MHz */ + + /* Init a fast PWM on Timer4 */ + TCCR4A = _BV(COM4A0) | _BV(PWM4A); /* Clear OC4A on Compare Match */ + TCCR4B = _BV(CS40); /* No prescaling => f = PCK/256 = 187500Hz */ + OCR4A = 0; + + /* Enable the OC4A output */ + DDRC |= _BV(PORTC6); + + TIMSK3 &= ~_BV(OCIE3A); // Turn off 3A interputs + + TCCR3A = 0x0; // Options not needed + TCCR3B = _BV(CS31) | _BV(CS30) | _BV(WGM32); // 64th prescaling and CTC + OCR3A = SAMPLE_DIVIDER - 1; // Correct count/compare, related to sample playback + #else + DDRC |= _BV(PORTC6); + + TIMSK3 &= ~_BV(OCIE3A); // Turn off 3A interputs + + TCCR3A = (0 << COM3A1) | (0 << COM3A0) | (1 << WGM31) | (0 << WGM30); + TCCR3B = (1 << WGM33) | (1 << WGM32) | (0 << CS32) | (1 << CS31) | (0 << CS30); + #endif + + inited = true; +} void stop_all_notes() { + if (!inited) { + audio_init(); + } voices = 0; #ifdef PWM_AUDIO TIMSK3 &= ~_BV(OCIE3A); @@ -105,8 +238,11 @@ void stop_all_notes() { } } -void stop_note(double freq) { +void stop_note(float freq) { if (note) { + if (!inited) { + audio_init(); + } #ifdef PWM_AUDIO freq = freq / SAMPLE_RATE; #endif @@ -120,11 +256,15 @@ void stop_note(double freq) { volumes[j] = volumes[j+1]; volumes[j+1] = 0; } + break; } } voices--; if (voices < 0) voices = 0; + if (voice_place >= voices) { + voice_place = 0; + } if (voices == 0) { #ifdef PWM_AUDIO TIMSK3 &= ~_BV(OCIE3A); @@ -135,66 +275,29 @@ 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; } } } -void init_notes() { - - /* check signature */ - if (!eeconfig_is_enabled()) { - eeconfig_init(); - } - audio_config.raw = eeconfig_read_audio(); - - #ifdef PWM_AUDIO - PLLFRQ = _BV(PDIV2); - PLLCSR = _BV(PLLE); - while(!(PLLCSR & _BV(PLOCK))); - PLLFRQ |= _BV(PLLTM0); /* PCK 48MHz */ - - /* Init a fast PWM on Timer4 */ - TCCR4A = _BV(COM4A0) | _BV(PWM4A); /* Clear OC4A on Compare Match */ - TCCR4B = _BV(CS40); /* No prescaling => f = PCK/256 = 187500Hz */ - OCR4A = 0; +#ifdef VIBRATO_ENABLE - /* Enable the OC4A output */ - DDRC |= _BV(PORTC6); - - TIMSK3 &= ~_BV(OCIE3A); // Turn off 3A interputs +float mod(float a, int b) +{ + float r = fmod(a, b); + return r < 0 ? r + b : r; +} - TCCR3A = 0x0; // Options not needed - TCCR3B = _BV(CS31) | _BV(CS30) | _BV(WGM32); // 64th prescaling and CTC - OCR3A = SAMPLE_DIVIDER - 1; // Correct count/compare, related to sample playback +float vibrato(float average_freq) { + #ifdef VIBRATO_STRENGTH_ENABLE + float vibrated_freq = average_freq * pow(VIBRATO_LUT[(int)vibrato_counter], vibrato_strength); #else - DDRC |= _BV(PORTC6); - - TIMSK3 &= ~_BV(OCIE3A); // Turn off 3A interputs - - TCCR3A = (0 << COM3A1) | (0 << COM3A0) | (1 << WGM31) | (0 << WGM30); - TCCR3B = (1 << WGM33) | (1 << WGM32) | (0 << CS32) | (1 << CS31) | (0 << CS30); + 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; } +#endif ISR(TIMER3_COMPA_vect) { if (note) { @@ -246,22 +349,55 @@ ISR(TIMER3_COMPA_vect) { OCR4A = sum; } #else - if (frequency > 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; + if (voices > 0) { + float freq; + if (polyphony_rate > 0) { + if (voices > 1) { + voice_place %= voices; + if (place++ > (frequencies[voice_place] / polyphony_rate / CPU_PRESCALER)) { + voice_place = (voice_place + 1) % voices; + place = 0.0; + } + } + #ifdef VIBRATO_ENABLE + if (vibrato_strength > 0) { + freq = vibrato(frequencies[voice_place]); + } else { + #else + { + #endif + freq = frequencies[voice_place]; + } + } 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 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]; + } + + + #ifdef VIBRATO_ENABLE + if (vibrato_strength > 0) { + freq = vibrato(frequency); + } else { + #else + { + #endif + 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)) >> 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++; + + if (envelope_index < 65535) { + envelope_index++; + } + freq = voice_envelope(freq); + + if (freq < 30.517578125) + freq = 30.52; + 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 } #endif } @@ -287,8 +423,25 @@ 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)) >> 1; // Set compare to half the period + float freq; + + #ifdef VIBRATO_ENABLE + if (vibrato_strength > 0) { + freq = vibrato(note_frequency); + } else { + #else + { + #endif + freq = note_frequency; + } + + if (envelope_index < 65535) { + envelope_index++; + } + freq = voice_envelope(freq); + + 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; @@ -304,7 +457,7 @@ ISR(TIMER3_COMPA_vect) { end_of_note = (note_position >= (note_length * 0x7FF)); if (end_of_note) { current_note++; - if (current_note >= notes_length) { + if (current_note >= notes_count) { if (notes_repeat) { current_note = 0; } else { @@ -327,10 +480,11 @@ ISR(TIMER3_COMPA_vect) { note_resting = false; #ifdef PWM_AUDIO note_frequency = (*notes_pointer)[current_note][0] / SAMPLE_RATE; - note_length = (*notes_pointer)[current_note][1]; + note_length = (*notes_pointer)[current_note][1] * (note_tempo / 100); #else + envelope_index = 0; note_frequency = (*notes_pointer)[current_note][0]; - note_length = (*notes_pointer)[current_note][1] / 4; + note_length = ((*notes_pointer)[current_note][1] / 4) * (note_tempo / 100); #endif } note_position = 0; @@ -344,15 +498,53 @@ ISR(TIMER3_COMPA_vect) { } } -void play_notes(float (*np)[][2], uint8_t n_length, bool n_repeat, float n_rest) { +void play_note(float freq, int vol) { -if (audio_config.enable) { + if (!inited) { + audio_init(); + } +if (audio_config.enable && voices < 8) { + TIMSK3 &= ~_BV(OCIE3A); + // Cancel notes if notes are playing + if (notes) + stop_all_notes(); + note = true; + envelope_index = 0; + #ifdef PWM_AUDIO + freq = freq / SAMPLE_RATE; + #endif + if (freq > 0) { + frequencies[voices] = freq; + volumes[voices] = vol; + voices++; + } + + #ifdef PWM_AUDIO + TIMSK3 |= _BV(OCIE3A); + #else + TIMSK3 |= _BV(OCIE3A); + TCCR3A |= _BV(COM3A1); + #endif +} + +} + +void play_notes(float (*np)[][2], uint16_t n_count, bool n_repeat, float n_rest) { + + if (!inited) { + audio_init(); + } + +if (audio_config.enable) { + TIMSK3 &= ~_BV(OCIE3A); + // Cancel note if a note is playing if (note) stop_all_notes(); + notes = true; notes_pointer = np; - notes_length = n_length; + notes_count = n_count; notes_repeat = n_repeat; notes_rest = n_rest; @@ -360,10 +552,10 @@ if (audio_config.enable) { current_note = 0; #ifdef PWM_AUDIO note_frequency = (*notes_pointer)[current_note][0] / SAMPLE_RATE; - note_length = (*notes_pointer)[current_note][1]; + note_length = (*notes_pointer)[current_note][1] * (note_tempo / 100); #else note_frequency = (*notes_pointer)[current_note][0]; - note_length = (*notes_pointer)[current_note][1] / 4; + note_length = ((*notes_pointer)[current_note][1] / 4) * (note_tempo / 100); #endif note_position = 0; @@ -374,69 +566,42 @@ if (audio_config.enable) { TIMSK3 |= _BV(OCIE3A); TCCR3A |= _BV(COM3A1); #endif - - notes = true; } } +#ifdef PWM_AUDIO void play_sample(uint8_t * s, uint16_t l, bool r) { + if (!inited) { + audio_init(); + } -if (audio_config.enable) { - - stop_all_notes(); - place_int = 0; - sample = s; - sample_length = l; - repeat = r; + if (audio_config.enable) { + TIMSK3 &= ~_BV(OCIE3A); + stop_all_notes(); + place_int = 0; + sample = s; + sample_length = l; + repeat = r; - #ifdef PWM_AUDIO TIMSK3 |= _BV(OCIE3A); - #else - #endif - + } } +#endif +//------------------------------------------------------------------------------ +// Override these functions in your keymap file to play different tunes on +// startup and bootloader jump +__attribute__ ((weak)) +void play_startup_tone() +{ } -void play_note(double freq, int vol) { -if (audio_config.enable && voices < 8) { - if (notes) - stop_all_notes(); - #ifdef PWM_AUDIO - 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; +__attribute__ ((weak)) +void play_goodbye_tone() +{ - frequencies[voices] = frequency; - volumes[voices] = volume; - voices++; - } - - #ifdef PWM_AUDIO - TIMSK3 |= _BV(OCIE3A); - #else - TIMSK3 |= _BV(OCIE3A); - TCCR3A |= _BV(COM3A1); - #endif - - note = true; } - -}
\ No newline at end of file +//------------------------------------------------------------------------------ diff --git a/quantum/audio.h b/quantum/audio/audio.h index e1bc23ffe..89769507e 100644 --- a/quantum/audio.h +++ b/quantum/audio/audio.h @@ -3,10 +3,20 @@ #include <avr/io.h> #include <util/delay.h> #include "musical_notes.h" +#include "song_list.h" +#include "voices.h" #ifndef AUDIO_H #define AUDIO_H +// Largely untested PWM audio mode (doesn't sound as good) +// #define PWM_AUDIO + +// #define VIBRATO_ENABLE + +// Enable vibrato strength/amplitude - slows down ISR too much +// #define VIBRATO_STRENGTH_ENABLE + typedef union { uint8_t raw; struct { @@ -19,13 +29,47 @@ void audio_toggle(void); void audio_on(void); void audio_off(void); +// Vibrato rate functions + +#ifdef VIBRATO_ENABLE + +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 + +#endif + +// Polyphony functions + +void set_polyphony_rate(float rate); +void enable_polyphony(void); +void disable_polyphony(void); +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 audio_init(void); + +#ifdef PWM_AUDIO void play_sample(uint8_t * s, uint16_t l, bool r); -void play_note(double freq, int vol); -void stop_note(double freq); +#endif +void play_note(float freq, int vol); +void stop_note(float freq); void stop_all_notes(void); -void init_notes(void); -void play_notes(float (*np)[][2], uint8_t n_length, bool n_repeat, float n_rest); - +void play_notes(float (*np)[][2], uint16_t n_count, bool n_repeat, float n_rest); #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), \ @@ -36,8 +80,10 @@ void play_notes(float (*np)[][2], uint8_t n_length, bool n_repeat, float n_rest) // These macros are used to allow play_notes to play an array of indeterminate // length. This works around the limitation of C's sizeof operation on pointers. // The global float array for the song must be used here. -#define NOTE_ARRAY_SIZE(x) ((int)(sizeof(x) / (sizeof(x[0])))) +#define NOTE_ARRAY_SIZE(x) ((int16_t)(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/audio/frequency_lut.h b/quantum/audio/frequency_lut.h new file mode 100644 index 000000000..e62da5be4 --- /dev/null +++ b/quantum/audio/frequency_lut.h @@ -0,0 +1,357 @@ +#include <avr/io.h> +#include <avr/interrupt.h> +#include <avr/pgmspace.h> + +#define FREQUENCY_LUT_LENGTH 349 + +const uint16_t FREQUENCY_LUT[FREQUENCY_LUT_LENGTH] = { +0x8E0B, +0x8C02, +0x8A00, +0x8805, +0x8612, +0x8426, +0x8241, +0x8063, +0x7E8C, +0x7CBB, +0x7AF2, +0x792E, +0x7772, +0x75BB, +0x740B, +0x7261, +0x70BD, +0x6F20, +0x6D88, +0x6BF6, +0x6A69, +0x68E3, +0x6762, +0x65E6, +0x6470, +0x6300, +0x6194, +0x602E, +0x5ECD, +0x5D71, +0x5C1A, +0x5AC8, +0x597B, +0x5833, +0x56EF, +0x55B0, +0x5475, +0x533F, +0x520E, +0x50E1, +0x4FB8, +0x4E93, +0x4D73, +0x4C57, +0x4B3E, +0x4A2A, +0x491A, +0x480E, +0x4705, +0x4601, +0x4500, +0x4402, +0x4309, +0x4213, +0x4120, +0x4031, +0x3F46, +0x3E5D, +0x3D79, +0x3C97, +0x3BB9, +0x3ADD, +0x3A05, +0x3930, +0x385E, +0x3790, +0x36C4, +0x35FB, +0x3534, +0x3471, +0x33B1, +0x32F3, +0x3238, +0x3180, +0x30CA, +0x3017, +0x2F66, +0x2EB8, +0x2E0D, +0x2D64, +0x2CBD, +0x2C19, +0x2B77, +0x2AD8, +0x2A3A, +0x299F, +0x2907, +0x2870, +0x27DC, +0x2749, +0x26B9, +0x262B, +0x259F, +0x2515, +0x248D, +0x2407, +0x2382, +0x2300, +0x2280, +0x2201, +0x2184, +0x2109, +0x2090, +0x2018, +0x1FA3, +0x1F2E, +0x1EBC, +0x1E4B, +0x1DDC, +0x1D6E, +0x1D02, +0x1C98, +0x1C2F, +0x1BC8, +0x1B62, +0x1AFD, +0x1A9A, +0x1A38, +0x19D8, +0x1979, +0x191C, +0x18C0, +0x1865, +0x180B, +0x17B3, +0x175C, +0x1706, +0x16B2, +0x165E, +0x160C, +0x15BB, +0x156C, +0x151D, +0x14CF, +0x1483, +0x1438, +0x13EE, +0x13A4, +0x135C, +0x1315, +0x12CF, +0x128A, +0x1246, +0x1203, +0x11C1, +0x1180, +0x1140, +0x1100, +0x10C2, +0x1084, +0x1048, +0x100C, +0xFD1, +0xF97, +0xF5E, +0xF25, +0xEEE, +0xEB7, +0xE81, +0xE4C, +0xE17, +0xDE4, +0xDB1, +0xD7E, +0xD4D, +0xD1C, +0xCEC, +0xCBC, +0xC8E, +0xC60, +0xC32, +0xC05, +0xBD9, +0xBAE, +0xB83, +0xB59, +0xB2F, +0xB06, +0xADD, +0xAB6, +0xA8E, +0xA67, +0xA41, +0xA1C, +0x9F7, +0x9D2, +0x9AE, +0x98A, +0x967, +0x945, +0x923, +0x901, +0x8E0, +0x8C0, +0x8A0, +0x880, +0x861, +0x842, +0x824, +0x806, +0x7E8, +0x7CB, +0x7AF, +0x792, +0x777, +0x75B, +0x740, +0x726, +0x70B, +0x6F2, +0x6D8, +0x6BF, +0x6A6, +0x68E, +0x676, +0x65E, +0x647, +0x630, +0x619, +0x602, +0x5EC, +0x5D7, +0x5C1, +0x5AC, +0x597, +0x583, +0x56E, +0x55B, +0x547, +0x533, +0x520, +0x50E, +0x4FB, +0x4E9, +0x4D7, +0x4C5, +0x4B3, +0x4A2, +0x491, +0x480, +0x470, +0x460, +0x450, +0x440, +0x430, +0x421, +0x412, +0x403, +0x3F4, +0x3E5, +0x3D7, +0x3C9, +0x3BB, +0x3AD, +0x3A0, +0x393, +0x385, +0x379, +0x36C, +0x35F, +0x353, +0x347, +0x33B, +0x32F, +0x323, +0x318, +0x30C, +0x301, +0x2F6, +0x2EB, +0x2E0, +0x2D6, +0x2CB, +0x2C1, +0x2B7, +0x2AD, +0x2A3, +0x299, +0x290, +0x287, +0x27D, +0x274, +0x26B, +0x262, +0x259, +0x251, +0x248, +0x240, +0x238, +0x230, +0x228, +0x220, +0x218, +0x210, +0x209, +0x201, +0x1FA, +0x1F2, +0x1EB, +0x1E4, +0x1DD, +0x1D6, +0x1D0, +0x1C9, +0x1C2, +0x1BC, +0x1B6, +0x1AF, +0x1A9, +0x1A3, +0x19D, +0x197, +0x191, +0x18C, +0x186, +0x180, +0x17B, +0x175, +0x170, +0x16B, +0x165, +0x160, +0x15B, +0x156, +0x151, +0x14C, +0x148, +0x143, +0x13E, +0x13A, +0x135, +0x131, +0x12C, +0x128, +0x124, +0x120, +0x11C, +0x118, +0x114, +0x110, +0x10C, +0x108, +0x104, +0x100, +0xFD, +0xF9, +0xF5, +0xF2, +0xEE +};
\ No newline at end of file diff --git a/quantum/musical_notes.h b/quantum/audio/musical_notes.h index 837f6a069..b08d16a6f 100644 --- a/quantum/musical_notes.h +++ b/quantum/audio/musical_notes.h @@ -2,22 +2,38 @@ #define MUSICAL_NOTES_H // Tempo Placeholder -#define TEMPO 120 +#define TEMPO_DEFAULT 100 + + +#define SONG(notes...) { notes } // Note Types -#define WHOLE_NOTE(note) {(NOTE##note), 64} -#define HALF_NOTE(note) {(NOTE##note), 32} -#define QUARTER_NOTE(note) {(NOTE##note), 16} -#define EIGHTH_NOTE(note) {(NOTE##note), 8} -#define SIXTEENTH_NOTE(note) {(NOTE##note), 4} - -// Note Types Short -#define W_NOTE(n) WHOLE_NOTE(n) -#define H_NOTE(n) HALF_NOTE(n) -#define Q_NOTE(n) QUARTER_NOTE(n) -#define E_NOTE(n) EIGTH_NOTE(n) -#define S_NOTE(n) SIXTEENTH_NOTE(n) +#define MUSICAL_NOTE(note, duration) {(NOTE##note), duration} +#define WHOLE_NOTE(note) MUSICAL_NOTE(note, 64) +#define HALF_NOTE(note) MUSICAL_NOTE(note, 32) +#define QUARTER_NOTE(note) MUSICAL_NOTE(note, 16) +#define EIGHTH_NOTE(note) MUSICAL_NOTE(note, 8) +#define SIXTEENTH_NOTE(note) MUSICAL_NOTE(note, 4) + +#define WHOLE_DOT_NOTE(note) MUSICAL_NOTE(note, 64+32) +#define HALF_DOT_NOTE(note) MUSICAL_NOTE(note, 32+16) +#define QUARTER_DOT_NOTE(note) MUSICAL_NOTE(note, 16+8) +#define EIGHTH_DOT_NOTE(note) MUSICAL_NOTE(note, 8+4) +#define SIXTEENTH_DOT_NOTE(note) MUSICAL_NOTE(note, 4+2) + +// Note Type Shortcuts +#define M__NOTE(note, duration) MUSICAL_NOTE(note, duration) +#define W__NOTE(n) WHOLE_NOTE(n) +#define H__NOTE(n) HALF_NOTE(n) +#define Q__NOTE(n) QUARTER_NOTE(n) +#define E__NOTE(n) EIGHTH_NOTE(n) +#define S__NOTE(n) SIXTEENTH_NOTE(n) +#define WD_NOTE(n) WHOLE_DOT_NOTE(n) +#define HD_NOTE(n) HALF_DOT_NOTE(n) +#define QD_NOTE(n) QUARTER_DOT_NOTE(n) +#define ED_NOTE(n) EIGHTH_DOT_NOTE(n) +#define SD_NOTE(n) SIXTEENTH_DOT_NOTE(n) // Note Styles // Staccato makes sure there is a rest between each note. Think: TA TA TA @@ -25,8 +41,20 @@ #define STACCATO 0.01 #define LEGATO 0 +// Note Timbre +// Changes how the notes sound +#define TIMBRE_12 0.125 +#define TIMBRE_25 0.250 +#define TIMBRE_50 0.500 +#define TIMBRE_75 0.750 +#define TIMBRE_DEFAULT TIMBRE_50 + + // 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 @@ -50,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/audio/song_list.h b/quantum/audio/song_list.h new file mode 100644 index 000000000..fc6fcdeef --- /dev/null +++ b/quantum/audio/song_list.h @@ -0,0 +1,117 @@ +#include "musical_notes.h" + +#ifndef SONG_LIST_H +#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), + +#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 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 PLOVER_SOUND \ + E__NOTE(_GS6 ), \ + E__NOTE(_A6 ), \ + S__NOTE(_REST), \ + ED_NOTE(_E7 ), \ + S__NOTE(_REST), \ + ED_NOTE(_A7 ), + +#define PLOVER_GOODBYE_SOUND \ + E__NOTE(_GS6 ), \ + E__NOTE(_A6 ), \ + S__NOTE(_REST), \ + ED_NOTE(_A7 ), \ + S__NOTE(_REST), \ + ED_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 diff --git a/quantum/audio/vibrato_lut.h b/quantum/audio/vibrato_lut.h new file mode 100644 index 000000000..a2b1f3e5c --- /dev/null +++ b/quantum/audio/vibrato_lut.h @@ -0,0 +1,28 @@ +#include <avr/io.h> +#include <avr/interrupt.h> +#include <avr/pgmspace.h> + +#define VIBRATO_LUT_LENGTH 20 + +const float VIBRATO_LUT[VIBRATO_LUT_LENGTH] = { \ +1.00223368114872, +1.00425299436105, +1.00585842560279, +1.00689052852052, +1.0072464122237, +1.00689052852052, +1.00585842560279, +1.00425299436105, +1.00223368114872, +1, +0.99777129706302, +0.99576501699778, +0.994175695650927, +0.993156625943589, +0.992805720491269, +0.993156625943589, +0.994175695650927, +0.99576501699778, +0.99777129706302, +1 +};
\ No newline at end of file diff --git a/quantum/audio/voices.c b/quantum/audio/voices.c new file mode 100644 index 000000000..d2316ba1b --- /dev/null +++ b/quantum/audio/voices.c @@ -0,0 +1,163 @@ +#include "voices.h" +#include "stdlib.h" +#include "vibrato_lut.h" + +// these are imported from audio.c +extern uint16_t envelope_index; +extern float note_timbre; +extern float polyphony_rate; + +voice_type voice = default_voice; + +void set_voice(voice_type v) { + voice = v; +} + +void voice_iterate() { + voice = (voice + 1) % number_of_voices; +} + +void voice_deiterate() { + voice = (voice - 1) % number_of_voices; +} + +float voice_envelope(float frequency) { + // envelope_index ranges from 0 to 0xFFFF, which is preserved at 880.0 Hz + uint16_t compensated_index = (uint16_t)((float)envelope_index * (880.0 / frequency)); + + switch (voice) { + case default_voice: + note_timbre = TIMBRE_50; + polyphony_rate = 0; + break; + + case butts_fader: + polyphony_rate = 0; + switch (compensated_index) { + case 0 ... 9: + frequency = frequency / 4; + note_timbre = TIMBRE_12; + break; + + case 10 ... 19: + frequency = frequency / 2; + note_timbre = TIMBRE_12; + break; + + case 20 ... 200: + note_timbre = .125 - pow(((float)compensated_index - 20) / (200 - 20), 2)*.125; + break; + + default: + note_timbre = 0; + break; + } + break; + + // case octave_crunch: + // polyphony_rate = 0; + // switch (compensated_index) { + // case 0 ... 9: + // case 20 ... 24: + // case 30 ... 32: + // frequency = frequency / 2; + // note_timbre = TIMBRE_12; + // break; + + // case 10 ... 19: + // case 25 ... 29: + // case 33 ... 35: + // frequency = frequency * 2; + // note_timbre = TIMBRE_12; + // break; + + // default: + // note_timbre = TIMBRE_12; + // break; + // } + // break; + + case duty_osc: + // This slows the loop down a substantial amount, so higher notes may freeze + polyphony_rate = 0; + switch (compensated_index) { + default: + #define OCS_SPEED 10 + #define OCS_AMP .25 + // sine wave is slow + // note_timbre = (sin((float)compensated_index/10000*OCS_SPEED) * OCS_AMP / 2) + .5; + // triangle wave is a bit faster + note_timbre = (float)abs((compensated_index*OCS_SPEED % 3000) - 1500) * ( OCS_AMP / 1500 ) + (1 - OCS_AMP) / 2; + break; + } + break; + + case duty_octave_down: + polyphony_rate = 0; + note_timbre = (envelope_index % 2) * .125 + .375 * 2; + if ((envelope_index % 4) == 0) + note_timbre = 0.5; + if ((envelope_index % 8) == 0) + note_timbre = 0; + break; + case delayed_vibrato: + polyphony_rate = 0; + note_timbre = TIMBRE_50; + #define VOICE_VIBRATO_DELAY 150 + #define VOICE_VIBRATO_SPEED 50 + switch (compensated_index) { + case 0 ... VOICE_VIBRATO_DELAY: + break; + default: + frequency = frequency * VIBRATO_LUT[(int)fmod((((float)compensated_index - (VOICE_VIBRATO_DELAY + 1))/1000*VOICE_VIBRATO_SPEED), VIBRATO_LUT_LENGTH)]; + break; + } + break; + // case delayed_vibrato_octave: + // polyphony_rate = 0; + // if ((envelope_index % 2) == 1) { + // note_timbre = 0.55; + // } else { + // note_timbre = 0.45; + // } + // #define VOICE_VIBRATO_DELAY 150 + // #define VOICE_VIBRATO_SPEED 50 + // switch (compensated_index) { + // case 0 ... VOICE_VIBRATO_DELAY: + // break; + // default: + // frequency = frequency * VIBRATO_LUT[(int)fmod((((float)compensated_index - (VOICE_VIBRATO_DELAY + 1))/1000*VOICE_VIBRATO_SPEED), VIBRATO_LUT_LENGTH)]; + // break; + // } + // break; + // case duty_fifth_down: + // note_timbre = 0.5; + // if ((envelope_index % 3) == 0) + // note_timbre = 0.75; + // break; + // case duty_fourth_down: + // note_timbre = 0.0; + // if ((envelope_index % 12) == 0) + // note_timbre = 0.75; + // if (((envelope_index % 12) % 4) != 1) + // note_timbre = 0.75; + // break; + // case duty_third_down: + // note_timbre = 0.5; + // if ((envelope_index % 5) == 0) + // note_timbre = 0.75; + // break; + // case duty_fifth_third_down: + // note_timbre = 0.5; + // if ((envelope_index % 5) == 0) + // note_timbre = 0.75; + // if ((envelope_index % 3) == 0) + // note_timbre = 0.25; + // break; + + default: + break; + } + + return frequency; +}
\ No newline at end of file diff --git a/quantum/audio/voices.h b/quantum/audio/voices.h new file mode 100644 index 000000000..74c873f42 --- /dev/null +++ b/quantum/audio/voices.h @@ -0,0 +1,32 @@ +#include <stdint.h> +#include <stdbool.h> +#include <avr/io.h> +#include <util/delay.h> +#include "musical_notes.h" +#include "song_list.h" + +#ifndef VOICES_H +#define VOICES_H + +float voice_envelope(float frequency); + +typedef enum { + default_voice, + butts_fader, + octave_crunch, + duty_osc, + duty_octave_down, + delayed_vibrato, + // delayed_vibrato_octave, + // duty_fifth_down, + // duty_fourth_down, + // duty_third_down, + // duty_fifth_third_down, + number_of_voices // important that this is last +} voice_type; + +void set_voice(voice_type v); +void voice_iterate(void); +void voice_deiterate(void); + +#endif
\ No newline at end of file diff --git a/quantum/wave.h b/quantum/audio/wave.h index 6ebc34851..6ebc34851 100644 --- a/quantum/wave.h +++ b/quantum/audio/wave.h diff --git a/quantum/keymap_common.c b/quantum/keymap_common.c index d38e6fdb2..4b4bd6210 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/>. #include "backlight.h" #include "keymap_midi.h" #include "bootloader.h" +#include "eeconfig.h" extern keymap_config_t keymap_config; @@ -33,22 +34,14 @@ extern keymap_config_t keymap_config; #include <inttypes.h> #ifdef AUDIO_ENABLE #include "audio.h" - #ifndef TONE_GOODBYE - #define TONE_GOODBYE { \ - {440.0*pow(2.0,(31)/12.0), 8}, \ - {440.0*pow(2.0,(24)/12.0), 8}, \ - {440.0*pow(2.0,(19)/12.0), 12}, \ - } - #endif - float tone_goodbye[][2] = TONE_GOODBYE; -#endif +#endif /* AUDIO_ENABLE */ 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) { @@ -191,7 +184,8 @@ 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); + stop_all_notes(); + play_goodbye_tone(); #endif _delay_ms(250); #ifdef ATREUS_ASTAR @@ -251,7 +245,7 @@ static action_t keycode_to_action(uint16_t keycode) keymap_config.swap_lalt_lgui = 0; keymap_config.swap_ralt_rgui = 0; } - eeconfig_write_keymap(keymap_config.raw); + eeconfig_update_keymap(keymap_config.raw); break; case 0x5100 ... 0x5FFF: ; // Layer movement shortcuts @@ -304,7 +298,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)]); } @@ -316,7 +310,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/keymap_common.h b/quantum/keymap_common.h index ce87e4770..0ede0296b 100644 --- a/quantum/keymap_common.h +++ b/quantum/keymap_common.h @@ -213,7 +213,7 @@ extern const uint16_t fn_actions[]; #define GUI_T(kc) MT(0x8, kc) #define C_S_T(kc) MT(0x3, kc) // Control + Shift e.g. for gnome-terminal #define MEH_T(kc) MT(0x7, kc) // Meh is a less hyper version of the Hyper key -- doesn't include Win or Cmd, so just alt+shift+ctrl -#define LCAG_T(kc) MT(0xD, kc) // Left control alt and gui +#define LCAG_T(kc) MT(0xD, kc) // Left control alt and gui #define ALL_T(kc) MT(0xF, kc) // see http://brettterpstra.com/2012/12/08/a-useful-caps-lock-key/ // Dedicated keycode versions for Hyper and Meh, if you want to use them as standalone keys rather than mod-tap @@ -231,8 +231,8 @@ extern const uint16_t fn_actions[]; // For tri-layer void update_tri_layer(uint8_t layer1, uint8_t layer2, uint8_t layer3); -#define IS_LAYER_ON(layer) ((layer_state) & (1UL<<(layer))) -#define IS_LAYER_OFF(layer) ((!layer_state) & (1UL<<(layer))) +#define IS_LAYER_ON(layer) (layer_state & (1UL << (layer))) +#define IS_LAYER_OFF(layer) (~layer_state & (1UL << (layer))) #endif diff --git a/quantum/keymap_extras/keymap_german_osx.h b/quantum/keymap_extras/keymap_german_osx.h index d0b77fb80..ee725bad5 100644 --- a/quantum/keymap_extras/keymap_german_osx.h +++ b/quantum/keymap_extras/keymap_german_osx.h @@ -85,8 +85,8 @@ #define DE_OSX_UNDS LSFT(DE_OSX_MINS) // _ // Alt-ed characters -#define DE_OSX_SQ2 LALT(KC_2) // ² -#define DE_OSX_SQ3 LALT(KC_3) // ³ +//#define DE_OSX_SQ2 LALT(KC_2) // ² +//#define DE_OSX_SQ3 LALT(KC_3) // ³ #define DE_OSX_LCBR LALT(KC_8) // { #define DE_OSX_LBRC LALT(KC_5) // [ #define DE_OSX_RBRC LALT(KC_6) // ] diff --git a/quantum/keymap_extras/keymap_plover.h b/quantum/keymap_extras/keymap_plover.h new file mode 100644 index 000000000..98e57ab7b --- /dev/null +++ b/quantum/keymap_extras/keymap_plover.h @@ -0,0 +1,32 @@ +#ifndef KEYMAP_PLOVER_H +#define KEYMAP_PLOVER_H + +#include "keymap_common.h" + +#define PV_NUM KC_1 +#define PV_LS KC_Q +#define PV_LT KC_W +#define PV_LP KC_E +#define PV_LH KC_R +#define PV_LK KC_S +#define PV_LW KC_D +#define PV_LR KC_F + +#define PV_STAR KC_Y +#define PV_RF KC_U +#define PV_RP KC_I +#define PV_RL KC_O +#define PV_RT KC_P +#define PV_RD KC_LBRC +#define PV_RR KC_J +#define PV_RB KC_K +#define PV_RG KC_L +#define PV_RS KC_SCLN +#define PV_RZ KC_QUOT + +#define PV_A KC_C +#define PV_O KC_V +#define PV_E KC_N +#define PV_U KC_M + +#endif diff --git a/quantum/led.c b/quantum/led.c index 9cdb8a5c2..208e348f3 100644 --- a/quantum/led.c +++ b/quantum/led.c @@ -24,6 +24,7 @@ void led_set_kb(uint8_t usb_led) { } +__attribute__ ((weak)) void led_set(uint8_t usb_led) { diff --git a/quantum/quantum.mk b/quantum/quantum.mk index 1fe7390eb..83c4f1d1d 100644 --- a/quantum/quantum.mk +++ b/quantum/quantum.mk @@ -28,7 +28,7 @@ ifeq ($(strip $(MIDI_ENABLE)), yes) endif ifeq ($(strip $(AUDIO_ENABLE)), yes) - SRC += $(QUANTUM_DIR)/audio.c + SRC += $(QUANTUM_DIR)/audio/audio.c $(QUANTUM_DIR)/audio/voices.c endif ifeq ($(strip $(UNICODE_ENABLE)), yes) @@ -47,6 +47,7 @@ endif # Search Path VPATH += $(TOP_DIR)/$(QUANTUM_DIR) VPATH += $(TOP_DIR)/$(QUANTUM_DIR)/keymap_extras +VPATH += $(TOP_DIR)/$(QUANTUM_DIR)/audio include $(TMK_DIR)/protocol/lufa.mk diff --git a/quantum/rgblight.c b/quantum/rgblight.c index 2215cf5cd..8c9ad7736 100644 --- a/quantum/rgblight.c +++ b/quantum/rgblight.c @@ -107,17 +107,17 @@ void setrgb(uint8_t r, uint8_t g, uint8_t b, struct cRGB *led1) { uint32_t eeconfig_read_rgblight(void) { return eeprom_read_dword(EECONFIG_RGBLIGHT); } -void eeconfig_write_rgblight(uint32_t val) { - eeprom_write_dword(EECONFIG_RGBLIGHT, val); +void eeconfig_update_rgblight(uint32_t val) { + eeprom_update_dword(EECONFIG_RGBLIGHT, val); } -void eeconfig_write_rgblight_default(void) { - dprintf("eeconfig_write_rgblight_default\n"); +void eeconfig_update_rgblight_default(void) { + dprintf("eeconfig_update_rgblight_default\n"); rgblight_config.enable = 1; rgblight_config.mode = 1; rgblight_config.hue = 200; rgblight_config.sat = 204; rgblight_config.val = 204; - eeconfig_write_rgblight(rgblight_config.raw); + eeconfig_update_rgblight(rgblight_config.raw); } void eeconfig_debug_rgblight(void) { dprintf("rgblight_config eprom\n"); @@ -136,12 +136,12 @@ void rgblight_init(void) { if (!eeconfig_is_enabled()) { dprintf("rgblight_init eeconfig is not enabled.\n"); eeconfig_init(); - eeconfig_write_rgblight_default(); + eeconfig_update_rgblight_default(); } rgblight_config.raw = eeconfig_read_rgblight(); if (!rgblight_config.mode) { dprintf("rgblight_init rgblight_config.mode = 0. Write default values to EEPROM.\n"); - eeconfig_write_rgblight_default(); + eeconfig_update_rgblight_default(); rgblight_config.raw = eeconfig_read_rgblight(); } eeconfig_debug_rgblight(); // display current eeprom values @@ -189,8 +189,8 @@ void rgblight_mode(uint8_t mode) { } else { rgblight_config.mode = mode; } - eeconfig_write_rgblight(rgblight_config.raw); - dprintf("rgblight mode: %u\n", rgblight_config.mode); + eeconfig_update_rgblight(rgblight_config.raw); + xprintf("rgblight mode: %u\n", rgblight_config.mode); if (rgblight_config.mode == 1) { rgblight_timer_disable(); } else if (rgblight_config.mode >=2 && rgblight_config.mode <=23) { @@ -206,8 +206,8 @@ void rgblight_mode(uint8_t mode) { void rgblight_toggle(void) { rgblight_config.enable ^= 1; - eeconfig_write_rgblight(rgblight_config.raw); - dprintf("rgblight toggle: rgblight_config.enable = %u\n", rgblight_config.enable); + eeconfig_update_rgblight(rgblight_config.raw); + xprintf("rgblight toggle: rgblight_config.enable = %u\n", rgblight_config.enable); if (rgblight_config.enable) { rgblight_mode(rgblight_config.mode); } else { @@ -299,8 +299,8 @@ void rgblight_sethsv(uint16_t hue, uint8_t sat, uint8_t val){ rgblight_config.hue = hue; rgblight_config.sat = sat; rgblight_config.val = val; - eeconfig_write_rgblight(rgblight_config.raw); - dprintf("rgblight set hsv [EEPROM]: %u,%u,%u\n", rgblight_config.hue, rgblight_config.sat, rgblight_config.val); + eeconfig_update_rgblight(rgblight_config.raw); + xprintf("rgblight set hsv [EEPROM]: %u,%u,%u\n", rgblight_config.hue, rgblight_config.sat, rgblight_config.val); } } diff --git a/quantum/rgblight.h b/quantum/rgblight.h index 9e1562328..37e207578 100644 --- a/quantum/rgblight.h +++ b/quantum/rgblight.h @@ -66,8 +66,8 @@ void rgblight_setrgb(uint8_t r, uint8_t g, uint8_t b); #define EECONFIG_RGBLIGHT (uint8_t *)7 uint32_t eeconfig_read_rgblight(void); -void eeconfig_write_rgblight(uint32_t val); -void eeconfig_write_rgblight_default(void); +void eeconfig_update_rgblight(uint32_t val); +void eeconfig_update_rgblight_default(void); void eeconfig_debug_rgblight(void); void sethsv(uint16_t hue, uint8_t sat, uint8_t val, struct cRGB *led1); diff --git a/quantum/template/Makefile b/quantum/template/Makefile index 4fa195468..1a535ef2c 100644 --- a/quantum/template/Makefile +++ b/quantum/template/Makefile @@ -111,23 +111,41 @@ OPT_DEFS += -DBOOTLOADER_SIZE=512 # Build Options -# comment out to disable the options. -# -BOOTMAGIC_ENABLE = yes # Virtual DIP switch configuration(+1000) -MOUSEKEY_ENABLE = yes # Mouse keys(+4700) -EXTRAKEY_ENABLE = yes # Audio control and System control(+450) -CONSOLE_ENABLE = yes # Console for debug(+400) -COMMAND_ENABLE = yes # Commands for debug and configuration -KEYBOARD_LOCK_ENABLE = yes # Allow locking of keyboard via magic key +# change yes to no to disable +# +BOOTMAGIC_ENABLE = yes # Virtual DIP switch configuration(+1000) +MOUSEKEY_ENABLE = yes # Mouse keys(+4700) +EXTRAKEY_ENABLE = yes # Audio control and System control(+450) +CONSOLE_ENABLE = yes # Console for debug(+400) +COMMAND_ENABLE = yes # Commands for debug and configuration +KEYBOARD_LOCK_ENABLE = yes # Allow locking of keyboard via magic key # Do not enable SLEEP_LED_ENABLE. it uses the same timer as BACKLIGHT_ENABLE -# SLEEP_LED_ENABLE = yes # Breathing sleep LED during USB suspend -#NKRO_ENABLE = yes # USB Nkey Rollover - if this doesn't work, see here: https://github.com/tmk/tmk_keyboard/wiki/FAQ#nkro-doesnt-work -# BACKLIGHT_ENABLE = yes # Enable keyboard backlight functionality -# MIDI_ENABLE = YES # MIDI controls -# UNICODE_ENABLE = YES # Unicode -# BLUETOOTH_ENABLE = yes # Enable Bluetooth with the Adafruit EZ-Key HID +SLEEP_LED_ENABLE = no # Breathing sleep LED during USB suspend +# if this doesn't work, see here: https://github.com/tmk/tmk_keyboard/wiki/FAQ#nkro-doesnt-work +NKRO_ENABLE = no # USB Nkey Rollover +BACKLIGHT_ENABLE = yes # Enable keyboard backlight functionality +MIDI_ENABLE = no # MIDI controls +UNICODE_ENABLE = no # Unicode +BLUETOOTH_ENABLE = no # Enable Bluetooth with the Adafruit EZ-Key HID +AUDIO_ENABLE = no # Audio output on port C6 +ifdef KEYMAP + +ifeq ("$(wildcard keymaps/$(KEYMAP).c)","") +ifneq ("$(wildcard keymaps/$(KEYMAP)/makefile.mk)","") + include keymaps/$(KEYMAP)/makefile.mk +endif +endif + +else + +ifneq ("$(wildcard keymaps/default/makefile.mk)","") + include keymaps/default/makefile.mk +endif + +endif + # Optimize size but this may cause error "relocation truncated to fit" #EXTRALDFLAGS = -Wl,--relax diff --git a/quantum/template/template.c b/quantum/template/template.c index cc52e496f..6050a2d20 100644 --- a/quantum/template/template.c +++ b/quantum/template/template.c @@ -46,3 +46,64 @@ void led_set_kb(uint8_t usb_led) { led_set_user(usb_led); } + +#ifdef BACKLIGHT_ENABLE +#define CHANNEL OCR1C + +void backlight_init_ports() +{ + + // Setup PB7 as output and output low. + DDRB |= (1<<7); + PORTB &= ~(1<<7); + + // Use full 16-bit resolution. + ICR1 = 0xFFFF; + + // I could write a wall of text here to explain... but TL;DW + // Go read the ATmega32u4 datasheet. + // And this: http://blog.saikoled.com/post/43165849837/secret-konami-cheat-code-to-high-resolution-pwm-on + + // Pin PB7 = OCR1C (Timer 1, Channel C) + // Compare Output Mode = Clear on compare match, Channel C = COM1C1=1 COM1C0=0 + // (i.e. start high, go low when counter matches.) + // WGM Mode 14 (Fast PWM) = WGM13=1 WGM12=1 WGM11=1 WGM10=0 + // Clock Select = clk/1 (no prescaling) = CS12=0 CS11=0 CS10=1 + + TCCR1A = _BV(COM1C1) | _BV(WGM11); // = 0b00001010; + TCCR1B = _BV(WGM13) | _BV(WGM12) | _BV(CS10); // = 0b00011001; + + backlight_init(); +} + +void backlight_set(uint8_t level) +{ + if ( level == 0 ) + { + // Turn off PWM control on PB7, revert to output low. + TCCR1A &= ~(_BV(COM1C1)); + CHANNEL = 0x0; + // Prevent backlight blink on lowest level + PORTB &= ~(_BV(PORTB7)); + } + else if ( level == BACKLIGHT_LEVELS ) + { + // Prevent backlight blink on lowest level + PORTB &= ~(_BV(PORTB7)); + // Turn on PWM control of PB7 + TCCR1A |= _BV(COM1C1); + // Set the brightness + CHANNEL = 0xFFFF; + } + else + { + // Prevent backlight blink on lowest level + PORTB &= ~(_BV(PORTB7)); + // Turn on PWM control of PB7 + TCCR1A |= _BV(COM1C1); + // Set the brightness + CHANNEL = 0xFFFF >> ((BACKLIGHT_LEVELS - level) * ((BACKLIGHT_LEVELS + 1) / 2)); + } +} + +#endif
\ No newline at end of file diff --git a/quantum/template/template.h b/quantum/template/template.h index b1c34d3cb..22742105a 100644 --- a/quantum/template/template.h +++ b/quantum/template/template.h @@ -3,7 +3,10 @@ #include "matrix.h" #include "keymap_common.h" -#include "backlight.h" +#ifdef BACKLIGHT_ENABLE + #include "backlight.h" +#endif +#include <avr/io.h> #include <stddef.h> // This a shortcut to help you visually see your layout. |