Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Proposal for MIDIInterface object in addition to MIDIAccess and MIDIPort. #156

Closed
objectkit opened this issue Nov 24, 2015 · 4 comments
Closed

Comments

@objectkit
Copy link

I'm hesitant to present this question/proposal/request for clarification here, as it may have been put forward already, but I didn't find anything and I feel the need to put if forward, so I'm taking the chance.

At the moment MIDIPorts are presented in MIDIPortMaps available via MIDIAccess#inputs and MIDIAccess#outputs attributes. As such, the only way to group MIDIPorts together to represent an individual physical device is to iterate the MIDIInputMap and the MIDIOutputMap, and if a MIDIPort has the same MIDIPort#name and MIDIPort#manufacturer as another, to group them together on the assumption that they belong to the same physical (or virtual?) device. Please forgive the flawed use of MIDIPortMap iteration and CoffeeScript used here

navigator.requestMIDIAccess()
    .then (midiAccess) ->
        model = {}
        for midiInputPort of midiAccess.inputs
            key = "#{midiInputPort.manufacturer} #{midiInputPort.name}"
            if not model[key]?
                model[key] =
                    manufacturer:   midiInputPort.manufacturer
                    name:           midiInputPort.name
                    id:             midiInputPort.id
                    inputs:         []
                    outputs:        []
            model[key].inputs.push midiInputPort.id

        for midiOutputPort of midiAccess.outputs
            key = "#{midiOutputPort.manufacturer} #{midiOutputPort.name}"
            if not model[key]?
                model[key] =
                    manufacturer:   midiOutputPort.manufacturer
                    name:           midiOutputPort.name
                    id:             midiOutputPort.id
                    inputs:         []
                    outputs:        []
            model[key].outputs.push midiOutputPort.id

        console.info JSON.stringify model, null, "\t"

This seems to assume that physical devices have either only 1 MIDI input and 1 MIDI output, or, that no-one will ever have more than one of the same device connected to their machine at the same time. I feel this is a shortfall of the API as I currently understand it. If I have missed something, I would much appreciate clarification, but just in case I haven't, I present the following hypothetical scenario.

The iConnectMIDI 4+ has 4 MIDI DIN INs and 4 MIDI DIN OUTs. (It also has virtual MIDI which I will sidestep for the moment as I want to bring this up later).

With only a single device attached to a computer, 4 MIDIInputPorts and 4 MIDIOutputPorts will be presented correctly by the API as it stands. As an app dev, assuming no foreknowledge of a connected device, I could iterate the available inputs and outputs of MIDIAccess, and judge by the #name and #manufacturer attributes presented, that a single device with 4 MIDIInputPorts and 4 MIDIOutputPorts is available to the system, and present that to a view in a hypothetical app.

This is fine. But in the case, rare as it may be, that a user has 2 iConnectMIDI4+ devices attached, if I were to use the same device identification strategy, my app would present a single device with 8 MIDIInput ports and 8 MIDIOutput ports! If I had foreknowledge of the device specification, I could accommodate this and correctly present 2 views, one for each device... but I feel that would be unnecessary foreknowledge in the context of a MIDI app.

Instead, I would propose the introduction of a MIDIInterface object. Again, forgive the flawed coffeescript, but if it was introduced, then this would be possible:

navigator.requestMIDIAccess()
    .then (midiAccess) ->
        model = {}
        for midiInterface in midiAccess.midiIterfaces
            descriptor =

                manufacturer:   midiInterface.manufacturer
                name:           midiInterface.name
                id:             midiInterface.id
                inputs:         []
                outputs:        []

            for midiInputPort in midiInterface.inputs
                descriptor.inputs.push midiInputPort.id

            for midiOutputPort in midiInterface.outputs
                descriptor.outputs.push midiOutputPort.id

            key = "#{midiInterface.manufacturer} #{midiInterface.name}"
            model[key] = descriptor

        console.info JSON.stringify model, null, "\t"

MIDIInterface, like MIDIAcess and MIDIPort could implement the statechange handler.

  • MIDIAccess statechange could show that a new MIDIInterface is available, or a previously connected one has disconnected.
  • MIDIInterface statechange could show that a previously connected MIDIPort associated with the MIDIInterface has disconnected, or in the case of virtual midi, that a new MIDIPort has become available to it.
  • MIDIPort statechange could then focus on MIDIPorts opening, pending, closing, and MIDIPorts could have a midiInterface attribute to track back to its parent MIDIInterface.

This would have a lot of advantages for presenting views, as well as simplifying event management from where I see it.

But then again, I've only just started with the API and there may be other means to do this, and if there are, I would appreciate some feedback as to how to do this with the present API.

@agoode
Copy link

agoode commented Nov 24, 2015

Is this possibly covered by issue #148 ?

@objectkit
Copy link
Author

@agoode - thank you - yes to some extent - I promise, I did search, but did not find that issue - thanks for referencing it! I think differences to statechange event dispatch and handling if MIDIInterface was introduced are the only difference. #148 does also point to another important issue, and that is port numeration. Hope this is of use to someone.

@cwilso
Copy link
Contributor

cwilso commented Dec 1, 2015

I think we should move the discussion there; this is pretty much precisely the same issue.

@cwilso cwilso closed this as completed Dec 1, 2015
@objectkit
Copy link
Author

Agreed 👌

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants