# Спецификация 04: TtsFeedback — подтверждения (Ф-1.4) Источники: Ф-1.4 (щелчок + голосовое подтверждение, TTS офлайн), Ф-1.3 (короткий сигнал ошибки), tech-req 4.1 (TTS — системный Android), решение гейта 1.3 №5. Единица 5. ## 1. Интерфейс (используется исполнителем, спец 03) ```kotlin interface VoiceFeedback { fun accepted(text: String) // щелчок + голосовое TTS-подтверждение fun rejected() // короткий сигнал ошибки, TTS молчит fun ttsAvailable(): Boolean // диагностика («Проверить TTS») } ``` Реализация `TtsFeedback(context)` — системный Android TTS (`android.speech.tts`) + `ToneGenerator`. ## 2. Звуки (ToneGenerator) - щелчок принятой команды — короткий позитивный тон (~120 мс, `TONE_PROP_BEEP`), громкость по системному потоку; - сигнал ошибки — отличимый низкий двойной тон (~300 мс, `TONE_PROP_NACK`; errata 2026-10-19: константы TONE_PROP_ERR в ToneGenerator нет); - звуки уважают беззвучный режим (поток уведомлений) — в тихом режиме подтверждение остаётся голосовым/текстовым; - два сигнала различимы на слух (принято/отказ) — ui-ux: различение паттернов. ## 3. TTS - язык `ru-RU`: `setLanguage` → `LANG_MISSING_DATA`/`LANG_NOT_SUPPORTED` → `ttsAvailable=false` — деградация (щелчок/сигнал + текст на экране, работа голоса не блокируется — решение гейта 1.3 №5); - инициализация асинхронная: фразы до готовности движка (≤ 2 с) ставятся в очередь, при таймауте — отбрасываются (щелчок уже прозвучал); - `speak(QUEUE_FLUSH)` — новая фраза прерывает недоговорённую (команды идут редко, экономия времени); - числовые значения озвучиваются движком (цифры в тексте); аббревиатура РПЭ в TTS-тексте раскрывается в «эр пэ э» — корректное пословное произношение: «Принято, эр пэ э семь»; - формулы фраз: «Принято, подход {W} на {R}», «Принято, вес {W}», «Принято, отдых {S} секунд», «Принято, эр пэ э {N}»; W=62,5 → «шестьдесят два с половиной» (TTS-движок озвучит «62,5» — проверить на смоке; при некорректном озвучивании дроби — словесная подстановка, шаг 3). ## 4. Жизненный цикл - экземпляр живёт в контейнере приложения, TTS-движок инициализируется лениво при первом включении микрофона; `shutdown()` — при выходе с экрана тренировки не вызывается (переиспользование между тренировками), только при разрушении процесса. ## 5. Тесты - интерфейс — поведение подтверждается unit-тестами исполнителя (спец 03) на фейке; сам TtsFeedback — тонкая обёртка системных API, ручной смок (критерий 2 module_reqs): услышать щелчок, фразу, сигнал ошибки; «Проверить TTS» в настройках (спец 05) показывает статус ru-голоса.