mirror of
https://github.com/w-okada/voice-changer.git
synced 2025-02-02 16:23:58 +03:00
WIP: gui commonize 2
This commit is contained in:
parent
79abc3d667
commit
debfbf83d7
213
client/demo/dist/assets/gui_settings/RVC.json
vendored
213
client/demo/dist/assets/gui_settings/RVC.json
vendored
@ -2,57 +2,178 @@
|
||||
"type": "demo",
|
||||
"id": "RVC",
|
||||
"front": {
|
||||
"title": {
|
||||
"title": [
|
||||
{
|
||||
"name": "title",
|
||||
"options": {
|
||||
"mainTitle": "Realtime Voice Changer Client",
|
||||
"subTitle": "for RVC",
|
||||
"lineNum": 1
|
||||
},
|
||||
"serverControl": {
|
||||
"modelInfoEnable": true
|
||||
},
|
||||
"modelSetting": {
|
||||
"ONNXEnable": false,
|
||||
"pyTorchEnable": true,
|
||||
"MMVCCorrespondense": false,
|
||||
"pyTorchClusterEnable": false,
|
||||
"showPyTorchDefault": true,
|
||||
"frameworkEnable": true,
|
||||
"modelUploaderEnable": true,
|
||||
"configRow": false,
|
||||
"uploadRow": true
|
||||
},
|
||||
"deviceSetting": {},
|
||||
"qualityControl": {
|
||||
"F0DetectorEnable": false,
|
||||
"analyzerRow": true,
|
||||
"samplingRow": true,
|
||||
"playRow": true
|
||||
},
|
||||
"speakerSetting": {
|
||||
"srcIdEnable": false,
|
||||
"dstIdEnable": true,
|
||||
"editSpeakerIdMappingEnable": false,
|
||||
"f0FactorEnable": false,
|
||||
"tuningEnable": true,
|
||||
"clusterInferRationEnable": false,
|
||||
"noiseScaleEnable": false,
|
||||
"silentThresholdEnable": true
|
||||
},
|
||||
"converterSetting": {
|
||||
"extraDataLengthEnable": true
|
||||
},
|
||||
"advancedSetting": {
|
||||
"serverURLEnable": true,
|
||||
"protocolEnable": true,
|
||||
"sampleRateEnable": true,
|
||||
"sendingSampleRateEnable": true,
|
||||
"crossFadeOverlapSizeEnable": true,
|
||||
"crossFadeOffsetRateEnable": true,
|
||||
"crossFadeEndRateEnable": true,
|
||||
"downSamplingModeEnable": true,
|
||||
"trancateNumTresholdEnable": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "clearSetting",
|
||||
"options": {}
|
||||
}
|
||||
],
|
||||
"serverControl": [
|
||||
{
|
||||
"name": "startButton",
|
||||
"options": {}
|
||||
},
|
||||
{
|
||||
"name": "performance",
|
||||
"options": {}
|
||||
},
|
||||
{
|
||||
"name": "serverInfo",
|
||||
"options": {}
|
||||
}
|
||||
],
|
||||
"modelSetting": [
|
||||
{
|
||||
"name": "modelUploader",
|
||||
"options": {
|
||||
"showConfig": true,
|
||||
"showOnnx": true,
|
||||
"showPyTorch": true,
|
||||
"showCorrespondence": false,
|
||||
"showPyTorchCluster": false,
|
||||
|
||||
"defaultEnablePyTorch": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "framework",
|
||||
"options": {
|
||||
"showFramework": true
|
||||
}
|
||||
}
|
||||
],
|
||||
"deviceSetting": [
|
||||
{
|
||||
"name": "audioInput",
|
||||
"options": {}
|
||||
},
|
||||
{
|
||||
"name": "audioOutput",
|
||||
"options": {}
|
||||
}
|
||||
],
|
||||
"qualityControl": [
|
||||
{
|
||||
"name": "noiseControl",
|
||||
"options": {}
|
||||
},
|
||||
{
|
||||
"name": "gainControl",
|
||||
"options": {}
|
||||
},
|
||||
{
|
||||
"name": "f0Detector",
|
||||
"options": {}
|
||||
},
|
||||
{
|
||||
"name": "divider",
|
||||
"options": {}
|
||||
},
|
||||
{
|
||||
"name": "analyzer",
|
||||
"options": {}
|
||||
}
|
||||
],
|
||||
"speakerSetting": [
|
||||
{
|
||||
"name": "srcId",
|
||||
"options": {
|
||||
"showF0": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "dstId",
|
||||
"options": {
|
||||
"showF0": true,
|
||||
"useServerInfo": false
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "editSpeakerIdMapping",
|
||||
"options": {}
|
||||
},
|
||||
{
|
||||
"name": "f0Factor",
|
||||
"options": {}
|
||||
},
|
||||
{
|
||||
"name": "tune",
|
||||
"options": {}
|
||||
},
|
||||
{
|
||||
"name": "clusterInferRatio",
|
||||
"options": {}
|
||||
},
|
||||
{
|
||||
"name": "noiseScale",
|
||||
"options": {}
|
||||
},
|
||||
{
|
||||
"name": "silentThreshold",
|
||||
"options": {}
|
||||
}
|
||||
],
|
||||
"converterSetting": [
|
||||
{
|
||||
"name": "inputChunkNum",
|
||||
"options": {}
|
||||
},
|
||||
{
|
||||
"name": "extraDataLength",
|
||||
"options": {}
|
||||
},
|
||||
{
|
||||
"name": "gpu",
|
||||
"options": {}
|
||||
}
|
||||
],
|
||||
"advancedSetting": [
|
||||
{
|
||||
"name": "serverURL",
|
||||
"options": {}
|
||||
},
|
||||
{
|
||||
"name": "protocol",
|
||||
"options": {}
|
||||
},
|
||||
{
|
||||
"name": "sampleRate",
|
||||
"options": {}
|
||||
},
|
||||
{
|
||||
"name": "sendingSampleRate",
|
||||
"options": {}
|
||||
},
|
||||
{
|
||||
"name": "crossFadeOverlapSize",
|
||||
"options": {}
|
||||
},
|
||||
{
|
||||
"name": "crossFadeOffsetRate",
|
||||
"options": {}
|
||||
},
|
||||
{
|
||||
"name": "crossFadeEndRate",
|
||||
"options": {}
|
||||
},
|
||||
{
|
||||
"name": "downSamplingMode",
|
||||
"options": {}
|
||||
},
|
||||
{
|
||||
"name": "trancateNumThreshold",
|
||||
"options": {}
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
"dialogs": {
|
||||
"license": [
|
||||
|
1001
client/demo/dist/index.js
vendored
1001
client/demo/dist/index.js
vendored
File diff suppressed because one or more lines are too long
@ -2,57 +2,178 @@
|
||||
"type": "demo",
|
||||
"id": "RVC",
|
||||
"front": {
|
||||
"title": {
|
||||
"title": [
|
||||
{
|
||||
"name": "title",
|
||||
"options": {
|
||||
"mainTitle": "Realtime Voice Changer Client",
|
||||
"subTitle": "for RVC",
|
||||
"lineNum": 1
|
||||
},
|
||||
"serverControl": {
|
||||
"modelInfoEnable": true
|
||||
},
|
||||
"modelSetting": {
|
||||
"ONNXEnable": false,
|
||||
"pyTorchEnable": true,
|
||||
"MMVCCorrespondense": false,
|
||||
"pyTorchClusterEnable": false,
|
||||
"showPyTorchDefault": true,
|
||||
"frameworkEnable": true,
|
||||
"modelUploaderEnable": true,
|
||||
"configRow": false,
|
||||
"uploadRow": true
|
||||
},
|
||||
"deviceSetting": {},
|
||||
"qualityControl": {
|
||||
"F0DetectorEnable": false,
|
||||
"analyzerRow": true,
|
||||
"samplingRow": true,
|
||||
"playRow": true
|
||||
},
|
||||
"speakerSetting": {
|
||||
"srcIdEnable": false,
|
||||
"dstIdEnable": true,
|
||||
"editSpeakerIdMappingEnable": false,
|
||||
"f0FactorEnable": false,
|
||||
"tuningEnable": true,
|
||||
"clusterInferRationEnable": false,
|
||||
"noiseScaleEnable": false,
|
||||
"silentThresholdEnable": true
|
||||
},
|
||||
"converterSetting": {
|
||||
"extraDataLengthEnable": true
|
||||
},
|
||||
"advancedSetting": {
|
||||
"serverURLEnable": true,
|
||||
"protocolEnable": true,
|
||||
"sampleRateEnable": true,
|
||||
"sendingSampleRateEnable": true,
|
||||
"crossFadeOverlapSizeEnable": true,
|
||||
"crossFadeOffsetRateEnable": true,
|
||||
"crossFadeEndRateEnable": true,
|
||||
"downSamplingModeEnable": true,
|
||||
"trancateNumTresholdEnable": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "clearSetting",
|
||||
"options": {}
|
||||
}
|
||||
],
|
||||
"serverControl": [
|
||||
{
|
||||
"name": "startButton",
|
||||
"options": {}
|
||||
},
|
||||
{
|
||||
"name": "performance",
|
||||
"options": {}
|
||||
},
|
||||
{
|
||||
"name": "serverInfo",
|
||||
"options": {}
|
||||
}
|
||||
],
|
||||
"modelSetting": [
|
||||
{
|
||||
"name": "modelUploader",
|
||||
"options": {
|
||||
"showConfig": true,
|
||||
"showOnnx": true,
|
||||
"showPyTorch": true,
|
||||
"showCorrespondence": false,
|
||||
"showPyTorchCluster": false,
|
||||
|
||||
"defaultEnablePyTorch": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "framework",
|
||||
"options": {
|
||||
"showFramework": true
|
||||
}
|
||||
}
|
||||
],
|
||||
"deviceSetting": [
|
||||
{
|
||||
"name": "audioInput",
|
||||
"options": {}
|
||||
},
|
||||
{
|
||||
"name": "audioOutput",
|
||||
"options": {}
|
||||
}
|
||||
],
|
||||
"qualityControl": [
|
||||
{
|
||||
"name": "noiseControl",
|
||||
"options": {}
|
||||
},
|
||||
{
|
||||
"name": "gainControl",
|
||||
"options": {}
|
||||
},
|
||||
{
|
||||
"name": "f0Detector",
|
||||
"options": {}
|
||||
},
|
||||
{
|
||||
"name": "divider",
|
||||
"options": {}
|
||||
},
|
||||
{
|
||||
"name": "analyzer",
|
||||
"options": {}
|
||||
}
|
||||
],
|
||||
"speakerSetting": [
|
||||
{
|
||||
"name": "srcId",
|
||||
"options": {
|
||||
"showF0": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "dstId",
|
||||
"options": {
|
||||
"showF0": true,
|
||||
"useServerInfo": false
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "editSpeakerIdMapping",
|
||||
"options": {}
|
||||
},
|
||||
{
|
||||
"name": "f0Factor",
|
||||
"options": {}
|
||||
},
|
||||
{
|
||||
"name": "tune",
|
||||
"options": {}
|
||||
},
|
||||
{
|
||||
"name": "clusterInferRatio",
|
||||
"options": {}
|
||||
},
|
||||
{
|
||||
"name": "noiseScale",
|
||||
"options": {}
|
||||
},
|
||||
{
|
||||
"name": "silentThreshold",
|
||||
"options": {}
|
||||
}
|
||||
],
|
||||
"converterSetting": [
|
||||
{
|
||||
"name": "inputChunkNum",
|
||||
"options": {}
|
||||
},
|
||||
{
|
||||
"name": "extraDataLength",
|
||||
"options": {}
|
||||
},
|
||||
{
|
||||
"name": "gpu",
|
||||
"options": {}
|
||||
}
|
||||
],
|
||||
"advancedSetting": [
|
||||
{
|
||||
"name": "serverURL",
|
||||
"options": {}
|
||||
},
|
||||
{
|
||||
"name": "protocol",
|
||||
"options": {}
|
||||
},
|
||||
{
|
||||
"name": "sampleRate",
|
||||
"options": {}
|
||||
},
|
||||
{
|
||||
"name": "sendingSampleRate",
|
||||
"options": {}
|
||||
},
|
||||
{
|
||||
"name": "crossFadeOverlapSize",
|
||||
"options": {}
|
||||
},
|
||||
{
|
||||
"name": "crossFadeOffsetRate",
|
||||
"options": {}
|
||||
},
|
||||
{
|
||||
"name": "crossFadeEndRate",
|
||||
"options": {}
|
||||
},
|
||||
{
|
||||
"name": "downSamplingMode",
|
||||
"options": {}
|
||||
},
|
||||
{
|
||||
"name": "trancateNumThreshold",
|
||||
"options": {}
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
"dialogs": {
|
||||
"license": [
|
||||
|
@ -7,120 +7,37 @@ export type AppGuiDemoSetting = {
|
||||
type: "demo",
|
||||
id: ClientType,
|
||||
front: {
|
||||
"title": {
|
||||
"mainTitle": string,
|
||||
"subTitle": string,
|
||||
"lineNum": number
|
||||
},
|
||||
"serverControl": {
|
||||
"modelInfoEnable": boolean
|
||||
},
|
||||
"modelSetting": {
|
||||
"ONNXEnable": boolean,
|
||||
"pyTorchEnable": boolean,
|
||||
"MMVCCorrespondense": boolean,
|
||||
"pyTorchClusterEnable": boolean,
|
||||
"showPyTorchDefault": boolean,
|
||||
"frameworkEnable": boolean,
|
||||
"modelUploaderEnable": boolean,
|
||||
"configRow": boolean,
|
||||
"uploadRow": boolean
|
||||
|
||||
},
|
||||
"deviceSetting": {},
|
||||
"qualityControl": {
|
||||
"F0DetectorEnable": boolean,
|
||||
"analyzerRow": boolean,
|
||||
"samplingRow": boolean,
|
||||
"playRow": boolean
|
||||
},
|
||||
"speakerSetting": {
|
||||
"srcIdEnable": boolean
|
||||
"dstIdEnable": boolean
|
||||
"editSpeakerIdMappingEnable": boolean
|
||||
"f0FactorEnable": boolean
|
||||
"tuningEnable": boolean
|
||||
"clusterInferRationEnable": boolean
|
||||
"noiseScaleEnable": boolean
|
||||
"silentThresholdEnable": boolean
|
||||
},
|
||||
"converterSetting": {
|
||||
"extraDataLengthEnable": boolean
|
||||
},
|
||||
"advancedSetting": {
|
||||
"serverURLEnable": boolean,
|
||||
"protocolEnable": boolean,
|
||||
"sampleRateEnable": boolean,
|
||||
"sendingSampleRateEnable": boolean,
|
||||
"crossFadeOverlapSizeEnable": boolean,
|
||||
"crossFadeOffsetRateEnable": boolean,
|
||||
"crossFadeEndRateEnable": boolean,
|
||||
"downSamplingModeEnable": boolean,
|
||||
"trancateNumTresholdEnable": boolean,
|
||||
}
|
||||
"title": GuiComponentSetting[],
|
||||
"serverControl": GuiComponentSetting[],
|
||||
"modelSetting": GuiComponentSetting[],
|
||||
"deviceSetting": GuiComponentSetting[],
|
||||
"qualityControl": GuiComponentSetting[],
|
||||
"speakerSetting": GuiComponentSetting[],
|
||||
"converterSetting": GuiComponentSetting[],
|
||||
"advancedSetting": GuiComponentSetting[],
|
||||
},
|
||||
dialogs: {
|
||||
"license": { title: string, auther: string, contact: string, url: string, license: string }[]
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
export type GuiComponentSetting = {
|
||||
"name": string,
|
||||
"options": any
|
||||
}
|
||||
|
||||
const InitialAppGuiDemoSetting: AppGuiDemoSetting = {
|
||||
type: "demo",
|
||||
id: ClientType.MMVCv13,
|
||||
front: {
|
||||
"title": {
|
||||
"mainTitle": "",
|
||||
"subTitle": "",
|
||||
"lineNum": 1
|
||||
},
|
||||
"serverControl": {
|
||||
"modelInfoEnable": true
|
||||
},
|
||||
"modelSetting": {
|
||||
"ONNXEnable": false,
|
||||
"pyTorchEnable": false,
|
||||
"MMVCCorrespondense": false,
|
||||
"pyTorchClusterEnable": false,
|
||||
"showPyTorchDefault": false,
|
||||
"frameworkEnable": false,
|
||||
"modelUploaderEnable": false,
|
||||
"configRow": false,
|
||||
"uploadRow": false
|
||||
},
|
||||
"deviceSetting": {},
|
||||
"qualityControl": {
|
||||
"F0DetectorEnable": false,
|
||||
"analyzerRow": true,
|
||||
"samplingRow": true,
|
||||
"playRow": true
|
||||
},
|
||||
"speakerSetting": {
|
||||
"srcIdEnable": false,
|
||||
"dstIdEnable": false,
|
||||
"editSpeakerIdMappingEnable": false,
|
||||
"f0FactorEnable": false,
|
||||
"tuningEnable": false,
|
||||
"clusterInferRationEnable": false,
|
||||
"noiseScaleEnable": false,
|
||||
"silentThresholdEnable": false
|
||||
|
||||
},
|
||||
"converterSetting": {
|
||||
"extraDataLengthEnable": false
|
||||
},
|
||||
"advancedSetting": {
|
||||
"serverURLEnable": false,
|
||||
"protocolEnable": false,
|
||||
"sampleRateEnable": false,
|
||||
"sendingSampleRateEnable": false,
|
||||
"crossFadeOverlapSizeEnable": false,
|
||||
"crossFadeOffsetRateEnable": false,
|
||||
"crossFadeEndRateEnable": false,
|
||||
"downSamplingModeEnable": false,
|
||||
"trancateNumTresholdEnable": false,
|
||||
}
|
||||
"title": [],
|
||||
"serverControl": [],
|
||||
"modelSetting": [],
|
||||
"deviceSetting": [],
|
||||
"qualityControl": [],
|
||||
"speakerSetting": [],
|
||||
"converterSetting": [],
|
||||
"advancedSetting": []
|
||||
},
|
||||
dialogs: {
|
||||
"license": [{ title: "", auther: "", contact: "", url: "", license: "MIT" }]
|
||||
|
@ -1,5 +1,4 @@
|
||||
import { ClientState, useClient, ClientType } from "@dannadori/voice-changer-client-js"
|
||||
import { AUDIO_ELEMENT_FOR_PLAY_RESULT } from "../const"
|
||||
|
||||
export type UseVCClientProps = {
|
||||
audioContext: AudioContext | null
|
||||
@ -14,7 +13,6 @@ export const useVCClient = (props: UseVCClientProps) => {
|
||||
const clientState = useClient({
|
||||
clientType: props.clientType,
|
||||
audioContext: props.audioContext,
|
||||
audioOutputElementId: AUDIO_ELEMENT_FOR_PLAY_RESULT
|
||||
})
|
||||
|
||||
const ret: VCClientState = {
|
||||
|
@ -1,46 +0,0 @@
|
||||
import * as React from "react";
|
||||
import { useMemo } from "react";
|
||||
import { useModelSettingArea } from "./102_model_setting";
|
||||
import { useDeviceSetting } from "./103_device_setting";
|
||||
import { useConvertSetting } from "./106_convert_setting";
|
||||
import { useAdvancedSetting } from "./107_advanced_setting";
|
||||
import { useSpeakerSetting } from "./105_speaker_setting";
|
||||
import { useServerControl } from "./101_server_control";
|
||||
import { useQualityControl } from "./104_qulity_control";
|
||||
|
||||
export const useMicrophoneOptions = () => {
|
||||
const serverControl = useServerControl()
|
||||
const modelSetting = useModelSettingArea()
|
||||
const deviceSetting = useDeviceSetting()
|
||||
const speakerSetting = useSpeakerSetting()
|
||||
const convertSetting = useConvertSetting()
|
||||
const advancedSetting = useAdvancedSetting()
|
||||
const qualityControl = useQualityControl()
|
||||
|
||||
|
||||
const voiceChangerSetting = useMemo(() => {
|
||||
return (
|
||||
<>
|
||||
{serverControl.serverControl}
|
||||
{modelSetting.modelSetting}
|
||||
{deviceSetting.deviceSetting}
|
||||
{qualityControl.qualityControl}
|
||||
{speakerSetting.speakerSetting}
|
||||
{convertSetting.convertSetting}
|
||||
{advancedSetting.advancedSetting}
|
||||
</>
|
||||
)
|
||||
}, [serverControl.serverControl,
|
||||
modelSetting.modelSetting,
|
||||
deviceSetting.deviceSetting,
|
||||
speakerSetting.speakerSetting,
|
||||
convertSetting.convertSetting,
|
||||
advancedSetting.advancedSetting,
|
||||
qualityControl.qualityControl])
|
||||
|
||||
|
||||
return {
|
||||
voiceChangerSetting
|
||||
}
|
||||
}
|
||||
|
@ -1,149 +0,0 @@
|
||||
import React, { useEffect, useMemo, useState } from "react"
|
||||
import { useAppState } from "./001_provider/001_AppStateProvider";
|
||||
import { AnimationTypes, HeaderButton, HeaderButtonProps } from "./components/101_HeaderButton";
|
||||
|
||||
export const useServerControl = () => {
|
||||
const appState = useAppState()
|
||||
const [startWithAudioContextCreate, setStartWithAudioContextCreate] = useState<boolean>(false)
|
||||
const [showPerformanceDetail, setShowPerformanceDetail] = useState<boolean>(false)
|
||||
|
||||
const accodionButton = useMemo(() => {
|
||||
const accodionButtonProps: HeaderButtonProps = {
|
||||
stateControlCheckbox: appState.frontendManagerState.stateControls.openServerControlCheckbox,
|
||||
tooltip: "Open/Close",
|
||||
onIcon: ["fas", "caret-up"],
|
||||
offIcon: ["fas", "caret-up"],
|
||||
animation: AnimationTypes.spinner,
|
||||
tooltipClass: "tooltip-right",
|
||||
};
|
||||
return <HeaderButton {...accodionButtonProps}></HeaderButton>;
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
if (!startWithAudioContextCreate) {
|
||||
return
|
||||
}
|
||||
appState.frontendManagerState.setIsConverting(true)
|
||||
appState.clientSetting.start()
|
||||
}, [startWithAudioContextCreate])
|
||||
|
||||
const startButtonRow = useMemo(() => {
|
||||
const onStartClicked = async () => {
|
||||
if (!appState.initializedRef.current) {
|
||||
while (true) {
|
||||
// console.log("wait 500ms")
|
||||
await new Promise<void>((resolve) => {
|
||||
setTimeout(resolve, 500)
|
||||
})
|
||||
// console.log("initiliazed", appState.initializedRef.current)
|
||||
if (appState.initializedRef.current) {
|
||||
break
|
||||
}
|
||||
}
|
||||
setStartWithAudioContextCreate(true)
|
||||
} else {
|
||||
appState.frontendManagerState.setIsConverting(true)
|
||||
await appState.clientSetting.start()
|
||||
}
|
||||
}
|
||||
const onStopClicked = async () => {
|
||||
appState.frontendManagerState.setIsConverting(false)
|
||||
await appState.clientSetting.stop()
|
||||
}
|
||||
const startClassName = appState.frontendManagerState.isConverting ? "body-button-active" : "body-button-stanby"
|
||||
const stopClassName = appState.frontendManagerState.isConverting ? "body-button-stanby" : "body-button-active"
|
||||
|
||||
return (
|
||||
<div className="body-row split-3-2-2-3 left-padding-1 guided">
|
||||
<div className="body-item-title left-padding-1">Start</div>
|
||||
<div className="body-button-container">
|
||||
<div onClick={onStartClicked} className={startClassName}>start</div>
|
||||
<div onClick={onStopClicked} className={stopClassName}>stop</div>
|
||||
</div>
|
||||
<div>
|
||||
</div>
|
||||
<div className="body-input-container">
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}, [appState.frontendManagerState.isConverting, appState.clientSetting.start, appState.clientSetting.stop])
|
||||
|
||||
const performanceRow = useMemo(() => {
|
||||
const performanceDetailLabel = showPerformanceDetail ? "[pre, main, post] <<" : "more >>"
|
||||
const performanceData = showPerformanceDetail ? `[${appState.performance.preprocessTime}, ${appState.performance.mainprocessTime},${appState.performance.postprocessTime}]` : ""
|
||||
return (
|
||||
<>
|
||||
<div className="body-row split-3-1-1-1-4 left-padding-1 guided">
|
||||
<div className="body-item-title left-padding-1">monitor:</div>
|
||||
<div className="body-item-text">vol<span className="body-item-text-small">(rms)</span></div>
|
||||
<div className="body-item-text">buf<span className="body-item-text-small">(ms)</span></div>
|
||||
<div className="body-item-text">res<span className="body-item-text-small">(ms)</span></div>
|
||||
<div className="body-item-text">
|
||||
<span onClick={() => { setShowPerformanceDetail(!showPerformanceDetail) }} >{performanceDetailLabel}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div className="body-row split-3-1-1-1-4 left-padding-1 guided">
|
||||
<div className="body-item-title left-padding-1"></div>
|
||||
<div className="body-item-text">{appState.volume.toFixed(4)}</div>
|
||||
<div className="body-item-text">{appState.bufferingTime}</div>
|
||||
<div className="body-item-text">{appState.performance.responseTime}</div>
|
||||
<div className="body-item-text">{performanceData}</div>
|
||||
</div>
|
||||
</>
|
||||
)
|
||||
}, [appState.volume, appState.bufferingTime, appState.performance, showPerformanceDetail])
|
||||
|
||||
const infoRow = useMemo(() => {
|
||||
const onReloadClicked = async () => {
|
||||
const info = await appState.getInfo()
|
||||
console.log("info", info)
|
||||
}
|
||||
return (
|
||||
<>
|
||||
<div className="body-row split-3-3-4 left-padding-1 guided">
|
||||
<div className="body-item-title left-padding-1">Model Info:</div>
|
||||
<div className="body-item-text">
|
||||
<span className="body-item-text-item">{appState.serverSetting.serverSetting.configFile || ""}</span>
|
||||
<span className="body-item-text-item">{appState.serverSetting.serverSetting.pyTorchModelFile || ""}</span>
|
||||
<span className="body-item-text-item">{appState.serverSetting.serverSetting.onnxModelFile || ""}</span>
|
||||
|
||||
|
||||
</div>
|
||||
<div className="body-button-container">
|
||||
<div className="body-button" onClick={onReloadClicked}>reload</div>
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
)
|
||||
}, [appState.getInfo, appState.serverSetting.serverSetting])
|
||||
|
||||
const serverControl = useMemo(() => {
|
||||
return (
|
||||
<>
|
||||
{appState.frontendManagerState.stateControls.openServerControlCheckbox.trigger}
|
||||
<div className="partition">
|
||||
<div className="partition-header">
|
||||
<span className="caret">
|
||||
{accodionButton}
|
||||
</span>
|
||||
<span className="title" onClick={() => { appState.frontendManagerState.stateControls.openServerControlCheckbox.updateState(!appState.frontendManagerState.stateControls.openServerControlCheckbox.checked()) }}>
|
||||
Server Control
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div className="partition-content">
|
||||
{startButtonRow}
|
||||
{performanceRow}
|
||||
{infoRow}
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
)
|
||||
}, [startButtonRow, performanceRow, infoRow])
|
||||
|
||||
return {
|
||||
serverControl,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,293 +0,0 @@
|
||||
import { OnnxExecutionProvider, Framework, fileSelector, Correspondence } from "@dannadori/voice-changer-client-js"
|
||||
import React, { useState } from "react"
|
||||
import { useMemo } from "react"
|
||||
import { useAppState } from "./001_provider/001_AppStateProvider";
|
||||
import { AnimationTypes, HeaderButton, HeaderButtonProps } from "./components/101_HeaderButton";
|
||||
|
||||
export type ServerSettingState = {
|
||||
modelSetting: JSX.Element;
|
||||
}
|
||||
|
||||
export const useModelSettingArea = (): ServerSettingState => {
|
||||
const appState = useAppState()
|
||||
const [showPyTorch, setShowPyTorch] = useState<boolean>(false)
|
||||
|
||||
const accodionButton = useMemo(() => {
|
||||
const accodionButtonProps: HeaderButtonProps = {
|
||||
stateControlCheckbox: appState.frontendManagerState.stateControls.openModelSettingCheckbox,
|
||||
tooltip: "Open/Close",
|
||||
onIcon: ["fas", "caret-up"],
|
||||
offIcon: ["fas", "caret-up"],
|
||||
animation: AnimationTypes.spinner,
|
||||
tooltipClass: "tooltip-right",
|
||||
};
|
||||
return <HeaderButton {...accodionButtonProps}></HeaderButton>;
|
||||
}, []);
|
||||
|
||||
const uploadeModelRow = useMemo(() => {
|
||||
const onPyTorchFileLoadClicked = async () => {
|
||||
const file = await fileSelector("")
|
||||
if (file.name.endsWith(".pth") == false) {
|
||||
alert("モデルファイルの拡張子はpthである必要があります。")
|
||||
return
|
||||
}
|
||||
appState.serverSetting.setFileUploadSetting({
|
||||
...appState.serverSetting.fileUploadSetting,
|
||||
pyTorchModel: {
|
||||
file: file
|
||||
}
|
||||
})
|
||||
}
|
||||
const onPyTorchFileClearClicked = () => {
|
||||
appState.serverSetting.setFileUploadSetting({
|
||||
...appState.serverSetting.fileUploadSetting,
|
||||
pyTorchModel: null
|
||||
})
|
||||
}
|
||||
const onConfigFileLoadClicked = async () => {
|
||||
const file = await fileSelector("")
|
||||
if (file.name.endsWith(".json") == false) {
|
||||
alert("モデルファイルの拡張子はjsonである必要があります。")
|
||||
return
|
||||
}
|
||||
appState.serverSetting.setFileUploadSetting({
|
||||
...appState.serverSetting.fileUploadSetting,
|
||||
configFile: {
|
||||
file: file
|
||||
}
|
||||
})
|
||||
}
|
||||
const onConfigFileClearClicked = () => {
|
||||
appState.serverSetting.setFileUploadSetting({
|
||||
...appState.serverSetting.fileUploadSetting,
|
||||
configFile: null
|
||||
})
|
||||
}
|
||||
const onOnnxFileLoadClicked = async () => {
|
||||
const file = await fileSelector("")
|
||||
if (file.name.endsWith(".onnx") == false) {
|
||||
alert("モデルファイルの拡張子はonnxである必要があります。")
|
||||
return
|
||||
}
|
||||
appState.serverSetting.setFileUploadSetting({
|
||||
...appState.serverSetting.fileUploadSetting,
|
||||
onnxModel: {
|
||||
file: file
|
||||
}
|
||||
})
|
||||
}
|
||||
const onOnnxFileClearClicked = () => {
|
||||
appState.serverSetting.setFileUploadSetting({
|
||||
...appState.serverSetting.fileUploadSetting,
|
||||
onnxModel: null
|
||||
})
|
||||
}
|
||||
const onCorrespondenceFileLoadClicked = async () => {
|
||||
const file = await fileSelector("")
|
||||
|
||||
const correspondenceText = await file.text()
|
||||
const cors = correspondenceText.split("\n").map(line => {
|
||||
const items = line.split("|")
|
||||
if (items.length != 3) {
|
||||
console.warn("Invalid Correspondence Line:", line)
|
||||
return null
|
||||
} else {
|
||||
const cor: Correspondence = {
|
||||
sid: Number(items[0]),
|
||||
correspondence: Number(items[1]),
|
||||
dirname: items[2]
|
||||
}
|
||||
return cor
|
||||
}
|
||||
}).filter(x => { return x != null }) as Correspondence[]
|
||||
console.log(cors)
|
||||
appState.clientSetting.updateClientSetting({ ...appState.clientSetting.clientSetting, correspondences: cors })
|
||||
|
||||
}
|
||||
const onCorrespondenceFileClearClicked = () => {
|
||||
appState.clientSetting.updateClientSetting({ ...appState.clientSetting.clientSetting, correspondences: [] })
|
||||
}
|
||||
|
||||
const onModelUploadClicked = async () => {
|
||||
appState.serverSetting.loadModel()
|
||||
}
|
||||
|
||||
const uploadButtonClassName = appState.serverSetting.isUploading ? "body-button-disabled" : "body-button"
|
||||
const uploadButtonAction = appState.serverSetting.isUploading ? () => { } : onModelUploadClicked
|
||||
const uploadButtonLabel = appState.serverSetting.isUploading ? "wait..." : "upload"
|
||||
|
||||
const configFilenameText = appState.serverSetting.fileUploadSetting.configFile?.filename || appState.serverSetting.fileUploadSetting.configFile?.file?.name || ""
|
||||
const onnxModelFilenameText = appState.serverSetting.fileUploadSetting.onnxModel?.filename || appState.serverSetting.fileUploadSetting.onnxModel?.file?.name || ""
|
||||
const pyTorchFilenameText = appState.serverSetting.fileUploadSetting.pyTorchModel?.filename || appState.serverSetting.fileUploadSetting.pyTorchModel?.file?.name || ""
|
||||
const correspondenceFileText = appState.clientSetting.clientSetting.correspondences ? JSON.stringify(appState.clientSetting.clientSetting.correspondences.map(x => { return x.dirname })) : ""
|
||||
|
||||
const uploadingStatus = appState.serverSetting.isUploading ?
|
||||
appState.serverSetting.uploadProgress == 0 ? `loading model...(wait about 20sec)` : `uploading.... ${appState.serverSetting.uploadProgress}%` : ""
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="body-row split-3-3-4 left-padding-1 guided">
|
||||
<div className="body-item-title left-padding-1">Model Uploader</div>
|
||||
<div className="body-item-text">
|
||||
<div></div>
|
||||
</div>
|
||||
<div className="body-item-text">
|
||||
<div>
|
||||
<input type="checkbox" checked={showPyTorch} onChange={(e) => {
|
||||
setShowPyTorch(e.target.checked)
|
||||
}} /> enable PyTorch
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="body-row split-3-3-4 left-padding-1 guided">
|
||||
<div className="body-item-title left-padding-2">Config(.json)</div>
|
||||
<div className="body-item-text">
|
||||
<div>{configFilenameText}</div>
|
||||
</div>
|
||||
<div className="body-button-container">
|
||||
<div className="body-button" onClick={onConfigFileLoadClicked}>select</div>
|
||||
<div className="body-button left-margin-1" onClick={onConfigFileClearClicked}>clear</div>
|
||||
</div>
|
||||
</div>
|
||||
{/* <div className="body-row split-3-3-4 left-padding-1 guided">
|
||||
<div className="body-item-title left-padding-2">Correspondence</div>
|
||||
<div className="body-item-text">
|
||||
<div>{correspondenceFileText}</div>
|
||||
</div>
|
||||
<div className="body-button-container">
|
||||
<div className="body-button" onClick={onCorrespondenceFileLoadClicked}>select</div>
|
||||
<div className="body-button left-margin-1" onClick={onCorrespondenceFileClearClicked}>clear</div>
|
||||
</div>
|
||||
</div>
|
||||
*/}
|
||||
<div className="body-row split-3-3-4 left-padding-1 guided">
|
||||
<div className="body-item-title left-padding-2">Onnx(.onnx)</div>
|
||||
<div className="body-item-text">
|
||||
<div>{onnxModelFilenameText}</div>
|
||||
</div>
|
||||
<div className="body-button-container">
|
||||
<div className="body-button" onClick={onOnnxFileLoadClicked}>select</div>
|
||||
<div className="body-button left-margin-1" onClick={onOnnxFileClearClicked}>clear</div>
|
||||
</div>
|
||||
</div>
|
||||
{showPyTorch ?
|
||||
(
|
||||
<div className="body-row split-3-3-4 left-padding-1 guided">
|
||||
<div className="body-item-title left-padding-2">PyTorch(.pth)</div>
|
||||
<div className="body-item-text">
|
||||
<div>{pyTorchFilenameText}</div>
|
||||
</div>
|
||||
<div className="body-button-container">
|
||||
<div className="body-button" onClick={onPyTorchFileLoadClicked}>select</div>
|
||||
<div className="body-button left-margin-1" onClick={onPyTorchFileClearClicked}>clear</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
)
|
||||
:
|
||||
(
|
||||
<></>
|
||||
)
|
||||
}
|
||||
<div className="body-row split-3-3-4 left-padding-1 guided">
|
||||
<div className="body-item-title left-padding-2"></div>
|
||||
<div className="body-item-text">
|
||||
{uploadingStatus}
|
||||
</div>
|
||||
<div className="body-button-container">
|
||||
<div className={uploadButtonClassName} onClick={uploadButtonAction}>{uploadButtonLabel}</div>
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
)
|
||||
}, [
|
||||
appState.serverSetting.fileUploadSetting,
|
||||
appState.serverSetting.loadModel,
|
||||
appState.serverSetting.isUploading,
|
||||
appState.serverSetting.uploadProgress,
|
||||
appState.clientSetting.clientSetting.correspondences,
|
||||
appState.serverSetting.updateServerSettings,
|
||||
appState.serverSetting.setFileUploadSetting,
|
||||
showPyTorch])
|
||||
|
||||
const frameworkRow = useMemo(() => {
|
||||
const onFrameworkChanged = async (val: Framework) => {
|
||||
appState.serverSetting.updateServerSettings({ ...appState.serverSetting.serverSetting, framework: val })
|
||||
}
|
||||
return (
|
||||
<div className="body-row split-3-7 left-padding-1 guided">
|
||||
<div className="body-item-title left-padding-1">Framework</div>
|
||||
<div className="body-select-container">
|
||||
<select className="body-select" value={appState.serverSetting.serverSetting.framework} onChange={(e) => {
|
||||
onFrameworkChanged(e.target.value as
|
||||
Framework)
|
||||
}}>
|
||||
{
|
||||
Object.values(Framework).map(x => {
|
||||
return <option key={x} value={x}>{x}</option>
|
||||
})
|
||||
}
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}, [appState.serverSetting.serverSetting.framework, appState.serverSetting.updateServerSettings])
|
||||
|
||||
const onnxExecutionProviderRow = useMemo(() => {
|
||||
if (appState.serverSetting.serverSetting.framework != "ONNX") {
|
||||
return
|
||||
}
|
||||
const onOnnxExecutionProviderChanged = async (val: OnnxExecutionProvider) => {
|
||||
appState.serverSetting.updateServerSettings({ ...appState.serverSetting.serverSetting, onnxExecutionProvider: val })
|
||||
}
|
||||
console.log("setting", appState.serverSetting.serverSetting)
|
||||
return (
|
||||
<div className="body-row split-3-7 left-padding-1">
|
||||
<div className="body-item-title left-padding-2">OnnxExecutionProvider</div>
|
||||
<div className="body-select-container">
|
||||
<select className="body-select" value={appState.serverSetting.serverSetting.onnxExecutionProvider} onChange={(e) => {
|
||||
onOnnxExecutionProviderChanged(e.target.value as
|
||||
OnnxExecutionProvider)
|
||||
}}>
|
||||
{
|
||||
Object.values(OnnxExecutionProvider).map(x => {
|
||||
return <option key={x} value={x}>{x}</option>
|
||||
})
|
||||
}
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}, [appState.serverSetting.serverSetting.framework, appState.serverSetting.serverSetting.onnxExecutionProvider, appState.serverSetting.updateServerSettings])
|
||||
|
||||
const modelSetting = useMemo(() => {
|
||||
return (
|
||||
<>
|
||||
{appState.frontendManagerState.stateControls.openModelSettingCheckbox.trigger}
|
||||
<div className="partition">
|
||||
<div className="partition-header">
|
||||
<span className="caret">
|
||||
{accodionButton}
|
||||
</span>
|
||||
<span className="title" onClick={() => { appState.frontendManagerState.stateControls.openModelSettingCheckbox.updateState(!appState.frontendManagerState.stateControls.openModelSettingCheckbox.checked()) }}>
|
||||
Model Setting
|
||||
</span>
|
||||
<span></span>
|
||||
</div>
|
||||
|
||||
<div className="partition-content">
|
||||
{uploadeModelRow}
|
||||
{frameworkRow}
|
||||
{onnxExecutionProviderRow}
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
)
|
||||
}, [uploadeModelRow, frameworkRow, onnxExecutionProviderRow])
|
||||
|
||||
|
||||
return {
|
||||
modelSetting,
|
||||
}
|
||||
}
|
@ -1,402 +0,0 @@
|
||||
import { fileSelectorAsDataURL, useIndexedDB } from "@dannadori/voice-changer-client-js"
|
||||
import React, { useEffect, useMemo, useRef, useState } from "react"
|
||||
import { AUDIO_ELEMENT_FOR_PLAY_RESULT, AUDIO_ELEMENT_FOR_TEST_CONVERTED, AUDIO_ELEMENT_FOR_TEST_CONVERTED_ECHOBACK, AUDIO_ELEMENT_FOR_TEST_ORIGINAL, CLIENT_TYPE, INDEXEDDB_KEY_AUDIO_OUTPUT } from "./const"
|
||||
import { useAppState } from "./001_provider/001_AppStateProvider";
|
||||
import { AnimationTypes, HeaderButton, HeaderButtonProps } from "./components/101_HeaderButton";
|
||||
|
||||
|
||||
const reloadDevices = async () => {
|
||||
try {
|
||||
const ms = await navigator.mediaDevices.getUserMedia({ video: false, audio: true });
|
||||
ms.getTracks().forEach(x => { x.stop() })
|
||||
} catch (e) {
|
||||
console.warn("Enumerate device error::", e)
|
||||
}
|
||||
const mediaDeviceInfos = await navigator.mediaDevices.enumerateDevices();
|
||||
|
||||
const audioInputs = mediaDeviceInfos.filter(x => { return x.kind == "audioinput" })
|
||||
audioInputs.push({
|
||||
deviceId: "none",
|
||||
groupId: "none",
|
||||
kind: "audioinput",
|
||||
label: "none",
|
||||
toJSON: () => { }
|
||||
})
|
||||
audioInputs.push({
|
||||
deviceId: "file",
|
||||
groupId: "file",
|
||||
kind: "audioinput",
|
||||
label: "file",
|
||||
toJSON: () => { }
|
||||
})
|
||||
const audioOutputs = mediaDeviceInfos.filter(x => { return x.kind == "audiooutput" })
|
||||
audioOutputs.push({
|
||||
deviceId: "none",
|
||||
groupId: "none",
|
||||
kind: "audiooutput",
|
||||
label: "none",
|
||||
toJSON: () => { }
|
||||
})
|
||||
// audioOutputs.push({
|
||||
// deviceId: "record",
|
||||
// groupId: "record",
|
||||
// kind: "audiooutput",
|
||||
// label: "record",
|
||||
// toJSON: () => { }
|
||||
// })
|
||||
return [audioInputs, audioOutputs]
|
||||
}
|
||||
|
||||
export type DeviceSettingState = {
|
||||
deviceSetting: JSX.Element;
|
||||
}
|
||||
|
||||
export const useDeviceSetting = (): DeviceSettingState => {
|
||||
const appState = useAppState()
|
||||
const accodionButton = useMemo(() => {
|
||||
const accodionButtonProps: HeaderButtonProps = {
|
||||
stateControlCheckbox: appState.frontendManagerState.stateControls.openDeviceSettingCheckbox,
|
||||
tooltip: "Open/Close",
|
||||
onIcon: ["fas", "caret-up"],
|
||||
offIcon: ["fas", "caret-up"],
|
||||
animation: AnimationTypes.spinner,
|
||||
tooltipClass: "tooltip-right",
|
||||
};
|
||||
return <HeaderButton {...accodionButtonProps}></HeaderButton>;
|
||||
}, []);
|
||||
|
||||
const [inputAudioDeviceInfo, setInputAudioDeviceInfo] = useState<MediaDeviceInfo[]>([])
|
||||
const [outputAudioDeviceInfo, setOutputAudioDeviceInfo] = useState<MediaDeviceInfo[]>([])
|
||||
|
||||
const [audioInputForGUI, setAudioInputForGUI] = useState<string>("none")
|
||||
const [audioOutputForGUI, setAudioOutputForGUI] = useState<string>("none")
|
||||
const [fileInputEchoback, setFileInputEchoback] = useState<boolean>()//最初のmuteが有効になるように。undefined
|
||||
const { getItem, setItem } = useIndexedDB({ clientType: CLIENT_TYPE })
|
||||
|
||||
const audioSrcNode = useRef<MediaElementAudioSourceNode>()
|
||||
|
||||
const [outputRecordingStarted, setOutputRecordingStarted] = useState<boolean>(false)
|
||||
|
||||
const [useServerMicrophone, setUseServerMicrophone] = useState<boolean>(false)
|
||||
|
||||
// リスト内の
|
||||
useEffect(() => {
|
||||
const initialize = async () => {
|
||||
const audioInfo = await reloadDevices()
|
||||
setInputAudioDeviceInfo(audioInfo[0])
|
||||
setOutputAudioDeviceInfo(audioInfo[1])
|
||||
// if (useServerMicrophone) {
|
||||
// try {
|
||||
// const serverDevices = await appState.serverSetting.getServerDevices()
|
||||
// setServerInputAudioDeviceInfo(serverDevices.audio_input_devices)
|
||||
// } catch (e) {
|
||||
// console.warn(e)
|
||||
// }
|
||||
// }
|
||||
}
|
||||
initialize()
|
||||
}, [useServerMicrophone])
|
||||
|
||||
// キャッシュの設定は反映(たぶん、設定操作の時も起動していしまう。が問題は起こらないはず)
|
||||
useEffect(() => {
|
||||
if (typeof appState.clientSetting.clientSetting.audioInput == "string") {
|
||||
if (inputAudioDeviceInfo.find(x => {
|
||||
// console.log("COMPARE:", x.deviceId, appState.clientSetting.setting.audioInput)
|
||||
return x.deviceId == appState.clientSetting.clientSetting.audioInput
|
||||
})) {
|
||||
setAudioInputForGUI(appState.clientSetting.clientSetting.audioInput)
|
||||
}
|
||||
}
|
||||
}, [inputAudioDeviceInfo, appState.clientSetting.clientSetting.audioInput])
|
||||
|
||||
const audioInputRow = useMemo(() => {
|
||||
if (useServerMicrophone) {
|
||||
return <></>
|
||||
}
|
||||
return (
|
||||
<div className="body-row split-3-7 left-padding-1 guided">
|
||||
<div className="body-item-title left-padding-1">AudioInput</div>
|
||||
<div className="body-select-container">
|
||||
<select className="body-select" value={audioInputForGUI} onChange={(e) => {
|
||||
setAudioInputForGUI(e.target.value)
|
||||
}}>
|
||||
{
|
||||
inputAudioDeviceInfo.map(x => {
|
||||
return <option key={x.deviceId} value={x.deviceId}>{x.label}</option>
|
||||
})
|
||||
}
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}, [inputAudioDeviceInfo, audioInputForGUI, useServerMicrophone])
|
||||
|
||||
useEffect(() => {
|
||||
if (audioInputForGUI == "file") {
|
||||
// file selector (audioMediaInputRow)
|
||||
} else {
|
||||
if (!useServerMicrophone) {
|
||||
appState.clientSetting.updateClientSetting({ ...appState.clientSetting.clientSetting, audioInput: audioInputForGUI })
|
||||
} else {
|
||||
console.log("server mic")
|
||||
appState.clientSetting.updateClientSetting({ ...appState.clientSetting.clientSetting, audioInput: null })
|
||||
}
|
||||
}
|
||||
}, [appState.audioContext, audioInputForGUI, appState.clientSetting.updateClientSetting])
|
||||
|
||||
const audioMediaInputRow = useMemo(() => {
|
||||
if (audioInputForGUI != "file") {
|
||||
return <></>
|
||||
}
|
||||
|
||||
const onFileLoadClicked = async () => {
|
||||
const url = await fileSelectorAsDataURL("")
|
||||
|
||||
// input stream for client.
|
||||
const audio = document.getElementById(AUDIO_ELEMENT_FOR_TEST_CONVERTED) as HTMLAudioElement
|
||||
audio.pause()
|
||||
audio.srcObject = null
|
||||
audio.src = url
|
||||
await audio.play()
|
||||
if (!audioSrcNode.current) {
|
||||
audioSrcNode.current = appState.audioContext!.createMediaElementSource(audio);
|
||||
}
|
||||
if (audioSrcNode.current.mediaElement != audio) {
|
||||
audioSrcNode.current = appState.audioContext!.createMediaElementSource(audio);
|
||||
}
|
||||
|
||||
const dst = appState.audioContext.createMediaStreamDestination()
|
||||
audioSrcNode.current.connect(dst)
|
||||
appState.clientSetting.updateClientSetting({ ...appState.clientSetting.clientSetting, audioInput: dst.stream })
|
||||
|
||||
const audio_echo = document.getElementById(AUDIO_ELEMENT_FOR_TEST_CONVERTED_ECHOBACK) as HTMLAudioElement
|
||||
audio_echo.srcObject = dst.stream
|
||||
audio_echo.play()
|
||||
audio_echo.volume = 0
|
||||
setFileInputEchoback(false)
|
||||
|
||||
// original stream to play.
|
||||
const audio_org = document.getElementById(AUDIO_ELEMENT_FOR_TEST_ORIGINAL) as HTMLAudioElement
|
||||
audio_org.src = url
|
||||
audio_org.pause()
|
||||
|
||||
// audio_org.onplay = () => {
|
||||
// console.log(audioOutputRef.current)
|
||||
// // @ts-ignore
|
||||
// audio_org.setSinkId(audioOutputRef.current)
|
||||
// }
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="body-row split-3-3-4 left-padding-1 guided">
|
||||
<div className="body-item-title"></div>
|
||||
<div className="body-item-text">
|
||||
<div style={{ display: "none" }}>
|
||||
org:<audio id={AUDIO_ELEMENT_FOR_TEST_ORIGINAL} controls></audio>
|
||||
</div>
|
||||
<div>
|
||||
<audio id={AUDIO_ELEMENT_FOR_TEST_CONVERTED} controls></audio>
|
||||
<audio id={AUDIO_ELEMENT_FOR_TEST_CONVERTED_ECHOBACK} controls hidden></audio>
|
||||
</div>
|
||||
</div>
|
||||
<div className="body-button-container">
|
||||
<div className="body-button" onClick={onFileLoadClicked}>load</div>
|
||||
<input type="checkbox" checked={fileInputEchoback} onChange={(e) => { setFileInputEchoback(e.target.checked) }} /> echoback
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}, [audioInputForGUI, appState.clientSetting.updateClientSetting, fileInputEchoback])
|
||||
|
||||
|
||||
|
||||
const audioOutputRow = useMemo(() => {
|
||||
return (
|
||||
<div className="body-row split-3-7 left-padding-1 guided">
|
||||
<div className="body-item-title left-padding-1">AudioOutput</div>
|
||||
<div className="body-select-container">
|
||||
<select className="body-select" value={audioOutputForGUI} onChange={(e) => {
|
||||
setAudioOutputForGUI(e.target.value)
|
||||
setItem(INDEXEDDB_KEY_AUDIO_OUTPUT, e.target.value)
|
||||
}}>
|
||||
{
|
||||
outputAudioDeviceInfo.map(x => {
|
||||
return <option key={x.deviceId} value={x.deviceId}>{x.label}</option>
|
||||
})
|
||||
}
|
||||
</select>
|
||||
<audio hidden id={AUDIO_ELEMENT_FOR_PLAY_RESULT}></audio>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}, [outputAudioDeviceInfo, audioOutputForGUI])
|
||||
|
||||
const audioOutputRecordingRow = useMemo(() => {
|
||||
// if (audioOutputForGUI != "record") {
|
||||
// return <></>
|
||||
// }
|
||||
const onOutputRecordStartClicked = async () => {
|
||||
setOutputRecordingStarted(true)
|
||||
await appState.workletNodeSetting.startOutputRecording()
|
||||
}
|
||||
const onOutputRecordStopClicked = async () => {
|
||||
setOutputRecordingStarted(false)
|
||||
const record = await appState.workletNodeSetting.stopOutputRecording()
|
||||
downloadRecord(record)
|
||||
}
|
||||
|
||||
const startClassName = outputRecordingStarted ? "body-button-active" : "body-button-stanby"
|
||||
const stopClassName = outputRecordingStarted ? "body-button-stanby" : "body-button-active"
|
||||
|
||||
return (
|
||||
<div className="body-row split-3-3-4 left-padding-1 guided">
|
||||
<div className="body-item-title left-padding-2">output record</div>
|
||||
<div className="body-button-container">
|
||||
<div onClick={onOutputRecordStartClicked} className={startClassName}>start</div>
|
||||
<div onClick={onOutputRecordStopClicked} className={stopClassName}>stop</div>
|
||||
</div>
|
||||
<div className="body-input-container">
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
|
||||
}, [audioOutputForGUI, outputRecordingStarted, appState.workletNodeSetting.startOutputRecording, appState.workletNodeSetting.stopOutputRecording])
|
||||
|
||||
useEffect(() => {
|
||||
const setAudioOutput = async () => {
|
||||
const mediaDeviceInfos = await navigator.mediaDevices.enumerateDevices();
|
||||
|
||||
[AUDIO_ELEMENT_FOR_PLAY_RESULT, AUDIO_ELEMENT_FOR_TEST_ORIGINAL, AUDIO_ELEMENT_FOR_TEST_CONVERTED_ECHOBACK].forEach(x => {
|
||||
const audio = document.getElementById(x) as HTMLAudioElement
|
||||
if (audio) {
|
||||
if (audioOutputForGUI == "none") {
|
||||
// @ts-ignore
|
||||
audio.setSinkId("")
|
||||
if (x == AUDIO_ELEMENT_FOR_TEST_CONVERTED_ECHOBACK) {
|
||||
audio.volume = 0
|
||||
} else {
|
||||
audio.volume = 0
|
||||
}
|
||||
} else {
|
||||
const audioOutputs = mediaDeviceInfos.filter(x => { return x.kind == "audiooutput" })
|
||||
const found = audioOutputs.some(x => { return x.deviceId == audioOutputForGUI })
|
||||
if (found) {
|
||||
// @ts-ignore // 例外キャッチできないので事前にIDチェックが必要らしい。!?
|
||||
audio.setSinkId(audioOutputForGUI)
|
||||
} else {
|
||||
console.warn("No audio output device. use default")
|
||||
}
|
||||
if (x == AUDIO_ELEMENT_FOR_TEST_CONVERTED_ECHOBACK) {
|
||||
audio.volume = fileInputEchoback ? 1 : 0
|
||||
} else {
|
||||
audio.volume = 1
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
setAudioOutput()
|
||||
}, [audioOutputForGUI])
|
||||
|
||||
|
||||
|
||||
useEffect(() => {
|
||||
const loadCache = async () => {
|
||||
const key = await getItem(INDEXEDDB_KEY_AUDIO_OUTPUT)
|
||||
if (key) {
|
||||
setAudioOutputForGUI(key as string)
|
||||
}
|
||||
}
|
||||
loadCache()
|
||||
}, [])
|
||||
|
||||
|
||||
useEffect(() => {
|
||||
[AUDIO_ELEMENT_FOR_TEST_CONVERTED_ECHOBACK].forEach(x => {
|
||||
const audio = document.getElementById(x) as HTMLAudioElement
|
||||
if (audio) {
|
||||
audio.volume = fileInputEchoback ? 1 : 0
|
||||
}
|
||||
})
|
||||
}, [fileInputEchoback])
|
||||
|
||||
const deviceSetting = useMemo(() => {
|
||||
return (
|
||||
<>
|
||||
{appState.frontendManagerState.stateControls.openDeviceSettingCheckbox.trigger}
|
||||
|
||||
<div className="partition">
|
||||
<div className="partition-header">
|
||||
<span className="caret">
|
||||
{accodionButton}
|
||||
</span>
|
||||
<span className="title" onClick={() => { appState.frontendManagerState.stateControls.openDeviceSettingCheckbox.updateState(!appState.frontendManagerState.stateControls.openDeviceSettingCheckbox.checked()) }}>
|
||||
Device Setting
|
||||
</span>
|
||||
<span className="belongings">
|
||||
{/* <input className="belongings-checkbox" type="checkbox" checked={useServerMicrophone} onChange={(e) => {
|
||||
setUseServerMicrophone(e.target.checked)
|
||||
}} /> use server mic (Experimental) */}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div className="partition-content">
|
||||
{audioInputRow}
|
||||
{audioMediaInputRow}
|
||||
{audioOutputRow}
|
||||
{audioOutputRecordingRow}
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
)
|
||||
}, [audioInputRow, audioMediaInputRow, audioOutputRow, audioOutputRecordingRow, useServerMicrophone])
|
||||
|
||||
|
||||
const downloadRecord = (data: Float32Array) => {
|
||||
|
||||
const writeString = (view: DataView, offset: number, string: string) => {
|
||||
for (var i = 0; i < string.length; i++) {
|
||||
view.setUint8(offset + i, string.charCodeAt(i));
|
||||
}
|
||||
};
|
||||
|
||||
const floatTo16BitPCM = (output: DataView, offset: number, input: Float32Array) => {
|
||||
for (var i = 0; i < input.length; i++, offset += 2) {
|
||||
var s = Math.max(-1, Math.min(1, input[i]));
|
||||
output.setInt16(offset, s < 0 ? s * 0x8000 : s * 0x7FFF, true);
|
||||
}
|
||||
};
|
||||
|
||||
const buffer = new ArrayBuffer(44 + data.length * 2);
|
||||
const view = new DataView(buffer);
|
||||
|
||||
// https://www.youfit.co.jp/archives/1418
|
||||
writeString(view, 0, 'RIFF'); // RIFFヘッダ
|
||||
view.setUint32(4, 32 + data.length * 2, true); // これ以降のファイルサイズ
|
||||
writeString(view, 8, 'WAVE'); // WAVEヘッダ
|
||||
writeString(view, 12, 'fmt '); // fmtチャンク
|
||||
view.setUint32(16, 16, true); // fmtチャンクのバイト数
|
||||
view.setUint16(20, 1, true); // フォーマットID
|
||||
view.setUint16(22, 1, true); // チャンネル数
|
||||
view.setUint32(24, 48000, true); // サンプリングレート
|
||||
view.setUint32(28, 48000 * 2, true); // データ速度
|
||||
view.setUint16(32, 2, true); // ブロックサイズ
|
||||
view.setUint16(34, 16, true); // サンプルあたりのビット数
|
||||
writeString(view, 36, 'data'); // dataチャンク
|
||||
view.setUint32(40, data.length * 2, true); // 波形データのバイト数
|
||||
floatTo16BitPCM(view, 44, data); // 波形データ
|
||||
const audioBlob = new Blob([view], { type: 'audio/wav' });
|
||||
|
||||
const url = URL.createObjectURL(audioBlob);
|
||||
const a = document.createElement("a");
|
||||
a.href = url;
|
||||
a.download = `output.wav`;
|
||||
document.body.appendChild(a);
|
||||
a.click();
|
||||
document.body.removeChild(a);
|
||||
URL.revokeObjectURL(url);
|
||||
}
|
||||
|
||||
return {
|
||||
deviceSetting,
|
||||
}
|
||||
}
|
@ -1,311 +0,0 @@
|
||||
import React, { useEffect, useMemo, useState } from "react"
|
||||
import { useAppState } from "./001_provider/001_AppStateProvider";
|
||||
import { AnimationTypes, HeaderButton, HeaderButtonProps } from "./components/101_HeaderButton";
|
||||
|
||||
|
||||
|
||||
export type QualityControlState = {
|
||||
qualityControl: JSX.Element;
|
||||
}
|
||||
const reloadDevices = async () => {
|
||||
try {
|
||||
const ms = await navigator.mediaDevices.getUserMedia({ video: false, audio: true });
|
||||
ms.getTracks().forEach(x => { x.stop() })
|
||||
} catch (e) {
|
||||
console.warn("Enumerate device error::", e)
|
||||
}
|
||||
const mediaDeviceInfos = await navigator.mediaDevices.enumerateDevices();
|
||||
const audioOutputs = mediaDeviceInfos.filter(x => { return x.kind == "audiooutput" })
|
||||
|
||||
return audioOutputs
|
||||
}
|
||||
|
||||
|
||||
export const useQualityControl = (): QualityControlState => {
|
||||
const appState = useAppState()
|
||||
const accodionButton = useMemo(() => {
|
||||
const accodionButtonProps: HeaderButtonProps = {
|
||||
stateControlCheckbox: appState.frontendManagerState.stateControls.openQualityControlCheckbox,
|
||||
tooltip: "Open/Close",
|
||||
onIcon: ["fas", "caret-up"],
|
||||
offIcon: ["fas", "caret-up"],
|
||||
animation: AnimationTypes.spinner,
|
||||
tooltipClass: "tooltip-right",
|
||||
};
|
||||
return <HeaderButton {...accodionButtonProps}></HeaderButton>;
|
||||
}, []);
|
||||
|
||||
const [recording, setRecording] = useState<boolean>(false)
|
||||
const [outputAudioDeviceInfo, setOutputAudioDeviceInfo] = useState<MediaDeviceInfo[]>([])
|
||||
const [audioOutputForGUI, setAudioOutputForGUI] = useState<string>("default")
|
||||
useEffect(() => {
|
||||
const initialize = async () => {
|
||||
const audioInfo = await reloadDevices()
|
||||
setOutputAudioDeviceInfo(audioInfo)
|
||||
}
|
||||
initialize()
|
||||
}, [])
|
||||
|
||||
|
||||
const noiseControlRow = useMemo(() => {
|
||||
return (
|
||||
<div className="body-row split-3-2-2-2-1 left-padding-1 guided">
|
||||
<div className="body-item-title left-padding-1 ">Noise Suppression</div>
|
||||
<div>
|
||||
<input type="checkbox" checked={appState.clientSetting.clientSetting.echoCancel} onChange={(e) => {
|
||||
appState.clientSetting.updateClientSetting({ ...appState.clientSetting.clientSetting, echoCancel: e.target.checked })
|
||||
}} /> echo cancel
|
||||
</div>
|
||||
<div>
|
||||
<input type="checkbox" checked={appState.clientSetting.clientSetting.noiseSuppression} onChange={(e) => {
|
||||
appState.clientSetting.updateClientSetting({ ...appState.clientSetting.clientSetting, noiseSuppression: e.target.checked })
|
||||
}} /> suppression1
|
||||
</div>
|
||||
<div>
|
||||
<input type="checkbox" checked={appState.clientSetting.clientSetting.noiseSuppression2} onChange={(e) => {
|
||||
appState.clientSetting.updateClientSetting({ ...appState.clientSetting.clientSetting, noiseSuppression2: e.target.checked })
|
||||
}} /> suppression2
|
||||
</div>
|
||||
<div className="body-button-container">
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}, [
|
||||
appState.clientSetting.clientSetting.echoCancel,
|
||||
appState.clientSetting.clientSetting.noiseSuppression,
|
||||
appState.clientSetting.clientSetting.noiseSuppression2,
|
||||
appState.clientSetting.updateClientSetting
|
||||
])
|
||||
|
||||
const gainControlRow = useMemo(() => {
|
||||
return (
|
||||
<div className="body-row split-3-2-2-3 left-padding-1 guided">
|
||||
<div className="body-item-title left-padding-1 ">Gain Control</div>
|
||||
<div>
|
||||
<span className="body-item-input-slider-label">in</span>
|
||||
<input type="range" className="body-item-input-slider" min="0.0" max="1.0" step="0.1" value={appState.clientSetting.clientSetting.inputGain} onChange={(e) => {
|
||||
appState.clientSetting.updateClientSetting({ ...appState.clientSetting.clientSetting, inputGain: Number(e.target.value) })
|
||||
}}></input>
|
||||
<span className="body-item-input-slider-val">{appState.clientSetting.clientSetting.inputGain}</span>
|
||||
</div>
|
||||
<div>
|
||||
<span className="body-item-input-slider-label">out</span>
|
||||
<input type="range" className="body-item-input-slider" min="0.0" max="1.0" step="0.1" value={appState.clientSetting.clientSetting.outputGain} onChange={(e) => {
|
||||
appState.clientSetting.updateClientSetting({ ...appState.clientSetting.clientSetting, outputGain: Number(e.target.value) })
|
||||
}}></input>
|
||||
<span className="body-item-input-slider-val">{appState.clientSetting.clientSetting.outputGain}</span>
|
||||
</div>
|
||||
<div className="body-button-container">
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}, [
|
||||
appState.clientSetting.clientSetting.inputGain,
|
||||
appState.clientSetting.clientSetting.outputGain,
|
||||
appState.clientSetting.updateClientSetting
|
||||
])
|
||||
|
||||
// const f0DetectorRow = useMemo(() => {
|
||||
// const desc = { "harvest": "High Quality", "dio": "Light Weight" }
|
||||
// return (
|
||||
// <div className="body-row split-3-7 left-padding-1 guided">
|
||||
// <div className="body-item-title left-padding-1 ">F0 Detector</div>
|
||||
// <div className="body-select-container">
|
||||
// <select className="body-select" value={appState.serverSetting.serverSetting.f0Detector} onChange={(e) => {
|
||||
// appState.serverSetting.updateServerSettings({ ...appState.serverSetting.serverSetting, f0Detector: e.target.value as F0Detector })
|
||||
// }}>
|
||||
// {
|
||||
// Object.values(F0Detector).map(x => {
|
||||
// //@ts-ignore
|
||||
// return <option key={x} value={x}>{x}({desc[x]})</option>
|
||||
// })
|
||||
// }
|
||||
// </select>
|
||||
// </div>
|
||||
// </div>
|
||||
// )
|
||||
// }, [appState.serverSetting.serverSetting.f0Detector, appState.serverSetting.updateServerSettings])
|
||||
|
||||
|
||||
const recordIORow = useMemo(() => {
|
||||
const onRecordStartClicked = async () => {
|
||||
setRecording(true)
|
||||
await appState.serverSetting.updateServerSettings({ ...appState.serverSetting.serverSetting, recordIO: 1 })
|
||||
}
|
||||
const onRecordStopClicked = async () => {
|
||||
setRecording(false)
|
||||
await appState.serverSetting.updateServerSettings({ ...appState.serverSetting.serverSetting, recordIO: 0 })
|
||||
|
||||
// set wav (input)
|
||||
const wavInput = document.getElementById("body-wav-container-wav-input") as HTMLAudioElement
|
||||
wavInput.src = "/tmp/in.wav?" + new Date().getTime()
|
||||
wavInput.controls = true
|
||||
// @ts-ignore
|
||||
wavInput.setSinkId(audioOutputForGUI)
|
||||
|
||||
// set wav (output)
|
||||
const wavOutput = document.getElementById("body-wav-container-wav-output") as HTMLAudioElement
|
||||
wavOutput.src = "/tmp/out.wav?" + new Date().getTime()
|
||||
wavOutput.controls = true
|
||||
// @ts-ignore
|
||||
wavOutput.setSinkId(audioOutputForGUI)
|
||||
}
|
||||
const onRecordAnalizeClicked = async () => {
|
||||
if (appState.frontendManagerState.isConverting) {
|
||||
alert("please stop voice conversion. 解析処理と音声変換を同時に行うことはできません。音声変化をストップしてください。")
|
||||
return
|
||||
}
|
||||
appState.frontendManagerState.setIsAnalyzing(true)
|
||||
await appState.serverSetting.updateServerSettings({ ...appState.serverSetting.serverSetting, recordIO: 2 })
|
||||
// set spectrogram (dio)
|
||||
const imageDio = document.getElementById("body-image-container-img-dio") as HTMLImageElement
|
||||
imageDio.src = "/tmp/analyze-dio.png?" + new Date().getTime()
|
||||
imageDio.style.width = "100%"
|
||||
|
||||
// set spectrogram (harvest)
|
||||
const imageHarvest = document.getElementById("body-image-container-img-harvest") as HTMLImageElement
|
||||
imageHarvest.src = "/tmp/analyze-harvest.png?" + new Date().getTime()
|
||||
imageHarvest.style.width = "100%"
|
||||
|
||||
appState.frontendManagerState.setIsAnalyzing(false)
|
||||
}
|
||||
|
||||
const startClassName = recording ? "body-button-active" : "body-button-stanby"
|
||||
const stopClassName = recording ? "body-button-stanby" : "body-button-active"
|
||||
const analyzeClassName = appState.frontendManagerState.isAnalyzing ? "body-button-active" : "body-button-stanby"
|
||||
const analyzeLabel = appState.frontendManagerState.isAnalyzing ? "wait..." : "Analyze"
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="body-row split-3-7 left-padding-1 guided">
|
||||
<div className="body-item-title left-padding-1 ">Analyzer(Experimental)</div>
|
||||
<div className="body-button-container">
|
||||
</div>
|
||||
</div>
|
||||
<div className="body-row split-3-7 left-padding-1 guided">
|
||||
<div className="body-item-title left-padding-2 ">
|
||||
Sampling
|
||||
</div>
|
||||
<div className="body-button-container">
|
||||
<div onClick={onRecordStartClicked} className={startClassName}>Start</div>
|
||||
<div onClick={onRecordStopClicked} className={stopClassName}>Stop</div>
|
||||
{/* <div onClick={onRecordAnalizeClicked} className={analyzeClassName}>{analyzeLabel}</div> */}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="body-row split-3-2-2-3 left-padding-1 guided">
|
||||
<div className="body-item-title left-padding-2 ">
|
||||
<div>
|
||||
Play
|
||||
</div>
|
||||
<select className="body-select-50 left-margin-2" value={audioOutputForGUI} onChange={(e) => {
|
||||
setAudioOutputForGUI(e.target.value)
|
||||
const wavInput = document.getElementById("body-wav-container-wav-input") as HTMLAudioElement
|
||||
const wavOutput = document.getElementById("body-wav-container-wav-output") as HTMLAudioElement
|
||||
//@ts-ignore
|
||||
wavInput.setSinkId(e.target.value)
|
||||
//@ts-ignore
|
||||
wavOutput.setSinkId(e.target.value)
|
||||
}}>
|
||||
{
|
||||
outputAudioDeviceInfo.map(x => {
|
||||
return <option key={x.deviceId} value={x.deviceId}>{x.label}</option>
|
||||
})
|
||||
}
|
||||
</select>
|
||||
</div>
|
||||
{/* <div>
|
||||
<div className="body-wav-container">
|
||||
<div className="body-wav-container-title">Input</div>
|
||||
<div className="body-wav-container-title">Output</div>
|
||||
</div>
|
||||
<div className="body-wav-container">
|
||||
<div className="body-wav-container-wav">
|
||||
<audio src="" id="body-wav-container-wav-input"></audio>
|
||||
</div>
|
||||
<div className="body-wav-container-wav" >
|
||||
<audio src="" id="body-wav-container-wav-output"></audio>
|
||||
</div>
|
||||
</div>
|
||||
</div> */}
|
||||
<div>
|
||||
<div className="body-wav-container-title">Input</div>
|
||||
<div className="body-wav-container-wav">
|
||||
<audio src="" id="body-wav-container-wav-input"></audio>
|
||||
</div>
|
||||
</div>
|
||||
<div >
|
||||
<div className="body-wav-container-title">Output</div>
|
||||
<div className="body-wav-container-wav" >
|
||||
<audio src="" id="body-wav-container-wav-output"></audio>
|
||||
</div>
|
||||
</div>
|
||||
<div></div>
|
||||
</div>
|
||||
|
||||
{/* <div className="body-row split-3-7 left-padding-1 guided">
|
||||
<div className="body-item-title left-padding-2 ">
|
||||
Spectrogram
|
||||
</div>
|
||||
<div>
|
||||
<div className="body-image-container">
|
||||
<div className="body-image-container-title">PyWorld Dio</div>
|
||||
<div className="body-image-container-title">PyWorld Harvest</div>
|
||||
</div>
|
||||
<div className="body-image-container">
|
||||
<div className="body-image-container-img" >
|
||||
<img src="" alt="" id="body-image-container-img-dio" />
|
||||
</div>
|
||||
<div className="body-image-container-img">
|
||||
<img src="" alt="" id="body-image-container-img-harvest" />
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div> */}
|
||||
|
||||
</>
|
||||
)
|
||||
}, [appState.serverSetting.serverSetting.recordIO, appState.serverSetting.updateServerSettings, outputAudioDeviceInfo, audioOutputForGUI, appState.frontendManagerState.isAnalyzing, appState.frontendManagerState.isConverting])
|
||||
|
||||
const QualityControlContent = useMemo(() => {
|
||||
return (
|
||||
<>
|
||||
{noiseControlRow}
|
||||
{gainControlRow}
|
||||
<div className="body-row divider"></div>
|
||||
{recordIORow}
|
||||
</>
|
||||
)
|
||||
}, [gainControlRow, noiseControlRow, recordIORow])
|
||||
|
||||
|
||||
const qualityControl = useMemo(() => {
|
||||
return (
|
||||
<>
|
||||
{appState.frontendManagerState.stateControls.openQualityControlCheckbox.trigger}
|
||||
<div className="partition">
|
||||
<div className="partition-header">
|
||||
<span className="caret">
|
||||
{accodionButton}
|
||||
</span>
|
||||
<span className="title" onClick={() => { appState.frontendManagerState.stateControls.openQualityControlCheckbox.updateState(!appState.frontendManagerState.stateControls.openQualityControlCheckbox.checked()) }}>
|
||||
Quality Control
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div className="partition-content">
|
||||
{QualityControlContent}
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
)
|
||||
}, [QualityControlContent])
|
||||
|
||||
return {
|
||||
qualityControl,
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
@ -1,165 +0,0 @@
|
||||
import React, { useMemo, useState } from "react"
|
||||
import { useAppState } from "./001_provider/001_AppStateProvider";
|
||||
import { AnimationTypes, HeaderButton, HeaderButtonProps } from "./components/101_HeaderButton";
|
||||
|
||||
export const useSpeakerSetting = () => {
|
||||
const appState = useAppState()
|
||||
const [editSpeakerTargetId, setEditSpeakerTargetId] = useState<number>(0)
|
||||
const [editSpeakerTargetName, setEditSpeakerTargetName] = useState<string>("")
|
||||
|
||||
|
||||
const accodionButton = useMemo(() => {
|
||||
const accodionButtonProps: HeaderButtonProps = {
|
||||
stateControlCheckbox: appState.frontendManagerState.stateControls.openSpeakerSettingCheckbox,
|
||||
tooltip: "Open/Close",
|
||||
onIcon: ["fas", "caret-up"],
|
||||
offIcon: ["fas", "caret-up"],
|
||||
animation: AnimationTypes.spinner,
|
||||
tooltipClass: "tooltip-right",
|
||||
};
|
||||
return <HeaderButton {...accodionButtonProps}></HeaderButton>;
|
||||
}, []);
|
||||
|
||||
|
||||
// const calcDefaultF0Factor = (srcId: number, dstId: number) => {
|
||||
// const src = appState.clientSetting.clientSetting.correspondences?.find(x => {
|
||||
// return x.sid == srcId
|
||||
// })
|
||||
// const dst = appState.clientSetting.clientSetting.correspondences?.find(x => {
|
||||
// return x.sid == dstId
|
||||
// })
|
||||
// const recommendedF0Factor = dst && src ? dst.correspondence / src.correspondence : 0
|
||||
// return recommendedF0Factor
|
||||
// }
|
||||
// useEffect(() => {
|
||||
// const recF0 = calcDefaultF0Factor(appState.serverSetting.serverSetting.srcId, appState.serverSetting.serverSetting.dstId)
|
||||
// appState.serverSetting.updateServerSettings({ ...appState.serverSetting.serverSetting, f0Factor: recF0 })
|
||||
// }, [appState.clientSetting.clientSetting.correspondences])
|
||||
|
||||
|
||||
const srcIdRow = useMemo(() => {
|
||||
return (
|
||||
<div className="body-row split-3-2-1-4 left-padding-1 guided">
|
||||
<div className="body-item-title left-padding-1">Source Speaker Id</div>
|
||||
<div className="body-select-container">
|
||||
<select className="body-select" value={appState.serverSetting.serverSetting.srcId} onChange={(e) => {
|
||||
appState.serverSetting.updateServerSettings({ ...appState.serverSetting.serverSetting, srcId: Number(e.target.value) })
|
||||
}}>
|
||||
{
|
||||
appState.clientSetting.clientSetting.speakers.map(x => {
|
||||
return <option key={x.id} value={x.id}>{x.name}({x.id})</option>
|
||||
})
|
||||
|
||||
}
|
||||
</select>
|
||||
</div>
|
||||
<div className="body-item-text">
|
||||
</div>
|
||||
<div className="body-item-text"></div>
|
||||
</div>
|
||||
)
|
||||
}, [appState.serverSetting.serverSetting.srcId, appState.serverSetting.serverSetting.dstId, appState.clientSetting.clientSetting.speakers, appState.serverSetting.updateServerSettings])
|
||||
|
||||
const dstIdRow = useMemo(() => {
|
||||
return (
|
||||
<div className="body-row split-3-2-1-4 left-padding-1 guided">
|
||||
<div className="body-item-title left-padding-1">Destination Speaker Id</div>
|
||||
<div className="body-select-container">
|
||||
<select className="body-select" value={appState.serverSetting.serverSetting.dstId} onChange={(e) => {
|
||||
appState.serverSetting.updateServerSettings({ ...appState.serverSetting.serverSetting, dstId: Number(e.target.value) })
|
||||
|
||||
}}>
|
||||
{
|
||||
appState.clientSetting.clientSetting.speakers?.map(x => {
|
||||
return <option key={x.id} value={x.id}>{x.name}({x.id})</option>
|
||||
})
|
||||
}
|
||||
</select>
|
||||
</div>
|
||||
<div className="body-item-text">
|
||||
</div>
|
||||
<div className="body-item-text"></div>
|
||||
</div>
|
||||
)
|
||||
}, [appState.serverSetting.serverSetting.srcId, appState.serverSetting.serverSetting.dstId, appState.clientSetting.clientSetting.speakers, appState.serverSetting.updateServerSettings])
|
||||
|
||||
const editSpeakerIdMappingRow = useMemo(() => {
|
||||
const onSetSpeakerMappingClicked = async () => {
|
||||
const targetId = editSpeakerTargetId
|
||||
const targetName = editSpeakerTargetName
|
||||
const targetSpeaker = appState.clientSetting.clientSetting.speakers.find(x => { return x.id == targetId })
|
||||
if (targetSpeaker) {
|
||||
if (targetName.length == 0) { // Delete
|
||||
const newSpeakers = appState.clientSetting.clientSetting.speakers.filter(x => { return x.id != targetId })
|
||||
appState.clientSetting.updateClientSetting({ ...appState.clientSetting.clientSetting, speakers: newSpeakers })
|
||||
} else { // Update
|
||||
targetSpeaker.name = targetName
|
||||
appState.clientSetting.updateClientSetting({ ...appState.clientSetting.clientSetting, speakers: [...appState.clientSetting.clientSetting.speakers] })
|
||||
}
|
||||
} else {
|
||||
if (targetName.length == 0) { // Noop
|
||||
} else {// add
|
||||
appState.clientSetting.clientSetting.speakers.push({
|
||||
id: targetId,
|
||||
name: targetName
|
||||
})
|
||||
appState.clientSetting.updateClientSetting({ ...appState.clientSetting.clientSetting, speakers: [...appState.clientSetting.clientSetting.speakers] })
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
return (
|
||||
<div className="body-row split-3-1-2-4 left-padding-1 guided">
|
||||
<div className="body-item-title left-padding-1">Edit Speaker Mapping</div>
|
||||
<div className="body-input-container">
|
||||
<input type="number" min={1} max={256} step={1} value={editSpeakerTargetId} onChange={(e) => {
|
||||
const id = Number(e.target.value)
|
||||
setEditSpeakerTargetId(id)
|
||||
setEditSpeakerTargetName(appState.clientSetting.clientSetting.speakers.find(x => { return x.id == id })?.name || "")
|
||||
}} />
|
||||
</div>
|
||||
<div className="body-input-container">
|
||||
<input type="text" value={editSpeakerTargetName} onChange={(e) => {
|
||||
setEditSpeakerTargetName(e.target.value)
|
||||
}} />
|
||||
</div>
|
||||
<div className="body-button-container">
|
||||
<div className="body-button" onClick={onSetSpeakerMappingClicked}>set</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}, [appState.clientSetting.clientSetting.speakers, editSpeakerTargetId, editSpeakerTargetName])
|
||||
|
||||
|
||||
|
||||
const speakerSetting = useMemo(() => {
|
||||
return (
|
||||
<>
|
||||
{appState.frontendManagerState.stateControls.openSpeakerSettingCheckbox.trigger}
|
||||
<div className="partition">
|
||||
<div className="partition-header">
|
||||
<span className="caret">
|
||||
{accodionButton}
|
||||
</span>
|
||||
<span className="title" onClick={() => { appState.frontendManagerState.stateControls.openSpeakerSettingCheckbox.updateState(!appState.frontendManagerState.stateControls.openSpeakerSettingCheckbox.checked()) }}>
|
||||
Speaker Setting
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div className="partition-content">
|
||||
{srcIdRow}
|
||||
{dstIdRow}
|
||||
{editSpeakerIdMappingRow}
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
)
|
||||
}, [srcIdRow, dstIdRow, editSpeakerIdMappingRow])
|
||||
|
||||
return {
|
||||
speakerSetting,
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
@ -1,85 +0,0 @@
|
||||
import React, { useMemo } from "react"
|
||||
import { useAppState } from "./001_provider/001_AppStateProvider";
|
||||
import { AnimationTypes, HeaderButton, HeaderButtonProps } from "./components/101_HeaderButton";
|
||||
|
||||
|
||||
export type ConvertSettingState = {
|
||||
convertSetting: JSX.Element;
|
||||
}
|
||||
|
||||
export const useConvertSetting = (): ConvertSettingState => {
|
||||
const appState = useAppState()
|
||||
const accodionButton = useMemo(() => {
|
||||
const accodionButtonProps: HeaderButtonProps = {
|
||||
stateControlCheckbox: appState.frontendManagerState.stateControls.openConverterSettingCheckbox,
|
||||
tooltip: "Open/Close",
|
||||
onIcon: ["fas", "caret-up"],
|
||||
offIcon: ["fas", "caret-up"],
|
||||
animation: AnimationTypes.spinner,
|
||||
tooltipClass: "tooltip-right",
|
||||
};
|
||||
return <HeaderButton {...accodionButtonProps}></HeaderButton>;
|
||||
}, []);
|
||||
const inputChunkNumRow = useMemo(() => {
|
||||
return (
|
||||
<div className="body-row split-3-2-1-4 left-padding-1 guided">
|
||||
<div className="body-item-title left-padding-1">Input Chunk Num(128sample/chunk)</div>
|
||||
<div className="body-input-container">
|
||||
<input type="number" min={1} max={256} step={1} value={appState.workletNodeSetting.workletNodeSetting.inputChunkNum} onChange={(e) => {
|
||||
appState.workletNodeSetting.updateWorkletNodeSetting({ ...appState.workletNodeSetting.workletNodeSetting, inputChunkNum: Number(e.target.value) })
|
||||
appState.workletNodeSetting.trancateBuffer()
|
||||
}} />
|
||||
</div>
|
||||
<div className="body-item-text">
|
||||
<div>buff: {(appState.workletNodeSetting.workletNodeSetting.inputChunkNum * 128 * 1000 / 48000).toFixed(1)}ms</div>
|
||||
</div>
|
||||
<div className="body-item-text"></div>
|
||||
|
||||
</div>
|
||||
)
|
||||
}, [appState.workletNodeSetting.workletNodeSetting.inputChunkNum, appState.workletNodeSetting.updateWorkletNodeSetting])
|
||||
|
||||
const gpuRow = useMemo(() => {
|
||||
return (
|
||||
<div className="body-row split-3-7 left-padding-1 guided">
|
||||
<div className="body-item-title left-padding-1">GPU</div>
|
||||
<div className="body-input-container">
|
||||
<input type="number" min={-2} max={5} step={1} value={appState.serverSetting.serverSetting.gpu} onChange={(e) => {
|
||||
appState.serverSetting.updateServerSettings({ ...appState.serverSetting.serverSetting, gpu: Number(e.target.value) })
|
||||
}} />
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}, [appState.serverSetting.serverSetting.gpu, appState.serverSetting.updateServerSettings])
|
||||
|
||||
|
||||
const convertSetting = useMemo(() => {
|
||||
return (
|
||||
<>
|
||||
{appState.frontendManagerState.stateControls.openConverterSettingCheckbox.trigger}
|
||||
<div className="partition">
|
||||
<div className="partition-header">
|
||||
<span className="caret">
|
||||
{accodionButton}
|
||||
</span>
|
||||
<span className="title" onClick={() => { appState.frontendManagerState.stateControls.openConverterSettingCheckbox.updateState(!appState.frontendManagerState.stateControls.openConverterSettingCheckbox.checked()) }}>
|
||||
Converter Setting
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div className="partition-content">
|
||||
{inputChunkNumRow}
|
||||
{gpuRow}
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
)
|
||||
}, [inputChunkNumRow, gpuRow])
|
||||
|
||||
return {
|
||||
convertSetting,
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
@ -1,266 +0,0 @@
|
||||
import { CrossFadeOverlapSize, DownSamplingMode, InputSampleRate, Protocol, SampleRate } from "@dannadori/voice-changer-client-js"
|
||||
import React, { useMemo } from "react"
|
||||
import { useAppState } from "./001_provider/001_AppStateProvider";
|
||||
import { AnimationTypes, HeaderButton, HeaderButtonProps } from "./components/101_HeaderButton";
|
||||
|
||||
export type AdvancedSettingState = {
|
||||
advancedSetting: JSX.Element;
|
||||
}
|
||||
|
||||
export const useAdvancedSetting = (): AdvancedSettingState => {
|
||||
const appState = useAppState()
|
||||
const accodionButton = useMemo(() => {
|
||||
const accodionButtonProps: HeaderButtonProps = {
|
||||
stateControlCheckbox: appState.frontendManagerState.stateControls.openAdvancedSettingCheckbox,
|
||||
tooltip: "Open/Close",
|
||||
onIcon: ["fas", "caret-up"],
|
||||
offIcon: ["fas", "caret-up"],
|
||||
animation: AnimationTypes.spinner,
|
||||
tooltipClass: "tooltip-right",
|
||||
};
|
||||
return <HeaderButton {...accodionButtonProps}></HeaderButton>;
|
||||
}, []);
|
||||
|
||||
const mmvcServerUrlRow = useMemo(() => {
|
||||
const onSetServerClicked = async () => {
|
||||
const input = document.getElementById("mmvc-server-url") as HTMLInputElement
|
||||
appState.clientSetting.setServerUrl(input.value)
|
||||
}
|
||||
return (
|
||||
<div className="body-row split-3-3-4 left-padding-1 guided">
|
||||
<div className="body-item-title left-padding-1">MMVC Server</div>
|
||||
<div className="body-input-container">
|
||||
<input type="text" defaultValue={appState.workletNodeSetting.workletNodeSetting.serverUrl} id="mmvc-server-url" className="body-item-input" />
|
||||
</div>
|
||||
<div className="body-button-container">
|
||||
<div className="body-button" onClick={onSetServerClicked}>set</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}, [appState.workletNodeSetting.workletNodeSetting.serverUrl, appState.clientSetting.setServerUrl])
|
||||
|
||||
const protocolRow = useMemo(() => {
|
||||
const onProtocolChanged = async (val: Protocol) => {
|
||||
appState.workletNodeSetting.updateWorkletNodeSetting({ ...appState.workletNodeSetting.workletNodeSetting, protocol: val })
|
||||
}
|
||||
return (
|
||||
<div className="body-row split-3-7 left-padding-1 guided">
|
||||
<div className="body-item-title left-padding-1">Protocol</div>
|
||||
<div className="body-select-container">
|
||||
<select className="body-select" value={appState.workletNodeSetting.workletNodeSetting.protocol} onChange={(e) => {
|
||||
onProtocolChanged(e.target.value as
|
||||
Protocol)
|
||||
}}>
|
||||
{
|
||||
Object.values(Protocol).map(x => {
|
||||
return <option key={x} value={x}>{x}</option>
|
||||
})
|
||||
}
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}, [appState.workletNodeSetting.workletNodeSetting.protocol, appState.workletNodeSetting.updateWorkletNodeSetting])
|
||||
|
||||
|
||||
const sampleRateRow = useMemo(() => {
|
||||
return (
|
||||
<div className="body-row split-3-7 left-padding-1 guided">
|
||||
<div className="body-item-title left-padding-1">Sample Rate</div>
|
||||
<div className="body-select-container">
|
||||
<select className="body-select" value={appState.clientSetting.clientSetting.sampleRate} onChange={(e) => {
|
||||
appState.clientSetting.updateClientSetting({ ...appState.clientSetting.clientSetting, sampleRate: Number(e.target.value) as SampleRate })
|
||||
}}>
|
||||
{
|
||||
Object.values(SampleRate).map(x => {
|
||||
return <option key={x} value={x}>{x}</option>
|
||||
})
|
||||
}
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}, [appState.clientSetting.clientSetting.sampleRate, appState.clientSetting.updateClientSetting])
|
||||
|
||||
const sendingSampleRateRow = useMemo(() => {
|
||||
return (
|
||||
<div className="body-row split-3-7 left-padding-1 guided">
|
||||
<div className="body-item-title left-padding-1">Sending Sample Rate</div>
|
||||
<div className="body-select-container">
|
||||
<select className="body-select" value={appState.workletNodeSetting.workletNodeSetting.sendingSampleRate} onChange={(e) => {
|
||||
appState.workletNodeSetting.updateWorkletNodeSetting({ ...appState.workletNodeSetting.workletNodeSetting, sendingSampleRate: Number(e.target.value) as InputSampleRate })
|
||||
appState.serverSetting.updateServerSettings({ ...appState.serverSetting.serverSetting, inputSampleRate: Number(e.target.value) as InputSampleRate })
|
||||
}}>
|
||||
{
|
||||
Object.values(InputSampleRate).map(x => {
|
||||
return <option key={x} value={x}>{x}</option>
|
||||
})
|
||||
}
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}, [appState.workletNodeSetting.workletNodeSetting.sendingSampleRate, appState.workletNodeSetting.updateWorkletNodeSetting, appState.serverSetting.updateServerSettings])
|
||||
|
||||
const crossFadeOverlapSizeRow = useMemo(() => {
|
||||
return (
|
||||
<div className="body-row split-3-7 left-padding-1 guided">
|
||||
<div className="body-item-title left-padding-1">Cross Fade Overlap Size</div>
|
||||
<div className="body-select-container">
|
||||
<select className="body-select" value={appState.serverSetting.serverSetting.crossFadeOverlapSize} onChange={(e) => {
|
||||
appState.serverSetting.updateServerSettings({ ...appState.serverSetting.serverSetting, crossFadeOverlapSize: Number(e.target.value) as CrossFadeOverlapSize })
|
||||
}}>
|
||||
{
|
||||
Object.values(CrossFadeOverlapSize).map(x => {
|
||||
return <option key={x} value={x}>{x}</option>
|
||||
})
|
||||
}
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}, [appState.serverSetting.serverSetting.crossFadeOverlapSize, appState.serverSetting.updateServerSettings])
|
||||
|
||||
const crossFadeOffsetRateRow = useMemo(() => {
|
||||
return (
|
||||
<div className="body-row split-3-7 left-padding-1 guided">
|
||||
<div className="body-item-title left-padding-1">Cross Fade Offset Rate</div>
|
||||
<div className="body-input-container">
|
||||
<input type="number" min={0} max={1} step={0.1} value={appState.serverSetting.serverSetting.crossFadeOffsetRate} onChange={(e) => {
|
||||
appState.serverSetting.updateServerSettings({ ...appState.serverSetting.serverSetting, crossFadeOffsetRate: Number(e.target.value) })
|
||||
}} />
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}, [appState.serverSetting.serverSetting.crossFadeOffsetRate, appState.serverSetting.updateServerSettings])
|
||||
|
||||
const crossFadeEndRateRow = useMemo(() => {
|
||||
return (
|
||||
<div className="body-row split-3-7 left-padding-1 guided">
|
||||
<div className="body-item-title left-padding-1">Cross Fade End Rate</div>
|
||||
<div className="body-input-container">
|
||||
<input type="number" min={0} max={1} step={0.1} value={appState.serverSetting.serverSetting.crossFadeEndRate} onChange={(e) => {
|
||||
appState.serverSetting.updateServerSettings({ ...appState.serverSetting.serverSetting, crossFadeEndRate: Number(e.target.value) })
|
||||
}} />
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}, [appState.serverSetting.serverSetting.crossFadeEndRate, appState.serverSetting.updateServerSettings])
|
||||
|
||||
|
||||
const downSamplingModeRow = useMemo(() => {
|
||||
return (
|
||||
<div className="body-row split-3-7 left-padding-1 guided">
|
||||
<div className="body-item-title left-padding-1 ">DownSamplingMode</div>
|
||||
<div className="body-select-container">
|
||||
<select className="body-select" value={appState.workletNodeSetting.workletNodeSetting.downSamplingMode} onChange={(e) => {
|
||||
appState.workletNodeSetting.updateWorkletNodeSetting({ ...appState.workletNodeSetting.workletNodeSetting, downSamplingMode: e.target.value as DownSamplingMode })
|
||||
}}>
|
||||
{
|
||||
Object.values(DownSamplingMode).map(x => {
|
||||
return <option key={x} value={x}>{x}</option>
|
||||
})
|
||||
}
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}, [appState.workletNodeSetting.workletNodeSetting.downSamplingMode, appState.workletNodeSetting.updateWorkletNodeSetting])
|
||||
|
||||
|
||||
const workletSettingRow = useMemo(() => {
|
||||
return (
|
||||
<>
|
||||
|
||||
<div className="body-row split-3-7 left-padding-1 guided">
|
||||
<div className="body-item-title left-padding-1">Trancate Num</div>
|
||||
<div className="body-input-container">
|
||||
<input type="number" min={5} max={300} step={1} value={appState.workletSetting.setting.numTrancateTreshold} onChange={(e) => {
|
||||
appState.workletSetting.setSetting({
|
||||
...appState.workletSetting.setting,
|
||||
numTrancateTreshold: Number(e.target.value)
|
||||
})
|
||||
}} />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* v.1.5.xより Silent skipは廃止 */}
|
||||
{/* <div className="body-row split-3-7 left-padding-1 guided">
|
||||
<div className="body-item-title left-padding-1">Trancate Vol</div>
|
||||
<div className="body-input-container">
|
||||
<input type="number" min={0.0001} max={0.0009} step={0.0001} value={appState.workletSetting.setting.volTrancateThreshold} onChange={(e) => {
|
||||
appState.workletSetting.setSetting({
|
||||
...appState.workletSetting.setting,
|
||||
volTrancateThreshold: Number(e.target.value)
|
||||
})
|
||||
}} />
|
||||
</div>
|
||||
</div>
|
||||
<div className="body-row split-3-7 left-padding-1 guided">
|
||||
<div className="body-item-title left-padding-1">Trancate Vol Length</div>
|
||||
<div className="body-input-container">
|
||||
<input type="number" min={16} max={128} step={1} value={appState.workletSetting.setting.volTrancateLength} onChange={(e) => {
|
||||
appState.workletSetting.setSetting({
|
||||
...appState.workletSetting.setting,
|
||||
volTrancateLength: Number(e.target.value)
|
||||
})
|
||||
}} />
|
||||
</div>
|
||||
</div> */}
|
||||
</>
|
||||
)
|
||||
}, [appState.workletSetting.setting, appState.workletSetting.setSetting])
|
||||
|
||||
|
||||
const advanceSettingContent = useMemo(() => {
|
||||
return (
|
||||
<>
|
||||
<div className="body-row divider"></div>
|
||||
{mmvcServerUrlRow}
|
||||
{protocolRow}
|
||||
<div className="body-row divider"></div>
|
||||
{sampleRateRow}
|
||||
{sendingSampleRateRow}
|
||||
<div className="body-row divider"></div>
|
||||
{crossFadeOverlapSizeRow}
|
||||
{crossFadeOffsetRateRow}
|
||||
{crossFadeEndRateRow}
|
||||
<div className="body-row divider"></div>
|
||||
{workletSettingRow}
|
||||
<div className="body-row divider"></div>
|
||||
{downSamplingModeRow}
|
||||
|
||||
</>
|
||||
)
|
||||
}, [mmvcServerUrlRow, protocolRow, sampleRateRow, sendingSampleRateRow, crossFadeOverlapSizeRow, crossFadeOffsetRateRow, crossFadeEndRateRow, workletSettingRow, downSamplingModeRow])
|
||||
|
||||
|
||||
const advancedSetting = useMemo(() => {
|
||||
return (
|
||||
<>
|
||||
{appState.frontendManagerState.stateControls.openAdvancedSettingCheckbox.trigger}
|
||||
<div className="partition">
|
||||
<div className="partition-header">
|
||||
<span className="caret">
|
||||
{accodionButton}
|
||||
</span>
|
||||
<span className="title" onClick={() => { appState.frontendManagerState.stateControls.openAdvancedSettingCheckbox.updateState(!appState.frontendManagerState.stateControls.openAdvancedSettingCheckbox.checked()) }}>
|
||||
Advanced Setting
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div className="partition-content">
|
||||
{advanceSettingContent}
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
)
|
||||
}, [advanceSettingContent])
|
||||
|
||||
return {
|
||||
advancedSetting,
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
99
client/demo/src/components/demo/002_ComponentGenerator.tsx
Normal file
99
client/demo/src/components/demo/002_ComponentGenerator.tsx
Normal file
@ -0,0 +1,99 @@
|
||||
import React from "react"
|
||||
import { ClearSettingRow, ClearSettingRowProps } from "./components/102_ClearSettingRow"
|
||||
import { Title, TitleProps } from "./components/101_Title"
|
||||
import { StartButtonRow, StartButtonRowProps } from "./components/201_StartButtonRow"
|
||||
import { PerformanceRow, PerformanceRowProps } from "./components/202_PerformanceRow"
|
||||
import { ServerInfoRow, ServerInfoRowProps } from "./components/203_ServerInfoRow"
|
||||
import { ModelUploaderRow, ModelUploaderRowProps } from "./components/301_ModelUploaderRow"
|
||||
import { FrameworkRow, FrameworkRowProps } from "./components/302_FrameworkRow"
|
||||
import { AudioInputRow, AudioInputRowProps } from "./components/401_AudioInputRow"
|
||||
import { AudioOutputRow, AudioOutputRowProps } from "./components/402_AudioOutputRow"
|
||||
import { GainControlRow, GainControlRowProps } from "./components/502_GainControlRow"
|
||||
import { NoiseControlRow, NoiseControlRowProps } from "./components/501_NoiseControlRow"
|
||||
import { F0DetectorRow, F0DetectorRowProps } from "./components/503_F0DetectorRow"
|
||||
import { DividerRow, DividerRowProps } from "./components/990_DividerRow"
|
||||
import { AnalyzerRow, AnalyzerRowProps } from "./components/510_AnalyzerRow"
|
||||
import { SrcIdRow, SrcIdRowProps } from "./components/601_SrcIdRow"
|
||||
import { DstIdRow, DstIdRowProps } from "./components/602_DstIdRow"
|
||||
import { EditSpeakerIdMappingRow, EditSpeakerIdMappingRowProps } from "./components/603_EditSpeakerIdMappingRow"
|
||||
import { F0FactorRow, F0FactorRowProps } from "./components/604_F0FactorRow"
|
||||
import { TuneRow, TuneRowProps } from "./components/605_TuneRow"
|
||||
import { ClusterInferRatioRow, ClusterInferRatioRowProps } from "./components/606_ClusterInferRatioRow"
|
||||
import { NoiseScaleRow, NoiseScaleRowProps } from "./components/607_NoiseScaleRow"
|
||||
import { SilentThresholdRow, SilentThresholdRowProps } from "./components/608_SilentThresholdRow"
|
||||
import { InputChunkNumRow, InputChunkNumRowProps } from "./components/701_InputChunkNumRow"
|
||||
import { ExtraDataLengthRow, ExtraDataLengthRowProps } from "./components/702_ExtraDataLengthRow"
|
||||
import { GPURow, GPURowProps } from "./components/703_GPURow"
|
||||
import { ServerURLRow, ServerURLRowProps } from "./components/801_ServerURLRow"
|
||||
import { ProtocolRow, ProtocolRowProps } from "./components/802_ProtocolRow"
|
||||
import { SampleRateRow, SampleRateRowProps } from "./components/803_SampleRateRow"
|
||||
import { SendingSampleRateRow, SendingSampleRateRowProps } from "./components/804_SendingSampleRateRow"
|
||||
import { CrossFadeOverlapSizeRow, CrossFadeOverlapSizeRowProps } from "./components/805_CrossFadeOverlapSizeRow"
|
||||
import { CrossFadeOffsetRateRow, CrossFadeOffsetRateRowProps } from "./components/806_CrossFadeOffsetRateRow"
|
||||
import { CrossFadeEndRateRow, CrossFadeEndRateRowProps } from "./components/807_CrossFadeEndRateRow"
|
||||
import { DownSamplingModeRow, DownSamplingModeRowProps } from "./components/808_DownSamplingModeRow"
|
||||
import { TrancateNumTresholdRow, TrancateNumTresholdRowProps } from "./components/809_TrancateNumTresholdRow"
|
||||
|
||||
export const catalog: { [key: string]: (props: any) => JSX.Element } = {}
|
||||
|
||||
export const addToCatalog = (key: string, generator: (props: any) => JSX.Element) => {
|
||||
catalog[key] = generator
|
||||
}
|
||||
|
||||
export const generateComponent = (key: string, props: any) => {
|
||||
if (!catalog[key]) {
|
||||
console.error("not found component generator.", key)
|
||||
return <></>
|
||||
}
|
||||
return catalog[key](props)
|
||||
}
|
||||
|
||||
const initialize = () => {
|
||||
addToCatalog("divider", (props: DividerRowProps) => { return <DividerRow {...props} /> })
|
||||
|
||||
addToCatalog("title", (props: TitleProps) => { return <Title {...props} /> })
|
||||
addToCatalog("clearSetting", (props: ClearSettingRowProps) => { return <ClearSettingRow {...props} /> })
|
||||
|
||||
addToCatalog("startButton", (props: StartButtonRowProps) => { return <StartButtonRow {...props} /> })
|
||||
addToCatalog("performance", (props: PerformanceRowProps) => { return <PerformanceRow {...props} /> })
|
||||
addToCatalog("serverInfo", (props: ServerInfoRowProps) => { return <ServerInfoRow {...props} /> })
|
||||
|
||||
addToCatalog("modelUploader", (props: ModelUploaderRowProps) => { return <ModelUploaderRow {...props} /> })
|
||||
addToCatalog("framework", (props: FrameworkRowProps) => { return <FrameworkRow {...props} /> })
|
||||
|
||||
|
||||
addToCatalog("audioInput", (props: AudioInputRowProps) => { return <AudioInputRow {...props} /> })
|
||||
addToCatalog("audioOutput", (props: AudioOutputRowProps) => { return <AudioOutputRow {...props} /> })
|
||||
|
||||
addToCatalog("noiseControl", (props: NoiseControlRowProps) => { return <NoiseControlRow {...props} /> })
|
||||
addToCatalog("gainControl", (props: GainControlRowProps) => { return <GainControlRow {...props} /> })
|
||||
addToCatalog("f0Detector", (props: F0DetectorRowProps) => { return <F0DetectorRow {...props} /> })
|
||||
addToCatalog("analyzer", (props: AnalyzerRowProps) => { return <AnalyzerRow {...props} /> })
|
||||
|
||||
addToCatalog("srcId", (props: SrcIdRowProps) => { return <SrcIdRow {...props} /> })
|
||||
addToCatalog("dstId", (props: DstIdRowProps) => { return <DstIdRow {...props} /> })
|
||||
addToCatalog("editSpeakerIdMapping", (props: EditSpeakerIdMappingRowProps) => { return <EditSpeakerIdMappingRow {...props} /> })
|
||||
addToCatalog("f0Factor", (props: F0FactorRowProps) => { return <F0FactorRow {...props} /> })
|
||||
addToCatalog("tune", (props: TuneRowProps) => { return <TuneRow {...props} /> })
|
||||
addToCatalog("clusterInferRatio", (props: ClusterInferRatioRowProps) => { return <ClusterInferRatioRow {...props} /> })
|
||||
addToCatalog("noiseScale", (props: NoiseScaleRowProps) => { return <NoiseScaleRow {...props} /> })
|
||||
addToCatalog("silentThreshold", (props: SilentThresholdRowProps) => { return <SilentThresholdRow {...props} /> })
|
||||
|
||||
addToCatalog("inputChunkNum", (props: InputChunkNumRowProps) => { return <InputChunkNumRow {...props} /> })
|
||||
addToCatalog("extraDataLength", (props: ExtraDataLengthRowProps) => { return <ExtraDataLengthRow {...props} /> })
|
||||
addToCatalog("gpu", (props: GPURowProps) => { return < GPURow {...props} /> })
|
||||
|
||||
addToCatalog("serverURL", (props: ServerURLRowProps) => { return <ServerURLRow {...props} /> })
|
||||
addToCatalog("protocol", (props: ProtocolRowProps) => { return <ProtocolRow {...props} /> })
|
||||
addToCatalog("sampleRate", (props: SampleRateRowProps) => { return <SampleRateRow {...props} /> })
|
||||
addToCatalog("sendingSampleRate", (props: SendingSampleRateRowProps) => { return <SendingSampleRateRow {...props} /> })
|
||||
addToCatalog("crossFadeOverlapSize", (props: CrossFadeOverlapSizeRowProps) => { return <CrossFadeOverlapSizeRow {...props} /> })
|
||||
addToCatalog("crossFadeOffsetRate", (props: CrossFadeOffsetRateRowProps) => { return <CrossFadeOffsetRateRow {...props} /> })
|
||||
addToCatalog("crossFadeEndRate", (props: CrossFadeEndRateRowProps) => { return <CrossFadeEndRateRow {...props} /> })
|
||||
addToCatalog("downSamplingMode", (props: DownSamplingModeRowProps) => { return <DownSamplingModeRow {...props} /> })
|
||||
addToCatalog("trancateNumThreshold", (props: TrancateNumTresholdRowProps) => { return <TrancateNumTresholdRow {...props} /> })
|
||||
|
||||
|
||||
}
|
||||
|
||||
initialize()
|
@ -10,8 +10,6 @@ import { SpeakerSetting } from "./600_SpeakerSetting";
|
||||
import { ConverterSetting } from "./700_ConverterSetting";
|
||||
import { AdvancedSetting } from "./800_AdvancedSetting";
|
||||
|
||||
|
||||
|
||||
export const Demo = () => {
|
||||
return (
|
||||
<GuiStateProvider>
|
||||
@ -26,12 +24,6 @@ export const Demo = () => {
|
||||
<SpeakerSetting />
|
||||
<ConverterSetting />
|
||||
<AdvancedSetting />
|
||||
|
||||
{/* <audio hidden id={AUDIO_ELEMENT_FOR_PLAY_RESULT}></audio>
|
||||
|
||||
org:<audio id={AUDIO_ELEMENT_FOR_TEST_ORIGINAL} controls></audio>
|
||||
<audio id={AUDIO_ELEMENT_FOR_TEST_CONVERTED} controls></audio>
|
||||
<audio id={AUDIO_ELEMENT_FOR_TEST_CONVERTED_ECHOBACK} controls hidden></audio> */}
|
||||
</div>
|
||||
</GuiStateProvider>
|
||||
|
||||
|
@ -1,13 +1,19 @@
|
||||
import React, { useMemo } from "react"
|
||||
import { Title } from "./101_Title"
|
||||
import { ClearSettingRow } from "./102_ClearSettingRow"
|
||||
import { generateComponent } from "./002_ComponentGenerator"
|
||||
import { useAppRoot } from "../../001_provider/001_AppRootProvider"
|
||||
|
||||
export const TitleArea = () => {
|
||||
const { appGuiSettingState } = useAppRoot()
|
||||
const componentSettings = appGuiSettingState.appGuiSetting.front.title
|
||||
|
||||
const titleArea = useMemo(() => {
|
||||
const components = componentSettings.map((x, index) => {
|
||||
const c = generateComponent(x.name, x.options)
|
||||
return <div key={`${x.name}_${index}`}>{c}</div>
|
||||
})
|
||||
return (
|
||||
<>
|
||||
<Title />
|
||||
<ClearSettingRow />
|
||||
{components}
|
||||
</>
|
||||
)
|
||||
}, [])
|
||||
|
@ -1,12 +1,13 @@
|
||||
import React, { useMemo } from "react"
|
||||
import { useAppRoot } from "../../001_provider/001_AppRootProvider"
|
||||
import { AnimationTypes, HeaderButton, HeaderButtonProps } from "../101_HeaderButton"
|
||||
import { useGuiState } from "./001_GuiStateProvider"
|
||||
import { StartButtonRow } from "./201_StartButtonRow"
|
||||
import { PerformanceRow } from "./202_PerformanceRow"
|
||||
import { ServerInfoRow } from "./203_ServerInfoRow"
|
||||
import { generateComponent } from "./002_ComponentGenerator"
|
||||
|
||||
export const ServerControl = () => {
|
||||
const guiState = useGuiState()
|
||||
const { appGuiSettingState } = useAppRoot()
|
||||
const componentSettings = appGuiSettingState.appGuiSetting.front.serverControl
|
||||
|
||||
const accodionButton = useMemo(() => {
|
||||
const accodionButtonProps: HeaderButtonProps = {
|
||||
@ -20,7 +21,12 @@ export const ServerControl = () => {
|
||||
return <HeaderButton {...accodionButtonProps}></HeaderButton>;
|
||||
}, []);
|
||||
|
||||
|
||||
const serverControl = useMemo(() => {
|
||||
const components = componentSettings.map((x, index) => {
|
||||
const c = generateComponent(x.name, x.options)
|
||||
return <div key={`${x.name}_${index}`}>{c}</div>
|
||||
})
|
||||
return (
|
||||
<>
|
||||
{guiState.stateControls.openServerControlCheckbox.trigger}
|
||||
@ -35,9 +41,7 @@ export const ServerControl = () => {
|
||||
</div>
|
||||
|
||||
<div className="partition-content">
|
||||
<StartButtonRow />
|
||||
<PerformanceRow />
|
||||
<ServerInfoRow />
|
||||
{components}
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
|
@ -1,20 +1,14 @@
|
||||
import React, { useMemo } from "react"
|
||||
import { AnimationTypes, HeaderButton, HeaderButtonProps } from "../101_HeaderButton"
|
||||
import { useGuiState } from "./001_GuiStateProvider"
|
||||
import { ModelUploaderRow } from "./301_ModelUploaderRow"
|
||||
import { ConfigSelectRow } from "./302_ConfigSelectRow"
|
||||
import { ONNXSelectRow } from "./303_ONNXSelectRow"
|
||||
import { PyTorchSelectRow } from "./304_PyTorchSelectRow"
|
||||
import { CorrespondenceSelectRow } from "./305_CorrespondenceSelectRow"
|
||||
import { PyTorchClusterSelectRow } from "./306_PyTorchClusterSelectRow"
|
||||
import { ModelUploadButtonRow } from "./310_ModelUploadButtonRow"
|
||||
import { FrameworkRow } from "./320_FrameworkRow"
|
||||
import { ONNXExecutorRow } from "./321_ONNXExecutorRow"
|
||||
import { useAppRoot } from "../../001_provider/001_AppRootProvider"
|
||||
import { generateComponent } from "./002_ComponentGenerator"
|
||||
|
||||
|
||||
export const ModelSetting = () => {
|
||||
const guiState = useGuiState()
|
||||
|
||||
const { appGuiSettingState } = useAppRoot()
|
||||
const componentSettings = appGuiSettingState.appGuiSetting.front.modelSetting
|
||||
const accodionButton = useMemo(() => {
|
||||
const accodionButtonProps: HeaderButtonProps = {
|
||||
stateControlCheckbox: guiState.stateControls.openModelSettingCheckbox,
|
||||
@ -28,7 +22,10 @@ export const ModelSetting = () => {
|
||||
}, []);
|
||||
|
||||
const modelSetting = useMemo(() => {
|
||||
|
||||
const components = componentSettings.map((x, index) => {
|
||||
const c = generateComponent(x.name, x.options)
|
||||
return <div key={`${x.name}_${index}`}>{c}</div>
|
||||
})
|
||||
return (
|
||||
<>
|
||||
{guiState.stateControls.openModelSettingCheckbox.trigger}
|
||||
@ -44,15 +41,7 @@ export const ModelSetting = () => {
|
||||
</div>
|
||||
|
||||
<div className="partition-content">
|
||||
<ModelUploaderRow />
|
||||
<ConfigSelectRow />
|
||||
<ONNXSelectRow />
|
||||
<PyTorchSelectRow />
|
||||
<CorrespondenceSelectRow />
|
||||
<PyTorchClusterSelectRow />
|
||||
<ModelUploadButtonRow />
|
||||
<FrameworkRow />
|
||||
<ONNXExecutorRow />
|
||||
{components}
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
|
@ -1,40 +0,0 @@
|
||||
import React, { useMemo, useEffect } from "react"
|
||||
import { useAppRoot } from "../../001_provider/001_AppRootProvider"
|
||||
import { useGuiState } from "./001_GuiStateProvider"
|
||||
|
||||
export const ModelUploaderRow = () => {
|
||||
const guiState = useGuiState()
|
||||
const { appGuiSettingState } = useAppRoot()
|
||||
const modelSetting = appGuiSettingState.appGuiSetting.front.modelSetting
|
||||
useEffect(() => {
|
||||
if (!modelSetting.modelUploaderEnable) {
|
||||
return
|
||||
}
|
||||
if (appGuiSettingState.appGuiSetting.front.modelSetting.showPyTorchDefault) {
|
||||
guiState.setShowPyTorchModelUpload(true)
|
||||
}
|
||||
}, [])
|
||||
|
||||
const modelUploaderRow = useMemo(() => {
|
||||
if (!modelSetting.modelUploaderEnable) {
|
||||
return <></>
|
||||
}
|
||||
return (
|
||||
<div className="body-row split-3-3-4 left-padding-1 guided">
|
||||
<div className="body-item-title left-padding-1">Model Uploader</div>
|
||||
<div className="body-item-text">
|
||||
<div></div>
|
||||
</div>
|
||||
<div className="body-item-text">
|
||||
<div>
|
||||
<input type="checkbox" checked={guiState.showPyTorchModelUpload} onChange={(e) => {
|
||||
guiState.setShowPyTorchModelUpload(e.target.checked)
|
||||
}} /> enable PyTorch
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}, [guiState.showPyTorchModelUpload])
|
||||
|
||||
return modelUploaderRow
|
||||
}
|
@ -1,40 +0,0 @@
|
||||
import React, { useMemo } from "react"
|
||||
import { Framework } from "@dannadori/voice-changer-client-js"
|
||||
import { useAppState } from "../../001_provider/001_AppStateProvider"
|
||||
import { useAppRoot } from "../../001_provider/001_AppRootProvider"
|
||||
|
||||
export const FrameworkRow = () => {
|
||||
const appState = useAppState()
|
||||
const { appGuiSettingState } = useAppRoot()
|
||||
const modelSetting = appGuiSettingState.appGuiSetting.front.modelSetting
|
||||
|
||||
const frameworkRow = useMemo(() => {
|
||||
if (!modelSetting.frameworkEnable) {
|
||||
return <></>
|
||||
}
|
||||
const onFrameworkChanged = async (val: Framework) => {
|
||||
appState.serverSetting.updateServerSettings({ ...appState.serverSetting.serverSetting, framework: val })
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="body-row split-3-7 left-padding-1 guided">
|
||||
<div className="body-item-title left-padding-1">Framework</div>
|
||||
<div className="body-select-container">
|
||||
<select className="body-select" value={appState.serverSetting.serverSetting.framework} onChange={(e) => {
|
||||
onFrameworkChanged(e.target.value as
|
||||
Framework)
|
||||
}}>
|
||||
{
|
||||
Object.values(Framework).map(x => {
|
||||
return <option key={x} value={x}>{x}</option>
|
||||
})
|
||||
}
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
)
|
||||
}, [appState.serverSetting.serverSetting.framework, appState.serverSetting.updateServerSettings])
|
||||
|
||||
return frameworkRow
|
||||
}
|
@ -1,38 +0,0 @@
|
||||
import React, { useMemo } from "react"
|
||||
import { OnnxExecutionProvider } from "@dannadori/voice-changer-client-js"
|
||||
import { useAppState } from "../../001_provider/001_AppStateProvider"
|
||||
|
||||
export const ONNXExecutorRow = () => {
|
||||
const appState = useAppState()
|
||||
|
||||
const onnxExecutorRow = useMemo(() => {
|
||||
if (appState.serverSetting.serverSetting.framework != "ONNX") {
|
||||
return <></>
|
||||
|
||||
}
|
||||
const onOnnxExecutionProviderChanged = async (val: OnnxExecutionProvider) => {
|
||||
appState.serverSetting.updateServerSettings({ ...appState.serverSetting.serverSetting, onnxExecutionProvider: val })
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="body-row split-3-7 left-padding-1">
|
||||
<div className="body-item-title left-padding-2">OnnxExecutionProvider</div>
|
||||
<div className="body-select-container">
|
||||
<select className="body-select" value={appState.serverSetting.serverSetting.onnxExecutionProvider} onChange={(e) => {
|
||||
onOnnxExecutionProviderChanged(e.target.value as
|
||||
OnnxExecutionProvider)
|
||||
}}>
|
||||
{
|
||||
Object.values(OnnxExecutionProvider).map(x => {
|
||||
return <option key={x} value={x}>{x}</option>
|
||||
})
|
||||
}
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
)
|
||||
}, [appState.serverSetting.serverSetting.framework, appState.serverSetting.updateServerSettings])
|
||||
|
||||
return onnxExecutorRow
|
||||
}
|
@ -1,14 +1,13 @@
|
||||
import React, { useMemo } from "react"
|
||||
import { useAppRoot } from "../../001_provider/001_AppRootProvider"
|
||||
import { AnimationTypes, HeaderButton, HeaderButtonProps } from "../101_HeaderButton"
|
||||
import { useGuiState } from "./001_GuiStateProvider"
|
||||
import { AudioInputRow } from "./401_AudioInputRow"
|
||||
import { AudioInputMediaRow } from "./402_AudioInputMediaRow"
|
||||
import { AudioOutputRow } from "./403_AudioOutputRow"
|
||||
import { AudioOutputRecordRow } from "./404_AudioOutputRecordRow"
|
||||
|
||||
import { generateComponent } from "./002_ComponentGenerator"
|
||||
|
||||
export const DeviceSetting = () => {
|
||||
const guiState = useGuiState()
|
||||
const { appGuiSettingState } = useAppRoot()
|
||||
const componentSettings = appGuiSettingState.appGuiSetting.front.deviceSetting
|
||||
|
||||
const accodionButton = useMemo(() => {
|
||||
const accodionButtonProps: HeaderButtonProps = {
|
||||
@ -23,6 +22,10 @@ export const DeviceSetting = () => {
|
||||
}, []);
|
||||
|
||||
const deviceSetting = useMemo(() => {
|
||||
const components = componentSettings.map((x, index) => {
|
||||
const c = generateComponent(x.name, x.options)
|
||||
return <div key={`${x.name}_${index}`}>{c}</div>
|
||||
})
|
||||
|
||||
return (
|
||||
<>
|
||||
@ -39,10 +42,7 @@ export const DeviceSetting = () => {
|
||||
</div>
|
||||
|
||||
<div className="partition-content">
|
||||
<AudioInputRow />
|
||||
<AudioInputMediaRow />
|
||||
<AudioOutputRow />
|
||||
<AudioOutputRecordRow />
|
||||
{components}
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
|
@ -1,16 +1,13 @@
|
||||
import React, { useMemo } from "react"
|
||||
import { useAppRoot } from "../../001_provider/001_AppRootProvider"
|
||||
import { AnimationTypes, HeaderButton, HeaderButtonProps } from "../101_HeaderButton"
|
||||
import { useGuiState } from "./001_GuiStateProvider"
|
||||
import { NoiseControlRow } from "./501_NoiseControlRow"
|
||||
import { GainControlRow } from "./502_GainControlRow"
|
||||
import { F0DetectorRow } from "./503_F0DetectorRow"
|
||||
import { AnalyzerRow } from "./510_AnalyzerRow"
|
||||
import { SamplingRow } from "./511_SamplingRow"
|
||||
import { SamplingPlayRow } from "./512_SamplingPlayRow"
|
||||
|
||||
import { generateComponent } from "./002_ComponentGenerator"
|
||||
|
||||
export const QualityControl = () => {
|
||||
const guiState = useGuiState()
|
||||
const { appGuiSettingState } = useAppRoot()
|
||||
const componentSettings = appGuiSettingState.appGuiSetting.front.qualityControl
|
||||
|
||||
const accodionButton = useMemo(() => {
|
||||
const accodionButtonProps: HeaderButtonProps = {
|
||||
@ -25,7 +22,10 @@ export const QualityControl = () => {
|
||||
}, []);
|
||||
|
||||
const deviceSetting = useMemo(() => {
|
||||
|
||||
const components = componentSettings.map((x, index) => {
|
||||
const c = generateComponent(x.name, x.options)
|
||||
return <div key={`${x.name}_${index}`}>{c}</div>
|
||||
})
|
||||
return (
|
||||
<>
|
||||
{guiState.stateControls.openQualityControlCheckbox.trigger}
|
||||
@ -41,13 +41,14 @@ export const QualityControl = () => {
|
||||
</div>
|
||||
|
||||
<div className="partition-content">
|
||||
<NoiseControlRow />
|
||||
{components}
|
||||
{/* <NoiseControlRow />
|
||||
<GainControlRow />
|
||||
<F0DetectorRow />
|
||||
<div className="body-row divider"></div>
|
||||
<AnalyzerRow />
|
||||
<SamplingRow />
|
||||
<SamplingPlayRow />
|
||||
<SamplingPlayRow /> */}
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
|
@ -1,18 +1,13 @@
|
||||
import React, { useMemo } from "react"
|
||||
import { useAppRoot } from "../../001_provider/001_AppRootProvider"
|
||||
import { AnimationTypes, HeaderButton, HeaderButtonProps } from "../101_HeaderButton"
|
||||
import { useGuiState } from "./001_GuiStateProvider"
|
||||
import { SrcIdRow } from "./601_SrcIdRow"
|
||||
import { DstIdRow } from "./602_DstIdRow"
|
||||
import { EditSpeakerIdMappingRow } from "./603_EditSpeakerIdMappingRow"
|
||||
import { F0FactorRow } from "./604_F0FactorRow"
|
||||
import { TuneRow } from "./605_TuneRow"
|
||||
import { ClusterInferRatioRow } from "./606_ClusterInferRatioRow"
|
||||
import { NoiseScaleRow } from "./607_NoiseScaleRow"
|
||||
import { SilentThresholdRow } from "./608_SilentThresholdRow"
|
||||
|
||||
import { generateComponent } from "./002_ComponentGenerator"
|
||||
|
||||
export const SpeakerSetting = () => {
|
||||
const guiState = useGuiState()
|
||||
const { appGuiSettingState } = useAppRoot()
|
||||
const componentSettings = appGuiSettingState.appGuiSetting.front.speakerSetting
|
||||
|
||||
const accodionButton = useMemo(() => {
|
||||
const accodionButtonProps: HeaderButtonProps = {
|
||||
@ -27,7 +22,10 @@ export const SpeakerSetting = () => {
|
||||
}, []);
|
||||
|
||||
const deviceSetting = useMemo(() => {
|
||||
|
||||
const components = componentSettings.map((x, index) => {
|
||||
const c = generateComponent(x.name, x.options)
|
||||
return <div key={`${x.name}_${index}`}>{c}</div>
|
||||
})
|
||||
return (
|
||||
<>
|
||||
{guiState.stateControls.openSpeakerSettingCheckbox.trigger}
|
||||
@ -43,14 +41,7 @@ export const SpeakerSetting = () => {
|
||||
</div>
|
||||
|
||||
<div className="partition-content">
|
||||
<SrcIdRow />
|
||||
<DstIdRow />
|
||||
<EditSpeakerIdMappingRow />
|
||||
<F0FactorRow />
|
||||
<TuneRow />
|
||||
<ClusterInferRatioRow />
|
||||
<NoiseScaleRow />
|
||||
<SilentThresholdRow />
|
||||
{components}
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
|
@ -1,12 +1,13 @@
|
||||
import React, { useMemo } from "react"
|
||||
import { useAppRoot } from "../../001_provider/001_AppRootProvider"
|
||||
import { AnimationTypes, HeaderButton, HeaderButtonProps } from "../101_HeaderButton"
|
||||
import { useGuiState } from "./001_GuiStateProvider"
|
||||
import { InputChunkNumRow } from "./701_InputChunkNumRow"
|
||||
import { ExtraDataLengthRow } from "./702_ExtraDataLengthRow"
|
||||
import { GPURow } from "./703_GPURow"
|
||||
import { generateComponent } from "./002_ComponentGenerator"
|
||||
|
||||
export const ConverterSetting = () => {
|
||||
const guiState = useGuiState()
|
||||
const { appGuiSettingState } = useAppRoot()
|
||||
const componentSettings = appGuiSettingState.appGuiSetting.front.converterSetting
|
||||
|
||||
const accodionButton = useMemo(() => {
|
||||
const accodionButtonProps: HeaderButtonProps = {
|
||||
@ -21,7 +22,10 @@ export const ConverterSetting = () => {
|
||||
}, []);
|
||||
|
||||
const deviceSetting = useMemo(() => {
|
||||
|
||||
const components = componentSettings.map((x, index) => {
|
||||
const c = generateComponent(x.name, x.options)
|
||||
return <div key={`${x.name}_${index}`}>{c}</div>
|
||||
})
|
||||
return (
|
||||
<>
|
||||
{guiState.stateControls.openConverterSettingCheckbox.trigger}
|
||||
@ -37,9 +41,7 @@ export const ConverterSetting = () => {
|
||||
</div>
|
||||
|
||||
<div className="partition-content">
|
||||
<InputChunkNumRow />
|
||||
<ExtraDataLengthRow />
|
||||
<GPURow />
|
||||
{components}
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
|
@ -1,19 +1,13 @@
|
||||
import React, { useMemo } from "react"
|
||||
import { useAppRoot } from "../../001_provider/001_AppRootProvider"
|
||||
import { AnimationTypes, HeaderButton, HeaderButtonProps } from "../101_HeaderButton"
|
||||
import { useGuiState } from "./001_GuiStateProvider"
|
||||
import { ServerURLRow } from "./801_ServerURLRow"
|
||||
import { ProtocolRow } from "./802_ProtocolRow"
|
||||
import { SampleRateRow } from "./803_SampleRateRow"
|
||||
import { SendingSampleRateRow } from "./804_SendingSampleRateRow"
|
||||
import { CrossFadeOverlapSizeRow } from "./805_CrossFadeOverlapSizeRow"
|
||||
import { CrossFadeOffsetRateRow } from "./806_CrossFadeOffsetRateRow"
|
||||
import { CrossFadeEndRateRow } from "./807_CrossFadeEndRateRow"
|
||||
import { DownSamplingModeRow } from "./808_DownSamplingModeRow"
|
||||
import { TrancateNumTresholdRow } from "./809_TrancateNumTresholdRow"
|
||||
import { generateComponent } from "./002_ComponentGenerator"
|
||||
|
||||
export const AdvancedSetting = () => {
|
||||
const guiState = useGuiState()
|
||||
|
||||
const { appGuiSettingState } = useAppRoot()
|
||||
const componentSettings = appGuiSettingState.appGuiSetting.front.advancedSetting
|
||||
const accodionButton = useMemo(() => {
|
||||
const accodionButtonProps: HeaderButtonProps = {
|
||||
stateControlCheckbox: guiState.stateControls.openAdvancedSettingCheckbox,
|
||||
@ -27,7 +21,10 @@ export const AdvancedSetting = () => {
|
||||
}, []);
|
||||
|
||||
const deviceSetting = useMemo(() => {
|
||||
|
||||
const components = componentSettings.map((x, index) => {
|
||||
const c = generateComponent(x.name, x.options)
|
||||
return <div key={`${x.name}_${index}`}>{c}</div>
|
||||
})
|
||||
return (
|
||||
<>
|
||||
{guiState.stateControls.openAdvancedSettingCheckbox.trigger}
|
||||
@ -43,20 +40,7 @@ export const AdvancedSetting = () => {
|
||||
</div>
|
||||
|
||||
<div className="partition-content">
|
||||
<div className="body-row divider"></div>
|
||||
<ServerURLRow />
|
||||
<ProtocolRow />
|
||||
<div className="body-row divider"></div>
|
||||
<SampleRateRow />
|
||||
<SendingSampleRateRow />
|
||||
<div className="body-row divider"></div>
|
||||
<CrossFadeOverlapSizeRow />
|
||||
<CrossFadeOffsetRateRow />
|
||||
<CrossFadeEndRateRow />
|
||||
<div className="body-row divider"></div>
|
||||
<DownSamplingModeRow />
|
||||
<div className="body-row divider"></div>
|
||||
<TrancateNumTresholdRow />
|
||||
{components}
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
|
@ -1,13 +1,16 @@
|
||||
import React, { useMemo } from "react";
|
||||
import { useAppRoot } from "../../001_provider/001_AppRootProvider";
|
||||
import { isDesktopApp } from "../../const";
|
||||
import { useGuiState } from "./001_GuiStateProvider";
|
||||
import { isDesktopApp } from "../../../const";
|
||||
import { useGuiState } from "../001_GuiStateProvider";
|
||||
|
||||
|
||||
export const Title = () => {
|
||||
const { appGuiSettingState } = useAppRoot()
|
||||
export type TitleProps = {
|
||||
lineNum: number
|
||||
mainTitle: string
|
||||
subTitle: string
|
||||
}
|
||||
|
||||
export const Title = (props: TitleProps) => {
|
||||
const guiState = useGuiState()
|
||||
const titleSetting = appGuiSettingState.appGuiSetting.front.title
|
||||
|
||||
|
||||
const githubLink = useMemo(() => {
|
||||
@ -111,14 +114,14 @@ export const Title = () => {
|
||||
}, [])
|
||||
|
||||
const titleRow = useMemo(() => {
|
||||
if (titleSetting.lineNum == 2) {
|
||||
if (props.lineNum == 2) {
|
||||
return (
|
||||
<>
|
||||
<div className="top-title">
|
||||
<span className="title">{titleSetting.mainTitle}</span>
|
||||
<span className="title">{props.mainTitle}</span>
|
||||
</div>
|
||||
<div className="top-title">
|
||||
<span className="top-title-version">{titleSetting.subTitle}</span>
|
||||
<span className="top-title-version">{props.subTitle}</span>
|
||||
<span className="belongings">
|
||||
{githubLink}
|
||||
{manualLink}
|
||||
@ -134,8 +137,8 @@ export const Title = () => {
|
||||
} else {
|
||||
return (
|
||||
<div className="top-title">
|
||||
<span className="title">{titleSetting.mainTitle}</span>
|
||||
<span className="top-title-version">{titleSetting.subTitle}</span>
|
||||
<span className="title">{props.mainTitle}</span>
|
||||
<span className="top-title-version">{props.subTitle}</span>
|
||||
<span className="belongings">
|
||||
{githubLink}
|
||||
{manualLink}
|
||||
@ -148,7 +151,7 @@ export const Title = () => {
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}, [titleSetting])
|
||||
}, [props.subTitle, props.mainTitle, props.lineNum])
|
||||
|
||||
return titleRow
|
||||
};
|
@ -1,10 +1,14 @@
|
||||
import React, { useMemo } from "react";
|
||||
import { useAppState } from "../../001_provider/001_AppStateProvider";
|
||||
import { useAppState } from "../../../001_provider/001_AppStateProvider";
|
||||
import { useIndexedDB } from "@dannadori/voice-changer-client-js";
|
||||
import { INDEXEDDB_KEY_AUDIO_OUTPUT } from "../../const";
|
||||
import { useAppRoot } from "../../001_provider/001_AppRootProvider";
|
||||
import { INDEXEDDB_KEY_AUDIO_OUTPUT } from "../../../const";
|
||||
import { useAppRoot } from "../../../001_provider/001_AppRootProvider";
|
||||
|
||||
export const ClearSettingRow = () => {
|
||||
export type ClearSettingRowProps = {
|
||||
}
|
||||
|
||||
|
||||
export const ClearSettingRow = (_props: ClearSettingRowProps) => {
|
||||
const appState = useAppState()
|
||||
const { appGuiSettingState } = useAppRoot()
|
||||
const clientType = appGuiSettingState.appGuiSetting.id
|
@ -1,8 +1,12 @@
|
||||
import React, { useMemo, useState, useEffect } from "react"
|
||||
import { useAppState } from "../../001_provider/001_AppStateProvider"
|
||||
import { useGuiState } from "./001_GuiStateProvider"
|
||||
import { useAppState } from "../../../001_provider/001_AppStateProvider"
|
||||
import { useGuiState } from "../001_GuiStateProvider"
|
||||
|
||||
export const StartButtonRow = () => {
|
||||
export type StartButtonRowProps = {
|
||||
}
|
||||
|
||||
|
||||
export const StartButtonRow = (_props: StartButtonRowProps) => {
|
||||
const appState = useAppState()
|
||||
const guiState = useGuiState()
|
||||
const [startWithAudioContextCreate, setStartWithAudioContextCreate] = useState<boolean>(false)
|
@ -1,7 +1,10 @@
|
||||
import React, { useMemo, useState } from "react"
|
||||
import { useAppState } from "../../001_provider/001_AppStateProvider"
|
||||
import { useAppState } from "../../../001_provider/001_AppStateProvider"
|
||||
|
||||
export const PerformanceRow = () => {
|
||||
export type PerformanceRowProps = {
|
||||
}
|
||||
|
||||
export const PerformanceRow = (_props: PerformanceRowProps) => {
|
||||
const appState = useAppState()
|
||||
const [showPerformanceDetail, setShowPerformanceDetail] = useState<boolean>(false)
|
||||
|
@ -1,16 +1,14 @@
|
||||
import React, { useMemo } from "react"
|
||||
import { useAppRoot } from "../../001_provider/001_AppRootProvider"
|
||||
import { useAppState } from "../../001_provider/001_AppStateProvider"
|
||||
import { useAppState } from "../../../001_provider/001_AppStateProvider"
|
||||
|
||||
export const ServerInfoRow = () => {
|
||||
|
||||
export type ServerInfoRowProps = {
|
||||
}
|
||||
|
||||
export const ServerInfoRow = (_props: ServerInfoRowProps) => {
|
||||
const appState = useAppState()
|
||||
const { appGuiSettingState } = useAppRoot()
|
||||
const serverControlSetting = appGuiSettingState.appGuiSetting.front.serverControl
|
||||
|
||||
const serverInfoRow = useMemo(() => {
|
||||
if (!serverControlSetting.modelInfoEnable) {
|
||||
return <></>
|
||||
}
|
||||
const onReloadClicked = async () => {
|
||||
const info = await appState.getInfo()
|
||||
console.log("info", info)
|
@ -1,18 +1,11 @@
|
||||
import React, { useMemo } from "react"
|
||||
import { fileSelector } from "@dannadori/voice-changer-client-js"
|
||||
|
||||
import { useAppState } from "../../001_provider/001_AppStateProvider"
|
||||
import { useAppRoot } from "../../001_provider/001_AppRootProvider"
|
||||
import { useAppState } from "../../../001_provider/001_AppStateProvider"
|
||||
|
||||
export const ConfigSelectRow = () => {
|
||||
const appState = useAppState()
|
||||
const { appGuiSettingState } = useAppRoot()
|
||||
const modelSetting = appGuiSettingState.appGuiSetting.front.modelSetting
|
||||
|
||||
const configSelectRow = useMemo(() => {
|
||||
if (!modelSetting.configRow) {
|
||||
return <></>
|
||||
}
|
||||
const configFilenameText = appState.serverSetting.fileUploadSetting.configFile?.filename || appState.serverSetting.fileUploadSetting.configFile?.file?.name || ""
|
||||
const onConfigFileLoadClicked = async () => {
|
||||
const file = await fileSelector("")
|
@ -1,20 +1,11 @@
|
||||
import React, { useMemo } from "react"
|
||||
import { fileSelector } from "@dannadori/voice-changer-client-js"
|
||||
|
||||
import { useAppState } from "../../001_provider/001_AppStateProvider"
|
||||
import { useAppRoot } from "../../001_provider/001_AppRootProvider"
|
||||
import { useAppState } from "../../../001_provider/001_AppStateProvider"
|
||||
|
||||
export const ONNXSelectRow = () => {
|
||||
const appState = useAppState()
|
||||
const { appGuiSettingState } = useAppRoot()
|
||||
|
||||
const modelSetting = appGuiSettingState.appGuiSetting.front.modelSetting
|
||||
|
||||
const onnxSelectRow = useMemo(() => {
|
||||
if (!modelSetting.ONNXEnable) {
|
||||
return <></>
|
||||
}
|
||||
|
||||
const onnxModelFilenameText = appState.serverSetting.fileUploadSetting.onnxModel?.filename || appState.serverSetting.fileUploadSetting.onnxModel?.file?.name || ""
|
||||
const onOnnxFileLoadClicked = async () => {
|
||||
const file = await fileSelector("")
|
||||
@ -48,7 +39,7 @@ export const ONNXSelectRow = () => {
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}, [modelSetting.ONNXEnable, appState.serverSetting.fileUploadSetting, appState.serverSetting.setFileUploadSetting])
|
||||
}, [appState.serverSetting.fileUploadSetting, appState.serverSetting.setFileUploadSetting])
|
||||
|
||||
return onnxSelectRow
|
||||
}
|
@ -1,24 +1,14 @@
|
||||
import React, { useMemo } from "react"
|
||||
import { fileSelector } from "@dannadori/voice-changer-client-js"
|
||||
import { useAppState } from "../../../001_provider/001_AppStateProvider"
|
||||
import { useGuiState } from "../001_GuiStateProvider"
|
||||
|
||||
import { useAppState } from "../../001_provider/001_AppStateProvider"
|
||||
import { useGuiState } from "./001_GuiStateProvider"
|
||||
import { useAppRoot } from "../../001_provider/001_AppRootProvider"
|
||||
|
||||
export const PyTorchSelectRow = () => {
|
||||
const appState = useAppState()
|
||||
const { appGuiSettingState } = useAppRoot()
|
||||
const modelSetting = appGuiSettingState.appGuiSetting.front.modelSetting
|
||||
const guiState = useGuiState()
|
||||
|
||||
const pyTorchSelectRow = useMemo(() => {
|
||||
if (!modelSetting.pyTorchEnable) {
|
||||
return <></>
|
||||
}
|
||||
if (!guiState.showPyTorchModelUpload) {
|
||||
return <></>
|
||||
}
|
||||
|
||||
const pyTorchFilenameText = appState.serverSetting.fileUploadSetting.pyTorchModel?.filename || appState.serverSetting.fileUploadSetting.pyTorchModel?.file?.name || ""
|
||||
const onPyTorchFileLoadClicked = async () => {
|
||||
const file = await fileSelector("")
|
||||
@ -52,7 +42,7 @@ export const PyTorchSelectRow = () => {
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}, [modelSetting.pyTorchEnable, guiState.showPyTorchModelUpload, appState.serverSetting.fileUploadSetting, appState.serverSetting.setFileUploadSetting])
|
||||
}, [guiState.showPyTorchModelUpload, appState.serverSetting.fileUploadSetting, appState.serverSetting.setFileUploadSetting])
|
||||
|
||||
return pyTorchSelectRow
|
||||
}
|
@ -1,18 +1,11 @@
|
||||
import React, { useMemo } from "react"
|
||||
import { fileSelector, Correspondence } from "@dannadori/voice-changer-client-js"
|
||||
|
||||
import { useAppState } from "../../001_provider/001_AppStateProvider"
|
||||
import { useAppRoot } from "../../001_provider/001_AppRootProvider"
|
||||
import { useAppState } from "../../../001_provider/001_AppStateProvider"
|
||||
|
||||
export const CorrespondenceSelectRow = () => {
|
||||
const appState = useAppState()
|
||||
const { appGuiSettingState } = useAppRoot()
|
||||
const modelSetting = appGuiSettingState.appGuiSetting.front.modelSetting
|
||||
|
||||
const CorrespondenceSelectRow = useMemo(() => {
|
||||
if (!modelSetting.MMVCCorrespondense) {
|
||||
return <></>
|
||||
}
|
||||
const correspondenceFileText = appState.clientSetting.clientSetting.correspondences ? JSON.stringify(appState.clientSetting.clientSetting.correspondences.map(x => { return x.dirname })) : ""
|
||||
const onCorrespondenceFileLoadClicked = async () => {
|
||||
const file = await fileSelector("")
|
||||
@ -54,7 +47,7 @@ export const CorrespondenceSelectRow = () => {
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}, [modelSetting.MMVCCorrespondense, appState.clientSetting.clientSetting.correspondences])
|
||||
}, [appState.clientSetting.clientSetting.correspondences])
|
||||
|
||||
return CorrespondenceSelectRow
|
||||
}
|
@ -1,19 +1,12 @@
|
||||
import React, { useMemo } from "react"
|
||||
import { fileSelector } from "@dannadori/voice-changer-client-js"
|
||||
import { useAppState } from "../../../001_provider/001_AppStateProvider"
|
||||
|
||||
import { useAppState } from "../../001_provider/001_AppStateProvider"
|
||||
import { useAppRoot } from "../../001_provider/001_AppRootProvider"
|
||||
|
||||
export const PyTorchClusterSelectRow = () => {
|
||||
const appState = useAppState()
|
||||
const { appGuiSettingState } = useAppRoot()
|
||||
const modelSetting = appGuiSettingState.appGuiSetting.front.modelSetting
|
||||
|
||||
const pyTorchSelectRow = useMemo(() => {
|
||||
if (!modelSetting.pyTorchClusterEnable) {
|
||||
return <></>
|
||||
}
|
||||
|
||||
const clusterModelFilenameText = appState.serverSetting.fileUploadSetting.clusterTorchModel?.filename || appState.serverSetting.fileUploadSetting.clusterTorchModel?.file?.name || ""
|
||||
const onClusterFileLoadClicked = async () => {
|
||||
const file = await fileSelector("")
|
||||
@ -48,7 +41,7 @@ export const PyTorchClusterSelectRow = () => {
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}, [modelSetting.pyTorchClusterEnable, appState.serverSetting.fileUploadSetting, appState.serverSetting.setFileUploadSetting])
|
||||
}, [appState.serverSetting.fileUploadSetting, appState.serverSetting.setFileUploadSetting])
|
||||
|
||||
return pyTorchSelectRow
|
||||
}
|
@ -1,18 +1,10 @@
|
||||
import React, { useMemo } from "react"
|
||||
import { useAppRoot } from "../../001_provider/001_AppRootProvider"
|
||||
|
||||
import { useAppState } from "../../001_provider/001_AppStateProvider"
|
||||
import { useAppState } from "../../../001_provider/001_AppStateProvider"
|
||||
|
||||
export const ModelUploadButtonRow = () => {
|
||||
const appState = useAppState()
|
||||
const { appGuiSettingState } = useAppRoot()
|
||||
|
||||
const modelSetting = appGuiSettingState.appGuiSetting.front.modelSetting
|
||||
|
||||
const modelUploadButtonRow = useMemo(() => {
|
||||
if (!modelSetting.uploadRow) {
|
||||
return <></>
|
||||
}
|
||||
const onModelUploadClicked = async () => {
|
||||
appState.serverSetting.loadModel()
|
||||
}
|
@ -0,0 +1,53 @@
|
||||
import React, { useMemo, useEffect } from "react"
|
||||
import { useGuiState } from "../001_GuiStateProvider"
|
||||
import { ConfigSelectRow } from "./301-1_ConfigSelectRow"
|
||||
import { ONNXSelectRow } from "./301-2_ONNXSelectRow"
|
||||
import { PyTorchSelectRow } from "./301-3_PyTorchSelectRow"
|
||||
import { CorrespondenceSelectRow } from "./301-4_CorrespondenceSelectRow"
|
||||
import { PyTorchClusterSelectRow } from "./301-5_PyTorchClusterSelectRow"
|
||||
import { ModelUploadButtonRow } from "./301-9_ModelUploadButtonRow"
|
||||
|
||||
export type ModelUploaderRowProps = {
|
||||
showConfig: boolean
|
||||
showOnnx: boolean
|
||||
showPyTorch: boolean
|
||||
showCorrespondence: boolean
|
||||
showPyTorchCluster: boolean
|
||||
|
||||
defaultEnablePyTorch: boolean
|
||||
}
|
||||
|
||||
export const ModelUploaderRow = (props: ModelUploaderRowProps) => {
|
||||
const guiState = useGuiState()
|
||||
useEffect(() => {
|
||||
guiState.setShowPyTorchModelUpload(props.defaultEnablePyTorch)
|
||||
}, [])
|
||||
|
||||
const modelUploaderRow = useMemo(() => {
|
||||
return (
|
||||
<>
|
||||
<div className="body-row split-3-3-4 left-padding-1 guided">
|
||||
<div className="body-item-title left-padding-1">Model Uploader</div>
|
||||
<div className="body-item-text">
|
||||
<div></div>
|
||||
</div>
|
||||
<div className="body-item-text">
|
||||
<div>
|
||||
<input type="checkbox" checked={guiState.showPyTorchModelUpload} onChange={(e) => {
|
||||
guiState.setShowPyTorchModelUpload(e.target.checked)
|
||||
}} /> enable PyTorch
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{props.showConfig ? <ConfigSelectRow /> : <></>}
|
||||
{props.showOnnx ? <ONNXSelectRow /> : <></>}
|
||||
{props.showPyTorch && guiState.showPyTorchModelUpload ? <PyTorchSelectRow /> : <></>}
|
||||
{props.showCorrespondence ? <CorrespondenceSelectRow /> : <></>}
|
||||
{props.showPyTorchCluster ? <PyTorchClusterSelectRow /> : <></>}
|
||||
<ModelUploadButtonRow />
|
||||
</>
|
||||
)
|
||||
}, [guiState.showPyTorchModelUpload])
|
||||
|
||||
return modelUploaderRow
|
||||
}
|
@ -0,0 +1,77 @@
|
||||
import React, { useMemo } from "react"
|
||||
import { Framework, OnnxExecutionProvider } from "@dannadori/voice-changer-client-js"
|
||||
import { useAppState } from "../../../001_provider/001_AppStateProvider"
|
||||
|
||||
export type FrameworkRowProps = {
|
||||
showFramework: boolean,
|
||||
}
|
||||
|
||||
export const FrameworkRow = (props: FrameworkRowProps) => {
|
||||
const appState = useAppState()
|
||||
|
||||
const frameworkRow = useMemo(() => {
|
||||
if (!props.showFramework) {
|
||||
return <></>
|
||||
}
|
||||
|
||||
const onFrameworkChanged = async (val: Framework) => {
|
||||
appState.serverSetting.updateServerSettings({ ...appState.serverSetting.serverSetting, framework: val })
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="body-row split-3-7 left-padding-1 guided">
|
||||
<div className="body-item-title left-padding-1">Framework</div>
|
||||
<div className="body-select-container">
|
||||
<select className="body-select" value={appState.serverSetting.serverSetting.framework} onChange={(e) => {
|
||||
onFrameworkChanged(e.target.value as
|
||||
Framework)
|
||||
}}>
|
||||
{
|
||||
Object.values(Framework).map(x => {
|
||||
return <option key={x} value={x}>{x}</option>
|
||||
})
|
||||
}
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}, [appState.serverSetting.serverSetting.framework, appState.serverSetting.updateServerSettings])
|
||||
|
||||
const onnxExecutorRow = useMemo(() => {
|
||||
if (appState.serverSetting.serverSetting.framework != "ONNX") {
|
||||
return <></>
|
||||
|
||||
}
|
||||
const onOnnxExecutionProviderChanged = async (val: OnnxExecutionProvider) => {
|
||||
appState.serverSetting.updateServerSettings({ ...appState.serverSetting.serverSetting, onnxExecutionProvider: val })
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="body-row split-3-7 left-padding-1">
|
||||
<div className="body-item-title left-padding-2">OnnxExecutionProvider</div>
|
||||
<div className="body-select-container">
|
||||
<select className="body-select" value={appState.serverSetting.serverSetting.onnxExecutionProvider} onChange={(e) => {
|
||||
onOnnxExecutionProviderChanged(e.target.value as
|
||||
OnnxExecutionProvider)
|
||||
}}>
|
||||
{
|
||||
Object.values(OnnxExecutionProvider).map(x => {
|
||||
return <option key={x} value={x}>{x}</option>
|
||||
})
|
||||
}
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
)
|
||||
}, [appState.serverSetting.serverSetting.framework, appState.serverSetting.updateServerSettings])
|
||||
|
||||
|
||||
return (
|
||||
<>
|
||||
{frameworkRow}
|
||||
{onnxExecutorRow}
|
||||
</>
|
||||
|
||||
)
|
||||
}
|
@ -1,8 +1,8 @@
|
||||
import React, { useMemo, useEffect, useRef } from "react"
|
||||
import { fileSelectorAsDataURL } from "@dannadori/voice-changer-client-js"
|
||||
import { useAppState } from "../../001_provider/001_AppStateProvider"
|
||||
import { AUDIO_ELEMENT_FOR_TEST_CONVERTED, AUDIO_ELEMENT_FOR_TEST_CONVERTED_ECHOBACK, AUDIO_ELEMENT_FOR_TEST_ORIGINAL } from "../../const"
|
||||
import { useGuiState } from "./001_GuiStateProvider"
|
||||
import { useAppState } from "../../../001_provider/001_AppStateProvider"
|
||||
import { useGuiState } from "../001_GuiStateProvider"
|
||||
import { AUDIO_ELEMENT_FOR_TEST_CONVERTED, AUDIO_ELEMENT_FOR_TEST_CONVERTED_ECHOBACK, AUDIO_ELEMENT_FOR_TEST_ORIGINAL } from "../../../const"
|
||||
|
||||
export const AudioInputMediaRow = () => {
|
||||
const appState = useAppState()
|
||||
@ -18,7 +18,7 @@ export const AudioInputMediaRow = () => {
|
||||
})
|
||||
}, [guiState.fileInputEchoback])
|
||||
|
||||
const audioInputRow = useMemo(() => {
|
||||
const audioInputMediaRow = useMemo(() => {
|
||||
if (guiState.audioInputForGUI != "file") {
|
||||
return <></>
|
||||
}
|
||||
@ -81,5 +81,5 @@ export const AudioInputMediaRow = () => {
|
||||
)
|
||||
}, [guiState.audioInputForGUI, guiState.fileInputEchoback])
|
||||
|
||||
return audioInputRow
|
||||
return audioInputMediaRow
|
||||
}
|
@ -1,8 +1,12 @@
|
||||
import React, { useMemo, useEffect } from "react"
|
||||
import { useAppState } from "../../001_provider/001_AppStateProvider"
|
||||
import { useGuiState } from "./001_GuiStateProvider"
|
||||
import { useAppState } from "../../../001_provider/001_AppStateProvider"
|
||||
import { useGuiState } from "../001_GuiStateProvider"
|
||||
import { AudioInputMediaRow } from "./401-1_AudioInputMediaRow"
|
||||
|
||||
export const AudioInputRow = () => {
|
||||
export type AudioInputRowProps = {
|
||||
}
|
||||
|
||||
export const AudioInputRow = (_props: AudioInputRowProps) => {
|
||||
const appState = useAppState()
|
||||
const guiState = useGuiState()
|
||||
|
||||
@ -44,5 +48,13 @@ export const AudioInputRow = () => {
|
||||
)
|
||||
}, [guiState.inputAudioDeviceInfo, guiState.audioInputForGUI])
|
||||
|
||||
return audioInputRow
|
||||
|
||||
|
||||
return (
|
||||
<>
|
||||
{audioInputRow}
|
||||
<AudioInputMediaRow />
|
||||
</>
|
||||
)
|
||||
|
||||
}
|
@ -1,6 +1,6 @@
|
||||
import React, { useMemo, useState } from "react"
|
||||
import { useAppState } from "../../001_provider/001_AppStateProvider"
|
||||
import { useGuiState } from "./001_GuiStateProvider"
|
||||
import { useAppState } from "../../../001_provider/001_AppStateProvider"
|
||||
import { useGuiState } from "../001_GuiStateProvider"
|
||||
|
||||
export const AudioOutputRecordRow = () => {
|
||||
const appState = useAppState()
|
||||
@ -37,7 +37,6 @@ export const AudioOutputRecordRow = () => {
|
||||
return audioOutputRecordRow
|
||||
}
|
||||
|
||||
|
||||
const downloadRecord = (data: Float32Array) => {
|
||||
|
||||
const writeString = (view: DataView, offset: number, string: string) => {
|
@ -1,10 +1,16 @@
|
||||
import React, { useMemo, useEffect } from "react"
|
||||
import { useGuiState } from "./001_GuiStateProvider"
|
||||
import { useIndexedDB } from "@dannadori/voice-changer-client-js"
|
||||
import { AUDIO_ELEMENT_FOR_PLAY_RESULT, AUDIO_ELEMENT_FOR_TEST_CONVERTED_ECHOBACK, AUDIO_ELEMENT_FOR_TEST_ORIGINAL, INDEXEDDB_KEY_AUDIO_OUTPUT } from "../../const"
|
||||
import { useAppRoot } from "../../001_provider/001_AppRootProvider"
|
||||
import { AudioOutputRecordRow } from "./402-1_AudioOutputRecordRow"
|
||||
import { useGuiState } from "../001_GuiStateProvider"
|
||||
import { useAppRoot } from "../../../001_provider/001_AppRootProvider"
|
||||
import { AUDIO_ELEMENT_FOR_PLAY_RESULT, AUDIO_ELEMENT_FOR_TEST_CONVERTED_ECHOBACK, AUDIO_ELEMENT_FOR_TEST_ORIGINAL, INDEXEDDB_KEY_AUDIO_OUTPUT } from "../../../const"
|
||||
import { useAppState } from "../../../001_provider/001_AppStateProvider"
|
||||
|
||||
export const AudioOutputRow = () => {
|
||||
export type AudioOutputRowProps = {
|
||||
}
|
||||
|
||||
export const AudioOutputRow = (_props: AudioOutputRowProps) => {
|
||||
const { setAudioOutputElementId, initializedRef } = useAppState()
|
||||
const guiState = useGuiState()
|
||||
const { appGuiSettingState } = useAppRoot()
|
||||
const clientType = appGuiSettingState.appGuiSetting.id
|
||||
@ -80,5 +86,14 @@ export const AudioOutputRow = () => {
|
||||
)
|
||||
}, [guiState.outputAudioDeviceInfo, guiState.audioOutputForGUI])
|
||||
|
||||
return audioOutputRow
|
||||
useEffect(() => {
|
||||
setAudioOutputElementId(AUDIO_ELEMENT_FOR_PLAY_RESULT)
|
||||
}, [initializedRef.current])
|
||||
|
||||
return (
|
||||
<>
|
||||
{audioOutputRow}
|
||||
<AudioOutputRecordRow />
|
||||
</>
|
||||
)
|
||||
}
|
@ -1,7 +1,10 @@
|
||||
import React, { useMemo } from "react"
|
||||
import { useAppState } from "../../001_provider/001_AppStateProvider"
|
||||
import { useAppState } from "../../../001_provider/001_AppStateProvider"
|
||||
|
||||
export const NoiseControlRow = () => {
|
||||
export type NoiseControlRowProps = {
|
||||
}
|
||||
|
||||
export const NoiseControlRow = (_props: NoiseControlRowProps) => {
|
||||
const appState = useAppState()
|
||||
|
||||
|
@ -1,7 +1,10 @@
|
||||
import React, { useMemo } from "react"
|
||||
import { useAppState } from "../../001_provider/001_AppStateProvider"
|
||||
import { useAppState } from "../../../001_provider/001_AppStateProvider"
|
||||
|
||||
export const GainControlRow = () => {
|
||||
export type GainControlRowProps = {
|
||||
}
|
||||
|
||||
export const GainControlRow = (_props: GainControlRowProps) => {
|
||||
const appState = useAppState()
|
||||
|
||||
|
@ -1,17 +1,14 @@
|
||||
import React, { useMemo } from "react"
|
||||
import { useAppState } from "../../001_provider/001_AppStateProvider"
|
||||
import { useAppState } from "../../../001_provider/001_AppStateProvider"
|
||||
import { F0Detector } from "@dannadori/voice-changer-client-js";
|
||||
import { useAppRoot } from "../../001_provider/001_AppRootProvider";
|
||||
|
||||
export const F0DetectorRow = () => {
|
||||
const appState = useAppState()
|
||||
const { appGuiSettingState } = useAppRoot()
|
||||
const qualityControlSetting = appGuiSettingState.appGuiSetting.front.qualityControl
|
||||
const f0DetectorRow = useMemo(() => {
|
||||
if (!qualityControlSetting.F0DetectorEnable) {
|
||||
return <></>
|
||||
|
||||
export type F0DetectorRowProps = {
|
||||
}
|
||||
export const F0DetectorRow = (_props: F0DetectorRowProps) => {
|
||||
const appState = useAppState()
|
||||
|
||||
const f0DetectorRow = useMemo(() => {
|
||||
const desc = { "harvest": "High Quality", "dio": "Light Weight" }
|
||||
return (
|
||||
<div className="body-row split-3-7 left-padding-1 guided">
|
@ -1,21 +1,15 @@
|
||||
import React, { useMemo, useState } from "react"
|
||||
import { useAppRoot } from "../../001_provider/001_AppRootProvider"
|
||||
import { useAppState } from "../../001_provider/001_AppStateProvider"
|
||||
import { AUDIO_ELEMENT_FOR_SAMPLING_INPUT, AUDIO_ELEMENT_FOR_SAMPLING_OUTPUT } from "../../const"
|
||||
import { useGuiState } from "./001_GuiStateProvider"
|
||||
import { useAppState } from "../../../001_provider/001_AppStateProvider"
|
||||
import { AUDIO_ELEMENT_FOR_SAMPLING_INPUT, AUDIO_ELEMENT_FOR_SAMPLING_OUTPUT } from "../../../const"
|
||||
import { useGuiState } from "./../001_GuiStateProvider"
|
||||
|
||||
export const SamplingRow = () => {
|
||||
const [recording, setRecording] = useState<boolean>(false)
|
||||
const appState = useAppState()
|
||||
const guiState = useGuiState()
|
||||
const { appGuiSettingState } = useAppRoot()
|
||||
const qualityControlSetting = appGuiSettingState.appGuiSetting.front.qualityControl
|
||||
|
||||
|
||||
const samplingRow = useMemo(() => {
|
||||
if (!qualityControlSetting.samplingRow) {
|
||||
return <></>
|
||||
}
|
||||
|
||||
const onRecordStartClicked = async () => {
|
||||
setRecording(true)
|
@ -1,17 +1,11 @@
|
||||
import React, { useMemo } from "react"
|
||||
import { useAppRoot } from "../../001_provider/001_AppRootProvider"
|
||||
import { AUDIO_ELEMENT_FOR_SAMPLING_INPUT, AUDIO_ELEMENT_FOR_SAMPLING_OUTPUT } from "../../const"
|
||||
import { useGuiState } from "./001_GuiStateProvider"
|
||||
import { AUDIO_ELEMENT_FOR_SAMPLING_INPUT, AUDIO_ELEMENT_FOR_SAMPLING_OUTPUT } from "../../../const"
|
||||
import { useGuiState } from "./../001_GuiStateProvider"
|
||||
|
||||
export const SamplingPlayRow = () => {
|
||||
const guiState = useGuiState()
|
||||
const { appGuiSettingState } = useAppRoot()
|
||||
const qualityControlSetting = appGuiSettingState.appGuiSetting.front.qualityControl
|
||||
|
||||
const samplingPlayRow = useMemo(() => {
|
||||
if (!qualityControlSetting.playRow) {
|
||||
return <></>
|
||||
}
|
||||
return (
|
||||
<div className="body-row split-3-2-2-3 left-padding-1 guided">
|
||||
<div className="body-item-title left-padding-2 ">
|
@ -1,13 +1,12 @@
|
||||
import React, { useMemo } from "react"
|
||||
import { useAppRoot } from "../../001_provider/001_AppRootProvider"
|
||||
import { SamplingRow } from "./510-1_SamplingRow"
|
||||
import { SamplingPlayRow } from "./510-2_SamplingPlayRow"
|
||||
|
||||
export const AnalyzerRow = () => {
|
||||
const { appGuiSettingState } = useAppRoot()
|
||||
const qualityControlSetting = appGuiSettingState.appGuiSetting.front.qualityControl
|
||||
const analyzerRow = useMemo(() => {
|
||||
if (!qualityControlSetting.analyzerRow) {
|
||||
return <></>
|
||||
export type AnalyzerRowProps = {
|
||||
}
|
||||
|
||||
export const AnalyzerRow = (_props: AnalyzerRowProps) => {
|
||||
const analyzerRow = useMemo(() => {
|
||||
return (
|
||||
<div className="body-row split-3-7 left-padding-1 guided">
|
||||
<div className="body-item-title left-padding-1 ">Analyzer(Experimental)</div>
|
||||
@ -17,5 +16,12 @@ export const AnalyzerRow = () => {
|
||||
)
|
||||
}, [])
|
||||
|
||||
return analyzerRow
|
||||
return (
|
||||
<>
|
||||
{analyzerRow}
|
||||
<SamplingRow />
|
||||
<SamplingPlayRow />
|
||||
</>
|
||||
)
|
||||
|
||||
}
|
@ -1,18 +1,15 @@
|
||||
import React, { useMemo } from "react"
|
||||
import { useAppRoot } from "../../001_provider/001_AppRootProvider"
|
||||
import { useAppState } from "../../001_provider/001_AppStateProvider"
|
||||
import { useAppState } from "../../../001_provider/001_AppStateProvider"
|
||||
|
||||
export const SrcIdRow = () => {
|
||||
export type SrcIdRowProps = {
|
||||
showF0: boolean
|
||||
}
|
||||
|
||||
export const SrcIdRow = (props: SrcIdRowProps) => {
|
||||
const appState = useAppState()
|
||||
const { appGuiSettingState } = useAppRoot()
|
||||
const speakerSetting = appGuiSettingState.appGuiSetting.front.speakerSetting
|
||||
const clientId = appGuiSettingState.appGuiSetting.id
|
||||
|
||||
const srcIdRow = useMemo(() => {
|
||||
if (!speakerSetting.srcIdEnable) {
|
||||
return <></>
|
||||
}
|
||||
if (clientId != "MMVCv13") {
|
||||
if (props.showF0) {
|
||||
return <></>
|
||||
}
|
||||
return (
|
||||
@ -38,13 +35,10 @@ export const SrcIdRow = () => {
|
||||
}, [appState.serverSetting.serverSetting, appState.serverSetting.updateServerSettings, appState.clientSetting.clientSetting.speakers])
|
||||
|
||||
const srcIdRowWithF0 = useMemo(() => {
|
||||
if (!speakerSetting.srcIdEnable) {
|
||||
if (!props.showF0) {
|
||||
return <></>
|
||||
}
|
||||
if (clientId != "MMVCv15") {
|
||||
return <></>
|
||||
}
|
||||
const selected = appState.clientSetting.clientSetting.correspondences?.find(x => {
|
||||
const selectedCorrespondence = appState.clientSetting.clientSetting.correspondences?.find(x => {
|
||||
return x.sid == appState.serverSetting.serverSetting.srcId
|
||||
})
|
||||
return (
|
||||
@ -65,7 +59,7 @@ export const SrcIdRow = () => {
|
||||
</select>
|
||||
</div>
|
||||
<div className="body-item-text">
|
||||
<div>F0: {selected?.correspondence.toFixed(1) || ""}</div>
|
||||
<div>F0: {selectedCorrespondence?.correspondence.toFixed(1) || ""}</div>
|
||||
</div>
|
||||
<div className="body-item-text"></div>
|
||||
</div>
|
@ -1,22 +1,21 @@
|
||||
import React, { useMemo } from "react"
|
||||
import { useAppRoot } from "../../001_provider/001_AppRootProvider"
|
||||
import { useAppState } from "../../001_provider/001_AppStateProvider"
|
||||
import { useAppState } from "../../../001_provider/001_AppStateProvider"
|
||||
import { ServerInfoSoVitsSVC } from "@dannadori/voice-changer-client-js";
|
||||
export const DstIdRow = () => {
|
||||
const appState = useAppState()
|
||||
const { appGuiSettingState } = useAppRoot()
|
||||
const speakerSetting = appGuiSettingState.appGuiSetting.front.speakerSetting
|
||||
const clientId = appGuiSettingState.appGuiSetting.id
|
||||
|
||||
export type DstIdRowProps = {
|
||||
showF0: boolean
|
||||
useServerInfo: boolean
|
||||
}
|
||||
|
||||
export const DstIdRow = (props: DstIdRowProps) => {
|
||||
const appState = useAppState()
|
||||
|
||||
const dstIdRow = useMemo(() => {
|
||||
if (!speakerSetting.dstIdEnable) {
|
||||
return <></>
|
||||
}
|
||||
if (clientId != "MMVCv13") {
|
||||
return <></>
|
||||
}
|
||||
if (!speakerSetting.dstIdEnable) {
|
||||
if (!props.showF0 && !props.useServerInfo) {
|
||||
// mmvc v.1.3ではない
|
||||
// noop
|
||||
} else {
|
||||
// mmvc v.1.3ではない
|
||||
return <></>
|
||||
}
|
||||
|
||||
@ -43,13 +42,14 @@ export const DstIdRow = () => {
|
||||
}, [appState.serverSetting.serverSetting, appState.clientSetting.clientSetting.speakers, appState.serverSetting.updateServerSettings])
|
||||
|
||||
const dstIdRowWithF0 = useMemo(() => {
|
||||
if (!speakerSetting.dstIdEnable) {
|
||||
if (props.showF0) {
|
||||
// mmvc v.15
|
||||
// noop
|
||||
} else {
|
||||
// mmvc v.1.5ではない
|
||||
return <></>
|
||||
}
|
||||
|
||||
if (clientId != "MMVCv15") {
|
||||
return <></>
|
||||
}
|
||||
const selected = appState.clientSetting.clientSetting.correspondences?.find(x => {
|
||||
return x.sid == appState.serverSetting.serverSetting.dstId
|
||||
})
|
||||
@ -79,7 +79,11 @@ export const DstIdRow = () => {
|
||||
}, [appState.serverSetting.serverSetting, appState.serverSetting.updateServerSettings, appState.clientSetting.clientSetting.correspondences])
|
||||
|
||||
const dstIdRowFromServer = useMemo(() => {
|
||||
if (!speakerSetting.dstIdEnable) {
|
||||
if (props.useServerInfo) {
|
||||
// not mmvc v1.3 or v.15
|
||||
// noop
|
||||
} else {
|
||||
// mmvc v1.3 or v.15
|
||||
return <></>
|
||||
}
|
||||
|
@ -1,18 +1,16 @@
|
||||
import React, { useMemo, useState } from "react"
|
||||
import { useAppRoot } from "../../001_provider/001_AppRootProvider"
|
||||
import { useAppState } from "../../001_provider/001_AppStateProvider"
|
||||
import { useAppState } from "../../../001_provider/001_AppStateProvider"
|
||||
|
||||
export const EditSpeakerIdMappingRow = () => {
|
||||
export type EditSpeakerIdMappingRowProps = {
|
||||
|
||||
}
|
||||
|
||||
export const EditSpeakerIdMappingRow = (_props: EditSpeakerIdMappingRowProps) => {
|
||||
const appState = useAppState()
|
||||
const { appGuiSettingState } = useAppRoot()
|
||||
const speakerSetting = appGuiSettingState.appGuiSetting.front.speakerSetting
|
||||
const [editSpeakerTargetId, setEditSpeakerTargetId] = useState<number>(0)
|
||||
const [editSpeakerTargetName, setEditSpeakerTargetName] = useState<string>("")
|
||||
|
||||
const editSpeakerIdMappingRow = useMemo(() => {
|
||||
if (!speakerSetting.editSpeakerIdMappingEnable) {
|
||||
return <></>
|
||||
}
|
||||
|
||||
const onSetSpeakerMappingClicked = async () => {
|
||||
const targetId = editSpeakerTargetId
|
@ -1,16 +1,12 @@
|
||||
import React, { useMemo, useEffect } from "react"
|
||||
import { useAppRoot } from "../../001_provider/001_AppRootProvider"
|
||||
import { useAppState } from "../../001_provider/001_AppStateProvider"
|
||||
import { useAppState } from "../../../001_provider/001_AppStateProvider"
|
||||
|
||||
export const F0FactorRow = () => {
|
||||
export type F0FactorRowProps = {
|
||||
}
|
||||
export const F0FactorRow = (_props: F0FactorRowProps) => {
|
||||
const appState = useAppState()
|
||||
const { appGuiSettingState } = useAppRoot()
|
||||
const speakerSetting = appGuiSettingState.appGuiSetting.front.speakerSetting
|
||||
|
||||
const f0FactorRow = useMemo(() => {
|
||||
if (!speakerSetting.f0FactorEnable) {
|
||||
return <></>
|
||||
}
|
||||
|
||||
const src = appState.clientSetting.clientSetting.correspondences?.find(x => {
|
||||
return x.sid == appState.serverSetting.serverSetting.srcId
|
||||
@ -38,10 +34,6 @@ export const F0FactorRow = () => {
|
||||
|
||||
|
||||
useEffect(() => {
|
||||
if (!speakerSetting.f0FactorEnable) {
|
||||
return
|
||||
}
|
||||
|
||||
const src = appState.clientSetting.clientSetting.correspondences?.find(x => {
|
||||
return x.sid == appState.serverSetting.serverSetting.srcId
|
||||
})
|
@ -1,18 +1,12 @@
|
||||
import React, { useMemo } from "react"
|
||||
import { useAppRoot } from "../../001_provider/001_AppRootProvider"
|
||||
import { useAppState } from "../../001_provider/001_AppStateProvider"
|
||||
import { useAppState } from "../../../001_provider/001_AppStateProvider"
|
||||
|
||||
export const TuneRow = () => {
|
||||
export type TuneRowProps = {
|
||||
}
|
||||
export const TuneRow = (_props: TuneRowProps) => {
|
||||
const appState = useAppState()
|
||||
const { appGuiSettingState } = useAppRoot()
|
||||
const speakerSetting = appGuiSettingState.appGuiSetting.front.speakerSetting
|
||||
|
||||
const tuneRow = useMemo(() => {
|
||||
if (!speakerSetting.tuningEnable) {
|
||||
return <></>
|
||||
}
|
||||
|
||||
|
||||
return (
|
||||
<div className="body-row split-3-2-2-3 left-padding-1 guided">
|
||||
<div className="body-item-title left-padding-1 ">Tuning</div>
|
@ -1,18 +1,13 @@
|
||||
import React, { useMemo } from "react"
|
||||
import { useAppRoot } from "../../001_provider/001_AppRootProvider"
|
||||
import { useAppState } from "../../001_provider/001_AppStateProvider"
|
||||
import { useAppState } from "../../../001_provider/001_AppStateProvider"
|
||||
|
||||
export const ClusterInferRatioRow = () => {
|
||||
const appState = useAppState()
|
||||
const { appGuiSettingState } = useAppRoot()
|
||||
|
||||
const speakerSetting = appGuiSettingState.appGuiSetting.front.speakerSetting
|
||||
|
||||
const clusterRatioRow = useMemo(() => {
|
||||
if (!speakerSetting.clusterInferRationEnable) {
|
||||
return <></>
|
||||
export type ClusterInferRatioRowProps = {
|
||||
}
|
||||
|
||||
export const ClusterInferRatioRow = (_props: ClusterInferRatioRowProps) => {
|
||||
const appState = useAppState()
|
||||
|
||||
const clusterRatioRow = useMemo(() => {
|
||||
return (
|
||||
<div className="body-row split-3-3-4 left-padding-1 guided">
|
||||
<div className="body-item-title left-padding-1 ">Cluster infer ratio</div>
|
@ -1,17 +1,13 @@
|
||||
import React, { useMemo } from "react"
|
||||
import { useAppRoot } from "../../001_provider/001_AppRootProvider"
|
||||
import { useAppState } from "../../001_provider/001_AppStateProvider"
|
||||
import { useAppState } from "../../../001_provider/001_AppStateProvider"
|
||||
|
||||
export const NoiseScaleRow = () => {
|
||||
const appState = useAppState()
|
||||
const { appGuiSettingState } = useAppRoot()
|
||||
const speakerSetting = appGuiSettingState.appGuiSetting.front.speakerSetting
|
||||
|
||||
const noiseScaleRow = useMemo(() => {
|
||||
if (!speakerSetting.noiseScaleEnable) {
|
||||
return <></>
|
||||
export type NoiseScaleRowProps = {
|
||||
}
|
||||
|
||||
export const NoiseScaleRow = (_props: NoiseScaleRowProps) => {
|
||||
const appState = useAppState()
|
||||
|
||||
const noiseScaleRow = useMemo(() => {
|
||||
return (
|
||||
<div className="body-row split-3-3-4 left-padding-1 guided">
|
||||
<div className="body-item-title left-padding-1 ">Noise Scale</div>
|
@ -1,18 +1,13 @@
|
||||
import React, { useMemo } from "react"
|
||||
import { useAppRoot } from "../../001_provider/001_AppRootProvider"
|
||||
import { useAppState } from "../../001_provider/001_AppStateProvider"
|
||||
import { useAppState } from "../../../001_provider/001_AppStateProvider"
|
||||
|
||||
export const SilentThresholdRow = () => {
|
||||
const appState = useAppState()
|
||||
const { appGuiSettingState } = useAppRoot()
|
||||
|
||||
const speakerSetting = appGuiSettingState.appGuiSetting.front.speakerSetting
|
||||
|
||||
const silentThresholdRow = useMemo(() => {
|
||||
if (!speakerSetting.silentThresholdEnable) {
|
||||
return <></>
|
||||
export type SilentThresholdRowProps = {
|
||||
}
|
||||
|
||||
export const SilentThresholdRow = (_props: SilentThresholdRowProps) => {
|
||||
const appState = useAppState()
|
||||
|
||||
const silentThresholdRow = useMemo(() => {
|
||||
return (
|
||||
<div className="body-row split-3-3-4 left-padding-1 guided">
|
||||
<div className="body-item-title left-padding-1 ">Silent Threshold</div>
|
@ -1,7 +1,9 @@
|
||||
import React, { useMemo } from "react"
|
||||
import { useAppState } from "../../001_provider/001_AppStateProvider"
|
||||
import { useAppState } from "../../../001_provider/001_AppStateProvider"
|
||||
|
||||
export const InputChunkNumRow = () => {
|
||||
export type InputChunkNumRowProps = {
|
||||
}
|
||||
export const InputChunkNumRow = (_props: InputChunkNumRowProps) => {
|
||||
const appState = useAppState()
|
||||
const inputChunkNumRow = useMemo(() => {
|
||||
return (
|
@ -1,17 +1,12 @@
|
||||
import React, { useMemo } from "react"
|
||||
import { useAppRoot } from "../../001_provider/001_AppRootProvider"
|
||||
import { useAppState } from "../../001_provider/001_AppStateProvider"
|
||||
import { useAppState } from "../../../001_provider/001_AppStateProvider"
|
||||
|
||||
export const ExtraDataLengthRow = () => {
|
||||
export type ExtraDataLengthRowProps = {
|
||||
}
|
||||
export const ExtraDataLengthRow = (_props: ExtraDataLengthRowProps) => {
|
||||
const appState = useAppState()
|
||||
const { appGuiSettingState } = useAppRoot()
|
||||
const converterSetting = appGuiSettingState.appGuiSetting.front.converterSetting
|
||||
|
||||
|
||||
const extraDataLengthRow = useMemo(() => {
|
||||
if (!converterSetting.extraDataLengthEnable) {
|
||||
return <></>
|
||||
}
|
||||
return (
|
||||
<div className="body-row split-3-2-1-4 left-padding-1 guided">
|
||||
<div className="body-item-title left-padding-1">Extra Data Length</div>
|
@ -1,7 +1,9 @@
|
||||
import React, { useMemo } from "react"
|
||||
import { useAppState } from "../../001_provider/001_AppStateProvider"
|
||||
import { useAppState } from "../../../001_provider/001_AppStateProvider"
|
||||
|
||||
export const GPURow = () => {
|
||||
export type GPURowProps = {
|
||||
}
|
||||
export const GPURow = (_props: GPURowProps) => {
|
||||
const appState = useAppState()
|
||||
const gpuRow = useMemo(() => {
|
||||
return (
|
@ -1,16 +1,13 @@
|
||||
import React, { useMemo } from "react"
|
||||
import { useAppRoot } from "../../001_provider/001_AppRootProvider"
|
||||
import { useAppState } from "../../001_provider/001_AppStateProvider"
|
||||
import { useAppState } from "../../../001_provider/001_AppStateProvider"
|
||||
|
||||
export const ServerURLRow = () => {
|
||||
export type ServerURLRowProps = {
|
||||
}
|
||||
|
||||
export const ServerURLRow = (_props: ServerURLRowProps) => {
|
||||
const appState = useAppState()
|
||||
const { appGuiSettingState } = useAppRoot()
|
||||
const advancedSetting = appGuiSettingState.appGuiSetting.front.advancedSetting
|
||||
|
||||
const serverUrlRow = useMemo(() => {
|
||||
if (!advancedSetting.serverURLEnable) {
|
||||
return <></>
|
||||
}
|
||||
const onSetServerClicked = async () => {
|
||||
const input = document.getElementById("mmvc-server-url") as HTMLInputElement
|
||||
appState.clientSetting.setServerUrl(input.value)
|
@ -1,17 +1,13 @@
|
||||
import React, { useMemo } from "react"
|
||||
import { useAppState } from "../../001_provider/001_AppStateProvider"
|
||||
import { useAppState } from "../../../001_provider/001_AppStateProvider"
|
||||
import { Protocol } from "@dannadori/voice-changer-client-js"
|
||||
import { useAppRoot } from "../../001_provider/001_AppRootProvider"
|
||||
|
||||
export const ProtocolRow = () => {
|
||||
export type ProtocolRowProps = {
|
||||
}
|
||||
export const ProtocolRow = (_props: ProtocolRowProps) => {
|
||||
const appState = useAppState()
|
||||
const { appGuiSettingState } = useAppRoot()
|
||||
const advancedSetting = appGuiSettingState.appGuiSetting.front.advancedSetting
|
||||
|
||||
const protocolRow = useMemo(() => {
|
||||
if (!advancedSetting.protocolEnable) {
|
||||
return <></>
|
||||
}
|
||||
const onProtocolChanged = async (val: Protocol) => {
|
||||
appState.workletNodeSetting.updateWorkletNodeSetting({ ...appState.workletNodeSetting.workletNodeSetting, protocol: val })
|
||||
}
|
@ -1,17 +1,13 @@
|
||||
import React, { useMemo } from "react"
|
||||
import { useAppState } from "../../001_provider/001_AppStateProvider"
|
||||
import { useAppState } from "../../../001_provider/001_AppStateProvider"
|
||||
import { SampleRate } from "@dannadori/voice-changer-client-js"
|
||||
import { useAppRoot } from "../../001_provider/001_AppRootProvider"
|
||||
|
||||
export const SampleRateRow = () => {
|
||||
export type SampleRateRowProps = {
|
||||
}
|
||||
export const SampleRateRow = (_props: SampleRateRowProps) => {
|
||||
const appState = useAppState()
|
||||
const { appGuiSettingState } = useAppRoot()
|
||||
const advancedSetting = appGuiSettingState.appGuiSetting.front.advancedSetting
|
||||
|
||||
const sampleRateRow = useMemo(() => {
|
||||
if (!advancedSetting.sampleRateEnable) {
|
||||
return <></>
|
||||
}
|
||||
return (
|
||||
<div className="body-row split-3-7 left-padding-1 guided">
|
||||
<div className="body-item-title left-padding-1">Sample Rate</div>
|
@ -1,18 +1,14 @@
|
||||
import React, { useMemo } from "react"
|
||||
import { useAppState } from "../../001_provider/001_AppStateProvider"
|
||||
import { useAppState } from "../../../001_provider/001_AppStateProvider"
|
||||
import { InputSampleRate } from "@dannadori/voice-changer-client-js"
|
||||
import { useAppRoot } from "../../001_provider/001_AppRootProvider"
|
||||
|
||||
export const SendingSampleRateRow = () => {
|
||||
export type SendingSampleRateRowProps = {
|
||||
}
|
||||
|
||||
export const SendingSampleRateRow = (_props: SendingSampleRateRowProps) => {
|
||||
const appState = useAppState()
|
||||
const { appGuiSettingState } = useAppRoot()
|
||||
|
||||
const advancedSetting = appGuiSettingState.appGuiSetting.front.advancedSetting
|
||||
|
||||
const sendingSampleRateRow = useMemo(() => {
|
||||
if (!advancedSetting.sendingSampleRateEnable) {
|
||||
return <></>
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="body-row split-3-7 left-padding-1 guided">
|
@ -1,18 +1,14 @@
|
||||
import React, { useMemo } from "react"
|
||||
import { useAppState } from "../../001_provider/001_AppStateProvider"
|
||||
import { useAppState } from "../../../001_provider/001_AppStateProvider"
|
||||
import { CrossFadeOverlapSize } from "@dannadori/voice-changer-client-js"
|
||||
import { useAppRoot } from "../../001_provider/001_AppRootProvider"
|
||||
|
||||
export const CrossFadeOverlapSizeRow = () => {
|
||||
export type CrossFadeOverlapSizeRowProps = {
|
||||
}
|
||||
|
||||
export const CrossFadeOverlapSizeRow = (_props: CrossFadeOverlapSizeRowProps) => {
|
||||
const appState = useAppState()
|
||||
const { appGuiSettingState } = useAppRoot()
|
||||
|
||||
const advancedSetting = appGuiSettingState.appGuiSetting.front.advancedSetting
|
||||
|
||||
const crossFadeOverlapSizeRow = useMemo(() => {
|
||||
if (!advancedSetting.crossFadeOverlapSizeEnable) {
|
||||
return <></>
|
||||
}
|
||||
return (
|
||||
<div className="body-row split-3-7 left-padding-1 guided">
|
||||
<div className="body-item-title left-padding-1">Cross Fade Overlap Size</div>
|
@ -1,17 +1,13 @@
|
||||
import React, { useMemo } from "react"
|
||||
import { useAppRoot } from "../../001_provider/001_AppRootProvider"
|
||||
import { useAppState } from "../../001_provider/001_AppStateProvider"
|
||||
import { useAppState } from "../../../001_provider/001_AppStateProvider"
|
||||
|
||||
export const CrossFadeOffsetRateRow = () => {
|
||||
export type CrossFadeOffsetRateRowProps = {
|
||||
}
|
||||
|
||||
export const CrossFadeOffsetRateRow = (_props: CrossFadeOffsetRateRowProps) => {
|
||||
const appState = useAppState()
|
||||
const { appGuiSettingState } = useAppRoot()
|
||||
|
||||
const advancedSetting = appGuiSettingState.appGuiSetting.front.advancedSetting
|
||||
|
||||
const crossFadeOffsetRateRow = useMemo(() => {
|
||||
if (!advancedSetting.crossFadeOffsetRateEnable) {
|
||||
return <></>
|
||||
}
|
||||
return (
|
||||
<div className="body-row split-3-7 left-padding-1 guided">
|
||||
<div className="body-item-title left-padding-1">Cross Fade Offset Rate</div>
|
@ -1,17 +1,13 @@
|
||||
import React, { useMemo } from "react"
|
||||
import { useAppRoot } from "../../001_provider/001_AppRootProvider"
|
||||
import { useAppState } from "../../001_provider/001_AppStateProvider"
|
||||
import { useAppState } from "../../../001_provider/001_AppStateProvider"
|
||||
|
||||
export const CrossFadeEndRateRow = () => {
|
||||
export type CrossFadeEndRateRowProps = {
|
||||
}
|
||||
|
||||
export const CrossFadeEndRateRow = (_props: CrossFadeEndRateRowProps) => {
|
||||
const appState = useAppState()
|
||||
const { appGuiSettingState } = useAppRoot()
|
||||
|
||||
const advancedSetting = appGuiSettingState.appGuiSetting.front.advancedSetting
|
||||
|
||||
const crossFadeEndRateRow = useMemo(() => {
|
||||
if (!advancedSetting.crossFadeEndRateEnable) {
|
||||
return <></>
|
||||
}
|
||||
return (
|
||||
<div className="body-row split-3-7 left-padding-1 guided">
|
||||
<div className="body-item-title left-padding-1">Cross Fade End Rate</div>
|
@ -1,18 +1,14 @@
|
||||
import React, { useMemo } from "react"
|
||||
import { useAppState } from "../../001_provider/001_AppStateProvider"
|
||||
import { useAppState } from "../../../001_provider/001_AppStateProvider"
|
||||
import { DownSamplingMode } from "@dannadori/voice-changer-client-js"
|
||||
import { useAppRoot } from "../../001_provider/001_AppRootProvider"
|
||||
|
||||
export const DownSamplingModeRow = () => {
|
||||
export type DownSamplingModeRowProps = {
|
||||
}
|
||||
|
||||
export const DownSamplingModeRow = (_props: DownSamplingModeRowProps) => {
|
||||
const appState = useAppState()
|
||||
const { appGuiSettingState } = useAppRoot()
|
||||
|
||||
const advancedSetting = appGuiSettingState.appGuiSetting.front.advancedSetting
|
||||
|
||||
const downSamplingModeRow = useMemo(() => {
|
||||
if (!advancedSetting.downSamplingModeEnable) {
|
||||
return <></>
|
||||
}
|
||||
return (
|
||||
<div className="body-row split-3-7 left-padding-1 guided">
|
||||
<div className="body-item-title left-padding-1 ">DownSamplingMode</div>
|
@ -1,17 +1,13 @@
|
||||
import React, { useMemo } from "react"
|
||||
import { useAppRoot } from "../../001_provider/001_AppRootProvider"
|
||||
import { useAppState } from "../../001_provider/001_AppStateProvider"
|
||||
import { useAppState } from "../../../001_provider/001_AppStateProvider"
|
||||
|
||||
export const TrancateNumTresholdRow = () => {
|
||||
export type TrancateNumTresholdRowProps = {
|
||||
}
|
||||
|
||||
export const TrancateNumTresholdRow = (_props: TrancateNumTresholdRowProps) => {
|
||||
const appState = useAppState()
|
||||
const { appGuiSettingState } = useAppRoot()
|
||||
|
||||
const advancedSetting = appGuiSettingState.appGuiSetting.front.advancedSetting
|
||||
|
||||
const trancateNumTresholdRow = useMemo(() => {
|
||||
if (!advancedSetting.trancateNumTresholdEnable) {
|
||||
return <></>
|
||||
}
|
||||
return (
|
||||
<div className="body-row split-3-7 left-padding-1 guided">
|
||||
<div className="body-item-title left-padding-1">Trancate Num</div>
|
@ -0,0 +1,17 @@
|
||||
import React, { useMemo } from "react"
|
||||
|
||||
export type DividerRowProps = {
|
||||
}
|
||||
|
||||
export const DividerRow = (_props: DividerRowProps) => {
|
||||
|
||||
const dividerRow = useMemo(() => {
|
||||
return (
|
||||
<>
|
||||
<div className="body-row divider"></div>
|
||||
</>
|
||||
)
|
||||
}, [])
|
||||
|
||||
return dividerRow
|
||||
}
|
@ -9,7 +9,6 @@ import { useWorkletSetting, WorkletSettingState } from "./useWorkletSetting"
|
||||
|
||||
export type UseClientProps = {
|
||||
audioContext: AudioContext | null
|
||||
audioOutputElementId: string
|
||||
clientType: ClientType
|
||||
}
|
||||
|
||||
@ -31,6 +30,8 @@ export type ClientState = {
|
||||
getInfo: () => Promise<void>
|
||||
// 設定クリア
|
||||
clearSetting: () => Promise<void>
|
||||
// AudioOutputElement 設定
|
||||
setAudioOutputElementId: (elemId: string) => void
|
||||
}
|
||||
|
||||
export type PerformanceData = {
|
||||
@ -114,15 +115,24 @@ export const useClient = (props: UseClientProps): ClientState => {
|
||||
setVoiceChangerClient(voiceChangerClientRef.current)
|
||||
console.log("[useClient] client initialized")
|
||||
|
||||
const audio = document.getElementById(props.audioOutputElementId) as HTMLAudioElement
|
||||
audio.srcObject = voiceChangerClientRef.current.stream
|
||||
audio.play()
|
||||
// const audio = document.getElementById(props.audioOutputElementId) as HTMLAudioElement
|
||||
// audio.srcObject = voiceChangerClientRef.current.stream
|
||||
// audio.play()
|
||||
initializedResolveRef.current!()
|
||||
setInitialized(true)
|
||||
}
|
||||
initialized()
|
||||
}, [props.audioContext])
|
||||
|
||||
const setAudioOutputElementId = (elemId: string) => {
|
||||
if (!voiceChangerClientRef.current) {
|
||||
console.warn("[voiceChangerClient] is not ready for set audio output.")
|
||||
return
|
||||
}
|
||||
const audio = document.getElementById(elemId) as HTMLAudioElement
|
||||
audio.srcObject = voiceChangerClientRef.current.stream
|
||||
audio.play()
|
||||
}
|
||||
|
||||
// (2-2) 情報リロード
|
||||
const getInfo = useMemo(() => {
|
||||
@ -160,5 +170,8 @@ export const useClient = (props: UseClientProps): ClientState => {
|
||||
|
||||
// 設定クリア
|
||||
clearSetting,
|
||||
|
||||
// AudioOutputElement 設定
|
||||
setAudioOutputElementId,
|
||||
}
|
||||
}
|
@ -65,7 +65,6 @@ export const useServerSetting = (props: UseServerSettingProps): ServerSettingSta
|
||||
return DefaultServerSetting_MMVCv15
|
||||
}
|
||||
}, [])
|
||||
console.log("default sss", defaultServerSetting)
|
||||
const [serverSetting, setServerSetting] = useState<ServerInfo>(defaultServerSetting)
|
||||
const [fileUploadSetting, setFileUploadSetting] = useState<FileUploadSetting>(InitialFileUploadSetting)
|
||||
const { setItem, getItem, removeItem } = useIndexedDB({ clientType: props.clientType })
|
||||
|
Loading…
Reference in New Issue
Block a user