tts-api / AGENTS.md
gavanduffy
Port pocket-tts to supertonic3: 44100 Hz, 10 voices, 31 languages
d715e26
|
Raw
History Blame Contribute Delete
4.45 kB
# Project Overview
**SuperTonic3 OpenAI-Compatible Server** wraps [supertonic3](https://github.com/nicegram/nicegram-android) (ONNX-based)
to provide OpenAI-compatible TTS endpoints. Any OpenAI TTS client can use this for local, CPU-based text-to-speech with
31 languages and 10 built-in voices.
## Why This Exists
The official `pocket-tts` server was **not OpenAI API compatible**. This project ports that server to
`supertonic3`, which provides a simpler, lighter stack (ONNX runtime, no PyTorch) with 44100 Hz output and
multi-language support.
## Architecture
```
server.py # Entry point, CLI, starts Waitress
└── app/__init__.py # Flask app factory
β”œβ”€β”€ app/routes.py # API endpoints
β”œβ”€β”€ app/config.py # Environment config
└── app/services/
β”œβ”€β”€ tts.py # TTSService: supertonic3 TTS engine wrapper
└── audio.py # Format conversion, streaming
```
## Key Files
| File | Purpose |
| --------------------- | ---------------------------------------------------------------- |
| `server.py` | Entry point, CLI args, Waitress server |
| `app/routes.py` | HTTP endpoints: `/`, `/health`, `/v1/voices`, `/v1/audio/speech` |
| `app/services/tts.py` | supertonic3 TTS engine loading, voice management, generation |
| `app/config.py` | Environment variables, path resolution |
## API Endpoints
| Endpoint | Method | Purpose |
| ------------------ | ------ | ----------------------------------- |
| `/` | GET | Web UI |
| `/health` | GET | Health check for containers |
| `/v1/voices` | GET | List voices |
| `/v1/audio/speech` | POST | Generate speech (OpenAI-compatible) |
### Speech Request
```json
{
"model": "tts-1",
"input": "Text to speak",
"voice": "M1",
"response_format": "mp3",
"stream": false,
"lang": "en"
}
```
## CLI Arguments
| Argument | Env Variable | Default | Purpose |
| ------------------- | -------------------------------------- | --------- | ------------------------------- |
| `--host` | `SUPERTONIC3_HOST` | `0.0.0.0` | Bind address |
| `--port` | `SUPERTONIC3_PORT` | `7860` | Port |
| `--voice` | `SUPERTONIC3_VOICE` | `M1` | Default voice |
| `--stream` | `SUPERTONIC3_STREAM_DEFAULT` | `false` | Enable streaming by default |
| `--text-preprocess` | `SUPERTONIC3_TEXT_PREPROCESS_DEFAULT` | `false` | Enable text preprocessing |
| `--log-level` | `SUPERTONIC3_LOG_LEVEL` | `INFO` | Log verbosity |
## Voices
10 built-in voices: M1-M5 (male), F1-F5 (female). No voice cloning.
Default voice: M1.
## Languages
31 supported languages via `lang` parameter in speech requests. See `SUPPORTED_LANGUAGES` in config.py.
## Development
```bash
# Install
pip install -r requirements.txt
# Run
python server.py --log-level DEBUG
# Test
curl http://localhost:7860/health
curl -X POST http://localhost:7860/v1/audio/speech \
-H "Content-Type: application/json" \
-d '{"input": "Hello", "voice": "M1"}' -o test.mp3
```
## Code Style
- Linter/formatter: `ruff` (config in `pyproject.toml`)
- Line length: 100
- Single quotes
## Deployment
- **Python**: `python server.py`
- **Docker**: `docker compose up -d`
## Key Differences from pocket-tts
| Feature | pocket-tts | supertonic3 |
| ---------------- | ----------------------- | ---------------------------- |
| Inference engine | PyTorch + torchao | ONNX Runtime |
| Sample rate | 24000 Hz | 44100 Hz |
| Voices | 8 + voice cloning | 10 (M1-M5, F1-F5), no clone |
| Languages | Per-language models | 31 languages, one model |
| Quantization | int8 support | Not applicable |
| Default port | 49112 | 7860 |