Skip to content

Commit

Permalink
MIDI-CI: fix MUID handling.
Browse files Browse the repository at this point in the history
  • Loading branch information
atsushieno committed Dec 10, 2023
1 parent ed73e4a commit a6028a4
Show file tree
Hide file tree
Showing 3 changed files with 22 additions and 18 deletions.
27 changes: 13 additions & 14 deletions ktmidi/src/commonMain/kotlin/dev/atsushieno/ktmidi/ci/CIFactory.kt
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
package dev.atsushieno.ktmidi.ci
import kotlin.experimental.and

class MidiCIProtocolTypeInfo(
val type: Byte,
Expand Down Expand Up @@ -62,27 +61,27 @@ object CIFactory {
// Assumes the input value is already 7-bit encoded if required.
fun midiCiDirectUint32At(dst: MutableList<Byte>, offset: Int, v: Int) {
dst[offset] = (v and 0xFF).toByte()
dst[offset + 1] = (v shr 8 and 0xFF).toByte()
dst[offset + 2] = (v shr 16 and 0xFF).toByte()
dst[offset + 3] = (v shr 24 and 0xFF).toByte()
dst[offset + 1] = ((v shr 8) and 0xFF).toByte()
dst[offset + 2] = ((v shr 16) and 0xFF).toByte()
dst[offset + 3] = ((v shr 24) and 0xFF).toByte()
}

fun midiCI7bitInt14At(dst: MutableList<Byte>, offset: Int, v: Short) {
dst[offset] = (v and 0x7F).toByte()
fun midiCI7bitInt14At(dst: MutableList<Byte>, offset: Int, v: UShort) {
dst[offset] = (v and 0x7Fu).toByte()
dst[offset + 1] = (v.toInt() shr 7 and 0x7F).toByte()
}

fun midiCI7bitInt21At(dst: MutableList<Byte>, offset: Int, v: Int) {
dst[offset] = (v and 0x7F).toByte()
dst[offset + 1] = (v shr 7 and 0x7F).toByte()
dst[offset + 2] = (v shr 14 and 0x7F).toByte()
dst[offset + 1] = ((v shr 7) and 0x7F).toByte()
dst[offset + 2] = ((v shr 14) and 0x7F).toByte()
}

fun midiCI7bitInt28At(dst: MutableList<Byte>, offset: Int, v: Int) {
dst[offset] = (v and 0x7F).toByte()
dst[offset + 1] = (v shr 7 and 0x7F).toByte()
dst[offset + 2] = (v shr 14 and 0x7F).toByte()
dst[offset + 3] = (v shr 21 and 0x7F).toByte()
dst[offset + 1] = ((v shr 7) and 0x7F).toByte()
dst[offset + 2] = ((v shr 14) and 0x7F).toByte()
dst[offset + 3] = ((v shr 21) and 0x7F).toByte()
}

fun midiCIMessageCommon(
Expand Down Expand Up @@ -111,14 +110,14 @@ object CIFactory {
midiCIMessageCommon(dst, 0x7F, sysexSubId2, versionAndFormat, sourceMUID, destinationMUID)
midiCiDirectUint32At(
dst, 13,
deviceManufacturer3Bytes.toInt()
deviceManufacturer3Bytes
) // the last byte is extraneous, but will be overwritten next.
midiCiDirectUint16At(dst, 16, deviceFamily)
midiCiDirectUint16At(dst, 18, deviceFamilyModelNumber)
// LAMESPEC: Software Revision Level does not mention in which endianness this field is stored.
midiCiDirectUint32At(dst, 20, softwareRevisionLevel.toInt())
midiCiDirectUint32At(dst, 20, softwareRevisionLevel)
dst[24] = ciCategorySupported
midiCiDirectUint32At(dst, 25, receivableMaxSysExSize.toInt())
midiCiDirectUint32At(dst, 25, receivableMaxSysExSize)
dst[29] = initiatorOutputPathId
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ object MidiCIConstants {

class MidiCIInitiator(private val sendOutput: (data: List<Byte>) -> Unit,
val outputPathId: Byte = 0,
val muid: Int = Random.nextInt()) {
val muid: Int = Random.nextInt() and 0x7F7F7F7F) {

var device: DeviceDetails = DeviceDetails.empty
var midiCIBufferSize = 1024
Expand Down Expand Up @@ -335,7 +335,7 @@ class MidiCIInitiator(private val sendOutput: (data: List<Byte>) -> Unit,
*
*/
class MidiCIResponder(private val sendOutput: (data: List<Byte>) -> Unit,
private val muid: Int = Random.nextInt()) {
private val muid: Int = Random.nextInt() and 0x7F7F7F7F) {

var device: DeviceDetails = DeviceDetails.empty
var capabilityInquirySupported = MidiCIDiscoveryCategoryFlags.ThreePs
Expand Down Expand Up @@ -527,4 +527,9 @@ class MidiCIResponder(private val sendOutput: (data: List<Byte>) -> Unit,
}*/
}
}

init {
if (muid != muid and 0x7F7F7F7F)
throw IllegalArgumentException("muid must consist of 7-bit byte values i.e. each 8-bit number must not have the topmost bit as 0. (`muid` must be equivalent to `muid and 0x7F7F7F7F`")
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ class TestCIMediator {
val responderSender = { data: List<Byte> -> initiator.processInput(data) }

val initiator: MidiCIInitiator =
MidiCIInitiator(initiatorSender, 0, 19474)
MidiCIInitiator(initiatorSender, 0, 19474 and 0x7F7F7F7F)
val responder: MidiCIResponder =
MidiCIResponder(responderSender, 37564)
MidiCIResponder(responderSender, 37564 and 0x7F7F7F7F)
}

0 comments on commit a6028a4

Please sign in to comment.