]> git.donarmstrong.com Git - qmk_firmware.git/blob - quantum/process_keycode/process_midi.c
Remove more commented out MCUs
[qmk_firmware.git] / quantum / process_keycode / process_midi.c
1 /* Copyright 2016 Jack Humbert
2  *
3  * This program is free software: you can redistribute it and/or modify
4  * it under the terms of the GNU General Public License as published by
5  * the Free Software Foundation, either version 2 of the License, or
6  * (at your option) any later version.
7  *
8  * This program is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11  * GNU General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public License
14  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
15  */
16 #include "process_midi.h"
17
18 #ifdef MIDI_ENABLE
19 #include <LUFA/Drivers/USB/USB.h>
20 #include "midi.h"
21 #include "qmk_midi.h"
22
23 #ifdef MIDI_BASIC
24
25 void process_midi_basic_noteon(uint8_t note)
26 {
27     midi_send_noteon(&midi_device, 0, note, 128);
28 }
29
30 void process_midi_basic_noteoff(uint8_t note)
31 {
32     midi_send_noteoff(&midi_device, 0, note, 0);
33 }
34
35 void process_midi_all_notes_off(void)
36 {
37     midi_send_cc(&midi_device, 0, 0x7B, 0);
38 }
39
40 #endif // MIDI_BASIC
41
42 #ifdef MIDI_ADVANCED
43
44 #include "timer.h"
45
46 static uint8_t tone_status[MIDI_TONE_COUNT];
47
48 static uint8_t midi_modulation;
49 static int8_t midi_modulation_step;
50 static uint16_t midi_modulation_timer;
51 midi_config_t midi_config;
52
53 inline uint8_t compute_velocity(uint8_t setting)
54 {
55     return (setting + 1) * (128 / (MIDI_VELOCITY_MAX - MIDI_VELOCITY_MIN + 1));
56 }
57
58 void midi_init(void)
59 {
60     midi_config.octave = MI_OCT_2 - MIDI_OCTAVE_MIN;
61     midi_config.transpose = 0;
62     midi_config.velocity = (MIDI_VELOCITY_MAX - MIDI_VELOCITY_MIN);
63     midi_config.channel = 0;
64     midi_config.modulation_interval = 8;
65
66     for (uint8_t i = 0; i < MIDI_TONE_COUNT; i++)
67     {
68         tone_status[i] = MIDI_INVALID_NOTE;
69     }
70
71     midi_modulation = 0;
72     midi_modulation_step = 0;
73     midi_modulation_timer = 0;
74 }
75
76 uint8_t midi_compute_note(uint16_t keycode)
77 {
78     return 12 * midi_config.octave + (keycode - MIDI_TONE_MIN) + midi_config.transpose;
79 }
80
81 bool process_midi(uint16_t keycode, keyrecord_t *record)
82 {
83     switch (keycode) {
84         case MIDI_TONE_MIN ... MIDI_TONE_MAX:
85         {
86             uint8_t channel = midi_config.channel;
87             uint8_t tone = keycode - MIDI_TONE_MIN;
88             uint8_t velocity = compute_velocity(midi_config.velocity);
89             if (record->event.pressed) {
90                 uint8_t note = midi_compute_note(keycode);
91                 midi_send_noteon(&midi_device, channel, note, velocity);
92                 dprintf("midi noteon channel:%d note:%d velocity:%d\n", channel, note, velocity);
93                 tone_status[tone] = note;
94             }
95             else {
96                 uint8_t note = tone_status[tone];
97                 if (note != MIDI_INVALID_NOTE)
98                 {
99                     midi_send_noteoff(&midi_device, channel, note, velocity);
100                     dprintf("midi noteoff channel:%d note:%d velocity:%d\n", channel, note, velocity);
101                 }
102                 tone_status[tone] = MIDI_INVALID_NOTE;
103             }
104             return false;
105         }
106         case MIDI_OCTAVE_MIN ... MIDI_OCTAVE_MAX:
107             if (record->event.pressed) {
108                 midi_config.octave = keycode - MIDI_OCTAVE_MIN;
109                 dprintf("midi octave %d\n", midi_config.octave);
110             }
111             return false;
112         case MI_OCTD:
113             if (record->event.pressed && midi_config.octave > 0) {
114                 midi_config.octave--;
115                 dprintf("midi octave %d\n", midi_config.octave);
116             }
117             return false;
118         case MI_OCTU:
119             if (record->event.pressed && midi_config.octave < (MIDI_OCTAVE_MAX - MIDI_OCTAVE_MIN)) {
120                 midi_config.octave++;
121                 dprintf("midi octave %d\n", midi_config.octave);
122             }
123             return false;
124         case MIDI_TRANSPOSE_MIN ... MIDI_TRANSPOSE_MAX:
125             if (record->event.pressed) {
126                 midi_config.transpose = keycode - MI_TRNS_0;
127                 dprintf("midi transpose %d\n", midi_config.transpose);
128             }
129             return false;
130         case MI_TRNSD:
131             if (record->event.pressed && midi_config.transpose > (MIDI_TRANSPOSE_MIN - MI_TRNS_0)) {
132                 midi_config.transpose--;
133                 dprintf("midi transpose %d\n", midi_config.transpose);
134             }
135             return false;
136         case MI_TRNSU:
137             if (record->event.pressed && midi_config.transpose < (MIDI_TRANSPOSE_MAX - MI_TRNS_0)) {
138                 const bool positive = midi_config.transpose > 0;
139                 midi_config.transpose++;
140                 if (positive && midi_config.transpose < 0)
141                     midi_config.transpose--;
142                 dprintf("midi transpose %d\n", midi_config.transpose);
143             }
144             return false;
145         case MIDI_VELOCITY_MIN ... MIDI_VELOCITY_MAX:
146             if (record->event.pressed) {
147                 midi_config.velocity = keycode - MIDI_VELOCITY_MIN;
148                 dprintf("midi velocity %d\n", midi_config.velocity);
149             }
150             return false;
151         case MI_VELD:
152             if (record->event.pressed && midi_config.velocity > 0) {
153                 midi_config.velocity--;
154                 dprintf("midi velocity %d\n", midi_config.velocity);
155             }
156             return false;
157         case MI_VELU:
158             if (record->event.pressed) {
159                 midi_config.velocity++;
160                 dprintf("midi velocity %d\n", midi_config.velocity);
161             }
162             return false;
163         case MIDI_CHANNEL_MIN ... MIDI_CHANNEL_MAX:
164             if (record->event.pressed) {
165                 midi_config.channel = keycode - MIDI_CHANNEL_MIN;
166                 dprintf("midi channel %d\n", midi_config.channel);
167             }
168             return false;
169         case MI_CHD:
170             if (record->event.pressed) {
171                 midi_config.channel--;
172                 dprintf("midi channel %d\n", midi_config.channel);
173             }
174             return false;
175         case MI_CHU:
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_ALLOFF:
182             if (record->event.pressed) {
183                 midi_send_cc(&midi_device, midi_config.channel, 0x7B, 0);
184                 dprintf("midi all notes off\n");
185             }
186             return false;
187         case MI_SUS:
188             midi_send_cc(&midi_device, midi_config.channel, 0x40, record->event.pressed ? 127 : 0);
189             dprintf("midi sustain %d\n", record->event.pressed);
190             return false;
191         case MI_PORT:
192             midi_send_cc(&midi_device, midi_config.channel, 0x41, record->event.pressed ? 127 : 0);
193             dprintf("midi portamento %d\n", record->event.pressed);
194             return false;
195         case MI_SOST:
196             midi_send_cc(&midi_device, midi_config.channel, 0x42, record->event.pressed ? 127 : 0);
197             dprintf("midi sostenuto %d\n", record->event.pressed);
198             return false;
199         case MI_SOFT:
200             midi_send_cc(&midi_device, midi_config.channel, 0x43, record->event.pressed ? 127 : 0);
201             dprintf("midi soft %d\n", record->event.pressed);
202             return false;
203         case MI_LEG:
204             midi_send_cc(&midi_device, midi_config.channel, 0x43, record->event.pressed ? 127 : 0);
205             dprintf("midi legato %d\n", record->event.pressed);
206             return false;
207         case MI_MOD:
208             midi_modulation_step = record->event.pressed ? 1 : -1;
209             return false;
210         case MI_MODSD:
211             if (record->event.pressed) {
212                 midi_config.modulation_interval++;
213                 // prevent overflow
214                 if (midi_config.modulation_interval == 0)
215                     midi_config.modulation_interval--;
216                 dprintf("midi modulation interval %d\n", midi_config.modulation_interval);
217             }
218             return false;
219         case MI_MODSU:
220             if (record->event.pressed && 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_BENDD:
226             if (record->event.pressed) {
227                 midi_send_pitchbend(&midi_device, midi_config.channel, -0x2000);
228                 dprintf("midi pitchbend channel:%d amount:%d\n", midi_config.channel, -0x2000);
229             }
230             else {
231                 midi_send_pitchbend(&midi_device, midi_config.channel, 0);
232                 dprintf("midi pitchbend channel:%d amount:%d\n", midi_config.channel, 0);
233             }
234             return false;
235         case MI_BENDU:
236             if (record->event.pressed) {
237                 midi_send_pitchbend(&midi_device, midi_config.channel, 0x1fff);
238                 dprintf("midi pitchbend channel:%d amount:%d\n", midi_config.channel, 0x1fff);
239             }
240             else {
241                 midi_send_pitchbend(&midi_device, midi_config.channel, 0);
242                 dprintf("midi pitchbend channel:%d amount:%d\n", midi_config.channel, 0);
243             }
244             return false;
245     };
246
247     return true;
248 }
249
250 #endif // MIDI_ADVANCED
251
252 void midi_task(void)
253 {
254     midi_device_process(&midi_device);
255 #ifdef MIDI_ADVANCED
256     if (timer_elapsed(midi_modulation_timer) < midi_config.modulation_interval)
257         return;
258     midi_modulation_timer = timer_read();
259
260     if (midi_modulation_step != 0)
261     {
262         dprintf("midi modulation %d\n", midi_modulation);
263         midi_send_cc(&midi_device, midi_config.channel, 0x1, midi_modulation);
264
265         if (midi_modulation_step < 0 && midi_modulation < -midi_modulation_step) {
266             midi_modulation = 0;
267             midi_modulation_step = 0;
268             return;
269         }
270
271         midi_modulation += midi_modulation_step;
272
273         if (midi_modulation > 127)
274             midi_modulation = 127;
275     }
276 #endif
277 }
278
279
280
281 #endif // MIDI_ENABLE