mirror of
https://github.com/RVC-Project/Retrieval-based-Voice-Conversion-WebUI.git
synced 2025-05-07 04:09:06 +08:00
Merge branch 'Precision-audio-processing' of https://github.com/autumnmotor/Retrieval-based-Voice-Conversion-WebUI into Precision-audio-processing
This commit is contained in:
commit
ed16a15203
10
.github/workflows/push_format.yml
vendored
10
.github/workflows/push_format.yml
vendored
@ -5,15 +5,11 @@ on:
|
|||||||
branches:
|
branches:
|
||||||
- main
|
- main
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: write
|
||||||
|
pull-requests: write
|
||||||
jobs:
|
jobs:
|
||||||
push_format:
|
push_format:
|
||||||
permissions:
|
|
||||||
actions: write
|
|
||||||
checks: write
|
|
||||||
contents: write
|
|
||||||
issues: write
|
|
||||||
repository-projects: write
|
|
||||||
pull-requests: write
|
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v3
|
||||||
|
@ -1,42 +1,23 @@
|
|||||||
20230409
|
### 20230409
|
||||||
|
- 修正训练参数,提升显卡平均利用率,A100最高从25%提升至90%左右,V100:50%->90%左右,2060S:60%->85%左右,P40:25%->95%左右,训练速度显著提升
|
||||||
|
- 修正参数:总batch_size改为每张卡的batch_size
|
||||||
|
- 修正total_epoch:最大限制100解锁至1000;默认10提升至默认20
|
||||||
|
- 修复ckpt提取识别是否带音高错误导致推理异常的问题
|
||||||
|
- 修复分布式训练每个rank都保存一次ckpt的问题
|
||||||
|
- 特征提取进行nan特征过滤
|
||||||
|
- 修复静音输入输出随机辅音or噪声的问题(老版模型需要重做训练集重训)
|
||||||
|
|
||||||
 1-修正训练参数,提升显卡平均利用率,A100最高从25%提升至90%左右,V100:50%->90%左右,2060S:60%->85%左右,P40:25%->95%左右,训练速度显著提升
|
### 20230416更新
|
||||||
|
- 新增本地实时变声迷你GUI,双击go-realtime-gui.bat启动
|
||||||
 2-修正参数:总batch_size改为每张卡的batch_size
|
- 训练推理均对<50Hz的频段进行滤波过滤
|
||||||
|
- 训练推理音高提取pyworld最低音高从默认80下降至50,50-80hz间的男声低音不会哑
|
||||||
 3-修正total_epoch:最大限制100解锁至1000;默认10提升至默认20
|
- WebUI支持根据系统区域变更语言(现支持en_US,ja_JP,zh_CN,zh_HK,zh_SG,zh_TW,不支持的默认en_US)
|
||||||
|
- 修正部分显卡识别(例如V100-16G识别失败,P4识别失败)
|
||||||
 4-修复ckpt提取识别是否带音高错误导致推理异常的问题
|
|
||||||
|
|
||||||
 5-修复分布式训练每个rank都保存一次ckpt的问题
|
|
||||||
|
|
||||||
 6-特征提取进行nan特征过滤
|
|
||||||
|
|
||||||
 7-修复静音输入输出随机辅音or噪声的问题(老版模型需要重做训练集重训)
|
|
||||||
|
|
||||||
20230416更新
|
|
||||||
|
|
||||||
 1-新增本地实时变声迷你GUI,双击go-realtime-gui.bat启动
|
|
||||||
|
|
||||||
 2-训练推理均对<50Hz的频段进行滤波过滤
|
|
||||||
|
|
||||||
 3-训练推理音高提取pyworld最低音高从默认80下降至50,50-80hz间的男声低音不会哑
|
|
||||||
|
|
||||||
 4-WebUI支持根据系统区域变更语言(现支持en_US,ja_JP,zh_CN,zh_HK,zh_SG,zh_TW,不支持的默认en_US)
|
|
||||||
|
|
||||||
 5-修正部分显卡识别(例如V100-16G识别失败,P4识别失败)
|
|
||||||
|
|
||||||
后续计划:
|
|
||||||
|
|
||||||
 1-收集呼吸wav加入训练集修正呼吸变声电音的问题
