Line data Source code
1 : #pragma once 2 : 3 : #include <AH/Hardware/Button.hpp> 4 : #include <Def/Def.hpp> 5 : #include <MIDI_Outputs/Abstract/MIDIOutputElement.hpp> 6 : 7 : BEGIN_CS_NAMESPACE 8 : 9 : /** 10 : * @brief An abstract class for momentary push buttons that send MIDI events. 11 : * 12 : * The buttons are debounced. 13 : * 14 : * @see Button 15 : */ 16 : template <class Sender, uint8_t NumButtons> 17 : class MIDIButtons : public MIDIOutputElement { 18 : protected: 19 : /** 20 : * @brief Construct a new MIDIButtons. 21 : * 22 : * @todo Documentation 23 : */ 24 3 : MIDIButtons(const Array<AH::Button, NumButtons> &buttons, 25 : MIDIAddress baseAddress, RelativeMIDIAddress incrementAddress, 26 : const Sender &sender) 27 3 : : buttons(buttons), baseAddress(baseAddress), 28 6 : incrementAddress(incrementAddress), sender(sender) {} 29 : 30 : public: 31 1 : void begin() final override { 32 3 : for (auto &button : buttons) 33 2 : button.begin(); 34 1 : } 35 7 : void update() final override { 36 7 : MIDIAddress address = baseAddress; 37 21 : for (auto &button : buttons) { 38 14 : AH::Button::State state = button.update(); 39 14 : if (state == AH::Button::Falling) { 40 2 : sender.sendOn(address); 41 12 : } else if (state == AH::Button::Rising) { 42 2 : sender.sendOff(address); 43 : } 44 14 : address += incrementAddress; 45 : } 46 7 : } 47 : 48 : AH::Button::State getButtonState(size_t index) const { 49 : return buttons[index].getState(); 50 : } 51 : 52 : /// Get the MIDI base address. 53 : MIDIAddress getBaseAddress() const { return this->baseAddress; } 54 : /// Set the MIDI base address. 55 : /// Has unexpected consequences if used while a push button is pressed. 56 : /// Use banks if you need to support that. 57 : void setBaseAddressUnsafe(MIDIAddress address) { 58 : this->baseAddress = address; 59 : } 60 : /// Get the MIDI increment address. 61 : RelativeMIDIAddress getIncrementAddress() const { 62 : return this->incrementAddress; 63 : } 64 : /// Set the MIDI increment address. 65 : /// Has unexpected consequences if used while a push button is pressed. 66 : /// Use banks if you need to support that. 67 : void setIncrementAddressUnsafe(RelativeMIDIAddress address) { 68 : this->incrementAddress = address; 69 : } 70 : 71 : /// @see @ref AH::Button::invert() 72 : void invert() { 73 : for (auto &button : buttons) 74 : button.invert(); 75 : } 76 : 77 : private: 78 : Array<AH::Button, NumButtons> buttons; 79 : MIDIAddress baseAddress; 80 : RelativeMIDIAddress incrementAddress; 81 : 82 : public: 83 : Sender sender; 84 : }; 85 : 86 : END_CS_NAMESPACE