Line data Source code
1 : #include "DebugMIDI_Interface.hpp" 2 : #include <AH/PrintStream/PrintStream.hpp> 3 : 4 : BEGIN_CS_NAMESPACE 5 : 6 : namespace DebugMIDIMessageNames { 7 : 8 : #ifdef PROGMEM 9 : 10 : const static char NoteOff[] PROGMEM = "Note Off "; 11 : const static char NoteOn[] PROGMEM = "Note On "; 12 : const static char KeyPressure[] PROGMEM = "Key Pressure "; 13 : const static char ControlChange[] PROGMEM = "Control Change "; 14 : const static char ProgramChange[] PROGMEM = "Program Change "; 15 : const static char ChannelPressure[] PROGMEM = "Channel Pressure"; 16 : const static char PitchBend[] PROGMEM = "Pitch Bend "; 17 : 18 : const static FlashString_t MIDIStatusTypeNames[] = { 19 : reinterpret_cast<FlashString_t>(NoteOff), 20 : reinterpret_cast<FlashString_t>(NoteOn), 21 : reinterpret_cast<FlashString_t>(KeyPressure), 22 : reinterpret_cast<FlashString_t>(ControlChange), 23 : reinterpret_cast<FlashString_t>(ProgramChange), 24 : reinterpret_cast<FlashString_t>(ChannelPressure), 25 : reinterpret_cast<FlashString_t>(PitchBend), 26 : }; 27 : 28 : #else 29 : 30 : const static char *MIDIStatusTypeNames[] = { 31 : "Note Off\t", "Note On\t\t", "Key Pressure\t", 32 : "Control Change\t", "Program Change\t", "Channel Pressure", 33 : "Pitch Bend\t", 34 : }; 35 : 36 : #endif 37 : 38 : } // namespace DebugMIDIMessageNames 39 : 40 4 : MIDIReadEvent StreamDebugMIDI_Interface::read() { 41 40 : while (stream.available() > 0) { 42 40 : char data = stream.read(); 43 : 44 40 : if (isxdigit(data)) { 45 : // if we receive a hexadecimal digit 46 29 : data = tolower(data); 47 29 : if (firstChar == '\0') { 48 15 : firstChar = data; 49 29 : } else if (secondChar == '\0') { 50 14 : secondChar = data; 51 14 : } 52 29 : } 53 40 : if (firstChar && secondChar) { 54 : // if we received two hex characters 55 28 : uint8_t midiByte = 56 14 : hexCharToNibble(firstChar) << 4 | hexCharToNibble(secondChar); 57 14 : firstChar = '\0'; 58 14 : secondChar = '\0'; 59 14 : MIDIReadEvent parseResult = parser.parse(midiByte); 60 14 : if (parseResult != MIDIReadEvent::NO_MESSAGE) 61 4 : return parseResult; 62 40 : } else if (!isxdigit(data) && firstChar) { 63 : // if we received one hex character followed by whitespace/other 64 1 : uint8_t midiByte = hexCharToNibble(firstChar); 65 1 : firstChar = '\0'; 66 1 : MIDIReadEvent parseResult = parser.parse(midiByte); 67 1 : if (parseResult != MIDIReadEvent::NO_MESSAGE) 68 0 : return parseResult; 69 1 : } else { 70 : // Ignore any characters other than whitespace and hexadecimal 71 : // digits 72 : } 73 40 : } 74 0 : return MIDIReadEvent::NO_MESSAGE; 75 4 : } 76 : 77 7 : void StreamDebugMIDI_Interface::sendImpl(uint8_t header, uint8_t d1, uint8_t d2, 78 : uint8_t cn) { 79 7 : uint8_t messageType = (header >> 4) - 8; 80 7 : if (messageType >= 7) 81 0 : return; 82 7 : uint8_t c = header & 0x0F; 83 7 : stream << DebugMIDIMessageNames::MIDIStatusTypeNames[messageType] 84 7 : << F("\tChannel: ") << (c + 1) << F("\tData 1: 0x") << hex << d1 85 7 : << F("\tData 2: 0x") << d2 << dec << F("\tCable: ") << (cn + 1) 86 7 : << endl; 87 7 : stream.flush(); 88 7 : } 89 : 90 5 : void StreamDebugMIDI_Interface::sendImpl(uint8_t header, uint8_t d1, 91 : uint8_t cn) { 92 5 : uint8_t messageType = (header >> 4) - 8; 93 5 : if (messageType >= 7) 94 0 : return; 95 5 : uint8_t c = header & 0x0F; 96 5 : stream << DebugMIDIMessageNames::MIDIStatusTypeNames[messageType] 97 5 : << F("\tChannel: ") << (c + 1) << F("\tData 1: 0x") << hex << d1 98 5 : << dec << F("\tCable: ") << (cn + 1) << endl; 99 5 : stream.flush(); 100 5 : } 101 : 102 1 : void StreamDebugMIDI_Interface::sendImpl(const uint8_t *data, size_t length, 103 : uint8_t cn) { 104 1 : stream << F("SysEx \t") << hex << uppercase; 105 9 : while (length-- > 0) 106 8 : stream << (*data++) << ' '; 107 1 : stream << dec << F("\tCable: ") << (cn + 1) << "\r\n"; 108 1 : stream.flush(); 109 1 : } 110 : 111 0 : void StreamDebugMIDI_Interface::sendImpl(uint8_t rt, uint8_t cn) { 112 0 : stream << F("Real-Time: 0x") << hex << rt << dec << F("\tCable: ") << cn 113 0 : << endl; 114 0 : stream.flush(); 115 0 : } 116 : 117 : END_CS_NAMESPACE