gui improvement

This commit is contained in:
w-okada 2023-07-22 13:23:43 +09:00
parent acab6644f7
commit 20e7a472be
7 changed files with 1322 additions and 246 deletions

View File

@ -1 +1,10 @@
<!doctype html><html style="width:100%;height:100%;overflow:hidden"><head><meta charset="utf-8"/><title>Voice Changer Client Demo</title><script defer="defer" src="index.js"></script></head><body style="width:100%;height:100%;margin:0"><div id="app" style="width:100%;height:100%"></div></body></html> <!DOCTYPE html>
<html style="width: 100%; height: 100%; overflow: hidden">
<head>
<meta charset="utf-8" />
<title>Voice Changer Client Demo</title>
<script defer src="index.js"></script></head>
<body style="width: 100%; height: 100%; margin: 0px">
<div id="app" style="width: 100%; height: 100%"></div>
</body>
</html>

File diff suppressed because one or more lines are too long

View File

@ -1,31 +0,0 @@
/*! regenerator-runtime -- Copyright (c) 2014-present, Facebook, Inc. -- license (MIT): https://github.com/facebook/regenerator/blob/main/LICENSE */
/**
* @license React
* react-dom.production.min.js
*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
/**
* @license React
* react.production.min.js
*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
/**
* @license React
* scheduler.production.min.js
*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/

View File

@ -144,7 +144,7 @@ export const GuiStateProvider = ({ children }: Props) => {
deviceId: "screen", deviceId: "screen",
groupId: "screen", groupId: "screen",
kind: "audioinput", kind: "audioinput",
label: "screen", label: "system(only win)",
toJSON: () => {}, toJSON: () => {},
}); });
const audioOutputs = mediaDeviceInfos.filter((x) => { const audioOutputs = mediaDeviceInfos.filter((x) => {

View File

@ -6,33 +6,33 @@ import { ModelSlotManagerDialogScreen } from "./904_ModelSlotManagerDialog";
import { checkExtention, trimfileName } from "../../utils/utils"; import { checkExtention, trimfileName } from "../../utils/utils";
export type FileUploaderScreenProps = { export type FileUploaderScreenProps = {
screen: ModelSlotManagerDialogScreen screen: ModelSlotManagerDialogScreen;
targetIndex: number targetIndex: number;
close: () => void close: () => void;
backToSlotManager: () => void backToSlotManager: () => void;
} };
export const FileUploaderScreen = (props: FileUploaderScreenProps) => { export const FileUploaderScreen = (props: FileUploaderScreenProps) => {
const { serverSetting } = useAppState() const { serverSetting } = useAppState();
const [voiceChangerType, setVoiceChangerType] = useState<VoiceChangerType>("RVC") const [voiceChangerType, setVoiceChangerType] = useState<VoiceChangerType>("RVC");
const [uploadSetting, setUploadSetting] = useState<ModelUploadSetting>() const [uploadSetting, setUploadSetting] = useState<ModelUploadSetting>();
const messageBuilderState = useMessageBuilder() const messageBuilderState = useMessageBuilder();
useMemo(() => { useMemo(() => {
messageBuilderState.setMessage(__filename, "header_message", { "ja": "ファイルをアップロードしてください. 対象:", "en": "Upload Files for " }) messageBuilderState.setMessage(__filename, "header_message", { ja: "ファイルをアップロードしてください. 対象:", en: "Upload Files for " });
messageBuilderState.setMessage(__filename, "back", { "ja": "戻る", "en": "back" }) messageBuilderState.setMessage(__filename, "back", { ja: "戻る", en: "back" });
messageBuilderState.setMessage(__filename, "select", { "ja": "ファイル選択", "en": "select file" }) messageBuilderState.setMessage(__filename, "select", { ja: "ファイル選択", en: "select file" });
messageBuilderState.setMessage(__filename, "upload", { "ja": "アップロード", "en": "upload" }) messageBuilderState.setMessage(__filename, "upload", { ja: "アップロード", en: "upload" });
messageBuilderState.setMessage(__filename, "uploading", { "ja": "アップロード中", "en": "uploading" }) messageBuilderState.setMessage(__filename, "uploading", { ja: "アップロード中", en: "uploading" });
messageBuilderState.setMessage(__filename, "alert-model-ext", { messageBuilderState.setMessage(__filename, "alert-model-ext", {
"ja": "ファイルの拡張子は次のモノである必要があります。", ja: "ファイルの拡張子は次のモノである必要があります。",
"en": "extension of file should be the following." en: "extension of file should be the following.",
}) });
messageBuilderState.setMessage(__filename, "alert-model-file", { messageBuilderState.setMessage(__filename, "alert-model-file", {
"ja": "ファイルが選択されていません", ja: "ファイルが選択されていません",
"en": "file is not selected." en: "file is not selected.",
}) });
}, []) }, []);
useEffect(() => { useEffect(() => {
setUploadSetting({ setUploadSetting({
@ -41,167 +41,198 @@ export const FileUploaderScreen = (props: FileUploaderScreenProps) => {
isSampleMode: false, isSampleMode: false,
sampleId: null, sampleId: null,
files: [], files: [],
params: {} params: {},
}) });
}, [props.targetIndex, voiceChangerType]) }, [props.targetIndex, voiceChangerType]);
const screen = useMemo(() => { const screen = useMemo(() => {
if (props.screen != "FileUploader") { if (props.screen != "FileUploader") {
return <></> return <></>;
} }
const vcTypeOptions = ( const vcTypeOptions = Object.values(VoiceChangerType).map((x) => {
Object.values(VoiceChangerType).map(x => { return (
return <option key={x} value={x}>{x}</option> <option key={x} value={x}>
}) {x}
) </option>
);
});
const checkModelSetting = (setting: ModelUploadSetting) => { const checkModelSetting = (setting: ModelUploadSetting) => {
if (setting.voiceChangerType == "RVC") { if (setting.voiceChangerType == "RVC") {
const enough = !!setting.files.find(x => { return x.kind == "rvcModel" }) const enough = !!setting.files.find((x) => {
return enough return x.kind == "rvcModel";
});
return enough;
} else if (setting.voiceChangerType == "MMVCv13") { } else if (setting.voiceChangerType == "MMVCv13") {
const enough = !!setting.files.find(x => { return x.kind == "mmvcv13Model" }) && const enough =
!!setting.files.find(x => { return x.kind == "mmvcv13Config" }) !!setting.files.find((x) => {
return enough return x.kind == "mmvcv13Model";
}) &&
!!setting.files.find((x) => {
return x.kind == "mmvcv13Config";
});
return enough;
} else if (setting.voiceChangerType == "MMVCv15") { } else if (setting.voiceChangerType == "MMVCv15") {
const enough = !!setting.files.find(x => { return x.kind == "mmvcv15Model" }) && const enough =
!!setting.files.find(x => { return x.kind == "mmvcv15Config" }) !!setting.files.find((x) => {
return enough return x.kind == "mmvcv15Model";
}) &&
!!setting.files.find((x) => {
return x.kind == "mmvcv15Config";
});
return enough;
} else if (setting.voiceChangerType == "so-vits-svc-40") { } else if (setting.voiceChangerType == "so-vits-svc-40") {
const enough = !!setting.files.find(x => { return x.kind == "soVitsSvc40Config" }) && const enough =
!!setting.files.find(x => { return x.kind == "soVitsSvc40Model" }) !!setting.files.find((x) => {
return enough return x.kind == "soVitsSvc40Config";
}) &&
!!setting.files.find((x) => {
return x.kind == "soVitsSvc40Model";
});
return enough;
} else if (setting.voiceChangerType == "DDSP-SVC") { } else if (setting.voiceChangerType == "DDSP-SVC") {
const enough = !!setting.files.find(x => { return x.kind == "ddspSvcModel" }) && const enough =
!!setting.files.find(x => { return x.kind == "ddspSvcModelConfig" }) && !!setting.files.find((x) => {
!!setting.files.find(x => { return x.kind == "ddspSvcDiffusion" }) && return x.kind == "ddspSvcModel";
!!setting.files.find(x => { return x.kind == "ddspSvcDiffusionConfig" }) }) &&
return enough !!setting.files.find((x) => {
return x.kind == "ddspSvcModelConfig";
}) &&
!!setting.files.find((x) => {
return x.kind == "ddspSvcDiffusion";
}) &&
!!setting.files.find((x) => {
return x.kind == "ddspSvcDiffusionConfig";
});
return enough;
} else if (setting.voiceChangerType == "Diffusion-SVC") { } else if (setting.voiceChangerType == "Diffusion-SVC") {
const enough = !!setting.files.find(x => { return x.kind == "diffusionSVCModel" }) const enough = !!setting.files.find((x) => {
return enough return x.kind == "diffusionSVCModel";
});
return enough;
} }
return false return false;
} };
const generateFileRow = (setting: ModelUploadSetting, title: string, kind: ModelFileKind, ext: string[], dir: string = "") => { const generateFileRow = (setting: ModelUploadSetting, title: string, kind: ModelFileKind, ext: string[], dir: string = "") => {
const selectedFile = setting.files.find(x => { return x.kind == kind }) const selectedFile = setting.files.find((x) => {
const selectedFilename = selectedFile?.file.name || "" return x.kind == kind;
});
const selectedFilename = selectedFile?.file.name || "";
return ( return (
<div key={`${title}`} className="file-uploader-file-select-row"> <div key={`${title}`} className="file-uploader-file-select-row">
<div className="file-uploader-file-select-row-label">{title}:</div> <div className="file-uploader-file-select-row-label">{title}:</div>
<div className="file-uploader-file-select-row-value" > <div className="file-uploader-file-select-row-value">{trimfileName(selectedFilename, 30)}</div>
{trimfileName(selectedFilename, 30)} <div
</div> className="file-uploader-file-select-row-button"
<div className="file-uploader-file-select-row-button" onClick={async () => { onClick={async () => {
const file = await fileSelector("") const file = await fileSelector("");
if (checkExtention(file.name, ext) == false) { if (checkExtention(file.name, ext) == false) {
const alertMessage = `${messageBuilderState.getMessage(__filename, "alert-model-ext")} ${ext}` const alertMessage = `${messageBuilderState.getMessage(__filename, "alert-model-ext")} ${ext}`;
alert(alertMessage) alert(alertMessage);
return return;
} }
if (selectedFile) { if (selectedFile) {
selectedFile.file = file selectedFile.file = file;
} else { } else {
setting.files.push({ kind: kind, file: file, dir: dir }) setting.files.push({ kind: kind, file: file, dir: dir });
} }
setUploadSetting({ ...setting }) setUploadSetting({ ...setting });
}}> }}
>
{messageBuilderState.getMessage(__filename, "select")} {messageBuilderState.getMessage(__filename, "select")}
</div> </div>
</div> </div>
) );
} };
const generateFileRowsByVCType = (vcType: VoiceChangerType) => { const generateFileRowsByVCType = (vcType: VoiceChangerType) => {
const rows: JSX.Element[] = [] const rows: JSX.Element[] = [];
if (vcType == "RVC") { if (vcType == "RVC") {
rows.push(generateFileRow(uploadSetting!, "Model", "rvcModel", ["pth", "onnx"])) rows.push(generateFileRow(uploadSetting!, "Model", "rvcModel", ["pth", "onnx"]));
rows.push(generateFileRow(uploadSetting!, "Index", "rvcIndex", ["index", "bin"])) rows.push(generateFileRow(uploadSetting!, "Index", "rvcIndex", ["index", "bin"]));
} else if (vcType == "MMVCv13") { } else if (vcType == "MMVCv13") {
rows.push(generateFileRow(uploadSetting!, "Config", "mmvcv13Config", ["json"])) rows.push(generateFileRow(uploadSetting!, "Config", "mmvcv13Config", ["json"]));
rows.push(generateFileRow(uploadSetting!, "Model", "mmvcv13Model", ["pth", "onnx"])) rows.push(generateFileRow(uploadSetting!, "Model", "mmvcv13Model", ["pth", "onnx"]));
} else if (vcType == "MMVCv15") { } else if (vcType == "MMVCv15") {
rows.push(generateFileRow(uploadSetting!, "Config", "mmvcv15Config", ["json"])) rows.push(generateFileRow(uploadSetting!, "Config", "mmvcv15Config", ["json"]));
rows.push(generateFileRow(uploadSetting!, "Corres", "mmvcv15Correspondence", ["txt"])) rows.push(generateFileRow(uploadSetting!, "Corres", "mmvcv15Correspondence", ["txt"]));
rows.push(generateFileRow(uploadSetting!, "Model", "mmvcv15Model", ["pth", "onnx"])) rows.push(generateFileRow(uploadSetting!, "Model", "mmvcv15Model", ["pth", "onnx"]));
} else if (vcType == "so-vits-svc-40") { } else if (vcType == "so-vits-svc-40") {
rows.push(generateFileRow(uploadSetting!, "Config", "soVitsSvc40Config", ["json"])) rows.push(generateFileRow(uploadSetting!, "Config", "soVitsSvc40Config", ["json"]));
rows.push(generateFileRow(uploadSetting!, "Model", "soVitsSvc40Model", ["pth"])) rows.push(generateFileRow(uploadSetting!, "Model", "soVitsSvc40Model", ["pth"]));
rows.push(generateFileRow(uploadSetting!, "Cluster", "soVitsSvc40Cluster", ["pth", "pt"])) rows.push(generateFileRow(uploadSetting!, "Cluster", "soVitsSvc40Cluster", ["pth", "pt"]));
} else if (vcType == "DDSP-SVC") { } else if (vcType == "DDSP-SVC") {
rows.push(generateFileRow(uploadSetting!, "Config", "ddspSvcModelConfig", ["yaml"], "model/")) rows.push(generateFileRow(uploadSetting!, "Config", "ddspSvcModelConfig", ["yaml"], "model/"));
rows.push(generateFileRow(uploadSetting!, "Model", "ddspSvcModel", ["pth", "pt"], "model/")) rows.push(generateFileRow(uploadSetting!, "Model", "ddspSvcModel", ["pth", "pt"], "model/"));
rows.push(generateFileRow(uploadSetting!, "Config(diff)", "ddspSvcDiffusionConfig", ["yaml"], "diff/")) rows.push(generateFileRow(uploadSetting!, "Config(diff)", "ddspSvcDiffusionConfig", ["yaml"], "diff/"));
rows.push(generateFileRow(uploadSetting!, "Model(diff)", "ddspSvcDiffusion", ["pth", "pt"], "diff/")) rows.push(generateFileRow(uploadSetting!, "Model(diff)", "ddspSvcDiffusion", ["pth", "pt"], "diff/"));
} else if(vcType == "Diffusion-SVC") { } else if (vcType == "Diffusion-SVC") {
rows.push(generateFileRow(uploadSetting!, "Model", "diffusionSVCModel", ["ptc"])) rows.push(generateFileRow(uploadSetting!, "Model(combo)", "diffusionSVCModel", ["ptc"]));
} }
return rows return rows;
} };
const fileRows = generateFileRowsByVCType(voiceChangerType) const fileRows = generateFileRowsByVCType(voiceChangerType);
// appState.serverSetting.uploadProgress == 0 ? `loading model...(wait about 20sec)` : `processing.... ${appState.serverSetting.uploadProgress.toFixed(1)}%` : "" // appState.serverSetting.uploadProgress == 0 ? `loading model...(wait about 20sec)` : `processing.... ${appState.serverSetting.uploadProgress.toFixed(1)}%` : ""
const buttonLabel = serverSetting.uploadProgress == 0 ? const buttonLabel = serverSetting.uploadProgress == 0 ? messageBuilderState.getMessage(__filename, "upload") : messageBuilderState.getMessage(__filename, "uploading") + `(${serverSetting.uploadProgress.toFixed(1)}%)`;
messageBuilderState.getMessage(__filename, "upload") :
messageBuilderState.getMessage(__filename, "uploading") + `(${serverSetting.uploadProgress.toFixed(1)}%)`
return ( return (
<div className="dialog-frame"> <div className="dialog-frame">
<div className="dialog-title">File Uploader</div> <div className="dialog-title">File Uploader</div>
<div className="dialog-fixed-size-content"> <div className="dialog-fixed-size-content">
<div className="file-uploader-header"> <div className="file-uploader-header">
{messageBuilderState.getMessage(__filename, "header_message")} Slot[{props.targetIndex}] {messageBuilderState.getMessage(__filename, "header_message")} Slot[{props.targetIndex}]
<span onClick={() => { <span
props.backToSlotManager() onClick={() => {
}} className="file-uploader-header-button">&lt;&lt;{messageBuilderState.getMessage(__filename, "back")}</span></div> props.backToSlotManager();
<div className="file-uploader-voice-changer-select" >VoiceChangerType: }}
<select value={voiceChangerType} onChange={(e) => { className="file-uploader-header-button"
setVoiceChangerType(e.target.value as VoiceChangerType) >
}}> &lt;&lt;{messageBuilderState.getMessage(__filename, "back")}
</span>
</div>
<div className="file-uploader-voice-changer-select">
VoiceChangerType:
<select
value={voiceChangerType}
onChange={(e) => {
setVoiceChangerType(e.target.value as VoiceChangerType);
}}
>
{vcTypeOptions} {vcTypeOptions}
</select> </select>
</div> </div>
<div className="file-uploader-file-select-container"> <div className="file-uploader-file-select-container">{fileRows}</div>
{fileRows}
</div>
<div className="file-uploader-file-select-upload-button-container"> <div className="file-uploader-file-select-upload-button-container">
<div className="file-uploader-file-select-upload-button" onClick={() => { <div
if (!uploadSetting) { className="file-uploader-file-select-upload-button"
return onClick={() => {
} if (!uploadSetting) {
if (serverSetting.uploadProgress != 0) { return;
return }
} if (serverSetting.uploadProgress != 0) {
if (checkModelSetting(uploadSetting)) { return;
serverSetting.uploadModel(uploadSetting).then(() => { }
props.backToSlotManager() if (checkModelSetting(uploadSetting)) {
}) serverSetting.uploadModel(uploadSetting).then(() => {
} else { props.backToSlotManager();
const errorMessage = messageBuilderState.getMessage(__filename, "alert-model-file") });
alert(errorMessage) } else {
} const errorMessage = messageBuilderState.getMessage(__filename, "alert-model-file");
}}> alert(errorMessage);
}
}}
>
{buttonLabel} {buttonLabel}
</div> </div>
</div> </div>
</div> </div>
</div> </div>
) );
}, [props.screen, props.targetIndex, voiceChangerType, uploadSetting, serverSetting.uploadModel, serverSetting.uploadProgress]);
}, [
props.screen,
props.targetIndex,
voiceChangerType,
uploadSetting,
serverSetting.uploadModel,
serverSetting.uploadProgress
])
return screen; return screen;
}; };

View File

@ -883,10 +883,10 @@ body {
flex-direction: row; flex-direction: row;
margin: 0.2rem; margin: 0.2rem;
.file-uploader-file-select-row-label { .file-uploader-file-select-row-label {
width: 5rem; width: 10rem;
} }
.file-uploader-file-select-row-value { .file-uploader-file-select-row-value {
width: 20rem; width: 15rem;
color: #f00; color: #f00;
white-space: nowrap; white-space: nowrap;
} }

View File

@ -1,76 +0,0 @@
{
"Diffusion-SVC": [
{
"id": "diffusion_combo_spk5_nl3_dl20_k50_500ep",
"voiceChangerType": "Diffusion-SVC",
"lang": "ja-JP",
"tag": ["diffsuion-svc", "torch"],
"name": "初期メン(3,20)",
"modelUrl": "https://huggingface.co/wok000/vcclient_model/resolve/main/diffusion-svc/combo_spk5_nl3_dl20_k50_500ep.ptc.bin",
"termsOfUseUrl": "https://huggingface.co/wok000/vcclient_model/raw/main/diffusion-svc/term_of_use.txt",
"icon": "https://huggingface.co/wok000/vcclient_model/resolve/main/diffusion-svc/diffusion-svc.png",
"credit": "あみたろ,つくよみちゃん,黄琴海月,黄琴まひろ,刻鳴時雨",
"description": "",
"sampleRate": 44100,
"modelType": "combo",
"f0": true,
"numOfDiffLayers":20,
"numOfNativeLayers":3,
"maxKStep":50
},
{
"id": "diffusion_combo_spk5_nl3_dl10_k50_500ep",
"voiceChangerType": "Diffusion-SVC",
"lang": "ja-JP",
"tag": ["diffsuion-svc", "torch"],
"name": "初期メン(3,10)",
"modelUrl": "https://huggingface.co/wok000/vcclient_model/resolve/main/diffusion-svc/combo_spk5_nl3_dl10_k50_500ep.ptc.bin",
"termsOfUseUrl": "https://huggingface.co/wok000/vcclient_model/raw/main/diffusion-svc/term_of_use.txt",
"icon": "https://huggingface.co/wok000/vcclient_model/resolve/main/diffusion-svc/diffusion-svc.png",
"credit": "あみたろ,つくよみちゃん,黄琴海月,黄琴まひろ,刻鳴時雨",
"description": "",
"sampleRate": 44100,
"modelType": "combo",
"f0": true,
"numOfDiffLayers":10,
"numOfNativeLayers":3,
"maxKStep":50
},
{
"id": "diffusion_combo_spk5_nl3_dl1_k50_500ep",
"voiceChangerType": "Diffusion-SVC",
"lang": "ja-JP",
"tag": ["diffsuion-svc", "torch"],
"name": "初期メン(3,1)",
"modelUrl": "https://huggingface.co/wok000/vcclient_model/resolve/main/diffusion-svc/combo_spk5_nl3_dl1_k50_500ep.ptc.bin",
"termsOfUseUrl": "https://huggingface.co/wok000/vcclient_model/raw/main/diffusion-svc/term_of_use.txt",
"icon": "https://huggingface.co/wok000/vcclient_model/resolve/main/diffusion-svc/diffusion-svc.png",
"credit": "あみたろ,つくよみちゃん,黄琴海月,黄琴まひろ,刻鳴時雨",
"description": "",
"sampleRate": 44100,
"modelType": "combo",
"f0": true,
"numOfDiffLayers":1,
"numOfNativeLayers":3,
"maxKStep":50
},
{
"id": "diffusion_combo_spk5_nl1_dl1_k50_500ep",
"voiceChangerType": "Diffusion-SVC",
"lang": "ja-JP",
"tag": ["diffsuion-svc", "torch"],
"name": "初期メン(1,1)",
"modelUrl": "https://huggingface.co/wok000/vcclient_model/resolve/main/diffusion-svc/combo_spk5_nl1_dl1_k50_500ep.ptc.bin",
"termsOfUseUrl": "https://huggingface.co/wok000/vcclient_model/raw/main/diffusion-svc/term_of_use.txt",
"icon": "https://huggingface.co/wok000/vcclient_model/resolve/main/diffusion-svc/diffusion-svc.png",
"credit": "あみたろ,つくよみちゃん,黄琴海月,黄琴まひろ,刻鳴時雨",
"description": "",
"sampleRate": 44100,
"modelType": "combo",
"f0": true,
"numOfDiffLayers":1,
"numOfNativeLayers":1,
"maxKStep":50
}
]
}