@@ -489,16 +489,84 @@ static void ch345_broken_sysex_input(struct snd_usb_midi_in_endpoint *ep,
489489
490490/*
491491 * 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.
493495 */
494496static void snd_usbmidi_cme_input (struct snd_usb_midi_in_endpoint * ep ,
495497 uint8_t * buffer , int buffer_length )
496498{
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+ }
502570}
503571
504572/*
0 commit comments