add localization(添加本地化) (#35)

* add i18n

* Add gui.py as target

* update

* Update extract_locale.py
This commit is contained in:
唐澤 克幸 2023-04-12 11:48:39 +09:00 committed by GitHub
parent 8143197b3f
commit 72d37119de
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 419 additions and 199 deletions

28
extract_locale.py Normal file
View File

@ -0,0 +1,28 @@
import json
import re
# Define regular expression patterns
pattern = r'i18n\([^)]*\)'
# Initialize the dictionary to store key-value pairs
data = {}
# Extract labels from infer-webui.py
with open('infer-web.py', 'r', encoding='utf-8') as f:
contents = f.read()
matches = re.findall(pattern, contents)
for match in matches:
key = match.strip('()"')
data[key] = key
# Extract labels from gui.py
with open('gui.py', 'r', encoding='utf-8') as f:
contents = f.read()
matches = re.findall(pattern, contents)
for match in matches:
key = match.strip('()"')
data[key] = key
# Save as a JSON file
with open('./locale/zh_CN.json', 'w', encoding='utf-8') as f:
json.dump(data, f, ensure_ascii=False, indent=4)

26
gui.py
View File

@ -5,10 +5,10 @@ import numpy as np
from fairseq import checkpoint_utils
import librosa,torch,parselmouth,faiss,time,threading
import torch.nn.functional as F
#import matplotlib.pyplot as plt
from infer_pack.models import SynthesizerTrnMs256NSFsid, SynthesizerTrnMs256NSFsid_nono
from language import language_gui
from webui_locale import I18nAuto
i18n = I18nAuto()
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
@ -170,24 +170,24 @@ class GUI:
sg.Frame(layout=[
[sg.Text(i18n("输入设备/Input Device")),sg.Combo(input_devices,key='sg_input_device',default_value=input_devices[sd.default.device[0]])],
[sg.Text(i18n("输出设备/Output Device")),sg.Combo(output_devices,key='sg_output_device',default_value=output_devices[sd.default.device[1]])]
],title=i18n('音频设备(请使用同种类驱动)/Audio Devices'))
],title=i18n("音频设备(请使用同种类驱动)/Audio Devices"))
],
[
sg.Frame(layout=[
[sg.Text(i18n('响应阈值/Silence Threhold')),sg.Slider(range=(-60,0),key='threhold',resolution=1,orientation='h',default_value=-30)],
[sg.Text(i18n("响应阈值/Silence Threhold")),sg.Slider(range=(-60,0),key='threhold',resolution=1,orientation='h',default_value=-30)],
[sg.Text(i18n("音调设置/Pitch Offset")),sg.Slider(range=(-24,24),key='pitch',resolution=1,orientation='h',default_value=12)]
],title=i18n('常规设置/Common')),
],title=i18n("常规设置/Common")),
sg.Frame(layout=[
[sg.Text(i18n('采样长度/Sample Length')),sg.Slider(range=(0.1,3.0),key='block_time',resolution=0.1,orientation='h',default_value=1.0)],
[sg.Text(i18n('淡入淡出长度/Crossfade Length')),sg.Slider(range=(0.01,0.15),key='crossfade_length',resolution=0.01,orientation='h',default_value=0.08)],
[sg.Text(i18n('额外推理时长/Extra Length')),sg.Slider(range=(0.05,3.00),key='extra_time',resolution=0.01,orientation='h',default_value=0.05)]
],title=i18n('性能设置/Performance'))
[sg.Text(i18n("采样长度/Sample Length")),sg.Slider(range=(0.1,3.0),key='block_time',resolution=0.1,orientation='h',default_value=1.0)],
[sg.Text(i18n("淡入淡出长度/Crossfade Length")),sg.Slider(range=(0.01,0.15),key='crossfade_length',resolution=0.01,orientation='h',default_value=0.08)],
[sg.Text(i18n("额外推理时长/Extra Length")),sg.Slider(range=(0.05,3.00),key='extra_time',resolution=0.01,orientation='h',default_value=0.05)]
],title=i18n("性能设置/Performance"))
],
[sg.Button(i18n('开始音频转换'),key='start_vc'),sg.Button(i18n('停止音频转换'),key='stop_vc')]
[sg.Button(i18n("开始音频转换"),key='start_vc'),sg.Button(i18n("停止音频转换"),key='stop_vc')]
]
self.window=sg.Window('RVC - GUI',layout=layout)
self.window=sg.Window("RVC - GUI",layout=layout)
self.event_handler()
def event_handler(self):
@ -325,6 +325,4 @@ class GUI:
sd.default.device[0]=input_device_indices[input_devices.index(input_device)]
sd.default.device[1]=output_device_indices[output_devices.index(output_device)]
print("input device:"+str(sd.default.device[0])+":"+str(input_device))
print("output device:"+str(sd.default.device[1])+":"+str(output_device))
i18n = language_gui.I18nAuto()
gui=GUI()
print("output device:"+str(sd.default.device[1])+":"+str(output_device))

View File

