Enable playing midi files with midi() function

This commit is contained in:
2020-03-17 20:12:55 +01:00
parent 15b77e2c8b
commit 8c3b6234ab
3 changed files with 38 additions and 23 deletions

View File

@@ -27,7 +27,7 @@ class MidiFunction : Function("midi") {
throw CustomException("MIDI standard supports max to 16 channels and that number has been exceeded")
}
Midi.with(unwrapConfig(config)).run(unwrappedLines)
Midi.with(unwrapConfig(config)).play(unwrappedLines)
Value.void()
}
@@ -39,7 +39,7 @@ class MidiFunction : Function("midi") {
throw CustomException("MIDI standard supports max to 16 channels and that number has been exceeded")
}
Midi.with(emptyMap()).run(unwrappedLines)
Midi.with(emptyMap()).play(unwrappedLines)
Value.void()
}
@@ -54,7 +54,7 @@ class MidiFunction : Function("midi") {
throw CustomException("MIDI standard supports max to 16 channels and that number has been exceeded")
}
Midi.with(unwrapConfig(config)).run(unwrappedChannels)
Midi.with(unwrapConfig(config)).play(unwrappedChannels)
Value.void()
}
@@ -66,10 +66,15 @@ class MidiFunction : Function("midi") {
throw CustomException("MIDI standard supports max to 16 channels and that number has been exceeded")
}
Midi.with(emptyMap()).run(unwrappedChannels)
Midi.with(emptyMap()).play(unwrappedChannels)
Value.void()
}
new function simple(ofType(STRING)) body { _, (file) ->
Midi.playFile(file.value as String)
Value.void()
}
}
private fun unwrapConfig(config: Value): Map<String, Any> {

View File

@@ -59,7 +59,7 @@ class MidiHelpFunction : Function("midiHelp") {
println(it)
Midi
.with(mapOf("bpm" to bpm))
.run(mapOf(channel to listOf(listOf("i:$instrument", it))))
.play(mapOf(channel to listOf(listOf("i:$instrument", it))))
Thread.sleep(100)
}
}

View File

@@ -1,5 +1,6 @@
package io.smnp.ext.midi
import java.io.File
import javax.sound.midi.MidiSystem
import javax.sound.midi.Sequence
import javax.sound.midi.Sequencer
@@ -13,35 +14,44 @@ object Midi {
val instruments: List<String>
get() = synthesizer.availableInstruments.map { it.toString() }
fun playFile(file: String) {
playSequence(MidiSystem.getSequence(File(file)))
}
private fun playSequence(sequence: Sequence, prepare: (Sequencer) -> Unit = {}) {
sequencer.sequence = sequence
sequencer.start()
while (sequencer.isRunning) Thread.sleep(20)
sequencer.stop()
}
fun with(config: Map<String, Any>): SequenceExecutor {
return SequenceExecutor(sequencer, config)
}
class SequenceExecutor(private val sequencer: Sequencer, private val config: Map<String, Any>) {
fun run(lines: List<List<Any>>) {
fun play(lines: List<List<Any>>) {
val sequence = Sequence(Sequence.PPQ, (config.getOrDefault("ppq", DEFAULT_PPQ) as Int))
provideCompiler(config).compileLines(lines, sequence)
run(sequence)
play(sequence)
}
fun run(channels: Map<Int, List<List<Any>>>) {
val sequence = Sequence(Sequence.PPQ, (config.getOrDefault("ppq", DEFAULT_PPQ) as Int))
provideCompiler(config).compileChannels(channels, sequence)
run(sequence)
}
private fun run(sequence: Sequence) {
sequencer.sequence = sequence
sequencer.tempoInBPM = (config.getOrDefault("bpm", DEFAULT_BPM) as Int).toFloat()
Midi.sequencer.start()
while (Midi.sequencer.isRunning) Thread.sleep(20)
Midi.sequencer.stop()
}
fun provideCompiler(config: Map<String, Any>): SequenceCompiler =
private fun provideCompiler(config: Map<String, Any>): SequenceCompiler =
if(config.containsKey("ppq")) PpqSequenceCompiler()
else DefaultSequenceCompiler()
private fun play(sequence: Sequence) {
playSequence(sequence) {
Midi.sequencer.tempoInBPM = (config.getOrDefault("bpm", DEFAULT_BPM) as Int).toFloat()
}
}
fun play(channels: Map<Int, List<List<Any>>>) {
val sequence = Sequence(Sequence.PPQ, (config.getOrDefault("ppq", DEFAULT_PPQ) as Int))
provideCompiler(config).compileChannels(channels, sequence)
play(sequence)
}
}
fun init() {