39 jassert (midiChannel >= 1 && midiChannel <= 16);
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;
58MidiRPNDetector::ChannelState::ChannelState()
noexcept
59 : parameterMSB (0
xff), parameterLSB (0
xff), valueMSB (0
xff), valueLSB (0
xff), isNRPN (
false)
63bool MidiRPNDetector::ChannelState::handleController (
int channel,
66 MidiRPNMessage& result)
noexcept
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;
85void MidiRPNDetector::ChannelState::resetValue() noexcept
92bool MidiRPNDetector::ChannelState::sendIfReady (
int channel, MidiRPNMessage& result)
noexcept
94 if (parameterMSB < 0x80 && parameterLSB < 0x80)
98 result.channel = channel;
99 result.parameterNumber = (parameterMSB << 7) + parameterLSB;
100 result.isNRPN = isNRPN;
104 result.value = (valueMSB << 7) + valueLSB;
105 result.is14BitValue =
true;
109 result.value = valueMSB;
110 result.is14BitValue =
false;
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);
171 void runTest()
override
173 beginTest (
"7-bit RPN");
177 expect (!
detector.parseControllerMessage (2, 101, 0,
rpn));
178 expect (!
detector.parseControllerMessage (2, 100, 7,
rpn));
179 expect (
detector.parseControllerMessage (2, 6, 42,
rpn));
181 expectEquals (
rpn.channel, 2);
182 expectEquals (
rpn.parameterNumber, 7);
183 expectEquals (
rpn.value, 42);
184 expect (!
rpn.isNRPN);
185 expect (!
rpn.is14BitValue);
188 beginTest (
"14-bit RPN");
192 expect (!
detector.parseControllerMessage (1, 100, 44,
rpn));
193 expect (!
detector.parseControllerMessage (1, 101, 2,
rpn));
194 expect (!
detector.parseControllerMessage (1, 38, 94,
rpn));
195 expect (
detector.parseControllerMessage (1, 6, 1,
rpn));
197 expectEquals (
rpn.channel, 1);
198 expectEquals (
rpn.parameterNumber, 300);
199 expectEquals (
rpn.value, 222);
200 expect (!
rpn.isNRPN);
201 expect (
rpn.is14BitValue);
204 beginTest (
"RPNs on multiple channels simultaneously");
208 expect (!
detector.parseControllerMessage (1, 100, 44,
rpn));
209 expect (!
detector.parseControllerMessage (2, 101, 0,
rpn));
210 expect (!
detector.parseControllerMessage (1, 101, 2,
rpn));
211 expect (!
detector.parseControllerMessage (2, 100, 7,
rpn));
212 expect (!
detector.parseControllerMessage (1, 38, 94,
rpn));
213 expect (
detector.parseControllerMessage (2, 6, 42,
rpn));
215 expectEquals (
rpn.channel, 2);
216 expectEquals (
rpn.parameterNumber, 7);
217 expectEquals (
rpn.value, 42);
218 expect (!
rpn.isNRPN);
219 expect (!
rpn.is14BitValue);
221 expect (
detector.parseControllerMessage (1, 6, 1,
rpn));
223 expectEquals (
rpn.channel, 1);
224 expectEquals (
rpn.parameterNumber, 300);
225 expectEquals (
rpn.value, 222);
226 expect (!
rpn.isNRPN);
227 expect (
rpn.is14BitValue);
230 beginTest (
"14-bit RPN with value within 7-bit range");
234 expect (!
detector.parseControllerMessage (16, 100, 0 ,
rpn));
235 expect (!
detector.parseControllerMessage (16, 101, 0,
rpn));
236 expect (!
detector.parseControllerMessage (16, 38, 3,
rpn));
237 expect (
detector.parseControllerMessage (16, 6, 0,
rpn));
239 expectEquals (
rpn.channel, 16);
240 expectEquals (
rpn.parameterNumber, 0);
241 expectEquals (
rpn.value, 3);
242 expect (!
rpn.isNRPN);
243 expect (
rpn.is14BitValue);
246 beginTest (
"invalid RPN (wrong order)");
250 expect (!
detector.parseControllerMessage (2, 6, 42,
rpn));
251 expect (!
detector.parseControllerMessage (2, 101, 0,
rpn));
252 expect (!
detector.parseControllerMessage (2, 100, 7,
rpn));
255 beginTest (
"14-bit RPN interspersed with unrelated CC messages");
259 expect (!
detector.parseControllerMessage (16, 3, 80,
rpn));
260 expect (!
detector.parseControllerMessage (16, 100, 0 ,
rpn));
261 expect (!
detector.parseControllerMessage (16, 4, 81,
rpn));
262 expect (!
detector.parseControllerMessage (16, 101, 0,
rpn));
263 expect (!
detector.parseControllerMessage (16, 5, 82,
rpn));
264 expect (!
detector.parseControllerMessage (16, 5, 83,
rpn));
265 expect (!
detector.parseControllerMessage (16, 38, 3,
rpn));
266 expect (!
detector.parseControllerMessage (16, 4, 84,
rpn));
267 expect (!
detector.parseControllerMessage (16, 3, 85,
rpn));
268 expect (
detector.parseControllerMessage (16, 6, 0,
rpn));
270 expectEquals (
rpn.channel, 16);
271 expectEquals (
rpn.parameterNumber, 0);
272 expectEquals (
rpn.value, 3);
273 expect (!
rpn.isNRPN);
274 expect (
rpn.is14BitValue);
277 beginTest (
"14-bit NRPN");
281 expect (!
detector.parseControllerMessage (1, 98, 44,
rpn));
282 expect (!
detector.parseControllerMessage (1, 99 , 2,
rpn));
283 expect (!
detector.parseControllerMessage (1, 38, 94,
rpn));
284 expect (
detector.parseControllerMessage (1, 6, 1,
rpn));
286 expectEquals (
rpn.channel, 1);
287 expectEquals (
rpn.parameterNumber, 300);
288 expectEquals (
rpn.value, 222);
290 expect (
rpn.is14BitValue);
297 expect (!
detector.parseControllerMessage (2, 101, 0,
rpn));
299 expect (!
detector.parseControllerMessage (2, 100, 7,
rpn));
300 expect (!
detector.parseControllerMessage (2, 6, 42,
rpn));
305static MidiRPNDetectorTests MidiRPNDetectorUnitTests;
308class MidiRPNGeneratorTests :
public UnitTest
313 void runTest()
override
315 beginTest (
"generating RPN/NRPN");
326 MidiRPNMessage message = { 16, 101, 34,
false,
false };
342 MidiRPNMessage
expected = { channel, parameterNumber, value, isNRPN, is14BitValue };
351 MidiRPNMessage result = MidiRPNMessage();
364 expectEquals (result.channel,
expected.channel);
365 expectEquals (result.parameterNumber,
expected.parameterNumber);
366 expectEquals (result.value,
expected.value);
367 expect (result.isNRPN ==
expected.isNRPN);
368 expect (result.is14BitValue ==
expected.is14BitValue);
372static MidiRPNGeneratorTests MidiRPNGeneratorUnitTests;
Holds a resizable array of primitive or copy-by-value objects.
Array()=default
Creates an empty array.
Holds a sequence of time-stamped midi events.
void addEvent(const MidiMessage &midiMessage, int sampleNumber)
Adds an event to the buffer.
Encapsulates a MIDI message.
MidiRPNDetector() noexcept
Constructor.
bool parseControllerMessage(int midiChannel, int controllerNumber, int controllerValue, MidiRPNMessage &result) noexcept
Takes the next in a stream of incoming MIDI CC messages and returns true if it forms the last of a se...
void reset() noexcept
Resets the RPN detector's internal state, so that it forgets about previously received MIDI CC messag...
~MidiRPNDetector() noexcept
Destructor.
static MidiBuffer generate(MidiRPNMessage message)
Generates a MIDI sequence representing the given RPN or NRPN message.
This is a base class for classes that perform a unit test.
bool isNRPN
True if this message is an NRPN; false if it is an RPN.
bool is14BitValue
True if the value uses 14-bit resolution (LSB + MSB); false if the value is 7-bit (MSB only).
int channel
Midi channel of the message, in the range 1 to 16.
int parameterNumber
The 14-bit parameter index, in the range 0 to 16383 (0x3fff).
int value
The parameter value, in the range 0 to 16383 (0x3fff).
Represents a MIDI RPN (registered parameter number) or NRPN (non-registered parameter number) message...