Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

ALSA: docs: Add MIDI 2.0 documentation

Add the brief document for describing the MIDI 2.0 implementation on
Linux kernel. Both rawmidi and sequencer API extensions are
described.

Acked-by: Jaroslav Kysela <perex@perex.cz>
Link: https://lore.kernel.org/r/20230523075358.9672-38-tiwai@suse.de
Signed-off-by: Takashi Iwai <tiwai@suse.de>

+352
+1
Documentation/sound/designs/index.rst
··· 15 15 oss-emulation 16 16 seq-oss 17 17 jack-injection 18 + midi-2.0
+351
Documentation/sound/designs/midi-2.0.rst
··· 1 + ================= 2 + MIDI 2.0 on Linux 3 + ================= 4 + 5 + General 6 + ======= 7 + 8 + MIDI 2.0 is an extended protocol for providing higher resolutions and 9 + more fine controls over the legacy MIDI 1.0. The fundamental changes 10 + introduced for supporting MIDI 2.0 are: 11 + 12 + - Support of Universal MIDI Packet (UMP) 13 + - Support of MIDI 2.0 protocol messages 14 + - Transparent conversions between UMP and legacy MIDI 1.0 byte stream 15 + - MIDI-CI for property and profile configurations 16 + 17 + UMP is a new container format to hold all MIDI protocol 1.0 and MIDI 18 + 2.0 protocol messages. Unlike the former byte stream, it's 32bit 19 + aligned, and each message can be put in a single packet. UMP can send 20 + the events up to 16 "UMP Groups", where each UMP Group contain up to 21 + 16 MIDI channels. 22 + 23 + MIDI 2.0 protocol is an extended protocol to achieve the higher 24 + resolution and more controls over the old MIDI 1.0 protocol. 25 + 26 + MIDI-CI is a high-level protocol that can talk with the MIDI device 27 + for the flexible profiles and configurations. It's represented in the 28 + form of special SysEx. 29 + 30 + For Linux implementations, the kernel supports the UMP transport and 31 + the encoding/decoding of MIDI protocols on UMP, while MIDI-CI is 32 + supported in user-space over the standard SysEx. 33 + 34 + As of this writing, only USB MIDI device supports the UMP and Linux 35 + 2.0 natively. The UMP support itself is pretty generic, hence it 36 + could be used by other transport layers, although it could be 37 + implemented differently (e.g. as a ALSA sequencer client), too. 38 + 39 + The access to UMP devices are provided in two ways: the access via 40 + rawmidi device and the access via ALSA sequencer API. 41 + 42 + ALSA sequencer API was extended to allow the payload of UMP packets. 43 + It's allowed to connect freely between MIDI 1.0 and MIDI 2.0 sequencer 44 + clients, and the events are converted transparently. 45 + 46 + 47 + Kernel Configuration 48 + ==================== 49 + 50 + The following new configs are added for supporting MIDI 2.0: 51 + `CONFIG_SND_UMP`, `CONFIG_SND_UMP_LEGACY_RAWMIDI`, 52 + `CONFIG_SND_SEQ_UMP`, `CONFIG_SND_SEQ_UMP_CLIENT`, and 53 + `CONFIG_SND_USB_AUDIO_MIDI_V2`. The first visible one is 54 + `CONFIG_SND_USB_AUDIO_MIDI_V2`, and when you choose it (to set `=y`), 55 + the core support for UMP (`CONFIG_SND_UMP`) and the sequencer binding 56 + (`CONFIG_SND_SEQ_UMP_CLIENT`) will be automatically selected. 57 + 58 + Additionally, `CONFIG_SND_UMP_LEGACY_RAWMIDI=y` will enable the 59 + support for the legacy raw MIDI device for UMP Endpoints. 60 + 61 + 62 + Rawmidi Device with USB MIDI 2.0 63 + ================================ 64 + 65 + When a device supports MIDI 2.0, the USB-audio driver probes and uses 66 + the MIDI 2.0 interface (that is found always at the altset 1) as 67 + default instead of the MIDI 1.0 interface (at altset 0). You can 68 + switch back to the binding with the old MIDI 1.0 interface by passing 69 + `midi2_enable=0` option to snd-usb-audio driver module, too. 70 + 71 + When the MIDI 2.0 device is probed, the kernel creates a rawmidi 72 + device for each UMP Endpoint of the device. Its device name is 73 + `/dev/snd/umpC*D*` and different from the standard rawmidi device name 74 + `/dev/snd/midiC*D*` for MIDI 1.0, in order to avoid confusing the 75 + legacy applications accessing mistakenly to UMP devices. 76 + 77 + You can read and write UMP packet data directly from/to this UMP 78 + rawmidi device. For example, reading via `hexdump` like below will 79 + show the incoming UMP packets of the card 0 device 0 in the hex 80 + format:: 81 + 82 + % hexdump -C /dev/snd/umpC0D0 83 + 00000000 01 07 b0 20 00 07 b0 20 64 3c 90 20 64 3c 80 20 |... ... d<. d<. | 84 + 85 + Unlike the MIDI 1.0 byte stream, UMP is a 32bit packet, and the size 86 + for reading or writing the device is also aligned to 32bit (which is 4 87 + bytes). 88 + 89 + The 32-bit words in the UMP packet payload are always in CPU native 90 + endianness. Transport drivers are responsible to convert UMP words 91 + from / to system endianness to required transport endianness / byte 92 + order. 93 + 94 + When `CONFIG_SND_UMP_LEGACY_RAWMIDI` is set, the driver creates 95 + another standard raw MIDI device additionally as `/dev/snd/midiC*D*`. 96 + This contains 16 substreams, and each substream corresponds to a 97 + (0-based) UMP Group. Legacy applications can access to the specified 98 + group via each substream in MIDI 1.0 byte stream format. With the 99 + ALSA rawmidi API, you can open the arbitrary substream, while just 100 + opening `/dev/snd/midiC*D*` will end up with opening the first 101 + substream. 102 + 103 + Each UMP Endpoint can provide the additional information, constructed 104 + from USB MIDI 2.0 descriptors. And a UMP Endpoint may contain one or 105 + more UMP Blocks, where UMP Block is an abstraction introduced in the 106 + ALSA UMP implementations to represent the associations among UMP 107 + Groups. UMP Block corresponds to Group Terminal Block (GTB) in USB 108 + MIDI 2.0 specifications but provide a few more generic information. 109 + The information of UMP Endpoints and UMP Blocks are found in the proc 110 + file `/proc/asound/card*/midi*`. For example:: 111 + 112 + % cat /proc/asound/card1/midi0 113 + ProtoZOA MIDI 114 + 115 + Type: UMP 116 + EP Name: ProtoZOA 117 + EP Product ID: ABCD12345678 118 + UMP Version: 0x0000 119 + Protocol Caps: 0x00000100 120 + Protocol: 0x00000100 121 + Num Blocks: 3 122 + 123 + Block 0 (ProtoZOA Main) 124 + Direction: bidirection 125 + Active: Yes 126 + Groups: 1-1 127 + Is MIDI1: No 128 + 129 + Block 1 (ProtoZOA Ext IN) 130 + Direction: output 131 + Active: Yes 132 + Groups: 2-2 133 + Is MIDI1: Yes (Low Speed) 134 + .... 135 + 136 + Note that `Groups` field shown in the proc file above indicates the 137 + 1-based UMP Group numbers (from-to). 138 + 139 + Those additional UMP Endpoint and UMP Block information can be 140 + obtained via the new ioctls `SNDRV_UMP_IOCTL_ENDPOINT_INFO` and 141 + `SNDRV_UMP_IOCTL_BLOCK_INFO`, respectively. 142 + 143 + The rawmidi name and the UMP Endpoint name are usually identical, and 144 + in the case of USB MIDI, it's taken from `iInterface` of the 145 + corresponding USB MIDI interface descriptor. If it's not provided, 146 + it's copied from `iProduct` of the USB device descriptor as a 147 + fallback. 148 + 149 + The Endpoint Product ID is a string field and supposed to be unique. 150 + It's copied from `iSerialNumber` of the device for USB MIDI. 151 + 152 + The protocol capabilities and the actual protocol bits are defined in 153 + `asound.h`. 154 + 155 + 156 + ALSA Sequencer with USB MIDI 2.0 157 + ================================ 158 + 159 + In addition to the rawmidi interfaces, ALSA sequencer interface 160 + supports the new UMP MIDI 2.0 device, too. Now, each ALSA sequencer 161 + client may set its MIDI version (0, 1 or 2) to declare itself being 162 + either the legacy, UMP MIDI 1.0 or UMP MIDI 2.0 device, respectively. 163 + The first, legacy client is the one that sends/receives the old 164 + sequencer event as was. Meanwhile, UMP MIDI 1.0 and 2.0 clients send 165 + and receive in the extended event record for UMP. The MIDI version is 166 + seen in the new `midi_version` field of `snd_seq_client_info`. 167 + 168 + A UMP packet can be sent/received in a sequencer event embedded by 169 + specifying the new event flag bit `SNDRV_SEQ_EVENT_UMP`. When this 170 + flag is set, the event has 16 byte (128 bit) data payload for holding 171 + the UMP packet. Without the `SNDRV_SEQ_EVENT_UMP` bit flag, the event 172 + is treated as a legacy event as it was (with max 12 byte data 173 + payload). 174 + 175 + With `SNDRV_SEQ_EVENT_UMP` flag set, the type field of a UMP sequencer 176 + event is ignored (but it should be set to 0 as default). 177 + 178 + The type of each client can be seen in `/proc/asound/seq/clients`. 179 + For example:: 180 + 181 + % cat /proc/asound/seq/clients 182 + Client info 183 + cur clients : 3 184 + .... 185 + Client 14 : "Midi Through" [Kernel Legacy] 186 + Port 0 : "Midi Through Port-0" (RWe-) 187 + Client 20 : "ProtoZOA" [Kernel UMP MIDI1] 188 + UMP Endpoint: ProtoZOA 189 + UMP Block 0: ProtoZOA Main [Active] 190 + Groups: 1-1 191 + UMP Block 1: ProtoZOA Ext IN [Active] 192 + Groups: 2-2 193 + UMP Block 2: ProtoZOA Ext OUT [Active] 194 + Groups: 3-3 195 + Port 0 : "MIDI 2.0" (RWeX) [In/Out] 196 + Port 1 : "ProtoZOA Main" (RWeX) [In/Out] 197 + Port 2 : "ProtoZOA Ext IN" (-We-) [Out] 198 + Port 3 : "ProtoZOA Ext OUT" (R-e-) [In] 199 + 200 + Here you can find two types of kernel clients, "Legacy" for client 14, 201 + and "UMP MIDI1" for client 20, which is a USB MIDI 2.0 device. 202 + A USB MIDI 2.0 client gives always the port 0 as "MIDI 2.0" and the 203 + rest ports from 1 for each UMP Group (e.g. port 1 for Group 1). 204 + In this example, the device has three active groups (Main, Ext IN and 205 + Ext OUT), and those are exposed as sequencer ports from 1 to 3. 206 + The "MIDI 2.0" port is for a UMP Endpoint, and its difference from 207 + other UMP Group ports is that UMP Endpoint port sends the events from 208 + the all ports on the device ("catch-all"), while each UMP Group port 209 + sends only the events from the given UMP Group. 210 + 211 + Note that, although each UMP sequencer client usually creates 16 212 + ports, those ports that don't belong to any UMP Blocks (or belonging 213 + to inactive UMP Blocks) are marked as inactive, and they don't appear 214 + in the proc outputs. In the example above, the sequencer ports from 4 215 + to 16 are present but not shown there. 216 + 217 + The proc file above shows the UMP Block information, too. The same 218 + entry (but with more detailed information) is found in the rawmidi 219 + proc output. 220 + 221 + When clients are connected between different MIDI versions, the events 222 + are translated automatically depending on the client's version, not 223 + only between the legacy and the UMP MIDI 1.0/2.0 types, but also 224 + between UMP MIDI 1.0 and 2.0 types, too. For example, running 225 + `aseqdump` program on the ProtoZOA Main port in the legacy mode will 226 + give you the output like:: 227 + 228 + % aseqdump -p 20:1 229 + Waiting for data. Press Ctrl+C to end. 230 + Source Event Ch Data 231 + 20:1 Note on 0, note 60, velocity 100 232 + 20:1 Note off 0, note 60, velocity 100 233 + 20:1 Control change 0, controller 11, value 4 234 + 235 + When you run `aseqdump` in MIDI 2.0 mode, it'll receive the high 236 + precision data like:: 237 + 238 + % aseqdump -u 2 -p 20:1 239 + Waiting for data. Press Ctrl+C to end. 240 + Source Event Ch Data 241 + 20:1 Note on 0, note 60, velocity 0xc924, attr type = 0, data = 0x0 242 + 20:1 Note off 0, note 60, velocity 0xc924, attr type = 0, data = 0x0 243 + 20:1 Control change 0, controller 11, value 0x2000000 244 + 245 + while the data is automatically converted by ALSA sequencer core. 246 + 247 + 248 + Rawmidi API Extensions 249 + ====================== 250 + 251 + * The additional UMP Endpoint information can be obtained via the new 252 + ioctl `SNDRV_UMP_IOCTL_ENDPOINT_INFO`. It contains the associated 253 + card and device numbers, the bit flags, the protocols, the number of 254 + UMP Blocks, the name string of the endpoint, etc. 255 + 256 + The protocols are specified in two field, the protocol capabilities 257 + and the current protocol. Both contain the bit flags specifying the 258 + MIDI protocol version (`SNDRV_UMP_EP_INFO_PROTO_MIDI1` or 259 + `SNDRV_UMP_EP_INFO_PROTO_MIDI2`) in the upper byte and the jitter 260 + reduction timestamp (`SNDRV_UMP_EP_INFO_PROTO_JRTS_TX` and 261 + `SNDRV_UMP_EP_INFO_PROTO_JRTS_RX`) in the lower byte. 262 + 263 + A UMP Endpoint may contain up to 32 UMP Blocks, and the number of 264 + the currently assigned blocks are shown in the Endpoint information. 265 + 266 + * Each UMP Block information can be obtained via another new ioctl 267 + `SNDRV_UMP_IOCTL_BLOCK_INFO`. The block ID number (0-based) has to 268 + be passed for the block to query. The received data contains the 269 + associated the direction of the block, the first associated group ID 270 + (0-based) and the number of groups, the name string of the block, 271 + etc. 272 + 273 + The direction is either `SNDRV_UMP_DIR_INPUT`, 274 + `SNDRV_UMP_DIR_OUTPUT` or `SNDRV_UMP_DIR_BIDIRECTION`. 275 + 276 + 277 + Control API Extensions 278 + ====================== 279 + 280 + * The new ioctl `SNDRV_CTL_IOCTL_UMP_NEXT_DEVICE` is introduced for 281 + querying the next UMP rawmidi device, while the existing ioctl 282 + `SNDRV_CTL_IOCTL_RAWMIDI_NEXT_DEVICE` queries only the legacy 283 + rawmidi devices. 284 + 285 + For setting the subdevice (substream number) to be opened, use the 286 + ioctl `SNDRV_CTL_IOCTL_RAWMIDI_PREFER_SUBDEVICE` like the normal 287 + rawmidi. 288 + 289 + * Two new ioctls `SNDRV_CTL_IOCTL_UMP_ENDPOINT_INFO` and 290 + `SNDRV_CTL_IOCTL_UMP_BLOCK_INFO` provide the UMP Endpoint and UMP 291 + Block information of the specified UMP device via ALSA control API 292 + without opening the actual (UMP) rawmidi device. 293 + The `card` field is ignored upon inquiry, always tied with the card 294 + of the control interface. 295 + 296 + 297 + Sequencer API Extensions 298 + ======================== 299 + 300 + * `midi_version` field is added to `snd_seq_client_info` to indicate 301 + the current MIDI version (either 0, 1 or 2) of each client. 302 + When `midi_version` is 1 or 2, the alignment of read from a UMP 303 + sequencer client is also changed from the former 28 bytes to 32 304 + bytes for the extended payload. The alignment size for the write 305 + isn't changed, but each event size may differ depending on the new 306 + bit flag below. 307 + 308 + * `SNDRV_SEQ_EVENT_UMP` flag bit is added for each sequencer event 309 + flags. When this bit flag is set, the sequencer event is extended 310 + to have a larger payload of 16 bytes instead of the legacy 12 311 + bytes, and the event contains the UMP packet in the payload. 312 + 313 + * The new sequencer port type bit (`SNDRV_SEQ_PORT_TYPE_MIDI_UMP`) 314 + indicates the port being UMP-capable. 315 + 316 + * The sequencer ports have new capability bits to indicate the 317 + inactive ports (`SNDRV_SEQ_PORT_CAP_INACTIVE`) and the UMP Endpoint 318 + port (`SNDRV_SEQ_PORT_CAP_UMP_ENDPOINT`). 319 + 320 + * The event conversion of ALSA sequencer clients can be suppressed the 321 + new filter bit `SNDRV_SEQ_FILTER_NO_CONVERT` set to the client info. 322 + For example, the kernel pass-through client (`snd-seq-dummy`) sets 323 + this flag internally. 324 + 325 + * The port information gained the new field `direction` to indicate 326 + the direction of the port (either `SNDRV_SEQ_PORT_DIR_INPUT`, 327 + `SNDRV_SEQ_PORT_DIR_OUTPUT` or `SNDRV_SEQ_PORT_DIR_BIDIRECTION`). 328 + 329 + * Another additional field for the port information is `ump_group` 330 + which specifies the associated UMP Group Number (1-based). 331 + When it's non-zero, the UMP group field in the UMP packet updated 332 + upon delivery to the specified group (corrected to be 0-based). 333 + Each sequencer port is supposed to set this field if it's a port to 334 + specific to a certain UMP group. 335 + 336 + * Each client may set the additional event filter for UMP Groups in 337 + `group_filter` bitmap. The filter consists of bitmap from 1-based 338 + Group numbers. For example, when the bit 1 is set, messages from 339 + Group 1 (i.e. the very first group) are filtered and not delivered. 340 + The bit 0 is reserved for future use. 341 + 342 + * Two new ioctls are added for UMP-capable clients: 343 + `SNDRV_SEQ_IOCTL_GET_CLIENT_UMP_INFO` and 344 + `SNDRV_SEQ_IOCTL_SET_CLIENT_UMP_INFO`. They are used to get and set 345 + either `snd_ump_endpoint_info` or `snd_ump_block_info` data 346 + associated with the sequencer client. The USB MIDI driver provides 347 + those information from the underlying UMP rawmidi, while a 348 + user-space client may provide its own data via `*_SET` ioctl. 349 + For an Endpoint data, pass 0 to the `type` field, while for a Block 350 + data, pass the block number + 1 to the `type` field. 351 + Setting the data for a kernel client shall result in an error.