Control Surface  1.1.1
MIDI Control Surface library for Arduino
MIDICNChannelAddress.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)) RawMIDICNChannelAddress {
12  bool valid : 1;
13  uint8_t address : 7;
14  uint8_t channel : 4;
15  uint8_t cableNumber : 4;
16 };
17 
20  friend class MIDICNChannelAddress;
21 
22  public:
23  constexpr MIDICNChannel() : addresses{0, 0, 0, 0} {}
24  constexpr MIDICNChannel(Channel channel, int cableNumber = 0)
25  : addresses{
26  1,
27  0,
28  (uint8_t)channel.getRaw(),
29  (uint8_t)cableNumber,
30  } {}
31 
33  constexpr Channel getChannel() const {
34  return Channel{int8_t(addresses.channel)};
35  }
36 
38  constexpr uint8_t getRawChannel() const { return addresses.channel; }
39 
41  constexpr uint8_t getCableNumber() const { return addresses.cableNumber; }
42 
44  constexpr bool isValid() const { return addresses.valid; }
45 
48  constexpr explicit operator bool() const { return isValid(); }
49 
50  constexpr static MIDICNChannel invalid() { return {}; }
51 
52  private:
53  RawMIDICNChannelAddress addresses;
54 };
55 
59  friend class MIDICNChannelAddress;
60 
61  public:
62  constexpr RelativeMIDICNChannelAddress() : addresses{0, 0, 0, 0} {}
63  constexpr RelativeMIDICNChannelAddress(int deltaAddress,
64  int deltaChannel = 0,
65  int deltaCableNumber = 0)
66  : addresses{
67  1,
68  (uint8_t)deltaAddress,
69  (uint8_t)deltaChannel,
70  (uint8_t)deltaCableNumber,
71  } {}
72  constexpr bool isValid() const { return addresses.valid; }
73 
74  private:
75  RawMIDICNChannelAddress addresses;
76  static_assert(((-1) & 0x7F) == 0x7F,
77  "Negative numbers must be two's complement");
78 };
79 
83  public:
85  : addresses{
86  0,
87  0,
88  0,
89  0,
90  } {}
91  constexpr MIDICNChannelAddress(int address, MIDICNChannel channelCN)
92  : addresses{
93  1,
94  (uint8_t)address,
95  channelCN.getRawChannel(),
96  channelCN.getCableNumber(),
97  } {}
98  constexpr MIDICNChannelAddress(int address, Channel channel = CHANNEL_1,
99  int cableNumber = 0x0)
100  : addresses{
101  1,
102  (uint8_t)address,
103  (uint8_t)channel.getRaw(),
104  (uint8_t)cableNumber,
105  } {} // Deliberate overflow for negative numbers
106  constexpr MIDICNChannelAddress(Channel channel, int cableNumber = 0x0)
107  : addresses{
108  1,
109  0,
110  (uint8_t)channel.getRaw(),
111  (uint8_t)cableNumber,
112  } {} // Deliberate overflow for negative numbers
113  constexpr MIDICNChannelAddress(const MIDICNChannel &address)
114  : addresses(address.addresses) {}
115 
117 
119 
121  operator+(const RelativeMIDICNChannelAddress &rhs) const;
122 
124  operator-(const RelativeMIDICNChannelAddress &rhs) const;
125 
126  constexpr bool operator==(const MIDICNChannelAddress &rhs) const {
127  return this->addresses.valid && rhs.addresses.valid &&
128  this->addresses.address == rhs.addresses.address &&
129  this->addresses.channel == rhs.addresses.channel &&
130  this->addresses.cableNumber == rhs.addresses.cableNumber;
131  }
132 
133  constexpr bool operator!=(const MIDICNChannelAddress &rhs) const {
134  return this->addresses.valid && rhs.addresses.valid &&
135  !(this->addresses.address == rhs.addresses.address &&
136  this->addresses.channel == rhs.addresses.channel &&
137  this->addresses.cableNumber == rhs.addresses.cableNumber);
138  }
139 
141  constexpr uint8_t getAddress() const { return addresses.address; }
142 
144  constexpr Channel getChannel() const {
145  return Channel{int8_t(addresses.channel)};
146  }
148  constexpr uint8_t getRawChannel() const { return addresses.channel; }
149 
151  constexpr uint8_t getCableNumber() const { return addresses.cableNumber; }
152 
154  constexpr bool isValid() const { return addresses.valid; }
155 
158  constexpr explicit operator bool() const { return isValid(); }
159 
161  static bool matchSingle(const MIDICNChannelAddress &toMatch,
162  const MIDICNChannelAddress &base);
163 
166  static bool matchAddressInRange(const MIDICNChannelAddress &toMatch,
167  const MIDICNChannelAddress &base,
168  uint8_t length);
169 
170  constexpr static MIDICNChannelAddress invalid() { return {}; }
171 
172  private:
173  RawMIDICNChannelAddress addresses;
174 };
175 
MIDICNChannelAddress::operator-
MIDICNChannelAddress operator-(const RelativeMIDICNChannelAddress &rhs) const
Definition: MIDICNChannelAddress.cpp:37
Channel
A type-safe class for MIDI channels.
Definition: Channel.hpp:13
MIDICNChannelAddress::invalid
constexpr static MIDICNChannelAddress invalid()
Definition: MIDICNChannelAddress.hpp:170
MIDICNChannelAddress::MIDICNChannelAddress
constexpr MIDICNChannelAddress(Channel channel, int cableNumber=0x0)
Definition: MIDICNChannelAddress.hpp:106
MIDICNChannelAddress::MIDICNChannelAddress
constexpr MIDICNChannelAddress()
Definition: MIDICNChannelAddress.hpp:84
RelativeMIDICNChannelAddress::addresses
RawMIDICNChannelAddress addresses
Definition: MIDICNChannelAddress.hpp:75
MIDICNChannelAddress::getRawChannel
constexpr uint8_t getRawChannel() const
Get the channel [0, 15].
Definition: MIDICNChannelAddress.hpp:148
Def.hpp
MIDICNChannelAddress::matchAddressInRange
static bool matchAddressInRange(const MIDICNChannelAddress &toMatch, const MIDICNChannelAddress &base, uint8_t length)
Check if an address falls within a range of addresses, starting with address base,...
Definition: MIDICNChannelAddress.cpp:48
BEGIN_CS_NAMESPACE
#define BEGIN_CS_NAMESPACE
Definition: Settings/NamespaceSettings.hpp:9
MIDICNChannelAddress::getCableNumber
constexpr uint8_t getCableNumber() const
Get the cable number [0, 15].
Definition: MIDICNChannelAddress.hpp:151
RelativeMIDICNChannelAddress
A class for saving an offset to a MIDI address.
Definition: MIDICNChannelAddress.hpp:58
MIDICNChannel::isValid
constexpr bool isValid() const
Check if the MIDI address is valid.
Definition: MIDICNChannelAddress.hpp:44
END_CS_NAMESPACE
#define END_CS_NAMESPACE
Definition: Settings/NamespaceSettings.hpp:10
MIDICNChannel::addresses
RawMIDICNChannelAddress addresses
Definition: MIDICNChannelAddress.hpp:53
MIDICNChannelAddress::matchSingle
static bool matchSingle(const MIDICNChannelAddress &toMatch, const MIDICNChannelAddress &base)
Check if two addresses match.
Definition: MIDICNChannelAddress.cpp:43
MIDICNChannelAddress
A type-safe utility class for saving a MIDI address consisting of a 7-bit address,...
Definition: MIDICNChannelAddress.hpp:82
MIDICNChannelAddress::MIDICNChannelAddress
constexpr MIDICNChannelAddress(int address, MIDICNChannel channelCN)
Definition: MIDICNChannelAddress.hpp:91
RelativeMIDICNChannelAddress::RelativeMIDICNChannelAddress
constexpr RelativeMIDICNChannelAddress()
Definition: MIDICNChannelAddress.hpp:62
MIDICNChannelAddress::getAddress
constexpr uint8_t getAddress() const
Get the address [0, 127].
Definition: MIDICNChannelAddress.hpp:141
MIDICNChannelAddress::isValid
constexpr bool isValid() const
Check if the MIDI address is valid.
Definition: MIDICNChannelAddress.hpp:154
RelativeMIDICNChannelAddress::RelativeMIDICNChannelAddress
constexpr RelativeMIDICNChannelAddress(int deltaAddress, int deltaChannel=0, int deltaCableNumber=0)
Definition: MIDICNChannelAddress.hpp:63
MIDICNChannel
A class for saving a MIDI channel and cable number.
Definition: MIDICNChannelAddress.hpp:19
MIDICNChannelAddress::addresses
RawMIDICNChannelAddress addresses
Definition: MIDICNChannelAddress.hpp:173
Channel::getRaw
constexpr int8_t getRaw() const
Get the channel as an integer.
Definition: Channel.hpp:29
MIDICNChannelAddress::MIDICNChannelAddress
constexpr MIDICNChannelAddress(const MIDICNChannel &address)
Definition: MIDICNChannelAddress.hpp:113
MIDICNChannel::MIDICNChannel
constexpr MIDICNChannel()
Definition: MIDICNChannelAddress.hpp:23
MIDICNChannelAddress::operator-=
MIDICNChannelAddress & operator-=(const RelativeMIDICNChannelAddress &rhs)
Definition: MIDICNChannelAddress.cpp:18
MIDICNChannelAddress::operator+
MIDICNChannelAddress operator+(const RelativeMIDICNChannelAddress &rhs) const
Definition: MIDICNChannelAddress.cpp:30
MIDICNChannelAddress::operator+=
MIDICNChannelAddress & operator+=(const RelativeMIDICNChannelAddress &rhs)
Definition: MIDICNChannelAddress.cpp:6
MIDICNChannelAddress::operator==
constexpr bool operator==(const MIDICNChannelAddress &rhs) const
Definition: MIDICNChannelAddress.hpp:126
MIDICNChannel::getRawChannel
constexpr uint8_t getRawChannel() const
Get the channel as an integer [0, 15].
Definition: MIDICNChannelAddress.hpp:38
MIDICNChannelAddress::MIDICNChannelAddress
constexpr MIDICNChannelAddress(int address, Channel channel=CHANNEL_1, int cableNumber=0x0)
Definition: MIDICNChannelAddress.hpp:98
MIDICNChannelAddress::operator!=
constexpr bool operator!=(const MIDICNChannelAddress &rhs) const
Definition: MIDICNChannelAddress.hpp:133
MIDICNChannel::invalid
constexpr static MIDICNChannel invalid()
Definition: MIDICNChannelAddress.hpp:50
MIDICNChannelAddress::getChannel
constexpr Channel getChannel() const
Get the channel [CHANNEL_1, CHANNEL_16].
Definition: MIDICNChannelAddress.hpp:144
CHANNEL_1
constexpr Channel CHANNEL_1
Definition: Channel.hpp:111
MIDICNChannel::getChannel
constexpr Channel getChannel() const
Get the channel [1, 16].
Definition: MIDICNChannelAddress.hpp:33
MIDICNChannel::MIDICNChannel
constexpr MIDICNChannel(Channel channel, int cableNumber=0)
Definition: MIDICNChannelAddress.hpp:24
RelativeMIDICNChannelAddress::isValid
constexpr bool isValid() const
Definition: MIDICNChannelAddress.hpp:72
MIDICNChannel::getCableNumber
constexpr uint8_t getCableNumber() const
Get the cable number [0, 15].
Definition: MIDICNChannelAddress.hpp:41