BlokasLabs / USBMIDI

USB MIDI library for Arduino.
Other
189 stars 14 forks source link

Clock data and/or raw message #12

Closed frederickk closed 4 years ago

frederickk commented 4 years ago

🙏 firstly, thank you for this great library!

I'm looking to get the clock data from USB (Ableton vis USB and Norns via USB, FWIW), but my efforts to read any of the timing messages CLOCK (0xF8), START (0xFA), CONTINUE (0xFB), or STOP (0xFC) have not worked.

Here's the main part of my body, with debugging Serial calls. Any tips or guidance on how to get the timing would be much appreciated!

  while(USBMIDI.available()) {
    u8 b = USBMIDI.read();
    Serial.print(b);
    Serial.print("\t>>\t");
    Serial.print(b >> 4);
    Serial.println("------------------------------------------------------");

    uint8_t type1 = b & 0x0F;
    uint8_t type2 = b & 0xF0;

    Serial.print("type1: D\t");
    Serial.print(type1);
    Serial.print("\tH\t");
    Serial.println(type1, HEX);

    Serial.print("type2: D\t");
    Serial.print(type2);
    Serial.print("\tH\t");
    Serial.println(type2, HEX);
    Serial.println("------------------------------------------------------");

    if (type1 == 0x02 || type1 == 0x03 || (type1 == 0x05 && type2 == 0x0F)) {
      Serial.println("system common or system realtime message");

      // I know this is wrong, but I'm not sure where to look for these messages
      switch (b) {
        case 0xF1:
          Serial.println("usbMIDI.TimeCodeQuarterFrame");
          break;
        case 0xF8:
          Serial.println("usbMIDI.Clock");
          break;
        case 0xFA:
          Serial.println(" usbMIDI.Start");
          break;
        case 0xFB:
          Serial.println("usbMIDI.Continue");
          break;
        case 0xFC:
          Serial.println("usbMIDI.Stop");
          break;
        case 0xFF:
          Serial.println("usbMIDI.SystemReset");
          break;
        default:
          return;
      }
    } 
    Serial.println("------------------------------------------------------");
  }
gtrainavicius commented 4 years ago

This library has a MIDI serializer which produces midi_event_t structures which are easy to differentiate between different types of messages.

See Midimon source code where it prints appropriate message based on message type.

To parse the incoming data, essentially you do this:

// Global var
MidiToUsb g_parser;
// ...
// In main loop:
while(USBMIDI.available()) {
    u8 b = USBMIDI.read();
    midi_event_t event;
    if (g_parser.process(b, event)) {
        // a full event was received, access its data through 'event' variable and process as necessary.
    }
}
frederickk commented 4 years ago

@gtrainavicius perfect! thank you.