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