Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

整理: AquesTalk風記法パース規則コメントの追加 #864

Merged
merged 5 commits into from
Dec 17, 2023
Merged
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 23 additions & 13 deletions voicevox_engine/tts_pipeline/kana_parser.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,17 @@
"""
「AquesTalk風記法」を実装した AquesTalk風記法テキスト <-> アクセント句系列 変換。
記法定義: `https://github.com/VOICEVOX/voicevox_engine/blob/master/README.md#読み方を-aquestalk風記法で取得修正するサンプルコード` # noqa

記法の規則は以下の通り。

- 読みはカタカナのみ
- `/` で区切り
- `、` で無音付き区切り
Hiroshiba marked this conversation as resolved.
Show resolved Hide resolved
- `_` で無声化
- `'` でアクセント位置
- `?` で疑問文
- アクセント位置はちょうど1つ

NOTE: ユーザー向け案内 `https://github.com/VOICEVOX/voicevox_engine/blob/master/README.md#読み方を-aquestalk風記法で取得修正するサンプルコード` # noqa
"""

from typing import List, Optional
Expand Down Expand Up @@ -30,7 +41,7 @@
is_interrogative=False,
)
if vowel in ["a", "i", "u", "e", "o"]:
# 手前に`_`を入れると無声化
# `_` で無声化」の実装
# 例: "_ホ" -> "hO"
_text2mora_with_unvoice[_UNVOICE_SYMBOL + text] = Mora(
text=text,
Expand Down Expand Up @@ -69,13 +80,14 @@ def _text_to_accent_phrase(phrase: str) -> AccentPhrase:
while base_index < len(phrase):
outer_loop += 1

# `'`の手前がアクセント位置
# `'` でアクセント位置」の実装
if phrase[base_index] == _ACCENT_SYMBOL:
# 「アクセント位置はちょうど1つ」の実装
if len(moras) == 0:
raise ParseKanaError(ParseKanaErrorCode.ACCENT_TOP, text=phrase)
# すでにアクセント位置がある場合はエラー
if accent_index is not None:
raise ParseKanaError(ParseKanaErrorCode.ACCENT_TWICE, text=phrase)

accent_index = len(moras)
base_index += 1
continue
Expand All @@ -89,8 +101,6 @@ def _text_to_accent_phrase(phrase: str) -> AccentPhrase:
break
stack += phrase[watch_index]
if stack in _text2mora_with_unvoice:
# より長い要素からなるモーラが見つかれば上書き(longest match)
# 例: phrase "キャ" -> "キ" 検出 -> "キャ" 検出/上書き -> Mora("キャ")
matched_text = stack
if matched_text is None:
raise ParseKanaError(ParseKanaErrorCode.UNKNOWN_TEXT, text=stack)
Expand Down Expand Up @@ -137,7 +147,7 @@ def parse_kana(text: str) -> List[AccentPhrase]:
)
phrase_base = i + 1

# アクセント句末に`?`で疑問文
# `?` で疑問文」の実装
is_interrogative = _WIDE_INTERROGATION_MARK in phrase
if is_interrogative:
if _WIDE_INTERROGATION_MARK in phrase[:-1]:
Expand All @@ -149,7 +159,7 @@ def parse_kana(text: str) -> List[AccentPhrase]:

accent_phrase: AccentPhrase = _text_to_accent_phrase(phrase)

# `、`で無音区間を挿入
# `、` で無音付き区切り」の実装
if i < len(text) and text[i] == _PAUSE_DELIMITER:
accent_phrase.pause_mora = Mora(
text="、",
Expand Down Expand Up @@ -182,23 +192,23 @@ def create_kana(accent_phrases: List[AccentPhrase]) -> str:
# アクセント句を先頭から逐次パースし、`text`末尾にAquesTalk風記法の文字を都度追加(ループ)
for i, phrase in enumerate(accent_phrases):
for j, mora in enumerate(phrase.moras):
# Rule3: "カナの手前に`_`を入れるとそのカナは無声化される"
# `_` で無声化」の実装
if mora.vowel in ["A", "I", "U", "E", "O"]:
text += _UNVOICE_SYMBOL
text += mora.text
# `'`でアクセント位置
# `'` でアクセント位置」の実装
if j + 1 == phrase.accent:
text += _ACCENT_SYMBOL

# Rule5: "アクセント句末に`?`(全角)を入れることにより疑問文の発音ができる"
# `?` で疑問文」の実装
if phrase.is_interrogative:
text += _WIDE_INTERROGATION_MARK

if i < len(accent_phrases) - 1:
# 「`/` で区切り」の実装
if phrase.pause_mora is None:
# アクセント句区切り
text += _NOPAUSE_DELIMITER
# 「`、` で無音付き区切り」の実装
else:
# 無音でアクセント句区切り
text += _PAUSE_DELIMITER
return text