From 29de37d5c0ea9fc6b5539ce4493c7b10a2a7f33f Mon Sep 17 00:00:00 2001
From: Jack Humbert <jack.humb@gmail.com>
Date: Mon, 11 Jan 2016 16:53:33 -0500
Subject: [PATCH 1/6] pwm audio

---
 .../ergodox_ez/keymaps/keymap_generated.c     |  78 ++++++
 keyboard/ergodox_ez/keymaps/keymap_jack.c     |  69 +----
 keyboard/planck/Makefile                      |   4 +-
 keyboard/planck/keymaps/keymap_eric.c         |  42 +++
 keyboard/planck/keymaps/keymap_lock.c         |  10 +-
 keyboard/planck/planck.c                      |  29 ++
 keyboard/planck/planck.h                      |   5 +-
 quantum/beeps.c                               | 245 ++++++++++------
 quantum/beeps.h                               |   2 +-
 quantum/keymap_midi.c                         |  21 +-
 quantum/keymap_midi.h                         |   2 +
 quantum/wave.h                                | 265 ++++++++++++++++++
 tmk_core/common/avr/timer.c                   |  18 +-
 13 files changed, 600 insertions(+), 190 deletions(-)
 create mode 100644 keyboard/ergodox_ez/keymaps/keymap_generated.c
 create mode 100644 keyboard/planck/keymaps/keymap_eric.c
 create mode 100644 quantum/wave.h

diff --git a/keyboard/ergodox_ez/keymaps/keymap_generated.c b/keyboard/ergodox_ez/keymaps/keymap_generated.c
new file mode 100644
index 0000000000..54fd3059f2
--- /dev/null
+++ b/keyboard/ergodox_ez/keymaps/keymap_generated.c
@@ -0,0 +1,78 @@
+#include "ergodox_ez.h"
+#include "debug.h"
+#include "action_layer.h"
+
+const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
+
+// If it accepts an argument (i.e, is a function), it doesn't need KC_.
+// Otherwise, it needs KC_*
+
+#define SYMB 0
+
+[0] = KEYMAP( \
+\
+KC_KP_EQUAL, KC_1, KC_2, KC_3, KC_4, KC_5, KC_LEFT, KC_DELETE, KC_Q, KC_W, KC_E, KC_R, KC_T, TG(1), KC_BSPACE, KC_A, KC_S, KC_D, KC_F, KC_G, KC_LSHIFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_TRANSPARENT, KC_TRANSPARENT, KC_TRANSPARENT, KC_TAB, KC_LEFT, KC_RIGHT, KC_TRANSPARENT, KC_LGUI, KC_HOME, KC_SPACE, KC_BSPACE, KC_END, KC_RIGHT, KC_6, KC_7, KC_8, KC_9, KC_0, KC_MINUS, TG(1), KC_Y, KC_U, KC_I, KC_O, KC_P, KC_BSLASH, KC_H, KC_J, KC_K, KC_L, KC_SCOLON, KC_QUOTE, KC_TRANSPARENT, KC_N, KC_M, KC_COMMA, KC_DOT, KC_LCTRL, KC_LSHIFT, KC_UP, KC_DOWN, KC_LBRACKET, KC_RBRACKET, KC_TRANSPARENT, KC_LALT, KC_ESCAPE, KC_PGUP, KC_PGDOWN, KC_TAB, KC_ENTER \
+\
+),
+
+[1] = KEYMAP( \
+\
+KC_TRANSPARENT, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_TRANSPARENT, KC_TRANSPARENT, KC_TRANSPARENT, KC_TRANSPARENT, KC_TRANSPARENT, KC_TRANSPARENT, KC_TRANSPARENT, KC_TRANSPARENT, KC_TRANSPARENT, KC_TRANSPARENT, KC_TRANSPARENT, KC_TRANSPARENT, KC_TRANSPARENT, KC_TRANSPARENT, KC_TRANSPARENT, KC_TRANSPARENT, KC_TRANSPARENT, KC_TRANSPARENT, KC_TRANSPARENT, KC_TRANSPARENT, KC_TRANSPARENT, KC_TRANSPARENT, KC_TRANSPARENT, KC_TRANSPARENT, KC_TRANSPARENT, KC_TRANSPARENT, KC_TRANSPARENT, KC_TRANSPARENT, KC_TRANSPARENT, KC_TRANSPARENT, KC_TRANSPARENT, KC_TRANSPARENT, KC_TRANSPARENT, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_TRANSPARENT, KC_UP, KC_KP_7, KC_KP_8, KC_KP_9, KC_KP_ASTERISK, KC_F12, KC_DOWN, KC_KP_4, KC_KP_5, KC_KP_6, KC_KP_PLUS, KC_TRANSPARENT, KC_TRANSPARENT, , KC_KP_1, KC_KP_2, KC_KP_3, KC_KP_SLASH, KC_TRANSPARENT, KC_TRANSPARENT, KC_KP_DOT, KC_KP_0, KC_KP_EQUAL, KC_TRANSPARENT, KC_TRANSPARENT, KC_TRANSPARENT, KC_TRANSPARENT, KC_TRANSPARENT, KC_TRANSPARENT, KC_TRANSPARENT \
+\
+),
+
+[2] = KEYMAP( \
+\
+KC_TRANSPARENT, KC_TRANSPARENT, KC_TRANSPARENT, KC_TRANSPARENT, KC_TRANSPARENT, KC_TRANSPARENT, KC_TRANSPARENT, KC_TRANSPARENT, KC_TRANSPARENT, KC_TRANSPARENT, KC_MS_UP, KC_TRANSPARENT, KC_TRANSPARENT, KC_TRANSPARENT, KC_TRANSPARENT, KC_TRANSPARENT, KC_MS_LEFT, KC_MS_DOWN, KC_MS_RIGHT, KC_TRANSPARENT, KC_TRANSPARENT, KC_TRANSPARENT, KC_TRANSPARENT, KC_TRANSPARENT, KC_TRANSPARENT, KC_TRANSPARENT, KC_TRANSPARENT, KC_TRANSPARENT, KC_TRANSPARENT, KC_TRANSPARENT, KC_MS_BTN3, KC_MS_BTN2, KC_TRANSPARENT, KC_TRANSPARENT, KC_TRANSPARENT, KC_TRANSPARENT, KC_TRANSPARENT, KC_TRANSPARENT, KC_TRANSPARENT, KC_TRANSPARENT, KC_TRANSPARENT, KC_TRANSPARENT, KC_TRANSPARENT, KC_TRANSPARENT, KC_TRANSPARENT, KC_TRANSPARENT, KC_TRANSPARENT, KC_TRANSPARENT, KC_TRANSPARENT, KC_TRANSPARENT, KC_TRANSPARENT, KC_TRANSPARENT, KC_TRANSPARENT, KC_TRANSPARENT, KC_TRANSPARENT, KC_TRANSPARENT, KC_TRANSPARENT, KC_MEDIA_PLAY_PAUSE, KC_TRANSPARENT, KC_TRANSPARENT, KC_TRANSPARENT, KC_MEDIA_PREV_TRACK, KC_MEDIA_NEXT_TRACK, KC_TRANSPARENT, KC_TRANSPARENT, KC_AUDIO_VOL_UP, KC_AUDIO_VOL_DOWN, KC_AUDIO_MUTE, KC_TRANSPARENT, KC_TRANSPARENT, KC_TRANSPARENT, KC_TRANSPARENT, KC_TRANSPARENT, KC_TRANSPARENT, KC_TRANSPARENT, KC_TRANSPARENT \
+\
+),
+
+};
+
+const uint16_t PROGMEM fn_actions[] = {
+    [1] = ACTION_LAYER_TAP_TOGGLE(SYMB)                // FN1 - Momentary Layer 1 (Symbols)
+};
+
+const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt)
+{
+  // MACRODOWN only works in this function
+      switch(id) {
+        case 0:
+        if (record->event.pressed) {
+          register_code(KC_RSFT);
+        } else {
+          unregister_code(KC_RSFT);
+        }
+        break;
+      }
+    return MACRO_NONE;
+};
+
+// Runs just one time when the keyboard initializes.
+void * matrix_init_user(void) {
+
+};
+
+// Runs constantly in the background, in a loop.
+void * matrix_scan_user(void) {
+
+    uint8_t layer = biton32(layer_state);
+
+    ergodox_board_led_off();
+    ergodox_right_led_1_off();
+    ergodox_right_led_2_off();
+    ergodox_right_led_3_off();
+    switch (layer) {
+      // TODO: Make this relevant to the ErgoDox EZ.
+        case 1:
+            ergodox_right_led_1_on();
+            break;
+        case 2:
+            ergodox_right_led_2_on();
+            break;
+        default:
+            // none
+            break;
+    }
+
+};
diff --git a/keyboard/ergodox_ez/keymaps/keymap_jack.c b/keyboard/ergodox_ez/keymaps/keymap_jack.c
index 2677a3d8fa..f8f73a1afd 100644
--- a/keyboard/ergodox_ez/keymaps/keymap_jack.c
+++ b/keyboard/ergodox_ez/keymaps/keymap_jack.c
@@ -8,29 +8,6 @@
 #define MDIA 2 // media keys
 
 const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
-/* Keymap 0: Basic layer
- *
- * ,--------------------------------------------------.           ,--------------------------------------------------.
- * |   =    |   1  |   2  |   3  |   4  |   5  | LEFT |           | RIGHT|   6  |   7  |   8  |   9  |   0  |   -    |
- * |--------+------+------+------+------+-------------|           |------+------+------+------+------+------+--------|
- * | Del    |   Q  |   W  |   E  |   R  |   T  |  L1  |           |  L1  |   Y  |   U  |   I  |   O  |   P  |   \    |
- * |--------+------+------+------+------+------|      |           |      |------+------+------+------+------+--------|
- * | BkSp   |   A  |   S  |   D  |   F  |   G  |------|           |------|   H  |   J  |   K  |   L  |; / L2|   '    |
- * |--------+------+------+------+------+------| Hyper|           | Meh  |------+------+------+------+------+--------|
- * | LShift |Z/Ctrl|   X  |   C  |   V  |   B  |      |           |      |   N  |   M  |   ,  |   .  |//Ctrl| RShift |
- * `--------+------+------+------+------+-------------'           `-------------+------+------+------+------+--------'
- *   |Grv/L1|  '"  |AltShf| Left | Right|                                       |  Up  | Down |   [  |   ]  | ~L1  |
- *   `----------------------------------'                                       `----------------------------------'
- *                                        ,-------------.       ,-------------.
- *                                        | App  | LGui |       | Alt  |Ctrl/Esc|
- *                                 ,------|------|------|       |------+--------+------.
- *                                 |      |      | Home |       | PgUp |        |      |
- *                                 | Space|Backsp|------|       |------|  Tab   |Enter |
- *                                 |      |ace   | End  |       | PgDn |        |      |
- *                                 `--------------------'       `----------------------'
- */
-// If it accepts an argument (i.e, is a function), it doesn't need KC_.
-// Otherwise, it needs KC_*
 [BASE] = KEYMAP(  // layer 0 : default
         // left hand
         KC_NO,          KC_1,         KC_2,   KC_3,   KC_4,   KC_5,   KC_NO,
@@ -51,28 +28,6 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
              KC_PGUP,
              KC_PGDN, KC_SPC,KC_SPC
     ),
-/* Keymap 1: Symbol Layer
- *
- * ,--------------------------------------------------.           ,--------------------------------------------------.
- * |        |  F1  |  F2  |  F3  |  F4  |  F5  |      |           |      |  F6  |  F7  |  F8  |  F9  |  F10 |   F11  |
- * |--------+------+------+------+------+-------------|           |------+------+------+------+------+------+--------|
- * |        |   !  |   @  |   {  |   }  |   |  |      |           |      |   Up |   7  |   8  |   9  |   *  |   F12  |
- * |--------+------+------+------+------+------|      |           |      |------+------+------+------+------+--------|
- * |        |   #  |   $  |   (  |   )  |   `  |------|           |------| Down |   4  |   5  |   6  |   +  |        |
- * |--------+------+------+------+------+------|      |           |      |------+------+------+------+------+--------|
- * |        |   %  |   ^  |   [  |   ]  |   ~  |      |           |      |   &  |   1  |   2  |   3  |   \  |        |
- * `--------+------+------+------+------+-------------'           `-------------+------+------+------+------+--------'
- *   |      |      |      |      |      |                                       |      |    . |   0  |   =  |      |
- *   `----------------------------------'                                       `----------------------------------'
- *                                        ,-------------.       ,-------------.
- *                                        |      |      |       |      |      |
- *                                 ,------|------|------|       |------+------+------.
- *                                 |      |      |      |       |      |      |      |
- *                                 |      |      |------|       |------|      |      |
- *                                 |      |      |      |       |      |      |      |
- *                                 `--------------------'       `--------------------'
- */
-// SYMBOLS
 [SYMB] = KEYMAP(
        // left hand
        KC_TRNS,KC_F1,  KC_F2,  KC_F3,  KC_F4,  KC_F5,  KC_TRNS,
@@ -93,29 +48,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
        KC_TRNS,
        KC_TRNS, KC_TRNS, KC_TRNS
 ),
