Remember volume per voices [satb] - for desktop
This commit is contained in:
parent
84a9626b08
commit
e6af7bd39e
4 changed files with 33 additions and 56 deletions
|
|
@ -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) {
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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(
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
}
|
||||
}
|
||||
|
|
@ -172,28 +169,24 @@ actual class FMediaPlayer actual constructor(
|
|||
private fun applyVoiceStates() {
|
||||
try {
|
||||
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()
|
||||
for (i in 0 until 4) {
|
||||
if (i < channels.size) {
|
||||
val targetVolume = voiceVolumes[i].toInt()
|
||||
|
||||
if (volume == 0) {
|
||||
channels[i].controlChange(123, 0)
|
||||
voiceStates[i] = false
|
||||
} else {
|
||||
channels[i].controlChange(7, currentVolume)
|
||||
channels[i].controlChange(11, currentVolume)
|
||||
voiceStates[i] = true
|
||||
channels[i].controlChange(7, targetVolume)
|
||||
channels[i].controlChange(11, targetVolume)
|
||||
|
||||
if (targetVolume == 0) {
|
||||
channels[i].controlChange(123, 0)
|
||||
}
|
||||
}
|
||||
println("SATB $i Volumes: ${voiceVolumes[i]}")
|
||||
}
|
||||
println("SATB màj: $voiceStates, 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() }
|
||||
for (i in 0 until 4) {
|
||||
if (i < states.size) voiceStates[i] = states[i]
|
||||
if (volumesArray.size == 4) {
|
||||
for (i in 0 until 4) {
|
||||
voiceVolumes[i] = volumesArray[i].toFloatOrNull() ?: 127f
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
Loading…
Add table
Reference in a new issue