Control Surface  1.2.0
MIDI Control Surface library for Arduino
MIDI_MessageTypes.hpp
Go to the documentation of this file.
1 #pragma once
2 
4 #include <Settings/NamespaceSettings.hpp>
5 #include <stddef.h> // size_t
6 #include <stdint.h> // uint8_t
7 
8 #ifndef ARDUINO
9 #include <vector>
10 #endif
11 
13 
14 #include <Def/Channel.hpp>
15 #include <Def/Cable.hpp>
16 
18 
19 // -------------------------------------------------------------------------- //
20 
21 enum class MIDIMessageType : uint8_t {
22  NOTE_OFF = 0x80, // 3B
23  NOTE_ON = 0x90, // 3B
24  KEY_PRESSURE = 0xA0, // 3B
25  CC = 0xB0, // 3B
26  CONTROL_CHANGE = CC, // 3B
27  PROGRAM_CHANGE = 0xC0, // 2B
28  CHANNEL_PRESSURE = 0xD0, // 2B
29  PITCH_BEND = 0xE0, // 3B
30 
31  SYSEX_START = 0xF0,
32  SYSEX_END = 0xF7,
33 
34  TUNE_REQUEST = 0xF6,
35 
36  /* System Real-Time messages */
37  TIMING_CLOCK = 0xF8,
38  UNDEFINED_REALTIME_1 = 0xF9,
39  START = 0xFA,
40  CONTINUE = 0xFB,
41  STOP = 0xFC,
42  UNDEFINED_REALTIME_2 = 0xFD,
43  ACTIVE_SENSING = 0xFE,
44  RESET = 0xFF,
45 };
46 
48 enum class MIDICodeIndexNumber : uint8_t {
49  MISC_FUNCTION_CODES = 0x0,
50  CABLE_EVENTS = 0x1,
51  SYSTEM_COMMON_2B = 0x2,
52  SYSTEM_COMMON_3B = 0x3,
53  SYSEX_START_CONT = 0x4,
54  SYSTEM_COMMON_1B = 0x5,
55  SYSEX_END_1B = 0x5,
56  SYSEX_END_2B = 0x6,
57  SYSEX_END_3B = 0x7,
58 
59  NOTE_OFF = 0x8,
60  NOTE_ON = 0x9,
61  KEY_PRESSURE = 0xA,
62  CONTROL_CHANGE = 0xB,
63  PROGRAM_CHANGE = 0xC,
64  CHANNEL_PRESSURE = 0xD,
65  PITCH_BEND = 0xE,
66 
67  SINGLE_BYTE = 0xF,
68 };
69 
70 // -------------------------------------------------------------------------- //
71 
74  ChannelMessage(uint8_t header, uint8_t data1, uint8_t data2, uint8_t CN)
75  : header(header), data1(data1), data2(data2), CN(CN) {}
76 
78  ChannelMessage(MIDIMessageType type, Channel channel, uint8_t data1,
79  uint8_t data2 = 0x00, Cable cable = CABLE_1)
80  : ChannelMessage(uint8_t(type) | channel.getRaw(), data1, data2,
81  cable.getRaw()) {}
82 
83  uint8_t header;
84  uint8_t data1;
85  uint8_t data2;
86 
87  uint8_t CN;
88 
90  bool operator==(ChannelMessage other) const {
91  return this->header == other.header && this->data1 == other.data1 &&
92  this->data2 == other.data2 && this->CN == other.CN;
93  }
95  bool operator!=(ChannelMessage other) const { return !(*this == other); }
96 
98  Channel getChannel() const { return Channel(header & 0x0F); }
100  void setChannel(Channel channel) {
101  header &= 0xF0;
102  header |= channel.getRaw();
103  }
104 
106  Cable getCable() const { return Cable(CN); }
108  void setCable(Cable cable) { CN = cable.getRaw(); }
109 
112  return static_cast<MIDIMessageType>(header & 0xF0);
113  }
116  header &= 0x0F;
117  header |= static_cast<uint8_t>(type) & 0xF0;
118  }
119 
124  bool hasTwoDataBytes() const {
125  auto type = getMessageType();
126  return type <= MIDIMessageType::CONTROL_CHANGE ||
127  type == MIDIMessageType::PITCH_BEND;
128  }
129 
131  bool hasValidHeader() const {
132  auto type = getMessageType();
133  return type >= MIDIMessageType::NOTE_OFF &&
134  type <= MIDIMessageType::PITCH_BEND;
135  }
136 };
137 
138 struct SysExMessage {
140  SysExMessage() : data(nullptr), length(0), CN(0) {}
141 
143  SysExMessage(const uint8_t *data, size_t length, uint8_t CN)
144  : data(data), length(length), CN(CN) {}
145 
147  SysExMessage(const uint8_t *data, size_t length, Cable cable = CABLE_1)
148  : data(data), length(length), CN(cable.getRaw()) {}
149 
150 #ifndef ARDUINO
151  SysExMessage(const std::vector<uint8_t> &vec, Cable cable = CABLE_1)
153  : SysExMessage(vec.data(), vec.size(), cable) {}
154 #endif
155 
156  const uint8_t *data;
157  uint8_t length;
158  uint8_t CN;
159 
160  bool operator==(SysExMessage other) const {
161  return this->length == other.length &&
162  this->data == other.data && // TODO: compare contents or pointer?
163  this->CN == other.CN;
164  }
165  bool operator!=(SysExMessage other) const { return !(*this == other); }
166 
168  Cable getCable() const { return Cable(CN); }
170  void setCable(Cable cable) { CN = cable.getRaw(); }
171 };
172 
175  RealTimeMessage(uint8_t message, uint8_t cn) : message(message), CN(cn) {}
176 
179  : message(uint8_t(message)), CN(cn) {}
180 
183  : message(message), CN(cable.getRaw()) {}
184 
187  : message(uint8_t(message)), CN(cable.getRaw()) {}
188 
189  uint8_t message;
190  uint8_t CN;
191 
192  bool operator==(RealTimeMessage other) const {
193  return this->message == other.message && this->CN == other.CN;
194  }
195  bool operator!=(RealTimeMessage other) const { return !(*this == other); }
196 
198  Cable getCable() const { return Cable(CN); }
200  void setCable(Cable cable) { CN = cable.getRaw(); }
201 };
202 
204 
SysExMessage::operator==
bool operator==(SysExMessage other) const
Definition: MIDI_MessageTypes.hpp:160
Channel
A type-safe class for MIDI channels.
Definition: Channel.hpp:13
CABLE_1
constexpr Cable CABLE_1
Definition: Cable.hpp:111
Cable
A type-safe class for MIDI USB Cable numbers.
Definition: Cable.hpp:13
Warnings.hpp
ChannelMessage::hasValidHeader
bool hasValidHeader() const
Check whether the header is a valid header for a channel message.
Definition: MIDI_MessageTypes.hpp:131
SysExMessage
Definition: MIDI_MessageTypes.hpp:138
SysExMessage::data
const uint8_t * data
Definition: MIDI_MessageTypes.hpp:156
MIDICodeIndexNumber::MISC_FUNCTION_CODES
@ MISC_FUNCTION_CODES
RealTimeMessage::operator!=
bool operator!=(RealTimeMessage other) const
Definition: MIDI_MessageTypes.hpp:195
ChannelMessage::CN
uint8_t CN
USB MIDI cable number;.
Definition: MIDI_MessageTypes.hpp:87
RealTimeMessage::RealTimeMessage
RealTimeMessage(MIDIMessageType message, uint8_t cn)
Constructor.
Definition: MIDI_MessageTypes.hpp:178
SysExMessage::SysExMessage
SysExMessage(const uint8_t *data, size_t length, Cable cable=CABLE_1)
Constructor.
Definition: MIDI_MessageTypes.hpp:147
BEGIN_CS_NAMESPACE
#define BEGIN_CS_NAMESPACE
Definition: Settings/NamespaceSettings.hpp:9
ChannelMessage::header
uint8_t header
MIDI status byte (message type and channel).
Definition: MIDI_MessageTypes.hpp:83
SysExMessage::operator!=
bool operator!=(SysExMessage other) const
Definition: MIDI_MessageTypes.hpp:165
RealTimeMessage::RealTimeMessage
RealTimeMessage(uint8_t message, Cable cable=CABLE_1)
Constructor.
Definition: MIDI_MessageTypes.hpp:182
AH_DIAGNOSTIC_POP
#define AH_DIAGNOSTIC_POP()
Definition: Warnings.hpp:36
RealTimeMessage::RealTimeMessage
RealTimeMessage(MIDIMessageType message, Cable cable=CABLE_1)
Constructor.
Definition: MIDI_MessageTypes.hpp:186
ChannelMessage::data2
uint8_t data2
First MIDI data byte.
Definition: MIDI_MessageTypes.hpp:85
ChannelMessage::operator==
bool operator==(ChannelMessage other) const
Check for equality.
Definition: MIDI_MessageTypes.hpp:90
SysExMessage::setCable
void setCable(Cable cable)
Set the MIDI USB cable number of the message.
Definition: MIDI_MessageTypes.hpp:170
SysExMessage::SysExMessage
SysExMessage()
Constructor.
Definition: MIDI_MessageTypes.hpp:140
END_CS_NAMESPACE
#define END_CS_NAMESPACE
Definition: Settings/NamespaceSettings.hpp:10
ChannelMessage::hasTwoDataBytes
bool hasTwoDataBytes() const
Check whether this message has one or two data bytes.
Definition: MIDI_MessageTypes.hpp:124
MIDICodeIndexNumber
MIDICodeIndexNumber
See table 4-1 in https://usb.org/sites/default/files/midi10.pdf.
Definition: MIDI_MessageTypes.hpp:48
MIDIMessageType
MIDIMessageType
Definition: MIDI_MessageTypes.hpp:21
MIDIMessageType::NOTE_OFF
@ NOTE_OFF
RealTimeMessage::RealTimeMessage
RealTimeMessage(uint8_t message, uint8_t cn)
Constructor.
Definition: MIDI_MessageTypes.hpp:175
ChannelMessage::ChannelMessage
ChannelMessage(MIDIMessageType type, Channel channel, uint8_t data1, uint8_t data2=0x00, Cable cable=CABLE_1)
Constructor.
Definition: MIDI_MessageTypes.hpp:78
RealTimeMessage
Definition: MIDI_MessageTypes.hpp:173
ChannelMessage::setChannel
void setChannel(Channel channel)
Set the MIDI channel of the message.
Definition: MIDI_MessageTypes.hpp:100
ChannelMessage::data1
uint8_t data1
First MIDI data byte.
Definition: MIDI_MessageTypes.hpp:84
SysExMessage::CN
uint8_t CN
Definition: MIDI_MessageTypes.hpp:158
ChannelMessage::setCable
void setCable(Cable cable)
Set the MIDI USB cable number of the message.
Definition: MIDI_MessageTypes.hpp:108
RealTimeMessage::getCable
Cable getCable() const
Get the MIDI USB cable number of the message.
Definition: MIDI_MessageTypes.hpp:198
ChannelMessage::getMessageType
MIDIMessageType getMessageType() const
Get the MIDI message type.
Definition: MIDI_MessageTypes.hpp:111
ChannelMessage::setMessageType
void setMessageType(MIDIMessageType type)
Set the MIDI message type.
Definition: MIDI_MessageTypes.hpp:115
RealTimeMessage::operator==
bool operator==(RealTimeMessage other) const
Definition: MIDI_MessageTypes.hpp:192
SysExMessage::getCable
Cable getCable() const
Get the MIDI USB cable number of the message.
Definition: MIDI_MessageTypes.hpp:168
RealTimeMessage::setCable
void setCable(Cable cable)
Set the MIDI USB cable number of the message.
Definition: MIDI_MessageTypes.hpp:200
AH_DIAGNOSTIC_WERROR
#define AH_DIAGNOSTIC_WERROR()
Definition: Warnings.hpp:35
ChannelMessage
Definition: MIDI_MessageTypes.hpp:72
RealTimeMessage::CN
uint8_t CN
Definition: MIDI_MessageTypes.hpp:190
Channel::getRaw
constexpr uint8_t getRaw() const
Get the channel as an integer.
Definition: Channel.hpp:29
ChannelMessage::operator!=
bool operator!=(ChannelMessage other) const
Check for inequality.
Definition: MIDI_MessageTypes.hpp:95
ChannelMessage::getCable
Cable getCable() const
Get the MIDI USB cable number of the message.
Definition: MIDI_MessageTypes.hpp:106
Cable::getRaw
constexpr uint8_t getRaw() const
Get the cable as an integer.
Definition: Cable.hpp:29
SysExMessage::SysExMessage
SysExMessage(const uint8_t *data, size_t length, uint8_t CN)
Constructor.
Definition: MIDI_MessageTypes.hpp:143
SysExMessage::length
uint8_t length
Definition: MIDI_MessageTypes.hpp:157
ChannelMessage::ChannelMessage
ChannelMessage(uint8_t header, uint8_t data1, uint8_t data2, uint8_t CN)
Constructor.
Definition: MIDI_MessageTypes.hpp:74
RealTimeMessage::message
uint8_t message
Definition: MIDI_MessageTypes.hpp:189
MCU::STOP
constexpr uint8_t STOP
Definition: MCU.hpp:129
ChannelMessage::getChannel
Channel getChannel() const
Get the MIDI channel of the message.
Definition: MIDI_MessageTypes.hpp:98
Cable.hpp