feat: управление яркостью/WiFi очков через Mercury + накопленные доработки
- Mercury (app-phone): управление яркостью (с авто-выкл. перед применением) и WiFi (скан/подключение/список сетей с паролем); добавлено право BLUETOOTH_ADVERTISE в манифест и runtime-запрос (без него GATT-сервер не рекламируется → очки не подключаются) - логирование (lib-core core.log): BatchingLogCollector + LogSink + LogSpool + LokiLogSink; цепочка очки→телефон→Loki; lib-core log() переадресован в коллектор - STT: Qwen3-ASR через pw.binom.asr:asr-qwen3-android, убран in-house whisper-фоллбек - audio-sync: P-регулятор с насыщением вместо фиксированной скорости - media-split: очки только video, телефон только audio (UI-чипы) - Components: форматирование размера через Locale.ROOT
This commit is contained in:
@@ -33,7 +33,7 @@ class AudioSyncPlayerTest {
|
||||
@Test
|
||||
fun speedsUpWhenAudioLagsBehind() {
|
||||
val d = decideSync(audioPosition = 10_000, videoPosition = 10_300, audioPlaying = true, videoPlaying = true)
|
||||
assertEquals(1f + DRIFT_RATE, d.speed, "звук отстаёт — догоняем ускорением ${1f + DRIFT_RATE}")
|
||||
assertEquals(1f + 300f * DRIFT_GAIN, d.speed, "звук отстаёт — догоняем ускорением ${1f + 300f * DRIFT_GAIN}")
|
||||
assertNull(d.seekToMs, "diff=300мс внутри HARD-порога — seek не нужен")
|
||||
assertNull(d.playing)
|
||||
}
|
||||
@@ -41,9 +41,22 @@ class AudioSyncPlayerTest {
|
||||
@Test
|
||||
fun slowsDownWhenAudioAhead() {
|
||||
val d = decideSync(audioPosition = 10_300, videoPosition = 10_000, audioPlaying = true, videoPlaying = true)
|
||||
assertEquals(1f - DRIFT_RATE, d.speed, "звук впереди — тормозим до ${1f - DRIFT_RATE}")
|
||||
assertEquals(1f - 300f * DRIFT_GAIN, d.speed, "звук впереди — тормозим до ${1f - 300f * DRIFT_GAIN}")
|
||||
assertNull(d.seekToMs)
|
||||
assertNull(d.playing)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun smallDriftJustOutsideBandIsProportional() {
|
||||
val d = decideSync(audioPosition = 10_151, videoPosition = 10_000, audioPlaying = true, videoPlaying = true)
|
||||
assertEquals(1f - 151f * DRIFT_GAIN, d.speed, "diff=151мс (чуть за зоной) — слабый пропорциональный темп")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun speedSaturatesAtMaxDrift() {
|
||||
val behind = decideSync(audioPosition = 9_000, videoPosition = 10_000, audioPlaying = true, videoPlaying = true)
|
||||
assertEquals(1f + MAX_DRIFT_SPEED, behind.speed, "diff=−1000мс → 1+0.2 упирается в потолок ${1f + MAX_DRIFT_SPEED}")
|
||||
val ahead = decideSync(audioPosition = 11_000, videoPosition = 10_000, audioPlaying = true, videoPlaying = true)
|
||||
assertEquals(1f - MAX_DRIFT_SPEED, ahead.speed, "diff=+1000мс → 1−0.2 упирается в потолок ${1f - MAX_DRIFT_SPEED}")
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -73,7 +86,7 @@ class AudioSyncPlayerTest {
|
||||
fun hardThresholdBoundaryDoesNotSeek() {
|
||||
val d = decideSync(audioPosition = 10_000, videoPosition = 12_000, audioPlaying = true, videoPlaying = true)
|
||||
assertNull(d.seekToMs, "diff=2000мс не БОЛЬШЕ порога — подгоняем скоростью, без рывка")
|
||||
assertEquals(1f + DRIFT_RATE, d.speed)
|
||||
assertEquals(1f + MAX_DRIFT_SPEED, d.speed, "diff=2000мс → 1+0.4 — упирается в потолок ${1f + MAX_DRIFT_SPEED}")
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
Reference in New Issue
Block a user