Metadata-Version: 2.4
Name: realtimetts
Version: 0.8.10
Summary: Stream text into audio with an easy-to-use, highly configurable library delivering voice output with minimal latency.
Home-page: https://github.com/KoljaB/realtimetts
Author: Kolja Beigel
Author-email: kolja.beigel@web.de
License: MIT
Keywords: real-time,text-to-speech,TTS,streaming,audio,voice,synthesis,sentence-segmentation,low-latency,character-streaming,dynamic feedback,audio-output,text-input,TTS-engine,audio-playback,stream-player,sentence-fragment,audio-feedback,interactive,python
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: 3.14
Classifier: Operating System :: OS Independent
Requires-Python: >=3.10, <3.15
Description-Content-Type: text/markdown
License-File: LICENSE
License-File: LICENSING_ADDENDUM.md
Requires-Dist: stream2sentence[nltk]>=1.0.4
Requires-Dist: pydub>=0.25.1
Requires-Dist: audioop-lts>=0.2.2; python_version >= "3.13"
Requires-Dist: resampy==0.4.3
Provides-Extra: minimal
Requires-Dist: stream2sentence[nltk]>=1.0.4; extra == "minimal"
Requires-Dist: pydub>=0.25.1; extra == "minimal"
Requires-Dist: audioop-lts>=0.2.2; python_version >= "3.13" and extra == "minimal"
Requires-Dist: resampy==0.4.3; extra == "minimal"
Provides-Extra: playback
Requires-Dist: stream2sentence[nltk]>=1.0.4; extra == "playback"
Requires-Dist: pydub>=0.25.1; extra == "playback"
Requires-Dist: audioop-lts>=0.2.2; python_version >= "3.13" and extra == "playback"
Requires-Dist: resampy==0.4.3; extra == "playback"
Requires-Dist: pyaudio>=0.2.14; extra == "playback"
Provides-Extra: all
Requires-Dist: stream2sentence[nltk]>=1.0.4; extra == "all"
Requires-Dist: pydub>=0.25.1; extra == "all"
Requires-Dist: audioop-lts>=0.2.2; python_version >= "3.13" and extra == "all"
Requires-Dist: resampy==0.4.3; extra == "all"
Requires-Dist: pyaudio>=0.2.14; extra == "all"
Requires-Dist: stream2sentence[stanza]>=1.0.4; extra == "all"
Requires-Dist: pyttsx3>=2.99; extra == "all"
Requires-Dist: azure-cognitiveservices-speech>=1.50.0; extra == "all"
Requires-Dist: elevenlabs>=2.49.0; extra == "all"
Requires-Dist: openai>=2.38.0; extra == "all"
Requires-Dist: gtts>=2.5.4; extra == "all"
Requires-Dist: coqui_tts>=0.27.5; extra == "all"
Requires-Dist: edge-tts>=7.2.8; extra == "all"
Requires-Dist: kokoro>=0.9.4; extra == "all"
Requires-Dist: camb-sdk>=1.5.11; extra == "all"
Requires-Dist: requests>=2.34.2; extra == "all"
Requires-Dist: cartesia==3.1.0; extra == "all"
Requires-Dist: typecast-python>=0.3.0; extra == "all"
Requires-Dist: realtimetts-qwen-native[cuda12]==0.2.0; sys_platform == "win32" and extra == "all"
Requires-Dist: realtimetts-qwen-native[cuda12]==0.2.0; sys_platform == "linux" and extra == "all"
Requires-Dist: numpy; extra == "all"
Requires-Dist: soundfile>=0.13.1; extra == "all"
Requires-Dist: numba<0.67,>=0.66; sys_platform == "win32" and extra == "all"
Requires-Dist: numba<0.63,>=0.62; (sys_platform == "darwin" and platform_machine == "x86_64") and extra == "all"
Requires-Dist: pyaudio>=0.2.14; extra == "all"
Requires-Dist: fastapi<1,>=0.115; extra == "all"
Requires-Dist: uvicorn[standard]<1,>=0.34; extra == "all"
Requires-Dist: fasttext-predict>=0.9.2.4; extra == "all"
Requires-Dist: snac>=1.2.1; extra == "all"
Requires-Dist: omnivoice>=0.1.5; extra == "all"
Requires-Dist: chatterbox-tts; extra == "all"
Requires-Dist: numpy<3,>=1.26; extra == "all"
Requires-Dist: soundfile>=0.13; extra == "all"
Requires-Dist: huggingface-hub>=0.36; extra == "all"
Requires-Dist: phonemizer>=3.3; extra == "all"
Requires-Dist: espeakng-loader>=0.2.4; extra == "all"
Requires-Dist: num2words>=0.5.14; extra == "all"
Requires-Dist: Unidecode>=1.3.8; extra == "all"
Requires-Dist: torch>=2.6; extra == "all"
Requires-Dist: scipy>=1.13; extra == "all"
Requires-Dist: onnxruntime<2,>=1.18; extra == "all"
Requires-Dist: sopro>=1.5.0; extra == "all"
Requires-Dist: soprano-tts>=0.2.0; extra == "all"
Requires-Dist: neutts; extra == "all"
Requires-Dist: pocket-tts>=2.1.0; extra == "all"
Requires-Dist: torch; extra == "all"
Requires-Dist: torch; extra == "all"
Requires-Dist: scipy; extra == "all"
Requires-Dist: safetensors; extra == "all"
Requires-Dist: huggingface-hub>=0.36.0; extra == "all"
Requires-Dist: torch; extra == "all"
Requires-Dist: torchaudio; extra == "all"
Requires-Dist: numpy; extra == "all"
Requires-Dist: huggingface-hub>=0.36.0; extra == "all"
Requires-Dist: safetensors; extra == "all"
Requires-Dist: vocos; extra == "all"
Requires-Dist: cn2an>=0.5.24; extra == "all"
Requires-Dist: inflect; extra == "all"
Requires-Dist: jieba>=0.42.1; extra == "all"
Requires-Dist: lhotse; extra == "all"
Requires-Dist: librosa; extra == "all"
Requires-Dist: numpy; extra == "all"
Requires-Dist: onnxruntime; extra == "all"
Requires-Dist: piper_phonemize; extra == "all"
Requires-Dist: pydub>=0.25.1; extra == "all"
Requires-Dist: pypinyin>=0.55.0; extra == "all"
Requires-Dist: safetensors; extra == "all"
Requires-Dist: setuptools<81; extra == "all"
Requires-Dist: tensorboard; extra == "all"
Requires-Dist: torch; extra == "all"
Requires-Dist: torchaudio; extra == "all"
Requires-Dist: transformers<=4.57.6; extra == "all"
Requires-Dist: vocos; extra == "all"
Requires-Dist: torch; extra == "all"
Requires-Dist: torchaudio; extra == "all"
Requires-Dist: numpy; extra == "all"
Requires-Dist: librosa; extra == "all"
Requires-Dist: nltk; extra == "all"
Requires-Dist: munch; extra == "all"
Requires-Dist: PyYAML; extra == "all"
Requires-Dist: phonemizer; extra == "all"
Requires-Dist: torch; extra == "all"
Requires-Dist: transformers; extra == "all"
Requires-Dist: numpy; extra == "all"
Requires-Dist: soundfile>=0.13.1; extra == "all"
Requires-Dist: torch; extra == "all"
Requires-Dist: torchaudio; extra == "all"
Requires-Dist: onnxruntime; extra == "all"
Requires-Dist: huggingface-hub>=0.36.0; extra == "all"
Requires-Dist: nltk; extra == "all"
Requires-Dist: requests>=2.34.2; extra == "all"
Requires-Dist: torch; extra == "all"
Requires-Dist: torchaudio; extra == "all"
Provides-Extra: nltk
Requires-Dist: stream2sentence[nltk]>=1.0.4; extra == "nltk"
Requires-Dist: pydub>=0.25.1; extra == "nltk"
Requires-Dist: audioop-lts>=0.2.2; python_version >= "3.13" and extra == "nltk"
Requires-Dist: resampy==0.4.3; extra == "nltk"
Provides-Extra: stanza
Requires-Dist: stream2sentence[nltk]>=1.0.4; extra == "stanza"
Requires-Dist: pydub>=0.25.1; extra == "stanza"
Requires-Dist: audioop-lts>=0.2.2; python_version >= "3.13" and extra == "stanza"
Requires-Dist: resampy==0.4.3; extra == "stanza"
Requires-Dist: stream2sentence[stanza]>=1.0.4; extra == "stanza"
Provides-Extra: system
Requires-Dist: stream2sentence[nltk]>=1.0.4; extra == "system"
Requires-Dist: pydub>=0.25.1; extra == "system"
Requires-Dist: audioop-lts>=0.2.2; python_version >= "3.13" and extra == "system"
Requires-Dist: resampy==0.4.3; extra == "system"
Requires-Dist: pyaudio>=0.2.14; extra == "system"
Requires-Dist: pyttsx3>=2.99; extra == "system"
Provides-Extra: azure
Requires-Dist: stream2sentence[nltk]>=1.0.4; extra == "azure"
Requires-Dist: pydub>=0.25.1; extra == "azure"
Requires-Dist: audioop-lts>=0.2.2; python_version >= "3.13" and extra == "azure"
Requires-Dist: resampy==0.4.3; extra == "azure"
Requires-Dist: pyaudio>=0.2.14; extra == "azure"
Requires-Dist: azure-cognitiveservices-speech>=1.50.0; extra == "azure"
Provides-Extra: elevenlabs
Requires-Dist: stream2sentence[nltk]>=1.0.4; extra == "elevenlabs"
Requires-Dist: pydub>=0.25.1; extra == "elevenlabs"
Requires-Dist: audioop-lts>=0.2.2; python_version >= "3.13" and extra == "elevenlabs"
Requires-Dist: resampy==0.4.3; extra == "elevenlabs"
Requires-Dist: pyaudio>=0.2.14; extra == "elevenlabs"
Requires-Dist: elevenlabs>=2.49.0; extra == "elevenlabs"
Provides-Extra: openai
Requires-Dist: stream2sentence[nltk]>=1.0.4; extra == "openai"
Requires-Dist: pydub>=0.25.1; extra == "openai"
Requires-Dist: audioop-lts>=0.2.2; python_version >= "3.13" and extra == "openai"
Requires-Dist: resampy==0.4.3; extra == "openai"
Requires-Dist: pyaudio>=0.2.14; extra == "openai"
Requires-Dist: openai>=2.38.0; extra == "openai"
Provides-Extra: gtts
Requires-Dist: stream2sentence[nltk]>=1.0.4; extra == "gtts"
Requires-Dist: pydub>=0.25.1; extra == "gtts"
Requires-Dist: audioop-lts>=0.2.2; python_version >= "3.13" and extra == "gtts"
Requires-Dist: resampy==0.4.3; extra == "gtts"
Requires-Dist: pyaudio>=0.2.14; extra == "gtts"
Requires-Dist: gtts>=2.5.4; extra == "gtts"
Provides-Extra: coqui
Requires-Dist: stream2sentence[nltk]>=1.0.4; extra == "coqui"
Requires-Dist: pydub>=0.25.1; extra == "coqui"
Requires-Dist: audioop-lts>=0.2.2; python_version >= "3.13" and extra == "coqui"
Requires-Dist: resampy==0.4.3; extra == "coqui"
Requires-Dist: pyaudio>=0.2.14; extra == "coqui"
Requires-Dist: coqui_tts>=0.27.5; extra == "coqui"
Provides-Extra: edge
Requires-Dist: stream2sentence[nltk]>=1.0.4; extra == "edge"
Requires-Dist: pydub>=0.25.1; extra == "edge"
Requires-Dist: audioop-lts>=0.2.2; python_version >= "3.13" and extra == "edge"
Requires-Dist: resampy==0.4.3; extra == "edge"
Requires-Dist: pyaudio>=0.2.14; extra == "edge"
Requires-Dist: edge-tts>=7.2.8; extra == "edge"
Provides-Extra: kokoro
Requires-Dist: stream2sentence[nltk]>=1.0.4; extra == "kokoro"
Requires-Dist: pydub>=0.25.1; extra == "kokoro"
Requires-Dist: audioop-lts>=0.2.2; python_version >= "3.13" and extra == "kokoro"
Requires-Dist: resampy==0.4.3; extra == "kokoro"
Requires-Dist: pyaudio>=0.2.14; extra == "kokoro"
Requires-Dist: kokoro>=0.9.4; extra == "kokoro"
Provides-Extra: camb
Requires-Dist: stream2sentence[nltk]>=1.0.4; extra == "camb"
Requires-Dist: pydub>=0.25.1; extra == "camb"
Requires-Dist: audioop-lts>=0.2.2; python_version >= "3.13" and extra == "camb"
Requires-Dist: resampy==0.4.3; extra == "camb"
Requires-Dist: pyaudio>=0.2.14; extra == "camb"
Requires-Dist: camb-sdk>=1.5.11; extra == "camb"
Provides-Extra: minimax
Requires-Dist: stream2sentence[nltk]>=1.0.4; extra == "minimax"
Requires-Dist: pydub>=0.25.1; extra == "minimax"
Requires-Dist: audioop-lts>=0.2.2; python_version >= "3.13" and extra == "minimax"
Requires-Dist: resampy==0.4.3; extra == "minimax"
Requires-Dist: pyaudio>=0.2.14; extra == "minimax"
Requires-Dist: requests>=2.34.2; extra == "minimax"
Provides-Extra: modelslab
Requires-Dist: stream2sentence[nltk]>=1.0.4; extra == "modelslab"
Requires-Dist: pydub>=0.25.1; extra == "modelslab"
Requires-Dist: audioop-lts>=0.2.2; python_version >= "3.13" and extra == "modelslab"
Requires-Dist: resampy==0.4.3; extra == "modelslab"
Requires-Dist: pyaudio>=0.2.14; extra == "modelslab"
Requires-Dist: requests>=2.34.2; extra == "modelslab"
Provides-Extra: cartesia
Requires-Dist: stream2sentence[nltk]>=1.0.4; extra == "cartesia"
Requires-Dist: pydub>=0.25.1; extra == "cartesia"
Requires-Dist: audioop-lts>=0.2.2; python_version >= "3.13" and extra == "cartesia"
Requires-Dist: resampy==0.4.3; extra == "cartesia"
Requires-Dist: pyaudio>=0.2.14; extra == "cartesia"
Requires-Dist: cartesia==3.1.0; extra == "cartesia"
Provides-Extra: typecast
Requires-Dist: stream2sentence[nltk]>=1.0.4; extra == "typecast"
Requires-Dist: pydub>=0.25.1; extra == "typecast"
Requires-Dist: audioop-lts>=0.2.2; python_version >= "3.13" and extra == "typecast"
Requires-Dist: resampy==0.4.3; extra == "typecast"
Requires-Dist: pyaudio>=0.2.14; extra == "typecast"
Requires-Dist: typecast-python>=0.3.0; extra == "typecast"
Provides-Extra: orpheus
Requires-Dist: stream2sentence[nltk]>=1.0.4; extra == "orpheus"
Requires-Dist: pydub>=0.25.1; extra == "orpheus"
Requires-Dist: audioop-lts>=0.2.2; python_version >= "3.13" and extra == "orpheus"
Requires-Dist: resampy==0.4.3; extra == "orpheus"
Requires-Dist: pyaudio>=0.2.14; extra == "orpheus"
Requires-Dist: snac>=1.2.1; extra == "orpheus"
Provides-Extra: omnivoice
Requires-Dist: stream2sentence[nltk]>=1.0.4; extra == "omnivoice"
Requires-Dist: pydub>=0.25.1; extra == "omnivoice"
Requires-Dist: audioop-lts>=0.2.2; python_version >= "3.13" and extra == "omnivoice"
Requires-Dist: resampy==0.4.3; extra == "omnivoice"
Requires-Dist: pyaudio>=0.2.14; extra == "omnivoice"
Requires-Dist: omnivoice>=0.1.5; extra == "omnivoice"
Provides-Extra: luxtts
Requires-Dist: stream2sentence[nltk]>=1.0.4; extra == "luxtts"
Requires-Dist: pydub>=0.25.1; extra == "luxtts"
Requires-Dist: audioop-lts>=0.2.2; python_version >= "3.13" and extra == "luxtts"
Requires-Dist: resampy==0.4.3; extra == "luxtts"
Requires-Dist: pyaudio>=0.2.14; extra == "luxtts"
Requires-Dist: cn2an>=0.5.24; extra == "luxtts"
Requires-Dist: inflect; extra == "luxtts"
Requires-Dist: jieba>=0.42.1; extra == "luxtts"
Requires-Dist: lhotse; extra == "luxtts"
Requires-Dist: librosa; extra == "luxtts"
Requires-Dist: numpy; extra == "luxtts"
Requires-Dist: onnxruntime; extra == "luxtts"
Requires-Dist: piper_phonemize; extra == "luxtts"
Requires-Dist: pydub>=0.25.1; extra == "luxtts"
Requires-Dist: pypinyin>=0.55.0; extra == "luxtts"
Requires-Dist: safetensors; extra == "luxtts"
Requires-Dist: setuptools<81; extra == "luxtts"
Requires-Dist: tensorboard; extra == "luxtts"
Requires-Dist: torch; extra == "luxtts"
Requires-Dist: torchaudio; extra == "luxtts"
Requires-Dist: transformers<=4.57.6; extra == "luxtts"
Requires-Dist: vocos; extra == "luxtts"
Provides-Extra: zipvoice
Requires-Dist: stream2sentence[nltk]>=1.0.4; extra == "zipvoice"
Requires-Dist: pydub>=0.25.1; extra == "zipvoice"
Requires-Dist: audioop-lts>=0.2.2; python_version >= "3.13" and extra == "zipvoice"
Requires-Dist: resampy==0.4.3; extra == "zipvoice"
Requires-Dist: pyaudio>=0.2.14; extra == "zipvoice"
Requires-Dist: torch; extra == "zipvoice"
Requires-Dist: torchaudio; extra == "zipvoice"
Requires-Dist: numpy; extra == "zipvoice"
Requires-Dist: huggingface-hub>=0.36.0; extra == "zipvoice"
Requires-Dist: safetensors; extra == "zipvoice"
Requires-Dist: vocos; extra == "zipvoice"
Provides-Extra: chatterbox
Requires-Dist: stream2sentence[nltk]>=1.0.4; extra == "chatterbox"
Requires-Dist: pydub>=0.25.1; extra == "chatterbox"
Requires-Dist: audioop-lts>=0.2.2; python_version >= "3.13" and extra == "chatterbox"
Requires-Dist: resampy==0.4.3; extra == "chatterbox"
Requires-Dist: pyaudio>=0.2.14; extra == "chatterbox"
Requires-Dist: chatterbox-tts; extra == "chatterbox"
Provides-Extra: inflect
Requires-Dist: stream2sentence[nltk]>=1.0.4; extra == "inflect"
Requires-Dist: pydub>=0.25.1; extra == "inflect"
Requires-Dist: audioop-lts>=0.2.2; python_version >= "3.13" and extra == "inflect"
Requires-Dist: resampy==0.4.3; extra == "inflect"
Requires-Dist: pyaudio>=0.2.14; extra == "inflect"
Requires-Dist: numpy<3,>=1.26; extra == "inflect"
Requires-Dist: soundfile>=0.13; extra == "inflect"
Requires-Dist: huggingface-hub>=0.36; extra == "inflect"
Requires-Dist: phonemizer>=3.3; extra == "inflect"
Requires-Dist: espeakng-loader>=0.2.4; extra == "inflect"
Requires-Dist: num2words>=0.5.14; extra == "inflect"
Requires-Dist: Unidecode>=1.3.8; extra == "inflect"
Requires-Dist: torch>=2.6; extra == "inflect"
Requires-Dist: scipy>=1.13; extra == "inflect"
Requires-Dist: onnxruntime<2,>=1.18; extra == "inflect"
Provides-Extra: inflect-pytorch
Requires-Dist: stream2sentence[nltk]>=1.0.4; extra == "inflect-pytorch"
Requires-Dist: pydub>=0.25.1; extra == "inflect-pytorch"
Requires-Dist: audioop-lts>=0.2.2; python_version >= "3.13" and extra == "inflect-pytorch"
Requires-Dist: resampy==0.4.3; extra == "inflect-pytorch"
Requires-Dist: pyaudio>=0.2.14; extra == "inflect-pytorch"
Requires-Dist: numpy<3,>=1.26; extra == "inflect-pytorch"
Requires-Dist: soundfile>=0.13; extra == "inflect-pytorch"
Requires-Dist: huggingface-hub>=0.36; extra == "inflect-pytorch"
Requires-Dist: phonemizer>=3.3; extra == "inflect-pytorch"
Requires-Dist: espeakng-loader>=0.2.4; extra == "inflect-pytorch"
Requires-Dist: num2words>=0.5.14; extra == "inflect-pytorch"
Requires-Dist: Unidecode>=1.3.8; extra == "inflect-pytorch"
Requires-Dist: torch>=2.6; extra == "inflect-pytorch"
Requires-Dist: scipy>=1.13; extra == "inflect-pytorch"
Provides-Extra: inflect-onnx
Requires-Dist: stream2sentence[nltk]>=1.0.4; extra == "inflect-onnx"
Requires-Dist: pydub>=0.25.1; extra == "inflect-onnx"
Requires-Dist: audioop-lts>=0.2.2; python_version >= "3.13" and extra == "inflect-onnx"
Requires-Dist: resampy==0.4.3; extra == "inflect-onnx"
Requires-Dist: pyaudio>=0.2.14; extra == "inflect-onnx"
Requires-Dist: numpy<3,>=1.26; extra == "inflect-onnx"
Requires-Dist: soundfile>=0.13; extra == "inflect-onnx"
Requires-Dist: huggingface-hub>=0.36; extra == "inflect-onnx"
Requires-Dist: phonemizer>=3.3; extra == "inflect-onnx"
Requires-Dist: espeakng-loader>=0.2.4; extra == "inflect-onnx"
Requires-Dist: num2words>=0.5.14; extra == "inflect-onnx"
Requires-Dist: Unidecode>=1.3.8; extra == "inflect-onnx"
Requires-Dist: onnxruntime<2,>=1.18; extra == "inflect-onnx"
Provides-Extra: sopro
Requires-Dist: stream2sentence[nltk]>=1.0.4; extra == "sopro"
Requires-Dist: pydub>=0.25.1; extra == "sopro"
Requires-Dist: audioop-lts>=0.2.2; python_version >= "3.13" and extra == "sopro"
Requires-Dist: resampy==0.4.3; extra == "sopro"
Requires-Dist: pyaudio>=0.2.14; extra == "sopro"
Requires-Dist: sopro>=1.5.0; extra == "sopro"
Provides-Extra: soprano
Requires-Dist: stream2sentence[nltk]>=1.0.4; extra == "soprano"
Requires-Dist: pydub>=0.25.1; extra == "soprano"
Requires-Dist: audioop-lts>=0.2.2; python_version >= "3.13" and extra == "soprano"
Requires-Dist: resampy==0.4.3; extra == "soprano"
Requires-Dist: pyaudio>=0.2.14; extra == "soprano"
Requires-Dist: soprano-tts>=0.2.0; extra == "soprano"
Provides-Extra: neutts
Requires-Dist: stream2sentence[nltk]>=1.0.4; extra == "neutts"
Requires-Dist: pydub>=0.25.1; extra == "neutts"
Requires-Dist: audioop-lts>=0.2.2; python_version >= "3.13" and extra == "neutts"
Requires-Dist: resampy==0.4.3; extra == "neutts"
Requires-Dist: pyaudio>=0.2.14; extra == "neutts"
Requires-Dist: neutts; extra == "neutts"
Provides-Extra: neutts-gguf
Requires-Dist: stream2sentence[nltk]>=1.0.4; extra == "neutts-gguf"
Requires-Dist: pydub>=0.25.1; extra == "neutts-gguf"
Requires-Dist: audioop-lts>=0.2.2; python_version >= "3.13" and extra == "neutts-gguf"
Requires-Dist: resampy==0.4.3; extra == "neutts-gguf"
Requires-Dist: pyaudio>=0.2.14; extra == "neutts-gguf"
Requires-Dist: neutts[llama,onnx]; extra == "neutts-gguf"
Provides-Extra: pockettts
Requires-Dist: stream2sentence[nltk]>=1.0.4; extra == "pockettts"
Requires-Dist: pydub>=0.25.1; extra == "pockettts"
Requires-Dist: audioop-lts>=0.2.2; python_version >= "3.13" and extra == "pockettts"
Requires-Dist: resampy==0.4.3; extra == "pockettts"
Requires-Dist: pyaudio>=0.2.14; extra == "pockettts"
Requires-Dist: pocket-tts>=2.1.0; extra == "pockettts"
Requires-Dist: torch; extra == "pockettts"
Provides-Extra: pocket
Requires-Dist: stream2sentence[nltk]>=1.0.4; extra == "pocket"
Requires-Dist: pydub>=0.25.1; extra == "pocket"
Requires-Dist: audioop-lts>=0.2.2; python_version >= "3.13" and extra == "pocket"
Requires-Dist: resampy==0.4.3; extra == "pocket"
Requires-Dist: pyaudio>=0.2.14; extra == "pocket"
Requires-Dist: pocket-tts>=2.1.0; extra == "pocket"
Requires-Dist: torch; extra == "pocket"
Provides-Extra: pockettts-gpu
Requires-Dist: stream2sentence[nltk]>=1.0.4; extra == "pockettts-gpu"
Requires-Dist: pydub>=0.25.1; extra == "pockettts-gpu"
Requires-Dist: audioop-lts>=0.2.2; python_version >= "3.13" and extra == "pockettts-gpu"
Requires-Dist: resampy==0.4.3; extra == "pockettts-gpu"
Requires-Dist: pyaudio>=0.2.14; extra == "pockettts-gpu"
Requires-Dist: torch; extra == "pockettts-gpu"
Requires-Dist: scipy; extra == "pockettts-gpu"
Requires-Dist: safetensors; extra == "pockettts-gpu"
Requires-Dist: huggingface-hub>=0.36.0; extra == "pockettts-gpu"
Provides-Extra: pocket-gpu
Requires-Dist: stream2sentence[nltk]>=1.0.4; extra == "pocket-gpu"
Requires-Dist: pydub>=0.25.1; extra == "pocket-gpu"
Requires-Dist: audioop-lts>=0.2.2; python_version >= "3.13" and extra == "pocket-gpu"
Requires-Dist: resampy==0.4.3; extra == "pocket-gpu"
Requires-Dist: pyaudio>=0.2.14; extra == "pocket-gpu"
Requires-Dist: torch; extra == "pocket-gpu"
Requires-Dist: scipy; extra == "pocket-gpu"
Requires-Dist: safetensors; extra == "pocket-gpu"
Requires-Dist: huggingface-hub>=0.36.0; extra == "pocket-gpu"
Provides-Extra: styletts
Requires-Dist: stream2sentence[nltk]>=1.0.4; extra == "styletts"
Requires-Dist: pydub>=0.25.1; extra == "styletts"
Requires-Dist: audioop-lts>=0.2.2; python_version >= "3.13" and extra == "styletts"
Requires-Dist: resampy==0.4.3; extra == "styletts"
Requires-Dist: pyaudio>=0.2.14; extra == "styletts"
Requires-Dist: torch; extra == "styletts"
Requires-Dist: torchaudio; extra == "styletts"
Requires-Dist: numpy; extra == "styletts"
Requires-Dist: librosa; extra == "styletts"
Requires-Dist: nltk; extra == "styletts"
Requires-Dist: munch; extra == "styletts"
Requires-Dist: PyYAML; extra == "styletts"
Requires-Dist: phonemizer; extra == "styletts"
Provides-Extra: style
Requires-Dist: stream2sentence[nltk]>=1.0.4; extra == "style"
Requires-Dist: pydub>=0.25.1; extra == "style"
Requires-Dist: audioop-lts>=0.2.2; python_version >= "3.13" and extra == "style"
Requires-Dist: resampy==0.4.3; extra == "style"
Requires-Dist: pyaudio>=0.2.14; extra == "style"
Requires-Dist: torch; extra == "style"
Requires-Dist: torchaudio; extra == "style"
Requires-Dist: numpy; extra == "style"
Requires-Dist: librosa; extra == "style"
Requires-Dist: nltk; extra == "style"
Requires-Dist: munch; extra == "style"
Requires-Dist: PyYAML; extra == "style"
Requires-Dist: phonemizer; extra == "style"
Provides-Extra: parler
Requires-Dist: stream2sentence[nltk]>=1.0.4; extra == "parler"
Requires-Dist: pydub>=0.25.1; extra == "parler"
Requires-Dist: audioop-lts>=0.2.2; python_version >= "3.13" and extra == "parler"
Requires-Dist: resampy==0.4.3; extra == "parler"
Requires-Dist: pyaudio>=0.2.14; extra == "parler"
Requires-Dist: torch; extra == "parler"
Requires-Dist: transformers; extra == "parler"
Provides-Extra: moss
Requires-Dist: stream2sentence[nltk]>=1.0.4; extra == "moss"
Requires-Dist: pydub>=0.25.1; extra == "moss"
Requires-Dist: audioop-lts>=0.2.2; python_version >= "3.13" and extra == "moss"
Requires-Dist: resampy==0.4.3; extra == "moss"
Requires-Dist: pyaudio>=0.2.14; extra == "moss"
Requires-Dist: numpy; extra == "moss"
Requires-Dist: soundfile>=0.13.1; extra == "moss"
Requires-Dist: torch; extra == "moss"
Requires-Dist: torchaudio; extra == "moss"
Requires-Dist: onnxruntime; extra == "moss"
Requires-Dist: huggingface-hub>=0.36.0; extra == "moss"
Requires-Dist: nltk; extra == "moss"
Provides-Extra: moss-tts
Requires-Dist: stream2sentence[nltk]>=1.0.4; extra == "moss-tts"
Requires-Dist: pydub>=0.25.1; extra == "moss-tts"
Requires-Dist: audioop-lts>=0.2.2; python_version >= "3.13" and extra == "moss-tts"
Requires-Dist: resampy==0.4.3; extra == "moss-tts"
Requires-Dist: pyaudio>=0.2.14; extra == "moss-tts"
Requires-Dist: numpy; extra == "moss-tts"
Requires-Dist: soundfile>=0.13.1; extra == "moss-tts"
Requires-Dist: torch; extra == "moss-tts"
Requires-Dist: torchaudio; extra == "moss-tts"
Requires-Dist: onnxruntime; extra == "moss-tts"
Requires-Dist: huggingface-hub>=0.36.0; extra == "moss-tts"
Requires-Dist: nltk; extra == "moss-tts"
Provides-Extra: higgs
Requires-Dist: stream2sentence[nltk]>=1.0.4; extra == "higgs"
Requires-Dist: pydub>=0.25.1; extra == "higgs"
Requires-Dist: audioop-lts>=0.2.2; python_version >= "3.13" and extra == "higgs"
Requires-Dist: resampy==0.4.3; extra == "higgs"
Requires-Dist: pyaudio>=0.2.14; extra == "higgs"
Requires-Dist: requests>=2.34.2; extra == "higgs"
Provides-Extra: alignment
Requires-Dist: stream2sentence[nltk]>=1.0.4; extra == "alignment"
Requires-Dist: pydub>=0.25.1; extra == "alignment"
Requires-Dist: audioop-lts>=0.2.2; python_version >= "3.13" and extra == "alignment"
Requires-Dist: resampy==0.4.3; extra == "alignment"
Requires-Dist: pyaudio>=0.2.14; extra == "alignment"
Requires-Dist: torch; extra == "alignment"
Requires-Dist: torchaudio; extra == "alignment"
Provides-Extra: omniasr
Requires-Dist: stream2sentence[nltk]>=1.0.4; extra == "omniasr"
Requires-Dist: pydub>=0.25.1; extra == "omniasr"
Requires-Dist: audioop-lts>=0.2.2; python_version >= "3.13" and extra == "omniasr"
Requires-Dist: resampy==0.4.3; extra == "omniasr"
Requires-Dist: pyaudio>=0.2.14; extra == "omniasr"
Requires-Dist: omnilingual-asr; extra == "omniasr"
Requires-Dist: silero-vad; extra == "omniasr"
Provides-Extra: piper
Requires-Dist: stream2sentence[nltk]>=1.0.4; extra == "piper"
Requires-Dist: pydub>=0.25.1; extra == "piper"
Requires-Dist: audioop-lts>=0.2.2; python_version >= "3.13" and extra == "piper"
Requires-Dist: resampy==0.4.3; extra == "piper"
Requires-Dist: pyaudio>=0.2.14; extra == "piper"
Provides-Extra: qwen
Requires-Dist: stream2sentence[nltk]>=1.0.4; extra == "qwen"
Requires-Dist: pydub>=0.25.1; extra == "qwen"
Requires-Dist: audioop-lts>=0.2.2; python_version >= "3.13" and extra == "qwen"
Requires-Dist: resampy==0.4.3; extra == "qwen"
Requires-Dist: realtimetts-qwen-native[cuda12]==0.2.0; sys_platform == "win32" and extra == "qwen"
Requires-Dist: realtimetts-qwen-native[cuda12]==0.2.0; sys_platform == "linux" and extra == "qwen"
Requires-Dist: numpy; extra == "qwen"
Requires-Dist: soundfile>=0.13.1; extra == "qwen"
Requires-Dist: numba<0.67,>=0.66; sys_platform == "win32" and extra == "qwen"
Requires-Dist: numba<0.63,>=0.62; (sys_platform == "darwin" and platform_machine == "x86_64") and extra == "qwen"
Requires-Dist: pyaudio>=0.2.14; extra == "qwen"
Provides-Extra: qwen-server
Requires-Dist: stream2sentence[nltk]>=1.0.4; extra == "qwen-server"
Requires-Dist: pydub>=0.25.1; extra == "qwen-server"
Requires-Dist: audioop-lts>=0.2.2; python_version >= "3.13" and extra == "qwen-server"
Requires-Dist: resampy==0.4.3; extra == "qwen-server"
Requires-Dist: realtimetts-qwen-native[cuda12]==0.2.0; sys_platform == "win32" and extra == "qwen-server"
Requires-Dist: realtimetts-qwen-native[cuda12]==0.2.0; sys_platform == "linux" and extra == "qwen-server"
Requires-Dist: numpy; extra == "qwen-server"
Requires-Dist: soundfile>=0.13.1; extra == "qwen-server"
Requires-Dist: numba<0.67,>=0.66; sys_platform == "win32" and extra == "qwen-server"
Requires-Dist: numba<0.63,>=0.62; (sys_platform == "darwin" and platform_machine == "x86_64") and extra == "qwen-server"
Requires-Dist: fastapi<1,>=0.115; extra == "qwen-server"
Requires-Dist: uvicorn[standard]<1,>=0.34; extra == "qwen-server"
Requires-Dist: fasttext-predict>=0.9.2.4; extra == "qwen-server"
Provides-Extra: qwen-cpu
Requires-Dist: stream2sentence[nltk]>=1.0.4; extra == "qwen-cpu"
Requires-Dist: pydub>=0.25.1; extra == "qwen-cpu"
Requires-Dist: audioop-lts>=0.2.2; python_version >= "3.13" and extra == "qwen-cpu"
Requires-Dist: resampy==0.4.3; extra == "qwen-cpu"
Requires-Dist: realtimetts-qwen-native-cpu==0.4.2; extra == "qwen-cpu"
Requires-Dist: numpy; extra == "qwen-cpu"
Requires-Dist: soundfile>=0.13.1; extra == "qwen-cpu"
Requires-Dist: numba<0.67,>=0.66; sys_platform == "win32" and extra == "qwen-cpu"
Requires-Dist: numba<0.63,>=0.62; (sys_platform == "darwin" and platform_machine == "x86_64") and extra == "qwen-cpu"
Requires-Dist: pyaudio>=0.2.14; extra == "qwen-cpu"
Provides-Extra: qwen-cpu-server
Requires-Dist: stream2sentence[nltk]>=1.0.4; extra == "qwen-cpu-server"
Requires-Dist: pydub>=0.25.1; extra == "qwen-cpu-server"
Requires-Dist: audioop-lts>=0.2.2; python_version >= "3.13" and extra == "qwen-cpu-server"
Requires-Dist: resampy==0.4.3; extra == "qwen-cpu-server"
Requires-Dist: realtimetts-qwen-native-cpu==0.4.2; extra == "qwen-cpu-server"
Requires-Dist: numpy; extra == "qwen-cpu-server"
Requires-Dist: soundfile>=0.13.1; extra == "qwen-cpu-server"
Requires-Dist: numba<0.67,>=0.66; sys_platform == "win32" and extra == "qwen-cpu-server"
Requires-Dist: numba<0.63,>=0.62; (sys_platform == "darwin" and platform_machine == "x86_64") and extra == "qwen-cpu-server"
Requires-Dist: fastapi<1,>=0.115; extra == "qwen-cpu-server"
Requires-Dist: uvicorn[standard]<1,>=0.34; extra == "qwen-cpu-server"
Requires-Dist: fasttext-predict>=0.9.2.4; extra == "qwen-cpu-server"
Provides-Extra: jp
Requires-Dist: stream2sentence[nltk]>=1.0.4; extra == "jp"
Requires-Dist: pydub>=0.25.1; extra == "jp"
Requires-Dist: audioop-lts>=0.2.2; python_version >= "3.13" and extra == "jp"
Requires-Dist: resampy==0.4.3; extra == "jp"
Requires-Dist: pyaudio>=0.2.14; extra == "jp"
Requires-Dist: mecab-python3>=1.0.12; extra == "jp"
Requires-Dist: unidic-lite>=1.0.8; extra == "jp"
Requires-Dist: cutlet; extra == "jp"
Requires-Dist: fugashi>=1.5.2; extra == "jp"
Requires-Dist: jaconv>=0.5.0; extra == "jp"
Requires-Dist: mojimoji>=0.0.13; extra == "jp"
Requires-Dist: pyopenjtalk>=0.4.1; extra == "jp"
Provides-Extra: zh
Requires-Dist: stream2sentence[nltk]>=1.0.4; extra == "zh"
Requires-Dist: pydub>=0.25.1; extra == "zh"
Requires-Dist: audioop-lts>=0.2.2; python_version >= "3.13" and extra == "zh"
Requires-Dist: resampy==0.4.3; extra == "zh"
Requires-Dist: pyaudio>=0.2.14; extra == "zh"
Requires-Dist: pypinyin>=0.55.0; extra == "zh"
Requires-Dist: ordered_set>=4.1.0; extra == "zh"
Requires-Dist: jieba>=0.42.1; extra == "zh"
Requires-Dist: cn2an>=0.5.24; extra == "zh"
Provides-Extra: ko
Requires-Dist: stream2sentence[nltk]>=1.0.4; extra == "ko"
Requires-Dist: pydub>=0.25.1; extra == "ko"
Requires-Dist: audioop-lts>=0.2.2; python_version >= "3.13" and extra == "ko"
Requires-Dist: resampy==0.4.3; extra == "ko"
Requires-Dist: pyaudio>=0.2.14; extra == "ko"
Requires-Dist: hangul_romanize; extra == "ko"
Dynamic: author
Dynamic: author-email
Dynamic: classifier
Dynamic: description
Dynamic: description-content-type
Dynamic: home-page
Dynamic: keywords
Dynamic: license
Dynamic: license-file
Dynamic: provides-extra
Dynamic: requires-dist
Dynamic: requires-python
Dynamic: summary


