# -*- coding: utf-8 -*-
"""
PyThaiTTS
"""
__version__ = "0.8.0"
from typing import Union, Iterable, Iterator
from pythaitts.preprocess import preprocess_text, num_to_thai, expand_maiyamok
from pythaitts.pretrained.fastthaig2p.en_g2p import (
EnglishG2P,
en_g2p,
en_ipa_to_thai_ipa,
en_to_ipa,
)
from pythaitts.realtime import (
RealtimeTTS,
FastThaiG2PEngine,
PyThaiTTSEngine,
RealtimeTTSEngine,
chunk_text,
stream_text_to_chunks,
)
[docs]
class TTS:
[docs]
def __init__(self, pretrained="fastthaig2p", mode="last_checkpoint", version="1.0", device:str="cpu", **kwargs) -> None:
"""
:param str pretrained: TTS pretrained (fastthaig2p, lunarlist_onnx, khanomtan, lunarlist, vachana)
:param str mode: pretrained mode (fastthaig2p, lunarlist_onnx, and vachana don't support)
:param str version: model version (default is 1.0 or 1.1)
:param str device: device for running model. (fastthaig2p, lunarlist_onnx, and vachana support CPU only.)
**Options for mode**
* *last_checkpoint* (default) - last checkpoint of model
* *best_model* - Best model (best loss)
You can see more about khanomtan tts at `https://github.com/wannaphong/KhanomTan-TTS-v1.0 <https://github.com/wannaphong/KhanomTan-TTS-v1.0>`_
and `https://github.com/wannaphong/KhanomTan-TTS-v1.1 <https://github.com/wannaphong/KhanomTan-TTS-v1.1>`_
If you want to use khanomtan tts, you must to install coqui-tts before use the model by pip install coqui-tts.
For lunarlist tts model, you must to install nemo before use the model by pip install nemo_toolkit['tts'].
You can see more about lunarlist tts at `https://link.medium.com/OpPjQis6wBb <https://link.medium.com/OpPjQis6wBb>`_
For lunarlist_onnx tts model, \
You can see more about lunarlist tts at `https://github.com/PyThaiNLP/thaitts-onnx <https://github.com/PyThaiNLP/thaitts-onnx>`_
For vachana tts model, you must install vachanatts before using the model by pip install vachanatts.
You can see more about vachana tts at `https://github.com/VYNCX/VachanaTTS2 <https://github.com/VYNCX/VachanaTTS2>`_
For fastthaig2p tts model, \
You can see more about fastthaig2p at `https://github.com/awslabs/FastThaiG2P <https://github.com/awslabs/FastThaiG2P>`_
"""
self.pretrained = pretrained
self.mode = mode
self.device = device
self.load_pretrained(version=version, **kwargs)
[docs]
def load_pretrained(self, version="1.0", **kwargs):
"""
Load pretrained
"""
if self.pretrained == "lunarlist_onnx":
from pythaitts.pretrained.lunarlist_onnx import LunarlistONNX
self.model = LunarlistONNX()
elif self.pretrained == "khanomtan":
from pythaitts.pretrained.khanomtan_tts import KhanomTan
self.model = KhanomTan(mode=self.mode, version=version)
elif self.pretrained == "lunarlist":
from pythaitts.pretrained.lunarlist_model import LunarlistModel
self.model = LunarlistModel(mode=self.mode, device=self.device)
elif self.pretrained == "vachana":
from pythaitts.pretrained.vachana_tts import VachanaTTS
self.model = VachanaTTS()
elif self.pretrained in ("fastthaig2p", "FastThaiG2P"):
from pythaitts.pretrained.fastthaig2p import FastThaiG2P
self.model = FastThaiG2P(device=self.device, **kwargs)
else:
raise NotImplementedError(
"PyThaiTTS doesn't support %s pretrained." % self.pretrained
)
[docs]
def tts(self, text: str, speaker_idx: str = "thai_som", language_idx: str = "th-th", return_type: str = "file", filename: str = None, preprocess: bool = True, **kwargs):
"""
speech synthesis
:param str text: text
:param str speaker_idx: speaker (default is thai_som for fastthaig2p, Linda for khanomtan, th_f_1 for vachana)
:param str language_idx: language (default is th-th)
:param str return_type: return type (default is file)
:param str filename: path filename for save wav file if return_type is file.
:param bool preprocess: whether to preprocess text (convert numbers to Thai text and expand ๆ). Default is True.
:param kwargs: Additional parameters passed to the underlying model.
"""
# Preprocess text if requested
if preprocess:
from pythaitts.preprocess import preprocess_text
text = preprocess_text(text)
if self.pretrained == "lunarlist" or self.pretrained == "lunarlist_onnx":
return self.model(text=text,return_type=return_type,filename=filename)
elif self.pretrained == "vachana":
if speaker_idx in ("thai_som", "Linda", None):
speaker_idx = "th_f_1"
return self.model(text=text,speaker_idx=speaker_idx,return_type=return_type,filename=filename, **kwargs)
elif self.pretrained in ("fastthaig2p", "FastThaiG2P"):
if speaker_idx in ("Linda", None):
speaker_idx = "thai_som"
return self.model(text=text,speaker_idx=speaker_idx,return_type=return_type,filename=filename, **kwargs)
if speaker_idx in ("thai_som", None):
speaker_idx = "Linda"
return self.model(
text=text,
speaker_idx=speaker_idx,
language_idx=language_idx,
return_type=return_type,
filename=filename
)
[docs]
def stream(
self,
text: Union[str, Iterable[str]],
speaker_idx: str = "thai_som",
return_type: str = "waveform",
play: bool = False,
preprocess: bool = True,
max_phonemes: int = 400,
**kwargs,
):
"""
Stream speech synthesis in real-time.
:param Union[str, Iterable[str]] text: Input text or stream of text tokens (e.g. from LLM)
:param str speaker_idx: Voice to use (default: "thai_som" for fastthaig2p)
:param str return_type: Return format ("waveform", "bytes", "raw", "file")
:param bool play: Whether to play audio chunks in real-time to speakers
:param bool preprocess: Whether to preprocess text (numbers to words, ๆ)
:param int max_phonemes: Maximum phonemes per synthesized chunk
:param kwargs: Additional parameters passed to the model
:return: Generator yielding audio chunks
"""
if self.pretrained in ("fastthaig2p", "FastThaiG2P"):
if speaker_idx in ("Linda", None):
speaker_idx = "thai_som"
return self.model.stream(
text=text,
speaker_idx=speaker_idx,
return_type=return_type,
play=play,
preprocess=preprocess,
max_phonemes=max_phonemes,
**kwargs,
)
else:
from pythaitts.realtime import stream_text_to_chunks
def _gen():
for chunk in stream_text_to_chunks(
text, max_phonemes=max_phonemes, preprocess=preprocess
):
yield self.tts(
text=chunk,
speaker_idx=speaker_idx,
return_type=return_type,
preprocess=False,
**kwargs,
)
return _gen()
tts_stream = stream
__all__ = [
"TTS",
"RealtimeTTS",
"FastThaiG2PEngine",
"PyThaiTTSEngine",
"RealtimeTTSEngine",
"EnglishG2P",
"en_g2p",
"en_to_ipa",
"en_ipa_to_thai_ipa",
"preprocess_text",
"num_to_thai",
"expand_maiyamok",
"chunk_text",
"stream_text_to_chunks",
]