Control Surface  1.1.0
MIDI Control Surface library for Arduino
NoteCCRange.hpp
Go to the documentation of this file.
1 #pragma once
2 
6 
8 
9 class INoteCCValue {
10  protected:
12 
13  public:
14  uint8_t length() const { return rangeLength; }
15  virtual uint8_t getValue(uint8_t index) const = 0;
16  uint8_t getValue() const { return getValue(0); }
17 
18  private:
19  uint8_t rangeLength;
20 };
21 
23  public:
24  void begin(const INoteCCValue &) {}
25  void update(const INoteCCValue &, uint8_t) {}
26  void updateAll(const INoteCCValue &) {}
27 };
28 
30  protected:
31  SimpleNoteCCValueCallback() = default;
32 
33  public:
34  virtual void begin(const INoteCCValue &) {}
35  virtual void update(const INoteCCValue &, uint8_t) = 0;
36  virtual void updateAll(const INoteCCValue &noteccval) {
37  for (uint8_t i = 0; i < noteccval.length(); ++i)
38  update(noteccval, i);
39  }
40 };
41 
42 // -------------------------------------------------------------------------- //
43 
44 template <class MIDIInput_t, uint8_t RangeLen, uint8_t NumBanks, class Callback>
45 class NoteCCRange : public MIDIInput_t, public INoteCCValue {
46  public:
47  NoteCCRange(MIDICNChannelAddress address, const Callback &callback)
48  : MIDIInput_t{address}, INoteCCValue{RangeLen}, callback(callback) {}
49 
50  /// @todo check index bounds
51  uint8_t getValue(uint8_t index) const override {
52  return values[getSelection()][index];
53  }
55 
56  /// Initialize
57  void begin() override { callback.begin(*this); }
58  /// Reset all values to zero
59  void reset() override {
60  values = {{}};
61  callback.updateAll(*this);
62  }
63 
64  private:
65  bool updateImpl(const ChannelMessageMatcher &midimsg,
66  const MIDICNChannelAddress &target) override {
67  uint8_t bankIndex = this->getBankIndex(target);
68  uint8_t rangeIndex = this->getRangeIndex(target);
69  uint8_t value = getValueFromMIDIMessage(midimsg);
70  values[bankIndex][rangeIndex] = value;
71  if (bankIndex == this->getSelection())
72  callback.update(*this, rangeIndex);
73  return true;
74  }
75 
76  static uint8_t
78  return midimsg.type == NOTE_OFF ? 0 : midimsg.data2;
79  }
80 
81  /// Get the active bank selection
82  virtual uint8_t getSelection() const { return 0; }
83 
84  /// Get the bank index from a MIDI address
86  (void)target;
87  return 0;
88  }
89 
90  virtual uint8_t getRangeIndex(MIDICNChannelAddress target) const {
91  return target.getAddress() - this->address.getAddress();
92  }
93 
95 
96  public:
97  Callback callback;
98  constexpr static uint8_t length() { return RangeLen; }
99 };
100 
101 // -------------------------------------------------------------------------- //
102 
103 template <class MIDIInput_t, uint8_t RangeLen,
104  class Callback = NoteCCRangeEmptyCallback>
106  : public NoteCCRange<MIDIInput_t, RangeLen, 1, Callback> {
107  public:
109  : NoteCCRange<MIDIInput_t, RangeLen, 1, Callback>{address, callback} {}
110 
111  private:
112  /// Check if the address of the incoming MIDI message is within the range
113  /// of addresses of this element.
114  bool match(const MIDICNChannelAddress &target) const override {
116  target, this->address, RangeLen);
117  }
118 };
119 
120 /**
121  * @brief MIDI Input Element that listens to a range of notes.
122  *
123  * @ingroup MIDIInputElements
124  * @tparam RangeLen
125  * The length of the range of notes to listen to.
126  */
127 template <uint8_t RangeLen>
128 class NoteRange : public GenericNoteCCRange<MIDIInputElementNote, RangeLen> {
129  public:
131  : GenericNoteCCRange<MIDIInputElementNote, RangeLen>{address, {}} {}
132 };
133 
134 class NoteValue : public GenericNoteCCRange<MIDIInputElementNote, 1> {
135  public:
138 };
139 using MIDINote[[deprecated("Use NoteValue instead")]] = NoteValue;
140 
141 template <uint8_t RangeLen>
142 class CCRange : public GenericNoteCCRange<MIDIInputElementCC, RangeLen> {
143  public:
145  : GenericNoteCCRange<MIDIInputElementCC, RangeLen>{address, {}} {}
146 };
147 
148 class CCValue : public GenericNoteCCRange<MIDIInputElementCC, 1> {
149  public:
152 };
153 
154 // -------------------------------------------------------------------------- //
155 
156 namespace Bankable {
157 
158 /// @tparam RangeLen
159 /// The length of the range.
160 /// @tparam NumBanks
161 /// The size of the bank.
162 template <class MIDIInput_t, uint8_t RangeLen, uint8_t NumBanks,
163  class Callback = NoteCCRangeEmptyCallback>
165  : public NoteCCRange<MIDIInput_t, RangeLen, NumBanks, Callback>,
166  public BankableMIDIInput<NumBanks> {
167  public:
169  MIDICNChannelAddress address,
170  const Callback &callback)
171  : NoteCCRange<MIDIInput_t, RangeLen, NumBanks, Callback>{
172  address,
173  callback,
174  }, BankableMIDIInput<NumBanks>{config} {}
175 
176  private:
177  /// Check if the address of the incoming MIDI message is within the range
178  /// of addresses and in one of the banks of this element.
179  bool match(const MIDICNChannelAddress &target) const override {
181  target, this->address, RangeLen);
182  }
183 
184  setting_t getSelection() const override {
186  };
187 
188  uint8_t getBankIndex(MIDICNChannelAddress target) const override {
189  return BankableMIDIInput<NumBanks>::getBankIndex(target, this->address);
190  }
191 
192  uint8_t getRangeIndex(MIDICNChannelAddress target) const override {
194  this->address);
195  }
196 
197  void onBankSettingChange() override { this->callback.updateAll(*this); }
198 };
199 
200 template <uint8_t RangeLen, uint8_t NumBanks>
202  : public GenericNoteCCRange<MIDIInputElementNote, RangeLen, NumBanks> {
203  public:
205  : GenericNoteCCRange<MIDIInputElementNote, RangeLen, NumBanks>{
206  config, address, {}} {}
207 };
208 
209 template <uint8_t NumBanks>
210 class NoteValue : public GenericNoteCCRange<MIDIInputElementNote, 1, NumBanks> {
211  public:
214  config, address, {}} {}
215 };
216 template <uint8_t NumBanks>
217 using MIDINote[[deprecated("Use NoteValue instead")]] = NoteValue<NumBanks>;
218 
219 template <uint8_t RangeLen, uint8_t NumBanks>
220 class CCRange
221  : public GenericNoteCCRange<MIDIInputElementCC, RangeLen, NumBanks> {
222  public:
224  : GenericNoteCCRange<MIDIInputElementCC, RangeLen, NumBanks>{
225  config, address, {}} {}
226 };
227 
228 template <uint8_t NumBanks>
229 class CCValue : public GenericNoteCCRange<MIDIInputElementCC, 1, NumBanks> {
230  public:
232  : GenericNoteCCRange<MIDIInputElementCC, 1, NumBanks>{
233  config, address, {}} {}
234 };
235 
236 } // namespace Bankable
237 
Bankable::GenericNoteCCRange::getSelection
setting_t getSelection() const override
Get the active bank selection.
Definition: NoteCCRange.hpp:184
NoteValue
Definition: NoteCCRange.hpp:134
MIDIInputElementNote
Class for objects that listen for incoming MIDI Note events.
Definition: MIDIInputElementNote.hpp:20
NoteCCRangeEmptyCallback::begin
void begin(const INoteCCValue &)
Definition: NoteCCRange.hpp:24
INoteCCValue::getValue
uint8_t getValue() const
Definition: NoteCCRange.hpp:16
Bankable
A namespace for MIDI elements that can be added to a Bank, to change their address or channel.
Definition: BankAddresses.hpp:7
GenericNoteCCRange
Definition: NoteCCRange.hpp:105
CCValue::CCValue
CCValue(MIDICNChannelAddress address)
Definition: NoteCCRange.hpp:150
INoteCCValue
Definition: NoteCCRange.hpp:9
NoteCCRange::reset
void reset() override
Reset all values to zero.
Definition: NoteCCRange.hpp:59
INoteCCValue::rangeLength
uint8_t rangeLength
Definition: NoteCCRange.hpp:19
NoteCCRange::getSelection
virtual uint8_t getSelection() const
Get the active bank selection.
Definition: NoteCCRange.hpp:82
NoteRange::NoteRange
NoteRange(MIDICNChannelAddress address)
Definition: NoteCCRange.hpp:130
BankableMIDIInput::matchBankableAddressInRange
bool matchBankableAddressInRange(const MIDICNChannelAddress &toMatch, const MIDICNChannelAddress &base, uint8_t length) const
Check whether a given address is part of the bank relative to the base address and within a range wit...
Definition: BankableMIDIInput.hpp:212
NoteCCRange::callback
Callback callback
Definition: NoteCCRange.hpp:97
SimpleNoteCCValueCallback
Definition: NoteCCRange.hpp:29
CCValue
Definition: NoteCCRange.hpp:148
GenericNoteCCRange::GenericNoteCCRange
GenericNoteCCRange(MIDICNChannelAddress address, const Callback &callback)
Definition: NoteCCRange.hpp:108
NoteCCRange::values
Array< Array< uint8_t, RangeLen >, NumBanks > values
Definition: NoteCCRange.hpp:94
Bankable::GenericNoteCCRange
Definition: NoteCCRange.hpp:164
BEGIN_CS_NAMESPACE
#define BEGIN_CS_NAMESPACE
Definition: Settings/NamespaceSettings.hpp:9
MIDIInputElementCC
Class for objects that listen for incoming MIDI Controller Change events.
Definition: MIDIInputElementCC.hpp:23
Bankable::GenericNoteCCRange::GenericNoteCCRange
GenericNoteCCRange(BankConfig< NumBanks > config, MIDICNChannelAddress address, const Callback &callback)
Definition: NoteCCRange.hpp:168
ChannelMessageMatcher
Struct for easily matching MIDI messages.
Definition: ChannelMessageMatcher.hpp:10
NoteCCRangeEmptyCallback::update
void update(const INoteCCValue &, uint8_t)
Definition: NoteCCRange.hpp:25
NoteCCRange::getValueFromMIDIMessage
static uint8_t getValueFromMIDIMessage(const ChannelMessageMatcher &midimsg)
Definition: NoteCCRange.hpp:77
BankableMIDIInput::getBankIndex
uint8_t getBankIndex(const MIDICNChannelAddress &target, const MIDICNChannelAddress &base) const
Calculate the bank setting of a given MIDI address, relative to a base address.
Definition: BankableMIDIInput.hpp:71
NoteCCRange::NoteCCRange
NoteCCRange(MIDICNChannelAddress address, const Callback &callback)
Definition: NoteCCRange.hpp:47
END_CS_NAMESPACE
#define END_CS_NAMESPACE
Definition: Settings/NamespaceSettings.hpp:10
SimpleNoteCCValueCallback::update
virtual void update(const INoteCCValue &, uint8_t)=0
Bankable::GenericNoteCCRange::onBankSettingChange
void onBankSettingChange() override
A function to be executed each time the bank setting changes.
Definition: NoteCCRange.hpp:197
NoteRange
MIDI Input Element that listens to a range of notes.
Definition: NoteCCRange.hpp:128
INoteCCValue::INoteCCValue
INoteCCValue(uint8_t rangeLength)
Definition: NoteCCRange.hpp:11
Bankable::CCRange::CCRange
CCRange(BankConfig< NumBanks > config, MIDICNChannelAddress address)
Definition: NoteCCRange.hpp:223
NoteCCRange::begin
void begin() override
Initialize.
Definition: NoteCCRange.hpp:57
NoteCCRange::getRangeIndex
virtual uint8_t getRangeIndex(MIDICNChannelAddress target) const
Definition: NoteCCRange.hpp:90
MIDICNChannelAddress
A type-safe utility class for saving a MIDI address consisting of a 7-bit address,...
Definition: MIDICNChannelAddress.hpp:82
AH::Array
An array wrapper for easy copying, comparing, and iterating.
Definition: Array.hpp:36
MIDIInputElementNote.hpp
Bankable::NoteValue::NoteValue
NoteValue(BankConfig< NumBanks > config, MIDICNChannelAddress address)
Definition: NoteCCRange.hpp:212
GenericNoteCCRange::match
bool match(const MIDICNChannelAddress &target) const override
Check if the address of the incoming MIDI message is within the range of addresses of this element.
Definition: NoteCCRange.hpp:114
Bankable::CCValue
Definition: NoteCCRange.hpp:229
NoteCCRange
Definition: NoteCCRange.hpp:45
NoteCCRange::updateImpl
bool updateImpl(const ChannelMessageMatcher &midimsg, const MIDICNChannelAddress &target) override
Definition: NoteCCRange.hpp:65
NoteCCRangeEmptyCallback
Definition: NoteCCRange.hpp:22
MIDIInputElementCC.hpp
Bankable::CCValue::CCValue
CCValue(BankConfig< NumBanks > config, MIDICNChannelAddress address)
Definition: NoteCCRange.hpp:231
INoteCCValue::length
uint8_t length() const
Definition: NoteCCRange.hpp:14
MIDICNChannelAddress::getAddress
constexpr uint8_t getAddress() const
Get the address [0, 127].
Definition: MIDICNChannelAddress.hpp:141
NOTE_OFF
const uint8_t NOTE_OFF
Definition: MIDI_Parser.hpp:16
ChannelMessageMatcher::type
uint8_t type
Definition: ChannelMessageMatcher.hpp:18
NoteCCRange::getBankIndex
virtual setting_t getBankIndex(MIDICNChannelAddress target) const
Get the bank index from a MIDI address.
Definition: NoteCCRange.hpp:85
NoteCCRangeEmptyCallback::updateAll
void updateAll(const INoteCCValue &)
Definition: NoteCCRange.hpp:26
CCRange::CCRange
CCRange(MIDICNChannelAddress address)
Definition: NoteCCRange.hpp:144
BankableMIDIInput::getSelection
setting_t getSelection() const
Get the current bank setting.
Definition: BankableMIDIInput.hpp:59
setting_t
uint8_t setting_t
The type used for Selectors.
Definition: Def.hpp:50
NoteValue::NoteValue
NoteValue(MIDICNChannelAddress address)
Definition: NoteCCRange.hpp:136
Bankable::CCRange
Definition: NoteCCRange.hpp:220
Bankable::NoteRange::NoteRange
NoteRange(BankConfig< NumBanks > config, MIDICNChannelAddress address)
Definition: NoteCCRange.hpp:204
Bankable::GenericNoteCCRange::getRangeIndex
uint8_t getRangeIndex(MIDICNChannelAddress target) const override
Definition: NoteCCRange.hpp:192
BankableMIDIInput
A base class for all MIDIInputElements that can be banked.
Definition: Bank.hpp:13
Bankable::NoteRange
Definition: NoteCCRange.hpp:201
BankConfig
A struct for selecting the bank of BankableMIDIInputs and the bank type.
Definition: BankConfig.hpp:39
SimpleNoteCCValueCallback::begin
virtual void begin(const INoteCCValue &)
Definition: NoteCCRange.hpp:34
MIDIInputElement::address
const MIDICNChannelAddress address
Definition: MIDIInputElement.hpp:80
Bankable::GenericNoteCCRange::getBankIndex
uint8_t getBankIndex(MIDICNChannelAddress target) const override
Get the bank index from a MIDI address.
Definition: NoteCCRange.hpp:188
Bankable::NoteValue
Definition: NoteCCRange.hpp:210
BankableMIDIInput.hpp
NoteCCRange::getValue
uint8_t getValue(uint8_t index) const override
Definition: NoteCCRange.hpp:51
NoteCCRange::length
constexpr static uint8_t length()
Definition: NoteCCRange.hpp:98
BankableMIDIInput::getRangeIndex
uint8_t getRangeIndex(MIDICNChannelAddress target, MIDICNChannelAddress base) const
If matchBankableAddressInRange returned true, get the index of the message in the range.
Definition: BankableMIDIInput.hpp:143
SimpleNoteCCValueCallback::SimpleNoteCCValueCallback
SimpleNoteCCValueCallback()=default
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
ChannelMessageMatcher::data2
uint8_t data2
Definition: ChannelMessageMatcher.hpp:21
Bankable::GenericNoteCCRange::match
bool match(const MIDICNChannelAddress &target) const override
Check if the address of the incoming MIDI message is within the range of addresses and in one of the ...
Definition: NoteCCRange.hpp:179
SimpleNoteCCValueCallback::updateAll
virtual void updateAll(const INoteCCValue &noteccval)
Definition: NoteCCRange.hpp:36
CCRange
Definition: NoteCCRange.hpp:142