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/
This commit is contained in:
@@ -36,7 +36,7 @@ dependencies = [
|
||||
'pydantic>=2.0',
|
||||
'pyopenjtalk-dict',
|
||||
'pypinyin',
|
||||
# 'pyworld',
|
||||
'pyworld-prebuilt',
|
||||
'safetensors',
|
||||
'scipy',
|
||||
'torch>=2.1,<2.2',
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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(
|
||||
|
||||
Reference in New Issue
Block a user