@ -5,6 +5,8 @@ from subprocess import Popen
from time import sleep
import torch, os,traceback,sys,warnings,shutil,numpy as np
import faiss
from webui_locale import I18nAuto
i18n = I18nAuto()
#判断是否有能用来训练和加速推理的N卡
ncpu=cpu_count()
ngpu=torch.cuda.device_count()
@ -457,22 +459,22 @@ def change_info_(ckpt_path):
with gr.Blocks() as app:
gr.Markdown(value="""
gr.Markdown(value=i18n("""
本软件以MIT协议开源作者不对软件具备任何控制力使用软件者传播软件导出的声音者自负全责<br>
如不认可该条款则不能使用或引用软件包内任何代码和文件详见根目录"使用需遵守的协议-LICENSE.txt"
""")
"""))
with gr.Tabs():
with gr.TabItem("模型推理"):
with gr.TabItem(i18n("模型推理")):
with gr.Row():
sid0 = gr.Dropdown(label="推理音色", choices=sorted(names))
refresh_button = gr.Button("刷新音色列表", variant="primary")
sid0 = gr.Dropdown(label=i18n("推理音色"), choices=sorted(names))
refresh_button = gr.Button(i18n("刷新音色列表"), variant="primary")
refresh_button.click(
fn=change_choices,
inputs=[],
outputs=[sid0]
)
clean_button = gr.Button("卸载音色省显存", variant="primary")
spk_item = gr.Slider(minimum=0, maximum=2333, step=1, label='请选择说话人id', value=0, visible=False, interactive=True)
clean_button = gr.Button(i18n("卸载音色省显存"), variant="primary")
spk_item = gr.Slider(minimum=0, maximum=2333, step=1, label=i18n("请选择说话人id"), value=0, visible=False, interactive=True)
clean_button.click(
fn=clean,
inputs=[],
@ -484,169 +486,169 @@ with gr.Blocks() as app:
outputs=[spk_item],
)
with gr.Group():
gr.Markdown(value="""
gr.Markdown(value=i18n("""
男转女推荐+12key女转男推荐-12key如果音域爆炸导致音色失真也可以自己调整到合适音域
""")
"""))
with gr.Row():
with gr.Column():
vc_transform0 = gr.Number(label="变调整数半音数量升八度12降八度-12", value=0)
input_audio0 = gr.Textbox(label="输入待处理音频文件路径(默认是正确格式示例)",value="E:\codes\py39\\vits_vc_gpu_train\\todo-songs\冬之花clip1.wav")
f0method0=gr.Radio(label="选择音高提取算法,输入歌声可用pm提速,harvest低音好但巨慢无比", choices=["pm","harvest"],value="pm", interactive=True)
vc_transform0 = gr.Number(label=i18n("变调整数半音数量升八度12降八度-12"), value=0)
input_audio0 = gr.Textbox(label=i18n("输入待处理音频文件路径(默认是正确格式示例)"),value="E:\codes\py39\\vits_vc_gpu_train\\todo-songs\冬之花clip1.wav")
f0method0=gr.Radio(label=i18n("选择音高提取算法,输入歌声可用pm提速,harvest低音好但巨慢无比"), choices=["pm","harvest"],value="pm", interactive=True)
with gr.Column():
file_index1 = gr.Textbox(label="特征检索库文件路径",value="E:\codes\py39\\vits_vc_gpu_train\logs\mi-test-1key\\added_IVF677_Flat_nprobe_7.index", interactive=True)
file_big_npy1 = gr.Textbox(label="特征文件路径",value="E:\codes\py39\\vits_vc_gpu_train\logs\mi-test-1key\\total_fea.npy", interactive=True)
file_index1 = gr.Textbox(label=i18n("特征检索库文件路径"),value="E:\codes\py39\\vits_vc_gpu_train\logs\mi-test-1key\\added_IVF677_Flat_nprobe_7.index", interactive=True)
file_big_npy1 = gr.Textbox(label=i18n("特征文件路径"),value="E:\codes\py39\\vits_vc_gpu_train\logs\mi-test-1key\\total_fea.npy", interactive=True)
index_rate1 = gr.Slider(minimum=0, maximum=1,label='检索特征占比', value=1,interactive=True)
f0_file = gr.File(label="F0曲线文件可选一行一个音高代替默认F0及升降调")
but0=gr.Button("转换", variant="primary")
f0_file = gr.File(label=i18n("F0曲线文件可选一行一个音高代替默认F0及升降调"))
but0=gr.Button(i18n("转换"), variant="primary")
with gr.Column():
vc_output1 = gr.Textbox(label="输出信息")
vc_output2 = gr.Audio(label="输出音频(右下角三个点,点了可以下载)")
vc_output1 = gr.Textbox(label=i18n("输出信息"))
vc_output2 = gr.Audio(label=i18n("输出音频(右下角三个点,点了可以下载)"))
but0.click(vc_single, [spk_item, input_audio0, vc_transform0,f0_file,f0method0,file_index1,file_big_npy1,index_rate1], [vc_output1, vc_output2])
with gr.Group():
gr.Markdown(value="""
gr.Markdown(value=i18n("""
批量转换输入待转换音频文件夹或上传多个音频文件在指定文件夹默认opt下输出转换的音频
""")
"""))
with gr.Row():
with gr.Column():
vc_transform1 = gr.Number(label="变调整数半音数量升八度12降八度-12", value=0)
opt_input = gr.Textbox(label="指定输出文件夹",value="opt")
f0method1=gr.Radio(label="选择音高提取算法,输入歌声可用pm提速,harvest低音好但巨慢无比", choices=["pm","harvest"],value="pm", interactive=True)
vc_transform1 = gr.Number(label=i18n("变调整数半音数量升八度12降八度-12"), value=0)
opt_input = gr.Textbox(label=i18n("指定输出文件夹"),value="opt")
f0method1=gr.Radio(label=i18n("选择音高提取算法,输入歌声可用pm提速,harvest低音好但巨慢无比"), choices=["pm","harvest"],value="pm", interactive=True)
with gr.Column():
file_index2 = gr.Textbox(label="特征检索库文件路径",value="E:\codes\py39\\vits_vc_gpu_train\logs\mi-test-1key\\added_IVF677_Flat_nprobe_7.index", interactive=True)
file_big_npy2 = gr.Textbox(label="特征文件路径",value="E:\codes\py39\\vits_vc_gpu_train\logs\mi-test-1key\\total_fea.npy", interactive=True)
index_rate2 = gr.Slider(minimum=0, maximum=1,label='检索特征占比', value=1,interactive=True)
file_index2 = gr.Textbox(label=i18n("特征检索库文件路径"),value="E:\codes\py39\\vits_vc_gpu_train\logs\mi-test-1key\\added_IVF677_Flat_nprobe_7.index", interactive=True)
file_big_npy2 = gr.Textbox(label=i18n("特征文件路径"),value="E:\codes\py39\\vits_vc_gpu_train\logs\mi-test-1key\\total_fea.npy", interactive=True)
index_rate2 = gr.Slider(minimum=0, maximum=1,label=i18n("检索特征占比"), value=1,interactive=True)
with gr.Column():
dir_input = gr.Textbox(label="输入待处理音频文件夹路径(去文件管理器地址栏拷就行了)",value="E:\codes\py39\\vits_vc_gpu_train\\todo-songs")
inputs = gr.File(file_count="multiple", label="也可批量输入音频文件,二选一,优先读文件夹")
but1=gr.Button("转换", variant="primary")
vc_output3 = gr.Textbox(label="输出信息")
dir_input = gr.Textbox(label=i18n("输入待处理音频文件夹路径(去文件管理器地址栏拷就行了)"),value="E:\codes\py39\\vits_vc_gpu_train\\todo-songs")
inputs = gr.File(file_count="multiple", label=i18n("也可批量输入音频文件,二选一,优先读文件夹"))
but1=gr.Button(i18n("转换"), variant="primary")
vc_output3 = gr.Textbox(label=i18n("输出信息"))
but1.click(vc_multi, [spk_item, dir_input,opt_input,inputs, vc_transform1,f0method1,file_index2,file_big_npy2,index_rate2], [vc_output3])
with gr.TabItem("伴奏人声分离"):
with gr.TabItem(i18n("伴奏人声分离")):
with gr.Group():
gr.Markdown(value="""
gr.Markdown(value=i18n("""
人声伴奏分离批量处理使用UVR5模型<br>
不带和声用HP2带和声且提取的人声不需要和声用HP5<br>
合格的文件夹路径格式举例E:\codes\py39\\vits_vc_gpu\白鹭霜华测试样例去文件管理器地址栏拷就行了
""")
"""))
with gr.Row():
with gr.Column():
dir_wav_input = gr.Textbox(label="输入待处理音频文件夹路径",value="E:\codes\py39\\vits_vc_gpu_train\\todo-songs")
wav_inputs = gr.File(file_count="multiple", label="也可批量输入音频文件,二选一,优先读文件夹")
dir_wav_input = gr.Textbox(label=i18n("输入待处理音频文件夹路径"),value="E:\codes\py39\\vits_vc_gpu_train\\todo-songs")
wav_inputs = gr.File(file_count="multiple", label=i18n("也可批量输入音频文件,二选一,优先读文件夹"))
with gr.Column():
model_choose = gr.Dropdown(label="模型", choices=uvr5_names)
opt_vocal_root = gr.Textbox(label="指定输出人声文件夹",value="opt")
opt_ins_root = gr.Textbox(label="指定输出乐器文件夹",value="opt")
but2=gr.Button("转换", variant="primary")
vc_output4 = gr.Textbox(label="输出信息")
model_choose = gr.Dropdown(label=i18n("模型"), choices=uvr5_names)
opt_vocal_root = gr.Textbox(label=i18n("指定输出人声文件夹"),value="opt")
opt_ins_root = gr.Textbox(label=i18n("指定输出乐器文件夹"),value="opt")
but2=gr.Button(i18n("转换"), variant="primary")
vc_output4 = gr.Textbox(label=i18n("输出信息"))
but2.click(uvr, [model_choose, dir_wav_input,opt_vocal_root,wav_inputs,opt_ins_root], [vc_output4])
with gr.TabItem("训练"):
gr.Markdown(value="""
with gr.TabItem(i18n("训练")):
gr.Markdown(value=i18n("""
step1填写实验配置实验数据放在logs下每个实验一个文件夹需手工输入实验名路径内含实验配置日志训练得到的模型文件
""")
"""))
with gr.Row():
exp_dir1 = gr.Textbox(label="输入实验名",value="mi-test")
sr2 = gr.Radio(label="目标采样率", choices=["32k","40k","48k"],value="40k", interactive=True)
if_f0_3 = gr.Radio(label="模型是否带音高指导(唱歌一定要,语音可以不要)", choices=["",""],value="", interactive=True)
exp_dir1 = gr.Textbox(label=i18n("输入实验名"),value="mi-test")
sr2 = gr.Radio(label=i18n("目标采样率"), choices=["32k","40k","48k"],value="40k", interactive=True)
if_f0_3 = gr.Radio(label=i18n("模型是否带音高指导(唱歌一定要,语音可以不要)"), choices=["",""],value="", interactive=True)
with gr.Group():#暂时单人的后面支持最多4人的#数据处理
gr.Markdown(value="""
gr.Markdown(value=i18n("""
step2a自动遍历训练文件夹下所有可解码成音频的文件并进行切片归一化在实验目录下生成2个wav文件夹暂时只支持单人训练
""")
"""))
with gr.Row():
trainset_dir4 = gr.Textbox(label="输入训练文件夹路径",value="E:\语音音频+标注\米津玄师\src")
spk_id5 = gr.Slider(minimum=0, maximum=4, step=1, label='请指定说话人id', value=0,interactive=True)
but1=gr.Button("处理数据", variant="primary")
info1=gr.Textbox(label="输出信息",value="")
trainset_dir4 = gr.Textbox(label=i18n("输入训练文件夹路径"),value="E:\语音音频+标注\米津玄师\src")
spk_id5 = gr.Slider(minimum=0, maximum=4, step=1, label=i18n("请指定说话人id"), value=0,interactive=True)
but1=gr.Button(i18n("处理数据"), variant="primary")
info1=gr.Textbox(label=i18n("输出信息"),value="")
but1.click(preprocess_dataset,[trainset_dir4,exp_dir1,sr2],[info1])
with gr.Group():
gr.Markdown(value="""
gr.Markdown(value=i18n("""
step2b使用CPU提取音高(如果模型带音高)使用GPU提取特征(选择卡号)
""")
"""))
with gr.Row():
with gr.Column():
gpus6 = gr.Textbox(label="以-分隔输入使用的卡号,例如 0-1-2 使用卡0和卡1和卡2",value=gpus,interactive=True)
gpu_info9 = gr.Textbox(label="显卡信息",value=gpu_info)
gpus6 = gr.Textbox(label=i18n("以-分隔输入使用的卡号,例如 0-1-2 使用卡0和卡1和卡2"),value=gpus,interactive=True)
gpu_info9 = gr.Textbox(label=i18n("显卡信息"),value=gpu_info)
with gr.Column():
np7 = gr.Slider(minimum=0, maximum=ncpu, step=1, label='提取音高使用的CPU进程数', value=ncpu,interactive=True)
f0method8 = gr.Radio(label="选择音高提取算法:输入歌声可用pm提速,高质量语音但CPU差可用dio提速,harvest质量更好但慢", choices=["pm", "harvest","dio"], value="harvest", interactive=True)
but2=gr.Button("特征提取", variant="primary")
info2=gr.Textbox(label="输出信息",value="",max_lines=8)
np7 = gr.Slider(minimum=0, maximum=ncpu, step=1, label=i18n("提取音高使用的CPU进程数"), value=ncpu,interactive=True)
f0method8 = gr.Radio(label=i18n("选择音高提取算法:输入歌声可用pm提速,高质量语音但CPU差可用dio提速,harvest质量更好但慢"), choices=["pm", "harvest","dio"], value="harvest", interactive=True)
but2=gr.Button(i18n("特征提取"), variant="primary")
info2=gr.Textbox(label=i18n("输出信息"),value="",max_lines=8)
but2.click(extract_f0_feature,[gpus6,np7,f0method8,if_f0_3,exp_dir1],[info2])
with gr.Group():
gr.Markdown(value="""
gr.Markdown(value=i18n("""
step3填写训练设置开始训练模型和索引
""")
"""))
with gr.Row():
save_epoch10 = gr.Slider(minimum=0, maximum=50, step=1, label='保存频率save_every_epoch', value=5,interactive=True)
total_epoch11 = gr.Slider(minimum=0, maximum=1000, step=1, label='总训练轮数total_epoch', value=20,interactive=True)
save_epoch10 = gr.Slider(minimum=0, maximum=50, step=1, label=i18n("保存频率save_every_epoch"), value=5,interactive=True)
total_epoch11 = gr.Slider(minimum=0, maximum=1000, step=1, label=i18n("总训练轮数total_epoch"), value=20,interactive=True)
batch_size12 = gr.Slider(minimum=0, maximum=32, step=1, label='每张显卡的batch_size', value=4,interactive=True)
if_save_latest13 = gr.Radio(label="是否仅保存最新的ckpt文件以节省硬盘空间", choices=["", ""], value="", interactive=True)
if_cache_gpu17 = gr.Radio(label="是否缓存所有训练集至显存。10min以下小数据可缓存以加速训练大数据缓存会炸显存也加不了多少速", choices=["", ""], value="", interactive=True)
if_save_latest13 = gr.Radio(label=i18n("是否仅保存最新的ckpt文件以节省硬盘空间"), choices=["", ""], value="", interactive=True)
if_cache_gpu17 = gr.Radio(label=i18n("是否缓存所有训练集至显存。10min以下小数据可缓存以加速训练大数据缓存会炸显存也加不了多少速"), choices=["", ""], value="", interactive=True)
with gr.Row():
pretrained_G14 = gr.Textbox(label="加载预训练底模G路径", value="pretrained/f0G40k.pth",interactive=True)
pretrained_D15 = gr.Textbox(label="加载预训练底模D路径", value="pretrained/f0D40k.pth",interactive=True)
pretrained_G14 = gr.Textbox(label=i18n("加载预训练底模G路径"), value="pretrained/f0G40k.pth",interactive=True)
pretrained_D15 = gr.Textbox(label=i18n("加载预训练底模D路径"), value="pretrained/f0D40k.pth",interactive=True)
sr2.change(change_sr2, [sr2,if_f0_3], [pretrained_G14,pretrained_D15])
if_f0_3.change(change_f0, [if_f0_3, sr2], [np7, f0method8, pretrained_G14, pretrained_D15])
gpus16 = gr.Textbox(label="以-分隔输入使用的卡号,例如 0-1-2 使用卡0和卡1和卡2", value=gpus,interactive=True)
but3 = gr.Button("训练模型", variant="primary")
but4 = gr.Button("训练特征索引", variant="primary")
but5 = gr.Button("一键训练", variant="primary")
info3 = gr.Textbox(label="输出信息", value="",max_lines=10)
gpus16 = gr.Textbox(label=i18n("以-分隔输入使用的卡号,例如 0-1-2 使用卡0和卡1和卡2"), value=gpus,interactive=True)
but3 = gr.Button(i18n("训练模型"), variant="primary")
but4 = gr.Button(i18n("训练特征索引"), variant="primary")
but5 = gr.Button(i18n("一键训练"), variant="primary")
info3 = gr.Textbox(label=i18n("输出信息"), value="",max_lines=10)
but3.click(click_train,[exp_dir1,sr2,if_f0_3,spk_id5,save_epoch10,total_epoch11,batch_size12,if_save_latest13,pretrained_G14,pretrained_D15,gpus16,if_cache_gpu17],info3)
but4.click(train_index,[exp_dir1],info3)
but5.click(train1key,[exp_dir1,sr2,if_f0_3,trainset_dir4,spk_id5,gpus6,np7,f0method8,save_epoch10,total_epoch11,batch_size12,if_save_latest13,pretrained_G14,pretrained_D15,gpus16,if_cache_gpu17],info3)
with gr.TabItem("ckpt处理"):
with gr.TabItem(i18n("ckpt处理")):
with gr.Group():
gr.Markdown(value="""模型融合,可用于测试音色融合""")
gr.Markdown(value=i18n("""模型融合,可用于测试音色融合"""))
with gr.Row():
ckpt_a = gr.Textbox(label="A模型路径", value="", interactive=True)
ckpt_b = gr.Textbox(label="B模型路径", value="", interactive=True)
alpha_a = gr.Slider(minimum=0, maximum=1, label='A模型权重', value=0.5, interactive=True)
ckpt_a = gr.Textbox(label=i18n("A模型路径"), value="", interactive=True)
ckpt_b = gr.Textbox(label=i18n("B模型路径"), value="", interactive=True)
alpha_a = gr.Slider(minimum=0, maximum=1, label=i18n("A模型权重"), value=0.5, interactive=True)
with gr.Row():
sr_ = gr.Radio(label="目标采样率", choices=["32k","40k","48k"],value="40k", interactive=True)
if_f0_ = gr.Radio(label="模型是否带音高指导", choices=["",""],value="", interactive=True)
info__ = gr.Textbox(label="要置入的模型信息", value="", max_lines=8, interactive=True)
name_to_save0=gr.Textbox(label="保存的模型名不带后缀", value="", max_lines=1, interactive=True)
sr_ = gr.Radio(label=i18n("目标采样率"), choices=["32k","40k","48k"],value="40k", interactive=True)
if_f0_ = gr.Radio(label=i18n("模型是否带音高指导"), choices=["",""],value="", interactive=True)
info__ = gr.Textbox(label=i18n("要置入的模型信息"), value="", max_lines=8, interactive=True)
name_to_save0=gr.Textbox(label=i18n("保存的模型名不带后缀"), value="", max_lines=1, interactive=True)
with gr.Row():
but6 = gr.Button("融合", variant="primary")
info4 = gr.Textbox(label="输出信息", value="", max_lines=8)
but6 = gr.Button(i18n("融合"), variant="primary")
info4 = gr.Textbox(label=i18n("输出信息"), value="", max_lines=8)
but6.click(merge, [ckpt_a,ckpt_b,alpha_a,sr_,if_f0_,info__,name_to_save0], info4)#def merge(path1,path2,alpha1,sr,f0,info):
with gr.Group():
gr.Markdown(value="修改模型信息(仅支持weights文件夹下提取的小模型文件)")
gr.Markdown(value=i18n("修改模型信息(仅支持weights文件夹下提取的小模型文件)"))
with gr.Row():
ckpt_path0 = gr.Textbox(label="模型路径", value="", interactive=True)
info_=gr.Textbox(label="要改的模型信息", value="", max_lines=8, interactive=True)
name_to_save1=gr.Textbox(label="保存的文件名,默认空为和源文件同名", value="", max_lines=8, interactive=True)
ckpt_path0 = gr.Textbox(label=i18n("模型路径"), value="", interactive=True)
info_=gr.Textbox(label=i18n("要改的模型信息"), value="", max_lines=8, interactive=True)
name_to_save1=gr.Textbox(label=i18n("保存的文件名,默认空为和源文件同名"), value="", max_lines=8, interactive=True)
with gr.Row():
but7 = gr.Button("修改", variant="primary")
info5 = gr.Textbox(label="输出信息", value="", max_lines=8)
but7 = gr.Button(i18n("修改"), variant="primary")
info5 = gr.Textbox(label=i18n("输出信息"), value="", max_lines=8)
but7.click(change_info, [ckpt_path0,info_,name_to_save1], info5)
with gr.Group():
gr.Markdown(value="查看模型信息(仅支持weights文件夹下提取的小模型文件)")
gr.Markdown(value=i18n("查看模型信息(仅支持weights文件夹下提取的小模型文件)"))
with gr.Row():
ckpt_path1 = gr.Textbox(label="模型路径", value="", interactive=True)
but8 = gr.Button("查看", variant="primary")
info6 = gr.Textbox(label="输出信息", value="", max_lines=8)
ckpt_path1 = gr.Textbox(label=i18n("模型路径"), value="", interactive=True)
but8 = gr.Button(i18n("查看"), variant="primary")
info6 = gr.Textbox(label=i18n("输出信息"), value="", max_lines=8)
but8.click(show_info, [ckpt_path1], info6)
with gr.Group():
gr.Markdown(value="模型提取(输入logs文件夹下大文件模型路径),适用于训一半不想训了模型没有自动提取保存小文件模型,或者想测试中间模型的情况")
gr.Markdown(value=i18n("模型提取(输入logs文件夹下大文件模型路径),适用于训一半不想训了模型没有自动提取保存小文件模型,或者想测试中间模型的情况"))
with gr.Row():
ckpt_path2 = gr.Textbox(label="模型路径", value="E:\codes\py39\logs\mi-test_f0_48k\\G_23333.pth", interactive=True)
save_name = gr.Textbox(label="保存名", value="", interactive=True)
sr__ = gr.Radio(label="目标采样率", choices=["32k","40k","48k"],value="40k", interactive=True)
if_f0__ = gr.Radio(label="模型是否带音高指导,1是0否", choices=["1","0"],value="1", interactive=True)
info___ = gr.Textbox(label="要置入的模型信息", value="", max_lines=8, interactive=True)
but9 = gr.Button("提取", variant="primary")
info7 = gr.Textbox(label="输出信息", value="", max_lines=8)
ckpt_path2 = gr.Textbox(label=i18n("模型路径"), value="E:\codes\py39\logs\mi-test_f0_48k\\G_23333.pth", interactive=True)
save_name = gr.Textbox(label=i18n("保存名"), value="", interactive=True)
sr__ = gr.Radio(label=i18n("目标采样率"), choices=["32k","40k","48k"],value="40k", interactive=True)
if_f0__ = gr.Radio(label=i18n("模型是否带音高指导,1是0否"), choices=["1","0"],value="1", interactive=True)
info___ = gr.Textbox(label=i18n("要置入的模型信息"), value="", max_lines=8, interactive=True)
but9 = gr.Button(i18n("提取"), variant="primary")
info7 = gr.Textbox(label=i18n("输出信息"), value="", max_lines=8)
ckpt_path2.change(change_info_,[ckpt_path2],[sr__,if_f0__])
but9.click(extract_small_model, [ckpt_path2,save_name,sr__,if_f0__,info___], info7)
with gr.TabItem("招募音高曲线前端编辑器"):
gr.Markdown(value="""加开发群联系我xxxxx""")
with gr.TabItem("点击查看交流、问题反馈群号"):
gr.Markdown(value="""xxxxx""")
with gr.TabItem(i18n("招募音高曲线前端编辑器")):
gr.Markdown(value=i18n("""加开发群联系我xxxxx"""))
with gr.TabItem(i18n("点击查看交流、问题反馈群号")):
gr.Markdown(value=i18n("""xxxxx"""))
if iscolab:
app.queue(concurrency_count=511, max_size=1022).launch(share=True)
else:
app.queue(concurrency_count=511, max_size=1022).launch(server_name="0.0.0.0",inbrowser=True,server_port=listen_port,quiet=True)
app.queue(concurrency_count=511, max_size=1022).launch(server_name="0.0.0.0",inbrowser=True,server_port=listen_port,quiet=True)

