Back to 0 on DC and stop on 'Farany' label

This commit is contained in:
hasinarak3@gmail.com 2026-03-16 14:23:52 +03:00
parent 249f0200fb
commit 6124b8d0b2
2 changed files with 67 additions and 7 deletions

View file

@ -211,10 +211,24 @@ class SharedScreenModel(private val fileRepository: FileRepository) : ScreenMode
val isDC = markerText.contains(Regex("""D\.?C\.?"""))
val isDS = markerText.contains(Regex("""D\.?S\.?"""))
val isFarany = markerText.trim().equals("Farany", ignoreCase = true)
var resultMarker: MidiMarkers = marker
if (isDC) {
if(isFarany) {
var forwardIndex = index
while (forwardIndex < tuos.size) {
val sep = tuos.getOrNull(forwardIndex)?.sep0 ?: ""
if (sep == "/") {
resultMarker = marker.copy(
gridIndex = forwardIndex - 1,
marker = "Farany_GROUP_PART"
)
println("Farany finalisé : grille $index${forwardIndex - 1}")
break
}
forwardIndex++
}
} else if (isDC) {
var forwardIndex = index
while (forwardIndex < tuos.size) {
val currentTuo = tuos.getOrNull(forwardIndex)
@ -299,7 +313,7 @@ class SharedScreenModel(private val fileRepository: FileRepository) : ScreenMode
// _isPos.value = true
// _isPlay.value = false
_currentPos.value = 0f
seekTo(0f)
seekToGrid(0)
_mediaPlayer?.stop()
setDcDone(false)
setDsDone(false)

View file

@ -3,16 +3,13 @@ package mg.dot.feufaro.midi
import SharedScreenModel
import kotlinx.coroutines.*
import mg.dot.feufaro.getConfigDirectoryPath
import mg.dot.feufaro.viewmodel.MidiMarkers
import java.io.File
import java.util.prefs.Preferences
import javax.sound.midi.MetaMessage
import javax.sound.midi.MidiSystem
import javax.sound.midi.Sequence
import javax.sound.midi.Sequencer
import javax.sound.midi.ShortMessage
import javax.sound.midi.Synthesizer
import javax.sound.midi.Track
import javax.sound.sampled.AudioSystem
import javax.sound.sampled.FloatControl
@ -59,6 +56,8 @@ actual class FMediaPlayer actual constructor(
val hairPinEndGrid: Int = -1,
val hairPinFromFactor: Float = 1.0f,
val hairPinToFactor: Float = 1.0f,
val isFin: Boolean = false, // Farany D.C.
var finActive: Boolean =false,
)
private val navigationSteps = mutableListOf<NavigationStep>()
@ -84,9 +83,13 @@ actual class FMediaPlayer actual constructor(
applyVoiceStates()
sequencer?.addMetaEventListener { meta ->
if(meta.type == 47){
val totalGrids = (sequencer!!.sequence.tickLength / sequencer!!.sequence.resolution).toInt()
val currentGrid = (sequencer!!.tickPosition / sequencer!!.sequence.resolution).toInt()
val pendingDc = getPendingDcStep()
if (pendingDc != null) {
val isDcNearEnd = pendingDc != null && (totalGrids - pendingDc.gridIndex) <= 2
if (isDcNearEnd && pendingDc != null) {
println("onFinished : DC pending → saut direct vers ${pendingDc.targetGrid}")
pendingDc.alreadyDone = true
seekToGrid(pendingDc.targetGrid)
@ -281,6 +284,27 @@ actual class FMediaPlayer actual constructor(
println("Lien DC créé : $marker à $indx vers le début")
}
// Farany
marker.trim().equals("Farany_GROUP_PART", ignoreCase = true) -> {
val hasDcAfter = metadataList.any { (_, gi, _, _, mk, _, _, _) ->
(gi ?: 0) > currentIndex &&
(dcGPattern.matches(mk.trim()) ||
dcRegex.matches(mk.trim()))
}
if (hasDcAfter) {
navigationSteps.add(
NavigationStep(
marker = marker,
gridIndex = currentIndex,
targetGrid = last_grid,
isFin = true,
finActive = false
)
)
println("Farany mémorisé à la grille $currentIndex")
}
}
// velocité
extractDynamic(marker) != null && marker.trim() != "=" -> {
val dyn = extractDynamic(marker) ?: return@forEach
@ -362,6 +386,7 @@ actual class FMediaPlayer actual constructor(
step.hairPin == null &&
step.dynamic == null &&
!step.isHold
&& !step.isFin
}
}
private fun startNavigationMonitor(sharedScreenModel: SharedScreenModel) {
@ -389,6 +414,19 @@ actual class FMediaPlayer actual constructor(
if (step != null) {
when {
step.isFin -> {
if(step.finActive) {
step.alreadyDone = true
// println("Farany passage → FIN à grille $currentIndex")
sequencer?.stop()
sequencer?.tempoFactor = 1f
synthetizer?.channels?.forEach {
it?.controlChange(64, 0)
it?.controlChange(123, 0)
}
onFinished()
}
}
// Point d'orgue
step.isHold -> {
val currentBpm = sequencer?.tempoInBPM ?: targetBpm
@ -443,6 +481,14 @@ actual class FMediaPlayer actual constructor(
seekToGrid(step.targetGrid)
synthetizer?.channels?.forEach { it?.controlChange(64, 0) }
sequencer?.tempoFactor = 1f
navigationSteps.filter { it.isFin }.forEach { faranyStep ->
if (step.gridIndex > faranyStep.gridIndex) {
faranyStep.finActive = true
faranyStep.alreadyDone = false
}
}
if (sequencer?.isRunning == false) {
sequencer?.tempoInBPM = targetBpm
sequencer?.start()