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()
// A-B loop
if (isLoopingAB && pointA >= 0 && pointB > pointA &&
ticksToMs(currentTickPos) >= pointB) {
if (isLoopingAB && pointA >= 0L && pointB > pointA && currentTickPos >= pointB) {
allNotesOff()
currentTickPos = msToTicks(pointA)
currentTickPos = pointA
clockNano = System.nanoTime()
clockTick = currentTickPos
idx = events.indexOfFirst { it.tickAbsolute >= currentTickPos }
@ -992,13 +991,38 @@ actual class FMediaPlayer actual constructor(
startNavigationMonitor(sharedScreenModel)
startSyncLoop(sharedScreenModel)
}
actual fun setPointA() { pointA = getCurrentPosition() }
actual fun setPointB() {
pointB = getCurrentPosition()
if (pointB > pointA && pointA != -1L) isLoopingAB = true
actual fun setPointA(grid: Int) {
val tick = grid.toLong() * resolution
pointA = tick
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() }
private fun saveVoicesVolumes() {
val data = voiceVolumes.joinToString(",")

View file

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

View file

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