remove old gui]

This commit is contained in:
wataru 2023-06-24 08:52:02 +09:00
parent 50ac1adc45
commit c333eb188e
81 changed files with 25 additions and 6547 deletions

View File

@ -1,193 +0,0 @@
{
"type": "demo",
"id": "DDSP-SVC",
"front": {
"title": [
{
"name": "title",
"options": {
"mainTitle": "Realtime Voice Changer Client",
"subTitle": "for DDSP-SVC",
"lineNum": 1
}
},
{
"name": "clearSetting",
"options": {}
}
],
"serverControl": [
{
"name": "startButton",
"options": {}
},
{
"name": "performance",
"options": {}
},
{
"name": "serverInfo",
"options": {}
}
],
"modelSetting": [
{
"name": "modelUploaderv2",
"options": {}
},
{
"name": "commonFileSelect",
"options": {
"title": "Model(.pt,.pth)",
"acceptExtentions": ["pt", "pth"],
"fileKind": "ddspSvcModel"
}
},
{
"name": "commonFileSelect",
"options": {
"title": "Model config(.yaml)",
"acceptExtentions": ["yaml"],
"fileKind": "ddspSvcModelConfig"
}
},
{
"name": "commonFileSelect",
"options": {
"title": "Diff(.pt,.pth)",
"acceptExtentions": ["pt", "pth"],
"fileKind": "ddspSvcDiffusion"
}
},
{
"name": "commonFileSelect",
"options": {
"title": "Diff config(.yaml)",
"acceptExtentions": ["yaml"],
"fileKind": "ddspSvcDiffusionConfig"
}
},
{
"name": "modelUploadButtonRow2",
"options": {}
}
],
"lab": [],
"deviceSetting": [
{
"name": "audioDeviceMode",
"options": {}
},
{
"name": "audioInput",
"options": {}
},
{
"name": "audioOutput",
"options": {}
}
],
"qualityControl": [
{
"name": "noiseControl",
"options": {}
},
{
"name": "gainControl",
"options": {}
},
{
"name": "f0Detector",
"options": {
"detectors": ["dio", "harvest", "crepe"]
}
},
{
"name": "divider",
"options": {}
},
{
"name": "analyzer",
"options": {}
}
],
"speakerSetting": [
{
"name": "dstId",
"options": {
"dstIdDisplayType": "ddspsvc",
"staticIds": [1]
}
},
{
"name": "tune",
"options": {}
},
{
"name": "silentThreshold",
"options": {}
},
{
"name": "diffEnabler",
"options": {}
},
{
"name": "diffMethod",
"options": {}
},
{
"name": "diffSetting",
"options": {}
}
],
"converterSetting": [
{
"name": "inputChunkNum",
"options": {}
},
{
"name": "extraDataLength",
"options": {}
},
{
"name": "gpu",
"options": {}
}
],
"advancedSetting": [
{
"name": "protocol",
"options": {}
},
{
"name": "crossFadeOverlapSize",
"options": {}
},
{
"name": "crossFadeOffsetRate",
"options": {}
},
{
"name": "crossFadeEndRate",
"options": {}
},
{
"name": "trancateNumThreshold",
"options": {}
}
]
},
"dialogs": {
"license": [
{
"title": "Retrieval-based-Voice-Conversion-WebUI",
"auther": "liujing04",
"contact": "",
"url": "https://github.com/liujing04/Retrieval-based-Voice-Conversion-WebUI",
"license": "MIT"
}
]
}
}

View File

@ -1,160 +0,0 @@
{
"type": "demo",
"id": "MMVCv13",
"front": {
"title": [
{
"name": "title",
"options": {
"mainTitle": "Realtime Voice Changer Client",
"subTitle": "for MMVC v.1.3",
"lineNum": 1
}
},
{
"name": "clearSetting",
"options": {}
}
],
"serverControl": [
{
"name": "startButton",
"options": {}
},
{
"name": "performance",
"options": {}
},
{
"name": "serverInfo",
"options": {}
}
],
"modelSetting": [
{
"name": "modelUploaderv2",
"options": {}
},
{
"name": "commonFileSelect",
"options": {
"title": "Config(.json)",
"acceptExtentions": ["json"],
"fileKind": "mmvcv13Config"
}
},
{
"name": "commonFileSelect",
"options": {
"title": "Model(.pt,.pth,.onxx)",
"acceptExtentions": ["pt", "pth", "onnx"],
"fileKind": "mmvcv13Model"
}
},
{
"name": "modelUploadButtonRow2",
"options": {}
}
],
"lab": [],
"deviceSetting": [
{
"name": "audioDeviceMode",
"options": {}
},
{
"name": "audioInput",
"options": {}
},
{
"name": "audioOutput",
"options": {}
}
],
"qualityControl": [
{
"name": "noiseControl",
"options": {}
},
{
"name": "gainControl",
"options": {}
},
{
"name": "divider",
"options": {}
},
{
"name": "analyzer",
"options": {}
}
],
"speakerSetting": [
{
"name": "srcId",
"options": {
"showF0": false
}
},
{
"name": "dstId",
"options": {
"showF0": false,
"useServerInfo": false,
"dstIdDisplayType": "MMVCv13"
}
},
{
"name": "editSpeakerIdMapping",
"options": {}
}
],
"converterSetting": [
{
"name": "inputChunkNum",
"options": {
"nums": [1, 2, 4, 8, 16, 24, 32, 40, 48, 56, 64]
}
},
{
"name": "gpu",
"options": {}
}
],
"advancedSetting": [
{
"name": "protocol",
"options": {}
},
{
"name": "crossFadeOverlapSize",
"options": {}
},
{
"name": "crossFadeOffsetRate",
"options": {}
},
{
"name": "crossFadeEndRate",
"options": {}
},
{
"name": "trancateNumThreshold",
"options": {}
}
]
},
"dialogs": {
"license": [
{
"title": "MMVC",
"auther": "isletennos",
"contact": "",
"url": "https://github.com/isletennos/MMVC_Trainer",
"license": "MIT"
}
]
}
}

View File

@ -1,166 +0,0 @@
{
"type": "demo",
"id": "MMVCv15",
"front": {
"title": [
{
"name": "title",
"options": {
"mainTitle": "Realtime Voice Changer Client",
"subTitle": "for MMVC v.1.5",
"lineNum": 1
}
},
{
"name": "clearSetting",
"options": {}
}
],
"serverControl": [
{
"name": "startButton",
"options": {}
},
{
"name": "performance",
"options": {}
},
{
"name": "serverInfo",
"options": {}
}
],
"modelSetting": [
{
"name": "modelUploaderv2",
"options": {}
},
{
"name": "commonFileSelect",
"options": {
"title": "Config(.json)",
"acceptExtentions": ["json"],
"fileKind": "mmvcv15Config"
}
},
{
"name": "commonFileSelect",
"options": {
"title": "Model(.pt,.pth,.onxx)",
"acceptExtentions": ["pt", "pth", "onnx"],
"fileKind": "mmvcv15Model"
}
},
{
"name": "correspondenceSelectRow2",
"options": {}
},
{
"name": "modelUploadButtonRow2",
"options": {}
}
],
"lab": [],
"deviceSetting": [
{
"name": "audioDeviceMode",
"options": {}
},
{
"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,
"dstIdDisplayType": "MMVCv15"
}
},
{
"name": "f0Factor",
"options": {}
}
],
"converterSetting": [
{
"name": "inputChunkNum",
"options": {}
},
{
"name": "gpu",
"options": {}
}
],
"advancedSetting": [
{
"name": "protocol",
"options": {}
},
{
"name": "crossFadeOverlapSize",
"options": {}
},
{
"name": "crossFadeOffsetRate",
"options": {}
},
{
"name": "crossFadeEndRate",
"options": {}
},
{
"name": "trancateNumThreshold",
"options": {}
}
]
},
"dialogs": {
"license": [
{
"title": "MMVC",
"auther": "isletennos",
"contact": "",
"url": "https://github.com/isletennos/MMVC_Trainer",
"license": "MIT"
}
]
}
}

View File

@ -1,182 +0,0 @@
{
"type": "demo",
"id": "so-vits-svc-40",
"front": {
"title": [
{
"name": "title",
"options": {
"mainTitle": "Realtime Voice Changer Client",
"subTitle": "for so-vits-svc-40",
"lineNum": 1
}
},
{
"name": "clearSetting",
"options": {}
}
],
"serverControl": [
{
"name": "startButton",
"options": {}
},
{
"name": "performance",
"options": {}
},
{
"name": "serverInfo",
"options": {}
}
],
"modelSetting": [
{
"name": "modelUploaderv2",
"options": {}
},
{
"name": "commonFileSelect",
"options": {
"title": "Config(.json)",
"acceptExtentions": ["json"],
"fileKind": "soVitsSvc40Config"
}
},
{
"name": "commonFileSelect",
"options": {
"title": "Model(.pth, .pt)",
"acceptExtentions": ["pth", "pt"],
"fileKind": "soVitsSvc40Model"
}
},
{
"name": "commonFileSelect",
"options": {
"title": "Cluster(.pth, .pt)",
"acceptExtentions": ["pth", "pt"],
"fileKind": "soVitsSvc40Cluster"
}
},
{
"name": "modelUploadButtonRow2",
"options": {}
}
],
"lab": [],
"deviceSetting": [
{
"name": "audioDeviceMode",
"options": {}
},
{
"name": "audioInput",
"options": {}
},
{
"name": "audioOutput",
"options": {}
}
],
"qualityControl": [
{
"name": "noiseControl",
"options": {}
},
{
"name": "gainControl",
"options": {}
},
{
"name": "f0Detector",
"options": {}
},
{
"name": "divider",
"options": {}
},
{
"name": "analyzer",
"options": {}
}
],
"speakerSetting": [
{
"name": "dstId",
"options": {
"showF0": false,
"useServerInfo": true,
"dstIdDisplayType": "sovitsvc40"
}
},
{
"name": "tune",
"options": {
"showPredictF0": true
}
},
{
"name": "clusterInferRatio",
"options": {}
},
{
"name": "noiseScale",
"options": {}
},
{
"name": "silentThreshold",
"options": {}
}
],
"converterSetting": [
{
"name": "inputChunkNum",
"options": {}
},
{
"name": "extraDataLength",
"options": {}
},
{
"name": "gpu",
"options": {}
}
],
"advancedSetting": [
{
"name": "protocol",
"options": {}
},
{
"name": "crossFadeOverlapSize",
"options": {}
},
{
"name": "crossFadeOffsetRate",
"options": {}
},
{
"name": "crossFadeEndRate",
"options": {}
},
{
"name": "trancateNumThreshold",
"options": {}
}
]
},
"dialogs": {
"license": [
{
"title": "svc-develop-team",
"auther": "",
"contact": "",
"url": "https://github.com/svc-develop-team/so-vits-svc",
"license": "MIT"
}
]
}
}

View File

@ -1,182 +0,0 @@
{
"type": "demo",
"id": "so-vits-svc-40v2",
"front": {
"title": [
{
"name": "title",
"options": {
"mainTitle": "Realtime Voice Changer Client",
"subTitle": "for so-vits-svc-40v2",
"lineNum": 1
}
},
{
"name": "clearSetting",
"options": {}
}
],
"serverControl": [
{
"name": "startButton",
"options": {}
},
{
"name": "performance",
"options": {}
},
{
"name": "serverInfo",
"options": {}
}
],
"modelSetting": [
{
"name": "modelUploaderv2",
"options": {}
},
{
"name": "commonFileSelect",
"options": {
"title": "Config(.json)",
"acceptExtentions": ["json"],
"fileKind": "soVitsSvc40v2Config"
}
},
{
"name": "commonFileSelect",
"options": {
"title": "Model(.pth, .pt)",
"acceptExtentions": ["pth", "pt"],
"fileKind": "soVitsSvc40v2Model"
}
},
{
"name": "commonFileSelect",
"options": {
"title": "Cluster(.pth, .pt)",
"acceptExtentions": ["pth", "pt"],
"fileKind": "soVitsSvc40v2Cluster"
}
},
{
"name": "modelUploadButtonRow2",
"options": {}
}
],
"lab": [],
"deviceSetting": [
{
"name": "audioDeviceMode",
"options": {}
},
{
"name": "audioInput",
"options": {}
},
{
"name": "audioOutput",
"options": {}
}
],
"qualityControl": [
{
"name": "noiseControl",
"options": {}
},
{
"name": "gainControl",
"options": {}
},
{
"name": "f0Detector",
"options": {}
},
{
"name": "divider",
"options": {}
},
{
"name": "analyzer",
"options": {}
}
],
"speakerSetting": [
{
"name": "dstId",
"options": {
"showF0": false,
"useServerInfo": true,
"dstIdDisplayType": "sovitsvc40v2"
}
},
{
"name": "tune",
"options": {
"showPredictF0": true
}
},
{
"name": "clusterInferRatio",
"options": {}
},
{
"name": "noiseScale",
"options": {}
},
{
"name": "silentThreshold",
"options": {}
}
],
"converterSetting": [
{
"name": "inputChunkNum",
"options": {}
},
{
"name": "extraDataLength",
"options": {}
},
{
"name": "gpu",
"options": {}
}
],
"advancedSetting": [
{
"name": "protocol",
"options": {}
},
{
"name": "crossFadeOverlapSize",
"options": {}
},
{
"name": "crossFadeOffsetRate",
"options": {}
},
{
"name": "crossFadeEndRate",
"options": {}
},
{
"name": "trancateNumThreshold",
"options": {}
}
]
},
"dialogs": {
"license": [
{
"title": "svc-develop-team",
"auther": "",
"contact": "",
"url": "https://github.com/svc-develop-team/so-vits-svc",
"license": "MIT"
}
]
}
}

File diff suppressed because one or more lines are too long

View File

@ -1,193 +0,0 @@
{
"type": "demo",
"id": "DDSP-SVC",
"front": {
"title": [
{
"name": "title",
"options": {
"mainTitle": "Realtime Voice Changer Client",
"subTitle": "for DDSP-SVC",
"lineNum": 1
}
},
{
"name": "clearSetting",
"options": {}
}
],
"serverControl": [
{
"name": "startButton",
"options": {}
},
{
"name": "performance",
"options": {}
},
{
"name": "serverInfo",
"options": {}
}
],
"modelSetting": [
{
"name": "modelUploaderv2",
"options": {}
},
{
"name": "commonFileSelect",
"options": {
"title": "Model(.pt,.pth)",
"acceptExtentions": ["pt", "pth"],
"fileKind": "ddspSvcModel"
}
},
{
"name": "commonFileSelect",
"options": {
"title": "Model config(.yaml)",
"acceptExtentions": ["yaml"],
"fileKind": "ddspSvcModelConfig"
}
},
{
"name": "commonFileSelect",
"options": {
"title": "Diff(.pt,.pth)",
"acceptExtentions": ["pt", "pth"],
"fileKind": "ddspSvcDiffusion"
}
},
{
"name": "commonFileSelect",
"options": {
"title": "Diff config(.yaml)",
"acceptExtentions": ["yaml"],
"fileKind": "ddspSvcDiffusionConfig"
}
},
{
"name": "modelUploadButtonRow2",
"options": {}
}
],
"lab": [],
"deviceSetting": [
{
"name": "audioDeviceMode",
"options": {}
},
{
"name": "audioInput",
"options": {}
},
{
"name": "audioOutput",
"options": {}
}
],
"qualityControl": [
{
"name": "noiseControl",
"options": {}
},
{
"name": "gainControl",
"options": {}
},
{
"name": "f0Detector",
"options": {
"detectors": ["dio", "harvest", "crepe"]
}
},
{
"name": "divider",
"options": {}
},
{
"name": "analyzer",
"options": {}
}
],
"speakerSetting": [
{
"name": "dstId",
"options": {
"dstIdDisplayType": "ddspsvc",
"staticIds": [1]
}
},
{
"name": "tune",
"options": {}
},
{
"name": "silentThreshold",
"options": {}
},
{
"name": "diffEnabler",
"options": {}
},
{
"name": "diffMethod",
"options": {}
},
{
"name": "diffSetting",
"options": {}
}
],
"converterSetting": [
{
"name": "inputChunkNum",
"options": {}
},
{
"name": "extraDataLength",
"options": {}
},
{
"name": "gpu",
"options": {}
}
],
"advancedSetting": [
{
"name": "protocol",
"options": {}
},
{
"name": "crossFadeOverlapSize",
"options": {}
},
{
"name": "crossFadeOffsetRate",
"options": {}
},
{
"name": "crossFadeEndRate",
"options": {}
},
{
"name": "trancateNumThreshold",
"options": {}
}
]
},
"dialogs": {
"license": [
{
"title": "Retrieval-based-Voice-Conversion-WebUI",
"auther": "liujing04",
"contact": "",
"url": "https://github.com/liujing04/Retrieval-based-Voice-Conversion-WebUI",
"license": "MIT"
}
]
}
}

View File

@ -1,160 +0,0 @@
{
"type": "demo",
"id": "MMVCv13",
"front": {
"title": [
{
"name": "title",
"options": {
"mainTitle": "Realtime Voice Changer Client",
"subTitle": "for MMVC v.1.3",
"lineNum": 1
}
},
{
"name": "clearSetting",
"options": {}
}
],
"serverControl": [
{
"name": "startButton",
"options": {}
},
{
"name": "performance",
"options": {}
},
{
"name": "serverInfo",
"options": {}
}
],
"modelSetting": [
{
"name": "modelUploaderv2",
"options": {}
},
{
"name": "commonFileSelect",
"options": {
"title": "Config(.json)",
"acceptExtentions": ["json"],
"fileKind": "mmvcv13Config"
}
},
{
"name": "commonFileSelect",
"options": {
"title": "Model(.pt,.pth,.onxx)",
"acceptExtentions": ["pt", "pth", "onnx"],
"fileKind": "mmvcv13Model"
}
},
{
"name": "modelUploadButtonRow2",
"options": {}
}
],
"lab": [],
"deviceSetting": [
{
"name": "audioDeviceMode",
"options": {}
},
{
"name": "audioInput",
"options": {}
},
{
"name": "audioOutput",
"options": {}
}
],
"qualityControl": [
{
"name": "noiseControl",
"options": {}
},
{
"name": "gainControl",
"options": {}
},
{
"name": "divider",
"options": {}
},
{
"name": "analyzer",
"options": {}
}
],
"speakerSetting": [
{
"name": "srcId",
"options": {
"showF0": false
}
},
{
"name": "dstId",
"options": {
"showF0": false,
"useServerInfo": false,
"dstIdDisplayType": "MMVCv13"
}
},
{
"name": "editSpeakerIdMapping",
"options": {}
}
],
"converterSetting": [
{
"name": "inputChunkNum",
"options": {
"nums": [1, 2, 4, 8, 16, 24, 32, 40, 48, 56, 64]
}
},
{
"name": "gpu",
"options": {}
}
],
"advancedSetting": [
{
"name": "protocol",
"options": {}
},
{
"name": "crossFadeOverlapSize",
"options": {}
},
{
"name": "crossFadeOffsetRate",
"options": {}
},
{
"name": "crossFadeEndRate",
"options": {}
},
{
"name": "trancateNumThreshold",
"options": {}
}
]
},
"dialogs": {
"license": [
{
"title": "MMVC",
"auther": "isletennos",
"contact": "",
"url": "https://github.com/isletennos/MMVC_Trainer",
"license": "MIT"
}
]
}
}

