Created
March 10, 2020 22:42
-
-
Save todbot/7f05268ed3c5201c163a3e269d2c2d64 to your computer and use it in GitHub Desktop.
Demonstrate MIDI message loss by comparing received note-on vs note-off messages
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
******************************************************************************* | |
* USB-MIDI dump utility | |
* Copyright (C) 2013-2017 Yuuichi Akagawa | |
* | |
* for use with USB Host Shield 2.0 from Circuitsathome.com | |
* https://github.com/felis/USB_Host_Shield_2.0 | |
* | |
* This is sample program. Do not expect perfect behavior. | |
******************************************************************************* | |
*/ | |
/* | |
* Demonstrate MIDI message loss by comparing received note-on vs note-off messages | |
* To use: connect MIDI keyboard and serial monitor, hit many keys, see note-on vs note-off mismatch | |
*/ | |
#include <usbh_midi.h> | |
#include <usbhub.h> | |
//// On SAMD boards where the native USB port is also the serial console, use | |
//// Serial1 for the serial console. This applies to all SAMD boards except for | |
//// Arduino Zero and M0 boards. | |
#if (USB_VID==0x2341 && defined(ARDUINO_SAMD_ZERO)) || (USB_VID==0x2a03 && defined(ARDUINO_SAM_ZERO)) | |
#define SerialDebug SERIAL_PORT_MONITOR | |
#else | |
#define SerialDebug Serial1 | |
#endif | |
USBHost UsbH; | |
USBHub Hub(&UsbH); | |
USBH_MIDI Midi(&UsbH); | |
void MIDI_poll(); | |
void doDelay(uint32_t t1, uint32_t t2, uint32_t delayTime); | |
uint16_t pid, vid; | |
char buf[128]; // must hold full bufMidi as str plus metainfo | |
void setup() | |
{ | |
vid = pid = 0; | |
SerialDebug.begin(115200); | |
if (UsbH.Init()) { | |
SerialDebug.println("USB host did not start"); | |
while (1); //halt | |
} | |
delay( 200 ); | |
} | |
void loop() | |
{ | |
UsbH.Task(); | |
//uint32_t t1 = (uint32_t)micros(); | |
if ( Midi ) { | |
MIDI_poll(); | |
} | |
} | |
int noteon_count = 0; | |
int noteoff_count = 0; | |
// parse out the multiple 4-byte USB-MIDI events inside the 64-byte USB packet | |
// display count of note on msgs vs note off msgs | |
void MIDI_parse(uint8_t* bufMidi) | |
{ | |
for( int i=0; i<64; i+=4 ) { // stride of 4, all USB-MIDI are 4-bytes | |
uint8_t cn = bufMidi[i] >> 4; // cable number | |
uint8_t cin = bufMidi[i] & 0x0f; // code index number | |
uint8_t* midiMsg = bufMidi+i+1; // actual midi msg (1-3 bytes) | |
if( midiMsg[0] == 0x90 ) { noteon_count++; } // note on | |
if( midiMsg[0] == 0x80 ) { noteoff_count++; } // note off | |
} | |
sprintf(buf, "note on:%d note off:%d", noteon_count, noteoff_count); | |
SerialDebug.println(buf); | |
} | |
// Poll USB MIDI Controler and send to serial MIDI | |
void MIDI_poll() | |
{ | |
uint8_t bufMidi[64]; | |
uint16_t rcvd; | |
memset(bufMidi,0, sizeof(bufMidi)); // clear out in case rcvd lies | |
if (Midi.idVendor() != vid || Midi.idProduct() != pid) { | |
vid = Midi.idVendor(); | |
pid = Midi.idProduct(); | |
sprintf(buf, "VID:%04X, PID:%04X", vid, pid); | |
SerialDebug.println(buf); | |
} | |
if (Midi.RecvData(&rcvd, bufMidi) == 0 ) { | |
uint32_t time = (uint32_t)millis(); | |
// Split variable to prevent warnings on the ESP8266 platform | |
sprintf(buf, "%04X%04X: ", (uint16_t)(time >> 16), (uint16_t)(time & 0xFFFF)); | |
SerialDebug.print(buf); | |
SerialDebug.print(rcvd); | |
SerialDebug.print(':'); | |
for (int i = 0; i < 64; i++) { | |
sprintf(buf, "%02X", bufMidi[i]); | |
SerialDebug.print(buf); | |
} | |
SerialDebug.println(); | |
MIDI_parse(bufMidi); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment