fixed startup audio with a 500ms delay

master
Jack Humbert 2016-04-20 01:08:17 -04:00
parent 462601f5e8
commit de4690593c
6 changed files with 106 additions and 183 deletions

View File

@ -364,7 +364,6 @@ void process_action_user(keyrecord_t *record) {
void matrix_init_user(void) { void matrix_init_user(void) {
#ifdef AUDIO_ENABLE #ifdef AUDIO_ENABLE
init_notes();
PLAY_NOTE_ARRAY(tone_startup, false, 0); PLAY_NOTE_ARRAY(tone_startup, false, 0);
#endif #endif
} }

View File

@ -133,7 +133,7 @@ OPT_DEFS += -DBOOTLOADER_SIZE=4096
BOOTMAGIC_ENABLE = no # Virtual DIP switch configuration(+1000) BOOTMAGIC_ENABLE = no # Virtual DIP switch configuration(+1000)
MOUSEKEY_ENABLE = yes # Mouse keys(+4700) MOUSEKEY_ENABLE = yes # Mouse keys(+4700)
EXTRAKEY_ENABLE = yes # Audio control and System control(+450) EXTRAKEY_ENABLE = yes # Audio control and System control(+450)
CONSOLE_ENABLE = no # Console for debug(+400) CONSOLE_ENABLE = on # Console for debug(+400)
COMMAND_ENABLE = yes # Commands for debug and configuration COMMAND_ENABLE = yes # Commands for debug and configuration
NKRO_ENABLE = no # Nkey Rollover - if this doesn't work, see here: https://github.com/tmk/tmk_keyboard/wiki/FAQ#nkro-doesnt-work NKRO_ENABLE = no # 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 BACKLIGHT_ENABLE = yes # Enable keyboard backlight functionality

View File

@ -3,6 +3,7 @@
#include "eeconfig.h" #include "eeconfig.h"
#ifdef AUDIO_ENABLE #ifdef AUDIO_ENABLE
#include "audio.h" #include "audio.h"
#include "song_list.h"
#endif #endif
// Each layer gets a name for readability, which is then used in the keymap matrix below. // Each layer gets a name for readability, which is then used in the keymap matrix below.
@ -189,43 +190,10 @@ float start_up[][2] = {
{440.0*pow(2.0,(26)/12.0), 8} {440.0*pow(2.0,(26)/12.0), 8}
}; };
float tone_qwerty[][2] = { float tone_qwerty[][2] = SONG(QWERTY_SOUND);
{440.0*pow(2.0,(23)/12.0), 8}, float tone_dvorak[][2] = SONG(DVORAK_SOUND);
{440.0*pow(2.0,(24)/12.0), 8}, float tone_colemak[][2] = SONG(COLEMAK_SOUND);
{0, 4},
{440.0*pow(2.0,(31)/12.0), 16}
};
float tone_colemak[][2] = {
{440.0*pow(2.0,(23)/12.0), 8},
{440.0*pow(2.0,(24)/12.0), 8},
{0, 4},
{440.0*pow(2.0,(31)/12.0), 12},
{0, 4},
{440.0*pow(2.0,(35)/12.0), 12}
};
float tone_dvorak[][2] = {
{440.0*pow(2.0,(23)/12.0), 8},
{440.0*pow(2.0,(24)/12.0), 8},
{0, 4},
{440.0*pow(2.0,(31)/12.0), 8},
{0, 4},
{440.0*pow(2.0,(33)/12.0), 8},
{0, 4},
{440.0*pow(2.0,(31)/12.0), 8}
};
float tone_music[][2] = {
{440.0*pow(2.0,(12)/12.0), 8},
{440.0*pow(2.0,(14)/12.0), 8},
{440.0*pow(2.0,(16)/12.0), 8},
{440.0*pow(2.0,(17)/12.0), 8},
{440.0*pow(2.0,(19)/12.0), 8},
{440.0*pow(2.0,(21)/12.0), 8},
{440.0*pow(2.0,(23)/12.0), 8},
{440.0*pow(2.0,(24)/12.0), 8}
};
float music_scale[][2] = SONG(MUSIC_SCALE_SOUND); float music_scale[][2] = SONG(MUSIC_SCALE_SOUND);
float goodbye[][2] = SONG(GOODBYE_SOUND); float goodbye[][2] = SONG(GOODBYE_SOUND);
#endif #endif
@ -341,12 +309,13 @@ void process_action_user(keyrecord_t *record) {
} }
void matrix_init_user(void) { void matrix_init_user(void) {
// audio_init();
play_startup_tone(); play_startup_tone();
} }
void play_startup_tone() void play_startup_tone()
{ {
PLAY_NOTE_ARRAY(start_up, false, 0); PLAY_NOTE_ARRAY(music_scale, false, 0);
} }
void play_goodbye_tone() void play_goodbye_tone()