View File

@ -1 +0,0 @@

View File

@ -1,77 +0,0 @@
import locale
'''
本地化方式如下所示此文件是"gui.py"的文本内容
'''
LANGUAGE_LIST = ['zh_CN', 'en_US']
LANGUAGE_ALL = {
'zh_CN': {
'SUPER': 'END',
'LANGUAGE': 'zh_CN',
'加载模型/Load Model': '加载模型',
'选择.pth文件/.pth File': '选择.pth文件',
'选择.index文件/.index File': '选择.index文件',
'选择.npy文件/.npy File': '选择.npy文件',
"输入设备/Input Device": "输入设备",
"输出设备/Output Device": "输出设备",
'音频设备(请使用同种类驱动)/Audio Devices': '音频设备(请使用同种类驱动)',
'响应阈值/Silence Threhold': '响应阈值',
'音调设置/Pitch Offset': '音调设置',
'常规设置/Common': '常规设置',
'采样长度/Sample Length': '采样长度',
'淡入淡出长度/Crossfade Length': '淡入淡出长度',
'额外推理时长/Extra Length': '额外推理时长',
'性能设置/Performance': '性能设置',
'开始音频转换': '开始音频转换',
'停止音频转换': '停止音频转换'
},
'en_US': {
'SUPER': 'zh_CN',
'LANGUAGE': 'en_US',
'加载模型/Load Model': 'Load Model',
'选择.pth文件/.pth File': 'Select .pth File',
'选择.index文件/.index File': 'Select .index File',
'选择.npy文件/.npy File': 'Select .npy File',
"输入设备/Input Device": "Input Device",
"输出设备/Output Device": "Output Device",
'音频设备(请使用同种类驱动)/Audio Devices': 'Audio Devices(Please use the same type of driver)',
'响应阈值/Silence Threhold': 'Silence Threhold',
'音调设置/Pitch Offset': 'Pitch Offset',
'常规设置/Common': 'Common',
'采样长度/Sample Length': 'Sample Length',
'淡入淡出长度/Crossfade Length': 'Crossfade Length',
'额外推理时长/Extra Length': 'Extra Length',
'性能设置/Performance': 'Performance',
'开始音频转换': 'Start VC',
'停止音频转换': 'Stop VC'
}
}
class I18nAuto:
def __init__(self, language=None):
self.language_list = LANGUAGE_LIST
self.language_all = LANGUAGE_ALL
self.language_map = {}
if language is None:
language = 'auto'
if language == 'auto':
language = locale.getdefaultlocale()[0]
if language not in self.language_list:
language = 'zh_CN'
self.language = language
super_language_list = []
while self.language_all[language]['SUPER'] != 'END':
super_language_list.append(language)
language = self.language_all[language]['SUPER']
super_language_list.append('zh_CN')
super_language_list.reverse()
for _lang in super_language_list:
self.read_language(self.language_all[_lang])
def read_language(self, lang_dict: dict):
for _key in lang_dict.keys():
self.language_map[_key] = lang_dict[_key]
def __call__(self, key):
return self.language_map[key]

