aboutsummaryrefslogtreecommitdiff
path: root/quantum/process_keycode/process_midi.c
diff options
context:
space:
mode:
Diffstat (limited to 'quantum/process_keycode/process_midi.c')
-rw-r--r--quantum/process_keycode/process_midi.c292
1 files changed, 231 insertions, 61 deletions
diff --git a/quantum/process_keycode/process_midi.c b/quantum/process_keycode/process_midi.c
index 577dad43a..700c6ce8e 100644
--- a/quantum/process_keycode/process_midi.c
+++ b/quantum/process_keycode/process_midi.c
@@ -1,68 +1,238 @@
1#include "process_midi.h" 1#include "process_midi.h"
2 2
3bool midi_activated = false; 3#ifdef MIDI_ENABLE
4uint8_t midi_starting_note = 0x0C; 4#include "midi.h"
5int midi_offset = 7; 5
6 6#ifdef MIDI_BASIC
7bool process_midi(uint16_t keycode, keyrecord_t *record) { 7
8 if (keycode == MI_ON && record->event.pressed) { 8void process_midi_basic_noteon(uint8_t note)
9 midi_activated = true; 9{
10#ifdef AUDIO_ENABLE 10 midi_send_noteon(&midi_device, 0, note, 128);
11 music_scale_user(); 11}
12#endif 12
13 return false; 13void process_midi_basic_noteoff(uint8_t note)
14 } 14{
15 midi_send_noteoff(&midi_device, 0, note, 0);
16}
17
18void process_midi_all_notes_off(void)
19{
20 midi_send_cc(&midi_device, 0, 0x7B, 0);
21}
22
23#endif // MIDI_BASIC
24
25#ifdef MIDI_ADVANCED
26
27#include "timer.h"
28
29static uint8_t tone_status[MIDI_TONE_COUNT];
30
31static uint8_t midi_modulation;
32static int8_t midi_modulation_step;
33static uint16_t midi_modulation_timer;
34
35inline uint8_t compute_velocity(uint8_t setting)
36{
37 return (setting + 1) * (128 / (MIDI_VELOCITY_MAX - MIDI_VELOCITY_MIN + 1));
38}
15 39
16 if (keycode == MI_OFF && record->event.pressed) { 40void midi_init(void)
17 midi_activated = false; 41{
18 midi_send_cc(&midi_device, 0, 0x7B, 0); 42 midi_config.octave = MI_OCT_2 - MIDI_OCTAVE_MIN;
19 return false; 43 midi_config.transpose = 0;
44 midi_config.velocity = (MIDI_VELOCITY_MAX - MIDI_VELOCITY_MIN);
45 midi_config.channel = 0;
46 midi_config.modulation_interval = 8;
47
48 for (uint8_t i = 0; i < MIDI_TONE_COUNT; i++)
49 {
50 tone_status[i] = MIDI_INVALID_NOTE;
20 } 51 }
21 52
22 if (midi_activated) { 53 midi_modulation = 0;
23 if (record->event.key.col == (MATRIX_COLS - 1) && record->event.key.row == (MATRIX_ROWS - 1)) { 54 midi_modulation_step = 0;
24 if (record->event.pressed) { 55 midi_modulation_timer = 0;
25 midi_starting_note++; // Change key 56}
26 midi_send_cc(&midi_device, 0, 0x7B, 0); 57
27 } 58void midi_task(void)
28 return false; 59{
29 } 60 if (timer_elapsed(midi_modulation_timer) < midi_config.modulation_interval)
30 if (record->event.key.col == (MATRIX_COLS - 2) && record->event.key.row == (MATRIX_ROWS - 1)) { 61 return;
31 if (record->event.pressed) { 62 midi_modulation_timer = timer_read();
32 midi_starting_note--; // Change key 63
33 midi_send_cc(&midi_device, 0, 0x7B, 0); 64 if (midi_modulation_step != 0)
34 } 65 {
35 return false; 66 dprintf("midi modulation %d\n", midi_modulation);
36 } 67 midi_send_cc(&midi_device, midi_config.channel, 0x1, midi_modulation);
37 if (record->event.key.col == (MATRIX_COLS - 3) && record->event.key.row == (MATRIX_ROWS - 1) && record->event.pressed) { 68
38 midi_offset++; // Change scale 69 if (midi_modulation_step < 0 && midi_modulation < -midi_modulation_step) {
39 midi_send_cc(&midi_device, 0, 0x7B, 0); 70 midi_modulation = 0;
40 return false; 71 midi_modulation_step = 0;
41 } 72 return;
42 if (record->event.key.col == (MATRIX_COLS - 4) && record->event.key.row == (MATRIX_ROWS - 1) && record->event.pressed) { 73 }
43 midi_offset--; // Change scale 74
44 midi_send_cc(&midi_device, 0, 0x7B, 0); 75 midi_modulation += midi_modulation_step;
45 return false; 76
46 } 77 if (midi_modulation > 127)
47 // basic 78 midi_modulation = 127;
48 // uint8_t note = (midi_starting_note + SCALE[record->event.key.col + midi_offset])+12*(MATRIX_ROWS - record->event.key.row);
49 // advanced
50 // uint8_t note = (midi_starting_note + record->event.key.col + midi_offset)+12*(MATRIX_ROWS - record->event.key.row);
51 // guitar
52 uint8_t note = (midi_starting_note + record->event.key.col + midi_offset)+5*(MATRIX_ROWS - record->event.key.row);
53 // violin
54 // uint8_t note = (midi_starting_note + record->event.key.col + midi_offset)+7*(MATRIX_ROWS - record->event.key.row);
55
56 if (record->event.pressed) {
57 // midi_send_noteon(&midi_device, record->event.key.row, midi_starting_note + SCALE[record->event.key.col], 127);
58 midi_send_noteon(&midi_device, 0, note, 127);
59 } else {
60 // midi_send_noteoff(&midi_device, record->event.key.row, midi_starting_note + SCALE[record->event.key.col], 127);
61 midi_send_noteoff(&midi_device, 0, note, 127);
62 }
63
64 if (keycode < 0xFF) // ignores all normal keycodes, but lets RAISE, LOWER, etc through
65 return false;
66 } 79 }
67 return true;
68} 80}
81
82uint8_t midi_compute_note(uint16_t keycode)
83{
84 return 12 * midi_config.octave + (keycode - MIDI_TONE_MIN) + midi_config.transpose;
85}
86
87bool process_midi(uint16_t keycode, keyrecord_t *record)
88{
89 switch (keycode) {
90 case MIDI_TONE_MIN ... MIDI_TONE_MAX:
91 {
92 uint8_t channel = midi_config.channel;
93 uint8_t tone = keycode - MIDI_TONE_MIN;
94 uint8_t velocity = compute_velocity(midi_config.velocity);
95 if (record->event.pressed) {
96 uint8_t note = midi_compute_note(keycode);
97 midi_send_noteon(&midi_device, channel, note, velocity);
98 dprintf("midi noteon channel:%d note:%d velocity:%d\n", channel, note, velocity);
99 tone_status[tone] = note;
100 }
101 else {
102 uint8_t note = tone_status[tone];
103 if (note != MIDI_INVALID_NOTE)
104 {
105 midi_send_noteoff(&midi_device, channel, note, velocity);
106 dprintf("midi noteoff channel:%d note:%d velocity:%d\n", channel, note, velocity);
107 }
108 tone_status[tone] = MIDI_INVALID_NOTE;
109 }
110 return false;
111 }
112 case MIDI_OCTAVE_MIN ... MIDI_OCTAVE_MAX:
113 if (record->event.pressed) {
114 midi_config.octave = keycode - MIDI_OCTAVE_MIN;
115 dprintf("midi octave %d\n", midi_config.octave);
116 }
117 return false;
118 case MI_OCTD:
119 if (record->event.pressed && midi_config.octave > 0) {
120 midi_config.octave--;
121 dprintf("midi octave %d\n", midi_config.octave);
122 }
123 return false;
124 case MI_OCTU:
125 if (record->event.pressed && midi_config.octave < (MIDI_OCTAVE_MAX - MIDI_OCTAVE_MIN)) {
126 midi_config.octave++;
127 dprintf("midi octave %d\n", midi_config.octave);
128 }
129 return false;
130 case MIDI_TRANSPOSE_MIN ... MIDI_TRANSPOSE_MAX:
131 if (record->event.pressed) {
132 midi_config.transpose = keycode - MI_TRNS_0;
133 dprintf("midi transpose %d\n", midi_config.transpose);
134 }
135 return false;
136 case MI_TRNSD:
137 if (record->event.pressed && midi_config.transpose > (MIDI_TRANSPOSE_MIN - MI_TRNS_0)) {
138 midi_config.transpose--;
139 dprintf("midi transpose %d\n", midi_config.transpose);
140 }
141 return false;
142 case MI_TRNSU:
143 if (record->event.pressed && midi_config.transpose < (MIDI_TRANSPOSE_MAX - MI_TRNS_0)) {
144 const bool positive = midi_config.transpose > 0;
145 midi_config.transpose++;
146 if (positive && midi_config.transpose < 0)
147 midi_config.transpose--;
148 dprintf("midi transpose %d\n", midi_config.transpose);
149 }
150 return false;
151 case MIDI_VELOCITY_MIN ... MIDI_VELOCITY_MAX:
152 if (record->event.pressed) {
153 midi_config.velocity = keycode - MIDI_VELOCITY_MIN;
154 dprintf("midi velocity %d\n", midi_config.velocity);
155 }
156 return false;
157 case MI_VELD:
158 if (record->event.pressed && midi_config.velocity > 0) {
159 midi_config.velocity--;
160 dprintf("midi velocity %d\n", midi_config.velocity);
161 }
162 return false;
163 case MI_VELU:
164 if (record->event.pressed) {
165 midi_config.velocity++;
166 dprintf("midi velocity %d\n", midi_config.velocity);
167 }
168 return false;
169 case MIDI_CHANNEL_MIN ... MIDI_CHANNEL_MAX:
170 if (record->event.pressed) {
171 midi_config.channel = keycode - MIDI_CHANNEL_MIN;
172 dprintf("midi channel %d\n", midi_config.channel);
173 }
174 return false;
175 case MI_CHD:
176 if (record->event.pressed) {
177 midi_config.channel--;
178 dprintf("midi channel %d\n", midi_config.channel);
179 }
180 return false;
181 case MI_CHU:
182 if (record->event.pressed) {
183 midi_config.channel++;
184 dprintf("midi channel %d\n", midi_config.channel);
185 }
186 return false;
187 case MI_ALLOFF:
188 if (record->event.pressed) {
189 midi_send_cc(&midi_device, midi_config.channel, 0x7B, 0);
190 dprintf("midi all notes off\n");
191 }
192 return false;
193 case MI_SUS:
194 midi_send_cc(&midi_device, midi_config.channel, 0x40, record->event.pressed ? 127 : 0);
195 dprintf("midi sustain %d\n", record->event.pressed);
196 return false;
197 case MI_PORT:
198 midi_send_cc(&midi_device, midi_config.channel, 0x41, record->event.pressed ? 127 : 0);
199 dprintf("midi portamento %d\n", record->event.pressed);
200 return false;
201 case MI_SOST:
202 midi_send_cc(&midi_device, midi_config.channel, 0x42, record->event.pressed ? 127 : 0);
203 dprintf("midi sostenuto %d\n", record->event.pressed);
204 return false;
205 case MI_SOFT:
206 midi_send_cc(&midi_device, midi_config.channel, 0x43, record->event.pressed ? 127 : 0);
207 dprintf("midi soft %d\n", record->event.pressed);
208 return false;
209 case MI_LEG:
210 midi_send_cc(&midi_device, midi_config.channel, 0x43, record->event.pressed ? 127 : 0);
211 dprintf("midi legato %d\n", record->event.pressed);
212 return false;
213 case MI_MOD:
214 midi_modulation_step = record->event.pressed ? 1 : -1;
215 return false;
216 case MI_MODSD:
217 if (record->event.pressed) {
218 midi_config.modulation_interval++;
219 // prevent overflow
220 if (midi_config.modulation_interval == 0)
221 midi_config.modulation_interval--;
222 dprintf("midi modulation interval %d\n", midi_config.modulation_interval);
223 }
224 return false;
225 case MI_MODSU:
226 if (record->event.pressed && midi_config.modulation_interval > 0) {
227 midi_config.modulation_interval--;
228 dprintf("midi modulation interval %d\n", midi_config.modulation_interval);
229 }
230 return false;
231 };
232
233 return true;
234}
235
236#endif // MIDI_ADVANCED
237
238#endif // MIDI_ENABLE