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
|