View File

@ -1,166 +0,0 @@
{
"type": "demo",
"id": "MMVCv15",
"front": {
"title": [
{
"name": "title",
"options": {
"mainTitle": "Realtime Voice Changer Client",
"subTitle": "for MMVC v.1.5",
"lineNum": 1
}
},
{
"name": "clearSetting",
"options": {}
}
],
"serverControl": [
{
"name": "startButton",
"options": {}
},
{
"name": "performance",
"options": {}
},
{
"name": "serverInfo",
"options": {}
}
],
"modelSetting": [
{
"name": "modelUploaderv2",
"options": {}
},
{
"name": "commonFileSelect",
"options": {
"title": "Config(.json)",
"acceptExtentions": ["json"],
"fileKind": "mmvcv15Config"
}
},
{
"name": "commonFileSelect",
"options": {
"title": "Model(.pt,.pth,.onxx)",
"acceptExtentions": ["pt", "pth", "onnx"],
"fileKind": "mmvcv15Model"
}
},
{
"name": "correspondenceSelectRow2",
"options": {}
},
{
"name": "modelUploadButtonRow2",
"options": {}
}
],
"lab": [],
"deviceSetting": [
{
"name": "audioDeviceMode",
"options": {}
},
{
"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,
"dstIdDisplayType": "MMVCv15"
}
},
{
"name": "f0Factor",
"options": {}
}
],
"converterSetting": [
{
"name": "inputChunkNum",
"options": {}
},
{
"name": "gpu",
"options": {}
}
],
"advancedSetting": [
{
"name": "protocol",
"options": {}
},
{
"name": "crossFadeOverlapSize",
"options": {}
},
{
"name": "crossFadeOffsetRate",
"options": {}
},
{
"name": "crossFadeEndRate",
"options": {}
},
{
"name": "trancateNumThreshold",
"options": {}
}
]
},
"dialogs": {
"license": [
{
"title": "MMVC",
"auther": "isletennos",
"contact": "",
"url": "https://github.com/isletennos/MMVC_Trainer",
"license": "MIT"
}
]
}
}

View File

@ -1,182 +0,0 @@
{
"type": "demo",
"id": "so-vits-svc-40",
"front": {
"title": [
{
"name": "title",
"options": {
"mainTitle": "Realtime Voice Changer Client",
"subTitle": "for so-vits-svc-40",
"lineNum": 1
}
},
{
"name": "clearSetting",
"options": {}
}
],
"serverControl": [
{
"name": "startButton",
"options": {}
},
{
"name": "performance",
"options": {}
},
{
"name": "serverInfo",
"options": {}
}
],
"modelSetting": [
{
"name": "modelUploaderv2",
"options": {}
},
{
"name": "commonFileSelect",
"options": {
"title": "Config(.json)",
"acceptExtentions": ["json"],
"fileKind": "soVitsSvc40Config"
}
},
{
"name": "commonFileSelect",
"options": {
"title": "Model(.pth, .pt)",
"acceptExtentions": ["pth", "pt"],
"fileKind": "soVitsSvc40Model"
}
},
{
"name": "commonFileSelect",
"options": {
"title": "Cluster(.pth, .pt)",
"acceptExtentions": ["pth", "pt"],
"fileKind": "soVitsSvc40Cluster"
}
},
{
"name": "modelUploadButtonRow2",
"options": {}
}
],
"lab": [],
"deviceSetting": [
{
"name": "audioDeviceMode",
"options": {}
},
{
"name": "audioInput",
"options": {}
},
{
"name": "audioOutput",
"options": {}
}
],
"qualityControl": [
{
"name": "noiseControl",
"options": {}
},
{
"name": "gainControl",
"options": {}
},
{
"name": "f0Detector",
"options": {}
},
{
"name": "divider",
"options": {}
},
{
"name": "analyzer",
"options": {}
}
],
"speakerSetting": [
{
"name": "dstId",
"options": {
"showF0": false,
"useServerInfo": true,
"dstIdDisplayType": "sovitsvc40"
}
},
{
"name": "tune",
"options": {
"showPredictF0": true
}
},
{
"name": "clusterInferRatio",
"options": {}
},
{
"name": "noiseScale",
"options": {}
},
{
"name": "silentThreshold",
"options": {}
}
],
"converterSetting": [
{
"name": "inputChunkNum",
"options": {}
},
{
"name": "extraDataLength",
"options": {}
},
{
"name": "gpu",
"options": {}
}
],
"advancedSetting": [
{
"name": "protocol",
"options": {}
},
{
"name": "crossFadeOverlapSize",
"options": {}
},
{
"name": "crossFadeOffsetRate",
"options": {}
},
{
"name": "crossFadeEndRate",
"options": {}
},
{
"name": "trancateNumThreshold",
"options": {}
}
]
},
"dialogs": {
"license": [
{
"title": "svc-develop-team",
"auther": "",
"contact": "",
"url": "https://github.com/svc-develop-team/so-vits-svc",
"license": "MIT"
}
]
}
}

View File

@ -1,182 +0,0 @@
{
"type": "demo",
"id": "so-vits-svc-40v2",
"front": {
"title": [
{
"name": "title",
"options": {
"mainTitle": "Realtime Voice Changer Client",
"subTitle": "for so-vits-svc-40v2",
"lineNum": 1
}
},
{
"name": "clearSetting",
"options": {}
}
],
"serverControl": [
{
"name": "startButton",
"options": {}
},
{
"name": "performance",
"options": {}
},
{
"name": "serverInfo",
"options": {}
}
],
"modelSetting": [
{
"name": "modelUploaderv2",
"options": {}
},
{
"name": "commonFileSelect",
"options": {
"title": "Config(.json)",
"acceptExtentions": ["json"],
"fileKind": "soVitsSvc40v2Config"
}
},
{
"name": "commonFileSelect",
"options": {
"title": "Model(.pth, .pt)",
"acceptExtentions": ["pth", "pt"],
"fileKind": "soVitsSvc40v2Model"
}
},
{
"name": "commonFileSelect",
"options": {
"title": "Cluster(.pth, .pt)",
"acceptExtentions": ["pth", "pt"],
"fileKind": "soVitsSvc40v2Cluster"
}
},
{
"name": "modelUploadButtonRow2",
"options": {}
}
],
"lab": [],
"deviceSetting": [
{
"name": "audioDeviceMode",
"options": {}
},
{
"name": "audioInput",
"options": {}
},
{
"name": "audioOutput",
"options": {}
}
],
"qualityControl": [
{
"name": "noiseControl",
"options": {}
},
{
"name": "gainControl",
"options": {}
},
{
"name": "f0Detector",
"options": {}
},
{
"name": "divider",
"options": {}
},
{
"name": "analyzer",
"options": {}
}
],
"speakerSetting": [
{
"name": "dstId",
"options": {
"showF0": false,
"useServerInfo": true,
"dstIdDisplayType": "sovitsvc40v2"
}
},
{
"name": "tune",
"options": {
"showPredictF0": true
}
},
{
"name": "clusterInferRatio",
"options": {}
},
{
"name": "noiseScale",
"options": {}
},
{
"name": "silentThreshold",
"options": {}
}
],
"converterSetting": [
{
"name": "inputChunkNum",
"options": {}
},
{
"name": "extraDataLength",
"options": {}
},
{
"name": "gpu",
"options": {}
}
],
"advancedSetting": [
{
"name": "protocol",
"options": {}
},
{
"name": "crossFadeOverlapSize",
"options": {}
},
{
"name": "crossFadeOffsetRate",
"options": {}
},
{
"name": "crossFadeEndRate",
"options": {}
},
{
"name": "trancateNumThreshold",
"options": {}
}
]
},
"dialogs": {
"license": [
{
"title": "svc-develop-team",
"auther": "",
"contact": "",
"url": "https://github.com/svc-develop-team/so-vits-svc",
"license": "MIT"
}
]
}
}

View File

