voice-changer/client/lib/src/hooks/useClientSetting.ts

253 lines
9.5 KiB
TypeScript
Raw Normal View History

2023-01-12 10:38:45 +03:00
import { useState, useMemo, useRef, useEffect } from "react"
2023-02-12 06:25:57 +03:00
import { VoiceChangerClientSetting, Protocol, BufferSize, VoiceChangerMode, SampleRate, Speaker, DefaultVoiceChangerClientSetting, INDEXEDDB_KEY_CLIENT, Correspondence } from "../const"
2023-01-12 17:01:45 +03:00
import { createDummyMediaStream } from "../util"
import { VoiceChangerClient } from "../VoiceChangerClient"
2023-01-29 03:42:45 +03:00
import { useIndexedDB } from "./useIndexedDB"
2023-01-12 10:38:45 +03:00
export type UseClientSettingProps = {
voiceChangerClient: VoiceChangerClient | null
audioContext: AudioContext | null
}
export type ClientSettingState = {
setting: VoiceChangerClientSetting;
2023-01-29 03:42:45 +03:00
clearSetting: () => Promise<void>
2023-01-12 10:38:45 +03:00
setServerUrl: (url: string) => void;
setProtocol: (proto: Protocol) => void;
setAudioInput: (audioInput: string | MediaStream | null) => Promise<void>
setBufferSize: (bufferSize: BufferSize) => Promise<void>
setVfForceDisabled: (vfForceDisabled: boolean) => Promise<void>
setInputChunkNum: (num: number) => void;
setVoiceChangerMode: (mode: VoiceChangerMode) => void
setSampleRate: (num: SampleRate) => void
setSpeakers: (speakers: Speaker[]) => void
2023-02-12 06:25:57 +03:00
setCorrespondences: (file: File | null) => Promise<void>
2023-01-12 10:38:45 +03:00
start: () => Promise<void>
stop: () => Promise<void>
reloadClientSetting: () => Promise<void>
}
export const useClientSetting = (props: UseClientSettingProps): ClientSettingState => {
const settingRef = useRef<VoiceChangerClientSetting>(DefaultVoiceChangerClientSetting)
const [setting, _setSetting] = useState<VoiceChangerClientSetting>(settingRef.current)
2023-01-29 03:42:45 +03:00
const { setItem, getItem, removeItem } = useIndexedDB()
// 初期化 その1 DBから取得
useEffect(() => {
const loadCache = async () => {
const setting = await getItem(INDEXEDDB_KEY_CLIENT)
if (!setting) {
// デフォルト設定
console.log("No Chache",)
const params = new URLSearchParams(location.search);
const colab = params.get("colab")
if (colab == "true") {
settingRef.current.protocol = "rest"
settingRef.current.inputChunkNum = 64
} else {
settingRef.current.protocol = "sio"
settingRef.current.inputChunkNum = 32
}
} else {
settingRef.current = setting as VoiceChangerClientSetting
}
_setSetting({ ...settingRef.current })
}
loadCache()
}, [])
// 初期化 その2 クライアントに設定
useEffect(() => {
if (!props.voiceChangerClient) return
props.voiceChangerClient.setServerUrl(settingRef.current.mmvcServerUrl)
props.voiceChangerClient.setInputChunkNum(settingRef.current.inputChunkNum)
props.voiceChangerClient.setProtocol(settingRef.current.protocol)
props.voiceChangerClient.setVoiceChangerMode(settingRef.current.voiceChangerMode)
// Input, bufferSize, VoiceFocus Disableは_setInputで設定
_setInput()
}, [props.voiceChangerClient])
const setSetting = async (setting: VoiceChangerClientSetting) => {
const storeData = { ...setting }
if (typeof storeData.audioInput != "string") {
storeData.audioInput = null
}
setItem(INDEXEDDB_KEY_CLIENT, storeData)
_setSetting(setting)
}
const clearSetting = async () => {
await removeItem(INDEXEDDB_KEY_CLIENT)
}
2023-01-12 10:38:45 +03:00
//////////////
// 設定
/////////////
const setServerUrl = useMemo(() => {
return (url: string) => {
if (!props.voiceChangerClient) return
2023-01-12 10:47:09 +03:00
props.voiceChangerClient.setServerUrl(url, true)
2023-01-12 10:38:45 +03:00
settingRef.current.mmvcServerUrl = url
2023-01-29 03:42:45 +03:00
setSetting({ ...settingRef.current })
2023-01-12 10:38:45 +03:00
}
}, [props.voiceChangerClient])
const setProtocol = useMemo(() => {
return (proto: Protocol) => {
if (!props.voiceChangerClient) return
props.voiceChangerClient.setProtocol(proto)
settingRef.current.protocol = proto
2023-01-29 03:42:45 +03:00
setSetting({ ...settingRef.current })
2023-01-12 10:38:45 +03:00
}
}, [props.voiceChangerClient])
const _setInput = async () => {
if (!props.voiceChangerClient) return
2023-01-29 03:42:45 +03:00
// console.log("[useClient] setup!(0)", settingRef.current.audioInput)
2023-01-12 10:38:45 +03:00
if (!settingRef.current.audioInput || settingRef.current.audioInput == "none") {
2023-01-29 03:42:45 +03:00
// console.log("[useClient] setup!(1)", settingRef.current.audioInput)
2023-01-12 10:38:45 +03:00
const ms = createDummyMediaStream(props.audioContext!)
await props.voiceChangerClient.setup(ms, settingRef.current.bufferSize, settingRef.current.forceVfDisable)
} else {
2023-01-29 03:42:45 +03:00
// console.log("[useClient] setup!(2)", settingRef.current.audioInput)
2023-01-12 10:38:45 +03:00
await props.voiceChangerClient.setup(settingRef.current.audioInput, settingRef.current.bufferSize, settingRef.current.forceVfDisable)
}
}
const setAudioInput = useMemo(() => {
return async (audioInput: string | MediaStream | null) => {
if (!props.voiceChangerClient) return
settingRef.current.audioInput = audioInput
await _setInput()
2023-01-29 03:42:45 +03:00
setSetting({ ...settingRef.current })
2023-01-12 10:38:45 +03:00
}
}, [props.voiceChangerClient])
const setBufferSize = useMemo(() => {
return async (bufferSize: BufferSize) => {
if (!props.voiceChangerClient) return
settingRef.current.bufferSize = bufferSize
await _setInput()
2023-01-29 03:42:45 +03:00
setSetting({ ...settingRef.current })
2023-01-12 10:38:45 +03:00
}
}, [props.voiceChangerClient])
const setVfForceDisabled = useMemo(() => {
return async (vfForceDisabled: boolean) => {
if (!props.voiceChangerClient) return
settingRef.current.forceVfDisable = vfForceDisabled
await _setInput()
2023-01-29 03:42:45 +03:00
setSetting({ ...settingRef.current })
2023-01-12 10:38:45 +03:00
}
}, [props.voiceChangerClient])
const setInputChunkNum = useMemo(() => {
return (num: number) => {
if (!props.voiceChangerClient) return
props.voiceChangerClient.setInputChunkNum(num)
settingRef.current.inputChunkNum = num
2023-01-29 03:42:45 +03:00
setSetting({ ...settingRef.current })
2023-01-12 10:38:45 +03:00
}
}, [props.voiceChangerClient])
const setVoiceChangerMode = useMemo(() => {
return (mode: VoiceChangerMode) => {
if (!props.voiceChangerClient) return
props.voiceChangerClient.setVoiceChangerMode(mode)
settingRef.current.voiceChangerMode = mode
2023-01-29 03:42:45 +03:00
setSetting({ ...settingRef.current })
2023-01-12 10:38:45 +03:00
}
}, [props.voiceChangerClient])
const setSampleRate = useMemo(() => {
return (num: SampleRate) => {
if (!props.voiceChangerClient) return
//props.voiceChangerClient.setSampleRate(num) // Not Implemented
settingRef.current.sampleRate = num
2023-01-29 03:42:45 +03:00
setSetting({ ...settingRef.current })
2023-01-12 10:38:45 +03:00
}
}, [props.voiceChangerClient])
const setSpeakers = useMemo(() => {
return (speakers: Speaker[]) => {
if (!props.voiceChangerClient) return
settingRef.current.speakers = speakers
2023-01-29 03:42:45 +03:00
setSetting({ ...settingRef.current })
2023-01-12 10:38:45 +03:00
}
}, [props.voiceChangerClient])
2023-02-12 06:25:57 +03:00
const setCorrespondences = useMemo(() => {
return async (file: File | null) => {
if (!props.voiceChangerClient) return
if (!file) {
settingRef.current.correspondences = []
} else {
const correspondenceText = await file.text()
const cors = correspondenceText.split("\n").map(line => {
const items = line.split("|")
if (items.length != 3) {
console.warn("Invalid Correspondence Line:", line)
return null
} else {
const cor: Correspondence = {
sid: Number(items[0]),
correspondence: Number(items[1]),
dirname: items[2]
}
return cor
}
}).filter(x => { return x != null }) as Correspondence[]
settingRef.current.correspondences = cors
}
setSetting({ ...settingRef.current })
}
}, [props.voiceChangerClient])
2023-01-12 10:38:45 +03:00
//////////////
// 操作
/////////////
// (1) start
const start = useMemo(() => {
return async () => {
if (!props.voiceChangerClient) return
props.voiceChangerClient.setServerUrl(setting.mmvcServerUrl, true)
props.voiceChangerClient.start()
}
}, [setting.mmvcServerUrl, props.voiceChangerClient])
// (2) stop
const stop = useMemo(() => {
return async () => {
if (!props.voiceChangerClient) return
props.voiceChangerClient.stop()
}
}, [props.voiceChangerClient])
const reloadClientSetting = useMemo(() => {
return async () => {
if (!props.voiceChangerClient) return
await props.voiceChangerClient.getClientSettings()
}
}, [props.voiceChangerClient])
return {
setting,
2023-01-29 03:42:45 +03:00
clearSetting,
2023-01-12 10:38:45 +03:00
setServerUrl,
setProtocol,
setAudioInput,
setBufferSize,
setVfForceDisabled,
setInputChunkNum,
setVoiceChangerMode,
setSampleRate,
setSpeakers,
2023-02-12 06:25:57 +03:00
setCorrespondences,
2023-01-12 10:38:45 +03:00
start,
stop,
reloadClientSetting
}
}