feat: голосовой ввод на очках — TripleClick + PCM → телефон → текст на очки
Протокол: SttAudio (PCM s16 16k mono кусками), SttPhrase/SttDone/SttCancel
(host→очки), StopStt(cancel) (очки→host).
Очки: TripleClick — безусловный вызов (кино: пауза + затемнение + слушаем);
во время распознавания Click — завершить (весь текст в консоль, затемнение
уходит, видео на паузе), DoubleClick — отмена; VAD-тишина 30с — автоотмена.
Микрофон (AudioRecord 16k) → SttAudio; на эмуляторе — PCM из filesDir/samples
(куски 3200 + пауза 200мс). Оверлей текста в Binocular (полупрозрачный фон,
текст по центру, в оба глаза). RECORD_AUDIO в манифесте. DEBUG-ресивер
(am broadcast DEBUG_GESTURE type=triple_click|click|double_click).
Телефон: SttStreamer — стриминговый VAD (Silero fp32, окна 512) → фразы →
Whisper-small int8 (executor, не блокирует приём) → SttPhrase на очки;
StopStt → SttDone (полный текст) / SttCancel; watchdog 30с тишины.
Фиксы (найдены на эмуляторе): IllegalThreadStateException — двойной старт
watchdog-потока (thread{}.apply{start()}); decode входящих — try/catch с
логом (не роняет сессию).
Проверено на эмуляторах (5554 очки + 5556 телефон, forward 8080):
triple_click → фразы «Раз, два» и «3 4 5» на очках (оверлей) → click →
«ВЕСЬ ТЕКСТ: Раз, два 3 4 5»; 30с-тишина → «отменено». Тесты: lib-core,
phone, glasses — зелёные.
This commit is contained in:
@@ -32,6 +32,9 @@ import pw.binom.viewmate.core.protocol.PlaybackPosition
|
||||
import pw.binom.viewmate.core.protocol.SetMode
|
||||
import pw.binom.viewmate.core.protocol.SetScale
|
||||
import pw.binom.viewmate.core.protocol.ShowText
|
||||
import pw.binom.viewmate.core.protocol.SttCancel
|
||||
import pw.binom.viewmate.core.protocol.SttDone
|
||||
import pw.binom.viewmate.core.protocol.SttPhrase
|
||||
import pw.binom.viewmate.core.protocol.Welcome
|
||||
|
||||
/**
|
||||
@@ -267,6 +270,21 @@ class HostConnection(
|
||||
is ShowText -> addMessage("ShowText: ${msg.text}")
|
||||
|
||||
is ChatSessionMsg -> addMessage("ChatSession: ${msg.sessionId} — ${msg.title}")
|
||||
|
||||
is SttPhrase -> {
|
||||
GlassesApp.instance.sttText.value = msg.full
|
||||
log("stt", "фраза: ${msg.phrase}")
|
||||
}
|
||||
|
||||
is SttDone -> {
|
||||
log("stt", "ВЕСЬ ТЕКСТ: ${msg.full}")
|
||||
GlassesApp.instance.listening.value = false
|
||||
}
|
||||
|
||||
is SttCancel -> {
|
||||
log("stt", "отменено")
|
||||
GlassesApp.instance.listening.value = false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user