@ -1,19 +1,17 @@
import * as React from "react";
import { createRoot } from "react-dom/client";
import "./css/App.css"
import { ErrorInfo, useEffect, useMemo, useState, } from "react";
import { AppStateProvider } from "./001_provider/001_AppStateProvider";
import { library } from "@fortawesome/fontawesome-svg-core";
import { fas } from "@fortawesome/free-solid-svg-icons";
import { far } from "@fortawesome/free-regular-svg-icons";
import { fab } from "@fortawesome/free-brands-svg-icons";
import { AppRootProvider, useAppRoot } from "./001_provider/001_AppRootProvider";
import { ErrorInfo, useEffect, useMemo, useState, } from "react";
import "./css/App.css"
import ErrorBoundary from "./001_provider/900_ErrorBoundary";
import { ClientType, useIndexedDB } from "@dannadori/voice-changer-client-js";
import { INDEXEDDB_KEY_DEFAULT_MODEL_TYPE } from "./const";
import { AppStateProvider } from "./001_provider/001_AppStateProvider";
import { AppRootProvider, useAppRoot } from "./001_provider/001_AppRootProvider";
import { useIndexedDB } from "@dannadori/voice-changer-client-js";
import { Demo } from "./components/demo/010_Demo";
import { ClientSelector } from "./001_ClientSelector";
import { useMessageBuilder } from "./hooks/useMessageBuilder";
library.add(fas, far, fab);
@ -40,7 +38,7 @@ const App = () => {
}
const AppStateWrapper = () => {
const { appGuiSettingState, clientType, setClientType } = useAppRoot()
const { appGuiSettingState, setClientType } = useAppRoot()
const messageBuilderState = useMessageBuilder()
// エラーメッセージ登録
useMemo(() => {
@ -53,7 +51,7 @@ const AppStateWrapper = () => {
// エラーバウンダリー設定
const [error, setError] = useState<{ error: Error, errorInfo: ErrorInfo }>()
const { getItem, removeDB } = useIndexedDB({ clientType: null })
const { removeDB } = useIndexedDB({ clientType: null })
const errorComponent = useMemo(() => {
@ -105,19 +103,15 @@ const AppStateWrapper = () => {
useEffect(() => {
const loadDefaultModelType = async () => {
const defaultModelType = await getItem(INDEXEDDB_KEY_DEFAULT_MODEL_TYPE)
if (defaultModelType && defaultModelType != "null") {
setClientType(defaultModelType as ClientType)
}
setClientType("RVC")
}
loadDefaultModelType()
}, [])
if (!clientType) {
return <ClientSelector></ClientSelector>
} else if (!appGuiSettingState.guiSettingLoaded) {
return <></>
if (!appGuiSettingState.guiSettingLoaded) {
return <>a</>
} else {
return (
<ErrorBoundary fallback={errorComponent} onError={updateError}>

View File

@ -1,151 +0,0 @@
import React, { useMemo } from "react";
import { isDesktopApp } from "./const";
import { useAppRoot } from "./001_provider/001_AppRootProvider";
import { useMessageBuilder } from "./hooks/useMessageBuilder";
export type TitleProps = {
lineNum: number
mainTitle: string
subTitle: string
}
export const Title = (props: TitleProps) => {
const messageBuilderState = useMessageBuilder()
useMemo(() => {
messageBuilderState.setMessage(__filename, "github", { "ja": "github", "en": "github" })
messageBuilderState.setMessage(__filename, "manual", { "ja": "マニュアル", "en": "manual" })
messageBuilderState.setMessage(__filename, "screenCapture", { "ja": "録画ツール", "en": "Record Screen" })
messageBuilderState.setMessage(__filename, "support", { "ja": "支援", "en": "Donation" })
}, [])
const githubLink = useMemo(() => {
return isDesktopApp() ?
(
// @ts-ignore
<span className="link tooltip" onClick={() => { window.electronAPI.openBrowser("https://github.com/w-okada/voice-changer") }}>
<img src="./assets/icons/github.svg" />
<div className="tooltip-text">{messageBuilderState.getMessage(__filename, "github")}</div>
</span>
)
:
(
<a className="link tooltip" href="https://github.com/w-okada/voice-changer" target="_blank" rel="noopener noreferrer">
<img src="./assets/icons/github.svg" />
<div className="tooltip-text">{messageBuilderState.getMessage(__filename, "github")}</div>
</a>
)
}, [])
const manualLink = useMemo(() => {
return isDesktopApp() ?
(
// @ts-ignore
<span className="link tooltip" onClick={() => { window.electronAPI.openBrowser("https://github.com/w-okada/voice-changer/blob/master/tutorials/tutorial_rvc_ja_latest.md") }}>
<img src="./assets/icons/help-circle.svg" />
<div className="tooltip-text tooltip-text-100px">{messageBuilderState.getMessage(__filename, "manual")}</div>
</span>
)
:
(
<a className="link tooltip" href="https://github.com/w-okada/voice-changer/blob/master/tutorials/tutorial_rvc_ja_latest.md" target="_blank" rel="noopener noreferrer">
<img src="./assets/icons/help-circle.svg" />
<div className="tooltip-text tooltip-text-100px">{messageBuilderState.getMessage(__filename, "manual")}</div>
</a>
)
}, [])
const toolLink = useMemo(() => {
return isDesktopApp() ?
(
<div className="link tooltip">
<img src="./assets/icons/tool.svg" />
<div className="tooltip-text tooltip-text-100px">
<p onClick={() => {
// @ts-ignore
window.electronAPI.openBrowser("https://w-okada.github.io/screen-recorder-ts/")
}}>
{messageBuilderState.getMessage(__filename, "screenCapture")}
</p>
</div>
</div>
)
:
(
<div className="link tooltip">
<img src="./assets/icons/tool.svg" />
<div className="tooltip-text tooltip-text-100px">
<p onClick={() => {
window.open("https://w-okada.github.io/screen-recorder-ts/", '_blank', "noreferrer")
}}>
{messageBuilderState.getMessage(__filename, "screenCapture")}
</p>
</div>
</div>
)
}, [])
const coffeeLink = useMemo(() => {
return isDesktopApp() ?
(
// @ts-ignore
<span className="link tooltip" onClick={() => { window.electronAPI.openBrowser("https://www.buymeacoffee.com/wokad") }}>
<img className="donate-img" src="./assets/buymeacoffee.png" />
<div className="tooltip-text tooltip-text-100px">{messageBuilderState.getMessage(__filename, "support")}</div>
</span>
)
:
(
<a className="link tooltip" href="https://www.buymeacoffee.com/wokad" target="_blank" rel="noopener noreferrer">
<img className="donate-img" src="./assets/buymeacoffee.png" />
<div className="tooltip-text tooltip-text-100px">
{messageBuilderState.getMessage(__filename, "support")}
</div>
</a>
)
}, [])
const titleRow = useMemo(() => {
if (props.lineNum == 2) {
return (
<>
<div className="top-title">
<span className="title">{props.mainTitle}</span>
</div>
<div className="top-title">
<span className="top-title-version">{props.subTitle}</span>
<span className="belongings">
{githubLink}
{manualLink}
{toolLink}
{coffeeLink}
</span>
</div>
</>
)
} else {
return (
<div className="top-title">
<span className="title">{props.mainTitle}</span>
<span className="top-title-version">{props.subTitle}</span>
<span className="belongings">
{githubLink}
{manualLink}
{toolLink}
{coffeeLink}
</span>
<span className="belongings">
</span>
</div>
)
}
}, [props.subTitle, props.mainTitle, props.lineNum])
return titleRow
};

View File

@ -1,55 +0,0 @@
import { ClientType, useIndexedDB } from "@dannadori/voice-changer-client-js"
import React, { useMemo } from "react"
import { Title } from "./001-1_Title"
import { useAppRoot } from "./001_provider/001_AppRootProvider"
import { INDEXEDDB_KEY_DEFAULT_MODEL_TYPE } from "./const"
export const ClientSelector = () => {
const { setClientType } = useAppRoot()
const { setItem } = useIndexedDB({ clientType: null })
const onClientTypeClicked = (clientType: ClientType) => {
setClientType(clientType);
setItem(INDEXEDDB_KEY_DEFAULT_MODEL_TYPE, clientType)
}
const selectableClientTypes = useMemo(() => {
const ua = window.navigator.userAgent.toLowerCase();
if (ua.indexOf("mac os x") !== -1) {
return ["MMVCv13", "MMVCv15", "so-vits-svc-40", "RVC"] as ClientType[]
} else {
return ["MMVCv13", "MMVCv15", "so-vits-svc-40", "DDSP-SVC", "RVC"] as ClientType[]
}
}, [])
const selectableClientTypesRowItems = useMemo(() => {
return selectableClientTypes.flatMap((_, i, a) => { return i % 2 ? [] : [a.slice(i, i + 2)] })
}, [])
const selectableClientTypesRow = useMemo(() => {
return selectableClientTypesRowItems.map((x, index) => {
return (
<div key={index} className="body-row split-1-8-1 left-padding-1 ">
<div></div>
<div className="body-button-container">
{
x.map(y => {
return <div key={y} className="body-button w40 bold" onClick={() => { onClientTypeClicked(y) }}>{y}</div>
})
}
</div>
<div></div>
</div>
)
})
}, [])
return (
<div className="main-body">
<Title lineNum={1} mainTitle={"Realtime Voice Changer Client"} subTitle={"launcher"} ></Title>
{selectableClientTypesRow}
</div>
)
}

View File

@ -1,62 +1,4 @@
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 { 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"
import { RVCQualityRow, RVCQualityRowProps } from "./components/810_RVCQualityRow"
import { ModelSamplingRateRow, ModelSamplingRateRowProps } from "./components/303_ModelSamplingRateRow"
import { DstIdRow2, DstIdRow2Props } from "./components/602v2_DstIdRow2"
import { SilenceFrontRow, SilenceFrontRowProps } from "./components/812_SilenceFrontRow"
import { ONNXExportRow, ONNXExportRowProps } from "./components/205_ONNXExportRow"
import { ONNXExecutorRow, ONNXExecutorRowProps } from "./components/206_ONNXExecutorRow"
import { MergeLabRow, MergeLabRowProps } from "./components/a01_MergeLab.Row"
import { ModelSwitchRow, ModelSwitchRowProps } from "./components/204_ModelSwitchRow"
import { EnableDirectMLRow, EnableDirectMLRowProps } from "./components/813_EnableDirectMLRow"
import { AudioDeviceModeRow, AudioDeviceModeRowProps } from "./components/410_AudioDeviceModeRow"
import { IOBufferRow, IOBufferRowProps } from "./components/411_IOBufferRow"
import { CommonFileSelectRow, CommonFileSelectRowProps } from "./components/301-e_CommonFileSelectRow"
import { ModelUploadButtonRow2, ModelUploadButtonRow2Props } from "./components/301-f_ModelUploadButtonRow"
import { ModelUploaderRowv2, ModelUploaderRowv2Props } from "./components/301_ModelUploaderRowv2"
import { CorrespondenceSelectRow2, CorrespondenceSelectRow2Props } from "./components/301-g_CorrespondenceSelectRow2"
import { ModelSlotRow2, ModelSlotRow2Props } from "./components/301-h_ModelSlotRowv2"
import { DefaultTuneRow2, DefaultTuneRow2Props } from "./components/301-i_DefaultTuneRowv2"
import { DiffEnablerRow, DiffEnablerRowProps } from "./components/611_DiffEnablerRow"
import { DiffSettingRow, DiffSettingRowProps } from "./components/612_DiffSettingRow"
import { DiffMethodRow, DiffMethodRowProps } from "./components/613_DiffMethodRow"
import { ServerOpertationRow, ServerOpertationRowProps } from "./components/207_ServerOpertationRow"
import { SampleModelSelectRow, SampleModelSelectRowProps } from "./components/301-j_SampleModelSelectRow"
import { SampleDownloadControlRow, SampleDownloadControlRowProps } from "./components/301-k_SampleDownloadControl"
import { IndexRatioRow, IndexRatioRowProps } from "./components/609_IndexRatioRow copy"
import { ProtectRow, ProtectRowProps } from "./components/610_ProtectRow"
import { ModelSlotArea, ModelSlotAreaProps } from "./components2/100_ModelSlotArea"
import { CharacterArea, CharacterAreaProps } from "./components2/101_CharacterArea"
import { ConfigArea, ConfigAreaProps } from "./components2/102_ConfigArea"
@ -77,87 +19,6 @@ export const generateComponent = (key: string, props: any) => {
}
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("modelSwitch", (props: ModelSwitchRowProps) => { return <ModelSwitchRow {...props} /> })
addToCatalog("onnxExport", (props: ONNXExportRowProps) => { return <ONNXExportRow {...props} /> })
addToCatalog("onnxExecutor", (props: ONNXExecutorRowProps) => { return <ONNXExecutorRow {...props} /> })
addToCatalog("serverOperation", (props: ServerOpertationRowProps) => { return <ServerOpertationRow {...props} /> })
addToCatalog("modelUploaderv2", (props: ModelUploaderRowv2Props) => { return <ModelUploaderRowv2 {...props} /> })
addToCatalog("framework", (props: FrameworkRowProps) => { return <FrameworkRow {...props} /> })
addToCatalog("modelSamplingRate", (props: ModelSamplingRateRowProps) => { return <ModelSamplingRateRow {...props} /> })
addToCatalog("commonFileSelect", (props: CommonFileSelectRowProps) => { return <CommonFileSelectRow {...props} /> })
addToCatalog("modelUploadButtonRow2", (props: ModelUploadButtonRow2Props) => { return <ModelUploadButtonRow2 {...props} /> })
addToCatalog("correspondenceSelectRow2", (props: CorrespondenceSelectRow2Props) => { return <CorrespondenceSelectRow2 {...props} /> })
addToCatalog("modelSlotRow2", (props: ModelSlotRow2Props) => { return <ModelSlotRow2 {...props} /> })
addToCatalog("defaultTuneRow2", (props: DefaultTuneRow2Props) => { return <DefaultTuneRow2 {...props} /> })
addToCatalog("sampleModelSelect", (props: SampleModelSelectRowProps) => { return <SampleModelSelectRow {...props} /> })
addToCatalog("sampleDownloadControlRow", (props: SampleDownloadControlRowProps) => { return <SampleDownloadControlRow {...props} /> })
addToCatalog("audioInput", (props: AudioInputRowProps) => { return <AudioInputRow {...props} /> })
addToCatalog("audioOutput", (props: AudioOutputRowProps) => { return <AudioOutputRow {...props} /> })
addToCatalog("audioDeviceMode", (props: AudioDeviceModeRowProps) => { return <AudioDeviceModeRow {...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("dstId2", (props: DstIdRow2Props) => { return <DstIdRow2 {...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("indexRatio", (props: IndexRatioRowProps) => { return <IndexRatioRow {...props} /> })
addToCatalog("protect", (props: ProtectRowProps) => { return <ProtectRow {...props} /> })
addToCatalog("diffEnabler", (props: DiffEnablerRowProps) => { return <DiffEnablerRow {...props} /> })
addToCatalog("diffSetting", (props: DiffSettingRowProps) => { return <DiffSettingRow {...props} /> })
addToCatalog("diffMethod", (props: DiffMethodRowProps) => { return <DiffMethodRow {...props} /> })
addToCatalog("inputChunkNum", (props: InputChunkNumRowProps) => { return <InputChunkNumRow {...props} /> })
addToCatalog("extraDataLength", (props: ExtraDataLengthRowProps) => { return <ExtraDataLengthRow {...props} /> })
addToCatalog("gpu", (props: GPURowProps) => { return <GPURow {...props} /> })
addToCatalog("ioBuffer", (props: IOBufferRowProps) => { return <IOBufferRow {...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} /> })
addToCatalog("rvcQuality", (props: RVCQualityRowProps) => { return <RVCQualityRow {...props} /> })
addToCatalog("silenceFront", (props: SilenceFrontRowProps) => { return <SilenceFrontRow {...props} /> })
addToCatalog("enableDirectML", (props: EnableDirectMLRowProps) => { return <EnableDirectMLRow {...props} /> })
addToCatalog("mergeLab", (props: MergeLabRowProps) => { return <MergeLabRow {...props} /> })
addToCatalog("headerArea", (props: HeaderAreaProps) => { return <HeaderArea {...props} /> })
addToCatalog("modelSlotArea", (props: ModelSlotAreaProps) => { return <ModelSlotArea {...props} /> })
addToCatalog("characterArea", (props: CharacterAreaProps) => { return <CharacterArea {...props} /> })

View File

@ -1,159 +0,0 @@
import React, { useMemo } from "react";
import { isDesktopApp } from "../../../const";
import { useGuiState } from "../001_GuiStateProvider";
import { useAppRoot } from "../../../001_provider/001_AppRootProvider";
export type TitleProps = {
lineNum: number
mainTitle: string
subTitle: string
}
export const Title = (props: TitleProps) => {
const guiState = useGuiState()
const appRootState = useAppRoot()
const githubLink = useMemo(() => {
return isDesktopApp() ?
(
// @ts-ignore
<span className="link tooltip" onClick={() => { window.electronAPI.openBrowser("https://github.com/w-okada/voice-changer") }}>
<img src="./assets/icons/github.svg" />
<div className="tooltip-text">github</div>
</span>
)
:
(
<a className="link tooltip" href="https://github.com/w-okada/voice-changer" target="_blank" rel="noopener noreferrer">
<img src="./assets/icons/github.svg" />
<div className="tooltip-text">github</div>
</a>
)
}, [])
const manualLink = useMemo(() => {
return isDesktopApp() ?
(
// @ts-ignore
<span className="link tooltip" onClick={() => { window.electronAPI.openBrowser("https://zenn.dev/wok/books/0004_vc-client-v_1_5_1_x") }}>
<img src="./assets/icons/help-circle.svg" />
<div className="tooltip-text">manual</div>
</span>
)
:
(
<a className="link tooltip" href="https://zenn.dev/wok/books/0004_vc-client-v_1_5_1_x" target="_blank" rel="noopener noreferrer">
<img src="./assets/icons/help-circle.svg" />
<div className="tooltip-text">manual</div>
</a>
)
}, [])
const toolLink = useMemo(() => {
return isDesktopApp() ?
(
<div className="link tooltip">
<img src="./assets/icons/tool.svg" />
<div className="tooltip-text tooltip-text-100px">
<p onClick={() => {
// @ts-ignore
window.electronAPI.openBrowser("https://w-okada.github.io/screen-recorder-ts/")
}}>
screen capture
</p>
</div>
</div>
)
:
(
<div className="link tooltip">
<img src="./assets/icons/tool.svg" />
<div className="tooltip-text tooltip-text-100px">
<p onClick={() => {
window.open("https://w-okada.github.io/screen-recorder-ts/", '_blank', "noreferrer")
}}>
screen capture
</p>
</div>
</div>
)
}, [])
const coffeeLink = useMemo(() => {
return isDesktopApp() ?
(
// @ts-ignore
<span className="link tooltip" onClick={() => { window.electronAPI.openBrowser("https://www.buymeacoffee.com/wokad") }}>
<img className="donate-img" src="./assets/buymeacoffee.png" />
<div className="tooltip-text tooltip-text-100px">donate()</div>
</span>
)
:
(
<a className="link tooltip" href="https://www.buymeacoffee.com/wokad" target="_blank" rel="noopener noreferrer">
<img className="donate-img" src="./assets/buymeacoffee.png" />
<div className="tooltip-text tooltip-text-100px">
donate()
</div>
</a>
)
}, [])
const licenseButton = useMemo(() => {
return (
<span className="link" onClick={() => {
document.getElementById("dialog")?.classList.add("dialog-container-show")
guiState.stateControls.showLicenseCheckbox.updateState(true)
}}>
<span>License</span>
</span>
)
}, [])
const titleRow = useMemo(() => {
if (props.lineNum == 2) {
return (
<>
<div className="top-title">
<span className="title">{props.mainTitle}</span>
</div>
<div className="top-title">
<span className="top-title-version">{props.subTitle}</span>
<span className="belongings">
{githubLink}
{manualLink}
{toolLink}
{coffeeLink}
{/* {licenseButton} */}
</span>
</div>
</>
)
} else {
return (
<div className="top-title">
<span className="title">{props.mainTitle}</span>
<span className="top-title-version">{props.subTitle}</span>
<span className="top-title-version-number">{appRootState.appGuiSettingState.version}</span>
<span className="top-title-version-number">{appRootState.appGuiSettingState.edition}</span>
<span className="belongings">
{githubLink}
{manualLink}
{toolLink}
{coffeeLink}
{/* {licenseButton} */}
</span>
<span className="belongings">
</span>
</div>
)
}
}, [props.subTitle, props.mainTitle, props.lineNum, appRootState.appGuiSettingState.version, appRootState.appGuiSettingState.edition])
return titleRow
};

View File

@ -1,53 +0,0 @@
import React, { useMemo } from "react";
import { useAppState } from "../../../001_provider/001_AppStateProvider";
import { useIndexedDB } from "@dannadori/voice-changer-client-js";
import { INDEXEDDB_KEY_AUDIO_OUTPUT, INDEXEDDB_KEY_DEFAULT_MODEL_TYPE } from "../../../const";
import { useAppRoot } from "../../../001_provider/001_AppRootProvider";
import { useGuiState } from "../001_GuiStateProvider"
export type ClearSettingRowProps = {
}
export const ClearSettingRow = (_props: ClearSettingRowProps) => {
const appState = useAppState()
const { appGuiSettingState, setClientType } = useAppRoot()
const guiState = useGuiState()
const clientType = appGuiSettingState.appGuiSetting.id
const { removeItem } = useIndexedDB({ clientType: clientType })
const { setItem } = useIndexedDB({ clientType: null })
const clearSettingRow = useMemo(() => {
const onClearSettingClicked = async () => {
await appState.clearSetting()
await removeItem(INDEXEDDB_KEY_AUDIO_OUTPUT)
location.reload()
}
const onReloadClicked = async () => {
location.reload()
}
const onReselectVCClicked = async () => {
guiState.setIsConverting(false)
if (guiState.isConverting) {
await appState.clientSetting.stop()
guiState.setIsConverting(false)
}
setItem(INDEXEDDB_KEY_DEFAULT_MODEL_TYPE, "null")
setClientType(null)
appGuiSettingState.clearAppGuiSetting()
}
return (
<div className="body-row split-2-2-6 left-padding-1">
<div className="body-button-container">
<div className="body-button" onClick={onClearSettingClicked}>clear setting</div>
<div className="body-button" onClick={onReloadClicked}>reload</div>
</div>
<div className="body-button-container">
<div className="body-button" onClick={onReselectVCClicked}>re-select vc</div>
</div>
<div className="body-item-text"></div>
</div>
)
}, [appState.clientSetting, guiState.isConverting])
return clearSettingRow
};

View File

@ -1,76 +0,0 @@
import React, { useMemo, useState, useEffect } from "react"
import { useAppState } from "../../../001_provider/001_AppStateProvider"
import { useGuiState } from "../001_GuiStateProvider"
export type StartButtonRowProps = {
}
export const StartButtonRow = (_props: StartButtonRowProps) => {
const appState = useAppState()
const guiState = useGuiState()
const [startWithAudioContextCreate, setStartWithAudioContextCreate] = useState<boolean>(false)
useEffect(() => {
if (!startWithAudioContextCreate) {
return
}
guiState.setIsConverting(true)
appState.clientSetting.start()
}, [startWithAudioContextCreate])
const startButtonRow = useMemo(() => {
const onStartClicked = async () => {
if (appState.serverSetting.serverSetting.enableServerAudio == 0) {
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 {
guiState.setIsConverting(true)
await appState.clientSetting.start()
}
} else {
appState.serverSetting.updateServerSettings({ ...appState.serverSetting.serverSetting, serverAudioStated: 1 })
guiState.setIsConverting(true)
}
}
const onStopClicked = async () => {
if (appState.serverSetting.serverSetting.enableServerAudio == 0) {
guiState.setIsConverting(false)
await appState.clientSetting.stop()
} else {
guiState.setIsConverting(false)
console.log("Stop clicked", appState.serverSetting.serverSetting)
appState.serverSetting.updateServerSettings({ ...appState.serverSetting.serverSetting, serverAudioStated: 0 })
}
}
const startClassName = guiState.isConverting ? "body-button-active" : "body-button-stanby"
const stopClassName = guiState.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>
)
}, [guiState.isConverting, appState.clientSetting.start, appState.clientSetting.stop, appState.serverSetting.serverSetting, appState.serverSetting.updateServerSettings])
return startButtonRow
}

View File

@ -1,69 +0,0 @@
import React, { useEffect, useMemo, useState } from "react"
import { useAppState } from "../../../001_provider/001_AppStateProvider"
export type PerformanceRowProps = {
}
export const PerformanceRow = (_props: PerformanceRowProps) => {
const appState = useAppState()
const [showPerformanceDetail, setShowPerformanceDetail] = useState<boolean>(false)
const performanceRow = useMemo(() => {
// if (appState.serverSetting.serverSetting.enableServerAudio) {
// return (
// <div className="body-row split-3-7 left-padding-1 guided">
// <div className="body-item-title left-padding-1">monitor:</div>
// <div className="body-item-text">server device mode. refer console.</div>
// </div>
// )
// }
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, appState.serverSetting.serverSetting.enableServerAudio])
useEffect(() => {
if (!appState.updatePerformance) {
return
}
if (appState.serverSetting.serverSetting.enableServerAudio != 1) {
return
}
let execNext = true
const updatePerformance = async () => {
await appState.updatePerformance!()
if (execNext) {
setTimeout(updatePerformance, 1000 * 2)
}
}
// updatePerformance()
return () => {
execNext = false
}
}, [appState.updatePerformance, appState.serverSetting.serverSetting.enableServerAudio])
return (
<>
{performanceRow}
</>
)
}

View File

@ -1,36 +0,0 @@
import React, { useMemo } from "react"
import { useAppState } from "../../../001_provider/001_AppStateProvider"
export type ServerInfoRowProps = {
}
export const ServerInfoRow = (_props: ServerInfoRowProps) => {
const appState = useAppState()
const serverInfoRow = 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])
return serverInfoRow
}

View File

@ -1,95 +0,0 @@
import React, { useMemo } from "react"
import { useAppState } from "../../../001_provider/001_AppStateProvider"
export type ModelSwitchRowProps = {
}
export const ModelSwitchRow = (_props: ModelSwitchRowProps) => {
const appState = useAppState()
const modelSwitchRow = useMemo(() => {
const slot = appState.serverSetting.serverSetting.modelSlotIndex
const onSwitchModelClicked = async (slot: number) => {
// Quick hack for same slot is selected. 下桁が実際のSlotID
const dummyModelSlotIndex = (Math.floor(Date.now() / 1000)) * 1000 + slot
await appState.serverSetting.updateServerSettings({ ...appState.serverSetting.serverSetting, modelSlotIndex: dummyModelSlotIndex })
setTimeout(() => { // quick hack
appState.getInfo()
}, 1000 * 2)
}
const onUpdateDefaultClicked = async () => {
await appState.serverSetting.updateModelDefault()
}
const modelSlots = appState.serverSetting.serverSetting.modelSlots
let options: React.JSX.Element[] = []
if (modelSlots) {
options = modelSlots.map((x, index) => {
let filename = ""
if (x.modelFile && x.modelFile.length > 0) {
filename = x.modelFile.replace(/^.*[\\\/]/, '')
} else {
return null
}
const f0str = x.f0 == true ? "f0" : "nof0"
const srstr = Math.floor(x.samplingRate / 1000) + "K"
const embedstr = x.embChannels
const typestr = (() => {
if (x.modelType == "pyTorchRVC" || x.modelType == "pyTorchRVCNono") {
return "org"
} else if (x.modelType == "pyTorchRVCv2" || x.modelType == "pyTorchRVCv2Nono") {
return "org_v2"
} else if (x.modelType == "pyTorchWebUI" || x.modelType == "pyTorchWebUINono") {
return "webui"
} else if (x.modelType == "onnxRVC" || x.modelType == "onnxRVCNono") {
return "onnx"
} else {
return "unknown"
}
})()
const metadata = x.deprecated ? `[${index}] [deprecated version]` : `[${index}] [${f0str},${srstr},${embedstr},${typestr}]`
const tuning = `t:${x.defaultTune}`
const useIndex = x.indexFile != null && x.indexFile.length > 0 ? `i:true` : `i:false`
const defaultIndexRatio = `ir:${x.defaultIndexRatio}`
const defaultProtect = `p:${x.defaultProtect}`
const subMetadata = `(${tuning},${useIndex},${defaultIndexRatio},${defaultProtect})`
const displayName = `${metadata} ${x.name || filename} ${subMetadata}`
return (
<option key={index} value={index}>{displayName}</option>
)
}).filter(x => { return x != null }) as React.JSX.Element[]
}
const selectedTermOfUseUrl = modelSlots ? modelSlots[slot]?.termsOfUseUrl || null : null
const selectedTermOfUseUrlLink = selectedTermOfUseUrl ? <a href={selectedTermOfUseUrl} target="_blank" rel="noopener noreferrer" className="body-item-text-small">[terms of use]</a> : <></>
return (
<>
<div className="body-row split-3-4-3 left-padding-1 guided">
<div className="body-item-title left-padding-1">Switch Model</div>
<div className="body-input-container">
<select className="body-select" value={slot} onChange={(e) => {
onSwitchModelClicked(Number(e.target.value))
}}>
{options}
</select>
{selectedTermOfUseUrlLink}
</div>
<div className="body-button-container">
<div className="body-button" onClick={onUpdateDefaultClicked}>update default</div>
</div>
</div>
</>
)
}, [appState.getInfo, appState.serverSetting.serverSetting])
return modelSwitchRow
}

View File

@ -1,67 +0,0 @@
import { OnnxExporterInfo } from "@dannadori/voice-changer-client-js"
import React, { useMemo } from "react"
import { useAppState } from "../../../001_provider/001_AppStateProvider"
import { useGuiState } from "../001_GuiStateProvider"
export type ONNXExportRowProps = {
}
export const ONNXExportRow = (_props: ONNXExportRowProps) => {
const appState = useAppState()
const guiState = useGuiState()
const onnxExporthRow = useMemo(() => {
const onnxExportButtonAction = async () => {
if (guiState.isConverting) {
alert("cannot export onnx when voice conversion is enabled")
return
}
document.getElementById("dialog")?.classList.add("dialog-container-show")
guiState.stateControls.showWaitingCheckbox.updateState(true)
const res = await appState.serverSetting.getOnnx() as OnnxExporterInfo
const a = document.createElement("a")
a.href = res.path
a.download = res.filename;
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
guiState.stateControls.showWaitingCheckbox.updateState(false)
}
const onDownloadClicked = () => {
const slot = appState.serverSetting.serverSetting.modelSlotIndex
const model = appState.serverSetting.serverSetting.modelSlots[slot]
const a = document.createElement("a")
a.href = model.modelFile
a.download = a.href.replace(/^.*[\\\/]/, '');
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
guiState.stateControls.showWaitingCheckbox.updateState(false)
}
const exportOnnx = appState.serverSetting.serverSetting.framework == "PyTorch" ? (
<div className="body-button left-margin-1" onClick={onnxExportButtonAction}>export onnx</div>
) : <></>
return (
<>
<div className="body-row split-3-7 left-padding-1 guided">
<div className="body-item-title left-padding-1">Export ONNX</div>
<div className="body-button-container">
{exportOnnx}
<div className="body-button left-margin-1" onClick={() => {
onDownloadClicked()
}}>download</div>
</div>
</div>
</>
)
}, [appState.getInfo, appState.serverSetting.serverSetting])
return onnxExporthRow
}

View File

@ -1,42 +0,0 @@
import { OnnxExecutionProvider } from "@dannadori/voice-changer-client-js"
import React, { useMemo } from "react"
import { useAppState } from "../../../001_provider/001_AppStateProvider"
export type ONNXExecutorRowProps = {
}
export const ONNXExecutorRow = (_props: ONNXExecutorRowProps) => {
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.getInfo, appState.serverSetting.serverSetting])
return onnxExecutorRow
}

View File

@ -1,94 +0,0 @@
import { OnnxExporterInfo } from "@dannadori/voice-changer-client-js"
import React, { useMemo } from "react"
import { useAppState } from "../../../001_provider/001_AppStateProvider"
import { useGuiState } from "../001_GuiStateProvider"
export type ServerOpertationRowProps = {
showDownload: boolean
showExportOnnx: boolean
showReload: boolean
}
export const ServerOpertationRow = (props: ServerOpertationRowProps) => {
const appState = useAppState()
const guiState = useGuiState()
const serverOpertationRow = useMemo(() => {
const onnxExportButtonAction = async () => {
if (guiState.isConverting) {
alert("cannot export onnx when voice conversion is enabled")
return
}
document.getElementById("dialog")?.classList.add("dialog-container-show")
guiState.stateControls.showWaitingCheckbox.updateState(true)
const res = await appState.serverSetting.getOnnx() as OnnxExporterInfo
const a = document.createElement("a")
a.href = res.path
a.download = res.filename;
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
guiState.stateControls.showWaitingCheckbox.updateState(false)
}
const onDownloadClicked = () => {
const slot = appState.serverSetting.serverSetting.modelSlotIndex
const model = appState.serverSetting.serverSetting.modelSlots[slot]
const a = document.createElement("a")
a.href = model.modelFile
a.download = a.href.replace(/^.*[\\\/]/, '');
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
}
const onModelSlotEditClicked = () => {
guiState.stateControls.showModelSlotManagerCheckbox.updateState(true)
}
const onReloadClicked = async () => {
const info = await appState.getInfo()
console.log("info", info)
}
const exportOnnx = (
appState.serverSetting.serverSetting.framework == "PyTorch" &&
props.showExportOnnx == true ? <div className="body-button left-margin-1" onClick={onnxExportButtonAction}>export onnx</div> : <></>
)
const download = (
props.showDownload ? <div className="body-button left-margin-1" onClick={() => {
onDownloadClicked()
}}>download</div> : <></>
)
const edit = (
props.showDownload ? <div className="body-button left-margin-1" onClick={() => {
onModelSlotEditClicked()
}}>edit</div> : <></>
)
const reload = (
props.showReload ? <div className="body-button-container">
<div className="body-button" onClick={onReloadClicked}>reload</div>
</div> : <></>
)
return (
<>
<div className="body-row split-3-7 left-padding-1 guided">
<div className="body-item-title left-padding-1">Operation</div>
<div className="body-button-container">
{exportOnnx}
{download}
{edit}
{reload}
</div>
</div>
</>
)
}, [appState.getInfo, appState.serverSetting.serverSetting, guiState.isConverting])
return serverOpertationRow
}

View File

@ -1,104 +0,0 @@
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"
export type CommonFileSelectRowProps = {
title: string
acceptExtentions: string[]
fileKind: Filekinds
}
export const Filekinds = {
"mmvcv13Config": "mmvcv13Config",
"mmvcv13Model": "mmvcv13Model",
"mmvcv15Config": "mmvcv15Config",
"mmvcv15Model": "mmvcv15Model",
"soVitsSvc40Config": "soVitsSvc40Config",
"soVitsSvc40Model": "soVitsSvc40Model",
"soVitsSvc40Cluster": "soVitsSvc40Cluster",
"soVitsSvc40v2Config": "soVitsSvc40v2Config",
"soVitsSvc40v2Model": "soVitsSvc40v2Model",
"soVitsSvc40v2Cluster": "soVitsSvc40v2Cluster",
"rvcModel": "rvcModel",
"rvcFeature": "rvcFeature",
"rvcIndex": "rvcIndex",
"ddspSvcModel": "ddspSvcModel",
"ddspSvcModelConfig": "ddspSvcModelConfig",
"ddspSvcDiffusion": "ddspSvcDiffusion",
"ddspSvcDiffusionConfig": "ddspSvcDiffusionConfig",
} as const
export type Filekinds = typeof Filekinds[keyof typeof Filekinds]
export const CommonFileSelectRow = (props: CommonFileSelectRowProps) => {
const appState = useAppState()
const guiState = useGuiState()
const commonFileSelectRow = useMemo(() => {
const slot = guiState.modelSlotNum
if (!appState.serverSetting.fileUploadSettings[slot]) {
return <></>
}
if (appState.serverSetting.fileUploadSettings[slot].isSampleMode == true) {
return <></>
}
const getTargetModelData = () => {
const targetSlot = appState.serverSetting.fileUploadSettings[slot]
if (!targetSlot) {
return null
}
return targetSlot[props.fileKind]
}
const targetModel = getTargetModelData()
const filenameText = targetModel?.filename || targetModel?.file?.name || ""
const checkExtention = (filename: string) => {
const ext = filename.split('.').pop();
if (!ext) {
return false
}
return props.acceptExtentions.includes(ext)
}
const onFileLoadClicked = async () => {
const file = await fileSelector("")
if (checkExtention(file.name) == false) {
alert(`モデルファイルの拡張子は${props.acceptExtentions}である必要があります。`)
return
}
appState.serverSetting.fileUploadSettings[slot][props.fileKind]! = { file: file }
appState.serverSetting.fileUploadSettings[slot].sampleId = null
appState.serverSetting.setFileUploadSetting(slot, {
...appState.serverSetting.fileUploadSettings[slot]
})
}
const onFileClearClicked = () => {
appState.serverSetting.fileUploadSettings[slot][props.fileKind] = null
appState.serverSetting.fileUploadSettings[slot].sampleId = null
appState.serverSetting.setFileUploadSetting(slot, {
...appState.serverSetting.fileUploadSettings[slot],
})
}
return (
<div className="body-row split-3-3-4 left-padding-1 guided">
<div className="body-item-title left-padding-2">{props.title}</div>
<div className="body-item-text">
<div>{filenameText}</div>
</div>
<div className="body-button-container">
<div className="body-button" onClick={onFileLoadClicked}>select</div>
<div className="body-button left-margin-1" onClick={onFileClearClicked}>clear</div>
</div>
</div>
)
}, [appState.serverSetting.fileUploadSettings, appState.serverSetting.setFileUploadSetting, appState.serverSetting.serverSetting, appState.serverSetting.updateServerSettings, guiState.modelSlotNum])
return commonFileSelectRow
}

View File

@ -1,52 +0,0 @@
import React, { useMemo } from "react"
import { useAppState } from "../../../001_provider/001_AppStateProvider"
import { useGuiState } from "../001_GuiStateProvider"
export type ModelUploadButtonRow2Props = {
}
export const ModelUploadButtonRow2 = (_props: ModelUploadButtonRow2Props) => {
const appState = useAppState()
const guiState = useGuiState()
const modelUploadButtonRow = useMemo(() => {
const slot = guiState.modelSlotNum
if (!appState.serverSetting.fileUploadSettings[slot]) {
return <></>
}
const onModelUploadClicked = async () => {
try {
await appState.serverSetting.loadModel(slot)
} catch (e) {
console.log(e)
alert(e)
}
}
const buttonText = appState.serverSetting.fileUploadSettings[slot].isSampleMode ? "select" : "upload"
const uploadButtonClassName = appState.serverSetting.isUploading ? "body-button-disabled" : "body-button"
const uploadButtonAction = appState.serverSetting.isUploading ? () => { } : onModelUploadClicked
const uploadButtonLabel = appState.serverSetting.isUploading ? "wait..." : buttonText
const uploadingStatus = appState.serverSetting.isUploading ?
appState.serverSetting.uploadProgress == 0 ? `loading model...(wait about 20sec)` : `processing.... ${appState.serverSetting.uploadProgress.toFixed(1)}%` : ""
const uploadedText = appState.serverSetting.fileUploadSettings[slot] == undefined ? "" : appState.serverSetting.fileUploadSettings[slot].uploaded ? "" : "not uploaded"
return (
<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 className="body-item-text-em" >{uploadedText}</div>
</div>
</div>
)
}, [appState.serverSetting.isUploading, appState.serverSetting.uploadProgress, appState.serverSetting.loadModel, guiState.modelSlotNum, appState.serverSetting.fileUploadSettings])
return modelUploadButtonRow
}

View File

@ -1,56 +0,0 @@
import React, { useMemo } from "react"
import { fileSelector, Correspondence } from "@dannadori/voice-changer-client-js"
import { useAppState } from "../../../001_provider/001_AppStateProvider"
export type CorrespondenceSelectRow2Props = {
}
export const CorrespondenceSelectRow2 = (_props: CorrespondenceSelectRow2Props) => {
const appState = useAppState()
const CorrespondenceSelectRow = useMemo(() => {
const correspondenceFileText = appState.clientSetting.clientSetting.correspondences ? JSON.stringify(appState.clientSetting.clientSetting.correspondences.map(x => { return x.dirname })) : ""
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("recogninzed corresponding lines:", cors)
appState.clientSetting.updateClientSetting({ ...appState.clientSetting.clientSetting, correspondences: cors })
}
const onCorrespondenceFileClearClicked = () => {
appState.clientSetting.updateClientSetting({ ...appState.clientSetting.clientSetting, correspondences: [] })
}
return (
<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>
)
}, [appState.clientSetting.clientSetting, appState.clientSetting.updateClientSetting])
return CorrespondenceSelectRow
}

View File

@ -1,57 +0,0 @@
import { MAX_MODEL_SLOT_NUM } from "@dannadori/voice-changer-client-js"
import React, { useMemo } from "react"
import { useGuiState } from "../001_GuiStateProvider"
import { useAppState } from "../../../001_provider/001_AppStateProvider"
export type ModelSlotRow2Props = {}
export const ModelSlotRow2 = (_prop: ModelSlotRow2Props) => {
const guiState = useGuiState()
const appState = useAppState()
const modelSlotRow = useMemo(() => {
const slot = guiState.modelSlotNum
if (!appState.serverSetting.fileUploadSettings[slot]) {
return <></>
}
const onModelSlotChanged = (val: number) => {
guiState.setModelSlotNum(val)
}
const onModeChanged = (val: boolean) => {
appState.serverSetting.fileUploadSettings[slot].isSampleMode = val
appState.serverSetting.setFileUploadSetting(slot, {
...appState.serverSetting.fileUploadSettings[slot],
})
}
const isSampleMode = appState.serverSetting.fileUploadSettings[slot].isSampleMode
return (
<div className="body-row split-3-3-4 left-padding-1 guided">
<div className="body-item-title left-padding-2">Model Slot</div>
<div className="body-input-container">
<select value={slot} onChange={(e) => { onModelSlotChanged(Number(e.target.value)) }}>
{Array(MAX_MODEL_SLOT_NUM).fill(0).map((_x, index) => {
return <option key={index} value={index} >{index}</option>
})}
</select>
<div className="left-padding-1">
<input className="left-padding-1" type="radio" id="from-file" name="sample-mode" checked={isSampleMode == false} onChange={() => { onModeChanged(false) }} />
<label className="left-padding-05" htmlFor="from-file">file</label>
</div>
<div className="left-padding-1">
<input className="left-padding-1" type="radio" id="from-net" name="sample-mode" checked={isSampleMode == true} onChange={() => { onModeChanged(true) }} />
<label className="left-padding-05" htmlFor="from-net">from net</label>
</div>
</div>
<div></div>
</div>
)
}, [guiState.modelSlotNum, appState.serverSetting.fileUploadSettings])
return modelSlotRow
}

View File

@ -1,43 +0,0 @@
import React, { useMemo } from "react"
import { useAppState } from "../../../001_provider/001_AppStateProvider"
import { useGuiState } from "../001_GuiStateProvider"
export type DefaultTuneRow2Props = {}
export const DefaultTuneRow2 = (_props: DefaultTuneRow2Props) => {
const appState = useAppState()
const guiState = useGuiState()
const defaultTuneRow = useMemo(() => {
const slot = guiState.modelSlotNum
const fileUploadSetting = appState.serverSetting.fileUploadSettings[slot]
if (!fileUploadSetting) {
return <></>
}
const currentValue = fileUploadSetting.defaultTune
const onDefaultTuneChanged = (val: number) => {
appState.serverSetting.setFileUploadSetting(slot, {
...appState.serverSetting.fileUploadSettings[slot],
defaultTune: val,
})
}
return (
<div className="body-row split-3-2-1-4 left-padding-1 guided">
<div className="body-item-title left-padding-2 ">Default Tune</div>
<div>
<input type="range" className="body-item-input-slider" min="-50" max="50" step="1" value={currentValue} onChange={(e) => {
onDefaultTuneChanged(Number(e.target.value))
}}></input>
<span className="body-item-input-slider-val">{currentValue}</span>
</div>
<div>
</div>
<div className="body-button-container">
</div>
</div>
)
}, [appState.serverSetting.fileUploadSettings, guiState.modelSlotNum])
return defaultTuneRow
}

View File

@ -1,71 +0,0 @@
import React, { useMemo, useState } from "react"
import { useAppState } from "../../../001_provider/001_AppStateProvider"
import { useGuiState } from "../001_GuiStateProvider"
export type SampleModelSelectRowProps = {}
export const SampleModelSelectRow = (_props: SampleModelSelectRowProps) => {
const appState = useAppState()
const guiState = useGuiState()
const [lang, setLang] = useState<string>("All")
const sampleModelSelectRow = useMemo(() => {
const slot = guiState.modelSlotNum
const fileUploadSetting = appState.serverSetting.fileUploadSettings[slot]
if (!fileUploadSetting) {
return <></>
}
if (fileUploadSetting.isSampleMode == false) {
return <></>
}
const langs = appState.serverSetting.serverSetting.sampleModels.reduce((prev, cur) => {
if (prev.includes(cur.lang) == false) {
prev.push(cur.lang)
}
return prev
}, ["All"] as string[])
const langOptions = (
langs.map(x => {
return <option key={x} value={x}>{x}</option>
})
)
const options = (
appState.serverSetting.serverSetting.sampleModels.filter(x => { return lang == "All" ? true : x.lang == lang }).map(x => {
return <option key={x.id} value={x.id}>{x.name}</option>
})
)
const selectedSample = appState.serverSetting.serverSetting.sampleModels.find(x => { return x.id == fileUploadSetting.sampleId })
const creditText = selectedSample ? `credit:${selectedSample.credit}` : ""
const termOfUseLink = selectedSample ? <a href={selectedSample.termsOfUseUrl} target="_blank" rel="noopener noreferrer" className="body-item-text-small">[terms of use]</a> : <></>
const onModelSelected = (val: string) => {
appState.serverSetting.setFileUploadSetting(slot, {
...appState.serverSetting.fileUploadSettings[slot], sampleId: val
})
}
return (
<div className="body-row split-3-3-4 left-padding-1 guided">
<div className="body-item-title left-padding-2 ">Select Model</div>
<div>
<select value={lang} onChange={(e) => { setLang(e.target.value) }}>
{langOptions}
</select>
<select value={fileUploadSetting.sampleId || ""} onChange={(e) => { onModelSelected(e.target.value) }}>
<option disabled value={""}> -- select model -- </option>
{options}
</select>
</div>
<div className="body-item-text">
{creditText}{termOfUseLink}
</div>
</div>
)
}, [appState.serverSetting.fileUploadSettings, guiState.modelSlotNum, lang])
return sampleModelSelectRow
}

View File

@ -1,36 +0,0 @@
import React, { useMemo, useState } from "react"
import { useAppState } from "../../../001_provider/001_AppStateProvider"
import { useGuiState } from "../001_GuiStateProvider"
export type SampleDownloadControlRowProps = {}
export const SampleDownloadControlRow = (_props: SampleDownloadControlRowProps) => {
const appState = useAppState()
const guiState = useGuiState()
const sampleDownloadControlRow = useMemo(() => {
const slot = guiState.modelSlotNum
const fileUploadSetting = appState.serverSetting.fileUploadSettings[slot]
if (!fileUploadSetting) {
return <></>
}
if (fileUploadSetting.isSampleMode == false) {
return <></>
}
return (
<div className="body-row split-3-3-4 left-padding-1 guided">
<div className="body-item-title left-padding-2 ">Advanced Configuration</div>
<div>
<input type="checkbox" checked={fileUploadSetting.rvcIndexDownload} onChange={(e) => {
appState.serverSetting.setFileUploadSetting(slot, { ...fileUploadSetting, rvcIndexDownload: e.target.checked })
}} /> useIndex
</div>
<div className="body-button-container">
</div>
</div>
)
}, [appState.serverSetting.fileUploadSettings, appState.serverSetting.setFileUploadSetting])
return sampleDownloadControlRow
}

View File

@ -1,24 +0,0 @@
import React, { useMemo } from "react"
import { useGuiState } from "../001_GuiStateProvider"
export type ModelUploaderRowv2Props = {}
export const ModelUploaderRowv2 = (_props: ModelUploaderRowv2Props) => {
const guiState = useGuiState()
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>
</div>
)
}, [guiState.showPyTorchModelUpload])
return modelUploaderRow
}

View File

@ -1,77 +0,0 @@
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}
</>
)
}

View File

@ -1,46 +0,0 @@
import React, { useMemo } from "react"
import { ModelSamplingRate } from "@dannadori/voice-changer-client-js"
import { useAppState } from "../../../001_provider/001_AppStateProvider"
export type ModelSamplingRateRowProps = {
}
export const ModelSamplingRateRow = (_props: ModelSamplingRateRowProps) => {
const appState = useAppState()
const modelSamplingRateRow = useMemo(() => {
if (appState.serverSetting.serverSetting.framework != "ONNX") {
return <></>
}
const onModelSamplingRateChanged = (val: ModelSamplingRate) => {
appState.serverSetting.updateServerSettings({
...appState.serverSetting.serverSetting,
modelSamplingRate: val
})
}
return (
<div className="body-row split-3-3-4 left-padding-1 guided">
<div className="body-item-title left-padding-2">Model Sampling Rate</div>
<div className="body-button-container">
<select className="body-select" value={appState.serverSetting.serverSetting.modelSamplingRate} onChange={(e) => {
onModelSamplingRateChanged(e.target.value as unknown as ModelSamplingRate)
}}>
{
Object.values(ModelSamplingRate).map(x => {
return <option key={x} value={x}>{x}</option>
})
}
</select>
</div>
<div className="body-item-text">
<div></div>
</div>
</div>
)
}, [appState.serverSetting.serverSetting, appState.serverSetting.updateServerSettings])
return modelSamplingRateRow
}

View File

@ -1,56 +0,0 @@
//////////////////////////
// currently not used //
//////////////////////////
import React, { useMemo } from "react"
// import { useAppState } from "../../../001_provider/001_AppStateProvider"
// import { OnnxExporterInfo } from "@dannadori/voice-changer-client-js";
// import { useGuiState } from "../001_GuiStateProvider";
// export type OnnxExportRowProps = {
// }
// export const OnnxExportRow = (_props: OnnxExportRowProps) => {
// const appState = useAppState()
// const guiState = useGuiState()
// const onnxExportRow = useMemo(() => {
// const onnxExportButtonAction = async () => {
// if (guiState.isConverting) {
// alert("cannot export onnx when voice conversion is enabled")
// return
// }
// document.getElementById("dialog")?.classList.add("dialog-container-show")
// guiState.stateControls.showWaitingCheckbox.updateState(true)
// const res = await appState.serverSetting.getOnnx() as OnnxExporterInfo
// const a = document.createElement("a")
// a.href = res.path
// a.download = res.filename;
// document.body.appendChild(a);
// a.click();
// document.body.removeChild(a);
// guiState.stateControls.showWaitingCheckbox.updateState(false)
// }
// const onnxExportButtonClassName = "body-button"
// const onnxExportButtonLabel = "onnx export"
// return (
// <div className="body-row split-3-3-4 left-padding-1 guided">
// <div className="body-item-title left-padding-2">Onnx Exporter</div>
// <div className="body-item-text">
// <div></div>
// </div>
// <div className="body-button-container">
// <div className={onnxExportButtonClassName} onClick={onnxExportButtonAction}>{onnxExportButtonLabel}</div>
// </div>
// </div>
// )
// }, [appState.serverSetting.serverSetting, appState.serverSetting.updateServerSettings, guiState.isConverting])
// return onnxExportRow
// }

View File

@ -1,89 +0,0 @@
import React, { useMemo, useEffect, useRef } from "react"
import { fileSelectorAsDataURL } from "@dannadori/voice-changer-client-js"
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()
const guiState = useGuiState()
const audioSrcNode = useRef<MediaElementAudioSourceNode>()
useEffect(() => {
[AUDIO_ELEMENT_FOR_TEST_CONVERTED_ECHOBACK].forEach(x => {
const audio = document.getElementById(x) as HTMLAudioElement
if (audio) {
audio.volume = guiState.fileInputEchoback ? 1 : 0
}
})
}, [guiState.fileInputEchoback])
const audioInputMediaRow = useMemo(() => {
if (guiState.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)
try {
appState.clientSetting.updateClientSetting({ ...appState.clientSetting.clientSetting, audioInput: dst.stream })
} catch (e) {
console.error(e)
}
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
guiState.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={guiState.fileInputEchoback} onChange={(e) => { guiState.setFileInputEchoback(e.target.checked) }} /> echoback
</div>
</div>
)
}, [guiState.audioInputForGUI, guiState.fileInputEchoback])
return audioInputMediaRow
}

View File

@ -1,101 +0,0 @@
import React, { useMemo, useEffect, useState } from "react"
import { useAppState } from "../../../001_provider/001_AppStateProvider"
import { useGuiState } from "../001_GuiStateProvider"
import { AudioInputMediaRow } from "./401-1_AudioInputMediaRow"
export type AudioInputRowProps = {
}
export const AudioInputRow = (_props: AudioInputRowProps) => {
const appState = useAppState()
const guiState = useGuiState()
const [hostApi, setHostApi] = useState<string>("")
// キャッシュの設定は反映(たぶん、設定操作の時も起動していしまう。が問題は起こらないはず)
useEffect(() => {
if (typeof appState.clientSetting.clientSetting.audioInput == "string") {
if (guiState.inputAudioDeviceInfo.find(x => {
// console.log("COMPARE:", x.deviceId, appState.clientSetting.setting.audioInput)
return x.deviceId == appState.clientSetting.clientSetting.audioInput
})) {
guiState.setAudioInputForGUI(appState.clientSetting.clientSetting.audioInput)
}
}
}, [guiState.inputAudioDeviceInfo, appState.clientSetting.clientSetting.audioInput])
const audioInputRow = useMemo(() => {
if (appState.serverSetting.serverSetting.enableServerAudio == 1) {
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={guiState.audioInputForGUI} onChange={(e) => {
guiState.setAudioInputForGUI(e.target.value)
if (guiState.audioInputForGUI != "file") {
try {
appState.clientSetting.updateClientSetting({ ...appState.clientSetting.clientSetting, audioInput: e.target.value })
} catch (e) {
console.error(e)
}
}
}}>
{
guiState.inputAudioDeviceInfo.map(x => {
return <option key={x.deviceId} value={x.deviceId}>{x.label}</option>
})
}
</select>
</div>
</div>
)
}, [guiState.inputAudioDeviceInfo, guiState.audioInputForGUI, appState.clientSetting.clientSetting, appState.clientSetting.updateClientSetting, appState.serverSetting.serverSetting.enableServerAudio])
const serverAudioInputRow = useMemo(() => {
if (appState.serverSetting.serverSetting.enableServerAudio == 0) {
return <></>
}
const devices = appState.serverSetting.serverSetting.serverAudioInputDevices
const hostAPIs = new Set(devices.map(x => { return x.hostAPI }))
const hostAPIOptions = Array.from(hostAPIs).map((x, index) => { return <option value={x} key={index} >{x}</option> })
const filteredDevice = devices.map((x, index) => {
const className = (x.hostAPI == hostApi || hostApi == "") ? "select-option-red" : ""
return <option className={className} value={x.index} key={index}>[{x.hostAPI}]{x.name}</option>
})
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">
<div className="body-select-container">
<select name="kinds" id="kinds" value={hostApi} onChange={(e) => { setHostApi(e.target.value) }}>
{hostAPIOptions}
</select>
<select className="body-select" value={appState.serverSetting.serverSetting.serverInputDeviceId} onChange={(e) => {
appState.serverSetting.updateServerSettings({ ...appState.serverSetting.serverSetting, serverInputDeviceId: Number(e.target.value) })
}}>
{filteredDevice}
</select>
</div>
</div>
</div>
)
}, [hostApi, appState.serverSetting.serverSetting, appState.serverSetting.updateServerSettings])
return (
<>
{audioInputRow}
<AudioInputMediaRow />
{serverAudioInputRow}
</>
)
}

View File

@ -1,83 +0,0 @@
import React, { useMemo, useState } from "react"
import { useAppState } from "../../../001_provider/001_AppStateProvider"
import { useGuiState } from "../001_GuiStateProvider"
export const AudioOutputRecordRow = () => {
const appState = useAppState()
const guiState = useGuiState()
const [outputRecordingStarted, setOutputRecordingStarted] = useState<boolean>(false)
const audioOutputRecordRow = useMemo(() => {
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>
)
}, [guiState.audioOutputForGUI, outputRecordingStarted, appState.workletNodeSetting.startOutputRecording, appState.workletNodeSetting.stopOutputRecording])
return audioOutputRecordRow
}
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);
}

