Skip to content

Commit

Permalink
feat: 自動調整によって擬似的に疑問文に対応する (#229)
Browse files Browse the repository at this point in the history
* feat: implemented is_interrogative in Phoneme

疑問系の文章に対して発音を変えるために、音素が質問かどうか判定する関数を追加した

refs #222

* is_interrogativeの戻り値の型を明示した

* Moraにis_interrogativeフィールドを追加

エンジンでMoraデータ変換後に、疑問系だったら調整をするのでその判定で必要になるため

* SynthesisEngineBaseにMoraが疑問系だった場合に調整する関数を追加

- AccentPhrase内のMoraにあるPhonemeが疑問系だった場合、Synthesis用のAccentPhraseには疑問系用のMoraを新たに追加するようにした
- adjust_interrogative_accent_phrasesを追加し、Synthesis用のAccentPhraseに含まれるMoraが疑問系だった場合エンジンから得られたMora値から調整する機能を実装した

refs #222

* fixed CI test errors

* フルコンテキストラベルについての説明を追加した

* create_accent_phrasesのテストケースを1ケース追加

* frontが動作しなくなるため is_interrogativeにdefault値を設定するようにした

* create_accent_phrasesで気になるテストデータのケースを追加

* shallow copyからdeep copyに変更した

deep copyのほうがよりコードのimmutabilityを主張するのに適してるようなので変更
#229 (comment)

* feat: fix vowel_length to 0.15

0.15のほうがよいとの意見を受けたため

* fix: 疑問系ではないMoraに対して調整を行っていたため修正した

* feat: implemented enable_interrogative option

* feat: added not_enable_interogative cases

* feat: question markがないケースを追加

interrogativeにのみ適用される変更が行われないことを確認するため

* API中で他に呼び出されてるところもパラメタを追加した

* fix: AccentPhraseにis_interrogativeを追加

#229 (comment)

* feat: removed is_interrogative from model.Mora

#229 (comment)

* fix: moved test cases to test_synthesis_engine_base.py

* feat: Phonemeのis_interrogativeを削除した

Because #229 (comment)

* feat: テスト関数内部にローカル関数でヘルパー関数作成

データ作成処理共通化目的のため
#229 (comment)

* Update voicevox_engine/synthesis_engine/synthesis_engine_base.py

消し忘れのため

Co-authored-by: aoirint <[email protected]>

* fixed: MockSynthesisEngineを使用するように変更した

このテストケースではSynthesisEngineを使用する必要がないため

* feat: removed unnecessary arguments

enable_interrogative引数が不要だったので削除

* feat: enable_interrogativeの説明を追加した

* feat: わかりづらいなと感じたところにコメントを追加

* fix: なんか重複してて気になったので修正

Co-authored-by: aoirint <[email protected]>
  • Loading branch information
qwerty2501 and aoirint authored Dec 19, 2021
1 parent a451258 commit 0701bf8
Show file tree
Hide file tree
Showing 5 changed files with 433 additions and 29 deletions.
41 changes: 35 additions & 6 deletions run.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,17 +73,31 @@ async def start_catch_disconnection():
loop = asyncio.get_event_loop()
_ = loop.create_task(cancellable_engine.catch_disconnection())

def enable_interrogative_query_param() -> Query:
return Query(
default=True,
description="疑問系のテキストが与えられたら自動調整する機能を有効にする。現在は長音を付け足すことで擬似的に実装される",
)

@app.post(
"/audio_query",
response_model=AudioQuery,
tags=["クエリ作成"],
summary="音声合成用のクエリを作成する",
)
def audio_query(text: str, speaker: int):
def audio_query(
text: str,
speaker: int,
enable_interrogative: bool = enable_interrogative_query_param(), # noqa B008,
):
"""
クエリの初期値を得ます。ここで得られたクエリはそのまま音声合成に利用できます。各値の意味は`Schemas`を参照してください。
"""
accent_phrases = engine.create_accent_phrases(text, speaker_id=speaker)
accent_phrases = engine.create_accent_phrases(
text,
speaker_id=speaker,
enable_interrogative=enable_interrogative,
)
return AudioQuery(
accent_phrases=accent_phrases,
speedScale=1,
Expand All @@ -103,7 +117,11 @@ def audio_query(text: str, speaker: int):
tags=["クエリ作成"],
summary="音声合成用のクエリをプリセットを用いて作成する",
)
def audio_query_from_preset(text: str, preset_id: int):
def audio_query_from_preset(
text: str,
preset_id: int,
enable_interrogative: bool = enable_interrogative_query_param(), # noqa B008,
):
"""
クエリの初期値を得ます。ここで得られたクエリはそのまま音声合成に利用できます。各値の意味は`Schemas`を参照してください。
"""
Expand All @@ -118,7 +136,9 @@ def audio_query_from_preset(text: str, preset_id: int):
raise HTTPException(status_code=422, detail="該当するプリセットIDが見つかりません")

accent_phrases = engine.create_accent_phrases(
text, speaker_id=selected_preset.style_id
text,
speaker_id=selected_preset.style_id,
enable_interrogative=enable_interrogative,
)
return AudioQuery(
accent_phrases=accent_phrases,
Expand All @@ -145,7 +165,12 @@ def audio_query_from_preset(text: str, preset_id: int):
}
},
)
def accent_phrases(text: str, speaker: int, is_kana: bool = False):
def accent_phrases(
text: str,
speaker: int,
is_kana: bool = False,
enable_interrogative: bool = enable_interrogative_query_param(), # noqa B008,
):
"""
テキストからアクセント句を得ます。
is_kanaが`true`のとき、テキストは次のようなAquesTalkライクな記法に従う読み仮名として処理されます。デフォルトは`false`です。
Expand All @@ -166,7 +191,11 @@ def accent_phrases(text: str, speaker: int, is_kana: bool = False):
accent_phrases=accent_phrases, speaker_id=speaker
)
else:
return engine.create_accent_phrases(text, speaker_id=speaker)
return engine.create_accent_phrases(
text,
speaker_id=speaker,
enable_interrogative=enable_interrogative,
)

@app.post(
"/mora_data",
Expand Down
286 changes: 286 additions & 0 deletions test/test_synthesis_engine_base.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,286 @@
from typing import List
from unittest import TestCase

from voicevox_engine.dev.synthesis_engine.mock import MockSynthesisEngine
from voicevox_engine.model import AccentPhrase, Mora


class TestSynthesisEngineBase(TestCase):
def setUp(self):
super().setUp()
self.synthesis_engine = MockSynthesisEngine(speakers="")

def create_accent_phrases_test_base(
self, text: str, expected: List[AccentPhrase], enable_interrogative: bool
):
actual = self.synthesis_engine.create_accent_phrases(
text, 1, enable_interrogative
)
self.assertEqual(
expected,
actual,
"case(text:"
+ text
+ ",enable_interrogative:"
+ str(enable_interrogative)
+ ")",
)

def test_create_accent_phrases(self):
def koreha_arimasuka_base_expected():
return [
AccentPhrase(
moras=[
Mora(
text="コ",
consonant="k",
consonant_length=0,
vowel="o",
vowel_length=0,
pitch=0,
),
Mora(
text="レ",
consonant="r",
consonant_length=0,
vowel="e",
vowel_length=0,
pitch=0,
),
Mora(
text="ワ",
consonant="w",
consonant_length=0,
vowel="a",
vowel_length=0,
pitch=0,
),
],
accent=3,
pause_mora=None,
),
AccentPhrase(
moras=[
Mora(
text="ア",
consonant=None,
consonant_length=None,
vowel="a",
vowel_length=0,
pitch=0,
),
Mora(
text="リ",
consonant="r",
consonant_length=0,
vowel="i",
vowel_length=0,
pitch=0,
),
Mora(
text="マ",
consonant="m",
consonant_length=0,
vowel="a",
vowel_length=0,
pitch=0,
),
Mora(
text="ス",
consonant="s",
consonant_length=0,
vowel="U",
vowel_length=0,
pitch=0,
),
Mora(
text="カ",
consonant="k",
consonant_length=0,
vowel="a",
vowel_length=0,
pitch=0,
),
],
accent=3,
pause_mora=None,
),
]

expected = koreha_arimasuka_base_expected()
expected[-1].moras += [
Mora(
text="ア",
consonant=None,
consonant_length=None,
vowel="a",
vowel_length=0.15,
pitch=0.3,
)
]
self.create_accent_phrases_test_base(
text="これはありますか?",
expected=expected,
enable_interrogative=True,
)

expected = koreha_arimasuka_base_expected()
self.create_accent_phrases_test_base(
text="これはありますか?",
expected=expected,
enable_interrogative=False,
)

expected = koreha_arimasuka_base_expected()
self.create_accent_phrases_test_base(
text="これはありますか",
expected=expected,
enable_interrogative=True,
)

def nn_base_expected():
return [
AccentPhrase(
moras=[
Mora(
text="ン",
consonant=None,
consonant_length=None,
vowel="N",
vowel_length=0,
pitch=0,
),
],
accent=1,
pause_mora=None,
)
]

expected = nn_base_expected()
self.create_accent_phrases_test_base(
text="ん",
expected=expected,
enable_interrogative=True,
)

expected = nn_base_expected()
expected[-1].moras += [
Mora(
text="ン",
consonant=None,
consonant_length=None,
vowel="N",
vowel_length=0.15,
pitch=0.3,
)
]
self.create_accent_phrases_test_base(
text="ん?",
expected=expected,
enable_interrogative=True,
)

expected = nn_base_expected()
self.create_accent_phrases_test_base(
text="ん?",
expected=expected,
enable_interrogative=False,
)

def ltu_base_expected():
return [
AccentPhrase(
moras=[
Mora(
text="ッ",
consonant=None,
consonant_length=None,
vowel="cl",
vowel_length=0,
pitch=0.0,
),
],
accent=1,
pause_mora=None,
)
]

expected = ltu_base_expected()
self.create_accent_phrases_test_base(
text="っ",
expected=expected,
enable_interrogative=True,
)

expected = ltu_base_expected()
expected[-1].moras += [
Mora(
text="ッ",
consonant=None,
consonant_length=None,
vowel="cl",
vowel_length=0.15,
pitch=0.3,
)
]
self.create_accent_phrases_test_base(
text="っ?",
expected=expected,
enable_interrogative=True,
)

expected = ltu_base_expected()
self.create_accent_phrases_test_base(
text="っ?",
expected=expected,
enable_interrogative=False,
)

def su_base_expected():
return [
AccentPhrase(
moras=[
Mora(
text="ス",
consonant="s",
consonant_length=0,
vowel="u",
vowel_length=0,
pitch=0,
),
],
accent=1,
pause_mora=None,
)
]

expected = su_base_expected()
self.create_accent_phrases_test_base(
text="す",
expected=expected,
enable_interrogative=True,
)

expected = su_base_expected()
expected[-1].moras += [
Mora(
text="ウ",
consonant=None,
consonant_length=None,
vowel="u",
vowel_length=0.15,
pitch=0.3,
)
]
self.create_accent_phrases_test_base(
text="す?",
expected=expected,
enable_interrogative=True,
)

expected = su_base_expected()
self.create_accent_phrases_test_base(
text="す?",
expected=expected,
enable_interrogative=False,
)
Loading

0 comments on commit 0701bf8

Please sign in to comment.