mirror of
https://github.com/w-okada/voice-changer.git
synced 2025-02-02 16:23:58 +03:00
async internal process
This commit is contained in:
parent
0e7c0daebc
commit
b24c781a72
@ -1,5 +1,11 @@
|
|||||||
import { VoiceChangerWorkletProcessorRequest } from "../@types/voice-changer-worklet-processor";
|
import { VoiceChangerWorkletProcessorRequest } from "../@types/voice-changer-worklet-processor";
|
||||||
import { DefaultClientSettng, DownSamplingMode, VOICE_CHANGER_CLIENT_EXCEPTION, WorkletNodeSetting, WorkletSetting } from "../const";
|
import {
|
||||||
|
DefaultClientSettng,
|
||||||
|
DownSamplingMode,
|
||||||
|
VOICE_CHANGER_CLIENT_EXCEPTION,
|
||||||
|
WorkletNodeSetting,
|
||||||
|
WorkletSetting,
|
||||||
|
} from "../const";
|
||||||
import { io, Socket } from "socket.io-client";
|
import { io, Socket } from "socket.io-client";
|
||||||
import { DefaultEventsMap } from "@socket.io/component-emitter";
|
import { DefaultEventsMap } from "@socket.io/component-emitter";
|
||||||
import { ServerRestClient } from "./ServerRestClient";
|
import { ServerRestClient } from "./ServerRestClient";
|
||||||
@ -8,7 +14,10 @@ export type VoiceChangerWorkletListener = {
|
|||||||
notifyVolume: (vol: number) => void;
|
notifyVolume: (vol: number) => void;
|
||||||
notifySendBufferingTime: (time: number) => void;
|
notifySendBufferingTime: (time: number) => void;
|
||||||
notifyResponseTime: (time: number, perf?: number[]) => void;
|
notifyResponseTime: (time: number, perf?: number[]) => void;
|
||||||
notifyException: (code: VOICE_CHANGER_CLIENT_EXCEPTION, message: string) => void;
|
notifyException: (
|
||||||
|
code: VOICE_CHANGER_CLIENT_EXCEPTION,
|
||||||
|
message: string
|
||||||
|
) => void;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type InternalCallback = {
|
export type InternalCallback = {
|
||||||
@ -29,8 +38,12 @@ export class VoiceChangerWorkletNode extends AudioWorkletNode {
|
|||||||
private outputNode: VoiceChangerWorkletNode | null = null;
|
private outputNode: VoiceChangerWorkletNode | null = null;
|
||||||
|
|
||||||
// Promises
|
// Promises
|
||||||
private startPromiseResolve: ((value: void | PromiseLike<void>) => void) | null = null;
|
private startPromiseResolve:
|
||||||
private stopPromiseResolve: ((value: void | PromiseLike<void>) => void) | null = null;
|
| ((value: void | PromiseLike<void>) => void)
|
||||||
|
| null = null;
|
||||||
|
private stopPromiseResolve:
|
||||||
|
| ((value: void | PromiseLike<void>) => void)
|
||||||
|
| null = null;
|
||||||
|
|
||||||
// InternalCallback
|
// InternalCallback
|
||||||
private internalCallback: InternalCallback | null = null;
|
private internalCallback: InternalCallback | null = null;
|
||||||
@ -49,9 +62,16 @@ export class VoiceChangerWorkletNode extends AudioWorkletNode {
|
|||||||
|
|
||||||
// 設定
|
// 設定
|
||||||
updateSetting = (setting: WorkletNodeSetting) => {
|
updateSetting = (setting: WorkletNodeSetting) => {
|
||||||
console.log(`[WorkletNode] Updating WorkletNode Setting,`, this.setting, setting);
|
console.log(
|
||||||
|
`[WorkletNode] Updating WorkletNode Setting,`,
|
||||||
|
this.setting,
|
||||||
|
setting
|
||||||
|
);
|
||||||
let recreateSocketIoRequired = false;
|
let recreateSocketIoRequired = false;
|
||||||
if (this.setting.serverUrl != setting.serverUrl || this.setting.protocol != setting.protocol) {
|
if (
|
||||||
|
this.setting.serverUrl != setting.serverUrl ||
|
||||||
|
this.setting.protocol != setting.protocol
|
||||||
|
) {
|
||||||
recreateSocketIoRequired = true;
|
recreateSocketIoRequired = true;
|
||||||
}
|
}
|
||||||
this.setting = setting;
|
this.setting = setting;
|
||||||
@ -80,7 +100,10 @@ export class VoiceChangerWorkletNode extends AudioWorkletNode {
|
|||||||
if (this.setting.protocol === "sio") {
|
if (this.setting.protocol === "sio") {
|
||||||
this.socket = io(this.setting.serverUrl + "/test");
|
this.socket = io(this.setting.serverUrl + "/test");
|
||||||
this.socket.on("connect_error", (err) => {
|
this.socket.on("connect_error", (err) => {
|
||||||
this.listener.notifyException(VOICE_CHANGER_CLIENT_EXCEPTION.ERR_SIO_CONNECT_FAILED, `[SIO] rconnection failed ${err}`);
|
this.listener.notifyException(
|
||||||
|
VOICE_CHANGER_CLIENT_EXCEPTION.ERR_SIO_CONNECT_FAILED,
|
||||||
|
`[SIO] rconnection failed ${err}`
|
||||||
|
);
|
||||||
});
|
});
|
||||||
this.socket.on("connect", () => {
|
this.socket.on("connect", () => {
|
||||||
console.log(`[SIO] connect to ${this.setting.serverUrl}`);
|
console.log(`[SIO] connect to ${this.setting.serverUrl}`);
|
||||||
@ -102,12 +125,18 @@ export class VoiceChangerWorkletNode extends AudioWorkletNode {
|
|||||||
|
|
||||||
// Quick hack for server device mode
|
// Quick hack for server device mode
|
||||||
if (response[0] == 0) {
|
if (response[0] == 0) {
|
||||||
this.listener.notifyResponseTime(Math.round(perf[0] * 1000), perf.slice(1, 4));
|
this.listener.notifyResponseTime(
|
||||||
|
Math.round(perf[0] * 1000),
|
||||||
|
perf.slice(1, 4)
|
||||||
|
);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (result.byteLength < 128 * 2) {
|
if (result.byteLength < 128 * 2) {
|
||||||
this.listener.notifyException(VOICE_CHANGER_CLIENT_EXCEPTION.ERR_SIO_INVALID_RESPONSE, `[SIO] recevied data is too short ${result.byteLength}`);
|
this.listener.notifyException(
|
||||||
|
VOICE_CHANGER_CLIENT_EXCEPTION.ERR_SIO_INVALID_RESPONSE,
|
||||||
|
`[SIO] recevied data is too short ${result.byteLength}`
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
if (this.outputNode != null) {
|
if (this.outputNode != null) {
|
||||||
this.outputNode.postReceivedVoice(response[1]);
|
this.outputNode.postReceivedVoice(response[1]);
|
||||||
@ -158,7 +187,11 @@ export class VoiceChangerWorkletNode extends AudioWorkletNode {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
private _averageDownsampleBuffer(buffer: Float32Array, originalSampleRate: number, destinationSamplerate: number) {
|
private _averageDownsampleBuffer(
|
||||||
|
buffer: Float32Array,
|
||||||
|
originalSampleRate: number,
|
||||||
|
destinationSamplerate: number
|
||||||
|
) {
|
||||||
if (originalSampleRate == destinationSamplerate) {
|
if (originalSampleRate == destinationSamplerate) {
|
||||||
return buffer;
|
return buffer;
|
||||||
}
|
}
|
||||||
@ -175,7 +208,11 @@ export class VoiceChangerWorkletNode extends AudioWorkletNode {
|
|||||||
// Use average value of skipped samples
|
// Use average value of skipped samples
|
||||||
var accum = 0,
|
var accum = 0,
|
||||||
count = 0;
|
count = 0;
|
||||||
for (var i = offsetBuffer; i < nextOffsetBuffer && i < buffer.length; i++) {
|
for (
|
||||||
|
var i = offsetBuffer;
|
||||||
|
i < nextOffsetBuffer && i < buffer.length;
|
||||||
|
i++
|
||||||
|
) {
|
||||||
accum += buffer[i];
|
accum += buffer[i];
|
||||||
count++;
|
count++;
|
||||||
}
|
}
|
||||||
@ -221,7 +258,11 @@ export class VoiceChangerWorkletNode extends AudioWorkletNode {
|
|||||||
} else {
|
} else {
|
||||||
//////// (Kind 2) 平均 //////////
|
//////// (Kind 2) 平均 //////////
|
||||||
// downsampledBuffer = this._averageDownsampleBuffer(buffer, 48000, 24000)
|
// downsampledBuffer = this._averageDownsampleBuffer(buffer, 48000, 24000)
|
||||||
downsampledBuffer = this._averageDownsampleBuffer(inputData, 48000, this.setting.sendingSampleRate);
|
downsampledBuffer = this._averageDownsampleBuffer(
|
||||||
|
inputData,
|
||||||
|
48000,
|
||||||
|
this.setting.sendingSampleRate
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Float to Int16 (internalの場合はfloatのまま行く。)
|
// Float to Int16 (internalの場合はfloatのまま行く。)
|
||||||
@ -264,7 +305,10 @@ export class VoiceChangerWorkletNode extends AudioWorkletNode {
|
|||||||
this.listener.notifySendBufferingTime(Date.now() - this.bufferStart);
|
this.listener.notifySendBufferingTime(Date.now() - this.bufferStart);
|
||||||
this.bufferStart = Date.now();
|
this.bufferStart = Date.now();
|
||||||
} else {
|
} else {
|
||||||
console.warn(`[worklet_node][voice-changer-worklet-processor] unknown response ${event.data.responseType}`, event.data);
|
console.warn(
|
||||||
|
`[worklet_node][voice-changer-worklet-processor] unknown response ${event.data.responseType}`,
|
||||||
|
event.data
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -281,7 +325,10 @@ export class VoiceChangerWorkletNode extends AudioWorkletNode {
|
|||||||
const restClient = new ServerRestClient(this.setting.serverUrl);
|
const restClient = new ServerRestClient(this.setting.serverUrl);
|
||||||
const res = await restClient.postVoice(timestamp, newBuffer.buffer);
|
const res = await restClient.postVoice(timestamp, newBuffer.buffer);
|
||||||
if (res.byteLength < 128 * 2) {
|
if (res.byteLength < 128 * 2) {
|
||||||
this.listener.notifyException(VOICE_CHANGER_CLIENT_EXCEPTION.ERR_REST_INVALID_RESPONSE, `[REST] recevied data is too short ${res.byteLength}`);
|
this.listener.notifyException(
|
||||||
|
VOICE_CHANGER_CLIENT_EXCEPTION.ERR_REST_INVALID_RESPONSE,
|
||||||
|
`[REST] recevied data is too short ${res.byteLength}`
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
if (this.outputNode != null) {
|
if (this.outputNode != null) {
|
||||||
this.outputNode.postReceivedVoice(res);
|
this.outputNode.postReceivedVoice(res);
|
||||||
@ -292,10 +339,22 @@ export class VoiceChangerWorkletNode extends AudioWorkletNode {
|
|||||||
}
|
}
|
||||||
} else if (this.setting.protocol == "internal") {
|
} else if (this.setting.protocol == "internal") {
|
||||||
if (!this.internalCallback) {
|
if (!this.internalCallback) {
|
||||||
this.listener.notifyException(VOICE_CHANGER_CLIENT_EXCEPTION.ERR_INTERNAL_AUDIO_PROCESS_CALLBACK_IS_NOT_INITIALIZED, `[AudioWorkletNode] internal audio process callback is not initialized`);
|
this.listener.notifyException(
|
||||||
|
VOICE_CHANGER_CLIENT_EXCEPTION.ERR_INTERNAL_AUDIO_PROCESS_CALLBACK_IS_NOT_INITIALIZED,
|
||||||
|
`[AudioWorkletNode] internal audio process callback is not initialized`
|
||||||
|
);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const res = await this.internalCallback.processAudio(newBuffer);
|
// const res = await this.internalCallback.processAudio(newBuffer);
|
||||||
|
// if (res.length < 128 * 2) {
|
||||||
|
// return;
|
||||||
|
// }
|
||||||
|
// if (this.outputNode != null) {
|
||||||
|
// this.outputNode.postReceivedVoice(res.buffer);
|
||||||
|
// } else {
|
||||||
|
// this.postReceivedVoice(res.buffer);
|
||||||
|
// }
|
||||||
|
this.internalCallback.processAudio(newBuffer).then((res) => {
|
||||||
if (res.length < 128 * 2) {
|
if (res.length < 128 * 2) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -304,6 +363,7 @@ export class VoiceChangerWorkletNode extends AudioWorkletNode {
|
|||||||
} else {
|
} else {
|
||||||
this.postReceivedVoice(res.buffer);
|
this.postReceivedVoice(res.buffer);
|
||||||
}
|
}
|
||||||
|
});
|
||||||
} else {
|
} else {
|
||||||
throw "unknown protocol";
|
throw "unknown protocol";
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user