39 jassert (midiChannel >= 1 && midiChannel <= 16);
40 jassert (controllerNumber >= 0 && controllerNumber < 128);
41 jassert (controllerValue >= 0 && controllerValue < 128);
43 return states[midiChannel - 1].handleController (midiChannel, controllerNumber, controllerValue, result);
48 for (
int i = 0; i < 16; ++i)
50 states[i].parameterMSB = 0xff;
51 states[i].parameterLSB = 0xff;
52 states[i].resetValue();
53 states[i].isNRPN =
false;
58 MidiRPNDetector::ChannelState::ChannelState() noexcept
59 : parameterMSB (0xff), parameterLSB (0xff), valueMSB (0xff), valueLSB (0xff), isNRPN (
false)
63 bool MidiRPNDetector::ChannelState::handleController (
int channel,
68 switch (controllerNumber)
70 case 0x62: parameterLSB = uint8 (value); resetValue(); isNRPN =
true;
break;
71 case 0x63: parameterMSB = uint8 (value); resetValue(); isNRPN =
true;
break;
73 case 0x64: parameterLSB = uint8 (value); resetValue(); isNRPN =
false;
break;
74 case 0x65: parameterMSB = uint8 (value); resetValue(); isNRPN =
false;
break;
76 case 0x06: valueMSB = uint8 (value);
return sendIfReady (channel, result);
77 case 0x26: valueLSB = uint8 (value);
break;
85 void MidiRPNDetector::ChannelState::resetValue() noexcept
92 bool MidiRPNDetector::ChannelState::sendIfReady (
int channel,
MidiRPNMessage& result) noexcept
94 if (parameterMSB < 0x80 && parameterLSB < 0x80)
104 result.
value = (valueMSB << 7) + valueLSB;
109 result.
value = valueMSB;
123 return generate (message.
channel,
136 jassert (midiChannel > 0 && midiChannel <= 16);
137 jassert (parameterNumber >= 0 && parameterNumber < 16384);
138 jassert (value >= 0 && value < (use14BitValue ? 16384 : 128));
140 uint8 parameterLSB = uint8 (parameterNumber & 0x0000007f);
141 uint8 parameterMSB = uint8 (parameterNumber >> 7);
143 uint8 valueLSB = use14BitValue ? uint8 (value & 0x0000007f) : 0x00;
144 uint8 valueMSB = use14BitValue ? uint8 (value >> 7) : uint8 (value);
146 uint8 channelByte = uint8 (0xb0 + midiChannel - 1);
167 class MidiRPNDetectorTests :
public UnitTest 170 MidiRPNDetectorTests()
171 :
UnitTest (
"MidiRPNDetector class", UnitTestCategories::midi)
174 void runTest()
override 176 beginTest (
"7-bit RPN");
186 expectEquals (rpn.
value, 42);
191 beginTest (
"14-bit RPN");
202 expectEquals (rpn.
value, 222);
207 beginTest (
"RPNs on multiple channels simultaneously");
220 expectEquals (rpn.
value, 42);
228 expectEquals (rpn.
value, 222);
233 beginTest (
"14-bit RPN with value within 7-bit range");
242 expectEquals (rpn.
channel, 16);
244 expectEquals (rpn.
value, 3);
249 beginTest (
"invalid RPN (wrong order)");
258 beginTest (
"14-bit RPN interspersed with unrelated CC messages");
273 expectEquals (rpn.
channel, 16);
275 expectEquals (rpn.
value, 3);
280 beginTest (
"14-bit NRPN");
291 expectEquals (rpn.
value, 222);
308 static MidiRPNDetectorTests MidiRPNDetectorUnitTests;
311 class MidiRPNGeneratorTests :
public UnitTest 314 MidiRPNGeneratorTests()
315 :
UnitTest (
"MidiRPNGenerator class", UnitTestCategories::midi)
318 void runTest()
override 320 beginTest (
"generating RPN/NRPN");
324 expectContainsRPN (buffer, 1, 23, 1337,
true,
true);
328 expectContainsRPN (buffer, 16, 101, 34,
false,
false);
333 expectContainsRPN (buffer, message);
340 void expectContainsRPN (
const MidiBuffer& midiBuffer,
347 MidiRPNMessage expected = { channel, parameterNumber, value, isNRPN, is14BitValue };
348 expectContainsRPN (midiBuffer, expected);
377 static MidiRPNGeneratorTests MidiRPNGeneratorUnitTests;
~MidiRPNDetector() noexcept
static MidiBuffer generate(MidiRPNMessage message)
bool getNextEvent(MidiMessage &result, int &samplePosition) noexcept
MidiRPNDetector() noexcept
int getControllerNumber() const noexcept
int getChannel() const noexcept
int getControllerValue() const noexcept
void addEvent(const MidiMessage &midiMessage, int sampleNumber)
bool parseControllerMessage(int midiChannel, int controllerNumber, int controllerValue, MidiRPNMessage &result) noexcept