76 lines
2.3 KiB
C++
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
|