WebAudio / web-midi-api

The Web MIDI API, developed by the W3C Audio WG
http://webaudio.github.io/web-midi-api/
Other
326 stars 49 forks source link

Expose system-level grouping of MIDIPorts #148

Open agoode opened 9 years ago

agoode commented 9 years ago

Both ALSA and CoreMIDI (Mac) have a 2-level organization of MIDI ports. The first level (called Entity in CoreMIDI and Client in ALSA) typically corresponds to an application or single hardware device. The second level (called Endpoint in Core MIDI and Port in ALSA) corresponds to actual MIDI ports.

Most USB MIDI devices have a single Entity (the device itself), but multiple Endpoints (the individual MIDI ports on a interface device, or the internal connections on a keyboard or synth). This allows software to reflect the grouping implicit in the hardware.

Web MIDI only exposes the second concept, as MIDIPort. It would be nice to have a way to express the first level concept in WebMIDI, so that software can say "Port X" on the "Y MIDI interface", and display appropriately.

toyoshim commented 9 years ago

Any thoughts on the actual API details? E.g., MIDIAccess could have MIDIDeviceMap devices attribute?

agoode commented 9 years ago

First, it is important that the MIDIPorts are ordered within a device. The ordering often has semantic meaning, for example numbered ports "Input 1", "Input 2", etc.

My initial thought was to have another MIDIPort attribute that points to its parent device. But maybe we should just introduce a new devices attribute on MIDIAccess. A MIDIDevice can contain inputs and outputs as well as other attributes.

We may still want to add a device attribute to MIDIPort that points to its MIDIDevice.

bome commented 9 years ago

Exposing more information of the underlying hardware is always good, IMHO. However, I'm not a big fan of the ALSA way, where you need to traverse a tree from top to bottom for iterating all ports. It forces advanced functionality (working with the device tree) on all programmers.

So, for me, adding a device (=parent) attribute to a MIDIPort will do the job. It's easy to get a flat list, and still possible to construct the tree.

cwilso commented 9 years ago

My primary concern with this is that it will not be supported consistently across all systems - notably Windows, of course - and what this might mean to patterns of development. I think it if is "add a parent device attribute to MIDIPort, which can explictly be null" or something like that, I can be okay, but sadly developers can't rely on this.

agoode commented 9 years ago

There is probably a way to extract the info on Windows. See https://msdn.microsoft.com/en-us/library/windows/hardware/ff536382%28v=vs.85%29.aspx.

Chrome does something with this structure to extract the USB vendor and product numbers. If there is a way to link back to a hardware node, then this functionality can exist on Windows as well.

bome commented 9 years ago

What I've seen on Windows, it depends on the driver what and if information is exposed as interface GUID etc. For example, virtual port drivers don't have a hardware interface.

But also for me, it's OK to allow null for parent for cases or OS'es where it's not possible to retrieve the topology. As said, I believe the parent attribute is meant for advanced functionality, and it's OK to let such software deal with the special case null then.

toyoshim commented 9 years ago

How about providing a pseudo device that holds devices that do not have device information? Also, it can be a fallback for a platform that never support device information. In such platform, all ports will be under the pseudo device. I think that would be better than null because API user does not need to do something special for them.

agoode commented 9 years ago

I like the idea of either a single pseudo device for all unknown devices, or perhaps a pseudo device per port.

bome commented 9 years ago

if providing parent functionality, it's important that a program can accurately find out the port parents, and where parent information is unavailable. I don't see a use case for pseudo devices, or how they improve the API other than avoiding null. In particular, one single pseudo device for all MIDI ports with unknown parent is suggesting a wrong relationship.

For me, using a pseudo device means that you need to be able to tell that it's the or a pseudo device, i.e. if (parent.isPseudoDevice) seems pretty much the same as if (parent == null). But I may be missing a use case here.

cwilso commented 9 years ago

I'm with Florian on this. I think it would be a mistake to concoct fake parents; it's more informative to deliberately shrug and say "we can't figure out the parent device." On Jun 3, 2015 2:53 AM, "Florian" notifications@github.com wrote:

if providing parent functionality, it's important that a program can accurately find out the port parents, and where parent information is unavailable. I don't see a use case for pseudo devices, or how they improve the API other than avoiding null. In particular, one single pseudo device for all MIDI ports with unknown parent is suggesting a wrong relationship.

— Reply to this email directly or view it on GitHub https://github.com/WebAudio/web-midi-api/issues/148#issuecomment-108280548 .

cwilso commented 8 years ago

This needs WG input on milestone.

cwilso commented 8 years ago

v1, attribute on MIDIPort.

agoode commented 8 years ago

I think the next step is to define the structure of the attribute. Here is a first draft:

interface MIDIDevice {
    readonly        attribute DOMString               id;
    readonly        attribute DOMString?              name;
};

id is an opaque but unique identifier as before.

Many of the attributes that might be in MIDIDevice are already denormalized into MIDIPort, so I did not repeat them.

The only other possible missing thing is the port number for the device. In both ALSA and CoreMIDI, the ports on a device are strictly ordered, because they typically have an ordering on the physical device. (IN 1, OUT 1, IN 2, OUT 2, etc.)

I am not sure if we should somehow record this index into the MIDIPort. We already sort of have it through the implicit ordering of inputs and outputs, though it would be nice to have it directly on the MIDIPort to use when responding to events.

toyoshim commented 8 years ago

FYI, now chrome has a new backend using Windows 10 API behind a flag, and it use CM_Get_DevNode_Property to obtain device information. It seems that we can extract device grouping by traversing the device tree.