PyThaiTTS 0.5.0__tar.gz → 0.7.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {pythaitts-0.5.0 → pythaitts-0.7.0}/PKG-INFO +79 -12
- {pythaitts-0.5.0 → pythaitts-0.7.0}/PyThaiTTS.egg-info/PKG-INFO +79 -12
- {pythaitts-0.5.0 → pythaitts-0.7.0}/PyThaiTTS.egg-info/SOURCES.txt +2 -0
- {pythaitts-0.5.0 → pythaitts-0.7.0}/PyThaiTTS.egg-info/requires.txt +9 -1
- {pythaitts-0.5.0 → pythaitts-0.7.0}/README.md +71 -10
- {pythaitts-0.5.0 → pythaitts-0.7.0}/pythaitts/__init__.py +89 -8
- {pythaitts-0.5.0 → pythaitts-0.7.0}/pythaitts/pretrained/fastthaig2p/__init__.py +21 -1
- {pythaitts-0.5.0 → pythaitts-0.7.0}/pythaitts/pretrained/fastthaig2p/tts.py +79 -1
- pythaitts-0.7.0/pythaitts/realtime.py +591 -0
- {pythaitts-0.5.0 → pythaitts-0.7.0}/setup.py +6 -1
- {pythaitts-0.5.0 → pythaitts-0.7.0}/tests/test_fastthaig2p.py +11 -0
- pythaitts-0.7.0/tests/test_realtime.py +302 -0
- {pythaitts-0.5.0 → pythaitts-0.7.0}/tests/test_vachana.py +9 -0
- {pythaitts-0.5.0 → pythaitts-0.7.0}/LICENSE +0 -0
- {pythaitts-0.5.0 → pythaitts-0.7.0}/PyThaiTTS.egg-info/dependency_links.txt +0 -0
- {pythaitts-0.5.0 → pythaitts-0.7.0}/PyThaiTTS.egg-info/not-zip-safe +0 -0
- {pythaitts-0.5.0 → pythaitts-0.7.0}/PyThaiTTS.egg-info/top_level.txt +0 -0
- {pythaitts-0.5.0 → pythaitts-0.7.0}/pythaitts/preprocess.py +0 -0
- {pythaitts-0.5.0 → pythaitts-0.7.0}/pythaitts/pretrained/__init__.py +0 -0
- {pythaitts-0.5.0 → pythaitts-0.7.0}/pythaitts/pretrained/fastthaig2p/_data.py +0 -0
- {pythaitts-0.5.0 → pythaitts-0.7.0}/pythaitts/pretrained/fastthaig2p/_th2ipa.py +0 -0
- {pythaitts-0.5.0 → pythaitts-0.7.0}/pythaitts/pretrained/fastthaig2p/data/dict.txt +0 -0
- {pythaitts-0.5.0 → pythaitts-0.7.0}/pythaitts/pretrained/fastthaig2p/data/fallback/PhSTrigram.sts +0 -0
- {pythaitts-0.5.0 → pythaitts-0.7.0}/pythaitts/pretrained/fastthaig2p/data/fallback/sylform_var.pkl +0 -0
- {pythaitts-0.5.0 → pythaitts-0.7.0}/pythaitts/pretrained/fastthaig2p/data/fallback/sylrule.lts +0 -0
- {pythaitts-0.5.0 → pythaitts-0.7.0}/pythaitts/pretrained/fastthaig2p/data/fallback/sylseg.3g +0 -0
- {pythaitts-0.5.0 → pythaitts-0.7.0}/pythaitts/pretrained/fastthaig2p/data/fallback/thaisyl.dict +0 -0
- {pythaitts-0.5.0 → pythaitts-0.7.0}/pythaitts/pretrained/fastthaig2p/data/fallback/thdict +0 -0
- {pythaitts-0.5.0 → pythaitts-0.7.0}/pythaitts/pretrained/fastthaig2p/data/ipa.json +0 -0
- {pythaitts-0.5.0 → pythaitts-0.7.0}/pythaitts/pretrained/fastthaig2p/fallback.py +0 -0
- {pythaitts-0.5.0 → pythaitts-0.7.0}/pythaitts/pretrained/fastthaig2p/g2p.py +0 -0
- {pythaitts-0.5.0 → pythaitts-0.7.0}/pythaitts/pretrained/fastthaig2p/kokoro.py +0 -0
- {pythaitts-0.5.0 → pythaitts-0.7.0}/pythaitts/pretrained/fastthaig2p/normalizer.py +0 -0
- {pythaitts-0.5.0 → pythaitts-0.7.0}/pythaitts/pretrained/fastthaig2p/tokenizer.py +0 -0
- {pythaitts-0.5.0 → pythaitts-0.7.0}/pythaitts/pretrained/khanomtan_tts.py +0 -0
- {pythaitts-0.5.0 → pythaitts-0.7.0}/pythaitts/pretrained/lunarlist_model.py +0 -0
- {pythaitts-0.5.0 → pythaitts-0.7.0}/pythaitts/pretrained/lunarlist_onnx.py +0 -0
- {pythaitts-0.5.0 → pythaitts-0.7.0}/pythaitts/pretrained/vachana_tts.py +0 -0
- {pythaitts-0.5.0 → pythaitts-0.7.0}/setup.cfg +0 -0
- {pythaitts-0.5.0 → pythaitts-0.7.0}/tests/__init__.py +0 -0
- {pythaitts-0.5.0 → pythaitts-0.7.0}/tests/test_preprocess.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: PyThaiTTS
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.7.0
|
|
4
4
|
Summary: Open Source Thai Text-to-speech library in Python
|
|
5
5
|
Home-page: https://github.com/pythainlp/pythaitts
|
|
6
6
|
Author: Wannaphong
|
|
@@ -24,9 +24,14 @@ License-File: LICENSE
|
|
|
24
24
|
Requires-Dist: huggingface_hub
|
|
25
25
|
Requires-Dist: numpy>=1.22
|
|
26
26
|
Requires-Dist: onnxruntime
|
|
27
|
-
Requires-Dist: vachanatts
|
|
28
27
|
Requires-Dist: soundfile
|
|
29
28
|
Requires-Dist: pythainlp
|
|
29
|
+
Provides-Extra: vachanatts
|
|
30
|
+
Requires-Dist: vachanatts; extra == "vachanatts"
|
|
31
|
+
Provides-Extra: vachana
|
|
32
|
+
Requires-Dist: vachanatts; extra == "vachana"
|
|
33
|
+
Provides-Extra: realtime
|
|
34
|
+
Requires-Dist: RealtimeTTS; extra == "realtime"
|
|
30
35
|
Dynamic: author
|
|
31
36
|
Dynamic: author-email
|
|
32
37
|
Dynamic: classifier
|
|
@@ -37,6 +42,7 @@ Dynamic: keywords
|
|
|
37
42
|
Dynamic: license
|
|
38
43
|
Dynamic: license-file
|
|
39
44
|
Dynamic: project-url
|
|
45
|
+
Dynamic: provides-extra
|
|
40
46
|
Dynamic: requires-dist
|
|
41
47
|
Dynamic: requires-python
|
|
42
48
|
Dynamic: summary
|
|
@@ -44,7 +50,7 @@ Dynamic: summary
|
|
|
44
50
|
# PyThaiTTS
|
|
45
51
|
Open Source Thai Text-to-speech library in Python
|
|
46
52
|
|
|
47
|
-
[Google Colab](https://colab.research.google.com/github/PyThaiNLP/PyThaiTTS/blob/
|
|
53
|
+
[Google Colab](https://colab.research.google.com/github/PyThaiNLP/PyThaiTTS/blob/main/notebook/use_fastthaig2p.ipynb) | [Docs](https://pythainlp.github.io/PyThaiTTS/) | [Notebooks](https://github.com/PyThaiNLP/PyThaiTTS/tree/main/notebook)
|
|
48
54
|
<a href="https://pepy.tech/project/pythaitts"><img alt="Download" src="https://pepy.tech/badge/pythaitts/month"/></a>
|
|
49
55
|
|
|
50
56
|
License: [Apache-2.0 License](https://github.com/PyThaiNLP/pythaitts/blob/main/LICENSE)
|
|
@@ -76,20 +82,20 @@ PyThaiTTS supports multiple TTS models. You can specify which model to use:
|
|
|
76
82
|
```python
|
|
77
83
|
from pythaitts import TTS
|
|
78
84
|
|
|
79
|
-
# Use
|
|
80
|
-
# Sample Rate is
|
|
81
|
-
tts = TTS(pretrained="
|
|
82
|
-
file = tts.tts("สวัสดีครับ", speaker_idx="
|
|
85
|
+
# Use FastThaiG2P (default) (default voice: thai_som)
|
|
86
|
+
# FastThaiG2P Sample Rate is 24000 Hz
|
|
87
|
+
tts = TTS(pretrained="fastthaig2p")
|
|
88
|
+
file = tts.tts("สวัสดีครับ", speaker_idx="thai_som", filename="output.wav")
|
|
83
89
|
|
|
84
|
-
# Use Lunarlist ONNX
|
|
90
|
+
# Use Lunarlist ONNX
|
|
85
91
|
# Sample Rate is 22050 Hz
|
|
86
92
|
tts = TTS(pretrained="lunarlist_onnx")
|
|
87
93
|
file = tts.tts("ภาษาไทย ง่าย มาก", filename="output.wav")
|
|
88
94
|
|
|
89
|
-
# Use
|
|
90
|
-
#
|
|
91
|
-
tts = TTS(pretrained="
|
|
92
|
-
file = tts.tts("สวัสดีครับ", speaker_idx="
|
|
95
|
+
# Use VachanaTTS (default voices: th_f_1, th_m_1, th_f_2, th_m_2)
|
|
96
|
+
# Sample Rate is 22050 Hz
|
|
97
|
+
tts = TTS(pretrained="vachana")
|
|
98
|
+
file = tts.tts("สวัสดีครับ", speaker_idx="th_f_1", filename="output.wav")
|
|
93
99
|
|
|
94
100
|
# Use KhanomTan
|
|
95
101
|
# Sample Rate is 16000 Hz
|
|
@@ -97,6 +103,67 @@ tts = TTS(pretrained="khanomtan")
|
|
|
97
103
|
file = tts.tts("ภาษาไทย", speaker_idx="Linda", filename="output.wav")
|
|
98
104
|
```
|
|
99
105
|
|
|
106
|
+
### Real-time / Streaming TTS (FastThaiG2P)
|
|
107
|
+
|
|
108
|
+
PyThaiTTS supports low-latency, real-time streaming speech synthesis with FastThaiG2P, making it ideal for conversational voice agents and LLM streaming:
|
|
109
|
+
|
|
110
|
+
#### 1. Streaming Audio from Text
|
|
111
|
+
|
|
112
|
+
Synthesize chunk-by-chunk in real time:
|
|
113
|
+
|
|
114
|
+
```python
|
|
115
|
+
from pythaitts import TTS
|
|
116
|
+
|
|
117
|
+
tts = TTS(pretrained="fastthaig2p")
|
|
118
|
+
|
|
119
|
+
# Stream audio chunks as 24kHz float32 NumPy arrays
|
|
120
|
+
for audio_chunk in tts.stream("สวัสดีครับ ยินดีต้อนรับสู่ระบบเรียลไทม์ทีทีเอส"):
|
|
121
|
+
print(f"Audio chunk shape: {audio_chunk.shape}")
|
|
122
|
+
|
|
123
|
+
# Stream raw 16-bit PCM bytes (for WebSockets or PyAudio)
|
|
124
|
+
for pcm_bytes in tts.stream("สวัสดีครับ", return_type="bytes"):
|
|
125
|
+
# send over websocket or write to audio stream
|
|
126
|
+
pass
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
#### 2. Streaming from an LLM Token Stream
|
|
130
|
+
|
|
131
|
+
Feed tokens directly from an LLM or generator into `tts.stream()`:
|
|
132
|
+
|
|
133
|
+
```python
|
|
134
|
+
from pythaitts import TTS
|
|
135
|
+
|
|
136
|
+
tts = TTS()
|
|
137
|
+
|
|
138
|
+
def token_stream():
|
|
139
|
+
tokens = ["สวัสดี", "ครับ", " ", "นี่", "คือ", "การ", "สตรีม", "มิ่ง"]
|
|
140
|
+
for tok in tokens:
|
|
141
|
+
yield tok
|
|
142
|
+
|
|
143
|
+
for audio_chunk in tts.stream(token_stream()):
|
|
144
|
+
# Process or play chunk with low latency
|
|
145
|
+
pass
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
#### 3. Integration with the RealtimeTTS Library
|
|
149
|
+
|
|
150
|
+
You can use FastThaiG2P as an engine with [KoljaB/RealtimeTTS](https://github.com/KoljaB/RealtimeTTS):
|
|
151
|
+
|
|
152
|
+
```sh
|
|
153
|
+
pip install pythaitts[realtime]
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
```python
|
|
157
|
+
from RealtimeTTS import TextToAudioStream
|
|
158
|
+
from pythaitts.realtime import FastThaiG2PEngine
|
|
159
|
+
|
|
160
|
+
engine = FastThaiG2PEngine()
|
|
161
|
+
stream = TextToAudioStream(engine)
|
|
162
|
+
stream.feed("สวัสดีครับ วันนี้อากาศดีมาก")
|
|
163
|
+
stream.play()
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
|
|
100
167
|
### Text Preprocessing
|
|
101
168
|
|
|
102
169
|
PyThaiTTS includes automatic text preprocessing to improve TTS quality:
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: PyThaiTTS
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.7.0
|
|
4
4
|
Summary: Open Source Thai Text-to-speech library in Python
|
|
5
5
|
Home-page: https://github.com/pythainlp/pythaitts
|
|
6
6
|
Author: Wannaphong
|
|
@@ -24,9 +24,14 @@ License-File: LICENSE
|
|
|
24
24
|
Requires-Dist: huggingface_hub
|
|
25
25
|
Requires-Dist: numpy>=1.22
|
|
26
26
|
Requires-Dist: onnxruntime
|
|
27
|
-
Requires-Dist: vachanatts
|
|
28
27
|
Requires-Dist: soundfile
|
|
29
28
|
Requires-Dist: pythainlp
|
|
29
|
+
Provides-Extra: vachanatts
|
|
30
|
+
Requires-Dist: vachanatts; extra == "vachanatts"
|
|
31
|
+
Provides-Extra: vachana
|
|
32
|
+
Requires-Dist: vachanatts; extra == "vachana"
|
|
33
|
+
Provides-Extra: realtime
|
|
34
|
+
Requires-Dist: RealtimeTTS; extra == "realtime"
|
|
30
35
|
Dynamic: author
|
|
31
36
|
Dynamic: author-email
|
|
32
37
|
Dynamic: classifier
|
|
@@ -37,6 +42,7 @@ Dynamic: keywords
|
|
|
37
42
|
Dynamic: license
|
|
38
43
|
Dynamic: license-file
|
|
39
44
|
Dynamic: project-url
|
|
45
|
+
Dynamic: provides-extra
|
|
40
46
|
Dynamic: requires-dist
|
|
41
47
|
Dynamic: requires-python
|
|
42
48
|
Dynamic: summary
|
|
@@ -44,7 +50,7 @@ Dynamic: summary
|
|
|
44
50
|
# PyThaiTTS
|
|
45
51
|
Open Source Thai Text-to-speech library in Python
|
|
46
52
|
|
|
47
|
-
[Google Colab](https://colab.research.google.com/github/PyThaiNLP/PyThaiTTS/blob/
|
|
53
|
+
[Google Colab](https://colab.research.google.com/github/PyThaiNLP/PyThaiTTS/blob/main/notebook/use_fastthaig2p.ipynb) | [Docs](https://pythainlp.github.io/PyThaiTTS/) | [Notebooks](https://github.com/PyThaiNLP/PyThaiTTS/tree/main/notebook)
|
|
48
54
|
<a href="https://pepy.tech/project/pythaitts"><img alt="Download" src="https://pepy.tech/badge/pythaitts/month"/></a>
|
|
49
55
|
|
|
50
56
|
License: [Apache-2.0 License](https://github.com/PyThaiNLP/pythaitts/blob/main/LICENSE)
|
|
@@ -76,20 +82,20 @@ PyThaiTTS supports multiple TTS models. You can specify which model to use:
|
|
|
76
82
|
```python
|
|
77
83
|
from pythaitts import TTS
|
|
78
84
|
|
|
79
|
-
# Use
|
|
80
|
-
# Sample Rate is
|
|
81
|
-
tts = TTS(pretrained="
|
|
82
|
-
file = tts.tts("สวัสดีครับ", speaker_idx="
|
|
85
|
+
# Use FastThaiG2P (default) (default voice: thai_som)
|
|
86
|
+
# FastThaiG2P Sample Rate is 24000 Hz
|
|
87
|
+
tts = TTS(pretrained="fastthaig2p")
|
|
88
|
+
file = tts.tts("สวัสดีครับ", speaker_idx="thai_som", filename="output.wav")
|
|
83
89
|
|
|
84
|
-
# Use Lunarlist ONNX
|
|
90
|
+
# Use Lunarlist ONNX
|
|
85
91
|
# Sample Rate is 22050 Hz
|
|
86
92
|
tts = TTS(pretrained="lunarlist_onnx")
|
|
87
93
|
file = tts.tts("ภาษาไทย ง่าย มาก", filename="output.wav")
|
|
88
94
|
|
|
89
|
-
# Use
|
|
90
|
-
#
|
|
91
|
-
tts = TTS(pretrained="
|
|
92
|
-
file = tts.tts("สวัสดีครับ", speaker_idx="
|
|
95
|
+
# Use VachanaTTS (default voices: th_f_1, th_m_1, th_f_2, th_m_2)
|
|
96
|
+
# Sample Rate is 22050 Hz
|
|
97
|
+
tts = TTS(pretrained="vachana")
|
|
98
|
+
file = tts.tts("สวัสดีครับ", speaker_idx="th_f_1", filename="output.wav")
|
|
93
99
|
|
|
94
100
|
# Use KhanomTan
|
|
95
101
|
# Sample Rate is 16000 Hz
|
|
@@ -97,6 +103,67 @@ tts = TTS(pretrained="khanomtan")
|
|
|
97
103
|
file = tts.tts("ภาษาไทย", speaker_idx="Linda", filename="output.wav")
|
|
98
104
|
```
|
|
99
105
|
|
|
106
|
+
### Real-time / Streaming TTS (FastThaiG2P)
|
|
107
|
+
|
|
108
|
+
PyThaiTTS supports low-latency, real-time streaming speech synthesis with FastThaiG2P, making it ideal for conversational voice agents and LLM streaming:
|
|
109
|
+
|
|
110
|
+
#### 1. Streaming Audio from Text
|
|
111
|
+
|
|
112
|
+
Synthesize chunk-by-chunk in real time:
|
|
113
|
+
|
|
114
|
+
```python
|
|
115
|
+
from pythaitts import TTS
|
|
116
|
+
|
|
117
|
+
tts = TTS(pretrained="fastthaig2p")
|
|
118
|
+
|
|
119
|
+
# Stream audio chunks as 24kHz float32 NumPy arrays
|
|
120
|
+
for audio_chunk in tts.stream("สวัสดีครับ ยินดีต้อนรับสู่ระบบเรียลไทม์ทีทีเอส"):
|
|
121
|
+
print(f"Audio chunk shape: {audio_chunk.shape}")
|
|
122
|
+
|
|
123
|
+
# Stream raw 16-bit PCM bytes (for WebSockets or PyAudio)
|
|
124
|
+
for pcm_bytes in tts.stream("สวัสดีครับ", return_type="bytes"):
|
|
125
|
+
# send over websocket or write to audio stream
|
|
126
|
+
pass
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
#### 2. Streaming from an LLM Token Stream
|
|
130
|
+
|
|
131
|
+
Feed tokens directly from an LLM or generator into `tts.stream()`:
|
|
132
|
+
|
|
133
|
+
```python
|
|
134
|
+
from pythaitts import TTS
|
|
135
|
+
|
|
136
|
+
tts = TTS()
|
|
137
|
+
|
|
138
|
+
def token_stream():
|
|
139
|
+
tokens = ["สวัสดี", "ครับ", " ", "นี่", "คือ", "การ", "สตรีม", "มิ่ง"]
|
|
140
|
+
for tok in tokens:
|
|
141
|
+
yield tok
|
|
142
|
+
|
|
143
|
+
for audio_chunk in tts.stream(token_stream()):
|
|
144
|
+
# Process or play chunk with low latency
|
|
145
|
+
pass
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
#### 3. Integration with the RealtimeTTS Library
|
|
149
|
+
|
|
150
|
+
You can use FastThaiG2P as an engine with [KoljaB/RealtimeTTS](https://github.com/KoljaB/RealtimeTTS):
|
|
151
|
+
|
|
152
|
+
```sh
|
|
153
|
+
pip install pythaitts[realtime]
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
```python
|
|
157
|
+
from RealtimeTTS import TextToAudioStream
|
|
158
|
+
from pythaitts.realtime import FastThaiG2PEngine
|
|
159
|
+
|
|
160
|
+
engine = FastThaiG2PEngine()
|
|
161
|
+
stream = TextToAudioStream(engine)
|
|
162
|
+
stream.feed("สวัสดีครับ วันนี้อากาศดีมาก")
|
|
163
|
+
stream.play()
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
|
|
100
167
|
### Text Preprocessing
|
|
101
168
|
|
|
102
169
|
PyThaiTTS includes automatic text preprocessing to improve TTS quality:
|
|
@@ -9,6 +9,7 @@ PyThaiTTS.egg-info/requires.txt
|
|
|
9
9
|
PyThaiTTS.egg-info/top_level.txt
|
|
10
10
|
pythaitts/__init__.py
|
|
11
11
|
pythaitts/preprocess.py
|
|
12
|
+
pythaitts/realtime.py
|
|
12
13
|
pythaitts/pretrained/__init__.py
|
|
13
14
|
pythaitts/pretrained/khanomtan_tts.py
|
|
14
15
|
pythaitts/pretrained/lunarlist_model.py
|
|
@@ -34,4 +35,5 @@ pythaitts/pretrained/fastthaig2p/data/fallback/thdict
|
|
|
34
35
|
tests/__init__.py
|
|
35
36
|
tests/test_fastthaig2p.py
|
|
36
37
|
tests/test_preprocess.py
|
|
38
|
+
tests/test_realtime.py
|
|
37
39
|
tests/test_vachana.py
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# PyThaiTTS
|
|
2
2
|
Open Source Thai Text-to-speech library in Python
|
|
3
3
|
|
|
4
|
-
[Google Colab](https://colab.research.google.com/github/PyThaiNLP/PyThaiTTS/blob/
|
|
4
|
+
[Google Colab](https://colab.research.google.com/github/PyThaiNLP/PyThaiTTS/blob/main/notebook/use_fastthaig2p.ipynb) | [Docs](https://pythainlp.github.io/PyThaiTTS/) | [Notebooks](https://github.com/PyThaiNLP/PyThaiTTS/tree/main/notebook)
|
|
5
5
|
<a href="https://pepy.tech/project/pythaitts"><img alt="Download" src="https://pepy.tech/badge/pythaitts/month"/></a>
|
|
6
6
|
|
|
7
7
|
License: [Apache-2.0 License](https://github.com/PyThaiNLP/pythaitts/blob/main/LICENSE)
|
|
@@ -33,20 +33,20 @@ PyThaiTTS supports multiple TTS models. You can specify which model to use:
|
|
|
33
33
|
```python
|
|
34
34
|
from pythaitts import TTS
|
|
35
35
|
|
|
36
|
-
# Use
|
|
37
|
-
# Sample Rate is
|
|
38
|
-
tts = TTS(pretrained="
|
|
39
|
-
file = tts.tts("สวัสดีครับ", speaker_idx="
|
|
36
|
+
# Use FastThaiG2P (default) (default voice: thai_som)
|
|
37
|
+
# FastThaiG2P Sample Rate is 24000 Hz
|
|
38
|
+
tts = TTS(pretrained="fastthaig2p")
|
|
39
|
+
file = tts.tts("สวัสดีครับ", speaker_idx="thai_som", filename="output.wav")
|
|
40
40
|
|
|
41
|
-
# Use Lunarlist ONNX
|
|
41
|
+
# Use Lunarlist ONNX
|
|
42
42
|
# Sample Rate is 22050 Hz
|
|
43
43
|
tts = TTS(pretrained="lunarlist_onnx")
|
|
44
44
|
file = tts.tts("ภาษาไทย ง่าย มาก", filename="output.wav")
|
|
45
45
|
|
|
46
|
-
# Use
|
|
47
|
-
#
|
|
48
|
-
tts = TTS(pretrained="
|
|
49
|
-
file = tts.tts("สวัสดีครับ", speaker_idx="
|
|
46
|
+
# Use VachanaTTS (default voices: th_f_1, th_m_1, th_f_2, th_m_2)
|
|
47
|
+
# Sample Rate is 22050 Hz
|
|
48
|
+
tts = TTS(pretrained="vachana")
|
|
49
|
+
file = tts.tts("สวัสดีครับ", speaker_idx="th_f_1", filename="output.wav")
|
|
50
50
|
|
|
51
51
|
# Use KhanomTan
|
|
52
52
|
# Sample Rate is 16000 Hz
|
|
@@ -54,6 +54,67 @@ tts = TTS(pretrained="khanomtan")
|
|
|
54
54
|
file = tts.tts("ภาษาไทย", speaker_idx="Linda", filename="output.wav")
|
|
55
55
|
```
|
|
56
56
|
|
|
57
|
+
### Real-time / Streaming TTS (FastThaiG2P)
|
|
58
|
+
|
|
59
|
+
PyThaiTTS supports low-latency, real-time streaming speech synthesis with FastThaiG2P, making it ideal for conversational voice agents and LLM streaming:
|
|
60
|
+
|
|
61
|
+
#### 1. Streaming Audio from Text
|
|
62
|
+
|
|
63
|
+
Synthesize chunk-by-chunk in real time:
|
|
64
|
+
|
|
65
|
+
```python
|
|
66
|
+
from pythaitts import TTS
|
|
67
|
+
|
|
68
|
+
tts = TTS(pretrained="fastthaig2p")
|
|
69
|
+
|
|
70
|
+
# Stream audio chunks as 24kHz float32 NumPy arrays
|
|
71
|
+
for audio_chunk in tts.stream("สวัสดีครับ ยินดีต้อนรับสู่ระบบเรียลไทม์ทีทีเอส"):
|
|
72
|
+
print(f"Audio chunk shape: {audio_chunk.shape}")
|
|
73
|
+
|
|
74
|
+
# Stream raw 16-bit PCM bytes (for WebSockets or PyAudio)
|
|
75
|
+
for pcm_bytes in tts.stream("สวัสดีครับ", return_type="bytes"):
|
|
76
|
+
# send over websocket or write to audio stream
|
|
77
|
+
pass
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
#### 2. Streaming from an LLM Token Stream
|
|
81
|
+
|
|
82
|
+
Feed tokens directly from an LLM or generator into `tts.stream()`:
|
|
83
|
+
|
|
84
|
+
```python
|
|
85
|
+
from pythaitts import TTS
|
|
86
|
+
|
|
87
|
+
tts = TTS()
|
|
88
|
+
|
|
89
|
+
def token_stream():
|
|
90
|
+
tokens = ["สวัสดี", "ครับ", " ", "นี่", "คือ", "การ", "สตรีม", "มิ่ง"]
|
|
91
|
+
for tok in tokens:
|
|
92
|
+
yield tok
|
|
93
|
+
|
|
94
|
+
for audio_chunk in tts.stream(token_stream()):
|
|
95
|
+
# Process or play chunk with low latency
|
|
96
|
+
pass
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
#### 3. Integration with the RealtimeTTS Library
|
|
100
|
+
|
|
101
|
+
You can use FastThaiG2P as an engine with [KoljaB/RealtimeTTS](https://github.com/KoljaB/RealtimeTTS):
|
|
102
|
+
|
|
103
|
+
```sh
|
|
104
|
+
pip install pythaitts[realtime]
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
```python
|
|
108
|
+
from RealtimeTTS import TextToAudioStream
|
|
109
|
+
from pythaitts.realtime import FastThaiG2PEngine
|
|
110
|
+
|
|
111
|
+
engine = FastThaiG2PEngine()
|
|
112
|
+
stream = TextToAudioStream(engine)
|
|
113
|
+
stream.feed("สวัสดีครับ วันนี้อากาศดีมาก")
|
|
114
|
+
stream.play()
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
|
|
57
118
|
### Text Preprocessing
|
|
58
119
|
|
|
59
120
|
PyThaiTTS includes automatic text preprocessing to improve TTS quality:
|
|
@@ -2,18 +2,28 @@
|
|
|
2
2
|
"""
|
|
3
3
|
PyThaiTTS
|
|
4
4
|
"""
|
|
5
|
-
__version__ = "0.
|
|
5
|
+
__version__ = "0.7.0"
|
|
6
|
+
|
|
7
|
+
from typing import Union, Iterable, Iterator
|
|
6
8
|
|
|
7
9
|
from pythaitts.preprocess import preprocess_text, num_to_thai, expand_maiyamok
|
|
10
|
+
from pythaitts.realtime import (
|
|
11
|
+
RealtimeTTS,
|
|
12
|
+
FastThaiG2PEngine,
|
|
13
|
+
PyThaiTTSEngine,
|
|
14
|
+
RealtimeTTSEngine,
|
|
15
|
+
chunk_text,
|
|
16
|
+
stream_text_to_chunks,
|
|
17
|
+
)
|
|
8
18
|
|
|
9
19
|
|
|
10
20
|
class TTS:
|
|
11
|
-
def __init__(self, pretrained="
|
|
21
|
+
def __init__(self, pretrained="fastthaig2p", mode="last_checkpoint", version="1.0", device:str="cpu", **kwargs) -> None:
|
|
12
22
|
"""
|
|
13
|
-
:param str pretrained: TTS pretrained (lunarlist_onnx, khanomtan, lunarlist, vachana
|
|
14
|
-
:param str mode: pretrained mode (
|
|
23
|
+
:param str pretrained: TTS pretrained (fastthaig2p, lunarlist_onnx, khanomtan, lunarlist, vachana)
|
|
24
|
+
:param str mode: pretrained mode (fastthaig2p, lunarlist_onnx, and vachana don't support)
|
|
15
25
|
:param str version: model version (default is 1.0 or 1.1)
|
|
16
|
-
:param str device: device for running model. (lunarlist_onnx and vachana support CPU only.)
|
|
26
|
+
:param str device: device for running model. (fastthaig2p, lunarlist_onnx, and vachana support CPU only.)
|
|
17
27
|
|
|
18
28
|
**Options for mode**
|
|
19
29
|
* *last_checkpoint* (default) - last checkpoint of model
|
|
@@ -29,7 +39,7 @@ class TTS:
|
|
|
29
39
|
For lunarlist_onnx tts model, \
|
|
30
40
|
You can see more about lunarlist tts at `https://github.com/PyThaiNLP/thaitts-onnx <https://github.com/PyThaiNLP/thaitts-onnx>`_
|
|
31
41
|
|
|
32
|
-
For vachana tts model,
|
|
42
|
+
For vachana tts model, you must install vachanatts before using the model by pip install vachanatts.
|
|
33
43
|
You can see more about vachana tts at `https://github.com/VYNCX/VachanaTTS2 <https://github.com/VYNCX/VachanaTTS2>`_
|
|
34
44
|
|
|
35
45
|
For fastthaig2p tts model, \
|
|
@@ -64,12 +74,12 @@ class TTS:
|
|
|
64
74
|
"PyThaiTTS doesn't support %s pretrained." % self.pretrained
|
|
65
75
|
)
|
|
66
76
|
|
|
67
|
-
def tts(self, text: str, speaker_idx: str = "
|
|
77
|
+
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):
|
|
68
78
|
"""
|
|
69
79
|
speech synthesis
|
|
70
80
|
|
|
71
81
|
:param str text: text
|
|
72
|
-
:param str speaker_idx: speaker (default is
|
|
82
|
+
:param str speaker_idx: speaker (default is thai_som for fastthaig2p, Linda for khanomtan, th_f_1 for vachana)
|
|
73
83
|
:param str language_idx: language (default is th-th)
|
|
74
84
|
:param str return_type: return type (default is file)
|
|
75
85
|
:param str filename: path filename for save wav file if return_type is file.
|
|
@@ -84,11 +94,15 @@ class TTS:
|
|
|
84
94
|
if self.pretrained == "lunarlist" or self.pretrained == "lunarlist_onnx":
|
|
85
95
|
return self.model(text=text,return_type=return_type,filename=filename)
|
|
86
96
|
elif self.pretrained == "vachana":
|
|
97
|
+
if speaker_idx in ("thai_som", "Linda", None):
|
|
98
|
+
speaker_idx = "th_f_1"
|
|
87
99
|
return self.model(text=text,speaker_idx=speaker_idx,return_type=return_type,filename=filename, **kwargs)
|
|
88
100
|
elif self.pretrained in ("fastthaig2p", "FastThaiG2P"):
|
|
89
101
|
if speaker_idx in ("Linda", None):
|
|
90
102
|
speaker_idx = "thai_som"
|
|
91
103
|
return self.model(text=text,speaker_idx=speaker_idx,return_type=return_type,filename=filename, **kwargs)
|
|
104
|
+
if speaker_idx in ("thai_som", None):
|
|
105
|
+
speaker_idx = "Linda"
|
|
92
106
|
return self.model(
|
|
93
107
|
text=text,
|
|
94
108
|
speaker_idx=speaker_idx,
|
|
@@ -96,3 +110,70 @@ class TTS:
|
|
|
96
110
|
return_type=return_type,
|
|
97
111
|
filename=filename
|
|
98
112
|
)
|
|
113
|
+
|
|
114
|
+
def stream(
|
|
115
|
+
self,
|
|
116
|
+
text: Union[str, Iterable[str]],
|
|
117
|
+
speaker_idx: str = "thai_som",
|
|
118
|
+
return_type: str = "waveform",
|
|
119
|
+
play: bool = False,
|
|
120
|
+
preprocess: bool = True,
|
|
121
|
+
max_phonemes: int = 400,
|
|
122
|
+
**kwargs,
|
|
123
|
+
):
|
|
124
|
+
"""
|
|
125
|
+
Stream speech synthesis in real-time.
|
|
126
|
+
|
|
127
|
+
:param Union[str, Iterable[str]] text: Input text or stream of text tokens (e.g. from LLM)
|
|
128
|
+
:param str speaker_idx: Voice to use (default: "thai_som" for fastthaig2p)
|
|
129
|
+
:param str return_type: Return format ("waveform", "bytes", "raw", "file")
|
|
130
|
+
:param bool play: Whether to play audio chunks in real-time to speakers
|
|
131
|
+
:param bool preprocess: Whether to preprocess text (numbers to words, ๆ)
|
|
132
|
+
:param int max_phonemes: Maximum phonemes per synthesized chunk
|
|
133
|
+
:param kwargs: Additional parameters passed to the model
|
|
134
|
+
:return: Generator yielding audio chunks
|
|
135
|
+
"""
|
|
136
|
+
if self.pretrained in ("fastthaig2p", "FastThaiG2P"):
|
|
137
|
+
if speaker_idx in ("Linda", None):
|
|
138
|
+
speaker_idx = "thai_som"
|
|
139
|
+
return self.model.stream(
|
|
140
|
+
text=text,
|
|
141
|
+
speaker_idx=speaker_idx,
|
|
142
|
+
return_type=return_type,
|
|
143
|
+
play=play,
|
|
144
|
+
preprocess=preprocess,
|
|
145
|
+
max_phonemes=max_phonemes,
|
|
146
|
+
**kwargs,
|
|
147
|
+
)
|
|
148
|
+
else:
|
|
149
|
+
from pythaitts.realtime import stream_text_to_chunks
|
|
150
|
+
|
|
151
|
+
def _gen():
|
|
152
|
+
for chunk in stream_text_to_chunks(
|
|
153
|
+
text, max_phonemes=max_phonemes, preprocess=preprocess
|
|
154
|
+
):
|
|
155
|
+
yield self.tts(
|
|
156
|
+
text=chunk,
|
|
157
|
+
speaker_idx=speaker_idx,
|
|
158
|
+
return_type=return_type,
|
|
159
|
+
preprocess=False,
|
|
160
|
+
**kwargs,
|
|
161
|
+
)
|
|
162
|
+
|
|
163
|
+
return _gen()
|
|
164
|
+
|
|
165
|
+
tts_stream = stream
|
|
166
|
+
|
|
167
|
+
|
|
168
|
+
__all__ = [
|
|
169
|
+
"TTS",
|
|
170
|
+
"RealtimeTTS",
|
|
171
|
+
"FastThaiG2PEngine",
|
|
172
|
+
"PyThaiTTSEngine",
|
|
173
|
+
"RealtimeTTSEngine",
|
|
174
|
+
"preprocess_text",
|
|
175
|
+
"num_to_thai",
|
|
176
|
+
"expand_maiyamok",
|
|
177
|
+
"chunk_text",
|
|
178
|
+
"stream_text_to_chunks",
|
|
179
|
+
]
|
|
@@ -23,7 +23,18 @@ from .kokoro import ipa_to_kokoro
|
|
|
23
23
|
from .normalizer import normalize
|
|
24
24
|
from .tokenizer import Tokenizer
|
|
25
25
|
|
|
26
|
-
__all__ = [
|
|
26
|
+
__all__ = [
|
|
27
|
+
"G2P",
|
|
28
|
+
"Tokenizer",
|
|
29
|
+
"normalize",
|
|
30
|
+
"ipa_to_kokoro",
|
|
31
|
+
"TTS",
|
|
32
|
+
"FastThaiG2P",
|
|
33
|
+
"FastThaiG2PEngine",
|
|
34
|
+
"FastThaiG2PVoice",
|
|
35
|
+
"chunk_text",
|
|
36
|
+
"stream_text_to_chunks",
|
|
37
|
+
]
|
|
27
38
|
|
|
28
39
|
|
|
29
40
|
def __getattr__(name):
|
|
@@ -31,5 +42,14 @@ def __getattr__(name):
|
|
|
31
42
|
from .tts import TTS, FastThaiG2P
|
|
32
43
|
|
|
33
44
|
return FastThaiG2P if name == "FastThaiG2P" else TTS
|
|
45
|
+
if name in ("FastThaiG2PEngine", "FastThaiG2PVoice", "chunk_text", "stream_text_to_chunks"):
|
|
46
|
+
from pythaitts.realtime import (
|
|
47
|
+
FastThaiG2PEngine,
|
|
48
|
+
FastThaiG2PVoice,
|
|
49
|
+
chunk_text,
|
|
50
|
+
stream_text_to_chunks,
|
|
51
|
+
)
|
|
52
|
+
|
|
53
|
+
return locals()[name]
|
|
34
54
|
raise AttributeError(f"module {__name__!r} has no attribute {name!r}")
|
|
35
55
|
|