60 lines
1.8 KiB
C++
60 lines
1.8 KiB
C++
#pragma once
|
|
|
|
#include <Control_Surface/Control_Surface_Class.hpp>
|
|
#include <AH/Arduino-Wrapper.h>
|
|
|
|
BEGIN_CS_NAMESPACE
|
|
|
|
enum relativeCCmode {
|
|
TWOS_COMPLEMENT,
|
|
BINARY_OFFSET,
|
|
SIGN_MAGNITUDE,
|
|
NEXT_ADDRESS = 4,
|
|
REAPER_RELATIVE_1 = TWOS_COMPLEMENT,
|
|
REAPER_RELATIVE_2 = BINARY_OFFSET,
|
|
REAPER_RELATIVE_3 = SIGN_MAGNITUDE,
|
|
TRACKTION_RELATIVE = TWOS_COMPLEMENT,
|
|
MACKIE_CONTROL_RELATIVE = SIGN_MAGNITUDE,
|
|
KORG_KONTROL_INC_DEC_1 = NEXT_ADDRESS,
|
|
};
|
|
|
|
class RelativeCCSender {
|
|
public:
|
|
static uint8_t toTwosComplement7bit(int8_t value) { return value & 0x7F; }
|
|
static uint8_t toBinaryOffset7bit(int8_t value) { return value + 64; }
|
|
static uint8_t toSignedMagnitude7bit(int8_t value) {
|
|
uint8_t mask = value >> 7;
|
|
uint8_t abs = (value + mask) ^ mask;
|
|
uint8_t sign = mask & 0b01000000;
|
|
return (abs & 0b00111111) | sign;
|
|
}
|
|
|
|
static uint8_t mapRelativeCC(int8_t value) {
|
|
switch (mode) {
|
|
case TWOS_COMPLEMENT: return toTwosComplement7bit(value);
|
|
case BINARY_OFFSET: return toBinaryOffset7bit(value);
|
|
case SIGN_MAGNITUDE: return toSignedMagnitude7bit(value);
|
|
case NEXT_ADDRESS: return value < 0 ? -value : value;
|
|
default: return 0;
|
|
}
|
|
}
|
|
|
|
static void send(long delta, MIDIAddress address) {
|
|
if (delta < 0 && mode == NEXT_ADDRESS)
|
|
address = address + 1;
|
|
while (delta != 0) {
|
|
long thisDelta = constrain(delta, -15, 15);
|
|
uint8_t msgVal = mapRelativeCC(thisDelta);
|
|
Control_Surface.sendControlChange(address, msgVal);
|
|
delta -= thisDelta;
|
|
}
|
|
}
|
|
|
|
static void setMode(relativeCCmode mode) { RelativeCCSender::mode = mode; }
|
|
|
|
private:
|
|
static relativeCCmode mode;
|
|
};
|
|
|
|
END_CS_NAMESPACE
|