Skip to content

Instantly share code, notes, and snippets.

@YuuichiAkagawa
Created September 24, 2017 02:38
Show Gist options
  • Save YuuichiAkagawa/8f3e8bf6ae7b69119dbb118fc39fb05e to your computer and use it in GitHub Desktop.
Save YuuichiAkagawa/8f3e8bf6ae7b69119dbb118fc39fb05e to your computer and use it in GitHub Desktop.
#include <usbh_midi.h>
#include <usbhub.h>
USB Usb;
//USBHub Hub(&Usb);
USBH_MIDI Midi(&Usb);
typedef enum {
nonsysex = 0,
ok = 1,
done = 0xfe,
overflow = 0xff
} SysExStatus;
void MIDI_poll();
boolean bFirst;
uint16_t pid, vid;
void setup() {
bFirst = true;
vid = pid = 0;
Serial.begin(115200);
if (Usb.Init() == -1) {
while (1); //halt
}//if (Usb.Init() == -1...
delay( 200 );
}
void loop() {
Usb.Task();
//uint32_t t1 = (uint32_t)micros();
if ( Usb.getUsbTaskState() == USB_STATE_RUNNING )
{
MIDI_poll();
}
}
//SysEx buffer
#define SYSEX_BUFSIZE (256)
uint8_t sysExBuf[SYSEX_BUFSIZE];
uint16_t sysExBufPtr = 0;
SysExStatus isSysEx(uint8_t *p)
{
uint8_t cin = *(p) & 0x0f;
//SysEx message?
//Non SysEx message
if( (cin & 0xc) != 4 ) return SysExStatus::nonsysex;
//SysEx end
if( 5 <= cin && cin <= 7 ) return SysExStatus::done;
return SysExStatus::ok;
}
// Poll USB MIDI Controler and send to serial MIDI
void MIDI_poll()
{
uint8_t size;
uint8_t recvBuf[MIDI_EVENT_PACKET_SIZE];
uint8_t rcode = 0; //return code
uint16_t rcvd;
uint8_t readPtr = 0;
rcode = Midi.RecvData( &rcvd, recvBuf);
//data check
if (rcode != 0) return;
if ( recvBuf[0] == 0 && recvBuf[1] == 0 && recvBuf[2] == 0 && recvBuf[3] == 0 ) {
return ;
}
uint8_t *p = recvBuf;
while (readPtr < MIDI_EVENT_PACKET_SIZE) {
if (*p == 0 && *(p + 1) == 0) break; //data end
uint8_t outbuf[3];
uint8_t rc = Midi.extractSysExData(p, outbuf);
if ( rc == 0 ) {
p++;
size = Midi.lookupMsgSize(*p);
// _MIDI_SERIAL_PORT.write(p, size);
dump(p, size, false);
p += 3;
} else {
//SysEX
// _MIDI_SERIAL_PORT.write(outbuf, rc);
/* copy buffer to SysEx packet */
for(uint8_t i=0; i<rc; i++){
sysExBuf[sysExBufPtr++] = outbuf[i];
}
//SysEx end?
if(isSysEx(p) ==SysExStatus::done) {
//SysEx end. any process
dump(sysExBuf, sysExBufPtr, true);
//clear
sysExBufPtr = 0;
}
p += 4;
}
readPtr += 4;
}
}
void dump(uint8_t *p, uint16_t size, boolean isSysEX)
{
char buf[16];
if(isSysEX) {//SysEX
sprintf(buf, "SysEx(%4d): ", size);
Serial.print(buf);
}else{
sprintf(buf, "StdMsg(%4d): ", size);
Serial.print(buf);
}
for (uint8_t i = 0; i < size; i++) {
sprintf(buf, " %02X", p[i]);
Serial.print(buf);
}
Serial.println("");
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment