Control Surface  1.2.0
MIDI Control Surface library for Arduino
MIDIAddress.hpp
Go to the documentation of this file.
1 /* ✔ */
2 
3 #pragma once
4 
5 #include <Def/Def.hpp>
6 
8 
11 struct __attribute__((packed)) RawMIDIAddress {
12  bool valid : 1;
13  uint8_t address : 7;
14  uint8_t channel : 4;
15  uint8_t cableNumber : 4;
16 };
17 
20  friend class MIDIAddress;
21 
22  public:
23  constexpr MIDIChannelCN() : addresses{0, 0, 0, 0} {}
24  constexpr MIDIChannelCN(Channel channel, Cable cableNumber = CABLE_1)
25  : addresses{
26  1,
27  0,
28  channel.getRaw(),
29  cableNumber.getRaw(),
30  } {}
31 
33  constexpr Channel getChannel() const { return Channel{addresses.channel}; }
35  constexpr uint8_t getRawChannel() const { return addresses.channel; }
36 
38  constexpr Cable getCableNumber() const {
39  return Cable(addresses.cableNumber);
40  }
42  constexpr uint8_t getRawCableNumber() const {
43  return addresses.cableNumber;
44  }
45 
47  constexpr bool isValid() const { return addresses.valid; }
48 
51  constexpr explicit operator bool() const { return isValid(); }
52 
53  constexpr static MIDIChannelCN invalid() { return {}; }
54 
55  private:
56  RawMIDIAddress addresses;
57 };
58 
60 using MIDICNChannel [[deprecated("Use MIDIChannelCN instead")]] = MIDIChannelCN;
61 
65  friend class MIDIAddress;
66 
67  public:
68  constexpr RelativeMIDIAddress() : addresses{0, 0, 0, 0} {}
69  constexpr RelativeMIDIAddress(int deltaAddress, int deltaChannel = 0,
70  int deltaCableNumber = 0)
71  : addresses{
72  1,
73  (uint8_t)deltaAddress,
74  (uint8_t)deltaChannel,
75  (uint8_t)deltaCableNumber,
76  } {}
77  constexpr bool isValid() const { return addresses.valid; }
78 
82 
83  private:
84  RawMIDIAddress addresses;
85  static_assert(((-1) & 0x7F) == 0x7F,
86  "Negative numbers must be two's complement");
87 };
88 
91 class MIDIAddress {
92  public:
95 
97  constexpr MIDIAddress()
98  : addresses{
99  0,
100  0,
101  0,
102  0,
103  } {}
104 
116  constexpr MIDIAddress(int address, MIDIChannelCN channelCN)
117  : addresses{
118  1,
119  (uint8_t)address,
120  channelCN.getRawChannel(),
121  channelCN.getRawCableNumber(),
122  } {} // Deliberate overflow for negative numbers
123 
139  constexpr MIDIAddress(int address, Channel channel = CHANNEL_1,
140  Cable cableNumber = CABLE_1)
141  : addresses{
142  1,
143  (uint8_t)address,
144  channel.getRaw(),
145  cableNumber.getRaw(),
146  } {} // Deliberate overflow for negative numbers
147 
160  constexpr MIDIAddress(int address, Cable cableNumber)
161  : addresses{
162  1,
163  (uint8_t)address,
164  0,
165  cableNumber.getRaw(),
166  } {} // Deliberate overflow for negative numbers
167 
178  constexpr MIDIAddress(Channel channel, Cable cableNumber = CABLE_1)
179  : addresses{
180  1,
181  0,
182  channel.getRaw(),
183  cableNumber.getRaw(),
184  } {}
185 
192  constexpr MIDIAddress(const MIDIChannelCN &address)
193  : addresses(address.addresses) {}
194 
196  constexpr static MIDIAddress invalid() { return {}; }
197 
199 
200  public:
203 
206 
209 
211  MIDIAddress operator+(const RelativeMIDIAddress &rhs) const;
212 
214  MIDIAddress operator-(const RelativeMIDIAddress &rhs) const;
215 
217 
218  public:
221 
223  constexpr uint8_t getAddress() const { return addresses.address; }
224 
226  constexpr Channel getChannel() const { return Channel{addresses.channel}; }
228  constexpr uint8_t getRawChannel() const { return addresses.channel; }
229 
231  constexpr Cable getCableNumber() const {
232  return Cable(addresses.cableNumber);
233  }
235  constexpr uint8_t getRawCableNumber() const {
236  return addresses.cableNumber;
237  }
238 
240 
241  public:
244 
249  constexpr bool operator==(const MIDIAddress &rhs) const {
250  return this->addresses.valid && rhs.addresses.valid &&
251  this->addresses.address == rhs.addresses.address &&
252  this->addresses.channel == rhs.addresses.channel &&
253  this->addresses.cableNumber == rhs.addresses.cableNumber;
254  }
255 
260  constexpr bool operator!=(const MIDIAddress &rhs) const {
261  return this->addresses.valid && rhs.addresses.valid &&
262  !(this->addresses.address == rhs.addresses.address &&
263  this->addresses.channel == rhs.addresses.channel &&
264  this->addresses.cableNumber == rhs.addresses.cableNumber);
265  }
266 
268  constexpr bool isValid() const { return addresses.valid; }
269 
272  constexpr explicit operator bool() const { return isValid(); }
273 
275 
276  public:
279 
281  static bool matchSingle(const MIDIAddress &toMatch,
282  const MIDIAddress &base);
283 
292  static bool matchAddressInRange(const MIDIAddress &toMatch,
293  const MIDIAddress &base, uint8_t length);
294 
296 
297  private:
298  RawMIDIAddress addresses;
299 };
300 
302 using MIDICNChannelAddress [[deprecated("Use MIDIAddress instead")]] =
303  MIDIAddress;
304 
MIDIAddress::operator+
MIDIAddress operator+(const RelativeMIDIAddress &rhs) const
Add a relative offset.
Definition: MIDIAddress.cpp:29
MIDIAddress::getRawChannel
constexpr uint8_t getRawChannel() const
Get the channel as an integer [0, 15].
Definition: MIDIAddress.hpp:228
Channel
A type-safe class for MIDI channels.
Definition: Channel.hpp:13
CABLE_1
constexpr Cable CABLE_1
Definition: Cable.hpp:111
MIDIAddress::invalid
constexpr static MIDIAddress invalid()
Return an invalid address.
Definition: MIDIAddress.hpp:196
MIDIAddress
A type-safe utility class for saving a MIDI address consisting of a 7-bit address,...
Definition: MIDIAddress.hpp:91
MIDIAddress::operator-=
MIDIAddress & operator-=(const RelativeMIDIAddress &rhs)
Subtract a relative offset from this address.
Definition: MIDIAddress.cpp:21
MIDIAddress::getCableNumber
constexpr Cable getCableNumber() const
Get the cable number [CABLE_1, CABLE_16].
Definition: MIDIAddress.hpp:231
Cable
A type-safe class for MIDI USB Cable numbers.
Definition: Cable.hpp:13
MIDIChannelCN::getCableNumber
constexpr Cable getCableNumber() const
Get the cable number [CABLE_1, CABLE_16].
Definition: MIDIAddress.hpp:38
RelativeMIDIAddress::RelativeMIDIAddress
constexpr RelativeMIDIAddress()
Definition: MIDIAddress.hpp:68
RelativeMIDIAddress::RelativeMIDIAddress
constexpr RelativeMIDIAddress(int deltaAddress, int deltaChannel=0, int deltaCableNumber=0)
Definition: MIDIAddress.hpp:69
RelativeMIDIAddress
A class for saving an offset to a MIDI address.
Definition: MIDIAddress.hpp:64
Def.hpp
MIDIChannelCN
A class for saving a MIDI channel and cable number.
Definition: MIDIAddress.hpp:19
MIDIAddress::addresses
RawMIDIAddress addresses
Definition: MIDIAddress.hpp:298
BEGIN_CS_NAMESPACE
#define BEGIN_CS_NAMESPACE
Definition: Settings/NamespaceSettings.hpp:9
MIDIAddress::MIDIAddress
constexpr MIDIAddress(Channel channel, Cable cableNumber=CABLE_1)
Constructor.
Definition: MIDIAddress.hpp:178
RelativeMIDIAddress::operator+=
RelativeMIDIAddress & operator+=(RelativeMIDIAddress that)
Compound addition.
Definition: MIDIAddress.cpp:5
RelativeMIDIAddress::isValid
constexpr bool isValid() const
Definition: MIDIAddress.hpp:77
MIDIAddress::MIDIAddress
constexpr MIDIAddress(int address, Cable cableNumber)
Constructor.
Definition: MIDIAddress.hpp:160
END_CS_NAMESPACE
#define END_CS_NAMESPACE
Definition: Settings/NamespaceSettings.hpp:10
MIDIAddress::matchAddressInRange
static bool matchAddressInRange(const MIDIAddress &toMatch, const MIDIAddress &base, uint8_t length)
Check if an address falls within a range of MIDI addresses, starting with address base,...
Definition: MIDIAddress.cpp:46
MIDIChannelCN::getChannel
constexpr Channel getChannel() const
Get the channel [1, 16].
Definition: MIDIAddress.hpp:33
MIDIAddress::operator+=
MIDIAddress & operator+=(const RelativeMIDIAddress &rhs)
Add a relative offset to this address.
Definition: MIDIAddress.cpp:13
MIDIAddress::matchSingle
static bool matchSingle(const MIDIAddress &toMatch, const MIDIAddress &base)
Check if two addresses match (are equal).
Definition: MIDIAddress.cpp:41
MIDIAddress::operator-
MIDIAddress operator-(const RelativeMIDIAddress &rhs) const
Subtract a relative offset.
Definition: MIDIAddress.cpp:35
MIDIAddress::MIDIAddress
constexpr MIDIAddress(const MIDIChannelCN &address)
Constructor.
Definition: MIDIAddress.hpp:192
RelativeMIDIAddress::addresses
RawMIDIAddress addresses
Definition: MIDIAddress.hpp:84
MIDIAddress::isValid
constexpr bool isValid() const
Check if the MIDI address is valid.
Definition: MIDIAddress.hpp:268
MIDIChannelCN::getRawChannel
constexpr uint8_t getRawChannel() const
Get the channel as an integer [0, 15].
Definition: MIDIAddress.hpp:35
MIDIChannelCN::invalid
constexpr static MIDIChannelCN invalid()
Definition: MIDIAddress.hpp:53
MIDIAddress::operator==
constexpr bool operator==(const MIDIAddress &rhs) const
Check for equality: two addresses are equal if and only if they are both valid addresses and the MIDI...
Definition: MIDIAddress.hpp:249
MIDIChannelCN::MIDIChannelCN
constexpr MIDIChannelCN(Channel channel, Cable cableNumber=CABLE_1)
Definition: MIDIAddress.hpp:24
MIDIChannelCN::MIDIChannelCN
constexpr MIDIChannelCN()
Definition: MIDIAddress.hpp:23
MIDIAddress::getAddress
constexpr uint8_t getAddress() const
Get the address [0, 127].
Definition: MIDIAddress.hpp:223
MIDIAddress::MIDIAddress
constexpr MIDIAddress(int address, Channel channel=CHANNEL_1, Cable cableNumber=CABLE_1)
Constructor.
Definition: MIDIAddress.hpp:139
MIDIAddress::getChannel
constexpr Channel getChannel() const
Get the channel [CHANNEL_1, CHANNEL_16].
Definition: MIDIAddress.hpp:226
MIDIAddress::operator!=
constexpr bool operator!=(const MIDIAddress &rhs) const
Check for inequality: two addresses are not equal if and only if they are both valid addresses and ha...
Definition: MIDIAddress.hpp:260
Channel::getRaw
constexpr uint8_t getRaw() const
Get the channel as an integer.
Definition: Channel.hpp:29
MIDIAddress::getRawCableNumber
constexpr uint8_t getRawCableNumber() const
Get the cable number as an integer [0, 15].
Definition: MIDIAddress.hpp:235
MIDIChannelCN::getRawCableNumber
constexpr uint8_t getRawCableNumber() const
Get the cable number as an integer [0, 15].
Definition: MIDIAddress.hpp:42
Cable::getRaw
constexpr uint8_t getRaw() const
Get the cable as an integer.
Definition: Cable.hpp:29
CHANNEL_1
constexpr Channel CHANNEL_1
Definition: Channel.hpp:111
MIDIChannelCN::isValid
constexpr bool isValid() const
Check if the MIDI address is valid.
Definition: MIDIAddress.hpp:47
MIDIChannelCN::addresses
RawMIDIAddress addresses
Definition: MIDIAddress.hpp:56
MIDIAddress::MIDIAddress
constexpr MIDIAddress()
Default constructor, creates an invalid address.
Definition: MIDIAddress.hpp:97
MIDIAddress::MIDIAddress
constexpr MIDIAddress(int address, MIDIChannelCN channelCN)
Constructor.
Definition: MIDIAddress.hpp:116