Add MidiMessageHandler for MIDI event handling
Introduced `MidiMessageHandler` to process and handle MIDI messages with customizable handlers for specific byte patterns. This addition improves extensibility and keeps MIDI message processing modular and organized.
This commit is contained in:
@@ -0,0 +1,82 @@
|
||||
package nl.astraeus.vst.midi
|
||||
|
||||
typealias MidiHandler = (Byte, Byte, Byte) -> Unit
|
||||
|
||||
val Byte.channel: Byte
|
||||
get() {
|
||||
return (this.toInt() and 0x0F).toByte()
|
||||
}
|
||||
|
||||
val Byte.command: Byte
|
||||
get() {
|
||||
return ((this.toInt() and 0xF0) shr 4).toByte()
|
||||
}
|
||||
|
||||
val Byte.channelCommand: Boolean
|
||||
get() {
|
||||
return this.command >= 8 && this.command <= 13
|
||||
}
|
||||
|
||||
class MidiMessageHandler(
|
||||
var channel: Byte = -1
|
||||
) {
|
||||
val singleByteHandlers = mutableMapOf<Byte, MidiHandler>()
|
||||
val doubleByteHandlers = mutableMapOf<Byte, MutableMap<Byte, MidiHandler>>()
|
||||
|
||||
fun addHandler(
|
||||
byte1: Byte,
|
||||
byte2: Byte = 0,
|
||||
handler: MidiHandler
|
||||
) {
|
||||
val b1 = if (byte1.channelCommand) {
|
||||
(byte1.toInt() and 0xF0).toByte()
|
||||
} else {
|
||||
byte1
|
||||
}
|
||||
if (byte2 == 0.toByte()) {
|
||||
singleByteHandlers[b1] = handler
|
||||
} else {
|
||||
val map = doubleByteHandlers.getOrPut(b1) {
|
||||
mutableMapOf()
|
||||
}
|
||||
map[byte2] = handler
|
||||
}
|
||||
}
|
||||
|
||||
fun addHandler(
|
||||
byte1: Int,
|
||||
byte2: Int = 0,
|
||||
handler: MidiHandler
|
||||
) = addHandler(
|
||||
byte1.toByte(),
|
||||
byte2.toByte(),
|
||||
handler
|
||||
)
|
||||
|
||||
fun handle(
|
||||
byte1: Byte,
|
||||
byte2: Byte,
|
||||
byte3: Byte
|
||||
) {
|
||||
if (
|
||||
channel < 0 ||
|
||||
!byte1.channelCommand ||
|
||||
(byte1.channelCommand && channel == byte1.channel)
|
||||
) {
|
||||
val b1 = if (byte1.channelCommand) {
|
||||
(byte1.toInt() and 0xF0).toByte()
|
||||
} else {
|
||||
byte1
|
||||
}
|
||||
|
||||
if (doubleByteHandlers.containsKey(b1)) {
|
||||
doubleByteHandlers[b1]?.get(byte2)?.invoke(byte1, byte2, byte3)
|
||||
} else if (singleByteHandlers.containsKey(b1)) {
|
||||
singleByteHandlers[b1]?.invoke(byte1, byte2, byte3)
|
||||
} else {
|
||||
println("Unhandled message: $byte1 $byte2 $byte3")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user