I accomplished this by creating a midiMessageAsObservable method which created a new observable subject that I could pass input.onmidimessage events down the stream by calling source.next(note).Ĭonst midiAccess$ = omPromise(navigator.requestMIDIAccess()) Ĭonst inputStream$ = midiAccess$.map((midi: any) => ().next().value) // grab the first controller In order to do this, I needed to find a way to wrap the onmidimessage event in an observable stream so I could pass the event object along. Now that we have our connected devices, how do we capture a signal from them? This was a bit of an interesting step for me because I wanted to do something that would preserve the observable stream.
How do I capture signal from a midi controller? We then assign the response to vices and then iterate over the collection and display them in our template. subscribe((devices: any) => vices = devices) map((devices: any) => devices.map(device => device)) // grab just the MIDIInput map((midi: any) => om(midi.inputs)) // convert from iterable fromPromise(navigator.requestMIDIAccess()) I am then grabbing just the midi inputs in the next map operation. To make it easy to select the device I want, I use om to convert the iterable into an array. Because I am a huge fan of observables, I use fromPromise to convert our response into an observable so that I can transform the response into just the device that I want.
To gain access to our midi devices, we use navigator.requestMIDIAccess() which will return a promise that contains an iterable of all our connected midi devices. Fortunately for us, there is a Web Midi API specification that allows us to enumerate, select and interact with midi devices.
Interestingly enough, I had no idea how to do this when I started building this project. Connecting to a controller is obviously the first place we needed to start.