diff options
author | Gabriel Young <gabeplaysdrums@live.com> | 2017-02-18 03:12:13 -0800 |
---|---|---|
committer | Gabriel Young <gabeplaysdrums@live.com> | 2017-02-19 16:41:59 -0800 |
commit | e405ab4bc6ff47d189d99c4d51aadf60a642d82a (patch) | |
tree | 60d81499162c5a8a6d5e479f2acb2bba7dfe3392 /quantum | |
parent | 5ae1411fc387a682d3e22f5cddfe1102e3312af5 (diff) | |
download | qmk_firmware-e405ab4bc6ff47d189d99c4d51aadf60a642d82a.tar.gz qmk_firmware-e405ab4bc6ff47d189d99c4d51aadf60a642d82a.zip |
initial implementation of polyphony using variable length array of notes on
Diffstat (limited to 'quantum')
-rw-r--r-- | quantum/process_keycode/process_midi.c | 199 | ||||
-rw-r--r-- | quantum/process_keycode/process_midi.h | 3 | ||||
-rw-r--r-- | quantum/quantum_keycodes.h | 1 |
3 files changed, 201 insertions, 2 deletions
diff --git a/quantum/process_keycode/process_midi.c b/quantum/process_keycode/process_midi.c index 577dad43a..bc48b3905 100644 --- a/quantum/process_keycode/process_midi.c +++ b/quantum/process_keycode/process_midi.c | |||
@@ -1,10 +1,204 @@ | |||
1 | #include "process_midi.h" | 1 | #include "process_midi.h" |
2 | 2 | ||
3 | #if 0 | ||
3 | bool midi_activated = false; | 4 | bool midi_activated = false; |
4 | uint8_t midi_starting_note = 0x0C; | 5 | uint8_t midi_starting_note = 0x0C; |
5 | int midi_offset = 7; | 6 | int midi_offset = 7; |
7 | #endif | ||
8 | |||
9 | typedef union { | ||
10 | uint16_t raw; | ||
11 | struct { | ||
12 | uint8_t octave :4; | ||
13 | uint8_t velocity :4; | ||
14 | uint8_t channel :4; | ||
15 | }; | ||
16 | } midi_config_t; | ||
17 | |||
18 | midi_config_t midi_config; | ||
19 | |||
20 | #define MIDI_INVALID_NOTE 0xFF | ||
21 | |||
22 | #if 0 | ||
23 | typedef struct { | ||
24 | uint64_t low; | ||
25 | uint64_t high; | ||
26 | } uint128_t; | ||
27 | |||
28 | #if 0 | ||
29 | static void right_shift_uint128_t(uint128_t* val, uint8_t shift) | ||
30 | { | ||
31 | uint64_t high_mask = ~0 >> (64 - shift); | ||
32 | uint64_t high_bits = (val->high & high_mask) << (64 - shift); | ||
33 | val->high = val->high >> shift; | ||
34 | val->low = (val->low >> shift) | high_bits; | ||
35 | } | ||
36 | #endif | ||
37 | |||
38 | static uint64_t left_shift_uint64_t(uint64_t val, uint8_t shift) | ||
39 | { | ||
40 | dprintf("left_shift_uint64_t(val, %c) ...\n", val, shift); | ||
41 | while (shift > 16u) { | ||
42 | dprintf(" left_shift_uint64_t: val=?, shift=%c\n", val, shift); | ||
43 | val <<= 16; | ||
44 | shift -= 16; | ||
45 | } | ||
46 | dprintf(" left_shift_uint64_t: val=?, shift=%c\n", val, shift); | ||
47 | val <<= shift; | ||
48 | return val; | ||
49 | } | ||
50 | |||
51 | static void set_bit_uint128_t(uint128_t* val, uint8_t shift) | ||
52 | { | ||
53 | uint64_t x = 1u; | ||
54 | |||
55 | if (shift < 64) | ||
56 | { | ||
57 | x = left_shift_uint64_t(x, shift); | ||
58 | dprintf("x: %d\n", x); | ||
59 | dprintf("set_bit_uint128_t (%d): 0x%016X%016X\n", shift, 0, x); | ||
60 | val->low = val->low | left_shift_uint64_t(1u, shift); | ||
61 | } | ||
62 | else | ||
63 | { | ||
64 | x = left_shift_uint64_t(x, shift - 64); | ||
65 | dprintf("set_bit_uint128_t (%d): 0x%016X%016X\n", shift, x, 0); | ||
66 | val->high = val->high | left_shift_uint64_t(1u, shift - 64); | ||
67 | } | ||
68 | } | ||
69 | |||
70 | static void clear_bit_uint128_t(uint128_t* val, uint8_t shift) | ||
71 | { | ||
72 | if (shift < 64) | ||
73 | { | ||
74 | val->low = val->low & ~left_shift_uint64_t(1u, shift); | ||
75 | } | ||
76 | else | ||
77 | { | ||
78 | val->high = val->high & ~left_shift_uint64_t(1u, shift - 64); | ||
79 | } | ||
80 | } | ||
6 | 81 | ||
7 | bool process_midi(uint16_t keycode, keyrecord_t *record) { | 82 | static bool is_bit_set_uint128_t(const uint128_t* val, uint8_t shift) |
83 | { | ||
84 | if (shift < 64) | ||
85 | { | ||
86 | return !!(val->low & (1u << shift)); | ||
87 | } | ||
88 | else | ||
89 | { | ||
90 | return !!(val->high & (1u << (shift - 64))); | ||
91 | } | ||
92 | } | ||
93 | |||
94 | uint128_t note_status = { 0, 0 }; | ||
95 | #endif | ||
96 | |||
97 | |||
98 | #define MIDI_MAX_NOTES_ON 10 | ||
99 | |||
100 | typedef struct { | ||
101 | uint8_t note; | ||
102 | uint8_t tone; | ||
103 | } midi_notes_on_array_entry_t; | ||
104 | |||
105 | typedef struct { | ||
106 | uint8_t length; | ||
107 | midi_notes_on_array_entry_t values[MIDI_MAX_NOTES_ON]; | ||
108 | } midi_notes_on_array_t; | ||
109 | |||
110 | static midi_notes_on_array_t notes_on; | ||
111 | |||
112 | inline uint8_t compute_velocity(uint8_t setting) | ||
113 | { | ||
114 | return (setting + 1) * (128 / (MIDI_VELOCITY_MAX - MIDI_VELOCITY_MIN + 1)); | ||
115 | } | ||
116 | |||
117 | void midi_init(void) | ||
118 | { | ||
119 | midi_config.octave = MI_OCT_0 - MIDI_OCTAVE_MIN; | ||
120 | midi_config.velocity = (MIDI_VELOCITY_MAX - MIDI_VELOCITY_MIN); | ||
121 | midi_config.channel = 0; | ||
122 | notes_on.length = 0; | ||
123 | } | ||
124 | |||
125 | bool process_midi(uint16_t keycode, keyrecord_t *record) | ||
126 | { | ||
127 | switch (keycode) { | ||
128 | case MIDI_TONE_MIN ... MIDI_TONE_MAX: | ||
129 | { | ||
130 | uint8_t channel = midi_config.channel; | ||
131 | uint8_t tone = keycode - MIDI_TONE_MIN; | ||
132 | uint8_t velocity = compute_velocity(midi_config.velocity); | ||
133 | if (record->event.pressed && notes_on.length < MIDI_MAX_NOTES_ON) { | ||
134 | uint8_t note = 12 * midi_config.octave + tone; | ||
135 | midi_send_noteon(&midi_device, channel, note, velocity); | ||
136 | dprintf("midi noteon channel:%d note:%d velocity:%d\n", channel, note, velocity); | ||
137 | notes_on.values[notes_on.length].note = note; | ||
138 | notes_on.values[notes_on.length].tone = tone; | ||
139 | notes_on.length++; | ||
140 | } | ||
141 | else { | ||
142 | for (uint8_t i = 0; i < notes_on.length; i++) { | ||
143 | uint8_t note = notes_on.values[i].note; | ||
144 | if (tone == notes_on.values[i].tone) { | ||
145 | midi_send_noteoff(&midi_device, channel, note, velocity); | ||
146 | dprintf("midi noteoff channel:%d note:%d velocity:%d\n", channel, note, velocity); | ||
147 | |||
148 | for (uint8_t j=i; j < notes_on.length - 1; j++) | ||
149 | { | ||
150 | notes_on.values[j] = notes_on.values[j + 1]; | ||
151 | } | ||
152 | |||
153 | notes_on.length--; | ||
154 | break; | ||
155 | } | ||
156 | } | ||
157 | } | ||
158 | return false; | ||
159 | } | ||
160 | case MIDI_OCTAVE_MIN ... MIDI_OCTAVE_MAX: | ||
161 | if (record->event.pressed) | ||
162 | midi_config.octave = keycode - MIDI_OCTAVE_MIN; | ||
163 | return false; | ||
164 | case MI_OCTD: | ||
165 | if (record->event.pressed && midi_config.octave > 0) | ||
166 | midi_config.octave--; | ||
167 | return false; | ||
168 | case MI_OCTU: | ||
169 | if (record->event.pressed && midi_config.octave < (MIDI_OCTAVE_MAX - MIDI_OCTAVE_MIN)) | ||
170 | midi_config.octave++; | ||
171 | return false; | ||
172 | case MIDI_VELOCITY_MIN ... MIDI_VELOCITY_MAX: | ||
173 | if (record->event.pressed) | ||
174 | midi_config.velocity = keycode - MIDI_VELOCITY_MIN; | ||
175 | return false; | ||
176 | case MI_VELD: | ||
177 | if (record->event.pressed && midi_config.velocity > 0) | ||
178 | midi_config.velocity--; | ||
179 | return false; | ||
180 | case MI_VELU: | ||
181 | if (record->event.pressed) | ||
182 | midi_config.velocity++; | ||
183 | return false; | ||
184 | case MIDI_CHANNEL_MIN ... MIDI_CHANNEL_MAX: | ||
185 | if (record->event.pressed) | ||
186 | midi_config.channel = keycode - MIDI_CHANNEL_MIN; | ||
187 | return false; | ||
188 | case MI_CHD: | ||
189 | if (record->event.pressed) | ||
190 | midi_config.channel--; | ||
191 | return false; | ||
192 | case MI_CHU: | ||
193 | if (record->event.pressed) | ||
194 | midi_config.channel++; | ||
195 | return false; | ||
196 | case MI_SUS: | ||
197 | //TODO | ||
198 | return false; | ||
199 | }; | ||
200 | |||
201 | #if 0 | ||
8 | if (keycode == MI_ON && record->event.pressed) { | 202 | if (keycode == MI_ON && record->event.pressed) { |
9 | midi_activated = true; | 203 | midi_activated = true; |
10 | #ifdef AUDIO_ENABLE | 204 | #ifdef AUDIO_ENABLE |
@@ -64,5 +258,6 @@ bool process_midi(uint16_t keycode, keyrecord_t *record) { | |||
64 | if (keycode < 0xFF) // ignores all normal keycodes, but lets RAISE, LOWER, etc through | 258 | if (keycode < 0xFF) // ignores all normal keycodes, but lets RAISE, LOWER, etc through |
65 | return false; | 259 | return false; |
66 | } | 260 | } |
67 | return true; | 261 | #endif |
262 | return true; | ||
68 | } | 263 | } |
diff --git a/quantum/process_keycode/process_midi.h b/quantum/process_keycode/process_midi.h index acd4fc1b1..b0e0aeb83 100644 --- a/quantum/process_keycode/process_midi.h +++ b/quantum/process_keycode/process_midi.h | |||
@@ -2,6 +2,9 @@ | |||
2 | #define PROCESS_MIDI_H | 2 | #define PROCESS_MIDI_H |
3 | 3 | ||
4 | #include "quantum.h" | 4 | #include "quantum.h" |
5 | #include "midi.h" | ||
6 | |||
7 | void midi_init(void); | ||
5 | 8 | ||
6 | bool process_midi(uint16_t keycode, keyrecord_t *record); | 9 | bool process_midi(uint16_t keycode, keyrecord_t *record); |
7 | 10 | ||
diff --git a/quantum/quantum_keycodes.h b/quantum/quantum_keycodes.h index 3728fa366..a024a9639 100644 --- a/quantum/quantum_keycodes.h +++ b/quantum/quantum_keycodes.h | |||
@@ -189,6 +189,7 @@ enum quantum_keycodes { | |||
189 | MI_VEL_1 = MIDI_VELOCITY_MIN, | 189 | MI_VEL_1 = MIDI_VELOCITY_MIN, |
190 | MI_VEL_2, | 190 | MI_VEL_2, |
191 | MI_VEL_3, | 191 | MI_VEL_3, |
192 | MI_VEL_4, | ||
192 | MI_VEL_5, | 193 | MI_VEL_5, |
193 | MI_VEL_6, | 194 | MI_VEL_6, |
194 | MI_VEL_7, | 195 | MI_VEL_7, |