Control Surface main
MIDI Control Surface library for Arduino
Loading...
Searching...
No Matches
VU.hpp
Go to the documentation of this file.
1#pragma once
2
6
8
9namespace MCU {
10
13struct VUState {
22 VUState(uint8_t value = 0, bool overload = false)
24
26 bool overload : 1;
27
33
48 switch (data) {
49 case 0xF: { // clear overload
51 overload = false;
52 return changed;
53 }
54 case 0xE: { // set overload
56 overload = true;
57 return changed;
58 }
59 case 0xD: { // no meaning
60 return NothingChanged;
61 }
62 default: { // set value
64 value = data;
65 return changed;
66 }
67 }
68 }
69
72 bool decay() {
73 if (value == 0)
74 return false;
75 value--;
76 return true;
77 }
78};
79
80// -------------------------------------------------------------------------- //
81
107struct VUMatcher {
110
112 struct Result {
113 bool match;
115 };
116
119 uint8_t track = m.data1 >> 4;
120 if (!MIDIAddress::matchSingle({track, m.getChannelCable()}, address))
121 return {false, 0};
122 uint8_t data = m.data1 & 0x0F;
123 return {true, data};
124 }
125
127};
128
132template <uint8_t BankSize>
137
144
149 uint8_t track = m.data1 >> 4;
151 if (!matchBankable(midiaddr, address, config))
152 return {false, 0, 0};
153 uint8_t data = m.data1 & 0x0F;
154 uint8_t bankIndex = getBankIndex(midiaddr, address, config);
155 return {true, data, bankIndex};
156 }
157
160 const Bank<BankSize> &getBank() const { return config.bank; }
161 BankType getBankType() const { return config.type; }
162 static constexpr setting_t getBankSize() { return BankSize; }
163
166 setting_t getSelection() const { return getBank().getSelection(); }
167
170};
171
172// -------------------------------------------------------------------------- //
173
175namespace VUDecay {
177constexpr unsigned int Hold = 0;
179constexpr unsigned int Default = 150;
180} // namespace VUDecay
181
188class VU : public MatchingMIDIInputElement<MIDIMessageType::ChannelPressure,
189 VUMatcher>,
190 public Interfaces::MCU::IVU {
191 public:
193 using Parent =
213 VU(uint8_t track, MIDIChannelCable channelCN,
214 unsigned int decayTime = VUDecay::Default)
215 : Parent({{track - 1, channelCN}}), IVU(12), decayTimer(decayTime) {}
216
232 VU(uint8_t track, unsigned int decayTime = VUDecay::Default)
233 : VU(track, Channel_1, decayTime) {}
234
235 protected:
236 bool handleUpdateImpl(typename Matcher::Result match) {
237 auto changed = state.update(match.data);
239 // reset the timer and fire after one interval
241 return changed;
242 }
243
244 void handleUpdate(typename Matcher::Result match) override {
245 dirty |= handleUpdateImpl(match);
246 }
247
248 bool decay() {
250 state.decay();
251 }
252
253 public:
255 void reset() override { state = {}; }
256
258 void update() override { dirty |= decay(); }
259
260 public:
263
265 uint8_t getValue() override { return state.value; }
267 bool getOverload() override { return state.overload; }
268
270
271 private:
274};
275
276// -------------------------------------------------------------------------- //
277
278namespace Bankable {
279
289template <uint8_t BankSize>
290class VU
291 : public BankableMatchingMIDIInputElement<MIDIMessageType::ChannelPressure,
292 BankableVUMatcher<BankSize>>,
293 public Interfaces::MCU::IVU {
294 public:
296 using Parent =
298 Matcher>;
299
321 unsigned int decayTime = VUDecay::Default)
322 : Parent({config, {track - 1, channelCN}}), IVU(12),
323 decayTimer(decayTime) {}
324
343 unsigned int decayTime = VUDecay::Default)
344 : VU(config, track, Channel_1, decayTime) {}
345
346 protected:
347 bool handleUpdateImpl(typename Matcher::Result match) {
348 auto changed = states[match.bankIndex].update(match.data);
350 match.bankIndex == this->getActiveBank())
351 // Only care about active bank's decay.
352 // Other banks will decay as well, but not as precisely.
353 // They aren't visible anyway, so it's a good compromise.
355 return changed && match.bankIndex == this->getActiveBank();
356 // Only mark dirty if the value of the active bank changed
357 }
358
359 void handleUpdate(typename Matcher::Result match) override {
360 dirty |= handleUpdateImpl(match);
361 }
362
363 bool decay() {
364 bool newdirty = false;
366 for (uint8_t i = 0; i < BankSize; ++i)
367 newdirty |= states[i].decay() && i == this->getActiveBank();
368 // Only mark dirty if the value of the active bank decayed
369 return newdirty;
370 }
371
372 public:
374 void reset() override {
375 states = {{}};
376 dirty = true;
377 }
378
380 void update() override { dirty |= decay(); }
381
382 protected:
383 void onBankSettingChange() override { dirty = true; }
384
385 public:
388
390 uint8_t getValue(uint8_t bank) const { return states[bank].value; }
392 bool getOverload(uint8_t bank) const { return states[bank].overload; }
395 float getFloatValue(uint8_t bank) const { return getValue(bank) / 12.f; }
396
398 uint8_t getValue() override { return getValue(this->getActiveBank()); }
400 bool getOverload() override { return getOverload(this->getActiveBank()); }
403 float getFloatValue() override { return getValue() / 12.f; }
404
406
407 private:
410};
411
412} // namespace Bankable
413
414} // namespace MCU
415
BankType
An enumeration of the different bank types.
constexpr Channel Channel_1
Definition Channel.hpp:118
uint8_t setting_t
The type used for Selectors.
Definition Def.hpp:53
@ ChannelPressure
Channel Pressure Channel Voice message (2B).
#define END_CS_NAMESPACE
#define BEGIN_CS_NAMESPACE
A class for easily managing timed events.
unsigned long getInterval() const
Get the interval of the timer.
void beginNextPeriod()
Initialize or reset the timer. The timer will fire after one period.
A class that groups Bankable MIDI Output Elements and Bankable MIDI Input Elements,...
Definition Bank.hpp:94
Similar to MatchingMIDIInputElement, but for Bankable MIDI Input Elements.
A struct for selecting the bank of BankableMIDIInputs and the bank type.
const BankType type
Bank< N > & bank
An abstract interface for VU meters.
IVU(uint8_t max, bool alwaysDirty=false)
A MIDI input element that represents a Mackie Control Universal VU meter.
Definition VU.hpp:293
void update() override
Decay the VU meter.
Definition VU.hpp:380
uint8_t getValue() override
Get the most recent VU position that was received for the active bank.
Definition VU.hpp:398
bool getOverload(uint8_t bank) const
Get the status of the overload indicator for the given bank.
Definition VU.hpp:392
AH::Timer< millis > decayTimer
Definition VU.hpp:409
void onBankSettingChange() override
A function to be executed each time the bank setting changes.
Definition VU.hpp:383
bool handleUpdateImpl(typename Matcher::Result match)
Definition VU.hpp:347
VU(BankConfig< BankSize > config, uint8_t track, unsigned int decayTime=VUDecay::Default)
Constructor.
Definition VU.hpp:342
bool getOverload() override
Get the status of the overload indicator for the active bank.
Definition VU.hpp:400
void handleUpdate(typename Matcher::Result match) override
Definition VU.hpp:359
float getFloatValue() override
Get the most recent VU position for the active bank as a value between 0 and 1.
Definition VU.hpp:403
VU(BankConfig< BankSize > config, uint8_t track, MIDIChannelCable channelCN, unsigned int decayTime=VUDecay::Default)
Constructor.
Definition VU.hpp:320
float getFloatValue(uint8_t bank) const
Get the most recent VU position for the given bank as a value between 0 and 1.
Definition VU.hpp:395
void reset() override
Reset all values to zero.
Definition VU.hpp:374
uint8_t getValue(uint8_t bank) const
Get the most recent VU position that was received for the given bank.
Definition VU.hpp:390
AH::Array< VUState, BankSize > states
Definition VU.hpp:408
bool decay()
Definition VU.hpp:363
A MIDI input element that represents a Mackie Control Universal VU meter.
Definition VU.hpp:190
VU(uint8_t track, unsigned int decayTime=VUDecay::Default)
Constructor.
Definition VU.hpp:232
void update() override
Decay the VU meter.
Definition VU.hpp:258
uint8_t getValue() override
Get the most recent VU position that was received.
Definition VU.hpp:265
VUState state
Definition VU.hpp:272
AH::Timer< millis > decayTimer
Definition VU.hpp:273
bool handleUpdateImpl(typename Matcher::Result match)
Definition VU.hpp:236
VU(uint8_t track, MIDIChannelCable channelCN, unsigned int decayTime=VUDecay::Default)
Constructor.
Definition VU.hpp:213
bool getOverload() override
Get the status of the overload indicator.
Definition VU.hpp:267
void handleUpdate(typename Matcher::Result match) override
Definition VU.hpp:244
void reset() override
Reset all values to zero.
Definition VU.hpp:255
bool decay()
Definition VU.hpp:248
A type-safe utility class for saving a MIDI address consisting of a 7-bit address,...
constexpr MIDIChannelCable getChannelCable() const
Get the channel and cable number.
static bool matchSingle(MIDIAddress toMatch, MIDIAddress base)
Check if two addresses match (are equal).
A class for saving a MIDI channel and cable number.
The MIDIInputElement base class is very general: you give it a MIDI message, and it calls the updateW...
Array< T, N > copyAs(const Array< U, N > &src)
Copy an Array to an Array of a different type.
uint8_t getBankIndex(uint8_t tgt, uint8_t base, const Bank< BankSize > &bank)
bool matchBankable(uint8_t tgt, uint8_t base, const Bank< BankSize > &bank)
Check if the given address is part of the bank relative to the base address.
A namespace for MIDI elements that can be added to a Bank, to change their address or channel.
constexpr unsigned int Default
Decay one segment/block every 150 ms if no new values are received.
Definition VU.hpp:179
constexpr unsigned int Hold
Don't decay automatically, hold the latest value until a new one is received.
Definition VU.hpp:177
An array wrapper for easy copying, comparing, and iterating.
Definition Array.hpp:32
Output data of the matcher/parser.
Definition VU.hpp:139
uint8_t bankIndex
The bank index of the message [0, BankSize-1].
Definition VU.hpp:142
uint8_t data
The data to update the VU meter with [0x0, 0xF].
Definition VU.hpp:141
bool match
Whether the address of the message matched our address.
Definition VU.hpp:140
MIDI Input matcher for Mackie Control Universal VU meters with bank support.
Definition VU.hpp:133
MIDIAddress address
MIDI address to compare incoming messages with.
Definition VU.hpp:169
setting_t getSelection() const
Get the current bank setting.
Definition VU.hpp:166
static constexpr setting_t getBankSize()
Definition VU.hpp:162
BankableVUMatcher(BankConfig< BankSize > config, MIDIAddress address)
Constructor.
Definition VU.hpp:135
BaseBankConfig< BankSize > config
Bank configuration.
Definition VU.hpp:168
const Bank< BankSize > & getBank() const
Definition VU.hpp:160
BankType getBankType() const
Definition VU.hpp:161
Result operator()(ChannelMessage m)
Parse and try to match the incoming MIDI message.
Definition VU.hpp:146
Bank< BankSize > & getBank()
Definition VU.hpp:159
Output data of the matcher/parser.
Definition VU.hpp:112
uint8_t data
The data to update the VU meter with [0x0, 0xF].
Definition VU.hpp:114
bool match
Whether the address of the message matched our address.
Definition VU.hpp:113
MIDI Input matcher for Mackie Control Universal VU meters.
Definition VU.hpp:107
MIDIAddress address
MIDI address to compare incoming messages with.
Definition VU.hpp:126
VUMatcher(MIDIAddress address)
Constructor.
Definition VU.hpp:109
Result operator()(ChannelMessage m)
Parse and try to match the incoming MIDI message.
Definition VU.hpp:118
Struct that keeps track of the value and overload indicator of a Mackie Control Universal VU meter.
Definition VU.hpp:13
bool overload
The state of the overload indicator.
Definition VU.hpp:26
uint8_t value
The value of the VU meter [0, 12].
Definition VU.hpp:25
@ OverloadChanged
Definition VU.hpp:31
@ ValueChanged
Definition VU.hpp:30
@ NothingChanged
Definition VU.hpp:29
Changed update(uint8_t data)
Update the value or overload status with a new raw MIDI value.
Definition VU.hpp:47
VUState(uint8_t value=0, bool overload=false)
Constructor.
Definition VU.hpp:22
bool decay()
Decay the VU value: subtract one from the position if it is not zero.
Definition VU.hpp:72