@@ -177,284 +177,4 @@ MidiBuffer MidiRPNGenerator::generate (int midiChannel,
177177 return buffer;
178178}
179179
180- // ==============================================================================
181- // ==============================================================================
182- #if YUP_UNIT_TESTS
183-
184- class MidiRPNDetectorTests final : public UnitTest
185- {
186- public:
187- MidiRPNDetectorTests ()
188- : UnitTest (" MidiRPNDetector class" , UnitTestCategories::midi)
189- {
190- }
191-
192- void runTest () override
193- {
194- // From the MIDI 1.0 spec:
195- // If 128 steps of resolution is sufficient the second byte (LSB) of the data value can be
196- // omitted. If both the MSB and LSB are sent initially, a subsequent fine adjustment only
197- // requires the sending of the LSB. The MSB does not have to be retransmitted. If a
198- // subsequent major adjustment is necessary the MSB must be transmitted again. When an MSB
199- // is received, the receiver should set its concept of the LSB to zero.
200-
201- beginTest (" Individual MSB is parsed as 7-bit" );
202- {
203- MidiRPNDetector detector;
204- expect (! detector.tryParse (2 , 101 , 0 ));
205- expect (! detector.tryParse (2 , 100 , 7 ));
206-
207- auto parsed = detector.tryParse (2 , 6 , 42 );
208- expect (parsed.has_value ());
209-
210- expectEquals (parsed->channel , 2 );
211- expectEquals (parsed->parameterNumber , 7 );
212- expectEquals (parsed->value , 42 );
213- expect (! parsed->isNRPN );
214- expect (! parsed->is14BitValue );
215- }
216-
217- beginTest (" LSB without preceding MSB is ignored" );
218- {
219- MidiRPNDetector detector;
220- expect (! detector.tryParse (2 , 101 , 0 ));
221- expect (! detector.tryParse (2 , 100 , 7 ));
222- expect (! detector.tryParse (2 , 38 , 42 ));
223- }
224-
225- beginTest (" LSB following MSB is parsed as 14-bit" );
226- {
227- MidiRPNDetector detector;
228- expect (! detector.tryParse (1 , 101 , 2 ));
229- expect (! detector.tryParse (1 , 100 , 44 ));
230-
231- expect (detector.tryParse (1 , 6 , 1 ).has_value ());
232-
233- auto lsbParsed = detector.tryParse (1 , 38 , 94 );
234- expect (lsbParsed.has_value ());
235-
236- expectEquals (lsbParsed->channel , 1 );
237- expectEquals (lsbParsed->parameterNumber , 300 );
238- expectEquals (lsbParsed->value , 222 );
239- expect (! lsbParsed->isNRPN );
240- expect (lsbParsed->is14BitValue );
241- }
242-
243- beginTest (" Multiple LSB following MSB re-use the MSB" );
244- {
245- MidiRPNDetector detector;
246- expect (! detector.tryParse (1 , 101 , 2 ));
247- expect (! detector.tryParse (1 , 100 , 43 ));
248-
249- expect (detector.tryParse (1 , 6 , 1 ).has_value ());
250-
251- expect (detector.tryParse (1 , 38 , 94 ).has_value ());
252- expect (detector.tryParse (1 , 38 , 95 ).has_value ());
253- expect (detector.tryParse (1 , 38 , 96 ).has_value ());
254-
255- auto lsbParsed = detector.tryParse (1 , 38 , 97 );
256- expect (lsbParsed.has_value ());
257-
258- expectEquals (lsbParsed->channel , 1 );
259- expectEquals (lsbParsed->parameterNumber , 299 );
260- expectEquals (lsbParsed->value , 225 );
261- expect (! lsbParsed->isNRPN );
262- expect (lsbParsed->is14BitValue );
263- }
264-
265- beginTest (" Sending a new MSB resets the LSB" );
266- {
267- MidiRPNDetector detector;
268- expect (! detector.tryParse (1 , 101 , 3 ));
269- expect (! detector.tryParse (1 , 100 , 43 ));
270-
271- expect (detector.tryParse (1 , 6 , 1 ).has_value ());
272- expect (detector.tryParse (1 , 38 , 94 ).has_value ());
273-
274- auto newMsb = detector.tryParse (1 , 6 , 2 );
275- expect (newMsb.has_value ());
276-
277- expectEquals (newMsb->channel , 1 );
278- expectEquals (newMsb->parameterNumber , 427 );
279- expectEquals (newMsb->value , 2 );
280- expect (! newMsb->isNRPN );
281- expect (! newMsb->is14BitValue );
282- }
283-
284- beginTest (" RPNs on multiple channels simultaneously" );
285- {
286- MidiRPNDetector detector;
287- expect (! detector.tryParse (1 , 100 , 44 ));
288- expect (! detector.tryParse (2 , 101 , 0 ));
289- expect (! detector.tryParse (1 , 101 , 2 ));
290- expect (! detector.tryParse (2 , 100 , 7 ));
291- expect (detector.tryParse (1 , 6 , 1 ).has_value ());
292-
293- auto channelTwo = detector.tryParse (2 , 6 , 42 );
294- expect (channelTwo.has_value ());
295-
296- expectEquals (channelTwo->channel , 2 );
297- expectEquals (channelTwo->parameterNumber , 7 );
298- expectEquals (channelTwo->value , 42 );
299- expect (! channelTwo->isNRPN );
300- expect (! channelTwo->is14BitValue );
301-
302- auto channelOne = detector.tryParse (1 , 38 , 94 );
303- expect (channelOne.has_value ());
304-
305- expectEquals (channelOne->channel , 1 );
306- expectEquals (channelOne->parameterNumber , 300 );
307- expectEquals (channelOne->value , 222 );
308- expect (! channelOne->isNRPN );
309- expect (channelOne->is14BitValue );
310- }
311-
312- beginTest (" 14-bit RPN with value within 7-bit range" );
313- {
314- MidiRPNDetector detector;
315- expect (! detector.tryParse (16 , 100 , 0 ));
316- expect (! detector.tryParse (16 , 101 , 0 ));
317- expect (detector.tryParse (16 , 6 , 0 ).has_value ());
318-
319- auto parsed = detector.tryParse (16 , 38 , 3 );
320- expect (parsed.has_value ());
321-
322- expectEquals (parsed->channel , 16 );
323- expectEquals (parsed->parameterNumber , 0 );
324- expectEquals (parsed->value , 3 );
325- expect (! parsed->isNRPN );
326- expect (parsed->is14BitValue );
327- }
328-
329- beginTest (" invalid RPN (wrong order)" );
330- {
331- MidiRPNDetector detector;
332- expect (! detector.tryParse (2 , 6 , 42 ));
333- expect (! detector.tryParse (2 , 101 , 0 ));
334- expect (! detector.tryParse (2 , 100 , 7 ));
335- }
336-
337- beginTest (" 14-bit RPN interspersed with unrelated CC messages" );
338- {
339- MidiRPNDetector detector;
340- expect (! detector.tryParse (16 , 3 , 80 ));
341- expect (! detector.tryParse (16 , 100 , 0 ));
342- expect (! detector.tryParse (16 , 4 , 81 ));
343- expect (! detector.tryParse (16 , 101 , 0 ));
344- expect (! detector.tryParse (16 , 5 , 82 ));
345- expect (! detector.tryParse (16 , 5 , 83 ));
346- expect (detector.tryParse (16 , 6 , 0 ).has_value ());
347- expect (! detector.tryParse (16 , 4 , 84 ).has_value ());
348- expect (! detector.tryParse (16 , 3 , 85 ).has_value ());
349-
350- auto parsed = detector.tryParse (16 , 38 , 3 );
351- expect (parsed.has_value ());
352-
353- expectEquals (parsed->channel , 16 );
354- expectEquals (parsed->parameterNumber , 0 );
355- expectEquals (parsed->value , 3 );
356- expect (! parsed->isNRPN );
357- expect (parsed->is14BitValue );
358- }
359-
360- beginTest (" 14-bit NRPN" );
361- {
362- MidiRPNDetector detector;
363- expect (! detector.tryParse (1 , 98 , 44 ));
364- expect (! detector.tryParse (1 , 99 , 2 ));
365- expect (detector.tryParse (1 , 6 , 1 ).has_value ());
366-
367- auto parsed = detector.tryParse (1 , 38 , 94 );
368- expect (parsed.has_value ());
369-
370- expectEquals (parsed->channel , 1 );
371- expectEquals (parsed->parameterNumber , 300 );
372- expectEquals (parsed->value , 222 );
373- expect (parsed->isNRPN );
374- expect (parsed->is14BitValue );
375- }
376-
377- beginTest (" reset" );
378- {
379- MidiRPNDetector detector;
380- expect (! detector.tryParse (2 , 101 , 0 ));
381- detector.reset ();
382- expect (! detector.tryParse (2 , 100 , 7 ));
383- expect (! detector.tryParse (2 , 6 , 42 ));
384- }
385- }
386- };
387-
388- static MidiRPNDetectorTests MidiRPNDetectorUnitTests;
389-
390- // ==============================================================================
391- class MidiRPNGeneratorTests final : public UnitTest
392- {
393- public:
394- MidiRPNGeneratorTests ()
395- : UnitTest (" MidiRPNGenerator class" , UnitTestCategories::midi)
396- {
397- }
398-
399- void runTest () override
400- {
401- beginTest (" generating RPN/NRPN" );
402- {
403- {
404- MidiBuffer buffer = MidiRPNGenerator::generate (1 , 23 , 1337 , true , true );
405- expectContainsRPN (buffer, 1 , 23 , 1337 , true , true );
406- }
407- {
408- MidiBuffer buffer = MidiRPNGenerator::generate (16 , 101 , 34 , false , false );
409- expectContainsRPN (buffer, 16 , 101 , 34 , false , false );
410- }
411- {
412- MidiRPNMessage message = { 16 , 101 , 34 , false , false };
413- MidiBuffer buffer = MidiRPNGenerator::generate (message);
414- expectContainsRPN (buffer, message);
415- }
416- }
417- }
418-
419- private:
420- // ==============================================================================
421- void expectContainsRPN (const MidiBuffer& midiBuffer,
422- int channel,
423- int parameterNumber,
424- int value,
425- bool isNRPN,
426- bool is14BitValue)
427- {
428- MidiRPNMessage expected = { channel, parameterNumber, value, isNRPN, is14BitValue };
429- expectContainsRPN (midiBuffer, expected);
430- }
431-
432- // ==============================================================================
433- void expectContainsRPN (const MidiBuffer& midiBuffer, MidiRPNMessage expected)
434- {
435- std::optional<MidiRPNMessage> result;
436- MidiRPNDetector detector;
437-
438- for (const auto metadata : midiBuffer)
439- {
440- const auto midiMessage = metadata.getMessage ();
441-
442- result = detector.tryParse (midiMessage.getChannel (),
443- midiMessage.getControllerNumber (),
444- midiMessage.getControllerValue ());
445- }
446-
447- expect (result.has_value ());
448- expectEquals (result->channel , expected.channel );
449- expectEquals (result->parameterNumber , expected.parameterNumber );
450- expectEquals (result->value , expected.value );
451- expect (result->isNRPN == expected.isNRPN );
452- expect (result->is14BitValue == expected.is14BitValue );
453- }
454- };
455-
456- static MidiRPNGeneratorTests MidiRPNGeneratorUnitTests;
457-
458- #endif
459-
460180} // namespace yup
0 commit comments