Control Surface  1.2.0
MIDI Control Surface library for Arduino
VPotRing.hpp
Go to the documentation of this file.
1 #pragma once
2 
5 
7 
8 namespace MCU {
9 
10 constexpr static uint8_t VPotRingAddress = 0x30;
11 
12 inline int8_t minimum(int8_t a, int8_t b) { return a > b ? b : a; }
13 inline int8_t maximum(int8_t a, int8_t b) { return a < b ? b : a; }
14 
16  VPotEmptyCallback() = default;
17  template <class T>
18  void begin(const T &) {}
19  template <class T>
20  void update(const T &) {}
21 };
22 
26 class IVPotRing {
27  protected:
28  IVPotRing() = default;
29 
30  public:
32  uint8_t getPosition() const { return getPosition(getValue()); }
34  bool getCenterLed() const { return getCenterLed(getValue()); }
37  uint8_t getMode() const { return getMode(getValue()); }
38 
40  uint8_t getStartOn() const {
41  int8_t position = getPosition();
42  if (position == 0)
43  return 0;
44  int8_t value = position - 1;
45  switch (getMode()) {
46  case 0: return value;
47  case 1: return minimum(value, 5);
48  case 2: return 0;
49  case 3: return maximum(5 - value, 0);
50  // Shouldn't happen, just keeps the compiler happy:
51  default: return 0;
52  }
53  }
54 
56  uint8_t getStartOff() const {
57  uint8_t value = getPosition();
58  switch (getMode()) {
59  case 0: return value;
60  case 1: return maximum(value, 6);
61  case 2: return value;
62  case 3: return minimum(5 + value, 11);
63  // Shouldn't happen, just keeps the compiler happy:
64  default: return 0;
65  }
66  }
67 
68  private:
69  virtual uint8_t getValue() const = 0;
70 
72  static uint8_t getPosition(uint8_t value) {
73  uint8_t position = value & 0x0F;
74  return position < 0x0C ? position : 0x0B;
75  }
77  static bool getCenterLed(uint8_t value) { return value & 0x40; }
79  static uint8_t getMode(uint8_t value) { return (value & 0x30) >> 4; }
80 };
81 
82 template <uint8_t NumValues, class Callback>
83 class VPotRing_Base : public MIDIInputElementCC, public IVPotRing {
84  protected:
85  VPotRing_Base(uint8_t track, const MIDIChannelCN &channelCN,
86  const Callback &callback)
87  : MIDIInputElementCC{{track + VPotRingAddress - 1, channelCN}},
88  callback(callback) {}
89 
90  public:
92  void begin() override { callback.begin(*this); }
93 
95  void reset() override {
96 #ifdef VPOTRING_RESET
97  values = {{}};
98  callback.update(*this);
99 #endif
100  }
101 
102  protected:
105  static uint8_t sanitizeValue(uint8_t value) {
106  return (value & 0x0F) < 0x0C ? value : ((value & 0xF0) | 0xB);
107  }
108 
109  private:
110  bool updateImpl(const ChannelMessageMatcher &midimsg,
111  const MIDIAddress &target) override {
112  uint8_t index = getBankIndex(target);
113  uint8_t value = sanitizeValue(midimsg.data2);
114  values[index] = value;
115  if (getSelection() == index)
116  callback.update(*this);
117  return true;
118  }
119 
120  uint8_t getValue() const override { return values[getSelection()]; }
121 
123  virtual uint8_t getSelection() const { return 0; }
124 
126  virtual setting_t getBankIndex(const MIDIAddress &target) const {
127  (void)target;
128  return 0;
129  }
130 
132 
133  public:
134  Callback callback;
135 };
136 
137 // -------------------------------------------------------------------------- //
138 
145 template <class Callback = VPotEmptyCallback>
146 class GenericVPotRing : public VPotRing_Base<1, Callback> {
147  public:
148  GenericVPotRing(uint8_t track, const MIDIChannelCN &channelCN,
149  const Callback &callback)
150  : VPotRing_Base<1, Callback>{track, channelCN, callback} {}
151 };
152 
159 class VPotRing : public GenericVPotRing<> {
160  public:
161  VPotRing(uint8_t track, const MIDIChannelCN &channelCN = CHANNEL_1)
162  : GenericVPotRing{track, channelCN, {}} {}
163 };
164 
165 // -------------------------------------------------------------------------- //
166 
167 namespace Bankable {
168 
178 template <uint8_t NumBanks, class Callback = VPotEmptyCallback>
179 class GenericVPotRing : public VPotRing_Base<NumBanks, Callback>,
180  public BankableMIDIInput<NumBanks> {
181  public:
182  GenericVPotRing(BankConfig<NumBanks> config, uint8_t track,
183  const MIDIChannelCN &channelCN, const Callback &callback)
184  : VPotRing_Base<NumBanks, Callback>{track, channelCN, callback},
185  BankableMIDIInput<NumBanks>{config} {}
186 
187  private:
188  setting_t getSelection() const override {
190  };
191 
192  uint8_t getBankIndex(const MIDIAddress &target) const override {
194  }
195 
198  bool match(const MIDIAddress &target) const override {
200  this->address);
201  }
202 
203  void onBankSettingChange() override { this->callback.update(*this); }
204 };
205 
214 template <uint8_t NumBanks>
215 class VPotRing : public GenericVPotRing<NumBanks> {
216  public:
217  VPotRing(BankConfig<NumBanks> config, uint8_t track,
218  MIDIChannelCN channelCN = CHANNEL_1)
219  : GenericVPotRing<NumBanks>{config, track, channelCN, {}} {}
220 };
221 
222 } // namespace Bankable
223 
224 } // namespace MCU
225 
MCU::Bankable::VPotRing
A class for MIDI input elements that represent Mackie Control Universal V-Pots.
Definition: VPotRing.hpp:215
MIDIAddress
A type-safe utility class for saving a MIDI address consisting of a 7-bit address,...
Definition: MIDIAddress.hpp:91
MCU::VPotRingAddress
constexpr static uint8_t VPotRingAddress
Definition: VPotRing.hpp:10
MCU::IVPotRing
Definition: VPotRing.hpp:26
MCU::IVPotRing::getCenterLed
static bool getCenterLed(uint8_t value)
Extract the center LED state from the raw value.
Definition: VPotRing.hpp:77
MCU::maximum
int8_t maximum(int8_t a, int8_t b)
Definition: VPotRing.hpp:13
MIDIInputElement::address
const MIDIAddress address
Definition: MIDIInputElement.hpp:83
MCU::VPotEmptyCallback::begin
void begin(const T &)
Definition: VPotRing.hpp:18
MCU::Bankable::GenericVPotRing::onBankSettingChange
void onBankSettingChange() override
A function to be executed each time the bank setting changes.
Definition: VPotRing.hpp:203
MCU::Bankable::GenericVPotRing
A class for MIDI input elements that represent Mackie Control Universal V-Pots.
Definition: VPotRing.hpp:180
Bankable
A namespace for MIDI elements that can be added to a Bank, to change their address or channel.
Definition: BankAddresses.hpp:7
BankableMIDIInput::getBankIndex
uint8_t getBankIndex(const MIDIAddress &target, const MIDIAddress &base) const
Calculate the bank setting of a given MIDI address, relative to a base address.
Definition: BankableMIDIInput.hpp:71
MCU::IVPotRing::getMode
uint8_t getMode() const
Return the mode of the V-Pot ring: 0 = single dot, 1 = boost/cut, 2 = wrap, 3 = spread.
Definition: VPotRing.hpp:37
MCU::VPotRing_Base::begin
void begin() override
Initialize.
Definition: VPotRing.hpp:92
ChannelMessageMatcher::data2
uint8_t data2
Definition: ChannelMessageMatcher.hpp:20
MCU::Bankable::GenericVPotRing::getSelection
setting_t getSelection() const override
Definition: VPotRing.hpp:188
MCU::VPotRing_Base::VPotRing_Base
VPotRing_Base(uint8_t track, const MIDIChannelCN &channelCN, const Callback &callback)
Definition: VPotRing.hpp:85
MCU::Bankable::GenericVPotRing::match
bool match(const MIDIAddress &target) const override
Check if the address of the incoming MIDI message is in one of the banks of this element.
Definition: VPotRing.hpp:198
MCU::VPotEmptyCallback::update
void update(const T &)
Definition: VPotRing.hpp:20
MCU::Bankable::GenericVPotRing::GenericVPotRing
GenericVPotRing(BankConfig< NumBanks > config, uint8_t track, const MIDIChannelCN &channelCN, const Callback &callback)
Definition: VPotRing.hpp:182
MCU
Definition: LCDDisplay.hpp:10
MCU::IVPotRing::getStartOff
uint8_t getStartOff() const
Get the first segment that should be off.
Definition: VPotRing.hpp:56
MCU::VPotRing_Base::sanitizeValue
static uint8_t sanitizeValue(uint8_t value)
Make sure that the received value is valid and will not result in array out of bounds conditions.
Definition: VPotRing.hpp:105
MIDIChannelCN
A class for saving a MIDI channel and cable number.
Definition: MIDIAddress.hpp:19
MCU::VPotRing::VPotRing
VPotRing(uint8_t track, const MIDIChannelCN &channelCN=CHANNEL_1)
Definition: VPotRing.hpp:161
BEGIN_CS_NAMESPACE
#define BEGIN_CS_NAMESPACE
Definition: Settings/NamespaceSettings.hpp:9
MCU::IVPotRing::getMode
static uint8_t getMode(uint8_t value)
Extract the mode from the raw value.
Definition: VPotRing.hpp:79
MIDIInputElementCC
Class for objects that listen for incoming MIDI Controller Change events.
Definition: MIDIInputElementCC.hpp:26
MCU::VPotRing_Base
Definition: VPotRing.hpp:83
ChannelMessageMatcher
Struct for easily matching MIDI messages.
Definition: ChannelMessageMatcher.hpp:10
MCU::IVPotRing::getCenterLed
bool getCenterLed() const
Return the status of the center LED of the V-Pot ring.
Definition: VPotRing.hpp:34
MCU::VPotRing_Base::getValue
uint8_t getValue() const override
Definition: VPotRing.hpp:120
END_CS_NAMESPACE
#define END_CS_NAMESPACE
Definition: Settings/NamespaceSettings.hpp:10
MCU::VPotRing
A class for MIDI input elements that represent Mackie Control Universal V-Pots.
Definition: VPotRing.hpp:159
BankableMIDIInput::getSelection
setting_t getSelection() const
Get the current bank setting.
Definition: BankableMIDIInput.hpp:59
AH::Array
An array wrapper for easy copying, comparing, and iterating.
Definition: Array.hpp:36
MCU::VPotEmptyCallback::VPotEmptyCallback
VPotEmptyCallback()=default
MCU::GenericVPotRing
A class for MIDI input elements that represent Mackie Control Universal V-Pots.
Definition: VPotRing.hpp:146
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
MIDIInputElementCC.hpp
MCU::Bankable::VPotRing::VPotRing
VPotRing(BankConfig< NumBanks > config, uint8_t track, MIDIChannelCN channelCN=CHANNEL_1)
Definition: VPotRing.hpp:217
MCU::VPotRing_Base::getSelection
virtual uint8_t getSelection() const
Get the active bank selection.
Definition: VPotRing.hpp:123
MCU::VPotRing_Base::getBankIndex
virtual setting_t getBankIndex(const MIDIAddress &target) const
Get the bank index from a MIDI address.
Definition: VPotRing.hpp:126
MCU::IVPotRing::getPosition
uint8_t getPosition() const
Return the position of the V-Pot ring. [0, 11].
Definition: VPotRing.hpp:32
MCU::GenericVPotRing::GenericVPotRing
GenericVPotRing(uint8_t track, const MIDIChannelCN &channelCN, const Callback &callback)
Definition: VPotRing.hpp:148
MCU::VPotRing_Base::values
Array< uint8_t, NumValues > values
Definition: VPotRing.hpp:131
MCU::Bankable::GenericVPotRing::getBankIndex
uint8_t getBankIndex(const MIDIAddress &target) const override
Get the bank index from a MIDI address.
Definition: VPotRing.hpp:192
MCU::VPotRing_Base::callback
Callback callback
Definition: VPotRing.hpp:134
MCU::IVPotRing::IVPotRing
IVPotRing()=default
setting_t
uint8_t setting_t
The type used for Selectors.
Definition: Def.hpp:50
MCU::IVPotRing::getValue
virtual uint8_t getValue() const =0
MCU::IVPotRing::getPosition
static uint8_t getPosition(uint8_t value)
Extract the position from the raw value.
Definition: VPotRing.hpp:72
MCU::VPotEmptyCallback
Definition: VPotRing.hpp:15
BankableMIDIInput
A base class for all MIDIInputElements that can be banked.
Definition: BankableMIDIInput.hpp:21
BankConfig
Definition: BankConfig.hpp:51
CHANNEL_1
constexpr Channel CHANNEL_1
Definition: Channel.hpp:111
MCU::IVPotRing::getStartOn
uint8_t getStartOn() const
Get the first segment that should be on.
Definition: VPotRing.hpp:40
BankableMIDIInput.hpp
MCU::VPotRing_Base::updateImpl
bool updateImpl(const ChannelMessageMatcher &midimsg, const MIDIAddress &target) override
Update the internal state with the new MIDI message.
Definition: VPotRing.hpp:110
MCU::minimum
int8_t minimum(int8_t a, int8_t b)
Definition: VPotRing.hpp:12
MCU::VPotRing_Base::reset
void reset() override
Reset all values to zero.
Definition: VPotRing.hpp:95