From 579ef6e4314ee5ceb5d6a63c9a39812efff788ad Mon Sep 17 00:00:00 2001 From: Hiroshiba Date: Wed, 10 Aug 2022 19:25:56 +0900 Subject: [PATCH 01/29] =?UTF-8?q?requirements-dev=E6=9B=B4=E6=96=B0=20(#44?= =?UTF-8?q?5)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 3 ++- requirements-dev.txt | 12 +++++++++++- requirements-test.txt | 4 +++- 3 files changed, 16 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index ec340cbe2..2ddc99064 100644 --- a/README.md +++ b/README.md @@ -434,7 +434,8 @@ pip-tools を用いて依存ライブラリのバージョンを固定してい `requirements*.in`ファイルを修正後、以下のコマンドで更新できます。 ```bash -pip-compile requirements.in +# pip>=22 の場合 pip-tools がエラーになります +pip-compile requirements.in # こちらを更新する場合は下2つも更新する必要があります。 pip-compile requirements-dev.in pip-compile requirements-test.in ``` diff --git a/requirements-dev.txt b/requirements-dev.txt index 8d744799c..80256f2d4 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -16,10 +16,14 @@ atomicwrites==1.4.0 # via -r requirements-dev.in backports.entry-points-selectable==1.1.1 # via virtualenv +certifi==2022.6.15 + # via requests cffi==1.15.0 # via soundfile cfgv==3.3.1 # via pre-commit +charset-normalizer==2.1.0 + # via requests click==8.0.3 # via # pip-tools @@ -45,7 +49,9 @@ h11==0.12.0 identify==2.4.0 # via pre-commit idna==3.3 - # via anyio + # via + # anyio + # requests nodeenv==1.6.0 # via pre-commit nuitka==0.6.17.4 @@ -82,6 +88,8 @@ pyyaml==6.0 # via # -r requirements.in # pre-commit +requests==2.28.1 + # via -r requirements.in scipy==1.7.1 # via -r requirements.in six==1.16.0 @@ -103,6 +111,8 @@ tqdm==4.62.3 # via pyopenjtalk typing-extensions==3.10.0.2 # via pydantic +urllib3==1.26.11 + # via requests uvicorn==0.15.0 # via -r requirements.in virtualenv==20.10.0 diff --git a/requirements-test.txt b/requirements-test.txt index b8722a5b3..5ea4dc89e 100644 --- a/requirements-test.txt +++ b/requirements-test.txt @@ -121,7 +121,9 @@ pyyaml==6.0 regex==2021.10.23 # via black requests==2.26.0 - # via coveralls + # via + # -r requirements.in + # coveralls scipy==1.7.1 # via -r requirements.in six==1.16.0 From 210d1ff9999e2ce17e6fa0183f7facf90a09a87f Mon Sep 17 00:00:00 2001 From: Hiroshiba Date: Fri, 12 Aug 2022 01:04:55 +0900 Subject: [PATCH 02/29] =?UTF-8?q?=E3=83=A9=E3=83=99=E3=83=AB=E5=90=8D?= =?UTF-8?q?=E5=A4=89=E6=9B=B4=E3=81=AB=E8=BF=BD=E5=BE=93=20(#444)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/ISSUE_TEMPLATE/bugreport.md | 2 +- .github/ISSUE_TEMPLATE/featurerequest.md | 2 +- .github/ISSUE_TEMPLATE/question.md | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/bugreport.md b/.github/ISSUE_TEMPLATE/bugreport.md index b9e455e56..28337b5ae 100644 --- a/.github/ISSUE_TEMPLATE/bugreport.md +++ b/.github/ISSUE_TEMPLATE/bugreport.md @@ -1,7 +1,7 @@ --- name: Bug Report about: 不具合の報告 -labels: bug +labels: バグ --- ## 不具合の内容 diff --git a/.github/ISSUE_TEMPLATE/featurerequest.md b/.github/ISSUE_TEMPLATE/featurerequest.md index 1852ec38a..78a3af90c 100644 --- a/.github/ISSUE_TEMPLATE/featurerequest.md +++ b/.github/ISSUE_TEMPLATE/featurerequest.md @@ -1,7 +1,7 @@ --- name: Feature Request about: 機能要望・改善提案 -labels: enhancement +labels: 機能向上 --- ## 内容 diff --git a/.github/ISSUE_TEMPLATE/question.md b/.github/ISSUE_TEMPLATE/question.md index dfc3c49bf..856a031e1 100644 --- a/.github/ISSUE_TEMPLATE/question.md +++ b/.github/ISSUE_TEMPLATE/question.md @@ -1,7 +1,7 @@ --- name: Question about: 質問 (既存のIssueや一般事例を良く調べてからしてください) -labels: question +labels: 要議論 --- ## 質問の内容 From 0adf91d2283e251d3517e08bc97c3b114df07673 Mon Sep 17 00:00:00 2001 From: Hiroshiba Date: Fri, 12 Aug 2022 01:08:01 +0900 Subject: [PATCH 03/29] to 0.13.0 --- .github/workflows/build-docker.yml | 4 ++-- .github/workflows/build.yml | 4 ++-- Dockerfile | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/build-docker.yml b/.github/workflows/build-docker.yml index 308f30598..309a914e1 100644 --- a/.github/workflows/build-docker.yml +++ b/.github/workflows/build-docker.yml @@ -11,8 +11,8 @@ on: env: IMAGE_NAME: ${{ secrets.DOCKERHUB_USERNAME }}/voicevox_engine PYTHON_VERSION: "3.8.10" - VOICEVOX_RESOURCE_VERSION: "0.13.0-preview.3" - VOICEVOX_CORE_VERSION: "0.12.5" + VOICEVOX_RESOURCE_VERSION: "0.13.0" + VOICEVOX_CORE_VERSION: "0.13.0" VOICEVOX_ENGINE_VERSION: |- # releaseのときはタグが、それ以外はlatestがバージョン名に ${{ github.event.release.tag_name != '' && github.event.release.tag_name || 'latest' }} diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index a1cac06e2..45ca17af2 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -22,8 +22,8 @@ on: env: IMAGE_NAME: ${{ secrets.DOCKERHUB_USERNAME }}/voicevox_engine PYTHON_VERSION: "3.8.10" - VOICEVOX_RESOURCE_VERSION: "0.13.0-preview.3" - VOICEVOX_CORE_VERSION: "0.12.5" + VOICEVOX_RESOURCE_VERSION: "0.13.0" + VOICEVOX_CORE_VERSION: "0.13.0" VOICEVOX_ENGINE_VERSION: |- # releaseタグ名か、workflow_dispatchでのバージョン名か、latestが入る ${{ github.event.release.tag_name || github.event.inputs.version || 'latest' }} diff --git a/Dockerfile b/Dockerfile index 793ef83de..305aeeb15 100644 --- a/Dockerfile +++ b/Dockerfile @@ -22,7 +22,7 @@ EOF # assert VOICEVOX_CORE_VERSION >= 0.11.0 (ONNX) ARG VOICEVOX_CORE_ASSET_PREFIX=voicevox_core-linux-x64-cpu -ARG VOICEVOX_CORE_VERSION=0.12.5 +ARG VOICEVOX_CORE_VERSION=0.13.0 RUN < Date: Fri, 12 Aug 2022 01:19:16 +0900 Subject: [PATCH 04/29] =?UTF-8?q?docker=E3=83=93=E3=83=AB=E3=83=89?= =?UTF-8?q?=E3=81=AEactions=E3=82=92workflow=5Fdispatch=E7=B5=8C=E7=94=B1?= =?UTF-8?q?=E3=81=A7=E5=AE=9F=E8=A1=8C=E5=8F=AF=E8=83=BD=E3=81=AB=E3=81=99?= =?UTF-8?q?=E3=82=8B=20(#447)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/build-docker.yml | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build-docker.yml b/.github/workflows/build-docker.yml index 309a914e1..e759483bb 100644 --- a/.github/workflows/build-docker.yml +++ b/.github/workflows/build-docker.yml @@ -7,6 +7,10 @@ on: types: - created workflow_dispatch: + inputs: + version: + description: "バージョン情報(A.BB.C / A.BB.C-preview.D)" + required: true env: IMAGE_NAME: ${{ secrets.DOCKERHUB_USERNAME }}/voicevox_engine @@ -14,8 +18,8 @@ env: VOICEVOX_RESOURCE_VERSION: "0.13.0" VOICEVOX_CORE_VERSION: "0.13.0" VOICEVOX_ENGINE_VERSION: - |- # releaseのときはタグが、それ以外はlatestがバージョン名に - ${{ github.event.release.tag_name != '' && github.event.release.tag_name || 'latest' }} + |- # releaseタグ名か、workflow_dispatchでのバージョン名か、latestが入る + ${{ github.event.release.tag_name || github.event.inputs.version || 'latest' }} jobs: build-docker: From 8431ed345c9f583a50090c943e7d7571aeeb08d4 Mon Sep 17 00:00:00 2001 From: Hiroshiba Date: Fri, 12 Aug 2022 02:31:08 +0900 Subject: [PATCH 05/29] =?UTF-8?q?prerelease=E3=81=AE=E8=AA=A4=E6=A4=8D?= =?UTF-8?q?=E4=BF=AE=E6=AD=A3=20(#448)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * prereleaseフラグを修正 * 誤字だった --- .github/workflows/build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 45ca17af2..1fc3fbebb 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -831,7 +831,7 @@ jobs: with: repo_token: ${{ secrets.GITHUB_TOKEN }} tag: ${{ env.VOICEVOX_ENGINE_VERSION }} - prelease: ${{ github.event.inputs.prerelease }} + prerelease: ${{ github.event.inputs.prerelease }} file_glob: true file: ${{ matrix.artifact_name }}.7z.* From 948288ecc7291b13810266d52fae9e3dcc215c2b Mon Sep 17 00:00:00 2001 From: Hiroshiba Date: Thu, 18 Aug 2022 18:25:22 +0900 Subject: [PATCH 06/29] =?UTF-8?q?=E3=83=80=E3=82=A6=E3=83=B3=E3=83=AD?= =?UTF-8?q?=E3=83=BC=E3=83=89=E3=81=AB=E9=96=A2=E3=81=99=E3=82=8B=E3=83=89?= =?UTF-8?q?=E3=82=AD=E3=83=A5=E3=83=A1=E3=83=B3=E3=83=88=E3=82=92=E8=BF=BD?= =?UTF-8?q?=E5=8A=A0=20(#451)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/README.md b/README.md index 2ddc99064..9d5a9821f 100644 --- a/README.md +++ b/README.md @@ -16,6 +16,10 @@ コアは [VOICEVOX CORE](https://github.com/VOICEVOX/voicevox_core/) 、 全体構成は [こちら](https://github.com/VOICEVOX/voicevox/blob/main/docs/%E5%85%A8%E4%BD%93%E6%A7%8B%E6%88%90.md) に詳細があります。) +## ダウンロード + +[こちら](https://github.com/VOICEVOX/voicevox_engine/releases/latest)から対応するエンジンをダウンロードしてください。 + ## API ドキュメント [API ドキュメント](https://voicevox.github.io/voicevox_engine/api/)をご参照ください。 @@ -263,6 +267,10 @@ curl -s -X GET "localhost:50021/speaker_info?speaker_uuid=7ffcb7ce-00ec-4bdc-82c この API は実験的機能であり、エンジン起動時に引数で`--enable_cancellable_synthesis`を指定しないと有効化されません。 音声合成に必要なパラメータは`/synthesis`と同様です。 +## アップデート + +エンジンディレクトリ内にあるファイルを全て消去し、新しいものに置き換えてください。 + ## Docker イメージ ### CPU From 9ae873cc53d9a1ad8df64326291bd59c3dc89416 Mon Sep 17 00:00:00 2001 From: Hiroshiba Date: Tue, 30 Aug 2022 02:18:54 +0900 Subject: [PATCH 07/29] =?UTF-8?q?=E9=81=8E=E5=8E=BB=E3=83=90=E3=83=BC?= =?UTF-8?q?=E3=82=B8=E3=83=A7=E3=83=B3=E3=82=92=E8=AA=AD=E3=81=BF=E8=BE=BC?= =?UTF-8?q?=E3=82=80=E3=83=A6=E3=83=BC=E3=82=B6=E3=83=BC=E3=83=87=E3=82=A3?= =?UTF-8?q?=E3=83=AC=E3=82=AF=E3=83=88=E3=83=AA=E3=82=92=E4=BD=9C=E3=82=8B?= =?UTF-8?q?=20(#458)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * 過去バージョンを読み込むユーザーディレクトリを作る * fix flake8 * importまとめ --- .../make_synthesis_engines.py | 77 ++++++++++++------- voicevox_engine/user_dict.py | 6 +- voicevox_engine/utility/__init__.py | 3 +- .../{engine_root.py => path_utility.py} | 9 +++ 4 files changed, 62 insertions(+), 33 deletions(-) rename voicevox_engine/utility/{engine_root.py => path_utility.py} (57%) diff --git a/voicevox_engine/synthesis_engine/make_synthesis_engines.py b/voicevox_engine/synthesis_engine/make_synthesis_engines.py index 7c23172a2..425d52fc2 100644 --- a/voicevox_engine/synthesis_engine/make_synthesis_engines.py +++ b/voicevox_engine/synthesis_engine/make_synthesis_engines.py @@ -1,10 +1,9 @@ import json import sys -import traceback from pathlib import Path from typing import Dict, List, Optional -from ..utility import engine_root +from ..utility import engine_root, get_save_dir from .core_wrapper import CoreWrapper, load_runtime_lib from .synthesis_engine import SynthesisEngine, SynthesisEngineBase @@ -68,34 +67,56 @@ def make_synthesis_engines( runtime_dirs = [p.expanduser() for p in runtime_dirs] load_runtime_lib(runtime_dirs) + synthesis_engines = {} - for core_dir in voicelib_dirs: - try: - core = CoreWrapper(use_gpu, core_dir, cpu_num_threads, load_all_models) - metas = json.loads(core.metas()) - core_version = metas[0]["version"] - if core_version in synthesis_engines: - print( - "Warning: Core loading is skipped because of version duplication.", - file=sys.stderr, - ) + + if not enable_mock: + + def load_core_library(core_dir: Path, suppress_error: bool = False): + """ + 指定されたディレクトリにあるコアを読み込む。 + ユーザーディレクトリの場合は存在しないこともあるので、エラーを抑制すると良い。 + """ + try: + core = CoreWrapper(use_gpu, core_dir, cpu_num_threads, load_all_models) + metas = json.loads(core.metas()) + core_version = metas[0]["version"] + if core_version in synthesis_engines: + print( + "Warning: Core loading is skipped because of version duplication.", + file=sys.stderr, + ) + else: + synthesis_engines[core_version] = SynthesisEngine(core=core) + except Exception: + if not suppress_error: + raise + + for core_dir in voicelib_dirs: + load_core_library(core_dir) + + # ユーザーディレクトリにあるコアを読み込む + user_voicelib_dirs = [] + core_libraries_dir = get_save_dir() / "core_libraries" + core_libraries_dir.mkdir(exist_ok=True) + user_voicelib_dirs.append(core_libraries_dir) + for path in core_libraries_dir.glob("*"): + if not path.is_dir(): continue - synthesis_engines[core_version] = SynthesisEngine(core=core) - except Exception: - if not enable_mock: - raise - traceback.print_exc() - print( - "Notice: mock-library will be used. Try re-run with valid --voicevox_dir", - file=sys.stderr, + user_voicelib_dirs.append(path) + + for core_dir in user_voicelib_dirs: + load_core_library(core_dir, suppress_error=True) + + else: + # モック追加 + from ..dev.core import metas as mock_metas + from ..dev.core import supported_devices as mock_supported_devices + from ..dev.synthesis_engine import MockSynthesisEngine + + if "0.0.0" not in synthesis_engines: + synthesis_engines["0.0.0"] = MockSynthesisEngine( + speakers=mock_metas(), supported_devices=mock_supported_devices() ) - from ..dev.core import metas as mock_metas - from ..dev.core import supported_devices as mock_supported_devices - from ..dev.synthesis_engine import MockSynthesisEngine - - if "0.0.0" not in synthesis_engines: - synthesis_engines["0.0.0"] = MockSynthesisEngine( - speakers=mock_metas(), supported_devices=mock_supported_devices() - ) return synthesis_engines diff --git a/voicevox_engine/user_dict.py b/voicevox_engine/user_dict.py index 940c06f15..2a35b32b2 100644 --- a/voicevox_engine/user_dict.py +++ b/voicevox_engine/user_dict.py @@ -7,17 +7,15 @@ import numpy as np import pyopenjtalk -from appdirs import user_data_dir from fastapi import HTTPException from pydantic import conint from .model import UserDictWord, WordTypes from .part_of_speech_data import MAX_PRIORITY, MIN_PRIORITY, part_of_speech_data -from .utility import engine_root +from .utility import engine_root, get_save_dir root_dir = engine_root() -# FIXME: ファイル保存場所をエンジン固有のIDが入ったものにする -save_dir = Path(user_data_dir("voicevox-engine")) +save_dir = get_save_dir() if not save_dir.is_dir(): save_dir.mkdir(parents=True) diff --git a/voicevox_engine/utility/__init__.py b/voicevox_engine/utility/__init__.py index 0248a9d6a..bc3e71279 100644 --- a/voicevox_engine/utility/__init__.py +++ b/voicevox_engine/utility/__init__.py @@ -3,11 +3,12 @@ connect_base64_waves, decode_base64_waves, ) -from .engine_root import engine_root +from .path_utility import engine_root, get_save_dir __all__ = [ "ConnectBase64WavesException", "connect_base64_waves", "decode_base64_waves", "engine_root", + "get_save_dir", ] diff --git a/voicevox_engine/utility/engine_root.py b/voicevox_engine/utility/path_utility.py similarity index 57% rename from voicevox_engine/utility/engine_root.py rename to voicevox_engine/utility/path_utility.py index dd911610c..86582179b 100644 --- a/voicevox_engine/utility/engine_root.py +++ b/voicevox_engine/utility/path_utility.py @@ -1,6 +1,8 @@ import sys from pathlib import Path +from appdirs import user_data_dir + def engine_root() -> Path: # nuitkaビルドをした際はグローバルに__compiled__が含まれる @@ -15,3 +17,10 @@ def engine_root() -> Path: root_dir = Path(__file__).parents[2] return root_dir.resolve(strict=True) + + +def get_save_dir(): + # FIXME: ファイル保存場所をエンジン固有のIDが入ったものにする + # FIXME: Windowsは`voicevox-engine/voicevox-engine`ディレクトリに保存されているので + # `VOICEVOX/voicevox-engine`に変更する + return Path(user_data_dir("voicevox-engine")) From 33c4d1e23443f30ac5a3dc9aad998f5b4f1d266e Mon Sep 17 00:00:00 2001 From: Hiroshiba Date: Thu, 1 Sep 2022 13:33:53 +0900 Subject: [PATCH 08/29] =?UTF-8?q?=E3=83=9E=E3=83=8B=E3=83=95=E3=82=A7?= =?UTF-8?q?=E3=82=B9=E3=83=88=E3=81=AB=E8=83=BD=E5=8A=9B=E3=82=92=E8=BF=BD?= =?UTF-8?q?=E5=8A=A0=20(#456)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- engine_manifest.json | 39 ++++++++++++++++++- .../engine_manifest/EngineManifest.py | 15 +++++++ .../engine_manifest/EngineManifestLoader.py | 4 ++ 3 files changed, 57 insertions(+), 1 deletion(-) diff --git a/engine_manifest.json b/engine_manifest.json index 057bf2737..fc87ec349 100644 --- a/engine_manifest.json +++ b/engine_manifest.json @@ -12,5 +12,42 @@ "update_infos": "engine_manifest_assets/update_infos.json", "dependency_licenses": "engine_manifest_assets/dependency_licenses.json", "downloadable_libraries_path": null, - "downloadable_libraries_url": null + "downloadable_libraries_url": null, + "supported_features": { + "adjust_mora_pitch": { + "type": "bool", + "value": true, + "name": "モーラごとの音高の調整" + }, + "adjust_phoneme_length": { + "type": "bool", + "value": true, + "name": "音素ごとの長さの調整" + }, + "adjust_speed_scale": { + "type": "bool", + "value": true, + "name": "全体の話速の調整" + }, + "adjust_pitch_scale": { + "type": "bool", + "value": true, + "name": "全体の音高の調整" + }, + "adjust_intonation_scale": { + "type": "bool", + "value": true, + "name": "全体の抑揚の調整" + }, + "adjust_volume_scale": { + "type": "bool", + "value": true, + "name": "全体の音量の調整" + }, + "interrogative_upspeak": { + "type": "bool", + "value": true, + "name": "疑問文の自動調整" + } + } } diff --git a/voicevox_engine/engine_manifest/EngineManifest.py b/voicevox_engine/engine_manifest/EngineManifest.py index d6356c7f1..d49a052e8 100644 --- a/voicevox_engine/engine_manifest/EngineManifest.py +++ b/voicevox_engine/engine_manifest/EngineManifest.py @@ -24,6 +24,20 @@ class LicenseInfo(BaseModel): text: str = Field(title="依存ライブラリのライセンス本文") +class SupportedFeatures(BaseModel): + """ + エンジンが持つ機能の一覧 + """ + + adjust_mora_pitch: bool = Field(title="モーラごとの音高の調整") + adjust_phoneme_length: bool = Field(title="音素ごとの長さの調整") + adjust_speed_scale: bool = Field(title="全体の話速の調整") + adjust_pitch_scale: bool = Field(title="全体の音高の調整") + adjust_intonation_scale: bool = Field(title="全体の抑揚の調整") + adjust_volume_scale: bool = Field(title="全体の音量の調整") + interrogative_upspeak: bool = Field(title="疑問文の自動調整") + + class EngineManifest(BaseModel): """ エンジン自体に関する情報 @@ -44,3 +58,4 @@ class EngineManifest(BaseModel): downloadable_libraries_url: Optional[str] = Field( title="ダウンロード可能な音声ライブラリ情報を取得するためのAPIのURL" ) + supported_features: SupportedFeatures = Field(title="エンジンが持つ機能") diff --git a/voicevox_engine/engine_manifest/EngineManifestLoader.py b/voicevox_engine/engine_manifest/EngineManifestLoader.py index c423a4b5c..c4b8f409f 100644 --- a/voicevox_engine/engine_manifest/EngineManifestLoader.py +++ b/voicevox_engine/engine_manifest/EngineManifestLoader.py @@ -39,5 +39,9 @@ def load_manifest(self) -> EngineManifest: ], downloadable_libraries_path=manifest["downloadable_libraries_path"], downloadable_libraries_url=manifest["downloadable_libraries_url"], + supported_features={ + key: item["value"] + for key, item in manifest["supported_features"].items() + }, ) return manifest From 25b7dd35e7034ba17444881fc2543d7fbf5a9f8a Mon Sep 17 00:00:00 2001 From: Gray Suitcase <41382894+PickledChair@users.noreply.github.com> Date: Sun, 4 Sep 2022 13:27:02 +0900 Subject: [PATCH 09/29] =?UTF-8?q?synthesis=E3=81=A8=5Fsynthesis=5Fimpl?= =?UTF-8?q?=E3=83=A1=E3=82=BD=E3=83=83=E3=83=89=E3=81=AE=E6=88=BB=E3=82=8A?= =?UTF-8?q?=E5=80=A4=E3=81=AE=E5=9E=8B=E3=82=92=E4=BF=AE=E6=AD=A3=20(#461)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit synthesisと_synthesis_impl関数の戻り値の型を修正 --- voicevox_engine/synthesis_engine/synthesis_engine_base.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/voicevox_engine/synthesis_engine/synthesis_engine_base.py b/voicevox_engine/synthesis_engine/synthesis_engine_base.py index 386b8de71..4e17669db 100644 --- a/voicevox_engine/synthesis_engine/synthesis_engine_base.py +++ b/voicevox_engine/synthesis_engine/synthesis_engine_base.py @@ -2,6 +2,8 @@ from abc import ABCMeta, abstractmethod from typing import List, Optional +import numpy as np + from .. import full_context_label from ..full_context_label import extract_full_context_label from ..model import AccentPhrase, AudioQuery, Mora @@ -208,7 +210,7 @@ def synthesis( query: AudioQuery, speaker_id: int, enable_interrogative_upspeak: bool = True, - ) -> str: + ) -> np.ndarray: """ 音声合成クエリ内の疑問文指定されたMoraを変形した後、 継承先における実装`_synthesis_impl`を使い音声合成を行う @@ -234,7 +236,7 @@ def synthesis( return self._synthesis_impl(query, speaker_id) @abstractmethod - def _synthesis_impl(self, query: AudioQuery, speaker_id: int): + def _synthesis_impl(self, query: AudioQuery, speaker_id: int) -> np.ndarray: """ 音声合成クエリから音声合成に必要な情報を構成し、実際に音声合成を行う Parameters From 341a46fa93213044ba0ef43a1ea720fcd74fe451 Mon Sep 17 00:00:00 2001 From: Appletigerv <112878528+Appletigerv@users.noreply.github.com> Date: Wed, 7 Sep 2022 03:53:19 +0900 Subject: [PATCH 10/29] =?UTF-8?q?=E3=83=86=E3=83=B3=E3=83=9D=E3=83=A9?= =?UTF-8?q?=E3=83=AA=E3=83=95=E3=82=A9=E3=83=AB=E3=83=80=E3=81=8C=E3=82=B7?= =?UTF-8?q?=E3=82=B9=E3=83=86=E3=83=A0=E3=83=91=E3=83=BC=E3=83=86=E3=82=A3?= =?UTF-8?q?=E3=82=B7=E3=83=A7=E3=83=B3=E4=BB=A5=E5=A4=96=E3=81=AB=E8=A8=AD?= =?UTF-8?q?=E5=AE=9A=E3=81=95=E3=82=8C=E3=81=A6=E3=81=84=E3=82=8B=E3=81=A8?= =?UTF-8?q?=E3=80=81=E8=BE=9E=E6=9B=B8=E3=81=AE=E6=9B=B4=E6=96=B0=E3=81=8C?= =?UTF-8?q?=E5=A4=B1=E6=95=97=E3=81=99=E3=82=8B=E4=B8=8D=E5=85=B7=E5=90=88?= =?UTF-8?q?=E3=82=92=E4=BF=AE=E6=AD=A3=E3=81=97=E3=81=9F=E3=80=82(#462)=20?= =?UTF-8?q?(#464)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * 一時フォルダがシステムパーティション以外にある場合、辞書の更新に失敗する不具合を修正した。(#462) * Update voicevox_engine/user_dict.py Co-authored-by: Hiroshiba * Update voicevox_engine/user_dict.py * pysen Co-authored-by: Hiroshiba Co-authored-by: takana-v <44311840+takana-v@users.noreply.github.com> --- voicevox_engine/user_dict.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/voicevox_engine/user_dict.py b/voicevox_engine/user_dict.py index 2a35b32b2..c536a4539 100644 --- a/voicevox_engine/user_dict.py +++ b/voicevox_engine/user_dict.py @@ -1,4 +1,5 @@ import json +import shutil import sys from pathlib import Path from tempfile import NamedTemporaryFile @@ -99,7 +100,7 @@ def update_dict( raise RuntimeError("辞書のコンパイル時にエラーが発生しました。") pyopenjtalk.unset_user_dict() try: - tmp_dict_path.replace(compiled_dict_path) + shutil.move(tmp_dict_path, compiled_dict_path) # ドライブを跨ぐためPath.replaceが使えない finally: if compiled_dict_path.is_file(): pyopenjtalk.set_user_dict(str(compiled_dict_path.resolve(strict=True))) From 51ca97fff13e1f7e4acb24521ac3cb8506034a4a Mon Sep 17 00:00:00 2001 From: sabonerune <102559104+sabonerune@users.noreply.github.com> Date: Wed, 14 Sep 2022 19:58:32 +0900 Subject: [PATCH 11/29] =?UTF-8?q?ENH:=20=E9=9F=B3=E5=A3=B0=E5=90=88?= =?UTF-8?q?=E6=88=90=E6=99=82=E3=81=A8=E8=BE=9E=E6=9B=B8=E6=9B=B4=E6=96=B0?= =?UTF-8?q?=E6=99=82=E3=81=AB=E4=BD=9C=E6=88=90=E3=81=95=E3=82=8C=E3=82=8B?= =?UTF-8?q?=E4=B8=80=E6=99=82=E3=83=95=E3=82=A1=E3=82=A4=E3=83=AB=E3=82=92?= =?UTF-8?q?=E5=A7=8B=E6=9C=AB=E3=81=99=E3=82=8B=20(#470)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * ENH: 作成される一時ファイルを始末する 音声合成時に生成される一時ファイルを削除する 辞書更新時に生成される一時ファイルを削除する * MAINT: delete_file関数をutility/path_utility.pyへ移動 * MAINT: BackgroundTaskをFileResponseへ --- run.py | 32 +++++++++++++++++++++---- voicevox_engine/user_dict.py | 3 ++- voicevox_engine/utility/__init__.py | 3 ++- voicevox_engine/utility/path_utility.py | 9 +++++++ 4 files changed, 40 insertions(+), 7 deletions(-) diff --git a/run.py b/run.py index 3d2c98a26..cdeb259a5 100644 --- a/run.py +++ b/run.py @@ -22,6 +22,7 @@ from fastapi.middleware.cors import CORSMiddleware from fastapi.params import Query from pydantic import ValidationError, conint +from starlette.background import BackgroundTask from starlette.responses import FileResponse from voicevox_engine import __version__ @@ -59,6 +60,7 @@ from voicevox_engine.utility import ( ConnectBase64WavesException, connect_base64_waves, + delete_file, engine_root, ) @@ -308,7 +310,11 @@ def synthesis( file=f, data=wave, samplerate=query.outputSamplingRate, format="WAV" ) - return FileResponse(f.name, media_type="audio/wav") + return FileResponse( + f.name, + media_type="audio/wav", + background=BackgroundTask(delete_file, f.name), + ) @app.post( "/cancellable_synthesis", @@ -343,7 +349,11 @@ def cancellable_synthesis( if f_name == "": raise HTTPException(status_code=422, detail="不明なバージョンです") - return FileResponse(f_name, media_type="audio/wav") + return FileResponse( + f_name, + media_type="audio/wav", + background=BackgroundTask(delete_file, f_name), + ) @app.post( "/multi_synthesis", @@ -391,7 +401,11 @@ def multi_synthesis( wav_file.seek(0) zip_file.writestr(f"{str(i + 1).zfill(3)}.wav", wav_file.read()) - return FileResponse(f.name, media_type="application/zip") + return FileResponse( + f.name, + media_type="application/zip", + background=BackgroundTask(delete_file, f.name), + ) @app.post( "/synthesis_morphing", @@ -441,7 +455,11 @@ def _synthesis_morphing( format="WAV", ) - return FileResponse(f.name, media_type="audio/wav") + return FileResponse( + f.name, + media_type="audio/wav", + background=BackgroundTask(delete_file, f.name), + ) @app.post( "/connect_waves", @@ -473,7 +491,11 @@ def connect_waves(waves: List[str]): format="WAV", ) - return FileResponse(f.name, media_type="audio/wav") + return FileResponse( + f.name, + media_type="audio/wav", + background=BackgroundTask(delete_file, f.name), + ) @app.get("/presets", response_model=List[Preset], tags=["その他"]) def get_presets(): diff --git a/voicevox_engine/user_dict.py b/voicevox_engine/user_dict.py index c536a4539..74b73c3bd 100644 --- a/voicevox_engine/user_dict.py +++ b/voicevox_engine/user_dict.py @@ -13,7 +13,7 @@ from .model import UserDictWord, WordTypes from .part_of_speech_data import MAX_PRIORITY, MIN_PRIORITY, part_of_speech_data -from .utility import engine_root, get_save_dir +from .utility import delete_file, engine_root, get_save_dir root_dir = engine_root() save_dir = get_save_dir() @@ -96,6 +96,7 @@ def update_dict( str(Path(f.name).resolve(strict=True)), str(tmp_dict_path), ) + delete_file(f.name) if not tmp_dict_path.is_file(): raise RuntimeError("辞書のコンパイル時にエラーが発生しました。") pyopenjtalk.unset_user_dict() diff --git a/voicevox_engine/utility/__init__.py b/voicevox_engine/utility/__init__.py index bc3e71279..6b715aba7 100644 --- a/voicevox_engine/utility/__init__.py +++ b/voicevox_engine/utility/__init__.py @@ -3,12 +3,13 @@ connect_base64_waves, decode_base64_waves, ) -from .path_utility import engine_root, get_save_dir +from .path_utility import delete_file, engine_root, get_save_dir __all__ = [ "ConnectBase64WavesException", "connect_base64_waves", "decode_base64_waves", + "delete_file", "engine_root", "get_save_dir", ] diff --git a/voicevox_engine/utility/path_utility.py b/voicevox_engine/utility/path_utility.py index 86582179b..9af369d45 100644 --- a/voicevox_engine/utility/path_utility.py +++ b/voicevox_engine/utility/path_utility.py @@ -1,4 +1,6 @@ +import os import sys +import traceback from pathlib import Path from appdirs import user_data_dir @@ -24,3 +26,10 @@ def get_save_dir(): # FIXME: Windowsは`voicevox-engine/voicevox-engine`ディレクトリに保存されているので # `VOICEVOX/voicevox-engine`に変更する return Path(user_data_dir("voicevox-engine")) + + +def delete_file(file_path: str) -> None: + try: + os.remove(file_path) + except OSError: + traceback.print_exc() From 21f0fa15eea240796db5d37cd3a8f519dc14fbf1 Mon Sep 17 00:00:00 2001 From: Hiroshiba Date: Thu, 15 Sep 2022 00:04:09 +0900 Subject: [PATCH 12/29] =?UTF-8?q?code=5Fsigning=E3=81=8Ctrue=E3=81=98?= =?UTF-8?q?=E3=82=83=E3=81=AA=E3=81=84=E3=81=A8=E3=81=8D=E3=80=8Cfalse?= =?UTF-8?q?=E3=80=8Denvironment=E3=82=92=E4=BD=BF=E3=81=8A=E3=81=86?= =?UTF-8?q?=E3=81=A8=E3=81=97=E3=81=A6=E3=81=97=E3=81=BE=E3=81=86=E5=95=8F?= =?UTF-8?q?=E9=A1=8C=E3=82=92=E8=A7=A3=E6=B1=BA=20(#467)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 1fc3fbebb..332e1e0b6 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -370,7 +370,7 @@ jobs: path: build/run.dist/ build-windows: - environment: ${{ github.event.inputs.code_signing == 'true' && 'code_signing' }} # コード署名用のenvironment + environment: ${{ github.event.inputs.code_signing == 'true' && 'code_signing' || '' }} # コード署名用のenvironment strategy: matrix: include: From 52d5c3836941fbd5862bcc58522a3b8e51e275d5 Mon Sep 17 00:00:00 2001 From: Gray Suitcase <41382894+PickledChair@users.noreply.github.com> Date: Thu, 15 Sep 2022 18:29:13 +0900 Subject: [PATCH 13/29] =?UTF-8?q?=E6=96=B0=E3=81=97=E3=81=84=E3=82=B3?= =?UTF-8?q?=E3=82=A2=E3=83=A9=E3=82=A4=E3=83=96=E3=83=A9=E3=83=AA=E3=81=AE?= =?UTF-8?q?=E3=83=95=E3=82=A1=E3=82=A4=E3=83=AB=E5=90=8D=E3=81=AB=E5=AF=BE?= =?UTF-8?q?=E5=BF=9C=20(#471)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * 新しい共有ライブラリ名(voicevox_core)に対応 * 新しいコアライブラリの名前についてコメントを追加 --- .../synthesis_engine/core_wrapper.py | 42 ++++++++++++------- 1 file changed, 26 insertions(+), 16 deletions(-) diff --git a/voicevox_engine/synthesis_engine/core_wrapper.py b/voicevox_engine/synthesis_engine/core_wrapper.py index 3e1895fa5..9502c9921 100644 --- a/voicevox_engine/synthesis_engine/core_wrapper.py +++ b/voicevox_engine/synthesis_engine/core_wrapper.py @@ -197,17 +197,21 @@ class CoreInfo: ] -# version 0.12 以降のコアの名前 +# version 0.12 以降のコアの名前の辞書 +# - version 0.12, 0.13 のコアの名前: core +# - version 0.14 からのコアの名前: voicevox_core CORENAME_DICT = { - "Windows": "core.dll", - "Linux": "libcore.so", - "Darwin": "libcore.dylib", + "Windows": ("voicevox_core.dll", "core.dll"), + "Linux": ("libvoicevox_core.so", "libcore.so"), + "Darwin": ("libvoicevox_core.dylib", "libcore.dylib"), } -def is_version_0_12_core_or_later(core_dir: Path) -> bool: +def find_version_0_12_core_or_later(core_dir: Path) -> Optional[str]: """ - core_dir で指定したディレクトリにあるコアライブラリが Version 0.12 以降であるかどうかを返す。 + core_dir で指定したディレクトリにあるコアライブラリが Version 0.12 以降である場合、 + 見つかった共有ライブラリの名前を返す。 + Version 0.12 以降と判定する条件は、 - core_dir に metas.json が存在しない @@ -216,10 +220,14 @@ def is_version_0_12_core_or_later(core_dir: Path) -> bool: の両方が真のときである。 cf. https://github.com/VOICEVOX/voicevox_engine/issues/385 """ - return ( - not (core_dir / "metas.json").exists() - and (core_dir / CORENAME_DICT[platform.system()]).is_file() - ) + if (core_dir / "metas.json").exists(): + return None + + for core_name in CORENAME_DICT[platform.system()]: + if (core_dir / core_name).is_file(): + return core_name + + return None def get_arch_name() -> Optional[str]: @@ -294,13 +302,12 @@ def check_core_type(core_dir: Path) -> Optional[str]: def load_core(core_dir: Path, use_gpu: bool) -> CDLL: - if is_version_0_12_core_or_later(core_dir): + core_name = find_version_0_12_core_or_later(core_dir) + if core_name: try: # NOTE: CDLL クラスのコンストラクタの引数 name には文字列を渡す必要がある。 # Windows 環境では PathLike オブジェクトを引数として渡すと初期化に失敗する。 - return CDLL( - str((core_dir / CORENAME_DICT[platform.system()]).resolve(strict=True)) - ) + return CDLL(str((core_dir / core_name).resolve(strict=True))) except OSError as err: raise RuntimeError(f"コアの読み込みに失敗しました:{err}") @@ -361,7 +368,10 @@ def __init__( self.exist_load_model = False self.exist_is_model_loaded = False - if is_version_0_12_core_or_later(core_dir): + is_version_0_12_core_or_later = ( + find_version_0_12_core_or_later(core_dir) is not None + ) + if is_version_0_12_core_or_later: model_type = "onnxruntime" self.exist_load_model = True self.exist_is_model_loaded = True @@ -409,7 +419,7 @@ def __init__( cwd = os.getcwd() os.chdir(core_dir) try: - if is_version_0_12_core_or_later(core_dir): + if is_version_0_12_core_or_later: if not self.core.initialize(use_gpu, cpu_num_threads, load_all_models): raise Exception(self.core.last_error_message().decode("utf-8")) elif exist_cpu_num_threads: From 440b463770ac5be1e8573575ad4c1d4367a1b70c Mon Sep 17 00:00:00 2001 From: takana-v <44311840+takana-v@users.noreply.github.com> Date: Fri, 16 Sep 2022 02:42:28 +0900 Subject: [PATCH 14/29] =?UTF-8?q?pyopenjtalk=E3=81=AE=E3=83=90=E3=83=BC?= =?UTF-8?q?=E3=82=B8=E3=83=A7=E3=83=B3=E3=82=92=E6=9B=B4=E6=96=B0=20(#469)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit requirements更新 --- requirements-dev.txt | 2 +- requirements-test.txt | 2 +- requirements.in | 2 +- requirements.txt | 6 ++++-- 4 files changed, 7 insertions(+), 5 deletions(-) diff --git a/requirements-dev.txt b/requirements-dev.txt index 80256f2d4..8eac186fc 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -78,7 +78,7 @@ pycparser==2.20 # via cffi pydantic==1.8.2 # via fastapi -pyopenjtalk @ git+https://github.com/VOICEVOX/pyopenjtalk@50b0296a9e1b666e5a09a41ec9e9284a2a9b608f +pyopenjtalk @ git+https://github.com/VOICEVOX/pyopenjtalk@f4ade29ef9a4f43d8605103cb5bacc29e0b2ccae # via -r requirements.in python-multipart==0.0.5 # via -r requirements.in diff --git a/requirements-test.txt b/requirements-test.txt index 5ea4dc89e..7a0e44f31 100644 --- a/requirements-test.txt +++ b/requirements-test.txt @@ -104,7 +104,7 @@ pydantic==1.8.2 # via fastapi pyflakes==2.3.1 # via flake8 -pyopenjtalk @ git+https://github.com/VOICEVOX/pyopenjtalk@50b0296a9e1b666e5a09a41ec9e9284a2a9b608f +pyopenjtalk @ git+https://github.com/VOICEVOX/pyopenjtalk@f4ade29ef9a4f43d8605103cb5bacc29e0b2ccae # via -r requirements.in pyparsing==3.0.1 # via packaging diff --git a/requirements.in b/requirements.in index 6f447b77f..1986f8e8b 100644 --- a/requirements.in +++ b/requirements.in @@ -9,4 +9,4 @@ PyYAML pyworld appdirs requests -git+https://github.com/VOICEVOX/pyopenjtalk@50b0296a9e1b666e5a09a41ec9e9284a2a9b608f#egg=pyopenjtalk +git+https://github.com/VOICEVOX/pyopenjtalk@f4ade29ef9a4f43d8605103cb5bacc29e0b2ccae#egg=pyopenjtalk diff --git a/requirements.txt b/requirements.txt index e5c5ffb0d..1c3a0d040 100644 --- a/requirements.txt +++ b/requirements.txt @@ -33,7 +33,9 @@ fastapi==0.70.0 h11==0.12.0 # via uvicorn idna==3.3 - # via anyio + # via + # anyio + # requests numpy==1.20.0 # via # -r requirements.in @@ -44,7 +46,7 @@ pycparser==2.20 # via cffi pydantic==1.8.2 # via fastapi -pyopenjtalk @ git+https://github.com/VOICEVOX/pyopenjtalk@50b0296a9e1b666e5a09a41ec9e9284a2a9b608f +pyopenjtalk @ git+https://github.com/VOICEVOX/pyopenjtalk@f4ade29ef9a4f43d8605103cb5bacc29e0b2ccae # via -r requirements.in python-multipart==0.0.5 # via -r requirements.in From 532f4211282c11319d8a30a737b48abdbf52b0ba Mon Sep 17 00:00:00 2001 From: Gray Suitcase <41382894+PickledChair@users.noreply.github.com> Date: Fri, 16 Sep 2022 19:03:53 +0900 Subject: [PATCH 15/29] =?UTF-8?q?fix:=20=E3=82=A8=E3=83=B3=E3=82=B8?= =?UTF-8?q?=E3=83=B3=E8=B5=B7=E5=8B=95=E6=99=82=E3=81=AB=E3=83=87=E3=83=95?= =?UTF-8?q?=E3=82=A9=E3=83=AB=E3=83=88=E8=BE=9E=E6=9B=B8=E3=81=AB=E5=8A=A0?= =?UTF-8?q?=E3=81=88=E3=81=A6=E3=83=A6=E3=83=BC=E3=82=B6=E3=83=BC=E8=BE=9E?= =?UTF-8?q?=E6=9B=B8=E3=82=82=E3=82=B3=E3=83=B3=E3=83=91=E3=82=A4=E3=83=AB?= =?UTF-8?q?=E3=81=99=E3=82=8B=20(#473)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit エンジン起動時にデフォルト辞書に加えてユーザー辞書もコンパイルする --- voicevox_engine/user_dict.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/voicevox_engine/user_dict.py b/voicevox_engine/user_dict.py index 74b73c3bd..0f0e911d4 100644 --- a/voicevox_engine/user_dict.py +++ b/voicevox_engine/user_dict.py @@ -49,6 +49,10 @@ def user_dict_startup_processing( str(compiled_dict_path.resolve()), ) pyopenjtalk.set_user_dict(str(compiled_dict_path.resolve(strict=True))) + if user_dict_path.is_file(): + update_dict( + default_dict_path=default_dict_path, compiled_dict_path=compiled_dict_path + ) def update_dict( From 65bc9f00fa22ba9053f2fa3fe5b8a57d61140292 Mon Sep 17 00:00:00 2001 From: sabonerune <102559104+sabonerune@users.noreply.github.com> Date: Tue, 20 Sep 2022 20:46:13 +0900 Subject: [PATCH 16/29] =?UTF-8?q?ENH:=E3=83=A6=E3=83=BC=E3=82=B6=E3=83=BC?= =?UTF-8?q?=E8=BE=9E=E6=9B=B8=E3=81=AE=E3=83=87=E3=82=A3=E3=83=AC=E3=82=AF?= =?UTF-8?q?=E3=83=88=E3=83=AA=E3=82=92=E8=A3=BD=E5=93=81=E7=89=88=E3=81=A8?= =?UTF-8?q?=E9=96=8B=E7=99=BA=E7=89=88=E3=81=A7=E5=88=87=E3=82=8A=E6=9B=BF?= =?UTF-8?q?=E3=81=88=E3=82=8B=20(#474)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * ENH:ユーザー辞書のディレクトリを製品版と開発版で切り替える * MAINT: engine_root()でもis_development()を使うように --- voicevox_engine/utility/path_utility.py | 30 +++++++++++++++++++------ 1 file changed, 23 insertions(+), 7 deletions(-) diff --git a/voicevox_engine/utility/path_utility.py b/voicevox_engine/utility/path_utility.py index 9af369d45..4de943624 100644 --- a/voicevox_engine/utility/path_utility.py +++ b/voicevox_engine/utility/path_utility.py @@ -7,25 +7,41 @@ def engine_root() -> Path: + if is_development(): + root_dir = Path(__file__).parents[2] + + # Nuitka/Pyinstallerでビルドされている場合 + else: + root_dir = Path(sys.argv[0]).parent + + return root_dir.resolve(strict=True) + + +def is_development() -> bool: + """ + 開発版かどうか判定する関数 + Nuitka/Pyinstallerでコンパイルされていない場合は開発環境とする。 + """ # nuitkaビルドをした際はグローバルに__compiled__が含まれる if "__compiled__" in globals(): - root_dir = Path(sys.argv[0]).parent + return False # pyinstallerでビルドをした際はsys.frozenが設定される elif getattr(sys, "frozen", False): - root_dir = Path(sys.argv[0]).parent + return False - else: - root_dir = Path(__file__).parents[2] - - return root_dir.resolve(strict=True) + return True def get_save_dir(): # FIXME: ファイル保存場所をエンジン固有のIDが入ったものにする # FIXME: Windowsは`voicevox-engine/voicevox-engine`ディレクトリに保存されているので # `VOICEVOX/voicevox-engine`に変更する - return Path(user_data_dir("voicevox-engine")) + if is_development(): + app_name = "voicevox-engine-dev" + else: + app_name = "voicevox-engine" + return Path(user_data_dir(app_name)) def delete_file(file_path: str) -> None: From 87f490c8c461da79b09e45b451e184c698e894bd Mon Sep 17 00:00:00 2001 From: sabonerune <102559104+sabonerune@users.noreply.github.com> Date: Tue, 27 Sep 2022 19:10:29 +0900 Subject: [PATCH 17/29] =?UTF-8?q?FIX:=20Windows=E3=81=A7=E3=82=A8=E3=83=87?= =?UTF-8?q?=E3=82=A3=E3=82=BF=E3=81=AE=E3=83=AD=E3=82=B0=E3=81=8C=E6=96=87?= =?UTF-8?q?=E5=AD=97=E5=8C=96=E3=81=91=E3=81=99=E3=82=8B=E5=95=8F=E9=A1=8C?= =?UTF-8?q?=E3=81=B8=E3=81=AE=E5=AF=BE=E7=AD=96=20(#478)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * FIX: Windowsのログが文字化けする問題への対策 * FIX: 環境変数・引数での指定に変更 * FIX: set_output_log_utf8を2回呼ぶとstdがcloseする問題を修正 * ADD: README.mbに記述を追加 * FIX: READMEとコメントを修正 --- README.md | 6 ++++++ run.py | 47 ++++++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 50 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 9d5a9821f..efc236ca0 100644 --- a/README.md +++ b/README.md @@ -331,6 +331,12 @@ python run.py --voicevox_dir=$VOICEVOX_DIR --voicelib_dir=$VOICELIB_DIR python run.py --enable_mock ``` +```bash +# ログをUTF8に変更 +python run.py --output_log_utf8 +# もしくは VV_OUTPUT_LOG_UTF8=1 python run.py +``` + ### CPU スレッド数を指定する CPU スレッド数が未指定の場合は、論理コア数の半分か物理コア数が使われます。(殆どの CPU で、これは全体の処理能力の半分です) diff --git a/run.py b/run.py index cdeb259a5..2f39c15b6 100644 --- a/run.py +++ b/run.py @@ -5,12 +5,12 @@ import json import multiprocessing import os +import sys import traceback - -# import sys import zipfile from distutils.version import LooseVersion from functools import lru_cache +from io import TextIOWrapper from pathlib import Path from tempfile import NamedTemporaryFile, TemporaryFile from typing import Dict, List, Optional @@ -69,6 +69,27 @@ def b64encode_str(s): return base64.b64encode(s).decode("utf-8") +def set_output_log_utf8() -> None: + """ + stdout/stderrのエンコーディングをUTF-8に切り替える関数 + """ + # コンソールがない環境だとNone https://docs.python.org/ja/3/library/sys.html#sys.__stdin__ + if sys.stdout is not None: + # 必ずしもreconfigure()が実装されているとは限らない + try: + sys.stdout.reconfigure(encoding="utf-8") + except AttributeError: + # バッファを全て出力する + sys.stdout.flush() + sys.stdout = TextIOWrapper(sys.stdout.buffer, encoding="utf-8") + if sys.stderr is not None: + try: + sys.stderr.reconfigure(encoding="utf-8") + except AttributeError: + sys.stderr.flush() + sys.stderr = TextIOWrapper(sys.stderr.buffer, encoding="utf-8") + + def generate_app( synthesis_engines: Dict[str, SynthesisEngineBase], latest_core_version: str, @@ -807,6 +828,16 @@ def engine_manifest(): if __name__ == "__main__": multiprocessing.freeze_support() + + output_log_utf8 = os.getenv("VV_OUTPUT_LOG_UTF8", default="") + if output_log_utf8 == "1": + set_output_log_utf8() + elif not (output_log_utf8 == "" or output_log_utf8 == "0"): + print( + "WARNING: invalid VV_OUTPUT_LOG_UTF8 environment variable value", + file=sys.stderr, + ) + parser = argparse.ArgumentParser(description="VOICEVOX のエンジンです。") parser.add_argument( "--host", type=str, default="127.0.0.1", help="接続を受け付けるホストアドレスです。" @@ -855,11 +886,21 @@ def engine_manifest(): type=int, default=os.getenv("VV_CPU_NUM_THREADS") or None, help="音声合成を行うスレッド数です。指定しないと、代わりに環境変数VV_CPU_NUM_THREADSの値が使われます。" - "VV_CPU_NUM_THREADSに値がなかった、または数値でなかった場合はエラー終了します。", + "VV_CPU_NUM_THREADSが空文字列でなく数値でもない場合はエラー終了します。", + ) + + parser.add_argument( + "--output_log_utf8", + action="store_true", + help="指定するとログ出力をUTF-8でおこないます。指定しないと、代わりに環境変数 VV_OUTPUT_LOG_UTF8 の値が使われます。" + "VV_OUTPUT_LOG_UTF8 の値が1の場合はUTF-8で、0または空文字、値がない場合は環境によって自動的に決定されます。", ) args = parser.parse_args() + if args.output_log_utf8: + set_output_log_utf8() + cpu_num_threads: Optional[int] = args.cpu_num_threads synthesis_engines = make_synthesis_engines( From 1f2b85b42dfe5e471491084bb4fd10c6bb7d635c Mon Sep 17 00:00:00 2001 From: Gray Suitcase <41382894+PickledChair@users.noreply.github.com> Date: Fri, 16 Sep 2022 19:03:53 +0900 Subject: [PATCH 18/29] =?UTF-8?q?fix:=20=E3=82=A8=E3=83=B3=E3=82=B8?= =?UTF-8?q?=E3=83=B3=E8=B5=B7=E5=8B=95=E6=99=82=E3=81=AB=E3=83=87=E3=83=95?= =?UTF-8?q?=E3=82=A9=E3=83=AB=E3=83=88=E8=BE=9E=E6=9B=B8=E3=81=AB=E5=8A=A0?= =?UTF-8?q?=E3=81=88=E3=81=A6=E3=83=A6=E3=83=BC=E3=82=B6=E3=83=BC=E8=BE=9E?= =?UTF-8?q?=E6=9B=B8=E3=82=82=E3=82=B3=E3=83=B3=E3=83=91=E3=82=A4=E3=83=AB?= =?UTF-8?q?=E3=81=99=E3=82=8B=20(#473)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit エンジン起動時にデフォルト辞書に加えてユーザー辞書もコンパイルする --- voicevox_engine/user_dict.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/voicevox_engine/user_dict.py b/voicevox_engine/user_dict.py index 940c06f15..98875d1b0 100644 --- a/voicevox_engine/user_dict.py +++ b/voicevox_engine/user_dict.py @@ -50,6 +50,10 @@ def user_dict_startup_processing( str(compiled_dict_path.resolve()), ) pyopenjtalk.set_user_dict(str(compiled_dict_path.resolve(strict=True))) + if user_dict_path.is_file(): + update_dict( + default_dict_path=default_dict_path, compiled_dict_path=compiled_dict_path + ) def update_dict( From 45f7c58f7b92dd03675958de26d685c3a2affeba Mon Sep 17 00:00:00 2001 From: Hiroshiba Date: Fri, 30 Sep 2022 13:55:01 +0900 Subject: [PATCH 19/29] to 0.13.1 (#479) --- .github/workflows/build-docker.yml | 4 ++-- .github/workflows/build.yml | 4 ++-- Dockerfile | 4 ++-- default.csv | 3 +++ engine_manifest.json | 2 +- 5 files changed, 10 insertions(+), 7 deletions(-) diff --git a/.github/workflows/build-docker.yml b/.github/workflows/build-docker.yml index e759483bb..7cd738b8e 100644 --- a/.github/workflows/build-docker.yml +++ b/.github/workflows/build-docker.yml @@ -15,8 +15,8 @@ on: env: IMAGE_NAME: ${{ secrets.DOCKERHUB_USERNAME }}/voicevox_engine PYTHON_VERSION: "3.8.10" - VOICEVOX_RESOURCE_VERSION: "0.13.0" - VOICEVOX_CORE_VERSION: "0.13.0" + VOICEVOX_RESOURCE_VERSION: "0.13.1" + VOICEVOX_CORE_VERSION: "0.13.1" VOICEVOX_ENGINE_VERSION: |- # releaseタグ名か、workflow_dispatchでのバージョン名か、latestが入る ${{ github.event.release.tag_name || github.event.inputs.version || 'latest' }} diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 1fc3fbebb..7751a74cc 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -22,8 +22,8 @@ on: env: IMAGE_NAME: ${{ secrets.DOCKERHUB_USERNAME }}/voicevox_engine PYTHON_VERSION: "3.8.10" - VOICEVOX_RESOURCE_VERSION: "0.13.0" - VOICEVOX_CORE_VERSION: "0.13.0" + VOICEVOX_RESOURCE_VERSION: "0.13.1" + VOICEVOX_CORE_VERSION: "0.13.1" VOICEVOX_ENGINE_VERSION: |- # releaseタグ名か、workflow_dispatchでのバージョン名か、latestが入る ${{ github.event.release.tag_name || github.event.inputs.version || 'latest' }} diff --git a/Dockerfile b/Dockerfile index 305aeeb15..a6ed57263 100644 --- a/Dockerfile +++ b/Dockerfile @@ -22,7 +22,7 @@ EOF # assert VOICEVOX_CORE_VERSION >= 0.11.0 (ONNX) ARG VOICEVOX_CORE_ASSET_PREFIX=voicevox_core-linux-x64-cpu -ARG VOICEVOX_CORE_VERSION=0.13.0 +ARG VOICEVOX_CORE_VERSION=0.13.1 RUN < Date: Fri, 7 Oct 2022 01:09:39 +0900 Subject: [PATCH 20/29] =?UTF-8?q?TST:=20user=5Fdict=5Fstartup=5Fprocessing?= =?UTF-8?q?=E3=81=AE=E3=83=86=E3=82=B9=E3=83=88=E3=82=92=E8=BF=BD=E5=8A=A0?= =?UTF-8?q?=E3=80=82=20(#483)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit テストのためuser_dict内の関数に引数を追加 --- test/test_user_dict.py | 33 ++++++++++++++++++++++++++++++++- voicevox_engine/user_dict.py | 18 ++++++++++++------ 2 files changed, 44 insertions(+), 7 deletions(-) diff --git a/test/test_user_dict.py b/test/test_user_dict.py index 250d65fa5..532797731 100644 --- a/test/test_user_dict.py +++ b/test/test_user_dict.py @@ -6,7 +6,7 @@ from unittest import TestCase from fastapi import HTTPException -from pyopenjtalk import unset_user_dict +from pyopenjtalk import g2p, unset_user_dict from voicevox_engine.model import UserDictWord, WordTypes from voicevox_engine.part_of_speech_data import MAX_PRIORITY, part_of_speech_data @@ -17,6 +17,7 @@ import_user_dict, read_dict, rewrite_word, + user_dict_startup_processing, ) # jsonとして保存される正しい形式の辞書データ @@ -315,3 +316,33 @@ def test_import_invalid_word(self): user_dict_path=user_dict_path, compiled_dict_path=compiled_dict_path, ) + + def test_startup_processing(self): + user_dict_path = self.tmp_dir_path / "test_startup_processing_dict.json" + compiled_dict_path = self.tmp_dir_path / "test_startup_processing_dict.dic" + user_dict_startup_processing( + user_dict_path=user_dict_path, compiled_dict_path=compiled_dict_path + ) + test_text = "テスト用の文字列" + success_pronunciation = "デフォルトノジショデハゼッタイニセイセイサレナイヨミ" + + # 既に辞書に登録されていないか確認する + self.assertNotEqual(g2p(text=test_text, kana=True), success_pronunciation) + + apply_word( + surface=test_text, + pronunciation=success_pronunciation, + accent_type=1, + priority=10, + user_dict_path=user_dict_path, + compiled_dict_path=compiled_dict_path, + ) + self.assertEqual(g2p(text=test_text, kana=True), success_pronunciation) + + # 疑似的にエンジンを再起動する + unset_user_dict() + user_dict_startup_processing( + user_dict_path=user_dict_path, compiled_dict_path=compiled_dict_path + ) + + self.assertEqual(g2p(text=test_text, kana=True), success_pronunciation) diff --git a/voicevox_engine/user_dict.py b/voicevox_engine/user_dict.py index 0f0e911d4..fadfa3e35 100644 --- a/voicevox_engine/user_dict.py +++ b/voicevox_engine/user_dict.py @@ -42,6 +42,7 @@ def write_to_json(user_dict: Dict[str, UserDictWord], user_dict_path: Path): def user_dict_startup_processing( default_dict_path: Path = default_dict_path, + user_dict_path: Path = user_dict_path, compiled_dict_path: Path = compiled_dict_path, ): pyopenjtalk.create_user_dict( @@ -51,12 +52,15 @@ def user_dict_startup_processing( pyopenjtalk.set_user_dict(str(compiled_dict_path.resolve(strict=True))) if user_dict_path.is_file(): update_dict( - default_dict_path=default_dict_path, compiled_dict_path=compiled_dict_path + default_dict_path=default_dict_path, + user_dict_path=user_dict_path, + compiled_dict_path=compiled_dict_path, ) def update_dict( default_dict_path: Path = default_dict_path, + user_dict_path: Path = user_dict_path, compiled_dict_path: Path = compiled_dict_path, ): with NamedTemporaryFile(encoding="utf-8", mode="w", delete=False) as f: @@ -67,7 +71,7 @@ def update_dict( if default_dict == default_dict.rstrip(): default_dict += "\n" f.write(default_dict) - user_dict = read_dict() + user_dict = read_dict(user_dict_path=user_dict_path) for word_uuid in user_dict: word = user_dict[word_uuid] f.write( @@ -185,7 +189,7 @@ def apply_word( word_uuid = str(uuid4()) user_dict[word_uuid] = word write_to_json(user_dict, user_dict_path) - update_dict(compiled_dict_path=compiled_dict_path) + update_dict(user_dict_path=user_dict_path, compiled_dict_path=compiled_dict_path) return word_uuid @@ -211,7 +215,7 @@ def rewrite_word( raise HTTPException(status_code=422, detail="UUIDに該当するワードが見つかりませんでした") user_dict[word_uuid] = word write_to_json(user_dict, user_dict_path) - update_dict(compiled_dict_path=compiled_dict_path) + update_dict(user_dict_path=user_dict_path, compiled_dict_path=compiled_dict_path) def delete_word( @@ -224,7 +228,7 @@ def delete_word( raise HTTPException(status_code=422, detail="IDに該当するワードが見つかりませんでした") del user_dict[word_uuid] write_to_json(user_dict, user_dict_path) - update_dict(compiled_dict_path=compiled_dict_path) + update_dict(user_dict_path=user_dict_path, compiled_dict_path=compiled_dict_path) def import_user_dict( @@ -263,7 +267,9 @@ def import_user_dict( new_dict = {**dict_data, **old_dict} write_to_json(user_dict=new_dict, user_dict_path=user_dict_path) update_dict( - default_dict_path=default_dict_path, compiled_dict_path=compiled_dict_path + default_dict_path=default_dict_path, + user_dict_path=user_dict_path, + compiled_dict_path=compiled_dict_path, ) From 0097d71a7745165dc547824bc2caa20081261ee4 Mon Sep 17 00:00:00 2001 From: sabonerune <102559104+sabonerune@users.noreply.github.com> Date: Sun, 9 Oct 2022 22:54:07 +0900 Subject: [PATCH 21/29] =?UTF-8?q?MAINT:=20user=5Fdict=5Fstratup=5Fprocessi?= =?UTF-8?q?ng=E3=82=92=E5=89=8A=E9=99=A4=20(#485)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * MAINT: user_dict_stratup_processingを削除 user_dict_stratup_processingの動作が結果的にupdate_dictと一致しているため削除する。 * FIX: テスト名等を修正 --- run.py | 4 ++-- test/test_user_dict.py | 12 ++++++------ voicevox_engine/user_dict.py | 18 ------------------ 3 files changed, 8 insertions(+), 26 deletions(-) diff --git a/run.py b/run.py index 2f39c15b6..0ead52d08 100644 --- a/run.py +++ b/run.py @@ -55,7 +55,7 @@ import_user_dict, read_dict, rewrite_word, - user_dict_startup_processing, + update_dict, ) from voicevox_engine.utility import ( ConnectBase64WavesException, @@ -134,7 +134,7 @@ def generate_app( @app.on_event("startup") def apply_user_dict(): - user_dict_startup_processing() + update_dict() def get_engine(core_version: Optional[str]) -> SynthesisEngineBase: if core_version is None: diff --git a/test/test_user_dict.py b/test/test_user_dict.py index 532797731..4280bbe53 100644 --- a/test/test_user_dict.py +++ b/test/test_user_dict.py @@ -17,7 +17,7 @@ import_user_dict, read_dict, rewrite_word, - user_dict_startup_processing, + update_dict, ) # jsonとして保存される正しい形式の辞書データ @@ -317,10 +317,10 @@ def test_import_invalid_word(self): compiled_dict_path=compiled_dict_path, ) - def test_startup_processing(self): - user_dict_path = self.tmp_dir_path / "test_startup_processing_dict.json" - compiled_dict_path = self.tmp_dir_path / "test_startup_processing_dict.dic" - user_dict_startup_processing( + def test_update_dict(self): + user_dict_path = self.tmp_dir_path / "test_update_dict.json" + compiled_dict_path = self.tmp_dir_path / "test_update_dict.dic" + update_dict( user_dict_path=user_dict_path, compiled_dict_path=compiled_dict_path ) test_text = "テスト用の文字列" @@ -341,7 +341,7 @@ def test_startup_processing(self): # 疑似的にエンジンを再起動する unset_user_dict() - user_dict_startup_processing( + update_dict( user_dict_path=user_dict_path, compiled_dict_path=compiled_dict_path ) diff --git a/voicevox_engine/user_dict.py b/voicevox_engine/user_dict.py index fadfa3e35..72828a629 100644 --- a/voicevox_engine/user_dict.py +++ b/voicevox_engine/user_dict.py @@ -40,24 +40,6 @@ def write_to_json(user_dict: Dict[str, UserDictWord], user_dict_path: Path): user_dict_path.write_text(user_dict_json, encoding="utf-8") -def user_dict_startup_processing( - default_dict_path: Path = default_dict_path, - user_dict_path: Path = user_dict_path, - compiled_dict_path: Path = compiled_dict_path, -): - pyopenjtalk.create_user_dict( - str(default_dict_path.resolve(strict=True)), - str(compiled_dict_path.resolve()), - ) - pyopenjtalk.set_user_dict(str(compiled_dict_path.resolve(strict=True))) - if user_dict_path.is_file(): - update_dict( - default_dict_path=default_dict_path, - user_dict_path=user_dict_path, - compiled_dict_path=compiled_dict_path, - ) - - def update_dict( default_dict_path: Path = default_dict_path, user_dict_path: Path = user_dict_path, From 7ab873f97e8c8a73109f59a4a0980f985645f7ca Mon Sep 17 00:00:00 2001 From: sabonerune <102559104+sabonerune@users.noreply.github.com> Date: Thu, 13 Oct 2022 19:00:34 +0900 Subject: [PATCH 22/29] =?UTF-8?q?ENH:=20=E7=95=B0=E3=81=AA=E3=82=8B?= =?UTF-8?q?=E3=82=B5=E3=83=B3=E3=83=97=E3=83=AA=E3=83=B3=E3=82=B0=E3=83=AC?= =?UTF-8?q?=E3=83=BC=E3=83=88=E3=81=AE=E9=9F=B3=E5=A3=B0=E3=82=82=E7=B5=90?= =?UTF-8?q?=E5=90=88=E3=81=A7=E3=81=8D=E3=82=8B=E3=82=88=E3=81=86=E3=81=AB?= =?UTF-8?q?=E3=81=99=E3=82=8B=20(#487)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * ENH: 異なるサンプリングレートの音声も結合できるようにする 最も高いサンプリングレート・チャンネルに合わせるように変更 異なるサンプリングレートの音声を結合させるテストを追加 異なるチャンネルの音声を結合させるテストを追加 * FIX: サンプリングレートの型を修正 * FIX: サンプリングレートとチャンネル数の最大値の計算を分かりやすく Co-authored-by: Hiroshiba * DOC: docstringを追加 ほか使用しないインポートを削除 Co-authored-by: Hiroshiba --- test/test_connect_base64_waves.py | 38 +++++++++--- .../utility/connect_base64_waves.py | 62 ++++++++++++------- 2 files changed, 66 insertions(+), 34 deletions(-) diff --git a/test/test_connect_base64_waves.py b/test/test_connect_base64_waves.py index e1d42ad3f..e50c8f517 100644 --- a/test/test_connect_base64_waves.py +++ b/test/test_connect_base64_waves.py @@ -3,7 +3,9 @@ from unittest import TestCase import numpy as np +import numpy.testing import soundfile +from scipy.signal import resample from voicevox_engine.utility import ConnectBase64WavesException, connect_base64_waves @@ -94,19 +96,35 @@ def test_invalid_wave_file_error(self): ], ) - def test_different_frequency_error(self): - wave_24000hz = generate_sine_wave_base64( + def test_different_frequency(self): + wave_24000hz = generate_sine_wave_ndarray( seconds=1, samplerate=24000, frequency=10 ) - wave_1000hz = generate_sine_wave_base64( + wave_1000hz = generate_sine_wave_ndarray( seconds=2, samplerate=1000, frequency=10 ) + wave_24000_base64 = encode_base64(encode_bytes(wave_24000hz, samplerate=24000)) + wave_1000_base64 = encode_base64(encode_bytes(wave_1000hz, samplerate=1000)) - self.assertRaises( - ConnectBase64WavesException, - connect_base64_waves, - waves=[ - wave_24000hz, - wave_1000hz, - ], + wave_1000hz_to2400hz = resample(wave_1000hz, 24000 * len(wave_1000hz) // 1000) + wave_x2_ref = np.concatenate([wave_24000hz, wave_1000hz_to2400hz]) + + wave_x2, _ = connect_base64_waves(waves=[wave_24000_base64, wave_1000_base64]) + + self.assertEqual(wave_x2_ref.shape, wave_x2.shape) + numpy.testing.assert_array_almost_equal(wave_x2_ref, wave_x2) + + def test_different_channels(self): + wave_1000hz = generate_sine_wave_ndarray( + seconds=2, samplerate=1000, frequency=10 ) + wave_2ch_1000hz = np.array([wave_1000hz, wave_1000hz]).T + wave_1ch_base64 = encode_base64(encode_bytes(wave_1000hz, samplerate=1000)) + wave_2ch_base64 = encode_base64(encode_bytes(wave_2ch_1000hz, samplerate=1000)) + + wave_x2_ref = np.concatenate([wave_2ch_1000hz, wave_2ch_1000hz]) + + wave_x2, _ = connect_base64_waves(waves=[wave_1ch_base64, wave_2ch_base64]) + + self.assertEqual(wave_x2_ref.shape, wave_x2.shape) + self.assertTrue((wave_x2_ref == wave_x2).all()) diff --git a/voicevox_engine/utility/connect_base64_waves.py b/voicevox_engine/utility/connect_base64_waves.py index b40d960a0..37f952409 100644 --- a/voicevox_engine/utility/connect_base64_waves.py +++ b/voicevox_engine/utility/connect_base64_waves.py @@ -4,6 +4,7 @@ import numpy as np import soundfile +from scipy.signal import resample class ConnectBase64WavesException(Exception): @@ -11,36 +12,49 @@ def __init__(self, message: str): self.message = message -def decode_base64_waves(waves: List[str]) -> Tuple[List[np.ndarray], float]: +def decode_base64_waves(waves: List[str]) -> List[Tuple[np.ndarray, int]]: + """ + base64エンコードされた複数のwavデータをデコードする + Parameters + ---------- + waves: list[str] + base64エンコードされたwavデータのリスト + Returns + ------- + waves_nparray_sr: List[Tuple[np.ndarray, int]] + (NumPy配列の音声波形データ, サンプリングレート) 形式のタプルのリスト + """ if len(waves) == 0: raise ConnectBase64WavesException("wavファイルが含まれていません") - waves_nparray = [] - for i in range(len(waves)): + waves_nparray_sr = [] + for wave in waves: try: - wav_bin = base64.standard_b64decode(waves[i]) + wav_bin = base64.standard_b64decode(wave) except ValueError: raise ConnectBase64WavesException("base64デコードに失敗しました") try: - _data, _sampling_rate = soundfile.read(io.BytesIO(wav_bin)) + _data = soundfile.read(io.BytesIO(wav_bin)) except Exception: raise ConnectBase64WavesException("wavファイルを読み込めませんでした") - if i == 0: - sampling_rate = _sampling_rate - channels = _data.ndim - else: - if sampling_rate != _sampling_rate: - raise ConnectBase64WavesException("ファイル間でサンプリングレートが異なります") - if channels != _data.ndim: - if channels == 1: - _data = _data.T[0] - else: - _data = np.array([_data, _data]).T - waves_nparray.append(_data) - - return waves_nparray, sampling_rate - - -def connect_base64_waves(waves: List[str]) -> Tuple[np.ndarray, float]: - waves_nparray_list, sampling_rate = decode_base64_waves(waves) - return np.concatenate(waves_nparray_list), sampling_rate + waves_nparray_sr.append(_data) + + return waves_nparray_sr + + +def connect_base64_waves(waves: List[str]) -> Tuple[np.ndarray, int]: + waves_nparray_sr = decode_base64_waves(waves) + + max_sampling_rate = max([sr for _, sr in waves_nparray_sr]) + max_channels = max([x.ndim for x, _ in waves_nparray_sr]) + assert 0 < max_channels <= 2 + + waves_nparray_list = [] + for nparray, sr in waves_nparray_sr: + if sr != max_sampling_rate: + nparray = resample(nparray, max_sampling_rate * len(nparray) // sr) + if nparray.ndim < max_channels: + nparray = np.array([nparray, nparray]).T + waves_nparray_list.append(nparray) + + return np.concatenate(waves_nparray_list), max_sampling_rate From 8ea53e252a1cbda71ed55012b84be783c3cc7c43 Mon Sep 17 00:00:00 2001 From: sabonerune <102559104+sabonerune@users.noreply.github.com> Date: Fri, 21 Oct 2022 17:26:24 +0900 Subject: [PATCH 23/29] =?UTF-8?q?FIX:=20=E3=82=A8=E3=83=A9=E3=83=BC?= =?UTF-8?q?=E5=87=A6=E7=90=86=E5=91=A8=E3=82=8A=E3=81=A7UnicodeError?= =?UTF-8?q?=E3=81=8C=E7=99=BA=E7=94=9F=E3=81=97=E3=81=AA=E3=81=84=E3=82=88?= =?UTF-8?q?=E3=81=86=E3=81=AB=E3=81=99=E3=82=8B=20(#490)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- run.py | 8 +++-- .../synthesis_engine/core_wrapper.py | 30 +++++++++++++++---- 2 files changed, 30 insertions(+), 8 deletions(-) diff --git a/run.py b/run.py index 0ead52d08..25f49cb12 100644 --- a/run.py +++ b/run.py @@ -81,13 +81,17 @@ def set_output_log_utf8() -> None: except AttributeError: # バッファを全て出力する sys.stdout.flush() - sys.stdout = TextIOWrapper(sys.stdout.buffer, encoding="utf-8") + sys.stdout = TextIOWrapper( + sys.stdout.buffer, encoding="utf-8", errors="backslashreplace" + ) if sys.stderr is not None: try: sys.stderr.reconfigure(encoding="utf-8") except AttributeError: sys.stderr.flush() - sys.stderr = TextIOWrapper(sys.stderr.buffer, encoding="utf-8") + sys.stderr = TextIOWrapper( + sys.stderr.buffer, encoding="utf-8", errors="backslashreplace" + ) def generate_app( diff --git a/voicevox_engine/synthesis_engine/core_wrapper.py b/voicevox_engine/synthesis_engine/core_wrapper.py index 9502c9921..9fa0ab3c4 100644 --- a/voicevox_engine/synthesis_engine/core_wrapper.py +++ b/voicevox_engine/synthesis_engine/core_wrapper.py @@ -421,13 +421,25 @@ def __init__( try: if is_version_0_12_core_or_later: if not self.core.initialize(use_gpu, cpu_num_threads, load_all_models): - raise Exception(self.core.last_error_message().decode("utf-8")) + raise Exception( + self.core.last_error_message().decode( + "utf-8", "backslashreplace" + ) + ) elif exist_cpu_num_threads: if not self.core.initialize(".", use_gpu, cpu_num_threads): - raise Exception(self.core.last_error_message().decode("utf-8")) + raise Exception( + self.core.last_error_message().decode( + "utf-8", "backslashreplace" + ) + ) else: if not self.core.initialize(".", use_gpu): - raise Exception(self.core.last_error_message().decode("utf-8")) + raise Exception( + self.core.last_error_message().decode( + "utf-8", "backslashreplace" + ) + ) finally: os.chdir(cwd) @@ -448,7 +460,9 @@ def yukarin_s_forward( output.ctypes.data_as(POINTER(c_float)), ) if not success: - raise Exception(self.core.last_error_message().decode("utf-8")) + raise Exception( + self.core.last_error_message().decode("utf-8", "backslashreplace") + ) return output def yukarin_sa_forward( @@ -481,7 +495,9 @@ def yukarin_sa_forward( output.ctypes.data_as(POINTER(c_float)), ) if not success: - raise Exception(self.core.last_error_message().decode("utf-8")) + raise Exception( + self.core.last_error_message().decode("utf-8", "backslashreplace") + ) return output def decode_forward( @@ -502,7 +518,9 @@ def decode_forward( output.ctypes.data_as(POINTER(c_float)), ) if not success: - raise Exception(self.core.last_error_message().decode("utf-8")) + raise Exception( + self.core.last_error_message().decode("utf-8", "backslashreplace") + ) return output def supported_devices(self) -> str: From 9f5a14d6f098a5068ab60e111480b0a042214390 Mon Sep 17 00:00:00 2001 From: aoirint Date: Fri, 21 Oct 2022 22:02:39 +0900 Subject: [PATCH 24/29] =?UTF-8?q?CI:=20=E8=87=AA=E5=8B=95=E4=BD=9C?= =?UTF-8?q?=E6=88=90=E3=81=95=E3=82=8C=E3=82=8B=E3=83=AA=E3=83=AA=E3=83=BC?= =?UTF-8?q?=E3=82=B9=E3=81=AE=E3=82=BF=E3=82=B0=E3=81=AE=E5=A0=B4=E6=89=80?= =?UTF-8?q?=E3=82=92=E6=AD=A3=E3=81=97=E3=81=8F=E3=81=99=E3=82=8B=20(#489)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Update build.yml * Update build.yml --- .github/workflows/build.yml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 178a8bdbf..2084592b5 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -827,13 +827,13 @@ jobs: mv archives.txt "${{ matrix.artifact_name }}.7z.txt" - name: Upload splitted archives to Release assets - uses: svenstaro/upload-release-action@v2 + uses: softprops/action-gh-release@v1 with: - repo_token: ${{ secrets.GITHUB_TOKEN }} - tag: ${{ env.VOICEVOX_ENGINE_VERSION }} prerelease: ${{ github.event.inputs.prerelease }} - file_glob: true - file: ${{ matrix.artifact_name }}.7z.* + tag_name: ${{ env.VOICEVOX_ENGINE_VERSION }} + files: |- + ${{ matrix.artifact_name }}.7z.* + target_commitish: ${{ github.sha }} run-release-test-workflow: if: (github.event.release.tag_name || github.event.inputs.version) != '' From edca5a3e2863c438489adfc41f62d6a6a20998be Mon Sep 17 00:00:00 2001 From: Hiroshiba Date: Mon, 24 Oct 2022 06:59:40 +0900 Subject: [PATCH 25/29] to 0.13.2 --- .github/workflows/build-docker.yml | 4 ++-- .github/workflows/build.yml | 4 ++-- Dockerfile | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/build-docker.yml b/.github/workflows/build-docker.yml index 7cd738b8e..f0bc67ab3 100644 --- a/.github/workflows/build-docker.yml +++ b/.github/workflows/build-docker.yml @@ -15,8 +15,8 @@ on: env: IMAGE_NAME: ${{ secrets.DOCKERHUB_USERNAME }}/voicevox_engine PYTHON_VERSION: "3.8.10" - VOICEVOX_RESOURCE_VERSION: "0.13.1" - VOICEVOX_CORE_VERSION: "0.13.1" + VOICEVOX_RESOURCE_VERSION: "0.13.2" + VOICEVOX_CORE_VERSION: "0.13.2" VOICEVOX_ENGINE_VERSION: |- # releaseタグ名か、workflow_dispatchでのバージョン名か、latestが入る ${{ github.event.release.tag_name || github.event.inputs.version || 'latest' }} diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 7751a74cc..b895a493e 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -22,8 +22,8 @@ on: env: IMAGE_NAME: ${{ secrets.DOCKERHUB_USERNAME }}/voicevox_engine PYTHON_VERSION: "3.8.10" - VOICEVOX_RESOURCE_VERSION: "0.13.1" - VOICEVOX_CORE_VERSION: "0.13.1" + VOICEVOX_RESOURCE_VERSION: "0.13.2" + VOICEVOX_CORE_VERSION: "0.13.2" VOICEVOX_ENGINE_VERSION: |- # releaseタグ名か、workflow_dispatchでのバージョン名か、latestが入る ${{ github.event.release.tag_name || github.event.inputs.version || 'latest' }} diff --git a/Dockerfile b/Dockerfile index a6ed57263..2cd0c4e78 100644 --- a/Dockerfile +++ b/Dockerfile @@ -22,7 +22,7 @@ EOF # assert VOICEVOX_CORE_VERSION >= 0.11.0 (ONNX) ARG VOICEVOX_CORE_ASSET_PREFIX=voicevox_core-linux-x64-cpu -ARG VOICEVOX_CORE_VERSION=0.13.1 +ARG VOICEVOX_CORE_VERSION=0.13.2 RUN < Date: Fri, 28 Oct 2022 09:55:04 +0900 Subject: [PATCH 26/29] =?UTF-8?q?Update:=20action=E3=81=AE=E3=83=90?= =?UTF-8?q?=E3=83=BC=E3=82=B8=E3=83=A7=E3=83=B3=E3=82=92=E6=9B=B4=E6=96=B0?= =?UTF-8?q?=20(#496)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/build-docker.yml | 12 +++---- .github/workflows/build.yml | 56 +++++++++++++++--------------- .github/workflows/test.yml | 6 ++-- 3 files changed, 37 insertions(+), 37 deletions(-) diff --git a/.github/workflows/build-docker.yml b/.github/workflows/build-docker.yml index f0bc67ab3..4f1d88638 100644 --- a/.github/workflows/build-docker.yml +++ b/.github/workflows/build-docker.yml @@ -83,21 +83,21 @@ jobs: onnxruntime_url: https://github.com/microsoft/onnxruntime/releases/download/v1.10.0/onnxruntime-linux-x64-gpu-1.10.0.tgz steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Setup Docker Buildx id: buildx - uses: docker/setup-buildx-action@v1 + uses: docker/setup-buildx-action@v2 - name: Login to DockerHub - uses: docker/login-action@v1 + uses: docker/login-action@v2 with: username: ${{ secrets.DOCKERHUB_USERNAME }} password: ${{ secrets.DOCKERHUB_TOKEN }} # Download VOICEVOX RESOURCE - name: Prepare VOICEVOX RESOURCE cache - uses: actions/cache@v2 + uses: actions/cache@v3 id: voicevox-resource-cache with: key: voicevox-resource-${{ env.VOICEVOX_RESOURCE_VERSION }} @@ -105,7 +105,7 @@ jobs: - name: Checkout VOICEVOX RESOURCE if: steps.voicevox-resource-cache.outputs.cache-hit != 'true' - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: repository: VOICEVOX/voicevox_resource ref: ${{ env.VOICEVOX_RESOURCE_VERSION }} @@ -119,7 +119,7 @@ jobs: run: bash build_util/merge_voicevox_resource.bash - name: Build and Deploy Docker image - uses: docker/build-push-action@v2 + uses: docker/build-push-action@v3 env: IMAGE_TAG: |- # If it's a release, add the version, otherwise add the `latest` diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index e91c44237..8d47b11e3 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -43,7 +43,7 @@ jobs: runs-on: ${{ matrix.os }} steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Install CCache shell: bash @@ -61,7 +61,7 @@ jobs: - name: Setup Python id: setup-python - uses: actions/setup-python@v2 + uses: actions/setup-python@v4 with: python-version: ${{ env.PYTHON_VERSION }} architecture: ${{ matrix.python_architecture }} @@ -88,7 +88,7 @@ jobs: run: echo "${{ matrix.onnxruntime_url }}" > download/onnxruntime_url.txt - name: Prepare ONNX Runtime cache - uses: actions/cache@v2 + uses: actions/cache@v3 id: onnxruntime-dylib-cache with: key: ${{ matrix.os }}-onnxruntime-dylib-${{ hashFiles('download/onnxruntime_url.txt') }}-v1 @@ -112,7 +112,7 @@ jobs: # Download VOICEVOX RESOURCE - name: Prepare VOICEVOX RESOURCE cache - uses: actions/cache@v2 + uses: actions/cache@v3 id: voicevox-resource-cache with: key: voicevox-resource-${{ env.VOICEVOX_RESOURCE_VERSION }} @@ -120,7 +120,7 @@ jobs: - name: Checkout VOICEVOX RESOURCE if: steps.voicevox-resource-cache.outputs.cache-hit != 'true' - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: repository: VOICEVOX/voicevox_resource ref: ${{ env.VOICEVOX_RESOURCE_VERSION }} @@ -134,7 +134,7 @@ jobs: run: bash build_util/merge_voicevox_resource.bash - name: Prepare VOICEVOX Core release cache - uses: actions/cache@v2 + uses: actions/cache@v3 id: voicevox-core-cache with: key: ${{ matrix.os }}-voicevox-core-${{ matrix.voicevox_core_asset_prefix }}-${{ env.VOICEVOX_CORE_VERSION }} @@ -232,7 +232,7 @@ jobs: # Currently, It is good to use static artifact name for future binary test workflow. # https://github.com/actions/toolkit/blob/ea81280a4d48fb0308d40f8f12ae00d117f8acb9/packages/artifact/src/internal/artifact-client.ts#L147 # https://github.com/dawidd6/action-download-artifact/blob/af92a8455a59214b7b932932f2662fdefbd78126/main.js#L113 - - uses: actions/upload-artifact@v2 + - uses: actions/upload-artifact@v3 # env: # VERSIONED_ARTIFACT_NAME: | # ${{ format('{0}-{1}', matrix.artifact_name, (env.VOICEVOX_ENGINE_VERSION != 'latest' && env.VOICEVOX_ENGINE_VERSION) || github.sha) }} @@ -271,21 +271,21 @@ jobs: runs-on: ${{ matrix.os }} steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Setup Docker Buildx id: buildx - uses: docker/setup-buildx-action@v1 + uses: docker/setup-buildx-action@v2 - name: Login to DockerHub - uses: docker/login-action@v1 + uses: docker/login-action@v2 with: username: ${{ secrets.DOCKERHUB_USERNAME }} password: ${{ secrets.DOCKERHUB_TOKEN }} # Download VOICEVOX RESOURCE - name: Prepare VOICEVOX RESOURCE cache - uses: actions/cache@v2 + uses: actions/cache@v3 id: voicevox-resource-cache with: key: voicevox-resource-${{ env.VOICEVOX_RESOURCE_VERSION }} @@ -293,7 +293,7 @@ jobs: - name: Checkout VOICEVOX RESOURCE if: steps.voicevox-resource-cache.outputs.cache-hit != 'true' - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: repository: VOICEVOX/voicevox_resource ref: ${{ env.VOICEVOX_RESOURCE_VERSION }} @@ -309,7 +309,7 @@ jobs: # NOTE: `load: true` may silently fail when the GitHub Actions disk (14GB) is full. # https://docs.github.com/ja/actions/using-github-hosted-runners/about-github-hosted-runners#supported-runners-and-hardware-resources - name: Create binary build environment with Docker - uses: docker/build-push-action@v2 + uses: docker/build-push-action@v3 env: IMAGE_TAG: ${{ env.IMAGE_NAME }}:${{ matrix.tag }}${{ (matrix.tag != '' && '-') || '' }}latest RUNTIME_IMAGE_TAG: ${{ env.IMAGE_NAME }}:${{ matrix.runtime_tag }}${{ (matrix.runtime_tag != '' && '-') || '' }}latest @@ -338,7 +338,7 @@ jobs: # Build run.py with Nuitka in Docker - name: Cache Nuitka (ccache, module-cache) - uses: actions/cache@v2 + uses: actions/cache@v3 id: nuitka-cache with: path: ${{ matrix.nuitka_cache_path }} @@ -361,7 +361,7 @@ jobs: # Currently, It is good to use static artifact name for future binary test workflow. # https://github.com/actions/toolkit/blob/ea81280a4d48fb0308d40f8f12ae00d117f8acb9/packages/artifact/src/internal/artifact-client.ts#L147 # https://github.com/dawidd6/action-download-artifact/blob/af92a8455a59214b7b932932f2662fdefbd78126/main.js#L113 - - uses: actions/upload-artifact@v2 + - uses: actions/upload-artifact@v3 # env: # VERSIONED_ARTIFACT_NAME: | # ${{ format('{0}-{1}', matrix.artifact_name, (env.VOICEVOX_ENGINE_VERSION != 'latest' && env.VOICEVOX_ENGINE_VERSION) || github.sha) }} @@ -405,7 +405,7 @@ jobs: runs-on: ${{ matrix.os }} steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Show disk space (debug info) shell: bash @@ -415,7 +415,7 @@ jobs: # Download CUDA - name: Prepare CUDA DLL cache if: matrix.cuda_version != '' - uses: actions/cache@v2 + uses: actions/cache@v3 id: cuda-dll-cache with: # update this key when ONNX Runtime CUDA dependency changed @@ -457,7 +457,7 @@ jobs: - name: Prepare cuDNN cache if: matrix.cudnn_url != '' - uses: actions/cache@v2 + uses: actions/cache@v3 id: cudnn-dll-cache with: # update this key when ONNX Runtime cuDNN dependency changed @@ -492,7 +492,7 @@ jobs: # Python install path: C:/hostedtoolcache/windows/Python - name: Setup Python id: setup-python - uses: actions/setup-python@v2 + uses: actions/setup-python@v4 with: python-version: ${{ env.PYTHON_VERSION }} architecture: ${{ matrix.architecture }} @@ -533,7 +533,7 @@ jobs: run: echo "${{ matrix.ccache_url }}" > download/ccache_url.txt - name: Prepare Ccache - uses: actions/cache@v2 + uses: actions/cache@v3 id: ccache-cache with: key: ${{ matrix.os }}-ccache-${{ hashFiles('download/ccache_url.txt') }} @@ -561,7 +561,7 @@ jobs: - name: Cache DirectML if: endswith(matrix.artifact_name, '-directml') - uses: actions/cache@v2 + uses: actions/cache@v3 id: directml-cache with: key: directml-cache-v1-${{ hashFiles('download/directml_url.txt') }} @@ -586,7 +586,7 @@ jobs: run: echo "${{ matrix.onnxruntime_url }}" > download/onnxruntime_url.txt - name: Prepare ONNX Runtime cache - uses: actions/cache@v2 + uses: actions/cache@v3 id: onnxruntime-dll-cache with: key: ${{ matrix.os }}-onnxruntime-dll-${{ hashFiles('download/onnxruntime_url.txt') }}-v1 @@ -618,7 +618,7 @@ jobs: # Download VOICEVOX RESOURCE - name: Prepare VOICEVOX RESOURCE cache - uses: actions/cache@v2 + uses: actions/cache@v3 id: voicevox-resource-cache with: key: voicevox-resource-${{ env.VOICEVOX_RESOURCE_VERSION }} @@ -626,7 +626,7 @@ jobs: - name: Checkout VOICEVOX RESOURCE if: steps.voicevox-resource-cache.outputs.cache-hit != 'true' - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: repository: VOICEVOX/voicevox_resource ref: ${{ env.VOICEVOX_RESOURCE_VERSION }} @@ -673,7 +673,7 @@ jobs: cp engine_manifest_assets/dependency_licenses.json licenses.json - name: Cache Nuitka (ccache, module-cache) - uses: actions/cache@v2 + uses: actions/cache@v3 id: nuitka-cache with: path: ${{ matrix.nuitka_cache_path }} @@ -780,7 +780,7 @@ jobs: # Currently, It is good to use static artifact name for future binary test workflow. # https://github.com/actions/toolkit/blob/ea81280a4d48fb0308d40f8f12ae00d117f8acb9/packages/artifact/src/internal/artifact-client.ts#L147 # https://github.com/dawidd6/action-download-artifact/blob/af92a8455a59214b7b932932f2662fdefbd78126/main.js#L113 - - uses: actions/upload-artifact@v2 + - uses: actions/upload-artifact@v3 # env: # VERSIONED_ARTIFACT_NAME: | # ${{ format('{0}-{1}', matrix.artifact_name, (env.VOICEVOX_ENGINE_VERSION != 'latest' && env.VOICEVOX_ENGINE_VERSION) || github.sha) }} @@ -803,7 +803,7 @@ jobs: - windows-directml - windows-nvidia steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Install dependencies run: | @@ -812,7 +812,7 @@ jobs: p7zip-full - name: Download and extract artifact - uses: actions/download-artifact@v2 + uses: actions/download-artifact@v3 with: name: ${{ matrix.artifact_name }} path: ${{ matrix.artifact_name }}/ diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 228cf95c3..946b74aea 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -23,10 +23,10 @@ jobs: path: ~\AppData\Local\pip\Cache steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Set up Python ${{ matrix.python }} - uses: actions/setup-python@v2 + uses: actions/setup-python@v4 with: python-version: ${{ matrix.python }} cache: pip @@ -61,7 +61,7 @@ jobs: - name: Upload coverage result if: github.event_name == 'pull_request' && matrix.os == 'ubuntu-latest' - uses: actions/upload-artifact@v2 + uses: actions/upload-artifact@v3 with: name: report path: report/ From 16548b118772a300e7c1c4aecaec8f5ed621c1ae Mon Sep 17 00:00:00 2001 From: ts-klassen <104614062+ts-klassen@users.noreply.github.com> Date: Mon, 31 Oct 2022 13:28:14 +0900 Subject: [PATCH 27/29] =?UTF-8?q?CORS=E9=96=A2=E9=80=A3=E3=81=AE=E3=82=AA?= =?UTF-8?q?=E3=83=97=E3=82=B7=E3=83=A7=E3=83=B3=E3=82=92=E8=BF=BD=E5=8A=A0?= =?UTF-8?q?=20(#494)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * add cors options * parser add argument --force_cors_policy * typecast args.port to string * add allow_origin option * fix typo "-" to "--" * if allow_origin is empty then don't extend * CORS関連のオプションを追加 * CORS関連オプションのhelpを修正 * allow localhost * you can now select by cors_policy_mode * helpの複数指定方法を修正 * escape backslash * helpの細かい日本語表現を修正(区切って指定->区切って追加) * formatted * split strings and check format. * Added a warning for when "*" found in allow_origin. --- run.py | 29 ++++++++++++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) diff --git a/run.py b/run.py index 25f49cb12..3cfb0bb7f 100644 --- a/run.py +++ b/run.py @@ -110,10 +110,24 @@ def generate_app( version=__version__, ) + # CORS設定 + allowed_origins = ["*"] + if args.cors_policy_mode == "localapps": + allowed_origins = ["app://."] + if args.allow_origin: + allowed_origins += args.allow_origin + if "*" in args.allow_origin: + print( + 'WARNING: Deprecated use of argument "*" in allow_origin. ' + 'Use option "--cors_policy_mod all" instead. See "--help" for more.', + file=sys.stderr, + ) + app.add_middleware( CORSMiddleware, - allow_origins=["*"], + allow_origins=allowed_origins, allow_credentials=True, + allow_origin_regex="^https?://(localhost|127\\.0\\.0\\.1)(:[0-9]+)?$", allow_methods=["*"], allow_headers=["*"], ) @@ -900,6 +914,19 @@ def engine_manifest(): "VV_OUTPUT_LOG_UTF8 の値が1の場合はUTF-8で、0または空文字、値がない場合は環境によって自動的に決定されます。", ) + parser.add_argument( + "--cors_policy_mode", + choices=["all", "localapps"], + default="localapps", + help="allまたはlocalappsを指定。allはすべてを許可します。" + "localappsはオリジン間リソース共有ポリシーを、app://.とlocalhost関連に限定します。" + "その他のオリジンはallow_originオプションで追加できます。デフォルトはlocalapps。", + ) + + parser.add_argument( + "--allow_origin", nargs="*", help="許可するオリジンを指定します。複数指定する場合は、直後にスペースで区切って追加できます。" + ) + args = parser.parse_args() if args.output_log_utf8: From 50a8e9a04601831e12c21d33b2f24febc9a5c7e3 Mon Sep 17 00:00:00 2001 From: masinc Date: Mon, 31 Oct 2022 17:54:43 +0900 Subject: [PATCH 28/29] =?UTF-8?q?=E7=92=B0=E5=A2=83=E6=A7=8B=E7=AF=89?= =?UTF-8?q?=E6=99=82=E3=81=AE=E5=89=8D=E6=8F=90=E3=82=92=E8=BF=BD=E5=8A=A0?= =?UTF-8?q?=20(#498)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index efc236ca0..bcce613be 100644 --- a/README.md +++ b/README.md @@ -295,6 +295,7 @@ Issue 側で取り組み始めたことを伝えるか、最初に Draft プル ## 環境構築 `Python 3.8.10` を用いて開発されています。 +インストールするには、各 OS ごとの C/C++ コンパイラ、CMake が必要になります。 ```bash # 開発に必要なライブラリのインストール From 0dec9dc86cae4ef4f5bce4f16a4a00a7c1de062d Mon Sep 17 00:00:00 2001 From: Hiroshiba Date: Wed, 2 Nov 2022 02:16:45 +0900 Subject: [PATCH 29/29] =?UTF-8?q?cors=5Fpolicy=5Fmode=E3=81=A8allow=5Forig?= =?UTF-8?q?in=E3=82=92generate=5Fapp=E3=81=AE=E5=BC=95=E6=95=B0=E3=81=AB?= =?UTF-8?q?=E3=81=99=E3=82=8B=20(#500)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * cors_policy_modeとallow_originをgenerate_appの引数にする * breakpoint() --- run.py | 29 ++++++++++++++++++++++------- 1 file changed, 22 insertions(+), 7 deletions(-) diff --git a/run.py b/run.py index 3cfb0bb7f..2da9df0da 100644 --- a/run.py +++ b/run.py @@ -9,6 +9,7 @@ import traceback import zipfile from distutils.version import LooseVersion +from enum import Enum from functools import lru_cache from io import TextIOWrapper from pathlib import Path @@ -65,6 +66,11 @@ ) +class CorsPolicyMode(str, Enum): + all = "all" + localapps = "localapps" + + def b64encode_str(s): return base64.b64encode(s).decode("utf-8") @@ -98,6 +104,8 @@ def generate_app( synthesis_engines: Dict[str, SynthesisEngineBase], latest_core_version: str, root_dir: Optional[Path] = None, + cors_policy_mode: CorsPolicyMode = CorsPolicyMode.localapps, + allow_origin: Optional[List[str]] = None, ) -> FastAPI: if root_dir is None: root_dir = engine_root() @@ -112,11 +120,11 @@ def generate_app( # CORS設定 allowed_origins = ["*"] - if args.cors_policy_mode == "localapps": + if cors_policy_mode == "localapps": allowed_origins = ["app://."] - if args.allow_origin: - allowed_origins += args.allow_origin - if "*" in args.allow_origin: + if allow_origin is not None: + allowed_origins += allow_origin + if "*" in allow_origin: print( 'WARNING: Deprecated use of argument "*" in allow_origin. ' 'Use option "--cors_policy_mod all" instead. See "--help" for more.', @@ -916,8 +924,9 @@ def engine_manifest(): parser.add_argument( "--cors_policy_mode", - choices=["all", "localapps"], - default="localapps", + type=CorsPolicyMode, + choices=list(CorsPolicyMode), + default=CorsPolicyMode.localapps, help="allまたはlocalappsを指定。allはすべてを許可します。" "localappsはオリジン間リソース共有ポリシーを、app://.とlocalhost関連に限定します。" "その他のオリジンはallow_originオプションで追加できます。デフォルトはlocalapps。", @@ -952,7 +961,13 @@ def engine_manifest(): root_dir = args.voicevox_dir if args.voicevox_dir is not None else engine_root() uvicorn.run( - generate_app(synthesis_engines, latest_core_version, root_dir=root_dir), + generate_app( + synthesis_engines, + latest_core_version, + root_dir=root_dir, + cors_policy_mode=args.cors_policy_mode, + allow_origin=args.allow_origin, + ), host=args.host, port=args.port, )