162306a36Sopenharmony_ci=================
262306a36Sopenharmony_ciMIDI 2.0 on Linux
362306a36Sopenharmony_ci=================
462306a36Sopenharmony_ci
562306a36Sopenharmony_ciGeneral
662306a36Sopenharmony_ci=======
762306a36Sopenharmony_ci
862306a36Sopenharmony_ciMIDI 2.0 is an extended protocol for providing higher resolutions and
962306a36Sopenharmony_cimore fine controls over the legacy MIDI 1.0.  The fundamental changes
1062306a36Sopenharmony_ciintroduced for supporting MIDI 2.0 are:
1162306a36Sopenharmony_ci
1262306a36Sopenharmony_ci- Support of Universal MIDI Packet (UMP)
1362306a36Sopenharmony_ci- Support of MIDI 2.0 protocol messages
1462306a36Sopenharmony_ci- Transparent conversions between UMP and legacy MIDI 1.0 byte stream
1562306a36Sopenharmony_ci- MIDI-CI for property and profile configurations
1662306a36Sopenharmony_ci
1762306a36Sopenharmony_ciUMP is a new container format to hold all MIDI protocol 1.0 and MIDI
1862306a36Sopenharmony_ci2.0 protocol messages.  Unlike the former byte stream, it's 32bit
1962306a36Sopenharmony_cialigned, and each message can be put in a single packet.  UMP can send
2062306a36Sopenharmony_cithe events up to 16 "UMP Groups", where each UMP Group contain up to
2162306a36Sopenharmony_ci16 MIDI channels.
2262306a36Sopenharmony_ci
2362306a36Sopenharmony_ciMIDI 2.0 protocol is an extended protocol to achieve the higher
2462306a36Sopenharmony_ciresolution and more controls over the old MIDI 1.0 protocol.
2562306a36Sopenharmony_ci
2662306a36Sopenharmony_ciMIDI-CI is a high-level protocol that can talk with the MIDI device
2762306a36Sopenharmony_cifor the flexible profiles and configurations.  It's represented in the
2862306a36Sopenharmony_ciform of special SysEx.
2962306a36Sopenharmony_ci
3062306a36Sopenharmony_ciFor Linux implementations, the kernel supports the UMP transport and
3162306a36Sopenharmony_cithe encoding/decoding of MIDI protocols on UMP, while MIDI-CI is
3262306a36Sopenharmony_cisupported in user-space over the standard SysEx.
3362306a36Sopenharmony_ci
3462306a36Sopenharmony_ciAs of this writing, only USB MIDI device supports the UMP and Linux
3562306a36Sopenharmony_ci2.0 natively.  The UMP support itself is pretty generic, hence it
3662306a36Sopenharmony_cicould be used by other transport layers, although it could be
3762306a36Sopenharmony_ciimplemented differently (e.g. as a ALSA sequencer client), too.
3862306a36Sopenharmony_ci
3962306a36Sopenharmony_ciThe access to UMP devices are provided in two ways: the access via
4062306a36Sopenharmony_cirawmidi device and the access via ALSA sequencer API.
4162306a36Sopenharmony_ci
4262306a36Sopenharmony_ciALSA sequencer API was extended to allow the payload of UMP packets.
4362306a36Sopenharmony_ciIt's allowed to connect freely between MIDI 1.0 and MIDI 2.0 sequencer
4462306a36Sopenharmony_ciclients, and the events are converted transparently.
4562306a36Sopenharmony_ci
4662306a36Sopenharmony_ci
4762306a36Sopenharmony_ciKernel Configuration
4862306a36Sopenharmony_ci====================
4962306a36Sopenharmony_ci
5062306a36Sopenharmony_ciThe following new configs are added for supporting MIDI 2.0:
5162306a36Sopenharmony_ci`CONFIG_SND_UMP`, `CONFIG_SND_UMP_LEGACY_RAWMIDI`,
5262306a36Sopenharmony_ci`CONFIG_SND_SEQ_UMP`, `CONFIG_SND_SEQ_UMP_CLIENT`, and
5362306a36Sopenharmony_ci`CONFIG_SND_USB_AUDIO_MIDI_V2`.  The first visible one is
5462306a36Sopenharmony_ci`CONFIG_SND_USB_AUDIO_MIDI_V2`, and when you choose it (to set `=y`),
5562306a36Sopenharmony_cithe core support for UMP (`CONFIG_SND_UMP`) and the sequencer binding
5662306a36Sopenharmony_ci(`CONFIG_SND_SEQ_UMP_CLIENT`) will be automatically selected.
5762306a36Sopenharmony_ci
5862306a36Sopenharmony_ciAdditionally, `CONFIG_SND_UMP_LEGACY_RAWMIDI=y` will enable the
5962306a36Sopenharmony_cisupport for the legacy raw MIDI device for UMP Endpoints.
6062306a36Sopenharmony_ci
6162306a36Sopenharmony_ci
6262306a36Sopenharmony_ciRawmidi Device with USB MIDI 2.0
6362306a36Sopenharmony_ci================================
6462306a36Sopenharmony_ci
6562306a36Sopenharmony_ciWhen a device supports MIDI 2.0, the USB-audio driver probes and uses
6662306a36Sopenharmony_cithe MIDI 2.0 interface (that is found always at the altset 1) as
6762306a36Sopenharmony_cidefault instead of the MIDI 1.0 interface (at altset 0).  You can
6862306a36Sopenharmony_ciswitch back to the binding with the old MIDI 1.0 interface by passing
6962306a36Sopenharmony_ci`midi2_enable=0` option to snd-usb-audio driver module, too.
7062306a36Sopenharmony_ci
7162306a36Sopenharmony_ciThe USB audio driver tries to query the UMP Endpoint and UMP Function
7262306a36Sopenharmony_ciBlock information that are provided since UMP v1.1, and builds up the
7362306a36Sopenharmony_citopology based on those information.  When the device is older and
7462306a36Sopenharmony_cidoesn't respond to the new UMP inquiries, the driver falls back and
7562306a36Sopenharmony_cibuilds the topology based on Group Terminal Block (GTB) information
7662306a36Sopenharmony_cifrom the USB descriptor.  Some device might be screwed up by the
7762306a36Sopenharmony_ciunexpected UMP command; in such a case, pass `midi2_ump_probe=0`
7862306a36Sopenharmony_cioption to snd-usb-audio driver for skipping the UMP v1.1 inquiries.
7962306a36Sopenharmony_ci
8062306a36Sopenharmony_ciWhen the MIDI 2.0 device is probed, the kernel creates a rawmidi
8162306a36Sopenharmony_cidevice for each UMP Endpoint of the device.  Its device name is
8262306a36Sopenharmony_ci`/dev/snd/umpC*D*` and different from the standard rawmidi device name
8362306a36Sopenharmony_ci`/dev/snd/midiC*D*` for MIDI 1.0, in order to avoid confusing the
8462306a36Sopenharmony_cilegacy applications accessing mistakenly to UMP devices.
8562306a36Sopenharmony_ci
8662306a36Sopenharmony_ciYou can read and write UMP packet data directly from/to this UMP
8762306a36Sopenharmony_cirawmidi device.  For example, reading via `hexdump` like below will
8862306a36Sopenharmony_cishow the incoming UMP packets of the card 0 device 0 in the hex
8962306a36Sopenharmony_ciformat::
9062306a36Sopenharmony_ci
9162306a36Sopenharmony_ci  % hexdump -C /dev/snd/umpC0D0
9262306a36Sopenharmony_ci  00000000  01 07 b0 20 00 07 b0 20  64 3c 90 20 64 3c 80 20  |... ... d<. d<. |
9362306a36Sopenharmony_ci
9462306a36Sopenharmony_ciUnlike the MIDI 1.0 byte stream, UMP is a 32bit packet, and the size
9562306a36Sopenharmony_cifor reading or writing the device is also aligned to 32bit (which is 4
9662306a36Sopenharmony_cibytes).
9762306a36Sopenharmony_ci
9862306a36Sopenharmony_ciThe 32-bit words in the UMP packet payload are always in CPU native
9962306a36Sopenharmony_ciendianness.  Transport drivers are responsible to convert UMP words
10062306a36Sopenharmony_cifrom / to system endianness to required transport endianness / byte
10162306a36Sopenharmony_ciorder.
10262306a36Sopenharmony_ci
10362306a36Sopenharmony_ciWhen `CONFIG_SND_UMP_LEGACY_RAWMIDI` is set, the driver creates
10462306a36Sopenharmony_cianother standard raw MIDI device additionally as `/dev/snd/midiC*D*`.
10562306a36Sopenharmony_ciThis contains 16 substreams, and each substream corresponds to a
10662306a36Sopenharmony_ci(0-based) UMP Group.  Legacy applications can access to the specified
10762306a36Sopenharmony_cigroup via each substream in MIDI 1.0 byte stream format.  With the
10862306a36Sopenharmony_ciALSA rawmidi API, you can open the arbitrary substream, while just
10962306a36Sopenharmony_ciopening `/dev/snd/midiC*D*` will end up with opening the first
11062306a36Sopenharmony_cisubstream.
11162306a36Sopenharmony_ci
11262306a36Sopenharmony_ciEach UMP Endpoint can provide the additional information, constructed
11362306a36Sopenharmony_cifrom the information inquired via UMP 1.1 Stream messages or USB MIDI
11462306a36Sopenharmony_ci2.0 descriptors.  And a UMP Endpoint may contain one or more UMP
11562306a36Sopenharmony_ciBlocks, where UMP Block is an abstraction introduced in the ALSA UMP
11662306a36Sopenharmony_ciimplementations to represent the associations among UMP Groups.  UMP
11762306a36Sopenharmony_ciBlock corresponds to Function Block in UMP 1.1 specification.  When
11862306a36Sopenharmony_ciUMP 1.1 Function Block information isn't available, it's filled
11962306a36Sopenharmony_cipartially from Group Terminal Block (GTB) as defined in USB MIDI 2.0
12062306a36Sopenharmony_cispecifications.
12162306a36Sopenharmony_ci
12262306a36Sopenharmony_ciThe information of UMP Endpoints and UMP Blocks are found in the proc
12362306a36Sopenharmony_cifile `/proc/asound/card*/midi*`.  For example::
12462306a36Sopenharmony_ci
12562306a36Sopenharmony_ci  % cat /proc/asound/card1/midi0
12662306a36Sopenharmony_ci  ProtoZOA MIDI
12762306a36Sopenharmony_ci  
12862306a36Sopenharmony_ci  Type: UMP
12962306a36Sopenharmony_ci  EP Name: ProtoZOA
13062306a36Sopenharmony_ci  EP Product ID: ABCD12345678
13162306a36Sopenharmony_ci  UMP Version: 0x0000
13262306a36Sopenharmony_ci  Protocol Caps: 0x00000100
13362306a36Sopenharmony_ci  Protocol: 0x00000100
13462306a36Sopenharmony_ci  Num Blocks: 3
13562306a36Sopenharmony_ci  
13662306a36Sopenharmony_ci  Block 0 (ProtoZOA Main)
13762306a36Sopenharmony_ci    Direction: bidirection
13862306a36Sopenharmony_ci    Active: Yes
13962306a36Sopenharmony_ci    Groups: 1-1
14062306a36Sopenharmony_ci    Is MIDI1: No
14162306a36Sopenharmony_ci
14262306a36Sopenharmony_ci  Block 1 (ProtoZOA Ext IN)
14362306a36Sopenharmony_ci    Direction: output
14462306a36Sopenharmony_ci    Active: Yes
14562306a36Sopenharmony_ci    Groups: 2-2
14662306a36Sopenharmony_ci    Is MIDI1: Yes (Low Speed)
14762306a36Sopenharmony_ci  ....
14862306a36Sopenharmony_ci
14962306a36Sopenharmony_ciNote that `Groups` field shown in the proc file above indicates the
15062306a36Sopenharmony_ci1-based UMP Group numbers (from-to).
15162306a36Sopenharmony_ci
15262306a36Sopenharmony_ciThose additional UMP Endpoint and UMP Block information can be
15362306a36Sopenharmony_ciobtained via the new ioctls `SNDRV_UMP_IOCTL_ENDPOINT_INFO` and
15462306a36Sopenharmony_ci`SNDRV_UMP_IOCTL_BLOCK_INFO`, respectively.
15562306a36Sopenharmony_ci
15662306a36Sopenharmony_ciThe rawmidi name and the UMP Endpoint name are usually identical, and
15762306a36Sopenharmony_ciin the case of USB MIDI, it's taken from `iInterface` of the
15862306a36Sopenharmony_cicorresponding USB MIDI interface descriptor.  If it's not provided,
15962306a36Sopenharmony_ciit's copied from `iProduct` of the USB device descriptor as a
16062306a36Sopenharmony_cifallback.
16162306a36Sopenharmony_ci
16262306a36Sopenharmony_ciThe Endpoint Product ID is a string field and supposed to be unique.
16362306a36Sopenharmony_ciIt's copied from `iSerialNumber` of the device for USB MIDI.
16462306a36Sopenharmony_ci
16562306a36Sopenharmony_ciThe protocol capabilities and the actual protocol bits are defined in
16662306a36Sopenharmony_ci`asound.h`.
16762306a36Sopenharmony_ci
16862306a36Sopenharmony_ci
16962306a36Sopenharmony_ciALSA Sequencer with USB MIDI 2.0
17062306a36Sopenharmony_ci================================
17162306a36Sopenharmony_ci
17262306a36Sopenharmony_ciIn addition to the rawmidi interfaces, ALSA sequencer interface
17362306a36Sopenharmony_cisupports the new UMP MIDI 2.0 device, too.  Now, each ALSA sequencer
17462306a36Sopenharmony_ciclient may set its MIDI version (0, 1 or 2) to declare itself being
17562306a36Sopenharmony_cieither the legacy, UMP MIDI 1.0 or UMP MIDI 2.0 device, respectively.
17662306a36Sopenharmony_ciThe first, legacy client is the one that sends/receives the old
17762306a36Sopenharmony_cisequencer event as was.  Meanwhile, UMP MIDI 1.0 and 2.0 clients send
17862306a36Sopenharmony_ciand receive in the extended event record for UMP.  The MIDI version is
17962306a36Sopenharmony_ciseen in the new `midi_version` field of `snd_seq_client_info`.
18062306a36Sopenharmony_ci
18162306a36Sopenharmony_ciA UMP packet can be sent/received in a sequencer event embedded by
18262306a36Sopenharmony_cispecifying the new event flag bit `SNDRV_SEQ_EVENT_UMP`.  When this
18362306a36Sopenharmony_ciflag is set, the event has 16 byte (128 bit) data payload for holding
18462306a36Sopenharmony_cithe UMP packet.  Without the `SNDRV_SEQ_EVENT_UMP` bit flag, the event
18562306a36Sopenharmony_ciis treated as a legacy event as it was (with max 12 byte data
18662306a36Sopenharmony_cipayload).
18762306a36Sopenharmony_ci
18862306a36Sopenharmony_ciWith `SNDRV_SEQ_EVENT_UMP` flag set, the type field of a UMP sequencer
18962306a36Sopenharmony_cievent is ignored (but it should be set to 0 as default).
19062306a36Sopenharmony_ci
19162306a36Sopenharmony_ciThe type of each client can be seen in `/proc/asound/seq/clients`.
19262306a36Sopenharmony_ciFor example::
19362306a36Sopenharmony_ci
19462306a36Sopenharmony_ci  % cat /proc/asound/seq/clients
19562306a36Sopenharmony_ci  Client info
19662306a36Sopenharmony_ci    cur  clients : 3
19762306a36Sopenharmony_ci  ....
19862306a36Sopenharmony_ci  Client  14 : "Midi Through" [Kernel Legacy]
19962306a36Sopenharmony_ci    Port   0 : "Midi Through Port-0" (RWe-)
20062306a36Sopenharmony_ci  Client  20 : "ProtoZOA" [Kernel UMP MIDI1]
20162306a36Sopenharmony_ci    UMP Endpoint: ProtoZOA
20262306a36Sopenharmony_ci    UMP Block 0: ProtoZOA Main [Active]
20362306a36Sopenharmony_ci      Groups: 1-1
20462306a36Sopenharmony_ci    UMP Block 1: ProtoZOA Ext IN [Active]
20562306a36Sopenharmony_ci      Groups: 2-2
20662306a36Sopenharmony_ci    UMP Block 2: ProtoZOA Ext OUT [Active]
20762306a36Sopenharmony_ci      Groups: 3-3
20862306a36Sopenharmony_ci    Port   0 : "MIDI 2.0" (RWeX) [In/Out]
20962306a36Sopenharmony_ci    Port   1 : "ProtoZOA Main" (RWeX) [In/Out]
21062306a36Sopenharmony_ci    Port   2 : "ProtoZOA Ext IN" (-We-) [Out]
21162306a36Sopenharmony_ci    Port   3 : "ProtoZOA Ext OUT" (R-e-) [In]
21262306a36Sopenharmony_ci
21362306a36Sopenharmony_ciHere you can find two types of kernel clients, "Legacy" for client 14,
21462306a36Sopenharmony_ciand "UMP MIDI1" for client 20, which is a USB MIDI 2.0 device.
21562306a36Sopenharmony_ciA USB MIDI 2.0 client gives always the port 0 as "MIDI 2.0" and the
21662306a36Sopenharmony_cirest ports from 1 for each UMP Group (e.g. port 1 for Group 1).
21762306a36Sopenharmony_ciIn this example, the device has three active groups (Main, Ext IN and
21862306a36Sopenharmony_ciExt OUT), and those are exposed as sequencer ports from 1 to 3.
21962306a36Sopenharmony_ciThe "MIDI 2.0" port is for a UMP Endpoint, and its difference from
22062306a36Sopenharmony_ciother UMP Group ports is that UMP Endpoint port sends the events from
22162306a36Sopenharmony_cithe all ports on the device ("catch-all"), while each UMP Group port
22262306a36Sopenharmony_cisends only the events from the given UMP Group.
22362306a36Sopenharmony_ciAlso, UMP groupless messages (such as the UMP message type 0x0f) are
22462306a36Sopenharmony_cisent only to the UMP Endpoint port.
22562306a36Sopenharmony_ci
22662306a36Sopenharmony_ciNote that, although each UMP sequencer client usually creates 16
22762306a36Sopenharmony_ciports, those ports that don't belong to any UMP Blocks (or belonging
22862306a36Sopenharmony_cito inactive UMP Blocks) are marked as inactive, and they don't appear
22962306a36Sopenharmony_ciin the proc outputs.  In the example above, the sequencer ports from 4
23062306a36Sopenharmony_cito 16 are present but not shown there.
23162306a36Sopenharmony_ci
23262306a36Sopenharmony_ciThe proc file above shows the UMP Block information, too.  The same
23362306a36Sopenharmony_cientry (but with more detailed information) is found in the rawmidi
23462306a36Sopenharmony_ciproc output.
23562306a36Sopenharmony_ci
23662306a36Sopenharmony_ciWhen clients are connected between different MIDI versions, the events
23762306a36Sopenharmony_ciare translated automatically depending on the client's version, not
23862306a36Sopenharmony_cionly between the legacy and the UMP MIDI 1.0/2.0 types, but also
23962306a36Sopenharmony_cibetween UMP MIDI 1.0 and 2.0 types, too.  For example, running
24062306a36Sopenharmony_ci`aseqdump` program on the ProtoZOA Main port in the legacy mode will
24162306a36Sopenharmony_cigive you the output like::
24262306a36Sopenharmony_ci
24362306a36Sopenharmony_ci  % aseqdump -p 20:1
24462306a36Sopenharmony_ci  Waiting for data. Press Ctrl+C to end.
24562306a36Sopenharmony_ci  Source  Event                  Ch  Data
24662306a36Sopenharmony_ci   20:1   Note on                 0, note 60, velocity 100
24762306a36Sopenharmony_ci   20:1   Note off                0, note 60, velocity 100
24862306a36Sopenharmony_ci   20:1   Control change          0, controller 11, value 4
24962306a36Sopenharmony_ci
25062306a36Sopenharmony_ciWhen you run `aseqdump` in MIDI 2.0 mode, it'll receive the high
25162306a36Sopenharmony_ciprecision data like::
25262306a36Sopenharmony_ci
25362306a36Sopenharmony_ci  % aseqdump -u 2 -p 20:1
25462306a36Sopenharmony_ci  Waiting for data. Press Ctrl+C to end.
25562306a36Sopenharmony_ci  Source  Event                  Ch  Data
25662306a36Sopenharmony_ci   20:1   Note on                 0, note 60, velocity 0xc924, attr type = 0, data = 0x0
25762306a36Sopenharmony_ci   20:1   Note off                0, note 60, velocity 0xc924, attr type = 0, data = 0x0
25862306a36Sopenharmony_ci   20:1   Control change          0, controller 11, value 0x2000000
25962306a36Sopenharmony_ci
26062306a36Sopenharmony_ciwhile the data is automatically converted by ALSA sequencer core.
26162306a36Sopenharmony_ci
26262306a36Sopenharmony_ci
26362306a36Sopenharmony_ciRawmidi API Extensions
26462306a36Sopenharmony_ci======================
26562306a36Sopenharmony_ci
26662306a36Sopenharmony_ci* The additional UMP Endpoint information can be obtained via the new
26762306a36Sopenharmony_ci  ioctl `SNDRV_UMP_IOCTL_ENDPOINT_INFO`.  It contains the associated
26862306a36Sopenharmony_ci  card and device numbers, the bit flags, the protocols, the number of
26962306a36Sopenharmony_ci  UMP Blocks, the name string of the endpoint, etc.
27062306a36Sopenharmony_ci
27162306a36Sopenharmony_ci  The protocols are specified in two field, the protocol capabilities
27262306a36Sopenharmony_ci  and the current protocol.  Both contain the bit flags specifying the
27362306a36Sopenharmony_ci  MIDI protocol version (`SNDRV_UMP_EP_INFO_PROTO_MIDI1` or
27462306a36Sopenharmony_ci  `SNDRV_UMP_EP_INFO_PROTO_MIDI2`) in the upper byte and the jitter
27562306a36Sopenharmony_ci  reduction timestamp (`SNDRV_UMP_EP_INFO_PROTO_JRTS_TX` and
27662306a36Sopenharmony_ci  `SNDRV_UMP_EP_INFO_PROTO_JRTS_RX`) in the lower byte.
27762306a36Sopenharmony_ci
27862306a36Sopenharmony_ci  A UMP Endpoint may contain up to 32 UMP Blocks, and the number of
27962306a36Sopenharmony_ci  the currently assigned blocks are shown in the Endpoint information.
28062306a36Sopenharmony_ci
28162306a36Sopenharmony_ci* Each UMP Block information can be obtained via another new ioctl
28262306a36Sopenharmony_ci  `SNDRV_UMP_IOCTL_BLOCK_INFO`.  The block ID number (0-based) has to
28362306a36Sopenharmony_ci  be passed for the block to query.  The received data contains the
28462306a36Sopenharmony_ci  associated the direction of the block, the first associated group ID
28562306a36Sopenharmony_ci  (0-based) and the number of groups, the name string of the block,
28662306a36Sopenharmony_ci  etc.
28762306a36Sopenharmony_ci
28862306a36Sopenharmony_ci  The direction is either `SNDRV_UMP_DIR_INPUT`,
28962306a36Sopenharmony_ci  `SNDRV_UMP_DIR_OUTPUT` or `SNDRV_UMP_DIR_BIDIRECTION`.
29062306a36Sopenharmony_ci
29162306a36Sopenharmony_ci* For the device supports UMP v1.1, the UMP MIDI protocol can be
29262306a36Sopenharmony_ci  switched via "Stream Configuration Request" message (UMP type 0x0f,
29362306a36Sopenharmony_ci  status 0x05).  When UMP core receives such a message, it updates the
29462306a36Sopenharmony_ci  UMP EP info and the corresponding sequencer clients as well.
29562306a36Sopenharmony_ci
29662306a36Sopenharmony_ci
29762306a36Sopenharmony_ciControl API Extensions
29862306a36Sopenharmony_ci======================
29962306a36Sopenharmony_ci
30062306a36Sopenharmony_ci* The new ioctl `SNDRV_CTL_IOCTL_UMP_NEXT_DEVICE` is introduced for
30162306a36Sopenharmony_ci  querying the next UMP rawmidi device, while the existing ioctl
30262306a36Sopenharmony_ci  `SNDRV_CTL_IOCTL_RAWMIDI_NEXT_DEVICE` queries only the legacy
30362306a36Sopenharmony_ci  rawmidi devices.
30462306a36Sopenharmony_ci
30562306a36Sopenharmony_ci  For setting the subdevice (substream number) to be opened, use the
30662306a36Sopenharmony_ci  ioctl `SNDRV_CTL_IOCTL_RAWMIDI_PREFER_SUBDEVICE` like the normal
30762306a36Sopenharmony_ci  rawmidi.
30862306a36Sopenharmony_ci
30962306a36Sopenharmony_ci* Two new ioctls `SNDRV_CTL_IOCTL_UMP_ENDPOINT_INFO` and
31062306a36Sopenharmony_ci  `SNDRV_CTL_IOCTL_UMP_BLOCK_INFO` provide the UMP Endpoint and UMP
31162306a36Sopenharmony_ci  Block information of the specified UMP device via ALSA control API
31262306a36Sopenharmony_ci  without opening the actual (UMP) rawmidi device.
31362306a36Sopenharmony_ci  The `card` field is ignored upon inquiry, always tied with the card
31462306a36Sopenharmony_ci  of the control interface.
31562306a36Sopenharmony_ci
31662306a36Sopenharmony_ci
31762306a36Sopenharmony_ciSequencer API Extensions
31862306a36Sopenharmony_ci========================
31962306a36Sopenharmony_ci
32062306a36Sopenharmony_ci* `midi_version` field is added to `snd_seq_client_info` to indicate
32162306a36Sopenharmony_ci  the current MIDI version (either 0, 1 or 2) of each client.
32262306a36Sopenharmony_ci  When `midi_version` is 1 or 2, the alignment of read from a UMP
32362306a36Sopenharmony_ci  sequencer client is also changed from the former 28 bytes to 32
32462306a36Sopenharmony_ci  bytes for the extended payload.  The alignment size for the write
32562306a36Sopenharmony_ci  isn't changed, but each event size may differ depending on the new
32662306a36Sopenharmony_ci  bit flag below.
32762306a36Sopenharmony_ci
32862306a36Sopenharmony_ci* `SNDRV_SEQ_EVENT_UMP` flag bit is added for each sequencer event
32962306a36Sopenharmony_ci  flags.  When this bit flag is set, the sequencer event is extended
33062306a36Sopenharmony_ci  to have a larger payload of 16 bytes instead of the legacy 12
33162306a36Sopenharmony_ci  bytes, and the event contains the UMP packet in the payload.
33262306a36Sopenharmony_ci
33362306a36Sopenharmony_ci* The new sequencer port type bit (`SNDRV_SEQ_PORT_TYPE_MIDI_UMP`)
33462306a36Sopenharmony_ci  indicates the port being UMP-capable.
33562306a36Sopenharmony_ci
33662306a36Sopenharmony_ci* The sequencer ports have new capability bits to indicate the
33762306a36Sopenharmony_ci  inactive ports (`SNDRV_SEQ_PORT_CAP_INACTIVE`) and the UMP Endpoint
33862306a36Sopenharmony_ci  port (`SNDRV_SEQ_PORT_CAP_UMP_ENDPOINT`).
33962306a36Sopenharmony_ci
34062306a36Sopenharmony_ci* The event conversion of ALSA sequencer clients can be suppressed the
34162306a36Sopenharmony_ci  new filter bit `SNDRV_SEQ_FILTER_NO_CONVERT` set to the client info.
34262306a36Sopenharmony_ci  For example, the kernel pass-through client (`snd-seq-dummy`) sets
34362306a36Sopenharmony_ci  this flag internally.
34462306a36Sopenharmony_ci
34562306a36Sopenharmony_ci* The port information gained the new field `direction` to indicate
34662306a36Sopenharmony_ci  the direction of the port (either `SNDRV_SEQ_PORT_DIR_INPUT`,
34762306a36Sopenharmony_ci  `SNDRV_SEQ_PORT_DIR_OUTPUT` or `SNDRV_SEQ_PORT_DIR_BIDIRECTION`).
34862306a36Sopenharmony_ci
34962306a36Sopenharmony_ci* Another additional field for the port information is `ump_group`
35062306a36Sopenharmony_ci  which specifies the associated UMP Group Number (1-based).
35162306a36Sopenharmony_ci  When it's non-zero, the UMP group field in the UMP packet updated
35262306a36Sopenharmony_ci  upon delivery to the specified group (corrected to be 0-based).
35362306a36Sopenharmony_ci  Each sequencer port is supposed to set this field if it's a port to
35462306a36Sopenharmony_ci  specific to a certain UMP group.
35562306a36Sopenharmony_ci
35662306a36Sopenharmony_ci* Each client may set the additional event filter for UMP Groups in
35762306a36Sopenharmony_ci  `group_filter` bitmap.  The filter consists of bitmap from 1-based
35862306a36Sopenharmony_ci  Group numbers.  For example, when the bit 1 is set, messages from
35962306a36Sopenharmony_ci  Group 1 (i.e. the very first group) are filtered and not delivered.
36062306a36Sopenharmony_ci  The bit 0 is used for filtering UMP groupless messages.
36162306a36Sopenharmony_ci
36262306a36Sopenharmony_ci* Two new ioctls are added for UMP-capable clients:
36362306a36Sopenharmony_ci  `SNDRV_SEQ_IOCTL_GET_CLIENT_UMP_INFO` and
36462306a36Sopenharmony_ci  `SNDRV_SEQ_IOCTL_SET_CLIENT_UMP_INFO`.  They are used to get and set
36562306a36Sopenharmony_ci  either `snd_ump_endpoint_info` or `snd_ump_block_info` data
36662306a36Sopenharmony_ci  associated with the sequencer client.  The USB MIDI driver provides
36762306a36Sopenharmony_ci  those information from the underlying UMP rawmidi, while a
36862306a36Sopenharmony_ci  user-space client may provide its own data via `*_SET` ioctl.
36962306a36Sopenharmony_ci  For an Endpoint data, pass 0 to the `type` field, while for a Block
37062306a36Sopenharmony_ci  data, pass the block number + 1 to the `type` field.
37162306a36Sopenharmony_ci  Setting the data for a kernel client shall result in an error.
37262306a36Sopenharmony_ci
37362306a36Sopenharmony_ci* With UMP 1.1, Function Block information may be changed
37462306a36Sopenharmony_ci  dynamically.  When the update of Function Block is received from the
37562306a36Sopenharmony_ci  device, ALSA sequencer core changes the corresponding sequencer port
37662306a36Sopenharmony_ci  name and attributes accordingly, and notifies the changes via the
37762306a36Sopenharmony_ci  announcement to the ALSA sequencer system port, similarly like the
37862306a36Sopenharmony_ci  normal port change notification.
37962306a36Sopenharmony_ci
38062306a36Sopenharmony_ci
38162306a36Sopenharmony_ciMIDI2 USB Gadget Function Driver
38262306a36Sopenharmony_ci================================
38362306a36Sopenharmony_ci
38462306a36Sopenharmony_ciThe latest kernel contains the support for USB MIDI 2.0 gadget
38562306a36Sopenharmony_cifunction driver, which can be used for prototyping and debugging MIDI
38662306a36Sopenharmony_ci2.0 features.
38762306a36Sopenharmony_ci
38862306a36Sopenharmony_ci`CONFIG_USB_GADGET`, `CONFIG_USB_CONFIGFS` and
38962306a36Sopenharmony_ci`CONFIG_USB_CONFIGFS_F_MIDI2` need to be enabled for the MIDI2 gadget
39062306a36Sopenharmony_cidriver.
39162306a36Sopenharmony_ci
39262306a36Sopenharmony_ciIn addition, for using a gadget driver, you need a working UDC driver.
39362306a36Sopenharmony_ciIn the example below, we use `dummy_hcd` driver (enabled via
39462306a36Sopenharmony_ci`CONFIG_USB_DUMMY_HCD`) that is available on PC and VM for debugging
39562306a36Sopenharmony_cipurpose.  There are other UDC drivers depending on the platform, and
39662306a36Sopenharmony_cithose can be used for a real device, instead, too.
39762306a36Sopenharmony_ci
39862306a36Sopenharmony_ciAt first, on a system to run the gadget, load `libcomposite` module::
39962306a36Sopenharmony_ci
40062306a36Sopenharmony_ci  % modprobe libcomposite
40162306a36Sopenharmony_ci
40262306a36Sopenharmony_ciand you'll have `usb_gadget` subdirectory under configfs space
40362306a36Sopenharmony_ci(typically `/sys/kernel/config` on modern OS).  Then create a gadget
40462306a36Sopenharmony_ciinstance and add configurations there, for example::
40562306a36Sopenharmony_ci
40662306a36Sopenharmony_ci  % cd /sys/kernel/config
40762306a36Sopenharmony_ci  % mkdir usb_gadget/g1
40862306a36Sopenharmony_ci
40962306a36Sopenharmony_ci  % cd usb_gadget/g1
41062306a36Sopenharmony_ci  % mkdir configs/c.1
41162306a36Sopenharmony_ci  % mkdir functions/midi2.usb0
41262306a36Sopenharmony_ci
41362306a36Sopenharmony_ci  % echo 0x0004 > idProduct
41462306a36Sopenharmony_ci  % echo 0x17b3 > idVendor
41562306a36Sopenharmony_ci  % mkdir strings/0x409
41662306a36Sopenharmony_ci  % echo "ACME Enterprises" > strings/0x409/manufacturer
41762306a36Sopenharmony_ci  % echo "ACMESynth" > strings/0x409/product
41862306a36Sopenharmony_ci  % echo "ABCD12345" > strings/0x409/serialnumber
41962306a36Sopenharmony_ci
42062306a36Sopenharmony_ci  % mkdir configs/c.1/strings/0x409
42162306a36Sopenharmony_ci  % echo "Monosynth" > configs/c.1/strings/0x409/configuration
42262306a36Sopenharmony_ci  % echo 120 > configs/c.1/MaxPower
42362306a36Sopenharmony_ci
42462306a36Sopenharmony_ciAt this point, there must be a subdirectory `ep.0`, and that is the
42562306a36Sopenharmony_ciconfiguration for a UMP Endpoint.  You can fill the Endpoint
42662306a36Sopenharmony_ciinformation like::
42762306a36Sopenharmony_ci
42862306a36Sopenharmony_ci  % echo "ACMESynth" > functions/midi2.usb0/iface_name
42962306a36Sopenharmony_ci  % echo "ACMESynth" > functions/midi2.usb0/ep.0/ep_name
43062306a36Sopenharmony_ci  % echo "ABCD12345" > functions/midi2.usb0/ep.0/product_id
43162306a36Sopenharmony_ci  % echo 0x0123 > functions/midi2.usb0/ep.0/family
43262306a36Sopenharmony_ci  % echo 0x4567 > functions/midi2.usb0/ep.0/model
43362306a36Sopenharmony_ci  % echo 0x123456 > functions/midi2.usb0/ep.0/manufacturer
43462306a36Sopenharmony_ci  % echo 0x12345678 > functions/midi2.usb0/ep.0/sw_revision
43562306a36Sopenharmony_ci
43662306a36Sopenharmony_ciThe default MIDI protocol can be set either 1 or 2::
43762306a36Sopenharmony_ci
43862306a36Sopenharmony_ci  % echo 2 > functions/midi2.usb0/ep.0/protocol
43962306a36Sopenharmony_ci
44062306a36Sopenharmony_ciAnd, you can find a subdirectory `block.0` under this Endpoint
44162306a36Sopenharmony_cisubdirectory.  This defines the Function Block information::
44262306a36Sopenharmony_ci
44362306a36Sopenharmony_ci  % echo "Monosynth" > functions/midi2.usb0/ep.0/block.0/name
44462306a36Sopenharmony_ci  % echo 0 > functions/midi2.usb0/ep.0/block.0/first_group
44562306a36Sopenharmony_ci  % echo 1 > functions/midi2.usb0/ep.0/block.0/num_groups
44662306a36Sopenharmony_ci
44762306a36Sopenharmony_ciFinally, link the configuration and enable it::
44862306a36Sopenharmony_ci
44962306a36Sopenharmony_ci  % ln -s functions/midi2.usb0 configs/c.1
45062306a36Sopenharmony_ci  % echo dummy_udc.0 > UDC
45162306a36Sopenharmony_ci
45262306a36Sopenharmony_ciwhere `dummy_udc.0` is an example case and it differs depending on the
45362306a36Sopenharmony_cisystem.  You can find the UDC instances in `/sys/class/udc` and pass
45462306a36Sopenharmony_cithe found name instead::
45562306a36Sopenharmony_ci
45662306a36Sopenharmony_ci  % ls /sys/class/udc
45762306a36Sopenharmony_ci  dummy_udc.0
45862306a36Sopenharmony_ci
45962306a36Sopenharmony_ciNow, the MIDI 2.0 gadget device is enabled, and the gadget host
46062306a36Sopenharmony_cicreates a new sound card instance containing a UMP rawmidi device by
46162306a36Sopenharmony_ci`f_midi2` driver::
46262306a36Sopenharmony_ci
46362306a36Sopenharmony_ci  % cat /proc/asound/cards
46462306a36Sopenharmony_ci  ....
46562306a36Sopenharmony_ci  1 [Gadget         ]: f_midi2 - MIDI 2.0 Gadget
46662306a36Sopenharmony_ci                       MIDI 2.0 Gadget
46762306a36Sopenharmony_ci
46862306a36Sopenharmony_ciAnd on the connected host, a similar card should appear, too, but with
46962306a36Sopenharmony_cithe card and device names given in the configfs above::
47062306a36Sopenharmony_ci
47162306a36Sopenharmony_ci  % cat /proc/asound/cards
47262306a36Sopenharmony_ci  ....
47362306a36Sopenharmony_ci  2 [ACMESynth      ]: USB-Audio - ACMESynth
47462306a36Sopenharmony_ci                       ACME Enterprises ACMESynth at usb-dummy_hcd.0-1, high speed
47562306a36Sopenharmony_ci
47662306a36Sopenharmony_ciYou can play a MIDI file on the gadget side::
47762306a36Sopenharmony_ci
47862306a36Sopenharmony_ci  % aplaymidi -p 20:1 to_host.mid
47962306a36Sopenharmony_ci
48062306a36Sopenharmony_ciand this will appear as an input from a MIDI device on the connected
48162306a36Sopenharmony_cihost::
48262306a36Sopenharmony_ci
48362306a36Sopenharmony_ci  % aseqdump -p 20:0 -u 2
48462306a36Sopenharmony_ci
48562306a36Sopenharmony_ciVice versa, a playback on the connected host will work as an input on
48662306a36Sopenharmony_cithe gadget, too.
48762306a36Sopenharmony_ci
48862306a36Sopenharmony_ciEach Function Block may have different direction and UI-hint,
48962306a36Sopenharmony_cispecified via `direction` and `ui_hint` attributes.
49062306a36Sopenharmony_ciPassing `1` is for input-only, `2` for out-only and `3` for
49162306a36Sopenharmony_cibidirectional (the default value).  For example::
49262306a36Sopenharmony_ci
49362306a36Sopenharmony_ci  % echo 2 > functions/midi2.usb0/ep.0/block.0/direction
49462306a36Sopenharmony_ci  % echo 2 > functions/midi2.usb0/ep.0/block.0/ui_hint
49562306a36Sopenharmony_ci
49662306a36Sopenharmony_ciWhen you need more than one Function Blocks, you can create
49762306a36Sopenharmony_cisubdirectories `block.1`, `block.2`, etc dynamically, and configure
49862306a36Sopenharmony_cithem in the configuration procedure above before linking.
49962306a36Sopenharmony_ciFor example, to create a second Function Block for a keyboard::
50062306a36Sopenharmony_ci
50162306a36Sopenharmony_ci  % mkdir functions/midi2.usb0/ep.0/block.1
50262306a36Sopenharmony_ci  % echo "Keyboard" > functions/midi2.usb0/ep.0/block.1/name
50362306a36Sopenharmony_ci  % echo 1 > functions/midi2.usb0/ep.0/block.1/first_group
50462306a36Sopenharmony_ci  % echo 1 > functions/midi2.usb0/ep.0/block.1/num_groups
50562306a36Sopenharmony_ci  % echo 1 > functions/midi2.usb0/ep.0/block.1/direction
50662306a36Sopenharmony_ci  % echo 1 > functions/midi2.usb0/ep.0/block.1/ui_hint
50762306a36Sopenharmony_ci
50862306a36Sopenharmony_ciThe `block.*` subdirectories can be removed dynamically, too (except
50962306a36Sopenharmony_cifor `block.0` which is persistent).
51062306a36Sopenharmony_ci
51162306a36Sopenharmony_ciFor assigning a Function Block for MIDI 1.0 I/O, set up in `is_midi1`
51262306a36Sopenharmony_ciattribute.  1 is for MIDI 1.0, and 2 is for MIDI 1.0 with low speed
51362306a36Sopenharmony_ciconnection::
51462306a36Sopenharmony_ci
51562306a36Sopenharmony_ci  % echo 2 > functions/midi2.usb0/ep.0/block.1/is_midi1
51662306a36Sopenharmony_ci
51762306a36Sopenharmony_ciFor disabling the processing of UMP Stream messages in the gadget
51862306a36Sopenharmony_cidriver, pass `0` to `process_ump` attribute in the top-level config::
51962306a36Sopenharmony_ci
52062306a36Sopenharmony_ci  % echo 0 > functions/midi2.usb0/process_ump
52162306a36Sopenharmony_ci
52262306a36Sopenharmony_ciThe MIDI 1.0 interface at altset 0 is supported by the gadget driver,
52362306a36Sopenharmony_citoo.  When MIDI 1.0 interface is selected by the connected host, the
52462306a36Sopenharmony_ciUMP I/O on the gadget is translated from/to USB MIDI 1.0 packets
52562306a36Sopenharmony_ciaccordingly while the gadget driver keeps communicating with the
52662306a36Sopenharmony_ciuser-space over UMP rawmidi.
52762306a36Sopenharmony_ci
52862306a36Sopenharmony_ciMIDI 1.0 ports are set up from the config in each Function Block.
52962306a36Sopenharmony_ciFor example::
53062306a36Sopenharmony_ci
53162306a36Sopenharmony_ci  % echo 0 > functions/midi2.usb0/ep.0/block.0/midi1_first_group
53262306a36Sopenharmony_ci  % echo 1 > functions/midi2.usb0/ep.0/block.0/midi1_num_groups
53362306a36Sopenharmony_ci
53462306a36Sopenharmony_ciThe configuration above will enable the Group 1 (the index 0) for MIDI
53562306a36Sopenharmony_ci1.0 interface.  Note that those groups must be in the groups defined
53662306a36Sopenharmony_cifor the Function Block itself.
53762306a36Sopenharmony_ci
53862306a36Sopenharmony_ciThe gadget driver supports more than one UMP Endpoints, too.
53962306a36Sopenharmony_ciSimilarly like the Function Blocks, you can create a new subdirectory
54062306a36Sopenharmony_ci`ep.1` (but under the card top-level config) to enable a new Endpoint::
54162306a36Sopenharmony_ci
54262306a36Sopenharmony_ci  % mkdir functions/midi2.usb0/ep.1
54362306a36Sopenharmony_ci
54462306a36Sopenharmony_ciand create a new Function Block there.  For example, to create 4
54562306a36Sopenharmony_ciGroups for the Function Block of this new Endpoint::
54662306a36Sopenharmony_ci
54762306a36Sopenharmony_ci  % mkdir functions/midi2.usb0/ep.1/block.0
54862306a36Sopenharmony_ci  % echo 4 > functions/midi2.usb0/ep.1/block.0/num_groups
54962306a36Sopenharmony_ci
55062306a36Sopenharmony_ciNow, you'll have 4 rawmidi devices in total: the first two are UMP
55162306a36Sopenharmony_cirawmidi devices for Endpoint 0 and Endpoint 1, and other two for the
55262306a36Sopenharmony_cilegacy MIDI 1.0 rawmidi devices corresponding to both EP 0 and EP 1.
55362306a36Sopenharmony_ci
55462306a36Sopenharmony_ciThe current altsetting on the gadget can be informed via a control
55562306a36Sopenharmony_cielement "Operation Mode" with `RAWMIDI` iface.  e.g. you can read it
55662306a36Sopenharmony_civia `amixer` program running on the gadget host like::
55762306a36Sopenharmony_ci
55862306a36Sopenharmony_ci  % amixer -c1 cget iface=RAWMIDI,name='Operation Mode'
55962306a36Sopenharmony_ci  ; type=INTEGER,access=r--v----,values=1,min=0,max=2,step=0
56062306a36Sopenharmony_ci  : values=2
56162306a36Sopenharmony_ci
56262306a36Sopenharmony_ciThe value (shown in the second returned line with `: values=`)
56362306a36Sopenharmony_ciindicates 1 for MIDI 1.0 (altset 0), 2 for MIDI 2.0 (altset 1) and 0
56462306a36Sopenharmony_cifor unset.
56562306a36Sopenharmony_ci
56662306a36Sopenharmony_ciAs of now, the configurations can't be changed after binding.
567