aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGabriel Young <gabeplaysdrums@live.com>2017-02-18 03:12:13 -0800
committerGabriel Young <gabeplaysdrums@live.com>2017-02-19 16:41:59 -0800
commite405ab4bc6ff47d189d99c4d51aadf60a642d82a (patch)
tree60d81499162c5a8a6d5e479f2acb2bba7dfe3392
parent5ae1411fc387a682d3e22f5cddfe1102e3312af5 (diff)
downloadqmk_firmware-e405ab4bc6ff47d189d99c4d51aadf60a642d82a.tar.gz
qmk_firmware-e405ab4bc6ff47d189d99c4d51aadf60a642d82a.zip
initial implementation of polyphony using variable length array of notes on
-rw-r--r--quantum/process_keycode/process_midi.c199
-rw-r--r--quantum/process_keycode/process_midi.h3
-rw-r--r--quantum/quantum_keycodes.h1
-rw-r--r--tmk_core/protocol/lufa/lufa.c13
-rw-r--r--tmk_core/protocol/lufa/lufa.h2
5 files changed, 211 insertions, 7 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
3bool midi_activated = false; 4bool midi_activated = false;
4uint8_t midi_starting_note = 0x0C; 5uint8_t midi_starting_note = 0x0C;
5int midi_offset = 7; 6int midi_offset = 7;
7#endif
8
9typedef 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
18midi_config_t midi_config;
19
20#define MIDI_INVALID_NOTE 0xFF
21
22#if 0
23typedef struct {
24 uint64_t low;
25 uint64_t high;
26} uint128_t;
27
28#if 0
29static 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
38static 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
51static 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
70static 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
7bool process_midi(uint16_t keycode, keyrecord_t *record) { 82static 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
94uint128_t note_status = { 0, 0 };
95#endif
96
97
98#define MIDI_MAX_NOTES_ON 10
99
100typedef struct {
101 uint8_t note;
102 uint8_t tone;
103} midi_notes_on_array_entry_t;
104
105typedef struct {
106 uint8_t length;
107 midi_notes_on_array_entry_t values[MIDI_MAX_NOTES_ON];
108} midi_notes_on_array_t;
109
110static midi_notes_on_array_t notes_on;
111
112inline uint8_t compute_velocity(uint8_t setting)
113{
114 return (setting + 1) * (128 / (MIDI_VELOCITY_MAX - MIDI_VELOCITY_MIN + 1));
115}
116
117void 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
125bool 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
7void midi_init(void);
5 8
6bool process_midi(uint16_t keycode, keyrecord_t *record); 9bool 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,
diff --git a/tmk_core/protocol/lufa/lufa.c b/tmk_core/protocol/lufa/lufa.c
index ba49284c9..fb60658df 100644
--- a/tmk_core/protocol/lufa/lufa.c
+++ b/tmk_core/protocol/lufa/lufa.c
@@ -1101,16 +1101,21 @@ void cc_callback(MidiDevice * device,
1101 uint8_t chan, uint8_t num, uint8_t val); 1101 uint8_t chan, uint8_t num, uint8_t val);
1102void sysex_callback(MidiDevice * device, 1102void sysex_callback(MidiDevice * device,
1103 uint16_t start, uint8_t length, uint8_t * data); 1103 uint16_t start, uint8_t length, uint8_t * data);
1104
1105void setup_midi(void)
1106{
1107 midi_init();
1108 midi_device_init(&midi_device);
1109 midi_device_set_send_func(&midi_device, usb_send_func);
1110 midi_device_set_pre_input_process_func(&midi_device, usb_get_midi);
1111}
1104#endif 1112#endif
1105 1113
1106int main(void) __attribute__ ((weak)); 1114int main(void) __attribute__ ((weak));
1107int main(void) 1115int main(void)
1108{ 1116{
1109
1110#ifdef MIDI_ENABLE 1117#ifdef MIDI_ENABLE
1111 midi_device_init(&midi_device); 1118 setup_midi();
1112 midi_device_set_send_func(&midi_device, usb_send_func);
1113 midi_device_set_pre_input_process_func(&midi_device, usb_get_midi);
1114#endif 1119#endif
1115 1120
1116 setup_mcu(); 1121 setup_mcu();
diff --git a/tmk_core/protocol/lufa/lufa.h b/tmk_core/protocol/lufa/lufa.h
index a049fd43c..a51573786 100644
--- a/tmk_core/protocol/lufa/lufa.h
+++ b/tmk_core/protocol/lufa/lufa.h
@@ -49,7 +49,7 @@
49#include <LUFA/Drivers/USB/USB.h> 49#include <LUFA/Drivers/USB/USB.h>
50#include "host.h" 50#include "host.h"
51#ifdef MIDI_ENABLE 51#ifdef MIDI_ENABLE
52 #include "midi.h" 52 #include "process_midi.h"
53#endif 53#endif
54#ifdef __cplusplus 54#ifdef __cplusplus
55extern "C" { 55extern "C" {