mirror of
https://github.com/w-okada/voice-changer.git
synced 2025-01-23 13:35:12 +03:00
server audio
This commit is contained in:
parent
f4e409187e
commit
af4cf4857e
@ -68,7 +68,12 @@
|
|||||||
"options": {}
|
"options": {}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
|
||||||
"deviceSetting": [
|
"deviceSetting": [
|
||||||
|
{
|
||||||
|
"name": "audioDeviceMode",
|
||||||
|
"options": {}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "audioInput",
|
"name": "audioInput",
|
||||||
"options": {}
|
"options": {}
|
||||||
@ -76,6 +81,10 @@
|
|||||||
{
|
{
|
||||||
"name": "audioOutput",
|
"name": "audioOutput",
|
||||||
"options": {}
|
"options": {}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "ioBuffer",
|
||||||
|
"options": {}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"qualityControl": [
|
"qualityControl": [
|
||||||
|
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
792
client/demo/package-lock.json
generated
792
client/demo/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -23,14 +23,14 @@
|
|||||||
"@babel/preset-env": "^7.21.5",
|
"@babel/preset-env": "^7.21.5",
|
||||||
"@babel/preset-react": "^7.18.6",
|
"@babel/preset-react": "^7.18.6",
|
||||||
"@babel/preset-typescript": "^7.21.5",
|
"@babel/preset-typescript": "^7.21.5",
|
||||||
"@types/node": "^18.16.3",
|
"@types/node": "^20.1.0",
|
||||||
"@types/react": "^18.2.5",
|
"@types/react": "^18.2.6",
|
||||||
"@types/react-dom": "^18.2.3",
|
"@types/react-dom": "^18.2.4",
|
||||||
"autoprefixer": "^10.4.14",
|
"autoprefixer": "^10.4.14",
|
||||||
"babel-loader": "^9.1.2",
|
"babel-loader": "^9.1.2",
|
||||||
"copy-webpack-plugin": "^11.0.0",
|
"copy-webpack-plugin": "^11.0.0",
|
||||||
"css-loader": "^6.7.3",
|
"css-loader": "^6.7.3",
|
||||||
"eslint": "^8.39.0",
|
"eslint": "^8.40.0",
|
||||||
"eslint-config-prettier": "^8.8.0",
|
"eslint-config-prettier": "^8.8.0",
|
||||||
"eslint-plugin-prettier": "^4.2.1",
|
"eslint-plugin-prettier": "^4.2.1",
|
||||||
"eslint-plugin-react": "^7.32.2",
|
"eslint-plugin-react": "^7.32.2",
|
||||||
@ -51,7 +51,7 @@
|
|||||||
"webpack-dev-server": "^4.13.3"
|
"webpack-dev-server": "^4.13.3"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@dannadori/voice-changer-client-js": "^1.0.122",
|
"@dannadori/voice-changer-client-js": "^1.0.123",
|
||||||
"@fortawesome/fontawesome-svg-core": "^6.4.0",
|
"@fortawesome/fontawesome-svg-core": "^6.4.0",
|
||||||
"@fortawesome/free-brands-svg-icons": "^6.4.0",
|
"@fortawesome/free-brands-svg-icons": "^6.4.0",
|
||||||
"@fortawesome/free-regular-svg-icons": "^6.4.0",
|
"@fortawesome/free-regular-svg-icons": "^6.4.0",
|
||||||
|
@ -68,7 +68,12 @@
|
|||||||
"options": {}
|
"options": {}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
|
||||||
"deviceSetting": [
|
"deviceSetting": [
|
||||||
|
{
|
||||||
|
"name": "audioDeviceMode",
|
||||||
|
"options": {}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "audioInput",
|
"name": "audioInput",
|
||||||
"options": {}
|
"options": {}
|
||||||
@ -76,6 +81,10 @@
|
|||||||
{
|
{
|
||||||
"name": "audioOutput",
|
"name": "audioOutput",
|
||||||
"options": {}
|
"options": {}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "ioBuffer",
|
||||||
|
"options": {}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"qualityControl": [
|
"qualityControl": [
|
||||||
|
@ -46,6 +46,8 @@ import { ONNXExecutorRow, ONNXExecutorRowProps } from "./components/206_ONNXExec
|
|||||||
import { MergeLabRow, MergeLabRowProps } from "./components/a01_MergeLab.Row"
|
import { MergeLabRow, MergeLabRowProps } from "./components/a01_MergeLab.Row"
|
||||||
import { ModelSwitchRow, ModelSwitchRowProps } from "./components/204v2_ModelSwitchRow"
|
import { ModelSwitchRow, ModelSwitchRowProps } from "./components/204v2_ModelSwitchRow"
|
||||||
import { EnableDirectMLRow, EnableDirectMLRowProps } from "./components/813_EnableDirectMLRow"
|
import { EnableDirectMLRow, EnableDirectMLRowProps } from "./components/813_EnableDirectMLRow"
|
||||||
|
import { AudioDeviceModeRow, AudioDeviceModeRowProps } from "./components/410_AudioDeviceModeRow"
|
||||||
|
import { IOBufferRow, IOBufferRowProps } from "./components/411_IOBufferRow"
|
||||||
|
|
||||||
export const catalog: { [key: string]: (props: any) => JSX.Element } = {}
|
export const catalog: { [key: string]: (props: any) => JSX.Element } = {}
|
||||||
|
|
||||||
@ -83,6 +85,10 @@ const initialize = () => {
|
|||||||
|
|
||||||
addToCatalog("audioInput", (props: AudioInputRowProps) => { return <AudioInputRow {...props} /> })
|
addToCatalog("audioInput", (props: AudioInputRowProps) => { return <AudioInputRow {...props} /> })
|
||||||
addToCatalog("audioOutput", (props: AudioOutputRowProps) => { return <AudioOutputRow {...props} /> })
|
addToCatalog("audioOutput", (props: AudioOutputRowProps) => { return <AudioOutputRow {...props} /> })
|
||||||
|
addToCatalog("audioDeviceMode", (props: AudioDeviceModeRowProps) => { return <AudioDeviceModeRow {...props} /> })
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
addToCatalog("noiseControl", (props: NoiseControlRowProps) => { return <NoiseControlRow {...props} /> })
|
addToCatalog("noiseControl", (props: NoiseControlRowProps) => { return <NoiseControlRow {...props} /> })
|
||||||
addToCatalog("gainControl", (props: GainControlRowProps) => { return <GainControlRow {...props} /> })
|
addToCatalog("gainControl", (props: GainControlRowProps) => { return <GainControlRow {...props} /> })
|
||||||
@ -105,7 +111,8 @@ const initialize = () => {
|
|||||||
|
|
||||||
addToCatalog("inputChunkNum", (props: InputChunkNumRowProps) => { return <InputChunkNumRow {...props} /> })
|
addToCatalog("inputChunkNum", (props: InputChunkNumRowProps) => { return <InputChunkNumRow {...props} /> })
|
||||||
addToCatalog("extraDataLength", (props: ExtraDataLengthRowProps) => { return <ExtraDataLengthRow {...props} /> })
|
addToCatalog("extraDataLength", (props: ExtraDataLengthRowProps) => { return <ExtraDataLengthRow {...props} /> })
|
||||||
addToCatalog("gpu", (props: GPURowProps) => { return < GPURow {...props} /> })
|
addToCatalog("gpu", (props: GPURowProps) => { return <GPURow {...props} /> })
|
||||||
|
addToCatalog("ioBuffer", (props: IOBufferRowProps) => { return <IOBufferRow {...props} /> })
|
||||||
|
|
||||||
addToCatalog("serverURL", (props: ServerURLRowProps) => { return <ServerURLRow {...props} /> })
|
addToCatalog("serverURL", (props: ServerURLRowProps) => { return <ServerURLRow {...props} /> })
|
||||||
addToCatalog("protocol", (props: ProtocolRowProps) => { return <ProtocolRow {...props} /> })
|
addToCatalog("protocol", (props: ProtocolRowProps) => { return <ProtocolRow {...props} /> })
|
||||||
|
@ -22,6 +22,7 @@ export const StartButtonRow = (_props: StartButtonRowProps) => {
|
|||||||
|
|
||||||
const startButtonRow = useMemo(() => {
|
const startButtonRow = useMemo(() => {
|
||||||
const onStartClicked = async () => {
|
const onStartClicked = async () => {
|
||||||
|
if (appState.serverSetting.serverSetting.enableServerAudio == 0) {
|
||||||
if (!appState.initializedRef.current) {
|
if (!appState.initializedRef.current) {
|
||||||
while (true) {
|
while (true) {
|
||||||
// console.log("wait 500ms")
|
// console.log("wait 500ms")
|
||||||
@ -38,10 +39,20 @@ export const StartButtonRow = (_props: StartButtonRowProps) => {
|
|||||||
guiState.setIsConverting(true)
|
guiState.setIsConverting(true)
|
||||||
await appState.clientSetting.start()
|
await appState.clientSetting.start()
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
appState.serverSetting.updateServerSettings({ ...appState.serverSetting.serverSetting, serverAudioStated: 1 })
|
||||||
|
guiState.setIsConverting(true)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
const onStopClicked = async () => {
|
const onStopClicked = async () => {
|
||||||
|
if (appState.serverSetting.serverSetting.enableServerAudio == 0) {
|
||||||
guiState.setIsConverting(false)
|
guiState.setIsConverting(false)
|
||||||
await appState.clientSetting.stop()
|
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 startClassName = guiState.isConverting ? "body-button-active" : "body-button-stanby"
|
||||||
const stopClassName = guiState.isConverting ? "body-button-stanby" : "body-button-active"
|
const stopClassName = guiState.isConverting ? "body-button-stanby" : "body-button-active"
|
||||||
@ -59,7 +70,7 @@ export const StartButtonRow = (_props: StartButtonRowProps) => {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}, [guiState.isConverting, appState.clientSetting.start, appState.clientSetting.stop])
|
}, [guiState.isConverting, appState.clientSetting.start, appState.clientSetting.stop, appState.serverSetting.serverSetting, , appState.serverSetting.updateServerSettings])
|
||||||
|
|
||||||
return startButtonRow
|
return startButtonRow
|
||||||
}
|
}
|
@ -1,4 +1,4 @@
|
|||||||
import React, { useMemo, useState } from "react"
|
import React, { useEffect, useMemo, useState } from "react"
|
||||||
import { useAppState } from "../../../001_provider/001_AppStateProvider"
|
import { useAppState } from "../../../001_provider/001_AppStateProvider"
|
||||||
|
|
||||||
export type PerformanceRowProps = {
|
export type PerformanceRowProps = {
|
||||||
@ -31,7 +31,31 @@ export const PerformanceRow = (_props: PerformanceRowProps) => {
|
|||||||
</div>
|
</div>
|
||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
}, [appState.volume, appState.bufferingTime, appState.performance, showPerformanceDetail])
|
}, [appState.volume, appState.bufferingTime, appState.performance, showPerformanceDetail, appState.serverSetting.serverSetting.enableServerAudio])
|
||||||
|
|
||||||
return performanceRow
|
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}
|
||||||
|
</>
|
||||||
|
)
|
||||||
}
|
}
|
@ -38,7 +38,7 @@ export const ModelSwitchRow = (_props: ModelSwitchRowProps) => {
|
|||||||
} else if (x.onnxModelFile && x.onnxModelFile.length > 0) {
|
} else if (x.onnxModelFile && x.onnxModelFile.length > 0) {
|
||||||
filename = x.onnxModelFile.replace(/^.*[\\\/]/, '')
|
filename = x.onnxModelFile.replace(/^.*[\\\/]/, '')
|
||||||
} else {
|
} else {
|
||||||
return <div key={index} ></div>
|
return null
|
||||||
}
|
}
|
||||||
const f0str = x.f0 == true ? "f0" : "nof0"
|
const f0str = x.f0 == true ? "f0" : "nof0"
|
||||||
const srstr = Math.floor(x.samplingRate / 1000) + "K"
|
const srstr = Math.floor(x.samplingRate / 1000) + "K"
|
||||||
@ -51,8 +51,8 @@ export const ModelSwitchRow = (_props: ModelSwitchRowProps) => {
|
|||||||
return (
|
return (
|
||||||
<option key={index} value={index}>{displayName}</option>
|
<option key={index} value={index}>{displayName}</option>
|
||||||
)
|
)
|
||||||
|
}).filter(x => { return x != null })
|
||||||
|
|
||||||
})
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div className="body-row split-3-7 left-padding-1 guided">
|
<div className="body-row split-3-7 left-padding-1 guided">
|
||||||
@ -60,7 +60,6 @@ export const ModelSwitchRow = (_props: ModelSwitchRowProps) => {
|
|||||||
<div className="body-input-container">
|
<div className="body-input-container">
|
||||||
<select className="body-select" value={slot} onChange={(e) => {
|
<select className="body-select" value={slot} onChange={(e) => {
|
||||||
onSwitchModelClicked(Number(e.target.value))
|
onSwitchModelClicked(Number(e.target.value))
|
||||||
appState.serverSetting.updateServerSettings({ ...appState.serverSetting.serverSetting, extraConvertSize: Number(e.target.value) })
|
|
||||||
}}>
|
}}>
|
||||||
{options}
|
{options}
|
||||||
</select>
|
</select>
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import React, { useMemo, useEffect } from "react"
|
import React, { useMemo, useEffect, useState } from "react"
|
||||||
import { useAppState } from "../../../001_provider/001_AppStateProvider"
|
import { useAppState } from "../../../001_provider/001_AppStateProvider"
|
||||||
import { useGuiState } from "../001_GuiStateProvider"
|
import { useGuiState } from "../001_GuiStateProvider"
|
||||||
import { AudioInputMediaRow } from "./401-1_AudioInputMediaRow"
|
import { AudioInputMediaRow } from "./401-1_AudioInputMediaRow"
|
||||||
@ -9,6 +9,7 @@ export type AudioInputRowProps = {
|
|||||||
export const AudioInputRow = (_props: AudioInputRowProps) => {
|
export const AudioInputRow = (_props: AudioInputRowProps) => {
|
||||||
const appState = useAppState()
|
const appState = useAppState()
|
||||||
const guiState = useGuiState()
|
const guiState = useGuiState()
|
||||||
|
const [hostApi, setHostApi] = useState<string>("")
|
||||||
|
|
||||||
// キャッシュの設定は反映(たぶん、設定操作の時も起動していしまう。が問題は起こらないはず)
|
// キャッシュの設定は反映(たぶん、設定操作の時も起動していしまう。が問題は起こらないはず)
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@ -24,6 +25,10 @@ export const AudioInputRow = (_props: AudioInputRowProps) => {
|
|||||||
|
|
||||||
|
|
||||||
const audioInputRow = useMemo(() => {
|
const audioInputRow = useMemo(() => {
|
||||||
|
if (appState.serverSetting.serverSetting.enableServerAudio == 1) {
|
||||||
|
return <></>
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="body-row split-3-7 left-padding-1 guided">
|
<div className="body-row split-3-7 left-padding-1 guided">
|
||||||
<div className="body-item-title left-padding-1">AudioInput</div>
|
<div className="body-item-title left-padding-1">AudioInput</div>
|
||||||
@ -43,7 +48,39 @@ export const AudioInputRow = (_props: AudioInputRowProps) => {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}, [guiState.inputAudioDeviceInfo, guiState.audioInputForGUI, appState.clientSetting.clientSetting, appState.clientSetting.updateClientSetting])
|
}, [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.filter(x => { return x.hostAPI == hostApi || hostApi == "" }).map((x, index) => { return <option value={x.index} key={index}>{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])
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -51,6 +88,7 @@ export const AudioInputRow = (_props: AudioInputRowProps) => {
|
|||||||
<>
|
<>
|
||||||
{audioInputRow}
|
{audioInputRow}
|
||||||
<AudioInputMediaRow />
|
<AudioInputMediaRow />
|
||||||
|
{serverAudioInputRow}
|
||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import React, { useMemo, useEffect } from "react"
|
import React, { useMemo, useEffect, useState } from "react"
|
||||||
import { useIndexedDB } from "@dannadori/voice-changer-client-js"
|
import { useIndexedDB } from "@dannadori/voice-changer-client-js"
|
||||||
import { AudioOutputRecordRow } from "./402-1_AudioOutputRecordRow"
|
import { AudioOutputRecordRow } from "./402-1_AudioOutputRecordRow"
|
||||||
import { useGuiState } from "../001_GuiStateProvider"
|
import { useGuiState } from "../001_GuiStateProvider"
|
||||||
@ -11,11 +11,12 @@ export type AudioOutputRowProps = {
|
|||||||
|
|
||||||
export const AudioOutputRow = (_props: AudioOutputRowProps) => {
|
export const AudioOutputRow = (_props: AudioOutputRowProps) => {
|
||||||
const { setAudioOutputElementId, initializedRef } = useAppState()
|
const { setAudioOutputElementId, initializedRef } = useAppState()
|
||||||
|
const appState = useAppState()
|
||||||
const guiState = useGuiState()
|
const guiState = useGuiState()
|
||||||
const { appGuiSettingState } = useAppRoot()
|
const { appGuiSettingState } = useAppRoot()
|
||||||
const clientType = appGuiSettingState.appGuiSetting.id
|
const clientType = appGuiSettingState.appGuiSetting.id
|
||||||
const { getItem, setItem } = useIndexedDB({ clientType: clientType })
|
const { getItem, setItem } = useIndexedDB({ clientType: clientType })
|
||||||
|
const [hostApi, setHostApi] = useState<string>("")
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const loadCache = async () => {
|
const loadCache = async () => {
|
||||||
@ -34,7 +35,11 @@ export const AudioOutputRow = (_props: AudioOutputRowProps) => {
|
|||||||
[AUDIO_ELEMENT_FOR_PLAY_RESULT, AUDIO_ELEMENT_FOR_TEST_ORIGINAL, AUDIO_ELEMENT_FOR_TEST_CONVERTED_ECHOBACK].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
|
const audio = document.getElementById(x) as HTMLAudioElement
|
||||||
if (audio) {
|
if (audio) {
|
||||||
if (guiState.audioOutputForGUI == "none") {
|
if (appState.serverSetting.serverSetting.enableServerAudio == 1) {
|
||||||
|
|
||||||
|
// Server Audio を使う場合はElementから音は出さない。
|
||||||
|
audio.volume = 0
|
||||||
|
} else if (guiState.audioOutputForGUI == "none") {
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
audio.setSinkId("")
|
audio.setSinkId("")
|
||||||
if (x == AUDIO_ELEMENT_FOR_TEST_CONVERTED_ECHOBACK) {
|
if (x == AUDIO_ELEMENT_FOR_TEST_CONVERTED_ECHOBACK) {
|
||||||
@ -51,6 +56,7 @@ export const AudioOutputRow = (_props: AudioOutputRowProps) => {
|
|||||||
} else {
|
} else {
|
||||||
console.warn("No audio output device. use default")
|
console.warn("No audio output device. use default")
|
||||||
}
|
}
|
||||||
|
|
||||||
if (x == AUDIO_ELEMENT_FOR_TEST_CONVERTED_ECHOBACK) {
|
if (x == AUDIO_ELEMENT_FOR_TEST_CONVERTED_ECHOBACK) {
|
||||||
audio.volume = guiState.fileInputEchoback ? 1 : 0
|
audio.volume = guiState.fileInputEchoback ? 1 : 0
|
||||||
} else {
|
} else {
|
||||||
@ -61,11 +67,15 @@ export const AudioOutputRow = (_props: AudioOutputRowProps) => {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
setAudioOutput()
|
setAudioOutput()
|
||||||
}, [guiState.audioOutputForGUI, guiState.fileInputEchoback])
|
}, [guiState.audioOutputForGUI, guiState.fileInputEchoback, appState.serverSetting.serverSetting.enableServerAudio])
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const audioOutputRow = useMemo(() => {
|
const audioOutputRow = useMemo(() => {
|
||||||
|
if (appState.serverSetting.serverSetting.enableServerAudio == 1) {
|
||||||
|
return <></>
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="body-row split-3-7 left-padding-1 guided">
|
<div className="body-row split-3-7 left-padding-1 guided">
|
||||||
<div className="body-item-title left-padding-1">AudioOutput</div>
|
<div className="body-item-title left-padding-1">AudioOutput</div>
|
||||||
@ -80,20 +90,52 @@ export const AudioOutputRow = (_props: AudioOutputRowProps) => {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
</select>
|
</select>
|
||||||
<audio hidden id={AUDIO_ELEMENT_FOR_PLAY_RESULT}></audio>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}, [guiState.outputAudioDeviceInfo, guiState.audioOutputForGUI])
|
}, [appState.serverSetting.serverSetting.enableServerAudio, guiState.outputAudioDeviceInfo, guiState.audioOutputForGUI])
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setAudioOutputElementId(AUDIO_ELEMENT_FOR_PLAY_RESULT)
|
setAudioOutputElementId(AUDIO_ELEMENT_FOR_PLAY_RESULT)
|
||||||
}, [initializedRef.current])
|
}, [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> })
|
||||||
|
|
||||||
|
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 (
|
return (
|
||||||
<>
|
<>
|
||||||
{audioOutputRow}
|
{audioOutputRow}
|
||||||
<AudioOutputRecordRow />
|
{appState.serverSetting.serverSetting.enableServerAudio == 0 ? <AudioOutputRecordRow /> : <></>}
|
||||||
|
|
||||||
|
{serverAudioOutputRow}
|
||||||
|
<audio hidden id={AUDIO_ELEMENT_FOR_PLAY_RESULT}></audio>
|
||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,50 @@
|
|||||||
|
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</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div></div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}, [appState.serverSetting.serverSetting, appState.serverSetting.updateServerSettings, guiState.isConverting])
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
{serverAudioInputRow}
|
||||||
|
</>
|
||||||
|
)
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,56 @@
|
|||||||
|
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
|
||||||
|
}
|
@ -6,6 +6,7 @@ export type InputChunkNumRowProps = {
|
|||||||
}
|
}
|
||||||
export const InputChunkNumRow = (props: InputChunkNumRowProps) => {
|
export const InputChunkNumRow = (props: InputChunkNumRowProps) => {
|
||||||
const appState = useAppState()
|
const appState = useAppState()
|
||||||
|
|
||||||
const inputChunkNumRow = useMemo(() => {
|
const inputChunkNumRow = useMemo(() => {
|
||||||
let nums: number[]
|
let nums: number[]
|
||||||
if (!props.nums) {
|
if (!props.nums) {
|
||||||
@ -20,6 +21,7 @@ export const InputChunkNumRow = (props: InputChunkNumRowProps) => {
|
|||||||
<select className="body-select" value={appState.workletNodeSetting.workletNodeSetting.inputChunkNum} onChange={(e) => {
|
<select className="body-select" value={appState.workletNodeSetting.workletNodeSetting.inputChunkNum} onChange={(e) => {
|
||||||
appState.workletNodeSetting.updateWorkletNodeSetting({ ...appState.workletNodeSetting.workletNodeSetting, inputChunkNum: Number(e.target.value) })
|
appState.workletNodeSetting.updateWorkletNodeSetting({ ...appState.workletNodeSetting.workletNodeSetting, inputChunkNum: Number(e.target.value) })
|
||||||
appState.workletNodeSetting.trancateBuffer()
|
appState.workletNodeSetting.trancateBuffer()
|
||||||
|
appState.serverSetting.updateServerSettings({ ...appState.serverSetting.serverSetting, serverReadChunkSize: Number(e.target.value) })
|
||||||
}}>
|
}}>
|
||||||
{
|
{
|
||||||
nums.map(x => {
|
nums.map(x => {
|
||||||
@ -35,7 +37,7 @@ export const InputChunkNumRow = (props: InputChunkNumRowProps) => {
|
|||||||
|
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}, [appState.workletNodeSetting.workletNodeSetting, appState.workletNodeSetting.updateWorkletNodeSetting])
|
}, [appState.workletNodeSetting.workletNodeSetting, appState.workletNodeSetting.updateWorkletNodeSetting, appState.serverSetting.serverSetting, appState.serverSetting.updateServerSettings])
|
||||||
|
|
||||||
return inputChunkNumRow
|
return inputChunkNumRow
|
||||||
}
|
}
|
146
client/lib/package-lock.json
generated
146
client/lib/package-lock.json
generated
@ -1,16 +1,16 @@
|
|||||||
{
|
{
|
||||||
"name": "@dannadori/voice-changer-client-js",
|
"name": "@dannadori/voice-changer-client-js",
|
||||||
"version": "1.0.122",
|
"version": "1.0.123",
|
||||||
"lockfileVersion": 2,
|
"lockfileVersion": 2,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "@dannadori/voice-changer-client-js",
|
"name": "@dannadori/voice-changer-client-js",
|
||||||
"version": "1.0.122",
|
"version": "1.0.123",
|
||||||
"license": "ISC",
|
"license": "ISC",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@types/readable-stream": "^2.3.15",
|
"@types/readable-stream": "^2.3.15",
|
||||||
"amazon-chime-sdk-js": "^3.13.0",
|
"amazon-chime-sdk-js": "^3.14.0",
|
||||||
"buffer": "^6.0.3",
|
"buffer": "^6.0.3",
|
||||||
"localforage": "^1.10.0",
|
"localforage": "^1.10.0",
|
||||||
"react": "^18.2.0",
|
"react": "^18.2.0",
|
||||||
@ -19,10 +19,10 @@
|
|||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/audioworklet": "^0.0.45",
|
"@types/audioworklet": "^0.0.45",
|
||||||
"@types/node": "^18.16.3",
|
"@types/node": "^20.1.0",
|
||||||
"@types/react": "18.2.5",
|
"@types/react": "18.2.6",
|
||||||
"@types/react-dom": "18.2.3",
|
"@types/react-dom": "18.2.4",
|
||||||
"eslint": "^8.39.0",
|
"eslint": "^8.40.0",
|
||||||
"eslint-config-prettier": "^8.8.0",
|
"eslint-config-prettier": "^8.8.0",
|
||||||
"eslint-plugin-prettier": "^4.2.1",
|
"eslint-plugin-prettier": "^4.2.1",
|
||||||
"eslint-plugin-react": "^7.32.2",
|
"eslint-plugin-react": "^7.32.2",
|
||||||
@ -1428,14 +1428,14 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@eslint/eslintrc": {
|
"node_modules/@eslint/eslintrc": {
|
||||||
"version": "2.0.2",
|
"version": "2.0.3",
|
||||||
"resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.0.3.tgz",
|
||||||
"integrity": "sha512-3W4f5tDUra+pA+FzgugqL2pRimUTDJWKr7BINqOpkZrC0uYI0NIc0/JFgBROCU07HR6GieA5m3/rsPIhDmCXTQ==",
|
"integrity": "sha512-+5gy6OQfk+xx3q0d6jGZZC3f3KzAkXc/IanVxd1is/VIIziRqqt3ongQz0FiTUXqTk0c7aDB3OaFuKnuSoJicQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"ajv": "^6.12.4",
|
"ajv": "^6.12.4",
|
||||||
"debug": "^4.3.2",
|
"debug": "^4.3.2",
|
||||||
"espree": "^9.5.1",
|
"espree": "^9.5.2",
|
||||||
"globals": "^13.19.0",
|
"globals": "^13.19.0",
|
||||||
"ignore": "^5.2.0",
|
"ignore": "^5.2.0",
|
||||||
"import-fresh": "^3.2.1",
|
"import-fresh": "^3.2.1",
|
||||||
@ -1451,9 +1451,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@eslint/js": {
|
"node_modules/@eslint/js": {
|
||||||
"version": "8.39.0",
|
"version": "8.40.0",
|
||||||
"resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.39.0.tgz",
|
"resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.40.0.tgz",
|
||||||
"integrity": "sha512-kf9RB0Fg7NZfap83B3QOqOGg9QmD9yBudqQXzzOtn3i4y7ZUXe5ONeW34Gwi+TxhH4mvj72R1Zc300KUMa9Bng==",
|
"integrity": "sha512-ElyB54bJIhXQYVKjDSvCkPO1iU1tSAeVQJbllWJq1XQSmmA4dgFk8CbiBGpiOPxleE48vDogxCtmMYku4HSVLA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
|
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
|
||||||
@ -1829,9 +1829,9 @@
|
|||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"node_modules/@types/node": {
|
"node_modules/@types/node": {
|
||||||
"version": "18.16.3",
|
"version": "20.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-18.16.3.tgz",
|
"resolved": "https://registry.npmjs.org/@types/node/-/node-20.1.0.tgz",
|
||||||
"integrity": "sha512-OPs5WnnT1xkCBiuQrZA4+YAV4HEJejmHneyraIaxsbev5yCEr6KMwINNFP9wQeFIw8FWcoTqF3vQsa5CDaI+8Q=="
|
"integrity": "sha512-O+z53uwx64xY7D6roOi4+jApDGFg0qn6WHcxe5QeqjMaTezBO/mxdfFXIVAVVyNWKx84OmPB3L8kbVYOTeN34A=="
|
||||||
},
|
},
|
||||||
"node_modules/@types/prop-types": {
|
"node_modules/@types/prop-types": {
|
||||||
"version": "15.7.5",
|
"version": "15.7.5",
|
||||||
@ -1852,9 +1852,9 @@
|
|||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"node_modules/@types/react": {
|
"node_modules/@types/react": {
|
||||||
"version": "18.2.5",
|
"version": "18.2.6",
|
||||||
"resolved": "https://registry.npmjs.org/@types/react/-/react-18.2.5.tgz",
|
"resolved": "https://registry.npmjs.org/@types/react/-/react-18.2.6.tgz",
|
||||||
"integrity": "sha512-RuoMedzJ5AOh23Dvws13LU9jpZHIc/k90AgmK7CecAYeWmSr3553L4u5rk4sWAPBuQosfT7HmTfG4Rg5o4nGEA==",
|
"integrity": "sha512-wRZClXn//zxCFW+ye/D2qY65UsYP1Fpex2YXorHc8awoNamkMZSvBxwxdYVInsHOZZd2Ppq8isnSzJL5Mpf8OA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@types/prop-types": "*",
|
"@types/prop-types": "*",
|
||||||
@ -1863,9 +1863,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@types/react-dom": {
|
"node_modules/@types/react-dom": {
|
||||||
"version": "18.2.3",
|
"version": "18.2.4",
|
||||||
"resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.2.3.tgz",
|
"resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.2.4.tgz",
|
||||||
"integrity": "sha512-hxXEXWxFJXbY0LMj/T69mznqOZJXNtQMqVxIiirVAZnnpeYiD4zt+lPsgcr/cfWg2VLsxZ1y26vigG03prYB+Q==",
|
"integrity": "sha512-G2mHoTMTL4yoydITgOGwWdWMVd8sNgyEP85xVmMKAPUBwQWm9wBPQUmvbeF4V3WBY1P7mmL4BkjQ0SqUpf1snw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@types/react": "*"
|
"@types/react": "*"
|
||||||
@ -2259,9 +2259,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/amazon-chime-sdk-js": {
|
"node_modules/amazon-chime-sdk-js": {
|
||||||
"version": "3.13.0",
|
"version": "3.14.0",
|
||||||
"resolved": "https://registry.npmjs.org/amazon-chime-sdk-js/-/amazon-chime-sdk-js-3.13.0.tgz",
|
"resolved": "https://registry.npmjs.org/amazon-chime-sdk-js/-/amazon-chime-sdk-js-3.14.0.tgz",
|
||||||
"integrity": "sha512-gRZ8SJgN2+0UMBRhUhAvc06ZklwDyYMEd/xJ17/lORX/XprcTVtRqicEJHxLtgzs61FKmmx1uBz0eGgrn9Dm3A==",
|
"integrity": "sha512-uNwCYygJahvncioPEzg4cDMPbYjpzbu1D92nUeYhUQcDK+qZn8zdPX8BRHI+eUSFBgI47udFPC933ZL79wXqJA==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@aws-crypto/sha256-js": "^2.0.1",
|
"@aws-crypto/sha256-js": "^2.0.1",
|
||||||
"@aws-sdk/client-chime-sdk-messaging": "^3.0.0",
|
"@aws-sdk/client-chime-sdk-messaging": "^3.0.0",
|
||||||
@ -3230,15 +3230,15 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/eslint": {
|
"node_modules/eslint": {
|
||||||
"version": "8.39.0",
|
"version": "8.40.0",
|
||||||
"resolved": "https://registry.npmjs.org/eslint/-/eslint-8.39.0.tgz",
|
"resolved": "https://registry.npmjs.org/eslint/-/eslint-8.40.0.tgz",
|
||||||
"integrity": "sha512-mwiok6cy7KTW7rBpo05k6+p4YVZByLNjAZ/ACB9DRCu4YDRwjXI01tWHp6KAUWelsBetTxKK/2sHB0vdS8Z2Og==",
|
"integrity": "sha512-bvR+TsP9EHL3TqNtj9sCNJVAFK3fBN8Q7g5waghxyRsPLIMwL73XSKnZFK0hk/O2ANC+iAoq6PWMQ+IfBAJIiQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@eslint-community/eslint-utils": "^4.2.0",
|
"@eslint-community/eslint-utils": "^4.2.0",
|
||||||
"@eslint-community/regexpp": "^4.4.0",
|
"@eslint-community/regexpp": "^4.4.0",
|
||||||
"@eslint/eslintrc": "^2.0.2",
|
"@eslint/eslintrc": "^2.0.3",
|
||||||
"@eslint/js": "8.39.0",
|
"@eslint/js": "8.40.0",
|
||||||
"@humanwhocodes/config-array": "^0.11.8",
|
"@humanwhocodes/config-array": "^0.11.8",
|
||||||
"@humanwhocodes/module-importer": "^1.0.1",
|
"@humanwhocodes/module-importer": "^1.0.1",
|
||||||
"@nodelib/fs.walk": "^1.2.8",
|
"@nodelib/fs.walk": "^1.2.8",
|
||||||
@ -3249,8 +3249,8 @@
|
|||||||
"doctrine": "^3.0.0",
|
"doctrine": "^3.0.0",
|
||||||
"escape-string-regexp": "^4.0.0",
|
"escape-string-regexp": "^4.0.0",
|
||||||
"eslint-scope": "^7.2.0",
|
"eslint-scope": "^7.2.0",
|
||||||
"eslint-visitor-keys": "^3.4.0",
|
"eslint-visitor-keys": "^3.4.1",
|
||||||
"espree": "^9.5.1",
|
"espree": "^9.5.2",
|
||||||
"esquery": "^1.4.2",
|
"esquery": "^1.4.2",
|
||||||
"esutils": "^2.0.2",
|
"esutils": "^2.0.2",
|
||||||
"fast-deep-equal": "^3.1.3",
|
"fast-deep-equal": "^3.1.3",
|
||||||
@ -3377,9 +3377,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/eslint-visitor-keys": {
|
"node_modules/eslint-visitor-keys": {
|
||||||
"version": "3.4.0",
|
"version": "3.4.1",
|
||||||
"resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.0.tgz",
|
"resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.1.tgz",
|
||||||
"integrity": "sha512-HPpKPUBQcAsZOsHAFwTtIKcYlCje62XB7SEAcxjtmW6TD1WVpkS6i6/hOVtTZIl4zGj/mBqpFVGvaDneik+VoQ==",
|
"integrity": "sha512-pZnmmLwYzf+kWaM/Qgrvpen51upAktaaiI01nsJD/Yr3lMOdNtq0cxkrrg16w64VtisN6okbs7Q8AfGqj4c9fA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
|
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
|
||||||
@ -3413,14 +3413,14 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/espree": {
|
"node_modules/espree": {
|
||||||
"version": "9.5.1",
|
"version": "9.5.2",
|
||||||
"resolved": "https://registry.npmjs.org/espree/-/espree-9.5.1.tgz",
|
"resolved": "https://registry.npmjs.org/espree/-/espree-9.5.2.tgz",
|
||||||
"integrity": "sha512-5yxtHSZXRSW5pvv3hAlXM5+/Oswi1AUFqBmbibKb5s6bp3rGIDkyXU6xCoyuuLhijr4SFwPrXRoZjz0AZDN9tg==",
|
"integrity": "sha512-7OASN1Wma5fum5SrNhFMAMJxOUAbhyfQ8dQ//PJaJbNw0URTPWqIghHWt1MmAANKhHZIYOHruW4Kw4ruUWOdGw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"acorn": "^8.8.0",
|
"acorn": "^8.8.0",
|
||||||
"acorn-jsx": "^5.3.2",
|
"acorn-jsx": "^5.3.2",
|
||||||
"eslint-visitor-keys": "^3.4.0"
|
"eslint-visitor-keys": "^3.4.1"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
|
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
|
||||||
@ -9118,14 +9118,14 @@
|
|||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"@eslint/eslintrc": {
|
"@eslint/eslintrc": {
|
||||||
"version": "2.0.2",
|
"version": "2.0.3",
|
||||||
"resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.0.3.tgz",
|
||||||
"integrity": "sha512-3W4f5tDUra+pA+FzgugqL2pRimUTDJWKr7BINqOpkZrC0uYI0NIc0/JFgBROCU07HR6GieA5m3/rsPIhDmCXTQ==",
|
"integrity": "sha512-+5gy6OQfk+xx3q0d6jGZZC3f3KzAkXc/IanVxd1is/VIIziRqqt3ongQz0FiTUXqTk0c7aDB3OaFuKnuSoJicQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"ajv": "^6.12.4",
|
"ajv": "^6.12.4",
|
||||||
"debug": "^4.3.2",
|
"debug": "^4.3.2",
|
||||||
"espree": "^9.5.1",
|
"espree": "^9.5.2",
|
||||||
"globals": "^13.19.0",
|
"globals": "^13.19.0",
|
||||||
"ignore": "^5.2.0",
|
"ignore": "^5.2.0",
|
||||||
"import-fresh": "^3.2.1",
|
"import-fresh": "^3.2.1",
|
||||||
@ -9135,9 +9135,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@eslint/js": {
|
"@eslint/js": {
|
||||||
"version": "8.39.0",
|
"version": "8.40.0",
|
||||||
"resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.39.0.tgz",
|
"resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.40.0.tgz",
|
||||||
"integrity": "sha512-kf9RB0Fg7NZfap83B3QOqOGg9QmD9yBudqQXzzOtn3i4y7ZUXe5ONeW34Gwi+TxhH4mvj72R1Zc300KUMa9Bng==",
|
"integrity": "sha512-ElyB54bJIhXQYVKjDSvCkPO1iU1tSAeVQJbllWJq1XQSmmA4dgFk8CbiBGpiOPxleE48vDogxCtmMYku4HSVLA==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"@humanwhocodes/config-array": {
|
"@humanwhocodes/config-array": {
|
||||||
@ -9476,9 +9476,9 @@
|
|||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"@types/node": {
|
"@types/node": {
|
||||||
"version": "18.16.3",
|
"version": "20.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-18.16.3.tgz",
|
"resolved": "https://registry.npmjs.org/@types/node/-/node-20.1.0.tgz",
|
||||||
"integrity": "sha512-OPs5WnnT1xkCBiuQrZA4+YAV4HEJejmHneyraIaxsbev5yCEr6KMwINNFP9wQeFIw8FWcoTqF3vQsa5CDaI+8Q=="
|
"integrity": "sha512-O+z53uwx64xY7D6roOi4+jApDGFg0qn6WHcxe5QeqjMaTezBO/mxdfFXIVAVVyNWKx84OmPB3L8kbVYOTeN34A=="
|
||||||
},
|
},
|
||||||
"@types/prop-types": {
|
"@types/prop-types": {
|
||||||
"version": "15.7.5",
|
"version": "15.7.5",
|
||||||
@ -9499,9 +9499,9 @@
|
|||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"@types/react": {
|
"@types/react": {
|
||||||
"version": "18.2.5",
|
"version": "18.2.6",
|
||||||
"resolved": "https://registry.npmjs.org/@types/react/-/react-18.2.5.tgz",
|
"resolved": "https://registry.npmjs.org/@types/react/-/react-18.2.6.tgz",
|
||||||
"integrity": "sha512-RuoMedzJ5AOh23Dvws13LU9jpZHIc/k90AgmK7CecAYeWmSr3553L4u5rk4sWAPBuQosfT7HmTfG4Rg5o4nGEA==",
|
"integrity": "sha512-wRZClXn//zxCFW+ye/D2qY65UsYP1Fpex2YXorHc8awoNamkMZSvBxwxdYVInsHOZZd2Ppq8isnSzJL5Mpf8OA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"@types/prop-types": "*",
|
"@types/prop-types": "*",
|
||||||
@ -9510,9 +9510,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@types/react-dom": {
|
"@types/react-dom": {
|
||||||
"version": "18.2.3",
|
"version": "18.2.4",
|
||||||
"resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.2.3.tgz",
|
"resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.2.4.tgz",
|
||||||
"integrity": "sha512-hxXEXWxFJXbY0LMj/T69mznqOZJXNtQMqVxIiirVAZnnpeYiD4zt+lPsgcr/cfWg2VLsxZ1y26vigG03prYB+Q==",
|
"integrity": "sha512-G2mHoTMTL4yoydITgOGwWdWMVd8sNgyEP85xVmMKAPUBwQWm9wBPQUmvbeF4V3WBY1P7mmL4BkjQ0SqUpf1snw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"@types/react": "*"
|
"@types/react": "*"
|
||||||
@ -9854,9 +9854,9 @@
|
|||||||
"requires": {}
|
"requires": {}
|
||||||
},
|
},
|
||||||
"amazon-chime-sdk-js": {
|
"amazon-chime-sdk-js": {
|
||||||
"version": "3.13.0",
|
"version": "3.14.0",
|
||||||
"resolved": "https://registry.npmjs.org/amazon-chime-sdk-js/-/amazon-chime-sdk-js-3.13.0.tgz",
|
"resolved": "https://registry.npmjs.org/amazon-chime-sdk-js/-/amazon-chime-sdk-js-3.14.0.tgz",
|
||||||
"integrity": "sha512-gRZ8SJgN2+0UMBRhUhAvc06ZklwDyYMEd/xJ17/lORX/XprcTVtRqicEJHxLtgzs61FKmmx1uBz0eGgrn9Dm3A==",
|
"integrity": "sha512-uNwCYygJahvncioPEzg4cDMPbYjpzbu1D92nUeYhUQcDK+qZn8zdPX8BRHI+eUSFBgI47udFPC933ZL79wXqJA==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"@aws-crypto/sha256-js": "^2.0.1",
|
"@aws-crypto/sha256-js": "^2.0.1",
|
||||||
"@aws-sdk/client-chime-sdk-messaging": "^3.0.0",
|
"@aws-sdk/client-chime-sdk-messaging": "^3.0.0",
|
||||||
@ -10566,15 +10566,15 @@
|
|||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"eslint": {
|
"eslint": {
|
||||||
"version": "8.39.0",
|
"version": "8.40.0",
|
||||||
"resolved": "https://registry.npmjs.org/eslint/-/eslint-8.39.0.tgz",
|
"resolved": "https://registry.npmjs.org/eslint/-/eslint-8.40.0.tgz",
|
||||||
"integrity": "sha512-mwiok6cy7KTW7rBpo05k6+p4YVZByLNjAZ/ACB9DRCu4YDRwjXI01tWHp6KAUWelsBetTxKK/2sHB0vdS8Z2Og==",
|
"integrity": "sha512-bvR+TsP9EHL3TqNtj9sCNJVAFK3fBN8Q7g5waghxyRsPLIMwL73XSKnZFK0hk/O2ANC+iAoq6PWMQ+IfBAJIiQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"@eslint-community/eslint-utils": "^4.2.0",
|
"@eslint-community/eslint-utils": "^4.2.0",
|
||||||
"@eslint-community/regexpp": "^4.4.0",
|
"@eslint-community/regexpp": "^4.4.0",
|
||||||
"@eslint/eslintrc": "^2.0.2",
|
"@eslint/eslintrc": "^2.0.3",
|
||||||
"@eslint/js": "8.39.0",
|
"@eslint/js": "8.40.0",
|
||||||
"@humanwhocodes/config-array": "^0.11.8",
|
"@humanwhocodes/config-array": "^0.11.8",
|
||||||
"@humanwhocodes/module-importer": "^1.0.1",
|
"@humanwhocodes/module-importer": "^1.0.1",
|
||||||
"@nodelib/fs.walk": "^1.2.8",
|
"@nodelib/fs.walk": "^1.2.8",
|
||||||
@ -10585,8 +10585,8 @@
|
|||||||
"doctrine": "^3.0.0",
|
"doctrine": "^3.0.0",
|
||||||
"escape-string-regexp": "^4.0.0",
|
"escape-string-regexp": "^4.0.0",
|
||||||
"eslint-scope": "^7.2.0",
|
"eslint-scope": "^7.2.0",
|
||||||
"eslint-visitor-keys": "^3.4.0",
|
"eslint-visitor-keys": "^3.4.1",
|
||||||
"espree": "^9.5.1",
|
"espree": "^9.5.2",
|
||||||
"esquery": "^1.4.2",
|
"esquery": "^1.4.2",
|
||||||
"esutils": "^2.0.2",
|
"esutils": "^2.0.2",
|
||||||
"fast-deep-equal": "^3.1.3",
|
"fast-deep-equal": "^3.1.3",
|
||||||
@ -10674,9 +10674,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"eslint-visitor-keys": {
|
"eslint-visitor-keys": {
|
||||||
"version": "3.4.0",
|
"version": "3.4.1",
|
||||||
"resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.0.tgz",
|
"resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.1.tgz",
|
||||||
"integrity": "sha512-HPpKPUBQcAsZOsHAFwTtIKcYlCje62XB7SEAcxjtmW6TD1WVpkS6i6/hOVtTZIl4zGj/mBqpFVGvaDneik+VoQ==",
|
"integrity": "sha512-pZnmmLwYzf+kWaM/Qgrvpen51upAktaaiI01nsJD/Yr3lMOdNtq0cxkrrg16w64VtisN6okbs7Q8AfGqj4c9fA==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"eslint-webpack-plugin": {
|
"eslint-webpack-plugin": {
|
||||||
@ -10693,14 +10693,14 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"espree": {
|
"espree": {
|
||||||
"version": "9.5.1",
|
"version": "9.5.2",
|
||||||
"resolved": "https://registry.npmjs.org/espree/-/espree-9.5.1.tgz",
|
"resolved": "https://registry.npmjs.org/espree/-/espree-9.5.2.tgz",
|
||||||
"integrity": "sha512-5yxtHSZXRSW5pvv3hAlXM5+/Oswi1AUFqBmbibKb5s6bp3rGIDkyXU6xCoyuuLhijr4SFwPrXRoZjz0AZDN9tg==",
|
"integrity": "sha512-7OASN1Wma5fum5SrNhFMAMJxOUAbhyfQ8dQ//PJaJbNw0URTPWqIghHWt1MmAANKhHZIYOHruW4Kw4ruUWOdGw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"acorn": "^8.8.0",
|
"acorn": "^8.8.0",
|
||||||
"acorn-jsx": "^5.3.2",
|
"acorn-jsx": "^5.3.2",
|
||||||
"eslint-visitor-keys": "^3.4.0"
|
"eslint-visitor-keys": "^3.4.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"esquery": {
|
"esquery": {
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@dannadori/voice-changer-client-js",
|
"name": "@dannadori/voice-changer-client-js",
|
||||||
"version": "1.0.122",
|
"version": "1.0.123",
|
||||||
"description": "",
|
"description": "",
|
||||||
"main": "dist/index.js",
|
"main": "dist/index.js",
|
||||||
"directories": {
|
"directories": {
|
||||||
@ -27,10 +27,10 @@
|
|||||||
"license": "ISC",
|
"license": "ISC",
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/audioworklet": "^0.0.45",
|
"@types/audioworklet": "^0.0.45",
|
||||||
"@types/node": "^18.16.3",
|
"@types/node": "^20.1.0",
|
||||||
"@types/react": "18.2.5",
|
"@types/react": "18.2.6",
|
||||||
"@types/react-dom": "18.2.3",
|
"@types/react-dom": "18.2.4",
|
||||||
"eslint": "^8.39.0",
|
"eslint": "^8.40.0",
|
||||||
"eslint-config-prettier": "^8.8.0",
|
"eslint-config-prettier": "^8.8.0",
|
||||||
"eslint-plugin-prettier": "^4.2.1",
|
"eslint-plugin-prettier": "^4.2.1",
|
||||||
"eslint-plugin-react": "^7.32.2",
|
"eslint-plugin-react": "^7.32.2",
|
||||||
@ -47,7 +47,7 @@
|
|||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@types/readable-stream": "^2.3.15",
|
"@types/readable-stream": "^2.3.15",
|
||||||
"amazon-chime-sdk-js": "^3.13.0",
|
"amazon-chime-sdk-js": "^3.14.0",
|
||||||
"buffer": "^6.0.3",
|
"buffer": "^6.0.3",
|
||||||
"localforage": "^1.10.0",
|
"localforage": "^1.10.0",
|
||||||
"react": "^18.2.0",
|
"react": "^18.2.0",
|
||||||
|
@ -27,6 +27,20 @@ export class ServerConfigurator {
|
|||||||
return info
|
return info
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getPerformance = async () => {
|
||||||
|
const url = this.serverUrl + "/performance"
|
||||||
|
const info = await new Promise<number[]>((resolve) => {
|
||||||
|
const request = new Request(url, {
|
||||||
|
method: 'GET',
|
||||||
|
});
|
||||||
|
fetch(request).then(async (response) => {
|
||||||
|
const json = await response.json() as number[]
|
||||||
|
resolve(json)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
return info
|
||||||
|
}
|
||||||
|
|
||||||
updateSettings = async (key: ServerSettingKey, val: string) => {
|
updateSettings = async (key: ServerSettingKey, val: string) => {
|
||||||
const url = this.serverUrl + "/update_settings"
|
const url = this.serverUrl + "/update_settings"
|
||||||
const info = await new Promise<ServerInfo>(async (resolve) => {
|
const info = await new Promise<ServerInfo>(async (resolve) => {
|
||||||
|
@ -331,6 +331,9 @@ export class VoiceChangerClient {
|
|||||||
getServerSettings = () => {
|
getServerSettings = () => {
|
||||||
return this.configurator.getSettings()
|
return this.configurator.getSettings()
|
||||||
}
|
}
|
||||||
|
getPerformance = () => {
|
||||||
|
return this.configurator.getPerformance()
|
||||||
|
}
|
||||||
|
|
||||||
getSocketId = () => {
|
getSocketId = () => {
|
||||||
return this.vcInNode.getSocketId()
|
return this.vcInNode.getSocketId()
|
||||||
|
@ -78,6 +78,7 @@ export class VoiceChangerWorkletNode extends AudioWorkletNode {
|
|||||||
console.log(`[SIO] ${this.socket?.id}`)
|
console.log(`[SIO] ${this.socket?.id}`)
|
||||||
});
|
});
|
||||||
this.socket.on('response', (response: any[]) => {
|
this.socket.on('response', (response: any[]) => {
|
||||||
|
console.log("response:", response)
|
||||||
const cur = Date.now()
|
const cur = Date.now()
|
||||||
const responseTime = cur - response[0]
|
const responseTime = cur - response[0]
|
||||||
const result = response[1] as ArrayBuffer
|
const result = response[1] as ArrayBuffer
|
||||||
|
@ -82,6 +82,16 @@ export const ServerSettingKey = {
|
|||||||
"f0Detector": "f0Detector",
|
"f0Detector": "f0Detector",
|
||||||
"recordIO": "recordIO",
|
"recordIO": "recordIO",
|
||||||
|
|
||||||
|
"enableServerAudio": "enableServerAudio",
|
||||||
|
"serverAudioStated": "serverAudioStated",
|
||||||
|
"serverInputAudioSampleRate": "serverInputAudioSampleRate",
|
||||||
|
"serverOutputAudioSampleRate": "serverOutputAudioSampleRate",
|
||||||
|
"serverInputAudioBufferSize": "serverInputAudioBufferSize",
|
||||||
|
"serverOutputAudioBufferSize": "serverOutputAudioBufferSize",
|
||||||
|
"serverInputDeviceId": "serverInputDeviceId",
|
||||||
|
"serverOutputDeviceId": "serverOutputDeviceId",
|
||||||
|
"serverReadChunkSize": "serverReadChunkSize",
|
||||||
|
|
||||||
"tran": "tran",
|
"tran": "tran",
|
||||||
"noiseScale": "noiseScale",
|
"noiseScale": "noiseScale",
|
||||||
"predictF0": "predictF0",
|
"predictF0": "predictF0",
|
||||||
@ -121,6 +131,17 @@ export type VoiceChangerServerSetting = {
|
|||||||
f0Detector: F0Detector // dio or harvest
|
f0Detector: F0Detector // dio or harvest
|
||||||
recordIO: number // 0:off, 1:on
|
recordIO: number // 0:off, 1:on
|
||||||
|
|
||||||
|
enableServerAudio: number // 0:off, 1:on
|
||||||
|
serverAudioStated: number // 0:off, 1:on
|
||||||
|
serverInputAudioSampleRate: number
|
||||||
|
serverOutputAudioSampleRate: number
|
||||||
|
serverInputAudioBufferSize: number
|
||||||
|
serverOutputAudioBufferSize: number
|
||||||
|
serverInputDeviceId: number
|
||||||
|
serverOutputDeviceId: number
|
||||||
|
serverReadChunkSize: number
|
||||||
|
|
||||||
|
|
||||||
tran: number // so-vits-svc
|
tran: number // so-vits-svc
|
||||||
noiseScale: number // so-vits-svc
|
noiseScale: number // so-vits-svc
|
||||||
predictF0: number // so-vits-svc
|
predictF0: number // so-vits-svc
|
||||||
@ -156,6 +177,13 @@ type ModelSlot = {
|
|||||||
deprecated: boolean
|
deprecated: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type ServerAudioDevice = {
|
||||||
|
kind: "audioinput" | "audiooutput",
|
||||||
|
index: number,
|
||||||
|
name: string
|
||||||
|
hostAPI: string
|
||||||
|
}
|
||||||
|
|
||||||
export type ServerInfo = VoiceChangerServerSetting & {
|
export type ServerInfo = VoiceChangerServerSetting & {
|
||||||
status: string
|
status: string
|
||||||
configFile: string,
|
configFile: string,
|
||||||
@ -163,6 +191,9 @@ export type ServerInfo = VoiceChangerServerSetting & {
|
|||||||
onnxModelFile: string,
|
onnxModelFile: string,
|
||||||
onnxExecutionProviders: OnnxExecutionProvider[]
|
onnxExecutionProviders: OnnxExecutionProvider[]
|
||||||
modelSlots: ModelSlot[]
|
modelSlots: ModelSlot[]
|
||||||
|
serverAudioInputDevices: ServerAudioDevice[]
|
||||||
|
serverAudioOutputDevices: ServerAudioDevice[]
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export type ServerInfoSoVitsSVC = ServerInfo & {
|
export type ServerInfoSoVitsSVC = ServerInfo & {
|
||||||
@ -179,6 +210,15 @@ export const DefaultServerSetting: ServerInfo = {
|
|||||||
|
|
||||||
recordIO: 0,
|
recordIO: 0,
|
||||||
|
|
||||||
|
enableServerAudio: 0,
|
||||||
|
serverAudioStated: 0,
|
||||||
|
serverInputAudioSampleRate: 48000,
|
||||||
|
serverOutputAudioSampleRate: 48000,
|
||||||
|
serverInputAudioBufferSize: 1024 * 24,
|
||||||
|
serverOutputAudioBufferSize: 1024 * 24,
|
||||||
|
serverInputDeviceId: -1,
|
||||||
|
serverOutputDeviceId: -1,
|
||||||
|
serverReadChunkSize: 256,
|
||||||
|
|
||||||
// VC Specific
|
// VC Specific
|
||||||
srcId: 0,
|
srcId: 0,
|
||||||
@ -214,7 +254,9 @@ export const DefaultServerSetting: ServerInfo = {
|
|||||||
pyTorchModelFile: "",
|
pyTorchModelFile: "",
|
||||||
onnxModelFile: "",
|
onnxModelFile: "",
|
||||||
onnxExecutionProviders: [],
|
onnxExecutionProviders: [],
|
||||||
modelSlots: []
|
modelSlots: [],
|
||||||
|
serverAudioInputDevices: [],
|
||||||
|
serverAudioOutputDevices: []
|
||||||
}
|
}
|
||||||
export const DefaultServerSetting_MMVCv15: ServerInfo = {
|
export const DefaultServerSetting_MMVCv15: ServerInfo = {
|
||||||
...DefaultServerSetting, dstId: 101,
|
...DefaultServerSetting, dstId: 101,
|
||||||
|
@ -25,7 +25,7 @@ export type ClientState = {
|
|||||||
bufferingTime: number;
|
bufferingTime: number;
|
||||||
volume: number;
|
volume: number;
|
||||||
performance: PerformanceData
|
performance: PerformanceData
|
||||||
|
updatePerformance: (() => Promise<void>) | null
|
||||||
// setClientType: (val: ClientType) => void
|
// setClientType: (val: ClientType) => void
|
||||||
|
|
||||||
// 情報取得
|
// 情報取得
|
||||||
@ -78,6 +78,31 @@ export const useClient = (props: UseClientProps): ClientState => {
|
|||||||
const [performance, setPerformance] = useState<PerformanceData>(InitialPerformanceData)
|
const [performance, setPerformance] = useState<PerformanceData>(InitialPerformanceData)
|
||||||
const [volume, setVolume] = useState<number>(0)
|
const [volume, setVolume] = useState<number>(0)
|
||||||
|
|
||||||
|
//// Server Audio Deviceを使うとき、モニタリングデータはpolling
|
||||||
|
const updatePerformance = useMemo(() => {
|
||||||
|
if (!voiceChangerClientRef.current) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
return async () => {
|
||||||
|
if (voiceChangerClientRef.current) {
|
||||||
|
const performance = await voiceChangerClientRef.current!.getPerformance()
|
||||||
|
const responseTime = performance[0]
|
||||||
|
const preprocessTime = performance[1]
|
||||||
|
const mainprocessTime = performance[2]
|
||||||
|
const postprocessTime = performance[3]
|
||||||
|
setPerformance({ responseTime, preprocessTime, mainprocessTime, postprocessTime })
|
||||||
|
} else {
|
||||||
|
const responseTime = 0
|
||||||
|
const preprocessTime = 0
|
||||||
|
const mainprocessTime = 0
|
||||||
|
const postprocessTime = 0
|
||||||
|
setPerformance({ responseTime, preprocessTime, mainprocessTime, postprocessTime })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, [voiceChangerClientRef.current])
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// (1-4) エラーステータス
|
// (1-4) エラーステータス
|
||||||
const errorCountRef = useRef<number>(0)
|
const errorCountRef = useRef<number>(0)
|
||||||
@ -168,6 +193,7 @@ export const useClient = (props: UseClientProps): ClientState => {
|
|||||||
bufferingTime,
|
bufferingTime,
|
||||||
volume,
|
volume,
|
||||||
performance,
|
performance,
|
||||||
|
updatePerformance,
|
||||||
|
|
||||||
// setClientType,
|
// setClientType,
|
||||||
|
|
||||||
|
@ -107,7 +107,11 @@ export const useServerSetting = (props: UseServerSettingProps): ServerSettingSta
|
|||||||
const cachedServerSetting = await getItem(INDEXEDDB_KEY_SERVER)
|
const cachedServerSetting = await getItem(INDEXEDDB_KEY_SERVER)
|
||||||
let initialSetting: ServerInfo
|
let initialSetting: ServerInfo
|
||||||
if (cachedServerSetting) {
|
if (cachedServerSetting) {
|
||||||
initialSetting = { ...defaultServerSetting, ...cachedServerSetting as ServerInfo, inputSampleRate: 48000 }// sample rateは時限措置
|
initialSetting = {
|
||||||
|
...defaultServerSetting, ...cachedServerSetting as ServerInfo,
|
||||||
|
serverAudioStated: 0,
|
||||||
|
inputSampleRate: 48000
|
||||||
|
}// sample rateは時限措置
|
||||||
} else {
|
} else {
|
||||||
initialSetting = { ...defaultServerSetting }
|
initialSetting = { ...defaultServerSetting }
|
||||||
}
|
}
|
||||||
|
@ -90,3 +90,8 @@ class EnumPitchExtractorTypes(Enum):
|
|||||||
class EnumFrameworkTypes(Enum):
|
class EnumFrameworkTypes(Enum):
|
||||||
pyTorch = "pyTorch"
|
pyTorch = "pyTorch"
|
||||||
onnx = "onnx"
|
onnx = "onnx"
|
||||||
|
|
||||||
|
|
||||||
|
class ServerAudioDeviceTypes(Enum):
|
||||||
|
audioinput = "audioinput"
|
||||||
|
audiooutput = "audiooutput"
|
||||||
|
@ -23,6 +23,7 @@ class MMVC_Rest_Fileuploader:
|
|||||||
self.voiceChangerManager = voiceChangerManager
|
self.voiceChangerManager = voiceChangerManager
|
||||||
self.router = APIRouter()
|
self.router = APIRouter()
|
||||||
self.router.add_api_route("/info", self.get_info, methods=["GET"])
|
self.router.add_api_route("/info", self.get_info, methods=["GET"])
|
||||||
|
self.router.add_api_route("/performance", self.get_performance, methods=["GET"])
|
||||||
self.router.add_api_route(
|
self.router.add_api_route(
|
||||||
"/upload_file", self.post_upload_file, methods=["POST"]
|
"/upload_file", self.post_upload_file, methods=["POST"]
|
||||||
)
|
)
|
||||||
@ -60,6 +61,11 @@ class MMVC_Rest_Fileuploader:
|
|||||||
json_compatible_item_data = jsonable_encoder(info)
|
json_compatible_item_data = jsonable_encoder(info)
|
||||||
return JSONResponse(content=json_compatible_item_data)
|
return JSONResponse(content=json_compatible_item_data)
|
||||||
|
|
||||||
|
def get_performance(self):
|
||||||
|
info = self.voiceChangerManager.get_performance()
|
||||||
|
json_compatible_item_data = jsonable_encoder(info)
|
||||||
|
return JSONResponse(content=json_compatible_item_data)
|
||||||
|
|
||||||
def post_update_settings(
|
def post_update_settings(
|
||||||
self, key: str = Form(...), val: Union[int, str, float] = Form(...)
|
self, key: str = Form(...), val: Union[int, str, float] = Form(...)
|
||||||
):
|
):
|
||||||
|
@ -6,6 +6,8 @@ from voice_changer.VoiceChangerManager import VoiceChangerManager
|
|||||||
|
|
||||||
|
|
||||||
class MMVC_Namespace(socketio.AsyncNamespace):
|
class MMVC_Namespace(socketio.AsyncNamespace):
|
||||||
|
sid: int = 0
|
||||||
|
|
||||||
def __init__(self, namespace: str, voiceChangerManager: VoiceChangerManager):
|
def __init__(self, namespace: str, voiceChangerManager: VoiceChangerManager):
|
||||||
super().__init__(namespace)
|
super().__init__(namespace)
|
||||||
self.voiceChangerManager = voiceChangerManager
|
self.voiceChangerManager = voiceChangerManager
|
||||||
@ -17,24 +19,32 @@ class MMVC_Namespace(socketio.AsyncNamespace):
|
|||||||
return cls._instance
|
return cls._instance
|
||||||
|
|
||||||
def on_connect(self, sid, environ):
|
def on_connect(self, sid, environ):
|
||||||
print('[{}] connet sid : {}'.format(datetime.now().strftime('%Y-%m-%d %H:%M:%S'), sid))
|
self.sid = sid
|
||||||
|
print(
|
||||||
|
"[{}] connet sid : {}".format(
|
||||||
|
datetime.now().strftime("%Y-%m-%d %H:%M:%S"), sid
|
||||||
|
)
|
||||||
|
)
|
||||||
pass
|
pass
|
||||||
|
|
||||||
async def on_request_message(self, sid, msg):
|
async def on_request_message(self, sid, msg):
|
||||||
|
self.sid = sid
|
||||||
timestamp = int(msg[0])
|
timestamp = int(msg[0])
|
||||||
data = msg[1]
|
data = msg[1]
|
||||||
if (isinstance(data, str)):
|
if isinstance(data, str):
|
||||||
print(type(data))
|
print(type(data))
|
||||||
print(data)
|
print(data)
|
||||||
await self.emit('response', [timestamp, 0], to=sid)
|
await self.emit("response", [timestamp, 0], to=sid)
|
||||||
else:
|
else:
|
||||||
unpackedData = np.array(struct.unpack('<%sh' % (len(data) // struct.calcsize('<h')), data)).astype(np.int16)
|
unpackedData = np.array(
|
||||||
|
struct.unpack("<%sh" % (len(data) // struct.calcsize("<h")), data)
|
||||||
|
).astype(np.int16)
|
||||||
|
|
||||||
res = self.voiceChangerManager.changeVoice(unpackedData)
|
res = self.voiceChangerManager.changeVoice(unpackedData)
|
||||||
audio1 = res[0]
|
audio1 = res[0]
|
||||||
perf = res[1] if len(res) == 2 else [0, 0, 0]
|
perf = res[1] if len(res) == 2 else [0, 0, 0]
|
||||||
bin = struct.pack('<%sh' % len(audio1), *audio1)
|
bin = struct.pack("<%sh" % len(audio1), *audio1)
|
||||||
await self.emit('response', [timestamp, bin, perf], to=sid)
|
await self.emit("response", [timestamp, bin, perf], to=sid)
|
||||||
|
|
||||||
def on_disconnect(self, sid):
|
def on_disconnect(self, sid):
|
||||||
# print('[{}] disconnect'.format(datetime.now().strftime('%Y-%m-%d %H:%M:%S')))
|
# print('[{}] disconnect'.format(datetime.now().strftime('%Y-%m-%d %H:%M:%S')))
|
||||||
|
BIN
server/test.wav
Normal file
BIN
server/test.wav
Normal file
Binary file not shown.
58
server/voice_changer/Local/AudioDeviceList.py
Normal file
58
server/voice_changer/Local/AudioDeviceList.py
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
import pyaudio
|
||||||
|
|
||||||
|
# import json
|
||||||
|
|
||||||
|
|
||||||
|
from dataclasses import dataclass
|
||||||
|
|
||||||
|
from const import ServerAudioDeviceTypes
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class ServerAudioDevice:
|
||||||
|
kind: ServerAudioDeviceTypes = ServerAudioDeviceTypes.audioinput
|
||||||
|
index: int = 0
|
||||||
|
name: str = ""
|
||||||
|
hostAPI: str = ""
|
||||||
|
|
||||||
|
|
||||||
|
def list_audio_device():
|
||||||
|
audio = pyaudio.PyAudio()
|
||||||
|
audio_input_devices: list[ServerAudioDevice] = []
|
||||||
|
audio_output_devices: list[ServerAudioDevice] = []
|
||||||
|
# audio_devices = {}
|
||||||
|
host_apis = []
|
||||||
|
|
||||||
|
for api_index in range(audio.get_host_api_count()):
|
||||||
|
host_apis.append(audio.get_host_api_info_by_index(api_index)["name"])
|
||||||
|
|
||||||
|
for x in range(0, audio.get_device_count()):
|
||||||
|
device = audio.get_device_info_by_index(x)
|
||||||
|
try:
|
||||||
|
deviceName = device["name"].encode("shift-jis").decode("utf-8")
|
||||||
|
except (UnicodeDecodeError, UnicodeEncodeError):
|
||||||
|
deviceName = device["name"]
|
||||||
|
|
||||||
|
deviceIndex = device["index"]
|
||||||
|
hostAPI = host_apis[device["hostApi"]]
|
||||||
|
|
||||||
|
if device["maxInputChannels"] > 0:
|
||||||
|
audio_input_devices.append(
|
||||||
|
ServerAudioDevice(
|
||||||
|
kind=ServerAudioDeviceTypes.audioinput,
|
||||||
|
index=deviceIndex,
|
||||||
|
name=deviceName,
|
||||||
|
hostAPI=hostAPI,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
if device["maxOutputChannels"] > 0:
|
||||||
|
audio_output_devices.append(
|
||||||
|
ServerAudioDevice(
|
||||||
|
kind=ServerAudioDeviceTypes.audiooutput,
|
||||||
|
index=deviceIndex,
|
||||||
|
name=deviceName,
|
||||||
|
hostAPI=hostAPI,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
return audio_input_devices, audio_output_devices
|
@ -1,4 +1,6 @@
|
|||||||
from typing import Any, Union, cast
|
from typing import Any, Union, cast
|
||||||
|
|
||||||
|
import socketio
|
||||||
from const import TMP_DIR, ModelType
|
from const import TMP_DIR, ModelType
|
||||||
import torch
|
import torch
|
||||||
import os
|
import os
|
||||||
@ -9,6 +11,7 @@ import resampy
|
|||||||
|
|
||||||
|
|
||||||
from voice_changer.IORecorder import IORecorder
|
from voice_changer.IORecorder import IORecorder
|
||||||
|
from voice_changer.Local.AudioDeviceList import ServerAudioDevice, list_audio_device
|
||||||
from voice_changer.utils.LoadModelParams import LoadModelParams
|
from voice_changer.utils.LoadModelParams import LoadModelParams
|
||||||
|
|
||||||
from voice_changer.utils.Timer import Timer
|
from voice_changer.utils.Timer import Timer
|
||||||
@ -21,6 +24,10 @@ from Exceptions import (
|
|||||||
ONNXInputArgumentException,
|
ONNXInputArgumentException,
|
||||||
)
|
)
|
||||||
from voice_changer.utils.VoiceChangerParams import VoiceChangerParams
|
from voice_changer.utils.VoiceChangerParams import VoiceChangerParams
|
||||||
|
import pyaudio
|
||||||
|
import threading
|
||||||
|
import struct
|
||||||
|
import time
|
||||||
|
|
||||||
providers = [
|
providers = [
|
||||||
"OpenVINOExecutionProvider",
|
"OpenVINOExecutionProvider",
|
||||||
@ -42,10 +49,38 @@ class VoiceChangerSettings:
|
|||||||
crossFadeOverlapSize: int = 4096
|
crossFadeOverlapSize: int = 4096
|
||||||
|
|
||||||
recordIO: int = 0 # 0:off, 1:on
|
recordIO: int = 0 # 0:off, 1:on
|
||||||
|
serverAudioInputDevices: list[ServerAudioDevice] = field(default_factory=lambda: [])
|
||||||
|
serverAudioOutputDevices: list[ServerAudioDevice] = field(
|
||||||
|
default_factory=lambda: []
|
||||||
|
)
|
||||||
|
|
||||||
|
enableServerAudio: int = 0 # 0:off, 1:on
|
||||||
|
serverAudioStated: int = 0 # 0:off, 1:on
|
||||||
|
serverInputAudioSampleRate: int = 48000
|
||||||
|
serverOutputAudioSampleRate: int = 48000
|
||||||
|
serverInputAudioBufferSize: int = 1024 * 24
|
||||||
|
serverOutputAudioBufferSize: int = 1024 * 24
|
||||||
|
serverInputDeviceId: int = -1
|
||||||
|
serverOutputDeviceId: int = -1
|
||||||
|
serverReadChunkSize: int = 256
|
||||||
|
performance: list[int] = field(default_factory=lambda: [0, 0, 0, 0])
|
||||||
|
|
||||||
# ↓mutableな物だけ列挙
|
# ↓mutableな物だけ列挙
|
||||||
intData: list[str] = field(
|
intData: list[str] = field(
|
||||||
default_factory=lambda: ["inputSampleRate", "crossFadeOverlapSize", "recordIO"]
|
default_factory=lambda: [
|
||||||
|
"inputSampleRate",
|
||||||
|
"crossFadeOverlapSize",
|
||||||
|
"recordIO",
|
||||||
|
"enableServerAudio",
|
||||||
|
"serverAudioStated",
|
||||||
|
"serverInputAudioSampleRate",
|
||||||
|
"serverOutputAudioSampleRate",
|
||||||
|
"serverInputAudioBufferSize",
|
||||||
|
"serverOutputAudioBufferSize",
|
||||||
|
"serverInputDeviceId",
|
||||||
|
"serverOutputDeviceId",
|
||||||
|
"serverReadChunkSize",
|
||||||
|
]
|
||||||
)
|
)
|
||||||
floatData: list[str] = field(
|
floatData: list[str] = field(
|
||||||
default_factory=lambda: ["crossFadeOffsetRate", "crossFadeEndRate"]
|
default_factory=lambda: ["crossFadeOffsetRate", "crossFadeEndRate"]
|
||||||
@ -53,11 +88,105 @@ class VoiceChangerSettings:
|
|||||||
strData: list[str] = field(default_factory=lambda: [])
|
strData: list[str] = field(default_factory=lambda: [])
|
||||||
|
|
||||||
|
|
||||||
|
def serverLocal(_vc):
|
||||||
|
vc: VoiceChanger = _vc
|
||||||
|
audio = pyaudio.PyAudio()
|
||||||
|
|
||||||
|
def createAudioInput(deviceId: int, sampleRate: int, bufferSize: int):
|
||||||
|
audio_input_stream = audio.open(
|
||||||
|
format=pyaudio.paInt16,
|
||||||
|
channels=1,
|
||||||
|
rate=sampleRate,
|
||||||
|
# frames_per_buffer=32768,
|
||||||
|
frames_per_buffer=bufferSize,
|
||||||
|
input_device_index=deviceId,
|
||||||
|
input=True,
|
||||||
|
)
|
||||||
|
return audio_input_stream
|
||||||
|
|
||||||
|
def createAudioOutput(deviceId: int, sampleRate: int, bufferSize: int):
|
||||||
|
audio_output_stream = audio.open(
|
||||||
|
format=pyaudio.paInt16,
|
||||||
|
channels=1,
|
||||||
|
rate=sampleRate,
|
||||||
|
# frames_per_buffer=32768,
|
||||||
|
frames_per_buffer=bufferSize,
|
||||||
|
output_device_index=deviceId,
|
||||||
|
output=True,
|
||||||
|
)
|
||||||
|
return audio_output_stream
|
||||||
|
|
||||||
|
currentInputDeviceId = -1
|
||||||
|
currentInputSampleRate = -1
|
||||||
|
currentInputBufferSize = -1
|
||||||
|
currentOutputDeviceId = -1
|
||||||
|
currentOutputSampleRate = -1
|
||||||
|
currentOutputBufferSize = -1
|
||||||
|
|
||||||
|
audio_input_stream = None
|
||||||
|
audio_output_stream = None
|
||||||
|
while True:
|
||||||
|
if (
|
||||||
|
vc.settings.enableServerAudio == 0
|
||||||
|
or vc.settings.serverAudioStated == 0
|
||||||
|
or vc.settings.serverInputDeviceId == -1
|
||||||
|
or vc.settings.serverOutputDeviceId == -1
|
||||||
|
):
|
||||||
|
time.sleep(2)
|
||||||
|
else:
|
||||||
|
if (
|
||||||
|
currentInputDeviceId != vc.settings.serverInputDeviceId
|
||||||
|
or currentInputSampleRate != vc.settings.serverInputAudioSampleRate
|
||||||
|
or currentInputBufferSize != vc.settings.serverInputAudioBufferSize
|
||||||
|
):
|
||||||
|
currentInputDeviceId = vc.settings.serverInputDeviceId
|
||||||
|
currentInputSampleRate = vc.settings.serverInputAudioSampleRate
|
||||||
|
currentInputBufferSize = vc.settings.serverInputAudioBufferSize
|
||||||
|
if audio_input_stream is not None:
|
||||||
|
audio_input_stream.close()
|
||||||
|
audio_input_stream = createAudioInput(
|
||||||
|
currentInputDeviceId,
|
||||||
|
currentInputSampleRate,
|
||||||
|
currentInputBufferSize,
|
||||||
|
)
|
||||||
|
|
||||||
|
if (
|
||||||
|
currentOutputDeviceId != vc.settings.serverOutputDeviceId
|
||||||
|
or currentOutputSampleRate != vc.settings.serverOutputAudioSampleRate
|
||||||
|
or currentOutputBufferSize != vc.settings.serverOutputAudioBufferSize
|
||||||
|
):
|
||||||
|
currentOutputDeviceId = vc.settings.serverOutputDeviceId
|
||||||
|
currentOutputSampleRate = vc.settings.serverOutputAudioSampleRate
|
||||||
|
currentOutputBufferSize = vc.settings.serverOutputAudioBufferSize
|
||||||
|
if audio_output_stream is not None:
|
||||||
|
audio_output_stream.close()
|
||||||
|
audio_output_stream = createAudioOutput(
|
||||||
|
currentOutputDeviceId,
|
||||||
|
currentOutputSampleRate,
|
||||||
|
currentOutputBufferSize,
|
||||||
|
)
|
||||||
|
|
||||||
|
in_wav = audio_input_stream.read(
|
||||||
|
vc.settings.serverReadChunkSize * 128, exception_on_overflow=False
|
||||||
|
)
|
||||||
|
unpackedData = np.array(
|
||||||
|
struct.unpack("<%sh" % (len(in_wav) // struct.calcsize("<h")), in_wav)
|
||||||
|
).astype(np.int16)
|
||||||
|
with Timer("all_inference_time") as t:
|
||||||
|
out_wav, times = vc.on_request(unpackedData)
|
||||||
|
all_inference_time = t.secs
|
||||||
|
performance = [all_inference_time] + times
|
||||||
|
performance = [round(x, 2) * 1000 for x in performance]
|
||||||
|
vc.settings.performance = performance
|
||||||
|
audio_output_stream.write(out_wav.tobytes())
|
||||||
|
|
||||||
|
|
||||||
class VoiceChanger:
|
class VoiceChanger:
|
||||||
settings: VoiceChangerSettings
|
settings: VoiceChangerSettings
|
||||||
voiceChanger: VoiceChangerModel
|
voiceChanger: VoiceChangerModel
|
||||||
ioRecorder: IORecorder
|
ioRecorder: IORecorder
|
||||||
sola_buffer: AudioInOut
|
sola_buffer: AudioInOut
|
||||||
|
namespace: socketio.AsyncNamespace | None = None
|
||||||
|
|
||||||
def __init__(self, params: VoiceChangerParams):
|
def __init__(self, params: VoiceChangerParams):
|
||||||
# 初期化
|
# 初期化
|
||||||
@ -78,6 +207,12 @@ class VoiceChanger:
|
|||||||
and torch.backends.mps.is_available()
|
and torch.backends.mps.is_available()
|
||||||
)
|
)
|
||||||
|
|
||||||
|
audioinput, audiooutput = list_audio_device()
|
||||||
|
self.settings.serverAudioInputDevices = audioinput
|
||||||
|
self.settings.serverAudioOutputDevices = audiooutput
|
||||||
|
|
||||||
|
thread = threading.Thread(target=serverLocal, args=(self,))
|
||||||
|
thread.start()
|
||||||
print(
|
print(
|
||||||
f"VoiceChanger Initialized (GPU_NUM:{self.gpu_num}, mps_enabled:{self.mps_enabled})"
|
f"VoiceChanger Initialized (GPU_NUM:{self.gpu_num}, mps_enabled:{self.mps_enabled})"
|
||||||
)
|
)
|
||||||
@ -140,6 +275,9 @@ class VoiceChanger:
|
|||||||
data.update(self.voiceChanger.get_info())
|
data.update(self.voiceChanger.get_info())
|
||||||
return data
|
return data
|
||||||
|
|
||||||
|
def get_performance(self):
|
||||||
|
return self.settings.performance
|
||||||
|
|
||||||
def update_settings(self, key: str, val: Any):
|
def update_settings(self, key: str, val: Any):
|
||||||
if key in self.settings.intData:
|
if key in self.settings.intData:
|
||||||
setattr(self.settings, key, int(val))
|
setattr(self.settings, key, int(val))
|
||||||
|
@ -33,6 +33,13 @@ class VoiceChangerManager(object):
|
|||||||
else:
|
else:
|
||||||
return {"status": "ERROR", "msg": "no model loaded"}
|
return {"status": "ERROR", "msg": "no model loaded"}
|
||||||
|
|
||||||
|
def get_performance(self):
|
||||||
|
if hasattr(self, "voiceChanger"):
|
||||||
|
info = self.voiceChanger.get_performance()
|
||||||
|
return info
|
||||||
|
else:
|
||||||
|
return {"status": "ERROR", "msg": "no model loaded"}
|
||||||
|
|
||||||
def update_settings(self, key: str, val: str | int | float):
|
def update_settings(self, key: str, val: str | int | float):
|
||||||
if hasattr(self, "voiceChanger"):
|
if hasattr(self, "voiceChanger"):
|
||||||
info = self.voiceChanger.update_settings(key, val)
|
info = self.voiceChanger.update_settings(key, val)
|
||||||
|
Loading…
Reference in New Issue
Block a user