summaryrefslogtreecommitdiffstats
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 000000000..d7814629f
--- /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 000000000..49c97db3b
--- /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 000000000..e53d221e7
--- /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 000000000..c83db8abb
--- /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 000000000..d6ab9c626
--- /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 000000000..acd4fc1b1
--- /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 000000000..c8f3ddb90
--- /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 000000000..318b3e387
--- /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 000000000..9b172e1b6
--- /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 000000000..b9d7c7fcf
--- /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 000000000..ad5d7f86b
--- /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 000000000..ca17f8f66
--- /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