cs-midi/MIDI_Outputs/Abstract/MIDIAbsoluteEncoder.hpp

76 lines
2.3 KiB
C++

#pragma once
#include <AH/STL/type_traits>
#include <AH/STL/utility>
#include <Def/Def.hpp>
#include <Def/TypeTraits.hpp>
#include <MIDI_Outputs/Abstract/EncoderState.hpp>
#include <MIDI_Outputs/Abstract/MIDIOutputElement.hpp>
#include <Submodules/Encoder/AHEncoder.hpp>
BEGIN_CS_NAMESPACE
template <class Enc, class Sender>
class GenericMIDIAbsoluteEncoder : public MIDIOutputElement {
public:
GenericMIDIAbsoluteEncoder(Enc &&encoder, MIDIAddress address,
int16_t speedMultiply, uint8_t pulsesPerStep,
const Sender &sender)
: encoder(std::forward<Enc>(encoder)), address(address),
encstate(speedMultiply, pulsesPerStep), sender(sender) {}
void begin() override { begin_if_possible(encoder); }
void update() override {
auto encval = encoder.read();
if (int16_t delta = encstate.update(encval)) {
int16_t oldValue = value;
int16_t newValue = oldValue + delta;
newValue = constrain(newValue, 0, maxValue);
if (oldValue != newValue) {
value = newValue;
forcedUpdate();
}
}
}
void forcedUpdate() { sender.send(value, address); }
uint16_t getValue() const { return value; }
void setValue(uint16_t value) { this->value = value; }
static int16_t getMaxValue() { return maxValue; }
void setSpeedMultiply(int16_t speedMultiply) {
encstate.setSpeedMultiply(speedMultiply);
}
int16_t getSpeedMultiply() const { return encstate.getSpeedMultiply(); }
MIDIAddress getAddress() const { return this->address; }
void setAddress(MIDIAddress address) { this->address = address; }
int16_t resetPositionOffset() {
auto encval = encoder.read();
return encstate.update(encval);
}
private:
Enc encoder;
MIDIAddress address;
int16_t value = 0;
EncoderState<decltype(encoder.read())> encstate;
constexpr static int16_t maxValue = uint16_t(1u << Sender::precision()) - 1;
public:
Sender sender;
};
template <class Sender>
using MIDIAbsoluteEncoder = GenericMIDIAbsoluteEncoder<AHEncoder, Sender>;
template <class Sender>
using BorrowedMIDIAbsoluteEncoder =
GenericMIDIAbsoluteEncoder<AHEncoder &, Sender>;
END_CS_NAMESPACE