[alsa-devel] Reflections on implementing Web MIDI on top of ALSA seq

Adam Goode agoode at google.com
Fri May 29 23:56:20 CEST 2015


Hi,

Chrome 43 is now in beta, with Web MIDI support.
(http://blog.chromium.org/2015/04/chrome-43-beta-web-midi-and-upgrading.html)

The Linux (and Chrome OS) version of Chrome uses ALSA seq to implement
Web MIDI. I wanted to reflect a bit on some of the issues I discovered
while implementing this new API on top of seq.

This is a little bit long, so the tl;dr is:
* ALSA seq worked pretty well for implementing Web MIDI, but I need a
way to get the card number for a given client, before my assumptions
about the kernel break.



Here is a quick overview of Web MIDI (http://www.w3.org/TR/webmidi/):
 - provides hotplug events for port connect/disconnect
 - incoming events are timestamped
 - outgoing events can be timestamped for future delivery by the system
 - timestamps are high precision, and use a monotonic clock
 - the port abstraction contains "name", "manufacturer", and "version" fields
 - open ports auto-reconnect if the port disappears and reappears, for
both send and receive
 - input and output ports are distinct: there are no duplex ports
 - uses MIDI bytestreams (not an event structure), but requires full
MIDI messages to be sent

The initial prototype of Chrome's Web MIDI support was built on top of
rawmidi. I rewrote it to use seq instead (to get multiple client and
user client access).

Here are my observations:
 - Getting the "manufacturer" is very hard from seq. I needed to join
against udev data, which relies on the current implementation of ALSA
in the kernel. These udev attributes are also used to match for
transparent reconnect.
 - I could not use the kernel seq timestamp, either for send or
receive, since I could not get it to just use a CLOCK_MONOTONIC
offset. Instead, timestamping is done in userspace.
 - Hotplug was tricky, since I needed to listen to both seq events and
udev events. I would prefer just to use udev, since I have to anyway.

I definitely want to fix the kernel so that I can stop relying on a
few implementation details. Here are the current assumptions I am
making:
 - Card based clients start at 16. (I need to know which clients
actually have cards)
 - Clients are in the same order as cards.
 - There is a 1:1 correspondence between clients and OPL3+rawmidi devices.

One way to fix these assumptions would be to fully expose all seq
events through sysfs. Right now, there is a seq device in sysfs but it
has no information.

Here are some ways that the kernel might be extended to simplify the
code and/or fix bad assumptions:
 1. Expose all seq clients+ports as kobjects, with a symlink to the
card if it's a hardware device
 2. Expose all subscriptions through sysfs
 3. Add a simplified timestamp mechanism that just uses a configurable
system clock, with at least CLOCK_MONOTONIC available (something like
what sound/core/timer.c does with tread?)

The first change would allow me to eliminate all the hardcoded
assumptions about which cards correspond to which clients. I believe
it would also allow me to drive the hotplug logic directly from udev,
instead of both udev and seq.
The second change is not strictly necessary, but would remove more
need to react to seq events for some uses.
The third change would allow me to use the kernel timestamp reliably,
since right now I timestamp events with CLOCK_MONOTONIC in userspace.


If I had to start today and create a new MIDI kernel interface for
ALSA, it would look like this: not-quite-raw-midi:
 - hotplug events completely driven by sysfs
 - ability to interoperate with existing seq clients (for kernel and
user clients)
 - non-exclusive access
 - reads and writes use a simple structured format, with timestamp and
a midi message as bytes
 - no or minimal alsa-lib needed
 - one device file per port (no subdevices)
 - some mechanism for creating userspace clients, preferably with some
number of key-value attributes (so I can report "manufacturer" and
other things if the user client sets it)


Thanks for reading these reflections. Comments are welcome.


Adam


More information about the Alsa-devel mailing list