Line data Source code
1 : #include "USBMIDI_Parser.hpp" 2 : #include <Settings/SettingsWrapper.hpp> 3 : 4 : BEGIN_CS_NAMESPACE 5 : 6 : // http://www.usb.org/developers/docs/devclass_docs/midi10.pdf 7 28 : MIDI_read_t USBMIDI_Parser::parse(uint8_t *packet) { 8 28 : DEBUG("MIDIUSB packet:\t" << hex << packet[0] << ' ' << packet[1] << ' ' 9 : << packet[2] << ' ' << packet[3] << dec); 10 28 : this->CN = (uint8_t)packet[0] >> 4; 11 28 : uint8_t CIN = (uint8_t)packet[0] << 4; // MIDI USB code index number 12 : 13 28 : if (CIN >= NOTE_OFF && CIN <= PITCH_BEND) { 14 : // 2- or 3-byte MIDI event 15 : 16 : // uint8_t type = packet[1] & 0xF0; 17 : // if (CIN != type) // invalid MIDI USB packet 18 : // return NO_MESSAGE; 19 4 : midimsg.header = packet[1]; 20 4 : midimsg.data1 = packet[2]; 21 4 : midimsg.data2 = packet[3]; 22 4 : midimsg.CN = this->CN; 23 4 : return CHANNEL_MESSAGE; 24 : } 25 : 26 : #if !IGNORE_SYSEX 27 24 : else if (CIN == 0x40) { 28 : // SysEx starts or continues (3 bytes) 29 10 : if (packet[1] == SysExStart) 30 6 : startSysEx(CN); // start a new message 31 : // (overwrite previous unfinished message) 32 4 : else if (!receivingSysEx(CN)) { // If we haven't received a SysExStart 33 0 : DEBUGREF(F("Error: No SysExStart received")); 34 0 : return NO_MESSAGE; // ignore the data 35 : } 36 10 : addSysExByte(CN, packet[1]) && // add three data bytes to buffer 37 10 : addSysExByte(CN, packet[2]) && addSysExByte(CN, packet[3]); 38 10 : return NO_MESSAGE; // SysEx is not finished yet 39 : } 40 : 41 14 : else if (CIN == 0x50) { 42 : // SysEx ends with following single byte 43 : // (or Single-byte System Common Message, not implemented) 44 3 : if (packet[1] != SysExEnd) { // System Common (not implemented) 45 0 : return NO_MESSAGE; 46 3 : } else if (!receivingSysEx(CN)) { // If we haven't received a SysExStart 47 1 : DEBUGFN(F("Error: No SysExStart received")); 48 1 : return NO_MESSAGE; // ignore the data 49 : } 50 2 : if (addSysExByte(CN, SysExEnd)) { 51 2 : endSysEx(CN); 52 2 : return SYSEX_MESSAGE; 53 : } else 54 0 : return NO_MESSAGE; // Buffer full, ignore message 55 : } 56 : 57 11 : else if (CIN == 0x60) { 58 : // SysEx ends with following two bytes 59 4 : if (packet[1] == SysExStart) 60 1 : startSysEx(CN); // start a new message 61 : // (overwrite previous unfinished message) 62 3 : else if (!receivingSysEx(CN)) { // If we haven't received a SysExStart 63 1 : DEBUGFN(F("Error: No SysExStart received")); 64 1 : return NO_MESSAGE; // ignore the data 65 : } 66 : if ( // add two data bytes to buffer 67 3 : addSysExByte(CN, packet[1]) && addSysExByte(CN, SysExEnd)) { 68 3 : endSysEx(CN); 69 3 : return SYSEX_MESSAGE; 70 : } else 71 0 : return NO_MESSAGE; // Buffer full, ignore message 72 : } 73 : 74 7 : else if (CIN == 0x70) { 75 : // SysEx ends with following three bytes 76 5 : if (packet[1] == SysExStart) 77 1 : startSysEx(CN); // start a new message 78 : // (overwrite previous unfinished message) 79 4 : else if (!receivingSysEx(CN)) { // If we haven't received a SysExStart 80 2 : DEBUGFN(F("Error: No SysExStart received")); 81 2 : return NO_MESSAGE; // ignore the data 82 : } 83 : if ( // add three data bytes to buffer 84 3 : addSysExByte(CN, packet[1]) && addSysExByte(CN, packet[2]) && 85 3 : addSysExByte(CN, SysExEnd)) { 86 3 : endSysEx(CN); 87 3 : return SYSEX_MESSAGE; 88 : } else 89 0 : return NO_MESSAGE; // Buffer full, ignore message 90 : } 91 : #endif // IGNORE_SYSEX 92 : 93 : /* 94 : else if (CIN == 0x00) // Miscellaneous function codes. Reserved for future extensions. (not implemented) 95 : ; 96 : else if (CIN == 0x10) // Cable events. Reserved for future expansion. (not implemented) 97 : ; 98 : else if (CIN == 0x20) // Two-byte System Common message (not implemented) 99 : ; 100 : else if (CIN == 0x30) // Three-byte System Common message (not implemented) 101 : ; 102 : */ 103 2 : else if (CIN == 0xF0) // Single Byte 104 2 : return static_cast<MIDI_read_t>(packet[1]); 105 : 106 0 : return NO_MESSAGE; 107 28 : } 108 : 109 : END_CS_NAMESPACE