## Интеграция VAD и Wakeword: выводы и план ### 1) Картина текущей архитектуры (Wyoming Satellite) - **Режимы работы спутника**: - AlwaysStreaming — всегда стримит аудио, VAD/Wake не участвуют. - VadStreaming — локальный VAD решает момент старта стриминга; при активации отправляется предречь (pre-roll), опционально действует таймаут на ожидание wakeword. - WakeStreaming — аудио уходит в локальный wakeword-сервис (Wyoming-протокол); при Detection начинается стриминг на сервер (STT/интенты). - **VAD по умолчанию**: `SileroVad` с интерфейсом `__call__(audio_bytes|None) -> bool`, поддержка `reset()` через передачу `None`. Предречь хранится в кольцевом буфере, при активации догружается первой. - **Wakeword**: внешние сервисы по Wyoming (например, openWakeWord, Porcupine, Snowboy), принимают `Audio*` события и отдают `Detection`. ### 2) Что есть в `myproject` - **VAD** (`myproject/vad_core.py`): - Использует `webrtcvad.Vad` + энерго-критерии, адаптивный порог, простое шумоподавление и автоусиление. - Имеет предбуфер и основной буфер записи сегмента речи; по завершении вызывает callback с целым кусочком аудио. - Ввод аудио сейчас завязан на PyAudio внутри класса, то есть детектор и источник аудио слиты. - **Wakeword на Vosk** (`myproject/vosk_local_STT.py` + `commands.py`): - Собирает грамматику из `commands.yaml` (в т.ч. секцию `Wakewords`) и распознаёт текст. - Факт wakeword определяется как точное совпадение распознанной фразы с элементами из `Wakewords` (то есть post-utterance wakeword через STT). ### 3) Сопоставление и ключевые различия - В Wyoming VAD — быстрый фрейм-по-фрейм решатель с мгновенным флагом активации, а у вас — сегментатор с внутренним циклом и завершением по тишине. - В Wyoming wakeword — отдельный потоковый сервис (KWS-подобное поведение), а у вас — определение wakeword как часть STT после завершения фразы. ### 4) Варианты интеграции 1. **Заменить локальный VAD на ваш (рекомендуется этап 2):** - Выделить из `VADPolling` чистый детектор без PyAudio-ввода (API вида: `process(frame_bytes) -> { started/stopped/speech_detected, prebuffer, ... }`). - Добавить фабрику VAD в спутник: `settings.vad.system: "silero"|"my_webrtc_vad"`, инициализировать нужную реализацию. - При активации отдавать предбуфер и стартовать стриминг — совместимо с текущей логикой VadStreaming. 2. **Оформить wakeword на Vosk как Wyoming-сервис (рекомендуется этап 1):** - Небольшой сервер по Wyoming-протоколу, который: - подгружает грамматику только из `Wakewords`; - принимает `AudioStart/AudioChunk/AudioStop` и кормит чанк в `KaldiRecognizer.AcceptWaveform`; - при совпадении фразы — отправляет `Detection(name=...)` немедленно. - Подключается как `wake.system: "vosk_wake"`, аналогично `openWakeWord`/`porcupine1`. ### 5) Минимальные изменения кода - **Для wakeword (этап 1):** - Реализовать отдельный модуль `vosk_wake` (сервер Wyoming): запуск по TCP, обработка событий, генерация `Detection` по фразам из `Wakewords`. - Unit-файл/скрипт запуска по аналогии с `local/services/wyoming-wakeword.service` и запись в конфиг `wake.system`. - **Для VAD (этап 2):** - Вынести логику детектора из `VADPolling` в отдельный класс без I/O. - Добавить флаг `vad.system` и фабрику выбора реализации; адаптер, который преобразует `AudioChunk` → фреймы и использует ваш детектор для решения «старт/стоп/предречь». ### 6) Пошаговый план внедрения 1) Wakeword на Vosk (быстрый выигрыш): - Сделать `vosk_wake` сервис: узкая грамматика = только `Wakewords`, немедленный `Detection` при совпадении. - Прописать сервис в systemd/скрипте, указать URI и `wake.system`. - Протестировать в режиме `WakeStreamingSatellite`. 2) Замена VAD: - Рефакторинг `VADPolling`: отделить детектор от аудио-источника. - Добавить `vad.system` и внедрить адаптер под текущий интерфейс Wyoming. - Протестировать в `VadStreamingSatellite` с предбуфером и таймаутом wakeword. ### 7) Риски и примечания - Vosk как wakeword — это распознавание текста; для «на лету» задержка может быть выше, чем у специализированного KWS. С узкой грамматикой (только wakewords) будет быстрее и устойчивее. - Ваши улучшения VAD (AGC/NR/адаптивные пороги) полезны; главное — отделить I/O и обеспечить детерминированный фреймовый API, совместимый с Wyoming. ### 8) Резюме - Этап 1: добавить `vosk_wake` как Wyoming-сервис wakeword — минимум инвазивности и быстрая интеграция. - Этап 2: внедрить ваш VAD через фабрику и адаптер — получить продвинутую локальную активацию речи, сохранив предречь и таймауты.