From ab837561d9d0b747919bd547e75bfd3379c16e46 Mon Sep 17 00:00:00 2001 From: w-okada Date: Wed, 22 Nov 2023 05:53:15 +0900 Subject: [PATCH] WIP:WEB version control --- .../src/001_globalHooks/100_useWebInfo.ts | 148 +++++++-------- .../src/001_provider/001_AppStateProvider.tsx | 2 +- .../101-8_web-editionSettingArea.tsx | 168 ++++++++++++++++++ .../demo/components2/101_CharacterArea.tsx | 5 + 4 files changed, 243 insertions(+), 80 deletions(-) create mode 100644 client/demo/src/components/demo/components2/101-8_web-editionSettingArea.tsx diff --git a/client/demo/src/001_globalHooks/100_useWebInfo.ts b/client/demo/src/001_globalHooks/100_useWebInfo.ts index 79d4cba6..39297adb 100644 --- a/client/demo/src/001_globalHooks/100_useWebInfo.ts +++ b/client/demo/src/001_globalHooks/100_useWebInfo.ts @@ -17,11 +17,13 @@ export type WebModelLoadingState = (typeof WebModelLoadingState)[keyof typeof We export type VoiceChangerConfig = { config: VoiceChangerJSClientConfig; modelUrl: string; - progressCallback?: ((data: any) => void) | null; portrait: string; name: string; termOfUse: string; - f0: boolean; + sampleRate: ModelSampleRateStr; + useF0: boolean; + inputLength: InputLengthKey; + progressCallback?: ((data: any) => void) | null; }; export type WebInfoState = { voiceChangerConfig: VoiceChangerConfig; @@ -35,6 +37,7 @@ export type WebInfoState = { export type WebInfoStateAndMethod = WebInfoState & { loadVoiceChanagerModel: () => Promise; setUpkey: (upkey: number) => void; + setVoiceChangerConfig: (voiceChangerType: VoiceChangerType, sampleRate: ModelSampleRateStr, useF0: boolean, inputLength: InputLengthKey) => void; }; const ModelSampleRateStr = { @@ -120,72 +123,51 @@ const f0ModelUrl: { [modelType in VoiceChangerType]: { [inputLength in InputLeng }, }; -// https://huggingface.co/wok000/vcclient_model/resolve/main/web_model/v_01_alpha/amitaro/rvcv1_amitaro_v1_32k_f0_8000.bin -// https://huggingface.co/wok000/vcclient_model/resolve/main/web_model/v_01_alpha/amitaro/rvcv1_amitaro_v1_32k_f0_12000.bin -// https://huggingface.co/wok000/vcclient_model/resolve/main/web_model/v_01_alpha/amitaro/rvcv1_amitaro_v1_32k_f0_16000.bin -// https://huggingface.co/wok000/vcclient_model/resolve/main/web_model/v_01_alpha/amitaro/rvcv1_amitaro_v1_32k_f0_24000.bin - -// https://huggingface.co/wok000/vcclient_model/resolve/main/web_model/v_01_alpha/amitaro/rvcv1_amitaro_v1_32k_nof0_8000.bin -// https://huggingface.co/wok000/vcclient_model/resolve/main/web_model/v_01_alpha/amitaro/rvcv1_amitaro_v1_32k_nof0_12000.bin -// https://huggingface.co/wok000/vcclient_model/resolve/main/web_model/v_01_alpha/amitaro/rvcv1_amitaro_v1_32k_nof0_16000.bin -// https://huggingface.co/wok000/vcclient_model/resolve/main/web_model/v_01_alpha/amitaro/rvcv1_amitaro_v1_32k_nof0_24000.bin - -// https://huggingface.co/wok000/vcclient_model/resolve/main/web_model/v_01_alpha/amitaro/rvcv1_amitaro_v1_40k_f0_8000.bin -// https://huggingface.co/wok000/vcclient_model/resolve/main/web_model/v_01_alpha/amitaro/rvcv1_amitaro_v1_40k_f0_12000.bin -// https://huggingface.co/wok000/vcclient_model/resolve/main/web_model/v_01_alpha/amitaro/rvcv1_amitaro_v1_40k_f0_16000.bin -// https://huggingface.co/wok000/vcclient_model/resolve/main/web_model/v_01_alpha/amitaro/rvcv1_amitaro_v1_40k_f0_24000.bin - -// https://huggingface.co/wok000/vcclient_model/resolve/main/web_model/v_01_alpha/amitaro/rvcv1_amitaro_v1_40k_nof0_8000.bin -// https://huggingface.co/wok000/vcclient_model/resolve/main/web_model/v_01_alpha/amitaro/rvcv1_amitaro_v1_40k_nof0_12000.bin -// https://huggingface.co/wok000/vcclient_model/resolve/main/web_model/v_01_alpha/amitaro/rvcv1_amitaro_v1_40k_nof0_16000.bin -// https://huggingface.co/wok000/vcclient_model/resolve/main/web_model/v_01_alpha/amitaro/rvcv1_amitaro_v1_40k_nof0_24000.bin - -// https://huggingface.co/wok000/vcclient_model/resolve/main/web_model/v_01_alpha/amitaro/rvcv2_amitaro_v2_32k_f0_8000.bin -// https://huggingface.co/wok000/vcclient_model/resolve/main/web_model/v_01_alpha/amitaro/rvcv2_amitaro_v2_32k_f0_12000.bin -// https://huggingface.co/wok000/vcclient_model/resolve/main/web_model/v_01_alpha/amitaro/rvcv2_amitaro_v2_32k_f0_16000.bin -// https://huggingface.co/wok000/vcclient_model/resolve/main/web_model/v_01_alpha/amitaro/rvcv2_amitaro_v2_32k_f0_24000.bin - -// https://huggingface.co/wok000/vcclient_model/resolve/main/web_model/v_01_alpha/amitaro/rvcv2_amitaro_v2_32k_nof0_8000.bin -// https://huggingface.co/wok000/vcclient_model/resolve/main/web_model/v_01_alpha/amitaro/rvcv2_amitaro_v2_32k_nof0_12000.bin -// https://huggingface.co/wok000/vcclient_model/resolve/main/web_model/v_01_alpha/amitaro/rvcv2_amitaro_v2_32k_nof0_16000.bin -// https://huggingface.co/wok000/vcclient_model/resolve/main/web_model/v_01_alpha/amitaro/rvcv2_amitaro_v2_32k_nof0_24000.bin - -// https://huggingface.co/wok000/vcclient_model/resolve/main/web_model/v_01_alpha/amitaro/rvcv2_amitaro_v2_40k_f0_8000.bin -// https://huggingface.co/wok000/vcclient_model/resolve/main/web_model/v_01_alpha/amitaro/rvcv2_amitaro_v2_40k_f0_12000.bin -// https://huggingface.co/wok000/vcclient_model/resolve/main/web_model/v_01_alpha/amitaro/rvcv2_amitaro_v2_40k_f0_16000.bin -// https://huggingface.co/wok000/vcclient_model/resolve/main/web_model/v_01_alpha/amitaro/rvcv2_amitaro_v2_40k_f0_24000.bin - -// https://huggingface.co/wok000/vcclient_model/resolve/main/web_model/v_01_alpha/amitaro/rvcv2_amitaro_v2_40k_nof0_8000.bin -// https://huggingface.co/wok000/vcclient_model/resolve/main/web_model/v_01_alpha/amitaro/rvcv2_amitaro_v2_40k_nof0_12000.bin -// https://huggingface.co/wok000/vcclient_model/resolve/main/web_model/v_01_alpha/amitaro/rvcv2_amitaro_v2_40k_nof0_16000.bin -// https://huggingface.co/wok000/vcclient_model/resolve/main/web_model/v_01_alpha/amitaro/rvcv2_amitaro_v2_40k_nof0_24000.bin - export const useWebInfo = (props: UseWebInfoProps): WebInfoStateAndMethod => { - const voiceChangerType: VoiceChangerType = "rvcv1"; - const inputLength: InputLengthKey = "24000"; - const useF0 = false; - const sampleRate: ModelSampleRateStr = "40k"; - let modelUrl; - if (useF0) { - modelUrl = f0ModelUrl[voiceChangerType][inputLength][sampleRate]; - } else { - modelUrl = noF0ModelUrl[voiceChangerType][inputLength][sampleRate]; - } - const [voiceChangerConfig, setVoiceChangerConfig] = useState({ - config: { - voiceChangerType: voiceChangerType, + const initVoiceChangerType: VoiceChangerType = "rvcv1"; + const initInputLength: InputLengthKey = "24000"; + const initUseF0 = false; + const initSampleRate: ModelSampleRateStr = "40k"; + + const progressCallback = (data: ProgreeeUpdateCallbcckInfo) => { + if (data.progressUpdateType === ProgressUpdateType.loadPreprocessModel) { + setProgressLoadPreprocess(data.progress); + } else if (data.progressUpdateType === ProgressUpdateType.loadVCModel) { + setProgressLoadVCModel(data.progress); + } else if (data.progressUpdateType === ProgressUpdateType.checkResponseTime) { + setProgressWarmup(data.progress); + } + }; + + const generateVoiceChangerConfig = (voiceChangerType: VoiceChangerType, sampleRate: ModelSampleRateStr, useF0: boolean, inputLength: InputLengthKey) => { + let modelUrl; + if (useF0) { + modelUrl = f0ModelUrl[voiceChangerType][inputLength][sampleRate]; + } else { + modelUrl = noF0ModelUrl[voiceChangerType][inputLength][sampleRate]; + } + + const config: VoiceChangerConfig = { + config: { + voiceChangerType: voiceChangerType, + inputLength: inputLength, + baseUrl: window.location.origin, + inputSamplingRate: 48000, + outputSamplingRate: 48000, + }, + modelUrl: modelUrl, + portrait: `${window.location.origin}/models/amitaro.png`, + name: "あみたろ", + termOfUse: "https://huggingface.co/wok000/vcclient_model/raw/main/rvc/amitaro_contentvec_256/term_of_use.txt", + sampleRate: sampleRate, + useF0: false, inputLength: inputLength, - baseUrl: window.location.origin, - inputSamplingRate: 48000, - outputSamplingRate: 48000, - }, - modelUrl: modelUrl, - progressCallback: null, - portrait: `${window.location.origin}/models/amitaro.png`, - name: "あみたろ", - termOfUse: "https://huggingface.co/wok000/vcclient_model/raw/main/rvc/amitaro_contentvec_256/term_of_use.txt", - f0: false, - }); + progressCallback, + }; + return config; + }; + + const [voiceChangerConfig, _setVoiceChangerConfig] = useState(generateVoiceChangerConfig(initVoiceChangerType, initSampleRate, initUseF0, initInputLength)); const [webModelLoadingState, setWebModelLoadingState] = useState(WebModelLoadingState.none); const [progressLoadPreprocess, setProgressLoadPreprocess] = useState(0); const [progressLoadVCModel, setProgressLoadVCModel] = useState(0); @@ -205,24 +187,19 @@ export const useWebInfo = (props: UseWebInfoProps): WebInfoStateAndMethod => { speakers: {}, defaultTune: 0, modelType: "pyTorchRVCNono", - f0: voiceChangerConfig.f0, + f0: voiceChangerConfig.useF0, samplingRate: 0, modelFile: "", }; }, []); - useEffect(() => { - const progressCallback = (data: ProgreeeUpdateCallbcckInfo) => { - if (data.progressUpdateType === ProgressUpdateType.loadPreprocessModel) { - setProgressLoadPreprocess(data.progress); - } else if (data.progressUpdateType === ProgressUpdateType.loadVCModel) { - setProgressLoadVCModel(data.progress); - } else if (data.progressUpdateType === ProgressUpdateType.checkResponseTime) { - setProgressWarmup(data.progress); - } - }; - setVoiceChangerConfig({ ...voiceChangerConfig, progressCallback }); - }, []); + const setVoiceChangerConfig = (voiceChangerType: VoiceChangerType, sampleRate: ModelSampleRateStr, useF0: boolean, inputLength: InputLengthKey) => { + const config = generateVoiceChangerConfig(voiceChangerType, sampleRate, useF0, inputLength); + _setVoiceChangerConfig(config); + }; + // useEffect(() => { + // setVoiceChangerConfig({ ...voiceChangerConfig, progressCallback }); + // }, []); const loadVoiceChanagerModel = async () => { if (!props.clientState) { @@ -232,9 +209,11 @@ export const useWebInfo = (props: UseWebInfoProps): WebInfoStateAndMethod => { console.warn("[useWebInfo] clientState is not initialized yet"); return; } + console.log("loadVoiceChanagerModel1", voiceChangerConfig); setWebModelLoadingState("loading"); voiceChangerJSClient.current = new VoiceChangerJSClient(); await voiceChangerJSClient.current.initialize(voiceChangerConfig.config, voiceChangerConfig.modelUrl, voiceChangerConfig.progressCallback); + console.log("loadVoiceChanagerModel2"); // worm up setWebModelLoadingState("warmup"); @@ -266,6 +245,16 @@ export const useWebInfo = (props: UseWebInfoProps): WebInfoStateAndMethod => { voiceChangerJSClient.current.setUpkey(upkey); }, [upkey]); + useEffect(() => { + console.log("change voice ", voiceChangerConfig); + + setProgressLoadPreprocess(0); + setProgressLoadVCModel(0); + setProgressWarmup(0); + + loadVoiceChanagerModel(); + }, [voiceChangerConfig, props.clientState?.initialized]); + return { voiceChangerConfig, webModelLoadingState, @@ -276,5 +265,6 @@ export const useWebInfo = (props: UseWebInfoProps): WebInfoStateAndMethod => { upkey, loadVoiceChanagerModel, setUpkey, + setVoiceChangerConfig, }; }; diff --git a/client/demo/src/001_provider/001_AppStateProvider.tsx b/client/demo/src/001_provider/001_AppStateProvider.tsx index b3fa47ca..0d40b33e 100644 --- a/client/demo/src/001_provider/001_AppStateProvider.tsx +++ b/client/demo/src/001_provider/001_AppStateProvider.tsx @@ -61,7 +61,7 @@ export const AppStateProvider = ({ children }: Props) => { useEffect(() => { if (appRoot.appGuiSettingState.edition.indexOf("web") >= 0 && clientState.clientState.initialized) { clientState.clientState.setWorkletNodeSetting({ ...clientState.clientState.setting.workletNodeSetting, protocol: "internal" }); - webInfoState.loadVoiceChanagerModel(); + // webInfoState.loadVoiceChanagerModel(); // hook内でuseEffectでinvoke } }, [clientState.clientState.initialized]); diff --git a/client/demo/src/components/demo/components2/101-8_web-editionSettingArea.tsx b/client/demo/src/components/demo/components2/101-8_web-editionSettingArea.tsx new file mode 100644 index 00000000..7413dcef --- /dev/null +++ b/client/demo/src/components/demo/components2/101-8_web-editionSettingArea.tsx @@ -0,0 +1,168 @@ +import React, { useMemo } from "react"; +import { useAppState } from "../../../001_provider/001_AppStateProvider"; +import { useAppRoot } from "../../../001_provider/001_AppRootProvider"; + +export type WebEditionSettingAreaProps = {}; + +export const WebEditionSettingArea = (_props: WebEditionSettingAreaProps) => { + const { serverSetting, webInfoState } = useAppState(); + const { appGuiSettingState } = useAppRoot(); + const webEdition = appGuiSettingState.edition.indexOf("web") >= 0; + + const selected = useMemo(() => { + if (webEdition) { + return webInfoState.webModelslot; + } + return null; + }, [webEdition]); + + const settingArea = useMemo(() => { + if (!selected) { + return <>; + } + + const versionV1ClassName = "character-area-control-button" + (webInfoState.voiceChangerConfig.config.voiceChangerType == "rvcv1" ? " character-area-control-button-active" : " character-area-control-button-stanby"); + const versionV2ClassName = "character-area-control-button" + (webInfoState.voiceChangerConfig.config.voiceChangerType == "rvcv2" ? " character-area-control-button-active" : " character-area-control-button-stanby"); + const verison = ( +
+
Version
+
+
+ + + { + webInfoState.setVoiceChangerConfig("rvcv1", webInfoState.voiceChangerConfig.sampleRate, webInfoState.voiceChangerConfig.useF0, webInfoState.voiceChangerConfig.inputLength); + }} + > + v1 + + { + console.log("v2 clicked!"); + webInfoState.setVoiceChangerConfig("rvcv2", webInfoState.voiceChangerConfig.sampleRate, webInfoState.voiceChangerConfig.useF0, webInfoState.voiceChangerConfig.inputLength); + }} + > + v2 + + +
+
+
+ ); + + const sr32KClassName = "character-area-control-button" + (webInfoState.voiceChangerConfig.sampleRate == "32k" ? " character-area-control-button-active" : " character-area-control-button-stanby"); + const sr40KClassName = "character-area-control-button" + (webInfoState.voiceChangerConfig.sampleRate == "40k" ? " character-area-control-button-active" : " character-area-control-button-stanby"); + const sampleRate = ( +
+
SR
+
+
+ + + { + webInfoState.setVoiceChangerConfig(webInfoState.voiceChangerConfig.config.voiceChangerType, "32k", webInfoState.voiceChangerConfig.useF0, webInfoState.voiceChangerConfig.inputLength); + }} + > + 32k + + { + webInfoState.setVoiceChangerConfig(webInfoState.voiceChangerConfig.config.voiceChangerType, "40k", webInfoState.voiceChangerConfig.useF0, webInfoState.voiceChangerConfig.inputLength); + }} + > + 40k + + +
+
+
+ ); + + const pitchEnableClassName = "character-area-control-button" + (webInfoState.voiceChangerConfig.useF0 == true ? " character-area-control-button-active" : " character-area-control-button-stanby"); + const pitchDisableClassName = "character-area-control-button" + (webInfoState.voiceChangerConfig.useF0 == false ? " character-area-control-button-active" : " character-area-control-button-stanby"); + const pitch = ( +
+
Pitch
+
+
+ + + { + webInfoState.setVoiceChangerConfig(webInfoState.voiceChangerConfig.config.voiceChangerType, webInfoState.voiceChangerConfig.sampleRate, true, webInfoState.voiceChangerConfig.inputLength); + }} + > + Enable + + { + webInfoState.setVoiceChangerConfig(webInfoState.voiceChangerConfig.config.voiceChangerType, webInfoState.voiceChangerConfig.sampleRate, false, webInfoState.voiceChangerConfig.inputLength); + }} + > + Disable + + +
+
+
+ ); + + const latencyHighClassName = "character-area-control-button" + (webInfoState.voiceChangerConfig.inputLength == "24000" ? " character-area-control-button-active" : " character-area-control-button-stanby"); + const latencyMidClassName = "character-area-control-button" + (webInfoState.voiceChangerConfig.inputLength == "12000" ? " character-area-control-button-active" : " character-area-control-button-stanby"); + const latencyLowClassName = "character-area-control-button" + (webInfoState.voiceChangerConfig.inputLength == "8000" ? " character-area-control-button-active" : " character-area-control-button-stanby"); + const latency = ( +
+
Latency
+
+
+ + + { + webInfoState.setVoiceChangerConfig(webInfoState.voiceChangerConfig.config.voiceChangerType, webInfoState.voiceChangerConfig.sampleRate, webInfoState.voiceChangerConfig.useF0, "24000"); + }} + > + High + + { + webInfoState.setVoiceChangerConfig(webInfoState.voiceChangerConfig.config.voiceChangerType, webInfoState.voiceChangerConfig.sampleRate, webInfoState.voiceChangerConfig.useF0, "12000"); + }} + > + Mid + + { + webInfoState.setVoiceChangerConfig(webInfoState.voiceChangerConfig.config.voiceChangerType, webInfoState.voiceChangerConfig.sampleRate, webInfoState.voiceChangerConfig.useF0, "8000"); + }} + > + Low + + +
+
+
+ ); + return ( + <> + {verison} + {sampleRate} + {pitch} + {latency} + + ); + }, [serverSetting.serverSetting, serverSetting.updateServerSettings, selected, webInfoState.upkey, webInfoState.voiceChangerConfig.config.voiceChangerType]); + + return settingArea; +}; diff --git a/client/demo/src/components/demo/components2/101_CharacterArea.tsx b/client/demo/src/components/demo/components2/101_CharacterArea.tsx index dc7708e8..5519d5dc 100644 --- a/client/demo/src/components/demo/components2/101_CharacterArea.tsx +++ b/client/demo/src/components/demo/components2/101_CharacterArea.tsx @@ -12,6 +12,7 @@ import { DDSPSVC30SettingArea } from "./101-6_ddsp-svc30SettingArea"; import { DiffusionSVCSettingArea } from "./101-7_diffusion-svcSettingArea"; import { Portrait } from "./101-0_Portrait"; import { useAppRoot } from "../../../001_provider/001_AppRootProvider"; +import { WebEditionSettingArea } from "./101-8_web-editionSettingArea"; export type CharacterAreaProps = {}; @@ -226,6 +227,9 @@ export const CharacterArea = (_props: CharacterAreaProps) => { if (!selected) { return <>; } + if (webEdition) { + return <>; + } const onUpdateDefaultClicked = async () => { await serverSetting.updateModelDefault(); }; @@ -286,6 +290,7 @@ export const CharacterArea = (_props: CharacterAreaProps) => { + {modelSlotControl}