From 64c94b4064b8b91a94cd0cfd431f31a4d1c7407a Mon Sep 17 00:00:00 2001 From: hasina Date: Mon, 19 Jan 2026 14:53:39 +0300 Subject: [PATCH] Remember voice states SATB --- .../kotlin/mg/dot/feufaro/midi/MidiPlayer.kt | 45 +++++++++---------- 1 file changed, 21 insertions(+), 24 deletions(-) diff --git a/composeApp/src/desktopMain/kotlin/mg/dot/feufaro/midi/MidiPlayer.kt b/composeApp/src/desktopMain/kotlin/mg/dot/feufaro/midi/MidiPlayer.kt index e3de7f2..b6625fe 100644 --- a/composeApp/src/desktopMain/kotlin/mg/dot/feufaro/midi/MidiPlayer.kt +++ b/composeApp/src/desktopMain/kotlin/mg/dot/feufaro/midi/MidiPlayer.kt @@ -6,15 +6,14 @@ import kotlinx.coroutines.launch import mg.dot.feufaro.FileRepository import java.io.ByteArrayInputStream import java.io.File +import java.util.prefs.Preferences import javax.sound.midi.MidiSystem import javax.sound.midi.Sequencer -import javax.sound.midi.Synthesizer //import javax.sound.midi.ShortMessage -//import javax.sound.midi.Synthesizer +import javax.sound.midi.Synthesizer import javax.sound.sampled.AudioFormat import javax.sound.sampled.AudioSystem import javax.sound.sampled.FloatControl -//private var sequencer: javax.sound.midi.Sequencer?= null actual class MediaPlayer actual constructor( private val filename: String, private val onFinished: () -> Unit @@ -27,6 +26,7 @@ actual class MediaPlayer actual constructor( null } + private val prefs = Preferences.userRoot().node("mg.dot.feufaro") private var synthetizer = MidiSystem.getSynthesizer() as Synthesizer? private var pointA: Long = -1L @@ -53,6 +53,7 @@ actual class MediaPlayer actual constructor( val file = File(filename) if (file.exists()){ sequencer?.sequence = MidiSystem.getSequence(file) + loadVoiceStates() applyVoiceStates() sequencer?.addMetaEventListener { meta -> if(meta.type == 47){ @@ -103,16 +104,6 @@ actual class MediaPlayer actual constructor( channel?.controlChange(7, volumeInt) } } - /*val logVolume = if (level > 0 ){ - (Math.log10(level.toDouble() * 9 + 1) / Math.log10(10.0)).toFloat() - } else { - 0f - } - val volumeInt = (logVolume * 127).toInt().coerceIn(0, 127) - - synthetizer?.channels?.forEach { it?.controlChange(7, volumeInt) } - synthetizer?.channels?.forEach { it?.controlChange(11, volumeInt) } -*/ val mixer = AudioSystem.getMixer(null) val lines = mixer.sourceLines for (line in lines) { @@ -124,14 +115,6 @@ actual class MediaPlayer actual constructor( } } -// val msg = ShortMessage() -// val receiver = sequencer?.receiver -// for (i in 0 until 16) { -// val msg = ShortMessage() -// msg.setMessage(ShortMessage.CONTROL_CHANGE, i, 7, volumeInt) -// receiver?.send(msg, -1) -// } - } catch (e: Exception){ e.printStackTrace() } @@ -170,6 +153,7 @@ actual class MediaPlayer actual constructor( actual fun toggleVoice(index: Int) { voiceStates[index] = !voiceStates[index] + saveVoiceStates() applyVoiceStates() } @@ -204,11 +188,8 @@ actual class MediaPlayer actual constructor( } } actual fun getCurrentBPM(): Float { -// return sequencer?.tempoInBPM?.toInt() ?: 0 val currentFactor = sequencer?.tempoFactor ?: 1.0f -// val currentBPM = sequencer?.tempoInBPM ?: 120.0f val currentBPM = (120f * currentFactor) -// println("202: ${sequencer?.tempoInBPM} ${sequencer?.tempoFactor} ${sequencer?.tempoInMPQ}") return currentBPM } @@ -231,4 +212,20 @@ actual class MediaPlayer actual constructor( e.printStackTrace() } } + + private fun saveVoiceStates() { + val data = voiceStates.joinToString(",") + prefs.put("voice_states", data) + } + + private fun loadVoiceStates() { + val defaultValue = "true,true,true,true" + val savedData = prefs.get("voice_states", defaultValue) + + val states = savedData.split(",").map { it.toBoolean() } + for (i in 0 until 4) { + if (i < states.size) voiceStates[i] = states[i] + } + } + } \ No newline at end of file