summaryrefslogtreecommitdiffstats
path: root/quantum/process_keycode
diff options
context:
space:
mode:
Diffstat (limited to 'quantum/process_keycode')
-rw-r--r--quantum/process_keycode/process_audio.c62
-rw-r--r--quantum/process_keycode/process_audio.h11
-rw-r--r--quantum/process_keycode/process_chording.c18
-rw-r--r--quantum/process_keycode/process_chording.h18
-rw-r--r--quantum/process_keycode/process_combo.c16
-rw-r--r--quantum/process_keycode/process_combo.h16
-rw-r--r--quantum/process_keycode/process_leader.c18
-rw-r--r--quantum/process_keycode/process_leader.h18
-rw-r--r--quantum/process_keycode/process_midi.c307
-rw-r--r--quantum/process_keycode/process_midi.h243
-rw-r--r--quantum/process_keycode/process_music.c133
-rw-r--r--quantum/process_keycode/process_music.h24
-rw-r--r--quantum/process_keycode/process_printer.c18
-rw-r--r--quantum/process_keycode/process_printer.h18
-rw-r--r--quantum/process_keycode/process_printer_bb.c18
-rw-r--r--quantum/process_keycode/process_tap_dance.c17
-rw-r--r--quantum/process_keycode/process_tap_dance.h15
-rw-r--r--quantum/process_keycode/process_ucis.c18
-rw-r--r--quantum/process_keycode/process_ucis.h16
-rw-r--r--quantum/process_keycode/process_unicode.c21
-rw-r--r--quantum/process_keycode/process_unicode.h15
-rw-r--r--quantum/process_keycode/process_unicode_common.c32
-rw-r--r--quantum/process_keycode/process_unicode_common.h18
-rw-r--r--quantum/process_keycode/process_unicodemap.c18
-rw-r--r--quantum/process_keycode/process_unicodemap.h18
25 files changed, 797 insertions, 329 deletions
diff --git a/quantum/process_keycode/process_audio.c b/quantum/process_keycode/process_audio.c
new file mode 100644
index 0000000000..0b6380ed39
--- /dev/null
+++ b/quantum/process_keycode/process_audio.c
@@ -0,0 +1,62 @@
+#include "audio.h"
+#include "process_audio.h"
+
+static float compute_freq_for_midi_note(uint8_t note)
+{
+ // https://en.wikipedia.org/wiki/MIDI_tuning_standard
+ return pow(2.0, (note - 69) / 12.0) * 440.0f;
+}
+
+bool process_audio(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 == 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;
+ }
+
+ return true;
+}
+
+void process_audio_noteon(uint8_t note) {
+ play_note(compute_freq_for_midi_note(note), 0xF);
+}
+
+void process_audio_noteoff(uint8_t note) {
+ stop_note(compute_freq_for_midi_note(note));
+}
+
+void process_audio_all_notes_off(void) {
+ stop_all_notes();
+}
+
+__attribute__ ((weak))
+void audio_on_user() {} \ No newline at end of file
diff --git a/quantum/process_keycode/process_audio.h b/quantum/process_keycode/process_audio.h
new file mode 100644
index 0000000000..7ac15b7330
--- /dev/null
+++ b/quantum/process_keycode/process_audio.h
@@ -0,0 +1,11 @@
+#ifndef PROCESS_AUDIO_H
+#define PROCESS_AUDIO_H
+
+bool process_audio(uint16_t keycode, keyrecord_t *record);
+void process_audio_noteon(uint8_t note);
+void process_audio_noteoff(uint8_t note);
+void process_audio_all_notes_off(void);
+
+void audio_on_user(void);
+
+#endif \ No newline at end of file
diff --git a/quantum/process_keycode/process_chording.c b/quantum/process_keycode/process_chording.c
index d7814629f3..6c6ebe300a 100644
--- a/quantum/process_keycode/process_chording.c
+++ b/quantum/process_keycode/process_chording.c
@@ -1,3 +1,19 @@
+/* Copyright 2016 Jack Humbert
+ *
+ * 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 "process_chording.h"
bool keys_chord(uint8_t keys[]) {
@@ -57,4 +73,4 @@ bool process_chording(uint16_t keycode, keyrecord_t *record) {
}
}
return true;
-} \ No newline at end of file
+}
diff --git a/quantum/process_keycode/process_chording.h b/quantum/process_keycode/process_chording.h
index 49c97db3bc..8c0f4862a8 100644
--- a/quantum/process_keycode/process_chording.h
+++ b/quantum/process_keycode/process_chording.h
@@ -1,3 +1,19 @@
+/* Copyright 2016 Jack Humbert
+ *
+ * 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/>.
+ */
+
#ifndef PROCESS_CHORDING_H
#define PROCESS_CHORDING_H
@@ -13,4 +29,4 @@ uint8_t chord_key_down = 0;
bool process_chording(uint16_t keycode, keyrecord_t *record);
-#endif \ No newline at end of file
+#endif
diff --git a/quantum/process_keycode/process_combo.c b/quantum/process_keycode/process_combo.c
index e2189ad98b..58d45add22 100644
--- a/quantum/process_keycode/process_combo.c
+++ b/quantum/process_keycode/process_combo.c
@@ -1,3 +1,19 @@
+/* Copyright 2016 Jack Humbert
+ *
+ * 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 "process_combo.h"
#include "print.h"
diff --git a/quantum/process_keycode/process_combo.h b/quantum/process_keycode/process_combo.h
index 847f2b7376..a5dbd788a4 100644
--- a/quantum/process_keycode/process_combo.h
+++ b/quantum/process_keycode/process_combo.h
@@ -1,3 +1,19 @@
+/* Copyright 2016 Jack Humbert
+ *
+ * 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/>.
+ */
+
#ifndef PROCESS_COMBO_H
#define PROCESS_COMBO_H
diff --git a/quantum/process_keycode/process_leader.c b/quantum/process_keycode/process_leader.c
index e53d221e75..473906d657 100644
--- a/quantum/process_keycode/process_leader.c
+++ b/quantum/process_keycode/process_leader.c
@@ -1,3 +1,19 @@
+/* Copyright 2016 Jack Humbert
+ *
+ * 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 "process_leader.h"
__attribute__ ((weak))
@@ -35,4 +51,4 @@ bool process_leader(uint16_t keycode, keyrecord_t *record) {
}
}
return true;
-} \ No newline at end of file
+}
diff --git a/quantum/process_keycode/process_leader.h b/quantum/process_keycode/process_leader.h
index c83db8abbd..da7a3d2ef7 100644
--- a/quantum/process_keycode/process_leader.h
+++ b/quantum/process_keycode/process_leader.h
@@ -1,3 +1,19 @@
+/* Copyright 2016 Jack Humbert
+ *
+ * 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/>.
+ */
+
#ifndef PROCESS_LEADER_H
#define PROCESS_LEADER_H
@@ -20,4 +36,4 @@ void leader_end(void);
#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
+#endif
diff --git a/quantum/process_keycode/process_midi.c b/quantum/process_keycode/process_midi.c
index 577dad43ac..9184feaae8 100644
--- a/quantum/process_keycode/process_midi.c
+++ b/quantum/process_keycode/process_midi.c
@@ -1,68 +1,253 @@
+/* Copyright 2016 Jack Humbert
+ *
+ * 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 "process_midi.h"
-bool midi_activated = false;
-uint8_t midi_starting_note = 0x0C;
-int midi_offset = 7;
-
-bool process_midi(uint16_t keycode, keyrecord_t *record) {
- if (keycode == MI_ON && record->event.pressed) {
- midi_activated = true;
-#ifdef AUDIO_ENABLE
- music_scale_user();
-#endif
- return false;
- }
+#ifdef MIDI_ENABLE
+#include "midi.h"
+
+#ifdef MIDI_BASIC
+
+void process_midi_basic_noteon(uint8_t note)
+{
+ midi_send_noteon(&midi_device, 0, note, 128);
+}
+
+void process_midi_basic_noteoff(uint8_t note)
+{
+ midi_send_noteoff(&midi_device, 0, note, 0);
+}
+
+void process_midi_all_notes_off(void)
+{
+ midi_send_cc(&midi_device, 0, 0x7B, 0);
+}
+
+#endif // MIDI_BASIC
+
+#ifdef MIDI_ADVANCED
+
+#include "timer.h"
+
+static uint8_t tone_status[MIDI_TONE_COUNT];
+
+static uint8_t midi_modulation;
+static int8_t midi_modulation_step;
+static uint16_t midi_modulation_timer;
+
+inline uint8_t compute_velocity(uint8_t setting)
+{
+ return (setting + 1) * (128 / (MIDI_VELOCITY_MAX - MIDI_VELOCITY_MIN + 1));
+}
- if (keycode == MI_OFF && record->event.pressed) {
- midi_activated = false;
- midi_send_cc(&midi_device, 0, 0x7B, 0);
- return false;
+void midi_init(void)
+{
+ midi_config.octave = MI_OCT_2 - MIDI_OCTAVE_MIN;
+ midi_config.transpose = 0;
+ midi_config.velocity = (MIDI_VELOCITY_MAX - MIDI_VELOCITY_MIN);
+ midi_config.channel = 0;
+ midi_config.modulation_interval = 8;
+
+ for (uint8_t i = 0; i < MIDI_TONE_COUNT; i++)
+ {
+ tone_status[i] = MIDI_INVALID_NOTE;
}
- if (midi_activated) {
- if (record->event.key.col == (MATRIX_COLS - 1) && record->event.key.row == (MATRIX_ROWS - 1)) {
- if (record->event.pressed) {
- midi_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) {
- midi_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) {
- midi_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) {
- midi_offset--; // Change scale
- midi_send_cc(&midi_device, 0, 0x7B, 0);
- return false;
- }
- // basic
- // uint8_t note = (midi_starting_note + SCALE[record->event.key.col + midi_offset])+12*(MATRIX_ROWS - record->event.key.row);
- // advanced
- // uint8_t note = (midi_starting_note + record->event.key.col + midi_offset)+12*(MATRIX_ROWS - record->event.key.row);
- // guitar
- uint8_t note = (midi_starting_note + record->event.key.col + midi_offset)+5*(MATRIX_ROWS - record->event.key.row);
- // violin
- // uint8_t note = (midi_starting_note + record->event.key.col + midi_offset)+7*(MATRIX_ROWS - record->event.key.row);
-
- if (record->event.pressed) {
- // midi_send_noteon(&midi_device, record->event.key.row, midi_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, midi_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;
+ midi_modulation = 0;
+ midi_modulation_step = 0;
+ midi_modulation_timer = 0;
+}
+
+void midi_task(void)
+{
+ if (timer_elapsed(midi_modulation_timer) < midi_config.modulation_interval)
+ return;
+ midi_modulation_timer = timer_read();
+
+ if (midi_modulation_step != 0)
+ {
+ dprintf("midi modulation %d\n", midi_modulation);
+ midi_send_cc(&midi_device, midi_config.channel, 0x1, midi_modulation);
+
+ if (midi_modulation_step < 0 && midi_modulation < -midi_modulation_step) {
+ midi_modulation = 0;
+ midi_modulation_step = 0;
+ return;
+ }
+
+ midi_modulation += midi_modulation_step;
+
+ if (midi_modulation > 127)
+ midi_modulation = 127;
}
- return true;
}
+
+uint8_t midi_compute_note(uint16_t keycode)
+{
+ return 12 * midi_config.octave + (keycode - MIDI_TONE_MIN) + midi_config.transpose;
+}
+
+bool process_midi(uint16_t keycode, keyrecord_t *record)
+{
+ switch (keycode) {
+ case MIDI_TONE_MIN ... MIDI_TONE_MAX:
+ {
+ uint8_t channel = midi_config.channel;
+ uint8_t tone = keycode - MIDI_TONE_MIN;
+ uint8_t velocity = compute_velocity(midi_config.velocity);
+ if (record->event.pressed) {
+ uint8_t note = midi_compute_note(keycode);
+ midi_send_noteon(&midi_device, channel, note, velocity);
+ dprintf("midi noteon channel:%d note:%d velocity:%d\n", channel, note, velocity);
+ tone_status[tone] = note;
+ }
+ else {
+ uint8_t note = tone_status[tone];
+ if (note != MIDI_INVALID_NOTE)
+ {
+ midi_send_noteoff(&midi_device, channel, note, velocity);
+ dprintf("midi noteoff channel:%d note:%d velocity:%d\n", channel, note, velocity);
+ }
+ tone_status[tone] = MIDI_INVALID_NOTE;
+ }
+ return false;
+ }
+ case MIDI_OCTAVE_MIN ... MIDI_OCTAVE_MAX:
+ if (record->event.pressed) {
+ midi_config.octave = keycode - MIDI_OCTAVE_MIN;
+ dprintf("midi octave %d\n", midi_config.octave);
+ }
+ return false;
+ case MI_OCTD:
+ if (record->event.pressed && midi_config.octave > 0) {
+ midi_config.octave--;
+ dprintf("midi octave %d\n", midi_config.octave);
+ }
+ return false;
+ case MI_OCTU:
+ if (record->event.pressed && midi_config.octave < (MIDI_OCTAVE_MAX - MIDI_OCTAVE_MIN)) {
+ midi_config.octave++;
+ dprintf("midi octave %d\n", midi_config.octave);
+ }
+ return false;
+ case MIDI_TRANSPOSE_MIN ... MIDI_TRANSPOSE_MAX:
+ if (record->event.pressed) {
+ midi_config.transpose = keycode - MI_TRNS_0;
+ dprintf("midi transpose %d\n", midi_config.transpose);
+ }
+ return false;
+ case MI_TRNSD:
+ if (record->event.pressed && midi_config.transpose > (MIDI_TRANSPOSE_MIN - MI_TRNS_0)) {
+ midi_config.transpose--;
+ dprintf("midi transpose %d\n", midi_config.transpose);
+ }
+ return false;
+ case MI_TRNSU:
+ if (record->event.pressed && midi_config.transpose < (MIDI_TRANSPOSE_MAX - MI_TRNS_0)) {
+ const bool positive = midi_config.transpose > 0;
+ midi_config.transpose++;
+ if (positive && midi_config.transpose < 0)
+ midi_config.transpose--;
+ dprintf("midi transpose %d\n", midi_config.transpose);
+ }
+ return false;
+ case MIDI_VELOCITY_MIN ... MIDI_VELOCITY_MAX:
+ if (record->event.pressed) {
+ midi_config.velocity = keycode - MIDI_VELOCITY_MIN;
+ dprintf("midi velocity %d\n", midi_config.velocity);
+ }
+ return false;
+ case MI_VELD:
+ if (record->event.pressed && midi_config.velocity > 0) {
+ midi_config.velocity--;
+ dprintf("midi velocity %d\n", midi_config.velocity);
+ }
+ return false;
+ case MI_VELU:
+ if (record->event.pressed) {
+ midi_config.velocity++;
+ dprintf("midi velocity %d\n", midi_config.velocity);
+ }
+ return false;
+ case MIDI_CHANNEL_MIN ... MIDI_CHANNEL_MAX:
+ if (record->event.pressed) {
+ midi_config.channel = keycode - MIDI_CHANNEL_MIN;
+ dprintf("midi channel %d\n", midi_config.channel);
+ }
+ return false;
+ case MI_CHD:
+ if (record->event.pressed) {
+ midi_config.channel--;
+ dprintf("midi channel %d\n", midi_config.channel);
+ }
+ return false;
+ case MI_CHU:
+ if (record->event.pressed) {
+ midi_config.channel++;
+ dprintf("midi channel %d\n", midi_config.channel);
+ }
+ return false;
+ case MI_ALLOFF:
+ if (record->event.pressed) {
+ midi_send_cc(&midi_device, midi_config.channel, 0x7B, 0);
+ dprintf("midi all notes off\n");
+ }
+ return false;
+ case MI_SUS:
+ midi_send_cc(&midi_device, midi_config.channel, 0x40, record->event.pressed ? 127 : 0);
+ dprintf("midi sustain %d\n", record->event.pressed);
+ return false;
+ case MI_PORT:
+ midi_send_cc(&midi_device, midi_config.channel, 0x41, record->event.pressed ? 127 : 0);
+ dprintf("midi portamento %d\n", record->event.pressed);
+ return false;
+ case MI_SOST:
+ midi_send_cc(&midi_device, midi_config.channel, 0x42, record->event.pressed ? 127 : 0);
+ dprintf("midi sostenuto %d\n", record->event.pressed);
+ return false;
+ case MI_SOFT:
+ midi_send_cc(&midi_device, midi_config.channel, 0x43, record->event.pressed ? 127 : 0);
+ dprintf("midi soft %d\n", record->event.pressed);
+ return false;
+ case MI_LEG:
+ midi_send_cc(&midi_device, midi_config.channel, 0x43, record->event.pressed ? 127 : 0);
+ dprintf("midi legato %d\n", record->event.pressed);
+ return false;
+ case MI_MOD:
+ midi_modulation_step = record->event.pressed ? 1 : -1;
+ return false;
+ case MI_MODSD:
+ if (record->event.pressed) {
+ midi_config.modulation_interval++;
+ // prevent overflow
+ if (midi_config.modulation_interval == 0)
+ midi_config.modulation_interval--;
+ dprintf("midi modulation interval %d\n", midi_config.modulation_interval);
+ }
+ return false;
+ case MI_MODSU:
+ if (record->event.pressed && midi_config.modulation_interval > 0) {
+ midi_config.modulation_interval--;
+ dprintf("midi modulation interval %d\n", midi_config.modulation_interval);
+ }
+ return false;
+ };
+
+ return true;
+}
+
+#endif // MIDI_ADVANCED
+
+#endif // MIDI_ENABLE
diff --git a/quantum/process_keycode/process_midi.h b/quantum/process_keycode/process_midi.h
index acd4fc1b16..ccac8981a6 100644
--- a/quantum/process_keycode/process_midi.h
+++ b/quantum/process_keycode/process_midi.h
@@ -1,207 +1,56 @@
+/* Copyright 2016 Jack Humbert
+ *
+ * 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/>.
+ */
+
#ifndef PROCESS_MIDI_H
#define PROCESS_MIDI_H
#include "quantum.h"
-bool process_midi(uint16_t keycode, keyrecord_t *record);
+#ifdef MIDI_ENABLE
+
+#ifdef MIDI_BASIC
+void process_midi_basic_noteon(uint8_t note);
+void process_midi_basic_noteoff(uint8_t note);
+void process_midi_all_notes_off(void);
+#endif
-#define MIDI(n) ((n) | 0x6000)
-#define MIDI12 0x6000, 0x6000, 0x6000, 0x6000, 0x6000, 0x6000, 0x6000, 0x6000, 0x6000, 0x6000, 0x6000, 0x6000
+#ifdef MIDI_ADVANCED
+typedef union {
+ uint32_t raw;
+ struct {
+ uint8_t octave :4;
+ int8_t transpose :4;
+ uint8_t velocity :4;
+ uint8_t channel :4;
+ uint8_t modulation_interval :4;
+ };
+} midi_config_t;
+
+midi_config_t midi_config;
+
+void midi_init(void);
+void midi_task(void);
+bool process_midi(uint16_t keycode, keyrecord_t *record);
-#define CHNL(note, channel) (note + (channel << 8))
+#define MIDI_INVALID_NOTE 0xFF
+#define MIDI_TONE_COUNT (MIDI_TONE_MAX - MIDI_TONE_MIN + 1)
-#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), }
+uint8_t midi_compute_note(uint16_t keycode);
+#endif // MIDI_ADVANCED
-#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