Fix lack of placed rests at the very end of MIDI tracks
This commit is contained in:
@@ -14,13 +14,22 @@ object MidiSequencer {
|
|||||||
const val NOTE_OFF = 0x80
|
const val NOTE_OFF = 0x80
|
||||||
const val NOTE_ON = 0x90
|
const val NOTE_ON = 0x90
|
||||||
const val PROGRAM_CHANGE = 0xC0
|
const val PROGRAM_CHANGE = 0xC0
|
||||||
|
const val CONTROL_CHANGE = 0xB0
|
||||||
|
}
|
||||||
|
|
||||||
|
private object Data1 {
|
||||||
|
const val ALL_NOTES_OFF = 0x7B
|
||||||
|
}
|
||||||
|
|
||||||
|
private object Data2 {
|
||||||
|
const val ZERO = 0x00
|
||||||
}
|
}
|
||||||
|
|
||||||
fun playChannels(channels: Map<Int, List<List<Any>>>, config: Map<String, Any>) {
|
fun playChannels(channels: Map<Int, List<List<Any>>>, config: Map<String, Any>) {
|
||||||
val sequence = Sequence(Sequence.PPQ, PPQ)
|
val sequence = Sequence(Sequence.PPQ, PPQ)
|
||||||
|
|
||||||
channels.forEach { (channel, lines) ->
|
channels.forEach { (channel, lines) ->
|
||||||
lines.forEach { line -> playLine(line, channel, sequence) }
|
lines.forEach { line -> playLine(line, channel-1, sequence) }
|
||||||
}
|
}
|
||||||
|
|
||||||
sequencer.sequence = sequence
|
sequencer.sequence = sequence
|
||||||
@@ -48,7 +57,7 @@ object MidiSequencer {
|
|||||||
private fun playLine(line: List<Any>, channel: Int, sequence: Sequence) {
|
private fun playLine(line: List<Any>, channel: Int, sequence: Sequence) {
|
||||||
val track = sequence.createTrack()
|
val track = sequence.createTrack()
|
||||||
|
|
||||||
line.fold(0L) { noteOnTick, item ->
|
val lastTick = line.fold(0L) { noteOnTick, item ->
|
||||||
when (item) {
|
when (item) {
|
||||||
is Note -> {
|
is Note -> {
|
||||||
note(item, channel, noteOnTick, track)
|
note(item, channel, noteOnTick, track)
|
||||||
@@ -58,6 +67,8 @@ object MidiSequencer {
|
|||||||
else -> throw ShouldNeverReachThisLineException()
|
else -> throw ShouldNeverReachThisLineException()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
track.add(allNotesOff(channel, lastTick))
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun command(instruction: String, channel: Int, beginTick: Long, track: Track): Long {
|
private fun command(instruction: String, channel: Int, beginTick: Long, track: Track): Long {
|
||||||
@@ -91,6 +102,10 @@ object MidiSequencer {
|
|||||||
return event(Command.NOTE_OFF, channel, note.intPitch() + 12, 127, tick)
|
return event(Command.NOTE_OFF, channel, note.intPitch() + 12, 127, tick)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun allNotesOff(channel: Int, tick: Long): MidiEvent {
|
||||||
|
return event(Command.CONTROL_CHANGE, channel, Data1.ALL_NOTES_OFF, Data2.ZERO, tick)
|
||||||
|
}
|
||||||
|
|
||||||
private fun event(command: Int, channel: Int, data1: Int, data2: Int, tick: Long): MidiEvent {
|
private fun event(command: Int, channel: Int, data1: Int, data2: Int, tick: Long): MidiEvent {
|
||||||
val message = ShortMessage(command, channel, data1, data2)
|
val message = ShortMessage(command, channel, data1, data2)
|
||||||
return MidiEvent(message, tick)
|
return MidiEvent(message, tick)
|
||||||
|
|||||||
Reference in New Issue
Block a user