Control Surface  1.2.0
MIDI Control Surface library for Arduino
DebugMIDI_Interface.cpp
Go to the documentation of this file.
3 
5 
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 
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 
41  while (stream.available() > 0) {
42  char data = stream.read();
43 
44  if (isxdigit(data)) {
45  // if we receive a hexadecimal digit
46  data = tolower(data);
47  if (firstChar == '\0') {
48  firstChar = data;
49  } else if (secondChar == '\0') {
50  secondChar = data;
51  }
52  }
53  if (firstChar && secondChar) {
54  // if we received two hex characters
55  uint8_t midiByte =
57  firstChar = '\0';
58  secondChar = '\0';
59  MIDIReadEvent parseResult = parser.parse(midiByte);
60  if (parseResult != MIDIReadEvent::NO_MESSAGE)
61  return parseResult;
62  } else if (!isxdigit(data) && firstChar) {
63  // if we received one hex character followed by whitespace/other
64  uint8_t midiByte = hexCharToNibble(firstChar);
65  firstChar = '\0';
66  MIDIReadEvent parseResult = parser.parse(midiByte);
67  if (parseResult != MIDIReadEvent::NO_MESSAGE)
68  return parseResult;
69  } else {
70  // Ignore any characters other than whitespace and hexadecimal
71  // digits
72  }
73  }
74  return MIDIReadEvent::NO_MESSAGE;
75 }
76 
77 void StreamDebugMIDI_Interface::sendImpl(uint8_t header, uint8_t d1, uint8_t d2,
78  uint8_t cn) {
79  uint8_t messageType = (header >> 4) - 8;
80  if (messageType >= 7)
81  return;
82  uint8_t c = header & 0x0F;
84  << F("\tChannel: ") << (c + 1) << F("\tData 1: 0x") << hex << d1
85  << F("\tData 2: 0x") << d2 << dec << F("\tCable: ") << (cn + 1)
86  << endl;
87  stream.flush();
88 }
89 
90 void StreamDebugMIDI_Interface::sendImpl(uint8_t header, uint8_t d1,
91  uint8_t cn) {
92  uint8_t messageType = (header >> 4) - 8;
93  if (messageType >= 7)
94  return;
95  uint8_t c = header & 0x0F;
97  << F("\tChannel: ") << (c + 1) << F("\tData 1: 0x") << hex << d1
98  << dec << F("\tCable: ") << (cn + 1) << endl;
99  stream.flush();
100 }
101 
102 void StreamDebugMIDI_Interface::sendImpl(const uint8_t *data, size_t length,
103  uint8_t cn) {
104  stream << F("SysEx \t") << hex << uppercase;
105  while (length-- > 0)
106  stream << (*data++) << ' ';
107  stream << dec << F("\tCable: ") << (cn + 1) << "\r\n";
108  stream.flush();
109 }
110 
111 void StreamDebugMIDI_Interface::sendImpl(uint8_t rt, uint8_t cn) {
112  stream << F("Real-Time: 0x") << hex << rt << dec << F("\tCable: ") << cn
113  << endl;
114  stream.flush();
115 }
116 
StreamMIDI_Interface::stream
Stream & stream
Definition: SerialMIDI_Interface.hpp:91
StreamDebugMIDI_Interface::sendImpl
void sendImpl(uint8_t header, uint8_t d1, uint8_t d2, uint8_t cn) override
Low-level function for sending a 3-byte MIDI message.
Definition: DebugMIDI_Interface.cpp:77
DebugMIDIMessageNames::ProgramChange
static const char ProgramChange[]
Definition: DebugMIDI_Interface.cpp:14
DebugMIDIMessageNames::NoteOn
static const char NoteOn[]
Definition: DebugMIDI_Interface.cpp:11
StreamDebugMIDI_Interface::hexCharToNibble
static uint8_t hexCharToNibble(char hex)
Convert a hexadecimal character to a 4-bit nibble.
Definition: DebugMIDI_Interface.hpp:42
DebugMIDIMessageNames::ChannelPressure
static const char ChannelPressure[]
Definition: DebugMIDI_Interface.cpp:15
AH::dec
Print & dec(Print &printer)
Definition: PrintStream.cpp:77
BEGIN_CS_NAMESPACE
#define BEGIN_CS_NAMESPACE
Definition: Settings/NamespaceSettings.hpp:9
DebugMIDIMessageNames::NoteOff
static const char NoteOff[]
Definition: DebugMIDI_Interface.cpp:10
DebugMIDIMessageNames::PitchBend
static const char PitchBend[]
Definition: DebugMIDI_Interface.cpp:16
AH::uppercase
Print & uppercase(Print &printer)
Definition: PrintStream.cpp:35
DebugMIDIMessageNames::ControlChange
static const char ControlChange[]
Definition: DebugMIDI_Interface.cpp:13
END_CS_NAMESPACE
#define END_CS_NAMESPACE
Definition: Settings/NamespaceSettings.hpp:10
DebugMIDIMessageNames::MIDIStatusTypeNames
static const FlashString_t MIDIStatusTypeNames[]
Definition: DebugMIDI_Interface.cpp:18
StreamDebugMIDI_Interface::secondChar
char secondChar
Definition: DebugMIDI_Interface.hpp:37
DebugMIDI_Interface.hpp
DebugMIDIMessageNames
Definition: DebugMIDI_Interface.cpp:6
FlashString_t
std::remove_reference< decltype(*F(""))>::type * FlashString_t
Definition: Arduino-Wrapper.h:18
StreamDebugMIDI_Interface::firstChar
char firstChar
Definition: DebugMIDI_Interface.hpp:36
AH::hex
Print & hex(Print &printer)
Definition: PrintStream.cpp:62
StreamMIDI_Interface::parser
SerialMIDI_Parser parser
Definition: SerialMIDI_Interface.hpp:48
StreamDebugMIDI_Interface::read
MIDIReadEvent read() override
Try reading and parsing a single incoming MIDI message.
Definition: DebugMIDI_Interface.cpp:40
MIDI_Notes::F
constexpr int8_t F
Definition: Notes.hpp:23
PrintStream.hpp
SerialMIDI_Parser::parse
MIDIReadEvent parse(uint8_t midibyte)
Definition: SerialMIDI_Parser.cpp:5
MIDIReadEvent
MIDIReadEvent
Result of the MIDI interface read methods.
Definition: MIDI_Parser.hpp:15
DebugMIDIMessageNames::KeyPressure
static const char KeyPressure[]
Definition: DebugMIDI_Interface.cpp:12
AH::endl
Print & endl(Print &printer)
Definition: PrintStream.cpp:27