Implement A-B looping based on measure - Android
This commit is contained in:
parent
60c11b7ac8
commit
5b493e5b4e
3 changed files with 40 additions and 14 deletions
|
|
@ -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(",")
|
||||||
|
|
|
||||||
|
|
@ -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) {
|
||||||
|
|
|
||||||
|
|
@ -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 {
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue