Merge branch 'fixg2p' into dev

This commit is contained in:
litagin02
2024-01-05 18:23:05 +09:00

View File

@@ -13,6 +13,331 @@ import pyopenjtalk
import jaconv
def hiragana2p(text: str) -> str:
"""
Modification of `jaconv.hiragana2julius`.
- avoid using `:`, instead, `あーーー` -> `a a a a`.
- avoid converting `o u` to `o o` (because the input is already actual `yomi`).
- avoid using `N` for `ん` (for compatibility)
"""
# 3文字以上からなる変換規則
text = text.replace("う゛ぁ", " b a")
text = text.replace("う゛ぃ", " b i")
text = text.replace("う゛ぇ", " b e")
text = text.replace("う゛ぉ", " b o")
text = text.replace("う゛ゅ", " by u")
# 2文字からなる変換規則
text = text.replace("ぅ゛", " b u")
text = text.replace("あぁ", " a a")
text = text.replace("いぃ", " i i")
text = text.replace("いぇ", " i e")
text = text.replace("いゃ", " y a")
text = text.replace("うぅ", " u:")
text = text.replace("えぇ", " e e")
text = text.replace("おぉ", " o:")
text = text.replace("かぁ", " k a:")
text = text.replace("きぃ", " k i:")
text = text.replace("くぅ", " k u:")
text = text.replace("くゃ", " ky a")
text = text.replace("くゅ", " ky u")
text = text.replace("くょ", " ky o")
text = text.replace("けぇ", " k e:")
text = text.replace("こぉ", " k o:")
text = text.replace("がぁ", " g a:")
text = text.replace("ぎぃ", " g i:")
text = text.replace("ぐぅ", " g u:")
text = text.replace("ぐゃ", " gy a")
text = text.replace("ぐゅ", " gy u")
text = text.replace("ぐょ", " gy o")
text = text.replace("げぇ", " g e:")
text = text.replace("ごぉ", " g o:")
text = text.replace("さぁ", " s a:")
text = text.replace("しぃ", " sh i:")
text = text.replace("すぅ", " s u:")
text = text.replace("すゃ", " sh a")
text = text.replace("すゅ", " sh u")
text = text.replace("すょ", " sh o")
text = text.replace("せぇ", " s e:")
text = text.replace("そぉ", " s o:")
text = text.replace("ざぁ", " z a:")
text = text.replace("じぃ", " j i:")
text = text.replace("ずぅ", " z u:")
text = text.replace("ずゃ", " zy a")
text = text.replace("ずゅ", " zy u")
text = text.replace("ずょ", " zy o")
text = text.replace("ぜぇ", " z e:")
text = text.replace("ぞぉ", " z o:")
text = text.replace("たぁ", " t a:")
text = text.replace("ちぃ", " ch i:")
text = text.replace("つぁ", " ts a")
text = text.replace("つぃ", " ts i")
text = text.replace("つぅ", " ts u:")
text = text.replace("つゃ", " ch a")
text = text.replace("つゅ", " ch u")
text = text.replace("つょ", " ch o")
text = text.replace("つぇ", " ts e")
text = text.replace("つぉ", " ts o")
text = text.replace("てぇ", " t e:")
text = text.replace("とぉ", " t o:")
text = text.replace("だぁ", " d a:")
text = text.replace("ぢぃ", " j i:")
text = text.replace("づぅ", " d u:")
text = text.replace("づゃ", " zy a")
text = text.replace("づゅ", " zy u")
text = text.replace("づょ", " zy o")
text = text.replace("でぇ", " d e:")
text = text.replace("どぉ", " d o:")
text = text.replace("なぁ", " n a:")
text = text.replace("にぃ", " n i:")
text = text.replace("ぬぅ", " n u:")
text = text.replace("ぬゃ", " ny a")
text = text.replace("ぬゅ", " ny u")
text = text.replace("ぬょ", " ny o")
text = text.replace("ねぇ", " n e:")
text = text.replace("のぉ", " n o:")
text = text.replace("はぁ", " h a:")
text = text.replace("ひぃ", " h i:")
text = text.replace("ふぅ", " f u:")
text = text.replace("ふゃ", " hy a")
text = text.replace("ふゅ", " hy u")
text = text.replace("ふょ", " hy o")
text = text.replace("へぇ", " h e:")
text = text.replace("ほぉ", " h o:")
text = text.replace("ばぁ", " b a:")
text = text.replace("びぃ", " b i:")
text = text.replace("ぶぅ", " b u:")
text = text.replace("ふゃ", " hy a")
text = text.replace("ぶゅ", " by u")
text = text.replace("ふょ", " hy o")
text = text.replace("べぇ", " b e:")
text = text.replace("ぼぉ", " b o:")
text = text.replace("ぱぁ", " p a:")
text = text.replace("ぴぃ", " p i:")
text = text.replace("ぷぅ", " p u:")
text = text.replace("ぷゃ", " py a")
text = text.replace("ぷゅ", " py u")
text = text.replace("ぷょ", " py o")
text = text.replace("ぺぇ", " p e:")
text = text.replace("ぽぉ", " p o:")
text = text.replace("まぁ", " m a:")
text = text.replace("みぃ", " m i:")
text = text.replace("むぅ", " m u:")
text = text.replace("むゃ", " my a")
text = text.replace("むゅ", " my u")
text = text.replace("むょ", " my o")
text = text.replace("めぇ", " m e:")
text = text.replace("もぉ", " m o:")
text = text.replace("やぁ", " y a:")
text = text.replace("ゆぅ", " y u:")
text = text.replace("ゆゃ", " y a:")
text = text.replace("ゆゅ", " y u:")
text = text.replace("ゆょ", " y o:")
text = text.replace("よぉ", " y o:")
text = text.replace("らぁ", " r a:")
text = text.replace("りぃ", " r i:")
text = text.replace("るぅ", " r u:")
text = text.replace("るゃ", " ry a")
text = text.replace("るゅ", " ry u")
text = text.replace("るょ", " ry o")
text = text.replace("れぇ", " r e:")
text = text.replace("ろぉ", " r o:")
text = text.replace("わぁ", " w a:")
text = text.replace("をぉ", " o:")
text = text.replace("う゛", " b u")
text = text.replace("でぃ", " d i")
text = text.replace("でぇ", " d e:")
text = text.replace("でゃ", " dy a")
text = text.replace("でゅ", " dy u")
text = text.replace("でょ", " dy o")
text = text.replace("てぃ", " t i")
text = text.replace("てぇ", " t e:")
text = text.replace("てゃ", " ty a")
text = text.replace("てゅ", " ty u")
text = text.replace("てょ", " ty o")
text = text.replace("すぃ", " s i")
text = text.replace("ずぁ", " z u a")
text = text.replace("ずぃ", " z i")
text = text.replace("ずぅ", " z u")
text = text.replace("ずゃ", " zy a")
text = text.replace("ずゅ", " zy u")
text = text.replace("ずょ", " zy o")
text = text.replace("ずぇ", " z e")
text = text.replace("ずぉ", " z o")
text = text.replace("きゃ", " ky a")
text = text.replace("きゅ", " ky u")
text = text.replace("きょ", " ky o")
text = text.replace("しゃ", " sh a")
text = text.replace("しゅ", " sh u")
text = text.replace("しぇ", " sh e")
text = text.replace("しょ", " sh o")
text = text.replace("ちゃ", " ch a")
text = text.replace("ちゅ", " ch u")
text = text.replace("ちぇ", " ch e")
text = text.replace("ちょ", " ch o")
text = text.replace("とぅ", " t u")
text = text.replace("とゃ", " ty a")
text = text.replace("とゅ", " ty u")
text = text.replace("とょ", " ty o")
text = text.replace("どぁ", " d o a")
text = text.replace("どぅ", " d u")
text = text.replace("どゃ", " dy a")
text = text.replace("どゅ", " dy u")
text = text.replace("どょ", " dy o")
text = text.replace("どぉ", " d o:")
text = text.replace("にゃ", " ny a")
text = text.replace("にゅ", " ny u")
text = text.replace("にょ", " ny o")
text = text.replace("ひゃ", " hy a")
text = text.replace("ひゅ", " hy u")
text = text.replace("ひょ", " hy o")
text = text.replace("みゃ", " my a")
text = text.replace("みゅ", " my u")
text = text.replace("みょ", " my o")
text = text.replace("りゃ", " ry a")
text = text.replace("りゅ", " ry u")
text = text.replace("りょ", " ry o")
text = text.replace("ぎゃ", " gy a")
text = text.replace("ぎゅ", " gy u")
text = text.replace("ぎょ", " gy o")
text = text.replace("ぢぇ", " j e")
text = text.replace("ぢゃ", " j a")
text = text.replace("ぢゅ", " j u")
text = text.replace("ぢょ", " j o")
text = text.replace("じぇ", " j e")
text = text.replace("じゃ", " j a")
text = text.replace("じゅ", " j u")
text = text.replace("じょ", " j o")
text = text.replace("びゃ", " by a")
text = text.replace("びゅ", " by u")
text = text.replace("びょ", " by o")
text = text.replace("ぴゃ", " py a")
text = text.replace("ぴゅ", " py u")
text = text.replace("ぴょ", " py o")
text = text.replace("うぁ", " u a")
text = text.replace("うぃ", " w i")
text = text.replace("うぇ", " w e")
text = text.replace("うぉ", " w o")
text = text.replace("ふぁ", " f a")
text = text.replace("ふぃ", " f i")
text = text.replace("ふぅ", " f u")
text = text.replace("ふゃ", " hy a")
text = text.replace("ふゅ", " hy u")
text = text.replace("ふょ", " hy o")
text = text.replace("ふぇ", " f e")
text = text.replace("ふぉ", " f o")
# 1音からなる変換規則
text = text.replace("", " a")
text = text.replace("", " i")
text = text.replace("", " u")
text = text.replace("", " e")
text = text.replace("", " o")
text = text.replace("", " k a")
text = text.replace("", " k i")
text = text.replace("", " k u")
text = text.replace("", " k e")
text = text.replace("", " k o")
text = text.replace("", " s a")
text = text.replace("", " sh i")
text = text.replace("", " s u")
text = text.replace("", " s e")
text = text.replace("", " s o")
text = text.replace("", " t a")
text = text.replace("", " ch i")
text = text.replace("", " ts u")
text = text.replace("", " t e")
text = text.replace("", " t o")
text = text.replace("", " n a")
text = text.replace("", " n i")
text = text.replace("", " n u")
text = text.replace("", " n e")
text = text.replace("", " n o")
text = text.replace("", " h a")
text = text.replace("", " h i")
text = text.replace("", " f u")
text = text.replace("", " h e")
text = text.replace("", " h o")
text = text.replace("", " m a")
text = text.replace("", " m i")
text = text.replace("", " m u")
text = text.replace("", " m e")
text = text.replace("", " m o")
text = text.replace("", " r a")
text = text.replace("", " r i")
text = text.replace("", " r u")
text = text.replace("", " r e")
text = text.replace("", " r o")
text = text.replace("", " g a")
text = text.replace("", " g i")
text = text.replace("", " g u")
text = text.replace("", " g e")
text = text.replace("", " g o")
text = text.replace("", " z a")
text = text.replace("", " j i")
text = text.replace("", " z u")
text = text.replace("", " z e")
text = text.replace("", " z o")
text = text.replace("", " d a")
text = text.replace("", " j i")
text = text.replace("", " z u")
text = text.replace("", " d e")
text = text.replace("", " d o")
text = text.replace("", " b a")
text = text.replace("", " b i")
text = text.replace("", " b u")
text = text.replace("", " b e")
text = text.replace("", " b o")
text = text.replace("", " p a")
text = text.replace("", " p i")
text = text.replace("", " p u")
text = text.replace("", " p e")
text = text.replace("", " p o")
text = text.replace("", " y a")
text = text.replace("", " y u")
text = text.replace("", " y o")
text = text.replace("", " w a")
text = text.replace("", " i")
text = text.replace("", " e")
text = text.replace("", " N")
text = text.replace("", " q")
# ここまでに処理されてない ぁぃぅぇぉ はそのまま大文字扱い
text = text.replace("", " a")
text = text.replace("", " i")
text = text.replace("", " u")
text = text.replace("", " e")
text = text.replace("", " o")
text = text.replace("", " w a")
text = text.replace("", " o")
# 長音の処理
# for (pattern, replace_str) in JULIUS_LONG_VOWEL:
# text = pattern.sub(replace_str, text)
# text = text.replace("o u", "o:") # おう -> おーの音便
text = text.replace("", ":")
text = text.replace("", ":")
text = text.replace("", ":")
text = text.replace("-", ":")
# その他特別な処理
text = text.replace("", " o")
text = text.strip()
text = text.replace(":+", ":")
# ここまで`jaconv.hiragana2julius`と音便処理と長音処理をのぞいて同じ
# ここから`k a:: k i:`→`k a a a k i i`のように`:`の数だけ繰り返す処理
pattern = r"(\w)(:*)"
replacement = lambda m: m.group(1) + (" " + m.group(1)) * len(m.group(2))
text = re.sub(pattern, replacement, text)
text = text.replace("N", "n") # 促音のNをnに変換
return text
def kata2phoneme(text: str) -> str:
"""Convert katakana text to phonemes."""
text = text.strip()
@@ -32,16 +357,12 @@ def kata2phoneme(text: str) -> str:
res.append(prev[-1])
text = text[1:]
continue
res += pyopenjtalk.g2p(text).lower().replace("cl", "q").split(" ")
res += hiragana2p(jaconv.kata2hira(text)).split(" ")
break
# res = _COLON_RX.sub(":", res)
return res
def hira2kata(text: str) -> str:
return jaconv.hira2kata(text)
_SYMBOL_TOKENS = set(list("・、。?!"))
_NO_YOMI_TOKENS = set(list("「」『』―()[][]"))
_MARKS = re.compile(
@@ -49,41 +370,8 @@ _MARKS = re.compile(
)
def text2kata(text: str) -> str:
def text2sep_kata(text: str):
parsed = pyopenjtalk.run_frontend(text)
res = []
for parts in parsed:
word, yomi = replace_punctuation(parts["string"]), parts["pron"].replace(
"", ""
)
if yomi:
if re.match(_MARKS, yomi):
if len(word) > 1:
word = [replace_punctuation(i) for i in list(word)]
yomi = word
res += yomi
sep += word
continue
elif word not in rep_map.keys() and word not in rep_map.values():
word = ","
yomi = word
res.append(yomi)
else:
if word in _SYMBOL_TOKENS:
res.append(word)
elif word in ("", ""):
res.append("")
elif word in _NO_YOMI_TOKENS:
pass
else:
res.append(word)
return hira2kata("".join(res))
def text2sep_kata(text: str) -> (list, list):
parsed = pyopenjtalk.run_frontend(text)
res = []
sep = []
for parts in parsed:
@@ -112,7 +400,7 @@ def text2sep_kata(text: str) -> (list, list):
else:
res.append(word)
sep.append(word)
return sep, [hira2kata(i) for i in res], get_accent(parsed)
return sep, res, get_accent(parsed)
def get_accent(parsed):
@@ -225,16 +513,6 @@ def japanese_convert_alpha_symbols_to_words(text: str) -> str:
return "".join([_ALPHASYMBOL_YOMI.get(ch, ch) for ch in text.lower()])
def japanese_text_to_phonemes(text: str) -> str:
"""Convert Japanese text to phonemes."""
res = unicodedata.normalize("NFKC", text)
res = japanese_convert_numbers_to_words(res)
# res = japanese_convert_alpha_symbols_to_words(res)
res = text2kata(res)
res = kata2phoneme(res)
return res
def is_japanese_character(char):
# 定义日语文字系统的 Unicode 范围
japanese_ranges = [