WIP:VC select

This commit is contained in:
wataru 2023-04-11 03:07:14 +09:00
parent 4cc02540ea
commit b57ddc180c
19 changed files with 544 additions and 1756 deletions

View File

@ -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>

File diff suppressed because one or more lines are too long

31
client/demo/dist/index.js.LICENSE.txt vendored Normal file
View 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.
*/

View File

@ -9,7 +9,7 @@
"version": "1.0.0",
"license": "ISC",
"dependencies": {
"@dannadori/voice-changer-client-js": "^1.0.103",
"@dannadori/voice-changer-client-js": "^1.0.105",
"@fortawesome/fontawesome-svg-core": "^6.4.0",
"@fortawesome/free-brands-svg-icons": "^6.4.0",
"@fortawesome/free-regular-svg-icons": "^6.4.0",
@ -24,13 +24,13 @@
"@babel/preset-react": "^7.18.6",
"@babel/preset-typescript": "^7.21.4",
"@types/node": "^18.15.11",
"@types/react": "^18.0.33",
"@types/react": "^18.0.34",
"@types/react-dom": "^18.0.11",
"autoprefixer": "^10.4.14",
"babel-loader": "^9.1.2",
"copy-webpack-plugin": "^11.0.0",
"css-loader": "^6.7.3",
"eslint": "^8.37.0",
"eslint": "^8.38.0",
"eslint-config-prettier": "^8.8.0",
"eslint-plugin-prettier": "^4.2.1",
"eslint-plugin-react": "^7.32.2",
@ -41,11 +41,11 @@
"postcss-loader": "^7.2.4",
"postcss-nested": "^6.0.1",
"prettier": "^2.8.7",
"rimraf": "^4.4.1",
"rimraf": "^5.0.0",
"style-loader": "^3.3.2",
"ts-loader": "^9.4.2",
"tsconfig-paths": "^4.2.0",
"typescript": "^5.0.3",
"typescript": "^5.0.4",
"webpack": "^5.78.0",
"webpack-cli": "^5.0.1",
"webpack-dev-server": "^4.13.2"
@ -3097,9 +3097,9 @@
}
},
"node_modules/@dannadori/voice-changer-client-js": {
"version": "1.0.103",
"resolved": "https://registry.npmjs.org/@dannadori/voice-changer-client-js/-/voice-changer-client-js-1.0.103.tgz",
"integrity": "sha512-6kW0AshtTI4CtTlpQYaFa2IX0AlR8zqwBzaaat4PFw7bsV/EKAz2vPLTi3Y9AdzHiv14t6uWH6cwjtp0xl4F1w==",
"version": "1.0.105",
"resolved": "https://registry.npmjs.org/@dannadori/voice-changer-client-js/-/voice-changer-client-js-1.0.105.tgz",
"integrity": "sha512-wfOkRPUy2/Jqez+O/8gO98dSoNHlz/Br0ZWxI7vSnDtuqKIcMdfwgxJ0Z0/TPB7+mNdS4ZntMy8s2+rHjIlwoA==",
"dependencies": {
"@types/readable-stream": "^2.3.15",
"amazon-chime-sdk-js": "^3.12.0",
@ -3177,9 +3177,10 @@
}
},
"node_modules/@eslint/js": {
"version": "8.37.0",
"version": "8.38.0",
"resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.38.0.tgz",
"integrity": "sha512-IoD2MfUnOV58ghIHCiil01PcohxjbYR/qCxsoC+xNgUwh1EY8jOOrYmu3d3a71+tJJ23uscEV4X2HJWMsPJu4g==",
"dev": true,
"license": "MIT",
"engines": {
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
}
@ -3708,9 +3709,9 @@
"license": "MIT"
},
"node_modules/@types/react": {
"version": "18.0.33",
"resolved": "https://registry.npmjs.org/@types/react/-/react-18.0.33.tgz",
"integrity": "sha512-sHxzVxeanvQyQ1lr8NSHaj0kDzcNiGpILEVt69g9S31/7PfMvNCKLKcsHw4lYKjs3cGNJjXSP4mYzX43QlnjNA==",
"version": "18.0.34",
"resolved": "https://registry.npmjs.org/@types/react/-/react-18.0.34.tgz",
"integrity": "sha512-NO1UO8941541CJl1BeOXi8a9dNKFK09Gnru5ZJqkm4Q3/WoQJtHvmwt0VX0SB9YCEwe7TfSSxDuaNmx6H2BAIQ==",
"dev": true,
"dependencies": {
"@types/prop-types": "*",
@ -5379,14 +5380,15 @@
}
},
"node_modules/eslint": {
"version": "8.37.0",
"version": "8.38.0",
"resolved": "https://registry.npmjs.org/eslint/-/eslint-8.38.0.tgz",
"integrity": "sha512-pIdsD2jwlUGf/U38Jv97t8lq6HpaU/G9NKbYmpWpZGw3LdTNhZLbJePqxOXGB5+JEKfOPU/XLxYxFh03nr1KTg==",
"dev": true,
"license": "MIT",
"dependencies": {
"@eslint-community/eslint-utils": "^4.2.0",
"@eslint-community/regexpp": "^4.4.0",
"@eslint/eslintrc": "^2.0.2",
"@eslint/js": "8.37.0",
"@eslint/js": "8.38.0",
"@humanwhocodes/config-array": "^0.11.8",
"@humanwhocodes/module-importer": "^1.0.1",
"@nodelib/fs.walk": "^1.2.8",
@ -6195,14 +6197,15 @@
}
},
"node_modules/glob": {
"version": "9.2.1",
"version": "10.0.0",
"resolved": "https://registry.npmjs.org/glob/-/glob-10.0.0.tgz",
"integrity": "sha512-zmp9ZDC6NpDNLujV2W2n+3lH+BafIVZ4/ct+Yj3BMZTH/+bgm/eVjHzeFLwxJrrIGgjjS2eiQLlpurHsNlEAtQ==",
"dev": true,
"license": "ISC",
"dependencies": {
"fs.realpath": "^1.0.0",
"minimatch": "^7.4.1",
"minipass": "^4.2.4",
"path-scurry": "^1.6.1"
"minimatch": "^9.0.0",
"minipass": "^5.0.0",
"path-scurry": "^1.6.4"
},
"engines": {
"node": ">=16 || 14 >=14.17"
@ -6229,21 +6232,23 @@
},
"node_modules/glob/node_modules/brace-expansion": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
"integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
"dev": true,
"license": "MIT",
"dependencies": {
"balanced-match": "^1.0.0"
}
},
"node_modules/glob/node_modules/minimatch": {
"version": "7.4.2",
"version": "9.0.0",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.0.tgz",
"integrity": "sha512-0jJj8AvgKqWN05mrwuqi8QYKx1WmYSUoKSxu5Qhs9prezTz10sxAHGNZe9J9cqIJzta8DWsleh2KaVaLl6Ru2w==",
"dev": true,
"license": "ISC",
"dependencies": {
"brace-expansion": "^2.0.1"
},
"engines": {
"node": ">=10"
"node": ">=16 || 14 >=14.17"
},
"funding": {
"url": "https://github.com/sponsors/isaacs"
@ -7579,9 +7584,10 @@
}
},
"node_modules/minipass": {
"version": "4.2.4",
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/minipass/-/minipass-5.0.0.tgz",
"integrity": "sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==",
"dev": true,
"license": "ISC",
"engines": {
"node": ">=8"
}
@ -8139,26 +8145,28 @@
"license": "MIT"
},
"node_modules/path-scurry": {
"version": "1.6.1",
"version": "1.6.4",
"resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.6.4.tgz",
"integrity": "sha512-Qp/9IHkdNiXJ3/Kon++At2nVpnhRiPq/aSvQN+H3U1WZbvNRK0RIQK/o4HMqPoXjpuGJUEWpHSs6Mnjxqh3TQg==",
"dev": true,
"license": "BlueOak-1.0.0",
"dependencies": {
"lru-cache": "^7.14.1",
"minipass": "^4.0.2"
"lru-cache": "^9.0.0",
"minipass": "^5.0.0"
},
"engines": {
"node": ">=14"
"node": ">=16 || 14 >=14.17"
},
"funding": {
"url": "https://github.com/sponsors/isaacs"
}
},
"node_modules/path-scurry/node_modules/lru-cache": {
"version": "7.18.3",
"version": "9.0.1",
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-9.0.1.tgz",
"integrity": "sha512-C8QsKIN1UIXeOs3iWmiZ1lQY+EnKDojWd37fXy1aSbJvH4iSma1uy2OWuoB3m4SYRli5+CUjDv3Dij5DVoetmg==",
"dev": true,
"license": "ISC",
"engines": {
"node": ">=12"
"node": "14 || >=16.14"
}
},
"node_modules/path-to-regexp": {
@ -8886,11 +8894,12 @@
}
},
"node_modules/rimraf": {
"version": "4.4.1",
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/rimraf/-/rimraf-5.0.0.tgz",
"integrity": "sha512-Jf9llaP+RvaEVS5nPShYFhtXIrb3LRKP281ib3So0KkeZKo2wIKyq0Re7TOSwanasA423PSr6CCIL4bP6T040g==",
"dev": true,
"license": "ISC",
"dependencies": {
"glob": "^9.2.0"
"glob": "^10.0.0"
},
"bin": {
"rimraf": "dist/cjs/src/bin.js"
@ -9895,9 +9904,10 @@
}
},
"node_modules/typescript": {
"version": "5.0.3",
"version": "5.0.4",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.0.4.tgz",
"integrity": "sha512-cW9T5W9xY37cc+jfEnaUvX91foxtHkza3Nw3wkoF4sSlKn0MONdkdEndig/qPBWXNkmplh3NzayQzCiHM4/hqw==",
"dev": true,
"license": "Apache-2.0",
"bin": {
"tsc": "bin/tsc",
"tsserver": "bin/tsserver"
@ -12867,9 +12877,9 @@
}
},
"@dannadori/voice-changer-client-js": {
"version": "1.0.103",
"resolved": "https://registry.npmjs.org/@dannadori/voice-changer-client-js/-/voice-changer-client-js-1.0.103.tgz",
"integrity": "sha512-6kW0AshtTI4CtTlpQYaFa2IX0AlR8zqwBzaaat4PFw7bsV/EKAz2vPLTi3Y9AdzHiv14t6uWH6cwjtp0xl4F1w==",
"version": "1.0.105",
"resolved": "https://registry.npmjs.org/@dannadori/voice-changer-client-js/-/voice-changer-client-js-1.0.105.tgz",
"integrity": "sha512-wfOkRPUy2/Jqez+O/8gO98dSoNHlz/Br0ZWxI7vSnDtuqKIcMdfwgxJ0Z0/TPB7+mNdS4ZntMy8s2+rHjIlwoA==",
"requires": {
"@types/readable-stream": "^2.3.15",
"amazon-chime-sdk-js": "^3.12.0",
@ -12920,7 +12930,9 @@
}
},
"@eslint/js": {
"version": "8.37.0",
"version": "8.38.0",
"resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.38.0.tgz",
"integrity": "sha512-IoD2MfUnOV58ghIHCiil01PcohxjbYR/qCxsoC+xNgUwh1EY8jOOrYmu3d3a71+tJJ23uscEV4X2HJWMsPJu4g==",
"dev": true
},
"@fortawesome/fontawesome-common-types": {
@ -13319,9 +13331,9 @@
"dev": true
},
"@types/react": {
"version": "18.0.33",
"resolved": "https://registry.npmjs.org/@types/react/-/react-18.0.33.tgz",
"integrity": "sha512-sHxzVxeanvQyQ1lr8NSHaj0kDzcNiGpILEVt69g9S31/7PfMvNCKLKcsHw4lYKjs3cGNJjXSP4mYzX43QlnjNA==",
"version": "18.0.34",
"resolved": "https://registry.npmjs.org/@types/react/-/react-18.0.34.tgz",
"integrity": "sha512-NO1UO8941541CJl1BeOXi8a9dNKFK09Gnru5ZJqkm4Q3/WoQJtHvmwt0VX0SB9YCEwe7TfSSxDuaNmx6H2BAIQ==",
"dev": true,
"requires": {
"@types/prop-types": "*",
@ -14410,13 +14422,15 @@
"dev": true
},
"eslint": {
"version": "8.37.0",
"version": "8.38.0",
"resolved": "https://registry.npmjs.org/eslint/-/eslint-8.38.0.tgz",
"integrity": "sha512-pIdsD2jwlUGf/U38Jv97t8lq6HpaU/G9NKbYmpWpZGw3LdTNhZLbJePqxOXGB5+JEKfOPU/XLxYxFh03nr1KTg==",
"dev": true,
"requires": {
"@eslint-community/eslint-utils": "^4.2.0",
"@eslint-community/regexpp": "^4.4.0",
"@eslint/eslintrc": "^2.0.2",
"@eslint/js": "8.37.0",
"@eslint/js": "8.38.0",
"@humanwhocodes/config-array": "^0.11.8",
"@humanwhocodes/module-importer": "^1.0.1",
"@nodelib/fs.walk": "^1.2.8",
@ -14923,24 +14937,30 @@
}
},
"glob": {
"version": "9.2.1",
"version": "10.0.0",
"resolved": "https://registry.npmjs.org/glob/-/glob-10.0.0.tgz",
"integrity": "sha512-zmp9ZDC6NpDNLujV2W2n+3lH+BafIVZ4/ct+Yj3BMZTH/+bgm/eVjHzeFLwxJrrIGgjjS2eiQLlpurHsNlEAtQ==",
"dev": true,
"requires": {
"fs.realpath": "^1.0.0",
"minimatch": "^7.4.1",
"minipass": "^4.2.4",
"path-scurry": "^1.6.1"
"minimatch": "^9.0.0",
"minipass": "^5.0.0",
"path-scurry": "^1.6.4"
},
"dependencies": {
"brace-expansion": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
"integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
"dev": true,
"requires": {
"balanced-match": "^1.0.0"
}
},
"minimatch": {
"version": "7.4.2",
"version": "9.0.0",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.0.tgz",
"integrity": "sha512-0jJj8AvgKqWN05mrwuqi8QYKx1WmYSUoKSxu5Qhs9prezTz10sxAHGNZe9J9cqIJzta8DWsleh2KaVaLl6Ru2w==",
"dev": true,
"requires": {
"brace-expansion": "^2.0.1"
@ -15761,7 +15781,9 @@
"dev": true
},
"minipass": {
"version": "4.2.4",
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/minipass/-/minipass-5.0.0.tgz",
"integrity": "sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==",
"dev": true
},
"ms": {
@ -16121,15 +16143,19 @@
"dev": true
},
"path-scurry": {
"version": "1.6.1",
"version": "1.6.4",
"resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.6.4.tgz",
"integrity": "sha512-Qp/9IHkdNiXJ3/Kon++At2nVpnhRiPq/aSvQN+H3U1WZbvNRK0RIQK/o4HMqPoXjpuGJUEWpHSs6Mnjxqh3TQg==",
"dev": true,
"requires": {
"lru-cache": "^7.14.1",
"minipass": "^4.0.2"
"lru-cache": "^9.0.0",
"minipass": "^5.0.0"
},
"dependencies": {
"lru-cache": {
"version": "7.18.3",
"version": "9.0.1",
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-9.0.1.tgz",
"integrity": "sha512-C8QsKIN1UIXeOs3iWmiZ1lQY+EnKDojWd37fXy1aSbJvH4iSma1uy2OWuoB3m4SYRli5+CUjDv3Dij5DVoetmg==",
"dev": true
}
}
@ -16571,10 +16597,12 @@
"dev": true
},
"rimraf": {
"version": "4.4.1",
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/rimraf/-/rimraf-5.0.0.tgz",
"integrity": "sha512-Jf9llaP+RvaEVS5nPShYFhtXIrb3LRKP281ib3So0KkeZKo2wIKyq0Re7TOSwanasA423PSr6CCIL4bP6T040g==",
"dev": true,
"requires": {
"glob": "^9.2.0"
"glob": "^10.0.0"
}
},
"run-parallel": {
@ -17207,7 +17235,9 @@
}
},
"typescript": {
"version": "5.0.3",
"version": "5.0.4",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.0.4.tgz",
"integrity": "sha512-cW9T5W9xY37cc+jfEnaUvX91foxtHkza3Nw3wkoF4sSlKn0MONdkdEndig/qPBWXNkmplh3NzayQzCiHM4/hqw==",
"dev": true
},
"ua-parser-js": {

View File

@ -24,13 +24,13 @@
"@babel/preset-react": "^7.18.6",
"@babel/preset-typescript": "^7.21.4",
"@types/node": "^18.15.11",
"@types/react": "^18.0.33",
"@types/react": "^18.0.34",
"@types/react-dom": "^18.0.11",
"autoprefixer": "^10.4.14",
"babel-loader": "^9.1.2",
"copy-webpack-plugin": "^11.0.0",
"css-loader": "^6.7.3",
"eslint": "^8.37.0",
"eslint": "^8.38.0",
"eslint-config-prettier": "^8.8.0",
"eslint-plugin-prettier": "^4.2.1",
"eslint-plugin-react": "^7.32.2",
@ -41,17 +41,17 @@
"postcss-loader": "^7.2.4",
"postcss-nested": "^6.0.1",
"prettier": "^2.8.7",
"rimraf": "^4.4.1",
"rimraf": "^5.0.0",
"style-loader": "^3.3.2",
"ts-loader": "^9.4.2",
"tsconfig-paths": "^4.2.0",
"typescript": "^5.0.3",
"typescript": "^5.0.4",
"webpack": "^5.78.0",
"webpack-cli": "^5.0.1",
"webpack-dev-server": "^4.13.2"
},
"dependencies": {
"@dannadori/voice-changer-client-js": "^1.0.103",
"@dannadori/voice-changer-client-js": "^1.0.105",
"@fortawesome/fontawesome-svg-core": "^6.4.0",
"@fortawesome/free-brands-svg-icons": "^6.4.0",
"@fortawesome/free-regular-svg-icons": "^6.4.0",

View File

@ -1,7 +1,7 @@
import * as React from "react";
import { createRoot } from "react-dom/client";
import "./css/App.css"
import { ErrorInfo, useMemo, useState, } from "react";
import { ErrorInfo, useEffect, useMemo, useState, } from "react";
import { AppStateProvider } from "./001_provider/001_AppStateProvider";
import { library } from "@fortawesome/fontawesome-svg-core";
@ -11,7 +11,7 @@ import { fab } from "@fortawesome/free-brands-svg-icons";
import { AppRootProvider, useAppRoot } from "./001_provider/001_AppRootProvider";
import ErrorBoundary from "./001_provider/900_ErrorBoundary";
import { ClientType, INDEXEDDB_KEY_CLIENT, INDEXEDDB_KEY_MODEL_DATA, INDEXEDDB_KEY_SERVER, INDEXEDDB_KEY_WORKLET, INDEXEDDB_KEY_WORKLETNODE, useIndexedDB } from "@dannadori/voice-changer-client-js";
import { CLIENT_TYPE, INDEXEDDB_KEY_AUDIO_OUTPUT } from "./const";
import { INDEXEDDB_KEY_AUDIO_OUTPUT, INDEXEDDB_KEY_DEFAULT_MODEL_TYPE } from "./const";
import { Demo } from "./components/demo/010_Demo";
import { ClientSelector } from "./001_ClientSelector";
@ -22,7 +22,7 @@ const container = document.getElementById("app")!;
const root = createRoot(container);
const App = () => {
const { appGuiSettingState, clientType } = useAppRoot()
const { appGuiSettingState } = useAppRoot()
const front = useMemo(() => {
if (appGuiSettingState.appGuiSetting.type == "demo") {
return <Demo></Demo>
@ -39,11 +39,11 @@ const App = () => {
}
const AppStateWrapper = () => {
const { appGuiSettingState, clientType } = useAppRoot()
const { appGuiSettingState, clientType, setClientType } = useAppRoot()
// エラーバウンダリー設定
const [error, setError] = useState<{ error: Error, errorInfo: ErrorInfo }>()
const { removeItem } = useIndexedDB({ clientType: CLIENT_TYPE })
const { removeItem } = useIndexedDB({ clientType: clientType })
const { getItem } = useIndexedDB({ clientType: null })
const errorComponent = useMemo(() => {
const errorName = error?.error.name || "no error name"
const errorMessage = error?.error.message || "no error message"
@ -98,6 +98,16 @@ const AppStateWrapper = () => {
}
useEffect(() => {
const loadDefaultModelType = async () => {
const defaultModelType = await getItem(INDEXEDDB_KEY_DEFAULT_MODEL_TYPE)
if (defaultModelType && defaultModelType != "null") {
setClientType(defaultModelType as ClientType)
}
}
loadDefaultModelType()
}, [])
if (!clientType) {
return <ClientSelector></ClientSelector>

View File

@ -0,0 +1,143 @@
import React, { useMemo } from "react";
import { isDesktopApp } from "./const";
export type TitleProps = {
lineNum: number
mainTitle: string
subTitle: string
}
export const Title = (props: TitleProps) => {
const githubLink = useMemo(() => {
return isDesktopApp() ?
(
// @ts-ignore
<span className="link tooltip" onClick={() => { window.electronAPI.openBrowser("https://github.com/w-okada/voice-changer") }}>
<img src="./assets/icons/github.svg" />
<div className="tooltip-text">github</div>
</span>
)
:
(
<a className="link tooltip" href="https://github.com/w-okada/voice-changer" target="_blank" rel="noopener noreferrer">
<img src="./assets/icons/github.svg" />
<div className="tooltip-text">github</div>
</a>
)
}, [])
const manualLink = useMemo(() => {
return isDesktopApp() ?
(
// @ts-ignore
<span className="link tooltip" onClick={() => { window.electronAPI.openBrowser("https://zenn.dev/wok/books/0003_vc-helper-v_1_5") }}>
<img src="./assets/icons/help-circle.svg" />
<div className="tooltip-text">manual</div>
</span>
)
:
(
<a className="link tooltip" href="https://zenn.dev/wok/books/0003_vc-helper-v_1_5" target="_blank" rel="noopener noreferrer">
<img src="./assets/icons/help-circle.svg" />
<div className="tooltip-text">manual</div>
</a>
)
}, [])
const toolLink = useMemo(() => {
return isDesktopApp() ?
(
<div className="link tooltip">
<img src="./assets/icons/tool.svg" />
<div className="tooltip-text tooltip-text-100px">
<p onClick={() => {
// @ts-ignore
window.electronAPI.openBrowser("https://w-okada.github.io/screen-recorder-ts/")
}}>
screen capture
</p>
</div>
</div>
)
:
(
<div className="link tooltip">
<img src="./assets/icons/tool.svg" />
<div className="tooltip-text tooltip-text-100px">
<p onClick={() => {
window.open("https://w-okada.github.io/screen-recorder-ts/", '_blank', "noreferrer")
}}>
screen capture
</p>
</div>
</div>
)
}, [])
const coffeeLink = useMemo(() => {
return isDesktopApp() ?
(
// @ts-ignore
<span className="link tooltip" onClick={() => { window.electronAPI.openBrowser("https://www.buymeacoffee.com/wokad") }}>
<img className="donate-img" src="./assets/buymeacoffee.png" />
<div className="tooltip-text tooltip-text-100px">donate()</div>
</span>
)
:
(
<a className="link tooltip" href="https://www.buymeacoffee.com/wokad" target="_blank" rel="noopener noreferrer">
<img className="donate-img" src="./assets/buymeacoffee.png" />
<div className="tooltip-text tooltip-text-100px">
donate()
</div>
</a>
)
}, [])
const titleRow = useMemo(() => {
if (props.lineNum == 2) {
return (
<>
<div className="top-title">
<span className="title">{props.mainTitle}</span>
</div>
<div className="top-title">
<span className="top-title-version">{props.subTitle}</span>
<span className="belongings">
{githubLink}
{manualLink}
{toolLink}
{coffeeLink}
</span>
</div>
</>
)
} else {
return (
<div className="top-title">
<span className="title">{props.mainTitle}</span>
<span className="top-title-version">{props.subTitle}</span>
<span className="belongings">
{githubLink}
{manualLink}
{toolLink}
{coffeeLink}
</span>
<span className="belongings">
</span>
</div>
)
}
}, [props.subTitle, props.mainTitle, props.lineNum])
return titleRow
};

View File

@ -1,15 +1,40 @@
import { useIndexedDB } from "@dannadori/voice-changer-client-js"
import React from "react"
import { Title } from "./001-1_Title"
import { useAppRoot } from "./001_provider/001_AppRootProvider"
import { INDEXEDDB_KEY_DEFAULT_MODEL_TYPE } from "./const"
export const ClientSelector = () => {
const { setClientType } = useAppRoot()
const { setItem } = useIndexedDB({ clientType: null })
return (
<div>
<div onClick={() => { setClientType("MMVCv13") }}>MMVCv13</div>
<div onClick={() => { setClientType("MMVCv15") }}>MMVCv15</div>
<div onClick={() => { setClientType("so-vits-svc-40") }}>so-vits-svc-40</div>
<div onClick={() => { setClientType("so-vits-svc-40v2") }}>so-vits-svc-40v2</div>
<div onClick={() => { setClientType("RVC") }}>RVC</div>
<div className="main-body">
<Title lineNum={1} mainTitle={"Realtime Voice Changer Client"} subTitle={"launcher"} ></Title>
<div className="body-row split-1-8-1 left-padding-1 ">
<div></div>
<div className="body-button-container">
<div className="body-button w40 bold" onClick={() => { setClientType("MMVCv13"); setItem(INDEXEDDB_KEY_DEFAULT_MODEL_TYPE, "MMVCv13") }}>MMVCv13</div>
<div className="body-button w40 bold" onClick={() => { setClientType("MMVCv15"); setItem(INDEXEDDB_KEY_DEFAULT_MODEL_TYPE, "MMVCv15") }}>MMVCv15</div>
</div>
<div></div>
</div>
<div className="body-row split-1-8-1 left-padding-1 ">
<div></div>
<div className="body-button-container">
<div className="body-button w40 bold" onClick={() => { setClientType("so-vits-svc-40"); setItem(INDEXEDDB_KEY_DEFAULT_MODEL_TYPE, "so-vits-svc-40") }}>so-vits-svc-40</div>
<div className="body-button w40 bold" onClick={() => { setClientType("so-vits-svc-40v2"); setItem(INDEXEDDB_KEY_DEFAULT_MODEL_TYPE, "so-vits-svc-40v2") }}>so-vits-svc-40v2</div>
</div>
<div></div>
</div>
<div className="body-row split-1-8-1 left-padding-1 ">
<div></div>
<div className="body-button-container">
<div className="body-button w40 bold" onClick={() => { setClientType("RVC"); setItem(INDEXEDDB_KEY_DEFAULT_MODEL_TYPE, "RVC") }}>RVC</div>
</div>
<div></div>
</div>
</div>
)

View File

@ -1,7 +1,7 @@
import React, { useMemo } from "react";
import { useAppState } from "../../../001_provider/001_AppStateProvider";
import { useIndexedDB } from "@dannadori/voice-changer-client-js";
import { INDEXEDDB_KEY_AUDIO_OUTPUT } from "../../../const";
import { INDEXEDDB_KEY_AUDIO_OUTPUT, INDEXEDDB_KEY_DEFAULT_MODEL_TYPE } from "../../../const";
import { useAppRoot } from "../../../001_provider/001_AppRootProvider";
import { useGuiState } from "../001_GuiStateProvider"
export type ClearSettingRowProps = {
@ -14,7 +14,7 @@ export const ClearSettingRow = (_props: ClearSettingRowProps) => {
const guiState = useGuiState()
const clientType = appGuiSettingState.appGuiSetting.id
const { removeItem } = useIndexedDB({ clientType: clientType })
const { setItem } = useIndexedDB({ clientType: null })
const clearSettingRow = useMemo(() => {
const onClearSettingClicked = async () => {
@ -24,13 +24,17 @@ export const ClearSettingRow = (_props: ClearSettingRowProps) => {
}
const onReselectVCClicked = async () => {
guiState.setIsConverting(false)
await appState.clientSetting.stop()
if (guiState.isConverting) {
await appState.clientSetting.stop()
guiState.setIsConverting(false)
}
setItem(INDEXEDDB_KEY_DEFAULT_MODEL_TYPE, "null")
setClientType(null)
appGuiSettingState.clearAppGuiSetting()
}
return (
<div className="body-row split-3-3-4 left-padding-1">
<div className="body-row split-2-2-6 left-padding-1">
<div className="body-button-container">
<div className="body-button" onClick={onClearSettingClicked}>clear setting</div>
</div>
@ -40,6 +44,6 @@ export const ClearSettingRow = (_props: ClearSettingRowProps) => {
<div className="body-item-text"></div>
</div>
)
}, [])
}, [appState.clientSetting, guiState.isConverting])
return clearSettingRow
};

View File

@ -1,6 +1,3 @@
import { ClientType } from "@dannadori/voice-changer-client-js"
export const CLIENT_TYPE = ClientType.MMVCv13
export const AUDIO_ELEMENT_FOR_PLAY_RESULT = "audio-result"
export const AUDIO_ELEMENT_FOR_TEST_ORIGINAL = "audio-test-original"
@ -11,6 +8,7 @@ export const AUDIO_ELEMENT_FOR_SAMPLING_INPUT = "body-wav-container-wav-input"
export const AUDIO_ELEMENT_FOR_SAMPLING_OUTPUT = "body-wav-container-wav-output"
export const INDEXEDDB_KEY_AUDIO_OUTPUT = "INDEXEDDB_KEY_AUDIO_OUTPUT"
export const INDEXEDDB_KEY_DEFAULT_MODEL_TYPE = "INDEXEDDB_KEY_AUDIO_OUTPUT"
export const isDesktopApp = () => {

View File

@ -48,7 +48,7 @@ body {
overflow-x: hidden;
color: var(--text-color);
/* background: linear-gradient(45deg, var(--company-color1) 0, 5%, var(--company-color2) 5% 10%, var(--company-color3) 10% 80%, var(--company-color1) 80% 85%, var(--company-color2) 85% 100%); */
background: linear-gradient(45deg, var(--company-color1) 0, 1%, var(--company-color2) 1% 5%, var(--company-color3) 5% 80%, var(--company-color1) 80% 85%, var(--company-color2) 85% 100%);
background: linear-gradient(45deg, var(--company-color1) 0, 1%, var(--company-color2) 1% 5%, var(--company-color3) 5% 90%, var(--company-color1) 90% 95%, var(--company-color2) 95% 100%);
}
#app {
height: 100%;
@ -197,6 +197,42 @@ body {
}
}
.split-1-8-1 {
display: flex;
width: 100%;
justify-content: center;
margin: 1px 0px 1px 0px;
& > div:nth-child(1) {
left: 0px;
width: 10%;
}
& > div:nth-child(2) {
left: 10%;
width: 80%;
}
& > div:nth-child(3) {
left: 90%;
width: 10%;
}
}
.split-2-2-6 {
display: flex;
width: 100%;
justify-content: center;
margin: 1px 0px 1px 0px;
& > div:nth-child(1) {
left: 0px;
width: 20%;
}
& > div:nth-child(2) {
left: 20%;
width: 20%;
}
& > div:nth-child(3) {
left: 40%;
width: 60%;
}
}
.split-3-3-4 {
display: flex;
width: 100%;
@ -270,6 +306,29 @@ body {
width: 20%;
}
}
.split-1-4-4-1 {
display: flex;
width: 100%;
justify-content: center;
margin: 1px 0px 1px 0px;
& > div:nth-child(1) {
left: 0px;
width: 10%;
}
& > div:nth-child(2) {
left: 10%;
width: 40%;
}
& > div:nth-child(3) {
left: 50%;
width: 40%;
}
& > div:nth-child(4) {
left: 90%;
width: 10%;
}
}
.split-3-2-2-3 {
display: flex;
width: 100%;
@ -410,6 +469,16 @@ body {
width: 40%;
}
}
.w20 {
width: 20%;
}
.bold {
font-weight: 700;
}
.w40 {
width: 40%;
}
.underline {
border-bottom: 3px solid #333;
}
@ -499,6 +568,7 @@ body {
border-radius: 2px;
cursor: pointer;
vertical-align: middle;
text-align: center;
&:hover {
border: solid 1px #000;
}

View File

@ -1,12 +1,12 @@
{
"name": "@dannadori/voice-changer-client-js",
"version": "1.0.103",
"version": "1.0.105",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "@dannadori/voice-changer-client-js",
"version": "1.0.103",
"version": "1.0.105",
"license": "ISC",
"dependencies": {
"@types/readable-stream": "^2.3.15",
@ -20,9 +20,9 @@
"devDependencies": {
"@types/audioworklet": "^0.0.41",
"@types/node": "^18.15.11",
"@types/react": "18.0.32",
"@types/react": "18.0.34",
"@types/react-dom": "18.0.11",
"eslint": "^8.37.0",
"eslint": "^8.38.0",
"eslint-config-prettier": "^8.8.0",
"eslint-plugin-prettier": "^4.2.1",
"eslint-plugin-react": "^7.32.2",
@ -30,10 +30,10 @@
"npm-run-all": "^4.1.5",
"prettier": "^2.8.7",
"raw-loader": "^4.0.2",
"rimraf": "^4.4.1",
"rimraf": "^5.0.0",
"ts-loader": "^9.4.2",
"typescript": "^5.0.3",
"webpack": "^5.77.0",
"typescript": "^5.0.4",
"webpack": "^5.78.0",
"webpack-cli": "^5.0.1",
"webpack-dev-server": "^4.13.2"
}
@ -1451,9 +1451,9 @@
}
},
"node_modules/@eslint/js": {
"version": "8.37.0",
"resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.37.0.tgz",
"integrity": "sha512-x5vzdtOOGgFVDCUs81QRB2+liax8rFg3+7hqM+QhBG0/G3F1ZsoYl97UrqgHgQ9KKT7G6c4V+aTUCgu/n22v1A==",
"version": "8.38.0",
"resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.38.0.tgz",
"integrity": "sha512-IoD2MfUnOV58ghIHCiil01PcohxjbYR/qCxsoC+xNgUwh1EY8jOOrYmu3d3a71+tJJ23uscEV4X2HJWMsPJu4g==",
"dev": true,
"engines": {
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
@ -1852,9 +1852,9 @@
"dev": true
},
"node_modules/@types/react": {
"version": "18.0.32",
"resolved": "https://registry.npmjs.org/@types/react/-/react-18.0.32.tgz",
"integrity": "sha512-gYGXdtPQ9Cj0w2Fwqg5/ak6BcK3Z15YgjSqtyDizWUfx7mQ8drs0NBUzRRsAdoFVTO8kJ8L2TL8Skm7OFPnLUw==",
"version": "18.0.34",
"resolved": "https://registry.npmjs.org/@types/react/-/react-18.0.34.tgz",
"integrity": "sha512-NO1UO8941541CJl1BeOXi8a9dNKFK09Gnru5ZJqkm4Q3/WoQJtHvmwt0VX0SB9YCEwe7TfSSxDuaNmx6H2BAIQ==",
"dev": true,
"dependencies": {
"@types/prop-types": "*",
@ -3230,15 +3230,15 @@
}
},
"node_modules/eslint": {
"version": "8.37.0",
"resolved": "https://registry.npmjs.org/eslint/-/eslint-8.37.0.tgz",
"integrity": "sha512-NU3Ps9nI05GUoVMxcZx1J8CNR6xOvUT4jAUMH5+z8lpp3aEdPVCImKw6PWG4PY+Vfkpr+jvMpxs/qoE7wq0sPw==",
"version": "8.38.0",
"resolved": "https://registry.npmjs.org/eslint/-/eslint-8.38.0.tgz",
"integrity": "sha512-pIdsD2jwlUGf/U38Jv97t8lq6HpaU/G9NKbYmpWpZGw3LdTNhZLbJePqxOXGB5+JEKfOPU/XLxYxFh03nr1KTg==",
"dev": true,
"dependencies": {
"@eslint-community/eslint-utils": "^4.2.0",
"@eslint-community/regexpp": "^4.4.0",
"@eslint/eslintrc": "^2.0.2",
"@eslint/js": "8.37.0",
"@eslint/js": "8.38.0",
"@humanwhocodes/config-array": "^0.11.8",
"@humanwhocodes/module-importer": "^1.0.1",
"@nodelib/fs.walk": "^1.2.8",
@ -5082,9 +5082,9 @@
}
},
"node_modules/minipass": {
"version": "4.2.5",
"resolved": "https://registry.npmjs.org/minipass/-/minipass-4.2.5.tgz",
"integrity": "sha512-+yQl7SX3bIT83Lhb4BVorMAHVuqsskxRdlmO9kTpyukp8vsm2Sn/fUOV9xlnG8/a5JsypJzap21lz/y3FBMJ8Q==",
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/minipass/-/minipass-5.0.0.tgz",
"integrity": "sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==",
"dev": true,
"engines": {
"node": ">=8"
@ -5688,28 +5688,28 @@
"dev": true
},
"node_modules/path-scurry": {
"version": "1.6.1",
"resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.6.1.tgz",
"integrity": "sha512-OW+5s+7cw6253Q4E+8qQ/u1fVvcJQCJo/VFD8pje+dbJCF1n5ZRMV2AEHbGp+5Q7jxQIYJxkHopnj6nzdGeZLA==",
"version": "1.6.4",
"resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.6.4.tgz",
"integrity": "sha512-Qp/9IHkdNiXJ3/Kon++At2nVpnhRiPq/aSvQN+H3U1WZbvNRK0RIQK/o4HMqPoXjpuGJUEWpHSs6Mnjxqh3TQg==",
"dev": true,
"dependencies": {
"lru-cache": "^7.14.1",
"minipass": "^4.0.2"
"lru-cache": "^9.0.0",
"minipass": "^5.0.0"
},
"engines": {
"node": ">=14"
"node": ">=16 || 14 >=14.17"
},
"funding": {
"url": "https://github.com/sponsors/isaacs"
}
},
"node_modules/path-scurry/node_modules/lru-cache": {
"version": "7.18.3",
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz",
"integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==",
"version": "9.0.1",
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-9.0.1.tgz",
"integrity": "sha512-C8QsKIN1UIXeOs3iWmiZ1lQY+EnKDojWd37fXy1aSbJvH4iSma1uy2OWuoB3m4SYRli5+CUjDv3Dij5DVoetmg==",
"dev": true,
"engines": {
"node": ">=12"
"node": "14 || >=16.14"
}
},
"node_modules/path-to-regexp": {
@ -6259,12 +6259,12 @@
}
},
"node_modules/rimraf": {
"version": "4.4.1",
"resolved": "https://registry.npmjs.org/rimraf/-/rimraf-4.4.1.tgz",
"integrity": "sha512-Gk8NlF062+T9CqNGn6h4tls3k6T1+/nXdOcSZVikNVtlRdYpA7wRJJMoXmuvOnLW844rPjdQ7JgXCYM6PPC/og==",
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/rimraf/-/rimraf-5.0.0.tgz",
"integrity": "sha512-Jf9llaP+RvaEVS5nPShYFhtXIrb3LRKP281ib3So0KkeZKo2wIKyq0Re7TOSwanasA423PSr6CCIL4bP6T040g==",
"dev": true,
"dependencies": {
"glob": "^9.2.0"
"glob": "^10.0.0"
},
"bin": {
"rimraf": "dist/cjs/src/bin.js"
@ -6286,15 +6286,15 @@
}
},
"node_modules/rimraf/node_modules/glob": {
"version": "9.2.1",
"resolved": "https://registry.npmjs.org/glob/-/glob-9.2.1.tgz",
"integrity": "sha512-Pxxgq3W0HyA3XUvSXcFhRSs+43Jsx0ddxcFrbjxNGkL2Ak5BAUBxLqI5G6ADDeCHLfzzXFhe0b1yYcctGmytMA==",
"version": "10.0.0",
"resolved": "https://registry.npmjs.org/glob/-/glob-10.0.0.tgz",
"integrity": "sha512-zmp9ZDC6NpDNLujV2W2n+3lH+BafIVZ4/ct+Yj3BMZTH/+bgm/eVjHzeFLwxJrrIGgjjS2eiQLlpurHsNlEAtQ==",
"dev": true,
"dependencies": {
"fs.realpath": "^1.0.0",
"minimatch": "^7.4.1",
"minipass": "^4.2.4",
"path-scurry": "^1.6.1"
"minimatch": "^9.0.0",
"minipass": "^5.0.0",
"path-scurry": "^1.6.4"
},
"engines": {
"node": ">=16 || 14 >=14.17"
@ -6304,15 +6304,15 @@
}
},
"node_modules/rimraf/node_modules/minimatch": {
"version": "7.4.2",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-7.4.2.tgz",
"integrity": "sha512-xy4q7wou3vUoC9k1xGTXc+awNdGaGVHtFUaey8tiX4H1QRc04DZ/rmDFwNm2EBsuYEhAZ6SgMmYf3InGY6OauA==",
"version": "9.0.0",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.0.tgz",
"integrity": "sha512-0jJj8AvgKqWN05mrwuqi8QYKx1WmYSUoKSxu5Qhs9prezTz10sxAHGNZe9J9cqIJzta8DWsleh2KaVaLl6Ru2w==",
"dev": true,
"dependencies": {
"brace-expansion": "^2.0.1"
},
"engines": {
"node": ">=10"
"node": ">=16 || 14 >=14.17"
},
"funding": {
"url": "https://github.com/sponsors/isaacs"
@ -7192,9 +7192,9 @@
}
},
"node_modules/typescript": {
"version": "5.0.3",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.0.3.tgz",
"integrity": "sha512-xv8mOEDnigb/tN9PSMTwSEqAnUvkoXMQlicOb0IUVDBSQCgBSaAAROUZYy2IcUy5qU6XajK5jjjO7TMWqBTKZA==",
"version": "5.0.4",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.0.4.tgz",
"integrity": "sha512-cW9T5W9xY37cc+jfEnaUvX91foxtHkza3Nw3wkoF4sSlKn0MONdkdEndig/qPBWXNkmplh3NzayQzCiHM4/hqw==",
"dev": true,
"bin": {
"tsc": "bin/tsc",
@ -7346,9 +7346,9 @@
}
},
"node_modules/webpack": {
"version": "5.77.0",
"resolved": "https://registry.npmjs.org/webpack/-/webpack-5.77.0.tgz",
"integrity": "sha512-sbGNjBr5Ya5ss91yzjeJTLKyfiwo5C628AFjEa6WSXcZa4E+F57om3Cc8xLb1Jh0b243AWuSYRf3dn7HVeFQ9Q==",
"version": "5.78.0",
"resolved": "https://registry.npmjs.org/webpack/-/webpack-5.78.0.tgz",
"integrity": "sha512-gT5DP72KInmE/3azEaQrISjTvLYlSM0j1Ezhht/KLVkrqtv10JoP/RXhwmX/frrutOPuSq3o5Vq0ehR/4Vmd1g==",
"dev": true,
"dependencies": {
"@types/eslint-scope": "^3.7.3",
@ -9138,9 +9138,9 @@
}
},
"@eslint/js": {
"version": "8.37.0",
"resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.37.0.tgz",
"integrity": "sha512-x5vzdtOOGgFVDCUs81QRB2+liax8rFg3+7hqM+QhBG0/G3F1ZsoYl97UrqgHgQ9KKT7G6c4V+aTUCgu/n22v1A==",
"version": "8.38.0",
"resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.38.0.tgz",
"integrity": "sha512-IoD2MfUnOV58ghIHCiil01PcohxjbYR/qCxsoC+xNgUwh1EY8jOOrYmu3d3a71+tJJ23uscEV4X2HJWMsPJu4g==",
"dev": true
},
"@humanwhocodes/config-array": {
@ -9502,9 +9502,9 @@
"dev": true
},
"@types/react": {
"version": "18.0.32",
"resolved": "https://registry.npmjs.org/@types/react/-/react-18.0.32.tgz",
"integrity": "sha512-gYGXdtPQ9Cj0w2Fwqg5/ak6BcK3Z15YgjSqtyDizWUfx7mQ8drs0NBUzRRsAdoFVTO8kJ8L2TL8Skm7OFPnLUw==",
"version": "18.0.34",
"resolved": "https://registry.npmjs.org/@types/react/-/react-18.0.34.tgz",
"integrity": "sha512-NO1UO8941541CJl1BeOXi8a9dNKFK09Gnru5ZJqkm4Q3/WoQJtHvmwt0VX0SB9YCEwe7TfSSxDuaNmx6H2BAIQ==",
"dev": true,
"requires": {
"@types/prop-types": "*",
@ -10569,15 +10569,15 @@
"dev": true
},
"eslint": {
"version": "8.37.0",
"resolved": "https://registry.npmjs.org/eslint/-/eslint-8.37.0.tgz",
"integrity": "sha512-NU3Ps9nI05GUoVMxcZx1J8CNR6xOvUT4jAUMH5+z8lpp3aEdPVCImKw6PWG4PY+Vfkpr+jvMpxs/qoE7wq0sPw==",
"version": "8.38.0",
"resolved": "https://registry.npmjs.org/eslint/-/eslint-8.38.0.tgz",
"integrity": "sha512-pIdsD2jwlUGf/U38Jv97t8lq6HpaU/G9NKbYmpWpZGw3LdTNhZLbJePqxOXGB5+JEKfOPU/XLxYxFh03nr1KTg==",
"dev": true,
"requires": {
"@eslint-community/eslint-utils": "^4.2.0",
"@eslint-community/regexpp": "^4.4.0",
"@eslint/eslintrc": "^2.0.2",
"@eslint/js": "8.37.0",
"@eslint/js": "8.38.0",
"@humanwhocodes/config-array": "^0.11.8",
"@humanwhocodes/module-importer": "^1.0.1",
"@nodelib/fs.walk": "^1.2.8",
@ -11920,9 +11920,9 @@
}
},
"minipass": {
"version": "4.2.5",
"resolved": "https://registry.npmjs.org/minipass/-/minipass-4.2.5.tgz",
"integrity": "sha512-+yQl7SX3bIT83Lhb4BVorMAHVuqsskxRdlmO9kTpyukp8vsm2Sn/fUOV9xlnG8/a5JsypJzap21lz/y3FBMJ8Q==",
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/minipass/-/minipass-5.0.0.tgz",
"integrity": "sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==",
"dev": true
},
"ms": {
@ -12372,19 +12372,19 @@
"dev": true
},
"path-scurry": {
"version": "1.6.1",
"resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.6.1.tgz",
"integrity": "sha512-OW+5s+7cw6253Q4E+8qQ/u1fVvcJQCJo/VFD8pje+dbJCF1n5ZRMV2AEHbGp+5Q7jxQIYJxkHopnj6nzdGeZLA==",
"version": "1.6.4",
"resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.6.4.tgz",
"integrity": "sha512-Qp/9IHkdNiXJ3/Kon++At2nVpnhRiPq/aSvQN+H3U1WZbvNRK0RIQK/o4HMqPoXjpuGJUEWpHSs6Mnjxqh3TQg==",
"dev": true,
"requires": {
"lru-cache": "^7.14.1",
"minipass": "^4.0.2"
"lru-cache": "^9.0.0",
"minipass": "^5.0.0"
},
"dependencies": {
"lru-cache": {
"version": "7.18.3",
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz",
"integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==",
"version": "9.0.1",
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-9.0.1.tgz",
"integrity": "sha512-C8QsKIN1UIXeOs3iWmiZ1lQY+EnKDojWd37fXy1aSbJvH4iSma1uy2OWuoB3m4SYRli5+CUjDv3Dij5DVoetmg==",
"dev": true
}
}
@ -12782,12 +12782,12 @@
"dev": true
},
"rimraf": {
"version": "4.4.1",
"resolved": "https://registry.npmjs.org/rimraf/-/rimraf-4.4.1.tgz",
"integrity": "sha512-Gk8NlF062+T9CqNGn6h4tls3k6T1+/nXdOcSZVikNVtlRdYpA7wRJJMoXmuvOnLW844rPjdQ7JgXCYM6PPC/og==",
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/rimraf/-/rimraf-5.0.0.tgz",
"integrity": "sha512-Jf9llaP+RvaEVS5nPShYFhtXIrb3LRKP281ib3So0KkeZKo2wIKyq0Re7TOSwanasA423PSr6CCIL4bP6T040g==",
"dev": true,
"requires": {
"glob": "^9.2.0"
"glob": "^10.0.0"
},
"dependencies": {
"brace-expansion": {
@ -12800,21 +12800,21 @@
}
},
"glob": {
"version": "9.2.1",
"resolved": "https://registry.npmjs.org/glob/-/glob-9.2.1.tgz",
"integrity": "sha512-Pxxgq3W0HyA3XUvSXcFhRSs+43Jsx0ddxcFrbjxNGkL2Ak5BAUBxLqI5G6ADDeCHLfzzXFhe0b1yYcctGmytMA==",
"version": "10.0.0",
"resolved": "https://registry.npmjs.org/glob/-/glob-10.0.0.tgz",
"integrity": "sha512-zmp9ZDC6NpDNLujV2W2n+3lH+BafIVZ4/ct+Yj3BMZTH/+bgm/eVjHzeFLwxJrrIGgjjS2eiQLlpurHsNlEAtQ==",
"dev": true,
"requires": {
"fs.realpath": "^1.0.0",
"minimatch": "^7.4.1",
"minipass": "^4.2.4",
"path-scurry": "^1.6.1"
"minimatch": "^9.0.0",
"minipass": "^5.0.0",
"path-scurry": "^1.6.4"
}
},
"minimatch": {
"version": "7.4.2",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-7.4.2.tgz",
"integrity": "sha512-xy4q7wou3vUoC9k1xGTXc+awNdGaGVHtFUaey8tiX4H1QRc04DZ/rmDFwNm2EBsuYEhAZ6SgMmYf3InGY6OauA==",
"version": "9.0.0",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.0.tgz",
"integrity": "sha512-0jJj8AvgKqWN05mrwuqi8QYKx1WmYSUoKSxu5Qhs9prezTz10sxAHGNZe9J9cqIJzta8DWsleh2KaVaLl6Ru2w==",
"dev": true,
"requires": {
"brace-expansion": "^2.0.1"
@ -13492,9 +13492,9 @@
}
},
"typescript": {
"version": "5.0.3",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.0.3.tgz",
"integrity": "sha512-xv8mOEDnigb/tN9PSMTwSEqAnUvkoXMQlicOb0IUVDBSQCgBSaAAROUZYy2IcUy5qU6XajK5jjjO7TMWqBTKZA==",
"version": "5.0.4",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.0.4.tgz",
"integrity": "sha512-cW9T5W9xY37cc+jfEnaUvX91foxtHkza3Nw3wkoF4sSlKn0MONdkdEndig/qPBWXNkmplh3NzayQzCiHM4/hqw==",
"dev": true
},
"ua-parser-js": {
@ -13592,9 +13592,9 @@
}
},
"webpack": {
"version": "5.77.0",
"resolved": "https://registry.npmjs.org/webpack/-/webpack-5.77.0.tgz",
"integrity": "sha512-sbGNjBr5Ya5ss91yzjeJTLKyfiwo5C628AFjEa6WSXcZa4E+F57om3Cc8xLb1Jh0b243AWuSYRf3dn7HVeFQ9Q==",
"version": "5.78.0",
"resolved": "https://registry.npmjs.org/webpack/-/webpack-5.78.0.tgz",
"integrity": "sha512-gT5DP72KInmE/3azEaQrISjTvLYlSM0j1Ezhht/KLVkrqtv10JoP/RXhwmX/frrutOPuSq3o5Vq0ehR/4Vmd1g==",
"dev": true,
"requires": {
"@types/eslint-scope": "^3.7.3",

View File

@ -1,6 +1,6 @@
{
"name": "@dannadori/voice-changer-client-js",
"version": "1.0.103",
"version": "1.0.105",
"description": "",
"main": "dist/index.js",
"directories": {
@ -28,9 +28,9 @@
"devDependencies": {
"@types/audioworklet": "^0.0.41",
"@types/node": "^18.15.11",
"@types/react": "18.0.32",
"@types/react": "18.0.34",
"@types/react-dom": "18.0.11",
"eslint": "^8.37.0",
"eslint": "^8.38.0",
"eslint-config-prettier": "^8.8.0",
"eslint-plugin-prettier": "^4.2.1",
"eslint-plugin-react": "^7.32.2",
@ -38,10 +38,10 @@
"npm-run-all": "^4.1.5",
"prettier": "^2.8.7",
"raw-loader": "^4.0.2",
"rimraf": "^4.4.1",
"rimraf": "^5.0.0",
"ts-loader": "^9.4.2",
"typescript": "^5.0.3",
"webpack": "^5.77.0",
"typescript": "^5.0.4",
"webpack": "^5.78.0",
"webpack-cli": "^5.0.1",
"webpack-dev-server": "^4.13.2"
},

View File

@ -9,6 +9,8 @@ export type RequestType = typeof RequestType[keyof typeof RequestType];
export declare const ResponseType: {
readonly volume: "volume";
readonly inputData: "inputData";
readonly start_ok: "start_ok";
readonly stop_ok: "stop_ok";
};
export type ResponseType = typeof ResponseType[keyof typeof ResponseType];
export type VoiceChangerWorkletProcessorRequest = {

View File

@ -181,12 +181,12 @@ export class VoiceChangerClient {
return this.currentMediaStreamAudioDestinationNode.stream
}
start = () => {
this.vcInNode.start()
start = async () => {
await this.vcInNode.start()
this._isVoiceChanging = true
}
stop = () => {
this.vcInNode.stop()
stop = async () => {
await this.vcInNode.stop()
this._isVoiceChanging = false
}

View File

@ -23,6 +23,12 @@ export class VoiceChangerWorkletNode extends AudioWorkletNode {
private recordingOutputChunk: Float32Array[] = []
private outputNode: VoiceChangerWorkletNode | null = null
// Promises
private startPromiseResolve: ((value: void | PromiseLike<void>) => void) | null = null
private stopPromiseResolve: ((value: void | PromiseLike<void>) => void) | null = null
constructor(context: AudioContext, listener: VoiceChangerWorkletListener) {
super(context, "voice-changer-worklet-processor");
this.port.onmessage = this.handleMessage.bind(this);
@ -157,10 +163,19 @@ export class VoiceChangerWorkletNode extends AudioWorkletNode {
}
return result;
}
handleMessage(event: any) {
// console.log(`[Node:handleMessage_] `, event.data.volume);
if (event.data.responseType === "volume") {
if (event.data.responseType === "start_ok") {
if (this.startPromiseResolve) {
this.startPromiseResolve()
this.startPromiseResolve = null
}
} else if (event.data.responseType === "stop_ok") {
if (this.stopPromiseResolve) {
this.stopPromiseResolve()
this.stopPromiseResolve = null
}
} else if (event.data.responseType === "volume") {
this.listener.notifyVolume(event.data.volume as number)
} else if (event.data.responseType === "inputData") {
const inputData = event.data.inputData as Float32Array
@ -270,7 +285,10 @@ export class VoiceChangerWorkletNode extends AudioWorkletNode {
this.port.postMessage(req)
}
start = () => {
start = async () => {
const p = new Promise<void>((resolve) => {
this.startPromiseResolve = resolve
})
const req: VoiceChangerWorkletProcessorRequest = {
requestType: "start",
voice: new Float32Array(1),
@ -279,9 +297,13 @@ export class VoiceChangerWorkletNode extends AudioWorkletNode {
volTrancateLength: 0
}
this.port.postMessage(req)
await p
}
stop = () => {
stop = async () => {
const p = new Promise<void>((resolve) => {
this.stopPromiseResolve = resolve
})
const req: VoiceChangerWorkletProcessorRequest = {
requestType: "stop",
voice: new Float32Array(1),
@ -290,6 +312,7 @@ export class VoiceChangerWorkletNode extends AudioWorkletNode {
volTrancateLength: 0
}
this.port.postMessage(req)
await p
}
trancateBuffer = () => {
const req: VoiceChangerWorkletProcessorRequest = {

View File

@ -97,14 +97,14 @@ export const useClientSetting = (props: UseClientSettingProps): ClientSettingSta
return async () => {
if (!props.voiceChangerClient) return
// props.voiceChangerClient.setServerUrl(setting.mmvcServerUrl, true)
props.voiceChangerClient.start()
await props.voiceChangerClient.start()
}
}, [props.voiceChangerClient])
// (2) stop
const stop = useMemo(() => {
return async () => {
if (!props.voiceChangerClient) return
props.voiceChangerClient.stop()
await props.voiceChangerClient.stop()
}
}, [props.voiceChangerClient])
const reloadClientSetting = useMemo(() => {

View File

@ -10,7 +10,9 @@ export type RequestType = typeof RequestType[keyof typeof RequestType]
export const ResponseType = {
"volume": "volume",
"inputData": "inputData"
"inputData": "inputData",
"start_ok": "start_ok",
"stop_ok": "stop_ok",
} as const
export type ResponseType = typeof ResponseType[keyof typeof ResponseType]
@ -80,6 +82,10 @@ class VoiceChangerWorkletProcessor extends AudioWorkletProcessor {
return
}
this.isRecording = true
const startResponse: VoiceChangerWorkletProcessorResponse = {
responseType: "start_ok",
}
this.port.postMessage(startResponse);
return
} else if (request.requestType === "stop") {
if (!this.isRecording) {
@ -87,6 +93,10 @@ class VoiceChangerWorkletProcessor extends AudioWorkletProcessor {
return
}
this.isRecording = false
const stopResponse: VoiceChangerWorkletProcessorResponse = {
responseType: "stop_ok",
}
this.port.postMessage(stopResponse);
return
} else if (request.requestType === "trancateBuffer") {
this.trancateBuffer()

View File

@ -63,7 +63,6 @@ class MMVCv15:
else:
self.settings.onnxModelFile = ""
print("self.settings.onnxModelFile::", self.settings.onnxModelFile)
# PyTorchモデル生成
self.net_g = SynthesizerTrn(
spec_channels=self.hps.data.filter_length // 2 + 1,