@@ -347,6 +347,8 @@ def create_accent_phrases(self, text: str, style_id: StyleId) -> list[AccentPhra
347
347
## 分割されていないカタカナモーラの場合、「チョ」「ビャ」のような拗音では二文字に跨るため、単に文字数を数えるだけではズレてしまう
348
348
## ちゃんと音素に分割することで、確実に要素数を mora_tone_list と合わせられる
349
349
sep_phonemes_with_joshi = _sep_kata_with_joshi2sep_phonemes_with_joshi (sep_kata_with_joshi ) # fmt: skip
350
+ ## この時点で、mora_tone_list 内のモーラ数と sep_phonemes_with_joshi 内のモーラ数が一致していなければならない
351
+ assert len (mora_tone_list ) == sum (map (len , sep_phonemes_with_joshi ))
350
352
351
353
# mora_tone_list を、まず記号から通常のモーラに変わったタイミングで区切ってグループ化
352
354
# 通常のモーラから記号に変わったタイミングでは区切らない
@@ -826,35 +828,50 @@ def mora2phonemes(mora: str) -> str:
826
828
return f" { vowel } "
827
829
return f" { consonant } ${ vowel } "
828
830
829
- # 一度モーラ単位で分割した後、その後子音と母音を分割して音素に変換
830
- sep_phonemes_with_joshi : list [list [tuple [str | None , str ]]] = []
831
- for sep_kata_with_joshi_element in sep_kata_with_joshi :
832
- # 記号の場合は1文字ずつ分割して処理
833
- if all (char in PUNCTUATIONS for char in sep_kata_with_joshi_element ):
834
- sep_phonemes_with_joshi .append (
835
- [(None , char ) for char in sep_kata_with_joshi_element ]
836
- )
837
- continue
838
-
839
- spaced_moras = __MORA_PATTERN .sub (lambda m : mora2phonemes (m .group ()), sep_kata_with_joshi_element ) # fmt: skip
831
+ def process_kana_part (kana : str ) -> list [tuple [str | None , str ]]:
832
+ """カタカナ部分を音素に変換する共通処理"""
833
+ result : list [tuple [str | None , str ]] = []
834
+ spaced_moras = __MORA_PATTERN .sub (lambda m : mora2phonemes (m .group ()), kana )
840
835
# 長音記号「ー」の処理
841
836
long_replacement = lambda m : m .group (1 ) + (" " + m .group (1 )) * len (m .group (2 )) # type: ignore # fmt: skip
842
837
spaced_moras = __LONG_PATTERN .sub (long_replacement , spaced_moras )
843
838
moras = spaced_moras .strip ().split (" " )
844
839
# モーラごとに子音と母音に分割
845
- sep_phonemes_with_joshi_element : list [tuple [str | None , str ]] = []
846
840
for mora in moras :
847
- # 記号モーラの場合は単独で追加
848
841
if mora in PUNCTUATIONS :
849
- sep_phonemes_with_joshi_element .append ((None , mora ))
850
- # $ が含まれていれば子音と母音に分割
842
+ result .append ((None , mora ))
851
843
elif "$" in mora :
852
844
consonant , vowel = mora .split ("$" )
853
- sep_phonemes_with_joshi_element .append ((consonant , vowel ))
854
- # $ が含まれていなければ母音のみ
845
+ result .append ((consonant , vowel ))
855
846
else :
856
- sep_phonemes_with_joshi_element .append ((None , mora ))
857
- sep_phonemes_with_joshi .append (sep_phonemes_with_joshi_element )
847
+ result .append ((None , mora ))
848
+ return result
849
+
850
+ # 一度モーラ単位で分割した後、その後子音と母音を分割して音素に変換
851
+ sep_phonemes_with_joshi : list [list [tuple [str | None , str ]]] = []
852
+ for sep_kata_with_joshi_element in sep_kata_with_joshi :
853
+ # 記号とカタカナが混在している場合、記号部分とカタカナ部分を分離して処理
854
+ current_symbols : list [tuple [str | None , str ]] = []
855
+ current_kana : str = ""
856
+ # 1文字ずつ処理して記号とカタカナを分離
857
+ for char in sep_kata_with_joshi_element :
858
+ # 記号の場合
859
+ if char in PUNCTUATIONS :
860
+ # 未処理のカタカナ部分があれば先に処理
861
+ if len (current_kana ) > 0 :
862
+ # カタカナ部分を音素に変換して追加
863
+ current_symbols .extend (process_kana_part (current_kana ))
864
+ current_kana = ""
865
+ # 記号を追加
866
+ current_symbols .append ((None , char ))
867
+ # カタカナの場合
868
+ else :
869
+ current_kana += char
870
+ # 最後の未処理カタカナ部分を処理
871
+ if len (current_kana ) > 0 :
872
+ current_symbols .extend (process_kana_part (current_kana ))
873
+
874
+ sep_phonemes_with_joshi .append (current_symbols )
858
875
859
876
return sep_phonemes_with_joshi
860
877
0 commit comments