aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIBNobody <IBNobody@users.noreply.github.com>2016-05-03 12:56:40 -0500
committerJack Humbert <jack.humb@gmail.com>2016-05-03 13:56:40 -0400
commit83e1cc241e3aabd69f6cdcd2581477d4b85bb8d3 (patch)
treefd0c9714f93e1afec478ddc42a86a6823136ad5f
parent2c070163ffffffde546fb00acaa2fbb96b93da64 (diff)
downloadqmk_firmware-83e1cc241e3aabd69f6cdcd2581477d4b85bb8d3.tar.gz
qmk_firmware-83e1cc241e3aabd69f6cdcd2581477d4b85bb8d3.zip
Clarified audio.c (#302)
* Updated personal layouts * tweaked personal * Nightly - Audio Cleanup Refactored the LUTs. Abstracted some of the registers out of audio to use more functional names. Split audio into audio and audio_pwm. WIP * nightly - collapsed code * Added check for note playing to LEDs
-rw-r--r--keyboard/atomic/keymaps/pvc/config.h5
-rw-r--r--keyboard/atomic/keymaps/pvc/keymap.c107
-rw-r--r--keyboard/planck/keymaps/pvc/config.h2
-rw-r--r--keyboard/planck/keymaps/pvc/keymap.c4
-rw-r--r--keyboard/planck/keymaps/pvc/makefile.mk3
-rw-r--r--quantum/audio/audio.c766
-rw-r--r--quantum/audio/audio.h6
-rw-r--r--quantum/audio/audio_pwm.c643
-rw-r--r--quantum/audio/frequency_lut.h357
-rw-r--r--quantum/audio/luts.c382
-rw-r--r--quantum/audio/luts.h15
-rw-r--r--quantum/audio/vibrato_lut.h28
-rw-r--r--quantum/audio/voices.c8
-rw-r--r--quantum/audio/voices.h3
-rw-r--r--quantum/keymap_common.c6
-rw-r--r--quantum/quantum.mk1
16 files changed, 1444 insertions, 892 deletions
diff --git a/keyboard/atomic/keymaps/pvc/config.h b/keyboard/atomic/keymaps/pvc/config.h
index cc9263464..034bc5dc5 100644
--- a/keyboard/atomic/keymaps/pvc/config.h
+++ b/keyboard/atomic/keymaps/pvc/config.h
@@ -158,4 +158,9 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
158//#define NO_ACTION_MACRO 158//#define NO_ACTION_MACRO
159//#define NO_ACTION_FUNCTION 159//#define NO_ACTION_FUNCTION
160 160
161
162//#define VIBRATO_ENABLE
163//#define VIBRATO_STRENGTH_ENABLE
164
165
161#endif 166#endif
diff --git a/keyboard/atomic/keymaps/pvc/keymap.c b/keyboard/atomic/keymaps/pvc/keymap.c
index e17c41e23..3d604a868 100644
--- a/keyboard/atomic/keymaps/pvc/keymap.c
+++ b/keyboard/atomic/keymaps/pvc/keymap.c
@@ -11,8 +11,8 @@
11#define LAYER_QWERTY 0 11#define LAYER_QWERTY 0
12#define LAYER_COLEMAK 1 12#define LAYER_COLEMAK 1
13#define LAYER_DVORAK 2 13#define LAYER_DVORAK 2
14#define LAYER_LOWER 3 14#define LAYER_RAISE 3
15#define LAYER_RAISE 4 15#define LAYER_LOWER 4
16#define LAYER_FUNCTION 5 16#define LAYER_FUNCTION 5
17#define LAYER_MOUSE 6 17#define LAYER_MOUSE 6
18#define LAYER_MUSIC 7 18#define LAYER_MUSIC 7
@@ -21,8 +21,8 @@
21#define MACRO_QWERTY 0 21#define MACRO_QWERTY 0
22#define MACRO_COLEMAK 1 22#define MACRO_COLEMAK 1
23#define MACRO_DVORAK 2 23#define MACRO_DVORAK 2
24#define MACRO_LOWER 3 24#define MACRO_RAISE 3
25#define MACRO_RAISE 4 25#define MACRO_LOWER 4
26#define MACRO_FUNCTION 5 26#define MACRO_FUNCTION 5
27#define MACRO_MOUSE 6 27#define MACRO_MOUSE 6
28#define MACRO_TIMBRE_1 7 28#define MACRO_TIMBRE_1 7
@@ -42,8 +42,8 @@
42#define M_QWRTY M(MACRO_QWERTY) 42#define M_QWRTY M(MACRO_QWERTY)
43#define M_COLMK M(MACRO_COLEMAK) 43#define M_COLMK M(MACRO_COLEMAK)
44#define M_DVORK M(MACRO_DVORAK) 44#define M_DVORK M(MACRO_DVORAK)
45#define M_LOWER M(MACRO_LOWER)
46#define M_RAISE M(MACRO_RAISE) 45#define M_RAISE M(MACRO_RAISE)
46#define M_LOWER M(MACRO_LOWER)
47#define M_FUNCT M(MACRO_FUNCTION) 47#define M_FUNCT M(MACRO_FUNCTION)
48#define M_MOUSE M(MACRO_MOUSE) 48#define M_MOUSE M(MACRO_MOUSE)
49#define TIMBR_1 M(MACRO_TIMBRE_1) 49#define TIMBR_1 M(MACRO_TIMBRE_1)
@@ -148,23 +148,22 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
148 { KC_LCTL, KC_LGUI, M_FUNCT, KC_LALT, M_RAISE, KC_SPC, KC_SPC, M_LOWER, KC_RALT, KC_RGUI, KC_MENU, KC_RCTL, KC_LEFT, KC_DOWN, KC_RGHT }, 148 { KC_LCTL, KC_LGUI, M_FUNCT, KC_LALT, M_RAISE, KC_SPC, KC_SPC, M_LOWER, KC_RALT, KC_RGUI, KC_MENU, KC_RCTL, KC_LEFT, KC_DOWN, KC_RGHT },
149 }, 149 },
150 150
151 [LAYER_RAISE] = { /* RAISED */
152 { KC_TILD, KC_PSCR, KC_PAUS, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, ________________ },
153 { _______, KC_F1, KC_F2, KC_F3, KC_F4, _______, _______, _______, _______, _______, _______, _______, _______, _______, KC_INS },
154 { _______, KC_F5, KC_F6, KC_F7, KC_F8, _______, _______, _______, _______, _______, _______, _______, ________________, KC_HOME },
155 { _______, KC_F9, KC_F10, KC_F11, KC_F12, _______, _______, _______, _______, _______, _______, ________________, _______, KC_END },
156 { _______, _______, _______, _______, _______, ________________, _______, _______, _______, _______, _______, _______, _______, _______ },
157 },
151 158
152 [LAYER_LOWER] = { /* LOWERED */ 159 [LAYER_LOWER] = { /* LOWERED */
153 { KC_GRV, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, ________________ }, 160 { KC_GRV, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, ________________ },
154 { _______, _______, _______, _______, SC_CCLS, _______, _______, _______, _______, _______, _______, _______, _______, _______, KC_INS }, 161 { _______, KC_F13, KC_F14, KC_F15, KC_F16, _______, _______, _______, _______, _______, _______, _______, _______, _______, KC_INS },
155 { _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, ________________, KC_HOME }, 162 { _______, KC_F17, KC_F18, KC_F19, KC_F20, _______, _______, _______, _______, _______, _______, _______, ________________, KC_HOME },
156 { _______, SC_REDO, _______, _______, _______, _______, _______, _______, _______, _______, _______, ________________, _______, KC_END }, 163 { _______, KC_F21, KC_F22, KC_F23, KC_F24, _______, _______, _______, _______, _______, _______, ________________, _______, KC_END },
157 { _______, _______, _______, _______, _______, KC_BSPC, KC_BSPC, _______, _______, _______, _______, _______, _______, _______, _______ }, 164 { _______, _______, _______, _______, _______, KC_BSPC, KC_BSPC, _______, _______, _______, _______, _______, _______, _______, _______ },
158 }, 165 },
159 166
160 [LAYER_RAISE] = { /* RAISED */
161 { KC_TILD, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, ________________ },
162 { _______, _______, _______, _______, SC_ACLS, _______, _______, _______, _______, _______, _______, _______, _______, _______, KC_INS },
163 { _______, SC_SELA, SC_SAVE, _______, _______, _______, _______, _______, _______, _______, _______, _______, ________________, KC_HOME },
164 { _______, SC_UNDO, SC_CUT, SC_COPY, SC_PSTE, _______, _______, _______, _______, _______, _______, ________________, _______, KC_END },
165 { _______, _______, _______, _______, _______, ________________, _______, _______, _______, _______, _______, _______, _______, _______ },
166 },
167
168 [LAYER_FUNCTION] = { /* FUNCTION */ 167 [LAYER_FUNCTION] = { /* FUNCTION */
169 { KC_NLCK, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, ________________ }, 168 { KC_NLCK, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, ________________ },
170 { KC_SLCK, KC_F13, KC_F14, KC_F15, KC_F16, KC_F17, KC_F18, KC_F19, KC_F20, KC_F21, KC_F22, KC_F23, KC_F24, _______, KC_PAUS }, 169 { KC_SLCK, KC_F13, KC_F14, KC_F15, KC_F16, KC_F17, KC_F18, KC_F19, KC_F20, KC_F21, KC_F22, KC_F23, KC_F24, _______, KC_PAUS },
@@ -281,28 +280,28 @@ const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt)
281 } 280 }
282 break; 281 break;
283 282
284 case MACRO_LOWER: 283 case MACRO_RAISE:
285 if (record->event.pressed) 284 if (record->event.pressed)
286 { 285 {
287 layer_on(LAYER_LOWER); 286 layer_on(LAYER_RAISE);
288 update_tri_layer(LAYER_LOWER, LAYER_RAISE, LAYER_ADJUST); 287 update_tri_layer(LAYER_LOWER, LAYER_RAISE, LAYER_ADJUST);
289 } 288 }
290 else 289 else
291 { 290 {
292 layer_off(LAYER_LOWER); 291 layer_off(LAYER_RAISE);
293 update_tri_layer(LAYER_LOWER, LAYER_RAISE, LAYER_ADJUST); 292 update_tri_layer(LAYER_LOWER, LAYER_RAISE, LAYER_ADJUST);
294 } 293 }
295 break; 294 break;
296 295
297 case MACRO_RAISE: 296 case MACRO_LOWER:
298 if (record->event.pressed) 297 if (record->event.pressed)
299 { 298 {
300 layer_on(LAYER_RAISE); 299 layer_on(LAYER_LOWER);
301 update_tri_layer(LAYER_LOWER, LAYER_RAISE, LAYER_ADJUST); 300 update_tri_layer(LAYER_LOWER, LAYER_RAISE, LAYER_ADJUST);
302 } 301 }
303 else 302 else
304 { 303 {
305 layer_off(LAYER_RAISE); 304 layer_off(LAYER_LOWER);
306 update_tri_layer(LAYER_LOWER, LAYER_RAISE, LAYER_ADJUST); 305 update_tri_layer(LAYER_LOWER, LAYER_RAISE, LAYER_ADJUST);
307 } 306 }
308 break; 307 break;
@@ -468,36 +467,40 @@ void led_set_user(uint8_t usb_led)
468 467
469 _delay_ms(10); // gets rid of tick 468 _delay_ms(10); // gets rid of tick
470 469
471 if ((usb_led & (1<<USB_LED_CAPS_LOCK)) && !(old_usb_led & (1<<USB_LED_CAPS_LOCK))) 470 if (!is_playing_notes())
472 { 471 {
473 // If CAPS LK LED is turning on... 472 if ((usb_led & (1<<USB_LED_CAPS_LOCK)) && !(old_usb_led & (1<<USB_LED_CAPS_LOCK)))
474 PLAY_NOTE_ARRAY(tone_caps_on, false, LEGATO); 473 {
475 } 474 // If CAPS LK LED is turning on...
476 else if (!(usb_led & (1<<USB_LED_CAPS_LOCK)) && (old_usb_led & (1<<USB_LED_CAPS_LOCK))) 475 PLAY_NOTE_ARRAY(tone_caps_on, false, LEGATO);
477 { 476 }
478 // If CAPS LK LED is turning off... 477 else if (!(usb_led & (1<<USB_LED_CAPS_LOCK)) && (old_usb_led & (1<<USB_LED_CAPS_LOCK)))
479 PLAY_NOTE_ARRAY(tone_caps_off, false, LEGATO); 478 {
480 } 479 // If CAPS LK LED is turning off...
481 else if ((usb_led & (1<<USB_LED_NUM_LOCK)) && !(old_usb_led & (1<<USB_LED_NUM_LOCK))) 480 PLAY_NOTE_ARRAY(tone_caps_off, false, LEGATO);
482 { 481 }
483 // If NUM LK LED is turning on... 482 else if ((usb_led & (1<<USB_LED_NUM_LOCK)) && !(old_usb_led & (1<<USB_LED_NUM_LOCK)))
484 PLAY_NOTE_ARRAY(tone_numlk_on, false, LEGATO); 483 {
485 } 484 // If NUM LK LED is turning on...
486 else if (!(usb_led & (1<<USB_LED_NUM_LOCK)) && (old_usb_led & (1<<USB_LED_NUM_LOCK))) 485 PLAY_NOTE_ARRAY(tone_numlk_on, false, LEGATO);
487 { 486 }
488 // If NUM LED is turning off... 487 else if (!(usb_led & (1<<USB_LED_NUM_LOCK)) && (old_usb_led & (1<<USB_LED_NUM_LOCK)))
489 PLAY_NOTE_ARRAY(tone_numlk_off, false, LEGATO); 488 {
490 } 489 // If NUM LED is turning off...
491 else if ((usb_led & (1<<USB_LED_SCROLL_LOCK)) && !(old_usb_led & (1<<USB_LED_SCROLL_LOCK))) 490 PLAY_NOTE_ARRAY(tone_numlk_off, false, LEGATO);
492 { 491 }
493 // If SCROLL LK LED is turning on... 492 else if ((usb_led & (1<<USB_LED_SCROLL_LOCK)) && !(old_usb_led & (1<<USB_LED_SCROLL_LOCK)))
494 PLAY_NOTE_ARRAY(tone_scroll_on, false, LEGATO); 493 {
495 } 494 // If SCROLL LK LED is turning on...
496 else if (!(usb_led & (1<<USB_LED_SCROLL_LOCK)) && (old_usb_led & (1<<USB_LED_SCROLL_LOCK))) 495 PLAY_NOTE_ARRAY(tone_scroll_on, false, LEGATO);
497 { 496 }
498 // If SCROLL LED is turning off... 497 else if (!(usb_led & (1<<USB_LED_SCROLL_LOCK)) && (old_usb_led & (1<<USB_LED_SCROLL_LOCK)))
499 PLAY_NOTE_ARRAY(tone_scroll_off, false, LEGATO); 498 {
500 } 499 // If SCROLL LED is turning off...
500 PLAY_NOTE_ARRAY(tone_scroll_off, false, LEGATO);
501 }
502 }
503
501 old_usb_led = usb_led; 504 old_usb_led = usb_led;
502} 505}
503 506
diff --git a/keyboard/planck/keymaps/pvc/config.h b/keyboard/planck/keymaps/pvc/config.h
index 7d64f0977..d435cc795 100644
--- a/keyboard/planck/keymaps/pvc/config.h
+++ b/keyboard/planck/keymaps/pvc/config.h
@@ -73,7 +73,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
73 */ 73 */
74 74
75/* disable debug print */ 75/* disable debug print */
76//#define NO_DEBUG 76#define NO_DEBUG
77 77
78/* disable print */ 78/* disable print */
79//#define NO_PRINT 79//#define NO_PRINT
diff --git a/keyboard/planck/keymaps/pvc/keymap.c b/keyboard/planck/keymaps/pvc/keymap.c
index 27850b215..830b00a4c 100644
--- a/keyboard/planck/keymaps/pvc/keymap.c
+++ b/keyboard/planck/keymaps/pvc/keymap.c
@@ -96,7 +96,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
96 96
97 [LAYER_QWERTY] = { /* QWERTY */ 97 [LAYER_QWERTY] = { /* QWERTY */
98 { KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_BSPC }, 98 { KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_BSPC },
99 { KC_BSPC, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT }, 99 { KC_ESC, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT },
100 { KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_ENT }, 100 { KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_ENT },
101 { KC_LCTL, KC_LGUI, M_FUNCT, KC_LALT, M_RAISE, KC_SPC, KC_SPC, M_LOWER, KC_UP, KC_DOWN, KC_LEFT, KC_RGHT }, 101 { KC_LCTL, KC_LGUI, M_FUNCT, KC_LALT, M_RAISE, KC_SPC, KC_SPC, M_LOWER, KC_UP, KC_DOWN, KC_LEFT, KC_RGHT },
102 }, 102 },
@@ -115,7 +115,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
115 115
116 [LAYER_COLEMAK] = { /* COLEMAK */ 116 [LAYER_COLEMAK] = { /* COLEMAK */
117 { KC_TAB, KC_Q, KC_W, KC_F, KC_P, KC_G, KC_J, KC_L, KC_U, KC_Y, KC_SCLN, KC_ESC }, 117 { KC_TAB, KC_Q, KC_W, KC_F, KC_P, KC_G, KC_J, KC_L, KC_U, KC_Y, KC_SCLN, KC_ESC },
118 { KC_ESC, KC_A, KC_R, KC_S, KC_T, KC_D, KC_H, KC_N, KC_E, KC_I, KC_O, KC_QUOT }, 118 { KC_BSPC, KC_A, KC_R, KC_S, KC_T, KC_D, KC_H, KC_N, KC_E, KC_I, KC_O, KC_QUOT },
119 { KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_K, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_ENT }, 119 { KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_K, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_ENT },
120 { KC_LCTL, KC_LGUI, M_FUNCT, KC_LALT, M_RAISE, KC_SPC, KC_SPC, M_LOWER, KC_UP, KC_DOWN, KC_LEFT, KC_RGHT }, 120 { KC_LCTL, KC_LGUI, M_FUNCT, KC_LALT, M_RAISE, KC_SPC, KC_SPC, M_LOWER, KC_UP, KC_DOWN, KC_LEFT, KC_RGHT },
121 }, 121 },
diff --git a/keyboard/planck/keymaps/pvc/makefile.mk b/keyboard/planck/keymaps/pvc/makefile.mk
index 4b9e34c53..b3f1b9e51 100644
--- a/keyboard/planck/keymaps/pvc/makefile.mk
+++ b/keyboard/planck/keymaps/pvc/makefile.mk
@@ -4,6 +4,7 @@ EXTRAKEY_ENABLE = yes # Audio control and System control(+450)
4CONSOLE_ENABLE = yes # Console for debug(+400) 4CONSOLE_ENABLE = yes # Console for debug(+400)
5COMMAND_ENABLE = yes # Commands for debug and configuration 5COMMAND_ENABLE = yes # Commands for debug and configuration
6NKRO_ENABLE = yes # Nkey Rollover - if this doesn't work, see here: https://github.com/tmk/tmk_keyboard/wiki/FAQ#nkro-doesnt-work 6NKRO_ENABLE = yes # Nkey Rollover - if this doesn't work, see here: https://github.com/tmk/tmk_keyboard/wiki/FAQ#nkro-doesnt-work
7BACKLIGHT_ENABLE = no # Enable keyboard backlight functionality
7MIDI_ENABLE = no # MIDI controls 8MIDI_ENABLE = no # MIDI controls
8AUDIO_ENABLE = no # Audio output on port C6 9AUDIO_ENABLE = no # Audio output on port C6
9UNICODE_ENABLE = no # Unicode 10UNICODE_ENABLE = no # Unicode
@@ -13,4 +14,4 @@ RGBLIGHT_ENABLE = no # Enable WS2812 RGB underlight. Do not enable this with
13# Do not enable SLEEP_LED_ENABLE. it uses the same timer as BACKLIGHT_ENABLE 14# Do not enable SLEEP_LED_ENABLE. it uses the same timer as BACKLIGHT_ENABLE
14SLEEP_LED_ENABLE = no # Breathing sleep LED during USB suspend 15SLEEP_LED_ENABLE = no # Breathing sleep LED during USB suspend
15 16
16CONFIG_H = keymaps/$(KEYMAP)/config.h 17CONFIG_H = keymaps/$(KEYMAP)/config.h \ No newline at end of file
diff --git a/quantum/audio/audio.c b/quantum/audio/audio.c
index e85370d95..3a7f0f556 100644
--- a/quantum/audio/audio.c
+++ b/quantum/audio/audio.c
@@ -1,6 +1,6 @@
1#include <stdio.h> 1#include <stdio.h>
2#include <string.h> 2#include <string.h>
3#include <math.h> 3//#include <math.h>
4#include <avr/pgmspace.h> 4#include <avr/pgmspace.h>
5#include <avr/interrupt.h> 5#include <avr/interrupt.h>
6#include <avr/io.h> 6#include <avr/io.h>
@@ -10,30 +10,28 @@
10 10
11#include "eeconfig.h" 11#include "eeconfig.h"
12 12
13#ifdef VIBRATO_ENABLE 13#define CPU_PRESCALER 8
14 #include "vibrato_lut.h"
15#endif
16 14
17#define PI 3.14159265 15// -----------------------------------------------------------------------------
16// Timer Abstractions
17// -----------------------------------------------------------------------------
18 18
19#define CPU_PRESCALER 8 19// TIMSK3 - Timer/Counter #3 Interrupt Mask Register
20// Turn on/off 3A interputs, stopping/enabling the ISR calls
21#define ENABLE_AUDIO_COUNTER_3_ISR TIMSK3 |= _BV(OCIE3A)
22#define DISABLE_AUDIO_COUNTER_3_ISR TIMSK3 &= ~_BV(OCIE3A)
20 23
21#ifdef PWM_AUDIO 24// TCCR3A: Timer/Counter #3 Control Register
22 #include "wave.h" 25// Compare Output Mode (COM3An) = 0b00 = Normal port operation, OC3A disconnected from PC6
23 #define SAMPLE_DIVIDER 39 26#define ENABLE_AUDIO_COUNTER_3_OUTPUT TCCR3A |= _BV(COM3A1);
24 #define SAMPLE_RATE (2000000.0/SAMPLE_DIVIDER/2048) 27#define DISABLE_AUDIO_COUNTER_3_OUTPUT TCCR3A &= ~(_BV(COM3A1) | _BV(COM3A0));
25 // Resistor value of 1/ (2 * PI * 10nF * (2000000 hertz / SAMPLE_DIVIDER / 10)) for 10nF cap
26 28
27 float places[8] = {0, 0, 0, 0, 0, 0, 0, 0}; 29// Fast PWM Mode Controls
28 uint16_t place_int = 0; 30#define TIMER_3_PERIOD ICR3
29 bool repeat = true; 31#define TIMER_3_DUTY_CYCLE OCR3A
30#endif 32
33// -----------------------------------------------------------------------------
31 34
32void delay_us(int count) {
33 while(count--) {
34 _delay_us(1);
35 }
36}
37 35
38int voices = 0; 36int voices = 0;
39int voice_place = 0; 37int voice_place = 0;
@@ -45,26 +43,23 @@ float frequencies[8] = {0, 0, 0, 0, 0, 0, 0, 0};
45int volumes[8] = {0, 0, 0, 0, 0, 0, 0, 0}; 43int volumes[8] = {0, 0, 0, 0, 0, 0, 0, 0};
46bool sliding = false; 44bool sliding = false;
47 45
48int max = 0xFF;
49float sum = 0;
50float place = 0; 46float place = 0;
51 47
52uint8_t * sample; 48uint8_t * sample;
53uint16_t sample_length = 0; 49uint16_t sample_length = 0;
54// float freq = 0; 50
55 51bool playing_notes = false;
56bool notes = false; 52bool playing_note = false;
57bool note = false; 53float note_frequency = 0;
58float note_frequency = 0; 54float note_length = 0;
59float note_length = 0; 55uint8_t note_tempo = TEMPO_DEFAULT;
60float note_tempo = TEMPO_DEFAULT; 56float note_timbre = TIMBRE_DEFAULT;
61float note_timbre = TIMBRE_DEFAULT;
62uint16_t note_position = 0; 57uint16_t note_position = 0;
63float (* notes_pointer)[][2]; 58float (* notes_pointer)[][2];
64uint16_t notes_count; 59uint16_t notes_count;
65bool notes_repeat; 60bool notes_repeat;
66float notes_rest; 61float notes_rest;
67bool note_resting = false; 62bool note_resting = false;
68 63
69uint8_t current_note = 0; 64uint8_t current_note = 0;
70uint8_t rest_counter = 0; 65uint8_t rest_counter = 0;
@@ -77,175 +72,65 @@ float vibrato_rate = 0.125;
77 72
78float polyphony_rate = 0; 73float polyphony_rate = 0;
79 74
80bool inited = false; 75static bool audio_initialized = false;
81 76
82audio_config_t audio_config; 77audio_config_t audio_config;
83 78
84uint16_t envelope_index = 0; 79uint16_t envelope_index = 0;
85 80
86void audio_toggle(void) { 81void audio_init()
87 audio_config.enable ^= 1; 82{
88 eeconfig_update_audio(audio_config.raw);
89}
90
91void audio_on(void) {
92 audio_config.enable = 1;
93 eeconfig_update_audio(audio_config.raw);
94}
95
96void audio_off(void) {
97 audio_config.enable = 0;
98 eeconfig_update_audio(audio_config.raw);
99}
100
101#ifdef VIBRATO_ENABLE
102// Vibrato rate functions
103
104void set_vibrato_rate(float rate) {
105 vibrato_rate = rate;
106}
107
108void increase_vibrato_rate(float change) {
109 vibrato_rate *= change;
110}
111
112void decrease_vibrato_rate(float change) {
113 vibrato_rate /= change;
114}
115
116#ifdef VIBRATO_STRENGTH_ENABLE
117
118void set_vibrato_strength(float strength) {
119 vibrato_strength = strength;
120}
121
122void increase_vibrato_strength(float change) {
123 vibrato_strength *= change;
124}
125
126void decrease_vibrato_strength(float change) {
127 vibrato_strength /= change;
128}
129
130#endif
131
132#endif
133
134// Polyphony functions
135
136void set_polyphony_rate(float rate) {
137 polyphony_rate = rate;
138}
139
140void enable_polyphony() {
141 polyphony_rate = 5;
142}
143
144void disable_polyphony() {
145 polyphony_rate = 0;
146}
147
148void increase_polyphony_rate(float change) {
149 polyphony_rate *= change;
150}
151
152void decrease_polyphony_rate(float change) {
153 polyphony_rate /= change;
154}
155
156// Timbre function
157
158void set_timbre(float timbre) {
159 note_timbre = timbre;
160}
161
162// Tempo functions
163
164void set_tempo(float tempo) {
165 note_tempo = tempo;
166}
167
168void decrease_tempo(uint8_t tempo_change) {
169 note_tempo += (float) tempo_change;
170}
171
172void increase_tempo(uint8_t tempo_change) {
173 if (note_tempo - (float) tempo_change < 10) {
174 note_tempo = 10;
175 } else {
176 note_tempo -= (float) tempo_change;
177 }
178}
179
180void audio_init() {
181 83
182 /* check signature */ 84 // Check EEPROM
183 if (!eeconfig_is_enabled()) { 85 if (!eeconfig_is_enabled())
86 {
184 eeconfig_init(); 87 eeconfig_init();
185 } 88 }
186 audio_config.raw = eeconfig_read_audio(); 89 audio_config.raw = eeconfig_read_audio();
187 90
188 #ifdef PWM_AUDIO 91 // Set port PC6 (OC3A and /OC4A) as output
189 PLLFRQ = _BV(PDIV2); 92 DDRC |= _BV(PORTC6);
190 PLLCSR = _BV(PLLE);
191 while(!(PLLCSR & _BV(PLOCK)));
192 PLLFRQ |= _BV(PLLTM0); /* PCK 48MHz */
193 93
194 /* Init a fast PWM on Timer4 */ 94 DISABLE_AUDIO_COUNTER_3_ISR;
195 TCCR4A = _BV(COM4A0) | _BV(PWM4A); /* Clear OC4A on Compare Match */
196 TCCR4B = _BV(CS40); /* No prescaling => f = PCK/256 = 187500Hz */
197 OCR4A = 0;
198 95
199 /* Enable the OC4A output */ 96 // TCCR3A / TCCR3B: Timer/Counter #3 Control Registers
200 DDRC |= _BV(PORTC6); 97 // Compare Output Mode (COM3An) = 0b00 = Normal port operation, OC3A disconnected from PC6
98 // Waveform Generation Mode (WGM3n) = 0b1110 = Fast PWM Mode 14 (Period = ICR3, Duty Cycle = OCR3A)
99 // Clock Select (CS3n) = 0b010 = Clock / 8
100 TCCR3A = (0 << COM3A1) | (0 << COM3A0) | (1 << WGM31) | (0 << WGM30);
101 TCCR3B = (1 << WGM33) | (1 << WGM32) | (0 << CS32) | (1 << CS31) | (0 << CS30);
201 102
202 TIMSK3 &= ~_BV(OCIE3A); // Turn off 3A interputs 103 audio_initialized = true;
203
204 TCCR3A = 0x0; // Options not needed
205 TCCR3B = _BV(CS31) | _BV(CS30) | _BV(WGM32); // 64th prescaling and CTC
206 OCR3A = SAMPLE_DIVIDER - 1; // Correct count/compare, related to sample playback
207 #else
208 DDRC |= _BV(PORTC6);
209
210 TIMSK3 &= ~_BV(OCIE3A); // Turn off 3A interputs
211
212 TCCR3A = (0 << COM3A1) | (0 << COM3A0) | (1 << WGM31) | (0 << WGM30);
213 TCCR3B = (1 << WGM33) | (1 << WGM32) | (0 << CS32) | (1 << CS31) | (0 << CS30);
214 #endif
215
216 inited = true;
217} 104}
218 105
219void stop_all_notes() { 106void stop_all_notes()
220 if (!inited) { 107{
108 if (!audio_initialized) {
221 audio_init(); 109 audio_init();
222 } 110 }
223 voices = 0; 111 voices = 0;
224 #ifdef PWM_AUDIO 112
225 TIMSK3 &= ~_BV(OCIE3A); 113 DISABLE_AUDIO_COUNTER_3_ISR;
226 #else 114 DISABLE_AUDIO_COUNTER_3_OUTPUT;
227 TIMSK3 &= ~_BV(OCIE3A); 115
228 TCCR3A &= ~_BV(COM3A1); 116 playing_notes = false;
229 #endif 117 playing_note = false;
230 notes = false;
231 note = false;
232 frequency = 0; 118 frequency = 0;
233 volume = 0; 119 volume = 0;
234 120
235 for (int i = 0; i < 8; i++) { 121 for (uint8_t i = 0; i < 8; i++)
122 {
236 frequencies[i] = 0; 123 frequencies[i] = 0;
237 volumes[i] = 0; 124 volumes[i] = 0;
238 } 125 }
239} 126}
240 127
241void stop_note(float freq) { 128void stop_note(float freq)
242 if (note) { 129{
243 if (!inited) { 130 if (playing_note) {
131 if (!audio_initialized) {
244 audio_init(); 132 audio_init();
245 } 133 }
246 #ifdef PWM_AUDIO
247 freq = freq / SAMPLE_RATE;
248 #endif
249 for (int i = 7; i >= 0; i--) { 134 for (int i = 7; i >= 0; i--) {
250 if (frequencies[i] == freq) { 135 if (frequencies[i] == freq) {
251 frequencies[i] = 0; 136 frequencies[i] = 0;
@@ -266,15 +151,11 @@ void stop_note(float freq) {
266 voice_place = 0; 151 voice_place = 0;
267 } 152 }
268 if (voices == 0) { 153 if (voices == 0) {
269 #ifdef PWM_AUDIO 154 DISABLE_AUDIO_COUNTER_3_ISR;
270 TIMSK3 &= ~_BV(OCIE3A); 155 DISABLE_AUDIO_COUNTER_3_OUTPUT;
271 #else
272 TIMSK3 &= ~_BV(OCIE3A);
273 TCCR3A &= ~_BV(COM3A1);
274 #endif
275 frequency = 0; 156 frequency = 0;
276 volume = 0; 157 volume = 0;
277 note = false; 158 playing_note = false;
278 } 159 }
279 } 160 }
280} 161}
@@ -289,9 +170,9 @@ float mod(float a, int b)
289 170
290float vibrato(float average_freq) { 171float vibrato(float average_freq) {
291 #ifdef VIBRATO_STRENGTH_ENABLE 172 #ifdef VIBRATO_STRENGTH_ENABLE
292 float vibrated_freq = average_freq * pow(VIBRATO_LUT[(int)vibrato_counter], vibrato_strength); 173 float vibrated_freq = average_freq * pow(vibrato_lut[(int)vibrato_counter], vibrato_strength);
293 #else 174 #else
294 float vibrated_freq = average_freq * VIBRATO_LUT[(int)vibrato_counter]; 175 float vibrated_freq = average_freq * vibrato_lut[(int)vibrato_counter];
295 #endif 176 #endif
296 vibrato_counter = mod((vibrato_counter + vibrato_rate * (1.0 + 440.0/average_freq)), VIBRATO_LUT_LENGTH); 177 vibrato_counter = mod((vibrato_counter + vibrato_rate * (1.0 + 440.0/average_freq)), VIBRATO_LUT_LENGTH);
297 return vibrated_freq; 178 return vibrated_freq;
@@ -299,295 +180,295 @@ float vibrato(float average_freq) {
299 180
300#endif 181#endif
301 182
302ISR(TIMER3_COMPA_vect) { 183ISR(TIMER3_COMPA_vect)
303 if (note) { 184{
304 #ifdef PWM_AUDIO 185 float freq;
305 if (voices == 1) { 186
306 // SINE 187 if (playing_note) {
307 OCR4A = pgm_read_byte(&sinewave[(uint16_t)place]) >> 2; 188 if (voices > 0) {
308 189 if (polyphony_rate > 0) {
309 // SQUARE 190 if (voices > 1) {
310 // if (((int)place) >= 1024){ 191 voice_place %= voices;
311 // OCR4A = 0xFF >> 2; 192 if (place++ > (frequencies[voice_place] / polyphony_rate / CPU_PRESCALER)) {
312 // } else { 193 voice_place = (voice_place + 1) % voices;
313 // OCR4A = 0x00; 194 place = 0.0;
314 // } 195 }
315 196 }
316 // SAWTOOTH 197
317 // OCR4A = (int)place / 4; 198 #ifdef VIBRATO_ENABLE
318 199 if (vibrato_strength > 0) {
319 // TRIANGLE 200 freq = vibrato(frequencies[voice_place]);
320 // if (((int)place) >= 1024) { 201 } else {
321 // OCR4A = (int)place / 2; 202 freq = frequencies[voice_place];
322 // } else { 203 }
323 // OCR4A = 2048 - (int)place / 2; 204 #else
324 // } 205 freq = frequencies[voice_place];
325 206 #endif
326 place += frequency; 207 } else {
327 208 if (frequency != 0 && frequency < frequencies[voices - 1] && frequency < frequencies[voices - 1] * pow(2, -440/frequencies[voices - 1]/12/2)) {
328 if (place >= SINE_LENGTH) 209 frequency = frequency * pow(2, 440/frequency/12/2);
329 place -= SINE_LENGTH; 210 } else if (frequency != 0 && frequency > frequencies[voices - 1] && frequency > frequencies[voices - 1] * pow(2, 440/frequencies[voices - 1]/12/2)) {
330 211 frequency = frequency * pow(2, -440/frequency/12/2);
331 } else { 212 } else {
332 int sum = 0; 213 frequency = frequencies[voices - 1];
333 for (int i = 0; i < voices; i++) { 214 }
334 // SINE 215
335 sum += pgm_read_byte(&sinewave[(uint16_t)places[i]]) >> 2; 216 #ifdef VIBRATO_ENABLE
336 217 if (vibrato_strength > 0) {
337 // SQUARE 218 freq = vibrato(frequency);
338 // if (((int)places[i]) >= 1024){ 219 } else {
339 // sum += 0xFF >> 2; 220 freq = frequency;
340 // } else { 221 }
341 // sum += 0x00; 222 #else
342 // } 223 freq = frequency;
343 224 #endif
344 places[i] += frequencies[i]; 225 }
345 226
346 if (places[i] >= SINE_LENGTH) 227 if (envelope_index < 65535) {
347 places[i] -= SINE_LENGTH; 228 envelope_index++;
348 } 229 }
349 OCR4A = sum; 230
350 } 231 freq = voice_envelope(freq);
351 #else 232
352 if (voices > 0) { 233 if (freq < 30.517578125) {
353 float freq; 234 freq = 30.52;
354 if (polyphony_rate > 0) { 235 }
355 if (voices > 1) { 236
356 voice_place %= voices; 237 TIMER_3_PERIOD = (uint16_t)(((float)F_CPU) / (freq * CPU_PRESCALER));
357 if (place++ > (frequencies[voice_place] / polyphony_rate / CPU_PRESCALER)) { 238 TIMER_3_DUTY_CYCLE = (uint16_t)((((float)F_CPU) / (freq * CPU_PRESCALER)) * note_timbre);
358 voice_place = (voice_place + 1) % voices; 239 }
359 place = 0.0; 240 }
360 } 241
361 } 242 if (playing_notes) {
362 #ifdef VIBRATO_ENABLE 243 if (note_frequency > 0) {
363 if (vibrato_strength > 0) { 244 #ifdef VIBRATO_ENABLE
364 freq = vibrato(frequencies[voice_place]); 245 if (vibrato_strength > 0) {
365 } else { 246 freq = vibrato(note_frequency);
366 #else 247 } else {
367 { 248 freq = note_frequency;
368 #endif 249 }
369 freq = frequencies[voice_place]; 250 #else
370 } 251 freq = note_frequency;
371 } else { 252 #endif
372 if (frequency != 0 && frequency < frequencies[voices - 1] && frequency < frequencies[voices - 1] * pow(2, -440/frequencies[voices - 1]/12/2)) { 253
373 frequency = frequency * pow(2, 440/frequency/12/2); 254 if (envelope_index < 65535) {
374 } else if (frequency != 0 && frequency > frequencies[voices - 1] && frequency > frequencies[voices - 1] * pow(2, 440/frequencies[voices - 1]/12/2)) { 255 envelope_index++;
375 frequency = frequency * pow(2, -440/frequency/12/2); 256 }
376 } else { 257 freq = voice_envelope(freq);
377 frequency = frequencies[voices - 1]; 258
378 } 259 TIMER_3_PERIOD = (uint16_t)(((float)F_CPU) / (freq * CPU_PRESCALER));
379 260 TIMER_3_DUTY_CYCLE = (uint16_t)((((float)F_CPU) / (freq * CPU_PRESCALER)) * note_timbre);
380 261 } else {
381 #ifdef VIBRATO_ENABLE 262 TIMER_3_PERIOD = 0;
382 if (vibrato_strength > 0) { 263 TIMER_3_DUTY_CYCLE = 0;
383 freq = vibrato(frequency); 264 }
384 } else { 265
385 #else 266 note_position++;
386 { 267 bool end_of_note = false;
387 #endif 268 if (TIMER_3_PERIOD > 0) {
388 freq = frequency; 269 end_of_note = (note_position >= (note_length / TIMER_3_PERIOD * 0xFFFF));
389 } 270 } else {
390 } 271 end_of_note = (note_position >= (note_length * 0x7FF));
272 }
273
274 if (end_of_note) {
275 current_note++;
276 if (current_note >= notes_count) {
277 if (notes_repeat) {
278 current_note = 0;
279 } else {
280 DISABLE_AUDIO_COUNTER_3_ISR;
281 DISABLE_AUDIO_COUNTER_3_OUTPUT;
282 playing_notes = false;
283 return;
284 }
285 }
286 if (!note_resting && (notes_rest > 0)) {
287 note_resting = true;
288 note_frequency = 0;
289 note_length = notes_rest;
290 current_note--;
291 } else {
292 note_resting = false;
293 envelope_index = 0;
294 note_frequency = (*notes_pointer)[current_note][0];
295 note_length = ((*notes_pointer)[current_note][1] / 4) * (((float)note_tempo) / 100);
296 }
297
298 note_position = 0;
299 }
300 }
301
302 if (!audio_config.enable) {
303 playing_notes = false;
304 playing_note = false;
305 }
306}
391 307
392 if (envelope_index < 65535) { 308void play_note(float freq, int vol) {
393 envelope_index++;
394 }
395 freq = voice_envelope(freq);
396 309
397 if (freq < 30.517578125) 310 if (!audio_initialized) {
398 freq = 30.52; 311 audio_init();
399 ICR3 = (int)(((double)F_CPU) / (freq * CPU_PRESCALER)); // Set max to the period
400 OCR3A = (int)((((double)F_CPU) / (freq * CPU_PRESCALER)) * note_timbre); // Set compare to half the period
401 }
402 #endif
403 } 312 }
404 313
405 // SAMPLE 314 if (audio_config.enable && voices < 8) {
406 // OCR4A = pgm_read_byte(&sample[(uint16_t)place_int]); 315 DISABLE_AUDIO_COUNTER_3_ISR;
407
408 // place_int++;
409
410 // if (place_int >= sample_length)
411 // if (repeat)
412 // place_int -= sample_length;
413 // else
414 // TIMSK3 &= ~_BV(OCIE3A);
415
416
417 if (notes) {
418 #ifdef PWM_AUDIO
419 OCR4A = pgm_read_byte(&sinewave[(uint16_t)place]) >> 0;
420
421 place += note_frequency;
422 if (place >= SINE_LENGTH)
423 place -= SINE_LENGTH;
424 #else
425 if (note_frequency > 0) {
426 float freq;
427
428 #ifdef VIBRATO_ENABLE
429 if (vibrato_strength > 0) {
430 freq = vibrato(note_frequency);
431 } else {
432 #else
433 {
434 #endif
435 freq = note_frequency;
436 }
437 316
438 if (envelope_index < 65535) { 317 // Cancel notes if notes are playing
439 envelope_index++; 318 if (playing_notes)
440 } 319 stop_all_notes();
441 freq = voice_envelope(freq);
442 320
443 ICR3 = (int)(((double)F_CPU) / (freq * CPU_PRESCALER)); // Set max to the period 321 playing_note = true;
444 OCR3A = (int)((((double)F_CPU) / (freq * CPU_PRESCALER)) * note_timbre); // Set compare to half the period
445 } else {
446 ICR3 = 0;
447 OCR3A = 0;
448 }
449 #endif
450
451
452 note_position++;
453 bool end_of_note = false;
454 if (ICR3 > 0)
455 end_of_note = (note_position >= (note_length / ICR3 * 0xFFFF));
456 else
457 end_of_note = (note_position >= (note_length * 0x7FF));
458 if (end_of_note) {
459 current_note++;
460 if (current_note >= notes_count) {
461 if (notes_repeat) {
462 current_note = 0;
463 } else {
464 #ifdef PWM_AUDIO
465 TIMSK3 &= ~_BV(OCIE3A);
466 #else
467 TIMSK3 &= ~_BV(OCIE3A);
468 TCCR3A &= ~_BV(COM3A1);
469 #endif
470 notes = false;
471 return;
472 }
473 }
474 if (!note_resting && (notes_rest > 0)) {
475 note_resting = true;
476 note_frequency = 0;
477 note_length = notes_rest;
478 current_note--;
479 } else {
480 note_resting = false;
481 #ifdef PWM_AUDIO
482 note_frequency = (*notes_pointer)[current_note][0] / SAMPLE_RATE;
483 note_length = (*notes_pointer)[current_note][1] * (note_tempo / 100);
484 #else
485 envelope_index = 0;
486 note_frequency = (*notes_pointer)[current_note][0];
487 note_length = ((*notes_pointer)[current_note][1] / 4) * (note_tempo / 100);
488 #endif
489 }
490 note_position = 0;
491 }
492 322
493 } 323 envelope_index = 0;
324
325 if (freq > 0) {
326 frequencies[voices] = freq;
327 volumes[voices] = vol;
328 voices++;
329 }
330
331 ENABLE_AUDIO_COUNTER_3_ISR;
332 ENABLE_AUDIO_COUNTER_3_OUTPUT;
333 }
494 334
495 if (!audio_config.enable) {
496 notes = false;
497 note = false;
498 }
499} 335}
500 336
501void play_note(float freq, int vol) { 337void play_notes(float (*np)[][2], uint16_t n_count, bool n_repeat, float n_rest)
338{
502 339
503 if (!inited) { 340 if (!audio_initialized) {
504 audio_init(); 341 audio_init();
505 } 342 }
506 343
507if (audio_config.enable && voices < 8) { 344 if (audio_config.enable) {
508 TIMSK3 &= ~_BV(OCIE3A); 345
509 // Cancel notes if notes are playing 346 DISABLE_AUDIO_COUNTER_3_ISR;
510 if (notes) 347
511 stop_all_notes(); 348 // Cancel note if a note is playing
512 note = true; 349 if (playing_note)
513 envelope_index = 0; 350 stop_all_notes();
514 #ifdef PWM_AUDIO 351
515 freq = freq / SAMPLE_RATE; 352 playing_notes = true;
516 #endif 353
517 if (freq > 0) { 354 notes_pointer = np;
518 frequencies[voices] = freq; 355 notes_count = n_count;
519 volumes[voices] = vol; 356 notes_repeat = n_repeat;
520 voices++; 357 notes_rest = n_rest;
521 } 358
359 place = 0;
360 current_note = 0;
361
362 note_frequency = (*notes_pointer)[current_note][0];
363 note_length = ((*notes_pointer)[current_note][1] / 4) * (((float)note_tempo) / 100);
364 note_position = 0;
365
366
367 ENABLE_AUDIO_COUNTER_3_ISR;
368 ENABLE_AUDIO_COUNTER_3_OUTPUT;
369 }
522 370
523 #ifdef PWM_AUDIO
524 TIMSK3 |= _BV(OCIE3A);
525 #else
526 TIMSK3 |= _BV(OCIE3A);
527 TCCR3A |= _BV(COM3A1);
528 #endif
529} 371}
530 372
373bool is_playing_notes(void) {
374 return playing_notes;
531} 375}
532 376
533void play_notes(float (*np)[][2], uint16_t n_count, bool n_repeat, float n_rest) { 377void audio_toggle(void) {
378 audio_config.enable ^= 1;
379 eeconfig_update_audio(audio_config.raw);
380}
534 381
535 if (!inited) { 382void audio_on(void) {
536 audio_init(); 383 audio_config.enable = 1;
537 } 384 eeconfig_update_audio(audio_config.raw);
385}
538 386
539if (audio_config.enable) { 387void audio_off(void) {
540 TIMSK3 &= ~_BV(OCIE3A); 388 audio_config.enable = 0;
541 // Cancel note if a note is playing 389 eeconfig_update_audio(audio_config.raw);
542 if (note) 390}
543 stop_all_notes();
544 notes = true;
545
546 notes_pointer = np;
547 notes_count = n_count;
548 notes_repeat = n_repeat;
549 notes_rest = n_rest;
550
551 place = 0;
552 current_note = 0;
553 #ifdef PWM_AUDIO
554 note_frequency = (*notes_pointer)[current_note][0] / SAMPLE_RATE;
555 note_length = (*notes_pointer)[current_note][1] * (note_tempo / 100);
556 #else
557 note_frequency = (*notes_pointer)[current_note][0];
558 note_length = ((*notes_pointer)[current_note][1] / 4) * (note_tempo / 100);
559 #endif
560 note_position = 0;
561 391
392#ifdef VIBRATO_ENABLE
562 393
563 #ifdef PWM_AUDIO 394// Vibrato rate functions
564 TIMSK3 |= _BV(OCIE3A); 395
565 #else 396void set_vibrato_rate(float rate) {
566 TIMSK3 |= _BV(OCIE3A); 397 vibrato_rate = rate;
567 TCCR3A |= _BV(COM3A1);
568 #endif
569} 398}
570 399
400void increase_vibrato_rate(float change) {
401 vibrato_rate *= change;
571} 402}
572 403
573#ifdef PWM_AUDIO 404void decrease_vibrato_rate(float change) {
574void play_sample(uint8_t * s, uint16_t l, bool r) { 405 vibrato_rate /= change;
575 if (!inited) { 406}
576 audio_init();
577 }
578 407
579 if (audio_config.enable) { 408#ifdef VIBRATO_STRENGTH_ENABLE
580 TIMSK3 &= ~_BV(OCIE3A); 409
581 stop_all_notes(); 410void set_vibrato_strength(float strength) {
582 place_int = 0; 411 vibrato_strength = strength;
583 sample = s; 412}
584 sample_length = l; 413
585 repeat = r; 414void increase_vibrato_strength(float change) {
415 vibrato_strength *= change;
416}
417
418void decrease_vibrato_strength(float change) {
419 vibrato_strength /= change;
420}
421
422#endif /* VIBRATO_STRENGTH_ENABLE */
423
424#endif /* VIBRATO_ENABLE */
586 425
587 TIMSK3 |= _BV(OCIE3A); 426// Polyphony functions
427
428void set_polyphony_rate(float rate) {
429 polyphony_rate = rate;
430}
431
432void enable_polyphony() {
433 polyphony_rate = 5;
434}
435
436void disable_polyphony() {
437 polyphony_rate = 0;
438}
439
440void increase_polyphony_rate(float change) {
441 polyphony_rate *= change;
442}
443
444void decrease_polyphony_rate(float change) {
445 polyphony_rate /= change;
446}
447
448// Timbre function
449
450void set_timbre(float timbre) {
451 note_timbre = timbre;
452}
453
454// Tempo functions
455
456void set_tempo(uint8_t tempo) {
457 note_tempo = tempo;
458}
459
460void decrease_tempo(uint8_t tempo_change) {
461 note_tempo += tempo_change;
462}
463
464void increase_tempo(uint8_t tempo_change) {
465 if (note_tempo - tempo_change < 10) {
466 note_tempo = 10;
467 } else {
468 note_tempo -= tempo_change;
588 } 469 }
589} 470}
590#endif 471
591 472
592//------------------------------------------------------------------------------ 473//------------------------------------------------------------------------------
593// Override these functions in your keymap file to play different tunes on 474// Override these functions in your keymap file to play different tunes on
@@ -597,11 +478,8 @@ void play_startup_tone()
597{ 478{
598} 479}
599 480
600
601
602__attribute__ ((weak)) 481__attribute__ ((weak))
603void play_goodbye_tone() 482void play_goodbye_tone()
604{ 483{
605
606} 484}
607//------------------------------------------------------------------------------ 485//------------------------------------------------------------------------------
diff --git a/quantum/audio/audio.h b/quantum/audio/audio.h
index 89769507e..3d706587a 100644
--- a/quantum/audio/audio.h
+++ b/quantum/audio/audio.h
@@ -56,7 +56,7 @@ void increase_polyphony_rate(float change);
56void decrease_polyphony_rate(float change); 56void decrease_polyphony_rate(float change);
57 57
58void set_timbre(float timbre); 58void set_timbre(float timbre);
59void set_tempo(float tempo); 59void set_tempo(uint8_t tempo);
60 60
61void increase_tempo(uint8_t tempo_change); 61void increase_tempo(uint8_t tempo_change);
62void decrease_tempo(uint8_t tempo_change); 62void decrease_tempo(uint8_t tempo_change);
@@ -83,7 +83,11 @@ void play_notes(float (*np)[][2], uint16_t n_count, bool n_repeat, float n_rest)
83#define NOTE_ARRAY_SIZE(x) ((int16_t)(sizeof(x) / (sizeof(x[0])))) 83#define NOTE_ARRAY_SIZE(x) ((int16_t)(sizeof(x) / (sizeof(x[0]))))
84#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)); 84#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));
85 85
86
87bool is_playing_notes(void);
86void play_goodbye_tone(void); 88void play_goodbye_tone(void);
87void play_startup_tone(void); 89void play_startup_tone(void);
88 90
91
92
89#endif \ No newline at end of file 93#endif \ No newline at end of file
diff --git a/quantum/audio/audio_pwm.c b/quantum/audio/audio_pwm.c
new file mode 100644
index 000000000..328a253a7
--- /dev/null
+++ b/quantum/audio/audio_pwm.c
@@ -0,0 +1,643 @@
1#include <stdio.h>
2#include <string.h>
3//#include <math.h>
4#include <avr/pgmspace.h>
5#include <avr/interrupt.h>
6#include <avr/io.h>
7#include "print.h"
8#include "audio.h"
9#include "keymap_common.h"
10
11#include "eeconfig.h"
12
13#define PI 3.14159265
14
15#define CPU_PRESCALER 8
16
17
18// Timer Abstractions
19
20// TIMSK3 - Timer/Counter #3 Interrupt Mask Register
21// Turn on/off 3A interputs, stopping/enabling the ISR calls
22#define ENABLE_AUDIO_COUNTER_3_ISR TIMSK3 |= _BV(OCIE3A)
23#define DISABLE_AUDIO_COUNTER_3_ISR TIMSK3 &= ~_BV(OCIE3A)
24
25
26// TCCR3A: Timer/Counter #3 Control Register
27// Compare Output Mode (COM3An) = 0b00 = Normal port operation, OC3A disconnected from PC6
28#define ENABLE_AUDIO_COUNTER_3_OUTPUT TCCR3A |= _BV(COM3A1);
29#define DISABLE_AUDIO_COUNTER_3_OUTPUT TCCR3A &= ~(_BV(COM3A1) | _BV(COM3A0));
30
31
32#define NOTE_PERIOD ICR3
33#define NOTE_DUTY_CYCLE OCR3A
34
35
36#ifdef PWM_AUDIO
37 #include "wave.h"
38 #define SAMPLE_DIVIDER 39
39 #define SAMPLE_RATE (2000000.0/SAMPLE_DIVIDER/2048)
40 // Resistor value of 1/ (2 * PI * 10nF * (2000000 hertz / SAMPLE_DIVIDER / 10)) for 10nF cap
41
42 float places[8] = {0, 0, 0, 0, 0, 0, 0, 0};
43 uint16_t place_int = 0;
44 bool repeat = true;
45#endif
46
47void delay_us(int count) {
48 while(count--) {
49 _delay_us(1);
50 }
51}
52
53int voices = 0;
54int voice_place = 0;
55float frequency = 0;
56int volume = 0;
57long position = 0;
58
59float frequencies[8] = {0, 0, 0, 0, 0, 0, 0, 0};
60int volumes[8] = {0, 0, 0, 0, 0, 0, 0, 0};
61bool sliding = false;
62
63float place = 0;
64
65uint8_t * sample;
66uint16_t sample_length = 0;
67// float freq = 0;
68
69bool playing_notes = false;
70bool playing_note = false;
71float note_frequency = 0;
72float note_length = 0;
73uint8_t note_tempo = TEMPO_DEFAULT;
74float note_timbre = TIMBRE_DEFAULT;
75uint16_t note_position = 0;
76float (* notes_pointer)[][2];
77uint16_t notes_count;
78bool notes_repeat;
79float notes_rest;
80bool note_resting = false;
81
82uint8_t current_note = 0;
83uint8_t rest_counter = 0;
84
85#ifdef VIBRATO_ENABLE
86float vibrato_counter = 0;
87float vibrato_strength = .5;
88float vibrato_rate = 0.125;
89#endif
90
91float polyphony_rate = 0;
92
93static bool audio_initialized = false;
94
95audio_config_t audio_config;
96
97uint16_t envelope_index = 0;
98
99void audio_init() {
100
101 // Check EEPROM
102 if (!eeconfig_is_enabled())
103 {
104 eeconfig_init();
105 }
106 audio_config.raw = eeconfig_read_audio();
107
108 #ifdef PWM_AUDIO
109
110 PLLFRQ = _BV(PDIV2);
111 PLLCSR = _BV(PLLE);
112 while(!(PLLCSR & _BV(PLOCK)));
113 PLLFRQ |= _BV(PLLTM0); /* PCK 48MHz */
114
115 /* Init a fast PWM on Timer4 */
116 TCCR4A = _BV(COM4A0) | _BV(PWM4A); /* Clear OC4A on Compare Match */
117 TCCR4B = _BV(CS40); /* No prescaling => f = PCK/256 = 187500Hz */
118 OCR4A = 0;
119
120 /* Enable the OC4A output */
121 DDRC |= _BV(PORTC6);
122
123 DISABLE_AUDIO_COUNTER_3_ISR; // Turn off 3A interputs
124
125 TCCR3A = 0x0; // Options not needed
126 TCCR3B = _BV(CS31) | _BV(CS30) | _BV(WGM32); // 64th prescaling and CTC
127 OCR3A = SAMPLE_DIVIDER - 1; // Correct count/compare, related to sample playback
128
129 #else
130
131 // Set port PC6 (OC3A and /OC4A) as output
132 DDRC |= _BV(PORTC6);
133
134 DISABLE_AUDIO_COUNTER_3_ISR;
135
136 // TCCR3A / TCCR3B: Timer/Counter #3 Control Registers
137 // Compare Output Mode (COM3An) = 0b00 = Normal port operation, OC3A disconnected from PC6
138 // Waveform Generation Mode (WGM3n) = 0b1110 = Fast PWM Mode 14 (Period = ICR3, Duty Cycle = OCR3A)
139 // Clock Select (CS3n) = 0b010 = Clock / 8
140 TCCR3A = (0 << COM3A1) | (0 << COM3A0) | (1 << WGM31) | (0 << WGM30);
141 TCCR3B = (1 << WGM33) | (1 << WGM32) | (0 << CS32) | (1 << CS31) | (0 << CS30);
142
143 #endif
144
145 audio_initialized = true;
146}
147
148void stop_all_notes() {
149 if (!audio_initialized) {
150 audio_init();
151 }
152 voices = 0;
153 #ifdef PWM_AUDIO
154 DISABLE_AUDIO_COUNTER_3_ISR;
155 #else
156 DISABLE_AUDIO_COUNTER_3_ISR;
157 DISABLE_AUDIO_COUNTER_3_OUTPUT;
158 #endif
159
160 playing_notes = false;
161 playing_note = false;
162 frequency = 0;
163 volume = 0;
164
165 for (uint8_t i = 0; i < 8; i++)
166 {
167 frequencies[i] = 0;
168 volumes[i] = 0;
169 }
170}
171
172void stop_note(float freq)
173{
174 if (playing_note) {
175 if (!audio_initialized) {
176 audio_init();
177 }
178 #ifdef PWM_AUDIO
179 freq = freq / SAMPLE_RATE;
180 #endif
181 for (int i = 7; i >= 0; i--) {
182 if (frequencies[i] == freq) {
183 frequencies[i] = 0;
184 volumes[i] = 0;
185 for (int j = i; (j < 7); j++) {
186 frequencies[j] = frequencies[j+1];
187 frequencies[j+1] = 0;
188 volumes[j] = volumes[j+1];
189 volumes[j+1] = 0;
190 }
191 break;
192 }
193 }
194 voices--;
195 if (voices < 0)
196 voices = 0;
197 if (voice_place >= voices) {
198 voice_place = 0;
199 }
200 if (voices == 0) {
201 #ifdef PWM_AUDIO
202 DISABLE_AUDIO_COUNTER_3_ISR;
203 #else
204 DISABLE_AUDIO_COUNTER_3_ISR;
205 DISABLE_AUDIO_COUNTER_3_OUTPUT;
206 #endif
207 frequency = 0;
208 volume = 0;
209 playing_note = false;
210 }
211 }
212}
213
214#ifdef VIBRATO_ENABLE
215
216float mod(float a, int b)
217{
218 float r = fmod(a, b);
219 return r < 0 ? r + b : r;
220}
221
222float vibrato(float average_freq) {
223 #ifdef VIBRATO_STRENGTH_ENABLE
224 float vibrated_freq = average_freq * pow(vibrato_lut[(int)vibrato_counter], vibrato_strength);
225 #else
226 float vibrated_freq = average_freq * vibrato_lut[(int)vibrato_counter];
227 #endif
228 vibrato_counter = mod((vibrato_counter + vibrato_rate * (1.0 + 440.0/average_freq)), VIBRATO_LUT_LENGTH);
229 return vibrated_freq;
230}
231
232#endif
233
234ISR(TIMER3_COMPA_vect)
235{
236 if (playing_note) {
237 #ifdef PWM_AUDIO
238 if (voices == 1) {
239 // SINE
240 OCR4A = pgm_read_byte(&sinewave[(uint16_t)place]) >> 2;
241
242 // SQUARE
243 // if (((int)place) >= 1024){
244 // OCR4A = 0xFF >> 2;
245 // } else {
246 // OCR4A = 0x00;
247 // }
248
249 // SAWTOOTH
250 // OCR4A = (int)place / 4;
251
252 // TRIANGLE
253 // if (((int)place) >= 1024) {
254 // OCR4A = (int)place / 2;
255 // } else {
256 // OCR4A = 2048 - (int)place / 2;
257 // }
258
259 place += frequency;
260
261 if (place >= SINE_LENGTH)
262 place -= SINE_LENGTH;
263
264 } else {
265 int sum = 0;
266 for (int i = 0; i < voices; i++) {
267 // SINE
268 sum += pgm_read_byte(&sinewave[(uint16_t)places[i]]) >> 2;
269
270 // SQUARE
271 // if (((int)places[i]) >= 1024){
272 // sum += 0xFF >> 2;
273 // } else {
274 // sum += 0x00;
275 // }
276
277 places[i] += frequencies[i];
278
279 if (places[i] >= SINE_LENGTH)
280 places[i] -= SINE_LENGTH;
281 }
282 OCR4A = sum;
283 }
284 #else
285 if (voices > 0) {
286 float freq;
287 if (polyphony_rate > 0) {
288 if (voices > 1) {
289 voice_place %= voices;
290 if (place++ > (frequencies[voice_place] / polyphony_rate / CPU_PRESCALER)) {
291 voice_place = (voice_place + 1) % voices;
292 place = 0.0;
293 }
294 }
295 #ifdef VIBRATO_ENABLE
296 if (vibrato_strength > 0) {
297 freq = vibrato(frequencies[voice_place]);
298 } else {
299 #else
300 {
301 #endif
302 freq = frequencies[voice_place];
303 }
304 } else {
305 if (frequency != 0 && frequency < frequencies[voices - 1] && frequency < frequencies[voices - 1] * pow(2, -440/frequencies[voices - 1]/12/2)) {
306 frequency = frequency * pow(2, 440/frequency/12/2);
307 } else if (frequency != 0 && frequency > frequencies[voices - 1] && frequency > frequencies[voices - 1] * pow(2, 440/frequencies[voices - 1]/12/2)) {
308 frequency = frequency * pow(2, -440/frequency/12/2);
309 } else {
310 frequency = frequencies[voices - 1];
311 }
312
313
314 #ifdef VIBRATO_ENABLE
315 if (vibrato_strength > 0) {
316 freq = vibrato(frequency);
317 } else {
318 #else
319 {
320 #endif
321 freq = frequency;
322 }
323 }
324
325 if (envelope_index < 65535) {
326 envelope_index++;
327 }
328 freq = voice_envelope(freq);
329
330 if (freq < 30.517578125)
331 freq = 30.52;
332 NOTE_PERIOD = (int)(((double)F_CPU) / (freq * CPU_PRESCALER)); // Set max to the period
333 NOTE_DUTY_CYCLE = (int)((((double)F_CPU) / (freq * CPU_PRESCALER)) * note_timbre); // Set compare to half the period
334 }
335 #endif
336 }
337
338 // SAMPLE
339 // OCR4A = pgm_read_byte(&sample[(uint16_t)place_int]);
340
341 // place_int++;
342
343 // if (place_int >= sample_length)
344 // if (repeat)
345 // place_int -= sample_length;
346 // else
347 // DISABLE_AUDIO_COUNTER_3_ISR;
348
349
350 if (playing_notes) {
351 #ifdef PWM_AUDIO
352 OCR4A = pgm_read_byte(&sinewave[(uint16_t)place]) >> 0;
353
354 place += note_frequency;
355 if (place >= SINE_LENGTH)
356 place -= SINE_LENGTH;
357 #else
358 if (note_frequency > 0) {
359 float freq;
360
361 #ifdef VIBRATO_ENABLE
362 if (vibrato_strength > 0) {
363 freq = vibrato(note_frequency);
364 } else {
365 #else
366 {
367 #endif
368 freq = note_frequency;
369 }
370
371 if (envelope_index < 65535) {
372 envelope_index++;
373 }
374 freq = voice_envelope(freq);
375
376 NOTE_PERIOD = (int)(((double)F_CPU) / (freq * CPU_PRESCALER)); // Set max to the period
377 NOTE_DUTY_CYCLE = (int)((((double)F_CPU) / (freq * CPU_PRESCALER)) * note_timbre); // Set compare to half the period
378 } else {
379 NOTE_PERIOD = 0;
380 NOTE_DUTY_CYCLE = 0;
381 }
382 #endif
383
384
385 note_position++;
386 bool end_of_note = false;
387 if (NOTE_PERIOD > 0)
388 end_of_note = (note_position >= (note_length / NOTE_PERIOD * 0xFFFF));
389 else
390 end_of_note = (note_position >= (note_length * 0x7FF));
391 if (end_of_note) {
392 current_note++;
393 if (current_note >= notes_count) {
394 if (notes_repeat) {
395 current_note = 0;
396 } else {
397 #ifdef PWM_AUDIO
398 DISABLE_AUDIO_COUNTER_3_ISR;
399 #else
400 DISABLE_AUDIO_COUNTER_3_ISR;
401 DISABLE_AUDIO_COUNTER_3_OUTPUT;
402 #endif
403 playing_notes = false;
404 return;
405 }
406 }
407 if (!note_resting && (notes_rest > 0)) {
408 note_resting = true;
409 note_frequency = 0;
410 note_length = notes_rest;
411 current_note--;
412 } else {
413 note_resting = false;
414 #ifdef PWM_AUDIO
415 note_frequency = (*notes_pointer)[current_note][0] / SAMPLE_RATE;
416 note_length = (*notes_pointer)[current_note][1] * (((float)note_tempo) / 100);
417 #else
418 envelope_index = 0;
419 note_frequency = (*notes_pointer)[current_note][0];
420 note_length = ((*notes_pointer)[current_note][1] / 4) * (((float)note_tempo) / 100);
421 #endif
422 }
423 note_position = 0;
424 }
425
426 }
427
428 if (!audio_config.enable) {
429 playing_notes = false;
430 playing_note = false;
431 }
432}
433
434void play_note(float freq, int vol) {
435
436 if (!audio_initialized) {
437 audio_init();
438 }
439
440 if (audio_config.enable && voices < 8) {
441 DISABLE_AUDIO_COUNTER_3_ISR;
442
443 // Cancel notes if notes are playing
444 if (playing_notes)
445 stop_all_notes();
446
447 playing_note = true;
448
449 envelope_index = 0;
450
451 #ifdef PWM_AUDIO
452 freq = freq / SAMPLE_RATE;
453 #endif
454 if (freq > 0) {
455 frequencies[voices] = freq;
456 volumes[voices] = vol;
457 voices++;
458 }
459
460 #ifdef PWM_AUDIO
461 ENABLE_AUDIO_COUNTER_3_ISR;
462 #else
463 ENABLE_AUDIO_COUNTER_3_ISR;
464 ENABLE_AUDIO_COUNTER_3_OUTPUT;
465 #endif
466 }
467
468}
469
470void play_notes(float (*np)[][2], uint16_t n_count, bool n_repeat, float n_rest)
471{
472
473 if (!audio_initialized) {
474 audio_init();
475 }
476
477 if (audio_config.enable) {
478
479 DISABLE_AUDIO_COUNTER_3_ISR;
480
481 // Cancel note if a note is playing
482 if (playing_note)
483 stop_all_notes();
484
485 playing_notes = true;
486
487 notes_pointer = np;
488 notes_count = n_count;
489 notes_repeat = n_repeat;
490 notes_rest = n_rest;
491
492 place = 0;
493 current_note = 0;
494
495 #ifdef PWM_AUDIO
496 note_frequency = (*notes_pointer)[current_note][0] / SAMPLE_RATE;
497 note_length = (*notes_pointer)[current_note][1] * (((float)note_tempo) / 100);
498 #else
499 note_frequency = (*notes_pointer)[current_note][0];
500 note_length = ((*notes_pointer)[current_note][1] / 4) * (((float)note_tempo) / 100);
501 #endif
502 note_position = 0;
503
504
505 #ifdef PWM_AUDIO
506 ENABLE_AUDIO_COUNTER_3_ISR;
507 #else
508 ENABLE_AUDIO_COUNTER_3_ISR;
509 ENABLE_AUDIO_COUNTER_3_OUTPUT;
510 #endif
511 }
512
513}
514
515#ifdef PWM_AUDIO
516void play_sample(uint8_t * s, uint16_t l, bool r) {
517 if (!audio_initialized) {
518 audio_init();
519 }
520
521 if (audio_config.enable) {
522 DISABLE_AUDIO_COUNTER_3_ISR;
523 stop_all_notes();
524 place_int = 0;
525 sample = s;
526 sample_length = l;
527 repeat = r;
528
529 ENABLE_AUDIO_COUNTER_3_ISR;
530 }
531}
532#endif
533
534
535void audio_toggle(void) {
536 audio_config.enable ^= 1;
537 eeconfig_update_audio(audio_config.raw);
538}
539
540void audio_on(void) {
541 audio_config.enable = 1;
542 eeconfig_update_audio(audio_config.raw);
543}
544
545void audio_off(void) {
546 audio_config.enable = 0;
547 eeconfig_update_audio(audio_config.raw);
548}
549
550#ifdef VIBRATO_ENABLE
551
552// Vibrato rate functions
553
554void set_vibrato_rate(float rate) {
555 vibrato_rate = rate;
556}
557
558void increase_vibrato_rate(float change) {
559 vibrato_rate *= change;
560}
561
562void decrease_vibrato_rate(float change) {
563 vibrato_rate /= change;
564}
565
566#ifdef VIBRATO_STRENGTH_ENABLE
567
568void set_vibrato_strength(float strength) {
569 vibrato_strength = strength;
570}
571
572void increase_vibrato_strength(float change) {
573 vibrato_strength *= change;
574}
575
576void decrease_vibrato_strength(float change) {
577 vibrato_strength /= change;
578}
579
580#endif /* VIBRATO_STRENGTH_ENABLE */
581
582#endif /* VIBRATO_ENABLE */
583
584// Polyphony functions
585
586void set_polyphony_rate(float rate) {
587 polyphony_rate = rate;
588}
589
590void enable_polyphony() {
591 polyphony_rate = 5;
592}
593
594void disable_polyphony() {
595 polyphony_rate = 0;
596}
597
598void increase_polyphony_rate(float change) {
599 polyphony_rate *= change;
600}
601
602void decrease_polyphony_rate(float change) {
603 polyphony_rate /= change;
604}
605
606// Timbre function
607
608void set_timbre(float timbre) {
609 note_timbre = timbre;
610}
611
612// Tempo functions
613
614void set_tempo(uint8_t tempo) {
615 note_tempo = tempo;
616}
617
618void decrease_tempo(uint8_t tempo_change) {
619 note_tempo += tempo_change;
620}
621
622void increase_tempo(uint8_t tempo_change) {
623 if (note_tempo - tempo_change < 10) {
624 note_tempo = 10;
625 } else {
626 note_tempo -= tempo_change;
627 }
628}
629
630
631//------------------------------------------------------------------------------
632// Override these functions in your keymap file to play different tunes on
633// startup and bootloader jump
634__attribute__ ((weak))
635void play_startup_tone()
636{
637}
638
639__attribute__ ((weak))
640void play_goodbye_tone()
641{
642}
643//------------------------------------------------------------------------------
diff --git a/quantum/audio/frequency_lut.h b/quantum/audio/frequency_lut.h
deleted file mode 100644
index e62da5be4..000000000
--- a/quantum/audio/frequency_lut.h
+++ /dev/null
@@ -1,357 +0,0 @@
1#include <avr/io.h>
2#include <avr/interrupt.h>
3#include <avr/pgmspace.h>
4
5#define FREQUENCY_LUT_LENGTH 349
6
7const uint16_t FREQUENCY_LUT[FREQUENCY_LUT_LENGTH] = {
80x8E0B,
90x8C02,
100x8A00,
110x8805,
120x8612,
130x8426,
140x8241,
150x8063,
160x7E8C,
170x7CBB,
180x7AF2,
190x792E,
200x7772,
210x75BB,
220x740B,
230x7261,
240x70BD,
250x6F20,
260x6D88,
270x6BF6,
280x6A69,
290x68E3,
300x6762,
310x65E6,
320x6470,
330x6300,
340x6194,
350x602E,
360x5ECD,
370x5D71,
380x5C1A,
390x5AC8,
400x597B,
410x5833,
420x56EF,
430x55B0,
440x5475,
450x533F,
460x520E,
470x50E1,
480x4FB8,
490x4E93,
500x4D73,
510x4C57,
520x4B3E,
530x4A2A,
540x491A,
550x480E,
560x4705,
570x4601,
580x4500,
590x4402,
600x4309,
610x4213,
620x4120,
630x4031,
640x3F46,
650x3E5D,
660x3D79,
670x3C97,
680x3BB9,
690x3ADD,
700x3A05,
710x3930,
720x385E,
730x3790,
740x36C4,
750x35FB,
760x3534,
770x3471,
780x33B1,
790x32F3,
800x3238,
810x3180,
820x30CA,
830x3017,
840x2F66,
850x2EB8,
860x2E0D,
870x2D64,
880x2CBD,
890x2C19,
900x2B77,
910x2AD8,
920x2A3A,
930x299F,
940x2907,
950x2870,
960x27DC,
970x2749,
980x26B9,
990x262B,
1000x259F,
1010x2515,
1020x248D,
1030x2407,
1040x2382,
1050x2300,
1060x2280,
1070x2201,
1080x2184,
1090x2109,
1100x2090,
1110x2018,
1120x1FA3,
1130x1F2E,
1140x1EBC,
1150x1E4B,
1160x1DDC,
1170x1D6E,
1180x1D02,
1190x1C98,
1200x1C2F,
1210x1BC8,
1220x1B62,
1230x1AFD,
1240x1A9A,
1250x1A38,
1260x19D8,
1270x1979,
1280x191C,
1290x18C0,
1300x1865,
1310x180B,
1320x17B3,
1330x175C,
1340x1706,
1350x16B2,
1360x165E,
1370x160C,
1380x15BB,
1390x156C,
1400x151D,
1410x14CF,
1420x1483,
1430x1438,
1440x13EE,
1450x13A4,
1460x135C,
1470x1315,
1480x12CF,
1490x128A,
1500x1246,
1510x1203,
1520x11C1,
1530x1180,
1540x1140,
1550x1100,
1560x10C2,
1570x1084,
1580x1048,
1590x100C,
1600xFD1,
1610xF97,
1620xF5E,
1630xF25,
1640xEEE,
1650xEB7,
1660xE81,
1670xE4C,
1680xE17,
1690xDE4,
1700xDB1,
1710xD7E,
1720xD4D,
1730xD1C,
1740xCEC,
1750xCBC,
1760xC8E,
1770xC60,
1780xC32,
1790xC05,
1800xBD9,
1810xBAE,
1820xB83,
1830xB59,
1840xB2F,
1850xB06,
1860xADD,
1870xAB6,
1880xA8E,
1890xA67,
1900xA41,
1910xA1C,
1920x9F7,
1930x9D2,
1940x9AE,
1950x98A,
1960x967,
1970x945,
1980x923,
1990x901,
2000x8E0,
2010x8C0,
2020x8A0,
2030x880,
2040x861,
2050x842,
2060x824,
2070x806,
2080x7E8,
2090x7CB,
2100x7AF,
2110x792,
2120x777,
2130x75B,
2140x740,
2150x726,
2160x70B,
2170x6F2,
2180x6D8,
2190x6BF,
2200x6A6,
2210x68E,
2220x676,
2230x65E,
2240x647,
2250x630,
2260x619,
2270x602,
2280x5EC,
2290x5D7,
2300x5C1,
2310x5AC,
2320x597,
2330x583,
2340x56E,
2350x55B,
2360x547,
2370x533,
2380x520,
2390x50E,
2400x4FB,
2410x4E9,
2420x4D7,
2430x4C5,
2440x4B3,
2450x4A2,
2460x491,
2470x480,
2480x470,
2490x460,
2500x450,
2510x440,
2520x430,
2530x421,
2540x412,
2550x403,
2560x3F4,
2570x3E5,
2580x3D7,
2590x3C9,
2600x3BB,
2610x3AD,
2620x3A0,
2630x393,
2640x385,
2650x379,
2660x36C,
2670x35F,
2680x353,
2690x347,
2700x33B,
2710x32F,
2720x323,
2730x318,
2740x30C,
2750x301,
2760x2F6,
2770x2EB,
2780x2E0,
2790x2D6,
2800x2CB,
2810x2C1,
2820x2B7,
2830x2AD,
2840x2A3,
2850x299,
2860x290,
2870x287,
2880x27D,
2890x274,
2900x26B,
2910x262,
2920x259,
2930x251,
2940x248,
2950x240,
2960x238,
2970x230,
2980x228,
2990x220,
3000x218,
3010x210,
3020x209,
3030x201,
3040x1FA,
3050x1F2,
3060x1EB,
3070x1E4,
3080x1DD,
3090x1D6,
3100x1D0,
3110x1C9,
3120x1C2,
3130x1BC,
3140x1B6,
3150x1AF,
3160x1A9,
3170x1A3,
3180x19D,
3190x197,
3200x191,
3210x18C,
3220x186,
3230x180,
3240x17B,
3250x175,
3260x170,
3270x16B,
3280x165,
3290x160,
3300x15B,
3310x156,
3320x151,
3330x14C,
3340x148,
3350x143,
3360x13E,
3370x13A,
3380x135,
3390x131,
3400x12C,
3410x128,
3420x124,
3430x120,
3440x11C,
3450x118,
3460x114,
3470x110,
3480x10C,
3490x108,
3500x104,
3510x100,
3520xFD,
3530xF9,
3540xF5,
3550xF2,
3560xEE
357}; \ No newline at end of file
diff --git a/quantum/audio/luts.c b/quantum/audio/luts.c
new file mode 100644
index 000000000..9f3de9a05
--- /dev/null
+++ b/quantum/audio/luts.c
@@ -0,0 +1,382 @@
1#include <avr/io.h>
2#include <avr/interrupt.h>
3#include <avr/pgmspace.h>
4#include "luts.h"
5
6const float vibrato_lut[VIBRATO_LUT_LENGTH] =
7{
8 1.0022336811487,
9 1.0042529943610,
10 1.0058584256028,
11 1.0068905285205,
12 1.0072464122237,
13 1.0068905285205,
14 1.0058584256028,
15 1.0042529943610,
16 1.0022336811487,
17 1.0000000000000,
18 0.9977712970630,
19 0.9957650169978,
20 0.9941756956510,
21 0.9931566259436,
22 0.9928057204913,
23 0.9931566259436,
24 0.9941756956510,
25 0.9957650169978,
26 0.9977712970630,
27 1.0000000000000,
28};
29
30const uint16_t frequency_lut[FREQUENCY_LUT_LENGTH] =
31{
32 0x8E0B,
33 0x8C02,
34 0x8A00,
35 0x8805,
36 0x8612,
37 0x8426,
38 0x8241,
39 0x8063,
40 0x7E8C,
41 0x7CBB,
42 0x7AF2,
43 0x792E,
44 0x7772,
45 0x75BB,
46 0x740B,
47 0x7261,
48 0x70BD,
49 0x6F20,
50 0x6D88,
51 0x6BF6,
52 0x6A69,
53 0x68E3,
54 0x6762,
55 0x65E6,
56 0x6470,
57 0x6300,
58 0x6194,
59 0x602E,
60 0x5ECD,
61 0x5D71,
62 0x5C1A,
63 0x5AC8,
64 0x597B,
65 0x5833,
66 0x56EF,
67 0x55B0,
68 0x5475,
69 0x533F,
70 0x520E,
71 0x50E1,
72 0x4FB8,
73 0x4E93,
74 0x4D73,
75 0x4C57,
76 0x4B3E,
77 0x4A2A,
78 0x491A,
79 0x480E,
80 0x4705,
81 0x4601,
82 0x4500,
83 0x4402,
84 0x4309,
85 0x4213,
86 0x4120,
87 0x4031,
88 0x3F46,
89 0x3E5D,
90 0x3D79,
91 0x3C97,
92 0x3BB9,
93 0x3ADD,
94 0x3A05,
95 0x3930,
96 0x385E,
97 0x3790,
98 0x36C4,
99 0x35FB,
100 0x3534,
101 0x3471,
102 0x33B1,
103 0x32F3,
104 0x3238,
105 0x3180,
106 0x30CA,
107 0x3017,
108 0x2F66,
109 0x2EB8,
110 0x2E0D,
111 0x2D64,
112 0x2CBD,
113 0x2C19,
114 0x2B77,
115 0x2AD8,
116 0x2A3A,
117 0x299F,
118 0x2907,
119 0x2870,
120 0x27DC,
121 0x2749,
122 0x26B9,
123 0x262B,
124 0x259F,
125 0x2515,
126 0x248D,
127 0x2407,
128 0x2382,
129 0x2300,
130 0x2280,
131 0x2201,
132 0x2184,
133 0x2109,
134 0x2090,
135 0x2018,
136 0x1FA3,
137 0x1F2E,
138 0x1EBC,
139 0x1E4B,
140 0x1DDC,
141 0x1D6E,
142 0x1D02,
143 0x1C98,
144 0x1C2F,
145 0x1BC8,
146 0x1B62,
147 0x1AFD,
148 0x1A9A,
149 0x1A38,
150 0x19D8,
151 0x1979,
152 0x191C,
153 0x18C0,
154 0x1865,
155 0x180B,
156 0x17B3,
157 0x175C,
158 0x1706,
159 0x16B2,
160 0x165E,
161 0x160C,
162 0x15BB,
163 0x156C,
164 0x151D,
165 0x14CF,
166 0x1483,
167 0x1438,
168 0x13EE,
169 0x13A4,
170 0x135C,
171 0x1315,
172 0x12CF,
173 0x128A,
174 0x1246,
175 0x1203,
176 0x11C1,
177 0x1180,
178 0x1140,
179 0x1100,
180 0x10C2,
181 0x1084,
182 0x1048,
183 0x100C,
184 0xFD1,
185 0xF97,
186 0xF5E,
187 0xF25,
188 0xEEE,
189 0xEB7,
190 0xE81,
191 0xE4C,
192 0xE17,
193 0xDE4,
194 0xDB1,
195 0xD7E,
196 0xD4D,
197 0xD1C,
198 0xCEC,
199 0xCBC,
200 0xC8E,
201 0xC60,
202 0xC32,
203 0xC05,
204 0xBD9,
205 0xBAE,
206 0xB83,
207 0xB59,
208 0xB2F,
209 0xB06,
210 0xADD,
211 0xAB6,
212 0xA8E,
213 0xA67,
214 0xA41,
215 0xA1C,
216 0x9F7,
217 0x9D2,
218 0x9AE,
219 0x98A,
220 0x967,
221 0x945,
222 0x923,
223 0x901,
224 0x8E0,
225 0x8C0,
226 0x8A0,
227 0x880,
228 0x861,
229 0x842,
230 0x824,
231 0x806,
232 0x7E8,
233 0x7CB,
234 0x7AF,
235 0x792,
236 0x777,
237 0x75B,
238 0x740,
239 0x726,
240 0x70B,
241 0x6F2,
242 0x6D8,
243 0x6BF,
244 0x6A6,
245 0x68E,
246 0x676,
247 0x65E,
248 0x647,
249 0x630,
250 0x619,
251 0x602,
252 0x5EC,
253 0x5D7,
254 0x5C1,
255 0x5AC,
256 0x597,
257 0x583,
258 0x56E,
259 0x55B,
260 0x547,
261 0x533,
262 0x520,
263 0x50E,
264 0x4FB,
265 0x4E9,
266 0x4D7,
267 0x4C5,
268 0x4B3,
269 0x4A2,
270 0x491,
271 0x480,
272 0x470,
273 0x460,
274 0x450,
275 0x440,
276 0x430,
277 0x421,
278 0x412,
279 0x403,
280 0x3F4,
281 0x3E5,
282 0x3D7,
283 0x3C9,
284 0x3BB,
285 0x3AD,
286 0x3A0,
287 0x393,
288 0x385,
289 0x379,
290 0x36C,
291 0x35F,
292 0x353,
293 0x347,
294 0x33B,
295 0x32F,
296 0x323,
297 0x318,
298 0x30C,
299 0x301,
300 0x2F6,
301 0x2EB,
302 0x2E0,
303 0x2D6,
304 0x2CB,
305 0x2C1,
306 0x2B7,
307 0x2AD,
308 0x2A3,
309 0x299,
310 0x290,
311 0x287,
312 0x27D,
313 0x274,
314 0x26B,
315 0x262,
316 0x259,
317 0x251,
318 0x248,
319 0x240,
320 0x238,
321 0x230,
322 0x228,
323 0x220,
324 0x218,
325 0x210,
326 0x209,
327 0x201,
328 0x1FA,
329 0x1F2,
330 0x1EB,
331 0x1E4,
332 0x1DD,
333 0x1D6,
334 0x1D0,
335 0x1C9,
336 0x1C2,
337 0x1BC,
338 0x1B6,
339 0x1AF,
340 0x1A9,
341 0x1A3,
342 0x19D,
343 0x197,
344 0x191,
345 0x18C,
346 0x186,
347 0x180,
348 0x17B,
349 0x175,
350 0x170,
351 0x16B,
352 0x165,
353 0x160,
354 0x15B,
355 0x156,
356 0x151,
357 0x14C,
358 0x148,
359 0x143,
360 0x13E,
361 0x13A,
362 0x135,
363 0x131,
364 0x12C,
365 0x128,
366 0x124,
367 0x120,
368 0x11C,
369 0x118,
370 0x114,
371 0x110,
372 0x10C,
373 0x108,
374 0x104,
375 0x100,
376 0xFD,
377 0xF9,
378 0xF5,
379 0xF2,
380 0xEE,
381};
382
diff --git a/quantum/audio/luts.h b/quantum/audio/luts.h
new file mode 100644
index 000000000..7df3078a7
--- /dev/null
+++ b/quantum/audio/luts.h
@@ -0,0 +1,15 @@
1#include <avr/io.h>
2#include <avr/interrupt.h>
3#include <avr/pgmspace.h>
4
5#ifndef LUTS_H
6#define LUTS_H
7
8#define VIBRATO_LUT_LENGTH 20
9
10#define FREQUENCY_LUT_LENGTH 349
11
12extern const float vibrato_lut[VIBRATO_LUT_LENGTH];
13extern const uint16_t frequency_lut[FREQUENCY_LUT_LENGTH];
14
15#endif /* LUTS_H */ \ No newline at end of file
diff --git a/quantum/audio/vibrato_lut.h b/quantum/audio/vibrato_lut.h
deleted file mode 100644
index a2b1f3e5c..000000000
--- a/quantum/audio/vibrato_lut.h
+++ /dev/null
@@ -1,28 +0,0 @@
1#include <avr/io.h>
2#include <avr/interrupt.h>
3#include <avr/pgmspace.h>
4
5#define VIBRATO_LUT_LENGTH 20
6
7const float VIBRATO_LUT[VIBRATO_LUT_LENGTH] = { \
81.00223368114872,
91.00425299436105,
101.00585842560279,
111.00689052852052,
121.0072464122237,
131.00689052852052,
141.00585842560279,
151.00425299436105,
161.00223368114872,
171,
180.99777129706302,
190.99576501699778,
200.994175695650927,
210.993156625943589,
220.992805720491269,
230.993156625943589,
240.994175695650927,
250.99576501699778,
260.99777129706302,
271
28}; \ No newline at end of file
diff --git a/quantum/audio/voices.c b/quantum/audio/voices.c
index d2316ba1b..6d4172a06 100644
--- a/quantum/audio/voices.c
+++ b/quantum/audio/voices.c
@@ -1,6 +1,6 @@
1#include "voices.h" 1#include "voices.h"
2#include "audio.h"
2#include "stdlib.h" 3#include "stdlib.h"
3#include "vibrato_lut.h"
4 4
5// these are imported from audio.c 5// these are imported from audio.c
6extern uint16_t envelope_index; 6extern uint16_t envelope_index;
@@ -109,7 +109,7 @@ float voice_envelope(float frequency) {
109 case 0 ... VOICE_VIBRATO_DELAY: 109 case 0 ... VOICE_VIBRATO_DELAY:
110 break; 110 break;
111 default: 111 default:
112 frequency = frequency * VIBRATO_LUT[(int)fmod((((float)compensated_index - (VOICE_VIBRATO_DELAY + 1))/1000*VOICE_VIBRATO_SPEED), VIBRATO_LUT_LENGTH)]; 112 frequency = frequency * vibrato_lut[(int)fmod((((float)compensated_index - (VOICE_VIBRATO_DELAY + 1))/1000*VOICE_VIBRATO_SPEED), VIBRATO_LUT_LENGTH)];
113 break; 113 break;
114 } 114 }
115 break; 115 break;
@@ -160,4 +160,6 @@ float voice_envelope(float frequency) {
160 } 160 }
161 161
162 return frequency; 162 return frequency;
163} \ No newline at end of file 163}
164
165
diff --git a/quantum/audio/voices.h b/quantum/audio/voices.h
index 74c873f42..b2495b23b 100644
--- a/quantum/audio/voices.h
+++ b/quantum/audio/voices.h
@@ -2,8 +2,7 @@
2#include <stdbool.h> 2#include <stdbool.h>
3#include <avr/io.h> 3#include <avr/io.h>
4#include <util/delay.h> 4#include <util/delay.h>
5#include "musical_notes.h" 5#include "luts.h"
6#include "song_list.h"
7 6
8#ifndef VOICES_H 7#ifndef VOICES_H
9#define VOICES_H 8#define VOICES_H
diff --git a/quantum/keymap_common.c b/quantum/keymap_common.c
index 4b4bd6210..5e78d1157 100644
--- a/quantum/keymap_common.c
+++ b/quantum/keymap_common.c
@@ -24,10 +24,14 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
24#include "action_macro.h" 24#include "action_macro.h"
25#include "debug.h" 25#include "debug.h"
26#include "backlight.h" 26#include "backlight.h"
27#include "keymap_midi.h"
28#include "bootloader.h" 27#include "bootloader.h"
29#include "eeconfig.h" 28#include "eeconfig.h"
30 29
30#ifdef MIDI_ENABLE
31 #include "keymap_midi.h"
32#endif
33
34
31extern keymap_config_t keymap_config; 35extern keymap_config_t keymap_config;
32 36
33#include <stdio.h> 37#include <stdio.h>
diff --git a/quantum/quantum.mk b/quantum/quantum.mk
index 83c4f1d1d..4a076eca4 100644
--- a/quantum/quantum.mk
+++ b/quantum/quantum.mk
@@ -29,6 +29,7 @@ endif
29 29
30ifeq ($(strip $(AUDIO_ENABLE)), yes) 30ifeq ($(strip $(AUDIO_ENABLE)), yes)
31 SRC += $(QUANTUM_DIR)/audio/audio.c $(QUANTUM_DIR)/audio/voices.c 31 SRC += $(QUANTUM_DIR)/audio/audio.c $(QUANTUM_DIR)/audio/voices.c
32 SRC += $(QUANTUM_DIR)/audio/audio.c $(QUANTUM_DIR)/audio/luts.c
32endif 33endif
33 34
34ifeq ($(strip $(UNICODE_ENABLE)), yes) 35ifeq ($(strip $(UNICODE_ENABLE)), yes)