diff options
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. | 