View File

@ -10,20 +10,23 @@
#include "eeconfig.h" #include "eeconfig.h"
#include "vibrato_lut.h" #ifdef VIBRATO_ENABLE
#include "vibrato_lut.h"
#endif
#define PI 3.14159265 #define PI 3.14159265
#define CPU_PRESCALER 8 #define CPU_PRESCALER 8
// Largely untested PWM audio mode (doesn't sound as good)
// #define PWM_AUDIO
#ifdef PWM_AUDIO #ifdef PWM_AUDIO
#include "wave.h" #include "wave.h"
#define SAMPLE_DIVIDER 39 #define SAMPLE_DIVIDER 39
#define SAMPLE_RATE (2000000.0/SAMPLE_DIVIDER/2048) #define SAMPLE_RATE (2000000.0/SAMPLE_DIVIDER/2048)
// Resistor value of 1/ (2 * PI * 10nF * (2000000 hertz / SAMPLE_DIVIDER / 10)) for 10nF cap // 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 #endif
void delay_us(int count) { void delay_us(int count) {
@ -34,25 +37,21 @@ void delay_us(int count) {
int voices = 0; int voices = 0;
int voice_place = 0; int voice_place = 0;
double frequency = 0; float frequency = 0;
int volume = 0; int volume = 0;
long position = 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}; int volumes[8] = {0, 0, 0, 0, 0, 0, 0, 0};
bool sliding = false; bool sliding = false;
int max = 0xFF; int max = 0xFF;
float sum = 0; float sum = 0;
int value = 128;
float place = 0; 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; uint8_t * sample;
uint16_t sample_length = 0; uint16_t sample_length = 0;
double freq = 0; // float freq = 0;
bool notes = false; bool notes = false;
bool note = false; bool note = false;
@ -62,7 +61,7 @@ float note_tempo = TEMPO_DEFAULT;
float note_timbre = TIMBRE_DEFAULT; float note_timbre = TIMBRE_DEFAULT;
uint16_t note_position = 0; uint16_t note_position = 0;
float (* notes_pointer)[][2]; float (* notes_pointer)[][2];
uint8_t notes_count; uint16_t notes_count;
bool notes_repeat; bool notes_repeat;
float notes_rest; float notes_rest;
bool note_resting = false; bool note_resting = false;
@ -70,9 +69,11 @@ bool note_resting = false;
uint8_t current_note = 0; uint8_t current_note = 0;
uint8_t rest_counter = 0; uint8_t rest_counter = 0;
#ifdef VIBRATO_ENABLE
float vibrato_counter = 0; float vibrato_counter = 0;
float vibrato_strength = .5; float vibrato_strength = .5;
float vibrato_rate = 0.125; float vibrato_rate = 0.125;
#endif
float polyphony_rate = 0; float polyphony_rate = 0;
@ -96,6 +97,7 @@ void audio_off(void) {
eeconfig_write_audio(audio_config.raw); eeconfig_write_audio(audio_config.raw);
} }
#ifdef VIBRATO_ENABLE
// Vibrato rate functions // Vibrato rate functions
void set_vibrato_rate(float rate) { void set_vibrato_rate(float rate) {
@ -126,6 +128,8 @@ void decrease_vibrato_strength(float change) {
#endif #endif
#endif
// Polyphony functions // Polyphony functions
void set_polyphony_rate(float rate) { void set_polyphony_rate(float rate) {
@ -209,6 +213,7 @@ void audio_init() {
#endif #endif
inited = true; inited = true;
_delay_ms(500);
} }
void stop_all_notes() { 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 (note) {
if (!inited) { if (!inited) {
audio_init(); audio_init();
@ -274,6 +279,8 @@ void stop_note(double freq) {
} }
} }
#ifdef VIBRATO_ENABLE
float mod(float a, int b) float mod(float a, int b)
{ {
float r = fmod(a, b); float r = fmod(a, b);
@ -290,6 +297,8 @@ float vibrato(float average_freq) {
return vibrated_freq; return vibrated_freq;
} }
#endif
ISR(TIMER3_COMPA_vect) { ISR(TIMER3_COMPA_vect) {
if (note) { if (note) {
#ifdef PWM_AUDIO #ifdef PWM_AUDIO
@ -341,6 +350,7 @@ ISR(TIMER3_COMPA_vect) {
} }
#else #else
if (voices > 0) { if (voices > 0) {
float freq;
if (polyphony_rate > 0) { if (polyphony_rate > 0) {
if (voices > 1) { if (voices > 1) {
voice_place %= voices; voice_place %= voices;
@ -349,9 +359,13 @@ ISR(TIMER3_COMPA_vect) {
place = 0.0; place = 0.0;
} }
} }
#ifdef VIBRATO_ENABLE
if (vibrato_strength > 0) { if (vibrato_strength > 0) {
freq = vibrato(frequencies[voice_place]); freq = vibrato(frequencies[voice_place]);
} else { } else {
#else
{
#endif
freq = frequencies[voice_place]; freq = frequencies[voice_place];
} }
} else { } else {
@ -363,9 +377,14 @@ ISR(TIMER3_COMPA_vect) {
frequency = frequencies[voices - 1]; frequency = frequencies[voices - 1];
} }
#ifdef VIBRATO_ENABLE
if (vibrato_strength > 0) { if (vibrato_strength > 0) {
freq = vibrato(frequency); freq = vibrato(frequency);
} else { } else {
#else
{
#endif
freq = frequency; freq = frequency;
} }
} }
@ -398,9 +417,13 @@ ISR(TIMER3_COMPA_vect) {
if (note_frequency > 0) { if (note_frequency > 0) {
float freq; float freq;
#ifdef VIBRATO_ENABLE
if (vibrato_strength > 0) { if (vibrato_strength > 0) {
freq = vibrato(note_frequency); freq = vibrato(note_frequency);
} else { } else {
#else
{
#endif
freq = note_frequency; 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) {
TIMSK3 &= ~_BV(OCIE3A);
if (!inited) { if (!inited) {
audio_init(); 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 // Cancel note if a note is playing
if (note) if (note)
stop_all_notes(); 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) { void play_sample(uint8_t * s, uint16_t l, bool r) {
if (audio_config.enable) {
TIMSK3 &= ~_BV(OCIE3A);
if (!inited) { if (!inited) {
audio_init(); audio_init();
} }
stop_all_notes();
place_int = 0;
sample = s;
sample_length = l;
repeat = r;
#ifdef PWM_AUDIO if (audio_config.enable) {
TIMSK3 |= _BV(OCIE3A); 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)
stop_all_notes(); stop_all_notes();
note = true; place_int = 0;
#ifdef PWM_AUDIO sample = s;
freq = freq / SAMPLE_RATE; sample_length = l;
#endif repeat = r;
if (freq > 0) {
frequencies[voices] = freq; TIMSK3 |= _BV(OCIE3A);
volumes[voices] = vol;
voices++;
} }
#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 // Override these functions in your keymap file to play different tunes on

View File

@ -8,6 +8,11 @@
#ifndef AUDIO_H #ifndef AUDIO_H
#define 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 // Enable vibrato strength/amplitude - slows down ISR too much
// #define VIBRATO_STRENGTH_ENABLE // #define VIBRATO_STRENGTH_ENABLE
@ -25,6 +30,8 @@ void audio_off(void);
// Vibrato rate functions // Vibrato rate functions
#ifdef VIBRATO_ENABLE
void set_vibrato_rate(float rate); void set_vibrato_rate(float rate);
void increase_vibrato_rate(float change); void increase_vibrato_rate(float change);
void decrease_vibrato_rate(float change); void decrease_vibrato_rate(float change);
@ -37,6 +44,8 @@ void decrease_vibrato_strength(float change);
#endif #endif
#endif
// Polyphony functions // Polyphony functions
void set_polyphony_rate(float rate); void set_polyphony_rate(float rate);
@ -51,11 +60,15 @@ void set_tempo(float tempo);
void increase_tempo(uint8_t tempo_change); void increase_tempo(uint8_t tempo_change);
void decrease_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_sample(uint8_t * s, uint16_t l, bool r);
void play_note(double freq, int vol); #endif
void stop_note(double freq); void play_note(float freq, int vol);
void stop_note(float freq);
void stop_all_notes(void); 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), \ #define SCALE (int []){ 0 + (12*0), 2 + (12*0), 4 + (12*0), 5 + (12*0), 7 + (12*0), 9 + (12*0), 11 + (12*0), \
0 + (12*1), 2 + (12*1), 4 + (12*1), 5 + (12*1), 7 + (12*1), 9 + (12*1), 11 + (12*1), \ 0 + (12*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 // 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. // length. This works around the limitation of C's sizeof operation on pointers.
// The global float array for the song must be used here. // 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(&note_array, NOTE_ARRAY_SIZE((note_array)), (note_repeat), (note_rest_style)); #define PLAY_NOTE_ARRAY(note_array, note_repeat, note_rest_style) play_notes(&note_array, NOTE_ARRAY_SIZE((note_array)), (note_repeat), (note_rest_style));
void play_goodbye_tone(void); void play_goodbye_tone(void);

View File

@ -2,107 +2,27 @@
#include <avr/interrupt.h> #include <avr/interrupt.h>
#include <avr/pgmspace.h> #include <avr/pgmspace.h>
#define VIBRATO_LUT_LENGTH 100 #define VIBRATO_LUT_LENGTH 20
const float VIBRATO_LUT[VIBRATO_LUT_LENGTH] = { \ const float VIBRATO_LUT[VIBRATO_LUT_LENGTH] = { \
1.00045346811453,
1.00090535101508,
1.00135386178926,
1.00179722447259,
1.00223368114872, 1.00223368114872,
1.0026614990145,
1.00307897737994,
1.00348445457284,
1.00387631471807,
1.00425299436105, 1.00425299436105,
1.00461298890553,
1.00495485883603,
1.00527723569589,
1.00557882779254,
1.00585842560279, 1.00585842560279,
1.00611490685176,
1.00634724124066,
1.00655449479987,
1.00673583384565,
1.00689052852052, 1.00689052852052,
1.00701795589922,
1.00711760264454,
1.0071890671992,
1.00723206150266,
1.0072464122237, 1.0072464122237,
1.00723206150266,
1.0071890671992,
1.00711760264454,
1.00701795589922,
1.00689052852052, 1.00689052852052,
1.00673583384565,
1.00655449479987,
1.00634724124066,
1.00611490685176,
1.00585842560279, 1.00585842560279,
1.00557882779254,
1.00527723569589,
1.00495485883603,
1.00461298890553,
1.00425299436105, 1.00425299436105,
1.00387631471807,
1.00348445457284,
1.00307897737994,
1.0026614990145,
1.00223368114872, 1.00223368114872,
1.00179722447259,
1.00135386178926,
1.00090535101508,
1.00045346811453,
1, 1,
0.999546737425598,
0.999095467903976,
0.998647968674285,
0.998205999748565,
0.99777129706302, 0.99777129706302,
0.997345565759612,
0.996930473622346,
0.996527644691494,
0.996138653077835,
0.99576501699778, 0.99576501699778,
0.995408193048995,
0.995069570744927,
0.994750467325326,
0.994452122858643,
0.994175695650927, 0.994175695650927,
0.993922257974591,
0.99369279212925,
0.993488186845591,
0.993309234042139,
0.993156625943589, 0.993156625943589,
0.993030952568311,
0.99293269959154,
0.992862246589715,
0.992819865670409,
0.992805720491269, 0.992805720491269,
0.992819865670409,
0.992862246589715,
0.99293269959154,
0.993030952568311,
0.993156625943589, 0.993156625943589,
0.993309234042139,
0.993488186845591,
0.99369279212925,
0.993922257974591,
0.994175695650927, 0.994175695650927,
0.994452122858643,
0.994750467325326,
0.995069570744927,
0.995408193048995,
0.99576501699778, 0.99576501699778,
0.996138653077835,
0.996527644691494,
0.996930473622346,
0.997345565759612,
0.99777129706302, 0.99777129706302,
0.998205999748565,
0.998647968674285,
0.999095467903976,
0.999546737425598,
1 1
}; };