Control Surface  1.1.1
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 
18 const static __FlashStringHelper *MIDIStatusTypeNames[] = {
19  reinterpret_cast<const __FlashStringHelper *>(NoteOff),
20  reinterpret_cast<const __FlashStringHelper *>(NoteOn),
21  reinterpret_cast<const __FlashStringHelper *>(KeyPressure),
22  reinterpret_cast<const __FlashStringHelper *>(ControlChange),
23  reinterpret_cast<const __FlashStringHelper *>(ProgramChange),
24  reinterpret_cast<const __FlashStringHelper *>(ChannelPressure),
25  reinterpret_cast<const __FlashStringHelper *>(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  MIDI_read_t parseResult = parser.parse(midiByte);
60  if (parseResult != 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  MIDI_read_t parseResult = parser.parse(midiByte);
67  if (parseResult != NO_MESSAGE)
68  return parseResult;
69  } else {
70  // Ignore any characters other than whitespace and hexadecimal
71  // digits
72  }
73  }
74  return NO_MESSAGE;
75 }
76 
77 void StreamDebugMIDI_Interface::sendImpl(uint8_t m, uint8_t c, uint8_t d1,
78  uint8_t d2, uint8_t cn) {
79  uint8_t messageType = (m >> 4) - 8;
80  if (messageType >= 7)
81  return;
83  << F("\tChannel: ") << (c + 1) << F("\tData 1: 0x") << hex << d1
84  << F("\tData 2: 0x") << d2 << dec << F("\tCable: ") << cn << endl;
85  stream.flush();
86 }
87 
88 void StreamDebugMIDI_Interface::sendImpl(uint8_t m, uint8_t c, uint8_t d1,
89  uint8_t cn) {
90  uint8_t messageType = (m >> 4) - 8;
91  if (messageType >= 7)
92  return;
94  << F("\tChannel: ") << (c + 1) << F("\tData 1: 0x") << hex << d1
95  << dec << F("\tCable: ") << cn << endl;
96  stream.flush();
97 }
98 
99 void StreamDebugMIDI_Interface::sendImpl(const uint8_t *data, size_t length,
100  uint8_t cn) {
101  stream << F("SysEx \t") << hex << uppercase;
102  while (length-- > 0)
103  stream << (*data++) << ' ';
104  stream << dec << F("\tCable: ") << cn << "\r\n";
105  stream.flush();
106 }
107 
108 void StreamDebugMIDI_Interface::sendImpl(uint8_t rt, uint8_t cn) {
109  stream << F("Real-Time: 0x") << hex << rt << dec << F("\tCable: ") << cn
110  << endl;
111  stream.flush();
112 }
113 
StreamMIDI_Interface::stream
Stream & stream
Definition: SerialMIDI_Interface.hpp:70
DebugMIDIMessageNames::NoteOn
const static char NoteOn[]
Definition: DebugMIDI_Interface.cpp:11
SerialMIDI_Parser::parse
MIDI_read_t parse(uint8_t midibyte)
Definition: SerialMIDI_Parser.cpp:5
MIDI_read_t
MIDI_read_t
Definition: MIDI_Parser.hpp:29
StreamDebugMIDI_Interface::sendImpl
void sendImpl(uint8_t m, uint8_t c, 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
StreamDebugMIDI_Interface::hexCharToNibble
static uint8_t hexCharToNibble(char hex)
Convert a hexadecimal character to a 4-bit nibble.
Definition: DebugMIDI_Interface.hpp:43
BEGIN_CS_NAMESPACE
#define BEGIN_CS_NAMESPACE
Definition: Settings/NamespaceSettings.hpp:9
DebugMIDIMessageNames::MIDIStatusTypeNames
const static __FlashStringHelper * MIDIStatusTypeNames[]
Definition: DebugMIDI_Interface.cpp:18
END_CS_NAMESPACE
#define END_CS_NAMESPACE
Definition: Settings/NamespaceSettings.hpp:10
StreamDebugMIDI_Interface::secondChar
char secondChar
Definition: DebugMIDI_Interface.hpp:38
DebugMIDIMessageNames::KeyPressure
const static char KeyPressure[]
Definition: DebugMIDI_Interface.cpp:12
DebugMIDI_Interface.hpp
DebugMIDIMessageNames
Definition: DebugMIDI_Interface.cpp:6
DebugMIDIMessageNames::NoteOff
const static char NoteOff[]
Definition: DebugMIDI_Interface.cpp:10
NO_MESSAGE
Definition: MIDI_Parser.hpp:30
StreamDebugMIDI_Interface::firstChar
char firstChar
Definition: DebugMIDI_Interface.hpp:37
StreamMIDI_Interface::parser
SerialMIDI_Parser parser
Definition: SerialMIDI_Interface.hpp:39
uppercase
Print & uppercase(Print &printer)
Definition: PrintStream.cpp:35
StreamDebugMIDI_Interface::read
MIDI_read_t read() override
Definition: DebugMIDI_Interface.cpp:40
hex
Print & hex(Print &printer)
Definition: PrintStream.cpp:62
MIDI_Notes::F
constexpr int8_t F
Definition: Notes.hpp:23
endl
Print & endl(Print &printer)
Definition: PrintStream.cpp:27
PrintStream.hpp
DebugMIDIMessageNames::ChannelPressure
const static char ChannelPressure[]
Definition: DebugMIDI_Interface.cpp:15
DebugMIDIMessageNames::ControlChange
const static char ControlChange[]
Definition: DebugMIDI_Interface.cpp:13
dec
Print & dec(Print &printer)
Definition: PrintStream.cpp:77
DebugMIDIMessageNames::PitchBend
const static char PitchBend[]
Definition: DebugMIDI_Interface.cpp:16
DebugMIDIMessageNames::ProgramChange
const static char ProgramChange[]
Definition: DebugMIDI_Interface.cpp:14