Metadata-Version: 2.4
Name: phoonnx
Version: 1.91.2a1
Summary: Multilingual TTS and phonemization using ONNX models
Author-email: JarbasAI <jarbasai@mailfence.com>
License: Apache-2.0
Project-URL: Homepage, https://github.com/TigreGotico/phoonnx
Classifier: Programming Language :: Python :: 3
Classifier: License :: OSI Approved :: Apache Software License
Classifier: Operating System :: OS Independent
Requires-Python: >=3.11
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: numpy
Requires-Dist: onnxruntime
Requires-Dist: quebra-frases
Requires-Dist: langcodes
Requires-Dist: ovos-number-parser>=0.4.0
Requires-Dist: ovos-date-parser>=0.6.4a1
Requires-Dist: scriptconv[phonemizers]>=0.0.4a25
Requires-Dist: unicode_rbnf
Requires-Dist: click
Requires-Dist: requests
Requires-Dist: huggingface_hub
Requires-Dist: json_database
Requires-Dist: ovos-plugin-manager>=2.1.0
Requires-Dist: ovos-utils
Requires-Dist: regex
Provides-Extra: test
Requires-Dist: pytest; extra == "test"
Requires-Dist: build; extra == "test"
Requires-Dist: setuptools>=68; extra == "test"
Requires-Dist: wheel; extra == "test"
Requires-Dist: torch<3,>=2.1; extra == "test"
Requires-Dist: torchaudio; extra == "test"
Requires-Dist: pytorch-lightning<3,>=2.0; extra == "test"
Requires-Dist: ovos-plugin-manager>=2.1.0; extra == "test"
Requires-Dist: pycotovia>=0.4.0a1; extra == "test"
Requires-Dist: sentencepiece; extra == "test"
Requires-Dist: ahotts-g2p>=0.1.0; extra == "test"
Requires-Dist: espyak>=0.0.3a1; extra == "test"
Requires-Dist: voiceclonnx>=0.0.3a3; extra == "test"
Requires-Dist: orthography2ipa; extra == "test"
Requires-Dist: arbtok; extra == "test"
Requires-Dist: euskaphone; extra == "test"
Requires-Dist: g2p_barranquenho; extra == "test"
Requires-Dist: mwl_phonemizer; extra == "test"
Requires-Dist: misaki[en]; python_version < "3.13" and extra == "test"
Requires-Dist: misaki[zh]; python_version < "3.13" and extra == "test"
Requires-Dist: spacy<4.0,>=3.7; python_version < "3.13" and extra == "test"
Requires-Dist: pypinyin>=0.50; extra == "test"
Requires-Dist: gruut[en]<3.0,>=2.3.0; extra == "test"
Requires-Dist: tokenizers; extra == "test"
Requires-Dist: sentencepiece; extra == "test"
Requires-Dist: onnx<1.18; python_version < "3.13" and extra == "test"
Requires-Dist: onnx>=1.18; python_version >= "3.13" and extra == "test"
Requires-Dist: ml_dtypes>=0.5; python_version >= "3.13" and extra == "test"
Requires-Dist: kittentts==0.1.3; extra == "test"
Provides-Extra: streaming
Requires-Dist: onnx; extra == "streaming"
Provides-Extra: espeak
Requires-Dist: espyak>=0.0.3a1; extra == "espeak"
Provides-Extra: matcha
Requires-Dist: scipy; extra == "matcha"
Provides-Extra: pockettts
Requires-Dist: safetensors; extra == "pockettts"
Provides-Extra: omnivoice
Requires-Dist: pydub; extra == "omnivoice"
Provides-Extra: indic-parler
Requires-Dist: tokenizers; extra == "indic-parler"
Provides-Extra: train
Requires-Dist: diffusers<0.36,>=0.25.0; extra == "train"
Requires-Dist: einops; extra == "train"
Requires-Dist: huggingface_hub; extra == "train"
Requires-Dist: librosa<1,>=0.9.2; extra == "train"
Requires-Dist: numpy<2,>=1.19.0; python_version < "3.13" and extra == "train"
Requires-Dist: numpy>=2.1; python_version >= "3.13" and extra == "train"
Requires-Dist: numba>=0.66; python_version >= "3.13" and extra == "train"
Requires-Dist: pytorch-lightning<3,>=2.0; extra == "train"
Requires-Dist: torch<3,>=2.1; extra == "train"
Requires-Dist: tqdm; extra == "train"
Requires-Dist: scipy; extra == "train"
Provides-Extra: train-styletts2
Requires-Dist: einops-exts; extra == "train-styletts2"
Requires-Dist: munch; extra == "train-styletts2"
Requires-Dist: transformers>=4.48; extra == "train-styletts2"
Requires-Dist: torchaudio; extra == "train-styletts2"
Requires-Dist: soundfile; extra == "train-styletts2"
Requires-Dist: pandas; extra == "train-styletts2"
Requires-Dist: PyYAML; extra == "train-styletts2"
Provides-Extra: train-resample
Requires-Dist: torchaudio; extra == "train-resample"
Provides-Extra: train-eval
Requires-Dist: speechonnxmetrics; extra == "train-eval"
Requires-Dist: speechmos; extra == "train-eval"
Requires-Dist: torchaudio; extra == "train-eval"
Requires-Dist: soundfile; extra == "train-eval"
Requires-Dist: speakeronnx; extra == "train-eval"
Requires-Dist: vadonnx; extra == "train-eval"
Requires-Dist: onnx-asr; extra == "train-eval"
Requires-Dist: pandas; extra == "train-eval"
Provides-Extra: train-data
Requires-Dist: pandas; extra == "train-data"
Requires-Dist: pyarrow; extra == "train-data"
Requires-Dist: datasets; extra == "train-data"
Requires-Dist: soundfile; extra == "train-data"
Provides-Extra: train-fastpitch
Provides-Extra: train-mixer
Provides-Extra: train-mosstts
Requires-Dist: sentencepiece; extra == "train-mosstts"
Requires-Dist: safetensors; extra == "train-mosstts"
Requires-Dist: soundfile; extra == "train-mosstts"
Requires-Dist: onnx; extra == "train-mosstts"
Provides-Extra: train-optispeech
Requires-Dist: pyloudnorm; extra == "train-optispeech"
Requires-Dist: scipy; extra == "train-optispeech"
Requires-Dist: torchaudio; extra == "train-optispeech"
Requires-Dist: onnx; extra == "train-optispeech"
Requires-Dist: opt_einsum; extra == "train-optispeech"
Provides-Extra: train-pyworld
Requires-Dist: pyworld>=0.3.2; extra == "train-pyworld"
Requires-Dist: setuptools<81; extra == "train-pyworld"
Provides-Extra: ar
Requires-Dist: epitran; extra == "ar"
Requires-Dist: arbtok; extra == "ar"
Requires-Dist: text2tashkeel; extra == "ar"
Provides-Extra: ca
Requires-Dist: epitran; extra == "ca"
Provides-Extra: gl
Requires-Dist: pycotovia>=0.4.0a1; extra == "gl"
Provides-Extra: cs
Requires-Dist: epitran; extra == "cs"
Provides-Extra: de
Requires-Dist: epitran; extra == "de"
Requires-Dist: gruut[de]<3.0,>=2.3.0; extra == "de"
Provides-Extra: en
Requires-Dist: epitran; extra == "en"
Requires-Dist: gruut[en]<3.0,>=2.3.0; extra == "en"
Requires-Dist: misaki[en]; extra == "en"
Requires-Dist: spacy<4.0,>=3.7; extra == "en"
Provides-Extra: es
Requires-Dist: epitran; extra == "es"
Provides-Extra: eu
Requires-Dist: ahotts-g2p>=0.1.0; extra == "eu"
Requires-Dist: euskaphone; extra == "eu"
Provides-Extra: fa
Requires-Dist: epitran; extra == "fa"
Provides-Extra: fr
Requires-Dist: epitran; extra == "fr"
Provides-Extra: he
Requires-Dist: epitran; extra == "he"
Provides-Extra: it
Requires-Dist: epitran; extra == "it"
Provides-Extra: ja
Requires-Dist: epitran; extra == "ja"
Requires-Dist: gruut[ja]<3.0,>=2.3.0; extra == "ja"
Requires-Dist: misaki[ja]; extra == "ja"
Requires-Dist: spacy<4.0,>=3.7; extra == "ja"
Provides-Extra: ko
Requires-Dist: epitran; extra == "ko"
Provides-Extra: mwl
Requires-Dist: mwl_phonemizer; extra == "mwl"
Provides-Extra: pt
Requires-Dist: epitran; extra == "pt"
Requires-Dist: g2p_barranquenho; extra == "pt"
Provides-Extra: ru
Requires-Dist: epitran; extra == "ru"
Provides-Extra: sv
Requires-Dist: epitran; extra == "sv"
Provides-Extra: sw
Requires-Dist: epitran; extra == "sw"
Provides-Extra: vi
Requires-Dist: epitran; extra == "vi"
Requires-Dist: gruut[vi]<3.0,>=2.3.0; extra == "vi"
Requires-Dist: misaki[vi]; extra == "vi"
Requires-Dist: spacy<4.0,>=3.7; extra == "vi"
Provides-Extra: zh
Requires-Dist: epitran; extra == "zh"
Requires-Dist: gruut[zh]<3.0,>=2.3.0; extra == "zh"
Requires-Dist: misaki[zh]; extra == "zh"
Requires-Dist: spacy<4.0,>=3.7; extra == "zh"
Provides-Extra: cjk
Requires-Dist: pykakasi==2.3.0; extra == "cjk"
Requires-Dist: spacy-pkuseg; extra == "cjk"
Provides-Extra: o2i
Requires-Dist: orthography2ipa; extra == "o2i"
Provides-Extra: cloning
Requires-Dist: soundfile; extra == "cloning"
Requires-Dist: scipy; extra == "cloning"
Provides-Extra: audiosr
Requires-Dist: audiosronnx; extra == "audiosr"
Provides-Extra: vc
Requires-Dist: voiceclonnx>=0.0.3a3; extra == "vc"
Provides-Extra: chatterbox-multilingual
Requires-Dist: pykakasi==2.3.0; extra == "chatterbox-multilingual"
Requires-Dist: spacy-pkuseg; extra == "chatterbox-multilingual"
Provides-Extra: all
Requires-Dist: scriptconv[ar-phonemizers,en-phonemizers,goruut,he,ja-phonemizers,phonemizers,pt,pt-phonemizers,stress,tashkeel,zh-phonemizers]>=0.0.4a23; extra == "all"
Requires-Dist: stressonnx>=0.0.3a2; extra == "all"
Requires-Dist: text2tashkeel; extra == "all"
Requires-Dist: epitran; extra == "all"
Requires-Dist: gruut[de]<3.0,>=2.3.0; extra == "all"
Requires-Dist: gruut[en]<3.0,>=2.3.0; extra == "all"
Requires-Dist: gruut[es]<3.0,>=2.3.0; extra == "all"
Requires-Dist: gruut[fr]<3.0,>=2.3.0; extra == "all"
Requires-Dist: gruut[it]<3.0,>=2.3.0; extra == "all"
Requires-Dist: gruut[ja]<3.0,>=2.3.0; extra == "all"
Requires-Dist: gruut[nl]<3.0,>=2.3.0; extra == "all"
Requires-Dist: gruut[ru]<3.0,>=2.3.0; extra == "all"
Requires-Dist: gruut[sv]<3.0,>=2.3.0; extra == "all"
Requires-Dist: gruut[sw]<3.0,>=2.3.0; extra == "all"
Requires-Dist: gruut[vi]<3.0,>=2.3.0; extra == "all"
Requires-Dist: gruut[zh]<3.0,>=2.3.0; extra == "all"
Requires-Dist: misaki[en]; extra == "all"
Requires-Dist: misaki[ja]; extra == "all"
Requires-Dist: misaki[vi]; extra == "all"
Requires-Dist: misaki[zh]; extra == "all"
Requires-Dist: ahotts-g2p>=0.1.0; extra == "all"
Requires-Dist: spacy<4.0,>=3.7; extra == "all"
Requires-Dist: pycotovia>=0.4.0a1; extra == "all"
Requires-Dist: pykakasi==2.3.0; extra == "all"
Requires-Dist: spacy-pkuseg; extra == "all"
Requires-Dist: soundfile; extra == "all"
Requires-Dist: scipy; extra == "all"
Requires-Dist: orthography2ipa; extra == "all"
Requires-Dist: arbtok; extra == "all"
Requires-Dist: euskaphone; extra == "all"
Requires-Dist: g2p_barranquenho; extra == "all"
Requires-Dist: mwl_phonemizer; extra == "all"
Requires-Dist: pydub; extra == "all"
Requires-Dist: tokenizers; extra == "all"
Requires-Dist: sentencepiece; extra == "all"
Requires-Dist: safetensors; extra == "all"
Requires-Dist: librosa<1,>=0.9.2; extra == "all"
Requires-Dist: onnx<1.18; extra == "all"
Requires-Dist: audiosronnx; extra == "all"
Requires-Dist: voiceclonnx>=0.0.3a3; extra == "all"
Dynamic: license-file

