EXP. remove microphone stream 4, fin
This commit is contained in:
parent
fccd631c00
commit
eb12f3db64
11
client/demo/dist/index.html
vendored
11
client/demo/dist/index.html
vendored
@ -1,10 +1 @@
|
||||
<!DOCTYPE html>
|
||||
<html style="width: 100%; height: 100%; overflow: hidden">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<title>Voice Changer Client Demo</title>
|
||||
<script defer src="index.js"></script></head>
|
||||
<body style="width: 100%; height: 100%; margin: 0px">
|
||||
<div id="app" style="width: 100%; height: 100%"></div>
|
||||
</body>
|
||||
</html>
|
||||
<!doctype html><html style="width:100%;height:100%;overflow:hidden"><head><meta charset="utf-8"/><title>Voice Changer Client Demo</title><script defer="defer" src="index.js"></script></head><body style="width:100%;height:100%;margin:0"><div id="app" style="width:100%;height:100%"></div></body></html>
|
793
client/demo/dist/index.js
vendored
793
client/demo/dist/index.js
vendored
File diff suppressed because one or more lines are too long
31
client/demo/dist/index.js.LICENSE.txt
vendored
Normal file
31
client/demo/dist/index.js.LICENSE.txt
vendored
Normal file
@ -0,0 +1,31 @@
|
||||
/*! regenerator-runtime -- Copyright (c) 2014-present, Facebook, Inc. -- license (MIT): https://github.com/facebook/regenerator/blob/main/LICENSE */
|
||||
|
||||
/**
|
||||
* @license React
|
||||
* react-dom.production.min.js
|
||||
*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @license React
|
||||
* react.production.min.js
|
||||
*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @license React
|
||||
* scheduler.production.min.js
|
||||
*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
2229
client/demo/package-lock.json
generated
2229
client/demo/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -23,7 +23,7 @@
|
||||
"@babel/preset-env": "^7.20.2",
|
||||
"@babel/preset-react": "^7.18.6",
|
||||
"@babel/preset-typescript": "^7.18.6",
|
||||
"@types/node": "^18.13.0",
|
||||
"@types/node": "^18.14.0",
|
||||
"@types/react": "^18.0.28",
|
||||
"@types/react-dom": "^18.0.11",
|
||||
"autoprefixer": "^10.4.13",
|
||||
@ -39,7 +39,7 @@
|
||||
"html-webpack-plugin": "^5.5.0",
|
||||
"npm-run-all": "^4.1.5",
|
||||
"postcss-loader": "^7.0.2",
|
||||
"postcss-nested": "^6.0.0",
|
||||
"postcss-nested": "^6.0.1",
|
||||
"prettier": "^2.8.4",
|
||||
"rimraf": "^4.1.2",
|
||||
"style-loader": "^3.3.1",
|
||||
@ -51,7 +51,7 @@
|
||||
"webpack-dev-server": "^4.11.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"@dannadori/voice-changer-client-js": "^1.0.70",
|
||||
"@dannadori/voice-changer-client-js": "^1.0.72",
|
||||
"@fortawesome/fontawesome-svg-core": "^6.3.0",
|
||||
"@fortawesome/free-brands-svg-icons": "^6.3.0",
|
||||
"@fortawesome/free-regular-svg-icons": "^6.3.0",
|
||||
|
@ -8,7 +8,6 @@ export const useAudioConfig = (): AudioConfigState => {
|
||||
const [audioContext, setAudioContext] = useState<AudioContext | null>(null)
|
||||
useEffect(() => {
|
||||
const createAudioContext = () => {
|
||||
console.log("click window")
|
||||
const ctx = new AudioContext()
|
||||
document.removeEventListener('touchstart', createAudioContext);
|
||||
document.removeEventListener('mousedown', createAudioContext);
|
||||
@ -18,9 +17,6 @@ export const useAudioConfig = (): AudioConfigState => {
|
||||
document.addEventListener('mousedown', createAudioContext);
|
||||
}, [])
|
||||
|
||||
|
||||
console.log("AUDIO CONTEXT", audioContext)
|
||||
|
||||
const ret: AudioConfigState = {
|
||||
audioContext
|
||||
}
|
||||
|
@ -236,11 +236,12 @@ export const useDeviceSetting = (): DeviceSettingState => {
|
||||
// }
|
||||
const onOutputRecordStartClicked = async () => {
|
||||
setOutputRecordingStarted(true)
|
||||
await appState.workletSetting.startOutputRecording()
|
||||
await appState.workletNodeSetting.startOutputRecording()
|
||||
}
|
||||
const onOutputRecordStopClicked = async () => {
|
||||
setOutputRecordingStarted(false)
|
||||
await appState.workletSetting.stopOutputRecording()
|
||||
const record = await appState.workletNodeSetting.stopOutputRecording()
|
||||
downloadRecord(record)
|
||||
}
|
||||
|
||||
const startClassName = outputRecordingStarted ? "body-button-active" : "body-button-stanby"
|
||||
@ -258,7 +259,7 @@ export const useDeviceSetting = (): DeviceSettingState => {
|
||||
</div>
|
||||
)
|
||||
|
||||
}, [audioOutputForGUI, outputRecordingStarted, appState.workletSetting.startOutputRecording, appState.workletSetting.stopOutputRecording])
|
||||
}, [audioOutputForGUI, outputRecordingStarted, appState.workletNodeSetting.startOutputRecording, appState.workletNodeSetting.stopOutputRecording])
|
||||
|
||||
useEffect(() => {
|
||||
[AUDIO_ELEMENT_FOR_PLAY_RESULT, AUDIO_ELEMENT_FOR_TEST_ORIGINAL, AUDIO_ELEMENT_FOR_TEST_CONVERTED_ECHOBACK].forEach(x => {
|
||||
@ -338,6 +339,53 @@ export const useDeviceSetting = (): DeviceSettingState => {
|
||||
}, [audioInputRow, audioMediaInputRow, audioOutputRow, audioOutputRecordingRow, useServerMicrophone])
|
||||
|
||||
|
||||
const downloadRecord = (data: Float32Array) => {
|
||||
|
||||
const writeString = (view: DataView, offset: number, string: string) => {
|
||||
for (var i = 0; i < string.length; i++) {
|
||||
view.setUint8(offset + i, string.charCodeAt(i));
|
||||
}
|
||||
};
|
||||
|
||||
const floatTo16BitPCM = (output: DataView, offset: number, input: Float32Array) => {
|
||||
for (var i = 0; i < input.length; i++, offset += 2) {
|
||||
var s = Math.max(-1, Math.min(1, input[i]));
|
||||
output.setInt16(offset, s < 0 ? s * 0x8000 : s * 0x7FFF, true);
|
||||
}
|
||||
};
|
||||
|
||||
const buffer = new ArrayBuffer(44 + data.length * 2);
|
||||
const view = new DataView(buffer);
|
||||
|
||||
// https://www.youfit.co.jp/archives/1418
|
||||
writeString(view, 0, 'RIFF'); // RIFFヘッダ
|
||||
view.setUint32(4, 32 + data.length * 2, true); // これ以降のファイルサイズ
|
||||
writeString(view, 8, 'WAVE'); // WAVEヘッダ
|
||||
writeString(view, 12, 'fmt '); // fmtチャンク
|
||||
view.setUint32(16, 16, true); // fmtチャンクのバイト数
|
||||
view.setUint16(20, 1, true); // フォーマットID
|
||||
view.setUint16(22, 1, true); // チャンネル数
|
||||
view.setUint32(24, 48000, true); // サンプリングレート
|
||||
view.setUint32(28, 48000 * 2, true); // データ速度
|
||||
view.setUint16(32, 2, true); // ブロックサイズ
|
||||
view.setUint16(34, 16, true); // サンプルあたりのビット数
|
||||
writeString(view, 36, 'data'); // dataチャンク
|
||||
view.setUint32(40, data.length * 2, true); // 波形データのバイト数
|
||||
floatTo16BitPCM(view, 44, data); // 波形データ
|
||||
const audioBlob = new Blob([view], { type: 'audio/wav' });
|
||||
|
||||
const url = URL.createObjectURL(audioBlob);
|
||||
const a = document.createElement("a");
|
||||
a.href = url;
|
||||
a.download = `output.wav`;
|
||||
document.body.appendChild(a);
|
||||
a.click();
|
||||
document.body.removeChild(a);
|
||||
URL.revokeObjectURL(url);
|
||||
|
||||
|
||||
}
|
||||
|
||||
// 出力の録音データ(from worklet)がストアされたら実行
|
||||
useEffect(() => {
|
||||
if (!appState.outputRecordData || appState.outputRecordData?.length == 0) {
|
||||
|
@ -24,7 +24,6 @@ export const useSpeakerSetting = () => {
|
||||
const dst = appState.clientSetting.clientSetting.correspondences?.find(x => {
|
||||
return x.sid == dstId
|
||||
})
|
||||
console.log("calcDefaultF0Factor", srcId, dstId, src, dst)
|
||||
const recommendedF0Factor = dst && src ? dst.correspondence / src.correspondence : 0
|
||||
return recommendedF0Factor
|
||||
}
|
||||
|
@ -12,7 +12,7 @@ export const useStateControlCheckbox = (className: string, changeCallback?: (new
|
||||
const currentValForTriggerCallbackRef = useRef<boolean>(false);
|
||||
// (4) トリガチェックボックス
|
||||
const callback = useMemo(() => {
|
||||
console.log("generate callback function", className);
|
||||
// console.log("generate callback function", className);
|
||||
return (newVal: boolean) => {
|
||||
if (!changeCallback) {
|
||||
return;
|
||||
|
342
client/lib/package-lock.json
generated
342
client/lib/package-lock.json
generated
@ -1,23 +1,19 @@
|
||||
{
|
||||
"name": "@dannadori/voice-changer-client-js",
|
||||
"version": "1.0.70",
|
||||
"version": "1.0.72",
|
||||
"lockfileVersion": 2,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "@dannadori/voice-changer-client-js",
|
||||
"version": "1.0.70",
|
||||
"version": "1.0.72",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"@types/readable-stream": "^2.3.15",
|
||||
"amazon-chime-sdk-js": "^3.11.0",
|
||||
"install": "^0.13.0",
|
||||
"localforage": "^1.10.0",
|
||||
"microphone-stream": "^6.0.1",
|
||||
"path-browserify": "^1.0.1",
|
||||
"react": "^18.2.0",
|
||||
"react-dom": "^18.2.0",
|
||||
"readable-stream": "^4.3.0",
|
||||
"socket.io-client": "^4.6.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
@ -2121,17 +2117,6 @@
|
||||
"integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/abort-controller": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz",
|
||||
"integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==",
|
||||
"dependencies": {
|
||||
"event-target-shim": "^5.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6.5"
|
||||
}
|
||||
},
|
||||
"node_modules/accepts": {
|
||||
"version": "1.3.8",
|
||||
"resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz",
|
||||
@ -2388,25 +2373,6 @@
|
||||
"integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/base64-js": {
|
||||
"version": "1.5.1",
|
||||
"resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz",
|
||||
"integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==",
|
||||
"funding": [
|
||||
{
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/feross"
|
||||
},
|
||||
{
|
||||
"type": "patreon",
|
||||
"url": "https://www.patreon.com/feross"
|
||||
},
|
||||
{
|
||||
"type": "consulting",
|
||||
"url": "https://feross.org/support"
|
||||
}
|
||||
]
|
||||
},
|
||||
"node_modules/batch": {
|
||||
"version": "0.6.1",
|
||||
"resolved": "https://registry.npmjs.org/batch/-/batch-0.6.1.tgz",
|
||||
@ -2546,33 +2512,11 @@
|
||||
"node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7"
|
||||
}
|
||||
},
|
||||
"node_modules/buffer": {
|
||||
"version": "6.0.3",
|
||||
"resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz",
|
||||
"integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==",
|
||||
"funding": [
|
||||
{
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/feross"
|
||||
},
|
||||
{
|
||||
"type": "patreon",
|
||||
"url": "https://www.patreon.com/feross"
|
||||
},
|
||||
{
|
||||
"type": "consulting",
|
||||
"url": "https://feross.org/support"
|
||||
}
|
||||
],
|
||||
"dependencies": {
|
||||
"base64-js": "^1.3.1",
|
||||
"ieee754": "^1.2.1"
|
||||
}
|
||||
},
|
||||
"node_modules/buffer-from": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz",
|
||||
"integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ=="
|
||||
"integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/bytes": {
|
||||
"version": "3.0.0",
|
||||
@ -3480,14 +3424,6 @@
|
||||
"node": ">= 0.6"
|
||||
}
|
||||
},
|
||||
"node_modules/event-target-shim": {
|
||||
"version": "5.0.1",
|
||||
"resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz",
|
||||
"integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==",
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/eventemitter3": {
|
||||
"version": "4.0.7",
|
||||
"resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz",
|
||||
@ -3498,6 +3434,7 @@
|
||||
"version": "3.3.0",
|
||||
"resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz",
|
||||
"integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=0.8.x"
|
||||
}
|
||||
@ -4144,6 +4081,15 @@
|
||||
"util-deprecate": "~1.0.1"
|
||||
}
|
||||
},
|
||||
"node_modules/hpack.js/node_modules/string_decoder": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
|
||||
"integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"safe-buffer": "~5.1.0"
|
||||
}
|
||||
},
|
||||
"node_modules/html-entities": {
|
||||
"version": "2.3.3",
|
||||
"resolved": "https://registry.npmjs.org/html-entities/-/html-entities-2.3.3.tgz",
|
||||
@ -4237,25 +4183,6 @@
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/ieee754": {
|
||||
"version": "1.2.1",
|
||||
"resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz",
|
||||
"integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==",
|
||||
"funding": [
|
||||
{
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/feross"
|
||||
},
|
||||
{
|
||||
"type": "patreon",
|
||||
"url": "https://www.patreon.com/feross"
|
||||
},
|
||||
{
|
||||
"type": "consulting",
|
||||
"url": "https://feross.org/support"
|
||||
}
|
||||
]
|
||||
},
|
||||
"node_modules/ignore": {
|
||||
"version": "5.2.4",
|
||||
"resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz",
|
||||
@ -4327,15 +4254,8 @@
|
||||
"node_modules/inherits": {
|
||||
"version": "2.0.4",
|
||||
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
|
||||
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
|
||||
},
|
||||
"node_modules/install": {
|
||||
"version": "0.13.0",
|
||||
"resolved": "https://registry.npmjs.org/install/-/install-0.13.0.tgz",
|
||||
"integrity": "sha512-zDml/jzr2PKU9I8J/xyZBQn8rPCAY//UOYNmR01XwNwyfhEWObo2SWfSl1+0tm1u6PhxLwDnfsT/6jB7OUxqFA==",
|
||||
"engines": {
|
||||
"node": ">= 0.10"
|
||||
}
|
||||
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/internal-slot": {
|
||||
"version": "1.0.5",
|
||||
@ -5019,28 +4939,6 @@
|
||||
"node": ">=8.6"
|
||||
}
|
||||
},
|
||||
"node_modules/microphone-stream": {
|
||||
"version": "6.0.1",
|
||||
"resolved": "https://registry.npmjs.org/microphone-stream/-/microphone-stream-6.0.1.tgz",
|
||||
"integrity": "sha512-yD7B2SfxaB+pLlWLcX4NNk2y81xwCyXGrB7q67nbP/Jq8JpIebX2iQV/M+LNZUleSg0A2cWYpb+wmdDs5nm3Fg==",
|
||||
"dependencies": {
|
||||
"buffer-from": "^1.1.1",
|
||||
"readable-stream": "^3.6.0"
|
||||
}
|
||||
},
|
||||
"node_modules/microphone-stream/node_modules/readable-stream": {
|
||||
"version": "3.6.0",
|
||||
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz",
|
||||
"integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==",
|
||||
"dependencies": {
|
||||
"inherits": "^2.0.3",
|
||||
"string_decoder": "^1.1.1",
|
||||
"util-deprecate": "^1.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 6"
|
||||
}
|
||||
},
|
||||
"node_modules/mime": {
|
||||
"version": "1.6.0",
|
||||
"resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz",
|
||||
@ -5665,11 +5563,6 @@
|
||||
"node": ">= 0.8"
|
||||
}
|
||||
},
|
||||
"node_modules/path-browserify": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-1.0.1.tgz",
|
||||
"integrity": "sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g=="
|
||||
},
|
||||
"node_modules/path-exists": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
|
||||
@ -5860,14 +5753,6 @@
|
||||
"node": ">=6.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/process": {
|
||||
"version": "0.11.10",
|
||||
"resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz",
|
||||
"integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==",
|
||||
"engines": {
|
||||
"node": ">= 0.6.0"
|
||||
}
|
||||
},
|
||||
"node_modules/process-nextick-args": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz",
|
||||
@ -6100,17 +5985,17 @@
|
||||
}
|
||||
},
|
||||
"node_modules/readable-stream": {
|
||||
"version": "4.3.0",
|
||||
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-4.3.0.tgz",
|
||||
"integrity": "sha512-MuEnA0lbSi7JS8XM+WNJlWZkHAAdm7gETHdFK//Q/mChGyj2akEFtdLZh32jSdkWGbRwCW9pn6g3LWDdDeZnBQ==",
|
||||
"version": "3.6.0",
|
||||
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz",
|
||||
"integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"abort-controller": "^3.0.0",
|
||||
"buffer": "^6.0.3",
|
||||
"events": "^3.3.0",
|
||||
"process": "^0.11.10"
|
||||
"inherits": "^2.0.3",
|
||||
"string_decoder": "^1.1.1",
|
||||
"util-deprecate": "^1.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
|
||||
"node": ">= 6"
|
||||
}
|
||||
},
|
||||
"node_modules/readdirp": {
|
||||
@ -6753,20 +6638,6 @@
|
||||
"wbuf": "^1.7.3"
|
||||
}
|
||||
},
|
||||
"node_modules/spdy-transport/node_modules/readable-stream": {
|
||||
"version": "3.6.0",
|
||||
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz",
|
||||
"integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"inherits": "^2.0.3",
|
||||
"string_decoder": "^1.1.1",
|
||||
"util-deprecate": "^1.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 6"
|
||||
}
|
||||
},
|
||||
"node_modules/statuses": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz",
|
||||
@ -6777,13 +6648,34 @@
|
||||
}
|
||||
},
|
||||
"node_modules/string_decoder": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
|
||||
"integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
|
||||
"version": "1.3.0",
|
||||
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz",
|
||||
"integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"safe-buffer": "~5.1.0"
|
||||
"safe-buffer": "~5.2.0"
|
||||
}
|
||||
},
|
||||
"node_modules/string_decoder/node_modules/safe-buffer": {
|
||||
"version": "5.2.1",
|
||||
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
|
||||
"integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
|
||||
"dev": true,
|
||||
"funding": [
|
||||
{
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/feross"
|
||||
},
|
||||
{
|
||||
"type": "patreon",
|
||||
"url": "https://www.patreon.com/feross"
|
||||
},
|
||||
{
|
||||
"type": "consulting",
|
||||
"url": "https://feross.org/support"
|
||||
}
|
||||
]
|
||||
},
|
||||
"node_modules/string.prototype.matchall": {
|
||||
"version": "4.0.8",
|
||||
"resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.8.tgz",
|
||||
@ -7243,7 +7135,8 @@
|
||||
"node_modules/util-deprecate": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
|
||||
"integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw=="
|
||||
"integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/utils-merge": {
|
||||
"version": "1.0.1",
|
||||
@ -9690,14 +9583,6 @@
|
||||
"integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==",
|
||||
"dev": true
|
||||
},
|
||||
"abort-controller": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz",
|
||||
"integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==",
|
||||
"requires": {
|
||||
"event-target-shim": "^5.0.0"
|
||||
}
|
||||
},
|
||||
"accepts": {
|
||||
"version": "1.3.8",
|
||||
"resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz",
|
||||
@ -9885,11 +9770,6 @@
|
||||
"integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
|
||||
"dev": true
|
||||
},
|
||||
"base64-js": {
|
||||
"version": "1.5.1",
|
||||
"resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz",
|
||||
"integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA=="
|
||||
},
|
||||
"batch": {
|
||||
"version": "0.6.1",
|
||||
"resolved": "https://registry.npmjs.org/batch/-/batch-0.6.1.tgz",
|
||||
@ -9999,19 +9879,11 @@
|
||||
"update-browserslist-db": "^1.0.10"
|
||||
}
|
||||
},
|
||||
"buffer": {
|
||||
"version": "6.0.3",
|
||||
"resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz",
|
||||
"integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==",
|
||||
"requires": {
|
||||
"base64-js": "^1.3.1",
|
||||
"ieee754": "^1.2.1"
|
||||
}
|
||||
},
|
||||
"buffer-from": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz",
|
||||
"integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ=="
|
||||
"integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==",
|
||||
"dev": true
|
||||
},
|
||||
"bytes": {
|
||||
"version": "3.0.0",
|
||||
@ -10677,11 +10549,6 @@
|
||||
"integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==",
|
||||
"dev": true
|
||||
},
|
||||
"event-target-shim": {
|
||||
"version": "5.0.1",
|
||||
"resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz",
|
||||
"integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ=="
|
||||
},
|
||||
"eventemitter3": {
|
||||
"version": "4.0.7",
|
||||
"resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz",
|
||||
@ -10691,7 +10558,8 @@
|
||||
"events": {
|
||||
"version": "3.3.0",
|
||||
"resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz",
|
||||
"integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q=="
|
||||
"integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==",
|
||||
"dev": true
|
||||
},
|
||||
"execa": {
|
||||
"version": "5.1.1",
|
||||
@ -11175,6 +11043,15 @@
|
||||
"string_decoder": "~1.1.1",
|
||||
"util-deprecate": "~1.0.1"
|
||||
}
|
||||
},
|
||||
"string_decoder": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
|
||||
"integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"safe-buffer": "~5.1.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -11248,11 +11125,6 @@
|
||||
"safer-buffer": ">= 2.1.2 < 3"
|
||||
}
|
||||
},
|
||||
"ieee754": {
|
||||
"version": "1.2.1",
|
||||
"resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz",
|
||||
"integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA=="
|
||||
},
|
||||
"ignore": {
|
||||
"version": "5.2.4",
|
||||
"resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz",
|
||||
@ -11303,12 +11175,8 @@
|
||||
"inherits": {
|
||||
"version": "2.0.4",
|
||||
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
|
||||
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
|
||||
},
|
||||
"install": {
|
||||
"version": "0.13.0",
|
||||
"resolved": "https://registry.npmjs.org/install/-/install-0.13.0.tgz",
|
||||
"integrity": "sha512-zDml/jzr2PKU9I8J/xyZBQn8rPCAY//UOYNmR01XwNwyfhEWObo2SWfSl1+0tm1u6PhxLwDnfsT/6jB7OUxqFA=="
|
||||
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
|
||||
"dev": true
|
||||
},
|
||||
"internal-slot": {
|
||||
"version": "1.0.5",
|
||||
@ -11801,27 +11669,6 @@
|
||||
"picomatch": "^2.3.1"
|
||||
}
|
||||
},
|
||||
"microphone-stream": {
|
||||
"version": "6.0.1",
|
||||
"resolved": "https://registry.npmjs.org/microphone-stream/-/microphone-stream-6.0.1.tgz",
|
||||
"integrity": "sha512-yD7B2SfxaB+pLlWLcX4NNk2y81xwCyXGrB7q67nbP/Jq8JpIebX2iQV/M+LNZUleSg0A2cWYpb+wmdDs5nm3Fg==",
|
||||
"requires": {
|
||||
"buffer-from": "^1.1.1",
|
||||
"readable-stream": "^3.6.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"readable-stream": {
|
||||
"version": "3.6.0",
|
||||
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz",
|
||||
"integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==",
|
||||
"requires": {
|
||||
"inherits": "^2.0.3",
|
||||
"string_decoder": "^1.1.1",
|
||||
"util-deprecate": "^1.0.1"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"mime": {
|
||||
"version": "1.6.0",
|
||||
"resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz",
|
||||
@ -12286,11 +12133,6 @@
|
||||
"integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==",
|
||||
"dev": true
|
||||
},
|
||||
"path-browserify": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-1.0.1.tgz",
|
||||
"integrity": "sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g=="
|
||||
},
|
||||
"path-exists": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
|
||||
@ -12423,11 +12265,6 @@
|
||||
"fast-diff": "^1.1.2"
|
||||
}
|
||||
},
|
||||
"process": {
|
||||
"version": "0.11.10",
|
||||
"resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz",
|
||||
"integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A=="
|
||||
},
|
||||
"process-nextick-args": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz",
|
||||
@ -12597,14 +12434,14 @@
|
||||
}
|
||||
},
|
||||
"readable-stream": {
|
||||
"version": "4.3.0",
|
||||
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-4.3.0.tgz",
|
||||
"integrity": "sha512-MuEnA0lbSi7JS8XM+WNJlWZkHAAdm7gETHdFK//Q/mChGyj2akEFtdLZh32jSdkWGbRwCW9pn6g3LWDdDeZnBQ==",
|
||||
"version": "3.6.0",
|
||||
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz",
|
||||
"integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"abort-controller": "^3.0.0",
|
||||
"buffer": "^6.0.3",
|
||||
"events": "^3.3.0",
|
||||
"process": "^0.11.10"
|
||||
"inherits": "^2.0.3",
|
||||
"string_decoder": "^1.1.1",
|
||||
"util-deprecate": "^1.0.1"
|
||||
}
|
||||
},
|
||||
"readdirp": {
|
||||
@ -13117,19 +12954,6 @@
|
||||
"obuf": "^1.1.2",
|
||||
"readable-stream": "^3.0.6",
|
||||
"wbuf": "^1.7.3"
|
||||
},
|
||||
"dependencies": {
|
||||
"readable-stream": {
|
||||
"version": "3.6.0",
|
||||
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz",
|
||||
"integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"inherits": "^2.0.3",
|
||||
"string_decoder": "^1.1.1",
|
||||
"util-deprecate": "^1.0.1"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"statuses": {
|
||||
@ -13139,11 +12963,20 @@
|
||||
"dev": true
|
||||
},
|
||||
"string_decoder": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
|
||||
"integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
|
||||
"version": "1.3.0",
|
||||
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz",
|
||||
"integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"safe-buffer": "~5.1.0"
|
||||
"safe-buffer": "~5.2.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"safe-buffer": {
|
||||
"version": "5.2.1",
|
||||
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
|
||||
"integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
|
||||
"dev": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"string.prototype.matchall": {
|
||||
@ -13448,7 +13281,8 @@
|
||||
"util-deprecate": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
|
||||
"integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw=="
|
||||
"integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==",
|
||||
"dev": true
|
||||
},
|
||||
"utils-merge": {
|
||||
"version": "1.0.1",
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@dannadori/voice-changer-client-js",
|
||||
"version": "1.0.70",
|
||||
"version": "1.0.72",
|
||||
"description": "",
|
||||
"main": "dist/index.js",
|
||||
"directories": {
|
||||
@ -48,13 +48,9 @@
|
||||
"dependencies": {
|
||||
"@types/readable-stream": "^2.3.15",
|
||||
"amazon-chime-sdk-js": "^3.11.0",
|
||||
"install": "^0.13.0",
|
||||
"localforage": "^1.10.0",
|
||||
"microphone-stream": "^6.0.1",
|
||||
"path-browserify": "^1.0.1",
|
||||
"react": "^18.2.0",
|
||||
"react-dom": "^18.2.0",
|
||||
"readable-stream": "^4.3.0",
|
||||
"socket.io-client": "^4.6.0"
|
||||
}
|
||||
}
|
||||
|
@ -1,10 +1,15 @@
|
||||
export declare const RequestType: {
|
||||
readonly voice: "voice";
|
||||
readonly config: "config";
|
||||
readonly startRecording: "startRecording";
|
||||
readonly stopRecording: "stopRecording";
|
||||
readonly start: "start";
|
||||
readonly stop: "stop";
|
||||
};
|
||||
export type RequestType = typeof RequestType[keyof typeof RequestType];
|
||||
export declare const ResponseType: {
|
||||
readonly volume: "volume";
|
||||
readonly inputData: "inputData";
|
||||
};
|
||||
export type ResponseType = typeof ResponseType[keyof typeof ResponseType];
|
||||
export type VoiceChangerWorkletProcessorRequest = {
|
||||
requestType: RequestType;
|
||||
voice: ArrayBuffer;
|
||||
@ -12,3 +17,9 @@ export type VoiceChangerWorkletProcessorRequest = {
|
||||
volTrancateThreshold: number;
|
||||
volTrancateLength: number;
|
||||
};
|
||||
export type VoiceChangerWorkletProcessorResponse = {
|
||||
responseType: ResponseType;
|
||||
volume?: number;
|
||||
recordData?: Float32Array[];
|
||||
inputData?: Float32Array;
|
||||
};
|
||||
|
@ -100,7 +100,7 @@ export class VoiceChangerClient {
|
||||
//// Input デバイスがnullの時はmicStreamを止めてリターン
|
||||
if (!this.setting.audioInput) {
|
||||
console.log(`Input Setup=> client mic is disabled.`)
|
||||
this.vcNode.stopRecording()
|
||||
this.vcNode.stop()
|
||||
await this.unlock(lockNum)
|
||||
return
|
||||
}
|
||||
@ -137,14 +137,14 @@ export class VoiceChangerClient {
|
||||
this.inputGainNode.connect(voiceFocusNode.start) // input node -> vf node
|
||||
voiceFocusNode.end.connect(this.vcNode)
|
||||
} else {
|
||||
console.log("input___ media stream", this.currentMediaStream)
|
||||
this.currentMediaStream.getTracks().forEach(x => {
|
||||
console.log("input___ media stream set", x.getSettings())
|
||||
console.log("input___ media stream con", x.getConstraints())
|
||||
console.log("input___ media stream cap", x.getCapabilities())
|
||||
})
|
||||
console.log("input___ media node", this.currentMediaStreamAudioSourceNode)
|
||||
console.log("input___ gain node", this.inputGainNode.channelCount, this.inputGainNode)
|
||||
// console.log("input___ media stream", this.currentMediaStream)
|
||||
// this.currentMediaStream.getTracks().forEach(x => {
|
||||
// console.log("input___ media stream set", x.getSettings())
|
||||
// console.log("input___ media stream con", x.getConstraints())
|
||||
// console.log("input___ media stream cap", x.getCapabilities())
|
||||
// })
|
||||
// console.log("input___ media node", this.currentMediaStreamAudioSourceNode)
|
||||
// console.log("input___ gain node", this.inputGainNode.channelCount, this.inputGainNode)
|
||||
this.inputGainNode.connect(this.vcNode)
|
||||
}
|
||||
console.log("Input Setup=> success")
|
||||
@ -155,11 +155,11 @@ export class VoiceChangerClient {
|
||||
}
|
||||
|
||||
start = () => {
|
||||
this.vcNode.startRecording()
|
||||
this.vcNode.start()
|
||||
this._isVoiceChanging = true
|
||||
}
|
||||
stop = () => {
|
||||
this.vcNode.stopRecording()
|
||||
this.vcNode.stop()
|
||||
this._isVoiceChanging = false
|
||||
}
|
||||
|
||||
@ -251,11 +251,11 @@ export class VoiceChangerClient {
|
||||
configureWorklet = (setting: WorkletSetting) => {
|
||||
this.vcNode.configure(setting)
|
||||
}
|
||||
startRecording = () => {
|
||||
this.vcNode.startRecording()
|
||||
startOutputRecording = () => {
|
||||
this.vcNode.startOutputRecording()
|
||||
}
|
||||
stopRecording = () => {
|
||||
this.vcNode.stopRecording()
|
||||
stopOutputRecording = () => {
|
||||
return this.vcNode.stopOutputRecording()
|
||||
}
|
||||
|
||||
|
||||
|
@ -5,7 +5,6 @@ import { DefaultEventsMap } from "@socket.io/component-emitter";
|
||||
|
||||
export type VoiceChangerWorkletListener = {
|
||||
notifyVolume: (vol: number) => void
|
||||
notifyOutputRecordData: (data: Float32Array[]) => void
|
||||
notifySendBufferingTime: (time: number) => void
|
||||
notifyResponseTime: (time: number) => void
|
||||
notifyException: (code: VOICE_CHANGER_CLIENT_EXCEPTION, message: string) => void
|
||||
@ -20,6 +19,9 @@ export class VoiceChangerWorkletNode extends AudioWorkletNode {
|
||||
// performance monitor
|
||||
private bufferStart = 0;
|
||||
|
||||
private isOutputRecording = false;
|
||||
private recordingOutputChunk: Float32Array[] = []
|
||||
|
||||
constructor(context: AudioContext, listener: VoiceChangerWorkletListener) {
|
||||
super(context, "voice-changer-worklet-processor");
|
||||
this.port.onmessage = this.handleMessage.bind(this);
|
||||
@ -78,14 +80,42 @@ export class VoiceChangerWorkletNode extends AudioWorkletNode {
|
||||
}
|
||||
|
||||
private postReceivedVoice = (data: ArrayBuffer) => {
|
||||
// Int16 to Float
|
||||
const i16Data = new Int16Array(data)
|
||||
const f32Data = new Float32Array(i16Data.length)
|
||||
// console.log(`[worklet] f32DataLength${f32Data.length} i16DataLength${i16Data.length}`)
|
||||
i16Data.forEach((x, i) => {
|
||||
const float = (x >= 0x8000) ? -(0x10000 - x) / 0x8000 : x / 0x7FFF;
|
||||
f32Data[i] = float
|
||||
})
|
||||
|
||||
// アップサンプリング
|
||||
let upSampledBuffer: Float32Array | null = null
|
||||
if (this.setting.sendingSampleRate == 48000) {
|
||||
upSampledBuffer = f32Data
|
||||
} else {
|
||||
upSampledBuffer = new Float32Array(f32Data.length * 2)
|
||||
for (let i = 0; i < f32Data.length; i++) {
|
||||
const currentFrame = f32Data[i]
|
||||
const nextFrame = i + 1 < f32Data.length ? f32Data[i + 1] : f32Data[i]
|
||||
upSampledBuffer[i * 2] = currentFrame
|
||||
upSampledBuffer[i * 2 + 1] = (currentFrame + nextFrame) / 2
|
||||
}
|
||||
}
|
||||
|
||||
const req: VoiceChangerWorkletProcessorRequest = {
|
||||
requestType: "voice",
|
||||
voice: data,
|
||||
voice: upSampledBuffer,
|
||||
numTrancateTreshold: 0,
|
||||
volTrancateThreshold: 0,
|
||||
volTrancateLength: 0
|
||||
}
|
||||
this.port.postMessage(req)
|
||||
|
||||
if (this.isOutputRecording) {
|
||||
this.recordingOutputChunk.push(upSampledBuffer)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private _averageDownsampleBuffer(buffer: Float32Array, originalSampleRate: number, destinationSamplerate: number) {
|
||||
@ -121,8 +151,6 @@ export class VoiceChangerWorkletNode extends AudioWorkletNode {
|
||||
// console.log(`[Node:handleMessage_] `, event.data.volume);
|
||||
if (event.data.responseType === "volume") {
|
||||
this.listener.notifyVolume(event.data.volume as number)
|
||||
} else if (event.data.responseType === "recordData") {
|
||||
this.listener.notifyOutputRecordData(event.data.recordData as Float32Array[])
|
||||
} else if (event.data.responseType === "inputData") {
|
||||
const inputData = event.data.inputData as Float32Array
|
||||
// console.log("receive input data", inputData)
|
||||
@ -227,9 +255,9 @@ export class VoiceChangerWorkletNode extends AudioWorkletNode {
|
||||
this.port.postMessage(req)
|
||||
}
|
||||
|
||||
startRecording = () => {
|
||||
start = () => {
|
||||
const req: VoiceChangerWorkletProcessorRequest = {
|
||||
requestType: "startRecording",
|
||||
requestType: "start",
|
||||
voice: new ArrayBuffer(1),
|
||||
numTrancateTreshold: 0,
|
||||
volTrancateThreshold: 0,
|
||||
@ -238,9 +266,9 @@ export class VoiceChangerWorkletNode extends AudioWorkletNode {
|
||||
this.port.postMessage(req)
|
||||
|
||||
}
|
||||
stopRecording = () => {
|
||||
stop = () => {
|
||||
const req: VoiceChangerWorkletProcessorRequest = {
|
||||
requestType: "stopRecording",
|
||||
requestType: "stop",
|
||||
voice: new ArrayBuffer(1),
|
||||
numTrancateTreshold: 0,
|
||||
volTrancateThreshold: 0,
|
||||
@ -248,6 +276,27 @@ export class VoiceChangerWorkletNode extends AudioWorkletNode {
|
||||
}
|
||||
this.port.postMessage(req)
|
||||
}
|
||||
|
||||
startOutputRecording = () => {
|
||||
this.recordingOutputChunk = []
|
||||
this.isOutputRecording = true
|
||||
}
|
||||
stopOutputRecording = () => {
|
||||
this.isOutputRecording = false
|
||||
|
||||
const dataSize = this.recordingOutputChunk.reduce((prev, cur) => {
|
||||
return prev + cur.length
|
||||
}, 0)
|
||||
const samples = new Float32Array(dataSize);
|
||||
let sampleIndex = 0
|
||||
for (let i = 0; i < this.recordingOutputChunk.length; i++) {
|
||||
for (let j = 0; j < this.recordingOutputChunk[i].length; j++) {
|
||||
samples[sampleIndex] = this.recordingOutputChunk[i][j];
|
||||
sampleIndex++;
|
||||
}
|
||||
}
|
||||
return samples
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -127,7 +127,7 @@ export type WorkletSetting = {
|
||||
volTrancateLength: number
|
||||
}
|
||||
export const DefaultWorkletSetting: WorkletSetting = {
|
||||
numTrancateTreshold: 188,
|
||||
numTrancateTreshold: 100,
|
||||
volTrancateThreshold: 0.0005,
|
||||
volTrancateLength: 32
|
||||
}
|
||||
|
@ -21,7 +21,6 @@ export type ClientState = {
|
||||
bufferingTime: number;
|
||||
responseTime: number;
|
||||
volume: number;
|
||||
outputRecordData: Float32Array[] | null; // Serverから帰ってきたデータをレコードしたもの
|
||||
|
||||
// 情報取得
|
||||
getInfo: () => Promise<void>
|
||||
@ -55,7 +54,6 @@ export const useClient = (props: UseClientProps): ClientState => {
|
||||
const [bufferingTime, setBufferingTime] = useState<number>(0)
|
||||
const [responseTime, setResponseTime] = useState<number>(0)
|
||||
const [volume, setVolume] = useState<number>(0)
|
||||
const [outputRecordData, setOutputRecordData] = useState<Float32Array[] | null>(null)
|
||||
|
||||
// (1-4) エラーステータス
|
||||
const errorCountRef = useRef<number>(0)
|
||||
@ -85,9 +83,6 @@ export const useClient = (props: UseClientProps): ClientState => {
|
||||
},
|
||||
notifyVolume: (vol: number) => {
|
||||
setVolume(vol)
|
||||
},
|
||||
notifyOutputRecordData: (data: Float32Array[]) => {
|
||||
setOutputRecordData(data)
|
||||
}
|
||||
})
|
||||
|
||||
@ -133,7 +128,6 @@ export const useClient = (props: UseClientProps): ClientState => {
|
||||
bufferingTime,
|
||||
responseTime,
|
||||
volume,
|
||||
outputRecordData,
|
||||
|
||||
// 情報取得
|
||||
getInfo,
|
||||
|
@ -65,8 +65,8 @@ export const useClientSetting = (props: UseClientSettingProps): ClientSettingSta
|
||||
return (_clientSetting: VoiceChangerClientSetting) => {
|
||||
if (!props.voiceChangerClient) return
|
||||
for (let k in _clientSetting) {
|
||||
const cur_v = clientSetting[k]
|
||||
const new_v = _clientSetting[k]
|
||||
const cur_v = clientSetting[k as keyof VoiceChangerClientSetting]
|
||||
const new_v = _clientSetting[k as keyof VoiceChangerClientSetting]
|
||||
if (cur_v != new_v) {
|
||||
storeSetting(_clientSetting)
|
||||
props.voiceChangerClient.updateClientSetting(_clientSetting)
|
||||
|
@ -90,9 +90,7 @@ export const useServerSetting = (props: UseServerSettingProps): ServerSettingSta
|
||||
const cur_v = serverSetting[k]
|
||||
const new_v = setting[k]
|
||||
if (cur_v != new_v) {
|
||||
console.log("update server setting!!!4", k, cur_v, new_v)
|
||||
const res = await props.voiceChangerClient.updateServerSettings(k, "" + new_v)
|
||||
console.log("update server setting!!!5", res)
|
||||
|
||||
setServerSetting(res)
|
||||
setItem(INDEXEDDB_KEY_SERVER, res)
|
||||
|
@ -12,6 +12,8 @@ export type WorkletNodeSettingState = {
|
||||
workletNodeSetting: WorkletNodeSetting;
|
||||
clearSetting: () => Promise<void>
|
||||
updateWorkletNodeSetting: (setting: WorkletNodeSetting) => void
|
||||
startOutputRecording: () => void
|
||||
stopOutputRecording: () => Promise<Float32Array>
|
||||
|
||||
}
|
||||
|
||||
@ -51,8 +53,8 @@ export const useWorkletNodeSetting = (props: UseWorkletNodeSettingProps): Workle
|
||||
return (_workletNodeSetting: WorkletNodeSetting) => {
|
||||
if (!props.voiceChangerClient) return
|
||||
for (let k in _workletNodeSetting) {
|
||||
const cur_v = workletNodeSetting[k]
|
||||
const new_v = _workletNodeSetting[k]
|
||||
const cur_v = workletNodeSetting[k as keyof WorkletNodeSetting]
|
||||
const new_v = _workletNodeSetting[k as keyof WorkletNodeSetting]
|
||||
if (cur_v != new_v) {
|
||||
_setWorkletNodeSetting(_workletNodeSetting)
|
||||
setItem(INDEXEDDB_KEY_WORKLETNODE, _workletNodeSetting)
|
||||
@ -63,11 +65,26 @@ export const useWorkletNodeSetting = (props: UseWorkletNodeSettingProps): Workle
|
||||
}
|
||||
}, [props.voiceChangerClient, workletNodeSetting])
|
||||
|
||||
const startOutputRecording = useMemo(() => {
|
||||
return () => {
|
||||
if (!props.voiceChangerClient) return
|
||||
props.voiceChangerClient.startOutputRecording()
|
||||
}
|
||||
}, [props.voiceChangerClient])
|
||||
|
||||
const stopOutputRecording = useMemo(() => {
|
||||
return async () => {
|
||||
if (!props.voiceChangerClient) return new Float32Array()
|
||||
return props.voiceChangerClient.stopOutputRecording()
|
||||
}
|
||||
}, [props.voiceChangerClient])
|
||||
|
||||
|
||||
return {
|
||||
workletNodeSetting,
|
||||
clearSetting,
|
||||
updateWorkletNodeSetting,
|
||||
|
||||
startOutputRecording,
|
||||
stopOutputRecording
|
||||
}
|
||||
}
|
@ -11,8 +11,7 @@ export type WorkletSettingState = {
|
||||
setting: WorkletSetting;
|
||||
clearSetting: () => Promise<void>
|
||||
setSetting: (setting: WorkletSetting) => void;
|
||||
// startOutputRecording: () => void
|
||||
// stopOutputRecording: () => Promise<void>
|
||||
|
||||
}
|
||||
|
||||
export const useWorkletSetting = (props: UseWorkletSettingProps): WorkletSettingState => {
|
||||
@ -34,7 +33,7 @@ export const useWorkletSetting = (props: UseWorkletSettingProps): WorkletSetting
|
||||
})
|
||||
} else {
|
||||
_setSetting({
|
||||
numTrancateTreshold: 150,
|
||||
numTrancateTreshold: 100,
|
||||
volTrancateThreshold: 0.0005,
|
||||
volTrancateLength: 32,
|
||||
})
|
||||
@ -68,26 +67,11 @@ export const useWorkletSetting = (props: UseWorkletSettingProps): WorkletSetting
|
||||
await removeItem(INDEXEDDB_KEY_WORKLET)
|
||||
}
|
||||
|
||||
// const startOutputRecording = useMemo(() => {
|
||||
// return () => {
|
||||
// if (!props.voiceChangerClient) return
|
||||
// props.voiceChangerClient.startOutputRecordingWorklet()
|
||||
// }
|
||||
// }, [props.voiceChangerClient])
|
||||
|
||||
// const stopOutputRecording = useMemo(() => {
|
||||
// return async () => {
|
||||
// if (!props.voiceChangerClient) return
|
||||
// props.voiceChangerClient.stopOutputRecordingWorklet()
|
||||
// }
|
||||
// }, [props.voiceChangerClient])
|
||||
|
||||
|
||||
return {
|
||||
setting,
|
||||
clearSetting,
|
||||
setSetting,
|
||||
// startOutputRecording,
|
||||
// stopOutputRecording
|
||||
|
||||
}
|
||||
}
|
@ -7,13 +7,13 @@
|
||||
/* ファイル名の大文字小文字を区別 */
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
|
||||
// /* 型チェック関係のオプション */
|
||||
// "strict": true,
|
||||
// "noImplicitAny": true,
|
||||
// "strictNullChecks": true,
|
||||
// "noUnusedLocals": true,
|
||||
// "noUnusedParameters": true,
|
||||
// "noImplicitReturns": true,
|
||||
/* 型チェック関係のオプション */
|
||||
"strict": true,
|
||||
"noImplicitAny": true,
|
||||
"strictNullChecks": true,
|
||||
"noUnusedLocals": true,
|
||||
"noUnusedParameters": true,
|
||||
"noImplicitReturns": true,
|
||||
|
||||
/* Module解決方法 */
|
||||
"moduleResolution": "node",
|
||||
|
@ -1,7 +1,7 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"target": "ES2020",
|
||||
"lib":["ES2020"],
|
||||
"lib": ["ES2020"],
|
||||
"outDir": "./worklet/dist",
|
||||
"declaration": true,
|
||||
/* ファイル名の大文字小文字を区別 */
|
||||
|
@ -5,6 +5,7 @@ module.exports = {
|
||||
resolve: {
|
||||
extensions: [".ts", ".js"],
|
||||
fallback: {
|
||||
// "buffer": false
|
||||
}
|
||||
},
|
||||
module: {
|
||||
@ -28,12 +29,6 @@ module.exports = {
|
||||
libraryTarget: "umd",
|
||||
globalObject: "typeof self !== 'undefined' ? self : this",
|
||||
},
|
||||
plugins: [
|
||||
new webpack.ProvidePlugin({
|
||||
Buffer: ["buffer", "Buffer"],
|
||||
process: "process/browser",
|
||||
}),
|
||||
],
|
||||
externals: {
|
||||
react: "react",
|
||||
"react-dom": "reactDOM",
|
||||
|
@ -1,8 +1,8 @@
|
||||
export const RequestType = {
|
||||
"voice": "voice",
|
||||
"config": "config",
|
||||
"startRecording": "startRecording",
|
||||
"stopRecording": "stopRecording"
|
||||
"start": "start",
|
||||
"stop": "stop"
|
||||
} as const
|
||||
export type RequestType = typeof RequestType[keyof typeof RequestType]
|
||||
|
||||
@ -17,7 +17,7 @@ export type ResponseType = typeof ResponseType[keyof typeof ResponseType]
|
||||
|
||||
export type VoiceChangerWorkletProcessorRequest = {
|
||||
requestType: RequestType,
|
||||
voice: ArrayBuffer,
|
||||
voice: Float32Array,
|
||||
numTrancateTreshold: number
|
||||
volTrancateThreshold: number
|
||||
volTrancateLength: number
|
||||
@ -67,14 +67,14 @@ class VoiceChangerWorkletProcessor extends AudioWorkletProcessor {
|
||||
this.volTrancateThreshold = request.volTrancateThreshold
|
||||
console.log("[worklet] worklet configured", request)
|
||||
return
|
||||
} else if (request.requestType === "startRecording") {
|
||||
} else if (request.requestType === "start") {
|
||||
if (this.isRecording) {
|
||||
console.warn("[worklet] recoring is already started")
|
||||
return
|
||||
}
|
||||
this.isRecording = true
|
||||
return
|
||||
} else if (request.requestType === "stopRecording") {
|
||||
} else if (request.requestType === "stop") {
|
||||
if (!this.isRecording) {
|
||||
console.warn("[worklet] recoring is not started")
|
||||
return
|
||||
@ -83,18 +83,6 @@ class VoiceChangerWorkletProcessor extends AudioWorkletProcessor {
|
||||
return
|
||||
}
|
||||
|
||||
const arrayBuffer = request.voice
|
||||
// データは(int16)で受信
|
||||
const i16Data = new Int16Array(arrayBuffer)
|
||||
const f32Data = new Float32Array(i16Data.length)
|
||||
// console.log(`[worklet] f32DataLength${f32Data.length} i16DataLength${i16Data.length}`)
|
||||
i16Data.forEach((x, i) => {
|
||||
const float = (x >= 0x8000) ? -(0x10000 - x) / 0x8000 : x / 0x7FFF;
|
||||
f32Data[i] = float
|
||||
})
|
||||
// console.log("[worklet] i16Data", i16Data)
|
||||
// console.log("[worklet] f32Data", f32Data)
|
||||
|
||||
if (this.playBuffer.length > this.numTrancateTreshold) {
|
||||
console.log("[worklet] Buffer truncated")
|
||||
while (this.playBuffer.length > 2) {
|
||||
@ -102,21 +90,11 @@ class VoiceChangerWorkletProcessor extends AudioWorkletProcessor {
|
||||
}
|
||||
}
|
||||
|
||||
// アップサンプリングしてPlayバッファに蓄積
|
||||
let f32Block: Float32Array
|
||||
for (let i = 0; i < f32Data.length; i++) {
|
||||
const frameIndexInBlock = (i * 2) % this.BLOCK_SIZE //
|
||||
if (frameIndexInBlock === 0) {
|
||||
f32Block = new Float32Array(this.BLOCK_SIZE)
|
||||
}
|
||||
|
||||
const currentFrame = f32Data[i]
|
||||
const nextFrame = i + 1 < f32Data.length ? f32Data[i + 1] : f32Data[i]
|
||||
f32Block![frameIndexInBlock] = currentFrame
|
||||
f32Block![frameIndexInBlock + 1] = (currentFrame + nextFrame) / 2
|
||||
if (f32Block!.length === frameIndexInBlock + 2) {
|
||||
this.playBuffer.push(f32Block!)
|
||||
}
|
||||
const f32Data = request.voice
|
||||
const chunkNum = f32Data.length / this.BLOCK_SIZE
|
||||
for (let i = 0; i < chunkNum; i++) {
|
||||
const block = f32Data.slice(i * this.BLOCK_SIZE, (i + 1) * this.BLOCK_SIZE)
|
||||
this.playBuffer.push(block)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -524,4 +524,8 @@ class VoiceChanger():
|
||||
if self.settings.recordIO == 1:
|
||||
self.stream_in.write(unpackedData.astype(np.int16).tobytes())
|
||||
self.stream_out.write(result.tobytes())
|
||||
|
||||
if self.settings.inputSampleRate != 24000:
|
||||
result = resampy.resample(result, 24000, 48000).astype(np.int16)
|
||||
|
||||
return result
|
||||
|
Loading…
x
Reference in New Issue
Block a user