Update MIDI message handling and version increment

Refactored MIDI message classes to improve modularity and flexibility, introducing separate classes for distinct MIDI message types. Updated `build.gradle.kts` version to `0.2.0` to reflect these changes. Removed `.idea/.name` file as part of cleanup.
This commit is contained in:
2024-12-16 20:13:41 +01:00
parent 00d8a67ed0
commit a592e91882
8 changed files with 188 additions and 5 deletions

View File

@@ -0,0 +1,8 @@
<component name="ArtifactManager">
<artifact type="jar" name="midi-arrays-js-0.1.0">
<output-path>$PROJECT_DIR$/build/libs</output-path>
<root id="archive" name="midi-arrays-js-0.1.0.jar">
<element id="module-output" name="midi-arrays.jsMain" />
</root>
</artifact>
</component>

View File

@@ -0,0 +1,8 @@
<component name="ArtifactManager">
<artifact type="jar" name="midi-arrays-js-0.2.0">
<output-path>$PROJECT_DIR$/build/libs</output-path>
<root id="archive" name="midi-arrays-js-0.2.0.jar">
<element id="module-output" name="midi-arrays.jsMain" />
</root>
</artifact>
</component>

View File

@@ -0,0 +1,8 @@
<component name="ArtifactManager">
<artifact type="jar" name="midi-arrays-jvm-0.1.0">
<output-path>$PROJECT_DIR$/build/libs</output-path>
<root id="archive" name="midi-arrays-jvm-0.1.0.jar">
<element id="module-output" name="midi-arrays.jvmMain" />
</root>
</artifact>
</component>

View File

@@ -0,0 +1,8 @@
<component name="ArtifactManager">
<artifact type="jar" name="midi-arrays-jvm-0.2.0">
<output-path>$PROJECT_DIR$/build/libs</output-path>
<root id="archive" name="midi-arrays-jvm-0.2.0.jar">
<element id="module-output" name="midi-arrays.jvmMain" />
</root>
</artifact>
</component>

View File

@@ -8,7 +8,7 @@ plugins {
}
group = "nl.astraeus"
version = "0.2.0"
version = "0.3.0"
repositories {
mavenCentral()
@@ -28,11 +28,23 @@ kotlin {
api("nl.astraeus:typed-byte-arrays:0.2.6")
}
}
val commonTest by getting
val commonTest by getting {
dependencies {
implementation(kotlin("test-common"))
}
}
val jvmMain by getting
val jvmTest by getting
val jvmTest by getting {
dependencies {
implementation(kotlin("test"))
}
}
val jsMain by getting
val jsTest by getting
val jsTest by getting {
dependencies {
implementation(kotlin("test-js"))
}
}
}
}

View File

@@ -50,7 +50,7 @@ class TimedMidiMessage() : MidiMessage(
Type("midi", DataType.BLOB, 48),
) {
var timeToPlay by double("timeToPlay")
var midi by blob("data")
var midi by blob("midi")
init {
this.type = MidiMessageTypes.MIDI_DATA.typeId

View File

@@ -0,0 +1,78 @@
package nl.astraeus.midi.message
class SortedTimedMidiMessageList(
val reservedSize: Int = 1024
) {
val list = Array<TimedMidiMessage>(reservedSize) { TimedMidiMessage(0.0) }
var full = false
var readPointer = 0
var writePointer = 0
private fun Int.wrappedAdd(delta:Int): Int = (this + reservedSize + delta) % reservedSize
fun size(): Int = (writePointer - readPointer + reservedSize) % reservedSize
fun isEmpty(): Boolean = !full && size() == 0
fun isNotEmpty(): Boolean = !isEmpty()
fun nextTimestamp(): Double? = if (isNotEmpty()) {
list[readPointer].timeToPlay
} else {
null
}
fun lastTimestamp(): Double? = if (isNotEmpty()) {
val lastPointer = writePointer.wrappedAdd(-1)
list[lastPointer].timeToPlay
} else {
null
}
fun add(message: TimedMidiMessage) {
check(!full) {
"SortedTimedMidiMessageList is full!"
}
val time = message.timeToPlay
if (message.timeToPlay < (nextTimestamp() ?: 0.0)) {
readPointer = readPointer.wrappedAdd(-1)
list[readPointer] = message
} else if (message.timeToPlay > (lastTimestamp() ?: 0.0)) {
list[writePointer] = message
writePointer = writePointer.wrappedAdd(1)
} else {
var index = readPointer
while(index != writePointer && list[index].timeToPlay < time) {
index = index.wrappedAdd(1)
}
if (index == writePointer) {
writePointer = writePointer.wrappedAdd(1)
list[writePointer] = message
} else {
val writePosition = index
while(index != writePointer) {
list[index.wrappedAdd(1)] = list[index]
index = index.wrappedAdd(1)
}
writePointer = writePointer.wrappedAdd(1)
list[writePosition] = message
}
}
full = readPointer == writePointer
}
fun read(): TimedMidiMessage {
check(isNotEmpty()) {
"Can't read from an empty list!"
}
val message = list[readPointer]
readPointer = readPointer.wrappedAdd(1)
full = false
return message
}
}

View File

@@ -0,0 +1,61 @@
package nl.astraeus.midi.message
import kotlin.test.Test
import kotlin.test.assertEquals
import kotlin.test.assertFailsWith
class SortedTimedMidiMessageListTest {
@Test
fun testInsert() {
val list = SortedTimedMidiMessageList(5)
list.add(TimedMidiMessage(1.0, 1, 2, 3))
list.add(TimedMidiMessage(2.0, 2, 3, 4))
list.add(TimedMidiMessage(1.5, 3, 4, 5))
list.add(TimedMidiMessage(0.5, 4, 5, 6))
assertEquals(0.5, list.nextTimestamp())
assertEquals(0.5, list.read().timeToPlay)
assertEquals(1.0, list.read().timeToPlay)
assertEquals(1.5, list.read().timeToPlay)
assertEquals(2.0, list.read().timeToPlay)
}
@Test
fun testEmpty() {
assertFailsWith(IllegalStateException::class) {
val list = SortedTimedMidiMessageList(5)
list.read()
}
}
@Test
fun testFull() {
assertFailsWith(IllegalStateException::class) {
val list = SortedTimedMidiMessageList(2)
list.add(TimedMidiMessage(1.0, 1, 2, 3))
list.add(TimedMidiMessage(2.0, 2, 3, 4))
list.add(TimedMidiMessage(1.5, 3, 4, 5))
}
}
@Test
fun testFull2() {
val list = SortedTimedMidiMessageList(2)
list.add(TimedMidiMessage(1.0, 1, 2, 3))
list.add(TimedMidiMessage(2.0, 2, 3, 4))
assertEquals(true, list.full)
list.read()
assertEquals(false, list.full)
list.add(TimedMidiMessage(1.5, 3, 4, 5))
}
}