[![Ask DeepWiki](https://deepwiki.com/badge.svg)](https://deepwiki.com/TigreGotico/phoonnx)

<img src="thumb.png" alt="phoonnx" width="480"/>

# phoonnx

Multilingual **phonemization** and **Text-to-Speech** using ONNX models. `phoonnx` loads
and runs TTS voices from several ecosystems (native phoonnx, Piper, Mimic3, Coqui, MMS,
Transformers) through one `onnxruntime`-based interface, and ships a training pipeline for
building your own voices.

It reaches **1000+ languages and voices** across the bundled voice indexes. See the full
list in [VOICES.md](./VOICES.md).

## 30-second quickstart

```bash
pip install phoonnx
```

Download a voice and synthesize a WAV from the command line:

```bash
# populate the local voice catalog, then fetch one voice
phoonnx-voices update-cache
phoonnx-voices download OpenVoiceOS/phoonnx_pt-PT_miro_tugaphone
```

The same thing from Python:

```python
import wave
from phoonnx.voice import TTSVoice

voice = TTSVoice.load("model.onnx", "model.json")
with wave.open("hello.wav", "wb") as wav_file:
    voice.synthesize_wav("Hello world!", wav_file)
```

New here? Start with the [Quickstart](docs/quickstart.md) — it downloads a voice and
speaks a sentence end-to-end.

## Train your own voice in an afternoon

Record (or obtain) a single-speaker dataset, preprocess it, train a VITS model on one GPU,
export to ONNX, and load it back — all with the bundled `phoonnx_train` toolkit. Follow the
golden path in [docs/training/quickstart.md](docs/training/quickstart.md).

## Features

| Capability | Where |
|---|---|
| Run ONNX voices on CPU or GPU (CUDA/ROCm/DirectML/CoreML/OpenVINO) | [Usage](docs/usage.md) · [Configuration](docs/configuration.md) |
| ~40 phonemizer backends across many languages | [Phonemizers](docs/phonemizers.md) |
| Load Piper / Mimic3 / Coqui / Transformers / MMS voices | [Architecture](docs/architecture.md) |
| 14 synthesis engines behind one adapter registry | [Engines](docs/engines.md) |
| Zero-shot voice cloning (YourTTS, StyleTTS2, ZipVoice, F5-TTS, Chatterbox) | [Cloning](docs/cloning.md) |
| Low-latency streaming for VITS voices | [Streaming](docs/streaming.md) |
| Optional 48 kHz audio super-resolution over synthesized audio | [OVOS plugin](docs/ovos_plugin.md#audio-super-resolution) |
| Download and cache voices from HuggingFace and other sources | [Voice manager](docs/voice_manager.md) |
| Train and fine-tune new voices | [Training](docs/training/quickstart.md) |
| Drop-in OpenVoiceOS TTS plugin | [OVOS plugin](docs/ovos_plugin.md) |

## Documentation

The docs are organized around three reader paths — see the [documentation index](docs/README.md):

- **Use a voice** — [Installation](docs/installation.md) → [Quickstart](docs/quickstart.md) → [Usage](docs/usage.md)
- **Train a voice** — [Training quickstart](docs/training/quickstart.md) → [Datasets](docs/training/datasets.md) → [Export](docs/training/export.md)
- **Understand the internals** — [Architecture](docs/architecture.md) → [Phonemizers](docs/phonemizers.md) → [Engines](docs/engines.md)

## OpenVoiceOS plugin

`phoonnx` ships the `ovos-tts-plugin-phoonnx` TTS plugin. Configure it in `mycroft.conf`:

```json
"tts": {
  "module": "ovos-tts-plugin-phoonnx",
  "ovos-tts-plugin-phoonnx": {
    "voice": "OpenVoiceOS/phoonnx_pt-PT_miro_tugaphone"
  }
}
```

Full options in [docs/ovos_plugin.md](docs/ovos_plugin.md).

## Docker / TTS server

```bash
docker compose up
```

See [docs/docker.md](docs/docker.md). For running it as a public or long-lived
service, see [docs/deployment.md](docs/deployment.md).

## Related projects

`phoonnx` is part of the [OpenVoiceOS](https://github.com/OpenVoiceOS) ecosystem:

- [ovos-core](https://github.com/OpenVoiceOS/ovos-core) — the voice assistant that loads this plugin
- [ovos-plugin-manager](https://github.com/OpenVoiceOS/ovos-plugin-manager) — the plugin framework `ovos-tts-plugin-phoonnx` registers against
- [ovos-tts-server](https://github.com/OpenVoiceOS/ovos-tts-server) — a standalone HTTP server for any OVOS TTS plugin, including this one

## License and credits

`phoonnx` is licensed under Apache-2.0. Copyright Casimiro Ferreira.

It builds on the work of others, including [jaywalnut310/vits](https://github.com/jaywalnut310/vits)
(the VITS backbone), and interoperates with the Piper, Mimic3, Coqui, MMS and Transformers
voice formats. Language-specific components are credited on the [Phonemizers](docs/phonemizers.md)
page.

The SuperTonic inference code (`phoonnx/engines/supertonic.py`) is adapted from Supertone
Inc.'s MIT-licensed reference implementation. **SuperTonic model weights
(`Supertone/supertonic-3`) are licensed OpenRAIL-M, not Apache-2.0** — review the model's
license before commercial use.
