Control Surface  1.1.1
MIDI Control Surface library for Arduino
USBMIDI_Parser.cpp
Go to the documentation of this file.
1 #include "USBMIDI_Parser.hpp"
2 #include <Settings/SettingsWrapper.hpp>
3 
5 
6 // http://www.usb.org/developers/docs/devclass_docs/midi10.pdf
8  DEBUG("MIDIUSB packet:\t" << hex << packet[0] << ' ' << packet[1] << ' '
9  << packet[2] << ' ' << packet[3] << dec);
10  this->CN = (uint8_t)packet[0] >> 4;
11  uint8_t CIN = (uint8_t)packet[0] << 4; // MIDI USB code index number
12 
13  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  midimsg.header = packet[1];
20  midimsg.data1 = packet[2];
21  midimsg.data2 = packet[3];
22  midimsg.CN = this->CN;
23  return CHANNEL_MESSAGE;
24  }
25 
26 #if !IGNORE_SYSEX
27  else if (CIN == 0x40) {
28  // SysEx starts or continues (3 bytes)
29  if (packet[1] == SysExStart)
30  startSysEx(CN); // start a new message
31  // (overwrite previous unfinished message)
32  else if (!receivingSysEx(CN)) { // If we haven't received a SysExStart
33  DEBUGREF(F("Error: No SysExStart received"));
34  return NO_MESSAGE; // ignore the data
35  }
36  addSysExByte(CN, packet[1]) && // add three data bytes to buffer
37  addSysExByte(CN, packet[2]) && addSysExByte(CN, packet[3]);
38  return NO_MESSAGE; // SysEx is not finished yet
39  }
40 
41  else if (CIN == 0x50) {
42  // SysEx ends with following single byte
43  // (or Single-byte System Common Message, not implemented)
44  if (packet[1] != SysExEnd) { // System Common (not implemented)
45  return NO_MESSAGE;
46  } else if (!receivingSysEx(CN)) { // If we haven't received a SysExStart
47  DEBUGFN(F("Error: No SysExStart received"));
48  return NO_MESSAGE; // ignore the data
49  }
50  if (addSysExByte(CN, SysExEnd)) {
51  endSysEx(CN);
52  return SYSEX_MESSAGE;
53  } else
54  return NO_MESSAGE; // Buffer full, ignore message
55  }
56 
57  else if (CIN == 0x60) {
58  // SysEx ends with following two bytes
59  if (packet[1] == SysExStart)
60  startSysEx(CN); // start a new message
61  // (overwrite previous unfinished message)
62  else if (!receivingSysEx(CN)) { // If we haven't received a SysExStart
63  DEBUGFN(F("Error: No SysExStart received"));
64  return NO_MESSAGE; // ignore the data
65  }
66  if ( // add two data bytes to buffer
67  addSysExByte(CN, packet[1]) && addSysExByte(CN, SysExEnd)) {
68  endSysEx(CN);
69  return SYSEX_MESSAGE;
70  } else
71  return NO_MESSAGE; // Buffer full, ignore message
72  }
73 
74  else if (CIN == 0x70) {
75  // SysEx ends with following three bytes
76  if (packet[1] == SysExStart)
77  startSysEx(CN); // start a new message
78  // (overwrite previous unfinished message)
79  else if (!receivingSysEx(CN)) { // If we haven't received a SysExStart
80  DEBUGFN(F("Error: No SysExStart received"));
81  return NO_MESSAGE; // ignore the data
82  }
83  if ( // add three data bytes to buffer
84  addSysExByte(CN, packet[1]) && addSysExByte(CN, packet[2]) &&
86  endSysEx(CN);
87  return SYSEX_MESSAGE;
88  } else
89  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  else if (CIN == 0xF0) // Single Byte
104  return static_cast<MIDI_read_t>(packet[1]);
105 
106  return NO_MESSAGE;
107 }
108 
USBMIDI_Parser::startSysEx
void startSysEx(uint8_t CN)
Definition: USBMIDI_Parser.hpp:33
USBMIDI_Parser::endSysEx
void endSysEx(uint8_t CN)
Definition: USBMIDI_Parser.hpp:34
MIDI_read_t
MIDI_read_t
Definition: MIDI_Parser.hpp:29
DEBUGREF
#define DEBUGREF(x)
Print an expression and its location (file and line number) to the debug output if debugging is enabl...
Definition: Debug.hpp:84
ChannelMessage::CN
uint8_t CN
Definition: MIDI_Parser.hpp:52
CHANNEL_MESSAGE
Definition: MIDI_Parser.hpp:31
BEGIN_CS_NAMESPACE
#define BEGIN_CS_NAMESPACE
Definition: Settings/NamespaceSettings.hpp:9
USBMIDI_Parser::receivingSysEx
bool receivingSysEx(uint8_t CN) const
Definition: USBMIDI_Parser.hpp:38
ChannelMessage::header
uint8_t header
Definition: MIDI_Parser.hpp:48
ChannelMessage::data2
uint8_t data2
Definition: MIDI_Parser.hpp:50
USBMIDI_Parser.hpp
END_CS_NAMESPACE
#define END_CS_NAMESPACE
Definition: Settings/NamespaceSettings.hpp:10
USBMIDI_Parser::addSysExByte
bool addSysExByte(uint8_t CN, uint8_t data)
Definition: USBMIDI_Parser.hpp:35
SysExEnd
const uint8_t SysExEnd
Definition: MIDI_Parser.hpp:25
USBMIDI_Parser::parse
MIDI_read_t parse(uint8_t *packet)
Definition: USBMIDI_Parser.cpp:7
NO_MESSAGE
Definition: MIDI_Parser.hpp:30
MIDI_Parser::midimsg
ChannelMessage midimsg
Definition: MIDI_Parser.hpp:102
PITCH_BEND
const uint8_t PITCH_BEND
Definition: MIDI_Parser.hpp:22
ChannelMessage::data1
uint8_t data1
Definition: MIDI_Parser.hpp:49
NOTE_OFF
const uint8_t NOTE_OFF
Definition: MIDI_Parser.hpp:16
SYSEX_MESSAGE
Definition: MIDI_Parser.hpp:32
hex
Print & hex(Print &printer)
Definition: PrintStream.cpp:62
MIDI_Notes::F
constexpr int8_t F
Definition: Notes.hpp:23
DEBUGFN
#define DEBUGFN(x)
Print an expression and its function (function name and line number) to the debug output if debugging...
Definition: Debug.hpp:93
dec
Print & dec(Print &printer)
Definition: PrintStream.cpp:77
DEBUG
#define DEBUG(x)
Print an expression to the debug output if debugging is enabled.
Definition: Debug.hpp:75
USBMIDI_Parser::CN
uint8_t CN
Definition: USBMIDI_Parser.hpp:43
SysExStart
const uint8_t SysExStart
Definition: MIDI_Parser.hpp:24