# Voice TTS

Локальный GPU-пайплайн синтеза речи в реальном времени с WebSocket API. 
Разработан для озвучки ИИ-агентов: текст поступает частями от LLM, аудио отдаётся 
клиенту по мере готовности.

## Основное

- **Стриминг текста**: фразы от LLM приходят частями, сервер не ждёт полного текста
- **Стриминг аудио**: PCM-чанки отправляются сразу после синтеза
- **Клонирование голоса**: один спикер по референсному аудио
- **Прерывание**: немедленная остановка по сигналу `stop`
- **Выбор бэкенда**: переключение между моделями через `TTS_BACKEND` без изменения кода

## Бэкенды

| Имя | Модель | Требования | VRAM | RTF |
|-----|--------|-----------|------|-----|
| `s2` | Fish Audio S2-Pro INT4 | S2 API сервер (порт 8081), PyTorch 2.4 | ~9.6 GB | **0.59** |
| `fish_speech` | Fish Speech 1.5 | чекпоинт fish-speech, PyTorch | ~12 GB | ~1.4 |
| `xtts_v2` | XTTS-v2 (Coqui) | авто-загрузка | ~2 GB | ~0.34 |
| `f5_tts` | F5-TTS v1 | чекпоинт F5TTS | ~4 GB | ~1.0 |
| `dummy` | синусоида | ничего | — | — |

## Быстрый старт (S2-Pro INT4)

```bash
# 1. S2 API сервер (требует ~9.6 GB VRAM, 50 tok/s с --compile)
cd models/fish-speech
PYTHONPATH=. /home/gmikcon/Projects/voice/.venv/bin/python tools/api_server.py \
  --llama-checkpoint-path checkpoints/fs-1.2-int4-g128-s2-pro-nf4 \
  --decoder-checkpoint-path checkpoints/s2-pro/codec.pth \
  --listen 127.0.0.1:8081 --compile

# 2. WebSocket прокси (в другом терминале)
TTS_BACKEND=s2 python -m voice_tts.main
```

Сервер слушает `ws://localhost:8765/ws`.

## WebSocket протокол

Полная документация — [`docs/03_websocket_protocol.md`](docs/03_websocket_protocol.md).

### Кратко

Клиент → Сервер:
- `init` — настройки сессии (голос, язык, скорость)
- `text` — чанк текста (`payload` — строка)
- `flush` — озвучить остаток буфера
- `stop` — немедленно прервать
- `emotion` / `config` — смена параметров

Сервер → Клиент:
- `status` — события (`session_ready`, `segment_started`, `segment_finished`, `stopped`)
- `audio` — PCM16 base64 с `sample_rate`
- `error` — ошибка

## Архитектура

```
[LLM / AI Agent] → WebSocket → [SessionManager]
                                    │
                           TextBuffer / Segmenter
                                    │
                           segments (async tasks)
                                    │
                          TTS Engine (через реестр)
                                    │
                           AudioQueue → WS send
```

Бэкенды регистрируются через декоратор `@register("name")` в `voice_tts.tts`.
Новый бэкенд добавляется одним файлом с декоратором — никаких правок в `server.py`.

```python
from voice_tts.tts import register as _register_backend

@_register_backend("my_model")
class MyEngine(TTSEngine):
    ...
```

## Установка

```bash
python3.11 -m venv .venv
source .venv/bin/activate
pip install torch torchaudio --index-url https://download.pytorch.org/whl/cu126
pip install -r requirements.txt
```

## Конфигурация

Все переменные в `.env` (см. `.env.example`). Ключевые:

| Переменная | По умолч. | Описание |
|-----------|-----------|----------|
| `TTS_BACKEND` | `s2` | `dummy` / `s2` / `fish_speech` / `f5_tts` / `xtts_v2` |
| `DEFAULT_VOICE_REF` | — | Референсное аудио для клонирования |
| `DEFAULT_REF_TEXT` | — | Точный транскрипт референса |
| `MIN_SEGMENT_LENGTH` | `30` | Мин. длина сегмента (прогрессивно: 12 → 30) |
| `MAX_SEGMENT_LENGTH` | `200` | Макс. длина сегмента |
| `FAST_START_INITIAL` | `12` | Порог для первого сегмента (снижает задержку) |
| `FAST_START_COUNT` | `3` | Сегментов с прогрессивным порогом |

## Тесты

```bash
pytest tests/ -v
```

## Документация

- [`docs/01_overview.md`](docs/01_overview.md) — обзор проекта
- [`docs/02_architecture.md`](docs/02_architecture.md) — архитектура
- [`docs/03_websocket_protocol.md`](docs/03_websocket_protocol.md) — протокол
- [`docs/05_usage.md`](docs/05_usage.md) — использование и развёртывание
