remove slotindex from json

This commit is contained in:
w-okada 2023-08-05 12:33:31 +09:00
parent c08099a512
commit db97441380
18 changed files with 154 additions and 59 deletions

File diff suppressed because one or more lines are too long

View File

@ -99,7 +99,7 @@ export const MainScreen = (props: MainScreenProps) => {
const slotRow = serverSetting.serverSetting.modelSlots.map((x, index) => {
// モデルのアイコン
const generateIconArea = (slotIndex: number, iconUrl: string, tooltip: boolean) => {
const realIconUrl = iconUrl.length > 0 ? iconUrl : "/assets/icons/noimage.png";
const realIconUrl = iconUrl.length > 0 ? serverSetting.serverSetting.voiceChangerParams.model_dir + "/" + slotIndex + "/" + iconUrl.split(/[\/\\]/).pop() : "/assets/icons/noimage.png";
const iconDivClass = tooltip ? "tooltip" : "";
const iconClass = tooltip ? "model-slot-icon-pointable" : "model-slot-icon";
return (

View File

@ -40,10 +40,11 @@ export const ModelSlotArea = (_props: ModelSlotAreaProps) => {
}
const tileContainerClass = x.slotIndex == serverSetting.serverSetting.modelSlotIndex ? "model-slot-tile-container-selected" : "model-slot-tile-container";
const name = x.name.length > 8 ? x.name.substring(0, 7) + "..." : x.name;
const iconElem =
x.iconFile.length > 0 ? (
<>
<img className="model-slot-tile-icon" src={x.iconFile} alt={x.name} />
<img className="model-slot-tile-icon" src={serverSetting.serverSetting.voiceChangerParams.model_dir + "/" + x.slotIndex + "/" + x.iconFile.split(/[\/\\]/).pop()} alt={x.name} />
<div className="model-slot-tile-vctype">{x.voiceChangerType}</div>
</>
) : (

View File

@ -49,7 +49,7 @@ export const CharacterArea = (_props: CharacterAreaProps) => {
return <></>;
}
const icon = selected.iconFile.length > 0 ? selected.iconFile : "./assets/icons/human.png";
const icon = selected.iconFile.length > 0 ? serverSetting.serverSetting.voiceChangerParams.model_dir + "/" + selected.slotIndex + "/" + selected.iconFile.split(/[\/\\]/).pop() : "./assets/icons/human.png";
const selectedTermOfUseUrlLink = selected.termsOfUseUrl ? (
<a href={selected.termsOfUseUrl} target="_blank" rel="noopener noreferrer" className="portrait-area-terms-of-use-link">
[{messageBuilderState.getMessage(__filename, "terms_of_use")}]

View File

@ -306,7 +306,9 @@ export type ServerInfo = VoiceChangerServerSetting & {
memory: number,
}[]
maxInputLength: number // MMVCv15
voiceChangerParams: {
model_dir: string
}
}
export type SampleModel = {
@ -409,7 +411,10 @@ export const DefaultServerSetting: ServerInfo = {
serverAudioInputDevices: [],
serverAudioOutputDevices: [],
maxInputLength: 128 * 2048
maxInputLength: 128 * 2048,
voiceChangerParams: {
model_dir: ""
}
}
///////////////////////

View File

@ -170,4 +170,4 @@ def saveSlotInfo(model_dir: str, slotIndex: int, slotInfo: ModelSlots):
slotDir = os.path.join(model_dir, str(slotIndex))
slotInfoDict = asdict(slotInfo)
slotInfo.slotIndex = -1 # スロットインデックスは動的に注入
json.dump(slotInfoDict, open(os.path.join(slotDir, "params.json"), "w"))
json.dump(slotInfoDict, open(os.path.join(slotDir, "params.json"), "w"), indent=4)

View File

@ -109,7 +109,7 @@ def _downloadSamples(samples: list[ModelSamples], sampleModelIds: list[Tuple[str
"position": line_num,
}
)
slotInfo.modelFile = modelFilePath
slotInfo.modelFile = os.path.basename(sample.modelUrl)
line_num += 1
if targetSampleParams["useIndex"] is True and hasattr(sample, "indexUrl") and sample.indexUrl != "":
@ -124,7 +124,7 @@ def _downloadSamples(samples: list[ModelSamples], sampleModelIds: list[Tuple[str
"position": line_num,
}
)
slotInfo.indexFile = indexPath
slotInfo.indexFile = os.path.basename(sample.indexUrl)
line_num += 1
if hasattr(sample, "icon") and sample.icon != "":
@ -139,7 +139,7 @@ def _downloadSamples(samples: list[ModelSamples], sampleModelIds: list[Tuple[str
"position": line_num,
}
)
slotInfo.iconFile = iconPath
slotInfo.iconFile = os.path.basename(sample.icon)
line_num += 1
slotInfo.sampleId = sample.id
@ -169,7 +169,7 @@ def _downloadSamples(samples: list[ModelSamples], sampleModelIds: list[Tuple[str
"position": line_num,
}
)
slotInfo.modelFile = modelFilePath
slotInfo.modelFile = os.path.basename(sample.modelUrl)
line_num += 1
if hasattr(sample, "icon") and sample.icon != "":
@ -184,7 +184,7 @@ def _downloadSamples(samples: list[ModelSamples], sampleModelIds: list[Tuple[str
"position": line_num,
}
)
slotInfo.iconFile = iconPath
slotInfo.iconFile = os.path.basename(sample.icon)
line_num += 1
slotInfo.sampleId = sample.id
@ -214,11 +214,12 @@ def _downloadSamples(samples: list[ModelSamples], sampleModelIds: list[Tuple[str
logger.info("[Voice Changer] Generating metadata...")
for targetSlotIndex in slotIndex:
slotInfo = modelSlotManager.get_slot_info(targetSlotIndex)
modelPath = os.path.join(model_dir, str(slotInfo.slotIndex), os.path.basename(slotInfo.modelFile))
if slotInfo.voiceChangerType == "RVC":
if slotInfo.isONNX:
slotInfo = RVCModelSlotGenerator._setInfoByONNX(slotInfo)
slotInfo = RVCModelSlotGenerator._setInfoByONNX(modelPath, slotInfo)
else:
slotInfo = RVCModelSlotGenerator._setInfoByPytorch(slotInfo)
slotInfo = RVCModelSlotGenerator._setInfoByPytorch(modelPath, slotInfo)
modelSlotManager.save_model_slot(targetSlotIndex, slotInfo)
elif slotInfo.voiceChangerType == "Diffusion-SVC":

View File

@ -6,6 +6,7 @@ import torch
from data.ModelSlot import DDSPSVCModelSlot
from voice_changer.DDSP_SVC.deviceManager.DeviceManager import DeviceManager
from voice_changer.VoiceChangerParamsManager import VoiceChangerParamsManager
if sys.platform.startswith("darwin"):
baseDir = [x for x in sys.path if x.endswith("Contents/MacOS")]
@ -69,12 +70,15 @@ class DDSP_SVC:
def initialize(self):
self.device = self.deviceManager.getDevice(self.settings.gpu)
vcparams = VoiceChangerParamsManager.get_instance().params
modelPath = os.path.join(vcparams.model_dir, str(self.slotInfo.slotIndex), "model", self.slotInfo.modelFile)
diffPath = os.path.join(vcparams.model_dir, str(self.slotInfo.slotIndex), "diff", self.slotInfo.diffModelFile)
self.svc_model = SvcDDSP()
self.svc_model.setVCParams(self.params)
self.svc_model.update_model(self.slotInfo.modelFile, self.device)
self.svc_model.update_model(modelPath, self.device)
self.diff_model = DiffGtMel(device=self.device)
self.diff_model.flush_model(self.slotInfo.diffModelFile, ddsp_config=self.svc_model.args)
self.diff_model.flush_model(diffPath, ddsp_config=self.svc_model.args)
def update_settings(self, key: str, val: int | float | str):
if key in self.settings.intData:
@ -174,5 +178,9 @@ class DDSP_SVC:
if file_path.find("DDSP-SVC" + os.path.sep) >= 0:
# print("remove", key, file_path)
sys.modules.pop(key)
except: # type:ignore
except: # type:ignore # noqa
pass
def get_model_current(self):
return [
]

View File

@ -1,6 +1,7 @@
import sys
import os
from data.ModelSlot import MMVCv13ModelSlot
from voice_changer.VoiceChangerParamsManager import VoiceChangerParamsManager
from voice_changer.utils.VoiceChangerModel import AudioInOut
@ -63,19 +64,22 @@ class MMVCv13:
def initialize(self):
print("[Voice Changer] [MMVCv13] Initializing... ")
vcparams = VoiceChangerParamsManager.get_instance().params
configPath = os.path.join(vcparams.model_dir, str(self.slotInfo.slotIndex), self.slotInfo.configFile)
modelPath = os.path.join(vcparams.model_dir, str(self.slotInfo.slotIndex), self.slotInfo.modelFile)
self.hps = get_hparams_from_file(self.slotInfo.configFile)
self.hps = get_hparams_from_file(configPath)
if self.slotInfo.isONNX:
providers, options = self.getOnnxExecutionProvider()
self.onnx_session = onnxruntime.InferenceSession(
self.slotInfo.modelFile,
modelPath,
providers=providers,
provider_options=options,
)
else:
self.net_g = SynthesizerTrn(len(symbols), self.hps.data.filter_length // 2 + 1, self.hps.train.segment_size // self.hps.data.hop_length, n_speakers=self.hps.data.n_speakers, **self.hps.model)
self.net_g.eval()
load_checkpoint(self.slotInfo.modelFile, self.net_g, None)
load_checkpoint(modelPath, self.net_g, None)
# その他の設定
self.settings.srcId = self.slotInfo.srcId
@ -105,8 +109,10 @@ class MMVCv13:
if key == "gpu" and self.slotInfo.isONNX:
providers, options = self.getOnnxExecutionProvider()
vcparams = VoiceChangerParamsManager.get_instance().params
modelPath = os.path.join(vcparams.model_dir, str(self.slotInfo.slotIndex), self.slotInfo.modelFile)
self.onnx_session = onnxruntime.InferenceSession(
self.slotInfo.modelFile,
modelPath,
providers=providers,
provider_options=options,
)
@ -249,3 +255,15 @@ class MMVCv13:
sys.modules.pop(key)
except: # NOQA
pass
def get_model_current(self):
return [
{
"key": "srcId",
"val": self.settings.srcId,
},
{
"key": "dstId",
"val": self.settings.dstId,
}
]

View File

@ -1,6 +1,7 @@
import sys
import os
from data.ModelSlot import MMVCv15ModelSlot
from voice_changer.VoiceChangerParamsManager import VoiceChangerParamsManager
from voice_changer.utils.VoiceChangerModel import AudioInOut
if sys.platform.startswith("darwin"):
@ -70,7 +71,11 @@ class MMVCv15:
def initialize(self):
print("[Voice Changer] [MMVCv15] Initializing... ")
self.hps = get_hparams_from_file(self.slotInfo.configFile)
vcparams = VoiceChangerParamsManager.get_instance().params
configPath = os.path.join(vcparams.model_dir, str(self.slotInfo.slotIndex), self.slotInfo.configFile)
modelPath = os.path.join(vcparams.model_dir, str(self.slotInfo.slotIndex), self.slotInfo.modelFile)
self.hps = get_hparams_from_file(configPath)
self.net_g = SynthesizerTrn(
spec_channels=self.hps.data.filter_length // 2 + 1,
@ -96,7 +101,7 @@ class MMVCv15:
self.onxx_input_length = 8192
providers, options = self.getOnnxExecutionProvider()
self.onnx_session = onnxruntime.InferenceSession(
self.slotInfo.modelFile,
modelPath,
providers=providers,
provider_options=options,
)
@ -108,7 +113,7 @@ class MMVCv15:
self.settings.maxInputLength = self.onxx_input_length - (0.012 * self.hps.data.sampling_rate) - 1024 # onnxの場合は入力長固(crossfadeの1024は仮) # NOQA
else:
self.net_g.eval()
load_checkpoint(self.slotInfo.modelFile, self.net_g, None)
load_checkpoint(modelPath, self.net_g, None)
# その他の設定
self.settings.srcId = self.slotInfo.srcId
@ -139,8 +144,10 @@ class MMVCv15:
setattr(self.settings, key, val)
if key == "gpu" and self.slotInfo.isONNX:
providers, options = self.getOnnxExecutionProvider()
vcparams = VoiceChangerParamsManager.get_instance().params
modelPath = os.path.join(vcparams.model_dir, str(self.slotInfo.slotIndex), self.slotInfo.modelFile)
self.onnx_session = onnxruntime.InferenceSession(
self.slotInfo.modelFile,
modelPath,
providers=providers,
provider_options=options,
)
@ -208,7 +215,8 @@ class MMVCv15:
solaSearchFrame: int = 0,
):
# maxInputLength を更新(ここでやると非効率だが、とりあえず。)
self.settings.maxInputLength = self.onxx_input_length - crossfadeSize - solaSearchFrame # onnxの場合は入力長固(crossfadeの1024は仮) # NOQA
if self.slotInfo.isONNX:
self.settings.maxInputLength = self.onxx_input_length - crossfadeSize - solaSearchFrame # onnxの場合は入力長固(crossfadeの1024は仮) # NOQA get_infoで返る値。この関数内の処理では使わない。
newData = newData.astype(np.float32) / self.hps.data.max_wav_value
@ -310,3 +318,19 @@ class MMVCv15:
sys.modules.pop(key)
except: # NOQA
pass
def get_model_current(self):
return [
{
"key": "srcId",
"val": self.settings.srcId,
},
{
"key": "dstId",
"val": self.settings.dstId,
},
{
"key": "f0Factor",
"val": self.settings.f0Factor,
}
]

View File

@ -1,6 +1,7 @@
import os
from data.ModelSlot import MMVCv15ModelSlot
from voice_changer.VoiceChangerParamsManager import VoiceChangerParamsManager
from voice_changer.utils.LoadModelParams import LoadModelParams
from voice_changer.utils.ModelSlotGenerator import ModelSlotGenerator
@ -15,7 +16,9 @@ class MMVCv15ModelSlotGenerator(ModelSlotGenerator):
elif file.kind == "mmvcv15Config":
slotInfo.configFile = file.name
elif file.kind == "mmvcv15Correspondence":
with open(file.name, "r") as f:
vcparams = VoiceChangerParamsManager.get_instance().params
filePath = os.path.join(vcparams.model_dir, str(props.slot), file.name)
with open(filePath, "r") as f:
slotInfo.speakers = {}
while True:
line = f.readline()

View File

@ -5,7 +5,8 @@ import torch
import onnxruntime
import json
from data.ModelSlot import ModelSlot, RVCModelSlot
from data.ModelSlot import RVCModelSlot
from voice_changer.VoiceChangerParamsManager import VoiceChangerParamsManager
from voice_changer.utils.LoadModelParams import LoadModelParams
from voice_changer.utils.ModelSlotGenerator import ModelSlotGenerator
@ -13,6 +14,7 @@ from voice_changer.utils.ModelSlotGenerator import ModelSlotGenerator
class RVCModelSlotGenerator(ModelSlotGenerator):
@classmethod
def loadModel(cls, props: LoadModelParams):
vcparams = VoiceChangerParamsManager.get_instance().params
slotInfo: RVCModelSlot = RVCModelSlot()
for file in props.files:
if file.kind == "rvcModel":
@ -24,17 +26,20 @@ class RVCModelSlotGenerator(ModelSlotGenerator):
slotInfo.defaultProtect = 0.5
slotInfo.isONNX = slotInfo.modelFile.endswith(".onnx")
slotInfo.name = os.path.splitext(os.path.basename(slotInfo.modelFile))[0]
print("RVC:: slotInfo.modelFile", slotInfo.modelFile)
# slotInfo.iconFile = "/assets/icons/noimage.png"
modelPath = os.path.join(vcparams.model_dir, str(props.slot), os.path.basename(slotInfo.modelFile))
if slotInfo.isONNX:
slotInfo = cls._setInfoByONNX(slotInfo)
slotInfo = cls._setInfoByONNX(modelPath, slotInfo)
else:
slotInfo = cls._setInfoByPytorch(slotInfo)
slotInfo = cls._setInfoByPytorch(modelPath, slotInfo)
return slotInfo
@classmethod
def _setInfoByPytorch(cls, slot: ModelSlot):
cpt = torch.load(slot.modelFile, map_location="cpu")
def _setInfoByPytorch(cls, modelPath: str, slot: RVCModelSlot):
cpt = torch.load(modelPath, map_location="cpu")
config_len = len(cpt["config"])
version = cpt.get("version", "v1")
@ -113,8 +118,8 @@ class RVCModelSlotGenerator(ModelSlotGenerator):
return slot
@classmethod
def _setInfoByONNX(cls, slot: ModelSlot):
tmp_onnx_session = onnxruntime.InferenceSession(slot.modelFile, providers=["CPUExecutionProvider"])
def _setInfoByONNX(cls, modelPath: str, slot: RVCModelSlot):
tmp_onnx_session = onnxruntime.InferenceSession(modelPath, providers=["CPUExecutionProvider"])
modelmeta = tmp_onnx_session.get_modelmeta()
try:
slot = RVCModelSlot(**asdict(slot))

View File

@ -48,7 +48,7 @@ class RVCr2(VoiceChangerModel):
# pipelineの生成
try:
self.pipeline = createPipeline(self.slotInfo, self.settings.gpu, self.settings.f0Detector)
self.pipeline = createPipeline(self.params, self.slotInfo, self.settings.gpu, self.settings.f0Detector)
except PipelineCreateException as e: # NOQA
logger.error("[Voice Changer] pipeline create failed. check your model is valid.")
return

View File

@ -4,7 +4,7 @@ import torch
from onnxsim import simplify
import onnx
from const import TMP_DIR, EnumInferenceTypes
from data.ModelSlot import ModelSlot
from data.ModelSlot import RVCModelSlot
from voice_changer.RVC.deviceManager.DeviceManager import DeviceManager
from voice_changer.RVC.onnxExporter.SynthesizerTrnMs256NSFsid_ONNX import (
SynthesizerTrnMs256NSFsid_ONNX,
@ -24,10 +24,12 @@ from voice_changer.RVC.onnxExporter.SynthesizerTrnMsNSFsidNono_webui_ONNX import
from voice_changer.RVC.onnxExporter.SynthesizerTrnMsNSFsid_webui_ONNX import (
SynthesizerTrnMsNSFsid_webui_ONNX,
)
from voice_changer.VoiceChangerParamsManager import VoiceChangerParamsManager
def export2onnx(gpu: int, modelSlot: ModelSlot):
modelFile = modelSlot.modelFile
def export2onnx(gpu: int, modelSlot: RVCModelSlot):
vcparams = VoiceChangerParamsManager.get_instance().params
modelFile = os.path.join(vcparams.model_dir, str(modelSlot.slotIndex), os.path.basename(modelSlot.modelFile))
output_file = os.path.splitext(os.path.basename(modelFile))[0] + ".onnx"
output_file_simple = os.path.splitext(os.path.basename(modelFile))[0] + "_simple.onnx"

View File

@ -9,15 +9,17 @@ from voice_changer.RVC.embedder.EmbedderManager import EmbedderManager
from voice_changer.RVC.inferencer.InferencerManager import InferencerManager
from voice_changer.RVC.pipeline.Pipeline import Pipeline
from voice_changer.RVC.pitchExtractor.PitchExtractorManager import PitchExtractorManager
from voice_changer.utils.VoiceChangerParams import VoiceChangerParams
def createPipeline(modelSlot: RVCModelSlot, gpu: int, f0Detector: str):
def createPipeline(params: VoiceChangerParams, modelSlot: RVCModelSlot, gpu: int, f0Detector: str):
dev = DeviceManager.get_instance().getDevice(gpu)
half = DeviceManager.get_instance().halfPrecisionAvailable(gpu)
# Inferencer 生成
try:
inferencer = InferencerManager.getInferencer(modelSlot.modelType, modelSlot.modelFile, gpu)
modelPath = os.path.join(params.model_dir, str(modelSlot.slotIndex), os.path.basename(modelSlot.modelFile))
inferencer = InferencerManager.getInferencer(modelSlot.modelType, modelPath, gpu)
except Exception as e:
print("[Voice Changer] exception! loading inferencer", e)
traceback.print_exc()
@ -40,7 +42,8 @@ def createPipeline(modelSlot: RVCModelSlot, gpu: int, f0Detector: str):
pitchExtractor = PitchExtractorManager.getPitchExtractor(f0Detector, gpu)
# index, feature
index = _loadIndex(modelSlot)
indexPath = os.path.join(params.model_dir, str(modelSlot.slotIndex), os.path.basename(modelSlot.indexFile))
index = _loadIndex(indexPath)
pipeline = Pipeline(
embedder,
@ -55,21 +58,17 @@ def createPipeline(modelSlot: RVCModelSlot, gpu: int, f0Detector: str):
return pipeline
def _loadIndex(modelSlot: RVCModelSlot):
def _loadIndex(indexPath: str):
# Indexのロード
print("[Voice Changer] Loading index...")
# ファイル指定がない場合はNone
if modelSlot.indexFile is None:
print("[Voice Changer] Index is None, not used")
return None
# ファイル指定があってもファイルがない場合はNone
if os.path.exists(modelSlot.indexFile) is not True:
if os.path.exists(indexPath) is not True or os.path.isfile(indexPath) is not True:
print("[Voice Changer] Index file is not found")
return None
try:
print("Try loading...", modelSlot.indexFile)
index = faiss.read_index(modelSlot.indexFile)
print("Try loading...", indexPath)
index = faiss.read_index(indexPath)
except: # NOQA
print("[Voice Changer] load index failed. Use no index.")
traceback.print_exc()

View File

@ -1,6 +1,7 @@
import sys
import os
from data.ModelSlot import SoVitsSvc40ModelSlot
from voice_changer.VoiceChangerParamsManager import VoiceChangerParamsManager
from voice_changer.utils.VoiceChangerModel import AudioInOut
from voice_changer.utils.VoiceChangerParams import VoiceChangerParams
@ -92,13 +93,17 @@ class SoVitsSvc40:
def initialize(self):
print("[Voice Changer] [so-vits-svc40] Initializing... ")
self.hps = get_hparams_from_file(self.slotInfo.configFile)
vcparams = VoiceChangerParamsManager.get_instance().params
configPath = os.path.join(vcparams.model_dir, str(self.slotInfo.slotIndex), self.slotInfo.configFile)
modelPath = os.path.join(vcparams.model_dir, str(self.slotInfo.slotIndex), self.slotInfo.modelFile)
self.hps = get_hparams_from_file(configPath)
self.settings.speakers = self.hps.spk
# cluster
try:
if self.slotInfo.clusterFile is not None:
self.cluster_model = get_cluster_model(self.slotInfo.clusterFile)
clusterPath = os.path.join(vcparams.model_dir, str(self.slotInfo.slotIndex), self.slotInfo.clusterFile)
self.cluster_model = get_cluster_model(clusterPath)
else:
self.cluster_model = None
except Exception as e:
@ -110,7 +115,7 @@ class SoVitsSvc40:
if self.slotInfo.isONNX:
providers, options = self.getOnnxExecutionProvider()
self.onnx_session = onnxruntime.InferenceSession(
self.slotInfo.modelFile,
modelPath,
providers=providers,
provider_options=options,
)
@ -122,7 +127,7 @@ class SoVitsSvc40:
)
net_g.eval()
self.net_g = net_g
load_checkpoint(self.slotInfo.modelFile, self.net_g, None)
load_checkpoint(modelPath, self.net_g, None)
def getOnnxExecutionProvider(self):
availableProviders = onnxruntime.get_available_providers()
@ -379,6 +384,10 @@ class SoVitsSvc40:
except Exception: # type:ignore
pass
def get_model_current(self):
return [
]
def resize_f0(x, target_len):
source = np.array(x)

View File

@ -11,6 +11,7 @@ from voice_changer.ModelSlotManager import ModelSlotManager
from voice_changer.RVC.RVCModelMerger import RVCModelMerger
from voice_changer.VoiceChanger import VoiceChanger
from const import STORED_SETTING_FILE, UPLOAD_DIR
from voice_changer.VoiceChangerParamsManager import VoiceChangerParamsManager
from voice_changer.VoiceChangerV2 import VoiceChangerV2
from voice_changer.utils.LoadModelParams import LoadModelParamFile, LoadModelParams
from voice_changer.utils.ModelMerger import MergeElement, ModelMergerRequest
@ -120,8 +121,9 @@ class VoiceChangerManager(ServerDeviceCallbacks):
@classmethod
def get_instance(cls, params: VoiceChangerParams):
if cls._instance is None:
vcparams = VoiceChangerParamsManager.get_instance()
vcparams.setParams(params)
cls._instance = cls(params)
# cls._instance.voiceChanger = VoiceChanger(params)
return cls._instance
def loadModel(self, params: LoadModelParams):
@ -147,7 +149,7 @@ class VoiceChangerManager(ServerDeviceCallbacks):
os.makedirs(dstDir, exist_ok=True)
logger.info(f"move to {srcPath} -> {dstPath}")
shutil.move(srcPath, dstPath)
file.name = dstPath
file.name = os.path.basename(dstPath)
# メタデータ作成(各VCで定義)
if params.voiceChangerType == "RVC":
@ -188,6 +190,7 @@ class VoiceChangerManager(ServerDeviceCallbacks):
data["modelSlots"] = self.modelSlotManager.getAllSlotInfo(reload=True)
data["sampleModels"] = getSampleInfos(self.params.sample_mode)
data["python"] = sys.version
data["voiceChangerParams"] = self.params
data["status"] = "OK"

View File

@ -0,0 +1,17 @@
from voice_changer.utils.VoiceChangerParams import VoiceChangerParams
class VoiceChangerParamsManager:
_instance = None
def __init__(self):
self.params = None
@classmethod
def get_instance(cls):
if cls._instance is None:
cls._instance = cls()
return cls._instance
def setParams(self, params: VoiceChangerParams):
self.params = params