Skip to content

Commit 11d4e96

Browse files
committed
Fix MIDI WebMIDI typing
1 parent 7eaed81 commit 11d4e96

1 file changed

Lines changed: 40 additions & 6 deletions

File tree

‎ts/src/tuningplayground/MIDI.ts‎

Lines changed: 40 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,32 @@ import { noteOn, noteOff } from "./index.js"
22
import { Midi } from "@tonejs/midi"
33
import { midiMultiplier } from "./config.js"
44

5+
type MidiMessageLike = {
6+
data?: ArrayLike<number> | null
7+
}
8+
9+
type MidiInputLike = {
10+
onmidimessage: ((event: MidiMessageLike) => void) | null
11+
}
12+
13+
type MidiAccessLike = {
14+
inputs?: {
15+
values?: () => Iterator<unknown>
16+
}
17+
}
18+
519
export function requestMIDI(): void {
620
if (navigator.requestMIDIAccess) {
7-
navigator.requestMIDIAccess().then(onMIDISuccess, onMIDIFailure)
21+
navigator
22+
.requestMIDIAccess()
23+
.then((midiAccess: unknown) => onMIDISuccess(midiAccess), onMIDIFailure)
824
} else {
925
alert("WebMIDI is not supported in this browser.")
1026
}
1127
}
1228

13-
function onMIDISuccess(midiAccess: WebMidi.MIDIAccess): void {
14-
const input = midiAccess.inputs.values().next().value as WebMidi.MIDIInput | undefined
29+
function onMIDISuccess(midiAccess: unknown): void {
30+
const input = firstMidiInput(midiAccess)
1531

1632
if (input) {
1733
input.onmidimessage = onMIDIMessage
@@ -24,10 +40,28 @@ function onMIDIFailure(error: DOMException): void {
2440
console.error("MIDI Access failed:", error)
2541
}
2642

27-
function onMIDIMessage(event: WebMidi.MIDIMessageEvent): void {
28-
if (!event.data) return
43+
function firstMidiInput(midiAccess: unknown): MidiInputLike | undefined {
44+
const inputs = (midiAccess as MidiAccessLike).inputs
45+
const input = inputs?.values?.().next().value
46+
47+
if (isMidiInputLike(input)) {
48+
return input
49+
}
50+
51+
return undefined
52+
}
53+
54+
function isMidiInputLike(value: unknown): value is MidiInputLike {
55+
return !!value && typeof value === "object" && "onmidimessage" in value
56+
}
57+
58+
function onMIDIMessage(event: MidiMessageLike): void {
59+
const data = event.data
60+
if (!data || data.length < 3) return
2961

30-
const [status, tone_index, velocity] = event.data
62+
const status = data[0]
63+
const tone_index = data[1]
64+
const velocity = data[2]
3165
const is_note_on = (status & 240) === 144
3266
const is_note_off = (status & 240) === 128
3367

0 commit comments

Comments
 (0)