diff options
Diffstat (limited to 'quantum')
-rw-r--r-- | quantum/audio.c | 136 | ||||
-rw-r--r-- | quantum/audio.h | 21 | ||||
-rw-r--r-- | quantum/vibrato_lut.h | 82 |
3 files changed, 97 insertions, 142 deletions
diff --git a/quantum/audio.c b/quantum/audio.c index bbdbc824c9..ab3444bc97 100644 --- a/quantum/audio.c +++ b/quantum/audio.c @@ -10,20 +10,23 @@ #include "eeconfig.h" -#include "vibrato_lut.h" +#ifdef VIBRATO_ENABLE + #include "vibrato_lut.h" +#endif #define PI 3.14159265 #define CPU_PRESCALER 8 -// Largely untested PWM audio mode (doesn't sound as good) -// #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) { @@ -34,25 +37,21 @@ void delay_us(int count) { int voices = 0; int voice_place = 0; -double frequency = 0; +float frequency = 0; int volume = 0; long position = 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; -double freq = 0; +// float freq = 0; bool notes = false; bool note = false; @@ -62,7 +61,7 @@ float note_tempo = TEMPO_DEFAULT; float note_timbre = TIMBRE_DEFAULT; uint16_t note_position = 0; float (* notes_pointer)[][2]; -uint8_t notes_count; +uint16_t notes_count; bool notes_repeat; float notes_rest; bool note_resting = false; @@ -70,9 +69,11 @@ 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; @@ -96,6 +97,7 @@ void audio_off(void) { eeconfig_write_audio(audio_config.raw); } +#ifdef VIBRATO_ENABLE // Vibrato rate functions void set_vibrato_rate(float rate) { @@ -126,6 +128,8 @@ void decrease_vibrato_strength(float change) { #endif +#endif + // Polyphony functions void set_polyphony_rate(float rate) { @@ -209,6 +213,7 @@ void audio_init() { #endif inited = true; + _delay_ms(500); } void stop_all_notes() { @@ -233,7 +238,7 @@ void stop_all_notes() { } } -void stop_note(double freq) { +void stop_note(float freq) { if (note) { if (!inited) { audio_init(); @@ -274,6 +279,8 @@ void stop_note(double freq) { } } +#ifdef VIBRATO_ENABLE + float mod(float a, int b) { float r = fmod(a, b); @@ -290,6 +297,8 @@ float vibrato(float average_freq) { return vibrated_freq; } +#endif + ISR(TIMER3_COMPA_vect) { if (note) { #ifdef PWM_AUDIO @@ -341,6 +350,7 @@ ISR(TIMER3_COMPA_vect) { } #else if (voices > 0) { + float freq; if (polyphony_rate > 0) { if (voices > 1) { voice_place %= voices; @@ -349,9 +359,13 @@ ISR(TIMER3_COMPA_vect) { place = 0.0; } } + #ifdef VIBRATO_ENABLE if (vibrato_strength > 0) { freq = vibrato(frequencies[voice_place]); } else { + #else + { + #endif freq = frequencies[voice_place]; } } else { @@ -363,9 +377,14 @@ ISR(TIMER3_COMPA_vect) { frequency = frequencies[voices - 1]; } + + #ifdef VIBRATO_ENABLE if (vibrato_strength > 0) { freq = vibrato(frequency); } else { + #else + { + #endif freq = frequency; } } @@ -398,9 +417,13 @@ ISR(TIMER3_COMPA_vect) { if (note_frequency > 0) { float freq; + #ifdef VIBRATO_ENABLE if (vibrato_strength > 0) { freq = vibrato(note_frequency); } else { + #else + { + #endif freq = note_frequency; } @@ -461,13 +484,45 @@ ISR(TIMER3_COMPA_vect) { } } -void play_notes(float (*np)[][2], uint8_t n_count, 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; + #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(); @@ -500,57 +555,24 @@ if (audio_config.enable) { } +#ifdef PWM_AUDIO void play_sample(uint8_t * s, uint16_t l, bool r) { - -if (audio_config.enable) { - TIMSK3 &= ~_BV(OCIE3A); if (!inited) { audio_init(); } - stop_all_notes(); - place_int = 0; - sample = s; - sample_length = l; - repeat = r; - #ifdef PWM_AUDIO - TIMSK3 |= _BV(OCIE3A); - #else - #endif - -} - -} - -void play_note(double freq, int vol) { - -if (audio_config.enable && voices < 8) { - TIMSK3 &= ~_BV(OCIE3A); - if (!inited) { - audio_init(); - } - // Cancel notes if notes are playing - if (notes) + if (audio_config.enable) { + TIMSK3 &= ~_BV(OCIE3A); stop_all_notes(); - note = true; - #ifdef PWM_AUDIO - freq = freq / SAMPLE_RATE; - #endif - if (freq > 0) { - frequencies[voices] = freq; - volumes[voices] = vol; - voices++; - } + place_int = 0; + sample = s; + sample_length = l; + repeat = r; - #ifdef PWM_AUDIO TIMSK3 |= _BV(OCIE3A); - #else - TIMSK3 |= _BV(OCIE3A); - TCCR3A |= _BV(COM3A1); - #endif -} - + } } +#endif //------------------------------------------------------------------------------ // Override these functions in your keymap file to play different tunes on diff --git a/quantum/audio.h b/quantum/audio.h index 0fe3eac9af..2d4d303ced 100644 --- a/quantum/audio.h +++ b/quantum/audio.h @@ -8,6 +8,11 @@ #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 @@ -25,6 +30,8 @@ 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); @@ -37,6 +44,8 @@ void decrease_vibrato_strength(float change); #endif +#endif + // Polyphony functions void set_polyphony_rate(float rate); @@ -51,11 +60,15 @@ void set_tempo(float tempo); void increase_tempo(uint8_t tempo_change); void decrease_tempo(uint8_t tempo_change); +void audio_init(); + +#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 play_notes(float (*np)[][2], uint8_t n_count, 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), \ @@ -66,7 +79,7 @@ void play_notes(float (*np)[][2], uint8_t n_count, 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); diff --git a/quantum/vibrato_lut.h b/quantum/vibrato_lut.h index 4c267a626a..a2b1f3e5ce 100644 --- a/quantum/vibrato_lut.h +++ b/quantum/vibrato_lut.h @@ -2,107 +2,27 @@ #include <avr/interrupt.h> #include <avr/pgmspace.h> -#define VIBRATO_LUT_LENGTH 100 +#define VIBRATO_LUT_LENGTH 20 const float VIBRATO_LUT[VIBRATO_LUT_LENGTH] = { \ -1.00045346811453, -1.00090535101508, -1.00135386178926, -1.00179722447259, 1.00223368114872, -1.0026614990145, -1.00307897737994, -1.00348445457284, -1.00387631471807, 1.00425299436105, -1.00461298890553, -1.00495485883603, -1.00527723569589, -1.00557882779254, 1.00585842560279, -1.00611490685176, -1.00634724124066, -1.00655449479987, -1.00673583384565, 1.00689052852052, -1.00701795589922, -1.00711760264454, -1.0071890671992, -1.00723206150266, 1.0072464122237, -1.00723206150266, -1.0071890671992, -1.00711760264454, -1.00701795589922, 1.00689052852052, -1.00673583384565, -1.00655449479987, -1.00634724124066, -1.00611490685176, 1.00585842560279, -1.00557882779254, -1.00527723569589, -1.00495485883603, -1.00461298890553, 1.00425299436105, -1.00387631471807, -1.00348445457284, -1.00307897737994, -1.0026614990145, 1.00223368114872, -1.00179722447259, -1.00135386178926, -1.00090535101508, -1.00045346811453, 1, -0.999546737425598, -0.999095467903976, -0.998647968674285, -0.998205999748565, 0.99777129706302, -0.997345565759612, -0.996930473622346, -0.996527644691494, -0.996138653077835, 0.99576501699778, -0.995408193048995, -0.995069570744927, -0.994750467325326, -0.994452122858643, 0.994175695650927, -0.993922257974591, -0.99369279212925, -0.993488186845591, -0.993309234042139, 0.993156625943589, -0.993030952568311, -0.99293269959154, -0.992862246589715, -0.992819865670409, 0.992805720491269, -0.992819865670409, -0.992862246589715, -0.99293269959154, -0.993030952568311, 0.993156625943589, -0.993309234042139, -0.993488186845591, -0.99369279212925, -0.993922257974591, 0.994175695650927, -0.994452122858643, -0.994750467325326, -0.995069570744927, -0.995408193048995, 0.99576501699778, -0.996138653077835, -0.996527644691494, -0.996930473622346, -0.997345565759612, 0.99777129706302, -0.998205999748565, -0.998647968674285, -0.999095467903976, -0.999546737425598, 1 };
\ No newline at end of file |