WIP: integrate vcs to new gui 4

This commit is contained in:
wataru 2023-06-23 14:00:40 +09:00
parent 776a6fd8b2
commit 4b212bd442
20 changed files with 729 additions and 83 deletions

File diff suppressed because one or more lines are too long

View File

@ -11,6 +11,7 @@ export type MainScreenProps = {
close: () => void
openSampleDownloader: (slotIndex: number) => void
openFileUploader: (slotIndex: number) => void
openEditor: (slotIndex: number) => void
}
@ -25,6 +26,7 @@ export const MainScreen = (props: MainScreenProps) => {
messageBuilderState.setMessage(__filename, "terms_of_use", { "ja": "利用規約", "en": "terms of use" })
messageBuilderState.setMessage(__filename, "sample", { "ja": "サンプル", "en": "DL sample" })
messageBuilderState.setMessage(__filename, "upload", { "ja": "アップロード", "en": "upload" })
messageBuilderState.setMessage(__filename, "edit", { "ja": "編集", "en": "edit" })
messageBuilderState.setMessage(__filename, "close", { "ja": "閉じる", "en": "close" })
}, [])
@ -219,6 +221,7 @@ export const MainScreen = (props: MainScreenProps) => {
<div className="model-slot-buttons">
<div className="model-slot-button" onClick={() => { props.openFileUploader(index) }} >{messageBuilderState.getMessage(__filename, "upload")}</div>
<div className="model-slot-button" onClick={() => { props.openSampleDownloader(index) }} >{messageBuilderState.getMessage(__filename, "sample")}</div>
<div className="model-slot-button" onClick={() => { props.openEditor(index) }} >{messageBuilderState.getMessage(__filename, "edit")}</div>
</div>
</div >
)

View File

