Line data Source code
1 : #pragma once
2 :
3 : #include "InterfaceMIDIInputElements.hpp"
4 : #include "MIDIInputElementMatchers.hpp"
5 :
6 : BEGIN_CS_NAMESPACE
7 :
8 : // -------------------------------------------------------------------------- //
9 :
10 : /// Generic base class for classes that listen for MIDI Note, Control Change and
11 : /// Key Pressure events on a single address and save their value.
12 : ///
13 : /// @tparam Type
14 : /// The type of MIDI messages to listen for:
15 : /// - @ref MIDIMessageType::NoteOn
16 : /// - @ref MIDIMessageType::ControlChange
17 : /// - @ref MIDIMessageType::KeyPressure
18 : template <MIDIMessageType Type>
19 : class NoteCCKPValue : public MatchingMIDIInputElement<Type, TwoByteMIDIMatcher>,
20 : public Interfaces::IValue {
21 : public:
22 : using Matcher = TwoByteMIDIMatcher;
23 :
24 : /// @param address
25 : /// The address to listen to.
26 1 : NoteCCKPValue(MIDIAddress address)
27 1 : : MatchingMIDIInputElement<Type, TwoByteMIDIMatcher>(address) {}
28 :
29 : protected:
30 3 : bool handleUpdateImpl(typename Matcher::Result match) {
31 3 : bool newdirty = value != match.value;
32 3 : value = match.value;
33 3 : return newdirty;
34 : }
35 :
36 3 : void handleUpdate(typename Matcher::Result match) override {
37 3 : dirty |= handleUpdateImpl(match);
38 3 : }
39 :
40 : public:
41 : /// @name Data access
42 : /// @{
43 :
44 : /// Get the most recent MIDI value that was received.
45 4 : uint8_t getValue() const override { return value; }
46 :
47 : /// @}
48 :
49 : /// Reset all values to zero.
50 0 : void reset() override {
51 0 : value = 0;
52 0 : dirty = true;
53 0 : }
54 :
55 : private:
56 : uint8_t value = 0;
57 : };
58 :
59 : /// Class that listens for MIDI Note events on a single address and saves their
60 : /// value.
61 : /// @ingroup MIDIInputElements
62 : using NoteValue = NoteCCKPValue<MIDIMessageType::NoteOn>;
63 :
64 : /// Class that listens for MIDI Control Change events on a single address and
65 : /// saves their value.
66 : /// @ingroup MIDIInputElements
67 : using CCValue = NoteCCKPValue<MIDIMessageType::ControlChange>;
68 :
69 : /// Class that listens for MIDI Key Pressure events on a single address and
70 : /// saves their value.
71 : /// @ingroup MIDIInputElements
72 : using KPValue = NoteCCKPValue<MIDIMessageType::KeyPressure>;
73 :
74 : // -------------------------------------------------------------------------- //
75 :
76 : namespace Bankable {
77 :
78 : /// Generic base class for classes that listen for MIDI Note, Control Change and
79 : /// Key Pressure events on a single address and save their value. This version
80 : /// listens accross multiple banks.
81 : ///
82 : /// @tparam Type
83 : /// The type of MIDI messages to listen for:
84 : /// - @ref MIDIMessageType::NoteOn
85 : /// - @ref MIDIMessageType::ControlChange
86 : /// - @ref MIDIMessageType::KeyPressure
87 : /// @tparam BankSize
88 : /// The number of banks.
89 : template <MIDIMessageType Type, uint8_t BankSize>
90 : class NoteCCKPValue : public BankableMatchingMIDIInputElement<
91 : Type, BankableTwoByteMIDIMatcher<BankSize>>,
92 : public Interfaces::IValue {
93 : public:
94 : using Matcher = BankableTwoByteMIDIMatcher<BankSize>;
95 :
96 : /// @param config
97 : /// The bank configuration to use.
98 : /// @param address
99 : /// The base address to listen to.
100 2 : NoteCCKPValue(BankConfig<BankSize> config, MIDIAddress address)
101 2 : : BankableMatchingMIDIInputElement<Type, Matcher>({config, address}) {}
102 :
103 : protected:
104 6 : bool handleUpdateImpl(typename Matcher::Result match) {
105 12 : bool newdirty = values[match.bankIndex] != match.value &&
106 6 : match.bankIndex == this->getActiveBank();
107 : // Only mark dirty if the value of the active bank changed
108 6 : values[match.bankIndex] = match.value;
109 6 : return newdirty;
110 : }
111 :
112 0 : void handleUpdate(typename Matcher::Result match) override {
113 0 : dirty |= handleUpdateImpl(match);
114 0 : }
115 :
116 : public:
117 : /// @name Data access
118 : /// @{
119 :
120 : /// Get the most recent MIDI value that was received for the active bank.
121 14 : uint8_t getValue() const override { return values[this->getActiveBank()]; }
122 : /// Get the most recent MIDI value that was received for the given bank.
123 16 : uint8_t getValue(uint8_t bank) const { return values[bank]; }
124 :
125 : /// @}
126 :
127 : /// Reset all values to zero.
128 0 : void reset() override {
129 0 : values = {{}};
130 0 : dirty = true;
131 0 : }
132 :
133 : protected:
134 2 : void onBankSettingChange() override { dirty = true; }
135 :
136 : private:
137 : AH::Array<uint8_t, BankSize> values = {{}};
138 : };
139 :
140 : /// Class that listens for MIDI Note events on a single address and
141 : /// saves their value. This version listens accross multiple banks.
142 : /// @ingroup BankableMIDIInputElements
143 : template <uint8_t BankSize>
144 : using NoteValue = NoteCCKPValue<MIDIMessageType::NoteOn, BankSize>;
145 :
146 : /// Class that listens for MIDI Control Change events on a single address and
147 : /// saves their value. This version listens accross multiple banks.
148 : /// @ingroup BankableMIDIInputElements
149 : template <uint8_t BankSize>
150 : using CCValue = NoteCCKPValue<MIDIMessageType::ControlChange, BankSize>;
151 :
152 : /// Class that listens for MIDI Key Pressure events on a single address and
153 : /// saves their value. This version listens accross multiple banks.
154 : /// @ingroup BankableMIDIInputElements
155 : template <uint8_t BankSize>
156 : using KPValue = NoteCCKPValue<MIDIMessageType::KeyPressure, BankSize>;
157 :
158 : } // namespace Bankable
159 :
160 : END_CS_NAMESPACE
|