Control Surface  1.1.1
MIDI Control Surface library for Arduino
NoteCCRange.hpp
Go to the documentation of this file.
1 #pragma once
2 
6 
8 
13 class INoteCCValue {
14  protected:
16 
17  public:
19  uint8_t length() const { return rangeLength; }
21  virtual uint8_t getValue(uint8_t index) const = 0;
24  uint8_t getValue() const { return getValue(0); }
25 
26  private:
27  uint8_t rangeLength;
28 };
29 
34  public:
35  void begin(const INoteCCValue &) {}
36  void update(const INoteCCValue &, uint8_t) {}
37  void updateAll(const INoteCCValue &) {}
38 };
39 
47  protected:
48  SimpleNoteCCValueCallback() = default;
49 
50  public:
52  virtual void begin(const INoteCCValue &) {}
55  virtual void update(const INoteCCValue &noteccval, uint8_t index) = 0;
58  virtual void updateAll(const INoteCCValue &noteccval) {
59  for (uint8_t i = 0; i < noteccval.length(); ++i)
60  update(noteccval, i);
61  }
62 };
63 
64 // -------------------------------------------------------------------------- //
65 
72 template <class MIDIInput_t, uint8_t RangeLen, uint8_t NumBanks, class Callback>
73 class NoteCCRange : public MIDIInput_t, public INoteCCValue {
74  public:
75  NoteCCRange(MIDICNChannelAddress address, const Callback &callback)
76  : MIDIInput_t{address}, INoteCCValue{RangeLen}, callback(callback) {}
77 
79  uint8_t getValue(uint8_t index) const final override {
80  return values[getSelection()][index];
81  }
83 
85  void begin() override { callback.begin(*this); }
87  void reset() override {
88  values = {{}};
89  callback.updateAll(*this);
90  }
91 
92  private:
93  // Called when a MIDI message comes in, and if that message has been matched
94  // by the `match` method.
95  bool updateImpl(const ChannelMessageMatcher &midimsg,
96  const MIDICNChannelAddress &target) override {
97  // Compute the offsets/indices in the range and the bank.
98  // E.g. if the start address of the range is 10 and the incoming message
99  // is on address 15, the range index will be 5 = 15 - 10.
100  // Very similar for banks, but in that case there are 3 possible
101  // addresses (note/controller number, MIDI channel and MIDI cable).
102  uint8_t bankIndex = this->getBankIndex(target);
103  uint8_t rangeIndex = this->getRangeIndex(target);
104  // extract the velocity or controller value from the message
105  uint8_t value = getValueFromMIDIMessage(midimsg);
106  // save the value
107  values[bankIndex][rangeIndex] = value;
108  // if the bank that the message belongs to is the active bank,
109  // update the display
110  if (bankIndex == this->getSelection())
111  callback.update(*this, rangeIndex);
112  // event was handled successfully
113  return true;
114  }
115 
119  static uint8_t
121  return midimsg.type == NOTE_OFF ? 0 : midimsg.data2;
122  }
123 
125  virtual uint8_t getSelection() const { return 0; }
126 
129  // Default implementation for non-bankable version (bank is always 0)
130  (void)target;
131  return 0;
132  }
133 
135  virtual uint8_t getRangeIndex(MIDICNChannelAddress target) const {
136  // Default implementation for non-bankable version (base address of the
137  // range is fixed)
138  return target.getAddress() - this->address.getAddress();
139  }
140 
143 
144  public:
146  Callback callback;
148  constexpr static uint8_t length() { return RangeLen; }
149 };
150 
151 // -------------------------------------------------------------------------- //
152 
153 template <class MIDIInput_t, uint8_t RangeLen,
154  class Callback = NoteCCRangeEmptyCallback>
156  : public NoteCCRange<MIDIInput_t, RangeLen, 1, Callback> {
157  public:
159  : NoteCCRange<MIDIInput_t, RangeLen, 1, Callback>{address, callback} {}
160 
161  private:
164  bool match(const MIDICNChannelAddress &target) const override {
166  target, this->address, RangeLen);
167  }
168 };
169 
170 template <uint8_t RangeLen, class Callback = NoteCCRangeEmptyCallback>
171 using GenericNoteRange =
173 
174 template <uint8_t RangeLen, class Callback = NoteCCRangeEmptyCallback>
175 using GenericCCRange =
177 
178 template <class Callback = NoteCCRangeEmptyCallback>
180 
181 template <class Callback = NoteCCRangeEmptyCallback>
183 
192 template <uint8_t RangeLen>
193 class NoteRange : public GenericNoteRange<RangeLen> {
194  public:
196  : GenericNoteRange<RangeLen>{address, {}} {}
197 };
198 
205 class NoteValue : public GenericNoteValue<> {
206  public:
207  NoteValue(MIDICNChannelAddress address) : GenericNoteValue<>{address, {}} {}
208 };
209 using MIDINote[[deprecated("Use NoteValue instead")]] = NoteValue;
210 
219 template <uint8_t RangeLen>
220 class CCRange : public GenericCCRange<RangeLen> {
221  public:
223  : GenericCCRange<RangeLen>{address, {}} {}
224 };
225 
232 class CCValue : public GenericCCValue<> {
233  public:
234  CCValue(MIDICNChannelAddress address) : GenericCCValue<>{address, {}} {}
235 };
236 
237 // -------------------------------------------------------------------------- //
238 
239 namespace Bankable {
240 
245 template <class MIDIInput_t, uint8_t RangeLen, uint8_t NumBanks,
246  class Callback = NoteCCRangeEmptyCallback>
248  : public NoteCCRange<MIDIInput_t, RangeLen, NumBanks, Callback>,
249  public BankableMIDIInput<NumBanks> {
250  public:
252  MIDICNChannelAddress address,
253  const Callback &callback)
254  : NoteCCRange<MIDIInput_t, RangeLen, NumBanks, Callback>{
255  address,
256  callback,
257  }, BankableMIDIInput<NumBanks>{config} {}
258 
259  private:
262  bool match(const MIDICNChannelAddress &target) const override {
264  target, this->address, RangeLen);
265  }
266 
267  setting_t getSelection() const override {
269  };
270 
271  uint8_t getBankIndex(MIDICNChannelAddress target) const override {
272  return BankableMIDIInput<NumBanks>::getBankIndex(target, this->address);
273  }
274 
275  uint8_t getRangeIndex(MIDICNChannelAddress target) const override {
277  this->address);
278  }
279 
280  void onBankSettingChange() override { this->callback.updateAll(*this); }
281 };
282 
283 template <uint8_t RangeLen, uint8_t NumBanks,
284  class Callback = NoteCCRangeEmptyCallback>
285 using GenericNoteRange =
287 
288 template <uint8_t RangeLen, uint8_t NumBanks,
289  class Callback = NoteCCRangeEmptyCallback>
290 using GenericCCRange =
292 
293 template <uint8_t NumBanks, class Callback = NoteCCRangeEmptyCallback>
294 using GenericNoteValue =
296 
297 template <uint8_t NumBanks, class Callback = NoteCCRangeEmptyCallback>
298 using GenericCCValue =
300 
311 template <uint8_t RangeLen, uint8_t NumBanks>
312 class NoteRange : public GenericNoteRange<RangeLen, NumBanks> {
313  public:
315  : GenericNoteRange<RangeLen, NumBanks>{config, address, {}} {}
316 };
317 
326 template <uint8_t NumBanks>
327 class NoteValue : public GenericNoteValue<NumBanks> {
328  public:
330  : GenericNoteValue<NumBanks>{config, address, {}} {}
331 };
332 
335 template <uint8_t NumBanks>
336 using MIDINote[[deprecated("Use NoteValue instead")]] = NoteValue<NumBanks>;
337 
348 template <uint8_t RangeLen, uint8_t NumBanks>
349 class CCRange : public GenericCCRange<RangeLen, NumBanks> {
350  public:
352  : GenericCCRange<RangeLen, NumBanks>{config, address, {}} {}
353 };
354 
363 template <uint8_t NumBanks>
364 class CCValue : public GenericCCValue<NumBanks> {
365  public:
367  : GenericCCValue<NumBanks>{config, address, {}} {}
368 };
369 
370 } // namespace Bankable
371 
CCValue::CCValue
CCValue(MIDICNChannelAddress address)
Definition: NoteCCRange.hpp:234
NoteCCRange::getBankIndex
virtual setting_t getBankIndex(MIDICNChannelAddress target) const
Get the bank index from a MIDI address.
Definition: NoteCCRange.hpp:128
NoteValue
MIDI Input Element that listens to a single note and saves its velocity value.
Definition: NoteCCRange.hpp:205
NoteCCRange::values
Array< Array< uint8_t, RangeLen >, NumBanks > values
A 2D array for saving all values of the range, for all banks.
Definition: NoteCCRange.hpp:142
NoteCCRange::length
constexpr static uint8_t length()
Get the length of the range.
Definition: NoteCCRange.hpp:148
ChannelMessageMatcher::type
uint8_t type
Definition: ChannelMessageMatcher.hpp:18
Bankable
A namespace for MIDI elements that can be added to a Bank, to change their address or channel.
Definition: BankAddresses.hpp:7
INoteCCValue::getValue
uint8_t getValue() const
Get the velocity or controller value of the first or only note or controller.
Definition: NoteCCRange.hpp:24
SimpleNoteCCValueCallback::updateAll
virtual void updateAll(const INoteCCValue &noteccval)
Update all values: called when a bank change causes all values to (possibly) change,...
Definition: NoteCCRange.hpp:58
GenericNoteCCRange
Definition: NoteCCRange.hpp:155
INoteCCValue
Interface for NoteCCValue objects: provides getters for the velocity or controller values.
Definition: NoteCCRange.hpp:13
ChannelMessageMatcher::data2
uint8_t data2
Definition: ChannelMessageMatcher.hpp:21
NoteValue::NoteValue
NoteValue(MIDICNChannelAddress address)
Definition: NoteCCRange.hpp:207
INoteCCValue::rangeLength
uint8_t rangeLength
Definition: NoteCCRange.hpp:27
NoteCCRange::getSelection
virtual uint8_t getSelection() const
Get the active bank selection.
Definition: NoteCCRange.hpp:125
SimpleNoteCCValueCallback
A callback for NoteCCRange with an action that can be implemented by the user.
Definition: NoteCCRange.hpp:46
CCRange::CCRange
CCRange(MIDICNChannelAddress address)
Definition: NoteCCRange.hpp:222
INoteCCValue::length
uint8_t length() const
Get the length of the range of note/CC addresses.
Definition: NoteCCRange.hpp:19
CCValue
MIDI Input Element that listens to a single controller and saves its value.
Definition: NoteCCRange.hpp:232
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
Bankable::GenericNoteCCRange
Definition: NoteCCRange.hpp:247
BEGIN_CS_NAMESPACE
#define BEGIN_CS_NAMESPACE
Definition: Settings/NamespaceSettings.hpp:9
Bankable::GenericNoteCCRange::GenericNoteCCRange
GenericNoteCCRange(BankConfig< NumBanks > config, MIDICNChannelAddress address, const Callback &callback)
Definition: NoteCCRange.hpp:251
ChannelMessageMatcher
Struct for easily matching MIDI messages.
Definition: ChannelMessageMatcher.hpp:10
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
Bankable::GenericNoteCCRange::getSelection
setting_t getSelection() const override
Get the active bank selection.
Definition: NoteCCRange.hpp:267
Bankable::GenericNoteCCRange::getBankIndex
uint8_t getBankIndex(MIDICNChannelAddress target) const override
Get the bank index from a MIDI address.
Definition: NoteCCRange.hpp:271
END_CS_NAMESPACE
#define END_CS_NAMESPACE
Definition: Settings/NamespaceSettings.hpp:10
Bankable::GenericNoteCCRange::getRangeIndex
uint8_t getRangeIndex(MIDICNChannelAddress target) const override
Get the index of the given MIDI address in the range.
Definition: NoteCCRange.hpp:275
NoteCCRange::callback
Callback callback
Callback that is called when a value in the active bank changes.
Definition: NoteCCRange.hpp:146
NoteRange
MIDI Input Element that listens to a range of notes and saves their velocity values.
Definition: NoteCCRange.hpp:193
SimpleNoteCCValueCallback::begin
virtual void begin(const INoteCCValue &)
Initialize: called once.
Definition: NoteCCRange.hpp:52
NoteCCRangeEmptyCallback::begin
void begin(const INoteCCValue &)
Definition: NoteCCRange.hpp:35
BankableMIDIInput::getSelection
setting_t getSelection() const
Get the current bank setting.
Definition: BankableMIDIInput.hpp:59
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
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
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:164
Bankable::CCValue
MIDI Input Element that listens to a single controller and saves its value.
Definition: NoteCCRange.hpp:364
NoteCCRange
Base class for all other classes that listen for incoming MIDI Note or Control Change messages and sa...
Definition: NoteCCRange.hpp:73
NoteRange::NoteRange
NoteRange(MIDICNChannelAddress address)
Definition: NoteCCRange.hpp:195
MIDICNChannelAddress::getAddress
constexpr uint8_t getAddress() const
Get the address [0, 127].
Definition: MIDICNChannelAddress.hpp:141
NoteCCRangeEmptyCallback
A callback for NoteCCRange that doesn't do anything.
Definition: NoteCCRange.hpp:33
MIDIInputElementCC.hpp
SimpleNoteCCValueCallback::SimpleNoteCCValueCallback
SimpleNoteCCValueCallback()=default
NoteCCRange::NoteCCRange
NoteCCRange(MIDICNChannelAddress address, const Callback &callback)
Definition: NoteCCRange.hpp:75
NoteCCRange::getValue
uint8_t getValue(uint8_t index) const final override
Definition: NoteCCRange.hpp:79
NOTE_OFF
const uint8_t NOTE_OFF
Definition: MIDI_Parser.hpp:16
NoteCCRange::getRangeIndex
virtual uint8_t getRangeIndex(MIDICNChannelAddress target) const
Get the index of the given MIDI address in the range.
Definition: NoteCCRange.hpp:135
INoteCCValue::INoteCCValue
INoteCCValue(uint8_t rangeLength)
Definition: NoteCCRange.hpp:15
Bankable::CCValue::CCValue
CCValue(BankConfig< NumBanks > config, MIDICNChannelAddress address)
Definition: NoteCCRange.hpp:366
GenericNoteCCRange::GenericNoteCCRange
GenericNoteCCRange(MIDICNChannelAddress address, const Callback &callback)
Definition: NoteCCRange.hpp:158
NoteCCRange::begin
void begin() override
Initialize.
Definition: NoteCCRange.hpp:85
SimpleNoteCCValueCallback::update
virtual void update(const INoteCCValue &noteccval, uint8_t index)=0
Update the given index: called when a new message is received for this index.
setting_t
uint8_t setting_t
The type used for Selectors.
Definition: Def.hpp:50
Bankable::CCRange
MIDI Input Element that listens to a range of controllers and saves their values.
Definition: NoteCCRange.hpp:349
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
BankableMIDIInput
A base class for all MIDIInputElements that can be banked.
Definition: Bank.hpp:13
Bankable::NoteRange
MIDI Input Element that listens to a range of notes and saves their velocity values.
Definition: NoteCCRange.hpp:312
BankConfig
A struct for selecting the bank of BankableMIDIInputs and the bank type.
Definition: BankConfig.hpp:39
Bankable::GenericNoteCCRange::onBankSettingChange
void onBankSettingChange() override
A function to be executed each time the bank setting changes.
Definition: NoteCCRange.hpp:280
NoteCCRangeEmptyCallback::update
void update(const INoteCCValue &, uint8_t)
Definition: NoteCCRange.hpp:36
Bankable::NoteValue
MIDI Input Element that listens to a single note and saves its value.
Definition: NoteCCRange.hpp:327
NoteCCRange::updateImpl
bool updateImpl(const ChannelMessageMatcher &midimsg, const MIDICNChannelAddress &target) override
Definition: NoteCCRange.hpp:95
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:262
Bankable::NoteRange::NoteRange
NoteRange(BankConfig< NumBanks > config, MIDICNChannelAddress address)
Definition: NoteCCRange.hpp:314
BankableMIDIInput.hpp
Bankable::NoteValue::NoteValue
NoteValue(BankConfig< NumBanks > config, MIDICNChannelAddress address)
Definition: NoteCCRange.hpp:329
NoteCCRange::reset
void reset() override
Reset all values to zero.
Definition: NoteCCRange.hpp:87
NoteCCRange::getValueFromMIDIMessage
static uint8_t getValueFromMIDIMessage(const ChannelMessageMatcher &midimsg)
Extract the "value" from a MIDI Note or Control Change message.
Definition: NoteCCRange.hpp:120
NoteCCRangeEmptyCallback::updateAll
void updateAll(const INoteCCValue &)
Definition: NoteCCRange.hpp:37
CCRange
MIDI Input Element that listens to a range of controllers and saves their values.
Definition: NoteCCRange.hpp:220
Bankable::CCRange::CCRange
CCRange(BankConfig< NumBanks > config, MIDICNChannelAddress address)
Definition: NoteCCRange.hpp:351