Create MapConfigSchema utility function
This commit is contained in:
@@ -13,9 +13,17 @@ import io.smnp.type.matcher.Matcher.Companion.listOfMatchers
|
||||
import io.smnp.type.matcher.Matcher.Companion.mapOfMatchers
|
||||
import io.smnp.type.matcher.Matcher.Companion.ofType
|
||||
import io.smnp.type.model.Value
|
||||
import io.smnp.util.config.MapConfig
|
||||
import io.smnp.util.config.MapConfigSchema
|
||||
|
||||
|
||||
class MidiFunction : Function("midi") {
|
||||
private val schema = MapConfigSchema()
|
||||
.optional("bpm", ofType(INT), Value.int(120))
|
||||
.optional("ppq", ofType(INT))
|
||||
.optional("output", ofType(STRING))
|
||||
.optional("play", ofType(BOOL))
|
||||
|
||||
override fun define(new: FunctionDefinitionTool) {
|
||||
new function vararg(
|
||||
listOf(NOTE, INT, STRING),
|
||||
@@ -27,7 +35,7 @@ class MidiFunction : Function("midi") {
|
||||
throw CustomException("MIDI standard supports max to 16 channels and that number has been exceeded")
|
||||
}
|
||||
|
||||
Midi.with(unwrapConfig(config)).play(unwrappedLines)
|
||||
Midi.with(schema.parse(config)).play(unwrappedLines)
|
||||
|
||||
Value.void()
|
||||
}
|
||||
@@ -39,7 +47,7 @@ class MidiFunction : Function("midi") {
|
||||
throw CustomException("MIDI standard supports max to 16 channels and that number has been exceeded")
|
||||
}
|
||||
|
||||
Midi.with(emptyMap()).play(unwrappedLines)
|
||||
Midi.with(MapConfig.EMPTY).play(unwrappedLines)
|
||||
|
||||
Value.void()
|
||||
}
|
||||
@@ -54,7 +62,7 @@ class MidiFunction : Function("midi") {
|
||||
throw CustomException("MIDI standard supports max to 16 channels and that number has been exceeded")
|
||||
}
|
||||
|
||||
Midi.with(unwrapConfig(config)).play(unwrappedChannels)
|
||||
Midi.with(schema.parse(config)).play(unwrappedChannels)
|
||||
|
||||
Value.void()
|
||||
}
|
||||
@@ -66,7 +74,7 @@ class MidiFunction : Function("midi") {
|
||||
throw CustomException("MIDI standard supports max to 16 channels and that number has been exceeded")
|
||||
}
|
||||
|
||||
Midi.with(emptyMap()).play(unwrappedChannels)
|
||||
Midi.with(MapConfig.EMPTY).play(unwrappedChannels)
|
||||
|
||||
Value.void()
|
||||
}
|
||||
@@ -76,21 +84,4 @@ class MidiFunction : Function("midi") {
|
||||
Value.void()
|
||||
}
|
||||
}
|
||||
|
||||
private fun unwrapConfig(config: Value): Map<String, Any> {
|
||||
return (config.unwrap() as Map<String, Any>)
|
||||
.map { (key, value) ->
|
||||
key to when (key) {
|
||||
"bpm" -> value as? Int
|
||||
?: throw CustomException("Invalid parameter type: 'bpm' is supposed to be of int type")
|
||||
"ppq" -> value as? Int
|
||||
?: throw CustomException("Invalid parameter type: 'ppq' is supposed to be of int type")
|
||||
"output" -> value as? String
|
||||
?: throw CustomException("Invalid parameter type: 'output' is supposed to be of string type")
|
||||
"play" -> value as? Boolean
|
||||
?: throw CustomException("Invalid parameter type: 'play' is supposed to be of bool type")
|
||||
else -> value
|
||||
}
|
||||
}.toMap()
|
||||
}
|
||||
}
|
||||
@@ -12,6 +12,7 @@ import io.smnp.type.enumeration.DataType.*
|
||||
import io.smnp.type.matcher.Matcher.Companion.ofType
|
||||
import io.smnp.type.matcher.Matcher.Companion.optional
|
||||
import io.smnp.type.model.Value
|
||||
import io.smnp.util.config.MapConfig
|
||||
|
||||
class MidiHelpFunction : Function("midiHelp") {
|
||||
override fun define(new: FunctionDefinitionTool) {
|
||||
@@ -58,7 +59,7 @@ class MidiHelpFunction : Function("midiHelp") {
|
||||
if (index > 0) {
|
||||
println(it)
|
||||
Midi
|
||||
.with(mapOf("bpm" to bpm))
|
||||
.with(MapConfig(mapOf(Value.string("bpm") to Value.int(bpm))))
|
||||
.play(mapOf(channel to listOf(listOf("i:$instrument", it))))
|
||||
Thread.sleep(100)
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package io.smnp.ext.midi
|
||||
|
||||
import io.smnp.util.config.MapConfig
|
||||
import java.io.File
|
||||
import javax.sound.midi.MidiSystem
|
||||
import javax.sound.midi.Sequence
|
||||
@@ -7,7 +8,6 @@ import javax.sound.midi.Sequencer
|
||||
|
||||
object Midi {
|
||||
private const val DEFAULT_PPQ = 1000
|
||||
private const val DEFAULT_BPM = 120
|
||||
private const val MIDI_FILE_TYPE = 1
|
||||
private val sequencer = MidiSystem.getSequencer()
|
||||
private val synthesizer = MidiSystem.getSynthesizer()
|
||||
@@ -28,38 +28,38 @@ object Midi {
|
||||
sequencer.stop()
|
||||
}
|
||||
|
||||
fun with(config: Map<String, Any>): SequenceExecutor {
|
||||
fun with(config: MapConfig): SequenceExecutor {
|
||||
return SequenceExecutor(sequencer, config)
|
||||
}
|
||||
|
||||
class SequenceExecutor(private val sequencer: Sequencer, private val config: Map<String, Any>) {
|
||||
class SequenceExecutor(private val sequencer: Sequencer, private val config: MapConfig) {
|
||||
fun play(lines: List<List<Any>>) {
|
||||
val sequence = Sequence(Sequence.PPQ, (config.getOrDefault("ppq", DEFAULT_PPQ) as Int))
|
||||
val sequence = Sequence(Sequence.PPQ, config.getUnwrappedOrDefault("ppq", DEFAULT_PPQ))
|
||||
provideCompiler(config).compileLines(lines, sequence)
|
||||
play(sequence)
|
||||
writeToFile(sequence)
|
||||
}
|
||||
|
||||
private fun provideCompiler(config: Map<String, Any>): SequenceCompiler =
|
||||
private fun provideCompiler(config: MapConfig): SequenceCompiler =
|
||||
if (config.containsKey("ppq")) PpqSequenceCompiler()
|
||||
else DefaultSequenceCompiler()
|
||||
|
||||
private fun play(sequence: Sequence) {
|
||||
(config.getOrDefault("play", true) as Boolean).takeIf { it }?.let {
|
||||
config.getUnwrappedOrDefault("play", true).takeIf { it }?.let {
|
||||
playSequence(sequence) {
|
||||
Midi.sequencer.tempoInBPM = (config.getOrDefault("bpm", DEFAULT_BPM) as Int).toFloat()
|
||||
sequencer.tempoInBPM = (config["bpm"].value as Int).toFloat()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun writeToFile(sequence: Sequence) {
|
||||
config.getOrDefault("output", null)?.let {
|
||||
MidiSystem.write(sequence, MIDI_FILE_TYPE, File(it as String))
|
||||
config.getUnwrappedOrDefault<String?>("output", null)?.let {
|
||||
MidiSystem.write(sequence, MIDI_FILE_TYPE, File(it))
|
||||
}
|
||||
}
|
||||
|
||||
fun play(channels: Map<Int, List<List<Any>>>) {
|
||||
val sequence = Sequence(Sequence.PPQ, (config.getOrDefault("ppq", DEFAULT_PPQ) as Int))
|
||||
val sequence = Sequence(Sequence.PPQ, config.getUnwrappedOrDefault("ppq", DEFAULT_PPQ))
|
||||
provideCompiler(config).compileChannels(channels, sequence)
|
||||
play(sequence)
|
||||
writeToFile(sequence)
|
||||
|
||||
Reference in New Issue
Block a user