@ -170,7 +170,9 @@ export const FileUploaderScreen = (props: FileUploaderScreenProps) => {
return
}
if (checkModelSetting(uploadSetting)) {
serverSetting.uploadModel(uploadSetting)
serverSetting.uploadModel(uploadSetting).then(() => {
props.backToSlotManager()
})
} else {
const errorMessage = messageBuilderState.getMessage(__filename, "alert-model-file")
alert(errorMessage)

View File

@ -0,0 +1,108 @@
import React, { useEffect, useMemo, useState } from "react";
import { useAppState } from "../../001_provider/001_AppStateProvider";
import { useMessageBuilder } from "../../hooks/useMessageBuilder";
import { ModelSlotManagerDialogScreen } from "./904_ModelSlotManagerDialog";
export type EditorScreenProps = {
screen: ModelSlotManagerDialogScreen
targetIndex: number
close: () => void
backToSlotManager: () => void
}
export const EditorScreen = (props: EditorScreenProps) => {
const { serverSetting } = useAppState()
const messageBuilderState = useMessageBuilder()
const [targetId, setTargetId] = useState<number>(0)
const [targetName, setTargetName] = useState<string>()
useMemo(() => {
messageBuilderState.setMessage(__filename, "header_message", { "ja": "詳細設定: ", "en": "Edit " })
messageBuilderState.setMessage(__filename, "edit_speaker", { "ja": "話者登録", "en": "Speaker ID" })
messageBuilderState.setMessage(__filename, "back", { "ja": "戻る", "en": "back" })
}, [])
useEffect(() => {
const targetSlot = serverSetting.serverSetting.modelSlots[props.targetIndex]
if (!targetSlot) {
return
}
const currentName = !!targetSlot.speakers[targetId] ? targetSlot.speakers[targetId] : ""
setTargetName(currentName)
}, [targetId])
const screen = useMemo(() => {
if (props.screen != "Editor") {
return <></>
}
const targetSlot = serverSetting.serverSetting.modelSlots[props.targetIndex]
return (
<div className="dialog-frame">
<div className="dialog-title">Model Slot Editor</div>
<div className="dialog-fixed-size-content">
<div className="file-uploader-header">
{messageBuilderState.getMessage(__filename, "header_message")} Slot[{props.targetIndex}]
<span onClick={() => {
props.backToSlotManager()
}} className="file-uploader-header-button">&lt;&lt;{messageBuilderState.getMessage(__filename, "back")}</span></div>
<div className="edit-model-slot-row">
<div className="edit-model-slot-title">
{messageBuilderState.getMessage(__filename, "edit_speaker")}
</div>
<div className="edit-model-slot-speakers">
<div className="edit-model-slot-speakers-id-label">
ID:
</div>
<div className="edit-model-slot-speakers-id-select">
<select name="" id="" value={targetId} onChange={(e) => { setTargetId(Number(e.target.value)) }}>
{
[...Array(127).keys()].map(x => { return <option key={x} value={x}>{x}</option> })
}
</select>
</div>
<div className="edit-model-slot-speakers-name-label">
Name:
</div>
<div className="edit-model-slot-speakers-name-input">
<input id="edit-model-slot-speakers-name-input" value={targetName} onChange={(e) => { setTargetName(e.target.value) }} />
</div>
<div className="edit-model-slot-speakers-buttons">
<div className="edit-model-slot-speakers-button" onClick={async () => {
const inputElem = document.getElementById("edit-model-slot-speakers-name-input") as HTMLInputElement
targetSlot.speakers[targetId] = inputElem.value
await serverSetting.updateModelInfo(props.targetIndex, "speakers", JSON.stringify(targetSlot.speakers))
}
}>set</div>
<div className="edit-model-slot-speakers-button" onClick={async () => {
delete targetSlot.speakers[targetId]
await serverSetting.updateModelInfo(props.targetIndex, "speakers", JSON.stringify(targetSlot.speakers))
}
}>del</div>
</div>
</div>
</div>
<div className="edit-model-slot-row">
</div>
</div>
</div>
)
}, [
props.screen,
props.targetIndex,
targetId,
targetName
])
return screen;
};

View File

@ -3,6 +3,7 @@ import { useGuiState } from "./001_GuiStateProvider";
import { MainScreen } from "./904-1_MainScreen";
import { SampleDownloaderScreen } from "./904-2_SampleDownloader";
import { FileUploaderScreen } from "./904-3_FileUploader";
import { EditorScreen } from "./904-4_Editor";
export type uploadData = {
slot: number
@ -19,7 +20,8 @@ export type ModelSlotSettingMode = typeof ModelSlotSettingMode[keyof typeof Mode
export const ModelSlotManagerDialogScreen = {
"Main": "Main",
"SampleDownloader": "SampleDownloader",
"FileUploader": "FileUploader"
"FileUploader": "FileUploader",
"Editor": "Editor"
} as const
export type ModelSlotManagerDialogScreen = typeof ModelSlotManagerDialogScreen[keyof typeof ModelSlotManagerDialogScreen]
@ -33,13 +35,17 @@ export const ModelSlotManagerDialog = () => {
const close = () => { guiState.stateControls.showModelSlotManagerCheckbox.updateState(false) }
const openSampleDownloader = (index: number) => { setTargetIndex(index); setScreen("SampleDownloader") }
const openFileUploader = (index: number) => { setTargetIndex(index); setScreen("FileUploader") }
const openEditor = (index: number) => { setTargetIndex(index); setScreen("Editor") }
const backToSlotManager = () => { setScreen("Main") }
const mainScreen = (
<MainScreen
screen={screen}
close={close}
openSampleDownloader={openSampleDownloader}
openFileUploader={openFileUploader} />
openFileUploader={openFileUploader}
openEditor={openEditor}
/>
)
const sampleDownloaderScreen = (
<SampleDownloaderScreen
@ -55,11 +61,19 @@ export const ModelSlotManagerDialog = () => {
close={close}
backToSlotManager={backToSlotManager} />
)
const editorScreen = (
<EditorScreen
screen={screen}
targetIndex={targetIndex}
close={close}
backToSlotManager={backToSlotManager} />
)
return (
<div className="dialog-frame">
{mainScreen}
{sampleDownloaderScreen}
{fileUploaderScreen}
{editorScreen}
</div>
)
}, [screen, targetIndex])

View File

@ -0,0 +1,55 @@
import React, { useMemo } from "react"
import { useAppState } from "../../../001_provider/001_AppStateProvider"
export type TuningAreaProps = {
}
export const TuningArea = (_props: TuningAreaProps) => {
const { serverSetting } = useAppState()
const selected = useMemo(() => {
if (serverSetting.serverSetting.modelSlotIndex == undefined) {
return
}
return serverSetting.serverSetting.modelSlots[serverSetting.serverSetting.modelSlotIndex]
}, [serverSetting.serverSetting.modelSlotIndex, serverSetting.serverSetting.modelSlots])
const tuningArea = useMemo(() => {
if (!selected) {
return <></>
}
if (selected.voiceChangerType == "MMVCv13" || selected.voiceChangerType == "MMVCv15") {
return <></>
}
const currentTuning = serverSetting.serverSetting.tran
const tranValueUpdatedAction = async (val: number) => {
await serverSetting.updateServerSettings({ ...serverSetting.serverSetting, tran: val })
}
return (
<div className="character-area-control">
<div className="character-area-control-title">
TUNE:
</div>
<div className="character-area-control-field">
<div className="character-area-slider-control">
<span className="character-area-slider-control-kind"></span>
<span className="character-area-slider-control-slider">
<input type="range" min="-50" max="50" step="1" value={currentTuning} onChange={(e) => {
tranValueUpdatedAction(Number(e.target.value))
}}></input>
</span>
<span className="character-area-slider-control-val">{currentTuning}</span>
</div>
</div>
</div>
)
}, [serverSetting.serverSetting, serverSetting.updateServerSettings, selected])
return tuningArea
}

View File

@ -0,0 +1,56 @@
import React, { useMemo } from "react"
import { useAppState } from "../../../001_provider/001_AppStateProvider"
export type IndexAreaProps = {
}
export const IndexArea = (_props: IndexAreaProps) => {
const { serverSetting } = useAppState()
const selected = useMemo(() => {
if (serverSetting.serverSetting.modelSlotIndex == undefined) {
return
}
return serverSetting.serverSetting.modelSlots[serverSetting.serverSetting.modelSlotIndex]
}, [serverSetting.serverSetting.modelSlotIndex, serverSetting.serverSetting.modelSlots])
const indexArea = useMemo(() => {
if (!selected) {
return <></>
}
if (selected.voiceChangerType != "RVC") {
return <></>
}
const currentIndexRatio = serverSetting.serverSetting.indexRatio
const indexRatioValueUpdatedAction = async (val: number) => {
await serverSetting.updateServerSettings({ ...serverSetting.serverSetting, indexRatio: val })
}
return (
<div className="character-area-control">
<div className="character-area-control-title">
INDEX:
</div>
<div className="character-area-control-field">
<div className="character-area-slider-control">
<span className="character-area-slider-control-kind"></span>
<span className="character-area-slider-control-slider">
<input type="range" min="0" max="1" step="0.1" value={currentIndexRatio} onChange={(e) => {
indexRatioValueUpdatedAction(Number(e.target.value))
}}></input>
</span>
<span className="character-area-slider-control-val">{currentIndexRatio}</span>
</div>
</div>
</div>
)
}, [serverSetting.serverSetting, serverSetting.updateServerSettings, selected])
return indexArea
}

View File

@ -0,0 +1,113 @@
import React, { useMemo } from "react"
import { useAppState } from "../../../001_provider/001_AppStateProvider"
export type SpeakerAreaProps = {
}
export const SpeakerArea = (_props: SpeakerAreaProps) => {
const { serverSetting } = useAppState()
const selected = useMemo(() => {
if (serverSetting.serverSetting.modelSlotIndex == undefined) {
return
}
return serverSetting.serverSetting.modelSlots[serverSetting.serverSetting.modelSlotIndex]
}, [serverSetting.serverSetting.modelSlotIndex, serverSetting.serverSetting.modelSlots])
const srcArea = useMemo(() => {
if (!selected) {
return <></>
}
if (selected.voiceChangerType != "MMVCv13" && selected.voiceChangerType != "MMVCv15") {
return <></>
}
const options = Object.keys(selected.speakers).map(key => {
const val = selected.speakers[Number(key)]
return (
<option key={key} value={key}>{val}[{key}]</option>
)
})
const srcSpeakerValueUpdatedAction = async (val: number) => {
await serverSetting.updateServerSettings({ ...serverSetting.serverSetting, srcId: val })
}
return (
<div className="character-area-control">
<div className="character-area-control-title">
Voice:
</div>
<div className="character-area-control-field">
<div className="character-area-slider-control">
<span className="character-area-slider-control-kind">src</span>
<span className="character-area-slider-control-slider">
<select value={serverSetting.serverSetting.srcId} onChange={(e) => { srcSpeakerValueUpdatedAction(Number(e.target.value)) }}>
{options}
</select>
</span>
</div>
</div>
</div >
)
}, [serverSetting.serverSetting, serverSetting.updateServerSettings, selected])
const dstArea = useMemo(() => {
if (!selected) {
return <></>
}
const options = Object.keys(selected.speakers).map(key => {
const val = selected.speakers[Number(key)]
return (
<option key={key} value={key}>{val}[{key}]</option>
)
})
const srcSpeakerValueUpdatedAction = async (val: number) => {
await serverSetting.updateServerSettings({ ...serverSetting.serverSetting, dstId: val })
}
return (
<div className="character-area-control">
<div className="character-area-control-title">
{
selected.voiceChangerType == "DDSP-SVC" ||
selected.voiceChangerType == "so-vits-svc-40" ||
selected.voiceChangerType == "RVC" ? "Voice:" : ""
}
</div>
<div className="character-area-control-field">
<div className="character-area-slider-control">
<span className="character-area-slider-control-kind">
{
selected.voiceChangerType == "MMVCv13" ||
selected.voiceChangerType == "MMVCv15" ? "dst" : ""
}
</span>
<span className="character-area-slider-control-slider">
<select value={serverSetting.serverSetting.dstId} onChange={(e) => { srcSpeakerValueUpdatedAction(Number(e.target.value)) }}>
{options}
</select>
</span>
</div>
</div>
</div >
)
}, [serverSetting.serverSetting, serverSetting.updateServerSettings, selected])
return (
<>
{srcArea}
{dstArea}
</>
)
}

View File

@ -0,0 +1,53 @@
import React, { useMemo } from "react"
import { useAppState } from "../../../001_provider/001_AppStateProvider"
export type SpeakerAreaProps = {
}
export const F0FactorArea = (_props: SpeakerAreaProps) => {
const { serverSetting } = useAppState()
const selected = useMemo(() => {
if (serverSetting.serverSetting.modelSlotIndex == undefined) {
return
}
return serverSetting.serverSetting.modelSlots[serverSetting.serverSetting.modelSlotIndex]
}, [serverSetting.serverSetting.modelSlotIndex, serverSetting.serverSetting.modelSlots])
const f0FactorArea = useMemo(() => {
if (!selected) {
return <></>
}
if (selected.voiceChangerType != "MMVCv15") {
return <></>
}
return (
<div className="character-area-control">
<div className="character-area-control-title">
F0Factor:
</div>
<div className="character-area-control-field">
<div className="character-area-slider-control">
<span className="character-area-slider-control-kind"></span>
<span className="character-area-slider-control-slider">
<input type="range" min="0.01" max="5.00" step="0.01" value={serverSetting.serverSetting.f0Factor} onChange={(e) => {
serverSetting.updateServerSettings({ ...serverSetting.serverSetting, f0Factor: Number(e.target.value) })
}}></input>
</span>
<span className="character-area-slider-control-val">{serverSetting.serverSetting.f0Factor}</span>
</div>
</div>
</div>
)
}, [serverSetting.serverSetting, serverSetting.updateServerSettings, selected])
return f0FactorArea
}

View File

@ -0,0 +1,81 @@
import React, { useMemo } from "react"
import { useAppState } from "../../../001_provider/001_AppStateProvider"
export type SoVitsSVC40SettingAreaProps = {
}
export const SoVitsSVC40SettingArea = (_props: SoVitsSVC40SettingAreaProps) => {
const { serverSetting } = useAppState()
const selected = useMemo(() => {
if (serverSetting.serverSetting.modelSlotIndex == undefined) {
return
}
return serverSetting.serverSetting.modelSlots[serverSetting.serverSetting.modelSlotIndex]
}, [serverSetting.serverSetting.modelSlotIndex, serverSetting.serverSetting.modelSlots])
const settingArea = useMemo(() => {
if (!selected) {
return <></>
}
if (selected.voiceChangerType != "so-vits-svc-40") {
return <></>
}
const cluster = (
<div className="character-area-control">
<div className="character-area-control-title">
Cluster:
</div>
<div className="character-area-control-field">
<div className="character-area-slider-control">
<span className="character-area-slider-control-kind"></span>
<span className="character-area-slider-control-slider">
<input type="range" min="0" max="1.0" step="0.1" value={serverSetting.serverSetting.clusterInferRatio} onChange={(e) => {
serverSetting.updateServerSettings({ ...serverSetting.serverSetting, clusterInferRatio: Number(e.target.value) })
}}></input>
</span>
<span className="character-area-slider-control-val">{serverSetting.serverSetting.clusterInferRatio}</span>
</div>
</div>
</div>
)
const noise = (
<div className="character-area-control">
<div className="character-area-control-title">
Noise:
</div>
<div className="character-area-control-field">
<div className="character-area-slider-control">
<span className="character-area-slider-control-kind"></span>
<span className="character-area-slider-control-slider">
<input type="range" min="0" max="1.0" step="0.1" value={serverSetting.serverSetting.noiseScale} onChange={(e) => {
serverSetting.updateServerSettings({ ...serverSetting.serverSetting, noiseScale: Number(e.target.value) })
}}></input>
</span>
<span className="character-area-slider-control-val">{serverSetting.serverSetting.noiseScale}</span>
</div>
</div>
</div>
)
return (
<>
{cluster}
{noise}
</>
)
}, [serverSetting.serverSetting, serverSetting.updateServerSettings, selected])
return settingArea
}

View File

@ -0,0 +1,81 @@
import React, { useMemo } from "react"
import { useAppState } from "../../../001_provider/001_AppStateProvider"
export type DDSPSVC30SettingAreaProps = {
}
export const DDSPSVC30SettingArea = (_props: DDSPSVC30SettingAreaProps) => {
const { serverSetting } = useAppState()
const selected = useMemo(() => {
if (serverSetting.serverSetting.modelSlotIndex == undefined) {
return
}
return serverSetting.serverSetting.modelSlots[serverSetting.serverSetting.modelSlotIndex]
}, [serverSetting.serverSetting.modelSlotIndex, serverSetting.serverSetting.modelSlots])
const settingArea = useMemo(() => {
if (!selected) {
return <></>
}
if (selected.voiceChangerType != "DDSP-SVC") {
return <></>
}
const acc = (
<div className="character-area-control">
<div className="character-area-control-title">
ACC:
</div>
<div className="character-area-control-field">
<div className="character-area-slider-control">
<span className="character-area-slider-control-kind"></span>
<span className="character-area-slider-control-slider">
<input type="range" min="1" max="20" step="1" value={serverSetting.serverSetting.diffAcc} onChange={(e) => {
serverSetting.updateServerSettings({ ...serverSetting.serverSetting, diffAcc: Number(e.target.value) })
}}></input>
</span>
<span className="character-area-slider-control-val">{serverSetting.serverSetting.diffAcc}</span>
</div>
</div>
</div>
)
const kstep = (
<div className="character-area-control">
<div className="character-area-control-title">
Kstep:
</div>
<div className="character-area-control-field">
<div className="character-area-slider-control">
<span className="character-area-slider-control-kind"></span>
<span className="character-area-slider-control-slider">
<input type="range" min="21" max="300" step="1" value={serverSetting.serverSetting.kStep} onChange={(e) => {
serverSetting.updateServerSettings({ ...serverSetting.serverSetting, kStep: Number(e.target.value) })
}}></input>
</span>
<span className="character-area-slider-control-val">{serverSetting.serverSetting.kStep}</span>
</div>
</div>
</div>
)
return (
<>
{acc}
{kstep}
</>
)
}, [serverSetting.serverSetting, serverSetting.updateServerSettings, selected])
return settingArea
}

View File

@ -3,6 +3,12 @@ import { useAppState } from "../../../001_provider/001_AppStateProvider"
import { useGuiState } from "../001_GuiStateProvider"
import { OnnxExporterInfo } from "@dannadori/voice-changer-client-js"
import { useMessageBuilder } from "../../../hooks/useMessageBuilder"
import { TuningArea } from "./101-1_TuningArea"
import { IndexArea } from "./101-2_IndexArea"
import { SpeakerArea } from "./101-3_SpeakerArea"
import { F0FactorArea } from "./101-4_F0FactorArea"
import { SoVitsSVC40SettingArea } from "./101-5_so-vits-svc40SettingArea"
import { DDSPSVC30SettingArea } from "./101-6_ddsp-svc30SettingArea"
export type CharacterAreaProps = {
}
@ -178,60 +184,6 @@ export const CharacterArea = (_props: CharacterAreaProps) => {
)
}, [serverSetting.serverSetting, clientSetting.clientSetting, clientSetting.updateClientSetting, serverSetting.updateServerSettings])
const tuningCotrol = useMemo(() => {
const currentTuning = serverSetting.serverSetting.tran
const tranValueUpdatedAction = async (val: number) => {
await serverSetting.updateServerSettings({ ...serverSetting.serverSetting, tran: val })
}
return (
<div className="character-area-control">
<div className="character-area-control-title">
TUNE:
</div>
<div className="character-area-control-field">
<div className="character-area-slider-control">
<span className="character-area-slider-control-kind"></span>
<span className="character-area-slider-control-slider">
<input type="range" min="-50" max="50" step="1" value={currentTuning} onChange={(e) => {
tranValueUpdatedAction(Number(e.target.value))
}}></input>
</span>
<span className="character-area-slider-control-val">{currentTuning}</span>
</div>
</div>
</div>
)
}, [serverSetting.serverSetting, clientSetting.updateClientSetting])
const indexCotrol = useMemo(() => {
const currentIndexRatio = serverSetting.serverSetting.indexRatio
const indexRatioValueUpdatedAction = async (val: number) => {
await serverSetting.updateServerSettings({ ...serverSetting.serverSetting, indexRatio: val })
}
return (
<div className="character-area-control">
<div className="character-area-control-title">
INDEX:
</div>
<div className="character-area-control-field">
<div className="character-area-slider-control">
<span className="character-area-slider-control-kind"></span>
<span className="character-area-slider-control-slider">
<input type="range" min="0" max="1" step="0.1" value={currentIndexRatio} onChange={(e) => {
indexRatioValueUpdatedAction(Number(e.target.value))
}}></input>
</span>
<span className="character-area-slider-control-val">{currentIndexRatio}</span>
</div>
</div>
</div>
)
}, [serverSetting.serverSetting, clientSetting.updateClientSetting])
const modelSlotControl = useMemo(() => {
@ -261,7 +213,7 @@ export const CharacterArea = (_props: CharacterAreaProps) => {
}
const exportOnnx = selected.modelFile.endsWith("pth") ? (
const exportOnnx = selected.voiceChangerType == "RVC" && selected.modelFile.endsWith("pth") ? (
<div className="character-area-button" onClick={onnxExportButtonAction}>{messageBuilderState.getMessage(__filename, "export_to_onnx")}</div>
) : <></>
return (
@ -286,13 +238,17 @@ export const CharacterArea = (_props: CharacterAreaProps) => {
<div className="character-area-control-area">
{startControl}
{gainControl}
{tuningCotrol}
{indexCotrol}
<TuningArea />
<IndexArea />
<SpeakerArea />
<F0FactorArea />
<SoVitsSVC40SettingArea />
<DDSPSVC30SettingArea />
{modelSlotControl}
</div>
</div>
)
}, [portrait, startControl, gainControl, tuningCotrol, modelSlotControl])
}, [portrait, startControl, gainControl, modelSlotControl])
return characterArea
}

