Control Surface  1.1.0
MIDI Control Surface library for Arduino
RelativeCCSender.hpp
Go to the documentation of this file.
1 #pragma once
2 
4 
5 #include <Arduino.h> // for constrain
6 
8 
9 /// The encoding to use for relative control change value.
11  /**
12  * @brief Encode negative MIDI CC values as 7-bit two's complement.
13  *
14  * | Encoded | Value |
15  * |---------:|------:|
16  * | 000'0000 | 0 |
17  * | 000'0001 | +1 |
18  * | 011'1111 | +63 |
19  * | 100'0000 | -64 |
20  * | 100'0001 | -63 |
21  * | 111'1111 | -1 |
22  */
24  /**
25  * @brief Encode negative MIDI CC values by adding a fixed offset of
26  * @f$ 2^6 = 64 @f$.
27  *
28  * | Encoded | Value |
29  * |---------:|------:|
30  * | 000'0000 | -64 |
31  * | 000'0001 | -63 |
32  * | 011'1111 | -1 |
33  * | 100'0000 | 0 |
34  * | 100'0001 | +1 |
35  * | 111'1111 | +63 |
36  */
38  /**
39  * @brief Encode negative MIDI CC values by using the most significant bit
40  * as a sign bit, and the six least significant bits as the
41  * absolute value.
42  *
43  * | Encoded | Value |
44  * |---------:|------:|
45  * | 000'0000 | +0 |
46  * | 000'0001 | 1 |
47  * | 011'1111 | 63 |
48  * | 100'0000 | -0 |
49  * | 100'0001 | -1 |
50  * | 111'1111 | -63 |
51  */
53  /// First relative mode in Reaper.
55  /// Second relative mode in Reaper.
57  /// Third relative mode in Reaper.
59  /// Relative mode in Tracktion.
61  /// Relative mode used by the Mackie Control Universal protocol.
63 };
64 
66  public:
67  /** Convert an 8-bit two's complement integer to a 7-bit two's complement
68  * integer. */
69  static uint8_t toTwosComplement7bit(int8_t value) { return value & 0x7F; }
70  /** Convert an 8-bit two's complement integer to a 7-bit integer with a
71  * binary offset of 64. In other words, a value of 0 corresponds to -64,
72  * a value of 64 corresponds to 0, and a value of 127 corresponds to 63. */
73  static uint8_t toBinaryOffset7bit(int8_t value) { return value + 64; }
74  /** Convert an 8-bit two's complement integer to 7-bit sign-magnitude
75  * format. */
76  static uint8_t toSignedMagnitude7bit(int8_t value) {
77  uint8_t mask = value >> 7;
78  uint8_t abs = (value + mask) ^ mask;
79  uint8_t sign = mask & 0b01000000;
80  return (abs & 0b00111111) | sign;
81  }
82  /** Convert an 8-bit two's complement integer to a 7-bit value to send over
83  * MIDI. */
84  static uint8_t mapRelativeCC(int8_t value) {
85  switch (mode) {
86  case TWOS_COMPLEMENT: return toTwosComplement7bit(value);
87  case BINARY_OFFSET: return toBinaryOffset7bit(value);
88  case SIGN_MAGNITUDE: return toSignedMagnitude7bit(value);
89  default: return 0; // Keeps the compiler happy
90  }
91  }
92 
93  static void send(long delta, MIDICNChannelAddress address) {
94  while (delta != 0) {
95  // Constrain relative movement to +/-15 for
96  // Mackie Control Universal compatibility
97  long thisDelta = constrain(delta, -15, 15);
98  uint8_t msgVal = mapRelativeCC(thisDelta);
99  // send a Control Change MIDI event
100  Control_Surface.MIDI().sendCC(address, msgVal);
101  delta -= thisDelta;
102  }
103  }
104 
106 
107  private:
109 };
110 
MACKIE_CONTROL_RELATIVE
Relative mode used by the Mackie Control Universal protocol.
Definition: RelativeCCSender.hpp:62
TWOS_COMPLEMENT
Encode negative MIDI CC values as 7-bit two's complement.
Definition: RelativeCCSender.hpp:23
BEGIN_CS_NAMESPACE
#define BEGIN_CS_NAMESPACE
Definition: Settings/NamespaceSettings.hpp:9
Control_Surface_::MIDI
MIDI_Interface & MIDI()
Get the MIDI interface of the Control Surface.
Definition: Control_Surface_Class.cpp:58
MIDI_Interface::sendCC
void sendCC(MIDICNChannelAddress address, uint8_t value)
Send a MIDI Control Change event.
Definition: MIDI_Interface.cpp:75
END_CS_NAMESPACE
#define END_CS_NAMESPACE
Definition: Settings/NamespaceSettings.hpp:10
RelativeCCSender::toBinaryOffset7bit
static uint8_t toBinaryOffset7bit(int8_t value)
Convert an 8-bit two's complement integer to a 7-bit integer with a binary offset of 64.
Definition: RelativeCCSender.hpp:73
Control_Surface_Class.hpp
MIDICNChannelAddress
A type-safe utility class for saving a MIDI address consisting of a 7-bit address,...
Definition: MIDICNChannelAddress.hpp:82
RelativeCCSender::setMode
static void setMode(relativeCCmode mode)
Definition: RelativeCCSender.hpp:105
Control_Surface
Control_Surface_ & Control_Surface
A predefined instance of the Control Surface to use in the Arduino sketches.
Definition: Control_Surface_Class.cpp:174
RelativeCCSender::mode
static relativeCCmode mode
Definition: RelativeCCSender.hpp:108
BINARY_OFFSET
Encode negative MIDI CC values by adding a fixed offset of .
Definition: RelativeCCSender.hpp:37
RelativeCCSender::toTwosComplement7bit
static uint8_t toTwosComplement7bit(int8_t value)
Convert an 8-bit two's complement integer to a 7-bit two's complement integer.
Definition: RelativeCCSender.hpp:69
RelativeCCSender::mapRelativeCC
static uint8_t mapRelativeCC(int8_t value)
Convert an 8-bit two's complement integer to a 7-bit value to send over MIDI.
Definition: RelativeCCSender.hpp:84
RelativeCCSender
Definition: RelativeCCSender.hpp:65
TRACKTION_RELATIVE
Relative mode in Tracktion.
Definition: RelativeCCSender.hpp:60
REAPER_RELATIVE_2
Second relative mode in Reaper.
Definition: RelativeCCSender.hpp:56
REAPER_RELATIVE_1
First relative mode in Reaper.
Definition: RelativeCCSender.hpp:54
REAPER_RELATIVE_3
Third relative mode in Reaper.
Definition: RelativeCCSender.hpp:58
RelativeCCSender::toSignedMagnitude7bit
static uint8_t toSignedMagnitude7bit(int8_t value)
Convert an 8-bit two's complement integer to 7-bit sign-magnitude format.
Definition: RelativeCCSender.hpp:76
relativeCCmode
relativeCCmode
The encoding to use for relative control change value.
Definition: RelativeCCSender.hpp:10
RelativeCCSender::send
static void send(long delta, MIDICNChannelAddress address)
Definition: RelativeCCSender.hpp:93
SIGN_MAGNITUDE
Encode negative MIDI CC values by using the most significant bit as a sign bit, and the six least sig...
Definition: RelativeCCSender.hpp:52