Clarify stream grid and PCM timeline contracts without per-record allocations

This commit is contained in:
evgeny committed 2026-10-29 13:34:24 +01:00
1 parent ffa5dece4f
commit 97f1eaa048
3 files changed
+12 -4

No files matched your search

@@ -5,7 +5,9 @@ import kotlin.math.max
import kotlin.math.min
import kotlin.math.roundToInt
/** Начало отдельного источника на шкале общего AudioTrack. PTS источников здесь не сравниваются. */
/** Worker-локальное начало источника на шкале AudioTrack, позиции/count — PCM frames, не stereo samples.
* append требует непрерывные порции, включая тишину источника; первый append фиксирует origin.
* played переводит общий head в локальные [0, frames]. Новая шкала требует нового экземпляра, PTS здесь не сравниваются. */
internal class StreamMixTimeline {
var origin = -1L
private set
@@ -23,7 +25,10 @@ internal class StreamMixTimeline {
}
/** Одна порция stereo 48k. Тихий новый участник не снижает громкость остальных.
* Буфер output переиспользуется только после полной записи предыдущей порции устройством. */
* frames=480 по умолчанию (10 мс), count у add — только подготовленный prefix PCM.
* fadeFrames=0..480 задаёт фазу 10 мс fade-in; add возвращает обновлённую фазу.
* clear очищает сумму, сохраняя состояние stereo limiter; finish возвращает переиспользуемый буфер,
* который разрешено менять только после полной записи предыдущей порции устройством. */
internal class StreamMixBuffer(val frames: Int = 480) {
private val sum = FloatArray(frames * 2)
private val output = ShortArray(frames * 2)
@@ -4,7 +4,9 @@ import kotlin.math.min
internal data class StreamGridShape(val columns: Int, val rows: Int)
/** Максимизирует видимую площадь видео; портретный экран не принуждается к квадратной сетке. */
/** Выбрать сетку для count одинаковых видео: максимальная суммарная площадь при заданном aspect.
* При равной площади выбирает меньше пустых ячеек; размеры/aspect — конечные, aspect > 0.
* Неположительные count/размеры дают 1x1. Возвращает только форму, без UI размеров/зазоров. */
internal fun streamGridShape(count: Int, width: Double, height: Double, aspect: Double = 16.0 / 9): StreamGridShape {
if (count <= 0 || width <= 0 || height <= 0) return StreamGridShape(1, 1)
var best = StreamGridShape(1, count)
@@ -29,7 +29,8 @@ internal class StreamReadQueue {
input.position(start + 28 + length)
}
for (record in parsed) {
if (record[0].toInt() in listOf(3, 6)) records.clear()
val kind = record[0].toInt()
if (kind == 3 || kind == 6) records.clear()
records.add(record)
}
return parsed.size