@@ -489,16 +489,84 @@ static void ch345_broken_sysex_input(struct snd_usb_midi_in_endpoint *ep,
489
489
490
490
/*
491
491
* CME protocol: like the standard protocol, but SysEx commands are sent as a
492
- * single USB packet preceded by a 0x0F byte.
492
+ * single USB packet preceded by a 0x0F byte, as are system realtime
493
+ * messages and MIDI Active Sensing.
494
+ * Also, multiple messages can be sent in the same packet.
493
495
*/
494
496
static void snd_usbmidi_cme_input (struct snd_usb_midi_in_endpoint * ep ,
495
497
uint8_t * buffer , int buffer_length )
496
498
{
497
- if (buffer_length < 2 || (buffer [0 ] & 0x0f ) != 0x0f )
498
- snd_usbmidi_standard_input (ep , buffer , buffer_length );
499
- else
500
- snd_usbmidi_input_data (ep , buffer [0 ] >> 4 ,
501
- & buffer [1 ], buffer_length - 1 );
499
+ int remaining = buffer_length ;
500
+
501
+ /*
502
+ * CME send sysex, song position pointer, system realtime
503
+ * and active sensing using CIN 0x0f, which in the standard
504
+ * is only intended for single byte unparsed data.
505
+ * So we need to interpret these here before sending them on.
506
+ * By default, we assume single byte data, which is true
507
+ * for system realtime (midi clock, start, stop and continue)
508
+ * and active sensing, and handle the other (known) cases
509
+ * separately.
510
+ * In contrast to the standard, CME does not split sysex
511
+ * into multiple 4-byte packets, but lumps everything together
512
+ * into one. In addition, CME can string multiple messages
513
+ * together in the same packet; pressing the Record button
514
+ * on an UF6 sends a sysex message directly followed
515
+ * by a song position pointer in the same packet.
516
+ * For it to have any reasonable meaning, a sysex message
517
+ * needs to be at least 3 bytes in length (0xf0, id, 0xf7),
518
+ * corresponding to a packet size of 4 bytes, and the ones sent
519
+ * by CME devices are 6 or 7 bytes, making the packet fragments
520
+ * 7 or 8 bytes long (six or seven bytes plus preceding CN+CIN byte).
521
+ * For the other types, the packet size is always 4 bytes,
522
+ * as per the standard, with the data size being 3 for SPP
523
+ * and 1 for the others.
524
+ * Thus all packet fragments are at least 4 bytes long, so we can
525
+ * skip anything that is shorter; this also conveniantly skips
526
+ * packets with size 0, which CME devices continuously send when
527
+ * they have nothing better to do.
528
+ * Another quirk is that sometimes multiple messages are sent
529
+ * in the same packet. This has been observed for midi clock
530
+ * and active sensing i.e. 0x0f 0xf8 0x00 0x00 0x0f 0xfe 0x00 0x00,
531
+ * but also multiple note ons/offs, and control change together
532
+ * with MIDI clock. Similarly, some sysex messages are followed by
533
+ * the song position pointer in the same packet, and occasionally
534
+ * additionally by a midi clock or active sensing.
535
+ * We handle this by looping over all data and parsing it along the way.
536
+ */
537
+ while (remaining >= 4 ) {
538
+ int source_length = 4 ; /* default */
539
+
540
+ if ((buffer [0 ] & 0x0f ) == 0x0f ) {
541
+ int data_length = 1 ; /* default */
542
+
543
+ if (buffer [1 ] == 0xf0 ) {
544
+ /* Sysex: Find EOX and send on whole message. */
545
+ /* To kick off the search, skip the first
546
+ * two bytes (CN+CIN and SYSEX (0xf0).
547
+ */
548
+ uint8_t * tmp_buf = buffer + 2 ;
549
+ int tmp_length = remaining - 2 ;
550
+
551
+ while (tmp_length > 1 && * tmp_buf != 0xf7 ) {
552
+ tmp_buf ++ ;
553
+ tmp_length -- ;
554
+ }
555
+ data_length = tmp_buf - buffer ;
556
+ source_length = data_length + 1 ;
557
+ } else if (buffer [1 ] == 0xf2 ) {
558
+ /* Three byte song position pointer */
559
+ data_length = 3 ;
560
+ }
561
+ snd_usbmidi_input_data (ep , buffer [0 ] >> 4 ,
562
+ & buffer [1 ], data_length );
563
+ } else {
564
+ /* normal channel events */
565
+ snd_usbmidi_standard_input (ep , buffer , source_length );
566
+ }
567
+ buffer += source_length ;
568
+ remaining -= source_length ;
569
+ }
502
570
}
503
571
504
572
/*
0 commit comments