summary refs log tree commit diff
path: root/quantum/process_keycode
diff options
context:
space:
mode:
Diffstat (limited to 'quantum/process_keycode')
-rw-r--r--quantum/process_keycode/process_chording.c60
-rw-r--r--quantum/process_keycode/process_chording.h16
-rw-r--r--quantum/process_keycode/process_leader.c38
-rw-r--r--quantum/process_keycode/process_leader.h23
-rw-r--r--quantum/process_keycode/process_midi.c66
-rw-r--r--quantum/process_keycode/process_midi.h207
-rw-r--r--quantum/process_keycode/process_music.c171
-rw-r--r--quantum/process_keycode/process_music.h27
-rw-r--r--quantum/process_keycode/process_tap_dance.c90
-rw-r--r--quantum/process_keycode/process_tap_dance.h62
-rw-r--r--quantum/process_keycode/process_unicode.c57
-rw-r--r--quantum/process_keycode/process_unicode.h122
12 files changed, 939 insertions, 0 deletions
diff --git a/quantum/process_keycode/process_chording.c b/quantum/process_keycode/process_chording.c
new file mode 100644
index 0000000000..d7814629f3
--- /dev/null
+++ b/quantum/process_keycode/process_chording.c
@@ -0,0 +1,60 @@
+#include "process_chording.h"
+
+bool keys_chord(uint8_t keys[]) {
+  uint8_t keys_size = sizeof(keys)/sizeof(keys[0]);
+  bool pass = true;
+  uint8_t in = 0;
+  for (uint8_t i = 0; i < chord_key_count; i++) {
+    bool found = false;
+    for (uint8_t j = 0; j < keys_size; j++) {
+      if (chord_keys[i] == (keys[j] & 0xFF)) {
+        in++; // detects key in chord
+        found = true;
+        break;
+      }
+    }
+    if (found)
+      continue;
+    if (chord_keys[i] != 0)  {
+      pass = false; // makes sure rest are blank
+    }
+  }
+  return (pass && (in == keys_size));
+}
+
+bool process_chording(uint16_t keycode, keyrecord_t *record) {
+  if (keycode >= QK_CHORDING && keycode <= QK_CHORDING_MAX) {
+    if (record->event.pressed) {
+      if (!chording) {
+        chording = true;
+        for (uint8_t i = 0; i < CHORDING_MAX; i++)
+          chord_keys[i] = 0;
+        chord_key_count = 0;
+        chord_key_down = 0;
+      }
+      chord_keys[chord_key_count] = (keycode & 0xFF);
+      chord_key_count++;
+      chord_key_down++;
+      return false;
+    } else {
+      if (chording) {
+        chord_key_down--;
+        if (chord_key_down == 0) {
+          chording = false;
+          // Chord Dictionary
+          if (keys_chord((uint8_t[]){KC_ENTER, KC_SPACE})) {
+            register_code(KC_A);
+            unregister_code(KC_A);
+            return false;
+          }
+          for (uint8_t i = 0; i < chord_key_count; i++) {
+            register_code(chord_keys[i]);
+            unregister_code(chord_keys[i]);
+            return false;
+          }
+        }
+      }
+    }
+  }
+  return true;
+}
\ No newline at end of file
diff --git a/quantum/process_keycode/process_chording.h b/quantum/process_keycode/process_chording.h
new file mode 100644
index 0000000000..49c97db3bc
--- /dev/null
+++ b/quantum/process_keycode/process_chording.h
@@ -0,0 +1,16 @@
+#ifndef PROCESS_CHORDING_H
+#define PROCESS_CHORDING_H
+
+#include "quantum.h"
+
+// Chording stuff
+#define CHORDING_MAX 4
+bool chording = false;
+
+uint8_t chord_keys[CHORDING_MAX] = {0};
+uint8_t chord_key_count = 0;
+uint8_t chord_key_down = 0;
+
+bool process_chording(uint16_t keycode, keyrecord_t *record);
+
+#endif
\ No newline at end of file
diff --git a/quantum/process_keycode/process_leader.c b/quantum/process_keycode/process_leader.c
new file mode 100644
index 0000000000..e53d221e75
--- /dev/null
+++ b/quantum/process_keycode/process_leader.c
@@ -0,0 +1,38 @@
+#include "process_leader.h"
+
+__attribute__ ((weak))
+void leader_start(void) {}
+
+__attribute__ ((weak))
+void leader_end(void) {}
+
+// Leader key stuff
+bool leading = false;
+uint16_t leader_time = 0;
+
+uint16_t leader_sequence[5] = {0, 0, 0, 0, 0};
+uint8_t leader_sequence_size = 0;
+
+bool process_leader(uint16_t keycode, keyrecord_t *record) {
+  // Leader key set-up
+  if (record->event.pressed) {
+    if (!leading && keycode == KC_LEAD) {
+      leader_start();
+      leading = true;
+      leader_time = timer_read();
+      leader_sequence_size = 0;
+      leader_sequence[0] = 0;
+      leader_sequence[1] = 0;
+      leader_sequence[2] = 0;
+      leader_sequence[3] = 0;
+      leader_sequence[4] = 0;
+      return false;
+    }
+    if (leading && timer_elapsed(leader_time) < LEADER_TIMEOUT) {
+      leader_sequence[leader_sequence_size] = keycode;
+      leader_sequence_size++;
+      return false;
+    }
+  }
+  return true;
+}
\ No newline at end of file
diff --git a/quantum/process_keycode/process_leader.h b/quantum/process_keycode/process_leader.h
new file mode 100644
index 0000000000..c83db8abbd
--- /dev/null
+++ b/quantum/process_keycode/process_leader.h
@@ -0,0 +1,23 @@
+#ifndef PROCESS_LEADER_H
+#define PROCESS_LEADER_H
+
+#include "quantum.h"
+
+bool process_leader(uint16_t keycode, keyrecord_t *record);
+
+void leader_start(void);
+void leader_end(void);
+
+#ifndef LEADER_TIMEOUT
+  #define LEADER_TIMEOUT 200
+#endif
+#define SEQ_ONE_KEY(key) if (leader_sequence[0] == (key) && leader_sequence[1] == 0 && leader_sequence[2] == 0 && leader_sequence[3] == 0 && leader_sequence[4] == 0)
+#define SEQ_TWO_KEYS(key1, key2) if (leader_sequence[0] == (key1) && leader_sequence[1] == (key2) && leader_sequence[2] == 0 && leader_sequence[3] == 0 && leader_sequence[4] == 0)
+#define SEQ_THREE_KEYS(key1, key2, key3) if (leader_sequence[0] == (key1) && leader_sequence[1] == (key2) && leader_sequence[2] == (key3) && leader_sequence[3] == 0 && leader_sequence[4] == 0)
+#define SEQ_FOUR_KEYS(key1, key2, key3, key4) if (leader_sequence[0] == (key1) && leader_sequence[1] == (key2) && leader_sequence[2] == (key3) && leader_sequence[3] == (key4) && leader_sequence[4] == 0)
+#define SEQ_FIVE_KEYS(key1, key2, key3, key4, key5) if (leader_sequence[0] == (key1) && leader_sequence[1] == (key2) && leader_sequence[2] == (key3) && leader_sequence[3] == (key4) && leader_sequence[4] == (key5))
+
+#define LEADER_EXTERNS() extern bool leading; extern uint16_t leader_time; extern uint16_t leader_sequence[5]; extern uint8_t leader_sequence_size
+#define LEADER_DICTIONARY() if (leading && timer_elapsed(leader_time) > LEADER_TIMEOUT)
+
+#endif
\ No newline at end of file
diff --git a/quantum/process_keycode/process_midi.c b/quantum/process_keycode/process_midi.c
new file mode 100644
index 0000000000..d6ab9c6264
--- /dev/null
+++ b/quantum/process_keycode/process_midi.c
@@ -0,0 +1,66 @@
+#include "process_midi.h"
+
+bool midi_activated = false;
+uint8_t starting_note = 0x0C;
+int offset = 7;
+
+bool process_midi(uint16_t keycode, keyrecord_t *record) {
+    if (keycode == MI_ON && record->event.pressed) {
+      midi_activated = true;
+      music_scale_user();
+      return false;
+    }
+
+    if (keycode == MI_OFF && record->event.pressed) {
+      midi_activated = false;
+      midi_send_cc(&midi_device, 0, 0x7B, 0);
+      return false;
+    }
+
+    if (midi_activated) {
+      if (record->event.key.col == (MATRIX_COLS - 1) && record->event.key.row == (MATRIX_ROWS - 1)) {
+          if (record->event.pressed) {
+              starting_note++; // Change key
+              midi_send_cc(&midi_device, 0, 0x7B, 0);
+          }
+          return false;
+      }
+      if (record->event.key.col == (MATRIX_COLS - 2) && record->event.key.row == (MATRIX_ROWS - 1)) {
+          if (record->event.pressed) {
+              starting_note--; // Change key
+              midi_send_cc(&midi_device, 0, 0x7B, 0);
+          }
+          return false;
+      }
+      if (record->event.key.col == (MATRIX_COLS - 3) && record->event.key.row == (MATRIX_ROWS - 1) && record->event.pressed) {
+          offset++; // Change scale
+          midi_send_cc(&midi_device, 0, 0x7B, 0);
+          return false;
+      }
+      if (record->event.key.col == (MATRIX_COLS - 4) && record->event.key.row == (MATRIX_ROWS - 1) && record->event.pressed) {
+          offset--; // Change scale
+          midi_send_cc(&midi_device, 0, 0x7B, 0);
+          return false;
+      }
+      // basic
+      // uint8_t note = (starting_note + SCALE[record->event.key.col + offset])+12*(MATRIX_ROWS - record->event.key.row);
+      // advanced
+      // uint8_t note = (starting_note + record->event.key.col + offset)+12*(MATRIX_ROWS - record->event.key.row);
+      // guitar
+      uint8_t note = (starting_note + record->event.key.col + offset)+5*(MATRIX_ROWS - record->event.key.row);
+      // violin
+      // uint8_t note = (starting_note + record->event.key.col + offset)+7*(MATRIX_ROWS - record->event.key.row);
+
+      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, note, 127);
+      } else {
+        // midi_send_noteoff(&midi_device, record->event.key.row, starting_note + SCALE[record->event.key.col], 127);
+        midi_send_noteoff(&midi_device, 0, note, 127);
+      }
+
+      if (keycode < 0xFF) // ignores all normal keycodes, but lets RAISE, LOWER, etc through
+        return false;
+    }
+  return true;
+}
\ No newline at end of file
diff --git a/quantum/process_keycode/process_midi.h b/quantum/process_keycode/process_midi.h
new file mode 100644
index 0000000000..acd4fc1b16
--- /dev/null
+++ b/quantum/process_keycode/process_midi.h
@@ -0,0 +1,207 @@
+#ifndef PROCESS_MIDI_H
+#define PROCESS_MIDI_H
+
+#include "quantum.h"
+
+bool process_midi(uint16_t keycode, keyrecord_t *record);
+
+#define MIDI(n) ((n) | 0x6000)
+#define MIDI12 0x6000, 0x6000, 0x6000, 0x6000, 0x6000, 0x6000, 0x6000, 0x6000, 0x6000, 0x6000, 0x6000, 0x6000
+
+#define CHNL(note, channel) (note + (channel << 8))
+
+#define SCALE (int8_t []){ 0 + (12*0), 2 + (12*0), 4 + (12*0), 5 + (12*0), 7 + (12*0), 9 + (12*0), 11 + (12*0), \
+                           0 + (12*1), 2 + (12*1), 4 + (12*1), 5 + (12*1), 7 + (12*1), 9 + (12*1), 11 + (12*1), \
+                           0 + (12*2), 2 + (12*2), 4 + (12*2), 5 + (12*2), 7 + (12*2), 9 + (12*2), 11 + (12*2), \
+                           0 + (12*3), 2 + (12*3), 4 + (12*3), 5 + (12*3), 7 + (12*3), 9 + (12*3), 11 + (12*3), \
+                           0 + (12*4), 2 + (12*4), 4 + (12*4), 5 + (12*4), 7 + (12*4), 9 + (12*4), 11 + (12*4), }
+
+#define N_CN1  (0x600C + (12 * -1) + 0 )
+#define N_CN1S (0x600C + (12 * -1) + 1 )
+#define N_DN1F (0x600C + (12 * -1) + 1 )
+#define N_DN1  (0x600C + (12 * -1) + 2 )
+#define N_DN1S (0x600C + (12 * -1) + 3 )
+#define N_EN1F (0x600C + (12 * -1) + 3 )
+#define N_EN1  (0x600C + (12 * -1) + 4 )
+#define N_FN1  (0x600C + (12 * -1) + 5 )
+#define N_FN1S (0x600C + (12 * -1) + 6 )
+#define N_GN1F (0x600C + (12 * -1) + 6 )
+#define N_GN1  (0x600C + (12 * -1) + 7 )
+#define N_GN1S (0x600C + (12 * -1) + 8 )
+#define N_AN1F (0x600C + (12 * -1) + 8 )
+#define N_AN1  (0x600C + (12 * -1) + 9 )
+#define N_AN1S (0x600C + (12 * -1) + 10)
+#define N_BN1F (0x600C + (12 * -1) + 10)
+#define N_BN1  (0x600C + (12 * -1) + 11)
+#define N_C0   (0x600C + (12 *  0) + 0 )
+#define N_C0S  (0x600C + (12 *  0) + 1 )
+#define N_D0F  (0x600C + (12 *  0) + 1 )
+#define N_D0   (0x600C + (12 *  0) + 2 )
+#define N_D0S  (0x600C + (12 *  0) + 3 )
+#define N_E0F  (0x600C + (12 *  0) + 3 )
+#define N_E0   (0x600C + (12 *  0) + 4 )
+#define N_F0   (0x600C + (12 *  0) + 5 )
+#define N_F0S  (0x600C + (12 *  0) + 6 )
+#define N_G0F  (0x600C + (12 *  0) + 6 )
+#define N_G0   (0x600C + (12 *  0) + 7 )
+#define N_G0S  (0x600C + (12 *  0) + 8 )
+#define N_A0F  (0x600C + (12 *  0) + 8 )
+#define N_A0   (0x600C + (12 *  0) + 9 )
+#define N_A0S  (0x600C + (12 *  0) + 10)
+#define N_B0F  (0x600C + (12 *  0) + 10)
+#define N_B0   (0x600C + (12 *  0) + 11)
+#define N_C1   (0x600C + (12 *  1) + 0 )
+#define N_C1S  (0x600C + (12 *  1) + 1 )
+#define N_D1F  (0x600C + (12 *  1) + 1 )
+#define N_D1   (0x600C + (12 *  1) + 2 )
+#define N_D1S  (0x600C + (12 *  1) + 3 )
+#define N_E1F  (0x600C + (12 *  1) + 3 )
+#define N_E1   (0x600C + (12 *  1) + 4 )
+#define N_F1   (0x600C + (12 *  1) + 5 )
+#define N_F1S  (0x600C + (12 *  1) + 6 )
+#define N_G1F  (0x600C + (12 *  1) + 6 )
+#define N_G1   (0x600C + (12 *  1) + 7 )
+#define N_G1S  (0x600C + (12 *  1) + 8 )
+#define N_A1F  (0x600C + (12 *  1) + 8 )
+#define N_A1   (0x600C + (12 *  1) + 9 )
+#define N_A1S  (0x600C + (12 *  1) + 10)
+#define N_B1F  (0x600C + (12 *  1) + 10)
+#define N_B1   (0x600C + (12 *  1) + 11)
+#define N_C2   (0x600C + (12 *  2) + 0 )
+#define N_C2S  (0x600C + (12 *  2) + 1 )
+#define N_D2F  (0x600C + (12 *  2) + 1 )
+#define N_D2   (0x600C + (12 *  2) + 2 )
+#define N_D2S  (0x600C + (12 *  2) + 3 )
+#define N_E2F  (0x600C + (12 *  2) + 3 )
+#define N_E2   (0x600C + (12 *  2) + 4 )
+#define N_F2   (0x600C + (12 *  2) + 5 )
+#define N_F2S  (0x600C + (12 *  2) + 6 )
+#define N_G2F  (0x600C + (12 *  2) + 6 )
+#define N_G2   (0x600C + (12 *  2) + 7 )
+#define N_G2S  (0x600C + (12 *  2) + 8 )
+#define N_A2F  (0x600C + (12 *  2) + 8 )
+#define N_A2   (0x600C + (12 *  2) + 9 )
+#define N_A2S  (0x600C + (12 *  2) + 10)
+#define N_B2F  (0x600C + (12 *  2) + 10)
+#define N_B2   (0x600C + (12 *  2) + 11)
+#define N_C3   (0x600C + (12 *  3) + 0 )
+#define N_C3S  (0x600C + (12 *  3) + 1 )
+#define N_D3F  (0x600C + (12 *  3) + 1 )
+#define N_D3   (0x600C + (12 *  3) + 2 )
+#define N_D3S  (0x600C + (12 *  3) + 3 )
+#define N_E3F  (0x600C + (12 *  3) + 3 )
+#define N_E3   (0x600C + (12 *  3) + 4 )
+#define N_F3   (0x600C + (12 *  3) + 5 )
+#define N_F3S  (0x600C + (12 *  3) + 6 )
+#define N_G3F  (0x600C + (12 *  3) + 6 )
+#define N_G3   (0x600C + (12 *  3) + 7 )
+#define N_G3S  (0x600C + (12 *  3) + 8 )
+#define N_A3F  (0x600C + (12 *  3) + 8 )
+#define N_A3   (0x600C + (12 *  3) + 9 )
+#define N_A3S  (0x600C + (12 *  3) + 10)
+#define N_B3F  (0x600C + (12 *  3) + 10)
+#define N_B3   (0x600C + (12 *  3) + 11)
+#define N_C4   (0x600C + (12 *  4) + 0 )
+#define N_C4S  (0x600C + (12 *  4) + 1 )
+#define N_D4F  (0x600C + (12 *  4) + 1 )
+#define N_D4   (0x600C + (12 *  4) + 2 )
+#define N_D4S  (0x600C + (12 *  4) + 3 )
+#define N_E4F  (0x600C + (12 *  4) + 3 )
+#define N_E4   (0x600C + (12 *  4) + 4 )
+#define N_F4   (0x600C + (12 *  4) + 5 )
+#define N_F4S  (0x600C + (12 *  4) + 6 )
+#define N_G4F  (0x600C + (12 *  4) + 6 )
+#define N_G4   (0x600C + (12 *  4) + 7 )
+#define N_G4S  (0x600C + (12 *  4) + 8 )
+#define N_A4F  (0x600C + (12 *  4) + 8 )
+#define N_A4   (0x600C + (12 *  4) + 9 )
+#define N_A4S  (0x600C + (12 *  4) + 10)
+#define N_B4F  (0x600C + (12 *  4) + 10)
+#define N_B4   (0x600C + (12 *  4) + 11)
+#define N_C5   (0x600C + (12 *  5) + 0 )
+#define N_C5S  (0x600C + (12 *  5) + 1 )
+#define N_D5F  (0x600C + (12 *  5) + 1 )
+#define N_D5   (0x600C + (12 *  5) + 2 )
+#define N_D5S  (0x600C + (12 *  5) + 3 )
+#define N_E5F  (0x600C + (12 *  5) + 3 )
+#define N_E5   (0x600C + (12 *  5) + 4 )
+#define N_F5   (0x600C + (12 *  5) + 5 )
+#define N_F5S  (0x600C + (12 *  5) + 6 )
+#define N_G5F  (0x600C + (12 *  5) + 6 )
+#define N_G5   (0x600C + (12 *  5) + 7 )
+#define N_G5S  (0x600C + (12 *  5) + 8 )
+#define N_A5F  (0x600C + (12 *  5) + 8 )
+#define N_A5   (0x600C + (12 *  5) + 9 )
+#define N_A5S  (0x600C + (12 *  5) + 10)
+#define N_B5F  (0x600C + (12 *  5) + 10)
+#define N_B5   (0x600C + (12 *  5) + 11)
+#define N_C6   (0x600C + (12 *  6) + 0 )
+#define N_C6S  (0x600C + (12 *  6) + 1 )
+#define N_D6F  (0x600C + (12 *  6) + 1 )
+#define N_D6   (0x600C + (12 *  6) + 2 )
+#define N_D6S  (0x600C + (12 *  6) + 3 )
+#define N_E6F  (0x600C + (12 *  6) + 3 )
+#define N_E6   (0x600C + (12 *  6) + 4 )
+#define N_F6   (0x600C + (12 *  6) + 5 )
+#define N_F6S  (0x600C + (12 *  6) + 6 )
+#define N_G6F  (0x600C + (12 *  6) + 6 )
+#define N_G6   (0x600C + (12 *  6) + 7 )
+#define N_G6S  (0x600C + (12 *  6) + 8 )
+#define N_A6F  (0x600C + (12 *  6) + 8 )
+#define N_A6   (0x600C + (12 *  6) + 9 )
+#define N_A6S  (0x600C + (12 *  6) + 10)
+#define N_B6F  (0x600C + (12 *  6) + 10)
+#define N_B6   (0x600C + (12 *  6) + 11)
+#define N_C7   (0x600C + (12 *  7) + 0 )
+#define N_C7S  (0x600C + (12 *  7) + 1 )
+#define N_D7F  (0x600C + (12 *  7) + 1 )
+#define N_D7   (0x600C + (12 *  7) + 2 )
+#define N_D7S  (0x600C + (12 *  7) + 3 )
+#define N_E7F  (0x600C + (12 *  7) + 3 )
+#define N_E7   (0x600C + (12 *  7) + 4 )
+#define N_F7   (0x600C + (12 *  7) + 5 )
+#define N_F7S  (0x600C + (12 *  7) + 6 )
+#define N_G7F  (0x600C + (12 *  7) + 6 )
+#define N_G7   (0x600C + (12 *  7) + 7 )
+#define N_G7S  (0x600C + (12 *  7) + 8 )
+#define N_A7F  (0x600C + (12 *  7) + 8 )
+#define N_A7   (0x600C + (12 *  7) + 9 )
+#define N_A7S  (0x600C + (12 *  7) + 10)
+#define N_B7F  (0x600C + (12 *  7) + 10)
+#define N_B7   (0x600C + (12 *  7) + 11)
+#define N_C8   (0x600C + (12 *  8) + 0 )
+#define N_C8S  (0x600C + (12 *  8) + 1 )
+#define N_D8F  (0x600C + (12 *  8) + 1 )
+#define N_D8   (0x600C + (12 *  8) + 2 )
+#define N_D8S  (0x600C + (12 *  8) + 3 )
+#define N_E8F  (0x600C + (12 *  8) + 3 )
+#define N_E8   (0x600C + (12 *  8) + 4 )
+#define N_F8   (0x600C + (12 *  8) + 5 )
+#define N_F8S  (0x600C + (12 *  8) + 6 )
+#define N_G8F  (0x600C + (12 *  8) + 6 )
+#define N_G8   (0x600C + (12 *  8) + 7 )
+#define N_G8S  (0x600C + (12 *  8) + 8 )
+#define N_A8F  (0x600C + (12 *  8) + 8 )
+#define N_A8   (0x600C + (12 *  8) + 9 )
+#define N_A8S  (0x600C + (12 *  8) + 10)
+#define N_B8F  (0x600C + (12 *  8) + 10)
+#define N_B8   (0x600C + (12 *  8) + 11)
+#define N_C8   (0x600C + (12 *  8) + 0 )
+#define N_C8S  (0x600C + (12 *  8) + 1 )
+#define N_D8F  (0x600C + (12 *  8) + 1 )
+#define N_D8   (0x600C + (12 *  8) + 2 )
+#define N_D8S  (0x600C + (12 *  8) + 3 )
+#define N_E8F  (0x600C + (12 *  8) + 3 )
+#define N_E8   (0x600C + (12 *  8) + 4 )
+#define N_F8   (0x600C + (12 *  8) + 5 )
+#define N_F8S  (0x600C + (12 *  8) + 6 )
+#define N_G8F  (0x600C + (12 *  8) + 6 )
+#define N_G8   (0x600C + (12 *  8) + 7 )
+#define N_G8S  (0x600C + (12 *  8) + 8 )
+#define N_A8F  (0x600C + (12 *  8) + 8 )
+#define N_A8   (0x600C + (12 *  8) + 9 )
+#define N_A8S  (0x600C + (12 *  8) + 10)
+#define N_B8F  (0x600C + (12 *  8) + 10)
+#define N_B8   (0x600C + (12 *  8) + 11)
+
+#endif
\ No newline at end of file
diff --git a/quantum/process_keycode/process_music.c b/quantum/process_keycode/process_music.c
new file mode 100644
index 0000000000..c8f3ddb900
--- /dev/null
+++ b/quantum/process_keycode/process_music.c
@@ -0,0 +1,171 @@
+#include "process_music.h"
+
+bool music_activated = false;
+uint8_t starting_note = 0x0C;
+int offset = 7;
+
+// music sequencer
+static bool music_sequence_recording = false;
+static bool music_sequence_playing = false;
+static float music_sequence[16] = {0};
+static uint8_t music_sequence_count = 0;
+static uint8_t music_sequence_position = 0;
+
+static uint16_t music_sequence_timer = 0;
+static uint16_t music_sequence_interval = 100;
+
+bool process_music(uint16_t keycode, keyrecord_t *record) {
+
+    if (keycode == AU_ON && record->event.pressed) {
+      audio_on();
+      return false;
+    }
+
+    if (keycode == AU_OFF && record->event.pressed) {
+      audio_off();
+      return false;
+    }
+
+    if (keycode == AU_TOG && record->event.pressed) {
+        if (is_audio_on())
+        {
+            audio_off();
+        }
+        else
+        {
+            audio_on();
+        }
+      return false;
+    }
+
+    if (keycode == MU_ON && record->event.pressed) {
+        music_on();
+        return false;
+    }
+
+    if (keycode == MU_OFF && record->event.pressed) {
+        music_off();
+        return false;
+    }
+
+    if (keycode == MU_TOG && record->event.pressed) {
+        if (music_activated)
+        {
+            music_off();
+        }
+        else
+        {
+            music_on();
+        }
+        return false;
+    }
+
+    if (keycode == MUV_IN && record->event.pressed) {
+        voice_iterate();
+        music_scale_user();
+        return false;
+    }
+
+    if (keycode == MUV_DE && record->event.pressed) {
+        voice_deiterate();
+        music_scale_user();
+        return false;
+    }
+
+    if (music_activated) {
+
+      if (keycode == KC_LCTL && record->event.pressed) { // Start recording
+        stop_all_notes();
+        music_sequence_recording = true;
+        music_sequence_playing = false;
+        music_sequence_count = 0;
+        return false;
+      }
+
+      if (keycode == KC_LALT && record->event.pressed) { // Stop recording/playing
+        stop_all_notes();
+        music_sequence_recording = false;
+        music_sequence_playing = false;
+        return false;
+      }
+
+      if (keycode == KC_LGUI && record->event.pressed) { // Start playing
+        stop_all_notes();
+        music_sequence_recording = false;
+        music_sequence_playing = true;
+        music_sequence_position = 0;
+        music_sequence_timer = 0;
+        return false;
+      }
+
+      if (keycode == KC_UP) {
+        if (record->event.pressed)
+            music_sequence_interval-=10;
+        return false;
+      }
+
+      if (keycode == KC_DOWN) {
+        if (record->event.pressed)
+            music_sequence_interval+=10;
+        return false;
+      }
+
+      float freq = ((float)220.0)*pow(2.0, -5.0)*pow(2.0,(starting_note + SCALE[record->event.key.col + offset])/12.0+(MATRIX_ROWS - record->event.key.row));
+      if (record->event.pressed) {
+        play_note(freq, 0xF);
+        if (music_sequence_recording) {
+          music_sequence[music_sequence_count] = freq;
+          music_sequence_count++;
+        }
+      } else {
+        stop_note(freq);
+      }
+
+      if (keycode < 0xFF) // ignores all normal keycodes, but lets RAISE, LOWER, etc through
+        return false;
+    }
+  return true;
+}
+
+bool is_music_on(void) {
+    return (music_activated != 0);
+}
+
+void music_toggle(void) {
+    if (!music_activated) {
+        music_on();
+    } else {
+        music_off();
+    }
+}
+
+void music_on(void) {
+    music_activated = 1;
+    music_on_user();
+}
+
+void music_off(void) {
+    music_activated = 0;
+    stop_all_notes();
+}
+
+
+__attribute__ ((weak))
+void music_on_user() {}
+
+__attribute__ ((weak))
+void audio_on_user() {}
+
+__attribute__ ((weak))
+void music_scale_user() {}
+
+void matrix_scan_music(void) {
+  if (music_sequence_playing) {
+    if ((music_sequence_timer == 0) || (timer_elapsed(music_sequence_timer) > music_sequence_interval)) {
+      music_sequence_timer = timer_read();
+      stop_note(music_sequence[(music_sequence_position - 1 < 0)?(music_sequence_position - 1 + music_sequence_count):(music_sequence_position - 1)]);
+      play_note(music_sequence[music_sequence_position], 0xF);
+      music_sequence_position = (music_sequence_position + 1) % music_sequence_count;
+    }
+  }
+}
diff --git a/quantum/process_keycode/process_music.h b/quantum/process_keycode/process_music.h
new file mode 100644
index 0000000000..318b3e3875
--- /dev/null
+++ b/quantum/process_keycode/process_music.h
@@ -0,0 +1,27 @@
+#ifndef PROCESS_MUSIC_H
+#define PROCESS_MUSIC_H
+
+#include "quantum.h"
+
+bool process_music(uint16_t keycode, keyrecord_t *record);
+
+bool is_music_on(void);
+void music_toggle(void);
+void music_on(void);
+void music_off(void);
+
+void audio_on_user(void);
+void music_on_user(void);
+void music_scale_user(void);
+
+void matrix_scan_music(void);
+
+#ifndef SCALE
+#define SCALE (int8_t []){ 0 + (12*0), 2 + (12*0), 4 + (12*0), 5 + (12*0), 7 + (12*0), 9 + (12*0), 11 + (12*0), \
+                           0 + (12*1), 2 + (12*1), 4 + (12*1), 5 + (12*1), 7 + (12*1), 9 + (12*1), 11 + (12*1), \
+                           0 + (12*2), 2 + (12*2), 4 + (12*2), 5 + (12*2), 7 + (12*2), 9 + (12*2), 11 + (12*2), \
+                           0 + (12*3), 2 + (12*3), 4 + (12*3), 5 + (12*3), 7 + (12*3), 9 + (12*3), 11 + (12*3), \
+                           0 + (12*4), 2 + (12*4), 4 + (12*4), 5 + (12*4), 7 + (12*4), 9 + (12*4), 11 + (12*4), }
+#endif
+
+#endif
\ No newline at end of file
diff --git a/quantum/process_keycode/process_tap_dance.c b/quantum/process_keycode/process_tap_dance.c
new file mode 100644
index 0000000000..9b172e1b6c
--- /dev/null
+++ b/quantum/process_keycode/process_tap_dance.c
@@ -0,0 +1,90 @@
+#include "quantum.h"
+
+static qk_tap_dance_state_t qk_tap_dance_state;
+
+static void _process_tap_dance_action_pair (qk_tap_dance_state_t *state,
+                                            uint16_t kc1, uint16_t kc2) {
+  uint16_t kc;
+
+  if (state->count == 0)
+    return;
+
+  kc = (state->count == 1) ? kc1 : kc2;
+
+  register_code (kc);
+  unregister_code (kc);
+
+  if (state->count >= 2) {
+    reset_tap_dance (state);
+  }
+}
+
+static void _process_tap_dance_action_fn (qk_tap_dance_state_t *state,
+                                          qk_tap_dance_user_fn_t fn)
+{
+  fn(state);
+}
+
+void process_tap_dance_action (uint16_t keycode)
+{
+  uint16_t idx = keycode - QK_TAP_DANCE;
+  qk_tap_dance_action_t action;
+
+  action = tap_dance_actions[idx];
+
+  switch (action.type) {
+  case QK_TAP_DANCE_TYPE_PAIR:
+    _process_tap_dance_action_pair (&qk_tap_dance_state,
+                                    action.pair.kc1, action.pair.kc2);
+    break;
+  case QK_TAP_DANCE_TYPE_FN:
+    _process_tap_dance_action_fn (&qk_tap_dance_state, action.fn);
+    break;
+
+  default:
+    break;
+  }
+}
+
+bool process_tap_dance(uint16_t keycode, keyrecord_t *record) {
+  bool r = true;
+
+  switch(keycode) {
+  case QK_TAP_DANCE ... QK_TAP_DANCE_MAX:
+    if (qk_tap_dance_state.keycode && qk_tap_dance_state.keycode != keycode) {
+      process_tap_dance_action (qk_tap_dance_state.keycode);
+    } else {
+      r = false;
+    }
+
+    if (record->event.pressed) {
+      qk_tap_dance_state.keycode = keycode;
+      qk_tap_dance_state.timer = timer_read ();
+      qk_tap_dance_state.count++;
+    }
+    break;
+
+  default:
+    if (qk_tap_dance_state.keycode) {
+      process_tap_dance_action (qk_tap_dance_state.keycode);
+
+      reset_tap_dance (&qk_tap_dance_state);
+    }
+    break;
+  }
+
+  return r;
+}
+
+void matrix_scan_tap_dance () {
+  if (qk_tap_dance_state.keycode && timer_elapsed (qk_tap_dance_state.timer) > TAPPING_TERM) {
+    process_tap_dance_action (qk_tap_dance_state.keycode);
+
+    reset_tap_dance (&qk_tap_dance_state);
+  }
+}
+
+void reset_tap_dance (qk_tap_dance_state_t *state) {
+  state->keycode = 0;
+  state->count = 0;
+}
diff --git a/quantum/process_keycode/process_tap_dance.h b/quantum/process_keycode/process_tap_dance.h
new file mode 100644
index 0000000000..b9d7c7fcf4
--- /dev/null
+++ b/quantum/process_keycode/process_tap_dance.h
@@ -0,0 +1,62 @@
+#ifndef PROCESS_TAP_DANCE_H
+#define PROCESS_TAP_DANCE_H
+
+#ifdef TAP_DANCE_ENABLE
+
+#include <stdbool.h>
+#include <inttypes.h>
+
+typedef struct
+{
+  uint8_t count;
+  uint16_t keycode;
+  uint16_t timer;
+} qk_tap_dance_state_t;
+
+#define TD(n) (QK_TAP_DANCE + n)
+
+typedef enum
+{
+  QK_TAP_DANCE_TYPE_PAIR,
+  QK_TAP_DANCE_TYPE_FN,
+} qk_tap_dance_type_t;
+
+typedef void (*qk_tap_dance_user_fn_t) (qk_tap_dance_state_t *state);
+
+typedef struct
+{
+  qk_tap_dance_type_t type;
+  union {
+    struct {
+      uint16_t kc1;
+      uint16_t kc2;
+    } pair;
+    qk_tap_dance_user_fn_t fn;
+  };
+} qk_tap_dance_action_t;
+
+#define ACTION_TAP_DANCE_DOUBLE(kc1, kc2) { \
+    .type = QK_TAP_DANCE_TYPE_PAIR,         \
+    .pair = { kc1, kc2 }                    \
+  }
+
+#define ACTION_TAP_DANCE_FN(user_fn) { \
+    .type = QK_TAP_DANCE_TYPE_FN, \
+    .fn = user_fn                 \
+  }
+
+extern const qk_tap_dance_action_t tap_dance_actions[];
+
+/* To be used internally */
+
+bool process_tap_dance(uint16_t keycode, keyrecord_t *record);
+void matrix_scan_tap_dance (void);
+void reset_tap_dance (qk_tap_dance_state_t *state);
+
+#else
+
+#define TD(n) KC_NO
+
+#endif
+
+#endif
diff --git a/quantum/process_keycode/process_unicode.c b/quantum/process_keycode/process_unicode.c
new file mode 100644
index 0000000000..ad5d7f86b7
--- /dev/null
+++ b/quantum/process_keycode/process_unicode.c
@@ -0,0 +1,57 @@
+#include "process_unicode.h"
+
+static uint8_t input_mode;
+
+uint16_t hex_to_keycode(uint8_t hex)
+{
+  if (hex == 0x0) {
+    return KC_0;
+  } else if (hex < 0xA) {
+    return KC_1 + (hex - 0x1);
+  } else {
+    return KC_A + (hex - 0xA);
+  }
+}
+
+void set_unicode_mode(uint8_t os_target)
+{
+  input_mode = os_target;
+}
+
+bool process_unicode(uint16_t keycode, keyrecord_t *record) {
+  if (keycode > QK_UNICODE && record->event.pressed) {
+    uint16_t unicode = keycode & 0x7FFF;
+    switch(input_mode) {
+      case UC_OSX:
+        register_code(KC_LALT);
+        break;
+      case UC_LNX:
+        register_code(KC_LCTL);
+        register_code(KC_LSFT);
+        register_code(KC_U);
+        unregister_code(KC_U);
+        break;
+      case UC_WIN:
+        register_code(KC_LALT);
+        register_code(KC_PPLS);
+        unregister_code(KC_PPLS);
+        break;
+    }
+    for(int i = 3; i >= 0; i--) {
+        uint8_t digit = ((unicode >> (i*4)) & 0xF);
+        register_code(hex_to_keycode(digit));
+        unregister_code(hex_to_keycode(digit));
+    }
+    switch(input_mode) {
+      case UC_OSX:
+      case UC_WIN:
+        unregister_code(KC_LALT);
+        break;
+      case UC_LNX:
+        unregister_code(KC_LCTL);
+        unregister_code(KC_LSFT);
+        break;
+    }
+  }
+  return true;
+}
\ No newline at end of file
diff --git a/quantum/process_keycode/process_unicode.h b/quantum/process_keycode/process_unicode.h
new file mode 100644
index 0000000000..ca17f8f669
--- /dev/null
+++ b/quantum/process_keycode/process_unicode.h
@@ -0,0 +1,122 @@
+#ifndef PROCESS_UNICODE_H
+#define PROCESS_UNICODE_H
+
+#include "quantum.h"
+
+#define UC_OSX 0
+#define UC_LNX 1
+#define UC_WIN 2
+#define UC_BSD 3
+
+void set_unicode_input_mode(uint8_t os_target);
+
+bool process_unicode(uint16_t keycode, keyrecord_t *record);
+
+#define UC_BSPC	UC(0x0008)
+
+#define UC_SPC	UC(0x0020)
+
+#define UC_EXLM	UC(0x0021)
+#define UC_DQUT	UC(0x0022)
+#define UC_HASH	UC(0x0023)
+#define UC_DLR	UC(0x0024)
+#define UC_PERC	UC(0x0025)
+#define UC_AMPR	UC(0x0026)
+#define UC_QUOT	UC(0x0027)
+#define UC_LPRN	UC(0x0028)
+#define UC_RPRN	UC(0x0029)
+#define UC_ASTR	UC(0x002A)
+#define UC_PLUS	UC(0x002B)
+#define UC_COMM	UC(0x002C)
+#define UC_DASH	UC(0x002D)
+#define UC_DOT	UC(0x002E)
+#define UC_SLSH	UC(0x002F)
+
+#define UC_0	UC(0x0030)
+#define UC_1	UC(0x0031)
+#define UC_2	UC(0x0032)
+#define UC_3	UC(0x0033)
+#define UC_4	UC(0x0034)
+#define UC_5	UC(0x0035)
+#define UC_6	UC(0x0036)
+#define UC_7	UC(0x0037)
+#define UC_8	UC(0x0038)
+#define UC_9	UC(0x0039)
+
+#define UC_COLN UC(0x003A)
+#define UC_SCLN UC(0x003B)
+#define UC_LT	UC(0x003C)
+#define UC_EQL	UC(0x003D)
+#define UC_GT	UC(0x003E)
+#define UC_QUES	UC(0x003F)
+#define UC_AT 	UC(0x0040)
+
+#define UC_A 	UC(0x0041)
+#define UC_B 	UC(0x0042)
+#define UC_C 	UC(0x0043)
+#define UC_D 	UC(0x0044)
+#define UC_E 	UC(0x0045)
+#define UC_F 	UC(0x0046)
+#define UC_G 	UC(0x0047)
+#define UC_H 	UC(0x0048)
+#define UC_I 	UC(0x0049)
+#define UC_J 	UC(0x004A)
+#define UC_K 	UC(0x004B)
+#define UC_L 	UC(0x004C)
+#define UC_M 	UC(0x004D)
+#define UC_N 	UC(0x004E)
+#define UC_O 	UC(0x004F)
+#define UC_P 	UC(0x0050)
+#define UC_Q 	UC(0x0051)
+#define UC_R 	UC(0x0052)
+#define UC_S 	UC(0x0053)
+#define UC_T 	UC(0x0054)
+#define UC_U 	UC(0x0055)
+#define UC_V 	UC(0x0056)
+#define UC_W 	UC(0x0057)
+#define UC_X 	UC(0x0058)
+#define UC_Y 	UC(0x0059)
+#define UC_Z 	UC(0x005A)
+
+#define UC_LBRC	UC(0x005B)
+#define UC_BSLS	UC(0x005C)
+#define UC_RBRC	UC(0x005D)
+#define UC_CIRM	UC(0x005E)
+#define UC_UNDR	UC(0x005F)
+
+#define UC_GRV 	UC(0x0060)
+
+#define UC_a 	UC(0x0061)
+#define UC_b 	UC(0x0062)
+#define UC_c 	UC(0x0063)
+#define UC_d 	UC(0x0064)
+#define UC_e 	UC(0x0065)
+#define UC_f 	UC(0x0066)
+#define UC_g 	UC(0x0067)
+#define UC_h 	UC(0x0068)
+#define UC_i 	UC(0x0069)
+#define UC_j 	UC(0x006A)
+#define UC_k 	UC(0x006B)
+#define UC_l 	UC(0x006C)
+#define UC_m 	UC(0x006D)
+#define UC_n 	UC(0x006E)
+#define UC_o 	UC(0x006F)
+#define UC_p 	UC(0x0070)
+#define UC_q 	UC(0x0071)
+#define UC_r 	UC(0x0072)
+#define UC_s 	UC(0x0073)
+#define UC_t 	UC(0x0074)
+#define UC_u 	UC(0x0075)
+#define UC_v 	UC(0x0076)
+#define UC_w 	UC(0x0077)
+#define UC_x 	UC(0x0078)
+#define UC_y 	UC(0x0079)
+#define UC_z 	UC(0x007A)
+
+#define UC_LCBR	UC(0x007B)
+#define UC_PIPE	UC(0x007C)
+#define UC_RCBR	UC(0x007D)
+#define UC_TILD	UC(0x007E)
+#define UC_DEL	UC(0x007F)
+
+#endif
\ No newline at end of file