我有一种方法可以很好地处理传入的 MIDI 消息。
它监听所有输入设备,而不仅仅是第一个。
我想使用 RxJS observables 来编写它。
这是工作(非 RxJS 可观察)之一:
public initMidiInputBis() {
if (navigator.requestMIDIAccess) {
console.log('This browser supports MIDI');
navigator.requestMIDIAccess().then(
(midiAccess: WebMidi.MIDIAccess) => this.onMIDISuccess(midiAccess),
(midiAccess: WebMidi.MIDIAccess) => this.onMIDIFailure(midiAccess)
);
} else {
console.log('This browser does not support MIDI');
}
}
private onMIDISuccess(midiAccess: WebMidi.MIDIAccess) {
for (const inputDevice of Array.from(midiAccess.inputs)) {
inputDevice[1].onmidimessage = (message: WebMidi.MIDIMessageEvent) => this.onMIDIMessage(message);
}
}
private onMIDIFailure(error: any) {
console.log('The browser could not access any MIDI device');
console.log(error);
}
上述方法工作正常,VMPK 虚拟键盘被视为输入 MIDI 设备并接收其 MIDI 消息。
这是我尝试使用 observables 再次编写它:
public initMidiInput() {
if (navigator.requestMIDIAccess) {
console.log('This browser supports MIDI');
const midiAccess$: Observable<WebMidi.MIDIAccess> = from(navigator.requestMIDIAccess());
const midiInput$: Observable<WebMidi.MIDIInput> = midiAccess$.pipe(
map((midiAccess: WebMidi.MIDIAccess) => {
return midiAccess.inputs.values().next().value;
})
);
midiInput$.pipe(
flatMap((midiInput: WebMidi.MIDIInput) => this.midiMessageAsObservable(midiInput)),
).subscribe((message: WebMidi.MIDIMessageEvent) => {
this.onMIDIMessage(message);
});
midiAccess$.subscribe(midiAccess => {
this.logOutputDevices(midiAccess);
});
} else {
console.log('This browser does not support MIDI');
}
}
使用上述方法,VMPK 虚拟键盘不会被视为输入 MIDI 设备。
此方法包含以下代码行,midiAccess.inputs.values().next().value;
它仅检索第一个输入 MIDI 设备。
如何考虑所有输入 MIDI 设备?
更新:添加一些记录器后,我可以看到VMPK
虚拟键盘被列为输入设备:
MIDIInput {onmidimessage: null, connection: "closed", id: "2A23249CBCD506F53AE4731A4FE186844C42191D517EC71DFC9813E84A1D2F87", manufacturer: "", name: "VMPK Output", …}
connection: "closed"
id: "2A23249CBCD506F53AE4731A4FE186844C42191D517EC71DFC9813E84A1D2F87"
manufacturer: ""
name: "VMPK Output"
onmidimessage: null
onstatechange: null
state: "connected"
type: "input"
version: "ALSA library version 1.1.6"
我觉得令人费解的是,它的连接在其状态处于连接状态时是关闭的。
这是我记录上述输出的方式:
const midiAccess$: Observable<WebMidi.MIDIAccess> = from(navigator.requestMIDIAccess());
const midiInput$: Observable<WebMidi.MIDIInput> = midiAccess$.pipe(
map((midiAccess: WebMidi.MIDIAccess) => {
Array.from(midiAccess.inputs.entries()).forEach(entry => {
console.log('Key: ' + entry[0]);
console.log(entry[1]);
});
return midiAccess.inputs.values().next().value;
})
);