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
|