Building a USB MIDI 2.0 Device – Part 3
This is the third part in this series on how developers go about building a USB MIDI 2.0 Device. Please read Part 1 and Part 2 before reading Part 3.
In Part 2 we looked at handling Function Blocks and Group Terminal Blocks, UMP Discovery.
In this third guide we will cover:
- Using a USB Descriptor Builder to avoid mistakes
- Interfaces and Interface Association Descriptors in USB
- Why having separate MIDI 1.0 mode may be useful
- OS Caching and Firmware updates that affect your USB Descriptors
Using a USB Descriptor Builder to avoid mistakes
Creating correct USB Descriptors can be difficult to get right. Issues can occur such as
- Incorrect lengths of descriptors
- Difficulties when creating USB Endpoint with multi MIDI 1.0 Ports
- Confusion between USB Endpoint In/Out to Embedded Out/IN to External In/Out Descriptors
- IAD creation
To make this much easier, members of the MIDI Association and MIDI2.dev have created a MIDI USB Descriptor Builder. It allows you to create the Descriptors needed to create a MIDI 1.0/2.0 USB Device. Although the Descriptor Builder is catered to output descriptor for use with tinyUSB tusb_ump driver (https://github.com/midi2-dev/tusb_ump) or the Linux Gadget interface, the generated code should be easily adaptable to other USB stack implementations.
The USB Descriptor Builder is located at https://midi2-dev.github.io/usbMIDI2DescriptorBuilder/
The GitHub repository is located here.
Parts 1 and 2 of this article include several examples of descriptors. Those examples are based on the default settings of the Descriptor Builder. The USB Descriptor sets many parameters and properties used by the device. It is also recommended that you consider the association of these parameters in relation to other UMP features, selecting values that are consistently formatted. In developing your USB device, be sure to reference the Property Names and Mapping article (https://midi.org/midi-2-0-device-design-property-names-and-mapping).
Interfaces and Interface Association Descriptors (IAD)
If a device supports both USB MIDI and USB Audio, the device should be configured as a Composite device with Audio Interfaces separated from MIDI Interfaces. This mechanism is particularly useful in devices which combine Audio Class version 2, 3, or 4 with a MIDI Class function. This is because the MIDI Class Function, defined as a subclass of Audio Class, has an Audio Control Interface.
An IAD is used to show the relationship between the Audio Interfaces, particularly to associate an Audio Control Interface with an Audio Streaming Interface(s).
A separate IAD is used to show the relationship between the Interfaces for the MIDI Function. This IAD associates a 2nd Audio Control Interface with a MIDI Streaming Interface.
USB Hosts may use the IADs to better determine which drivers will be used to support the device.
Two Alternate Settings: To Enable Backward Compatibility
The USB Device Class Definition for MIDI Devices, Version 2.0 defines how the use of 2 Alternate Settings on the Class Specific MIDI Streaming Interface provides the widest compatibility of Devices and Hosts.
Using this mechanism, a Device can operate as a MIDI 1.0 Device when necessary, but can switch to operating as a MIDI 2.0 Device on any Host which can support MIDI 2.0.
Alternate Setting 0 of the MIDI Streaming Interface is compliant with USB Device Class Specification for MIDI Devices Version 1.0.
Alternate Setting 1 of the MIDI Streaming Interface has descriptors for the MIDI 2.0 function.
The bcdMSC field in Alternate Setting 0 is set to 0x0100. (MIDI 1.0)
The bcdMSC field in Alternate Setting 1 is set to 0x0200. (MIDI 2.0)
USB MIDI Hosts which do not support USB MIDI 2.0 use the descriptors found on Alternate Setting 0 and install the Device as a MIDI 1.0 Device.
USB MIDI Hosts capable of supporting a USB MIDI 2.0 Device instead start by looking for an Alternate Setting 1 with bcdMSC set to 0x0200. If such an Alternate Setting is found in the device, the Host installs the Device as a MIDI 2.0 Device using those descriptors. If the Host does not find the Alternate Setting 1, then the Host will use the descriptors found on Alternate Setting 0 and install the Device as a MIDI 1.0 Device.
Why having separate MIDI 1.0 USB Only mode may be useful in some cases at this time
This may be done to be more compatible with and avoid unexpected behavior when used with some early beta versions of Host USB MIDI 2.0 drivers in 2023 and 2024.
Initial USB MIDI 2.0 Devices, such as the Native Instruments Komplete Kontrol MK3 and the Roland A-88 MK2, store 2 sets of USB Descriptors :
- Legacy MIDI 1.0 only
- USB MIDI 2.0 (with alt 0 = MIDI 1.0, alt 1 = MIDI 2.0)
The user decides which to enable on the device. On the A-88MK2 this is a button combination on start up, on the Kontrol it is a menu option (which causes a reboot).
It is expected that with a short timeframe this will not be a concern and this suggestion will change. Ultimately, all Devices should simply have a single mode of operation which has an Alternate Setting 0 for MIDI 1.0 and an Alternate Setting 1 for MIDI 2.0.
OS Caching and Firmware updates that affect your USB Descriptors
When Devices connect to a Host, an OS may cache the USB Descriptors. For example CoreMIDI uses caching to build a database of MIDI Devices and to handle reconnects.
A Host might not be able to recognize when a device makes these kinds of changes::
- USB Descriptors including string name changes
- Group Terminal Block updates
- Switching between a USB MIDI 1.0 only mode and USB MIDI 2.0 mode
If the Host OS does not recognize that a change has occurred, the user may experience errors and unknown behaviors.
One method to avoid errors, the user needs to clear the cache and remove the prior device entry. However, this is not always possible and explaining the steps to users can be a challenge. This can be confusing and may still result in further technical support issues.
If the device can change the iSerial string value or the PID every time these notable configuration changes occur, then the OS will see a new device with a new set of features.
The End…
This set of articles would not have been possible without the input and support of the MIDI Association OSAPI Working Group members who provided much of the content.
Writing this series has helped me to clarify and organize my own understanding of USB MIDI. The MIDI Association intends to continue publishing these kinds of articles to support developers.
Thank you to everyone else who provided information, asked probing questions, and read this series.