]> git.donarmstrong.com Git - qmk_firmware.git/blob - quantum/process_keycode/process_midi.c
Factor basic note processing into respective processors
[qmk_firmware.git] / quantum / process_keycode / process_midi.c
1 #include "process_midi.h"
2
3 #ifdef MIDI_ENABLE
4 #include "midi.h"
5
6 #ifdef MIDI_BASIC
7
8 void process_midi_basic_noteon(uint8_t note) 
9 {
10     midi_send_noteon(&midi_device, 0, note, 128);
11 }
12
13 void process_midi_basic_noteoff(uint8_t note)
14 {
15     midi_send_noteoff(&midi_device, 0, note, 0);
16 }
17
18 void process_midi_basic_stop_all_notes(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
29 static uint8_t tone_status[MIDI_TONE_COUNT];
30
31 static uint8_t midi_modulation;
32 static int8_t midi_modulation_step;
33 static uint16_t midi_modulation_timer;
34
35 inline uint8_t compute_velocity(uint8_t setting)
36 {
37     return (setting + 1) * (128 / (MIDI_VELOCITY_MAX - MIDI_VELOCITY_MIN + 1));
38 }
39
40 void midi_init(void)
41 {
42     midi_config.octave = MI_OCT_2 - MIDI_OCTAVE_MIN;
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;
51     }
52
53     midi_modulation = 0;
54     midi_modulation_step = 0;
55     midi_modulation_timer = 0;
56 }
57
58 void midi_task(void)
59 {
60     if (timer_elapsed(midi_modulation_timer) < midi_config.modulation_interval)
61         return;
62     midi_modulation_timer = timer_read();
63
64     if (midi_modulation_step != 0)
65     {
66         dprintf("midi modulation %d\n", midi_modulation);
67         midi_send_cc(&midi_device, midi_config.channel, 0x1, midi_modulation);
68
69         if (midi_modulation_step < 0 && midi_modulation < -midi_modulation_step) {
70             midi_modulation = 0;
71             midi_modulation_step = 0;
72             return;
73         }
74
75         midi_modulation += midi_modulation_step;
76
77         if (midi_modulation > 127)
78             midi_modulation = 127;
79     }
80 }
81
82 uint8_t midi_compute_note(uint16_t keycode)
83 {
84     return 12 * midi_config.octave + (keycode - MIDI_TONE_MIN) + midi_config.transpose;
85 }
86
87 bool 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