117 lines
2.5 KiB
Kotlin
117 lines
2.5 KiB
Kotlin
package nl.astraeus.vst.chip.midi
|
|
|
|
import kotlinx.browser.window
|
|
import nl.astraeus.vst.chip.audio.VstChipWorklet
|
|
import nl.astraeus.vst.chip.view.MainView
|
|
import org.khronos.webgl.Uint8Array
|
|
import org.khronos.webgl.get
|
|
|
|
external class MIDIInput {
|
|
val connection: String
|
|
val id: String
|
|
val manufacturer: String
|
|
val name: String
|
|
val state: String
|
|
val type: String
|
|
val version: String
|
|
var onmidimessage: (dynamic) -> Unit
|
|
var onstatechange: (dynamic) -> Unit
|
|
|
|
fun open()
|
|
fun close()
|
|
}
|
|
|
|
external class MIDIOutput {
|
|
val connection: String
|
|
val id: String
|
|
val manufacturer: String
|
|
val name: String
|
|
val state: String
|
|
val type: String
|
|
val version: String
|
|
|
|
fun send(message: dynamic, timestamp: dynamic)
|
|
|
|
fun open()
|
|
fun close()
|
|
}
|
|
|
|
object Midi {
|
|
var outputChannel: Int = -1
|
|
|
|
var inputs = mutableListOf<MIDIInput>()
|
|
var outputs = mutableListOf<MIDIOutput>()
|
|
var currentInput: MIDIInput? = null
|
|
var currentOutput: MIDIOutput? = null
|
|
|
|
fun start() {
|
|
val navigator = window.navigator.asDynamic()
|
|
|
|
navigator.requestMIDIAccess().then(
|
|
{ midiAccess ->
|
|
val inp = midiAccess.inputs
|
|
val outp = midiAccess.outputs
|
|
|
|
console.log("Midi inputs:", inputs)
|
|
console.log("Midi outputs:", outputs)
|
|
|
|
inp.forEach() { input ->
|
|
console.log("Midi input:", input)
|
|
inputs.add(input)
|
|
console.log("Name: ${(input as? MIDIInput)?.name}")
|
|
}
|
|
|
|
outp.forEach() { output ->
|
|
console.log("Midi output:", output)
|
|
outputs.add(output)
|
|
}
|
|
|
|
MainView.requestUpdate()
|
|
},
|
|
{ e ->
|
|
println("Failed to get MIDI access - $e")
|
|
}
|
|
)
|
|
}
|
|
|
|
fun setInput(input: MIDIInput?) {
|
|
console.log("Setting input", input)
|
|
currentInput?.close()
|
|
|
|
currentInput = input
|
|
|
|
currentInput?.onstatechange = { message ->
|
|
console.log("State change:", message)
|
|
}
|
|
|
|
currentInput?.onmidimessage = { message ->
|
|
val data = message.data as Uint8Array
|
|
val hex = StringBuilder()
|
|
for (index in 0 until data.length) {
|
|
hex.append(data[index].toString(16))
|
|
hex.append(" ")
|
|
}
|
|
console.log("Midi message:", hex)
|
|
VstChipWorklet.postMessage(
|
|
message.data
|
|
)
|
|
}
|
|
|
|
currentInput?.open()
|
|
}
|
|
|
|
fun setOutput(output: MIDIOutput?) {
|
|
console.log("Setting output", output)
|
|
currentOutput?.close()
|
|
|
|
currentOutput = output
|
|
|
|
currentOutput?.open()
|
|
}
|
|
|
|
fun send(data: Uint8Array, timestamp: dynamic = null) {
|
|
currentOutput?.send(data, timestamp)
|
|
}
|
|
|
|
}
|