To install realtimetts, you need to specify the TTS engine(s) you wish to use.

For example, to install all supported engines:

    pip install realtimetts[all]

To install with the Coqui TTS engine:

    pip install realtimetts[coqui]

Available engine options include:

- **all**: Install all supported engines
- **system**: Local system TTS via `pyttsx3`
- **azure**: Azure Speech Services support
- **elevenlabs**: ElevenLabs API integration
- **openai**: OpenAI TTS services
- **gtts**: Google Text-to-Speech
- **edge**: Microsoft Edge TTS
- **coqui**: Coqui TTS engine
- **camb**: CAMB AI MARS TTS
- **minimax**: MiniMax Cloud TTS
- **cartesia**: Cartesia API integration
- **modelslab**: ModelsLab API integration
- **orpheus**: Orpheus TTS support
- **qwen**: Native qwentts.cpp Qwen3 TTS integration
- **qwen-server**: OpenAI-compatible native Qwen3 TTS HTTP server
- **qwen-cpu**: Native Qwen3 TTS on CPU, without CUDA dependencies
- **qwen-cpu-server**: The same Qwen HTTP/WebSocket API on CPU
- **omnivoice**: Omnivoice TTS integration
- **luxtts**: LuxTTS integration
- **chatterbox**: Chatterbox Turbo integration
- **inflect**: Inflect-Micro-v2 local TTS integration
- **inflect-pytorch**: Inflect-Micro-v2 PyTorch backend only
- **inflect-onnx**: Inflect-Micro-v2 ONNX backend only
- **sopro**: SoproTTS integration
- **soprano**: SopranoTTS integration
- **neutts**: NeuTTS integration
- **zipvoice**: ZipVoice dependency support
- **moss**: MOSS-TTS dependency support
- **higgs**: SGLang-Omni Higgs Audio v3 raw-PCM HTTP streaming integration
- **alignment**: Torchaudio MMS forced character alignment
- **omniasr**: Experimental omniASR CTC word/character alignment
- **pockettts**: PocketTTS integration
- **parler**: Parler TTS integration
- **styletts**: StyleTTS integration
- **piper**: Piper executable engine support
- **typecast**: Typecast API integration
- **nltk**: Default NLTK plus rule-based sentence tokenizer (included by default)
- **stanza**: Add the optional Stanza sentence tokenizer
- **minimal**: Core package only (for custom engine development)

