WIP:VC select
This commit is contained in:
parent
bd6080c52e
commit
4cc02540ea
@ -105,10 +105,6 @@
|
|||||||
"name": "indexRatio",
|
"name": "indexRatio",
|
||||||
"options": {}
|
"options": {}
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"name": "noiseScale",
|
|
||||||
"options": {}
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"name": "silentThreshold",
|
"name": "silentThreshold",
|
||||||
"options": {}
|
"options": {}
|
||||||
|
41
client/demo/dist/index.js
vendored
41
client/demo/dist/index.js
vendored
File diff suppressed because one or more lines are too long
@ -10,9 +10,10 @@ import { far } from "@fortawesome/free-regular-svg-icons";
|
|||||||
import { fab } from "@fortawesome/free-brands-svg-icons";
|
import { fab } from "@fortawesome/free-brands-svg-icons";
|
||||||
import { AppRootProvider, useAppRoot } from "./001_provider/001_AppRootProvider";
|
import { AppRootProvider, useAppRoot } from "./001_provider/001_AppRootProvider";
|
||||||
import ErrorBoundary from "./001_provider/900_ErrorBoundary";
|
import ErrorBoundary from "./001_provider/900_ErrorBoundary";
|
||||||
import { INDEXEDDB_KEY_CLIENT, INDEXEDDB_KEY_MODEL_DATA, INDEXEDDB_KEY_SERVER, INDEXEDDB_KEY_WORKLET, INDEXEDDB_KEY_WORKLETNODE, useIndexedDB } from "@dannadori/voice-changer-client-js";
|
import { ClientType, INDEXEDDB_KEY_CLIENT, INDEXEDDB_KEY_MODEL_DATA, INDEXEDDB_KEY_SERVER, INDEXEDDB_KEY_WORKLET, INDEXEDDB_KEY_WORKLETNODE, useIndexedDB } from "@dannadori/voice-changer-client-js";
|
||||||
import { CLIENT_TYPE, INDEXEDDB_KEY_AUDIO_OUTPUT } from "./const";
|
import { CLIENT_TYPE, INDEXEDDB_KEY_AUDIO_OUTPUT } from "./const";
|
||||||
import { Demo } from "./components/demo/010_Demo";
|
import { Demo } from "./components/demo/010_Demo";
|
||||||
|
import { ClientSelector } from "./001_ClientSelector";
|
||||||
|
|
||||||
library.add(fas, far, fab);
|
library.add(fas, far, fab);
|
||||||
|
|
||||||
@ -21,7 +22,7 @@ const container = document.getElementById("app")!;
|
|||||||
const root = createRoot(container);
|
const root = createRoot(container);
|
||||||
|
|
||||||
const App = () => {
|
const App = () => {
|
||||||
const { appGuiSettingState } = useAppRoot()
|
const { appGuiSettingState, clientType } = useAppRoot()
|
||||||
const front = useMemo(() => {
|
const front = useMemo(() => {
|
||||||
if (appGuiSettingState.appGuiSetting.type == "demo") {
|
if (appGuiSettingState.appGuiSetting.type == "demo") {
|
||||||
return <Demo></Demo>
|
return <Demo></Demo>
|
||||||
@ -38,7 +39,7 @@ const App = () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const AppStateWrapper = () => {
|
const AppStateWrapper = () => {
|
||||||
const { appGuiSettingState } = useAppRoot()
|
const { appGuiSettingState, clientType } = useAppRoot()
|
||||||
// エラーバウンダリー設定
|
// エラーバウンダリー設定
|
||||||
const [error, setError] = useState<{ error: Error, errorInfo: ErrorInfo }>()
|
const [error, setError] = useState<{ error: Error, errorInfo: ErrorInfo }>()
|
||||||
const { removeItem } = useIndexedDB({ clientType: CLIENT_TYPE })
|
const { removeItem } = useIndexedDB({ clientType: CLIENT_TYPE })
|
||||||
@ -96,7 +97,11 @@ const AppStateWrapper = () => {
|
|||||||
setError({ error, errorInfo })
|
setError({ error, errorInfo })
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!appGuiSettingState.guiSettingLoaded) {
|
|
||||||
|
if (!clientType) {
|
||||||
|
return <ClientSelector></ClientSelector>
|
||||||
|
|
||||||
|
} else if (!appGuiSettingState.guiSettingLoaded) {
|
||||||
return <></>
|
return <></>
|
||||||
} else {
|
} else {
|
||||||
return (
|
return (
|
||||||
|
16
client/demo/src/001_ClientSelector.tsx
Normal file
16
client/demo/src/001_ClientSelector.tsx
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
import React from "react"
|
||||||
|
import { useAppRoot } from "./001_provider/001_AppRootProvider"
|
||||||
|
|
||||||
|
export const ClientSelector = () => {
|
||||||
|
const { setClientType } = useAppRoot()
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<div onClick={() => { setClientType("MMVCv13") }}>MMVCv13</div>
|
||||||
|
<div onClick={() => { setClientType("MMVCv15") }}>MMVCv15</div>
|
||||||
|
<div onClick={() => { setClientType("so-vits-svc-40") }}>so-vits-svc-40</div>
|
||||||
|
<div onClick={() => { setClientType("so-vits-svc-40v2") }}>so-vits-svc-40v2</div>
|
||||||
|
<div onClick={() => { setClientType("RVC") }}>RVC</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
|
||||||
|
}
|
@ -51,13 +51,14 @@ export type AppGuiSettingState = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export type AppGuiSettingStateAndMethod = AppGuiSettingState & {
|
export type AppGuiSettingStateAndMethod = AppGuiSettingState & {
|
||||||
getAppSetting: (url: string) => Promise<void>
|
getAppGuiSetting: (url: string) => Promise<void>
|
||||||
|
clearAppGuiSetting: () => void
|
||||||
}
|
}
|
||||||
|
|
||||||
export const userAppGuiSetting = (): AppGuiSettingStateAndMethod => {
|
export const userAppGuiSetting = (): AppGuiSettingStateAndMethod => {
|
||||||
const [guiSettingLoaded, setGuiSettingLoaded] = useState<boolean>(false)
|
const [guiSettingLoaded, setGuiSettingLoaded] = useState<boolean>(false)
|
||||||
const [appGuiSetting, setAppGuiSetting] = useState<AppGuiSetting>(InitialAppGuiDemoSetting)
|
const [appGuiSetting, setAppGuiSetting] = useState<AppGuiSetting>(InitialAppGuiDemoSetting)
|
||||||
const getAppSetting = async (url: string) => {
|
const getAppGuiSetting = async (url: string) => {
|
||||||
const res = await fetch(`${url}`, {
|
const res = await fetch(`${url}`, {
|
||||||
method: "GET",
|
method: "GET",
|
||||||
})
|
})
|
||||||
@ -65,9 +66,15 @@ export const userAppGuiSetting = (): AppGuiSettingStateAndMethod => {
|
|||||||
setAppGuiSetting(appSetting)
|
setAppGuiSetting(appSetting)
|
||||||
setGuiSettingLoaded(true)
|
setGuiSettingLoaded(true)
|
||||||
}
|
}
|
||||||
|
const clearAppGuiSetting = () => {
|
||||||
|
setAppGuiSetting(InitialAppGuiDemoSetting)
|
||||||
|
setGuiSettingLoaded(false)
|
||||||
|
}
|
||||||
return {
|
return {
|
||||||
appGuiSetting,
|
appGuiSetting,
|
||||||
guiSettingLoaded,
|
guiSettingLoaded,
|
||||||
getAppSetting,
|
getAppGuiSetting,
|
||||||
|
clearAppGuiSetting,
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,23 +2,30 @@ import { ClientState, useClient, ClientType } from "@dannadori/voice-changer-cli
|
|||||||
|
|
||||||
export type UseVCClientProps = {
|
export type UseVCClientProps = {
|
||||||
audioContext: AudioContext | null
|
audioContext: AudioContext | null
|
||||||
clientType: ClientType
|
clientType: ClientType | null
|
||||||
}
|
}
|
||||||
|
|
||||||
export type VCClientState = {
|
export type VCClientState = {
|
||||||
clientState: ClientState
|
clientState: ClientState
|
||||||
}
|
}
|
||||||
|
|
||||||
export const useVCClient = (props: UseVCClientProps) => {
|
export const useVCClient = (props: UseVCClientProps): VCClientState => {
|
||||||
const clientState = useClient({
|
const clientState = useClient({
|
||||||
clientType: props.clientType,
|
|
||||||
audioContext: props.audioContext,
|
audioContext: props.audioContext,
|
||||||
|
clientType: props.clientType,
|
||||||
|
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// const setClientType = (clientType: ClientType) => {
|
||||||
|
// console.log("SET CLIENT TYPE", clientType)
|
||||||
|
// clientState.setClientType(clientType)
|
||||||
|
// }
|
||||||
|
|
||||||
const ret: VCClientState = {
|
const ret: VCClientState = {
|
||||||
clientState
|
clientState
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
}
|
}
|
@ -1,4 +1,5 @@
|
|||||||
import React, { useContext, useEffect } from "react";
|
import { ClientType } from "@dannadori/voice-changer-client-js";
|
||||||
|
import React, { useContext, useEffect, useState } from "react";
|
||||||
import { ReactNode } from "react";
|
import { ReactNode } from "react";
|
||||||
import { AppGuiSettingStateAndMethod, userAppGuiSetting } from "../001_globalHooks/001_useAppGuiSetting";
|
import { AppGuiSettingStateAndMethod, userAppGuiSetting } from "../001_globalHooks/001_useAppGuiSetting";
|
||||||
import { AudioConfigState, useAudioConfig } from "../001_globalHooks/001_useAudioConfig";
|
import { AudioConfigState, useAudioConfig } from "../001_globalHooks/001_useAudioConfig";
|
||||||
@ -10,6 +11,8 @@ type Props = {
|
|||||||
type AppRootValue = {
|
type AppRootValue = {
|
||||||
audioContextState: AudioConfigState
|
audioContextState: AudioConfigState
|
||||||
appGuiSettingState: AppGuiSettingStateAndMethod
|
appGuiSettingState: AppGuiSettingStateAndMethod
|
||||||
|
clientType: ClientType | null
|
||||||
|
setClientType: (val: ClientType | null) => void
|
||||||
}
|
}
|
||||||
|
|
||||||
const AppRootContext = React.createContext<AppRootValue | null>(null);
|
const AppRootContext = React.createContext<AppRootValue | null>(null);
|
||||||
@ -24,16 +27,20 @@ export const useAppRoot = (): AppRootValue => {
|
|||||||
export const AppRootProvider = ({ children }: Props) => {
|
export const AppRootProvider = ({ children }: Props) => {
|
||||||
const audioContextState = useAudioConfig()
|
const audioContextState = useAudioConfig()
|
||||||
const appGuiSettingState = userAppGuiSetting()
|
const appGuiSettingState = userAppGuiSetting()
|
||||||
|
const [clientType, setClientType] = useState<ClientType | null>(null)
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const params = new URLSearchParams(window.location.search);
|
if (!clientType) {
|
||||||
const modelType = params.get("modelType") || ""
|
return
|
||||||
appGuiSettingState.getAppSetting(`/assets/gui_settings/${modelType}.json`)
|
}
|
||||||
}, [])
|
appGuiSettingState.getAppGuiSetting(`/assets/gui_settings/${clientType}.json`)
|
||||||
|
}, [clientType])
|
||||||
|
|
||||||
const providerValue: AppRootValue = {
|
const providerValue: AppRootValue = {
|
||||||
audioContextState,
|
audioContextState,
|
||||||
appGuiSettingState
|
appGuiSettingState,
|
||||||
|
clientType,
|
||||||
|
setClientType
|
||||||
};
|
};
|
||||||
return <AppRootContext.Provider value={providerValue}>{children}</AppRootContext.Provider>;
|
return <AppRootContext.Provider value={providerValue}>{children}</AppRootContext.Provider>;
|
||||||
};
|
};
|
||||||
|
@ -24,7 +24,7 @@ export const useAppState = (): AppStateValue => {
|
|||||||
|
|
||||||
export const AppStateProvider = ({ children }: Props) => {
|
export const AppStateProvider = ({ children }: Props) => {
|
||||||
const appRoot = useAppRoot()
|
const appRoot = useAppRoot()
|
||||||
const clientState = useVCClient({ audioContext: appRoot.audioContextState.audioContext, clientType: appRoot.appGuiSettingState.appGuiSetting.id })
|
const clientState = useVCClient({ audioContext: appRoot.audioContextState.audioContext, clientType: appRoot.clientType })
|
||||||
|
|
||||||
|
|
||||||
const initializedRef = useRef<boolean>(false)
|
const initializedRef = useRef<boolean>(false)
|
||||||
|
@ -3,14 +3,15 @@ import { useAppState } from "../../../001_provider/001_AppStateProvider";
|
|||||||
import { useIndexedDB } from "@dannadori/voice-changer-client-js";
|
import { useIndexedDB } from "@dannadori/voice-changer-client-js";
|
||||||
import { INDEXEDDB_KEY_AUDIO_OUTPUT } from "../../../const";
|
import { INDEXEDDB_KEY_AUDIO_OUTPUT } from "../../../const";
|
||||||
import { useAppRoot } from "../../../001_provider/001_AppRootProvider";
|
import { useAppRoot } from "../../../001_provider/001_AppRootProvider";
|
||||||
|
import { useGuiState } from "../001_GuiStateProvider"
|
||||||
export type ClearSettingRowProps = {
|
export type ClearSettingRowProps = {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
export const ClearSettingRow = (_props: ClearSettingRowProps) => {
|
export const ClearSettingRow = (_props: ClearSettingRowProps) => {
|
||||||
const appState = useAppState()
|
const appState = useAppState()
|
||||||
const { appGuiSettingState } = useAppRoot()
|
const { appGuiSettingState, setClientType } = useAppRoot()
|
||||||
|
const guiState = useGuiState()
|
||||||
const clientType = appGuiSettingState.appGuiSetting.id
|
const clientType = appGuiSettingState.appGuiSetting.id
|
||||||
const { removeItem } = useIndexedDB({ clientType: clientType })
|
const { removeItem } = useIndexedDB({ clientType: clientType })
|
||||||
|
|
||||||
@ -21,12 +22,21 @@ export const ClearSettingRow = (_props: ClearSettingRowProps) => {
|
|||||||
await removeItem(INDEXEDDB_KEY_AUDIO_OUTPUT)
|
await removeItem(INDEXEDDB_KEY_AUDIO_OUTPUT)
|
||||||
location.reload()
|
location.reload()
|
||||||
}
|
}
|
||||||
|
const onReselectVCClicked = async () => {
|
||||||
|
guiState.setIsConverting(false)
|
||||||
|
await appState.clientSetting.stop()
|
||||||
|
setClientType(null)
|
||||||
|
appGuiSettingState.clearAppGuiSetting()
|
||||||
|
|
||||||
|
}
|
||||||
return (
|
return (
|
||||||
<div className="body-row split-3-3-4 left-padding-1">
|
<div className="body-row split-3-3-4 left-padding-1">
|
||||||
<div className="body-button-container">
|
<div className="body-button-container">
|
||||||
<div className="body-button" onClick={onClearSettingClicked}>clear setting</div>
|
<div className="body-button" onClick={onClearSettingClicked}>clear setting</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="body-item-text"></div>
|
<div className="body-button-container">
|
||||||
|
<div className="body-button" onClick={onReselectVCClicked}>re-select vc</div>
|
||||||
|
</div>
|
||||||
<div className="body-item-text"></div>
|
<div className="body-item-text"></div>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
|
@ -11,7 +11,7 @@ export const TuneRow = (_props: TuneRowProps) => {
|
|||||||
<div className="body-row split-3-2-2-3 left-padding-1 guided">
|
<div className="body-row split-3-2-2-3 left-padding-1 guided">
|
||||||
<div className="body-item-title left-padding-1 ">Tuning</div>
|
<div className="body-item-title left-padding-1 ">Tuning</div>
|
||||||
<div>
|
<div>
|
||||||
<input type="range" className="body-item-input-slider" min="-50" max="50" step="1" value={appState.serverSetting.serverSetting.tran} onChange={(e) => {
|
<input type="range" className="body-item-input-slider" min="-50" max="50" step="1" value={appState.serverSetting.serverSetting.tran || 0} onChange={(e) => {
|
||||||
appState.serverSetting.updateServerSettings({ ...appState.serverSetting.serverSetting, tran: Number(e.target.value) })
|
appState.serverSetting.updateServerSettings({ ...appState.serverSetting.serverSetting, tran: Number(e.target.value) })
|
||||||
}}></input>
|
}}></input>
|
||||||
<span className="body-item-input-slider-val">{appState.serverSetting.serverSetting.tran}</span>
|
<span className="body-item-input-slider-val">{appState.serverSetting.serverSetting.tran}</span>
|
||||||
|
@ -12,7 +12,7 @@ export const ClusterInferRatioRow = (_props: ClusterInferRatioRowProps) => {
|
|||||||
<div className="body-row split-3-3-4 left-padding-1 guided">
|
<div className="body-row split-3-3-4 left-padding-1 guided">
|
||||||
<div className="body-item-title left-padding-1 ">Cluster infer ratio</div>
|
<div className="body-item-title left-padding-1 ">Cluster infer ratio</div>
|
||||||
<div>
|
<div>
|
||||||
<input type="range" className="body-item-input-slider" min="0" max="1" step="0.1" value={appState.serverSetting.serverSetting.clusterInferRatio} onChange={(e) => {
|
<input type="range" className="body-item-input-slider" min="0" max="1" step="0.1" value={appState.serverSetting.serverSetting.clusterInferRatio || 0} onChange={(e) => {
|
||||||
appState.serverSetting.updateServerSettings({ ...appState.serverSetting.serverSetting, clusterInferRatio: Number(e.target.value) })
|
appState.serverSetting.updateServerSettings({ ...appState.serverSetting.serverSetting, clusterInferRatio: Number(e.target.value) })
|
||||||
}}></input>
|
}}></input>
|
||||||
<span className="body-item-input-slider-val">{appState.serverSetting.serverSetting.clusterInferRatio}</span>
|
<span className="body-item-input-slider-val">{appState.serverSetting.serverSetting.clusterInferRatio}</span>
|
||||||
|
@ -12,7 +12,7 @@ export const NoiseScaleRow = (_props: NoiseScaleRowProps) => {
|
|||||||
<div className="body-row split-3-3-4 left-padding-1 guided">
|
<div className="body-row split-3-3-4 left-padding-1 guided">
|
||||||
<div className="body-item-title left-padding-1 ">Noise Scale</div>
|
<div className="body-item-title left-padding-1 ">Noise Scale</div>
|
||||||
<div>
|
<div>
|
||||||
<input type="range" className="body-item-input-slider" min="0" max="1" step="0.1" value={appState.serverSetting.serverSetting.noiceScale} onChange={(e) => {
|
<input type="range" className="body-item-input-slider" min="0" max="1" step="0.1" value={appState.serverSetting.serverSetting.noiceScale || 0} onChange={(e) => {
|
||||||
appState.serverSetting.updateServerSettings({ ...appState.serverSetting.serverSetting, noiceScale: Number(e.target.value) })
|
appState.serverSetting.updateServerSettings({ ...appState.serverSetting.serverSetting, noiceScale: Number(e.target.value) })
|
||||||
}}></input>
|
}}></input>
|
||||||
<span className="body-item-input-slider-val">{appState.serverSetting.serverSetting.noiceScale}</span>
|
<span className="body-item-input-slider-val">{appState.serverSetting.serverSetting.noiceScale}</span>
|
||||||
|
@ -12,7 +12,7 @@ export const SilentThresholdRow = (_props: SilentThresholdRowProps) => {
|
|||||||
<div className="body-row split-3-3-4 left-padding-1 guided">
|
<div className="body-row split-3-3-4 left-padding-1 guided">
|
||||||
<div className="body-item-title left-padding-1 ">Silent Threshold</div>
|
<div className="body-item-title left-padding-1 ">Silent Threshold</div>
|
||||||
<div>
|
<div>
|
||||||
<input type="range" className="body-item-input-slider" min="0.00000" max="0.001" step="0.00001" value={appState.serverSetting.serverSetting.silentThreshold} onChange={(e) => {
|
<input type="range" className="body-item-input-slider" min="0.00000" max="0.001" step="0.00001" value={appState.serverSetting.serverSetting.silentThreshold || 0} onChange={(e) => {
|
||||||
appState.serverSetting.updateServerSettings({ ...appState.serverSetting.serverSetting, silentThreshold: Number(e.target.value) })
|
appState.serverSetting.updateServerSettings({ ...appState.serverSetting.serverSetting, silentThreshold: Number(e.target.value) })
|
||||||
}}></input>
|
}}></input>
|
||||||
<span className="body-item-input-slider-val">{appState.serverSetting.serverSetting.silentThreshold}</span>
|
<span className="body-item-input-slider-val">{appState.serverSetting.serverSetting.silentThreshold}</span>
|
||||||
|
@ -12,7 +12,7 @@ export const IndexRatioRow = (_props: IndexRatioRowProps) => {
|
|||||||
<div className="body-row split-3-3-4 left-padding-1 guided">
|
<div className="body-row split-3-3-4 left-padding-1 guided">
|
||||||
<div className="body-item-title left-padding-1 ">index ratio</div>
|
<div className="body-item-title left-padding-1 ">index ratio</div>
|
||||||
<div>
|
<div>
|
||||||
<input type="range" className="body-item-input-slider" min="0" max="1" step="0.1" value={appState.serverSetting.serverSetting.indexRatio} onChange={(e) => {
|
<input type="range" className="body-item-input-slider" min="0" max="1" step="0.1" value={appState.serverSetting.serverSetting.indexRatio || 0} onChange={(e) => {
|
||||||
appState.serverSetting.updateServerSettings({ ...appState.serverSetting.serverSetting, indexRatio: Number(e.target.value) })
|
appState.serverSetting.updateServerSettings({ ...appState.serverSetting.serverSetting, indexRatio: Number(e.target.value) })
|
||||||
}}></input>
|
}}></input>
|
||||||
<span className="body-item-input-slider-val">{appState.serverSetting.serverSetting.indexRatio}</span>
|
<span className="body-item-input-slider-val">{appState.serverSetting.serverSetting.indexRatio}</span>
|
||||||
|
@ -10,7 +10,7 @@ export const GPURow = (_props: GPURowProps) => {
|
|||||||
<div className="body-row split-3-7 left-padding-1 guided">
|
<div className="body-row split-3-7 left-padding-1 guided">
|
||||||
<div className="body-item-title left-padding-1">GPU</div>
|
<div className="body-item-title left-padding-1">GPU</div>
|
||||||
<div className="body-input-container">
|
<div className="body-input-container">
|
||||||
<input type="number" min={-2} max={5} step={1} value={appState.serverSetting.serverSetting.gpu} onChange={(e) => {
|
<input type="number" min={-2} max={5} step={1} value={appState.serverSetting.serverSetting.gpu || 0} onChange={(e) => {
|
||||||
appState.serverSetting.updateServerSettings({ ...appState.serverSetting.serverSetting, gpu: Number(e.target.value) })
|
appState.serverSetting.updateServerSettings({ ...appState.serverSetting.serverSetting, gpu: Number(e.target.value) })
|
||||||
}} />
|
}} />
|
||||||
</div>
|
</div>
|
||||||
|
@ -21,7 +21,7 @@ export const TrancateNumTresholdRow = (_props: TrancateNumTresholdRowProps) => {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}, [appState.workletNodeSetting.workletNodeSetting, appState.workletNodeSetting.updateWorkletNodeSetting])
|
}, [appState.workletSetting.setting, appState.workletSetting.setSetting])
|
||||||
|
|
||||||
return trancateNumTresholdRow
|
return trancateNumTresholdRow
|
||||||
}
|
}
|
@ -1,4 +1,4 @@
|
|||||||
import { ServerInfo, ServerSettingKey } from "./const";
|
import { ClientType, ServerInfo, ServerSettingKey } from "./const";
|
||||||
|
|
||||||
|
|
||||||
type FileChunk = {
|
type FileChunk = {
|
||||||
@ -132,4 +132,32 @@ export class ServerConfigurator {
|
|||||||
return await info
|
return await info
|
||||||
}
|
}
|
||||||
|
|
||||||
|
switchModelType = async (clinetType: ClientType) => {
|
||||||
|
const url = this.serverUrl + "/model_type"
|
||||||
|
const info = new Promise<ServerInfo>(async (resolve) => {
|
||||||
|
const formData = new FormData();
|
||||||
|
formData.append("modelType", clinetType);
|
||||||
|
|
||||||
|
const request = new Request(url, {
|
||||||
|
method: 'POST',
|
||||||
|
body: formData,
|
||||||
|
});
|
||||||
|
const res = await (await fetch(request)).json() as ServerInfo
|
||||||
|
resolve(res)
|
||||||
|
})
|
||||||
|
return await info
|
||||||
|
}
|
||||||
|
|
||||||
|
getModelType = async () => {
|
||||||
|
const url = this.serverUrl + "/model_type"
|
||||||
|
const info = new Promise<ServerInfo>(async (resolve) => {
|
||||||
|
const request = new Request(url, {
|
||||||
|
method: 'GET',
|
||||||
|
});
|
||||||
|
const res = await (await fetch(request)).json() as ServerInfo
|
||||||
|
resolve(res)
|
||||||
|
})
|
||||||
|
return await info
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,7 @@ import { VoiceChangerWorkletNode, VoiceChangerWorkletListener } from "./VoiceCha
|
|||||||
import workerjs from "raw-loader!../worklet/dist/index.js";
|
import workerjs from "raw-loader!../worklet/dist/index.js";
|
||||||
import { VoiceFocusDeviceTransformer, VoiceFocusTransformDevice } from "amazon-chime-sdk-js";
|
import { VoiceFocusDeviceTransformer, VoiceFocusTransformDevice } from "amazon-chime-sdk-js";
|
||||||
import { createDummyMediaStream, validateUrl } from "./util";
|
import { createDummyMediaStream, validateUrl } from "./util";
|
||||||
import { DefaultVoiceChangerClientSetting, ServerSettingKey, VoiceChangerClientSetting, WorkletNodeSetting, WorkletSetting } from "./const";
|
import { ClientType, DefaultVoiceChangerClientSetting, ServerSettingKey, VoiceChangerClientSetting, WorkletNodeSetting, WorkletSetting } from "./const";
|
||||||
import { ServerConfigurator } from "./ServerConfigurator";
|
import { ServerConfigurator } from "./ServerConfigurator";
|
||||||
|
|
||||||
// オーディオデータの流れ
|
// オーディオデータの流れ
|
||||||
@ -44,15 +44,28 @@ export class VoiceChangerClient {
|
|||||||
this.vfEnable = vfEnable
|
this.vfEnable = vfEnable
|
||||||
this.promiseForInitialize = new Promise<void>(async (resolve) => {
|
this.promiseForInitialize = new Promise<void>(async (resolve) => {
|
||||||
const scriptUrl = URL.createObjectURL(new Blob([workerjs], { type: "text/javascript" }));
|
const scriptUrl = URL.createObjectURL(new Blob([workerjs], { type: "text/javascript" }));
|
||||||
await this.ctx.audioWorklet.addModule(scriptUrl)
|
|
||||||
|
|
||||||
this.vcInNode = new VoiceChangerWorkletNode(this.ctx, voiceChangerWorkletListener); // vc node
|
// await this.ctx.audioWorklet.addModule(scriptUrl)
|
||||||
|
// this.vcInNode = new VoiceChangerWorkletNode(this.ctx, voiceChangerWorkletListener); // vc node
|
||||||
|
|
||||||
|
try {
|
||||||
|
this.vcInNode = new VoiceChangerWorkletNode(this.ctx, voiceChangerWorkletListener); // vc node
|
||||||
|
} catch (err) {
|
||||||
|
await this.ctx.audioWorklet.addModule(scriptUrl)
|
||||||
|
this.vcInNode = new VoiceChangerWorkletNode(this.ctx, voiceChangerWorkletListener); // vc node
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// const ctx44k = new AudioContext({ sampleRate: 44100 }) // これでもプチプチが残る
|
// const ctx44k = new AudioContext({ sampleRate: 44100 }) // これでもプチプチが残る
|
||||||
const ctx44k = new AudioContext({ sampleRate: 48000 }) // 結局これが一番まし。
|
const ctx44k = new AudioContext({ sampleRate: 48000 }) // 結局これが一番まし。
|
||||||
console.log("audio out:", ctx44k)
|
console.log("audio out:", ctx44k)
|
||||||
await ctx44k.audioWorklet.addModule(scriptUrl)
|
try {
|
||||||
this.vcOutNode = new VoiceChangerWorkletNode(ctx44k, voiceChangerWorkletListener); // vc node
|
this.vcOutNode = new VoiceChangerWorkletNode(ctx44k, voiceChangerWorkletListener); // vc node
|
||||||
|
} catch (err) {
|
||||||
|
await ctx44k.audioWorklet.addModule(scriptUrl)
|
||||||
|
this.vcOutNode = new VoiceChangerWorkletNode(ctx44k, voiceChangerWorkletListener); // vc node
|
||||||
|
}
|
||||||
this.currentMediaStreamAudioDestinationNode = ctx44k.createMediaStreamDestination() // output node
|
this.currentMediaStreamAudioDestinationNode = ctx44k.createMediaStreamDestination() // output node
|
||||||
this.outputGainNode = ctx44k.createGain()
|
this.outputGainNode = ctx44k.createGain()
|
||||||
this.outputGainNode.gain.value = this.setting.outputGain
|
this.outputGainNode.gain.value = this.setting.outputGain
|
||||||
@ -248,6 +261,14 @@ export class VoiceChangerClient {
|
|||||||
// コンポーネント設定、操作
|
// コンポーネント設定、操作
|
||||||
/////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////
|
||||||
//## Server ##//
|
//## Server ##//
|
||||||
|
switchModelType = (clientType: ClientType) => {
|
||||||
|
return this.configurator.switchModelType(clientType)
|
||||||
|
}
|
||||||
|
getModelType = () => {
|
||||||
|
return this.configurator.getModelType()
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
updateServerSettings = (key: ServerSettingKey, val: string) => {
|
updateServerSettings = (key: ServerSettingKey, val: string) => {
|
||||||
return this.configurator.updateSettings(key, val)
|
return this.configurator.updateSettings(key, val)
|
||||||
}
|
}
|
||||||
|
@ -9,7 +9,7 @@ import { useWorkletSetting, WorkletSettingState } from "./useWorkletSetting"
|
|||||||
|
|
||||||
export type UseClientProps = {
|
export type UseClientProps = {
|
||||||
audioContext: AudioContext | null
|
audioContext: AudioContext | null
|
||||||
clientType: ClientType
|
clientType: ClientType | null
|
||||||
}
|
}
|
||||||
|
|
||||||
export type ClientState = {
|
export type ClientState = {
|
||||||
@ -26,6 +26,8 @@ export type ClientState = {
|
|||||||
volume: number;
|
volume: number;
|
||||||
performance: PerformanceData
|
performance: PerformanceData
|
||||||
|
|
||||||
|
// setClientType: (val: ClientType) => void
|
||||||
|
|
||||||
// 情報取得
|
// 情報取得
|
||||||
getInfo: () => Promise<void>
|
getInfo: () => Promise<void>
|
||||||
// 設定クリア
|
// 設定クリア
|
||||||
@ -50,6 +52,7 @@ const InitialPerformanceData: PerformanceData = {
|
|||||||
export const useClient = (props: UseClientProps): ClientState => {
|
export const useClient = (props: UseClientProps): ClientState => {
|
||||||
|
|
||||||
const [initialized, setInitialized] = useState<boolean>(false)
|
const [initialized, setInitialized] = useState<boolean>(false)
|
||||||
|
// const [clientType, setClientType] = useState<ClientType | null>(null)
|
||||||
// (1-1) クライアント
|
// (1-1) クライアント
|
||||||
const voiceChangerClientRef = useRef<VoiceChangerClient | null>(null)
|
const voiceChangerClientRef = useRef<VoiceChangerClient | null>(null)
|
||||||
const [voiceChangerClient, setVoiceChangerClient] = useState<VoiceChangerClient | null>(voiceChangerClientRef.current)
|
const [voiceChangerClient, setVoiceChangerClient] = useState<VoiceChangerClient | null>(voiceChangerClientRef.current)
|
||||||
@ -165,6 +168,8 @@ export const useClient = (props: UseClientProps): ClientState => {
|
|||||||
volume,
|
volume,
|
||||||
performance,
|
performance,
|
||||||
|
|
||||||
|
// setClientType,
|
||||||
|
|
||||||
// 情報取得
|
// 情報取得
|
||||||
getInfo,
|
getInfo,
|
||||||
|
|
||||||
|
@ -5,7 +5,7 @@ import { VoiceChangerClient } from "../VoiceChangerClient"
|
|||||||
import { useIndexedDB } from "./useIndexedDB"
|
import { useIndexedDB } from "./useIndexedDB"
|
||||||
|
|
||||||
export type UseClientSettingProps = {
|
export type UseClientSettingProps = {
|
||||||
clientType: ClientType
|
clientType: ClientType | null
|
||||||
voiceChangerClient: VoiceChangerClient | null
|
voiceChangerClient: VoiceChangerClient | null
|
||||||
audioContext: AudioContext | null
|
audioContext: AudioContext | null
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,7 @@ import { useMemo } from "react";
|
|||||||
import { ClientType, INDEXEDDB_DB_APP_NAME, INDEXEDDB_DB_NAME } from "../const";
|
import { ClientType, INDEXEDDB_DB_APP_NAME, INDEXEDDB_DB_NAME } from "../const";
|
||||||
|
|
||||||
export type UseIndexedDBProps = {
|
export type UseIndexedDBProps = {
|
||||||
clientType: ClientType
|
clientType: ClientType | null
|
||||||
}
|
}
|
||||||
export type IndexedDBState = {
|
export type IndexedDBState = {
|
||||||
dummy: string
|
dummy: string
|
||||||
@ -16,31 +16,36 @@ export type IndexedDBStateAndMethod = IndexedDBState & {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export const useIndexedDB = (props: UseIndexedDBProps): IndexedDBStateAndMethod => {
|
export const useIndexedDB = (props: UseIndexedDBProps): IndexedDBStateAndMethod => {
|
||||||
|
const clientType = props.clientType || "default"
|
||||||
localForage.config({
|
localForage.config({
|
||||||
driver: localForage.INDEXEDDB,
|
driver: localForage.INDEXEDDB,
|
||||||
name: INDEXEDDB_DB_APP_NAME,
|
name: INDEXEDDB_DB_APP_NAME,
|
||||||
version: 1.0,
|
version: 1.0,
|
||||||
storeName: `${INDEXEDDB_DB_NAME}_${props.clientType}`,
|
storeName: `${INDEXEDDB_DB_NAME}`,
|
||||||
description: 'appStorage'
|
description: 'appStorage'
|
||||||
|
|
||||||
})
|
})
|
||||||
|
|
||||||
const setItem = useMemo(() => {
|
const setItem = useMemo(() => {
|
||||||
return async (key: string, value: unknown) => {
|
return async (key: string, value: unknown) => {
|
||||||
await localForage.setItem(key, value)
|
const clientKey = `${clientType}_${key}`
|
||||||
|
await localForage.setItem(clientKey, value)
|
||||||
}
|
}
|
||||||
}, [])
|
}, [props.clientType])
|
||||||
|
|
||||||
const getItem = useMemo(() => {
|
const getItem = useMemo(() => {
|
||||||
return async (key: string) => {
|
return async (key: string) => {
|
||||||
return await localForage.getItem(key)
|
const clientKey = `${clientType}_${key}`
|
||||||
|
return await localForage.getItem(clientKey)
|
||||||
}
|
}
|
||||||
}, [])
|
}, [props.clientType])
|
||||||
|
|
||||||
const removeItem = useMemo(() => {
|
const removeItem = useMemo(() => {
|
||||||
return async (key: string) => {
|
return async (key: string) => {
|
||||||
return await localForage.removeItem(key)
|
const clientKey = `${clientType}_${key}`
|
||||||
|
return await localForage.removeItem(clientKey)
|
||||||
}
|
}
|
||||||
}, [])
|
}, [props.clientType])
|
||||||
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
@ -38,7 +38,7 @@ const InitialFileUploadSetting: FileUploadSetting = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export type UseServerSettingProps = {
|
export type UseServerSettingProps = {
|
||||||
clientType: ClientType
|
clientType: ClientType | null
|
||||||
voiceChangerClient: VoiceChangerClient | null
|
voiceChangerClient: VoiceChangerClient | null
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -58,7 +58,7 @@ export type ServerSettingState = {
|
|||||||
|
|
||||||
export const useServerSetting = (props: UseServerSettingProps): ServerSettingState => {
|
export const useServerSetting = (props: UseServerSettingProps): ServerSettingState => {
|
||||||
// const settingRef = useRef<VoiceChangerServerSetting>(DefaultVoiceChangerServerSetting)
|
// const settingRef = useRef<VoiceChangerServerSetting>(DefaultVoiceChangerServerSetting)
|
||||||
const defaultServerSetting = useMemo(() => {
|
const getDefaultServerSetting = () => {
|
||||||
if (props.clientType == "MMVCv13") {
|
if (props.clientType == "MMVCv13") {
|
||||||
return DefaultServerSetting_MMVCv13
|
return DefaultServerSetting_MMVCv13
|
||||||
} else if (props.clientType == "MMVCv15") {
|
} else if (props.clientType == "MMVCv15") {
|
||||||
@ -75,43 +75,57 @@ export const useServerSetting = (props: UseServerSettingProps): ServerSettingSta
|
|||||||
} else {
|
} else {
|
||||||
return DefaultServerSetting_MMVCv15
|
return DefaultServerSetting_MMVCv15
|
||||||
}
|
}
|
||||||
}, [])
|
}
|
||||||
const [serverSetting, setServerSetting] = useState<ServerInfo>(defaultServerSetting)
|
|
||||||
|
const [serverSetting, setServerSetting] = useState<ServerInfo>(getDefaultServerSetting())
|
||||||
const [fileUploadSetting, setFileUploadSetting] = useState<FileUploadSetting>(InitialFileUploadSetting)
|
const [fileUploadSetting, setFileUploadSetting] = useState<FileUploadSetting>(InitialFileUploadSetting)
|
||||||
const { setItem, getItem, removeItem } = useIndexedDB({ clientType: props.clientType })
|
const { setItem, getItem, removeItem } = useIndexedDB({ clientType: props.clientType })
|
||||||
|
|
||||||
|
|
||||||
// DBから設定取得(キャッシュによる初期化)
|
// clientTypeが新しく設定されたときに、serverのmodelType動作を変更+設定反映
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const loadCache = async () => {
|
if (!props.voiceChangerClient) return
|
||||||
const setting = await getItem(INDEXEDDB_KEY_SERVER)
|
if (!props.clientType) return
|
||||||
if (!setting) {
|
|
||||||
|
const setInitialSetting = async () => {
|
||||||
|
// Set Model Type
|
||||||
|
await props.voiceChangerClient!.switchModelType(props.clientType!)
|
||||||
|
|
||||||
|
// Load Default (and Cache) and set
|
||||||
|
const defaultServerSetting = getDefaultServerSetting()
|
||||||
|
const cachedServerSetting = await getItem(INDEXEDDB_KEY_SERVER)
|
||||||
|
let initialSetting: ServerInfo
|
||||||
|
if (cachedServerSetting) {
|
||||||
|
initialSetting = { ...defaultServerSetting, ...cachedServerSetting as ServerInfo }
|
||||||
|
console.log("Initial Setting1:", initialSetting)
|
||||||
} else {
|
} else {
|
||||||
setServerSetting(setting as ServerInfo)
|
initialSetting = { ...defaultServerSetting }
|
||||||
|
console.log("Initial Setting2:", initialSetting)
|
||||||
|
}
|
||||||
|
setServerSetting(initialSetting)
|
||||||
|
|
||||||
|
// upload setting
|
||||||
|
for (let i = 0; i < Object.values(ServerSettingKey).length; i++) {
|
||||||
|
const k = Object.values(ServerSettingKey)[i] as keyof VoiceChangerServerSetting
|
||||||
|
const v = initialSetting[k]
|
||||||
|
if (v) {
|
||||||
|
props.voiceChangerClient!.updateServerSettings(k, "" + v)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Load file upload cache
|
||||||
const fileuploadSetting = await getItem(INDEXEDDB_KEY_MODEL_DATA)
|
const fileuploadSetting = await getItem(INDEXEDDB_KEY_MODEL_DATA)
|
||||||
if (!fileuploadSetting) {
|
if (!fileuploadSetting) {
|
||||||
} else {
|
} else {
|
||||||
setFileUploadSetting(fileuploadSetting as FileUploadSetting)
|
setFileUploadSetting(fileuploadSetting as FileUploadSetting)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
reloadServerInfo()
|
||||||
}
|
}
|
||||||
|
|
||||||
loadCache()
|
setInitialSetting()
|
||||||
}, [])
|
|
||||||
|
|
||||||
// サーバへキャッシュの内容を反映 (クライアント初期化した時の一回)
|
}, [props.voiceChangerClient, props.clientType])
|
||||||
useEffect(() => {
|
|
||||||
if (!props.voiceChangerClient) return
|
|
||||||
for (let i = 0; i < Object.values(ServerSettingKey).length; i++) {
|
|
||||||
const k = Object.values(ServerSettingKey)[i] as keyof VoiceChangerServerSetting
|
|
||||||
const v = serverSetting[k]
|
|
||||||
if (v) {
|
|
||||||
props.voiceChangerClient.updateServerSettings(k, "" + v)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
reloadServerInfo()
|
|
||||||
}, [props.voiceChangerClient])
|
|
||||||
|
|
||||||
//////////////
|
//////////////
|
||||||
// 設定
|
// 設定
|
||||||
@ -125,7 +139,7 @@ export const useServerSetting = (props: UseServerSettingProps): ServerSettingSta
|
|||||||
const new_v = setting[k]
|
const new_v = setting[k]
|
||||||
if (cur_v != new_v) {
|
if (cur_v != new_v) {
|
||||||
const res = await props.voiceChangerClient.updateServerSettings(k, "" + new_v)
|
const res = await props.voiceChangerClient.updateServerSettings(k, "" + new_v)
|
||||||
if (res.onnxExecutionProviders.length > 0) {
|
if (res.onnxExecutionProviders && res.onnxExecutionProviders.length > 0) {
|
||||||
res.onnxExecutionProvider = res.onnxExecutionProviders[0]
|
res.onnxExecutionProvider = res.onnxExecutionProviders[0]
|
||||||
} else {
|
} else {
|
||||||
res.onnxExecutionProvider = "CPUExecutionProvider"
|
res.onnxExecutionProvider = "CPUExecutionProvider"
|
||||||
|
@ -5,7 +5,7 @@ import { VoiceChangerClient } from "../VoiceChangerClient"
|
|||||||
import { useIndexedDB } from "./useIndexedDB"
|
import { useIndexedDB } from "./useIndexedDB"
|
||||||
|
|
||||||
export type UseWorkletNodeSettingProps = {
|
export type UseWorkletNodeSettingProps = {
|
||||||
clientType: ClientType
|
clientType: ClientType | null
|
||||||
voiceChangerClient: VoiceChangerClient | null
|
voiceChangerClient: VoiceChangerClient | null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4,7 +4,7 @@ import { VoiceChangerClient } from "../VoiceChangerClient";
|
|||||||
import { useIndexedDB } from "./useIndexedDB";
|
import { useIndexedDB } from "./useIndexedDB";
|
||||||
|
|
||||||
export type UseWorkletSettingProps = {
|
export type UseWorkletSettingProps = {
|
||||||
clientType: ClientType
|
clientType: ClientType | null
|
||||||
voiceChangerClient: VoiceChangerClient | null
|
voiceChangerClient: VoiceChangerClient | null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8,8 +8,8 @@ class UvicornSuppressFilter(logging.Filter):
|
|||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
# logger = logging.getLogger("uvicorn.error")
|
logger = logging.getLogger("uvicorn.error")
|
||||||
# logger.addFilter(UvicornSuppressFilter())
|
logger.addFilter(UvicornSuppressFilter())
|
||||||
|
|
||||||
logger = logging.getLogger("fairseq.tasks.hubert_pretraining")
|
logger = logging.getLogger("fairseq.tasks.hubert_pretraining")
|
||||||
logger.addFilter(UvicornSuppressFilter())
|
logger.addFilter(UvicornSuppressFilter())
|
||||||
|
@ -9,7 +9,7 @@ from fastapi import HTTPException, FastAPI, UploadFile, File, Form
|
|||||||
from restapi.mods.FileUploader import upload_file, concat_file_chunks
|
from restapi.mods.FileUploader import upload_file, concat_file_chunks
|
||||||
from voice_changer.VoiceChangerManager import VoiceChangerManager
|
from voice_changer.VoiceChangerManager import VoiceChangerManager
|
||||||
|
|
||||||
from const import MODEL_DIR, UPLOAD_DIR
|
from const import MODEL_DIR, UPLOAD_DIR, ModelType
|
||||||
os.makedirs(UPLOAD_DIR, exist_ok=True)
|
os.makedirs(UPLOAD_DIR, exist_ok=True)
|
||||||
os.makedirs(MODEL_DIR, exist_ok=True)
|
os.makedirs(MODEL_DIR, exist_ok=True)
|
||||||
|
|
||||||
@ -25,8 +25,8 @@ class MMVC_Rest_Fileuploader:
|
|||||||
self.router.add_api_route("/load_model", self.post_load_model, methods=["POST"])
|
self.router.add_api_route("/load_model", self.post_load_model, methods=["POST"])
|
||||||
self.router.add_api_route("/load_model_for_train", self.post_load_model_for_train, methods=["POST"])
|
self.router.add_api_route("/load_model_for_train", self.post_load_model_for_train, methods=["POST"])
|
||||||
self.router.add_api_route("/extract_voices", self.post_extract_voices, methods=["POST"])
|
self.router.add_api_route("/extract_voices", self.post_extract_voices, methods=["POST"])
|
||||||
|
self.router.add_api_route("/model_type", self.post_model_type, methods=["POST"])
|
||||||
self.onnx_provider = ""
|
self.router.add_api_route("/model_type", self.get_model_type, methods=["GET"])
|
||||||
|
|
||||||
def post_upload_file(self, file: UploadFile = File(...), filename: str = Form(...)):
|
def post_upload_file(self, file: UploadFile = File(...), filename: str = Form(...)):
|
||||||
res = upload_file(UPLOAD_DIR, file, filename)
|
res = upload_file(UPLOAD_DIR, file, filename)
|
||||||
@ -95,3 +95,18 @@ class MMVC_Rest_Fileuploader:
|
|||||||
UPLOAD_DIR, zipFilename, zipFileChunkNum, UPLOAD_DIR)
|
UPLOAD_DIR, zipFilename, zipFileChunkNum, UPLOAD_DIR)
|
||||||
shutil.unpack_archive(zipFilePath, "MMVC_Trainer/dataset/textful/")
|
shutil.unpack_archive(zipFilePath, "MMVC_Trainer/dataset/textful/")
|
||||||
return {"Zip file unpacked": f"{zipFilePath}"}
|
return {"Zip file unpacked": f"{zipFilePath}"}
|
||||||
|
|
||||||
|
def post_model_type(
|
||||||
|
self,
|
||||||
|
modelType: ModelType = Form(...),
|
||||||
|
):
|
||||||
|
info = self.voiceChangerManager.switchModelType(modelType)
|
||||||
|
json_compatible_item_data = jsonable_encoder(info)
|
||||||
|
return JSONResponse(content=json_compatible_item_data)
|
||||||
|
|
||||||
|
def get_model_type(
|
||||||
|
self,
|
||||||
|
):
|
||||||
|
info = self.voiceChangerManager.getModelType(modelType)
|
||||||
|
json_compatible_item_data = jsonable_encoder(info)
|
||||||
|
return JSONResponse(content=json_compatible_item_data)
|
||||||
|
@ -273,6 +273,10 @@ class DDSP_SVC:
|
|||||||
del self.net_g
|
del self.net_g
|
||||||
del self.onnx_session
|
del self.onnx_session
|
||||||
|
|
||||||
|
def __del__(self):
|
||||||
|
del self.net_g
|
||||||
|
del self.onnx_session
|
||||||
|
|
||||||
|
|
||||||
def cross_fade(a: np.ndarray, b: np.ndarray, idx: int):
|
def cross_fade(a: np.ndarray, b: np.ndarray, idx: int):
|
||||||
result = np.zeros(idx + b.shape[0])
|
result = np.zeros(idx + b.shape[0])
|
||||||
|
@ -10,6 +10,7 @@ if sys.platform.startswith('darwin'):
|
|||||||
else:
|
else:
|
||||||
sys.path.append("MMVC_Client_v13/python")
|
sys.path.append("MMVC_Client_v13/python")
|
||||||
|
|
||||||
|
|
||||||
from dataclasses import dataclass, asdict
|
from dataclasses import dataclass, asdict
|
||||||
import numpy as np
|
import numpy as np
|
||||||
import torch
|
import torch
|
||||||
@ -199,6 +200,18 @@ class MMVCv13:
|
|||||||
audio = self._pyTorch_inference(data)
|
audio = self._pyTorch_inference(data)
|
||||||
return audio
|
return audio
|
||||||
|
|
||||||
def destroy(self):
|
def __del__(self):
|
||||||
del self.net_g
|
del self.net_g
|
||||||
del self.onnx_session
|
del self.onnx_session
|
||||||
|
remove_path = os.path.join("MMVC_Client_v13", "python")
|
||||||
|
sys.path = [x for x in sys.path if x.endswith(remove_path) == False]
|
||||||
|
|
||||||
|
for key in list(sys.modules):
|
||||||
|
val = sys.modules.get(key)
|
||||||
|
try:
|
||||||
|
file_path = val.__file__
|
||||||
|
if file_path.find("MMVC_Client_v13/python") >= 0:
|
||||||
|
print("remove", key, file_path)
|
||||||
|
sys.modules.pop(key)
|
||||||
|
except Exception as e:
|
||||||
|
pass
|
||||||
|
@ -247,6 +247,19 @@ class MMVCv15:
|
|||||||
audio = self._pyTorch_inference(data)
|
audio = self._pyTorch_inference(data)
|
||||||
return audio
|
return audio
|
||||||
|
|
||||||
def destroy(self):
|
def __del__(self):
|
||||||
del self.net_g
|
del self.net_g
|
||||||
del self.onnx_session
|
del self.onnx_session
|
||||||
|
|
||||||
|
remove_path = os.path.join("MMVC_Client_v15", "python")
|
||||||
|
sys.path = [x for x in sys.path if x.endswith(remove_path) == False]
|
||||||
|
|
||||||
|
for key in list(sys.modules):
|
||||||
|
val = sys.modules.get(key)
|
||||||
|
try:
|
||||||
|
file_path = val.__file__
|
||||||
|
if file_path.find("MMVC_Client_v15/python") >= 0:
|
||||||
|
print("remove", key, file_path)
|
||||||
|
sys.modules.pop(key)
|
||||||
|
except Exception as e:
|
||||||
|
pass
|
||||||
|
@ -277,6 +277,19 @@ class RVC:
|
|||||||
audio = self._pyTorch_inference(data)
|
audio = self._pyTorch_inference(data)
|
||||||
return audio
|
return audio
|
||||||
|
|
||||||
def destroy(self):
|
def __del__(self):
|
||||||
del self.net_g
|
del self.net_g
|
||||||
del self.onnx_session
|
del self.onnx_session
|
||||||
|
|
||||||
|
remove_path = os.path.join("RVC")
|
||||||
|
sys.path = [x for x in sys.path if x.endswith(remove_path) == False]
|
||||||
|
|
||||||
|
for key in list(sys.modules):
|
||||||
|
val = sys.modules.get(key)
|
||||||
|
try:
|
||||||
|
file_path = val.__file__
|
||||||
|
if file_path.find("RVC/") >= 0:
|
||||||
|
print("remove", key, file_path)
|
||||||
|
sys.modules.pop(key)
|
||||||
|
except Exception as e:
|
||||||
|
pass
|
||||||
|
@ -351,9 +351,21 @@ class SoVitsSvc40:
|
|||||||
audio = self._pyTorch_inference(data)
|
audio = self._pyTorch_inference(data)
|
||||||
return audio
|
return audio
|
||||||
|
|
||||||
def destroy(self):
|
def __del__(self):
|
||||||
del self.net_g
|
del self.net_g
|
||||||
del self.onnx_session
|
del self.onnx_session
|
||||||
|
remove_path = os.path.join("so-vits-svc-40")
|
||||||
|
sys.path = [x for x in sys.path if x.endswith(remove_path) == False]
|
||||||
|
|
||||||
|
for key in list(sys.modules):
|
||||||
|
val = sys.modules.get(key)
|
||||||
|
try:
|
||||||
|
file_path = val.__file__
|
||||||
|
if file_path.find("so-vits-svc-40/") >= 0:
|
||||||
|
print("remove", key, file_path)
|
||||||
|
sys.modules.pop(key)
|
||||||
|
except Exception as e:
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
def resize_f0(x, target_len):
|
def resize_f0(x, target_len):
|
||||||
|
@ -314,10 +314,23 @@ class SoVitsSvc40v2:
|
|||||||
audio = self._pyTorch_inference(data)
|
audio = self._pyTorch_inference(data)
|
||||||
return audio
|
return audio
|
||||||
|
|
||||||
def destroy(self):
|
def __del__(self):
|
||||||
del self.net_g
|
del self.net_g
|
||||||
del self.onnx_session
|
del self.onnx_session
|
||||||
|
|
||||||
|
remove_path = os.path.join("so-vits-svc-40v2")
|
||||||
|
sys.path = [x for x in sys.path if x.endswith(remove_path) == False]
|
||||||
|
|
||||||
|
for key in list(sys.modules):
|
||||||
|
val = sys.modules.get(key)
|
||||||
|
try:
|
||||||
|
file_path = val.__file__
|
||||||
|
if file_path.find("so-vits-svc-40v2/") >= 0:
|
||||||
|
print("remove", key, file_path)
|
||||||
|
sys.modules.pop(key)
|
||||||
|
except Exception as e:
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
def resize_f0(x, target_len):
|
def resize_f0(x, target_len):
|
||||||
source = np.array(x)
|
source = np.array(x)
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
from typing import Any, Callable, Optional, Protocol, TypeAlias, Union, cast
|
from typing import Any, Callable, Optional, Protocol, TypeAlias, Union, cast
|
||||||
from const import TMP_DIR, getModelType
|
from const import TMP_DIR, ModelType
|
||||||
import torch
|
import torch
|
||||||
import os
|
import os
|
||||||
import traceback
|
import traceback
|
||||||
import numpy as np
|
import numpy as np
|
||||||
from dataclasses import dataclass, asdict
|
from dataclasses import dataclass, asdict, field
|
||||||
import resampy
|
import resampy
|
||||||
|
|
||||||
|
|
||||||
@ -46,9 +46,15 @@ class VoiceChangerSettings():
|
|||||||
recordIO: int = 0 # 0:off, 1:on
|
recordIO: int = 0 # 0:off, 1:on
|
||||||
|
|
||||||
# ↓mutableな物だけ列挙
|
# ↓mutableな物だけ列挙
|
||||||
intData: list[str] = ["inputSampleRate", "crossFadeOverlapSize", "recordIO"]
|
intData: list[str] = field(
|
||||||
floatData: list[str] = ["crossFadeOffsetRate", "crossFadeEndRate"]
|
default_factory=lambda: ["inputSampleRate", "crossFadeOverlapSize", "recordIO"]
|
||||||
strData: list[str] = []
|
)
|
||||||
|
floatData: list[str] = field(
|
||||||
|
default_factory=lambda: ["crossFadeOffsetRate", "crossFadeEndRate"]
|
||||||
|
)
|
||||||
|
strData: list[str] = field(
|
||||||
|
default_factory=lambda: []
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class VoiceChanger():
|
class VoiceChanger():
|
||||||
@ -64,8 +70,46 @@ class VoiceChanger():
|
|||||||
self.currentCrossFadeOverlapSize = 0 # setting
|
self.currentCrossFadeOverlapSize = 0 # setting
|
||||||
self.crossfadeSize = 0 # calculated
|
self.crossfadeSize = 0 # calculated
|
||||||
|
|
||||||
self.modelType = getModelType()
|
# self.modelType = getModelType()
|
||||||
print("[VoiceChanger] activate model type:", self.modelType)
|
# print("[VoiceChanger] activate model type:", self.modelType)
|
||||||
|
# if self.modelType == "MMVCv15":
|
||||||
|
# from voice_changer.MMVCv15.MMVCv15 import MMVCv15
|
||||||
|
# self.voiceChanger = MMVCv15() # type: ignore
|
||||||
|
# elif self.modelType == "MMVCv13":
|
||||||
|
# from voice_changer.MMVCv13.MMVCv13 import MMVCv13
|
||||||
|
# self.voiceChanger = MMVCv13()
|
||||||
|
# elif self.modelType == "so-vits-svc-40v2":
|
||||||
|
# from voice_changer.SoVitsSvc40v2.SoVitsSvc40v2 import SoVitsSvc40v2
|
||||||
|
# self.voiceChanger = SoVitsSvc40v2(params)
|
||||||
|
# elif self.modelType == "so-vits-svc-40" or self.modelType == "so-vits-svc-40_c":
|
||||||
|
# from voice_changer.SoVitsSvc40.SoVitsSvc40 import SoVitsSvc40
|
||||||
|
# self.voiceChanger = SoVitsSvc40(params)
|
||||||
|
# elif self.modelType == "DDSP-SVC":
|
||||||
|
# from voice_changer.DDSP_SVC.DDSP_SVC import DDSP_SVC
|
||||||
|
# self.voiceChanger = DDSP_SVC(params)
|
||||||
|
# elif self.modelType == "RVC":
|
||||||
|
# from voice_changer.RVC.RVC import RVC
|
||||||
|
# self.voiceChanger = RVC(params)
|
||||||
|
# else:
|
||||||
|
# from voice_changer.MMVCv13.MMVCv13 import MMVCv13
|
||||||
|
# self.voiceChanger = MMVCv13()
|
||||||
|
|
||||||
|
self.voiceChanger = None
|
||||||
|
self.modelType = None
|
||||||
|
self.params = params
|
||||||
|
self.gpu_num = torch.cuda.device_count()
|
||||||
|
self.prev_audio = np.zeros(4096)
|
||||||
|
self.mps_enabled: bool = getattr(torch.backends, "mps", None) is not None and torch.backends.mps.is_available()
|
||||||
|
|
||||||
|
print(f"VoiceChanger Initialized (GPU_NUM:{self.gpu_num}, mps_enabled:{self.mps_enabled})")
|
||||||
|
|
||||||
|
def switchModelType(self, modelType: ModelType):
|
||||||
|
if hasattr(self, "voiceChanger") and self.voiceChanger != None:
|
||||||
|
# return {"status": "ERROR", "msg": "vc is already selected. currently re-select is not implemented"}
|
||||||
|
del self.voiceChanger
|
||||||
|
self.voiceChanger = None
|
||||||
|
|
||||||
|
self.modelType = modelType
|
||||||
if self.modelType == "MMVCv15":
|
if self.modelType == "MMVCv15":
|
||||||
from voice_changer.MMVCv15.MMVCv15 import MMVCv15
|
from voice_changer.MMVCv15.MMVCv15 import MMVCv15
|
||||||
self.voiceChanger = MMVCv15() # type: ignore
|
self.voiceChanger = MMVCv15() # type: ignore
|
||||||
@ -74,25 +118,27 @@ class VoiceChanger():
|
|||||||
self.voiceChanger = MMVCv13()
|
self.voiceChanger = MMVCv13()
|
||||||
elif self.modelType == "so-vits-svc-40v2":
|
elif self.modelType == "so-vits-svc-40v2":
|
||||||
from voice_changer.SoVitsSvc40v2.SoVitsSvc40v2 import SoVitsSvc40v2
|
from voice_changer.SoVitsSvc40v2.SoVitsSvc40v2 import SoVitsSvc40v2
|
||||||
self.voiceChanger = SoVitsSvc40v2(params)
|
self.voiceChanger = SoVitsSvc40v2(self.params)
|
||||||
elif self.modelType == "so-vits-svc-40" or self.modelType == "so-vits-svc-40_c":
|
elif self.modelType == "so-vits-svc-40" or self.modelType == "so-vits-svc-40_c":
|
||||||
from voice_changer.SoVitsSvc40.SoVitsSvc40 import SoVitsSvc40
|
from voice_changer.SoVitsSvc40.SoVitsSvc40 import SoVitsSvc40
|
||||||
self.voiceChanger = SoVitsSvc40(params)
|
self.voiceChanger = SoVitsSvc40(self.params)
|
||||||
elif self.modelType == "DDSP-SVC":
|
elif self.modelType == "DDSP-SVC":
|
||||||
from voice_changer.DDSP_SVC.DDSP_SVC import DDSP_SVC
|
from voice_changer.DDSP_SVC.DDSP_SVC import DDSP_SVC
|
||||||
self.voiceChanger = DDSP_SVC(params)
|
self.voiceChanger = DDSP_SVC(self.params)
|
||||||
elif self.modelType == "RVC":
|
elif self.modelType == "RVC":
|
||||||
from voice_changer.RVC.RVC import RVC
|
from voice_changer.RVC.RVC import RVC
|
||||||
self.voiceChanger = RVC(params)
|
self.voiceChanger = RVC(self.params)
|
||||||
else:
|
else:
|
||||||
from voice_changer.MMVCv13.MMVCv13 import MMVCv13
|
from voice_changer.MMVCv13.MMVCv13 import MMVCv13
|
||||||
self.voiceChanger = MMVCv13()
|
self.voiceChanger = MMVCv13()
|
||||||
|
|
||||||
self.gpu_num = torch.cuda.device_count()
|
return {"status": "OK", "msg": "vc is switched."}
|
||||||
self.prev_audio = np.zeros(4096)
|
|
||||||
self.mps_enabled: bool = getattr(torch.backends, "mps", None) is not None and torch.backends.mps.is_available()
|
|
||||||
|
|
||||||
print(f"VoiceChanger Initialized (GPU_NUM:{self.gpu_num}, mps_enabled:{self.mps_enabled})")
|
def getModelType(self):
|
||||||
|
if self.modelType != None:
|
||||||
|
return {"status": "OK", "vc": self.modelType}
|
||||||
|
else:
|
||||||
|
return {"status": "OK", "vc": "none"}
|
||||||
|
|
||||||
def loadModel(
|
def loadModel(
|
||||||
self,
|
self,
|
||||||
@ -115,7 +161,8 @@ class VoiceChanger():
|
|||||||
|
|
||||||
def get_info(self):
|
def get_info(self):
|
||||||
data = asdict(self.settings)
|
data = asdict(self.settings)
|
||||||
data.update(self.voiceChanger.get_info())
|
if hasattr(self, "voiceChanger"):
|
||||||
|
data.update(self.voiceChanger.get_info())
|
||||||
return data
|
return data
|
||||||
|
|
||||||
def update_settings(self, key: str, val: Any):
|
def update_settings(self, key: str, val: Any):
|
||||||
@ -148,10 +195,12 @@ class VoiceChanger():
|
|||||||
elif key in self.settings.strData:
|
elif key in self.settings.strData:
|
||||||
setattr(self.settings, key, str(val))
|
setattr(self.settings, key, str(val))
|
||||||
else:
|
else:
|
||||||
ret = self.voiceChanger.update_settings(key, val)
|
if hasattr(self, "voiceChanger"):
|
||||||
if ret == False:
|
ret = self.voiceChanger.update_settings(key, val)
|
||||||
print(f"{key} is not mutable variable or unknown variable!")
|
if ret == False:
|
||||||
|
print(f"{key} is not mutable variable or unknown variable!")
|
||||||
|
else:
|
||||||
|
print(f"voice changer is not initialized!")
|
||||||
return self.get_info()
|
return self.get_info()
|
||||||
|
|
||||||
def _generate_strength(self, crossfadeSize: int):
|
def _generate_strength(self, crossfadeSize: int):
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import numpy as np
|
import numpy as np
|
||||||
from voice_changer.VoiceChanger import VoiceChanger
|
from voice_changer.VoiceChanger import VoiceChanger
|
||||||
|
from const import ModelType
|
||||||
|
|
||||||
|
|
||||||
class VoiceChangerManager():
|
class VoiceChangerManager():
|
||||||
@ -37,3 +38,9 @@ class VoiceChangerManager():
|
|||||||
else:
|
else:
|
||||||
print("Voice Change is not loaded. Did you load a correct model?")
|
print("Voice Change is not loaded. Did you load a correct model?")
|
||||||
return np.zeros(1).astype(np.int16), []
|
return np.zeros(1).astype(np.int16), []
|
||||||
|
|
||||||
|
def switchModelType(self, modelType: ModelType):
|
||||||
|
return self.voiceChanger.switchModelType(modelType)
|
||||||
|
|
||||||
|
def getModelType(self):
|
||||||
|
return self.voiceChanger.getModelType()
|
||||||
|
Loading…
x
Reference in New Issue
Block a user