mirror of
https://github.com/w-okada/voice-changer.git
synced 2025-01-23 13:35:12 +03:00
uploading status
This commit is contained in:
parent
8082783644
commit
276f086823
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
2744
client/demo/dist/index.js.LICENSE.txt
vendored
2744
client/demo/dist/index.js.LICENSE.txt
vendored
File diff suppressed because it is too large
Load Diff
@ -14,13 +14,19 @@ import { ServerSettingKey } from "@dannadori/voice-changer-client-js";
|
||||
|
||||
export const useMicrophoneOptions = () => {
|
||||
const [audioContext, setAudioContext] = useState<AudioContext | null>(null)
|
||||
const [loadModelFunc, setLoadModelFunc] = useState<() => Promise<void>>()
|
||||
const [uploadProgress, setUploadProgress] = useState<number>(0)
|
||||
const [isUploading, setIsUploading] = useState<boolean>(false)
|
||||
const clientState = useClient({
|
||||
audioContext: audioContext,
|
||||
audioOutputElementId: AUDIO_ELEMENT_FOR_PLAY_RESULT
|
||||
})
|
||||
|
||||
const serverSetting = useServerSetting({
|
||||
clientState
|
||||
clientState,
|
||||
loadModelFunc,
|
||||
uploadProgress: uploadProgress,
|
||||
isUploading: isUploading
|
||||
})
|
||||
const deviceSetting = useDeviceSetting(audioContext)
|
||||
const speakerSetting = useSpeakerSetting()
|
||||
@ -34,7 +40,8 @@ export const useMicrophoneOptions = () => {
|
||||
getInfo: clientState.getInfo,
|
||||
volume: clientState.volume,
|
||||
bufferingTime: clientState.bufferingTime,
|
||||
responseTime: clientState.responseTime
|
||||
responseTime: clientState.responseTime,
|
||||
|
||||
})
|
||||
|
||||
useEffect(() => {
|
||||
@ -51,70 +58,94 @@ export const useMicrophoneOptions = () => {
|
||||
// 101 ServerSetting
|
||||
//// サーバ変更
|
||||
useEffect(() => {
|
||||
if (!clientState.clientInitialized) return
|
||||
clientState.setServerUrl(serverSetting.mmvcServerUrl)
|
||||
}, [clientState.clientInitialized, serverSetting.mmvcServerUrl])
|
||||
}, [serverSetting.mmvcServerUrl])
|
||||
//// プロトコル変更
|
||||
useEffect(() => {
|
||||
if (!clientState.clientInitialized) return
|
||||
clientState.setProtocol(serverSetting.protocol)
|
||||
}, [clientState.clientInitialized, serverSetting.protocol])
|
||||
}, [serverSetting.protocol])
|
||||
//// フレームワーク変更
|
||||
useEffect(() => {
|
||||
if (!clientState.clientInitialized) return
|
||||
clientState.updateSettings(ServerSettingKey.framework, serverSetting.framework)
|
||||
}, [clientState.clientInitialized, serverSetting.framework])
|
||||
}, [serverSetting.framework])
|
||||
//// OnnxExecutionProvider変更
|
||||
useEffect(() => {
|
||||
if (!clientState.clientInitialized) return
|
||||
clientState.updateSettings(ServerSettingKey.onnxExecutionProvider, serverSetting.onnxExecutionProvider)
|
||||
}, [clientState.clientInitialized, serverSetting.onnxExecutionProvider])
|
||||
}, [serverSetting.onnxExecutionProvider])
|
||||
|
||||
// 102 DeviceSetting
|
||||
//// 入力情報の設定
|
||||
useEffect(() => {
|
||||
if (!clientState.clientInitialized) return
|
||||
clientState.changeInput(deviceSetting.audioInput, convertSetting.bufferSize, advancedSetting.vfForceDisabled)
|
||||
}, [clientState.clientInitialized, deviceSetting.audioInput, convertSetting.bufferSize, advancedSetting.vfForceDisabled])
|
||||
}, [deviceSetting.audioInput, convertSetting.bufferSize, advancedSetting.vfForceDisabled])
|
||||
|
||||
// 103 SpeakerSetting
|
||||
// 音声変換元、変換先の設定
|
||||
useEffect(() => {
|
||||
if (!clientState.clientInitialized) return
|
||||
clientState.updateSettings(ServerSettingKey.srcId, speakerSetting.srcId)
|
||||
}, [clientState.clientInitialized, speakerSetting.srcId])
|
||||
}, [speakerSetting.srcId])
|
||||
useEffect(() => {
|
||||
if (!clientState.clientInitialized) return
|
||||
clientState.updateSettings(ServerSettingKey.dstId, speakerSetting.dstId)
|
||||
}, [clientState.clientInitialized, speakerSetting.dstId])
|
||||
}, [speakerSetting.dstId])
|
||||
|
||||
// 104 ConvertSetting
|
||||
useEffect(() => {
|
||||
if (!clientState.clientInitialized) return
|
||||
clientState.setInputChunkNum(convertSetting.inputChunkNum)
|
||||
}, [clientState.clientInitialized, convertSetting.inputChunkNum])
|
||||
}, [convertSetting.inputChunkNum])
|
||||
useEffect(() => {
|
||||
if (!clientState.clientInitialized) return
|
||||
clientState.updateSettings(ServerSettingKey.convertChunkNum, convertSetting.convertChunkNum)
|
||||
}, [clientState.clientInitialized, convertSetting.convertChunkNum])
|
||||
}, [convertSetting.convertChunkNum])
|
||||
useEffect(() => {
|
||||
if (!clientState.clientInitialized) return
|
||||
clientState.updateSettings(ServerSettingKey.gpu, convertSetting.gpu)
|
||||
}, [clientState.clientInitialized, convertSetting.gpu])
|
||||
}, [convertSetting.gpu])
|
||||
useEffect(() => {
|
||||
if (!clientState.clientInitialized) return
|
||||
clientState.updateSettings(ServerSettingKey.crossFadeOffsetRate, convertSetting.crossFadeOffsetRate)
|
||||
}, [clientState.clientInitialized, convertSetting.crossFadeOffsetRate])
|
||||
}, [convertSetting.crossFadeOffsetRate])
|
||||
useEffect(() => {
|
||||
if (!clientState.clientInitialized) return
|
||||
clientState.updateSettings(ServerSettingKey.crossFadeEndRate, convertSetting.crossFadeEndRate)
|
||||
}, [clientState.clientInitialized, convertSetting.crossFadeEndRate])
|
||||
}, [convertSetting.crossFadeEndRate])
|
||||
|
||||
// 105 AdvancedSetting
|
||||
useEffect(() => {
|
||||
if (!clientState.clientInitialized) return
|
||||
clientState.setVoiceChangerMode(advancedSetting.voiceChangerMode)
|
||||
}, [clientState.clientInitialized, advancedSetting.voiceChangerMode])
|
||||
}, [advancedSetting.voiceChangerMode])
|
||||
|
||||
|
||||
// Model Load
|
||||
useEffect(() => {
|
||||
const loadModel = () => {
|
||||
return async () => {
|
||||
if (!serverSetting.pyTorchModel && !serverSetting.onnxModel) {
|
||||
alert("PyTorchモデルとONNXモデルのどちらか一つ以上指定する必要があります。")
|
||||
return
|
||||
}
|
||||
if (!serverSetting.configFile) {
|
||||
alert("Configファイルを指定する必要があります。")
|
||||
return
|
||||
}
|
||||
setUploadProgress(0)
|
||||
setIsUploading(true)
|
||||
const models = [serverSetting.pyTorchModel, serverSetting.onnxModel].filter(x => { return x != null }) as File[]
|
||||
for (let i = 0; i < models.length; i++) {
|
||||
const progRate = 1 / models.length
|
||||
const progOffset = 100 * i * progRate
|
||||
await clientState.uploadFile(models[i], (progress: number, end: boolean) => {
|
||||
// console.log(progress * progRate + progOffset, end, progRate,)
|
||||
setUploadProgress(progress * progRate + progOffset)
|
||||
})
|
||||
}
|
||||
|
||||
await clientState.uploadFile(serverSetting.configFile, (progress: number, end: boolean) => {
|
||||
console.log(progress, end)
|
||||
})
|
||||
|
||||
await clientState.loadModel(serverSetting.configFile, serverSetting.pyTorchModel, serverSetting.onnxModel)
|
||||
setUploadProgress(0)
|
||||
setIsUploading(false)
|
||||
}
|
||||
}
|
||||
setLoadModelFunc(loadModel)
|
||||
}, [serverSetting.configFile, serverSetting.pyTorchModel, serverSetting.onnxModel])
|
||||
|
||||
|
||||
const voiceChangerSetting = useMemo(() => {
|
||||
|
@ -5,6 +5,9 @@ import { ClientState } from "./hooks/useClient"
|
||||
|
||||
export type UseServerSettingProps = {
|
||||
clientState: ClientState
|
||||
loadModelFunc: (() => Promise<void>) | undefined
|
||||
uploadProgress: number,
|
||||
isUploading: boolean
|
||||
}
|
||||
|
||||
export type ServerSettingState = {
|
||||
@ -16,6 +19,7 @@ export type ServerSettingState = {
|
||||
framework: string;
|
||||
onnxExecutionProvider: OnnxExecutionProvider;
|
||||
protocol: Protocol;
|
||||
|
||||
}
|
||||
|
||||
export const useServerSetting = (props: UseServerSettingProps): ServerSettingState => {
|
||||
@ -54,6 +58,9 @@ export const useServerSetting = (props: UseServerSettingProps): ServerSettingSta
|
||||
}
|
||||
setPyTorchModel(file)
|
||||
}
|
||||
const onPyTorchFileClearClicked = () => {
|
||||
setPyTorchModel(null)
|
||||
}
|
||||
const onConfigFileLoadClicked = async () => {
|
||||
const file = await fileSelector("")
|
||||
if (file.name.endsWith(".json") == false) {
|
||||
@ -62,6 +69,9 @@ export const useServerSetting = (props: UseServerSettingProps): ServerSettingSta
|
||||
}
|
||||
setConfigFile(file)
|
||||
}
|
||||
const onConfigFileClearClicked = () => {
|
||||
setConfigFile(null)
|
||||
}
|
||||
const onOnnxFileLoadClicked = async () => {
|
||||
const file = await fileSelector("")
|
||||
if (file.name.endsWith(".onnx") == false) {
|
||||
@ -70,31 +80,14 @@ export const useServerSetting = (props: UseServerSettingProps): ServerSettingSta
|
||||
}
|
||||
setOnnxModel(file)
|
||||
}
|
||||
const onOnnxFileClearClicked = () => {
|
||||
setOnnxModel(null)
|
||||
}
|
||||
const onModelUploadClicked = async () => {
|
||||
if (!pyTorchModel && !onnxModel) {
|
||||
alert("PyTorchモデルとONNXモデルのどちらか一つ以上指定する必要があります。")
|
||||
if (!props.loadModelFunc) {
|
||||
return
|
||||
}
|
||||
if (!configFile) {
|
||||
alert("Configファイルを指定する必要があります。")
|
||||
return
|
||||
}
|
||||
if (pyTorchModel) {
|
||||
await props.clientState.uploadFile(pyTorchModel, (progress: number, end: boolean) => {
|
||||
console.log(progress, end)
|
||||
})
|
||||
}
|
||||
if (onnxModel) {
|
||||
await props.clientState.uploadFile(onnxModel, (progress: number, end: boolean) => {
|
||||
console.log(progress, end)
|
||||
})
|
||||
}
|
||||
await props.clientState.uploadFile(configFile, (progress: number, end: boolean) => {
|
||||
console.log(progress, end)
|
||||
})
|
||||
|
||||
await props.clientState.loadModel(configFile, pyTorchModel, onnxModel)
|
||||
console.log("loaded")
|
||||
props.loadModelFunc()
|
||||
}
|
||||
|
||||
return (
|
||||
@ -115,6 +108,7 @@ export const useServerSetting = (props: UseServerSettingProps): ServerSettingSta
|
||||
</div>
|
||||
<div className="body-button-container">
|
||||
<div className="body-button" onClick={onPyTorchFileLoadClicked}>select</div>
|
||||
<div className="body-button left-margin-1" onClick={onPyTorchFileClearClicked}>clear</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="body-row split-3-3-4 left-padding-1 guided">
|
||||
@ -124,6 +118,7 @@ export const useServerSetting = (props: UseServerSettingProps): ServerSettingSta
|
||||
</div>
|
||||
<div className="body-button-container">
|
||||
<div className="body-button" onClick={onConfigFileLoadClicked}>select</div>
|
||||
<div className="body-button left-margin-1" onClick={onConfigFileClearClicked}>clear</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="body-row split-3-3-4 left-padding-1 guided">
|
||||
@ -133,11 +128,13 @@ export const useServerSetting = (props: UseServerSettingProps): ServerSettingSta
|
||||
</div>
|
||||
<div className="body-button-container">
|
||||
<div className="body-button" onClick={onOnnxFileLoadClicked}>select</div>
|
||||
<div className="body-button left-margin-1" onClick={onOnnxFileClearClicked}>clear</div>
|
||||
</div>
|
||||
</div>
|
||||
<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">
|
||||
{props.isUploading ? `uploading.... ${props.uploadProgress}%` : ""}
|
||||
</div>
|
||||
<div className="body-button-container">
|
||||
<div className="body-button" onClick={onModelUploadClicked}>upload</div>
|
||||
@ -145,7 +142,7 @@ export const useServerSetting = (props: UseServerSettingProps): ServerSettingSta
|
||||
</div>
|
||||
</>
|
||||
)
|
||||
}, [pyTorchModel, configFile, onnxModel, mmvcServerUrl])
|
||||
}, [pyTorchModel, configFile, onnxModel, props.loadModelFunc, props.isUploading, props.uploadProgress])
|
||||
|
||||
const protocolRow = useMemo(() => {
|
||||
const onProtocolChanged = async (val: Protocol) => {
|
||||
|
@ -194,6 +194,12 @@ body {
|
||||
.left-padding-2 {
|
||||
padding-left: 2rem;
|
||||
}
|
||||
.left-margin-1 {
|
||||
margin-left: 1rem;
|
||||
}
|
||||
.left-margin-2 {
|
||||
margin-left: 2rem;
|
||||
}
|
||||
.highlight {
|
||||
background-color: rgba(200, 200, 255, 0.3);
|
||||
}
|
||||
|
@ -41,6 +41,13 @@ export const useClient = (props: UseClientProps): ClientState => {
|
||||
const [responseTime, setResponseTime] = useState<number>(0)
|
||||
const [volume, setVolume] = useState<number>(0)
|
||||
|
||||
const initializedResolveRef = useRef<(value: void | PromiseLike<void>) => void>()
|
||||
const initializedPromise = useMemo(() => {
|
||||
return new Promise<void>((resolve) => {
|
||||
initializedResolveRef.current = resolve
|
||||
})
|
||||
}, [])
|
||||
|
||||
useEffect(() => {
|
||||
const initialized = async () => {
|
||||
if (!props.audioContext) {
|
||||
@ -63,6 +70,7 @@ export const useClient = (props: UseClientProps): ClientState => {
|
||||
setVolume(vol)
|
||||
}
|
||||
})
|
||||
|
||||
await voiceChangerClient.isInitialized()
|
||||
voiceChangerClientRef.current = voiceChangerClient
|
||||
console.log("[useClient] client initialized")
|
||||
@ -71,6 +79,7 @@ export const useClient = (props: UseClientProps): ClientState => {
|
||||
const audio = document.getElementById(props.audioOutputElementId) as HTMLAudioElement
|
||||
audio.srcObject = voiceChangerClientRef.current.stream
|
||||
audio.play()
|
||||
initializedResolveRef.current!()
|
||||
}
|
||||
initialized()
|
||||
}, [props.audioContext])
|
||||
@ -78,10 +87,7 @@ export const useClient = (props: UseClientProps): ClientState => {
|
||||
// Client Setting
|
||||
const setServerUrl = useMemo(() => {
|
||||
return async (mmvcServerUrl: string) => {
|
||||
if (!voiceChangerClientRef.current) {
|
||||
console.log("client is not initialized")
|
||||
return
|
||||
}
|
||||
await initializedPromise
|
||||
voiceChangerClientRef.current.setServerUrl(mmvcServerUrl, true)
|
||||
voiceChangerClientRef.current.stop()
|
||||
}
|
||||
@ -89,30 +95,21 @@ export const useClient = (props: UseClientProps): ClientState => {
|
||||
|
||||
const setProtocol = useMemo(() => {
|
||||
return async (protocol: Protocol) => {
|
||||
if (!voiceChangerClientRef.current) {
|
||||
console.log("client is not initialized")
|
||||
return
|
||||
}
|
||||
await initializedPromise
|
||||
voiceChangerClientRef.current.setProtocol(protocol)
|
||||
}
|
||||
}, [])
|
||||
|
||||
const setInputChunkNum = useMemo(() => {
|
||||
return async (num: number) => {
|
||||
if (!voiceChangerClientRef.current) {
|
||||
console.log("client is not initialized")
|
||||
return
|
||||
}
|
||||
await initializedPromise
|
||||
voiceChangerClientRef.current.setInputChunkNum(num)
|
||||
}
|
||||
}, [])
|
||||
|
||||
const setVoiceChangerMode = useMemo(() => {
|
||||
return async (val: VoiceChangerMode) => {
|
||||
if (!voiceChangerClientRef.current) {
|
||||
console.log("client is not initialized")
|
||||
return
|
||||
}
|
||||
await initializedPromise
|
||||
voiceChangerClientRef.current.setVoiceChangerMode(val)
|
||||
voiceChangerClientRef.current.stop()
|
||||
}
|
||||
@ -122,20 +119,14 @@ export const useClient = (props: UseClientProps): ClientState => {
|
||||
// Client Control
|
||||
const start = useMemo(() => {
|
||||
return async (mmvcServerUrl: string) => {
|
||||
if (!voiceChangerClientRef.current) {
|
||||
console.log("client is not initialized")
|
||||
return
|
||||
}
|
||||
await initializedPromise
|
||||
voiceChangerClientRef.current.setServerUrl(mmvcServerUrl, true)
|
||||
voiceChangerClientRef.current.start()
|
||||
}
|
||||
}, [])
|
||||
const stop = useMemo(() => {
|
||||
return async () => {
|
||||
if (!voiceChangerClientRef.current) {
|
||||
// console.log("client is not initialized")
|
||||
return
|
||||
}
|
||||
await initializedPromise
|
||||
voiceChangerClientRef.current.stop()
|
||||
}
|
||||
}, [])
|
||||
@ -144,10 +135,8 @@ export const useClient = (props: UseClientProps): ClientState => {
|
||||
// Device Setting
|
||||
const changeInput = useMemo(() => {
|
||||
return async (audioInput: MediaStream | string, bufferSize: BufferSize, vfForceDisable: boolean) => {
|
||||
if (!voiceChangerClientRef.current || !props.audioContext) {
|
||||
console.log("[useClient] not initialized", voiceChangerClientRef.current, props.audioContext)
|
||||
return
|
||||
}
|
||||
await initializedPromise
|
||||
if (!props.audioContext) return
|
||||
if (!audioInput || audioInput == "none") {
|
||||
console.log("[useClient] setup!(1)", audioInput)
|
||||
const ms = createDummyMediaStream(props.audioContext)
|
||||
@ -165,9 +154,7 @@ export const useClient = (props: UseClientProps): ClientState => {
|
||||
// Server Setting
|
||||
const uploadFile = useMemo(() => {
|
||||
return async (file: File, onprogress: (progress: number, end: boolean) => void) => {
|
||||
if (!voiceChangerClientRef.current) {
|
||||
throw "[useClient] Client Not Initialized."
|
||||
}
|
||||
await initializedPromise
|
||||
const num = await voiceChangerClientRef.current.uploadFile(file, onprogress)
|
||||
const res = await voiceChangerClientRef.current.concatUploadedFile(file, num)
|
||||
console.log("upload", num, res)
|
||||
@ -176,9 +163,7 @@ export const useClient = (props: UseClientProps): ClientState => {
|
||||
|
||||
const loadModel = useMemo(() => {
|
||||
return async (configFile: File, pyTorchModelFile: File | null, onnxModelFile: File | null) => {
|
||||
if (!voiceChangerClientRef.current) {
|
||||
throw "[useClient] Client Not Initialized."
|
||||
}
|
||||
await initializedPromise
|
||||
await voiceChangerClientRef.current.loadModel(configFile, pyTorchModelFile, onnxModelFile)
|
||||
console.log("load model")
|
||||
}
|
||||
@ -186,9 +171,7 @@ export const useClient = (props: UseClientProps): ClientState => {
|
||||
|
||||
const updateSettings = useMemo(() => {
|
||||
return async (key: ServerSettingKey, val: string | number) => {
|
||||
if (!voiceChangerClientRef.current) {
|
||||
throw "[useClient] Client Not Initialized."
|
||||
}
|
||||
await initializedPromise
|
||||
return await voiceChangerClientRef.current.updateServerSettings(key, "" + val)
|
||||
}
|
||||
}, [])
|
||||
@ -196,9 +179,7 @@ export const useClient = (props: UseClientProps): ClientState => {
|
||||
// Information
|
||||
const getInfo = useMemo(() => {
|
||||
return async () => {
|
||||
if (!voiceChangerClientRef.current) {
|
||||
throw "[useClient] Client Not Initialized."
|
||||
}
|
||||
await initializedPromise
|
||||
const serverSettings = await voiceChangerClientRef.current.getServerSettings()
|
||||
const clientSettings = await voiceChangerClientRef.current.getClientSettings()
|
||||
console.log(serverSettings, clientSettings)
|
||||
|
@ -59,7 +59,7 @@ export class ServerConfigurator {
|
||||
}
|
||||
|
||||
const chunkNum = fileChunks.length
|
||||
console.log("FILE_CHUNKS:", chunkNum, fileChunks)
|
||||
// console.log("FILE_CHUNKS:", chunkNum, fileChunks)
|
||||
|
||||
|
||||
while (true) {
|
||||
@ -77,8 +77,8 @@ export class ServerConfigurator {
|
||||
method: 'POST',
|
||||
body: formData,
|
||||
});
|
||||
fetch(request).then(async (response) => {
|
||||
console.log(await response.text())
|
||||
fetch(request).then(async (_response) => {
|
||||
// console.log(await response.text())
|
||||
resolve()
|
||||
})
|
||||
})
|
||||
|
@ -122,9 +122,7 @@ export class VoiceChnagerClient {
|
||||
|
||||
// create mic stream
|
||||
if (this.micStream) {
|
||||
console.log("DESTROY!!!!!!!!!!!!!!!!!!!")
|
||||
this.micStream.unpipe()
|
||||
// this.micStream.stop()
|
||||
this.micStream.destroy()
|
||||
this.micStream = null
|
||||
}
|
||||
@ -176,9 +174,8 @@ export class VoiceChnagerClient {
|
||||
setServerUrl = (serverUrl: string, openTab: boolean = false) => {
|
||||
const url = validateUrl(serverUrl)
|
||||
const pageUrl = `${location.protocol}//${location.host}`
|
||||
console.log("SERVER CHECK", url, pageUrl)
|
||||
|
||||
if (url != pageUrl && location.protocol == "https:" && this.sslCertified.includes(url) == false) {
|
||||
if (url != pageUrl && url.length != 0 && location.protocol == "https:" && this.sslCertified.includes(url) == false) {
|
||||
if (openTab) {
|
||||
const value = window.confirm("MMVC Server is different from this page's origin. Open tab to open ssl connection. OK? (You can close the opened tab after ssl connection succeed.)");
|
||||
if (value) {
|
||||
|
@ -9,7 +9,7 @@ import logging
|
||||
# logger = logging.getLogger("uvicorn.error")
|
||||
# logger.addFilter(UvicornSuppressFilter())
|
||||
# # logger.propagate = False
|
||||
# logger = logging.getLogger("multipart.multipart")
|
||||
# logger.propagate = False
|
||||
logger = logging.getLogger("multipart.multipart")
|
||||
logger.propagate = False
|
||||
|
||||
logging.getLogger('asyncio').setLevel(logging.WARNING)
|
||||
|
@ -1,5 +1,6 @@
|
||||
import base64, struct
|
||||
import numpy as np
|
||||
import traceback
|
||||
|
||||
from fastapi import APIRouter
|
||||
from fastapi.encoders import jsonable_encoder
|
||||
@ -10,14 +11,7 @@ from pydantic import BaseModel
|
||||
import threading
|
||||
|
||||
class VoiceModel(BaseModel):
|
||||
gpu: int
|
||||
srcId: int
|
||||
dstId: int
|
||||
timestamp: int
|
||||
convertChunkNum: int
|
||||
crossFadeLowerValue: float
|
||||
crossFadeOffsetRate:float
|
||||
crossFadeEndRate:float
|
||||
buffer: str
|
||||
|
||||
class MMVC_Rest_VoiceChanger:
|
||||
@ -30,14 +24,7 @@ class MMVC_Rest_VoiceChanger:
|
||||
|
||||
def test(self, voice: VoiceModel):
|
||||
try:
|
||||
gpu = voice.gpu
|
||||
srcId = voice.srcId
|
||||
dstId = voice.dstId
|
||||
timestamp = voice.timestamp
|
||||
convertChunkNum = voice.convertChunkNum
|
||||
crossFadeLowerValue = voice.crossFadeLowerValue
|
||||
crossFadeOffsetRate = voice.crossFadeOffsetRate
|
||||
crossFadeEndRate = voice.crossFadeEndRate
|
||||
buffer = voice.buffer
|
||||
wav = base64.b64decode(buffer)
|
||||
|
||||
@ -51,17 +38,12 @@ class MMVC_Rest_VoiceChanger:
|
||||
# unpackedData.astype(np.int16))
|
||||
|
||||
self.tlock.acquire()
|
||||
changedVoice = self.voiceChangerManager.changeVoice(
|
||||
gpu, srcId, dstId, timestamp, convertChunkNum, crossFadeLowerValue, crossFadeOffsetRate, crossFadeEndRate, unpackedData)
|
||||
changedVoice = self.voiceChangerManager.changeVoice( unpackedData)
|
||||
self.tlock.release()
|
||||
|
||||
changedVoiceBase64 = base64.b64encode(changedVoice).decode('utf-8')
|
||||
data = {
|
||||
"gpu": gpu,
|
||||
"srcId": srcId,
|
||||
"dstId": dstId,
|
||||
"timestamp": timestamp,
|
||||
"convertChunkNum": voice.convertChunkNum,
|
||||
"changedVoiceBase64": changedVoiceBase64
|
||||
}
|
||||
|
||||
@ -71,6 +53,7 @@ class MMVC_Rest_VoiceChanger:
|
||||
except Exception as e:
|
||||
print("REQUEST PROCESSING!!!! EXCEPTION!!!", e)
|
||||
print(traceback.format_exc())
|
||||
self.tlock.release()
|
||||
return str(e)
|
||||
|
||||
|
||||
|
@ -86,19 +86,25 @@ class VoiceChanger():
|
||||
self.onnx_session = None
|
||||
|
||||
def destroy(self):
|
||||
del self.net_g
|
||||
del self.onnx_session
|
||||
if hasattr(self, "net_g"):
|
||||
del self.net_g
|
||||
if hasattr(self, "onnx_session"):
|
||||
del self.onnx_session
|
||||
|
||||
def get_info(self):
|
||||
data = asdict(self.settings)
|
||||
data["providers"] = self.onnx_session.get_providers() if hasattr(self, "onnx_session") else ""
|
||||
data["providers"] = self.onnx_session.get_providers() if self.onnx_session != None else ""
|
||||
files = ["config_file", "pyTorch_model_file", "onnx_model_file"]
|
||||
for f in files:
|
||||
data[f] = os.path.basename(data[f])
|
||||
if os.path.exists(f):
|
||||
data[f] = os.path.basename(data[f])
|
||||
else:
|
||||
data[f] = ""
|
||||
|
||||
return data
|
||||
|
||||
def update_setteings(self, key:str, val:any):
|
||||
if key == "onnxExecutionProvider":
|
||||
if key == "onnxExecutionProvider" and self.onnx_session != None:
|
||||
if val == "CUDAExecutionProvider":
|
||||
provider_options=[{'device_id': self.settings.gpu}]
|
||||
self.onnx_session.set_providers(providers=[val], provider_options=provider_options)
|
||||
@ -107,7 +113,7 @@ class VoiceChanger():
|
||||
return self.get_info()
|
||||
elif key in self.settings.intData:
|
||||
setattr(self.settings, key, int(val))
|
||||
if key == "gpu" and val >= 0 and val < self.gpu_num and hasattr(self, "onnx_session"):
|
||||
if key == "gpu" and val >= 0 and val < self.gpu_num and self.onnx_session != None:
|
||||
providers = self.onnx_session.get_providers()
|
||||
print("Providers::::", providers)
|
||||
if "CUDAExecutionProvider" in providers:
|
||||
@ -176,35 +182,40 @@ class VoiceChanger():
|
||||
|
||||
|
||||
def _onnx_inference(self, data, inputSize):
|
||||
if hasattr(self, 'onnx_session'):
|
||||
x, x_lengths, spec, spec_lengths, y, y_lengths, sid_src = [x for x in data]
|
||||
sid_tgt1 = torch.LongTensor([self.settings.dstId])
|
||||
# if spec.size()[2] >= 8:
|
||||
audio1 = self.onnx_session.run(
|
||||
["audio"],
|
||||
{
|
||||
"specs": spec.numpy(),
|
||||
"lengths": spec_lengths.numpy(),
|
||||
"sid_src": sid_src.numpy(),
|
||||
"sid_tgt": sid_tgt1.numpy()
|
||||
})[0][0,0] * self.hps.data.max_wav_value
|
||||
if hasattr(self, 'np_prev_audio1') == True:
|
||||
prev = self.np_prev_audio1[-1*inputSize:]
|
||||
cur = audio1[-2*inputSize:-1*inputSize]
|
||||
# print(prev.shape, self.np_prev_strength.shape, cur.shape, self.np_cur_strength.shape)
|
||||
powered_prev = prev * self.np_prev_strength
|
||||
powered_cur = cur * self.np_cur_strength
|
||||
result = powered_prev + powered_cur
|
||||
#result = prev * self.np_prev_strength + cur * self.np_cur_strength
|
||||
else:
|
||||
cur = audio1[-2*inputSize:-1*inputSize]
|
||||
result = cur
|
||||
self.np_prev_audio1 = audio1
|
||||
return result
|
||||
if hasattr(self, "onnx_session") == False or self.onnx_session == None:
|
||||
print("[Voice Changer] No ONNX session.")
|
||||
return np.zeros(1).astype(np.int16)
|
||||
|
||||
x, x_lengths, spec, spec_lengths, y, y_lengths, sid_src = [x for x in data]
|
||||
sid_tgt1 = torch.LongTensor([self.settings.dstId])
|
||||
# if spec.size()[2] >= 8:
|
||||
audio1 = self.onnx_session.run(
|
||||
["audio"],
|
||||
{
|
||||
"specs": spec.numpy(),
|
||||
"lengths": spec_lengths.numpy(),
|
||||
"sid_src": sid_src.numpy(),
|
||||
"sid_tgt": sid_tgt1.numpy()
|
||||
})[0][0,0] * self.hps.data.max_wav_value
|
||||
if hasattr(self, 'np_prev_audio1') == True:
|
||||
prev = self.np_prev_audio1[-1*inputSize:]
|
||||
cur = audio1[-2*inputSize:-1*inputSize]
|
||||
# print(prev.shape, self.np_prev_strength.shape, cur.shape, self.np_cur_strength.shape)
|
||||
powered_prev = prev * self.np_prev_strength
|
||||
powered_cur = cur * self.np_cur_strength
|
||||
result = powered_prev + powered_cur
|
||||
#result = prev * self.np_prev_strength + cur * self.np_cur_strength
|
||||
else:
|
||||
raise ValueError(ERROR_NO_ONNX_SESSION, "No ONNX Session.")
|
||||
cur = audio1[-2*inputSize:-1*inputSize]
|
||||
result = cur
|
||||
self.np_prev_audio1 = audio1
|
||||
return result
|
||||
|
||||
def _pyTorch_inference(self, data, inputSize):
|
||||
if hasattr(self, "net_g") == False or self.net_g ==None:
|
||||
print("[Voice Changer] No pyTorch session.")
|
||||
return np.zeros(1).astype(np.int16)
|
||||
|
||||
if self.settings.gpu < 0 or self.gpu_num == 0:
|
||||
with torch.no_grad():
|
||||
x, x_lengths, spec, spec_lengths, y, y_lengths, sid_src = [x.cpu() for x in data]
|
||||
@ -281,8 +292,11 @@ class VoiceChanger():
|
||||
except Exception as e:
|
||||
print("VC PROCESSING!!!! EXCEPTION!!!", e)
|
||||
print(traceback.format_exc())
|
||||
del self.np_prev_audio1
|
||||
del self.prev_audio1
|
||||
if hasattr(self, "np_prev_audio1"):
|
||||
del self.np_prev_audio1
|
||||
if hasattr(self, "prev_audio1"):
|
||||
del self.prev_audio1
|
||||
return np.zeros(1).astype(np.int16)
|
||||
|
||||
result = result.astype(np.int16)
|
||||
# print("on_request result size:",result.shape)
|
||||
|
Loading…
Reference in New Issue
Block a user