You can install multiple engines by separating them with commas. For example:

    pip install realtimetts[azure,elevenlabs,openai]

# RealtimeTTS

[![PyPI](https://img.shields.io/pypi/v/RealtimeTTS)](https://pypi.org/project/RealtimeTTS/)
[![Downloads](https://static.pepy.tech/badge/RealtimeTTS)](https://www.pepy.tech/projects/realtimetts)
[![GitHub release](https://img.shields.io/github/release/KoljaB/RealtimeTTS.svg)](https://github.com/KoljaB/RealtimeTTS/releases/)

RealtimeTTS is a Python text-to-speech library for applications that need to
turn strings, generators, and LLM token streams into audio with low latency. It
can play speech locally, stream chunks to another process, write WAV files, and
fall back across multiple engines.

The project supports a broad engine matrix: local system voices, cloud APIs,
free service wrappers, local neural models, and voice-cloning stacks.

### Support RealtimeTTS

If RealtimeTTS saved you time, one GitHub star is a simple way to help make it
more stable.

Stars improve visibility, and visibility brings more users, more real-world
testing, more bug reports, more fixes, and better releases for everyone.

## Demo

https://github.com/KoljaB/RealtimeTTS/assets/7604638/87dcd9a5-3a4e-4f57-be45-837fc63237e7

## Recommended Engine: Qwen (GPU and CPU)

For supported Windows and Linux systems with an NVIDIA GPU, **QwenEngine is
currently the recommended and preferred RealtimeTTS engine for high-quality,
low-latency conversational speech**. It offers multilingual Qwen3-TTS quality,
x-vector and ICL voice cloning, native 24 kHz PCM streaming, fast cancellation,
and the same engine either in-process or behind the production Qwen server.

In 10 warm Linux runs on our tuned RTX 4090 setup, the timeline was: about
**35 ms engine TTFT**, another **35 ms until RealtimeTTS emits its first PCM
chunk**, and about **10 ms of silence inside that chunk**. Predicted audible
onset was **80.9 ms** and RTF was **0.108**. These are orientation figures;
measure the complete path on your target system.

RealtimeTTS 0.8.10 also provides `QwenCpuEngine`, using the maintained CPU-only
native runtime with worker-pool improvements and streaming silence trimming. Choose one of
these server installations in a fresh Python 3.11 or 3.12 virtual environment:

```bash
# NVIDIA GPU on Windows or Linux x86-64
python -m pip install "realtimetts[qwen-server]"
realtimetts-qwen-server --device gpu --clone-mode speaker_only --demo-voice
```

```bash
# CPU on Windows: example for 12 physical cores; adjust both worker counts
python -m pip install "realtimetts[qwen-cpu-server]"
realtimetts-qwen-server --device cpu --cpu-threads 6 --cpu-codec-threads 6 --cpu-core-split --cpu-stream-frames 1 --cpu-fused-attention --startup-buffer-ms 80 --onset-silence-profile qwen3_tts_12hz_0_6b_base_q8_v1 --demo-voice
```

Neither server extra needs Torch, a local CUDA Toolkit, or PortAudio. GPU mode
still needs a compatible NVIDIA GPU/driver. CPU wheels support Windows x86-64,
Linux x86-64 with glibc 2.35+, Intel macOS 13+, and Apple Silicon macOS 11+.
x86-64 CPUs require AVX2/FMA/F16C/BMI2. CPU throughput depends on the machine;
older x86 CPUs, Linux ARM CPU, Windows ARM64, and Metal are outside this release.

`--device cpu --cpu-fused-attention --demo-voice` alone keeps serial decoding.
A positive `--cpu-codec-threads` enables overlap; `--cpu-threads` controls code
generation and `--cpu-stream-frames 1` selects 80 ms chunks. Six plus six is an
example for 12 physical cores, not a universal default. On Windows,
`--cpu-core-split` discovers the topology and separates the pools without changing
process priority. It requires enough available cores in the highest performance
class. Omit that Windows-only option on Linux/macOS. See the quick start for
smaller CPUs and the full configuration used in the Windows latency checks.
Studio starts with **0 ms additional browser buffering**, adjustable under
Sampling & options / Codec, transport & more options.

The optional `--demo-voice` prepares a public neutral cloning example, ready to
select as **demo-neutral**. On Windows Ryzen 3900X, use `--preset windows-3900x`
instead of `--device cpu` for the explicit overlap profile. Add
`--cpu-fused-attention` to enable the optional CPU attention optimization. See the
[three-command CPU/GPU uv quick start](docs/qwen-studio.md#quick-start-with-a-cloning-example).

Both servers offer browser playback at `http://127.0.0.1:8080/studio`, early
em-dash speech, streaming segment controls, and language detection. See the
[QwenEngine guide](docs/engines/qwen.md) for models, voices, authentication,
language routing, and reproducing the deployed CPU settings.

CPU decoder overlap is available through explicit worker and chunk settings.
See [CPU scheduling and measured results](docs/qwen-cpu-scheduling.md).
Windows Ryzen 9 3900X users can use the [tested cmd launcher and fresh-venv guide](docs/qwen-cpu-scheduling.md#windows-ryzen-9-3900x-ready-to-run-server).

### Emotional Qwen demo from the video

The complete editable demo is in `tests/faster_qwen_emotions.py`, including the
voice texts and playback loop. Its compact colored output is the default;
add `--verbose` for native diagnostics. Warnings and errors remain visible.
The packaged `RealtimeTTS.qwen_emotions` command is built from the same source.
It keeps the original eleven emotional references/texts and the 0.6B Base Q8
speaker-only workflow. In an activated Python 3.11 or 3.12 environment:

```bash
git clone https://github.com/KoljaB/RealtimeTTS.git
cd RealtimeTTS
python -m pip install -e ".[qwen]"
cd tests
python faster_qwen_emotions.py
```

For CPU use `.[qwen-cpu]` when installing, then run
`python faster_qwen_emotions.py --device cpu`. Local playback on Linux/macOS
needs PortAudio (see below). The first run downloads the model pair if needed.
See the [emotional showcase guide](docs/qwen-emotions.md) for the complete
virtual-environment setup, headless/server mode, and package-only commands.

[`InflectEngine`](docs/engines/inflect.md) is the documented lightweight
alternative for one fixed English voice on CUDA or ONNX CPU.

## Install

For the fastest local smoke test, install the system engine:

```bash
pip install "realtimetts[system]"
```

The `system` and other traditional engine extras use PyAudio. On Linux, install
PortAudio headers before those extras:

```bash
sudo apt-get update
sudo apt-get install python3-dev portaudio19-dev
```

On macOS:

```bash
brew install portaudio
```

The local `qwen`, `qwen-cpu`, and Inflect extras use PyAudio/PortAudio for
playback. Windows has prebuilt PyAudio wheels; on Linux and macOS install
PortAudio first using the commands above. Use Python 3.11 or 3.12 for the
Qwen workflows. Server-only installations do not need audio-device libraries.

Install `realtimetts[qwen-server]` (GPU) or `realtimetts[qwen-cpu-server]` (CPU)
to expose the same native engine through
an OpenAI-compatible HTTP API. The server provides `/v1/audio/speech`, dynamic
voice registration, persistent voice latents, and watchdog-ready request/stall
metrics on `/health`; it is headless and does not install PyAudio/PortAudio.
The server defaults to loopback (`127.0.0.1`). LAN exposure requires a
deliberate `--allow-lan` bind plus a built-in API key, or a trusted reverse
proxy that terminates TLS and enforces authentication. CORS defaults to
explicit localhost origins and rejects wildcard `*`; CORS is not an access
control boundary. See [the Qwen guide](docs/engines/qwen.md#http-server) for
deployment, protocol, licensing, and asset boundaries.

Sentence splitting defaults to stream2sentence's `nltk+rule-based` consensus
mode. The normal install, including `realtimetts[qwen]`, installs
`stream2sentence[nltk]` but not Stanza or PyTorch. Add Stanza only when wanted:

```bash
pip install "realtimetts[stanza]"
# or
pip install "realtimetts[qwen,stanza]"
```

For cloud engines, local neural engines, CUDA, `mpv`, and current packaging
caveats, see [docs/installation.md](docs/installation.md).

## First Audio

```python
from RealtimeTTS import TextToAudioStream, SystemEngine


if __name__ == "__main__":
    stream = TextToAudioStream(SystemEngine())
    stream.feed("Hello from RealtimeTTS.")
    stream.play()
```

Use the `if __name__ == "__main__":` guard in scripts, especially on Windows and
when using engines that start worker processes.

## Streaming Text

`feed()` accepts an iterator, so text can arrive while audio is already playing:

```python
from RealtimeTTS import TextToAudioStream, SystemEngine


def text_chunks():
    yield "This starts speaking quickly. "
    yield "More text can arrive while audio is already playing."


if __name__ == "__main__":
    stream = TextToAudioStream(SystemEngine())
    stream.feed(text_chunks())
    stream.play()
```

Use the same pattern with an LLM client by yielding only non-empty text chunks.
See [docs/llm-streaming.md](docs/llm-streaming.md).

## Output

Write audio to a WAV file without local speaker playback:

```python
from RealtimeTTS import TextToAudioStream, SystemEngine


if __name__ == "__main__":
    stream = TextToAudioStream(SystemEngine())
    stream.feed("Save this speech to a file.")
    stream.play(output_wavfile="speech.wav", muted=True)
```

For output devices, `mpv` playback, muted mode, callbacks, and chunk formats,
see [docs/output-and-files.md](docs/output-and-files.md).

## Features

- Low-latency playback from strings, generators, and streamed model output.
- Multiple engines with local, cloud, free-service, and neural model options.
- Fallback engines for more resilient synthesis.
- Sync and async playback with pause, resume, stop, and state inspection.
- Text, audio, sentence, character, word-timing, and audio-chunk callbacks.
- WAV output, muted synthesis, selected output devices, and volume control.
- Voice switching and voice-cloning workflows where supported by the engine.

## Engine Overview

| Engine | Type | Install/status note | Best first use |
| --- | --- | --- | --- |
| **[`QwenEngine`](docs/engines/qwen.md) (recommended)** | Local native neural / HTTP server | `realtimetts[qwen]` or `realtimetts[qwen-server]` with a matching native wheel | High-quality multilingual realtime speech, voice cloning, and fast cancellation. |
| [`QwenCpuEngine`](docs/engines/qwen.md#cpu-engine) | Local CPU native / HTTP server | `realtimetts[qwen-cpu]` or `realtimetts[qwen-cpu-server]` | CPU-only Qwen on Windows/Linux x86-64 and Intel/Apple Silicon macOS; silence trimming and the same streaming controls. |
| [`InflectEngine`](docs/engines/inflect.md) | Local lightweight | `realtimetts[inflect]` | Fast fixed English voice through PyTorch CUDA or ONNX CPU. |
| [`SystemEngine`](docs/engines/system.md) | Local | `realtimetts[system]` | First local audio smoke test. |
| [`GTTSEngine`](docs/engines/gtts.md) | Free service | `realtimetts[gtts]` | Simple network-backed speech. |
| [`EdgeEngine`](docs/engines/edge.md) | Free service | `realtimetts[edge]`, needs `mpv` | Free streamed voices. |
| [`OpenAIEngine`](docs/engines/openai.md) | Cloud API | `realtimetts[openai]` | OpenAI TTS voices. |
| [`AzureEngine`](docs/engines/azure.md) | Cloud API | `realtimetts[azure]` | Azure voices and word timings. |
| [`ElevenlabsEngine`](docs/engines/elevenlabs.md) | Cloud API | `realtimetts[elevenlabs]`, needs `mpv` | High-quality API voices. |
| [`CambEngine`](docs/engines/camb.md) | Cloud API | `realtimetts[camb]` | CAMB MARS API voices. |
| [`MiniMaxEngine`](docs/engines/minimax.md) | Cloud API | `realtimetts[minimax]` | MiniMax cloud voices. |
| [`CartesiaEngine`](docs/engines/cartesia.md) | Cloud API | `realtimetts[cartesia]` | Cartesia API voices. |
| [`TypecastEngine`](docs/engines/typecast.md) | Cloud API | `realtimetts[typecast]` | Typecast API voices. |
| [`ModelsLabEngine`](docs/engines/modelslab.md) | Cloud API | `realtimetts[modelslab]` | ModelsLab API voices. |
| [`CoquiEngine`](docs/engines/coqui.md) | Local neural | `realtimetts[coqui]` | Local XTTS voice cloning. |
| [`PiperEngine`](docs/engines/piper.md) | Local executable | `realtimetts[piper]`, external Piper setup | Fast local executable TTS. |
| [`StyleTTSEngine`](docs/engines/styletts.md) | Local neural | `realtimetts[styletts]`, local checkout/assets | StyleTTS experiments. |
| [`ParlerEngine`](docs/engines/parler.md) | Local neural | `realtimetts[parler]` | GPU local model experiments. |
| [`KokoroEngine`](docs/engines/kokoro.md) | Local neural | `realtimetts[kokoro]` | Local voices and timing support. |
| [`OrpheusEngine`](docs/engines/orpheus.md) | Local/API-style | `realtimetts[orpheus]` | Orpheus model workflows. |
| [`OmniVoiceEngine`](docs/engines/omnivoice.md) | Local neural | `realtimetts[omnivoice]` | Multilingual voice cloning. |
| [`PocketTTSEngine`](docs/engines/pockettts.md) / `PocketTTSGpuEngine` | Local lightweight | `realtimetts[pockettts]`, `realtimetts[pockettts-gpu]` plus GPU fork | CPU-oriented voice cloning, optional CUDA fork path. |
| [`NeuTTSEngine`](docs/engines/neutts.md) | Local neural | `realtimetts[neutts]`, optional `neutts-gguf` | Reference-audio voice cloning. |
| [`ZipVoiceEngine`](docs/engines/zipvoice.md) | Local neural | `realtimetts[zipvoice]`, external checkout | ZipVoice cloning/server demos. |
| [`LuxTTSEngine`](docs/engines/luxtts.md) | Local neural | `realtimetts[luxtts]` | LuxTTS voice cloning. |
| [`ChatterboxEngine`](docs/engines/chatterbox.md) | Local neural | `realtimetts[chatterbox]` | Chatterbox prompt-audio voices. |
| [`SoproTTSEngine`](docs/engines/sopro.md) | Local neural | `realtimetts[sopro]` | Sopro reference-audio voices. |
| [`SopranoEngine`](docs/engines/soprano.md) | Local neural | `realtimetts[soprano]` | Soprano local synthesis. |
| [`MossTTSEngine`](docs/engines/moss-tts.md) | Local neural | `realtimetts[moss]`, runtime assets | MOSS-TTS experiments. |
| [`HiggsEngine`](docs/engines/higgs.md) | Local HTTP PCM server | `realtimetts[higgs]`, separate SGLang-Omni server | Stream Higgs Audio v3 PCM from a trusted server. |

See [docs/engine-selection.md](docs/engine-selection.md) before choosing an
engine for an application. The engine-specific docs are being split out from the
old README and source audit.

## Documentation

- [Quick start](docs/quick-start.md): shortest working examples.
- [Installation](docs/installation.md): extras, platform setup, external tools,
  API keys, and known packaging mismatches.
- [Engine selection](docs/engine-selection.md): engine matrix and selection
  guidance.
- [Feed and playback](docs/feed-and-playback.md): `feed()`, `play()`,
  `play_async()`, pause, resume, stop, text state, and inline tags.
- [LLM streaming](docs/llm-streaming.md): provider-neutral streamed text
  patterns and latency tuning.
- [Output and files](docs/output-and-files.md): WAV files, audio chunks, muted
  mode, output devices, mpv, buffering, and volume.
- [Forced alignment](docs/ctc-forced-alignment.md): optional word and character
  timing for engines without native timings.
- [Engine setup pages](docs/engine-selection.md) now link one focused page for
  each concrete engine source.
- [FAQ](FAQ.md): legacy troubleshooting page while topic docs are being split
  out.

Legacy translated docs remain under `docs/<locale>/` while English is refactored
as the canonical source.

## Server Example

The browser and WebSocket server example lives in `example_fast_api/`:

```bash
python -m pip install fastapi uvicorn websockets pyaudio
python example_fast_api/async_server.py
```

Open `http://localhost:8000` or connect to `ws://localhost:8000/ws`.

## Related Project

[RealtimeSTT](https://github.com/KoljaB/RealtimeSTT) is the speech-to-text
counterpart for realtime voice input.

## Contributing

Focused docs, tests, and engine fixes are easiest to review. During the docs
refactor, keep English docs canonical and note mismatches between source,
packaging, examples, and tests rather than hiding them.

## License

RealtimeTTS source code is MIT licensed. Engine providers, model weights, voice
data, datasets, generated audio, and third-party services can have separate
terms. Read [LICENSING_ADDENDUM.md](LICENSING_ADDENDUM.md) and the relevant
provider or model licenses before commercial use.

For the native Qwen/Inflect paths, `qwentts.cpp` and `realtimetts-qwen-native` are
MIT-licensed; Qwen 0.6B Base/tokenizer and Inflect Micro-v2/ONNX are
Apache-2.0. Model weights, voice latents, and reference audio are not bundled,
and users are responsible for the rights to every voice or recording they
provide.

Audio samples derived from the EARS dataset by Meta are licensed under CC BY-NC
4.0. See the original dataset terms for details.

## Author

Kolja Beigel