View File

@ -1,145 +0,0 @@
import React, { useMemo, useEffect, useState } from "react"
import { useIndexedDB } from "@dannadori/voice-changer-client-js"
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 type AudioOutputRowProps = {
}
export const AudioOutputRow = (_props: AudioOutputRowProps) => {
const { setAudioOutputElementId, initializedRef } = useAppState()
const appState = useAppState()
const guiState = useGuiState()
const { appGuiSettingState } = useAppRoot()
const clientType = appGuiSettingState.appGuiSetting.id
const { getItem, setItem } = useIndexedDB({ clientType: clientType })
const [hostApi, setHostApi] = useState<string>("")
useEffect(() => {
const loadCache = async () => {
const key = await getItem(INDEXEDDB_KEY_AUDIO_OUTPUT)
if (key) {
guiState.setAudioOutputForGUI(key as string)
}
}
loadCache()
}, [])
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 (appState.serverSetting.serverSetting.enableServerAudio == 1) {
// Server Audio を使う場合はElementから音は出さない。
audio.volume = 0
} else if (guiState.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 == guiState.audioOutputForGUI })
if (found) {
// @ts-ignore // 例外キャッチできないので事前にIDチェックが必要らしい。
audio.setSinkId(guiState.audioOutputForGUI)
} else {
console.warn("No audio output device. use default")
}
if (x == AUDIO_ELEMENT_FOR_TEST_CONVERTED_ECHOBACK) {
audio.volume = guiState.fileInputEchoback ? 1 : 0
} else {
audio.volume = 1
}
}
}
})
}
setAudioOutput()
}, [guiState.audioOutputForGUI, guiState.fileInputEchoback, appState.serverSetting.serverSetting.enableServerAudio])
const audioOutputRow = useMemo(() => {
if (appState.serverSetting.serverSetting.enableServerAudio == 1) {
return <></>
}
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={guiState.audioOutputForGUI} onChange={(e) => {
guiState.setAudioOutputForGUI(e.target.value)
setItem(INDEXEDDB_KEY_AUDIO_OUTPUT, e.target.value)
}}>
{
guiState.outputAudioDeviceInfo.map(x => {
return <option key={x.deviceId} value={x.deviceId}>{x.label}</option>
})
}
</select>
</div>
</div>
)
}, [appState.serverSetting.serverSetting.enableServerAudio, guiState.outputAudioDeviceInfo, guiState.audioOutputForGUI])
useEffect(() => {
setAudioOutputElementId(AUDIO_ELEMENT_FOR_PLAY_RESULT)
}, [initializedRef.current])
const serverAudioOutputRow = useMemo(() => {
if (appState.serverSetting.serverSetting.enableServerAudio == 0) {
return <></>
}
const devices = appState.serverSetting.serverSetting.serverAudioOutputDevices
const hostAPIs = new Set(devices.map(x => { return x.hostAPI }))
const hostAPIOptions = Array.from(hostAPIs).map((x, index) => { return <option value={x} key={index} >{x}</option> })
// const filteredDevice = devices.filter(x => { return x.hostAPI == hostApi || hostApi == "" }).map((x, index) => { return <option value={x.index} key={index}>{x.name}</option> })
const filteredDevice = devices.map((x, index) => {
const className = (x.hostAPI == hostApi || hostApi == "") ? "select-option-red" : ""
return <option className={className} value={x.index} key={index}>[{x.hostAPI}]{x.name}</option>
})
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">
<div className="body-select-container">
<select name="kinds" id="kinds" value={hostApi} onChange={(e) => { setHostApi(e.target.value) }}>
{hostAPIOptions}
</select>
<select className="body-select" value={appState.serverSetting.serverSetting.serverOutputDeviceId} onChange={(e) => {
appState.serverSetting.updateServerSettings({ ...appState.serverSetting.serverSetting, serverOutputDeviceId: Number(e.target.value) })
}}>
{filteredDevice}
</select>
</div>
</div>
</div>
)
}, [hostApi, appState.serverSetting.serverSetting, appState.serverSetting.updateServerSettings])
return (
<>
{audioOutputRow}
{appState.serverSetting.serverSetting.enableServerAudio == 0 ? <AudioOutputRecordRow /> : <></>}
{serverAudioOutputRow}
<audio hidden id={AUDIO_ELEMENT_FOR_PLAY_RESULT}></audio>
</>
)
}

