Implement A-B looping based on measure - Android

This commit is contained in:
Hasinjato 2026-09-08 10:32:07 +03:00
parent 60c11b7ac8
commit 5b493e5b4e
3 changed files with 40 additions and 14 deletions

View file

@ -391,10 +391,9 @@ actual class FMediaPlayer actual constructor(
lastEventNano = System.nanoTime() lastEventNano = System.nanoTime()
// A-B loop // A-B loop
if (isLoopingAB && pointA >= 0 && pointB > pointA && if (isLoopingAB && pointA >= 0L && pointB > pointA && currentTickPos >= pointB) {
ticksToMs(currentTickPos) >= pointB) {
allNotesOff() allNotesOff()
currentTickPos = msToTicks(pointA) currentTickPos = pointA
clockNano = System.nanoTime() clockNano = System.nanoTime()
clockTick = currentTickPos clockTick = currentTickPos
idx = events.indexOfFirst { it.tickAbsolute >= currentTickPos } idx = events.indexOfFirst { it.tickAbsolute >= currentTickPos }
@ -992,13 +991,38 @@ actual class FMediaPlayer actual constructor(
startNavigationMonitor(sharedScreenModel) startNavigationMonitor(sharedScreenModel)
startSyncLoop(sharedScreenModel) startSyncLoop(sharedScreenModel)
} }
actual fun setPointA() { pointA = getCurrentPosition() } actual fun setPointA(grid: Int) {
actual fun setPointB() { val tick = grid.toLong() * resolution
pointB = getCurrentPosition() pointA = tick
if (pointB > pointA && pointA != -1L) isLoopingAB = true
val currentB = sharedScreenModel.loopingState.value.second
sharedScreenModel.updateLoopingState(grid, currentB)
} }
actual fun clearLoop() { isLoopingAB = false; pointA = -1L; pointB = -1L }
actual fun getLoopState() = Triple(pointA, pointB, isLoopingAB) actual fun setPointB(grid: Int) {
val tick = (((grid + 1).toDouble() * resolution) - 1.0).toLong()
pointB = tick.coerceAtLeast(0L)
val currentA = sharedScreenModel.loopingState.value.first
sharedScreenModel.updateLoopingState(currentA, grid)
if (currentA != -1) {
seekToGrid(currentA)
}
if (pointB > pointA && pointA != -1L) {
isLoopingAB = true
}
}
actual fun clearLoop() {
isLoopingAB = false
pointA = -1
pointB = -1
}
actual fun getLoopState() = Triple(pointA.toLong(), pointB.toLong(), isLoopingAB)
actual fun toggleVoice(index: Int) { applyVoiceStates() } actual fun toggleVoice(index: Int) { applyVoiceStates() }
private fun saveVoicesVolumes() { private fun saveVoicesVolumes() {
val data = voiceVolumes.joinToString(",") val data = voiceVolumes.joinToString(",")

View file

@ -639,7 +639,6 @@ fun LazyVerticalGridTUO(
val platform = getPlatform() val platform = getPlatform()
val isAndroid = platform.name.startsWith("Android") val isAndroid = platform.name.startsWith("Android")
val loopingState by sharedScreenModel.loopingState.collectAsState()
val activeIndex by sharedScreenModel.activeIndex.collectAsState() val activeIndex by sharedScreenModel.activeIndex.collectAsState()
val loopState by produceState(Triple(-1L, -1L, false), sharedScreenModel.mediaPlayer) { val loopState by produceState(Triple(-1L, -1L, false), sharedScreenModel.mediaPlayer) {
while (true) { while (true) {
@ -1011,7 +1010,8 @@ fun LazyVerticalGridTUO(
Row(modifier = Modifier.fillMaxWidth()) { Row(modifier = Modifier.fillMaxWidth()) {
measureTUOs.forEachIndexed { indexInMeasure, oneTUO -> measureTUOs.forEachIndexed { indexInMeasure, oneTUO ->
val globalIndex = (measureIndex * gridColumnCount) + indexInMeasure val globalIndex = (measureIndex * gridColumnCount) + indexInMeasure
val pointA = loopingState.first val loopingState by sharedScreenModel.loopingState.collectAsState()
val pointA = loopingState.first
val pointB = loopingState.second val pointB = loopingState.second
val isInABrange = if (pointA != -1 && pointB != -1) { val isInABrange = if (pointA != -1 && pointB != -1) {

View file

@ -445,11 +445,13 @@ class SharedScreenModel(private val fileRepository: FileRepository) : ScreenMode
} }
} }
private val _loopingState = MutableStateFlow(Pair(-1, -1)) data class LoopRange(val first: Int = -1, val second: Int = -1)
val loopingState: StateFlow<Pair<Int, Int>> = _loopingState.asStateFlow()
private val _loopingState = MutableStateFlow(LoopRange())
val loopingState: StateFlow<LoopRange> = _loopingState.asStateFlow()
fun updateLoopingState(a: Int, b: Int) { fun updateLoopingState(a: Int, b: Int) {
_loopingState.value = Pair(a, b) _loopingState.value = LoopRange(a, b)
} }
fun calculateSmartPointB(rawPointB: Int, isZeroIndexed: Boolean = false): Int { fun calculateSmartPointB(rawPointB: Int, isZeroIndexed: Boolean = false): Int {