// https://forum.pjrc.com/index.php?threads/teensy-4-1-hang-up-when-using-usbhost_t36-h-with-hub-to-control-multiple-midi-device.74966/
//
// Teensy MIDI USBhost test
// as submitted to the Teensy forum 20240226 (https://forum.pjrc.com/index.php?threads/whether-multiple-midi-devices-work-thru-usb-hub-seems-to-be-plug-order-dependent.74561/post-339860)
//
// - reads MIDI data & cmds from traditional MIDI, usbMIDI, or USBhost & plays the indicated note(s)
//
// Arduino IDE Configuration:
// Tools/Board: "Teensy 4.0"
// Tools/USB Type: "Serial + MIDI"
// Tools/CPU Speed: "600MHz"
// Tools/Optimize: "Debug"
// Tools/Keyboard Layout: "US English"
// Tools/Port: "COMx Serial (Teensy 4.0)"
//
#define DEBUG_NOTE_MSGS
#define DEBUG_MIDI_NOTE_MSGS
#define DEBUG_USB_MIDI_NOTE_MSGS
#define DEBUG_USBHOST_MIDI_NOTE_MSGS
#include <SPI.h>
#include <USBHost_t36.h>
#include <MIDI.h>
#include <Audio.h>
#define LOCAL_MIDI_CHANNEL_OMNI -1
int midi_channel = LOCAL_MIDI_CHANNEL_OMNI;
USBHost thisUSB;
USBHub hub1(thisUSB);
USBHub hub2(thisUSB);
USBHub hub3(thisUSB);
USBHub hub4(thisUSB);
MIDIDevice_BigBuffer usbhostMIDIa(thisUSB);
MIDIDevice_BigBuffer usbhostMIDIb(thisUSB);
MIDI_CREATE_DEFAULT_INSTANCE();
#define LED_PIN 13
// function headers
void handleNoteOff(byte channel, byte pitch, byte velocity);
void handleNoteOn(byte channel, byte pitch, byte velocity);
void loop(void);
void MIDIhandleNoteOff(byte channel, byte pitch, byte velocity);
void MIDIhandleNoteOn(byte channel, byte pitch, byte velocity);
void setup();
void USBhandleNoteOff(byte channel, byte pitch, byte velocity);
void USBhandleNoteOn(byte channel, byte pitch, byte velocity);
void usbhostMIDIahandleNoteOff(byte channel, byte pitch, byte velocity);
void usbhostMIDIahandleNoteOn(byte channel, byte pitch, byte velocity);
void usbhostMIDIbhandleNoteOff(byte channel, byte pitch, byte velocity);
void usbhostMIDIbhandleNoteOn(byte channel, byte pitch, byte velocity);
uint8_t type = 0;
uint8_t pitch = 0;
uint8_t velocity = 0;
uint8_t channel = 0;
uint32_t i = 0;
// -----------------------------------------------------------------------------
void setup() {
Serial.begin(9600);
delay(3000);
Serial.println("set up ...begin");
if (CrashReport) {
Serial.print(CrashReport);
}
pinMode(LED_PIN, OUTPUT);
usbMIDI.setHandleNoteOn(handleNoteOn); // Put only the name of the function
usbMIDI.setHandleNoteOff(handleNoteOff);
MIDI.setHandleNoteOn(MIDIhandleNoteOn); // Put only the name of the function
MIDI.setHandleNoteOff(MIDIhandleNoteOff);
usbMIDI.setHandleNoteOn(USBhandleNoteOn);
usbMIDI.setHandleNoteOff(USBhandleNoteOff);
usbhostMIDIa.setHandleNoteOn(usbhostMIDIahandleNoteOn);
usbhostMIDIa.setHandleNoteOff(usbhostMIDIahandleNoteOff);
usbhostMIDIb.setHandleNoteOn(usbhostMIDIbhandleNoteOn);
usbhostMIDIb.setHandleNoteOff(usbhostMIDIbhandleNoteOff);
// start the USBhost for MIDI inputs/devices
Serial.println("thisUSB.begin();");
thisUSB.begin();
// Initiate MIDI communications, listen to all channels
Serial.println("MIDI.begin(MIDI_CHANNEL_OMNI);");
MIDI.begin(MIDI_CHANNEL_OMNI);
Serial.println(" fine Set up");
}
// -----------------------------------------------------------------------------
void loop(void) {
static elapsedMillis msec; // print at a reasonable pace
if (msec > 1000) {
msec = 0;
Serial.print("loop:"); Serial.println(i);
i++;
}
MIDI.read();
usbMIDI.read();
usbhostMIDIa.read();
usbhostMIDIb.read();
thisUSB.Task();
} // loop()
// -----------------------------------------------------------------------------
void handleNoteOff(byte channel, byte pitch, byte velocity) {
Serial.print("Note Off: ch="); Serial.print(channel); Serial.print(" pitch="); Serial.println(pitch);
}
void handleNoteOn(byte channel, byte pitch, byte velocity) {
Serial.print("Note On: ch="); Serial.print(channel); Serial.print(" pitch="); Serial.print(pitch); Serial.print(" velocity="); Serial.println(velocity);
}
void MIDIhandleNoteOff(byte channel, byte pitch, byte velocity) {
Serial.print("MIDI Note Off: ch="); Serial.print(channel); Serial.print(" pitch="); Serial.println(pitch);
}
void MIDIhandleNoteOn(byte channel, byte pitch, byte velocity) {
Serial.print("MIDI Note On: ch="); Serial.print(channel); Serial.print(" pitch="); Serial.print(pitch); Serial.print(" velocity="); Serial.println(velocity);
}
void USBhandleNoteOff(byte channel, byte pitch, byte velocity) {
Serial.print("USB MIDI Note Off: ch="); Serial.print(channel); Serial.print(" pitch="); Serial.println(pitch);
}
void USBhandleNoteOn(byte channel, byte pitch, byte velocity) {
Serial.print("USB MIDI Note On: ch="); Serial.print(channel); Serial.print(" pitch="); Serial.print(pitch); Serial.print(" velocity="); Serial.println(velocity);
}
void usbhostMIDIahandleNoteOff(byte channel, byte pitch, byte velocity) {
Serial.print("USBhost MIDI(a) Note Off: ch="); Serial.print("0"); Serial.print(channel); Serial.print(" pitch="); Serial.println(pitch);
}
void usbhostMIDIahandleNoteOn(byte channel, byte pitch, byte velocity) {
Serial.print("USBhost MIDI(a) Note On: ch="); Serial.print(channel); Serial.print(" pitch="); Serial.print(pitch); Serial.print(" velocity="); Serial.println(velocity);
}
void usbhostMIDIbhandleNoteOff(byte channel, byte pitch, byte velocity) {
Serial.print("USBhost MIDI(b) Note Off: ch="); Serial.print("0"); Serial.print(channel); Serial.print(" pitch="); Serial.println(pitch);
}
void usbhostMIDIbhandleNoteOn(byte channel, byte pitch, byte velocity) {
Serial.print("USBhost MIDI(b) Note On: ch="); Serial.print(channel); Serial.print(" pitch="); Serial.print(pitch); Serial.print(" velocity="); Serial.println(velocity);
}
// EOF PLACEHOLDER