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