PyThaiTTS 0.6.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.
Files changed (41) hide show
  1. {pythaitts-0.6.0 → pythaitts-0.7.0}/PKG-INFO +64 -1
  2. {pythaitts-0.6.0 → pythaitts-0.7.0}/PyThaiTTS.egg-info/PKG-INFO +64 -1
  3. {pythaitts-0.6.0 → pythaitts-0.7.0}/PyThaiTTS.egg-info/SOURCES.txt +2 -0
  4. {pythaitts-0.6.0 → pythaitts-0.7.0}/PyThaiTTS.egg-info/requires.txt +3 -0
  5. {pythaitts-0.6.0 → pythaitts-0.7.0}/README.md +61 -0
  6. {pythaitts-0.6.0 → pythaitts-0.7.0}/pythaitts/__init__.py +78 -1
  7. {pythaitts-0.6.0 → pythaitts-0.7.0}/pythaitts/pretrained/fastthaig2p/__init__.py +21 -1
  8. {pythaitts-0.6.0 → pythaitts-0.7.0}/pythaitts/pretrained/fastthaig2p/tts.py +79 -1
  9. pythaitts-0.7.0/pythaitts/realtime.py +591 -0
  10. {pythaitts-0.6.0 → pythaitts-0.7.0}/setup.py +2 -1
  11. pythaitts-0.7.0/tests/test_realtime.py +302 -0
  12. {pythaitts-0.6.0 → pythaitts-0.7.0}/LICENSE +0 -0
  13. {pythaitts-0.6.0 → pythaitts-0.7.0}/PyThaiTTS.egg-info/dependency_links.txt +0 -0
  14. {pythaitts-0.6.0 → pythaitts-0.7.0}/PyThaiTTS.egg-info/not-zip-safe +0 -0
  15. {pythaitts-0.6.0 → pythaitts-0.7.0}/PyThaiTTS.egg-info/top_level.txt +0 -0
  16. {pythaitts-0.6.0 → pythaitts-0.7.0}/pythaitts/preprocess.py +0 -0
  17. {pythaitts-0.6.0 → pythaitts-0.7.0}/pythaitts/pretrained/__init__.py +0 -0
  18. {pythaitts-0.6.0 → pythaitts-0.7.0}/pythaitts/pretrained/fastthaig2p/_data.py +0 -0
  19. {pythaitts-0.6.0 → pythaitts-0.7.0}/pythaitts/pretrained/fastthaig2p/_th2ipa.py +0 -0
  20. {pythaitts-0.6.0 → pythaitts-0.7.0}/pythaitts/pretrained/fastthaig2p/data/dict.txt +0 -0
  21. {pythaitts-0.6.0 → pythaitts-0.7.0}/pythaitts/pretrained/fastthaig2p/data/fallback/PhSTrigram.sts +0 -0
  22. {pythaitts-0.6.0 → pythaitts-0.7.0}/pythaitts/pretrained/fastthaig2p/data/fallback/sylform_var.pkl +0 -0
  23. {pythaitts-0.6.0 → pythaitts-0.7.0}/pythaitts/pretrained/fastthaig2p/data/fallback/sylrule.lts +0 -0
  24. {pythaitts-0.6.0 → pythaitts-0.7.0}/pythaitts/pretrained/fastthaig2p/data/fallback/sylseg.3g +0 -0
  25. {pythaitts-0.6.0 → pythaitts-0.7.0}/pythaitts/pretrained/fastthaig2p/data/fallback/thaisyl.dict +0 -0
  26. {pythaitts-0.6.0 → pythaitts-0.7.0}/pythaitts/pretrained/fastthaig2p/data/fallback/thdict +0 -0
  27. {pythaitts-0.6.0 → pythaitts-0.7.0}/pythaitts/pretrained/fastthaig2p/data/ipa.json +0 -0
  28. {pythaitts-0.6.0 → pythaitts-0.7.0}/pythaitts/pretrained/fastthaig2p/fallback.py +0 -0
  29. {pythaitts-0.6.0 → pythaitts-0.7.0}/pythaitts/pretrained/fastthaig2p/g2p.py +0 -0
  30. {pythaitts-0.6.0 → pythaitts-0.7.0}/pythaitts/pretrained/fastthaig2p/kokoro.py +0 -0
  31. {pythaitts-0.6.0 → pythaitts-0.7.0}/pythaitts/pretrained/fastthaig2p/normalizer.py +0 -0
  32. {pythaitts-0.6.0 → pythaitts-0.7.0}/pythaitts/pretrained/fastthaig2p/tokenizer.py +0 -0
  33. {pythaitts-0.6.0 → pythaitts-0.7.0}/pythaitts/pretrained/khanomtan_tts.py +0 -0
  34. {pythaitts-0.6.0 → pythaitts-0.7.0}/pythaitts/pretrained/lunarlist_model.py +0 -0
  35. {pythaitts-0.6.0 → pythaitts-0.7.0}/pythaitts/pretrained/lunarlist_onnx.py +0 -0
  36. {pythaitts-0.6.0 → pythaitts-0.7.0}/pythaitts/pretrained/vachana_tts.py +0 -0
  37. {pythaitts-0.6.0 → pythaitts-0.7.0}/setup.cfg +0 -0
  38. {pythaitts-0.6.0 → pythaitts-0.7.0}/tests/__init__.py +0 -0
  39. {pythaitts-0.6.0 → pythaitts-0.7.0}/tests/test_fastthaig2p.py +0 -0
  40. {pythaitts-0.6.0 → pythaitts-0.7.0}/tests/test_preprocess.py +0 -0
  41. {pythaitts-0.6.0 → pythaitts-0.7.0}/tests/test_vachana.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: PyThaiTTS
