Line data Source code
1 : #pragma once
2 :
3 : #include <AH/Hardware/ButtonMatrix.hpp>
4 : #include <Def/Def.hpp>
5 : #include <MIDI_Outputs/Abstract/MIDIOutputElement.hpp>
6 :
7 : BEGIN_CS_NAMESPACE
8 :
9 : /**
10 : * @brief MIDIButtonMatrix
11 : * @todo Documentation.
12 : * @see AH::ButtonMatrix
13 : */
14 : template <class Sender, uint8_t NumRows, uint8_t NumCols>
15 : class MIDIButtonMatrix
16 : : public MIDIOutputElement,
17 : public AH::ButtonMatrix<MIDIButtonMatrix<Sender, NumRows, NumCols>,
18 : NumRows, NumCols> {
19 : using ButtonMatrix = AH::ButtonMatrix<MIDIButtonMatrix, NumRows, NumCols>;
20 : friend class AH::ButtonMatrix<MIDIButtonMatrix, NumRows, NumCols>;
21 :
22 : protected:
23 : /**
24 : * @brief Construct a new MIDIButtonMatrix.
25 : *
26 : * @param rowPins
27 : * A list of pin numbers connected to the rows of the button
28 : * matrix.
29 : * **⚠** These pins will be driven LOW as outputs (Lo-Z).
30 : * @param colPins
31 : * A list of pin numbers connected to the columns of the button
32 : * matrix.
33 : * These pins will be used as inputs (Hi-Z), and the internal
34 : * pull-up resistor will be enabled.
35 : * @param addresses
36 : * A matrix containing the address corresponding to each button.
37 : * @param channelCN
38 : * The MIDI channel and optional cable number for all buttons.
39 : * @param sender
40 : * The MIDI sender to use.
41 : */
42 3 : MIDIButtonMatrix(const PinList<NumRows> &rowPins,
43 : const PinList<NumCols> &colPins,
44 : const AddressMatrix<NumRows, NumCols> &addresses,
45 : MIDIChannelCable channelCN, const Sender &sender)
46 3 : : ButtonMatrix(rowPins, colPins), addresses(addresses),
47 6 : baseChannelCN(channelCN), sender(sender) {}
48 :
49 : public:
50 1 : void begin() final override { ButtonMatrix::begin(); }
51 :
52 2 : void update() final override { ButtonMatrix::update(); }
53 :
54 : /// Get the MIDI address of the button at the given row and column.
55 : MIDIAddress getAddress(uint8_t row, uint8_t col) const {
56 : return {this->addresses[row][col], baseChannelCN};
57 : }
58 : /// Set the MIDI address of button at the given row and column.
59 : /// Has unexpected consequences if used while the push button is pressed.
60 : /// Use banks if you need to support that.
61 : void setAddressUnsafe(uint8_t row, uint8_t col, uint8_t address) {
62 : this->addresses[row][col] = address;
63 : }
64 : /// Get the MIDI channel and cable number.
65 : MIDIChannelCable getChannelCable() const { return this->baseChannelCN; }
66 : /// Set the MIDI channel and cable number of all buttons. Has unexpected
67 : /// consequences if used while the push button is pressed.
68 : /// Use banks if you need to support that.
69 : void setChannelCableUnsafe(MIDIChannelCable bccn) {
70 : this->baseChannelCN = bccn;
71 : }
72 :
73 : private:
74 2 : void onButtonChanged(uint8_t row, uint8_t col, bool state) {
75 2 : int8_t address = addresses[row][col];
76 2 : if (state == LOW)
77 1 : sender.sendOn({address, baseChannelCN});
78 : else
79 1 : sender.sendOff({address, baseChannelCN});
80 2 : }
81 :
82 : AddressMatrix<NumRows, NumCols> addresses;
83 : MIDIChannelCable baseChannelCN;
84 :
85 : public:
86 : Sender sender;
87 : };
88 :
89 : END_CS_NAMESPACE
|