View File

@ -1,50 +0,0 @@
import React, { useMemo } from "react"
import { useAppState } from "../../../001_provider/001_AppStateProvider"
import { useGuiState } from "../001_GuiStateProvider"
export type AudioDeviceModeRowProps = {
}
export const AudioDeviceModeRow = (_props: AudioDeviceModeRowProps) => {
const appState = useAppState()
const guiState = useGuiState()
const serverAudioInputRow = useMemo(() => {
const enableServerAudio = appState.serverSetting.serverSetting.enableServerAudio
const serverChecked = enableServerAudio == 1 ? true : false
const clientChecked = enableServerAudio == 1 ? false : true
const onDeviceModeChanged = (val: number) => {
if (guiState.isConverting) {
alert("cannot change mode when voice conversion is enabled")
return
}
appState.serverSetting.updateServerSettings({ ...appState.serverSetting.serverSetting, enableServerAudio: val })
}
return (
<div className="body-row split-3-3-4 left-padding-1 guided">
<div className="body-item-title left-padding-1">Device Mode</div>
<div className="body-input-container">
<div className="left-padding-1">
<input type="radio" id="client-device" name="device-mode" checked={clientChecked} onChange={() => { onDeviceModeChanged(0) }} />
<label htmlFor="client-device">client device</label>
</div>
<div className="left-padding-1">
<input className="left-padding-1" type="radio" id="server-device" name="device-mode" checked={serverChecked} onChange={() => { onDeviceModeChanged(1) }} />
<label htmlFor="server-device">server device(exp.)</label>
</div>
</div>
<div></div>
</div>
)
}, [appState.serverSetting.serverSetting, appState.serverSetting.updateServerSettings, guiState.isConverting])
return (
<>
{serverAudioInputRow}
</>
)
}

View File

@ -1,56 +0,0 @@
import React, { useMemo } from "react"
import { useAppState } from "../../../001_provider/001_AppStateProvider"
export type IOBufferRowProps = {
}
export const IOBufferRow = (_props: IOBufferRowProps) => {
const appState = useAppState()
const ioBufferRow = useMemo(() => {
if (appState.serverSetting.serverSetting.enableServerAudio == 0) {
return <></>
}
const readBuf = appState.serverSetting.serverSetting.serverInputAudioBufferSize
const writeBuf = appState.serverSetting.serverSetting.serverOutputAudioBufferSize
return (
<div className="body-row split-3-3-4 left-padding-1 guided">
<div className="body-item-title left-padding-1">I/O Buffer</div>
<div className="body-input-container">
<div className="left-padding-1">
In:
<select className="body-select" value={readBuf} onChange={(e) => {
appState.serverSetting.updateServerSettings({ ...appState.serverSetting.serverSetting, serverInputAudioBufferSize: Number(e.target.value) })
appState.workletNodeSetting.trancateBuffer()
}}>
{
[1024 * 4, 1024 * 8, 1024 * 12, 1024 * 16, 1024 * 24, 1024 * 32].map(x => {
return <option key={x} value={x}>{x}</option>
})
}
</select>
</div>
<div className="left-padding-1">
Out:
<select className="body-select" value={writeBuf} onChange={(e) => {
appState.serverSetting.updateServerSettings({ ...appState.serverSetting.serverSetting, serverOutputAudioBufferSize: Number(e.target.value) })
appState.workletNodeSetting.trancateBuffer()
}}>
{
[1024 * 4, 1024 * 8, 1024 * 12, 1024 * 16, 1024 * 24, 1024 * 32].map(x => {
return <option key={x} value={x}>{x}</option>
})
}
</select>
</div>
</div>
<div className="body-item-text"></div>
</div>
)
}, [appState.serverSetting.serverSetting, appState.serverSetting.updateServerSettings])
return ioBufferRow
}

