Skip to content

Instantly share code, notes, and snippets.

@YuuichiAkagawa
Created February 20, 2021 15:50
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save YuuichiAkagawa/52710af4bc013d1af7248b1aaa80f7f2 to your computer and use it in GitHub Desktop.
Save YuuichiAkagawa/52710af4bc013d1af7248b1aaa80f7f2 to your computer and use it in GitHub Desktop.
/*
*******************************************************************************
Serial MIDI to USB MIDI bridge
Copyright (C) 2021 Yuuichi Akagawa
for use with Arduino MIDI library
https://github.com/FortySevenEffects/arduino_midi_library/
Note:
- If you want use with Leonardo, you must choose Arduino MIDI library v4.0 or higher.
- This is sample program. Do not expect perfect behavior.
*******************************************************************************
*/
#include <MIDI.h>
#include <usbh_midi.h>
#include <usbhub.h>
#include <SoftwareSerial.h>
// Satisfy the IDE, which needs to see the include statment in the ino too.
#ifdef dobogusinclude
#include <spi4teensy3.h>
#endif
#include <SPI.h>
//Arduino MIDI library v4.2 compatibility
#ifdef MIDI_CREATE_DEFAULT_INSTANCE
MIDI_CREATE_DEFAULT_INSTANCE();
#endif
USB Usb;
USBHub Hub1(&Usb);
USBH_MIDI Midi1(&Usb);
USBH_MIDI Midi2(&Usb);
SoftwareSerial mySerial(5, 6); // RX, TX
//If you want handle System Exclusive message, enable this #define otherwise comment out it.
#define USBH_MIDI_SYSEX_ENABLE
#ifdef USBH_MIDI_SYSEX_ENABLE
//SysEx:
void handle_sysex( byte* sysexmsg, unsigned sizeofsysex) {
// Midi.SendSysEx(sysexmsg, sizeofsysex);
}
#endif
#define DEBUG
void setup()
{
mySerial.begin(115200);
MIDI.begin(MIDI_CHANNEL_OMNI);
MIDI.turnThruOff();
#ifdef USBH_MIDI_SYSEX_ENABLE
MIDI.setHandleSystemExclusive(handle_sysex);
#endif
if (Usb.Init() == -1) {
while (1); //halt
}//if (Usb.Init() == -1...
delay( 200 );
}
void loop()
{
Usb.Task();
uint8_t msg[4];
if (MIDI.read()) {
msg[0] = MIDI.getType();
switch (msg[0]) {
case midi::ActiveSensing :
break;
case midi::SystemExclusive :
//SysEx is handled by event.
break;
default :
#ifdef DEBUG
mySerial.print("MIDI Type(hex) = ");
mySerial.println(msg[0], HEX);
#endif
// If this is a channel messages, set the channel number.
if ( msg[0] < 0xf0 ) {
// The getchannel() returns 1-16, but the MIDI status byte starts at 0.
msg[0] |= MIDI.getChannel() - 1;
#ifdef DEBUG
mySerial.print("Channel = ");
mySerial.println(MIDI.getChannel());
mySerial.println();
#endif
}
msg[1] = MIDI.getData1();
msg[2] = MIDI.getData2();
if ( Midi1 )
{
uint8_t rc = Midi1.SendData(msg, 0);
if ( rc != 0 ) {
mySerial.print("Midi1 error:");
mySerial.println(rc, HEX);
}
#ifdef DEBUG
mySerial.println("MIDI 1");
mySerial.print("Status Byte = ");
mySerial.println(msg[0]);
mySerial.print("DataByte 1 = ");
mySerial.println(msg[1]);
mySerial.print("DataByte 2 = ");
mySerial.println(msg[2]);
mySerial.println();
#endif
}
if ( Midi2 ) {
uint8_t rc = Midi2.SendData(msg, 0);
if ( rc != 0 ) {
mySerial.print("Midi1 error:");
mySerial.println(rc, HEX);
}
#ifdef DEBUG
mySerial.println("MIDI 2");
mySerial.print("Status Byte = ");
mySerial.println(msg[0]);
mySerial.print("DataByte 1 = ");
mySerial.println(msg[1]);
mySerial.print("DataByte 2 = ");
mySerial.println(msg[2]);
mySerial.println("************************");
mySerial.println();
#endif
}
delayMicroseconds(3000);
break;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment