Remember volume per voices [satb] - for desktop

This commit is contained in:
hasinarak3@gmail.com 2026-02-18 10:44:24 +03:00
parent 84a9626b08
commit e6af7bd39e
4 changed files with 33 additions and 56 deletions

View file

@ -15,7 +15,7 @@ private var androidMediaPlayer: MediaPlayer?= null
actual class FMediaPlayer actual constructor(val filename: String, onFinished: () -> Unit) {
private var mediaPlayer: android.media.MediaPlayer? = android.media.MediaPlayer()
private val voiceStates = mutableListOf(true, true, true, true)
// private val voiceStates = mutableListOf(true, true, true, true)
private val midiFileName = filename
// private var currentGlobalVolume: Float = 0.8f
@ -132,11 +132,12 @@ actual fun setVolume(level: Float) {
actual fun getLoopState() = Triple(pointA, pointB, isLoopingAB)
actual fun toggleVoice(index: Int) {
voiceStates[index] = !voiceStates[index]
// voiceStates[index] = !voiceStates[index]
println("Toggle voice $index (Limitation: Nécessite SoundFont/Fluidsynth sur Android)")
}
actual fun getVoiceStates(): List<Boolean> = voiceStates
// actual fun getVoiceStates(): List<Boolean> = voiceStates
actual fun getVoiceVolumes(): List<Float> = MutableList(4) { 127f }
actual fun changeInstru(noInstru: Int) {
}

View file

@ -9,7 +9,7 @@ expect class FMediaPlayer(filename: String, onFinished: () -> Unit) {
fun getDuration(): Long
fun getLoopState(): Triple<Long, Long, Boolean>
fun toggleVoice(index: Int)
fun getVoiceStates(): List<Boolean>
fun getVoiceVolumes(): List<Float>
fun changeInstru(noInstru: Int)
fun getCurrentPosition(): Long
fun seekTo(position: Long)

View file

@ -64,9 +64,8 @@ fun MidiControlPanel(
}
}
val voiceStates = mediaPlayer.getVoiceStates()
val sliderVolumes = remember {
mutableStateListOf(127f, 127f, 127f, 127f)
mediaPlayer.getVoiceVolumes().map { mutableStateOf(it) }.toMutableStateList()
}
val labels = listOf("S", "A", "T", "B")
listOf("Soprano", "Alto", "Ténor", "Basse")
@ -201,9 +200,9 @@ fun MidiControlPanel(
contentAlignment = Alignment.Center
) {
Slider(
value = sliderVolumes[i],
value = sliderVolumes[i].value,
onValueChange = { newValue ->
sliderVolumes[i] = newValue
sliderVolumes[i].value = newValue
mediaPlayer.updateVoiceVolume(i, newValue)
},
valueRange = 0f..126f,
@ -234,22 +233,6 @@ fun MidiControlPanel(
)
}
}
/*Row(
modifier = Modifier.padding(vertical = 8.dp),
horizontalArrangement = Arrangement.spacedBy(4.dp)
) {
labels.forEachIndexed { index, label ->
FilterChip(
selected = voiceStates[index],
onClick = { mediaPlayer.toggleVoice(index) },
label = { Text(label) },
colors = FilterChipDefaults.filterChipColors(
selectedContainerColor = MaterialTheme.colorScheme.primaryContainer,
selectedLabelColor = MaterialTheme.colorScheme.primary
)
)
}
}*/
}
}
AnimatedVisibility(

View file

@ -2,13 +2,11 @@ package mg.dot.feufaro.midi
import kotlinx.coroutines.*
import mg.dot.feufaro.getConfigDirectoryPath
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.sampled.AudioFormat
import javax.sound.sampled.AudioSystem
import javax.sound.sampled.FloatControl
@ -31,7 +29,6 @@ actual class FMediaPlayer actual constructor(
private var pointB: Long = -1L
private var isLoopingAB: Boolean = false
private val voiceStates = mutableListOf(true, true, true, true)
private val voiceVolumes = FloatArray(4) { 127f }
private var currentGlobalVolume: Float = 0.8f
@ -53,7 +50,7 @@ actual class FMediaPlayer actual constructor(
val file = File(filename)
if (file.exists()){
sequencer?.sequence = MidiSystem.getSequence(file)
loadVoiceStates()
loadVoiceVolumes()
applyVoiceStates()
sequencer?.addMetaEventListener { meta ->
if(meta.type == 47){
@ -103,7 +100,7 @@ actual class FMediaPlayer actual constructor(
synthetizer?.channels?.forEachIndexed { index, channel ->
if (index < 4) {
val vol = if (voiceStates[index]) volumeInt else 0
val vol = if (voiceVolumes[index] != 0f) volumeInt else 0
channel?.controlChange(7, vol)
} else {
channel?.controlChange(7, volumeInt)
@ -158,13 +155,13 @@ actual class FMediaPlayer actual constructor(
actual fun getLoopState() = Triple(pointA, pointB, isLoopingAB)
actual fun toggleVoice(index: Int) {
voiceStates[index] = !voiceStates[index]
saveVoiceStates()
saveVoicesVolumes()
applyVoiceStates()
}
actual fun updateVoiceVolume(voiceIndex: Int, newVolume: Float) {
if (voiceIndex in 0..3) {
voiceVolumes[voiceIndex] = newVolume
saveVoicesVolumes()
applyVoiceStates()
}
}
@ -174,26 +171,22 @@ actual class FMediaPlayer actual constructor(
synthetizer?.channels?.let { channels ->
for (i in 0 until 4) {
if (i < channels.size) {
val volume = voiceVolumes[i].toInt()
val isVoiceActive = voiceStates[i]
val currentVolume = voiceVolumes[i].toInt()
val targetVolume = voiceVolumes[i].toInt()
if (volume == 0) {
channels[i].controlChange(7, targetVolume)
channels[i].controlChange(11, targetVolume)
if (targetVolume == 0) {
channels[i].controlChange(123, 0)
voiceStates[i] = false
} else {
channels[i].controlChange(7, currentVolume)
channels[i].controlChange(11, currentVolume)
voiceStates[i] = true
}
}
println("SATB màj: $voiceStates, Volumes: ${voiceVolumes[i]}")
println("SATB $i Volumes: ${voiceVolumes[i]}")
}
}
} catch (e: Exception) { e.printStackTrace() }
}
actual fun getVoiceStates(): List<Boolean> = voiceStates
actual fun getVoiceVolumes(): List<Float> = voiceVolumes.toList()
actual fun changeInstru(noInstru: Int) {
val pgm = noInstru
@ -230,19 +223,19 @@ actual class FMediaPlayer actual constructor(
}
}
private fun saveVoiceStates() {
val data = voiceStates.joinToString(",")
prefs.put("voice_states", data)
private fun saveVoicesVolumes() {
val data = voiceVolumes.joinToString(",")
prefs.put("voices_volumes", data)
}
private fun loadVoiceStates() {
val defaultValue = "true,true,true,true"
val savedData = prefs.get("voice_states", defaultValue)
private fun loadVoiceVolumes() {
val data = prefs.get("voices_volumes", "127,127,127,127")
val volumesArray = data.split(",")
val states = savedData.split(",").map { it.toBoolean() }
if (volumesArray.size == 4) {
for (i in 0 until 4) {
if (i < states.size) voiceStates[i] = states[i]
voiceVolumes[i] = volumesArray[i].toFloatOrNull() ?: 127f
}
}
}
}