View File

@ -1,54 +0,0 @@
import React, { useMemo } from "react"
import { useAppState } from "../../../001_provider/001_AppStateProvider"
export type NoiseControlRowProps = {
}
export const NoiseControlRow = (_props: NoiseControlRowProps) => {
const appState = useAppState()
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) => {
try {
appState.clientSetting.updateClientSetting({ ...appState.clientSetting.clientSetting, echoCancel: e.target.checked })
} catch (e) {
console.error(e)
}
}} /> echo cancel
</div>
<div>
<input type="checkbox" checked={appState.clientSetting.clientSetting.noiseSuppression} onChange={(e) => {
try {
appState.clientSetting.updateClientSetting({ ...appState.clientSetting.clientSetting, noiseSuppression: e.target.checked })
} catch (e) {
console.error(e)
}
}} /> suppression1
</div>
<div>
<input type="checkbox" checked={appState.clientSetting.clientSetting.noiseSuppression2} onChange={(e) => {
try {
appState.clientSetting.updateClientSetting({ ...appState.clientSetting.clientSetting, noiseSuppression2: e.target.checked })
} catch (e) {
console.error(e)
}
}} /> suppression2
</div>
<div className="body-button-container">
</div>
</div>
)
}, [
appState.clientSetting.clientSetting.echoCancel,
appState.clientSetting.clientSetting.noiseSuppression,
appState.clientSetting.clientSetting.noiseSuppression2,
appState.clientSetting.updateClientSetting
])
return noiseControlRow
}

View File

@ -1,84 +0,0 @@
import React, { useMemo } from "react"
import { useAppState } from "../../../001_provider/001_AppStateProvider"
export type GainControlRowProps = {
}
export const GainControlRow = (_props: GainControlRowProps) => {
const appState = useAppState()
const gainControlRow = useMemo(() => {
if (appState.serverSetting.serverSetting.enableServerAudio == 1) {
return <></>
}
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.1" max="10.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.1" max="10.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,
appState.serverSetting.serverSetting.enableServerAudio
])
const serverGainControlRow = useMemo(() => {
if (appState.serverSetting.serverSetting.enableServerAudio == 0) {
return <></>
}
return (
<div className="body-row split-3-2-2-3 left-padding-1 guided">
<div className="body-item-title left-padding-1 ">Server Gain Control</div>
<div>
<span className="body-item-input-slider-label">in</span>
<input type="range" className="body-item-input-slider" min="0.1" max="10.0" step="0.1" value={appState.serverSetting.serverSetting.serverInputAudioGain} onChange={(e) => {
appState.serverSetting.updateServerSettings({ ...appState.serverSetting.serverSetting, serverInputAudioGain: Number(e.target.value) })
}}></input>
<span className="body-item-input-slider-val">{appState.serverSetting.serverSetting.serverInputAudioGain}</span>
</div>
<div>
<span className="body-item-input-slider-label">out</span>
<input type="range" className="body-item-input-slider" min="0.1" max="10.0" step="0.1" value={appState.serverSetting.serverSetting.serverOutputAudioGain} onChange={(e) => {
appState.serverSetting.updateServerSettings({ ...appState.serverSetting.serverSetting, serverOutputAudioGain: Number(e.target.value) })
}}></input>
<span className="body-item-input-slider-val">{appState.serverSetting.serverSetting.serverOutputAudioGain}</span>
</div>
<div className="body-button-container">
</div>
</div>
)
}, [
appState.serverSetting.serverSetting.serverInputAudioGain,
appState.serverSetting.serverSetting.serverOutputAudioGain,
appState.serverSetting.updateServerSettings,
appState.serverSetting.serverSetting.enableServerAudio
])
return (
<>
{gainControlRow}
{serverGainControlRow}
</>
)
}

View File

@ -1,37 +0,0 @@
import React, { useMemo } from "react"
import { useAppState } from "../../../001_provider/001_AppStateProvider"
import { F0Detector } from "@dannadori/voice-changer-client-js";
export type F0DetectorRowProps = {
detectors: string[]
}
export const F0DetectorRow = (props: F0DetectorRowProps) => {
const appState = useAppState()
const f0DetectorRow = useMemo(() => {
const desc = { "harvest": "harvest(High Quality)", "dio": "dio/pm(Light Weight)" }
const detectors = props.detectors || ["dio", "harvest"]
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(detectors).map(x => {
//@ts-ignore
return <option key={x} value={x}>{x}</option>
})
}
</select>
</div>
</div>
)
}, [appState.serverSetting.serverSetting.f0Detector, appState.serverSetting.updateServerSettings])
return f0DetectorRow
}

View File

@ -1,54 +0,0 @@
import React, { useMemo, useState } from "react"
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 samplingRow = 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(AUDIO_ELEMENT_FOR_SAMPLING_INPUT) as HTMLAudioElement
wavInput.src = "/tmp/in.wav?" + new Date().getTime()
wavInput.controls = true
// @ts-ignore
wavInput.setSinkId(guiState.audioOutputForAnalyzer)
// set wav (output)
const wavOutput = document.getElementById(AUDIO_ELEMENT_FOR_SAMPLING_OUTPUT) as HTMLAudioElement
wavOutput.src = "/tmp/out.wav?" + new Date().getTime()
wavOutput.controls = true
// @ts-ignore
wavOutput.setSinkId(guiState.audioOutputForAnalyzer)
}
const startClassName = recording ? "body-button-active" : "body-button-stanby"
const stopClassName = recording ? "body-button-stanby" : "body-button-active"
return (
<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>
)
}, [recording, appState.serverSetting.serverSetting, appState.serverSetting.updateServerSettings, guiState.audioOutputForAnalyzer])
return samplingRow
}

View File

@ -1,52 +0,0 @@
import React, { useMemo } from "react"
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 samplingPlayRow = useMemo(() => {
return (
<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={guiState.audioOutputForAnalyzer} onChange={(e) => {
guiState.setAudioOutputForAnalyzer(e.target.value)
const wavInput = document.getElementById(AUDIO_ELEMENT_FOR_SAMPLING_INPUT) as HTMLAudioElement
const wavOutput = document.getElementById(AUDIO_ELEMENT_FOR_SAMPLING_OUTPUT) as HTMLAudioElement
//@ts-ignore
wavInput.setSinkId(e.target.value)
//@ts-ignore
wavOutput.setSinkId(e.target.value)
}}>
{
guiState.outputAudioDeviceInfo.map(x => {
if (x.deviceId == "none") {
return null
}
return <option key={x.deviceId} value={x.deviceId}>{x.label}</option>
}).filter(x => { return x != null })
}
</select>
</div>
<div>
<div className="body-wav-container-title">Input</div>
<div className="body-wav-container-wav">
<audio src="" id={AUDIO_ELEMENT_FOR_SAMPLING_INPUT}></audio>
</div>
</div>
<div >
<div className="body-wav-container-title">Output</div>
<div className="body-wav-container-wav" >
<audio src="" id={AUDIO_ELEMENT_FOR_SAMPLING_OUTPUT}></audio>
</div>
</div>
<div></div>
</div>
)
}, [guiState.audioOutputForAnalyzer, guiState.outputAudioDeviceInfo])
return samplingPlayRow
}

View File

@ -1,27 +0,0 @@
import React, { useMemo } from "react"
import { SamplingRow } from "./510-1_SamplingRow"
import { SamplingPlayRow } from "./510-2_SamplingPlayRow"
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</div>
<div className="body-button-container">
</div>
</div>
)
}, [])
return (
<>
{analyzerRow}
<SamplingRow />
<SamplingPlayRow />
</>
)
}

View File

@ -1,75 +0,0 @@
import React, { useMemo } from "react"
import { useAppState } from "../../../001_provider/001_AppStateProvider"
export type SrcIdRowProps = {
showF0: boolean
}
export const SrcIdRow = (props: SrcIdRowProps) => {
const appState = useAppState()
const srcIdRow = useMemo(() => {
if (props.showF0) {
return <></>
}
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, appState.serverSetting.updateServerSettings, appState.clientSetting.clientSetting.speakers])
const srcIdRowWithF0 = useMemo(() => {
if (!props.showF0) {
return <></>
}
const selectedCorrespondence = appState.clientSetting.clientSetting.correspondences?.find(x => {
return x.sid == appState.serverSetting.serverSetting.srcId
})
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) => {
// const recF0 = calcDefaultF0Factor(Number(e.target.value), appState.serverSetting.serverSetting.dstId)
// appState.serverSetting.updateServerSettings({ ...appState.serverSetting.serverSetting, srcId: Number(e.target.value), f0Factor: recF0 })
appState.serverSetting.updateServerSettings({ ...appState.serverSetting.serverSetting, srcId: Number(e.target.value) })
}}>
{
appState.clientSetting.clientSetting.correspondences?.map(x => {
return <option key={x.sid} value={x.sid}>{x.dirname}({x.sid})</option>
})
}
</select>
</div>
<div className="body-item-text">
<div>F0: {selectedCorrespondence?.correspondence.toFixed(1) || ""}</div>
</div>
<div className="body-item-text"></div>
</div>
)
}, [appState.serverSetting.serverSetting, appState.serverSetting.updateServerSettings, appState.clientSetting.clientSetting.correspondences])
return (
<>
{srcIdRow}
{srcIdRowWithF0}
</>
)
}

View File

@ -1,166 +0,0 @@
import React, { useMemo } from "react"
import { useAppState } from "../../../001_provider/001_AppStateProvider"
import { ServerInfoSoVitsSVC } from "@dannadori/voice-changer-client-js";
export type DstIdRowProps = {
showF0: boolean
useServerInfo: boolean
dstIdDisplayType: DstIdDisplayType
staticIds: number[]
}
export const DstIdDisplayType = {
"MMVCv13": "MMVCv13",
"MMVCv15": "MMVCv15",
"sovitsvc40": "sovitsvc40",
"sovitsvc40v2": "sovitsvc40v2",
"rvc": "rvc",
"ddspsvc": "ddspsvc",
} as const
export type DstIdDisplayType = typeof DstIdDisplayType[keyof typeof DstIdDisplayType]
export const DstIdRow = (props: DstIdRowProps) => {
const appState = useAppState()
const dstIdRow = useMemo(() => {
if (props.dstIdDisplayType != "MMVCv13") {
return <></>
}
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, appState.clientSetting.clientSetting.speakers, appState.serverSetting.updateServerSettings])
const dstIdRowWithF0 = useMemo(() => {
if (props.dstIdDisplayType != "MMVCv15") {
return <></>
}
const selected = appState.clientSetting.clientSetting.correspondences?.find(x => {
return x.sid == appState.serverSetting.serverSetting.dstId
})
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) => {
// const recF0 = calcDefaultF0Factor(appState.serverSetting.serverSetting.srcId, Number(e.target.value))
// appState.serverSetting.updateServerSettings({ ...appState.serverSetting.serverSetting, dstId: Number(e.target.value), f0Factor: recF0 })
appState.serverSetting.updateServerSettings({ ...appState.serverSetting.serverSetting, dstId: Number(e.target.value) })
}}>
{
appState.clientSetting.clientSetting.correspondences?.map(x => {
return <option key={x.sid} value={x.sid}>{x.dirname}({x.sid})</option>
})
}
</select>
</div>
<div className="body-item-text">
<div>F0: {selected?.correspondence.toFixed(1) || ""}</div>
</div>
<div className="body-item-text"></div>
</div>
)
}, [appState.serverSetting.serverSetting, appState.serverSetting.updateServerSettings, appState.clientSetting.clientSetting.correspondences])
const dstIdRowFromServer = useMemo(() => {
if (props.dstIdDisplayType != "sovitsvc40" && props.dstIdDisplayType != "sovitsvc40v2") {
return <></>
}
const settings = appState.serverSetting.serverSetting as ServerInfoSoVitsSVC
const speakers = settings.speakers
if (!speakers) {
return <></>
}
const currentValue = Object.values(speakers).includes(appState.serverSetting.serverSetting.dstId) ? appState.serverSetting.serverSetting.dstId : -1
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={currentValue} onChange={(e) => {
appState.serverSetting.updateServerSettings({ ...appState.serverSetting.serverSetting, dstId: Number(e.target.value) })
}}>
<option key="unknown" value={0}>default(0)</option>
{
Object.keys(speakers).map(x => {
return <option key={x} value={speakers[x]}>{x}({speakers[x]})</option>
})
}
</select>
</div>
<div className="body-item-text">
</div>
<div className="body-item-text"></div>
</div>
)
}, [appState.serverSetting.serverSetting, appState.serverSetting.updateServerSettings, appState.clientSetting.clientSetting.correspondences])
const dstIdRowStatic = useMemo(() => {
if (props.dstIdDisplayType != "rvc" && props.dstIdDisplayType != "ddspsvc") {
return <></>
}
// const settings = appState.serverSetting.serverSetting as ServerInfoSoVitsSVC
// const speakers = settings.speakers
// if (!speakers) {
// return <></>
// }
const currentValue = Object.values(props.staticIds).includes(appState.serverSetting.serverSetting.dstId) ? appState.serverSetting.serverSetting.dstId : -1
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={currentValue} onChange={(e) => {
appState.serverSetting.updateServerSettings({ ...appState.serverSetting.serverSetting, dstId: Number(e.target.value) })
}}>
<option key="unknown" value={0}>default(0)</option>
{
Object.values(props.staticIds).map(x => {
return <option key={x} value={x}>{x}</option>
})
}
</select>
</div>
<div className="body-item-text">
</div>
<div className="body-item-text"></div>
</div>
)
}, [appState.serverSetting.serverSetting, appState.serverSetting.updateServerSettings])
return (
<>
{dstIdRow}
{dstIdRowWithF0}
{dstIdRowFromServer}
{dstIdRowStatic}
</>
)
}

View File

@ -1,40 +0,0 @@
import React, { useMemo } from "react"
import { useAppState } from "../../../001_provider/001_AppStateProvider"
import { ServerInfoSoVitsSVC } from "@dannadori/voice-changer-client-js";
export type DstIdRow2Props = {
selectableIds: (number | string)[]
}
export const DstIdRow2 = (props: DstIdRow2Props) => {
const appState = useAppState()
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) })
}}>
{
props.selectableIds.map(x => {
return <option key={x} value={x}>{x}({x})</option>
})
}
</select>
</div>
<div className="body-item-text">
</div>
<div className="body-item-text"></div>
</div>
)
}, [appState.serverSetting.serverSetting, appState.serverSetting.updateServerSettings])
return (
<>
{dstIdRow}
</>
)
}

View File

@ -1,62 +0,0 @@
import React, { useMemo, useState } from "react"
import { useAppState } from "../../../001_provider/001_AppStateProvider"
export type EditSpeakerIdMappingRowProps = {
}
export const EditSpeakerIdMappingRow = (_props: EditSpeakerIdMappingRowProps) => {
const appState = useAppState()
const [editSpeakerTargetId, setEditSpeakerTargetId] = useState<number>(0)
const [editSpeakerTargetName, setEditSpeakerTargetName] = useState<string>("")
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])
return editSpeakerIdMappingRow
}

View File

@ -1,50 +0,0 @@
import React, { useMemo, useEffect } from "react"
import { useAppState } from "../../../001_provider/001_AppStateProvider"
export type F0FactorRowProps = {
}
export const F0FactorRow = (_props: F0FactorRowProps) => {
const appState = useAppState()
const f0FactorRow = useMemo(() => {
const src = appState.clientSetting.clientSetting.correspondences?.find(x => {
return x.sid == appState.serverSetting.serverSetting.srcId
})
const dst = appState.clientSetting.clientSetting.correspondences?.find(x => {
return x.sid == appState.serverSetting.serverSetting.dstId
})
const recommendedF0Factor = dst && src ? dst.correspondence / src.correspondence : 0
return (
<div className="body-row split-3-2-1-4 left-padding-1 guided">
<div className="body-item-title left-padding-1">F0 Factor</div>
<div className="body-input-container">
<input type="range" className="body-item-input-slider" min="0.1" max="5.0" step="0.01" value={appState.serverSetting.serverSetting.f0Factor || 0} onChange={(e) => {
appState.serverSetting.updateServerSettings({ ...appState.serverSetting.serverSetting, f0Factor: Number(e.target.value) })
}}></input>
<span className="body-item-input-slider-val">{appState.serverSetting.serverSetting.f0Factor?.toFixed(2) || 0}</span>
</div>
<div className="body-item-text"></div>
<div className="body-item-text">recommend: {recommendedF0Factor.toFixed(1)}</div>
</div>
)
}, [appState.serverSetting.serverSetting.f0Factor, appState.serverSetting.serverSetting.srcId, appState.serverSetting.serverSetting.dstId, appState.clientSetting.clientSetting.correspondences, appState.serverSetting.updateServerSettings])
useEffect(() => {
const src = appState.clientSetting.clientSetting.correspondences?.find(x => {
return x.sid == appState.serverSetting.serverSetting.srcId
})
const dst = appState.clientSetting.clientSetting.correspondences?.find(x => {
return x.sid == appState.serverSetting.serverSetting.dstId
})
const recommendedF0Factor = dst && src ? dst.correspondence / src.correspondence : 0
appState.serverSetting.updateServerSettings({ ...appState.serverSetting.serverSetting, f0Factor: recommendedF0Factor })
}, [appState.serverSetting.serverSetting.srcId, appState.serverSetting.serverSetting.dstId])
return f0FactorRow
}

View File

