Line data Source code
1 : #include "SerialMIDI_Parser.hpp" 2 : 3 : BEGIN_CS_NAMESPACE 4 : 5 459 : MIDI_read_t SerialMIDI_Parser::parse(uint8_t midiByte) { 6 459 : DEBUGFN(hex << NAMEDVALUE(midiByte) << dec); 7 : #if !IGNORE_SYSEX 8 : // If the previous byte was a SysExStart 9 : // I have to handle a start in the next time step, because a start can also 10 : // end the previous message. When that happens, I have to return 11 : // SYSEX_MESSAGE without resetting the buffer. 12 : // Then, after handling the message by the user, I do have to reset the 13 : // buffer. 14 459 : if (midimsg.header == SysExStart && !sysexbuffer.isReceiving()) { 15 25 : startSysEx(); 16 25 : addSysExByte(SysExStart); 17 25 : } 18 : #endif 19 459 : if (isStatus(midiByte)) { 20 : // If it's a status byte (first byte) 21 91 : if (midiByte >= 0xF8) { 22 : // If it's a Real-Time message 23 8 : return static_cast<MIDI_read_t>(midiByte); 24 : } else { 25 : // Normal header 26 83 : uint8_t previousHeader = midimsg.header; 27 83 : midimsg.header = midiByte; 28 83 : thirdByte = false; 29 : #if !IGNORE_SYSEX 30 83 : if (midimsg.header == TuneRequest) { 31 : ; // Tune request (not implemented) 32 0 : } 33 83 : if (previousHeader == SysExStart) { 34 : // If we're currently receiving a SysEx message 35 25 : addSysExByte(SysExEnd); // Try to add SysExEnd byte to buffer 36 : // Even if the buffer is full, end the message anyway 37 25 : endSysEx(); 38 25 : return SYSEX_MESSAGE; 39 : } 40 : #else 41 : (void)previousHeader; 42 : #endif // IGNORE_SYSEX 43 : } 44 58 : } else { 45 : // If it's a data byte 46 368 : if (midimsg.header == 0) { 47 3 : DEBUGFN("Warning: No header"); 48 : ; // Ignore 49 368 : } else if (thirdByte) { 50 : // Third byte of three (data 2) 51 23 : midimsg.data2 = midiByte; 52 23 : thirdByte = false; 53 23 : return CHANNEL_MESSAGE; 54 : } else { 55 : // Second byte (data 1) or SysEx data 56 342 : if (midimsg.header < 0xC0 || midimsg.header == 0xE0) { 57 : // Note, Aftertouch, CC or Pitch Bend 58 23 : midimsg.data1 = midiByte; 59 23 : thirdByte = true; 60 342 : } else if (midimsg.header < 0xE0) { 61 : // Program Change or Channel Pressure 62 6 : midimsg.data1 = midiByte; 63 6 : return CHANNEL_MESSAGE; 64 : } 65 : #if !IGNORE_SYSEX 66 313 : else if (midimsg.header == SysExStart) { 67 : // SysEx data byte 68 307 : addSysExByte(midiByte); 69 307 : } 70 : #endif // IGNORE_SYSEX 71 : else { 72 6 : DEBUGFN("Data byte ignored"); 73 : } 74 : } 75 : } 76 397 : return NO_MESSAGE; 77 459 : } 78 : 79 : END_CS_NAMESPACE