Line data Source code
1 : #pragma once 2 : 3 : #include <AH/Containers/Array.hpp> 4 : #include <AH/Hardware/Button.hpp> 5 : #include <Banks/BankableAddresses.hpp> 6 : #include <Def/Def.hpp> 7 : #include <MIDI_Outputs/Abstract/MIDIOutputElement.hpp> 8 : 9 : BEGIN_CS_NAMESPACE 10 : 11 : namespace Bankable { 12 : 13 : /** 14 : * @brief An abstract class for momentary push buttons that send MIDI events. 15 : * 16 : * The buttons are debounced. 17 : * 18 : * @todo Use BankAddresses? 19 : * 20 : * @see Button 21 : */ 22 : template <class BankAddress, class Sender, uint8_t NumButtons> 23 4 : class MIDIButtons : public MIDIOutputElement { 24 : protected: 25 : /** 26 : * @brief Construct a new MIDIButtons. 27 : * 28 : * @todo Documentation 29 : */ 30 4 : MIDIButtons(BankAddress bankAddress, 31 : const Array<AH::Button, NumButtons> &buttons, 32 : const RelativeMIDIAddress &incrementAddress, 33 : const Sender &sender) 34 4 : : address(bankAddress), buttons{buttons}, 35 16 : incrementAddress(incrementAddress), sender{sender} {} 36 : 37 : public: 38 2 : void begin() final override { 39 6 : for (auto &button : buttons) 40 4 : button.begin(); 41 2 : } 42 16 : void update() final override { 43 16 : RelativeMIDIAddress offset = {0, 0, 0}; 44 48 : for (auto &button : buttons) { 45 32 : AH::Button::State state = button.update(); 46 32 : if (state == AH::Button::Falling) { 47 5 : if (!activeButtons) 48 3 : address.lock(); // Don't allow changing of the bank setting 49 5 : MIDIAddress sendAddress = address.getActiveAddress() + offset; 50 5 : sender.sendOn(sendAddress); 51 5 : activeButtons++; 52 32 : } else if (state == AH::Button::Rising) { 53 5 : MIDIAddress sendAddress = address.getActiveAddress() + offset; 54 5 : sender.sendOff(sendAddress); 55 5 : activeButtons--; 56 5 : if (!activeButtons) 57 3 : address.unlock(); 58 5 : } 59 32 : offset += incrementAddress; 60 32 : } 61 16 : } 62 : 63 : #ifdef AH_INDIVIDUAL_BUTTON_INVERT 64 : void invert() { 65 : for (auto &button : buttons) 66 : button.invert(); 67 : } 68 : #endif 69 : 70 : AH::Button::State getButtonState(size_t index) const { 71 : return buttons[index].getState(); 72 : } 73 : 74 : private: 75 : BankAddress address; 76 : Array<AH::Button, NumButtons> buttons; 77 : RelativeMIDIAddress incrementAddress; 78 4 : uint8_t activeButtons = 0; 79 : 80 : public: 81 : Sender sender; 82 : }; 83 : 84 : } // namespace Bankable 85 : 86 : END_CS_NAMESPACE