1 #include <LUFA/Drivers/USB/USB.h>
3 #include "sysex_tools.h"
5 #include "usb_descriptor.h"
6 #include "process_midi.h"
11 /*******************************************************************************
13 ******************************************************************************/
15 MidiDevice midi_device;
17 #define SYSEX_START_OR_CONT 0x40
18 #define SYSEX_ENDS_IN_1 0x50
19 #define SYSEX_ENDS_IN_2 0x60
20 #define SYSEX_ENDS_IN_3 0x70
22 #define SYS_COMMON_1 0x50
23 #define SYS_COMMON_2 0x20
24 #define SYS_COMMON_3 0x30
26 static void usb_send_func(MidiDevice * device, uint16_t cnt, uint8_t byte0, uint8_t byte1, uint8_t byte2) {
27 MIDI_EventPacket_t event;
34 //if the length is undefined we assume it is a SYSEX message
35 if (midi_packet_length(byte0) == UNDEFINED) {
38 if (byte2 == SYSEX_END)
39 event.Event = MIDI_EVENT(cable, SYSEX_ENDS_IN_3);
41 event.Event = MIDI_EVENT(cable, SYSEX_START_OR_CONT);
44 if (byte1 == SYSEX_END)
45 event.Event = MIDI_EVENT(cable, SYSEX_ENDS_IN_2);
47 event.Event = MIDI_EVENT(cable, SYSEX_START_OR_CONT);
50 if (byte0 == SYSEX_END)
51 event.Event = MIDI_EVENT(cable, SYSEX_ENDS_IN_1);
53 event.Event = MIDI_EVENT(cable, SYSEX_START_OR_CONT);
59 //deal with 'system common' messages
60 //TODO are there any more?
62 case MIDI_SONGPOSITION:
63 event.Event = MIDI_EVENT(cable, SYS_COMMON_3);
66 case MIDI_TC_QUARTERFRAME:
67 event.Event = MIDI_EVENT(cable, SYS_COMMON_2);
70 event.Event = MIDI_EVENT(cable, byte0);
75 send_midi_packet(&event);
78 static void usb_get_midi(MidiDevice * device) {
79 MIDI_EventPacket_t event;
80 while (recv_midi_packet(&event)) {
82 midi_packet_length_t length = midi_packet_length(event.Data1);
84 input[0] = event.Data1;
85 input[1] = event.Data2;
86 input[2] = event.Data3;
87 if (length == UNDEFINED) {
89 if (event.Event == MIDI_EVENT(0, SYSEX_START_OR_CONT) || event.Event == MIDI_EVENT(0, SYSEX_ENDS_IN_3)) {
91 } else if (event.Event == MIDI_EVENT(0, SYSEX_ENDS_IN_2)) {
93 } else if(event.Event == MIDI_EVENT(0, SYSEX_ENDS_IN_1)) {
100 //pass the data to the device input function
101 if (length != UNDEFINED)
102 midi_device_input(device, length, input);
106 static void fallthrough_callback(MidiDevice * device,
107 uint16_t cnt, uint8_t byte0, uint8_t byte1, uint8_t byte2){
111 switch (byte0 & 0xF0) {
113 play_note(((double)261.6)*pow(2.0, -4.0)*pow(2.0,(byte1 & 0x7F)/12.0), (byte2 & 0x7F) / 8);
116 stop_note(((double)261.6)*pow(2.0, -4.0)*pow(2.0,(byte1 & 0x7F)/12.0));
120 if (byte0 == MIDI_STOP) {
127 static void cc_callback(MidiDevice * device,
128 uint8_t chan, uint8_t num, uint8_t val) {
129 //sending it back on the next channel
130 // midi_send_cc(device, (chan + 1) % 16, num, val);
133 #ifdef API_SYSEX_ENABLE
134 uint8_t midi_buffer[MIDI_SYSEX_BUFFER] = {0};
136 static void sysex_callback(MidiDevice * device, uint16_t start, uint8_t length, uint8_t * data) {
137 // SEND_STRING("\n");
139 // SEND_STRING(": ");
140 // Don't store the header
141 int16_t pos = start - 4;
142 for (uint8_t place = 0; place < length; place++) {
146 // SEND_STRING("\nRD: ");
147 // for (uint8_t i = 0; i < start + place + 1; i++){
148 // send_byte(midi_buffer[i]);
151 const unsigned decoded_length = sysex_decoded_length(pos);
152 uint8_t decoded[API_SYSEX_MAX_SIZE];
153 sysex_decode(decoded, midi_buffer, pos);
154 process_api(decoded_length, decoded);
157 else if (pos >= MIDI_SYSEX_BUFFER) {
160 midi_buffer[pos] = *data;
169 void midi_init(void);
171 void setup_midi(void)
176 midi_device_init(&midi_device);
177 midi_device_set_send_func(&midi_device, usb_send_func);
178 midi_device_set_pre_input_process_func(&midi_device, usb_get_midi);
179 midi_register_fallthrough_callback(&midi_device, fallthrough_callback);
180 midi_register_cc_callback(&midi_device, cc_callback);
181 #ifdef API_SYSEX_ENABLE
182 midi_register_sysex_callback(&midi_device, sysex_callback);