71
locale/en_US.json Normal file
View File

@ -0,0 +1,71 @@
{
"模型推理": "Model inference",
"推理音色": "Inferencing timbre",
"刷新音色列表": "Refresh timbre list",
"卸载音色省显存": "Unload timbre to save GPU memory",
"请选择说话人id": "Please select a speaker id",
"变调整数半音数量升八度12降八度-12": "Pitch shift (integer, number of semitones, up to 12 octaves or down to -12 octaves)",
"输入待处理音频文件路径(默认是正确格式示例": "Input the path of the audio file to be processed (the default format is an example of the correct format)",
"选择音高提取算法,输入歌声可用pm提速,harvest低音好但巨慢无比": "Select the algorithm for pitch extraction. Use 'pm' to speed up for singing voices, or use 'harvest' for better low-pitched voices, but it is extremely slow.",
"特征检索库文件路径": "Feature search database file path",
"特征文件路径": "Feature file path",
"F0曲线文件可选一行一个音高代替默认F0及升降调": "F0 curve file, optional. One pitch per line to replace default F0 and pitch shifting.",
"转换": "Conversion",
"输出信息": "Output information",
"输出音频(右下角三个点,点了可以下载": "Output audio (three dots in the lower right corner, click to download)",
"指定输出文件夹": "Specify output folder",
"检索特征占比": "Search feature ratio",
"输入待处理音频文件夹路径(去文件管理器地址栏拷就行了": "Input the path of the audio file folder to be processed (just copy it from the address bar of the file manager)",
"也可批量输入音频文件,二选一,优先读文件夹": "Batch input of audio files is also available. Choose one of them, and the folder has a higher priority.",
"伴奏人声分离": "Accompaniment and vocal separation",
"输入待处理音频文件夹路径": "Input audio folder path",
"模型": "Model",
"指定输出人声文件夹": "Specify output vocal folder",
"指定输出乐器文件夹": "Specify output instrumental folder",
"训练": "Train",
"输入实验名": "Input experiment name",
"目标采样率": "Target sample rate",
"模型是否带音高指导(唱歌一定要,语音可以不要": "Does the model have pitch guidance? (Necessary for singing, not necessary for speech)",
"输入训练文件夹路径": "Input training folder path",
"请指定说话人id": "Please specify speaker ID",
"处理数据": "Process data",
"以-分隔输入使用的卡号,例如 0-1-2 使用卡0和卡1和卡2": "Input card numbers to use, separated by '-'. For example, '0-1-2' means using card 0, card 1, and card 2.",
"显卡信息": "GPU information",
"提取音高使用的CPU进程数": "Number of CPU processes used for pitch extraction",
"选择音高提取算法:输入歌声可用pm提速,高质量语音但CPU差可用dio提速,harvest质量更好但慢": "Select pitch extraction algorithm: Use 'pm' for faster processing of singing voice, 'dio' for high-quality speech but slower processing, and 'harvest' for the best quality but slowest processing.",
"特征提取": "Feature extraction",
"保存频率save_every_epoch": "Save frequency (save_every_epoch)",
"总训练轮数total_epoch": "Total training epochs (total_epoch)",
"是否仅保存最新的ckpt文件以节省硬盘空间": "Whether to save only the latest ckpt file to save disk space",
"是否缓存所有训练集至显存。10min以下小数据可缓存以加速训练大数据缓存会炸显存也加不了多少速": "Whether to cache all training sets in the video memory. Small data less than 10 minutes can be cached to speed up training, but caching large data will cause the video memory to explode and not add much speed.",
"加载预训练底模G路径": "Load pre-trained base model G path.",
"加载预训练底模D路径": "Load pre-trained base model D path.",
"训练模型": "Train model.",
"训练特征索引": "Train feature index.",
"一键训练": "One-click training.",
"ckpt处理": "ckpt processing.",
"A模型路径": "A model path.",
"B模型路径": "B model path.",
"A模型权重": "A model weight.",
"模型是否带音高指导": "Whether the model has pitch guidance.",
"要置入的模型信息": "Model information to be placed.",
"保存的模型名不带后缀": "Saved model name without extension.",
"融合": "Fusion.",
"修改模型信息(仅支持weights文件夹下提取的小模型文件": "Modify model information (only supports small model files extracted under the weights folder)",
"模型路径": "Model path",
"要改的模型信息": "Model information to be modified",
"保存的文件名,默认空为和源文件同名": "Saved file name, empty by default to use the same name as the source file",
"修改": "Modify",
"查看模型信息(仅支持weights文件夹下提取的小模型文件": "View model information (only supports small model files extracted under the weights folder)",
"查看": "View",
"模型提取(输入logs文件夹下大文件模型路径),适用于训一半不想训了模型没有自动提取保存小文件模型,或者想测试中间模型的情况": "Model extraction (input the path of the large file model under the logs folder), suitable for situations where you do not want to continue training halfway and the model has not automatically extracted and saved a small file model, or when you want to test intermediate models",
"保存名": "Save Name",
"模型是否带音高指导,1是0否": "Whether the model comes with pitch guidance, 1 for yes, 0 for no",
"提取": "Extract",
"招募音高曲线前端编辑器": "Recruit front-end editors for pitch curves",
"点击查看交流、问题反馈群号": "Click to view the communication and problem feedback group number",
"输入设备/Input Device": "Input device",
"输出设备/Output Device": "Output device",
"音频设备(请使用同种类驱动)/Audio Devices": "Audio devices (please use the same type of driver)",
"音调设置/Pitch Offset": "Pitch setting / Pitch Offset"
}

