Spaces:
Running
Running
MarcusSu1216
commited on
Commit
•
b80e41a
1
Parent(s):
8d12e0c
Update inference_main.py
Browse files- inference_main.py +14 -50
inference_main.py
CHANGED
@@ -25,30 +25,27 @@ def main():
|
|
25 |
# 一定要设置的部分
|
26 |
parser.add_argument('-m', '--model_path', type=str, default="logs/44k/G_0.pth", help='模型路径')
|
27 |
parser.add_argument('-c', '--config_path', type=str, default="configs/config.json", help='配置文件路径')
|
28 |
-
parser.add_argument('-cl', '--clip', type=float, default=0, help='音频强制切片,默认0为自动切片,单位为秒/s')
|
29 |
parser.add_argument('-n', '--clean_names', type=str, nargs='+', default=["君の知らない物語-src.wav"], help='wav文件名列表,放在raw文件夹下')
|
30 |
parser.add_argument('-t', '--trans', type=int, nargs='+', default=[0], help='音高调整,支持正负(半音)')
|
31 |
parser.add_argument('-s', '--spk_list', type=str, nargs='+', default=['nen'], help='合成目标说话人名称')
|
32 |
|
33 |
# 可选项部分
|
34 |
-
parser.add_argument('-a', '--auto_predict_f0', action='store_true', default=False,
|
|
|
35 |
parser.add_argument('-cm', '--cluster_model_path', type=str, default="logs/44k/kmeans_10000.pt", help='聚类模型路径,如果没有训练聚类则随便填')
|
36 |
-
parser.add_argument('-cr', '--cluster_infer_ratio', type=float, default=0, help='聚类方案占比,范围0-1
|
37 |
-
|
38 |
-
parser.add_argument('-fmp', '--f0_mean_pooling', type=bool, default=False, help='是否对F0使用均值滤波器(池化),对部分哑音有改善。注意,启动该选项会导致推理速度下降,默认关闭')
|
39 |
-
parser.add_argument('-eh', '--enhance', type=bool, default=False, help='是否使用NSF_HIFIGAN增强器,该选项对部分训练集少的模型有一定的音质增强效果,但是对训练好的模型有反面效果,默认关闭')
|
40 |
-
|
41 |
# 不用动的部分
|
42 |
parser.add_argument('-sd', '--slice_db', type=int, default=-40, help='默认-40,嘈杂的音频可以-30,干声保留呼吸可以-50')
|
43 |
parser.add_argument('-d', '--device', type=str, default=None, help='推理设备,None则为自动选择cpu和gpu')
|
44 |
parser.add_argument('-ns', '--noice_scale', type=float, default=0.4, help='噪音级别,会影响咬字和音质,较为玄学')
|
45 |
parser.add_argument('-p', '--pad_seconds', type=float, default=0.5, help='推理音频pad秒数,由于未知原因开头结尾会有异响,pad一小段静音段后就不会出现')
|
46 |
parser.add_argument('-wf', '--wav_format', type=str, default='flac', help='音频输出格式')
|
47 |
-
|
48 |
-
parser.add_argument('-eak', '--enhancer_adaptive_key', type=int, default=0, help='使增强器适应更高的音域(单位为半音数)|默认为0')
|
49 |
-
|
50 |
args = parser.parse_args()
|
51 |
|
|
|
|
|
52 |
clean_names = args.clean_names
|
53 |
trans = args.trans
|
54 |
spk_list = args.spk_list
|
@@ -58,15 +55,6 @@ def main():
|
|
58 |
cluster_infer_ratio = args.cluster_infer_ratio
|
59 |
noice_scale = args.noice_scale
|
60 |
pad_seconds = args.pad_seconds
|
61 |
-
clip = args.clip
|
62 |
-
lg = args.linear_gradient
|
63 |
-
lgr = args.linear_gradient_retain
|
64 |
-
F0_mean_pooling = args.f0_mean_pooling
|
65 |
-
enhance = args.enhance
|
66 |
-
enhancer_adaptive_key = args.enhancer_adaptive_key
|
67 |
-
|
68 |
-
svc_model = Svc(args.model_path, args.config_path, args.device, args.cluster_model_path,enhance)
|
69 |
-
infer_tool.mkdir(["raw", "results"])
|
70 |
|
71 |
infer_tool.fill_a_to_b(trans, clean_names)
|
72 |
for clean_name, tran in zip(clean_names, trans):
|
@@ -77,61 +65,37 @@ def main():
|
|
77 |
wav_path = Path(raw_audio_path).with_suffix('.wav')
|
78 |
chunks = slicer.cut(wav_path, db_thresh=slice_db)
|
79 |
audio_data, audio_sr = slicer.chunks2audio(wav_path, chunks)
|
80 |
-
per_size = int(clip*audio_sr)
|
81 |
-
lg_size = int(lg*audio_sr)
|
82 |
-
lg_size_r = int(lg_size*lgr)
|
83 |
-
lg_size_c_l = (lg_size-lg_size_r)//2
|
84 |
-
lg_size_c_r = lg_size-lg_size_r-lg_size_c_l
|
85 |
-
lg = np.linspace(0,1,lg_size_r) if lg_size!=0 else 0
|
86 |
|
87 |
for spk in spk_list:
|
88 |
audio = []
|
89 |
for (slice_tag, data) in audio_data:
|
90 |
print(f'#=====segment start, {round(len(data) / audio_sr, 3)}s======')
|
91 |
-
|
92 |
length = int(np.ceil(len(data) / audio_sr * svc_model.target_sample))
|
93 |
if slice_tag:
|
94 |
print('jump empty segment')
|
95 |
_audio = np.zeros(length)
|
96 |
-
audio.extend(list(infer_tool.pad_array(_audio, length)))
|
97 |
-
continue
|
98 |
-
if per_size != 0:
|
99 |
-
datas = infer_tool.split_list_by_n(data, per_size,lg_size)
|
100 |
else:
|
101 |
-
datas = [data]
|
102 |
-
for k,dat in enumerate(datas):
|
103 |
-
per_length = int(np.ceil(len(dat) / audio_sr * svc_model.target_sample)) if clip!=0 else length
|
104 |
-
if clip!=0: print(f'###=====segment clip start, {round(len(dat) / audio_sr, 3)}s======')
|
105 |
# padd
|
106 |
pad_len = int(audio_sr * pad_seconds)
|
107 |
-
|
108 |
raw_path = io.BytesIO()
|
109 |
-
soundfile.write(raw_path,
|
110 |
raw_path.seek(0)
|
111 |
out_audio, out_sr = svc_model.infer(spk, tran, raw_path,
|
112 |
cluster_infer_ratio=cluster_infer_ratio,
|
113 |
auto_predict_f0=auto_predict_f0,
|
114 |
-
noice_scale=noice_scale
|
115 |
-
F0_mean_pooling = F0_mean_pooling,
|
116 |
-
enhancer_adaptive_key = enhancer_adaptive_key
|
117 |
)
|
118 |
_audio = out_audio.cpu().numpy()
|
119 |
pad_len = int(svc_model.target_sample * pad_seconds)
|
120 |
_audio = _audio[pad_len:-pad_len]
|
121 |
-
|
122 |
-
|
123 |
-
lg1 = audio[-(lg_size_r+lg_size_c_r):-lg_size_c_r] if lgr != 1 else audio[-lg_size:]
|
124 |
-
lg2 = _audio[lg_size_c_l:lg_size_c_l+lg_size_r] if lgr != 1 else _audio[0:lg_size]
|
125 |
-
lg_pre = lg1*(1-lg)+lg2*lg
|
126 |
-
audio = audio[0:-(lg_size_r+lg_size_c_r)] if lgr != 1 else audio[0:-lg_size]
|
127 |
-
audio.extend(lg_pre)
|
128 |
-
_audio = _audio[lg_size_c_l+lg_size_r:] if lgr != 1 else _audio[lg_size:]
|
129 |
-
audio.extend(list(_audio))
|
130 |
key = "auto" if auto_predict_f0 else f"{tran}key"
|
131 |
cluster_name = "" if cluster_infer_ratio == 0 else f"_{cluster_infer_ratio}"
|
132 |
res_path = f'./results/{clean_name}_{key}_{spk}{cluster_name}.{wav_format}'
|
133 |
soundfile.write(res_path, audio, svc_model.target_sample, format=wav_format)
|
134 |
-
|
135 |
-
|
136 |
if __name__ == '__main__':
|
137 |
main()
|
|
|
25 |
# 一定要设置的部分
|
26 |
parser.add_argument('-m', '--model_path', type=str, default="logs/44k/G_0.pth", help='模型路径')
|
27 |
parser.add_argument('-c', '--config_path', type=str, default="configs/config.json", help='配置文件路径')
|
|
|
28 |
parser.add_argument('-n', '--clean_names', type=str, nargs='+', default=["君の知らない物語-src.wav"], help='wav文件名列表,放在raw文件夹下')
|
29 |
parser.add_argument('-t', '--trans', type=int, nargs='+', default=[0], help='音高调整,支持正负(半音)')
|
30 |
parser.add_argument('-s', '--spk_list', type=str, nargs='+', default=['nen'], help='合成目标说话人名称')
|
31 |
|
32 |
# 可选项部分
|
33 |
+
parser.add_argument('-a', '--auto_predict_f0', action='store_true', default=False,
|
34 |
+
help='语音转换自动预测音高,转换歌声时不要打开这个会严重跑调')
|
35 |
parser.add_argument('-cm', '--cluster_model_path', type=str, default="logs/44k/kmeans_10000.pt", help='聚类模型路径,如果没有训练聚类则随便填')
|
36 |
+
parser.add_argument('-cr', '--cluster_infer_ratio', type=float, default=0, help='聚类方案占比,范围0-1,若没有训练聚类模型则填0即可')
|
37 |
+
|
|
|
|
|
|
|
38 |
# 不用动的部分
|
39 |
parser.add_argument('-sd', '--slice_db', type=int, default=-40, help='默认-40,嘈杂的音频可以-30,干声保留呼吸可以-50')
|
40 |
parser.add_argument('-d', '--device', type=str, default=None, help='推理设备,None则为自动选择cpu和gpu')
|
41 |
parser.add_argument('-ns', '--noice_scale', type=float, default=0.4, help='噪音级别,会影响咬字和音质,较为玄学')
|
42 |
parser.add_argument('-p', '--pad_seconds', type=float, default=0.5, help='推理音频pad秒数,由于未知原因开头结尾会有异响,pad一小段静音段后就不会出现')
|
43 |
parser.add_argument('-wf', '--wav_format', type=str, default='flac', help='音频输出格式')
|
44 |
+
|
|
|
|
|
45 |
args = parser.parse_args()
|
46 |
|
47 |
+
svc_model = Svc(args.model_path, args.config_path, args.device, args.cluster_model_path)
|
48 |
+
infer_tool.mkdir(["raw", "results"])
|
49 |
clean_names = args.clean_names
|
50 |
trans = args.trans
|
51 |
spk_list = args.spk_list
|
|
|
55 |
cluster_infer_ratio = args.cluster_infer_ratio
|
56 |
noice_scale = args.noice_scale
|
57 |
pad_seconds = args.pad_seconds
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
58 |
|
59 |
infer_tool.fill_a_to_b(trans, clean_names)
|
60 |
for clean_name, tran in zip(clean_names, trans):
|
|
|
65 |
wav_path = Path(raw_audio_path).with_suffix('.wav')
|
66 |
chunks = slicer.cut(wav_path, db_thresh=slice_db)
|
67 |
audio_data, audio_sr = slicer.chunks2audio(wav_path, chunks)
|
|
|
|
|
|
|
|
|
|
|
|
|
68 |
|
69 |
for spk in spk_list:
|
70 |
audio = []
|
71 |
for (slice_tag, data) in audio_data:
|
72 |
print(f'#=====segment start, {round(len(data) / audio_sr, 3)}s======')
|
73 |
+
|
74 |
length = int(np.ceil(len(data) / audio_sr * svc_model.target_sample))
|
75 |
if slice_tag:
|
76 |
print('jump empty segment')
|
77 |
_audio = np.zeros(length)
|
|
|
|
|
|
|
|
|
78 |
else:
|
|
|
|
|
|
|
|
|
79 |
# padd
|
80 |
pad_len = int(audio_sr * pad_seconds)
|
81 |
+
data = np.concatenate([np.zeros([pad_len]), data, np.zeros([pad_len])])
|
82 |
raw_path = io.BytesIO()
|
83 |
+
soundfile.write(raw_path, data, audio_sr, format="wav")
|
84 |
raw_path.seek(0)
|
85 |
out_audio, out_sr = svc_model.infer(spk, tran, raw_path,
|
86 |
cluster_infer_ratio=cluster_infer_ratio,
|
87 |
auto_predict_f0=auto_predict_f0,
|
88 |
+
noice_scale=noice_scale
|
|
|
|
|
89 |
)
|
90 |
_audio = out_audio.cpu().numpy()
|
91 |
pad_len = int(svc_model.target_sample * pad_seconds)
|
92 |
_audio = _audio[pad_len:-pad_len]
|
93 |
+
|
94 |
+
audio.extend(list(infer_tool.pad_array(_audio, length)))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
95 |
key = "auto" if auto_predict_f0 else f"{tran}key"
|
96 |
cluster_name = "" if cluster_infer_ratio == 0 else f"_{cluster_infer_ratio}"
|
97 |
res_path = f'./results/{clean_name}_{key}_{spk}{cluster_name}.{wav_format}'
|
98 |
soundfile.write(res_path, audio, svc_model.target_sample, format=wav_format)
|
99 |
+
|
|
|
100 |
if __name__ == '__main__':
|
101 |
main()
|