This is an old version of the documentation. View the latest version here.
Control Surface  1.0.0
MIDI Control Surface library for Arduino
BankableMIDIInput.hpp
Go to the documentation of this file.
1 #pragma once
2 
3 #include "Bank.hpp"
4 #include "BankConfig.hpp"
6 #include <Helpers/Debug.hpp>
7 #include <Helpers/LinkedList.hpp>
8 
10 
20 template <setting_t N>
21 class BankableMIDIInput : public DoublyLinkable<BankableMIDIInput<N>> {
22  friend class Bank<N>;
23 
24  protected:
34  bank.add(this);
35  }
36 
46  : BankableMIDIInput<N>(config.bank, config.type) {}
47 
48  public:
52  virtual ~BankableMIDIInput() { bank.remove(this); }
53 
59  setting_t getSelection() const { return bank.getSelection(); }
60 
71  uint8_t getBankIndex(const MIDICNChannelAddress &target,
72  const MIDICNChannelAddress &base) const {
73  switch (type) {
74  case CHANGE_ADDRESS:
75  return (target.getAddress() - base.getAddress()) /
76  bank.getTracksPerBank();
77  case CHANGE_CHANNEL:
78  return (target.getRawChannel() - base.getRawChannel()) /
79  bank.getTracksPerBank();
80  case CHANGE_CABLENB:
81  return (target.getCableNumber() - base.getCableNumber()) /
82  bank.getTracksPerBank();
83  default: return 0;
84  }
85  }
86 
87  protected:
113  bool matchBankable(uint8_t toMatch, uint8_t base) const {
114  uint8_t diff = toMatch - base;
115  return toMatch >= base && diff < N * bank.getTracksPerBank() &&
116  diff % bank.getTracksPerBank() == 0;
117  }
118 
132  bool matchBankableInRange(uint8_t toMatch, uint8_t base,
133  uint8_t length) const {
134  uint8_t diff = toMatch - base;
135  return toMatch >= base && diff < N * bank.getTracksPerBank() &&
136  diff % bank.getTracksPerBank() < length;
137  }
138 
144  MIDICNChannelAddress base) const {
145  uint8_t diff = target.getAddress() - base.getAddress();
146  if (type == CHANGE_ADDRESS)
147  diff %= bank.getTracksPerBank();
148  return diff;
149  }
150 
162  static bool inRange(uint8_t toMatch, uint8_t base, uint8_t length) {
163  return (base <= toMatch) && (toMatch - base < length);
164  }
165 
175  bool matchBankable(const MIDICNChannelAddress &toMatch,
176  const MIDICNChannelAddress &base) const {
177  if (!toMatch.isValid() || !base.isValid())
178  return false;
179  switch (type) {
180  case CHANGE_ADDRESS: {
181  return toMatch.getChannel() == base.getChannel() &&
182  toMatch.getCableNumber() == base.getCableNumber() &&
183  matchBankable(toMatch.getAddress(), base.getAddress());
184  }
185  case CHANGE_CHANNEL: {
186  return toMatch.getAddress() == base.getAddress() &&
187  toMatch.getCableNumber() == base.getCableNumber() &&
188  matchBankable(toMatch.getRawChannel(),
189  base.getRawChannel());
190  }
191  case CHANGE_CABLENB: {
192  return toMatch.getAddress() == base.getAddress() &&
193  toMatch.getChannel() == base.getChannel() &&
194  matchBankable(toMatch.getCableNumber(),
195  base.getCableNumber());
196  }
197  default: return false;
198  }
199  }
200 
213  const MIDICNChannelAddress &base,
214  uint8_t length) const {
215  if (!toMatch.isValid() || !base.isValid())
216  return false;
217  switch (type) {
218  case CHANGE_ADDRESS: {
219  return toMatch.getChannel() == base.getChannel() &&
220  toMatch.getCableNumber() == base.getCableNumber() &&
222  base.getAddress(), length);
223  }
224  case CHANGE_CHANNEL: {
225  return inRange(toMatch.getAddress(), base.getAddress(),
226  length) &&
227  toMatch.getCableNumber() == base.getCableNumber() &&
228  matchBankable(toMatch.getChannel(), base.getChannel());
229  }
230  case CHANGE_CABLENB: {
231  return inRange(toMatch.getAddress(), base.getAddress(),
232  length) &&
233  toMatch.getChannel() == base.getChannel() &&
234  matchBankable(toMatch.getCableNumber(),
235  base.getCableNumber());
236  }
237  default: return false;
238  }
239  }
240 
241  private:
243  const BankType type;
244 
255  virtual void onBankSettingChange() {}
256 };
257 
BankableMIDIInput::matchBankableInRange
bool matchBankableInRange(uint8_t toMatch, uint8_t base, uint8_t length) const
Check if the given address is part of the bank relative to the base address.
Definition: BankableMIDIInput.hpp:132
Bank
A class that groups Bankable BankableMIDIOutputs and BankableMIDIInputs, and allows the user to chang...
Definition: Bank.hpp:77
MIDICNChannelAddress::getCableNumber
constexpr uint8_t getCableNumber() const
Get the cable number [0, 15].
Definition: MIDICNChannelAddress.hpp:151
BankConfig.hpp
MIDICNChannelAddress::isValid
constexpr bool isValid() const
Check if the MIDI address is valid.
Definition: MIDICNChannelAddress.hpp:154
BankableMIDIInput::inRange
static bool inRange(uint8_t toMatch, uint8_t base, uint8_t length)
Check whether a given address is within a range of given length starting from the given base address.
Definition: BankableMIDIInput.hpp:162
BankableMIDIInput::type
const BankType type
Definition: BankableMIDIInput.hpp:243
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
MIDICNChannelAddress.hpp
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
BankableMIDIInput::onBankSettingChange
virtual void onBankSettingChange()
A function to be executed each time the bank setting changes.
Definition: BankableMIDIInput.hpp:255
LinkedList.hpp
BEGIN_CS_NAMESPACE
#define BEGIN_CS_NAMESPACE
Definition: NamespaceSettings.hpp:9
MIDICNChannelAddress
A type-safe utility class for saving a MIDI address consisting of a 7-bit address,...
Definition: MIDICNChannelAddress.hpp:82
BankableMIDIInput::matchBankable
bool matchBankable(uint8_t toMatch, uint8_t base) const
Check if the given address is part of the bank relative to the base address.
Definition: BankableMIDIInput.hpp:113
CHANGE_CHANNEL
Change the offset of the channel number of the element.
Definition: BankConfig.hpp:21
BankableMIDIInput::~BankableMIDIInput
virtual ~BankableMIDIInput()
Destructor: remove element from the bank.
Definition: BankableMIDIInput.hpp:52
MIDICNChannelAddress::getAddress
constexpr uint8_t getAddress() const
Get the address [0, 127].
Definition: MIDICNChannelAddress.hpp:141
END_CS_NAMESPACE
#define END_CS_NAMESPACE
Definition: NamespaceSettings.hpp:10
CHANGE_CABLENB
Change the offset of the cable number of the element (experimental).
Definition: BankConfig.hpp:27
BankType
BankType
An enumeration of the different bank types.
Definition: BankConfig.hpp:12
BankableMIDIInput::BankableMIDIInput
BankableMIDIInput(const BankConfig< N > &config)
Create a new BankableMIDIInput object, and add it to the bank.
Definition: BankableMIDIInput.hpp:45
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:63
DoublyLinkable
A class that can be inherited from to allow inserting into a DoublyLinkedList.
Definition: LinkedList.hpp:298
Bank.hpp
Debug.hpp
BankableMIDIInput
A base class for all MIDIInputElements that can be banked.
Definition: Bank.hpp:13
MIDICNChannelAddress::getRawChannel
constexpr uint8_t getRawChannel() const
Get the channel [0, 15].
Definition: MIDICNChannelAddress.hpp:148
BankConfig
A struct for selecting the bank of BankableMIDIInputs and the bank type.
Definition: BankConfig.hpp:39
CHANGE_ADDRESS
Change the offset of the address (i.e.
Definition: BankConfig.hpp:17
BankableMIDIInput::matchBankable
bool matchBankable(const MIDICNChannelAddress &toMatch, const MIDICNChannelAddress &base) const
Check whether a given address is part of the bank relative to the base address.
Definition: BankableMIDIInput.hpp:175
MIDICNChannelAddress::getChannel
constexpr Channel getChannel() const
Get the channel [CHANNEL_1, CHANNEL_16].
Definition: MIDICNChannelAddress.hpp:144
BankableMIDIInput::bank
Bank< N > & bank
Definition: BankableMIDIInput.hpp:242
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::BankableMIDIInput
BankableMIDIInput(Bank< N > &bank, BankType type)
Create a new BankableMIDIInput object, and add it to the bank.
Definition: BankableMIDIInput.hpp:33