LCOV - code coverage report
Current view: top level - src/MIDI_Outputs/Bankable/Abstract - MIDIAbsoluteEncoder.hpp (source / functions) Hit Total Coverage
Test: ffed98f648fe78e7aa7bdd228474317d40dadbec Lines: 3 19 15.8 %
Date: 2022-05-28 15:22:59 Functions: 4 16 25.0 %
Legend: Lines: hit not hit

          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             : AH_DIAGNOSTIC_WERROR()
      17             : 
      18             : BEGIN_CS_NAMESPACE
      19             : 
      20             : namespace Bankable {
      21             : 
      22             : /**
      23             :  * @brief   An abstract class for rotary encoders that send absolute MIDI 
      24             :  *          events.
      25             :  */
      26             : template <class Enc, uint8_t NumBanks, class BankAddress, class Sender>
      27             : class GenericMIDIAbsoluteEncoder : public MIDIOutputElement {
      28             :   public:
      29           4 :     GenericMIDIAbsoluteEncoder(const BankAddress &address, Enc &&encoder,
      30             :                                int16_t speedMultiply, uint8_t pulsesPerStep,
      31             :                                const Sender &sender)
      32           4 :         : encoder(std::forward<Enc>(encoder)), address(address),
      33           8 :           encstate(speedMultiply, pulsesPerStep), sender(sender) {}
      34             : 
      35           0 :     void begin() override { begin_if_possible(encoder); }
      36             : 
      37           0 :     void update() override {
      38           0 :         auto encval = encoder.read();
      39           0 :         if (int16_t delta = encstate.update(encval)) {
      40           0 :             address.lock();
      41           0 :             int16_t oldValue = values[address.getSelection()];
      42           0 :             int16_t newValue = oldValue + delta;
      43           0 :             newValue = constrain(newValue, 0, maxValue);
      44           0 :             if (oldValue != newValue) {
      45           0 :                 values[address.getSelection()] = newValue;
      46           0 :                 forcedUpdate();
      47             :             }
      48           0 :             address.unlock();
      49             :         }
      50           0 :     }
      51             : 
      52             :     /// Send the current value over MIDI, even if the position of the encoder
      53             :     /// didn't change.
      54           0 :     void forcedUpdate() {
      55           0 :         sender.send(values[address.getSelection()], address.getActiveAddress());
      56           0 :     }
      57             :     void forcedUpdate(setting_t bank) {
      58             :         sender.send(values[bank], address.getActiveAddress(bank));
      59             :     }
      60             : 
      61             :     /**
      62             :      * @brief   Get the absolute value of the encoder in the given bank.
      63             :      */
      64             :     uint16_t getValue(setting_t bank) const { return values[bank]; }
      65             :     /**
      66             :      * @brief   Get the absolute value of the encoder in the active bank.
      67             :      */
      68             :     uint16_t getValue() const { return getValue(address.getSelection()); }
      69             : 
      70             :     /**
      71             :      * @brief   Set the absolute value of the encoder in the given bank.
      72             :      */
      73             :     void setValue(uint16_t value, setting_t bank) { values[bank] = value; }
      74             :     /**
      75             :      * @brief   Set the absolute value of the encoder in the active bank.
      76             :      */
      77             :     void setValue(uint16_t value) { setValue(value, address.getSelection()); }
      78             : 
      79             :     /// Get the maximum possible value that can be returned by @ref getValue.
      80             :     static int16_t getMaxValue() { return maxValue; }
      81             : 
      82             :     void setSpeedMultiply(int16_t speedMultiply) {
      83             :         encstate.setSpeedMultiply(speedMultiply);
      84             :     }
      85             :     int16_t getSpeedMultiply() const { return encstate.getSpeedMultiply(); }
      86             : 
      87             :   protected:
      88             :     Enc encoder;
      89             :     BankAddress address;
      90             :     Array<int16_t, NumBanks> values = {{}};
      91             :     EncoderState<decltype(encoder.read())> encstate;
      92             : 
      93             :     constexpr static int16_t maxValue = uint16_t(1u << Sender::precision()) - 1;
      94             : 
      95             :   public:
      96             :     Sender sender;
      97             : };
      98             : 
      99             : template <uint8_t NumBanks, class BankAddress, class Sender>
     100             : using MIDIAbsoluteEncoder =
     101             :     GenericMIDIAbsoluteEncoder<AHEncoder, NumBanks, BankAddress, Sender>;
     102             : 
     103             : template <uint8_t NumBanks, class BankAddress, class Sender>
     104             : using BorrowedMIDIAbsoluteEncoder =
     105             :     GenericMIDIAbsoluteEncoder<AHEncoder &, NumBanks, BankAddress, Sender>;
     106             : 
     107             : } // namespace Bankable
     108             : 
     109             : END_CS_NAMESPACE
     110             : 
     111             : AH_DIAGNOSTIC_POP()

Generated by: LCOV version 1.15