worklet setting

This commit is contained in:
wataru 2023-01-12 04:52:01 +09:00
parent ccd5111fd2
commit 43fd0316ff
7 changed files with 121 additions and 12 deletions

File diff suppressed because one or more lines are too long

View File

@ -53,6 +53,53 @@ export const useAdvancedSetting = (props: UseAdvancedSettingProps): AdvancedSett
) )
}, [props.clientState.settingState]) }, [props.clientState.settingState])
const workletSettingRow = useMemo(() => {
return (
<>
<div className="body-row split-3-7 left-padding-1 guided">
<div className="body-item-title left-padding-1">Trancate Num</div>
<div className="body-input-container">
<input type="number" min={50} max={300} step={1} value={props.clientState.workletSetting.setting.numTrancateTreshold} onChange={(e) => {
props.clientState.workletSetting.setSetting({
...props.clientState.workletSetting.setting,
numTrancateTreshold: Number(e.target.value)
})
}} />
</div>
</div>
<div className="body-row split-3-7 left-padding-1 guided">
<div className="body-item-title left-padding-1">Trancate Vol</div>
<div className="body-input-container">
<input type="number" min={0.0001} max={0.0009} step={0.0001} value={props.clientState.workletSetting.setting.volTrancateThreshold} onChange={(e) => {
props.clientState.workletSetting.setSetting({
...props.clientState.workletSetting.setting,
volTrancateThreshold: Number(e.target.value)
})
}} />
</div>
</div>
<div className="body-row split-3-7 left-padding-1 guided">
<div className="body-item-title left-padding-1">Trancate Vol Length</div>
<div className="body-input-container">
<input type="number" min={16} max={128} step={1} value={props.clientState.workletSetting.setting.volTrancateLength} onChange={(e) => {
props.clientState.workletSetting.setSetting({
...props.clientState.workletSetting.setting,
volTrancateLength: Number(e.target.value)
})
}} />
</div>
</div>
</>
)
}, [props.clientState.workletSetting.setting, props.clientState.workletSetting.setSetting])
const advancedSetting = useMemo(() => { const advancedSetting = useMemo(() => {
return ( return (
<> <>
@ -63,9 +110,10 @@ export const useAdvancedSetting = (props: UseAdvancedSettingProps): AdvancedSett
</div> </div>
{vfForceDisableRow} {vfForceDisableRow}
{voiceChangeModeRow} {voiceChangeModeRow}
{workletSettingRow}
</> </>
) )
}, [vfForceDisableRow, voiceChangeModeRow]) }, [vfForceDisableRow, voiceChangeModeRow, workletSettingRow])
return { return {
advancedSetting, advancedSetting,

View File

@ -1,5 +1,6 @@
import { ServerInfo, BufferSize, createDummyMediaStream, DefaultVoiceChangerOptions, DefaultVoiceChangerRequestParamas, Framework, OnnxExecutionProvider, Protocol, SampleRate, ServerSettingKey, Speaker, VoiceChangerMode, VoiceChnagerClient } from "@dannadori/voice-changer-client-js" import { ServerInfo, BufferSize, createDummyMediaStream, DefaultVoiceChangerOptions, DefaultVoiceChangerRequestParamas, Framework, OnnxExecutionProvider, Protocol, SampleRate, ServerSettingKey, Speaker, VoiceChangerMode, VoiceChangerClient } from "@dannadori/voice-changer-client-js"
import { useEffect, useMemo, useRef, useState } from "react" import { useEffect, useMemo, useRef, useState } from "react"
import { useWorkletSetting, WorkletSettingState } from "./useWorkletSetting"
export type UseClientProps = { export type UseClientProps = {
audioContext: AudioContext | null audioContext: AudioContext | null
@ -89,6 +90,9 @@ export type ClientState = {
start: () => Promise<void>; start: () => Promise<void>;
stop: () => Promise<void>; stop: () => Promise<void>;
getInfo: () => Promise<void> getInfo: () => Promise<void>
workletSetting: WorkletSettingState
} }
@ -96,7 +100,9 @@ export type ClientState = {
export const useClient = (props: UseClientProps): ClientState => { export const useClient = (props: UseClientProps): ClientState => {
// (1) クライアント初期化 // (1) クライアント初期化
const voiceChangerClientRef = useRef<VoiceChnagerClient | null>(null) const voiceChangerClientRef = useRef<VoiceChangerClient | null>(null)
const [voiceChangerClient, setVoiceChangerClient] = useState<VoiceChangerClient | null>(voiceChangerClientRef.current)
const workletSetting = useWorkletSetting({ voiceChangerClient })
const [clientInitialized, setClientInitialized] = useState<boolean>(false) const [clientInitialized, setClientInitialized] = useState<boolean>(false)
const initializedResolveRef = useRef<(value: void | PromiseLike<void>) => void>() const initializedResolveRef = useRef<(value: void | PromiseLike<void>) => void>()
const initializedPromise = useMemo(() => { const initializedPromise = useMemo(() => {
@ -123,7 +129,7 @@ export const useClient = (props: UseClientProps): ClientState => {
if (!props.audioContext) { if (!props.audioContext) {
return return
} }
const voiceChangerClient = new VoiceChnagerClient(props.audioContext, true, { const voiceChangerClient = new VoiceChangerClient(props.audioContext, true, {
notifySendBufferingTime: (val: number) => { notifySendBufferingTime: (val: number) => {
setBufferingTime(val) setBufferingTime(val)
}, },
@ -143,6 +149,7 @@ export const useClient = (props: UseClientProps): ClientState => {
await voiceChangerClient.isInitialized() await voiceChangerClient.isInitialized()
voiceChangerClientRef.current = voiceChangerClient voiceChangerClientRef.current = voiceChangerClient
setVoiceChangerClient(voiceChangerClientRef.current)
console.log("[useClient] client initialized") console.log("[useClient] client initialized")
setClientInitialized(true) setClientInitialized(true)
@ -414,6 +421,7 @@ export const useClient = (props: UseClientProps): ClientState => {
}, []) }, [])
return { return {
clientInitialized, clientInitialized,
bufferingTime, bufferingTime,
@ -429,5 +437,7 @@ export const useClient = (props: UseClientProps): ClientState => {
start, start,
stop, stop,
getInfo, getInfo,
workletSetting
} }
} }

View File

@ -0,0 +1,29 @@
import { DefaultWorkletSetting, VoiceChangerClient, WorkletSetting } from "@dannadori/voice-changer-client-js"
import { useState, useMemo } from "react"
export type UseWorkletSettingProps = {
voiceChangerClient: VoiceChangerClient | null
}
export type WorkletSettingState = {
setting: WorkletSetting;
setSetting: (setting: WorkletSetting) => void;
}
export const useWorkletSetting = (props: UseWorkletSettingProps): WorkletSettingState => {
const [setting, _setSetting] = useState<WorkletSetting>(DefaultWorkletSetting)
const setSetting = useMemo(() => {
return (setting: WorkletSetting) => {
if (!props.voiceChangerClient) return
props.voiceChangerClient.configureWorklet(setting)
_setSetting(setting)
}
}, [props.voiceChangerClient])
return {
setting,
setSetting
}
}

View File

@ -3,7 +3,7 @@ import { VoiceChangerWorkletNode, VolumeListener } from "./VoiceChangerWorkletNo
import workerjs from "raw-loader!../worklet/dist/index.js"; import workerjs from "raw-loader!../worklet/dist/index.js";
import { VoiceFocusDeviceTransformer, VoiceFocusTransformDevice } from "amazon-chime-sdk-js"; import { VoiceFocusDeviceTransformer, VoiceFocusTransformDevice } from "amazon-chime-sdk-js";
import { createDummyMediaStream, validateUrl } from "./util"; import { createDummyMediaStream, validateUrl } from "./util";
import { BufferSize, DefaultVoiceChangerOptions, Protocol, ServerSettingKey, VoiceChangerMode, VOICE_CHANGER_CLIENT_EXCEPTION } from "./const"; import { BufferSize, DefaultVoiceChangerOptions, Protocol, ServerSettingKey, VoiceChangerMode, VOICE_CHANGER_CLIENT_EXCEPTION, WorkletSetting } from "./const";
import MicrophoneStream from "microphone-stream"; import MicrophoneStream from "microphone-stream";
import { AudioStreamer, Callbacks, AudioStreamerListeners } from "./AudioStreamer"; import { AudioStreamer, Callbacks, AudioStreamerListeners } from "./AudioStreamer";
import { ServerConfigurator } from "./ServerConfigurator"; import { ServerConfigurator } from "./ServerConfigurator";
@ -15,7 +15,7 @@ import { VoiceChangerWorkletProcessorRequest } from "./@types/voice-changer-work
export class VoiceChnagerClient { export class VoiceChangerClient {
private configurator: ServerConfigurator private configurator: ServerConfigurator
private ctx: AudioContext private ctx: AudioContext
private vfEnable = false private vfEnable = false
@ -209,6 +209,18 @@ export class VoiceChnagerClient {
this.audioStreamer.setVoiceChangerMode(val) this.audioStreamer.setVoiceChangerMode(val)
} }
// configure worklet
configureWorklet = (setting: WorkletSetting) => {
const req: VoiceChangerWorkletProcessorRequest = {
requestType: "config",
voice: new ArrayBuffer(1),
numTrancateTreshold: setting.numTrancateTreshold,
volTrancateThreshold: setting.volTrancateThreshold,
volTrancateLength: setting.volTrancateLength
}
this.vcNode.postReceivedVoice(req)
}
// Configurator Method // Configurator Method
uploadFile = (file: File, onprogress: (progress: number, end: boolean) => void) => { uploadFile = (file: File, onprogress: (progress: number, end: boolean) => void) => {
return this.configurator.uploadFile(file, onprogress) return this.configurator.uploadFile(file, onprogress)

View File

@ -2,6 +2,7 @@
// (★1) chunk sizeは 128サンプル, 256byte(int16)と定義。 // (★1) chunk sizeは 128サンプル, 256byte(int16)と定義。
// (★2) 256byte(最低バッファサイズ256から間引いた個数x2byte)をchunkとして管理。 // (★2) 256byte(最低バッファサイズ256から間引いた個数x2byte)をchunkとして管理。
// 24000sample -> 1sec, 128sample(1chunk) -> 5.333msec // 24000sample -> 1sec, 128sample(1chunk) -> 5.333msec
// 187.5chunk -> 1sec
// types // types
export type VoiceChangerRequestParamas = { export type VoiceChangerRequestParamas = {
@ -31,6 +32,11 @@ export type VoiceChangerOptions = {
framework: Framework framework: Framework
} }
export type WorkletSetting = {
numTrancateTreshold: number,
volTrancateThreshold: number,
volTrancateLength: number
}
export type Speaker = { export type Speaker = {
"id": number, "id": number,
@ -160,7 +166,11 @@ export const DefaultVoiceChangerOptions: VoiceChangerOptions = {
onnxExecutionProvider: "CPUExecutionProvider" onnxExecutionProvider: "CPUExecutionProvider"
} }
export const DefaultWorkletSetting: WorkletSetting = {
numTrancateTreshold: 188,
volTrancateThreshold: 0.0005,
volTrancateLength: 32
}
export const VOICE_CHANGER_CLIENT_EXCEPTION = { export const VOICE_CHANGER_CLIENT_EXCEPTION = {
ERR_SIO_CONNECT_FAILED: "ERR_SIO_CONNECT_FAILED", ERR_SIO_CONNECT_FAILED: "ERR_SIO_CONNECT_FAILED",

View File

@ -16,7 +16,7 @@ class VoiceChangerWorkletProcessor extends AudioWorkletProcessor {
private BLOCK_SIZE = 128 private BLOCK_SIZE = 128
private initialized = false; private initialized = false;
private volume = 0 private volume = 0
private numTrancateTreshold = 50 private numTrancateTreshold = 150
private volTrancateThreshold = 0.0005 private volTrancateThreshold = 0.0005
private volTrancateLength = 32 private volTrancateLength = 32
private volTrancateCount = 0 private volTrancateCount = 0
@ -92,7 +92,7 @@ class VoiceChangerWorkletProcessor extends AudioWorkletProcessor {
} }
if (this.playBuffer.length === 0) { if (this.playBuffer.length === 0) {
console.log("[worklet] no play buffer") // console.log("[worklet] no play buffer")
return true return true
} }
@ -111,10 +111,10 @@ class VoiceChangerWorkletProcessor extends AudioWorkletProcessor {
} }
if (this.volTrancateCount < this.volTrancateLength) { if (this.volTrancateCount < this.volTrancateLength || this.volTrancateLength < 0) {
break break
} else { } else {
console.log("silent...skip") // console.log("silent...skip")
} }
} }