mirror of
https://github.com/w-okada/voice-changer.git
synced 2025-02-02 16:23:58 +03:00
WIP: integrate vcs to new gui 2
This commit is contained in:
parent
c7e72e52db
commit
06a5250f61
@ -10,6 +10,11 @@ import json
|
||||
@dataclass
|
||||
class ModelSlot:
|
||||
voiceChangerType: VoiceChangerType | None = None
|
||||
name: str = ""
|
||||
description: str = ""
|
||||
credit: str = ""
|
||||
termsOfUseUrl: str = ""
|
||||
iconFile: str = ""
|
||||
|
||||
|
||||
@dataclass
|
||||
@ -30,12 +35,7 @@ class RVCModelSlot(ModelSlot):
|
||||
deprecated: bool = False
|
||||
embedder: str = EnumEmbedderTypes.hubert.value
|
||||
|
||||
name: str = ""
|
||||
description: str = ""
|
||||
credit: str = ""
|
||||
termsOfUseUrl: str = ""
|
||||
sampleId: str = ""
|
||||
iconFile: str = ""
|
||||
|
||||
|
||||
@dataclass
|
||||
@ -48,10 +48,6 @@ class MMVCv13ModelSlot(ModelSlot):
|
||||
isONNX: bool = False
|
||||
samplingRate: int = 24000
|
||||
|
||||
name: str = ""
|
||||
description: str = ""
|
||||
iconFile: str = ""
|
||||
|
||||
|
||||
@dataclass
|
||||
class MMVCv15ModelSlot(ModelSlot):
|
||||
@ -60,13 +56,10 @@ class MMVCv15ModelSlot(ModelSlot):
|
||||
configFile: str = ""
|
||||
srcId: int = 0
|
||||
dstId: int = 101
|
||||
f0Factor: float = 1.0
|
||||
isONNX: bool = False
|
||||
samplingRate: int = 24000
|
||||
|
||||
name: str = ""
|
||||
description: str = ""
|
||||
iconFile: str = ""
|
||||
|
||||
|
||||
@dataclass
|
||||
class SoVitsSvc40ModelSlot(ModelSlot):
|
||||
@ -77,12 +70,11 @@ class SoVitsSvc40ModelSlot(ModelSlot):
|
||||
dstId: int = 0
|
||||
isONNX: bool = False
|
||||
|
||||
name: str = ""
|
||||
description: str = ""
|
||||
credit: str = ""
|
||||
termsOfUseUrl: str = ""
|
||||
sampleId: str = ""
|
||||
iconFile: str = ""
|
||||
|
||||
defaultTune: int = 0
|
||||
defaultClusterInferRatio: float = 0.0
|
||||
noiseScale: float = 0.0
|
||||
|
||||
|
||||
@dataclass
|
||||
@ -95,12 +87,12 @@ class DDSPSVCModelSlot(ModelSlot):
|
||||
dstId: int = 0
|
||||
isONNX: bool = False
|
||||
|
||||
name: str = ""
|
||||
description: str = ""
|
||||
credit: str = ""
|
||||
termsOfUseUrl: str = ""
|
||||
sampleId: str = ""
|
||||
iconFile: str = ""
|
||||
defaultTune: int = 0
|
||||
enhancer: bool = False
|
||||
diffusion: bool = True
|
||||
acc: int = 20
|
||||
kstep: int = 100
|
||||
|
||||
|
||||
ModelSlots: TypeAlias = Union[ModelSlot, RVCModelSlot, MMVCv13ModelSlot, MMVCv15ModelSlot, SoVitsSvc40ModelSlot, DDSPSVCModelSlot]
|
||||
|
@ -15,7 +15,7 @@ def downloadInitialSamples(mode: RVCSampleMode, model_dir: str):
|
||||
sampleJsonUrls, sampleModels = getSampleJsonAndModelIds(mode)
|
||||
sampleJsons = _downloadSampleJsons(sampleJsonUrls)
|
||||
if os.path.exists(model_dir):
|
||||
print("[Voice Changer] model_dir is already exists. skil download samples.")
|
||||
print("[Voice Changer] model_dir is already exists. skip download samples.")
|
||||
return
|
||||
samples = _generateSampleList(sampleJsons)
|
||||
slotIndex = list(range(len(sampleModels)))
|
||||
|
@ -1,12 +1,10 @@
|
||||
import sys
|
||||
import os
|
||||
from dataclasses import asdict
|
||||
from typing import cast
|
||||
import numpy as np
|
||||
import torch
|
||||
import torchaudio
|
||||
from data.ModelSlot import RVCModelSlot
|
||||
from voice_changer.ModelSlotManager import ModelSlotManager
|
||||
|
||||
|
||||
# avoiding parse arg error in RVC
|
||||
@ -22,15 +20,13 @@ if sys.platform.startswith("darwin"):
|
||||
else:
|
||||
sys.path.append("RVC")
|
||||
|
||||
from voice_changer.RVC.modelMerger.MergeModel import merge_model
|
||||
from voice_changer.RVC.modelMerger.MergeModelRequest import MergeModelRequest
|
||||
from voice_changer.RVC.ModelSlotGenerator import (
|
||||
_setInfoByONNX,
|
||||
_setInfoByPytorch,
|
||||
)
|
||||
from voice_changer.RVC.RVCSettings import RVCSettings
|
||||
from voice_changer.RVC.embedder.EmbedderManager import EmbedderManager
|
||||
from voice_changer.utils.LoadModelParams import LoadModelParams, LoadModelParams2
|
||||
from voice_changer.utils.LoadModelParams import LoadModelParams2
|
||||
from voice_changer.utils.VoiceChangerModel import AudioInOut
|
||||
from voice_changer.utils.VoiceChangerParams import VoiceChangerParams
|
||||
from voice_changer.RVC.onnxExporter.export2onnx import export2onnx
|
||||
@ -40,11 +36,6 @@ from voice_changer.RVC.deviceManager.DeviceManager import DeviceManager
|
||||
from voice_changer.RVC.pipeline.Pipeline import Pipeline
|
||||
|
||||
from Exceptions import DeviceCannotSupportHalfPrecisionException, NoModeLoadedException
|
||||
from const import (
|
||||
UPLOAD_DIR,
|
||||
)
|
||||
import shutil
|
||||
import json
|
||||
|
||||
|
||||
class RVC:
|
||||
@ -61,34 +52,29 @@ class RVC:
|
||||
currentSlot: int = 0
|
||||
needSwitch: bool = False
|
||||
|
||||
def __init__(self, params: VoiceChangerParams):
|
||||
self.pitchExtractor = PitchExtractorManager.getPitchExtractor(self.settings.f0Detector)
|
||||
self.params = params
|
||||
def __init__(self, params: VoiceChangerParams, slotInfo: RVCModelSlot):
|
||||
print("[Voice Changer][RVC] Creating instance ")
|
||||
EmbedderManager.initialize(params)
|
||||
print("[Voice Changer] RVC initialization: ", params)
|
||||
self.modelSlotManager = ModelSlotManager.get_instance(self.params.model_dir)
|
||||
|
||||
# 起動時にスロットにモデルがある場合はロードしておく
|
||||
allSlots = self.modelSlotManager.getAllSlotInfo()
|
||||
availableIndex = -1
|
||||
for i, slot in enumerate(allSlots):
|
||||
if slot.modelFile is not None and slot.modelFile != "":
|
||||
availableIndex = i
|
||||
break
|
||||
if availableIndex >= 0:
|
||||
self.prepareModel(availableIndex)
|
||||
self.settings.modelSlotIndex = availableIndex
|
||||
self.switchModel(self.settings.modelSlotIndex)
|
||||
self.initialLoad = False
|
||||
self.params = params
|
||||
self.pitchExtractor = PitchExtractorManager.getPitchExtractor(self.settings.f0Detector)
|
||||
|
||||
self.prevVol = 0.0
|
||||
self.slotInfo = slotInfo
|
||||
self.initialize()
|
||||
|
||||
def moveToModelDir(self, file: str, dstDir: str):
|
||||
dst = os.path.join(dstDir, os.path.basename(file))
|
||||
if os.path.exists(dst):
|
||||
os.remove(dst)
|
||||
shutil.move(file, dst)
|
||||
return dst
|
||||
def initialize(self):
|
||||
print("[Voice Changer][RVC] Initializing... ")
|
||||
|
||||
# pipelineの生成
|
||||
self.pipeline = createPipeline(self.slotInfo, self.settings.gpu, self.settings.f0Detector)
|
||||
|
||||
# その他の設定
|
||||
self.trans = self.slotInfo.defaultTune
|
||||
self.index_ratio = self.slotInfo.defaultIndexRatio
|
||||
self.protect = self.slotInfo.defaultProtect
|
||||
self.samplingRate = self.slotInfo.samplingRate
|
||||
print("[Voice Changer][RVC] Initializing... done")
|
||||
|
||||
@classmethod
|
||||
def loadModel2(cls, props: LoadModelParams2):
|
||||
@ -111,70 +97,13 @@ class RVC:
|
||||
_setInfoByPytorch(slotInfo)
|
||||
return slotInfo
|
||||
|
||||
def loadModel(self, props: LoadModelParams):
|
||||
target_slot_idx = props.slot
|
||||
params = props.params
|
||||
slotInfo: RVCModelSlot = RVCModelSlot()
|
||||
|
||||
print("loadModel", params)
|
||||
slotInfo.modelFile = params["files"]["rvcModel"]
|
||||
slotInfo.indexFile = params["files"]["rvcIndex"] if "rvcIndex" in params["files"] else None
|
||||
|
||||
slotInfo.defaultTune = params["defaultTune"]
|
||||
slotInfo.defaultIndexRatio = params["defaultIndexRatio"]
|
||||
slotInfo.defaultProtect = params["defaultProtect"]
|
||||
slotInfo.voiceChangerType = "RVC"
|
||||
slotInfo.isONNX = slotInfo.modelFile.endswith(".onnx")
|
||||
|
||||
if slotInfo.isONNX:
|
||||
_setInfoByONNX(slotInfo)
|
||||
else:
|
||||
_setInfoByPytorch(slotInfo)
|
||||
|
||||
# メタデータを見て、永続化モデルフォルダに移動させる
|
||||
# その際に、メタデータのファイル格納場所も書き換える
|
||||
slotDir = os.path.join(self.params.model_dir, str(target_slot_idx))
|
||||
os.makedirs(slotDir, exist_ok=True)
|
||||
slotInfo.modelFile = self.moveToModelDir(slotInfo.modelFile, slotDir)
|
||||
if slotInfo.indexFile is not None and len(slotInfo.indexFile) > 0:
|
||||
slotInfo.indexFile = self.moveToModelDir(slotInfo.indexFile, slotDir)
|
||||
if slotInfo.iconFile is not None and len(slotInfo.iconFile) > 0:
|
||||
slotInfo.iconFile = self.moveToModelDir(slotInfo.iconFile, slotDir)
|
||||
# json.dump(asdict(slotInfo), open(os.path.join(slotDir, "params.json"), "w"))
|
||||
self.modelSlotManager.save_model_slot(target_slot_idx, slotInfo)
|
||||
|
||||
# 初回のみロード(起動時にスロットにモデルがあった場合はinitialLoadはFalseになっている)
|
||||
if self.initialLoad:
|
||||
self.prepareModel(target_slot_idx)
|
||||
self.settings.modelSlotIndex = target_slot_idx
|
||||
self.switchModel(self.settings.modelSlotIndex)
|
||||
self.initialLoad = False
|
||||
elif target_slot_idx == self.currentSlot:
|
||||
self.prepareModel(target_slot_idx)
|
||||
|
||||
return self.get_info()
|
||||
|
||||
def update_settings(self, key: str, val: int | float | str):
|
||||
print("[Voice Changer][RVC]: update_settings", key, val)
|
||||
if key in self.settings.intData:
|
||||
# 設定前処理
|
||||
val = cast(int, val)
|
||||
if key == "modelSlotIndex":
|
||||
if val < 0:
|
||||
return True
|
||||
val = val % 1000 # Quick hack for same slot is selected
|
||||
allModelSlots = self.modelSlotManager.getAllSlotInfo()
|
||||
if allModelSlots[val].modelFile is None or allModelSlots[val].modelFile == "":
|
||||
print("[Voice Changer] slot does not have model.")
|
||||
return True
|
||||
self.prepareModel(val)
|
||||
|
||||
# 設定
|
||||
setattr(self.settings, key, val)
|
||||
|
||||
setattr(self.settings, key, int(val))
|
||||
if key == "gpu":
|
||||
self.deviceManager.setForceTensor(False)
|
||||
self.prepareModel(self.settings.modelSlotIndex)
|
||||
|
||||
self.initialize()
|
||||
elif key in self.settings.floatData:
|
||||
setattr(self.settings, key, float(val))
|
||||
elif key in self.settings.strData:
|
||||
@ -186,44 +115,6 @@ class RVC:
|
||||
return False
|
||||
return True
|
||||
|
||||
def prepareModel(self, slot: int):
|
||||
if slot < 0:
|
||||
print("[Voice Changer] Prepare Model of slot skip:", slot)
|
||||
return self.get_info()
|
||||
allModelSlots = self.modelSlotManager.getAllSlotInfo()
|
||||
modelSlot = allModelSlots[slot]
|
||||
|
||||
print("[Voice Changer] Prepare Model of slot:", slot)
|
||||
|
||||
# pipelineの生成
|
||||
self.next_pipeline = createPipeline(modelSlot, self.settings.gpu, self.settings.f0Detector)
|
||||
|
||||
# その他の設定
|
||||
self.next_trans = modelSlot.defaultTune
|
||||
self.next_index_ratio = modelSlot.defaultIndexRatio
|
||||
self.next_protect = modelSlot.defaultProtect
|
||||
self.next_samplingRate = modelSlot.samplingRate
|
||||
self.next_framework = "ONNX" if modelSlot.isONNX else "PyTorch"
|
||||
# self.needSwitch = True
|
||||
print("[Voice Changer] Prepare done.")
|
||||
self.switchModel(slot)
|
||||
return self.get_info()
|
||||
|
||||
def switchModel(self, slot: int):
|
||||
print("[Voice Changer] Switching model..")
|
||||
self.pipeline = self.next_pipeline
|
||||
self.settings.tran = self.next_trans
|
||||
self.settings.indexRatio = self.next_index_ratio
|
||||
self.settings.protect = self.next_protect
|
||||
self.settings.modelSamplingRate = self.next_samplingRate
|
||||
self.settings.framework = self.next_framework
|
||||
|
||||
# self.currentSlot = self.settings.modelSlotIndex # prepareModelから呼ばれるということはupdate_settingsの中で呼ばれるということなので、まだmodelSlotIndexは更新されていない
|
||||
self.currentSlot = slot
|
||||
print(
|
||||
"[Voice Changer] Switching model..done",
|
||||
)
|
||||
|
||||
def get_info(self):
|
||||
data = asdict(self.settings)
|
||||
if self.pipeline is not None:
|
||||
@ -279,22 +170,13 @@ class RVC:
|
||||
return (audio_buffer, convertSize, vol)
|
||||
|
||||
def inference(self, data):
|
||||
if self.settings.modelSlotIndex < 0:
|
||||
print(
|
||||
"[Voice Changer] wait for loading model...",
|
||||
self.settings.modelSlotIndex,
|
||||
self.currentSlot,
|
||||
)
|
||||
raise NoModeLoadedException("model_common")
|
||||
# if self.needSwitch:
|
||||
# if self.settings.modelSlotIndex < 0:
|
||||
# print(
|
||||
# f"[Voice Changer] Switch model {self.currentSlot} -> {self.settings.modelSlotIndex}"
|
||||
# "[Voice Changer] wait for loading model...",
|
||||
# self.settings.modelSlotIndex,
|
||||
# self.currentSlot,
|
||||
# )
|
||||
# self.switchModel()
|
||||
# self.needSwitch = False
|
||||
|
||||
# half = self.deviceManager.halfPrecisionAvailable(self.settings.gpu)
|
||||
# half = self.pipeline.isHalf
|
||||
# raise NoModeLoadedException("model_common")
|
||||
|
||||
audio = data[0]
|
||||
convertSize = data[1]
|
||||
@ -314,9 +196,9 @@ class RVC:
|
||||
# embOutputLayer = self.settings.modelSlots[self.currentSlot].embOutputLayer
|
||||
# useFinalProj = self.settings.modelSlots[self.currentSlot].useFinalProj
|
||||
|
||||
if_f0 = 1 if self.modelSlotManager.get_slot_info(self.currentSlot).f0 else 0
|
||||
embOutputLayer = self.modelSlotManager.get_slot_info(self.currentSlot).embOutputLayer
|
||||
useFinalProj = self.modelSlotManager.get_slot_info(self.currentSlot).useFinalProj
|
||||
if_f0 = 1 if self.slotInfo.f0 else 0
|
||||
embOutputLayer = self.slotInfo.embOutputLayer
|
||||
useFinalProj = self.slotInfo.useFinalProj
|
||||
|
||||
try:
|
||||
audio_out = self.pipeline.exec(
|
||||
@ -345,7 +227,7 @@ class RVC:
|
||||
def __del__(self):
|
||||
del self.pipeline
|
||||
|
||||
# print("---------- REMOVING ---------------")
|
||||
print("---------- REMOVING ---------------")
|
||||
|
||||
remove_path = os.path.join("RVC")
|
||||
sys.path = [x for x in sys.path if x.endswith(remove_path) is False]
|
||||
@ -378,70 +260,86 @@ class RVC:
|
||||
|
||||
def merge_models(self, request: str):
|
||||
print("[Voice Changer] MergeRequest:", request)
|
||||
req: MergeModelRequest = MergeModelRequest.from_json(request)
|
||||
merged = merge_model(req)
|
||||
targetSlot = 0
|
||||
if req.slot < 0:
|
||||
# 最後尾のスロット番号を格納先とする。
|
||||
allModelSlots = self.modelSlotManager.getAllSlotInfo()
|
||||
targetSlot = len(allModelSlots) - 1
|
||||
else:
|
||||
targetSlot = req.slot
|
||||
# req: MergeModelRequest = MergeModelRequest.from_json(request)
|
||||
# merged = merge_model(req)
|
||||
# targetSlot = 0
|
||||
# if req.slot < 0:
|
||||
# # 最後尾のスロット番号を格納先とする。
|
||||
# allModelSlots = self.modelSlotManager.getAllSlotInfo()
|
||||
# targetSlot = len(allModelSlots) - 1
|
||||
# else:
|
||||
# targetSlot = req.slot
|
||||
|
||||
# いったんは、アップロードフォルダに格納する。(歴史的経緯)
|
||||
# 後続のloadmodelを呼び出すことで永続化モデルフォルダに移動させられる。
|
||||
storeDir = os.path.join(UPLOAD_DIR, f"{targetSlot}")
|
||||
print("[Voice Changer] store merged model to:", storeDir)
|
||||
os.makedirs(storeDir, exist_ok=True)
|
||||
storeFile = os.path.join(storeDir, "merged.pth")
|
||||
torch.save(merged, storeFile)
|
||||
# # いったんは、アップロードフォルダに格納する。(歴史的経緯)
|
||||
# # 後続のloadmodelを呼び出すことで永続化モデルフォルダに移動させられる。
|
||||
# storeDir = os.path.join(UPLOAD_DIR, f"{targetSlot}")
|
||||
# print("[Voice Changer] store merged model to:", storeDir)
|
||||
# os.makedirs(storeDir, exist_ok=True)
|
||||
# storeFile = os.path.join(storeDir, "merged.pth")
|
||||
# torch.save(merged, storeFile)
|
||||
|
||||
# loadmodelを呼び出して永続化モデルフォルダに移動させる。
|
||||
params = {
|
||||
"defaultTune": req.defaultTune,
|
||||
"defaultIndexRatio": req.defaultIndexRatio,
|
||||
"defaultProtect": req.defaultProtect,
|
||||
"sampleId": "",
|
||||
"files": {"rvcModel": storeFile},
|
||||
}
|
||||
props: LoadModelParams = LoadModelParams(slot=targetSlot, isHalf=True, params=params)
|
||||
self.loadModel(props)
|
||||
self.prepareModel(targetSlot)
|
||||
self.settings.modelSlotIndex = targetSlot
|
||||
self.currentSlot = self.settings.modelSlotIndex
|
||||
# # loadmodelを呼び出して永続化モデルフォルダに移動させる。
|
||||
# params = {
|
||||
# "defaultTune": req.defaultTune,
|
||||
# "defaultIndexRatio": req.defaultIndexRatio,
|
||||
# "defaultProtect": req.defaultProtect,
|
||||
# "sampleId": "",
|
||||
# "files": {"rvcModel": storeFile},
|
||||
# }
|
||||
# props: LoadModelParams = LoadModelParams(slot=targetSlot, isHalf=True, params=params)
|
||||
# self.loadModel(props)
|
||||
# self.prepareModel(targetSlot)
|
||||
# self.settings.modelSlotIndex = targetSlot
|
||||
# self.currentSlot = self.settings.modelSlotIndex
|
||||
|
||||
def update_model_default(self):
|
||||
# {"slot":9,"key":"name","val":"dogsdododg"}
|
||||
self.modelSlotManager.update_model_info(
|
||||
json.dumps(
|
||||
{
|
||||
"slot": self.currentSlot,
|
||||
"key": "defaultTune",
|
||||
"val": self.settings.tran,
|
||||
}
|
||||
)
|
||||
)
|
||||
self.modelSlotManager.update_model_info(
|
||||
json.dumps(
|
||||
{
|
||||
"slot": self.currentSlot,
|
||||
"key": "defaultIndexRatio",
|
||||
"val": self.settings.indexRatio,
|
||||
}
|
||||
)
|
||||
)
|
||||
self.modelSlotManager.update_model_info(
|
||||
json.dumps(
|
||||
{
|
||||
"slot": self.currentSlot,
|
||||
"key": "defaultProtect",
|
||||
"val": self.settings.protect,
|
||||
}
|
||||
)
|
||||
)
|
||||
# def update_model_default(self):
|
||||
# # {"slot":9,"key":"name","val":"dogsdododg"}
|
||||
# self.modelSlotManager.update_model_info(
|
||||
# json.dumps(
|
||||
# {
|
||||
# "slot": self.currentSlot,
|
||||
# "key": "defaultTune",
|
||||
# "val": self.settings.tran,
|
||||
# }
|
||||
# )
|
||||
# )
|
||||
# self.modelSlotManager.update_model_info(
|
||||
# json.dumps(
|
||||
# {
|
||||
# "slot": self.currentSlot,
|
||||
# "key": "defaultIndexRatio",
|
||||
# "val": self.settings.indexRatio,
|
||||
# }
|
||||
# )
|
||||
# )
|
||||
# self.modelSlotManager.update_model_info(
|
||||
# json.dumps(
|
||||
# {
|
||||
# "slot": self.currentSlot,
|
||||
# "key": "defaultProtect",
|
||||
# "val": self.settings.protect,
|
||||
# }
|
||||
# )
|
||||
# )
|
||||
|
||||
def update_model_info(self, newData: str):
|
||||
self.modelSlotManager.update_model_info(newData)
|
||||
def get_model_current(self):
|
||||
return [
|
||||
{
|
||||
"key": "defaultTune",
|
||||
"val": self.settings.tran,
|
||||
},
|
||||
{
|
||||
"key": "defaultIndexRatio",
|
||||
"val": self.settings.indexRatio,
|
||||
},
|
||||
{
|
||||
"key": "defaultProtect",
|
||||
"val": self.settings.protect,
|
||||
},
|
||||
]
|
||||
|
||||
def upload_model_assets(self, params: str):
|
||||
self.modelSlotManager.store_model_assets(params)
|
||||
# def update_model_info(self, newData: str):
|
||||
# self.modelSlotManager.update_model_info(newData)
|
||||
|
||||
# def upload_model_assets(self, params: str):
|
||||
# self.modelSlotManager.store_model_assets(params)
|
||||
|
@ -19,7 +19,6 @@ class RVCSettings:
|
||||
rvcQuality: int = 0
|
||||
silenceFront: int = 1 # 0:off, 1:on
|
||||
modelSamplingRate: int = 48000
|
||||
modelSlotIndex: int = -1
|
||||
|
||||
speakers: dict[str, int] = field(default_factory=lambda: {})
|
||||
isHalf: int = 1 # 0:off, 1:on
|
||||
|
@ -80,48 +80,51 @@ class VoiceChanger:
|
||||
|
||||
print(f"VoiceChanger Initialized (GPU_NUM:{self.gpu_num}, mps_enabled:{self.mps_enabled})")
|
||||
|
||||
def switchModelType(self, modelType: ModelType):
|
||||
print("Switch Model Type:", modelType)
|
||||
try:
|
||||
if self.voiceChanger is not None:
|
||||
# return {"status": "ERROR", "msg": "vc is already selected. currently re-select is not implemented"}
|
||||
del self.voiceChanger
|
||||
self.voiceChanger = None
|
||||
def setModel(self, model: Any):
|
||||
self.voiceChanger = model
|
||||
|
||||
self.modelType = modelType
|
||||
if self.modelType == "MMVCv15":
|
||||
from voice_changer.MMVCv15.MMVCv15 import MMVCv15
|
||||
# def switchModelType(self, modelType: ModelType):
|
||||
# print("Switch Model Type:", modelType)
|
||||
# try:
|
||||
# if self.voiceChanger is not None:
|
||||
# # return {"status": "ERROR", "msg": "vc is already selected. currently re-select is not implemented"}
|
||||
# del self.voiceChanger
|
||||
# self.voiceChanger = None
|
||||
|
||||
self.voiceChanger = MMVCv15() # type: ignore
|
||||
elif self.modelType == "MMVCv13":
|
||||
from voice_changer.MMVCv13.MMVCv13 import MMVCv13
|
||||
# self.modelType = modelType
|
||||
# if self.modelType == "MMVCv15":
|
||||
# from voice_changer.MMVCv15.MMVCv15 import MMVCv15
|
||||
|
||||
self.voiceChanger = MMVCv13()
|
||||
elif self.modelType == "so-vits-svc-40v2":
|
||||
from voice_changer.SoVitsSvc40v2.SoVitsSvc40v2 import SoVitsSvc40v2
|
||||
# self.voiceChanger = MMVCv15() # type: ignore
|
||||
# elif self.modelType == "MMVCv13":
|
||||
# from voice_changer.MMVCv13.MMVCv13 import MMVCv13
|
||||
|
||||
self.voiceChanger = SoVitsSvc40v2(self.params)
|
||||
elif self.modelType == "so-vits-svc-40" or self.modelType == "so-vits-svc-40_c":
|
||||
from voice_changer.SoVitsSvc40.SoVitsSvc40 import SoVitsSvc40
|
||||
# self.voiceChanger = MMVCv13()
|
||||
# elif self.modelType == "so-vits-svc-40v2":
|
||||
# from voice_changer.SoVitsSvc40v2.SoVitsSvc40v2 import SoVitsSvc40v2
|
||||
|
||||
self.voiceChanger = SoVitsSvc40(self.params)
|
||||
elif self.modelType == "DDSP-SVC":
|
||||
from voice_changer.DDSP_SVC.DDSP_SVC import DDSP_SVC
|
||||
# self.voiceChanger = SoVitsSvc40v2(self.params)
|
||||
# elif self.modelType == "so-vits-svc-40" or self.modelType == "so-vits-svc-40_c":
|
||||
# from voice_changer.SoVitsSvc40.SoVitsSvc40 import SoVitsSvc40
|
||||
|
||||
self.voiceChanger = DDSP_SVC(self.params)
|
||||
elif self.modelType == "RVC":
|
||||
from voice_changer.RVC.RVC import RVC
|
||||
# self.voiceChanger = SoVitsSvc40(self.params)
|
||||
# elif self.modelType == "DDSP-SVC":
|
||||
# from voice_changer.DDSP_SVC.DDSP_SVC import DDSP_SVC
|
||||
|
||||
self.voiceChanger = RVC(self.params)
|
||||
else:
|
||||
from voice_changer.MMVCv13.MMVCv13 import MMVCv13
|
||||
# self.voiceChanger = DDSP_SVC(self.params)
|
||||
# elif self.modelType == "RVC":
|
||||
# from voice_changer.RVC.RVC import RVC
|
||||
|
||||
self.voiceChanger = MMVCv13()
|
||||
except Exception as e:
|
||||
print(e)
|
||||
print(traceback.format_exc())
|
||||
print("Switch Model Type:", self.voiceChanger)
|
||||
return {"status": "OK", "msg": "vc is switched."}
|
||||
# self.voiceChanger = RVC(self.params)
|
||||
# else:
|
||||
# from voice_changer.MMVCv13.MMVCv13 import MMVCv13
|
||||
|
||||
# self.voiceChanger = MMVCv13()
|
||||
# except Exception as e:
|
||||
# print(e)
|
||||
# print(traceback.format_exc())
|
||||
# print("Switch Model Type:", self.voiceChanger)
|
||||
# return {"status": "OK", "msg": "vc is switched."}
|
||||
|
||||
def getModelType(self):
|
||||
if self.modelType is not None:
|
||||
|
@ -1,3 +1,4 @@
|
||||
import json
|
||||
import os
|
||||
import shutil
|
||||
import numpy as np
|
||||
@ -9,9 +10,10 @@ from const import UPLOAD_DIR, ModelType
|
||||
from voice_changer.utils.LoadModelParams import LoadModelParamFile, LoadModelParams, LoadModelParams2
|
||||
from voice_changer.utils.VoiceChangerModel import AudioInOut
|
||||
from voice_changer.utils.VoiceChangerParams import VoiceChangerParams
|
||||
from dataclasses import dataclass, asdict
|
||||
from dataclasses import dataclass, asdict, field
|
||||
import torch
|
||||
import threading
|
||||
|
||||
# import threading
|
||||
from typing import Callable
|
||||
from typing import Any
|
||||
|
||||
@ -26,8 +28,9 @@ class GPUInfo:
|
||||
@dataclass()
|
||||
class VoiceChangerManagerSettings:
|
||||
dummy: int
|
||||
|
||||
# intData: list[str] = field(default_factory=lambda: ["slotIndex"])
|
||||
modelSlotIndex: int = -1
|
||||
# ↓mutableな物だけ列挙
|
||||
intData: list[str] = field(default_factory=lambda: ["modelSlotIndex"])
|
||||
|
||||
|
||||
class VoiceChangerManager(ServerDeviceCallbacks):
|
||||
@ -62,8 +65,8 @@ class VoiceChangerManager(ServerDeviceCallbacks):
|
||||
|
||||
self.serverDevice = ServerDevice(self)
|
||||
|
||||
thread = threading.Thread(target=self.serverDevice.start, args=())
|
||||
thread.start()
|
||||
# thread = threading.Thread(target=self.serverDevice.start, args=())
|
||||
# thread.start()
|
||||
|
||||
def _get_gpuInfos(self):
|
||||
devCount = torch.cuda.device_count()
|
||||
@ -174,12 +177,38 @@ class VoiceChangerManager(ServerDeviceCallbacks):
|
||||
else:
|
||||
return {"status": "ERROR", "msg": "no model loaded"}
|
||||
|
||||
def update_settings(self, key: str, val: str | int | float):
|
||||
self.serverDevice.update_settings(key, val)
|
||||
if hasattr(self, "voiceChanger"):
|
||||
self.voiceChanger.update_settings(key, val)
|
||||
def generateVoiceChanger(self, val: int):
|
||||
slotInfo = self.modelSlotManager.get_slot_info(val)
|
||||
if slotInfo is None:
|
||||
print(f"[Voice Changer] model slot is not found {val}")
|
||||
return
|
||||
elif slotInfo.voiceChangerType == "RVC":
|
||||
print("................RVC")
|
||||
from voice_changer.RVC.RVC import RVC
|
||||
|
||||
self.voiceChangerModel = RVC(self.params, slotInfo)
|
||||
self.voiceChanger = VoiceChanger(self.params)
|
||||
self.voiceChanger.setModel(self.voiceChangerModel)
|
||||
|
||||
else:
|
||||
return {"status": "ERROR", "msg": "no model loaded"}
|
||||
print(f"[Voice Changer] unknown voice changer model: {slotInfo.voiceChangerType}")
|
||||
del self.voiceChangerModel
|
||||
return
|
||||
|
||||
def update_settings(self, key: str, val: str | int | float):
|
||||
if key in self.settings.intData:
|
||||
newVal = int(val)
|
||||
if key == "modelSlotIndex":
|
||||
newVal = newVal % 1000
|
||||
print(f"[Voice Changer] model slot is changed {self.settings.modelSlotIndex} -> {newVal}")
|
||||
self.generateVoiceChanger(newVal)
|
||||
setattr(self.settings, key, newVal)
|
||||
|
||||
else:
|
||||
self.serverDevice.update_settings(key, val)
|
||||
if hasattr(self, "voiceChanger"):
|
||||
self.voiceChanger.update_settings(key, val)
|
||||
|
||||
return self.get_info()
|
||||
|
||||
def changeVoice(self, receivedData: AudioInOut):
|
||||
@ -206,13 +235,19 @@ class VoiceChangerManager(ServerDeviceCallbacks):
|
||||
self.emitToFunc = emitTo
|
||||
|
||||
def update_model_default(self):
|
||||
self.voiceChanger.update_model_default()
|
||||
# self.voiceChanger.update_model_default()
|
||||
current_settings = self.voiceChangerModel.get_model_current()
|
||||
for current_setting in current_settings:
|
||||
current_setting["slot"] = self.settings.modelSlotIndex
|
||||
self.modelSlotManager.update_model_info(json.dumps(current_setting))
|
||||
return self.get_info()
|
||||
|
||||
def update_model_info(self, newData: str):
|
||||
self.voiceChanger.update_model_info(newData)
|
||||
# self.voiceChanger.update_model_info(newData)
|
||||
self.modelSlotManager.update_model_info(newData)
|
||||
return self.get_info()
|
||||
|
||||
def upload_model_assets(self, params: str):
|
||||
self.voiceChanger.upload_model_assets(params)
|
||||
# self.voiceChanger.upload_model_assets(params)
|
||||
self.modelSlotManager.store_model_assets(params)
|
||||
return self.get_info()
|
||||
|
Loading…
Reference in New Issue
Block a user