From be265d42ed1a946bbb4bcc12d76fe9ab01da59b2 Mon Sep 17 00:00:00 2001 From: tsukumi Date: Sun, 10 Mar 2024 16:51:58 +0000 Subject: [PATCH] Improve: switch pyworld to pyworld-prebuilt and enable it by default Prebuilt wheels for almost every OS/architecture (except musl) are now available on PyPI, eliminating the need for a build environment. ref: https://pypi.org/project/pyworld-prebuilt/ --- pyproject.toml | 2 +- requirements.txt | 2 +- style_bert_vits2/voice.py | 30 ++++++++++++++++++------------ webui/inference.py | 2 -- 4 files changed, 20 insertions(+), 16 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 0a1bd99..870c3b2 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -36,7 +36,7 @@ dependencies = [ 'pydantic>=2.0', 'pyopenjtalk-dict', 'pypinyin', - # 'pyworld', + 'pyworld-prebuilt', 'safetensors', 'scipy', 'torch>=2.1,<2.2', diff --git a/requirements.txt b/requirements.txt index 75dbdcd..bf47ec0 100644 --- a/requirements.txt +++ b/requirements.txt @@ -19,7 +19,7 @@ pyloudnorm # pyopenjtalk-prebuilt # Should be manually uninstalled pyopenjtalk-dict pypinyin -# pyworld # Not supported on Windows without Cython... +pyworld-prebuilt PyYAML requests safetensors diff --git a/style_bert_vits2/voice.py b/style_bert_vits2/voice.py index f1cfcac..ed7843f 100644 --- a/style_bert_vits2/voice.py +++ b/style_bert_vits2/voice.py @@ -1,6 +1,7 @@ from typing import Any import numpy as np +import pyworld from numpy.typing import NDArray @@ -10,29 +11,34 @@ def adjust_voice( pitch_scale: float = 1.0, intonation_scale: float = 1.0, ) -> tuple[int, NDArray[Any]]: + """ + 音声のピッチとイントネーションを調整する。 + 変更すると若干音質が劣化するので、どちらも初期値のままならそのまま返す。 + + Args: + fs (int): 音声のサンプリング周波数 + wave (NDArray[Any]): 音声データ + pitch_scale (float, optional): ピッチの高さ. Defaults to 1.0. + intonation_scale (float, optional): イントネーションの高さ. Defaults to 1.0. + + Returns: + tuple[int, NDArray[Any]]: 調整後の音声データのサンプリング周波数と音声データ + """ if pitch_scale == 1.0 and intonation_scale == 1.0: # 初期値の場合は、音質劣化を避けるためにそのまま返す return fs, wave - try: - import pyworld - except ImportError: - raise ImportError( - "pyworld is not installed. Please install it by `pip install pyworld`" - ) - # pyworld で f0 を加工して合成 # pyworld よりもよいのがあるかもしれないが…… - ## pyworld は Cython で書かれているが、スタブファイルがないため型補完が全く効かない… wave = wave.astype(np.double) # 質が高そうだしとりあえずharvestにしておく - f0, t = pyworld.harvest(wave, fs) # type: ignore + f0, t = pyworld.harvest(wave, fs) - sp = pyworld.cheaptrick(wave, f0, t, fs) # type: ignore - ap = pyworld.d4c(wave, f0, t, fs) # type: ignore + sp = pyworld.cheaptrick(wave, f0, t, fs) + ap = pyworld.d4c(wave, f0, t, fs) non_zero_f0 = [f for f in f0 if f != 0] f0_mean = sum(non_zero_f0) / len(non_zero_f0) @@ -42,5 +48,5 @@ def adjust_voice( continue f0[i] = pitch_scale * f0_mean + intonation_scale * (f - f0_mean) - wave = pyworld.synthesize(f0, sp, ap, fs) # type: ignore + wave = pyworld.synthesize(f0, sp, ap, fs) return fs, wave diff --git a/webui/inference.py b/webui/inference.py index e32907c..91baed5 100644 --- a/webui/inference.py +++ b/webui/inference.py @@ -294,7 +294,6 @@ def create_inference_app(model_holder: TTSModelHolder) -> gr.Blocks: value=1, step=0.05, label="音程(1以外では音質劣化)", - visible=False, # pyworldが必要 ) intonation_scale = gr.Slider( minimum=0, @@ -302,7 +301,6 @@ def create_inference_app(model_holder: TTSModelHolder) -> gr.Blocks: value=1, step=0.1, label="抑揚(1以外では音質劣化)", - visible=False, # pyworldが必要 ) line_split = gr.Checkbox(