This is an old version of the documentation. View the latest version here.
Control Surface  1.0.0
MIDI Control Surface library for Arduino
VU.hpp
Go to the documentation of this file.
1 #pragma once
2 
5 #include <Helpers/MinMaxFix.hpp>
7 #include <string.h>
8 
10 
20 class IVU {
21  public:
22  IVU(uint8_t max) : max(max) {}
24  virtual uint8_t getValue() = 0;
26  virtual bool getOverload() = 0;
28  virtual float getFloatValue() { return (float)getValue() / getMax(); }
30  uint8_t getMax() const { return max; }
31 
32  protected:
33  const uint8_t max;
34 };
35 
36 namespace MCU {
37 
39 namespace VUDecay {
41 constexpr unsigned int Hold = 0;
43 constexpr unsigned int Default = 150;
44 } // namespace VUDecay
45 
48  template <class T>
49  void begin(const T &) {}
50  template <class T>
51  void update(const T &) {}
52 };
53 
77 template <uint8_t NumValues, class Callback>
79  protected:
80  VU_Base(uint8_t track, const MIDICNChannel &channelCN,
81  unsigned int decayTime, const Callback &callback)
82  : MIDIInputElementChannelPressure{{track - 1, channelCN}}, IVU(12),
84 
85  public:
87  void begin() override { callback.begin(*this); }
89  void reset() override {
90  values = {};
91  callback.update(*this);
92  }
93 
95  uint8_t getValue() override { return getValue(getSelection()); }
97  bool getOverload() override { return getOverload(getSelection()); }
98 
100  void update() override {
101  if (decayTime && (millis() - prevDecayTime >= decayTime)) {
103  decay();
104  callback.update(*this);
105  }
106  }
107 
108  private:
110  bool updateImpl(const ChannelMessageMatcher &midimsg,
111  const MIDICNChannelAddress &target) override {
112  uint8_t data = midimsg.data1 & 0x0F;
113  uint8_t index = getBankIndex(target);
114  switch (data) {
115  case 0xF: clearOverload(index); break;
116  case 0xE: setOverload(index); break;
117  case 0xD: break; // no meaning
118  default: setValue(index, data); break;
119  }
120  callback.update(*this);
121  return true;
122  }
123 
127  getTarget(const ChannelMessageMatcher &midimsg) const override {
128  return {
129  int8_t(midimsg.data1 >> 4),
130  Channel(midimsg.channel),
131  midimsg.CN,
132  };
133  }
134 
135  void decay() {
136  for (uint8_t i = 0; i < NumValues; ++i)
137  if (getValue(i) > 0)
138  values[i]--;
139  }
140 
142  virtual uint8_t getSelection() const { return 0; }
143 
145  virtual setting_t getBankIndex(const MIDICNChannelAddress &target) const {
146  (void)target;
147  return 0;
148  }
149 
151  void setValue(uint8_t index, uint8_t newValue) {
152  prevDecayTime = millis();
153  values[index] = newValue | (values[index] & 0xF0);
154  }
155 
157  void setOverload(uint8_t index) { values[index] |= 0xF0; }
159  void clearOverload(uint8_t index) { values[index] &= 0x0F; }
161  uint8_t getValue(uint8_t index) const { return values[index] & 0x0F; }
163  bool getOverload(uint8_t index) const { return values[index] & 0xF0; }
164 
165  private:
167  unsigned int decayTime;
168  unsigned long prevDecayTime = 0;
169 
170  public:
171  Callback callback;
172 };
173 
174 // -------------------------------------------------------------------------- //
175 
182 template <class Callback = VUEmptyCallback>
183 class GenericVU : public VU_Base<1, Callback> {
184  public:
205  GenericVU(uint8_t track, const MIDICNChannel &channelCN,
206  unsigned int decayTime, const Callback &callback)
207  : VU_Base<1, Callback>{
208  track,
209  channelCN,
210  decayTime,
211  callback,
212  } {}
213 };
214 
222 class VU : public GenericVU<> {
223  public:
241  VU(uint8_t track, const MIDICNChannel &channelCN,
242  unsigned int decayTime = VUDecay::Default)
243  : GenericVU<>{
244  track,
245  channelCN,
246  decayTime,
247  {},
248  } {}
249 
264  VU(uint8_t track, unsigned int decayTime = VUDecay::Default)
265  : GenericVU<>{
266  track,
267  CHANNEL_1,
268  decayTime,
269  {},
270  } {}
271 };
272 
273 // -------------------------------------------------------------------------- //
274 
275 namespace Bankable {
276 
286 template <uint8_t NumBanks, class Callback = VUEmptyCallback>
287 class GenericVU : public VU_Base<NumBanks, Callback>,
288  public BankableMIDIInput<NumBanks> {
289  public:
313  GenericVU(const BankConfig<NumBanks> &config, uint8_t track,
314  const MIDICNChannel &channelCN, unsigned int decayTime,
315  const Callback &callback)
316  : VU_Base<NumBanks, Callback>{
317  track,
318  channelCN,
319  decayTime,
320  callback,
321  },
322  BankableMIDIInput<NumBanks>{config} {}
323 
324  private:
325  setting_t getSelection() const override {
327  };
328 
329  uint8_t getBankIndex(const MIDICNChannelAddress &target) const override {
331  }
332 
335  bool match(const MIDICNChannelAddress &target) const override {
337  this->address);
338  }
339 
340  void onBankSettingChange() override { this->callback.update(*this); }
341 };
342 
352 template <uint8_t NumBanks>
353 class VU : public GenericVU<NumBanks> {
354  public:
374  VU(const BankConfig<NumBanks> &config, uint8_t track,
375  const MIDICNChannel &channelCN,
376  unsigned int decayTime = VUDecay::Default)
377  : GenericVU<NumBanks>{
378  config, track, channelCN, decayTime, {},
379  } {}
380 
397  VU(const BankConfig<NumBanks> &config, uint8_t track,
398  unsigned int decayTime = VUDecay::Default)
399  : GenericVU<NumBanks>{
400  config, track, CHANNEL_1, decayTime, {},
401  } {}
402 };
403 
404 } // namespace Bankable
405 
406 } // namespace MCU
407 
MCU::VU_Base::getSelection
virtual uint8_t getSelection() const
Get the active bank selection.
Definition: VU.hpp:142
MCU::VU::VU
VU(uint8_t track, const MIDICNChannel &channelCN, unsigned int decayTime=VUDecay::Default)
Construct a new VU object.
Definition: VU.hpp:241
ChannelMessageMatcher::CN
uint8_t CN
Definition: ChannelMessageMatcher.hpp:22
MCU::VU_Base::callback
Callback callback
Definition: VU.hpp:171
Channel
A type-safe class for MIDI channels.
Definition: Channel.hpp:13
MCU::VU_Base::update
void update() override
Update is called periodically, it decays the meter if the time is right.
Definition: VU.hpp:100
IVU::max
const uint8_t max
Definition: VU.hpp:33
IVU
An abstract interface for VU meters.
Definition: VU.hpp:20
MCU::VU_Base::setOverload
void setOverload(uint8_t index)
Set the overload status.
Definition: VU.hpp:157
IVU::getFloatValue
virtual float getFloatValue()
Get the VU meter value as a floating point number.
Definition: VU.hpp:28
Bankable
A namespace for MIDI elements that can be added to a Bank, to change their address or channel.
Definition: BankAddresses.hpp:7
MCU::VU_Base::begin
void begin() override
Initialize.
Definition: VU.hpp:87
MCU::VU_Base::clearOverload
void clearOverload(uint8_t index)
Clear the overload status.
Definition: VU.hpp:159
MCU::VU_Base::getOverload
bool getOverload(uint8_t index) const
Get the overload status value from the raw value.
Definition: VU.hpp:163
MCU::Bankable::GenericVU
A class for MIDI input elements that represent Mackie Control Universal VU meters.
Definition: VU.hpp:287
MCU::Bankable::GenericVU::onBankSettingChange
void onBankSettingChange() override
A function to be executed each time the bank setting changes.
Definition: VU.hpp:340
MCU::VU_Base::getTarget
MIDICNChannelAddress getTarget(const ChannelMessageMatcher &midimsg) const override
The address of the VU meter is the high nibble of the first (and only) data byte.
Definition: VU.hpp:127
IVU::getOverload
virtual bool getOverload()=0
Return the overload status.
MCU::VUEmptyCallback::update
void update(const T &)
Definition: VU.hpp:51
MCU
Names and note and controller numbers for the Mackie Control Universal (MCU) protocol.
Definition: LCDDisplay.hpp:10
MCU::VUEmptyCallback
Empty callback for VU meters that does nothing.
Definition: VU.hpp:47
IVU::getValue
virtual uint8_t getValue()=0
Return the VU meter value as an integer.
MCU::VU_Base::getBankIndex
virtual setting_t getBankIndex(const MIDICNChannelAddress &target) const
Get the bank index from a MIDI address.
Definition: VU.hpp:145
MCU::VU_Base::setValue
void setValue(uint8_t index, uint8_t newValue)
Set the VU meter value.
Definition: VU.hpp:151
ExtendedInputOutput.hpp
MCU::VUDecay::Default
constexpr unsigned int Default
Decay one segment/block every 150 ms if no new values are received.
Definition: VU.hpp:43
MCU::Bankable::VU
A class for MIDI input elements that represent Mackie Control Universal VU meters.
Definition: VU.hpp:353
MCU::VU_Base::getValue
uint8_t getValue(uint8_t index) const
Get the VU meter value from the raw value.
Definition: VU.hpp:161
Array< uint8_t, NumValues >
MCU::Bankable::VU::VU
VU(const BankConfig< NumBanks > &config, uint8_t track, const MIDICNChannel &channelCN, unsigned int decayTime=VUDecay::Default)
Construct a new Bankable VU object.
Definition: VU.hpp:374
MCU::VU::VU
VU(uint8_t track, unsigned int decayTime=VUDecay::Default)
Construct a new VU object.
Definition: VU.hpp:264
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
MCU::VUDecay::Hold
constexpr unsigned int Hold
Don't decay automatically, hold the latest value until a new one is received.
Definition: VU.hpp:41
MCU::VU
A class for MIDI input elements that represent Mackie Control Universal VU meters.
Definition: VU.hpp:222
BEGIN_CS_NAMESPACE
#define BEGIN_CS_NAMESPACE
Definition: NamespaceSettings.hpp:9
MCU::VU_Base::decayTime
unsigned int decayTime
Definition: VU.hpp:167
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
IVU::IVU
IVU(uint8_t max)
Definition: VU.hpp:22
MIDIInputElementChannelPressure
Definition: MIDIInputElementChannelPressure.hpp:15
MCU::GenericVU
A class for MIDI input elements that represent Mackie Control Universal VU meters.
Definition: VU.hpp:183
MIDICNChannel
A class for saving a MIDI channel and cable number.
Definition: MIDICNChannelAddress.hpp:19
MCU::VU_Base::updateImpl
bool updateImpl(const ChannelMessageMatcher &midimsg, const MIDICNChannelAddress &target) override
Called when an incoming MIDI message matches this element.
Definition: VU.hpp:110
END_CS_NAMESPACE
#define END_CS_NAMESPACE
Definition: NamespaceSettings.hpp:10
MCU::Bankable::GenericVU::GenericVU
GenericVU(const BankConfig< NumBanks > &config, uint8_t track, const MIDICNChannel &channelCN, unsigned int decayTime, const Callback &callback)
Construct a new Bankable VU object.
Definition: VU.hpp:313
MCU::VU_Base::getValue
uint8_t getValue() override
Return the VU meter value as an integer in [0, 12].
Definition: VU.hpp:95
ChannelMessageMatcher::channel
uint8_t channel
Definition: ChannelMessageMatcher.hpp:19
ChannelMessageMatcher::data1
uint8_t data1
Definition: ChannelMessageMatcher.hpp:20
MCU::VU_Base::reset
void reset() override
Reset all values to zero.
Definition: VU.hpp:89
MCU::GenericVU::GenericVU
GenericVU(uint8_t track, const MIDICNChannel &channelCN, unsigned int decayTime, const Callback &callback)
Construct a new GenericVU object.
Definition: VU.hpp:205
MCU::VUEmptyCallback::begin
void begin(const T &)
Definition: VU.hpp:49
BankableMIDIInput::getSelection
setting_t getSelection() const
Get the current bank setting.
Definition: BankableMIDIInput.hpp:59
MCU::VU_Base::values
Array< uint8_t, NumValues > values
Definition: VU.hpp:166
MCU::Bankable::GenericVU::getSelection
setting_t getSelection() const override
Get the active bank selection.
Definition: VU.hpp:325
setting_t
uint8_t setting_t
The type used for Selectors.
Definition: Def.hpp:63
MCU::VU_Base
A MIDI input element that represents a Mackie Control Universal VU meter.
Definition: VU.hpp:78
MCU::Bankable::GenericVU::match
bool match(const MIDICNChannelAddress &target) const override
Check if the address of the incoming MIDI message is in one of the banks of this element.
Definition: VU.hpp:335
BankableMIDIInput
A base class for all MIDIInputElements that can be banked.
Definition: Bank.hpp:13
MCU::VU_Base::getOverload
bool getOverload() override
Return the overload status.
Definition: VU.hpp:97
BankConfig
A struct for selecting the bank of BankableMIDIInputs and the bank type.
Definition: BankConfig.hpp:39
MCU::Bankable::GenericVU::getBankIndex
uint8_t getBankIndex(const MIDICNChannelAddress &target) const override
Get the bank index from a MIDI address.
Definition: VU.hpp:329
MIDIInputElement::address
const MIDICNChannelAddress address
Definition: MIDIInputElement.hpp:80
MinMaxFix.hpp
MCU::VU_Base::VU_Base
VU_Base(uint8_t track, const MIDICNChannel &channelCN, unsigned int decayTime, const Callback &callback)
Definition: VU.hpp:80
IVU::getMax
uint8_t getMax() const
Get the maximum value that this VU meter can return.
Definition: VU.hpp:30
CHANNEL_1
constexpr Channel CHANNEL_1
Definition: Channel.hpp:111
BankableMIDIInput.hpp
MIDIInputElementChannelPressure.hpp
MCU::Bankable::VU::VU
VU(const BankConfig< NumBanks > &config, uint8_t track, unsigned int decayTime=VUDecay::Default)
Construct a new Bankable VU object.
Definition: VU.hpp:397
MCU::VU_Base::prevDecayTime
unsigned long prevDecayTime
Definition: VU.hpp:168
MCU::VU_Base::decay
void decay()
Definition: VU.hpp:135