Sync: app updates, remove obsolete files
Browse files- _blue_vocab.py +0 -362
- app.py +42 -12
- blue_tts.py +0 -467
- fonts/base64_font.txt +0 -1
- voices/male1.json +0 -3
_blue_vocab.py
DELETED
|
@@ -1,362 +0,0 @@
|
|
| 1 |
-
"""
|
| 2 |
-
Multilingual IPA vocabulary for TTS, built on the piper phoneme set.
|
| 3 |
-
|
| 4 |
-
Layout:
|
| 5 |
-
0..156 = Piper core symbols (exact IDs from rhasspy/piper-checkpoints)
|
| 6 |
-
157..243 = Extended symbols (uppercase letters, additional IPA, punctuation)
|
| 7 |
-
244..383 = Language tokens (140 slots)
|
| 8 |
-
|
| 9 |
-
VOCAB_SIZE = 384 (fixed, embedding-friendly: 384 = 6 × 64)
|
| 10 |
-
|
| 11 |
-
Special indices:
|
| 12 |
-
PAD_ID = 0 (_) padding / unknown
|
| 13 |
-
BOS_ID = 1 (^) begin-of-sequence (piper convention)
|
| 14 |
-
EOS_ID = 2 ($) end-of-sequence (piper convention)
|
| 15 |
-
|
| 16 |
-
Adding a new language:
|
| 17 |
-
1. Add one line to LANG_ID below
|
| 18 |
-
2. Add training data with a 'lang' column in the CSV
|
| 19 |
-
3. Resume training — no architecture change needed
|
| 20 |
-
"""
|
| 21 |
-
|
| 22 |
-
import os
|
| 23 |
-
import re
|
| 24 |
-
from unicodedata import normalize as uni_normalize
|
| 25 |
-
|
| 26 |
-
# ============================================================
|
| 27 |
-
# Piper phoneme map (exact IDs from rhasspy/piper-checkpoints)
|
| 28 |
-
# Source: en/en_US/ljspeech/medium/config.json phoneme_id_map
|
| 29 |
-
# ============================================================
|
| 30 |
-
_PIPER_MAP: dict[str, int] = {
|
| 31 |
-
"_": 0, # PAD
|
| 32 |
-
"^": 1, # BOS
|
| 33 |
-
"$": 2, # EOS
|
| 34 |
-
" ": 3,
|
| 35 |
-
"!": 4, "'": 5, "(": 6, ")": 7, ",": 8, "-": 9, ".": 10,
|
| 36 |
-
":": 11, ";": 12, "?": 13,
|
| 37 |
-
"a": 14, "b": 15, "c": 16, "d": 17, "e": 18, "f": 19,
|
| 38 |
-
"h": 20, "i": 21, "j": 22, "k": 23, "l": 24, "m": 25, "n": 26,
|
| 39 |
-
"o": 27, "p": 28, "q": 29, "r": 30, "s": 31, "t": 32, "u": 33,
|
| 40 |
-
"v": 34, "w": 35, "x": 36, "y": 37, "z": 38,
|
| 41 |
-
"æ": 39, "ç": 40, "ð": 41, "ø": 42, "ħ": 43, "ŋ": 44, "œ": 45,
|
| 42 |
-
"ǀ": 46, "ǁ": 47, "ǂ": 48, "ǃ": 49,
|
| 43 |
-
"ɐ": 50, "ɑ": 51, "ɒ": 52, "ɓ": 53, "ɔ": 54, "ɕ": 55,
|
| 44 |
-
"ɖ": 56, "ɗ": 57, "ɘ": 58, "ə": 59, "ɚ": 60, "ɛ": 61,
|
| 45 |
-
"ɜ": 62, "ɞ": 63, "ɟ": 64, "ɠ": 65, "ɡ": 66, "ɢ": 67,
|
| 46 |
-
"ɣ": 68, "ɤ": 69, "ɥ": 70, "ɦ": 71, "ɧ": 72, "ɨ": 73,
|
| 47 |
-
"ɪ": 74, "ɫ": 75, "ɬ": 76, "ɭ": 77, "ɮ": 78, "ɯ": 79,
|
| 48 |
-
"ɰ": 80, "ɱ": 81, "ɲ": 82, "ɳ": 83, "ɴ": 84, "ɵ": 85,
|
| 49 |
-
"ɶ": 86, "ɸ": 87, "ɹ": 88, "ɺ": 89, "ɻ": 90, "ɽ": 91,
|
| 50 |
-
"ɾ": 92, "ʀ": 93, "ʁ": 94, "ʂ": 95, "ʃ": 96, "ʄ": 97,
|
| 51 |
-
"ʈ": 98, "ʉ": 99, "ʊ": 100, "ʋ": 101, "ʌ": 102, "ʍ": 103,
|
| 52 |
-
"ʎ": 104, "ʏ": 105, "ʐ": 106, "ʑ": 107, "ʒ": 108, "ʔ": 109,
|
| 53 |
-
"ʕ": 110, "ʘ": 111, "ʙ": 112, "ʛ": 113, "ʜ": 114, "ʝ": 115,
|
| 54 |
-
"ʟ": 116, "ʡ": 117, "ʢ": 118, "ʲ": 119,
|
| 55 |
-
"ˈ": 120, "ˌ": 121, "ː": 122, "ˑ": 123, "˞": 124,
|
| 56 |
-
"β": 125, "θ": 126, "χ": 127, "ᵻ": 128, "ⱱ": 129,
|
| 57 |
-
"0": 130, "1": 131, "2": 132, "3": 133, "4": 134,
|
| 58 |
-
"5": 135, "6": 136, "7": 137, "8": 138, "9": 139,
|
| 59 |
-
"\u0327": 140, # ̧ combining cedilla
|
| 60 |
-
"\u0303": 141, # ̃ combining tilde
|
| 61 |
-
"\u032A": 142, # ̪ combining dental below
|
| 62 |
-
"\u032F": 143, # ̯ combining inverted breve below
|
| 63 |
-
"\u0329": 144, # ̩ combining vertical line below
|
| 64 |
-
"ʰ": 145, "ˤ": 146, "ε": 147, "↓": 148, "#": 149,
|
| 65 |
-
'"': 150, "↑": 151,
|
| 66 |
-
"\u033A": 152, # ̺ combining inverted bridge below
|
| 67 |
-
"\u033B": 153, # ̻ combining square below
|
| 68 |
-
"g": 154, "ʦ": 155, "X": 156,
|
| 69 |
-
}
|
| 70 |
-
|
| 71 |
-
# ============================================================
|
| 72 |
-
# Extended symbol map (indices 157..243)
|
| 73 |
-
# Covers uppercase letters, additional IPA symbols, and punctuation
|
| 74 |
-
# from: _letters, _letters_ipa, _punctuation
|
| 75 |
-
# ============================================================
|
| 76 |
-
_EXTENDED_MAP: dict[str, int] = {
|
| 77 |
-
# --- Uppercase letters (A-Z, X already at 156) ---
|
| 78 |
-
"A": 157, "B": 158, "C": 159, "D": 160, "E": 161, "F": 162, "G": 163,
|
| 79 |
-
"H": 164, "I": 165, "J": 166, "K": 167, "L": 168, "M": 169, "N": 170,
|
| 80 |
-
"O": 171, "P": 172, "Q": 173, "R": 174, "S": 175, "T": 176, "U": 177,
|
| 81 |
-
"V": 178, "W": 179, "Y": 180, "Z": 181,
|
| 82 |
-
# --- Additional IPA symbols ---
|
| 83 |
-
"ʤ": 182, # voiced postalveolar affricate (dʒ digraph)
|
| 84 |
-
"ɝ": 183, # open-mid central rhotic vowel
|
| 85 |
-
"ʧ": 184, # voiceless postalveolar affricate (tʃ digraph)
|
| 86 |
-
"ʼ": 185, # ejective marker (modifier letter apostrophe)
|
| 87 |
-
"ʴ": 186, # modifier letter small turned r
|
| 88 |
-
"ʱ": 187, # modifier letter small h with hook
|
| 89 |
-
"ʷ": 188, # modifier letter small w (labialization diacritic)
|
| 90 |
-
"ˠ": 189, # modifier letter small gamma (velarization diacritic)
|
| 91 |
-
"→": 190, # rightwards arrow (level tone)
|
| 92 |
-
"↗": 191, # north east arrow (rising tone)
|
| 93 |
-
"↘": 192, # south east arrow (falling tone)
|
| 94 |
-
# --- Additional punctuation ---
|
| 95 |
-
"¡": 193, # inverted exclamation mark
|
| 96 |
-
"¿": 194, # inverted question mark
|
| 97 |
-
"…": 195, # horizontal ellipsis
|
| 98 |
-
"«": 196, # left-pointing double angle quotation mark
|
| 99 |
-
"»": 197, # right-pointing double angle quotation mark
|
| 100 |
-
"*": 198, # asterisk
|
| 101 |
-
"~": 199, # tilde
|
| 102 |
-
"/": 200, # solidus
|
| 103 |
-
"\\": 201, # reverse solidus
|
| 104 |
-
"&": 202, # ampersand
|
| 105 |
-
# --- Combining IPA diacritics (203..223) ---
|
| 106 |
-
"\u0361": 203, # ͡ combining double inverted breve (affricate tie, e.g. t͡ʃ)
|
| 107 |
-
"\u035C": 204, # ͜ combining double breve below (alternative tie bar)
|
| 108 |
-
"\u0325": 205, # ̥ combining ring below (devoiced)
|
| 109 |
-
"\u032C": 206, # ̬ combining caron below (voiced)
|
| 110 |
-
"\u0339": 207, # ̹ combining right half ring below (more rounded)
|
| 111 |
-
"\u031C": 208, # ̜ combining left half ring below (less rounded)
|
| 112 |
-
"\u031D": 209, # ̝ combining up tack below (raised)
|
| 113 |
-
"\u031E": 210, # ̞ combining down tack below (lowered)
|
| 114 |
-
"\u031F": 211, # ̟ combining plus sign below (advanced)
|
| 115 |
-
"\u0320": 212, # ̠ combining minus sign below (retracted)
|
| 116 |
-
"\u0330": 213, # ̰ combining tilde below (creaky voice)
|
| 117 |
-
"\u0334": 214, # ̴ combining tilde overlay (nasalization)
|
| 118 |
-
"\u031A": 215, # ̚ combining left angle above (no audible release)
|
| 119 |
-
"\u0318": 216, # ̘ combining left tack below (advanced tongue root)
|
| 120 |
-
"\u0319": 217, # ̙ combining right tack below (retracted tongue root)
|
| 121 |
-
"\u0348": 218, # ͈ combining double vertical line below (fortis)
|
| 122 |
-
"\u0306": 219, # ̆ combining breve (extra short)
|
| 123 |
-
"\u0308": 220, # ̈ combining diaeresis above (centralized)
|
| 124 |
-
"\u031B": 221, # ̛ combining horn
|
| 125 |
-
"\u0324": 222, # ̤ combining diaeresis below (breathy voice)
|
| 126 |
-
"\u033C": 223, # ̼ combining seagull below (linguolabial)
|
| 127 |
-
# --- Modifier letters (224..232) ---
|
| 128 |
-
"\u02C0": 224, # ˀ modifier letter glottal stop
|
| 129 |
-
"\u02C1": 225, # ˁ modifier letter reversed glottal stop
|
| 130 |
-
"\u02BE": 226, # ʾ modifier letter right half ring
|
| 131 |
-
"\u02BF": 227, # ʿ modifier letter left half ring
|
| 132 |
-
"\u02BB": 228, # ʻ modifier letter turned comma
|
| 133 |
-
"\u02C9": 229, # ˉ modifier letter macron (level tone)
|
| 134 |
-
"\u02CA": 230, # ˊ modifier letter acute accent (rising tone)
|
| 135 |
-
"\u02CB": 231, # ˋ modifier letter grave accent (falling tone)
|
| 136 |
-
"\u02C6": 232, # ˆ modifier letter circumflex accent
|
| 137 |
-
# --- Tone bar letters (233..237) ---
|
| 138 |
-
"\u02E5": 233, # ˥ extra-high tone bar
|
| 139 |
-
"\u02E6": 234, # ˦ high tone bar
|
| 140 |
-
"\u02E7": 235, # ˧ mid tone bar
|
| 141 |
-
"\u02E8": 236, # ˨ low tone bar
|
| 142 |
-
"\u02E9": 237, # ˩ extra-low tone bar
|
| 143 |
-
# --- Additional combining accent marks (238..243) ---
|
| 144 |
-
"\u0300": 238, # ̀ combining grave accent
|
| 145 |
-
"\u0301": 239, # ́ combining acute accent
|
| 146 |
-
"\u0302": 240, # ̂ combining circumflex accent
|
| 147 |
-
"\u0304": 241, # ̄ combining macron (mid tone)
|
| 148 |
-
"\u030C": 242, # ̌ combining caron
|
| 149 |
-
"\u0307": 243, # ̇ combining dot above
|
| 150 |
-
}
|
| 151 |
-
|
| 152 |
-
# ============================================================
|
| 153 |
-
# Region constants
|
| 154 |
-
# ============================================================
|
| 155 |
-
PIPER_REGION_END = 156 # last piper index
|
| 156 |
-
LANG_REGION_START = 244 # first language token index
|
| 157 |
-
LANG_REGION_SIZE = 140 # slots for 140 languages
|
| 158 |
-
VOCAB_SIZE = LANG_REGION_START + LANG_REGION_SIZE # 384
|
| 159 |
-
|
| 160 |
-
# Special token IDs
|
| 161 |
-
PAD_ID = 0 # "_"
|
| 162 |
-
BOS_ID = 1 # "^"
|
| 163 |
-
EOS_ID = 2 # "$"
|
| 164 |
-
|
| 165 |
-
# ============================================================
|
| 166 |
-
# Language tokens (indices 244..383)
|
| 167 |
-
# To add a language: add one line here, nothing else changes.
|
| 168 |
-
# ============================================================
|
| 169 |
-
LANG_ID: dict[str, int] = {
|
| 170 |
-
"he": LANG_REGION_START + 0, # 244 — Hebrew
|
| 171 |
-
"en": LANG_REGION_START + 1, # 245 — English
|
| 172 |
-
# --- add new languages below, in any order ---
|
| 173 |
-
"es": LANG_REGION_START + 2, # 246 — Spanish
|
| 174 |
-
# "fr": LANG_REGION_START + 3, # 247 — French
|
| 175 |
-
# "ar": LANG_REGION_START + 4, # 248 — Arabic
|
| 176 |
-
# "pt": LANG_REGION_START + 5, # 249 — Portuguese
|
| 177 |
-
# "ko": LANG_REGION_START + 6, # 250 — Korean
|
| 178 |
-
# "ja": LANG_REGION_START + 7, # 251 — Japanese
|
| 179 |
-
"de": LANG_REGION_START + 8, # 252 — German
|
| 180 |
-
"it": LANG_REGION_START + 9, # 253 — Italian
|
| 181 |
-
# "ru": LANG_REGION_START + 10, # 254 — Russian
|
| 182 |
-
# "zh": LANG_REGION_START + 11, # 255 — Chinese
|
| 183 |
-
# "hi": LANG_REGION_START + 12, # 256 — Hindi
|
| 184 |
-
# "tr": LANG_REGION_START + 13, # 257 — Turkish
|
| 185 |
-
# "xx": LANG_REGION_START + 139,# 383 — last slot
|
| 186 |
-
}
|
| 187 |
-
|
| 188 |
-
LANG_NAMES: dict[int, str] = {v: k for k, v in LANG_ID.items()}
|
| 189 |
-
|
| 190 |
-
# User-facing aliases (canonical token is the target key in LANG_ID).
|
| 191 |
-
LANG_CODE_ALIASES: dict[str, str] = {
|
| 192 |
-
"ge": "de", # German — README uses `ge`; vocab slot is `de`
|
| 193 |
-
}
|
| 194 |
-
|
| 195 |
-
# ============================================================
|
| 196 |
-
# Lookup tables
|
| 197 |
-
# ============================================================
|
| 198 |
-
CHAR_TO_ID: dict[str, int] = {**_PIPER_MAP, **_EXTENDED_MAP}
|
| 199 |
-
|
| 200 |
-
ID_TO_CHAR: dict[int, str] = {v: k for k, v in CHAR_TO_ID.items()}
|
| 201 |
-
for _lang_name, _lang_idx in LANG_ID.items():
|
| 202 |
-
ID_TO_CHAR[_lang_idx] = f"<{_lang_name}>"
|
| 203 |
-
|
| 204 |
-
# All characters that have a valid mapping (used for coverage reporting in dataset)
|
| 205 |
-
VOCAB_LIST: list[str] = list(CHAR_TO_ID.keys())
|
| 206 |
-
|
| 207 |
-
# ============================================================
|
| 208 |
-
# Safety assertions
|
| 209 |
-
# ============================================================
|
| 210 |
-
assert VOCAB_SIZE == 384
|
| 211 |
-
assert len(_PIPER_MAP) == 157, f"Piper map must have 157 entries, got {len(_PIPER_MAP)}"
|
| 212 |
-
assert max(_PIPER_MAP.values()) == PIPER_REGION_END, \
|
| 213 |
-
f"Piper max ID should be {PIPER_REGION_END}"
|
| 214 |
-
assert all(v < LANG_REGION_START for v in _PIPER_MAP.values()), \
|
| 215 |
-
"Piper IDs must not overlap language region"
|
| 216 |
-
assert all(PIPER_REGION_END < v < LANG_REGION_START for v in _EXTENDED_MAP.values()), \
|
| 217 |
-
"Extended IDs must be in range 157..243"
|
| 218 |
-
assert len(set(_EXTENDED_MAP.values())) == len(_EXTENDED_MAP), \
|
| 219 |
-
"Extended map has duplicate IDs"
|
| 220 |
-
assert not (set(_PIPER_MAP.values()) & set(_EXTENDED_MAP.values())), \
|
| 221 |
-
"Piper and extended maps share IDs"
|
| 222 |
-
|
| 223 |
-
|
| 224 |
-
# ============================================================
|
| 225 |
-
# Public API
|
| 226 |
-
# ============================================================
|
| 227 |
-
|
| 228 |
-
def text_to_indices(text: str, lang: str = "he") -> list[int]:
|
| 229 |
-
"""
|
| 230 |
-
Convert an IPA phoneme string to vocab indices with a language token prepended.
|
| 231 |
-
|
| 232 |
-
Args:
|
| 233 |
-
text: IPA string (output of a G2P / phonemizer tool)
|
| 234 |
-
lang: language code ("he", "en", "es", ...)
|
| 235 |
-
Returns:
|
| 236 |
-
list of ints — first element is the language token (244+),
|
| 237 |
-
followed by per-character IDs. Unknown chars map to PAD_ID (0).
|
| 238 |
-
Raises:
|
| 239 |
-
ValueError: if lang is not registered in LANG_ID
|
| 240 |
-
"""
|
| 241 |
-
lang = LANG_CODE_ALIASES.get(lang, lang)
|
| 242 |
-
if lang not in LANG_ID:
|
| 243 |
-
raise ValueError(
|
| 244 |
-
f"Unknown language '{lang}'. Available: {list(LANG_ID.keys())}. "
|
| 245 |
-
f"Add it to LANG_ID in _blue_vocab.py"
|
| 246 |
-
)
|
| 247 |
-
lang_token = LANG_ID[lang]
|
| 248 |
-
return [lang_token] + [CHAR_TO_ID.get(ch, PAD_ID) for ch in text]
|
| 249 |
-
|
| 250 |
-
|
| 251 |
-
def text_to_indices_multilang(text: str, base_lang: str = "he") -> list[int]:
|
| 252 |
-
"""
|
| 253 |
-
Convert an IPA string with inline language tags to vocab indices.
|
| 254 |
-
|
| 255 |
-
Supported markup (same as training / ``TextProcessor`` output):
|
| 256 |
-
|
| 257 |
-
- **Preferred:** explicit close — ``<lan>…</lan>`` e.g. ``<en>ˈhɛloʊ</en>``.
|
| 258 |
-
- **Legacy:** toggle close — ``<lan>…<lan>`` (same tag repeats).
|
| 259 |
-
|
| 260 |
-
Unknown tag names fall back to ``base_lang``. Alias ``ge`` → German (same as ``de``).
|
| 261 |
-
"""
|
| 262 |
-
base_lang = LANG_CODE_ALIASES.get(base_lang, base_lang)
|
| 263 |
-
if base_lang not in LANG_ID:
|
| 264 |
-
raise ValueError(
|
| 265 |
-
f"Unknown language '{base_lang}'. Available: {list(LANG_ID.keys())}."
|
| 266 |
-
)
|
| 267 |
-
|
| 268 |
-
# Fast path: no tags
|
| 269 |
-
if "<" not in text:
|
| 270 |
-
return text_to_indices(text, lang=base_lang)
|
| 271 |
-
|
| 272 |
-
# Parse segments: alternating base-lang and tagged sections
|
| 273 |
-
segments: list[tuple[str, str]] = [] # [(lang, ipa_text), ...]
|
| 274 |
-
last_end = 0
|
| 275 |
-
for m in re.finditer(r"<(\w+)>(.*?)(?:</\1>|<\1>)", text, flags=re.DOTALL):
|
| 276 |
-
if m.start() > last_end:
|
| 277 |
-
segments.append((base_lang, text[last_end:m.start()]))
|
| 278 |
-
tag_lang = LANG_CODE_ALIASES.get(m.group(1), m.group(1))
|
| 279 |
-
segments.append((tag_lang if tag_lang in LANG_ID else base_lang, m.group(2)))
|
| 280 |
-
last_end = m.end()
|
| 281 |
-
if last_end < len(text):
|
| 282 |
-
segments.append((base_lang, text[last_end:]))
|
| 283 |
-
|
| 284 |
-
# Build token sequence: start with base language token, insert switch tokens
|
| 285 |
-
ids: list[int] = [LANG_ID[base_lang]]
|
| 286 |
-
current_lang = base_lang
|
| 287 |
-
for lang, seg in segments:
|
| 288 |
-
if lang != current_lang:
|
| 289 |
-
ids.append(LANG_ID.get(lang, LANG_ID[base_lang]))
|
| 290 |
-
current_lang = lang
|
| 291 |
-
ids.extend(CHAR_TO_ID.get(ch, PAD_ID) for ch in seg)
|
| 292 |
-
return ids
|
| 293 |
-
|
| 294 |
-
|
| 295 |
-
def indices_to_text(indices: list[int]) -> str:
|
| 296 |
-
"""Convert indices back to a readable string (for debugging)."""
|
| 297 |
-
return "".join(ID_TO_CHAR.get(i, "?") for i in indices)
|
| 298 |
-
|
| 299 |
-
|
| 300 |
-
def normalize_text(text: str, lang: str = "he") -> str:
|
| 301 |
-
"""
|
| 302 |
-
Normalize text before tokenization.
|
| 303 |
-
Applies Unicode normalization and common phoneme substitutions.
|
| 304 |
-
|
| 305 |
-
Args:
|
| 306 |
-
text: IPA or raw-text string to normalize.
|
| 307 |
-
lang: language code — Hebrew-specific substitutions (r→ʁ, g→ɡ)
|
| 308 |
-
are only applied when lang == "he".
|
| 309 |
-
"""
|
| 310 |
-
text = text.strip()
|
| 311 |
-
text = uni_normalize("NFD", text)
|
| 312 |
-
|
| 313 |
-
# Universal replacements (fancy quotes/dashes → ASCII equivalents)
|
| 314 |
-
replacements = {
|
| 315 |
-
"\u201c": '"', "\u201d": '"',
|
| 316 |
-
"\u2018": "'", "\u2019": "'",
|
| 317 |
-
"´": "'", "`": "'",
|
| 318 |
-
"–": "-", "‑": "-", "—": "-",
|
| 319 |
-
}
|
| 320 |
-
for k, v in replacements.items():
|
| 321 |
-
text = text.replace(k, v)
|
| 322 |
-
|
| 323 |
-
# Hebrew phonemizer output normalization
|
| 324 |
-
# (phonikud sometimes emits ASCII r/g instead of IPA ʁ/ɡ)
|
| 325 |
-
if lang == "he":
|
| 326 |
-
text = text.replace("r", "ʁ")
|
| 327 |
-
text = text.replace("g", "ɡ")
|
| 328 |
-
|
| 329 |
-
text = re.sub(r"\s+", " ", text).strip()
|
| 330 |
-
return text
|
| 331 |
-
|
| 332 |
-
|
| 333 |
-
def check_coverage(text: str) -> dict:
|
| 334 |
-
"""Debug: report which chars in text are missing from vocab."""
|
| 335 |
-
known, unknown = [], []
|
| 336 |
-
for ch in text:
|
| 337 |
-
(known if ch in CHAR_TO_ID else unknown).append(ch)
|
| 338 |
-
return {
|
| 339 |
-
"total": len(text),
|
| 340 |
-
"known": len(known),
|
| 341 |
-
"unknown": len(unknown),
|
| 342 |
-
"missing_chars": sorted(set(unknown)),
|
| 343 |
-
"missing_codepoints": [f"U+{ord(c):04X}" for c in sorted(set(unknown))],
|
| 344 |
-
}
|
| 345 |
-
|
| 346 |
-
|
| 347 |
-
def get_supported_languages() -> list[str]:
|
| 348 |
-
return list(LANG_ID.keys())
|
| 349 |
-
|
| 350 |
-
|
| 351 |
-
# ============================================================
|
| 352 |
-
# Import diagnostics (opt-in: BLUE_TTS_DEBUG_VOCAB=1)
|
| 353 |
-
# ============================================================
|
| 354 |
-
if os.environ.get("BLUE_TTS_DEBUG_VOCAB", "").strip() in ("1", "true", "yes"):
|
| 355 |
-
print(
|
| 356 |
-
f"[Vocab] VOCAB_SIZE={VOCAB_SIZE} | "
|
| 357 |
-
f"piper={len(_PIPER_MAP)} (0..{PIPER_REGION_END}) | "
|
| 358 |
-
f"extended={len(_EXTENDED_MAP)} (157..{max(_EXTENDED_MAP.values())}) | "
|
| 359 |
-
f"lang_slots={LANG_REGION_SIZE} ({LANG_REGION_START}..{VOCAB_SIZE - 1}) | "
|
| 360 |
-
f"active_langs={list(LANG_ID.keys())}"
|
| 361 |
-
)
|
| 362 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
app.py
CHANGED
|
@@ -141,9 +141,13 @@ class TextProcessor:
|
|
| 141 |
|
| 142 |
def __init__(self, renikud_path: Optional[str] = None):
|
| 143 |
self.renikud = None
|
|
|
|
|
|
|
|
|
|
|
|
|
| 144 |
if renikud_path is None and os.path.exists("model.onnx"):
|
| 145 |
renikud_path = "model.onnx"
|
| 146 |
-
|
| 147 |
self._renikud_path = renikud_path
|
| 148 |
if renikud_path and os.path.exists(renikud_path):
|
| 149 |
try:
|
|
@@ -155,6 +159,36 @@ class TextProcessor:
|
|
| 155 |
"Hebrew G2P needs the `renikud-onnx` package. Install project deps: uv sync"
|
| 156 |
) from e
|
| 157 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 158 |
def _hebrew_requires_renikud_error(self) -> ValueError:
|
| 159 |
return ValueError(
|
| 160 |
"Hebrew text requires the Renikud ONNX weights (not bundled with the wheel). "
|
|
@@ -167,19 +201,15 @@ class TextProcessor:
|
|
| 167 |
espeak_lang = self._ESPEAK_MAP.get(lang)
|
| 168 |
if espeak_lang is None:
|
| 169 |
return text
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 170 |
try:
|
| 171 |
-
|
| 172 |
-
from phonemizer.backend import EspeakBackend
|
| 173 |
-
from phonemizer.backend.espeak.wrapper import EspeakWrapper
|
| 174 |
-
from phonemizer.separator import Separator
|
| 175 |
-
EspeakWrapper.set_library(espeakng_loader.get_library_path())
|
| 176 |
-
EspeakWrapper.set_data_path(espeakng_loader.get_data_path())
|
| 177 |
-
backend = EspeakBackend(
|
| 178 |
-
espeak_lang, preserve_punctuation=True,
|
| 179 |
-
with_stress=True, language_switch="remove-flags",
|
| 180 |
-
)
|
| 181 |
raw = backend.phonemize(
|
| 182 |
-
[text], separator=
|
| 183 |
)[0]
|
| 184 |
return normalize_text(raw, lang=lang)
|
| 185 |
except Exception as e:
|
|
|
|
| 141 |
|
| 142 |
def __init__(self, renikud_path: Optional[str] = None):
|
| 143 |
self.renikud = None
|
| 144 |
+
self._espeak_backends: Dict[str, Any] = {}
|
| 145 |
+
self._espeak_separator: Any = None
|
| 146 |
+
self._espeak_ready = False
|
| 147 |
+
|
| 148 |
if renikud_path is None and os.path.exists("model.onnx"):
|
| 149 |
renikud_path = "model.onnx"
|
| 150 |
+
|
| 151 |
self._renikud_path = renikud_path
|
| 152 |
if renikud_path and os.path.exists(renikud_path):
|
| 153 |
try:
|
|
|
|
| 159 |
"Hebrew G2P needs the `renikud-onnx` package. Install project deps: uv sync"
|
| 160 |
) from e
|
| 161 |
|
| 162 |
+
self._init_espeak()
|
| 163 |
+
|
| 164 |
+
def _init_espeak(self):
|
| 165 |
+
"""Set up the espeak-ng library path once at startup (cross-platform via espeakng-loader)."""
|
| 166 |
+
if self._espeak_ready:
|
| 167 |
+
return
|
| 168 |
+
try:
|
| 169 |
+
import espeakng_loader
|
| 170 |
+
from phonemizer.backend.espeak.wrapper import EspeakWrapper
|
| 171 |
+
from phonemizer.separator import Separator
|
| 172 |
+
EspeakWrapper.set_library(espeakng_loader.get_library_path())
|
| 173 |
+
EspeakWrapper.set_data_path(espeakng_loader.get_data_path())
|
| 174 |
+
self._espeak_separator = Separator(phone="", word=" ", syllable="")
|
| 175 |
+
self._espeak_ready = True
|
| 176 |
+
print("[INFO] espeak-ng initialised via espeakng-loader")
|
| 177 |
+
except Exception as e:
|
| 178 |
+
print(f"[WARN] espeak-ng setup failed: {e}")
|
| 179 |
+
|
| 180 |
+
def _get_espeak_backend(self, espeak_lang: str) -> Any:
|
| 181 |
+
"""Return a cached EspeakBackend for *espeak_lang*, creating it on first use."""
|
| 182 |
+
if espeak_lang not in self._espeak_backends:
|
| 183 |
+
from phonemizer.backend import EspeakBackend
|
| 184 |
+
print(f"[INFO] Loading espeak backend for '{espeak_lang}'…")
|
| 185 |
+
self._espeak_backends[espeak_lang] = EspeakBackend(
|
| 186 |
+
espeak_lang, preserve_punctuation=True,
|
| 187 |
+
with_stress=True, language_switch="remove-flags",
|
| 188 |
+
)
|
| 189 |
+
print(f"[INFO] espeak backend for '{espeak_lang}' ready")
|
| 190 |
+
return self._espeak_backends[espeak_lang]
|
| 191 |
+
|
| 192 |
def _hebrew_requires_renikud_error(self) -> ValueError:
|
| 193 |
return ValueError(
|
| 194 |
"Hebrew text requires the Renikud ONNX weights (not bundled with the wheel). "
|
|
|
|
| 201 |
espeak_lang = self._ESPEAK_MAP.get(lang)
|
| 202 |
if espeak_lang is None:
|
| 203 |
return text
|
| 204 |
+
if not self._espeak_ready:
|
| 205 |
+
self._init_espeak()
|
| 206 |
+
if not self._espeak_ready:
|
| 207 |
+
print(f"[WARN] espeak-ng not available, returning raw text for lang={lang}")
|
| 208 |
+
return text
|
| 209 |
try:
|
| 210 |
+
backend = self._get_espeak_backend(espeak_lang)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 211 |
raw = backend.phonemize(
|
| 212 |
+
[text], separator=self._espeak_separator
|
| 213 |
)[0]
|
| 214 |
return normalize_text(raw, lang=lang)
|
| 215 |
except Exception as e:
|
blue_tts.py
DELETED
|
@@ -1,467 +0,0 @@
|
|
| 1 |
-
import os
|
| 2 |
-
import json
|
| 3 |
-
import sys
|
| 4 |
-
import re
|
| 5 |
-
from typing import List, Optional, Tuple
|
| 6 |
-
|
| 7 |
-
import numpy as np
|
| 8 |
-
import onnxruntime as ort
|
| 9 |
-
|
| 10 |
-
_src = os.path.dirname(os.path.abspath(__file__))
|
| 11 |
-
if _src not in sys.path:
|
| 12 |
-
sys.path.insert(0, _src)
|
| 13 |
-
|
| 14 |
-
from _blue_vocab import text_to_indices, text_to_indices_multilang
|
| 15 |
-
from _common import Style, TextProcessor, chunk_text # noqa: E402
|
| 16 |
-
|
| 17 |
-
|
| 18 |
-
class BlueTTS:
|
| 19 |
-
def __init__(
|
| 20 |
-
self,
|
| 21 |
-
onnx_dir: str,
|
| 22 |
-
config_path: str = "tts.json",
|
| 23 |
-
style_json: Optional[str] = None,
|
| 24 |
-
steps: int = 32,
|
| 25 |
-
cfg_scale: float = 3.0,
|
| 26 |
-
speed: float = 1.0,
|
| 27 |
-
seed: int = 42,
|
| 28 |
-
use_gpu: bool = False,
|
| 29 |
-
chunk_len: int = 150,
|
| 30 |
-
silence_sec: float = 0.15,
|
| 31 |
-
fade_duration: float = 0.02,
|
| 32 |
-
renikud_path: Optional[str] = None,
|
| 33 |
-
):
|
| 34 |
-
self.onnx_dir = onnx_dir
|
| 35 |
-
self.style_json = style_json
|
| 36 |
-
self.steps = steps
|
| 37 |
-
self.cfg_scale = cfg_scale
|
| 38 |
-
self.speed = speed
|
| 39 |
-
self.seed = seed
|
| 40 |
-
self.chunk_len = chunk_len
|
| 41 |
-
self.silence_sec = silence_sec
|
| 42 |
-
self.fade_duration = fade_duration
|
| 43 |
-
|
| 44 |
-
if renikud_path is None:
|
| 45 |
-
if os.path.exists("model.onnx"):
|
| 46 |
-
renikud_path = "model.onnx"
|
| 47 |
-
elif os.path.exists(os.path.join(onnx_dir, "model.onnx")):
|
| 48 |
-
renikud_path = os.path.join(onnx_dir, "model.onnx")
|
| 49 |
-
|
| 50 |
-
self._load_config(config_path)
|
| 51 |
-
self._init_sessions(use_gpu)
|
| 52 |
-
self._load_stats()
|
| 53 |
-
self._load_uncond()
|
| 54 |
-
self._load_shuffle_keys()
|
| 55 |
-
self._text_proc = TextProcessor(renikud_path)
|
| 56 |
-
|
| 57 |
-
# ------------------------------------------------------------------
|
| 58 |
-
# Setup
|
| 59 |
-
# ------------------------------------------------------------------
|
| 60 |
-
|
| 61 |
-
def _load_config(self, config_path: str):
|
| 62 |
-
self.normalizer_scale = 1.0
|
| 63 |
-
self.latent_dim = 24
|
| 64 |
-
self.chunk_compress_factor = 6
|
| 65 |
-
self.hop_length = 512
|
| 66 |
-
self.sample_rate = 44100
|
| 67 |
-
|
| 68 |
-
if config_path and os.path.exists(config_path):
|
| 69 |
-
with open(config_path) as f:
|
| 70 |
-
cfg = json.load(f)
|
| 71 |
-
self.normalizer_scale = float(cfg.get("ttl", {}).get("normalizer", {}).get("scale", self.normalizer_scale))
|
| 72 |
-
self.latent_dim = int(cfg.get("ttl", {}).get("latent_dim", self.latent_dim))
|
| 73 |
-
self.chunk_compress_factor = int(cfg.get("ttl", {}).get("chunk_compress_factor", self.chunk_compress_factor))
|
| 74 |
-
self.sample_rate = int(cfg.get("ae", {}).get("sample_rate", self.sample_rate))
|
| 75 |
-
self.hop_length = int(cfg.get("ae", {}).get("encoder", {}).get("spec_processor", {}).get("hop_length", self.hop_length))
|
| 76 |
-
|
| 77 |
-
self.compressed_channels = self.latent_dim * self.chunk_compress_factor
|
| 78 |
-
|
| 79 |
-
def _init_sessions(self, use_gpu: bool):
|
| 80 |
-
available = ort.get_available_providers()
|
| 81 |
-
if use_gpu:
|
| 82 |
-
providers = [p for p in ["CUDAExecutionProvider", "OpenVINOExecutionProvider", "CPUExecutionProvider"] if p in available]
|
| 83 |
-
else:
|
| 84 |
-
providers = [p for p in ["OpenVINOExecutionProvider", "CPUExecutionProvider"] if p in available]
|
| 85 |
-
|
| 86 |
-
opts = ort.SessionOptions()
|
| 87 |
-
opts.log_severity_level = 3
|
| 88 |
-
opts.graph_optimization_level = ort.GraphOptimizationLevel.ORT_ENABLE_ALL
|
| 89 |
-
cpu_cores = max(1, (os.cpu_count() or 4) // 4)
|
| 90 |
-
opts.intra_op_num_threads = int(os.environ.get("ORT_INTRA", cpu_cores))
|
| 91 |
-
opts.inter_op_num_threads = int(os.environ.get("ORT_INTER", 1))
|
| 92 |
-
|
| 93 |
-
self._opts = opts
|
| 94 |
-
self._providers = providers
|
| 95 |
-
|
| 96 |
-
self._text_enc = self._load_session("text_encoder.onnx")
|
| 97 |
-
self._ref_enc = self._load_session("reference_encoder.onnx", required=False)
|
| 98 |
-
|
| 99 |
-
vf_name = "backbone_keys.onnx" if os.path.exists(os.path.join(self.onnx_dir, "backbone_keys.onnx")) else "backbone.onnx"
|
| 100 |
-
if not os.path.exists(os.path.join(self.onnx_dir, vf_name)):
|
| 101 |
-
vf_name = "vector_estimator.onnx"
|
| 102 |
-
self._vf_model_name = vf_name.replace(".onnx", "")
|
| 103 |
-
self._vf = self._load_session(vf_name)
|
| 104 |
-
self._vocoder = self._load_session("vocoder.onnx")
|
| 105 |
-
dp_name = "duration_predictor.onnx" if os.path.exists(os.path.join(self.onnx_dir, "duration_predictor.onnx")) else "length_pred.onnx"
|
| 106 |
-
self._dp = self._load_session(dp_name, required=False)
|
| 107 |
-
self._dp_style = self._load_session("length_pred_style.onnx", required=False)
|
| 108 |
-
|
| 109 |
-
vf_inputs = {i.name for i in self._vf.get_inputs()}
|
| 110 |
-
self._vf_inputs = vf_inputs
|
| 111 |
-
self._vf_supports_style_keys = "style_keys" in vf_inputs
|
| 112 |
-
self._vf_uses_text_emb = "text_emb" in vf_inputs and "text_context" not in vf_inputs
|
| 113 |
-
|
| 114 |
-
def _load_session(self, name: str, required: bool = True) -> Optional[ort.InferenceSession]:
|
| 115 |
-
base = os.path.join(self.onnx_dir, name)
|
| 116 |
-
slim = base.replace(".onnx", ".slim.onnx")
|
| 117 |
-
path = slim if os.path.exists(slim) else base
|
| 118 |
-
if not os.path.exists(path):
|
| 119 |
-
if required:
|
| 120 |
-
raise FileNotFoundError(f"Model not found: {base}")
|
| 121 |
-
return None
|
| 122 |
-
return ort.InferenceSession(path, sess_options=self._opts, providers=self._providers)
|
| 123 |
-
|
| 124 |
-
def _load_stats(self):
|
| 125 |
-
stats_path = os.path.join(self.onnx_dir, "stats.npz")
|
| 126 |
-
self.mean = self.std = None
|
| 127 |
-
if os.path.exists(stats_path):
|
| 128 |
-
stats = np.load(stats_path)
|
| 129 |
-
self.mean = stats["mean"].astype(np.float32)
|
| 130 |
-
self.std = stats["std"].astype(np.float32)
|
| 131 |
-
if self.mean.ndim == 1:
|
| 132 |
-
self.mean = self.mean.reshape(1, -1, 1)
|
| 133 |
-
self.std = self.std.reshape(1, -1, 1)
|
| 134 |
-
if self.mean.ndim == 3:
|
| 135 |
-
self.compressed_channels = int(self.mean.shape[1])
|
| 136 |
-
if "normalizer_scale" in stats.files:
|
| 137 |
-
self.normalizer_scale = float(stats["normalizer_scale"].item() if stats["normalizer_scale"].ndim == 0 else stats["normalizer_scale"][0])
|
| 138 |
-
|
| 139 |
-
def _load_uncond(self):
|
| 140 |
-
uncond_path = os.path.join(self.onnx_dir, "uncond.npz")
|
| 141 |
-
self._u_text = self._u_ref = self._u_keys = self._cond_keys = None
|
| 142 |
-
if os.path.exists(uncond_path):
|
| 143 |
-
u = np.load(uncond_path)
|
| 144 |
-
self._u_text = u["u_text"]
|
| 145 |
-
self._u_ref = u["u_ref"]
|
| 146 |
-
self._u_keys = u.get("u_keys") if "u_keys" in u.files else None
|
| 147 |
-
self._cond_keys = u.get("cond_keys") if "cond_keys" in u.files else None
|
| 148 |
-
|
| 149 |
-
def _load_shuffle_keys(self):
|
| 150 |
-
self._model_keys: dict = {}
|
| 151 |
-
keys_path = os.path.join(self.onnx_dir, "keys.npz")
|
| 152 |
-
if not os.path.exists(keys_path):
|
| 153 |
-
return
|
| 154 |
-
data = np.load(keys_path)
|
| 155 |
-
for k in data.files:
|
| 156 |
-
parts = k.split("/", 1)
|
| 157 |
-
if len(parts) == 2:
|
| 158 |
-
model, inp = parts
|
| 159 |
-
self._model_keys.setdefault(model, {})[inp] = data[k]
|
| 160 |
-
|
| 161 |
-
# ------------------------------------------------------------------
|
| 162 |
-
# Public API
|
| 163 |
-
# ------------------------------------------------------------------
|
| 164 |
-
|
| 165 |
-
def create(self, phonemes: str, lang: str = "he") -> Tuple[np.ndarray, int]:
|
| 166 |
-
"""Synthesize speech from a pre-phonemized (IPA) string.
|
| 167 |
-
|
| 168 |
-
Returns:
|
| 169 |
-
(samples, sample_rate) — float32 numpy array and int sample rate.
|
| 170 |
-
"""
|
| 171 |
-
chunks = chunk_text(phonemes, self.chunk_len)
|
| 172 |
-
silence = np.zeros(int(self.silence_sec * self.sample_rate), dtype=np.float32)
|
| 173 |
-
parts = []
|
| 174 |
-
for i, chunk in enumerate(chunks):
|
| 175 |
-
parts.append(self._infer_chunk(chunk, lang=lang))
|
| 176 |
-
if i < len(chunks) - 1:
|
| 177 |
-
parts.append(silence)
|
| 178 |
-
wav = np.concatenate(parts) if parts else np.array([], dtype=np.float32)
|
| 179 |
-
return wav, self.sample_rate
|
| 180 |
-
|
| 181 |
-
def synthesize(self, text: str, lang: str = "he") -> Tuple[np.ndarray, int]:
|
| 182 |
-
"""Phonemize raw text (phonikud for Hebrew, espeak for others) then synthesize.
|
| 183 |
-
|
| 184 |
-
Returns:
|
| 185 |
-
(samples, sample_rate) — float32 numpy array and int sample rate.
|
| 186 |
-
"""
|
| 187 |
-
phonemes = self._text_proc.phonemize(text, lang=lang)
|
| 188 |
-
return self.create(phonemes, lang=lang)
|
| 189 |
-
|
| 190 |
-
# ------------------------------------------------------------------
|
| 191 |
-
# Internals
|
| 192 |
-
# ------------------------------------------------------------------
|
| 193 |
-
|
| 194 |
-
def _run(self, sess: ort.InferenceSession, feed: dict, model_name: str):
|
| 195 |
-
keys = self._model_keys.get(model_name)
|
| 196 |
-
if keys:
|
| 197 |
-
feed = {**feed, **keys}
|
| 198 |
-
return sess.run(None, feed)
|
| 199 |
-
|
| 200 |
-
def _load_style_json(self, path: str):
|
| 201 |
-
with open(path) as f:
|
| 202 |
-
j = json.load(f)
|
| 203 |
-
|
| 204 |
-
def _arr(key):
|
| 205 |
-
if key not in j:
|
| 206 |
-
return None
|
| 207 |
-
a = np.array(j[key]["data"], dtype=np.float32)
|
| 208 |
-
return a[None] if a.ndim == 2 else a
|
| 209 |
-
|
| 210 |
-
style_ttl = _arr("style_ttl")
|
| 211 |
-
style_keys = _arr("style_keys")
|
| 212 |
-
style_dp = _arr("style_dp")
|
| 213 |
-
z_ref = _arr("z_ref")
|
| 214 |
-
return style_ttl, style_keys, style_dp, z_ref
|
| 215 |
-
|
| 216 |
-
def _extract_style(self, z_ref_norm: np.ndarray):
|
| 217 |
-
if self._ref_enc is None:
|
| 218 |
-
raise ValueError("Reference encoder not loaded.")
|
| 219 |
-
TARGET = 256
|
| 220 |
-
B, C, T = z_ref_norm.shape
|
| 221 |
-
if T < TARGET:
|
| 222 |
-
pad = TARGET - T
|
| 223 |
-
z = np.pad(z_ref_norm, ((0, 0), (0, 0), (0, pad)))
|
| 224 |
-
mask = np.zeros((B, 1, TARGET), dtype=np.float32)
|
| 225 |
-
mask[:, :, :T] = 1.0
|
| 226 |
-
else:
|
| 227 |
-
z = z_ref_norm[:, :, :TARGET]
|
| 228 |
-
mask = np.ones((B, 1, TARGET), dtype=np.float32)
|
| 229 |
-
|
| 230 |
-
ref_names = [i.name for i in self._ref_enc.get_inputs()]
|
| 231 |
-
feed = {"z_ref": z}
|
| 232 |
-
if "mask" in ref_names:
|
| 233 |
-
feed["mask"] = mask
|
| 234 |
-
elif "ref_mask" in ref_names:
|
| 235 |
-
feed["ref_mask"] = mask
|
| 236 |
-
elif len(ref_names) >= 2:
|
| 237 |
-
feed[ref_names[1]] = mask
|
| 238 |
-
|
| 239 |
-
ref_values, ref_keys = self._run(self._ref_enc, feed, "reference_encoder")[:2]
|
| 240 |
-
return ref_values, ref_keys
|
| 241 |
-
|
| 242 |
-
def _infer_chunk(self, phonemes: str, lang: str = "he") -> np.ndarray:
|
| 243 |
-
if self.mean is None or self.std is None:
|
| 244 |
-
raise ValueError("stats.npz not loaded.")
|
| 245 |
-
|
| 246 |
-
style_ttl = style_keys = style_dp = z_ref = None
|
| 247 |
-
if self.style_json:
|
| 248 |
-
style_ttl, style_keys, style_dp, z_ref = self._load_style_json(self.style_json)
|
| 249 |
-
|
| 250 |
-
if z_ref is None and style_ttl is None:
|
| 251 |
-
raise ValueError("Provide style_json with z_ref or style_ttl content.")
|
| 252 |
-
|
| 253 |
-
# Text encoding
|
| 254 |
-
text_plain = re.sub(r"</?[a-z]{2,8}>", "", phonemes)
|
| 255 |
-
indices_dp = text_to_indices(text_plain, lang=lang)
|
| 256 |
-
ids_dp = np.array([indices_dp], dtype=np.int64)
|
| 257 |
-
mask_dp = np.ones((1, 1, len(indices_dp)), dtype=np.float32)
|
| 258 |
-
|
| 259 |
-
indices_full = text_to_indices_multilang(phonemes, base_lang=lang)
|
| 260 |
-
text_ids = np.array([indices_full], dtype=np.int64)
|
| 261 |
-
text_mask = np.ones((1, 1, len(indices_full)), dtype=np.float32)
|
| 262 |
-
|
| 263 |
-
# Style
|
| 264 |
-
z_ref_norm = None
|
| 265 |
-
if z_ref is not None:
|
| 266 |
-
z_ref_norm = ((z_ref - self.mean) / self.std) * float(self.normalizer_scale)
|
| 267 |
-
T = z_ref_norm.shape[2]
|
| 268 |
-
tail = max(2, int(T * 0.05))
|
| 269 |
-
z_ref_norm = z_ref_norm[:, :, : max(1, T - tail)]
|
| 270 |
-
if z_ref_norm.shape[2] > 150:
|
| 271 |
-
z_ref_norm = z_ref_norm[:, :, :150]
|
| 272 |
-
|
| 273 |
-
if style_ttl is not None:
|
| 274 |
-
ref_values = style_ttl
|
| 275 |
-
else:
|
| 276 |
-
ref_values, style_keys = self._extract_style(z_ref_norm)
|
| 277 |
-
|
| 278 |
-
if ref_values.ndim == 2:
|
| 279 |
-
ref_values = ref_values[None]
|
| 280 |
-
if style_keys is not None and style_keys.ndim == 2:
|
| 281 |
-
style_keys = style_keys[None]
|
| 282 |
-
|
| 283 |
-
ref_keys = style_keys if style_keys is not None else ref_values
|
| 284 |
-
|
| 285 |
-
# Text encoder
|
| 286 |
-
te_names = {i.name for i in self._text_enc.get_inputs()}
|
| 287 |
-
te_feed = {"text_ids": text_ids}
|
| 288 |
-
if "text_mask" in te_names:
|
| 289 |
-
te_feed["text_mask"] = text_mask
|
| 290 |
-
if "style_ttl" in te_names:
|
| 291 |
-
te_feed["style_ttl"] = ref_values
|
| 292 |
-
elif "ref_values" in te_names:
|
| 293 |
-
te_feed["ref_values"] = ref_values
|
| 294 |
-
else:
|
| 295 |
-
raise ValueError("Unknown text encoder input names.")
|
| 296 |
-
if "ref_keys" in te_names:
|
| 297 |
-
te_feed["ref_keys"] = ref_keys
|
| 298 |
-
elif "used_ref_keys" in te_names:
|
| 299 |
-
te_feed["used_ref_keys"] = ref_keys
|
| 300 |
-
|
| 301 |
-
text_emb = self._run(self._text_enc, te_feed, "text_encoder")[0]
|
| 302 |
-
|
| 303 |
-
# Duration
|
| 304 |
-
T_lat = self._predict_duration(ids_dp, mask_dp, z_ref_norm, style_dp)
|
| 305 |
-
|
| 306 |
-
# Flow matching
|
| 307 |
-
x = self._flow_matching(text_emb, ref_values, text_mask, T_lat)
|
| 308 |
-
|
| 309 |
-
# Decode
|
| 310 |
-
return self._decode(x)
|
| 311 |
-
|
| 312 |
-
def _predict_duration(self, text_ids, text_mask, z_ref_norm, style_dp) -> int:
|
| 313 |
-
T_lat = None
|
| 314 |
-
|
| 315 |
-
if style_dp is not None and self._dp_style is not None:
|
| 316 |
-
out = self._run(self._dp_style, {"text_ids": text_ids, "style_dp": style_dp, "text_mask": text_mask}, "length_pred_style")
|
| 317 |
-
val = float(np.squeeze(out[0]))
|
| 318 |
-
if np.isfinite(val):
|
| 319 |
-
T_lat = int(np.round(val / max(self.speed, 1e-6)))
|
| 320 |
-
|
| 321 |
-
if T_lat is None and z_ref_norm is not None and self._dp is not None:
|
| 322 |
-
ref_len = int(z_ref_norm.shape[2])
|
| 323 |
-
out = self._run(self._dp, {
|
| 324 |
-
"text_ids": text_ids,
|
| 325 |
-
"z_ref": z_ref_norm.astype(np.float32),
|
| 326 |
-
"text_mask": text_mask,
|
| 327 |
-
"ref_mask": np.ones((1, 1, ref_len), dtype=np.float32),
|
| 328 |
-
}, "length_pred")
|
| 329 |
-
val = float(np.squeeze(out[0]))
|
| 330 |
-
if np.isfinite(val):
|
| 331 |
-
T_lat = int(np.round(val / max(self.speed, 1e-6)))
|
| 332 |
-
|
| 333 |
-
if T_lat is None:
|
| 334 |
-
T_lat = int(text_ids.shape[1] * 1.3)
|
| 335 |
-
|
| 336 |
-
txt_len = int(np.sum(text_mask))
|
| 337 |
-
T_cap = max(20, min(txt_len * 3 + 20, 600))
|
| 338 |
-
T_lat = min(max(int(T_lat), 1), T_cap, 800)
|
| 339 |
-
return max(10, T_lat)
|
| 340 |
-
|
| 341 |
-
def _flow_matching(self, text_emb, ref_values, text_mask, T_lat) -> np.ndarray:
|
| 342 |
-
rng = np.random.RandomState(self.seed)
|
| 343 |
-
x = rng.randn(1, self.compressed_channels, T_lat).astype(np.float32)
|
| 344 |
-
latent_mask = np.ones((1, 1, T_lat), dtype=np.float32)
|
| 345 |
-
|
| 346 |
-
vf_inputs = self._vf_inputs
|
| 347 |
-
cond_keys = None
|
| 348 |
-
if self._vf_supports_style_keys and self._cond_keys is not None:
|
| 349 |
-
cond_keys = self._cond_keys.astype(np.float32)
|
| 350 |
-
if cond_keys.ndim == 2:
|
| 351 |
-
cond_keys = cond_keys[None]
|
| 352 |
-
|
| 353 |
-
u_text = self._u_text.astype(np.float32) if self._u_text is not None else None
|
| 354 |
-
u_ref = self._u_ref.astype(np.float32) if self._u_ref is not None else None
|
| 355 |
-
u_keys = self._u_keys.astype(np.float32) if self._u_keys is not None else None
|
| 356 |
-
u_text_mask = np.ones((1, 1, 1), dtype=np.float32)
|
| 357 |
-
|
| 358 |
-
for i in range(self.steps):
|
| 359 |
-
t_val = np.array([float(i)], dtype=np.float32)
|
| 360 |
-
total_t = np.array([float(self.steps)], dtype=np.float32)
|
| 361 |
-
|
| 362 |
-
feed: dict = {}
|
| 363 |
-
if "noisy_latent" in vf_inputs:
|
| 364 |
-
feed["noisy_latent"] = x
|
| 365 |
-
if "text_emb" in vf_inputs:
|
| 366 |
-
feed["text_emb"] = text_emb
|
| 367 |
-
elif "text_context" in vf_inputs:
|
| 368 |
-
feed["text_context"] = text_emb
|
| 369 |
-
if "style_ttl" in vf_inputs:
|
| 370 |
-
feed["style_ttl"] = ref_values
|
| 371 |
-
elif "ref_values" in vf_inputs:
|
| 372 |
-
feed["ref_values"] = ref_values
|
| 373 |
-
if "latent_mask" in vf_inputs:
|
| 374 |
-
feed["latent_mask"] = latent_mask
|
| 375 |
-
if "text_mask" in vf_inputs:
|
| 376 |
-
feed["text_mask"] = text_mask
|
| 377 |
-
if "current_step" in vf_inputs:
|
| 378 |
-
feed["current_step"] = t_val
|
| 379 |
-
if "total_step" in vf_inputs:
|
| 380 |
-
feed["total_step"] = total_t
|
| 381 |
-
if "style_keys" in vf_inputs and cond_keys is not None:
|
| 382 |
-
feed["style_keys"] = cond_keys
|
| 383 |
-
if "style_mask" in vf_inputs:
|
| 384 |
-
feed["style_mask"] = np.ones((1, 1, ref_values.shape[1]), dtype=np.float32)
|
| 385 |
-
|
| 386 |
-
den_cond = self._run(self._vf, feed, self._vf_model_name)[0]
|
| 387 |
-
|
| 388 |
-
if self.cfg_scale != 1.0 and u_text is not None:
|
| 389 |
-
feed_u = dict(feed)
|
| 390 |
-
if "text_emb" in vf_inputs:
|
| 391 |
-
feed_u["text_emb"] = u_text
|
| 392 |
-
elif "text_context" in vf_inputs:
|
| 393 |
-
feed_u["text_context"] = u_text
|
| 394 |
-
if "style_ttl" in vf_inputs:
|
| 395 |
-
feed_u["style_ttl"] = u_ref
|
| 396 |
-
elif "ref_values" in vf_inputs:
|
| 397 |
-
feed_u["ref_values"] = u_ref
|
| 398 |
-
if "text_mask" in vf_inputs:
|
| 399 |
-
feed_u["text_mask"] = u_text_mask
|
| 400 |
-
if "style_keys" in vf_inputs:
|
| 401 |
-
feed_u["style_keys"] = u_keys
|
| 402 |
-
if "style_mask" in vf_inputs:
|
| 403 |
-
feed_u["style_mask"] = np.ones((1, 1, u_ref.shape[1]), dtype=np.float32)
|
| 404 |
-
|
| 405 |
-
den_uncond = self._run(self._vf, feed_u, self._vf_model_name)[0]
|
| 406 |
-
x = den_uncond + self.cfg_scale * (den_cond - den_uncond)
|
| 407 |
-
else:
|
| 408 |
-
x = den_cond
|
| 409 |
-
|
| 410 |
-
return x
|
| 411 |
-
|
| 412 |
-
def _apply_fade(self, wav: np.ndarray) -> np.ndarray:
|
| 413 |
-
fade_samples = int(self.fade_duration * self.sample_rate)
|
| 414 |
-
if fade_samples == 0 or len(wav) < 2 * fade_samples:
|
| 415 |
-
return wav
|
| 416 |
-
wav = wav.copy()
|
| 417 |
-
wav[:fade_samples] *= np.linspace(0.0, 1.0, fade_samples, dtype=np.float32)
|
| 418 |
-
wav[-fade_samples:] *= np.linspace(1.0, 0.0, fade_samples, dtype=np.float32)
|
| 419 |
-
return wav
|
| 420 |
-
|
| 421 |
-
def _decode(self, z_pred: np.ndarray) -> np.ndarray:
|
| 422 |
-
if float(self.normalizer_scale) not in (0.0, 1.0):
|
| 423 |
-
z_unnorm = (z_pred / float(self.normalizer_scale)) * self.std + self.mean
|
| 424 |
-
else:
|
| 425 |
-
z_unnorm = z_pred * self.std + self.mean
|
| 426 |
-
|
| 427 |
-
B, C, T = z_unnorm.shape
|
| 428 |
-
z_dec = (
|
| 429 |
-
z_unnorm.reshape(B, self.latent_dim, self.chunk_compress_factor, T)
|
| 430 |
-
.transpose(0, 1, 3, 2)
|
| 431 |
-
.reshape(B, self.latent_dim, T * self.chunk_compress_factor)
|
| 432 |
-
)
|
| 433 |
-
|
| 434 |
-
wav = self._run(self._vocoder, {"latent": z_dec}, "vocoder")[0]
|
| 435 |
-
|
| 436 |
-
frame_len = int(self.hop_length * self.chunk_compress_factor)
|
| 437 |
-
if wav.shape[-1] > 2 * frame_len:
|
| 438 |
-
wav = wav[..., frame_len:-frame_len]
|
| 439 |
-
|
| 440 |
-
wav = wav.squeeze()
|
| 441 |
-
return self._apply_fade(wav)
|
| 442 |
-
|
| 443 |
-
|
| 444 |
-
# ─── Module-level loaders ─────────────────────────────────────────────────────
|
| 445 |
-
|
| 446 |
-
def load_voice_style(style_paths: List[str]) -> Style:
|
| 447 |
-
"""Load pre-extracted style vectors from one or more style JSON files."""
|
| 448 |
-
B = len(style_paths)
|
| 449 |
-
with open(style_paths[0]) as f:
|
| 450 |
-
first = json.load(f)
|
| 451 |
-
|
| 452 |
-
ttl_dims = first["style_ttl"]["dims"]
|
| 453 |
-
ttl = np.zeros([B, ttl_dims[1], ttl_dims[2]], dtype=np.float32)
|
| 454 |
-
|
| 455 |
-
dp: Optional[np.ndarray] = None
|
| 456 |
-
if "style_dp" in first:
|
| 457 |
-
dp_dims = first["style_dp"]["dims"]
|
| 458 |
-
dp = np.zeros([B, dp_dims[1], dp_dims[2]], dtype=np.float32)
|
| 459 |
-
|
| 460 |
-
for i, path in enumerate(style_paths):
|
| 461 |
-
with open(path) as f:
|
| 462 |
-
d = json.load(f)
|
| 463 |
-
ttl[i] = np.array(d["style_ttl"]["data"], dtype=np.float32).reshape(ttl_dims[1], ttl_dims[2])
|
| 464 |
-
if dp is not None and "style_dp" in d:
|
| 465 |
-
dp[i] = np.array(d["style_dp"]["data"], dtype=np.float32).reshape(dp_dims[1], dp_dims[2])
|
| 466 |
-
|
| 467 |
-
return Style(ttl=ttl, dp=dp)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
fonts/base64_font.txt
DELETED
|
@@ -1 +0,0 @@
|
|
| 1 |
-
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
|
|
|
|
|
|
voices/male1.json
DELETED
|
@@ -1,3 +0,0 @@
|
|
| 1 |
-
version https://git-lfs.github.com/spec/v1
|
| 2 |
-
oid sha256:27ab2c960deaf42e38d1e4e79a34d59173f45cc16617c189d99ecb006a920b87
|
| 3 |
-
size 566553
|
|
|
|
|
|
|
|
|
|
|
|