From 2ec69a8b13480d78acfe38a5a79d786a498e8eab Mon Sep 17 00:00:00 2001 From: Hasinjato Date: Fri, 10 Jul 2026 16:05:32 +0300 Subject: [PATCH] Update metronome count-in by time measure --- .../kotlin/mg/dot/feufaro/midi/MidiPlayer.kt | 53 ++++++++++++++----- .../kotlin/mg/dot/feufaro/midi/MidiPlayer.kt | 39 +++++++++++--- 2 files changed, 73 insertions(+), 19 deletions(-) diff --git a/composeApp/src/androidMain/kotlin/mg/dot/feufaro/midi/MidiPlayer.kt b/composeApp/src/androidMain/kotlin/mg/dot/feufaro/midi/MidiPlayer.kt index 6e48484..8545870 100644 --- a/composeApp/src/androidMain/kotlin/mg/dot/feufaro/midi/MidiPlayer.kt +++ b/composeApp/src/androidMain/kotlin/mg/dot/feufaro/midi/MidiPlayer.kt @@ -680,18 +680,49 @@ 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) { - midiDriver.write(noteOnEvent) - delay(100) - midiDriver.write(noteOffEvent) + val noteOnSnare = byteArrayOf(0x99.toByte(), 38.toByte(), velocity.toByte()) + val noteOffSnare = byteArrayOf(0x89.toByte(), 38.toByte(), 0.toByte()) - delay((beatDurationMs - 100).coerceAtLeast(0L)) + 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) { @@ -780,11 +811,7 @@ actual class FMediaPlayer actual constructor( } actual fun getVoiceVolumes(): List = 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 { val gmInstruments = listOf( 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 6fb7a6c..a5247a9 100644 --- a/composeApp/src/desktopMain/kotlin/mg/dot/feufaro/midi/MidiPlayer.kt +++ b/composeApp/src/desktopMain/kotlin/mg/dot/feufaro/midi/MidiPlayer.kt @@ -679,14 +679,41 @@ 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) { - metronomeChannel?.noteOn(noteEvent, velocity) - delay(100) - metronomeChannel?.noteOff(noteEvent) + val isEvenMeasure = adjustedMeasure in setOf(2, 4, 8) - delay((beatDurationMs - 100).coerceAtLeast(0L)) + 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) {