summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.travis.yml2
-rw-r--r--Makefile37
-rw-r--r--keyboards/alps64/matrix.c2
-rw-r--r--keyboards/clueboard/Makefile39
-rw-r--r--keyboards/ergodox_ez/matrix.c3
-rw-r--r--keyboards/hhkb/matrix.c11
-rw-r--r--keyboards/planck/rev3/config.h2
-rw-r--r--keyboards/sixkeyboard/matrix.c2
-rw-r--r--quantum/keymap.h2
-rw-r--r--quantum/keymap_midi.c109
-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.h (renamed from quantum/keymap_midi.h)23
-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.h (renamed from quantum/unicode.h)28
-rw-r--r--quantum/quantum.c425
-rw-r--r--quantum/quantum.h57
-rw-r--r--tmk_core/common.mk15
25 files changed, 759 insertions, 608 deletions
diff --git a/.travis.yml b/.travis.yml
index f5ae78c898..955f696794 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -10,7 +10,7 @@ env:
global:
- secure: vBTSL34BDPxDilKUuTXqU4CJ26Pv5hogD2nghatkxSQkI1/jbdnLj/DQdPUrMJFDIY6TK3AltsBx72MaMsLQ1JO/Ou24IeHINHXzUC1FlS9yQa48cpxnhX5kzXNyGs3oa0qaFbvnr7RgYRWtmD52n4bIZuSuW+xpBv05x2OCizdT2ZonH33nATaHGFasxROm4qYZ241VfzcUv766V6RVHgL4x9V08warugs+RENVkfzxxwhk3NmkrISabze0gSVJLHBPHxroZC6EUcf/ocobcuDrCwFqtEt90i7pNIAFUE7gZsN2uE75LmpzAWin21G7lLPcPL2k4FJVd8an1HiP2WmscJU6U89fOfMb2viObnKcCzebozBCmKGtHEuXZo9FcReOx49AnQSpmESJGs+q2dL/FApkTjQiyT4J6O5dJpoww0/r57Wx0cmmqjETKBb5rSgXM51Etk3wO09mvcPHsEwrT7qH8r9XWdyCDoEn7FCLX3/LYnf/D4SmZ633YPl5gv3v9XEwxR5+04akjgnvWDSNIaDbWBdxHNb7l4pMc+WR1bwCyMyA7KXj0RrftEGOrm9ZRLe6BkbT4cycA+j77nbPOMcyZChliV9pPQos+4TOJoTzcK2L8yWVoY409aDNVuAjdP6Yum0R2maBGl/etLmIMpJC35C5/lZ+dUNjJAM=
script:
-- make all-keyboards quick AUTOGEN=true
+- make all-keyboards-quick AUTOGEN=true
addons:
apt:
packages:
diff --git a/Makefile b/Makefile
index 72710c2d9c..5642aa2839 100644
--- a/Makefile
+++ b/Makefile
@@ -120,11 +120,15 @@ else
endif
-
ifneq ("$(wildcard $(KEYMAP_PATH)/config.h)","")
CONFIG_H = $(KEYMAP_PATH)/config.h
else
CONFIG_H = $(KEYBOARD_PATH)/config.h
+ ifdef SUBPROJECT
+ ifneq ("$(wildcard $(SUBPROJECT_PATH)/$(SUBPROJECT).c)","")
+ CONFIG_H = $(SUBPROJECT_PATH)/config.h
+ endif
+ endif
endif
# # project specific files
@@ -132,7 +136,16 @@ SRC += $(KEYBOARD_FILE) \
$(KEYMAP_FILE) \
$(QUANTUM_DIR)/quantum.c \
$(QUANTUM_DIR)/keymap.c \
- $(QUANTUM_DIR)/keycode_config.c
+ $(QUANTUM_DIR)/keycode_config.c \
+ $(QUANTUM_DIR)/process_keycode/process_leader.c
+
+ifdef SUBPROJECT
+ SRC += $(SUBPROJECT_FILE)
+endif
+
+ifdef SUBPROJECT
+ SRC += $(SUBPROJECT_FILE)
+endif
ifdef SUBPROJECT
SRC += $(SUBPROJECT_FILE)
@@ -142,16 +155,33 @@ ifndef CUSTOM_MATRIX
SRC += $(QUANTUM_DIR)/matrix.c
endif
+ifeq ($(strip $(MIDI_ENABLE)), yes)
+ OPT_DEFS += -DMIDI_ENABLE
+ SRC += $(QUANTUM_DIR)/process_keycode/process_audio.c
+endif
+
ifeq ($(strip $(AUDIO_ENABLE)), yes)
+ OPT_DEFS += -DAUDIO_ENABLE
+ SRC += $(QUANTUM_DIR)/process_keycode/process_music.c
SRC += $(QUANTUM_DIR)/audio/audio.c
SRC += $(QUANTUM_DIR)/audio/voices.c
SRC += $(QUANTUM_DIR)/audio/luts.c
endif
+ifeq ($(strip $(UNICODE_ENABLE)), yes)
+ OPT_DEFS += -DUNICODE_ENABLE
+ SRC += $(QUANTUM_DIR)/process_keycode/process_unicode.c
+endif
+
ifeq ($(strip $(RGBLIGHT_ENABLE)), yes)
+ OPT_DEFS += -DRGBLIGHT_ENABLE
SRC += $(QUANTUM_DIR)/light_ws2812.c
SRC += $(QUANTUM_DIR)/rgblight.c
- OPT_DEFS += -DRGBLIGHT_ENABLE
+endif
+
+ifeq ($(strip $(TAP_DANCE_ENABLE)), yes)
+ OPT_DEFS += -DTAP_DANCE_ENABLE
+ SRC += $(QUANTUM_DIR)/process_keycode/process_tap_dance.c
endif
# Optimize size but this may cause error "relocation truncated to fit"
@@ -168,6 +198,7 @@ VPATH += $(TMK_PATH)
VPATH += $(QUANTUM_PATH)
VPATH += $(QUANTUM_PATH)/keymap_extras
VPATH += $(QUANTUM_PATH)/audio
+VPATH += $(QUANTUM_PATH)/process_keycode
include $(TMK_PATH)/protocol/lufa.mk
include $(TMK_PATH)/common.mk
diff --git a/keyboards/alps64/matrix.c b/keyboards/alps64/matrix.c
index 805999d4a1..b3508850de 100644
--- a/keyboards/alps64/matrix.c
+++ b/keyboards/alps64/matrix.c
@@ -100,6 +100,8 @@ uint8_t matrix_scan(void)
}
}
+ matrix_scan_quantum();
+
return 1;
}
diff --git a/keyboards/clueboard/Makefile b/keyboards/clueboard/Makefile
index d6f4bfcae6..ccc01ea9a7 100644
--- a/keyboards/clueboard/Makefile
+++ b/keyboards/clueboard/Makefile
@@ -1,3 +1,42 @@
+#----------------------------------------------------------------------------
+# On command line:
+#
+# make all = Make software.
+#
+# make clean = Clean out built project files.
+#
+# make coff = Convert ELF to AVR COFF.
+#
+# make extcoff = Convert ELF to AVR Extended COFF.
+#
+# make program = Download the hex file to the device.
+# Please customize your programmer settings(PROGRAM_CMD)
+#
+# make teensy = Download the hex file to the device, using teensy_loader_cli.
+# (must have teensy_loader_cli installed).
+#
+# make dfu = Download the hex file to the device, using dfu-programmer (must
+# have dfu-programmer installed).
+#
+# make flip = Download the hex file to the device, using Atmel FLIP (must
+# have Atmel FLIP installed).
+#
+# make dfu-ee = Download the eeprom file to the device, using dfu-programmer
+# (must have dfu-programmer installed).
+#
+# make flip-ee = Download the eeprom file to the device, using Atmel FLIP
+# (must have Atmel FLIP installed).
+#
+# make debug = Start either simulavr or avarice as specified for debugging,
+# with avr-gdb or avr-insight as the front end for debugging.
+#
+# make filename.s = Just compile filename.c into the assembler code only.
+#
+# make filename.i = Create a preprocessed source file for use in submitting
+# bug reports to the GCC project.
+#
+# To rebuild project do "make clean" then "make all".
+#----------------------------------------------------------------------------
SUBPROJECT_DEFAULT = rev2
diff --git a/keyboards/ergodox_ez/matrix.c b/keyboards/ergodox_ez/matrix.c
index e0de06c349..b87fddbad7 100644
--- a/keyboards/ergodox_ez/matrix.c
+++ b/keyboards/ergodox_ez/matrix.c
@@ -187,8 +187,7 @@ uint8_t matrix_scan(void)
}
}
-
- matrix_scan_kb();
+ matrix_scan_quantum();
return 1;
}
diff --git a/keyboards/hhkb/matrix.c b/keyboards/hhkb/matrix.c
index 2dfb2f5e1f..666b6f595f 100644
--- a/keyboards/hhkb/matrix.c
+++ b/keyboards/hhkb/matrix.c
@@ -71,6 +71,14 @@ void matrix_init(void)
matrix_prev = _matrix1;
}
+__attribute__ ((weak))
+void matrix_scan_user(void) {
+}
+
+void matrix_scan_kb(void) {
+ matrix_scan_user();
+}
+
uint8_t matrix_scan(void)
{
uint8_t *tmp;
@@ -150,6 +158,9 @@ uint8_t matrix_scan(void)
KEY_POWER_OFF();
suspend_power_down();
}
+
+ matrix_scan_quantum();
+
return 1;
}
diff --git a/keyboards/planck/rev3/config.h b/keyboards/planck/rev3/config.h
index fa50a5622c..cc37874e83 100644
--- a/keyboards/planck/rev3/config.h
+++ b/keyboards/planck/rev3/config.h
@@ -5,4 +5,4 @@
#define DEVICE_VER 0x0003
-#endif \ No newline at end of file
+#endif
diff --git a/keyboards/sixkeyboard/matrix.c b/keyboards/sixkeyboard/matrix.c
index c279986487..ed1b70e286 100644
--- a/keyboards/sixkeyboard/matrix.c
+++ b/keyboards/sixkeyboard/matrix.c
@@ -87,7 +87,7 @@ uint8_t matrix_scan(void)
matrix[0] = (PINC&(1<<7) ? 0 : (1<<0)) | (PINB&(1<<7) ? 0 : (1<<1)) | (PINB&(1<<5) ? 0 : (1<<2));
matrix[1] = (PIND&(1<<6) ? 0 : (1<<0)) | (PIND&(1<<1) ? 0 : (1<<1)) | (PIND&(1<<4) ? 0 : (1<<2));
- matrix_scan_kb();
+ matrix_scan_quantum();
return 1;
}
diff --git a/quantum/keymap.h b/quantum/keymap.h
index 41fa394ab6..a994f4f2e5 100644
--- a/quantum/keymap.h
+++ b/quantum/keymap.h
@@ -77,6 +77,8 @@ enum quantum_keycodes {
#endif
QK_MOD_TAP = 0x6000,
QK_MOD_TAP_MAX = 0x6FFF,
+ QK_TAP_DANCE = 0x7100,
+ QK_TAP_DANCE_MAX = 0x71FF,
#ifdef UNICODE_ENABLE
QK_UNICODE = 0x8000,
QK_UNICODE_MAX = 0xFFFF,
diff --git a/quantum/keymap_midi.c b/quantum/keymap_midi.c
deleted file mode 100644
index 46049b9875..0000000000
--- a/quantum/keymap_midi.c
+++ /dev/null
@@ -1,109 +0,0 @@
-/*
-Copyright 2015 Jack Humbert <jack.humb@gmail.com>
-
-This program is free software: you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation, either version 2 of the License, or
-(at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#include "keymap.h"
-#include "keymap_midi.h"
-
-uint8_t starting_note = 0x0C;
-int offset = 7;
-
-void action_function(keyrecord_t *record, uint8_t id, uint8_t opt)
-{
- if (id != 0) {
- if (record->event.pressed) {
- midi_send_noteon(&midi_device, opt, (id & 0xFF), 127);
- } else {
- midi_send_noteoff(&midi_device, opt, (id & 0xFF), 127);
- }
- }
-
- 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.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);
- midi_send_cc(&midi_device, 3, 0x7B, 0);
- midi_send_cc(&midi_device, 4, 0x7B, 0);
- return;
- } else {
- 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;
- }
- }
- 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.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);
- midi_send_cc(&midi_device, 3, 0x7B, 0);
- midi_send_cc(&midi_device, 4, 0x7B, 0);
- return;
- } else {
- 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;
- }
- }
-
- if (record->event.key.col == (MATRIX_COLS - 3) && record->event.key.row == (MATRIX_ROWS - 1) && record->event.pressed) {
- offset++;
- midi_send_cc(&midi_device, 0, 0x7B, 0);
- midi_send_cc(&midi_device, 1, 0x7B, 0);
- midi_send_cc(&midi_device, 2, 0x7B, 0);
- midi_send_cc(&midi_device, 3, 0x7B, 0);
- midi_send_cc(&midi_device, 4, 0x7B, 0);
- stop_all_notes();
- for (int i = 0; i <= 7; i++) {
- 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.626)*pow(2.0, -1.0)*pow(2.0,(starting_note + SCALE[i + offset])/12.0+(MATRIX_ROWS - 1)));
- _delay_us(8000);
- }
- return;
- }
- if (record->event.key.col == (MATRIX_COLS - 4) && record->event.key.row == (MATRIX_ROWS - 1) && record->event.pressed) {
- offset--;
- midi_send_cc(&midi_device, 0, 0x7B, 0);
- midi_send_cc(&midi_device, 1, 0x7B, 0);
- midi_send_cc(&midi_device, 2, 0x7B, 0);
- midi_send_cc(&midi_device, 3, 0x7B, 0);
- midi_send_cc(&midi_device, 4, 0x7B, 0);
- stop_all_notes();
- for (int i = 0; i <= 7; i++) {
- 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.626)*pow(2.0, -1.0)*pow(2.0,(starting_note + SCALE[i + offset])/12.0+(MATRIX_ROWS - 1)));
- _delay_us(8000);
- }
- return;
- }
-
- 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, -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, -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/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/keymap_midi.h b/quantum/process_keycode/process_midi.h
index 3a2bf3afff..acd4fc1b16 100644
--- a/quantum/keymap_midi.h
+++ b/quantum/process_keycode/process_midi.h
@@ -1,24 +1,9 @@
-/*
-Copyright 2015 Jack Humbert <jack.humb@gmail.com>
+#ifndef PROCESS_MIDI_H
+#define PROCESS_MIDI_H
-This program is free software: you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation, either version 2 of the License, or
-(at your option) any later version.
+#include "quantum.h"
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#ifndef KEYMAP_MIDI_H
-#define KEYMAP_MIDI_H
-
-#include <lufa.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
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), \
+