Newer
Older
voice / docs / 02_architecture.md

Архитектура системы

Компоненты

1. WebSocket API (src/voice_tts/api/)

  • server.py — FastAPI-приложение, endpoint /ws, управление сессией.
  • protocol.py — Pydantic-модели всех входящих и исходящих сообщений.

Отвечает за:

  • Приём подключений от Python-агента.
  • Парсинг сообщений.
  • Жизненный цикл сессии и её graceful shutdown.

2. Сессия (src/voice_tts/session/)

  • state.pySessionState и VoiceProfile.

Хранит:

  • Текстовый буфер.
  • Текущий язык, скорость, эмоцию.
  • Референсные аудио для спикера и эмоций.
  • Очередь аудио-выхода.
  • Флаг остановки (stop_event).

3. Сегментатор (src/voice_tts/tts/segmenter.py)

Segmenter превращает накопленный текст в сегменты для синтеза.

Правила:

  • Разбиение по концам предложений (., , !, ?, ;, : и newline).
  • Если сегмент превышает max_length, разрез по запятой/тире/скобкам.
  • Минимальная длина сегмента (min_length) не применяется при принудительном flush.

4. TTS Engine (src/voice_tts/tts/)

  • engine.py — абстрактный базовый класс TTSEngine и DummyTTSEngine для тестов.
  • f5_backend.py — реализация на F5-TTS, включая кэширование транскрибированных референсов.

Интерфейс:

async def synthesize(
    self,
    text: str,
    ref_audio_path: Path | None,
    language: str,
    speed: float,
    emotion: str,
) -> np.ndarray:
    ...

5. Аудио (src/voice_tts/audio/)

  • formats.py — преобразование float32 -> PCM16 -> base64, генерация WAV-заголовка.

6. Конфигурация (src/voice_tts/config.py)

pydantic-settings, загружает переменные из .env.

Потоки выполнения

WebSocket receiver (async)
    |
    v
SessionManager
    |
    +---> Text buffer / Segmenter
    |          |
    |          v
    |     _synthesize_segment (async task per segment)
    |          |
    |          v
    |     TTS Engine (GPU-bound, выполняется в отдельной задаче)
    |          |
    |          v
    |     audio_queue.put((segment_seq, pcm))
    |
    +---> _audio_sender (async worker)
              |
              +---> WebSocket send(audio base64)
              |
              +---> WebSocket send(status: segment_finished)

Важно: все обращения к CUDA-инференсу сериализованы через один TTS worker, чтобы избежать contention и OOM.

Управление прерыванием

Каждая сессия содержит asyncio.Event stop_event.

При получении сообщения stop:

  1. Устанавливается stop_event.
  2. Очищается текстовый буфер.
  3. Опустошается аудио-очередь.
  4. Любая текущая/последующая генерация отменяется.
  5. Клиенту отправляется status: stopped.

Новый текст после stop автоматически сбрасывает stop_event и начинает новую фразу.