View File

@ -870,7 +870,8 @@ body {
}
}
.file-uploader-voice-changer-select {
.file-uploader-voice-changer-select,
.edit-model-slot-title {
font-size: 1rem;
padding-left: 0.5rem;
}
@ -923,6 +924,39 @@ body {
}
}
}
.edit-model-slot-row {
display: flex;
flex-direction: row;
.edit-model-slot-title {
}
.edit-model-slot-speakers {
display: flex;
flex-direction: row;
margin: 0px 0px 0px 1rem;
.edit-model-slot-speakers-id-label,
.edit-model-slot-speakers-name-label {
margin: 0px 0px 0px 0.5rem;
}
.edit-model-slot-speakers-buttons {
margin: 0px 0px 0px 0.5rem;
display: flex;
flex-direction: row;
.edit-model-slot-speakers-button {
margin: 0px 0.5rem 0px 0.5rem;
user-select: none;
border: solid 1px #999;
border-radius: 2px;
cursor: pointer;
vertical-align: middle;
text-align: center;
padding: 0px 10px 0px 10px;
&:hover {
border: solid 1px #000;
}
}
}
}
}
}
}
}
@ -1250,8 +1284,9 @@ body {
}
}
}
.character-area-control-title {
width: 3rem;
width: 4rem;
font-weight: 700;
}
.character-area-control-field {

View File

@ -217,6 +217,7 @@ type ModelSlot = {
credit: string,
termsOfUseUrl: string,
iconFile: string
speakers: { [key: number]: string }
}
export type RVCModelSlot = ModelSlot & {
@ -240,6 +241,7 @@ export type MMVCv13ModelSlot = ModelSlot & {
dstId: number
samplingRate: number
speakers: { [key: number]: string }
}
export type MMVCv15ModelSlot = ModelSlot & {
@ -249,6 +251,7 @@ export type MMVCv15ModelSlot = ModelSlot & {
dstId: number
f0Factor: number
samplingRate: number
}
export type SoVitsSvc40ModelSlot = ModelSlot & {
@ -262,6 +265,7 @@ export type SoVitsSvc40ModelSlot = ModelSlot & {
defaultTune: number
defaultClusterInferRatio: number
noiseScale: number
speakers: { [key: number]: string }
}
export type DDSPSVCModelSlot = ModelSlot & {
@ -278,6 +282,7 @@ export type DDSPSVCModelSlot = ModelSlot & {
diffusion: boolean
acc: number
kstep: number
speakers: { [key: number]: string }
}
export type ModelSlotUnion = RVCModelSlot | MMVCv13ModelSlot | MMVCv15ModelSlot | SoVitsSvc40ModelSlot | DDSPSVCModelSlot

View File

@ -1,7 +1,7 @@
from typing import TypeAlias, Union
from const import MAX_SLOT_NUM, EnumInferenceTypes, EnumEmbedderTypes, VoiceChangerType
from dataclasses import dataclass, asdict
from dataclasses import dataclass, asdict, field
import os
import json
@ -15,6 +15,7 @@ class ModelSlot:
credit: str = ""
termsOfUseUrl: str = ""
iconFile: str = ""
speakers: dict = field(default_factory=lambda: {})
@dataclass
@ -36,6 +37,7 @@ class RVCModelSlot(ModelSlot):
embedder: str = EnumEmbedderTypes.hubert.value
sampleId: str = ""
speakers: dict = field(default_factory=lambda: {0: "target"})
@dataclass
@ -47,6 +49,7 @@ class MMVCv13ModelSlot(ModelSlot):
dstId: int = 100
isONNX: bool = False
samplingRate: int = 24000
speakers: dict = field(default_factory=lambda: {107: "user", 100: "zundamon", 101: "sora", 102: "methane", 103: "tsumugi"})
@dataclass
@ -59,6 +62,7 @@ class MMVCv15ModelSlot(ModelSlot):
f0Factor: float = 1.0
isONNX: bool = False
samplingRate: int = 24000
speakers: dict = field(default_factory=lambda: {0: "user", 101: "zundamon", 102: "sora", 103: "methane", 104: "tsumugi"})
@dataclass
@ -75,6 +79,7 @@ class SoVitsSvc40ModelSlot(ModelSlot):
defaultTune: int = 0
defaultClusterInferRatio: float = 0.0
noiseScale: float = 0.0
speakers: dict = field(default_factory=lambda: {1: "user"})
@dataclass
@ -93,6 +98,7 @@ class DDSPSVCModelSlot(ModelSlot):
diffusion: bool = True
acc: int = 20
kstep: int = 100
speakers: dict = field(default_factory=lambda: {1: "user"})
ModelSlots: TypeAlias = Union[ModelSlot, RVCModelSlot, MMVCv13ModelSlot, MMVCv15ModelSlot, SoVitsSvc40ModelSlot, DDSPSVCModelSlot]

View File

@ -119,7 +119,6 @@ class SvcDDSP:
audio_t = torch.from_numpy(audio).float().unsqueeze(0).to(self.device)
# extract f0
print("pitch_extractor_type", pitch_extractor_type)
pitch_extractor = F0_Extractor(pitch_extractor_type, sample_rate, hop_size, float(f0_min), float(f0_max))
f0 = pitch_extractor.extract(audio, uv_interp=True, device=self.device, silence_front=silence_front)
f0 = torch.from_numpy(f0).float().to(self.device).unsqueeze(-1).unsqueeze(0)

View File

@ -1,6 +1,6 @@
import os
import numpy as np
import yaml
import yaml # type: ignore
import torch
import torch.nn.functional as F
import pyworld as pw
@ -72,7 +72,7 @@ class F0_Extractor:
f0 = np.pad(f0, (start_frame, 0))
else:
raise ValueError(f" [x] Unknown f0 extractor: {f0_extractor}")
raise ValueError(f" [x] Unknown f0 extractor: {f0_extractor}") # NOQA # type: ignore
# interpolate the unvoiced f0
if uv_interp:
@ -410,12 +410,12 @@ class Audio2HubertLarge1024L24:
class DotDict(dict):
def __getattr__(*args):
def __getattr__(*args): # type: ignore
val = dict.get(*args)
return DotDict(val) if type(val) is dict else val
__setattr__ = dict.__setitem__
__delattr__ = dict.__delitem__
__setattr__ = dict.__setitem__ # type: ignore
__delattr__ = dict.__delitem__ # type: ignore
def load_model(model_path, device="cpu"):

View File

@ -1,5 +1,5 @@
import os
import yaml
import yaml # type: ignore
import torch
import torch.nn as nn
import numpy as np
@ -9,12 +9,12 @@ from .vocoder import Vocoder
class DotDict(dict):
def __getattr__(*args):
def __getattr__(*args): # type: ignore
val = dict.get(*args)
return DotDict(val) if type(val) is dict else val
__setattr__ = dict.__setitem__
__delattr__ = dict.__delitem__
__setattr__ = dict.__setitem__ # type: ignore
__delattr__ = dict.__delitem__ # type: ignore
def load_model_vocoder(model_path, device="cpu"):

View File

@ -1,7 +1,7 @@
import torch
from torchaudio.transforms import Resample
from ..nsf_hifigan.nvSTFT import STFT
from ..nsf_hifigan.models import load_model, load_config
from ..nsf_hifigan.nvSTFT import STFT # type: ignore
from ..nsf_hifigan.models import load_model, load_config # type: ignore
class Vocoder:

View File

@ -40,11 +40,13 @@ class ModelSlotManager:
print("[Voice Changer] UPDATE MODEL INFO", newData)
newDataDict = json.loads(newData)
slotInfo = self._load_model_slot(newDataDict["slot"])
if newDataDict["key"] == "speakers":
setattr(slotInfo, newDataDict["key"], json.loads(newDataDict["val"]))
else:
setattr(slotInfo, newDataDict["key"], newDataDict["val"])
self._save_model_slot(newDataDict["slot"], slotInfo)
def store_model_assets(self, params: str):
print("[Voice Changer] UPLOAD ASSETS", params)
paramsDict = json.loads(params)
uploadPath = os.path.join(UPLOAD_DIR, paramsDict["file"])
storeDir = os.path.join(self.model_dir, str(paramsDict["slot"]))