LCOV - code coverage report
Current view: top level - src/MIDI_Outputs/Abstract - EncoderState.hpp (source / functions) Coverage Total Hit
Test: 73449d9b107c772cf65493691543348214e5d5eb Lines: 100.0 % 12 12
Test Date: 2026-06-06 17:44:35 Functions: 100.0 % 2 2
Legend: Lines:     hit not hit

            Line data    Source code
       1              : #pragma once
       2              : 
       3              : #include <AH/STL/type_traits>
       4              : #include <Settings/NamespaceSettings.hpp>
       5              : #include <stdint.h>
       6              : 
       7              : BEGIN_CS_NAMESPACE
       8              : 
       9              : /// Class to keep track of relative position changes of rotary encoders.
      10              : template <class Enc_t>
      11              : class EncoderState {
      12              :   private:
      13              :     using SignedEnc_t = typename std::make_signed<Enc_t>::type;
      14              :     int16_t speedMultiply;
      15              :     uint8_t pulsesPerStep;
      16              :     int16_t remainder = 0;
      17              :     Enc_t deltaOffset = 0;
      18              : 
      19              :   public:
      20           21 :     EncoderState(int16_t speedMultiply, uint8_t pulsesPerStep)
      21           21 :         : speedMultiply(speedMultiply), pulsesPerStep(pulsesPerStep) {}
      22              : 
      23           35 :     int16_t update(Enc_t encval) {
      24              :         // If Enc_t is an unsigned type, integer overflow is well-defined, which
      25              :         // is what we want when Enc_t is small and expected to overflow.
      26              :         // However, we need it to be signed because we're interested in the
      27              :         // delta.
      28           35 :         Enc_t uDelta = encval - deltaOffset;
      29           35 :         if (uDelta == 0)
      30            2 :             return 0;
      31           33 :         int16_t delta = static_cast<SignedEnc_t>(uDelta);
      32              :         // Assumption: delta and speedMultiply are relatively small, so
      33              :         // multiplication probably won't overflow.
      34           33 :         int16_t multipliedDelta = delta * speedMultiply + remainder;
      35           33 :         int16_t scaledDelta = multipliedDelta / pulsesPerStep;
      36           33 :         remainder = multipliedDelta % pulsesPerStep;
      37           33 :         deltaOffset += uDelta;
      38           33 :         return scaledDelta;
      39              :     }
      40              :     void setSpeedMultiply(int16_t speedMultiply) {
      41              :         // TODO: Is this correct? Is it necessary? What with negative speedMult?
      42              :         remainder = remainder * speedMultiply / this->speedMultiply;
      43              :         this->speedMultiply = speedMultiply;
      44              :     }
      45              :     int16_t getSpeedMultiply() const { return this->speedMultiply; }
      46              : };
      47              : 
      48              : END_CS_NAMESPACE
        

Generated by: LCOV version 2.4-beta