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 : 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 : RelativeMIDIAddress incrementAddress, const Sender &sender) 33 4 : : address(bankAddress), buttons(buttons), 34 8 : incrementAddress(incrementAddress), sender(sender) {} 35 : 36 : public: 37 2 : void begin() final override { 38 6 : for (auto &button : buttons) 39 4 : button.begin(); 40 2 : } 41 16 : void update() final override { 42 16 : RelativeMIDIAddress offset = {0, 0, 0}; 43 48 : for (auto &button : buttons) { 44 32 : AH::Button::State state = button.update(); 45 32 : if (state == AH::Button::Falling) { 46 5 : if (!activeButtons) 47 3 : address.lock(); // Don't allow changing of the bank setting 48 5 : MIDIAddress sendAddress = address.getActiveAddress() + offset; 49 5 : sender.sendOn(sendAddress); 50 5 : activeButtons++; 51 27 : } else if (state == AH::Button::Rising) { 52 5 : MIDIAddress sendAddress = address.getActiveAddress() + offset; 53 5 : sender.sendOff(sendAddress); 54 5 : activeButtons--; 55 5 : if (!activeButtons) 56 3 : address.unlock(); 57 : } 58 32 : offset += incrementAddress; 59 : } 60 16 : } 61 : 62 : /// @see @ref AH::Button::invert() 63 : void invert() { 64 : for (auto &button : buttons) 65 : button.invert(); 66 : } 67 : 68 : AH::Button::State getButtonState(size_t index) const { 69 : return buttons[index].getState(); 70 : } 71 : 72 : protected: 73 : BankAddress address; 74 : Array<AH::Button, NumButtons> buttons; 75 : RelativeMIDIAddress incrementAddress; 76 : uint8_t activeButtons = 0; 77 : 78 : public: 79 : Sender sender; 80 : }; 81 : 82 : } // namespace Bankable 83 : 84 : END_CS_NAMESPACE