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;
150 MIDIAddress midiaddr = {track, m.getChannelCable()};
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
@ ChannelPressure
Channel Pressure Channel Voice message (2B).
#define END_CS_NAMESPACE
#define BEGIN_CS_NAMESPACE
unsigned long getInterval() const
Get the interval of the timer.
void beginNextPeriod()
Initialize or reset the timer. The timer will fire after one period.
Similar to MatchingMIDIInputElement, but for Bankable MIDI Input Elements.
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,...
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...
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