3
- Version: 0.6.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
@@ -30,6 +30,8 @@ Provides-Extra: vachanatts
30
30
  Requires-Dist: vachanatts; extra == "vachanatts"
31
31
  Provides-Extra: vachana
32
32
  Requires-Dist: vachanatts; extra == "vachana"
33
+ Provides-Extra: realtime
34
+ Requires-Dist: RealtimeTTS; extra == "realtime"
33
35
  Dynamic: author
34
36
  Dynamic: author-email
35
37
  Dynamic: classifier
@@ -101,6 +103,67 @@ tts = TTS(pretrained="khanomtan")
101
103
  file = tts.tts("ภาษาไทย", speaker_idx="Linda", filename="output.wav")
102
104
  ```
103
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
+
104
167
  ### Text Preprocessing
105
168
 
106
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.6.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
@@ -30,6 +30,8 @@ Provides-Extra: vachanatts
30
30
  Requires-Dist: vachanatts; extra == "vachanatts"
31
31
  Provides-Extra: vachana
32
32
  Requires-Dist: vachanatts; extra == "vachana"
33
+ Provides-Extra: realtime
34
+ Requires-Dist: RealtimeTTS; extra == "realtime"
33
35
  Dynamic: author
34
36
  Dynamic: author-email
35
37
  Dynamic: classifier
@@ -101,6 +103,67 @@ tts = TTS(pretrained="khanomtan")
101
103
  file = tts.tts("ภาษาไทย", speaker_idx="Linda", filename="output.wav")
102
104
  ```
103
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
+
104
167
  ### Text Preprocessing
105
168
 
106
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
@@ -4,6 +4,9 @@ onnxruntime
4
4
  soundfile
5
5
  pythainlp
6
6
 
7
+ [realtime]
8
+ RealtimeTTS
9
+
7
10
  [vachana]
8
11
  vachanatts
9
12
 
@@ -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,9 +2,19 @@
2
2
  """
3
3
  PyThaiTTS
4
4
  """
5
- __version__ = "0.6.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:
@@ -100,3 +110,70 @@ class TTS:
100
110
  return_type=return_type,
101
111
  filename=filename
102
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__ = ["G2P", "Tokenizer", "normalize", "ipa_to_kokoro", "TTS", "FastThaiG2P"]
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
 