-/* Keymap 2: Media and mouse keys
- *
- * ,--------------------------------------------------.           ,--------------------------------------------------.
- * |        |      |      |      |      |      |      |           |      |      |      |      |      |      |        |
- * |--------+------+------+------+------+-------------|           |------+------+------+------+------+------+--------|
- * |        |      |      | MsUp |      |      |      |           |      |      |      |      |      |      |        |
- * |--------+------+------+------+------+------|      |           |      |------+------+------+------+------+--------|
- * |        |      |MsLeft|MsDown|MsRght|      |------|           |------|      |      |      |      |      |  Play  |
- * |--------+------+------+------+------+------|      |           |      |------+------+------+------+------+--------|
- * |        |      |      |      |      |      |      |           |      |      |      | Prev | Next |      |        |
- * `--------+------+------+------+------+-------------'           `-------------+------+------+------+------+--------'
- *   |      |      |      | Lclk | Rclk |                                       |VolUp |VolDn | Mute |      |      |
- *   `----------------------------------'                                       `----------------------------------'
- *                                        ,-------------.       ,-------------.
- *                                        |      |      |       |      |      |
- *                                 ,------|------|------|       |------+------+------.
- *                                 |      |      |      |       |      |      |Brwser|
- *                                 |      |      |------|       |------|      |Back  |
- *                                 |      |      |      |       |      |      |      |
- *                                 `--------------------'       `--------------------'
- */
-// MEDIA AND MOUSE
-KEYMAP(
+[MDIA] = KEYMAP(
        KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
        KC_TILD, KC_EXLM, KC_AT,   KC_HASH, KC_DLR,  KC_PERC, KC_TRNS,
        KC_TRNS, KC_F1,   KC_F2,   KC_F3,   KC_F4,   KC_F5,  
diff --git a/keyboard/planck/Makefile b/keyboard/planck/Makefile
index 485c5f77f6..fdf8c16400 100644
--- a/keyboard/planck/Makefile
+++ b/keyboard/planck/Makefile
@@ -122,8 +122,8 @@ COMMAND_ENABLE = yes    # Commands for debug and configuration
 # Do not enable SLEEP_LED_ENABLE. it uses the same timer as BACKLIGHT_ENABLE
 # SLEEP_LED_ENABLE = yes  # Breathing sleep LED during USB suspend
 # NKRO_ENABLE = yes		# USB Nkey Rollover - if this doesn't work, see here: https://github.com/tmk/tmk_keyboard/wiki/FAQ#nkro-doesnt-work
-BACKLIGHT_ENABLE = yes  # Enable keyboard backlight functionality
-# MIDI_ENABLE = YES 		# MIDI controls
+# BACKLIGHT_ENABLE = yes  # Enable keyboard backlight functionality
+MIDI_ENABLE = YES 		# MIDI controls
 # UNICODE_ENABLE = YES 		# Unicode
 # BLUETOOTH_ENABLE = yes # Enable Bluetooth with the Adafruit EZ-Key HID
 
diff --git a/keyboard/planck/keymaps/keymap_eric.c b/keyboard/planck/keymaps/keymap_eric.c
new file mode 100644
index 0000000000..ffeec5f805
--- /dev/null
+++ b/keyboard/planck/keymaps/keymap_eric.c
@@ -0,0 +1,42 @@
+#include "planck.h"
+
+const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
+ [0] = {
+    {KC_BSLS, S(KC_SLSH), KC_COMM,       KC_DOT,   KC_P,   KC_Y,   KC_F,    KC_G,         KC_C,    KC_R,    KC_L, KC_SLSH}, 
+    {TG(1),         KC_A,    KC_O,         KC_E,   KC_U,   KC_I,   KC_D,    KC_H,         KC_T,    KC_N,    KC_S, KC_MINS},
+    {KC_LGUI,    KC_QUOT,    KC_Q,         KC_J,   KC_K,   KC_X,   KC_B,    KC_M,         KC_W,    KC_V,    KC_Z, KC_RGUI},
+    {KC_LCBR,    KC_LCTL, KC_LALT, LT(1, TG(2)), KC_SPC, KC_TAB, KC_ENT, KC_BSPC, LT(1, TG(3)), KC_RALT, KC_RCTL, KC_RCBR}
+  },
+
+ [1] = {
+    {KC_PIPE,    KC_COLN, KC_LBRC,  KC_RBRC, S(KC_P), S(KC_Y), S(KC_F), S(KC_G), S(KC_C), S(KC_R), S(KC_L), KC_AMPR}, 
+    {KC_TRNS,    S(KC_A), S(KC_O),  S(KC_E), S(KC_U), S(KC_I), S(KC_D), S(KC_H), S(KC_T), S(KC_N), S(KC_S), KC_GRV},
+    {KC_TRNS,    KC_SCLN, S(KC_Q),  S(KC_J), S(KC_K), S(KC_X), S(KC_B), S(KC_M), S(KC_W), S(KC_V), S(KC_Z), KC_TRNS},
+    {S(KC_COMM), KC_TRNS, KC_TRNS,  KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, S(KC_DOT)}
+  },
+
+ [2] = {
+    {KC_ESC,  KC_F1,   KC_F2,   KC_F3,   KC_F4,   KC_F5,   KC_F6,   KC_F7,   KC_F8,   KC_F9,  KC_F10, KC_NO}, 
+    {KC_NO,  KC_F11,  KC_F12,  KC_F13,  KC_F14,  KC_F15,  KC_F16,  KC_F17,  KC_F18,  KC_F19,  KC_F20, KC_NO},
+    {KC_TRNS, KC_NO,   KC_NO,   KC_NO,   KC_NO,   KC_NO,   KC_NO,   KC_NO,   KC_NO,   KC_NO,   KC_NO, KC_TRNS},
+    {KC_NO, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_NO}
+  },
+
+ [3] = {
+    {KC_EXLM,  KC_7,    KC_5,    KC_3,      KC_1,    KC_9,    KC_0,    KC_2,    KC_4,    KC_6,    KC_8, KC_EQL}, 
+    {TG(4),   KC_NO, KC_PGUP, KC_HOME, KC_INSERT,   KC_NO,   KC_NO,  BL_DEC,   KC_UP,  BL_INC,   KC_NO, KC_NO},
+    {KC_TRNS, KC_NO, KC_PGDN,  KC_END, KC_DELETE,   KC_NO,   KC_NO, KC_LEFT, KC_DOWN, KC_RGHT,   KC_NO, KC_TRNS},
+    {KC_NO, KC_TRNS, KC_TRNS, KC_TRNS,   KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_NO}
+  },
+
+ [4] = {
+    {KC_TILD, KC_HASH, KC_LPRN, KC_RPRN, S(KC_QUOT), KC_PERC, KC_UNDS, KC_CIRC,  KC_DLR,   KC_AT, KC_ASTR, KC_PLUS}, 
+    {KC_TRNS,   KC_NO,   KC_NO,   KC_NO,      KC_NO,   KC_NO,   KC_NO,   KC_NO,   KC_NO,   KC_NO,   KC_NO, KC_NO},
+    {KC_TRNS,   KC_NO,   KC_NO,   KC_NO,      KC_NO,   KC_NO,   KC_NO,   KC_NO,   KC_NO,   KC_NO,   KC_NO, KC_TRNS},
+    {KC_NO,   KC_TRNS, KC_TRNS, KC_TRNS,    KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_NO}
+  }
+};
+
+const uint16_t PROGMEM fn_actions[] = {
+
+};
\ No newline at end of file
diff --git a/keyboard/planck/keymaps/keymap_lock.c b/keyboard/planck/keymaps/keymap_lock.c
index cc9be55f64..c2bf0b7d81 100644
--- a/keyboard/planck/keymaps/keymap_lock.c
+++ b/keyboard/planck/keymaps/keymap_lock.c
@@ -1,5 +1,5 @@
 #include "keymap_common.h"
-#include "backlight.h"
+// #include "backlight.h"
 #include "action_layer.h"
 #include "keymap_midi.h"
 #include <avr/boot.h>
@@ -71,7 +71,7 @@ const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt)
         if (record->event.pressed) {
           // play_note(440, 20);
           // register_code(KC_RSFT);
-          backlight_set(BACKLIGHT_LEVELS);
+          // backlight_set(BACKLIGHT_LEVELS);
           default_layer_and(0); 
           default_layer_or((1<<5));
 
@@ -106,9 +106,9 @@ const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt)
           // note(0+12, 20);
           // note(0+24, 20);
         } else {
-          // unregister_code(KC_RSFT);
-          // stop_note();
-          backlight_set(0);
+          unregister_code(KC_RSFT);
+          // stop_all_notes();
+          // backlight_set(0);
           default_layer_and(0); 
           default_layer_or(0);
           // note(0+24, 20);
diff --git a/keyboard/planck/planck.c b/keyboard/planck/planck.c
index b62862af04..a986bd8812 100644
--- a/keyboard/planck/planck.c
+++ b/keyboard/planck/planck.c
@@ -19,6 +19,35 @@ void * matrix_init_kb(void) {
     DDRE |= (1<<6);
     PORTE |= (1<<6);
 
+    init_notes();
+
+    // play_note(((double)261.6*32)*pow(2.0,(36)/12.0), 0xF);
+    // _delay_ms(50);
+
+    // play_note(((double)261.6*32)*pow(2.0,(48)/12.0), 0xF);
+    // _delay_ms(25);
+    // stop_note(((double)261.6*32)*pow(2.0,(48)/12.0));
+
+    // play_note(((double)261.6*32)*pow(2.0,(48)/12.0), 0xF);
+    // _delay_ms(25);
+    // stop_note(((double)261.6*32)*pow(2.0,(48)/12.0));
+
+
+    // stop_note(((double)261.6*32)*pow(2.0,(36)/12.0));
+
+
+    // play_note(((double)261.6*32)*pow(2.0,(62)/12.0), 0xF);
+    // _delay_ms(50);
+    // stop_note(((double)261.6*32)*pow(2.0,(62)/12.0));
+
+
+    // play_note(((double)261.6*32)*pow(2.0,(64)/12.0), 0xF);
+    // _delay_ms(50);
+    // stop_note(((double)261.6*32)*pow(2.0,(64)/12.0));
+
+
+
+
 	if (matrix_init_user) {
 		(*matrix_init_user)();
 	}
diff --git a/keyboard/planck/planck.h b/keyboard/planck/planck.h
index 4e59aef566..32c08f3b0b 100644
--- a/keyboard/planck/planck.h
+++ b/keyboard/planck/planck.h
@@ -3,8 +3,11 @@
 
 #include "matrix.h"
 #include "keymap_common.h"
-#include "backlight.h"
+// #include "backlight.h"
 #include <stddef.h>
+#ifdef MIDI_ENABLE
+	#include <keymap_midi.h>
+#endif
 
 #define PLANCK_MIT( \
 	k00, k01, k02, k03, k04, k05, k06, k07, k08, k09, k0a, k0b, \
diff --git a/quantum/beeps.c b/quantum/beeps.c
index 8d1f81f210..edcc84aca4 100644
--- a/quantum/beeps.c
+++ b/quantum/beeps.c
@@ -1,11 +1,20 @@
-#include "beeps.h"
+#include <stdio.h>
+#include <string.h>
 #include <math.h>
 #include <avr/pgmspace.h>
 #include <avr/interrupt.h>
 #include <avr/io.h>
 
+#include "beeps.h"
+#include "keymap_common.h"
+#include "wave.h"
+
 #define PI 3.14159265
 
+#define SAMPLE_DIVIDER 70
+#define SAMPLE_RATE (2000000.0/SAMPLE_DIVIDER/256)
+// Resistor value of 1/ (2 * PI * 10nF * (2000000 hertz / SAMPLE_DIVIDER / 10)) for 10nF cap
+
 void delay_us(int count) {
   while(count--) {
     _delay_us(1);
@@ -15,7 +24,7 @@ void delay_us(int count) {
 int voices = 0;
 double frequency = 0;
 int volume = 0;
-int position = 0;
+long position = 0;
 
 double frequencies[8] = {0, 0, 0, 0, 0, 0, 0, 0};
 int volumes[8] = {0, 0, 0, 0, 0, 0, 0, 0};
@@ -23,6 +32,19 @@ bool sliding = false;
 #define RANGE 1000
 volatile int i=0; //elements of the wave
 
+// uint8_t sine[128];
+// uint8_t tri[128];
+// uint8_t squ[128];
+// uint8_t* sine_start;
+// uint8_t* sine_end;
+// uint8_t* tri_start;
+// uint8_t* tri_end;
+
+// uint8_t* s_start;
+// uint8_t* s_end;
+// uint8_t* s_ptr;
+
+
 
 void beeps() {
     play_notes();
@@ -36,8 +58,7 @@ void send_freq(double freq, int vol) {
 
 void stop_all_notes() {
     voices = 0;
-    TCCR3A = 0;
-    TCCR3B = 0;
+    TIMSK0 &= ~_BV(OCIE0A);
     frequency = 0;
     volume = 0;
 
@@ -48,6 +69,7 @@ void stop_all_notes() {
 }
 
 void stop_note(double freq) {
+    freq = freq / SAMPLE_RATE;
     for (int i = 7; i >= 0; i--) {
         if (frequencies[i] == freq) {
             frequencies[i] = 0;
@@ -64,151 +86,176 @@ void stop_note(double freq) {
     if (voices < 0)
         voices = 0;
     if (voices == 0) {
-        TCCR3A = 0;
-        TCCR3B = 0;
+        TIMSK0 &= ~_BV(OCIE0A);
         frequency = 0;
         volume = 0;
     } else {
         double freq = frequencies[voices - 1];
         int vol = volumes[voices - 1];
+        double starting_f = frequency;
         if (frequency < freq) {
             sliding = true;
-            for (double f = frequency; f <= freq; f += ((freq - frequency) / 500.0)) {
-                send_freq(f, vol);
+            for (double f = starting_f; f <= freq; f += ((freq - starting_f) / 500.0)) {
+                frequency = f;
             }
             sliding = false;
         } else if (frequency > freq) {
             sliding = true;
-            for (double f = frequency; f >= freq; f -= ((frequency - freq) / 500.0)) {
-                send_freq(f, vol);
+            for (double f = starting_f; f >= freq; f -= ((starting_f - freq) / 500.0)) {
+                frequency = f;
             }
             sliding = false;
         }
-        send_freq(freq, vol);
+        // send_freq(freq, vol);
         frequency = freq;
         volume = vol;
     }
 }
 
 void init_notes() {
-    // TCCR1A = (1 << COM1A1) | (0 << COM1A0) | (1 << WGM11) | (1 << WGM10);
-    // TCCR1B = (1 << COM1B1) | (0 << COM1A0) | (1 << WGM13) | (1 << WGM12) | (0 << CS12) | (0 << CS11) | (1 << CS10);
 
-    // DDRC |= (1<<6); 
+    // for(int i = 0; i < 128; i++) {
+    //     sine[i] = sin(i * PI / 64) * 128 + 128;
+    //     tri[i] = 256 - abs((i - 64) * 4);
+    // }
+    // sine_start = &sine;
+    // sine_end = &sine + 128;
+    // tri_start = &tri;
+    // tri_end = &tri + 128;
 
-    // TCCR3A = (1 << COM3A1) | (0 << COM3A0) | (1 << WGM31) | (0 << WGM30);
-    // TCCR3B = (1 << WGM33) | (1 << WGM32) | (0 << CS32) | (0 << CS31) | (1 << CS30);
-
-    // ICR3 = 0xFFFF; 
-    // OCR3A = (int)((float)wave[i]*ICR3/RANGE); //go to next array element
+ // new
 
 
-    // cli();
+  PLLFRQ = _BV(PDIV2);
+  PLLCSR = _BV(PLLE);
+  while(!(PLLCSR & _BV(PLOCK)));
+  PLLFRQ |= _BV(PLLTM0); /* PCK 48MHz */
+  
+  /* Init a fast PWM on Timer4 */
+  TCCR4A = _BV(COM4A0) | _BV(PWM4A); /* Clear OC4A on Compare Match */
+  TCCR4B = _BV(CS40); /* No prescaling => f = PCK/256 = 187500Hz */
+  OCR4A = 0;
 
-    // /* Enable interrupt on timer2 == 127, with clk/8 prescaler. At 16MHz,
-    //    this gives a timer interrupt at 15625Hz. */
-    // TIMSK3 = (1 << OCIE3A);
-
-    // /* clear/reset timer on match */
-    // // TCCR3A = 1<<WGM31 | 0<<WGM30;  CTC mode, reset on match 
-    // // TCCR3B = 0<<CS32 | 1<<CS31 | 0<<CS30; /* clk, /8 prescaler */
-
-    // TCCR3A = (1 << COM3A1) | (0 << COM3A0) | (1 << WGM31) | (0 << WGM30);
-    // TCCR3B = (0 << WGM33) | (0 << WGM32) | (0 << CS32) | (0 << CS31) | (1 << CS30);
+  /* Enable the OC4A output */
+  DDRC |= _BV(PORTC6);
 
 
-    // TCCR1A = (1 << COM1A1) | (0 << COM1A0) | (1 << WGM11) | (0 << WGM10);
-    // TCCR1B = (1 << WGM12) | (0 << CS12) | (0 << CS11) | (1 << CS10);
-    // // SPCR = 0x50;
-    // // SPSR = 0x01;
-    // DDRC |= (1<<6);
-    // // ICR3 = 0xFFFF; 
-    // // OCR3A=80;
-    // PORTC |= (1<<6);
 
-    // sei();
+       /* First disable the timer overflow interrupt while we're configuring */
+  // TIMSK0 &= ~(1<<TOIE0);
+ 
+  // /* Configure timer4 in normal mode (pure counting, no PWM etc.) */
+  // TCCR0A &= ~((1<<WGM01) | (1<<WGM00));
+  // TCCR0B &= ~(1<<WGM02);
+
+  // /* Disable Compare Match A interrupt enable (only want overflow) */
+  // TIMSK0 &= ~(1<<OCIE0A);
+  
+  // TCCR0B |= (1<<CS01); // Set bits
+  // TCCR0B &= ~(1<<CS00) | ~(1<<CS02);             // Clear bit
+   
+  // /* Save value globally for later reload in ISR */
+  // tcnt0 = 45 - 1; 
+
+  // /* Finally load end enable the timer */
+  // TCNT0 = tcnt0;
+  // TIMSK0 |= (1<<TOIE0);
+
 }
 
-// #define highByte(c) ((c >> 8) & 0x00FF)
-// #define lowByte(c) (c & 0x00FF)
+int max = 0xFF;
+float sum = 0;
+int value = 128;
+float place = 0;
 
-ISR(TIMER3_COMPA_vect) {
-
-    if (ICR3 > 0 && !sliding) {
-        switch (position) {
-            case 0: {
-                int duty = (((double)F_CPU) / (frequency));
-                ICR3 = duty; // Set max to the period
-                OCR3A = duty >> 1; // Set compare to half the period
-                break;
-            }
-            case 1: {
-                int duty = (((double)F_CPU) / (frequency*2));
-                ICR3 = duty; // Set max to the period
-                OCR3A = duty >> 1; // Set compare to half the period
-                break;
-            }
-            case 2: {
-                int duty = (((double)F_CPU) / (frequency*3));
-                ICR3 = duty; // Set max to the period
-                OCR3A = duty >> 1; // Set compare to half the period
-                break;
-            }
-        }
-        position = (position + 1) % 3;
-    }
-//     /* OCR2A has been cleared, per TCCR2A above */
-//     // OCR3A = 127;
-
-//     // pos1 += incr1;
-//     // pos2 += incr2;
-//     // pos3 += incr3;
-
-//     // sample = sinewave[highByte(pos1)] + sinewave[highByte(pos2)] + sinewave[highByte(pos3)];
-
-//     // OCR3A = sample;
+ISR(TIMER0_COMPA_vect) {
 
 
-//     OCR3A=pgm_read_byte(&sinewave[pos1]);
-//     pos1++;
-//     // PORTC &= ~(1<<6);
 
-//     /* buffered, 1x gain, active mode */
-//     // SPDR = highByte(sample) | 0x70;
-//     // while (!(SPSR & (1<<SPIF)));
+    // value = *(sine_start+=(long)frequencies[0]);
+    // OCR4A = value;
+    // if (sine_start >= sine_end) {
+    //     sine_start = &sine[(sine_start - sine_end) % 128];
+    // }
 
-//     // SPDR = lowByte(sample);
-//     // while (!(SPSR & (1<<SPIF)));
 
-//     // PORTC |= (1<<6);
+    // OCR4A = pgm_read_byte(sine_start);
+    // // sine_start = &sine[(sine_start - &sine[0] + (int)frequencies[0]) % 128];
+    // sine_start +=  (int)frequencies[0];
+    // if (sine_start >= sine_end) {
+    //     sine_start = &sine[(sine_start - sine_end) % 128];
+    // }
+    
+    // OCR4A = pgm_read_byte(s_ptr);
+    // s_ptr = s_start + (uint8_t)place;
+    // OCR4A = pgm_read_byte(s_ptr);
+
+
+    // SINE
+    OCR4A = pgm_read_byte(&sinewave[(uint16_t)place]);
+    
+    // SQUARE
+    // if (((int)place) >= 1024){
+    //     OCR4A = 0xFF;
+    // } else {
+    //     OCR4A = 0x00;
+    // }
+    
+    // SAWTOOTH
+    // OCR4A = (int)place / 4;
+
+    // TRIANGLE
+    // if (((int)place) >= 1024) {
+    //     OCR4A = (int)place / 2;
+    // } else {
+    //     OCR4A = 2048 - (int)place / 2;
+    // }
+
+    place += frequency;
+    if (place >= SINE_LENGTH)
+        place -= SINE_LENGTH;
+
+}
+
+
+ISR(TIMER0_COMPB_vect)
+{
+
+  /* Disable the interrupt */
+  TIMSK0 &= ~_BV(OCIE0B);
+
 }
 
 void play_note(double freq, int vol) {
 
+    freq = freq / SAMPLE_RATE;
     if (freq > 0) {
-        DDRC |= (1<<6); 
 
-        TCCR3A = (1 << COM3A1) | (0 << COM3A0) | (1 << WGM31) | (0 << WGM30);
-        TCCR3B = (1 << WGM33) | (1 << WGM32) | (0 << CS32) | (1 << CS31) | (0 << CS30);
+        // TCCR3A = (1 << COM3A1) | (0 << COM3A0) | (1 << WGM31) | (1 << WGM30);
+        // TCCR3B = (0 << WGM33) | (1 << WGM32) | (0 << CS32) | (0 << CS31) | (1 << CS30);
 
+      // TIMSK3 = 0x0;
         if (frequency != 0) {
+            double starting_f = frequency;
             if (frequency < freq) {
-                for (double f = frequency; f <= freq; f += ((freq - frequency) / 500.0)) {
-                    send_freq(f, vol);
+                for (double f = starting_f; f <= freq; f += ((freq - starting_f) / 500.0)) {   
+                    frequency = f;
                 }
             } else if (frequency > freq) {
-                for (double f = frequency; f >= freq; f -= ((frequency - freq) / 500.0)) {
-                    send_freq(f, vol);
+                for (double f = starting_f; f >= freq; f -= ((starting_f - freq) / 500.0)) {
+                    frequency = f;
                 }
             }
         }
-        send_freq(freq, vol);
+        // send_freq(freq, vol);
         frequency = freq;
         volume = vol;
 
         frequencies[voices] = frequency;
         volumes[voices] = volume;
         voices++;
+        // position = 0;
+        // TCNT0 = 0;
     }
     // ICR3 = 0xFFFF;
     // for (int i = 0; i < 10000; i++) {
@@ -218,6 +265,18 @@ void play_note(double freq, int vol) {
 
     // TCCR3A = 0;
     // TCCR3B = 0;
+
+
+    TIMSK0 &= ~_BV(OCIE0A) | ~_BV(OCIE0B);
+
+    TCCR0A = _BV(WGM01); 
+    TCCR0B = _BV(CS01);
+    OCR0A = SAMPLE_DIVIDER - 1;  
+    OCR0B = 1;
+
+    TIMSK0 |= _BV(OCIE0A);
+    // sei();
+
 }
 
 // void note(int x, float length) {
diff --git a/quantum/beeps.h b/quantum/beeps.h
index 378983c605..a7fcf6c23c 100644
--- a/quantum/beeps.h
+++ b/quantum/beeps.h
@@ -9,4 +9,4 @@ void true_note(float x, float y, float length);
 void play_note(double freq, int vol);
 void stop_note(double freq);
 void stop_all_notes();
-void init_notes();
\ No newline at end of file
+void init_notes();
diff --git a/quantum/keymap_midi.c b/quantum/keymap_midi.c
index b7eba3ab76..3a1408e220 100644
--- a/quantum/keymap_midi.c
+++ b/quantum/keymap_midi.c
@@ -17,7 +17,6 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
 #include "keymap_common.h"
 #include "keymap_midi.h"
-#include <lufa.h>
 
 uint8_t starting_note = 0x0C;
 int offset = 7;
@@ -35,7 +34,7 @@ void action_function(keyrecord_t *record, uint8_t id, uint8_t opt)
     if (record->event.key.col == (MATRIX_COLS - 1) && record->event.key.row == (MATRIX_ROWS - 1)) {
         if (record->event.pressed) {
             starting_note++;
-            play_note(((double)261.6)*pow(2.0, -1.0)*pow(2.0,(starting_note + SCALE[0 + offset])/12.0+(MATRIX_ROWS - 1)), 0xC);
+            play_note(((double)261.626)*pow(2.0, -1.0)*pow(2.0,(starting_note + SCALE[0 + offset])/12.0+(MATRIX_ROWS - 1)), 0xC);
             midi_send_cc(&midi_device, 0, 0x7B, 0);
             midi_send_cc(&midi_device, 1, 0x7B, 0);
             midi_send_cc(&midi_device, 2, 0x7B, 0);
@@ -43,7 +42,7 @@ void action_function(keyrecord_t *record, uint8_t id, uint8_t opt)
             midi_send_cc(&midi_device, 4, 0x7B, 0);
             return;
         } else {
-            stop_note(((double)261.6)*pow(2.0, -1.0)*pow(2.0,(starting_note + SCALE[0 + offset])/12.0+(MATRIX_ROWS - 1)));
+            stop_note(((double)261.626)*pow(2.0, -1.0)*pow(2.0,(starting_note + SCALE[0 + offset])/12.0+(MATRIX_ROWS - 1)));
             stop_all_notes();
             return;
         }
@@ -51,7 +50,7 @@ void action_function(keyrecord_t *record, uint8_t id, uint8_t opt)
     if (record->event.key.col == (MATRIX_COLS - 2) && record->event.key.row == (MATRIX_ROWS - 1)) {
         if (record->event.pressed) {
             starting_note--;
-            play_note(((double)261.6)*pow(2.0, -1.0)*pow(2.0,(starting_note + SCALE[0 + offset])/12.0+(MATRIX_ROWS - 1)), 0xC);
+            play_note(((double)261.626)*pow(2.0, -1.0)*pow(2.0,(starting_note + SCALE[0 + offset])/12.0+(MATRIX_ROWS - 1)), 0xC);
             midi_send_cc(&midi_device, 0, 0x7B, 0);
             midi_send_cc(&midi_device, 1, 0x7B, 0);
             midi_send_cc(&midi_device, 2, 0x7B, 0);
@@ -59,7 +58,7 @@ void action_function(keyrecord_t *record, uint8_t id, uint8_t opt)
             midi_send_cc(&midi_device, 4, 0x7B, 0);
             return;
         } else {
-            stop_note(((double)261.6)*pow(2.0, -1.0)*pow(2.0,(starting_note + SCALE[0 + offset])/12.0+(MATRIX_ROWS - 1)));
+            stop_note(((double)261.626)*pow(2.0, -1.0)*pow(2.0,(starting_note + SCALE[0 + offset])/12.0+(MATRIX_ROWS - 1)));
             stop_all_notes();
             return;
         }
@@ -74,9 +73,9 @@ void action_function(keyrecord_t *record, uint8_t id, uint8_t opt)
         midi_send_cc(&midi_device, 4, 0x7B, 0);
         stop_all_notes();
         for (int i = 0; i <= 7; i++) {
-            play_note(((double)261.6)*pow(2.0, -1.0)*pow(2.0,(starting_note + SCALE[i + offset])/12.0+(MATRIX_ROWS - 1)), 0xC);
+            play_note(((double)261.626)*pow(2.0, -1.0)*pow(2.0,(starting_note + SCALE[i + offset])/12.0+(MATRIX_ROWS - 1)), 0xC);
             _delay_us(80000);
-            stop_note(((double)261.6)*pow(2.0, -1.0)*pow(2.0,(starting_note + SCALE[i + offset])/12.0+(MATRIX_ROWS - 1)));
+            stop_note(((double)261.626)*pow(2.0, -1.0)*pow(2.0,(starting_note + SCALE[i + offset])/12.0+(MATRIX_ROWS - 1)));
             _delay_us(8000);
         }
         return;
@@ -90,9 +89,9 @@ void action_function(keyrecord_t *record, uint8_t id, uint8_t opt)
         midi_send_cc(&midi_device, 4, 0x7B, 0);
         stop_all_notes();
         for (int i = 0; i <= 7; i++) {
-            play_note(((double)261.6)*pow(2.0, -1.0)*pow(2.0,(starting_note + SCALE[i + offset])/12.0+(MATRIX_ROWS - 1)), 0xC);
+            play_note(((double)261.626)*pow(2.0, -1.0)*pow(2.0,(starting_note + SCALE[i + offset])/12.0+(MATRIX_ROWS - 1)), 0xC);
             _delay_us(80000);
-            stop_note(((double)261.6)*pow(2.0, -1.0)*pow(2.0,(starting_note + SCALE[i + offset])/12.0+(MATRIX_ROWS - 1)));
+            stop_note(((double)261.626)*pow(2.0, -1.0)*pow(2.0,(starting_note + SCALE[i + offset])/12.0+(MATRIX_ROWS - 1)));
             _delay_us(8000);
         }
         return;
@@ -101,10 +100,10 @@ void action_function(keyrecord_t *record, uint8_t id, uint8_t opt)
     if (record->event.pressed) {
     	// midi_send_noteon(&midi_device, record->event.key.row, starting_note + SCALE[record->event.key.col], 127);
         midi_send_noteon(&midi_device, 0, (starting_note + SCALE[record->event.key.col + offset])+12*(MATRIX_ROWS - record->event.key.row), 127);
-        play_note(((double)261.6)*pow(2.0, -1.0)*pow(2.0,(starting_note + SCALE[record->event.key.col + offset])/12.0+(MATRIX_ROWS - record->event.key.row)), 0xF);
+        play_note(((double)261.626)*pow(2.0, 0.0)*pow(2.0,(starting_note + SCALE[record->event.key.col + offset])/12.0+(MATRIX_ROWS - record->event.key.row)), 0xF);
     } else {
         // midi_send_noteoff(&midi_device, record->event.key.row, starting_note + SCALE[record->event.key.col], 127);
         midi_send_noteoff(&midi_device, 0, (starting_note + SCALE[record->event.key.col + offset])+12*(MATRIX_ROWS - record->event.key.row), 127);
-        stop_note(((double)261.6)*pow(2.0, -1.0)*pow(2.0,(starting_note + SCALE[record->event.key.col + offset])/12.0+(MATRIX_ROWS - record->event.key.row)));
+        stop_note(((double)261.626)*pow(2.0, 0.0)*pow(2.0,(starting_note + SCALE[record->event.key.col + offset])/12.0+(MATRIX_ROWS - record->event.key.row)));
     }
 }
\ No newline at end of file
diff --git a/quantum/keymap_midi.h b/quantum/keymap_midi.h
index c5917f884e..a89420ce2a 100644
--- a/quantum/keymap_midi.h
+++ b/quantum/keymap_midi.h
@@ -18,6 +18,8 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 #ifndef KEYMAP_MIDI_H
 #define KEYMAP_MIDI_H
 
+#include <lufa.h>
+
 #define MIDI 0x6000
 #define MIDI12 0x6000, 0x6000, 0x6000, 0x6000, 0x6000, 0x6000, 0x6000, 0x6000, 0x6000, 0x6000, 0x6000, 0x6000
 
diff --git a/quantum/wave.h b/quantum/wave.h
new file mode 100644
index 0000000000..6ebc348519
--- /dev/null
+++ b/quantum/wave.h
@@ -0,0 +1,265 @@
+#include <avr/io.h>
+#include <avr/interrupt.h>
+#include <avr/pgmspace.h>
+
+#define SINE_LENGTH 2048
+
+const uint8_t sinewave[] PROGMEM= //2048 values
+{
+0x80,0x80,0x80,0x81,0x81,0x81,0x82,0x82,
+0x83,0x83,0x83,0x84,0x84,0x85,0x85,0x85,
+0x86,0x86,0x87,0x87,0x87,0x88,0x88,0x88,
+0x89,0x89,0x8a,0x8a,0x8a,0x8b,0x8b,0x8c,
+0x8c,0x8c,0x8d,0x8d,0x8e,0x8e,0x8e,0x8f,
+0x8f,0x8f,0x90,0x90,0x91,0x91,0x91,0x92,
+0x92,0x93,0x93,0x93,0x94,0x94,0x95,0x95,
+0x95,0x96,0x96,0x96,0x97,0x97,0x98,0x98,
+0x98,0x99,0x99,0x9a,0x9a,0x9a,0x9b,0x9b,
+0x9b,0x9c,0x9c,0x9d,0x9d,0x9d,0x9e,0x9e,
+0x9e,0x9f,0x9f,0xa0,0xa0,0xa0,0xa1,0xa1,
+0xa2,0xa2,0xa2,0xa3,0xa3,0xa3,0xa4,0xa4,
+0xa5,0xa5,0xa5,0xa6,0xa6,0xa6,0xa7,0xa7,
+0xa7,0xa8,0xa8,0xa9,0xa9,0xa9,0xaa,0xaa,
+0xaa,0xab,0xab,0xac,0xac,0xac,0xad,0xad,
+0xad,0xae,0xae,0xae,0xaf,0xaf,0xb0,0xb0,
+0xb0,0xb1,0xb1,0xb1,0xb2,0xb2,0xb2,0xb3,
+0xb3,0xb4,0xb4,0xb4,0xb5,0xb5,0xb5,0xb6,
+0xb6,0xb6,0xb7,0xb7,0xb7,0xb8,0xb8,0xb8,
+0xb9,0xb9,0xba,0xba,0xba,0xbb,0xbb,0xbb,
+0xbc,0xbc,0xbc,0xbd,0xbd,0xbd,0xbe,0xbe,
+0xbe,0xbf,0xbf,0xbf,0xc0,0xc0,0xc0,0xc1,
+0xc1,0xc1,0xc2,0xc2,0xc2,0xc3,0xc3,0xc3,
+0xc4,0xc4,0xc4,0xc5,0xc5,0xc5,0xc6,0xc6,
+0xc6,0xc7,0xc7,0xc7,0xc8,0xc8,0xc8,0xc9,
+0xc9,0xc9,0xca,0xca,0xca,0xcb,0xcb,0xcb,
+0xcb,0xcc,0xcc,0xcc,0xcd,0xcd,0xcd,0xce,
+0xce,0xce,0xcf,0xcf,0xcf,0xcf,0xd0,0xd0,
+0xd0,0xd1,0xd1,0xd1,0xd2,0xd2,0xd2,0xd2,
+0xd3,0xd3,0xd3,0xd4,0xd4,0xd4,0xd5,0xd5,
+0xd5,0xd5,0xd6,0xd6,0xd6,0xd7,0xd7,0xd7,
+0xd7,0xd8,0xd8,0xd8,0xd9,0xd9,0xd9,0xd9,
+0xda,0xda,0xda,0xda,0xdb,0xdb,0xdb,0xdc,
+0xdc,0xdc,0xdc,0xdd,0xdd,0xdd,0xdd,0xde,
+0xde,0xde,0xde,0xdf,0xdf,0xdf,0xe0,0xe0,
+0xe0,0xe0,0xe1,0xe1,0xe1,0xe1,0xe2,0xe2,
+0xe2,0xe2,0xe3,0xe3,0xe3,0xe3,0xe4,0xe4,
+0xe4,0xe4,0xe4,0xe5,0xe5,0xe5,0xe5,0xe6,
+0xe6,0xe6,0xe6,0xe7,0xe7,0xe7,0xe7,0xe8,
+0xe8,0xe8,0xe8,0xe8,0xe9,0xe9,0xe9,0xe9,
+0xea,0xea,0xea,0xea,0xea,0xeb,0xeb,0xeb,
+0xeb,0xeb,0xec,0xec,0xec,0xec,0xec,0xed,
+0xed,0xed,0xed,0xed,0xee,0xee,0xee,0xee,
+0xee,0xef,0xef,0xef,0xef,0xef,0xf0,0xf0,
+0xf0,0xf0,0xf0,0xf0,0xf1,0xf1,0xf1,0xf1,
+0xf1,0xf2,0xf2,0xf2,0xf2,0xf2,0xf2,0xf3,
+0xf3,0xf3,0xf3,0xf3,0xf3,0xf4,0xf4,0xf4,
+0xf4,0xf4,0xf4,0xf5,0xf5,0xf5,0xf5,0xf5,
+0xf5,0xf5,0xf6,0xf6,0xf6,0xf6,0xf6,0xf6,
+0xf6,0xf7,0xf7,0xf7,0xf7,0xf7,0xf7,0xf7,
+0xf8,0xf8,0xf8,0xf8,0xf8,0xf8,0xf8,0xf8,
+0xf9,0xf9,0xf9,0xf9,0xf9,0xf9,0xf9,0xf9,
+0xfa,0xfa,0xfa,0xfa,0xfa,0xfa,0xfa,0xfa,
+0xfa,0xfa,0xfb,0xfb,0xfb,0xfb,0xfb,0xfb,
+0xfb,0xfb,0xfb,0xfb,0xfc,0xfc,0xfc,0xfc,
+0xfc,0xfc,0xfc,0xfc,0xfc,0xfc,0xfc,0xfc,
+0xfd,0xfd,0xfd,0xfd,0xfd,0xfd,0xfd,0xfd,
+0xfd,0xfd,0xfd,0xfd,0xfd,0xfd,0xfe,0xfe,
+0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,
+0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,
+0xfe,0xfe,0xfe,0xfe,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xfe,0xfe,0xfe,
+0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,
+0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,
+0xfe,0xfe,0xfe,0xfd,0xfd,0xfd,0xfd,0xfd,
+0xfd,0xfd,0xfd,0xfd,0xfd,0xfd,0xfd,0xfd,
+0xfd,0xfc,0xfc,0xfc,0xfc,0xfc,0xfc,0xfc,
+0xfc,0xfc,0xfc,0xfc,0xfc,0xfb,0xfb,0xfb,
+0xfb,0xfb,0xfb,0xfb,0xfb,0xfb,0xfb,0xfa,
+0xfa,0xfa,0xfa,0xfa,0xfa,0xfa,0xfa,0xfa,
+0xfa,0xf9,0xf9,0xf9,0xf9,0xf9,0xf9,0xf9,
+0xf9,0xf8,0xf8,0xf8,0xf8,0xf8,0xf8,0xf8,
+0xf8,0xf7,0xf7,0xf7,0xf7,0xf7,0xf7,0xf7,
+0xf6,0xf6,0xf6,0xf6,0xf6,0xf6,0xf6,0xf5,
+0xf5,0xf5,0xf5,0xf5,0xf5,0xf5,0xf4,0xf4,
+0xf4,0xf4,0xf4,0xf4,0xf3,0xf3,0xf3,0xf3,
+0xf3,0xf3,0xf2,0xf2,0xf2,0xf2,0xf2,0xf2,
+0xf1,0xf1,0xf1,0xf1,0xf1,0xf0,0xf0,0xf0,
+0xf0,0xf0,0xf0,0xef,0xef,0xef,0xef,0xef,
+0xee,0xee,0xee,0xee,0xee,0xed,0xed,0xed,
+0xed,0xed,0xec,0xec,0xec,0xec,0xec,0xeb,
+0xeb,0xeb,0xeb,0xeb,0xea,0xea,0xea,0xea,
+0xea,0xe9,0xe9,0xe9,0xe9,0xe8,0xe8,0xe8,
+0xe8,0xe8,0xe7,0xe7,0xe7,0xe7,0xe6,0xe6,
+0xe6,0xe6,0xe5,0xe5,0xe5,0xe5,0xe4,0xe4,
+0xe4,0xe4,0xe4,0xe3,0xe3,0xe3,0xe3,0xe2,
+0xe2,0xe2,0xe2,0xe1,0xe1,0xe1,0xe1,0xe0,
+0xe0,0xe0,0xe0,0xdf,0xdf,0xdf,0xde,0xde,
+0xde,0xde,0xdd,0xdd,0xdd,0xdd,0xdc,0xdc,
+0xdc,0xdc,0xdb,0xdb,0xdb,0xda,0xda,0xda,
+0xda,0xd9,0xd9,0xd9,0xd9,0xd8,0xd8,0xd8,
+0xd7,0xd7,0xd7,0xd7,0xd6,0xd6,0xd6,0xd5,
+0xd5,0xd5,0xd5,0xd4,0xd4,0xd4,0xd3,0xd3,
+0xd3,0xd2,0xd2,0xd2,0xd2,0xd1,0xd1,0xd1,
+0xd0,0xd0,0xd0,0xcf,0xcf,0xcf,0xcf,0xce,
+0xce,0xce,0xcd,0xcd,0xcd,0xcc,0xcc,0xcc,
+0xcb,0xcb,0xcb,0xcb,0xca,0xca,0xca,0xc9,
+0xc9,0xc9,0xc8,0xc8,0xc8,0xc7,0xc7,0xc7,
+0xc6,0xc6,0xc6,0xc5,0xc5,0xc5,0xc4,0xc4,
+0xc4,0xc3,0xc3,0xc3,0xc2,0xc2,0xc2,0xc1,
+0xc1,0xc1,0xc0,0xc0,0xc0,0xbf,0xbf,0xbf,
+0xbe,0xbe,0xbe,0xbd,0xbd,0xbd,0xbc,0xbc,
+0xbc,0xbb,0xbb,0xbb,0xba,0xba,0xba,0xb9,
+0xb9,0xb8,0xb8,0xb8,0xb7,0xb7,0xb7,0xb6,
+0xb6,0xb6,0xb5,0xb5,0xb5,0xb4,0xb4,0xb4,
+0xb3,0xb3,0xb2,0xb2,0xb2,0xb1,0xb1,0xb1,
+0xb0,0xb0,0xb0,0xaf,0xaf,0xae,0xae,0xae,
+0xad,0xad,0xad,0xac,0xac,0xac,0xab,0xab,
+0xaa,0xaa,0xaa,0xa9,0xa9,0xa9,0xa8,0xa8,
+0xa7,0xa7,0xa7,0xa6,0xa6,0xa6,0xa5,0xa5,
+0xa5,0xa4,0xa4,0xa3,0xa3,0xa3,0xa2,0xa2,
+0xa2,0xa1,0xa1,0xa0,0xa0,0xa0,0x9f,0x9f,
+0x9e,0x9e,0x9e,0x9d,0x9d,0x9d,0x9c,0x9c,
+0x9b,0x9b,0x9b,0x9a,0x9a,0x9a,0x99,0x99,
+0x98,0x98,0x98,0x97,0x97,0x96,0x96,0x96,
+0x95,0x95,0x95,0x94,0x94,0x93,0x93,0x93,
+0x92,0x92,0x91,0x91,0x91,0x90,0x90,0x8f,
+0x8f,0x8f,0x8e,0x8e,0x8e,0x8d,0x8d,0x8c,
+0x8c,0x8c,0x8b,0x8b,0x8a,0x8a,0x8a,0x89,
+0x89,0x88,0x88,0x88,0x87,0x87,0x87,0x86,
+0x86,0x85,0x85,0x85,0x84,0x84,0x83,0x83,
+0x83,0x82,0x82,0x81,0x81,0x81,0x80,0x80,
+0x80,0x7f,0x7f,0x7e,0x7e,0x7e,0x7d,0x7d,
+0x7c,0x7c,0x7c,0x7b,0x7b,0x7a,0x7a,0x7a,
+0x79,0x79,0x78,0x78,0x78,0x77,0x77,0x77,
+0x76,0x76,0x75,0x75,0x75,0x74,0x74,0x73,
+0x73,0x73,0x72,0x72,0x71,0x71,0x71,0x70,
+0x70,0x70,0x6f,0x6f,0x6e,0x6e,0x6e,0x6d,
+0x6d,0x6c,0x6c,0x6c,0x6b,0x6b,0x6a,0x6a,
+0x6a,0x69,0x69,0x69,0x68,0x68,0x67,0x67,
+0x67,0x66,0x66,0x65,0x65,0x65,0x64,0x64,
+0x64,0x63,0x63,0x62,0x62,0x62,0x61,0x61,
+0x61,0x60,0x60,0x5f,0x5f,0x5f,0x5e,0x5e,
+0x5d,0x5d,0x5d,0x5c,0x5c,0x5c,0x5b,0x5b,
+0x5a,0x5a,0x5a,0x59,0x59,0x59,0x58,0x58,
+0x58,0x57,0x57,0x56,0x56,0x56,0x55,0x55,
+0x55,0x54,0x54,0x53,0x53,0x53,0x52,0x52,
+0x52,0x51,0x51,0x51,0x50,0x50,0x4f,0x4f,
+0x4f,0x4e,0x4e,0x4e,0x4d,0x4d,0x4d,0x4c,
+0x4c,0x4b,0x4b,0x4b,0x4a,0x4a,0x4a,0x49,
+0x49,0x49,0x48,0x48,0x48,0x47,0x47,0x47,
+0x46,0x46,0x45,0x45,0x45,0x44,0x44,0x44,
+0x43,0x43,0x43,0x42,0x42,0x42,0x41,0x41,
+0x41,0x40,0x40,0x40,0x3f,0x3f,0x3f,0x3e,
+0x3e,0x3e,0x3d,0x3d,0x3d,0x3c,0x3c,0x3c,
+0x3b,0x3b,0x3b,0x3a,0x3a,0x3a,0x39,0x39,
+0x39,0x38,0x38,0x38,0x37,0x37,0x37,0x36,
+0x36,0x36,0x35,0x35,0x35,0x34,0x34,0x34,
+0x34,0x33,0x33,0x33,0x32,0x32,0x32,0x31,
+0x31,0x31,0x30,0x30,0x30,0x30,0x2f,0x2f,
+0x2f,0x2e,0x2e,0x2e,0x2d,0x2d,0x2d,0x2d,
+0x2c,0x2c,0x2c,0x2b,0x2b,0x2b,0x2a,0x2a,
+0x2a,0x2a,0x29,0x29,0x29,0x28,0x28,0x28,
+0x28,0x27,0x27,0x27,0x26,0x26,0x26,0x26,
+0x25,0x25,0x25,0x25,0x24,0x24,0x24,0x23,
+0x23,0x23,0x23,0x22,0x22,0x22,0x22,0x21,
+0x21,0x21,0x21,0x20,0x20,0x20,0x1f,0x1f,
+0x1f,0x1f,0x1e,0x1e,0x1e,0x1e,0x1d,0x1d,
+0x1d,0x1d,0x1c,0x1c,0x1c,0x1c,0x1b,0x1b,
+0x1b,0x1b,0x1b,0x1a,0x1a,0x1a,0x1a,0x19,
+0x19,0x19,0x19,0x18,0x18,0x18,0x18,0x17,
+0x17,0x17,0x17,0x17,0x16,0x16,0x16,0x16,
+0x15,0x15,0x15,0x15,0x15,0x14,0x14,0x14,
+0x14,0x14,0x13,0x13,0x13,0x13,0x13,0x12,
+0x12,0x12,0x12,0x12,0x11,0x11,0x11,0x11,
+0x11,0x10,0x10,0x10,0x10,0x10,0xf,0xf,
+0xf,0xf,0xf,0xf,0xe,0xe,0xe,0xe,
+0xe,0xd,0xd,0xd,0xd,0xd,0xd,0xc,
+0xc,0xc,0xc,0xc,0xc,0xb,0xb,0xb,
+0xb,0xb,0xb,0xa,0xa,0xa,0xa,0xa,
+0xa,0xa,0x9,0x9,0x9,0x9,0x9,0x9,
+0x9,0x8,0x8,0x8,0x8,0x8,0x8,0x8,
+0x7,0x7,0x7,0x7,0x7,0x7,0x7,0x7,
+0x6,0x6,0x6,0x6,0x6,0x6,0x6,0x6,
+0x5,0x5,0x5,0x5,0x5,0x5,0x5,0x5,
+0x5,0x5,0x4,0x4,0x4,0x4,0x4,0x4,
+0x4,0x4,0x4,0x4,0x3,0x3,0x3,0x3,
+0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,
+0x2,0x2,0x2,0x2,0x2,0x2,0x2,0x2,
+0x2,0x2,0x2,0x2,0x2,0x2,0x1,0x1,
+0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,
+0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,
+0x1,0x1,0x1,0x1,0x0,0x0,0x0,0x0,
+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
+0x0,0x0,0x0,0x0,0x0,0x1,0x1,0x1,
+0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,
+0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,
+0x1,0x1,0x1,0x2,0x2,0x2,0x2,0x2,
+0x2,0x2,0x2,0x2,0x2,0x2,0x2,0x2,
+0x2,0x3,0x3,0x3,0x3,0x3,0x3,0x3,
+0x3,0x3,0x3,0x3,0x3,0x4,0x4,0x4,
+0x4,0x4,0x4,0x4,0x4,0x4,0x4,0x5,
+0x5,0x5,0x5,0x5,0x5,0x5,0x5,0x5,
+0x5,0x6,0x6,0x6,0x6,0x6,0x6,0x6,
+0x6,0x7,0x7,0x7,0x7,0x7,0x7,0x7,
+0x7,0x8,0x8,0x8,0x8,0x8,0x8,0x8,
+0x9,0x9,0x9,0x9,0x9,0x9,0x9,0xa,
+0xa,0xa,0xa,0xa,0xa,0xa,0xb,0xb,
+0xb,0xb,0xb,0xb,0xc,0xc,0xc,0xc,
+0xc,0xc,0xd,0xd,0xd,0xd,0xd,0xd,
+0xe,0xe,0xe,0xe,0xe,0xf,0xf,0xf,
+0xf,0xf,0xf,0x10,0x10,0x10,0x10,0x10,
+0x11,0x11,0x11,0x11,0x11,0x12,0x12,0x12,
+0x12,0x12,0x13,0x13,0x13,0x13,0x13,0x14,
+0x14,0x14,0x14,0x14,0x15,0x15,0x15,0x15,
+0x15,0x16,0x16,0x16,0x16,0x17,0x17,0x17,
+0x17,0x17,0x18,0x18,0x18,0x18,0x19,0x19,
+0x19,0x19,0x1a,0x1a,0x1a,0x1a,0x1b,0x1b,
+0x1b,0x1b,0x1b,0x1c,0x1c,0x1c,0x1c,0x1d,
+0x1d,0x1d,0x1d,0x1e,0x1e,0x1e,0x1e,0x1f,
+0x1f,0x1f,0x1f,0x20,0x20,0x20,0x21,0x21,
+0x21,0x21,0x22,0x22,0x22,0x22,0x23,0x23,
+0x23,0x23,0x24,0x24,0x24,0x25,0x25,0x25,
+0x25,0x26,0x26,0x26,0x26,0x27,0x27,0x27,
+0x28,0x28,0x28,0x28,0x29,0x29,0x29,0x2a,
+0x2a,0x2a,0x2a,0x2b,0x2b,0x2b,0x2c,0x2c,
+0x2c,0x2d,0x2d,0x2d,0x2d,0x2e,0x2e,0x2e,
+0x2f,0x2f,0x2f,0x30,0x30,0x30,0x30,0x31,
+0x31,0x31,0x32,0x32,0x32,0x33,0x33,0x33,
+0x34,0x34,0x34,0x34,0x35,0x35,0x35,0x36,
+0x36,0x36,0x37,0x37,0x37,0x38,0x38,0x38,
+0x39,0x39,0x39,0x3a,0x3a,0x3a,0x3b,0x3b,
+0x3b,0x3c,0x3c,0x3c,0x3d,0x3d,0x3d,0x3e,
+0x3e,0x3e,0x3f,0x3f,0x3f,0x40,0x40,0x40,
+0x41,0x41,0x41,0x42,0x42,0x42,0x43,0x43,
+0x43,0x44,0x44,0x44,0x45,0x45,0x45,0x46,
+0x46,0x47,0x47,0x47,0x48,0x48,0x48,0x49,
+0x49,0x49,0x4a,0x4a,0x4a,0x4b,0x4b,0x4b,
+0x4c,0x4c,0x4d,0x4d,0x4d,0x4e,0x4e,0x4e,
+0x4f,0x4f,0x4f,0x50,0x50,0x51,0x51,0x51,
+0x52,0x52,0x52,0x53,0x53,0x53,0x54,0x54,
+0x55,0x55,0x55,0x56,0x56,0x56,0x57,0x57,
+0x58,0x58,0x58,0x59,0x59,0x59,0x5a,0x5a,
+0x5a,0x5b,0x5b,0x5c,0x5c,0x5c,0x5d,0x5d,
+0x5d,0x5e,0x5e,0x5f,0x5f,0x5f,0x60,0x60,
+0x61,0x61,0x61,0x62,0x62,0x62,0x63,0x63,
+0x64,0x64,0x64,0x65,0x65,0x65,0x66,0x66,
+0x67,0x67,0x67,0x68,0x68,0x69,0x69,0x69,
+0x6a,0x6a,0x6a,0x6b,0x6b,0x6c,0x6c,0x6c,
+0x6d,0x6d,0x6e,0x6e,0x6e,0x6f,0x6f,0x70,
+0x70,0x70,0x71,0x71,0x71,0x72,0x72,0x73,
+0x73,0x73,0x74,0x74,0x75,0x75,0x75,0x76,
+0x76,0x77,0x77,0x77,0x78,0x78,0x78,0x79,
+0x79,0x7a,0x7a,0x7a,0x7b,0x7b,0x7c,0x7c,
+0x7c,0x7d,0x7d,0x7e,0x7e,0x7e,0x7f,0x7f
+};
\ No newline at end of file
diff --git a/tmk_core/common/avr/timer.c b/tmk_core/common/avr/timer.c
index 292b41c3a6..1a695a9aae 100644
--- a/tmk_core/common/avr/timer.c
+++ b/tmk_core/common/avr/timer.c
@@ -29,24 +29,24 @@ volatile uint32_t timer_count = 0;
 void timer_init(void)
 {
     // Timer0 CTC mode
-    TCCR0A = 0x02;
+    TCCR1A = 0x02;
 
 #if TIMER_PRESCALER == 1
-    TCCR0B = 0x01;
+    TCCR1B = 0x01;
 #elif TIMER_PRESCALER == 8
-    TCCR0B = 0x02;
+    TCCR1B = 0x02;
 #elif TIMER_PRESCALER == 64
-    TCCR0B = 0x03;
+    TCCR1B = 0x03;
 #elif TIMER_PRESCALER == 256
-    TCCR0B = 0x04;
+    TCCR1B = 0x04;
 #elif TIMER_PRESCALER == 1024
-    TCCR0B = 0x05;
+    TCCR1B = 0x05;
 #else
 #   error "Timer prescaler value is NOT vaild."
 #endif
 
-    OCR0A = TIMER_RAW_TOP;
-    TIMSK0 = (1<<OCIE0A);
+    OCR1A = TIMER_RAW_TOP;
+    TIMSK1 = (1<<OCIE1A);
 }
 
 inline
@@ -111,7 +111,7 @@ uint32_t timer_elapsed32(uint32_t last)
 }
 
 // excecuted once per 1ms.(excess for just timer count?)
-ISR(TIMER0_COMPA_vect)
+ISR(TIMER1_COMPA_vect)
 {
     timer_count++;
 }

From 0f867796de6f24a202463e125c1b4bc961621bf7 Mon Sep 17 00:00:00 2001
From: Jack Humbert <jack.humb@gmail.com>
Date: Mon, 11 Jan 2016 17:52:35 -0500
Subject: [PATCH 2/6] timer 3

---
 quantum/beeps.c             | 151 +++---------------------------------
 tmk_core/common/avr/timer.c |  18 ++---
 2 files changed, 18 insertions(+), 151 deletions(-)

diff --git a/quantum/beeps.c b/quantum/beeps.c
index edcc84aca4..08b35abbd8 100644
--- a/quantum/beeps.c
+++ b/quantum/beeps.c
@@ -32,33 +32,9 @@ bool sliding = false;
 #define RANGE 1000
 volatile int i=0; //elements of the wave
 
-// uint8_t sine[128];
-// uint8_t tri[128];
-// uint8_t squ[128];
-// uint8_t* sine_start;
-// uint8_t* sine_end;
-// uint8_t* tri_start;
-// uint8_t* tri_end;
-
-// uint8_t* s_start;
-// uint8_t* s_end;
-// uint8_t* s_ptr;
-
-
-
-void beeps() {
-    play_notes();
-}
-
-void send_freq(double freq, int vol) {
-    int duty = (((double)F_CPU) / freq);
-    ICR3 = duty; // Set max to the period
-    OCR3A = duty >> (0x10 - vol); // Set compare to half the period
-}
-
 void stop_all_notes() {
     voices = 0;
-    TIMSK0 &= ~_BV(OCIE0A);
+    TIMSK3 &= ~_BV(OCIE3A);
     frequency = 0;
     volume = 0;
 
@@ -86,7 +62,7 @@ void stop_note(double freq) {
     if (voices < 0)
         voices = 0;
     if (voices == 0) {
-        TIMSK0 &= ~_BV(OCIE0A);
+        TIMSK3 &= ~_BV(OCIE3A);
         frequency = 0;
         volume = 0;
     } else {
@@ -106,7 +82,6 @@ void stop_note(double freq) {
             }
             sliding = false;
         }
-        // send_freq(freq, vol);
         frequency = freq;
         volume = vol;
     }
@@ -114,18 +89,6 @@ void stop_note(double freq) {
 
 void init_notes() {
 
-    // for(int i = 0; i < 128; i++) {
-    //     sine[i] = sin(i * PI / 64) * 128 + 128;
-    //     tri[i] = 256 - abs((i - 64) * 4);
-    // }
-    // sine_start = &sine;
-    // sine_end = &sine + 128;
-    // tri_start = &tri;
-    // tri_end = &tri + 128;
-
- // new
-
-
   PLLFRQ = _BV(PDIV2);
   PLLCSR = _BV(PLLE);
   while(!(PLLCSR & _BV(PLOCK)));
@@ -139,28 +102,6 @@ void init_notes() {
   /* Enable the OC4A output */
   DDRC |= _BV(PORTC6);
 
-
-
-       /* First disable the timer overflow interrupt while we're configuring */
-  // TIMSK0 &= ~(1<<TOIE0);
- 
-  // /* Configure timer4 in normal mode (pure counting, no PWM etc.) */
-  // TCCR0A &= ~((1<<WGM01) | (1<<WGM00));
-  // TCCR0B &= ~(1<<WGM02);
-
-  // /* Disable Compare Match A interrupt enable (only want overflow) */
-  // TIMSK0 &= ~(1<<OCIE0A);
-  
-  // TCCR0B |= (1<<CS01); // Set bits
-  // TCCR0B &= ~(1<<CS00) | ~(1<<CS02);             // Clear bit
-   
-  // /* Save value globally for later reload in ISR */
-  // tcnt0 = 45 - 1; 
-
-  // /* Finally load end enable the timer */
-  // TCNT0 = tcnt0;
-  // TIMSK0 |= (1<<TOIE0);
-
 }
 
 int max = 0xFF;
@@ -168,28 +109,7 @@ float sum = 0;
 int value = 128;
 float place = 0;
 
-ISR(TIMER0_COMPA_vect) {
-
-
-
-    // value = *(sine_start+=(long)frequencies[0]);
-    // OCR4A = value;
-    // if (sine_start >= sine_end) {
-    //     sine_start = &sine[(sine_start - sine_end) % 128];
-    // }
-
-
-    // OCR4A = pgm_read_byte(sine_start);
-    // // sine_start = &sine[(sine_start - &sine[0] + (int)frequencies[0]) % 128];
-    // sine_start +=  (int)frequencies[0];
-    // if (sine_start >= sine_end) {
-    //     sine_start = &sine[(sine_start - sine_end) % 128];
-    // }
-    
-    // OCR4A = pgm_read_byte(s_ptr);
-    // s_ptr = s_start + (uint8_t)place;
-    // OCR4A = pgm_read_byte(s_ptr);
-
+ISR(TIMER3_COMPA_vect) {
 
     // SINE
     OCR4A = pgm_read_byte(&sinewave[(uint16_t)place]);
@@ -217,24 +137,10 @@ ISR(TIMER0_COMPA_vect) {
 
 }
 
-
-ISR(TIMER0_COMPB_vect)
-{
-
-  /* Disable the interrupt */
-  TIMSK0 &= ~_BV(OCIE0B);
-
-}
-
 void play_note(double freq, int vol) {
 
     freq = freq / SAMPLE_RATE;
     if (freq > 0) {
-
-        // TCCR3A = (1 << COM3A1) | (0 << COM3A0) | (1 << WGM31) | (1 << WGM30);
-        // TCCR3B = (0 << WGM33) | (1 << WGM32) | (0 << CS32) | (0 << CS31) | (1 << CS30);
-
-      // TIMSK3 = 0x0;
         if (frequency != 0) {
             double starting_f = frequency;
             if (frequency < freq) {
@@ -247,59 +153,20 @@ void play_note(double freq, int vol) {
                 }
             }
         }
-        // send_freq(freq, vol);
         frequency = freq;
         volume = vol;
 
         frequencies[voices] = frequency;
         volumes[voices] = volume;
         voices++;
-        // position = 0;
-        // TCNT0 = 0;
     }
-    // ICR3 = 0xFFFF;
-    // for (int i = 0; i < 10000; i++) {
-    //     OCR3A = round((sin(i*freq)*.5)+.5)*0xFFFF;
-    //     // _delay_us(50);
-    // }
 
-    // TCCR3A = 0;
-    // TCCR3B = 0;
+    TIMSK3 &= ~_BV(OCIE3A);
 
+    TCCR3A = 0x0; 
+    TCCR3B = _BV(CS31) | _BV(WGM32);
+    OCR3A = SAMPLE_DIVIDER - 1;
 
-    TIMSK0 &= ~_BV(OCIE0A) | ~_BV(OCIE0B);
+    TIMSK3 |= _BV(OCIE3A);
 
-    TCCR0A = _BV(WGM01); 
-    TCCR0B = _BV(CS01);
-    OCR0A = SAMPLE_DIVIDER - 1;  
-    OCR0B = 1;
-
-    TIMSK0 |= _BV(OCIE0A);
-    // sei();
-
-}
-
-// void note(int x, float length) {
-//     DDRC |= (1<<6);
-// 	int t = (int)(440*pow(2,-x/12.0)); // starting note
-//     for (int y = 0; y < length*1000/t; y++) { // note length
-//         PORTC |= (1<<6);
-//         delay_us(t);
-//         PORTC &= ~(1<<6);
-//         delay_us(t);
-//     }
-// 	PORTC &= ~(1<<6);
-// }
-
-// void true_note(float x, float y, float length) {
-// 	for (uint32_t i = 0; i < length * 50; i++) {
-// 		uint32_t v = (uint32_t) (round(sin(PI*2*i*640000*pow(2, x/12.0))*.5+1 + sin(PI*2*i*640000*pow(2, y/12.0))*.5+1) / 2 * pow(2, 8)); 
-// 		for (int u = 0; u < 8; u++) {
-// 			if (v & (1 << u) && !(PORTC&(1<<6)))
-// 		        PORTC |= (1<<6);
-// 		    else if (PORTC&(1<<6))
-// 	        	PORTC &= ~(1<<6);
-// 		}
-// 	}
-// 	PORTC &= ~(1<<6);
-// }
\ No newline at end of file
+}
\ No newline at end of file
diff --git a/tmk_core/common/avr/timer.c b/tmk_core/common/avr/timer.c
index 1a695a9aae..292b41c3a6 100644
--- a/tmk_core/common/avr/timer.c
+++ b/tmk_core/common/avr/timer.c
@@ -29,24 +29,24 @@ volatile uint32_t timer_count = 0;
 void timer_init(void)
 {
     // Timer0 CTC mode
-    TCCR1A = 0x02;
+    TCCR0A = 0x02;
 
 #if TIMER_PRESCALER == 1
-    TCCR1B = 0x01;
+    TCCR0B = 0x01;
 #elif TIMER_PRESCALER == 8
-    TCCR1B = 0x02;
+    TCCR0B = 0x02;
 #elif TIMER_PRESCALER == 64
-    TCCR1B = 0x03;
+    TCCR0B = 0x03;
 #elif TIMER_PRESCALER == 256
-    TCCR1B = 0x04;
+    TCCR0B = 0x04;
 #elif TIMER_PRESCALER == 1024
-    TCCR1B = 0x05;
+    TCCR0B = 0x05;
 #else
 #   error "Timer prescaler value is NOT vaild."
 #endif
 
-    OCR1A = TIMER_RAW_TOP;
-    TIMSK1 = (1<<OCIE1A);
+    OCR0A = TIMER_RAW_TOP;
+    TIMSK0 = (1<<OCIE0A);
 }
 
 inline
@@ -111,7 +111,7 @@ uint32_t timer_elapsed32(uint32_t last)
 }
 
 // excecuted once per 1ms.(excess for just timer count?)
-ISR(TIMER1_COMPA_vect)
+ISR(TIMER0_COMPA_vect)
 {
     timer_count++;
 }

From 263344d42f8b16e1cd80c4c871e15fa86208d086 Mon Sep 17 00:00:00 2001
From: Jack Humbert <jack.humb@gmail.com>
Date: Mon, 11 Jan 2016 18:00:07 -0500
Subject: [PATCH 3/6] beeps on lock keymap

---
 keyboard/planck/keymaps/keymap_lock.c | 32 ++++++++++++++++++++++++++-
 keyboard/planck/planck.c              | 29 ------------------------
 2 files changed, 31 insertions(+), 30 deletions(-)

diff --git a/keyboard/planck/keymaps/keymap_lock.c b/keyboard/planck/keymaps/keymap_lock.c
index c2bf0b7d81..c8e1b8fa86 100644
--- a/keyboard/planck/keymaps/keymap_lock.c
+++ b/keyboard/planck/keymaps/keymap_lock.c
@@ -107,7 +107,7 @@ const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt)
           // note(0+24, 20);
         } else {
           unregister_code(KC_RSFT);
-          // stop_all_notes();
+          stop_all_notes();
           // backlight_set(0);
           default_layer_and(0); 
           default_layer_or(0);
@@ -119,3 +119,33 @@ const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt)
       } 
     return MACRO_NONE;
 };
+
+
+void * matrix_init_user(void) {
+    init_notes();
+
+    play_note(((double)261.6*3)*pow(2.0,(36)/12.0), 0xF);
+    _delay_ms(50);
+
+    play_note(((double)261.6*3)*pow(2.0,(48)/12.0), 0xF);
+    _delay_ms(25);
+    stop_note(((double)261.6*3)*pow(2.0,(48)/12.0));
+
+    play_note(((double)261.6*3)*pow(2.0,(48)/12.0), 0xF);
+    _delay_ms(25);
+    stop_note(((double)261.6*3)*pow(2.0,(48)/12.0));
+
+
+    stop_note(((double)261.6*3)*pow(2.0,(36)/12.0));
+
+
+    play_note(((double)261.6*3)*pow(2.0,(62)/12.0), 0xF);
+    _delay_ms(50);
+    stop_note(((double)261.6*3)*pow(2.0,(62)/12.0));
+
+
+    play_note(((double)261.6*3)*pow(2.0,(64)/12.0), 0xF);
+    _delay_ms(50);
+    stop_note(((double)261.6*3)*pow(2.0,(64)/12.0));
+
+}
diff --git a/keyboard/planck/planck.c b/keyboard/planck/planck.c
index a986bd8812..b62862af04 100644
--- a/keyboard/planck/planck.c
+++ b/keyboard/planck/planck.c
@@ -19,35 +19,6 @@ void * matrix_init_kb(void) {
     DDRE |= (1<<6);
     PORTE |= (1<<6);
 
-    init_notes();
-
-    // play_note(((double)261.6*32)*pow(2.0,(36)/12.0), 0xF);
-    // _delay_ms(50);
-
-    // play_note(((double)261.6*32)*pow(2.0,(48)/12.0), 0xF);
-    // _delay_ms(25);
-    // stop_note(((double)261.6*32)*pow(2.0,(48)/12.0));
-
-    // play_note(((double)261.6*32)*pow(2.0,(48)/12.0), 0xF);
-    // _delay_ms(25);
-    // stop_note(((double)261.6*32)*pow(2.0,(48)/12.0));
-
-
-    // stop_note(((double)261.6*32)*pow(2.0,(36)/12.0));
-
-
-    // play_note(((double)261.6*32)*pow(2.0,(62)/12.0), 0xF);
-    // _delay_ms(50);
-    // stop_note(((double)261.6*32)*pow(2.0,(62)/12.0));
-
-
-    // play_note(((double)261.6*32)*pow(2.0,(64)/12.0), 0xF);
-    // _delay_ms(50);
-    // stop_note(((double)261.6*32)*pow(2.0,(64)/12.0));
-
-
-
-
 	if (matrix_init_user) {
 		(*matrix_init_user)();
 	}

From 4c100dbbef5b97290cbe6d4846575a940649c958 Mon Sep 17 00:00:00 2001
From: Jack Humbert <jack.humb@gmail.com>
Date: Wed, 13 Jan 2016 00:25:31 -0500
Subject: [PATCH 4/6] note seq, start-up beeps, function beeps

---
 keyboard/planck/keymaps/keymap_lock.c |  73 ++++++++++---
 quantum/beeps.c                       | 147 +++++++++++++++++++++-----
 quantum/beeps.h                       |   9 +-
 3 files changed, 183 insertions(+), 46 deletions(-)

diff --git a/keyboard/planck/keymaps/keymap_lock.c b/keyboard/planck/keymaps/keymap_lock.c
index c8e1b8fa86..5e5390b036 100644
--- a/keyboard/planck/keymaps/keymap_lock.c
+++ b/keyboard/planck/keymaps/keymap_lock.c
@@ -2,6 +2,7 @@
 // #include "backlight.h"
 #include "action_layer.h"
 #include "keymap_midi.h"
+#include "beeps.h"
 #include <avr/boot.h>
 
 const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
@@ -63,12 +64,26 @@ uint16_t hextokeycode(int hex) {
     }
 }
 
+float walk_up[][2] = {
+  {440.0*pow(2.0,(60)/12.0), 400},
+  {0, 50},
+  {440.0*pow(2.0,(67)/12.0), 400},
+};
+
+float walk_dn[][2] = {
+  {440.0*pow(2.0,(67)/12.0), 400},
+  {0, 50},
+  {440.0*pow(2.0,(60)/12.0), 400},
+};
+
 const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt) 
 {
   // MACRODOWN only works in this function
       switch(id) {
         case 0:   
         if (record->event.pressed) {
+
+          play_notes(&walk_up, 3, false);
           // play_note(440, 20);
           // register_code(KC_RSFT);
           // backlight_set(BACKLIGHT_LEVELS);
@@ -107,7 +122,7 @@ const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt)
           // note(0+24, 20);
         } else {
           unregister_code(KC_RSFT);
-          stop_all_notes();
+          play_notes(&walk_dn, 3, false);
           // backlight_set(0);
           default_layer_and(0); 
           default_layer_or(0);
@@ -120,32 +135,58 @@ const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt)
     return MACRO_NONE;
 };
 
+float start_up[][2] = {
+  {440.0*pow(2.0,(67)/12.0), 600},
+  {0, 50},
+  {440.0*pow(2.0,(64)/12.0), 400},
+  {0, 50},
+  {440.0*pow(2.0,(55)/12.0), 400},
+  {0, 50},
+  {440.0*pow(2.0,(60)/12.0), 400},
+  {0, 50},
+  {440.0*pow(2.0,(64)/12.0), 1000},
+};
 
 void * matrix_init_user(void) {
     init_notes();
 
-    play_note(((double)261.6*3)*pow(2.0,(36)/12.0), 0xF);
-    _delay_ms(50);
+    play_notes(&start_up, 9, false);
+    // play_note(((double)261.6*3)*pow(2.0,(36)/12.0), 0xF);
+    // _delay_ms(50);
 
-    play_note(((double)261.6*3)*pow(2.0,(48)/12.0), 0xF);
-    _delay_ms(25);
-    stop_note(((double)261.6*3)*pow(2.0,(48)/12.0));
+    // play_note(((double)261.6*3)*pow(2.0,(48)/12.0), 0xF);
+    // _delay_ms(25);
+    // stop_note(((double)261.6*3)*pow(2.0,(48)/12.0));
 
-    play_note(((double)261.6*3)*pow(2.0,(48)/12.0), 0xF);
-    _delay_ms(25);
-    stop_note(((double)261.6*3)*pow(2.0,(48)/12.0));
+    // play_note(((double)261.6*3)*pow(2.0,(48)/12.0), 0xF);
+    // _delay_ms(25);
+    // stop_note(((double)261.6*3)*pow(2.0,(48)/12.0));
 
 
-    stop_note(((double)261.6*3)*pow(2.0,(36)/12.0));
+    // stop_note(((double)261.6*3)*pow(2.0,(36)/12.0));
 
 
-    play_note(((double)261.6*3)*pow(2.0,(62)/12.0), 0xF);
-    _delay_ms(50);
-    stop_note(((double)261.6*3)*pow(2.0,(62)/12.0));
+    // play_note(((double)261.6*3)*pow(2.0,(62)/12.0), 0xF);
+    // _delay_ms(50);
+    // stop_note(((double)261.6*3)*pow(2.0,(62)/12.0));
 
 
-    play_note(((double)261.6*3)*pow(2.0,(64)/12.0), 0xF);
-    _delay_ms(50);
-    stop_note(((double)261.6*3)*pow(2.0,(64)/12.0));
+    // play_note(((double)261.6*3)*pow(2.0,(64)/12.0), 0xF);
+    // _delay_ms(50);
+    // stop_note(((double)261.6*3)*pow(2.0,(64)/12.0));
 
 }
+
+
+// void * matrix_scan_user(void) {
+//   if (layer_state & (1<<2)) {
+//     if (!playing_notes)
+//       play_notes(&start_up, 9, true);
+//   } else if (layer_state & (1<<3)) {
+//     if (!playing_notes)
+//       play_notes(&start_up, 9, true);
+//   } else {
+//     if (playing_notes)
+//       stop_all_notes();
+//   }
+// }
\ No newline at end of file
diff --git a/quantum/beeps.c b/quantum/beeps.c
index 08b35abbd8..7586ebc522 100644
--- a/quantum/beeps.c
+++ b/quantum/beeps.c
@@ -11,8 +11,8 @@
 
 #define PI 3.14159265
 
-#define SAMPLE_DIVIDER 70
-#define SAMPLE_RATE (2000000.0/SAMPLE_DIVIDER/256)
+#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
 
 void delay_us(int count) {
@@ -32,9 +32,31 @@ bool sliding = false;
 #define RANGE 1000
 volatile int i=0; //elements of the wave
 
+int max = 0xFF;
+float sum = 0;
+int value = 128;
+float place = 0;
+
+uint16_t place_int = 0;
+bool repeat = true;
+uint8_t * sample;
+uint16_t sample_length = 0;
+
+
+bool notes = false;
+float note_frequency = 0;
+float note_length = 0;
+uint16_t note_position = 0;
+float (* notes_pointer)[][2];
+uint8_t notes_length;
+bool notes_repeat;
+uint8_t current_note = 0;
+
 void stop_all_notes() {
     voices = 0;
     TIMSK3 &= ~_BV(OCIE3A);
+    notes = false;
+    playing_notes = false;
     frequency = 0;
     volume = 0;
 
@@ -89,30 +111,35 @@ void stop_note(double freq) {
 
 void init_notes() {
 
-  PLLFRQ = _BV(PDIV2);
-  PLLCSR = _BV(PLLE);
-  while(!(PLLCSR & _BV(PLOCK)));
-  PLLFRQ |= _BV(PLLTM0); /* PCK 48MHz */
-  
-  /* Init a fast PWM on Timer4 */
-  TCCR4A = _BV(COM4A0) | _BV(PWM4A); /* Clear OC4A on Compare Match */
-  TCCR4B = _BV(CS40); /* No prescaling => f = PCK/256 = 187500Hz */
-  OCR4A = 0;
+    PLLFRQ = _BV(PDIV2);
+    PLLCSR = _BV(PLLE);
+    while(!(PLLCSR & _BV(PLOCK)));
+    PLLFRQ |= _BV(PLLTM0); /* PCK 48MHz */
 
-  /* Enable the OC4A output */
-  DDRC |= _BV(PORTC6);
+    /* Init a fast PWM on Timer4 */
+    TCCR4A = _BV(COM4A0) | _BV(PWM4A); /* Clear OC4A on Compare Match */
+    TCCR4B = _BV(CS40); /* No prescaling => f = PCK/256 = 187500Hz */
+    OCR4A = 0;
+
+    /* Enable the OC4A output */
+    DDRC |= _BV(PORTC6);
+
+    TIMSK3 &= ~_BV(OCIE3A); // Turn off 3A interputs
+    
+    TCCR3A = 0x0; // Options not needed
+    TCCR3B = _BV(CS31) | _BV(CS30) | _BV(WGM32); // 64th prescaling and CTC
+    OCR3A = SAMPLE_DIVIDER - 1; // Correct count/compare, related to sample playback
+
+    playing_notes = false;
 
 }
 
-int max = 0xFF;
-float sum = 0;
-int value = 128;
-float place = 0;
 
 ISR(TIMER3_COMPA_vect) {
 
+
     // SINE
-    OCR4A = pgm_read_byte(&sinewave[(uint16_t)place]);
+    // OCR4A = pgm_read_byte(&sinewave[(uint16_t)place]);
     
     // SQUARE
     // if (((int)place) >= 1024){
@@ -131,10 +158,82 @@ ISR(TIMER3_COMPA_vect) {
     //     OCR4A = 2048 - (int)place / 2;
     // }
 
-    place += frequency;
-    if (place >= SINE_LENGTH)
-        place -= SINE_LENGTH;
+    // place += frequency;
 
+    // if (place >= SINE_LENGTH)
+    //     if (repeat)
+    //         place -= SINE_LENGTH;
+    //     else
+    //         TIMSK3 &= ~_BV(OCIE3A);
+
+    // SAMPLE
+    // OCR4A = pgm_read_byte(&sample[(uint16_t)place_int]);
+
+    // place_int++;
+
+    // if (place_int >= sample_length)
+    //     if (repeat)
+    //         place_int -= sample_length;
+    //     else
+    //         TIMSK3 &= ~_BV(OCIE3A);
+
+
+    if (notes) {
+        OCR4A = pgm_read_byte(&sinewave[(uint16_t)place]) >> 0;
+
+        place += note_frequency;
+        if (place >= SINE_LENGTH)
+            place -= SINE_LENGTH;
+        note_position++;
+        if (note_position >= note_length) {
+            current_note++;
+            if (current_note >= notes_length) {
+                if (notes_repeat) {
+                    current_note = 0;
+                } else {
+                    TIMSK3 &= ~_BV(OCIE3A);
+                    notes = false;
+                    playing_notes = false;
+                    return;
+                }
+            }
+            note_frequency = (*notes_pointer)[current_note][0] / SAMPLE_RATE;
+            note_length = (*notes_pointer)[current_note][1];
+            note_position = 0;
+        }
+
+    }
+
+}
+
+void play_notes(float (*np)[][2], uint8_t n_length, bool n_repeat) {
+    notes = true;
+
+    notes_pointer = np;
+    notes_length = n_length;
+    notes_repeat = n_repeat;
+
+    place = 0;
+    current_note = 0;
+    note_frequency = (*notes_pointer)[current_note][0] / SAMPLE_RATE;
+    note_length = (*notes_pointer)[current_note][1];
+    // note_frequency = 880.0 / SAMPLE_RATE;
+    // note_length = 1000;
+    note_position = 0;
+
+
+    TIMSK3 |= _BV(OCIE3A);
+    playing_notes = true;
+}
+
+void play_sample(uint8_t * s, uint16_t l, bool r) {
+    place_int = 0;
+    sample = s;
+    sample_length = l;
+    repeat = r;
+
+    TIMSK3 |= _BV(OCIE3A);
+    playing_notes = true;
 }
 
 void play_note(double freq, int vol) {
@@ -161,12 +260,6 @@ void play_note(double freq, int vol) {
         voices++;
     }
 
-    TIMSK3 &= ~_BV(OCIE3A);
-
-    TCCR3A = 0x0; 
-    TCCR3B = _BV(CS31) | _BV(WGM32);
-    OCR3A = SAMPLE_DIVIDER - 1;
-
     TIMSK3 |= _BV(OCIE3A);
 
 }
\ No newline at end of file
diff --git a/quantum/beeps.h b/quantum/beeps.h
index a7fcf6c23c..4ccc344973 100644
--- a/quantum/beeps.h
+++ b/quantum/beeps.h
@@ -3,10 +3,13 @@
 #include <avr/io.h>
 #include <util/delay.h>
 
-void note(int x, float length);
-void beeps();
-void true_note(float x, float y, float length);
+bool playing_notes;
+
+void play_sample(uint8_t * s, uint16_t l, bool r);
 void play_note(double freq, int vol);
 void stop_note(double freq);
 void stop_all_notes();
 void init_notes();
+
+
+void play_notes(float (*np)[][2], uint8_t n_length, bool n_repeat);
\ No newline at end of file

From 6e3c36360ed291b9ca2bd014571236308a933d0c Mon Sep 17 00:00:00 2001
From: Jack Humbert <jack.humb@gmail.com>
Date: Fri, 15 Jan 2016 23:10:30 -0500
Subject: [PATCH 5/6] sounds

---
 keyboard/planck/keymaps/keymap_lock.c | 4 ++--
 quantum/keymap_unicode.c              | 2 ++
 2 files changed, 4 insertions(+), 2 deletions(-)

diff --git a/keyboard/planck/keymaps/keymap_lock.c b/keyboard/planck/keymaps/keymap_lock.c
index 5e5390b036..7a99b57c9d 100644
--- a/keyboard/planck/keymaps/keymap_lock.c
+++ b/keyboard/planck/keymaps/keymap_lock.c
@@ -67,13 +67,13 @@ uint16_t hextokeycode(int hex) {
 float walk_up[][2] = {
   {440.0*pow(2.0,(60)/12.0), 400},
   {0, 50},
-  {440.0*pow(2.0,(67)/12.0), 400},
+  {440.0*pow(2.0,(67)/12.0), 600},
 };
 
 float walk_dn[][2] = {
   {440.0*pow(2.0,(67)/12.0), 400},
   {0, 50},
-  {440.0*pow(2.0,(60)/12.0), 400},
+  {440.0*pow(2.0,(60)/12.0), 600},
 };
 
 const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt) 
diff --git a/quantum/keymap_unicode.c b/quantum/keymap_unicode.c
index a9357edec7..a44965e611 100644
--- a/quantum/keymap_unicode.c
+++ b/quantum/keymap_unicode.c
@@ -30,6 +30,8 @@ uint16_t hextokeycode(int hex) {
 void action_function(keyrecord_t *record, uint8_t id, uint8_t opt)
 {
 
+    // For more info on how this works per OS, see here: https://en.wikipedia.org/wiki/Unicode_input#Hexadecimal_code_input
+
     if (record->event.pressed) {
         uint16_t unicode = (opt << 8) | id;
         register_code(KC_LALT);

From eb61700912f1713ba27d34c23d7f07be66ee6513 Mon Sep 17 00:00:00 2001
From: Jack Humbert <jack.humb@gmail.com>
Date: Wed, 20 Jan 2016 00:06:52 -0500
Subject: [PATCH 6/6] better integrations

---
 keyboard/planck/Makefile                 |   7 +-
 keyboard/planck/keymaps/keymap_default.c |   8 +-
 keyboard/planck/keymaps/keymap_lock.c    |  60 +---
 keyboard/planck/planck.h                 |   4 +-
 quantum/audio.c                          | 362 +++++++++++++++++++++++
 quantum/{beeps.h => audio.h}             |   4 -
 quantum/beeps.c                          | 265 -----------------
 quantum/keymap_midi.c                    |   4 +-
 quantum/quantum.mk                       |   7 +-
 tmk_core/common.mk                       |   3 +
 tmk_core/protocol/lufa/lufa.c            |   7 +-
 11 files changed, 402 insertions(+), 329 deletions(-)
 create mode 100644 quantum/audio.c
 rename quantum/{beeps.h => audio.h} (92%)
 delete mode 100644 quantum/beeps.c

diff --git a/keyboard/planck/Makefile b/keyboard/planck/Makefile
index fdf8c16400..7b06446d74 100644
--- a/keyboard/planck/Makefile
+++ b/keyboard/planck/Makefile
@@ -50,8 +50,7 @@ TMK_DIR = ../../tmk_core
 TARGET_DIR = .
 
 # # project specific files
-SRC = planck.c \
-	backlight.c 
+SRC = planck.c
 
 ifdef KEYMAP
     SRC := keymaps/keymap_$(KEYMAP).c $(SRC)
@@ -124,9 +123,13 @@ COMMAND_ENABLE = yes    # Commands for debug and configuration
 # NKRO_ENABLE = yes		# USB Nkey Rollover - if this doesn't work, see here: https://github.com/tmk/tmk_keyboard/wiki/FAQ#nkro-doesnt-work
 # BACKLIGHT_ENABLE = yes  # Enable keyboard backlight functionality
 MIDI_ENABLE = YES 		# MIDI controls
+AUDIO_ENABLE = YES 		# Audio output on port C6
 # UNICODE_ENABLE = YES 		# Unicode
 # BLUETOOTH_ENABLE = yes # Enable Bluetooth with the Adafruit EZ-Key HID
 
+ifdef BACKLIGHT_ENABLE
+	SRC += backlight.c
+endif
 
 # Optimize size but this may cause error "relocation truncated to fit"
 #EXTRALDFLAGS = -Wl,--relax
diff --git a/keyboard/planck/keymaps/keymap_default.c b/keyboard/planck/keymaps/keymap_default.c
index 49670dafd3..a9c2a06813 100644
--- a/keyboard/planck/keymaps/keymap_default.c
+++ b/keyboard/planck/keymaps/keymap_default.c
@@ -2,7 +2,9 @@
 // this is the style you want to emulate.
 
 #include "planck.h"
-#include "backlight.h"
+#ifdef BACKLIGHT_ENABLE
+  #include "backlight.h"
+#endif
 
 // Each layer gets a name for readability, which is then used in the keymap matrix below.
 // The underscores don't mean anything - you can have a layer called STUFF or any other name.
@@ -58,7 +60,9 @@ const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt)
         case 0:
           if (record->event.pressed) {
             register_code(KC_RSFT);
-            backlight_step();
+            #ifdef BACKLIGHT_ENABLE
+              backlight_step();
+            #endif
           } else {
             unregister_code(KC_RSFT);
           }
diff --git a/keyboard/planck/keymaps/keymap_lock.c b/keyboard/planck/keymaps/keymap_lock.c
index 7a99b57c9d..0deb212cc7 100644
--- a/keyboard/planck/keymaps/keymap_lock.c
+++ b/keyboard/planck/keymaps/keymap_lock.c
@@ -1,8 +1,10 @@
 #include "keymap_common.h"
-// #include "backlight.h"
+#ifdef BACKLIGHT_ENABLE
+  #include "backlight.h"
+#endif
 #include "action_layer.h"
 #include "keymap_midi.h"
-#include "beeps.h"
+#include "audio.h"
 #include <avr/boot.h>
 
 const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
@@ -86,7 +88,9 @@ const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt)
           play_notes(&walk_up, 3, false);
           // play_note(440, 20);
           // register_code(KC_RSFT);
-          // backlight_set(BACKLIGHT_LEVELS);
+          #ifdef BACKLIGHT_ENABLE
+            backlight_set(BACKLIGHT_LEVELS);
+          #endif
           default_layer_and(0); 
           default_layer_or((1<<5));
 
@@ -118,17 +122,14 @@ const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt)
           // register_code(hextokeycode((lock & 0x0F)));
           // unregister_code(hextokeycode((lock & 0x0F)));
 
-          // note(0+12, 20);
-          // note(0+24, 20);
         } else {
           unregister_code(KC_RSFT);
           play_notes(&walk_dn, 3, false);
-          // backlight_set(0);
+          #ifdef BACKLIGHT_ENABLE
+            backlight_set(0);
+          #endif
           default_layer_and(0); 
           default_layer_or(0);
-          // note(0+24, 20);
-          // note(0, 20);
-          // play_note(4, 20);
         }
         break;
       } 
@@ -149,44 +150,5 @@ float start_up[][2] = {
 
 void * matrix_init_user(void) {
     init_notes();
-
     play_notes(&start_up, 9, false);
-    // play_note(((double)261.6*3)*pow(2.0,(36)/12.0), 0xF);
-    // _delay_ms(50);
-
-    // play_note(((double)261.6*3)*pow(2.0,(48)/12.0), 0xF);
-    // _delay_ms(25);
-    // stop_note(((double)261.6*3)*pow(2.0,(48)/12.0));
-
-    // play_note(((double)261.6*3)*pow(2.0,(48)/12.0), 0xF);
-    // _delay_ms(25);
-    // stop_note(((double)261.6*3)*pow(2.0,(48)/12.0));
-
-
-    // stop_note(((double)261.6*3)*pow(2.0,(36)/12.0));
-
-
-    // play_note(((double)261.6*3)*pow(2.0,(62)/12.0), 0xF);
-    // _delay_ms(50);
-    // stop_note(((double)261.6*3)*pow(2.0,(62)/12.0));
-
-
-    // play_note(((double)261.6*3)*pow(2.0,(64)/12.0), 0xF);
-    // _delay_ms(50);
-    // stop_note(((double)261.6*3)*pow(2.0,(64)/12.0));
-
-}
-
-
-// void * matrix_scan_user(void) {
-//   if (layer_state & (1<<2)) {
-//     if (!playing_notes)
-//       play_notes(&start_up, 9, true);
-//   } else if (layer_state & (1<<3)) {
-//     if (!playing_notes)
-//       play_notes(&start_up, 9, true);
-//   } else {
-//     if (playing_notes)
-//       stop_all_notes();
-//   }
-// }
\ No newline at end of file
+}
\ No newline at end of file
diff --git a/keyboard/planck/planck.h b/keyboard/planck/planck.h
index 32c08f3b0b..e775ea7c62 100644
--- a/keyboard/planck/planck.h
+++ b/keyboard/planck/planck.h
@@ -3,7 +3,9 @@
 
 #include "matrix.h"
 #include "keymap_common.h"
-// #include "backlight.h"
+#ifdef BACKLIGHT_ENABLE
+	#include "backlight.h"
+#endif
 #include <stddef.h>
 #ifdef MIDI_ENABLE
 	#include <keymap_midi.h>
diff --git a/quantum/audio.c b/quantum/audio.c
new file mode 100644
index 0000000000..3a3a1a4910
--- /dev/null
+++ b/quantum/audio.c
@@ -0,0 +1,362 @@
+#include <stdio.h>
+#include <string.h>
+#include <math.h>
+#include <avr/pgmspace.h>
+#include <avr/interrupt.h>
+#include <avr/io.h>
+
+#include "audio.h"
+#include "keymap_common.h"
+
+#define PI 3.14159265
+
+// #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
+#endif
+
+void delay_us(int count) {
+  while(count--) {
+    _delay_us(1);
+  }
+}
+
+int voices = 0;
+int voice_place = 0;
+double frequency = 0;
+int volume = 0;
+long position = 0;
+
+double 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;
+
+
+bool notes = false;
+bool note = false;
+float note_frequency = 0;
+float note_length = 0;
+uint16_t note_position = 0;
+float (* notes_pointer)[][2];
+uint8_t notes_length;
+bool notes_repeat;
+uint8_t current_note = 0;
+
+void stop_all_notes() {
+    voices = 0;
+    #ifdef PWM_AUDIO
+        TIMSK3 &= ~_BV(OCIE3A);
+    #else
+        TIMSK3 &= ~_BV(OCIE3A);
+        TCCR3A &= ~_BV(COM3A1);
+    #endif
+    notes = false;
+    note = false;
+    frequency = 0;
+    volume = 0;
+
+    for (int i = 0; i < 8; i++) {
+        frequencies[i] = 0;
+        volumes[i] = 0;
+    }
+}
+
+void stop_note(double freq) {
+    #ifdef PWM_AUDIO
+        freq = freq / SAMPLE_RATE;
+    #endif
+    for (int i = 7; i >= 0; i--) {
+        if (frequencies[i] == freq) {
+            frequencies[i] = 0;
+            volumes[i] = 0;
+            for (int j = i; (j < 7); j++) {
+                frequencies[j] = frequencies[j+1];
+                frequencies[j+1] = 0;
+                volumes[j] = volumes[j+1];
+                volumes[j+1] = 0;
+            }
+        }
+    }
+    voices--;
+    if (voices < 0)
+        voices = 0;
+    if (voices == 0) {
+        #ifdef PWM_AUDIO
+            TIMSK3 &= ~_BV(OCIE3A);
+        #else
+            TIMSK3 &= ~_BV(OCIE3A);
+            TCCR3A &= ~_BV(COM3A1);
+        #endif
+        frequency = 0;
+        volume = 0;
+        note = false;
+    } else {
+        double freq = frequencies[voices - 1];
+        int vol = volumes[voices - 1];
+        double starting_f = frequency;
+        if (frequency < freq) {
+            sliding = true;
+            for (double f = starting_f; f <= freq; f += ((freq - starting_f) / 2000.0)) {
+                frequency = f;
+            }
+            sliding = false;
+        } else if (frequency > freq) {
+            sliding = true;
+            for (double f = starting_f; f >= freq; f -= ((starting_f - freq) / 2000.0)) {
+                frequency = f;
+            }
+            sliding = false;
+        }
+        frequency = freq;
+        volume = vol;
+    }
+}
+
+void init_notes() {
+
+    #ifdef PWM_AUDIO
+        PLLFRQ = _BV(PDIV2);
+        PLLCSR = _BV(PLLE);
+        while(!(PLLCSR & _BV(PLOCK)));
+        PLLFRQ |= _BV(PLLTM0); /* PCK 48MHz */
+
+        /* Init a fast PWM on Timer4 */
+        TCCR4A = _BV(COM4A0) | _BV(PWM4A); /* Clear OC4A on Compare Match */
+        TCCR4B = _BV(CS40); /* No prescaling => f = PCK/256 = 187500Hz */
+        OCR4A = 0;
+
+        /* Enable the OC4A output */
+        DDRC |= _BV(PORTC6);
+
+        TIMSK3 &= ~_BV(OCIE3A); // Turn off 3A interputs
+        
+        TCCR3A = 0x0; // Options not needed
+        TCCR3B = _BV(CS31) | _BV(CS30) | _BV(WGM32); // 64th prescaling and CTC
+        OCR3A = SAMPLE_DIVIDER - 1; // Correct count/compare, related to sample playback
+    #else
+        DDRC |= _BV(PORTC6);
+
+        TIMSK3 &= ~_BV(OCIE3A); // Turn off 3A interputs
+
+        TCCR3A = (0 << COM3A1) | (0 << COM3A0) | (1 << WGM31) | (0 << WGM30);
+        TCCR3B = (1 << WGM33) | (1 << WGM32) | (0 << CS32) | (1 << CS31) | (0 << CS30);
+    #endif
+}
+
+
+ISR(TIMER3_COMPA_vect) {
+
+    if (note) {
+        #ifdef PWM_AUDIO
+            if (voices == 1) {
+                // SINE
+                OCR4A = pgm_read_byte(&sinewave[(uint16_t)place]) >> 2;
+            
+                // SQUARE
+                // if (((int)place) >= 1024){
+                //     OCR4A = 0xFF >> 2;
+                // } else {
+                //     OCR4A = 0x00;
+                // }
+                
+                // SAWTOOTH
+                // OCR4A = (int)place / 4;
+
+                // TRIANGLE
+                // if (((int)place) >= 1024) {
+                //     OCR4A = (int)place / 2;
+                // } else {
+                //     OCR4A = 2048 - (int)place / 2;
+                // }
+
+                place += frequency;
+
+                if (place >= SINE_LENGTH)
+                    place -= SINE_LENGTH;
+
+            } else {
+                int sum = 0;
+                for (int i = 0; i < voices; i++) {
+                    // SINE
+                    sum += pgm_read_byte(&sinewave[(uint16_t)places[i]]) >> 2;
+
+                    // SQUARE
+                    // if (((int)places[i]) >= 1024){
+                    //     sum += 0xFF >> 2;
+                    // } else {
+                    //     sum += 0x00;
+                    // }
+
+                    places[i] += frequencies[i];
+
+                    if (places[i] >= SINE_LENGTH)
+                        places[i] -= SINE_LENGTH;
+                }
+                OCR4A = sum;
+            }
+        #else
+            if (frequency > 0) {
+                // ICR3 = (int)(((double)F_CPU) / frequency); // Set max to the period
+                // OCR3A = (int)(((double)F_CPU) / frequency) >> 1; // Set compare to half the period
+                if (place > 10) {
+                    voice_place = (voice_place + 1) % voices;
+                    place = 0.0;
+                }
+                ICR3 = (int)(((double)F_CPU) / frequencies[voice_place]); // Set max to the period
+                OCR3A = (int)(((double)F_CPU) / frequencies[voice_place]) >> 1; // Set compare to half the period
+                place++;
+            }
+        #endif
+    }
+
+    // SAMPLE
+    // OCR4A = pgm_read_byte(&sample[(uint16_t)place_int]);
+
+    // place_int++;
+
+    // if (place_int >= sample_length)
+    //     if (repeat)
+    //         place_int -= sample_length;
+    //     else
+    //         TIMSK3 &= ~_BV(OCIE3A);
+
+
+    if (notes) {
+        #ifdef PWM_AUDIO
+            OCR4A = pgm_read_byte(&sinewave[(uint16_t)place]) >> 0;
+
+            place += note_frequency;
+            if (place >= SINE_LENGTH)
+                place -= SINE_LENGTH;
+        #else
+            if (note_frequency > 0) {
+                ICR3 = (int)(((double)F_CPU) / note_frequency); // Set max to the period
+                OCR3A = (int)(((double)F_CPU) / note_frequency) >> 1; // Set compare to half the period
+            }
+        #endif
+
+
+        note_position++;
+        if (note_position >= note_length) {
+            current_note++;
+            if (current_note >= notes_length) {
+                if (notes_repeat) {
+                    current_note = 0;
+                } else {
+                    #ifdef PWM_AUDIO
+                        TIMSK3 &= ~_BV(OCIE3A);
+                    #else
+                        TIMSK3 &= ~_BV(OCIE3A);
+                        TCCR3A &= ~_BV(COM3A1);
+                    #endif
+                    notes = false;
+                    return;
+                }
+            }
+            #ifdef PWM_AUDIO
+                note_frequency = (*notes_pointer)[current_note][0] / SAMPLE_RATE;
+                note_length = (*notes_pointer)[current_note][1];
+            #else
+                note_frequency = (*notes_pointer)[current_note][0];
+                note_length = (*notes_pointer)[current_note][1] / 4;
+            #endif
+            note_position = 0;
+        }
+
+    }
+
+}
+
+void play_notes(float (*np)[][2], uint8_t n_length, bool n_repeat) {
+    if (note)
+        stop_all_notes();
+    notes = true;
+
+    notes_pointer = np;
+    notes_length = n_length;
+    notes_repeat = n_repeat;
+
+    place = 0;
+    current_note = 0;
+    #ifdef PWM_AUDIO
+        note_frequency = (*notes_pointer)[current_note][0] / SAMPLE_RATE;
+        note_length = (*notes_pointer)[current_note][1];
+    #else
+        note_frequency = (*notes_pointer)[current_note][0];
+        note_length = (*notes_pointer)[current_note][1] / 4;
+    #endif
+    note_position = 0;
+
+
+    #ifdef PWM_AUDIO
+        TIMSK3 |= _BV(OCIE3A);
+    #else
+        TIMSK3 |= _BV(OCIE3A);
+        TCCR3A |= _BV(COM3A1);
+    #endif
+}
+
+void play_sample(uint8_t * s, uint16_t l, bool r) {
+    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 (notes)
+        stop_all_notes();
+    note = true;
+    #ifdef PWM_AUDIO
+        freq = freq / SAMPLE_RATE;
+    #endif
+    if (freq > 0) {
+        if (frequency != 0) {
+            double starting_f = frequency;
+            if (frequency < freq) {
+                for (double f = starting_f; f <= freq; f += ((freq - starting_f) / 2000.0)) {   
+                    frequency = f;
+                }
+            } else if (frequency > freq) {
+                for (double f = starting_f; f >= freq; f -= ((starting_f - freq) / 2000.0)) {
+                    frequency = f;
+                }
+            }
+        }
+        frequency = freq;
+        volume = vol;
+
+        frequencies[voices] = frequency;
+        volumes[voices] = volume;
+        voices++;
+    }
+
+    #ifdef PWM_AUDIO
+        TIMSK3 |= _BV(OCIE3A);
+    #else
+        TIMSK3 |= _BV(OCIE3A);
+        TCCR3A |= _BV(COM3A1);
+    #endif
+
+}
\ No newline at end of file
diff --git a/quantum/beeps.h b/quantum/audio.h
similarity index 92%
rename from quantum/beeps.h
rename to quantum/audio.h
index 4ccc344973..99203cea7a 100644
--- a/quantum/beeps.h
+++ b/quantum/audio.h
@@ -3,13 +3,9 @@
 #include <avr/io.h>
 #include <util/delay.h>
 
-bool playing_notes;
-
 void play_sample(uint8_t * s, uint16_t l, bool r);
 void play_note(double freq, int vol);
 void stop_note(double freq);
 void stop_all_notes();
 void init_notes();
-
-
 void play_notes(float (*np)[][2], uint8_t n_length, bool n_repeat);
\ No newline at end of file
diff --git a/quantum/beeps.c b/quantum/beeps.c
deleted file mode 100644
index 7586ebc522..0000000000
--- a/quantum/beeps.c
+++ /dev/null
@@ -1,265 +0,0 @@
-#include <stdio.h>
-#include <string.h>
-#include <math.h>
-#include <avr/pgmspace.h>
-#include <avr/interrupt.h>
-#include <avr/io.h>
-
-#include "beeps.h"
-#include "keymap_common.h"
-#include "wave.h"
-
-#define PI 3.14159265
-
-#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
-
-void delay_us(int count) {
-  while(count--) {
-    _delay_us(1);
-  }
-}
-
-int voices = 0;
-double frequency = 0;
-int volume = 0;
-long position = 0;
-
-double frequencies[8] = {0, 0, 0, 0, 0, 0, 0, 0};
-int volumes[8] = {0, 0, 0, 0, 0, 0, 0, 0};
-bool sliding = false;
-#define RANGE 1000
-volatile int i=0; //elements of the wave
-
-int max = 0xFF;
-float sum = 0;
-int value = 128;
-float place = 0;
-
-uint16_t place_int = 0;
-bool repeat = true;
-uint8_t * sample;
-uint16_t sample_length = 0;
-
-
-bool notes = false;
-float note_frequency = 0;
-float note_length = 0;
-uint16_t note_position = 0;
-float (* notes_pointer)[][2];
-uint8_t notes_length;
-bool notes_repeat;
-uint8_t current_note = 0;
-
-void stop_all_notes() {
-    voices = 0;
-    TIMSK3 &= ~_BV(OCIE3A);
-    notes = false;
-    playing_notes = false;
-    frequency = 0;
-    volume = 0;
-
-    for (int i = 0; i < 8; i++) {
-        frequencies[i] = 0;
-        volumes[i] = 0;
-    }
-}
-
-void stop_note(double freq) {
-    freq = freq / SAMPLE_RATE;
-    for (int i = 7; i >= 0; i--) {
-        if (frequencies[i] == freq) {
-            frequencies[i] = 0;
-            volumes[i] = 0;
-            for (int j = i; (j < 7); j++) {
-                frequencies[j] = frequencies[j+1];
-                frequencies[j+1] = 0;
-                volumes[j] = volumes[j+1];
-                volumes[j+1] = 0;
-            }
-        }
-    }
-    voices--;
-    if (voices < 0)
-        voices = 0;
-    if (voices == 0) {
-        TIMSK3 &= ~_BV(OCIE3A);
-        frequency = 0;
-        volume = 0;
-    } else {
-        double freq = frequencies[voices - 1];
-        int vol = volumes[voices - 1];
-        double starting_f = frequency;
-        if (frequency < freq) {
-            sliding = true;
-            for (double f = starting_f; f <= freq; f += ((freq - starting_f) / 500.0)) {
-                frequency = f;
-            }
-            sliding = false;
-        } else if (frequency > freq) {
-            sliding = true;
-            for (double f = starting_f; f >= freq; f -= ((starting_f - freq) / 500.0)) {
-                frequency = f;
-            }
-            sliding = false;
-        }
-        frequency = freq;
-        volume = vol;
-    }
-}
-
-void init_notes() {
-
-    PLLFRQ = _BV(PDIV2);
-    PLLCSR = _BV(PLLE);
-    while(!(PLLCSR & _BV(PLOCK)));
-    PLLFRQ |= _BV(PLLTM0); /* PCK 48MHz */
-
-    /* Init a fast PWM on Timer4 */
-    TCCR4A = _BV(COM4A0) | _BV(PWM4A); /* Clear OC4A on Compare Match */
-    TCCR4B = _BV(CS40); /* No prescaling => f = PCK/256 = 187500Hz */
-    OCR4A = 0;
-
-    /* Enable the OC4A output */
-    DDRC |= _BV(PORTC6);
-
-    TIMSK3 &= ~_BV(OCIE3A); // Turn off 3A interputs
-    
-    TCCR3A = 0x0; // Options not needed
-    TCCR3B = _BV(CS31) | _BV(CS30) | _BV(WGM32); // 64th prescaling and CTC
-    OCR3A = SAMPLE_DIVIDER - 1; // Correct count/compare, related to sample playback
-
-    playing_notes = false;
-
-}
-
-
-ISR(TIMER3_COMPA_vect) {
-
-
-    // SINE
-    // OCR4A = pgm_read_byte(&sinewave[(uint16_t)place]);
-    
-    // SQUARE
-    // if (((int)place) >= 1024){
-    //     OCR4A = 0xFF;
-    // } else {
-    //     OCR4A = 0x00;
-    // }
-    
-    // SAWTOOTH
-    // OCR4A = (int)place / 4;
-
-    // TRIANGLE
-    // if (((int)place) >= 1024) {
-    //     OCR4A = (int)place / 2;
-    // } else {
-    //     OCR4A = 2048 - (int)place / 2;
-    // }
-
-    // place += frequency;
-
-    // if (place >= SINE_LENGTH)
-    //     if (repeat)
-    //         place -= SINE_LENGTH;
-    //     else
-    //         TIMSK3 &= ~_BV(OCIE3A);
-
-    // SAMPLE
-    // OCR4A = pgm_read_byte(&sample[(uint16_t)place_int]);
-
-    // place_int++;
-
-    // if (place_int >= sample_length)
-    //     if (repeat)
-    //         place_int -= sample_length;
-    //     else
-    //         TIMSK3 &= ~_BV(OCIE3A);
-
-
-    if (notes) {
-        OCR4A = pgm_read_byte(&sinewave[(uint16_t)place]) >> 0;
-
-        place += note_frequency;
-        if (place >= SINE_LENGTH)
-            place -= SINE_LENGTH;
-        note_position++;
-        if (note_position >= note_length) {
-            current_note++;
-            if (current_note >= notes_length) {
-                if (notes_repeat) {
-                    current_note = 0;
-                } else {
-                    TIMSK3 &= ~_BV(OCIE3A);
-                    notes = false;
-                    playing_notes = false;
-                    return;
-                }
-            }
-            note_frequency = (*notes_pointer)[current_note][0] / SAMPLE_RATE;
-            note_length = (*notes_pointer)[current_note][1];
-            note_position = 0;
-        }
-
-    }
-
-}
-
-void play_notes(float (*np)[][2], uint8_t n_length, bool n_repeat) {
-    notes = true;
-
-    notes_pointer = np;
-    notes_length = n_length;
-    notes_repeat = n_repeat;
-
-    place = 0;
-    current_note = 0;
-    note_frequency = (*notes_pointer)[current_note][0] / SAMPLE_RATE;
-    note_length = (*notes_pointer)[current_note][1];
-    // note_frequency = 880.0 / SAMPLE_RATE;
-    // note_length = 1000;
-    note_position = 0;
-
-
-    TIMSK3 |= _BV(OCIE3A);
-    playing_notes = true;
-}
-
-void play_sample(uint8_t * s, uint16_t l, bool r) {
-    place_int = 0;
-    sample = s;
-    sample_length = l;
-    repeat = r;
-
-    TIMSK3 |= _BV(OCIE3A);
-    playing_notes = true;
-}
-
-void play_note(double freq, int vol) {
-
-    freq = freq / SAMPLE_RATE;
-    if (freq > 0) {
-        if (frequency != 0) {
-            double starting_f = frequency;
-            if (frequency < freq) {
-                for (double f = starting_f; f <= freq; f += ((freq - starting_f) / 500.0)) {   
-                    frequency = f;
-                }
-            } else if (frequency > freq) {
-                for (double f = starting_f; f >= freq; f -= ((starting_f - freq) / 500.0)) {
-                    frequency = f;
-                }
-            }
-        }
-        frequency = freq;
-        volume = vol;
-
-        frequencies[voices] = frequency;
-        volumes[voices] = volume;
-        voices++;
-    }
-
-    TIMSK3 |= _BV(OCIE3A);
-
-}
\ No newline at end of file
diff --git a/quantum/keymap_midi.c b/quantum/keymap_midi.c
index 3a1408e220..e37ea31039 100644
--- a/quantum/keymap_midi.c
+++ b/quantum/keymap_midi.c
@@ -100,10 +100,10 @@ void action_function(keyrecord_t *record, uint8_t id, uint8_t opt)
     if (record->event.pressed) {
     	// midi_send_noteon(&midi_device, record->event.key.row, starting_note + SCALE[record->event.key.col], 127);
         midi_send_noteon(&midi_device, 0, (starting_note + SCALE[record->event.key.col + offset])+12*(MATRIX_ROWS - record->event.key.row), 127);
-        play_note(((double)261.626)*pow(2.0, 0.0)*pow(2.0,(starting_note + SCALE[record->event.key.col + offset])/12.0+(MATRIX_ROWS - record->event.key.row)), 0xF);
+        play_note(((double)261.626)*pow(2.0, -1.0)*pow(2.0,(starting_note + SCALE[record->event.key.col + offset])/12.0+(MATRIX_ROWS - record->event.key.row)), 0xF);
     } else {
         // midi_send_noteoff(&midi_device, record->event.key.row, starting_note + SCALE[record->event.key.col], 127);
         midi_send_noteoff(&midi_device, 0, (starting_note + SCALE[record->event.key.col + offset])+12*(MATRIX_ROWS - record->event.key.row), 127);
-        stop_note(((double)261.626)*pow(2.0, 0.0)*pow(2.0,(starting_note + SCALE[record->event.key.col + offset])/12.0+(MATRIX_ROWS - record->event.key.row)));
+        stop_note(((double)261.626)*pow(2.0, -1.0)*pow(2.0,(starting_note + SCALE[record->event.key.col + offset])/12.0+(MATRIX_ROWS - record->event.key.row)));
     }
 }
\ No newline at end of file
diff --git a/quantum/quantum.mk b/quantum/quantum.mk
index c82e478725..81a53f2035 100644
--- a/quantum/quantum.mk
+++ b/quantum/quantum.mk
@@ -9,8 +9,11 @@ ifndef CUSTOM_MATRIX
 endif
 
 ifdef MIDI_ENABLE
-	SRC += $(QUANTUM_DIR)/keymap_midi.c \
-		   $(QUANTUM_DIR)/beeps.c
+	SRC += $(QUANTUM_DIR)/keymap_midi.c
+endif
+
+ifdef AUDIO_ENABLE
+	SRC += $(QUANTUM_DIR)/audio.c
 endif
 
 ifdef UNICODE_ENABLE
diff --git a/tmk_core/common.mk b/tmk_core/common.mk
index edbcc282a5..89c366f554 100644
--- a/tmk_core/common.mk
+++ b/tmk_core/common.mk
@@ -53,6 +53,9 @@ ifdef MIDI_ENABLE
     OPT_DEFS += -DMIDI_ENABLE
 endif
 
+ifdef AUDIO_ENABLE
+    OPT_DEFS += -DAUDIO_ENABLE
+endif
 
 ifdef USB_6KRO_ENABLE
     OPT_DEFS += -DUSB_6KRO_ENABLE
diff --git a/tmk_core/protocol/lufa/lufa.c b/tmk_core/protocol/lufa/lufa.c
index f04790f4e8..5d40dcf7b2 100644
--- a/tmk_core/protocol/lufa/lufa.c
+++ b/tmk_core/protocol/lufa/lufa.c
@@ -52,8 +52,8 @@
 #include "descriptor.h"
 #include "lufa.h"
 
-#ifdef MIDI_ENABLE
-    #include <beeps.h>
+#ifdef AUDIO_ENABLE
+    #include <audio.h>
 #endif
 
 #ifdef BLUETOOTH_ENABLE
@@ -946,6 +946,8 @@ int main(void)
 #ifdef MIDI_ENABLE
 void fallthrough_callback(MidiDevice * device,
     uint16_t cnt, uint8_t byte0, uint8_t byte1, uint8_t byte2){
+
+#ifdef AUDIO_ENABLE
   if (cnt == 3) {
     switch (byte0 & 0xF0) {
         case MIDI_NOTEON:
@@ -959,6 +961,7 @@ void fallthrough_callback(MidiDevice * device,
   if (byte0 == MIDI_STOP) {
     stop_all_notes();
   }
+#endif
 }
 
 void cc_callback(MidiDevice * device,