|
|
||||||
|
|
||||||
 2-研究更优的默认faiss索引配置,计划将索引打包进weights/xxx.pth中,取消推理界面的 特征/检索库 选择
|
|
||||||
|
|
||||||
 3-根据显存情况和显卡架构自动给到最优配置(batch size,训练集切块,推理音频长度相关的config,训练是否fp16),未来所有>=4G显存的>=pascal架构的显卡都可以训练或推理,而<4G显存的显卡不会进行支持
|
|
||||||
|
|
||||||
 4-我们正在训练增加了歌声训练集的底模,未来会公开
|
|
||||||
|
|
||||||
 5-推理音高识别选项加入"是否开启中值滤波"
|
|
||||||
|
|
||||||
 6-增加选项:每次epoch保存的小模型均进行提取; 增加选项:设置默认测试集音频,每次保存的小模型均在保存后对其进行推理导出,用户可试听(来选择哪个中间epoch最好)
|
|
||||||
|
|
||||||
|
### 后续计划:
|
||||||
|
- 收集呼吸wav加入训练集修正呼吸变声电音的问题
|
||||||
|
- 研究更优的默认faiss索引配置,计划将索引打包进weights/xxx.pth中,取消推理界面的 特征/检索库 选择
|
||||||
|
- 根据显存情况和显卡架构自动给到最优配置(batch size,训练集切块,推理音频长度相关的config,训练是否fp16),未来所有>=4G显存的>=pascal架构的显卡都可以训练或推理,而<4G显存的显卡不会进行支持
|
||||||
|
- 我们正在训练增加了歌声训练集的底模,未来会公开
|
||||||
|
- 推理音高识别选项加入"是否开启中值滤波"
|
||||||
|
- 增加选项:每次epoch保存的小模型均进行提取; 增加选项:设置默认测试集音频,每次保存的小模型均在保存后对其进行推理导出,用户可试听(来选择哪个中间epoch最好)
|
||||||
|
@ -28,3 +28,4 @@ process("gui.py")
|
|||||||
# Save as a JSON file
|
# Save as a JSON file
|
||||||
with open("./i18n/zh_CN.json", "w", encoding="utf-8") as f:
|
with open("./i18n/zh_CN.json", "w", encoding="utf-8") as f:
|
||||||
json.dump(data, f, ensure_ascii=False, indent=4)
|
json.dump(data, f, ensure_ascii=False, indent=4)
|
||||||
|
f.write("\n")
|
||||||
|
17
gui.py
17
gui.py
@ -1,4 +1,5 @@
|
|||||||
import os,sys
|
import os, sys
|
||||||
|
|
||||||
now_dir = os.getcwd()
|
now_dir = os.getcwd()
|
||||||
sys.path.append(now_dir)
|
sys.path.append(now_dir)
|
||||||
import PySimpleGUI as sg
|
import PySimpleGUI as sg
|
||||||
@ -15,7 +16,6 @@ from infer_pack.models import SynthesizerTrnMs256NSFsid, SynthesizerTrnMs256NSFs
|
|||||||
from i18n import I18nAuto
|
from i18n import I18nAuto
|
||||||
|
|
||||||
i18n = I18nAuto()
|
i18n = I18nAuto()
|
||||||
print(i18n.language_map)
|
|
||||||
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
|
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
|
||||||
|
|
||||||
|
|
||||||
@ -32,10 +32,11 @@ class RVC:
|
|||||||
self.f0_max = 1100
|
self.f0_max = 1100
|
||||||
self.f0_mel_min = 1127 * np.log(1 + self.f0_min / 700)
|
self.f0_mel_min = 1127 * np.log(1 + self.f0_min / 700)
|
||||||
self.f0_mel_max = 1127 * np.log(1 + self.f0_max / 700)
|
self.f0_mel_max = 1127 * np.log(1 + self.f0_max / 700)
|
||||||
|
if index_rate != 0:
|
||||||
self.index = faiss.read_index(index_path)
|
self.index = faiss.read_index(index_path)
|
||||||
self.index_rate = index_rate
|
|
||||||
"""NOT YET USED"""
|
|
||||||
self.big_npy = np.load(npy_path)
|
self.big_npy = np.load(npy_path)
|
||||||
|
print("index search enabled")
|
||||||
|
self.index_rate = index_rate
|
||||||
model_path = hubert_path
|
model_path = hubert_path
|
||||||
print("load model(s) from {}".format(model_path))
|
print("load model(s) from {}".format(model_path))
|
||||||
models, saved_cfg, task = checkpoint_utils.load_model_ensemble_and_task(
|
models, saved_cfg, task = checkpoint_utils.load_model_ensemble_and_task(
|
||||||
@ -110,11 +111,7 @@ class RVC:
|
|||||||
feats = self.model.final_proj(logits[0])
|
feats = self.model.final_proj(logits[0])
|
||||||
|
|
||||||
####索引优化
|
####索引优化
|
||||||
if (
|
if hasattr(self, "index") and hasattr(self, "big_npy") and self.index_rate != 0:
|
||||||
isinstance(self.index, type(None)) == False
|
|
||||||
and isinstance(self.big_npy, type(None)) == False
|
|
||||||
and self.index_rate != 0
|
|
||||||
):
|
|
||||||
npy = feats[0].cpu().numpy().astype("float32")
|
npy = feats[0].cpu().numpy().astype("float32")
|
||||||
_, I = self.index.search(npy, 1)
|
_, I = self.index.search(npy, 1)
|
||||||
npy = self.big_npy[I.squeeze()].astype("float16")
|
npy = self.big_npy[I.squeeze()].astype("float16")
|
||||||
@ -122,6 +119,8 @@ class RVC:
|
|||||||
torch.from_numpy(npy).unsqueeze(0).to(device) * self.index_rate
|
torch.from_numpy(npy).unsqueeze(0).to(device) * self.index_rate
|
||||||
+ (1 - self.index_rate) * feats
|
+ (1 - self.index_rate) * feats
|
||||||
)
|
)
|
||||||
|
else:
|
||||||
|
print("index search FAIL or disabled")
|
||||||
|
|
||||||
feats = F.interpolate(feats.permute(0, 2, 1), scale_factor=2).permute(0, 2, 1)
|
feats = F.interpolate(feats.permute(0, 2, 1), scale_factor=2).permute(0, 2, 1)
|
||||||
torch.cuda.synchronize()
|
torch.cuda.synchronize()
|
||||||
|
@ -11,17 +11,17 @@
|
|||||||
"选择音高提取算法,输入歌声可用pm提速,harvest低音好但巨慢无比": "ピッチ抽出アルゴリズムを選択してください。歌声の場合は、pmを使用して速度を上げることができます。低音が重要な場合は、harvestを使用できますが、非常に遅くなります。",
|
"选择音高提取算法,输入歌声可用pm提速,harvest低音好但巨慢无比": "ピッチ抽出アルゴリズムを選択してください。歌声の場合は、pmを使用して速度を上げることができます。低音が重要な場合は、harvestを使用できますが、非常に遅くなります。",
|
||||||
"特征检索库文件路径": "特徴量検索データベースのファイルパス",
|
"特征检索库文件路径": "特徴量検索データベースのファイルパス",
|
||||||
"特征文件路径": "特徴量ファイルのパス",
|
"特征文件路径": "特徴量ファイルのパス",
|
||||||
"F0曲线文件, 可选, 一行一个音高, 代替默认F0及升降调": "F0曲线文件, 可选, 一行一个音高, 代替默认F0及升降调",
|
"F0曲线文件, 可选, 一行一个音高, 代替默认F0及升降调": "F0(最低共振周波数)カーブファイル(オプション、1行に1ピッチ、デフォルトのF0(最低共振周波数)とエレベーションを置き換えます。)",
|
||||||
"转换": "変換",
|
"转换": "変換",
|
||||||
"输出信息": "出力情報",
|
"输出信息": "出力情報",
|
||||||
"输出音频(右下角三个点,点了可以下载)": "出力音声(右下の三点をクリックしてダウンロードできます)",
|
"输出音频(右下角三个点,点了可以下载)": "出力音声(右下の三点をクリックしてダウンロードできます)",
|
||||||
"批量转换, 输入待转换音频文件夹, 或上传多个音频文件, 在指定文件夹(默认opt)下输出转换的音频. ": "批量转换, 输入待转换音频文件夹, 或上传多个音频文件, 在指定文件夹(默认opt)下输出转换的音频. ",
|
"批量转换, 输入待转换音频文件夹, 或上传多个音频文件, 在指定文件夹(默认opt)下输出转换的音频. ": "一括変換、変換する音声フォルダを入力、または複数の音声ファイルをアップロードし、指定したフォルダ(デフォルトのopt)に変換した音声を出力します。",
|
||||||
"指定输出文件夹": "出力フォルダを指定してください",
|
"指定输出文件夹": "出力フォルダを指定してください",
|
||||||
"检索特征占比": "検索特徴率",
|
"检索特征占比": "検索特徴率",
|
||||||
"输入待处理音频文件夹路径(去文件管理器地址栏拷就行了)": "処理対象音声フォルダーのパスを入力してください(ファイルマネージャのアドレスバーからコピーしてください)",
|
"输入待处理音频文件夹路径(去文件管理器地址栏拷就行了)": "処理対象音声フォルダーのパスを入力してください(ファイルマネージャのアドレスバーからコピーしてください)",
|
||||||
"也可批量输入音频文件, 二选一, 优先读文件夹": "複数の音声ファイルを一括で入力することもできますが、フォルダーを優先して読み込みます",
|
"也可批量输入音频文件, 二选一, 优先读文件夹": "複数の音声ファイルを一括で入力することもできますが、フォルダーを優先して読み込みます",
|
||||||
"伴奏人声分离": "伴奏とボーカルの分離",
|
"伴奏人声分离": "伴奏とボーカルの分離",
|
||||||
"人声伴奏分离批量处理, 使用UVR5模型. <br>不带和声用HP2, 带和声且提取的人声不需要和声用HP5<br>合格的文件夹路径格式举例: E:\\codes\\py39\\vits_vc_gpu\\白鹭霜华测试样例(去文件管理器地址栏拷就行了)": "人声伴奏分离批量处理, 使用UVR5模型. <br>不带和声用HP2, 带和声且提取的人声不需要和声用HP5<br>合格的文件夹路径格式举例: E:\\codes\\py39\\vits_vc_gpu\\白鹭霜华测试样例(去文件管理器地址栏拷就行了)",
|
"人声伴奏分离批量处理, 使用UVR5模型. <br>不带和声用HP2, 带和声且提取的人声不需要和声用HP5<br>合格的文件夹路径格式举例: E:\\codes\\py39\\vits_vc_gpu\\白鹭霜华测试样例(去文件管理器地址栏拷就行了)": "UVR5モデルを使用した、声帯分離バッチ処理です。<br>HP2はハーモニー、ハーモニーのあるボーカルとハーモニーのないボーカルを抽出したものはHP5を使ってください <br>フォルダーパスの形式例: E:\\codes\\py39\\vits_vc_gpu\\白鹭霜华测试样例(エクスプローラーのアドレスバーからコピーするだけです)",
|
||||||
"输入待处理音频文件夹路径": "処理するオーディオファイルのフォルダパスを入力してください",
|
"输入待处理音频文件夹路径": "処理するオーディオファイルのフォルダパスを入力してください",
|
||||||
"模型": "モデル",
|
"模型": "モデル",
|
||||||
"指定输出人声文件夹": "人の声を出力するフォルダを指定してください",
|
"指定输出人声文件夹": "人の声を出力するフォルダを指定してください",
|
||||||
@ -60,7 +60,7 @@
|
|||||||
"要置入的模型信息": "挿入するモデル情報",
|
"要置入的模型信息": "挿入するモデル情報",
|
||||||
"保存的模型名不带后缀": "拡張子のない保存するモデル名",
|
"保存的模型名不带后缀": "拡張子のない保存するモデル名",
|
||||||
"融合": "フュージョン",
|
"融合": "フュージョン",
|
||||||
"修改模型信息(仅支持weights文件夹下提取的小模型文件)": "修改模型信息(仅支持weights文件夹下提取的小模型文件)",
|
"修改模型信息(仅支持weights文件夹下提取的小模型文件)": "モデル情報の修正(weightsフォルダから抽出された小さなモデルファイルのみ対応)",
|
||||||
"模型路径": "モデルパス",
|
"模型路径": "モデルパス",
|
||||||
"要改的模型信息": "変更するモデル情報",
|
"要改的模型信息": "変更するモデル情報",
|
||||||
"保存的文件名, 默认空为和源文件同名": "保存するファイル名、デフォルトでは空欄で元のファイル名と同じ名前になります",
|
"保存的文件名, 默认空为和源文件同名": "保存するファイル名、デフォルトでは空欄で元のファイル名と同じ名前になります",
|
||||||
@ -68,18 +68,18 @@
|
|||||||
"查看模型信息(仅支持weights文件夹下提取的小模型文件)": "モデル情報を表示する(小さいモデルファイルはweightsフォルダーからのみサポートされています)",
|
"查看模型信息(仅支持weights文件夹下提取的小模型文件)": "モデル情報を表示する(小さいモデルファイルはweightsフォルダーからのみサポートされています)",
|
||||||
"查看": "表示",
|
"查看": "表示",
|
||||||
"模型提取(输入logs文件夹下大文件模型路径),适用于训一半不想训了模型没有自动提取保存小文件模型,或者想测试中间模型的情况": "モデル抽出(ログフォルダー内の大きなファイルのモデルパスを入力)、モデルを半分までトレーニングし、自動的に小さいファイルモデルを保存しなかったり、中間モデルをテストしたい場合に適用されます。",
|
"模型提取(输入logs文件夹下大文件模型路径),适用于训一半不想训了模型没有自动提取保存小文件模型,或者想测试中间模型的情况": "モデル抽出(ログフォルダー内の大きなファイルのモデルパスを入力)、モデルを半分までトレーニングし、自動的に小さいファイルモデルを保存しなかったり、中間モデルをテストしたい場合に適用されます。",
|
||||||
"保存名": "保存するファイル名",
|
"保存名": "保存ファイル名",
|
||||||
"模型是否带音高指导,1是0否": "モデルに音高ガイドを付けるかどうか、1は付ける、0は付けない",
|
"模型是否带音高指导,1是0否": "モデルに音高ガイドを付けるかどうか、1は付ける、0は付けない",
|
||||||
"提取": "抽出",
|
"提取": "抽出",
|
||||||
"招募音高曲线前端编辑器": "音高曲線フロントエンドエディターを募集",
|
"招募音高曲线前端编辑器": "音高曲線フロントエンドエディターを募集",
|
||||||
"加开发群联系我xxxxx": "開発グループに参加して私に連絡してくださいxxxxx",
|
"加开发群联系我xxxxx": "開発グループに参加して私に連絡してくださいxxxxx",
|
||||||
"点击查看交流、问题反馈群号": "クリックして交流、問題フィードバックグループ番号を表示",
|
"点击查看交流、问题反馈群号": "クリックして交流、問題フィードバックグループ番号を表示",
|
||||||
"xxxxx": "xxxxx",
|
"xxxxx": "xxxxx",
|
||||||
"加载模型": "モデルをロードする",
|
"加载模型": "モデルをロード",
|
||||||
"Hubert模型": "Hubert模型",
|
"Hubert模型": "Hubert模型",
|
||||||
"选择.pth文件": ".pthファイルを選択する",
|
"选择.pth文件": ".pthファイルを選択",
|
||||||
"选择.index文件": ".indexファイルを選択する",
|
"选择.index文件": ".indexファイルを選択",
|
||||||
"选择.npy文件": ".npyファイルを選択する",
|
"选择.npy文件": ".npyファイルを選択",
|
||||||
"输入设备": "入力デバイス",
|
"输入设备": "入力デバイス",
|
||||||
"输出设备": "出力デバイス",
|
"输出设备": "出力デバイス",
|
||||||
"音频设备(请使用同种类驱动)": "オーディオデバイス(同じ種類のドライバーを使用してください)",
|
"音频设备(请使用同种类驱动)": "オーディオデバイス(同じ種類のドライバーを使用してください)",
|
||||||
@ -93,7 +93,7 @@
|
|||||||
"输入降噪": "入力ノイズの低減",
|
"输入降噪": "入力ノイズの低減",
|
||||||
"输出降噪": "出力ノイズの低減",
|
"输出降噪": "出力ノイズの低減",
|
||||||
"性能设置": "パフォーマンス設定",
|
"性能设置": "パフォーマンス設定",
|
||||||
"开始音频转换": "音声変換を開始する",
|
"开始音频转换": "音声変換を開始",
|
||||||
"停止音频转换": "音声変換を停止する",
|
"停止音频转换": "音声変換を停止",
|
||||||
"推理时间(ms):": "推論時間(ms):"
|
"推理时间(ms):": "推論時間(ms):"
|
||||||
}
|
}
|
@ -42,3 +42,4 @@ for lang_file in languages:
|
|||||||
# Save the updated language file
|
# Save the updated language file
|
||||||
with open(lang_file, "w", encoding="utf-8") as f:
|
with open(lang_file, "w", encoding="utf-8") as f:
|
||||||
json.dump(lang_data, f, ensure_ascii=False, indent=4)
|
json.dump(lang_data, f, ensure_ascii=False, indent=4)
|
||||||
|
f.write("\n")
|
||||||
|
13
infer-web.py
13
infer-web.py
@ -139,8 +139,17 @@ def vc_single(
|
|||||||
if hubert_model == None:
|
if hubert_model == None:
|
||||||
load_hubert()
|
load_hubert()
|
||||||
if_f0 = cpt.get("f0", 1)
|
if_f0 = cpt.get("f0", 1)
|
||||||
file_index = file_index.strip(" ").strip('"').strip("\n").strip('"').strip(" ").replace("trained","added")#防止小白写错,自动帮他替换掉
|
file_index = (
|
||||||
file_big_npy = file_big_npy.strip(" ").strip('"').strip("\n").strip('"').strip(" ")
|
file_index.strip(" ")
|
||||||
|
.strip('"')
|
||||||
|
.strip("\n")
|
||||||
|
.strip('"')
|
||||||
|
.strip(" ")
|
||||||
|
.replace("trained", "added")
|
||||||
|
) # 防止小白写错,自动帮他替换掉
|
||||||
|
file_big_npy = (
|
||||||
|
file_big_npy.strip(" ").strip('"').strip("\n").strip('"').strip(" ")
|
||||||
|
)
|
||||||
audio_opt = vc.pipeline(
|
audio_opt = vc.pipeline(
|
||||||
hubert_model,
|
hubert_model,
|
||||||
net_g,
|
net_g,
|
||||||
|
@ -4,7 +4,8 @@ scipy==1.9.3
|
|||||||
librosa==0.9.2
|
librosa==0.9.2
|
||||||
llvmlite==0.39.0
|
llvmlite==0.39.0
|
||||||
fairseq==0.12.2
|
fairseq==0.12.2
|
||||||
faiss-cpu==1.7.2
|
faiss-cpu==1.7.0; sys_platform == "darwin"
|
||||||
|
faiss-cpu==1.7.2; sys_platform != "darwin"
|
||||||
gradio
|
gradio
|
||||||
Cython
|
Cython
|
||||||
future>=0.18.3
|
future>=0.18.3
|
||||||
|
@ -39,7 +39,7 @@ class PreProcess:
|
|||||||
max_sil_kept=150,
|
max_sil_kept=150,
|
||||||
)
|
)
|
||||||
self.sr = sr
|
self.sr = sr
|
||||||
self.bh, self.ah = signal.butter(N=5, Wn=48, btype='high', fs=self.sr)
|
self.bh, self.ah = signal.butter(N=5, Wn=48, btype="high", fs=self.sr)
|
||||||
self.per = 3.7
|
self.per = 3.7
|
||||||
self.overlap = 0.3
|
self.overlap = 0.3
|
||||||
self.tail = self.per + self.overlap
|
self.tail = self.per + self.overlap
|
||||||
|
@ -5,7 +5,9 @@ from config import x_pad, x_query, x_center, x_max
|
|||||||
import scipy.signal as signal
|
import scipy.signal as signal
|
||||||
import pyworld, os, traceback, faiss
|
import pyworld, os, traceback, faiss
|
||||||
from scipy import signal
|
from scipy import signal
|
||||||
bh, ah = signal.butter(N=5, Wn=48, btype='high', fs=16000)
|
|
||||||
|
bh, ah = signal.butter(N=5, Wn=48, btype="high", fs=16000)
|
||||||
|
|
||||||
|
|
||||||
class VC(object):
|
class VC(object):
|
||||||
def __init__(self, tgt_sr, device, is_half):
|
def __init__(self, tgt_sr, device, is_half):
|
||||||
|
Loading…
x
Reference in New Issue
Block a user