Spaces:
Runtime error
Runtime error
Upload 3 files
Browse files- app.py +28 -36
- index.html +488 -563
- voices_data.py +330 -0
app.py
CHANGED
|
@@ -2,24 +2,26 @@ import os
|
|
| 2 |
import uuid
|
| 3 |
import asyncio
|
| 4 |
import tempfile
|
|
|
|
| 5 |
|
| 6 |
import edge_tts
|
| 7 |
from flask import Flask, request, jsonify, send_file, after_this_request
|
| 8 |
|
|
|
|
|
|
|
| 9 |
BASE_DIR = os.path.dirname(os.path.abspath(__file__))
|
| 10 |
app = Flask(__name__)
|
| 11 |
|
| 12 |
-
# ---
|
| 13 |
-
VOICES =
|
| 14 |
-
|
| 15 |
-
|
| 16 |
-
}
|
| 17 |
|
| 18 |
DEFAULT_VOICE = "my-MM-NilarNeural"
|
| 19 |
TMP_DIR = os.path.join(tempfile.gettempdir(), "mm_tts_outputs")
|
| 20 |
os.makedirs(TMP_DIR, exist_ok=True)
|
| 21 |
|
| 22 |
-
MAX_CHARS =
|
| 23 |
|
| 24 |
|
| 25 |
def clamp_pct(value, lo=-50, hi=50):
|
|
@@ -30,39 +32,29 @@ def clamp_pct(value, lo=-50, hi=50):
|
|
| 30 |
return max(lo, min(hi, value))
|
| 31 |
|
| 32 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 33 |
@app.route("/")
|
| 34 |
def index():
|
| 35 |
return send_file(os.path.join(BASE_DIR, "index.html"))
|
| 36 |
|
| 37 |
|
| 38 |
-
@app.route("/about")
|
| 39 |
-
def about():
|
| 40 |
-
return send_file(os.path.join(BASE_DIR, "about.html"))
|
| 41 |
-
|
| 42 |
-
|
| 43 |
-
@app.route("/privacy")
|
| 44 |
-
def privacy():
|
| 45 |
-
return send_file(os.path.join(BASE_DIR, "privacy.html"))
|
| 46 |
-
|
| 47 |
-
|
| 48 |
-
@app.route("/terms")
|
| 49 |
-
def terms():
|
| 50 |
-
return send_file(os.path.join(BASE_DIR, "terms.html"))
|
| 51 |
-
|
| 52 |
-
|
| 53 |
-
@app.route("/style.css")
|
| 54 |
-
def style_css():
|
| 55 |
-
return send_file(os.path.join(BASE_DIR, "style.css"), mimetype="text/css")
|
| 56 |
-
|
| 57 |
-
|
| 58 |
-
@app.route("/app.js")
|
| 59 |
-
def app_js():
|
| 60 |
-
return send_file(os.path.join(BASE_DIR, "app.js"), mimetype="application/javascript")
|
| 61 |
-
|
| 62 |
-
|
| 63 |
@app.route("/api/voices")
|
| 64 |
def get_voices():
|
| 65 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 66 |
|
| 67 |
|
| 68 |
@app.route("/api/tts", methods=["POST"])
|
|
@@ -75,10 +67,10 @@ def tts():
|
|
| 75 |
pitch = clamp_pct(data.get("pitch", 0))
|
| 76 |
|
| 77 |
if not text:
|
| 78 |
-
return jsonify({"error": "
|
| 79 |
|
| 80 |
if len(text) > MAX_CHARS:
|
| 81 |
-
return jsonify({"error": f"
|
| 82 |
|
| 83 |
if voice not in VOICES:
|
| 84 |
voice = DEFAULT_VOICE
|
|
@@ -99,7 +91,7 @@ def tts():
|
|
| 99 |
return jsonify({"error": str(e)}), 500
|
| 100 |
|
| 101 |
if not os.path.exists(filepath) or os.path.getsize(filepath) == 0:
|
| 102 |
-
return jsonify({"error": "
|
| 103 |
|
| 104 |
@after_this_request
|
| 105 |
def cleanup(response):
|
|
@@ -113,7 +105,7 @@ def tts():
|
|
| 113 |
filepath,
|
| 114 |
mimetype="audio/mpeg",
|
| 115 |
as_attachment=False,
|
| 116 |
-
download_name="
|
| 117 |
conditional=False,
|
| 118 |
)
|
| 119 |
|
|
|
|
| 2 |
import uuid
|
| 3 |
import asyncio
|
| 4 |
import tempfile
|
| 5 |
+
from collections import OrderedDict
|
| 6 |
|
| 7 |
import edge_tts
|
| 8 |
from flask import Flask, request, jsonify, send_file, after_this_request
|
| 9 |
|
| 10 |
+
from voices_data import VOICE_LIST
|
| 11 |
+
|
| 12 |
BASE_DIR = os.path.dirname(os.path.abspath(__file__))
|
| 13 |
app = Flask(__name__)
|
| 14 |
|
| 15 |
+
# --- Build voice catalogue: short_name -> {lang, gender} ---
|
| 16 |
+
VOICES = OrderedDict()
|
| 17 |
+
for short_name, lang, gender in VOICE_LIST:
|
| 18 |
+
VOICES[short_name] = {"lang": lang, "gender": gender}
|
|
|
|
| 19 |
|
| 20 |
DEFAULT_VOICE = "my-MM-NilarNeural"
|
| 21 |
TMP_DIR = os.path.join(tempfile.gettempdir(), "mm_tts_outputs")
|
| 22 |
os.makedirs(TMP_DIR, exist_ok=True)
|
| 23 |
|
| 24 |
+
MAX_CHARS = 3000
|
| 25 |
|
| 26 |
|
| 27 |
def clamp_pct(value, lo=-50, hi=50):
|
|
|
|
| 32 |
return max(lo, min(hi, value))
|
| 33 |
|
| 34 |
|
| 35 |
+
def display_name(short_name):
|
| 36 |
+
# e.g. "en-US-AvaMultilingualNeural" -> "Ava (Multilingual)"
|
| 37 |
+
part = short_name.split("-")[-1]
|
| 38 |
+
part = part.replace("Neural", "")
|
| 39 |
+
if part.endswith("Multilingual"):
|
| 40 |
+
part = part.replace("Multilingual", "") + " (Multilingual)"
|
| 41 |
+
return part
|
| 42 |
+
|
| 43 |
+
|
| 44 |
@app.route("/")
|
| 45 |
def index():
|
| 46 |
return send_file(os.path.join(BASE_DIR, "index.html"))
|
| 47 |
|
| 48 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 49 |
@app.route("/api/voices")
|
| 50 |
def get_voices():
|
| 51 |
+
"""Return voices grouped by language for the UI dropdowns."""
|
| 52 |
+
grouped = OrderedDict()
|
| 53 |
+
for short_name, lang, gender in VOICE_LIST:
|
| 54 |
+
grouped.setdefault(lang, []).append(
|
| 55 |
+
{"id": short_name, "name": display_name(short_name), "gender": gender}
|
| 56 |
+
)
|
| 57 |
+
return jsonify(grouped)
|
| 58 |
|
| 59 |
|
| 60 |
@app.route("/api/tts", methods=["POST"])
|
|
|
|
| 67 |
pitch = clamp_pct(data.get("pitch", 0))
|
| 68 |
|
| 69 |
if not text:
|
| 70 |
+
return jsonify({"error": "စာသား ထည့်ပေးပါ (text is required)"}), 400
|
| 71 |
|
| 72 |
if len(text) > MAX_CHARS:
|
| 73 |
+
return jsonify({"error": f"စာသား {MAX_CHARS} လုံးအထိသာ ထည့်နိုင်ပါသည်"}), 400
|
| 74 |
|
| 75 |
if voice not in VOICES:
|
| 76 |
voice = DEFAULT_VOICE
|
|
|
|
| 91 |
return jsonify({"error": str(e)}), 500
|
| 92 |
|
| 93 |
if not os.path.exists(filepath) or os.path.getsize(filepath) == 0:
|
| 94 |
+
return jsonify({"error": "အသံဖိုင် ထုတ်ယူခြင်း မအောင်မြင်ပါ"}), 500
|
| 95 |
|
| 96 |
@after_this_request
|
| 97 |
def cleanup(response):
|
|
|
|
| 105 |
filepath,
|
| 106 |
mimetype="audio/mpeg",
|
| 107 |
as_attachment=False,
|
| 108 |
+
download_name="voice.mp3",
|
| 109 |
conditional=False,
|
| 110 |
)
|
| 111 |
|
index.html
CHANGED
|
@@ -3,399 +3,334 @@
|
|
| 3 |
<head>
|
| 4 |
<meta charset="UTF-8">
|
| 5 |
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
| 6 |
-
<title>
|
| 7 |
-
<meta name="description" content="Convert Myanmar (Burmese) text into natural-sounding speech for free. Choose from neural voices, adjust speed and pitch, and download MP3 audio instantly — no sign-up required.">
|
| 8 |
-
|
| 9 |
-
<!-- Google AdSense Verification -->
|
| 10 |
-
<meta name="google-adsense-account" content="ca-pub-1188893611988786">
|
| 11 |
|
| 12 |
<link rel="preconnect" href="https://fonts.googleapis.com">
|
| 13 |
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
| 14 |
-
<link href="https://fonts.googleapis.com/css2?family=
|
| 15 |
-
<link rel="stylesheet" href="/style.css">
|
| 16 |
-
|
| 17 |
-
<!-- Google AdSense -->
|
| 18 |
-
<script async src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-1188893611988786" crossorigin="anonymous"></script>
|
| 19 |
|
| 20 |
<style>
|
| 21 |
-
|
| 22 |
-
:
|
| 23 |
-
|
| 24 |
-
|
| 25 |
-
|
| 26 |
-
|
| 27 |
-
|
| 28 |
-
|
| 29 |
-
|
| 30 |
-
|
| 31 |
-
|
| 32 |
-
|
| 33 |
-
}
|
| 34 |
-
|
| 35 |
-
*
|
| 36 |
-
|
| 37 |
-
|
| 38 |
-
|
| 39 |
-
|
| 40 |
-
|
| 41 |
-
|
| 42 |
-
|
| 43 |
-
|
| 44 |
-
|
| 45 |
-
|
| 46 |
-
|
| 47 |
-
|
| 48 |
-
|
| 49 |
-
|
| 50 |
-
|
| 51 |
-
|
| 52 |
-
|
| 53 |
-
|
| 54 |
-
|
| 55 |
-
|
| 56 |
-
|
| 57 |
-
|
| 58 |
-
|
| 59 |
-
|
| 60 |
-
|
| 61 |
-
|
| 62 |
-
|
| 63 |
-
|
| 64 |
-
|
| 65 |
-
|
| 66 |
-
|
| 67 |
-
|
| 68 |
-
|
| 69 |
-
|
| 70 |
-
|
| 71 |
-
|
| 72 |
-
|
| 73 |
-
|
| 74 |
-
|
| 75 |
-
|
| 76 |
-
|
| 77 |
-
|
| 78 |
-
|
| 79 |
-
|
| 80 |
-
|
| 81 |
-
|
| 82 |
-
|
| 83 |
-
|
| 84 |
-
|
| 85 |
-
|
| 86 |
-
|
| 87 |
-
|
| 88 |
-
|
| 89 |
-
|
| 90 |
-
|
| 91 |
-
|
| 92 |
-
|
| 93 |
-
|
| 94 |
-
|
| 95 |
-
|
| 96 |
-
|
| 97 |
-
|
| 98 |
-
|
| 99 |
-
|
| 100 |
-
|
| 101 |
-
|
| 102 |
-
.
|
| 103 |
-
|
| 104 |
-
|
| 105 |
-
|
| 106 |
-
|
| 107 |
-
|
| 108 |
-
|
| 109 |
-
|
| 110 |
-
|
| 111 |
-
|
| 112 |
-
|
| 113 |
-
|
| 114 |
-
|
| 115 |
-
|
| 116 |
-
|
| 117 |
-
|
| 118 |
-
|
| 119 |
-
|
| 120 |
-
|
| 121 |
-
|
| 122 |
-
|
| 123 |
-
|
| 124 |
-
|
| 125 |
-
|
| 126 |
-
|
| 127 |
-
|
| 128 |
-
|
| 129 |
-
|
| 130 |
-
|
| 131 |
-
|
| 132 |
-
|
| 133 |
-
}
|
| 134 |
-
|
| 135 |
-
|
| 136 |
-
|
| 137 |
-
|
| 138 |
-
|
| 139 |
-
|
| 140 |
-
|
| 141 |
-
|
| 142 |
-
|
| 143 |
-
|
| 144 |
-
|
| 145 |
-
|
| 146 |
-
|
| 147 |
-
|
| 148 |
-
|
| 149 |
-
|
| 150 |
-
|
| 151 |
-
|
| 152 |
-
|
| 153 |
-
|
| 154 |
-
|
| 155 |
-
|
| 156 |
-
|
| 157 |
-
|
| 158 |
-
|
| 159 |
-
|
| 160 |
-
|
| 161 |
-
|
| 162 |
-
|
| 163 |
-
|
| 164 |
-
|
| 165 |
-
|
| 166 |
-
|
| 167 |
-
|
| 168 |
-
|
| 169 |
-
|
| 170 |
-
|
| 171 |
-
|
| 172 |
-
|
| 173 |
-
|
| 174 |
-
|
| 175 |
-
|
| 176 |
-
|
| 177 |
-
|
| 178 |
-
|
| 179 |
-
|
| 180 |
-
|
| 181 |
-
|
| 182 |
-
|
| 183 |
-
|
| 184 |
-
|
| 185 |
-
|
| 186 |
-
|
| 187 |
-
|
| 188 |
-
|
| 189 |
-
|
| 190 |
-
|
| 191 |
-
|
| 192 |
-
|
| 193 |
-
|
| 194 |
-
|
| 195 |
-
|
| 196 |
-
|
| 197 |
-
|
| 198 |
-
|
| 199 |
-
|
| 200 |
-
|
| 201 |
-
|
| 202 |
-
|
| 203 |
-
|
| 204 |
-
|
| 205 |
-
|
| 206 |
-
.
|
| 207 |
-
|
| 208 |
-
|
| 209 |
-
|
| 210 |
-
|
| 211 |
-
|
| 212 |
-
|
| 213 |
-
|
| 214 |
-
|
| 215 |
-
|
| 216 |
-
|
| 217 |
-
|
| 218 |
-
|
| 219 |
-
|
| 220 |
-
|
| 221 |
-
|
| 222 |
-
|
| 223 |
-
|
| 224 |
-
|
| 225 |
-
|
| 226 |
-
|
| 227 |
-
|
| 228 |
-
|
| 229 |
-
|
| 230 |
-
|
| 231 |
-
|
| 232 |
-
|
| 233 |
-
|
| 234 |
-
|
| 235 |
-
|
| 236 |
-
|
| 237 |
-
|
| 238 |
-
|
| 239 |
-
|
| 240 |
-
|
| 241 |
-
|
| 242 |
-
|
| 243 |
-
|
| 244 |
-
|
| 245 |
-
|
| 246 |
-
|
| 247 |
-
|
| 248 |
-
|
| 249 |
-
|
| 250 |
-
|
| 251 |
-
|
| 252 |
-
|
| 253 |
-
|
| 254 |
-
|
| 255 |
-
|
| 256 |
-
|
| 257 |
-
|
| 258 |
-
|
| 259 |
-
|
| 260 |
-
|
| 261 |
-
|
| 262 |
-
|
| 263 |
-
|
| 264 |
-
|
| 265 |
-
|
| 266 |
-
|
| 267 |
-
.
|
| 268 |
-
|
| 269 |
-
|
| 270 |
-
|
| 271 |
-
|
| 272 |
-
|
| 273 |
-
|
| 274 |
-
|
| 275 |
-
|
| 276 |
-
|
| 277 |
-
|
| 278 |
-
|
| 279 |
-
|
| 280 |
-
|
| 281 |
-
|
| 282 |
-
|
| 283 |
-
|
| 284 |
-
|
| 285 |
-
|
| 286 |
-
|
| 287 |
-
|
|
|
|
|
|
|
| 288 |
</style>
|
| 289 |
</head>
|
| 290 |
<body>
|
| 291 |
|
| 292 |
-
<!-- ===================== NAVBAR ===================== -->
|
| 293 |
-
<nav class="nav">
|
| 294 |
<div class="wrap">
|
| 295 |
-
|
| 296 |
-
|
| 297 |
-
|
| 298 |
-
<
|
| 299 |
-
|
| 300 |
-
|
| 301 |
-
|
| 302 |
-
|
| 303 |
-
|
| 304 |
-
<
|
| 305 |
-
|
| 306 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 307 |
</div>
|
| 308 |
-
</a>
|
| 309 |
-
|
| 310 |
-
<!-- Desktop nav links -->
|
| 311 |
-
<div class="nav-links" id="navLinks">
|
| 312 |
-
<a href="/" class="active">Home</a>
|
| 313 |
-
<a href="#tool">Try It</a>
|
| 314 |
-
<a href="#how-it-works">How It Works</a>
|
| 315 |
-
<a href="#faq">FAQ</a>
|
| 316 |
-
<a href="/about">About</a>
|
| 317 |
-
<span class="nav-badge">Free</span>
|
| 318 |
-
<a href="#tool" class="nav-cta">Generate Voice →</a>
|
| 319 |
-
</div>
|
| 320 |
-
|
| 321 |
-
<!-- Hamburger toggle -->
|
| 322 |
-
<button class="nav-toggle" id="navToggle" aria-label="Toggle menu">
|
| 323 |
-
<span></span>
|
| 324 |
-
<span></span>
|
| 325 |
-
<span></span>
|
| 326 |
-
</button>
|
| 327 |
|
| 328 |
-
|
| 329 |
-
<
|
| 330 |
-
|
| 331 |
-
<
|
| 332 |
-
|
| 333 |
-
|
| 334 |
-
|
| 335 |
-
|
| 336 |
-
|
| 337 |
-
Burmese text aloud. Paste up to 10,000 characters, fine-tune the speed and
|
| 338 |
-
pitch, and download a ready-to-use MP3 — completely free, no account needed.</p>
|
| 339 |
-
<div class="wave" id="wave"></div>
|
| 340 |
-
</header>
|
| 341 |
-
|
| 342 |
-
</div>
|
| 343 |
-
|
| 344 |
-
<!-- Top ad slot -->
|
| 345 |
-
<div class="ad-slot">
|
| 346 |
-
<div class="ad-label">Advertisement</div>
|
| 347 |
-
<div class="ad-inner">
|
| 348 |
-
<ins class="adsbygoogle"
|
| 349 |
-
style="display:block;width:100%"
|
| 350 |
-
data-ad-client="ca-pub-1188893611988786"
|
| 351 |
-
data-ad-slot="1111111111"
|
| 352 |
-
data-ad-format="auto"
|
| 353 |
-
data-full-width-responsive="true"></ins>
|
| 354 |
-
<script>(adsbygoogle = window.adsbygoogle || []).push({});</script>
|
| 355 |
-
</div>
|
| 356 |
-
</div>
|
| 357 |
-
|
| 358 |
-
<div class="wrap" id="tool">
|
| 359 |
-
|
| 360 |
-
<!-- Text input -->
|
| 361 |
-
<section class="tight">
|
| 362 |
-
<div class="panel">
|
| 363 |
-
<h3>Your Script</h3>
|
| 364 |
-
<textarea id="text" placeholder="Type or paste Myanmar text here..." maxlength="10000"></textarea>
|
| 365 |
-
<div class="char-count" id="charCount">0 / 10000</div>
|
| 366 |
-
</div>
|
| 367 |
-
</section>
|
| 368 |
-
|
| 369 |
-
<!-- Voice + settings -->
|
| 370 |
-
<section class="tight">
|
| 371 |
-
<div class="panel">
|
| 372 |
-
<h3>Voice</h3>
|
| 373 |
-
<div class="voices" id="voices">
|
| 374 |
-
<label class="voice-card selected" data-voice="my-MM-NilarNeural">
|
| 375 |
-
<input type="radio" name="voice" value="my-MM-NilarNeural" checked>
|
| 376 |
-
<div class="name">နီလာ — Nilar</div>
|
| 377 |
-
<div class="role">Female</div>
|
| 378 |
-
</label>
|
| 379 |
-
<label class="voice-card" data-voice="my-MM-ThihaNeural">
|
| 380 |
-
<input type="radio" name="voice" value="my-MM-ThihaNeural">
|
| 381 |
-
<div class="name">သီဟ — Thiha</div>
|
| 382 |
-
<div class="role">Male</div>
|
| 383 |
-
</label>
|
| 384 |
</div>
|
| 385 |
|
| 386 |
<div class="controls">
|
| 387 |
<div class="control">
|
| 388 |
-
<label>Speed <span class="val" id="rateVal">+0%</span></label>
|
| 389 |
<input type="range" id="rate" min="-50" max="50" value="0" step="5">
|
| 390 |
</div>
|
| 391 |
<div class="control">
|
| 392 |
-
<label>Pitch <span class="val" id="pitchVal">+0Hz</span></label>
|
| 393 |
<input type="range" id="pitch" min="-50" max="50" value="0" step="5">
|
| 394 |
</div>
|
| 395 |
</div>
|
| 396 |
|
| 397 |
<div class="actions">
|
| 398 |
-
<button class="btn-primary" id="generateBtn">
|
| 399 |
</div>
|
| 400 |
|
| 401 |
<div class="status" id="status"></div>
|
|
@@ -403,209 +338,199 @@
|
|
| 403 |
<div class="output" id="output">
|
| 404 |
<audio id="player" controls></audio>
|
| 405 |
<div class="actions">
|
| 406 |
-
<a class="btn-secondary" id="downloadLink" download="
|
| 407 |
</div>
|
| 408 |
</div>
|
| 409 |
-
</
|
| 410 |
-
</section>
|
| 411 |
-
|
| 412 |
-
<!-- How it works -->
|
| 413 |
-
<section id="how-it-works">
|
| 414 |
-
<div class="section-head">
|
| 415 |
-
<p class="eyebrow">How It Works</p>
|
| 416 |
-
<h2>From text to voice in three steps</h2>
|
| 417 |
-
<p>No installation, no registration. Everything runs directly in your browser.</p>
|
| 418 |
-
</div>
|
| 419 |
-
<div class="grid">
|
| 420 |
-
<div class="card">
|
| 421 |
-
<div class="index">01</div>
|
| 422 |
-
<h3>Write or paste your text</h3>
|
| 423 |
-
<p>Add up to 10,000 characters of Myanmar text — scripts, articles, captions, or study notes.</p>
|
| 424 |
-
</div>
|
| 425 |
-
<div class="card">
|
| 426 |
-
<div class="index">02</div>
|
| 427 |
-
<h3>Pick a voice & tune it</h3>
|
| 428 |
-
<p>Choose between Nilar (female) and Thiha (male), then adjust the speaking speed and pitch.</p>
|
| 429 |
-
</div>
|
| 430 |
-
<div class="card">
|
| 431 |
-
<div class="index">03</div>
|
| 432 |
-
<h3>Generate & download</h3>
|
| 433 |
-
<p>Click Generate, preview the audio instantly, and download it as an MP3 file.</p>
|
| 434 |
-
</div>
|
| 435 |
-
</div>
|
| 436 |
-
</section>
|
| 437 |
-
|
| 438 |
-
<!-- Features -->
|
| 439 |
-
<section>
|
| 440 |
-
<div class="section-head">
|
| 441 |
-
<p class="eyebrow">Features</p>
|
| 442 |
-
<h2>Built for creators & learners</h2>
|
| 443 |
-
<p>Everything you need for quick, natural Myanmar voiceovers.</p>
|
| 444 |
-
</div>
|
| 445 |
-
<div class="grid">
|
| 446 |
-
<div class="card">
|
| 447 |
-
<h3>Natural Neural Voices</h3>
|
| 448 |
-
<p>Powered by Microsoft's neural text-to-speech engine for clear, lifelike Myanmar pronunciation.</p>
|
| 449 |
-
</div>
|
| 450 |
-
<div class="card">
|
| 451 |
-
<h3>Adjustable Speed & Pitch</h3>
|
| 452 |
-
<p>Slow it down for learning material, or speed it up for short-form video narration.</p>
|
| 453 |
-
</div>
|
| 454 |
-
<div class="card">
|
| 455 |
-
<h3>Up to 10,000 Characters</h3>
|
| 456 |
-
<p>Convert long articles, scripts, or chapters in a single request.</p>
|
| 457 |
-
</div>
|
| 458 |
-
<div class="card">
|
| 459 |
-
<h3>Instant MP3 Download</h3>
|
| 460 |
-
<p>Your audio file is ready to download and use the moment it's generated.</p>
|
| 461 |
-
</div>
|
| 462 |
-
<div class="card">
|
| 463 |
-
<h3>No Sign-up Required</h3>
|
| 464 |
-
<p>Start using the tool immediately — there are no accounts, passwords, or limits to unlock.</p>
|
| 465 |
-
</div>
|
| 466 |
-
<div class="card">
|
| 467 |
-
<h3>Free to Use</h3>
|
| 468 |
-
<p>Myanmar Voice Studio is free for personal, educational, and commercial projects.</p>
|
| 469 |
-
</div>
|
| 470 |
-
</div>
|
| 471 |
-
</section>
|
| 472 |
-
|
| 473 |
-
<!-- Use cases -->
|
| 474 |
-
<section>
|
| 475 |
-
<div class="section-head">
|
| 476 |
-
<p class="eyebrow">Use Cases</p>
|
| 477 |
-
<h2>Who is this for?</h2>
|
| 478 |
-
</div>
|
| 479 |
-
<div class="grid">
|
| 480 |
-
<div class="card">
|
| 481 |
-
<h3>Content Creators</h3>
|
| 482 |
-
<p>Generate voiceovers for YouTube videos, TikToks, and Reels in Myanmar language.</p>
|
| 483 |
-
</div>
|
| 484 |
-
<div class="card">
|
| 485 |
-
<h3>Educators & Students</h3>
|
| 486 |
-
<p>Turn lesson notes and reading material into audio for revision and accessibility.</p>
|
| 487 |
-
</div>
|
| 488 |
-
<div class="card">
|
| 489 |
-
<h3>Developers</h3>
|
| 490 |
-
<p>Prototype Myanmar-language apps, games, and IVR systems with quick sample audio.</p>
|
| 491 |
-
</div>
|
| 492 |
-
<div class="card">
|
| 493 |
-
<h3>Podcasters & Writers</h3>
|
| 494 |
-
<p>Preview how your written Myanmar content sounds when read aloud.</p>
|
| 495 |
-
</div>
|
| 496 |
-
<div class="card">
|
| 497 |
-
<h3>Accessibility</h3>
|
| 498 |
-
<p>Help readers who are visually impaired or prefer listening over reading.</p>
|
| 499 |
-
</div>
|
| 500 |
-
<div class="card">
|
| 501 |
-
<h3>Translators</h3>
|
| 502 |
-
<p>Check pronunciation and pacing of translated Myanmar scripts before recording.</p>
|
| 503 |
-
</div>
|
| 504 |
-
</div>
|
| 505 |
-
</section>
|
| 506 |
-
|
| 507 |
-
<!-- In-content ad slot -->
|
| 508 |
-
<div class="ad-slot" style="padding:0">
|
| 509 |
-
<div class="ad-label">Advertisement</div>
|
| 510 |
-
<div class="ad-inner">
|
| 511 |
-
<ins class="adsbygoogle"
|
| 512 |
-
style="display:block;width:100%"
|
| 513 |
-
data-ad-client="ca-pub-1188893611988786"
|
| 514 |
-
data-ad-slot="2222222222"
|
| 515 |
-
data-ad-format="auto"
|
| 516 |
-
data-full-width-responsive="true"></ins>
|
| 517 |
-
<script>(adsbygoogle = window.adsbygoogle || []).push({});</script>
|
| 518 |
-
</div>
|
| 519 |
-
</div>
|
| 520 |
-
|
| 521 |
-
<!-- FAQ -->
|
| 522 |
-
<section id="faq">
|
| 523 |
-
<div class="section-head">
|
| 524 |
-
<p class="eyebrow">FAQ</p>
|
| 525 |
-
<h2>Frequently asked questions</h2>
|
| 526 |
-
</div>
|
| 527 |
-
|
| 528 |
-
<details class="faq-item" open>
|
| 529 |
-
<summary>Is Myanmar Voice Studio free to use?</summary>
|
| 530 |
-
<p>Yes. The tool is completely free for personal, educational, and commercial use. There are no hidden fees or subscriptions.</p>
|
| 531 |
-
</details>
|
| 532 |
-
|
| 533 |
-
<details class="faq-item">
|
| 534 |
-
<summary>Which Myanmar voices are available?</summary>
|
| 535 |
-
<p>You can choose between two neural voices: Nilar, a female voice, and Thiha, a male voice. Both are tuned for natural Burmese pronunciation.</p>
|
| 536 |
-
</details>
|
| 537 |
-
|
| 538 |
-
<details class="faq-item">
|
| 539 |
-
<summary>Can I change the speaking speed and pitch?</summary>
|
| 540 |
-
<p>Yes. Use the Speed and Pitch sliders before generating audio to make the voice sound slower, faster, deeper, or lighter.</p>
|
| 541 |
-
</details>
|
| 542 |
-
|
| 543 |
-
<details class="faq-item">
|
| 544 |
-
<summary>What is the maximum text length?</summary>
|
| 545 |
-
<p>You can convert up to 10,000 characters of Myanmar text in a single request.</p>
|
| 546 |
-
</details>
|
| 547 |
-
|
| 548 |
-
<details class="faq-item">
|
| 549 |
-
<summary>Can I use the audio in my videos or projects?</summary>
|
| 550 |
-
<p>Yes, generated audio files can be downloaded and used in your own videos, presentations, apps, and other projects.</p>
|
| 551 |
-
</details>
|
| 552 |
-
|
| 553 |
-
<details class="faq-item">
|
| 554 |
-
<summary>Is my text stored or shared with anyone?</summary>
|
| 555 |
-
<p>No. Text you submit is sent only to generate the audio file and is not stored on our servers afterwards. See our <a href="/privacy">Privacy Policy</a> for details.</p>
|
| 556 |
-
</details>
|
| 557 |
-
</section>
|
| 558 |
-
|
| 559 |
-
</div>
|
| 560 |
-
|
| 561 |
-
<footer>
|
| 562 |
-
<div class="wrap">
|
| 563 |
-
<div class="footer-grid">
|
| 564 |
-
<div class="footer-col">
|
| 565 |
-
<h4>Myanmar Voice Studio</h4>
|
| 566 |
-
<a href="/">Home</a>
|
| 567 |
-
<a href="#tool">Text to Speech Tool</a>
|
| 568 |
-
<a href="#how-it-works">How It Works</a>
|
| 569 |
-
</div>
|
| 570 |
-
<div class="footer-col">
|
| 571 |
-
<h4>Resources</h4>
|
| 572 |
-
<a href="#faq">FAQ</a>
|
| 573 |
-
<a href="/about">About</a>
|
| 574 |
-
</div>
|
| 575 |
-
<div class="footer-col">
|
| 576 |
-
<h4>Legal</h4>
|
| 577 |
-
<a href="/privacy">Privacy Policy</a>
|
| 578 |
-
<a href="/terms">Terms of Use</a>
|
| 579 |
-
</div>
|
| 580 |
-
</div>
|
| 581 |
-
<div class="footer-bottom">
|
| 582 |
-
© 2026 Myanmar Voice Studio. Voices powered by neural text-to-speech technology.
|
| 583 |
-
</div>
|
| 584 |
</div>
|
| 585 |
-
</footer>
|
| 586 |
|
| 587 |
-
<
|
|
|
|
|
|
|
| 588 |
|
| 589 |
-
<!-- Hamburger toggle script -->
|
| 590 |
<script>
|
| 591 |
-
|
| 592 |
-
|
| 593 |
-
|
| 594 |
-
|
| 595 |
-
|
| 596 |
-
|
| 597 |
-
|
| 598 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 599 |
});
|
| 600 |
-
|
| 601 |
-
|
| 602 |
-
|
| 603 |
-
|
| 604 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 605 |
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 606 |
});
|
| 607 |
-
})();
|
| 608 |
</script>
|
| 609 |
-
|
| 610 |
</body>
|
| 611 |
</html>
|
|
|
|
| 3 |
<head>
|
| 4 |
<meta charset="UTF-8">
|
| 5 |
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
| 6 |
+
<title>အသံစာပေ — Voice Studio</title>
|
|
|
|
|
|
|
|
|
|
|
|
|
| 7 |
|
| 8 |
<link rel="preconnect" href="https://fonts.googleapis.com">
|
| 9 |
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
| 10 |
+
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&family=Noto+Sans+Myanmar:wght@400;500;600;700&display=swap" rel="stylesheet">
|
|
|
|
|
|
|
|
|
|
|
|
|
| 11 |
|
| 12 |
<style>
|
| 13 |
+
:root{
|
| 14 |
+
--bg:#FFFFFF;
|
| 15 |
+
--surface:#FFFFFF;
|
| 16 |
+
--surface-2:#F5F6F8;
|
| 17 |
+
--ink:#16181D;
|
| 18 |
+
--ink-soft:#7B828F;
|
| 19 |
+
--accent:#2563EB;
|
| 20 |
+
--accent-soft:#EAF0FE;
|
| 21 |
+
--line:#E7E9EE;
|
| 22 |
+
--radius:14px;
|
| 23 |
+
--sans:'Inter', sans-serif;
|
| 24 |
+
--mm:'Noto Sans Myanmar', sans-serif;
|
| 25 |
+
}
|
| 26 |
+
|
| 27 |
+
*{ box-sizing:border-box; }
|
| 28 |
+
|
| 29 |
+
body{
|
| 30 |
+
margin:0;
|
| 31 |
+
background:var(--bg);
|
| 32 |
+
color:var(--ink);
|
| 33 |
+
font-family:var(--mm);
|
| 34 |
+
line-height:1.6;
|
| 35 |
+
-webkit-font-smoothing:antialiased;
|
| 36 |
+
}
|
| 37 |
+
|
| 38 |
+
.wrap{
|
| 39 |
+
max-width:640px;
|
| 40 |
+
margin:0 auto;
|
| 41 |
+
padding:0 18px 48px;
|
| 42 |
+
}
|
| 43 |
+
|
| 44 |
+
/* ---------- Header ---------- */
|
| 45 |
+
header{
|
| 46 |
+
padding:32px 0 20px;
|
| 47 |
+
text-align:center;
|
| 48 |
+
}
|
| 49 |
+
.eyebrow{
|
| 50 |
+
font-family:var(--sans);
|
| 51 |
+
font-weight:600;
|
| 52 |
+
font-size:12px;
|
| 53 |
+
letter-spacing:.14em;
|
| 54 |
+
text-transform:uppercase;
|
| 55 |
+
color:var(--accent);
|
| 56 |
+
margin:0 0 8px;
|
| 57 |
+
}
|
| 58 |
+
h1{
|
| 59 |
+
font-family:var(--mm);
|
| 60 |
+
font-weight:700;
|
| 61 |
+
font-size:clamp(24px,6vw,32px);
|
| 62 |
+
margin:0 0 8px;
|
| 63 |
+
}
|
| 64 |
+
.tagline{
|
| 65 |
+
color:var(--ink-soft);
|
| 66 |
+
font-size:14px;
|
| 67 |
+
margin:0;
|
| 68 |
+
}
|
| 69 |
+
|
| 70 |
+
.wave{
|
| 71 |
+
display:flex;
|
| 72 |
+
align-items:center;
|
| 73 |
+
justify-content:center;
|
| 74 |
+
gap:4px;
|
| 75 |
+
height:28px;
|
| 76 |
+
margin:18px auto 0;
|
| 77 |
+
}
|
| 78 |
+
.wave .bar{
|
| 79 |
+
width:4px;
|
| 80 |
+
border-radius:3px;
|
| 81 |
+
background:var(--accent);
|
| 82 |
+
height:8px;
|
| 83 |
+
opacity:.35;
|
| 84 |
+
animation:breathe 2.6s ease-in-out infinite;
|
| 85 |
+
transition:height .12s ease;
|
| 86 |
+
}
|
| 87 |
+
@keyframes breathe{
|
| 88 |
+
0%, 100% { height:6px; opacity:.3; }
|
| 89 |
+
50% { height:22px; opacity:.7; }
|
| 90 |
+
}
|
| 91 |
+
.wave.is-active .bar{ animation:none; opacity:1; }
|
| 92 |
+
|
| 93 |
+
/* ---------- Card ---------- */
|
| 94 |
+
.panel{
|
| 95 |
+
background:var(--surface);
|
| 96 |
+
border:1px solid var(--line);
|
| 97 |
+
border-radius:var(--radius);
|
| 98 |
+
padding:18px;
|
| 99 |
+
margin-top:16px;
|
| 100 |
+
}
|
| 101 |
+
|
| 102 |
+
.panel h2{
|
| 103 |
+
font-family:var(--sans);
|
| 104 |
+
font-weight:600;
|
| 105 |
+
font-size:12px;
|
| 106 |
+
letter-spacing:.1em;
|
| 107 |
+
text-transform:uppercase;
|
| 108 |
+
color:var(--ink-soft);
|
| 109 |
+
margin:0 0 12px;
|
| 110 |
+
}
|
| 111 |
+
|
| 112 |
+
textarea{
|
| 113 |
+
width:100%;
|
| 114 |
+
min-height:140px;
|
| 115 |
+
resize:vertical;
|
| 116 |
+
border:1px solid var(--line);
|
| 117 |
+
border-radius:10px;
|
| 118 |
+
background:var(--surface-2);
|
| 119 |
+
padding:14px 16px;
|
| 120 |
+
font-family:var(--mm);
|
| 121 |
+
font-size:16px;
|
| 122 |
+
line-height:1.7;
|
| 123 |
+
color:var(--ink);
|
| 124 |
+
outline:none;
|
| 125 |
+
}
|
| 126 |
+
textarea:focus{ border-color:var(--accent); background:var(--surface); }
|
| 127 |
+
textarea::placeholder{ color:var(--ink-soft); }
|
| 128 |
+
|
| 129 |
+
.char-count{
|
| 130 |
+
text-align:right;
|
| 131 |
+
font-size:12px;
|
| 132 |
+
color:var(--ink-soft);
|
| 133 |
+
margin-top:6px;
|
| 134 |
+
font-family:var(--sans);
|
| 135 |
+
}
|
| 136 |
+
.char-count.over{ color:#D14343; }
|
| 137 |
+
|
| 138 |
+
/* ---------- Selects ---------- */
|
| 139 |
+
.field{ margin-bottom:14px; }
|
| 140 |
+
.field:last-child{ margin-bottom:0; }
|
| 141 |
+
.field label{
|
| 142 |
+
display:block;
|
| 143 |
+
font-family:var(--sans);
|
| 144 |
+
font-size:12px;
|
| 145 |
+
font-weight:600;
|
| 146 |
+
letter-spacing:.04em;
|
| 147 |
+
color:var(--ink-soft);
|
| 148 |
+
margin-bottom:6px;
|
| 149 |
+
}
|
| 150 |
+
select{
|
| 151 |
+
width:100%;
|
| 152 |
+
border:1px solid var(--line);
|
| 153 |
+
border-radius:10px;
|
| 154 |
+
background:var(--surface-2);
|
| 155 |
+
padding:12px 14px;
|
| 156 |
+
font-family:var(--mm);
|
| 157 |
+
font-size:15px;
|
| 158 |
+
color:var(--ink);
|
| 159 |
+
outline:none;
|
| 160 |
+
appearance:none;
|
| 161 |
+
background-image:url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="14" height="9" viewBox="0 0 14 9"><path d="M1 1l6 6 6-6" stroke="%237B828F" stroke-width="1.6" fill="none" fill-rule="evenodd"/></svg>');
|
| 162 |
+
background-repeat:no-repeat;
|
| 163 |
+
background-position:right 14px center;
|
| 164 |
+
padding-right:34px;
|
| 165 |
+
}
|
| 166 |
+
select:focus{ border-color:var(--accent); background-color:var(--surface); }
|
| 167 |
+
|
| 168 |
+
.lang-search{
|
| 169 |
+
width:100%;
|
| 170 |
+
border:1px solid var(--line);
|
| 171 |
+
border-radius:10px;
|
| 172 |
+
background:var(--surface-2);
|
| 173 |
+
padding:10px 14px;
|
| 174 |
+
font-family:var(--sans);
|
| 175 |
+
font-size:14px;
|
| 176 |
+
color:var(--ink);
|
| 177 |
+
outline:none;
|
| 178 |
+
margin-bottom:8px;
|
| 179 |
+
}
|
| 180 |
+
.lang-search:focus{ border-color:var(--accent); background:var(--surface); }
|
| 181 |
+
|
| 182 |
+
.row2{
|
| 183 |
+
display:grid;
|
| 184 |
+
grid-template-columns:1fr 1fr;
|
| 185 |
+
gap:12px;
|
| 186 |
+
}
|
| 187 |
+
@media (max-width:420px){
|
| 188 |
+
.row2{ grid-template-columns:1fr; }
|
| 189 |
+
}
|
| 190 |
+
|
| 191 |
+
/* ---------- Sliders ---------- */
|
| 192 |
+
.controls{
|
| 193 |
+
display:grid;
|
| 194 |
+
grid-template-columns:1fr 1fr;
|
| 195 |
+
gap:16px;
|
| 196 |
+
margin-top:16px;
|
| 197 |
+
}
|
| 198 |
+
.control label{
|
| 199 |
+
display:flex;
|
| 200 |
+
justify-content:space-between;
|
| 201 |
+
font-size:12px;
|
| 202 |
+
color:var(--ink-soft);
|
| 203 |
+
margin-bottom:6px;
|
| 204 |
+
font-family:var(--sans);
|
| 205 |
+
font-weight:600;
|
| 206 |
+
}
|
| 207 |
+
.control label span.val{
|
| 208 |
+
font-family:var(--mm);
|
| 209 |
+
color:var(--ink);
|
| 210 |
+
font-weight:600;
|
| 211 |
+
}
|
| 212 |
+
input[type="range"]{
|
| 213 |
+
width:100%;
|
| 214 |
+
accent-color:var(--accent);
|
| 215 |
+
}
|
| 216 |
+
|
| 217 |
+
@media (max-width:480px){
|
| 218 |
+
.controls{ grid-template-columns:1fr; }
|
| 219 |
+
}
|
| 220 |
+
|
| 221 |
+
/* ---------- Button ---------- */
|
| 222 |
+
.actions{
|
| 223 |
+
margin-top:18px;
|
| 224 |
+
display:flex;
|
| 225 |
+
gap:10px;
|
| 226 |
+
flex-wrap:wrap;
|
| 227 |
+
}
|
| 228 |
+
button{
|
| 229 |
+
font-family:var(--mm);
|
| 230 |
+
font-size:15px;
|
| 231 |
+
font-weight:600;
|
| 232 |
+
border:none;
|
| 233 |
+
border-radius:10px;
|
| 234 |
+
padding:13px 22px;
|
| 235 |
+
cursor:pointer;
|
| 236 |
+
transition:opacity .15s ease, transform .05s ease;
|
| 237 |
+
}
|
| 238 |
+
button:active{ transform:scale(.98); }
|
| 239 |
+
button:disabled{ opacity:.5; cursor:wait; }
|
| 240 |
+
|
| 241 |
+
.btn-primary{
|
| 242 |
+
background:var(--accent);
|
| 243 |
+
color:#fff;
|
| 244 |
+
flex:1;
|
| 245 |
+
}
|
| 246 |
+
.btn-primary:hover:not(:disabled){ opacity:.9; }
|
| 247 |
+
|
| 248 |
+
.btn-secondary{
|
| 249 |
+
background:var(--surface-2);
|
| 250 |
+
color:var(--ink);
|
| 251 |
+
border:1px solid var(--line);
|
| 252 |
+
}
|
| 253 |
+
|
| 254 |
+
/* ---------- Output ---------- */
|
| 255 |
+
.output{
|
| 256 |
+
margin-top:16px;
|
| 257 |
+
display:none;
|
| 258 |
+
}
|
| 259 |
+
.output.visible{ display:block; }
|
| 260 |
+
|
| 261 |
+
.output audio{
|
| 262 |
+
width:100%;
|
| 263 |
+
margin-top:12px;
|
| 264 |
+
}
|
| 265 |
+
|
| 266 |
+
.status{
|
| 267 |
+
font-family:var(--sans);
|
| 268 |
+
font-size:13px;
|
| 269 |
+
color:var(--ink-soft);
|
| 270 |
+
margin-top:10px;
|
| 271 |
+
min-height:18px;
|
| 272 |
+
}
|
| 273 |
+
.status.error{ color:#D14343; }
|
| 274 |
+
|
| 275 |
+
footer{
|
| 276 |
+
text-align:center;
|
| 277 |
+
margin-top:32px;
|
| 278 |
+
font-size:12px;
|
| 279 |
+
color:var(--ink-soft);
|
| 280 |
+
font-family:var(--sans);
|
| 281 |
+
}
|
| 282 |
</style>
|
| 283 |
</head>
|
| 284 |
<body>
|
| 285 |
|
|
|
|
|
|
|
| 286 |
<div class="wrap">
|
| 287 |
+
<header>
|
| 288 |
+
<p class="eyebrow">Voice Studio · Free Text-to-Speech</p>
|
| 289 |
+
<h1>အသံ Studio</h1>
|
| 290 |
+
<p class="tagline">ဘာသာစကား 140+ မျိုးဖြင့် စာသားကို အသံအဖြစ် ပြောင်းလဲပါ</p>
|
| 291 |
+
<div class="wave" id="wave"></div>
|
| 292 |
+
</header>
|
| 293 |
+
|
| 294 |
+
<!-- Text input -->
|
| 295 |
+
<section class="panel">
|
| 296 |
+
<h2>Script</h2>
|
| 297 |
+
<textarea id="text" placeholder="စာသား ဒီနေရာတွင် ရိုက်ထည့်ပါ..." maxlength="3000"></textarea>
|
| 298 |
+
<div class="char-count" id="charCount">0 / 3000</div>
|
| 299 |
+
</section>
|
| 300 |
+
|
| 301 |
+
<!-- Voice + settings -->
|
| 302 |
+
<section class="panel">
|
| 303 |
+
<h2>Voice</h2>
|
| 304 |
+
|
| 305 |
+
<div class="field">
|
| 306 |
+
<label>ဘာသာစကား ရှာရန် (Search language)</label>
|
| 307 |
+
<input type="text" class="lang-search" id="langSearch" placeholder="e.g. Myanmar, English, Thai...">
|
| 308 |
</div>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 309 |
|
| 310 |
+
<div class="row2">
|
| 311 |
+
<div class="field">
|
| 312 |
+
<label>ဘာသာစကား (Language)</label>
|
| 313 |
+
<select id="langSelect"></select>
|
| 314 |
+
</div>
|
| 315 |
+
<div class="field">
|
| 316 |
+
<label>အသံ (Voice)</label>
|
| 317 |
+
<select id="voiceSelect"></select>
|
| 318 |
+
</div>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 319 |
</div>
|
| 320 |
|
| 321 |
<div class="controls">
|
| 322 |
<div class="control">
|
| 323 |
+
<label>အသံနှုန်း (Speed) <span class="val" id="rateVal">+0%</span></label>
|
| 324 |
<input type="range" id="rate" min="-50" max="50" value="0" step="5">
|
| 325 |
</div>
|
| 326 |
<div class="control">
|
| 327 |
+
<label>အသံအနိမ့်အမြင့် (Pitch) <span class="val" id="pitchVal">+0Hz</span></label>
|
| 328 |
<input type="range" id="pitch" min="-50" max="50" value="0" step="5">
|
| 329 |
</div>
|
| 330 |
</div>
|
| 331 |
|
| 332 |
<div class="actions">
|
| 333 |
+
<button class="btn-primary" id="generateBtn">အသံ ထုတ်မည်</button>
|
| 334 |
</div>
|
| 335 |
|
| 336 |
<div class="status" id="status"></div>
|
|
|
|
| 338 |
<div class="output" id="output">
|
| 339 |
<audio id="player" controls></audio>
|
| 340 |
<div class="actions">
|
| 341 |
+
<a class="btn-secondary" id="downloadLink" download="voice.mp3" style="text-decoration:none; display:inline-block; text-align:center;">ဒေါင်းလုဒ် (mp3)</a>
|
| 342 |
</div>
|
| 343 |
</div>
|
| 344 |
+
</section>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 345 |
</div>
|
|
|
|
| 346 |
|
| 347 |
+
<footer>
|
| 348 |
+
Powered by Edge TTS · Free & Open Voice Studio
|
| 349 |
+
</footer>
|
| 350 |
|
|
|
|
| 351 |
<script>
|
| 352 |
+
// ---- Build signature waveform ----
|
| 353 |
+
const wave = document.getElementById('wave');
|
| 354 |
+
const BAR_COUNT = 20;
|
| 355 |
+
for (let i = 0; i < BAR_COUNT; i++) {
|
| 356 |
+
const bar = document.createElement('div');
|
| 357 |
+
bar.className = 'bar';
|
| 358 |
+
bar.style.animationDelay = (i * 0.06) + 's';
|
| 359 |
+
wave.appendChild(bar);
|
| 360 |
+
}
|
| 361 |
+
const bars = wave.querySelectorAll('.bar');
|
| 362 |
+
|
| 363 |
+
function setWaveActive(active) {
|
| 364 |
+
wave.classList.toggle('is-active', active);
|
| 365 |
+
if (!active) {
|
| 366 |
+
bars.forEach(b => b.style.height = '');
|
| 367 |
+
return;
|
| 368 |
+
}
|
| 369 |
+
}
|
| 370 |
+
|
| 371 |
+
let waveInterval = null;
|
| 372 |
+
function startWaveAnimation() {
|
| 373 |
+
setWaveActive(true);
|
| 374 |
+
waveInterval = setInterval(() => {
|
| 375 |
+
bars.forEach(b => {
|
| 376 |
+
const h = 6 + Math.random() * 22;
|
| 377 |
+
b.style.height = h + 'px';
|
| 378 |
+
});
|
| 379 |
+
}, 110);
|
| 380 |
+
}
|
| 381 |
+
function stopWaveAnimation() {
|
| 382 |
+
if (waveInterval) clearInterval(waveInterval);
|
| 383 |
+
waveInterval = null;
|
| 384 |
+
setWaveActive(false);
|
| 385 |
+
}
|
| 386 |
+
|
| 387 |
+
// ---- Sliders ----
|
| 388 |
+
const rate = document.getElementById('rate');
|
| 389 |
+
const pitch = document.getElementById('pitch');
|
| 390 |
+
const rateVal = document.getElementById('rateVal');
|
| 391 |
+
const pitchVal = document.getElementById('pitchVal');
|
| 392 |
+
|
| 393 |
+
function fmt(v, unit) {
|
| 394 |
+
const n = Number(v);
|
| 395 |
+
return (n >= 0 ? '+' : '') + n + unit;
|
| 396 |
+
}
|
| 397 |
+
rate.addEventListener('input', () => rateVal.textContent = fmt(rate.value, '%'));
|
| 398 |
+
pitch.addEventListener('input', () => pitchVal.textContent = fmt(pitch.value, 'Hz'));
|
| 399 |
+
|
| 400 |
+
// ---- Character counter ----
|
| 401 |
+
const text = document.getElementById('text');
|
| 402 |
+
const charCount = document.getElementById('charCount');
|
| 403 |
+
text.addEventListener('input', () => {
|
| 404 |
+
const len = text.value.length;
|
| 405 |
+
charCount.textContent = `${len} / 3000`;
|
| 406 |
+
charCount.classList.toggle('over', len > 3000);
|
| 407 |
});
|
| 408 |
+
|
| 409 |
+
// ---- Voices: fetch grouped by language, populate selects ----
|
| 410 |
+
const langSelect = document.getElementById('langSelect');
|
| 411 |
+
const voiceSelect = document.getElementById('voiceSelect');
|
| 412 |
+
const langSearch = document.getElementById('langSearch');
|
| 413 |
+
|
| 414 |
+
let voiceData = {}; // { language: [ {id, name, gender}, ... ] }
|
| 415 |
+
let languages = []; // sorted language names
|
| 416 |
+
const DEFAULT_LANG = 'Myanmar (Burmese)';
|
| 417 |
+
const DEFAULT_VOICE_ID = 'my-MM-NilarNeural';
|
| 418 |
+
|
| 419 |
+
function populateVoicesFor(lang) {
|
| 420 |
+
voiceSelect.innerHTML = '';
|
| 421 |
+
const list = voiceData[lang] || [];
|
| 422 |
+
list.forEach(v => {
|
| 423 |
+
const opt = document.createElement('option');
|
| 424 |
+
opt.value = v.id;
|
| 425 |
+
opt.textContent = `${v.name} (${v.gender})`;
|
| 426 |
+
voiceSelect.appendChild(opt);
|
| 427 |
});
|
| 428 |
+
}
|
| 429 |
+
|
| 430 |
+
function populateLanguages(filter) {
|
| 431 |
+
langSelect.innerHTML = '';
|
| 432 |
+
const f = (filter || '').trim().toLowerCase();
|
| 433 |
+
const filtered = f ? languages.filter(l => l.toLowerCase().includes(f)) : languages;
|
| 434 |
+
filtered.forEach(lang => {
|
| 435 |
+
const opt = document.createElement('option');
|
| 436 |
+
opt.value = lang;
|
| 437 |
+
opt.textContent = lang;
|
| 438 |
+
langSelect.appendChild(opt);
|
| 439 |
+
});
|
| 440 |
+
if (filtered.length) {
|
| 441 |
+
const preferred = filtered.includes(DEFAULT_LANG) && !f ? DEFAULT_LANG : filtered[0];
|
| 442 |
+
langSelect.value = preferred;
|
| 443 |
+
populateVoicesFor(preferred);
|
| 444 |
+
} else {
|
| 445 |
+
voiceSelect.innerHTML = '';
|
| 446 |
+
}
|
| 447 |
+
}
|
| 448 |
+
|
| 449 |
+
langSearch.addEventListener('input', () => populateLanguages(langSearch.value));
|
| 450 |
+
langSelect.addEventListener('change', () => populateVoicesFor(langSelect.value));
|
| 451 |
+
|
| 452 |
+
async function loadVoices() {
|
| 453 |
+
try {
|
| 454 |
+
const res = await fetch('/api/voices');
|
| 455 |
+
voiceData = await res.json();
|
| 456 |
+
languages = Object.keys(voiceData);
|
| 457 |
+
populateLanguages('');
|
| 458 |
+
// select default Myanmar voice if present
|
| 459 |
+
if (voiceData[DEFAULT_LANG] && voiceData[DEFAULT_LANG].some(v => v.id === DEFAULT_VOICE_ID)) {
|
| 460 |
+
langSelect.value = DEFAULT_LANG;
|
| 461 |
+
populateVoicesFor(DEFAULT_LANG);
|
| 462 |
+
voiceSelect.value = DEFAULT_VOICE_ID;
|
| 463 |
+
}
|
| 464 |
+
} catch (e) {
|
| 465 |
+
status.textContent = 'ဘာသာစကား စာရင်း ရယူခြင်း မအောင်မြင်ပါ။';
|
| 466 |
+
status.classList.add('error');
|
| 467 |
+
}
|
| 468 |
+
}
|
| 469 |
+
loadVoices();
|
| 470 |
+
|
| 471 |
+
// ---- Generate ----
|
| 472 |
+
const generateBtn = document.getElementById('generateBtn');
|
| 473 |
+
const status = document.getElementById('status');
|
| 474 |
+
const output = document.getElementById('output');
|
| 475 |
+
const player = document.getElementById('player');
|
| 476 |
+
const downloadLink = document.getElementById('downloadLink');
|
| 477 |
+
|
| 478 |
+
let currentObjectUrl = null;
|
| 479 |
+
|
| 480 |
+
generateBtn.addEventListener('click', async () => {
|
| 481 |
+
const value = text.value.trim();
|
| 482 |
+
if (!value) {
|
| 483 |
+
status.textContent = 'စာသား ထည့်ပေးပါ။';
|
| 484 |
+
status.classList.add('error');
|
| 485 |
+
return;
|
| 486 |
+
}
|
| 487 |
+
|
| 488 |
+
const voice = voiceSelect.value;
|
| 489 |
+
if (!voice) {
|
| 490 |
+
status.textContent = 'အသံတစ်ခု ရွေးပေးပါ။';
|
| 491 |
+
status.classList.add('error');
|
| 492 |
+
return;
|
| 493 |
+
}
|
| 494 |
+
|
| 495 |
+
status.classList.remove('error');
|
| 496 |
+
status.textContent = 'အသံထုတ်နေပါသည်...';
|
| 497 |
+
generateBtn.disabled = true;
|
| 498 |
+
startWaveAnimation();
|
| 499 |
+
|
| 500 |
+
try {
|
| 501 |
+
const res = await fetch('/api/tts', {
|
| 502 |
+
method: 'POST',
|
| 503 |
+
headers: { 'Content-Type': 'application/json' },
|
| 504 |
+
body: JSON.stringify({
|
| 505 |
+
text: value,
|
| 506 |
+
voice: voice,
|
| 507 |
+
rate: Number(rate.value),
|
| 508 |
+
pitch: Number(pitch.value)
|
| 509 |
+
})
|
| 510 |
+
});
|
| 511 |
+
|
| 512 |
+
if (!res.ok) {
|
| 513 |
+
const err = await res.json().catch(() => ({}));
|
| 514 |
+
throw new Error(err.error || 'အသံထုတ်ခြင်း မအောင်မြင်ပါ');
|
| 515 |
+
}
|
| 516 |
+
|
| 517 |
+
const blob = await res.blob();
|
| 518 |
+
if (currentObjectUrl) URL.revokeObjectURL(currentObjectUrl);
|
| 519 |
+
currentObjectUrl = URL.createObjectURL(blob);
|
| 520 |
+
|
| 521 |
+
player.src = currentObjectUrl;
|
| 522 |
+
downloadLink.href = currentObjectUrl;
|
| 523 |
+
output.classList.add('visible');
|
| 524 |
+
status.textContent = 'အသံ အောင်မြင်စွာ ထုတ်ပြီးပါပြီ။';
|
| 525 |
+
player.play().catch(() => {});
|
| 526 |
+
} catch (e) {
|
| 527 |
+
status.textContent = e.message;
|
| 528 |
+
status.classList.add('error');
|
| 529 |
+
} finally {
|
| 530 |
+
generateBtn.disabled = false;
|
| 531 |
+
stopWaveAnimation();
|
| 532 |
+
}
|
| 533 |
});
|
|
|
|
| 534 |
</script>
|
|
|
|
| 535 |
</body>
|
| 536 |
</html>
|
voices_data.py
ADDED
|
@@ -0,0 +1,330 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Comprehensive Edge TTS voice catalogue (ShortName -> language label, gender)
|
| 2 |
+
# Format: (short_name, language_display_name, gender)
|
| 3 |
+
VOICE_LIST = [
|
| 4 |
+
("af-ZA-AdriNeural", "Afrikaans", "Female"),
|
| 5 |
+
("af-ZA-WillemNeural", "Afrikaans", "Male"),
|
| 6 |
+
("am-ET-AmehaNeural", "Amharic", "Male"),
|
| 7 |
+
("am-ET-MekdesNeural", "Amharic", "Female"),
|
| 8 |
+
("ar-AE-FatimaNeural", "Arabic (UAE)", "Female"),
|
| 9 |
+
("ar-AE-HamdanNeural", "Arabic (UAE)", "Male"),
|
| 10 |
+
("ar-BH-AliNeural", "Arabic (Bahrain)", "Male"),
|
| 11 |
+
("ar-BH-LailaNeural", "Arabic (Bahrain)", "Female"),
|
| 12 |
+
("ar-DZ-AminaNeural", "Arabic (Algeria)", "Female"),
|
| 13 |
+
("ar-DZ-IsmaelNeural", "Arabic (Algeria)", "Male"),
|
| 14 |
+
("ar-EG-SalmaNeural", "Arabic (Egypt)", "Female"),
|
| 15 |
+
("ar-EG-ShakirNeural", "Arabic (Egypt)", "Male"),
|
| 16 |
+
("ar-IQ-BasselNeural", "Arabic (Iraq)", "Male"),
|
| 17 |
+
("ar-IQ-RanaNeural", "Arabic (Iraq)", "Female"),
|
| 18 |
+
("ar-JO-SanaNeural", "Arabic (Jordan)", "Female"),
|
| 19 |
+
("ar-JO-TaimNeural", "Arabic (Jordan)", "Male"),
|
| 20 |
+
("ar-KW-FahedNeural", "Arabic (Kuwait)", "Male"),
|
| 21 |
+
("ar-KW-NouraNeural", "Arabic (Kuwait)", "Female"),
|
| 22 |
+
("ar-LB-LaylaNeural", "Arabic (Lebanon)", "Female"),
|
| 23 |
+
("ar-LB-RamiNeural", "Arabic (Lebanon)", "Male"),
|
| 24 |
+
("ar-LY-ImanNeural", "Arabic (Libya)", "Female"),
|
| 25 |
+
("ar-LY-OmarNeural", "Arabic (Libya)", "Male"),
|
| 26 |
+
("ar-MA-JamalNeural", "Arabic (Morocco)", "Male"),
|
| 27 |
+
("ar-MA-MounaNeural", "Arabic (Morocco)", "Female"),
|
| 28 |
+
("ar-OM-AbdullahNeural", "Arabic (Oman)", "Male"),
|
| 29 |
+
("ar-OM-AyshaNeural", "Arabic (Oman)", "Female"),
|
| 30 |
+
("ar-QA-AmalNeural", "Arabic (Qatar)", "Female"),
|
| 31 |
+
("ar-QA-MoazNeural", "Arabic (Qatar)", "Male"),
|
| 32 |
+
("ar-SA-HamedNeural", "Arabic (Saudi Arabia)", "Male"),
|
| 33 |
+
("ar-SA-ZariyahNeural", "Arabic (Saudi Arabia)", "Female"),
|
| 34 |
+
("ar-SY-AmanyNeural", "Arabic (Syria)", "Female"),
|
| 35 |
+
("ar-SY-LaithNeural", "Arabic (Syria)", "Male"),
|
| 36 |
+
("ar-TN-HediNeural", "Arabic (Tunisia)", "Male"),
|
| 37 |
+
("ar-TN-ReemNeural", "Arabic (Tunisia)", "Female"),
|
| 38 |
+
("ar-YE-MaryamNeural", "Arabic (Yemen)", "Female"),
|
| 39 |
+
("ar-YE-SalehNeural", "Arabic (Yemen)", "Male"),
|
| 40 |
+
("az-AZ-BabekNeural", "Azerbaijani", "Male"),
|
| 41 |
+
("az-AZ-BanuNeural", "Azerbaijani", "Female"),
|
| 42 |
+
("bg-BG-BorislavNeural", "Bulgarian", "Male"),
|
| 43 |
+
("bg-BG-KalinaNeural", "Bulgarian", "Female"),
|
| 44 |
+
("bn-BD-NabanitaNeural", "Bengali (Bangladesh)", "Female"),
|
| 45 |
+
("bn-BD-PradeepNeural", "Bengali (Bangladesh)", "Male"),
|
| 46 |
+
("bn-IN-BashkarNeural", "Bengali (India)", "Male"),
|
| 47 |
+
("bn-IN-TanishaaNeural", "Bengali (India)", "Female"),
|
| 48 |
+
("bs-BA-GoranNeural", "Bosnian", "Male"),
|
| 49 |
+
("bs-BA-VesnaNeural", "Bosnian", "Female"),
|
| 50 |
+
("ca-ES-AlbaNeural", "Catalan", "Female"),
|
| 51 |
+
("ca-ES-EnricNeural", "Catalan", "Male"),
|
| 52 |
+
("ca-ES-JoanaNeural", "Catalan", "Female"),
|
| 53 |
+
("cs-CZ-AntoninNeural", "Czech", "Male"),
|
| 54 |
+
("cs-CZ-VlastaNeural", "Czech", "Female"),
|
| 55 |
+
("cy-GB-AledNeural", "Welsh", "Male"),
|
| 56 |
+
("cy-GB-NiaNeural", "Welsh", "Female"),
|
| 57 |
+
("da-DK-ChristelNeural", "Danish", "Female"),
|
| 58 |
+
("da-DK-JeppeNeural", "Danish", "Male"),
|
| 59 |
+
("de-AT-IngridNeural", "German (Austria)", "Female"),
|
| 60 |
+
("de-AT-JonasNeural", "German (Austria)", "Male"),
|
| 61 |
+
("de-CH-JanNeural", "German (Switzerland)", "Male"),
|
| 62 |
+
("de-CH-LeniNeural", "German (Switzerland)", "Female"),
|
| 63 |
+
("de-DE-AmalaNeural", "German", "Female"),
|
| 64 |
+
("de-DE-ConradNeural", "German", "Male"),
|
| 65 |
+
("de-DE-FlorianMultilingualNeural", "German", "Male"),
|
| 66 |
+
("de-DE-KatjaNeural", "German", "Female"),
|
| 67 |
+
("de-DE-KillianNeural", "German", "Male"),
|
| 68 |
+
("de-DE-SeraphinaMultilingualNeural", "German", "Female"),
|
| 69 |
+
("el-GR-AthinaNeural", "Greek", "Female"),
|
| 70 |
+
("el-GR-NestorasNeural", "Greek", "Male"),
|
| 71 |
+
("en-AU-NatashaNeural", "English (Australia)", "Female"),
|
| 72 |
+
("en-AU-WilliamNeural", "English (Australia)", "Male"),
|
| 73 |
+
("en-CA-ClaraNeural", "English (Canada)", "Female"),
|
| 74 |
+
("en-CA-LiamNeural", "English (Canada)", "Male"),
|
| 75 |
+
("en-GB-LibbyNeural", "English (UK)", "Female"),
|
| 76 |
+
("en-GB-MaisieNeural", "English (UK)", "Female"),
|
| 77 |
+
("en-GB-RyanNeural", "English (UK)", "Male"),
|
| 78 |
+
("en-GB-SoniaNeural", "English (UK)", "Female"),
|
| 79 |
+
("en-GB-ThomasNeural", "English (UK)", "Male"),
|
| 80 |
+
("en-HK-SamNeural", "English (Hong Kong)", "Male"),
|
| 81 |
+
("en-HK-YanNeural", "English (Hong Kong)", "Female"),
|
| 82 |
+
("en-IE-ConnorNeural", "English (Ireland)", "Male"),
|
| 83 |
+
("en-IE-EmilyNeural", "English (Ireland)", "Female"),
|
| 84 |
+
("en-IN-NeerjaNeural", "English (India)", "Female"),
|
| 85 |
+
("en-IN-PrabhatNeural", "English (India)", "Male"),
|
| 86 |
+
("en-KE-AsiliaNeural", "English (Kenya)", "Female"),
|
| 87 |
+
("en-KE-ChilembaNeural", "English (Kenya)", "Male"),
|
| 88 |
+
("en-NG-AbeoNeural", "English (Nigeria)", "Male"),
|
| 89 |
+
("en-NG-EzinneNeural", "English (Nigeria)", "Female"),
|
| 90 |
+
("en-NZ-MitchellNeural", "English (New Zealand)", "Male"),
|
| 91 |
+
("en-NZ-MollyNeural", "English (New Zealand)", "Female"),
|
| 92 |
+
("en-PH-JamesNeural", "English (Philippines)", "Male"),
|
| 93 |
+
("en-PH-RosaNeural", "English (Philippines)", "Female"),
|
| 94 |
+
("en-SG-LunaNeural", "English (Singapore)", "Female"),
|
| 95 |
+
("en-SG-WayneNeural", "English (Singapore)", "Male"),
|
| 96 |
+
("en-TZ-ElimuNeural", "English (Tanzania)", "Male"),
|
| 97 |
+
("en-TZ-ImaniNeural", "English (Tanzania)", "Female"),
|
| 98 |
+
("en-US-AnaNeural", "English (US)", "Female"),
|
| 99 |
+
("en-US-AndrewNeural", "English (US)", "Male"),
|
| 100 |
+
("en-US-AndrewMultilingualNeural", "English (US)", "Male"),
|
| 101 |
+
("en-US-AriaNeural", "English (US)", "Female"),
|
| 102 |
+
("en-US-AvaNeural", "English (US)", "Female"),
|
| 103 |
+
("en-US-AvaMultilingualNeural", "English (US)", "Female"),
|
| 104 |
+
("en-US-BrianNeural", "English (US)", "Male"),
|
| 105 |
+
("en-US-BrianMultilingualNeural", "English (US)", "Male"),
|
| 106 |
+
("en-US-ChristopherNeural", "English (US)", "Male"),
|
| 107 |
+
("en-US-EmmaNeural", "English (US)", "Female"),
|
| 108 |
+
("en-US-EmmaMultilingualNeural", "English (US)", "Female"),
|
| 109 |
+
("en-US-EricNeural", "English (US)", "Male"),
|
| 110 |
+
("en-US-GuyNeural", "English (US)", "Male"),
|
| 111 |
+
("en-US-JennyNeural", "English (US)", "Female"),
|
| 112 |
+
("en-US-MichelleNeural", "English (US)", "Female"),
|
| 113 |
+
("en-US-RogerNeural", "English (US)", "Male"),
|
| 114 |
+
("en-US-SteffanNeural", "English (US)", "Male"),
|
| 115 |
+
("en-ZA-LeahNeural", "English (South Africa)", "Female"),
|
| 116 |
+
("en-ZA-LukeNeural", "English (South Africa)", "Male"),
|
| 117 |
+
("es-AR-ElenaNeural", "Spanish (Argentina)", "Female"),
|
| 118 |
+
("es-AR-TomasNeural", "Spanish (Argentina)", "Male"),
|
| 119 |
+
("es-BO-MarceloNeural", "Spanish (Bolivia)", "Male"),
|
| 120 |
+
("es-BO-SofiaNeural", "Spanish (Bolivia)", "Female"),
|
| 121 |
+
("es-CL-CatalinaNeural", "Spanish (Chile)", "Female"),
|
| 122 |
+
("es-CL-LorenzoNeural", "Spanish (Chile)", "Male"),
|
| 123 |
+
("es-CO-GonzaloNeural", "Spanish (Colombia)", "Male"),
|
| 124 |
+
("es-CO-SalomeNeural", "Spanish (Colombia)", "Female"),
|
| 125 |
+
("es-CR-JuanNeural", "Spanish (Costa Rica)", "Male"),
|
| 126 |
+
("es-CR-MariaNeural", "Spanish (Costa Rica)", "Female"),
|
| 127 |
+
("es-CU-BelkysNeural", "Spanish (Cuba)", "Female"),
|
| 128 |
+
("es-CU-ManuelNeural", "Spanish (Cuba)", "Male"),
|
| 129 |
+
("es-DO-EmilioNeural", "Spanish (Dominican Republic)", "Male"),
|
| 130 |
+
("es-DO-RamonaNeural", "Spanish (Dominican Republic)", "Female"),
|
| 131 |
+
("es-EC-AndreaNeural", "Spanish (Ecuador)", "Female"),
|
| 132 |
+
("es-EC-LuisNeural", "Spanish (Ecuador)", "Male"),
|
| 133 |
+
("es-ES-AlvaroNeural", "Spanish (Spain)", "Male"),
|
| 134 |
+
("es-ES-ElviraNeural", "Spanish (Spain)", "Female"),
|
| 135 |
+
("es-ES-XimenaNeural", "Spanish (Spain)", "Female"),
|
| 136 |
+
("es-GQ-JavierNeural", "Spanish (Equatorial Guinea)", "Male"),
|
| 137 |
+
("es-GQ-TeresaNeural", "Spanish (Equatorial Guinea)", "Female"),
|
| 138 |
+
("es-GT-AndresNeural", "Spanish (Guatemala)", "Male"),
|
| 139 |
+
("es-GT-MartaNeural", "Spanish (Guatemala)", "Female"),
|
| 140 |
+
("es-HN-CarlosNeural", "Spanish (Honduras)", "Male"),
|
| 141 |
+
("es-HN-KarlaNeural", "Spanish (Honduras)", "Female"),
|
| 142 |
+
("es-MX-DaliaNeural", "Spanish (Mexico)", "Female"),
|
| 143 |
+
("es-MX-JorgeNeural", "Spanish (Mexico)", "Male"),
|
| 144 |
+
("es-NI-FedericoNeural", "Spanish (Nicaragua)", "Male"),
|
| 145 |
+
("es-NI-YolandaNeural", "Spanish (Nicaragua)", "Female"),
|
| 146 |
+
("es-PA-MargaritaNeural", "Spanish (Panama)", "Female"),
|
| 147 |
+
("es-PA-RobertoNeural", "Spanish (Panama)", "Male"),
|
| 148 |
+
("es-PE-AlexNeural", "Spanish (Peru)", "Male"),
|
| 149 |
+
("es-PE-CamilaNeural", "Spanish (Peru)", "Female"),
|
| 150 |
+
("es-PR-KarinaNeural", "Spanish (Puerto Rico)", "Female"),
|
| 151 |
+
("es-PR-VictorNeural", "Spanish (Puerto Rico)", "Male"),
|
| 152 |
+
("es-PY-MarioNeural", "Spanish (Paraguay)", "Male"),
|
| 153 |
+
("es-PY-TaniaNeural", "Spanish (Paraguay)", "Female"),
|
| 154 |
+
("es-SV-LorenaNeural", "Spanish (El Salvador)", "Female"),
|
| 155 |
+
("es-SV-RodrigoNeural", "Spanish (El Salvador)", "Male"),
|
| 156 |
+
("es-US-AlonsoNeural", "Spanish (US)", "Male"),
|
| 157 |
+
("es-US-PalomaNeural", "Spanish (US)", "Female"),
|
| 158 |
+
("es-UY-MateoNeural", "Spanish (Uruguay)", "Male"),
|
| 159 |
+
("es-UY-ValentinaNeural", "Spanish (Uruguay)", "Female"),
|
| 160 |
+
("es-VE-PaolaNeural", "Spanish (Venezuela)", "Female"),
|
| 161 |
+
("es-VE-SebastianNeural", "Spanish (Venezuela)", "Male"),
|
| 162 |
+
("et-EE-AnuNeural", "Estonian", "Female"),
|
| 163 |
+
("et-EE-KertNeural", "Estonian", "Male"),
|
| 164 |
+
("eu-ES-AinhoaNeural", "Basque", "Female"),
|
| 165 |
+
("eu-ES-AnderNeural", "Basque", "Male"),
|
| 166 |
+
("fa-IR-DilaraNeural", "Persian", "Female"),
|
| 167 |
+
("fa-IR-FaridNeural", "Persian", "Male"),
|
| 168 |
+
("fi-FI-HarriNeural", "Finnish", "Male"),
|
| 169 |
+
("fi-FI-NooraNeural", "Finnish", "Female"),
|
| 170 |
+
("fil-PH-AngeloNeural", "Filipino", "Male"),
|
| 171 |
+
("fil-PH-BlessicaNeural", "Filipino", "Female"),
|
| 172 |
+
("fr-BE-CharlineNeural", "French (Belgium)", "Female"),
|
| 173 |
+
("fr-BE-GerardNeural", "French (Belgium)", "Male"),
|
| 174 |
+
("fr-CA-AntoineNeural", "French (Canada)", "Male"),
|
| 175 |
+
("fr-CA-JeanNeural", "French (Canada)", "Male"),
|
| 176 |
+
("fr-CA-SylvieNeural", "French (Canada)", "Female"),
|
| 177 |
+
("fr-CA-ThierryNeural", "French (Canada)", "Male"),
|
| 178 |
+
("fr-CH-ArianeNeural", "French (Switzerland)", "Female"),
|
| 179 |
+
("fr-CH-FabriceNeural", "French (Switzerland)", "Male"),
|
| 180 |
+
("fr-FR-DeniseNeural", "French", "Female"),
|
| 181 |
+
("fr-FR-EloiseNeural", "French", "Female"),
|
| 182 |
+
("fr-FR-HenriNeural", "French", "Male"),
|
| 183 |
+
("fr-FR-RemyMultilingualNeural", "French", "Male"),
|
| 184 |
+
("fr-FR-VivienneMultilingualNeural", "French", "Female"),
|
| 185 |
+
("ga-IE-ColmNeural", "Irish", "Male"),
|
| 186 |
+
("ga-IE-OrlaNeural", "Irish", "Female"),
|
| 187 |
+
("gl-ES-RoiNeural", "Galician", "Male"),
|
| 188 |
+
("gl-ES-SabelaNeural", "Galician", "Female"),
|
| 189 |
+
("gu-IN-DhwaniNeural", "Gujarati", "Female"),
|
| 190 |
+
("gu-IN-NiranjanNeural", "Gujarati", "Male"),
|
| 191 |
+
("he-IL-AvriNeural", "Hebrew", "Male"),
|
| 192 |
+
("he-IL-HilaNeural", "Hebrew", "Female"),
|
| 193 |
+
("hi-IN-MadhurNeural", "Hindi", "Male"),
|
| 194 |
+
("hi-IN-SwaraNeural", "Hindi", "Female"),
|
| 195 |
+
("hr-HR-GabrijelaNeural", "Croatian", "Female"),
|
| 196 |
+
("hr-HR-SreckoNeural", "Croatian", "Male"),
|
| 197 |
+
("hu-HU-NoemiNeural", "Hungarian", "Female"),
|
| 198 |
+
("hu-HU-TamasNeural", "Hungarian", "Male"),
|
| 199 |
+
("id-ID-ArdiNeural", "Indonesian", "Male"),
|
| 200 |
+
("id-ID-GadisNeural", "Indonesian", "Female"),
|
| 201 |
+
("is-IS-GudrunNeural", "Icelandic", "Female"),
|
| 202 |
+
("is-IS-GunnarNeural", "Icelandic", "Male"),
|
| 203 |
+
("it-IT-DiegoNeural", "Italian", "Male"),
|
| 204 |
+
("it-IT-ElsaNeural", "Italian", "Female"),
|
| 205 |
+
("it-IT-GiuseppeNeural", "Italian", "Male"),
|
| 206 |
+
("it-IT-GiuseppeMultilingualNeural", "Italian", "Male"),
|
| 207 |
+
("it-IT-IsabellaNeural", "Italian", "Female"),
|
| 208 |
+
("iu-Cans-CA-SiqiniqNeural", "Inuktitut (Syllabics)", "Female"),
|
| 209 |
+
("iu-Cans-CA-TaqqiqNeural", "Inuktitut (Syllabics)", "Male"),
|
| 210 |
+
("iu-Latn-CA-SiqiniqNeural", "Inuktitut (Latin)", "Female"),
|
| 211 |
+
("iu-Latn-CA-TaqqiqNeural", "Inuktitut (Latin)", "Male"),
|
| 212 |
+
("ja-JP-KeitaNeural", "Japanese", "Male"),
|
| 213 |
+
("ja-JP-NanamiNeural", "Japanese", "Female"),
|
| 214 |
+
("jv-ID-DimasNeural", "Javanese", "Male"),
|
| 215 |
+
("jv-ID-SitiNeural", "Javanese", "Female"),
|
| 216 |
+
("ka-GE-EkaNeural", "Georgian", "Female"),
|
| 217 |
+
("ka-GE-GiorgiNeural", "Georgian", "Male"),
|
| 218 |
+
("kk-KZ-AigulNeural", "Kazakh", "Female"),
|
| 219 |
+
("kk-KZ-DauletNeural", "Kazakh", "Male"),
|
| 220 |
+
("km-KH-PisethNeural", "Khmer", "Male"),
|
| 221 |
+
("km-KH-SreymomNeural", "Khmer", "Female"),
|
| 222 |
+
("kn-IN-GaganNeural", "Kannada", "Male"),
|
| 223 |
+
("kn-IN-SapnaNeural", "Kannada", "Female"),
|
| 224 |
+
("ko-KR-HyunsuNeural", "Korean", "Male"),
|
| 225 |
+
("ko-KR-InJoonNeural", "Korean", "Male"),
|
| 226 |
+
("ko-KR-SunHiNeural", "Korean", "Female"),
|
| 227 |
+
("lo-LA-ChanthavongNeural", "Lao", "Male"),
|
| 228 |
+
("lo-LA-KeomanyNeural", "Lao", "Female"),
|
| 229 |
+
("lt-LT-LeonasNeural", "Lithuanian", "Male"),
|
| 230 |
+
("lt-LT-OnaNeural", "Lithuanian", "Female"),
|
| 231 |
+
("lv-LV-EveritaNeural", "Latvian", "Female"),
|
| 232 |
+
("lv-LV-NilsNeural", "Latvian", "Male"),
|
| 233 |
+
("mk-MK-AleksandarNeural", "Macedonian", "Male"),
|
| 234 |
+
("mk-MK-MarijaNeural", "Macedonian", "Female"),
|
| 235 |
+
("ml-IN-MidhunNeural", "Malayalam", "Male"),
|
| 236 |
+
("ml-IN-SobhanaNeural", "Malayalam", "Female"),
|
| 237 |
+
("mn-MN-BataaNeural", "Mongolian", "Male"),
|
| 238 |
+
("mn-MN-YesuiNeural", "Mongolian", "Female"),
|
| 239 |
+
("mr-IN-AarohiNeural", "Marathi", "Female"),
|
| 240 |
+
("mr-IN-ManoharNeural", "Marathi", "Male"),
|
| 241 |
+
("ms-MY-OsmanNeural", "Malay", "Male"),
|
| 242 |
+
("ms-MY-YasminNeural", "Malay", "Female"),
|
| 243 |
+
("mt-MT-GraceNeural", "Maltese", "Female"),
|
| 244 |
+
("mt-MT-JosephNeural", "Maltese", "Male"),
|
| 245 |
+
("my-MM-NilarNeural", "Myanmar (Burmese)", "Female"),
|
| 246 |
+
("my-MM-ThihaNeural", "Myanmar (Burmese)", "Male"),
|
| 247 |
+
("nb-NO-FinnNeural", "Norwegian", "Male"),
|
| 248 |
+
("nb-NO-PernilleNeural", "Norwegian", "Female"),
|
| 249 |
+
("ne-NP-HemkalaNeural", "Nepali", "Female"),
|
| 250 |
+
("ne-NP-SagarNeural", "Nepali", "Male"),
|
| 251 |
+
("nl-BE-ArnaudNeural", "Dutch (Belgium)", "Male"),
|
| 252 |
+
("nl-BE-DenaNeural", "Dutch (Belgium)", "Female"),
|
| 253 |
+
("nl-NL-ColetteNeural", "Dutch", "Female"),
|
| 254 |
+
("nl-NL-FennaNeural", "Dutch", "Female"),
|
| 255 |
+
("nl-NL-MaartenNeural", "Dutch", "Male"),
|
| 256 |
+
("pl-PL-MarekNeural", "Polish", "Male"),
|
| 257 |
+
("pl-PL-ZofiaNeural", "Polish", "Female"),
|
| 258 |
+
("ps-AF-GulNawazNeural", "Pashto", "Male"),
|
| 259 |
+
("ps-AF-LatifaNeural", "Pashto", "Female"),
|
| 260 |
+
("pt-BR-AntonioNeural", "Portuguese (Brazil)", "Male"),
|
| 261 |
+
("pt-BR-FranciscaNeural", "Portuguese (Brazil)", "Female"),
|
| 262 |
+
("pt-BR-ThalitaNeural", "Portuguese (Brazil)", "Female"),
|
| 263 |
+
("pt-BR-ThalitaMultilingualNeural", "Portuguese (Brazil)", "Female"),
|
| 264 |
+
("pt-PT-DuarteNeural", "Portuguese (Portugal)", "Male"),
|
| 265 |
+
("pt-PT-RaquelNeural", "Portuguese (Portugal)", "Female"),
|
| 266 |
+
("ro-RO-AlinaNeural", "Romanian", "Female"),
|
| 267 |
+
("ro-RO-EmilNeural", "Romanian", "Male"),
|
| 268 |
+
("ru-RU-DmitryNeural", "Russian", "Male"),
|
| 269 |
+
("ru-RU-SvetlanaNeural", "Russian", "Female"),
|
| 270 |
+
("si-LK-SameeraNeural", "Sinhala", "Male"),
|
| 271 |
+
("si-LK-ThiliniNeural", "Sinhala", "Female"),
|
| 272 |
+
("sk-SK-LukasNeural", "Slovak", "Male"),
|
| 273 |
+
("sk-SK-ViktoriaNeural", "Slovak", "Female"),
|
| 274 |
+
("sl-SI-PetraNeural", "Slovenian", "Female"),
|
| 275 |
+
("sl-SI-RokNeural", "Slovenian", "Male"),
|
| 276 |
+
("so-SO-MuuseNeural", "Somali", "Male"),
|
| 277 |
+
("so-SO-UbaxNeural", "Somali", "Female"),
|
| 278 |
+
("sq-AL-AnilaNeural", "Albanian", "Female"),
|
| 279 |
+
("sq-AL-IlirNeural", "Albanian", "Male"),
|
| 280 |
+
("sr-RS-NicholasNeural", "Serbian", "Male"),
|
| 281 |
+
("sr-RS-SophieNeural", "Serbian", "Female"),
|
| 282 |
+
("su-ID-JajangNeural", "Sundanese", "Male"),
|
| 283 |
+
("su-ID-TutiNeural", "Sundanese", "Female"),
|
| 284 |
+
("sv-SE-MattiasNeural", "Swedish", "Male"),
|
| 285 |
+
("sv-SE-SofieNeural", "Swedish", "Female"),
|
| 286 |
+
("sw-KE-RafikiNeural", "Swahili (Kenya)", "Male"),
|
| 287 |
+
("sw-KE-ZuriNeural", "Swahili (Kenya)", "Female"),
|
| 288 |
+
("sw-TZ-DaudiNeural", "Swahili (Tanzania)", "Male"),
|
| 289 |
+
("sw-TZ-RehemaNeural", "Swahili (Tanzania)", "Female"),
|
| 290 |
+
("ta-IN-PallaviNeural", "Tamil (India)", "Female"),
|
| 291 |
+
("ta-IN-ValluvarNeural", "Tamil (India)", "Male"),
|
| 292 |
+
("ta-LK-KumarNeural", "Tamil (Sri Lanka)", "Male"),
|
| 293 |
+
("ta-LK-SaranyaNeural", "Tamil (Sri Lanka)", "Female"),
|
| 294 |
+
("ta-MY-KaniNeural", "Tamil (Malaysia)", "Female"),
|
| 295 |
+
("ta-MY-SuryaNeural", "Tamil (Malaysia)", "Male"),
|
| 296 |
+
("ta-SG-AnbuNeural", "Tamil (Singapore)", "Male"),
|
| 297 |
+
("ta-SG-VenbaNeural", "Tamil (Singapore)", "Female"),
|
| 298 |
+
("te-IN-MohanNeural", "Telugu", "Male"),
|
| 299 |
+
("te-IN-ShrutiNeural", "Telugu", "Female"),
|
| 300 |
+
("th-TH-NiwatNeural", "Thai", "Male"),
|
| 301 |
+
("th-TH-PremwadeeNeural", "Thai", "Female"),
|
| 302 |
+
("tr-TR-AhmetNeural", "Turkish", "Male"),
|
| 303 |
+
("tr-TR-EmelNeural", "Turkish", "Female"),
|
| 304 |
+
("uk-UA-OstapNeural", "Ukrainian", "Male"),
|
| 305 |
+
("uk-UA-PolinaNeural", "Ukrainian", "Female"),
|
| 306 |
+
("ur-IN-GulNeural", "Urdu (India)", "Female"),
|
| 307 |
+
("ur-IN-SalmanNeural", "Urdu (India)", "Male"),
|
| 308 |
+
("ur-PK-AsadNeural", "Urdu (Pakistan)", "Male"),
|
| 309 |
+
("ur-PK-UzmaNeural", "Urdu (Pakistan)", "Female"),
|
| 310 |
+
("uz-UZ-MadinaNeural", "Uzbek", "Female"),
|
| 311 |
+
("uz-UZ-SardorNeural", "Uzbek", "Male"),
|
| 312 |
+
("vi-VN-HoaiMyNeural", "Vietnamese", "Female"),
|
| 313 |
+
("vi-VN-NamMinhNeural", "Vietnamese", "Male"),
|
| 314 |
+
("zh-CN-XiaoxiaoNeural", "Chinese (Mandarin)", "Female"),
|
| 315 |
+
("zh-CN-XiaoyiNeural", "Chinese (Mandarin)", "Female"),
|
| 316 |
+
("zh-CN-YunjianNeural", "Chinese (Mandarin)", "Male"),
|
| 317 |
+
("zh-CN-YunxiNeural", "Chinese (Mandarin)", "Male"),
|
| 318 |
+
("zh-CN-YunxiaNeural", "Chinese (Mandarin)", "Male"),
|
| 319 |
+
("zh-CN-YunyangNeural", "Chinese (Mandarin)", "Male"),
|
| 320 |
+
("zh-CN-liaoning-XiaobeiNeural", "Chinese (Liaoning)", "Female"),
|
| 321 |
+
("zh-CN-shaanxi-XiaoniNeural", "Chinese (Shaanxi)", "Female"),
|
| 322 |
+
("zh-HK-HiuGaaiNeural", "Chinese (Cantonese, HK)", "Female"),
|
| 323 |
+
("zh-HK-HiuMaanNeural", "Chinese (Cantonese, HK)", "Female"),
|
| 324 |
+
("zh-HK-WanLungNeural", "Chinese (Cantonese, HK)", "Male"),
|
| 325 |
+
("zh-TW-HsiaoChenNeural", "Chinese (Taiwan)", "Female"),
|
| 326 |
+
("zh-TW-HsiaoYuNeural", "Chinese (Taiwan)", "Female"),
|
| 327 |
+
("zh-TW-YunJheNeural", "Chinese (Taiwan)", "Male"),
|
| 328 |
+
("zu-ZA-ThandoNeural", "Zulu", "Female"),
|
| 329 |
+
("zu-ZA-ThembaNeural", "Zulu", "Male"),
|
| 330 |
+
]
|