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 4
This commit is contained in:
parent
776a6fd8b2
commit
4b212bd442
87
client/demo/dist/index.js
vendored
87
client/demo/dist/index.js
vendored
File diff suppressed because one or more lines are too long
@ -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 >
|
||||
)
|
||||
|
@ -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)
|
||||
|
108
client/demo/src/components/demo/904-4_Editor.tsx
Normal file
108
client/demo/src/components/demo/904-4_Editor.tsx
Normal 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"><<{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;
|
||||
|
||||
};
|
@ -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])
|
||||
|
@ -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
|
||||
}
|
@ -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
|
||||
}
|
@ -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}
|
||||
</>
|
||||
)
|
||||
}
|
@ -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
|
||||
}
|
@ -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
|
||||
}
|
@ -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
|
||||
}
|
@ -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
|
||||
}
|
@ -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 {
|
||||
|
@ -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
|
||||
|
@ -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]
|
||||
|
@ -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)
|
||||
|
@ -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"):
|
||||
|
@ -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"):
|
||||
|
@ -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:
|
||||
|
@ -40,11 +40,13 @@ class ModelSlotManager:
|
||||
print("[Voice Changer] UPDATE MODEL INFO", newData)
|
||||
newDataDict = json.loads(newData)
|
||||
slotInfo = self._load_model_slot(newDataDict["slot"])
|
||||
setattr(slotInfo, newDataDict["key"], newDataDict["val"])
|
||||
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"]))
|
||||
|
Loading…
Reference in New Issue
Block a user