This commit is contained in:
wataru 2023-02-21 04:07:43 +09:00
parent eeb940480e
commit 2cfc7b2887
14 changed files with 215 additions and 213 deletions

File diff suppressed because one or more lines are too long

View File

@ -9,7 +9,7 @@
"version": "1.0.0",
"license": "ISC",
"dependencies": {
"@dannadori/voice-changer-client-js": "^1.0.73",
"@dannadori/voice-changer-client-js": "^1.0.74",
"@fortawesome/fontawesome-svg-core": "^6.3.0",
"@fortawesome/free-brands-svg-icons": "^6.3.0",
"@fortawesome/free-regular-svg-icons": "^6.3.0",
@ -19,10 +19,10 @@
"react-dom": "^18.2.0"
},
"devDependencies": {
"@babel/plugin-transform-runtime": "^7.19.6",
"@babel/plugin-transform-runtime": "^7.21.0",
"@babel/preset-env": "^7.20.2",
"@babel/preset-react": "^7.18.6",
"@babel/preset-typescript": "^7.18.6",
"@babel/preset-typescript": "^7.21.0",
"@types/node": "^18.14.0",
"@types/react": "^18.0.28",
"@types/react-dom": "^18.0.11",
@ -1546,15 +1546,15 @@
}
},
"node_modules/@babel/helper-create-class-features-plugin": {
"version": "7.20.12",
"resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.20.12.tgz",
"integrity": "sha512-9OunRkbT0JQcednL0UFvbfXpAsUXiGjUk0a7sN8fUXX7Mue79cUSMjHGDRRi/Vz9vYlpIhLV5fMD5dKoMhhsNQ==",
"version": "7.21.0",
"resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.21.0.tgz",
"integrity": "sha512-Q8wNiMIdwsv5la5SPxNYzzkPnjgC0Sy0i7jLkVOCdllu/xcVNkr3TeZzbHBJrj+XXRqzX5uCyCoV9eu6xUG7KQ==",
"dev": true,
"dependencies": {
"@babel/helper-annotate-as-pure": "^7.18.6",
"@babel/helper-environment-visitor": "^7.18.9",
"@babel/helper-function-name": "^7.19.0",
"@babel/helper-member-expression-to-functions": "^7.20.7",
"@babel/helper-function-name": "^7.21.0",
"@babel/helper-member-expression-to-functions": "^7.21.0",
"@babel/helper-optimise-call-expression": "^7.18.6",
"@babel/helper-replace-supers": "^7.20.7",
"@babel/helper-skip-transparent-expression-wrappers": "^7.20.0",
@ -1622,13 +1622,13 @@
}
},
"node_modules/@babel/helper-function-name": {
"version": "7.19.0",
"resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.19.0.tgz",
"integrity": "sha512-WAwHBINyrpqywkUH0nTnNgI5ina5TFn85HKS0pbPDfxFfhyR/aNQEn4hGi1P1JyT//I0t4OgXUlofzWILRvS5w==",
"version": "7.21.0",
"resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.21.0.tgz",
"integrity": "sha512-HfK1aMRanKHpxemaY2gqBmL04iAPOPRj7DxtNbiDOrJK+gdwkiNRVpCpUJYbUT+aZyemKN8brqTOxzCaG6ExRg==",
"dev": true,
"dependencies": {
"@babel/template": "^7.18.10",
"@babel/types": "^7.19.0"
"@babel/template": "^7.20.7",
"@babel/types": "^7.21.0"
},
"engines": {
"node": ">=6.9.0"
@ -1647,12 +1647,12 @@
}
},
"node_modules/@babel/helper-member-expression-to-functions": {
"version": "7.20.7",
"resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.20.7.tgz",
"integrity": "sha512-9J0CxJLq315fEdi4s7xK5TQaNYjZw+nDVpVqr1axNGKzdrdwYBD5b4uKv3n75aABG0rCCTK8Im8Ww7eYfMrZgw==",
"version": "7.21.0",
"resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.21.0.tgz",
"integrity": "sha512-Muu8cdZwNN6mRRNG6lAYErJ5X3bRevgYR2O8wN0yn7jJSnGDu6eG59RfT29JHxGUovyfrh6Pj0XzmR7drNVL3Q==",
"dev": true,
"dependencies": {
"@babel/types": "^7.20.7"
"@babel/types": "^7.21.0"
},
"engines": {
"node": ">=6.9.0"
@ -1800,9 +1800,9 @@
}
},
"node_modules/@babel/helper-validator-option": {
"version": "7.18.6",
"resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.18.6.tgz",
"integrity": "sha512-XO7gESt5ouv/LRJdrVjkShckw6STTaB7l9BrpBaAHDeF5YZT+01PCwmR0SJHnkW6i8OwW/EVWRShfi4j2x+KQw==",
"version": "7.21.0",
"resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.21.0.tgz",
"integrity": "sha512-rmL/B8/f0mKS2baE9ZpyTcTavvEuWhTTW8amjzXNvYG4AwBsqTLikfXsEofsJEfKHf+HQVQbFOHy6o+4cnC/fQ==",
"dev": true,
"engines": {
"node": ">=6.9.0"
@ -2833,13 +2833,13 @@
}
},
"node_modules/@babel/plugin-transform-runtime": {
"version": "7.19.6",
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.19.6.tgz",
"integrity": "sha512-PRH37lz4JU156lYFW1p8OxE5i7d6Sl/zV58ooyr+q1J1lnQPyg5tIiXlIwNVhJaY4W3TmOtdc8jqdXQcB1v5Yw==",
"version": "7.21.0",
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.21.0.tgz",
"integrity": "sha512-ReY6pxwSzEU0b3r2/T/VhqMKg/AkceBT19X0UptA3/tYi5Pe2eXgEUH+NNMC5nok6c6XQz5tyVTUpuezRfSMSg==",
"dev": true,
"dependencies": {
"@babel/helper-module-imports": "^7.18.6",
"@babel/helper-plugin-utils": "^7.19.0",
"@babel/helper-plugin-utils": "^7.20.2",
"babel-plugin-polyfill-corejs2": "^0.3.3",
"babel-plugin-polyfill-corejs3": "^0.6.0",
"babel-plugin-polyfill-regenerator": "^0.4.1",
@ -2929,12 +2929,12 @@
}
},
"node_modules/@babel/plugin-transform-typescript": {
"version": "7.20.13",
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.20.13.tgz",
"integrity": "sha512-O7I/THxarGcDZxkgWKMUrk7NK1/WbHAg3Xx86gqS6x9MTrNL6AwIluuZ96ms4xeDe6AVx6rjHbWHP7x26EPQBA==",
"version": "7.21.0",
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.21.0.tgz",
"integrity": "sha512-xo///XTPp3mDzTtrqXoBlK9eiAYW3wv9JXglcn/u1bi60RW11dEUxIgA8cbnDhutS1zacjMRmAwxE0gMklLnZg==",
"dev": true,
"dependencies": {
"@babel/helper-create-class-features-plugin": "^7.20.12",
"@babel/helper-create-class-features-plugin": "^7.21.0",
"@babel/helper-plugin-utils": "^7.20.2",
"@babel/plugin-syntax-typescript": "^7.20.0"
},
@ -3102,14 +3102,14 @@
}
},
"node_modules/@babel/preset-typescript": {
"version": "7.18.6",
"resolved": "https://registry.npmjs.org/@babel/preset-typescript/-/preset-typescript-7.18.6.tgz",
"integrity": "sha512-s9ik86kXBAnD760aybBucdpnLsAt0jK1xqJn2juOn9lkOvSHV60os5hxoVJsPzMQxvnUJFAlkont2DvvaYEBtQ==",
"version": "7.21.0",
"resolved": "https://registry.npmjs.org/@babel/preset-typescript/-/preset-typescript-7.21.0.tgz",
"integrity": "sha512-myc9mpoVA5m1rF8K8DgLEatOYFDpwC+RkMkjZ0Du6uI62YvDe8uxIEYVs/VCdSJ097nlALiU/yBC7//3nI+hNg==",
"dev": true,
"dependencies": {
"@babel/helper-plugin-utils": "^7.18.6",
"@babel/helper-validator-option": "^7.18.6",
"@babel/plugin-transform-typescript": "^7.18.6"
"@babel/helper-plugin-utils": "^7.20.2",
"@babel/helper-validator-option": "^7.21.0",
"@babel/plugin-transform-typescript": "^7.21.0"
},
"engines": {
"node": ">=6.9.0"
@ -3172,9 +3172,9 @@
}
},
"node_modules/@babel/types": {
"version": "7.20.7",
"resolved": "https://registry.npmjs.org/@babel/types/-/types-7.20.7.tgz",
"integrity": "sha512-69OnhBxSSgK0OzTJai4kyPDiKTIe3j+ctaHdIGVbRahTLAT7L3R9oeXHC2aVSuGYt3cVnoAMDmOCgJ2yaiLMvg==",
"version": "7.21.0",
"resolved": "https://registry.npmjs.org/@babel/types/-/types-7.21.0.tgz",
"integrity": "sha512-uR7NWq2VNFnDi7EYqiRz2Jv/VQIu38tu64Zy8TX2nQFQ6etJ9V/Rr2msW8BS132mum2rL645qpDrLtAJtVpuow==",
"dev": true,
"dependencies": {
"@babel/helper-string-parser": "^7.19.4",
@ -3186,9 +3186,9 @@
}
},
"node_modules/@dannadori/voice-changer-client-js": {
"version": "1.0.73",
"resolved": "https://registry.npmjs.org/@dannadori/voice-changer-client-js/-/voice-changer-client-js-1.0.73.tgz",
"integrity": "sha512-9vzlxy+Q5Rw52ra5taaU1ioNY7QpZsPiG0iiUsD1DkQ0FbtJsiKmoH+8QQKMzfxeK5efhNFCNn2flPHMLmsTmw==",
"version": "1.0.74",
"resolved": "https://registry.npmjs.org/@dannadori/voice-changer-client-js/-/voice-changer-client-js-1.0.74.tgz",
"integrity": "sha512-/pqBNJTsisYBT2Nh1/SsVsS8Zjm/b+o59DHLpqjZlXohMaCCJ4BBroJxn8GXrtR84nkxvIehvWH1stiuAhnd6A==",
"dependencies": {
"@types/readable-stream": "^2.3.15",
"amazon-chime-sdk-js": "^3.11.0",
@ -12347,15 +12347,15 @@
}
},
"@babel/helper-create-class-features-plugin": {
"version": "7.20.12",
"resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.20.12.tgz",
"integrity": "sha512-9OunRkbT0JQcednL0UFvbfXpAsUXiGjUk0a7sN8fUXX7Mue79cUSMjHGDRRi/Vz9vYlpIhLV5fMD5dKoMhhsNQ==",
"version": "7.21.0",
"resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.21.0.tgz",
"integrity": "sha512-Q8wNiMIdwsv5la5SPxNYzzkPnjgC0Sy0i7jLkVOCdllu/xcVNkr3TeZzbHBJrj+XXRqzX5uCyCoV9eu6xUG7KQ==",
"dev": true,
"requires": {
"@babel/helper-annotate-as-pure": "^7.18.6",
"@babel/helper-environment-visitor": "^7.18.9",
"@babel/helper-function-name": "^7.19.0",
"@babel/helper-member-expression-to-functions": "^7.20.7",
"@babel/helper-function-name": "^7.21.0",
"@babel/helper-member-expression-to-functions": "^7.21.0",
"@babel/helper-optimise-call-expression": "^7.18.6",
"@babel/helper-replace-supers": "^7.20.7",
"@babel/helper-skip-transparent-expression-wrappers": "^7.20.0",
@ -12402,13 +12402,13 @@
}
},
"@babel/helper-function-name": {
"version": "7.19.0",
"resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.19.0.tgz",
"integrity": "sha512-WAwHBINyrpqywkUH0nTnNgI5ina5TFn85HKS0pbPDfxFfhyR/aNQEn4hGi1P1JyT//I0t4OgXUlofzWILRvS5w==",
"version": "7.21.0",
"resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.21.0.tgz",
"integrity": "sha512-HfK1aMRanKHpxemaY2gqBmL04iAPOPRj7DxtNbiDOrJK+gdwkiNRVpCpUJYbUT+aZyemKN8brqTOxzCaG6ExRg==",
"dev": true,
"requires": {
"@babel/template": "^7.18.10",
"@babel/types": "^7.19.0"
"@babel/template": "^7.20.7",
"@babel/types": "^7.21.0"
}
},
"@babel/helper-hoist-variables": {
@ -12421,12 +12421,12 @@
}
},
"@babel/helper-member-expression-to-functions": {
"version": "7.20.7",
"resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.20.7.tgz",
"integrity": "sha512-9J0CxJLq315fEdi4s7xK5TQaNYjZw+nDVpVqr1axNGKzdrdwYBD5b4uKv3n75aABG0rCCTK8Im8Ww7eYfMrZgw==",
"version": "7.21.0",
"resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.21.0.tgz",
"integrity": "sha512-Muu8cdZwNN6mRRNG6lAYErJ5X3bRevgYR2O8wN0yn7jJSnGDu6eG59RfT29JHxGUovyfrh6Pj0XzmR7drNVL3Q==",
"dev": true,
"requires": {
"@babel/types": "^7.20.7"
"@babel/types": "^7.21.0"
}
},
"@babel/helper-module-imports": {
@ -12535,9 +12535,9 @@
"dev": true
},
"@babel/helper-validator-option": {
"version": "7.18.6",
"resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.18.6.tgz",
"integrity": "sha512-XO7gESt5ouv/LRJdrVjkShckw6STTaB7l9BrpBaAHDeF5YZT+01PCwmR0SJHnkW6i8OwW/EVWRShfi4j2x+KQw==",
"version": "7.21.0",
"resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.21.0.tgz",
"integrity": "sha512-rmL/B8/f0mKS2baE9ZpyTcTavvEuWhTTW8amjzXNvYG4AwBsqTLikfXsEofsJEfKHf+HQVQbFOHy6o+4cnC/fQ==",
"dev": true
},
"@babel/helper-wrap-function": {
@ -13205,13 +13205,13 @@
}
},
"@babel/plugin-transform-runtime": {
"version": "7.19.6",
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.19.6.tgz",
"integrity": "sha512-PRH37lz4JU156lYFW1p8OxE5i7d6Sl/zV58ooyr+q1J1lnQPyg5tIiXlIwNVhJaY4W3TmOtdc8jqdXQcB1v5Yw==",
"version": "7.21.0",
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.21.0.tgz",
"integrity": "sha512-ReY6pxwSzEU0b3r2/T/VhqMKg/AkceBT19X0UptA3/tYi5Pe2eXgEUH+NNMC5nok6c6XQz5tyVTUpuezRfSMSg==",
"dev": true,
"requires": {
"@babel/helper-module-imports": "^7.18.6",
"@babel/helper-plugin-utils": "^7.19.0",
"@babel/helper-plugin-utils": "^7.20.2",
"babel-plugin-polyfill-corejs2": "^0.3.3",
"babel-plugin-polyfill-corejs3": "^0.6.0",
"babel-plugin-polyfill-regenerator": "^0.4.1",
@ -13265,12 +13265,12 @@
}
},
"@babel/plugin-transform-typescript": {
"version": "7.20.13",
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.20.13.tgz",
"integrity": "sha512-O7I/THxarGcDZxkgWKMUrk7NK1/WbHAg3Xx86gqS6x9MTrNL6AwIluuZ96ms4xeDe6AVx6rjHbWHP7x26EPQBA==",
"version": "7.21.0",
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.21.0.tgz",
"integrity": "sha512-xo///XTPp3mDzTtrqXoBlK9eiAYW3wv9JXglcn/u1bi60RW11dEUxIgA8cbnDhutS1zacjMRmAwxE0gMklLnZg==",
"dev": true,
"requires": {
"@babel/helper-create-class-features-plugin": "^7.20.12",
"@babel/helper-create-class-features-plugin": "^7.21.0",
"@babel/helper-plugin-utils": "^7.20.2",
"@babel/plugin-syntax-typescript": "^7.20.0"
}
@ -13405,14 +13405,14 @@
}
},
"@babel/preset-typescript": {
"version": "7.18.6",
"resolved": "https://registry.npmjs.org/@babel/preset-typescript/-/preset-typescript-7.18.6.tgz",
"integrity": "sha512-s9ik86kXBAnD760aybBucdpnLsAt0jK1xqJn2juOn9lkOvSHV60os5hxoVJsPzMQxvnUJFAlkont2DvvaYEBtQ==",
"version": "7.21.0",
"resolved": "https://registry.npmjs.org/@babel/preset-typescript/-/preset-typescript-7.21.0.tgz",
"integrity": "sha512-myc9mpoVA5m1rF8K8DgLEatOYFDpwC+RkMkjZ0Du6uI62YvDe8uxIEYVs/VCdSJ097nlALiU/yBC7//3nI+hNg==",
"dev": true,
"requires": {
"@babel/helper-plugin-utils": "^7.18.6",
"@babel/helper-validator-option": "^7.18.6",
"@babel/plugin-transform-typescript": "^7.18.6"
"@babel/helper-plugin-utils": "^7.20.2",
"@babel/helper-validator-option": "^7.21.0",
"@babel/plugin-transform-typescript": "^7.21.0"
}
},
"@babel/regjsgen": {
@ -13460,9 +13460,9 @@
}
},
"@babel/types": {
"version": "7.20.7",
"resolved": "https://registry.npmjs.org/@babel/types/-/types-7.20.7.tgz",
"integrity": "sha512-69OnhBxSSgK0OzTJai4kyPDiKTIe3j+ctaHdIGVbRahTLAT7L3R9oeXHC2aVSuGYt3cVnoAMDmOCgJ2yaiLMvg==",
"version": "7.21.0",
"resolved": "https://registry.npmjs.org/@babel/types/-/types-7.21.0.tgz",
"integrity": "sha512-uR7NWq2VNFnDi7EYqiRz2Jv/VQIu38tu64Zy8TX2nQFQ6etJ9V/Rr2msW8BS132mum2rL645qpDrLtAJtVpuow==",
"dev": true,
"requires": {
"@babel/helper-string-parser": "^7.19.4",
@ -13471,9 +13471,9 @@
}
},
"@dannadori/voice-changer-client-js": {
"version": "1.0.73",
"resolved": "https://registry.npmjs.org/@dannadori/voice-changer-client-js/-/voice-changer-client-js-1.0.73.tgz",
"integrity": "sha512-9vzlxy+Q5Rw52ra5taaU1ioNY7QpZsPiG0iiUsD1DkQ0FbtJsiKmoH+8QQKMzfxeK5efhNFCNn2flPHMLmsTmw==",
"version": "1.0.74",
"resolved": "https://registry.npmjs.org/@dannadori/voice-changer-client-js/-/voice-changer-client-js-1.0.74.tgz",
"integrity": "sha512-/pqBNJTsisYBT2Nh1/SsVsS8Zjm/b+o59DHLpqjZlXohMaCCJ4BBroJxn8GXrtR84nkxvIehvWH1stiuAhnd6A==",
"requires": {
"@types/readable-stream": "^2.3.15",
"amazon-chime-sdk-js": "^3.11.0",

View File

@ -19,10 +19,10 @@
"author": "wataru.okada@flect.co.jp",
"license": "ISC",
"devDependencies": {
"@babel/plugin-transform-runtime": "^7.19.6",
"@babel/plugin-transform-runtime": "^7.21.0",
"@babel/preset-env": "^7.20.2",
"@babel/preset-react": "^7.18.6",
"@babel/preset-typescript": "^7.18.6",
"@babel/preset-typescript": "^7.21.0",
"@types/node": "^18.14.0",
"@types/react": "^18.0.28",
"@types/react-dom": "^18.0.11",
@ -51,7 +51,7 @@
"webpack-dev-server": "^4.11.1"
},
"dependencies": {
"@dannadori/voice-changer-client-js": "^1.0.73",
"@dannadori/voice-changer-client-js": "^1.0.74",
"@fortawesome/fontawesome-svg-core": "^6.3.0",
"@fortawesome/free-brands-svg-icons": "^6.3.0",
"@fortawesome/free-regular-svg-icons": "^6.3.0",

View File

@ -5,6 +5,7 @@ import { AnimationTypes, HeaderButton, HeaderButtonProps } from "./components/10
export const useServerControl = () => {
const appState = useAppState()
const [startWithAudioContextCreate, setStartWithAudioContextCreate] = useState<boolean>(false)
const [showPerformanceDetail, setShowPerformanceDetail] = useState<boolean>(false)
const accodionButton = useMemo(() => {
const accodionButtonProps: HeaderButtonProps = {
@ -62,6 +63,8 @@ export const useServerControl = () => {
}, [appState.frontendManagerState.isConverting, appState.clientSetting.start, appState.clientSetting.stop])
const performanceRow = useMemo(() => {
const performanceDetailLabel = showPerformanceDetail ? "[pre, main, post] <<" : "more >>"
const performanceData = showPerformanceDetail ? `[${appState.performance.preprocessTime}, ${appState.performance.mainprocessTime},${appState.performance.postprocessTime}]` : ""
return (
<>
<div className="body-row split-3-1-1-1-4 left-padding-1 guided">
@ -69,20 +72,20 @@ export const useServerControl = () => {
<div className="body-item-text">vol<span className="body-item-text-small">(rms)</span></div>
<div className="body-item-text">buf<span className="body-item-text-small">(ms)</span></div>
<div className="body-item-text">res<span className="body-item-text-small">(ms)</span></div>
<div className="body-item-text"></div>
<div className="body-item-text">
<span onClick={() => { setShowPerformanceDetail(!showPerformanceDetail) }} >{performanceDetailLabel}</span>
</div>
</div>
<div className="body-row split-3-1-1-1-4 left-padding-1 guided">
<div className="body-item-title left-padding-1"></div>
<div className="body-item-text">{appState.volume.toFixed(4)}</div>
<div className="body-item-text">{appState.bufferingTime}</div>
<div className="body-item-text">{appState.responseTime}</div>
<div className="body-item-text"></div>
<div className="body-item-text">{appState.performance.responseTime}</div>
<div className="body-item-text">{performanceData}</div>
</div>
</>
)
}, [appState.volume, appState.bufferingTime, appState.responseTime])
}, [appState.volume, appState.bufferingTime, appState.performance, showPerformanceDetail])
const infoRow = useMemo(() => {
const onReloadClicked = async () => {

View File

@ -382,74 +382,8 @@ export const useDeviceSetting = (): DeviceSettingState => {
a.click();
document.body.removeChild(a);
URL.revokeObjectURL(url);
}
// 出力の録音データ(from worklet)がストアされたら実行
useEffect(() => {
if (!appState.outputRecordData || appState.outputRecordData?.length == 0) {
return
}
const f32Datas = appState.outputRecordData
const sampleSize = f32Datas.reduce((prev, cur) => {
return prev + cur.length
}, 0)
const samples = new Float32Array(sampleSize);
let sampleIndex = 0
for (let i = 0; i < f32Datas.length; i++) {
for (let j = 0; j < f32Datas[i].length; j++) {
samples[sampleIndex] = f32Datas[i][j];
sampleIndex++;
}
}
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 + samples.length * 2);
const view = new DataView(buffer);
// https://www.youfit.co.jp/archives/1418
writeString(view, 0, 'RIFF'); // RIFFヘッダ
view.setUint32(4, 32 + samples.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, samples.length * 2, true); // 波形データのバイト数
floatTo16BitPCM(view, 44, samples); // 波形データ
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);
}, [appState.outputRecordData])
return {
deviceSetting,
}

View File

@ -1,12 +1,12 @@
{
"name": "@dannadori/voice-changer-client-js",
"version": "1.0.73",
"version": "1.0.75",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "@dannadori/voice-changer-client-js",
"version": "1.0.73",
"version": "1.0.75",
"license": "ISC",
"dependencies": {
"@types/readable-stream": "^2.3.15",

View File

@ -1,6 +1,6 @@
{
"name": "@dannadori/voice-changer-client-js",
"version": "1.0.73",
"version": "1.0.75",
"description": "",
"main": "dist/index.js",
"directories": {

View File

@ -6,7 +6,7 @@ import { DefaultEventsMap } from "@socket.io/component-emitter";
export type VoiceChangerWorkletListener = {
notifyVolume: (vol: number) => void
notifySendBufferingTime: (time: number) => void
notifyResponseTime: (time: number) => void
notifyResponseTime: (time: number, perf?: number[]) => void
notifyException: (code: VOICE_CHANGER_CLIENT_EXCEPTION, message: string) => void
}
@ -69,11 +69,12 @@ export class VoiceChangerWorkletNode extends AudioWorkletNode {
const cur = Date.now()
const responseTime = cur - response[0]
const result = response[1] as ArrayBuffer
const perf = response[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}`)
} else {
this.postReceivedVoice(response[1])
this.listener.notifyResponseTime(responseTime)
this.listener.notifyResponseTime(responseTime, perf)
}
});
}

View File

@ -96,9 +96,9 @@ export const DefaultServerSetting: ServerInfo = {
dstId: 101,
gpu: 0,
crossFadeOffsetRate: 0.1,
crossFadeEndRate: 0.9,
crossFadeOverlapSize: CrossFadeOverlapSize[4096],
crossFadeOffsetRate: 0.0,
crossFadeEndRate: 1.0,
crossFadeOverlapSize: CrossFadeOverlapSize[1024],
framework: Framework.PyTorch,
f0Factor: 1.0,
@ -106,7 +106,7 @@ export const DefaultServerSetting: ServerInfo = {
f0Detector: F0Detector.dio,
recordIO: 0,
inputSampleRate: 48000,
inputSampleRate: 24000,
//
status: "ok",
@ -163,7 +163,7 @@ export type WorkletNodeSetting = {
export const DefaultWorkletNodeSetting: WorkletNodeSetting = {
serverUrl: "",
protocol: "sio",
sendingSampleRate: 48000,
sendingSampleRate: 24000,
inputChunkNum: 48,
downSamplingMode: "average"
}

View File

@ -19,8 +19,8 @@ export type ClientState = {
// モニタリングデータ
bufferingTime: number;
responseTime: number;
volume: number;
performance: PerformanceData
// 情報取得
getInfo: () => Promise<void>
@ -28,7 +28,18 @@ export type ClientState = {
clearSetting: () => Promise<void>
}
export type PerformanceData = {
responseTime: number
preprocessTime: number
mainprocessTime: number
postprocessTime: number
}
const InitialPerformanceData: PerformanceData = {
responseTime: 0,
preprocessTime: 0,
mainprocessTime: 0,
postprocessTime: 0
}
export const useClient = (props: UseClientProps): ClientState => {
@ -52,7 +63,7 @@ export const useClient = (props: UseClientProps): ClientState => {
// (1-3) モニタリングデータ
const [bufferingTime, setBufferingTime] = useState<number>(0)
const [responseTime, setResponseTime] = useState<number>(0)
const [performance, setPerformance] = useState<PerformanceData>(InitialPerformanceData)
const [volume, setVolume] = useState<number>(0)
// (1-4) エラーステータス
@ -68,8 +79,12 @@ export const useClient = (props: UseClientProps): ClientState => {
notifySendBufferingTime: (val: number) => {
setBufferingTime(val)
},
notifyResponseTime: (val: number) => {
setResponseTime(val)
notifyResponseTime: (val: number, perf?: number[]) => {
const responseTime = val
const preprocessTime = perf ? Math.ceil(perf[0] * 1000) : 0
const mainprocessTime = perf ? Math.ceil(perf[1] * 1000) : 0
const postprocessTime = perf ? Math.ceil(perf[2] * 1000) : 0
setPerformance({ responseTime, preprocessTime, mainprocessTime, postprocessTime })
},
notifyException: (mes: string) => {
if (mes.length > 0) {
@ -126,8 +141,8 @@ export const useClient = (props: UseClientProps): ClientState => {
// モニタリングデータ
bufferingTime,
responseTime,
volume,
performance,
// 情報取得
getInfo,

View File

@ -89,8 +89,9 @@ class MyCustomNamespace(socketio.ClientNamespace):
timestamp = msg[0]
responseTime = time.time() * 1000 - timestamp
data = msg[1]
print(f"RT:{responseTime}msec")
unpackedData = struct.unpack('<%sh' % (len(data) // struct.calcsize('<h')), data)
perf = msg[2]
print(f"RT:{responseTime}msec", perf)
# unpackedData = struct.unpack('<%sh' % (len(data) // struct.calcsize('<h')), data)
if self.file_output_stream != None:
self.file_output_stream.write(data)

View File

@ -4,12 +4,29 @@ import numpy as np
import socketio
from voice_changer.VoiceChangerManager import VoiceChangerManager
import time
import multiprocessing as mp
# Queueからデータを読み取り
def read(q_in, q_out):
while True:
time.sleep(1)
[timestamp, sid] = q_in.get(True)
print("put........................................")
q_out.put([timestamp, sid])
class MMVC_Namespace(socketio.AsyncNamespace):
def __init__(self, namespace: str, voiceChangerManager: VoiceChangerManager):
super().__init__(namespace)
self.voiceChangerManager = voiceChangerManager
self.q_in = mp.Queue()
self.q_out = mp.Queue()
self.p = mp.Process(target=read, args=(self.q_in, self.q_out))
self.p.start()
@classmethod
def get_instance(cls, voiceChangerManager: VoiceChangerManager):
if not hasattr(cls, "_instance"):
@ -28,10 +45,23 @@ class MMVC_Namespace(socketio.AsyncNamespace):
print(data)
await self.emit('response', [timestamp, 0], to=sid)
else:
# print("receive ")
# self.q_in.put([timestamp, sid])
# while self.q_out.empty() == False:
# print("send........................................")
# [timestamp, sid] = self.q_out.get(True)
# await self.emit('response', [timestamp, 0], to=sid)
# print("end")
# print("receive ")
# time.sleep(2)
# await self.emit('response', [timestamp, 0], to=sid)
# print("end")
unpackedData = np.array(struct.unpack('<%sh' % (len(data) // struct.calcsize('<h')), data))
audio1 = self.voiceChangerManager.changeVoice(unpackedData)
audio1, perf = self.voiceChangerManager.changeVoice(unpackedData)
bin = struct.pack('<%sh' % len(audio1), *audio1)
await self.emit('response', [timestamp, bin], to=sid)
await self.emit('response', [timestamp, bin, perf], to=sid)
def on_disconnect(self, sid):
# print('[{}] disconnect'.format(datetime.now().strftime('%Y-%m-%d %H:%M:%S')))

View File

@ -12,11 +12,10 @@ from symbols import symbols
from models import SynthesizerTrn
import pyworld as pw
# from voice_changer.TrainerFunctions import TextAudioSpeakerCollate, spectrogram_torch, load_checkpoint, get_hparams_from_file
from voice_changer.client_modules import convert_continuos_f0, spectrogram_torch, TextAudioSpeakerCollate, get_hparams_from_file, load_checkpoint
import time
import multiprocessing as mp
providers = ['OpenVINOExecutionProvider', "CUDAExecutionProvider", "DmlExecutionProvider", "CPUExecutionProvider"]
@ -30,10 +29,6 @@ import librosa
import librosa.display
SAMPLING_RATE = 24000
import pyaudio
import json
from multiprocessing import Process, Queue
class MockStream:
"""
@ -366,7 +361,7 @@ class VoiceChanger():
f0_factor=self.settings.f0Factor
)([(spec, sid, f0)])
return data, f0.numpy()
return data
def _onnx_inference(self, data, inputSize):
if hasattr(self, "onnx_session") == False or self.onnx_session == None:
@ -489,41 +484,64 @@ class VoiceChanger():
return result
def on_request(self, unpackedData: any):
if self.settings.inputSampleRate != 24000:
# print("convert sampling rate!", self.settings.inputSampleRate)
unpackedData = resampy.resample(unpackedData, 48000, 24000)
convertSize = unpackedData.shape[0] + min(self.settings.crossFadeOverlapSize, unpackedData.shape[0])
# print(convertSize, unpackedData.shape[0])
if convertSize < 8192:
convertSize = 8192
with Timer("pre-process") as t:
if self.settings.inputSampleRate != 24000:
# print("convert sampling rate!", self.settings.inputSampleRate)
unpackedData = resampy.resample(unpackedData, 48000, 24000)
convertSize = unpackedData.shape[0] + min(self.settings.crossFadeOverlapSize, unpackedData.shape[0])
# print(convertSize, unpackedData.shape[0])
if convertSize < 8192:
convertSize = 8192
if convertSize % 128 != 0: # モデルの出力のホップサイズで切り捨てが発生するので補う。
convertSize = convertSize + (128 - (convertSize % 128))
self._generate_strength(unpackedData)
data = self._generate_input(unpackedData, convertSize)
preprocess_time = t.secs
self._generate_strength(unpackedData)
# f0はデバッグ用
data, f0 = self._generate_input(unpackedData, convertSize)
with Timer("main-process") as t:
try:
if self.settings.framework == "ONNX":
result = self._onnx_inference(data, unpackedData.shape[0])
else:
result = self._pyTorch_inference(data, unpackedData.shape[0])
try:
if self.settings.framework == "ONNX":
result = self._onnx_inference(data, unpackedData.shape[0])
else:
result = self._pyTorch_inference(data, unpackedData.shape[0])
except Exception as e:
print("VC PROCESSING!!!! EXCEPTION!!!", e)
print(traceback.format_exc())
if hasattr(self, "np_prev_audio1"):
del self.np_prev_audio1
if hasattr(self, "prev_audio1"):
del self.prev_audio1
return np.zeros(1).astype(np.int16)
mainprocess_time = t.secs
except Exception as e:
print("VC PROCESSING!!!! EXCEPTION!!!", e)
print(traceback.format_exc())
if hasattr(self, "np_prev_audio1"):
del self.np_prev_audio1
if hasattr(self, "prev_audio1"):
del self.prev_audio1
return np.zeros(1).astype(np.int16)
with Timer("post-process") as t:
result = result.astype(np.int16)
# print("on_request result size:",result.shape)
if self.settings.recordIO == 1:
self.stream_in.write(unpackedData.astype(np.int16).tobytes())
self.stream_out.write(result.tobytes())
result = result.astype(np.int16)
# print("on_request result size:",result.shape)
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)
if self.settings.inputSampleRate != 24000:
result = resampy.resample(result, 24000, 48000).astype(np.int16)
postprocess_time = t.secs
return result
perf = [preprocess_time, mainprocess_time, postprocess_time]
return result, perf
##############
class Timer(object):
def __init__(self, title: str):
self.title = title
def __enter__(self):
self.start = time.time()
return self
def __exit__(self, *args):
self.end = time.time()
self.secs = self.end - self.start
self.msecs = self.secs * 1000 # millisecs

View File

@ -36,4 +36,4 @@ class VoiceChangerManager():
return self.voiceChanger.on_request(unpackedData)
else:
print("Voice Change is not loaded. Did you load a correct model?")
return np.zeros(1).astype(np.int16)
return np.zeros(1).astype(np.int16), []