commit
3afaeea4ac
2
client/demo/dist/index.js
vendored
2
client/demo/dist/index.js
vendored
File diff suppressed because one or more lines are too long
@ -1,4 +1,4 @@
|
||||
import { OnnxExecutionProvider, Protocol, Framework, fileSelector } from "@dannadori/voice-changer-client-js"
|
||||
import { OnnxExecutionProvider, Framework, fileSelector } from "@dannadori/voice-changer-client-js"
|
||||
import React from "react"
|
||||
import { useMemo } from "react"
|
||||
import { ClientState } from "./hooks/useClient"
|
||||
@ -126,29 +126,6 @@ export const useServerSettingArea = (props: UseServerSettingProps): ServerSettin
|
||||
props.clientState.serverSetting.isUploading,
|
||||
props.clientState.serverSetting.uploadProgress])
|
||||
|
||||
const protocolRow = useMemo(() => {
|
||||
const onProtocolChanged = async (val: Protocol) => {
|
||||
props.clientState.clientSetting.setProtocol(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={props.clientState.clientSetting.setting.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>
|
||||
)
|
||||
}, [props.clientState.clientSetting.setting.protocol, props.clientState.clientSetting.setProtocol])
|
||||
|
||||
const frameworkRow = useMemo(() => {
|
||||
const onFrameworkChanged = async (val: Framework) => {
|
||||
props.clientState.serverSetting.setFramework(val)
|
||||
@ -209,10 +186,9 @@ export const useServerSettingArea = (props: UseServerSettingProps): ServerSettin
|
||||
{uploadeModelRow}
|
||||
{frameworkRow}
|
||||
{onnxExecutionProviderRow}
|
||||
{protocolRow}
|
||||
</>
|
||||
)
|
||||
}, [uploadeModelRow, frameworkRow, onnxExecutionProviderRow, protocolRow])
|
||||
}, [uploadeModelRow, frameworkRow, onnxExecutionProviderRow])
|
||||
|
||||
|
||||
return {
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { fileSelectorAsDataURL, createDummyMediaStream, SampleRate } from "@dannadori/voice-changer-client-js"
|
||||
import React, { useEffect, useMemo, useState } from "react"
|
||||
import { AUDIO_ELEMENT_FOR_PLAY_RESULT, AUDIO_ELEMENT_FOR_TEST_CONVERTED, AUDIO_ELEMENT_FOR_TEST_ORIGINAL } from "./const"
|
||||
import { AUDIO_ELEMENT_FOR_PLAY_RESULT, AUDIO_ELEMENT_FOR_TEST_CONVERTED, AUDIO_ELEMENT_FOR_TEST_CONVERTED_ECHOBACK, AUDIO_ELEMENT_FOR_TEST_ORIGINAL } from "./const"
|
||||
import { ClientState } from "./hooks/useClient";
|
||||
|
||||
|
||||
@ -44,6 +44,7 @@ export const useDeviceSetting = (audioContext: AudioContext | null, props: UseDe
|
||||
|
||||
const [audioInputForGUI, setAudioInputForGUI] = useState<string>("none")
|
||||
const [audioOutputForGUI, setAudioOutputForGUI] = useState<string>("none")
|
||||
const [fileInputEchoback, setFileInputEchoback] = useState<boolean>()//最初のmuteが有効になるように。undefined
|
||||
|
||||
|
||||
useEffect(() => {
|
||||
@ -114,6 +115,12 @@ export const useDeviceSetting = (audioContext: AudioContext | null, props: UseDe
|
||||
const dst = audioContext!.createMediaStreamDestination()
|
||||
src.connect(dst)
|
||||
props.clientState.clientSetting.setAudioInput(dst.stream)
|
||||
|
||||
const audio_echo = document.getElementById(AUDIO_ELEMENT_FOR_TEST_CONVERTED_ECHOBACK) as HTMLAudioElement
|
||||
audio_echo.srcObject = dst.stream
|
||||
audio_echo.play()
|
||||
setFileInputEchoback(false)
|
||||
|
||||
// original stream to play.
|
||||
const audio_org = document.getElementById(AUDIO_ELEMENT_FOR_TEST_ORIGINAL) as HTMLAudioElement
|
||||
audio_org.src = url
|
||||
@ -135,14 +142,16 @@ export const useDeviceSetting = (audioContext: AudioContext | null, props: UseDe
|
||||
</div>
|
||||
<div>
|
||||
cnv:<audio id={AUDIO_ELEMENT_FOR_TEST_CONVERTED} controls></audio>
|
||||
<audio id={AUDIO_ELEMENT_FOR_TEST_CONVERTED_ECHOBACK} controls hidden></audio>
|
||||
</div>
|
||||
</div>
|
||||
<div className="body-button-container">
|
||||
<div className="body-button" onClick={onFileLoadClicked}>load</div>
|
||||
<input type="checkbox" checked={fileInputEchoback} onChange={(e) => { setFileInputEchoback(e.target.checked) }} /> echoback
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}, [audioInputForGUI, props.clientState.clientSetting.setAudioInput])
|
||||
}, [audioInputForGUI, props.clientState.clientSetting.setAudioInput, fileInputEchoback])
|
||||
|
||||
|
||||
|
||||
@ -166,7 +175,7 @@ export const useDeviceSetting = (audioContext: AudioContext | null, props: UseDe
|
||||
|
||||
useEffect(() => {
|
||||
if (audioOutputForGUI == "none") return
|
||||
[AUDIO_ELEMENT_FOR_PLAY_RESULT, AUDIO_ELEMENT_FOR_TEST_ORIGINAL].forEach(x => {
|
||||
[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) {
|
||||
// @ts-ignore
|
||||
@ -175,6 +184,14 @@ export const useDeviceSetting = (audioContext: AudioContext | null, props: UseDe
|
||||
})
|
||||
}, [audioOutputForGUI])
|
||||
|
||||
useEffect(() => {
|
||||
[AUDIO_ELEMENT_FOR_TEST_CONVERTED_ECHOBACK].forEach(x => {
|
||||
const audio = document.getElementById(x) as HTMLAudioElement
|
||||
if (audio) {
|
||||
audio.volume = fileInputEchoback ? 1 : 0
|
||||
}
|
||||
})
|
||||
}, [fileInputEchoback])
|
||||
|
||||
const deviceSetting = useMemo(() => {
|
||||
return (
|
||||
|
@ -1,5 +1,4 @@
|
||||
import { BufferSize } from "@dannadori/voice-changer-client-js"
|
||||
import React, { useMemo, useState } from "react"
|
||||
import React, { useMemo } from "react"
|
||||
import { ClientState } from "./hooks/useClient"
|
||||
|
||||
export type UseConvertSettingProps = {
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { BufferSize, SampleRate, VoiceChangerMode } from "@dannadori/voice-changer-client-js"
|
||||
import { BufferSize, Protocol, SampleRate, VoiceChangerMode } from "@dannadori/voice-changer-client-js"
|
||||
import React, { useMemo, useState } from "react"
|
||||
import { ClientState } from "./hooks/useClient"
|
||||
|
||||
@ -31,6 +31,30 @@ export const useAdvancedSetting = (props: UseAdvancedSettingProps): AdvancedSett
|
||||
)
|
||||
}, [props.clientState.clientSetting.setting.mmvcServerUrl, props.clientState.clientSetting.setServerUrl])
|
||||
|
||||
const protocolRow = useMemo(() => {
|
||||
const onProtocolChanged = async (val: Protocol) => {
|
||||
props.clientState.clientSetting.setProtocol(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={props.clientState.clientSetting.setting.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>
|
||||
)
|
||||
}, [props.clientState.clientSetting.setting.protocol, props.clientState.clientSetting.setProtocol])
|
||||
|
||||
|
||||
const sampleRateRow = useMemo(() => {
|
||||
return (
|
||||
<div className="body-row split-3-7 left-padding-1 guided">
|
||||
@ -84,6 +108,20 @@ export const useAdvancedSetting = (props: UseAdvancedSettingProps): AdvancedSett
|
||||
)
|
||||
}, [props.clientState.serverSetting.setting.convertChunkNum, props.clientState.serverSetting.setConvertChunkNum])
|
||||
|
||||
const minConvertSizeRow = useMemo(() => {
|
||||
return (
|
||||
|
||||
<div className="body-row split-3-7 left-padding-1 guided">
|
||||
<div className="body-item-title left-padding-1">Min Convert Size(byte)</div>
|
||||
<div className="body-input-container">
|
||||
<input type="number" min={0} max={8196} step={8196} value={props.clientState.serverSetting.setting.minConvertSize} onChange={(e) => {
|
||||
props.clientState.serverSetting.setMinConvertSize(Number(e.target.value))
|
||||
}} />
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}, [props.clientState.serverSetting.setting.minConvertSize, props.clientState.serverSetting.setMinConvertSize])
|
||||
|
||||
const crossFadeOverlapRateRow = useMemo(() => {
|
||||
return (
|
||||
<div className="body-row split-3-7 left-padding-1 guided">
|
||||
@ -209,12 +247,14 @@ export const useAdvancedSetting = (props: UseAdvancedSettingProps): AdvancedSett
|
||||
<>
|
||||
<div className="body-row divider"></div>
|
||||
{mmvcServerUrlRow}
|
||||
{protocolRow}
|
||||
<div className="body-row divider"></div>
|
||||
{sampleRateRow}
|
||||
{bufferSizeRow}
|
||||
<div className="body-row divider"></div>
|
||||
|
||||
{convertChunkNumRow}
|
||||
{minConvertSizeRow}
|
||||
{crossFadeOverlapRateRow}
|
||||
{crossFadeOffsetRateRow}
|
||||
{crossFadeEndRateRow}
|
||||
@ -226,7 +266,7 @@ export const useAdvancedSetting = (props: UseAdvancedSettingProps): AdvancedSett
|
||||
<div className="body-row divider"></div>
|
||||
</>
|
||||
)
|
||||
}, [showAdvancedSetting, mmvcServerUrlRow, sampleRateRow, bufferSizeRow, convertChunkNumRow, crossFadeOverlapRateRow, crossFadeOffsetRateRow, crossFadeEndRateRow, vfForceDisableRow, voiceChangeModeRow, workletSettingRow])
|
||||
}, [showAdvancedSetting, mmvcServerUrlRow, protocolRow, sampleRateRow, bufferSizeRow, convertChunkNumRow, minConvertSizeRow, crossFadeOverlapRateRow, crossFadeOffsetRateRow, crossFadeEndRateRow, vfForceDisableRow, voiceChangeModeRow, workletSettingRow])
|
||||
|
||||
|
||||
const advancedSetting = useMemo(() => {
|
||||
|
@ -3,3 +3,4 @@ export const CHROME_EXTENSION = false
|
||||
export const AUDIO_ELEMENT_FOR_PLAY_RESULT = "audio-result"
|
||||
export const AUDIO_ELEMENT_FOR_TEST_ORIGINAL = "audio-test-original"
|
||||
export const AUDIO_ELEMENT_FOR_TEST_CONVERTED = "audio-test-converted"
|
||||
export const AUDIO_ELEMENT_FOR_TEST_CONVERTED_ECHOBACK = "audio-test-converted-echoback"
|
||||
|
@ -150,19 +150,23 @@ export const useClientSetting = (props: UseClientSettingProps): ClientSettingSta
|
||||
}
|
||||
}, [props.voiceChangerClient])
|
||||
|
||||
|
||||
//////////////
|
||||
// Colab対応
|
||||
// デフォルト設定
|
||||
/////////////
|
||||
useEffect(() => {
|
||||
const params = new URLSearchParams(location.search);
|
||||
const colab = params.get("colab")
|
||||
if (colab == "true") {
|
||||
settingRef.current.protocol = "rest"
|
||||
settingRef.current.inputChunkNum = 64
|
||||
_setSetting({ ...settingRef.current })
|
||||
setProtocol("rest")
|
||||
setInputChunkNum(64)
|
||||
|
||||
} else {
|
||||
setProtocol("sio")
|
||||
setInputChunkNum(32)
|
||||
|
||||
}
|
||||
}, [])
|
||||
}, [props.voiceChangerClient])
|
||||
|
||||
|
||||
|
||||
return {
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { DefaultVoiceChangerServerSetting, Framework, OnnxExecutionProvider, ServerInfo, ServerSettingKey, VoiceChangerClient, VoiceChangerServerSetting, } from "@dannadori/voice-changer-client-js"
|
||||
import { useState, useMemo, useRef, } from "react"
|
||||
import { useState, useMemo, useRef, useEffect } from "react"
|
||||
|
||||
|
||||
export type FileUploadSetting = {
|
||||
@ -25,6 +25,7 @@ export type ServerSettingState = {
|
||||
setSrcId: (num: number) => Promise<boolean>;
|
||||
setDstId: (num: number) => Promise<boolean>;
|
||||
setConvertChunkNum: (num: number) => Promise<boolean>;
|
||||
setMinConvertSize: (num: number) => Promise<boolean>
|
||||
setGpu: (num: number) => Promise<boolean>;
|
||||
setCrossFadeOffsetRate: (num: number) => Promise<boolean>;
|
||||
setCrossFadeEndRate: (num: number) => Promise<boolean>;
|
||||
@ -56,6 +57,7 @@ export const useServerSetting = (props: UseServerSettingProps): ServerSettingSta
|
||||
_setSetting({
|
||||
...settingRef.current,
|
||||
convertChunkNum: res.convertChunkNum,
|
||||
minConvertSize: res.minConvertSize,
|
||||
srcId: res.srcId,
|
||||
dstId: res.dstId,
|
||||
gpu: res.gpu,
|
||||
@ -103,6 +105,13 @@ export const useServerSetting = (props: UseServerSettingProps): ServerSettingSta
|
||||
}
|
||||
}, [props.voiceChangerClient])
|
||||
|
||||
const setMinConvertSize = useMemo(() => {
|
||||
return async (num: number) => {
|
||||
return await _set_and_store(ServerSettingKey.minConvertSize, "" + num)
|
||||
}
|
||||
}, [props.voiceChangerClient])
|
||||
|
||||
|
||||
const setGpu = useMemo(() => {
|
||||
return async (num: number) => {
|
||||
return await _set_and_store(ServerSettingKey.gpu, "" + num)
|
||||
@ -125,6 +134,8 @@ export const useServerSetting = (props: UseServerSettingProps): ServerSettingSta
|
||||
}
|
||||
}, [props.voiceChangerClient])
|
||||
|
||||
|
||||
|
||||
//////////////
|
||||
// 操作
|
||||
/////////////
|
||||
@ -195,6 +206,20 @@ export const useServerSetting = (props: UseServerSettingProps): ServerSettingSta
|
||||
}
|
||||
}, [props.voiceChangerClient])
|
||||
|
||||
|
||||
//////////////
|
||||
// デフォルト設定
|
||||
/////////////
|
||||
useEffect(() => {
|
||||
const params = new URLSearchParams(location.search);
|
||||
const colab = params.get("colab")
|
||||
if (colab == "true") {
|
||||
} else {
|
||||
}
|
||||
}, [props.voiceChangerClient])
|
||||
|
||||
|
||||
|
||||
return {
|
||||
setting,
|
||||
serverInfo,
|
||||
@ -204,6 +229,7 @@ export const useServerSetting = (props: UseServerSettingProps): ServerSettingSta
|
||||
setSrcId,
|
||||
setDstId,
|
||||
setConvertChunkNum,
|
||||
setMinConvertSize,
|
||||
setGpu,
|
||||
setCrossFadeOffsetRate,
|
||||
setCrossFadeEndRate,
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { DefaultWorkletSetting, VoiceChangerClient, WorkletSetting } from "@dannadori/voice-changer-client-js"
|
||||
import { useState, useMemo } from "react"
|
||||
import { useState, useMemo, useEffect } from "react"
|
||||
|
||||
export type UseWorkletSettingProps = {
|
||||
voiceChangerClient: VoiceChangerClient | null
|
||||
@ -22,6 +22,28 @@ export const useWorkletSetting = (props: UseWorkletSettingProps): WorkletSetting
|
||||
}
|
||||
}, [props.voiceChangerClient])
|
||||
|
||||
|
||||
//////////////
|
||||
// デフォルト設定
|
||||
/////////////
|
||||
useEffect(() => {
|
||||
const params = new URLSearchParams(location.search);
|
||||
const colab = params.get("colab")
|
||||
if (colab == "true") {
|
||||
setSetting({
|
||||
numTrancateTreshold: 300,
|
||||
volTrancateThreshold: 0.0005,
|
||||
volTrancateLength: 32,
|
||||
})
|
||||
} else {
|
||||
setSetting({
|
||||
numTrancateTreshold: 150,
|
||||
volTrancateThreshold: 0.0005,
|
||||
volTrancateLength: 32,
|
||||
})
|
||||
}
|
||||
}, [props.voiceChangerClient])
|
||||
|
||||
return {
|
||||
setting,
|
||||
setSetting
|
||||
|
@ -7,6 +7,8 @@
|
||||
// types
|
||||
export type VoiceChangerServerSetting = {
|
||||
convertChunkNum: number, // VITSに入力する変換サイズ。(入力データの2倍以上の大きさで指定。それより小さいものが指定された場合は、サーバ側で自動的に入力の2倍のサイズが設定される。)
|
||||
minConvertSize: number, // この値より小さい場合にこの値に揃える。
|
||||
|
||||
srcId: number,
|
||||
dstId: number,
|
||||
gpu: number,
|
||||
@ -50,6 +52,7 @@ export type ServerInfo = {
|
||||
pyTorchModelFile: string,
|
||||
onnxModelFile: string,
|
||||
convertChunkNum: number,
|
||||
minConvertSize: number,
|
||||
crossFadeOffsetRate: number,
|
||||
crossFadeEndRate: number,
|
||||
crossFadeOverlapRate: number,
|
||||
@ -111,6 +114,7 @@ export const ServerSettingKey = {
|
||||
"srcId": "srcId",
|
||||
"dstId": "dstId",
|
||||
"convertChunkNum": "convertChunkNum",
|
||||
"minConvertSize": "minConvertSize",
|
||||
"gpu": "gpu",
|
||||
"crossFadeOffsetRate": "crossFadeOffsetRate",
|
||||
"crossFadeEndRate": "crossFadeEndRate",
|
||||
@ -123,6 +127,7 @@ export type ServerSettingKey = typeof ServerSettingKey[keyof typeof ServerSettin
|
||||
// Defaults
|
||||
export const DefaultVoiceChangerServerSetting: VoiceChangerServerSetting = {
|
||||
convertChunkNum: 32, //(★1)
|
||||
minConvertSize: 0,
|
||||
srcId: 107,
|
||||
dstId: 100,
|
||||
gpu: 0,
|
||||
|
@ -26,12 +26,13 @@ class VocieChangerSettings():
|
||||
crossFadeEndRate:float = 0.9
|
||||
crossFadeOverlapRate:float = 0.9
|
||||
convertChunkNum:int = 32
|
||||
minConvertSize:int = 0
|
||||
framework:str = "PyTorch" # PyTorch or ONNX
|
||||
pyTorchModelFile:str = ""
|
||||
onnxModelFile:str = ""
|
||||
configFile:str = ""
|
||||
# ↓mutableな物だけ列挙
|
||||
intData = ["gpu","srcId", "dstId", "convertChunkNum"]
|
||||
intData = ["gpu","srcId", "dstId", "convertChunkNum", "minConvertSize"]
|
||||
floatData = [ "crossFadeOffsetRate", "crossFadeEndRate", "crossFadeOverlapRate"]
|
||||
strData = ["framework"]
|
||||
|
||||
@ -298,8 +299,9 @@ class VoiceChanger():
|
||||
|
||||
if unpackedData.shape[0]*(1 + self.settings.crossFadeOverlapRate) + 1024 > convertSize:
|
||||
convertSize = int(unpackedData.shape[0]*(1 + self.settings.crossFadeOverlapRate)) + 1024
|
||||
|
||||
# print("convert Size", unpackedData.shape[0], unpackedData.shape[0]*(1 + self.settings.crossFadeOverlapRate), convertSize)
|
||||
if convertSize < self.settings.minConvertSize:
|
||||
convertSize = self.settings.minConvertSize
|
||||
# print("convert Size", unpackedData.shape[0], unpackedData.shape[0]*(1 + self.settings.crossFadeOverlapRate), convertSize, self.settings.minConvertSize)
|
||||
|
||||
self._generate_strength(unpackedData)
|
||||
data = self._generate_input(unpackedData, convertSize)
|
||||
|
Loading…
x
Reference in New Issue
Block a user