The universal MIDI hub for ESP32 — 8 transports, one API.
ESP32_Host_MIDI turns your ESP32 into a full-featured, multi-protocol MIDI hub. Connect a USB keyboard, receive notes from an iPhone via Bluetooth, bridge your DAW over WiFi with RTP-MIDI (Apple MIDI), control Max/MSP via OSC, reach 40-year-old synths through a DIN-5 serial cable, and link multiple ESP32 boards wirelessly with ESP-NOW — all simultaneously, all through the same clean event API.
#include <ESP32_Host_MIDI.h>
void setup() { midiHandler.begin(); }
void loop() {
midiHandler.task();
for (const auto& ev : midiHandler.getQueue())
Serial.printf("%-12s %-4s ch=%d vel=%d\n",
ev.status.c_str(), ev.noteOctave.c_str(),
ev.channel, ev.velocity);
}A partial list. Every combination of transports opens a new instrument, tool, or installation.
Wireless MIDI interfaces
- USB keyboard → ESP32 → WiFi → macOS (Logic Pro / GarageBand) — no drivers, no cables to the Mac
- iPhone / iPad BLE app → ESP32 → USB MIDI Device → DAW port — iOS apps become studio controllers
- ESP32 presents itself as a USB MIDI Class Compliant interface — plug into any computer, it just works
Custom hardware instruments
- Effects pedal board — ESP32 sends Program Change / CC messages to a Daisy Seed or hardware multi-effects unit; display shows preset name and bank
- MIDI drum pad — piezo sensors on ADC inputs → velocity-sensitive MIDI notes → USB or BLE
- Custom synthesizer — ESP32 receives MIDI and controls an external DAC + VCO/VCA analog circuit, or triggers a Daisy Seed running a synth engine
- MIDI controller — encoders, faders, buttons, touchpads → USB MIDI Device → any DAW
- MIDI to CV converter — ESP32 + external DAC (MCP4728, MCP4921) → 0–5 V CV / gate for Eurorack and analog synths
- Wireless expression pedal — foot controller with ESP-NOW → central ESP32 hub → CC messages
- Smart metronome / clock — generates MIDI Clock at precise BPM, sent simultaneously over USB, BLE, DIN-5, and WiFi
- Theremin with MIDI output — ultrasonic sensors or capacitive touch → pitch + volume → MIDI notes
- MIDI accordion or wind controller — pressure sensors + buttons → ESP32 → BLE → iPad instrument
Bridges and routers
- DIN-5 vintage synth → ESP32 → USB Device → modern DAW — zero-driver adapter
- Wireless stage rig: ESP-NOW mesh of performers → single USB output to FOH computer Creative software integration
- Max/MSP / Pure Data / SuperCollider ↔ ESP32 over OSC — bidirectional, address-mapped
- TouchOSC tablet → ESP32 → DIN-5 hardware synth — touchscreen for vintage gear
- Algorithmic composition in Max → OSC → ESP32 → BLE → iOS instrument app
Monitoring and education
- Live piano roll: keys lit as you play, scrollable view on a 1.9" display
- Real-time chord detection: plays a chord, see its name instantly ("Cmaj7", "Dm7♭5")
- MIDI event logger with timestamps, channel, velocity, and chord grouping
| Transport | Protocol | Physical | Latency | Requires |
|---|---|---|---|---|
| USB Host | USB MIDI 1.0 | USB-OTG cable | < 1 ms | ESP32-S3 / S2 / P4 |
| BLE MIDI | BLE MIDI 1.0 | Bluetooth LE | 3–15 ms | Any ESP32 with BT |
| USB Device | USB MIDI 1.0 | USB-OTG cable | < 1 ms | ESP32-S3 / S2 / P4 |
| ESP-NOW MIDI | ESP-NOW | 2.4 GHz radio | 1–5 ms | Any ESP32 |
| RTP-MIDI (WiFi) | AppleMIDI / RFC 6295 | WiFi UDP | 5–20 ms | Any ESP32 with WiFi |
| Ethernet MIDI | AppleMIDI / RFC 6295 | Wired (W5x00 / native) | 2–10 ms | W5500 SPI or ESP32-P4 |
| OSC | Open Sound Control | WiFi UDP | 5–15 ms | Any ESP32 with WiFi |
| UART / DIN-5 | Serial MIDI 1.0 | DIN-5 connector | < 1 ms | Any ESP32 |
All transports share a single MIDIHandler event queue and the same send API. Mix and match at will.
#include <ESP32_Host_MIDI.h>
// Arduino IDE: Tools > USB Mode → "USB Host"
void setup() {
Serial.begin(115200);
midiHandler.begin();
}
void loop() {
midiHandler.task();
for (const auto& ev : midiHandler.getQueue())
Serial.println(ev.noteOctave.c_str());
}Access individual fields:
for (const auto& ev : midiHandler.getQueue()) {
ev.status; // "NoteOn" | "NoteOff" | "ControlChange" | "PitchBend" …
ev.channel; // 1–16
ev.note; // MIDI note number (0–127)
ev.noteOctave; // "C4", "D#5" …
ev.velocity; // 0–127
ev.pitchBend; // 0–16383 (center = 8192)
ev.chordIndex; // groups simultaneous notes
ev.timestamp; // millis() at arrival
}RTP-MIDI / Apple MIDI connecting to macOS · 25-key scrolling piano roll
25-key scrolling piano roll · Real-time chord name (Gingoduino) · Event queue debug
BLE Receiver (iPhone → ESP32) · BLE Sender · Piano debug view
Videos — each example folder contains an
.mp4demo insideexamples/<name>/images/.
╔══════════════════════════════════════════════════════════════════════╗
║ INPUTS MIDIHandler OUTPUTS ║
║ ║
║ USB keyboard ──[USBConnection]────► ┌──────────────┐ ║
║ iPhone BLE ──[BLEConnection]────► │ │ ║
║ macOS WiFi ──[RTPMIDIConn.]─────► │ Event Queue │──► getQueue()║
║ DAW USB out ──[USBDeviceConn]────► │ (ring buf, │ ║
║ Max/MSP OSC ──[OSCConnection]────► │ thread-safe)│──► Active ║
║ W5500 LAN ──[EthernetMIDI]─────► │ │ notes ║
║ DIN-5 serial ──[UARTConnection]───► │ Chord │ ║
║ ESP32 radio ──[ESPNowConn.]──────► └──────┬───────┘──► Chord ║
║ │ names ║
║ │ ║
║ ▼ ║
║ sendMidiMessage() ║
║ (broadcasts to ALL transports) ║
╚══════════════════════════════════════════════════════════════════════╝
Core 0 — USB Host task, BLE stack, radio / network drivers (FreeRTOS tasks)
Core 1 — midiHandler.task() + your loop() code
Thread safety — ring buffers + portMUX spinlocks on every transport
Every transport implements the same MIDITransport abstract interface. Adding a new transport is one line: midiHandler.addTransport(&myTransport).
Connects any class-compliant USB MIDI device — keyboards, pads, interfaces, drum machines, controllers — directly to the ESP32's USB-OTG port. No hub, no driver, no OS configuration.
Boards: ESP32-S3, ESP32-S2, ESP32-P4 · Arduino IDE: Tools > USB Mode → "USB Host"
#include <ESP32_Host_MIDI.h>
void setup() { midiHandler.begin(); }Examples: T-Display-S3, T-Display-S3-Queue, T-Display-S3-Piano, T-Display-S3-Gingoduino
The ESP32 advertises as a BLE MIDI 1.0 peripheral. macOS (Audio MIDI Setup → Bluetooth), iOS (GarageBand, AUM, Loopy, Moog), and Android connect without any pairing ritual. Also supports Central (scanner) mode to connect to another BLE MIDI device.
Boards: Any ESP32 with Bluetooth · Range: ~30 m · Latency: 3–15 ms
#include <ESP32_Host_MIDI.h>
void setup() { midiHandler.begin(); } // BLE advertises automaticallyExamples: T-Display-S3-BLE-Sender, T-Display-S3-BLE-Receiver
The ESP32-S3 presents itself as a class-compliant USB MIDI interface to the host computer. macOS, Windows, and Linux recognise it instantly — no driver. Acts as a transparent bridge: any MIDI from BLE, WiFi, UART, or ESP-NOW is forwarded to the DAW via USB, and vice versa.
Boards: ESP32-S3, ESP32-S2, ESP32-P4 · Arduino IDE: Tools > USB Mode → "USB-OTG (TinyUSB)"
Cannot coexist with USB Host — both use the OTG port.
#include "src/USBDeviceConnection.h"
USBDeviceConnection usbMIDI("ESP32 MIDI"); // name shown in DAW MIDI port list
void setup() {
midiHandler.addTransport(&usbMIDI);
usbMIDI.begin();
midiHandler.begin();
}Examples: USB-Device-MIDI, T-Display-S3-USB-Device
Ultra-low-latency (~1–5 ms) wireless MIDI between ESP32 boards via Espressif's proprietary peer-to-peer radio. No WiFi router, no handshake, no pairing. Broadcast mode (all boards receive everyone's notes) or unicast.
Boards: Any ESP32 · Range: ~200 m open air · Infrastructure: none
#include "src/ESPNowConnection.h"
ESPNowConnection espNow;
void setup() {
espNow.begin();
midiHandler.addTransport(&espNow);
midiHandler.begin();
}Examples: ESP-NOW-MIDI, T-Display-S3-ESP-NOW-Jam
Implements Apple MIDI (RTP-MIDI, RFC 6295) over WiFi UDP. macOS and iOS discover the ESP32 automatically via mDNS Bonjour — it appears in Audio MIDI Setup → Network with no manual configuration. Compatible with Logic Pro, GarageBand, Ableton, and any CoreMIDI app.
Requires: lathoub/Arduino-AppleMIDI-Library v3.x
#include <WiFi.h>
#include "src/RTPMIDIConnection.h"
RTPMIDIConnection rtpMIDI;
void setup() {
WiFi.begin("YourSSID", "YourPassword");
while (WiFi.status() != WL_CONNECTED) delay(500);
midiHandler.addTransport(&rtpMIDI);
rtpMIDI.begin();
midiHandler.begin();
}Examples: RTP-MIDI-WiFi
Same RTP-MIDI / AppleMIDI protocol over a wired W5x00 SPI Ethernet module or ESP32-P4 native Ethernet MAC. Lower and more consistent latency than WiFi. Ideal for studio racks and live venues with managed networks.
Requires: lathoub/Arduino-AppleMIDI-Library v3.x + Arduino Ethernet library
#include <SPI.h>
#include "src/EthernetMIDIConnection.h"
EthernetMIDIConnection ethMIDI;
static const uint8_t MAC[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
void setup() {
midiHandler.addTransport(ðMIDI);
ethMIDI.begin(MAC); // DHCP — pass a static IPAddress as second arg for fixed IP
midiHandler.begin();
}Examples: Ethernet-MIDI
Bidirectional OSC ↔ MIDI bridge over WiFi UDP. Receives OSC messages from Max/MSP, Pure Data, SuperCollider, and TouchOSC and converts them to MIDI events — and sends every MIDI event out as an OSC message.
Address map: /midi/noteon, /midi/noteoff, /midi/cc, /midi/pc, /midi/pitchbend, /midi/aftertouch
Requires: CNMAT/OSC library
#include <WiFi.h>
#include "src/OSCConnection.h"
OSCConnection oscMIDI;
void setup() {
WiFi.begin("YourSSID", "YourPassword");
while (WiFi.status() != WL_CONNECTED) delay(500);
midiHandler.addTransport(&oscMIDI);
oscMIDI.begin(8000, IPAddress(192, 168, 1, 100), 9000);
midiHandler.begin();
}Examples: OSC-MIDI-WiFi, T-Display-S3-OSC
Standard MIDI serial (31250 baud, 8N1) for connecting vintage hardware — synthesizers, drum machines, mixers, sequencers, anything with a DIN-5 connector. Supports running status, real-time messages (Clock, Start, Stop), and multiple simultaneous UART ports (ESP32-P4 has five hardware UARTs).
Hardware: TX → DIN-5 pin 5 via 220 Ω; PC-900V / 6N138 optocoupler on RX → DIN-5 pin 4
#include "src/UARTConnection.h"
UARTConnection uartMIDI;
void setup() {
uartMIDI.begin(Serial1, /*RX=*/16, /*TX=*/17);
midiHandler.addTransport(&uartMIDI);
midiHandler.begin();
}Examples: UART-MIDI-Basic, P4-Dual-UART-MIDI
Any MIDI arriving on any transport is automatically forwarded to all others — no extra code.
| Bridge | Diagram |
|---|---|
| Wireless keyboard → DAW | iPhone BLE → ESP32 → USB Device → Logic Pro |
| USB keyboard → WiFi | USB keyboard → ESP32 → RTP-MIDI → macOS |
| Legacy to modern | DIN-5 synth → ESP32 → USB Device → any DAW |
| Modern to legacy | macOS → RTP-MIDI → ESP32 → DIN-5 → 1980s drum machine |
| Wireless stage mesh | ESP-NOW nodes → ESP32 hub → USB → FOH computer |
| Creative software | Max/MSP OSC → ESP32 → BLE → iPad instrument app |
Full hub — receive everything, send everywhere:
USB keyboard ─┐
iPhone BLE ─┤
macOS RTP ──┼──► MIDIHandler ──► USB Device (DAW)
DIN-5 synth ─┤ ──► BLE (iOS app)
TouchOSC ─┤ ──► DIN-5 (drum machine)
ESP-NOW ─┘ ──► ESP-NOW (stage nodes)
ESP32_Host_MIDI acts as the MIDI brain and protocol hub. It connects and communicates with a broad ecosystem of boards and devices.
| Board | Connection | Use case |
|---|---|---|
| Daisy Seed (Electro-Smith) | UART / DIN-5 or USB | DSP audio synthesis engine; ESP32 sends MIDI, Daisy plays notes |
| Teensy 4.x (PJRC) | UART serial or USB Host | Complex MIDI routing or synthesis; excellent USB MIDI native support |
| Arduino UNO / MEGA / Nano | UART serial (DIN-5) | Classic MIDI projects; ESP32 is the wireless gateway |
| Raspberry Pi | RTP-MIDI, OSC, or USB | DAW host, audio processing, generative composition |
| Eurorack / modular synths | MIDI DIN-5 → CV/gate interface | Pitch CV, gate, velocity → analogue voltage via converter module |
| Hardware synthesizers | DIN-5 | Any keyboard, rack synth, or effects unit with MIDI In/Out/Thru |
| iPad / iPhone | BLE MIDI | GarageBand, AUM, Moog apps, NLog, Animoog — all CoreMIDI-compatible |
| Computer DAW | USB Device or RTP-MIDI | Logic Pro, Ableton, Bitwig, FL Studio, Reaper, Pro Tools |
Daisy Seed + ESP32 is a particularly powerful combination: the ESP32 handles all MIDI connectivity (USB, BLE, WiFi, DIN-5) and the Daisy Seed processes audio in real time at 48 kHz / 24-bit with its ARM Cortex-M7 DSP. They talk over a single UART/DIN-5 cable.
Teensy 4.1 can run complex MIDI logic, arpeggiators, chord voicers, or sequencers, while ESP32 handles wireless transport — each board doing what it does best.
┌─────────────────────────────────────────────────────────────────────┐
│ PROJECT │ COMPONENTS │
├─────────────────────────────────────────────────────────────────────┤
│ Wireless MIDI pedal │ ESP32 + buttons + enclosure → ESP-NOW │
│ board │ → central hub → DIN-5 / USB to amp rack │
├─────────────────────────────────────────────────────────────────────┤
│ MIDI drum pad │ ESP32 + piezo sensors + ADC → velocity- │
│ │ sensitive MIDI notes over USB or BLE │
├─────────────────────────────────────────────────────────────────────┤
│ Synthesizer │ ESP32 + Daisy Seed: ESP32 bridges all │
│ │ MIDI protocols, Daisy generates audio │
├─────────────────────────────────────────────────────────────────────┤
│ MIDI to CV converter │ ESP32 + MCP4728 DAC → 0–5 V pitch CV + │
│ │ gate for Eurorack / analogue synths │
├─────────────────────────────────────────────────────────────────────┤
│ Custom MIDI │ ESP32-S3 + encoders + faders + OLED → │
│ controller │ USB MIDI Device recognized by any DAW │
├─────────────────────────────────────────────────────────────────────┤
│ Piano learning aid │ ESP32 + RGB LEDs on piano keys + display │
│ │ → lights the correct key for each note │
├─────────────────────────────────────────────────────────────────────┤
│ Wireless expression │ ESP32 + FSR / potentiometer in foot │
│ pedal │ enclosure → CC messages via ESP-NOW │
├─────────────────────────────────────────────────────────────────────┤
│ MIDI arpeggiator / │ ESP32 receives chords, generates │
│ sequencer │ arpeggiated patterns, sends to DIN-5 │
├─────────────────────────────────────────────────────────────────────┤
│ Theremin / air synth │ Ultrasonic sensors → pitch + volume → │
│ │ MIDI notes via BLE or USB │
├─────────────────────────────────────────────────────────────────────┤
│ Interactive art │ Motion / proximity / touch sensors → │
│ installation │ MIDI → generative music / light control │
└─────────────────────────────────────────────────────────────────────┘
The LilyGO T-Display-S3 has a 1.9" 170×320 ST7789 display + ESP32-S3. These examples show a live MIDI dashboard in landscape mode (320×170 after setRotation(2)).
| Example | Transport | What the display shows |
|---|---|---|
T-Display-S3 |
USB Host | Active notes + event log |
T-Display-S3-Queue |
USB Host | Full event queue debug view |
T-Display-S3-Piano |
USB Host | 25-key scrollable piano roll |
T-Display-S3-Piano-Debug |
USB Host | Piano roll + extended debug info |
T-Display-S3-Gingoduino |
USB Host + BLE | Chord names (music theory engine) |
T-Display-S3-BLE-Sender |
BLE | Send mode status + event log |
T-Display-S3-BLE-Receiver |
BLE | Receive mode + note log |
T-Display-S3-ESP-NOW-Jam |
ESP-NOW | Peer status + jam events |
T-Display-S3-OSC |
OSC + WiFi | WiFi status + OSC bridge log |
T-Display-S3-USB-Device |
BLE + USB Device | Dual status + bridge log |
Gingoduino is a music theory library for embedded systems — the same engine that powers the T-Display-S3-Gingoduino example. When integrated via GingoAdapter.h, it listens to the same MIDI event stream and continuously analyses the active notes to produce:
- Chord name — "Cmaj7", "Dm7♭5", "G7", "Am" with extensions and alterations
- Root note — identified root pitch of the chord
- Active note set — structured list of currently pressed notes
- Interval analysis — intervals between notes (M3, m7, P5, etc.)
- Scale matching — identifies likely scale (major, minor, modes)
Everything runs on-device at interrupt speed — no cloud, no network, no latency.
#include "src/GingoAdapter.h" // requires Gingoduino ≥ v0.2.2
void loop() {
midiHandler.task();
// Chord name updates automatically as notes arrive and are released:
std::string chord = gingoAdapter.getChordName(); // "Cmaj7", "Dm", "G7sus4" …
std::string root = gingoAdapter.getRootNote(); // "C", "D", "G" …
display.setChord(chord.c_str());
}T-Display-S3-Gingoduino: chord name, root note, and active keys updated in real time
→ github.com/sauloverissimo/gingoduino
Gingo is the desktop and Python counterpart of Gingoduino — the same music theory concepts ported to Python for use in scripts, DAW integrations, MIDI processors, composition tools, and web apps.
Use it to:
- Analyse MIDI files and extract chord progressions
- Build Python MIDI processors that recognise chords on the fly
- Create web applications with real-time music theory annotation
- Prototype music theory algorithms before porting them to Gingoduino
- Generate chord charts, lead sheets, and educational exercises
from gingo import Gingo
g = Gingo()
chord = g.identify([60, 64, 67, 71]) # C E G B
print(chord.name) # "Cmaj7"
print(chord.root) # "C"→ github.com/sauloverissimo/gingo → sauloverissimo.github.io/gingo
ESP32 + Gingo workflow: prototype music theory algorithms in Python with Gingo → port the logic to Gingoduino on ESP32 → display chord names live on T-Display-S3.
| Chip | USB Host | BLE | USB Device | WiFi | Ethernet (native) | UART | ESP-NOW |
|---|---|---|---|---|---|---|---|
| ESP32-S3 | ✅ | ✅ | ✅ | ✅ | ❌ (W5500 SPI) | ✅ | ✅ |
| ESP32-S2 | ✅ | ❌ | ✅ | ✅ | ❌ (W5500 SPI) | ✅ | ❌ |
| ESP32-P4 | ✅ | ❌ | ✅ | ❌ | ✅ | ✅ ×5 | ❌ |
| ESP32 (classic) | ❌ | ✅ | ❌ | ✅ | ❌ (W5500 SPI) | ✅ | ✅ |
| ESP32-C3 / C6 / H2 | ❌ | ✅ | ❌ | ✅ | ❌ | ✅ | ✅ |
W5500 SPI Ethernet works on any ESP32 via
EthernetMIDIConnection.
| Use case | Board |
|---|---|
| Best all-round (USB Host + BLE + WiFi + display) | LilyGO T-Display-S3 |
| Full USB Host + USB Device + BLE | Any ESP32-S3 DevKit |
| Ultra-low-latency wireless stage mesh | ESP32 DevKit (ESP-NOW) |
| Wired studio rack | ESP32-P4 native Ethernet or any ESP32 + W5500 |
| DIN-5 MIDI gateway | Any ESP32 + UART optocoupler |
Arduino IDE: Sketch → Include Library → Manage Libraries → search ESP32_Host_MIDI
PlatformIO:
[env:esp32-s3-devkitc-1]
platform = espressif32
board = esp32-s3-devkitc-1
framework = arduino
lib_deps =
sauloverissimo/ESP32_Host_MIDI
# lathoub/Arduino-AppleMIDI-Library ; RTP-MIDI + Ethernet MIDI
# arduino-libraries/Ethernet ; Ethernet MIDI
# CNMAT/OSC ; OSC
# sauloverissimo/gingoduino ; Chord namesBoard package: Tools > Boards Manager → "esp32" by Espressif → ≥ 3.0.0
USB Host and USB Device require arduino-esp32 ≥ 3.0 (TinyUSB MIDI).
| Transport | Required library |
|---|---|
| RTP-MIDI / Ethernet MIDI | lathoub/Arduino-AppleMIDI-Library |
| Ethernet MIDI | arduino-libraries/Ethernet |
| OSC | CNMAT/OSC |
| Chord names | sauloverissimo/gingoduino |
| USB Host / Device / BLE / ESP-NOW | Built into arduino-esp32 |
// Setup
midiHandler.begin(); // start built-in transports (USB, BLE, ESP-NOW)
midiHandler.begin(cfg); // with custom config
midiHandler.addTransport(&t); // register external transport
// Receive
const auto& q = midiHandler.getQueue(); // event ring buffer
std::vector<std::string> n = midiHandler.getActiveNotesVector(); // ["C4","E4","G4"]
std::string chord = midiHandler.getChordName(); // "Cmaj7"
// Send (broadcasts to ALL transports simultaneously)
midiHandler.sendNoteOn(ch, note, vel);
midiHandler.sendNoteOff(ch, note, vel);
midiHandler.sendControlChange(ch, ctrl, val);
midiHandler.sendProgramChange(ch, prog);
midiHandler.sendPitchBend(ch, val); // 0–16383, center = 8192MIDIHandlerConfig:
MIDIHandlerConfig cfg;
cfg.maxEvents = 20; // queue capacity
cfg.enableHistory = true; // keep full history
cfg.chordDetection = true; // group simultaneous notesCustom transport interface:
class MyTransport : public MIDITransport {
public:
void task() override;
bool isConnected() const override;
bool sendMidiMessage(const uint8_t* data, size_t len) override;
protected:
void dispatchMidiData(const uint8_t* data, size_t len); // inject received MIDI
void dispatchConnected();
void dispatchDisconnected();
};
midiHandler.addTransport(&myTransport);ESP32_Host_MIDI/
├── src/
│ ├── ESP32_Host_MIDI.h ← main include (USB + BLE + ESP-NOW built-in)
│ ├── MIDIHandler.h / .cpp ← event queue, chord detection, active notes
│ ├── MIDITransport.h ← abstract transport interface
│ ├── MIDIHandlerConfig.h ← config struct
│ ├── USBConnection.h / .cpp ← USB Host OTG
│ ├── BLEConnection.h / .cpp ← BLE MIDI
│ ├── ESPNowConnection.h / .cpp ← ESP-NOW MIDI
│ ├── UARTConnection.h / .cpp ← UART / DIN-5
│ ├── USBDeviceConnection.h ← USB MIDI Device (header-only)
│ ├── RTPMIDIConnection.h / .cpp ← RTP-MIDI over WiFi (header-only)
│ ├── EthernetMIDIConnection.h ← AppleMIDI over Ethernet (header-only)
│ ├── OSCConnection.h ← OSC ↔ MIDI bridge (header-only)
│ └── GingoAdapter.h ← Gingoduino chord integration
└── examples/
├── T-Display-S3/ T-Display-S3-Queue/
├── T-Display-S3-Piano/ T-Display-S3-Piano-Debug/
├── T-Display-S3-Gingoduino/ T-Display-S3-BLE-Sender/
├── T-Display-S3-BLE-Receiver/ T-Display-S3-ESP-NOW-Jam/
├── T-Display-S3-OSC/ T-Display-S3-USB-Device/
├── ESP-NOW-MIDI/ UART-MIDI-Basic/
├── P4-Dual-UART-MIDI/ RTP-MIDI-WiFi/
├── Ethernet-MIDI/ OSC-MIDI-WiFi/
└── USB-Device-MIDI/
MIT — see LICENSE
Built with ❤️ for musicians, makers, and researchers.
Issues and contributions welcome:
github.com/sauloverissimo/ESP32_Host_MIDI