71
locale/ja_JP.json Normal file
View File

@ -0,0 +1,71 @@
{
"模型推理": "モデル推論",
"推理音色": "",
"刷新音色列表": "",
"卸载音色省显存": "",
"请选择说话人id": "話者IDを選択してください",
"变调整数半音数量升八度12降八度-12": "音程変更(整数、半音数、12半音の上昇/下降)",
"输入待处理音频文件路径(默认是正确格式示例": "処理対象のオーディオファイルのパスを入力してください(デフォルトは正しいフォーマットの例です)",
"选择音高提取算法,输入歌声可用pm提速,harvest低音好但巨慢无比": "ピッチ抽出アルゴリズムを選択してください。歌声の場合は、pmを使用して速度を上げることができます。低音が重要な場合は、harvestを使用できますが、非常に遅くなります。",
"特征检索库文件路径": "特徴量検索データベースのファイルパス",
"特征文件路径": "特徴量ファイルのパス",
"F0曲线文件可选一行一个音高代替默认F0及升降调": "F0曲線ファイル(オプション)、1行に1つのピッチが含まれます。デフォルトのF0および音程を置き換えます。",
"转换": "変換",
"输出信息": "出力情報",
"输出音频(右下角三个点,点了可以下载": "オーディオ出力右下の3つの点をクリックするとダウンロードできます",
"指定输出文件夹": "出力フォルダを指定してください",
"检索特征占比": "検索特徴率",
"输入待处理音频文件夹路径(去文件管理器地址栏拷就行了": "処理対象のオーディオフォルダのパスを入力してください(ファイルマネージャーのアドレスバーからコピーしてください)",
"也可批量输入音频文件,二选一,优先读文件夹": "オーディオファイルを一括入力することもできます。2つのオプションから1つを選択し、フォルダの読み込みを優先します。",
"伴奏人声分离": "伴奏とボーカルの分離",
"输入待处理音频文件夹路径": "処理するオーディオファイルのフォルダパスを入力してください",
"模型": "モデル",
"指定输出人声文件夹": "人の声を出力するフォルダを指定してください",
"指定输出乐器文件夹": "楽器の出力フォルダを指定してください",
"训练": "トレーニング",
"输入实验名": "実験名を入力してください",
"目标采样率": "目標サンプリングレート",
"模型是否带音高指导(唱歌一定要,语音可以不要": "モデルに音高ガイドを付けるかどうか(歌を歌う場合は必要ですが、音声は必要ありません)",
"输入训练文件夹路径": "トレーニング用フォルダのパスを入力してください",
"请指定说话人id": "話者IDを指定してください",
"处理数据": "データ処理",
"以-分隔输入使用的卡号,例如 0-1-2 使用卡0和卡1和卡2": "使用するカード番号を-で区切って入力してください。例0-1-2は、カード0、カード1、カード2を使用します",
"显卡信息": "カード情報",
"提取音高使用的CPU进程数": "抽出に使用するCPUプロセス数",
"选择音高提取算法:输入歌声可用pm提速,高质量语音但CPU差可用dio提速,harvest质量更好但慢": "",
"特征提取": "特徴抽出",
"保存频率save_every_epoch": "エポックごとの保存頻度",
"总训练轮数total_epoch": "総トレーニング回数",
"是否仅保存最新的ckpt文件以节省硬盘空间": "ハードディスク容量を節約するため、最新のckptファイルのみを保存するかどうか",
"是否缓存所有训练集至显存。10min以下小数据可缓存以加速训练大数据缓存会炸显存也加不了多少速": "すべてのトレーニングセットをキャッシュしてGPUメモリに保存するかどうか。10分以下の小さなデータはキャッシュしてトレーニングを高速化できますが、大きなデータをキャッシュするとGPUメモリが不足して速度が上がりません。",
"加载预训练底模G路径": "事前学習済みのGモデルのパスをロードしてください",
"加载预训练底模D路径": "事前学習済みのDモデルのパスをロードしてください",
"训练模型": "モデルのトレーニング",
"训练特征索引": "特徴インデックスのトレーニング",
"一键训练": "ワンクリックトレーニング",
"ckpt处理": "ckptファイルの処理",
"A模型路径": "Aモデルのパス",
"B模型路径": "Bモデルのパス",
"A模型权重": "Aモデルの重み",
"模型是否带音高指导": "モデルに音高ガイドを付けるかどうか",
"要置入的模型信息": "挿入するモデル情報",
"保存的模型名不带后缀": "拡張子のない保存するモデル名",
"融合": "フュージョン",
"修改模型信息(仅支持weights文件夹下提取的小模型文件": "モデル情報の変更(小さなモデルファイルのみ、weightsフォルダーから抽出)",
"模型路径": "モデルパス",
"要改的模型信息": "変更するモデル情報",
"保存的文件名,默认空为和源文件同名": "保存するファイル名。デフォルトは元のファイル名と同じです",
"修改": "変更",
"查看模型信息(仅支持weights文件夹下提取的小模型文件": "モデル情報の表示小さなモデルファイルのみ、weightsフォルダーから抽出",
"查看": "表示",
"模型提取(输入logs文件夹下大文件模型路径),适用于训一半不想训了模型没有自动提取保存小文件模型,或者想测试中间模型的情况": "モデル抽出logsフォルダー内の大きなファイルモデルパスを入力。トレーニングが途中で止まり、自動的に小さなモデルファイルを保存していない場合、または中間モデルをテストしたい場合に使用できます。",
"保存名": "保存するファイル名",
"模型是否带音高指导,1是0否": "モデルに音高ガイドを付けるかどうか、1は付ける、0は付けない",
"提取": "抽出",
"招募音高曲线前端编辑器": "音高曲線フロントエンドエディターを募集",
"点击查看交流、问题反馈群号": "クリックして交流、問題フィードバックグループ番号を表示",
"输入设备/Input Device": "入力デバイス",
"输出设备/Output Device": "出力デバイス",
"音频设备(请使用同种类驱动)/Audio Devices": "音声デバイス",
"音调设置/Pitch Offset": "音程オフセット"
}

