Line data Source code
1 : #pragma once 2 : 3 : #include <AH/STL/utility> // std::forward 4 : #include <Banks/BankableAddresses.hpp> 5 : #include <Def/Def.hpp> 6 : #include <Def/TypeTraits.hpp> 7 : #include <MIDI_Outputs/Abstract/EncoderState.hpp> 8 : #include <MIDI_Outputs/Abstract/MIDIOutputElement.hpp> 9 : 10 : #ifdef ARDUINO 11 : #include <Submodules/Encoder/AHEncoder.hpp> 12 : #else 13 : #include <Encoder.h> // Mock 14 : #endif 15 : 16 : BEGIN_CS_NAMESPACE 17 : 18 : namespace Bankable { 19 : 20 : /** 21 : * @brief An abstract class for rotary encoders that send MIDI events and that 22 : * can be added to a Bank. 23 : */ 24 : template <class Enc, class BankAddress, class Sender> 25 : class GenericMIDIRotaryEncoder : public MIDIOutputElement { 26 : protected: 27 : /** 28 : * @brief Construct a new GenericMIDIRotaryEncoder. 29 : * 30 : * @todo Documentation 31 : */ 32 3 : GenericMIDIRotaryEncoder(BankAddress bankAddress, Enc &&encoder, 33 : int16_t speedMultiply, uint8_t pulsesPerStep, 34 : const Sender &sender) 35 3 : : address(bankAddress), encoder(std::forward<Enc>(encoder)), 36 6 : encstate(speedMultiply, pulsesPerStep), sender(sender) {} 37 : 38 : public: 39 0 : void begin() override { begin_if_possible(encoder); } 40 : 41 2 : void update() override { 42 2 : auto encval = encoder.read(); 43 2 : if (int16_t delta = encstate.update(encval)) { 44 2 : sender.send(delta, address.getActiveAddress()); 45 : } 46 2 : } 47 : 48 : void setSpeedMultiply(int16_t speedMultiply) { 49 : encstate.setSpeedMultiply(speedMultiply); 50 : } 51 : int16_t getSpeedMultiply() const { return encstate.getSpeedMultiply(); } 52 : 53 : int16_t resetPositionOffset() { 54 : auto encval = encoder.read(); 55 : return encstate.update(encval); 56 : } 57 : 58 : protected: 59 : BankAddress address; 60 : Enc encoder; 61 : EncoderState<decltype(encoder.read())> encstate; 62 : 63 : public: 64 : Sender sender; 65 : }; 66 : 67 : template <class BankAddress, class Sender> 68 : using MIDIRotaryEncoder = 69 : GenericMIDIRotaryEncoder<AHEncoder, BankAddress, Sender>; 70 : 71 : template <class BankAddress, class Sender> 72 : using BorrowedMIDIRotaryEncoder = 73 : GenericMIDIRotaryEncoder<AHEncoder &, BankAddress, Sender>; 74 : 75 : } // namespace Bankable 76 : 77 : END_CS_NAMESPACE