Line data Source code
1 : /* ✔ */ 2 : 3 : #pragma once 4 : 5 : #include "ChannelMessageMatcher.hpp" 6 : #include <Def/MIDICNChannelAddress.hpp> 7 : 8 : BEGIN_CS_NAMESPACE 9 : 10 : /** 11 : * @brief A class for objects that listen for incoming MIDI events. 12 : * 13 : * They can either update some kind of display, or they can just save the state. 14 : */ 15 : class MIDIInputElement { 16 : protected: 17 : MIDIInputElement() {} // not used, only for virtual inheritance 18 : /** 19 : * @brief Create a new MIDIInputElement that listens on the given address. 20 : * 21 : * @param address 22 : * The MIDI address to listen to. 23 : */ 24 43 : MIDIInputElement(const MIDICNChannelAddress &address) : address(address) {} 25 : 26 : public: 27 43 : virtual ~MIDIInputElement() = default; 28 : 29 : /// Initialize the input element. 30 0 : virtual void begin() {} 31 : 32 : /// Reset the input element to its initial state. 33 0 : virtual void reset() {} 34 : 35 : /// Update the value of the input element. Used for decaying VU meters etc. 36 0 : virtual void update() {} 37 : 38 : /// Receive a new MIDI message and update the internal state. 39 125 : bool updateWith(const ChannelMessageMatcher &midimsg) { 40 125 : MIDICNChannelAddress target = getTarget(midimsg); 41 125 : if (!this->match(target)) 42 12 : return false; 43 113 : DEBUGFN(F("MIDI message matches")); 44 113 : if (!updateImpl(midimsg, target)) 45 0 : return false; 46 113 : DEBUGFN(F("Updated")); 47 113 : return true; 48 125 : } 49 : 50 : private: 51 : /// Update the internal state with the new MIDI message. 52 : virtual bool updateImpl(const ChannelMessageMatcher &midimsg, 53 : const MIDICNChannelAddress &target) = 0; 54 : 55 : /** 56 : * @brief Extract the target address from a MIDI message. 57 : * @note This base version of the function is only valid for messages 58 : * that use data1 as an address (i.e. Note On, Note Off, Polyphonic 59 : * Key Pressure and Control Change), because it assumes that the 60 : * target address consists of the address (data 1), the MIDI 61 : * channel and the cable number. 62 : */ 63 : virtual MIDICNChannelAddress 64 106 : getTarget(const ChannelMessageMatcher &midimsg) const { 65 106 : return {int8_t(midimsg.data1), Channel(midimsg.channel), midimsg.CN}; 66 : } 67 : 68 : /** 69 : * @brief Check if the address of the incoming MIDI message matches an 70 : * address of this element. 71 : * @note This base version of the function is only valid for non-Bankable 72 : * MIDI input elements, it only matches if the address is equal to 73 : * the address of this element. 74 : */ 75 12 : virtual bool match(const MIDICNChannelAddress &target) const { 76 12 : return MIDICNChannelAddress::matchSingle(this->address, target); 77 : } 78 : 79 : protected: 80 : const MIDICNChannelAddress address; 81 : }; 82 : 83 : END_CS_NAMESPACE