@ -1,45 +0,0 @@
import React, { useMemo } from "react"
import { useAppState } from "../../../001_provider/001_AppStateProvider"
import { useGuiState } from "../001_GuiStateProvider"
export type TuneRowProps = {
showPredictF0: boolean
}
export const TuneRow = (props: TuneRowProps) => {
const appState = useAppState()
const guiState = useGuiState()
const tuneRow = useMemo(() => {
const predictF0 = props.showPredictF0 ?
<>
<input type="checkbox" checked={appState.serverSetting.serverSetting.predictF0 == 1} onChange={(e) => {
appState.serverSetting.updateServerSettings({ ...appState.serverSetting.serverSetting, predictF0: e.target.checked ? 1 : 0 })
}} /> predict f0
</> :
<></>
return (
<div className="body-row split-3-2-1-4 left-padding-1 guided">
<div className="body-item-title left-padding-1 ">Tuning</div>
<div>
<input type="range" className="body-item-input-slider" min="-50" max="50" step="1" value={appState.serverSetting.serverSetting.tran || 0} onChange={(e) => {
appState.serverSetting.updateServerSettings({ ...appState.serverSetting.serverSetting, tran: Number(e.target.value) })
}}></input>
<span className="body-item-input-slider-val">{appState.serverSetting.serverSetting.tran}</span>
</div>
<div>
{predictF0}
</div>
<div className="body-button-container">
</div>
</div>
)
}, [
appState.serverSetting.serverSetting,
appState.serverSetting.updateServerSettings,
guiState.modelSlotNum
])
return tuneRow
}

View File

@ -1,30 +0,0 @@
import React, { useMemo } from "react"
import { useAppState } from "../../../001_provider/001_AppStateProvider"
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>
<div>
<input type="range" className="body-item-input-slider" min="0" max="1" step="0.1" value={appState.serverSetting.serverSetting.clusterInferRatio || 0} onChange={(e) => {
appState.serverSetting.updateServerSettings({ ...appState.serverSetting.serverSetting, clusterInferRatio: Number(e.target.value) })
}}></input>
<span className="body-item-input-slider-val">{appState.serverSetting.serverSetting.clusterInferRatio}</span>
</div>
<div className="body-button-container">
</div>
</div>
)
}, [
appState.serverSetting.serverSetting,
appState.serverSetting.updateServerSettings
])
return clusterRatioRow
}

View File

@ -1,31 +0,0 @@
import React, { useMemo } from "react"
import { useAppState } from "../../../001_provider/001_AppStateProvider"
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>
<div>
<input type="range" className="body-item-input-slider" min="0" max="1" step="0.1" value={appState.serverSetting.serverSetting.noiseScale || 0} onChange={(e) => {
appState.serverSetting.updateServerSettings({ ...appState.serverSetting.serverSetting, noiseScale: Number(e.target.value) })
}}></input>
<span className="body-item-input-slider-val">{appState.serverSetting.serverSetting.noiseScale}</span>
</div>
<div className="body-button-container">
</div>
</div>
)
}, [
appState.serverSetting.serverSetting,
appState.serverSetting.updateServerSettings
])
return noiseScaleRow
}

View File

@ -1,32 +0,0 @@
import React, { useMemo } from "react"
import { useAppState } from "../../../001_provider/001_AppStateProvider"
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>
<div>
<input type="range" className="body-item-input-slider" min="0.00000" max="0.001" step="0.00001" value={appState.serverSetting.serverSetting.silentThreshold || 0} onChange={(e) => {
appState.serverSetting.updateServerSettings({ ...appState.serverSetting.serverSetting, silentThreshold: Number(e.target.value) })
}}></input>
<span className="body-item-input-slider-val">{appState.serverSetting.serverSetting.silentThreshold}</span>
</div>
<div className="body-button-container">
</div>
</div>
)
}, [
appState.serverSetting.serverSetting,
appState.serverSetting.updateServerSettings
])
return silentThresholdRow
}

View File

@ -1,30 +0,0 @@
import React, { useMemo } from "react"
import { useAppState } from "../../../001_provider/001_AppStateProvider"
export type IndexRatioRowProps = {
}
export const IndexRatioRow = (_props: IndexRatioRowProps) => {
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 ">index ratio</div>
<div>
<input type="range" className="body-item-input-slider" min="0" max="1" step="0.1" value={appState.serverSetting.serverSetting.indexRatio || 0} onChange={(e) => {
appState.serverSetting.updateServerSettings({ ...appState.serverSetting.serverSetting, indexRatio: Number(e.target.value) })
}}></input>
<span className="body-item-input-slider-val">{appState.serverSetting.serverSetting.indexRatio}</span>
</div>
<div className="body-button-container">
</div>
</div>
)
}, [
appState.serverSetting.serverSetting,
appState.serverSetting.updateServerSettings
])
return clusterRatioRow
}

View File

@ -1,30 +0,0 @@
import React, { useMemo } from "react"
import { useAppState } from "../../../001_provider/001_AppStateProvider"
export type ProtectRowProps = {
}
export const ProtectRow = (_props: ProtectRowProps) => {
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 ">protect</div>
<div>
<input type="range" className="body-item-input-slider" min="0" max="0.5" step="0.1" value={appState.serverSetting.serverSetting.protect || 0} onChange={(e) => {
appState.serverSetting.updateServerSettings({ ...appState.serverSetting.serverSetting, protect: Number(e.target.value) })
}}></input>
<span className="body-item-input-slider-val">{appState.serverSetting.serverSetting.protect}</span>
</div>
<div className="body-button-container">
</div>
</div>
)
}, [
appState.serverSetting.serverSetting,
appState.serverSetting.updateServerSettings
])
return clusterRatioRow
}

View File

@ -1,42 +0,0 @@
import React, { useMemo } from "react"
import { useAppState } from "../../../001_provider/001_AppStateProvider"
export type DiffEnablerRowProps = {
}
export const DiffEnablerRow = (_props: DiffEnablerRowProps) => {
const appState = useAppState()
const diffEnablerRow = useMemo(() => {
return (
<div className="body-row split-3-2-2-2-1 left-padding-1 guided">
<div className="body-item-title left-padding-1 ">DDSP Setting</div>
<div>
<input type="checkbox" checked={appState.serverSetting.serverSetting.useEnhancer == 1} onChange={(e) => {
appState.serverSetting.updateServerSettings({ ...appState.serverSetting.serverSetting, useEnhancer: e.target.checked ? 1 : 0 })
}} /> Enhancer
</div>
<div>
<input type="checkbox" checked={appState.serverSetting.serverSetting.useDiff == 1} onChange={(e) => {
appState.serverSetting.updateServerSettings({ ...appState.serverSetting.serverSetting, useDiff: e.target.checked ? 1 : 0 })
}} /> Diff
</div>
<div>
<input type="checkbox" checked={appState.serverSetting.serverSetting.useDiffSilence == 1} onChange={(e) => {
appState.serverSetting.updateServerSettings({ ...appState.serverSetting.serverSetting, useDiffSilence: e.target.checked ? 1 : 0 })
}} /> Silence
</div>
<div></div>
</div>
)
}, [
appState.serverSetting.serverSetting,
appState.serverSetting.updateServerSettings
])
return diffEnablerRow
}

View File

@ -1,42 +0,0 @@
import React, { useMemo } from "react"
import { useAppState } from "../../../001_provider/001_AppStateProvider"
export type DiffSettingRowProps = {
}
export const DiffSettingRow = (_props: DiffSettingRowProps) => {
const appState = useAppState()
const diffSettingRow = useMemo(() => {
return (
<div className="body-row split-3-2-2-3 left-padding-1 guided">
<div className="body-item-title left-padding-1 ">Diff Setting</div>
<div>
<span className="body-item-input-slider-label">Acc</span>
<input type="range" className="body-item-input-slider" min="1" max="20" step="1" value={appState.serverSetting.serverSetting.diffAcc} onChange={(e) => {
appState.serverSetting.updateServerSettings({ ...appState.serverSetting.serverSetting, diffAcc: Number(e.target.value) })
}}></input>
<span className="body-item-input-slider-val">{appState.serverSetting.serverSetting.diffAcc}</span>
</div>
<div>
<span className="body-item-input-slider-label">kstep</span>
<input type="range" className="body-item-input-slider" min="21" max="300" step="1" value={appState.serverSetting.serverSetting.kStep} onChange={(e) => {
appState.serverSetting.updateServerSettings({ ...appState.serverSetting.serverSetting, kStep: Number(e.target.value) })
}}></input>
<span className="body-item-input-slider-val">{appState.serverSetting.serverSetting.kStep}</span>
</div>
<div className="body-button-container">
</div>
</div>
)
}, [
appState.serverSetting.serverSetting,
appState.serverSetting.updateServerSettings
])
return diffSettingRow
}

View File

@ -1,41 +0,0 @@
import React, { useMemo } from "react"
import { useAppState } from "../../../001_provider/001_AppStateProvider"
import { DiffMethod } from "@dannadori/voice-changer-client-js"
export type DiffMethodRowProps = {
}
export const DiffMethodRow = (_props: DiffMethodRowProps) => {
const appState = useAppState()
const diffMethodRow = useMemo(() => {
const onDiffMethodChanged = (val: DiffMethod) => {
appState.serverSetting.updateServerSettings({ ...appState.serverSetting.serverSetting, diffMethod: val })
}
return (
<div className="body-row split-3-7 left-padding-1 guided">
<div className="body-item-title left-padding-1">Diff Method</div>
<div className="body-select-container">
<select className="body-select" value={appState.serverSetting.serverSetting.diffMethod} onChange={(e) => {
onDiffMethodChanged(e.target.value as DiffMethod)
}}>
{
Object.values(DiffMethod).map(x => {
return <option key={x} value={x}>{x}</option>
})
}
</select>
</div>
</div>
)
}, [
appState.serverSetting.serverSetting,
appState.serverSetting.updateServerSettings
])
return diffMethodRow
}

View File

@ -1,45 +0,0 @@
import React, { useMemo } from "react"
import { useAppState } from "../../../001_provider/001_AppStateProvider"
export type InputChunkNumRowProps = {
nums: number[]
}
export const InputChunkNumRow = (props: InputChunkNumRowProps) => {
const appState = useAppState()
const inputChunkNumRow = useMemo(() => {
let nums: number[]
if (!props.nums) {
nums = [8, 16, 24, 32, 40, 48, 64, 80, 96, 112, 128, 192, 256, 320, 384, 448, 512, 576, 640, 704, 768, 832, 896, 960, 1024, 2048]
} else {
nums = props.nums
}
return (
<div className="body-row split-3-2-2-3 left-padding-1 guided">
<div className="body-item-title left-padding-1">Input Chunk Num(128sample/chunk)</div>
<div className="body-input-container">
<select className="body-select" value={appState.workletNodeSetting.workletNodeSetting.inputChunkNum} onChange={(e) => {
appState.workletNodeSetting.updateWorkletNodeSetting({ ...appState.workletNodeSetting.workletNodeSetting, inputChunkNum: Number(e.target.value) })
appState.workletNodeSetting.trancateBuffer()
appState.serverSetting.updateServerSettings({ ...appState.serverSetting.serverSetting, serverReadChunkSize: Number(e.target.value) })
}}>
{
nums.map(x => {
return <option key={x} value={x}>{x}</option>
})
}
</select>
</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>sample: {(appState.workletNodeSetting.workletNodeSetting.inputChunkNum * 128)}</div>
</div>
</div>
)
}, [appState.workletNodeSetting.workletNodeSetting, appState.workletNodeSetting.updateWorkletNodeSetting, appState.serverSetting.serverSetting, appState.serverSetting.updateServerSettings])
return inputChunkNumRow
}

View File

@ -1,33 +0,0 @@
import React, { useMemo } from "react"
import { useAppState } from "../../../001_provider/001_AppStateProvider"
export type ExtraDataLengthRowProps = {
}
export const ExtraDataLengthRow = (_props: ExtraDataLengthRowProps) => {
const appState = useAppState()
const extraDataLengthRow = useMemo(() => {
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>
<div className="body-input-container">
<select className="body-select" value={appState.serverSetting.serverSetting.extraConvertSize} onChange={(e) => {
appState.serverSetting.updateServerSettings({ ...appState.serverSetting.serverSetting, extraConvertSize: Number(e.target.value) })
appState.workletNodeSetting.trancateBuffer()
}}>
{
[1024 * 4, 1024 * 8, 1024 * 16, 1024 * 32, 1024 * 64, 1024 * 128].map(x => {
return <option key={x} value={x}>{x}</option>
})
}
</select>
</div>
<div className="body-item-text">
</div>
<div className="body-item-text"></div>
</div>
)
}, [appState.serverSetting.serverSetting, appState.serverSetting.updateServerSettings])
return extraDataLengthRow
}

View File

@ -1,21 +0,0 @@
import React, { useMemo } from "react"
import { useAppState } from "../../../001_provider/001_AppStateProvider"
export type GPURowProps = {
}
export const GPURow = (_props: GPURowProps) => {
const appState = useAppState()
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 || 0} onChange={(e) => {
appState.serverSetting.updateServerSettings({ ...appState.serverSetting.serverSetting, gpu: Number(e.target.value) })
}} />
</div>
</div>
)
}, [appState.serverSetting.serverSetting, appState.serverSetting.updateServerSettings])
return gpuRow
}

View File

@ -1,29 +0,0 @@
import React, { useMemo } from "react"
import { useAppState } from "../../../001_provider/001_AppStateProvider"
export type ServerURLRowProps = {
}
export const ServerURLRow = (_props: ServerURLRowProps) => {
const appState = useAppState()
const serverUrlRow = 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, appState.clientSetting.setServerUrl])
return serverUrlRow
}

View File

@ -1,34 +0,0 @@
import React, { useMemo } from "react"
import { useAppState } from "../../../001_provider/001_AppStateProvider"
import { Protocol } from "@dannadori/voice-changer-client-js"
export type ProtocolRowProps = {
}
export const ProtocolRow = (_props: ProtocolRowProps) => {
const appState = useAppState()
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, appState.workletNodeSetting.updateWorkletNodeSetting])
return protocolRow
}

View File

@ -1,33 +0,0 @@
import React, { useMemo } from "react"
import { useAppState } from "../../../001_provider/001_AppStateProvider"
import { SampleRate } from "@dannadori/voice-changer-client-js"
export type SampleRateRowProps = {
}
export const SampleRateRow = (_props: SampleRateRowProps) => {
const appState = useAppState()
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) => {
try {
appState.clientSetting.updateClientSetting({ ...appState.clientSetting.clientSetting, sampleRate: Number(e.target.value) as SampleRate })
} catch (e) {
console.error(e)
}
}}>
{
Object.values(SampleRate).map(x => {
return <option key={x} value={x}>{x}</option>
})
}
</select>
</div>
</div>
)
}, [appState.clientSetting.clientSetting, appState.clientSetting.updateClientSetting])
return sampleRateRow
}

View File

@ -1,33 +0,0 @@
import React, { useMemo } from "react"
import { useAppState } from "../../../001_provider/001_AppStateProvider"
import { InputSampleRate } from "@dannadori/voice-changer-client-js"
export type SendingSampleRateRowProps = {
}
export const SendingSampleRateRow = (_props: SendingSampleRateRowProps) => {
const appState = useAppState()
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, appState.workletNodeSetting.updateWorkletNodeSetting, appState.serverSetting.updateServerSettings])
return sendingSampleRateRow
}

View File

@ -1,31 +0,0 @@
import React, { useMemo } from "react"
import { useAppState } from "../../../001_provider/001_AppStateProvider"
import { CrossFadeOverlapSize } from "@dannadori/voice-changer-client-js"
export type CrossFadeOverlapSizeRowProps = {
}
export const CrossFadeOverlapSizeRow = (_props: CrossFadeOverlapSizeRowProps) => {
const appState = useAppState()
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, appState.serverSetting.updateServerSettings])
return crossFadeOverlapSizeRow
}

View File

@ -1,24 +0,0 @@
import React, { useMemo } from "react"
import { useAppState } from "../../../001_provider/001_AppStateProvider"
export type CrossFadeOffsetRateRowProps = {
}
export const CrossFadeOffsetRateRow = (_props: CrossFadeOffsetRateRowProps) => {
const appState = useAppState()
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])
return crossFadeOffsetRateRow
}

View File

@ -1,24 +0,0 @@
import React, { useMemo } from "react"
import { useAppState } from "../../../001_provider/001_AppStateProvider"
export type CrossFadeEndRateRowProps = {
}
export const CrossFadeEndRateRow = (_props: CrossFadeEndRateRowProps) => {
const appState = useAppState()
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, appState.serverSetting.updateServerSettings])
return crossFadeEndRateRow
}

View File

@ -1,31 +0,0 @@
import React, { useMemo } from "react"
import { useAppState } from "../../../001_provider/001_AppStateProvider"
import { DownSamplingMode } from "@dannadori/voice-changer-client-js"
export type DownSamplingModeRowProps = {
}
export const DownSamplingModeRow = (_props: DownSamplingModeRowProps) => {
const appState = useAppState()
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, appState.workletNodeSetting.updateWorkletNodeSetting])
return downSamplingModeRow
}

View File

@ -1,27 +0,0 @@
import React, { useMemo } from "react"
import { useAppState } from "../../../001_provider/001_AppStateProvider"
export type TrancateNumTresholdRowProps = {
}
export const TrancateNumTresholdRow = (_props: TrancateNumTresholdRowProps) => {
const appState = useAppState()
const trancateNumTresholdRow = 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>
)
}, [appState.workletSetting.setting, appState.workletSetting.setSetting])
return trancateNumTresholdRow
}

View File

@ -1,31 +0,0 @@
import React, { useMemo } from "react"
import { useAppState } from "../../../001_provider/001_AppStateProvider"
export type RVCQualityRowProps = {
}
export const RVCQualityRow = (_props: RVCQualityRowProps) => {
const appState = useAppState()
const trancateNumTresholdRow = useMemo(() => {
const onRVCQualityChanged = (val: number) => {
appState.serverSetting.updateServerSettings({
...appState.serverSetting.serverSetting,
rvcQuality: val
})
}
return (
<div className="body-row split-3-7 left-padding-1 guided">
<div className="body-item-title left-padding-1">RCV Quality</div>
<div className="body-input-container">
<select value={appState.serverSetting.serverSetting.rvcQuality} onChange={(e) => { onRVCQualityChanged(Number(e.target.value)) }}>
<option value="0" >low</option>
<option value="1" >high</option>
</select>
</div>
</div>
)
}, [appState.serverSetting.serverSetting, appState.serverSetting.updateServerSettings])
return trancateNumTresholdRow
}

View File

@ -1,31 +0,0 @@
import React, { useMemo } from "react"
import { useAppState } from "../../../001_provider/001_AppStateProvider"
export type SilenceFrontRowProps = {
}
export const SilenceFrontRow = (_props: SilenceFrontRowProps) => {
const appState = useAppState()
const trancateNumTresholdRow = useMemo(() => {
const onSilenceFrontChanged = (val: number) => {
appState.serverSetting.updateServerSettings({
...appState.serverSetting.serverSetting,
silenceFront: val
})
}
return (
<div className="body-row split-3-7 left-padding-1 guided">
<div className="body-item-title left-padding-1">Silence Front</div>
<div className="body-input-container">
<select value={appState.serverSetting.serverSetting.silenceFront} onChange={(e) => { onSilenceFrontChanged(Number(e.target.value)) }}>
<option value="0" >off</option>
<option value="1" >on</option>
</select>
</div>
</div>
)
}, [appState.serverSetting.serverSetting, appState.serverSetting.updateServerSettings])
return trancateNumTresholdRow
}

