Update metronome count-in by time measure

This commit is contained in:
Hasinjato 2026-07-10 16:05:32 +03:00
parent 5f8e0e03a7
commit 2ec69a8b13
2 changed files with 73 additions and 19 deletions

View file

@ -680,20 +680,51 @@ actual class FMediaPlayer actual constructor(
else -> originalMeasure
}
val anacrouseBeats = nbSilent / 4
val totalBeats = if (anacrouseBeats > 5) anacrouseBeats else adjustedMeasure + anacrouseBeats
// println("Android Décompte total : $totalBeats bips ($adjustedMeasure de préparation + $anacrouseBeats d'anacrouse) à $bpm BPM")
val noteOnEvent = byteArrayOf(0x99.toByte(), noteEvent.toByte(), velocity.toByte())
val noteOffEvent = byteArrayOf(0x89.toByte(), noteEvent.toByte(), 0.toByte())
for (i in 1..totalBeats) {
val noteOnSnare = byteArrayOf(0x99.toByte(), 38.toByte(), velocity.toByte())
val noteOffSnare = byteArrayOf(0x89.toByte(), 38.toByte(), 0.toByte())
val isEvenMeasure = adjustedMeasure in setOf(2, 4, 8)
if (isEvenMeasure) {
for (i in 1..2) {
midiDriver.write(noteOnEvent)
delay(100)
midiDriver.write(noteOffEvent)
val slowDuration = beatDurationMs * 2
delay((slowDuration - 100).coerceAtLeast(0L))
}
val remainingBeats = if (anacrouseBeats == 0) 4 else anacrouseBeats
for (i in 1..remainingBeats) {
val onBytes = if (i == remainingBeats) noteOnSnare else noteOnEvent
val offBytes = if (i == remainingBeats) noteOffSnare else noteOffEvent
midiDriver.write(onBytes)
delay(100)
midiDriver.write(offBytes)
delay((beatDurationMs - 100).coerceAtLeast(0L))
}
} else {
val totalBeats = if (anacrouseBeats > 5) anacrouseBeats else adjustedMeasure + anacrouseBeats
// println("Android dcompte total : $totalBeats bips ($adjustedMeasure de préparation + $anacrouseBeats d'anacrouse) à $bpm BPM")
for (i in 1..totalBeats) {
val onBytes = if (i == adjustedMeasure) noteOnSnare else noteOnEvent
val offBytes = if (i == adjustedMeasure) noteOffSnare else noteOffEvent
midiDriver.write(onBytes)
delay(100)
midiDriver.write(offBytes)
delay((beatDurationMs - 100).coerceAtLeast(0L))
}
}
withContext(Dispatchers.Main) {
applyVoiceStates()
startPlaybackLoop()
@ -780,11 +811,7 @@ actual class FMediaPlayer actual constructor(
}
actual fun getVoiceVolumes(): List<Float> = voiceVolumes.toList()
actual fun changeInstru(noInstru: Int) {
val buffer = byteArrayOf(
(0xC0 or 0).toByte(),
noInstru.toByte()
)
midiDriver.write(buffer)
for (ch in 0 until 4) send(0xC0 or ch, noInstru)
}
actual fun getAvalaibleInstruments(): List<MidiInstrument> {
val gmInstruments = listOf(

View file

@ -679,16 +679,43 @@ actual class FMediaPlayer actual constructor(
val anacrouseBeats = nbSilent / 4
val totalBeats = if(anacrouseBeats > 5) anacrouseBeats else adjustedMeasure + anacrouseBeats
// println("Décompte total : $totalBeats bips ($adjustedMeasure de préparation + $anacrouseBeats d'anacrouse [$nbSilent / $4 ]) à $bpm BPM")
println("Décompte total : $totalBeats bips ($adjustedMeasure de préparation + $anacrouseBeats d'anacrouse [$nbSilent / $4 ]) à $bpm BPM")
for (i in 1..totalBeats) {
val isEvenMeasure = adjustedMeasure in setOf(2, 4, 8)
if (isEvenMeasure) {
for (i in 1..2) {
metronomeChannel?.noteOn(noteEvent, velocity)
delay(100)
metronomeChannel?.noteOff(noteEvent)
val slowDuration = beatDurationMs * 2
delay((slowDuration - 100).coerceAtLeast(0L))
}
val remainingBeats = if(anacrouseBeats == 0) 4 else anacrouseBeats
for (i in 1..remainingBeats) {
val currentNote = if (i == remainingBeats) 38 else noteEvent
metronomeChannel?.noteOn(currentNote, velocity)
delay(100)
metronomeChannel?.noteOff(currentNote)
delay((beatDurationMs - 100).coerceAtLeast(0L))
}
} else {
for (i in 1..totalBeats) {
val currentNote = if (i == adjustedMeasure) 38 else noteEvent
metronomeChannel?.noteOn(currentNote, velocity)
delay(100)
metronomeChannel?.noteOff(currentNote)
delay((beatDurationMs - 100).coerceAtLeast(0L))
}
}
withContext(Dispatchers.Main) {
startMidiPlayback()
}