@@ -32,7 +32,7 @@ import json
32
32
  import os
33
33
  import wave
34
34
  from pathlib import Path
35
- from typing import Optional
35
+ from typing import Optional, Union, Iterable, Iterator
36
36
 
37
37
  import numpy as np
38
38
 
@@ -277,6 +277,84 @@ class TTS:
277
277
  self.synthesize(text, filename)
278
278
  return str(filename)
279
279
 
280
+ def stream(
281
+ self,
282
+ text: Union[str, Iterable[str]],
283
+ speaker_idx: str = "thai_som",
284
+ return_type: str = "waveform",
285
+ play: bool = False,
286
+ preprocess: bool = True,
287
+ max_phonemes: int = 400,
288
+ **kwargs,
289
+ ):
290
+ """Stream Thai speech generation chunk by chunk in real-time.
291
+
292
+ :param Union[str, Iterable[str]] text: Input text or stream of text tokens (e.g. from LLM)
293
+ :param str speaker_idx: Voice to use (default: "thai_som" or path to custom voicepack)
294
+ :param str return_type: Return format ("waveform", "bytes", "raw", "file")
295
+ :param bool play: Whether to play audio chunks in real-time to speakers
296
+ :param bool preprocess: Whether to preprocess text (numbers to words, ๆ)
297
+ :param int max_phonemes: Maximum phonemes per synthesized chunk (default: 400)
298
+ :param kwargs: Additional parameters (e.g., speed)
299
+ :yield: Audio chunk (np.ndarray float32 waveform, int16 bytes, or wav file path)
300
+ """
301
+ if speaker_idx in ("Linda", None):
302
+ speaker_idx = "thai_som"
303
+
304
+ if speaker_idx not in self.SUPPORTED_VOICES and not os.path.exists(str(speaker_idx)):
305
+ raise ValueError(
306
+ f"Unsupported voice '{speaker_idx}'. Supported voices are: {', '.join(self.SUPPORTED_VOICES)}"
307
+ )
308
+
309
+ orig_speed = self.speed
310
+ if "speed" in kwargs:
311
+ self.speed = kwargs["speed"]
312
+
313
+ from pythaitts.realtime import _AudioPlayer, stream_text_to_chunks
314
+
315
+ player = _AudioPlayer(sample_rate=self.sample_rate) if play else None
316
+
317
+ try:
318
+ chunks = stream_text_to_chunks(
319
+ text,
320
+ max_phonemes=max_phonemes,
321
+ preprocess=preprocess,
322
+ g2p_converter=self._text_to_phonemes,
323
+ )
324
+ for chunk in chunks:
325
+ audio = self.generate(chunk)
326
+ if len(audio) == 0:
327
+ continue
328
+
329
+ if player is not None:
330
+ player.play(audio)
331
+
332
+ if return_type == "waveform":
333
+ yield audio
334
+ elif return_type in ("bytes", "raw"):
335
+ yield (np.clip(audio, -1.0, 1.0) * 32767).astype(np.int16).tobytes()
336
+ elif return_type == "file":
337
+ import tempfile
338
+ with tempfile.NamedTemporaryFile(suffix=".wav", delete=False) as fp:
339
+ temp_name = fp.name
340
+ audio_int16 = (np.clip(audio, -1.0, 1.0) * 32767).astype(np.int16)
341
+ with wave.open(temp_name, "wb") as wf:
342
+ wf.setnchannels(1)
343
+ wf.setsampwidth(2)
344
+ wf.setframerate(self.sample_rate)
345
+ wf.writeframes(audio_int16.tobytes())
346
+ yield temp_name
347
+ else:
348
+ raise ValueError(
349
+ f"Unsupported return_type '{return_type}'. Choose 'waveform', 'bytes', or 'file'."
350
+ )
351
+ finally:
352
+ if player is not None:
353
+ player.close()
354
+ self.speed = orig_speed
355
+
356
+ tts_stream = stream
357
+
280
358
 
281
359
  FastThaiG2P = TTS
282
360