33
locale/locale_diff.py Normal file
View File

@ -0,0 +1,33 @@
import json
import os
from collections import OrderedDict
# Define the standard file name
standard_file = "zh_CN.json"
# Define the list of supported languages
languages = ["ja_JP.json", "en_US.json"]
# Load the standard file
with open(standard_file, "r", encoding="utf-8") as f:
standard_data = json.load(f, object_pairs_hook=OrderedDict)
# Loop through each language file
for lang_file in languages:
# Load the language file
with open(lang_file, "r", encoding="utf-8") as f:
lang_data = json.load(f, object_pairs_hook=OrderedDict)
# Find the difference between the language file and the standard file
diff = set(standard_data.keys()) - set(lang_data.keys())
# Add any missing keys to the language file
for key in diff:
lang_data[key] = key
# Sort the keys of the language file to match the order of the standard file
lang_data = OrderedDict(sorted(lang_data.items(), key=lambda x: list(standard_data.keys()).index(x[0])))
# Save the updated language file
with open(lang_file, "w", encoding="utf-8") as f:
json.dump(lang_data, f, ensure_ascii=False, indent=4)

71
locale/zh_CN.json Normal file
View File

@ -0,0 +1,71 @@
{
"模型推理": "模型推理",
"推理音色": "推理音色",
"刷新音色列表": "刷新音色列表",
"卸载音色省显存": "卸载音色省显存",
"请选择说话人id": "请选择说话人id",
"变调整数半音数量升八度12降八度-12": "变调整数半音数量升八度12降八度-12",
"输入待处理音频文件路径(默认是正确格式示例": "输入待处理音频文件路径(默认是正确格式示例",
"选择音高提取算法,输入歌声可用pm提速,harvest低音好但巨慢无比": "选择音高提取算法,输入歌声可用pm提速,harvest低音好但巨慢无比",
"特征检索库文件路径": "特征检索库文件路径",
"特征文件路径": "特征文件路径",
"F0曲线文件可选一行一个音高代替默认F0及升降调": "F0曲线文件可选一行一个音高代替默认F0及升降调",
"转换": "转换",
"输出信息": "输出信息",
"输出音频(右下角三个点,点了可以下载": "输出音频(右下角三个点,点了可以下载",
"指定输出文件夹": "指定输出文件夹",
"检索特征占比": "检索特征占比",
"输入待处理音频文件夹路径(去文件管理器地址栏拷就行了": "输入待处理音频文件夹路径(去文件管理器地址栏拷就行了",
"也可批量输入音频文件,二选一,优先读文件夹": "也可批量输入音频文件,二选一,优先读文件夹",
"伴奏人声分离": "伴奏人声分离",
"输入待处理音频文件夹路径": "输入待处理音频文件夹路径",
"模型": "模型",
"指定输出人声文件夹": "指定输出人声文件夹",
"指定输出乐器文件夹": "指定输出乐器文件夹",
"训练": "训练",
"输入实验名": "输入实验名",
"目标采样率": "目标采样率",
"模型是否带音高指导(唱歌一定要,语音可以不要": "模型是否带音高指导(唱歌一定要,语音可以不要",
"输入训练文件夹路径": "输入训练文件夹路径",
"请指定说话人id": "请指定说话人id",
"处理数据": "处理数据",
"以-分隔输入使用的卡号,例如 0-1-2 使用卡0和卡1和卡2": "以-分隔输入使用的卡号,例如 0-1-2 使用卡0和卡1和卡2",
"显卡信息": "显卡信息",
"提取音高使用的CPU进程数": "提取音高使用的CPU进程数",
"选择音高提取算法:输入歌声可用pm提速,高质量语音但CPU差可用dio提速,harvest质量更好但慢": "选择音高提取算法:输入歌声可用pm提速,高质量语音但CPU差可用dio提速,harvest质量更好但慢",
"特征提取": "特征提取",
"保存频率save_every_epoch": "保存频率save_every_epoch",
"总训练轮数total_epoch": "总训练轮数total_epoch",
"是否仅保存最新的ckpt文件以节省硬盘空间": "是否仅保存最新的ckpt文件以节省硬盘空间",
"是否缓存所有训练集至显存。10min以下小数据可缓存以加速训练大数据缓存会炸显存也加不了多少速": "是否缓存所有训练集至显存。10min以下小数据可缓存以加速训练大数据缓存会炸显存也加不了多少速",
"加载预训练底模G路径": "加载预训练底模G路径",
"加载预训练底模D路径": "加载预训练底模D路径",
"训练模型": "训练模型",
"训练特征索引": "训练特征索引",
"一键训练": "一键训练",
"ckpt处理": "ckpt处理",
"A模型路径": "A模型路径",
"B模型路径": "B模型路径",
"A模型权重": "A模型权重",
"模型是否带音高指导": "模型是否带音高指导",
"要置入的模型信息": "要置入的模型信息",
"保存的模型名不带后缀": "保存的模型名不带后缀",
"融合": "融合",
"修改模型信息(仅支持weights文件夹下提取的小模型文件": "修改模型信息(仅支持weights文件夹下提取的小模型文件",
"模型路径": "模型路径",
"要改的模型信息": "要改的模型信息",
"保存的文件名,默认空为和源文件同名": "保存的文件名,默认空为和源文件同名",
"修改": "修改",
"查看模型信息(仅支持weights文件夹下提取的小模型文件": "查看模型信息(仅支持weights文件夹下提取的小模型文件",
"查看": "查看",
"模型提取(输入logs文件夹下大文件模型路径),适用于训一半不想训了模型没有自动提取保存小文件模型,或者想测试中间模型的情况": "模型提取(输入logs文件夹下大文件模型路径),适用于训一半不想训了模型没有自动提取保存小文件模型,或者想测试中间模型的情况",
"保存名": "保存名",
"模型是否带音高指导,1是0否": "模型是否带音高指导,1是0否",
"提取": "提取",
"招募音高曲线前端编辑器": "招募音高曲线前端编辑器",
"点击查看交流、问题反馈群号": "点击查看交流、问题反馈群号",
"输入设备/Input Device": "输入设备/Input Device",
"输出设备/Output Device": "输出设备/Output Device",
"音频设备(请使用同种类驱动)/Audio Devices": "音频设备(请使用同种类驱动)/Audio Devices",
"音调设置/Pitch Offset": "音调设置/Pitch Offset"
}

24
webui_locale.py Normal file
View File

@ -0,0 +1,24 @@
import locale
import json
def load_language_list(language):
with open(f"./locale/{language}.json", "r", encoding="utf-8") as f:
language_list = json.load(f)
return language_list
class I18nAuto:
def __init__(self, language=None):
self.language_map = {}
if language is None:
language = 'auto'
if language == 'auto':
language = locale.getdefaultlocale()[0]
self.language = language
self.language_list = load_language_list(language)
self.read_language(self.language_list)
def read_language(self, lang_dict: dict):
self.language_map.update(lang_dict)
def __call__(self, key):
return self.language_map[key]