Skip to content

Commit

Permalink
fix #96 - use arena and reuse MIDIEventList like we did for MIDI1 (#85).
Browse files Browse the repository at this point in the history
  • Loading branch information
atsushieno committed Jan 6, 2025
1 parent 2890fe7 commit 64fc443
Show file tree
Hide file tree
Showing 3 changed files with 15 additions and 10 deletions.
1 change: 1 addition & 0 deletions input-sample/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ kotlin {
binaries {
executable {
entryPoint = "main"
runTask?.standardInput = System.`in`
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,23 @@ package dev.atsushieno.ktmidi

import kotlinx.cinterop.*
import platform.CoreMIDI.*
import platform.posix.alloca

class UmpCoreMidiAccess : CoreMidiAccess() {
class UmpCoreMidiAccess(val sendBufferSize: Int) : CoreMidiAccess() {
// It is kept for ABI backward compatibility...
constructor() : this(1024)

override val name = "CoreMIDI-UMP"

override suspend fun openInput(portId: String): MidiInput =
UmpCoreMidiInput(ClientHolder(this), null, inputs.first { it.id == portId } as CoreMidiPortDetails)

override suspend fun openOutput(portId: String): MidiOutput =
UmpCoreMidiOutput(ClientHolder(this), outputs.first { it.id == portId } as CoreMidiPortDetails)
UmpCoreMidiOutput(sendBufferSize, ClientHolder(this), outputs.first { it.id == portId } as CoreMidiPortDetails)

override suspend fun createVirtualInputSender(context: PortCreatorContext): MidiOutput {
val holder = ClientHolder(this)
val endpoint = createVirtualInputSource(holder.clientRef, context)
return UmpCoreMidiOutput(holder, CoreMidiPortDetails(endpoint))
return UmpCoreMidiOutput(sendBufferSize, holder, CoreMidiPortDetails(endpoint))
}

@OptIn(ExperimentalForeignApi::class)
Expand Down Expand Up @@ -104,7 +106,7 @@ private class UmpCoreMidiInput(holder: ClientHolder, customReceiveBlockHolder: R
}

@OptIn(ExperimentalForeignApi::class)
private class UmpCoreMidiOutput(holder: ClientHolder, private val coreMidiPortDetails: CoreMidiPortDetails)
private class UmpCoreMidiOutput(val sendBufferSize: Int, holder: ClientHolder, private val coreMidiPortDetails: CoreMidiPortDetails)
: CoreMidiPort(holder, coreMidiPortDetails), MidiOutput
{
private val portRef by lazy {
Expand All @@ -117,13 +119,14 @@ private class UmpCoreMidiOutput(holder: ClientHolder, private val coreMidiPortDe
}
private val protocol = if (details.midiTransportProtocol == MidiTransportProtocol.UMP) kMIDIProtocol_2_0 else kMIDIProtocol_1_0

val arena = Arena()
val eventList by lazy { arena.alloc(sendBufferSize, 0) as MIDIEventList }

override fun send(mevent: ByteArray, offset: Int, length: Int, timestampInNanoseconds: Long) {
mevent.usePinned { pinned ->
val eventListPtr = alloca(length.toULong()) ?: return
val eventListRef: CValuesRef<MIDIEventList> = eventListPtr.reinterpret()
MIDIEventListInit(eventListRef, protocol)
MIDIEventListAdd(eventListRef, 1U, null, timestampInNanoseconds.toULong(), length.toULong(), pinned.addressOf(offset).reinterpret())
MIDISendEventList(portRef, coreMidiPortDetails.endpoint, eventListRef)
val packet = MIDIEventListInit(eventList.ptr, protocol)
MIDIEventListAdd(eventList.ptr, 1U, packet, timestampInNanoseconds.toULong(), length.toULong(), pinned.addressOf(offset).reinterpret())
MIDISendEventList(portRef, coreMidiPortDetails.endpoint, eventList.ptr)
}
}
}
1 change: 1 addition & 0 deletions player-sample/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ kotlin {
binaries {
executable {
entryPoint = "main"
runTask?.standardInput = System.`in`
}
}
}
Expand Down

0 comments on commit 64fc443

Please sign in to comment.