Convert USB MIDI to recognizable MIDI format

I have a USB host shield on an Arduino Leonardo, powered with 5v via the USB on the Leonardo.
The shield is connected to a piano's USB MIDI out.

I'm trying to isolate a couple parameters of the incoming midi data to control a peripheral. I'm having difficulty dumping and observing the MIDI data in a meaningful way.
Using the USBH_MIDI_dump example in the USB_Host_Shield_2.0 library, I can register key down and up events, and using the bidirectional_converter example, even send random/mystery data to the piano.

Here is the portion of the MIDI_dump sketch I think is most relevant.

 if (Midi.RecvData( &rcvd,  bufMidi) == 0 ) {
    uint32_t time = (uint32_t)millis();
    sprintf(buf, "%04X%04X: ", (uint16_t)(time >> 16), (uint16_t)(time & 0xFFFF)); // Split variable to prevent warnings on the ESP8266 platform
    Serial.print(buf);
    Serial.print(rcvd);
    Serial.print(':');
    for (int i = 0; i < 64; i++) {
      sprintf(buf, " %02X", bufMidi[i]);
      Serial.print(buf);
    }
    Serial.println("");
  }

Here we check if MIDI was received, iterate through it, split it and prints it in a way that I think is meant to be more easily readable. Regardless, I don't understand the data that's output. Is there a conversion I need to do on the received data? As it is, I'm unable to parse or manipulate the data because I'm ignorant of what it is.

Below is the data returned for a key down and key up event.

0000363F: 4: 09 90 18 4D 00 00 00 08 82 05 22 01 00 01 01 02 00 01 02 71 10 A4 00 00 40 00 00 00 00 08 82 05 22 01 00 01 01 02 00 01 04 01 00 A0 0F CB 10 43 04 03 03 B3 0F FF 20 00 00 B5 B6 35 57 00 04 50
000036AF: 4: 08 80 18 66 00 00 00 08 82 05 22 01 00 01 01 02 00 01 02 71 10 A4 00 00 40 00 00 00 00 08 82 05 22 01 00 01 01 02 00 01 04 01 00 A0 0F CB 10 43 04 03 03 B3 0F FF 20 00 00 B5 B6 35 57 00 04 50

Or for the USB_MIDI_converter example, if I dump the data being output via the serial port,

  do {
    if ( (size = Midi.RecvData(outBuf)) > 0 ) {
      //MIDI Output
      _MIDI_SERIAL_PORT.write(outBuf, size);
    }
  } while (size > 0);

every key press returns

121 3

Of the USB MIDI libraries I've tried, these USB_Host_Shield_2.0 MIDI examples are the only one's that I've had some success with. They receive and send some form of midi data.

Searching around, most people posting about using the shield aren't interested in decoding or manipulating MIDI in from a source, so I haven't found resources about this particular issue.

Any guidance is very appreciated. Thank you.

MIDI.RecvData writes the number of bytes it read to the rcvd variable. You're printing the entire buffer, which is meaningless, you should only print bytes 0 through rcvd-1:

    for (int i = 0; i < rcvd; i++) {
      sprintf(buf, " %02X", bufMidi[i]);
      Serial.print(buf);
    }

So the valid data from your experiment is:

0000363F: 4: 09 90 18 4D
000036AF: 4: 08 80 18 66

To interpret this data, you'll have to read the MIDI USB spec: The MIDI Association - USB-MIDI

A first byte of 09 means that the cable number for this message is 0 (CN = 0) and that the message is a MIDI Note On Channel Message (CIN = 9).
The second byte of 90 means that it is a MIDI Note On message on channel 1.
The third byte of 18 is the note number (24 semitones from the lowest note).
The fourth byte of 4D is the velocity.

Pieter

PieterP:
MIDI.RecvData writes the number of bytes it read to the rcvd variable. You're printing the entire buffer, which is meaningless, you should only print bytes 0 through rcvd-1:

    for (int i = 0; i < rcvd; i++) {

sprintf(buf, " %02X", bufMidi[i]);
      Serial.print(buf);
    }




So the valid data from your experiment is:


0000363F: 4: 09 90 18 4D
000036AF: 4: 08 80 18 66



To interpret this data, you'll have to read the MIDI USB spec: https://www.midi.org/specifications/midi-transports-specifications/usb

A first byte of `09` means that the cable number for this message is 0 (CN = 0) and that the message is a MIDI Note On Channel Message (CIN = 9).
The second byte of `90` means that it is a MIDI Note On message on channel 1.
The third byte of `18` is the note number (24 semitones from the lowest note).
The fourth byte of `4D` is the velocity.

Pieter

Thank you so much. This is wildly helpful.
It's 24 semitones? Wouldn't it be 4 semitones on an 88 key keyboard? I thought key 21 was A0
Regardless, up next will be figuring out how why it registered a key that doesn't exist.
Thanks again.

Dr-Zee:
It's 24 semitones? Wouldn't it be 4 semitones on an 88 key keyboard? I thought key 21 was A0
Regardless, up next will be figuring out how why it registered a key that doesn't exist.

1816 = 2410
The lowest MIDI note is C-1. Note 24 is two octaves higher, so C1.