85 lines
3.8 KiB
Arduino
85 lines
3.8 KiB
Arduino
/*
|
|
This is an example of receiving USB MIDI 1.0 messages using an ESP32 with a native USB support stack
|
|
(S2, S3, etc.).
|
|
|
|
Receiving and decoding USB MIDI 1.0 packets is a more advanced topic than sending MIDI over USB,
|
|
please refer to the other examples in this library for a more basic example of sending MIDI over USB.
|
|
|
|
This example should still be self explanatory, please refer to the USB MIDI 1.0 specification (the spec)
|
|
for a more in-depth explanation of the packet format.
|
|
|
|
For the spec please visit: https://www.midi.org/specifications-old/item/usb-midi-1-0-specification
|
|
*/
|
|
#if ARDUINO_USB_MODE
|
|
#warning This sketch should be used when USB is in OTG mode
|
|
void setup() {}
|
|
void loop() {}
|
|
#else
|
|
|
|
#include "USB.h"
|
|
#include "USBMIDI.h"
|
|
USBMIDI MIDI;
|
|
|
|
void setup() {
|
|
Serial.begin(115200);
|
|
|
|
MIDI.begin();
|
|
USB.begin();
|
|
}
|
|
|
|
void loop() {
|
|
midiEventPacket_t midi_packet_in = {0, 0, 0, 0};
|
|
|
|
if (MIDI.readPacket(&midi_packet_in)) {
|
|
printDetails(midi_packet_in);
|
|
}
|
|
}
|
|
|
|
void printDetails(midiEventPacket_t &midi_packet_in) {
|
|
// See Chapter 4: USB-MIDI Event Packets (page 16) of the spec.
|
|
uint8_t cable_num = MIDI_EP_HEADER_CN_GET(midi_packet_in.header);
|
|
midi_code_index_number_t code_index_num = MIDI_EP_HEADER_CIN_GET(midi_packet_in.header);
|
|
|
|
Serial.println("Received a USB MIDI packet:");
|
|
Serial.println(".----.-----.--------.--------.--------.");
|
|
Serial.println("| CN | CIN | STATUS | DATA 0 | DATA 1 |");
|
|
Serial.println("+----+-----+--------+--------+--------+");
|
|
Serial.printf("| %d | %X | %X | %X | %X |\n", cable_num, code_index_num, midi_packet_in.byte1, midi_packet_in.byte2, midi_packet_in.byte3);
|
|
Serial.println("'----'-----'--------.--------'--------'\n");
|
|
Serial.print("Description: ");
|
|
|
|
switch (code_index_num) {
|
|
case MIDI_CIN_MISC: Serial.println("This a Miscellaneous event"); break;
|
|
case MIDI_CIN_CABLE_EVENT: Serial.println("This a Cable event"); break;
|
|
case MIDI_CIN_SYSCOM_2BYTE: // 2 byte system common message e.g MTC, SongSelect
|
|
case MIDI_CIN_SYSCOM_3BYTE: // 3 byte system common message e.g SPP
|
|
Serial.println("This a System Common (SysCom) event");
|
|
break;
|
|
case MIDI_CIN_SYSEX_START: // SysEx starts or continue
|
|
case MIDI_CIN_SYSEX_END_1BYTE: // SysEx ends with 1 data, or 1 byte system common message
|
|
case MIDI_CIN_SYSEX_END_2BYTE: // SysEx ends with 2 data
|
|
case MIDI_CIN_SYSEX_END_3BYTE: // SysEx ends with 3 data
|
|
Serial.println("This a system exclusive (SysEx) event");
|
|
break;
|
|
case MIDI_CIN_NOTE_ON: Serial.printf("This a Note-On event of Note %d with a Velocity of %d\n", midi_packet_in.byte2, midi_packet_in.byte3); break;
|
|
case MIDI_CIN_NOTE_OFF: Serial.printf("This a Note-Off event of Note %d with a Velocity of %d\n", midi_packet_in.byte2, midi_packet_in.byte3); break;
|
|
case MIDI_CIN_POLY_KEYPRESS: Serial.printf("This a Poly Aftertouch event for Note %d and Value %d\n", midi_packet_in.byte2, midi_packet_in.byte3); break;
|
|
case MIDI_CIN_CONTROL_CHANGE:
|
|
Serial.printf(
|
|
"This a Control Change/Continuous Controller (CC) event of Controller %d "
|
|
"with a Value of %d\n",
|
|
midi_packet_in.byte2, midi_packet_in.byte3
|
|
);
|
|
break;
|
|
case MIDI_CIN_PROGRAM_CHANGE: Serial.printf("This a Program Change event with a Value of %d\n", midi_packet_in.byte2); break;
|
|
case MIDI_CIN_CHANNEL_PRESSURE: Serial.printf("This a Channel Pressure event with a Value of %d\n", midi_packet_in.byte2); break;
|
|
case MIDI_CIN_PITCH_BEND_CHANGE:
|
|
Serial.printf("This a Pitch Bend Change event with a Value of %d\n", ((uint16_t)midi_packet_in.byte2) << 7 | midi_packet_in.byte3);
|
|
break;
|
|
case MIDI_CIN_1BYTE_DATA: Serial.printf("This an embedded Serial MIDI event byte with Value %X\n", midi_packet_in.byte1); break;
|
|
}
|
|
|
|
Serial.println();
|
|
}
|
|
#endif /* ARDUINO_USB_MODE */
|