From 52360e853338a58ade760b096f3b14ac6769da3a Mon Sep 17 00:00:00 2001 From: X-20A <155217226+X-20A@users.noreply.github.com> Date: Sat, 25 May 2024 22:37:07 +0900 Subject: [PATCH 01/86] =?UTF-8?q?=E8=A8=AD=E5=AE=9A=E3=81=A7=E3=81=AE?= =?UTF-8?q?=E6=93=8D=E4=BD=9C=E3=81=A8=E5=8F=B3=E6=AC=84=E5=88=9D=E6=9C=9F?= =?UTF-8?q?=E5=8C=96&=E8=A8=AD=E5=AE=9A=E5=8F=8D=E6=98=A0=E3=81=BE?= =?UTF-8?q?=E3=81=A7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .env.production | 14 - .env.test | 14 - openapi.json | 3171 ++++++++++++++++- src/backend/electron/main.ts | 3 +- src/components/App.vue | 1 + .../Dialog/DictionaryManageDialog.vue | 1 + src/components/Dialog/SettingDialog.vue | 58 + src/components/Talk/AccentPhrase.vue | 7 +- src/components/Talk/AudioCell.vue | 1 + src/components/Talk/AudioDetail.vue | 1 + src/components/Talk/AudioInfo.vue | 306 +- src/components/Talk/TalkEditor.vue | 4 +- src/domain/project/schema.ts | 2 + src/openapi/apis/DefaultApi.ts | 199 +- src/openapi/models/AudioQuery.ts | 45 +- src/openapi/models/Preset.ts | 45 +- src/store/audio.ts | 124 +- src/store/audioGenerate.ts | 17 +- src/store/engine.ts | 3 + src/store/preset.ts | 8 +- src/store/project.ts | 7 + src/store/proxy.ts | 2 + src/store/type.ts | 25 + src/store/ui.ts | 32 + src/store/utility.ts | 20 + src/type/preload.ts | 7 + .../unit/backend/common/pastConfigs/0.13.json | 3 +- 27 files changed, 3851 insertions(+), 269 deletions(-) delete mode 100644 .env.production delete mode 100644 .env.test diff --git a/.env.production b/.env.production deleted file mode 100644 index 5b0dcb0498..0000000000 --- a/.env.production +++ /dev/null @@ -1,14 +0,0 @@ -VITE_APP_NAME=voicevox -VITE_DEFAULT_ENGINE_INFOS=`[ - { - "uuid": "074fc39e-678b-4c13-8916-ffca8d505d1d", - "name": "VOICEVOX Engine", - "executionEnabled": true, - "executionFilePath": "vv-engine/run.exe", - "executionArgs": [], - "host": "http://127.0.0.1:50021" - } -]` -VITE_OFFICIAL_WEBSITE_URL=https://voicevox.hiroshiba.jp/ -VITE_LATEST_UPDATE_INFOS_URL=https://raw.githubusercontent.com/VOICEVOX/voicevox_blog/master/src/data/updateInfos.json -VITE_GTM_CONTAINER_ID=GTM-DUMMY diff --git a/.env.test b/.env.test deleted file mode 100644 index dcf447f8b2..0000000000 --- a/.env.test +++ /dev/null @@ -1,14 +0,0 @@ -VITE_APP_NAME=voicevox -VITE_DEFAULT_ENGINE_INFOS=`[ - { - "uuid": "074fc39e-678b-4c13-8916-ffca8d505d1d", - "name": "VOICEVOX Engine", - "executionEnabled": true, - "executionFilePath": "../voicevox_engine/run.exe", - "executionArgs": [], - "host": "http://127.0.0.1:50021" - } -]` -VITE_OFFICIAL_WEBSITE_URL=https://voicevox.hiroshiba.jp/ -VITE_LATEST_UPDATE_INFOS_URL=https://raw.githubusercontent.com/VOICEVOX/voicevox_blog/master/src/data/updateInfos.json -VITE_GTM_CONTAINER_ID=GTM-DUMMY diff --git a/openapi.json b/openapi.json index 12f75ded53..bdef017bb1 100644 --- a/openapi.json +++ b/openapi.json @@ -1 +1,3170 @@ -{"openapi":"3.1.0","info":{"title":"VOICEVOX Engine","description":"VOICEVOXの音声合成エンジンです。","version":"latest"},"paths":{"/audio_query":{"post":{"tags":["クエリ作成"],"summary":"音声合成用のクエリを作成する","description":"音声合成用のクエリの初期値を得ます。ここで得られたクエリはそのまま音声合成に利用できます。各値の意味は`Schemas`を参照してください。","operationId":"audio_query_audio_query_post","parameters":[{"required":true,"schema":{"type":"string","title":"Text"},"name":"text","in":"query"},{"required":true,"schema":{"type":"integer","title":"Speaker"},"name":"speaker","in":"query"},{"required":false,"schema":{"type":"string","title":"Core Version"},"name":"core_version","in":"query"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AudioQuery"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/audio_query_from_preset":{"post":{"tags":["クエリ作成"],"summary":"音声合成用のクエリをプリセットを用いて作成する","description":"音声合成用のクエリの初期値を得ます。ここで得られたクエリはそのまま音声合成に利用できます。各値の意味は`Schemas`を参照してください。","operationId":"audio_query_from_preset_audio_query_from_preset_post","parameters":[{"required":true,"schema":{"type":"string","title":"Text"},"name":"text","in":"query"},{"required":true,"schema":{"type":"integer","title":"Preset Id"},"name":"preset_id","in":"query"},{"required":false,"schema":{"type":"string","title":"Core Version"},"name":"core_version","in":"query"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AudioQuery"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/accent_phrases":{"post":{"tags":["クエリ編集"],"summary":"テキストからアクセント句を得る","description":"テキストからアクセント句を得ます。\nis_kanaが`true`のとき、テキストは次のAquesTalk 風記法で解釈されます。デフォルトは`false`です。\n* 全てのカナはカタカナで記述される\n* アクセント句は`/`または`、`で区切る。`、`で区切った場合に限り無音区間が挿入される。\n* カナの手前に`_`を入れるとそのカナは無声化される\n* アクセント位置を`'`で指定する。全てのアクセント句にはアクセント位置を1つ指定する必要がある。\n* アクセント句末に`?`(全角)を入れることにより疑問文の発音ができる。","operationId":"accent_phrases_accent_phrases_post","parameters":[{"required":true,"schema":{"type":"string","title":"Text"},"name":"text","in":"query"},{"required":true,"schema":{"type":"integer","title":"Speaker"},"name":"speaker","in":"query"},{"required":false,"schema":{"type":"boolean","title":"Is Kana","default":false},"name":"is_kana","in":"query"},{"required":false,"schema":{"type":"string","title":"Core Version"},"name":"core_version","in":"query"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/AccentPhrase"},"type":"array","title":"Response Accent Phrases Accent Phrases Post"}}}},"400":{"description":"読み仮名のパースに失敗","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ParseKanaBadRequest"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/mora_data":{"post":{"tags":["クエリ編集"],"summary":"アクセント句から音高・音素長を得る","operationId":"mora_data_mora_data_post","parameters":[{"required":true,"schema":{"type":"integer","title":"Speaker"},"name":"speaker","in":"query"},{"required":false,"schema":{"type":"string","title":"Core Version"},"name":"core_version","in":"query"}],"requestBody":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/AccentPhrase"},"type":"array","title":"Accent Phrases"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/AccentPhrase"},"type":"array","title":"Response Mora Data Mora Data Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/mora_length":{"post":{"tags":["クエリ編集"],"summary":"アクセント句から音素長を得る","operationId":"mora_length_mora_length_post","parameters":[{"required":true,"schema":{"type":"integer","title":"Speaker"},"name":"speaker","in":"query"},{"required":false,"schema":{"type":"string","title":"Core Version"},"name":"core_version","in":"query"}],"requestBody":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/AccentPhrase"},"type":"array","title":"Accent Phrases"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/AccentPhrase"},"type":"array","title":"Response Mora Length Mora Length Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/mora_pitch":{"post":{"tags":["クエリ編集"],"summary":"アクセント句から音高を得る","operationId":"mora_pitch_mora_pitch_post","parameters":[{"required":true,"schema":{"type":"integer","title":"Speaker"},"name":"speaker","in":"query"},{"required":false,"schema":{"type":"string","title":"Core Version"},"name":"core_version","in":"query"}],"requestBody":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/AccentPhrase"},"type":"array","title":"Accent Phrases"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/AccentPhrase"},"type":"array","title":"Response Mora Pitch Mora Pitch Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/synthesis":{"post":{"tags":["音声合成"],"summary":"音声合成する","operationId":"synthesis_synthesis_post","parameters":[{"required":true,"schema":{"type":"integer","title":"Speaker"},"name":"speaker","in":"query"},{"description":"疑問系のテキストが与えられたら語尾を自動調整する","required":false,"schema":{"type":"boolean","title":"Enable Interrogative Upspeak","description":"疑問系のテキストが与えられたら語尾を自動調整する","default":true},"name":"enable_interrogative_upspeak","in":"query"},{"required":false,"schema":{"type":"string","title":"Core Version"},"name":"core_version","in":"query"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AudioQuery"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"audio/wav":{"schema":{"type":"string","format":"binary"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/cancellable_synthesis":{"post":{"tags":["音声合成"],"summary":"音声合成する(キャンセル可能)","operationId":"cancellable_synthesis_cancellable_synthesis_post","parameters":[{"required":true,"schema":{"type":"integer","title":"Speaker"},"name":"speaker","in":"query"},{"required":false,"schema":{"type":"string","title":"Core Version"},"name":"core_version","in":"query"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AudioQuery"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"audio/wav":{"schema":{"type":"string","format":"binary"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/multi_synthesis":{"post":{"tags":["音声合成"],"summary":"複数まとめて音声合成する","operationId":"multi_synthesis_multi_synthesis_post","parameters":[{"required":true,"schema":{"type":"integer","title":"Speaker"},"name":"speaker","in":"query"},{"required":false,"schema":{"type":"string","title":"Core Version"},"name":"core_version","in":"query"}],"requestBody":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/AudioQuery"},"type":"array","title":"Queries"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/zip":{"schema":{"type":"string","format":"binary"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/sing_frame_audio_query":{"post":{"tags":["クエリ作成"],"summary":"歌唱音声合成用のクエリを作成する","description":"歌唱音声合成用のクエリの初期値を得ます。ここで得られたクエリはそのまま歌唱音声合成に利用できます。各値の意味は`Schemas`を参照してください。","operationId":"sing_frame_audio_query_sing_frame_audio_query_post","parameters":[{"required":true,"schema":{"type":"integer","title":"Speaker"},"name":"speaker","in":"query"},{"required":false,"schema":{"type":"string","title":"Core Version"},"name":"core_version","in":"query"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Score"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FrameAudioQuery"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/sing_frame_volume":{"post":{"tags":["クエリ編集"],"summary":"スコア・歌唱音声合成用のクエリからフレームごとの音量を得る","operationId":"sing_frame_volume_sing_frame_volume_post","parameters":[{"required":true,"schema":{"type":"integer","title":"Speaker"},"name":"speaker","in":"query"},{"required":false,"schema":{"type":"string","title":"Core Version"},"name":"core_version","in":"query"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Body_sing_frame_volume_sing_frame_volume_post"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"items":{"type":"number"},"type":"array","title":"Response Sing Frame Volume Sing Frame Volume Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/frame_synthesis":{"post":{"tags":["音声合成"],"summary":"Frame Synthesis","description":"歌唱音声合成を行います。","operationId":"frame_synthesis_frame_synthesis_post","parameters":[{"required":true,"schema":{"type":"integer","title":"Speaker"},"name":"speaker","in":"query"},{"required":false,"schema":{"type":"string","title":"Core Version"},"name":"core_version","in":"query"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/FrameAudioQuery"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"audio/wav":{"schema":{"type":"string","format":"binary"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/connect_waves":{"post":{"tags":["その他"],"summary":"base64エンコードされた複数のwavデータを一つに結合する","description":"base64エンコードされたwavデータを一纏めにし、wavファイルで返します。","operationId":"connect_waves_connect_waves_post","requestBody":{"content":{"application/json":{"schema":{"items":{"type":"string"},"type":"array","title":"Waves"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"audio/wav":{"schema":{"type":"string","format":"binary"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/validate_kana":{"post":{"tags":["その他"],"summary":"テキストがAquesTalk 風記法に従っているか判定する","description":"テキストがAquesTalk 風記法に従っているかどうかを判定します。\n従っていない場合はエラーが返ります。","operationId":"validate_kana_validate_kana_post","parameters":[{"description":"判定する対象の文字列","required":true,"schema":{"type":"string","title":"Text","description":"判定する対象の文字列"},"name":"text","in":"query"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"boolean","title":"Response Validate Kana Validate Kana Post"}}}},"400":{"description":"テキストが不正です","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ParseKanaBadRequest"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/morphable_targets":{"post":{"tags":["音声合成"],"summary":"指定したスタイルに対してエンジン内の話者がモーフィングが可能か判定する","description":"指定されたベーススタイルに対してエンジン内の各話者がモーフィング機能を利用可能か返します。\nモーフィングの許可/禁止は`/speakers`の`speaker.supported_features.synthesis_morphing`に記載されています。\nプロパティが存在しない場合は、モーフィングが許可されているとみなします。\n返り値のスタイルIDはstring型なので注意。","operationId":"morphable_targets_morphable_targets_post","parameters":[{"required":false,"schema":{"type":"string","title":"Core Version"},"name":"core_version","in":"query"}],"requestBody":{"content":{"application/json":{"schema":{"items":{"type":"integer"},"type":"array","title":"Base Style Ids"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"items":{"additionalProperties":{"$ref":"#/components/schemas/MorphableTargetInfo"},"type":"object"},"type":"array","title":"Response Morphable Targets Morphable Targets Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/synthesis_morphing":{"post":{"tags":["音声合成"],"summary":"2種類のスタイルでモーフィングした音声を合成する","description":"指定された2種類のスタイルで音声を合成、指定した割合でモーフィングした音声を得ます。\nモーフィングの割合は`morph_rate`で指定でき、0.0でベースのスタイル、1.0でターゲットのスタイルに近づきます。","operationId":"_synthesis_morphing_synthesis_morphing_post","parameters":[{"required":true,"schema":{"type":"integer","title":"Base Speaker"},"name":"base_speaker","in":"query"},{"required":true,"schema":{"type":"integer","title":"Target Speaker"},"name":"target_speaker","in":"query"},{"required":true,"schema":{"type":"number","maximum":1.0,"minimum":0.0,"title":"Morph Rate"},"name":"morph_rate","in":"query"},{"required":false,"schema":{"type":"string","title":"Core Version"},"name":"core_version","in":"query"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AudioQuery"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"audio/wav":{"schema":{"type":"string","format":"binary"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/presets":{"get":{"tags":["その他"],"summary":"Get Presets","description":"エンジンが保持しているプリセットの設定を返します","operationId":"get_presets_presets_get","responses":{"200":{"description":"プリセットのリスト","content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/Preset"},"type":"array","title":"Response Get Presets Presets Get"}}}}}}},"/add_preset":{"post":{"tags":["その他"],"summary":"Add Preset","description":"新しいプリセットを追加します","operationId":"add_preset_add_preset_post","requestBody":{"content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Preset"}],"title":"Preset","description":"新しいプリセット。プリセットIDが既存のものと重複している場合は、新規のプリセットIDが採番されます。"}}},"required":true},"responses":{"200":{"description":"追加したプリセットのプリセットID","content":{"application/json":{"schema":{"type":"integer","title":"Response Add Preset Add Preset Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/update_preset":{"post":{"tags":["その他"],"summary":"Update Preset","description":"既存のプリセットを更新します","operationId":"update_preset_update_preset_post","requestBody":{"content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Preset"}],"title":"Preset","description":"更新するプリセット。プリセットIDが更新対象と一致している必要があります。"}}},"required":true},"responses":{"200":{"description":"更新したプリセットのプリセットID","content":{"application/json":{"schema":{"type":"integer","title":"Response Update Preset Update Preset Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/delete_preset":{"post":{"tags":["その他"],"summary":"Delete Preset","description":"既存のプリセットを削除します","operationId":"delete_preset_delete_preset_post","parameters":[{"description":"削除するプリセットのプリセットID","required":true,"schema":{"type":"integer","title":"Id","description":"削除するプリセットのプリセットID"},"name":"id","in":"query"}],"responses":{"204":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/version":{"get":{"tags":["その他"],"summary":"Version","operationId":"version_version_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"string","title":"Response Version Version Get"}}}}}}},"/core_versions":{"get":{"tags":["その他"],"summary":"Core Versions","operationId":"core_versions_core_versions_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"items":{"type":"string"},"type":"array","title":"Response Core Versions Core Versions Get"}}}}}}},"/speakers":{"get":{"tags":["その他"],"summary":"Speakers","operationId":"speakers_speakers_get","parameters":[{"required":false,"schema":{"type":"string","title":"Core Version"},"name":"core_version","in":"query"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/Speaker"},"type":"array","title":"Response Speakers Speakers Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/speaker_info":{"get":{"tags":["その他"],"summary":"Speaker Info","description":"指定されたspeaker_uuidに関する情報をjson形式で返します。\n画像や音声はbase64エンコードされたものが返されます。","operationId":"speaker_info_speaker_info_get","parameters":[{"required":true,"schema":{"type":"string","title":"Speaker Uuid"},"name":"speaker_uuid","in":"query"},{"required":false,"schema":{"type":"string","title":"Core Version"},"name":"core_version","in":"query"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SpeakerInfo"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/singers":{"get":{"tags":["その他"],"summary":"Singers","operationId":"singers_singers_get","parameters":[{"required":false,"schema":{"type":"string","title":"Core Version"},"name":"core_version","in":"query"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/Speaker"},"type":"array","title":"Response Singers Singers Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/singer_info":{"get":{"tags":["その他"],"summary":"Singer Info","description":"指定されたspeaker_uuidに関する情報をjson形式で返します。\n画像や音声はbase64エンコードされたものが返されます。","operationId":"singer_info_singer_info_get","parameters":[{"required":true,"schema":{"type":"string","title":"Speaker Uuid"},"name":"speaker_uuid","in":"query"},{"required":false,"schema":{"type":"string","title":"Core Version"},"name":"core_version","in":"query"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SpeakerInfo"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/downloadable_libraries":{"get":{"tags":["音声ライブラリ管理"],"summary":"Downloadable Libraries","description":"ダウンロード可能な音声ライブラリの情報を返します。","operationId":"downloadable_libraries_downloadable_libraries_get","responses":{"200":{"description":"ダウンロード可能な音声ライブラリの情報リスト","content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/DownloadableLibraryInfo"},"type":"array","title":"Response Downloadable Libraries Downloadable Libraries Get"}}}}}}},"/installed_libraries":{"get":{"tags":["音声ライブラリ管理"],"summary":"Installed Libraries","description":"インストールした音声ライブラリの情報を返します。","operationId":"installed_libraries_installed_libraries_get","responses":{"200":{"description":"インストールした音声ライブラリの情報","content":{"application/json":{"schema":{"additionalProperties":{"$ref":"#/components/schemas/InstalledLibraryInfo"},"type":"object","title":"Response Installed Libraries Installed Libraries Get"}}}}}}},"/install_library/{library_uuid}":{"post":{"tags":["音声ライブラリ管理"],"summary":"Install Library","description":"音声ライブラリをインストールします。\n音声ライブラリのZIPファイルをリクエストボディとして送信してください。","operationId":"install_library_install_library__library_uuid__post","parameters":[{"description":"音声ライブラリのID","required":true,"schema":{"type":"string","title":"Library Uuid","description":"音声ライブラリのID"},"name":"library_uuid","in":"path"}],"responses":{"204":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/uninstall_library/{library_uuid}":{"post":{"tags":["音声ライブラリ管理"],"summary":"Uninstall Library","description":"音声ライブラリをアンインストールします。","operationId":"uninstall_library_uninstall_library__library_uuid__post","parameters":[{"description":"音声ライブラリのID","required":true,"schema":{"type":"string","title":"Library Uuid","description":"音声ライブラリのID"},"name":"library_uuid","in":"path"}],"responses":{"204":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/initialize_speaker":{"post":{"tags":["その他"],"summary":"Initialize Speaker","description":"指定されたスタイルを初期化します。\n実行しなくても他のAPIは使用できますが、初回実行時に時間がかかることがあります。","operationId":"initialize_speaker_initialize_speaker_post","parameters":[{"required":true,"schema":{"type":"integer","title":"Speaker"},"name":"speaker","in":"query"},{"description":"既に初期化済みのスタイルの再初期化をスキップするかどうか","required":false,"schema":{"type":"boolean","title":"Skip Reinit","description":"既に初期化済みのスタイルの再初期化をスキップするかどうか","default":false},"name":"skip_reinit","in":"query"},{"required":false,"schema":{"type":"string","title":"Core Version"},"name":"core_version","in":"query"}],"responses":{"204":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/is_initialized_speaker":{"get":{"tags":["その他"],"summary":"Is Initialized Speaker","description":"指定されたスタイルが初期化されているかどうかを返します。","operationId":"is_initialized_speaker_is_initialized_speaker_get","parameters":[{"required":true,"schema":{"type":"integer","title":"Speaker"},"name":"speaker","in":"query"},{"required":false,"schema":{"type":"string","title":"Core Version"},"name":"core_version","in":"query"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"boolean","title":"Response Is Initialized Speaker Is Initialized Speaker Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/user_dict":{"get":{"tags":["ユーザー辞書"],"summary":"Get User Dict Words","description":"ユーザー辞書に登録されている単語の一覧を返します。\n単語の表層形(surface)は正規化済みの物を返します。","operationId":"get_user_dict_words_user_dict_get","responses":{"200":{"description":"単語のUUIDとその詳細","content":{"application/json":{"schema":{"additionalProperties":{"$ref":"#/components/schemas/UserDictWord"},"type":"object","title":"Response Get User Dict Words User Dict Get"}}}}}}},"/user_dict_word":{"post":{"tags":["ユーザー辞書"],"summary":"Add User Dict Word","description":"ユーザー辞書に言葉を追加します。","operationId":"add_user_dict_word_user_dict_word_post","parameters":[{"description":"言葉の表層形","required":true,"schema":{"type":"string","title":"Surface","description":"言葉の表層形"},"name":"surface","in":"query"},{"description":"言葉の発音(カタカナ)","required":true,"schema":{"type":"string","title":"Pronunciation","description":"言葉の発音(カタカナ)"},"name":"pronunciation","in":"query"},{"description":"アクセント型(音が下がる場所を指す)","required":true,"schema":{"type":"integer","title":"Accent Type","description":"アクセント型(音が下がる場所を指す)"},"name":"accent_type","in":"query"},{"description":"PROPER_NOUN(固有名詞)、COMMON_NOUN(普通名詞)、VERB(動詞)、ADJECTIVE(形容詞)、SUFFIX(語尾)のいずれか","required":false,"schema":{"allOf":[{"$ref":"#/components/schemas/WordTypes"}],"description":"PROPER_NOUN(固有名詞)、COMMON_NOUN(普通名詞)、VERB(動詞)、ADJECTIVE(形容詞)、SUFFIX(語尾)のいずれか"},"name":"word_type","in":"query"},{"description":"単語の優先度(0から10までの整数)。数字が大きいほど優先度が高くなる。1から9までの値を指定することを推奨","required":false,"schema":{"type":"integer","maximum":10.0,"minimum":0.0,"title":"Priority","description":"単語の優先度(0から10までの整数)。数字が大きいほど優先度が高くなる。1から9までの値を指定することを推奨"},"name":"priority","in":"query"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"string","title":"Response Add User Dict Word User Dict Word Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/user_dict_word/{word_uuid}":{"put":{"tags":["ユーザー辞書"],"summary":"Rewrite User Dict Word","description":"ユーザー辞書に登録されている言葉を更新します。","operationId":"rewrite_user_dict_word_user_dict_word__word_uuid__put","parameters":[{"description":"更新する言葉のUUID","required":true,"schema":{"type":"string","title":"Word Uuid","description":"更新する言葉のUUID"},"name":"word_uuid","in":"path"},{"description":"言葉の表層形","required":true,"schema":{"type":"string","title":"Surface","description":"言葉の表層形"},"name":"surface","in":"query"},{"description":"言葉の発音(カタカナ)","required":true,"schema":{"type":"string","title":"Pronunciation","description":"言葉の発音(カタカナ)"},"name":"pronunciation","in":"query"},{"description":"アクセント型(音が下がる場所を指す)","required":true,"schema":{"type":"integer","title":"Accent Type","description":"アクセント型(音が下がる場所を指す)"},"name":"accent_type","in":"query"},{"description":"PROPER_NOUN(固有名詞)、COMMON_NOUN(普通名詞)、VERB(動詞)、ADJECTIVE(形容詞)、SUFFIX(語尾)のいずれか","required":false,"schema":{"allOf":[{"$ref":"#/components/schemas/WordTypes"}],"description":"PROPER_NOUN(固有名詞)、COMMON_NOUN(普通名詞)、VERB(動詞)、ADJECTIVE(形容詞)、SUFFIX(語尾)のいずれか"},"name":"word_type","in":"query"},{"description":"単語の優先度(0から10までの整数)。数字が大きいほど優先度が高くなる。1から9までの値を指定することを推奨。","required":false,"schema":{"type":"integer","maximum":10.0,"minimum":0.0,"title":"Priority","description":"単語の優先度(0から10までの整数)。数字が大きいほど優先度が高くなる。1から9までの値を指定することを推奨。"},"name":"priority","in":"query"}],"responses":{"204":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["ユーザー辞書"],"summary":"Delete User Dict Word","description":"ユーザー辞書に登録されている言葉を削除します。","operationId":"delete_user_dict_word_user_dict_word__word_uuid__delete","parameters":[{"description":"削除する言葉のUUID","required":true,"schema":{"type":"string","title":"Word Uuid","description":"削除する言葉のUUID"},"name":"word_uuid","in":"path"}],"responses":{"204":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/import_user_dict":{"post":{"tags":["ユーザー辞書"],"summary":"Import User Dict Words","description":"他のユーザー辞書をインポートします。","operationId":"import_user_dict_words_import_user_dict_post","parameters":[{"description":"重複したエントリがあった場合、上書きするかどうか","required":true,"schema":{"type":"boolean","title":"Override","description":"重複したエントリがあった場合、上書きするかどうか"},"name":"override","in":"query"}],"requestBody":{"content":{"application/json":{"schema":{"additionalProperties":{"$ref":"#/components/schemas/UserDictWord"},"type":"object","title":"Import Dict Data","description":"インポートするユーザー辞書のデータ"}}},"required":true},"responses":{"204":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/supported_devices":{"get":{"tags":["その他"],"summary":"Supported Devices","operationId":"supported_devices_supported_devices_get","parameters":[{"required":false,"schema":{"type":"string","title":"Core Version"},"name":"core_version","in":"query"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SupportedDevicesInfo"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/engine_manifest":{"get":{"tags":["その他"],"summary":"Engine Manifest","operationId":"engine_manifest_engine_manifest_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EngineManifest"}}}}}}},"/setting":{"get":{"tags":["設定"],"summary":"Setting Get","description":"設定ページを返します。","operationId":"setting_get_setting_get","responses":{"200":{"description":"Successful Response"}}},"post":{"tags":["設定"],"summary":"Setting Post","description":"設定を更新します。","operationId":"setting_post_setting_post","requestBody":{"content":{"application/x-www-form-urlencoded":{"schema":{"$ref":"#/components/schemas/Body_setting_post_setting_post"}}},"required":true},"responses":{"200":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}}},"components":{"schemas":{"AccentPhrase":{"properties":{"moras":{"items":{"$ref":"#/components/schemas/Mora"},"type":"array","title":"モーラのリスト"},"accent":{"type":"integer","title":"アクセント箇所"},"pause_mora":{"allOf":[{"$ref":"#/components/schemas/Mora"}],"title":"後ろに無音を付けるかどうか"},"is_interrogative":{"type":"boolean","title":"疑問系かどうか","default":false}},"type":"object","required":["moras","accent"],"title":"AccentPhrase","description":"アクセント句ごとの情報"},"AudioQuery":{"properties":{"accent_phrases":{"items":{"$ref":"#/components/schemas/AccentPhrase"},"type":"array","title":"アクセント句のリスト"},"speedScale":{"type":"number","title":"全体の話速"},"pitchScale":{"type":"number","title":"全体の音高"},"intonationScale":{"type":"number","title":"全体の抑揚"},"volumeScale":{"type":"number","title":"全体の音量"},"prePhonemeLength":{"type":"number","title":"音声の前の無音時間"},"postPhonemeLength":{"type":"number","title":"音声の後の無音時間"},"outputSamplingRate":{"type":"integer","title":"音声データの出力サンプリングレート"},"outputStereo":{"type":"boolean","title":"音声データをステレオ出力するか否か"},"kana":{"type":"string","title":"[読み取り専用]AquesTalk 風記法によるテキスト。音声合成用のクエリとしては無視される"}},"type":"object","required":["accent_phrases","speedScale","pitchScale","intonationScale","volumeScale","prePhonemeLength","postPhonemeLength","outputSamplingRate","outputStereo"],"title":"AudioQuery","description":"音声合成用のクエリ"},"Body_setting_post_setting_post":{"properties":{"cors_policy_mode":{"$ref":"#/components/schemas/CorsPolicyMode"},"allow_origin":{"type":"string","title":"Allow Origin"}},"type":"object","required":["cors_policy_mode"],"title":"Body_setting_post_setting_post"},"Body_sing_frame_volume_sing_frame_volume_post":{"properties":{"score":{"$ref":"#/components/schemas/Score"},"frame_audio_query":{"$ref":"#/components/schemas/FrameAudioQuery"}},"type":"object","required":["score","frame_audio_query"],"title":"Body_sing_frame_volume_sing_frame_volume_post"},"CorsPolicyMode":{"type":"string","enum":["all","localapps"],"title":"CorsPolicyMode","description":"CORSの許可モード"},"DownloadableLibraryInfo":{"properties":{"name":{"type":"string","title":"音声ライブラリの名前"},"uuid":{"type":"string","title":"音声ライブラリのUUID"},"version":{"type":"string","title":"音声ライブラリのバージョン"},"download_url":{"type":"string","title":"音声ライブラリのダウンロードURL"},"bytes":{"type":"integer","title":"音声ライブラリのバイト数"},"speakers":{"items":{"$ref":"#/components/schemas/LibrarySpeaker"},"type":"array","title":"音声ライブラリに含まれる話者のリスト"}},"type":"object","required":["name","uuid","version","download_url","bytes","speakers"],"title":"DownloadableLibraryInfo","description":"ダウンロード可能な音声ライブラリの情報"},"EngineManifest":{"properties":{"manifest_version":{"type":"string","title":"マニフェストのバージョン"},"name":{"type":"string","title":"エンジン名"},"brand_name":{"type":"string","title":"ブランド名"},"uuid":{"type":"string","title":"エンジンのUUID"},"url":{"type":"string","title":"エンジンのURL"},"icon":{"type":"string","title":"エンジンのアイコンをBASE64エンコードしたもの"},"default_sampling_rate":{"type":"integer","title":"デフォルトのサンプリング周波数"},"frame_rate":{"type":"number","title":"エンジンのフレームレート"},"terms_of_service":{"type":"string","title":"エンジンの利用規約"},"update_infos":{"items":{"$ref":"#/components/schemas/UpdateInfo"},"type":"array","title":"エンジンのアップデート情報"},"dependency_licenses":{"items":{"$ref":"#/components/schemas/LicenseInfo"},"type":"array","title":"依存関係のライセンス情報"},"supported_vvlib_manifest_version":{"type":"string","title":"エンジンが対応するvvlibのバージョン"},"supported_features":{"allOf":[{"$ref":"#/components/schemas/SupportedFeatures"}],"title":"エンジンが持つ機能"}},"type":"object","required":["manifest_version","name","brand_name","uuid","url","icon","default_sampling_rate","frame_rate","terms_of_service","update_infos","dependency_licenses","supported_features"],"title":"EngineManifest","description":"エンジン自体に関する情報"},"FrameAudioQuery":{"properties":{"f0":{"items":{"type":"number"},"type":"array","title":"フレームごとの基本周波数"},"volume":{"items":{"type":"number"},"type":"array","title":"フレームごとの音量"},"phonemes":{"items":{"$ref":"#/components/schemas/FramePhoneme"},"type":"array","title":"音素のリスト"},"volumeScale":{"type":"number","title":"全体の音量"},"outputSamplingRate":{"type":"integer","title":"音声データの出力サンプリングレート"},"outputStereo":{"type":"boolean","title":"音声データをステレオ出力するか否か"}},"type":"object","required":["f0","volume","phonemes","volumeScale","outputSamplingRate","outputStereo"],"title":"FrameAudioQuery","description":"フレームごとの音声合成用のクエリ"},"FramePhoneme":{"properties":{"phoneme":{"type":"string","title":"音素"},"frame_length":{"type":"integer","title":"音素のフレーム長"}},"type":"object","required":["phoneme","frame_length"],"title":"FramePhoneme","description":"音素の情報"},"HTTPValidationError":{"properties":{"detail":{"items":{"$ref":"#/components/schemas/ValidationError"},"type":"array","title":"Detail"}},"type":"object","title":"HTTPValidationError"},"InstalledLibraryInfo":{"properties":{"name":{"type":"string","title":"音声ライブラリの名前"},"uuid":{"type":"string","title":"音声ライブラリのUUID"},"version":{"type":"string","title":"音声ライブラリのバージョン"},"download_url":{"type":"string","title":"音声ライブラリのダウンロードURL"},"bytes":{"type":"integer","title":"音声ライブラリのバイト数"},"speakers":{"items":{"$ref":"#/components/schemas/LibrarySpeaker"},"type":"array","title":"音声ライブラリに含まれる話者のリスト"},"uninstallable":{"type":"boolean","title":"アンインストール可能かどうか"}},"type":"object","required":["name","uuid","version","download_url","bytes","speakers","uninstallable"],"title":"InstalledLibraryInfo","description":"インストール済み音声ライブラリの情報"},"LibrarySpeaker":{"properties":{"speaker":{"allOf":[{"$ref":"#/components/schemas/Speaker"}],"title":"話者情報"},"speaker_info":{"allOf":[{"$ref":"#/components/schemas/SpeakerInfo"}],"title":"話者の追加情報"}},"type":"object","required":["speaker","speaker_info"],"title":"LibrarySpeaker","description":"音声ライブラリに含まれる話者の情報"},"LicenseInfo":{"properties":{"name":{"type":"string","title":"依存ライブラリ名"},"version":{"type":"string","title":"依存ライブラリのバージョン"},"license":{"type":"string","title":"依存ライブラリのライセンス名"},"text":{"type":"string","title":"依存ライブラリのライセンス本文"}},"type":"object","required":["name","text"],"title":"LicenseInfo","description":"依存ライブラリのライセンス情報"},"Mora":{"properties":{"text":{"type":"string","title":"文字"},"consonant":{"type":"string","title":"子音の音素"},"consonant_length":{"type":"number","title":"子音の音長"},"vowel":{"type":"string","title":"母音の音素"},"vowel_length":{"type":"number","title":"母音の音長"},"pitch":{"type":"number","title":"音高"}},"type":"object","required":["text","vowel","vowel_length","pitch"],"title":"Mora","description":"モーラ(子音+母音)ごとの情報"},"MorphableTargetInfo":{"properties":{"is_morphable":{"type":"boolean","title":"指定した話者に対してモーフィングの可否"}},"type":"object","required":["is_morphable"],"title":"MorphableTargetInfo"},"Note":{"properties":{"key":{"type":"integer","title":"音階"},"frame_length":{"type":"integer","title":"音符のフレーム長"},"lyric":{"type":"string","title":"音符の歌詞"}},"type":"object","required":["frame_length","lyric"],"title":"Note","description":"音符ごとの情報"},"ParseKanaBadRequest":{"properties":{"text":{"type":"string","title":"エラーメッセージ"},"error_name":{"type":"string","title":"エラー名","description":"|name|description|\n|---|---|\n| UNKNOWN_TEXT | 判別できない読み仮名があります: {text} |\n| ACCENT_TOP | 句頭にアクセントは置けません: {text} |\n| ACCENT_TWICE | 1つのアクセント句に二つ以上のアクセントは置けません: {text} |\n| ACCENT_NOTFOUND | アクセントを指定していないアクセント句があります: {text} |\n| EMPTY_PHRASE | {position}番目のアクセント句が空白です |\n| INTERROGATION_MARK_NOT_AT_END | アクセント句末以外に「?」は置けません: {text} |\n| INFINITE_LOOP | 処理時に無限ループになってしまいました...バグ報告をお願いします。 |"},"error_args":{"additionalProperties":{"type":"string"},"type":"object","title":"エラーを起こした箇所"}},"type":"object","required":["text","error_name","error_args"],"title":"ParseKanaBadRequest"},"Preset":{"properties":{"id":{"type":"integer","title":"プリセットID"},"name":{"type":"string","title":"プリセット名"},"speaker_uuid":{"type":"string","title":"話者のUUID"},"style_id":{"type":"integer","title":"スタイルID"},"speedScale":{"type":"number","title":"全体の話速"},"pitchScale":{"type":"number","title":"全体の音高"},"intonationScale":{"type":"number","title":"全体の抑揚"},"volumeScale":{"type":"number","title":"全体の音量"},"prePhonemeLength":{"type":"number","title":"音声の前の無音時間"},"postPhonemeLength":{"type":"number","title":"音声の後の無音時間"}},"type":"object","required":["id","name","speaker_uuid","style_id","speedScale","pitchScale","intonationScale","volumeScale","prePhonemeLength","postPhonemeLength"],"title":"Preset","description":"プリセット情報"},"Score":{"properties":{"notes":{"items":{"$ref":"#/components/schemas/Note"},"type":"array","title":"音符のリスト"}},"type":"object","required":["notes"],"title":"Score","description":"楽譜情報"},"Speaker":{"properties":{"supported_features":{"allOf":[{"$ref":"#/components/schemas/SpeakerSupportedFeatures"}],"title":"話者の対応機能"},"name":{"type":"string","title":"名前"},"speaker_uuid":{"type":"string","title":"話者のUUID"},"styles":{"items":{"$ref":"#/components/schemas/SpeakerStyle"},"type":"array","title":"スタイルの一覧"},"version":{"type":"string","title":"Version","default":"話者のバージョン"}},"type":"object","required":["name","speaker_uuid","styles"],"title":"Speaker","description":"話者情報"},"SpeakerInfo":{"properties":{"policy":{"type":"string","title":"policy.md"},"portrait":{"type":"string","title":"portrait.pngをbase64エンコードしたもの"},"style_infos":{"items":{"$ref":"#/components/schemas/StyleInfo"},"type":"array","title":"スタイルの追加情報"}},"type":"object","required":["policy","portrait","style_infos"],"title":"SpeakerInfo","description":"話者の追加情報"},"SpeakerStyle":{"properties":{"name":{"type":"string","title":"スタイル名"},"id":{"type":"integer","title":"スタイルID"},"type":{"type":"string","enum":["talk","singing_teacher","frame_decode","sing"],"title":"スタイルの種類。talk:音声合成クエリの作成と音声合成が可能。singing_teacher:歌唱音声合成用のクエリの作成が可能。frame_decode:歌唱音声合成が可能。sing:歌唱音声合成用のクエリの作成と歌唱音声合成が可能。","default":"talk"}},"type":"object","required":["name","id"],"title":"SpeakerStyle","description":"話者のスタイル情報"},"SpeakerSupportPermittedSynthesisMorphing":{"type":"string","enum":["ALL","SELF_ONLY","NOTHING"],"title":"SpeakerSupportPermittedSynthesisMorphing","description":"An enumeration."},"SpeakerSupportedFeatures":{"properties":{"permitted_synthesis_morphing":{"allOf":[{"$ref":"#/components/schemas/SpeakerSupportPermittedSynthesisMorphing"}],"title":"モーフィング機能への対応","default":"ALL"}},"type":"object","title":"SpeakerSupportedFeatures","description":"話者の対応機能の情報"},"StyleInfo":{"properties":{"id":{"type":"integer","title":"スタイルID"},"icon":{"type":"string","title":"当該スタイルのアイコンをbase64エンコードしたもの"},"portrait":{"type":"string","title":"当該スタイルのportrait.pngをbase64エンコードしたもの"},"voice_samples":{"items":{"type":"string"},"type":"array","title":"voice_sampleのwavファイルをbase64エンコードしたもの"}},"type":"object","required":["id","icon","voice_samples"],"title":"StyleInfo","description":"スタイルの追加情報"},"SupportedDevicesInfo":{"properties":{"cpu":{"type":"boolean","title":"CPUに対応しているか"},"cuda":{"type":"boolean","title":"CUDA(Nvidia GPU)に対応しているか"},"dml":{"type":"boolean","title":"DirectML(Nvidia GPU/Radeon GPU等)に対応しているか"}},"type":"object","required":["cpu","cuda","dml"],"title":"SupportedDevicesInfo","description":"対応しているデバイスの情報"},"SupportedFeatures":{"properties":{"adjust_mora_pitch":{"type":"boolean","title":"モーラごとの音高の調整"},"adjust_phoneme_length":{"type":"boolean","title":"音素ごとの長さの調整"},"adjust_speed_scale":{"type":"boolean","title":"全体の話速の調整"},"adjust_pitch_scale":{"type":"boolean","title":"全体の音高の調整"},"adjust_intonation_scale":{"type":"boolean","title":"全体の抑揚の調整"},"adjust_volume_scale":{"type":"boolean","title":"全体の音量の調整"},"interrogative_upspeak":{"type":"boolean","title":"疑問文の自動調整"},"synthesis_morphing":{"type":"boolean","title":"2種類のスタイルでモーフィングした音声を合成"},"sing":{"type":"boolean","title":"歌唱音声合成"},"manage_library":{"type":"boolean","title":"音声ライブラリのインストール・アンインストール"}},"type":"object","required":["adjust_mora_pitch","adjust_phoneme_length","adjust_speed_scale","adjust_pitch_scale","adjust_intonation_scale","adjust_volume_scale","interrogative_upspeak","synthesis_morphing"],"title":"SupportedFeatures","description":"エンジンが持つ機能の一覧"},"UpdateInfo":{"properties":{"version":{"type":"string","title":"エンジンのバージョン名"},"descriptions":{"items":{"type":"string"},"type":"array","title":"アップデートの詳細についての説明"},"contributors":{"items":{"type":"string"},"type":"array","title":"貢献者名"}},"type":"object","required":["version","descriptions"],"title":"UpdateInfo","description":"エンジンのアップデート情報"},"UserDictWord":{"properties":{"surface":{"type":"string","title":"表層形"},"priority":{"type":"integer","maximum":10.0,"minimum":0.0,"title":"優先度"},"context_id":{"type":"integer","title":"文脈ID","default":1348},"part_of_speech":{"type":"string","title":"品詞"},"part_of_speech_detail_1":{"type":"string","title":"品詞細分類1"},"part_of_speech_detail_2":{"type":"string","title":"品詞細分類2"},"part_of_speech_detail_3":{"type":"string","title":"品詞細分類3"},"inflectional_type":{"type":"string","title":"活用型"},"inflectional_form":{"type":"string","title":"活用形"},"stem":{"type":"string","title":"原形"},"yomi":{"type":"string","title":"読み"},"pronunciation":{"type":"string","title":"発音"},"accent_type":{"type":"integer","title":"アクセント型"},"mora_count":{"type":"integer","title":"モーラ数"},"accent_associative_rule":{"type":"string","title":"アクセント結合規則"}},"type":"object","required":["surface","priority","part_of_speech","part_of_speech_detail_1","part_of_speech_detail_2","part_of_speech_detail_3","inflectional_type","inflectional_form","stem","yomi","pronunciation","accent_type","accent_associative_rule"],"title":"UserDictWord","description":"辞書のコンパイルに使われる情報"},"ValidationError":{"properties":{"loc":{"items":{"anyOf":[{"type":"string"},{"type":"integer"}]},"type":"array","title":"Location"},"msg":{"type":"string","title":"Message"},"type":{"type":"string","title":"Error Type"}},"type":"object","required":["loc","msg","type"],"title":"ValidationError"},"WordTypes":{"type":"string","enum":["PROPER_NOUN","COMMON_NOUN","VERB","ADJECTIVE","SUFFIX"],"title":"WordTypes","description":"fastapiでword_type引数を検証する時に使用するクラス"},"VvlibManifest":{"title":"VvlibManifest","description":"vvlib(VOICEVOX Library)に関する情報","type":"object","properties":{"manifest_version":{"title":"マニフェストバージョン","type":"string"},"name":{"title":"音声ライブラリ名","type":"string"},"version":{"title":"音声ライブラリバージョン","type":"string"},"uuid":{"title":"音声ライブラリのUUID","type":"string"},"brand_name":{"title":"エンジンのブランド名","type":"string"},"engine_name":{"title":"エンジン名","type":"string"},"engine_uuid":{"title":"エンジンのUUID","type":"string"}},"required":["manifest_version","name","version","uuid","brand_name","engine_name","engine_uuid"]},"BaseLibraryInfo":{"title":"BaseLibraryInfo","description":"音声ライブラリの情報","type":"object","properties":{"name":{"title":"音声ライブラリの名前","type":"string"},"uuid":{"title":"音声ライブラリのUUID","type":"string"},"version":{"title":"音声ライブラリのバージョン","type":"string"},"download_url":{"title":"音声ライブラリのダウンロードURL","type":"string"},"bytes":{"title":"音声ライブラリのバイト数","type":"integer"},"speakers":{"title":"音声ライブラリに含まれる話者のリスト","type":"array","items":{"$ref":"#/components/schemas/LibrarySpeaker"}}},"required":["name","uuid","version","download_url","bytes","speakers"]}}}} \ No newline at end of file +{ + "openapi": "3.1.0", + "info": { + "title": "VOICEVOX Engine", + "description": "VOICEVOXの音声合成エンジンです。", + "version": "0.18.1" + }, + "paths": { + "/audio_query": { + "post": { + "tags": [ + "クエリ作成" + ], + "summary": "音声合成用のクエリを作成する", + "description": "音声合成用のクエリの初期値を得ます。ここで得られたクエリはそのまま音声合成に利用できます。各値の意味は`Schemas`を参照してください。", + "operationId": "audio_query_audio_query_post", + "parameters": [ + { + "required": true, + "schema": { + "type": "string", + "title": "Text" + }, + "name": "text", + "in": "query" + }, + { + "required": true, + "schema": { + "type": "integer", + "title": "Speaker" + }, + "name": "speaker", + "in": "query" + }, + { + "required": false, + "schema": { + "type": "string", + "title": "Core Version" + }, + "name": "core_version", + "in": "query" + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AudioQuery" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/audio_query_from_preset": { + "post": { + "tags": [ + "クエリ作成" + ], + "summary": "音声合成用のクエリをプリセットを用いて作成する", + "description": "音声合成用のクエリの初期値を得ます。ここで得られたクエリはそのまま音声合成に利用できます。各値の意味は`Schemas`を参照してください。", + "operationId": "audio_query_from_preset_audio_query_from_preset_post", + "parameters": [ + { + "required": true, + "schema": { + "type": "string", + "title": "Text" + }, + "name": "text", + "in": "query" + }, + { + "required": true, + "schema": { + "type": "integer", + "title": "Preset Id" + }, + "name": "preset_id", + "in": "query" + }, + { + "required": false, + "schema": { + "type": "string", + "title": "Core Version" + }, + "name": "core_version", + "in": "query" + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AudioQuery" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/accent_phrases": { + "post": { + "tags": [ + "クエリ編集" + ], + "summary": "テキストからアクセント句を得る", + "description": "テキストからアクセント句を得ます。\nis_kanaが`true`のとき、テキストは次のAquesTalk 風記法で解釈されます。デフォルトは`false`です。\n* 全てのカナはカタカナで記述される\n* アクセント句は`/`または`、`で区切る。`、`で区切った場合に限り無音区間が挿入される。\n* カナの手前に`_`を入れるとそのカナは無声化される\n* アクセント位置を`'`で指定する。全てのアクセント句にはアクセント位置を1つ指定する必要がある。\n* アクセント句末に`?`(全角)を入れることにより疑問文の発音ができる。", + "operationId": "accent_phrases_accent_phrases_post", + "parameters": [ + { + "required": true, + "schema": { + "type": "string", + "title": "Text" + }, + "name": "text", + "in": "query" + }, + { + "required": true, + "schema": { + "type": "integer", + "title": "Speaker" + }, + "name": "speaker", + "in": "query" + }, + { + "required": false, + "schema": { + "type": "boolean", + "title": "Is Kana", + "default": false + }, + "name": "is_kana", + "in": "query" + }, + { + "required": false, + "schema": { + "type": "string", + "title": "Core Version" + }, + "name": "core_version", + "in": "query" + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "items": { + "$ref": "#/components/schemas/AccentPhrase" + }, + "type": "array", + "title": "Response Accent Phrases Accent Phrases Post" + } + } + } + }, + "400": { + "description": "読み仮名のパースに失敗", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ParseKanaBadRequest" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/mora_data": { + "post": { + "tags": [ + "クエリ編集" + ], + "summary": "アクセント句から音高・音素長を得る", + "operationId": "mora_data_mora_data_post", + "parameters": [ + { + "required": true, + "schema": { + "type": "integer", + "title": "Speaker" + }, + "name": "speaker", + "in": "query" + }, + { + "required": false, + "schema": { + "type": "string", + "title": "Core Version" + }, + "name": "core_version", + "in": "query" + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "items": { + "$ref": "#/components/schemas/AccentPhrase" + }, + "type": "array", + "title": "Accent Phrases" + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "items": { + "$ref": "#/components/schemas/AccentPhrase" + }, + "type": "array", + "title": "Response Mora Data Mora Data Post" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/mora_length": { + "post": { + "tags": [ + "クエリ編集" + ], + "summary": "アクセント句から音素長を得る", + "operationId": "mora_length_mora_length_post", + "parameters": [ + { + "required": true, + "schema": { + "type": "integer", + "title": "Speaker" + }, + "name": "speaker", + "in": "query" + }, + { + "required": false, + "schema": { + "type": "string", + "title": "Core Version" + }, + "name": "core_version", + "in": "query" + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "items": { + "$ref": "#/components/schemas/AccentPhrase" + }, + "type": "array", + "title": "Accent Phrases" + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "items": { + "$ref": "#/components/schemas/AccentPhrase" + }, + "type": "array", + "title": "Response Mora Length Mora Length Post" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/mora_pitch": { + "post": { + "tags": [ + "クエリ編集" + ], + "summary": "アクセント句から音高を得る", + "operationId": "mora_pitch_mora_pitch_post", + "parameters": [ + { + "required": true, + "schema": { + "type": "integer", + "title": "Speaker" + }, + "name": "speaker", + "in": "query" + }, + { + "required": false, + "schema": { + "type": "string", + "title": "Core Version" + }, + "name": "core_version", + "in": "query" + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "items": { + "$ref": "#/components/schemas/AccentPhrase" + }, + "type": "array", + "title": "Accent Phrases" + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "items": { + "$ref": "#/components/schemas/AccentPhrase" + }, + "type": "array", + "title": "Response Mora Pitch Mora Pitch Post" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/synthesis": { + "post": { + "tags": [ + "音声合成" + ], + "summary": "音声合成する", + "operationId": "synthesis_synthesis_post", + "parameters": [ + { + "required": true, + "schema": { + "type": "integer", + "title": "Speaker" + }, + "name": "speaker", + "in": "query" + }, + { + "description": "疑問系のテキストが与えられたら語尾を自動調整する", + "required": false, + "schema": { + "type": "boolean", + "title": "Enable Interrogative Upspeak", + "description": "疑問系のテキストが与えられたら語尾を自動調整する", + "default": true + }, + "name": "enable_interrogative_upspeak", + "in": "query" + }, + { + "required": false, + "schema": { + "type": "string", + "title": "Core Version" + }, + "name": "core_version", + "in": "query" + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AudioQuery" + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "audio/wav": { + "schema": { + "type": "string", + "format": "binary" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/cancellable_synthesis": { + "post": { + "tags": [ + "音声合成" + ], + "summary": "音声合成する(キャンセル可能)", + "operationId": "cancellable_synthesis_cancellable_synthesis_post", + "parameters": [ + { + "required": true, + "schema": { + "type": "integer", + "title": "Speaker" + }, + "name": "speaker", + "in": "query" + }, + { + "required": false, + "schema": { + "type": "string", + "title": "Core Version" + }, + "name": "core_version", + "in": "query" + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AudioQuery" + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "audio/wav": { + "schema": { + "type": "string", + "format": "binary" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/multi_synthesis": { + "post": { + "tags": [ + "音声合成" + ], + "summary": "複数まとめて音声合成する", + "operationId": "multi_synthesis_multi_synthesis_post", + "parameters": [ + { + "required": true, + "schema": { + "type": "integer", + "title": "Speaker" + }, + "name": "speaker", + "in": "query" + }, + { + "required": false, + "schema": { + "type": "string", + "title": "Core Version" + }, + "name": "core_version", + "in": "query" + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "items": { + "$ref": "#/components/schemas/AudioQuery" + }, + "type": "array", + "title": "Queries" + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/zip": { + "schema": { + "type": "string", + "format": "binary" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/morphable_targets": { + "post": { + "tags": [ + "音声合成" + ], + "summary": "指定したスタイルに対してエンジン内の話者がモーフィングが可能か判定する", + "description": "指定されたベーススタイルに対してエンジン内の各話者がモーフィング機能を利用可能か返します。\nモーフィングの許可/禁止は`/speakers`の`speaker.supported_features.synthesis_morphing`に記載されています。\nプロパティが存在しない場合は、モーフィングが許可されているとみなします。\n返り値のスタイルIDはstring型なので注意。", + "operationId": "morphable_targets_morphable_targets_post", + "parameters": [ + { + "required": false, + "schema": { + "type": "string", + "title": "Core Version" + }, + "name": "core_version", + "in": "query" + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "items": { + "type": "integer" + }, + "type": "array", + "title": "Base Style Ids" + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "items": { + "additionalProperties": { + "$ref": "#/components/schemas/MorphableTargetInfo" + }, + "type": "object" + }, + "type": "array", + "title": "Response Morphable Targets Morphable Targets Post" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/synthesis_morphing": { + "post": { + "tags": [ + "音声合成" + ], + "summary": "2種類のスタイルでモーフィングした音声を合成する", + "description": "指定された2種類のスタイルで音声を合成、指定した割合でモーフィングした音声を得ます。\nモーフィングの割合は`morph_rate`で指定でき、0.0でベースのスタイル、1.0でターゲットのスタイルに近づきます。", + "operationId": "_synthesis_morphing_synthesis_morphing_post", + "parameters": [ + { + "required": true, + "schema": { + "type": "integer", + "title": "Base Speaker" + }, + "name": "base_speaker", + "in": "query" + }, + { + "required": true, + "schema": { + "type": "integer", + "title": "Target Speaker" + }, + "name": "target_speaker", + "in": "query" + }, + { + "required": true, + "schema": { + "type": "number", + "maximum": 1.0, + "minimum": 0.0, + "title": "Morph Rate" + }, + "name": "morph_rate", + "in": "query" + }, + { + "required": false, + "schema": { + "type": "string", + "title": "Core Version" + }, + "name": "core_version", + "in": "query" + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AudioQuery" + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "audio/wav": { + "schema": { + "type": "string", + "format": "binary" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/sing_frame_audio_query": { + "post": { + "tags": [ + "クエリ作成" + ], + "summary": "歌唱音声合成用のクエリを作成する", + "description": "歌唱音声合成用のクエリの初期値を得ます。ここで得られたクエリはそのまま歌唱音声合成に利用できます。各値の意味は`Schemas`を参照してください。", + "operationId": "sing_frame_audio_query_sing_frame_audio_query_post", + "parameters": [ + { + "required": true, + "schema": { + "type": "integer", + "title": "Speaker" + }, + "name": "speaker", + "in": "query" + }, + { + "required": false, + "schema": { + "type": "string", + "title": "Core Version" + }, + "name": "core_version", + "in": "query" + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Score" + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/FrameAudioQuery" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/frame_synthesis": { + "post": { + "tags": [ + "音声合成" + ], + "summary": "Frame Synthesis", + "description": "歌唱音声合成を行います。", + "operationId": "frame_synthesis_frame_synthesis_post", + "parameters": [ + { + "required": true, + "schema": { + "type": "integer", + "title": "Speaker" + }, + "name": "speaker", + "in": "query" + }, + { + "required": false, + "schema": { + "type": "string", + "title": "Core Version" + }, + "name": "core_version", + "in": "query" + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/FrameAudioQuery" + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "audio/wav": { + "schema": { + "type": "string", + "format": "binary" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/connect_waves": { + "post": { + "tags": [ + "その他" + ], + "summary": "base64エンコードされた複数のwavデータを一つに結合する", + "description": "base64エンコードされたwavデータを一纏めにし、wavファイルで返します。", + "operationId": "connect_waves_connect_waves_post", + "requestBody": { + "content": { + "application/json": { + "schema": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Waves" + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "audio/wav": { + "schema": { + "type": "string", + "format": "binary" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/presets": { + "get": { + "tags": [ + "その他" + ], + "summary": "Get Presets", + "description": "エンジンが保持しているプリセットの設定を返します", + "operationId": "get_presets_presets_get", + "responses": { + "200": { + "description": "プリセットのリスト", + "content": { + "application/json": { + "schema": { + "items": { + "$ref": "#/components/schemas/Preset" + }, + "type": "array", + "title": "Response Get Presets Presets Get" + } + } + } + } + } + } + }, + "/add_preset": { + "post": { + "tags": [ + "その他" + ], + "summary": "Add Preset", + "description": "新しいプリセットを追加します", + "operationId": "add_preset_add_preset_post", + "requestBody": { + "content": { + "application/json": { + "schema": { + "allOf": [ + { + "$ref": "#/components/schemas/Preset" + } + ], + "title": "Preset", + "description": "新しいプリセット。プリセットIDが既存のものと重複している場合は、新規のプリセットIDが採番されます。" + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "追加したプリセットのプリセットID", + "content": { + "application/json": { + "schema": { + "type": "integer", + "title": "Response Add Preset Add Preset Post" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/update_preset": { + "post": { + "tags": [ + "その他" + ], + "summary": "Update Preset", + "description": "既存のプリセットを更新します", + "operationId": "update_preset_update_preset_post", + "requestBody": { + "content": { + "application/json": { + "schema": { + "allOf": [ + { + "$ref": "#/components/schemas/Preset" + } + ], + "title": "Preset", + "description": "更新するプリセット。プリセットIDが更新対象と一致している必要があります。" + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "更新したプリセットのプリセットID", + "content": { + "application/json": { + "schema": { + "type": "integer", + "title": "Response Update Preset Update Preset Post" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/delete_preset": { + "post": { + "tags": [ + "その他" + ], + "summary": "Delete Preset", + "description": "既存のプリセットを削除します", + "operationId": "delete_preset_delete_preset_post", + "parameters": [ + { + "description": "削除するプリセットのプリセットID", + "required": true, + "schema": { + "type": "integer", + "title": "Id", + "description": "削除するプリセットのプリセットID" + }, + "name": "id", + "in": "query" + } + ], + "responses": { + "204": { + "description": "Successful Response" + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/version": { + "get": { + "tags": [ + "その他" + ], + "summary": "Version", + "operationId": "version_version_get", + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "type": "string", + "title": "Response Version Version Get" + } + } + } + } + } + } + }, + "/core_versions": { + "get": { + "tags": [ + "その他" + ], + "summary": "Core Versions", + "operationId": "core_versions_core_versions_get", + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Response Core Versions Core Versions Get" + } + } + } + } + } + } + }, + "/speakers": { + "get": { + "tags": [ + "その他" + ], + "summary": "Speakers", + "operationId": "speakers_speakers_get", + "parameters": [ + { + "required": false, + "schema": { + "type": "string", + "title": "Core Version" + }, + "name": "core_version", + "in": "query" + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "items": { + "$ref": "#/components/schemas/Speaker" + }, + "type": "array", + "title": "Response Speakers Speakers Get" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/speaker_info": { + "get": { + "tags": [ + "その他" + ], + "summary": "Speaker Info", + "description": "指定されたspeaker_uuidに関する情報をjson形式で返します。\n画像や音声はbase64エンコードされたものが返されます。", + "operationId": "speaker_info_speaker_info_get", + "parameters": [ + { + "required": true, + "schema": { + "type": "string", + "title": "Speaker Uuid" + }, + "name": "speaker_uuid", + "in": "query" + }, + { + "required": false, + "schema": { + "type": "string", + "title": "Core Version" + }, + "name": "core_version", + "in": "query" + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/SpeakerInfo" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/singers": { + "get": { + "tags": [ + "その他" + ], + "summary": "Singers", + "operationId": "singers_singers_get", + "parameters": [ + { + "required": false, + "schema": { + "type": "string", + "title": "Core Version" + }, + "name": "core_version", + "in": "query" + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "items": { + "$ref": "#/components/schemas/Speaker" + }, + "type": "array", + "title": "Response Singers Singers Get" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/singer_info": { + "get": { + "tags": [ + "その他" + ], + "summary": "Singer Info", + "description": "指定されたspeaker_uuidに関する情報をjson形式で返します。\n画像や音声はbase64エンコードされたものが返されます。", + "operationId": "singer_info_singer_info_get", + "parameters": [ + { + "required": true, + "schema": { + "type": "string", + "title": "Speaker Uuid" + }, + "name": "speaker_uuid", + "in": "query" + }, + { + "required": false, + "schema": { + "type": "string", + "title": "Core Version" + }, + "name": "core_version", + "in": "query" + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/SpeakerInfo" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/downloadable_libraries": { + "get": { + "tags": [ + "音声ライブラリ管理" + ], + "summary": "Downloadable Libraries", + "description": "ダウンロード可能な音声ライブラリの情報を返します。", + "operationId": "downloadable_libraries_downloadable_libraries_get", + "responses": { + "200": { + "description": "ダウンロード可能な音声ライブラリの情報リスト", + "content": { + "application/json": { + "schema": { + "items": { + "$ref": "#/components/schemas/DownloadableLibraryInfo" + }, + "type": "array", + "title": "Response Downloadable Libraries Downloadable Libraries Get" + } + } + } + } + } + } + }, + "/installed_libraries": { + "get": { + "tags": [ + "音声ライブラリ管理" + ], + "summary": "Installed Libraries", + "description": "インストールした音声ライブラリの情報を返します。", + "operationId": "installed_libraries_installed_libraries_get", + "responses": { + "200": { + "description": "インストールした音声ライブラリの情報", + "content": { + "application/json": { + "schema": { + "additionalProperties": { + "$ref": "#/components/schemas/InstalledLibraryInfo" + }, + "type": "object", + "title": "Response Installed Libraries Installed Libraries Get" + } + } + } + } + } + } + }, + "/install_library/{library_uuid}": { + "post": { + "tags": [ + "音声ライブラリ管理" + ], + "summary": "Install Library", + "description": "音声ライブラリをインストールします。\n音声ライブラリのZIPファイルをリクエストボディとして送信してください。", + "operationId": "install_library_install_library__library_uuid__post", + "parameters": [ + { + "description": "音声ライブラリのID", + "required": true, + "schema": { + "type": "string", + "title": "Library Uuid", + "description": "音声ライブラリのID" + }, + "name": "library_uuid", + "in": "path" + } + ], + "responses": { + "204": { + "description": "Successful Response" + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/uninstall_library/{library_uuid}": { + "post": { + "tags": [ + "音声ライブラリ管理" + ], + "summary": "Uninstall Library", + "description": "音声ライブラリをアンインストールします。", + "operationId": "uninstall_library_uninstall_library__library_uuid__post", + "parameters": [ + { + "description": "音声ライブラリのID", + "required": true, + "schema": { + "type": "string", + "title": "Library Uuid", + "description": "音声ライブラリのID" + }, + "name": "library_uuid", + "in": "path" + } + ], + "responses": { + "204": { + "description": "Successful Response" + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/initialize_speaker": { + "post": { + "tags": [ + "その他" + ], + "summary": "Initialize Speaker", + "description": "指定されたスタイルを初期化します。\n実行しなくても他のAPIは使用できますが、初回実行時に時間がかかることがあります。", + "operationId": "initialize_speaker_initialize_speaker_post", + "parameters": [ + { + "required": true, + "schema": { + "type": "integer", + "title": "Speaker" + }, + "name": "speaker", + "in": "query" + }, + { + "description": "既に初期化済みのスタイルの再初期化をスキップするかどうか", + "required": false, + "schema": { + "type": "boolean", + "title": "Skip Reinit", + "description": "既に初期化済みのスタイルの再初期化をスキップするかどうか", + "default": false + }, + "name": "skip_reinit", + "in": "query" + }, + { + "required": false, + "schema": { + "type": "string", + "title": "Core Version" + }, + "name": "core_version", + "in": "query" + } + ], + "responses": { + "204": { + "description": "Successful Response" + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/is_initialized_speaker": { + "get": { + "tags": [ + "その他" + ], + "summary": "Is Initialized Speaker", + "description": "指定されたスタイルが初期化されているかどうかを返します。", + "operationId": "is_initialized_speaker_is_initialized_speaker_get", + "parameters": [ + { + "required": true, + "schema": { + "type": "integer", + "title": "Speaker" + }, + "name": "speaker", + "in": "query" + }, + { + "required": false, + "schema": { + "type": "string", + "title": "Core Version" + }, + "name": "core_version", + "in": "query" + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "type": "boolean", + "title": "Response Is Initialized Speaker Is Initialized Speaker Get" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/user_dict": { + "get": { + "tags": [ + "ユーザー辞書" + ], + "summary": "Get User Dict Words", + "description": "ユーザー辞書に登録されている単語の一覧を返します。\n単語の表層形(surface)は正規化済みの物を返します。", + "operationId": "get_user_dict_words_user_dict_get", + "responses": { + "200": { + "description": "単語のUUIDとその詳細", + "content": { + "application/json": { + "schema": { + "additionalProperties": { + "$ref": "#/components/schemas/UserDictWord" + }, + "type": "object", + "title": "Response Get User Dict Words User Dict Get" + } + } + } + } + } + } + }, + "/user_dict_word": { + "post": { + "tags": [ + "ユーザー辞書" + ], + "summary": "Add User Dict Word", + "description": "ユーザー辞書に言葉を追加します。", + "operationId": "add_user_dict_word_user_dict_word_post", + "parameters": [ + { + "description": "言葉の表層形", + "required": true, + "schema": { + "type": "string", + "title": "Surface", + "description": "言葉の表層形" + }, + "name": "surface", + "in": "query" + }, + { + "description": "言葉の発音(カタカナ)", + "required": true, + "schema": { + "type": "string", + "title": "Pronunciation", + "description": "言葉の発音(カタカナ)" + }, + "name": "pronunciation", + "in": "query" + }, + { + "description": "アクセント型(音が下がる場所を指す)", + "required": true, + "schema": { + "type": "integer", + "title": "Accent Type", + "description": "アクセント型(音が下がる場所を指す)" + }, + "name": "accent_type", + "in": "query" + }, + { + "description": "PROPER_NOUN(固有名詞)、COMMON_NOUN(普通名詞)、VERB(動詞)、ADJECTIVE(形容詞)、SUFFIX(語尾)のいずれか", + "required": false, + "schema": { + "allOf": [ + { + "$ref": "#/components/schemas/WordTypes" + } + ], + "description": "PROPER_NOUN(固有名詞)、COMMON_NOUN(普通名詞)、VERB(動詞)、ADJECTIVE(形容詞)、SUFFIX(語尾)のいずれか" + }, + "name": "word_type", + "in": "query" + }, + { + "description": "単語の優先度(0から10までの整数)。数字が大きいほど優先度が高くなる。1から9までの値を指定することを推奨", + "required": false, + "schema": { + "type": "integer", + "maximum": 10.0, + "minimum": 0.0, + "title": "Priority", + "description": "単語の優先度(0から10までの整数)。数字が大きいほど優先度が高くなる。1から9までの値を指定することを推奨" + }, + "name": "priority", + "in": "query" + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "type": "string", + "title": "Response Add User Dict Word User Dict Word Post" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/user_dict_word/{word_uuid}": { + "put": { + "tags": [ + "ユーザー辞書" + ], + "summary": "Rewrite User Dict Word", + "description": "ユーザー辞書に登録されている言葉を更新します。", + "operationId": "rewrite_user_dict_word_user_dict_word__word_uuid__put", + "parameters": [ + { + "description": "更新する言葉のUUID", + "required": true, + "schema": { + "type": "string", + "title": "Word Uuid", + "description": "更新する言葉のUUID" + }, + "name": "word_uuid", + "in": "path" + }, + { + "description": "言葉の表層形", + "required": true, + "schema": { + "type": "string", + "title": "Surface", + "description": "言葉の表層形" + }, + "name": "surface", + "in": "query" + }, + { + "description": "言葉の発音(カタカナ)", + "required": true, + "schema": { + "type": "string", + "title": "Pronunciation", + "description": "言葉の発音(カタカナ)" + }, + "name": "pronunciation", + "in": "query" + }, + { + "description": "アクセント型(音が下がる場所を指す)", + "required": true, + "schema": { + "type": "integer", + "title": "Accent Type", + "description": "アクセント型(音が下がる場所を指す)" + }, + "name": "accent_type", + "in": "query" + }, + { + "description": "PROPER_NOUN(固有名詞)、COMMON_NOUN(普通名詞)、VERB(動詞)、ADJECTIVE(形容詞)、SUFFIX(語尾)のいずれか", + "required": false, + "schema": { + "allOf": [ + { + "$ref": "#/components/schemas/WordTypes" + } + ], + "description": "PROPER_NOUN(固有名詞)、COMMON_NOUN(普通名詞)、VERB(動詞)、ADJECTIVE(形容詞)、SUFFIX(語尾)のいずれか" + }, + "name": "word_type", + "in": "query" + }, + { + "description": "単語の優先度(0から10までの整数)。数字が大きいほど優先度が高くなる。1から9までの値を指定することを推奨。", + "required": false, + "schema": { + "type": "integer", + "maximum": 10.0, + "minimum": 0.0, + "title": "Priority", + "description": "単語の優先度(0から10までの整数)。数字が大きいほど優先度が高くなる。1から9までの値を指定することを推奨。" + }, + "name": "priority", + "in": "query" + } + ], + "responses": { + "204": { + "description": "Successful Response" + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + }, + "delete": { + "tags": [ + "ユーザー辞書" + ], + "summary": "Delete User Dict Word", + "description": "ユーザー辞書に登録されている言葉を削除します。", + "operationId": "delete_user_dict_word_user_dict_word__word_uuid__delete", + "parameters": [ + { + "description": "削除する言葉のUUID", + "required": true, + "schema": { + "type": "string", + "title": "Word Uuid", + "description": "削除する言葉のUUID" + }, + "name": "word_uuid", + "in": "path" + } + ], + "responses": { + "204": { + "description": "Successful Response" + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/import_user_dict": { + "post": { + "tags": [ + "ユーザー辞書" + ], + "summary": "Import User Dict Words", + "description": "他のユーザー辞書をインポートします。", + "operationId": "import_user_dict_words_import_user_dict_post", + "parameters": [ + { + "description": "重複したエントリがあった場合、上書きするかどうか", + "required": true, + "schema": { + "type": "boolean", + "title": "Override", + "description": "重複したエントリがあった場合、上書きするかどうか" + }, + "name": "override", + "in": "query" + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "additionalProperties": { + "$ref": "#/components/schemas/UserDictWord" + }, + "type": "object", + "title": "Import Dict Data", + "description": "インポートするユーザー辞書のデータ" + } + } + }, + "required": true + }, + "responses": { + "204": { + "description": "Successful Response" + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/supported_devices": { + "get": { + "tags": [ + "その他" + ], + "summary": "Supported Devices", + "operationId": "supported_devices_supported_devices_get", + "parameters": [ + { + "required": false, + "schema": { + "type": "string", + "title": "Core Version" + }, + "name": "core_version", + "in": "query" + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/SupportedDevicesInfo" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/engine_manifest": { + "get": { + "tags": [ + "その他" + ], + "summary": "Engine Manifest", + "operationId": "engine_manifest_engine_manifest_get", + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/EngineManifest" + } + } + } + } + } + } + }, + "/validate_kana": { + "post": { + "tags": [ + "その他" + ], + "summary": "テキストがAquesTalk 風記法に従っているか判定する", + "description": "テキストがAquesTalk 風記法に従っているかどうかを判定します。\n従っていない場合はエラーが返ります。", + "operationId": "validate_kana_validate_kana_post", + "parameters": [ + { + "description": "判定する対象の文字列", + "required": true, + "schema": { + "type": "string", + "title": "Text", + "description": "判定する対象の文字列" + }, + "name": "text", + "in": "query" + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "type": "boolean", + "title": "Response Validate Kana Validate Kana Post" + } + } + } + }, + "400": { + "description": "テキストが不正です", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ParseKanaBadRequest" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/setting": { + "get": { + "tags": [ + "設定" + ], + "summary": "Setting Get", + "description": "設定ページを返します。", + "operationId": "setting_get_setting_get", + "responses": { + "200": { + "description": "Successful Response" + } + } + }, + "post": { + "tags": [ + "設定" + ], + "summary": "Setting Post", + "description": "設定を更新します。", + "operationId": "setting_post_setting_post", + "requestBody": { + "content": { + "application/x-www-form-urlencoded": { + "schema": { + "$ref": "#/components/schemas/Body_setting_post_setting_post" + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "Successful Response" + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + } + }, + "components": { + "schemas": { + "AccentPhrase": { + "properties": { + "moras": { + "items": { + "$ref": "#/components/schemas/Mora" + }, + "type": "array", + "title": "モーラのリスト" + }, + "accent": { + "type": "integer", + "title": "アクセント箇所" + }, + "pause_mora": { + "allOf": [ + { + "$ref": "#/components/schemas/Mora" + } + ], + "title": "後ろに無音を付けるかどうか" + }, + "is_interrogative": { + "type": "boolean", + "title": "疑問系かどうか", + "default": false + } + }, + "type": "object", + "required": [ + "moras", + "accent" + ], + "title": "AccentPhrase", + "description": "アクセント句ごとの情報" + }, + "AudioQuery": { + "properties": { + "accent_phrases": { + "items": { + "$ref": "#/components/schemas/AccentPhrase" + }, + "type": "array", + "title": "アクセント句のリスト" + }, + "speedScale": { + "type": "number", + "title": "全体の話速" + }, + "pitchScale": { + "type": "number", + "title": "全体の音高" + }, + "intonationScale": { + "type": "number", + "title": "全体の抑揚" + }, + "volumeScale": { + "type": "number", + "title": "全体の音量" + }, + "prePhonemeLength": { + "type": "number", + "title": "音声の前の無音時間" + }, + "postPhonemeLength": { + "type": "number", + "title": "音声の後の無音時間" + }, + "pauseLength": { + "type": "number", + "title": "読点や括弧等の無音時間(絶対値)" + }, + "pauseLengthScale": { + "type": "number", + "title": "読点や括弧等の無音時間(倍率)" + }, + "outputSamplingRate": { + "type": "integer", + "title": "音声データの出力サンプリングレート" + }, + "outputStereo": { + "type": "boolean", + "title": "音声データをステレオ出力するか否か" + }, + "kana": { + "type": "string", + "title": "[読み取り専用]AquesTalk 風記法によるテキスト。音声合成用のクエリとしては無視される" + } + }, + "type": "object", + "required": [ + "accent_phrases", + "speedScale", + "pitchScale", + "intonationScale", + "volumeScale", + "prePhonemeLength", + "postPhonemeLength", + "pauseLength", + "pauseLengthScale", + "outputSamplingRate", + "outputStereo" + ], + "title": "AudioQuery", + "description": "音声合成用のクエリ" + }, + "Body_setting_post_setting_post": { + "properties": { + "cors_policy_mode": { + "$ref": "#/components/schemas/CorsPolicyMode" + }, + "allow_origin": { + "type": "string", + "title": "Allow Origin" + } + }, + "type": "object", + "required": [ + "cors_policy_mode" + ], + "title": "Body_setting_post_setting_post" + }, + "CorsPolicyMode": { + "type": "string", + "enum": [ + "all", + "localapps" + ], + "title": "CorsPolicyMode", + "description": "CORSの許可モード" + }, + "DownloadableLibraryInfo": { + "properties": { + "name": { + "type": "string", + "title": "音声ライブラリの名前" + }, + "uuid": { + "type": "string", + "title": "音声ライブラリのUUID" + }, + "version": { + "type": "string", + "title": "音声ライブラリのバージョン" + }, + "download_url": { + "type": "string", + "title": "音声ライブラリのダウンロードURL" + }, + "bytes": { + "type": "integer", + "title": "音声ライブラリのバイト数" + }, + "speakers": { + "items": { + "$ref": "#/components/schemas/LibrarySpeaker" + }, + "type": "array", + "title": "音声ライブラリに含まれる話者のリスト" + } + }, + "type": "object", + "required": [ + "name", + "uuid", + "version", + "download_url", + "bytes", + "speakers" + ], + "title": "DownloadableLibraryInfo", + "description": "ダウンロード可能な音声ライブラリの情報" + }, + "EngineManifest": { + "properties": { + "manifest_version": { + "type": "string", + "title": "マニフェストのバージョン" + }, + "name": { + "type": "string", + "title": "エンジン名" + }, + "brand_name": { + "type": "string", + "title": "ブランド名" + }, + "uuid": { + "type": "string", + "title": "エンジンのUUID" + }, + "url": { + "type": "string", + "title": "エンジンのURL" + }, + "icon": { + "type": "string", + "title": "エンジンのアイコンをBASE64エンコードしたもの" + }, + "default_sampling_rate": { + "type": "integer", + "title": "デフォルトのサンプリング周波数" + }, + "frame_rate": { + "type": "number", + "title": "エンジンのフレームレート" + }, + "terms_of_service": { + "type": "string", + "title": "エンジンの利用規約" + }, + "update_infos": { + "items": { + "$ref": "#/components/schemas/UpdateInfo" + }, + "type": "array", + "title": "エンジンのアップデート情報" + }, + "dependency_licenses": { + "items": { + "$ref": "#/components/schemas/LicenseInfo" + }, + "type": "array", + "title": "依存関係のライセンス情報" + }, + "supported_vvlib_manifest_version": { + "type": "string", + "title": "エンジンが対応するvvlibのバージョン" + }, + "supported_features": { + "allOf": [ + { + "$ref": "#/components/schemas/SupportedFeatures" + } + ], + "title": "エンジンが持つ機能" + } + }, + "type": "object", + "required": [ + "manifest_version", + "name", + "brand_name", + "uuid", + "url", + "icon", + "default_sampling_rate", + "frame_rate", + "terms_of_service", + "update_infos", + "dependency_licenses", + "supported_features" + ], + "title": "EngineManifest", + "description": "エンジン自体に関する情報" + }, + "FrameAudioQuery": { + "properties": { + "f0": { + "items": { + "type": "number" + }, + "type": "array", + "title": "フレームごとの基本周波数" + }, + "volume": { + "items": { + "type": "number" + }, + "type": "array", + "title": "フレームごとの音量" + }, + "phonemes": { + "items": { + "$ref": "#/components/schemas/FramePhoneme" + }, + "type": "array", + "title": "音素のリスト" + }, + "volumeScale": { + "type": "number", + "title": "全体の音量" + }, + "outputSamplingRate": { + "type": "integer", + "title": "音声データの出力サンプリングレート" + }, + "outputStereo": { + "type": "boolean", + "title": "音声データをステレオ出力するか否か" + } + }, + "type": "object", + "required": [ + "f0", + "volume", + "phonemes", + "volumeScale", + "outputSamplingRate", + "outputStereo" + ], + "title": "FrameAudioQuery", + "description": "フレームごとの音声合成用のクエリ" + }, + "FramePhoneme": { + "properties": { + "phoneme": { + "type": "string", + "title": "音素" + }, + "frame_length": { + "type": "integer", + "title": "音素のフレーム長" + } + }, + "type": "object", + "required": [ + "phoneme", + "frame_length" + ], + "title": "FramePhoneme", + "description": "音素の情報" + }, + "HTTPValidationError": { + "properties": { + "detail": { + "items": { + "$ref": "#/components/schemas/ValidationError" + }, + "type": "array", + "title": "Detail" + } + }, + "type": "object", + "title": "HTTPValidationError" + }, + "InstalledLibraryInfo": { + "properties": { + "name": { + "type": "string", + "title": "音声ライブラリの名前" + }, + "uuid": { + "type": "string", + "title": "音声ライブラリのUUID" + }, + "version": { + "type": "string", + "title": "音声ライブラリのバージョン" + }, + "download_url": { + "type": "string", + "title": "音声ライブラリのダウンロードURL" + }, + "bytes": { + "type": "integer", + "title": "音声ライブラリのバイト数" + }, + "speakers": { + "items": { + "$ref": "#/components/schemas/LibrarySpeaker" + }, + "type": "array", + "title": "音声ライブラリに含まれる話者のリスト" + }, + "uninstallable": { + "type": "boolean", + "title": "アンインストール可能かどうか" + } + }, + "type": "object", + "required": [ + "name", + "uuid", + "version", + "download_url", + "bytes", + "speakers", + "uninstallable" + ], + "title": "InstalledLibraryInfo", + "description": "インストール済み音声ライブラリの情報" + }, + "LibrarySpeaker": { + "properties": { + "speaker": { + "allOf": [ + { + "$ref": "#/components/schemas/Speaker" + } + ], + "title": "話者情報" + }, + "speaker_info": { + "allOf": [ + { + "$ref": "#/components/schemas/SpeakerInfo" + } + ], + "title": "話者の追加情報" + } + }, + "type": "object", + "required": [ + "speaker", + "speaker_info" + ], + "title": "LibrarySpeaker", + "description": "音声ライブラリに含まれる話者の情報" + }, + "LicenseInfo": { + "properties": { + "name": { + "type": "string", + "title": "依存ライブラリ名" + }, + "version": { + "type": "string", + "title": "依存ライブラリのバージョン" + }, + "license": { + "type": "string", + "title": "依存ライブラリのライセンス名" + }, + "text": { + "type": "string", + "title": "依存ライブラリのライセンス本文" + } + }, + "type": "object", + "required": [ + "name", + "text" + ], + "title": "LicenseInfo", + "description": "依存ライブラリのライセンス情報" + }, + "Mora": { + "properties": { + "text": { + "type": "string", + "title": "文字" + }, + "consonant": { + "type": "string", + "title": "子音の音素" + }, + "consonant_length": { + "type": "number", + "title": "子音の音長" + }, + "vowel": { + "type": "string", + "title": "母音の音素" + }, + "vowel_length": { + "type": "number", + "title": "母音の音長" + }, + "pitch": { + "type": "number", + "title": "音高" + } + }, + "type": "object", + "required": [ + "text", + "vowel", + "vowel_length", + "pitch" + ], + "title": "Mora", + "description": "モーラ(子音+母音)ごとの情報" + }, + "MorphableTargetInfo": { + "properties": { + "is_morphable": { + "type": "boolean", + "title": "指定した話者に対してモーフィングの可否" + } + }, + "type": "object", + "required": [ + "is_morphable" + ], + "title": "MorphableTargetInfo" + }, + "Note": { + "properties": { + "key": { + "type": "integer", + "title": "音階" + }, + "frame_length": { + "type": "integer", + "title": "音符のフレーム長" + }, + "lyric": { + "type": "string", + "title": "音符の歌詞" + } + }, + "type": "object", + "required": [ + "frame_length", + "lyric" + ], + "title": "Note", + "description": "音符ごとの情報" + }, + "ParseKanaBadRequest": { + "properties": { + "text": { + "type": "string", + "title": "エラーメッセージ" + }, + "error_name": { + "type": "string", + "title": "エラー名", + "description": "|name|description|\n|---|---|\n| UNKNOWN_TEXT | 判別できない読み仮名があります: {text} |\n| ACCENT_TOP | 句頭にアクセントは置けません: {text} |\n| ACCENT_TWICE | 1つのアクセント句に二つ以上のアクセントは置けません: {text} |\n| ACCENT_NOTFOUND | アクセントを指定していないアクセント句があります: {text} |\n| EMPTY_PHRASE | {position}番目のアクセント句が空白です |\n| INTERROGATION_MARK_NOT_AT_END | アクセント句末以外に「?」は置けません: {text} |\n| INFINITE_LOOP | 処理時に無限ループになってしまいました...バグ報告をお願いします。 |" + }, + "error_args": { + "additionalProperties": { + "type": "string" + }, + "type": "object", + "title": "エラーを起こした箇所" + } + }, + "type": "object", + "required": [ + "text", + "error_name", + "error_args" + ], + "title": "ParseKanaBadRequest" + }, + "Preset": { + "properties": { + "id": { + "type": "integer", + "title": "プリセットID" + }, + "name": { + "type": "string", + "title": "プリセット名" + }, + "speaker_uuid": { + "type": "string", + "title": "話者のUUID" + }, + "style_id": { + "type": "integer", + "title": "スタイルID" + }, + "speedScale": { + "type": "number", + "title": "全体の話速" + }, + "pitchScale": { + "type": "number", + "title": "全体の音高" + }, + "intonationScale": { + "type": "number", + "title": "全体の抑揚" + }, + "volumeScale": { + "type": "number", + "title": "全体の音量" + }, + "prePhonemeLength": { + "type": "number", + "title": "音声の前の無音時間" + }, + "postPhonemeLength": { + "type": "number", + "title": "音声の後の無音時間" + }, + "pauseLength": { + "type": "number", + "title": "読点や括弧等の無音時間(絶対値)" + }, + "pauseLengthScale": { + "type": "number", + "title": "読点や括弧等の無音時間(倍率)" + } + }, + "type": "object", + "required": [ + "id", + "name", + "speaker_uuid", + "style_id", + "speedScale", + "pitchScale", + "intonationScale", + "volumeScale", + "prePhonemeLength", + "postPhonemeLength", + "pauseLength", + "pauseLengthScale" + ], + "title": "Preset", + "description": "プリセット情報" + }, + "Score": { + "properties": { + "notes": { + "items": { + "$ref": "#/components/schemas/Note" + }, + "type": "array", + "title": "音符のリスト" + } + }, + "type": "object", + "required": [ + "notes" + ], + "title": "Score", + "description": "楽譜情報" + }, + "Speaker": { + "properties": { + "supported_features": { + "allOf": [ + { + "$ref": "#/components/schemas/SpeakerSupportedFeatures" + } + ], + "title": "話者の対応機能" + }, + "name": { + "type": "string", + "title": "名前" + }, + "speaker_uuid": { + "type": "string", + "title": "話者のUUID" + }, + "styles": { + "items": { + "$ref": "#/components/schemas/SpeakerStyle" + }, + "type": "array", + "title": "スタイルの一覧" + }, + "version": { + "type": "string", + "title": "Version", + "default": "話者のバージョン" + } + }, + "type": "object", + "required": [ + "name", + "speaker_uuid", + "styles" + ], + "title": "Speaker", + "description": "話者情報" + }, + "SpeakerInfo": { + "properties": { + "policy": { + "type": "string", + "title": "policy.md" + }, + "portrait": { + "type": "string", + "title": "portrait.pngをbase64エンコードしたもの" + }, + "style_infos": { + "items": { + "$ref": "#/components/schemas/StyleInfo" + }, + "type": "array", + "title": "スタイルの追加情報" + } + }, + "type": "object", + "required": [ + "policy", + "portrait", + "style_infos" + ], + "title": "SpeakerInfo", + "description": "話者の追加情報" + }, + "SpeakerStyle": { + "properties": { + "name": { + "type": "string", + "title": "スタイル名" + }, + "id": { + "type": "integer", + "title": "スタイルID" + }, + "type": { + "type": "string", + "enum": [ + "talk", + "singing_teacher", + "frame_decode", + "sing" + ], + "title": "スタイルの種類。talk:音声合成クエリの作成と音声合成が可能。singing_teacher:歌唱音声合成用のクエリの作成が可能。frame_decode:歌唱音声合成が可能。sing:歌唱音声合成用のクエリの作成と歌唱音声合成が可能。", + "default": "talk" + } + }, + "type": "object", + "required": [ + "name", + "id" + ], + "title": "SpeakerStyle", + "description": "話者のスタイル情報" + }, + "SpeakerSupportPermittedSynthesisMorphing": { + "type": "string", + "enum": [ + "ALL", + "SELF_ONLY", + "NOTHING" + ], + "title": "SpeakerSupportPermittedSynthesisMorphing", + "description": "An enumeration." + }, + "SpeakerSupportedFeatures": { + "properties": { + "permitted_synthesis_morphing": { + "allOf": [ + { + "$ref": "#/components/schemas/SpeakerSupportPermittedSynthesisMorphing" + } + ], + "title": "モーフィング機能への対応", + "default": "ALL" + } + }, + "type": "object", + "title": "SpeakerSupportedFeatures", + "description": "話者の対応機能の情報" + }, + "StyleInfo": { + "properties": { + "id": { + "type": "integer", + "title": "スタイルID" + }, + "icon": { + "type": "string", + "title": "当該スタイルのアイコンをbase64エンコードしたもの" + }, + "portrait": { + "type": "string", + "title": "当該スタイルのportrait.pngをbase64エンコードしたもの" + }, + "voice_samples": { + "items": { + "type": "string" + }, + "type": "array", + "title": "voice_sampleのwavファイルをbase64エンコードしたもの" + } + }, + "type": "object", + "required": [ + "id", + "icon", + "voice_samples" + ], + "title": "StyleInfo", + "description": "スタイルの追加情報" + }, + "SupportedDevicesInfo": { + "properties": { + "cpu": { + "type": "boolean", + "title": "CPUに対応しているか" + }, + "cuda": { + "type": "boolean", + "title": "CUDA(Nvidia GPU)に対応しているか" + }, + "dml": { + "type": "boolean", + "title": "DirectML(Nvidia GPU/Radeon GPU等)に対応しているか" + } + }, + "type": "object", + "required": [ + "cpu", + "cuda", + "dml" + ], + "title": "SupportedDevicesInfo", + "description": "対応しているデバイスの情報" + }, + "SupportedFeatures": { + "properties": { + "adjust_mora_pitch": { + "type": "boolean", + "title": "モーラごとの音高の調整" + }, + "adjust_phoneme_length": { + "type": "boolean", + "title": "音素ごとの長さの調整" + }, + "adjust_speed_scale": { + "type": "boolean", + "title": "全体の話速の調整" + }, + "adjust_pitch_scale": { + "type": "boolean", + "title": "全体の音高の調整" + }, + "adjust_intonation_scale": { + "type": "boolean", + "title": "全体の抑揚の調整" + }, + "adjust_volume_scale": { + "type": "boolean", + "title": "全体の音量の調整" + }, + "interrogative_upspeak": { + "type": "boolean", + "title": "疑問文の自動調整" + }, + "synthesis_morphing": { + "type": "boolean", + "title": "2種類のスタイルでモーフィングした音声を合成" + }, + "sing": { + "type": "boolean", + "title": "歌唱音声合成" + }, + "manage_library": { + "type": "boolean", + "title": "音声ライブラリのインストール・アンインストール" + } + }, + "type": "object", + "required": [ + "adjust_mora_pitch", + "adjust_phoneme_length", + "adjust_speed_scale", + "adjust_pitch_scale", + "adjust_intonation_scale", + "adjust_volume_scale", + "interrogative_upspeak", + "synthesis_morphing" + ], + "title": "SupportedFeatures", + "description": "エンジンが持つ機能の一覧" + }, + "UpdateInfo": { + "properties": { + "version": { + "type": "string", + "title": "エンジンのバージョン名" + }, + "descriptions": { + "items": { + "type": "string" + }, + "type": "array", + "title": "アップデートの詳細についての説明" + }, + "contributors": { + "items": { + "type": "string" + }, + "type": "array", + "title": "貢献者名" + } + }, + "type": "object", + "required": [ + "version", + "descriptions" + ], + "title": "UpdateInfo", + "description": "エンジンのアップデート情報" + }, + "UserDictWord": { + "properties": { + "surface": { + "type": "string", + "title": "表層形" + }, + "priority": { + "type": "integer", + "maximum": 10.0, + "minimum": 0.0, + "title": "優先度" + }, + "context_id": { + "type": "integer", + "title": "文脈ID", + "default": 1348 + }, + "part_of_speech": { + "type": "string", + "title": "品詞" + }, + "part_of_speech_detail_1": { + "type": "string", + "title": "品詞細分類1" + }, + "part_of_speech_detail_2": { + "type": "string", + "title": "品詞細分類2" + }, + "part_of_speech_detail_3": { + "type": "string", + "title": "品詞細分類3" + }, + "inflectional_type": { + "type": "string", + "title": "活用型" + }, + "inflectional_form": { + "type": "string", + "title": "活用形" + }, + "stem": { + "type": "string", + "title": "原形" + }, + "yomi": { + "type": "string", + "title": "読み" + }, + "pronunciation": { + "type": "string", + "title": "発音" + }, + "accent_type": { + "type": "integer", + "title": "アクセント型" + }, + "mora_count": { + "type": "integer", + "title": "モーラ数" + }, + "accent_associative_rule": { + "type": "string", + "title": "アクセント結合規則" + } + }, + "type": "object", + "required": [ + "surface", + "priority", + "part_of_speech", + "part_of_speech_detail_1", + "part_of_speech_detail_2", + "part_of_speech_detail_3", + "inflectional_type", + "inflectional_form", + "stem", + "yomi", + "pronunciation", + "accent_type", + "accent_associative_rule" + ], + "title": "UserDictWord", + "description": "辞書のコンパイルに使われる情報" + }, + "ValidationError": { + "properties": { + "loc": { + "items": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "integer" + } + ] + }, + "type": "array", + "title": "Location" + }, + "msg": { + "type": "string", + "title": "Message" + }, + "type": { + "type": "string", + "title": "Error Type" + } + }, + "type": "object", + "required": [ + "loc", + "msg", + "type" + ], + "title": "ValidationError" + }, + "WordTypes": { + "type": "string", + "enum": [ + "PROPER_NOUN", + "COMMON_NOUN", + "VERB", + "ADJECTIVE", + "SUFFIX" + ], + "title": "WordTypes", + "description": "fastapiでword_type引数を検証する時に使用するクラス" + }, + "VvlibManifest": { + "title": "VvlibManifest", + "description": "vvlib(VOICEVOX Library)に関する情報", + "type": "object", + "properties": { + "manifest_version": { + "title": "マニフェストバージョン", + "type": "string" + }, + "name": { + "title": "音声ライブラリ名", + "type": "string" + }, + "version": { + "title": "音声ライブラリバージョン", + "type": "string" + }, + "uuid": { + "title": "音声ライブラリのUUID", + "type": "string" + }, + "brand_name": { + "title": "エンジンのブランド名", + "type": "string" + }, + "engine_name": { + "title": "エンジン名", + "type": "string" + }, + "engine_uuid": { + "title": "エンジンのUUID", + "type": "string" + } + }, + "required": [ + "manifest_version", + "name", + "version", + "uuid", + "brand_name", + "engine_name", + "engine_uuid" + ] + }, + "BaseLibraryInfo": { + "title": "BaseLibraryInfo", + "description": "音声ライブラリの情報", + "type": "object", + "properties": { + "name": { + "title": "音声ライブラリの名前", + "type": "string" + }, + "uuid": { + "title": "音声ライブラリのUUID", + "type": "string" + }, + "version": { + "title": "音声ライブラリのバージョン", + "type": "string" + }, + "download_url": { + "title": "音声ライブラリのダウンロードURL", + "type": "string" + }, + "bytes": { + "title": "音声ライブラリのバイト数", + "type": "integer" + }, + "speakers": { + "title": "音声ライブラリに含まれる話者のリスト", + "type": "array", + "items": { + "$ref": "#/components/schemas/LibrarySpeaker" + } + } + }, + "required": [ + "name", + "uuid", + "version", + "download_url", + "bytes", + "speakers" + ] + } + } + } +} diff --git a/src/backend/electron/main.ts b/src/backend/electron/main.ts index 1889dee3ec..9f7d5d27cd 100644 --- a/src/backend/electron/main.ts +++ b/src/backend/electron/main.ts @@ -403,6 +403,7 @@ async function createWindow() { nodeIntegration: false, contextIsolation: true, sandbox: false, // TODO: 外しても問題ないか検証して外す + devTools: true, // 検証ツール有効 デバッグ時のみ }, icon: path.join(__static, "icon.png"), }); @@ -585,7 +586,7 @@ if (isMac) { Menu.setApplicationMenu(Menu.buildFromTemplate(menuTemplateForMac)); } else { if (!isDevelopment) { - Menu.setApplicationMenu(null); + //Menu.setApplicationMenu(null); // デバッグを有効にする場合、コメントアウト } } diff --git a/src/components/App.vue b/src/components/App.vue index 1dc3451b31..ff059d5d95 100644 --- a/src/components/App.vue +++ b/src/components/App.vue @@ -122,6 +122,7 @@ onMounted(async () => { engineIds = store.state.engineIds; } await store.dispatch("LOAD_USER_CHARACTER_ORDER"); + console.log("onMounted"); await store.dispatch("POST_ENGINE_START", { engineIds, }); diff --git a/src/components/Dialog/DictionaryManageDialog.vue b/src/components/Dialog/DictionaryManageDialog.vue index b646d45205..aeffd0cb5e 100644 --- a/src/components/Dialog/DictionaryManageDialog.vue +++ b/src/components/Dialog/DictionaryManageDialog.vue @@ -397,6 +397,7 @@ const setYomi = async (text: string, changeWord?: boolean) => { if (isOnlyHiraOrKana.value && text.length) { text = convertHiraToKana(text); text = convertLongVowel(text); + console.log("setYomi"); accentPhrase.value = ( await createUILockAction( store.dispatch("FETCH_ACCENT_PHRASES", { diff --git a/src/components/Dialog/SettingDialog.vue b/src/components/Dialog/SettingDialog.vue index 7f776502ae..50a07f1ed5 100644 --- a/src/components/Dialog/SettingDialog.vue +++ b/src/components/Dialog/SettingDialog.vue @@ -184,6 +184,51 @@ + +
無音時間の指定方法
+
+ + + 無音時間を一括指定する際のモードを選べます。 + + +
+ + + + + +
パラメータの引き継ぎ
store.state.engineIds); const engineInfos = computed(() => store.state.engineInfos); +// 新規 +// QBtnToggleはv-modelがの変更がsetに結びつく設計になってるみたい +// Vuexの変更がgetで反映される +// それらがcomputedによって自動反映 +const switchPauseLengthMode = computed({ + get: () => store.state.switchPauseLengthMode, + set: (switchPauseLengthMode: SwitchPauseLengthMode) => { + store.dispatch("SET_SWITCH_PAUSE_LENGTH_MODE", { + switchPauseLengthMode, + }); + }, +}); const inheritAudioInfoMode = computed(() => store.state.inheritAudioInfo); const activePointScrollMode = computed({ get: () => store.state.activePointScrollMode, diff --git a/src/components/Talk/AccentPhrase.vue b/src/components/Talk/AccentPhrase.vue index dcc82d72c7..f026f4c0e2 100644 --- a/src/components/Talk/AccentPhrase.vue +++ b/src/components/Talk/AccentPhrase.vue @@ -48,7 +48,7 @@ class="q-mb-sm pitch-cell" :style="{ 'grid-column': `${moraIndex * 2 + 1} / span 1` }" > - + - + - + { }); const handleChangePronounce = (newPronunciation: string) => { + console.log("handleChangePronounce"); let popUntilPause = false; newPronunciation = newPronunciation .replace(/,/g, "、") diff --git a/src/components/Talk/AudioCell.vue b/src/components/Talk/AudioCell.vue index a69fc56a6e..690542c947 100644 --- a/src/components/Talk/AudioCell.vue +++ b/src/components/Talk/AudioCell.vue @@ -307,6 +307,7 @@ watch( ); const pushAudioTextIfNeeded = async (event?: KeyboardEvent) => { + console.log("pushAudioTextIfNeeded"); if (event && event.isComposing) return; if (!willRemove.value && isChangeFlag.value && !willFocusOrBlur.value) { isChangeFlag.value = false; diff --git a/src/components/Talk/AudioDetail.vue b/src/components/Talk/AudioDetail.vue index f44aad85f0..957e886181 100644 --- a/src/components/Talk/AudioDetail.vue +++ b/src/components/Talk/AudioDetail.vue @@ -242,6 +242,7 @@ watch(accentPhrases, async () => { // audio play const play = async () => { + console.log("play in AudioDetail"); try { await store.dispatch("PLAY_AUDIO", { audioKey: props.activeAudioKey, diff --git a/src/components/Talk/AudioInfo.vue b/src/components/Talk/AudioInfo.vue index 8250cf3296..b3da96e3cd 100644 --- a/src/components/Talk/AudioInfo.vue +++ b/src/components/Talk/AudioInfo.vue @@ -324,14 +324,22 @@ const props = defineProps<{ }>(); const store = useStore(); + const { info } = createLogger("AudioInfo"); // accent phrase const uiLocked = computed(() => store.getters.UI_LOCKED); const audioItem = computed(() => store.state.audioItems[props.activeAudioKey]); + const query = computed(() => audioItem.value?.query); +// 文内無音の指定方式 "SCALE" || "ABSOLUTE" +// 折り返さないとESLintにおこられる +const switchPauseLengthMode = computed(() => { + return store.state.switchPauseLengthMode; +}); + const supportedFeatures = computed( () => (store.state.engineIds.some( @@ -353,126 +361,183 @@ const selectedAudioKeys = computed(() => ? store.getters.SELECTED_AUDIO_KEYS : [props.activeAudioKey], ); -const parameters = computed(() => [ - { - label: "話速", - slider: previewSliderHelper({ - modelValue: () => query.value?.speedScale ?? null, - disable: () => - uiLocked.value || supportedFeatures.value?.adjustSpeedScale === false, - max: SLIDER_PARAMETERS.SPEED.max, - min: SLIDER_PARAMETERS.SPEED.min, - step: SLIDER_PARAMETERS.SPEED.step, - scrollStep: SLIDER_PARAMETERS.SPEED.scrollStep, - scrollMinStep: SLIDER_PARAMETERS.SPEED.scrollMinStep, - onChange: (speedScale: number) => - store.dispatch("COMMAND_MULTI_SET_AUDIO_SPEED_SCALE", { - audioKeys: selectedAudioKeys.value, - speedScale, - }), - }), - action: "COMMAND_MULTI_SET_AUDIO_SPEED_SCALE", - key: "speedScale", - }, - { - label: "音高", - slider: previewSliderHelper({ - modelValue: () => query.value?.pitchScale ?? null, - disable: () => - uiLocked.value || supportedFeatures.value?.adjustPitchScale === false, - max: SLIDER_PARAMETERS.PITCH.max, - min: SLIDER_PARAMETERS.PITCH.min, - step: SLIDER_PARAMETERS.PITCH.step, - scrollStep: SLIDER_PARAMETERS.PITCH.scrollStep, - onChange: (pitchScale: number) => - store.dispatch("COMMAND_MULTI_SET_AUDIO_PITCH_SCALE", { - audioKeys: selectedAudioKeys.value, - pitchScale, - }), - }), - action: "COMMAND_MULTI_SET_AUDIO_PITCH_SCALE", - key: "pitchScale", - }, - { - label: "抑揚", - slider: previewSliderHelper({ - modelValue: () => query.value?.intonationScale ?? null, - disable: () => - uiLocked.value || - supportedFeatures.value?.adjustIntonationScale === false, - max: SLIDER_PARAMETERS.INTONATION.max, - min: SLIDER_PARAMETERS.INTONATION.min, - step: SLIDER_PARAMETERS.INTONATION.step, - scrollStep: SLIDER_PARAMETERS.INTONATION.scrollStep, - scrollMinStep: SLIDER_PARAMETERS.INTONATION.scrollMinStep, - onChange: (intonationScale: number) => - store.dispatch("COMMAND_MULTI_SET_AUDIO_INTONATION_SCALE", { - audioKeys: selectedAudioKeys.value, - intonationScale, - }), - }), - action: "COMMAND_MULTI_SET_AUDIO_INTONATION_SCALE", - key: "intonationScale", - }, - { - label: "音量", - slider: previewSliderHelper({ - modelValue: () => query.value?.volumeScale ?? null, - disable: () => - uiLocked.value || supportedFeatures.value?.adjustVolumeScale === false, - max: SLIDER_PARAMETERS.VOLUME.max, - min: SLIDER_PARAMETERS.VOLUME.min, - step: SLIDER_PARAMETERS.VOLUME.step, - scrollStep: SLIDER_PARAMETERS.VOLUME.scrollStep, - scrollMinStep: SLIDER_PARAMETERS.VOLUME.scrollMinStep, - onChange: (volumeScale: number) => - store.dispatch("COMMAND_MULTI_SET_AUDIO_VOLUME_SCALE", { - audioKeys: selectedAudioKeys.value, - volumeScale, - }), - }), - action: "COMMAND_MULTI_SET_AUDIO_VOLUME_SCALE", - key: "volumeScale", - }, - { - label: "開始無音", - slider: previewSliderHelper({ - modelValue: () => query.value?.prePhonemeLength ?? null, - disable: () => uiLocked.value, - max: SLIDER_PARAMETERS.PRE_PHONEME_LENGTH.max, - min: SLIDER_PARAMETERS.PRE_PHONEME_LENGTH.min, - step: SLIDER_PARAMETERS.PRE_PHONEME_LENGTH.step, - scrollStep: SLIDER_PARAMETERS.PRE_PHONEME_LENGTH.scrollStep, - scrollMinStep: SLIDER_PARAMETERS.PRE_PHONEME_LENGTH.scrollMinStep, - onChange: (prePhonemeLength: number) => - store.dispatch("COMMAND_MULTI_SET_AUDIO_PRE_PHONEME_LENGTH", { - audioKeys: selectedAudioKeys.value, - prePhonemeLength, - }), - }), - action: "COMMAND_MULTI_SET_AUDIO_PRE_PHONEME_LENGTH", - key: "prePhonemeLength", - }, - { - label: "終了無音", - slider: previewSliderHelper({ - modelValue: () => query.value?.postPhonemeLength ?? null, - disable: () => uiLocked.value, - max: SLIDER_PARAMETERS.POST_PHONEME_LENGTH.max, - min: SLIDER_PARAMETERS.POST_PHONEME_LENGTH.min, - step: SLIDER_PARAMETERS.POST_PHONEME_LENGTH.step, - scrollStep: SLIDER_PARAMETERS.POST_PHONEME_LENGTH.scrollStep, - scrollMinStep: SLIDER_PARAMETERS.POST_PHONEME_LENGTH.scrollMinStep, - onChange: (postPhonemeLength: number) => - store.dispatch("COMMAND_MULTI_SET_AUDIO_POST_PHONEME_LENGTH", { - audioKeys: selectedAudioKeys.value, - postPhonemeLength, - }), - }), - action: "COMMAND_MULTI_SET_AUDIO_POST_PHONEME_LENGTH", - key: "postPhonemeLength", - }, -]); + +const plParam: Parameter = { + label: "文内無音", + slider: previewSliderHelper({ + modelValue: () => query.value?.pauseLength ?? null, + disable: () => uiLocked.value, + max: SLIDER_PARAMETERS.PAUSE_LENGTH.max, + min: SLIDER_PARAMETERS.PAUSE_LENGTH.min, + step: SLIDER_PARAMETERS.PAUSE_LENGTH.step, + scrollStep: SLIDER_PARAMETERS.PAUSE_LENGTH.scrollStep, + scrollMinStep: SLIDER_PARAMETERS.PAUSE_LENGTH.scrollMinStep, + onChange: (pauseLength: number) => + store.dispatch("COMMAND_MULTI_SET_AUDIO_PAUSE_LENGTH", { + audioKeys: selectedAudioKeys.value, + pauseLength, + }), + }), + action: "COMMAND_MULTI_SET_AUDIO_PAUSE_LENGTH", + key: "pauseLength", +}; + +const plsParam: Parameter = { + label: "文内無音", + slider: previewSliderHelper({ + modelValue: () => query.value?.pauseLengthScale ?? null, + disable: () => uiLocked.value, + max: SLIDER_PARAMETERS.PAUSE_LENGTH_SCALE.max, + min: SLIDER_PARAMETERS.PAUSE_LENGTH_SCALE.min, + step: SLIDER_PARAMETERS.PAUSE_LENGTH_SCALE.step, + scrollStep: SLIDER_PARAMETERS.PAUSE_LENGTH_SCALE.scrollStep, + scrollMinStep: SLIDER_PARAMETERS.PAUSE_LENGTH_SCALE.scrollMinStep, + onChange: (pauseLengthScale: number) => + store.dispatch("COMMAND_MULTI_SET_AUDIO_PAUSE_LENGTH_SCALE", { + audioKeys: selectedAudioKeys.value, + pauseLengthScale, + }), + }), + action: "COMMAND_MULTI_SET_AUDIO_PAUSE_LENGTH", + key: "pauseLength", +}; + +// 文内無音はひとまず倍率verを表示 のち必要に応じ絶対値に切替 +// 泥臭くなっちゃったかも +const parameters = computed(() => { + const baseParam: Parameter[] = [ + { + label: "話速", + slider: previewSliderHelper({ + modelValue: () => query.value?.speedScale ?? null, + disable: () => + uiLocked.value || supportedFeatures.value?.adjustSpeedScale === false, + max: SLIDER_PARAMETERS.SPEED.max, + min: SLIDER_PARAMETERS.SPEED.min, + step: SLIDER_PARAMETERS.SPEED.step, + scrollStep: SLIDER_PARAMETERS.SPEED.scrollStep, + scrollMinStep: SLIDER_PARAMETERS.SPEED.scrollMinStep, + onChange: (speedScale: number) => + store.dispatch("COMMAND_MULTI_SET_AUDIO_SPEED_SCALE", { + audioKeys: selectedAudioKeys.value, + speedScale, + }), + }), + action: "COMMAND_MULTI_SET_AUDIO_SPEED_SCALE", + key: "speedScale", + }, + { + label: "音高", + slider: previewSliderHelper({ + modelValue: () => query.value?.pitchScale ?? null, + disable: () => + uiLocked.value || supportedFeatures.value?.adjustPitchScale === false, + max: SLIDER_PARAMETERS.PITCH.max, + min: SLIDER_PARAMETERS.PITCH.min, + step: SLIDER_PARAMETERS.PITCH.step, + scrollStep: SLIDER_PARAMETERS.PITCH.scrollStep, + onChange: (pitchScale: number) => + store.dispatch("COMMAND_MULTI_SET_AUDIO_PITCH_SCALE", { + audioKeys: selectedAudioKeys.value, + pitchScale, + }), + }), + action: "COMMAND_MULTI_SET_AUDIO_PITCH_SCALE", + key: "pitchScale", + }, + { + label: "抑揚", + slider: previewSliderHelper({ + modelValue: () => query.value?.intonationScale ?? null, + disable: () => + uiLocked.value || + supportedFeatures.value?.adjustIntonationScale === false, + max: SLIDER_PARAMETERS.INTONATION.max, + min: SLIDER_PARAMETERS.INTONATION.min, + step: SLIDER_PARAMETERS.INTONATION.step, + scrollStep: SLIDER_PARAMETERS.INTONATION.scrollStep, + scrollMinStep: SLIDER_PARAMETERS.INTONATION.scrollMinStep, + onChange: (intonationScale: number) => + store.dispatch("COMMAND_MULTI_SET_AUDIO_INTONATION_SCALE", { + audioKeys: selectedAudioKeys.value, + intonationScale, + }), + }), + action: "COMMAND_MULTI_SET_AUDIO_INTONATION_SCALE", + key: "intonationScale", + }, + { + label: "音量", + slider: previewSliderHelper({ + modelValue: () => query.value?.volumeScale ?? null, + disable: () => + uiLocked.value || + supportedFeatures.value?.adjustVolumeScale === false, + max: SLIDER_PARAMETERS.VOLUME.max, + min: SLIDER_PARAMETERS.VOLUME.min, + step: SLIDER_PARAMETERS.VOLUME.step, + scrollStep: SLIDER_PARAMETERS.VOLUME.scrollStep, + scrollMinStep: SLIDER_PARAMETERS.VOLUME.scrollMinStep, + onChange: (volumeScale: number) => + store.dispatch("COMMAND_MULTI_SET_AUDIO_VOLUME_SCALE", { + audioKeys: selectedAudioKeys.value, + volumeScale, + }), + }), + action: "COMMAND_MULTI_SET_AUDIO_VOLUME_SCALE", + key: "volumeScale", + }, + { + label: "開始無音", + slider: previewSliderHelper({ + modelValue: () => query.value?.prePhonemeLength ?? null, + disable: () => uiLocked.value, + max: SLIDER_PARAMETERS.PRE_PHONEME_LENGTH.max, + min: SLIDER_PARAMETERS.PRE_PHONEME_LENGTH.min, + step: SLIDER_PARAMETERS.PRE_PHONEME_LENGTH.step, + scrollStep: SLIDER_PARAMETERS.PRE_PHONEME_LENGTH.scrollStep, + scrollMinStep: SLIDER_PARAMETERS.PRE_PHONEME_LENGTH.scrollMinStep, + onChange: (prePhonemeLength: number) => + store.dispatch("COMMAND_MULTI_SET_AUDIO_PRE_PHONEME_LENGTH", { + audioKeys: selectedAudioKeys.value, + prePhonemeLength, + }), + }), + action: "COMMAND_MULTI_SET_AUDIO_PRE_PHONEME_LENGTH", + key: "prePhonemeLength", + }, + { + label: "終了無音", + slider: previewSliderHelper({ + modelValue: () => query.value?.postPhonemeLength ?? null, + disable: () => uiLocked.value, + max: SLIDER_PARAMETERS.POST_PHONEME_LENGTH.max, + min: SLIDER_PARAMETERS.POST_PHONEME_LENGTH.min, + step: SLIDER_PARAMETERS.POST_PHONEME_LENGTH.step, + scrollStep: SLIDER_PARAMETERS.POST_PHONEME_LENGTH.scrollStep, + scrollMinStep: SLIDER_PARAMETERS.POST_PHONEME_LENGTH.scrollMinStep, + onChange: (postPhonemeLength: number) => + store.dispatch("COMMAND_MULTI_SET_AUDIO_POST_PHONEME_LENGTH", { + audioKeys: selectedAudioKeys.value, + postPhonemeLength, + }), + }), + action: "COMMAND_MULTI_SET_AUDIO_POST_PHONEME_LENGTH", + key: "postPhonemeLength", + }, + switchPauseLengthMode.value === "SCALE" ? plsParam : plParam, + ]; + // こっからswitchPauseLengthModeの変更に伴って更新 + const newParam = switchPauseLengthMode.value === "SCALE" ? plsParam : plParam; + const index = baseParam.findIndex((param) => param.label === newParam.label); + if (index !== -1) { + baseParam[index] = newParam; + } else { + baseParam.push(newParam); + } + return baseParam; +}); + const handleParameterChange = ( parameter: Parameter, inputValue: string | number | null, @@ -507,6 +572,7 @@ const morphingTargetEngines = store.getters.MORPHING_SUPPORTED_ENGINES; // モーフィング可能なターゲット一覧を取得 watchEffect(() => { + // console.log("watchEffect"); if (audioItem.value != undefined) { store.dispatch("LOAD_MORPHABLE_TARGETS", { engineId: audioItem.value.voice.engineId, diff --git a/src/components/Talk/TalkEditor.vue b/src/components/Talk/TalkEditor.vue index cb11bd6e5b..861351b23b 100644 --- a/src/components/Talk/TalkEditor.vue +++ b/src/components/Talk/TalkEditor.vue @@ -512,15 +512,17 @@ watch(userOrderedCharacterInfos, (userOrderedCharacterInfos) => { // エンジン初期化後の処理 const isCompletedInitialStartup = ref(false); -// TODO: Vueっぽくないので解体する +// TODO: Vueっぽくないので解体する チョットマッテ onetimeWatch( () => props.isProjectFileLoaded, async (isProjectFileLoaded) => { + console.log("onetimeWatch"); if (isProjectFileLoaded == "waiting" || !props.isEnginesReady) return "continue"; if (!isProjectFileLoaded) { // 最初のAudioCellを作成 const audioItem = await store.dispatch("GENERATE_AUDIO_ITEM", {}); + console.log(audioItem); const newAudioKey = await store.dispatch("REGISTER_AUDIO_ITEM", { audioItem, }); diff --git a/src/domain/project/schema.ts b/src/domain/project/schema.ts index ca74e7987f..08d39bd201 100644 --- a/src/domain/project/schema.ts +++ b/src/domain/project/schema.ts @@ -34,6 +34,8 @@ const audioQuerySchema = z.object({ volumeScale: z.number(), prePhonemeLength: z.number(), postPhonemeLength: z.number(), + pauseLength: z.number(), + pauseLengthScale: z.number(), outputSamplingRate: z.union([z.number(), z.literal("engineDefault")]), outputStereo: z.boolean(), kana: z.string().optional(), diff --git a/src/openapi/apis/DefaultApi.ts b/src/openapi/apis/DefaultApi.ts index 0295755437..de92cc6177 100644 --- a/src/openapi/apis/DefaultApi.ts +++ b/src/openapi/apis/DefaultApi.ts @@ -5,7 +5,7 @@ * VOICEVOXの音声合成エンジンです。 * * The version of the OpenAPI document: latest - * + * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). * https://openapi-generator.tech @@ -254,7 +254,7 @@ export interface ValidateKanaValidateKanaPostRequest { /** * DefaultApi - interface - * + * * @export * @interface DefaultApiInterface */ @@ -262,10 +262,10 @@ export interface DefaultApiInterface { /** * テキストからアクセント句を得ます。 is_kanaが`true`のとき、テキストは次のAquesTalk 風記法で解釈されます。デフォルトは`false`です。 * 全てのカナはカタカナで記述される * アクセント句は`/`または`、`で区切る。`、`で区切った場合に限り無音区間が挿入される。 * カナの手前に`_`を入れるとそのカナは無声化される * アクセント位置を`\'`で指定する。全てのアクセント句にはアクセント位置を1つ指定する必要がある。 * アクセント句末に`?`(全角)を入れることにより疑問文の発音ができる。 * @summary テキストからアクセント句を得る - * @param {string} text - * @param {number} speaker - * @param {boolean} [isKana] - * @param {string} [coreVersion] + * @param {string} text + * @param {number} speaker + * @param {boolean} [isKana] + * @param {string} [coreVersion] * @param {*} [options] Override http request option. * @throws {RequiredError} * @memberof DefaultApiInterface @@ -281,7 +281,7 @@ export interface DefaultApiInterface { /** * 新しいプリセットを追加します * @summary Add Preset - * @param {Preset} preset + * @param {Preset} preset * @param {*} [options] Override http request option. * @throws {RequiredError} * @memberof DefaultApiInterface @@ -317,9 +317,9 @@ export interface DefaultApiInterface { /** * 音声合成用のクエリの初期値を得ます。ここで得られたクエリはそのまま音声合成に利用できます。各値の意味は`Schemas`を参照してください。 * @summary 音声合成用のクエリを作成する - * @param {string} text - * @param {number} speaker - * @param {string} [coreVersion] + * @param {string} text + * @param {number} speaker + * @param {string} [coreVersion] * @param {*} [options] Override http request option. * @throws {RequiredError} * @memberof DefaultApiInterface @@ -335,9 +335,9 @@ export interface DefaultApiInterface { /** * 音声合成用のクエリの初期値を得ます。ここで得られたクエリはそのまま音声合成に利用できます。各値の意味は`Schemas`を参照してください。 * @summary 音声合成用のクエリをプリセットを用いて作成する - * @param {string} text - * @param {number} presetId - * @param {string} [coreVersion] + * @param {string} text + * @param {number} presetId + * @param {string} [coreVersion] * @param {*} [options] Override http request option. * @throws {RequiredError} * @memberof DefaultApiInterface @@ -351,11 +351,11 @@ export interface DefaultApiInterface { audioQueryFromPresetAudioQueryFromPresetPost(requestParameters: AudioQueryFromPresetAudioQueryFromPresetPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise; /** - * + * * @summary 音声合成する(キャンセル可能) - * @param {number} speaker - * @param {AudioQuery} audioQuery - * @param {string} [coreVersion] + * @param {number} speaker + * @param {AudioQuery} audioQuery + * @param {string} [coreVersion] * @param {*} [options] Override http request option. * @throws {RequiredError} * @memberof DefaultApiInterface @@ -370,7 +370,7 @@ export interface DefaultApiInterface { /** * base64エンコードされたwavデータを一纏めにし、wavファイルで返します。 * @summary base64エンコードされた複数のwavデータを一つに結合する - * @param {Array} requestBody + * @param {Array} requestBody * @param {*} [options] Override http request option. * @throws {RequiredError} * @memberof DefaultApiInterface @@ -384,7 +384,7 @@ export interface DefaultApiInterface { connectWavesConnectWavesPost(requestParameters: ConnectWavesConnectWavesPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise; /** - * + * * @summary Core Versions * @param {*} [options] Override http request option. * @throws {RequiredError} @@ -445,7 +445,7 @@ export interface DefaultApiInterface { downloadableLibrariesDownloadableLibrariesGet(initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>; /** - * + * * @summary Engine Manifest * @param {*} [options] Override http request option. * @throws {RequiredError} @@ -461,9 +461,9 @@ export interface DefaultApiInterface { /** * 歌唱音声合成を行います。 * @summary Frame Synthesis - * @param {number} speaker - * @param {FrameAudioQuery} frameAudioQuery - * @param {string} [coreVersion] + * @param {number} speaker + * @param {FrameAudioQuery} frameAudioQuery + * @param {string} [coreVersion] * @param {*} [options] Override http request option. * @throws {RequiredError} * @memberof DefaultApiInterface @@ -510,7 +510,7 @@ export interface DefaultApiInterface { * 他のユーザー辞書をインポートします。 * @summary Import User Dict Words * @param {boolean} override 重複したエントリがあった場合、上書きするかどうか - * @param {{ [key: string]: UserDictWord; }} requestBody + * @param {{ [key: string]: UserDictWord; }} requestBody * @param {*} [options] Override http request option. * @throws {RequiredError} * @memberof DefaultApiInterface @@ -526,9 +526,9 @@ export interface DefaultApiInterface { /** * 指定されたスタイルを初期化します。 実行しなくても他のAPIは使用できますが、初回実行時に時間がかかることがあります。 * @summary Initialize Speaker - * @param {number} speaker + * @param {number} speaker * @param {boolean} [skipReinit] 既に初期化済みのスタイルの再初期化をスキップするかどうか - * @param {string} [coreVersion] + * @param {string} [coreVersion] * @param {*} [options] Override http request option. * @throws {RequiredError} * @memberof DefaultApiInterface @@ -575,8 +575,8 @@ export interface DefaultApiInterface { /** * 指定されたスタイルが初期化されているかどうかを返します。 * @summary Is Initialized Speaker - * @param {number} speaker - * @param {string} [coreVersion] + * @param {number} speaker + * @param {string} [coreVersion] * @param {*} [options] Override http request option. * @throws {RequiredError} * @memberof DefaultApiInterface @@ -590,11 +590,11 @@ export interface DefaultApiInterface { isInitializedSpeakerIsInitializedSpeakerGet(requestParameters: IsInitializedSpeakerIsInitializedSpeakerGetRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise; /** - * + * * @summary アクセント句から音高・音素長を得る - * @param {number} speaker - * @param {Array} accentPhrase - * @param {string} [coreVersion] + * @param {number} speaker + * @param {Array} accentPhrase + * @param {string} [coreVersion] * @param {*} [options] Override http request option. * @throws {RequiredError} * @memberof DefaultApiInterface @@ -607,11 +607,11 @@ export interface DefaultApiInterface { moraDataMoraDataPost(requestParameters: MoraDataMoraDataPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>; /** - * + * * @summary アクセント句から音素長を得る - * @param {number} speaker - * @param {Array} accentPhrase - * @param {string} [coreVersion] + * @param {number} speaker + * @param {Array} accentPhrase + * @param {string} [coreVersion] * @param {*} [options] Override http request option. * @throws {RequiredError} * @memberof DefaultApiInterface @@ -624,11 +624,11 @@ export interface DefaultApiInterface { moraLengthMoraLengthPost(requestParameters: MoraLengthMoraLengthPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>; /** - * + * * @summary アクセント句から音高を得る - * @param {number} speaker - * @param {Array} accentPhrase - * @param {string} [coreVersion] + * @param {number} speaker + * @param {Array} accentPhrase + * @param {string} [coreVersion] * @param {*} [options] Override http request option. * @throws {RequiredError} * @memberof DefaultApiInterface @@ -643,8 +643,8 @@ export interface DefaultApiInterface { /** * 指定されたベーススタイルに対してエンジン内の各話者がモーフィング機能を利用可能か返します。 モーフィングの許可/禁止は`/speakers`の`speaker.supported_features.synthesis_morphing`に記載されています。 プロパティが存在しない場合は、モーフィングが許可されているとみなします。 返り値のスタイルIDはstring型なので注意。 * @summary 指定したスタイルに対してエンジン内の話者がモーフィングが可能か判定する - * @param {Array} requestBody - * @param {string} [coreVersion] + * @param {Array} requestBody + * @param {string} [coreVersion] * @param {*} [options] Override http request option. * @throws {RequiredError} * @memberof DefaultApiInterface @@ -658,11 +658,11 @@ export interface DefaultApiInterface { morphableTargetsMorphableTargetsPost(requestParameters: MorphableTargetsMorphableTargetsPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>; /** - * + * * @summary 複数まとめて音声合成する - * @param {number} speaker - * @param {Array} audioQuery - * @param {string} [coreVersion] + * @param {number} speaker + * @param {Array} audioQuery + * @param {string} [coreVersion] * @param {*} [options] Override http request option. * @throws {RequiredError} * @memberof DefaultApiInterface @@ -713,8 +713,8 @@ export interface DefaultApiInterface { /** * 設定を更新します。 * @summary Setting Post - * @param {CorsPolicyMode} corsPolicyMode - * @param {string} [allowOrigin] + * @param {CorsPolicyMode} corsPolicyMode + * @param {string} [allowOrigin] * @param {*} [options] Override http request option. * @throws {RequiredError} * @memberof DefaultApiInterface @@ -730,9 +730,9 @@ export interface DefaultApiInterface { /** * 歌唱音声合成用のクエリの初期値を得ます。ここで得られたクエリはそのまま歌唱音声合成に利用できます。各値の意味は`Schemas`を参照してください。 * @summary 歌唱音声合成用のクエリを作成する - * @param {number} speaker - * @param {Score} score - * @param {string} [coreVersion] + * @param {number} speaker + * @param {Score} score + * @param {string} [coreVersion] * @param {*} [options] Override http request option. * @throws {RequiredError} * @memberof DefaultApiInterface @@ -746,11 +746,11 @@ export interface DefaultApiInterface { singFrameAudioQuerySingFrameAudioQueryPost(requestParameters: SingFrameAudioQuerySingFrameAudioQueryPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise; /** - * + * * @summary スコア・歌唱音声合成用のクエリからフレームごとの音量を得る - * @param {number} speaker - * @param {BodySingFrameVolumeSingFrameVolumePost} bodySingFrameVolumeSingFrameVolumePost - * @param {string} [coreVersion] + * @param {number} speaker + * @param {BodySingFrameVolumeSingFrameVolumePost} bodySingFrameVolumeSingFrameVolumePost + * @param {string} [coreVersion] * @param {*} [options] Override http request option. * @throws {RequiredError} * @memberof DefaultApiInterface @@ -765,8 +765,8 @@ export interface DefaultApiInterface { /** * 指定されたspeaker_uuidに関する情報をjson形式で返します。 画像や音声はbase64エンコードされたものが返されます。 * @summary Singer Info - * @param {string} speakerUuid - * @param {string} [coreVersion] + * @param {string} speakerUuid + * @param {string} [coreVersion] * @param {*} [options] Override http request option. * @throws {RequiredError} * @memberof DefaultApiInterface @@ -780,9 +780,9 @@ export interface DefaultApiInterface { singerInfoSingerInfoGet(requestParameters: SingerInfoSingerInfoGetRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise; /** - * + * * @summary Singers - * @param {string} [coreVersion] + * @param {string} [coreVersion] * @param {*} [options] Override http request option. * @throws {RequiredError} * @memberof DefaultApiInterface @@ -797,8 +797,8 @@ export interface DefaultApiInterface { /** * 指定されたspeaker_uuidに関する情報をjson形式で返します。 画像や音声はbase64エンコードされたものが返されます。 * @summary Speaker Info - * @param {string} speakerUuid - * @param {string} [coreVersion] + * @param {string} speakerUuid + * @param {string} [coreVersion] * @param {*} [options] Override http request option. * @throws {RequiredError} * @memberof DefaultApiInterface @@ -812,9 +812,9 @@ export interface DefaultApiInterface { speakerInfoSpeakerInfoGet(requestParameters: SpeakerInfoSpeakerInfoGetRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise; /** - * + * * @summary Speakers - * @param {string} [coreVersion] + * @param {string} [coreVersion] * @param {*} [options] Override http request option. * @throws {RequiredError} * @memberof DefaultApiInterface @@ -827,9 +827,9 @@ export interface DefaultApiInterface { speakersSpeakersGet(requestParameters: SpeakersSpeakersGetRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>; /** - * + * * @summary Supported Devices - * @param {string} [coreVersion] + * @param {string} [coreVersion] * @param {*} [options] Override http request option. * @throws {RequiredError} * @memberof DefaultApiInterface @@ -844,11 +844,11 @@ export interface DefaultApiInterface { /** * 指定された2種類のスタイルで音声を合成、指定した割合でモーフィングした音声を得ます。 モーフィングの割合は`morph_rate`で指定でき、0.0でベースのスタイル、1.0でターゲットのスタイルに近づきます。 * @summary 2種類のスタイルでモーフィングした音声を合成する - * @param {number} baseSpeaker - * @param {number} targetSpeaker - * @param {number} morphRate - * @param {AudioQuery} audioQuery - * @param {string} [coreVersion] + * @param {number} baseSpeaker + * @param {number} targetSpeaker + * @param {number} morphRate + * @param {AudioQuery} audioQuery + * @param {string} [coreVersion] * @param {*} [options] Override http request option. * @throws {RequiredError} * @memberof DefaultApiInterface @@ -862,12 +862,12 @@ export interface DefaultApiInterface { synthesisMorphingSynthesisMorphingPost(requestParameters: SynthesisMorphingSynthesisMorphingPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise; /** - * + * * @summary 音声合成する - * @param {number} speaker - * @param {AudioQuery} audioQuery + * @param {number} speaker + * @param {AudioQuery} audioQuery * @param {boolean} [enableInterrogativeUpspeak] 疑問系のテキストが与えられたら語尾を自動調整する - * @param {string} [coreVersion] + * @param {string} [coreVersion] * @param {*} [options] Override http request option. * @throws {RequiredError} * @memberof DefaultApiInterface @@ -898,7 +898,7 @@ export interface DefaultApiInterface { /** * 既存のプリセットを更新します * @summary Update Preset - * @param {Preset} preset + * @param {Preset} preset * @param {*} [options] Override http request option. * @throws {RequiredError} * @memberof DefaultApiInterface @@ -928,7 +928,7 @@ export interface DefaultApiInterface { validateKanaValidateKanaPost(requestParameters: ValidateKanaValidateKanaPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise; /** - * + * * @summary Version * @param {*} [options] Override http request option. * @throws {RequiredError} @@ -944,7 +944,7 @@ export interface DefaultApiInterface { } /** - * + * */ export class DefaultApi extends runtime.BaseAPI implements DefaultApiInterface { @@ -953,6 +953,7 @@ export class DefaultApi extends runtime.BaseAPI implements DefaultApiInterface { * テキストからアクセント句を得る */ async accentPhrasesAccentPhrasesPostRaw(requestParameters: AccentPhrasesAccentPhrasesPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>> { + console.log("accentPhrasesAccentPhrasesPostRaw"); if (requestParameters.text === null || requestParameters.text === undefined) { throw new runtime.RequiredError('text','Required parameter requestParameters.text was null or undefined when calling accentPhrasesAccentPhrasesPost.'); } @@ -996,6 +997,7 @@ export class DefaultApi extends runtime.BaseAPI implements DefaultApiInterface { * テキストからアクセント句を得る */ async accentPhrasesAccentPhrasesPost(requestParameters: AccentPhrasesAccentPhrasesPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + console.log("accentPhrasesAccentPhrasesPost"); const response = await this.accentPhrasesAccentPhrasesPostRaw(requestParameters, initOverrides); return await response.value(); } @@ -1005,6 +1007,7 @@ export class DefaultApi extends runtime.BaseAPI implements DefaultApiInterface { * Add Preset */ async addPresetAddPresetPostRaw(requestParameters: AddPresetAddPresetPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + console.log("addPresetAddPresetPostRaw"); if (requestParameters.preset === null || requestParameters.preset === undefined) { throw new runtime.RequiredError('preset','Required parameter requestParameters.preset was null or undefined when calling addPresetAddPresetPost.'); } @@ -1044,6 +1047,7 @@ export class DefaultApi extends runtime.BaseAPI implements DefaultApiInterface { * Add User Dict Word */ async addUserDictWordUserDictWordPostRaw(requestParameters: AddUserDictWordUserDictWordPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + console.log("addUserDictWordUserDictWordPostRaw"); if (requestParameters.surface === null || requestParameters.surface === undefined) { throw new runtime.RequiredError('surface','Required parameter requestParameters.surface was null or undefined when calling addUserDictWordUserDictWordPost.'); } @@ -1108,12 +1112,13 @@ export class DefaultApi extends runtime.BaseAPI implements DefaultApiInterface { * 音声合成用のクエリを作成する */ async audioQueryAudioQueryPostRaw(requestParameters: AudioQueryAudioQueryPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + console.log("audioQueryAudioQueryPostRaw"); if (requestParameters.text === null || requestParameters.text === undefined) { throw new runtime.RequiredError('text','Required parameter requestParameters.text was null or undefined when calling audioQueryAudioQueryPost.'); } if (requestParameters.speaker === null || requestParameters.speaker === undefined) { - throw new runtime.RequiredError('speaker','Required parameter requestParameters.speaker was null or undefined when calling audioQueryAudioQueryPost.'); + throw new runtime.RequiredError('speaker','Required parameter requestParameters.speaker was null or undefined when calling QueryPost.'); } const queryParameters: any = {}; @@ -1131,14 +1136,13 @@ export class DefaultApi extends runtime.BaseAPI implements DefaultApiInterface { } const headerParameters: runtime.HTTPHeaders = {}; - + console.log(queryParameters); const response = await this.request({ path: `/audio_query`, method: 'POST', headers: headerParameters, query: queryParameters, }, initOverrides); - return new runtime.JSONApiResponse(response, (jsonValue) => AudioQueryFromJSON(jsonValue)); } @@ -1147,6 +1151,7 @@ export class DefaultApi extends runtime.BaseAPI implements DefaultApiInterface { * 音声合成用のクエリを作成する */ async audioQueryAudioQueryPost(requestParameters: AudioQueryAudioQueryPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { + console.log("audioQueryAudioQueryPost"); const response = await this.audioQueryAudioQueryPostRaw(requestParameters, initOverrides); return await response.value(); } @@ -1156,6 +1161,7 @@ export class DefaultApi extends runtime.BaseAPI implements DefaultApiInterface { * 音声合成用のクエリをプリセットを用いて作成する */ async audioQueryFromPresetAudioQueryFromPresetPostRaw(requestParameters: AudioQueryFromPresetAudioQueryFromPresetPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + console.log("audioQueryFromPresetAudioQueryFromPresetPostRaw"); if (requestParameters.text === null || requestParameters.text === undefined) { throw new runtime.RequiredError('text','Required parameter requestParameters.text was null or undefined when calling audioQueryFromPresetAudioQueryFromPresetPost.'); } @@ -1203,6 +1209,7 @@ export class DefaultApi extends runtime.BaseAPI implements DefaultApiInterface { * 音声合成する(キャンセル可能) */ async cancellableSynthesisCancellableSynthesisPostRaw(requestParameters: CancellableSynthesisCancellableSynthesisPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + console.log("cancellableSynthesisCancellableSynthesisPostRaw"); if (requestParameters.speaker === null || requestParameters.speaker === undefined) { throw new runtime.RequiredError('speaker','Required parameter requestParameters.speaker was null or undefined when calling cancellableSynthesisCancellableSynthesisPost.'); } @@ -1249,6 +1256,7 @@ export class DefaultApi extends runtime.BaseAPI implements DefaultApiInterface { * base64エンコードされた複数のwavデータを一つに結合する */ async connectWavesConnectWavesPostRaw(requestParameters: ConnectWavesConnectWavesPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + console.log("connectWavesConnectWavesPostRaw"); if (requestParameters.requestBody === null || requestParameters.requestBody === undefined) { throw new runtime.RequiredError('requestBody','Required parameter requestParameters.requestBody was null or undefined when calling connectWavesConnectWavesPost.'); } @@ -1283,6 +1291,7 @@ export class DefaultApi extends runtime.BaseAPI implements DefaultApiInterface { * Core Versions */ async coreVersionsCoreVersionsGetRaw(initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>> { + console.log("coreVersionsCoreVersionsGetRaw"); const queryParameters: any = {}; const headerParameters: runtime.HTTPHeaders = {}; @@ -1310,6 +1319,7 @@ export class DefaultApi extends runtime.BaseAPI implements DefaultApiInterface { * Delete Preset */ async deletePresetDeletePresetPostRaw(requestParameters: DeletePresetDeletePresetPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + console.log("deletePresetDeletePresetPostRaw"); if (requestParameters.id === null || requestParameters.id === undefined) { throw new runtime.RequiredError('id','Required parameter requestParameters.id was null or undefined when calling deletePresetDeletePresetPost.'); } @@ -1345,6 +1355,7 @@ export class DefaultApi extends runtime.BaseAPI implements DefaultApiInterface { * Delete User Dict Word */ async deleteUserDictWordUserDictWordWordUuidDeleteRaw(requestParameters: DeleteUserDictWordUserDictWordWordUuidDeleteRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + console.log("deleteUserDictWordUserDictWordWordUuidDeleteRaw"); if (requestParameters.wordUuid === null || requestParameters.wordUuid === undefined) { throw new runtime.RequiredError('wordUuid','Required parameter requestParameters.wordUuid was null or undefined when calling deleteUserDictWordUserDictWordWordUuidDelete.'); } @@ -1376,6 +1387,7 @@ export class DefaultApi extends runtime.BaseAPI implements DefaultApiInterface { * Downloadable Libraries */ async downloadableLibrariesDownloadableLibrariesGetRaw(initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>> { + console.log("downloadableLibrariesDownloadableLibrariesGetRaw"); const queryParameters: any = {}; const headerParameters: runtime.HTTPHeaders = {}; @@ -1403,6 +1415,7 @@ export class DefaultApi extends runtime.BaseAPI implements DefaultApiInterface { * Engine Manifest */ async engineManifestEngineManifestGetRaw(initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + console.log("engineManifestEngineManifestGetRaw"); const queryParameters: any = {}; const headerParameters: runtime.HTTPHeaders = {}; @@ -1430,6 +1443,7 @@ export class DefaultApi extends runtime.BaseAPI implements DefaultApiInterface { * Frame Synthesis */ async frameSynthesisFrameSynthesisPostRaw(requestParameters: FrameSynthesisFrameSynthesisPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + console.log("frameSynthesisFrameSynthesisPostRaw"); if (requestParameters.speaker === null || requestParameters.speaker === undefined) { throw new runtime.RequiredError('speaker','Required parameter requestParameters.speaker was null or undefined when calling frameSynthesisFrameSynthesisPost.'); } @@ -1477,6 +1491,7 @@ export class DefaultApi extends runtime.BaseAPI implements DefaultApiInterface { * Get Presets */ async getPresetsPresetsGetRaw(initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>> { + console.log("getPresetsPresetsGetRaw"); const queryParameters: any = {}; const headerParameters: runtime.HTTPHeaders = {}; @@ -1505,6 +1520,7 @@ export class DefaultApi extends runtime.BaseAPI implements DefaultApiInterface { * Get User Dict Words */ async getUserDictWordsUserDictGetRaw(initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + console.log("getUserDictWordsUserDictGetRaw"); const queryParameters: any = {}; const headerParameters: runtime.HTTPHeaders = {}; @@ -1533,6 +1549,7 @@ export class DefaultApi extends runtime.BaseAPI implements DefaultApiInterface { * Import User Dict Words */ async importUserDictWordsImportUserDictPostRaw(requestParameters: ImportUserDictWordsImportUserDictPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + console.log("importUserDictWordsImportUserDictPostRaw"); if (requestParameters.override === null || requestParameters.override === undefined) { throw new runtime.RequiredError('override','Required parameter requestParameters.override was null or undefined when calling importUserDictWordsImportUserDictPost.'); } @@ -1575,6 +1592,7 @@ export class DefaultApi extends runtime.BaseAPI implements DefaultApiInterface { * Initialize Speaker */ async initializeSpeakerInitializeSpeakerPostRaw(requestParameters: InitializeSpeakerInitializeSpeakerPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + console.log("initializeSpeakerInitializeSpeakerPostRaw"); if (requestParameters.speaker === null || requestParameters.speaker === undefined) { throw new runtime.RequiredError('speaker','Required parameter requestParameters.speaker was null or undefined when calling initializeSpeakerInitializeSpeakerPost.'); } @@ -1618,6 +1636,7 @@ export class DefaultApi extends runtime.BaseAPI implements DefaultApiInterface { * Install Library */ async installLibraryInstallLibraryLibraryUuidPostRaw(requestParameters: InstallLibraryInstallLibraryLibraryUuidPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + console.log("installLibraryInstallLibraryLibraryUuidPostRaw"); if (requestParameters.libraryUuid === null || requestParameters.libraryUuid === undefined) { throw new runtime.RequiredError('libraryUuid','Required parameter requestParameters.libraryUuid was null or undefined when calling installLibraryInstallLibraryLibraryUuidPost.'); } @@ -1649,6 +1668,7 @@ export class DefaultApi extends runtime.BaseAPI implements DefaultApiInterface { * Installed Libraries */ async installedLibrariesInstalledLibrariesGetRaw(initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + console.log("installedLibrariesInstalledLibrariesGetRaw"); const queryParameters: any = {}; const headerParameters: runtime.HTTPHeaders = {}; @@ -1677,6 +1697,7 @@ export class DefaultApi extends runtime.BaseAPI implements DefaultApiInterface { * Is Initialized Speaker */ async isInitializedSpeakerIsInitializedSpeakerGetRaw(requestParameters: IsInitializedSpeakerIsInitializedSpeakerGetRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + console.log("isInitializedSpeakerIsInitializedSpeakerGetRaw"); if (requestParameters.speaker === null || requestParameters.speaker === undefined) { throw new runtime.RequiredError('speaker','Required parameter requestParameters.speaker was null or undefined when calling isInitializedSpeakerIsInitializedSpeakerGet.'); } @@ -1712,6 +1733,7 @@ export class DefaultApi extends runtime.BaseAPI implements DefaultApiInterface { * Is Initialized Speaker */ async isInitializedSpeakerIsInitializedSpeakerGet(requestParameters: IsInitializedSpeakerIsInitializedSpeakerGetRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { + console.log("isInitializedSpeakerIsInitializedSpeakerGet"); const response = await this.isInitializedSpeakerIsInitializedSpeakerGetRaw(requestParameters, initOverrides); return await response.value(); } @@ -1720,6 +1742,7 @@ export class DefaultApi extends runtime.BaseAPI implements DefaultApiInterface { * アクセント句から音高・音素長を得る */ async moraDataMoraDataPostRaw(requestParameters: MoraDataMoraDataPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>> { + console.log("moraDataMoraDataPostRaw"); if (requestParameters.speaker === null || requestParameters.speaker === undefined) { throw new runtime.RequiredError('speaker','Required parameter requestParameters.speaker was null or undefined when calling moraDataMoraDataPost.'); } @@ -1765,6 +1788,7 @@ export class DefaultApi extends runtime.BaseAPI implements DefaultApiInterface { * アクセント句から音素長を得る */ async moraLengthMoraLengthPostRaw(requestParameters: MoraLengthMoraLengthPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>> { + console.log("moraLengthMoraLengthPostRaw"); if (requestParameters.speaker === null || requestParameters.speaker === undefined) { throw new runtime.RequiredError('speaker','Required parameter requestParameters.speaker was null or undefined when calling moraLengthMoraLengthPost.'); } @@ -1810,6 +1834,7 @@ export class DefaultApi extends runtime.BaseAPI implements DefaultApiInterface { * アクセント句から音高を得る */ async moraPitchMoraPitchPostRaw(requestParameters: MoraPitchMoraPitchPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>> { + console.log("moraPitchMoraPitchPostRaw"); if (requestParameters.speaker === null || requestParameters.speaker === undefined) { throw new runtime.RequiredError('speaker','Required parameter requestParameters.speaker was null or undefined when calling moraPitchMoraPitchPost.'); } @@ -1856,6 +1881,7 @@ export class DefaultApi extends runtime.BaseAPI implements DefaultApiInterface { * 指定したスタイルに対してエンジン内の話者がモーフィングが可能か判定する */ async morphableTargetsMorphableTargetsPostRaw(requestParameters: MorphableTargetsMorphableTargetsPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>> { + // console.log("morphableTargetsMorphableTargetsPostRaw"); if (requestParameters.requestBody === null || requestParameters.requestBody === undefined) { throw new runtime.RequiredError('requestBody','Required parameter requestParameters.requestBody was null or undefined when calling morphableTargetsMorphableTargetsPost.'); } @@ -1886,6 +1912,7 @@ export class DefaultApi extends runtime.BaseAPI implements DefaultApiInterface { * 指定したスタイルに対してエンジン内の話者がモーフィングが可能か判定する */ async morphableTargetsMorphableTargetsPost(requestParameters: MorphableTargetsMorphableTargetsPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + // console.log("morphableTargetsMorphableTargetsPost"); const response = await this.morphableTargetsMorphableTargetsPostRaw(requestParameters, initOverrides); return await response.value(); } @@ -1894,6 +1921,7 @@ export class DefaultApi extends runtime.BaseAPI implements DefaultApiInterface { * 複数まとめて音声合成する */ async multiSynthesisMultiSynthesisPostRaw(requestParameters: MultiSynthesisMultiSynthesisPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + console.log("multiSynthesisMultiSynthesisPostRaw"); if (requestParameters.speaker === null || requestParameters.speaker === undefined) { throw new runtime.RequiredError('speaker','Required parameter requestParameters.speaker was null or undefined when calling multiSynthesisMultiSynthesisPost.'); } @@ -1940,6 +1968,7 @@ export class DefaultApi extends runtime.BaseAPI implements DefaultApiInterface { * Rewrite User Dict Word */ async rewriteUserDictWordUserDictWordWordUuidPutRaw(requestParameters: RewriteUserDictWordUserDictWordWordUuidPutRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + console.log("rewriteUserDictWordUserDictWordWordUuidPutRaw"); if (requestParameters.wordUuid === null || requestParameters.wordUuid === undefined) { throw new runtime.RequiredError('wordUuid','Required parameter requestParameters.wordUuid was null or undefined when calling rewriteUserDictWordUserDictWordWordUuidPut.'); } @@ -2003,6 +2032,7 @@ export class DefaultApi extends runtime.BaseAPI implements DefaultApiInterface { * Setting Get */ async settingGetSettingGetRaw(initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + console.log("settingGetSettingGetRaw"); const queryParameters: any = {}; const headerParameters: runtime.HTTPHeaders = {}; @@ -2030,6 +2060,7 @@ export class DefaultApi extends runtime.BaseAPI implements DefaultApiInterface { * Setting Post */ async settingPostSettingPostRaw(requestParameters: SettingPostSettingPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + console.log("settingPostSettingPostRaw"); if (requestParameters.corsPolicyMode === null || requestParameters.corsPolicyMode === undefined) { throw new runtime.RequiredError('corsPolicyMode','Required parameter requestParameters.corsPolicyMode was null or undefined when calling settingPostSettingPost.'); } @@ -2176,6 +2207,7 @@ export class DefaultApi extends runtime.BaseAPI implements DefaultApiInterface { * Singer Info */ async singerInfoSingerInfoGetRaw(requestParameters: SingerInfoSingerInfoGetRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + // console.log("singerInfoSingerInfoGetRaw"); if (requestParameters.speakerUuid === null || requestParameters.speakerUuid === undefined) { throw new runtime.RequiredError('speakerUuid','Required parameter requestParameters.speakerUuid was null or undefined when calling singerInfoSingerInfoGet.'); } @@ -2246,6 +2278,7 @@ export class DefaultApi extends runtime.BaseAPI implements DefaultApiInterface { * Speaker Info */ async speakerInfoSpeakerInfoGetRaw(requestParameters: SpeakerInfoSpeakerInfoGetRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + // console.log("speakerInfoSpeakerInfoGetRaw"); if (requestParameters.speakerUuid === null || requestParameters.speakerUuid === undefined) { throw new runtime.RequiredError('speakerUuid','Required parameter requestParameters.speakerUuid was null or undefined when calling speakerInfoSpeakerInfoGet.'); } @@ -2285,6 +2318,7 @@ export class DefaultApi extends runtime.BaseAPI implements DefaultApiInterface { * Speakers */ async speakersSpeakersGetRaw(requestParameters: SpeakersSpeakersGetRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>> { + console.log("speakersSpeakersGetRaw"); const queryParameters: any = {}; if (requestParameters.coreVersion !== undefined) { @@ -2346,6 +2380,7 @@ export class DefaultApi extends runtime.BaseAPI implements DefaultApiInterface { * 2種類のスタイルでモーフィングした音声を合成する */ async synthesisMorphingSynthesisMorphingPostRaw(requestParameters: SynthesisMorphingSynthesisMorphingPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + console.log("synthesisMorphingSynthesisMorphingPostRaw"); if (requestParameters.baseSpeaker === null || requestParameters.baseSpeaker === undefined) { throw new runtime.RequiredError('baseSpeaker','Required parameter requestParameters.baseSpeaker was null or undefined when calling synthesisMorphingSynthesisMorphingPost.'); } @@ -2408,6 +2443,7 @@ export class DefaultApi extends runtime.BaseAPI implements DefaultApiInterface { * 音声合成する */ async synthesisSynthesisPostRaw(requestParameters: SynthesisSynthesisPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + console.log("synthesisSynthesisPostRaw"); if (requestParameters.speaker === null || requestParameters.speaker === undefined) { throw new runtime.RequiredError('speaker','Required parameter requestParameters.speaker was null or undefined when calling synthesisSynthesisPost.'); } @@ -2449,6 +2485,7 @@ export class DefaultApi extends runtime.BaseAPI implements DefaultApiInterface { * 音声合成する */ async synthesisSynthesisPost(requestParameters: SynthesisSynthesisPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { + console.log("synthesisSynthesisPost"); const response = await this.synthesisSynthesisPostRaw(requestParameters, initOverrides); return await response.value(); } @@ -2489,6 +2526,7 @@ export class DefaultApi extends runtime.BaseAPI implements DefaultApiInterface { * Update Preset */ async updatePresetUpdatePresetPostRaw(requestParameters: UpdatePresetUpdatePresetPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + console.log("updatePresetUpdatePresetPostRaw"); if (requestParameters.preset === null || requestParameters.preset === undefined) { throw new runtime.RequiredError('preset','Required parameter requestParameters.preset was null or undefined when calling updatePresetUpdatePresetPost.'); } @@ -2528,6 +2566,7 @@ export class DefaultApi extends runtime.BaseAPI implements DefaultApiInterface { * テキストがAquesTalk 風記法に従っているか判定する */ async validateKanaValidateKanaPostRaw(requestParameters: ValidateKanaValidateKanaPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + console.log("validateKanaValidateKanaPostRaw"); if (requestParameters.text === null || requestParameters.text === undefined) { throw new runtime.RequiredError('text','Required parameter requestParameters.text was null or undefined when calling validateKanaValidateKanaPost.'); } diff --git a/src/openapi/models/AudioQuery.ts b/src/openapi/models/AudioQuery.ts index 6dfe8177e5..baab874e2a 100644 --- a/src/openapi/models/AudioQuery.ts +++ b/src/openapi/models/AudioQuery.ts @@ -5,7 +5,7 @@ * VOICEVOXの音声合成エンジンです。 * * The version of the OpenAPI document: latest - * + * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). * https://openapi-generator.tech @@ -27,61 +27,73 @@ import { */ export interface AudioQuery { /** - * + * * @type {Array} * @memberof AudioQuery */ accentPhrases: Array; /** - * + * * @type {number} * @memberof AudioQuery */ speedScale: number; /** - * + * * @type {number} * @memberof AudioQuery */ pitchScale: number; /** - * + * * @type {number} * @memberof AudioQuery */ intonationScale: number; /** - * + * * @type {number} * @memberof AudioQuery */ volumeScale: number; /** - * + * * @type {number} * @memberof AudioQuery */ prePhonemeLength: number; /** - * + * * @type {number} * @memberof AudioQuery */ postPhonemeLength: number; /** - * + * * @type {number} * @memberof AudioQuery */ + pauseLength: number; + /** + * + * @type {number} + * @memberof AudioQuery + */ + pauseLengthScale: number; + /** + * + * @type {number} + * @memberof AudioQuery + */ outputSamplingRate: number; /** - * + * * @type {boolean} * @memberof AudioQuery */ outputStereo: boolean; /** - * + * * @type {string} * @memberof AudioQuery */ @@ -100,6 +112,8 @@ export function instanceOfAudioQuery(value: object): boolean { isInstance = isInstance && "volumeScale" in value; isInstance = isInstance && "prePhonemeLength" in value; isInstance = isInstance && "postPhonemeLength" in value; + isInstance = isInstance && "pauseLength" in value; + isInstance = isInstance && "pauseLengthScale" in value; isInstance = isInstance && "outputSamplingRate" in value; isInstance = isInstance && "outputStereo" in value; @@ -115,7 +129,7 @@ export function AudioQueryFromJSONTyped(json: any, ignoreDiscriminator: boolean) return json; } return { - + 'accentPhrases': ((json['accent_phrases'] as Array).map(AccentPhraseFromJSON)), 'speedScale': json['speedScale'], 'pitchScale': json['pitchScale'], @@ -123,6 +137,8 @@ export function AudioQueryFromJSONTyped(json: any, ignoreDiscriminator: boolean) 'volumeScale': json['volumeScale'], 'prePhonemeLength': json['prePhonemeLength'], 'postPhonemeLength': json['postPhonemeLength'], + 'pauseLength': json['pauseLength'], + 'pauseLengthScale': json['pauseLengthScale'], 'outputSamplingRate': json['outputSamplingRate'], 'outputStereo': json['outputStereo'], 'kana': !exists(json, 'kana') ? undefined : json['kana'], @@ -137,7 +153,7 @@ export function AudioQueryToJSON(value?: AudioQuery | null): any { return null; } return { - + 'accent_phrases': ((value.accentPhrases as Array).map(AccentPhraseToJSON)), 'speedScale': value.speedScale, 'pitchScale': value.pitchScale, @@ -145,9 +161,10 @@ export function AudioQueryToJSON(value?: AudioQuery | null): any { 'volumeScale': value.volumeScale, 'prePhonemeLength': value.prePhonemeLength, 'postPhonemeLength': value.postPhonemeLength, + 'pauseLength': value.pauseLength, + 'pauseLengthScale': value.pauseLengthScale, 'outputSamplingRate': value.outputSamplingRate, 'outputStereo': value.outputStereo, 'kana': value.kana, }; } - diff --git a/src/openapi/models/Preset.ts b/src/openapi/models/Preset.ts index 4a7670ffab..e8a4e5c1d4 100644 --- a/src/openapi/models/Preset.ts +++ b/src/openapi/models/Preset.ts @@ -5,7 +5,7 @@ * VOICEVOXの音声合成エンジンです。 * * The version of the OpenAPI document: latest - * + * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). * https://openapi-generator.tech @@ -20,65 +20,77 @@ import { exists, mapValues } from '../runtime'; */ export interface Preset { /** - * + * * @type {number} * @memberof Preset */ id: number; /** - * + * * @type {string} * @memberof Preset */ name: string; /** - * + * * @type {string} * @memberof Preset */ speakerUuid: string; /** - * + * * @type {number} * @memberof Preset */ styleId: number; /** - * + * * @type {number} * @memberof Preset */ speedScale: number; /** - * + * * @type {number} * @memberof Preset */ pitchScale: number; /** - * + * * @type {number} * @memberof Preset */ intonationScale: number; /** - * + * * @type {number} * @memberof Preset */ volumeScale: number; /** - * + * * @type {number} * @memberof Preset */ prePhonemeLength: number; /** - * + * * @type {number} * @memberof Preset */ postPhonemeLength: number; + /** + * + * @type {number} + * @memberof Preset + */ + pauseLength: number; + /** + * + * @type {number} + * @memberof Preset + */ + pauseLengthScale: number; } /** @@ -96,6 +108,8 @@ export function instanceOfPreset(value: object): boolean { isInstance = isInstance && "volumeScale" in value; isInstance = isInstance && "prePhonemeLength" in value; isInstance = isInstance && "postPhonemeLength" in value; + isInstance = isInstance && "pauseLength" in value; + isInstance = isInstance && "pauseLengthScale" in value; return isInstance; } @@ -109,7 +123,7 @@ export function PresetFromJSONTyped(json: any, ignoreDiscriminator: boolean): Pr return json; } return { - + 'id': json['id'], 'name': json['name'], 'speakerUuid': json['speaker_uuid'], @@ -120,6 +134,8 @@ export function PresetFromJSONTyped(json: any, ignoreDiscriminator: boolean): Pr 'volumeScale': json['volumeScale'], 'prePhonemeLength': json['prePhonemeLength'], 'postPhonemeLength': json['postPhonemeLength'], + 'pauseLength': json['pauseLength'], + 'pauseLengthScale': json['pauseLengthScale'], }; } @@ -131,7 +147,7 @@ export function PresetToJSON(value?: Preset | null): any { return null; } return { - + 'id': value.id, 'name': value.name, 'speaker_uuid': value.speakerUuid, @@ -142,6 +158,7 @@ export function PresetToJSON(value?: Preset | null): any { 'volumeScale': value.volumeScale, 'prePhonemeLength': value.prePhonemeLength, 'postPhonemeLength': value.postPhonemeLength, + 'pauseLength': value.pauseLength, + 'pauseLengthScale': value.pauseLengthScale, }; } - diff --git a/src/store/audio.ts b/src/store/audio.ts index 45abaf0d51..db947396b5 100644 --- a/src/store/audio.ts +++ b/src/store/audio.ts @@ -66,6 +66,7 @@ function parseTextFile( userOrderedCharacterInfos: CharacterInfo[], initVoice?: Voice, ): AudioItem[] { + console.log("parseTextFile"); // きてない const name2Voice = new Map(); const uuid2Voice = new Map(); for (const defaultStyleId of defaultStyleIds) { @@ -435,6 +436,7 @@ export const audioStore = createPartialStore({ LOAD_MORPHABLE_TARGETS: { async action({ state, dispatch, commit }, { engineId, baseStyleId }) { + // console.log("LOAD_MORPHABLE_TARGETS"); if (!state.engineManifests[engineId].supportedFeatures?.synthesisMorphing) return; @@ -545,6 +547,7 @@ export const audioStore = createPartialStore({ * AudioItemに設定される話者(スタイルID)に対してエンジン側の初期化を行い、即座に音声合成ができるようにする。 */ async action({ commit, dispatch }, { engineId, audioKeys, styleId }) { + console.log("SETUP_SPEAKER"); const isInitialized = await dispatch("IS_INITIALIZED_ENGINE_SPEAKER", { engineId, styleId, @@ -640,6 +643,7 @@ export const audioStore = createPartialStore({ baseAudioItem?: AudioItem; }, ) { + console.log("GENERATE_AUDIO_ITEM"); //引数にbaseAudioItemが与えられた場合、baseAudioItemから話速等のパラメータを引き継いだAudioItemを返す //baseAudioItem.queryのうち、accentPhrasesとkanaは基本設定パラメータではないので引き継がない //baseAudioItemのうち、textとstyleIdは別途与えられるので引き継がない @@ -675,12 +679,13 @@ export const audioStore = createPartialStore({ engineId: voice.engineId, styleId: voice.styleId, }; - + // ここでAudioItem > query > pauseLengthにundefinedが入ってると思う const query = getters.IS_ENGINE_READY(voice.engineId) ? await dispatch("FETCH_AUDIO_QUERY", fetchQueryParams).catch( () => undefined, ) : undefined; + console.log(query); const newAudioItem: AudioItem = { text, voice }; if (query != undefined) { @@ -721,6 +726,9 @@ export const audioStore = createPartialStore({ baseAudioItem.query.prePhonemeLength; newAudioItem.query.postPhonemeLength = baseAudioItem.query.postPhonemeLength; + newAudioItem.query.pauseLength = baseAudioItem.query.pauseLength; + newAudioItem.query.pauseLengthScale = + baseAudioItem.query.pauseLengthScale; newAudioItem.query.outputSamplingRate = baseAudioItem.query.outputSamplingRate; newAudioItem.query.outputStereo = baseAudioItem.query.outputStereo; @@ -741,6 +749,7 @@ export const audioStore = createPartialStore({ prevAudioKey, }: { audioItem: AudioItem; prevAudioKey?: AudioKey }, ) { + console.log("REGISTER_AUDIO_ITEM"); const audioKey = generateAudioKey(); commit("INSERT_AUDIO_ITEM", { audioItem, audioKey, prevAudioKey }); return audioKey; @@ -760,6 +769,7 @@ export const audioStore = createPartialStore({ prevAudioKey: AudioKey | undefined; }, ) { + console.log("INSERT_AUDIO_ITEM"); const index = prevAudioKey != undefined ? state.audioKeys.indexOf(prevAudioKey) + 1 @@ -783,6 +793,7 @@ export const audioStore = createPartialStore({ prevAudioKey: AudioKey | undefined; }, ) { + console.log("INSERT_AUDIO_ITEMS"); const index = prevAudioKey != undefined ? state.audioKeys.indexOf(prevAudioKey) + 1 @@ -895,12 +906,45 @@ export const audioStore = createPartialStore({ postPhonemeLength, }: { audioKey: AudioKey; postPhonemeLength: number }, ) { + console.log("SET_AUDIO_POST_PHONEME_LENGTH"); const query = state.audioItems[audioKey].query; if (query == undefined) throw new Error("query == undefined"); query.postPhonemeLength = postPhonemeLength; }, }, + SET_AUDIO_PAUSE_LENGTH: { + mutation( + state, + { audioKey, pauseLength }: { audioKey: AudioKey; pauseLength: number }, + ) { + console.log("SET_AUDIO_PAUSE_LENGTH"); + const query = state.audioItems[audioKey].query; + console.log(query); + if (query == undefined) throw new Error("query == undefined"); + query.pauseLength = pauseLength; + }, + }, + + SET_AUDIO_PAUSE_LENGTH_SCALE: { + mutation( + state, + { + audioKey, + pauseLengthScale, + }: { + audioKey: AudioKey; + pauseLengthScale: number; + }, + ) { + console.log("SET_AUDIO_PAUSE_LENGTH_SCALE"); + const query = state.audioItems[audioKey].query; + console.log(query); + if (query == undefined) throw new Error("query == undefined"); + query.pauseLengthScale = pauseLengthScale; + }, + }, + SET_MORPHING_INFO: { mutation( state, @@ -933,6 +977,7 @@ export const audioStore = createPartialStore({ state, { audioKey, audioQuery }: { audioKey: AudioKey; audioQuery: AudioQuery }, ) { + console.log("SET_AUDIO_QUERY"); state.audioItems[audioKey].query = audioQuery; }, action( @@ -952,6 +997,7 @@ export const audioStore = createPartialStore({ styleId, }: { text: string; engineId: EngineId; styleId: StyleId }, ) { + console.log("FETCH_AUDIO_QUERY"); return dispatch("INSTANTIATE_ENGINE_CONNECTOR", { engineId, }) @@ -985,6 +1031,7 @@ export const audioStore = createPartialStore({ accentPhrases, }: { audioKey: AudioKey; accentPhrases: AccentPhrase[] }, ) { + console.log("SET_SINGLE_ACCENT_PHRASE"); const query = state.audioItems[audioKey].query; if (query == undefined) throw new Error("query == undefined"); query.accentPhrases = accentPhrases; @@ -1006,6 +1053,7 @@ export const audioStore = createPartialStore({ isKana?: boolean; }, ) { + console.log("FETCH_ACCENT_PHRASES"); return dispatch("INSTANTIATE_ENGINE_CONNECTOR", { engineId, }) @@ -1104,6 +1152,7 @@ export const audioStore = createPartialStore({ APPLY_AUDIO_PRESET: { mutation(state, { audioKey }: { audioKey: AudioKey }) { + console.log("APPLY_AUDIO_PRESET"); const audioItem = state.audioItems[audioKey]; if (!audioItem.presetKey) return; @@ -1230,7 +1279,9 @@ export const audioStore = createPartialStore({ GET_AUDIO_PLAY_OFFSETS: { action({ state }, { audioKey }: { audioKey: AudioKey }) { + console.log("GET_AUDIO_PLAY_OFFSETS"); const query = state.audioItems[audioKey].query; + console.log(query); const accentPhrases = query?.accentPhrases; if (query == undefined || accentPhrases == undefined) throw Error("query == undefined or accentPhrases == undefined"); @@ -1263,9 +1314,12 @@ export const audioStore = createPartialStore({ { dispatch, state }, { audioKey, ...options }: { audioKey: AudioKey; cacheOnly?: boolean }, ) { + console.log("FETCH_AUDIO"); + await console.log(state.audioItems[audioKey]); const audioItem: AudioItem = JSON.parse( JSON.stringify(state.audioItems[audioKey]), ); + await console.log(audioItem); // この時点ではまだpresetがmoraに反映されていない return dispatch("FETCH_AUDIO_FROM_AUDIO_ITEM", { audioItem, ...options, @@ -1279,6 +1333,7 @@ export const audioStore = createPartialStore({ { dispatch, state }, options: { audioItem: AudioItem; cacheOnly?: boolean }, ) => { + console.log("FETCH_AUDIO_FROM_AUDIO_ITEM"); const instance = await dispatch("INSTANTIATE_ENGINE_CONNECTOR", { engineId: options.audioItem.voice.engineId, }); @@ -1324,6 +1379,7 @@ export const audioStore = createPartialStore({ filePath?: string; }, ): Promise => { + console.log("GENERATE_AND_SAVE_AUDIO"); const defaultAudioFileName = getters.DEFAULT_AUDIO_FILE_NAME(audioKey); if (state.savingSetting.fixedExportEnabled) { filePath = path.join( @@ -1468,6 +1524,7 @@ export const audioStore = createPartialStore({ callback?: (finishedCount: number, totalCount: number) => void; }, ): Promise => { + console.log("GENERATE_AND_CONNECT_AND_SAVE_AUDIO"); const defaultFileName = `${getters.DEFAULT_PROJECT_FILE_BASE_NAME}.wav`; if (state.savingSetting.fixedExportEnabled) { @@ -1605,6 +1662,7 @@ export const audioStore = createPartialStore({ { state, getters }, { filePath }: { filePath?: string }, ): Promise => { + console.log("CONNECT_AND_EXPORT_TEXT"); const defaultFileName = `${getters.DEFAULT_PROJECT_FILE_BASE_NAME}.txt`; if (state.savingSetting.fixedExportEnabled) { filePath = path.join( @@ -1684,6 +1742,7 @@ export const audioStore = createPartialStore({ PLAY_AUDIO: { action: createUILockAction( async ({ commit, dispatch }, { audioKey }: { audioKey: AudioKey }) => { + console.log("PLAY_AUDIO"); await dispatch("STOP_AUDIO"); // 音声用意 @@ -1692,18 +1751,21 @@ export const audioStore = createPartialStore({ audioKey, nowGenerating: true, }); + console.log(`audioKey : ${audioKey}`); try { fetchAudioResult = await withProgress( dispatch("FETCH_AUDIO", { audioKey }), dispatch, ); + console.log(fetchAudioResult); } finally { + // console.log(fetchAudioResult); // 来てない commit("SET_AUDIO_NOW_GENERATING", { audioKey, nowGenerating: false, }); } - + console.log("PLAY_AUDIO:到達"); const { blob } = fetchAudioResult; return dispatch("PLAY_AUDIO_BLOB", { audioBlob: blob, @@ -1719,6 +1781,7 @@ export const audioStore = createPartialStore({ { getters, commit, dispatch }, { audioBlob, audioKey }: { audioBlob: Blob; audioKey?: AudioKey }, ) => { + console.log("PLAY_AUDIO_BLOB"); commit("SET_AUDIO_SOURCE", { audioBlob }); let offset: number | undefined; // 途中再生用の処理 @@ -1749,6 +1812,7 @@ export const audioStore = createPartialStore({ presetKey, }: { audioKey: AudioKey; presetKey: PresetKey | undefined }, ) { + console.log("SET_AUDIO_PRESET_KEY"); if (presetKey == undefined) { delete state.audioItems[audioKey].presetKey; } else { @@ -1905,6 +1969,7 @@ export const audioCommandStore = transformCommandStore( { state, commit, dispatch }, { audioKey, text }: { audioKey: AudioKey; text: string }, ) { + console.log("COMMAND_CHANGE_AUDIO_TEXT"); const engineId = state.audioItems[audioKey].voice.engineId; const styleId = state.audioItems[audioKey].voice.styleId; const query = state.audioItems[audioKey].query; @@ -1912,6 +1977,7 @@ export const audioCommandStore = transformCommandStore( enableMemoNotation: state.enableMemoNotation, enableRubyNotation: state.enableRubyNotation, }); + console.log(`skippedText : ${skippedText}`); try { if (query != undefined) { @@ -1923,6 +1989,8 @@ export const audioCommandStore = transformCommandStore( styleId, }, ); + await console.log(query); + await console.log(accentPhrases); // 読みの内容が変わっていなければテキストだけ変更 const isSameText = !isAccentPhrasesTextDifferent( @@ -1995,6 +2063,7 @@ export const audioCommandStore = transformCommandStore( >; }, ) { + console.log("COMMAND_MULTI_CHANGE_VOICE"); for (const [audioKey_, change] of Object.entries(payload.changes)) { // TypeScriptは`Object.entries`のKeyの型を`string`としてしまうので、`as`で型を指定する const audioKey = audioKey_ as AudioKey; @@ -2130,6 +2199,7 @@ export const audioCommandStore = transformCommandStore( accent, }: { audioKey: AudioKey; accentPhraseIndex: number; accent: number }, ) { + console.log("COMMAND_CHANGE_ACCENT"); const query = state.audioItems[audioKey].query; if (query != undefined) { const newAccentPhrases: AccentPhrase[] = JSON.parse( @@ -2183,6 +2253,7 @@ export const audioCommandStore = transformCommandStore( accentPhraseIndex: number; } & ({ isPause: false; moraIndex: number } | { isPause: true }), ) { + console.log("COMMAND_CHANGE_ACCENT_PHRASE_SPLIT"); const { audioKey, accentPhraseIndex } = payload; const query = state.audioItems[audioKey].query; @@ -2299,6 +2370,7 @@ export const audioCommandStore = transformCommandStore( accentPhraseIndex: number; }, ) { + console.log("COMMAND_DELETE_ACCENT_PHRASE"); const query = state.audioItems[audioKey].query; if (query == undefined) throw new Error("query == undefined"); @@ -2341,6 +2413,7 @@ export const audioCommandStore = transformCommandStore( popUntilPause: boolean; }, ) { + console.log("COMMAND_CHANGE_SINGLE_ACCENT_PHRASE"); const engineId = state.audioItems[audioKey].voice.engineId; const styleId = state.audioItems[audioKey].voice.styleId; @@ -2362,6 +2435,7 @@ export const audioCommandStore = transformCommandStore( // accent phraseの生成をリクエスト // 判別できない読み仮名が混じっていた場合400エラーが帰るのでfallback + console.log("COMMAND_CHANGE_SINGLE_ACCENT_PHRASE"); newAccentPhrasesSegment = await dispatch("FETCH_ACCENT_PHRASES", { text: pureKatakanaWithAccent, engineId, @@ -2436,6 +2510,7 @@ export const audioCommandStore = transformCommandStore( COMMAND_MULTI_RESET_MORA_PITCH_AND_LENGTH: { async action({ state, dispatch, commit }, { audioKeys }) { + console.log("COMMAND_MULTI_RESET_MORA_PITCH_AND_LENGTH"); for (const audioKey of audioKeys) { const engineId = state.audioItems[audioKey].voice.engineId; const styleId = state.audioItems[audioKey].voice.styleId; @@ -2462,6 +2537,7 @@ export const audioCommandStore = transformCommandStore( { state, dispatch, commit }, { audioKey, accentPhraseIndex }, ) { + console.log("COMMAND_RESET_SELECTED_MORA_PITCH_AND_LENGTH"); const engineId = state.audioItems[audioKey].voice.engineId; const styleId = state.audioItems[audioKey].voice.styleId; @@ -2520,6 +2596,7 @@ export const audioCommandStore = transformCommandStore( type: MoraDataType; }, ) { + console.log("COMMAND_SET_AUDIO_MORA_DATA_ACCENT_PHRASE"); const maxPitch = 6.5; const minPitch = 3; const maxMoraLength = 0.3; @@ -2717,6 +2794,46 @@ export const audioCommandStore = transformCommandStore( }, }, + COMMAND_MULTI_SET_AUDIO_PAUSE_LENGTH: { + mutation(draft, payload: { audioKeys: AudioKey[]; pauseLength: number }) { + for (const audioKey of payload.audioKeys) { + audioStore.mutations.SET_AUDIO_PAUSE_LENGTH(draft, { + audioKey, + pauseLength: payload.pauseLength, + }); + } + }, + action( + { commit }, + payload: { audioKeys: AudioKey[]; pauseLength: number }, + ) { + commit("COMMAND_MULTI_SET_AUDIO_PAUSE_LENGTH", payload); + }, + }, + + COMMAND_MULTI_SET_AUDIO_PAUSE_LENGTH_SCALE: { + mutation( + draft, + payload: { + audioKeys: AudioKey[]; + pauseLengthScale: number; + }, + ) { + for (const audioKey of payload.audioKeys) { + audioStore.mutations.SET_AUDIO_PAUSE_LENGTH_SCALE(draft, { + audioKey, + pauseLengthScale: payload.pauseLengthScale, + }); + } + }, + action( + { commit }, + payload: { audioKeys: AudioKey[]; pauseLengthScale: number }, + ) { + commit("COMMAND_MULTI_SET_AUDIO_PAUSE_LENGTH_SCALE", payload); + }, + }, + COMMAND_MULTI_SET_MORPHING_INFO: { mutation( draft, @@ -2783,6 +2900,7 @@ export const audioCommandStore = transformCommandStore( COMMAND_FULLY_APPLY_AUDIO_PRESET: { mutation(draft, { presetKey }: { presetKey: PresetKey }) { + console.log("COMMAND_FULLY_APPLY_AUDIO_PRESET"); const targetAudioKeys = draft.audioKeys.filter( (audioKey) => draft.audioItems[audioKey].presetKey === presetKey, ); @@ -2814,6 +2932,7 @@ export const audioCommandStore = transformCommandStore( { state, commit, dispatch, getters }, { filePath }: { filePath?: string }, ) => { + console.log("COMMAND_IMPORT_FROM_FILE"); if (!filePath) { filePath = await window.backend.showImportFileDialog({ title: "セリフ読み込み", @@ -2892,6 +3011,7 @@ export const audioCommandStore = transformCommandStore( voice: Voice; }, ) => { + console.log("COMMAND_PUT_TEXTS"); const audioKeyItemPairs: { audioKey: AudioKey; audioItem: AudioItem; diff --git a/src/store/audioGenerate.ts b/src/store/audioGenerate.ts index 7d9ca52b74..3de4d1be57 100644 --- a/src/store/audioGenerate.ts +++ b/src/store/audioGenerate.ts @@ -27,23 +27,35 @@ export async function fetchAudioFromAudioItem( audioItem: AudioItem; }, ): Promise { + console.log("fetchAudioFromAudioItem"); + // 試しにここで弄ってみる + // audioItem.query.accentPhrases[0].moras[0].consonantLength = 0.1; コンソールには出るがqueryでundefined + // 多分非同期が悪さしててこの時点ではまだaudioQueryのresponseは入ってない const engineId = audioItem.voice.engineId; const [id, audioQuery] = await generateUniqueIdAndQuery(state, audioItem); + await console.log(audioQuery); // preset未反映 + // audioQuery.accentPhrases[0].moras[0].vowelLength = 0.1; // まだ if (audioQuery == undefined) throw new Error("audioQuery is not defined for audioItem"); if (Object.prototype.hasOwnProperty.call(audioBlobCache, id)) { + console.log("check"); // 来てない const blob = audioBlobCache[id]; return { audioQuery, blob }; } - + // audioQuery.accentPhrases[0].moras[0].vowelLength = 0.1; // 反映確認 const speaker = audioItem.voice.styleId; - + // audioQuery.accentPhrases[0].moras[0].vowelLength = 0.1; // 反映確認 + // 何かしらの互換のための処理? const engineAudioQuery = convertAudioQueryFromEditorToEngine( audioQuery, state.engineManifests[engineId].defaultSamplingRate, ); + // audioQuery.accentPhrases[0].moras[0].vowelLength = 0.1; // 反映確認 + // マニュアル値の設定はどこでやってるんだろ audioQueryの前? + // console.log(audioQuery); + await console.log(engineAudioQuery); let blob: Blob; // FIXME: モーフィングが設定で無効化されていてもモーフィングが行われるので気づけるUIを作成する @@ -71,6 +83,7 @@ export async function generateLabFromAudioQuery( audioQuery: EditorAudioQuery, offset?: number, ) { + console.log("generateLabFromAudioQuery"); const speedScale = audioQuery.speedScale; let labString = ""; diff --git a/src/store/engine.ts b/src/store/engine.ts index 3e8823b99b..561575880a 100644 --- a/src/store/engine.ts +++ b/src/store/engine.ts @@ -202,6 +202,7 @@ export const engineStore = createPartialStore({ RESTART_ENGINES: { async action({ dispatch, commit }, { engineIds }) { + console.log("RESTART_ENGINES"); await Promise.all( engineIds.map(async (engineId) => { commit("SET_ENGINE_STATE", { engineId, engineState: "STARTING" }); @@ -230,6 +231,7 @@ export const engineStore = createPartialStore({ POST_ENGINE_START: { async action({ state, dispatch }, { engineIds }) { + console.log("POST_ENGINE_START"); await dispatch("GET_ALT_PORT_INFOS"); const result = await Promise.all( engineIds.map(async (engineId) => { @@ -311,6 +313,7 @@ export const engineStore = createPartialStore({ * 指定した話者(スタイルID)がエンジン側で初期化されているか */ async action({ dispatch }, { engineId, styleId }) { + console.log("IS_INITIALIZED_ENGINE_SPEAKER"); const isInitialized = await dispatch("INSTANTIATE_ENGINE_CONNECTOR", { engineId, }).then((instance) => diff --git a/src/store/preset.ts b/src/store/preset.ts index ac0bbf5561..94a16eb325 100644 --- a/src/store/preset.ts +++ b/src/store/preset.ts @@ -167,6 +167,7 @@ export const presetStore = createPartialStore({ presetKeys, }: { presetItems: Record; presetKeys: PresetKey[] }, ) { + console.log("SAVE_PRESET_CONFIG"); const result = await window.backend.setSetting("presets", { items: JSON.parse(JSON.stringify(presetItems)), keys: JSON.parse(JSON.stringify(presetKeys)), @@ -200,8 +201,8 @@ export const presetStore = createPartialStore({ CREATE_ALL_DEFAULT_PRESET: { async action({ state, dispatch, getters }) { + console.log("CREATE_ALL_DEFAULT_PRESET"); const voices = getters.GET_ALL_VOICES("talk"); - for (const voice of voices) { const voiceId = VoiceId(voice); const defaultPresetKey = state.defaultPresetKeys[voiceId]; @@ -211,7 +212,7 @@ export const presetStore = createPartialStore({ } const characterName = getters.VOICE_NAME(voice); - + console.log(`characterName : ${characterName}`); const presetData: Preset = { name: `デフォルト:${characterName}`, speedScale: 1.0, @@ -220,6 +221,8 @@ export const presetStore = createPartialStore({ volumeScale: 1.0, prePhonemeLength: 0.1, postPhonemeLength: 0.1, + pauseLength: 0.3, + pauseLengthScale: 1, }; const newPresetKey = await dispatch("ADD_PRESET", { presetData }); @@ -238,6 +241,7 @@ export const presetStore = createPartialStore({ context, { presetKey, presetData }: { presetData: Preset; presetKey: PresetKey }, ) { + console.log("UPDATE_PRESET"); const newPresetItems = { ...context.state.presetItems, [presetKey]: presetData, diff --git a/src/store/project.ts b/src/store/project.ts index b8fd91512d..0ad034d14c 100755 --- a/src/store/project.ts +++ b/src/store/project.ts @@ -187,6 +187,7 @@ export const projectStore = createPartialStore({ context, { filePath, confirm }: { filePath?: string; confirm?: boolean }, ) => { + console.log("LOAD_PROJECT_FILE"); if (!filePath) { // Select and load a project File. const ret = await window.backend.showProjectLoadDialog({ @@ -250,12 +251,17 @@ export const projectStore = createPartialStore({ } } for (const audioItemsKey in projectData.audioItems) { + console.log(`audioItemsKey : ${audioItemsKey}`); if (projectData.audioItems[audioItemsKey].query != null) { + console.log("query代入"); projectData.audioItems[audioItemsKey].query.volumeScale = 1; projectData.audioItems[audioItemsKey].query.prePhonemeLength = 0.1; projectData.audioItems[audioItemsKey].query.postPhonemeLength = 0.1; + projectData.audioItems[audioItemsKey].query.pauseLength = 0.1; + projectData.audioItems[audioItemsKey].query.pauseLengthScale = + 1; projectData.audioItems[audioItemsKey].query.outputSamplingRate = DEFAULT_SAMPLING_RATE; } @@ -459,6 +465,7 @@ export const projectStore = createPartialStore({ // Validation check // トークはvalidateTalkProjectで検証する // ソングはSET_SCOREの中の`isValidScore`関数で検証される + console.log("parsedProjectData"); const parsedProjectData = projectSchema.parse(projectData); validateTalkProject(parsedProjectData.talk); diff --git a/src/store/proxy.ts b/src/store/proxy.ts index 799ef3e069..784c82b3b0 100644 --- a/src/store/proxy.ts +++ b/src/store/proxy.ts @@ -13,6 +13,7 @@ const proxyStoreCreator = (_engineFactory: IEngineConnectorFactory) => { const proxyStore = createPartialStore({ INSTANTIATE_ENGINE_CONNECTOR: { action({ state }, payload) { + // console.log("INSTANTIATE_ENGINE_CONNECTOR"); const engineId = payload.engineId; const engineInfo: EngineInfo | undefined = state.engineInfos[engineId]; if (engineInfo == undefined) @@ -21,6 +22,7 @@ const proxyStoreCreator = (_engineFactory: IEngineConnectorFactory) => { ); const instance = _engineFactory.instance(engineInfo.host); + // console.log(instance); return Promise.resolve({ invoke: (v) => (arg) => // FIXME: anyを使わないようにする diff --git a/src/store/type.ts b/src/store/type.ts index d134eef477..2dd16d6d5f 100644 --- a/src/store/type.ts +++ b/src/store/type.ts @@ -34,6 +34,7 @@ import { UpdateInfo, Preset, MorphingInfo, + SwitchPauseLengthMode, ActivePointScrollMode, EngineInfo, ConfirmedTips, @@ -289,6 +290,14 @@ export type AudioStoreTypes = { mutation: { audioKey: AudioKey; postPhonemeLength: number }; }; + SET_AUDIO_PAUSE_LENGTH: { + mutation: { audioKey: AudioKey; pauseLength: number }; + }; + + SET_AUDIO_PAUSE_LENGTH_SCALE: { + mutation: { audioKey: AudioKey; pauseLengthScale: number }; + }; + LOAD_MORPHABLE_TARGETS: { action(payload: { engineId: EngineId; baseStyleId: StyleId }): void; }; @@ -628,6 +637,16 @@ export type AudioCommandStoreTypes = { action(payload: { audioKeys: AudioKey[]; postPhonemeLength: number }): void; }; + COMMAND_MULTI_SET_AUDIO_PAUSE_LENGTH: { + mutation: { audioKeys: AudioKey[]; pauseLength: number }; + action(payload: { audioKeys: AudioKey[]; pauseLength: number }): void; + }; + + COMMAND_MULTI_SET_AUDIO_PAUSE_LENGTH_SCALE: { + mutation: { audioKeys: AudioKey[]; pauseLengthScale: number }; + action(payload: { audioKeys: AudioKey[]; pauseLengthScale: number }): void; + }; + COMMAND_MULTI_SET_MORPHING_INFO: { mutation: { audioKeys: AudioKey[]; @@ -1625,6 +1644,7 @@ export type UiStoreState = { uiLockCount: number; dialogLockCount: number; reloadingLock: boolean; + switchPauseLengthMode: SwitchPauseLengthMode; inheritAudioInfo: boolean; activePointScrollMode: ActivePointScrollMode; isHelpDialogOpen: boolean; @@ -1765,6 +1785,11 @@ export type UiStoreTypes = { action(): void; }; + SET_SWITCH_PAUSE_LENGTH_MODE: { + mutation: { switchPauseLengthMode: SwitchPauseLengthMode }; + action(payload: { switchPauseLengthMode: SwitchPauseLengthMode }): void; + }; + SET_INHERIT_AUDIOINFO: { mutation: { inheritAudioInfo: boolean }; action(payload: { inheritAudioInfo: boolean }): void; diff --git a/src/store/ui.ts b/src/store/ui.ts index d83d9974db..b8a12730d3 100644 --- a/src/store/ui.ts +++ b/src/store/ui.ts @@ -7,6 +7,7 @@ import { UiStoreTypes, } from "./type"; import { createPartialStore } from "./vuex"; +import { SwitchPauseLengthMode } from "@/type/preload"; import { ActivePointScrollMode } from "@/type/preload"; import { CommonDialogOptions, @@ -53,6 +54,7 @@ export const uiStoreState: UiStoreState = { uiLockCount: 0, dialogLockCount: 0, reloadingLock: false, + switchPauseLengthMode: "SCALE", inheritAudioInfo: true, activePointScrollMode: "OFF", isHelpDialogOpen: false, @@ -257,6 +259,12 @@ export const uiStore = createPartialStore({ HYDRATE_UI_STORE: { async action({ commit }) { + commit("SET_SWITCH_PAUSE_LENGTH_MODE", { + switchPauseLengthMode: await window.backend.getSetting( + "switchPauseLengthMode", + ), + }); + commit("SET_INHERIT_AUDIOINFO", { inheritAudioInfo: await window.backend.getSetting("inheritAudioInfo"), }); @@ -301,6 +309,30 @@ export const uiStore = createPartialStore({ }, }, + SET_SWITCH_PAUSE_LENGTH_MODE: { + mutation( + state, + { + switchPauseLengthMode, + }: { switchPauseLengthMode: SwitchPauseLengthMode }, + ) { + state.switchPauseLengthMode = switchPauseLengthMode; + }, + async action( + { commit }, + { + switchPauseLengthMode, + }: { switchPauseLengthMode: SwitchPauseLengthMode }, + ) { + commit("SET_SWITCH_PAUSE_LENGTH_MODE", { + switchPauseLengthMode: await window.backend.setSetting( + "switchPauseLengthMode", + switchPauseLengthMode, + ), + }); + }, + }, + SET_INHERIT_AUDIOINFO: { mutation(state, { inheritAudioInfo }: { inheritAudioInfo: boolean }) { state.inheritAudioInfo = inheritAudioInfo; diff --git a/src/store/utility.ts b/src/store/utility.ts index a5379bf5c0..a3d89e9e62 100644 --- a/src/store/utility.ts +++ b/src/store/utility.ts @@ -102,6 +102,26 @@ export const SLIDER_PARAMETERS = { scrollStep: () => 0.1, scrollMinStep: () => 0.01, }, + /** + * 文内無音(絶対値)パラメータの定義 + */ + PAUSE_LENGTH: { + max: () => 3, + min: () => 0, + step: () => 0.01, + scrollStep: () => 0.1, + scrollMinStep: () => 0.01, + }, + /** + * 文内無音(倍率)パラメータの定義 + */ + PAUSE_LENGTH_SCALE: { + max: () => 2, + min: () => 0, + step: () => 0.01, + scrollStep: () => 0.1, + scrollMinStep: () => 0.01, + }, /** * モーフィングレートパラメータの定義 */ diff --git a/src/type/preload.ts b/src/type/preload.ts index 179f5a1b05..b44326d6f0 100644 --- a/src/type/preload.ts +++ b/src/type/preload.ts @@ -349,6 +349,8 @@ export type AcceptRetrieveTelemetryStatus = export type AcceptTermsStatus = "Unconfirmed" | "Accepted" | "Rejected"; +export type SwitchPauseLengthMode = "SCALE" | "ABSOLUTE"; + export type ActivePointScrollMode = "CONTINUOUSLY" | "PAGE" | "OFF"; export type SplitTextWhenPasteType = "PERIOD_AND_NEW_LINE" | "NEW_LINE" | "OFF"; @@ -424,6 +426,8 @@ export type Preset = { volumeScale: number; prePhonemeLength: number; postPhonemeLength: number; + pauseLength: number; + pauseLengthScale: number; morphingInfo?: MorphingInfo; }; @@ -601,6 +605,7 @@ export type RootMiscSettingType = z.infer; export const configSchema = z .object({ + switchPauseLengthMode: z.enum(["SCALE", "ABSOLUTE"]).default("SCALE"), inheritAudioInfo: z.boolean().default(true), activePointScrollMode: z .enum(["CONTINUOUSLY", "PAGE", "OFF"]) @@ -647,6 +652,8 @@ export const configSchema = z volumeScale: z.number(), prePhonemeLength: z.number(), postPhonemeLength: z.number(), + pauseLength: z.number(), + pauseLengthScale: z.number(), morphingInfo: z .object({ rate: z.number(), diff --git a/tests/unit/backend/common/pastConfigs/0.13.json b/tests/unit/backend/common/pastConfigs/0.13.json index a66de624ad..09eee3552d 100644 --- a/tests/unit/backend/common/pastConfigs/0.13.json +++ b/tests/unit/backend/common/pastConfigs/0.13.json @@ -1,5 +1,6 @@ { "useGpu": false, + "switchPauseLengthMode": "SCALE", "inheritAudioInfo": true, "activePointScrollMode": "OFF", "savingSetting": { @@ -148,4 +149,4 @@ "version": "0.13.3" } } -} \ No newline at end of file +} From a5db9d2718a32fa6b45b5bfd17c56fc1b1c6d0a4 Mon Sep 17 00:00:00 2001 From: X-20A <155217226+X-20A@users.noreply.github.com> Date: Sun, 26 May 2024 10:29:02 +0900 Subject: [PATCH 02/86] =?UTF-8?q?=E6=96=B0=E8=A6=8F:=E3=83=97=E3=83=AA?= =?UTF-8?q?=E3=82=BB=E3=83=83=E3=83=88[pauseLength,=20pauseLengthScale]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/Dialog/AllDialog.vue | 10 +++- src/components/Dialog/SettingDialog.vue | 25 ++++++++ src/components/Talk/AudioInfo.vue | 80 ++++++++++++------------- src/store/audio.ts | 13 +++- 4 files changed, 86 insertions(+), 42 deletions(-) diff --git a/src/components/Dialog/AllDialog.vue b/src/components/Dialog/AllDialog.vue index 981cae021e..cb09b3a75f 100644 --- a/src/components/Dialog/AllDialog.vue +++ b/src/components/Dialog/AllDialog.vue @@ -4,7 +4,10 @@ /> - + (); const store = useStore(); +const activeAudioKey = computed( + () => store.getters.ACTIVE_AUDIO_KEY, +); + // ライセンス表示 const isHelpDialogOpenComputed = computed({ get: () => store.state.isHelpDialogOpen, diff --git a/src/components/Dialog/SettingDialog.vue b/src/components/Dialog/SettingDialog.vue index 50a07f1ed5..e026885d3d 100644 --- a/src/components/Dialog/SettingDialog.vue +++ b/src/components/Dialog/SettingDialog.vue @@ -1065,6 +1065,7 @@ import { computed, ref, watchEffect } from "vue"; import FileNamePatternDialog from "./FileNamePatternDialog.vue"; import { useStore } from "@/store"; import { + AudioKey, isProduction, SavingSetting, EngineSettingType, @@ -1091,6 +1092,7 @@ const useRootMiscSetting = (key: T) => { const props = defineProps<{ modelValue: boolean; + activeAudioKey: AudioKey; }>(); const emit = defineEmits<{ (e: "update:modelValue", val: boolean): void; @@ -1126,6 +1128,29 @@ const switchPauseLengthMode = computed({ }); }, }); + +const selectedAudioKeys = computed(() => + store.state.experimentalSetting.enableMultiSelect + ? store.getters.SELECTED_AUDIO_KEYS + : [props.activeAudioKey], +); + +watchEffect(() => { + if (selectedAudioKeys.value) { + if (switchPauseLengthMode.value === "SCALE") { + store.dispatch("COMMAND_MULTI_SET_AUDIO_PAUSE_LENGTH", { + audioKeys: selectedAudioKeys.value, + pauseLength: 0.3, + }); + } else { + store.dispatch("COMMAND_MULTI_SET_AUDIO_PAUSE_LENGTH_SCALE", { + audioKeys: selectedAudioKeys.value, + pauseLengthScale: 1, + }); + } + } +}); + const inheritAudioInfoMode = computed(() => store.state.inheritAudioInfo); const activePointScrollMode = computed({ get: () => store.state.activePointScrollMode, diff --git a/src/components/Talk/AudioInfo.vue b/src/components/Talk/AudioInfo.vue index b3da96e3cd..d7c88632a2 100644 --- a/src/components/Talk/AudioInfo.vue +++ b/src/components/Talk/AudioInfo.vue @@ -362,49 +362,49 @@ const selectedAudioKeys = computed(() => : [props.activeAudioKey], ); -const plParam: Parameter = { - label: "文内無音", - slider: previewSliderHelper({ - modelValue: () => query.value?.pauseLength ?? null, - disable: () => uiLocked.value, - max: SLIDER_PARAMETERS.PAUSE_LENGTH.max, - min: SLIDER_PARAMETERS.PAUSE_LENGTH.min, - step: SLIDER_PARAMETERS.PAUSE_LENGTH.step, - scrollStep: SLIDER_PARAMETERS.PAUSE_LENGTH.scrollStep, - scrollMinStep: SLIDER_PARAMETERS.PAUSE_LENGTH.scrollMinStep, - onChange: (pauseLength: number) => - store.dispatch("COMMAND_MULTI_SET_AUDIO_PAUSE_LENGTH", { - audioKeys: selectedAudioKeys.value, - pauseLength, - }), - }), - action: "COMMAND_MULTI_SET_AUDIO_PAUSE_LENGTH", - key: "pauseLength", -}; - -const plsParam: Parameter = { - label: "文内無音", - slider: previewSliderHelper({ - modelValue: () => query.value?.pauseLengthScale ?? null, - disable: () => uiLocked.value, - max: SLIDER_PARAMETERS.PAUSE_LENGTH_SCALE.max, - min: SLIDER_PARAMETERS.PAUSE_LENGTH_SCALE.min, - step: SLIDER_PARAMETERS.PAUSE_LENGTH_SCALE.step, - scrollStep: SLIDER_PARAMETERS.PAUSE_LENGTH_SCALE.scrollStep, - scrollMinStep: SLIDER_PARAMETERS.PAUSE_LENGTH_SCALE.scrollMinStep, - onChange: (pauseLengthScale: number) => - store.dispatch("COMMAND_MULTI_SET_AUDIO_PAUSE_LENGTH_SCALE", { - audioKeys: selectedAudioKeys.value, - pauseLengthScale, - }), - }), - action: "COMMAND_MULTI_SET_AUDIO_PAUSE_LENGTH", - key: "pauseLength", -}; - // 文内無音はひとまず倍率verを表示 のち必要に応じ絶対値に切替 // 泥臭くなっちゃったかも const parameters = computed(() => { + // 一旦ここで初期値を入れてしまう + const plParam: Parameter = { + label: "文内無音(秒)", + slider: previewSliderHelper({ + modelValue: () => query.value?.pauseLength ?? null, + disable: () => uiLocked.value, + max: SLIDER_PARAMETERS.PAUSE_LENGTH.max, + min: SLIDER_PARAMETERS.PAUSE_LENGTH.min, + step: SLIDER_PARAMETERS.PAUSE_LENGTH.step, + scrollStep: SLIDER_PARAMETERS.PAUSE_LENGTH.scrollStep, + scrollMinStep: SLIDER_PARAMETERS.PAUSE_LENGTH.scrollMinStep, + onChange: (pauseLength: number) => + store.dispatch("COMMAND_MULTI_SET_AUDIO_PAUSE_LENGTH", { + audioKeys: selectedAudioKeys.value, + pauseLength: pauseLength, + }), + }), + action: "COMMAND_MULTI_SET_AUDIO_PAUSE_LENGTH", + key: "pauseLength", + }; + + const plsParam: Parameter = { + label: "文内無音(倍)", + slider: previewSliderHelper({ + modelValue: () => query.value?.pauseLengthScale ?? null, + disable: () => uiLocked.value, + max: SLIDER_PARAMETERS.PAUSE_LENGTH_SCALE.max, + min: SLIDER_PARAMETERS.PAUSE_LENGTH_SCALE.min, + step: SLIDER_PARAMETERS.PAUSE_LENGTH_SCALE.step, + scrollStep: SLIDER_PARAMETERS.PAUSE_LENGTH_SCALE.scrollStep, + scrollMinStep: SLIDER_PARAMETERS.PAUSE_LENGTH_SCALE.scrollMinStep, + onChange: (pauseLengthScale: number) => + store.dispatch("COMMAND_MULTI_SET_AUDIO_PAUSE_LENGTH_SCALE", { + audioKeys: selectedAudioKeys.value, + pauseLengthScale: pauseLengthScale, + }), + }), + action: "COMMAND_MULTI_SET_AUDIO_PAUSE_LENGTH_SCALE", + key: "pauseLengthScale", + }; const baseParam: Parameter[] = [ { label: "話速", diff --git a/src/store/audio.ts b/src/store/audio.ts index db947396b5..685180be3f 100644 --- a/src/store/audio.ts +++ b/src/store/audio.ts @@ -685,6 +685,9 @@ export const audioStore = createPartialStore({ () => undefined, ) : undefined; + if (query) { + query.pauseLength = 0.3; + } console.log(query); const newAudioItem: AudioItem = { text, voice }; @@ -1319,7 +1322,14 @@ export const audioStore = createPartialStore({ const audioItem: AudioItem = JSON.parse( JSON.stringify(state.audioItems[audioKey]), ); - await console.log(audioItem); // この時点ではまだpresetがmoraに反映されていない + // ここでqueryのチェックを行う + if (audioItem.query?.pauseLengthScale !== 1) { + if (audioItem.query) { + audioItem.query.pauseLength = -1; + } + } + await console.log("以下audioItem"); + await console.log(audioItem); return dispatch("FETCH_AUDIO_FROM_AUDIO_ITEM", { audioItem, ...options, @@ -1823,6 +1833,7 @@ export const audioStore = createPartialStore({ PLAY_CONTINUOUSLY_AUDIO: { action: createUILockAction(async ({ state, getters, commit, dispatch }) => { + console.log("PLAY_CONTINUOUSLY_AUDIO"); const currentAudioKey = state._activeAudioKey; const currentAudioPlayStartPoint = getters.AUDIO_PLAY_START_POINT; From 25da5cabe65d2533b5970fdec7363b1c5a46ac93 Mon Sep 17 00:00:00 2001 From: X-20A <155217226+X-20A@users.noreply.github.com> Date: Tue, 28 May 2024 20:08:12 +0900 Subject: [PATCH 03/86] =?UTF-8?q?=E3=83=9E=E3=83=8B=E3=83=A5=E3=82=A2?= =?UTF-8?q?=E3=83=AB=E5=80=A4=E3=81=AE=E8=A8=AD=E5=AE=9A=E3=81=AB=E5=AF=BE?= =?UTF-8?q?=E5=BF=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/App.vue | 1 - .../Dialog/DictionaryManageDialog.vue | 1 - src/components/Talk/AccentPhrase.vue | 2 ++ src/components/Talk/AudioDetail.vue | 32 ++++++++++++++++++- src/components/Talk/AudioInfo.vue | 1 - src/domain/project/schema.ts | 2 +- src/openapi/apis/DefaultApi.ts | 4 --- src/openapi/models/AudioQuery.ts | 4 +-- src/openapi/models/Preset.ts | 6 ++-- src/store/audio.ts | 28 +++++++++------- src/store/audioGenerate.ts | 5 --- src/store/project.ts | 2 +- src/store/type.ts | 9 ++++-- src/store/utility.ts | 4 +-- src/type/preload.ts | 2 +- 15 files changed, 65 insertions(+), 38 deletions(-) diff --git a/src/components/App.vue b/src/components/App.vue index ff059d5d95..1dc3451b31 100644 --- a/src/components/App.vue +++ b/src/components/App.vue @@ -122,7 +122,6 @@ onMounted(async () => { engineIds = store.state.engineIds; } await store.dispatch("LOAD_USER_CHARACTER_ORDER"); - console.log("onMounted"); await store.dispatch("POST_ENGINE_START", { engineIds, }); diff --git a/src/components/Dialog/DictionaryManageDialog.vue b/src/components/Dialog/DictionaryManageDialog.vue index aeffd0cb5e..b646d45205 100644 --- a/src/components/Dialog/DictionaryManageDialog.vue +++ b/src/components/Dialog/DictionaryManageDialog.vue @@ -397,7 +397,6 @@ const setYomi = async (text: string, changeWord?: boolean) => { if (isOnlyHiraOrKana.value && text.length) { text = convertHiraToKana(text); text = convertLongVowel(text); - console.log("setYomi"); accentPhrase.value = ( await createUILockAction( store.dispatch("FETCH_ACCENT_PHRASES", { diff --git a/src/components/Talk/AccentPhrase.vue b/src/components/Talk/AccentPhrase.vue index f026f4c0e2..6db3210c0d 100644 --- a/src/components/Talk/AccentPhrase.vue +++ b/src/components/Talk/AccentPhrase.vue @@ -363,6 +363,7 @@ const lastPitches = computed(() => props.accentPhrase.moras.map((mora) => mora.pitch), ); +// スライダー操作で発火 const maxPitch = 6.5; const minPitch = 3; const maxMoraLength = 0.3; @@ -372,6 +373,7 @@ const changeMoraData = ( data: number, type: MoraDataType, ) => { + console.log("changeMoraData in AccentPhrase.vue"); const accentPhraseIndex = props.index; if (!props.altKeyFlag) { if (type == "pitch") { diff --git a/src/components/Talk/AudioDetail.vue b/src/components/Talk/AudioDetail.vue index 957e886181..a08a0970b7 100644 --- a/src/components/Talk/AudioDetail.vue +++ b/src/components/Talk/AudioDetail.vue @@ -183,9 +183,38 @@ const selectedDetail = ref("accent"); // accent phrase const uiLocked = computed(() => store.getters.UI_LOCKED); +const switchPauseLengthMode = computed(() => store.state.switchPauseLengthMode); + const audioItem = computed(() => store.state.audioItems[props.activeAudioKey]); + const query = computed(() => audioItem.value?.query); -const accentPhrases = computed(() => query.value?.accentPhrases); + +// pauseLength&pauseLengthScaleにおいては、エンジン側で行う処理を例外的にここで行う +// storeへの反映はAccentPhrases.vueでやってくれる +const accentPhrases = computed(() => { + console.log("accentPhrase in AudioDetail.vue"); + const newAccentPhrases = query.value?.accentPhrases; + if (switchPauseLengthMode.value === "ABSOLUTE" && newAccentPhrases) { + const pauseLength = query.value?.pauseLength; + if (pauseLength != null) { + newAccentPhrases.forEach((accentPhrase) => { + if (accentPhrase.pauseMora) { + accentPhrase.pauseMora.vowelLength = pauseLength; + } + }); + } + } else if (switchPauseLengthMode.value === "SCALE" && newAccentPhrases) { + const pauseLengthScale = query.value?.pauseLengthScale; + if (pauseLengthScale != null) { + newAccentPhrases.forEach((accentPhrase) => { + if (accentPhrase.pauseMora) { + accentPhrase.pauseMora.vowelLength *= pauseLengthScale; + } + }); + } + } + return newAccentPhrases; +}); // エンジンが変わったとき、selectedDetailが対応していないものを選択している場合はaccentに戻す // TODO: 連続再生するとアクセントに移動してしまうため、タブの中身を全てdisabledにする、半透明divをかぶせるなど @@ -314,6 +343,7 @@ watch(nowPlaying, async (newState) => { const accentPhraseOffsets = await store.dispatch("GET_AUDIO_PLAY_OFFSETS", { audioKey: props.activeAudioKey, }); + console.log(accentPhraseOffsets); // 現在再生されているaudio elementの再生時刻を描画毎に取得(監視)し、 // それに合わせてフォーカスするアクセント句を変えていく const focusAccentPhrase = () => { diff --git a/src/components/Talk/AudioInfo.vue b/src/components/Talk/AudioInfo.vue index d7c88632a2..230b175e5c 100644 --- a/src/components/Talk/AudioInfo.vue +++ b/src/components/Talk/AudioInfo.vue @@ -365,7 +365,6 @@ const selectedAudioKeys = computed(() => // 文内無音はひとまず倍率verを表示 のち必要に応じ絶対値に切替 // 泥臭くなっちゃったかも const parameters = computed(() => { - // 一旦ここで初期値を入れてしまう const plParam: Parameter = { label: "文内無音(秒)", slider: previewSliderHelper({ diff --git a/src/domain/project/schema.ts b/src/domain/project/schema.ts index 08d39bd201..6fe97d4d58 100644 --- a/src/domain/project/schema.ts +++ b/src/domain/project/schema.ts @@ -34,7 +34,7 @@ const audioQuerySchema = z.object({ volumeScale: z.number(), prePhonemeLength: z.number(), postPhonemeLength: z.number(), - pauseLength: z.number(), + pauseLength: z.number().nullable(), pauseLengthScale: z.number(), outputSamplingRate: z.union([z.number(), z.literal("engineDefault")]), outputStereo: z.boolean(), diff --git a/src/openapi/apis/DefaultApi.ts b/src/openapi/apis/DefaultApi.ts index de92cc6177..91e68f190b 100644 --- a/src/openapi/apis/DefaultApi.ts +++ b/src/openapi/apis/DefaultApi.ts @@ -1881,7 +1881,6 @@ export class DefaultApi extends runtime.BaseAPI implements DefaultApiInterface { * 指定したスタイルに対してエンジン内の話者がモーフィングが可能か判定する */ async morphableTargetsMorphableTargetsPostRaw(requestParameters: MorphableTargetsMorphableTargetsPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>> { - // console.log("morphableTargetsMorphableTargetsPostRaw"); if (requestParameters.requestBody === null || requestParameters.requestBody === undefined) { throw new runtime.RequiredError('requestBody','Required parameter requestParameters.requestBody was null or undefined when calling morphableTargetsMorphableTargetsPost.'); } @@ -1912,7 +1911,6 @@ export class DefaultApi extends runtime.BaseAPI implements DefaultApiInterface { * 指定したスタイルに対してエンジン内の話者がモーフィングが可能か判定する */ async morphableTargetsMorphableTargetsPost(requestParameters: MorphableTargetsMorphableTargetsPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { - // console.log("morphableTargetsMorphableTargetsPost"); const response = await this.morphableTargetsMorphableTargetsPostRaw(requestParameters, initOverrides); return await response.value(); } @@ -2207,7 +2205,6 @@ export class DefaultApi extends runtime.BaseAPI implements DefaultApiInterface { * Singer Info */ async singerInfoSingerInfoGetRaw(requestParameters: SingerInfoSingerInfoGetRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { - // console.log("singerInfoSingerInfoGetRaw"); if (requestParameters.speakerUuid === null || requestParameters.speakerUuid === undefined) { throw new runtime.RequiredError('speakerUuid','Required parameter requestParameters.speakerUuid was null or undefined when calling singerInfoSingerInfoGet.'); } @@ -2278,7 +2275,6 @@ export class DefaultApi extends runtime.BaseAPI implements DefaultApiInterface { * Speaker Info */ async speakerInfoSpeakerInfoGetRaw(requestParameters: SpeakerInfoSpeakerInfoGetRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { - // console.log("speakerInfoSpeakerInfoGetRaw"); if (requestParameters.speakerUuid === null || requestParameters.speakerUuid === undefined) { throw new runtime.RequiredError('speakerUuid','Required parameter requestParameters.speakerUuid was null or undefined when calling speakerInfoSpeakerInfoGet.'); } diff --git a/src/openapi/models/AudioQuery.ts b/src/openapi/models/AudioQuery.ts index baab874e2a..cef65dac0e 100644 --- a/src/openapi/models/AudioQuery.ts +++ b/src/openapi/models/AudioQuery.ts @@ -70,10 +70,10 @@ export interface AudioQuery { postPhonemeLength: number; /** * - * @type {number} + * @type {number | null} * @memberof AudioQuery */ - pauseLength: number; + pauseLength: number | null; /** * * @type {number} diff --git a/src/openapi/models/Preset.ts b/src/openapi/models/Preset.ts index e8a4e5c1d4..53bb75ef9f 100644 --- a/src/openapi/models/Preset.ts +++ b/src/openapi/models/Preset.ts @@ -81,10 +81,10 @@ export interface Preset { postPhonemeLength: number; /** * - * @type {number} - * @memberof Preset + * @type {number | null} + * @memberof AudioQuery */ - pauseLength: number; + pauseLength: number | null; /** * * @type {number} diff --git a/src/store/audio.ts b/src/store/audio.ts index 685180be3f..41ae4860d0 100644 --- a/src/store/audio.ts +++ b/src/store/audio.ts @@ -66,7 +66,6 @@ function parseTextFile( userOrderedCharacterInfos: CharacterInfo[], initVoice?: Voice, ): AudioItem[] { - console.log("parseTextFile"); // きてない const name2Voice = new Map(); const uuid2Voice = new Map(); for (const defaultStyleId of defaultStyleIds) { @@ -436,7 +435,6 @@ export const audioStore = createPartialStore({ LOAD_MORPHABLE_TARGETS: { async action({ state, dispatch, commit }, { engineId, baseStyleId }) { - // console.log("LOAD_MORPHABLE_TARGETS"); if (!state.engineManifests[engineId].supportedFeatures?.synthesisMorphing) return; @@ -919,7 +917,10 @@ export const audioStore = createPartialStore({ SET_AUDIO_PAUSE_LENGTH: { mutation( state, - { audioKey, pauseLength }: { audioKey: AudioKey; pauseLength: number }, + { + audioKey, + pauseLength, + }: { audioKey: AudioKey; pauseLength: number | null }, ) { console.log("SET_AUDIO_PAUSE_LENGTH"); const query = state.audioItems[audioKey].query; @@ -1318,15 +1319,13 @@ export const audioStore = createPartialStore({ { audioKey, ...options }: { audioKey: AudioKey; cacheOnly?: boolean }, ) { console.log("FETCH_AUDIO"); - await console.log(state.audioItems[audioKey]); const audioItem: AudioItem = JSON.parse( JSON.stringify(state.audioItems[audioKey]), ); - // ここでqueryのチェックを行う - if (audioItem.query?.pauseLengthScale !== 1) { - if (audioItem.query) { - audioItem.query.pauseLength = -1; - } + // pauseLength&pauseLengthScaleは無効(APIに相当する処理はAudioDetail.vue > accentPhraseで既に済んでる) + if (audioItem.query) { + audioItem.query.pauseLength = null; + audioItem.query.pauseLengthScale = 1; } await console.log("以下audioItem"); await console.log(audioItem); @@ -1775,7 +1774,6 @@ export const audioStore = createPartialStore({ nowGenerating: false, }); } - console.log("PLAY_AUDIO:到達"); const { blob } = fetchAudioResult; return dispatch("PLAY_AUDIO_BLOB", { audioBlob: blob, @@ -2806,7 +2804,13 @@ export const audioCommandStore = transformCommandStore( }, COMMAND_MULTI_SET_AUDIO_PAUSE_LENGTH: { - mutation(draft, payload: { audioKeys: AudioKey[]; pauseLength: number }) { + mutation( + draft, + payload: { + audioKeys: AudioKey[]; + pauseLength: number | null; + }, + ) { for (const audioKey of payload.audioKeys) { audioStore.mutations.SET_AUDIO_PAUSE_LENGTH(draft, { audioKey, @@ -2816,7 +2820,7 @@ export const audioCommandStore = transformCommandStore( }, action( { commit }, - payload: { audioKeys: AudioKey[]; pauseLength: number }, + payload: { audioKeys: AudioKey[]; pauseLength: number | null }, ) { commit("COMMAND_MULTI_SET_AUDIO_PAUSE_LENGTH", payload); }, diff --git a/src/store/audioGenerate.ts b/src/store/audioGenerate.ts index 3de4d1be57..278e298dbd 100644 --- a/src/store/audioGenerate.ts +++ b/src/store/audioGenerate.ts @@ -28,14 +28,9 @@ export async function fetchAudioFromAudioItem( }, ): Promise { console.log("fetchAudioFromAudioItem"); - // 試しにここで弄ってみる - // audioItem.query.accentPhrases[0].moras[0].consonantLength = 0.1; コンソールには出るがqueryでundefined - // 多分非同期が悪さしててこの時点ではまだaudioQueryのresponseは入ってない const engineId = audioItem.voice.engineId; const [id, audioQuery] = await generateUniqueIdAndQuery(state, audioItem); - await console.log(audioQuery); // preset未反映 - // audioQuery.accentPhrases[0].moras[0].vowelLength = 0.1; // まだ if (audioQuery == undefined) throw new Error("audioQuery is not defined for audioItem"); diff --git a/src/store/project.ts b/src/store/project.ts index 0ad034d14c..917e98f18c 100755 --- a/src/store/project.ts +++ b/src/store/project.ts @@ -259,7 +259,7 @@ export const projectStore = createPartialStore({ 0.1; projectData.audioItems[audioItemsKey].query.postPhonemeLength = 0.1; - projectData.audioItems[audioItemsKey].query.pauseLength = 0.1; + projectData.audioItems[audioItemsKey].query.pauseLength = 0.3; projectData.audioItems[audioItemsKey].query.pauseLengthScale = 1; projectData.audioItems[audioItemsKey].query.outputSamplingRate = diff --git a/src/store/type.ts b/src/store/type.ts index 2dd16d6d5f..20913afee2 100644 --- a/src/store/type.ts +++ b/src/store/type.ts @@ -291,7 +291,7 @@ export type AudioStoreTypes = { }; SET_AUDIO_PAUSE_LENGTH: { - mutation: { audioKey: AudioKey; pauseLength: number }; + mutation: { audioKey: AudioKey; pauseLength: number | null }; }; SET_AUDIO_PAUSE_LENGTH_SCALE: { @@ -638,8 +638,11 @@ export type AudioCommandStoreTypes = { }; COMMAND_MULTI_SET_AUDIO_PAUSE_LENGTH: { - mutation: { audioKeys: AudioKey[]; pauseLength: number }; - action(payload: { audioKeys: AudioKey[]; pauseLength: number }): void; + mutation: { audioKeys: AudioKey[]; pauseLength: number | null }; + action(payload: { + audioKeys: AudioKey[]; + pauseLength: number | null; + }): void; }; COMMAND_MULTI_SET_AUDIO_PAUSE_LENGTH_SCALE: { diff --git a/src/store/utility.ts b/src/store/utility.ts index a3d89e9e62..b04c631ea9 100644 --- a/src/store/utility.ts +++ b/src/store/utility.ts @@ -106,10 +106,10 @@ export const SLIDER_PARAMETERS = { * 文内無音(絶対値)パラメータの定義 */ PAUSE_LENGTH: { - max: () => 3, + max: () => 1, min: () => 0, step: () => 0.01, - scrollStep: () => 0.1, + scrollStep: () => 0.01, scrollMinStep: () => 0.01, }, /** diff --git a/src/type/preload.ts b/src/type/preload.ts index b44326d6f0..c13095c269 100644 --- a/src/type/preload.ts +++ b/src/type/preload.ts @@ -426,7 +426,7 @@ export type Preset = { volumeScale: number; prePhonemeLength: number; postPhonemeLength: number; - pauseLength: number; + pauseLength: number | null; pauseLengthScale: number; morphingInfo?: MorphingInfo; }; From 1f22f5614b812269481664adfc40a02fd812105b Mon Sep 17 00:00:00 2001 From: X-20A <155217226+X-20A@users.noreply.github.com> Date: Tue, 28 May 2024 20:50:41 +0900 Subject: [PATCH 04/86] Add files via upload --- env.production | 14 ++++++++++++++ env.test | 14 ++++++++++++++ 2 files changed, 28 insertions(+) create mode 100644 env.production create mode 100644 env.test diff --git a/env.production b/env.production new file mode 100644 index 0000000000..5b0dcb0498 --- /dev/null +++ b/env.production @@ -0,0 +1,14 @@ +VITE_APP_NAME=voicevox +VITE_DEFAULT_ENGINE_INFOS=`[ + { + "uuid": "074fc39e-678b-4c13-8916-ffca8d505d1d", + "name": "VOICEVOX Engine", + "executionEnabled": true, + "executionFilePath": "vv-engine/run.exe", + "executionArgs": [], + "host": "http://127.0.0.1:50021" + } +]` +VITE_OFFICIAL_WEBSITE_URL=https://voicevox.hiroshiba.jp/ +VITE_LATEST_UPDATE_INFOS_URL=https://raw.githubusercontent.com/VOICEVOX/voicevox_blog/master/src/data/updateInfos.json +VITE_GTM_CONTAINER_ID=GTM-DUMMY diff --git a/env.test b/env.test new file mode 100644 index 0000000000..dcf447f8b2 --- /dev/null +++ b/env.test @@ -0,0 +1,14 @@ +VITE_APP_NAME=voicevox +VITE_DEFAULT_ENGINE_INFOS=`[ + { + "uuid": "074fc39e-678b-4c13-8916-ffca8d505d1d", + "name": "VOICEVOX Engine", + "executionEnabled": true, + "executionFilePath": "../voicevox_engine/run.exe", + "executionArgs": [], + "host": "http://127.0.0.1:50021" + } +]` +VITE_OFFICIAL_WEBSITE_URL=https://voicevox.hiroshiba.jp/ +VITE_LATEST_UPDATE_INFOS_URL=https://raw.githubusercontent.com/VOICEVOX/voicevox_blog/master/src/data/updateInfos.json +VITE_GTM_CONTAINER_ID=GTM-DUMMY From 81079eedca21da3a7d475efd48bfd3696775296f Mon Sep 17 00:00:00 2001 From: X-20A <155217226+X-20A@users.noreply.github.com> Date: Tue, 28 May 2024 21:36:22 +0900 Subject: [PATCH 05/86] =?UTF-8?q?pauseLengthScale=E3=82=92=E8=A4=87?= =?UTF-8?q?=E6=95=B0=E5=9B=9E=E6=93=8D=E4=BD=9C=E3=81=99=E3=82=8B=E3=81=A8?= =?UTF-8?q?=E5=8F=8D=E6=98=A0=E3=81=95=E3=82=8C=E3=81=AA=E3=81=84=E3=83=90?= =?UTF-8?q?=E3=82=B0=E3=82=92=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- env.production | 14 ++++++++++++++ src/components/Talk/AudioDetail.vue | 6 ++++-- src/store/audio.ts | 7 +++++-- 3 files changed, 23 insertions(+), 4 deletions(-) create mode 100644 env.production diff --git a/env.production b/env.production new file mode 100644 index 0000000000..5b0dcb0498 --- /dev/null +++ b/env.production @@ -0,0 +1,14 @@ +VITE_APP_NAME=voicevox +VITE_DEFAULT_ENGINE_INFOS=`[ + { + "uuid": "074fc39e-678b-4c13-8916-ffca8d505d1d", + "name": "VOICEVOX Engine", + "executionEnabled": true, + "executionFilePath": "vv-engine/run.exe", + "executionArgs": [], + "host": "http://127.0.0.1:50021" + } +]` +VITE_OFFICIAL_WEBSITE_URL=https://voicevox.hiroshiba.jp/ +VITE_LATEST_UPDATE_INFOS_URL=https://raw.githubusercontent.com/VOICEVOX/voicevox_blog/master/src/data/updateInfos.json +VITE_GTM_CONTAINER_ID=GTM-DUMMY diff --git a/src/components/Talk/AudioDetail.vue b/src/components/Talk/AudioDetail.vue index a08a0970b7..7e5e514e52 100644 --- a/src/components/Talk/AudioDetail.vue +++ b/src/components/Talk/AudioDetail.vue @@ -193,6 +193,7 @@ const query = computed(() => audioItem.value?.query); // storeへの反映はAccentPhrases.vueでやってくれる const accentPhrases = computed(() => { console.log("accentPhrase in AudioDetail.vue"); + console.log(switchPauseLengthMode.value); const newAccentPhrases = query.value?.accentPhrases; if (switchPauseLengthMode.value === "ABSOLUTE" && newAccentPhrases) { const pauseLength = query.value?.pauseLength; @@ -203,8 +204,9 @@ const accentPhrases = computed(() => { } }); } - } else if (switchPauseLengthMode.value === "SCALE" && newAccentPhrases) { + }/* else if (switchPauseLengthMode.value === "SCALE" && newAccentPhrases) { const pauseLengthScale = query.value?.pauseLengthScale; + console.log(pauseLengthScale); if (pauseLengthScale != null) { newAccentPhrases.forEach((accentPhrase) => { if (accentPhrase.pauseMora) { @@ -212,7 +214,7 @@ const accentPhrases = computed(() => { } }); } - } + }*/ return newAccentPhrases; }); diff --git a/src/store/audio.ts b/src/store/audio.ts index 41ae4860d0..b14fca2b0b 100644 --- a/src/store/audio.ts +++ b/src/store/audio.ts @@ -1301,7 +1301,11 @@ export const audioStore = createPartialStore({ length += m.consonantLength != undefined ? m.consonantLength : 0; length += m.vowelLength; }); - length += phrase.pauseMora ? phrase.pauseMora.vowelLength : 0; + if (state.switchPauseLengthMode === "SCALE") { + length += phrase.pauseMora ? phrase.pauseMora.vowelLength * query.pauseLengthScale : 0; + } else { + length += phrase.pauseMora ? phrase.pauseMora.vowelLength : 0; + } // post phoneme lengthは最後のアクセント句の一部として扱う if (i === accentPhrases.length - 1) { length += query.postPhonemeLength; @@ -1325,7 +1329,6 @@ export const audioStore = createPartialStore({ // pauseLength&pauseLengthScaleは無効(APIに相当する処理はAudioDetail.vue > accentPhraseで既に済んでる) if (audioItem.query) { audioItem.query.pauseLength = null; - audioItem.query.pauseLengthScale = 1; } await console.log("以下audioItem"); await console.log(audioItem); From 0ccb1e3724d9f6ed753a75643448c480ff5c3b06 Mon Sep 17 00:00:00 2001 From: X-20A <155217226+X-20A@users.noreply.github.com> Date: Tue, 28 May 2024 21:40:07 +0900 Subject: [PATCH 06/86] Delete env.test --- env.test | 14 -------------- 1 file changed, 14 deletions(-) delete mode 100644 env.test diff --git a/env.test b/env.test deleted file mode 100644 index dcf447f8b2..0000000000 --- a/env.test +++ /dev/null @@ -1,14 +0,0 @@ -VITE_APP_NAME=voicevox -VITE_DEFAULT_ENGINE_INFOS=`[ - { - "uuid": "074fc39e-678b-4c13-8916-ffca8d505d1d", - "name": "VOICEVOX Engine", - "executionEnabled": true, - "executionFilePath": "../voicevox_engine/run.exe", - "executionArgs": [], - "host": "http://127.0.0.1:50021" - } -]` -VITE_OFFICIAL_WEBSITE_URL=https://voicevox.hiroshiba.jp/ -VITE_LATEST_UPDATE_INFOS_URL=https://raw.githubusercontent.com/VOICEVOX/voicevox_blog/master/src/data/updateInfos.json -VITE_GTM_CONTAINER_ID=GTM-DUMMY From 5fc13cd78ada8a2f4b2ae6797bf397601d7cc020 Mon Sep 17 00:00:00 2001 From: X-20A <155217226+X-20A@users.noreply.github.com> Date: Tue, 28 May 2024 21:40:29 +0900 Subject: [PATCH 07/86] Delete env.production --- env.production | 14 -------------- 1 file changed, 14 deletions(-) delete mode 100644 env.production diff --git a/env.production b/env.production deleted file mode 100644 index 5b0dcb0498..0000000000 --- a/env.production +++ /dev/null @@ -1,14 +0,0 @@ -VITE_APP_NAME=voicevox -VITE_DEFAULT_ENGINE_INFOS=`[ - { - "uuid": "074fc39e-678b-4c13-8916-ffca8d505d1d", - "name": "VOICEVOX Engine", - "executionEnabled": true, - "executionFilePath": "vv-engine/run.exe", - "executionArgs": [], - "host": "http://127.0.0.1:50021" - } -]` -VITE_OFFICIAL_WEBSITE_URL=https://voicevox.hiroshiba.jp/ -VITE_LATEST_UPDATE_INFOS_URL=https://raw.githubusercontent.com/VOICEVOX/voicevox_blog/master/src/data/updateInfos.json -VITE_GTM_CONTAINER_ID=GTM-DUMMY From 5ca3eca71c9e4c04ff737ada5801ec67bf8fab7a Mon Sep 17 00:00:00 2001 From: X-20A <155217226+X-20A@users.noreply.github.com> Date: Sun, 2 Jun 2024 05:40:28 +0900 Subject: [PATCH 08/86] =?UTF-8?q?=E7=89=87=E4=BB=98=E3=81=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- env.test | 14 + openapi.json | 3171 +---------------------- src/backend/electron/main.ts | 3 +- src/components/Dialog/SettingDialog.vue | 5 +- src/components/Talk/AccentPhrase.vue | 9 +- src/components/Talk/AudioCell.vue | 1 - src/components/Talk/AudioDetail.vue | 16 +- src/components/Talk/AudioInfo.vue | 4 - src/components/Talk/TalkEditor.vue | 4 +- src/openapi/apis/DefaultApi.ts | 37 - src/store/audio.ts | 54 +- src/store/audioGenerate.ts | 11 +- src/store/engine.ts | 3 - src/store/preset.ts | 5 +- src/store/project.ts | 4 - src/store/proxy.ts | 2 - 16 files changed, 28 insertions(+), 3315 deletions(-) create mode 100644 env.test diff --git a/env.test b/env.test new file mode 100644 index 0000000000..dcf447f8b2 --- /dev/null +++ b/env.test @@ -0,0 +1,14 @@ +VITE_APP_NAME=voicevox +VITE_DEFAULT_ENGINE_INFOS=`[ + { + "uuid": "074fc39e-678b-4c13-8916-ffca8d505d1d", + "name": "VOICEVOX Engine", + "executionEnabled": true, + "executionFilePath": "../voicevox_engine/run.exe", + "executionArgs": [], + "host": "http://127.0.0.1:50021" + } +]` +VITE_OFFICIAL_WEBSITE_URL=https://voicevox.hiroshiba.jp/ +VITE_LATEST_UPDATE_INFOS_URL=https://raw.githubusercontent.com/VOICEVOX/voicevox_blog/master/src/data/updateInfos.json +VITE_GTM_CONTAINER_ID=GTM-DUMMY diff --git a/openapi.json b/openapi.json index bdef017bb1..f3cfa20a90 100644 --- a/openapi.json +++ b/openapi.json @@ -1,3170 +1 @@ -{ - "openapi": "3.1.0", - "info": { - "title": "VOICEVOX Engine", - "description": "VOICEVOXの音声合成エンジンです。", - "version": "0.18.1" - }, - "paths": { - "/audio_query": { - "post": { - "tags": [ - "クエリ作成" - ], - "summary": "音声合成用のクエリを作成する", - "description": "音声合成用のクエリの初期値を得ます。ここで得られたクエリはそのまま音声合成に利用できます。各値の意味は`Schemas`を参照してください。", - "operationId": "audio_query_audio_query_post", - "parameters": [ - { - "required": true, - "schema": { - "type": "string", - "title": "Text" - }, - "name": "text", - "in": "query" - }, - { - "required": true, - "schema": { - "type": "integer", - "title": "Speaker" - }, - "name": "speaker", - "in": "query" - }, - { - "required": false, - "schema": { - "type": "string", - "title": "Core Version" - }, - "name": "core_version", - "in": "query" - } - ], - "responses": { - "200": { - "description": "Successful Response", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/AudioQuery" - } - } - } - }, - "422": { - "description": "Validation Error", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/HTTPValidationError" - } - } - } - } - } - } - }, - "/audio_query_from_preset": { - "post": { - "tags": [ - "クエリ作成" - ], - "summary": "音声合成用のクエリをプリセットを用いて作成する", - "description": "音声合成用のクエリの初期値を得ます。ここで得られたクエリはそのまま音声合成に利用できます。各値の意味は`Schemas`を参照してください。", - "operationId": "audio_query_from_preset_audio_query_from_preset_post", - "parameters": [ - { - "required": true, - "schema": { - "type": "string", - "title": "Text" - }, - "name": "text", - "in": "query" - }, - { - "required": true, - "schema": { - "type": "integer", - "title": "Preset Id" - }, - "name": "preset_id", - "in": "query" - }, - { - "required": false, - "schema": { - "type": "string", - "title": "Core Version" - }, - "name": "core_version", - "in": "query" - } - ], - "responses": { - "200": { - "description": "Successful Response", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/AudioQuery" - } - } - } - }, - "422": { - "description": "Validation Error", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/HTTPValidationError" - } - } - } - } - } - } - }, - "/accent_phrases": { - "post": { - "tags": [ - "クエリ編集" - ], - "summary": "テキストからアクセント句を得る", - "description": "テキストからアクセント句を得ます。\nis_kanaが`true`のとき、テキストは次のAquesTalk 風記法で解釈されます。デフォルトは`false`です。\n* 全てのカナはカタカナで記述される\n* アクセント句は`/`または`、`で区切る。`、`で区切った場合に限り無音区間が挿入される。\n* カナの手前に`_`を入れるとそのカナは無声化される\n* アクセント位置を`'`で指定する。全てのアクセント句にはアクセント位置を1つ指定する必要がある。\n* アクセント句末に`?`(全角)を入れることにより疑問文の発音ができる。", - "operationId": "accent_phrases_accent_phrases_post", - "parameters": [ - { - "required": true, - "schema": { - "type": "string", - "title": "Text" - }, - "name": "text", - "in": "query" - }, - { - "required": true, - "schema": { - "type": "integer", - "title": "Speaker" - }, - "name": "speaker", - "in": "query" - }, - { - "required": false, - "schema": { - "type": "boolean", - "title": "Is Kana", - "default": false - }, - "name": "is_kana", - "in": "query" - }, - { - "required": false, - "schema": { - "type": "string", - "title": "Core Version" - }, - "name": "core_version", - "in": "query" - } - ], - "responses": { - "200": { - "description": "Successful Response", - "content": { - "application/json": { - "schema": { - "items": { - "$ref": "#/components/schemas/AccentPhrase" - }, - "type": "array", - "title": "Response Accent Phrases Accent Phrases Post" - } - } - } - }, - "400": { - "description": "読み仮名のパースに失敗", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ParseKanaBadRequest" - } - } - } - }, - "422": { - "description": "Validation Error", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/HTTPValidationError" - } - } - } - } - } - } - }, - "/mora_data": { - "post": { - "tags": [ - "クエリ編集" - ], - "summary": "アクセント句から音高・音素長を得る", - "operationId": "mora_data_mora_data_post", - "parameters": [ - { - "required": true, - "schema": { - "type": "integer", - "title": "Speaker" - }, - "name": "speaker", - "in": "query" - }, - { - "required": false, - "schema": { - "type": "string", - "title": "Core Version" - }, - "name": "core_version", - "in": "query" - } - ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "items": { - "$ref": "#/components/schemas/AccentPhrase" - }, - "type": "array", - "title": "Accent Phrases" - } - } - }, - "required": true - }, - "responses": { - "200": { - "description": "Successful Response", - "content": { - "application/json": { - "schema": { - "items": { - "$ref": "#/components/schemas/AccentPhrase" - }, - "type": "array", - "title": "Response Mora Data Mora Data Post" - } - } - } - }, - "422": { - "description": "Validation Error", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/HTTPValidationError" - } - } - } - } - } - } - }, - "/mora_length": { - "post": { - "tags": [ - "クエリ編集" - ], - "summary": "アクセント句から音素長を得る", - "operationId": "mora_length_mora_length_post", - "parameters": [ - { - "required": true, - "schema": { - "type": "integer", - "title": "Speaker" - }, - "name": "speaker", - "in": "query" - }, - { - "required": false, - "schema": { - "type": "string", - "title": "Core Version" - }, - "name": "core_version", - "in": "query" - } - ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "items": { - "$ref": "#/components/schemas/AccentPhrase" - }, - "type": "array", - "title": "Accent Phrases" - } - } - }, - "required": true - }, - "responses": { - "200": { - "description": "Successful Response", - "content": { - "application/json": { - "schema": { - "items": { - "$ref": "#/components/schemas/AccentPhrase" - }, - "type": "array", - "title": "Response Mora Length Mora Length Post" - } - } - } - }, - "422": { - "description": "Validation Error", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/HTTPValidationError" - } - } - } - } - } - } - }, - "/mora_pitch": { - "post": { - "tags": [ - "クエリ編集" - ], - "summary": "アクセント句から音高を得る", - "operationId": "mora_pitch_mora_pitch_post", - "parameters": [ - { - "required": true, - "schema": { - "type": "integer", - "title": "Speaker" - }, - "name": "speaker", - "in": "query" - }, - { - "required": false, - "schema": { - "type": "string", - "title": "Core Version" - }, - "name": "core_version", - "in": "query" - } - ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "items": { - "$ref": "#/components/schemas/AccentPhrase" - }, - "type": "array", - "title": "Accent Phrases" - } - } - }, - "required": true - }, - "responses": { - "200": { - "description": "Successful Response", - "content": { - "application/json": { - "schema": { - "items": { - "$ref": "#/components/schemas/AccentPhrase" - }, - "type": "array", - "title": "Response Mora Pitch Mora Pitch Post" - } - } - } - }, - "422": { - "description": "Validation Error", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/HTTPValidationError" - } - } - } - } - } - } - }, - "/synthesis": { - "post": { - "tags": [ - "音声合成" - ], - "summary": "音声合成する", - "operationId": "synthesis_synthesis_post", - "parameters": [ - { - "required": true, - "schema": { - "type": "integer", - "title": "Speaker" - }, - "name": "speaker", - "in": "query" - }, - { - "description": "疑問系のテキストが与えられたら語尾を自動調整する", - "required": false, - "schema": { - "type": "boolean", - "title": "Enable Interrogative Upspeak", - "description": "疑問系のテキストが与えられたら語尾を自動調整する", - "default": true - }, - "name": "enable_interrogative_upspeak", - "in": "query" - }, - { - "required": false, - "schema": { - "type": "string", - "title": "Core Version" - }, - "name": "core_version", - "in": "query" - } - ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/AudioQuery" - } - } - }, - "required": true - }, - "responses": { - "200": { - "description": "Successful Response", - "content": { - "audio/wav": { - "schema": { - "type": "string", - "format": "binary" - } - } - } - }, - "422": { - "description": "Validation Error", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/HTTPValidationError" - } - } - } - } - } - } - }, - "/cancellable_synthesis": { - "post": { - "tags": [ - "音声合成" - ], - "summary": "音声合成する(キャンセル可能)", - "operationId": "cancellable_synthesis_cancellable_synthesis_post", - "parameters": [ - { - "required": true, - "schema": { - "type": "integer", - "title": "Speaker" - }, - "name": "speaker", - "in": "query" - }, - { - "required": false, - "schema": { - "type": "string", - "title": "Core Version" - }, - "name": "core_version", - "in": "query" - } - ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/AudioQuery" - } - } - }, - "required": true - }, - "responses": { - "200": { - "description": "Successful Response", - "content": { - "audio/wav": { - "schema": { - "type": "string", - "format": "binary" - } - } - } - }, - "422": { - "description": "Validation Error", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/HTTPValidationError" - } - } - } - } - } - } - }, - "/multi_synthesis": { - "post": { - "tags": [ - "音声合成" - ], - "summary": "複数まとめて音声合成する", - "operationId": "multi_synthesis_multi_synthesis_post", - "parameters": [ - { - "required": true, - "schema": { - "type": "integer", - "title": "Speaker" - }, - "name": "speaker", - "in": "query" - }, - { - "required": false, - "schema": { - "type": "string", - "title": "Core Version" - }, - "name": "core_version", - "in": "query" - } - ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "items": { - "$ref": "#/components/schemas/AudioQuery" - }, - "type": "array", - "title": "Queries" - } - } - }, - "required": true - }, - "responses": { - "200": { - "description": "Successful Response", - "content": { - "application/zip": { - "schema": { - "type": "string", - "format": "binary" - } - } - } - }, - "422": { - "description": "Validation Error", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/HTTPValidationError" - } - } - } - } - } - } - }, - "/morphable_targets": { - "post": { - "tags": [ - "音声合成" - ], - "summary": "指定したスタイルに対してエンジン内の話者がモーフィングが可能か判定する", - "description": "指定されたベーススタイルに対してエンジン内の各話者がモーフィング機能を利用可能か返します。\nモーフィングの許可/禁止は`/speakers`の`speaker.supported_features.synthesis_morphing`に記載されています。\nプロパティが存在しない場合は、モーフィングが許可されているとみなします。\n返り値のスタイルIDはstring型なので注意。", - "operationId": "morphable_targets_morphable_targets_post", - "parameters": [ - { - "required": false, - "schema": { - "type": "string", - "title": "Core Version" - }, - "name": "core_version", - "in": "query" - } - ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "items": { - "type": "integer" - }, - "type": "array", - "title": "Base Style Ids" - } - } - }, - "required": true - }, - "responses": { - "200": { - "description": "Successful Response", - "content": { - "application/json": { - "schema": { - "items": { - "additionalProperties": { - "$ref": "#/components/schemas/MorphableTargetInfo" - }, - "type": "object" - }, - "type": "array", - "title": "Response Morphable Targets Morphable Targets Post" - } - } - } - }, - "422": { - "description": "Validation Error", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/HTTPValidationError" - } - } - } - } - } - } - }, - "/synthesis_morphing": { - "post": { - "tags": [ - "音声合成" - ], - "summary": "2種類のスタイルでモーフィングした音声を合成する", - "description": "指定された2種類のスタイルで音声を合成、指定した割合でモーフィングした音声を得ます。\nモーフィングの割合は`morph_rate`で指定でき、0.0でベースのスタイル、1.0でターゲットのスタイルに近づきます。", - "operationId": "_synthesis_morphing_synthesis_morphing_post", - "parameters": [ - { - "required": true, - "schema": { - "type": "integer", - "title": "Base Speaker" - }, - "name": "base_speaker", - "in": "query" - }, - { - "required": true, - "schema": { - "type": "integer", - "title": "Target Speaker" - }, - "name": "target_speaker", - "in": "query" - }, - { - "required": true, - "schema": { - "type": "number", - "maximum": 1.0, - "minimum": 0.0, - "title": "Morph Rate" - }, - "name": "morph_rate", - "in": "query" - }, - { - "required": false, - "schema": { - "type": "string", - "title": "Core Version" - }, - "name": "core_version", - "in": "query" - } - ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/AudioQuery" - } - } - }, - "required": true - }, - "responses": { - "200": { - "description": "Successful Response", - "content": { - "audio/wav": { - "schema": { - "type": "string", - "format": "binary" - } - } - } - }, - "422": { - "description": "Validation Error", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/HTTPValidationError" - } - } - } - } - } - } - }, - "/sing_frame_audio_query": { - "post": { - "tags": [ - "クエリ作成" - ], - "summary": "歌唱音声合成用のクエリを作成する", - "description": "歌唱音声合成用のクエリの初期値を得ます。ここで得られたクエリはそのまま歌唱音声合成に利用できます。各値の意味は`Schemas`を参照してください。", - "operationId": "sing_frame_audio_query_sing_frame_audio_query_post", - "parameters": [ - { - "required": true, - "schema": { - "type": "integer", - "title": "Speaker" - }, - "name": "speaker", - "in": "query" - }, - { - "required": false, - "schema": { - "type": "string", - "title": "Core Version" - }, - "name": "core_version", - "in": "query" - } - ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Score" - } - } - }, - "required": true - }, - "responses": { - "200": { - "description": "Successful Response", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/FrameAudioQuery" - } - } - } - }, - "422": { - "description": "Validation Error", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/HTTPValidationError" - } - } - } - } - } - } - }, - "/frame_synthesis": { - "post": { - "tags": [ - "音声合成" - ], - "summary": "Frame Synthesis", - "description": "歌唱音声合成を行います。", - "operationId": "frame_synthesis_frame_synthesis_post", - "parameters": [ - { - "required": true, - "schema": { - "type": "integer", - "title": "Speaker" - }, - "name": "speaker", - "in": "query" - }, - { - "required": false, - "schema": { - "type": "string", - "title": "Core Version" - }, - "name": "core_version", - "in": "query" - } - ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/FrameAudioQuery" - } - } - }, - "required": true - }, - "responses": { - "200": { - "description": "Successful Response", - "content": { - "audio/wav": { - "schema": { - "type": "string", - "format": "binary" - } - } - } - }, - "422": { - "description": "Validation Error", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/HTTPValidationError" - } - } - } - } - } - } - }, - "/connect_waves": { - "post": { - "tags": [ - "その他" - ], - "summary": "base64エンコードされた複数のwavデータを一つに結合する", - "description": "base64エンコードされたwavデータを一纏めにし、wavファイルで返します。", - "operationId": "connect_waves_connect_waves_post", - "requestBody": { - "content": { - "application/json": { - "schema": { - "items": { - "type": "string" - }, - "type": "array", - "title": "Waves" - } - } - }, - "required": true - }, - "responses": { - "200": { - "description": "Successful Response", - "content": { - "audio/wav": { - "schema": { - "type": "string", - "format": "binary" - } - } - } - }, - "422": { - "description": "Validation Error", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/HTTPValidationError" - } - } - } - } - } - } - }, - "/presets": { - "get": { - "tags": [ - "その他" - ], - "summary": "Get Presets", - "description": "エンジンが保持しているプリセットの設定を返します", - "operationId": "get_presets_presets_get", - "responses": { - "200": { - "description": "プリセットのリスト", - "content": { - "application/json": { - "schema": { - "items": { - "$ref": "#/components/schemas/Preset" - }, - "type": "array", - "title": "Response Get Presets Presets Get" - } - } - } - } - } - } - }, - "/add_preset": { - "post": { - "tags": [ - "その他" - ], - "summary": "Add Preset", - "description": "新しいプリセットを追加します", - "operationId": "add_preset_add_preset_post", - "requestBody": { - "content": { - "application/json": { - "schema": { - "allOf": [ - { - "$ref": "#/components/schemas/Preset" - } - ], - "title": "Preset", - "description": "新しいプリセット。プリセットIDが既存のものと重複している場合は、新規のプリセットIDが採番されます。" - } - } - }, - "required": true - }, - "responses": { - "200": { - "description": "追加したプリセットのプリセットID", - "content": { - "application/json": { - "schema": { - "type": "integer", - "title": "Response Add Preset Add Preset Post" - } - } - } - }, - "422": { - "description": "Validation Error", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/HTTPValidationError" - } - } - } - } - } - } - }, - "/update_preset": { - "post": { - "tags": [ - "その他" - ], - "summary": "Update Preset", - "description": "既存のプリセットを更新します", - "operationId": "update_preset_update_preset_post", - "requestBody": { - "content": { - "application/json": { - "schema": { - "allOf": [ - { - "$ref": "#/components/schemas/Preset" - } - ], - "title": "Preset", - "description": "更新するプリセット。プリセットIDが更新対象と一致している必要があります。" - } - } - }, - "required": true - }, - "responses": { - "200": { - "description": "更新したプリセットのプリセットID", - "content": { - "application/json": { - "schema": { - "type": "integer", - "title": "Response Update Preset Update Preset Post" - } - } - } - }, - "422": { - "description": "Validation Error", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/HTTPValidationError" - } - } - } - } - } - } - }, - "/delete_preset": { - "post": { - "tags": [ - "その他" - ], - "summary": "Delete Preset", - "description": "既存のプリセットを削除します", - "operationId": "delete_preset_delete_preset_post", - "parameters": [ - { - "description": "削除するプリセットのプリセットID", - "required": true, - "schema": { - "type": "integer", - "title": "Id", - "description": "削除するプリセットのプリセットID" - }, - "name": "id", - "in": "query" - } - ], - "responses": { - "204": { - "description": "Successful Response" - }, - "422": { - "description": "Validation Error", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/HTTPValidationError" - } - } - } - } - } - } - }, - "/version": { - "get": { - "tags": [ - "その他" - ], - "summary": "Version", - "operationId": "version_version_get", - "responses": { - "200": { - "description": "Successful Response", - "content": { - "application/json": { - "schema": { - "type": "string", - "title": "Response Version Version Get" - } - } - } - } - } - } - }, - "/core_versions": { - "get": { - "tags": [ - "その他" - ], - "summary": "Core Versions", - "operationId": "core_versions_core_versions_get", - "responses": { - "200": { - "description": "Successful Response", - "content": { - "application/json": { - "schema": { - "items": { - "type": "string" - }, - "type": "array", - "title": "Response Core Versions Core Versions Get" - } - } - } - } - } - } - }, - "/speakers": { - "get": { - "tags": [ - "その他" - ], - "summary": "Speakers", - "operationId": "speakers_speakers_get", - "parameters": [ - { - "required": false, - "schema": { - "type": "string", - "title": "Core Version" - }, - "name": "core_version", - "in": "query" - } - ], - "responses": { - "200": { - "description": "Successful Response", - "content": { - "application/json": { - "schema": { - "items": { - "$ref": "#/components/schemas/Speaker" - }, - "type": "array", - "title": "Response Speakers Speakers Get" - } - } - } - }, - "422": { - "description": "Validation Error", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/HTTPValidationError" - } - } - } - } - } - } - }, - "/speaker_info": { - "get": { - "tags": [ - "その他" - ], - "summary": "Speaker Info", - "description": "指定されたspeaker_uuidに関する情報をjson形式で返します。\n画像や音声はbase64エンコードされたものが返されます。", - "operationId": "speaker_info_speaker_info_get", - "parameters": [ - { - "required": true, - "schema": { - "type": "string", - "title": "Speaker Uuid" - }, - "name": "speaker_uuid", - "in": "query" - }, - { - "required": false, - "schema": { - "type": "string", - "title": "Core Version" - }, - "name": "core_version", - "in": "query" - } - ], - "responses": { - "200": { - "description": "Successful Response", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/SpeakerInfo" - } - } - } - }, - "422": { - "description": "Validation Error", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/HTTPValidationError" - } - } - } - } - } - } - }, - "/singers": { - "get": { - "tags": [ - "その他" - ], - "summary": "Singers", - "operationId": "singers_singers_get", - "parameters": [ - { - "required": false, - "schema": { - "type": "string", - "title": "Core Version" - }, - "name": "core_version", - "in": "query" - } - ], - "responses": { - "200": { - "description": "Successful Response", - "content": { - "application/json": { - "schema": { - "items": { - "$ref": "#/components/schemas/Speaker" - }, - "type": "array", - "title": "Response Singers Singers Get" - } - } - } - }, - "422": { - "description": "Validation Error", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/HTTPValidationError" - } - } - } - } - } - } - }, - "/singer_info": { - "get": { - "tags": [ - "その他" - ], - "summary": "Singer Info", - "description": "指定されたspeaker_uuidに関する情報をjson形式で返します。\n画像や音声はbase64エンコードされたものが返されます。", - "operationId": "singer_info_singer_info_get", - "parameters": [ - { - "required": true, - "schema": { - "type": "string", - "title": "Speaker Uuid" - }, - "name": "speaker_uuid", - "in": "query" - }, - { - "required": false, - "schema": { - "type": "string", - "title": "Core Version" - }, - "name": "core_version", - "in": "query" - } - ], - "responses": { - "200": { - "description": "Successful Response", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/SpeakerInfo" - } - } - } - }, - "422": { - "description": "Validation Error", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/HTTPValidationError" - } - } - } - } - } - } - }, - "/downloadable_libraries": { - "get": { - "tags": [ - "音声ライブラリ管理" - ], - "summary": "Downloadable Libraries", - "description": "ダウンロード可能な音声ライブラリの情報を返します。", - "operationId": "downloadable_libraries_downloadable_libraries_get", - "responses": { - "200": { - "description": "ダウンロード可能な音声ライブラリの情報リスト", - "content": { - "application/json": { - "schema": { - "items": { - "$ref": "#/components/schemas/DownloadableLibraryInfo" - }, - "type": "array", - "title": "Response Downloadable Libraries Downloadable Libraries Get" - } - } - } - } - } - } - }, - "/installed_libraries": { - "get": { - "tags": [ - "音声ライブラリ管理" - ], - "summary": "Installed Libraries", - "description": "インストールした音声ライブラリの情報を返します。", - "operationId": "installed_libraries_installed_libraries_get", - "responses": { - "200": { - "description": "インストールした音声ライブラリの情報", - "content": { - "application/json": { - "schema": { - "additionalProperties": { - "$ref": "#/components/schemas/InstalledLibraryInfo" - }, - "type": "object", - "title": "Response Installed Libraries Installed Libraries Get" - } - } - } - } - } - } - }, - "/install_library/{library_uuid}": { - "post": { - "tags": [ - "音声ライブラリ管理" - ], - "summary": "Install Library", - "description": "音声ライブラリをインストールします。\n音声ライブラリのZIPファイルをリクエストボディとして送信してください。", - "operationId": "install_library_install_library__library_uuid__post", - "parameters": [ - { - "description": "音声ライブラリのID", - "required": true, - "schema": { - "type": "string", - "title": "Library Uuid", - "description": "音声ライブラリのID" - }, - "name": "library_uuid", - "in": "path" - } - ], - "responses": { - "204": { - "description": "Successful Response" - }, - "422": { - "description": "Validation Error", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/HTTPValidationError" - } - } - } - } - } - } - }, - "/uninstall_library/{library_uuid}": { - "post": { - "tags": [ - "音声ライブラリ管理" - ], - "summary": "Uninstall Library", - "description": "音声ライブラリをアンインストールします。", - "operationId": "uninstall_library_uninstall_library__library_uuid__post", - "parameters": [ - { - "description": "音声ライブラリのID", - "required": true, - "schema": { - "type": "string", - "title": "Library Uuid", - "description": "音声ライブラリのID" - }, - "name": "library_uuid", - "in": "path" - } - ], - "responses": { - "204": { - "description": "Successful Response" - }, - "422": { - "description": "Validation Error", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/HTTPValidationError" - } - } - } - } - } - } - }, - "/initialize_speaker": { - "post": { - "tags": [ - "その他" - ], - "summary": "Initialize Speaker", - "description": "指定されたスタイルを初期化します。\n実行しなくても他のAPIは使用できますが、初回実行時に時間がかかることがあります。", - "operationId": "initialize_speaker_initialize_speaker_post", - "parameters": [ - { - "required": true, - "schema": { - "type": "integer", - "title": "Speaker" - }, - "name": "speaker", - "in": "query" - }, - { - "description": "既に初期化済みのスタイルの再初期化をスキップするかどうか", - "required": false, - "schema": { - "type": "boolean", - "title": "Skip Reinit", - "description": "既に初期化済みのスタイルの再初期化をスキップするかどうか", - "default": false - }, - "name": "skip_reinit", - "in": "query" - }, - { - "required": false, - "schema": { - "type": "string", - "title": "Core Version" - }, - "name": "core_version", - "in": "query" - } - ], - "responses": { - "204": { - "description": "Successful Response" - }, - "422": { - "description": "Validation Error", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/HTTPValidationError" - } - } - } - } - } - } - }, - "/is_initialized_speaker": { - "get": { - "tags": [ - "その他" - ], - "summary": "Is Initialized Speaker", - "description": "指定されたスタイルが初期化されているかどうかを返します。", - "operationId": "is_initialized_speaker_is_initialized_speaker_get", - "parameters": [ - { - "required": true, - "schema": { - "type": "integer", - "title": "Speaker" - }, - "name": "speaker", - "in": "query" - }, - { - "required": false, - "schema": { - "type": "string", - "title": "Core Version" - }, - "name": "core_version", - "in": "query" - } - ], - "responses": { - "200": { - "description": "Successful Response", - "content": { - "application/json": { - "schema": { - "type": "boolean", - "title": "Response Is Initialized Speaker Is Initialized Speaker Get" - } - } - } - }, - "422": { - "description": "Validation Error", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/HTTPValidationError" - } - } - } - } - } - } - }, - "/user_dict": { - "get": { - "tags": [ - "ユーザー辞書" - ], - "summary": "Get User Dict Words", - "description": "ユーザー辞書に登録されている単語の一覧を返します。\n単語の表層形(surface)は正規化済みの物を返します。", - "operationId": "get_user_dict_words_user_dict_get", - "responses": { - "200": { - "description": "単語のUUIDとその詳細", - "content": { - "application/json": { - "schema": { - "additionalProperties": { - "$ref": "#/components/schemas/UserDictWord" - }, - "type": "object", - "title": "Response Get User Dict Words User Dict Get" - } - } - } - } - } - } - }, - "/user_dict_word": { - "post": { - "tags": [ - "ユーザー辞書" - ], - "summary": "Add User Dict Word", - "description": "ユーザー辞書に言葉を追加します。", - "operationId": "add_user_dict_word_user_dict_word_post", - "parameters": [ - { - "description": "言葉の表層形", - "required": true, - "schema": { - "type": "string", - "title": "Surface", - "description": "言葉の表層形" - }, - "name": "surface", - "in": "query" - }, - { - "description": "言葉の発音(カタカナ)", - "required": true, - "schema": { - "type": "string", - "title": "Pronunciation", - "description": "言葉の発音(カタカナ)" - }, - "name": "pronunciation", - "in": "query" - }, - { - "description": "アクセント型(音が下がる場所を指す)", - "required": true, - "schema": { - "type": "integer", - "title": "Accent Type", - "description": "アクセント型(音が下がる場所を指す)" - }, - "name": "accent_type", - "in": "query" - }, - { - "description": "PROPER_NOUN(固有名詞)、COMMON_NOUN(普通名詞)、VERB(動詞)、ADJECTIVE(形容詞)、SUFFIX(語尾)のいずれか", - "required": false, - "schema": { - "allOf": [ - { - "$ref": "#/components/schemas/WordTypes" - } - ], - "description": "PROPER_NOUN(固有名詞)、COMMON_NOUN(普通名詞)、VERB(動詞)、ADJECTIVE(形容詞)、SUFFIX(語尾)のいずれか" - }, - "name": "word_type", - "in": "query" - }, - { - "description": "単語の優先度(0から10までの整数)。数字が大きいほど優先度が高くなる。1から9までの値を指定することを推奨", - "required": false, - "schema": { - "type": "integer", - "maximum": 10.0, - "minimum": 0.0, - "title": "Priority", - "description": "単語の優先度(0から10までの整数)。数字が大きいほど優先度が高くなる。1から9までの値を指定することを推奨" - }, - "name": "priority", - "in": "query" - } - ], - "responses": { - "200": { - "description": "Successful Response", - "content": { - "application/json": { - "schema": { - "type": "string", - "title": "Response Add User Dict Word User Dict Word Post" - } - } - } - }, - "422": { - "description": "Validation Error", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/HTTPValidationError" - } - } - } - } - } - } - }, - "/user_dict_word/{word_uuid}": { - "put": { - "tags": [ - "ユーザー辞書" - ], - "summary": "Rewrite User Dict Word", - "description": "ユーザー辞書に登録されている言葉を更新します。", - "operationId": "rewrite_user_dict_word_user_dict_word__word_uuid__put", - "parameters": [ - { - "description": "更新する言葉のUUID", - "required": true, - "schema": { - "type": "string", - "title": "Word Uuid", - "description": "更新する言葉のUUID" - }, - "name": "word_uuid", - "in": "path" - }, - { - "description": "言葉の表層形", - "required": true, - "schema": { - "type": "string", - "title": "Surface", - "description": "言葉の表層形" - }, - "name": "surface", - "in": "query" - }, - { - "description": "言葉の発音(カタカナ)", - "required": true, - "schema": { - "type": "string", - "title": "Pronunciation", - "description": "言葉の発音(カタカナ)" - }, - "name": "pronunciation", - "in": "query" - }, - { - "description": "アクセント型(音が下がる場所を指す)", - "required": true, - "schema": { - "type": "integer", - "title": "Accent Type", - "description": "アクセント型(音が下がる場所を指す)" - }, - "name": "accent_type", - "in": "query" - }, - { - "description": "PROPER_NOUN(固有名詞)、COMMON_NOUN(普通名詞)、VERB(動詞)、ADJECTIVE(形容詞)、SUFFIX(語尾)のいずれか", - "required": false, - "schema": { - "allOf": [ - { - "$ref": "#/components/schemas/WordTypes" - } - ], - "description": "PROPER_NOUN(固有名詞)、COMMON_NOUN(普通名詞)、VERB(動詞)、ADJECTIVE(形容詞)、SUFFIX(語尾)のいずれか" - }, - "name": "word_type", - "in": "query" - }, - { - "description": "単語の優先度(0から10までの整数)。数字が大きいほど優先度が高くなる。1から9までの値を指定することを推奨。", - "required": false, - "schema": { - "type": "integer", - "maximum": 10.0, - "minimum": 0.0, - "title": "Priority", - "description": "単語の優先度(0から10までの整数)。数字が大きいほど優先度が高くなる。1から9までの値を指定することを推奨。" - }, - "name": "priority", - "in": "query" - } - ], - "responses": { - "204": { - "description": "Successful Response" - }, - "422": { - "description": "Validation Error", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/HTTPValidationError" - } - } - } - } - } - }, - "delete": { - "tags": [ - "ユーザー辞書" - ], - "summary": "Delete User Dict Word", - "description": "ユーザー辞書に登録されている言葉を削除します。", - "operationId": "delete_user_dict_word_user_dict_word__word_uuid__delete", - "parameters": [ - { - "description": "削除する言葉のUUID", - "required": true, - "schema": { - "type": "string", - "title": "Word Uuid", - "description": "削除する言葉のUUID" - }, - "name": "word_uuid", - "in": "path" - } - ], - "responses": { - "204": { - "description": "Successful Response" - }, - "422": { - "description": "Validation Error", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/HTTPValidationError" - } - } - } - } - } - } - }, - "/import_user_dict": { - "post": { - "tags": [ - "ユーザー辞書" - ], - "summary": "Import User Dict Words", - "description": "他のユーザー辞書をインポートします。", - "operationId": "import_user_dict_words_import_user_dict_post", - "parameters": [ - { - "description": "重複したエントリがあった場合、上書きするかどうか", - "required": true, - "schema": { - "type": "boolean", - "title": "Override", - "description": "重複したエントリがあった場合、上書きするかどうか" - }, - "name": "override", - "in": "query" - } - ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "additionalProperties": { - "$ref": "#/components/schemas/UserDictWord" - }, - "type": "object", - "title": "Import Dict Data", - "description": "インポートするユーザー辞書のデータ" - } - } - }, - "required": true - }, - "responses": { - "204": { - "description": "Successful Response" - }, - "422": { - "description": "Validation Error", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/HTTPValidationError" - } - } - } - } - } - } - }, - "/supported_devices": { - "get": { - "tags": [ - "その他" - ], - "summary": "Supported Devices", - "operationId": "supported_devices_supported_devices_get", - "parameters": [ - { - "required": false, - "schema": { - "type": "string", - "title": "Core Version" - }, - "name": "core_version", - "in": "query" - } - ], - "responses": { - "200": { - "description": "Successful Response", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/SupportedDevicesInfo" - } - } - } - }, - "422": { - "description": "Validation Error", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/HTTPValidationError" - } - } - } - } - } - } - }, - "/engine_manifest": { - "get": { - "tags": [ - "その他" - ], - "summary": "Engine Manifest", - "operationId": "engine_manifest_engine_manifest_get", - "responses": { - "200": { - "description": "Successful Response", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/EngineManifest" - } - } - } - } - } - } - }, - "/validate_kana": { - "post": { - "tags": [ - "その他" - ], - "summary": "テキストがAquesTalk 風記法に従っているか判定する", - "description": "テキストがAquesTalk 風記法に従っているかどうかを判定します。\n従っていない場合はエラーが返ります。", - "operationId": "validate_kana_validate_kana_post", - "parameters": [ - { - "description": "判定する対象の文字列", - "required": true, - "schema": { - "type": "string", - "title": "Text", - "description": "判定する対象の文字列" - }, - "name": "text", - "in": "query" - } - ], - "responses": { - "200": { - "description": "Successful Response", - "content": { - "application/json": { - "schema": { - "type": "boolean", - "title": "Response Validate Kana Validate Kana Post" - } - } - } - }, - "400": { - "description": "テキストが不正です", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ParseKanaBadRequest" - } - } - } - }, - "422": { - "description": "Validation Error", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/HTTPValidationError" - } - } - } - } - } - } - }, - "/setting": { - "get": { - "tags": [ - "設定" - ], - "summary": "Setting Get", - "description": "設定ページを返します。", - "operationId": "setting_get_setting_get", - "responses": { - "200": { - "description": "Successful Response" - } - } - }, - "post": { - "tags": [ - "設定" - ], - "summary": "Setting Post", - "description": "設定を更新します。", - "operationId": "setting_post_setting_post", - "requestBody": { - "content": { - "application/x-www-form-urlencoded": { - "schema": { - "$ref": "#/components/schemas/Body_setting_post_setting_post" - } - } - }, - "required": true - }, - "responses": { - "200": { - "description": "Successful Response" - }, - "422": { - "description": "Validation Error", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/HTTPValidationError" - } - } - } - } - } - } - } - }, - "components": { - "schemas": { - "AccentPhrase": { - "properties": { - "moras": { - "items": { - "$ref": "#/components/schemas/Mora" - }, - "type": "array", - "title": "モーラのリスト" - }, - "accent": { - "type": "integer", - "title": "アクセント箇所" - }, - "pause_mora": { - "allOf": [ - { - "$ref": "#/components/schemas/Mora" - } - ], - "title": "後ろに無音を付けるかどうか" - }, - "is_interrogative": { - "type": "boolean", - "title": "疑問系かどうか", - "default": false - } - }, - "type": "object", - "required": [ - "moras", - "accent" - ], - "title": "AccentPhrase", - "description": "アクセント句ごとの情報" - }, - "AudioQuery": { - "properties": { - "accent_phrases": { - "items": { - "$ref": "#/components/schemas/AccentPhrase" - }, - "type": "array", - "title": "アクセント句のリスト" - }, - "speedScale": { - "type": "number", - "title": "全体の話速" - }, - "pitchScale": { - "type": "number", - "title": "全体の音高" - }, - "intonationScale": { - "type": "number", - "title": "全体の抑揚" - }, - "volumeScale": { - "type": "number", - "title": "全体の音量" - }, - "prePhonemeLength": { - "type": "number", - "title": "音声の前の無音時間" - }, - "postPhonemeLength": { - "type": "number", - "title": "音声の後の無音時間" - }, - "pauseLength": { - "type": "number", - "title": "読点や括弧等の無音時間(絶対値)" - }, - "pauseLengthScale": { - "type": "number", - "title": "読点や括弧等の無音時間(倍率)" - }, - "outputSamplingRate": { - "type": "integer", - "title": "音声データの出力サンプリングレート" - }, - "outputStereo": { - "type": "boolean", - "title": "音声データをステレオ出力するか否か" - }, - "kana": { - "type": "string", - "title": "[読み取り専用]AquesTalk 風記法によるテキスト。音声合成用のクエリとしては無視される" - } - }, - "type": "object", - "required": [ - "accent_phrases", - "speedScale", - "pitchScale", - "intonationScale", - "volumeScale", - "prePhonemeLength", - "postPhonemeLength", - "pauseLength", - "pauseLengthScale", - "outputSamplingRate", - "outputStereo" - ], - "title": "AudioQuery", - "description": "音声合成用のクエリ" - }, - "Body_setting_post_setting_post": { - "properties": { - "cors_policy_mode": { - "$ref": "#/components/schemas/CorsPolicyMode" - }, - "allow_origin": { - "type": "string", - "title": "Allow Origin" - } - }, - "type": "object", - "required": [ - "cors_policy_mode" - ], - "title": "Body_setting_post_setting_post" - }, - "CorsPolicyMode": { - "type": "string", - "enum": [ - "all", - "localapps" - ], - "title": "CorsPolicyMode", - "description": "CORSの許可モード" - }, - "DownloadableLibraryInfo": { - "properties": { - "name": { - "type": "string", - "title": "音声ライブラリの名前" - }, - "uuid": { - "type": "string", - "title": "音声ライブラリのUUID" - }, - "version": { - "type": "string", - "title": "音声ライブラリのバージョン" - }, - "download_url": { - "type": "string", - "title": "音声ライブラリのダウンロードURL" - }, - "bytes": { - "type": "integer", - "title": "音声ライブラリのバイト数" - }, - "speakers": { - "items": { - "$ref": "#/components/schemas/LibrarySpeaker" - }, - "type": "array", - "title": "音声ライブラリに含まれる話者のリスト" - } - }, - "type": "object", - "required": [ - "name", - "uuid", - "version", - "download_url", - "bytes", - "speakers" - ], - "title": "DownloadableLibraryInfo", - "description": "ダウンロード可能な音声ライブラリの情報" - }, - "EngineManifest": { - "properties": { - "manifest_version": { - "type": "string", - "title": "マニフェストのバージョン" - }, - "name": { - "type": "string", - "title": "エンジン名" - }, - "brand_name": { - "type": "string", - "title": "ブランド名" - }, - "uuid": { - "type": "string", - "title": "エンジンのUUID" - }, - "url": { - "type": "string", - "title": "エンジンのURL" - }, - "icon": { - "type": "string", - "title": "エンジンのアイコンをBASE64エンコードしたもの" - }, - "default_sampling_rate": { - "type": "integer", - "title": "デフォルトのサンプリング周波数" - }, - "frame_rate": { - "type": "number", - "title": "エンジンのフレームレート" - }, - "terms_of_service": { - "type": "string", - "title": "エンジンの利用規約" - }, - "update_infos": { - "items": { - "$ref": "#/components/schemas/UpdateInfo" - }, - "type": "array", - "title": "エンジンのアップデート情報" - }, - "dependency_licenses": { - "items": { - "$ref": "#/components/schemas/LicenseInfo" - }, - "type": "array", - "title": "依存関係のライセンス情報" - }, - "supported_vvlib_manifest_version": { - "type": "string", - "title": "エンジンが対応するvvlibのバージョン" - }, - "supported_features": { - "allOf": [ - { - "$ref": "#/components/schemas/SupportedFeatures" - } - ], - "title": "エンジンが持つ機能" - } - }, - "type": "object", - "required": [ - "manifest_version", - "name", - "brand_name", - "uuid", - "url", - "icon", - "default_sampling_rate", - "frame_rate", - "terms_of_service", - "update_infos", - "dependency_licenses", - "supported_features" - ], - "title": "EngineManifest", - "description": "エンジン自体に関する情報" - }, - "FrameAudioQuery": { - "properties": { - "f0": { - "items": { - "type": "number" - }, - "type": "array", - "title": "フレームごとの基本周波数" - }, - "volume": { - "items": { - "type": "number" - }, - "type": "array", - "title": "フレームごとの音量" - }, - "phonemes": { - "items": { - "$ref": "#/components/schemas/FramePhoneme" - }, - "type": "array", - "title": "音素のリスト" - }, - "volumeScale": { - "type": "number", - "title": "全体の音量" - }, - "outputSamplingRate": { - "type": "integer", - "title": "音声データの出力サンプリングレート" - }, - "outputStereo": { - "type": "boolean", - "title": "音声データをステレオ出力するか否か" - } - }, - "type": "object", - "required": [ - "f0", - "volume", - "phonemes", - "volumeScale", - "outputSamplingRate", - "outputStereo" - ], - "title": "FrameAudioQuery", - "description": "フレームごとの音声合成用のクエリ" - }, - "FramePhoneme": { - "properties": { - "phoneme": { - "type": "string", - "title": "音素" - }, - "frame_length": { - "type": "integer", - "title": "音素のフレーム長" - } - }, - "type": "object", - "required": [ - "phoneme", - "frame_length" - ], - "title": "FramePhoneme", - "description": "音素の情報" - }, - "HTTPValidationError": { - "properties": { - "detail": { - "items": { - "$ref": "#/components/schemas/ValidationError" - }, - "type": "array", - "title": "Detail" - } - }, - "type": "object", - "title": "HTTPValidationError" - }, - "InstalledLibraryInfo": { - "properties": { - "name": { - "type": "string", - "title": "音声ライブラリの名前" - }, - "uuid": { - "type": "string", - "title": "音声ライブラリのUUID" - }, - "version": { - "type": "string", - "title": "音声ライブラリのバージョン" - }, - "download_url": { - "type": "string", - "title": "音声ライブラリのダウンロードURL" - }, - "bytes": { - "type": "integer", - "title": "音声ライブラリのバイト数" - }, - "speakers": { - "items": { - "$ref": "#/components/schemas/LibrarySpeaker" - }, - "type": "array", - "title": "音声ライブラリに含まれる話者のリスト" - }, - "uninstallable": { - "type": "boolean", - "title": "アンインストール可能かどうか" - } - }, - "type": "object", - "required": [ - "name", - "uuid", - "version", - "download_url", - "bytes", - "speakers", - "uninstallable" - ], - "title": "InstalledLibraryInfo", - "description": "インストール済み音声ライブラリの情報" - }, - "LibrarySpeaker": { - "properties": { - "speaker": { - "allOf": [ - { - "$ref": "#/components/schemas/Speaker" - } - ], - "title": "話者情報" - }, - "speaker_info": { - "allOf": [ - { - "$ref": "#/components/schemas/SpeakerInfo" - } - ], - "title": "話者の追加情報" - } - }, - "type": "object", - "required": [ - "speaker", - "speaker_info" - ], - "title": "LibrarySpeaker", - "description": "音声ライブラリに含まれる話者の情報" - }, - "LicenseInfo": { - "properties": { - "name": { - "type": "string", - "title": "依存ライブラリ名" - }, - "version": { - "type": "string", - "title": "依存ライブラリのバージョン" - }, - "license": { - "type": "string", - "title": "依存ライブラリのライセンス名" - }, - "text": { - "type": "string", - "title": "依存ライブラリのライセンス本文" - } - }, - "type": "object", - "required": [ - "name", - "text" - ], - "title": "LicenseInfo", - "description": "依存ライブラリのライセンス情報" - }, - "Mora": { - "properties": { - "text": { - "type": "string", - "title": "文字" - }, - "consonant": { - "type": "string", - "title": "子音の音素" - }, - "consonant_length": { - "type": "number", - "title": "子音の音長" - }, - "vowel": { - "type": "string", - "title": "母音の音素" - }, - "vowel_length": { - "type": "number", - "title": "母音の音長" - }, - "pitch": { - "type": "number", - "title": "音高" - } - }, - "type": "object", - "required": [ - "text", - "vowel", - "vowel_length", - "pitch" - ], - "title": "Mora", - "description": "モーラ(子音+母音)ごとの情報" - }, - "MorphableTargetInfo": { - "properties": { - "is_morphable": { - "type": "boolean", - "title": "指定した話者に対してモーフィングの可否" - } - }, - "type": "object", - "required": [ - "is_morphable" - ], - "title": "MorphableTargetInfo" - }, - "Note": { - "properties": { - "key": { - "type": "integer", - "title": "音階" - }, - "frame_length": { - "type": "integer", - "title": "音符のフレーム長" - }, - "lyric": { - "type": "string", - "title": "音符の歌詞" - } - }, - "type": "object", - "required": [ - "frame_length", - "lyric" - ], - "title": "Note", - "description": "音符ごとの情報" - }, - "ParseKanaBadRequest": { - "properties": { - "text": { - "type": "string", - "title": "エラーメッセージ" - }, - "error_name": { - "type": "string", - "title": "エラー名", - "description": "|name|description|\n|---|---|\n| UNKNOWN_TEXT | 判別できない読み仮名があります: {text} |\n| ACCENT_TOP | 句頭にアクセントは置けません: {text} |\n| ACCENT_TWICE | 1つのアクセント句に二つ以上のアクセントは置けません: {text} |\n| ACCENT_NOTFOUND | アクセントを指定していないアクセント句があります: {text} |\n| EMPTY_PHRASE | {position}番目のアクセント句が空白です |\n| INTERROGATION_MARK_NOT_AT_END | アクセント句末以外に「?」は置けません: {text} |\n| INFINITE_LOOP | 処理時に無限ループになってしまいました...バグ報告をお願いします。 |" - }, - "error_args": { - "additionalProperties": { - "type": "string" - }, - "type": "object", - "title": "エラーを起こした箇所" - } - }, - "type": "object", - "required": [ - "text", - "error_name", - "error_args" - ], - "title": "ParseKanaBadRequest" - }, - "Preset": { - "properties": { - "id": { - "type": "integer", - "title": "プリセットID" - }, - "name": { - "type": "string", - "title": "プリセット名" - }, - "speaker_uuid": { - "type": "string", - "title": "話者のUUID" - }, - "style_id": { - "type": "integer", - "title": "スタイルID" - }, - "speedScale": { - "type": "number", - "title": "全体の話速" - }, - "pitchScale": { - "type": "number", - "title": "全体の音高" - }, - "intonationScale": { - "type": "number", - "title": "全体の抑揚" - }, - "volumeScale": { - "type": "number", - "title": "全体の音量" - }, - "prePhonemeLength": { - "type": "number", - "title": "音声の前の無音時間" - }, - "postPhonemeLength": { - "type": "number", - "title": "音声の後の無音時間" - }, - "pauseLength": { - "type": "number", - "title": "読点や括弧等の無音時間(絶対値)" - }, - "pauseLengthScale": { - "type": "number", - "title": "読点や括弧等の無音時間(倍率)" - } - }, - "type": "object", - "required": [ - "id", - "name", - "speaker_uuid", - "style_id", - "speedScale", - "pitchScale", - "intonationScale", - "volumeScale", - "prePhonemeLength", - "postPhonemeLength", - "pauseLength", - "pauseLengthScale" - ], - "title": "Preset", - "description": "プリセット情報" - }, - "Score": { - "properties": { - "notes": { - "items": { - "$ref": "#/components/schemas/Note" - }, - "type": "array", - "title": "音符のリスト" - } - }, - "type": "object", - "required": [ - "notes" - ], - "title": "Score", - "description": "楽譜情報" - }, - "Speaker": { - "properties": { - "supported_features": { - "allOf": [ - { - "$ref": "#/components/schemas/SpeakerSupportedFeatures" - } - ], - "title": "話者の対応機能" - }, - "name": { - "type": "string", - "title": "名前" - }, - "speaker_uuid": { - "type": "string", - "title": "話者のUUID" - }, - "styles": { - "items": { - "$ref": "#/components/schemas/SpeakerStyle" - }, - "type": "array", - "title": "スタイルの一覧" - }, - "version": { - "type": "string", - "title": "Version", - "default": "話者のバージョン" - } - }, - "type": "object", - "required": [ - "name", - "speaker_uuid", - "styles" - ], - "title": "Speaker", - "description": "話者情報" - }, - "SpeakerInfo": { - "properties": { - "policy": { - "type": "string", - "title": "policy.md" - }, - "portrait": { - "type": "string", - "title": "portrait.pngをbase64エンコードしたもの" - }, - "style_infos": { - "items": { - "$ref": "#/components/schemas/StyleInfo" - }, - "type": "array", - "title": "スタイルの追加情報" - } - }, - "type": "object", - "required": [ - "policy", - "portrait", - "style_infos" - ], - "title": "SpeakerInfo", - "description": "話者の追加情報" - }, - "SpeakerStyle": { - "properties": { - "name": { - "type": "string", - "title": "スタイル名" - }, - "id": { - "type": "integer", - "title": "スタイルID" - }, - "type": { - "type": "string", - "enum": [ - "talk", - "singing_teacher", - "frame_decode", - "sing" - ], - "title": "スタイルの種類。talk:音声合成クエリの作成と音声合成が可能。singing_teacher:歌唱音声合成用のクエリの作成が可能。frame_decode:歌唱音声合成が可能。sing:歌唱音声合成用のクエリの作成と歌唱音声合成が可能。", - "default": "talk" - } - }, - "type": "object", - "required": [ - "name", - "id" - ], - "title": "SpeakerStyle", - "description": "話者のスタイル情報" - }, - "SpeakerSupportPermittedSynthesisMorphing": { - "type": "string", - "enum": [ - "ALL", - "SELF_ONLY", - "NOTHING" - ], - "title": "SpeakerSupportPermittedSynthesisMorphing", - "description": "An enumeration." - }, - "SpeakerSupportedFeatures": { - "properties": { - "permitted_synthesis_morphing": { - "allOf": [ - { - "$ref": "#/components/schemas/SpeakerSupportPermittedSynthesisMorphing" - } - ], - "title": "モーフィング機能への対応", - "default": "ALL" - } - }, - "type": "object", - "title": "SpeakerSupportedFeatures", - "description": "話者の対応機能の情報" - }, - "StyleInfo": { - "properties": { - "id": { - "type": "integer", - "title": "スタイルID" - }, - "icon": { - "type": "string", - "title": "当該スタイルのアイコンをbase64エンコードしたもの" - }, - "portrait": { - "type": "string", - "title": "当該スタイルのportrait.pngをbase64エンコードしたもの" - }, - "voice_samples": { - "items": { - "type": "string" - }, - "type": "array", - "title": "voice_sampleのwavファイルをbase64エンコードしたもの" - } - }, - "type": "object", - "required": [ - "id", - "icon", - "voice_samples" - ], - "title": "StyleInfo", - "description": "スタイルの追加情報" - }, - "SupportedDevicesInfo": { - "properties": { - "cpu": { - "type": "boolean", - "title": "CPUに対応しているか" - }, - "cuda": { - "type": "boolean", - "title": "CUDA(Nvidia GPU)に対応しているか" - }, - "dml": { - "type": "boolean", - "title": "DirectML(Nvidia GPU/Radeon GPU等)に対応しているか" - } - }, - "type": "object", - "required": [ - "cpu", - "cuda", - "dml" - ], - "title": "SupportedDevicesInfo", - "description": "対応しているデバイスの情報" - }, - "SupportedFeatures": { - "properties": { - "adjust_mora_pitch": { - "type": "boolean", - "title": "モーラごとの音高の調整" - }, - "adjust_phoneme_length": { - "type": "boolean", - "title": "音素ごとの長さの調整" - }, - "adjust_speed_scale": { - "type": "boolean", - "title": "全体の話速の調整" - }, - "adjust_pitch_scale": { - "type": "boolean", - "title": "全体の音高の調整" - }, - "adjust_intonation_scale": { - "type": "boolean", - "title": "全体の抑揚の調整" - }, - "adjust_volume_scale": { - "type": "boolean", - "title": "全体の音量の調整" - }, - "interrogative_upspeak": { - "type": "boolean", - "title": "疑問文の自動調整" - }, - "synthesis_morphing": { - "type": "boolean", - "title": "2種類のスタイルでモーフィングした音声を合成" - }, - "sing": { - "type": "boolean", - "title": "歌唱音声合成" - }, - "manage_library": { - "type": "boolean", - "title": "音声ライブラリのインストール・アンインストール" - } - }, - "type": "object", - "required": [ - "adjust_mora_pitch", - "adjust_phoneme_length", - "adjust_speed_scale", - "adjust_pitch_scale", - "adjust_intonation_scale", - "adjust_volume_scale", - "interrogative_upspeak", - "synthesis_morphing" - ], - "title": "SupportedFeatures", - "description": "エンジンが持つ機能の一覧" - }, - "UpdateInfo": { - "properties": { - "version": { - "type": "string", - "title": "エンジンのバージョン名" - }, - "descriptions": { - "items": { - "type": "string" - }, - "type": "array", - "title": "アップデートの詳細についての説明" - }, - "contributors": { - "items": { - "type": "string" - }, - "type": "array", - "title": "貢献者名" - } - }, - "type": "object", - "required": [ - "version", - "descriptions" - ], - "title": "UpdateInfo", - "description": "エンジンのアップデート情報" - }, - "UserDictWord": { - "properties": { - "surface": { - "type": "string", - "title": "表層形" - }, - "priority": { - "type": "integer", - "maximum": 10.0, - "minimum": 0.0, - "title": "優先度" - }, - "context_id": { - "type": "integer", - "title": "文脈ID", - "default": 1348 - }, - "part_of_speech": { - "type": "string", - "title": "品詞" - }, - "part_of_speech_detail_1": { - "type": "string", - "title": "品詞細分類1" - }, - "part_of_speech_detail_2": { - "type": "string", - "title": "品詞細分類2" - }, - "part_of_speech_detail_3": { - "type": "string", - "title": "品詞細分類3" - }, - "inflectional_type": { - "type": "string", - "title": "活用型" - }, - "inflectional_form": { - "type": "string", - "title": "活用形" - }, - "stem": { - "type": "string", - "title": "原形" - }, - "yomi": { - "type": "string", - "title": "読み" - }, - "pronunciation": { - "type": "string", - "title": "発音" - }, - "accent_type": { - "type": "integer", - "title": "アクセント型" - }, - "mora_count": { - "type": "integer", - "title": "モーラ数" - }, - "accent_associative_rule": { - "type": "string", - "title": "アクセント結合規則" - } - }, - "type": "object", - "required": [ - "surface", - "priority", - "part_of_speech", - "part_of_speech_detail_1", - "part_of_speech_detail_2", - "part_of_speech_detail_3", - "inflectional_type", - "inflectional_form", - "stem", - "yomi", - "pronunciation", - "accent_type", - "accent_associative_rule" - ], - "title": "UserDictWord", - "description": "辞書のコンパイルに使われる情報" - }, - "ValidationError": { - "properties": { - "loc": { - "items": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "integer" - } - ] - }, - "type": "array", - "title": "Location" - }, - "msg": { - "type": "string", - "title": "Message" - }, - "type": { - "type": "string", - "title": "Error Type" - } - }, - "type": "object", - "required": [ - "loc", - "msg", - "type" - ], - "title": "ValidationError" - }, - "WordTypes": { - "type": "string", - "enum": [ - "PROPER_NOUN", - "COMMON_NOUN", - "VERB", - "ADJECTIVE", - "SUFFIX" - ], - "title": "WordTypes", - "description": "fastapiでword_type引数を検証する時に使用するクラス" - }, - "VvlibManifest": { - "title": "VvlibManifest", - "description": "vvlib(VOICEVOX Library)に関する情報", - "type": "object", - "properties": { - "manifest_version": { - "title": "マニフェストバージョン", - "type": "string" - }, - "name": { - "title": "音声ライブラリ名", - "type": "string" - }, - "version": { - "title": "音声ライブラリバージョン", - "type": "string" - }, - "uuid": { - "title": "音声ライブラリのUUID", - "type": "string" - }, - "brand_name": { - "title": "エンジンのブランド名", - "type": "string" - }, - "engine_name": { - "title": "エンジン名", - "type": "string" - }, - "engine_uuid": { - "title": "エンジンのUUID", - "type": "string" - } - }, - "required": [ - "manifest_version", - "name", - "version", - "uuid", - "brand_name", - "engine_name", - "engine_uuid" - ] - }, - "BaseLibraryInfo": { - "title": "BaseLibraryInfo", - "description": "音声ライブラリの情報", - "type": "object", - "properties": { - "name": { - "title": "音声ライブラリの名前", - "type": "string" - }, - "uuid": { - "title": "音声ライブラリのUUID", - "type": "string" - }, - "version": { - "title": "音声ライブラリのバージョン", - "type": "string" - }, - "download_url": { - "title": "音声ライブラリのダウンロードURL", - "type": "string" - }, - "bytes": { - "title": "音声ライブラリのバイト数", - "type": "integer" - }, - "speakers": { - "title": "音声ライブラリに含まれる話者のリスト", - "type": "array", - "items": { - "$ref": "#/components/schemas/LibrarySpeaker" - } - } - }, - "required": [ - "name", - "uuid", - "version", - "download_url", - "bytes", - "speakers" - ] - } - } - } -} +{"openapi":"3.1.0","info":{"title":"VOICEVOX Engine","description":"VOICEVOXの音声合成エンジンです。","version":"0.18.1"},"paths":{"/audio_query":{"post":{"tags":["クエリ作成"],"summary":"音声合成用のクエリを作成する","description":"音声合成用のクエリの初期値を得ます。ここで得られたクエリはそのまま音声合成に利用できます。各値の意味は`Schemas`を参照してください。","operationId":"audio_query_audio_query_post","parameters":[{"required":true,"schema":{"type":"string","title":"Text"},"name":"text","in":"query"},{"required":true,"schema":{"type":"integer","title":"Speaker"},"name":"speaker","in":"query"},{"required":false,"schema":{"type":"string","title":"Core Version"},"name":"core_version","in":"query"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AudioQuery"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/audio_query_from_preset":{"post":{"tags":["クエリ作成"],"summary":"音声合成用のクエリをプリセットを用いて作成する","description":"音声合成用のクエリの初期値を得ます。ここで得られたクエリはそのまま音声合成に利用できます。各値の意味は`Schemas`を参照してください。","operationId":"audio_query_from_preset_audio_query_from_preset_post","parameters":[{"required":true,"schema":{"type":"string","title":"Text"},"name":"text","in":"query"},{"required":true,"schema":{"type":"integer","title":"Preset Id"},"name":"preset_id","in":"query"},{"required":false,"schema":{"type":"string","title":"Core Version"},"name":"core_version","in":"query"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AudioQuery"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/accent_phrases":{"post":{"tags":["クエリ編集"],"summary":"テキストからアクセント句を得る","description":"テキストからアクセント句を得ます。\nis_kanaが`true`のとき、テキストは次のAquesTalk 風記法で解釈されます。デフォルトは`false`です。\n* 全てのカナはカタカナで記述される\n* アクセント句は`/`または`、`で区切る。`、`で区切った場合に限り無音区間が挿入される。\n* カナの手前に`_`を入れるとそのカナは無声化される\n* アクセント位置を`'`で指定する。全てのアクセント句にはアクセント位置を1つ指定する必要がある。\n* アクセント句末に`?`(全角)を入れることにより疑問文の発音ができる。","operationId":"accent_phrases_accent_phrases_post","parameters":[{"required":true,"schema":{"type":"string","title":"Text"},"name":"text","in":"query"},{"required":true,"schema":{"type":"integer","title":"Speaker"},"name":"speaker","in":"query"},{"required":false,"schema":{"type":"boolean","title":"Is Kana","default":false},"name":"is_kana","in":"query"},{"required":false,"schema":{"type":"string","title":"Core Version"},"name":"core_version","in":"query"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/AccentPhrase"},"type":"array","title":"Response Accent Phrases Accent Phrases Post"}}}},"400":{"description":"読み仮名のパースに失敗","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ParseKanaBadRequest"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/mora_data":{"post":{"tags":["クエリ編集"],"summary":"アクセント句から音高・音素長を得る","operationId":"mora_data_mora_data_post","parameters":[{"required":true,"schema":{"type":"integer","title":"Speaker"},"name":"speaker","in":"query"},{"required":false,"schema":{"type":"string","title":"Core Version"},"name":"core_version","in":"query"}],"requestBody":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/AccentPhrase"},"type":"array","title":"Accent Phrases"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/AccentPhrase"},"type":"array","title":"Response Mora Data Mora Data Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/mora_length":{"post":{"tags":["クエリ編集"],"summary":"アクセント句から音素長を得る","operationId":"mora_length_mora_length_post","parameters":[{"required":true,"schema":{"type":"integer","title":"Speaker"},"name":"speaker","in":"query"},{"required":false,"schema":{"type":"string","title":"Core Version"},"name":"core_version","in":"query"}],"requestBody":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/AccentPhrase"},"type":"array","title":"Accent Phrases"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/AccentPhrase"},"type":"array","title":"Response Mora Length Mora Length Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/mora_pitch":{"post":{"tags":["クエリ編集"],"summary":"アクセント句から音高を得る","operationId":"mora_pitch_mora_pitch_post","parameters":[{"required":true,"schema":{"type":"integer","title":"Speaker"},"name":"speaker","in":"query"},{"required":false,"schema":{"type":"string","title":"Core Version"},"name":"core_version","in":"query"}],"requestBody":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/AccentPhrase"},"type":"array","title":"Accent Phrases"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/AccentPhrase"},"type":"array","title":"Response Mora Pitch Mora Pitch Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/synthesis":{"post":{"tags":["音声合成"],"summary":"音声合成する","operationId":"synthesis_synthesis_post","parameters":[{"required":true,"schema":{"type":"integer","title":"Speaker"},"name":"speaker","in":"query"},{"description":"疑問系のテキストが与えられたら語尾を自動調整する","required":false,"schema":{"type":"boolean","title":"Enable Interrogative Upspeak","description":"疑問系のテキストが与えられたら語尾を自動調整する","default":true},"name":"enable_interrogative_upspeak","in":"query"},{"required":false,"schema":{"type":"string","title":"Core Version"},"name":"core_version","in":"query"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AudioQuery"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"audio/wav":{"schema":{"type":"string","format":"binary"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/cancellable_synthesis":{"post":{"tags":["音声合成"],"summary":"音声合成する(キャンセル可能)","operationId":"cancellable_synthesis_cancellable_synthesis_post","parameters":[{"required":true,"schema":{"type":"integer","title":"Speaker"},"name":"speaker","in":"query"},{"required":false,"schema":{"type":"string","title":"Core Version"},"name":"core_version","in":"query"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AudioQuery"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"audio/wav":{"schema":{"type":"string","format":"binary"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/multi_synthesis":{"post":{"tags":["音声合成"],"summary":"複数まとめて音声合成する","operationId":"multi_synthesis_multi_synthesis_post","parameters":[{"required":true,"schema":{"type":"integer","title":"Speaker"},"name":"speaker","in":"query"},{"required":false,"schema":{"type":"string","title":"Core Version"},"name":"core_version","in":"query"}],"requestBody":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/AudioQuery"},"type":"array","title":"Queries"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/zip":{"schema":{"type":"string","format":"binary"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/morphable_targets":{"post":{"tags":["音声合成"],"summary":"指定したスタイルに対してエンジン内の話者がモーフィングが可能か判定する","description":"指定されたベーススタイルに対してエンジン内の各話者がモーフィング機能を利用可能か返します。\nモーフィングの許可/禁止は`/speakers`の`speaker.supported_features.synthesis_morphing`に記載されています。\nプロパティが存在しない場合は、モーフィングが許可されているとみなします。\n返り値のスタイルIDはstring型なので注意。","operationId":"morphable_targets_morphable_targets_post","parameters":[{"required":false,"schema":{"type":"string","title":"Core Version"},"name":"core_version","in":"query"}],"requestBody":{"content":{"application/json":{"schema":{"items":{"type":"integer"},"type":"array","title":"Base Style Ids"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"items":{"additionalProperties":{"$ref":"#/components/schemas/MorphableTargetInfo"},"type":"object"},"type":"array","title":"Response Morphable Targets Morphable Targets Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/synthesis_morphing":{"post":{"tags":["音声合成"],"summary":"2種類のスタイルでモーフィングした音声を合成する","description":"指定された2種類のスタイルで音声を合成、指定した割合でモーフィングした音声を得ます。\nモーフィングの割合は`morph_rate`で指定でき、0.0でベースのスタイル、1.0でターゲットのスタイルに近づきます。","operationId":"_synthesis_morphing_synthesis_morphing_post","parameters":[{"required":true,"schema":{"type":"integer","title":"Base Speaker"},"name":"base_speaker","in":"query"},{"required":true,"schema":{"type":"integer","title":"Target Speaker"},"name":"target_speaker","in":"query"},{"required":true,"schema":{"type":"number","maximum":1.0,"minimum":0.0,"title":"Morph Rate"},"name":"morph_rate","in":"query"},{"required":false,"schema":{"type":"string","title":"Core Version"},"name":"core_version","in":"query"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AudioQuery"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"audio/wav":{"schema":{"type":"string","format":"binary"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/sing_frame_audio_query":{"post":{"tags":["クエリ作成"],"summary":"歌唱音声合成用のクエリを作成する","description":"歌唱音声合成用のクエリの初期値を得ます。ここで得られたクエリはそのまま歌唱音声合成に利用できます。各値の意味は`Schemas`を参照してください。","operationId":"sing_frame_audio_query_sing_frame_audio_query_post","parameters":[{"required":true,"schema":{"type":"integer","title":"Speaker"},"name":"speaker","in":"query"},{"required":false,"schema":{"type":"string","title":"Core Version"},"name":"core_version","in":"query"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Score"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FrameAudioQuery"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/frame_synthesis":{"post":{"tags":["音声合成"],"summary":"Frame Synthesis","description":"歌唱音声合成を行います。","operationId":"frame_synthesis_frame_synthesis_post","parameters":[{"required":true,"schema":{"type":"integer","title":"Speaker"},"name":"speaker","in":"query"},{"required":false,"schema":{"type":"string","title":"Core Version"},"name":"core_version","in":"query"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/FrameAudioQuery"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"audio/wav":{"schema":{"type":"string","format":"binary"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/connect_waves":{"post":{"tags":["その他"],"summary":"base64エンコードされた複数のwavデータを一つに結合する","description":"base64エンコードされたwavデータを一纏めにし、wavファイルで返します。","operationId":"connect_waves_connect_waves_post","requestBody":{"content":{"application/json":{"schema":{"items":{"type":"string"},"type":"array","title":"Waves"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"audio/wav":{"schema":{"type":"string","format":"binary"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/presets":{"get":{"tags":["その他"],"summary":"Get Presets","description":"エンジンが保持しているプリセットの設定を返します","operationId":"get_presets_presets_get","responses":{"200":{"description":"プリセットのリスト","content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/Preset"},"type":"array","title":"Response Get Presets Presets Get"}}}}}}},"/add_preset":{"post":{"tags":["その他"],"summary":"Add Preset","description":"新しいプリセットを追加します","operationId":"add_preset_add_preset_post","requestBody":{"content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Preset"}],"title":"Preset","description":"新しいプリセット。プリセットIDが既存のものと重複している場合は、新規のプリセットIDが採番されます。"}}},"required":true},"responses":{"200":{"description":"追加したプリセットのプリセットID","content":{"application/json":{"schema":{"type":"integer","title":"Response Add Preset Add Preset Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/update_preset":{"post":{"tags":["その他"],"summary":"Update Preset","description":"既存のプリセットを更新します","operationId":"update_preset_update_preset_post","requestBody":{"content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Preset"}],"title":"Preset","description":"更新するプリセット。プリセットIDが更新対象と一致している必要があります。"}}},"required":true},"responses":{"200":{"description":"更新したプリセットのプリセットID","content":{"application/json":{"schema":{"type":"integer","title":"Response Update Preset Update Preset Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/delete_preset":{"post":{"tags":["その他"],"summary":"Delete Preset","description":"既存のプリセットを削除します","operationId":"delete_preset_delete_preset_post","parameters":[{"description":"削除するプリセットのプリセットID","required":true,"schema":{"type":"integer","title":"Id","description":"削除するプリセットのプリセットID"},"name":"id","in":"query"}],"responses":{"204":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/version":{"get":{"tags":["その他"],"summary":"Version","operationId":"version_version_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"string","title":"Response Version Version Get"}}}}}}},"/core_versions":{"get":{"tags":["その他"],"summary":"Core Versions","operationId":"core_versions_core_versions_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"items":{"type":"string"},"type":"array","title":"Response Core Versions Core Versions Get"}}}}}}},"/speakers":{"get":{"tags":["その他"],"summary":"Speakers","operationId":"speakers_speakers_get","parameters":[{"required":false,"schema":{"type":"string","title":"Core Version"},"name":"core_version","in":"query"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/Speaker"},"type":"array","title":"Response Speakers Speakers Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/speaker_info":{"get":{"tags":["その他"],"summary":"Speaker Info","description":"指定されたspeaker_uuidに関する情報をjson形式で返します。\n画像や音声はbase64エンコードされたものが返されます。","operationId":"speaker_info_speaker_info_get","parameters":[{"required":true,"schema":{"type":"string","title":"Speaker Uuid"},"name":"speaker_uuid","in":"query"},{"required":false,"schema":{"type":"string","title":"Core Version"},"name":"core_version","in":"query"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SpeakerInfo"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/singers":{"get":{"tags":["その他"],"summary":"Singers","operationId":"singers_singers_get","parameters":[{"required":false,"schema":{"type":"string","title":"Core Version"},"name":"core_version","in":"query"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/Speaker"},"type":"array","title":"Response Singers Singers Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/singer_info":{"get":{"tags":["その他"],"summary":"Singer Info","description":"指定されたspeaker_uuidに関する情報をjson形式で返します。\n画像や音声はbase64エンコードされたものが返されます。","operationId":"singer_info_singer_info_get","parameters":[{"required":true,"schema":{"type":"string","title":"Speaker Uuid"},"name":"speaker_uuid","in":"query"},{"required":false,"schema":{"type":"string","title":"Core Version"},"name":"core_version","in":"query"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SpeakerInfo"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/downloadable_libraries":{"get":{"tags":["音声ライブラリ管理"],"summary":"Downloadable Libraries","description":"ダウンロード可能な音声ライブラリの情報を返します。","operationId":"downloadable_libraries_downloadable_libraries_get","responses":{"200":{"description":"ダウンロード可能な音声ライブラリの情報リスト","content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/DownloadableLibraryInfo"},"type":"array","title":"Response Downloadable Libraries Downloadable Libraries Get"}}}}}}},"/installed_libraries":{"get":{"tags":["音声ライブラリ管理"],"summary":"Installed Libraries","description":"インストールした音声ライブラリの情報を返します。","operationId":"installed_libraries_installed_libraries_get","responses":{"200":{"description":"インストールした音声ライブラリの情報","content":{"application/json":{"schema":{"additionalProperties":{"$ref":"#/components/schemas/InstalledLibraryInfo"},"type":"object","title":"Response Installed Libraries Installed Libraries Get"}}}}}}},"/install_library/{library_uuid}":{"post":{"tags":["音声ライブラリ管理"],"summary":"Install Library","description":"音声ライブラリをインストールします。\n音声ライブラリのZIPファイルをリクエストボディとして送信してください。","operationId":"install_library_install_library__library_uuid__post","parameters":[{"description":"音声ライブラリのID","required":true,"schema":{"type":"string","title":"Library Uuid","description":"音声ライブラリのID"},"name":"library_uuid","in":"path"}],"responses":{"204":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/uninstall_library/{library_uuid}":{"post":{"tags":["音声ライブラリ管理"],"summary":"Uninstall Library","description":"音声ライブラリをアンインストールします。","operationId":"uninstall_library_uninstall_library__library_uuid__post","parameters":[{"description":"音声ライブラリのID","required":true,"schema":{"type":"string","title":"Library Uuid","description":"音声ライブラリのID"},"name":"library_uuid","in":"path"}],"responses":{"204":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/initialize_speaker":{"post":{"tags":["その他"],"summary":"Initialize Speaker","description":"指定されたスタイルを初期化します。\n実行しなくても他のAPIは使用できますが、初回実行時に時間がかかることがあります。","operationId":"initialize_speaker_initialize_speaker_post","parameters":[{"required":true,"schema":{"type":"integer","title":"Speaker"},"name":"speaker","in":"query"},{"description":"既に初期化済みのスタイルの再初期化をスキップするかどうか","required":false,"schema":{"type":"boolean","title":"Skip Reinit","description":"既に初期化済みのスタイルの再初期化をスキップするかどうか","default":false},"name":"skip_reinit","in":"query"},{"required":false,"schema":{"type":"string","title":"Core Version"},"name":"core_version","in":"query"}],"responses":{"204":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/is_initialized_speaker":{"get":{"tags":["その他"],"summary":"Is Initialized Speaker","description":"指定されたスタイルが初期化されているかどうかを返します。","operationId":"is_initialized_speaker_is_initialized_speaker_get","parameters":[{"required":true,"schema":{"type":"integer","title":"Speaker"},"name":"speaker","in":"query"},{"required":false,"schema":{"type":"string","title":"Core Version"},"name":"core_version","in":"query"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"boolean","title":"Response Is Initialized Speaker Is Initialized Speaker Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/user_dict":{"get":{"tags":["ユーザー辞書"],"summary":"Get User Dict Words","description":"ユーザー辞書に登録されている単語の一覧を返します。\n単語の表層形(surface)は正規化済みの物を返します。","operationId":"get_user_dict_words_user_dict_get","responses":{"200":{"description":"単語のUUIDとその詳細","content":{"application/json":{"schema":{"additionalProperties":{"$ref":"#/components/schemas/UserDictWord"},"type":"object","title":"Response Get User Dict Words User Dict Get"}}}}}}},"/user_dict_word":{"post":{"tags":["ユーザー辞書"],"summary":"Add User Dict Word","description":"ユーザー辞書に言葉を追加します。","operationId":"add_user_dict_word_user_dict_word_post","parameters":[{"description":"言葉の表層形","required":true,"schema":{"type":"string","title":"Surface","description":"言葉の表層形"},"name":"surface","in":"query"},{"description":"言葉の発音(カタカナ)","required":true,"schema":{"type":"string","title":"Pronunciation","description":"言葉の発音(カタカナ)"},"name":"pronunciation","in":"query"},{"description":"アクセント型(音が下がる場所を指す)","required":true,"schema":{"type":"integer","title":"Accent Type","description":"アクセント型(音が下がる場所を指す)"},"name":"accent_type","in":"query"},{"description":"PROPER_NOUN(固有名詞)、COMMON_NOUN(普通名詞)、VERB(動詞)、ADJECTIVE(形容詞)、SUFFIX(語尾)のいずれか","required":false,"schema":{"allOf":[{"$ref":"#/components/schemas/WordTypes"}],"description":"PROPER_NOUN(固有名詞)、COMMON_NOUN(普通名詞)、VERB(動詞)、ADJECTIVE(形容詞)、SUFFIX(語尾)のいずれか"},"name":"word_type","in":"query"},{"description":"単語の優先度(0から10までの整数)。数字が大きいほど優先度が高くなる。1から9までの値を指定することを推奨","required":false,"schema":{"type":"integer","maximum":10.0,"minimum":0.0,"title":"Priority","description":"単語の優先度(0から10までの整数)。数字が大きいほど優先度が高くなる。1から9までの値を指定することを推奨"},"name":"priority","in":"query"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"string","title":"Response Add User Dict Word User Dict Word Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/user_dict_word/{word_uuid}":{"put":{"tags":["ユーザー辞書"],"summary":"Rewrite User Dict Word","description":"ユーザー辞書に登録されている言葉を更新します。","operationId":"rewrite_user_dict_word_user_dict_word__word_uuid__put","parameters":[{"description":"更新する言葉のUUID","required":true,"schema":{"type":"string","title":"Word Uuid","description":"更新する言葉のUUID"},"name":"word_uuid","in":"path"},{"description":"言葉の表層形","required":true,"schema":{"type":"string","title":"Surface","description":"言葉の表層形"},"name":"surface","in":"query"},{"description":"言葉の発音(カタカナ)","required":true,"schema":{"type":"string","title":"Pronunciation","description":"言葉の発音(カタカナ)"},"name":"pronunciation","in":"query"},{"description":"アクセント型(音が下がる場所を指す)","required":true,"schema":{"type":"integer","title":"Accent Type","description":"アクセント型(音が下がる場所を指す)"},"name":"accent_type","in":"query"},{"description":"PROPER_NOUN(固有名詞)、COMMON_NOUN(普通名詞)、VERB(動詞)、ADJECTIVE(形容詞)、SUFFIX(語尾)のいずれか","required":false,"schema":{"allOf":[{"$ref":"#/components/schemas/WordTypes"}],"description":"PROPER_NOUN(固有名詞)、COMMON_NOUN(普通名詞)、VERB(動詞)、ADJECTIVE(形容詞)、SUFFIX(語尾)のいずれか"},"name":"word_type","in":"query"},{"description":"単語の優先度(0から10までの整数)。数字が大きいほど優先度が高くなる。1から9までの値を指定することを推奨。","required":false,"schema":{"type":"integer","maximum":10.0,"minimum":0.0,"title":"Priority","description":"単語の優先度(0から10までの整数)。数字が大きいほど優先度が高くなる。1から9までの値を指定することを推奨。"},"name":"priority","in":"query"}],"responses":{"204":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["ユーザー辞書"],"summary":"Delete User Dict Word","description":"ユーザー辞書に登録されている言葉を削除します。","operationId":"delete_user_dict_word_user_dict_word__word_uuid__delete","parameters":[{"description":"削除する言葉のUUID","required":true,"schema":{"type":"string","title":"Word Uuid","description":"削除する言葉のUUID"},"name":"word_uuid","in":"path"}],"responses":{"204":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/import_user_dict":{"post":{"tags":["ユーザー辞書"],"summary":"Import User Dict Words","description":"他のユーザー辞書をインポートします。","operationId":"import_user_dict_words_import_user_dict_post","parameters":[{"description":"重複したエントリがあった場合、上書きするかどうか","required":true,"schema":{"type":"boolean","title":"Override","description":"重複したエントリがあった場合、上書きするかどうか"},"name":"override","in":"query"}],"requestBody":{"content":{"application/json":{"schema":{"additionalProperties":{"$ref":"#/components/schemas/UserDictWord"},"type":"object","title":"Import Dict Data","description":"インポートするユーザー辞書のデータ"}}},"required":true},"responses":{"204":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/supported_devices":{"get":{"tags":["その他"],"summary":"Supported Devices","operationId":"supported_devices_supported_devices_get","parameters":[{"required":false,"schema":{"type":"string","title":"Core Version"},"name":"core_version","in":"query"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SupportedDevicesInfo"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/engine_manifest":{"get":{"tags":["その他"],"summary":"Engine Manifest","operationId":"engine_manifest_engine_manifest_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EngineManifest"}}}}}}},"/validate_kana":{"post":{"tags":["その他"],"summary":"テキストがAquesTalk 風記法に従っているか判定する","description":"テキストがAquesTalk 風記法に従っているかどうかを判定します。\n従っていない場合はエラーが返ります。","operationId":"validate_kana_validate_kana_post","parameters":[{"description":"判定する対象の文字列","required":true,"schema":{"type":"string","title":"Text","description":"判定する対象の文字列"},"name":"text","in":"query"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"boolean","title":"Response Validate Kana Validate Kana Post"}}}},"400":{"description":"テキストが不正です","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ParseKanaBadRequest"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/setting":{"get":{"tags":["設定"],"summary":"Setting Get","description":"設定ページを返します。","operationId":"setting_get_setting_get","responses":{"200":{"description":"Successful Response"}}},"post":{"tags":["設定"],"summary":"Setting Post","description":"設定を更新します。","operationId":"setting_post_setting_post","requestBody":{"content":{"application/x-www-form-urlencoded":{"schema":{"$ref":"#/components/schemas/Body_setting_post_setting_post"}}},"required":true},"responses":{"200":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}}},"components":{"schemas":{"AccentPhrase":{"properties":{"moras":{"items":{"$ref":"#/components/schemas/Mora"},"type":"array","title":"モーラのリスト"},"accent":{"type":"integer","title":"アクセント箇所"},"pause_mora":{"allOf":[{"$ref":"#/components/schemas/Mora"}],"title":"後ろに無音を付けるかどうか"},"is_interrogative":{"type":"boolean","title":"疑問系かどうか","default":false}},"type":"object","required":["moras","accent"],"title":"AccentPhrase","description":"アクセント句ごとの情報"},"AudioQuery":{"properties":{"accent_phrases":{"items":{"$ref":"#/components/schemas/AccentPhrase"},"type":"array","title":"アクセント句のリスト"},"speedScale":{"type":"number","title":"全体の話速"},"pitchScale":{"type":"number","title":"全体の音高"},"intonationScale":{"type":"number","title":"全体の抑揚"},"volumeScale":{"type":"number","title":"全体の音量"},"prePhonemeLength":{"type":"number","title":"音声の前の無音時間"},"postPhonemeLength":{"type":"number","title":"音声の後の無音時間"},"pauseLength":{"type":"number","title":"読点や括弧等の無音時間(絶対値)"},"pauseLengthScale":{"type":"number","title":"読点や括弧等の無音時間(倍率)"},"outputSamplingRate":{"type":"integer","title":"音声データの出力サンプリングレート"},"outputStereo":{"type":"boolean","title":"音声データをステレオ出力するか否か"},"kana":{"type":"string","title":"[読み取り専用]AquesTalk 風記法によるテキスト。音声合成用のクエリとしては無視される"}},"type":"object","required":["accent_phrases","speedScale","pitchScale","intonationScale","volumeScale","prePhonemeLength","postPhonemeLength","pauseLength","pauseLengthScale","outputSamplingRate","outputStereo"],"title":"AudioQuery","description":"音声合成用のクエリ"},"Body_setting_post_setting_post":{"properties":{"cors_policy_mode":{"$ref":"#/components/schemas/CorsPolicyMode"},"allow_origin":{"type":"string","title":"Allow Origin"}},"type":"object","required":["cors_policy_mode"],"title":"Body_setting_post_setting_post"},"CorsPolicyMode":{"type":"string","enum":["all","localapps"],"title":"CorsPolicyMode","description":"CORSの許可モード"},"DownloadableLibraryInfo":{"properties":{"name":{"type":"string","title":"音声ライブラリの名前"},"uuid":{"type":"string","title":"音声ライブラリのUUID"},"version":{"type":"string","title":"音声ライブラリのバージョン"},"download_url":{"type":"string","title":"音声ライブラリのダウンロードURL"},"bytes":{"type":"integer","title":"音声ライブラリのバイト数"},"speakers":{"items":{"$ref":"#/components/schemas/LibrarySpeaker"},"type":"array","title":"音声ライブラリに含まれる話者のリスト"}},"type":"object","required":["name","uuid","version","download_url","bytes","speakers"],"title":"DownloadableLibraryInfo","description":"ダウンロード可能な音声ライブラリの情報"},"EngineManifest":{"properties":{"manifest_version":{"type":"string","title":"マニフェストのバージョン"},"name":{"type":"string","title":"エンジン名"},"brand_name":{"type":"string","title":"ブランド名"},"uuid":{"type":"string","title":"エンジンのUUID"},"url":{"type":"string","title":"エンジンのURL"},"icon":{"type":"string","title":"エンジンのアイコンをBASE64エンコードしたもの"},"default_sampling_rate":{"type":"integer","title":"デフォルトのサンプリング周波数"},"frame_rate":{"type":"number","title":"エンジンのフレームレート"},"terms_of_service":{"type":"string","title":"エンジンの利用規約"},"update_infos":{"items":{"$ref":"#/components/schemas/UpdateInfo"},"type":"array","title":"エンジンのアップデート情報"},"dependency_licenses":{"items":{"$ref":"#/components/schemas/LicenseInfo"},"type":"array","title":"依存関係のライセンス情報"},"supported_vvlib_manifest_version":{"type":"string","title":"エンジンが対応するvvlibのバージョン"},"supported_features":{"allOf":[{"$ref":"#/components/schemas/SupportedFeatures"}],"title":"エンジンが持つ機能"}},"type":"object","required":["manifest_version","name","brand_name","uuid","url","icon","default_sampling_rate","frame_rate","terms_of_service","update_infos","dependency_licenses","supported_features"],"title":"EngineManifest","description":"エンジン自体に関する情報"},"FrameAudioQuery":{"properties":{"f0":{"items":{"type":"number"},"type":"array","title":"フレームごとの基本周波数"},"volume":{"items":{"type":"number"},"type":"array","title":"フレームごとの音量"},"phonemes":{"items":{"$ref":"#/components/schemas/FramePhoneme"},"type":"array","title":"音素のリスト"},"volumeScale":{"type":"number","title":"全体の音量"},"outputSamplingRate":{"type":"integer","title":"音声データの出力サンプリングレート"},"outputStereo":{"type":"boolean","title":"音声データをステレオ出力するか否か"}},"type":"object","required":["f0","volume","phonemes","volumeScale","outputSamplingRate","outputStereo"],"title":"FrameAudioQuery","description":"フレームごとの音声合成用のクエリ"},"FramePhoneme":{"properties":{"phoneme":{"type":"string","title":"音素"},"frame_length":{"type":"integer","title":"音素のフレーム長"}},"type":"object","required":["phoneme","frame_length"],"title":"FramePhoneme","description":"音素の情報"},"HTTPValidationError":{"properties":{"detail":{"items":{"$ref":"#/components/schemas/ValidationError"},"type":"array","title":"Detail"}},"type":"object","title":"HTTPValidationError"},"InstalledLibraryInfo":{"properties":{"name":{"type":"string","title":"音声ライブラリの名前"},"uuid":{"type":"string","title":"音声ライブラリのUUID"},"version":{"type":"string","title":"音声ライブラリのバージョン"},"download_url":{"type":"string","title":"音声ライブラリのダウンロードURL"},"bytes":{"type":"integer","title":"音声ライブラリのバイト数"},"speakers":{"items":{"$ref":"#/components/schemas/LibrarySpeaker"},"type":"array","title":"音声ライブラリに含まれる話者のリスト"},"uninstallable":{"type":"boolean","title":"アンインストール可能かどうか"}},"type":"object","required":["name","uuid","version","download_url","bytes","speakers","uninstallable"],"title":"InstalledLibraryInfo","description":"インストール済み音声ライブラリの情報"},"LibrarySpeaker":{"properties":{"speaker":{"allOf":[{"$ref":"#/components/schemas/Speaker"}],"title":"話者情報"},"speaker_info":{"allOf":[{"$ref":"#/components/schemas/SpeakerInfo"}],"title":"話者の追加情報"}},"type":"object","required":["speaker","speaker_info"],"title":"LibrarySpeaker","description":"音声ライブラリに含まれる話者の情報"},"LicenseInfo":{"properties":{"name":{"type":"string","title":"依存ライブラリ名"},"version":{"type":"string","title":"依存ライブラリのバージョン"},"license":{"type":"string","title":"依存ライブラリのライセンス名"},"text":{"type":"string","title":"依存ライブラリのライセンス本文"}},"type":"object","required":["name","text"],"title":"LicenseInfo","description":"依存ライブラリのライセンス情報"},"Mora":{"properties":{"text":{"type":"string","title":"文字"},"consonant":{"type":"string","title":"子音の音素"},"consonant_length":{"type":"number","title":"子音の音長"},"vowel":{"type":"string","title":"母音の音素"},"vowel_length":{"type":"number","title":"母音の音長"},"pitch":{"type":"number","title":"音高"}},"type":"object","required":["text","vowel","vowel_length","pitch"],"title":"Mora","description":"モーラ(子音+母音)ごとの情報"},"MorphableTargetInfo":{"properties":{"is_morphable":{"type":"boolean","title":"指定した話者に対してモーフィングの可否"}},"type":"object","required":["is_morphable"],"title":"MorphableTargetInfo"},"Note":{"properties":{"key":{"type":"integer","title":"音階"},"frame_length":{"type":"integer","title":"音符のフレーム長"},"lyric":{"type":"string","title":"音符の歌詞"}},"type":"object","required":["frame_length","lyric"],"title":"Note","description":"音符ごとの情報"},"ParseKanaBadRequest":{"properties":{"text":{"type":"string","title":"エラーメッセージ"},"error_name":{"type":"string","title":"エラー名","description":"|name|description|\n|---|---|\n| UNKNOWN_TEXT | 判別できない読み仮名があります: {text} |\n| ACCENT_TOP | 句頭にアクセントは置けません: {text} |\n| ACCENT_TWICE | 1つのアクセント句に二つ以上のアクセントは置けません: {text} |\n| ACCENT_NOTFOUND | アクセントを指定していないアクセント句があります: {text} |\n| EMPTY_PHRASE | {position}番目のアクセント句が空白です |\n| INTERROGATION_MARK_NOT_AT_END | アクセント句末以外に「?」は置けません: {text} |\n| INFINITE_LOOP | 処理時に無限ループになってしまいました...バグ報告をお願いします。 |"},"error_args":{"additionalProperties":{"type":"string"},"type":"object","title":"エラーを起こした箇所"}},"type":"object","required":["text","error_name","error_args"],"title":"ParseKanaBadRequest"},"Preset":{"properties":{"id":{"type":"integer","title":"プリセットID"},"name":{"type":"string","title":"プリセット名"},"speaker_uuid":{"type":"string","title":"話者のUUID"},"style_id":{"type":"integer","title":"スタイルID"},"speedScale":{"type":"number","title":"全体の話速"},"pitchScale":{"type":"number","title":"全体の音高"},"intonationScale":{"type":"number","title":"全体の抑揚"},"volumeScale":{"type":"number","title":"全体の音量"},"prePhonemeLength":{"type":"number","title":"音声の前の無音時間"},"postPhonemeLength":{"type":"number","title":"音声の後の無音時間"},"pauseLength":{"type":"number","title":"読点や括弧等の無音時間(絶対値)"},"pauseLengthScale":{"type":"number","title":"読点や括弧等の無音時間(倍率)"}},"type":"object","required":["id","name","speaker_uuid","style_id","speedScale","pitchScale","intonationScale","volumeScale","prePhonemeLength","postPhonemeLength","pauseLength","pauseLengthScale"],"title":"Preset","description":"プリセット情報"},"Score":{"properties":{"notes":{"items":{"$ref":"#/components/schemas/Note"},"type":"array","title":"音符のリスト"}},"type":"object","required":["notes"],"title":"Score","description":"楽譜情報"},"Speaker":{"properties":{"supported_features":{"allOf":[{"$ref":"#/components/schemas/SpeakerSupportedFeatures"}],"title":"話者の対応機能"},"name":{"type":"string","title":"名前"},"speaker_uuid":{"type":"string","title":"話者のUUID"},"styles":{"items":{"$ref":"#/components/schemas/SpeakerStyle"},"type":"array","title":"スタイルの一覧"},"version":{"type":"string","title":"Version","default":"話者のバージョン"}},"type":"object","required":["name","speaker_uuid","styles"],"title":"Speaker","description":"話者情報"},"SpeakerInfo":{"properties":{"policy":{"type":"string","title":"policy.md"},"portrait":{"type":"string","title":"portrait.pngをbase64エンコードしたもの"},"style_infos":{"items":{"$ref":"#/components/schemas/StyleInfo"},"type":"array","title":"スタイルの追加情報"}},"type":"object","required":["policy","portrait","style_infos"],"title":"SpeakerInfo","description":"話者の追加情報"},"SpeakerStyle":{"properties":{"name":{"type":"string","title":"スタイル名"},"id":{"type":"integer","title":"スタイルID"},"type":{"type":"string","enum":["talk","singing_teacher","frame_decode","sing"],"title":"スタイルの種類。talk:音声合成クエリの作成と音声合成が可能。singing_teacher:歌唱音声合成用のクエリの作成が可能。frame_decode:歌唱音声合成が可能。sing:歌唱音声合成用のクエリの作成と歌唱音声合成が可能。","default":"talk"}},"type":"object","required":["name","id"],"title":"SpeakerStyle","description":"話者のスタイル情報"},"SpeakerSupportPermittedSynthesisMorphing":{"type":"string","enum":["ALL","SELF_ONLY","NOTHING"],"title":"SpeakerSupportPermittedSynthesisMorphing","description":"An enumeration."},"SpeakerSupportedFeatures":{"properties":{"permitted_synthesis_morphing":{"allOf":[{"$ref":"#/components/schemas/SpeakerSupportPermittedSynthesisMorphing"}],"title":"モーフィング機能への対応","default":"ALL"}},"type":"object","title":"SpeakerSupportedFeatures","description":"話者の対応機能の情報"},"StyleInfo":{"properties":{"id":{"type":"integer","title":"スタイルID"},"icon":{"type":"string","title":"当該スタイルのアイコンをbase64エンコードしたもの"},"portrait":{"type":"string","title":"当該スタイルのportrait.pngをbase64エンコードしたもの"},"voice_samples":{"items":{"type":"string"},"type":"array","title":"voice_sampleのwavファイルをbase64エンコードしたもの"}},"type":"object","required":["id","icon","voice_samples"],"title":"StyleInfo","description":"スタイルの追加情報"},"SupportedDevicesInfo":{"properties":{"cpu":{"type":"boolean","title":"CPUに対応しているか"},"cuda":{"type":"boolean","title":"CUDA(Nvidia GPU)に対応しているか"},"dml":{"type":"boolean","title":"DirectML(Nvidia GPU/Radeon GPU等)に対応しているか"}},"type":"object","required":["cpu","cuda","dml"],"title":"SupportedDevicesInfo","description":"対応しているデバイスの情報"},"SupportedFeatures":{"properties":{"adjust_mora_pitch":{"type":"boolean","title":"モーラごとの音高の調整"},"adjust_phoneme_length":{"type":"boolean","title":"音素ごとの長さの調整"},"adjust_speed_scale":{"type":"boolean","title":"全体の話速の調整"},"adjust_pitch_scale":{"type":"boolean","title":"全体の音高の調整"},"adjust_intonation_scale":{"type":"boolean","title":"全体の抑揚の調整"},"adjust_volume_scale":{"type":"boolean","title":"全体の音量の調整"},"interrogative_upspeak":{"type":"boolean","title":"疑問文の自動調整"},"synthesis_morphing":{"type":"boolean","title":"2種類のスタイルでモーフィングした音声を合成"},"sing":{"type":"boolean","title":"歌唱音声合成"},"manage_library":{"type":"boolean","title":"音声ライブラリのインストール・アンインストール"}},"type":"object","required":["adjust_mora_pitch","adjust_phoneme_length","adjust_speed_scale","adjust_pitch_scale","adjust_intonation_scale","adjust_volume_scale","interrogative_upspeak","synthesis_morphing"],"title":"SupportedFeatures","description":"エンジンが持つ機能の一覧"},"UpdateInfo":{"properties":{"version":{"type":"string","title":"エンジンのバージョン名"},"descriptions":{"items":{"type":"string"},"type":"array","title":"アップデートの詳細についての説明"},"contributors":{"items":{"type":"string"},"type":"array","title":"貢献者名"}},"type":"object","required":["version","descriptions"],"title":"UpdateInfo","description":"エンジンのアップデート情報"},"UserDictWord":{"properties":{"surface":{"type":"string","title":"表層形"},"priority":{"type":"integer","maximum":10.0,"minimum":0.0,"title":"優先度"},"context_id":{"type":"integer","title":"文脈ID","default":1348},"part_of_speech":{"type":"string","title":"品詞"},"part_of_speech_detail_1":{"type":"string","title":"品詞細分類1"},"part_of_speech_detail_2":{"type":"string","title":"品詞細分類2"},"part_of_speech_detail_3":{"type":"string","title":"品詞細分類3"},"inflectional_type":{"type":"string","title":"活用型"},"inflectional_form":{"type":"string","title":"活用形"},"stem":{"type":"string","title":"原形"},"yomi":{"type":"string","title":"読み"},"pronunciation":{"type":"string","title":"発音"},"accent_type":{"type":"integer","title":"アクセント型"},"mora_count":{"type":"integer","title":"モーラ数"},"accent_associative_rule":{"type":"string","title":"アクセント結合規則"}},"type":"object","required":["surface","priority","part_of_speech","part_of_speech_detail_1","part_of_speech_detail_2","part_of_speech_detail_3","inflectional_type","inflectional_form","stem","yomi","pronunciation","accent_type","accent_associative_rule"],"title":"UserDictWord","description":"辞書のコンパイルに使われる情報"},"ValidationError":{"properties":{"loc":{"items":{"anyOf":[{"type":"string"},{"type":"integer"}]},"type":"array","title":"Location"},"msg":{"type":"string","title":"Message"},"type":{"type":"string","title":"Error Type"}},"type":"object","required":["loc","msg","type"],"title":"ValidationError"},"WordTypes":{"type":"string","enum":["PROPER_NOUN","COMMON_NOUN","VERB","ADJECTIVE","SUFFIX"],"title":"WordTypes","description":"fastapiでword_type引数を検証する時に使用するクラス"},"VvlibManifest":{"title":"VvlibManifest","description":"vvlib(VOICEVOX Library)に関する情報","type":"object","properties":{"manifest_version":{"title":"マニフェストバージョン","type":"string"},"name":{"title":"音声ライブラリ名","type":"string"},"version":{"title":"音声ライブラリバージョン","type":"string"},"uuid":{"title":"音声ライブラリのUUID","type":"string"},"brand_name":{"title":"エンジンのブランド名","type":"string"},"engine_name":{"title":"エンジン名","type":"string"},"engine_uuid":{"title":"エンジンのUUID","type":"string"}},"required":["manifest_version","name","version","uuid","brand_name","engine_name","engine_uuid"]},"BaseLibraryInfo":{"title":"BaseLibraryInfo","description":"音声ライブラリの情報","type":"object","properties":{"name":{"title":"音声ライブラリの名前","type":"string"},"uuid":{"title":"音声ライブラリのUUID","type":"string"},"version":{"title":"音声ライブラリのバージョン","type":"string"},"download_url":{"title":"音声ライブラリのダウンロードURL","type":"string"},"bytes":{"title":"音声ライブラリのバイト数","type":"integer"},"speakers":{"title":"音声ライブラリに含まれる話者のリスト","type":"array","items":{"$ref":"#/components/schemas/LibrarySpeaker"}}},"required":["name","uuid","version","download_url","bytes","speakers"]}}}} diff --git a/src/backend/electron/main.ts b/src/backend/electron/main.ts index 9f7d5d27cd..1889dee3ec 100644 --- a/src/backend/electron/main.ts +++ b/src/backend/electron/main.ts @@ -403,7 +403,6 @@ async function createWindow() { nodeIntegration: false, contextIsolation: true, sandbox: false, // TODO: 外しても問題ないか検証して外す - devTools: true, // 検証ツール有効 デバッグ時のみ }, icon: path.join(__static, "icon.png"), }); @@ -586,7 +585,7 @@ if (isMac) { Menu.setApplicationMenu(Menu.buildFromTemplate(menuTemplateForMac)); } else { if (!isDevelopment) { - //Menu.setApplicationMenu(null); // デバッグを有効にする場合、コメントアウト + Menu.setApplicationMenu(null); } } diff --git a/src/components/Dialog/SettingDialog.vue b/src/components/Dialog/SettingDialog.vue index e026885d3d..3af03bb315 100644 --- a/src/components/Dialog/SettingDialog.vue +++ b/src/components/Dialog/SettingDialog.vue @@ -1116,10 +1116,7 @@ const engineUseGpu = computed({ }); const engineIds = computed(() => store.state.engineIds); const engineInfos = computed(() => store.state.engineInfos); -// 新規 -// QBtnToggleはv-modelがの変更がsetに結びつく設計になってるみたい -// Vuexの変更がgetで反映される -// それらがcomputedによって自動反映 + const switchPauseLengthMode = computed({ get: () => store.state.switchPauseLengthMode, set: (switchPauseLengthMode: SwitchPauseLengthMode) => { diff --git a/src/components/Talk/AccentPhrase.vue b/src/components/Talk/AccentPhrase.vue index 6db3210c0d..dcc82d72c7 100644 --- a/src/components/Talk/AccentPhrase.vue +++ b/src/components/Talk/AccentPhrase.vue @@ -48,7 +48,7 @@ class="q-mb-sm pitch-cell" :style="{ 'grid-column': `${moraIndex * 2 + 1} / span 1` }" > - + - + - + { }); const handleChangePronounce = (newPronunciation: string) => { - console.log("handleChangePronounce"); let popUntilPause = false; newPronunciation = newPronunciation .replace(/,/g, "、") @@ -363,7 +362,6 @@ const lastPitches = computed(() => props.accentPhrase.moras.map((mora) => mora.pitch), ); -// スライダー操作で発火 const maxPitch = 6.5; const minPitch = 3; const maxMoraLength = 0.3; @@ -373,7 +371,6 @@ const changeMoraData = ( data: number, type: MoraDataType, ) => { - console.log("changeMoraData in AccentPhrase.vue"); const accentPhraseIndex = props.index; if (!props.altKeyFlag) { if (type == "pitch") { diff --git a/src/components/Talk/AudioCell.vue b/src/components/Talk/AudioCell.vue index 690542c947..a69fc56a6e 100644 --- a/src/components/Talk/AudioCell.vue +++ b/src/components/Talk/AudioCell.vue @@ -307,7 +307,6 @@ watch( ); const pushAudioTextIfNeeded = async (event?: KeyboardEvent) => { - console.log("pushAudioTextIfNeeded"); if (event && event.isComposing) return; if (!willRemove.value && isChangeFlag.value && !willFocusOrBlur.value) { isChangeFlag.value = false; diff --git a/src/components/Talk/AudioDetail.vue b/src/components/Talk/AudioDetail.vue index 7e5e514e52..c8e152318f 100644 --- a/src/components/Talk/AudioDetail.vue +++ b/src/components/Talk/AudioDetail.vue @@ -192,8 +192,6 @@ const query = computed(() => audioItem.value?.query); // pauseLength&pauseLengthScaleにおいては、エンジン側で行う処理を例外的にここで行う // storeへの反映はAccentPhrases.vueでやってくれる const accentPhrases = computed(() => { - console.log("accentPhrase in AudioDetail.vue"); - console.log(switchPauseLengthMode.value); const newAccentPhrases = query.value?.accentPhrases; if (switchPauseLengthMode.value === "ABSOLUTE" && newAccentPhrases) { const pauseLength = query.value?.pauseLength; @@ -204,17 +202,7 @@ const accentPhrases = computed(() => { } }); } - }/* else if (switchPauseLengthMode.value === "SCALE" && newAccentPhrases) { - const pauseLengthScale = query.value?.pauseLengthScale; - console.log(pauseLengthScale); - if (pauseLengthScale != null) { - newAccentPhrases.forEach((accentPhrase) => { - if (accentPhrase.pauseMora) { - accentPhrase.pauseMora.vowelLength *= pauseLengthScale; - } - }); - } - }*/ + } return newAccentPhrases; }); @@ -273,7 +261,6 @@ watch(accentPhrases, async () => { // audio play const play = async () => { - console.log("play in AudioDetail"); try { await store.dispatch("PLAY_AUDIO", { audioKey: props.activeAudioKey, @@ -345,7 +332,6 @@ watch(nowPlaying, async (newState) => { const accentPhraseOffsets = await store.dispatch("GET_AUDIO_PLAY_OFFSETS", { audioKey: props.activeAudioKey, }); - console.log(accentPhraseOffsets); // 現在再生されているaudio elementの再生時刻を描画毎に取得(監視)し、 // それに合わせてフォーカスするアクセント句を変えていく const focusAccentPhrase = () => { diff --git a/src/components/Talk/AudioInfo.vue b/src/components/Talk/AudioInfo.vue index 230b175e5c..150bd484cd 100644 --- a/src/components/Talk/AudioInfo.vue +++ b/src/components/Talk/AudioInfo.vue @@ -324,18 +324,15 @@ const props = defineProps<{ }>(); const store = useStore(); - const { info } = createLogger("AudioInfo"); // accent phrase const uiLocked = computed(() => store.getters.UI_LOCKED); const audioItem = computed(() => store.state.audioItems[props.activeAudioKey]); - const query = computed(() => audioItem.value?.query); // 文内無音の指定方式 "SCALE" || "ABSOLUTE" -// 折り返さないとESLintにおこられる const switchPauseLengthMode = computed(() => { return store.state.switchPauseLengthMode; }); @@ -571,7 +568,6 @@ const morphingTargetEngines = store.getters.MORPHING_SUPPORTED_ENGINES; // モーフィング可能なターゲット一覧を取得 watchEffect(() => { - // console.log("watchEffect"); if (audioItem.value != undefined) { store.dispatch("LOAD_MORPHABLE_TARGETS", { engineId: audioItem.value.voice.engineId, diff --git a/src/components/Talk/TalkEditor.vue b/src/components/Talk/TalkEditor.vue index 861351b23b..cb11bd6e5b 100644 --- a/src/components/Talk/TalkEditor.vue +++ b/src/components/Talk/TalkEditor.vue @@ -512,17 +512,15 @@ watch(userOrderedCharacterInfos, (userOrderedCharacterInfos) => { // エンジン初期化後の処理 const isCompletedInitialStartup = ref(false); -// TODO: Vueっぽくないので解体する チョットマッテ +// TODO: Vueっぽくないので解体する onetimeWatch( () => props.isProjectFileLoaded, async (isProjectFileLoaded) => { - console.log("onetimeWatch"); if (isProjectFileLoaded == "waiting" || !props.isEnginesReady) return "continue"; if (!isProjectFileLoaded) { // 最初のAudioCellを作成 const audioItem = await store.dispatch("GENERATE_AUDIO_ITEM", {}); - console.log(audioItem); const newAudioKey = await store.dispatch("REGISTER_AUDIO_ITEM", { audioItem, }); diff --git a/src/openapi/apis/DefaultApi.ts b/src/openapi/apis/DefaultApi.ts index 91e68f190b..18e65d5ca2 100644 --- a/src/openapi/apis/DefaultApi.ts +++ b/src/openapi/apis/DefaultApi.ts @@ -953,7 +953,6 @@ export class DefaultApi extends runtime.BaseAPI implements DefaultApiInterface { * テキストからアクセント句を得る */ async accentPhrasesAccentPhrasesPostRaw(requestParameters: AccentPhrasesAccentPhrasesPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>> { - console.log("accentPhrasesAccentPhrasesPostRaw"); if (requestParameters.text === null || requestParameters.text === undefined) { throw new runtime.RequiredError('text','Required parameter requestParameters.text was null or undefined when calling accentPhrasesAccentPhrasesPost.'); } @@ -997,7 +996,6 @@ export class DefaultApi extends runtime.BaseAPI implements DefaultApiInterface { * テキストからアクセント句を得る */ async accentPhrasesAccentPhrasesPost(requestParameters: AccentPhrasesAccentPhrasesPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { - console.log("accentPhrasesAccentPhrasesPost"); const response = await this.accentPhrasesAccentPhrasesPostRaw(requestParameters, initOverrides); return await response.value(); } @@ -1007,7 +1005,6 @@ export class DefaultApi extends runtime.BaseAPI implements DefaultApiInterface { * Add Preset */ async addPresetAddPresetPostRaw(requestParameters: AddPresetAddPresetPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { - console.log("addPresetAddPresetPostRaw"); if (requestParameters.preset === null || requestParameters.preset === undefined) { throw new runtime.RequiredError('preset','Required parameter requestParameters.preset was null or undefined when calling addPresetAddPresetPost.'); } @@ -1047,7 +1044,6 @@ export class DefaultApi extends runtime.BaseAPI implements DefaultApiInterface { * Add User Dict Word */ async addUserDictWordUserDictWordPostRaw(requestParameters: AddUserDictWordUserDictWordPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { - console.log("addUserDictWordUserDictWordPostRaw"); if (requestParameters.surface === null || requestParameters.surface === undefined) { throw new runtime.RequiredError('surface','Required parameter requestParameters.surface was null or undefined when calling addUserDictWordUserDictWordPost.'); } @@ -1112,7 +1108,6 @@ export class DefaultApi extends runtime.BaseAPI implements DefaultApiInterface { * 音声合成用のクエリを作成する */ async audioQueryAudioQueryPostRaw(requestParameters: AudioQueryAudioQueryPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { - console.log("audioQueryAudioQueryPostRaw"); if (requestParameters.text === null || requestParameters.text === undefined) { throw new runtime.RequiredError('text','Required parameter requestParameters.text was null or undefined when calling audioQueryAudioQueryPost.'); } @@ -1136,7 +1131,6 @@ export class DefaultApi extends runtime.BaseAPI implements DefaultApiInterface { } const headerParameters: runtime.HTTPHeaders = {}; - console.log(queryParameters); const response = await this.request({ path: `/audio_query`, method: 'POST', @@ -1151,7 +1145,6 @@ export class DefaultApi extends runtime.BaseAPI implements DefaultApiInterface { * 音声合成用のクエリを作成する */ async audioQueryAudioQueryPost(requestParameters: AudioQueryAudioQueryPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { - console.log("audioQueryAudioQueryPost"); const response = await this.audioQueryAudioQueryPostRaw(requestParameters, initOverrides); return await response.value(); } @@ -1161,7 +1154,6 @@ export class DefaultApi extends runtime.BaseAPI implements DefaultApiInterface { * 音声合成用のクエリをプリセットを用いて作成する */ async audioQueryFromPresetAudioQueryFromPresetPostRaw(requestParameters: AudioQueryFromPresetAudioQueryFromPresetPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { - console.log("audioQueryFromPresetAudioQueryFromPresetPostRaw"); if (requestParameters.text === null || requestParameters.text === undefined) { throw new runtime.RequiredError('text','Required parameter requestParameters.text was null or undefined when calling audioQueryFromPresetAudioQueryFromPresetPost.'); } @@ -1209,7 +1201,6 @@ export class DefaultApi extends runtime.BaseAPI implements DefaultApiInterface { * 音声合成する(キャンセル可能) */ async cancellableSynthesisCancellableSynthesisPostRaw(requestParameters: CancellableSynthesisCancellableSynthesisPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { - console.log("cancellableSynthesisCancellableSynthesisPostRaw"); if (requestParameters.speaker === null || requestParameters.speaker === undefined) { throw new runtime.RequiredError('speaker','Required parameter requestParameters.speaker was null or undefined when calling cancellableSynthesisCancellableSynthesisPost.'); } @@ -1256,7 +1247,6 @@ export class DefaultApi extends runtime.BaseAPI implements DefaultApiInterface { * base64エンコードされた複数のwavデータを一つに結合する */ async connectWavesConnectWavesPostRaw(requestParameters: ConnectWavesConnectWavesPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { - console.log("connectWavesConnectWavesPostRaw"); if (requestParameters.requestBody === null || requestParameters.requestBody === undefined) { throw new runtime.RequiredError('requestBody','Required parameter requestParameters.requestBody was null or undefined when calling connectWavesConnectWavesPost.'); } @@ -1291,7 +1281,6 @@ export class DefaultApi extends runtime.BaseAPI implements DefaultApiInterface { * Core Versions */ async coreVersionsCoreVersionsGetRaw(initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>> { - console.log("coreVersionsCoreVersionsGetRaw"); const queryParameters: any = {}; const headerParameters: runtime.HTTPHeaders = {}; @@ -1319,7 +1308,6 @@ export class DefaultApi extends runtime.BaseAPI implements DefaultApiInterface { * Delete Preset */ async deletePresetDeletePresetPostRaw(requestParameters: DeletePresetDeletePresetPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { - console.log("deletePresetDeletePresetPostRaw"); if (requestParameters.id === null || requestParameters.id === undefined) { throw new runtime.RequiredError('id','Required parameter requestParameters.id was null or undefined when calling deletePresetDeletePresetPost.'); } @@ -1355,7 +1343,6 @@ export class DefaultApi extends runtime.BaseAPI implements DefaultApiInterface { * Delete User Dict Word */ async deleteUserDictWordUserDictWordWordUuidDeleteRaw(requestParameters: DeleteUserDictWordUserDictWordWordUuidDeleteRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { - console.log("deleteUserDictWordUserDictWordWordUuidDeleteRaw"); if (requestParameters.wordUuid === null || requestParameters.wordUuid === undefined) { throw new runtime.RequiredError('wordUuid','Required parameter requestParameters.wordUuid was null or undefined when calling deleteUserDictWordUserDictWordWordUuidDelete.'); } @@ -1387,7 +1374,6 @@ export class DefaultApi extends runtime.BaseAPI implements DefaultApiInterface { * Downloadable Libraries */ async downloadableLibrariesDownloadableLibrariesGetRaw(initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>> { - console.log("downloadableLibrariesDownloadableLibrariesGetRaw"); const queryParameters: any = {}; const headerParameters: runtime.HTTPHeaders = {}; @@ -1415,7 +1401,6 @@ export class DefaultApi extends runtime.BaseAPI implements DefaultApiInterface { * Engine Manifest */ async engineManifestEngineManifestGetRaw(initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { - console.log("engineManifestEngineManifestGetRaw"); const queryParameters: any = {}; const headerParameters: runtime.HTTPHeaders = {}; @@ -1443,7 +1428,6 @@ export class DefaultApi extends runtime.BaseAPI implements DefaultApiInterface { * Frame Synthesis */ async frameSynthesisFrameSynthesisPostRaw(requestParameters: FrameSynthesisFrameSynthesisPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { - console.log("frameSynthesisFrameSynthesisPostRaw"); if (requestParameters.speaker === null || requestParameters.speaker === undefined) { throw new runtime.RequiredError('speaker','Required parameter requestParameters.speaker was null or undefined when calling frameSynthesisFrameSynthesisPost.'); } @@ -1491,7 +1475,6 @@ export class DefaultApi extends runtime.BaseAPI implements DefaultApiInterface { * Get Presets */ async getPresetsPresetsGetRaw(initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>> { - console.log("getPresetsPresetsGetRaw"); const queryParameters: any = {}; const headerParameters: runtime.HTTPHeaders = {}; @@ -1520,7 +1503,6 @@ export class DefaultApi extends runtime.BaseAPI implements DefaultApiInterface { * Get User Dict Words */ async getUserDictWordsUserDictGetRaw(initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { - console.log("getUserDictWordsUserDictGetRaw"); const queryParameters: any = {}; const headerParameters: runtime.HTTPHeaders = {}; @@ -1549,7 +1531,6 @@ export class DefaultApi extends runtime.BaseAPI implements DefaultApiInterface { * Import User Dict Words */ async importUserDictWordsImportUserDictPostRaw(requestParameters: ImportUserDictWordsImportUserDictPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { - console.log("importUserDictWordsImportUserDictPostRaw"); if (requestParameters.override === null || requestParameters.override === undefined) { throw new runtime.RequiredError('override','Required parameter requestParameters.override was null or undefined when calling importUserDictWordsImportUserDictPost.'); } @@ -1592,7 +1573,6 @@ export class DefaultApi extends runtime.BaseAPI implements DefaultApiInterface { * Initialize Speaker */ async initializeSpeakerInitializeSpeakerPostRaw(requestParameters: InitializeSpeakerInitializeSpeakerPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { - console.log("initializeSpeakerInitializeSpeakerPostRaw"); if (requestParameters.speaker === null || requestParameters.speaker === undefined) { throw new runtime.RequiredError('speaker','Required parameter requestParameters.speaker was null or undefined when calling initializeSpeakerInitializeSpeakerPost.'); } @@ -1636,7 +1616,6 @@ export class DefaultApi extends runtime.BaseAPI implements DefaultApiInterface { * Install Library */ async installLibraryInstallLibraryLibraryUuidPostRaw(requestParameters: InstallLibraryInstallLibraryLibraryUuidPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { - console.log("installLibraryInstallLibraryLibraryUuidPostRaw"); if (requestParameters.libraryUuid === null || requestParameters.libraryUuid === undefined) { throw new runtime.RequiredError('libraryUuid','Required parameter requestParameters.libraryUuid was null or undefined when calling installLibraryInstallLibraryLibraryUuidPost.'); } @@ -1668,7 +1647,6 @@ export class DefaultApi extends runtime.BaseAPI implements DefaultApiInterface { * Installed Libraries */ async installedLibrariesInstalledLibrariesGetRaw(initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { - console.log("installedLibrariesInstalledLibrariesGetRaw"); const queryParameters: any = {}; const headerParameters: runtime.HTTPHeaders = {}; @@ -1697,7 +1675,6 @@ export class DefaultApi extends runtime.BaseAPI implements DefaultApiInterface { * Is Initialized Speaker */ async isInitializedSpeakerIsInitializedSpeakerGetRaw(requestParameters: IsInitializedSpeakerIsInitializedSpeakerGetRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { - console.log("isInitializedSpeakerIsInitializedSpeakerGetRaw"); if (requestParameters.speaker === null || requestParameters.speaker === undefined) { throw new runtime.RequiredError('speaker','Required parameter requestParameters.speaker was null or undefined when calling isInitializedSpeakerIsInitializedSpeakerGet.'); } @@ -1733,7 +1710,6 @@ export class DefaultApi extends runtime.BaseAPI implements DefaultApiInterface { * Is Initialized Speaker */ async isInitializedSpeakerIsInitializedSpeakerGet(requestParameters: IsInitializedSpeakerIsInitializedSpeakerGetRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { - console.log("isInitializedSpeakerIsInitializedSpeakerGet"); const response = await this.isInitializedSpeakerIsInitializedSpeakerGetRaw(requestParameters, initOverrides); return await response.value(); } @@ -1742,7 +1718,6 @@ export class DefaultApi extends runtime.BaseAPI implements DefaultApiInterface { * アクセント句から音高・音素長を得る */ async moraDataMoraDataPostRaw(requestParameters: MoraDataMoraDataPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>> { - console.log("moraDataMoraDataPostRaw"); if (requestParameters.speaker === null || requestParameters.speaker === undefined) { throw new runtime.RequiredError('speaker','Required parameter requestParameters.speaker was null or undefined when calling moraDataMoraDataPost.'); } @@ -1788,7 +1763,6 @@ export class DefaultApi extends runtime.BaseAPI implements DefaultApiInterface { * アクセント句から音素長を得る */ async moraLengthMoraLengthPostRaw(requestParameters: MoraLengthMoraLengthPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>> { - console.log("moraLengthMoraLengthPostRaw"); if (requestParameters.speaker === null || requestParameters.speaker === undefined) { throw new runtime.RequiredError('speaker','Required parameter requestParameters.speaker was null or undefined when calling moraLengthMoraLengthPost.'); } @@ -1834,7 +1808,6 @@ export class DefaultApi extends runtime.BaseAPI implements DefaultApiInterface { * アクセント句から音高を得る */ async moraPitchMoraPitchPostRaw(requestParameters: MoraPitchMoraPitchPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>> { - console.log("moraPitchMoraPitchPostRaw"); if (requestParameters.speaker === null || requestParameters.speaker === undefined) { throw new runtime.RequiredError('speaker','Required parameter requestParameters.speaker was null or undefined when calling moraPitchMoraPitchPost.'); } @@ -1919,7 +1892,6 @@ export class DefaultApi extends runtime.BaseAPI implements DefaultApiInterface { * 複数まとめて音声合成する */ async multiSynthesisMultiSynthesisPostRaw(requestParameters: MultiSynthesisMultiSynthesisPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { - console.log("multiSynthesisMultiSynthesisPostRaw"); if (requestParameters.speaker === null || requestParameters.speaker === undefined) { throw new runtime.RequiredError('speaker','Required parameter requestParameters.speaker was null or undefined when calling multiSynthesisMultiSynthesisPost.'); } @@ -1966,7 +1938,6 @@ export class DefaultApi extends runtime.BaseAPI implements DefaultApiInterface { * Rewrite User Dict Word */ async rewriteUserDictWordUserDictWordWordUuidPutRaw(requestParameters: RewriteUserDictWordUserDictWordWordUuidPutRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { - console.log("rewriteUserDictWordUserDictWordWordUuidPutRaw"); if (requestParameters.wordUuid === null || requestParameters.wordUuid === undefined) { throw new runtime.RequiredError('wordUuid','Required parameter requestParameters.wordUuid was null or undefined when calling rewriteUserDictWordUserDictWordWordUuidPut.'); } @@ -2030,7 +2001,6 @@ export class DefaultApi extends runtime.BaseAPI implements DefaultApiInterface { * Setting Get */ async settingGetSettingGetRaw(initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { - console.log("settingGetSettingGetRaw"); const queryParameters: any = {}; const headerParameters: runtime.HTTPHeaders = {}; @@ -2058,7 +2028,6 @@ export class DefaultApi extends runtime.BaseAPI implements DefaultApiInterface { * Setting Post */ async settingPostSettingPostRaw(requestParameters: SettingPostSettingPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { - console.log("settingPostSettingPostRaw"); if (requestParameters.corsPolicyMode === null || requestParameters.corsPolicyMode === undefined) { throw new runtime.RequiredError('corsPolicyMode','Required parameter requestParameters.corsPolicyMode was null or undefined when calling settingPostSettingPost.'); } @@ -2314,7 +2283,6 @@ export class DefaultApi extends runtime.BaseAPI implements DefaultApiInterface { * Speakers */ async speakersSpeakersGetRaw(requestParameters: SpeakersSpeakersGetRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>> { - console.log("speakersSpeakersGetRaw"); const queryParameters: any = {}; if (requestParameters.coreVersion !== undefined) { @@ -2376,7 +2344,6 @@ export class DefaultApi extends runtime.BaseAPI implements DefaultApiInterface { * 2種類のスタイルでモーフィングした音声を合成する */ async synthesisMorphingSynthesisMorphingPostRaw(requestParameters: SynthesisMorphingSynthesisMorphingPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { - console.log("synthesisMorphingSynthesisMorphingPostRaw"); if (requestParameters.baseSpeaker === null || requestParameters.baseSpeaker === undefined) { throw new runtime.RequiredError('baseSpeaker','Required parameter requestParameters.baseSpeaker was null or undefined when calling synthesisMorphingSynthesisMorphingPost.'); } @@ -2439,7 +2406,6 @@ export class DefaultApi extends runtime.BaseAPI implements DefaultApiInterface { * 音声合成する */ async synthesisSynthesisPostRaw(requestParameters: SynthesisSynthesisPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { - console.log("synthesisSynthesisPostRaw"); if (requestParameters.speaker === null || requestParameters.speaker === undefined) { throw new runtime.RequiredError('speaker','Required parameter requestParameters.speaker was null or undefined when calling synthesisSynthesisPost.'); } @@ -2481,7 +2447,6 @@ export class DefaultApi extends runtime.BaseAPI implements DefaultApiInterface { * 音声合成する */ async synthesisSynthesisPost(requestParameters: SynthesisSynthesisPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { - console.log("synthesisSynthesisPost"); const response = await this.synthesisSynthesisPostRaw(requestParameters, initOverrides); return await response.value(); } @@ -2522,7 +2487,6 @@ export class DefaultApi extends runtime.BaseAPI implements DefaultApiInterface { * Update Preset */ async updatePresetUpdatePresetPostRaw(requestParameters: UpdatePresetUpdatePresetPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { - console.log("updatePresetUpdatePresetPostRaw"); if (requestParameters.preset === null || requestParameters.preset === undefined) { throw new runtime.RequiredError('preset','Required parameter requestParameters.preset was null or undefined when calling updatePresetUpdatePresetPost.'); } @@ -2562,7 +2526,6 @@ export class DefaultApi extends runtime.BaseAPI implements DefaultApiInterface { * テキストがAquesTalk 風記法に従っているか判定する */ async validateKanaValidateKanaPostRaw(requestParameters: ValidateKanaValidateKanaPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { - console.log("validateKanaValidateKanaPostRaw"); if (requestParameters.text === null || requestParameters.text === undefined) { throw new runtime.RequiredError('text','Required parameter requestParameters.text was null or undefined when calling validateKanaValidateKanaPost.'); } diff --git a/src/store/audio.ts b/src/store/audio.ts index b14fca2b0b..674f3da499 100644 --- a/src/store/audio.ts +++ b/src/store/audio.ts @@ -545,7 +545,6 @@ export const audioStore = createPartialStore({ * AudioItemに設定される話者(スタイルID)に対してエンジン側の初期化を行い、即座に音声合成ができるようにする。 */ async action({ commit, dispatch }, { engineId, audioKeys, styleId }) { - console.log("SETUP_SPEAKER"); const isInitialized = await dispatch("IS_INITIALIZED_ENGINE_SPEAKER", { engineId, styleId, @@ -641,7 +640,6 @@ export const audioStore = createPartialStore({ baseAudioItem?: AudioItem; }, ) { - console.log("GENERATE_AUDIO_ITEM"); //引数にbaseAudioItemが与えられた場合、baseAudioItemから話速等のパラメータを引き継いだAudioItemを返す //baseAudioItem.queryのうち、accentPhrasesとkanaは基本設定パラメータではないので引き継がない //baseAudioItemのうち、textとstyleIdは別途与えられるので引き継がない @@ -677,7 +675,7 @@ export const audioStore = createPartialStore({ engineId: voice.engineId, styleId: voice.styleId, }; - // ここでAudioItem > query > pauseLengthにundefinedが入ってると思う + const query = getters.IS_ENGINE_READY(voice.engineId) ? await dispatch("FETCH_AUDIO_QUERY", fetchQueryParams).catch( () => undefined, @@ -686,7 +684,6 @@ export const audioStore = createPartialStore({ if (query) { query.pauseLength = 0.3; } - console.log(query); const newAudioItem: AudioItem = { text, voice }; if (query != undefined) { @@ -750,7 +747,6 @@ export const audioStore = createPartialStore({ prevAudioKey, }: { audioItem: AudioItem; prevAudioKey?: AudioKey }, ) { - console.log("REGISTER_AUDIO_ITEM"); const audioKey = generateAudioKey(); commit("INSERT_AUDIO_ITEM", { audioItem, audioKey, prevAudioKey }); return audioKey; @@ -770,7 +766,6 @@ export const audioStore = createPartialStore({ prevAudioKey: AudioKey | undefined; }, ) { - console.log("INSERT_AUDIO_ITEM"); const index = prevAudioKey != undefined ? state.audioKeys.indexOf(prevAudioKey) + 1 @@ -794,7 +789,6 @@ export const audioStore = createPartialStore({ prevAudioKey: AudioKey | undefined; }, ) { - console.log("INSERT_AUDIO_ITEMS"); const index = prevAudioKey != undefined ? state.audioKeys.indexOf(prevAudioKey) + 1 @@ -907,7 +901,6 @@ export const audioStore = createPartialStore({ postPhonemeLength, }: { audioKey: AudioKey; postPhonemeLength: number }, ) { - console.log("SET_AUDIO_POST_PHONEME_LENGTH"); const query = state.audioItems[audioKey].query; if (query == undefined) throw new Error("query == undefined"); query.postPhonemeLength = postPhonemeLength; @@ -922,9 +915,7 @@ export const audioStore = createPartialStore({ pauseLength, }: { audioKey: AudioKey; pauseLength: number | null }, ) { - console.log("SET_AUDIO_PAUSE_LENGTH"); const query = state.audioItems[audioKey].query; - console.log(query); if (query == undefined) throw new Error("query == undefined"); query.pauseLength = pauseLength; }, @@ -941,9 +932,7 @@ export const audioStore = createPartialStore({ pauseLengthScale: number; }, ) { - console.log("SET_AUDIO_PAUSE_LENGTH_SCALE"); const query = state.audioItems[audioKey].query; - console.log(query); if (query == undefined) throw new Error("query == undefined"); query.pauseLengthScale = pauseLengthScale; }, @@ -981,7 +970,6 @@ export const audioStore = createPartialStore({ state, { audioKey, audioQuery }: { audioKey: AudioKey; audioQuery: AudioQuery }, ) { - console.log("SET_AUDIO_QUERY"); state.audioItems[audioKey].query = audioQuery; }, action( @@ -1001,7 +989,6 @@ export const audioStore = createPartialStore({ styleId, }: { text: string; engineId: EngineId; styleId: StyleId }, ) { - console.log("FETCH_AUDIO_QUERY"); return dispatch("INSTANTIATE_ENGINE_CONNECTOR", { engineId, }) @@ -1035,7 +1022,6 @@ export const audioStore = createPartialStore({ accentPhrases, }: { audioKey: AudioKey; accentPhrases: AccentPhrase[] }, ) { - console.log("SET_SINGLE_ACCENT_PHRASE"); const query = state.audioItems[audioKey].query; if (query == undefined) throw new Error("query == undefined"); query.accentPhrases = accentPhrases; @@ -1057,7 +1043,6 @@ export const audioStore = createPartialStore({ isKana?: boolean; }, ) { - console.log("FETCH_ACCENT_PHRASES"); return dispatch("INSTANTIATE_ENGINE_CONNECTOR", { engineId, }) @@ -1156,7 +1141,6 @@ export const audioStore = createPartialStore({ APPLY_AUDIO_PRESET: { mutation(state, { audioKey }: { audioKey: AudioKey }) { - console.log("APPLY_AUDIO_PRESET"); const audioItem = state.audioItems[audioKey]; if (!audioItem.presetKey) return; @@ -1283,9 +1267,7 @@ export const audioStore = createPartialStore({ GET_AUDIO_PLAY_OFFSETS: { action({ state }, { audioKey }: { audioKey: AudioKey }) { - console.log("GET_AUDIO_PLAY_OFFSETS"); const query = state.audioItems[audioKey].query; - console.log(query); const accentPhrases = query?.accentPhrases; if (query == undefined || accentPhrases == undefined) throw Error("query == undefined or accentPhrases == undefined"); @@ -1302,7 +1284,9 @@ export const audioStore = createPartialStore({ length += m.vowelLength; }); if (state.switchPauseLengthMode === "SCALE") { - length += phrase.pauseMora ? phrase.pauseMora.vowelLength * query.pauseLengthScale : 0; + length += phrase.pauseMora + ? phrase.pauseMora.vowelLength * query.pauseLengthScale + : 0; } else { length += phrase.pauseMora ? phrase.pauseMora.vowelLength : 0; } @@ -1322,7 +1306,6 @@ export const audioStore = createPartialStore({ { dispatch, state }, { audioKey, ...options }: { audioKey: AudioKey; cacheOnly?: boolean }, ) { - console.log("FETCH_AUDIO"); const audioItem: AudioItem = JSON.parse( JSON.stringify(state.audioItems[audioKey]), ); @@ -1330,8 +1313,6 @@ export const audioStore = createPartialStore({ if (audioItem.query) { audioItem.query.pauseLength = null; } - await console.log("以下audioItem"); - await console.log(audioItem); return dispatch("FETCH_AUDIO_FROM_AUDIO_ITEM", { audioItem, ...options, @@ -1345,7 +1326,6 @@ export const audioStore = createPartialStore({ { dispatch, state }, options: { audioItem: AudioItem; cacheOnly?: boolean }, ) => { - console.log("FETCH_AUDIO_FROM_AUDIO_ITEM"); const instance = await dispatch("INSTANTIATE_ENGINE_CONNECTOR", { engineId: options.audioItem.voice.engineId, }); @@ -1391,7 +1371,6 @@ export const audioStore = createPartialStore({ filePath?: string; }, ): Promise => { - console.log("GENERATE_AND_SAVE_AUDIO"); const defaultAudioFileName = getters.DEFAULT_AUDIO_FILE_NAME(audioKey); if (state.savingSetting.fixedExportEnabled) { filePath = path.join( @@ -1536,7 +1515,6 @@ export const audioStore = createPartialStore({ callback?: (finishedCount: number, totalCount: number) => void; }, ): Promise => { - console.log("GENERATE_AND_CONNECT_AND_SAVE_AUDIO"); const defaultFileName = `${getters.DEFAULT_PROJECT_FILE_BASE_NAME}.wav`; if (state.savingSetting.fixedExportEnabled) { @@ -1674,7 +1652,6 @@ export const audioStore = createPartialStore({ { state, getters }, { filePath }: { filePath?: string }, ): Promise => { - console.log("CONNECT_AND_EXPORT_TEXT"); const defaultFileName = `${getters.DEFAULT_PROJECT_FILE_BASE_NAME}.txt`; if (state.savingSetting.fixedExportEnabled) { filePath = path.join( @@ -1754,7 +1731,6 @@ export const audioStore = createPartialStore({ PLAY_AUDIO: { action: createUILockAction( async ({ commit, dispatch }, { audioKey }: { audioKey: AudioKey }) => { - console.log("PLAY_AUDIO"); await dispatch("STOP_AUDIO"); // 音声用意 @@ -1763,15 +1739,12 @@ export const audioStore = createPartialStore({ audioKey, nowGenerating: true, }); - console.log(`audioKey : ${audioKey}`); try { fetchAudioResult = await withProgress( dispatch("FETCH_AUDIO", { audioKey }), dispatch, ); - console.log(fetchAudioResult); } finally { - // console.log(fetchAudioResult); // 来てない commit("SET_AUDIO_NOW_GENERATING", { audioKey, nowGenerating: false, @@ -1792,7 +1765,6 @@ export const audioStore = createPartialStore({ { getters, commit, dispatch }, { audioBlob, audioKey }: { audioBlob: Blob; audioKey?: AudioKey }, ) => { - console.log("PLAY_AUDIO_BLOB"); commit("SET_AUDIO_SOURCE", { audioBlob }); let offset: number | undefined; // 途中再生用の処理 @@ -1823,7 +1795,6 @@ export const audioStore = createPartialStore({ presetKey, }: { audioKey: AudioKey; presetKey: PresetKey | undefined }, ) { - console.log("SET_AUDIO_PRESET_KEY"); if (presetKey == undefined) { delete state.audioItems[audioKey].presetKey; } else { @@ -1834,7 +1805,6 @@ export const audioStore = createPartialStore({ PLAY_CONTINUOUSLY_AUDIO: { action: createUILockAction(async ({ state, getters, commit, dispatch }) => { - console.log("PLAY_CONTINUOUSLY_AUDIO"); const currentAudioKey = state._activeAudioKey; const currentAudioPlayStartPoint = getters.AUDIO_PLAY_START_POINT; @@ -1981,7 +1951,6 @@ export const audioCommandStore = transformCommandStore( { state, commit, dispatch }, { audioKey, text }: { audioKey: AudioKey; text: string }, ) { - console.log("COMMAND_CHANGE_AUDIO_TEXT"); const engineId = state.audioItems[audioKey].voice.engineId; const styleId = state.audioItems[audioKey].voice.styleId; const query = state.audioItems[audioKey].query; @@ -1989,7 +1958,6 @@ export const audioCommandStore = transformCommandStore( enableMemoNotation: state.enableMemoNotation, enableRubyNotation: state.enableRubyNotation, }); - console.log(`skippedText : ${skippedText}`); try { if (query != undefined) { @@ -2001,8 +1969,6 @@ export const audioCommandStore = transformCommandStore( styleId, }, ); - await console.log(query); - await console.log(accentPhrases); // 読みの内容が変わっていなければテキストだけ変更 const isSameText = !isAccentPhrasesTextDifferent( @@ -2075,7 +2041,6 @@ export const audioCommandStore = transformCommandStore( >; }, ) { - console.log("COMMAND_MULTI_CHANGE_VOICE"); for (const [audioKey_, change] of Object.entries(payload.changes)) { // TypeScriptは`Object.entries`のKeyの型を`string`としてしまうので、`as`で型を指定する const audioKey = audioKey_ as AudioKey; @@ -2211,7 +2176,6 @@ export const audioCommandStore = transformCommandStore( accent, }: { audioKey: AudioKey; accentPhraseIndex: number; accent: number }, ) { - console.log("COMMAND_CHANGE_ACCENT"); const query = state.audioItems[audioKey].query; if (query != undefined) { const newAccentPhrases: AccentPhrase[] = JSON.parse( @@ -2265,7 +2229,6 @@ export const audioCommandStore = transformCommandStore( accentPhraseIndex: number; } & ({ isPause: false; moraIndex: number } | { isPause: true }), ) { - console.log("COMMAND_CHANGE_ACCENT_PHRASE_SPLIT"); const { audioKey, accentPhraseIndex } = payload; const query = state.audioItems[audioKey].query; @@ -2382,7 +2345,6 @@ export const audioCommandStore = transformCommandStore( accentPhraseIndex: number; }, ) { - console.log("COMMAND_DELETE_ACCENT_PHRASE"); const query = state.audioItems[audioKey].query; if (query == undefined) throw new Error("query == undefined"); @@ -2425,7 +2387,6 @@ export const audioCommandStore = transformCommandStore( popUntilPause: boolean; }, ) { - console.log("COMMAND_CHANGE_SINGLE_ACCENT_PHRASE"); const engineId = state.audioItems[audioKey].voice.engineId; const styleId = state.audioItems[audioKey].voice.styleId; @@ -2447,7 +2408,6 @@ export const audioCommandStore = transformCommandStore( // accent phraseの生成をリクエスト // 判別できない読み仮名が混じっていた場合400エラーが帰るのでfallback - console.log("COMMAND_CHANGE_SINGLE_ACCENT_PHRASE"); newAccentPhrasesSegment = await dispatch("FETCH_ACCENT_PHRASES", { text: pureKatakanaWithAccent, engineId, @@ -2522,7 +2482,6 @@ export const audioCommandStore = transformCommandStore( COMMAND_MULTI_RESET_MORA_PITCH_AND_LENGTH: { async action({ state, dispatch, commit }, { audioKeys }) { - console.log("COMMAND_MULTI_RESET_MORA_PITCH_AND_LENGTH"); for (const audioKey of audioKeys) { const engineId = state.audioItems[audioKey].voice.engineId; const styleId = state.audioItems[audioKey].voice.styleId; @@ -2549,7 +2508,6 @@ export const audioCommandStore = transformCommandStore( { state, dispatch, commit }, { audioKey, accentPhraseIndex }, ) { - console.log("COMMAND_RESET_SELECTED_MORA_PITCH_AND_LENGTH"); const engineId = state.audioItems[audioKey].voice.engineId; const styleId = state.audioItems[audioKey].voice.styleId; @@ -2608,7 +2566,6 @@ export const audioCommandStore = transformCommandStore( type: MoraDataType; }, ) { - console.log("COMMAND_SET_AUDIO_MORA_DATA_ACCENT_PHRASE"); const maxPitch = 6.5; const minPitch = 3; const maxMoraLength = 0.3; @@ -2918,7 +2875,6 @@ export const audioCommandStore = transformCommandStore( COMMAND_FULLY_APPLY_AUDIO_PRESET: { mutation(draft, { presetKey }: { presetKey: PresetKey }) { - console.log("COMMAND_FULLY_APPLY_AUDIO_PRESET"); const targetAudioKeys = draft.audioKeys.filter( (audioKey) => draft.audioItems[audioKey].presetKey === presetKey, ); @@ -2950,7 +2906,6 @@ export const audioCommandStore = transformCommandStore( { state, commit, dispatch, getters }, { filePath }: { filePath?: string }, ) => { - console.log("COMMAND_IMPORT_FROM_FILE"); if (!filePath) { filePath = await window.backend.showImportFileDialog({ title: "セリフ読み込み", @@ -3029,7 +2984,6 @@ export const audioCommandStore = transformCommandStore( voice: Voice; }, ) => { - console.log("COMMAND_PUT_TEXTS"); const audioKeyItemPairs: { audioKey: AudioKey; audioItem: AudioItem; diff --git a/src/store/audioGenerate.ts b/src/store/audioGenerate.ts index 278e298dbd..879bdbe5f0 100644 --- a/src/store/audioGenerate.ts +++ b/src/store/audioGenerate.ts @@ -27,7 +27,6 @@ export async function fetchAudioFromAudioItem( audioItem: AudioItem; }, ): Promise { - console.log("fetchAudioFromAudioItem"); const engineId = audioItem.voice.engineId; const [id, audioQuery] = await generateUniqueIdAndQuery(state, audioItem); @@ -35,22 +34,15 @@ export async function fetchAudioFromAudioItem( throw new Error("audioQuery is not defined for audioItem"); if (Object.prototype.hasOwnProperty.call(audioBlobCache, id)) { - console.log("check"); // 来てない const blob = audioBlobCache[id]; return { audioQuery, blob }; } - // audioQuery.accentPhrases[0].moras[0].vowelLength = 0.1; // 反映確認 + const speaker = audioItem.voice.styleId; - // audioQuery.accentPhrases[0].moras[0].vowelLength = 0.1; // 反映確認 - // 何かしらの互換のための処理? const engineAudioQuery = convertAudioQueryFromEditorToEngine( audioQuery, state.engineManifests[engineId].defaultSamplingRate, ); - // audioQuery.accentPhrases[0].moras[0].vowelLength = 0.1; // 反映確認 - // マニュアル値の設定はどこでやってるんだろ audioQueryの前? - // console.log(audioQuery); - await console.log(engineAudioQuery); let blob: Blob; // FIXME: モーフィングが設定で無効化されていてもモーフィングが行われるので気づけるUIを作成する @@ -78,7 +70,6 @@ export async function generateLabFromAudioQuery( audioQuery: EditorAudioQuery, offset?: number, ) { - console.log("generateLabFromAudioQuery"); const speedScale = audioQuery.speedScale; let labString = ""; diff --git a/src/store/engine.ts b/src/store/engine.ts index 561575880a..3e8823b99b 100644 --- a/src/store/engine.ts +++ b/src/store/engine.ts @@ -202,7 +202,6 @@ export const engineStore = createPartialStore({ RESTART_ENGINES: { async action({ dispatch, commit }, { engineIds }) { - console.log("RESTART_ENGINES"); await Promise.all( engineIds.map(async (engineId) => { commit("SET_ENGINE_STATE", { engineId, engineState: "STARTING" }); @@ -231,7 +230,6 @@ export const engineStore = createPartialStore({ POST_ENGINE_START: { async action({ state, dispatch }, { engineIds }) { - console.log("POST_ENGINE_START"); await dispatch("GET_ALT_PORT_INFOS"); const result = await Promise.all( engineIds.map(async (engineId) => { @@ -313,7 +311,6 @@ export const engineStore = createPartialStore({ * 指定した話者(スタイルID)がエンジン側で初期化されているか */ async action({ dispatch }, { engineId, styleId }) { - console.log("IS_INITIALIZED_ENGINE_SPEAKER"); const isInitialized = await dispatch("INSTANTIATE_ENGINE_CONNECTOR", { engineId, }).then((instance) => diff --git a/src/store/preset.ts b/src/store/preset.ts index 94a16eb325..3d4ef200a2 100644 --- a/src/store/preset.ts +++ b/src/store/preset.ts @@ -167,7 +167,6 @@ export const presetStore = createPartialStore({ presetKeys, }: { presetItems: Record; presetKeys: PresetKey[] }, ) { - console.log("SAVE_PRESET_CONFIG"); const result = await window.backend.setSetting("presets", { items: JSON.parse(JSON.stringify(presetItems)), keys: JSON.parse(JSON.stringify(presetKeys)), @@ -201,8 +200,8 @@ export const presetStore = createPartialStore({ CREATE_ALL_DEFAULT_PRESET: { async action({ state, dispatch, getters }) { - console.log("CREATE_ALL_DEFAULT_PRESET"); const voices = getters.GET_ALL_VOICES("talk"); + for (const voice of voices) { const voiceId = VoiceId(voice); const defaultPresetKey = state.defaultPresetKeys[voiceId]; @@ -212,7 +211,6 @@ export const presetStore = createPartialStore({ } const characterName = getters.VOICE_NAME(voice); - console.log(`characterName : ${characterName}`); const presetData: Preset = { name: `デフォルト:${characterName}`, speedScale: 1.0, @@ -241,7 +239,6 @@ export const presetStore = createPartialStore({ context, { presetKey, presetData }: { presetData: Preset; presetKey: PresetKey }, ) { - console.log("UPDATE_PRESET"); const newPresetItems = { ...context.state.presetItems, [presetKey]: presetData, diff --git a/src/store/project.ts b/src/store/project.ts index 917e98f18c..71cb0b6ba4 100755 --- a/src/store/project.ts +++ b/src/store/project.ts @@ -187,7 +187,6 @@ export const projectStore = createPartialStore({ context, { filePath, confirm }: { filePath?: string; confirm?: boolean }, ) => { - console.log("LOAD_PROJECT_FILE"); if (!filePath) { // Select and load a project File. const ret = await window.backend.showProjectLoadDialog({ @@ -251,9 +250,7 @@ export const projectStore = createPartialStore({ } } for (const audioItemsKey in projectData.audioItems) { - console.log(`audioItemsKey : ${audioItemsKey}`); if (projectData.audioItems[audioItemsKey].query != null) { - console.log("query代入"); projectData.audioItems[audioItemsKey].query.volumeScale = 1; projectData.audioItems[audioItemsKey].query.prePhonemeLength = 0.1; @@ -465,7 +462,6 @@ export const projectStore = createPartialStore({ // Validation check // トークはvalidateTalkProjectで検証する // ソングはSET_SCOREの中の`isValidScore`関数で検証される - console.log("parsedProjectData"); const parsedProjectData = projectSchema.parse(projectData); validateTalkProject(parsedProjectData.talk); diff --git a/src/store/proxy.ts b/src/store/proxy.ts index 784c82b3b0..799ef3e069 100644 --- a/src/store/proxy.ts +++ b/src/store/proxy.ts @@ -13,7 +13,6 @@ const proxyStoreCreator = (_engineFactory: IEngineConnectorFactory) => { const proxyStore = createPartialStore({ INSTANTIATE_ENGINE_CONNECTOR: { action({ state }, payload) { - // console.log("INSTANTIATE_ENGINE_CONNECTOR"); const engineId = payload.engineId; const engineInfo: EngineInfo | undefined = state.engineInfos[engineId]; if (engineInfo == undefined) @@ -22,7 +21,6 @@ const proxyStoreCreator = (_engineFactory: IEngineConnectorFactory) => { ); const instance = _engineFactory.instance(engineInfo.host); - // console.log(instance); return Promise.resolve({ invoke: (v) => (arg) => // FIXME: anyを使わないようにする From e66efe67de00c73e9a6638bea50f3ecb7daa4b22 Mon Sep 17 00:00:00 2001 From: X-20A <155217226+X-20A@users.noreply.github.com> Date: Sun, 2 Jun 2024 05:48:08 +0900 Subject: [PATCH 09/86] =?UTF-8?q?=E7=89=87=E4=BB=98=E3=81=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- env.production | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 env.production diff --git a/env.production b/env.production new file mode 100644 index 0000000000..5b0dcb0498 --- /dev/null +++ b/env.production @@ -0,0 +1,14 @@ +VITE_APP_NAME=voicevox +VITE_DEFAULT_ENGINE_INFOS=`[ + { + "uuid": "074fc39e-678b-4c13-8916-ffca8d505d1d", + "name": "VOICEVOX Engine", + "executionEnabled": true, + "executionFilePath": "vv-engine/run.exe", + "executionArgs": [], + "host": "http://127.0.0.1:50021" + } +]` +VITE_OFFICIAL_WEBSITE_URL=https://voicevox.hiroshiba.jp/ +VITE_LATEST_UPDATE_INFOS_URL=https://raw.githubusercontent.com/VOICEVOX/voicevox_blog/master/src/data/updateInfos.json +VITE_GTM_CONTAINER_ID=GTM-DUMMY From 3a56962a69c8fbd4ac9d2951b54463447d439cff Mon Sep 17 00:00:00 2001 From: X-20A <155217226+X-20A@users.noreply.github.com> Date: Fri, 7 Jun 2024 15:17:33 +0900 Subject: [PATCH 10/86] =?UTF-8?q?=E3=83=97=E3=83=AA=E3=82=BB=E3=83=83?= =?UTF-8?q?=E3=83=88=E5=90=8D=E5=A4=89=E6=9B=B4=20=E4=BB=96=E6=95=B4?= =?UTF-8?q?=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/Talk/AudioInfo.vue | 11 +++++------ src/openapi/apis/DefaultApi.ts | 6 ++++-- src/store/audio.ts | 1 + src/store/audioGenerate.ts | 1 + src/store/preset.ts | 1 + src/store/utility.ts | 4 ++-- src/type/preload.ts | 2 +- 7 files changed, 15 insertions(+), 11 deletions(-) diff --git a/src/components/Talk/AudioInfo.vue b/src/components/Talk/AudioInfo.vue index 150bd484cd..b974b71c6c 100644 --- a/src/components/Talk/AudioInfo.vue +++ b/src/components/Talk/AudioInfo.vue @@ -332,7 +332,7 @@ const uiLocked = computed(() => store.getters.UI_LOCKED); const audioItem = computed(() => store.state.audioItems[props.activeAudioKey]); const query = computed(() => audioItem.value?.query); -// 文内無音の指定方式 "SCALE" || "ABSOLUTE" +// 句読点などの無音時間の指定方式 "SCALE" || "ABSOLUTE" const switchPauseLengthMode = computed(() => { return store.state.switchPauseLengthMode; }); @@ -359,11 +359,10 @@ const selectedAudioKeys = computed(() => : [props.activeAudioKey], ); -// 文内無音はひとまず倍率verを表示 のち必要に応じ絶対値に切替 -// 泥臭くなっちゃったかも +// 句読点などの無音時間はひとまず倍率verを表示 のち必要に応じ絶対値に切替 const parameters = computed(() => { const plParam: Parameter = { - label: "文内無音(秒)", + label: "句読点などの無音時間(秒)", slider: previewSliderHelper({ modelValue: () => query.value?.pauseLength ?? null, disable: () => uiLocked.value, @@ -383,7 +382,7 @@ const parameters = computed(() => { }; const plsParam: Parameter = { - label: "文内無音(倍)", + label: "句読点などの無音時間(倍)", slider: previewSliderHelper({ modelValue: () => query.value?.pauseLengthScale ?? null, disable: () => uiLocked.value, @@ -523,7 +522,7 @@ const parameters = computed(() => { }, switchPauseLengthMode.value === "SCALE" ? plsParam : plParam, ]; - // こっからswitchPauseLengthModeの変更に伴って更新 + // switchPauseLengthModeの変更に伴って更新 const newParam = switchPauseLengthMode.value === "SCALE" ? plsParam : plParam; const index = baseParam.findIndex((param) => param.label === newParam.label); if (index !== -1) { diff --git a/src/openapi/apis/DefaultApi.ts b/src/openapi/apis/DefaultApi.ts index 18e65d5ca2..98ab6ad468 100644 --- a/src/openapi/apis/DefaultApi.ts +++ b/src/openapi/apis/DefaultApi.ts @@ -5,7 +5,7 @@ * VOICEVOXの音声合成エンジンです。 * * The version of the OpenAPI document: latest - * + * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). * https://openapi-generator.tech @@ -1113,7 +1113,7 @@ export class DefaultApi extends runtime.BaseAPI implements DefaultApiInterface { } if (requestParameters.speaker === null || requestParameters.speaker === undefined) { - throw new runtime.RequiredError('speaker','Required parameter requestParameters.speaker was null or undefined when calling QueryPost.'); + throw new runtime.RequiredError('speaker','Required parameter requestParameters.speaker was null or undefined when calling audioQueryAudioQueryPost.'); } const queryParameters: any = {}; @@ -1131,12 +1131,14 @@ export class DefaultApi extends runtime.BaseAPI implements DefaultApiInterface { } const headerParameters: runtime.HTTPHeaders = {}; + const response = await this.request({ path: `/audio_query`, method: 'POST', headers: headerParameters, query: queryParameters, }, initOverrides); + return new runtime.JSONApiResponse(response, (jsonValue) => AudioQueryFromJSON(jsonValue)); } diff --git a/src/store/audio.ts b/src/store/audio.ts index 674f3da499..e2c300bda8 100644 --- a/src/store/audio.ts +++ b/src/store/audio.ts @@ -1750,6 +1750,7 @@ export const audioStore = createPartialStore({ nowGenerating: false, }); } + const { blob } = fetchAudioResult; return dispatch("PLAY_AUDIO_BLOB", { audioBlob: blob, diff --git a/src/store/audioGenerate.ts b/src/store/audioGenerate.ts index 879bdbe5f0..9d69bf1e03 100644 --- a/src/store/audioGenerate.ts +++ b/src/store/audioGenerate.ts @@ -39,6 +39,7 @@ export async function fetchAudioFromAudioItem( } const speaker = audioItem.voice.styleId; + const engineAudioQuery = convertAudioQueryFromEditorToEngine( audioQuery, state.engineManifests[engineId].defaultSamplingRate, diff --git a/src/store/preset.ts b/src/store/preset.ts index 3d4ef200a2..8bf55b9bda 100644 --- a/src/store/preset.ts +++ b/src/store/preset.ts @@ -211,6 +211,7 @@ export const presetStore = createPartialStore({ } const characterName = getters.VOICE_NAME(voice); + const presetData: Preset = { name: `デフォルト:${characterName}`, speedScale: 1.0, diff --git a/src/store/utility.ts b/src/store/utility.ts index b04c631ea9..49f5cff8a9 100644 --- a/src/store/utility.ts +++ b/src/store/utility.ts @@ -103,7 +103,7 @@ export const SLIDER_PARAMETERS = { scrollMinStep: () => 0.01, }, /** - * 文内無音(絶対値)パラメータの定義 + * 句読点などの無音時間(絶対値)パラメータの定義 */ PAUSE_LENGTH: { max: () => 1, @@ -113,7 +113,7 @@ export const SLIDER_PARAMETERS = { scrollMinStep: () => 0.01, }, /** - * 文内無音(倍率)パラメータの定義 + * 句読点などの無音時間(倍率)パラメータの定義 */ PAUSE_LENGTH_SCALE: { max: () => 2, diff --git a/src/type/preload.ts b/src/type/preload.ts index c13095c269..903fb86c2d 100644 --- a/src/type/preload.ts +++ b/src/type/preload.ts @@ -652,7 +652,7 @@ export const configSchema = z volumeScale: z.number(), prePhonemeLength: z.number(), postPhonemeLength: z.number(), - pauseLength: z.number(), + pauseLength: z.number().nullable(), pauseLengthScale: z.number(), morphingInfo: z .object({ From bb35b1758ba17405f2cda1f0318286afefe8695a Mon Sep 17 00:00:00 2001 From: X-20A <155217226+X-20A@users.noreply.github.com> Date: Fri, 7 Jun 2024 15:33:54 +0900 Subject: [PATCH 11/86] =?UTF-8?q?=E3=83=97=E3=83=AA=E3=82=BB=E3=83=83?= =?UTF-8?q?=E3=83=88=E5=90=8D=E5=A4=89=E6=9B=B4=20=E4=BB=96=E6=95=B4?= =?UTF-8?q?=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/openapi/apis/DefaultApi.ts | 2554 +++++++++++++++--------------- src/openapi/models/AudioQuery.ts | 24 +- src/openapi/models/Preset.ts | 26 +- 3 files changed, 1302 insertions(+), 1302 deletions(-) diff --git a/src/openapi/apis/DefaultApi.ts b/src/openapi/apis/DefaultApi.ts index 98ab6ad468..6c404c7aa2 100644 --- a/src/openapi/apis/DefaultApi.ts +++ b/src/openapi/apis/DefaultApi.ts @@ -15,62 +15,62 @@ import * as runtime from '../runtime'; import type { - AccentPhrase, - AudioQuery, - BodySingFrameVolumeSingFrameVolumePost, - CorsPolicyMode, - DownloadableLibraryInfo, - EngineManifest, - FrameAudioQuery, - HTTPValidationError, - InstalledLibraryInfo, - MorphableTargetInfo, - ParseKanaBadRequest, - Preset, - Score, - Speaker, - SpeakerInfo, - SupportedDevicesInfo, - UserDictWord, - WordTypes, +AccentPhrase, +AudioQuery, +BodySingFrameVolumeSingFrameVolumePost, +CorsPolicyMode, +DownloadableLibraryInfo, +EngineManifest, +FrameAudioQuery, +HTTPValidationError, +InstalledLibraryInfo, +MorphableTargetInfo, +ParseKanaBadRequest, +Preset, +Score, +Speaker, +SpeakerInfo, +SupportedDevicesInfo, +UserDictWord, +WordTypes, } from '../models/index'; import { - AccentPhraseFromJSON, - AccentPhraseToJSON, - AudioQueryFromJSON, - AudioQueryToJSON, - BodySingFrameVolumeSingFrameVolumePostFromJSON, - BodySingFrameVolumeSingFrameVolumePostToJSON, - CorsPolicyModeFromJSON, - CorsPolicyModeToJSON, - DownloadableLibraryInfoFromJSON, - DownloadableLibraryInfoToJSON, - EngineManifestFromJSON, - EngineManifestToJSON, - FrameAudioQueryFromJSON, - FrameAudioQueryToJSON, - HTTPValidationErrorFromJSON, - HTTPValidationErrorToJSON, - InstalledLibraryInfoFromJSON, - InstalledLibraryInfoToJSON, - MorphableTargetInfoFromJSON, - MorphableTargetInfoToJSON, - ParseKanaBadRequestFromJSON, - ParseKanaBadRequestToJSON, - PresetFromJSON, - PresetToJSON, - ScoreFromJSON, - ScoreToJSON, - SpeakerFromJSON, - SpeakerToJSON, - SpeakerInfoFromJSON, - SpeakerInfoToJSON, - SupportedDevicesInfoFromJSON, - SupportedDevicesInfoToJSON, - UserDictWordFromJSON, - UserDictWordToJSON, - WordTypesFromJSON, - WordTypesToJSON, +AccentPhraseFromJSON, +AccentPhraseToJSON, +AudioQueryFromJSON, +AudioQueryToJSON, +BodySingFrameVolumeSingFrameVolumePostFromJSON, +BodySingFrameVolumeSingFrameVolumePostToJSON, +CorsPolicyModeFromJSON, +CorsPolicyModeToJSON, +DownloadableLibraryInfoFromJSON, +DownloadableLibraryInfoToJSON, +EngineManifestFromJSON, +EngineManifestToJSON, +FrameAudioQueryFromJSON, +FrameAudioQueryToJSON, +HTTPValidationErrorFromJSON, +HTTPValidationErrorToJSON, +InstalledLibraryInfoFromJSON, +InstalledLibraryInfoToJSON, +MorphableTargetInfoFromJSON, +MorphableTargetInfoToJSON, +ParseKanaBadRequestFromJSON, +ParseKanaBadRequestToJSON, +PresetFromJSON, +PresetToJSON, +ScoreFromJSON, +ScoreToJSON, +SpeakerFromJSON, +SpeakerToJSON, +SpeakerInfoFromJSON, +SpeakerInfoToJSON, +SupportedDevicesInfoFromJSON, +SupportedDevicesInfoToJSON, +UserDictWordFromJSON, +UserDictWordToJSON, +WordTypesFromJSON, +WordTypesToJSON, } from '../models/index'; export interface AccentPhrasesAccentPhrasesPostRequest { @@ -130,7 +130,7 @@ export interface FrameSynthesisFrameSynthesisPostRequest { export interface ImportUserDictWordsImportUserDictPostRequest { override: boolean; - requestBody: { [key: string]: UserDictWord; } | null; +requestBody: { [key: string]: UserDictWord; } | null; } export interface InitializeSpeakerInitializeSpeakerPostRequest { @@ -254,47 +254,47 @@ export interface ValidateKanaValidateKanaPostRequest { /** * DefaultApi - interface - * + * * @export * @interface DefaultApiInterface */ export interface DefaultApiInterface { - /** +/** * テキストからアクセント句を得ます。 is_kanaが`true`のとき、テキストは次のAquesTalk 風記法で解釈されます。デフォルトは`false`です。 * 全てのカナはカタカナで記述される * アクセント句は`/`または`、`で区切る。`、`で区切った場合に限り無音区間が挿入される。 * カナの手前に`_`を入れるとそのカナは無声化される * アクセント位置を`\'`で指定する。全てのアクセント句にはアクセント位置を1つ指定する必要がある。 * アクセント句末に`?`(全角)を入れることにより疑問文の発音ができる。 * @summary テキストからアクセント句を得る - * @param {string} text - * @param {number} speaker - * @param {boolean} [isKana] - * @param {string} [coreVersion] + * @param {string} text + * @param {number} speaker + * @param {boolean} [isKana] + * @param {string} [coreVersion] * @param {*} [options] Override http request option. * @throws {RequiredError} * @memberof DefaultApiInterface */ accentPhrasesAccentPhrasesPostRaw(requestParameters: AccentPhrasesAccentPhrasesPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>>; - /** +/** * テキストからアクセント句を得ます。 is_kanaが`true`のとき、テキストは次のAquesTalk 風記法で解釈されます。デフォルトは`false`です。 * 全てのカナはカタカナで記述される * アクセント句は`/`または`、`で区切る。`、`で区切った場合に限り無音区間が挿入される。 * カナの手前に`_`を入れるとそのカナは無声化される * アクセント位置を`\'`で指定する。全てのアクセント句にはアクセント位置を1つ指定する必要がある。 * アクセント句末に`?`(全角)を入れることにより疑問文の発音ができる。 * テキストからアクセント句を得る */ accentPhrasesAccentPhrasesPost(requestParameters: AccentPhrasesAccentPhrasesPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>; - /** +/** * 新しいプリセットを追加します * @summary Add Preset - * @param {Preset} preset + * @param {Preset} preset * @param {*} [options] Override http request option. * @throws {RequiredError} * @memberof DefaultApiInterface */ addPresetAddPresetPostRaw(requestParameters: AddPresetAddPresetPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>; - /** +/** * 新しいプリセットを追加します * Add Preset */ addPresetAddPresetPost(requestParameters: AddPresetAddPresetPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise; - /** +/** * ユーザー辞書に言葉を追加します。 * @summary Add User Dict Word * @param {string} surface 言葉の表層形 @@ -308,83 +308,83 @@ export interface DefaultApiInterface { */ addUserDictWordUserDictWordPostRaw(requestParameters: AddUserDictWordUserDictWordPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>; - /** +/** * ユーザー辞書に言葉を追加します。 * Add User Dict Word */ addUserDictWordUserDictWordPost(requestParameters: AddUserDictWordUserDictWordPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise; - /** +/** * 音声合成用のクエリの初期値を得ます。ここで得られたクエリはそのまま音声合成に利用できます。各値の意味は`Schemas`を参照してください。 * @summary 音声合成用のクエリを作成する - * @param {string} text - * @param {number} speaker - * @param {string} [coreVersion] + * @param {string} text + * @param {number} speaker + * @param {string} [coreVersion] * @param {*} [options] Override http request option. * @throws {RequiredError} * @memberof DefaultApiInterface */ audioQueryAudioQueryPostRaw(requestParameters: AudioQueryAudioQueryPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>; - /** +/** * 音声合成用のクエリの初期値を得ます。ここで得られたクエリはそのまま音声合成に利用できます。各値の意味は`Schemas`を参照してください。 * 音声合成用のクエリを作成する */ audioQueryAudioQueryPost(requestParameters: AudioQueryAudioQueryPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise; - /** +/** * 音声合成用のクエリの初期値を得ます。ここで得られたクエリはそのまま音声合成に利用できます。各値の意味は`Schemas`を参照してください。 * @summary 音声合成用のクエリをプリセットを用いて作成する - * @param {string} text - * @param {number} presetId - * @param {string} [coreVersion] + * @param {string} text + * @param {number} presetId + * @param {string} [coreVersion] * @param {*} [options] Override http request option. * @throws {RequiredError} * @memberof DefaultApiInterface */ audioQueryFromPresetAudioQueryFromPresetPostRaw(requestParameters: AudioQueryFromPresetAudioQueryFromPresetPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>; - /** +/** * 音声合成用のクエリの初期値を得ます。ここで得られたクエリはそのまま音声合成に利用できます。各値の意味は`Schemas`を参照してください。 * 音声合成用のクエリをプリセットを用いて作成する */ audioQueryFromPresetAudioQueryFromPresetPost(requestParameters: AudioQueryFromPresetAudioQueryFromPresetPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise; - /** - * +/** + * * @summary 音声合成する(キャンセル可能) - * @param {number} speaker - * @param {AudioQuery} audioQuery - * @param {string} [coreVersion] + * @param {number} speaker + * @param {AudioQuery} audioQuery + * @param {string} [coreVersion] * @param {*} [options] Override http request option. * @throws {RequiredError} * @memberof DefaultApiInterface */ cancellableSynthesisCancellableSynthesisPostRaw(requestParameters: CancellableSynthesisCancellableSynthesisPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>; - /** +/** * 音声合成する(キャンセル可能) */ cancellableSynthesisCancellableSynthesisPost(requestParameters: CancellableSynthesisCancellableSynthesisPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise; - /** +/** * base64エンコードされたwavデータを一纏めにし、wavファイルで返します。 * @summary base64エンコードされた複数のwavデータを一つに結合する - * @param {Array} requestBody + * @param {Array} requestBody * @param {*} [options] Override http request option. * @throws {RequiredError} * @memberof DefaultApiInterface */ connectWavesConnectWavesPostRaw(requestParameters: ConnectWavesConnectWavesPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>; - /** +/** * base64エンコードされたwavデータを一纏めにし、wavファイルで返します。 * base64エンコードされた複数のwavデータを一つに結合する */ connectWavesConnectWavesPost(requestParameters: ConnectWavesConnectWavesPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise; - /** - * +/** + * * @summary Core Versions * @param {*} [options] Override http request option. * @throws {RequiredError} @@ -392,12 +392,12 @@ export interface DefaultApiInterface { */ coreVersionsCoreVersionsGetRaw(initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>>; - /** +/** * Core Versions */ coreVersionsCoreVersionsGet(initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>; - /** +/** * 既存のプリセットを削除します * @summary Delete Preset * @param {number} id 削除するプリセットのプリセットID @@ -407,13 +407,13 @@ export interface DefaultApiInterface { */ deletePresetDeletePresetPostRaw(requestParameters: DeletePresetDeletePresetPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>; - /** +/** * 既存のプリセットを削除します * Delete Preset */ deletePresetDeletePresetPost(requestParameters: DeletePresetDeletePresetPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise; - /** +/** * ユーザー辞書に登録されている言葉を削除します。 * @summary Delete User Dict Word * @param {string} wordUuid 削除する言葉のUUID @@ -423,13 +423,13 @@ export interface DefaultApiInterface { */ deleteUserDictWordUserDictWordWordUuidDeleteRaw(requestParameters: DeleteUserDictWordUserDictWordWordUuidDeleteRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>; - /** +/** * ユーザー辞書に登録されている言葉を削除します。 * Delete User Dict Word */ deleteUserDictWordUserDictWordWordUuidDelete(requestParameters: DeleteUserDictWordUserDictWordWordUuidDeleteRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise; - /** +/** * ダウンロード可能な音声ライブラリの情報を返します。 * @summary Downloadable Libraries * @param {*} [options] Override http request option. @@ -438,14 +438,14 @@ export interface DefaultApiInterface { */ downloadableLibrariesDownloadableLibrariesGetRaw(initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>>; - /** +/** * ダウンロード可能な音声ライブラリの情報を返します。 * Downloadable Libraries */ downloadableLibrariesDownloadableLibrariesGet(initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>; - /** - * +/** + * * @summary Engine Manifest * @param {*} [options] Override http request option. * @throws {RequiredError} @@ -453,30 +453,30 @@ export interface DefaultApiInterface { */ engineManifestEngineManifestGetRaw(initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>; - /** +/** * Engine Manifest */ engineManifestEngineManifestGet(initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise; - /** +/** * 歌唱音声合成を行います。 * @summary Frame Synthesis - * @param {number} speaker - * @param {FrameAudioQuery} frameAudioQuery - * @param {string} [coreVersion] + * @param {number} speaker + * @param {FrameAudioQuery} frameAudioQuery + * @param {string} [coreVersion] * @param {*} [options] Override http request option. * @throws {RequiredError} * @memberof DefaultApiInterface */ frameSynthesisFrameSynthesisPostRaw(requestParameters: FrameSynthesisFrameSynthesisPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>; - /** +/** * 歌唱音声合成を行います。 * Frame Synthesis */ frameSynthesisFrameSynthesisPost(requestParameters: FrameSynthesisFrameSynthesisPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise; - /** +/** * エンジンが保持しているプリセットの設定を返します * @summary Get Presets * @param {*} [options] Override http request option. @@ -485,13 +485,13 @@ export interface DefaultApiInterface { */ getPresetsPresetsGetRaw(initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>>; - /** +/** * エンジンが保持しているプリセットの設定を返します * Get Presets */ getPresetsPresetsGet(initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>; - /** +/** * ユーザー辞書に登録されている単語の一覧を返します。 単語の表層形(surface)は正規化済みの物を返します。 * @summary Get User Dict Words * @param {*} [options] Override http request option. @@ -500,48 +500,48 @@ export interface DefaultApiInterface { */ getUserDictWordsUserDictGetRaw(initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>; - /** +/** * ユーザー辞書に登録されている単語の一覧を返します。 単語の表層形(surface)は正規化済みの物を返します。 * Get User Dict Words */ getUserDictWordsUserDictGet(initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise<{ [key: string]: UserDictWord; }>; - /** +/** * 他のユーザー辞書をインポートします。 * @summary Import User Dict Words * @param {boolean} override 重複したエントリがあった場合、上書きするかどうか - * @param {{ [key: string]: UserDictWord; }} requestBody + * @param {{ [key: string]: UserDictWord; }} requestBody * @param {*} [options] Override http request option. * @throws {RequiredError} * @memberof DefaultApiInterface */ importUserDictWordsImportUserDictPostRaw(requestParameters: ImportUserDictWordsImportUserDictPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>; - /** +/** * 他のユーザー辞書をインポートします。 * Import User Dict Words */ importUserDictWordsImportUserDictPost(requestParameters: ImportUserDictWordsImportUserDictPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise; - /** +/** * 指定されたスタイルを初期化します。 実行しなくても他のAPIは使用できますが、初回実行時に時間がかかることがあります。 * @summary Initialize Speaker - * @param {number} speaker + * @param {number} speaker * @param {boolean} [skipReinit] 既に初期化済みのスタイルの再初期化をスキップするかどうか - * @param {string} [coreVersion] + * @param {string} [coreVersion] * @param {*} [options] Override http request option. * @throws {RequiredError} * @memberof DefaultApiInterface */ initializeSpeakerInitializeSpeakerPostRaw(requestParameters: InitializeSpeakerInitializeSpeakerPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>; - /** +/** * 指定されたスタイルを初期化します。 実行しなくても他のAPIは使用できますが、初回実行時に時間がかかることがあります。 * Initialize Speaker */ initializeSpeakerInitializeSpeakerPost(requestParameters: InitializeSpeakerInitializeSpeakerPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise; - /** +/** * 音声ライブラリをインストールします。 音声ライブラリのZIPファイルをリクエストボディとして送信してください。 * @summary Install Library * @param {string} libraryUuid 音声ライブラリのID @@ -551,13 +551,13 @@ export interface DefaultApiInterface { */ installLibraryInstallLibraryLibraryUuidPostRaw(requestParameters: InstallLibraryInstallLibraryLibraryUuidPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>; - /** +/** * 音声ライブラリをインストールします。 音声ライブラリのZIPファイルをリクエストボディとして送信してください。 * Install Library */ installLibraryInstallLibraryLibraryUuidPost(requestParameters: InstallLibraryInstallLibraryLibraryUuidPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise; - /** +/** * インストールした音声ライブラリの情報を返します。 * @summary Installed Libraries * @param {*} [options] Override http request option. @@ -566,115 +566,115 @@ export interface DefaultApiInterface { */ installedLibrariesInstalledLibrariesGetRaw(initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>; - /** +/** * インストールした音声ライブラリの情報を返します。 * Installed Libraries */ installedLibrariesInstalledLibrariesGet(initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise<{ [key: string]: InstalledLibraryInfo; }>; - /** +/** * 指定されたスタイルが初期化されているかどうかを返します。 * @summary Is Initialized Speaker - * @param {number} speaker - * @param {string} [coreVersion] + * @param {number} speaker + * @param {string} [coreVersion] * @param {*} [options] Override http request option. * @throws {RequiredError} * @memberof DefaultApiInterface */ isInitializedSpeakerIsInitializedSpeakerGetRaw(requestParameters: IsInitializedSpeakerIsInitializedSpeakerGetRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>; - /** +/** * 指定されたスタイルが初期化されているかどうかを返します。 * Is Initialized Speaker */ isInitializedSpeakerIsInitializedSpeakerGet(requestParameters: IsInitializedSpeakerIsInitializedSpeakerGetRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise; - /** - * +/** + * * @summary アクセント句から音高・音素長を得る - * @param {number} speaker - * @param {Array} accentPhrase - * @param {string} [coreVersion] + * @param {number} speaker + * @param {Array} accentPhrase + * @param {string} [coreVersion] * @param {*} [options] Override http request option. * @throws {RequiredError} * @memberof DefaultApiInterface */ moraDataMoraDataPostRaw(requestParameters: MoraDataMoraDataPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>>; - /** +/** * アクセント句から音高・音素長を得る */ moraDataMoraDataPost(requestParameters: MoraDataMoraDataPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>; - /** - * +/** + * * @summary アクセント句から音素長を得る - * @param {number} speaker - * @param {Array} accentPhrase - * @param {string} [coreVersion] + * @param {number} speaker + * @param {Array} accentPhrase + * @param {string} [coreVersion] * @param {*} [options] Override http request option. * @throws {RequiredError} * @memberof DefaultApiInterface */ moraLengthMoraLengthPostRaw(requestParameters: MoraLengthMoraLengthPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>>; - /** +/** * アクセント句から音素長を得る */ moraLengthMoraLengthPost(requestParameters: MoraLengthMoraLengthPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>; - /** - * +/** + * * @summary アクセント句から音高を得る - * @param {number} speaker - * @param {Array} accentPhrase - * @param {string} [coreVersion] + * @param {number} speaker + * @param {Array} accentPhrase + * @param {string} [coreVersion] * @param {*} [options] Override http request option. * @throws {RequiredError} * @memberof DefaultApiInterface */ moraPitchMoraPitchPostRaw(requestParameters: MoraPitchMoraPitchPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>>; - /** +/** * アクセント句から音高を得る */ moraPitchMoraPitchPost(requestParameters: MoraPitchMoraPitchPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>; - /** +/** * 指定されたベーススタイルに対してエンジン内の各話者がモーフィング機能を利用可能か返します。 モーフィングの許可/禁止は`/speakers`の`speaker.supported_features.synthesis_morphing`に記載されています。 プロパティが存在しない場合は、モーフィングが許可されているとみなします。 返り値のスタイルIDはstring型なので注意。 * @summary 指定したスタイルに対してエンジン内の話者がモーフィングが可能か判定する - * @param {Array} requestBody - * @param {string} [coreVersion] + * @param {Array} requestBody + * @param {string} [coreVersion] * @param {*} [options] Override http request option. * @throws {RequiredError} * @memberof DefaultApiInterface */ morphableTargetsMorphableTargetsPostRaw(requestParameters: MorphableTargetsMorphableTargetsPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>>; - /** +/** * 指定されたベーススタイルに対してエンジン内の各話者がモーフィング機能を利用可能か返します。 モーフィングの許可/禁止は`/speakers`の`speaker.supported_features.synthesis_morphing`に記載されています。 プロパティが存在しない場合は、モーフィングが許可されているとみなします。 返り値のスタイルIDはstring型なので注意。 * 指定したスタイルに対してエンジン内の話者がモーフィングが可能か判定する */ morphableTargetsMorphableTargetsPost(requestParameters: MorphableTargetsMorphableTargetsPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>; - /** - * +/** + * * @summary 複数まとめて音声合成する - * @param {number} speaker - * @param {Array} audioQuery - * @param {string} [coreVersion] + * @param {number} speaker + * @param {Array} audioQuery + * @param {string} [coreVersion] * @param {*} [options] Override http request option. * @throws {RequiredError} * @memberof DefaultApiInterface */ multiSynthesisMultiSynthesisPostRaw(requestParameters: MultiSynthesisMultiSynthesisPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>; - /** +/** * 複数まとめて音声合成する */ multiSynthesisMultiSynthesisPost(requestParameters: MultiSynthesisMultiSynthesisPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise; - /** +/** * ユーザー辞書に登録されている言葉を更新します。 * @summary Rewrite User Dict Word * @param {string} wordUuid 更新する言葉のUUID @@ -689,13 +689,13 @@ export interface DefaultApiInterface { */ rewriteUserDictWordUserDictWordWordUuidPutRaw(requestParameters: RewriteUserDictWordUserDictWordWordUuidPutRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>; - /** +/** * ユーザー辞書に登録されている言葉を更新します。 * Rewrite User Dict Word */ rewriteUserDictWordUserDictWordWordUuidPut(requestParameters: RewriteUserDictWordUserDictWordWordUuidPutRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise; - /** +/** * 設定ページを返します。 * @summary Setting Get * @param {*} [options] Override http request option. @@ -704,182 +704,182 @@ export interface DefaultApiInterface { */ settingGetSettingGetRaw(initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>; - /** +/** * 設定ページを返します。 * Setting Get */ settingGetSettingGet(initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise; - /** +/** * 設定を更新します。 * @summary Setting Post - * @param {CorsPolicyMode} corsPolicyMode - * @param {string} [allowOrigin] + * @param {CorsPolicyMode} corsPolicyMode + * @param {string} [allowOrigin] * @param {*} [options] Override http request option. * @throws {RequiredError} * @memberof DefaultApiInterface */ settingPostSettingPostRaw(requestParameters: SettingPostSettingPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>; - /** +/** * 設定を更新します。 * Setting Post */ settingPostSettingPost(requestParameters: SettingPostSettingPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise; - /** +/** * 歌唱音声合成用のクエリの初期値を得ます。ここで得られたクエリはそのまま歌唱音声合成に利用できます。各値の意味は`Schemas`を参照してください。 * @summary 歌唱音声合成用のクエリを作成する - * @param {number} speaker - * @param {Score} score - * @param {string} [coreVersion] + * @param {number} speaker + * @param {Score} score + * @param {string} [coreVersion] * @param {*} [options] Override http request option. * @throws {RequiredError} * @memberof DefaultApiInterface */ singFrameAudioQuerySingFrameAudioQueryPostRaw(requestParameters: SingFrameAudioQuerySingFrameAudioQueryPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>; - /** +/** * 歌唱音声合成用のクエリの初期値を得ます。ここで得られたクエリはそのまま歌唱音声合成に利用できます。各値の意味は`Schemas`を参照してください。 * 歌唱音声合成用のクエリを作成する */ singFrameAudioQuerySingFrameAudioQueryPost(requestParameters: SingFrameAudioQuerySingFrameAudioQueryPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise; - /** - * +/** + * * @summary スコア・歌唱音声合成用のクエリからフレームごとの音量を得る - * @param {number} speaker - * @param {BodySingFrameVolumeSingFrameVolumePost} bodySingFrameVolumeSingFrameVolumePost - * @param {string} [coreVersion] + * @param {number} speaker + * @param {BodySingFrameVolumeSingFrameVolumePost} bodySingFrameVolumeSingFrameVolumePost + * @param {string} [coreVersion] * @param {*} [options] Override http request option. * @throws {RequiredError} * @memberof DefaultApiInterface */ singFrameVolumeSingFrameVolumePostRaw(requestParameters: SingFrameVolumeSingFrameVolumePostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>>; - /** +/** * スコア・歌唱音声合成用のクエリからフレームごとの音量を得る */ singFrameVolumeSingFrameVolumePost(requestParameters: SingFrameVolumeSingFrameVolumePostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>; - /** +/** * 指定されたspeaker_uuidに関する情報をjson形式で返します。 画像や音声はbase64エンコードされたものが返されます。 * @summary Singer Info - * @param {string} speakerUuid - * @param {string} [coreVersion] + * @param {string} speakerUuid + * @param {string} [coreVersion] * @param {*} [options] Override http request option. * @throws {RequiredError} * @memberof DefaultApiInterface */ singerInfoSingerInfoGetRaw(requestParameters: SingerInfoSingerInfoGetRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>; - /** +/** * 指定されたspeaker_uuidに関する情報をjson形式で返します。 画像や音声はbase64エンコードされたものが返されます。 * Singer Info */ singerInfoSingerInfoGet(requestParameters: SingerInfoSingerInfoGetRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise; - /** - * +/** + * * @summary Singers - * @param {string} [coreVersion] + * @param {string} [coreVersion] * @param {*} [options] Override http request option. * @throws {RequiredError} * @memberof DefaultApiInterface */ singersSingersGetRaw(requestParameters: SingersSingersGetRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>>; - /** +/** * Singers */ singersSingersGet(requestParameters: SingersSingersGetRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>; - /** +/** * 指定されたspeaker_uuidに関する情報をjson形式で返します。 画像や音声はbase64エンコードされたものが返されます。 * @summary Speaker Info - * @param {string} speakerUuid - * @param {string} [coreVersion] + * @param {string} speakerUuid + * @param {string} [coreVersion] * @param {*} [options] Override http request option. * @throws {RequiredError} * @memberof DefaultApiInterface */ speakerInfoSpeakerInfoGetRaw(requestParameters: SpeakerInfoSpeakerInfoGetRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>; - /** +/** * 指定されたspeaker_uuidに関する情報をjson形式で返します。 画像や音声はbase64エンコードされたものが返されます。 * Speaker Info */ speakerInfoSpeakerInfoGet(requestParameters: SpeakerInfoSpeakerInfoGetRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise; - /** - * +/** + * * @summary Speakers - * @param {string} [coreVersion] + * @param {string} [coreVersion] * @param {*} [options] Override http request option. * @throws {RequiredError} * @memberof DefaultApiInterface */ speakersSpeakersGetRaw(requestParameters: SpeakersSpeakersGetRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>>; - /** +/** * Speakers */ speakersSpeakersGet(requestParameters: SpeakersSpeakersGetRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>; - /** - * +/** + * * @summary Supported Devices - * @param {string} [coreVersion] + * @param {string} [coreVersion] * @param {*} [options] Override http request option. * @throws {RequiredError} * @memberof DefaultApiInterface */ supportedDevicesSupportedDevicesGetRaw(requestParameters: SupportedDevicesSupportedDevicesGetRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>; - /** +/** * Supported Devices */ supportedDevicesSupportedDevicesGet(requestParameters: SupportedDevicesSupportedDevicesGetRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise; - /** +/** * 指定された2種類のスタイルで音声を合成、指定した割合でモーフィングした音声を得ます。 モーフィングの割合は`morph_rate`で指定でき、0.0でベースのスタイル、1.0でターゲットのスタイルに近づきます。 * @summary 2種類のスタイルでモーフィングした音声を合成する - * @param {number} baseSpeaker - * @param {number} targetSpeaker - * @param {number} morphRate - * @param {AudioQuery} audioQuery - * @param {string} [coreVersion] + * @param {number} baseSpeaker + * @param {number} targetSpeaker + * @param {number} morphRate + * @param {AudioQuery} audioQuery + * @param {string} [coreVersion] * @param {*} [options] Override http request option. * @throws {RequiredError} * @memberof DefaultApiInterface */ synthesisMorphingSynthesisMorphingPostRaw(requestParameters: SynthesisMorphingSynthesisMorphingPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>; - /** +/** * 指定された2種類のスタイルで音声を合成、指定した割合でモーフィングした音声を得ます。 モーフィングの割合は`morph_rate`で指定でき、0.0でベースのスタイル、1.0でターゲットのスタイルに近づきます。 * 2種類のスタイルでモーフィングした音声を合成する */ synthesisMorphingSynthesisMorphingPost(requestParameters: SynthesisMorphingSynthesisMorphingPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise; - /** - * +/** + * * @summary 音声合成する - * @param {number} speaker - * @param {AudioQuery} audioQuery + * @param {number} speaker + * @param {AudioQuery} audioQuery * @param {boolean} [enableInterrogativeUpspeak] 疑問系のテキストが与えられたら語尾を自動調整する - * @param {string} [coreVersion] + * @param {string} [coreVersion] * @param {*} [options] Override http request option. * @throws {RequiredError} * @memberof DefaultApiInterface */ synthesisSynthesisPostRaw(requestParameters: SynthesisSynthesisPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>; - /** +/** * 音声合成する */ synthesisSynthesisPost(requestParameters: SynthesisSynthesisPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise; - /** +/** * 音声ライブラリをアンインストールします。 * @summary Uninstall Library * @param {string} libraryUuid 音声ライブラリのID @@ -889,29 +889,29 @@ export interface DefaultApiInterface { */ uninstallLibraryUninstallLibraryLibraryUuidPostRaw(requestParameters: UninstallLibraryUninstallLibraryLibraryUuidPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>; - /** +/** * 音声ライブラリをアンインストールします。 * Uninstall Library */ uninstallLibraryUninstallLibraryLibraryUuidPost(requestParameters: UninstallLibraryUninstallLibraryLibraryUuidPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise; - /** +/** * 既存のプリセットを更新します * @summary Update Preset - * @param {Preset} preset + * @param {Preset} preset * @param {*} [options] Override http request option. * @throws {RequiredError} * @memberof DefaultApiInterface */ updatePresetUpdatePresetPostRaw(requestParameters: UpdatePresetUpdatePresetPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>; - /** +/** * 既存のプリセットを更新します * Update Preset */ updatePresetUpdatePresetPost(requestParameters: UpdatePresetUpdatePresetPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise; - /** +/** * テキストがAquesTalk 風記法に従っているかどうかを判定します。 従っていない場合はエラーが返ります。 * @summary テキストがAquesTalk 風記法に従っているか判定する * @param {string} text 判定する対象の文字列 @@ -921,14 +921,14 @@ export interface DefaultApiInterface { */ validateKanaValidateKanaPostRaw(requestParameters: ValidateKanaValidateKanaPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>; - /** +/** * テキストがAquesTalk 風記法に従っているかどうかを判定します。 従っていない場合はエラーが返ります。 * テキストがAquesTalk 風記法に従っているか判定する */ validateKanaValidateKanaPost(requestParameters: ValidateKanaValidateKanaPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise; - /** - * +/** + * * @summary Version * @param {*} [options] Override http request option. * @throws {RequiredError} @@ -936,7 +936,7 @@ export interface DefaultApiInterface { */ versionVersionGetRaw(initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>; - /** +/** * Version */ versionVersionGet(initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise; @@ -944,1653 +944,1653 @@ export interface DefaultApiInterface { } /** - * + * */ export class DefaultApi extends runtime.BaseAPI implements DefaultApiInterface { - /** +/** * テキストからアクセント句を得ます。 is_kanaが`true`のとき、テキストは次のAquesTalk 風記法で解釈されます。デフォルトは`false`です。 * 全てのカナはカタカナで記述される * アクセント句は`/`または`、`で区切る。`、`で区切った場合に限り無音区間が挿入される。 * カナの手前に`_`を入れるとそのカナは無声化される * アクセント位置を`\'`で指定する。全てのアクセント句にはアクセント位置を1つ指定する必要がある。 * アクセント句末に`?`(全角)を入れることにより疑問文の発音ができる。 * テキストからアクセント句を得る */ - async accentPhrasesAccentPhrasesPostRaw(requestParameters: AccentPhrasesAccentPhrasesPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>> { - if (requestParameters.text === null || requestParameters.text === undefined) { - throw new runtime.RequiredError('text','Required parameter requestParameters.text was null or undefined when calling accentPhrasesAccentPhrasesPost.'); - } +async accentPhrasesAccentPhrasesPostRaw(requestParameters: AccentPhrasesAccentPhrasesPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>> { +if (requestParameters.text === null || requestParameters.text === undefined) { + throw new runtime.RequiredError('text','Required parameter requestParameters.text was null or undefined when calling accentPhrasesAccentPhrasesPost.'); +} - if (requestParameters.speaker === null || requestParameters.speaker === undefined) { - throw new runtime.RequiredError('speaker','Required parameter requestParameters.speaker was null or undefined when calling accentPhrasesAccentPhrasesPost.'); - } +if (requestParameters.speaker === null || requestParameters.speaker === undefined) { + throw new runtime.RequiredError('speaker','Required parameter requestParameters.speaker was null or undefined when calling accentPhrasesAccentPhrasesPost.'); +} - const queryParameters: any = {}; +const queryParameters: any = {}; - if (requestParameters.text !== undefined) { - queryParameters['text'] = requestParameters.text; - } +if (requestParameters.text !== undefined) { + queryParameters['text'] = requestParameters.text; +} - if (requestParameters.speaker !== undefined) { - queryParameters['speaker'] = requestParameters.speaker; - } +if (requestParameters.speaker !== undefined) { + queryParameters['speaker'] = requestParameters.speaker; +} - if (requestParameters.isKana !== undefined) { - queryParameters['is_kana'] = requestParameters.isKana; - } +if (requestParameters.isKana !== undefined) { + queryParameters['is_kana'] = requestParameters.isKana; +} - if (requestParameters.coreVersion !== undefined) { - queryParameters['core_version'] = requestParameters.coreVersion; - } +if (requestParameters.coreVersion !== undefined) { + queryParameters['core_version'] = requestParameters.coreVersion; +} - const headerParameters: runtime.HTTPHeaders = {}; +const headerParameters: runtime.HTTPHeaders = {}; - const response = await this.request({ - path: `/accent_phrases`, - method: 'POST', - headers: headerParameters, - query: queryParameters, - }, initOverrides); +const response = await this.request({ + path: `/accent_phrases`, + method: 'POST', + headers: headerParameters, + query: queryParameters, +}, initOverrides); - return new runtime.JSONApiResponse(response, (jsonValue) => jsonValue.map(AccentPhraseFromJSON)); + return new runtime.JSONApiResponse(response, (jsonValue) => jsonValue.map(AccentPhraseFromJSON)); } - /** +/** * テキストからアクセント句を得ます。 is_kanaが`true`のとき、テキストは次のAquesTalk 風記法で解釈されます。デフォルトは`false`です。 * 全てのカナはカタカナで記述される * アクセント句は`/`または`、`で区切る。`、`で区切った場合に限り無音区間が挿入される。 * カナの手前に`_`を入れるとそのカナは無声化される * アクセント位置を`\'`で指定する。全てのアクセント句にはアクセント位置を1つ指定する必要がある。 * アクセント句末に`?`(全角)を入れることにより疑問文の発音ができる。 * テキストからアクセント句を得る */ - async accentPhrasesAccentPhrasesPost(requestParameters: AccentPhrasesAccentPhrasesPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { - const response = await this.accentPhrasesAccentPhrasesPostRaw(requestParameters, initOverrides); - return await response.value(); - } +async accentPhrasesAccentPhrasesPost(requestParameters: AccentPhrasesAccentPhrasesPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { +const response = await this.accentPhrasesAccentPhrasesPostRaw(requestParameters, initOverrides); +return await response.value(); +} - /** +/** * 新しいプリセットを追加します * Add Preset */ - async addPresetAddPresetPostRaw(requestParameters: AddPresetAddPresetPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { - if (requestParameters.preset === null || requestParameters.preset === undefined) { - throw new runtime.RequiredError('preset','Required parameter requestParameters.preset was null or undefined when calling addPresetAddPresetPost.'); - } +async addPresetAddPresetPostRaw(requestParameters: AddPresetAddPresetPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { +if (requestParameters.preset === null || requestParameters.preset === undefined) { + throw new runtime.RequiredError('preset','Required parameter requestParameters.preset was null or undefined when calling addPresetAddPresetPost.'); +} - const queryParameters: any = {}; +const queryParameters: any = {}; - const headerParameters: runtime.HTTPHeaders = {}; +const headerParameters: runtime.HTTPHeaders = {}; - headerParameters['Content-Type'] = 'application/json'; +headerParameters['Content-Type'] = 'application/json'; - const response = await this.request({ - path: `/add_preset`, - method: 'POST', - headers: headerParameters, - query: queryParameters, - body: PresetToJSON(requestParameters.preset), - }, initOverrides); +const response = await this.request({ + path: `/add_preset`, + method: 'POST', + headers: headerParameters, + query: queryParameters, + body: PresetToJSON(requestParameters.preset), +}, initOverrides); - if (this.isJsonMime(response.headers.get('content-type'))) { - return new runtime.JSONApiResponse(response); - } else { - return new runtime.TextApiResponse(response) as any; - } - } +if (this.isJsonMime(response.headers.get('content-type'))) { + return new runtime.JSONApiResponse(response); +} else { + return new runtime.TextApiResponse(response) as any; +} +} - /** +/** * 新しいプリセットを追加します * Add Preset */ - async addPresetAddPresetPost(requestParameters: AddPresetAddPresetPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { - const response = await this.addPresetAddPresetPostRaw(requestParameters, initOverrides); - return await response.value(); - } +async addPresetAddPresetPost(requestParameters: AddPresetAddPresetPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { +const response = await this.addPresetAddPresetPostRaw(requestParameters, initOverrides); +return await response.value(); +} - /** +/** * ユーザー辞書に言葉を追加します。 * Add User Dict Word */ - async addUserDictWordUserDictWordPostRaw(requestParameters: AddUserDictWordUserDictWordPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { - if (requestParameters.surface === null || requestParameters.surface === undefined) { - throw new runtime.RequiredError('surface','Required parameter requestParameters.surface was null or undefined when calling addUserDictWordUserDictWordPost.'); - } +async addUserDictWordUserDictWordPostRaw(requestParameters: AddUserDictWordUserDictWordPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { +if (requestParameters.surface === null || requestParameters.surface === undefined) { + throw new runtime.RequiredError('surface','Required parameter requestParameters.surface was null or undefined when calling addUserDictWordUserDictWordPost.'); +} - if (requestParameters.pronunciation === null || requestParameters.pronunciation === undefined) { - throw new runtime.RequiredError('pronunciation','Required parameter requestParameters.pronunciation was null or undefined when calling addUserDictWordUserDictWordPost.'); - } +if (requestParameters.pronunciation === null || requestParameters.pronunciation === undefined) { + throw new runtime.RequiredError('pronunciation','Required parameter requestParameters.pronunciation was null or undefined when calling addUserDictWordUserDictWordPost.'); +} - if (requestParameters.accentType === null || requestParameters.accentType === undefined) { - throw new runtime.RequiredError('accentType','Required parameter requestParameters.accentType was null or undefined when calling addUserDictWordUserDictWordPost.'); - } +if (requestParameters.accentType === null || requestParameters.accentType === undefined) { + throw new runtime.RequiredError('accentType','Required parameter requestParameters.accentType was null or undefined when calling addUserDictWordUserDictWordPost.'); +} - const queryParameters: any = {}; +const queryParameters: any = {}; - if (requestParameters.surface !== undefined) { - queryParameters['surface'] = requestParameters.surface; - } +if (requestParameters.surface !== undefined) { + queryParameters['surface'] = requestParameters.surface; +} - if (requestParameters.pronunciation !== undefined) { - queryParameters['pronunciation'] = requestParameters.pronunciation; - } +if (requestParameters.pronunciation !== undefined) { + queryParameters['pronunciation'] = requestParameters.pronunciation; +} - if (requestParameters.accentType !== undefined) { - queryParameters['accent_type'] = requestParameters.accentType; - } +if (requestParameters.accentType !== undefined) { + queryParameters['accent_type'] = requestParameters.accentType; +} - if (requestParameters.wordType !== undefined) { - queryParameters['word_type'] = requestParameters.wordType; - } +if (requestParameters.wordType !== undefined) { + queryParameters['word_type'] = requestParameters.wordType; +} - if (requestParameters.priority !== undefined) { - queryParameters['priority'] = requestParameters.priority; - } +if (requestParameters.priority !== undefined) { + queryParameters['priority'] = requestParameters.priority; +} - const headerParameters: runtime.HTTPHeaders = {}; +const headerParameters: runtime.HTTPHeaders = {}; - const response = await this.request({ - path: `/user_dict_word`, - method: 'POST', - headers: headerParameters, - query: queryParameters, - }, initOverrides); +const response = await this.request({ + path: `/user_dict_word`, + method: 'POST', + headers: headerParameters, + query: queryParameters, +}, initOverrides); - if (this.isJsonMime(response.headers.get('content-type'))) { - return new runtime.JSONApiResponse(response); - } else { - return new runtime.TextApiResponse(response) as any; - } - } +if (this.isJsonMime(response.headers.get('content-type'))) { + return new runtime.JSONApiResponse(response); +} else { + return new runtime.TextApiResponse(response) as any; +} +} - /** +/** * ユーザー辞書に言葉を追加します。 * Add User Dict Word */ - async addUserDictWordUserDictWordPost(requestParameters: AddUserDictWordUserDictWordPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { - const response = await this.addUserDictWordUserDictWordPostRaw(requestParameters, initOverrides); - return await response.value(); - } +async addUserDictWordUserDictWordPost(requestParameters: AddUserDictWordUserDictWordPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { +const response = await this.addUserDictWordUserDictWordPostRaw(requestParameters, initOverrides); +return await response.value(); +} - /** +/** * 音声合成用のクエリの初期値を得ます。ここで得られたクエリはそのまま音声合成に利用できます。各値の意味は`Schemas`を参照してください。 * 音声合成用のクエリを作成する */ - async audioQueryAudioQueryPostRaw(requestParameters: AudioQueryAudioQueryPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { - if (requestParameters.text === null || requestParameters.text === undefined) { - throw new runtime.RequiredError('text','Required parameter requestParameters.text was null or undefined when calling audioQueryAudioQueryPost.'); - } +async audioQueryAudioQueryPostRaw(requestParameters: AudioQueryAudioQueryPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { +if (requestParameters.text === null || requestParameters.text === undefined) { + throw new runtime.RequiredError('text','Required parameter requestParameters.text was null or undefined when calling audioQueryAudioQueryPost.'); +} - if (requestParameters.speaker === null || requestParameters.speaker === undefined) { - throw new runtime.RequiredError('speaker','Required parameter requestParameters.speaker was null or undefined when calling audioQueryAudioQueryPost.'); - } +if (requestParameters.speaker === null || requestParameters.speaker === undefined) { + throw new runtime.RequiredError('speaker','Required parameter requestParameters.speaker was null or undefined when calling audioQueryAudioQueryPost.'); +} - const queryParameters: any = {}; +const queryParameters: any = {}; - if (requestParameters.text !== undefined) { - queryParameters['text'] = requestParameters.text; - } +if (requestParameters.text !== undefined) { + queryParameters['text'] = requestParameters.text; +} - if (requestParameters.speaker !== undefined) { - queryParameters['speaker'] = requestParameters.speaker; - } +if (requestParameters.speaker !== undefined) { + queryParameters['speaker'] = requestParameters.speaker; +} - if (requestParameters.coreVersion !== undefined) { - queryParameters['core_version'] = requestParameters.coreVersion; - } +if (requestParameters.coreVersion !== undefined) { + queryParameters['core_version'] = requestParameters.coreVersion; +} - const headerParameters: runtime.HTTPHeaders = {}; +const headerParameters: runtime.HTTPHeaders = {}; - const response = await this.request({ - path: `/audio_query`, - method: 'POST', - headers: headerParameters, - query: queryParameters, - }, initOverrides); +const response = await this.request({ + path: `/audio_query`, + method: 'POST', + headers: headerParameters, + query: queryParameters, +}, initOverrides); - return new runtime.JSONApiResponse(response, (jsonValue) => AudioQueryFromJSON(jsonValue)); + return new runtime.JSONApiResponse(response, (jsonValue) => AudioQueryFromJSON(jsonValue)); } - /** +/** * 音声合成用のクエリの初期値を得ます。ここで得られたクエリはそのまま音声合成に利用できます。各値の意味は`Schemas`を参照してください。 * 音声合成用のクエリを作成する */ - async audioQueryAudioQueryPost(requestParameters: AudioQueryAudioQueryPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { - const response = await this.audioQueryAudioQueryPostRaw(requestParameters, initOverrides); - return await response.value(); - } +async audioQueryAudioQueryPost(requestParameters: AudioQueryAudioQueryPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { +const response = await this.audioQueryAudioQueryPostRaw(requestParameters, initOverrides); +return await response.value(); +} - /** +/** * 音声合成用のクエリの初期値を得ます。ここで得られたクエリはそのまま音声合成に利用できます。各値の意味は`Schemas`を参照してください。 * 音声合成用のクエリをプリセットを用いて作成する */ - async audioQueryFromPresetAudioQueryFromPresetPostRaw(requestParameters: AudioQueryFromPresetAudioQueryFromPresetPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { - if (requestParameters.text === null || requestParameters.text === undefined) { - throw new runtime.RequiredError('text','Required parameter requestParameters.text was null or undefined when calling audioQueryFromPresetAudioQueryFromPresetPost.'); - } +async audioQueryFromPresetAudioQueryFromPresetPostRaw(requestParameters: AudioQueryFromPresetAudioQueryFromPresetPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { +if (requestParameters.text === null || requestParameters.text === undefined) { + throw new runtime.RequiredError('text','Required parameter requestParameters.text was null or undefined when calling audioQueryFromPresetAudioQueryFromPresetPost.'); +} - if (requestParameters.presetId === null || requestParameters.presetId === undefined) { - throw new runtime.RequiredError('presetId','Required parameter requestParameters.presetId was null or undefined when calling audioQueryFromPresetAudioQueryFromPresetPost.'); - } +if (requestParameters.presetId === null || requestParameters.presetId === undefined) { + throw new runtime.RequiredError('presetId','Required parameter requestParameters.presetId was null or undefined when calling audioQueryFromPresetAudioQueryFromPresetPost.'); +} - const queryParameters: any = {}; +const queryParameters: any = {}; - if (requestParameters.text !== undefined) { - queryParameters['text'] = requestParameters.text; - } +if (requestParameters.text !== undefined) { + queryParameters['text'] = requestParameters.text; +} - if (requestParameters.presetId !== undefined) { - queryParameters['preset_id'] = requestParameters.presetId; - } +if (requestParameters.presetId !== undefined) { + queryParameters['preset_id'] = requestParameters.presetId; +} - if (requestParameters.coreVersion !== undefined) { - queryParameters['core_version'] = requestParameters.coreVersion; - } +if (requestParameters.coreVersion !== undefined) { + queryParameters['core_version'] = requestParameters.coreVersion; +} - const headerParameters: runtime.HTTPHeaders = {}; +const headerParameters: runtime.HTTPHeaders = {}; - const response = await this.request({ - path: `/audio_query_from_preset`, - method: 'POST', - headers: headerParameters, - query: queryParameters, - }, initOverrides); +const response = await this.request({ + path: `/audio_query_from_preset`, + method: 'POST', + headers: headerParameters, + query: queryParameters, +}, initOverrides); - return new runtime.JSONApiResponse(response, (jsonValue) => AudioQueryFromJSON(jsonValue)); + return new runtime.JSONApiResponse(response, (jsonValue) => AudioQueryFromJSON(jsonValue)); } - /** +/** * 音声合成用のクエリの初期値を得ます。ここで得られたクエリはそのまま音声合成に利用できます。各値の意味は`Schemas`を参照してください。 * 音声合成用のクエリをプリセットを用いて作成する */ - async audioQueryFromPresetAudioQueryFromPresetPost(requestParameters: AudioQueryFromPresetAudioQueryFromPresetPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { - const response = await this.audioQueryFromPresetAudioQueryFromPresetPostRaw(requestParameters, initOverrides); - return await response.value(); - } +async audioQueryFromPresetAudioQueryFromPresetPost(requestParameters: AudioQueryFromPresetAudioQueryFromPresetPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { +const response = await this.audioQueryFromPresetAudioQueryFromPresetPostRaw(requestParameters, initOverrides); +return await response.value(); +} - /** +/** * 音声合成する(キャンセル可能) */ - async cancellableSynthesisCancellableSynthesisPostRaw(requestParameters: CancellableSynthesisCancellableSynthesisPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { - if (requestParameters.speaker === null || requestParameters.speaker === undefined) { - throw new runtime.RequiredError('speaker','Required parameter requestParameters.speaker was null or undefined when calling cancellableSynthesisCancellableSynthesisPost.'); - } +async cancellableSynthesisCancellableSynthesisPostRaw(requestParameters: CancellableSynthesisCancellableSynthesisPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { +if (requestParameters.speaker === null || requestParameters.speaker === undefined) { + throw new runtime.RequiredError('speaker','Required parameter requestParameters.speaker was null or undefined when calling cancellableSynthesisCancellableSynthesisPost.'); +} - if (requestParameters.audioQuery === null || requestParameters.audioQuery === undefined) { - throw new runtime.RequiredError('audioQuery','Required parameter requestParameters.audioQuery was null or undefined when calling cancellableSynthesisCancellableSynthesisPost.'); - } +if (requestParameters.audioQuery === null || requestParameters.audioQuery === undefined) { + throw new runtime.RequiredError('audioQuery','Required parameter requestParameters.audioQuery was null or undefined when calling cancellableSynthesisCancellableSynthesisPost.'); +} - const queryParameters: any = {}; +const queryParameters: any = {}; - if (requestParameters.speaker !== undefined) { - queryParameters['speaker'] = requestParameters.speaker; - } +if (requestParameters.speaker !== undefined) { + queryParameters['speaker'] = requestParameters.speaker; +} - if (requestParameters.coreVersion !== undefined) { - queryParameters['core_version'] = requestParameters.coreVersion; - } +if (requestParameters.coreVersion !== undefined) { + queryParameters['core_version'] = requestParameters.coreVersion; +} - const headerParameters: runtime.HTTPHeaders = {}; +const headerParameters: runtime.HTTPHeaders = {}; - headerParameters['Content-Type'] = 'application/json'; +headerParameters['Content-Type'] = 'application/json'; - const response = await this.request({ - path: `/cancellable_synthesis`, - method: 'POST', - headers: headerParameters, - query: queryParameters, - body: AudioQueryToJSON(requestParameters.audioQuery), - }, initOverrides); +const response = await this.request({ + path: `/cancellable_synthesis`, + method: 'POST', + headers: headerParameters, + query: queryParameters, + body: AudioQueryToJSON(requestParameters.audioQuery), +}, initOverrides); - return new runtime.BlobApiResponse(response); + return new runtime.BlobApiResponse(response); } - /** +/** * 音声合成する(キャンセル可能) */ - async cancellableSynthesisCancellableSynthesisPost(requestParameters: CancellableSynthesisCancellableSynthesisPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { - const response = await this.cancellableSynthesisCancellableSynthesisPostRaw(requestParameters, initOverrides); - return await response.value(); - } +async cancellableSynthesisCancellableSynthesisPost(requestParameters: CancellableSynthesisCancellableSynthesisPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { +const response = await this.cancellableSynthesisCancellableSynthesisPostRaw(requestParameters, initOverrides); +return await response.value(); +} - /** +/** * base64エンコードされたwavデータを一纏めにし、wavファイルで返します。 * base64エンコードされた複数のwavデータを一つに結合する */ - async connectWavesConnectWavesPostRaw(requestParameters: ConnectWavesConnectWavesPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { - if (requestParameters.requestBody === null || requestParameters.requestBody === undefined) { - throw new runtime.RequiredError('requestBody','Required parameter requestParameters.requestBody was null or undefined when calling connectWavesConnectWavesPost.'); - } +async connectWavesConnectWavesPostRaw(requestParameters: ConnectWavesConnectWavesPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { +if (requestParameters.requestBody === null || requestParameters.requestBody === undefined) { + throw new runtime.RequiredError('requestBody','Required parameter requestParameters.requestBody was null or undefined when calling connectWavesConnectWavesPost.'); +} - const queryParameters: any = {}; +const queryParameters: any = {}; - const headerParameters: runtime.HTTPHeaders = {}; +const headerParameters: runtime.HTTPHeaders = {}; - headerParameters['Content-Type'] = 'application/json'; +headerParameters['Content-Type'] = 'application/json'; - const response = await this.request({ - path: `/connect_waves`, - method: 'POST', - headers: headerParameters, - query: queryParameters, - body: requestParameters.requestBody, - }, initOverrides); +const response = await this.request({ + path: `/connect_waves`, + method: 'POST', + headers: headerParameters, + query: queryParameters, + body: requestParameters.requestBody, +}, initOverrides); - return new runtime.BlobApiResponse(response); + return new runtime.BlobApiResponse(response); } - /** +/** * base64エンコードされたwavデータを一纏めにし、wavファイルで返します。 * base64エンコードされた複数のwavデータを一つに結合する */ - async connectWavesConnectWavesPost(requestParameters: ConnectWavesConnectWavesPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { - const response = await this.connectWavesConnectWavesPostRaw(requestParameters, initOverrides); - return await response.value(); - } +async connectWavesConnectWavesPost(requestParameters: ConnectWavesConnectWavesPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { +const response = await this.connectWavesConnectWavesPostRaw(requestParameters, initOverrides); +return await response.value(); +} - /** +/** * Core Versions */ - async coreVersionsCoreVersionsGetRaw(initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>> { - const queryParameters: any = {}; +async coreVersionsCoreVersionsGetRaw(initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>> { +const queryParameters: any = {}; - const headerParameters: runtime.HTTPHeaders = {}; +const headerParameters: runtime.HTTPHeaders = {}; - const response = await this.request({ - path: `/core_versions`, - method: 'GET', - headers: headerParameters, - query: queryParameters, - }, initOverrides); +const response = await this.request({ + path: `/core_versions`, + method: 'GET', + headers: headerParameters, + query: queryParameters, +}, initOverrides); - return new runtime.JSONApiResponse(response); + return new runtime.JSONApiResponse(response); } - /** +/** * Core Versions */ - async coreVersionsCoreVersionsGet(initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { - const response = await this.coreVersionsCoreVersionsGetRaw(initOverrides); - return await response.value(); - } +async coreVersionsCoreVersionsGet(initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { +const response = await this.coreVersionsCoreVersionsGetRaw(initOverrides); +return await response.value(); +} - /** +/** * 既存のプリセットを削除します * Delete Preset */ - async deletePresetDeletePresetPostRaw(requestParameters: DeletePresetDeletePresetPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { - if (requestParameters.id === null || requestParameters.id === undefined) { - throw new runtime.RequiredError('id','Required parameter requestParameters.id was null or undefined when calling deletePresetDeletePresetPost.'); - } +async deletePresetDeletePresetPostRaw(requestParameters: DeletePresetDeletePresetPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { +if (requestParameters.id === null || requestParameters.id === undefined) { + throw new runtime.RequiredError('id','Required parameter requestParameters.id was null or undefined when calling deletePresetDeletePresetPost.'); +} - const queryParameters: any = {}; +const queryParameters: any = {}; - if (requestParameters.id !== undefined) { - queryParameters['id'] = requestParameters.id; - } +if (requestParameters.id !== undefined) { + queryParameters['id'] = requestParameters.id; +} - const headerParameters: runtime.HTTPHeaders = {}; +const headerParameters: runtime.HTTPHeaders = {}; - const response = await this.request({ - path: `/delete_preset`, - method: 'POST', - headers: headerParameters, - query: queryParameters, - }, initOverrides); +const response = await this.request({ + path: `/delete_preset`, + method: 'POST', + headers: headerParameters, + query: queryParameters, +}, initOverrides); - return new runtime.VoidApiResponse(response); + return new runtime.VoidApiResponse(response); } - /** +/** * 既存のプリセットを削除します * Delete Preset */ - async deletePresetDeletePresetPost(requestParameters: DeletePresetDeletePresetPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { - await this.deletePresetDeletePresetPostRaw(requestParameters, initOverrides); - } +async deletePresetDeletePresetPost(requestParameters: DeletePresetDeletePresetPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { + await this.deletePresetDeletePresetPostRaw(requestParameters, initOverrides); +} - /** +/** * ユーザー辞書に登録されている言葉を削除します。 * Delete User Dict Word */ - async deleteUserDictWordUserDictWordWordUuidDeleteRaw(requestParameters: DeleteUserDictWordUserDictWordWordUuidDeleteRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { - if (requestParameters.wordUuid === null || requestParameters.wordUuid === undefined) { - throw new runtime.RequiredError('wordUuid','Required parameter requestParameters.wordUuid was null or undefined when calling deleteUserDictWordUserDictWordWordUuidDelete.'); - } +async deleteUserDictWordUserDictWordWordUuidDeleteRaw(requestParameters: DeleteUserDictWordUserDictWordWordUuidDeleteRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { +if (requestParameters.wordUuid === null || requestParameters.wordUuid === undefined) { + throw new runtime.RequiredError('wordUuid','Required parameter requestParameters.wordUuid was null or undefined when calling deleteUserDictWordUserDictWordWordUuidDelete.'); +} - const queryParameters: any = {}; +const queryParameters: any = {}; - const headerParameters: runtime.HTTPHeaders = {}; +const headerParameters: runtime.HTTPHeaders = {}; - const response = await this.request({ - path: `/user_dict_word/{word_uuid}`.replace(`{${"word_uuid"}}`, encodeURIComponent(String(requestParameters.wordUuid))), - method: 'DELETE', - headers: headerParameters, - query: queryParameters, - }, initOverrides); +const response = await this.request({ + path: `/user_dict_word/{word_uuid}`.replace(`{${"word_uuid"}}`, encodeURIComponent(String(requestParameters.wordUuid))), + method: 'DELETE', + headers: headerParameters, + query: queryParameters, +}, initOverrides); - return new runtime.VoidApiResponse(response); + return new runtime.VoidApiResponse(response); } - /** +/** * ユーザー辞書に登録されている言葉を削除します。 * Delete User Dict Word */ - async deleteUserDictWordUserDictWordWordUuidDelete(requestParameters: DeleteUserDictWordUserDictWordWordUuidDeleteRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { - await this.deleteUserDictWordUserDictWordWordUuidDeleteRaw(requestParameters, initOverrides); - } +async deleteUserDictWordUserDictWordWordUuidDelete(requestParameters: DeleteUserDictWordUserDictWordWordUuidDeleteRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { + await this.deleteUserDictWordUserDictWordWordUuidDeleteRaw(requestParameters, initOverrides); +} - /** +/** * ダウンロード可能な音声ライブラリの情報を返します。 * Downloadable Libraries */ - async downloadableLibrariesDownloadableLibrariesGetRaw(initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>> { - const queryParameters: any = {}; +async downloadableLibrariesDownloadableLibrariesGetRaw(initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>> { +const queryParameters: any = {}; - const headerParameters: runtime.HTTPHeaders = {}; +const headerParameters: runtime.HTTPHeaders = {}; - const response = await this.request({ - path: `/downloadable_libraries`, - method: 'GET', - headers: headerParameters, - query: queryParameters, - }, initOverrides); +const response = await this.request({ + path: `/downloadable_libraries`, + method: 'GET', + headers: headerParameters, + query: queryParameters, +}, initOverrides); - return new runtime.JSONApiResponse(response, (jsonValue) => jsonValue.map(DownloadableLibraryInfoFromJSON)); + return new runtime.JSONApiResponse(response, (jsonValue) => jsonValue.map(DownloadableLibraryInfoFromJSON)); } - /** +/** * ダウンロード可能な音声ライブラリの情報を返します。 * Downloadable Libraries */ - async downloadableLibrariesDownloadableLibrariesGet(initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { - const response = await this.downloadableLibrariesDownloadableLibrariesGetRaw(initOverrides); - return await response.value(); - } +async downloadableLibrariesDownloadableLibrariesGet(initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { +const response = await this.downloadableLibrariesDownloadableLibrariesGetRaw(initOverrides); +return await response.value(); +} - /** +/** * Engine Manifest */ - async engineManifestEngineManifestGetRaw(initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { - const queryParameters: any = {}; +async engineManifestEngineManifestGetRaw(initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { +const queryParameters: any = {}; - const headerParameters: runtime.HTTPHeaders = {}; +const headerParameters: runtime.HTTPHeaders = {}; - const response = await this.request({ - path: `/engine_manifest`, - method: 'GET', - headers: headerParameters, - query: queryParameters, - }, initOverrides); +const response = await this.request({ + path: `/engine_manifest`, + method: 'GET', + headers: headerParameters, + query: queryParameters, +}, initOverrides); - return new runtime.JSONApiResponse(response, (jsonValue) => EngineManifestFromJSON(jsonValue)); + return new runtime.JSONApiResponse(response, (jsonValue) => EngineManifestFromJSON(jsonValue)); } - /** +/** * Engine Manifest */ - async engineManifestEngineManifestGet(initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { - const response = await this.engineManifestEngineManifestGetRaw(initOverrides); - return await response.value(); - } +async engineManifestEngineManifestGet(initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { +const response = await this.engineManifestEngineManifestGetRaw(initOverrides); +return await response.value(); +} - /** +/** * 歌唱音声合成を行います。 * Frame Synthesis */ - async frameSynthesisFrameSynthesisPostRaw(requestParameters: FrameSynthesisFrameSynthesisPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { - if (requestParameters.speaker === null || requestParameters.speaker === undefined) { - throw new runtime.RequiredError('speaker','Required parameter requestParameters.speaker was null or undefined when calling frameSynthesisFrameSynthesisPost.'); - } +async frameSynthesisFrameSynthesisPostRaw(requestParameters: FrameSynthesisFrameSynthesisPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { +if (requestParameters.speaker === null || requestParameters.speaker === undefined) { + throw new runtime.RequiredError('speaker','Required parameter requestParameters.speaker was null or undefined when calling frameSynthesisFrameSynthesisPost.'); +} - if (requestParameters.frameAudioQuery === null || requestParameters.frameAudioQuery === undefined) { - throw new runtime.RequiredError('frameAudioQuery','Required parameter requestParameters.frameAudioQuery was null or undefined when calling frameSynthesisFrameSynthesisPost.'); - } +if (requestParameters.frameAudioQuery === null || requestParameters.frameAudioQuery === undefined) { + throw new runtime.RequiredError('frameAudioQuery','Required parameter requestParameters.frameAudioQuery was null or undefined when calling frameSynthesisFrameSynthesisPost.'); +} - const queryParameters: any = {}; +const queryParameters: any = {}; - if (requestParameters.speaker !== undefined) { - queryParameters['speaker'] = requestParameters.speaker; - } +if (requestParameters.speaker !== undefined) { + queryParameters['speaker'] = requestParameters.speaker; +} - if (requestParameters.coreVersion !== undefined) { - queryParameters['core_version'] = requestParameters.coreVersion; - } +if (requestParameters.coreVersion !== undefined) { + queryParameters['core_version'] = requestParameters.coreVersion; +} - const headerParameters: runtime.HTTPHeaders = {}; +const headerParameters: runtime.HTTPHeaders = {}; - headerParameters['Content-Type'] = 'application/json'; +headerParameters['Content-Type'] = 'application/json'; - const response = await this.request({ - path: `/frame_synthesis`, - method: 'POST', - headers: headerParameters, - query: queryParameters, - body: FrameAudioQueryToJSON(requestParameters.frameAudioQuery), - }, initOverrides); +const response = await this.request({ + path: `/frame_synthesis`, + method: 'POST', + headers: headerParameters, + query: queryParameters, + body: FrameAudioQueryToJSON(requestParameters.frameAudioQuery), +}, initOverrides); - return new runtime.BlobApiResponse(response); + return new runtime.BlobApiResponse(response); } - /** +/** * 歌唱音声合成を行います。 * Frame Synthesis */ - async frameSynthesisFrameSynthesisPost(requestParameters: FrameSynthesisFrameSynthesisPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { - const response = await this.frameSynthesisFrameSynthesisPostRaw(requestParameters, initOverrides); - return await response.value(); - } +async frameSynthesisFrameSynthesisPost(requestParameters: FrameSynthesisFrameSynthesisPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { +const response = await this.frameSynthesisFrameSynthesisPostRaw(requestParameters, initOverrides); +return await response.value(); +} - /** +/** * エンジンが保持しているプリセットの設定を返します * Get Presets */ - async getPresetsPresetsGetRaw(initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>> { - const queryParameters: any = {}; +async getPresetsPresetsGetRaw(initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>> { +const queryParameters: any = {}; - const headerParameters: runtime.HTTPHeaders = {}; +const headerParameters: runtime.HTTPHeaders = {}; - const response = await this.request({ - path: `/presets`, - method: 'GET', - headers: headerParameters, - query: queryParameters, - }, initOverrides); +const response = await this.request({ + path: `/presets`, + method: 'GET', + headers: headerParameters, + query: queryParameters, +}, initOverrides); - return new runtime.JSONApiResponse(response, (jsonValue) => jsonValue.map(PresetFromJSON)); + return new runtime.JSONApiResponse(response, (jsonValue) => jsonValue.map(PresetFromJSON)); } - /** +/** * エンジンが保持しているプリセットの設定を返します * Get Presets */ - async getPresetsPresetsGet(initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { - const response = await this.getPresetsPresetsGetRaw(initOverrides); - return await response.value(); - } +async getPresetsPresetsGet(initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { +const response = await this.getPresetsPresetsGetRaw(initOverrides); +return await response.value(); +} - /** +/** * ユーザー辞書に登録されている単語の一覧を返します。 単語の表層形(surface)は正規化済みの物を返します。 * Get User Dict Words */ - async getUserDictWordsUserDictGetRaw(initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { - const queryParameters: any = {}; +async getUserDictWordsUserDictGetRaw(initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { +const queryParameters: any = {}; - const headerParameters: runtime.HTTPHeaders = {}; +const headerParameters: runtime.HTTPHeaders = {}; - const response = await this.request({ - path: `/user_dict`, - method: 'GET', - headers: headerParameters, - query: queryParameters, - }, initOverrides); +const response = await this.request({ + path: `/user_dict`, + method: 'GET', + headers: headerParameters, + query: queryParameters, +}, initOverrides); - return new runtime.JSONApiResponse(response, (jsonValue) => runtime.mapValues(jsonValue, UserDictWordFromJSON)); + return new runtime.JSONApiResponse(response, (jsonValue) => runtime.mapValues(jsonValue, UserDictWordFromJSON)); } - /** +/** * ユーザー辞書に登録されている単語の一覧を返します。 単語の表層形(surface)は正規化済みの物を返します。 * Get User Dict Words */ - async getUserDictWordsUserDictGet(initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise<{ [key: string]: UserDictWord; }> { - const response = await this.getUserDictWordsUserDictGetRaw(initOverrides); - return await response.value(); - } +async getUserDictWordsUserDictGet(initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise<{ [key: string]: UserDictWord; }> { + const response = await this.getUserDictWordsUserDictGetRaw(initOverrides); + return await response.value(); +} - /** +/** * 他のユーザー辞書をインポートします。 * Import User Dict Words */ - async importUserDictWordsImportUserDictPostRaw(requestParameters: ImportUserDictWordsImportUserDictPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { - if (requestParameters.override === null || requestParameters.override === undefined) { - throw new runtime.RequiredError('override','Required parameter requestParameters.override was null or undefined when calling importUserDictWordsImportUserDictPost.'); - } +async importUserDictWordsImportUserDictPostRaw(requestParameters: ImportUserDictWordsImportUserDictPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { +if (requestParameters.override === null || requestParameters.override === undefined) { + throw new runtime.RequiredError('override','Required parameter requestParameters.override was null or undefined when calling importUserDictWordsImportUserDictPost.'); +} - if (requestParameters.requestBody === null || requestParameters.requestBody === undefined) { - throw new runtime.RequiredError('requestBody','Required parameter requestParameters.requestBody was null or undefined when calling importUserDictWordsImportUserDictPost.'); - } +if (requestParameters.requestBody === null || requestParameters.requestBody === undefined) { + throw new runtime.RequiredError('requestBody','Required parameter requestParameters.requestBody was null or undefined when calling importUserDictWordsImportUserDictPost.'); +} - const queryParameters: any = {}; +const queryParameters: any = {}; - if (requestParameters.override !== undefined) { - queryParameters['override'] = requestParameters.override; - } +if (requestParameters.override !== undefined) { + queryParameters['override'] = requestParameters.override; +} - const headerParameters: runtime.HTTPHeaders = {}; +const headerParameters: runtime.HTTPHeaders = {}; - headerParameters['Content-Type'] = 'application/json'; +headerParameters['Content-Type'] = 'application/json'; - const response = await this.request({ - path: `/import_user_dict`, - method: 'POST', - headers: headerParameters, - query: queryParameters, - body: requestParameters.requestBody, - }, initOverrides); +const response = await this.request({ + path: `/import_user_dict`, + method: 'POST', + headers: headerParameters, + query: queryParameters, + body: requestParameters.requestBody, +}, initOverrides); - return new runtime.VoidApiResponse(response); + return new runtime.VoidApiResponse(response); } - /** +/** * 他のユーザー辞書をインポートします。 * Import User Dict Words */ - async importUserDictWordsImportUserDictPost(requestParameters: ImportUserDictWordsImportUserDictPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { - await this.importUserDictWordsImportUserDictPostRaw(requestParameters, initOverrides); - } +async importUserDictWordsImportUserDictPost(requestParameters: ImportUserDictWordsImportUserDictPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { + await this.importUserDictWordsImportUserDictPostRaw(requestParameters, initOverrides); +} - /** +/** * 指定されたスタイルを初期化します。 実行しなくても他のAPIは使用できますが、初回実行時に時間がかかることがあります。 * Initialize Speaker */ - async initializeSpeakerInitializeSpeakerPostRaw(requestParameters: InitializeSpeakerInitializeSpeakerPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { - if (requestParameters.speaker === null || requestParameters.speaker === undefined) { - throw new runtime.RequiredError('speaker','Required parameter requestParameters.speaker was null or undefined when calling initializeSpeakerInitializeSpeakerPost.'); - } +async initializeSpeakerInitializeSpeakerPostRaw(requestParameters: InitializeSpeakerInitializeSpeakerPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { +if (requestParameters.speaker === null || requestParameters.speaker === undefined) { + throw new runtime.RequiredError('speaker','Required parameter requestParameters.speaker was null or undefined when calling initializeSpeakerInitializeSpeakerPost.'); +} - const queryParameters: any = {}; +const queryParameters: any = {}; - if (requestParameters.speaker !== undefined) { - queryParameters['speaker'] = requestParameters.speaker; - } +if (requestParameters.speaker !== undefined) { + queryParameters['speaker'] = requestParameters.speaker; +} - if (requestParameters.skipReinit !== undefined) { - queryParameters['skip_reinit'] = requestParameters.skipReinit; - } +if (requestParameters.skipReinit !== undefined) { + queryParameters['skip_reinit'] = requestParameters.skipReinit; +} - if (requestParameters.coreVersion !== undefined) { - queryParameters['core_version'] = requestParameters.coreVersion; - } +if (requestParameters.coreVersion !== undefined) { + queryParameters['core_version'] = requestParameters.coreVersion; +} - const headerParameters: runtime.HTTPHeaders = {}; +const headerParameters: runtime.HTTPHeaders = {}; - const response = await this.request({ - path: `/initialize_speaker`, - method: 'POST', - headers: headerParameters, - query: queryParameters, - }, initOverrides); +const response = await this.request({ + path: `/initialize_speaker`, + method: 'POST', + headers: headerParameters, + query: queryParameters, +}, initOverrides); - return new runtime.VoidApiResponse(response); + return new runtime.VoidApiResponse(response); } - /** +/** * 指定されたスタイルを初期化します。 実行しなくても他のAPIは使用できますが、初回実行時に時間がかかることがあります。 * Initialize Speaker */ - async initializeSpeakerInitializeSpeakerPost(requestParameters: InitializeSpeakerInitializeSpeakerPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { - await this.initializeSpeakerInitializeSpeakerPostRaw(requestParameters, initOverrides); - } +async initializeSpeakerInitializeSpeakerPost(requestParameters: InitializeSpeakerInitializeSpeakerPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { + await this.initializeSpeakerInitializeSpeakerPostRaw(requestParameters, initOverrides); +} - /** +/** * 音声ライブラリをインストールします。 音声ライブラリのZIPファイルをリクエストボディとして送信してください。 * Install Library */ - async installLibraryInstallLibraryLibraryUuidPostRaw(requestParameters: InstallLibraryInstallLibraryLibraryUuidPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { - if (requestParameters.libraryUuid === null || requestParameters.libraryUuid === undefined) { - throw new runtime.RequiredError('libraryUuid','Required parameter requestParameters.libraryUuid was null or undefined when calling installLibraryInstallLibraryLibraryUuidPost.'); - } +async installLibraryInstallLibraryLibraryUuidPostRaw(requestParameters: InstallLibraryInstallLibraryLibraryUuidPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { +if (requestParameters.libraryUuid === null || requestParameters.libraryUuid === undefined) { + throw new runtime.RequiredError('libraryUuid','Required parameter requestParameters.libraryUuid was null or undefined when calling installLibraryInstallLibraryLibraryUuidPost.'); +} - const queryParameters: any = {}; +const queryParameters: any = {}; - const headerParameters: runtime.HTTPHeaders = {}; +const headerParameters: runtime.HTTPHeaders = {}; - const response = await this.request({ - path: `/install_library/{library_uuid}`.replace(`{${"library_uuid"}}`, encodeURIComponent(String(requestParameters.libraryUuid))), - method: 'POST', - headers: headerParameters, - query: queryParameters, - }, initOverrides); +const response = await this.request({ + path: `/install_library/{library_uuid}`.replace(`{${"library_uuid"}}`, encodeURIComponent(String(requestParameters.libraryUuid))), + method: 'POST', + headers: headerParameters, + query: queryParameters, +}, initOverrides); - return new runtime.VoidApiResponse(response); + return new runtime.VoidApiResponse(response); } - /** +/** * 音声ライブラリをインストールします。 音声ライブラリのZIPファイルをリクエストボディとして送信してください。 * Install Library */ - async installLibraryInstallLibraryLibraryUuidPost(requestParameters: InstallLibraryInstallLibraryLibraryUuidPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { - await this.installLibraryInstallLibraryLibraryUuidPostRaw(requestParameters, initOverrides); - } +async installLibraryInstallLibraryLibraryUuidPost(requestParameters: InstallLibraryInstallLibraryLibraryUuidPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { + await this.installLibraryInstallLibraryLibraryUuidPostRaw(requestParameters, initOverrides); +} - /** +/** * インストールした音声ライブラリの情報を返します。 * Installed Libraries */ - async installedLibrariesInstalledLibrariesGetRaw(initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { - const queryParameters: any = {}; +async installedLibrariesInstalledLibrariesGetRaw(initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { +const queryParameters: any = {}; - const headerParameters: runtime.HTTPHeaders = {}; +const headerParameters: runtime.HTTPHeaders = {}; - const response = await this.request({ - path: `/installed_libraries`, - method: 'GET', - headers: headerParameters, - query: queryParameters, - }, initOverrides); +const response = await this.request({ + path: `/installed_libraries`, + method: 'GET', + headers: headerParameters, + query: queryParameters, +}, initOverrides); - return new runtime.JSONApiResponse(response, (jsonValue) => runtime.mapValues(jsonValue, InstalledLibraryInfoFromJSON)); + return new runtime.JSONApiResponse(response, (jsonValue) => runtime.mapValues(jsonValue, InstalledLibraryInfoFromJSON)); } - /** +/** * インストールした音声ライブラリの情報を返します。 * Installed Libraries */ - async installedLibrariesInstalledLibrariesGet(initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise<{ [key: string]: InstalledLibraryInfo; }> { - const response = await this.installedLibrariesInstalledLibrariesGetRaw(initOverrides); - return await response.value(); - } +async installedLibrariesInstalledLibrariesGet(initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise<{ [key: string]: InstalledLibraryInfo; }> { + const response = await this.installedLibrariesInstalledLibrariesGetRaw(initOverrides); + return await response.value(); +} - /** +/** * 指定されたスタイルが初期化されているかどうかを返します。 * Is Initialized Speaker */ - async isInitializedSpeakerIsInitializedSpeakerGetRaw(requestParameters: IsInitializedSpeakerIsInitializedSpeakerGetRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { - if (requestParameters.speaker === null || requestParameters.speaker === undefined) { - throw new runtime.RequiredError('speaker','Required parameter requestParameters.speaker was null or undefined when calling isInitializedSpeakerIsInitializedSpeakerGet.'); - } +async isInitializedSpeakerIsInitializedSpeakerGetRaw(requestParameters: IsInitializedSpeakerIsInitializedSpeakerGetRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { +if (requestParameters.speaker === null || requestParameters.speaker === undefined) { + throw new runtime.RequiredError('speaker','Required parameter requestParameters.speaker was null or undefined when calling isInitializedSpeakerIsInitializedSpeakerGet.'); +} - const queryParameters: any = {}; +const queryParameters: any = {}; - if (requestParameters.speaker !== undefined) { - queryParameters['speaker'] = requestParameters.speaker; - } +if (requestParameters.speaker !== undefined) { + queryParameters['speaker'] = requestParameters.speaker; +} - if (requestParameters.coreVersion !== undefined) { - queryParameters['core_version'] = requestParameters.coreVersion; - } +if (requestParameters.coreVersion !== undefined) { + queryParameters['core_version'] = requestParameters.coreVersion; +} - const headerParameters: runtime.HTTPHeaders = {}; +const headerParameters: runtime.HTTPHeaders = {}; - const response = await this.request({ - path: `/is_initialized_speaker`, - method: 'GET', - headers: headerParameters, - query: queryParameters, - }, initOverrides); +const response = await this.request({ + path: `/is_initialized_speaker`, + method: 'GET', + headers: headerParameters, + query: queryParameters, +}, initOverrides); - if (this.isJsonMime(response.headers.get('content-type'))) { - return new runtime.JSONApiResponse(response); - } else { - return new runtime.TextApiResponse(response) as any; - } - } +if (this.isJsonMime(response.headers.get('content-type'))) { + return new runtime.JSONApiResponse(response); +} else { + return new runtime.TextApiResponse(response) as any; +} +} - /** +/** * 指定されたスタイルが初期化されているかどうかを返します。 * Is Initialized Speaker */ - async isInitializedSpeakerIsInitializedSpeakerGet(requestParameters: IsInitializedSpeakerIsInitializedSpeakerGetRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { - const response = await this.isInitializedSpeakerIsInitializedSpeakerGetRaw(requestParameters, initOverrides); - return await response.value(); - } +async isInitializedSpeakerIsInitializedSpeakerGet(requestParameters: IsInitializedSpeakerIsInitializedSpeakerGetRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { +const response = await this.isInitializedSpeakerIsInitializedSpeakerGetRaw(requestParameters, initOverrides); +return await response.value(); +} - /** +/** * アクセント句から音高・音素長を得る */ - async moraDataMoraDataPostRaw(requestParameters: MoraDataMoraDataPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>> { - if (requestParameters.speaker === null || requestParameters.speaker === undefined) { - throw new runtime.RequiredError('speaker','Required parameter requestParameters.speaker was null or undefined when calling moraDataMoraDataPost.'); - } +async moraDataMoraDataPostRaw(requestParameters: MoraDataMoraDataPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>> { +if (requestParameters.speaker === null || requestParameters.speaker === undefined) { + throw new runtime.RequiredError('speaker','Required parameter requestParameters.speaker was null or undefined when calling moraDataMoraDataPost.'); +} - if (requestParameters.accentPhrase === null || requestParameters.accentPhrase === undefined) { - throw new runtime.RequiredError('accentPhrase','Required parameter requestParameters.accentPhrase was null or undefined when calling moraDataMoraDataPost.'); - } +if (requestParameters.accentPhrase === null || requestParameters.accentPhrase === undefined) { + throw new runtime.RequiredError('accentPhrase','Required parameter requestParameters.accentPhrase was null or undefined when calling moraDataMoraDataPost.'); +} - const queryParameters: any = {}; +const queryParameters: any = {}; - if (requestParameters.speaker !== undefined) { - queryParameters['speaker'] = requestParameters.speaker; - } +if (requestParameters.speaker !== undefined) { + queryParameters['speaker'] = requestParameters.speaker; +} - if (requestParameters.coreVersion !== undefined) { - queryParameters['core_version'] = requestParameters.coreVersion; - } +if (requestParameters.coreVersion !== undefined) { + queryParameters['core_version'] = requestParameters.coreVersion; +} - const headerParameters: runtime.HTTPHeaders = {}; +const headerParameters: runtime.HTTPHeaders = {}; - headerParameters['Content-Type'] = 'application/json'; +headerParameters['Content-Type'] = 'application/json'; - const response = await this.request({ - path: `/mora_data`, - method: 'POST', - headers: headerParameters, - query: queryParameters, - body: requestParameters.accentPhrase.map(AccentPhraseToJSON), - }, initOverrides); +const response = await this.request({ + path: `/mora_data`, + method: 'POST', + headers: headerParameters, + query: queryParameters, + body: requestParameters.accentPhrase.map(AccentPhraseToJSON), +}, initOverrides); - return new runtime.JSONApiResponse(response, (jsonValue) => jsonValue.map(AccentPhraseFromJSON)); + return new runtime.JSONApiResponse(response, (jsonValue) => jsonValue.map(AccentPhraseFromJSON)); } - /** +/** * アクセント句から音高・音素長を得る */ - async moraDataMoraDataPost(requestParameters: MoraDataMoraDataPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { - const response = await this.moraDataMoraDataPostRaw(requestParameters, initOverrides); - return await response.value(); - } +async moraDataMoraDataPost(requestParameters: MoraDataMoraDataPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { +const response = await this.moraDataMoraDataPostRaw(requestParameters, initOverrides); +return await response.value(); +} - /** +/** * アクセント句から音素長を得る */ - async moraLengthMoraLengthPostRaw(requestParameters: MoraLengthMoraLengthPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>> { - if (requestParameters.speaker === null || requestParameters.speaker === undefined) { - throw new runtime.RequiredError('speaker','Required parameter requestParameters.speaker was null or undefined when calling moraLengthMoraLengthPost.'); - } +async moraLengthMoraLengthPostRaw(requestParameters: MoraLengthMoraLengthPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>> { +if (requestParameters.speaker === null || requestParameters.speaker === undefined) { + throw new runtime.RequiredError('speaker','Required parameter requestParameters.speaker was null or undefined when calling moraLengthMoraLengthPost.'); +} - if (requestParameters.accentPhrase === null || requestParameters.accentPhrase === undefined) { - throw new runtime.RequiredError('accentPhrase','Required parameter requestParameters.accentPhrase was null or undefined when calling moraLengthMoraLengthPost.'); - } +if (requestParameters.accentPhrase === null || requestParameters.accentPhrase === undefined) { + throw new runtime.RequiredError('accentPhrase','Required parameter requestParameters.accentPhrase was null or undefined when calling moraLengthMoraLengthPost.'); +} - const queryParameters: any = {}; +const queryParameters: any = {}; - if (requestParameters.speaker !== undefined) { - queryParameters['speaker'] = requestParameters.speaker; - } +if (requestParameters.speaker !== undefined) { + queryParameters['speaker'] = requestParameters.speaker; +} - if (requestParameters.coreVersion !== undefined) { - queryParameters['core_version'] = requestParameters.coreVersion; - } +if (requestParameters.coreVersion !== undefined) { + queryParameters['core_version'] = requestParameters.coreVersion; +} - const headerParameters: runtime.HTTPHeaders = {}; +const headerParameters: runtime.HTTPHeaders = {}; - headerParameters['Content-Type'] = 'application/json'; +headerParameters['Content-Type'] = 'application/json'; - const response = await this.request({ - path: `/mora_length`, - method: 'POST', - headers: headerParameters, - query: queryParameters, - body: requestParameters.accentPhrase.map(AccentPhraseToJSON), - }, initOverrides); +const response = await this.request({ + path: `/mora_length`, + method: 'POST', + headers: headerParameters, + query: queryParameters, + body: requestParameters.accentPhrase.map(AccentPhraseToJSON), +}, initOverrides); - return new runtime.JSONApiResponse(response, (jsonValue) => jsonValue.map(AccentPhraseFromJSON)); + return new runtime.JSONApiResponse(response, (jsonValue) => jsonValue.map(AccentPhraseFromJSON)); } - /** +/** * アクセント句から音素長を得る */ - async moraLengthMoraLengthPost(requestParameters: MoraLengthMoraLengthPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { - const response = await this.moraLengthMoraLengthPostRaw(requestParameters, initOverrides); - return await response.value(); - } +async moraLengthMoraLengthPost(requestParameters: MoraLengthMoraLengthPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { +const response = await this.moraLengthMoraLengthPostRaw(requestParameters, initOverrides); +return await response.value(); +} - /** +/** * アクセント句から音高を得る */ - async moraPitchMoraPitchPostRaw(requestParameters: MoraPitchMoraPitchPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>> { - if (requestParameters.speaker === null || requestParameters.speaker === undefined) { - throw new runtime.RequiredError('speaker','Required parameter requestParameters.speaker was null or undefined when calling moraPitchMoraPitchPost.'); - } +async moraPitchMoraPitchPostRaw(requestParameters: MoraPitchMoraPitchPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>> { +if (requestParameters.speaker === null || requestParameters.speaker === undefined) { + throw new runtime.RequiredError('speaker','Required parameter requestParameters.speaker was null or undefined when calling moraPitchMoraPitchPost.'); +} - if (requestParameters.accentPhrase === null || requestParameters.accentPhrase === undefined) { - throw new runtime.RequiredError('accentPhrase','Required parameter requestParameters.accentPhrase was null or undefined when calling moraPitchMoraPitchPost.'); - } +if (requestParameters.accentPhrase === null || requestParameters.accentPhrase === undefined) { + throw new runtime.RequiredError('accentPhrase','Required parameter requestParameters.accentPhrase was null or undefined when calling moraPitchMoraPitchPost.'); +} - const queryParameters: any = {}; +const queryParameters: any = {}; - if (requestParameters.speaker !== undefined) { - queryParameters['speaker'] = requestParameters.speaker; - } +if (requestParameters.speaker !== undefined) { + queryParameters['speaker'] = requestParameters.speaker; +} - if (requestParameters.coreVersion !== undefined) { - queryParameters['core_version'] = requestParameters.coreVersion; - } +if (requestParameters.coreVersion !== undefined) { + queryParameters['core_version'] = requestParameters.coreVersion; +} - const headerParameters: runtime.HTTPHeaders = {}; +const headerParameters: runtime.HTTPHeaders = {}; - headerParameters['Content-Type'] = 'application/json'; +headerParameters['Content-Type'] = 'application/json'; - const response = await this.request({ - path: `/mora_pitch`, - method: 'POST', - headers: headerParameters, - query: queryParameters, - body: requestParameters.accentPhrase.map(AccentPhraseToJSON), - }, initOverrides); +const response = await this.request({ + path: `/mora_pitch`, + method: 'POST', + headers: headerParameters, + query: queryParameters, + body: requestParameters.accentPhrase.map(AccentPhraseToJSON), +}, initOverrides); - return new runtime.JSONApiResponse(response, (jsonValue) => jsonValue.map(AccentPhraseFromJSON)); + return new runtime.JSONApiResponse(response, (jsonValue) => jsonValue.map(AccentPhraseFromJSON)); } - /** +/** * アクセント句から音高を得る */ - async moraPitchMoraPitchPost(requestParameters: MoraPitchMoraPitchPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { - const response = await this.moraPitchMoraPitchPostRaw(requestParameters, initOverrides); - return await response.value(); - } +async moraPitchMoraPitchPost(requestParameters: MoraPitchMoraPitchPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { +const response = await this.moraPitchMoraPitchPostRaw(requestParameters, initOverrides); +return await response.value(); +} - /** +/** * 指定されたベーススタイルに対してエンジン内の各話者がモーフィング機能を利用可能か返します。 モーフィングの許可/禁止は`/speakers`の`speaker.supported_features.synthesis_morphing`に記載されています。 プロパティが存在しない場合は、モーフィングが許可されているとみなします。 返り値のスタイルIDはstring型なので注意。 * 指定したスタイルに対してエンジン内の話者がモーフィングが可能か判定する */ - async morphableTargetsMorphableTargetsPostRaw(requestParameters: MorphableTargetsMorphableTargetsPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>> { - if (requestParameters.requestBody === null || requestParameters.requestBody === undefined) { - throw new runtime.RequiredError('requestBody','Required parameter requestParameters.requestBody was null or undefined when calling morphableTargetsMorphableTargetsPost.'); - } +async morphableTargetsMorphableTargetsPostRaw(requestParameters: MorphableTargetsMorphableTargetsPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>> { +if (requestParameters.requestBody === null || requestParameters.requestBody === undefined) { + throw new runtime.RequiredError('requestBody','Required parameter requestParameters.requestBody was null or undefined when calling morphableTargetsMorphableTargetsPost.'); +} - const queryParameters: any = {}; +const queryParameters: any = {}; - if (requestParameters.coreVersion !== undefined) { - queryParameters['core_version'] = requestParameters.coreVersion; - } +if (requestParameters.coreVersion !== undefined) { + queryParameters['core_version'] = requestParameters.coreVersion; +} - const headerParameters: runtime.HTTPHeaders = {}; +const headerParameters: runtime.HTTPHeaders = {}; - headerParameters['Content-Type'] = 'application/json'; + headerParameters['Content-Type'] = 'application/json'; - const response = await this.request({ - path: `/morphable_targets`, - method: 'POST', - headers: headerParameters, - query: queryParameters, - body: requestParameters.requestBody, - }, initOverrides); +const response = await this.request({ + path: `/morphable_targets`, + method: 'POST', + headers: headerParameters, + query: queryParameters, + body: requestParameters.requestBody, +}, initOverrides); - return new runtime.JSONApiResponse(response); + return new runtime.JSONApiResponse(response); } - /** +/** * 指定されたベーススタイルに対してエンジン内の各話者がモーフィング機能を利用可能か返します。 モーフィングの許可/禁止は`/speakers`の`speaker.supported_features.synthesis_morphing`に記載されています。 プロパティが存在しない場合は、モーフィングが許可されているとみなします。 返り値のスタイルIDはstring型なので注意。 * 指定したスタイルに対してエンジン内の話者がモーフィングが可能か判定する */ - async morphableTargetsMorphableTargetsPost(requestParameters: MorphableTargetsMorphableTargetsPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { - const response = await this.morphableTargetsMorphableTargetsPostRaw(requestParameters, initOverrides); - return await response.value(); - } +async morphableTargetsMorphableTargetsPost(requestParameters: MorphableTargetsMorphableTargetsPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + const response = await this.morphableTargetsMorphableTargetsPostRaw(requestParameters, initOverrides); + return await response.value(); +} - /** +/** * 複数まとめて音声合成する */ - async multiSynthesisMultiSynthesisPostRaw(requestParameters: MultiSynthesisMultiSynthesisPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { - if (requestParameters.speaker === null || requestParameters.speaker === undefined) { - throw new runtime.RequiredError('speaker','Required parameter requestParameters.speaker was null or undefined when calling multiSynthesisMultiSynthesisPost.'); - } +async multiSynthesisMultiSynthesisPostRaw(requestParameters: MultiSynthesisMultiSynthesisPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { +if (requestParameters.speaker === null || requestParameters.speaker === undefined) { + throw new runtime.RequiredError('speaker','Required parameter requestParameters.speaker was null or undefined when calling multiSynthesisMultiSynthesisPost.'); +} - if (requestParameters.audioQuery === null || requestParameters.audioQuery === undefined) { - throw new runtime.RequiredError('audioQuery','Required parameter requestParameters.audioQuery was null or undefined when calling multiSynthesisMultiSynthesisPost.'); - } +if (requestParameters.audioQuery === null || requestParameters.audioQuery === undefined) { + throw new runtime.RequiredError('audioQuery','Required parameter requestParameters.audioQuery was null or undefined when calling multiSynthesisMultiSynthesisPost.'); +} - const queryParameters: any = {}; +const queryParameters: any = {}; - if (requestParameters.speaker !== undefined) { - queryParameters['speaker'] = requestParameters.speaker; - } +if (requestParameters.speaker !== undefined) { + queryParameters['speaker'] = requestParameters.speaker; +} - if (requestParameters.coreVersion !== undefined) { - queryParameters['core_version'] = requestParameters.coreVersion; - } +if (requestParameters.coreVersion !== undefined) { + queryParameters['core_version'] = requestParameters.coreVersion; +} - const headerParameters: runtime.HTTPHeaders = {}; +const headerParameters: runtime.HTTPHeaders = {}; - headerParameters['Content-Type'] = 'application/json'; +headerParameters['Content-Type'] = 'application/json'; - const response = await this.request({ - path: `/multi_synthesis`, - method: 'POST', - headers: headerParameters, - query: queryParameters, - body: requestParameters.audioQuery.map(AudioQueryToJSON), - }, initOverrides); +const response = await this.request({ + path: `/multi_synthesis`, + method: 'POST', + headers: headerParameters, + query: queryParameters, + body: requestParameters.audioQuery.map(AudioQueryToJSON), +}, initOverrides); - return new runtime.BlobApiResponse(response); + return new runtime.BlobApiResponse(response); } - /** +/** * 複数まとめて音声合成する */ - async multiSynthesisMultiSynthesisPost(requestParameters: MultiSynthesisMultiSynthesisPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { - const response = await this.multiSynthesisMultiSynthesisPostRaw(requestParameters, initOverrides); - return await response.value(); - } +async multiSynthesisMultiSynthesisPost(requestParameters: MultiSynthesisMultiSynthesisPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { +const response = await this.multiSynthesisMultiSynthesisPostRaw(requestParameters, initOverrides); +return await response.value(); +} - /** +/** * ユーザー辞書に登録されている言葉を更新します。 * Rewrite User Dict Word */ - async rewriteUserDictWordUserDictWordWordUuidPutRaw(requestParameters: RewriteUserDictWordUserDictWordWordUuidPutRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { - if (requestParameters.wordUuid === null || requestParameters.wordUuid === undefined) { - throw new runtime.RequiredError('wordUuid','Required parameter requestParameters.wordUuid was null or undefined when calling rewriteUserDictWordUserDictWordWordUuidPut.'); - } +async rewriteUserDictWordUserDictWordWordUuidPutRaw(requestParameters: RewriteUserDictWordUserDictWordWordUuidPutRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { +if (requestParameters.wordUuid === null || requestParameters.wordUuid === undefined) { + throw new runtime.RequiredError('wordUuid','Required parameter requestParameters.wordUuid was null or undefined when calling rewriteUserDictWordUserDictWordWordUuidPut.'); +} - if (requestParameters.surface === null || requestParameters.surface === undefined) { - throw new runtime.RequiredError('surface','Required parameter requestParameters.surface was null or undefined when calling rewriteUserDictWordUserDictWordWordUuidPut.'); - } +if (requestParameters.surface === null || requestParameters.surface === undefined) { + throw new runtime.RequiredError('surface','Required parameter requestParameters.surface was null or undefined when calling rewriteUserDictWordUserDictWordWordUuidPut.'); +} - if (requestParameters.pronunciation === null || requestParameters.pronunciation === undefined) { - throw new runtime.RequiredError('pronunciation','Required parameter requestParameters.pronunciation was null or undefined when calling rewriteUserDictWordUserDictWordWordUuidPut.'); - } +if (requestParameters.pronunciation === null || requestParameters.pronunciation === undefined) { + throw new runtime.RequiredError('pronunciation','Required parameter requestParameters.pronunciation was null or undefined when calling rewriteUserDictWordUserDictWordWordUuidPut.'); +} - if (requestParameters.accentType === null || requestParameters.accentType === undefined) { - throw new runtime.RequiredError('accentType','Required parameter requestParameters.accentType was null or undefined when calling rewriteUserDictWordUserDictWordWordUuidPut.'); - } +if (requestParameters.accentType === null || requestParameters.accentType === undefined) { + throw new runtime.RequiredError('accentType','Required parameter requestParameters.accentType was null or undefined when calling rewriteUserDictWordUserDictWordWordUuidPut.'); +} - const queryParameters: any = {}; +const queryParameters: any = {}; - if (requestParameters.surface !== undefined) { - queryParameters['surface'] = requestParameters.surface; - } +if (requestParameters.surface !== undefined) { + queryParameters['surface'] = requestParameters.surface; +} - if (requestParameters.pronunciation !== undefined) { - queryParameters['pronunciation'] = requestParameters.pronunciation; - } +if (requestParameters.pronunciation !== undefined) { + queryParameters['pronunciation'] = requestParameters.pronunciation; +} - if (requestParameters.accentType !== undefined) { - queryParameters['accent_type'] = requestParameters.accentType; - } +if (requestParameters.accentType !== undefined) { + queryParameters['accent_type'] = requestParameters.accentType; +} - if (requestParameters.wordType !== undefined) { - queryParameters['word_type'] = requestParameters.wordType; - } +if (requestParameters.wordType !== undefined) { + queryParameters['word_type'] = requestParameters.wordType; +} - if (requestParameters.priority !== undefined) { - queryParameters['priority'] = requestParameters.priority; - } +if (requestParameters.priority !== undefined) { + queryParameters['priority'] = requestParameters.priority; +} - const headerParameters: runtime.HTTPHeaders = {}; +const headerParameters: runtime.HTTPHeaders = {}; - const response = await this.request({ - path: `/user_dict_word/{word_uuid}`.replace(`{${"word_uuid"}}`, encodeURIComponent(String(requestParameters.wordUuid))), - method: 'PUT', - headers: headerParameters, - query: queryParameters, - }, initOverrides); +const response = await this.request({ + path: `/user_dict_word/{word_uuid}`.replace(`{${"word_uuid"}}`, encodeURIComponent(String(requestParameters.wordUuid))), + method: 'PUT', + headers: headerParameters, + query: queryParameters, +}, initOverrides); - return new runtime.VoidApiResponse(response); + return new runtime.VoidApiResponse(response); } - /** +/** * ユーザー辞書に登録されている言葉を更新します。 * Rewrite User Dict Word */ - async rewriteUserDictWordUserDictWordWordUuidPut(requestParameters: RewriteUserDictWordUserDictWordWordUuidPutRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { - await this.rewriteUserDictWordUserDictWordWordUuidPutRaw(requestParameters, initOverrides); - } +async rewriteUserDictWordUserDictWordWordUuidPut(requestParameters: RewriteUserDictWordUserDictWordWordUuidPutRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { + await this.rewriteUserDictWordUserDictWordWordUuidPutRaw(requestParameters, initOverrides); +} - /** +/** * 設定ページを返します。 * Setting Get */ - async settingGetSettingGetRaw(initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { - const queryParameters: any = {}; +async settingGetSettingGetRaw(initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { +const queryParameters: any = {}; - const headerParameters: runtime.HTTPHeaders = {}; +const headerParameters: runtime.HTTPHeaders = {}; - const response = await this.request({ - path: `/setting`, - method: 'GET', - headers: headerParameters, - query: queryParameters, - }, initOverrides); +const response = await this.request({ + path: `/setting`, + method: 'GET', + headers: headerParameters, + query: queryParameters, +}, initOverrides); - return new runtime.VoidApiResponse(response); + return new runtime.VoidApiResponse(response); } - /** +/** * 設定ページを返します。 * Setting Get */ - async settingGetSettingGet(initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { - await this.settingGetSettingGetRaw(initOverrides); - } +async settingGetSettingGet(initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { + await this.settingGetSettingGetRaw(initOverrides); +} - /** +/** * 設定を更新します。 * Setting Post */ - async settingPostSettingPostRaw(requestParameters: SettingPostSettingPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { - if (requestParameters.corsPolicyMode === null || requestParameters.corsPolicyMode === undefined) { - throw new runtime.RequiredError('corsPolicyMode','Required parameter requestParameters.corsPolicyMode was null or undefined when calling settingPostSettingPost.'); - } - - const queryParameters: any = {}; - - const headerParameters: runtime.HTTPHeaders = {}; - - const consumes: runtime.Consume[] = [ - { contentType: 'application/x-www-form-urlencoded' }, - ]; - // @ts-ignore: canConsumeForm may be unused - const canConsumeForm = runtime.canConsumeForm(consumes); - - let formParams: { append(param: string, value: any): any }; - let useForm = false; - if (useForm) { - formParams = new FormData(); - } else { - formParams = new URLSearchParams(); - } - - if (requestParameters.corsPolicyMode !== undefined) { - formParams.append('cors_policy_mode', new Blob([JSON.stringify(CorsPolicyModeToJSON(requestParameters.corsPolicyMode))], { type: "application/json", })); - } - - if (requestParameters.allowOrigin !== undefined) { - formParams.append('allow_origin', requestParameters.allowOrigin as any); - } - - const response = await this.request({ - path: `/setting`, - method: 'POST', - headers: headerParameters, - query: queryParameters, - body: formParams, - }, initOverrides); - - return new runtime.VoidApiResponse(response); +async settingPostSettingPostRaw(requestParameters: SettingPostSettingPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { +if (requestParameters.corsPolicyMode === null || requestParameters.corsPolicyMode === undefined) { + throw new runtime.RequiredError('corsPolicyMode','Required parameter requestParameters.corsPolicyMode was null or undefined when calling settingPostSettingPost.'); +} + +const queryParameters: any = {}; + +const headerParameters: runtime.HTTPHeaders = {}; + +const consumes: runtime.Consume[] = [ + { contentType: 'application/x-www-form-urlencoded' }, +]; +// @ts-ignore: canConsumeForm may be unused +const canConsumeForm = runtime.canConsumeForm(consumes); + +let formParams: { append(param: string, value: any): any }; +let useForm = false; +if (useForm) { + formParams = new FormData(); +} else { + formParams = new URLSearchParams(); +} + +if (requestParameters.corsPolicyMode !== undefined) { + formParams.append('cors_policy_mode', new Blob([JSON.stringify(CorsPolicyModeToJSON(requestParameters.corsPolicyMode))], { type: "application/json", })); +} + +if (requestParameters.allowOrigin !== undefined) { + formParams.append('allow_origin', requestParameters.allowOrigin as any); +} + +const response = await this.request({ + path: `/setting`, + method: 'POST', + headers: headerParameters, + query: queryParameters, + body: formParams, +}, initOverrides); + + return new runtime.VoidApiResponse(response); } - /** +/** * 設定を更新します。 * Setting Post */ - async settingPostSettingPost(requestParameters: SettingPostSettingPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { - await this.settingPostSettingPostRaw(requestParameters, initOverrides); - } +async settingPostSettingPost(requestParameters: SettingPostSettingPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { + await this.settingPostSettingPostRaw(requestParameters, initOverrides); +} - /** +/** * 歌唱音声合成用のクエリの初期値を得ます。ここで得られたクエリはそのまま歌唱音声合成に利用できます。各値の意味は`Schemas`を参照してください。 * 歌唱音声合成用のクエリを作成する */ - async singFrameAudioQuerySingFrameAudioQueryPostRaw(requestParameters: SingFrameAudioQuerySingFrameAudioQueryPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { - if (requestParameters.speaker === null || requestParameters.speaker === undefined) { - throw new runtime.RequiredError('speaker','Required parameter requestParameters.speaker was null or undefined when calling singFrameAudioQuerySingFrameAudioQueryPost.'); - } +async singFrameAudioQuerySingFrameAudioQueryPostRaw(requestParameters: SingFrameAudioQuerySingFrameAudioQueryPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { +if (requestParameters.speaker === null || requestParameters.speaker === undefined) { + throw new runtime.RequiredError('speaker','Required parameter requestParameters.speaker was null or undefined when calling singFrameAudioQuerySingFrameAudioQueryPost.'); +} - if (requestParameters.score === null || requestParameters.score === undefined) { - throw new runtime.RequiredError('score','Required parameter requestParameters.score was null or undefined when calling singFrameAudioQuerySingFrameAudioQueryPost.'); - } +if (requestParameters.score === null || requestParameters.score === undefined) { + throw new runtime.RequiredError('score','Required parameter requestParameters.score was null or undefined when calling singFrameAudioQuerySingFrameAudioQueryPost.'); +} - const queryParameters: any = {}; +const queryParameters: any = {}; - if (requestParameters.speaker !== undefined) { - queryParameters['speaker'] = requestParameters.speaker; - } +if (requestParameters.speaker !== undefined) { + queryParameters['speaker'] = requestParameters.speaker; +} - if (requestParameters.coreVersion !== undefined) { - queryParameters['core_version'] = requestParameters.coreVersion; - } +if (requestParameters.coreVersion !== undefined) { + queryParameters['core_version'] = requestParameters.coreVersion; +} - const headerParameters: runtime.HTTPHeaders = {}; +const headerParameters: runtime.HTTPHeaders = {}; - headerParameters['Content-Type'] = 'application/json'; +headerParameters['Content-Type'] = 'application/json'; - const response = await this.request({ - path: `/sing_frame_audio_query`, - method: 'POST', - headers: headerParameters, - query: queryParameters, - body: ScoreToJSON(requestParameters.score), - }, initOverrides); +const response = await this.request({ + path: `/sing_frame_audio_query`, + method: 'POST', + headers: headerParameters, + query: queryParameters, + body: ScoreToJSON(requestParameters.score), +}, initOverrides); - return new runtime.JSONApiResponse(response, (jsonValue) => FrameAudioQueryFromJSON(jsonValue)); + return new runtime.JSONApiResponse(response, (jsonValue) => FrameAudioQueryFromJSON(jsonValue)); } - /** +/** * 歌唱音声合成用のクエリの初期値を得ます。ここで得られたクエリはそのまま歌唱音声合成に利用できます。各値の意味は`Schemas`を参照してください。 * 歌唱音声合成用のクエリを作成する */ - async singFrameAudioQuerySingFrameAudioQueryPost(requestParameters: SingFrameAudioQuerySingFrameAudioQueryPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { - const response = await this.singFrameAudioQuerySingFrameAudioQueryPostRaw(requestParameters, initOverrides); - return await response.value(); - } +async singFrameAudioQuerySingFrameAudioQueryPost(requestParameters: SingFrameAudioQuerySingFrameAudioQueryPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { +const response = await this.singFrameAudioQuerySingFrameAudioQueryPostRaw(requestParameters, initOverrides); +return await response.value(); +} - /** +/** * スコア・歌唱音声合成用のクエリからフレームごとの音量を得る */ - async singFrameVolumeSingFrameVolumePostRaw(requestParameters: SingFrameVolumeSingFrameVolumePostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>> { - if (requestParameters.speaker === null || requestParameters.speaker === undefined) { - throw new runtime.RequiredError('speaker','Required parameter requestParameters.speaker was null or undefined when calling singFrameVolumeSingFrameVolumePost.'); - } +async singFrameVolumeSingFrameVolumePostRaw(requestParameters: SingFrameVolumeSingFrameVolumePostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>> { +if (requestParameters.speaker === null || requestParameters.speaker === undefined) { + throw new runtime.RequiredError('speaker','Required parameter requestParameters.speaker was null or undefined when calling singFrameVolumeSingFrameVolumePost.'); +} - if (requestParameters.bodySingFrameVolumeSingFrameVolumePost === null || requestParameters.bodySingFrameVolumeSingFrameVolumePost === undefined) { - throw new runtime.RequiredError('bodySingFrameVolumeSingFrameVolumePost','Required parameter requestParameters.bodySingFrameVolumeSingFrameVolumePost was null or undefined when calling singFrameVolumeSingFrameVolumePost.'); - } +if (requestParameters.bodySingFrameVolumeSingFrameVolumePost === null || requestParameters.bodySingFrameVolumeSingFrameVolumePost === undefined) { + throw new runtime.RequiredError('bodySingFrameVolumeSingFrameVolumePost','Required parameter requestParameters.bodySingFrameVolumeSingFrameVolumePost was null or undefined when calling singFrameVolumeSingFrameVolumePost.'); +} - const queryParameters: any = {}; +const queryParameters: any = {}; - if (requestParameters.speaker !== undefined) { - queryParameters['speaker'] = requestParameters.speaker; - } +if (requestParameters.speaker !== undefined) { + queryParameters['speaker'] = requestParameters.speaker; +} - if (requestParameters.coreVersion !== undefined) { - queryParameters['core_version'] = requestParameters.coreVersion; - } +if (requestParameters.coreVersion !== undefined) { + queryParameters['core_version'] = requestParameters.coreVersion; +} - const headerParameters: runtime.HTTPHeaders = {}; +const headerParameters: runtime.HTTPHeaders = {}; - headerParameters['Content-Type'] = 'application/json'; +headerParameters['Content-Type'] = 'application/json'; - const response = await this.request({ - path: `/sing_frame_volume`, - method: 'POST', - headers: headerParameters, - query: queryParameters, - body: BodySingFrameVolumeSingFrameVolumePostToJSON(requestParameters.bodySingFrameVolumeSingFrameVolumePost), - }, initOverrides); +const response = await this.request({ + path: `/sing_frame_volume`, + method: 'POST', + headers: headerParameters, + query: queryParameters, + body: BodySingFrameVolumeSingFrameVolumePostToJSON(requestParameters.bodySingFrameVolumeSingFrameVolumePost), +}, initOverrides); - return new runtime.JSONApiResponse(response); + return new runtime.JSONApiResponse(response); } - /** +/** * スコア・歌唱音声合成用のクエリからフレームごとの音量を得る */ - async singFrameVolumeSingFrameVolumePost(requestParameters: SingFrameVolumeSingFrameVolumePostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { - const response = await this.singFrameVolumeSingFrameVolumePostRaw(requestParameters, initOverrides); - return await response.value(); - } +async singFrameVolumeSingFrameVolumePost(requestParameters: SingFrameVolumeSingFrameVolumePostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { +const response = await this.singFrameVolumeSingFrameVolumePostRaw(requestParameters, initOverrides); +return await response.value(); +} - /** +/** * 指定されたspeaker_uuidに関する情報をjson形式で返します。 画像や音声はbase64エンコードされたものが返されます。 * Singer Info */ - async singerInfoSingerInfoGetRaw(requestParameters: SingerInfoSingerInfoGetRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { - if (requestParameters.speakerUuid === null || requestParameters.speakerUuid === undefined) { - throw new runtime.RequiredError('speakerUuid','Required parameter requestParameters.speakerUuid was null or undefined when calling singerInfoSingerInfoGet.'); - } +async singerInfoSingerInfoGetRaw(requestParameters: SingerInfoSingerInfoGetRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { +if (requestParameters.speakerUuid === null || requestParameters.speakerUuid === undefined) { + throw new runtime.RequiredError('speakerUuid','Required parameter requestParameters.speakerUuid was null or undefined when calling singerInfoSingerInfoGet.'); +} - const queryParameters: any = {}; +const queryParameters: any = {}; - if (requestParameters.speakerUuid !== undefined) { - queryParameters['speaker_uuid'] = requestParameters.speakerUuid; - } +if (requestParameters.speakerUuid !== undefined) { + queryParameters['speaker_uuid'] = requestParameters.speakerUuid; +} - if (requestParameters.coreVersion !== undefined) { - queryParameters['core_version'] = requestParameters.coreVersion; - } +if (requestParameters.coreVersion !== undefined) { + queryParameters['core_version'] = requestParameters.coreVersion; +} - const headerParameters: runtime.HTTPHeaders = {}; +const headerParameters: runtime.HTTPHeaders = {}; - const response = await this.request({ - path: `/singer_info`, - method: 'GET', - headers: headerParameters, - query: queryParameters, - }, initOverrides); +const response = await this.request({ + path: `/singer_info`, + method: 'GET', + headers: headerParameters, + query: queryParameters, +}, initOverrides); - return new runtime.JSONApiResponse(response, (jsonValue) => SpeakerInfoFromJSON(jsonValue)); + return new runtime.JSONApiResponse(response, (jsonValue) => SpeakerInfoFromJSON(jsonValue)); } - /** +/** * 指定されたspeaker_uuidに関する情報をjson形式で返します。 画像や音声はbase64エンコードされたものが返されます。 * Singer Info */ - async singerInfoSingerInfoGet(requestParameters: SingerInfoSingerInfoGetRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { - const response = await this.singerInfoSingerInfoGetRaw(requestParameters, initOverrides); - return await response.value(); - } +async singerInfoSingerInfoGet(requestParameters: SingerInfoSingerInfoGetRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { +const response = await this.singerInfoSingerInfoGetRaw(requestParameters, initOverrides); +return await response.value(); +} - /** +/** * Singers */ - async singersSingersGetRaw(requestParameters: SingersSingersGetRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>> { - const queryParameters: any = {}; +async singersSingersGetRaw(requestParameters: SingersSingersGetRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>> { +const queryParameters: any = {}; - if (requestParameters.coreVersion !== undefined) { - queryParameters['core_version'] = requestParameters.coreVersion; - } +if (requestParameters.coreVersion !== undefined) { + queryParameters['core_version'] = requestParameters.coreVersion; +} - const headerParameters: runtime.HTTPHeaders = {}; +const headerParameters: runtime.HTTPHeaders = {}; - const response = await this.request({ - path: `/singers`, - method: 'GET', - headers: headerParameters, - query: queryParameters, - }, initOverrides); +const response = await this.request({ + path: `/singers`, + method: 'GET', + headers: headerParameters, + query: queryParameters, +}, initOverrides); - return new runtime.JSONApiResponse(response, (jsonValue) => jsonValue.map(SpeakerFromJSON)); + return new runtime.JSONApiResponse(response, (jsonValue) => jsonValue.map(SpeakerFromJSON)); } - /** +/** * Singers */ - async singersSingersGet(requestParameters: SingersSingersGetRequest = {}, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { - const response = await this.singersSingersGetRaw(requestParameters, initOverrides); - return await response.value(); - } +async singersSingersGet(requestParameters: SingersSingersGetRequest = {}, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { +const response = await this.singersSingersGetRaw(requestParameters, initOverrides); +return await response.value(); +} - /** +/** * 指定されたspeaker_uuidに関する情報をjson形式で返します。 画像や音声はbase64エンコードされたものが返されます。 * Speaker Info */ - async speakerInfoSpeakerInfoGetRaw(requestParameters: SpeakerInfoSpeakerInfoGetRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { - if (requestParameters.speakerUuid === null || requestParameters.speakerUuid === undefined) { - throw new runtime.RequiredError('speakerUuid','Required parameter requestParameters.speakerUuid was null or undefined when calling speakerInfoSpeakerInfoGet.'); - } +async speakerInfoSpeakerInfoGetRaw(requestParameters: SpeakerInfoSpeakerInfoGetRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { +if (requestParameters.speakerUuid === null || requestParameters.speakerUuid === undefined) { + throw new runtime.RequiredError('speakerUuid','Required parameter requestParameters.speakerUuid was null or undefined when calling speakerInfoSpeakerInfoGet.'); +} - const queryParameters: any = {}; +const queryParameters: any = {}; - if (requestParameters.speakerUuid !== undefined) { - queryParameters['speaker_uuid'] = requestParameters.speakerUuid; - } +if (requestParameters.speakerUuid !== undefined) { + queryParameters['speaker_uuid'] = requestParameters.speakerUuid; +} - if (requestParameters.coreVersion !== undefined) { - queryParameters['core_version'] = requestParameters.coreVersion; - } +if (requestParameters.coreVersion !== undefined) { + queryParameters['core_version'] = requestParameters.coreVersion; +} - const headerParameters: runtime.HTTPHeaders = {}; +const headerParameters: runtime.HTTPHeaders = {}; - const response = await this.request({ - path: `/speaker_info`, - method: 'GET', - headers: headerParameters, - query: queryParameters, - }, initOverrides); +const response = await this.request({ + path: `/speaker_info`, + method: 'GET', + headers: headerParameters, + query: queryParameters, +}, initOverrides); - return new runtime.JSONApiResponse(response, (jsonValue) => SpeakerInfoFromJSON(jsonValue)); + return new runtime.JSONApiResponse(response, (jsonValue) => SpeakerInfoFromJSON(jsonValue)); } - /** +/** * 指定されたspeaker_uuidに関する情報をjson形式で返します。 画像や音声はbase64エンコードされたものが返されます。 * Speaker Info */ - async speakerInfoSpeakerInfoGet(requestParameters: SpeakerInfoSpeakerInfoGetRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { - const response = await this.speakerInfoSpeakerInfoGetRaw(requestParameters, initOverrides); - return await response.value(); - } +async speakerInfoSpeakerInfoGet(requestParameters: SpeakerInfoSpeakerInfoGetRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { +const response = await this.speakerInfoSpeakerInfoGetRaw(requestParameters, initOverrides); +return await response.value(); +} - /** +/** * Speakers */ - async speakersSpeakersGetRaw(requestParameters: SpeakersSpeakersGetRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>> { - const queryParameters: any = {}; +async speakersSpeakersGetRaw(requestParameters: SpeakersSpeakersGetRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>> { +const queryParameters: any = {}; - if (requestParameters.coreVersion !== undefined) { - queryParameters['core_version'] = requestParameters.coreVersion; - } +if (requestParameters.coreVersion !== undefined) { + queryParameters['core_version'] = requestParameters.coreVersion; +} - const headerParameters: runtime.HTTPHeaders = {}; +const headerParameters: runtime.HTTPHeaders = {}; - const response = await this.request({ - path: `/speakers`, - method: 'GET', - headers: headerParameters, - query: queryParameters, - }, initOverrides); +const response = await this.request({ + path: `/speakers`, + method: 'GET', + headers: headerParameters, + query: queryParameters, +}, initOverrides); - return new runtime.JSONApiResponse(response, (jsonValue) => jsonValue.map(SpeakerFromJSON)); + return new runtime.JSONApiResponse(response, (jsonValue) => jsonValue.map(SpeakerFromJSON)); } - /** +/** * Speakers */ - async speakersSpeakersGet(requestParameters: SpeakersSpeakersGetRequest = {}, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { - const response = await this.speakersSpeakersGetRaw(requestParameters, initOverrides); - return await response.value(); - } +async speakersSpeakersGet(requestParameters: SpeakersSpeakersGetRequest = {}, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { +const response = await this.speakersSpeakersGetRaw(requestParameters, initOverrides); +return await response.value(); +} - /** +/** * Supported Devices */ - async supportedDevicesSupportedDevicesGetRaw(requestParameters: SupportedDevicesSupportedDevicesGetRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { - const queryParameters: any = {}; +async supportedDevicesSupportedDevicesGetRaw(requestParameters: SupportedDevicesSupportedDevicesGetRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { +const queryParameters: any = {}; - if (requestParameters.coreVersion !== undefined) { - queryParameters['core_version'] = requestParameters.coreVersion; - } +if (requestParameters.coreVersion !== undefined) { + queryParameters['core_version'] = requestParameters.coreVersion; +} - const headerParameters: runtime.HTTPHeaders = {}; +const headerParameters: runtime.HTTPHeaders = {}; - const response = await this.request({ - path: `/supported_devices`, - method: 'GET', - headers: headerParameters, - query: queryParameters, - }, initOverrides); +const response = await this.request({ + path: `/supported_devices`, + method: 'GET', + headers: headerParameters, + query: queryParameters, +}, initOverrides); - return new runtime.JSONApiResponse(response, (jsonValue) => SupportedDevicesInfoFromJSON(jsonValue)); + return new runtime.JSONApiResponse(response, (jsonValue) => SupportedDevicesInfoFromJSON(jsonValue)); } - /** +/** * Supported Devices */ - async supportedDevicesSupportedDevicesGet(requestParameters: SupportedDevicesSupportedDevicesGetRequest = {}, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { - const response = await this.supportedDevicesSupportedDevicesGetRaw(requestParameters, initOverrides); - return await response.value(); - } +async supportedDevicesSupportedDevicesGet(requestParameters: SupportedDevicesSupportedDevicesGetRequest = {}, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { +const response = await this.supportedDevicesSupportedDevicesGetRaw(requestParameters, initOverrides); +return await response.value(); +} - /** +/** * 指定された2種類のスタイルで音声を合成、指定した割合でモーフィングした音声を得ます。 モーフィングの割合は`morph_rate`で指定でき、0.0でベースのスタイル、1.0でターゲットのスタイルに近づきます。 * 2種類のスタイルでモーフィングした音声を合成する */ - async synthesisMorphingSynthesisMorphingPostRaw(requestParameters: SynthesisMorphingSynthesisMorphingPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { - if (requestParameters.baseSpeaker === null || requestParameters.baseSpeaker === undefined) { - throw new runtime.RequiredError('baseSpeaker','Required parameter requestParameters.baseSpeaker was null or undefined when calling synthesisMorphingSynthesisMorphingPost.'); - } +async synthesisMorphingSynthesisMorphingPostRaw(requestParameters: SynthesisMorphingSynthesisMorphingPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { +if (requestParameters.baseSpeaker === null || requestParameters.baseSpeaker === undefined) { + throw new runtime.RequiredError('baseSpeaker','Required parameter requestParameters.baseSpeaker was null or undefined when calling synthesisMorphingSynthesisMorphingPost.'); +} - if (requestParameters.targetSpeaker === null || requestParameters.targetSpeaker === undefined) { - throw new runtime.RequiredError('targetSpeaker','Required parameter requestParameters.targetSpeaker was null or undefined when calling synthesisMorphingSynthesisMorphingPost.'); - } +if (requestParameters.targetSpeaker === null || requestParameters.targetSpeaker === undefined) { + throw new runtime.RequiredError('targetSpeaker','Required parameter requestParameters.targetSpeaker was null or undefined when calling synthesisMorphingSynthesisMorphingPost.'); +} - if (requestParameters.morphRate === null || requestParameters.morphRate === undefined) { - throw new runtime.RequiredError('morphRate','Required parameter requestParameters.morphRate was null or undefined when calling synthesisMorphingSynthesisMorphingPost.'); - } +if (requestParameters.morphRate === null || requestParameters.morphRate === undefined) { + throw new runtime.RequiredError('morphRate','Required parameter requestParameters.morphRate was null or undefined when calling synthesisMorphingSynthesisMorphingPost.'); +} - if (requestParameters.audioQuery === null || requestParameters.audioQuery === undefined) { - throw new runtime.RequiredError('audioQuery','Required parameter requestParameters.audioQuery was null or undefined when calling synthesisMorphingSynthesisMorphingPost.'); - } +if (requestParameters.audioQuery === null || requestParameters.audioQuery === undefined) { + throw new runtime.RequiredError('audioQuery','Required parameter requestParameters.audioQuery was null or undefined when calling synthesisMorphingSynthesisMorphingPost.'); +} - const queryParameters: any = {}; +const queryParameters: any = {}; - if (requestParameters.baseSpeaker !== undefined) { - queryParameters['base_speaker'] = requestParameters.baseSpeaker; - } +if (requestParameters.baseSpeaker !== undefined) { + queryParameters['base_speaker'] = requestParameters.baseSpeaker; +} - if (requestParameters.targetSpeaker !== undefined) { - queryParameters['target_speaker'] = requestParameters.targetSpeaker; - } +if (requestParameters.targetSpeaker !== undefined) { + queryParameters['target_speaker'] = requestParameters.targetSpeaker; +} - if (requestParameters.morphRate !== undefined) { - queryParameters['morph_rate'] = requestParameters.morphRate; - } +if (requestParameters.morphRate !== undefined) { + queryParameters['morph_rate'] = requestParameters.morphRate; +} - if (requestParameters.coreVersion !== undefined) { - queryParameters['core_version'] = requestParameters.coreVersion; - } +if (requestParameters.coreVersion !== undefined) { + queryParameters['core_version'] = requestParameters.coreVersion; +} - const headerParameters: runtime.HTTPHeaders = {}; +const headerParameters: runtime.HTTPHeaders = {}; - headerParameters['Content-Type'] = 'application/json'; +headerParameters['Content-Type'] = 'application/json'; - const response = await this.request({ - path: `/synthesis_morphing`, - method: 'POST', - headers: headerParameters, - query: queryParameters, - body: AudioQueryToJSON(requestParameters.audioQuery), - }, initOverrides); +const response = await this.request({ + path: `/synthesis_morphing`, + method: 'POST', + headers: headerParameters, + query: queryParameters, + body: AudioQueryToJSON(requestParameters.audioQuery), +}, initOverrides); - return new runtime.BlobApiResponse(response); + return new runtime.BlobApiResponse(response); } - /** +/** * 指定された2種類のスタイルで音声を合成、指定した割合でモーフィングした音声を得ます。 モーフィングの割合は`morph_rate`で指定でき、0.0でベースのスタイル、1.0でターゲットのスタイルに近づきます。 * 2種類のスタイルでモーフィングした音声を合成する */ - async synthesisMorphingSynthesisMorphingPost(requestParameters: SynthesisMorphingSynthesisMorphingPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { - const response = await this.synthesisMorphingSynthesisMorphingPostRaw(requestParameters, initOverrides); - return await response.value(); - } +async synthesisMorphingSynthesisMorphingPost(requestParameters: SynthesisMorphingSynthesisMorphingPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { +const response = await this.synthesisMorphingSynthesisMorphingPostRaw(requestParameters, initOverrides); +return await response.value(); +} - /** +/** * 音声合成する */ - async synthesisSynthesisPostRaw(requestParameters: SynthesisSynthesisPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { - if (requestParameters.speaker === null || requestParameters.speaker === undefined) { - throw new runtime.RequiredError('speaker','Required parameter requestParameters.speaker was null or undefined when calling synthesisSynthesisPost.'); - } +async synthesisSynthesisPostRaw(requestParameters: SynthesisSynthesisPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { +if (requestParameters.speaker === null || requestParameters.speaker === undefined) { + throw new runtime.RequiredError('speaker','Required parameter requestParameters.speaker was null or undefined when calling synthesisSynthesisPost.'); +} - if (requestParameters.audioQuery === null || requestParameters.audioQuery === undefined) { - throw new runtime.RequiredError('audioQuery','Required parameter requestParameters.audioQuery was null or undefined when calling synthesisSynthesisPost.'); - } +if (requestParameters.audioQuery === null || requestParameters.audioQuery === undefined) { + throw new runtime.RequiredError('audioQuery','Required parameter requestParameters.audioQuery was null or undefined when calling synthesisSynthesisPost.'); +} - const queryParameters: any = {}; +const queryParameters: any = {}; - if (requestParameters.speaker !== undefined) { - queryParameters['speaker'] = requestParameters.speaker; - } +if (requestParameters.speaker !== undefined) { + queryParameters['speaker'] = requestParameters.speaker; +} - if (requestParameters.enableInterrogativeUpspeak !== undefined) { - queryParameters['enable_interrogative_upspeak'] = requestParameters.enableInterrogativeUpspeak; - } +if (requestParameters.enableInterrogativeUpspeak !== undefined) { + queryParameters['enable_interrogative_upspeak'] = requestParameters.enableInterrogativeUpspeak; +} - if (requestParameters.coreVersion !== undefined) { - queryParameters['core_version'] = requestParameters.coreVersion; - } +if (requestParameters.coreVersion !== undefined) { + queryParameters['core_version'] = requestParameters.coreVersion; +} - const headerParameters: runtime.HTTPHeaders = {}; +const headerParameters: runtime.HTTPHeaders = {}; - headerParameters['Content-Type'] = 'application/json'; +headerParameters['Content-Type'] = 'application/json'; - const response = await this.request({ - path: `/synthesis`, - method: 'POST', - headers: headerParameters, - query: queryParameters, - body: AudioQueryToJSON(requestParameters.audioQuery), - }, initOverrides); +const response = await this.request({ + path: `/synthesis`, + method: 'POST', + headers: headerParameters, + query: queryParameters, + body: AudioQueryToJSON(requestParameters.audioQuery), +}, initOverrides); - return new runtime.BlobApiResponse(response); + return new runtime.BlobApiResponse(response); } - /** +/** * 音声合成する */ - async synthesisSynthesisPost(requestParameters: SynthesisSynthesisPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { - const response = await this.synthesisSynthesisPostRaw(requestParameters, initOverrides); - return await response.value(); - } +async synthesisSynthesisPost(requestParameters: SynthesisSynthesisPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { +const response = await this.synthesisSynthesisPostRaw(requestParameters, initOverrides); +return await response.value(); +} - /** +/** * 音声ライブラリをアンインストールします。 * Uninstall Library */ - async uninstallLibraryUninstallLibraryLibraryUuidPostRaw(requestParameters: UninstallLibraryUninstallLibraryLibraryUuidPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { - if (requestParameters.libraryUuid === null || requestParameters.libraryUuid === undefined) { - throw new runtime.RequiredError('libraryUuid','Required parameter requestParameters.libraryUuid was null or undefined when calling uninstallLibraryUninstallLibraryLibraryUuidPost.'); - } +async uninstallLibraryUninstallLibraryLibraryUuidPostRaw(requestParameters: UninstallLibraryUninstallLibraryLibraryUuidPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { +if (requestParameters.libraryUuid === null || requestParameters.libraryUuid === undefined) { + throw new runtime.RequiredError('libraryUuid','Required parameter requestParameters.libraryUuid was null or undefined when calling uninstallLibraryUninstallLibraryLibraryUuidPost.'); +} - const queryParameters: any = {}; +const queryParameters: any = {}; - const headerParameters: runtime.HTTPHeaders = {}; +const headerParameters: runtime.HTTPHeaders = {}; - const response = await this.request({ - path: `/uninstall_library/{library_uuid}`.replace(`{${"library_uuid"}}`, encodeURIComponent(String(requestParameters.libraryUuid))), - method: 'POST', - headers: headerParameters, - query: queryParameters, - }, initOverrides); +const response = await this.request({ + path: `/uninstall_library/{library_uuid}`.replace(`{${"library_uuid"}}`, encodeURIComponent(String(requestParameters.libraryUuid))), + method: 'POST', + headers: headerParameters, + query: queryParameters, +}, initOverrides); - return new runtime.VoidApiResponse(response); + return new runtime.VoidApiResponse(response); } - /** +/** * 音声ライブラリをアンインストールします。 * Uninstall Library */ - async uninstallLibraryUninstallLibraryLibraryUuidPost(requestParameters: UninstallLibraryUninstallLibraryLibraryUuidPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { - await this.uninstallLibraryUninstallLibraryLibraryUuidPostRaw(requestParameters, initOverrides); - } +async uninstallLibraryUninstallLibraryLibraryUuidPost(requestParameters: UninstallLibraryUninstallLibraryLibraryUuidPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { + await this.uninstallLibraryUninstallLibraryLibraryUuidPostRaw(requestParameters, initOverrides); +} - /** +/** * 既存のプリセットを更新します * Update Preset */ - async updatePresetUpdatePresetPostRaw(requestParameters: UpdatePresetUpdatePresetPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { - if (requestParameters.preset === null || requestParameters.preset === undefined) { - throw new runtime.RequiredError('preset','Required parameter requestParameters.preset was null or undefined when calling updatePresetUpdatePresetPost.'); - } +async updatePresetUpdatePresetPostRaw(requestParameters: UpdatePresetUpdatePresetPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { +if (requestParameters.preset === null || requestParameters.preset === undefined) { + throw new runtime.RequiredError('preset','Required parameter requestParameters.preset was null or undefined when calling updatePresetUpdatePresetPost.'); +} - const queryParameters: any = {}; +const queryParameters: any = {}; - const headerParameters: runtime.HTTPHeaders = {}; +const headerParameters: runtime.HTTPHeaders = {}; - headerParameters['Content-Type'] = 'application/json'; +headerParameters['Content-Type'] = 'application/json'; - const response = await this.request({ - path: `/update_preset`, - method: 'POST', - headers: headerParameters, - query: queryParameters, - body: PresetToJSON(requestParameters.preset), - }, initOverrides); +const response = await this.request({ + path: `/update_preset`, + method: 'POST', + headers: headerParameters, + query: queryParameters, + body: PresetToJSON(requestParameters.preset), +}, initOverrides); - if (this.isJsonMime(response.headers.get('content-type'))) { - return new runtime.JSONApiResponse(response); - } else { - return new runtime.TextApiResponse(response) as any; - } - } +if (this.isJsonMime(response.headers.get('content-type'))) { + return new runtime.JSONApiResponse(response); +} else { + return new runtime.TextApiResponse(response) as any; +} +} - /** +/** * 既存のプリセットを更新します * Update Preset */ - async updatePresetUpdatePresetPost(requestParameters: UpdatePresetUpdatePresetPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { - const response = await this.updatePresetUpdatePresetPostRaw(requestParameters, initOverrides); - return await response.value(); - } +async updatePresetUpdatePresetPost(requestParameters: UpdatePresetUpdatePresetPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { +const response = await this.updatePresetUpdatePresetPostRaw(requestParameters, initOverrides); +return await response.value(); +} - /** +/** * テキストがAquesTalk 風記法に従っているかどうかを判定します。 従っていない場合はエラーが返ります。 * テキストがAquesTalk 風記法に従っているか判定する */ - async validateKanaValidateKanaPostRaw(requestParameters: ValidateKanaValidateKanaPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { - if (requestParameters.text === null || requestParameters.text === undefined) { - throw new runtime.RequiredError('text','Required parameter requestParameters.text was null or undefined when calling validateKanaValidateKanaPost.'); - } +async validateKanaValidateKanaPostRaw(requestParameters: ValidateKanaValidateKanaPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { +if (requestParameters.text === null || requestParameters.text === undefined) { + throw new runtime.RequiredError('text','Required parameter requestParameters.text was null or undefined when calling validateKanaValidateKanaPost.'); +} - const queryParameters: any = {}; +const queryParameters: any = {}; - if (requestParameters.text !== undefined) { - queryParameters['text'] = requestParameters.text; - } +if (requestParameters.text !== undefined) { + queryParameters['text'] = requestParameters.text; +} - const headerParameters: runtime.HTTPHeaders = {}; +const headerParameters: runtime.HTTPHeaders = {}; - const response = await this.request({ - path: `/validate_kana`, - method: 'POST', - headers: headerParameters, - query: queryParameters, - }, initOverrides); +const response = await this.request({ + path: `/validate_kana`, + method: 'POST', + headers: headerParameters, + query: queryParameters, +}, initOverrides); - if (this.isJsonMime(response.headers.get('content-type'))) { - return new runtime.JSONApiResponse(response); - } else { - return new runtime.TextApiResponse(response) as any; - } - } +if (this.isJsonMime(response.headers.get('content-type'))) { + return new runtime.JSONApiResponse(response); +} else { + return new runtime.TextApiResponse(response) as any; +} +} - /** +/** * テキストがAquesTalk 風記法に従っているかどうかを判定します。 従っていない場合はエラーが返ります。 * テキストがAquesTalk 風記法に従っているか判定する */ - async validateKanaValidateKanaPost(requestParameters: ValidateKanaValidateKanaPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { - const response = await this.validateKanaValidateKanaPostRaw(requestParameters, initOverrides); - return await response.value(); - } +async validateKanaValidateKanaPost(requestParameters: ValidateKanaValidateKanaPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { +const response = await this.validateKanaValidateKanaPostRaw(requestParameters, initOverrides); +return await response.value(); +} - /** +/** * Version */ - async versionVersionGetRaw(initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { - const queryParameters: any = {}; +async versionVersionGetRaw(initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { +const queryParameters: any = {}; - const headerParameters: runtime.HTTPHeaders = {}; +const headerParameters: runtime.HTTPHeaders = {}; - const response = await this.request({ - path: `/version`, - method: 'GET', - headers: headerParameters, - query: queryParameters, - }, initOverrides); +const response = await this.request({ + path: `/version`, + method: 'GET', + headers: headerParameters, + query: queryParameters, +}, initOverrides); - if (this.isJsonMime(response.headers.get('content-type'))) { - return new runtime.JSONApiResponse(response); - } else { - return new runtime.TextApiResponse(response) as any; - } - } +if (this.isJsonMime(response.headers.get('content-type'))) { + return new runtime.JSONApiResponse(response); +} else { + return new runtime.TextApiResponse(response) as any; +} +} - /** +/** * Version */ - async versionVersionGet(initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { - const response = await this.versionVersionGetRaw(initOverrides); - return await response.value(); - } +async versionVersionGet(initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { +const response = await this.versionVersionGetRaw(initOverrides); +return await response.value(); +} } diff --git a/src/openapi/models/AudioQuery.ts b/src/openapi/models/AudioQuery.ts index cef65dac0e..de60f7b50c 100644 --- a/src/openapi/models/AudioQuery.ts +++ b/src/openapi/models/AudioQuery.ts @@ -5,7 +5,7 @@ * VOICEVOXの音声合成エンジンです。 * * The version of the OpenAPI document: latest - * + * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). * https://openapi-generator.tech @@ -27,19 +27,19 @@ import { */ export interface AudioQuery { /** - * + * * @type {Array} * @memberof AudioQuery */ accentPhrases: Array; /** - * + * * @type {number} * @memberof AudioQuery */ speedScale: number; /** - * + * * @type {number} * @memberof AudioQuery */ @@ -51,49 +51,49 @@ export interface AudioQuery { */ intonationScale: number; /** - * + * * @type {number} * @memberof AudioQuery */ volumeScale: number; /** - * + * * @type {number} * @memberof AudioQuery */ prePhonemeLength: number; /** - * + * * @type {number} * @memberof AudioQuery */ postPhonemeLength: number; /** - * + * * @type {number | null} * @memberof AudioQuery */ pauseLength: number | null; /** - * + * * @type {number} * @memberof AudioQuery */ pauseLengthScale: number; /** - * + * * @type {number} * @memberof AudioQuery */ outputSamplingRate: number; /** - * + * * @type {boolean} * @memberof AudioQuery */ outputStereo: boolean; /** - * + * * @type {string} * @memberof AudioQuery */ diff --git a/src/openapi/models/Preset.ts b/src/openapi/models/Preset.ts index 53bb75ef9f..dc068fdfc1 100644 --- a/src/openapi/models/Preset.ts +++ b/src/openapi/models/Preset.ts @@ -5,7 +5,7 @@ * VOICEVOXの音声合成エンジンです。 * * The version of the OpenAPI document: latest - * + * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). * https://openapi-generator.tech @@ -20,73 +20,73 @@ import { exists, mapValues } from '../runtime'; */ export interface Preset { /** - * + * * @type {number} * @memberof Preset */ id: number; /** - * + * * @type {string} * @memberof Preset */ name: string; /** - * + * * @type {string} * @memberof Preset */ speakerUuid: string; /** - * + * * @type {number} * @memberof Preset */ styleId: number; /** - * + * * @type {number} * @memberof Preset */ speedScale: number; /** - * + * * @type {number} * @memberof Preset */ pitchScale: number; /** - * + * * @type {number} * @memberof Preset */ intonationScale: number; /** - * + * * @type {number} * @memberof Preset */ volumeScale: number; /** - * + * * @type {number} * @memberof Preset */ prePhonemeLength: number; /** - * + * * @type {number} * @memberof Preset */ postPhonemeLength: number; /** - * + * * @type {number | null} * @memberof AudioQuery */ pauseLength: number | null; /** - * + * * @type {number} * @memberof Preset */ From 7a3394ae75ee0c393fbb09609f83ee255f5484b9 Mon Sep 17 00:00:00 2001 From: X-20A <155217226+X-20A@users.noreply.github.com> Date: Fri, 7 Jun 2024 15:44:42 +0900 Subject: [PATCH 12/86] =?UTF-8?q?=E3=83=97=E3=83=AA=E3=82=BB=E3=83=83?= =?UTF-8?q?=E3=83=88=E5=90=8D=E5=A4=89=E6=9B=B4=20=E4=BB=96=E6=95=B4?= =?UTF-8?q?=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/openapi/apis/DefaultApi.ts | 2404 +++++++++++++++--------------- src/openapi/models/AudioQuery.ts | 6 +- src/openapi/models/Preset.ts | 4 +- 3 files changed, 1207 insertions(+), 1207 deletions(-) diff --git a/src/openapi/apis/DefaultApi.ts b/src/openapi/apis/DefaultApi.ts index 6c404c7aa2..f8d710a278 100644 --- a/src/openapi/apis/DefaultApi.ts +++ b/src/openapi/apis/DefaultApi.ts @@ -15,62 +15,62 @@ import * as runtime from '../runtime'; import type { -AccentPhrase, -AudioQuery, -BodySingFrameVolumeSingFrameVolumePost, -CorsPolicyMode, -DownloadableLibraryInfo, -EngineManifest, -FrameAudioQuery, -HTTPValidationError, -InstalledLibraryInfo, -MorphableTargetInfo, -ParseKanaBadRequest, -Preset, -Score, -Speaker, -SpeakerInfo, -SupportedDevicesInfo, -UserDictWord, -WordTypes, + AccentPhrase, + AudioQuery, + BodySingFrameVolumeSingFrameVolumePost, + CorsPolicyMode, + DownloadableLibraryInfo, + EngineManifest, + FrameAudioQuery, + HTTPValidationError, + InstalledLibraryInfo, + MorphableTargetInfo, + ParseKanaBadRequest, + Preset, + Score, + Speaker, + SpeakerInfo, + SupportedDevicesInfo, + UserDictWord, + WordTypes, } from '../models/index'; import { -AccentPhraseFromJSON, -AccentPhraseToJSON, -AudioQueryFromJSON, -AudioQueryToJSON, -BodySingFrameVolumeSingFrameVolumePostFromJSON, -BodySingFrameVolumeSingFrameVolumePostToJSON, -CorsPolicyModeFromJSON, -CorsPolicyModeToJSON, -DownloadableLibraryInfoFromJSON, -DownloadableLibraryInfoToJSON, -EngineManifestFromJSON, -EngineManifestToJSON, -FrameAudioQueryFromJSON, -FrameAudioQueryToJSON, -HTTPValidationErrorFromJSON, -HTTPValidationErrorToJSON, -InstalledLibraryInfoFromJSON, -InstalledLibraryInfoToJSON, -MorphableTargetInfoFromJSON, -MorphableTargetInfoToJSON, -ParseKanaBadRequestFromJSON, -ParseKanaBadRequestToJSON, -PresetFromJSON, -PresetToJSON, -ScoreFromJSON, -ScoreToJSON, -SpeakerFromJSON, -SpeakerToJSON, -SpeakerInfoFromJSON, -SpeakerInfoToJSON, -SupportedDevicesInfoFromJSON, -SupportedDevicesInfoToJSON, -UserDictWordFromJSON, -UserDictWordToJSON, -WordTypesFromJSON, -WordTypesToJSON, + AccentPhraseFromJSON, + AccentPhraseToJSON, + AudioQueryFromJSON, + AudioQueryToJSON, + BodySingFrameVolumeSingFrameVolumePostFromJSON, + BodySingFrameVolumeSingFrameVolumePostToJSON, + CorsPolicyModeFromJSON, + CorsPolicyModeToJSON, + DownloadableLibraryInfoFromJSON, + DownloadableLibraryInfoToJSON, + EngineManifestFromJSON, + EngineManifestToJSON, + FrameAudioQueryFromJSON, + FrameAudioQueryToJSON, + HTTPValidationErrorFromJSON, + HTTPValidationErrorToJSON, + InstalledLibraryInfoFromJSON, + InstalledLibraryInfoToJSON, + MorphableTargetInfoFromJSON, + MorphableTargetInfoToJSON, + ParseKanaBadRequestFromJSON, + ParseKanaBadRequestToJSON, + PresetFromJSON, + PresetToJSON, + ScoreFromJSON, + ScoreToJSON, + SpeakerFromJSON, + SpeakerToJSON, + SpeakerInfoFromJSON, + SpeakerInfoToJSON, + SupportedDevicesInfoFromJSON, + SupportedDevicesInfoToJSON, + UserDictWordFromJSON, + UserDictWordToJSON, + WordTypesFromJSON, + WordTypesToJSON, } from '../models/index'; export interface AccentPhrasesAccentPhrasesPostRequest { @@ -130,7 +130,7 @@ export interface FrameSynthesisFrameSynthesisPostRequest { export interface ImportUserDictWordsImportUserDictPostRequest { override: boolean; -requestBody: { [key: string]: UserDictWord; } | null; + requestBody: { [key: string]: UserDictWord; } | null; } export interface InitializeSpeakerInitializeSpeakerPostRequest { @@ -259,7 +259,7 @@ export interface ValidateKanaValidateKanaPostRequest { * @interface DefaultApiInterface */ export interface DefaultApiInterface { -/** + /** * テキストからアクセント句を得ます。 is_kanaが`true`のとき、テキストは次のAquesTalk 風記法で解釈されます。デフォルトは`false`です。 * 全てのカナはカタカナで記述される * アクセント句は`/`または`、`で区切る。`、`で区切った場合に限り無音区間が挿入される。 * カナの手前に`_`を入れるとそのカナは無声化される * アクセント位置を`\'`で指定する。全てのアクセント句にはアクセント位置を1つ指定する必要がある。 * アクセント句末に`?`(全角)を入れることにより疑問文の発音ができる。 * @summary テキストからアクセント句を得る * @param {string} text @@ -272,13 +272,13 @@ export interface DefaultApiInterface { */ accentPhrasesAccentPhrasesPostRaw(requestParameters: AccentPhrasesAccentPhrasesPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>>; -/** + /** * テキストからアクセント句を得ます。 is_kanaが`true`のとき、テキストは次のAquesTalk 風記法で解釈されます。デフォルトは`false`です。 * 全てのカナはカタカナで記述される * アクセント句は`/`または`、`で区切る。`、`で区切った場合に限り無音区間が挿入される。 * カナの手前に`_`を入れるとそのカナは無声化される * アクセント位置を`\'`で指定する。全てのアクセント句にはアクセント位置を1つ指定する必要がある。 * アクセント句末に`?`(全角)を入れることにより疑問文の発音ができる。 * テキストからアクセント句を得る */ accentPhrasesAccentPhrasesPost(requestParameters: AccentPhrasesAccentPhrasesPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>; -/** + /** * 新しいプリセットを追加します * @summary Add Preset * @param {Preset} preset @@ -288,13 +288,13 @@ export interface DefaultApiInterface { */ addPresetAddPresetPostRaw(requestParameters: AddPresetAddPresetPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>; -/** + /** * 新しいプリセットを追加します * Add Preset */ addPresetAddPresetPost(requestParameters: AddPresetAddPresetPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise; -/** + /** * ユーザー辞書に言葉を追加します。 * @summary Add User Dict Word * @param {string} surface 言葉の表層形 @@ -308,13 +308,13 @@ export interface DefaultApiInterface { */ addUserDictWordUserDictWordPostRaw(requestParameters: AddUserDictWordUserDictWordPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>; -/** + /** * ユーザー辞書に言葉を追加します。 * Add User Dict Word */ addUserDictWordUserDictWordPost(requestParameters: AddUserDictWordUserDictWordPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise; -/** + /** * 音声合成用のクエリの初期値を得ます。ここで得られたクエリはそのまま音声合成に利用できます。各値の意味は`Schemas`を参照してください。 * @summary 音声合成用のクエリを作成する * @param {string} text @@ -326,13 +326,13 @@ export interface DefaultApiInterface { */ audioQueryAudioQueryPostRaw(requestParameters: AudioQueryAudioQueryPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>; -/** + /** * 音声合成用のクエリの初期値を得ます。ここで得られたクエリはそのまま音声合成に利用できます。各値の意味は`Schemas`を参照してください。 * 音声合成用のクエリを作成する */ audioQueryAudioQueryPost(requestParameters: AudioQueryAudioQueryPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise; -/** + /** * 音声合成用のクエリの初期値を得ます。ここで得られたクエリはそのまま音声合成に利用できます。各値の意味は`Schemas`を参照してください。 * @summary 音声合成用のクエリをプリセットを用いて作成する * @param {string} text @@ -344,13 +344,13 @@ export interface DefaultApiInterface { */ audioQueryFromPresetAudioQueryFromPresetPostRaw(requestParameters: AudioQueryFromPresetAudioQueryFromPresetPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>; -/** + /** * 音声合成用のクエリの初期値を得ます。ここで得られたクエリはそのまま音声合成に利用できます。各値の意味は`Schemas`を参照してください。 * 音声合成用のクエリをプリセットを用いて作成する */ audioQueryFromPresetAudioQueryFromPresetPost(requestParameters: AudioQueryFromPresetAudioQueryFromPresetPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise; -/** + /** * * @summary 音声合成する(キャンセル可能) * @param {number} speaker @@ -362,12 +362,12 @@ export interface DefaultApiInterface { */ cancellableSynthesisCancellableSynthesisPostRaw(requestParameters: CancellableSynthesisCancellableSynthesisPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>; -/** + /** * 音声合成する(キャンセル可能) */ cancellableSynthesisCancellableSynthesisPost(requestParameters: CancellableSynthesisCancellableSynthesisPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise; -/** + /** * base64エンコードされたwavデータを一纏めにし、wavファイルで返します。 * @summary base64エンコードされた複数のwavデータを一つに結合する * @param {Array} requestBody @@ -377,13 +377,13 @@ export interface DefaultApiInterface { */ connectWavesConnectWavesPostRaw(requestParameters: ConnectWavesConnectWavesPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>; -/** + /** * base64エンコードされたwavデータを一纏めにし、wavファイルで返します。 * base64エンコードされた複数のwavデータを一つに結合する */ connectWavesConnectWavesPost(requestParameters: ConnectWavesConnectWavesPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise; -/** + /** * * @summary Core Versions * @param {*} [options] Override http request option. @@ -392,12 +392,12 @@ export interface DefaultApiInterface { */ coreVersionsCoreVersionsGetRaw(initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>>; -/** + /** * Core Versions */ coreVersionsCoreVersionsGet(initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>; -/** + /** * 既存のプリセットを削除します * @summary Delete Preset * @param {number} id 削除するプリセットのプリセットID @@ -407,13 +407,13 @@ export interface DefaultApiInterface { */ deletePresetDeletePresetPostRaw(requestParameters: DeletePresetDeletePresetPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>; -/** + /** * 既存のプリセットを削除します * Delete Preset */ deletePresetDeletePresetPost(requestParameters: DeletePresetDeletePresetPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise; -/** + /** * ユーザー辞書に登録されている言葉を削除します。 * @summary Delete User Dict Word * @param {string} wordUuid 削除する言葉のUUID @@ -423,13 +423,13 @@ export interface DefaultApiInterface { */ deleteUserDictWordUserDictWordWordUuidDeleteRaw(requestParameters: DeleteUserDictWordUserDictWordWordUuidDeleteRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>; -/** + /** * ユーザー辞書に登録されている言葉を削除します。 * Delete User Dict Word */ deleteUserDictWordUserDictWordWordUuidDelete(requestParameters: DeleteUserDictWordUserDictWordWordUuidDeleteRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise; -/** + /** * ダウンロード可能な音声ライブラリの情報を返します。 * @summary Downloadable Libraries * @param {*} [options] Override http request option. @@ -438,13 +438,13 @@ export interface DefaultApiInterface { */ downloadableLibrariesDownloadableLibrariesGetRaw(initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>>; -/** + /** * ダウンロード可能な音声ライブラリの情報を返します。 * Downloadable Libraries */ downloadableLibrariesDownloadableLibrariesGet(initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>; -/** + /** * * @summary Engine Manifest * @param {*} [options] Override http request option. @@ -453,12 +453,12 @@ export interface DefaultApiInterface { */ engineManifestEngineManifestGetRaw(initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>; -/** + /** * Engine Manifest */ engineManifestEngineManifestGet(initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise; -/** + /** * 歌唱音声合成を行います。 * @summary Frame Synthesis * @param {number} speaker @@ -470,13 +470,13 @@ export interface DefaultApiInterface { */ frameSynthesisFrameSynthesisPostRaw(requestParameters: FrameSynthesisFrameSynthesisPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>; -/** + /** * 歌唱音声合成を行います。 * Frame Synthesis */ frameSynthesisFrameSynthesisPost(requestParameters: FrameSynthesisFrameSynthesisPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise; -/** + /** * エンジンが保持しているプリセットの設定を返します * @summary Get Presets * @param {*} [options] Override http request option. @@ -485,13 +485,13 @@ export interface DefaultApiInterface { */ getPresetsPresetsGetRaw(initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>>; -/** + /** * エンジンが保持しているプリセットの設定を返します * Get Presets */ getPresetsPresetsGet(initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>; -/** + /** * ユーザー辞書に登録されている単語の一覧を返します。 単語の表層形(surface)は正規化済みの物を返します。 * @summary Get User Dict Words * @param {*} [options] Override http request option. @@ -500,13 +500,13 @@ export interface DefaultApiInterface { */ getUserDictWordsUserDictGetRaw(initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>; -/** + /** * ユーザー辞書に登録されている単語の一覧を返します。 単語の表層形(surface)は正規化済みの物を返します。 * Get User Dict Words */ getUserDictWordsUserDictGet(initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise<{ [key: string]: UserDictWord; }>; -/** + /** * 他のユーザー辞書をインポートします。 * @summary Import User Dict Words * @param {boolean} override 重複したエントリがあった場合、上書きするかどうか @@ -517,13 +517,13 @@ export interface DefaultApiInterface { */ importUserDictWordsImportUserDictPostRaw(requestParameters: ImportUserDictWordsImportUserDictPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>; -/** + /** * 他のユーザー辞書をインポートします。 * Import User Dict Words */ importUserDictWordsImportUserDictPost(requestParameters: ImportUserDictWordsImportUserDictPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise; -/** + /** * 指定されたスタイルを初期化します。 実行しなくても他のAPIは使用できますが、初回実行時に時間がかかることがあります。 * @summary Initialize Speaker * @param {number} speaker @@ -535,13 +535,13 @@ export interface DefaultApiInterface { */ initializeSpeakerInitializeSpeakerPostRaw(requestParameters: InitializeSpeakerInitializeSpeakerPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>; -/** + /** * 指定されたスタイルを初期化します。 実行しなくても他のAPIは使用できますが、初回実行時に時間がかかることがあります。 * Initialize Speaker */ initializeSpeakerInitializeSpeakerPost(requestParameters: InitializeSpeakerInitializeSpeakerPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise; -/** + /** * 音声ライブラリをインストールします。 音声ライブラリのZIPファイルをリクエストボディとして送信してください。 * @summary Install Library * @param {string} libraryUuid 音声ライブラリのID @@ -551,13 +551,13 @@ export interface DefaultApiInterface { */ installLibraryInstallLibraryLibraryUuidPostRaw(requestParameters: InstallLibraryInstallLibraryLibraryUuidPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>; -/** + /** * 音声ライブラリをインストールします。 音声ライブラリのZIPファイルをリクエストボディとして送信してください。 * Install Library */ installLibraryInstallLibraryLibraryUuidPost(requestParameters: InstallLibraryInstallLibraryLibraryUuidPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise; -/** + /** * インストールした音声ライブラリの情報を返します。 * @summary Installed Libraries * @param {*} [options] Override http request option. @@ -566,13 +566,13 @@ export interface DefaultApiInterface { */ installedLibrariesInstalledLibrariesGetRaw(initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>; -/** + /** * インストールした音声ライブラリの情報を返します。 * Installed Libraries */ installedLibrariesInstalledLibrariesGet(initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise<{ [key: string]: InstalledLibraryInfo; }>; -/** + /** * 指定されたスタイルが初期化されているかどうかを返します。 * @summary Is Initialized Speaker * @param {number} speaker @@ -583,13 +583,13 @@ export interface DefaultApiInterface { */ isInitializedSpeakerIsInitializedSpeakerGetRaw(requestParameters: IsInitializedSpeakerIsInitializedSpeakerGetRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>; -/** + /** * 指定されたスタイルが初期化されているかどうかを返します。 * Is Initialized Speaker */ isInitializedSpeakerIsInitializedSpeakerGet(requestParameters: IsInitializedSpeakerIsInitializedSpeakerGetRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise; -/** + /** * * @summary アクセント句から音高・音素長を得る * @param {number} speaker @@ -601,12 +601,12 @@ export interface DefaultApiInterface { */ moraDataMoraDataPostRaw(requestParameters: MoraDataMoraDataPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>>; -/** + /** * アクセント句から音高・音素長を得る */ moraDataMoraDataPost(requestParameters: MoraDataMoraDataPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>; -/** + /** * * @summary アクセント句から音素長を得る * @param {number} speaker @@ -618,12 +618,12 @@ export interface DefaultApiInterface { */ moraLengthMoraLengthPostRaw(requestParameters: MoraLengthMoraLengthPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>>; -/** + /** * アクセント句から音素長を得る */ moraLengthMoraLengthPost(requestParameters: MoraLengthMoraLengthPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>; -/** + /** * * @summary アクセント句から音高を得る * @param {number} speaker @@ -635,12 +635,12 @@ export interface DefaultApiInterface { */ moraPitchMoraPitchPostRaw(requestParameters: MoraPitchMoraPitchPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>>; -/** + /** * アクセント句から音高を得る */ moraPitchMoraPitchPost(requestParameters: MoraPitchMoraPitchPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>; -/** + /** * 指定されたベーススタイルに対してエンジン内の各話者がモーフィング機能を利用可能か返します。 モーフィングの許可/禁止は`/speakers`の`speaker.supported_features.synthesis_morphing`に記載されています。 プロパティが存在しない場合は、モーフィングが許可されているとみなします。 返り値のスタイルIDはstring型なので注意。 * @summary 指定したスタイルに対してエンジン内の話者がモーフィングが可能か判定する * @param {Array} requestBody @@ -651,13 +651,13 @@ export interface DefaultApiInterface { */ morphableTargetsMorphableTargetsPostRaw(requestParameters: MorphableTargetsMorphableTargetsPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>>; -/** + /** * 指定されたベーススタイルに対してエンジン内の各話者がモーフィング機能を利用可能か返します。 モーフィングの許可/禁止は`/speakers`の`speaker.supported_features.synthesis_morphing`に記載されています。 プロパティが存在しない場合は、モーフィングが許可されているとみなします。 返り値のスタイルIDはstring型なので注意。 * 指定したスタイルに対してエンジン内の話者がモーフィングが可能か判定する */ morphableTargetsMorphableTargetsPost(requestParameters: MorphableTargetsMorphableTargetsPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>; -/** + /** * * @summary 複数まとめて音声合成する * @param {number} speaker @@ -669,12 +669,12 @@ export interface DefaultApiInterface { */ multiSynthesisMultiSynthesisPostRaw(requestParameters: MultiSynthesisMultiSynthesisPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>; -/** + /** * 複数まとめて音声合成する */ multiSynthesisMultiSynthesisPost(requestParameters: MultiSynthesisMultiSynthesisPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise; -/** + /** * ユーザー辞書に登録されている言葉を更新します。 * @summary Rewrite User Dict Word * @param {string} wordUuid 更新する言葉のUUID @@ -689,13 +689,13 @@ export interface DefaultApiInterface { */ rewriteUserDictWordUserDictWordWordUuidPutRaw(requestParameters: RewriteUserDictWordUserDictWordWordUuidPutRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>; -/** + /** * ユーザー辞書に登録されている言葉を更新します。 * Rewrite User Dict Word */ rewriteUserDictWordUserDictWordWordUuidPut(requestParameters: RewriteUserDictWordUserDictWordWordUuidPutRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise; -/** + /** * 設定ページを返します。 * @summary Setting Get * @param {*} [options] Override http request option. @@ -704,13 +704,13 @@ export interface DefaultApiInterface { */ settingGetSettingGetRaw(initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>; -/** + /** * 設定ページを返します。 * Setting Get */ settingGetSettingGet(initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise; -/** + /** * 設定を更新します。 * @summary Setting Post * @param {CorsPolicyMode} corsPolicyMode @@ -721,13 +721,13 @@ export interface DefaultApiInterface { */ settingPostSettingPostRaw(requestParameters: SettingPostSettingPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>; -/** + /** * 設定を更新します。 * Setting Post */ settingPostSettingPost(requestParameters: SettingPostSettingPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise; -/** + /** * 歌唱音声合成用のクエリの初期値を得ます。ここで得られたクエリはそのまま歌唱音声合成に利用できます。各値の意味は`Schemas`を参照してください。 * @summary 歌唱音声合成用のクエリを作成する * @param {number} speaker @@ -739,13 +739,13 @@ export interface DefaultApiInterface { */ singFrameAudioQuerySingFrameAudioQueryPostRaw(requestParameters: SingFrameAudioQuerySingFrameAudioQueryPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>; -/** + /** * 歌唱音声合成用のクエリの初期値を得ます。ここで得られたクエリはそのまま歌唱音声合成に利用できます。各値の意味は`Schemas`を参照してください。 * 歌唱音声合成用のクエリを作成する */ singFrameAudioQuerySingFrameAudioQueryPost(requestParameters: SingFrameAudioQuerySingFrameAudioQueryPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise; -/** + /** * * @summary スコア・歌唱音声合成用のクエリからフレームごとの音量を得る * @param {number} speaker @@ -757,12 +757,12 @@ export interface DefaultApiInterface { */ singFrameVolumeSingFrameVolumePostRaw(requestParameters: SingFrameVolumeSingFrameVolumePostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>>; -/** + /** * スコア・歌唱音声合成用のクエリからフレームごとの音量を得る */ singFrameVolumeSingFrameVolumePost(requestParameters: SingFrameVolumeSingFrameVolumePostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>; -/** + /** * 指定されたspeaker_uuidに関する情報をjson形式で返します。 画像や音声はbase64エンコードされたものが返されます。 * @summary Singer Info * @param {string} speakerUuid @@ -773,13 +773,13 @@ export interface DefaultApiInterface { */ singerInfoSingerInfoGetRaw(requestParameters: SingerInfoSingerInfoGetRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>; -/** + /** * 指定されたspeaker_uuidに関する情報をjson形式で返します。 画像や音声はbase64エンコードされたものが返されます。 * Singer Info */ singerInfoSingerInfoGet(requestParameters: SingerInfoSingerInfoGetRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise; -/** + /** * * @summary Singers * @param {string} [coreVersion] @@ -789,12 +789,12 @@ export interface DefaultApiInterface { */ singersSingersGetRaw(requestParameters: SingersSingersGetRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>>; -/** + /** * Singers */ singersSingersGet(requestParameters: SingersSingersGetRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>; -/** + /** * 指定されたspeaker_uuidに関する情報をjson形式で返します。 画像や音声はbase64エンコードされたものが返されます。 * @summary Speaker Info * @param {string} speakerUuid @@ -805,13 +805,13 @@ export interface DefaultApiInterface { */ speakerInfoSpeakerInfoGetRaw(requestParameters: SpeakerInfoSpeakerInfoGetRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>; -/** + /** * 指定されたspeaker_uuidに関する情報をjson形式で返します。 画像や音声はbase64エンコードされたものが返されます。 * Speaker Info */ speakerInfoSpeakerInfoGet(requestParameters: SpeakerInfoSpeakerInfoGetRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise; -/** + /** * * @summary Speakers * @param {string} [coreVersion] @@ -821,12 +821,12 @@ export interface DefaultApiInterface { */ speakersSpeakersGetRaw(requestParameters: SpeakersSpeakersGetRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>>; -/** + /** * Speakers */ speakersSpeakersGet(requestParameters: SpeakersSpeakersGetRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>; -/** + /** * * @summary Supported Devices * @param {string} [coreVersion] @@ -836,12 +836,12 @@ export interface DefaultApiInterface { */ supportedDevicesSupportedDevicesGetRaw(requestParameters: SupportedDevicesSupportedDevicesGetRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>; -/** + /** * Supported Devices */ supportedDevicesSupportedDevicesGet(requestParameters: SupportedDevicesSupportedDevicesGetRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise; -/** + /** * 指定された2種類のスタイルで音声を合成、指定した割合でモーフィングした音声を得ます。 モーフィングの割合は`morph_rate`で指定でき、0.0でベースのスタイル、1.0でターゲットのスタイルに近づきます。 * @summary 2種類のスタイルでモーフィングした音声を合成する * @param {number} baseSpeaker @@ -855,13 +855,13 @@ export interface DefaultApiInterface { */ synthesisMorphingSynthesisMorphingPostRaw(requestParameters: SynthesisMorphingSynthesisMorphingPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>; -/** + /** * 指定された2種類のスタイルで音声を合成、指定した割合でモーフィングした音声を得ます。 モーフィングの割合は`morph_rate`で指定でき、0.0でベースのスタイル、1.0でターゲットのスタイルに近づきます。 * 2種類のスタイルでモーフィングした音声を合成する */ synthesisMorphingSynthesisMorphingPost(requestParameters: SynthesisMorphingSynthesisMorphingPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise; -/** + /** * * @summary 音声合成する * @param {number} speaker @@ -874,12 +874,12 @@ export interface DefaultApiInterface { */ synthesisSynthesisPostRaw(requestParameters: SynthesisSynthesisPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>; -/** + /** * 音声合成する */ synthesisSynthesisPost(requestParameters: SynthesisSynthesisPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise; -/** + /** * 音声ライブラリをアンインストールします。 * @summary Uninstall Library * @param {string} libraryUuid 音声ライブラリのID @@ -889,13 +889,13 @@ export interface DefaultApiInterface { */ uninstallLibraryUninstallLibraryLibraryUuidPostRaw(requestParameters: UninstallLibraryUninstallLibraryLibraryUuidPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>; -/** + /** * 音声ライブラリをアンインストールします。 * Uninstall Library */ uninstallLibraryUninstallLibraryLibraryUuidPost(requestParameters: UninstallLibraryUninstallLibraryLibraryUuidPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise; -/** + /** * 既存のプリセットを更新します * @summary Update Preset * @param {Preset} preset @@ -905,13 +905,13 @@ export interface DefaultApiInterface { */ updatePresetUpdatePresetPostRaw(requestParameters: UpdatePresetUpdatePresetPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>; -/** + /** * 既存のプリセットを更新します * Update Preset */ updatePresetUpdatePresetPost(requestParameters: UpdatePresetUpdatePresetPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise; -/** + /** * テキストがAquesTalk 風記法に従っているかどうかを判定します。 従っていない場合はエラーが返ります。 * @summary テキストがAquesTalk 風記法に従っているか判定する * @param {string} text 判定する対象の文字列 @@ -921,13 +921,13 @@ export interface DefaultApiInterface { */ validateKanaValidateKanaPostRaw(requestParameters: ValidateKanaValidateKanaPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>; -/** + /** * テキストがAquesTalk 風記法に従っているかどうかを判定します。 従っていない場合はエラーが返ります。 * テキストがAquesTalk 風記法に従っているか判定する */ validateKanaValidateKanaPost(requestParameters: ValidateKanaValidateKanaPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise; -/** + /** * * @summary Version * @param {*} [options] Override http request option. @@ -936,7 +936,7 @@ export interface DefaultApiInterface { */ versionVersionGetRaw(initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>; -/** + /** * Version */ versionVersionGet(initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise; @@ -948,1649 +948,1649 @@ export interface DefaultApiInterface { */ export class DefaultApi extends runtime.BaseAPI implements DefaultApiInterface { -/** + /** * テキストからアクセント句を得ます。 is_kanaが`true`のとき、テキストは次のAquesTalk 風記法で解釈されます。デフォルトは`false`です。 * 全てのカナはカタカナで記述される * アクセント句は`/`または`、`で区切る。`、`で区切った場合に限り無音区間が挿入される。 * カナの手前に`_`を入れるとそのカナは無声化される * アクセント位置を`\'`で指定する。全てのアクセント句にはアクセント位置を1つ指定する必要がある。 * アクセント句末に`?`(全角)を入れることにより疑問文の発音ができる。 * テキストからアクセント句を得る */ -async accentPhrasesAccentPhrasesPostRaw(requestParameters: AccentPhrasesAccentPhrasesPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>> { -if (requestParameters.text === null || requestParameters.text === undefined) { - throw new runtime.RequiredError('text','Required parameter requestParameters.text was null or undefined when calling accentPhrasesAccentPhrasesPost.'); -} + async accentPhrasesAccentPhrasesPostRaw(requestParameters: AccentPhrasesAccentPhrasesPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>> { + if (requestParameters.text === null || requestParameters.text === undefined) { + throw new runtime.RequiredError('text','Required parameter requestParameters.text was null or undefined when calling accentPhrasesAccentPhrasesPost.'); + } -if (requestParameters.speaker === null || requestParameters.speaker === undefined) { - throw new runtime.RequiredError('speaker','Required parameter requestParameters.speaker was null or undefined when calling accentPhrasesAccentPhrasesPost.'); -} + if (requestParameters.speaker === null || requestParameters.speaker === undefined) { + throw new runtime.RequiredError('speaker','Required parameter requestParameters.speaker was null or undefined when calling accentPhrasesAccentPhrasesPost.'); + } -const queryParameters: any = {}; + const queryParameters: any = {}; -if (requestParameters.text !== undefined) { - queryParameters['text'] = requestParameters.text; -} + if (requestParameters.text !== undefined) { + queryParameters['text'] = requestParameters.text; + } -if (requestParameters.speaker !== undefined) { - queryParameters['speaker'] = requestParameters.speaker; -} + if (requestParameters.speaker !== undefined) { + queryParameters['speaker'] = requestParameters.speaker; + } -if (requestParameters.isKana !== undefined) { - queryParameters['is_kana'] = requestParameters.isKana; -} + if (requestParameters.isKana !== undefined) { + queryParameters['is_kana'] = requestParameters.isKana; + } -if (requestParameters.coreVersion !== undefined) { - queryParameters['core_version'] = requestParameters.coreVersion; -} + if (requestParameters.coreVersion !== undefined) { + queryParameters['core_version'] = requestParameters.coreVersion; + } -const headerParameters: runtime.HTTPHeaders = {}; + const headerParameters: runtime.HTTPHeaders = {}; -const response = await this.request({ - path: `/accent_phrases`, - method: 'POST', - headers: headerParameters, - query: queryParameters, -}, initOverrides); + const response = await this.request({ + path: `/accent_phrases`, + method: 'POST', + headers: headerParameters, + query: queryParameters, + }, initOverrides); - return new runtime.JSONApiResponse(response, (jsonValue) => jsonValue.map(AccentPhraseFromJSON)); + return new runtime.JSONApiResponse(response, (jsonValue) => jsonValue.map(AccentPhraseFromJSON)); } -/** + /** * テキストからアクセント句を得ます。 is_kanaが`true`のとき、テキストは次のAquesTalk 風記法で解釈されます。デフォルトは`false`です。 * 全てのカナはカタカナで記述される * アクセント句は`/`または`、`で区切る。`、`で区切った場合に限り無音区間が挿入される。 * カナの手前に`_`を入れるとそのカナは無声化される * アクセント位置を`\'`で指定する。全てのアクセント句にはアクセント位置を1つ指定する必要がある。 * アクセント句末に`?`(全角)を入れることにより疑問文の発音ができる。 * テキストからアクセント句を得る */ -async accentPhrasesAccentPhrasesPost(requestParameters: AccentPhrasesAccentPhrasesPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { -const response = await this.accentPhrasesAccentPhrasesPostRaw(requestParameters, initOverrides); -return await response.value(); -} + async accentPhrasesAccentPhrasesPost(requestParameters: AccentPhrasesAccentPhrasesPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + const response = await this.accentPhrasesAccentPhrasesPostRaw(requestParameters, initOverrides); + return await response.value(); + } -/** + /** * 新しいプリセットを追加します * Add Preset */ -async addPresetAddPresetPostRaw(requestParameters: AddPresetAddPresetPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { -if (requestParameters.preset === null || requestParameters.preset === undefined) { - throw new runtime.RequiredError('preset','Required parameter requestParameters.preset was null or undefined when calling addPresetAddPresetPost.'); -} + async addPresetAddPresetPostRaw(requestParameters: AddPresetAddPresetPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + if (requestParameters.preset === null || requestParameters.preset === undefined) { + throw new runtime.RequiredError('preset','Required parameter requestParameters.preset was null or undefined when calling addPresetAddPresetPost.'); + } -const queryParameters: any = {}; + const queryParameters: any = {}; -const headerParameters: runtime.HTTPHeaders = {}; + const headerParameters: runtime.HTTPHeaders = {}; -headerParameters['Content-Type'] = 'application/json'; + headerParameters['Content-Type'] = 'application/json'; -const response = await this.request({ - path: `/add_preset`, - method: 'POST', - headers: headerParameters, - query: queryParameters, - body: PresetToJSON(requestParameters.preset), -}, initOverrides); + const response = await this.request({ + path: `/add_preset`, + method: 'POST', + headers: headerParameters, + query: queryParameters, + body: PresetToJSON(requestParameters.preset), + }, initOverrides); -if (this.isJsonMime(response.headers.get('content-type'))) { - return new runtime.JSONApiResponse(response); -} else { - return new runtime.TextApiResponse(response) as any; -} -} + if (this.isJsonMime(response.headers.get('content-type'))) { + return new runtime.JSONApiResponse(response); + } else { + return new runtime.TextApiResponse(response) as any; + } + } -/** + /** * 新しいプリセットを追加します * Add Preset */ -async addPresetAddPresetPost(requestParameters: AddPresetAddPresetPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { -const response = await this.addPresetAddPresetPostRaw(requestParameters, initOverrides); -return await response.value(); -} + async addPresetAddPresetPost(requestParameters: AddPresetAddPresetPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { + const response = await this.addPresetAddPresetPostRaw(requestParameters, initOverrides); + return await response.value(); + } -/** + /** * ユーザー辞書に言葉を追加します。 * Add User Dict Word */ -async addUserDictWordUserDictWordPostRaw(requestParameters: AddUserDictWordUserDictWordPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { -if (requestParameters.surface === null || requestParameters.surface === undefined) { - throw new runtime.RequiredError('surface','Required parameter requestParameters.surface was null or undefined when calling addUserDictWordUserDictWordPost.'); -} + async addUserDictWordUserDictWordPostRaw(requestParameters: AddUserDictWordUserDictWordPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + if (requestParameters.surface === null || requestParameters.surface === undefined) { + throw new runtime.RequiredError('surface','Required parameter requestParameters.surface was null or undefined when calling addUserDictWordUserDictWordPost.'); + } -if (requestParameters.pronunciation === null || requestParameters.pronunciation === undefined) { - throw new runtime.RequiredError('pronunciation','Required parameter requestParameters.pronunciation was null or undefined when calling addUserDictWordUserDictWordPost.'); -} + if (requestParameters.pronunciation === null || requestParameters.pronunciation === undefined) { + throw new runtime.RequiredError('pronunciation','Required parameter requestParameters.pronunciation was null or undefined when calling addUserDictWordUserDictWordPost.'); + } -if (requestParameters.accentType === null || requestParameters.accentType === undefined) { - throw new runtime.RequiredError('accentType','Required parameter requestParameters.accentType was null or undefined when calling addUserDictWordUserDictWordPost.'); -} + if (requestParameters.accentType === null || requestParameters.accentType === undefined) { + throw new runtime.RequiredError('accentType','Required parameter requestParameters.accentType was null or undefined when calling addUserDictWordUserDictWordPost.'); + } -const queryParameters: any = {}; + const queryParameters: any = {}; -if (requestParameters.surface !== undefined) { - queryParameters['surface'] = requestParameters.surface; -} + if (requestParameters.surface !== undefined) { + queryParameters['surface'] = requestParameters.surface; + } -if (requestParameters.pronunciation !== undefined) { - queryParameters['pronunciation'] = requestParameters.pronunciation; -} + if (requestParameters.pronunciation !== undefined) { + queryParameters['pronunciation'] = requestParameters.pronunciation; + } -if (requestParameters.accentType !== undefined) { - queryParameters['accent_type'] = requestParameters.accentType; -} + if (requestParameters.accentType !== undefined) { + queryParameters['accent_type'] = requestParameters.accentType; + } -if (requestParameters.wordType !== undefined) { - queryParameters['word_type'] = requestParameters.wordType; -} + if (requestParameters.wordType !== undefined) { + queryParameters['word_type'] = requestParameters.wordType; + } -if (requestParameters.priority !== undefined) { - queryParameters['priority'] = requestParameters.priority; -} + if (requestParameters.priority !== undefined) { + queryParameters['priority'] = requestParameters.priority; + } -const headerParameters: runtime.HTTPHeaders = {}; + const headerParameters: runtime.HTTPHeaders = {}; -const response = await this.request({ - path: `/user_dict_word`, - method: 'POST', - headers: headerParameters, - query: queryParameters, -}, initOverrides); + const response = await this.request({ + path: `/user_dict_word`, + method: 'POST', + headers: headerParameters, + query: queryParameters, + }, initOverrides); -if (this.isJsonMime(response.headers.get('content-type'))) { - return new runtime.JSONApiResponse(response); -} else { - return new runtime.TextApiResponse(response) as any; -} -} + if (this.isJsonMime(response.headers.get('content-type'))) { + return new runtime.JSONApiResponse(response); + } else { + return new runtime.TextApiResponse(response) as any; + } + } -/** + /** * ユーザー辞書に言葉を追加します。 * Add User Dict Word */ -async addUserDictWordUserDictWordPost(requestParameters: AddUserDictWordUserDictWordPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { -const response = await this.addUserDictWordUserDictWordPostRaw(requestParameters, initOverrides); -return await response.value(); -} + async addUserDictWordUserDictWordPost(requestParameters: AddUserDictWordUserDictWordPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { + const response = await this.addUserDictWordUserDictWordPostRaw(requestParameters, initOverrides); + return await response.value(); + } -/** + /** * 音声合成用のクエリの初期値を得ます。ここで得られたクエリはそのまま音声合成に利用できます。各値の意味は`Schemas`を参照してください。 * 音声合成用のクエリを作成する */ -async audioQueryAudioQueryPostRaw(requestParameters: AudioQueryAudioQueryPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { -if (requestParameters.text === null || requestParameters.text === undefined) { - throw new runtime.RequiredError('text','Required parameter requestParameters.text was null or undefined when calling audioQueryAudioQueryPost.'); -} + async audioQueryAudioQueryPostRaw(requestParameters: AudioQueryAudioQueryPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + if (requestParameters.text === null || requestParameters.text === undefined) { + throw new runtime.RequiredError('text','Required parameter requestParameters.text was null or undefined when calling audioQueryAudioQueryPost.'); + } -if (requestParameters.speaker === null || requestParameters.speaker === undefined) { - throw new runtime.RequiredError('speaker','Required parameter requestParameters.speaker was null or undefined when calling audioQueryAudioQueryPost.'); -} + if (requestParameters.speaker === null || requestParameters.speaker === undefined) { + throw new runtime.RequiredError('speaker','Required parameter requestParameters.speaker was null or undefined when calling audioQueryAudioQueryPost.'); + } -const queryParameters: any = {}; + const queryParameters: any = {}; -if (requestParameters.text !== undefined) { - queryParameters['text'] = requestParameters.text; -} + if (requestParameters.text !== undefined) { + queryParameters['text'] = requestParameters.text; + } -if (requestParameters.speaker !== undefined) { - queryParameters['speaker'] = requestParameters.speaker; -} + if (requestParameters.speaker !== undefined) { + queryParameters['speaker'] = requestParameters.speaker; + } -if (requestParameters.coreVersion !== undefined) { - queryParameters['core_version'] = requestParameters.coreVersion; -} + if (requestParameters.coreVersion !== undefined) { + queryParameters['core_version'] = requestParameters.coreVersion; + } -const headerParameters: runtime.HTTPHeaders = {}; + const headerParameters: runtime.HTTPHeaders = {}; -const response = await this.request({ - path: `/audio_query`, - method: 'POST', - headers: headerParameters, - query: queryParameters, -}, initOverrides); + const response = await this.request({ + path: `/audio_query`, + method: 'POST', + headers: headerParameters, + query: queryParameters, + }, initOverrides); - return new runtime.JSONApiResponse(response, (jsonValue) => AudioQueryFromJSON(jsonValue)); + return new runtime.JSONApiResponse(response, (jsonValue) => AudioQueryFromJSON(jsonValue)); } -/** + /** * 音声合成用のクエリの初期値を得ます。ここで得られたクエリはそのまま音声合成に利用できます。各値の意味は`Schemas`を参照してください。 * 音声合成用のクエリを作成する */ -async audioQueryAudioQueryPost(requestParameters: AudioQueryAudioQueryPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { -const response = await this.audioQueryAudioQueryPostRaw(requestParameters, initOverrides); -return await response.value(); -} + async audioQueryAudioQueryPost(requestParameters: AudioQueryAudioQueryPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { + const response = await this.audioQueryAudioQueryPostRaw(requestParameters, initOverrides); + return await response.value(); + } -/** + /** * 音声合成用のクエリの初期値を得ます。ここで得られたクエリはそのまま音声合成に利用できます。各値の意味は`Schemas`を参照してください。 * 音声合成用のクエリをプリセットを用いて作成する */ -async audioQueryFromPresetAudioQueryFromPresetPostRaw(requestParameters: AudioQueryFromPresetAudioQueryFromPresetPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { -if (requestParameters.text === null || requestParameters.text === undefined) { - throw new runtime.RequiredError('text','Required parameter requestParameters.text was null or undefined when calling audioQueryFromPresetAudioQueryFromPresetPost.'); -} + async audioQueryFromPresetAudioQueryFromPresetPostRaw(requestParameters: AudioQueryFromPresetAudioQueryFromPresetPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + if (requestParameters.text === null || requestParameters.text === undefined) { + throw new runtime.RequiredError('text','Required parameter requestParameters.text was null or undefined when calling audioQueryFromPresetAudioQueryFromPresetPost.'); + } -if (requestParameters.presetId === null || requestParameters.presetId === undefined) { - throw new runtime.RequiredError('presetId','Required parameter requestParameters.presetId was null or undefined when calling audioQueryFromPresetAudioQueryFromPresetPost.'); -} + if (requestParameters.presetId === null || requestParameters.presetId === undefined) { + throw new runtime.RequiredError('presetId','Required parameter requestParameters.presetId was null or undefined when calling audioQueryFromPresetAudioQueryFromPresetPost.'); + } -const queryParameters: any = {}; + const queryParameters: any = {}; -if (requestParameters.text !== undefined) { - queryParameters['text'] = requestParameters.text; -} + if (requestParameters.text !== undefined) { + queryParameters['text'] = requestParameters.text; + } -if (requestParameters.presetId !== undefined) { - queryParameters['preset_id'] = requestParameters.presetId; -} + if (requestParameters.presetId !== undefined) { + queryParameters['preset_id'] = requestParameters.presetId; + } -if (requestParameters.coreVersion !== undefined) { - queryParameters['core_version'] = requestParameters.coreVersion; -} + if (requestParameters.coreVersion !== undefined) { + queryParameters['core_version'] = requestParameters.coreVersion; + } -const headerParameters: runtime.HTTPHeaders = {}; + const headerParameters: runtime.HTTPHeaders = {}; -const response = await this.request({ - path: `/audio_query_from_preset`, - method: 'POST', - headers: headerParameters, - query: queryParameters, -}, initOverrides); + const response = await this.request({ + path: `/audio_query_from_preset`, + method: 'POST', + headers: headerParameters, + query: queryParameters, + }, initOverrides); - return new runtime.JSONApiResponse(response, (jsonValue) => AudioQueryFromJSON(jsonValue)); + return new runtime.JSONApiResponse(response, (jsonValue) => AudioQueryFromJSON(jsonValue)); } -/** + /** * 音声合成用のクエリの初期値を得ます。ここで得られたクエリはそのまま音声合成に利用できます。各値の意味は`Schemas`を参照してください。 * 音声合成用のクエリをプリセットを用いて作成する */ -async audioQueryFromPresetAudioQueryFromPresetPost(requestParameters: AudioQueryFromPresetAudioQueryFromPresetPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { -const response = await this.audioQueryFromPresetAudioQueryFromPresetPostRaw(requestParameters, initOverrides); -return await response.value(); -} + async audioQueryFromPresetAudioQueryFromPresetPost(requestParameters: AudioQueryFromPresetAudioQueryFromPresetPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { + const response = await this.audioQueryFromPresetAudioQueryFromPresetPostRaw(requestParameters, initOverrides); + return await response.value(); + } -/** + /** * 音声合成する(キャンセル可能) */ -async cancellableSynthesisCancellableSynthesisPostRaw(requestParameters: CancellableSynthesisCancellableSynthesisPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { -if (requestParameters.speaker === null || requestParameters.speaker === undefined) { - throw new runtime.RequiredError('speaker','Required parameter requestParameters.speaker was null or undefined when calling cancellableSynthesisCancellableSynthesisPost.'); -} + async cancellableSynthesisCancellableSynthesisPostRaw(requestParameters: CancellableSynthesisCancellableSynthesisPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + if (requestParameters.speaker === null || requestParameters.speaker === undefined) { + throw new runtime.RequiredError('speaker','Required parameter requestParameters.speaker was null or undefined when calling cancellableSynthesisCancellableSynthesisPost.'); + } -if (requestParameters.audioQuery === null || requestParameters.audioQuery === undefined) { - throw new runtime.RequiredError('audioQuery','Required parameter requestParameters.audioQuery was null or undefined when calling cancellableSynthesisCancellableSynthesisPost.'); -} + if (requestParameters.audioQuery === null || requestParameters.audioQuery === undefined) { + throw new runtime.RequiredError('audioQuery','Required parameter requestParameters.audioQuery was null or undefined when calling cancellableSynthesisCancellableSynthesisPost.'); + } -const queryParameters: any = {}; + const queryParameters: any = {}; -if (requestParameters.speaker !== undefined) { - queryParameters['speaker'] = requestParameters.speaker; -} + if (requestParameters.speaker !== undefined) { + queryParameters['speaker'] = requestParameters.speaker; + } -if (requestParameters.coreVersion !== undefined) { - queryParameters['core_version'] = requestParameters.coreVersion; -} + if (requestParameters.coreVersion !== undefined) { + queryParameters['core_version'] = requestParameters.coreVersion; + } -const headerParameters: runtime.HTTPHeaders = {}; + const headerParameters: runtime.HTTPHeaders = {}; -headerParameters['Content-Type'] = 'application/json'; + headerParameters['Content-Type'] = 'application/json'; -const response = await this.request({ - path: `/cancellable_synthesis`, - method: 'POST', - headers: headerParameters, - query: queryParameters, - body: AudioQueryToJSON(requestParameters.audioQuery), -}, initOverrides); + const response = await this.request({ + path: `/cancellable_synthesis`, + method: 'POST', + headers: headerParameters, + query: queryParameters, + body: AudioQueryToJSON(requestParameters.audioQuery), + }, initOverrides); - return new runtime.BlobApiResponse(response); + return new runtime.BlobApiResponse(response); } -/** + /** * 音声合成する(キャンセル可能) */ -async cancellableSynthesisCancellableSynthesisPost(requestParameters: CancellableSynthesisCancellableSynthesisPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { -const response = await this.cancellableSynthesisCancellableSynthesisPostRaw(requestParameters, initOverrides); -return await response.value(); -} + async cancellableSynthesisCancellableSynthesisPost(requestParameters: CancellableSynthesisCancellableSynthesisPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { + const response = await this.cancellableSynthesisCancellableSynthesisPostRaw(requestParameters, initOverrides); + return await response.value(); + } -/** + /** * base64エンコードされたwavデータを一纏めにし、wavファイルで返します。 * base64エンコードされた複数のwavデータを一つに結合する */ -async connectWavesConnectWavesPostRaw(requestParameters: ConnectWavesConnectWavesPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { -if (requestParameters.requestBody === null || requestParameters.requestBody === undefined) { - throw new runtime.RequiredError('requestBody','Required parameter requestParameters.requestBody was null or undefined when calling connectWavesConnectWavesPost.'); -} + async connectWavesConnectWavesPostRaw(requestParameters: ConnectWavesConnectWavesPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + if (requestParameters.requestBody === null || requestParameters.requestBody === undefined) { + throw new runtime.RequiredError('requestBody','Required parameter requestParameters.requestBody was null or undefined when calling connectWavesConnectWavesPost.'); + } -const queryParameters: any = {}; + const queryParameters: any = {}; -const headerParameters: runtime.HTTPHeaders = {}; + const headerParameters: runtime.HTTPHeaders = {}; -headerParameters['Content-Type'] = 'application/json'; + headerParameters['Content-Type'] = 'application/json'; -const response = await this.request({ - path: `/connect_waves`, - method: 'POST', - headers: headerParameters, - query: queryParameters, - body: requestParameters.requestBody, -}, initOverrides); + const response = await this.request({ + path: `/connect_waves`, + method: 'POST', + headers: headerParameters, + query: queryParameters, + body: requestParameters.requestBody, + }, initOverrides); - return new runtime.BlobApiResponse(response); + return new runtime.BlobApiResponse(response); } -/** + /** * base64エンコードされたwavデータを一纏めにし、wavファイルで返します。 * base64エンコードされた複数のwavデータを一つに結合する */ -async connectWavesConnectWavesPost(requestParameters: ConnectWavesConnectWavesPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { -const response = await this.connectWavesConnectWavesPostRaw(requestParameters, initOverrides); -return await response.value(); -} + async connectWavesConnectWavesPost(requestParameters: ConnectWavesConnectWavesPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { + const response = await this.connectWavesConnectWavesPostRaw(requestParameters, initOverrides); + return await response.value(); + } -/** + /** * Core Versions */ -async coreVersionsCoreVersionsGetRaw(initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>> { -const queryParameters: any = {}; + async coreVersionsCoreVersionsGetRaw(initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>> { + const queryParameters: any = {}; -const headerParameters: runtime.HTTPHeaders = {}; + const headerParameters: runtime.HTTPHeaders = {}; -const response = await this.request({ - path: `/core_versions`, - method: 'GET', - headers: headerParameters, - query: queryParameters, -}, initOverrides); + const response = await this.request({ + path: `/core_versions`, + method: 'GET', + headers: headerParameters, + query: queryParameters, + }, initOverrides); - return new runtime.JSONApiResponse(response); + return new runtime.JSONApiResponse(response); } -/** + /** * Core Versions */ -async coreVersionsCoreVersionsGet(initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { -const response = await this.coreVersionsCoreVersionsGetRaw(initOverrides); -return await response.value(); -} + async coreVersionsCoreVersionsGet(initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + const response = await this.coreVersionsCoreVersionsGetRaw(initOverrides); + return await response.value(); + } -/** + /** * 既存のプリセットを削除します * Delete Preset */ -async deletePresetDeletePresetPostRaw(requestParameters: DeletePresetDeletePresetPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { -if (requestParameters.id === null || requestParameters.id === undefined) { - throw new runtime.RequiredError('id','Required parameter requestParameters.id was null or undefined when calling deletePresetDeletePresetPost.'); -} + async deletePresetDeletePresetPostRaw(requestParameters: DeletePresetDeletePresetPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + if (requestParameters.id === null || requestParameters.id === undefined) { + throw new runtime.RequiredError('id','Required parameter requestParameters.id was null or undefined when calling deletePresetDeletePresetPost.'); + } -const queryParameters: any = {}; + const queryParameters: any = {}; -if (requestParameters.id !== undefined) { - queryParameters['id'] = requestParameters.id; -} + if (requestParameters.id !== undefined) { + queryParameters['id'] = requestParameters.id; + } -const headerParameters: runtime.HTTPHeaders = {}; + const headerParameters: runtime.HTTPHeaders = {}; -const response = await this.request({ - path: `/delete_preset`, - method: 'POST', - headers: headerParameters, - query: queryParameters, -}, initOverrides); + const response = await this.request({ + path: `/delete_preset`, + method: 'POST', + headers: headerParameters, + query: queryParameters, + }, initOverrides); - return new runtime.VoidApiResponse(response); + return new runtime.VoidApiResponse(response); } -/** + /** * 既存のプリセットを削除します * Delete Preset */ -async deletePresetDeletePresetPost(requestParameters: DeletePresetDeletePresetPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { - await this.deletePresetDeletePresetPostRaw(requestParameters, initOverrides); -} + async deletePresetDeletePresetPost(requestParameters: DeletePresetDeletePresetPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { + await this.deletePresetDeletePresetPostRaw(requestParameters, initOverrides); + } -/** + /** * ユーザー辞書に登録されている言葉を削除します。 * Delete User Dict Word */ -async deleteUserDictWordUserDictWordWordUuidDeleteRaw(requestParameters: DeleteUserDictWordUserDictWordWordUuidDeleteRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { -if (requestParameters.wordUuid === null || requestParameters.wordUuid === undefined) { - throw new runtime.RequiredError('wordUuid','Required parameter requestParameters.wordUuid was null or undefined when calling deleteUserDictWordUserDictWordWordUuidDelete.'); -} + async deleteUserDictWordUserDictWordWordUuidDeleteRaw(requestParameters: DeleteUserDictWordUserDictWordWordUuidDeleteRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + if (requestParameters.wordUuid === null || requestParameters.wordUuid === undefined) { + throw new runtime.RequiredError('wordUuid','Required parameter requestParameters.wordUuid was null or undefined when calling deleteUserDictWordUserDictWordWordUuidDelete.'); + } -const queryParameters: any = {}; + const queryParameters: any = {}; -const headerParameters: runtime.HTTPHeaders = {}; + const headerParameters: runtime.HTTPHeaders = {}; -const response = await this.request({ - path: `/user_dict_word/{word_uuid}`.replace(`{${"word_uuid"}}`, encodeURIComponent(String(requestParameters.wordUuid))), - method: 'DELETE', - headers: headerParameters, - query: queryParameters, -}, initOverrides); + const response = await this.request({ + path: `/user_dict_word/{word_uuid}`.replace(`{${"word_uuid"}}`, encodeURIComponent(String(requestParameters.wordUuid))), + method: 'DELETE', + headers: headerParameters, + query: queryParameters, + }, initOverrides); - return new runtime.VoidApiResponse(response); + return new runtime.VoidApiResponse(response); } -/** + /** * ユーザー辞書に登録されている言葉を削除します。 * Delete User Dict Word */ -async deleteUserDictWordUserDictWordWordUuidDelete(requestParameters: DeleteUserDictWordUserDictWordWordUuidDeleteRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { - await this.deleteUserDictWordUserDictWordWordUuidDeleteRaw(requestParameters, initOverrides); -} + async deleteUserDictWordUserDictWordWordUuidDelete(requestParameters: DeleteUserDictWordUserDictWordWordUuidDeleteRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { + await this.deleteUserDictWordUserDictWordWordUuidDeleteRaw(requestParameters, initOverrides); + } -/** + /** * ダウンロード可能な音声ライブラリの情報を返します。 * Downloadable Libraries */ -async downloadableLibrariesDownloadableLibrariesGetRaw(initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>> { -const queryParameters: any = {}; + async downloadableLibrariesDownloadableLibrariesGetRaw(initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>> { + const queryParameters: any = {}; -const headerParameters: runtime.HTTPHeaders = {}; + const headerParameters: runtime.HTTPHeaders = {}; -const response = await this.request({ - path: `/downloadable_libraries`, - method: 'GET', - headers: headerParameters, - query: queryParameters, -}, initOverrides); + const response = await this.request({ + path: `/downloadable_libraries`, + method: 'GET', + headers: headerParameters, + query: queryParameters, + }, initOverrides); - return new runtime.JSONApiResponse(response, (jsonValue) => jsonValue.map(DownloadableLibraryInfoFromJSON)); + return new runtime.JSONApiResponse(response, (jsonValue) => jsonValue.map(DownloadableLibraryInfoFromJSON)); } -/** + /** * ダウンロード可能な音声ライブラリの情報を返します。 * Downloadable Libraries */ -async downloadableLibrariesDownloadableLibrariesGet(initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { -const response = await this.downloadableLibrariesDownloadableLibrariesGetRaw(initOverrides); -return await response.value(); -} + async downloadableLibrariesDownloadableLibrariesGet(initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + const response = await this.downloadableLibrariesDownloadableLibrariesGetRaw(initOverrides); + return await response.value(); + } -/** + /** * Engine Manifest */ -async engineManifestEngineManifestGetRaw(initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { -const queryParameters: any = {}; + async engineManifestEngineManifestGetRaw(initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + const queryParameters: any = {}; -const headerParameters: runtime.HTTPHeaders = {}; + const headerParameters: runtime.HTTPHeaders = {}; -const response = await this.request({ - path: `/engine_manifest`, - method: 'GET', - headers: headerParameters, - query: queryParameters, -}, initOverrides); + const response = await this.request({ + path: `/engine_manifest`, + method: 'GET', + headers: headerParameters, + query: queryParameters, + }, initOverrides); - return new runtime.JSONApiResponse(response, (jsonValue) => EngineManifestFromJSON(jsonValue)); + return new runtime.JSONApiResponse(response, (jsonValue) => EngineManifestFromJSON(jsonValue)); } -/** + /** * Engine Manifest */ -async engineManifestEngineManifestGet(initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { -const response = await this.engineManifestEngineManifestGetRaw(initOverrides); -return await response.value(); -} + async engineManifestEngineManifestGet(initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { + const response = await this.engineManifestEngineManifestGetRaw(initOverrides); + return await response.value(); + } -/** + /** * 歌唱音声合成を行います。 * Frame Synthesis */ -async frameSynthesisFrameSynthesisPostRaw(requestParameters: FrameSynthesisFrameSynthesisPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { -if (requestParameters.speaker === null || requestParameters.speaker === undefined) { - throw new runtime.RequiredError('speaker','Required parameter requestParameters.speaker was null or undefined when calling frameSynthesisFrameSynthesisPost.'); -} + async frameSynthesisFrameSynthesisPostRaw(requestParameters: FrameSynthesisFrameSynthesisPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + if (requestParameters.speaker === null || requestParameters.speaker === undefined) { + throw new runtime.RequiredError('speaker','Required parameter requestParameters.speaker was null or undefined when calling frameSynthesisFrameSynthesisPost.'); + } -if (requestParameters.frameAudioQuery === null || requestParameters.frameAudioQuery === undefined) { - throw new runtime.RequiredError('frameAudioQuery','Required parameter requestParameters.frameAudioQuery was null or undefined when calling frameSynthesisFrameSynthesisPost.'); -} + if (requestParameters.frameAudioQuery === null || requestParameters.frameAudioQuery === undefined) { + throw new runtime.RequiredError('frameAudioQuery','Required parameter requestParameters.frameAudioQuery was null or undefined when calling frameSynthesisFrameSynthesisPost.'); + } -const queryParameters: any = {}; + const queryParameters: any = {}; -if (requestParameters.speaker !== undefined) { - queryParameters['speaker'] = requestParameters.speaker; -} + if (requestParameters.speaker !== undefined) { + queryParameters['speaker'] = requestParameters.speaker; + } -if (requestParameters.coreVersion !== undefined) { - queryParameters['core_version'] = requestParameters.coreVersion; -} + if (requestParameters.coreVersion !== undefined) { + queryParameters['core_version'] = requestParameters.coreVersion; + } -const headerParameters: runtime.HTTPHeaders = {}; + const headerParameters: runtime.HTTPHeaders = {}; -headerParameters['Content-Type'] = 'application/json'; + headerParameters['Content-Type'] = 'application/json'; -const response = await this.request({ - path: `/frame_synthesis`, - method: 'POST', - headers: headerParameters, - query: queryParameters, - body: FrameAudioQueryToJSON(requestParameters.frameAudioQuery), -}, initOverrides); + const response = await this.request({ + path: `/frame_synthesis`, + method: 'POST', + headers: headerParameters, + query: queryParameters, + body: FrameAudioQueryToJSON(requestParameters.frameAudioQuery), + }, initOverrides); - return new runtime.BlobApiResponse(response); + return new runtime.BlobApiResponse(response); } -/** + /** * 歌唱音声合成を行います。 * Frame Synthesis */ -async frameSynthesisFrameSynthesisPost(requestParameters: FrameSynthesisFrameSynthesisPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { -const response = await this.frameSynthesisFrameSynthesisPostRaw(requestParameters, initOverrides); -return await response.value(); -} + async frameSynthesisFrameSynthesisPost(requestParameters: FrameSynthesisFrameSynthesisPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { + const response = await this.frameSynthesisFrameSynthesisPostRaw(requestParameters, initOverrides); + return await response.value(); + } -/** + /** * エンジンが保持しているプリセットの設定を返します * Get Presets */ -async getPresetsPresetsGetRaw(initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>> { -const queryParameters: any = {}; + async getPresetsPresetsGetRaw(initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>> { + const queryParameters: any = {}; -const headerParameters: runtime.HTTPHeaders = {}; + const headerParameters: runtime.HTTPHeaders = {}; -const response = await this.request({ - path: `/presets`, - method: 'GET', - headers: headerParameters, - query: queryParameters, -}, initOverrides); + const response = await this.request({ + path: `/presets`, + method: 'GET', + headers: headerParameters, + query: queryParameters, + }, initOverrides); - return new runtime.JSONApiResponse(response, (jsonValue) => jsonValue.map(PresetFromJSON)); + return new runtime.JSONApiResponse(response, (jsonValue) => jsonValue.map(PresetFromJSON)); } -/** + /** * エンジンが保持しているプリセットの設定を返します * Get Presets */ -async getPresetsPresetsGet(initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { -const response = await this.getPresetsPresetsGetRaw(initOverrides); -return await response.value(); -} + async getPresetsPresetsGet(initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + const response = await this.getPresetsPresetsGetRaw(initOverrides); + return await response.value(); + } -/** + /** * ユーザー辞書に登録されている単語の一覧を返します。 単語の表層形(surface)は正規化済みの物を返します。 * Get User Dict Words */ -async getUserDictWordsUserDictGetRaw(initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { -const queryParameters: any = {}; + async getUserDictWordsUserDictGetRaw(initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + const queryParameters: any = {}; -const headerParameters: runtime.HTTPHeaders = {}; + const headerParameters: runtime.HTTPHeaders = {}; -const response = await this.request({ - path: `/user_dict`, - method: 'GET', - headers: headerParameters, - query: queryParameters, -}, initOverrides); + const response = await this.request({ + path: `/user_dict`, + method: 'GET', + headers: headerParameters, + query: queryParameters, + }, initOverrides); - return new runtime.JSONApiResponse(response, (jsonValue) => runtime.mapValues(jsonValue, UserDictWordFromJSON)); + return new runtime.JSONApiResponse(response, (jsonValue) => runtime.mapValues(jsonValue, UserDictWordFromJSON)); } -/** + /** * ユーザー辞書に登録されている単語の一覧を返します。 単語の表層形(surface)は正規化済みの物を返します。 * Get User Dict Words */ -async getUserDictWordsUserDictGet(initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise<{ [key: string]: UserDictWord; }> { - const response = await this.getUserDictWordsUserDictGetRaw(initOverrides); - return await response.value(); -} + async getUserDictWordsUserDictGet(initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise<{ [key: string]: UserDictWord; }> { + const response = await this.getUserDictWordsUserDictGetRaw(initOverrides); + return await response.value(); + } -/** + /** * 他のユーザー辞書をインポートします。 * Import User Dict Words */ -async importUserDictWordsImportUserDictPostRaw(requestParameters: ImportUserDictWordsImportUserDictPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { -if (requestParameters.override === null || requestParameters.override === undefined) { - throw new runtime.RequiredError('override','Required parameter requestParameters.override was null or undefined when calling importUserDictWordsImportUserDictPost.'); -} + async importUserDictWordsImportUserDictPostRaw(requestParameters: ImportUserDictWordsImportUserDictPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + if (requestParameters.override === null || requestParameters.override === undefined) { + throw new runtime.RequiredError('override','Required parameter requestParameters.override was null or undefined when calling importUserDictWordsImportUserDictPost.'); + } -if (requestParameters.requestBody === null || requestParameters.requestBody === undefined) { - throw new runtime.RequiredError('requestBody','Required parameter requestParameters.requestBody was null or undefined when calling importUserDictWordsImportUserDictPost.'); -} + if (requestParameters.requestBody === null || requestParameters.requestBody === undefined) { + throw new runtime.RequiredError('requestBody','Required parameter requestParameters.requestBody was null or undefined when calling importUserDictWordsImportUserDictPost.'); + } -const queryParameters: any = {}; + const queryParameters: any = {}; -if (requestParameters.override !== undefined) { - queryParameters['override'] = requestParameters.override; -} + if (requestParameters.override !== undefined) { + queryParameters['override'] = requestParameters.override; + } -const headerParameters: runtime.HTTPHeaders = {}; + const headerParameters: runtime.HTTPHeaders = {}; -headerParameters['Content-Type'] = 'application/json'; + headerParameters['Content-Type'] = 'application/json'; -const response = await this.request({ - path: `/import_user_dict`, - method: 'POST', - headers: headerParameters, - query: queryParameters, - body: requestParameters.requestBody, -}, initOverrides); + const response = await this.request({ + path: `/import_user_dict`, + method: 'POST', + headers: headerParameters, + query: queryParameters, + body: requestParameters.requestBody, + }, initOverrides); - return new runtime.VoidApiResponse(response); + return new runtime.VoidApiResponse(response); } -/** + /** * 他のユーザー辞書をインポートします。 * Import User Dict Words */ -async importUserDictWordsImportUserDictPost(requestParameters: ImportUserDictWordsImportUserDictPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { - await this.importUserDictWordsImportUserDictPostRaw(requestParameters, initOverrides); -} + async importUserDictWordsImportUserDictPost(requestParameters: ImportUserDictWordsImportUserDictPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { + await this.importUserDictWordsImportUserDictPostRaw(requestParameters, initOverrides); + } -/** + /** * 指定されたスタイルを初期化します。 実行しなくても他のAPIは使用できますが、初回実行時に時間がかかることがあります。 * Initialize Speaker */ -async initializeSpeakerInitializeSpeakerPostRaw(requestParameters: InitializeSpeakerInitializeSpeakerPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { -if (requestParameters.speaker === null || requestParameters.speaker === undefined) { - throw new runtime.RequiredError('speaker','Required parameter requestParameters.speaker was null or undefined when calling initializeSpeakerInitializeSpeakerPost.'); -} + async initializeSpeakerInitializeSpeakerPostRaw(requestParameters: InitializeSpeakerInitializeSpeakerPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + if (requestParameters.speaker === null || requestParameters.speaker === undefined) { + throw new runtime.RequiredError('speaker','Required parameter requestParameters.speaker was null or undefined when calling initializeSpeakerInitializeSpeakerPost.'); + } -const queryParameters: any = {}; + const queryParameters: any = {}; -if (requestParameters.speaker !== undefined) { - queryParameters['speaker'] = requestParameters.speaker; -} + if (requestParameters.speaker !== undefined) { + queryParameters['speaker'] = requestParameters.speaker; + } -if (requestParameters.skipReinit !== undefined) { - queryParameters['skip_reinit'] = requestParameters.skipReinit; -} + if (requestParameters.skipReinit !== undefined) { + queryParameters['skip_reinit'] = requestParameters.skipReinit; + } -if (requestParameters.coreVersion !== undefined) { - queryParameters['core_version'] = requestParameters.coreVersion; -} + if (requestParameters.coreVersion !== undefined) { + queryParameters['core_version'] = requestParameters.coreVersion; + } -const headerParameters: runtime.HTTPHeaders = {}; + const headerParameters: runtime.HTTPHeaders = {}; -const response = await this.request({ - path: `/initialize_speaker`, - method: 'POST', - headers: headerParameters, - query: queryParameters, -}, initOverrides); + const response = await this.request({ + path: `/initialize_speaker`, + method: 'POST', + headers: headerParameters, + query: queryParameters, + }, initOverrides); - return new runtime.VoidApiResponse(response); + return new runtime.VoidApiResponse(response); } -/** + /** * 指定されたスタイルを初期化します。 実行しなくても他のAPIは使用できますが、初回実行時に時間がかかることがあります。 * Initialize Speaker */ -async initializeSpeakerInitializeSpeakerPost(requestParameters: InitializeSpeakerInitializeSpeakerPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { - await this.initializeSpeakerInitializeSpeakerPostRaw(requestParameters, initOverrides); -} + async initializeSpeakerInitializeSpeakerPost(requestParameters: InitializeSpeakerInitializeSpeakerPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { + await this.initializeSpeakerInitializeSpeakerPostRaw(requestParameters, initOverrides); + } -/** + /** * 音声ライブラリをインストールします。 音声ライブラリのZIPファイルをリクエストボディとして送信してください。 * Install Library */ -async installLibraryInstallLibraryLibraryUuidPostRaw(requestParameters: InstallLibraryInstallLibraryLibraryUuidPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { -if (requestParameters.libraryUuid === null || requestParameters.libraryUuid === undefined) { - throw new runtime.RequiredError('libraryUuid','Required parameter requestParameters.libraryUuid was null or undefined when calling installLibraryInstallLibraryLibraryUuidPost.'); -} + async installLibraryInstallLibraryLibraryUuidPostRaw(requestParameters: InstallLibraryInstallLibraryLibraryUuidPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + if (requestParameters.libraryUuid === null || requestParameters.libraryUuid === undefined) { + throw new runtime.RequiredError('libraryUuid','Required parameter requestParameters.libraryUuid was null or undefined when calling installLibraryInstallLibraryLibraryUuidPost.'); + } -const queryParameters: any = {}; + const queryParameters: any = {}; -const headerParameters: runtime.HTTPHeaders = {}; + const headerParameters: runtime.HTTPHeaders = {}; -const response = await this.request({ - path: `/install_library/{library_uuid}`.replace(`{${"library_uuid"}}`, encodeURIComponent(String(requestParameters.libraryUuid))), - method: 'POST', - headers: headerParameters, - query: queryParameters, -}, initOverrides); + const response = await this.request({ + path: `/install_library/{library_uuid}`.replace(`{${"library_uuid"}}`, encodeURIComponent(String(requestParameters.libraryUuid))), + method: 'POST', + headers: headerParameters, + query: queryParameters, + }, initOverrides); - return new runtime.VoidApiResponse(response); + return new runtime.VoidApiResponse(response); } -/** + /** * 音声ライブラリをインストールします。 音声ライブラリのZIPファイルをリクエストボディとして送信してください。 * Install Library */ -async installLibraryInstallLibraryLibraryUuidPost(requestParameters: InstallLibraryInstallLibraryLibraryUuidPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { - await this.installLibraryInstallLibraryLibraryUuidPostRaw(requestParameters, initOverrides); -} + async installLibraryInstallLibraryLibraryUuidPost(requestParameters: InstallLibraryInstallLibraryLibraryUuidPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { + await this.installLibraryInstallLibraryLibraryUuidPostRaw(requestParameters, initOverrides); + } -/** + /** * インストールした音声ライブラリの情報を返します。 * Installed Libraries */ -async installedLibrariesInstalledLibrariesGetRaw(initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { -const queryParameters: any = {}; + async installedLibrariesInstalledLibrariesGetRaw(initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + const queryParameters: any = {}; -const headerParameters: runtime.HTTPHeaders = {}; + const headerParameters: runtime.HTTPHeaders = {}; -const response = await this.request({ - path: `/installed_libraries`, - method: 'GET', - headers: headerParameters, - query: queryParameters, -}, initOverrides); + const response = await this.request({ + path: `/installed_libraries`, + method: 'GET', + headers: headerParameters, + query: queryParameters, + }, initOverrides); - return new runtime.JSONApiResponse(response, (jsonValue) => runtime.mapValues(jsonValue, InstalledLibraryInfoFromJSON)); + return new runtime.JSONApiResponse(response, (jsonValue) => runtime.mapValues(jsonValue, InstalledLibraryInfoFromJSON)); } -/** + /** * インストールした音声ライブラリの情報を返します。 * Installed Libraries */ -async installedLibrariesInstalledLibrariesGet(initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise<{ [key: string]: InstalledLibraryInfo; }> { - const response = await this.installedLibrariesInstalledLibrariesGetRaw(initOverrides); - return await response.value(); -} + async installedLibrariesInstalledLibrariesGet(initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise<{ [key: string]: InstalledLibraryInfo; }> { + const response = await this.installedLibrariesInstalledLibrariesGetRaw(initOverrides); + return await response.value(); + } -/** + /** * 指定されたスタイルが初期化されているかどうかを返します。 * Is Initialized Speaker */ -async isInitializedSpeakerIsInitializedSpeakerGetRaw(requestParameters: IsInitializedSpeakerIsInitializedSpeakerGetRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { -if (requestParameters.speaker === null || requestParameters.speaker === undefined) { - throw new runtime.RequiredError('speaker','Required parameter requestParameters.speaker was null or undefined when calling isInitializedSpeakerIsInitializedSpeakerGet.'); -} + async isInitializedSpeakerIsInitializedSpeakerGetRaw(requestParameters: IsInitializedSpeakerIsInitializedSpeakerGetRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + if (requestParameters.speaker === null || requestParameters.speaker === undefined) { + throw new runtime.RequiredError('speaker','Required parameter requestParameters.speaker was null or undefined when calling isInitializedSpeakerIsInitializedSpeakerGet.'); + } -const queryParameters: any = {}; + const queryParameters: any = {}; -if (requestParameters.speaker !== undefined) { - queryParameters['speaker'] = requestParameters.speaker; -} + if (requestParameters.speaker !== undefined) { + queryParameters['speaker'] = requestParameters.speaker; + } -if (requestParameters.coreVersion !== undefined) { - queryParameters['core_version'] = requestParameters.coreVersion; -} + if (requestParameters.coreVersion !== undefined) { + queryParameters['core_version'] = requestParameters.coreVersion; + } -const headerParameters: runtime.HTTPHeaders = {}; + const headerParameters: runtime.HTTPHeaders = {}; -const response = await this.request({ - path: `/is_initialized_speaker`, - method: 'GET', - headers: headerParameters, - query: queryParameters, -}, initOverrides); + const response = await this.request({ + path: `/is_initialized_speaker`, + method: 'GET', + headers: headerParameters, + query: queryParameters, + }, initOverrides); -if (this.isJsonMime(response.headers.get('content-type'))) { - return new runtime.JSONApiResponse(response); -} else { - return new runtime.TextApiResponse(response) as any; -} -} + if (this.isJsonMime(response.headers.get('content-type'))) { + return new runtime.JSONApiResponse(response); + } else { + return new runtime.TextApiResponse(response) as any; + } + } -/** + /** * 指定されたスタイルが初期化されているかどうかを返します。 * Is Initialized Speaker */ -async isInitializedSpeakerIsInitializedSpeakerGet(requestParameters: IsInitializedSpeakerIsInitializedSpeakerGetRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { -const response = await this.isInitializedSpeakerIsInitializedSpeakerGetRaw(requestParameters, initOverrides); -return await response.value(); -} + async isInitializedSpeakerIsInitializedSpeakerGet(requestParameters: IsInitializedSpeakerIsInitializedSpeakerGetRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { + const response = await this.isInitializedSpeakerIsInitializedSpeakerGetRaw(requestParameters, initOverrides); + return await response.value(); + } -/** + /** * アクセント句から音高・音素長を得る */ -async moraDataMoraDataPostRaw(requestParameters: MoraDataMoraDataPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>> { -if (requestParameters.speaker === null || requestParameters.speaker === undefined) { - throw new runtime.RequiredError('speaker','Required parameter requestParameters.speaker was null or undefined when calling moraDataMoraDataPost.'); -} + async moraDataMoraDataPostRaw(requestParameters: MoraDataMoraDataPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>> { + if (requestParameters.speaker === null || requestParameters.speaker === undefined) { + throw new runtime.RequiredError('speaker','Required parameter requestParameters.speaker was null or undefined when calling moraDataMoraDataPost.'); + } -if (requestParameters.accentPhrase === null || requestParameters.accentPhrase === undefined) { - throw new runtime.RequiredError('accentPhrase','Required parameter requestParameters.accentPhrase was null or undefined when calling moraDataMoraDataPost.'); -} + if (requestParameters.accentPhrase === null || requestParameters.accentPhrase === undefined) { + throw new runtime.RequiredError('accentPhrase','Required parameter requestParameters.accentPhrase was null or undefined when calling moraDataMoraDataPost.'); + } -const queryParameters: any = {}; + const queryParameters: any = {}; -if (requestParameters.speaker !== undefined) { - queryParameters['speaker'] = requestParameters.speaker; -} + if (requestParameters.speaker !== undefined) { + queryParameters['speaker'] = requestParameters.speaker; + } -if (requestParameters.coreVersion !== undefined) { - queryParameters['core_version'] = requestParameters.coreVersion; -} + if (requestParameters.coreVersion !== undefined) { + queryParameters['core_version'] = requestParameters.coreVersion; + } -const headerParameters: runtime.HTTPHeaders = {}; + const headerParameters: runtime.HTTPHeaders = {}; -headerParameters['Content-Type'] = 'application/json'; + headerParameters['Content-Type'] = 'application/json'; -const response = await this.request({ - path: `/mora_data`, - method: 'POST', - headers: headerParameters, - query: queryParameters, - body: requestParameters.accentPhrase.map(AccentPhraseToJSON), -}, initOverrides); + const response = await this.request({ + path: `/mora_data`, + method: 'POST', + headers: headerParameters, + query: queryParameters, + body: requestParameters.accentPhrase.map(AccentPhraseToJSON), + }, initOverrides); - return new runtime.JSONApiResponse(response, (jsonValue) => jsonValue.map(AccentPhraseFromJSON)); + return new runtime.JSONApiResponse(response, (jsonValue) => jsonValue.map(AccentPhraseFromJSON)); } -/** + /** * アクセント句から音高・音素長を得る */ -async moraDataMoraDataPost(requestParameters: MoraDataMoraDataPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { -const response = await this.moraDataMoraDataPostRaw(requestParameters, initOverrides); -return await response.value(); -} + async moraDataMoraDataPost(requestParameters: MoraDataMoraDataPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + const response = await this.moraDataMoraDataPostRaw(requestParameters, initOverrides); + return await response.value(); + } -/** + /** * アクセント句から音素長を得る */ -async moraLengthMoraLengthPostRaw(requestParameters: MoraLengthMoraLengthPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>> { -if (requestParameters.speaker === null || requestParameters.speaker === undefined) { - throw new runtime.RequiredError('speaker','Required parameter requestParameters.speaker was null or undefined when calling moraLengthMoraLengthPost.'); -} + async moraLengthMoraLengthPostRaw(requestParameters: MoraLengthMoraLengthPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>> { + if (requestParameters.speaker === null || requestParameters.speaker === undefined) { + throw new runtime.RequiredError('speaker','Required parameter requestParameters.speaker was null or undefined when calling moraLengthMoraLengthPost.'); + } -if (requestParameters.accentPhrase === null || requestParameters.accentPhrase === undefined) { - throw new runtime.RequiredError('accentPhrase','Required parameter requestParameters.accentPhrase was null or undefined when calling moraLengthMoraLengthPost.'); -} + if (requestParameters.accentPhrase === null || requestParameters.accentPhrase === undefined) { + throw new runtime.RequiredError('accentPhrase','Required parameter requestParameters.accentPhrase was null or undefined when calling moraLengthMoraLengthPost.'); + } -const queryParameters: any = {}; + const queryParameters: any = {}; -if (requestParameters.speaker !== undefined) { - queryParameters['speaker'] = requestParameters.speaker; -} + if (requestParameters.speaker !== undefined) { + queryParameters['speaker'] = requestParameters.speaker; + } -if (requestParameters.coreVersion !== undefined) { - queryParameters['core_version'] = requestParameters.coreVersion; -} + if (requestParameters.coreVersion !== undefined) { + queryParameters['core_version'] = requestParameters.coreVersion; + } -const headerParameters: runtime.HTTPHeaders = {}; + const headerParameters: runtime.HTTPHeaders = {}; -headerParameters['Content-Type'] = 'application/json'; + headerParameters['Content-Type'] = 'application/json'; -const response = await this.request({ - path: `/mora_length`, - method: 'POST', - headers: headerParameters, - query: queryParameters, - body: requestParameters.accentPhrase.map(AccentPhraseToJSON), -}, initOverrides); + const response = await this.request({ + path: `/mora_length`, + method: 'POST', + headers: headerParameters, + query: queryParameters, + body: requestParameters.accentPhrase.map(AccentPhraseToJSON), + }, initOverrides); - return new runtime.JSONApiResponse(response, (jsonValue) => jsonValue.map(AccentPhraseFromJSON)); + return new runtime.JSONApiResponse(response, (jsonValue) => jsonValue.map(AccentPhraseFromJSON)); } -/** + /** * アクセント句から音素長を得る */ -async moraLengthMoraLengthPost(requestParameters: MoraLengthMoraLengthPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { -const response = await this.moraLengthMoraLengthPostRaw(requestParameters, initOverrides); -return await response.value(); -} + async moraLengthMoraLengthPost(requestParameters: MoraLengthMoraLengthPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + const response = await this.moraLengthMoraLengthPostRaw(requestParameters, initOverrides); + return await response.value(); + } -/** + /** * アクセント句から音高を得る */ -async moraPitchMoraPitchPostRaw(requestParameters: MoraPitchMoraPitchPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>> { -if (requestParameters.speaker === null || requestParameters.speaker === undefined) { - throw new runtime.RequiredError('speaker','Required parameter requestParameters.speaker was null or undefined when calling moraPitchMoraPitchPost.'); -} + async moraPitchMoraPitchPostRaw(requestParameters: MoraPitchMoraPitchPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>> { + if (requestParameters.speaker === null || requestParameters.speaker === undefined) { + throw new runtime.RequiredError('speaker','Required parameter requestParameters.speaker was null or undefined when calling moraPitchMoraPitchPost.'); + } -if (requestParameters.accentPhrase === null || requestParameters.accentPhrase === undefined) { - throw new runtime.RequiredError('accentPhrase','Required parameter requestParameters.accentPhrase was null or undefined when calling moraPitchMoraPitchPost.'); -} + if (requestParameters.accentPhrase === null || requestParameters.accentPhrase === undefined) { + throw new runtime.RequiredError('accentPhrase','Required parameter requestParameters.accentPhrase was null or undefined when calling moraPitchMoraPitchPost.'); + } -const queryParameters: any = {}; + const queryParameters: any = {}; -if (requestParameters.speaker !== undefined) { - queryParameters['speaker'] = requestParameters.speaker; -} + if (requestParameters.speaker !== undefined) { + queryParameters['speaker'] = requestParameters.speaker; + } -if (requestParameters.coreVersion !== undefined) { - queryParameters['core_version'] = requestParameters.coreVersion; -} + if (requestParameters.coreVersion !== undefined) { + queryParameters['core_version'] = requestParameters.coreVersion; + } -const headerParameters: runtime.HTTPHeaders = {}; + const headerParameters: runtime.HTTPHeaders = {}; -headerParameters['Content-Type'] = 'application/json'; + headerParameters['Content-Type'] = 'application/json'; -const response = await this.request({ - path: `/mora_pitch`, - method: 'POST', - headers: headerParameters, - query: queryParameters, - body: requestParameters.accentPhrase.map(AccentPhraseToJSON), -}, initOverrides); + const response = await this.request({ + path: `/mora_pitch`, + method: 'POST', + headers: headerParameters, + query: queryParameters, + body: requestParameters.accentPhrase.map(AccentPhraseToJSON), + }, initOverrides); - return new runtime.JSONApiResponse(response, (jsonValue) => jsonValue.map(AccentPhraseFromJSON)); + return new runtime.JSONApiResponse(response, (jsonValue) => jsonValue.map(AccentPhraseFromJSON)); } -/** + /** * アクセント句から音高を得る */ -async moraPitchMoraPitchPost(requestParameters: MoraPitchMoraPitchPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { -const response = await this.moraPitchMoraPitchPostRaw(requestParameters, initOverrides); -return await response.value(); -} + async moraPitchMoraPitchPost(requestParameters: MoraPitchMoraPitchPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + const response = await this.moraPitchMoraPitchPostRaw(requestParameters, initOverrides); + return await response.value(); + } -/** + /** * 指定されたベーススタイルに対してエンジン内の各話者がモーフィング機能を利用可能か返します。 モーフィングの許可/禁止は`/speakers`の`speaker.supported_features.synthesis_morphing`に記載されています。 プロパティが存在しない場合は、モーフィングが許可されているとみなします。 返り値のスタイルIDはstring型なので注意。 * 指定したスタイルに対してエンジン内の話者がモーフィングが可能か判定する */ -async morphableTargetsMorphableTargetsPostRaw(requestParameters: MorphableTargetsMorphableTargetsPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>> { -if (requestParameters.requestBody === null || requestParameters.requestBody === undefined) { - throw new runtime.RequiredError('requestBody','Required parameter requestParameters.requestBody was null or undefined when calling morphableTargetsMorphableTargetsPost.'); -} + async morphableTargetsMorphableTargetsPostRaw(requestParameters: MorphableTargetsMorphableTargetsPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>> { + if (requestParameters.requestBody === null || requestParameters.requestBody === undefined) { + throw new runtime.RequiredError('requestBody','Required parameter requestParameters.requestBody was null or undefined when calling morphableTargetsMorphableTargetsPost.'); + } -const queryParameters: any = {}; + const queryParameters: any = {}; -if (requestParameters.coreVersion !== undefined) { - queryParameters['core_version'] = requestParameters.coreVersion; -} + if (requestParameters.coreVersion !== undefined) { + queryParameters['core_version'] = requestParameters.coreVersion; + } -const headerParameters: runtime.HTTPHeaders = {}; + const headerParameters: runtime.HTTPHeaders = {}; - headerParameters['Content-Type'] = 'application/json'; + headerParameters['Content-Type'] = 'application/json'; -const response = await this.request({ - path: `/morphable_targets`, - method: 'POST', - headers: headerParameters, - query: queryParameters, - body: requestParameters.requestBody, -}, initOverrides); + const response = await this.request({ + path: `/morphable_targets`, + method: 'POST', + headers: headerParameters, + query: queryParameters, + body: requestParameters.requestBody, + }, initOverrides); - return new runtime.JSONApiResponse(response); + return new runtime.JSONApiResponse(response); } -/** + /** * 指定されたベーススタイルに対してエンジン内の各話者がモーフィング機能を利用可能か返します。 モーフィングの許可/禁止は`/speakers`の`speaker.supported_features.synthesis_morphing`に記載されています。 プロパティが存在しない場合は、モーフィングが許可されているとみなします。 返り値のスタイルIDはstring型なので注意。 * 指定したスタイルに対してエンジン内の話者がモーフィングが可能か判定する */ -async morphableTargetsMorphableTargetsPost(requestParameters: MorphableTargetsMorphableTargetsPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { - const response = await this.morphableTargetsMorphableTargetsPostRaw(requestParameters, initOverrides); - return await response.value(); -} + async morphableTargetsMorphableTargetsPost(requestParameters: MorphableTargetsMorphableTargetsPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + const response = await this.morphableTargetsMorphableTargetsPostRaw(requestParameters, initOverrides); + return await response.value(); + } -/** + /** * 複数まとめて音声合成する */ -async multiSynthesisMultiSynthesisPostRaw(requestParameters: MultiSynthesisMultiSynthesisPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { -if (requestParameters.speaker === null || requestParameters.speaker === undefined) { - throw new runtime.RequiredError('speaker','Required parameter requestParameters.speaker was null or undefined when calling multiSynthesisMultiSynthesisPost.'); -} + async multiSynthesisMultiSynthesisPostRaw(requestParameters: MultiSynthesisMultiSynthesisPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + if (requestParameters.speaker === null || requestParameters.speaker === undefined) { + throw new runtime.RequiredError('speaker','Required parameter requestParameters.speaker was null or undefined when calling multiSynthesisMultiSynthesisPost.'); + } -if (requestParameters.audioQuery === null || requestParameters.audioQuery === undefined) { - throw new runtime.RequiredError('audioQuery','Required parameter requestParameters.audioQuery was null or undefined when calling multiSynthesisMultiSynthesisPost.'); -} + if (requestParameters.audioQuery === null || requestParameters.audioQuery === undefined) { + throw new runtime.RequiredError('audioQuery','Required parameter requestParameters.audioQuery was null or undefined when calling multiSynthesisMultiSynthesisPost.'); + } -const queryParameters: any = {}; + const queryParameters: any = {}; -if (requestParameters.speaker !== undefined) { - queryParameters['speaker'] = requestParameters.speaker; -} + if (requestParameters.speaker !== undefined) { + queryParameters['speaker'] = requestParameters.speaker; + } -if (requestParameters.coreVersion !== undefined) { - queryParameters['core_version'] = requestParameters.coreVersion; -} + if (requestParameters.coreVersion !== undefined) { + queryParameters['core_version'] = requestParameters.coreVersion; + } -const headerParameters: runtime.HTTPHeaders = {}; + const headerParameters: runtime.HTTPHeaders = {}; -headerParameters['Content-Type'] = 'application/json'; + headerParameters['Content-Type'] = 'application/json'; -const response = await this.request({ - path: `/multi_synthesis`, - method: 'POST', - headers: headerParameters, - query: queryParameters, - body: requestParameters.audioQuery.map(AudioQueryToJSON), -}, initOverrides); + const response = await this.request({ + path: `/multi_synthesis`, + method: 'POST', + headers: headerParameters, + query: queryParameters, + body: requestParameters.audioQuery.map(AudioQueryToJSON), + }, initOverrides); - return new runtime.BlobApiResponse(response); + return new runtime.BlobApiResponse(response); } -/** + /** * 複数まとめて音声合成する */ -async multiSynthesisMultiSynthesisPost(requestParameters: MultiSynthesisMultiSynthesisPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { -const response = await this.multiSynthesisMultiSynthesisPostRaw(requestParameters, initOverrides); -return await response.value(); -} + async multiSynthesisMultiSynthesisPost(requestParameters: MultiSynthesisMultiSynthesisPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { + const response = await this.multiSynthesisMultiSynthesisPostRaw(requestParameters, initOverrides); + return await response.value(); + } -/** + /** * ユーザー辞書に登録されている言葉を更新します。 * Rewrite User Dict Word */ -async rewriteUserDictWordUserDictWordWordUuidPutRaw(requestParameters: RewriteUserDictWordUserDictWordWordUuidPutRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { -if (requestParameters.wordUuid === null || requestParameters.wordUuid === undefined) { - throw new runtime.RequiredError('wordUuid','Required parameter requestParameters.wordUuid was null or undefined when calling rewriteUserDictWordUserDictWordWordUuidPut.'); -} + async rewriteUserDictWordUserDictWordWordUuidPutRaw(requestParameters: RewriteUserDictWordUserDictWordWordUuidPutRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + if (requestParameters.wordUuid === null || requestParameters.wordUuid === undefined) { + throw new runtime.RequiredError('wordUuid','Required parameter requestParameters.wordUuid was null or undefined when calling rewriteUserDictWordUserDictWordWordUuidPut.'); + } -if (requestParameters.surface === null || requestParameters.surface === undefined) { - throw new runtime.RequiredError('surface','Required parameter requestParameters.surface was null or undefined when calling rewriteUserDictWordUserDictWordWordUuidPut.'); -} + if (requestParameters.surface === null || requestParameters.surface === undefined) { + throw new runtime.RequiredError('surface','Required parameter requestParameters.surface was null or undefined when calling rewriteUserDictWordUserDictWordWordUuidPut.'); + } -if (requestParameters.pronunciation === null || requestParameters.pronunciation === undefined) { - throw new runtime.RequiredError('pronunciation','Required parameter requestParameters.pronunciation was null or undefined when calling rewriteUserDictWordUserDictWordWordUuidPut.'); -} + if (requestParameters.pronunciation === null || requestParameters.pronunciation === undefined) { + throw new runtime.RequiredError('pronunciation','Required parameter requestParameters.pronunciation was null or undefined when calling rewriteUserDictWordUserDictWordWordUuidPut.'); + } -if (requestParameters.accentType === null || requestParameters.accentType === undefined) { - throw new runtime.RequiredError('accentType','Required parameter requestParameters.accentType was null or undefined when calling rewriteUserDictWordUserDictWordWordUuidPut.'); -} + if (requestParameters.accentType === null || requestParameters.accentType === undefined) { + throw new runtime.RequiredError('accentType','Required parameter requestParameters.accentType was null or undefined when calling rewriteUserDictWordUserDictWordWordUuidPut.'); + } -const queryParameters: any = {}; + const queryParameters: any = {}; -if (requestParameters.surface !== undefined) { - queryParameters['surface'] = requestParameters.surface; -} + if (requestParameters.surface !== undefined) { + queryParameters['surface'] = requestParameters.surface; + } -if (requestParameters.pronunciation !== undefined) { - queryParameters['pronunciation'] = requestParameters.pronunciation; -} + if (requestParameters.pronunciation !== undefined) { + queryParameters['pronunciation'] = requestParameters.pronunciation; + } -if (requestParameters.accentType !== undefined) { - queryParameters['accent_type'] = requestParameters.accentType; -} + if (requestParameters.accentType !== undefined) { + queryParameters['accent_type'] = requestParameters.accentType; + } -if (requestParameters.wordType !== undefined) { - queryParameters['word_type'] = requestParameters.wordType; -} + if (requestParameters.wordType !== undefined) { + queryParameters['word_type'] = requestParameters.wordType; + } -if (requestParameters.priority !== undefined) { - queryParameters['priority'] = requestParameters.priority; -} + if (requestParameters.priority !== undefined) { + queryParameters['priority'] = requestParameters.priority; + } -const headerParameters: runtime.HTTPHeaders = {}; + const headerParameters: runtime.HTTPHeaders = {}; -const response = await this.request({ - path: `/user_dict_word/{word_uuid}`.replace(`{${"word_uuid"}}`, encodeURIComponent(String(requestParameters.wordUuid))), - method: 'PUT', - headers: headerParameters, - query: queryParameters, -}, initOverrides); + const response = await this.request({ + path: `/user_dict_word/{word_uuid}`.replace(`{${"word_uuid"}}`, encodeURIComponent(String(requestParameters.wordUuid))), + method: 'PUT', + headers: headerParameters, + query: queryParameters, + }, initOverrides); - return new runtime.VoidApiResponse(response); + return new runtime.VoidApiResponse(response); } -/** + /** * ユーザー辞書に登録されている言葉を更新します。 * Rewrite User Dict Word */ -async rewriteUserDictWordUserDictWordWordUuidPut(requestParameters: RewriteUserDictWordUserDictWordWordUuidPutRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { - await this.rewriteUserDictWordUserDictWordWordUuidPutRaw(requestParameters, initOverrides); -} + async rewriteUserDictWordUserDictWordWordUuidPut(requestParameters: RewriteUserDictWordUserDictWordWordUuidPutRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { + await this.rewriteUserDictWordUserDictWordWordUuidPutRaw(requestParameters, initOverrides); + } -/** + /** * 設定ページを返します。 * Setting Get */ -async settingGetSettingGetRaw(initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { -const queryParameters: any = {}; + async settingGetSettingGetRaw(initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + const queryParameters: any = {}; -const headerParameters: runtime.HTTPHeaders = {}; + const headerParameters: runtime.HTTPHeaders = {}; -const response = await this.request({ - path: `/setting`, - method: 'GET', - headers: headerParameters, - query: queryParameters, -}, initOverrides); + const response = await this.request({ + path: `/setting`, + method: 'GET', + headers: headerParameters, + query: queryParameters, + }, initOverrides); - return new runtime.VoidApiResponse(response); + return new runtime.VoidApiResponse(response); } -/** + /** * 設定ページを返します。 * Setting Get */ -async settingGetSettingGet(initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { - await this.settingGetSettingGetRaw(initOverrides); -} + async settingGetSettingGet(initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { + await this.settingGetSettingGetRaw(initOverrides); + } -/** + /** * 設定を更新します。 * Setting Post */ -async settingPostSettingPostRaw(requestParameters: SettingPostSettingPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { -if (requestParameters.corsPolicyMode === null || requestParameters.corsPolicyMode === undefined) { - throw new runtime.RequiredError('corsPolicyMode','Required parameter requestParameters.corsPolicyMode was null or undefined when calling settingPostSettingPost.'); -} - -const queryParameters: any = {}; - -const headerParameters: runtime.HTTPHeaders = {}; - -const consumes: runtime.Consume[] = [ - { contentType: 'application/x-www-form-urlencoded' }, -]; -// @ts-ignore: canConsumeForm may be unused -const canConsumeForm = runtime.canConsumeForm(consumes); - -let formParams: { append(param: string, value: any): any }; -let useForm = false; -if (useForm) { - formParams = new FormData(); -} else { - formParams = new URLSearchParams(); -} - -if (requestParameters.corsPolicyMode !== undefined) { - formParams.append('cors_policy_mode', new Blob([JSON.stringify(CorsPolicyModeToJSON(requestParameters.corsPolicyMode))], { type: "application/json", })); -} - -if (requestParameters.allowOrigin !== undefined) { - formParams.append('allow_origin', requestParameters.allowOrigin as any); -} - -const response = await this.request({ - path: `/setting`, - method: 'POST', - headers: headerParameters, - query: queryParameters, - body: formParams, -}, initOverrides); - - return new runtime.VoidApiResponse(response); + async settingPostSettingPostRaw(requestParameters: SettingPostSettingPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + if (requestParameters.corsPolicyMode === null || requestParameters.corsPolicyMode === undefined) { + throw new runtime.RequiredError('corsPolicyMode','Required parameter requestParameters.corsPolicyMode was null or undefined when calling settingPostSettingPost.'); + } + + const queryParameters: any = {}; + + const headerParameters: runtime.HTTPHeaders = {}; + + const consumes: runtime.Consume[] = [ + { contentType: 'application/x-www-form-urlencoded' }, + ]; + // @ts-ignore: canConsumeForm may be unused + const canConsumeForm = runtime.canConsumeForm(consumes); + + let formParams: { append(param: string, value: any): any }; + let useForm = false; + if (useForm) { + formParams = new FormData(); + } else { + formParams = new URLSearchParams(); + } + + if (requestParameters.corsPolicyMode !== undefined) { + formParams.append('cors_policy_mode', new Blob([JSON.stringify(CorsPolicyModeToJSON(requestParameters.corsPolicyMode))], { type: "application/json", })); + } + + if (requestParameters.allowOrigin !== undefined) { + formParams.append('allow_origin', requestParameters.allowOrigin as any); + } + + const response = await this.request({ + path: `/setting`, + method: 'POST', + headers: headerParameters, + query: queryParameters, + body: formParams, + }, initOverrides); + + return new runtime.VoidApiResponse(response); } -/** + /** * 設定を更新します。 * Setting Post */ -async settingPostSettingPost(requestParameters: SettingPostSettingPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { - await this.settingPostSettingPostRaw(requestParameters, initOverrides); -} + async settingPostSettingPost(requestParameters: SettingPostSettingPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { + await this.settingPostSettingPostRaw(requestParameters, initOverrides); + } -/** + /** * 歌唱音声合成用のクエリの初期値を得ます。ここで得られたクエリはそのまま歌唱音声合成に利用できます。各値の意味は`Schemas`を参照してください。 * 歌唱音声合成用のクエリを作成する */ -async singFrameAudioQuerySingFrameAudioQueryPostRaw(requestParameters: SingFrameAudioQuerySingFrameAudioQueryPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { -if (requestParameters.speaker === null || requestParameters.speaker === undefined) { - throw new runtime.RequiredError('speaker','Required parameter requestParameters.speaker was null or undefined when calling singFrameAudioQuerySingFrameAudioQueryPost.'); -} + async singFrameAudioQuerySingFrameAudioQueryPostRaw(requestParameters: SingFrameAudioQuerySingFrameAudioQueryPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + if (requestParameters.speaker === null || requestParameters.speaker === undefined) { + throw new runtime.RequiredError('speaker','Required parameter requestParameters.speaker was null or undefined when calling singFrameAudioQuerySingFrameAudioQueryPost.'); + } -if (requestParameters.score === null || requestParameters.score === undefined) { - throw new runtime.RequiredError('score','Required parameter requestParameters.score was null or undefined when calling singFrameAudioQuerySingFrameAudioQueryPost.'); -} + if (requestParameters.score === null || requestParameters.score === undefined) { + throw new runtime.RequiredError('score','Required parameter requestParameters.score was null or undefined when calling singFrameAudioQuerySingFrameAudioQueryPost.'); + } -const queryParameters: any = {}; + const queryParameters: any = {}; -if (requestParameters.speaker !== undefined) { - queryParameters['speaker'] = requestParameters.speaker; -} + if (requestParameters.speaker !== undefined) { + queryParameters['speaker'] = requestParameters.speaker; + } -if (requestParameters.coreVersion !== undefined) { - queryParameters['core_version'] = requestParameters.coreVersion; -} + if (requestParameters.coreVersion !== undefined) { + queryParameters['core_version'] = requestParameters.coreVersion; + } -const headerParameters: runtime.HTTPHeaders = {}; + const headerParameters: runtime.HTTPHeaders = {}; -headerParameters['Content-Type'] = 'application/json'; + headerParameters['Content-Type'] = 'application/json'; -const response = await this.request({ - path: `/sing_frame_audio_query`, - method: 'POST', - headers: headerParameters, - query: queryParameters, - body: ScoreToJSON(requestParameters.score), -}, initOverrides); + const response = await this.request({ + path: `/sing_frame_audio_query`, + method: 'POST', + headers: headerParameters, + query: queryParameters, + body: ScoreToJSON(requestParameters.score), + }, initOverrides); - return new runtime.JSONApiResponse(response, (jsonValue) => FrameAudioQueryFromJSON(jsonValue)); + return new runtime.JSONApiResponse(response, (jsonValue) => FrameAudioQueryFromJSON(jsonValue)); } -/** + /** * 歌唱音声合成用のクエリの初期値を得ます。ここで得られたクエリはそのまま歌唱音声合成に利用できます。各値の意味は`Schemas`を参照してください。 * 歌唱音声合成用のクエリを作成する */ -async singFrameAudioQuerySingFrameAudioQueryPost(requestParameters: SingFrameAudioQuerySingFrameAudioQueryPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { -const response = await this.singFrameAudioQuerySingFrameAudioQueryPostRaw(requestParameters, initOverrides); -return await response.value(); -} + async singFrameAudioQuerySingFrameAudioQueryPost(requestParameters: SingFrameAudioQuerySingFrameAudioQueryPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { + const response = await this.singFrameAudioQuerySingFrameAudioQueryPostRaw(requestParameters, initOverrides); + return await response.value(); + } -/** + /** * スコア・歌唱音声合成用のクエリからフレームごとの音量を得る */ -async singFrameVolumeSingFrameVolumePostRaw(requestParameters: SingFrameVolumeSingFrameVolumePostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>> { -if (requestParameters.speaker === null || requestParameters.speaker === undefined) { - throw new runtime.RequiredError('speaker','Required parameter requestParameters.speaker was null or undefined when calling singFrameVolumeSingFrameVolumePost.'); -} + async singFrameVolumeSingFrameVolumePostRaw(requestParameters: SingFrameVolumeSingFrameVolumePostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>> { + if (requestParameters.speaker === null || requestParameters.speaker === undefined) { + throw new runtime.RequiredError('speaker','Required parameter requestParameters.speaker was null or undefined when calling singFrameVolumeSingFrameVolumePost.'); + } -if (requestParameters.bodySingFrameVolumeSingFrameVolumePost === null || requestParameters.bodySingFrameVolumeSingFrameVolumePost === undefined) { - throw new runtime.RequiredError('bodySingFrameVolumeSingFrameVolumePost','Required parameter requestParameters.bodySingFrameVolumeSingFrameVolumePost was null or undefined when calling singFrameVolumeSingFrameVolumePost.'); -} + if (requestParameters.bodySingFrameVolumeSingFrameVolumePost === null || requestParameters.bodySingFrameVolumeSingFrameVolumePost === undefined) { + throw new runtime.RequiredError('bodySingFrameVolumeSingFrameVolumePost','Required parameter requestParameters.bodySingFrameVolumeSingFrameVolumePost was null or undefined when calling singFrameVolumeSingFrameVolumePost.'); + } -const queryParameters: any = {}; + const queryParameters: any = {}; -if (requestParameters.speaker !== undefined) { - queryParameters['speaker'] = requestParameters.speaker; -} + if (requestParameters.speaker !== undefined) { + queryParameters['speaker'] = requestParameters.speaker; + } -if (requestParameters.coreVersion !== undefined) { - queryParameters['core_version'] = requestParameters.coreVersion; -} + if (requestParameters.coreVersion !== undefined) { + queryParameters['core_version'] = requestParameters.coreVersion; + } -const headerParameters: runtime.HTTPHeaders = {}; + const headerParameters: runtime.HTTPHeaders = {}; -headerParameters['Content-Type'] = 'application/json'; + headerParameters['Content-Type'] = 'application/json'; -const response = await this.request({ - path: `/sing_frame_volume`, - method: 'POST', - headers: headerParameters, - query: queryParameters, - body: BodySingFrameVolumeSingFrameVolumePostToJSON(requestParameters.bodySingFrameVolumeSingFrameVolumePost), -}, initOverrides); + const response = await this.request({ + path: `/sing_frame_volume`, + method: 'POST', + headers: headerParameters, + query: queryParameters, + body: BodySingFrameVolumeSingFrameVolumePostToJSON(requestParameters.bodySingFrameVolumeSingFrameVolumePost), + }, initOverrides); - return new runtime.JSONApiResponse(response); + return new runtime.JSONApiResponse(response); } -/** + /** * スコア・歌唱音声合成用のクエリからフレームごとの音量を得る */ -async singFrameVolumeSingFrameVolumePost(requestParameters: SingFrameVolumeSingFrameVolumePostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { -const response = await this.singFrameVolumeSingFrameVolumePostRaw(requestParameters, initOverrides); -return await response.value(); -} + async singFrameVolumeSingFrameVolumePost(requestParameters: SingFrameVolumeSingFrameVolumePostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + const response = await this.singFrameVolumeSingFrameVolumePostRaw(requestParameters, initOverrides); + return await response.value(); + } -/** + /** * 指定されたspeaker_uuidに関する情報をjson形式で返します。 画像や音声はbase64エンコードされたものが返されます。 * Singer Info */ -async singerInfoSingerInfoGetRaw(requestParameters: SingerInfoSingerInfoGetRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { -if (requestParameters.speakerUuid === null || requestParameters.speakerUuid === undefined) { - throw new runtime.RequiredError('speakerUuid','Required parameter requestParameters.speakerUuid was null or undefined when calling singerInfoSingerInfoGet.'); -} + async singerInfoSingerInfoGetRaw(requestParameters: SingerInfoSingerInfoGetRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + if (requestParameters.speakerUuid === null || requestParameters.speakerUuid === undefined) { + throw new runtime.RequiredError('speakerUuid','Required parameter requestParameters.speakerUuid was null or undefined when calling singerInfoSingerInfoGet.'); + } -const queryParameters: any = {}; + const queryParameters: any = {}; -if (requestParameters.speakerUuid !== undefined) { - queryParameters['speaker_uuid'] = requestParameters.speakerUuid; -} + if (requestParameters.speakerUuid !== undefined) { + queryParameters['speaker_uuid'] = requestParameters.speakerUuid; + } -if (requestParameters.coreVersion !== undefined) { - queryParameters['core_version'] = requestParameters.coreVersion; -} + if (requestParameters.coreVersion !== undefined) { + queryParameters['core_version'] = requestParameters.coreVersion; + } -const headerParameters: runtime.HTTPHeaders = {}; + const headerParameters: runtime.HTTPHeaders = {}; -const response = await this.request({ - path: `/singer_info`, - method: 'GET', - headers: headerParameters, - query: queryParameters, -}, initOverrides); + const response = await this.request({ + path: `/singer_info`, + method: 'GET', + headers: headerParameters, + query: queryParameters, + }, initOverrides); - return new runtime.JSONApiResponse(response, (jsonValue) => SpeakerInfoFromJSON(jsonValue)); + return new runtime.JSONApiResponse(response, (jsonValue) => SpeakerInfoFromJSON(jsonValue)); } -/** + /** * 指定されたspeaker_uuidに関する情報をjson形式で返します。 画像や音声はbase64エンコードされたものが返されます。 * Singer Info */ -async singerInfoSingerInfoGet(requestParameters: SingerInfoSingerInfoGetRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { -const response = await this.singerInfoSingerInfoGetRaw(requestParameters, initOverrides); -return await response.value(); -} + async singerInfoSingerInfoGet(requestParameters: SingerInfoSingerInfoGetRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { + const response = await this.singerInfoSingerInfoGetRaw(requestParameters, initOverrides); + return await response.value(); + } -/** + /** * Singers */ -async singersSingersGetRaw(requestParameters: SingersSingersGetRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>> { -const queryParameters: any = {}; + async singersSingersGetRaw(requestParameters: SingersSingersGetRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>> { + const queryParameters: any = {}; -if (requestParameters.coreVersion !== undefined) { - queryParameters['core_version'] = requestParameters.coreVersion; -} + if (requestParameters.coreVersion !== undefined) { + queryParameters['core_version'] = requestParameters.coreVersion; + } -const headerParameters: runtime.HTTPHeaders = {}; + const headerParameters: runtime.HTTPHeaders = {}; -const response = await this.request({ - path: `/singers`, - method: 'GET', - headers: headerParameters, - query: queryParameters, -}, initOverrides); + const response = await this.request({ + path: `/singers`, + method: 'GET', + headers: headerParameters, + query: queryParameters, + }, initOverrides); - return new runtime.JSONApiResponse(response, (jsonValue) => jsonValue.map(SpeakerFromJSON)); + return new runtime.JSONApiResponse(response, (jsonValue) => jsonValue.map(SpeakerFromJSON)); } -/** + /** * Singers */ -async singersSingersGet(requestParameters: SingersSingersGetRequest = {}, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { -const response = await this.singersSingersGetRaw(requestParameters, initOverrides); -return await response.value(); -} + async singersSingersGet(requestParameters: SingersSingersGetRequest = {}, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + const response = await this.singersSingersGetRaw(requestParameters, initOverrides); + return await response.value(); + } -/** + /** * 指定されたspeaker_uuidに関する情報をjson形式で返します。 画像や音声はbase64エンコードされたものが返されます。 * Speaker Info */ -async speakerInfoSpeakerInfoGetRaw(requestParameters: SpeakerInfoSpeakerInfoGetRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { -if (requestParameters.speakerUuid === null || requestParameters.speakerUuid === undefined) { - throw new runtime.RequiredError('speakerUuid','Required parameter requestParameters.speakerUuid was null or undefined when calling speakerInfoSpeakerInfoGet.'); -} + async speakerInfoSpeakerInfoGetRaw(requestParameters: SpeakerInfoSpeakerInfoGetRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + if (requestParameters.speakerUuid === null || requestParameters.speakerUuid === undefined) { + throw new runtime.RequiredError('speakerUuid','Required parameter requestParameters.speakerUuid was null or undefined when calling speakerInfoSpeakerInfoGet.'); + } -const queryParameters: any = {}; + const queryParameters: any = {}; -if (requestParameters.speakerUuid !== undefined) { - queryParameters['speaker_uuid'] = requestParameters.speakerUuid; -} + if (requestParameters.speakerUuid !== undefined) { + queryParameters['speaker_uuid'] = requestParameters.speakerUuid; + } -if (requestParameters.coreVersion !== undefined) { - queryParameters['core_version'] = requestParameters.coreVersion; -} + if (requestParameters.coreVersion !== undefined) { + queryParameters['core_version'] = requestParameters.coreVersion; + } -const headerParameters: runtime.HTTPHeaders = {}; + const headerParameters: runtime.HTTPHeaders = {}; -const response = await this.request({ - path: `/speaker_info`, - method: 'GET', - headers: headerParameters, - query: queryParameters, -}, initOverrides); + const response = await this.request({ + path: `/speaker_info`, + method: 'GET', + headers: headerParameters, + query: queryParameters, + }, initOverrides); - return new runtime.JSONApiResponse(response, (jsonValue) => SpeakerInfoFromJSON(jsonValue)); + return new runtime.JSONApiResponse(response, (jsonValue) => SpeakerInfoFromJSON(jsonValue)); } -/** + /** * 指定されたspeaker_uuidに関する情報をjson形式で返します。 画像や音声はbase64エンコードされたものが返されます。 * Speaker Info */ -async speakerInfoSpeakerInfoGet(requestParameters: SpeakerInfoSpeakerInfoGetRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { -const response = await this.speakerInfoSpeakerInfoGetRaw(requestParameters, initOverrides); -return await response.value(); -} + async speakerInfoSpeakerInfoGet(requestParameters: SpeakerInfoSpeakerInfoGetRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { + const response = await this.speakerInfoSpeakerInfoGetRaw(requestParameters, initOverrides); + return await response.value(); + } -/** + /** * Speakers */ -async speakersSpeakersGetRaw(requestParameters: SpeakersSpeakersGetRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>> { -const queryParameters: any = {}; + async speakersSpeakersGetRaw(requestParameters: SpeakersSpeakersGetRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise>> { + const queryParameters: any = {}; -if (requestParameters.coreVersion !== undefined) { - queryParameters['core_version'] = requestParameters.coreVersion; -} + if (requestParameters.coreVersion !== undefined) { + queryParameters['core_version'] = requestParameters.coreVersion; + } -const headerParameters: runtime.HTTPHeaders = {}; + const headerParameters: runtime.HTTPHeaders = {}; -const response = await this.request({ - path: `/speakers`, - method: 'GET', - headers: headerParameters, - query: queryParameters, -}, initOverrides); + const response = await this.request({ + path: `/speakers`, + method: 'GET', + headers: headerParameters, + query: queryParameters, + }, initOverrides); - return new runtime.JSONApiResponse(response, (jsonValue) => jsonValue.map(SpeakerFromJSON)); + return new runtime.JSONApiResponse(response, (jsonValue) => jsonValue.map(SpeakerFromJSON)); } -/** + /** * Speakers */ -async speakersSpeakersGet(requestParameters: SpeakersSpeakersGetRequest = {}, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { -const response = await this.speakersSpeakersGetRaw(requestParameters, initOverrides); -return await response.value(); -} + async speakersSpeakersGet(requestParameters: SpeakersSpeakersGetRequest = {}, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + const response = await this.speakersSpeakersGetRaw(requestParameters, initOverrides); + return await response.value(); + } -/** + /** * Supported Devices */ -async supportedDevicesSupportedDevicesGetRaw(requestParameters: SupportedDevicesSupportedDevicesGetRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { -const queryParameters: any = {}; + async supportedDevicesSupportedDevicesGetRaw(requestParameters: SupportedDevicesSupportedDevicesGetRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + const queryParameters: any = {}; -if (requestParameters.coreVersion !== undefined) { - queryParameters['core_version'] = requestParameters.coreVersion; -} + if (requestParameters.coreVersion !== undefined) { + queryParameters['core_version'] = requestParameters.coreVersion; + } -const headerParameters: runtime.HTTPHeaders = {}; + const headerParameters: runtime.HTTPHeaders = {}; -const response = await this.request({ - path: `/supported_devices`, - method: 'GET', - headers: headerParameters, - query: queryParameters, -}, initOverrides); + const response = await this.request({ + path: `/supported_devices`, + method: 'GET', + headers: headerParameters, + query: queryParameters, + }, initOverrides); - return new runtime.JSONApiResponse(response, (jsonValue) => SupportedDevicesInfoFromJSON(jsonValue)); + return new runtime.JSONApiResponse(response, (jsonValue) => SupportedDevicesInfoFromJSON(jsonValue)); } -/** + /** * Supported Devices */ -async supportedDevicesSupportedDevicesGet(requestParameters: SupportedDevicesSupportedDevicesGetRequest = {}, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { -const response = await this.supportedDevicesSupportedDevicesGetRaw(requestParameters, initOverrides); -return await response.value(); -} + async supportedDevicesSupportedDevicesGet(requestParameters: SupportedDevicesSupportedDevicesGetRequest = {}, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { + const response = await this.supportedDevicesSupportedDevicesGetRaw(requestParameters, initOverrides); + return await response.value(); + } -/** + /** * 指定された2種類のスタイルで音声を合成、指定した割合でモーフィングした音声を得ます。 モーフィングの割合は`morph_rate`で指定でき、0.0でベースのスタイル、1.0でターゲットのスタイルに近づきます。 * 2種類のスタイルでモーフィングした音声を合成する */ -async synthesisMorphingSynthesisMorphingPostRaw(requestParameters: SynthesisMorphingSynthesisMorphingPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { -if (requestParameters.baseSpeaker === null || requestParameters.baseSpeaker === undefined) { - throw new runtime.RequiredError('baseSpeaker','Required parameter requestParameters.baseSpeaker was null or undefined when calling synthesisMorphingSynthesisMorphingPost.'); -} + async synthesisMorphingSynthesisMorphingPostRaw(requestParameters: SynthesisMorphingSynthesisMorphingPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + if (requestParameters.baseSpeaker === null || requestParameters.baseSpeaker === undefined) { + throw new runtime.RequiredError('baseSpeaker','Required parameter requestParameters.baseSpeaker was null or undefined when calling synthesisMorphingSynthesisMorphingPost.'); + } -if (requestParameters.targetSpeaker === null || requestParameters.targetSpeaker === undefined) { - throw new runtime.RequiredError('targetSpeaker','Required parameter requestParameters.targetSpeaker was null or undefined when calling synthesisMorphingSynthesisMorphingPost.'); -} + if (requestParameters.targetSpeaker === null || requestParameters.targetSpeaker === undefined) { + throw new runtime.RequiredError('targetSpeaker','Required parameter requestParameters.targetSpeaker was null or undefined when calling synthesisMorphingSynthesisMorphingPost.'); + } -if (requestParameters.morphRate === null || requestParameters.morphRate === undefined) { - throw new runtime.RequiredError('morphRate','Required parameter requestParameters.morphRate was null or undefined when calling synthesisMorphingSynthesisMorphingPost.'); -} + if (requestParameters.morphRate === null || requestParameters.morphRate === undefined) { + throw new runtime.RequiredError('morphRate','Required parameter requestParameters.morphRate was null or undefined when calling synthesisMorphingSynthesisMorphingPost.'); + } -if (requestParameters.audioQuery === null || requestParameters.audioQuery === undefined) { - throw new runtime.RequiredError('audioQuery','Required parameter requestParameters.audioQuery was null or undefined when calling synthesisMorphingSynthesisMorphingPost.'); -} + if (requestParameters.audioQuery === null || requestParameters.audioQuery === undefined) { + throw new runtime.RequiredError('audioQuery','Required parameter requestParameters.audioQuery was null or undefined when calling synthesisMorphingSynthesisMorphingPost.'); + } -const queryParameters: any = {}; + const queryParameters: any = {}; -if (requestParameters.baseSpeaker !== undefined) { - queryParameters['base_speaker'] = requestParameters.baseSpeaker; -} + if (requestParameters.baseSpeaker !== undefined) { + queryParameters['base_speaker'] = requestParameters.baseSpeaker; + } -if (requestParameters.targetSpeaker !== undefined) { - queryParameters['target_speaker'] = requestParameters.targetSpeaker; -} + if (requestParameters.targetSpeaker !== undefined) { + queryParameters['target_speaker'] = requestParameters.targetSpeaker; + } -if (requestParameters.morphRate !== undefined) { - queryParameters['morph_rate'] = requestParameters.morphRate; -} + if (requestParameters.morphRate !== undefined) { + queryParameters['morph_rate'] = requestParameters.morphRate; + } -if (requestParameters.coreVersion !== undefined) { - queryParameters['core_version'] = requestParameters.coreVersion; -} + if (requestParameters.coreVersion !== undefined) { + queryParameters['core_version'] = requestParameters.coreVersion; + } -const headerParameters: runtime.HTTPHeaders = {}; + const headerParameters: runtime.HTTPHeaders = {}; -headerParameters['Content-Type'] = 'application/json'; + headerParameters['Content-Type'] = 'application/json'; -const response = await this.request({ - path: `/synthesis_morphing`, - method: 'POST', - headers: headerParameters, - query: queryParameters, - body: AudioQueryToJSON(requestParameters.audioQuery), -}, initOverrides); + const response = await this.request({ + path: `/synthesis_morphing`, + method: 'POST', + headers: headerParameters, + query: queryParameters, + body: AudioQueryToJSON(requestParameters.audioQuery), + }, initOverrides); - return new runtime.BlobApiResponse(response); + return new runtime.BlobApiResponse(response); } -/** + /** * 指定された2種類のスタイルで音声を合成、指定した割合でモーフィングした音声を得ます。 モーフィングの割合は`morph_rate`で指定でき、0.0でベースのスタイル、1.0でターゲットのスタイルに近づきます。 * 2種類のスタイルでモーフィングした音声を合成する */ -async synthesisMorphingSynthesisMorphingPost(requestParameters: SynthesisMorphingSynthesisMorphingPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { -const response = await this.synthesisMorphingSynthesisMorphingPostRaw(requestParameters, initOverrides); -return await response.value(); -} + async synthesisMorphingSynthesisMorphingPost(requestParameters: SynthesisMorphingSynthesisMorphingPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { + const response = await this.synthesisMorphingSynthesisMorphingPostRaw(requestParameters, initOverrides); + return await response.value(); + } -/** + /** * 音声合成する */ -async synthesisSynthesisPostRaw(requestParameters: SynthesisSynthesisPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { -if (requestParameters.speaker === null || requestParameters.speaker === undefined) { - throw new runtime.RequiredError('speaker','Required parameter requestParameters.speaker was null or undefined when calling synthesisSynthesisPost.'); -} + async synthesisSynthesisPostRaw(requestParameters: SynthesisSynthesisPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + if (requestParameters.speaker === null || requestParameters.speaker === undefined) { + throw new runtime.RequiredError('speaker','Required parameter requestParameters.speaker was null or undefined when calling synthesisSynthesisPost.'); + } -if (requestParameters.audioQuery === null || requestParameters.audioQuery === undefined) { - throw new runtime.RequiredError('audioQuery','Required parameter requestParameters.audioQuery was null or undefined when calling synthesisSynthesisPost.'); -} + if (requestParameters.audioQuery === null || requestParameters.audioQuery === undefined) { + throw new runtime.RequiredError('audioQuery','Required parameter requestParameters.audioQuery was null or undefined when calling synthesisSynthesisPost.'); + } -const queryParameters: any = {}; + const queryParameters: any = {}; -if (requestParameters.speaker !== undefined) { - queryParameters['speaker'] = requestParameters.speaker; -} + if (requestParameters.speaker !== undefined) { + queryParameters['speaker'] = requestParameters.speaker; + } -if (requestParameters.enableInterrogativeUpspeak !== undefined) { - queryParameters['enable_interrogative_upspeak'] = requestParameters.enableInterrogativeUpspeak; -} + if (requestParameters.enableInterrogativeUpspeak !== undefined) { + queryParameters['enable_interrogative_upspeak'] = requestParameters.enableInterrogativeUpspeak; + } -if (requestParameters.coreVersion !== undefined) { - queryParameters['core_version'] = requestParameters.coreVersion; -} + if (requestParameters.coreVersion !== undefined) { + queryParameters['core_version'] = requestParameters.coreVersion; + } -const headerParameters: runtime.HTTPHeaders = {}; + const headerParameters: runtime.HTTPHeaders = {}; -headerParameters['Content-Type'] = 'application/json'; + headerParameters['Content-Type'] = 'application/json'; -const response = await this.request({ - path: `/synthesis`, - method: 'POST', - headers: headerParameters, - query: queryParameters, - body: AudioQueryToJSON(requestParameters.audioQuery), -}, initOverrides); + const response = await this.request({ + path: `/synthesis`, + method: 'POST', + headers: headerParameters, + query: queryParameters, + body: AudioQueryToJSON(requestParameters.audioQuery), + }, initOverrides); - return new runtime.BlobApiResponse(response); + return new runtime.BlobApiResponse(response); } -/** + /** * 音声合成する */ -async synthesisSynthesisPost(requestParameters: SynthesisSynthesisPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { -const response = await this.synthesisSynthesisPostRaw(requestParameters, initOverrides); -return await response.value(); -} + async synthesisSynthesisPost(requestParameters: SynthesisSynthesisPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { + const response = await this.synthesisSynthesisPostRaw(requestParameters, initOverrides); + return await response.value(); + } -/** + /** * 音声ライブラリをアンインストールします。 * Uninstall Library */ -async uninstallLibraryUninstallLibraryLibraryUuidPostRaw(requestParameters: UninstallLibraryUninstallLibraryLibraryUuidPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { -if (requestParameters.libraryUuid === null || requestParameters.libraryUuid === undefined) { - throw new runtime.RequiredError('libraryUuid','Required parameter requestParameters.libraryUuid was null or undefined when calling uninstallLibraryUninstallLibraryLibraryUuidPost.'); -} + async uninstallLibraryUninstallLibraryLibraryUuidPostRaw(requestParameters: UninstallLibraryUninstallLibraryLibraryUuidPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + if (requestParameters.libraryUuid === null || requestParameters.libraryUuid === undefined) { + throw new runtime.RequiredError('libraryUuid','Required parameter requestParameters.libraryUuid was null or undefined when calling uninstallLibraryUninstallLibraryLibraryUuidPost.'); + } -const queryParameters: any = {}; + const queryParameters: any = {}; -const headerParameters: runtime.HTTPHeaders = {}; + const headerParameters: runtime.HTTPHeaders = {}; -const response = await this.request({ - path: `/uninstall_library/{library_uuid}`.replace(`{${"library_uuid"}}`, encodeURIComponent(String(requestParameters.libraryUuid))), - method: 'POST', - headers: headerParameters, - query: queryParameters, -}, initOverrides); + const response = await this.request({ + path: `/uninstall_library/{library_uuid}`.replace(`{${"library_uuid"}}`, encodeURIComponent(String(requestParameters.libraryUuid))), + method: 'POST', + headers: headerParameters, + query: queryParameters, + }, initOverrides); - return new runtime.VoidApiResponse(response); + return new runtime.VoidApiResponse(response); } -/** + /** * 音声ライブラリをアンインストールします。 * Uninstall Library */ -async uninstallLibraryUninstallLibraryLibraryUuidPost(requestParameters: UninstallLibraryUninstallLibraryLibraryUuidPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { - await this.uninstallLibraryUninstallLibraryLibraryUuidPostRaw(requestParameters, initOverrides); -} + async uninstallLibraryUninstallLibraryLibraryUuidPost(requestParameters: UninstallLibraryUninstallLibraryLibraryUuidPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { + await this.uninstallLibraryUninstallLibraryLibraryUuidPostRaw(requestParameters, initOverrides); + } -/** + /** * 既存のプリセットを更新します * Update Preset */ -async updatePresetUpdatePresetPostRaw(requestParameters: UpdatePresetUpdatePresetPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { -if (requestParameters.preset === null || requestParameters.preset === undefined) { - throw new runtime.RequiredError('preset','Required parameter requestParameters.preset was null or undefined when calling updatePresetUpdatePresetPost.'); -} + async updatePresetUpdatePresetPostRaw(requestParameters: UpdatePresetUpdatePresetPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + if (requestParameters.preset === null || requestParameters.preset === undefined) { + throw new runtime.RequiredError('preset','Required parameter requestParameters.preset was null or undefined when calling updatePresetUpdatePresetPost.'); + } -const queryParameters: any = {}; + const queryParameters: any = {}; -const headerParameters: runtime.HTTPHeaders = {}; + const headerParameters: runtime.HTTPHeaders = {}; -headerParameters['Content-Type'] = 'application/json'; + headerParameters['Content-Type'] = 'application/json'; -const response = await this.request({ - path: `/update_preset`, - method: 'POST', - headers: headerParameters, - query: queryParameters, - body: PresetToJSON(requestParameters.preset), -}, initOverrides); + const response = await this.request({ + path: `/update_preset`, + method: 'POST', + headers: headerParameters, + query: queryParameters, + body: PresetToJSON(requestParameters.preset), + }, initOverrides); -if (this.isJsonMime(response.headers.get('content-type'))) { - return new runtime.JSONApiResponse(response); -} else { - return new runtime.TextApiResponse(response) as any; -} -} + if (this.isJsonMime(response.headers.get('content-type'))) { + return new runtime.JSONApiResponse(response); + } else { + return new runtime.TextApiResponse(response) as any; + } + } -/** + /** * 既存のプリセットを更新します * Update Preset */ -async updatePresetUpdatePresetPost(requestParameters: UpdatePresetUpdatePresetPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { -const response = await this.updatePresetUpdatePresetPostRaw(requestParameters, initOverrides); -return await response.value(); -} + async updatePresetUpdatePresetPost(requestParameters: UpdatePresetUpdatePresetPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { + const response = await this.updatePresetUpdatePresetPostRaw(requestParameters, initOverrides); + return await response.value(); + } -/** + /** * テキストがAquesTalk 風記法に従っているかどうかを判定します。 従っていない場合はエラーが返ります。 * テキストがAquesTalk 風記法に従っているか判定する */ -async validateKanaValidateKanaPostRaw(requestParameters: ValidateKanaValidateKanaPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { -if (requestParameters.text === null || requestParameters.text === undefined) { - throw new runtime.RequiredError('text','Required parameter requestParameters.text was null or undefined when calling validateKanaValidateKanaPost.'); -} + async validateKanaValidateKanaPostRaw(requestParameters: ValidateKanaValidateKanaPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + if (requestParameters.text === null || requestParameters.text === undefined) { + throw new runtime.RequiredError('text','Required parameter requestParameters.text was null or undefined when calling validateKanaValidateKanaPost.'); + } -const queryParameters: any = {}; + const queryParameters: any = {}; -if (requestParameters.text !== undefined) { - queryParameters['text'] = requestParameters.text; -} + if (requestParameters.text !== undefined) { + queryParameters['text'] = requestParameters.text; + } -const headerParameters: runtime.HTTPHeaders = {}; + const headerParameters: runtime.HTTPHeaders = {}; -const response = await this.request({ - path: `/validate_kana`, - method: 'POST', - headers: headerParameters, - query: queryParameters, -}, initOverrides); + const response = await this.request({ + path: `/validate_kana`, + method: 'POST', + headers: headerParameters, + query: queryParameters, + }, initOverrides); -if (this.isJsonMime(response.headers.get('content-type'))) { - return new runtime.JSONApiResponse(response); -} else { - return new runtime.TextApiResponse(response) as any; -} -} + if (this.isJsonMime(response.headers.get('content-type'))) { + return new runtime.JSONApiResponse(response); + } else { + return new runtime.TextApiResponse(response) as any; + } + } -/** + /** * テキストがAquesTalk 風記法に従っているかどうかを判定します。 従っていない場合はエラーが返ります。 * テキストがAquesTalk 風記法に従っているか判定する */ -async validateKanaValidateKanaPost(requestParameters: ValidateKanaValidateKanaPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { -const response = await this.validateKanaValidateKanaPostRaw(requestParameters, initOverrides); -return await response.value(); -} + async validateKanaValidateKanaPost(requestParameters: ValidateKanaValidateKanaPostRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { + const response = await this.validateKanaValidateKanaPostRaw(requestParameters, initOverrides); + return await response.value(); + } -/** + /** * Version */ -async versionVersionGetRaw(initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { -const queryParameters: any = {}; + async versionVersionGetRaw(initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + const queryParameters: any = {}; -const headerParameters: runtime.HTTPHeaders = {}; + const headerParameters: runtime.HTTPHeaders = {}; -const response = await this.request({ - path: `/version`, - method: 'GET', - headers: headerParameters, - query: queryParameters, -}, initOverrides); + const response = await this.request({ + path: `/version`, + method: 'GET', + headers: headerParameters, + query: queryParameters, + }, initOverrides); -if (this.isJsonMime(response.headers.get('content-type'))) { - return new runtime.JSONApiResponse(response); -} else { - return new runtime.TextApiResponse(response) as any; -} -} + if (this.isJsonMime(response.headers.get('content-type'))) { + return new runtime.JSONApiResponse(response); + } else { + return new runtime.TextApiResponse(response) as any; + } + } -/** + /** * Version */ -async versionVersionGet(initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { -const response = await this.versionVersionGetRaw(initOverrides); -return await response.value(); -} + async versionVersionGet(initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { + const response = await this.versionVersionGetRaw(initOverrides); + return await response.value(); + } -} +} \ No newline at end of file diff --git a/src/openapi/models/AudioQuery.ts b/src/openapi/models/AudioQuery.ts index de60f7b50c..b366a4c894 100644 --- a/src/openapi/models/AudioQuery.ts +++ b/src/openapi/models/AudioQuery.ts @@ -45,7 +45,7 @@ export interface AudioQuery { */ pitchScale: number; /** - * + * * @type {number} * @memberof AudioQuery */ @@ -129,7 +129,7 @@ export function AudioQueryFromJSONTyped(json: any, ignoreDiscriminator: boolean) return json; } return { - + 'accentPhrases': ((json['accent_phrases'] as Array).map(AccentPhraseFromJSON)), 'speedScale': json['speedScale'], 'pitchScale': json['pitchScale'], @@ -153,7 +153,7 @@ export function AudioQueryToJSON(value?: AudioQuery | null): any { return null; } return { - + 'accent_phrases': ((value.accentPhrases as Array).map(AccentPhraseToJSON)), 'speedScale': value.speedScale, 'pitchScale': value.pitchScale, diff --git a/src/openapi/models/Preset.ts b/src/openapi/models/Preset.ts index dc068fdfc1..534b47211f 100644 --- a/src/openapi/models/Preset.ts +++ b/src/openapi/models/Preset.ts @@ -123,7 +123,7 @@ export function PresetFromJSONTyped(json: any, ignoreDiscriminator: boolean): Pr return json; } return { - + 'id': json['id'], 'name': json['name'], 'speakerUuid': json['speaker_uuid'], @@ -147,7 +147,7 @@ export function PresetToJSON(value?: Preset | null): any { return null; } return { - + 'id': value.id, 'name': value.name, 'speaker_uuid': value.speakerUuid, From 3842b38bf9bc82870ccb9577df4783950f765a83 Mon Sep 17 00:00:00 2001 From: X-20A <155217226+X-20A@users.noreply.github.com> Date: Fri, 7 Jun 2024 15:49:10 +0900 Subject: [PATCH 13/86] =?UTF-8?q?=E3=83=97=E3=83=AA=E3=82=BB=E3=83=83?= =?UTF-8?q?=E3=83=88=E5=90=8D=E5=A4=89=E6=9B=B4=20=E4=BB=96=E6=95=B4?= =?UTF-8?q?=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/store/audioGenerate.ts | 2 +- src/store/preset.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/store/audioGenerate.ts b/src/store/audioGenerate.ts index 9d69bf1e03..7d9ca52b74 100644 --- a/src/store/audioGenerate.ts +++ b/src/store/audioGenerate.ts @@ -39,7 +39,7 @@ export async function fetchAudioFromAudioItem( } const speaker = audioItem.voice.styleId; - + const engineAudioQuery = convertAudioQueryFromEditorToEngine( audioQuery, state.engineManifests[engineId].defaultSamplingRate, diff --git a/src/store/preset.ts b/src/store/preset.ts index 8bf55b9bda..c5c213ab94 100644 --- a/src/store/preset.ts +++ b/src/store/preset.ts @@ -211,7 +211,7 @@ export const presetStore = createPartialStore({ } const characterName = getters.VOICE_NAME(voice); - + const presetData: Preset = { name: `デフォルト:${characterName}`, speedScale: 1.0, From cc7f005384c36487a968389409f066b7311f0b01 Mon Sep 17 00:00:00 2001 From: X-20A <155217226+X-20A@users.noreply.github.com> Date: Fri, 7 Jun 2024 15:53:26 +0900 Subject: [PATCH 14/86] =?UTF-8?q?=E3=83=97=E3=83=AA=E3=82=BB=E3=83=83?= =?UTF-8?q?=E3=83=88=E5=90=8D=E5=A4=89=E6=9B=B4=20=E4=BB=96=E6=95=B4?= =?UTF-8?q?=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/openapi/models/AudioQuery.ts | 2 +- src/openapi/models/Preset.ts | 2 +- tests/unit/backend/common/pastConfigs/0.13.json | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/openapi/models/AudioQuery.ts b/src/openapi/models/AudioQuery.ts index b366a4c894..3830b675a9 100644 --- a/src/openapi/models/AudioQuery.ts +++ b/src/openapi/models/AudioQuery.ts @@ -167,4 +167,4 @@ export function AudioQueryToJSON(value?: AudioQuery | null): any { 'outputStereo': value.outputStereo, 'kana': value.kana, }; -} +} \ No newline at end of file diff --git a/src/openapi/models/Preset.ts b/src/openapi/models/Preset.ts index 534b47211f..38ab356854 100644 --- a/src/openapi/models/Preset.ts +++ b/src/openapi/models/Preset.ts @@ -161,4 +161,4 @@ export function PresetToJSON(value?: Preset | null): any { 'pauseLength': value.pauseLength, 'pauseLengthScale': value.pauseLengthScale, }; -} +} \ No newline at end of file diff --git a/tests/unit/backend/common/pastConfigs/0.13.json b/tests/unit/backend/common/pastConfigs/0.13.json index 09eee3552d..21845b68dc 100644 --- a/tests/unit/backend/common/pastConfigs/0.13.json +++ b/tests/unit/backend/common/pastConfigs/0.13.json @@ -149,4 +149,4 @@ "version": "0.13.3" } } -} +} \ No newline at end of file From cd9ae32ffee7a3b7f6b55b566ec0b91e1ce6a37c Mon Sep 17 00:00:00 2001 From: X-20A <155217226+X-20A@users.noreply.github.com> Date: Fri, 7 Jun 2024 16:58:34 +0900 Subject: [PATCH 15/86] Rename env.test to .env.test --- env.test => .env.test | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename env.test => .env.test (100%) diff --git a/env.test b/.env.test similarity index 100% rename from env.test rename to .env.test From abc324de35f7eebb5317c9b960429656e7d4426e Mon Sep 17 00:00:00 2001 From: X-20A <155217226+X-20A@users.noreply.github.com> Date: Fri, 7 Jun 2024 16:58:59 +0900 Subject: [PATCH 16/86] Rename env.production to .env.production --- env.production => .env.production | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename env.production => .env.production (100%) diff --git a/env.production b/.env.production similarity index 100% rename from env.production rename to .env.production From 696d5ad5cb000d043c4b32a246528c6879815ac6 Mon Sep 17 00:00:00 2001 From: X-20A <155217226+X-20A@users.noreply.github.com> Date: Fri, 7 Jun 2024 21:18:28 +0900 Subject: [PATCH 17/86] test --- env.production => .env.production | 0 env.test => .env.test | 0 src/components/Talk/AudioInfo.vue | 6 +++--- 3 files changed, 3 insertions(+), 3 deletions(-) rename env.production => .env.production (100%) rename env.test => .env.test (100%) diff --git a/env.production b/.env.production similarity index 100% rename from env.production rename to .env.production diff --git a/env.test b/.env.test similarity index 100% rename from env.test rename to .env.test diff --git a/src/components/Talk/AudioInfo.vue b/src/components/Talk/AudioInfo.vue index b974b71c6c..16eed5a6e2 100644 --- a/src/components/Talk/AudioInfo.vue +++ b/src/components/Talk/AudioInfo.vue @@ -362,7 +362,7 @@ const selectedAudioKeys = computed(() => // 句読点などの無音時間はひとまず倍率verを表示 のち必要に応じ絶対値に切替 const parameters = computed(() => { const plParam: Parameter = { - label: "句読点などの無音時間(秒)", + label: "文内無音(秒)", slider: previewSliderHelper({ modelValue: () => query.value?.pauseLength ?? null, disable: () => uiLocked.value, @@ -382,7 +382,7 @@ const parameters = computed(() => { }; const plsParam: Parameter = { - label: "句読点などの無音時間(倍)", + label: "文内無音(倍)", slider: previewSliderHelper({ modelValue: () => query.value?.pauseLengthScale ?? null, disable: () => uiLocked.value, @@ -520,7 +520,7 @@ const parameters = computed(() => { action: "COMMAND_MULTI_SET_AUDIO_POST_PHONEME_LENGTH", key: "postPhonemeLength", }, - switchPauseLengthMode.value === "SCALE" ? plsParam : plParam, + plsParam, ]; // switchPauseLengthModeの変更に伴って更新 const newParam = switchPauseLengthMode.value === "SCALE" ? plsParam : plParam; From b6c03e6aac960243a050d9ae08a92e1c8533ddea Mon Sep 17 00:00:00 2001 From: X-20A <155217226+X-20A@users.noreply.github.com> Date: Fri, 7 Jun 2024 22:15:33 +0900 Subject: [PATCH 18/86] test --- src/components/Talk/AudioInfo.vue | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/Talk/AudioInfo.vue b/src/components/Talk/AudioInfo.vue index 16eed5a6e2..575b389c95 100644 --- a/src/components/Talk/AudioInfo.vue +++ b/src/components/Talk/AudioInfo.vue @@ -520,7 +520,7 @@ const parameters = computed(() => { action: "COMMAND_MULTI_SET_AUDIO_POST_PHONEME_LENGTH", key: "postPhonemeLength", }, - plsParam, + switchPauseLengthMode.value === "SCALE" ? plsParam : plParam, ]; // switchPauseLengthModeの変更に伴って更新 const newParam = switchPauseLengthMode.value === "SCALE" ? plsParam : plParam; From 7bfd6adc88fb87927d7961b4609edabfbc121ce4 Mon Sep 17 00:00:00 2001 From: X-20A <155217226+X-20A@users.noreply.github.com> Date: Fri, 7 Jun 2024 22:21:32 +0900 Subject: [PATCH 19/86] =?UTF-8?q?UI=E3=82=92=E5=A4=89=E6=9B=B4=20[update?= =?UTF-8?q?=20snapshots]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/Talk/AudioInfo.vue | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/Talk/AudioInfo.vue b/src/components/Talk/AudioInfo.vue index b974b71c6c..e9c420db3d 100644 --- a/src/components/Talk/AudioInfo.vue +++ b/src/components/Talk/AudioInfo.vue @@ -520,7 +520,7 @@ const parameters = computed(() => { action: "COMMAND_MULTI_SET_AUDIO_POST_PHONEME_LENGTH", key: "postPhonemeLength", }, - switchPauseLengthMode.value === "SCALE" ? plsParam : plParam, + store.state.switchPauseLengthMode.value === "SCALE" ? plsParam : plParam, ]; // switchPauseLengthModeの変更に伴って更新 const newParam = switchPauseLengthMode.value === "SCALE" ? plsParam : plParam; From 4f8108560cfc5ee0777200e45ed0af990de24478 Mon Sep 17 00:00:00 2001 From: X-20A <155217226+X-20A@users.noreply.github.com> Date: Fri, 7 Jun 2024 23:38:47 +0900 Subject: [PATCH 20/86] =?UTF-8?q?UI=E3=82=92=E5=A4=89=E6=9B=B4=20[update?= =?UTF-8?q?=20snapshots]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/Talk/AudioInfo.vue | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/Talk/AudioInfo.vue b/src/components/Talk/AudioInfo.vue index e9c420db3d..b974b71c6c 100644 --- a/src/components/Talk/AudioInfo.vue +++ b/src/components/Talk/AudioInfo.vue @@ -520,7 +520,7 @@ const parameters = computed(() => { action: "COMMAND_MULTI_SET_AUDIO_POST_PHONEME_LENGTH", key: "postPhonemeLength", }, - store.state.switchPauseLengthMode.value === "SCALE" ? plsParam : plParam, + switchPauseLengthMode.value === "SCALE" ? plsParam : plParam, ]; // switchPauseLengthModeの変更に伴って更新 const newParam = switchPauseLengthMode.value === "SCALE" ? plsParam : plParam; From 715c0677e272b3856f2cfa1ba7895fb5b152407b Mon Sep 17 00:00:00 2001 From: X-20A <155217226+X-20A@users.noreply.github.com> Date: Sat, 8 Jun 2024 02:49:36 +0900 Subject: [PATCH 21/86] =?UTF-8?q?UI=E3=82=92=E5=A4=89=E6=9B=B4=20[update?= =?UTF-8?q?=20snapshots]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../\345\200\244\345\244\211\346\233\264.spec.ts" | 1 + 1 file changed, 1 insertion(+) diff --git "a/tests/e2e/browser/\350\244\207\346\225\260\351\201\270\346\212\236/\345\200\244\345\244\211\346\233\264.spec.ts" "b/tests/e2e/browser/\350\244\207\346\225\260\351\201\270\346\212\236/\345\200\244\345\244\211\346\233\264.spec.ts" index 4f3863a1fa..a1fa88db45 100644 --- "a/tests/e2e/browser/\350\244\207\346\225\260\351\201\270\346\212\236/\345\200\244\345\244\211\346\233\264.spec.ts" +++ "b/tests/e2e/browser/\350\244\207\346\225\260\351\201\270\346\212\236/\345\200\244\345\244\211\346\233\264.spec.ts" @@ -117,6 +117,7 @@ test("複数選択:AudioInfo操作", async ({ page }) => { const parameters = await audioInfo.locator(".parameters > div").all(); for (const parameter of parameters) { + console.log(parameter); const input = parameter.locator("label input"); await input.fill("2"); await page.waitForTimeout(100); From 0786b1ca4388df20ab99ba2404dbf311cc7b53b6 Mon Sep 17 00:00:00 2001 From: X-20A <155217226+X-20A@users.noreply.github.com> Date: Sat, 8 Jun 2024 03:40:30 +0900 Subject: [PATCH 22/86] =?UTF-8?q?UI=E3=82=92=E5=A4=89=E6=9B=B4=20[update?= =?UTF-8?q?=20snapshots]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../\345\200\244\345\244\211\346\233\264.spec.ts" | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git "a/tests/e2e/browser/\350\244\207\346\225\260\351\201\270\346\212\236/\345\200\244\345\244\211\346\233\264.spec.ts" "b/tests/e2e/browser/\350\244\207\346\225\260\351\201\270\346\212\236/\345\200\244\345\244\211\346\233\264.spec.ts" index a1fa88db45..d688fdf2b4 100644 --- "a/tests/e2e/browser/\350\244\207\346\225\260\351\201\270\346\212\236/\345\200\244\345\244\211\346\233\264.spec.ts" +++ "b/tests/e2e/browser/\350\244\207\346\225\260\351\201\270\346\212\236/\345\200\244\345\244\211\346\233\264.spec.ts" @@ -117,8 +117,10 @@ test("複数選択:AudioInfo操作", async ({ page }) => { const parameters = await audioInfo.locator(".parameters > div").all(); for (const parameter of parameters) { - console.log(parameter); const input = parameter.locator("label input"); + const isVisible = await input.isVisible(); + const isEnabled = await input.isEnabled(); + console.log(`Input visibility: ${isVisible}, enabled: ${isEnabled}`); await input.fill("2"); await page.waitForTimeout(100); } From 992673259a26f562f179eaa975172410f4316333 Mon Sep 17 00:00:00 2001 From: X-20A <155217226+X-20A@users.noreply.github.com> Date: Sat, 8 Jun 2024 03:58:24 +0900 Subject: [PATCH 23/86] =?UTF-8?q?UI=E3=82=92=E5=A4=89=E6=9B=B4=20[update?= =?UTF-8?q?=20snapshots]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/Talk/AudioInfo.vue | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/Talk/AudioInfo.vue b/src/components/Talk/AudioInfo.vue index b974b71c6c..f9365a4cec 100644 --- a/src/components/Talk/AudioInfo.vue +++ b/src/components/Talk/AudioInfo.vue @@ -400,6 +400,7 @@ const parameters = computed(() => { action: "COMMAND_MULTI_SET_AUDIO_PAUSE_LENGTH_SCALE", key: "pauseLengthScale", }; + const baseParam: Parameter[] = [ { label: "話速", @@ -520,7 +521,6 @@ const parameters = computed(() => { action: "COMMAND_MULTI_SET_AUDIO_POST_PHONEME_LENGTH", key: "postPhonemeLength", }, - switchPauseLengthMode.value === "SCALE" ? plsParam : plParam, ]; // switchPauseLengthModeの変更に伴って更新 const newParam = switchPauseLengthMode.value === "SCALE" ? plsParam : plParam; From 523ef78b9b2c43c6d68efdcf01646ebaf07e9705 Mon Sep 17 00:00:00 2001 From: X-20A <155217226+X-20A@users.noreply.github.com> Date: Sat, 8 Jun 2024 04:12:49 +0900 Subject: [PATCH 24/86] =?UTF-8?q?UI=E3=82=92=E5=A4=89=E6=9B=B4=20[update?= =?UTF-8?q?=20snapshots]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/Talk/AudioInfo.vue | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/components/Talk/AudioInfo.vue b/src/components/Talk/AudioInfo.vue index f9365a4cec..d7f69f135a 100644 --- a/src/components/Talk/AudioInfo.vue +++ b/src/components/Talk/AudioInfo.vue @@ -521,10 +521,14 @@ const parameters = computed(() => { action: "COMMAND_MULTI_SET_AUDIO_POST_PHONEME_LENGTH", key: "postPhonemeLength", }, + plsParam, ]; // switchPauseLengthModeの変更に伴って更新 const newParam = switchPauseLengthMode.value === "SCALE" ? plsParam : plParam; - const index = baseParam.findIndex((param) => param.label === newParam.label); + const index = baseParam.findIndex((param) => + param.label.includes("句読点などの無音時間"), + ); + if (index !== -1) { baseParam[index] = newParam; } else { From e0e59f466eada93c2eda7f30a4f1d08ee00ac363 Mon Sep 17 00:00:00 2001 From: X-20A <155217226+X-20A@users.noreply.github.com> Date: Sat, 8 Jun 2024 04:19:09 +0900 Subject: [PATCH 25/86] =?UTF-8?q?UI=E3=82=92=E5=A4=89=E6=9B=B4=20[update?= =?UTF-8?q?=20snapshots]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/Talk/AudioInfo.vue | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/src/components/Talk/AudioInfo.vue b/src/components/Talk/AudioInfo.vue index d7f69f135a..295868c69a 100644 --- a/src/components/Talk/AudioInfo.vue +++ b/src/components/Talk/AudioInfo.vue @@ -523,17 +523,6 @@ const parameters = computed(() => { }, plsParam, ]; - // switchPauseLengthModeの変更に伴って更新 - const newParam = switchPauseLengthMode.value === "SCALE" ? plsParam : plParam; - const index = baseParam.findIndex((param) => - param.label.includes("句読点などの無音時間"), - ); - - if (index !== -1) { - baseParam[index] = newParam; - } else { - baseParam.push(newParam); - } return baseParam; }); From fe06cba384d9cc16a4fdaa8ad22743c1ad7ed9e0 Mon Sep 17 00:00:00 2001 From: X-20A <155217226+X-20A@users.noreply.github.com> Date: Sat, 8 Jun 2024 04:25:04 +0900 Subject: [PATCH 26/86] =?UTF-8?q?UI=E3=82=92=E5=A4=89=E6=9B=B4=20[update?= =?UTF-8?q?=20snapshots]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/Talk/AudioInfo.vue | 31 ++++++++++++++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/src/components/Talk/AudioInfo.vue b/src/components/Talk/AudioInfo.vue index 295868c69a..b9162fbb8d 100644 --- a/src/components/Talk/AudioInfo.vue +++ b/src/components/Talk/AudioInfo.vue @@ -521,8 +521,37 @@ const parameters = computed(() => { action: "COMMAND_MULTI_SET_AUDIO_POST_PHONEME_LENGTH", key: "postPhonemeLength", }, - plsParam, + { + label: "句読点などの無音時間(秒)", + slider: previewSliderHelper({ + modelValue: () => query.value?.pauseLength ?? null, + disable: () => uiLocked.value, + max: SLIDER_PARAMETERS.PAUSE_LENGTH.max, + min: SLIDER_PARAMETERS.PAUSE_LENGTH.min, + step: SLIDER_PARAMETERS.PAUSE_LENGTH.step, + scrollStep: SLIDER_PARAMETERS.PAUSE_LENGTH.scrollStep, + scrollMinStep: SLIDER_PARAMETERS.PAUSE_LENGTH.scrollMinStep, + onChange: (pauseLength: number) => + store.dispatch("COMMAND_MULTI_SET_AUDIO_PAUSE_LENGTH", { + audioKeys: selectedAudioKeys.value, + pauseLength: pauseLength, + }), + }), + action: "COMMAND_MULTI_SET_AUDIO_PAUSE_LENGTH", + key: "pauseLength", + }, ]; + // switchPauseLengthModeの変更に伴って更新 + const newParam = switchPauseLengthMode.value === "SCALE" ? plsParam : plParam; + const index = baseParam.findIndex((param) => + param.label.includes("句読点などの無音時間"), + ); + + if (index !== -1) { + baseParam[index] = newParam; + } else { + baseParam.push(newParam); + } return baseParam; }); From aed060200ed4bd030315d37cec087ea504d6d4d9 Mon Sep 17 00:00:00 2001 From: X-20A <155217226+X-20A@users.noreply.github.com> Date: Sat, 8 Jun 2024 04:25:49 +0900 Subject: [PATCH 27/86] =?UTF-8?q?UI=E3=82=92=E5=A4=89=E6=9B=B4=20[update?= =?UTF-8?q?=20snapshots]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/Talk/AudioInfo.vue | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/src/components/Talk/AudioInfo.vue b/src/components/Talk/AudioInfo.vue index 575b389c95..99b20ed9c6 100644 --- a/src/components/Talk/AudioInfo.vue +++ b/src/components/Talk/AudioInfo.vue @@ -520,7 +520,25 @@ const parameters = computed(() => { action: "COMMAND_MULTI_SET_AUDIO_POST_PHONEME_LENGTH", key: "postPhonemeLength", }, - switchPauseLengthMode.value === "SCALE" ? plsParam : plParam, + { + label: "文内無音(秒)", + slider: previewSliderHelper({ + modelValue: () => query.value?.pauseLength ?? null, + disable: () => uiLocked.value, + max: SLIDER_PARAMETERS.PAUSE_LENGTH.max, + min: SLIDER_PARAMETERS.PAUSE_LENGTH.min, + step: SLIDER_PARAMETERS.PAUSE_LENGTH.step, + scrollStep: SLIDER_PARAMETERS.PAUSE_LENGTH.scrollStep, + scrollMinStep: SLIDER_PARAMETERS.PAUSE_LENGTH.scrollMinStep, + onChange: (pauseLength: number) => + store.dispatch("COMMAND_MULTI_SET_AUDIO_PAUSE_LENGTH", { + audioKeys: selectedAudioKeys.value, + pauseLength: pauseLength, + }), + }), + action: "COMMAND_MULTI_SET_AUDIO_PAUSE_LENGTH", + key: "pauseLength", + }, ]; // switchPauseLengthModeの変更に伴って更新 const newParam = switchPauseLengthMode.value === "SCALE" ? plsParam : plParam; From c59b4f3d2dd95a6b138e2bc5d6017634da101435 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Fri, 7 Jun 2024 19:35:51 +0000 Subject: [PATCH 28/86] =?UTF-8?q?=EF=BC=88=E3=82=B9=E3=83=8A=E3=83=83?= =?UTF-8?q?=E3=83=97=E3=82=B7=E3=83=A7=E3=83=83=E3=83=88=E3=82=92=E6=9B=B4?= =?UTF-8?q?=E6=96=B0=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...347\224\273\351\235\242-browser-win32.png" | Bin 53964 -> 54318 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git "a/tests/e2e/browser/\343\202\271\343\202\257\343\203\252\343\203\274\343\203\263\343\202\267\343\203\247\343\203\203\343\203\210.spec.ts-snapshots/\343\203\241\343\202\244\343\203\263\347\224\273\351\235\242-browser-win32.png" "b/tests/e2e/browser/\343\202\271\343\202\257\343\203\252\343\203\274\343\203\263\343\202\267\343\203\247\343\203\203\343\203\210.spec.ts-snapshots/\343\203\241\343\202\244\343\203\263\347\224\273\351\235\242-browser-win32.png" index 8c4fd69899cf0b44f332625498ff0af0f4ecab94..51b4bfea7ee086361c37af661ae0938867dd68f0 100644 GIT binary patch literal 54318 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 literal 53964 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 Date: Sat, 8 Jun 2024 04:37:47 +0900 Subject: [PATCH 29/86] =?UTF-8?q?UI=E3=82=92=E5=A4=89=E6=9B=B4=20[update?= =?UTF-8?q?=20snapshots]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/Talk/AudioInfo.vue | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/Talk/AudioInfo.vue b/src/components/Talk/AudioInfo.vue index 99b20ed9c6..b8722e5659 100644 --- a/src/components/Talk/AudioInfo.vue +++ b/src/components/Talk/AudioInfo.vue @@ -539,7 +539,7 @@ const parameters = computed(() => { action: "COMMAND_MULTI_SET_AUDIO_PAUSE_LENGTH", key: "pauseLength", }, - ]; + ]; // 文内無音は何故か変数埋め込みだと「test("複数選択:AudioInfo操作"・・・」でvisibilityでfillが効かない // switchPauseLengthModeの変更に伴って更新 const newParam = switchPauseLengthMode.value === "SCALE" ? plsParam : plParam; const index = baseParam.findIndex((param) => param.label === newParam.label); From 38f54302deb908e479d9cf69a835538419e553bf Mon Sep 17 00:00:00 2001 From: X-20A <155217226+X-20A@users.noreply.github.com> Date: Sat, 8 Jun 2024 04:49:44 +0900 Subject: [PATCH 30/86] =?UTF-8?q?UI=E3=82=92=E5=A4=89=E6=9B=B4=20[update?= =?UTF-8?q?=20snapshots]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/Talk/AudioInfo.vue | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/src/components/Talk/AudioInfo.vue b/src/components/Talk/AudioInfo.vue index b9162fbb8d..7e8226efca 100644 --- a/src/components/Talk/AudioInfo.vue +++ b/src/components/Talk/AudioInfo.vue @@ -522,23 +522,23 @@ const parameters = computed(() => { key: "postPhonemeLength", }, { - label: "句読点などの無音時間(秒)", + label: "句読点などの無音時間(倍)", slider: previewSliderHelper({ - modelValue: () => query.value?.pauseLength ?? null, + modelValue: () => query.value?.pauseLengthScale ?? null, disable: () => uiLocked.value, - max: SLIDER_PARAMETERS.PAUSE_LENGTH.max, - min: SLIDER_PARAMETERS.PAUSE_LENGTH.min, - step: SLIDER_PARAMETERS.PAUSE_LENGTH.step, - scrollStep: SLIDER_PARAMETERS.PAUSE_LENGTH.scrollStep, - scrollMinStep: SLIDER_PARAMETERS.PAUSE_LENGTH.scrollMinStep, - onChange: (pauseLength: number) => - store.dispatch("COMMAND_MULTI_SET_AUDIO_PAUSE_LENGTH", { + max: SLIDER_PARAMETERS.PAUSE_LENGTH_SCALE.max, + min: SLIDER_PARAMETERS.PAUSE_LENGTH_SCALE.min, + step: SLIDER_PARAMETERS.PAUSE_LENGTH_SCALE.step, + scrollStep: SLIDER_PARAMETERS.PAUSE_LENGTH_SCALE.scrollStep, + scrollMinStep: SLIDER_PARAMETERS.PAUSE_LENGTH_SCALE.scrollMinStep, + onChange: (pauseLengthScale: number) => + store.dispatch("COMMAND_MULTI_SET_AUDIO_PAUSE_LENGTH_SCALE", { audioKeys: selectedAudioKeys.value, - pauseLength: pauseLength, + pauseLengthScale: pauseLengthScale, }), }), - action: "COMMAND_MULTI_SET_AUDIO_PAUSE_LENGTH", - key: "pauseLength", + action: "COMMAND_MULTI_SET_AUDIO_PAUSE_LENGTH_SCALE", + key: "pauseLengthScale", }, ]; // switchPauseLengthModeの変更に伴って更新 From e699611e009e7afeb8b7f6792881ec9d9dd10f0b Mon Sep 17 00:00:00 2001 From: X-20A <155217226+X-20A@users.noreply.github.com> Date: Sat, 8 Jun 2024 04:57:26 +0900 Subject: [PATCH 31/86] =?UTF-8?q?UI=E3=82=92=E5=A4=89=E6=9B=B4=20[update?= =?UTF-8?q?=20snapshots]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/Talk/AudioInfo.vue | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/components/Talk/AudioInfo.vue b/src/components/Talk/AudioInfo.vue index 7e8226efca..6619a891cf 100644 --- a/src/components/Talk/AudioInfo.vue +++ b/src/components/Talk/AudioInfo.vue @@ -362,7 +362,7 @@ const selectedAudioKeys = computed(() => // 句読点などの無音時間はひとまず倍率verを表示 のち必要に応じ絶対値に切替 const parameters = computed(() => { const plParam: Parameter = { - label: "句読点などの無音時間(秒)", + label: "文内無音(秒)", slider: previewSliderHelper({ modelValue: () => query.value?.pauseLength ?? null, disable: () => uiLocked.value, @@ -382,7 +382,7 @@ const parameters = computed(() => { }; const plsParam: Parameter = { - label: "句読点などの無音時間(倍)", + label: "文内無音(倍)", slider: previewSliderHelper({ modelValue: () => query.value?.pauseLengthScale ?? null, disable: () => uiLocked.value, @@ -544,7 +544,7 @@ const parameters = computed(() => { // switchPauseLengthModeの変更に伴って更新 const newParam = switchPauseLengthMode.value === "SCALE" ? plsParam : plParam; const index = baseParam.findIndex((param) => - param.label.includes("句読点などの無音時間"), + param.label.includes("文内無音"), ); if (index !== -1) { From 9f23e307ccbe3dff82edc373d8473214bd080eb8 Mon Sep 17 00:00:00 2001 From: X-20A <155217226+X-20A@users.noreply.github.com> Date: Sat, 8 Jun 2024 05:02:07 +0900 Subject: [PATCH 32/86] =?UTF-8?q?UI=E3=82=92=E5=A4=89=E6=9B=B4=20[update?= =?UTF-8?q?=20snapshots]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/Talk/AudioInfo.vue | 6 +++--- src/store/utility.ts | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/components/Talk/AudioInfo.vue b/src/components/Talk/AudioInfo.vue index 6619a891cf..daab1e0e20 100644 --- a/src/components/Talk/AudioInfo.vue +++ b/src/components/Talk/AudioInfo.vue @@ -332,7 +332,7 @@ const uiLocked = computed(() => store.getters.UI_LOCKED); const audioItem = computed(() => store.state.audioItems[props.activeAudioKey]); const query = computed(() => audioItem.value?.query); -// 句読点などの無音時間の指定方式 "SCALE" || "ABSOLUTE" +// 文内無音の指定方式 "SCALE" || "ABSOLUTE" const switchPauseLengthMode = computed(() => { return store.state.switchPauseLengthMode; }); @@ -359,7 +359,7 @@ const selectedAudioKeys = computed(() => : [props.activeAudioKey], ); -// 句読点などの無音時間はひとまず倍率verを表示 のち必要に応じ絶対値に切替 +// 文内無音はひとまず倍率verを表示 のち必要に応じ絶対値に切替 const parameters = computed(() => { const plParam: Parameter = { label: "文内無音(秒)", @@ -522,7 +522,7 @@ const parameters = computed(() => { key: "postPhonemeLength", }, { - label: "句読点などの無音時間(倍)", + label: "文内無音(倍)", slider: previewSliderHelper({ modelValue: () => query.value?.pauseLengthScale ?? null, disable: () => uiLocked.value, diff --git a/src/store/utility.ts b/src/store/utility.ts index 49f5cff8a9..b04c631ea9 100644 --- a/src/store/utility.ts +++ b/src/store/utility.ts @@ -103,7 +103,7 @@ export const SLIDER_PARAMETERS = { scrollMinStep: () => 0.01, }, /** - * 句読点などの無音時間(絶対値)パラメータの定義 + * 文内無音(絶対値)パラメータの定義 */ PAUSE_LENGTH: { max: () => 1, @@ -113,7 +113,7 @@ export const SLIDER_PARAMETERS = { scrollMinStep: () => 0.01, }, /** - * 句読点などの無音時間(倍率)パラメータの定義 + * 文内無音(倍率)パラメータの定義 */ PAUSE_LENGTH_SCALE: { max: () => 2, From 59d2f7c733014e8214052bf28ce45c05eb8d8e3d Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Fri, 7 Jun 2024 20:15:10 +0000 Subject: [PATCH 33/86] =?UTF-8?q?=EF=BC=88=E3=82=B9=E3=83=8A=E3=83=83?= =?UTF-8?q?=E3=83=97=E3=82=B7=E3=83=A7=E3=83=83=E3=83=88=E3=82=92=E6=9B=B4?= =?UTF-8?q?=E6=96=B0=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...347\224\273\351\235\242-browser-win32.png" | Bin 53964 -> 54318 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git "a/tests/e2e/browser/\343\202\271\343\202\257\343\203\252\343\203\274\343\203\263\343\202\267\343\203\247\343\203\203\343\203\210.spec.ts-snapshots/\343\203\241\343\202\244\343\203\263\347\224\273\351\235\242-browser-win32.png" "b/tests/e2e/browser/\343\202\271\343\202\257\343\203\252\343\203\274\343\203\263\343\202\267\343\203\247\343\203\203\343\203\210.spec.ts-snapshots/\343\203\241\343\202\244\343\203\263\347\224\273\351\235\242-browser-win32.png" index 8c4fd69899cf0b44f332625498ff0af0f4ecab94..51b4bfea7ee086361c37af661ae0938867dd68f0 100644 GIT binary patch literal 54318 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 literal 53964 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 Date: Sat, 8 Jun 2024 05:17:16 +0900 Subject: [PATCH 34/86] =?UTF-8?q?UI=E3=82=92=E5=A4=89=E6=9B=B4=20[update?= =?UTF-8?q?=20snapshots]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/Talk/AudioInfo.vue | 20 +------------------ ...5\200\244\345\244\211\346\233\264.spec.ts" | 3 --- 2 files changed, 1 insertion(+), 22 deletions(-) diff --git a/src/components/Talk/AudioInfo.vue b/src/components/Talk/AudioInfo.vue index daab1e0e20..d4022ada76 100644 --- a/src/components/Talk/AudioInfo.vue +++ b/src/components/Talk/AudioInfo.vue @@ -521,25 +521,7 @@ const parameters = computed(() => { action: "COMMAND_MULTI_SET_AUDIO_POST_PHONEME_LENGTH", key: "postPhonemeLength", }, - { - label: "文内無音(倍)", - slider: previewSliderHelper({ - modelValue: () => query.value?.pauseLengthScale ?? null, - disable: () => uiLocked.value, - max: SLIDER_PARAMETERS.PAUSE_LENGTH_SCALE.max, - min: SLIDER_PARAMETERS.PAUSE_LENGTH_SCALE.min, - step: SLIDER_PARAMETERS.PAUSE_LENGTH_SCALE.step, - scrollStep: SLIDER_PARAMETERS.PAUSE_LENGTH_SCALE.scrollStep, - scrollMinStep: SLIDER_PARAMETERS.PAUSE_LENGTH_SCALE.scrollMinStep, - onChange: (pauseLengthScale: number) => - store.dispatch("COMMAND_MULTI_SET_AUDIO_PAUSE_LENGTH_SCALE", { - audioKeys: selectedAudioKeys.value, - pauseLengthScale: pauseLengthScale, - }), - }), - action: "COMMAND_MULTI_SET_AUDIO_PAUSE_LENGTH_SCALE", - key: "pauseLengthScale", - }, + plsParam, ]; // switchPauseLengthModeの変更に伴って更新 const newParam = switchPauseLengthMode.value === "SCALE" ? plsParam : plParam; diff --git "a/tests/e2e/browser/\350\244\207\346\225\260\351\201\270\346\212\236/\345\200\244\345\244\211\346\233\264.spec.ts" "b/tests/e2e/browser/\350\244\207\346\225\260\351\201\270\346\212\236/\345\200\244\345\244\211\346\233\264.spec.ts" index d688fdf2b4..4f3863a1fa 100644 --- "a/tests/e2e/browser/\350\244\207\346\225\260\351\201\270\346\212\236/\345\200\244\345\244\211\346\233\264.spec.ts" +++ "b/tests/e2e/browser/\350\244\207\346\225\260\351\201\270\346\212\236/\345\200\244\345\244\211\346\233\264.spec.ts" @@ -118,9 +118,6 @@ test("複数選択:AudioInfo操作", async ({ page }) => { for (const parameter of parameters) { const input = parameter.locator("label input"); - const isVisible = await input.isVisible(); - const isEnabled = await input.isEnabled(); - console.log(`Input visibility: ${isVisible}, enabled: ${isEnabled}`); await input.fill("2"); await page.waitForTimeout(100); } From 2e967a3a86bc928fe3e90c7ac2f65efb842b9d7e Mon Sep 17 00:00:00 2001 From: X-20A <155217226+X-20A@users.noreply.github.com> Date: Thu, 13 Jun 2024 04:14:41 +0900 Subject: [PATCH 35/86] test --- src/components/Dialog/SettingDialog.vue | 49 +++++----- src/components/Talk/AccentPhrase.vue | 32 ++++++- src/components/Talk/AudioCell.vue | 23 +++++ src/components/Talk/AudioDetail.vue | 19 +--- src/components/Talk/AudioInfo.vue | 63 +++++++++++-- src/openapi/models/Mora.ts | 3 +- src/store/audio.ts | 90 ++++++++++++++++--- src/store/audioGenerate.ts | 1 + src/store/preset.ts | 2 +- src/store/project.ts | 2 +- src/store/proxy.ts | 27 ++++-- src/store/type.ts | 28 +++--- src/store/ui.ts | 33 +++---- src/store/utility.ts | 2 +- src/type/preload.ts | 4 +- .../unit/backend/common/pastConfigs/0.13.json | 2 +- 16 files changed, 266 insertions(+), 114 deletions(-) diff --git a/src/components/Dialog/SettingDialog.vue b/src/components/Dialog/SettingDialog.vue index 3af03bb315..1e8caa7352 100644 --- a/src/components/Dialog/SettingDialog.vue +++ b/src/components/Dialog/SettingDialog.vue @@ -201,7 +201,7 @@
(key: T) => { const props = defineProps<{ modelValue: boolean; - activeAudioKey: AudioKey; }>(); const emit = defineEmits<{ (e: "update:modelValue", val: boolean): void; @@ -1117,34 +1115,33 @@ const engineUseGpu = computed({ const engineIds = computed(() => store.state.engineIds); const engineInfos = computed(() => store.state.engineInfos); -const switchPauseLengthMode = computed({ - get: () => store.state.switchPauseLengthMode, - set: (switchPauseLengthMode: SwitchPauseLengthMode) => { - store.dispatch("SET_SWITCH_PAUSE_LENGTH_MODE", { - switchPauseLengthMode, +const pauseLengthMode = computed({ + get: () => store.state.pauseLengthMode, + set: (pauseLengthMode: PauseLengthMode) => { + store.dispatch("SET_PAUSE_LENGTH_MODE", { + pauseLengthMode, }); }, }); -const selectedAudioKeys = computed(() => - store.state.experimentalSetting.enableMultiSelect - ? store.getters.SELECTED_AUDIO_KEYS - : [props.activeAudioKey], -); +const audioKeys = computed(() => store.state.audioKeys); watchEffect(() => { - if (selectedAudioKeys.value) { - if (switchPauseLengthMode.value === "SCALE") { - store.dispatch("COMMAND_MULTI_SET_AUDIO_PAUSE_LENGTH", { - audioKeys: selectedAudioKeys.value, - pauseLength: 0.3, - }); - } else { - store.dispatch("COMMAND_MULTI_SET_AUDIO_PAUSE_LENGTH_SCALE", { - audioKeys: selectedAudioKeys.value, - pauseLengthScale: 1, - }); - } + console.log("SettingDialog.vue > watchEffect"); + console.log(`audioKeys: ${audioKeys.value}`); + if (pauseLengthMode.value === "ABSOLUTE") { + // a.設定で絶対値モードに変更し、query.pauseLengthにnull以外の値が入っているとき + // 適用範囲: 全てのaudioItem + // COMMAND_MULTI_SET_AUDIO_PAUSE_LENGTHから呼び出し + store.dispatch("COMMAND_MULTI_SET_AUDIO_PAUSE_LENGTH", { + audioKeys: store.state.audioKeys, + pauseLength: 0.3, + }); + } else { + store.dispatch("COMMAND_MULTI_SET_AUDIO_PAUSE_LENGTH_SCALE", { + audioKeys: store.state.audioKeys, + pauseLengthScale: 1, + }); } }); diff --git a/src/components/Talk/AccentPhrase.vue b/src/components/Talk/AccentPhrase.vue index dcc82d72c7..79d3b6c3ee 100644 --- a/src/components/Talk/AccentPhrase.vue +++ b/src/components/Talk/AccentPhrase.vue @@ -254,15 +254,21 @@ const contextMenudata = ref<[MenuItemButton]>([ }, ]); +let beforeText: string = ""; + const pronunciation = computed(() => { let textString = props.accentPhrase.moras.map((mora) => mora.text).join(""); if (props.accentPhrase.pauseMora) { textString += "、"; } + beforeText = textString; return textString; }); -const handleChangePronounce = (newPronunciation: string) => { +const handleChangePronounce = async (newPronunciation: string) => { + console.log("AccentPhrase.vue > handleChangePronounce"); + const copyBeforeText = beforeText; + let popUntilPause = false; newPronunciation = newPronunciation .replace(/,/g, "、") @@ -278,12 +284,31 @@ const handleChangePronounce = (newPronunciation: string) => { popUntilPause = true; } } - store.dispatch("COMMAND_CHANGE_SINGLE_ACCENT_PHRASE", { + await store.dispatch("COMMAND_CHANGE_SINGLE_ACCENT_PHRASE", { audioKey: props.audioKey, newPronunciation, accentPhraseIndex: props.index, popUntilPause, }); + + // e.AccentPhrasesをfetchしたとき(読み変更で句読点を含めたとき) + // 適用範囲: 現在選択しているAudioItem + console.log(`copyBeforeText: ${copyBeforeText}`); + console.log(`newPronunciation: ${newPronunciation}`); + await console.log(store.state.audioItems[props.audioKey]); + if (store.state.pauseLengthMode === "ABSOLUTE") { + // テキストが変更されて、かつ読点が追加されたことを確認 + if (!copyBeforeText.includes("、") && newPronunciation.includes("、")) { + const pauseLength = + store.state.audioItems[props.audioKey].query?.pauseLength; + if (pauseLength != null && pauseLength != undefined) { + store.dispatch("COMMAND_MULTI_APPLY_PAUSE_LENGTH", { + audioKeys: [props.audioKey], + pauseLength: pauseLength, + }); + } + } + } }; const hoveredMoraIndex = ref(undefined); @@ -371,6 +396,9 @@ const changeMoraData = ( data: number, type: MoraDataType, ) => { + console.log("AccentPhrase.vue >chageMoraData"); + console.log(`data: ${data}`); + console.log(`type: ${type}`); const accentPhraseIndex = props.index; if (!props.altKeyFlag) { if (type == "pitch") { diff --git a/src/components/Talk/AudioCell.vue b/src/components/Talk/AudioCell.vue index a69fc56a6e..6fbba85da7 100644 --- a/src/components/Talk/AudioCell.vue +++ b/src/components/Talk/AudioCell.vue @@ -291,6 +291,7 @@ const isSelectedAudioCell = computed(() => const audioTextBuffer = ref(audioItem.value.text); const isChangeFlag = ref(false); const setAudioTextBuffer = (text: string | number | null) => { + console.log("AudioCell.vue > setAudioTextBuffer"); if (typeof text !== "string") throw new Error("typeof text !== 'string'"); audioTextBuffer.value = text; isChangeFlag.value = true; @@ -307,6 +308,11 @@ watch( ); const pushAudioTextIfNeeded = async (event?: KeyboardEvent) => { + console.log("AudioCell.vue > pushAudioTextIfNeeded"); + console.log(`isChangeFlag: ${isChangeFlag.value}`); + // COMMAND_CHANGE_AUDIO_TEXTでもAccenPhrases弄ってるっぽいのでフラグをコピーして後で処理 + const copy_isChangeFlag = isChangeFlag.value; + if (event && event.isComposing) return; if (!willRemove.value && isChangeFlag.value && !willFocusOrBlur.value) { isChangeFlag.value = false; @@ -315,6 +321,23 @@ const pushAudioTextIfNeeded = async (event?: KeyboardEvent) => { text: audioTextBuffer.value, }); } + + // d.AudioQueryをfetchしたとき(テキスト入力したとき) + // 適用範囲: 現在選択しているAudioItem + // pushAudioTextIfNeededはblurで発火するので、さらにテキスト変更時に絞り込む + if ( + store.state.pauseLengthMode === "ABSOLUTE" && + copy_isChangeFlag === true + ) { + const pauseLength = + store.state.audioItems[props.audioKey].query?.pauseLength; + if (pauseLength != null && pauseLength != undefined) { + store.dispatch("COMMAND_MULTI_APPLY_PAUSE_LENGTH", { + audioKeys: [props.audioKey], + pauseLength: pauseLength, + }); + } + } }; // バグ修正用 diff --git a/src/components/Talk/AudioDetail.vue b/src/components/Talk/AudioDetail.vue index c8e152318f..d22fb44553 100644 --- a/src/components/Talk/AudioDetail.vue +++ b/src/components/Talk/AudioDetail.vue @@ -183,28 +183,11 @@ const selectedDetail = ref("accent"); // accent phrase const uiLocked = computed(() => store.getters.UI_LOCKED); -const switchPauseLengthMode = computed(() => store.state.switchPauseLengthMode); - const audioItem = computed(() => store.state.audioItems[props.activeAudioKey]); const query = computed(() => audioItem.value?.query); -// pauseLength&pauseLengthScaleにおいては、エンジン側で行う処理を例外的にここで行う -// storeへの反映はAccentPhrases.vueでやってくれる -const accentPhrases = computed(() => { - const newAccentPhrases = query.value?.accentPhrases; - if (switchPauseLengthMode.value === "ABSOLUTE" && newAccentPhrases) { - const pauseLength = query.value?.pauseLength; - if (pauseLength != null) { - newAccentPhrases.forEach((accentPhrase) => { - if (accentPhrase.pauseMora) { - accentPhrase.pauseMora.vowelLength = pauseLength; - } - }); - } - } - return newAccentPhrases; -}); +const accentPhrases = computed(() => query.value?.accentPhrases); // エンジンが変わったとき、selectedDetailが対応していないものを選択している場合はaccentに戻す // TODO: 連続再生するとアクセントに移動してしまうため、タブの中身を全てdisabledにする、半透明divをかぶせるなど diff --git a/src/components/Talk/AudioInfo.vue b/src/components/Talk/AudioInfo.vue index b8722e5659..1a3fc283e2 100644 --- a/src/components/Talk/AudioInfo.vue +++ b/src/components/Talk/AudioInfo.vue @@ -301,7 +301,7 @@ import { QSelectProps } from "quasar"; import CharacterButton from "@/components/CharacterButton.vue"; import PresetManageDialog from "@/components/Dialog/PresetManageDialog.vue"; import { useStore } from "@/store"; - +import { AudioItem } from "@/store/type"; import { AudioKey, CharacterInfo, @@ -332,9 +332,9 @@ const uiLocked = computed(() => store.getters.UI_LOCKED); const audioItem = computed(() => store.state.audioItems[props.activeAudioKey]); const query = computed(() => audioItem.value?.query); -// 句読点などの無音時間の指定方式 "SCALE" || "ABSOLUTE" -const switchPauseLengthMode = computed(() => { - return store.state.switchPauseLengthMode; +// 文内無音の指定方式 "SCALE" || "ABSOLUTE" +const pauseLengthMode = computed(() => { + return store.state.pauseLengthMode; }); const supportedFeatures = computed( @@ -361,8 +361,9 @@ const selectedAudioKeys = computed(() => // 句読点などの無音時間はひとまず倍率verを表示 のち必要に応じ絶対値に切替 const parameters = computed(() => { - const plParam: Parameter = { - label: "文内無音(秒)", + console.log("AudioInfo.vue > parameters"); + const pauseLengthParameter: Parameter = { + label: "文内無音", slider: previewSliderHelper({ modelValue: () => query.value?.pauseLength ?? null, disable: () => uiLocked.value, @@ -372,6 +373,9 @@ const parameters = computed(() => { scrollStep: SLIDER_PARAMETERS.PAUSE_LENGTH.scrollStep, scrollMinStep: SLIDER_PARAMETERS.PAUSE_LENGTH.scrollMinStep, onChange: (pauseLength: number) => + // b.query.pauseLengthにnull以外の値を代入したとき + // COMMAND_MULTI_SET_AUDIO_PAUSE_LENGTHから呼び出し + // 適用範囲: 現在選択しているaudioItem store.dispatch("COMMAND_MULTI_SET_AUDIO_PAUSE_LENGTH", { audioKeys: selectedAudioKeys.value, pauseLength: pauseLength, @@ -381,8 +385,8 @@ const parameters = computed(() => { key: "pauseLength", }; - const plsParam: Parameter = { - label: "文内無音(倍)", + const pauseLengthScaleParameter: Parameter = { + label: "文内無音倍率", slider: previewSliderHelper({ modelValue: () => query.value?.pauseLengthScale ?? null, disable: () => uiLocked.value, @@ -482,6 +486,7 @@ const parameters = computed(() => { action: "COMMAND_MULTI_SET_AUDIO_VOLUME_SCALE", key: "volumeScale", }, + pauseLengthScaleParameter, { label: "開始無音", slider: previewSliderHelper({ @@ -520,6 +525,7 @@ const parameters = computed(() => { action: "COMMAND_MULTI_SET_AUDIO_POST_PHONEME_LENGTH", key: "postPhonemeLength", }, +<<<<<<< Updated upstream { label: "文内無音(秒)", slider: previewSliderHelper({ @@ -543,10 +549,22 @@ const parameters = computed(() => { // switchPauseLengthModeの変更に伴って更新 const newParam = switchPauseLengthMode.value === "SCALE" ? plsParam : plParam; const index = baseParam.findIndex((param) => param.label === newParam.label); +======= + ]; + // pauseLengthModeの変更に伴って更新 + const newParam = + pauseLengthMode.value === "SCALE" + ? pauseLengthScaleParameter + : pauseLengthParameter; + const index = baseParam.findIndex((param) => + param.label.includes("文内無音"), + ); + +>>>>>>> Stashed changes if (index !== -1) { baseParam[index] = newParam; } else { - baseParam.push(newParam); + baseParam.splice(4, 0, newParam); } return baseParam; }); @@ -791,6 +809,7 @@ const presetList = computed<{ label: string; key: PresetKey }[]>(() => // セルへのプリセットの設定 const selectablePresetList = computed(() => { + console.log("AudioInfo.vue > selectablePresetList"); const topPresetList: { key: PresetKey | undefined; label: string }[] = []; if (isRegisteredPreset.value) { @@ -870,6 +889,7 @@ const closeAllDialog = () => { // プリセットの登録 const registerPreset = ({ overwrite }: { overwrite: boolean }) => { + console.log("AudioInfo.vue > registerPreset"); // 既存の場合は名前をセット if (isRegisteredPreset.value) { if (audioPresetKey.value == undefined) @@ -979,6 +999,31 @@ const updatePreset = async (fullApply: boolean) => { }); if (fullApply) { + if (store.state.pauseLengthMode === "ABSOLUTE") { + // c.「プリセットの再適用」をしたとき + // 適用範囲: 現在選択しているAudioItemとpresetKeyが同じAudioItem + const audioItems = store.state.audioItems; + console.log(audioItems); + const audioKeys: AudioKey[] = Object.keys( + audioItems as Record, + ) + .filter((audioKey) => { + const audioItem = audioItems[audioKey as keyof typeof audioItems]; + return audioItem.presetKey === key; + }) + .map((audioKey) => audioKey as unknown as AudioKey); + const activeAudioItem = audioItems[props.activeAudioKey]; + if (activeAudioItem && activeAudioItem.query) { + const pauseLength = activeAudioItem.query.pauseLength; + if (pauseLength != null) { + store.dispatch("COMMAND_MULTI_APPLY_PAUSE_LENGTH", { + audioKeys: audioKeys, + pauseLength: pauseLength, + }); + } + } + } + await store.dispatch("COMMAND_FULLY_APPLY_AUDIO_PRESET", { presetKey: key, }); diff --git a/src/openapi/models/Mora.ts b/src/openapi/models/Mora.ts index 430d8c2983..9f3f1c7faf 100644 --- a/src/openapi/models/Mora.ts +++ b/src/openapi/models/Mora.ts @@ -105,5 +105,4 @@ export function MoraToJSON(value?: Mora | null): any { 'vowel_length': value.vowelLength, 'pitch': value.pitch, }; -} - +} \ No newline at end of file diff --git a/src/store/audio.ts b/src/store/audio.ts index e2c300bda8..a814fca277 100644 --- a/src/store/audio.ts +++ b/src/store/audio.ts @@ -226,6 +226,33 @@ export function applyAudioPresetToAudioItem( return newAudioItem; } +/** + * 与えたAudioItemを元に、pauseLengthを適用した新しいAccentPhrasesを返す + * pauseLengthにおいては、エンジン側で行う処理を例外的にここで行う + */ +export function applyPauseLengthToAccentPhrases( + audioItem: AudioItem, + pauseLength: number, +): AudioItem { + console.log("applyPauseLengthToAccentPhrases"); + console.log(`pauseLength: ${pauseLength}`); + + const newAccentPhrases = audioItem?.query?.accentPhrases ?? []; + + const newAudioItem = audioItem; + + newAccentPhrases.forEach((accentPhrase) => { + if (accentPhrase.pauseMora) { + accentPhrase.pauseMora.vowelLength = pauseLength; + } + }); + if (newAudioItem.query) { + newAudioItem.query.accentPhrases = newAccentPhrases; + } + + return newAudioItem; +} + export const audioStoreState: AudioStoreState = { characterInfos: {}, audioKeysWithInitializingSpeaker: [], @@ -910,10 +937,7 @@ export const audioStore = createPartialStore({ SET_AUDIO_PAUSE_LENGTH: { mutation( state, - { - audioKey, - pauseLength, - }: { audioKey: AudioKey; pauseLength: number | null }, + { audioKey, pauseLength }: { audioKey: AudioKey; pauseLength: number }, ) { const query = state.audioItems[audioKey].query; if (query == undefined) throw new Error("query == undefined"); @@ -1152,6 +1176,22 @@ export const audioStore = createPartialStore({ }, }, + APPLY_PAUSE_LENGTH: { + mutation( + state, + { audioKey, pauseLength }: { audioKey: AudioKey; pauseLength: number }, + ) { + console.log("APPLY_PAUSE_LENGTH"); + const audioItem = state.audioItems[audioKey]; + + const newAudioItem = applyPauseLengthToAccentPhrases( + audioItem, + pauseLength, + ); + state.audioItems[audioKey] = newAudioItem; + }, + }, + FETCH_MORA_DATA: { action( { dispatch }, @@ -1283,7 +1323,7 @@ export const audioStore = createPartialStore({ length += m.consonantLength != undefined ? m.consonantLength : 0; length += m.vowelLength; }); - if (state.switchPauseLengthMode === "SCALE") { + if (state.pauseLengthMode === "SCALE") { length += phrase.pauseMora ? phrase.pauseMora.vowelLength * query.pauseLengthScale : 0; @@ -1309,10 +1349,6 @@ export const audioStore = createPartialStore({ const audioItem: AudioItem = JSON.parse( JSON.stringify(state.audioItems[audioKey]), ); - // pauseLength&pauseLengthScaleは無効(APIに相当する処理はAudioDetail.vue > accentPhraseで既に済んでる) - if (audioItem.query) { - audioItem.query.pauseLength = null; - } return dispatch("FETCH_AUDIO_FROM_AUDIO_ITEM", { audioItem, ...options, @@ -2388,6 +2424,7 @@ export const audioCommandStore = transformCommandStore( popUntilPause: boolean; }, ) { + console.log("COMMAND_CHANGE_SINGLE_ACCENT_PHRASE"); const engineId = state.audioItems[audioKey].voice.engineId; const styleId = state.audioItems[audioKey].voice.styleId; @@ -2769,7 +2806,7 @@ export const audioCommandStore = transformCommandStore( draft, payload: { audioKeys: AudioKey[]; - pauseLength: number | null; + pauseLength: number; }, ) { for (const audioKey of payload.audioKeys) { @@ -2780,10 +2817,15 @@ export const audioCommandStore = transformCommandStore( } }, action( - { commit }, - payload: { audioKeys: AudioKey[]; pauseLength: number | null }, + { commit, dispatch }, + payload: { audioKeys: AudioKey[]; pauseLength: number }, ) { + console.log("COMMAND_MULTI_SET_AUDIO_PAUSE_LENGTH"); commit("COMMAND_MULTI_SET_AUDIO_PAUSE_LENGTH", payload); + dispatch("COMMAND_MULTI_APPLY_PAUSE_LENGTH", { + audioKeys: payload.audioKeys, + pauseLength: payload.pauseLength, + }); }, }, @@ -2874,6 +2916,30 @@ export const audioCommandStore = transformCommandStore( }, }, + COMMAND_MULTI_APPLY_PAUSE_LENGTH: { + mutation( + draft, + payload: { + audioKeys: AudioKey[]; + pauseLength: number; + }, + ) { + for (const audioKey of payload.audioKeys) { + audioStore.mutations.APPLY_PAUSE_LENGTH(draft, { + audioKey, + pauseLength: payload.pauseLength, + }); + } + }, + action( + { commit }, + payload: { audioKeys: AudioKey[]; pauseLength: number }, + ) { + console.log("COMMAND_MULTI_APPLY_PAUSE_LENGTH"); + commit("COMMAND_MULTI_APPLY_PAUSE_LENGTH", payload); + }, + }, + COMMAND_FULLY_APPLY_AUDIO_PRESET: { mutation(draft, { presetKey }: { presetKey: PresetKey }) { const targetAudioKeys = draft.audioKeys.filter( diff --git a/src/store/audioGenerate.ts b/src/store/audioGenerate.ts index 7d9ca52b74..a526df49f0 100644 --- a/src/store/audioGenerate.ts +++ b/src/store/audioGenerate.ts @@ -43,6 +43,7 @@ export async function fetchAudioFromAudioItem( const engineAudioQuery = convertAudioQueryFromEditorToEngine( audioQuery, state.engineManifests[engineId].defaultSamplingRate, + state.pauseLengthMode, ); let blob: Blob; diff --git a/src/store/preset.ts b/src/store/preset.ts index c5c213ab94..9e29601390 100644 --- a/src/store/preset.ts +++ b/src/store/preset.ts @@ -220,7 +220,7 @@ export const presetStore = createPartialStore({ volumeScale: 1.0, prePhonemeLength: 0.1, postPhonemeLength: 0.1, - pauseLength: 0.3, + pauseLength: null, pauseLengthScale: 1, }; const newPresetKey = await dispatch("ADD_PRESET", { presetData }); diff --git a/src/store/project.ts b/src/store/project.ts index 71cb0b6ba4..6519902dc0 100755 --- a/src/store/project.ts +++ b/src/store/project.ts @@ -256,7 +256,7 @@ export const projectStore = createPartialStore({ 0.1; projectData.audioItems[audioItemsKey].query.postPhonemeLength = 0.1; - projectData.audioItems[audioItemsKey].query.pauseLength = 0.3; + projectData.audioItems[audioItemsKey].query.pauseLength = null; projectData.audioItems[audioItemsKey].query.pauseLengthScale = 1; projectData.audioItems[audioItemsKey].query.outputSamplingRate = diff --git a/src/store/proxy.ts b/src/store/proxy.ts index 799ef3e069..b3dcebb1aa 100644 --- a/src/store/proxy.ts +++ b/src/store/proxy.ts @@ -38,14 +38,27 @@ const proxyStoreCreator = (_engineFactory: IEngineConnectorFactory) => { export const convertAudioQueryFromEditorToEngine = ( editorAudioQuery: EditorAudioQuery, defaultOutputSamplingRate: number, + pauseLengthMode: "SCALE" | "ABSOLUTE", ): AudioQuery => { - return { - ...editorAudioQuery, - outputSamplingRate: - editorAudioQuery.outputSamplingRate == "engineDefault" - ? defaultOutputSamplingRate - : editorAudioQuery.outputSamplingRate, - }; + console.log("convertAudioQueryFromEditorToEngine"); + // editorAudioQuery の内容をそのままコピーする + const convertedQuery: AudioQuery = { ...editorAudioQuery }; + + // outputSamplingRate を設定する + convertedQuery.outputSamplingRate = + editorAudioQuery.outputSamplingRate === "engineDefault" + ? defaultOutputSamplingRate + : editorAudioQuery.outputSamplingRate; + + // 不要なプロパティ除去 + if (pauseLengthMode === "ABSOLUTE") { + delete editorAudioQuery.pauseLengthScale; + } else { + delete editorAudioQuery.pauseLength; + } + console.log(editorAudioQuery); + // 変換されたオブジェクトを返す + return convertedQuery; }; export const proxyStore = proxyStoreCreator(OpenAPIEngineConnectorFactory); diff --git a/src/store/type.ts b/src/store/type.ts index 20913afee2..2309e3af0f 100644 --- a/src/store/type.ts +++ b/src/store/type.ts @@ -34,7 +34,7 @@ import { UpdateInfo, Preset, MorphingInfo, - SwitchPauseLengthMode, + PauseLengthMode, ActivePointScrollMode, EngineInfo, ConfirmedTips, @@ -291,7 +291,7 @@ export type AudioStoreTypes = { }; SET_AUDIO_PAUSE_LENGTH: { - mutation: { audioKey: AudioKey; pauseLength: number | null }; + mutation: { audioKey: AudioKey; pauseLength: number }; }; SET_AUDIO_PAUSE_LENGTH_SCALE: { @@ -380,6 +380,10 @@ export type AudioStoreTypes = { mutation: { audioKey: AudioKey }; }; + APPLY_PAUSE_LENGTH: { + mutation: { audioKey: AudioKey; pauseLength: number }; + }; + FETCH_MORA_DATA: { action(payload: { accentPhrases: AccentPhrase[]; @@ -638,11 +642,8 @@ export type AudioCommandStoreTypes = { }; COMMAND_MULTI_SET_AUDIO_PAUSE_LENGTH: { - mutation: { audioKeys: AudioKey[]; pauseLength: number | null }; - action(payload: { - audioKeys: AudioKey[]; - pauseLength: number | null; - }): void; + mutation: { audioKeys: AudioKey[]; pauseLength: number }; + action(payload: { audioKeys: AudioKey[]; pauseLength: number }): void; }; COMMAND_MULTI_SET_AUDIO_PAUSE_LENGTH_SCALE: { @@ -677,6 +678,11 @@ export type AudioCommandStoreTypes = { action(payload: { audioKeys: AudioKey[] }): void; }; + COMMAND_MULTI_APPLY_PAUSE_LENGTH: { + mutation: { audioKeys: AudioKey[]; pauseLength: number }; + action(payload: { audioKeys: AudioKey[]; pauseLength: number }): void; + }; + COMMAND_FULLY_APPLY_AUDIO_PRESET: { mutation: { presetKey: PresetKey }; action(payload: { presetKey: PresetKey }): void; @@ -1647,7 +1653,7 @@ export type UiStoreState = { uiLockCount: number; dialogLockCount: number; reloadingLock: boolean; - switchPauseLengthMode: SwitchPauseLengthMode; + pauseLengthMode: PauseLengthMode; inheritAudioInfo: boolean; activePointScrollMode: ActivePointScrollMode; isHelpDialogOpen: boolean; @@ -1788,9 +1794,9 @@ export type UiStoreTypes = { action(): void; }; - SET_SWITCH_PAUSE_LENGTH_MODE: { - mutation: { switchPauseLengthMode: SwitchPauseLengthMode }; - action(payload: { switchPauseLengthMode: SwitchPauseLengthMode }): void; + SET_PAUSE_LENGTH_MODE: { + mutation: { pauseLengthMode: PauseLengthMode }; + action(payload: { pauseLengthMode: PauseLengthMode }): void; }; SET_INHERIT_AUDIOINFO: { diff --git a/src/store/ui.ts b/src/store/ui.ts index b8a12730d3..f517b1483a 100644 --- a/src/store/ui.ts +++ b/src/store/ui.ts @@ -7,7 +7,7 @@ import { UiStoreTypes, } from "./type"; import { createPartialStore } from "./vuex"; -import { SwitchPauseLengthMode } from "@/type/preload"; +import { PauseLengthMode } from "@/type/preload"; import { ActivePointScrollMode } from "@/type/preload"; import { CommonDialogOptions, @@ -54,7 +54,7 @@ export const uiStoreState: UiStoreState = { uiLockCount: 0, dialogLockCount: 0, reloadingLock: false, - switchPauseLengthMode: "SCALE", + pauseLengthMode: "SCALE", inheritAudioInfo: true, activePointScrollMode: "OFF", isHelpDialogOpen: false, @@ -259,10 +259,8 @@ export const uiStore = createPartialStore({ HYDRATE_UI_STORE: { async action({ commit }) { - commit("SET_SWITCH_PAUSE_LENGTH_MODE", { - switchPauseLengthMode: await window.backend.getSetting( - "switchPauseLengthMode", - ), + commit("SET_PAUSE_LENGTH_MODE", { + pauseLengthMode: await window.backend.getSetting("pauseLengthMode"), }); commit("SET_INHERIT_AUDIOINFO", { @@ -309,25 +307,18 @@ export const uiStore = createPartialStore({ }, }, - SET_SWITCH_PAUSE_LENGTH_MODE: { - mutation( - state, - { - switchPauseLengthMode, - }: { switchPauseLengthMode: SwitchPauseLengthMode }, - ) { - state.switchPauseLengthMode = switchPauseLengthMode; + SET_PAUSE_LENGTH_MODE: { + mutation(state, { pauseLengthMode }: { pauseLengthMode: PauseLengthMode }) { + state.pauseLengthMode = pauseLengthMode; }, async action( { commit }, - { - switchPauseLengthMode, - }: { switchPauseLengthMode: SwitchPauseLengthMode }, + { pauseLengthMode }: { pauseLengthMode: PauseLengthMode }, ) { - commit("SET_SWITCH_PAUSE_LENGTH_MODE", { - switchPauseLengthMode: await window.backend.setSetting( - "switchPauseLengthMode", - switchPauseLengthMode, + commit("SET_PAUSE_LENGTH_MODE", { + pauseLengthMode: await window.backend.setSetting( + "pauseLengthMode", + pauseLengthMode, ), }); }, diff --git a/src/store/utility.ts b/src/store/utility.ts index 49f5cff8a9..db6f613988 100644 --- a/src/store/utility.ts +++ b/src/store/utility.ts @@ -109,7 +109,7 @@ export const SLIDER_PARAMETERS = { max: () => 1, min: () => 0, step: () => 0.01, - scrollStep: () => 0.01, + scrollStep: () => 0.1, scrollMinStep: () => 0.01, }, /** diff --git a/src/type/preload.ts b/src/type/preload.ts index 903fb86c2d..dd2c9c478e 100644 --- a/src/type/preload.ts +++ b/src/type/preload.ts @@ -349,7 +349,7 @@ export type AcceptRetrieveTelemetryStatus = export type AcceptTermsStatus = "Unconfirmed" | "Accepted" | "Rejected"; -export type SwitchPauseLengthMode = "SCALE" | "ABSOLUTE"; +export type PauseLengthMode = "SCALE" | "ABSOLUTE"; export type ActivePointScrollMode = "CONTINUOUSLY" | "PAGE" | "OFF"; @@ -605,7 +605,7 @@ export type RootMiscSettingType = z.infer; export const configSchema = z .object({ - switchPauseLengthMode: z.enum(["SCALE", "ABSOLUTE"]).default("SCALE"), + pauseLengthMode: z.enum(["SCALE", "ABSOLUTE"]).default("SCALE"), inheritAudioInfo: z.boolean().default(true), activePointScrollMode: z .enum(["CONTINUOUSLY", "PAGE", "OFF"]) diff --git a/tests/unit/backend/common/pastConfigs/0.13.json b/tests/unit/backend/common/pastConfigs/0.13.json index 21845b68dc..a7b8c3bd89 100644 --- a/tests/unit/backend/common/pastConfigs/0.13.json +++ b/tests/unit/backend/common/pastConfigs/0.13.json @@ -1,6 +1,6 @@ { "useGpu": false, - "switchPauseLengthMode": "SCALE", + "pauseLengthMode": "SCALE", "inheritAudioInfo": true, "activePointScrollMode": "OFF", "savingSetting": { From 990973b44a17ff754bc7f3b4fe2affbd6ac439b2 Mon Sep 17 00:00:00 2001 From: X-20A <155217226+X-20A@users.noreply.github.com> Date: Thu, 13 Jun 2024 04:59:46 +0900 Subject: [PATCH 36/86] test --- docker-compose.yml | 6 +++--- src/components/Talk/AccentPhrase.vue | 2 +- src/components/Talk/AudioInfo.vue | 26 -------------------------- src/store/audioGenerate.ts | 3 ++- src/store/proxy.ts | 24 ++++++++++++------------ 5 files changed, 18 insertions(+), 43 deletions(-) diff --git a/docker-compose.yml b/docker-compose.yml index c7215ca192..e6e99519fa 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -3,7 +3,7 @@ services: test: build: . working_dir: /work - # If you don't have node_modules, use "npm ci", install node_modules into the yor directory. + # If you don't have node_modules, use "npm ci", install node_modules into the your directory. # Use command bellow # `docker-compose up -d --build` # The container will stop automatically after install @@ -12,7 +12,7 @@ services: # command: "npm ci" - # After node_modules install, use command bellow to exec "/bin/sh" and the container will remain. + # After node_modules install, use command bellow to exec "/bin/sh" and the container will remain. # `docker-compose up -d` # To access container, use command bellow # `docker exec -it voicevox_test_1 /bin/bash` @@ -21,7 +21,7 @@ services: # If you want test automatically (test runs when you save any files), use this command property and view logs - # Use Command bellow + # Use Command bellow # `docker logs --tail 1000 -f voicevox_test_1` command: "npm run test-watch:unit " diff --git a/src/components/Talk/AccentPhrase.vue b/src/components/Talk/AccentPhrase.vue index 79d3b6c3ee..5fa84141f7 100644 --- a/src/components/Talk/AccentPhrase.vue +++ b/src/components/Talk/AccentPhrase.vue @@ -396,7 +396,7 @@ const changeMoraData = ( data: number, type: MoraDataType, ) => { - console.log("AccentPhrase.vue >chageMoraData"); + console.log("AccentPhrase.vue > changeMoraData"); console.log(`data: ${data}`); console.log(`type: ${type}`); const accentPhraseIndex = props.index; diff --git a/src/components/Talk/AudioInfo.vue b/src/components/Talk/AudioInfo.vue index 1a3fc283e2..a357ee73fb 100644 --- a/src/components/Talk/AudioInfo.vue +++ b/src/components/Talk/AudioInfo.vue @@ -525,31 +525,6 @@ const parameters = computed(() => { action: "COMMAND_MULTI_SET_AUDIO_POST_PHONEME_LENGTH", key: "postPhonemeLength", }, -<<<<<<< Updated upstream - { - label: "文内無音(秒)", - slider: previewSliderHelper({ - modelValue: () => query.value?.pauseLength ?? null, - disable: () => uiLocked.value, - max: SLIDER_PARAMETERS.PAUSE_LENGTH.max, - min: SLIDER_PARAMETERS.PAUSE_LENGTH.min, - step: SLIDER_PARAMETERS.PAUSE_LENGTH.step, - scrollStep: SLIDER_PARAMETERS.PAUSE_LENGTH.scrollStep, - scrollMinStep: SLIDER_PARAMETERS.PAUSE_LENGTH.scrollMinStep, - onChange: (pauseLength: number) => - store.dispatch("COMMAND_MULTI_SET_AUDIO_PAUSE_LENGTH", { - audioKeys: selectedAudioKeys.value, - pauseLength: pauseLength, - }), - }), - action: "COMMAND_MULTI_SET_AUDIO_PAUSE_LENGTH", - key: "pauseLength", - }, - ]; // 文内無音は何故か変数埋め込みだと「test("複数選択:AudioInfo操作"・・・」でvisibilityでfillが効かない - // switchPauseLengthModeの変更に伴って更新 - const newParam = switchPauseLengthMode.value === "SCALE" ? plsParam : plParam; - const index = baseParam.findIndex((param) => param.label === newParam.label); -======= ]; // pauseLengthModeの変更に伴って更新 const newParam = @@ -560,7 +535,6 @@ const parameters = computed(() => { param.label.includes("文内無音"), ); ->>>>>>> Stashed changes if (index !== -1) { baseParam[index] = newParam; } else { diff --git a/src/store/audioGenerate.ts b/src/store/audioGenerate.ts index a526df49f0..9cbd2c4ccd 100644 --- a/src/store/audioGenerate.ts +++ b/src/store/audioGenerate.ts @@ -1,6 +1,7 @@ import { AudioItem, AudioStoreState, + UiStoreState, EditorAudioQuery, FetchAudioResult, IEngineConnectorFactoryActionsMapper, @@ -19,7 +20,7 @@ type Instance = { * エンジンで音声を合成する。音声のキャッシュ機構も備える。 */ export async function fetchAudioFromAudioItem( - state: AudioStoreState & SettingStoreState, + state: AudioStoreState & SettingStoreState & UiStoreState, instance: Instance, { audioItem, diff --git a/src/store/proxy.ts b/src/store/proxy.ts index b3dcebb1aa..051a458004 100644 --- a/src/store/proxy.ts +++ b/src/store/proxy.ts @@ -42,23 +42,23 @@ export const convertAudioQueryFromEditorToEngine = ( ): AudioQuery => { console.log("convertAudioQueryFromEditorToEngine"); // editorAudioQuery の内容をそのままコピーする - const convertedQuery: AudioQuery = { ...editorAudioQuery }; + const newAudioQuery = { + ...editorAudioQuery, + outputSamplingRate: + editorAudioQuery.outputSamplingRate == "engineDefault" + ? defaultOutputSamplingRate + : editorAudioQuery.outputSamplingRate, + }; - // outputSamplingRate を設定する - convertedQuery.outputSamplingRate = - editorAudioQuery.outputSamplingRate === "engineDefault" - ? defaultOutputSamplingRate - : editorAudioQuery.outputSamplingRate; - - // 不要なプロパティ除去 + // 不要なプロパティを無効化 if (pauseLengthMode === "ABSOLUTE") { - delete editorAudioQuery.pauseLengthScale; + newAudioQuery.pauseLengthScale = 1; } else { - delete editorAudioQuery.pauseLength; + newAudioQuery.pauseLength = null; } - console.log(editorAudioQuery); + console.log(newAudioQuery); // 変換されたオブジェクトを返す - return convertedQuery; + return newAudioQuery; }; export const proxyStore = proxyStoreCreator(OpenAPIEngineConnectorFactory); From c5a4c551ed1352cfb82703ac9ec8fe229df3f8c4 Mon Sep 17 00:00:00 2001 From: X-20A <155217226+X-20A@users.noreply.github.com> Date: Thu, 13 Jun 2024 05:12:39 +0900 Subject: [PATCH 37/86] =?UTF-8?q?UI=E3=82=92=E5=A4=89=E6=9B=B4=20[update?= =?UTF-8?q?=20snapshots]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/Talk/AudioInfo.vue | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/Talk/AudioInfo.vue b/src/components/Talk/AudioInfo.vue index a357ee73fb..bfab36fc56 100644 --- a/src/components/Talk/AudioInfo.vue +++ b/src/components/Talk/AudioInfo.vue @@ -526,7 +526,7 @@ const parameters = computed(() => { key: "postPhonemeLength", }, ]; - // pauseLengthModeの変更に伴って更新 + // pauseLengthModeの変更に伴って切替 const newParam = pauseLengthMode.value === "SCALE" ? pauseLengthScaleParameter From 84b42098450b3748af87b95289a11c0c0ea214d7 Mon Sep 17 00:00:00 2001 From: X-20A <155217226+X-20A@users.noreply.github.com> Date: Thu, 13 Jun 2024 07:43:13 +0900 Subject: [PATCH 38/86] =?UTF-8?q?UI=E3=82=92=E5=A4=89=E6=9B=B4=20[update?= =?UTF-8?q?=20snapshots]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docker-compose.yml | 4 ++-- src/components/Dialog/AllDialog.vue | 10 +--------- src/components/Talk/AccentPhrase.vue | 3 --- src/components/Talk/AudioDetail.vue | 2 -- src/components/Talk/AudioInfo.vue | 1 - src/store/audio.ts | 1 - 6 files changed, 3 insertions(+), 18 deletions(-) diff --git a/docker-compose.yml b/docker-compose.yml index e6e99519fa..4e79ef7d2a 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,9 +1,9 @@ version: '3' services: test: - build: . + build: . working_dir: /work - # If you don't have node_modules, use "npm ci", install node_modules into the your directory. + # If you don't have node_modules, use "npm ci", install node_modules into the yor directory. # Use command bellow # `docker-compose up -d --build` # The container will stop automatically after install diff --git a/src/components/Dialog/AllDialog.vue b/src/components/Dialog/AllDialog.vue index cb09b3a75f..981cae021e 100644 --- a/src/components/Dialog/AllDialog.vue +++ b/src/components/Dialog/AllDialog.vue @@ -4,10 +4,7 @@ /> - + (); const store = useStore(); -const activeAudioKey = computed( - () => store.getters.ACTIVE_AUDIO_KEY, -); - // ライセンス表示 const isHelpDialogOpenComputed = computed({ get: () => store.state.isHelpDialogOpen, diff --git a/src/components/Talk/AccentPhrase.vue b/src/components/Talk/AccentPhrase.vue index 5fa84141f7..ea89e94397 100644 --- a/src/components/Talk/AccentPhrase.vue +++ b/src/components/Talk/AccentPhrase.vue @@ -396,9 +396,6 @@ const changeMoraData = ( data: number, type: MoraDataType, ) => { - console.log("AccentPhrase.vue > changeMoraData"); - console.log(`data: ${data}`); - console.log(`type: ${type}`); const accentPhraseIndex = props.index; if (!props.altKeyFlag) { if (type == "pitch") { diff --git a/src/components/Talk/AudioDetail.vue b/src/components/Talk/AudioDetail.vue index d22fb44553..f44aad85f0 100644 --- a/src/components/Talk/AudioDetail.vue +++ b/src/components/Talk/AudioDetail.vue @@ -184,9 +184,7 @@ const selectedDetail = ref("accent"); const uiLocked = computed(() => store.getters.UI_LOCKED); const audioItem = computed(() => store.state.audioItems[props.activeAudioKey]); - const query = computed(() => audioItem.value?.query); - const accentPhrases = computed(() => query.value?.accentPhrases); // エンジンが変わったとき、selectedDetailが対応していないものを選択している場合はaccentに戻す diff --git a/src/components/Talk/AudioInfo.vue b/src/components/Talk/AudioInfo.vue index bfab36fc56..7e5bf49562 100644 --- a/src/components/Talk/AudioInfo.vue +++ b/src/components/Talk/AudioInfo.vue @@ -783,7 +783,6 @@ const presetList = computed<{ label: string; key: PresetKey }[]>(() => // セルへのプリセットの設定 const selectablePresetList = computed(() => { - console.log("AudioInfo.vue > selectablePresetList"); const topPresetList: { key: PresetKey | undefined; label: string }[] = []; if (isRegisteredPreset.value) { diff --git a/src/store/audio.ts b/src/store/audio.ts index a814fca277..f7a5227289 100644 --- a/src/store/audio.ts +++ b/src/store/audio.ts @@ -2424,7 +2424,6 @@ export const audioCommandStore = transformCommandStore( popUntilPause: boolean; }, ) { - console.log("COMMAND_CHANGE_SINGLE_ACCENT_PHRASE"); const engineId = state.audioItems[audioKey].voice.engineId; const styleId = state.audioItems[audioKey].voice.styleId; From 598ce6921b25397fc61dc205f943a0bb70098372 Mon Sep 17 00:00:00 2001 From: X-20A <155217226+X-20A@users.noreply.github.com> Date: Thu, 13 Jun 2024 10:27:06 +0900 Subject: [PATCH 39/86] test --- .env.production | 14 --------- .env.test | 14 --------- src/backend/electron/main.ts | 9 ++++-- src/components/Dialog/AcceptTermsDialog.vue | 1 + src/components/Dialog/EngineManageDialog.vue | 1 + src/components/Dialog/SettingDialog.vue | 31 +++++++++++--------- src/components/EngineStartupOverlay.vue | 1 + src/plugins/ipcMessageReceiverPlugin.ts | 1 + src/store/project.ts | 1 + src/store/ui.ts | 1 + 10 files changed, 29 insertions(+), 45 deletions(-) delete mode 100644 .env.production delete mode 100644 .env.test diff --git a/.env.production b/.env.production deleted file mode 100644 index 5b0dcb0498..0000000000 --- a/.env.production +++ /dev/null @@ -1,14 +0,0 @@ -VITE_APP_NAME=voicevox -VITE_DEFAULT_ENGINE_INFOS=`[ - { - "uuid": "074fc39e-678b-4c13-8916-ffca8d505d1d", - "name": "VOICEVOX Engine", - "executionEnabled": true, - "executionFilePath": "vv-engine/run.exe", - "executionArgs": [], - "host": "http://127.0.0.1:50021" - } -]` -VITE_OFFICIAL_WEBSITE_URL=https://voicevox.hiroshiba.jp/ -VITE_LATEST_UPDATE_INFOS_URL=https://raw.githubusercontent.com/VOICEVOX/voicevox_blog/master/src/data/updateInfos.json -VITE_GTM_CONTAINER_ID=GTM-DUMMY diff --git a/.env.test b/.env.test deleted file mode 100644 index dcf447f8b2..0000000000 --- a/.env.test +++ /dev/null @@ -1,14 +0,0 @@ -VITE_APP_NAME=voicevox -VITE_DEFAULT_ENGINE_INFOS=`[ - { - "uuid": "074fc39e-678b-4c13-8916-ffca8d505d1d", - "name": "VOICEVOX Engine", - "executionEnabled": true, - "executionFilePath": "../voicevox_engine/run.exe", - "executionArgs": [], - "host": "http://127.0.0.1:50021" - } -]` -VITE_OFFICIAL_WEBSITE_URL=https://voicevox.hiroshiba.jp/ -VITE_LATEST_UPDATE_INFOS_URL=https://raw.githubusercontent.com/VOICEVOX/voicevox_blog/master/src/data/updateInfos.json -VITE_GTM_CONTAINER_ID=GTM-DUMMY diff --git a/src/backend/electron/main.ts b/src/backend/electron/main.ts index 1889dee3ec..eb3b9e30d9 100644 --- a/src/backend/electron/main.ts +++ b/src/backend/electron/main.ts @@ -254,9 +254,10 @@ async function installVvppEngineWithWarning({ }) .then((result) => { if (result.response === 0) { - ipcMainSend(win, "CHECK_EDITED_AND_NOT_SAVE", { + ipcMainSend(win, "CHECK_EDITED_AND_NOT_SAVE", { // これじゃない closeOrReload: "reload", }); + console.log("installVvppEngineWithWarning"); } }); } @@ -456,9 +457,10 @@ async function createWindow() { win.on("close", (event) => { if (!appState.willQuit) { event.preventDefault(); - ipcMainSend(win, "CHECK_EDITED_AND_NOT_SAVE", { + ipcMainSend(win, "CHECK_EDITED_AND_NOT_SAVE", { // これじゃない closeOrReload: "close", }); + console.log("win.on > close"); return; } }); @@ -1038,7 +1040,8 @@ app.on("window-all-closed", () => { app.on("before-quit", async (event) => { if (!appState.willQuit) { event.preventDefault(); - ipcMainSend(win, "CHECK_EDITED_AND_NOT_SAVE", { closeOrReload: "close" }); + ipcMainSend(win, "CHECK_EDITED_AND_NOT_SAVE", { closeOrReload: "close" }); // これじゃない + console.log("before-quit"); return; } diff --git a/src/components/Dialog/AcceptTermsDialog.vue b/src/components/Dialog/AcceptTermsDialog.vue index 88d4aaa123..92b1c07110 100644 --- a/src/components/Dialog/AcceptTermsDialog.vue +++ b/src/components/Dialog/AcceptTermsDialog.vue @@ -81,6 +81,7 @@ const modelValueComputed = computed({ }); const handler = (acceptTerms: boolean) => { + console.log("handler"); store.dispatch("SET_ACCEPT_TERMS", { acceptTerms: acceptTerms ? "Accepted" : "Rejected", }); diff --git a/src/components/Dialog/EngineManageDialog.vue b/src/components/Dialog/EngineManageDialog.vue index ddc3315925..c2c63ad9be 100644 --- a/src/components/Dialog/EngineManageDialog.vue +++ b/src/components/Dialog/EngineManageDialog.vue @@ -577,6 +577,7 @@ const restartSelectedEngine = () => { }; const requireReload = async (message: string) => { + console.log("requireReload"); const result = await store.dispatch("SHOW_WARNING_DIALOG", { title: "再読み込みが必要です", message: message, diff --git a/src/components/Dialog/SettingDialog.vue b/src/components/Dialog/SettingDialog.vue index 1e8caa7352..5cf00c0a95 100644 --- a/src/components/Dialog/SettingDialog.vue +++ b/src/components/Dialog/SettingDialog.vue @@ -1128,20 +1128,23 @@ const audioKeys = computed(() => store.state.audioKeys); watchEffect(() => { console.log("SettingDialog.vue > watchEffect"); - console.log(`audioKeys: ${audioKeys.value}`); - if (pauseLengthMode.value === "ABSOLUTE") { - // a.設定で絶対値モードに変更し、query.pauseLengthにnull以外の値が入っているとき - // 適用範囲: 全てのaudioItem - // COMMAND_MULTI_SET_AUDIO_PAUSE_LENGTHから呼び出し - store.dispatch("COMMAND_MULTI_SET_AUDIO_PAUSE_LENGTH", { - audioKeys: store.state.audioKeys, - pauseLength: 0.3, - }); - } else { - store.dispatch("COMMAND_MULTI_SET_AUDIO_PAUSE_LENGTH_SCALE", { - audioKeys: store.state.audioKeys, - pauseLengthScale: 1, - }); + const nonComputedAudioKeys = store.state.audioKeys; + console.log(nonComputedAudioKeys); + if(nonComputedAudioKeys.length > 0) { + if (pauseLengthMode.value === "ABSOLUTE") { + // a.設定で絶対値モードに変更し、query.pauseLengthにnull以外の値が入っているとき + // 適用範囲: 全てのaudioItem + // COMMAND_MULTI_SET_AUDIO_PAUSE_LENGTHから呼び出し + store.dispatch("COMMAND_MULTI_SET_AUDIO_PAUSE_LENGTH", { + audioKeys: nonComputedAudioKeys, + pauseLength: 0.3, + }); + } else { + store.dispatch("COMMAND_MULTI_SET_AUDIO_PAUSE_LENGTH_SCALE", { + audioKeys: nonComputedAudioKeys, + pauseLengthScale: 1, + }); + } } }); diff --git a/src/components/EngineStartupOverlay.vue b/src/components/EngineStartupOverlay.vue index 41627cffcb..806d0f43a5 100644 --- a/src/components/EngineStartupOverlay.vue +++ b/src/components/EngineStartupOverlay.vue @@ -91,6 +91,7 @@ watch(allEngineState, (newEngineState) => { }); const reloadAppWithMultiEngineOffMode = () => { + console.log("reloadAppWithMultiEngineOffMode"); store.dispatch("CHECK_EDITED_AND_NOT_SAVE", { closeOrReload: "reload", isMultiEngineOffMode: true, diff --git a/src/plugins/ipcMessageReceiverPlugin.ts b/src/plugins/ipcMessageReceiverPlugin.ts index 87caec21fb..cbfa07cac3 100644 --- a/src/plugins/ipcMessageReceiverPlugin.ts +++ b/src/plugins/ipcMessageReceiverPlugin.ts @@ -45,6 +45,7 @@ export const ipcMessageReceiver: Plugin = { ); window.backend.onReceivedIPCMsg("CHECK_EDITED_AND_NOT_SAVE", (_, obj) => { + console.log("window.backend.onReceivedIPCMsg"); options.store.dispatch("CHECK_EDITED_AND_NOT_SAVE", obj); }); diff --git a/src/store/project.ts b/src/store/project.ts index 6519902dc0..5879f64add 100755 --- a/src/store/project.ts +++ b/src/store/project.ts @@ -620,6 +620,7 @@ export const projectStore = createPartialStore({ */ SAVE_OR_DISCARD_PROJECT_FILE: { action: createUILockAction(async ({ dispatch }, { additionalMessage }) => { + console.log("SAVE_OR_DISCARD_PROJECT_FILE"); let message = "プロジェクトの変更が保存されていません。"; if (additionalMessage) { message += "\n" + additionalMessage; diff --git a/src/store/ui.ts b/src/store/ui.ts index f517b1483a..ac7a5793de 100644 --- a/src/store/ui.ts +++ b/src/store/ui.ts @@ -432,6 +432,7 @@ export const uiStore = createPartialStore({ * 保存がキャンセルされた場合は何もしない。 */ async action({ dispatch, getters }, obj) { + console.log("CHECK_EDITED_AND_NOT_SAVE"); await dispatch("SING_STOP_AUDIO"); // FIXME: ON_BEFORE_QUITTINGなどを作成して移動すべき if (getters.IS_EDITED) { From e7b45411ee297b36b4d9aa65fea5c6cff5783d92 Mon Sep 17 00:00:00 2001 From: X-20A <155217226+X-20A@users.noreply.github.com> Date: Thu, 13 Jun 2024 10:32:59 +0900 Subject: [PATCH 40/86] test --- .env.production | 14 ++++++++++++++ .env.test | 14 ++++++++++++++ src/backend/electron/main.ts | 6 ++++-- src/components/Dialog/SettingDialog.vue | 12 +++++------- 4 files changed, 37 insertions(+), 9 deletions(-) create mode 100644 .env.production create mode 100644 .env.test diff --git a/.env.production b/.env.production new file mode 100644 index 0000000000..5b0dcb0498 --- /dev/null +++ b/.env.production @@ -0,0 +1,14 @@ +VITE_APP_NAME=voicevox +VITE_DEFAULT_ENGINE_INFOS=`[ + { + "uuid": "074fc39e-678b-4c13-8916-ffca8d505d1d", + "name": "VOICEVOX Engine", + "executionEnabled": true, + "executionFilePath": "vv-engine/run.exe", + "executionArgs": [], + "host": "http://127.0.0.1:50021" + } +]` +VITE_OFFICIAL_WEBSITE_URL=https://voicevox.hiroshiba.jp/ +VITE_LATEST_UPDATE_INFOS_URL=https://raw.githubusercontent.com/VOICEVOX/voicevox_blog/master/src/data/updateInfos.json +VITE_GTM_CONTAINER_ID=GTM-DUMMY diff --git a/.env.test b/.env.test new file mode 100644 index 0000000000..dcf447f8b2 --- /dev/null +++ b/.env.test @@ -0,0 +1,14 @@ +VITE_APP_NAME=voicevox +VITE_DEFAULT_ENGINE_INFOS=`[ + { + "uuid": "074fc39e-678b-4c13-8916-ffca8d505d1d", + "name": "VOICEVOX Engine", + "executionEnabled": true, + "executionFilePath": "../voicevox_engine/run.exe", + "executionArgs": [], + "host": "http://127.0.0.1:50021" + } +]` +VITE_OFFICIAL_WEBSITE_URL=https://voicevox.hiroshiba.jp/ +VITE_LATEST_UPDATE_INFOS_URL=https://raw.githubusercontent.com/VOICEVOX/voicevox_blog/master/src/data/updateInfos.json +VITE_GTM_CONTAINER_ID=GTM-DUMMY diff --git a/src/backend/electron/main.ts b/src/backend/electron/main.ts index eb3b9e30d9..c0066bf9e7 100644 --- a/src/backend/electron/main.ts +++ b/src/backend/electron/main.ts @@ -254,7 +254,8 @@ async function installVvppEngineWithWarning({ }) .then((result) => { if (result.response === 0) { - ipcMainSend(win, "CHECK_EDITED_AND_NOT_SAVE", { // これじゃない + ipcMainSend(win, "CHECK_EDITED_AND_NOT_SAVE", { + // これじゃない closeOrReload: "reload", }); console.log("installVvppEngineWithWarning"); @@ -457,7 +458,8 @@ async function createWindow() { win.on("close", (event) => { if (!appState.willQuit) { event.preventDefault(); - ipcMainSend(win, "CHECK_EDITED_AND_NOT_SAVE", { // これじゃない + ipcMainSend(win, "CHECK_EDITED_AND_NOT_SAVE", { + // これじゃない closeOrReload: "close", }); console.log("win.on > close"); diff --git a/src/components/Dialog/SettingDialog.vue b/src/components/Dialog/SettingDialog.vue index 5cf00c0a95..f6fb01d4cb 100644 --- a/src/components/Dialog/SettingDialog.vue +++ b/src/components/Dialog/SettingDialog.vue @@ -1124,24 +1124,22 @@ const pauseLengthMode = computed({ }, }); -const audioKeys = computed(() => store.state.audioKeys); - watchEffect(() => { console.log("SettingDialog.vue > watchEffect"); - const nonComputedAudioKeys = store.state.audioKeys; - console.log(nonComputedAudioKeys); - if(nonComputedAudioKeys.length > 0) { + const audioKeys = store.state.audioKeys; + console.log(audioKeys); + if (audioKeys.length > 0) { if (pauseLengthMode.value === "ABSOLUTE") { // a.設定で絶対値モードに変更し、query.pauseLengthにnull以外の値が入っているとき // 適用範囲: 全てのaudioItem // COMMAND_MULTI_SET_AUDIO_PAUSE_LENGTHから呼び出し store.dispatch("COMMAND_MULTI_SET_AUDIO_PAUSE_LENGTH", { - audioKeys: nonComputedAudioKeys, + audioKeys: audioKeys, pauseLength: 0.3, }); } else { store.dispatch("COMMAND_MULTI_SET_AUDIO_PAUSE_LENGTH_SCALE", { - audioKeys: nonComputedAudioKeys, + audioKeys: audioKeys, pauseLengthScale: 1, }); } From 004117203ec2fd7bf0359e30844a89c5b40d2c1c Mon Sep 17 00:00:00 2001 From: X-20A <155217226+X-20A@users.noreply.github.com> Date: Thu, 13 Jun 2024 10:40:03 +0900 Subject: [PATCH 41/86] =?UTF-8?q?UI=E3=82=92=E5=A4=89=E6=9B=B4=20[update?= =?UTF-8?q?=20snapshots]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/backend/electron/main.ts | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/src/backend/electron/main.ts b/src/backend/electron/main.ts index c0066bf9e7..1889dee3ec 100644 --- a/src/backend/electron/main.ts +++ b/src/backend/electron/main.ts @@ -255,10 +255,8 @@ async function installVvppEngineWithWarning({ .then((result) => { if (result.response === 0) { ipcMainSend(win, "CHECK_EDITED_AND_NOT_SAVE", { - // これじゃない closeOrReload: "reload", }); - console.log("installVvppEngineWithWarning"); } }); } @@ -459,10 +457,8 @@ async function createWindow() { if (!appState.willQuit) { event.preventDefault(); ipcMainSend(win, "CHECK_EDITED_AND_NOT_SAVE", { - // これじゃない closeOrReload: "close", }); - console.log("win.on > close"); return; } }); @@ -1042,8 +1038,7 @@ app.on("window-all-closed", () => { app.on("before-quit", async (event) => { if (!appState.willQuit) { event.preventDefault(); - ipcMainSend(win, "CHECK_EDITED_AND_NOT_SAVE", { closeOrReload: "close" }); // これじゃない - console.log("before-quit"); + ipcMainSend(win, "CHECK_EDITED_AND_NOT_SAVE", { closeOrReload: "close" }); return; } From c87c22d90a1f57acf2662ff4d36c5f04d3ce4cb4 Mon Sep 17 00:00:00 2001 From: X-20A <155217226+X-20A@users.noreply.github.com> Date: Thu, 13 Jun 2024 10:59:16 +0900 Subject: [PATCH 42/86] test --- .env.production | 14 -------------- .env.test | 14 -------------- 2 files changed, 28 deletions(-) delete mode 100644 .env.production delete mode 100644 .env.test diff --git a/.env.production b/.env.production deleted file mode 100644 index 5b0dcb0498..0000000000 --- a/.env.production +++ /dev/null @@ -1,14 +0,0 @@ -VITE_APP_NAME=voicevox -VITE_DEFAULT_ENGINE_INFOS=`[ - { - "uuid": "074fc39e-678b-4c13-8916-ffca8d505d1d", - "name": "VOICEVOX Engine", - "executionEnabled": true, - "executionFilePath": "vv-engine/run.exe", - "executionArgs": [], - "host": "http://127.0.0.1:50021" - } -]` -VITE_OFFICIAL_WEBSITE_URL=https://voicevox.hiroshiba.jp/ -VITE_LATEST_UPDATE_INFOS_URL=https://raw.githubusercontent.com/VOICEVOX/voicevox_blog/master/src/data/updateInfos.json -VITE_GTM_CONTAINER_ID=GTM-DUMMY diff --git a/.env.test b/.env.test deleted file mode 100644 index dcf447f8b2..0000000000 --- a/.env.test +++ /dev/null @@ -1,14 +0,0 @@ -VITE_APP_NAME=voicevox -VITE_DEFAULT_ENGINE_INFOS=`[ - { - "uuid": "074fc39e-678b-4c13-8916-ffca8d505d1d", - "name": "VOICEVOX Engine", - "executionEnabled": true, - "executionFilePath": "../voicevox_engine/run.exe", - "executionArgs": [], - "host": "http://127.0.0.1:50021" - } -]` -VITE_OFFICIAL_WEBSITE_URL=https://voicevox.hiroshiba.jp/ -VITE_LATEST_UPDATE_INFOS_URL=https://raw.githubusercontent.com/VOICEVOX/voicevox_blog/master/src/data/updateInfos.json -VITE_GTM_CONTAINER_ID=GTM-DUMMY From c8a987d5c242a39d1b926eaf5db53dfb2388a2d4 Mon Sep 17 00:00:00 2001 From: X-20A <155217226+X-20A@users.noreply.github.com> Date: Thu, 13 Jun 2024 11:03:06 +0900 Subject: [PATCH 43/86] test --- .env.production | 14 ++++++++++++++ .env.test | 14 ++++++++++++++ 2 files changed, 28 insertions(+) create mode 100644 .env.production create mode 100644 .env.test diff --git a/.env.production b/.env.production new file mode 100644 index 0000000000..5b0dcb0498 --- /dev/null +++ b/.env.production @@ -0,0 +1,14 @@ +VITE_APP_NAME=voicevox +VITE_DEFAULT_ENGINE_INFOS=`[ + { + "uuid": "074fc39e-678b-4c13-8916-ffca8d505d1d", + "name": "VOICEVOX Engine", + "executionEnabled": true, + "executionFilePath": "vv-engine/run.exe", + "executionArgs": [], + "host": "http://127.0.0.1:50021" + } +]` +VITE_OFFICIAL_WEBSITE_URL=https://voicevox.hiroshiba.jp/ +VITE_LATEST_UPDATE_INFOS_URL=https://raw.githubusercontent.com/VOICEVOX/voicevox_blog/master/src/data/updateInfos.json +VITE_GTM_CONTAINER_ID=GTM-DUMMY diff --git a/.env.test b/.env.test new file mode 100644 index 0000000000..dcf447f8b2 --- /dev/null +++ b/.env.test @@ -0,0 +1,14 @@ +VITE_APP_NAME=voicevox +VITE_DEFAULT_ENGINE_INFOS=`[ + { + "uuid": "074fc39e-678b-4c13-8916-ffca8d505d1d", + "name": "VOICEVOX Engine", + "executionEnabled": true, + "executionFilePath": "../voicevox_engine/run.exe", + "executionArgs": [], + "host": "http://127.0.0.1:50021" + } +]` +VITE_OFFICIAL_WEBSITE_URL=https://voicevox.hiroshiba.jp/ +VITE_LATEST_UPDATE_INFOS_URL=https://raw.githubusercontent.com/VOICEVOX/voicevox_blog/master/src/data/updateInfos.json +VITE_GTM_CONTAINER_ID=GTM-DUMMY From 76c7bd462920aeed6854dd647e791929d7937d13 Mon Sep 17 00:00:00 2001 From: X-20A <155217226+X-20A@users.noreply.github.com> Date: Thu, 13 Jun 2024 11:09:45 +0900 Subject: [PATCH 44/86] =?UTF-8?q?UI=E3=82=92=E5=A4=89=E6=9B=B4=20[update?= =?UTF-8?q?=20snapshots]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/plugins/ipcMessageReceiverPlugin.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/plugins/ipcMessageReceiverPlugin.ts b/src/plugins/ipcMessageReceiverPlugin.ts index cbfa07cac3..87caec21fb 100644 --- a/src/plugins/ipcMessageReceiverPlugin.ts +++ b/src/plugins/ipcMessageReceiverPlugin.ts @@ -45,7 +45,6 @@ export const ipcMessageReceiver: Plugin = { ); window.backend.onReceivedIPCMsg("CHECK_EDITED_AND_NOT_SAVE", (_, obj) => { - console.log("window.backend.onReceivedIPCMsg"); options.store.dispatch("CHECK_EDITED_AND_NOT_SAVE", obj); }); From a53c29913221f115aeac87a0222070a861d23a98 Mon Sep 17 00:00:00 2001 From: X-20A <155217226+X-20A@users.noreply.github.com> Date: Fri, 14 Jun 2024 03:24:07 +0900 Subject: [PATCH 45/86] test --- .github/workflows/test.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index a0f1d8d9ae..d67197da5d 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -8,8 +8,8 @@ on: workflow_dispatch: env: - VOICEVOX_ENGINE_REPO: "VOICEVOX/voicevox_nemo_engine" # 軽いのでNemoを使う - VOICEVOX_ENGINE_VERSION: "0.14.0" + VOICEVOX_ENGINE_REPO: "VOICEVOX/voicevox_engine" # 軽いのでNemoを使う + VOICEVOX_ENGINE_VERSION: "0.19.1" defaults: run: From 445b70214274c3805a2c910aba6b594bfe801005 Mon Sep 17 00:00:00 2001 From: X-20A <155217226+X-20A@users.noreply.github.com> Date: Fri, 14 Jun 2024 03:46:59 +0900 Subject: [PATCH 46/86] =?UTF-8?q?UI=E3=82=92=E5=A4=89=E6=9B=B4=20[update?= =?UTF-8?q?=20snapshots]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/Talk/AudioCell.vue | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/Talk/AudioCell.vue b/src/components/Talk/AudioCell.vue index 6fbba85da7..0a7d3a369d 100644 --- a/src/components/Talk/AudioCell.vue +++ b/src/components/Talk/AudioCell.vue @@ -324,7 +324,7 @@ const pushAudioTextIfNeeded = async (event?: KeyboardEvent) => { // d.AudioQueryをfetchしたとき(テキスト入力したとき) // 適用範囲: 現在選択しているAudioItem - // pushAudioTextIfNeededはblurで発火するので、さらにテキスト変更時に絞り込む + // pushAudioTextIfNeededはblurで発火するので、さらにテキストを変更した場合に絞り込む if ( store.state.pauseLengthMode === "ABSOLUTE" && copy_isChangeFlag === true From 27cb55cefe5a7953ba4cdc4260cb12b32cfa3be1 Mon Sep 17 00:00:00 2001 From: X-20A <155217226+X-20A@users.noreply.github.com> Date: Fri, 14 Jun 2024 07:24:04 +0900 Subject: [PATCH 47/86] =?UTF-8?q?UI=E3=82=92=E5=A4=89=E6=9B=B4=20[update?= =?UTF-8?q?=20snapshots]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .env.production | 14 - .env.test | 14 - src/components/Talk/AudioCell.vue | 1 - src/components/Talk/AudioInfo.vue | 325 ++++++++---------- ...347\224\273\351\235\242-browser-win32.png" | Bin 54318 -> 55238 bytes 5 files changed, 150 insertions(+), 204 deletions(-) delete mode 100644 .env.production delete mode 100644 .env.test diff --git a/.env.production b/.env.production deleted file mode 100644 index 5b0dcb0498..0000000000 --- a/.env.production +++ /dev/null @@ -1,14 +0,0 @@ -VITE_APP_NAME=voicevox -VITE_DEFAULT_ENGINE_INFOS=`[ - { - "uuid": "074fc39e-678b-4c13-8916-ffca8d505d1d", - "name": "VOICEVOX Engine", - "executionEnabled": true, - "executionFilePath": "vv-engine/run.exe", - "executionArgs": [], - "host": "http://127.0.0.1:50021" - } -]` -VITE_OFFICIAL_WEBSITE_URL=https://voicevox.hiroshiba.jp/ -VITE_LATEST_UPDATE_INFOS_URL=https://raw.githubusercontent.com/VOICEVOX/voicevox_blog/master/src/data/updateInfos.json -VITE_GTM_CONTAINER_ID=GTM-DUMMY diff --git a/.env.test b/.env.test deleted file mode 100644 index dcf447f8b2..0000000000 --- a/.env.test +++ /dev/null @@ -1,14 +0,0 @@ -VITE_APP_NAME=voicevox -VITE_DEFAULT_ENGINE_INFOS=`[ - { - "uuid": "074fc39e-678b-4c13-8916-ffca8d505d1d", - "name": "VOICEVOX Engine", - "executionEnabled": true, - "executionFilePath": "../voicevox_engine/run.exe", - "executionArgs": [], - "host": "http://127.0.0.1:50021" - } -]` -VITE_OFFICIAL_WEBSITE_URL=https://voicevox.hiroshiba.jp/ -VITE_LATEST_UPDATE_INFOS_URL=https://raw.githubusercontent.com/VOICEVOX/voicevox_blog/master/src/data/updateInfos.json -VITE_GTM_CONTAINER_ID=GTM-DUMMY diff --git a/src/components/Talk/AudioCell.vue b/src/components/Talk/AudioCell.vue index 0a7d3a369d..2730bc6448 100644 --- a/src/components/Talk/AudioCell.vue +++ b/src/components/Talk/AudioCell.vue @@ -309,7 +309,6 @@ watch( const pushAudioTextIfNeeded = async (event?: KeyboardEvent) => { console.log("AudioCell.vue > pushAudioTextIfNeeded"); - console.log(`isChangeFlag: ${isChangeFlag.value}`); // COMMAND_CHANGE_AUDIO_TEXTでもAccenPhrases弄ってるっぽいのでフラグをコピーして後で処理 const copy_isChangeFlag = isChangeFlag.value; diff --git a/src/components/Talk/AudioInfo.vue b/src/components/Talk/AudioInfo.vue index 7e5bf49562..323b54a384 100644 --- a/src/components/Talk/AudioInfo.vue +++ b/src/components/Talk/AudioInfo.vue @@ -333,9 +333,7 @@ const audioItem = computed(() => store.state.audioItems[props.activeAudioKey]); const query = computed(() => audioItem.value?.query); // 文内無音の指定方式 "SCALE" || "ABSOLUTE" -const pauseLengthMode = computed(() => { - return store.state.pauseLengthMode; -}); +const pauseLengthMode = computed(() => store.state.pauseLengthMode); const supportedFeatures = computed( () => @@ -360,188 +358,165 @@ const selectedAudioKeys = computed(() => ); // 句読点などの無音時間はひとまず倍率verを表示 のち必要に応じ絶対値に切替 -const parameters = computed(() => { - console.log("AudioInfo.vue > parameters"); - const pauseLengthParameter: Parameter = { - label: "文内無音", +const parameters = computed(() => [ + { + label: "話速", + slider: previewSliderHelper({ + modelValue: () => query.value?.speedScale ?? null, + disable: () => + uiLocked.value || supportedFeatures.value?.adjustSpeedScale === false, + max: SLIDER_PARAMETERS.SPEED.max, + min: SLIDER_PARAMETERS.SPEED.min, + step: SLIDER_PARAMETERS.SPEED.step, + scrollStep: SLIDER_PARAMETERS.SPEED.scrollStep, + onChange: (speedScale: number) => + store.dispatch("COMMAND_MULTI_SET_AUDIO_SPEED_SCALE", { + audioKeys: selectedAudioKeys.value, + speedScale, + }), + }), + action: "COMMAND_MULTI_SET_AUDIO_SPEED_SCALE", + key: "speedScale", + }, + { + label: "音高", + slider: previewSliderHelper({ + modelValue: () => query.value?.pitchScale ?? null, + disable: () => + uiLocked.value || supportedFeatures.value?.adjustPitchScale === false, + max: SLIDER_PARAMETERS.PITCH.max, + min: SLIDER_PARAMETERS.PITCH.min, + step: SLIDER_PARAMETERS.PITCH.step, + scrollStep: SLIDER_PARAMETERS.PITCH.scrollStep, + onChange: (pitchScale: number) => + store.dispatch("COMMAND_MULTI_SET_AUDIO_PITCH_SCALE", { + audioKeys: selectedAudioKeys.value, + pitchScale, + }), + }), + action: "COMMAND_MULTI_SET_AUDIO_PITCH_SCALE", + key: "pitchScale", + }, + { + label: "抑揚", + slider: previewSliderHelper({ + modelValue: () => query.value?.intonationScale ?? null, + disable: () => + uiLocked.value || + supportedFeatures.value?.adjustIntonationScale === false, + max: SLIDER_PARAMETERS.INTONATION.max, + min: SLIDER_PARAMETERS.INTONATION.min, + step: SLIDER_PARAMETERS.INTONATION.step, + scrollStep: SLIDER_PARAMETERS.INTONATION.scrollStep, + scrollMinStep: SLIDER_PARAMETERS.INTONATION.scrollMinStep, + onChange: (intonationScale: number) => + store.dispatch("COMMAND_MULTI_SET_AUDIO_INTONATION_SCALE", { + audioKeys: selectedAudioKeys.value, + intonationScale, + }), + }), + action: "COMMAND_MULTI_SET_AUDIO_INTONATION_SCALE", + key: "intonationScale", + }, + { + label: "音量", + slider: previewSliderHelper({ + modelValue: () => query.value?.volumeScale ?? null, + disable: () => + uiLocked.value || supportedFeatures.value?.adjustVolumeScale === false, + max: SLIDER_PARAMETERS.VOLUME.max, + min: SLIDER_PARAMETERS.VOLUME.min, + step: SLIDER_PARAMETERS.VOLUME.step, + scrollStep: SLIDER_PARAMETERS.VOLUME.scrollStep, + scrollMinStep: SLIDER_PARAMETERS.VOLUME.scrollMinStep, + onChange: (volumeScale: number) => + store.dispatch("COMMAND_MULTI_SET_AUDIO_VOLUME_SCALE", { + audioKeys: selectedAudioKeys.value, + volumeScale, + }), + }), + action: "COMMAND_MULTI_SET_AUDIO_VOLUME_SCALE", + key: "volumeScale", + }, + // 条件に基づくパラメータの追加 + pauseLengthMode.value === "SCALE" + ? { + label: "文内無音倍率", + slider: previewSliderHelper({ + modelValue: () => query.value?.pauseLengthScale ?? null, + disable: () => uiLocked.value, + max: SLIDER_PARAMETERS.PAUSE_LENGTH_SCALE.max, + min: SLIDER_PARAMETERS.PAUSE_LENGTH_SCALE.min, + step: SLIDER_PARAMETERS.PAUSE_LENGTH_SCALE.step, + scrollStep: SLIDER_PARAMETERS.PAUSE_LENGTH_SCALE.scrollStep, + scrollMinStep: SLIDER_PARAMETERS.PAUSE_LENGTH_SCALE.scrollMinStep, + onChange: (pauseLengthScale: number) => + store.dispatch("COMMAND_MULTI_SET_AUDIO_PAUSE_LENGTH_SCALE", { + audioKeys: selectedAudioKeys.value, + pauseLengthScale, + }), + }), + action: "COMMAND_MULTI_SET_AUDIO_PAUSE_LENGTH_SCALE", + key: "pauseLengthScale", + } + : { + label: "文内無音", + slider: previewSliderHelper({ + modelValue: () => query.value?.pauseLength ?? null, + disable: () => uiLocked.value, + max: SLIDER_PARAMETERS.PAUSE_LENGTH.max, + min: SLIDER_PARAMETERS.PAUSE_LENGTH.min, + step: SLIDER_PARAMETERS.PAUSE_LENGTH.step, + scrollStep: SLIDER_PARAMETERS.PAUSE_LENGTH.scrollStep, + scrollMinStep: SLIDER_PARAMETERS.PAUSE_LENGTH.scrollMinStep, + onChange: (pauseLength: number) => + store.dispatch("COMMAND_MULTI_SET_AUDIO_PAUSE_LENGTH", { + audioKeys: selectedAudioKeys.value, + pauseLength, + }), + }), + action: "COMMAND_MULTI_SET_AUDIO_PAUSE_LENGTH", + key: "pauseLength", + }, + { + label: "開始無音", slider: previewSliderHelper({ - modelValue: () => query.value?.pauseLength ?? null, + modelValue: () => query.value?.prePhonemeLength ?? null, disable: () => uiLocked.value, - max: SLIDER_PARAMETERS.PAUSE_LENGTH.max, - min: SLIDER_PARAMETERS.PAUSE_LENGTH.min, - step: SLIDER_PARAMETERS.PAUSE_LENGTH.step, - scrollStep: SLIDER_PARAMETERS.PAUSE_LENGTH.scrollStep, - scrollMinStep: SLIDER_PARAMETERS.PAUSE_LENGTH.scrollMinStep, - onChange: (pauseLength: number) => - // b.query.pauseLengthにnull以外の値を代入したとき - // COMMAND_MULTI_SET_AUDIO_PAUSE_LENGTHから呼び出し - // 適用範囲: 現在選択しているaudioItem - store.dispatch("COMMAND_MULTI_SET_AUDIO_PAUSE_LENGTH", { + max: SLIDER_PARAMETERS.PRE_PHONEME_LENGTH.max, + min: SLIDER_PARAMETERS.PRE_PHONEME_LENGTH.min, + step: SLIDER_PARAMETERS.PRE_PHONEME_LENGTH.step, + scrollStep: SLIDER_PARAMETERS.PRE_PHONEME_LENGTH.scrollStep, + scrollMinStep: SLIDER_PARAMETERS.PRE_PHONEME_LENGTH.scrollMinStep, + onChange: (prePhonemeLength: number) => + store.dispatch("COMMAND_MULTI_SET_AUDIO_PRE_PHONEME_LENGTH", { audioKeys: selectedAudioKeys.value, - pauseLength: pauseLength, + prePhonemeLength, }), }), - action: "COMMAND_MULTI_SET_AUDIO_PAUSE_LENGTH", - key: "pauseLength", - }; - - const pauseLengthScaleParameter: Parameter = { - label: "文内無音倍率", + action: "COMMAND_MULTI_SET_AUDIO_PRE_PHONEME_LENGTH", + key: "prePhonemeLength", + }, + { + label: "終了無音", slider: previewSliderHelper({ - modelValue: () => query.value?.pauseLengthScale ?? null, + modelValue: () => query.value?.postPhonemeLength ?? null, disable: () => uiLocked.value, - max: SLIDER_PARAMETERS.PAUSE_LENGTH_SCALE.max, - min: SLIDER_PARAMETERS.PAUSE_LENGTH_SCALE.min, - step: SLIDER_PARAMETERS.PAUSE_LENGTH_SCALE.step, - scrollStep: SLIDER_PARAMETERS.PAUSE_LENGTH_SCALE.scrollStep, - scrollMinStep: SLIDER_PARAMETERS.PAUSE_LENGTH_SCALE.scrollMinStep, - onChange: (pauseLengthScale: number) => - store.dispatch("COMMAND_MULTI_SET_AUDIO_PAUSE_LENGTH_SCALE", { + max: SLIDER_PARAMETERS.POST_PHONEME_LENGTH.max, + min: SLIDER_PARAMETERS.POST_PHONEME_LENGTH.min, + step: SLIDER_PARAMETERS.POST_PHONEME_LENGTH.step, + scrollStep: SLIDER_PARAMETERS.POST_PHONEME_LENGTH.scrollStep, + scrollMinStep: SLIDER_PARAMETERS.POST_PHONEME_LENGTH.scrollMinStep, + onChange: (postPhonemeLength: number) => + store.dispatch("COMMAND_MULTI_SET_AUDIO_POST_PHONEME_LENGTH", { audioKeys: selectedAudioKeys.value, - pauseLengthScale: pauseLengthScale, + postPhonemeLength, }), }), - action: "COMMAND_MULTI_SET_AUDIO_PAUSE_LENGTH_SCALE", - key: "pauseLengthScale", - }; - const baseParam: Parameter[] = [ - { - label: "話速", - slider: previewSliderHelper({ - modelValue: () => query.value?.speedScale ?? null, - disable: () => - uiLocked.value || supportedFeatures.value?.adjustSpeedScale === false, - max: SLIDER_PARAMETERS.SPEED.max, - min: SLIDER_PARAMETERS.SPEED.min, - step: SLIDER_PARAMETERS.SPEED.step, - scrollStep: SLIDER_PARAMETERS.SPEED.scrollStep, - scrollMinStep: SLIDER_PARAMETERS.SPEED.scrollMinStep, - onChange: (speedScale: number) => - store.dispatch("COMMAND_MULTI_SET_AUDIO_SPEED_SCALE", { - audioKeys: selectedAudioKeys.value, - speedScale, - }), - }), - action: "COMMAND_MULTI_SET_AUDIO_SPEED_SCALE", - key: "speedScale", - }, - { - label: "音高", - slider: previewSliderHelper({ - modelValue: () => query.value?.pitchScale ?? null, - disable: () => - uiLocked.value || supportedFeatures.value?.adjustPitchScale === false, - max: SLIDER_PARAMETERS.PITCH.max, - min: SLIDER_PARAMETERS.PITCH.min, - step: SLIDER_PARAMETERS.PITCH.step, - scrollStep: SLIDER_PARAMETERS.PITCH.scrollStep, - onChange: (pitchScale: number) => - store.dispatch("COMMAND_MULTI_SET_AUDIO_PITCH_SCALE", { - audioKeys: selectedAudioKeys.value, - pitchScale, - }), - }), - action: "COMMAND_MULTI_SET_AUDIO_PITCH_SCALE", - key: "pitchScale", - }, - { - label: "抑揚", - slider: previewSliderHelper({ - modelValue: () => query.value?.intonationScale ?? null, - disable: () => - uiLocked.value || - supportedFeatures.value?.adjustIntonationScale === false, - max: SLIDER_PARAMETERS.INTONATION.max, - min: SLIDER_PARAMETERS.INTONATION.min, - step: SLIDER_PARAMETERS.INTONATION.step, - scrollStep: SLIDER_PARAMETERS.INTONATION.scrollStep, - scrollMinStep: SLIDER_PARAMETERS.INTONATION.scrollMinStep, - onChange: (intonationScale: number) => - store.dispatch("COMMAND_MULTI_SET_AUDIO_INTONATION_SCALE", { - audioKeys: selectedAudioKeys.value, - intonationScale, - }), - }), - action: "COMMAND_MULTI_SET_AUDIO_INTONATION_SCALE", - key: "intonationScale", - }, - { - label: "音量", - slider: previewSliderHelper({ - modelValue: () => query.value?.volumeScale ?? null, - disable: () => - uiLocked.value || - supportedFeatures.value?.adjustVolumeScale === false, - max: SLIDER_PARAMETERS.VOLUME.max, - min: SLIDER_PARAMETERS.VOLUME.min, - step: SLIDER_PARAMETERS.VOLUME.step, - scrollStep: SLIDER_PARAMETERS.VOLUME.scrollStep, - scrollMinStep: SLIDER_PARAMETERS.VOLUME.scrollMinStep, - onChange: (volumeScale: number) => - store.dispatch("COMMAND_MULTI_SET_AUDIO_VOLUME_SCALE", { - audioKeys: selectedAudioKeys.value, - volumeScale, - }), - }), - action: "COMMAND_MULTI_SET_AUDIO_VOLUME_SCALE", - key: "volumeScale", - }, - pauseLengthScaleParameter, - { - label: "開始無音", - slider: previewSliderHelper({ - modelValue: () => query.value?.prePhonemeLength ?? null, - disable: () => uiLocked.value, - max: SLIDER_PARAMETERS.PRE_PHONEME_LENGTH.max, - min: SLIDER_PARAMETERS.PRE_PHONEME_LENGTH.min, - step: SLIDER_PARAMETERS.PRE_PHONEME_LENGTH.step, - scrollStep: SLIDER_PARAMETERS.PRE_PHONEME_LENGTH.scrollStep, - scrollMinStep: SLIDER_PARAMETERS.PRE_PHONEME_LENGTH.scrollMinStep, - onChange: (prePhonemeLength: number) => - store.dispatch("COMMAND_MULTI_SET_AUDIO_PRE_PHONEME_LENGTH", { - audioKeys: selectedAudioKeys.value, - prePhonemeLength, - }), - }), - action: "COMMAND_MULTI_SET_AUDIO_PRE_PHONEME_LENGTH", - key: "prePhonemeLength", - }, - { - label: "終了無音", - slider: previewSliderHelper({ - modelValue: () => query.value?.postPhonemeLength ?? null, - disable: () => uiLocked.value, - max: SLIDER_PARAMETERS.POST_PHONEME_LENGTH.max, - min: SLIDER_PARAMETERS.POST_PHONEME_LENGTH.min, - step: SLIDER_PARAMETERS.POST_PHONEME_LENGTH.step, - scrollStep: SLIDER_PARAMETERS.POST_PHONEME_LENGTH.scrollStep, - scrollMinStep: SLIDER_PARAMETERS.POST_PHONEME_LENGTH.scrollMinStep, - onChange: (postPhonemeLength: number) => - store.dispatch("COMMAND_MULTI_SET_AUDIO_POST_PHONEME_LENGTH", { - audioKeys: selectedAudioKeys.value, - postPhonemeLength, - }), - }), - action: "COMMAND_MULTI_SET_AUDIO_POST_PHONEME_LENGTH", - key: "postPhonemeLength", - }, - ]; - // pauseLengthModeの変更に伴って切替 - const newParam = - pauseLengthMode.value === "SCALE" - ? pauseLengthScaleParameter - : pauseLengthParameter; - const index = baseParam.findIndex((param) => - param.label.includes("文内無音"), - ); - - if (index !== -1) { - baseParam[index] = newParam; - } else { - baseParam.splice(4, 0, newParam); - } - return baseParam; -}); + action: "COMMAND_MULTI_SET_AUDIO_POST_PHONEME_LENGTH", + key: "postPhonemeLength", + }, +]); const handleParameterChange = ( parameter: Parameter, diff --git "a/tests/e2e/browser/\343\202\271\343\202\257\343\203\252\343\203\274\343\203\263\343\202\267\343\203\247\343\203\203\343\203\210.spec.ts-snapshots/\343\203\241\343\202\244\343\203\263\347\224\273\351\235\242-browser-win32.png" "b/tests/e2e/browser/\343\202\271\343\202\257\343\203\252\343\203\274\343\203\263\343\202\267\343\203\247\343\203\203\343\203\210.spec.ts-snapshots/\343\203\241\343\202\244\343\203\263\347\224\273\351\235\242-browser-win32.png" index 51b4bfea7ee086361c37af661ae0938867dd68f0..09781ae4ee7326a2f7e85907c6e1fd51dfba301d 100644 GIT binary patch literal 55238 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

^N(0MgUa90pS z0*tssu|qwqM98ts=)5&WBuqmBsJOteRuA%xbD45JebRw!2fa!M14fq=@IPRc_JNUk z500Xe8FG1)lqf_?Mm|20$r3;ThO4R>pLbmVl}taV7n59lAucTfv~k}`SmUp55N#C# zX^F0a*y+sf0omCQ1c1&XM7mc5(9n=emJO+uMp5EBZ+<#dGR;GtE#lOT{10&DZewe^ z4c=z!{L-z5fF_ZfcKXS$yno~`oTvgJMK5G6i}YXcgv57H@Q4Wr2`xf@FMSL#x*?IQ z3jXPYk*dF!S2S+!1`X1b@U@|~N31e62O~s3+ zhQFZ?IdD;dN}6c(iS(TSb|2<-H=`pGbKN+Alz{j|?E89q8Kau}X2|`e0=&~Vmg&li z?0&LG|6LWye9EQm4fPogU3fBN4D2WU$Oq`^|F<`R|JhI|B>s1J$Kmh(i*jYZKx{KL z?%_s%Khd=&zwUO-G;HpJ{apZ!h}F;c(Ef#Bfn2W#w5{NK)pnPk5^QfY7uk+vv)y1z z5I6Rd!DRovx4HfxDYwdCtPE~XN*jrmYs;lC|3L=bIsXNBD7^o|2$cGb|AITlry2kD z&YX*8Lqfv}E{V)VDdaDdtE#J5O`K};kJY?sv9zq(cB+8Zc&9-}2${UP!5emeHwTno zr}@nZvHmq7q`m*aJCEc?v}!d*bKQ3qMs#0U*ytU{N~~V?{ul2^-2<2rJa%e};op0V zEgAC%q_e$ORea27feoYo&)*NZk`YwXjPBs1de7)FNA>r9rLw%K@NZdvtuZtwPQd~- zhP1f*gY~`!|DaJuyrjQDkQI;lJDDI{0<6rHe~+nzlXWIwbOq#a&)x~nJ=PS`Q;_(U~d1Kz^(2>4_0 zp_6*U$=E@{3WJ#rYK9EoK_md~2VQA>^AzRFU4o~7+wF=NQ1GR|oi#-KF0T5+$KvbX zE@O^X1GtOOc~<-h6w|5+{0cFoQO#t}o8XkNxdYa6gLEM_AhPDifelA=f8cY*(49iT zr$8G#$!P(yb&xgb|k%-)Tm8=u} z2%WedxM%?fqZ3=pjsf}z1qi!m-EQqF8x0BUE`Dnbgvjm(W^)T9;~*)u76B5);qy!! z3Es|qR;J{xc=ri_FpwgUjj)c0oPeC$@Td6!XwNx~>K;NOlo|j$I?qWQB%oC_`Q#iB zLcQPyhn@6F;0uqnNojyXiVzio$P5ysA3=vUKB|R~KLi`&!J3vs?j^*IZI*_LF%X^` zvnG%d;b`xLPs{y}yb&?vScRjNRX1!Tu8qV(RuI#TLHyGH9q>V@|8VxgZs2KMLCc+2 zSje?(TWbjW$v}|}#Qwl&S3&#{j6aN6pEbc3;2HYv%>dOgyN&b$u#?`?(Q;MxM!LFe z5Icb!|Lc)R1AEf$LJz%y`jx$Zc_ZW&w|HS}laIHuU<iij(Fe!WGm%O@vBhX#Dk1T2=-m>RH% zkT6jOimKYRujgP^^<}H21K-%4x;&qiT$oo_bkA}6 z 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 From 1537bc32cf112d1cfbae1b9aef5306dec68a7d8f Mon Sep 17 00:00:00 2001 From: X-20A <155217226+X-20A@users.noreply.github.com> Date: Fri, 14 Jun 2024 07:26:43 +0900 Subject: [PATCH 48/86] =?UTF-8?q?UI=E3=82=92=E5=A4=89=E6=9B=B4=20[update?= =?UTF-8?q?=20snapshots]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .env.production | 14 ++++++++++++++ .env.test | 14 ++++++++++++++ 2 files changed, 28 insertions(+) create mode 100644 .env.production create mode 100644 .env.test diff --git a/.env.production b/.env.production new file mode 100644 index 0000000000..5b0dcb0498 --- /dev/null +++ b/.env.production @@ -0,0 +1,14 @@ +VITE_APP_NAME=voicevox +VITE_DEFAULT_ENGINE_INFOS=`[ + { + "uuid": "074fc39e-678b-4c13-8916-ffca8d505d1d", + "name": "VOICEVOX Engine", + "executionEnabled": true, + "executionFilePath": "vv-engine/run.exe", + "executionArgs": [], + "host": "http://127.0.0.1:50021" + } +]` +VITE_OFFICIAL_WEBSITE_URL=https://voicevox.hiroshiba.jp/ +VITE_LATEST_UPDATE_INFOS_URL=https://raw.githubusercontent.com/VOICEVOX/voicevox_blog/master/src/data/updateInfos.json +VITE_GTM_CONTAINER_ID=GTM-DUMMY diff --git a/.env.test b/.env.test new file mode 100644 index 0000000000..dcf447f8b2 --- /dev/null +++ b/.env.test @@ -0,0 +1,14 @@ +VITE_APP_NAME=voicevox +VITE_DEFAULT_ENGINE_INFOS=`[ + { + "uuid": "074fc39e-678b-4c13-8916-ffca8d505d1d", + "name": "VOICEVOX Engine", + "executionEnabled": true, + "executionFilePath": "../voicevox_engine/run.exe", + "executionArgs": [], + "host": "http://127.0.0.1:50021" + } +]` +VITE_OFFICIAL_WEBSITE_URL=https://voicevox.hiroshiba.jp/ +VITE_LATEST_UPDATE_INFOS_URL=https://raw.githubusercontent.com/VOICEVOX/voicevox_blog/master/src/data/updateInfos.json +VITE_GTM_CONTAINER_ID=GTM-DUMMY From e27d557eeb4a88126d5c14945bc6d5faa771f529 Mon Sep 17 00:00:00 2001 From: X-20A <155217226+X-20A@users.noreply.github.com> Date: Fri, 14 Jun 2024 08:17:10 +0900 Subject: [PATCH 49/86] =?UTF-8?q?UI=E3=82=92=E5=A4=89=E6=9B=B4=20[update?= =?UTF-8?q?=20snapshots]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/Dialog/AcceptTermsDialog.vue | 1 - src/components/Dialog/EngineManageDialog.vue | 1 - src/components/Dialog/SettingDialog.vue | 2 -- src/components/EngineStartupOverlay.vue | 1 - src/components/Talk/AccentPhrase.vue | 4 ---- src/components/Talk/AudioCell.vue | 2 -- src/components/Talk/AudioInfo.vue | 2 -- src/store/audio.ts | 6 ------ src/store/project.ts | 1 - src/store/proxy.ts | 2 -- src/store/ui.ts | 1 - 11 files changed, 23 deletions(-) diff --git a/src/components/Dialog/AcceptTermsDialog.vue b/src/components/Dialog/AcceptTermsDialog.vue index 92b1c07110..88d4aaa123 100644 --- a/src/components/Dialog/AcceptTermsDialog.vue +++ b/src/components/Dialog/AcceptTermsDialog.vue @@ -81,7 +81,6 @@ const modelValueComputed = computed({ }); const handler = (acceptTerms: boolean) => { - console.log("handler"); store.dispatch("SET_ACCEPT_TERMS", { acceptTerms: acceptTerms ? "Accepted" : "Rejected", }); diff --git a/src/components/Dialog/EngineManageDialog.vue b/src/components/Dialog/EngineManageDialog.vue index c2c63ad9be..ddc3315925 100644 --- a/src/components/Dialog/EngineManageDialog.vue +++ b/src/components/Dialog/EngineManageDialog.vue @@ -577,7 +577,6 @@ const restartSelectedEngine = () => { }; const requireReload = async (message: string) => { - console.log("requireReload"); const result = await store.dispatch("SHOW_WARNING_DIALOG", { title: "再読み込みが必要です", message: message, diff --git a/src/components/Dialog/SettingDialog.vue b/src/components/Dialog/SettingDialog.vue index f6fb01d4cb..26bb135007 100644 --- a/src/components/Dialog/SettingDialog.vue +++ b/src/components/Dialog/SettingDialog.vue @@ -1125,9 +1125,7 @@ const pauseLengthMode = computed({ }); watchEffect(() => { - console.log("SettingDialog.vue > watchEffect"); const audioKeys = store.state.audioKeys; - console.log(audioKeys); if (audioKeys.length > 0) { if (pauseLengthMode.value === "ABSOLUTE") { // a.設定で絶対値モードに変更し、query.pauseLengthにnull以外の値が入っているとき diff --git a/src/components/EngineStartupOverlay.vue b/src/components/EngineStartupOverlay.vue index 806d0f43a5..41627cffcb 100644 --- a/src/components/EngineStartupOverlay.vue +++ b/src/components/EngineStartupOverlay.vue @@ -91,7 +91,6 @@ watch(allEngineState, (newEngineState) => { }); const reloadAppWithMultiEngineOffMode = () => { - console.log("reloadAppWithMultiEngineOffMode"); store.dispatch("CHECK_EDITED_AND_NOT_SAVE", { closeOrReload: "reload", isMultiEngineOffMode: true, diff --git a/src/components/Talk/AccentPhrase.vue b/src/components/Talk/AccentPhrase.vue index ea89e94397..04938eb200 100644 --- a/src/components/Talk/AccentPhrase.vue +++ b/src/components/Talk/AccentPhrase.vue @@ -266,7 +266,6 @@ const pronunciation = computed(() => { }); const handleChangePronounce = async (newPronunciation: string) => { - console.log("AccentPhrase.vue > handleChangePronounce"); const copyBeforeText = beforeText; let popUntilPause = false; @@ -293,9 +292,6 @@ const handleChangePronounce = async (newPronunciation: string) => { // e.AccentPhrasesをfetchしたとき(読み変更で句読点を含めたとき) // 適用範囲: 現在選択しているAudioItem - console.log(`copyBeforeText: ${copyBeforeText}`); - console.log(`newPronunciation: ${newPronunciation}`); - await console.log(store.state.audioItems[props.audioKey]); if (store.state.pauseLengthMode === "ABSOLUTE") { // テキストが変更されて、かつ読点が追加されたことを確認 if (!copyBeforeText.includes("、") && newPronunciation.includes("、")) { diff --git a/src/components/Talk/AudioCell.vue b/src/components/Talk/AudioCell.vue index 2730bc6448..c098ef66ec 100644 --- a/src/components/Talk/AudioCell.vue +++ b/src/components/Talk/AudioCell.vue @@ -291,7 +291,6 @@ const isSelectedAudioCell = computed(() => const audioTextBuffer = ref(audioItem.value.text); const isChangeFlag = ref(false); const setAudioTextBuffer = (text: string | number | null) => { - console.log("AudioCell.vue > setAudioTextBuffer"); if (typeof text !== "string") throw new Error("typeof text !== 'string'"); audioTextBuffer.value = text; isChangeFlag.value = true; @@ -308,7 +307,6 @@ watch( ); const pushAudioTextIfNeeded = async (event?: KeyboardEvent) => { - console.log("AudioCell.vue > pushAudioTextIfNeeded"); // COMMAND_CHANGE_AUDIO_TEXTでもAccenPhrases弄ってるっぽいのでフラグをコピーして後で処理 const copy_isChangeFlag = isChangeFlag.value; diff --git a/src/components/Talk/AudioInfo.vue b/src/components/Talk/AudioInfo.vue index 323b54a384..40166e063c 100644 --- a/src/components/Talk/AudioInfo.vue +++ b/src/components/Talk/AudioInfo.vue @@ -837,7 +837,6 @@ const closeAllDialog = () => { // プリセットの登録 const registerPreset = ({ overwrite }: { overwrite: boolean }) => { - console.log("AudioInfo.vue > registerPreset"); // 既存の場合は名前をセット if (isRegisteredPreset.value) { if (audioPresetKey.value == undefined) @@ -951,7 +950,6 @@ const updatePreset = async (fullApply: boolean) => { // c.「プリセットの再適用」をしたとき // 適用範囲: 現在選択しているAudioItemとpresetKeyが同じAudioItem const audioItems = store.state.audioItems; - console.log(audioItems); const audioKeys: AudioKey[] = Object.keys( audioItems as Record, ) diff --git a/src/store/audio.ts b/src/store/audio.ts index f7a5227289..1bfbf73c97 100644 --- a/src/store/audio.ts +++ b/src/store/audio.ts @@ -234,9 +234,6 @@ export function applyPauseLengthToAccentPhrases( audioItem: AudioItem, pauseLength: number, ): AudioItem { - console.log("applyPauseLengthToAccentPhrases"); - console.log(`pauseLength: ${pauseLength}`); - const newAccentPhrases = audioItem?.query?.accentPhrases ?? []; const newAudioItem = audioItem; @@ -1181,7 +1178,6 @@ export const audioStore = createPartialStore({ state, { audioKey, pauseLength }: { audioKey: AudioKey; pauseLength: number }, ) { - console.log("APPLY_PAUSE_LENGTH"); const audioItem = state.audioItems[audioKey]; const newAudioItem = applyPauseLengthToAccentPhrases( @@ -2819,7 +2815,6 @@ export const audioCommandStore = transformCommandStore( { commit, dispatch }, payload: { audioKeys: AudioKey[]; pauseLength: number }, ) { - console.log("COMMAND_MULTI_SET_AUDIO_PAUSE_LENGTH"); commit("COMMAND_MULTI_SET_AUDIO_PAUSE_LENGTH", payload); dispatch("COMMAND_MULTI_APPLY_PAUSE_LENGTH", { audioKeys: payload.audioKeys, @@ -2934,7 +2929,6 @@ export const audioCommandStore = transformCommandStore( { commit }, payload: { audioKeys: AudioKey[]; pauseLength: number }, ) { - console.log("COMMAND_MULTI_APPLY_PAUSE_LENGTH"); commit("COMMAND_MULTI_APPLY_PAUSE_LENGTH", payload); }, }, diff --git a/src/store/project.ts b/src/store/project.ts index 5879f64add..6519902dc0 100755 --- a/src/store/project.ts +++ b/src/store/project.ts @@ -620,7 +620,6 @@ export const projectStore = createPartialStore({ */ SAVE_OR_DISCARD_PROJECT_FILE: { action: createUILockAction(async ({ dispatch }, { additionalMessage }) => { - console.log("SAVE_OR_DISCARD_PROJECT_FILE"); let message = "プロジェクトの変更が保存されていません。"; if (additionalMessage) { message += "\n" + additionalMessage; diff --git a/src/store/proxy.ts b/src/store/proxy.ts index 051a458004..1442eb3644 100644 --- a/src/store/proxy.ts +++ b/src/store/proxy.ts @@ -40,7 +40,6 @@ export const convertAudioQueryFromEditorToEngine = ( defaultOutputSamplingRate: number, pauseLengthMode: "SCALE" | "ABSOLUTE", ): AudioQuery => { - console.log("convertAudioQueryFromEditorToEngine"); // editorAudioQuery の内容をそのままコピーする const newAudioQuery = { ...editorAudioQuery, @@ -56,7 +55,6 @@ export const convertAudioQueryFromEditorToEngine = ( } else { newAudioQuery.pauseLength = null; } - console.log(newAudioQuery); // 変換されたオブジェクトを返す return newAudioQuery; }; diff --git a/src/store/ui.ts b/src/store/ui.ts index ac7a5793de..f517b1483a 100644 --- a/src/store/ui.ts +++ b/src/store/ui.ts @@ -432,7 +432,6 @@ export const uiStore = createPartialStore({ * 保存がキャンセルされた場合は何もしない。 */ async action({ dispatch, getters }, obj) { - console.log("CHECK_EDITED_AND_NOT_SAVE"); await dispatch("SING_STOP_AUDIO"); // FIXME: ON_BEFORE_QUITTINGなどを作成して移動すべき if (getters.IS_EDITED) { From 96b82782ca40bb2486aec97e7ef6465142e071a3 Mon Sep 17 00:00:00 2001 From: X-20A <155217226+X-20A@users.noreply.github.com> Date: Fri, 14 Jun 2024 08:33:56 +0900 Subject: [PATCH 50/86] =?UTF-8?q?=E6=95=B4=E7=90=86=20[update=20snapshots]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docker-compose.yml | 8 ++++---- src/openapi/apis/DefaultApi.ts | 2 +- src/openapi/models/AudioQuery.ts | 2 +- src/openapi/models/Mora.ts | 2 +- src/openapi/models/Preset.ts | 2 +- 5 files changed, 8 insertions(+), 8 deletions(-) diff --git a/docker-compose.yml b/docker-compose.yml index 4e79ef7d2a..c7215ca192 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,9 +1,9 @@ version: '3' services: test: - build: . + build: . working_dir: /work - # If you don't have node_modules, use "npm ci", install node_modules into the yor directory. + # If you don't have node_modules, use "npm ci", install node_modules into the yor directory. # Use command bellow # `docker-compose up -d --build` # The container will stop automatically after install @@ -12,7 +12,7 @@ services: # command: "npm ci" - # After node_modules install, use command bellow to exec "/bin/sh" and the container will remain. + # After node_modules install, use command bellow to exec "/bin/sh" and the container will remain. # `docker-compose up -d` # To access container, use command bellow # `docker exec -it voicevox_test_1 /bin/bash` @@ -21,7 +21,7 @@ services: # If you want test automatically (test runs when you save any files), use this command property and view logs - # Use Command bellow + # Use Command bellow # `docker logs --tail 1000 -f voicevox_test_1` command: "npm run test-watch:unit " diff --git a/src/openapi/apis/DefaultApi.ts b/src/openapi/apis/DefaultApi.ts index f8d710a278..0295755437 100644 --- a/src/openapi/apis/DefaultApi.ts +++ b/src/openapi/apis/DefaultApi.ts @@ -2593,4 +2593,4 @@ export class DefaultApi extends runtime.BaseAPI implements DefaultApiInterface { return await response.value(); } -} \ No newline at end of file +} diff --git a/src/openapi/models/AudioQuery.ts b/src/openapi/models/AudioQuery.ts index 3830b675a9..b366a4c894 100644 --- a/src/openapi/models/AudioQuery.ts +++ b/src/openapi/models/AudioQuery.ts @@ -167,4 +167,4 @@ export function AudioQueryToJSON(value?: AudioQuery | null): any { 'outputStereo': value.outputStereo, 'kana': value.kana, }; -} \ No newline at end of file +} diff --git a/src/openapi/models/Mora.ts b/src/openapi/models/Mora.ts index 9f3f1c7faf..6892222dfc 100644 --- a/src/openapi/models/Mora.ts +++ b/src/openapi/models/Mora.ts @@ -105,4 +105,4 @@ export function MoraToJSON(value?: Mora | null): any { 'vowel_length': value.vowelLength, 'pitch': value.pitch, }; -} \ No newline at end of file +} diff --git a/src/openapi/models/Preset.ts b/src/openapi/models/Preset.ts index 38ab356854..534b47211f 100644 --- a/src/openapi/models/Preset.ts +++ b/src/openapi/models/Preset.ts @@ -161,4 +161,4 @@ export function PresetToJSON(value?: Preset | null): any { 'pauseLength': value.pauseLength, 'pauseLengthScale': value.pauseLengthScale, }; -} \ No newline at end of file +} From 586f41098032a33376a88d1bbcfa19c52190af1c Mon Sep 17 00:00:00 2001 From: X-20A <155217226+X-20A@users.noreply.github.com> Date: Fri, 14 Jun 2024 09:31:47 +0900 Subject: [PATCH 51/86] =?UTF-8?q?=E6=95=B4=E7=90=86=20[update=20snapshots]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .env.production | 14 -------------- .env.test | 14 -------------- package-lock.json | 14 +++++++------- src/store/audio.ts | 14 +++++--------- 4 files changed, 12 insertions(+), 44 deletions(-) delete mode 100644 .env.production delete mode 100644 .env.test diff --git a/.env.production b/.env.production deleted file mode 100644 index 5b0dcb0498..0000000000 --- a/.env.production +++ /dev/null @@ -1,14 +0,0 @@ -VITE_APP_NAME=voicevox -VITE_DEFAULT_ENGINE_INFOS=`[ - { - "uuid": "074fc39e-678b-4c13-8916-ffca8d505d1d", - "name": "VOICEVOX Engine", - "executionEnabled": true, - "executionFilePath": "vv-engine/run.exe", - "executionArgs": [], - "host": "http://127.0.0.1:50021" - } -]` -VITE_OFFICIAL_WEBSITE_URL=https://voicevox.hiroshiba.jp/ -VITE_LATEST_UPDATE_INFOS_URL=https://raw.githubusercontent.com/VOICEVOX/voicevox_blog/master/src/data/updateInfos.json -VITE_GTM_CONTAINER_ID=GTM-DUMMY diff --git a/.env.test b/.env.test deleted file mode 100644 index dcf447f8b2..0000000000 --- a/.env.test +++ /dev/null @@ -1,14 +0,0 @@ -VITE_APP_NAME=voicevox -VITE_DEFAULT_ENGINE_INFOS=`[ - { - "uuid": "074fc39e-678b-4c13-8916-ffca8d505d1d", - "name": "VOICEVOX Engine", - "executionEnabled": true, - "executionFilePath": "../voicevox_engine/run.exe", - "executionArgs": [], - "host": "http://127.0.0.1:50021" - } -]` -VITE_OFFICIAL_WEBSITE_URL=https://voicevox.hiroshiba.jp/ -VITE_LATEST_UPDATE_INFOS_URL=https://raw.githubusercontent.com/VOICEVOX/voicevox_blog/master/src/data/updateInfos.json -VITE_GTM_CONTAINER_ID=GTM-DUMMY diff --git a/package-lock.json b/package-lock.json index 397cc6c0f1..5dc8f2f59d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -4010,12 +4010,12 @@ } }, "node_modules/braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", "dev": true, "dependencies": { - "fill-range": "^7.0.1" + "fill-range": "^7.1.1" }, "engines": { "node": ">=8" @@ -6748,9 +6748,9 @@ } }, "node_modules/fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", "dev": true, "dependencies": { "to-regex-range": "^5.0.1" diff --git a/src/store/audio.ts b/src/store/audio.ts index 1bfbf73c97..68c60f3690 100644 --- a/src/store/audio.ts +++ b/src/store/audio.ts @@ -705,9 +705,6 @@ export const audioStore = createPartialStore({ () => undefined, ) : undefined; - if (query) { - query.pauseLength = 0.3; - } const newAudioItem: AudioItem = { text, voice }; if (query != undefined) { @@ -1319,12 +1316,11 @@ export const audioStore = createPartialStore({ length += m.consonantLength != undefined ? m.consonantLength : 0; length += m.vowelLength; }); - if (state.pauseLengthMode === "SCALE") { - length += phrase.pauseMora - ? phrase.pauseMora.vowelLength * query.pauseLengthScale - : 0; - } else { - length += phrase.pauseMora ? phrase.pauseMora.vowelLength : 0; + if (phrase.pauseMora != null) { + let pauseLength = phrase.pauseMora.vowelLength + if (state.pauseLengthMode === "SCALE") { + length += pauseLength * query.pauseLengthScale; + } } // post phoneme lengthは最後のアクセント句の一部として扱う if (i === accentPhrases.length - 1) { From f18a8630b35129757d29163bb2af3504934c2d0a Mon Sep 17 00:00:00 2001 From: X-20A <155217226+X-20A@users.noreply.github.com> Date: Fri, 14 Jun 2024 09:33:39 +0900 Subject: [PATCH 52/86] =?UTF-8?q?=E6=95=B4=E7=90=86=20[update=20snapshots]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .env.production | 14 ++++++++++++++ .env.test | 14 ++++++++++++++ 2 files changed, 28 insertions(+) create mode 100644 .env.production create mode 100644 .env.test diff --git a/.env.production b/.env.production new file mode 100644 index 0000000000..5b0dcb0498 --- /dev/null +++ b/.env.production @@ -0,0 +1,14 @@ +VITE_APP_NAME=voicevox +VITE_DEFAULT_ENGINE_INFOS=`[ + { + "uuid": "074fc39e-678b-4c13-8916-ffca8d505d1d", + "name": "VOICEVOX Engine", + "executionEnabled": true, + "executionFilePath": "vv-engine/run.exe", + "executionArgs": [], + "host": "http://127.0.0.1:50021" + } +]` +VITE_OFFICIAL_WEBSITE_URL=https://voicevox.hiroshiba.jp/ +VITE_LATEST_UPDATE_INFOS_URL=https://raw.githubusercontent.com/VOICEVOX/voicevox_blog/master/src/data/updateInfos.json +VITE_GTM_CONTAINER_ID=GTM-DUMMY diff --git a/.env.test b/.env.test new file mode 100644 index 0000000000..dcf447f8b2 --- /dev/null +++ b/.env.test @@ -0,0 +1,14 @@ +VITE_APP_NAME=voicevox +VITE_DEFAULT_ENGINE_INFOS=`[ + { + "uuid": "074fc39e-678b-4c13-8916-ffca8d505d1d", + "name": "VOICEVOX Engine", + "executionEnabled": true, + "executionFilePath": "../voicevox_engine/run.exe", + "executionArgs": [], + "host": "http://127.0.0.1:50021" + } +]` +VITE_OFFICIAL_WEBSITE_URL=https://voicevox.hiroshiba.jp/ +VITE_LATEST_UPDATE_INFOS_URL=https://raw.githubusercontent.com/VOICEVOX/voicevox_blog/master/src/data/updateInfos.json +VITE_GTM_CONTAINER_ID=GTM-DUMMY From 90d5e5675407e111a9adedf893d0b06e647a92aa Mon Sep 17 00:00:00 2001 From: X-20A <155217226+X-20A@users.noreply.github.com> Date: Fri, 14 Jun 2024 09:42:35 +0900 Subject: [PATCH 53/86] =?UTF-8?q?=E6=95=B4=E7=90=86=20[update=20snapshots]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/store/audio.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/store/audio.ts b/src/store/audio.ts index 68c60f3690..41066bb3ff 100644 --- a/src/store/audio.ts +++ b/src/store/audio.ts @@ -1317,7 +1317,7 @@ export const audioStore = createPartialStore({ length += m.vowelLength; }); if (phrase.pauseMora != null) { - let pauseLength = phrase.pauseMora.vowelLength + const pauseLength = phrase.pauseMora.vowelLength; if (state.pauseLengthMode === "SCALE") { length += pauseLength * query.pauseLengthScale; } From 43be8ed44ae0249b2fb1fd73ddb37e4abccd099c Mon Sep 17 00:00:00 2001 From: X-20A <155217226+X-20A@users.noreply.github.com> Date: Fri, 14 Jun 2024 14:16:00 +0900 Subject: [PATCH 54/86] =?UTF-8?q?=E6=95=B4=E7=90=86=20[update=20snapshots]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .env.production | 14 -------------- .env.test | 14 -------------- ...3\202\242\343\203\255\343\202\260.spec.ts" | 9 ++++++--- ...347\224\273\351\235\242-browser-win32.png" | Bin 54318 -> 55238 bytes 4 files changed, 6 insertions(+), 31 deletions(-) delete mode 100644 .env.production delete mode 100644 .env.test diff --git a/.env.production b/.env.production deleted file mode 100644 index 5b0dcb0498..0000000000 --- a/.env.production +++ /dev/null @@ -1,14 +0,0 @@ -VITE_APP_NAME=voicevox -VITE_DEFAULT_ENGINE_INFOS=`[ - { - "uuid": "074fc39e-678b-4c13-8916-ffca8d505d1d", - "name": "VOICEVOX Engine", - "executionEnabled": true, - "executionFilePath": "vv-engine/run.exe", - "executionArgs": [], - "host": "http://127.0.0.1:50021" - } -]` -VITE_OFFICIAL_WEBSITE_URL=https://voicevox.hiroshiba.jp/ -VITE_LATEST_UPDATE_INFOS_URL=https://raw.githubusercontent.com/VOICEVOX/voicevox_blog/master/src/data/updateInfos.json -VITE_GTM_CONTAINER_ID=GTM-DUMMY diff --git a/.env.test b/.env.test deleted file mode 100644 index dcf447f8b2..0000000000 --- a/.env.test +++ /dev/null @@ -1,14 +0,0 @@ -VITE_APP_NAME=voicevox -VITE_DEFAULT_ENGINE_INFOS=`[ - { - "uuid": "074fc39e-678b-4c13-8916-ffca8d505d1d", - "name": "VOICEVOX Engine", - "executionEnabled": true, - "executionFilePath": "../voicevox_engine/run.exe", - "executionArgs": [], - "host": "http://127.0.0.1:50021" - } -]` -VITE_OFFICIAL_WEBSITE_URL=https://voicevox.hiroshiba.jp/ -VITE_LATEST_UPDATE_INFOS_URL=https://raw.githubusercontent.com/VOICEVOX/voicevox_blog/master/src/data/updateInfos.json -VITE_GTM_CONTAINER_ID=GTM-DUMMY diff --git "a/tests/e2e/browser/\343\202\242\343\203\203\343\203\227\343\203\207\343\203\274\343\203\210\351\200\232\347\237\245\343\203\200\343\202\244\343\202\242\343\203\255\343\202\260.spec.ts" "b/tests/e2e/browser/\343\202\242\343\203\203\343\203\227\343\203\207\343\203\274\343\203\210\351\200\232\347\237\245\343\203\200\343\202\244\343\202\242\343\203\255\343\202\260.spec.ts" index 06cac7487e..bdd9acf4da 100644 --- "a/tests/e2e/browser/\343\202\242\343\203\203\343\203\227\343\203\207\343\203\274\343\203\210\351\200\232\347\237\245\343\203\200\343\202\244\343\202\242\343\203\255\343\202\260.spec.ts" +++ "b/tests/e2e/browser/\343\202\242\343\203\203\343\203\227\343\203\207\343\203\274\343\203\210\351\200\232\347\237\245\343\203\200\343\202\244\343\202\242\343\203\255\343\202\260.spec.ts" @@ -8,18 +8,21 @@ import { assertNonNullable } from "@/type/utility"; // アップデート通知が出る環境にする test.beforeEach(async ({ page }) => { - dotenv.config(); + console.log("アップデート通知ダイアログ 出力"); + console.log(process.env.VITE_APP_VERSION); // undefined + console.log(process.env.npm_package_version); // 999.999.999 // 動作環境より新しいバージョン const latestVersion = semver.inc( process.env.VITE_APP_VERSION ?? process.env.npm_package_version ?? "0.0.0", "major", ); + console.log(latestVersion); // 1000.0.0 assertNonNullable(latestVersion); // アップデート情報を返すAPIのモック if (process.env.VITE_LATEST_UPDATE_INFOS_URL == undefined) { - throw new Error("VITE_LATEST_UPDATE_INFOS_URL is not defined"); + throw new Error("VITE_LATEST_UPDATE_INFOS_URL is not defined"); // 該当しない } page.route(process.env.VITE_LATEST_UPDATE_INFOS_URL, (route) => { const updateInfos: UpdateInfo[] = [ @@ -63,7 +66,7 @@ test("アップデートが通知されたりスキップしたりできる", as // 再度開くとまた表示される await page.reload(); await expect(dialog.getByText("アップデートのお知らせ")).toBeVisible({ - timeout: 10000, // 表示に時間がかかる + timeout: 20000, // 表示に時間がかかる }); // スキップすると消える diff --git "a/tests/e2e/browser/\343\202\271\343\202\257\343\203\252\343\203\274\343\203\263\343\202\267\343\203\247\343\203\203\343\203\210.spec.ts-snapshots/\343\203\241\343\202\244\343\203\263\347\224\273\351\235\242-browser-win32.png" "b/tests/e2e/browser/\343\202\271\343\202\257\343\203\252\343\203\274\343\203\263\343\202\267\343\203\247\343\203\203\343\203\210.spec.ts-snapshots/\343\203\241\343\202\244\343\203\263\347\224\273\351\235\242-browser-win32.png" index 51b4bfea7ee086361c37af661ae0938867dd68f0..09781ae4ee7326a2f7e85907c6e1fd51dfba301d 100644 GIT binary patch literal 55238 zcmcfpWmH^U)HMng5(2>zNN@`t+zIX)T!Xv2y95XXcefBcXmEFTcL^Tc-Fox9-+S-< z(?5EQ?j|*;8pWw|cAdTUTyxH~c7o+(#E{?Myn#R<$P(hh3J?e^cnR$c4+oywYfg;7 z6O@C3m>{Hd1aB7tA%aK<3n;m!9V~ljDowB4oJNMAP;!EQRI!EzU&9gusy31y<0`t! zg%2qQVv|%{`*HJQcTdO12$ZCvhY+uRPHnuRhW>)fX^$t1(|O92uxUCcR~V)r20cQw zejJG{3Ky8_m#BF>JE;1{{2C05pZ&dFcY83yZlZZNzVSKuw|e~%|v zl+4*v#i!jyt#DChnX2#ru7gQJKA4}o%cVbv;Qju42-e5!&-PI_xYibZg!hpohWzgz zI(V{0Dz_i>=;{`y-v;oJy@ULp(}I&9{jR8BQczI1xo&+P4#y4W{qp#Y3>xx3X9T}H zv|KLtloRN6WJE;+;h|Y#)L|f{!=#SR#{oIXISWiN#MV|r|1(hVJAkjATsmbe zOX#)amoI9~?$zK^Xo(ANZrpFi8ngKlX}^0qsY_!=v<8r~==BLvackxprt<_oMP}kw zw)hdT6K`YXxYSD4?@4CiZ`NM`;;K(;GVK&RjS(M$%lAs-Y61@ZMjH!QGM)s$yV&Uwq}K7-Me7-By@-jH1H$!MGkIiV7YJ zM|kdpXmjGtGl?IcLl zeGnSA9jri$f(Q0tz690-h3eO`G^pVoNBCfVRjwg}Fk(STru$L^@w4OpG(U zq(xv3N=5SySYp_Yh0_h7Hz~!wGg*bbNggbTW6oMl@5<9MzaVeZkoY%e7JyvbDUZcU z>XjsQX6Ju+hcmnx+)hcg>WkB$X_PCE(~b^C?W1&uk+B9o%h5o!tf; zHa2!wcelKzCQ{qpbP*I5w=08m3QPSUYq6S?6jE;le$k&WDRP79-^!OO&hGA938KJpVb!|d4T!(D*1&0L#JSn z5q^tCU7vjqg4m#S+SRN4l<3RZt52I+M!u)TnsBC!DpJX?tS~uqOvoW2oR2j|6DpYQ zlkZ|JTzR^EJF}_p@voM4F)RD7vY4bsho*r`ZCTVvu$k=}_eHVRua?F5ch+Lj!Q6#Y zSy}XEMxy7Ug4L^xgYB@|66_?jI-gXfr)>H1j@Zz#2s#6YgDqWsaQrn{h542flN*sD zaQkLs8z?_`7>)`OUnIpPOITYcFJ%%NZkA!bb ze>vv82p0@uUKziJQsEI72GiNk_nC0!;a@mLLqyD`SD29+vx9kMvtO?wePVVq?vTN< z}AFyx`-0=e4RtfJw4PE z@PZ_iWY2we-d14`-&7s??^=&vWuqH=!POIYc&uaa+6W4%1k zOXw4(UgG@OXWHznAGOh(JC!!2`Y(Mt%)hAxME_mYr^nQpwezPH*}sb_Bgd*Eb|=>~ zlBGID72&vTH=IrT6LAF6H=I_inUdHn7RZ&a*$%R!Kar$h=ZnVPq^xguRQ3n>P*K=f zLkzpotl>%QlwhuVH*v>~BE%+{(Z0*b{w>hf9B$qF+S45#vBE@3_fvyCESd8|77vdv z^o7}O((Axq7v=F@q)B~x(-&0Js?Ip4yMg9>38>+ub7c>or)V^DC`<(m4|xnl)YtRH zve~{(vHQM5-&t^9qA_L9Cq|Ao_?%5tkXhxu*es0^i%@y^tfe6ljTMU^8&zQ(m^QU* zb}`443V~dZ1_Z?JDX_j(p(}HQ4gTP+bzH!yRXejXB9$M`50gS7iBYETYd%S=Yw0JK zqD|JfB=OWIB#F{@0fFNEnnt=~q#VhgP75Aq9c#O}^uErFnIXZ}ilbGCFO=SQxz5`ra*`6H7c}DseNb#^Pthmej8Ng^%pW zRhW3(htMr@^c9L^A}gmIS=kN;n6cpkPagF#I^3SFiEcctpMn#Ax6-BzHyGglo zUZ!j@wkl|-ubarqr7&V2=%a4>TXm{KIFWUJ`>R17QSDC{xBTC?kb*f|hs_Wr^+BCk z1(KBN^EuMw&J^||L5D+29K;D2wMhre)EqrnV;UkhzA!ltWvK(5+?{!?N_m2CvOO)@ zF!_1jbN=;joqwp`BTwDDK0zcNYV_PsF1{QlWiY|{Rzp_$A=8xG|7%lQe1K8e+f}Nt zXSKJMhb5Kx{&&lyO)Hf=ST%2m?9VZU^$)XH>f44x|tpyt$w&ja?1gkDIe6D*VvY?`L}BkU?clQQNE&({vk48!L3MR zd4kG;5*8h$a1!L+i^B5DVe)%!2}t)!h`Cq-flq77Hq^=B#ASg~e2V(EZH!&-K${k< z0BHPPR??kjQK|1et-Em;S{c~3-MxHmyjsw{p6KMVg_k!WNdF=>*Z1-T*VMjzkin;D zr;hVdhJI@ghm2}$erFf9vDvrxb;OqCTZF;2ax>;VlD=@C(o}DFz%8fS9e0s|j|!}w zvfmvVw4bPM+Rv>`=nn&dbgH?;qK>btg~JNnOT_Q^2H`h^tLD$;FRlOCE6WBG!CzPC zdrLjTaqX zGhr|AXMekoo8hP0R5S zD&2245Bkfd0<3MIPct#zUL4_|9nW}jKlcy$kfs%&Du-d+Aou2s2w_9|{E}NAuu?Te z(J}N7y+(#cN$FX_-qi%@s^&ZB+r;MxLb_qtmrkN2iwF~_6yN=k6fuohv8yv_31kWN z>#iZBt>;84wclj=6r&PfV=^A?-Zzvcf4O>OYp@V2tWL)d)u7cI9ii~?^@%*AyLS0G+++#W1X`o`=)d9Ma>lg6 zMwQAZXMafiXmdIO9W^|jW?|OHB{5R*W-Z3OrleLPznoa(9A5S^akFQl4s!BSX_*3{ zvf^ES9E1%~=2hG_U+2h_zl;_IyOOcU$Rzrb+{qm8DAQPD9I6W@{SmaLecL5uKL~7e zNDMH%et`F!_9iyoXL! z=tGu?o+uV$V^M#iEpD8@(C+7LT$V`~Joj%-*!?Hl=8L8zFlLiF`g-yVm13{f^dybe z7RN8{bh#?;B_JgI=MR19G5&jFN_pg85D1F&12TW#;j36f~25RUHIU~QZG zg{vrV|JIlm|9E%;nt+^*c4g6MY-9@g8%IaYuaP^Zok!_?c{W57dax-Np)+HY z9A-;POG!*dZy=vOeVR_#pZh~%(|n21>~T%b$45wCwkNi>f(&@F1J;5LFY?b{GU=SG zb5B%oPy;YfmsSsovye7IRm3{|dcR`j*9(o+8@1FkF#BT@u^7WC4y89}ueRZiuZ!FK zWKu)zJ-f>iVbyFje&wXGppE?gfkpX!$uOoNT-Uz)mk1nKv!++%*}VImKX@^Q=tn6o zRB)b6SPRZ!5E_;VN))1;6MiCLNw>{^ASHY~&rde+M#pq(n`j@oTSEZ#Q__XIWA8bH z`A!r4l{-G?qMUVE!^Hy&Q(>6_-%q`38N-jbR7>yA`<5~W@<`M#0?;Zs4vhVn4!wu` z^EsNo&9p2pe$3h+ksJ{EQd)`;*un-s`3@PU%|aj6KMLLO%R=r6%)Bme0 ziA(~%-rHV{de<~vp!u$N3m!V~3)JE^* z@#Sd|^~?r{W`gFt3o`@)WKb!dqP{V#o>}w-7|Wu)>%?4aQ53az5h}y3)`V9;<^0v| zieQTYVc3olrO$KYx-I5h#9%o4S+r5H5=}~1zKj@+#zGZy;)H{=v3Ujgz8jU2BhgNC zRW-9}`vy8__6mRZMNw=b{MWKc79dx zneL7q_>FzuPwzh2UH!V-oZ;_-TK4V&6{F8ASU#iBjeT<6a1WPYtcwyS-3vM?K)~W3H_w*C}+`O5-lBgAV+%R#^ z&bSSl)98Lv=o8hP+t+0*yhMDFsTORG90G4~VtMVzLea9q%lMizJYrUSPJ3tbbDP%` z-OUNPX7KawrW6l%AA4MtBJ21i=sXNuV)*Rggzl6qIkh$)BFFMnJ#d^W1e{0>+<)Bx@?6ciMT z*+h;2?!0ymp#3!=iY(O7AE;WtFM`I}`*x)^`yA+?iGqOcqdGQy1rO=i+`UdtL+wy!ebGZXd*xc73^5)pX z6#|~Z(Dm^-Zw2Y#k8R6R8S~Se536LDmob{}{Xf*`evjT{kC7`*wL*k8tYD_gkb-E+ zM}+VzXTr%MBQ^dKztS1r^WN&EqWJeXowSl9QDs7W{#un&r`By*ok@WMgJ9g0-F;0a z>g`F7b6iRBtY}-)`}ec>3Q%aD9oZDusaSrVvldL6pf{`&U|qdq3hKiC7BQ%aCsr&D z2g`UL?#jZU*XQ-;6+?^O)m+jd>Kn3O;v!sp zB7EUFzxXgOK7#3>XiBSYsd)+EVQIhiq7uDiKrO0?k#P7j<9)Owo6LEln+H{=VlR%k zW90rcXc@$z!)7sFrqm`S67U3hKg;6X+oRj<`;I(?g=Vxvbm~-Gf>L@KW6}P>;9goNTz5kl=#?a(sEH<<89PaaV1;A%UyLI9G%*WB^2U-8) zGS4}__&k^?vGm^V2lp+S=2EThPG!lWZCWVPeX88@oTN%sYuX~c^f(-GZx{3sm(~I{ zbL&1vqU%^<`G7xql{piyXaqQ@erY>&OYe+kA8cFNh)#V{@Z+s}?8(1)N1wAma8u`| zM|bwIz=Q=Mw+I18mwb{79z~EyV&?UrCr|Qs$qw>(!tWWIw561M@Ffh_GXYufo8jXI z%CZTH62i?zB#v%U`0kuErm922>~zuP>M|COH5#gKL}}D5ZLk_8$;3z0e`p!&J8M!} z&Ieo^<638!OfoWsSG?hQdV-ZkYD^}~${O);hGw4hpDQmtiylA-*N{HDu+`T>PhNiB z?!2_pswGFJW^-q-^8c6Ga9sU6>Ty-XuWCX|8;#)y!?L6Y%tF$iSeqVc@}8C$*kHcR z59&V?^0t%>>y)omg^2|u2(}m49b!{oE11y^yGjuG_ekq)K`l}SR+>BK1u?pH52q0; z$TED;Dskh|{62BUO{mfnmrJ9|8Z~d$ zku_PKN(pW3NGnvek6^JS42${iCgy3E$>&m&I>Ufa_Sg0(dy^X&d6a$d+R=V)YVSLn zFo+2c{4KNzCjOjb^Pn_64A!dk+OM=1-%dzfEa|yE2}MXANor@rmA6KcBhkl&?3q&v z+|D@HbPfM)^_(Tfo`a!xAb=hEX!$GVaoA(dV+yw>EjHyMWB4j^BbjkNvAUGX-8H$N z8rg8D1)2gqCryEzO*o$dlzo}&r*fG%jKhLBth_H|7VI|QU`|idYq}(4*gE5LUc)O z3*~VG@^>0LOPmPogE1>(=Wlw=)x(*{gc}h~XwgsnnNl%3o-;wP=;#DrZrY&UBk2f9eoxKZ z^~Jf9keK^r@+6E}K+D%ra)xN&p~*U18Jafsfsu3=nL^<1)jRK{87B+wx1&v;Ve|$K za7_9tZEd0puuiuHF$fsmZtwRzEhjf!8S8(yke1Lb4+~C_+D3KGV8w5<|BD-AsAqXn zl;`V1L}G|8PnZ^IZY#vgFD@6J*3%(^gM_|Shc89OtdA3Xr6s;Q&4)FNvcEIU_Sb=h z^caQMHM&ISv(9ixEwa?&J4s(3$hpgf(HhE!U<31^0RAx#ohcvTq+|Gwp4)|ya1?1l zqO4VwrAXA@Z#c9M$Yq?xZ5Ol8X-8(wa)~aQ>EX2u+m#G^l&M5wV!NnAJK!})i(EMR zNwR2U5RB}i5flqq5z6!isW0#`d)9Hpge4G?GWynbF{H>VFKKBokP+|OtMH-1zm7;q z--*Q}eK3=zJ0KQW81OTex7mMREJ{NG-;usHv8#6%?tW8KtLVOqM{(`d$yZD8x9Qt8Q!9!`zuiyZ4V_^ znN7kKDoIL8z5y~XE}m89{!C`E(gfAx>Htck{I3efmzy0LMqRBbYQxLWUDfv)s3eK% z=b8zc^lP(&t<$wntQB~&#@z`@Rqlu(f8mMQEsJx(PN z8?8Qf71bNIoxC!#J!YO#dU|VLngf-*)$^0Rysi`f*8=GN;wu)vg2oZ2<(P49P5U4p zEUc104{w?&N=V8ZsK^)}{U$ppgq!|7p2Vl!j+9O<@KG-ei$=tLQ9vBAAzblmUA~}9 zPP<)=sSq=y#5+I9BBMsJnK`-x+To zt%Nxr>84B?YYWp+C4I<}t_|3(Y>Wos)5)OmVPia_KP5NR;Dm;FFfi+sS-BWZg1LaFq%+kR+NNbFvj0c9Nst9=%UEQc#Yi?+kGN!qQ7#qSs76 zJSJ+X7tH6IHtv%tJE4;p!)D9Vj?7ZBL;mTvo?gK5$|y^s6dMZu@W*@J_cyYV zLb0__g{!o%G9gl5sUn~YgF|W8ETS`Vw#LiNQQJo{4ENPX5_G5Rse*F{buW)3lYbYL zXt=Gbp{E#)AK*16Wy|!V_k zh*#Ip&rc3tE49W8f|04&p9W*^<9A>`+x~@^jHImrd)lT;eF+nl%EyNp2wrT zw3^h6ETCtYqCou1f*Q6!^HvS#KZ&Fqf$I6IyAlP&z-;rdm3CN`8-H^lrYt^P{`FND zH>)zUCIjHNE(aU_#EU}v-1M3P^}|mb0z*XZWQLslU#D0CNi6ZEkCj7&)}deH)ENv- z>>uh-gm~X?8vhzTC9=FV7d$?BJ9?*Go9CJBRC>m9?(z1B21X+L2{C*KvH1-Ds#(5T zUSB-9|BDSSRyA>;+32SOMFbiX)~?aijvlrzbCq-##>Z{*h8>TJ*mm51I;ii8=MOqB zh16R0c}X5@*q&(W)fFPYU@KsN9ASPHc;RH5Hmb>$PP_tF5VP)97g6AdN8cOsR^t1ybLu~4tZm-U zv!nCPz>fHLAd zWwP`@2*Z1s=Tdelj^)?h+z$2}^ZR~9o3F|@_vL(=V!k7k4n5f;>qUNU75h)7{igCU zaeItA+h@n2yH+~=nh57s6YDMxIg9Za3Ca@{~J@(kPZ-?qi zTe{jvd|cdHLc-DSh?sad&s(M1&5|lA7_z*#q_pZ)rVnqH1A$dc65Ic^+B|-8^m+C9 z-UkVnEv%rRKx3tMYcO%X#tPTk+M1Q^s1_7jri)bFw&GPyCwtt~2hNU_nxP>OUaN)^ zVKFjW|6+&Uo6CWD_1QvI2tTOjnmYEx6>>ka(LC4O5m+la;~*6Mny>p3IbI{RjoI~2 zEi{?=x5BZng!EJt3!GPVif)ifJi_Af@)k8bp)Sju2=YJo4lvn3i&BebG$UYcf4qxNAAQI7d@}95C&AUs3Qb?1Z^#Fki zYFSmfCo*EM2+6ZInm^Y z?hi5(O2WU%klJj5S5gj9R;+zsF{bJmzd$6h6eWGvS+wh9-e!Ln-U)x}h7z<=hBe0+ z&9nHztSwJWe$QjOB3`m{Nk~-w?ld6h}sEiB>FgJTUI|&z_tN*tb zAREPEso~ZXLK~3%ViPDH_&kq3gU~)UR*TA z%IFUd0j2q+(P9!w^HE!!MPsR?A(n?9zc~*V0O;$T*FvQZ1_fBOf(0XUiejpqOK3Ut8m!$QEj|2^tV;xt=D zHD-IH-%`M%{!WGR#SMRu{ofveEDYKd*4`rJ`$jEffg8n!+}f9K^}i2WpLdG?*NNW3 zu0av~Kbi;pP9SfgApiFuTp>RozW>)piMS!c|Ap@Vxe@{7|87|T7eIylKl>B{Ui<#P z9smEAFPpfi#_?0phT!ZZ%WZOTAxzhyq&QCJjs18AmwNu0y_qU70JGI5`AqP3+|{r# z%d|Um@2X|Cx-Ti05H24x-n`tLG1snholdmF=*FU!!%Pjk!PPilnP#_~beqnZZK&C% z!qCUGnXBB`FOBQdzaQ~`&o7S`n#Bz?l4>KYc-& zeFA8~759DG3wNGX&vWG2GM$~j?f(B9Ib|}qgM)%zD-^~>MZFCP32{9iX1@h}I$HU6 zk6ZLUYn`ZkIbRa#AeIYN!DTIXAx`@39?isZff z@eSrRal9lHL$Va!XIls#AD^d}7nJEj)hEeZG+9~M{6!A0I~I*vYmjravrI-aTrRM1 z0uhEoz84T?4zKH3leVt)PQ{&#LjRa&MP4qjjTyj1)*4D-84i=G6Nb0hOrGIXKZHXs4U;3aG7?qt&2;3RaIP56ZZ>AxW77#mdpkAY?pRR zPEG)cScKfyum8%^i&V>E;^Rd?sP_*KSJS(I56NcoR+*0fTHrJ^F?s39$dk>K0c64Y zUULb-g%)D_c;{5AS>I7%G+5{T$SEQs!kR!&N7tkO$M)&L4YY4aIy}2}n84V^poOGhTfB*ioXGVIuG#Cp6Eg06t<=Pwu0(wpI%FCm`cV3BZVCP26%WVDV zJugApSi|fxtp~mGDuQCnMS+|AS{H+mW9UHPb4xw_+I|=o6o)S32ip%n3w-^Eqdp`v zq(KFWmb>b@IV{bH&+am22?u_=s51oy0%u`pN`Q!Y5Lv~yQdpF5e!T%QW})zvHAUtb zjd%jB!1@W3H=Egl@--EprR4kf-5Fn@6$Dx$l3hX)dDRxgiwIIXfwv023M361rLZz- zQuH2BJcZcmNU$ddUGFF%k4Lt@Tm;O2ghX`4_h~}Ha)who^3r}gv6f~I_>%J6G5gXa zT{fa4TvmTz%wz1N$9wd+pSuo3EBF2LP-~dG_&LmEML8;|Ipc50;RADT@aR|@jqC}SN4S@{G!?sDqtl9k58;?mM&jEv)Y&2(A~ z3_eeuoR0tagHZ5aYF|QuNQH{a1l~7#;LWypYSph5h6o%S9LfWmI~qYh=``!c2+~e2 zFOAy$UR`A#JGDODQQO(sh2e80fHns-RaI3Q3`F`f!u*w{==Ot=E5P6l5cgyL3y zrZ+J!Zw3Hd1r?Q^AVP0(;CF!d+=><>5Fm~o`yF3>U+J(j;`wyDbF~Wvnm_;=*d8r$ zJe_Ag&+X4t7=6)p-zC%3EY9!MWrzaH5?pelH`3*E#H^0b^4iWTM2wRe4I9?GTMPK_ z-@jua!4Y^IFa{#yiaI;jOu~6i=1IFp*pnU#KFJ9rd-P-yttdAf4wVoMyv2Ovq`_f!WiiYr_t9EyHAFdW{Sgluw zhr_`XFSHzbKi-XlS*F^msH_~{b-XxQ#jmVq;_dGcyS> z>9unJP#>%`r!F_Tz>HN}sA_xP8f~8a9(Cn=yg*k|Q|mKi>gen=n<>TyD@m|K1qe9T z^JDiI!G`E^%W`{<8k| z;r9ID>HgU9aABG^MV%^sVKMspSED*JSX4Vi4v!C5BC_z?Xi=~i#LCY&9Kzuy! z4{JBKwR#>&1iIZ?$E$&Xfdhxz^Ye3XV<_V#7iw)#eN~FOO<7{%;<{pGc_q}; zuq|ea^;TQFK&IcBhUh>9o%7ur?B z;a;Sh$S}hyvTtq{3ggXrq(4_JEM<4a1;yV>_?yJuTr>C?syolrlmW~YqF{t74Kevf zicu`tLEYs}yOmo;iU6-7K88OAQEF~W+Icg33Z#jX3xhHp3B3-LZKo3$Wx^d z*%bCuBzUgl<5wy2A>S1dA%z5l+ct)dho3~MvfmJLMvDGN$&66~4%(i~Y;w@tQ+;}M zl?O5^$m9Wlnc1y(As7!O={x%ela!fqoYFaHksa9M!5RGN$~v=ZTSI{po3Um;>*iZRJ>3j`N$ zd4BS!v7BFLx&0m#Bo+@pS5(#_X=}>>qG>3ZIfx>|)sKDE6WzC}ip6+1#fV-*POgpb z`BpZ=`_2pw2}?Kf0erE*Jn7Vl2B-ad<31k|uApZA*aY+1DrpE=bGF+*exnn;L4&g{@B z@rtNC6R%%wF?``b3G0%2?It-CrOyNgqR`{JVDA7j{irDsiDM_hOk|A4&WujtUxw7Rh%Up)-F_KY7;I@jx-54)NH4DcvVyEV7Ayb@Jm8s(pJs9NIbLaQ zdb-=cxx1UFvC_z&gg(Lq&i=#w>hm_hPR%-7C|_S+2pkHYIN*1HP5?lA3D2$nYt+&!V`uux9I-VXHqa@NEkwjDWO67ys#s|sg7T(> z-S51&x}X^vp{OZZfjLk!+vS>w1ez*zU?3;Y>ls~MUOp5W7*wOdcmg_L{rGqk1R`L7`;8>o!R zXQrLuR1Z=;r2ju-e)>Q!kEAF7*>AHJ9QDml(r;o+x=2M7*RSISPn3 zC`Jo3;say)|FDNP)%>IOV#f`!|1o+pIf%lk?`&c2O58hAB!6{)AT8ocu5T0MK(*sm zNZ`4LQLd_rCq2C~!7Q{LQnMjF1T|C(8BWA48_a^Hhj=niMs~;;+CE3vKPZQ}a*p@d zx=SA-R^RuoH_*y=5!7B@p;ks+34BIO%+-VNqY9azGgH4c%H;Rh$UJ~04-{T&B5XCU z5ETCofy8o&Kx$Ser0>yR&JhthX0D3MZ;Tz!yc#R49w_7N}S>e6;e_{7<`=W4HY-uPd z|E_n30(1ft$;#$$V}1Q}p+MQ}elnXCj@SLwR_pV9E53VNI$-z6qkPZYbE3o`D*ZuA z>G=rP@!V_)cXgdaEcvwc^}q3KBm(Zb2r+M)f1s()VSDIB5?sN0wLV_q0!s3dGyv64 z0t)2CUh%rdfAjs9q@aDUu%9NKOW##wiT^q9jzDND-4_3vDbY9w%#dqnezd>8-O&E& zZg+3{>KWiI<@-1JnadVO=4fr&&F&v#)lyj>?=Jt-v>*{ak+~k#?;IeXgHT$i;9;`ZH7#YhJ9~&A1@S%iHZL$*3usx9sRp>Z+STT0%^HF z;sU^nI%LcY^4Sg;wJv~N-7h)cXk!f)Ypmoc-vdh5;BqV@DH+0(bg~viSOKs)2oG{S z3Gdt1#&5`k4dmJtWC)SI$yY(`a@rDb+fBe0%bXqCGX39++{$?m{i~rN<>VPn(Rvof zNmVgBB!S2rt#l12x_{-xoh~yQ@>onDwK=hD`H}kN=L)Bk*3qX|W}p*9Kv0uuZ>m05(?h<@*8Vd!Bpz-ypl0ennX(O#M^IYY9AKTyLyeF;VdA;V#7Uk+}yr?==Ht^ zh^idqftS1rqDX9L_h$^hDmP*27kbQRNkv=Idn(t?ga4@(qIkc{*+kmfYzI3Y*wBU7 z{hxga`lw-xq<7`Hnc1L(Y9UH6&bWTk%Ymk45p&y(AW*xb!cdnEj8D*{q_pjig6>S^%rVyxKr^`|5BJ0ST!} z%sz$9YHzGk=ZPxhp7k|M*8;26QuxgJ`+`&shMhPXNuHhrh#06Xdi*ZNH2U*9ocY+CTXJlEPUcLCg zO;{rH) z6y)SRyk0~kB>sQ`osJ2iGMbFwd3qL)+Gb>ADCa?OUrs5Kl98R>?qoXLo*8L-o{F$p zEjX?^3eMy_)cM?QVS;5o5=!6F_fx>%6zEP+*#3Q{&I4p3h$aOiExg`h5kc^Zx z04U9~4n+EsaWO)UCg@+kfW3JJ5c0gAB6F!WnPq=)c{v>jah%X@L6Ejz$~ z_rhaQjeG8PxF;r?d{;vinktg2yj4&Z!I+syV1g^g%7bLzIbu&FWD1dg^bb0@pV5aW z-+FQL{yU#|=-B=%=yvG+<*`{t%$oFo~@VV+m>CQbK8 zjXo-OR%P?;yE9SK|*!)@R%%AqS=P zgXpvuKe^23G4#bH2d*v?NPU3*i2$PYVyu8oA!6x)hM@8j3@n|f#GNGJ;)l?rOq)@0 zQJ^sayWi>fj_7&TPk}-L!_C9v23$e>6-(RJ7s9Aos`-(RFB2?4fKwrma5_TYCKtzkNAc*ua?rpBGbxUFk|Cdq6*8p zf8E%#Nd`GL25Y9HXl*GfMSY2%7sH_4U34N!l^*lmBMC=aB_j4r_sPR+z*6oI)EB!& z3r+KF=bg#%e$fKB(akmCLdUP=bG=Gaq=qgazmKN<*sLK7%*y89%oT|B%+_YSl%*6* z7gr@#$qwexB&Y4({b^dq)d(_*7k~Y(hR8R7tX~RQ+}ON(wBZ%{`6&(s6xM%bD*|EQ zUIKsgWsSZ=Llaa|Qi?aZd6|Y)@B47Tu*Uxwh2f##U2 zvm+TF9|uNpDA>;z1;hdy+P{7VzZp{dIx!_sh|aS5opnT`lJVR_?2oFFm@I{l91O> znn_3?94=Hl{0OOUY~*S_1>n3y=n!M?TLy0$=k1# z6w$=z$V8SZSid#!%t&|f`!U7DvcEjTNk<@@T^5|@!Xl#(!>ev~!YNxlz?ibVi%;D= zKpzS;ciu)H+7sdsCYX+L8}rpJ6LrCO*)EUQ1^?_T8SaCiAj^-@z86lC1`9WUE$(GS zj*u}S359?#PeEB@zc>S+n&*S;Ita&FTd5H+2kH;1Q6@2;Q z$IWC&ZH+lC)rX>LcAmXcl}in?>Jo)Q<+m0V)F$cEDjJDms{7TLRVC^lMB0BrzY=B% zM}Yda)MrKRuzY_l){*ov))37;bH{)-A-S2)<9HMaVf*~4iSKxnz4cS|FgX_?^K9pv>hR1mRavN!T9EEIal(_5fDHc)4aoTFB(?6i5;8k>Dn^YmXf{g8VxJ?w>dYtD_zpyEL9xrUemjxE>l*5ht@ z#BOBA)OH>c@mft~3#ys7&~ZFEf%eFf6F+s;^lsHjF#3cOPVW7AL1*=ebFgA+X^AFt zboL|s+hAd|%DJHDa+E*{XYR$VTl8K+H&*Y(nhz*JTh5K>0=}j!zr{(3tG%|p>W#O> zAI@WkwK9%JkHtO}2cmdfx}opSb|NFcDRiQ4B#5N%L^g+aQ!M>1yL5kI1$iw{mnHDg zB;$V!32xJWS*w=hWU9N^d@l%Gl zl}4>7_pKi$HG~WtU6MKxk8&q?e><3xH#Y7|PaZf%iq|gk=>Ia=WkSjpava*ScS@m( zt>@N4vE*sSzVUIlOZ2}dX>cLjt08=9no@&lUb~>APxncF5Zb7Of-0>kl)c>>`BA`v&T5cq;5_w_2nQ$xfehi zkDICP?!40J>Z(KfzD7JI0y+ROD9W2_dLEG4XbEC&;^WOZuUB%c$V)O&;ir?x51?S8v^C#8}97jJJJR#p48i!MSi z01J>75Co)=kOomgN5x`ZM5Lr+5fTbWcQ0a{G4cI<`+R#} z`=5RGb-3203)Y%*KJ$t3+~Xei7?Xl_=IXWb16^l#XYLfm&>lhK)oHh`)z`}x!E*J_E{lya8O|d`>WEUbZC^7on1fpi{)OM z76WKBOXTkE3wvGNw>zs76OOx*hiW}Hk z+#DVl7?|%6n&{8TO1cr&==^OpoyGeg$$oSYV&+w~gY&L7>%W^Yz@ip{YV-!Ea%O5r z&i5W1oUB^2gt9BMky&zt=wjx=kgf7R;`ys*qk;uS^@afOG?;q#2kGL>bBc@A;>;CdZl@xnmX92qn|s6B`Zk;p zPRl{AVQrmrgPmPtycBxHW5Tb}f3NZCLac_0!fv|49=iVc!;>et%I|OS&U<E(s}1-OrS0hke^m5ylO7+{jU-Fu-f9J7mfeOZ3XAo9|@e?J9Lov?MC|IUR} zT|&K7=q<$IdGr-Of?7xg_>qrK8jRZnFd(-=Cwh$MKxiO0H}@XwsOjUrn;qYdpu6%! zS3b!oD=XjN=0m{fn7Az$X-a1sxUq@6~ zJ?8NSncM;U?cNX~&ZscIQja}aeYLU+({m17C56w0wV9c+mE+!d7wf3{EGne2WBO)UWx7_)))-Bz7R6ym_{5X>I?vV7ez`Qdn)wuHq)dd?%xeIHZ@bz zbRavkKm>AK{R^=EIg*FJ&SO?Q>hmC02a!R)XS19SKix+ThAK{OU(c{GMQUqmT0^`= zWcR0w+jmM!R=DwJEJ@wavB{n*HC~%#k7w>BLSVeDwN=gB`~$*ojRjzjs03^tw4MLT zLqtYO>WY#6aI=x-H2x(&s{nvHbA*z6(rsOxGmq!v^c{MD4=Dob7u#oFId;7W{qEDw zKbKXyp)(cz<`s?99UKag+3WB#8+<&mnfx8_KI9VJ26ZvNuhg?Dhyb^>-Isj)0A{`7 zR)HT@#HVZiN6Hm)a(Az>UucNGN}HRT*Lsgf51y>+K&5zhVwA#$cWu?51Y1{7z1ct{ zwra7k+Vxk+6&pbQF&QB4%KP-`R*ye`w6=~8O-;?$FfI9E`DJWRTxL;uz(etX{=&=V zsc3WEkz&&@BpQ^f{7?UU*>GxuMC6c*d@{^I1@61s_)6^EI>=w%U zR9-bt&36mZkmP|ig2=FoI=M7p>blLu)vX2bx0yLWSG3MHvxgQKPIUoSZ$ z{GYqLhmZ2UnV#_KRXSi=2=U#Ek=UQUd$6;r=6Cpc%K+Z+5nU?|^Yzg-^!fmO3H4w;fC~#(wceWRNw{elS$8nDY6F8v zi_zECj^Bvbbq&3h*fj;?rD`{0nP34`G6LLla8b*nKqBe~fRL!%WmaVw+8S@@ZQXWk zVQxMzc|0ZQ+R7Yn)%jkSHfdt)K*4RChY0MB=*%XGLEo_7NODy36i_SL>aubNK0C87 z0&@KU$)z~Hv_3<0752}kcNj-%eJWvYBn!&6tJ3IvEcMseSblT0W+DSp(4yYBj|0@POkIGDHVzFT4T266?AcrAkZ^b zykoRFTq*~KTm(*EZ9j@Gy15)6|8B=#&FjeFZh;O}LDc(p*W6nHC4ZtsSDvntJ-b61 zAqxR*=3prW9hh#|6r@-X zF6%>%sy*Cjui75eH&4j?4z<=m*`NpPmE*FNes=>85n`a)y1LNfyFb%GH)=4k_g(13 zYXtpT55$Ka=;`IcT3q-}?HJoWqpqf=rhd;?1m@e>vu7{igt$)6&e|dfVd^S28#Epg zJ+mtkq6$=!{xygG^;~s(CNtC1b8v9Kbyi}WXV*D$j&36?MmrI1RH2JsS%WK{y{8Mb z*7^;`_kqG4crWZy=CkXd4Cc^d+$#%2QU_b&l~FtHZuT7HeX9XjA5O!XPkoc81W=go znST1NOV2|@v}n)q?;Mm$R?a+qf{K>E)6vmEbclnZumCIqFO%XoM2&MVo6Z@}@z6~i zzu;7er*%=&yE0T!kePX1m?kn~`zJ8L&u;9fWNCn(iY(O>cG9!Jl(4d}WHr(kUvnvbGSAJY<$7Z1z$`sav8CiHfUWwU!wmScN*l1yU8^$~Je)g&epk#vgV2|8; zbJ*QDX)95yZ4+&V3ch|!^)fh(9n`NKceDM>rwnt11W-hc_krw)FLhPPDs7ysKRT*0 zEE1zrZQBeB-`=(eMbEolw|GP7ExX@s3%0w+cZNMTKmP&KC54P%SqH}?rwB%p&xbX7 zLp%}Lg{~7|$F`e!UStgK9KVs4^tJcPMML**&UT>zRYiUJjw^twikCm|c*mD@U>3P4 z&!Ff&6m#3TN%C~dny{JDM%y@bjKPFQJAR~VtMo0JmC`!Id%8#x7R3rSB;bPqUP?7O z>`E>5T<(g@e7SXkf&eOV%b$#lti)a)^rTQ>r-%jZDMqK9B=)(ny!NxUqmkv;FOts~ zDDOJFz3b34F2)+d3GXT8yv(MB&8I~^d>W%7rMNABL|F{c4lj!7IQ85(YF$2QHS=mgo4E*W;PQA2F34I@n-kjyKM^2A)6e%DHAR# zXD4V@ph(omZ%*f6YQAP=Dd}iSu`(XP7xZ%Xv;=wxVt{Ox3*C;TLySu5u&nsvxt+Xd#Lr zPu1fD((<@|WTED{)MT&wI#t!hcZ6Vja3yY#Td9@RDv!{(-2NhKD}}v$sM)}s401+r z?@(XlZxf@8pN?G3?v<1r_BCt2!r}J5XZH=?cORxGw(6#s1d|eKc$t>qIS(@^{-KC^ z!MGb;cM7>lnbSCMC=60H_3m6mTZEr>;}`Q5im5n`*1~6Pg%R?+`jM@=d{G-M5)`iu zE=L<&eO;nN8G?^oH!%7M3dQr!a79^`wNdgZoENwrw$Wb}o|0CWb+*NAmZqD>O}Fqe z=PjoeY~%J{con_)vgYt6a^wsALyPl7cz&1gTlkp67zCO!tVaFbhyEs$ru_A3+D@CJ zCvGWo&>ZKwBJ%A>9ad6xrc0Dd4)l#`_!lUylbpg)Npw{&au?(&NsO^?cfh!wld`pR zSv0O6La*a076d(6`Z0PJjy21K2!sK+G%7V*931^X&rWZ9Gb@0XL3p07A6%z0=P6mR z5{m#A;;a*F92^Gg{0{j2Fk2+`dBYV2gjap<1DfjtN?2@i_1vw0;D%oe#r$@EsFHp~ zvPyQ8c;w2d7jCcAE>xN~+qatgCLsP6&uy6Ix|#ddF|H~qk>K|h0YbKcFaiVu2S7?v z2GKVJ7i0I6v2U#=dVAA=2iFG)=Af=+;s@kCz>8--np#?Ivzznh1NLNo4?!|Tj!UO7 z%kuH5VCl~fxjsKEbQqOQSJQm(AUicx8g$UwhK7bkBgSS7z!Y4*?DBovd&kIz`f&FT z)o7ejdb|)cjDimQEyTS6?D&nhaNs+fwTlfSd_{*XleJ{ZN)64?>xGkh4*S?6iP} z+z`)k8zFsxXeA~l9@|+2uLTXVvUG4HZ2?e^RTSmt#{$<2V))C=5acVj>S45psKBxy z#oHDXDwMU6hhNwu4Z$rfgxHv+KW|>xg~iU=5fkWCyjZ7u`&ot3P@{rV*aBmYzH7dG zPLWPyL)1*@Ta2R_ogS6bHv>R_6zc9PKi`&|Hoki|gej-2>_MJZL2s^Ro(KmHD|p9A z;y%+(w_JblHgD-BOKiUFnp-OEQXyqrQUO2Wy2^Xj`iW#$-?msbgpv9B%Sq23wy5M< zLLyoiWQGM+EW(uac?gyDSDl&!W9*x?6sog0S>Mf>SLpWAk<{Bv&aRa*;CoOjI>zaZf>8945@Yk+VR2+IQ*D}{)o4UR*s zh%W9+m7ZE~vv%jizfG;Hbm_)1k5=^A1V=vujzD@T^Ak}R+ch-9XCmDh&Jqv7fU28; z?JuL3W7VePXfl^-QwOI)%}A@vRd!oj9<$b!E4V-Pv%^7sY1sf;Xdb4da*YId6|Q4$ z==p%-*?=-2r~u^wGd8b3fr)#_6<@d4#Jxa0u@_3z*!|?xIRwz%O;-a40djfgVDW-y zhm3hSV893}fqU#)`Q2<;?|WG&lcZEHqELJc3vYMVtjmi#c~F{j2K-! zdhvDRFZn!T+3VpbT*?-bZ{~iN;;2jt@B-xY*Xy&H7hio`I{GyoRL89ABU2*bU|nz( zv3j^i;6QgX$3IL%u|HH+BtP~b=tcl75486Yc}qA)f$dDH`BHOF#^eK<=)#i zK<8k4iG_ZqKm>bd-v^R`9>8p*qNaWo32AUPBW2b=`JJp*6sqMxg_%&Z`PHW_<5%Nq zxjCu@Z#0SMZjx0pKi@Wno|z7BGSMqGxtpdQ@aWN_sKLgt#zz7I0@k}LW8iQ17F3Ss z0vhLHlc5(C)tB6BIA3PgdI=c5wWkL(5wb{YY9VM7lL3LbnVA`DaCx59A&r1H2rba( z0P~3%ZWXxyOmNTL+}v`Did0G4&k+P8ZqRGcVq5J3(scc_f{;01e|-d{eE-l;HUiLW ztgHaj6>@!=#DyJ4F$QeiTg#;3sk)ijS;)(&Y!@^v(ngr7m3pkdIHXEFt{#iY(08mA zDDHS9V$Z_|(*%A31wjLu49-520vMGlkO@pfbVpr1jn`CSER~IgMNZUXMJYcOJGSc2 zlH7%aOIvw}kW~{Uw((Tra7|_z)I~FPSef(U8H(Js{L6KI%eF>~P7o5Y9xgFgXol!! z0YZ5J!tSwpFg!d=8%~nhM{w;tY^X9{Cw7adm$;xE5>C1ecZ0`54D})Fvak-bKvKGd z&@Svi5`pZtm}LiX|~{ku>zVyuT1_qIVV+0Qr4esZ&A+sL$3rWgaIkZzoRXN zLCs(dK_Lt7rq{-FZ1Z{IjnSLRH)ouUS+4k=WUA~>^4mV({H)@ za(*ASCP=P)!ttU*`g0sM%ojYH&9u$N2u_qD{A26^|HIFg$TZ06KJ{*09$wHw#+3OsSqxKsdsb)@Z%C?o^{yOG8By|aYX=O{uE01dd7 z=hgC#ZGL@rGdg1X3hzO3!+-uh<+1PD`;V7+or6QqBx!PEx75i2sL<3T0vweDo+52s zJPKh}+>`G&_Lm*9Q7v-!wqLC;l;VF=(vd2K6C8lt4UGPyAFCVl`8mm&E=(y>{Moru z%8SmGs;0gnM2FE*CtpE@3fH%@z^mN+6e{Q6o(&}W_rw3=H_samVdDLLM!?_e{2!m{ z@8Kfgj+H~!a7g1XLjxlNgMx*H1&P%w-PC_aH{~+yRtQZ8?7WZLQF@d_E-(;fT?ePO zLR~(Jo}43?lPban@E{ULNZL4reN2R=8YoA%QTs|r7DSxren<(0Q1JT=jL&MV(7YQY zrD+uz766^&K3WOn2*^ULA?@b|7njzfN2%b>?;HV7@;^aT-v9FMdyIEawdklWc?zxz zNIr-D&=@H1-_1Tcag4{}>tzt;Qce;R4W2CGJPJD>ehI?UtFU{E5Y~`mq{~)R&Y>6) z5mCayKI7HL|N7lK_C6(U%4(p;B_R^@8n`>CmSGDbSYWJs0*=rDt&7{4HIR9tghUB| z$B0c#EP(LA!hZv*Lc-M{UPt&a^PO}K{cwMd2Et)mf%u{d$XIiVP`lB=3GA^4 zf++!kuWpSXG`%;Z=aoDC`WibcWH*%J=sQI%GW*`8YFUoyQV;CFwuxSU-im-61&#+e zj(~0?;t$a)_b^*3DylMYm&d?nKFbdQ^ZWoo3ZP#B3m>CJ{X*&QV4Bq=Bv1hrbKpJC;^V@W5q^hJuiCvpMP!}{!M`!noBId_ko)l?k8?6`B8g64&s5E4zEhWA zp^9*?Qkryv&=SHQgEk@jPFsD~Y#$``W$R=Ze;M!#{w(vvA4SQ-ct;fT(5iHR7u8{x8QZDSPH32wYR8(|+2nifOE>0I_ zBfkFqhA^Z}ATfZx1r1=sA+J+3zXLKb9vB!TLI@|!1@_;BTh3{R{sFz~Y#NzX?QxuE z!y2v2*FD9ow=XuH`}d+z8kjXUH)NBa--#%2yDba ziGxFi0dl+uP}S$Y-@al0+-9f+rw22y8Zcrmj+0XKueo#wVlo|gxJ;Usu-gm;2GtdP zi-lDSHz-3>C6DG+0Rza3B*({Rf#cO)VGonree`_&1b2MxwB^< z7#eboR=lb>`=WUYLJJTt`WFHrZ5`Q%y*+EzLbuA*I&0R@XIa30tV$EeKn0QG zA2+)IzN=;>y6fp3Q3%+?+Su4U(9lQ+vYR<_b+l3yd=qf_Xbai?2iRJ`i~VnCD|Y

^N(0MgUa90pS z0*tssu|qwqM98ts=)5&WBuqmBsJOteRuA%xbD45JebRw!2fa!M14fq=@IPRc_JNUk z500Xe8FG1)lqf_?Mm|20$r3;ThO4R>pLbmVl}taV7n59lAucTfv~k}`SmUp55N#C# zX^F0a*y+sf0omCQ1c1&XM7mc5(9n=emJO+uMp5EBZ+<#dGR;GtE#lOT{10&DZewe^ z4c=z!{L-z5fF_ZfcKXS$yno~`oTvgJMK5G6i}YXcgv57H@Q4Wr2`xf@FMSL#x*?IQ z3jXPYk*dF!S2S+!1`X1b@U@|~N31e62O~s3+ zhQFZ?IdD;dN}6c(iS(TSb|2<-H=`pGbKN+Alz{j|?E89q8Kau}X2|`e0=&~Vmg&li z?0&LG|6LWye9EQm4fPogU3fBN4D2WU$Oq`^|F<`R|JhI|B>s1J$Kmh(i*jYZKx{KL z?%_s%Khd=&zwUO-G;HpJ{apZ!h}F;c(Ef#Bfn2W#w5{NK)pnPk5^QfY7uk+vv)y1z z5I6Rd!DRovx4HfxDYwdCtPE~XN*jrmYs;lC|3L=bIsXNBD7^o|2$cGb|AITlry2kD z&YX*8Lqfv}E{V)VDdaDdtE#J5O`K};kJY?sv9zq(cB+8Zc&9-}2${UP!5emeHwTno zr}@nZvHmq7q`m*aJCEc?v}!d*bKQ3qMs#0U*ytU{N~~V?{ul2^-2<2rJa%e};op0V zEgAC%q_e$ORea27feoYo&)*NZk`YwXjPBs1de7)FNA>r9rLw%K@NZdvtuZtwPQd~- zhP1f*gY~`!|DaJuyrjQDkQI;lJDDI{0<6rHe~+nzlXWIwbOq#a&)x~nJ=PS`Q;_(U~d1Kz^(2>4_0 zp_6*U$=E@{3WJ#rYK9EoK_md~2VQA>^AzRFU4o~7+wF=NQ1GR|oi#-KF0T5+$KvbX zE@O^X1GtOOc~<-h6w|5+{0cFoQO#t}o8XkNxdYa6gLEM_AhPDifelA=f8cY*(49iT zr$8G#$!P(yb&xgb|k%-)Tm8=u} z2%WedxM%?fqZ3=pjsf}z1qi!m-EQqF8x0BUE`Dnbgvjm(W^)T9;~*)u76B5);qy!! z3Es|qR;J{xc=ri_FpwgUjj)c0oPeC$@Td6!XwNx~>K;NOlo|j$I?qWQB%oC_`Q#iB zLcQPyhn@6F;0uqnNojyXiVzio$P5ysA3=vUKB|R~KLi`&!J3vs?j^*IZI*_LF%X^` zvnG%d;b`xLPs{y}yb&?vScRjNRX1!Tu8qV(RuI#TLHyGH9q>V@|8VxgZs2KMLCc+2 zSje?(TWbjW$v}|}#Qwl&S3&#{j6aN6pEbc3;2HYv%>dOgyN&b$u#?`?(Q;MxM!LFe z5Icb!|Lc)R1AEf$LJz%y`jx$Zc_ZW&w|HS}laIHuU<iij(Fe!WGm%O@vBhX#Dk1T2=-m>RH% zkT6jOimKYRujgP^^<}H21K-%4x;&qiT$oo_bkA}6 z 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 From 6c106d60d2f59b78c0631a48f944fda400e2cabb Mon Sep 17 00:00:00 2001 From: X-20A <155217226+X-20A@users.noreply.github.com> Date: Fri, 14 Jun 2024 14:16:28 +0900 Subject: [PATCH 55/86] =?UTF-8?q?=E6=95=B4=E7=90=86=20[update=20snapshots]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .env.production | 14 ++++++++++++++ .env.test | 14 ++++++++++++++ 2 files changed, 28 insertions(+) create mode 100644 .env.production create mode 100644 .env.test diff --git a/.env.production b/.env.production new file mode 100644 index 0000000000..5b0dcb0498 --- /dev/null +++ b/.env.production @@ -0,0 +1,14 @@ +VITE_APP_NAME=voicevox +VITE_DEFAULT_ENGINE_INFOS=`[ + { + "uuid": "074fc39e-678b-4c13-8916-ffca8d505d1d", + "name": "VOICEVOX Engine", + "executionEnabled": true, + "executionFilePath": "vv-engine/run.exe", + "executionArgs": [], + "host": "http://127.0.0.1:50021" + } +]` +VITE_OFFICIAL_WEBSITE_URL=https://voicevox.hiroshiba.jp/ +VITE_LATEST_UPDATE_INFOS_URL=https://raw.githubusercontent.com/VOICEVOX/voicevox_blog/master/src/data/updateInfos.json +VITE_GTM_CONTAINER_ID=GTM-DUMMY diff --git a/.env.test b/.env.test new file mode 100644 index 0000000000..dcf447f8b2 --- /dev/null +++ b/.env.test @@ -0,0 +1,14 @@ +VITE_APP_NAME=voicevox +VITE_DEFAULT_ENGINE_INFOS=`[ + { + "uuid": "074fc39e-678b-4c13-8916-ffca8d505d1d", + "name": "VOICEVOX Engine", + "executionEnabled": true, + "executionFilePath": "../voicevox_engine/run.exe", + "executionArgs": [], + "host": "http://127.0.0.1:50021" + } +]` +VITE_OFFICIAL_WEBSITE_URL=https://voicevox.hiroshiba.jp/ +VITE_LATEST_UPDATE_INFOS_URL=https://raw.githubusercontent.com/VOICEVOX/voicevox_blog/master/src/data/updateInfos.json +VITE_GTM_CONTAINER_ID=GTM-DUMMY From ca60f56254b97d4ab3af27e66528e5ae474e65e0 Mon Sep 17 00:00:00 2001 From: X-20A <155217226+X-20A@users.noreply.github.com> Date: Fri, 14 Jun 2024 14:31:08 +0900 Subject: [PATCH 56/86] =?UTF-8?q?=E6=95=B4=E7=90=86=20[update=20snapshots]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...200\343\202\244\343\202\242\343\203\255\343\202\260.spec.ts" | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git "a/tests/e2e/browser/\343\202\242\343\203\203\343\203\227\343\203\207\343\203\274\343\203\210\351\200\232\347\237\245\343\203\200\343\202\244\343\202\242\343\203\255\343\202\260.spec.ts" "b/tests/e2e/browser/\343\202\242\343\203\203\343\203\227\343\203\207\343\203\274\343\203\210\351\200\232\347\237\245\343\203\200\343\202\244\343\202\242\343\203\255\343\202\260.spec.ts" index bdd9acf4da..57b616587f 100644 --- "a/tests/e2e/browser/\343\202\242\343\203\203\343\203\227\343\203\207\343\203\274\343\203\210\351\200\232\347\237\245\343\203\200\343\202\244\343\202\242\343\203\255\343\202\260.spec.ts" +++ "b/tests/e2e/browser/\343\202\242\343\203\203\343\203\227\343\203\207\343\203\274\343\203\210\351\200\232\347\237\245\343\203\200\343\202\244\343\202\242\343\203\255\343\202\260.spec.ts" @@ -66,7 +66,7 @@ test("アップデートが通知されたりスキップしたりできる", as // 再度開くとまた表示される await page.reload(); await expect(dialog.getByText("アップデートのお知らせ")).toBeVisible({ - timeout: 20000, // 表示に時間がかかる + timeout: 40000, // 表示に時間がかかる }); // スキップすると消える From fd63cc07440bb327def6aea92040a77320d9640a Mon Sep 17 00:00:00 2001 From: X-20A <155217226+X-20A@users.noreply.github.com> Date: Fri, 14 Jun 2024 14:41:42 +0900 Subject: [PATCH 57/86] =?UTF-8?q?=E6=95=B4=E7=90=86=20[update=20snapshots]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...\200\343\202\244\343\202\242\343\203\255\343\202\260.spec.ts" | 1 + 1 file changed, 1 insertion(+) diff --git "a/tests/e2e/browser/\343\202\242\343\203\203\343\203\227\343\203\207\343\203\274\343\203\210\351\200\232\347\237\245\343\203\200\343\202\244\343\202\242\343\203\255\343\202\260.spec.ts" "b/tests/e2e/browser/\343\202\242\343\203\203\343\203\227\343\203\207\343\203\274\343\203\210\351\200\232\347\237\245\343\203\200\343\202\244\343\202\242\343\203\255\343\202\260.spec.ts" index 57b616587f..da077b23fb 100644 --- "a/tests/e2e/browser/\343\202\242\343\203\203\343\203\227\343\203\207\343\203\274\343\203\210\351\200\232\347\237\245\343\203\200\343\202\244\343\202\242\343\203\255\343\202\260.spec.ts" +++ "b/tests/e2e/browser/\343\202\242\343\203\203\343\203\227\343\203\207\343\203\274\343\203\210\351\200\232\347\237\245\343\203\200\343\202\244\343\202\242\343\203\255\343\202\260.spec.ts" @@ -8,6 +8,7 @@ import { assertNonNullable } from "@/type/utility"; // アップデート通知が出る環境にする test.beforeEach(async ({ page }) => { + dotenv.config(); console.log("アップデート通知ダイアログ 出力"); console.log(process.env.VITE_APP_VERSION); // undefined From d5a5952c593e62c3d8631e311e96b0135b3eaae9 Mon Sep 17 00:00:00 2001 From: X-20A <155217226+X-20A@users.noreply.github.com> Date: Fri, 14 Jun 2024 14:55:24 +0900 Subject: [PATCH 58/86] =?UTF-8?q?=E6=95=B4=E7=90=86=20[update=20snapshots]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...\202\244\343\202\242\343\203\255\343\202\260.spec.ts" | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git "a/tests/e2e/browser/\343\202\242\343\203\203\343\203\227\343\203\207\343\203\274\343\203\210\351\200\232\347\237\245\343\203\200\343\202\244\343\202\242\343\203\255\343\202\260.spec.ts" "b/tests/e2e/browser/\343\202\242\343\203\203\343\203\227\343\203\207\343\203\274\343\203\210\351\200\232\347\237\245\343\203\200\343\202\244\343\202\242\343\203\255\343\202\260.spec.ts" index da077b23fb..ecce36901b 100644 --- "a/tests/e2e/browser/\343\202\242\343\203\203\343\203\227\343\203\207\343\203\274\343\203\210\351\200\232\347\237\245\343\203\200\343\202\244\343\202\242\343\203\255\343\202\260.spec.ts" +++ "b/tests/e2e/browser/\343\202\242\343\203\203\343\203\227\343\203\207\343\203\274\343\203\210\351\200\232\347\237\245\343\203\200\343\202\244\343\202\242\343\203\255\343\202\260.spec.ts" @@ -9,21 +9,16 @@ import { assertNonNullable } from "@/type/utility"; // アップデート通知が出る環境にする test.beforeEach(async ({ page }) => { dotenv.config(); - console.log("アップデート通知ダイアログ 出力"); - - console.log(process.env.VITE_APP_VERSION); // undefined - console.log(process.env.npm_package_version); // 999.999.999 // 動作環境より新しいバージョン const latestVersion = semver.inc( process.env.VITE_APP_VERSION ?? process.env.npm_package_version ?? "0.0.0", "major", ); - console.log(latestVersion); // 1000.0.0 assertNonNullable(latestVersion); // アップデート情報を返すAPIのモック if (process.env.VITE_LATEST_UPDATE_INFOS_URL == undefined) { - throw new Error("VITE_LATEST_UPDATE_INFOS_URL is not defined"); // 該当しない + throw new Error("VITE_LATEST_UPDATE_INFOS_URL is not defined"); } page.route(process.env.VITE_LATEST_UPDATE_INFOS_URL, (route) => { const updateInfos: UpdateInfo[] = [ @@ -79,6 +74,6 @@ test("アップデートが通知されたりスキップしたりできる", as // 再度開いても表示されない(スキップされた) await page.reload(); - await page.waitForTimeout(5000); // エンジン読み込み待機 + await page.waitForTimeout(40000); // エンジン読み込み待機 await expect(dialog).not.toBeVisible(); }); From e207c11067dc5149d58cc1f59e125d874b588090 Mon Sep 17 00:00:00 2001 From: X-20A <155217226+X-20A@users.noreply.github.com> Date: Fri, 14 Jun 2024 15:11:23 +0900 Subject: [PATCH 59/86] =?UTF-8?q?=E6=95=B4=E7=90=86=20[update=20snapshots]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- playwright.config.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/playwright.config.ts b/playwright.config.ts index 8b0e6e768c..a62ffb2478 100644 --- a/playwright.config.ts +++ b/playwright.config.ts @@ -53,7 +53,7 @@ if (isElectron) { const config: PlaywrightTestConfig = { testDir: "./tests/e2e", /* Maximum time one test can run for. */ - timeout: 60 * 1000, + timeout: 120 * 1000, expect: { /** * Maximum time expect() should wait for the condition to be met. From 2b1201dee849e0c22eefa5641c01883b0da61b47 Mon Sep 17 00:00:00 2001 From: X-20A <155217226+X-20A@users.noreply.github.com> Date: Fri, 14 Jun 2024 15:53:13 +0900 Subject: [PATCH 60/86] =?UTF-8?q?=E6=95=B4=E7=90=86=20[update=20snapshots]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/test.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index d67197da5d..a0f1d8d9ae 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -8,8 +8,8 @@ on: workflow_dispatch: env: - VOICEVOX_ENGINE_REPO: "VOICEVOX/voicevox_engine" # 軽いのでNemoを使う - VOICEVOX_ENGINE_VERSION: "0.19.1" + VOICEVOX_ENGINE_REPO: "VOICEVOX/voicevox_nemo_engine" # 軽いのでNemoを使う + VOICEVOX_ENGINE_VERSION: "0.14.0" defaults: run: From 2d209174d2e5cca651ebba7292b85e4fc67ddae0 Mon Sep 17 00:00:00 2001 From: X-20A <155217226+X-20A@users.noreply.github.com> Date: Sat, 15 Jun 2024 03:43:24 +0900 Subject: [PATCH 61/86] =?UTF-8?q?UI=E3=82=92=E5=A4=89=E6=9B=B4=20[update?= =?UTF-8?q?=20snapshots]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .env.production | 14 -------------- .env.test | 14 -------------- playwright.config.ts | 2 +- query.json | 0 ...44\343\202\242\343\203\255\343\202\260.spec.ts" | 5 +++-- 5 files changed, 4 insertions(+), 31 deletions(-) delete mode 100644 .env.production delete mode 100644 .env.test create mode 100644 query.json diff --git a/.env.production b/.env.production deleted file mode 100644 index 5b0dcb0498..0000000000 --- a/.env.production +++ /dev/null @@ -1,14 +0,0 @@ -VITE_APP_NAME=voicevox -VITE_DEFAULT_ENGINE_INFOS=`[ - { - "uuid": "074fc39e-678b-4c13-8916-ffca8d505d1d", - "name": "VOICEVOX Engine", - "executionEnabled": true, - "executionFilePath": "vv-engine/run.exe", - "executionArgs": [], - "host": "http://127.0.0.1:50021" - } -]` -VITE_OFFICIAL_WEBSITE_URL=https://voicevox.hiroshiba.jp/ -VITE_LATEST_UPDATE_INFOS_URL=https://raw.githubusercontent.com/VOICEVOX/voicevox_blog/master/src/data/updateInfos.json -VITE_GTM_CONTAINER_ID=GTM-DUMMY diff --git a/.env.test b/.env.test deleted file mode 100644 index dcf447f8b2..0000000000 --- a/.env.test +++ /dev/null @@ -1,14 +0,0 @@ -VITE_APP_NAME=voicevox -VITE_DEFAULT_ENGINE_INFOS=`[ - { - "uuid": "074fc39e-678b-4c13-8916-ffca8d505d1d", - "name": "VOICEVOX Engine", - "executionEnabled": true, - "executionFilePath": "../voicevox_engine/run.exe", - "executionArgs": [], - "host": "http://127.0.0.1:50021" - } -]` -VITE_OFFICIAL_WEBSITE_URL=https://voicevox.hiroshiba.jp/ -VITE_LATEST_UPDATE_INFOS_URL=https://raw.githubusercontent.com/VOICEVOX/voicevox_blog/master/src/data/updateInfos.json -VITE_GTM_CONTAINER_ID=GTM-DUMMY diff --git a/playwright.config.ts b/playwright.config.ts index a62ffb2478..8b0e6e768c 100644 --- a/playwright.config.ts +++ b/playwright.config.ts @@ -53,7 +53,7 @@ if (isElectron) { const config: PlaywrightTestConfig = { testDir: "./tests/e2e", /* Maximum time one test can run for. */ - timeout: 120 * 1000, + timeout: 60 * 1000, expect: { /** * Maximum time expect() should wait for the condition to be met. diff --git a/query.json b/query.json new file mode 100644 index 0000000000..e69de29bb2 diff --git "a/tests/e2e/browser/\343\202\242\343\203\203\343\203\227\343\203\207\343\203\274\343\203\210\351\200\232\347\237\245\343\203\200\343\202\244\343\202\242\343\203\255\343\202\260.spec.ts" "b/tests/e2e/browser/\343\202\242\343\203\203\343\203\227\343\203\207\343\203\274\343\203\210\351\200\232\347\237\245\343\203\200\343\202\244\343\202\242\343\203\255\343\202\260.spec.ts" index ecce36901b..e6aec6518b 100644 --- "a/tests/e2e/browser/\343\202\242\343\203\203\343\203\227\343\203\207\343\203\274\343\203\210\351\200\232\347\237\245\343\203\200\343\202\244\343\202\242\343\203\255\343\202\260.spec.ts" +++ "b/tests/e2e/browser/\343\202\242\343\203\203\343\203\227\343\203\207\343\203\274\343\203\210\351\200\232\347\237\245\343\203\200\343\202\244\343\202\242\343\203\255\343\202\260.spec.ts" @@ -9,6 +9,7 @@ import { assertNonNullable } from "@/type/utility"; // アップデート通知が出る環境にする test.beforeEach(async ({ page }) => { dotenv.config(); + // 動作環境より新しいバージョン const latestVersion = semver.inc( process.env.VITE_APP_VERSION ?? process.env.npm_package_version ?? "0.0.0", @@ -62,7 +63,7 @@ test("アップデートが通知されたりスキップしたりできる", as // 再度開くとまた表示される await page.reload(); await expect(dialog.getByText("アップデートのお知らせ")).toBeVisible({ - timeout: 40000, // 表示に時間がかかる + timeout: 10000, // 表示に時間がかかる }); // スキップすると消える @@ -74,6 +75,6 @@ test("アップデートが通知されたりスキップしたりできる", as // 再度開いても表示されない(スキップされた) await page.reload(); - await page.waitForTimeout(40000); // エンジン読み込み待機 + await page.waitForTimeout(5000); // エンジン読み込み待機 await expect(dialog).not.toBeVisible(); }); From e57687b61f507bc89a56d8c6bfe667db1bf0720a Mon Sep 17 00:00:00 2001 From: X-20A <155217226+X-20A@users.noreply.github.com> Date: Sat, 15 Jun 2024 03:43:46 +0900 Subject: [PATCH 62/86] =?UTF-8?q?UI=E3=82=92=E5=A4=89=E6=9B=B4=20[update?= =?UTF-8?q?=20snapshots]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .env.production | 14 ++++++++++++++ .env.test | 14 ++++++++++++++ 2 files changed, 28 insertions(+) create mode 100644 .env.production create mode 100644 .env.test diff --git a/.env.production b/.env.production new file mode 100644 index 0000000000..5b0dcb0498 --- /dev/null +++ b/.env.production @@ -0,0 +1,14 @@ +VITE_APP_NAME=voicevox +VITE_DEFAULT_ENGINE_INFOS=`[ + { + "uuid": "074fc39e-678b-4c13-8916-ffca8d505d1d", + "name": "VOICEVOX Engine", + "executionEnabled": true, + "executionFilePath": "vv-engine/run.exe", + "executionArgs": [], + "host": "http://127.0.0.1:50021" + } +]` +VITE_OFFICIAL_WEBSITE_URL=https://voicevox.hiroshiba.jp/ +VITE_LATEST_UPDATE_INFOS_URL=https://raw.githubusercontent.com/VOICEVOX/voicevox_blog/master/src/data/updateInfos.json +VITE_GTM_CONTAINER_ID=GTM-DUMMY diff --git a/.env.test b/.env.test new file mode 100644 index 0000000000..dcf447f8b2 --- /dev/null +++ b/.env.test @@ -0,0 +1,14 @@ +VITE_APP_NAME=voicevox +VITE_DEFAULT_ENGINE_INFOS=`[ + { + "uuid": "074fc39e-678b-4c13-8916-ffca8d505d1d", + "name": "VOICEVOX Engine", + "executionEnabled": true, + "executionFilePath": "../voicevox_engine/run.exe", + "executionArgs": [], + "host": "http://127.0.0.1:50021" + } +]` +VITE_OFFICIAL_WEBSITE_URL=https://voicevox.hiroshiba.jp/ +VITE_LATEST_UPDATE_INFOS_URL=https://raw.githubusercontent.com/VOICEVOX/voicevox_blog/master/src/data/updateInfos.json +VITE_GTM_CONTAINER_ID=GTM-DUMMY From 52dda5aa9c1f33130cd5fab40d4fde61cdfc9301 Mon Sep 17 00:00:00 2001 From: X-20A <155217226+X-20A@users.noreply.github.com> Date: Sat, 15 Jun 2024 03:47:21 +0900 Subject: [PATCH 63/86] =?UTF-8?q?UI=E3=82=92=E5=A4=89=E6=9B=B4=20[update?= =?UTF-8?q?=20snapshots]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...200\343\202\244\343\202\242\343\203\255\343\202\260.spec.ts" | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git "a/tests/e2e/browser/\343\202\242\343\203\203\343\203\227\343\203\207\343\203\274\343\203\210\351\200\232\347\237\245\343\203\200\343\202\244\343\202\242\343\203\255\343\202\260.spec.ts" "b/tests/e2e/browser/\343\202\242\343\203\203\343\203\227\343\203\207\343\203\274\343\203\210\351\200\232\347\237\245\343\203\200\343\202\244\343\202\242\343\203\255\343\202\260.spec.ts" index e6aec6518b..06cac7487e 100644 --- "a/tests/e2e/browser/\343\202\242\343\203\203\343\203\227\343\203\207\343\203\274\343\203\210\351\200\232\347\237\245\343\203\200\343\202\244\343\202\242\343\203\255\343\202\260.spec.ts" +++ "b/tests/e2e/browser/\343\202\242\343\203\203\343\203\227\343\203\207\343\203\274\343\203\210\351\200\232\347\237\245\343\203\200\343\202\244\343\202\242\343\203\255\343\202\260.spec.ts" @@ -9,7 +9,7 @@ import { assertNonNullable } from "@/type/utility"; // アップデート通知が出る環境にする test.beforeEach(async ({ page }) => { dotenv.config(); - + // 動作環境より新しいバージョン const latestVersion = semver.inc( process.env.VITE_APP_VERSION ?? process.env.npm_package_version ?? "0.0.0", From a3b6ef51a57e94f84303aea44ad49790c244990c Mon Sep 17 00:00:00 2001 From: X-20A <155217226+X-20A@users.noreply.github.com> Date: Sat, 15 Jun 2024 04:30:48 +0900 Subject: [PATCH 64/86] =?UTF-8?q?=E6=95=B4=E7=90=86=20[update=20snapshots]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- query.json | 0 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 query.json diff --git a/query.json b/query.json deleted file mode 100644 index e69de29bb2..0000000000 From 56d109ce67f4a85af07a8ab3f2b9e796c9cef849 Mon Sep 17 00:00:00 2001 From: X-20A <155217226+X-20A@users.noreply.github.com> Date: Sat, 15 Jun 2024 04:35:08 +0900 Subject: [PATCH 65/86] =?UTF-8?q?UI=E3=82=92=E5=A4=89=E6=9B=B4=20[update?= =?UTF-8?q?=20snapshots]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tests/e2e/electron/example.spec.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tests/e2e/electron/example.spec.ts b/tests/e2e/electron/example.spec.ts index 56fb7733cf..3ad83ec14a 100644 --- a/tests/e2e/electron/example.spec.ts +++ b/tests/e2e/electron/example.spec.ts @@ -49,14 +49,18 @@ test("起動したら「利用規約に関するお知らせ」が表示され VITE_DEV_SERVER_URL: "http://localhost:7357", }, }); + console.log("check1"); const sut = await app.firstWindow({ timeout: process.env.CI ? 60000 : 30000, }); + console.log("check2"); // エンジンが起動し「利用規約に関するお知らせ」が表示されるのを待つ await sut.waitForSelector("text=利用規約に関するお知らせ", { timeout: 60000, }); + console.log("check3"); await app.close(); + console.log("check4"); }); From cb963d4b09ab5265e727998a1297456ed5aaa043 Mon Sep 17 00:00:00 2001 From: X-20A <155217226+X-20A@users.noreply.github.com> Date: Sat, 15 Jun 2024 05:10:58 +0900 Subject: [PATCH 66/86] =?UTF-8?q?UI=E3=82=92=E5=A4=89=E6=9B=B4=20[update?= =?UTF-8?q?=20snapshots]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .env.production | 14 ---------- .env.test | 14 ---------- src/components/Dialog/SettingDialog.vue | 37 +++++++++++++++---------- src/components/Talk/AudioInfo.vue | 1 + src/store/audio.ts | 1 + 5 files changed, 24 insertions(+), 43 deletions(-) delete mode 100644 .env.production delete mode 100644 .env.test diff --git a/.env.production b/.env.production deleted file mode 100644 index 5b0dcb0498..0000000000 --- a/.env.production +++ /dev/null @@ -1,14 +0,0 @@ -VITE_APP_NAME=voicevox -VITE_DEFAULT_ENGINE_INFOS=`[ - { - "uuid": "074fc39e-678b-4c13-8916-ffca8d505d1d", - "name": "VOICEVOX Engine", - "executionEnabled": true, - "executionFilePath": "vv-engine/run.exe", - "executionArgs": [], - "host": "http://127.0.0.1:50021" - } -]` -VITE_OFFICIAL_WEBSITE_URL=https://voicevox.hiroshiba.jp/ -VITE_LATEST_UPDATE_INFOS_URL=https://raw.githubusercontent.com/VOICEVOX/voicevox_blog/master/src/data/updateInfos.json -VITE_GTM_CONTAINER_ID=GTM-DUMMY diff --git a/.env.test b/.env.test deleted file mode 100644 index dcf447f8b2..0000000000 --- a/.env.test +++ /dev/null @@ -1,14 +0,0 @@ -VITE_APP_NAME=voicevox -VITE_DEFAULT_ENGINE_INFOS=`[ - { - "uuid": "074fc39e-678b-4c13-8916-ffca8d505d1d", - "name": "VOICEVOX Engine", - "executionEnabled": true, - "executionFilePath": "../voicevox_engine/run.exe", - "executionArgs": [], - "host": "http://127.0.0.1:50021" - } -]` -VITE_OFFICIAL_WEBSITE_URL=https://voicevox.hiroshiba.jp/ -VITE_LATEST_UPDATE_INFOS_URL=https://raw.githubusercontent.com/VOICEVOX/voicevox_blog/master/src/data/updateInfos.json -VITE_GTM_CONTAINER_ID=GTM-DUMMY diff --git a/src/components/Dialog/SettingDialog.vue b/src/components/Dialog/SettingDialog.vue index 26bb135007..771a569310 100644 --- a/src/components/Dialog/SettingDialog.vue +++ b/src/components/Dialog/SettingDialog.vue @@ -1124,23 +1124,30 @@ const pauseLengthMode = computed({ }, }); +// 読込時の1回は除外しないと設定を操作した判定になって何もしなくても終了時にダイアログが出てしまう +// 何か他にスマートな方法があればいいけど +let isFirst: boolean = true; + watchEffect(() => { + if (isFirst) { + isFirst = false; + return; + } const audioKeys = store.state.audioKeys; - if (audioKeys.length > 0) { - if (pauseLengthMode.value === "ABSOLUTE") { - // a.設定で絶対値モードに変更し、query.pauseLengthにnull以外の値が入っているとき - // 適用範囲: 全てのaudioItem - // COMMAND_MULTI_SET_AUDIO_PAUSE_LENGTHから呼び出し - store.dispatch("COMMAND_MULTI_SET_AUDIO_PAUSE_LENGTH", { - audioKeys: audioKeys, - pauseLength: 0.3, - }); - } else { - store.dispatch("COMMAND_MULTI_SET_AUDIO_PAUSE_LENGTH_SCALE", { - audioKeys: audioKeys, - pauseLengthScale: 1, - }); - } + if (pauseLengthMode.value === "ABSOLUTE") { + console.log("watchEffect"); + // a.設定で絶対値モードに変更し、query.pauseLengthにnull以外の値が入っているとき + // 適用範囲: 全てのaudioItem + // COMMAND_MULTI_SET_AUDIO_PAUSE_LENGTHから呼び出し + store.dispatch("COMMAND_MULTI_SET_AUDIO_PAUSE_LENGTH", { + audioKeys: audioKeys, + pauseLength: 0.3, + }); + } else { + store.dispatch("COMMAND_MULTI_SET_AUDIO_PAUSE_LENGTH_SCALE", { + audioKeys: audioKeys, + pauseLengthScale: 1, + }); } }); diff --git a/src/components/Talk/AudioInfo.vue b/src/components/Talk/AudioInfo.vue index 40166e063c..9eaf5ad2a9 100644 --- a/src/components/Talk/AudioInfo.vue +++ b/src/components/Talk/AudioInfo.vue @@ -439,6 +439,7 @@ const parameters = computed(() => [ key: "volumeScale", }, // 条件に基づくパラメータの追加 + // b.query.pauseLengthにnull以外の値を代入したとき pauseLengthMode.value === "SCALE" ? { label: "文内無音倍率", diff --git a/src/store/audio.ts b/src/store/audio.ts index 41066bb3ff..ea5f1d498d 100644 --- a/src/store/audio.ts +++ b/src/store/audio.ts @@ -2811,6 +2811,7 @@ export const audioCommandStore = transformCommandStore( { commit, dispatch }, payload: { audioKeys: AudioKey[]; pauseLength: number }, ) { + console.log("COMMAND_MULTI_SET_AUDIO_PAUSE_LENGTH"); commit("COMMAND_MULTI_SET_AUDIO_PAUSE_LENGTH", payload); dispatch("COMMAND_MULTI_APPLY_PAUSE_LENGTH", { audioKeys: payload.audioKeys, From cb5f6c610fec5fb00068e8c90e0a5cbce0da21c2 Mon Sep 17 00:00:00 2001 From: X-20A <155217226+X-20A@users.noreply.github.com> Date: Sat, 15 Jun 2024 05:13:11 +0900 Subject: [PATCH 67/86] =?UTF-8?q?UI=E3=82=92=E5=A4=89=E6=9B=B4=20[update?= =?UTF-8?q?=20snapshots]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .env.production | 14 ++++++++++++++ .env.test | 14 ++++++++++++++ 2 files changed, 28 insertions(+) create mode 100644 .env.production create mode 100644 .env.test diff --git a/.env.production b/.env.production new file mode 100644 index 0000000000..5b0dcb0498 --- /dev/null +++ b/.env.production @@ -0,0 +1,14 @@ +VITE_APP_NAME=voicevox +VITE_DEFAULT_ENGINE_INFOS=`[ + { + "uuid": "074fc39e-678b-4c13-8916-ffca8d505d1d", + "name": "VOICEVOX Engine", + "executionEnabled": true, + "executionFilePath": "vv-engine/run.exe", + "executionArgs": [], + "host": "http://127.0.0.1:50021" + } +]` +VITE_OFFICIAL_WEBSITE_URL=https://voicevox.hiroshiba.jp/ +VITE_LATEST_UPDATE_INFOS_URL=https://raw.githubusercontent.com/VOICEVOX/voicevox_blog/master/src/data/updateInfos.json +VITE_GTM_CONTAINER_ID=GTM-DUMMY diff --git a/.env.test b/.env.test new file mode 100644 index 0000000000..dcf447f8b2 --- /dev/null +++ b/.env.test @@ -0,0 +1,14 @@ +VITE_APP_NAME=voicevox +VITE_DEFAULT_ENGINE_INFOS=`[ + { + "uuid": "074fc39e-678b-4c13-8916-ffca8d505d1d", + "name": "VOICEVOX Engine", + "executionEnabled": true, + "executionFilePath": "../voicevox_engine/run.exe", + "executionArgs": [], + "host": "http://127.0.0.1:50021" + } +]` +VITE_OFFICIAL_WEBSITE_URL=https://voicevox.hiroshiba.jp/ +VITE_LATEST_UPDATE_INFOS_URL=https://raw.githubusercontent.com/VOICEVOX/voicevox_blog/master/src/data/updateInfos.json +VITE_GTM_CONTAINER_ID=GTM-DUMMY From 10c7a3c588088bf69e5cfbc7c0945cf263f951e2 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Fri, 14 Jun 2024 20:22:10 +0000 Subject: [PATCH 68/86] =?UTF-8?q?=EF=BC=88=E3=82=B9=E3=83=8A=E3=83=83?= =?UTF-8?q?=E3=83=97=E3=82=B7=E3=83=A7=E3=83=83=E3=83=88=E3=82=92=E6=9B=B4?= =?UTF-8?q?=E6=96=B0=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...347\224\273\351\235\242-browser-win32.png" | Bin 55238 -> 54221 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git "a/tests/e2e/browser/\343\202\271\343\202\257\343\203\252\343\203\274\343\203\263\343\202\267\343\203\247\343\203\203\343\203\210.spec.ts-snapshots/\343\203\241\343\202\244\343\203\263\347\224\273\351\235\242-browser-win32.png" "b/tests/e2e/browser/\343\202\271\343\202\257\343\203\252\343\203\274\343\203\263\343\202\267\343\203\247\343\203\203\343\203\210.spec.ts-snapshots/\343\203\241\343\202\244\343\203\263\347\224\273\351\235\242-browser-win32.png" index 09781ae4ee7326a2f7e85907c6e1fd51dfba301d..25cf9f11cca1c7162efb29ca6637e98a6b70db27 100644 GIT binary patch literal 54221 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

^N(0MgUa90pS z0*tssu|qwqM98ts=)5&WBuqmBsJOteRuA%xbD45JebRw!2fa!M14fq=@IPRc_JNUk z500Xe8FG1)lqf_?Mm|20$r3;ThO4R>pLbmVl}taV7n59lAucTfv~k}`SmUp55N#C# zX^F0a*y+sf0omCQ1c1&XM7mc5(9n=emJO+uMp5EBZ+<#dGR;GtE#lOT{10&DZewe^ z4c=z!{L-z5fF_ZfcKXS$yno~`oTvgJMK5G6i}YXcgv57H@Q4Wr2`xf@FMSL#x*?IQ z3jXPYk*dF!S2S+!1`X1b@U@|~N31e62O~s3+ zhQFZ?IdD;dN}6c(iS(TSb|2<-H=`pGbKN+Alz{j|?E89q8Kau}X2|`e0=&~Vmg&li z?0&LG|6LWye9EQm4fPogU3fBN4D2WU$Oq`^|F<`R|JhI|B>s1J$Kmh(i*jYZKx{KL z?%_s%Khd=&zwUO-G;HpJ{apZ!h}F;c(Ef#Bfn2W#w5{NK)pnPk5^QfY7uk+vv)y1z z5I6Rd!DRovx4HfxDYwdCtPE~XN*jrmYs;lC|3L=bIsXNBD7^o|2$cGb|AITlry2kD z&YX*8Lqfv}E{V)VDdaDdtE#J5O`K};kJY?sv9zq(cB+8Zc&9-}2${UP!5emeHwTno zr}@nZvHmq7q`m*aJCEc?v}!d*bKQ3qMs#0U*ytU{N~~V?{ul2^-2<2rJa%e};op0V zEgAC%q_e$ORea27feoYo&)*NZk`YwXjPBs1de7)FNA>r9rLw%K@NZdvtuZtwPQd~- zhP1f*gY~`!|DaJuyrjQDkQI;lJDDI{0<6rHe~+nzlXWIwbOq#a&)x~nJ=PS`Q;_(U~d1Kz^(2>4_0 zp_6*U$=E@{3WJ#rYK9EoK_md~2VQA>^AzRFU4o~7+wF=NQ1GR|oi#-KF0T5+$KvbX zE@O^X1GtOOc~<-h6w|5+{0cFoQO#t}o8XkNxdYa6gLEM_AhPDifelA=f8cY*(49iT zr$8G#$!P(yb&xgb|k%-)Tm8=u} z2%WedxM%?fqZ3=pjsf}z1qi!m-EQqF8x0BUE`Dnbgvjm(W^)T9;~*)u76B5);qy!! z3Es|qR;J{xc=ri_FpwgUjj)c0oPeC$@Td6!XwNx~>K;NOlo|j$I?qWQB%oC_`Q#iB zLcQPyhn@6F;0uqnNojyXiVzio$P5ysA3=vUKB|R~KLi`&!J3vs?j^*IZI*_LF%X^` zvnG%d;b`xLPs{y}yb&?vScRjNRX1!Tu8qV(RuI#TLHyGH9q>V@|8VxgZs2KMLCc+2 zSje?(TWbjW$v}|}#Qwl&S3&#{j6aN6pEbc3;2HYv%>dOgyN&b$u#?`?(Q;MxM!LFe z5Icb!|Lc)R1AEf$LJz%y`jx$Zc_ZW&w|HS}laIHuU<iij(Fe!WGm%O@vBhX#Dk1T2=-m>RH% zkT6jOimKYRujgP^^<}H21K-%4x;&qiT$oo_bkA}6 z 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 Date: Sat, 15 Jun 2024 05:25:14 +0900 Subject: [PATCH 69/86] =?UTF-8?q?=E7=89=87=E4=BB=98=E3=81=91=20[update=20s?= =?UTF-8?q?napshots]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/Dialog/SettingDialog.vue | 1 - src/store/audio.ts | 1 - tests/e2e/electron/example.spec.ts | 4 ---- 3 files changed, 6 deletions(-) diff --git a/src/components/Dialog/SettingDialog.vue b/src/components/Dialog/SettingDialog.vue index 771a569310..6879492327 100644 --- a/src/components/Dialog/SettingDialog.vue +++ b/src/components/Dialog/SettingDialog.vue @@ -1135,7 +1135,6 @@ watchEffect(() => { } const audioKeys = store.state.audioKeys; if (pauseLengthMode.value === "ABSOLUTE") { - console.log("watchEffect"); // a.設定で絶対値モードに変更し、query.pauseLengthにnull以外の値が入っているとき // 適用範囲: 全てのaudioItem // COMMAND_MULTI_SET_AUDIO_PAUSE_LENGTHから呼び出し diff --git a/src/store/audio.ts b/src/store/audio.ts index ea5f1d498d..41066bb3ff 100644 --- a/src/store/audio.ts +++ b/src/store/audio.ts @@ -2811,7 +2811,6 @@ export const audioCommandStore = transformCommandStore( { commit, dispatch }, payload: { audioKeys: AudioKey[]; pauseLength: number }, ) { - console.log("COMMAND_MULTI_SET_AUDIO_PAUSE_LENGTH"); commit("COMMAND_MULTI_SET_AUDIO_PAUSE_LENGTH", payload); dispatch("COMMAND_MULTI_APPLY_PAUSE_LENGTH", { audioKeys: payload.audioKeys, diff --git a/tests/e2e/electron/example.spec.ts b/tests/e2e/electron/example.spec.ts index 3ad83ec14a..56fb7733cf 100644 --- a/tests/e2e/electron/example.spec.ts +++ b/tests/e2e/electron/example.spec.ts @@ -49,18 +49,14 @@ test("起動したら「利用規約に関するお知らせ」が表示され VITE_DEV_SERVER_URL: "http://localhost:7357", }, }); - console.log("check1"); const sut = await app.firstWindow({ timeout: process.env.CI ? 60000 : 30000, }); - console.log("check2"); // エンジンが起動し「利用規約に関するお知らせ」が表示されるのを待つ await sut.waitForSelector("text=利用規約に関するお知らせ", { timeout: 60000, }); - console.log("check3"); await app.close(); - console.log("check4"); }); From 74f826a661a69da47d02867b69b6248592f67d5d Mon Sep 17 00:00:00 2001 From: X-20A <155217226+X-20A@users.noreply.github.com> Date: Sat, 15 Jun 2024 06:53:13 +0900 Subject: [PATCH 70/86] =?UTF-8?q?=E7=89=87=E4=BB=98=E3=81=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .env.production | 14 -------------- .env.test | 14 -------------- src/components/Talk/AudioCell.vue | 5 +++++ src/components/Talk/AudioInfo.vue | 2 +- src/store/audio.ts | 6 ++++++ 5 files changed, 12 insertions(+), 29 deletions(-) delete mode 100644 .env.production delete mode 100644 .env.test diff --git a/.env.production b/.env.production deleted file mode 100644 index 5b0dcb0498..0000000000 --- a/.env.production +++ /dev/null @@ -1,14 +0,0 @@ -VITE_APP_NAME=voicevox -VITE_DEFAULT_ENGINE_INFOS=`[ - { - "uuid": "074fc39e-678b-4c13-8916-ffca8d505d1d", - "name": "VOICEVOX Engine", - "executionEnabled": true, - "executionFilePath": "vv-engine/run.exe", - "executionArgs": [], - "host": "http://127.0.0.1:50021" - } -]` -VITE_OFFICIAL_WEBSITE_URL=https://voicevox.hiroshiba.jp/ -VITE_LATEST_UPDATE_INFOS_URL=https://raw.githubusercontent.com/VOICEVOX/voicevox_blog/master/src/data/updateInfos.json -VITE_GTM_CONTAINER_ID=GTM-DUMMY diff --git a/.env.test b/.env.test deleted file mode 100644 index dcf447f8b2..0000000000 --- a/.env.test +++ /dev/null @@ -1,14 +0,0 @@ -VITE_APP_NAME=voicevox -VITE_DEFAULT_ENGINE_INFOS=`[ - { - "uuid": "074fc39e-678b-4c13-8916-ffca8d505d1d", - "name": "VOICEVOX Engine", - "executionEnabled": true, - "executionFilePath": "../voicevox_engine/run.exe", - "executionArgs": [], - "host": "http://127.0.0.1:50021" - } -]` -VITE_OFFICIAL_WEBSITE_URL=https://voicevox.hiroshiba.jp/ -VITE_LATEST_UPDATE_INFOS_URL=https://raw.githubusercontent.com/VOICEVOX/voicevox_blog/master/src/data/updateInfos.json -VITE_GTM_CONTAINER_ID=GTM-DUMMY diff --git a/src/components/Talk/AudioCell.vue b/src/components/Talk/AudioCell.vue index c098ef66ec..db1f664ebe 100644 --- a/src/components/Talk/AudioCell.vue +++ b/src/components/Talk/AudioCell.vue @@ -307,8 +307,10 @@ watch( ); const pushAudioTextIfNeeded = async (event?: KeyboardEvent) => { + console.log("pushAudioTextIfNeeded"); // COMMAND_CHANGE_AUDIO_TEXTでもAccenPhrases弄ってるっぽいのでフラグをコピーして後で処理 const copy_isChangeFlag = isChangeFlag.value; + console.log(copy_isChangeFlag); if (event && event.isComposing) return; if (!willRemove.value && isChangeFlag.value && !willFocusOrBlur.value) { @@ -326,8 +328,11 @@ const pushAudioTextIfNeeded = async (event?: KeyboardEvent) => { store.state.pauseLengthMode === "ABSOLUTE" && copy_isChangeFlag === true ) { + console.log("check"); + console.log(props.audioKey); const pauseLength = store.state.audioItems[props.audioKey].query?.pauseLength; + console.log(pauseLength); if (pauseLength != null && pauseLength != undefined) { store.dispatch("COMMAND_MULTI_APPLY_PAUSE_LENGTH", { audioKeys: [props.audioKey], diff --git a/src/components/Talk/AudioInfo.vue b/src/components/Talk/AudioInfo.vue index 9eaf5ad2a9..9f2994f49a 100644 --- a/src/components/Talk/AudioInfo.vue +++ b/src/components/Talk/AudioInfo.vue @@ -463,7 +463,7 @@ const parameters = computed(() => [ : { label: "文内無音", slider: previewSliderHelper({ - modelValue: () => query.value?.pauseLength ?? null, + modelValue: () => query.value?.pauseLength ?? 0.3, disable: () => uiLocked.value, max: SLIDER_PARAMETERS.PAUSE_LENGTH.max, min: SLIDER_PARAMETERS.PAUSE_LENGTH.min, diff --git a/src/store/audio.ts b/src/store/audio.ts index 41066bb3ff..be88f61494 100644 --- a/src/store/audio.ts +++ b/src/store/audio.ts @@ -706,6 +706,12 @@ export const audioStore = createPartialStore({ ) : undefined; + // query.pauseLengthはAPIの初期値がnullなので表示の為に0.3(エディタでのデフォルト値)を設定しないといけない + // ただしこのとき、IS_EDITEDが更新されないようにしないと設定を操作していないのに閉じるときにダイアログが表示される + if (query) { + query.pauseLength = 0.3; + } + const newAudioItem: AudioItem = { text, voice }; if (query != undefined) { newAudioItem.query = query; From ada5dc42aa51f48d12b44e9241d76e84ad62190c Mon Sep 17 00:00:00 2001 From: X-20A <155217226+X-20A@users.noreply.github.com> Date: Sat, 15 Jun 2024 06:54:06 +0900 Subject: [PATCH 71/86] =?UTF-8?q?=E7=89=87=E4=BB=98=E3=81=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .env.production | 14 ++++++++++++++ .env.test | 14 ++++++++++++++ 2 files changed, 28 insertions(+) create mode 100644 .env.production create mode 100644 .env.test diff --git a/.env.production b/.env.production new file mode 100644 index 0000000000..5b0dcb0498 --- /dev/null +++ b/.env.production @@ -0,0 +1,14 @@ +VITE_APP_NAME=voicevox +VITE_DEFAULT_ENGINE_INFOS=`[ + { + "uuid": "074fc39e-678b-4c13-8916-ffca8d505d1d", + "name": "VOICEVOX Engine", + "executionEnabled": true, + "executionFilePath": "vv-engine/run.exe", + "executionArgs": [], + "host": "http://127.0.0.1:50021" + } +]` +VITE_OFFICIAL_WEBSITE_URL=https://voicevox.hiroshiba.jp/ +VITE_LATEST_UPDATE_INFOS_URL=https://raw.githubusercontent.com/VOICEVOX/voicevox_blog/master/src/data/updateInfos.json +VITE_GTM_CONTAINER_ID=GTM-DUMMY diff --git a/.env.test b/.env.test new file mode 100644 index 0000000000..dcf447f8b2 --- /dev/null +++ b/.env.test @@ -0,0 +1,14 @@ +VITE_APP_NAME=voicevox +VITE_DEFAULT_ENGINE_INFOS=`[ + { + "uuid": "074fc39e-678b-4c13-8916-ffca8d505d1d", + "name": "VOICEVOX Engine", + "executionEnabled": true, + "executionFilePath": "../voicevox_engine/run.exe", + "executionArgs": [], + "host": "http://127.0.0.1:50021" + } +]` +VITE_OFFICIAL_WEBSITE_URL=https://voicevox.hiroshiba.jp/ +VITE_LATEST_UPDATE_INFOS_URL=https://raw.githubusercontent.com/VOICEVOX/voicevox_blog/master/src/data/updateInfos.json +VITE_GTM_CONTAINER_ID=GTM-DUMMY From 84fbefafa13414db523ea371f03f4617c5ce42e2 Mon Sep 17 00:00:00 2001 From: X-20A <155217226+X-20A@users.noreply.github.com> Date: Sat, 15 Jun 2024 06:55:56 +0900 Subject: [PATCH 72/86] =?UTF-8?q?=E7=89=87=E4=BB=98=E3=81=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/Talk/AudioCell.vue | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/components/Talk/AudioCell.vue b/src/components/Talk/AudioCell.vue index db1f664ebe..c098ef66ec 100644 --- a/src/components/Talk/AudioCell.vue +++ b/src/components/Talk/AudioCell.vue @@ -307,10 +307,8 @@ watch( ); const pushAudioTextIfNeeded = async (event?: KeyboardEvent) => { - console.log("pushAudioTextIfNeeded"); // COMMAND_CHANGE_AUDIO_TEXTでもAccenPhrases弄ってるっぽいのでフラグをコピーして後で処理 const copy_isChangeFlag = isChangeFlag.value; - console.log(copy_isChangeFlag); if (event && event.isComposing) return; if (!willRemove.value && isChangeFlag.value && !willFocusOrBlur.value) { @@ -328,11 +326,8 @@ const pushAudioTextIfNeeded = async (event?: KeyboardEvent) => { store.state.pauseLengthMode === "ABSOLUTE" && copy_isChangeFlag === true ) { - console.log("check"); - console.log(props.audioKey); const pauseLength = store.state.audioItems[props.audioKey].query?.pauseLength; - console.log(pauseLength); if (pauseLength != null && pauseLength != undefined) { store.dispatch("COMMAND_MULTI_APPLY_PAUSE_LENGTH", { audioKeys: [props.audioKey], From 33bb684a44d33309573272676d83a26d9f747dcf Mon Sep 17 00:00:00 2001 From: X-20A <155217226+X-20A@users.noreply.github.com> Date: Sat, 15 Jun 2024 07:49:47 +0900 Subject: [PATCH 73/86] =?UTF-8?q?=E7=89=87=E4=BB=98=E3=81=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .env.production | 14 ------- .env.test | 14 ------- src/components/Dialog/SettingDialog.vue | 51 ++++++++++++++----------- 3 files changed, 28 insertions(+), 51 deletions(-) delete mode 100644 .env.production delete mode 100644 .env.test diff --git a/.env.production b/.env.production deleted file mode 100644 index 5b0dcb0498..0000000000 --- a/.env.production +++ /dev/null @@ -1,14 +0,0 @@ -VITE_APP_NAME=voicevox -VITE_DEFAULT_ENGINE_INFOS=`[ - { - "uuid": "074fc39e-678b-4c13-8916-ffca8d505d1d", - "name": "VOICEVOX Engine", - "executionEnabled": true, - "executionFilePath": "vv-engine/run.exe", - "executionArgs": [], - "host": "http://127.0.0.1:50021" - } -]` -VITE_OFFICIAL_WEBSITE_URL=https://voicevox.hiroshiba.jp/ -VITE_LATEST_UPDATE_INFOS_URL=https://raw.githubusercontent.com/VOICEVOX/voicevox_blog/master/src/data/updateInfos.json -VITE_GTM_CONTAINER_ID=GTM-DUMMY diff --git a/.env.test b/.env.test deleted file mode 100644 index dcf447f8b2..0000000000 --- a/.env.test +++ /dev/null @@ -1,14 +0,0 @@ -VITE_APP_NAME=voicevox -VITE_DEFAULT_ENGINE_INFOS=`[ - { - "uuid": "074fc39e-678b-4c13-8916-ffca8d505d1d", - "name": "VOICEVOX Engine", - "executionEnabled": true, - "executionFilePath": "../voicevox_engine/run.exe", - "executionArgs": [], - "host": "http://127.0.0.1:50021" - } -]` -VITE_OFFICIAL_WEBSITE_URL=https://voicevox.hiroshiba.jp/ -VITE_LATEST_UPDATE_INFOS_URL=https://raw.githubusercontent.com/VOICEVOX/voicevox_blog/master/src/data/updateInfos.json -VITE_GTM_CONTAINER_ID=GTM-DUMMY diff --git a/src/components/Dialog/SettingDialog.vue b/src/components/Dialog/SettingDialog.vue index 6879492327..87c5551cd9 100644 --- a/src/components/Dialog/SettingDialog.vue +++ b/src/components/Dialog/SettingDialog.vue @@ -1061,7 +1061,7 @@