Midi 2.0

As of January 2026, Microsoft has started rolling out Windows MIDI Services which includes multi-client MIDI ports, lower latency / jitter and MIDI 2.0 support. I don't really care for MIDI 2.0 support to satisfy my needs, but I'm certain my customers are going to be asking for it.
 
I just hope that MIDI 1.0 will continue to be supported. I have lots of hardware using good old midi that just work. Also I have my own projects that I use good old MIDI and 127 different values per potentiometer is more than enough (can't move the knob more precisely). Zipper noise is not an issue as I have adaptive exponential parameter smoothing in software in 32 bit float so changes are both perfectly smooth (way beyond 16K promised by MIDI2) and quick and absolutely zero zipper noise. This is also the technique that hardware VA synths use (like Access Music Virus TI).
 
I just hope that MIDI 1.0 will continue to be supported. I have lots of hardware using good old midi that just work. Also I have my own projects that I use good old MIDI and 127 different values per potentiometer is more than enough (can't move the knob more precisely). Zipper noise is not an issue as I have adaptive exponential parameter smoothing in software in 32 bit float so changes are both perfectly smooth (way beyond 16K promised by MIDI2) and quick and absolutely zero zipper noise. This is also the technique that hardware VA synths use (like Access Music Virus TI).
Can you share what you mean by "zipper noise"?
 
Zipper noise occurs when you change a parameter of sound synthesis path such as oscillator freq, amp, filter cutoff, delay time, etc, in a "stepped" way.
Analog signals are smooth, so when you turn say frequency knob in analog circuit the frequency sweeps in smooth way.
When you control digital oscillator using MIDI parameter (such as CC message) it has 127 discrete "steps" and changes occur in stepped way that creates audible ("zipper") noise, UNLESS you perform parameter smoothing that interpolates single-step big change into thousands of perfectly smooth, per-sample microscopic changes (something like smooth "bezier curve" between points). Then you have noise-free parameter change, even if your CC resolution is 7 bit MIDI 1.0.
 
Last edited:
Zipper noise occurs when you change a parameter of sound synthesis path such as oscillator freq, amp, filter cutoff, delay time, etc, in a "stepped" way.
Analog signals are smooth, so when you turn say frequency knob in analog circuit the frequency sweeps in smooth way.
When you control digital oscillator using MIDI parameter (such as CC message) it has 127 discrete "steps" and changes occur in stepped way that creates audible ("zipper") noise, UNLESS you perform parameter smoothing that interpolates single-step big change into thousands of perfectly smooth, per-sample microscopic changes (something like smooth "bezier curve" between points). Then you have noise-free parameter change, even if your CC resolution is 7 bit MIDI 1.0.
Beautiful explanation, thank you!
 
I just hope that MIDI 1.0 will continue to be supported. I have lots of hardware using good old midi that just work. Also I have my own projects that I use good old MIDI and 127 different values per potentiometer is more than enough (can't move the knob more precisely). Zipper noise is not an issue as I have adaptive exponential parameter smoothing in software in 32 bit float so changes are both perfectly smooth (way beyond 16K promised by MIDI2) and quick and absolutely zero zipper noise. This is also the technique that hardware VA synths use (like Access Music Virus TI).
To be fair, the only times I can recall personally having this issue was with older outboard gear (e.g. my JP-8000), and obviously those can't get fixed by MIDI2.0. I don't know how much current equipment and software do interpolation. Most? All? Not sure. While it's a really smart fix for an old limitation, it's not great separation of concerns. Maybe I'm just being pedantic.

That aside. I am having a lot of fun with my Teensy4.1s. I eventually realized it's a lot more enjoyable to build what I want now rather than sitting around waiting for everyone from Microsoft to firmware developers to wrap up all their hard work first. I have a pretty ambitious project (for me anyway) that I'm almost done with the hardware for. If I learned anything it's that the Teensy4.1 is a beast with a ton of attention to detail. Super impressed.

I can always update the SW side later. MIDI2.0 will def. be backwards compatible. Knobs are knobs, and I can future proof my analog interfaces with higher bit ADCs.
 
I just hope that MIDI 1.0 will continue to be supported. I have lots of hardware using good old midi that just work. Also I have my own projects that I use good old MIDI and 127 different values per potentiometer is more than enough (can't move the knob more precisely). Zipper noise is not an issue as I have adaptive exponential parameter smoothing in software in 32 bit float so changes are both perfectly smooth (way beyond 16K promised by MIDI2) and quick and absolutely zero zipper noise. This is also the technique that hardware VA synths use (like Access Music Virus TI).

What kind of MIDI 1.0 support are you worried about? My understanding is that MIDI 2.0 is backwards compatible.
 
I mean that I hope that Teensy 4.x USB MIDI (when Teensy libs are upgraded to MIDI2.0) will continue to work with MIDI 1.0 drivers and devices, so we can continue using old devices and "old" OS (I don't know what plans does Microsoft have for MIDI 2, but chances are that they won't release new drivers for Windows 10 just because they want to push W11).
 
MIDI Capability Inquiry (MIDI-CI) exists exactly for that purpose. A MIDI 2.0 implementation does not just assume MIDI 2.0 support in the devices it talks to: it sends a capability inquiry to find out exactly what features are supported. A MIDI 1.0 implementation will not respond to this query, so the fallback is to use MIDI 1.0.

 
Any proper implementation of MIDI2.0 has to be able to fall back to MIDI1.0, otherwise it's not in spec. It'd be a nightmare otherwise. I don't think you can even patch a piece of gear that totally relies on DIN MIDI connectors to handle MIDI2.0 data, not at real-time levels of latency anyway. The MIDI1.0 spec for DIN connectors required optoisolators, like the 6N138, and set the bandwidth at 31.25Kbs, meaning the HW is already kneecapped to not support RT data rates for MIDI2.0's 32 bit UMP packets. IOW, dropping MIDI1.0 support is not an option.

Theres already drivers available that implement this. I would expect those to be capitalized on in whatever is implemented by PJRC. Since other MCUs like the RP2040 have already been shown using these drivers and running MIDI2.0 (with MIDI1.0 fallback), I imagine it won't be a hurdle for the better spec'd Teensy4.1 to handle this expertly.
 
Hello @PaulStoffregen and community,

I've been working on a MIDI 2.0 architecture across several
platforms, Teensy included via experimental 'cores' overrides,
and while looking for discussions about it here on the forum
I came back to this thread after five years.

Back in February 2020 (posts #23 and #25) you listed three
preconditions before starting work on MIDI 2.0 for Teensy. All
three are now met:

1. OS driver: Linux kernel 6.5 (snd-usb-midi2, Aug/2023),
CoreMIDI 2.0 on macOS, Windows MIDI Services in GA preview.
2. Test software: amidi2, MIDI Workbench, Windows MIDI Console,
AmenoteUMP toolkit.
3. Moderately priced commercial product: Roland A-88MKII
firmware 2.0 (Nov/2023) and Korg Keystage, both native
USB MIDI 2.0 devices.

Over the past few months I worked on the USB MIDI 2.0
implementation and validation in TinyUSB. It's upstream now
(PR #3571, merged). I built device, host and bridge examples
on a few platforms: RP2040, RP2350, ESP32, STM32, NXP and
Daisy Seed. That said, the Teensy 4.1 has always been one of
my favorites. A little over two months ago I started working
on it as well.

I sketched out a descriptor starting point for cores following
your style, no dependencies (613 LOC, no app logic, Alt
Setting 1 + GTB + raw UMP read/write, 60k UMP stress test with
zero loss):

fork on github -> sauloverissimo/cores/tree/feature/usb-midi2-descriptors

This isn't a merge request, it's a way to reopen the MIDI 2.0
conversation. The landscape is different now: Microsoft, with
Pete Brown leading Windows MIDI Services, has been putting
serious effort into the protocol, DAWs are catching up, and it
feels like this could be the moment in the embedded world. I
have several questions to ask you, but that's for another post.

Thanks,
 
Last edited:
This looks really interesting, and is relevant to my current interests :)

I see that so far you’ve done some (all?) of the tricky low level stuff, but there don’t appear to be any simple examples of e.g. a keyboard or control surface sketch so one can add a couple of switches or pots to a Teensy and get a feel for how it’d all work. Or send it events that get parsed and printed to Serial.

I may be alone in this, but I’m always much more inclined to try stuff out if I can hack together a few parts I already own and have a play with simple but known-working examples. I’m sure the Roland and Korg products are great, but they’re still not exactly impulse buys…
 
This looks really interesting, and is relevant to my current interests :)

I see that so far you’ve done some (all?) of the tricky low level stuff, but there don’t appear to be any simple examples of e.g. a keyboard or control surface sketch so one can add a couple of switches or pots to a Teensy and get a feel for how it’d all work. Or send it events that get parsed and printed to Serial.

I may be alone in this, but I’m always much more inclined to try stuff out if I can hack together a few parts I already own and have a play with simple but known-working examples. I’m sure the Roland and Korg products are great, but they’re still not exactly impulse buys…
Hi @h4yn0nnym0u5e , thanks for reading the post carefully.

You pinpointed exactly what I chose not to bring into this
conversation yet: the application layer. The initial post covered
only USB descriptors and raw UMP I/O because I wanted to first
understand how Paul and the community see that low-level piece.
The application layer (UMP parsing, MIDI-CI, Property Exchange,
Discovery, 14/16/32-bit controllers) still involves an
architectural decision that isn't mine to make, it's Paul's:

- vendored inside cores (zero external dependency)?
- external Arduino lib dependency (cores just calls into it)?
- Paul writes it from scratch, no dependency at all?

The three have tradeoffs and it feels natural to hear how Paul
prefers to work before proposing anything to cores at that layer.
MIDI 2.0's semantics are broader than MIDI 1.0's (Discovery,
Profiles, Property Exchange come into play alongside the
messages), so the decision of where that lives in the stack
carries more weight.

About Teensy examples: I ran a proof of concept of the application
layer in a lib of mine called midi2cpp (sauloverissimo/midi2cpp on
github). It has a Teensy 4.1 sketch (teensy41-midi2.ino) that
shows the full path: UMP Stream identity (Endpoint Discovery,
Function Block), MIDI-CI with Discovery + Profile + 2 Properties,
and a demo loop that fires the MIDI 2.0 repertoire: NoteOn with
32-bit velocity, 32-bit CC, Per-Note Pitch Bend, Per-Note
Controllers, Flex Data (Tempo + Time Signature). It's the
skeleton. Right now I'm working on an adaptation with pot and
switch reading, to close exactly the use case you described.
Today it runs on top of the cores fork as experimental overrides;
if the conversation with Paul lands on a different path, it
adapts. But I built it driven by the desire to see Teensy
operating in MIDI 2.0, more as an experiment than anything.

I agree 100% with you about the products. I cited Roland A-88MKII
and Korg Keystage only because Paul set that premise back in 2020.
They check the box, but you're right: real hobbyist work calls for
something more accessible.

---

Edit: Follow-up: the adaptation I mentioned is up.

teensy41-control-surface in midi2cpp covers exactly what you
described: 4 pots on A0..A3 sending 32-bit CC (CC1 Modulation,
CC74 Brightness, CC71 Resonance, CC91 Reverb Send), 4 switches
on D2..D5 sending NoteOn/Off (C4..D#4), and any UMP received from
the host decoded line by line to Serial at 115200: NoteOn/Off,
CC, PitchBend, ChannelPressure, Program, Per-Note PitchBend,
Flex Data Set Tempo + Set Time Signature.

~175 LOC sketch, MIDI-CI left out to keep it simple. EMA smoothing
+ deadband on pots, millis debounce on switches, 12-bit ADC
expanded to 32-bit by replicating the MSB so the full range
reaches MIDI 2.0 receivers. Hardware-validated on Teensy 4.1
today against Linux ALSA (/dev/snd/umpC*D0).

Repo: github -> sauloverissimo/midi2cpp, examples/teensy41-control-surface.
README has pin map, wiring, build command, and what each block
does.

🤓
 

Attachments

  • monitor.png
    monitor.png
    427.7 KB · Views: 23
  • properties.png
    properties.png
    84.7 KB · Views: 22
  • banner.png
    banner.png
    28.3 KB · Views: 19
  • stack.jpg
    stack.jpg
    277.9 KB · Views: 18
Last edited:
Just trying the control surface example, and it doesn't compile:
Code:
Arduino: 1.8.19 (Windows 10), TD: 1.59, Board: "Teensy 4.1, Serial, 600 MHz, Faster, US English, 44.1kHz, 128 samples (normal), 2, Off"
C:\Program Files (x86)\Arduino\arduino-builder -dump-prefs -logger=machine -hardware C:\Program Files (x86)\Arduino\hardware -tools C:\Program Files (x86)\Arduino\tools-builder -tools C:\Program Files (x86)\Arduino\hardware\tools\avr -built-in-libraries C:\Program Files (x86)\Arduino\libraries -libraries D:\Jonathan\Teensy\libraries -fqbn=teensy:avr:teensy41:usb=serial,speed=600,opt=o2std,keys=en-us,audiorate=44,audioblocksize=normal,USBchannelcount=2,gdb=off -ide-version=10819 -build-path C:\Users\Admin\AppData\Local\Temp\arduino_build_870774 -warnings=none -build-cache C:\Users\Admin\AppData\Local\Temp\arduino_cache_476675 -verbose D:\Jonathan\Teensy\libraries\midi2cpp\examples\teensy41-control-surface\teensy41-control-surface.ino
C:\Program Files (x86)\Arduino\arduino-builder -compile -logger=machine -hardware C:\Program Files (x86)\Arduino\hardware -tools C:\Program Files (x86)\Arduino\tools-builder -tools C:\Program Files (x86)\Arduino\hardware\tools\avr -built-in-libraries C:\Program Files (x86)\Arduino\libraries -libraries D:\Jonathan\Teensy\libraries -fqbn=teensy:avr:teensy41:usb=serial,speed=600,opt=o2std,keys=en-us,audiorate=44,audioblocksize=normal,USBchannelcount=2,gdb=off -ide-version=10819 -build-path C:\Users\Admin\AppData\Local\Temp\arduino_build_870774 -warnings=none -build-cache C:\Users\Admin\AppData\Local\Temp\arduino_cache_476675 -verbose D:\Jonathan\Teensy\libraries\midi2cpp\examples\teensy41-control-surface\teensy41-control-surface.ino
Using board 'teensy41' from platform in folder: C:\Program Files (x86)\Arduino\hardware\teensy\avr
Using core 'teensy4' from platform in folder: C:\Program Files (x86)\Arduino\hardware\teensy\avr
Detecting libraries used...
"C:\\Program Files (x86)\\Arduino\\hardware\\teensy/../tools/arm/bin/arm-none-eabi-g++" -E -CC -x c++ -w -g -Wall -ffunction-sections -fdata-sections -nostdlib -std=gnu++17 -fno-exceptions -fpermissive -fno-rtti -fno-threadsafe-statics -felide-constructors -Wno-error=narrowing -mthumb -mcpu=cortex-m7 -mfloat-abi=hard -mfpu=fpv5-d16 -D__IMXRT1062__ -DTEENSYDUINO=159 -DARDUINO=10819 -DARDUINO_TEENSY41 -DF_CPU=600000000 -DUSB_SERIAL -DLAYOUT_US_ENGLISH "-IC:\\Program Files (x86)\\Arduino\\hardware\\teensy\\avr\\cores\\teensy4" "C:\\Users\\Admin\\AppData\\Local\\Temp\\arduino_build_870774\\sketch\\teensy41-control-surface.ino.cpp" -o nul
Alternatives for midi2cpp.h: [midi2cpp@0.4.1]
ResolveLibrary(midi2cpp.h)
  -> candidates: [midi2cpp@0.4.1]
"C:\\Program Files (x86)\\Arduino\\hardware\\teensy/../tools/arm/bin/arm-none-eabi-g++" -E -CC -x c++ -w -g -Wall -ffunction-sections -fdata-sections -nostdlib -std=gnu++17 -fno-exceptions -fpermissive -fno-rtti -fno-threadsafe-statics -felide-constructors -Wno-error=narrowing -mthumb -mcpu=cortex-m7 -mfloat-abi=hard -mfpu=fpv5-d16 -D__IMXRT1062__ -DTEENSYDUINO=159 -DARDUINO=10819 -DARDUINO_TEENSY41 -DF_CPU=600000000 -DUSB_SERIAL -DLAYOUT_US_ENGLISH "-IC:\\Program Files (x86)\\Arduino\\hardware\\teensy\\avr\\cores\\teensy4" "-ID:\\Jonathan\\Teensy\\libraries\\midi2cpp\\src" "C:\\Users\\Admin\\AppData\\Local\\Temp\\arduino_build_870774\\sketch\\teensy41-control-surface.ino.cpp" -o nul
Alternatives for midi2.h: []
ResolveLibrary(midi2.h)In file included from D:\Jonathan\Teensy\libraries\midi2cpp\examples\teensy41-control-surface\src\teensy41_control_surface.h:24,
  -> candidates: []
                 from D:\Jonathan\Teensy\libraries\midi2cpp\examples\teensy41-control-surface\teensy41-control-surface.ino:22:
D:\Jonathan\Teensy\libraries\midi2cpp\src/midi2cpp.h:27:10: fatal error: midi2.h: No such file or directory
   27 | #include "midi2.h"
      |          ^~~~~~~~~
compilation terminated.
Using library midi2cpp at version 0.4.1 in folder: D:\Jonathan\Teensy\libraries\midi2cpp
Error compiling for board Teensy 4.1.

Loving the level of documentation you've put into this, by the way! I can't pretend I've read it all yet, though...
 
OK, found it - there's a second library it's dependent on, which you didn't mention in the example header comment. Compiles ... now to test ...
Thanks for catching that. Fixed.
The README mentions Teensyduino 1.60+ as the
minimum, and you're on 1.59. Switch USB Type to MIDI2 in Tools before upload.
Let me know how it goes.
 
Last edited:
Very brief testing done, all seems to be working as advertised! I only tested the CCs, but given they're good I can see no reason why buttons / notes won't work too.

I know it looks as if I'm using Teensyduino 1.59, but actually it's just a horrible mash-up of various versions including PRs that haven't even made it to a beta, let alone a release...
Switch USB Type to MIDI2 in Tools before upload.
Yes ... I had to add those menu entries to my boards.local.txt so they appeared in the Tools menu ... is that in a ReadMe somewhere? Again, I have that pretty heavily modified already, so I can test the multi-channel USB, so that was straightforward for me to do - maybe not so much for others? My changes are:
Code:
## USB
# Extra menu entries for custom USB devices

teensy41.menu.usb.midi2=MIDI 2.0
teensy41.menu.usb.midi2.build.usbtype=USB_MIDI2
teensy41.menu.usb.midi2.upload_port.usbtype=USB_MIDI2
teensy41.menu.usb.midi2.fake_serial=teensy_gateway
teensy41.menu.usb.midi2serial=Serial + MIDI 2.0
teensy41.menu.usb.midi2serial.build.usbtype=USB_MIDI2_SERIAL
teensy41.menu.usb.midi2serial.upload_port.usbtype=USB_MIDI2_SERIAL
teensy41.menu.usb.midi2x4=MIDI 2.0 x 4
teensy41.menu.usb.midi2x4.build.usbtype=USB_MIDI2_4
teensy41.menu.usb.midi2x4.upload_port.usbtype=USB_MIDI2_4
teensy41.menu.usb.midi2x4.fake_serial=teensy_gateway
teensy41.menu.usb.midi2x16=MIDI 2.0 x 16
teensy41.menu.usb.midi2x16.build.usbtype=USB_MIDI2_16
teensy41.menu.usb.midi2x16.upload_port.usbtype=USB_MIDI2_16
teensy41.menu.usb.midi2x16.fake_serial=teensy_gateway

teensy40.menu.usb.midi2=MIDI 2.0
teensy40.menu.usb.midi2.build.usbtype=USB_MIDI2
teensy40.menu.usb.midi2.upload_port.usbtype=USB_MIDI2
teensy40.menu.usb.midi2.fake_serial=teensy_gateway
teensy40.menu.usb.midi2serial=Serial + MIDI 2.0
teensy40.menu.usb.midi2serial.build.usbtype=USB_MIDI2_SERIAL
teensy40.menu.usb.midi2serial.upload_port.usbtype=USB_MIDI2_SERIAL
teensy40.menu.usb.midi2x4=MIDI 2.0 x 4
teensy40.menu.usb.midi2x4.build.usbtype=USB_MIDI2_4
teensy40.menu.usb.midi2x4.upload_port.usbtype=USB_MIDI2_4
teensy40.menu.usb.midi2x4.fake_serial=teensy_gateway
teensy40.menu.usb.midi2x16=MIDI 2.0 x 16
teensy40.menu.usb.midi2x16.build.usbtype=USB_MIDI2_16
teensy40.menu.usb.midi2x16.upload_port.usbtype=USB_MIDI2_16
teensy40.menu.usb.midi2x16.fake_serial=teensy_gateway

teensyMM.menu.usb.midi2=MIDI 2.0
teensyMM.menu.usb.midi2.build.usbtype=USB_MIDI2
teensyMM.menu.usb.midi2.upload_port.usbtype=USB_MIDI2
teensyMM.menu.usb.midi2.fake_serial=teensy_gateway
teensyMM.menu.usb.midi2serial=Serial + MIDI 2.0
teensyMM.menu.usb.midi2serial.build.usbtype=USB_MIDI2_SERIAL
teensyMM.menu.usb.midi2serial.upload_port.usbtype=USB_MIDI2_SERIAL
teensyMM.menu.usb.midi2x4=MIDI 2.0 x 4
teensyMM.menu.usb.midi2x4.build.usbtype=USB_MIDI2_4
teensyMM.menu.usb.midi2x4.upload_port.usbtype=USB_MIDI2_4
teensyMM.menu.usb.midi2x4.fake_serial=teensy_gateway
teensyMM.menu.usb.midi2x16=MIDI 2.0 x 16
teensyMM.menu.usb.midi2x16.build.usbtype=USB_MIDI2_16
teensyMM.menu.usb.midi2x16.upload_port.usbtype=USB_MIDI2_16
teensyMM.menu.usb.midi2x16.fake_serial=teensy_gateway
I only tested the Serial + MIDI 2.0 option on a Teensy 4.0, so there could be errors for other combinations, though I have a Python builder for the config files which should reduce the likelihood.
 
Glad it works, h4yn0nnym0u5e, and thanks for the snippet.

Right. The 'cores' fork doesn't carry the midi2 menu entries
for Tools > USB Type (they live one level up, in the Teensyduino
boards.txt). I added boards.local.txt with your snippet to both
recipes and documented the install path in both READMEs. I made
the adjustments you suggested.

About incorporating those entries into the official Teensyduino
boards.txt, I'd rather wait for Paul to see, review and weigh in
before proposing any upstream PR, same approach as the
application layer. The drop-in covers it for now so we can test
here.


🌟
 
For what it’s worth, I think the structure you have looks about right. Very minimal changes to cores, which should make maintenance easier, then libraries on top which can be forked if needed, and will survive Teensyduino updates.

I wasn’t sure about the need to install two libraries, but it’s probably better to keep the proven structure you have, and Adafruit do much the same with their peripheral and display support.
 
Thanks for reading, @h4yn0nnym0u5e. To be clear: what I put
together isn't a "do it this way" proposal, it's a way to make
it work now without an invasive fork and without locking down
an architecture decision that isn't mine to make.

The transport (USB descriptors + raw UMP I/O) has to live in
cores either way, and that's all I touched. The application
layer (UMP parsing, MIDI-CI, Property Exchange) is what stays
open. In MIDI 1.0 everything fit inside cores; MIDI 2.0 is much
larger, so where that layer lives becomes a real choice, with a
few possible shapes:

- everything inside cores, written from scratch (as in MIDI 1.0);
- the midi2 C99 lib vendored inside cores, exposed as a C API
(usb_midi style);
- same lib vendored, with a C++ wrapper on top (usbMIDI style);
- transport inside cores, application as an external lib (what
I did).

About the two libs: midi2cpp is just the thin C++ wrapper over
midi2, the C99 core. The two can collapse into a single lib, or
be vendored entirely. The Adafruit parallel is spot on: keeping
the application layer out of cores is exactly what lets it
survive updates, as you pointed out.

If you spot any adjustment to the transport I touched
(descriptors or the raw UMP I/O), feel free to point it out. I
brought this here to genuinely build it together, with the
community and with people who know cores. Good to see we're
already making progress.

The good thing is we can experiment before locking the decision:
run it, watch the behavior, adjust, and only then pick the best
way to implement.
 
@h4yn0nnym0u5e,

Quick update: midi2cpp v0.6.0 is out, with the midi2 C99
core bundled in. The Arduino install is down to a single
library now, no transitive dependency.

Both teensy41-midi2 and teensy41-control-surface recipes
are already updated. The cores fork, descriptors and
boards.local.txt stay the same.

Closes the earlier question about installing two libraries.
If anyone wants to try it on Teensy 4.0 or MicroMod, the
boards.local.txt already covers all three.

👍
 
Hello, my friends.

Following up on the USB device descriptor work from the past few
weeks, here is the host side: USB MIDI 2.0 on the Teensy 4.1 host
port.

Same spirit as the cores fork: minimal changes, transport only.
The USBHost_t36 fork (+110 LOC, branch feature/midi2-host-base on
my github) walks the descriptors in claim(), selects Alternate
Setting 1 via SET_INTERFACE when the device exposes UMP, and adds
readUMP() / writeUMP() / umpMode() to MIDIDeviceBase. MIDIDevice
and MIDIDevice_BigBuffer inherit it with no source changes, and
MIDI 1.0 devices keep working through the usual path (alt 0).

There is a ready-to-run example in midi2cpp: teensy41-host-midi2.
Plug a MIDI 2.0 device into the host port, the sketch discovers
its identity (Endpoint Name via UMP Stream + MIDI-CI Discovery)
and prints every decoded message to Serial. The sketch also has a
stress mode: the same zero-loss methodology we used to validate
the TinyUSB, midi2cpp and ESP32_Host_MIDI. Result on the
Teensy 4.1: 144,693 UMPs received over 9 min 43 s, one full
16-bit sequence wrap-around, zero loss.

The cores fork also got a spec conformance refinement this week
(Group Terminal Block default protocol + SET_INTERFACE bounds).

If anyone wants to test it with their MIDI 2.0 gear, or review
the descriptor walk, feedback is very welcome.

@h4yn0nnym0u5e
@PaulStoffregen
 

Attachments

  • teensy_midi2_host.jpg
    teensy_midi2_host.jpg
    187.7 KB · Views: 0
Back
Top