View File

@ -1,31 +0,0 @@
import React, { useMemo } from "react"
import { useAppState } from "../../../001_provider/001_AppStateProvider"
export type EnableDirectMLRowProps = {
}
export const EnableDirectMLRow = (_props: EnableDirectMLRowProps) => {
const appState = useAppState()
const enableDirctMLRow = useMemo(() => {
const onEnableDirectMLChanged = (val: number) => {
appState.serverSetting.updateServerSettings({
...appState.serverSetting.serverSetting,
enableDirectML: val
})
}
return (
<div className="body-row split-3-7 left-padding-1 guided">
<div className="body-item-title left-padding-1">DirectML(experimental)</div>
<div className="body-input-container">
<select value={appState.serverSetting.serverSetting.enableDirectML} onChange={(e) => { onEnableDirectMLChanged(Number(e.target.value)) }}>
<option value="0" >off</option>
<option value="1" >on</option>
</select>
</div>
</div>
)
}, [appState.serverSetting.serverSetting, appState.serverSetting.updateServerSettings])
return enableDirctMLRow
}

View File

@ -1,17 +0,0 @@
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
}

View File

@ -1,180 +0,0 @@
import React, { useEffect, useMemo, useState } from "react"
import { useAppState } from "../../../001_provider/001_AppStateProvider"
import { MergeElement } from "@dannadori/voice-changer-client-js"
export type MergeLabRowProps = {
}
export const MergeLabRow = (_props: MergeLabRowProps) => {
const [mergeElements, setMergeElements] = useState<MergeElement[]>([])
const appState = useAppState()
const [defaultTune, setDefaultTune] = useState<number>(0)
// スロットが変更されたときの初期化処理
const newSlotChangeKey = useMemo(() => {
if (!appState.serverSetting.serverSetting.modelSlots) {
return ""
}
return appState.serverSetting.serverSetting.modelSlots.reduce((prev, cur) => {
return prev + "_" + cur.modelFile
}, "")
}, [appState.serverSetting.serverSetting.modelSlots])
// マージ用データセットの初期化
const clearMergeModelSetting = useMemo(() => {
return () => {
// PyTorchモデルだけフィルタリング
const models = appState.serverSetting.serverSetting.modelSlots.filter(x => { return x.modelFile && x.modelFile.endsWith("onnx") == false })
if (models.length == 0) {
setMergeElements([])
return
}
const newMergeElements = models.map((x) => {
const elem: MergeElement = { filename: x.modelFile, strength: 0 }
return elem
})
setMergeElements(newMergeElements)
}
}, [appState.serverSetting.serverSetting.modelSlots])
useEffect(() => {
clearMergeModelSetting()
}, [newSlotChangeKey])
const mergeLabRow = useMemo(() => {
const onMergeClicked = async () => {
appState.serverSetting.mergeModel({
command: "mix",
defaultTune: defaultTune,
defaultIndexRatio: 1,
defaultProtect: 0.5,
files: mergeElements
})
}
const onMergeElementsChanged = (filename: string, strength: number) => {
console.log("targetelement")
const srcElements = mergeElements.filter(x => { return x.strength > 0 })
const targetElement = mergeElements.find(x => { return x.filename == filename })
if (!targetElement) {
console.warn("target model is not found")
return
}
// 一つ目の対象モデル
if (srcElements.length == 0) {
targetElement.strength = strength
setMergeElements([...mergeElements])
return
}
//二つ目以降
const srcSample = appState.serverSetting.serverSetting.modelSlots.find(x => { return x.modelFile == srcElements[0].filename })
const tgtSample = appState.serverSetting.serverSetting.modelSlots.find(x => { return x.modelFile == filename })
if (!srcSample || !tgtSample) {
console.warn("target model is not found", srcSample, tgtSample)
return
}
if (
srcSample.samplingRate != tgtSample.samplingRate ||
srcSample.embChannels != tgtSample.embChannels ||
srcSample.modelType != tgtSample.modelType
) {
alert("current selected model is not same as the other selected.")
console.log("current selected model is not same as the other selected.", srcSample.samplingRate, tgtSample.samplingRate,
srcSample.embChannels, tgtSample.embChannels,
srcSample.modelType, tgtSample.modelType)
return
}
targetElement.strength = strength
setMergeElements([...mergeElements])
return
}
const modelOptions = mergeElements.map((x, index) => {
let filename = ""
if (x.filename.length > 0) {
filename = x.filename.replace(/^.*[\\\/]/, '')
} else {
return (
<div key={index} >
</div>
)
}
const modelInfo = appState.serverSetting.serverSetting.modelSlots.find(y => { return y.modelFile == x.filename })
if (!modelInfo) {
return (
<div key={index} >
</div>
)
}
const f0str = modelInfo.f0 == true ? "f0" : "nof0"
const srstr = Math.floor(modelInfo.samplingRate / 1000) + "K"
const embedstr = modelInfo.embChannels
const typestr = (() => {
if (modelInfo.modelType == "pyTorchRVC" || modelInfo.modelType == "pyTorchRVCNono") {
return "org"
} else if (modelInfo.modelType == "pyTorchRVCv2" || modelInfo.modelType == "pyTorchRVCv2Nono") {
return "g_v2"
} else if (modelInfo.modelType == "pyTorchWebUI" || modelInfo.modelType == "pyTorchWebUINono") {
return "webui"
} else {
return "unknown"
}
})()
const metadata = `[${f0str},${srstr},${embedstr},${typestr}]`
return (
<div key={index} className="merge-field split-8-2">
<div className="merge-field-elem">{metadata} {filename}</div>
<div className="merge-field-elem">
<input type="range" className="body-item-input-slider" min="0" max="100" step="1" value={x.strength} onChange={(e) => {
onMergeElementsChanged(x.filename, Number(e.target.value))
}}></input>
<span className="body-item-input-slider-val">{x.strength}</span>
</div>
</div >
)
})
return (
<div className="body-row split-3-3-4 left-padding-1 guided">
<div className="body-item-title left-padding-1">Model Merger</div>
<div className="merge-field-container">
{modelOptions}
<div className="merge-field split-8-2">
<div className="merge-field-elem grey-bold">Default Tune</div>
<div className="merge-field-elem">
<input type="range" className="body-item-input-slider-2nd" min="-50" max="50" step="1" value={defaultTune} onChange={(e) => {
setDefaultTune(Number(e.target.value))
}}></input>
<span className="body-item-input-slider-val">{defaultTune}</span>
</div>
</div >
</div>
<div className="body-button-container">
<div className="body-button" onClick={onMergeClicked}>merge</div>
<div className="body-button" onClick={clearMergeModelSetting}>clear</div>
</div>
</div>
)
}, [mergeElements, appState.serverSetting.serverSetting, defaultTune])
return mergeLabRow
}

View File

@ -13,14 +13,12 @@ export type HeaderAreaProps = {
}
export const HeaderArea = (props: HeaderAreaProps) => {
const { appGuiSettingState, setClientType } = useAppRoot()
const { appGuiSettingState } = useAppRoot()
const messageBuilderState = useMessageBuilder()
const { clientSetting, clearSetting } = useAppState()
const { setIsConverting, isConverting } = useGuiState()
const { clearSetting } = useAppState()
const clientType = appGuiSettingState.appGuiSetting.id
const { removeItem } = useIndexedDB({ clientType: clientType })
const { setItem } = useIndexedDB({ clientType: null })
useMemo(() => {
messageBuilderState.setMessage(__filename, "github", { "ja": "github", "en": "github" })
@ -125,20 +123,6 @@ export const HeaderArea = (props: HeaderAreaProps) => {
await removeItem(INDEXEDDB_KEY_AUDIO_OUTPUT)
location.reload()
}
const onReloadClicked = async () => {
location.reload()
}
const onReselectVCClicked = async () => {
setIsConverting(false)
if (isConverting) {
await clientSetting.stop()
setIsConverting(false)
}
setItem(INDEXEDDB_KEY_DEFAULT_MODEL_TYPE, "null")
setClientType(null)
appGuiSettingState.clearAppGuiSetting()
}
return (
<div className="headerArea">
@ -158,8 +142,8 @@ export const HeaderArea = (props: HeaderAreaProps) => {
</span>
<span className="belongings">
<div className="belongings-button" onClick={onClearSettingClicked}>clear setting</div>
<div className="belongings-button" onClick={onReloadClicked}>reload</div>
<div className="belongings-button" onClick={onReselectVCClicked}>select vc</div>
{/* <div className="belongings-button" onClick={onReloadClicked}>reload</div>
<div className="belongings-button" onClick={onReselectVCClicked}>select vc</div> */}
</span>
</div>

View File

@ -72,7 +72,7 @@ export const useClient = (props: UseClientProps): ClientState => {
const clientSetting = useClientSetting({ clientType: props.clientType, voiceChangerClient, audioContext: props.audioContext })
const workletNodeSetting = useWorkletNodeSetting({ clientType: props.clientType, voiceChangerClient })
const workletSetting = useWorkletSetting({ clientType: props.clientType, voiceChangerClient })
const serverSetting = useServerSetting({ clientType: props.clientType, voiceChangerClient })
const serverSetting = useServerSetting({ voiceChangerClient })
const indexedDBState = useIndexedDB({ clientType: props.clientType })
@ -184,7 +184,6 @@ export const useClient = (props: UseClientProps): ClientState => {
await clientSetting.clearSetting()
await workletNodeSetting.clearSetting()
await workletSetting.clearSetting()
await serverSetting.clearSetting()
}
return {

View File

@ -1,14 +1,6 @@
import { useState, useMemo, useEffect } from "react"
import { VoiceChangerServerSetting, ServerInfo, ServerSettingKey, INDEXEDDB_KEY_SERVER, INDEXEDDB_KEY_MODEL_DATA, ClientType, DefaultServerSetting_MMVCv13, DefaultServerSetting_MMVCv15, DefaultServerSetting_so_vits_svc_40, DefaultServerSetting_RVC, OnnxExporterInfo, DefaultServerSetting_DDSP_SVC, MAX_MODEL_SLOT_NUM, Framework, MergeModelRequest, VoiceChangerType } from "../const"
import { useState, useMemo } from "react"
import { VoiceChangerServerSetting, ServerInfo, ServerSettingKey, OnnxExporterInfo, MergeModelRequest, VoiceChangerType, DefaultServerSetting } from "../const"
import { VoiceChangerClient } from "../VoiceChangerClient"
import { useIndexedDB } from "./useIndexedDB"
type ModelData = {
file?: File
data?: ArrayBuffer
filename?: string
}
export const ModelAssetName = {
iconFile: "iconFile"
@ -60,68 +52,6 @@ export type ModelUploadSettingForServer = Omit<ModelUploadSetting, "files"> & {
files: ModelFileForServer[]
}
export type FileUploadSetting = {
isHalf: boolean
uploaded: boolean
defaultTune: number
defaultIndexRatio: number
defaultProtect: number
framework: Framework
params: string
mmvcv13Config: ModelData | null
mmvcv13Model: ModelData | null
mmvcv15Config: ModelData | null
mmvcv15Model: ModelData | null
soVitsSvc40Config: ModelData | null
soVitsSvc40Model: ModelData | null
soVitsSvc40Cluster: ModelData | null
rvcModel: ModelData | null
rvcFeature: ModelData | null
rvcIndex: ModelData | null
isSampleMode: boolean
sampleId: string | null
rvcIndexDownload: boolean
ddspSvcModel: ModelData | null
ddspSvcModelConfig: ModelData | null
ddspSvcDiffusion: ModelData | null
ddspSvcDiffusionConfig: ModelData | null
}
export const InitialFileUploadSetting: FileUploadSetting = {
isHalf: true,
uploaded: false,
defaultTune: 0,
defaultIndexRatio: 1,
defaultProtect: 0.5,
framework: Framework.PyTorch,
params: "{}",
mmvcv13Config: null,
mmvcv13Model: null,
mmvcv15Config: null,
mmvcv15Model: null,
soVitsSvc40Config: null,
soVitsSvc40Model: null,
soVitsSvc40Cluster: null,
rvcModel: null,
rvcFeature: null,
rvcIndex: null,
isSampleMode: false,
sampleId: null,
rvcIndexDownload: true,
ddspSvcModel: null,
ddspSvcModelConfig: null,
ddspSvcDiffusion: null,
ddspSvcDiffusionConfig: null,
}
type AssetUploadSetting = {
slot: number
name: ModelAssetName
@ -129,18 +59,14 @@ type AssetUploadSetting = {
}
export type UseServerSettingProps = {
clientType: ClientType | null
voiceChangerClient: VoiceChangerClient | null
}
export type ServerSettingState = {
serverSetting: ServerInfo
updateServerSettings: (setting: ServerInfo) => Promise<void>
clearSetting: () => Promise<void>
reloadServerInfo: () => Promise<void>;
fileUploadSettings: FileUploadSetting[]
setFileUploadSetting: (slot: number, val: FileUploadSetting) => void
uploadModel: (setting: ModelUploadSetting) => Promise<void>
uploadProgress: number
isUploading: boolean
@ -153,80 +79,7 @@ export type ServerSettingState = {
}
export const useServerSetting = (props: UseServerSettingProps): ServerSettingState => {
// const settingRef = useRef<VoiceChangerServerSetting>(DefaultVoiceChangerServerSetting)
const getDefaultServerSetting = () => {
if (props.clientType == "MMVCv13") {
return DefaultServerSetting_MMVCv13
} else if (props.clientType == "MMVCv15") {
return DefaultServerSetting_MMVCv15
} else if (props.clientType == "so-vits-svc-40") {
return DefaultServerSetting_so_vits_svc_40
} else if (props.clientType == "DDSP-SVC") {
return DefaultServerSetting_DDSP_SVC
} else if (props.clientType == "RVC") {
return DefaultServerSetting_RVC
} else {
return DefaultServerSetting_MMVCv15
}
}
const [serverSetting, setServerSetting] = useState<ServerInfo>(getDefaultServerSetting())
const [fileUploadSettings, setFileUploadSettings] = useState<FileUploadSetting[]>([])
const { setItem, getItem, removeItem } = useIndexedDB({ clientType: props.clientType })
// clientTypeが新しく設定されたときに、serverのmodelType動作を変更設定反映
useEffect(() => {
if (!props.voiceChangerClient) return
if (!props.clientType) return
const setInitialSetting = async () => {
// Set Model Type
await props.voiceChangerClient!.switchModelType(props.clientType!)
// Load Default (and Cache) and set
const defaultServerSetting = getDefaultServerSetting()
const cachedServerSetting = await getItem(INDEXEDDB_KEY_SERVER)
let initialSetting: ServerInfo
if (cachedServerSetting) {
initialSetting = {
...defaultServerSetting, ...cachedServerSetting as ServerInfo,
serverAudioStated: 0,
inputSampleRate: 48000
}// sample rateは時限措置
} else {
initialSetting = { ...defaultServerSetting }
}
setServerSetting(initialSetting)
// upload setting
for (let i = 0; i < Object.values(ServerSettingKey).length; i++) {
const k = Object.values(ServerSettingKey)[i] as keyof VoiceChangerServerSetting
const v = initialSetting[k]
if (v) {
props.voiceChangerClient!.updateServerSettings(k, "" + v)
}
}
// Load file upload cache
const loadedFileUploadSettings: FileUploadSetting[] = []
for (let i = 0; i < MAX_MODEL_SLOT_NUM; i++) {
const modleKey = `${INDEXEDDB_KEY_MODEL_DATA}_${i}`
const fileuploadSetting = await getItem(modleKey)
if (!fileuploadSetting) {
loadedFileUploadSettings.push(InitialFileUploadSetting)
} else {
loadedFileUploadSettings.push(fileuploadSetting as FileUploadSetting)
}
}
setFileUploadSettings(loadedFileUploadSettings)
reloadServerInfo()
}
setInitialSetting()
}, [props.voiceChangerClient, props.clientType])
const [serverSetting, setServerSetting] = useState<ServerInfo>(DefaultServerSetting)
//////////////
// 設定
@ -249,19 +102,11 @@ export const useServerSetting = (props: UseServerSettingProps): ServerSettingSta
setServerSetting(res)
const storeData = { ...res }
storeData.recordIO = 0
setItem(INDEXEDDB_KEY_SERVER, storeData)
}
}
}
}, [props.voiceChangerClient, serverSetting])
const setFileUploadSetting = useMemo(() => {
return async (slot: number, fileUploadSetting: FileUploadSetting) => {
fileUploadSetting.uploaded = false
fileUploadSettings[slot] = fileUploadSetting
setFileUploadSettings([...fileUploadSettings])
}
}, [fileUploadSettings])
//////////////
@ -335,7 +180,7 @@ export const useServerSetting = (props: UseServerSettingProps): ServerSettingSta
await props.voiceChangerClient.uploadAssets(JSON.stringify(assetUploadSetting))
reloadServerInfo()
}
}, [fileUploadSettings, props.voiceChangerClient, props.clientType])
}, [props.voiceChangerClient])
@ -347,19 +192,9 @@ export const useServerSetting = (props: UseServerSettingProps): ServerSettingSta
setServerSetting(res)
const storeData = { ...res }
storeData.recordIO = 0
setItem(INDEXEDDB_KEY_SERVER, storeData)
}
}, [props.voiceChangerClient])
const clearSetting = async () => {
await removeItem(INDEXEDDB_KEY_SERVER)
await removeItem(INDEXEDDB_KEY_MODEL_DATA)
for (let i = 0; i < MAX_MODEL_SLOT_NUM; i++) {
const modleKey = `${INDEXEDDB_KEY_MODEL_DATA}_${i}`
await removeItem(modleKey)
}
}
const getOnnx = async () => {
return props.voiceChangerClient!.getOnnx()
@ -385,11 +220,8 @@ export const useServerSetting = (props: UseServerSettingProps): ServerSettingSta
return {
serverSetting,
updateServerSettings,
clearSetting,
reloadServerInfo,
fileUploadSettings,
setFileUploadSetting,
uploadModel,
uploadProgress,
isUploading,