diff --git a/client/demo/dist/index.js b/client/demo/dist/index.js index 253e40ee..b05d24ac 100644 --- a/client/demo/dist/index.js +++ b/client/demo/dist/index.js @@ -323,7 +323,7 @@ eval("var __filename = \"/index.js\";\n__webpack_require__.r(__webpack_exports__ /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { "use strict"; -eval("var __filename = \"/index.js\";\n__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ SampleDownloaderScreen: () => (/* binding */ SampleDownloaderScreen)\n/* harmony export */ });\n/* harmony import */ var _babel_runtime_helpers_defineProperty__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @babel/runtime/helpers/defineProperty */ \"./node_modules/@babel/runtime/helpers/esm/defineProperty.js\");\n/* harmony import */ var _babel_runtime_helpers_asyncToGenerator__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @babel/runtime/helpers/asyncToGenerator */ \"./node_modules/@babel/runtime/helpers/esm/asyncToGenerator.js\");\n/* harmony import */ var _babel_runtime_helpers_slicedToArray__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! @babel/runtime/helpers/slicedToArray */ \"./node_modules/@babel/runtime/helpers/esm/slicedToArray.js\");\n/* harmony import */ var _babel_runtime_regenerator__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! @babel/runtime/regenerator */ \"./node_modules/@babel/runtime/regenerator/index.js\");\n/* harmony import */ var _babel_runtime_regenerator__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(_babel_runtime_regenerator__WEBPACK_IMPORTED_MODULE_3__);\n/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! react */ \"./node_modules/react/index.js\");\n/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_4___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_4__);\n/* harmony import */ var _001_provider_001_AppStateProvider__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../../001_provider/001_AppStateProvider */ \"./src/001_provider/001_AppStateProvider.tsx\");\n/* harmony import */ var _dannadori_voice_changer_client_js__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! @dannadori/voice-changer-client-js */ \"./node_modules/@dannadori/voice-changer-client-js/dist/index.js\");\n/* harmony import */ var _dannadori_voice_changer_client_js__WEBPACK_IMPORTED_MODULE_6___default = /*#__PURE__*/__webpack_require__.n(_dannadori_voice_changer_client_js__WEBPACK_IMPORTED_MODULE_6__);\n/* harmony import */ var _hooks_useMessageBuilder__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../../hooks/useMessageBuilder */ \"./src/hooks/useMessageBuilder.ts\");\n\n\n\n\nfunction ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }\nfunction _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { (0,_babel_runtime_helpers_defineProperty__WEBPACK_IMPORTED_MODULE_0__[\"default\"])(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }\n\n\n\n\nvar SampleDownloaderScreen = function SampleDownloaderScreen(props) {\n var _useAppState = (0,_001_provider_001_AppStateProvider__WEBPACK_IMPORTED_MODULE_5__.useAppState)(),\n serverSetting = _useAppState.serverSetting;\n var _useState = (0,react__WEBPACK_IMPORTED_MODULE_4__.useState)(\"All\"),\n _useState2 = (0,_babel_runtime_helpers_slicedToArray__WEBPACK_IMPORTED_MODULE_2__[\"default\"])(_useState, 2),\n lang = _useState2[0],\n setLang = _useState2[1];\n var messageBuilderState = (0,_hooks_useMessageBuilder__WEBPACK_IMPORTED_MODULE_7__.useMessageBuilder)();\n (0,react__WEBPACK_IMPORTED_MODULE_4__.useMemo)(function () {\n messageBuilderState.setMessage(__filename, \"header_message\", {\n \"ja\": \"サンプルをダウンロードしてください. 対象:\",\n \"en\": \"Download Sample for\"\n });\n messageBuilderState.setMessage(__filename, \"lang\", {\n \"ja\": \"言語\",\n \"en\": \"Lang\"\n });\n messageBuilderState.setMessage(__filename, \"back\", {\n \"ja\": \"戻る\",\n \"en\": \"back\"\n });\n messageBuilderState.setMessage(__filename, \"terms_of_use\", {\n \"ja\": \"利用規約\",\n \"en\": \"terms of use\"\n });\n messageBuilderState.setMessage(__filename, \"download\", {\n \"ja\": \"ダウンロード\",\n \"en\": \"download\"\n });\n }, []);\n\n /////////////////////////////////////////\n // Sample Downloader\n /////////////////////////////////////////\n var screen = (0,react__WEBPACK_IMPORTED_MODULE_4__.useMemo)(function () {\n if (props.screen != \"SampleDownloader\") {\n return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_4___default().createElement((react__WEBPACK_IMPORTED_MODULE_4___default().Fragment), null);\n }\n if (!serverSetting.serverSetting.modelSlots) {\n return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_4___default().createElement((react__WEBPACK_IMPORTED_MODULE_4___default().Fragment), null);\n }\n var langs = serverSetting.serverSetting.sampleModels.reduce(function (prev, cur) {\n if (prev.includes(cur.lang) == false) {\n prev.push(cur.lang);\n }\n return prev;\n }, [\"All\"]);\n var langOptions = langs.map(function (x) {\n return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_4___default().createElement(\"option\", {\n key: x,\n value: x\n }, x);\n });\n var onDownloadSampleClicked = /*#__PURE__*/function () {\n var _ref = (0,_babel_runtime_helpers_asyncToGenerator__WEBPACK_IMPORTED_MODULE_1__[\"default\"])( /*#__PURE__*/_babel_runtime_regenerator__WEBPACK_IMPORTED_MODULE_3___default().mark(function _callee(id) {\n return _babel_runtime_regenerator__WEBPACK_IMPORTED_MODULE_3___default().wrap(function _callee$(_context) {\n while (1) switch (_context.prev = _context.next) {\n case 0:\n serverSetting.fileUploadSettings[props.targetIndex] = _objectSpread(_objectSpread({}, _dannadori_voice_changer_client_js__WEBPACK_IMPORTED_MODULE_6__.InitialFileUploadSetting), {}, {\n rvcModel: null,\n rvcIndex: null,\n sampleId: id,\n isSampleMode: true\n });\n _context.prev = 1;\n _context.next = 4;\n return serverSetting.loadModel(props.targetIndex);\n case 4:\n _context.next = 9;\n break;\n case 6:\n _context.prev = 6;\n _context.t0 = _context[\"catch\"](1);\n alert(_context.t0);\n case 9:\n props.backToSlotManager();\n // setMode(\"localFile\")\n case 10:\n case \"end\":\n return _context.stop();\n }\n }, _callee, null, [[1, 6]]);\n }));\n return function onDownloadSampleClicked(_x) {\n return _ref.apply(this, arguments);\n };\n }();\n var options = serverSetting.serverSetting.sampleModels.filter(function (x) {\n return lang == \"All\" ? true : x.lang == lang;\n }).map(function (x, index) {\n var termOfUseUrlLink = x.termsOfUseUrl && x.termsOfUseUrl.length > 0 ? /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_4___default().createElement(\"a\", {\n href: x.termsOfUseUrl,\n target: \"_blank\",\n rel: \"noopener noreferrer\",\n className: \"body-item-text-small\"\n }, \"[\", messageBuilderState.getMessage(__filename, \"terms_of_use\"), \"]\") : /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_4___default().createElement((react__WEBPACK_IMPORTED_MODULE_4___default().Fragment), null);\n return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_4___default().createElement(\"div\", {\n key: index,\n className: \"model-slot\"\n }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_4___default().createElement(\"img\", {\n src: x.icon,\n className: \"model-slot-icon\"\n }), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_4___default().createElement(\"div\", {\n className: \"model-slot-detail\"\n }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_4___default().createElement(\"div\", {\n className: \"model-slot-detail-row\"\n }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_4___default().createElement(\"div\", {\n className: \"model-slot-detail-row-label\"\n }, \"name:\"), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_4___default().createElement(\"div\", {\n className: \"model-slot-detail-row-value\"\n }, x.name), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_4___default().createElement(\"div\", {\n className: \"\"\n }, termOfUseUrlLink)), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_4___default().createElement(\"div\", {\n className: \"model-slot-detail-row\"\n }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_4___default().createElement(\"div\", {\n className: \"model-slot-detail-row-label\"\n }, \"info: \"), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_4___default().createElement(\"div\", {\n className: \"model-slot-detail-row-value\"\n }, x.modelType, \",\", x.f0 ? \"f0\" : \"nof0\", \",\", x.sampleRate), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_4___default().createElement(\"div\", {\n className: \"\"\n }))), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_4___default().createElement(\"div\", {\n className: \"model-slot-buttons\"\n }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_4___default().createElement(\"div\", {\n className: \"model-slot-button\",\n onClick: function onClick() {\n onDownloadSampleClicked(x.id);\n }\n }, messageBuilderState.getMessage(__filename, \"download\"))));\n });\n return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_4___default().createElement(\"div\", {\n className: \"dialog-frame\"\n }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_4___default().createElement(\"div\", {\n className: \"dialog-title\"\n }, \"Sample Downloader\"), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_4___default().createElement(\"div\", {\n className: \"dialog-fixed-size-content\"\n }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_4___default().createElement(\"div\", {\n className: \"model-slot-header\"\n }, messageBuilderState.getMessage(__filename, \"header_message\"), \" Slot[\", props.targetIndex, \"]\", /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_4___default().createElement(\"span\", {\n onClick: function onClick() {\n props.backToSlotManager();\n },\n className: \"model-slot-header-button\"\n }, \"<<\", messageBuilderState.getMessage(__filename, \"back\"))), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_4___default().createElement(\"div\", null, messageBuilderState.getMessage(__filename, \"lang\"), \":\", /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_4___default().createElement(\"select\", {\n value: lang,\n onChange: function onChange(e) {\n setLang(e.target.value);\n }\n }, langOptions)), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_4___default().createElement(\"div\", {\n className: \"model-slot-container\"\n }, options)));\n }, [props.screen, props.targetIndex, lang, serverSetting.serverSetting]);\n return screen;\n};\n\n//# sourceURL=webpack://demo/./src/components/demo/904-2_SampleDownloader.tsx?"); +eval("var __filename = \"/index.js\";\n__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ SampleDownloaderScreen: () => (/* binding */ SampleDownloaderScreen)\n/* harmony export */ });\n/* harmony import */ var _babel_runtime_helpers_asyncToGenerator__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @babel/runtime/helpers/asyncToGenerator */ \"./node_modules/@babel/runtime/helpers/esm/asyncToGenerator.js\");\n/* harmony import */ var _babel_runtime_helpers_slicedToArray__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @babel/runtime/helpers/slicedToArray */ \"./node_modules/@babel/runtime/helpers/esm/slicedToArray.js\");\n/* harmony import */ var _babel_runtime_regenerator__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! @babel/runtime/regenerator */ \"./node_modules/@babel/runtime/regenerator/index.js\");\n/* harmony import */ var _babel_runtime_regenerator__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(_babel_runtime_regenerator__WEBPACK_IMPORTED_MODULE_2__);\n/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! react */ \"./node_modules/react/index.js\");\n/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_3__);\n/* harmony import */ var _001_provider_001_AppStateProvider__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../../001_provider/001_AppStateProvider */ \"./src/001_provider/001_AppStateProvider.tsx\");\n/* harmony import */ var _hooks_useMessageBuilder__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../../hooks/useMessageBuilder */ \"./src/hooks/useMessageBuilder.ts\");\n\n\n\n\n\n\nvar SampleDownloaderScreen = function SampleDownloaderScreen(props) {\n var _useAppState = (0,_001_provider_001_AppStateProvider__WEBPACK_IMPORTED_MODULE_4__.useAppState)(),\n serverSetting = _useAppState.serverSetting;\n var _useState = (0,react__WEBPACK_IMPORTED_MODULE_3__.useState)(\"All\"),\n _useState2 = (0,_babel_runtime_helpers_slicedToArray__WEBPACK_IMPORTED_MODULE_1__[\"default\"])(_useState, 2),\n lang = _useState2[0],\n setLang = _useState2[1];\n var messageBuilderState = (0,_hooks_useMessageBuilder__WEBPACK_IMPORTED_MODULE_5__.useMessageBuilder)();\n (0,react__WEBPACK_IMPORTED_MODULE_3__.useMemo)(function () {\n messageBuilderState.setMessage(__filename, \"header_message\", {\n \"ja\": \"サンプルをダウンロードしてください. 対象:\",\n \"en\": \"Download Sample for\"\n });\n messageBuilderState.setMessage(__filename, \"lang\", {\n \"ja\": \"言語\",\n \"en\": \"Lang\"\n });\n messageBuilderState.setMessage(__filename, \"back\", {\n \"ja\": \"戻る\",\n \"en\": \"back\"\n });\n messageBuilderState.setMessage(__filename, \"terms_of_use\", {\n \"ja\": \"利用規約\",\n \"en\": \"terms of use\"\n });\n messageBuilderState.setMessage(__filename, \"download\", {\n \"ja\": \"ダウンロード\",\n \"en\": \"download\"\n });\n }, []);\n\n /////////////////////////////////////////\n // Sample Downloader\n /////////////////////////////////////////\n var screen = (0,react__WEBPACK_IMPORTED_MODULE_3__.useMemo)(function () {\n if (props.screen != \"SampleDownloader\") {\n return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_3___default().createElement((react__WEBPACK_IMPORTED_MODULE_3___default().Fragment), null);\n }\n if (!serverSetting.serverSetting.modelSlots) {\n return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_3___default().createElement((react__WEBPACK_IMPORTED_MODULE_3___default().Fragment), null);\n }\n var langs = serverSetting.serverSetting.sampleModels.reduce(function (prev, cur) {\n if (prev.includes(cur.lang) == false) {\n prev.push(cur.lang);\n }\n return prev;\n }, [\"All\"]);\n var langOptions = langs.map(function (x) {\n return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_3___default().createElement(\"option\", {\n key: x,\n value: x\n }, x);\n });\n var onDownloadSampleClicked = /*#__PURE__*/function () {\n var _ref = (0,_babel_runtime_helpers_asyncToGenerator__WEBPACK_IMPORTED_MODULE_0__[\"default\"])( /*#__PURE__*/_babel_runtime_regenerator__WEBPACK_IMPORTED_MODULE_2___default().mark(function _callee(id) {\n var uploadParams;\n return _babel_runtime_regenerator__WEBPACK_IMPORTED_MODULE_2___default().wrap(function _callee$(_context) {\n while (1) switch (_context.prev = _context.next) {\n case 0:\n uploadParams = {\n voiceChangerType: \"RVC\",\n slot: props.targetIndex,\n isSampleMode: true,\n sampleId: id,\n files: [],\n params: {\n rvcIndexDownload: true\n }\n };\n _context.prev = 1;\n _context.next = 4;\n return serverSetting.uploadModel(uploadParams);\n case 4:\n _context.next = 9;\n break;\n case 6:\n _context.prev = 6;\n _context.t0 = _context[\"catch\"](1);\n alert(_context.t0);\n case 9:\n props.backToSlotManager();\n // setMode(\"localFile\")\n case 10:\n case \"end\":\n return _context.stop();\n }\n }, _callee, null, [[1, 6]]);\n }));\n return function onDownloadSampleClicked(_x) {\n return _ref.apply(this, arguments);\n };\n }();\n var options = serverSetting.serverSetting.sampleModels.filter(function (x) {\n return lang == \"All\" ? true : x.lang == lang;\n }).map(function (x, index) {\n var termOfUseUrlLink = x.termsOfUseUrl && x.termsOfUseUrl.length > 0 ? /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_3___default().createElement(\"a\", {\n href: x.termsOfUseUrl,\n target: \"_blank\",\n rel: \"noopener noreferrer\",\n className: \"body-item-text-small\"\n }, \"[\", messageBuilderState.getMessage(__filename, \"terms_of_use\"), \"]\") : /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_3___default().createElement((react__WEBPACK_IMPORTED_MODULE_3___default().Fragment), null);\n return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_3___default().createElement(\"div\", {\n key: index,\n className: \"model-slot\"\n }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_3___default().createElement(\"img\", {\n src: x.icon,\n className: \"model-slot-icon\"\n }), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_3___default().createElement(\"div\", {\n className: \"model-slot-detail\"\n }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_3___default().createElement(\"div\", {\n className: \"model-slot-detail-row\"\n }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_3___default().createElement(\"div\", {\n className: \"model-slot-detail-row-label\"\n }, \"name:\"), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_3___default().createElement(\"div\", {\n className: \"model-slot-detail-row-value\"\n }, x.name), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_3___default().createElement(\"div\", {\n className: \"\"\n }, termOfUseUrlLink)), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_3___default().createElement(\"div\", {\n className: \"model-slot-detail-row\"\n }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_3___default().createElement(\"div\", {\n className: \"model-slot-detail-row-label\"\n }, \"info: \"), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_3___default().createElement(\"div\", {\n className: \"model-slot-detail-row-value\"\n }, x.modelType, \",\", x.f0 ? \"f0\" : \"nof0\", \",\", x.sampleRate), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_3___default().createElement(\"div\", {\n className: \"\"\n }))), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_3___default().createElement(\"div\", {\n className: \"model-slot-buttons\"\n }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_3___default().createElement(\"div\", {\n className: \"model-slot-button\",\n onClick: function onClick() {\n onDownloadSampleClicked(x.id);\n }\n }, messageBuilderState.getMessage(__filename, \"download\"))));\n });\n return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_3___default().createElement(\"div\", {\n className: \"dialog-frame\"\n }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_3___default().createElement(\"div\", {\n className: \"dialog-title\"\n }, \"Sample Downloader\"), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_3___default().createElement(\"div\", {\n className: \"dialog-fixed-size-content\"\n }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_3___default().createElement(\"div\", {\n className: \"model-slot-header\"\n }, messageBuilderState.getMessage(__filename, \"header_message\"), \" Slot[\", props.targetIndex, \"]\", /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_3___default().createElement(\"span\", {\n onClick: function onClick() {\n props.backToSlotManager();\n },\n className: \"model-slot-header-button\"\n }, \"<<\", messageBuilderState.getMessage(__filename, \"back\"))), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_3___default().createElement(\"div\", null, messageBuilderState.getMessage(__filename, \"lang\"), \":\", /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_3___default().createElement(\"select\", {\n value: lang,\n onChange: function onChange(e) {\n setLang(e.target.value);\n }\n }, langOptions)), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_3___default().createElement(\"div\", {\n className: \"model-slot-container\"\n }, options)));\n }, [props.screen, props.targetIndex, lang, serverSetting.serverSetting]);\n return screen;\n};\n\n//# sourceURL=webpack://demo/./src/components/demo/904-2_SampleDownloader.tsx?"); /***/ }), @@ -334,7 +334,7 @@ eval("var __filename = \"/index.js\";\n__webpack_require__.r(__webpack_exports__ /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { "use strict"; -eval("var __filename = \"/index.js\";\n__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ FileUploaderScreen: () => (/* binding */ FileUploaderScreen)\n/* harmony export */ });\n/* harmony import */ var _babel_runtime_helpers_defineProperty__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @babel/runtime/helpers/defineProperty */ \"./node_modules/@babel/runtime/helpers/esm/defineProperty.js\");\n/* harmony import */ var _babel_runtime_helpers_asyncToGenerator__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @babel/runtime/helpers/asyncToGenerator */ \"./node_modules/@babel/runtime/helpers/esm/asyncToGenerator.js\");\n/* harmony import */ var _babel_runtime_helpers_slicedToArray__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! @babel/runtime/helpers/slicedToArray */ \"./node_modules/@babel/runtime/helpers/esm/slicedToArray.js\");\n/* harmony import */ var _babel_runtime_regenerator__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! @babel/runtime/regenerator */ \"./node_modules/@babel/runtime/regenerator/index.js\");\n/* harmony import */ var _babel_runtime_regenerator__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(_babel_runtime_regenerator__WEBPACK_IMPORTED_MODULE_3__);\n/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! react */ \"./node_modules/react/index.js\");\n/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_4___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_4__);\n/* harmony import */ var _001_provider_001_AppStateProvider__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../../001_provider/001_AppStateProvider */ \"./src/001_provider/001_AppStateProvider.tsx\");\n/* harmony import */ var _dannadori_voice_changer_client_js__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! @dannadori/voice-changer-client-js */ \"./node_modules/@dannadori/voice-changer-client-js/dist/index.js\");\n/* harmony import */ var _dannadori_voice_changer_client_js__WEBPACK_IMPORTED_MODULE_6___default = /*#__PURE__*/__webpack_require__.n(_dannadori_voice_changer_client_js__WEBPACK_IMPORTED_MODULE_6__);\n/* harmony import */ var _hooks_useMessageBuilder__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../../hooks/useMessageBuilder */ \"./src/hooks/useMessageBuilder.ts\");\n/* harmony import */ var _utils_utils__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../../utils/utils */ \"./src/utils/utils.ts\");\n\n\n\n\nfunction ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }\nfunction _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { (0,_babel_runtime_helpers_defineProperty__WEBPACK_IMPORTED_MODULE_0__[\"default\"])(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }\n\n\n\n\n\nvar FileUploaderScreen = function FileUploaderScreen(props) {\n var _useAppState = (0,_001_provider_001_AppStateProvider__WEBPACK_IMPORTED_MODULE_5__.useAppState)(),\n serverSetting = _useAppState.serverSetting;\n var _useState = (0,react__WEBPACK_IMPORTED_MODULE_4__.useState)(\"RVC\"),\n _useState2 = (0,_babel_runtime_helpers_slicedToArray__WEBPACK_IMPORTED_MODULE_2__[\"default\"])(_useState, 2),\n voiceChangerType = _useState2[0],\n setVoiceChangerType = _useState2[1];\n var _useState3 = (0,react__WEBPACK_IMPORTED_MODULE_4__.useState)(),\n _useState4 = (0,_babel_runtime_helpers_slicedToArray__WEBPACK_IMPORTED_MODULE_2__[\"default\"])(_useState3, 2),\n uploadSetting = _useState4[0],\n setUploadSetting = _useState4[1];\n var messageBuilderState = (0,_hooks_useMessageBuilder__WEBPACK_IMPORTED_MODULE_7__.useMessageBuilder)();\n (0,react__WEBPACK_IMPORTED_MODULE_4__.useMemo)(function () {\n messageBuilderState.setMessage(__filename, \"header_message\", {\n \"ja\": \"ファイルをアップロードしてください. 対象:\",\n \"en\": \"Upload Files for \"\n });\n messageBuilderState.setMessage(__filename, \"back\", {\n \"ja\": \"戻る\",\n \"en\": \"back\"\n });\n messageBuilderState.setMessage(__filename, \"select\", {\n \"ja\": \"ファイル選択\",\n \"en\": \"select file\"\n });\n messageBuilderState.setMessage(__filename, \"upload\", {\n \"ja\": \"アップロード\",\n \"en\": \"upload\"\n });\n messageBuilderState.setMessage(__filename, \"uploading\", {\n \"ja\": \"アップロード中\",\n \"en\": \"uploading\"\n });\n messageBuilderState.setMessage(__filename, \"alert-model-ext\", {\n \"ja\": \"ファイルの拡張子は次のモノである必要があります。\",\n \"en\": \"extension of file should be the following.\"\n });\n messageBuilderState.setMessage(__filename, \"alert-model-file\", {\n \"ja\": \"ファイルが選択されていません\",\n \"en\": \"file is not selected.\"\n });\n }, []);\n (0,react__WEBPACK_IMPORTED_MODULE_4__.useEffect)(function () {\n setUploadSetting({\n voiceChangerType: voiceChangerType,\n slot: props.targetIndex,\n isSampleMode: false,\n sampleId: null,\n files: []\n });\n }, [props.targetIndex, voiceChangerType]);\n var screen = (0,react__WEBPACK_IMPORTED_MODULE_4__.useMemo)(function () {\n if (props.screen != \"FileUploader\") {\n return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_4___default().createElement((react__WEBPACK_IMPORTED_MODULE_4___default().Fragment), null);\n }\n var vcTypeOptions = Object.values(_dannadori_voice_changer_client_js__WEBPACK_IMPORTED_MODULE_6__.VoiceChangerType).map(function (x) {\n return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_4___default().createElement(\"option\", {\n key: x,\n value: x\n }, x);\n });\n var checkModelSetting = function checkModelSetting(setting) {\n if (setting.voiceChangerType == \"RVC\") {\n var enough = !!setting.files.find(function (x) {\n return x.kind == \"rvcModel\";\n });\n return enough;\n } else if (setting.voiceChangerType == \"MMVCv13\") {\n var _enough = !!setting.files.find(function (x) {\n return x.kind == \"mmvcv13Model\";\n }) && !!setting.files.find(function (x) {\n return x.kind == \"mmvcv13Config\";\n });\n return _enough;\n } else if (setting.voiceChangerType == \"MMVCv15\") {\n var _enough2 = !!setting.files.find(function (x) {\n return x.kind == \"mmvcv15Model\";\n }) && !!setting.files.find(function (x) {\n return x.kind == \"mmvcv15Config\";\n });\n return _enough2;\n } else if (setting.voiceChangerType == \"so-vits-svc-40\") {\n var _enough3 = !!setting.files.find(function (x) {\n return x.kind == \"soVitsSvc40Config\";\n }) && !!setting.files.find(function (x) {\n return x.kind == \"soVitsSvc40Model\";\n });\n return _enough3;\n } else if (setting.voiceChangerType == \"DDSP-SVC\") {\n var _enough4 = !!setting.files.find(function (x) {\n return x.kind == \"ddspSvcModel\";\n }) && !!setting.files.find(function (x) {\n return x.kind == \"ddspSvcModelConfig\";\n }) && !!setting.files.find(function (x) {\n return x.kind == \"ddspSvcDiffusion\";\n }) && !!setting.files.find(function (x) {\n return x.kind == \"ddspSvcDiffusionConfig\";\n });\n return _enough4;\n }\n return false;\n };\n var generateFileRow = function generateFileRow(setting, title, kind, ext) {\n var dir = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : \"\";\n var selectedFile = setting.files.find(function (x) {\n return x.kind == kind;\n });\n var selectedFilename = (selectedFile === null || selectedFile === void 0 ? void 0 : selectedFile.file.name) || \"\";\n return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_4___default().createElement(\"div\", {\n key: \"\".concat(title),\n className: \"file-uploader-file-select-row\"\n }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_4___default().createElement(\"div\", {\n className: \"file-uploader-file-select-row-label\"\n }, title, \":\"), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_4___default().createElement(\"div\", {\n className: \"file-uploader-file-select-row-value\"\n }, (0,_utils_utils__WEBPACK_IMPORTED_MODULE_8__.trimfileName)(selectedFilename, 30)), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_4___default().createElement(\"div\", {\n className: \"file-uploader-file-select-row-button\",\n onClick: /*#__PURE__*/(0,_babel_runtime_helpers_asyncToGenerator__WEBPACK_IMPORTED_MODULE_1__[\"default\"])( /*#__PURE__*/_babel_runtime_regenerator__WEBPACK_IMPORTED_MODULE_3___default().mark(function _callee() {\n var file, alertMessage;\n return _babel_runtime_regenerator__WEBPACK_IMPORTED_MODULE_3___default().wrap(function _callee$(_context) {\n while (1) switch (_context.prev = _context.next) {\n case 0:\n _context.next = 2;\n return (0,_dannadori_voice_changer_client_js__WEBPACK_IMPORTED_MODULE_6__.fileSelector)(\"\");\n case 2:\n file = _context.sent;\n if (!((0,_utils_utils__WEBPACK_IMPORTED_MODULE_8__.checkExtention)(file.name, ext) == false)) {\n _context.next = 7;\n break;\n }\n alertMessage = \"\".concat(messageBuilderState.getMessage(__filename, \"alert-model-ext\"), \" \").concat(ext);\n alert(alertMessage);\n return _context.abrupt(\"return\");\n case 7:\n if (selectedFile) {\n selectedFile.file = file;\n } else {\n setting.files.push({\n kind: kind,\n file: file,\n dir: dir\n });\n }\n setUploadSetting(_objectSpread({}, setting));\n case 9:\n case \"end\":\n return _context.stop();\n }\n }, _callee);\n }))\n }, messageBuilderState.getMessage(__filename, \"select\")));\n };\n var generateFileRowsByVCType = function generateFileRowsByVCType(vcType) {\n var rows = [];\n if (vcType == \"RVC\") {\n rows.push(generateFileRow(uploadSetting, \"Model\", \"rvcModel\", [\"pth\", \"onnx\"]));\n rows.push(generateFileRow(uploadSetting, \"Index\", \"rvcIndex\", [\"index\", \"bin\"]));\n } else if (vcType == \"MMVCv13\") {\n rows.push(generateFileRow(uploadSetting, \"Config\", \"mmvcv13Config\", [\"json\"]));\n rows.push(generateFileRow(uploadSetting, \"Model\", \"mmvcv13Model\", [\"pth\", \"onnx\"]));\n } else if (vcType == \"MMVCv15\") {\n rows.push(generateFileRow(uploadSetting, \"Config\", \"mmvcv15Config\", [\"json\"]));\n rows.push(generateFileRow(uploadSetting, \"Model\", \"mmvcv15Model\", [\"pth\", \"onnx\"]));\n } else if (vcType == \"so-vits-svc-40\") {\n rows.push(generateFileRow(uploadSetting, \"Config\", \"soVitsSvc40Config\", [\"json\"]));\n rows.push(generateFileRow(uploadSetting, \"Model\", \"soVitsSvc40Model\", [\"pth\"]));\n rows.push(generateFileRow(uploadSetting, \"Cluster\", \"soVitsSvc40Cluster\", [\"pth\", \"pt\"]));\n } else if (vcType == \"DDSP-SVC\") {\n rows.push(generateFileRow(uploadSetting, \"Config\", \"ddspSvcModelConfig\", [\"yaml\"], \"model/\"));\n rows.push(generateFileRow(uploadSetting, \"Model\", \"ddspSvcModel\", [\"pth\", \"pt\"], \"model/\"));\n rows.push(generateFileRow(uploadSetting, \"Config(diff)\", \"ddspSvcDiffusionConfig\", [\"yaml\"], \"diff/\"));\n rows.push(generateFileRow(uploadSetting, \"Model(diff)\", \"ddspSvcDiffusion\", [\"pth\", \"pt\"], \"diff/\"));\n }\n return rows;\n };\n var fileRows = generateFileRowsByVCType(voiceChangerType);\n\n // appState.serverSetting.uploadProgress == 0 ? `loading model...(wait about 20sec)` : `processing.... ${appState.serverSetting.uploadProgress.toFixed(1)}%` : \"\"\n\n var buttonLabel = serverSetting.uploadProgress == 0 ? messageBuilderState.getMessage(__filename, \"upload\") : messageBuilderState.getMessage(__filename, \"uploading\") + \"(\".concat(serverSetting.uploadProgress.toFixed(1), \"%)\");\n return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_4___default().createElement(\"div\", {\n className: \"dialog-frame\"\n }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_4___default().createElement(\"div\", {\n className: \"dialog-title\"\n }, \"File Uploader\"), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_4___default().createElement(\"div\", {\n className: \"dialog-fixed-size-content\"\n }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_4___default().createElement(\"div\", {\n className: \"file-uploader-header\"\n }, messageBuilderState.getMessage(__filename, \"header_message\"), \" Slot[\", props.targetIndex, \"]\", /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_4___default().createElement(\"span\", {\n onClick: function onClick() {\n props.backToSlotManager();\n },\n className: \"file-uploader-header-button\"\n }, \"<<\", messageBuilderState.getMessage(__filename, \"back\"))), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_4___default().createElement(\"div\", {\n className: \"file-uploader-voice-changer-select\"\n }, \"VoiceChangerType:\", /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_4___default().createElement(\"select\", {\n value: voiceChangerType,\n onChange: function onChange(e) {\n setVoiceChangerType(e.target.value);\n }\n }, vcTypeOptions)), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_4___default().createElement(\"div\", {\n className: \"file-uploader-file-select-container\"\n }, fileRows), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_4___default().createElement(\"div\", {\n className: \"file-uploader-file-select-upload-button-container\"\n }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_4___default().createElement(\"div\", {\n className: \"file-uploader-file-select-upload-button\",\n onClick: function onClick() {\n if (!uploadSetting) {\n return;\n }\n if (serverSetting.uploadProgress != 0) {\n return;\n }\n if (checkModelSetting(uploadSetting)) {\n serverSetting.uploadModel(uploadSetting);\n } else {\n var errorMessage = messageBuilderState.getMessage(__filename, \"alert-model-file\");\n alert(errorMessage);\n }\n }\n }, buttonLabel))));\n }, [props.screen, props.targetIndex, voiceChangerType, uploadSetting, serverSetting.uploadModel, serverSetting.uploadProgress]);\n return screen;\n};\n\n//# sourceURL=webpack://demo/./src/components/demo/904-3_FileUploader.tsx?"); +eval("var __filename = \"/index.js\";\n__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ FileUploaderScreen: () => (/* binding */ FileUploaderScreen)\n/* harmony export */ });\n/* harmony import */ var _babel_runtime_helpers_defineProperty__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @babel/runtime/helpers/defineProperty */ \"./node_modules/@babel/runtime/helpers/esm/defineProperty.js\");\n/* harmony import */ var _babel_runtime_helpers_asyncToGenerator__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @babel/runtime/helpers/asyncToGenerator */ \"./node_modules/@babel/runtime/helpers/esm/asyncToGenerator.js\");\n/* harmony import */ var _babel_runtime_helpers_slicedToArray__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! @babel/runtime/helpers/slicedToArray */ \"./node_modules/@babel/runtime/helpers/esm/slicedToArray.js\");\n/* harmony import */ var _babel_runtime_regenerator__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! @babel/runtime/regenerator */ \"./node_modules/@babel/runtime/regenerator/index.js\");\n/* harmony import */ var _babel_runtime_regenerator__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(_babel_runtime_regenerator__WEBPACK_IMPORTED_MODULE_3__);\n/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! react */ \"./node_modules/react/index.js\");\n/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_4___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_4__);\n/* harmony import */ var _001_provider_001_AppStateProvider__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../../001_provider/001_AppStateProvider */ \"./src/001_provider/001_AppStateProvider.tsx\");\n/* harmony import */ var _dannadori_voice_changer_client_js__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! @dannadori/voice-changer-client-js */ \"./node_modules/@dannadori/voice-changer-client-js/dist/index.js\");\n/* harmony import */ var _dannadori_voice_changer_client_js__WEBPACK_IMPORTED_MODULE_6___default = /*#__PURE__*/__webpack_require__.n(_dannadori_voice_changer_client_js__WEBPACK_IMPORTED_MODULE_6__);\n/* harmony import */ var _hooks_useMessageBuilder__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../../hooks/useMessageBuilder */ \"./src/hooks/useMessageBuilder.ts\");\n/* harmony import */ var _utils_utils__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../../utils/utils */ \"./src/utils/utils.ts\");\n\n\n\n\nfunction ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }\nfunction _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { (0,_babel_runtime_helpers_defineProperty__WEBPACK_IMPORTED_MODULE_0__[\"default\"])(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }\n\n\n\n\n\nvar FileUploaderScreen = function FileUploaderScreen(props) {\n var _useAppState = (0,_001_provider_001_AppStateProvider__WEBPACK_IMPORTED_MODULE_5__.useAppState)(),\n serverSetting = _useAppState.serverSetting;\n var _useState = (0,react__WEBPACK_IMPORTED_MODULE_4__.useState)(\"RVC\"),\n _useState2 = (0,_babel_runtime_helpers_slicedToArray__WEBPACK_IMPORTED_MODULE_2__[\"default\"])(_useState, 2),\n voiceChangerType = _useState2[0],\n setVoiceChangerType = _useState2[1];\n var _useState3 = (0,react__WEBPACK_IMPORTED_MODULE_4__.useState)(),\n _useState4 = (0,_babel_runtime_helpers_slicedToArray__WEBPACK_IMPORTED_MODULE_2__[\"default\"])(_useState3, 2),\n uploadSetting = _useState4[0],\n setUploadSetting = _useState4[1];\n var messageBuilderState = (0,_hooks_useMessageBuilder__WEBPACK_IMPORTED_MODULE_7__.useMessageBuilder)();\n (0,react__WEBPACK_IMPORTED_MODULE_4__.useMemo)(function () {\n messageBuilderState.setMessage(__filename, \"header_message\", {\n \"ja\": \"ファイルをアップロードしてください. 対象:\",\n \"en\": \"Upload Files for \"\n });\n messageBuilderState.setMessage(__filename, \"back\", {\n \"ja\": \"戻る\",\n \"en\": \"back\"\n });\n messageBuilderState.setMessage(__filename, \"select\", {\n \"ja\": \"ファイル選択\",\n \"en\": \"select file\"\n });\n messageBuilderState.setMessage(__filename, \"upload\", {\n \"ja\": \"アップロード\",\n \"en\": \"upload\"\n });\n messageBuilderState.setMessage(__filename, \"uploading\", {\n \"ja\": \"アップロード中\",\n \"en\": \"uploading\"\n });\n messageBuilderState.setMessage(__filename, \"alert-model-ext\", {\n \"ja\": \"ファイルの拡張子は次のモノである必要があります。\",\n \"en\": \"extension of file should be the following.\"\n });\n messageBuilderState.setMessage(__filename, \"alert-model-file\", {\n \"ja\": \"ファイルが選択されていません\",\n \"en\": \"file is not selected.\"\n });\n }, []);\n (0,react__WEBPACK_IMPORTED_MODULE_4__.useEffect)(function () {\n setUploadSetting({\n voiceChangerType: voiceChangerType,\n slot: props.targetIndex,\n isSampleMode: false,\n sampleId: null,\n files: [],\n params: {}\n });\n }, [props.targetIndex, voiceChangerType]);\n var screen = (0,react__WEBPACK_IMPORTED_MODULE_4__.useMemo)(function () {\n if (props.screen != \"FileUploader\") {\n return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_4___default().createElement((react__WEBPACK_IMPORTED_MODULE_4___default().Fragment), null);\n }\n var vcTypeOptions = Object.values(_dannadori_voice_changer_client_js__WEBPACK_IMPORTED_MODULE_6__.VoiceChangerType).map(function (x) {\n return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_4___default().createElement(\"option\", {\n key: x,\n value: x\n }, x);\n });\n var checkModelSetting = function checkModelSetting(setting) {\n if (setting.voiceChangerType == \"RVC\") {\n var enough = !!setting.files.find(function (x) {\n return x.kind == \"rvcModel\";\n });\n return enough;\n } else if (setting.voiceChangerType == \"MMVCv13\") {\n var _enough = !!setting.files.find(function (x) {\n return x.kind == \"mmvcv13Model\";\n }) && !!setting.files.find(function (x) {\n return x.kind == \"mmvcv13Config\";\n });\n return _enough;\n } else if (setting.voiceChangerType == \"MMVCv15\") {\n var _enough2 = !!setting.files.find(function (x) {\n return x.kind == \"mmvcv15Model\";\n }) && !!setting.files.find(function (x) {\n return x.kind == \"mmvcv15Config\";\n });\n return _enough2;\n } else if (setting.voiceChangerType == \"so-vits-svc-40\") {\n var _enough3 = !!setting.files.find(function (x) {\n return x.kind == \"soVitsSvc40Config\";\n }) && !!setting.files.find(function (x) {\n return x.kind == \"soVitsSvc40Model\";\n });\n return _enough3;\n } else if (setting.voiceChangerType == \"DDSP-SVC\") {\n var _enough4 = !!setting.files.find(function (x) {\n return x.kind == \"ddspSvcModel\";\n }) && !!setting.files.find(function (x) {\n return x.kind == \"ddspSvcModelConfig\";\n }) && !!setting.files.find(function (x) {\n return x.kind == \"ddspSvcDiffusion\";\n }) && !!setting.files.find(function (x) {\n return x.kind == \"ddspSvcDiffusionConfig\";\n });\n return _enough4;\n }\n return false;\n };\n var generateFileRow = function generateFileRow(setting, title, kind, ext) {\n var dir = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : \"\";\n var selectedFile = setting.files.find(function (x) {\n return x.kind == kind;\n });\n var selectedFilename = (selectedFile === null || selectedFile === void 0 ? void 0 : selectedFile.file.name) || \"\";\n return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_4___default().createElement(\"div\", {\n key: \"\".concat(title),\n className: \"file-uploader-file-select-row\"\n }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_4___default().createElement(\"div\", {\n className: \"file-uploader-file-select-row-label\"\n }, title, \":\"), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_4___default().createElement(\"div\", {\n className: \"file-uploader-file-select-row-value\"\n }, (0,_utils_utils__WEBPACK_IMPORTED_MODULE_8__.trimfileName)(selectedFilename, 30)), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_4___default().createElement(\"div\", {\n className: \"file-uploader-file-select-row-button\",\n onClick: /*#__PURE__*/(0,_babel_runtime_helpers_asyncToGenerator__WEBPACK_IMPORTED_MODULE_1__[\"default\"])( /*#__PURE__*/_babel_runtime_regenerator__WEBPACK_IMPORTED_MODULE_3___default().mark(function _callee() {\n var file, alertMessage;\n return _babel_runtime_regenerator__WEBPACK_IMPORTED_MODULE_3___default().wrap(function _callee$(_context) {\n while (1) switch (_context.prev = _context.next) {\n case 0:\n _context.next = 2;\n return (0,_dannadori_voice_changer_client_js__WEBPACK_IMPORTED_MODULE_6__.fileSelector)(\"\");\n case 2:\n file = _context.sent;\n if (!((0,_utils_utils__WEBPACK_IMPORTED_MODULE_8__.checkExtention)(file.name, ext) == false)) {\n _context.next = 7;\n break;\n }\n alertMessage = \"\".concat(messageBuilderState.getMessage(__filename, \"alert-model-ext\"), \" \").concat(ext);\n alert(alertMessage);\n return _context.abrupt(\"return\");\n case 7:\n if (selectedFile) {\n selectedFile.file = file;\n } else {\n setting.files.push({\n kind: kind,\n file: file,\n dir: dir\n });\n }\n setUploadSetting(_objectSpread({}, setting));\n case 9:\n case \"end\":\n return _context.stop();\n }\n }, _callee);\n }))\n }, messageBuilderState.getMessage(__filename, \"select\")));\n };\n var generateFileRowsByVCType = function generateFileRowsByVCType(vcType) {\n var rows = [];\n if (vcType == \"RVC\") {\n rows.push(generateFileRow(uploadSetting, \"Model\", \"rvcModel\", [\"pth\", \"onnx\"]));\n rows.push(generateFileRow(uploadSetting, \"Index\", \"rvcIndex\", [\"index\", \"bin\"]));\n } else if (vcType == \"MMVCv13\") {\n rows.push(generateFileRow(uploadSetting, \"Config\", \"mmvcv13Config\", [\"json\"]));\n rows.push(generateFileRow(uploadSetting, \"Model\", \"mmvcv13Model\", [\"pth\", \"onnx\"]));\n } else if (vcType == \"MMVCv15\") {\n rows.push(generateFileRow(uploadSetting, \"Config\", \"mmvcv15Config\", [\"json\"]));\n rows.push(generateFileRow(uploadSetting, \"Model\", \"mmvcv15Model\", [\"pth\", \"onnx\"]));\n } else if (vcType == \"so-vits-svc-40\") {\n rows.push(generateFileRow(uploadSetting, \"Config\", \"soVitsSvc40Config\", [\"json\"]));\n rows.push(generateFileRow(uploadSetting, \"Model\", \"soVitsSvc40Model\", [\"pth\"]));\n rows.push(generateFileRow(uploadSetting, \"Cluster\", \"soVitsSvc40Cluster\", [\"pth\", \"pt\"]));\n } else if (vcType == \"DDSP-SVC\") {\n rows.push(generateFileRow(uploadSetting, \"Config\", \"ddspSvcModelConfig\", [\"yaml\"], \"model/\"));\n rows.push(generateFileRow(uploadSetting, \"Model\", \"ddspSvcModel\", [\"pth\", \"pt\"], \"model/\"));\n rows.push(generateFileRow(uploadSetting, \"Config(diff)\", \"ddspSvcDiffusionConfig\", [\"yaml\"], \"diff/\"));\n rows.push(generateFileRow(uploadSetting, \"Model(diff)\", \"ddspSvcDiffusion\", [\"pth\", \"pt\"], \"diff/\"));\n }\n return rows;\n };\n var fileRows = generateFileRowsByVCType(voiceChangerType);\n\n // appState.serverSetting.uploadProgress == 0 ? `loading model...(wait about 20sec)` : `processing.... ${appState.serverSetting.uploadProgress.toFixed(1)}%` : \"\"\n\n var buttonLabel = serverSetting.uploadProgress == 0 ? messageBuilderState.getMessage(__filename, \"upload\") : messageBuilderState.getMessage(__filename, \"uploading\") + \"(\".concat(serverSetting.uploadProgress.toFixed(1), \"%)\");\n return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_4___default().createElement(\"div\", {\n className: \"dialog-frame\"\n }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_4___default().createElement(\"div\", {\n className: \"dialog-title\"\n }, \"File Uploader\"), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_4___default().createElement(\"div\", {\n className: \"dialog-fixed-size-content\"\n }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_4___default().createElement(\"div\", {\n className: \"file-uploader-header\"\n }, messageBuilderState.getMessage(__filename, \"header_message\"), \" Slot[\", props.targetIndex, \"]\", /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_4___default().createElement(\"span\", {\n onClick: function onClick() {\n props.backToSlotManager();\n },\n className: \"file-uploader-header-button\"\n }, \"<<\", messageBuilderState.getMessage(__filename, \"back\"))), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_4___default().createElement(\"div\", {\n className: \"file-uploader-voice-changer-select\"\n }, \"VoiceChangerType:\", /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_4___default().createElement(\"select\", {\n value: voiceChangerType,\n onChange: function onChange(e) {\n setVoiceChangerType(e.target.value);\n }\n }, vcTypeOptions)), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_4___default().createElement(\"div\", {\n className: \"file-uploader-file-select-container\"\n }, fileRows), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_4___default().createElement(\"div\", {\n className: \"file-uploader-file-select-upload-button-container\"\n }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_4___default().createElement(\"div\", {\n className: \"file-uploader-file-select-upload-button\",\n onClick: function onClick() {\n if (!uploadSetting) {\n return;\n }\n if (serverSetting.uploadProgress != 0) {\n return;\n }\n if (checkModelSetting(uploadSetting)) {\n serverSetting.uploadModel(uploadSetting);\n } else {\n var errorMessage = messageBuilderState.getMessage(__filename, \"alert-model-file\");\n alert(errorMessage);\n }\n }\n }, buttonLabel))));\n }, [props.screen, props.targetIndex, voiceChangerType, uploadSetting, serverSetting.uploadModel, serverSetting.uploadProgress]);\n return screen;\n};\n\n//# sourceURL=webpack://demo/./src/components/demo/904-3_FileUploader.tsx?"); /***/ }), diff --git a/client/demo/src/components/demo/904-2_SampleDownloader.tsx b/client/demo/src/components/demo/904-2_SampleDownloader.tsx index 499c66c4..e266ed47 100644 --- a/client/demo/src/components/demo/904-2_SampleDownloader.tsx +++ b/client/demo/src/components/demo/904-2_SampleDownloader.tsx @@ -1,6 +1,6 @@ import React, { useMemo, useState } from "react"; import { useAppState } from "../../001_provider/001_AppStateProvider"; -import { InitialFileUploadSetting } from "@dannadori/voice-changer-client-js"; +import { ModelUploadSetting } from "@dannadori/voice-changer-client-js"; import { useMessageBuilder } from "../../hooks/useMessageBuilder"; import { ModelSlotManagerDialogScreen } from "./904_ModelSlotManagerDialog"; @@ -51,15 +51,18 @@ export const SampleDownloaderScreen = (props: SampleDownloaderScreenProps) => { ) const onDownloadSampleClicked = async (id: string) => { - serverSetting.fileUploadSettings[props.targetIndex] = { - ...InitialFileUploadSetting, - rvcModel: null, - rvcIndex: null, + const uploadParams: ModelUploadSetting = { + voiceChangerType: "RVC", + slot: props.targetIndex, + isSampleMode: true, sampleId: id, - isSampleMode: true + files: [], + params: { + rvcIndexDownload: true + } } try { - await serverSetting.loadModel(props.targetIndex) + await serverSetting.uploadModel(uploadParams) } catch (e) { alert(e) } diff --git a/client/demo/src/components/demo/904-3_FileUploader.tsx b/client/demo/src/components/demo/904-3_FileUploader.tsx index 4faa41a3..7ed3505b 100644 --- a/client/demo/src/components/demo/904-3_FileUploader.tsx +++ b/client/demo/src/components/demo/904-3_FileUploader.tsx @@ -41,6 +41,7 @@ export const FileUploaderScreen = (props: FileUploaderScreenProps) => { isSampleMode: false, sampleId: null, files: [], + params: {} }) }, [props.targetIndex, voiceChangerType]) diff --git a/client/lib/src/hooks/useServerSetting.ts b/client/lib/src/hooks/useServerSetting.ts index cfb349a1..d2927dc9 100644 --- a/client/lib/src/hooks/useServerSetting.ts +++ b/client/lib/src/hooks/useServerSetting.ts @@ -51,6 +51,7 @@ export type ModelUploadSetting = { sampleId: string | null files: ModelFile[] + params: any } export type ModelFileForServer = Omit & { name: string, @@ -341,7 +342,6 @@ export const useServerSetting = (props: UseServerSettingProps): ServerSettingSta } }, [props.voiceChangerClient]) - // 古いアップローダ(新GUIへ以降まで、当分残しておく。) const loadModel = useMemo(() => { return async (slot: number) => { diff --git a/server/downloader/SampleDownloader.py b/server/downloader/SampleDownloader.py index e862f009..5fdf33eb 100644 --- a/server/downloader/SampleDownloader.py +++ b/server/downloader/SampleDownloader.py @@ -7,7 +7,7 @@ from const import RVCSampleMode, getSampleJsonAndModelIds from data.ModelSample import ModelSamples, generateModelSample from data.ModelSlot import RVCModelSlot from voice_changer.ModelSlotManager import ModelSlotManager -from voice_changer.RVC.ModelSlotGenerator import _setInfoByONNX, _setInfoByPytorch +from voice_changer.RVC.RVCModelSlotGenerator import RVCModelSlotGenerator from downloader.Downloader import download, download_no_tqdm @@ -166,7 +166,7 @@ def _downloadSamples(samples: list[ModelSamples], sampleModelIds: list[Tuple[str slotInfo = modelSlotManager.get_slot_info(targetSlotIndex) if slotInfo.voiceChangerType == "RVC": if slotInfo.isONNX: - _setInfoByONNX(slotInfo) + RVCModelSlotGenerator._setInfoByONNX(slotInfo) else: - _setInfoByPytorch(slotInfo) + RVCModelSlotGenerator._setInfoByPytorch(slotInfo) modelSlotManager.save_model_slot(targetSlotIndex, slotInfo) diff --git a/server/restapi/MMVC_Rest_Fileuploader.py b/server/restapi/MMVC_Rest_Fileuploader.py index 2de234b8..57406304 100644 --- a/server/restapi/MMVC_Rest_Fileuploader.py +++ b/server/restapi/MMVC_Rest_Fileuploader.py @@ -1,7 +1,6 @@ import sys import json import os -import shutil from typing import Union from fastapi import APIRouter from fastapi.encoders import jsonable_encoder @@ -12,7 +11,7 @@ from restapi.mods.FileUploader import upload_file, concat_file_chunks from voice_changer.VoiceChangerManager import VoiceChangerManager from const import MODEL_DIR, UPLOAD_DIR, ModelType -from voice_changer.utils.LoadModelParams import LoadModelParams +from voice_changer.utils.LoadModelParams import LoadModelParamFile, LoadModelParams os.makedirs(UPLOAD_DIR, exist_ok=True) @@ -88,26 +87,11 @@ class MMVC_Rest_Fileuploader: try: paramDict = json.loads(params) print("paramDict", paramDict) - if paramDict["voiceChangerType"]: - # 新しいアップローダ用 - print("NEW UPLOADER") - props: LoadModelParams = LoadModelParams(slot=slot, isHalf=isHalf, params=paramDict) - else: - # 古いアップローダ用 - # Change Filepath - newFilesDict = {} - for key, val in paramDict["files"].items(): - if val != "-" and val != "": - uploadPath = os.path.join(UPLOAD_DIR, val) - storePath = os.path.join(UPLOAD_DIR, f"{slot}", val) - storeDir = os.path.dirname(storePath) - os.makedirs(storeDir, exist_ok=True) - shutil.move(uploadPath, storePath) - newFilesDict[key] = storePath - paramDict["files"] = newFilesDict - props = LoadModelParams(slot=slot, isHalf=isHalf, params=paramDict) + loadModelparams = LoadModelParams(**paramDict) + loadModelparams.files = [LoadModelParamFile(**x) for x in paramDict["files"]] + # print("paramDict", loadModelparams) - info = self.voiceChangerManager.loadModel(props) + info = self.voiceChangerManager.loadModel(loadModelparams) json_compatible_item_data = jsonable_encoder(info) return JSONResponse(content=json_compatible_item_data) except Exception as e: diff --git a/server/restapi/mods/Trainer_Model.py b/server/restapi/mods/Trainer_Model.py deleted file mode 100755 index 2449b4c2..00000000 --- a/server/restapi/mods/Trainer_Model.py +++ /dev/null @@ -1,14 +0,0 @@ - -from fastapi.responses import FileResponse -import os - - -def mod_get_model(modelFile: str): - modelPath = os.path.join("MMVC_Trainer/logs", modelFile) - return FileResponse(path=modelPath) - - -def mod_delete_model(modelFile: str): - modelPath = os.path.join("MMVC_Trainer/logs", modelFile) - os.remove(modelPath) - return {"Model deleted": f"{modelFile}"} diff --git a/server/restapi/mods/Trainer_Models.py b/server/restapi/mods/Trainer_Models.py deleted file mode 100755 index 5aaccd2e..00000000 --- a/server/restapi/mods/Trainer_Models.py +++ /dev/null @@ -1,23 +0,0 @@ - -from fastapi.responses import JSONResponse -from fastapi.encoders import jsonable_encoder -from restapi.utils.files import get_file_list -import os - -def mod_get_models(): - gModels = get_file_list(f'MMVC_Trainer/logs/G*.pth') - dModels = get_file_list(f'MMVC_Trainer/logs/D*.pth') - configs = get_file_list(f'MMVC_Trainer/logs/config.json') - models = [] - models.extend(gModels) - models.extend(dModels) - models.extend(configs) - models = [ os.path.basename(x) for x in models] - - models = sorted(models) - data = { - "models":models - } - json_compatible_item_data = jsonable_encoder(data) - return JSONResponse(content=json_compatible_item_data) - diff --git a/server/restapi/mods/Trainer_MultiSpeakerSetting.py b/server/restapi/mods/Trainer_MultiSpeakerSetting.py deleted file mode 100755 index cbeab8cb..00000000 --- a/server/restapi/mods/Trainer_MultiSpeakerSetting.py +++ /dev/null @@ -1,26 +0,0 @@ -from fastapi.responses import JSONResponse -from fastapi.encoders import jsonable_encoder -import os - -MULTI_SPEAKER_SETTING_PATH = "MMVC_Trainer/dataset/multi_speaker_correspondence.txt" -def mod_get_multi_speaker_setting(): - data = {} - if os.path.isfile(MULTI_SPEAKER_SETTING_PATH) == False: - with open(MULTI_SPEAKER_SETTING_PATH, "w") as f: - f.write("") - f.flush() - f.close() - - with open(MULTI_SPEAKER_SETTING_PATH, "r") as f: - setting = f.read() - data["multi_speaker_setting"] = setting - json_compatible_item_data = jsonable_encoder(data) - return JSONResponse(content=json_compatible_item_data) - - -def mod_post_multi_speaker_setting(setting:str): - with open(MULTI_SPEAKER_SETTING_PATH, "w") as f: - f.write(setting) - f.flush() - f.close() - return {"Write Multispeaker setting": f"{setting}"} \ No newline at end of file diff --git a/server/restapi/mods/Trainer_Speaker.py b/server/restapi/mods/Trainer_Speaker.py deleted file mode 100755 index e17f8fb0..00000000 --- a/server/restapi/mods/Trainer_Speaker.py +++ /dev/null @@ -1,15 +0,0 @@ -import shutil -from restapi.mods.Trainer_MultiSpeakerSetting import MULTI_SPEAKER_SETTING_PATH - -def mod_delete_speaker(speaker:str): - shutil.rmtree(f"MMVC_Trainer/dataset/textful/{speaker}") - - with open(MULTI_SPEAKER_SETTING_PATH, "r") as f: - setting = f.readlines() - - filtered = filter(lambda x: x.startswith(f"{speaker}|")==False, setting) - with open(MULTI_SPEAKER_SETTING_PATH, "w") as f: - f.writelines(list(filtered)) - f.flush() - f.close() - return {"Speaker deleted": f"{speaker}"} \ No newline at end of file diff --git a/server/restapi/mods/Trainer_Speaker_Voice.py b/server/restapi/mods/Trainer_Speaker_Voice.py deleted file mode 100755 index 0727d7b1..00000000 --- a/server/restapi/mods/Trainer_Speaker_Voice.py +++ /dev/null @@ -1,28 +0,0 @@ -from fastapi.responses import JSONResponse -from fastapi.encoders import jsonable_encoder -import os, base64 - -def mod_get_speaker_voice(speaker:str, voice:str): - wav_file = f'MMVC_Trainer/dataset/textful/{speaker}/wav/{voice}.wav' - text_file = f'MMVC_Trainer/dataset/textful/{speaker}/text/{voice}.txt' - readable_text_file = f'MMVC_Trainer/dataset/textful/{speaker}/readable_text/{voice}.txt' - - data = {} - if os.path.exists(wav_file): - with open(wav_file, "rb") as f: - wav_data = f.read() - wav_data_base64 = base64.b64encode(wav_data).decode('utf-8') - data["wav"] = wav_data_base64 - - - if os.path.exists(text_file): - with open(text_file, "r") as f: - text_data = f.read() - data["text"] = text_data - - if os.path.exists(readable_text_file): - with open(readable_text_file, "r") as f: - text_data = f.read() - data["readable_text"] = text_data - json_compatible_item_data = jsonable_encoder(data) - return JSONResponse(content=json_compatible_item_data) diff --git a/server/restapi/mods/Trainer_Speaker_Voices.py b/server/restapi/mods/Trainer_Speaker_Voices.py deleted file mode 100755 index 5f2b899d..00000000 --- a/server/restapi/mods/Trainer_Speaker_Voices.py +++ /dev/null @@ -1,22 +0,0 @@ -from fastapi.responses import JSONResponse -from fastapi.encoders import jsonable_encoder -from restapi.utils.files import get_file_list -import os - -def mod_get_speaker_voices(speaker:str): - voices = get_file_list(f'MMVC_Trainer/dataset/textful/{speaker}/wav/*.wav') - - texts = get_file_list(f'MMVC_Trainer/dataset/textful/{speaker}/text/*.txt') - - readable_texts = get_file_list(f'MMVC_Trainer/dataset/textful/{speaker}/readable_text/*.txt') - - items = voices - items.extend(texts) - items.extend(readable_texts) - items = [ os.path.splitext(os.path.basename(x))[0] for x in items] - items = sorted(set(items)) - data = { - "voices":items - } - json_compatible_item_data = jsonable_encoder(data) - return JSONResponse(content=json_compatible_item_data) \ No newline at end of file diff --git a/server/restapi/mods/Trainer_Speakers.py b/server/restapi/mods/Trainer_Speakers.py deleted file mode 100755 index 572a90b1..00000000 --- a/server/restapi/mods/Trainer_Speakers.py +++ /dev/null @@ -1,15 +0,0 @@ -from fastapi.responses import JSONResponse -from fastapi.encoders import jsonable_encoder -from restapi.utils.files import get_dir_list -import os -# CreateはFileUploaderで実装。 - -def mod_get_speakers(): - os.makedirs("MMVC_Trainer/dataset/textful", exist_ok=True) - speakers = get_dir_list("MMVC_Trainer/dataset/textful/") - - data = { - "speakers":sorted(speakers) - } - json_compatible_item_data = jsonable_encoder(data) - return JSONResponse(content=json_compatible_item_data) diff --git a/server/restapi/mods/Trainer_Training.py b/server/restapi/mods/Trainer_Training.py deleted file mode 100755 index e5ac1f00..00000000 --- a/server/restapi/mods/Trainer_Training.py +++ /dev/null @@ -1,176 +0,0 @@ -import subprocess,os -from restapi.utils.files import get_file_list -from fastapi.responses import JSONResponse -from fastapi.encoders import jsonable_encoder - -LOG_DIR = "info" -train_proc = None - -SUCCESS = 0 -ERROR = -1 -### Submodule for Pre train -def sync_exec(cmd:str, log_path:str, cwd=None): - shortCmdStr = cmd[:20] - try: - with open(log_path, 'w') as log_file: - if cwd == None: - proc = subprocess.run(cmd, shell=True, text=True, stdout=log_file, stderr=log_file) - else: - proc = subprocess.run(cmd, shell=True, text=True, stdout=log_file, stderr=log_file, cwd=cwd) - print(f"{shortCmdStr} returncode:{proc.returncode}") - if proc.returncode != 0: - print(f"{shortCmdStr} exception:") - return (ERROR, f"returncode:{proc.returncode}") - except Exception as e: - print(f"{shortCmdStr} exception:", str(e)) - return (ERROR, str(e)) - return (SUCCESS, "success") - -def sync_exec_with_stdout(cmd:str, log_path:str): - shortCmdStr = cmd[:20] - try: - with open(log_path, 'w') as log_file: - proc = subprocess.run(cmd, shell=True, text=True, stdout=subprocess.PIPE, - stderr=log_file, cwd="MMVC_Trainer") - print(f"STDOUT{shortCmdStr}",proc.stdout) - except Exception as e: - print(f"{shortCmdStr} exception:", str(e)) - return (ERROR, str(e)) - return (SUCCESS, proc.stdout) - - -def create_dataset(): - cmd = "python3 create_dataset_jtalk.py -f train_config -s 24000 -m dataset/multi_speaker_correspondence.txt" - log_file = os.path.join(LOG_DIR, "log_create_dataset_jtalk.txt") - res = sync_exec(cmd, log_file, "MMVC_Trainer") - return res - -def set_batch_size(batch:int): - cmd = "sed -i 's/\"batch_size\": [0-9]*/\"batch_size\": " + str(batch) + "/' MMVC_Trainer/configs/baseconfig.json" - log_file = os.path.join(LOG_DIR, "log_set_batch_size.txt") - res = sync_exec(cmd, log_file) - return res - -def set_dummy_device_count(): - cmd = 'sed -ie "s/torch.cuda.device_count()/1/" MMVC_Trainer/train_ms.py' - log_file = os.path.join(LOG_DIR, "log_set_dummy_device_count.txt") - res = sync_exec(cmd, log_file) - return res - -### Submodule for Train -def exec_training(enable_finetuning:bool, GModel:str, DModel:str): - global train_proc - log_file = os.path.join(LOG_DIR, "training.txt") - - # トレーニング開始確認(二重起動回避) - if train_proc != None: - status = train_proc.poll() - if status != None: - print("Training have ended.", status) - train_proc = None - else: - print("Training have stated.") - return (ERROR, "Training have started") - - try: - with open(log_file, 'w') as log_file: - if enable_finetuning == True: - GModelPath = os.path.join("logs", GModel) # 実行時にcwdを指定しているのでフォルダはlogsでよい。 - DModelPath = os.path.join("logs", DModel) - cmd = f'python3 train_ms.py -c configs/train_config.json -m ./ -fg {GModelPath} -fd {DModelPath}' - else: - cmd = 'python3 train_ms.py -c configs/train_config.json -m ./' - print("exec:",cmd) - train_proc = subprocess.Popen("exec "+cmd, shell=True, text=True, stdout=log_file, stderr=log_file, cwd="MMVC_Trainer") - print("Training stated") - print(f"returncode:{train_proc.returncode}") - except Exception as e: - print("start training exception:", str(e)) - return (ERROR, str(e)) - - return (SUCCESS, "success") - -def stop_training(): - global train_proc - if train_proc == None: - print("Training have not stated.") - return (ERROR, "Training have not stated.") - - status = train_proc.poll() - if status != None: - print("Training have already ended.", status) - train_proc = None - return (ERROR, "Training have already ended. " + status) - else: - train_proc.kill() - print("Training have stoped.") - return (SUCCESS, "success") - -### Main -def mod_post_pre_training(batch:int): - res = set_batch_size(batch) - if res[0] == ERROR: - return {"result":"failed", "detail": f"Preprocess(set_batch_size) failed. {res[1]}"} - - res = set_dummy_device_count() - if res[0] == ERROR: - return {"result":"failed", "detail": f"Preprocess(set_dummy_device_count) failed. {res[1]}"} - - res = create_dataset() - if res[0] == ERROR: - return {"result":"failed", "detail": f"Preprocess failed(create_dataset). {res[1]}"} - - return {"result":"success", "detail": f"Preprocess succeeded. {res[1]}"} - - -def mod_post_start_training(enable_finetuning:str, GModel:str, DModel:str): - print("START_TRAINING:::::::", enable_finetuning, GModel, DModel) - res = exec_training(enable_finetuning, GModel, DModel) - if res[0] == ERROR: - return {"result":"failed", "detail": f"Start training failed. {res[1]}"} - - return {"result":"success", "detail": f"Start training succeeded. {res[1]}"} - -def mod_post_stop_training(): - res = stop_training() - if res[0] == ERROR: - return {"result":"failed", "detail": f"Stop training failed. {res[1]}"} - - return {"result":"success", "detail": f"Stop training succeeded. {res[1]}"} - -### DEBUG -def mod_get_related_files(): - files = get_file_list(os.path.join(LOG_DIR,"*")) - files.extend([ - "MMVC_Trainer/dataset/multi_speaker_correspondence.txt", - "MMVC_Trainer/train_ms.py", - ]) - files.extend( - get_file_list("MMVC_Trainer/configs/*") - ) - - res = [] - for f in files: - size = os.path.getsize(f) - data = "" - if size < 1024*1024: - with open(f, "r") as input: - data = input.read() - - res.append({ - "name":f, - "size":size, - "data":data - }) - - json_compatible_item_data = jsonable_encoder(res) - return JSONResponse(content=json_compatible_item_data) - -def mod_get_tail_training_log(num:int): - training_log_file = os.path.join(LOG_DIR, "training.txt") - res = sync_exec(f"cat {training_log_file} | sed -e 's/.*\r//' > /tmp/out","/dev/null") - cmd = f'tail -n {num} /tmp/out' - res = sync_exec_with_stdout(cmd, "/dev/null") - if res[0] == ERROR: - return {"result":"failed", "detail": f"Tail training log failed. {res[1]}"} - return {"result":"success", "detail":res[1]} diff --git a/server/voice_changer/RVC/ModelSlotGenerator.py b/server/voice_changer/RVC/ModelSlotGenerator.py deleted file mode 100644 index aa86d6b1..00000000 --- a/server/voice_changer/RVC/ModelSlotGenerator.py +++ /dev/null @@ -1,126 +0,0 @@ -from const import EnumEmbedderTypes, EnumInferenceTypes - -import torch -import onnxruntime -import json - -from data.ModelSlot import ModelSlot - - -def _setInfoByPytorch(slot: ModelSlot): - cpt = torch.load(slot.modelFile, map_location="cpu") - config_len = len(cpt["config"]) - - if config_len == 18: - # Original RVC - slot.f0 = True if cpt["f0"] == 1 else False - version = cpt.get("version", "v1") - if version is None or version == "v1": - slot.modelType = EnumInferenceTypes.pyTorchRVC.value if slot.f0 else EnumInferenceTypes.pyTorchRVCNono.value - slot.embChannels = 256 - slot.embOutputLayer = 9 - slot.useFinalProj = True - slot.embedder = EnumEmbedderTypes.hubert.value - print("[Voice Changer] Official Model(pyTorch) : v1") - else: - slot.modelType = EnumInferenceTypes.pyTorchRVCv2.value if slot.f0 else EnumInferenceTypes.pyTorchRVCv2Nono.value - slot.embChannels = 768 - slot.embOutputLayer = 12 - slot.useFinalProj = False - slot.embedder = EnumEmbedderTypes.hubert.value - print("[Voice Changer] Official Model(pyTorch) : v2") - - else: - # DDPN RVC - slot.f0 = True if cpt["f0"] == 1 else False - slot.modelType = EnumInferenceTypes.pyTorchWebUI.value if slot.f0 else EnumInferenceTypes.pyTorchWebUINono.value - slot.embChannels = cpt["config"][17] - slot.embOutputLayer = cpt["embedder_output_layer"] if "embedder_output_layer" in cpt else 9 - if slot.embChannels == 256: - slot.useFinalProj = True - else: - slot.useFinalProj = False - - # DDPNモデルの情報を表示 - if slot.embChannels == 256 and slot.embOutputLayer == 9 and slot.useFinalProj is True: - print("[Voice Changer] DDPN Model(pyTorch) : Official v1 like") - elif slot.embChannels == 768 and slot.embOutputLayer == 12 and slot.useFinalProj is False: - print("[Voice Changer] DDPN Model(pyTorch): Official v2 like") - else: - print(f"[Voice Changer] DDPN Model(pyTorch): ch:{slot.embChannels}, L:{slot.embOutputLayer}, FP:{slot.useFinalProj}") - - slot.embedder = cpt["embedder_name"] - if slot.embedder.endswith("768"): - slot.embedder = slot.embedder[:-3] - - # if slot.embedder == EnumEmbedderTypes.hubert.value: - # slot.embedder = EnumEmbedderTypes.hubert - # elif slot.embedder == EnumEmbedderTypes.contentvec.value: - # slot.embedder = EnumEmbedderTypes.contentvec - # elif slot.embedder == EnumEmbedderTypes.hubert_jp.value: - # slot.embedder = EnumEmbedderTypes.hubert_jp - # else: - # raise RuntimeError("[Voice Changer][setInfoByONNX] unknown embedder") - - slot.samplingRate = cpt["config"][-1] - - del cpt - - -def _setInfoByONNX(slot: ModelSlot): - tmp_onnx_session = onnxruntime.InferenceSession(slot.modelFile, providers=["CPUExecutionProvider"]) - modelmeta = tmp_onnx_session.get_modelmeta() - try: - metadata = json.loads(modelmeta.custom_metadata_map["metadata"]) - - # slot.modelType = metadata["modelType"] - slot.embChannels = metadata["embChannels"] - - slot.embOutputLayer = metadata["embOutputLayer"] if "embOutputLayer" in metadata else 9 - slot.useFinalProj = metadata["useFinalProj"] if "useFinalProj" in metadata else True if slot.embChannels == 256 else False - - if slot.embChannels == 256: - slot.useFinalProj = True - else: - slot.useFinalProj = False - - # ONNXモデルの情報を表示 - if slot.embChannels == 256 and slot.embOutputLayer == 9 and slot.useFinalProj is True: - print("[Voice Changer] ONNX Model: Official v1 like") - elif slot.embChannels == 768 and slot.embOutputLayer == 12 and slot.useFinalProj is False: - print("[Voice Changer] ONNX Model: Official v2 like") - else: - print(f"[Voice Changer] ONNX Model: ch:{slot.embChannels}, L:{slot.embOutputLayer}, FP:{slot.useFinalProj}") - - if "embedder" not in metadata: - slot.embedder = EnumEmbedderTypes.hubert.value - else: - slot.embedder = metadata["embedder"] - # elif metadata["embedder"] == EnumEmbedderTypes.hubert.value: - # slot.embedder = EnumEmbedderTypes.hubert - # elif metadata["embedder"] == EnumEmbedderTypes.contentvec.value: - # slot.embedder = EnumEmbedderTypes.contentvec - # elif metadata["embedder"] == EnumEmbedderTypes.hubert_jp.value: - # slot.embedder = EnumEmbedderTypes.hubert_jp - # else: - # raise RuntimeError("[Voice Changer][setInfoByONNX] unknown embedder") - - slot.f0 = metadata["f0"] - slot.modelType = EnumInferenceTypes.onnxRVC.value if slot.f0 else EnumInferenceTypes.onnxRVCNono.value - slot.samplingRate = metadata["samplingRate"] - slot.deprecated = False - - except Exception as e: - slot.modelType = EnumInferenceTypes.onnxRVC.value - slot.embChannels = 256 - slot.embedder = EnumEmbedderTypes.hubert.value - slot.f0 = True - slot.samplingRate = 48000 - slot.deprecated = True - - print("[Voice Changer] setInfoByONNX", e) - print("[Voice Changer] ############## !!!! CAUTION !!!! ####################") - print("[Voice Changer] This onnxfie is depricated. Please regenerate onnxfile.") - print("[Voice Changer] ############## !!!! CAUTION !!!! ####################") - - del tmp_onnx_session diff --git a/server/voice_changer/RVC/RVC.py b/server/voice_changer/RVC/RVC.py index 9fe0154e..0bd75c64 100644 --- a/server/voice_changer/RVC/RVC.py +++ b/server/voice_changer/RVC/RVC.py @@ -20,14 +20,10 @@ if sys.platform.startswith("darwin"): else: sys.path.append("RVC") -from voice_changer.RVC.ModelSlotGenerator import ( - _setInfoByONNX, - _setInfoByPytorch, -) + from voice_changer.RVC.RVCSettings import RVCSettings from voice_changer.RVC.embedder.EmbedderManager import EmbedderManager -from voice_changer.utils.LoadModelParams import LoadModelParams2 -from voice_changer.utils.VoiceChangerModel import AudioInOut +from voice_changer.utils.VoiceChangerModel import AudioInOut, VoiceChangerModel from voice_changer.utils.VoiceChangerParams import VoiceChangerParams from voice_changer.RVC.onnxExporter.export2onnx import export2onnx from voice_changer.RVC.pitchExtractor.PitchExtractorManager import PitchExtractorManager @@ -35,10 +31,10 @@ from voice_changer.RVC.pipeline.PipelineGenerator import createPipeline from voice_changer.RVC.deviceManager.DeviceManager import DeviceManager from voice_changer.RVC.pipeline.Pipeline import Pipeline -from Exceptions import DeviceCannotSupportHalfPrecisionException, NoModeLoadedException +from Exceptions import DeviceCannotSupportHalfPrecisionException -class RVC: +class RVC(VoiceChangerModel): initialLoad: bool = True settings: RVCSettings = RVCSettings() @@ -53,7 +49,7 @@ class RVC: needSwitch: bool = False def __init__(self, params: VoiceChangerParams, slotInfo: RVCModelSlot): - print("[Voice Changer][RVC] Creating instance ") + print("[Voice Changer] [RVC] Creating instance ") EmbedderManager.initialize(params) self.params = params @@ -64,38 +60,16 @@ class RVC: self.initialize() def initialize(self): - print("[Voice Changer][RVC] Initializing... ") + print("[Voice Changer] [RVC] Initializing... ") # pipelineの生成 self.pipeline = createPipeline(self.slotInfo, self.settings.gpu, self.settings.f0Detector) # その他の設定 - self.trans = self.slotInfo.defaultTune - self.index_ratio = self.slotInfo.defaultIndexRatio - self.protect = self.slotInfo.defaultProtect - self.samplingRate = self.slotInfo.samplingRate - print("[Voice Changer][RVC] Initializing... done") - - @classmethod - def loadModel2(cls, props: LoadModelParams2): - slotInfo: RVCModelSlot = RVCModelSlot() - for file in props.files: - if file.kind == "rvcModel": - slotInfo.modelFile = file.name - elif file.kind == "rvcIndex": - slotInfo.indexFile = file.name - slotInfo.defaultTune = 0 - slotInfo.defaultIndexRatio = 0 - slotInfo.defaultProtect = 0.5 - slotInfo.isONNX = slotInfo.modelFile.endswith(".onnx") - slotInfo.name = os.path.splitext(os.path.basename(slotInfo.modelFile))[0] - # slotInfo.iconFile = "/assets/icons/noimage.png" - - if slotInfo.isONNX: - _setInfoByONNX(slotInfo) - else: - _setInfoByPytorch(slotInfo) - return slotInfo + self.settings.tran = self.slotInfo.defaultTune + self.settings.indexRatio = self.slotInfo.defaultIndexRatio + self.settings.protect = self.slotInfo.defaultProtect + print("[Voice Changer] [RVC] Initializing... done") def update_settings(self, key: str, val: int | float | str): print("[Voice Changer][RVC]: update_settings", key, val) @@ -123,7 +97,7 @@ class RVC: return data def get_processing_sampling_rate(self): - return self.settings.modelSamplingRate + return self.slotInfo.samplingRate def generate_input( self, @@ -170,14 +144,6 @@ class RVC: return (audio_buffer, convertSize, vol) def inference(self, data): - # if self.settings.modelSlotIndex < 0: - # print( - # "[Voice Changer] wait for loading model...", - # self.settings.modelSlotIndex, - # self.currentSlot, - # ) - # raise NoModeLoadedException("model_common") - audio = data[0] convertSize = data[1] vol = data[2] @@ -185,17 +151,13 @@ class RVC: if vol < self.settings.silentThreshold: return np.zeros(convertSize).astype(np.int16) - audio = torchaudio.functional.resample(audio, self.settings.modelSamplingRate, 16000, rolloff=0.99) + audio = torchaudio.functional.resample(audio, self.slotInfo.samplingRate, 16000, rolloff=0.99) repeat = 1 if self.settings.rvcQuality else 0 sid = 0 f0_up_key = self.settings.tran index_rate = self.settings.indexRatio protect = self.settings.protect - # if_f0 = 1 if self.settings.modelSlots[self.currentSlot].f0 else 0 - # embOutputLayer = self.settings.modelSlots[self.currentSlot].embOutputLayer - # useFinalProj = self.settings.modelSlots[self.currentSlot].useFinalProj - if_f0 = 1 if self.slotInfo.f0 else 0 embOutputLayer = self.slotInfo.embOutputLayer useFinalProj = self.slotInfo.useFinalProj @@ -207,7 +169,7 @@ class RVC: f0_up_key, index_rate, if_f0, - self.settings.extraConvertSize / self.settings.modelSamplingRate, # extaraDataSizeの秒数。RVCのモデルのサンプリングレートで処理(★1)。 + self.settings.extraConvertSize / self.slotInfo.samplingRate, # extaraDataSizeの秒数。RVCのモデルのサンプリングレートで処理(★1)。 embOutputLayer, useFinalProj, repeat, @@ -292,36 +254,6 @@ class RVC: # self.settings.modelSlotIndex = targetSlot # self.currentSlot = self.settings.modelSlotIndex - # def update_model_default(self): - # # {"slot":9,"key":"name","val":"dogsdododg"} - # self.modelSlotManager.update_model_info( - # json.dumps( - # { - # "slot": self.currentSlot, - # "key": "defaultTune", - # "val": self.settings.tran, - # } - # ) - # ) - # self.modelSlotManager.update_model_info( - # json.dumps( - # { - # "slot": self.currentSlot, - # "key": "defaultIndexRatio", - # "val": self.settings.indexRatio, - # } - # ) - # ) - # self.modelSlotManager.update_model_info( - # json.dumps( - # { - # "slot": self.currentSlot, - # "key": "defaultProtect", - # "val": self.settings.protect, - # } - # ) - # ) - def get_model_current(self): return [ { @@ -337,9 +269,3 @@ class RVC: "val": self.settings.protect, }, ] - - # def update_model_info(self, newData: str): - # self.modelSlotManager.update_model_info(newData) - - # def upload_model_assets(self, params: str): - # self.modelSlotManager.store_model_assets(params) diff --git a/server/voice_changer/RVC/RVCModelSlotGenerator.py b/server/voice_changer/RVC/RVCModelSlotGenerator.py new file mode 100644 index 00000000..662e7d05 --- /dev/null +++ b/server/voice_changer/RVC/RVCModelSlotGenerator.py @@ -0,0 +1,152 @@ +import os +from const import EnumEmbedderTypes, EnumInferenceTypes + +import torch +import onnxruntime +import json + +from data.ModelSlot import ModelSlot, RVCModelSlot +from voice_changer.utils.LoadModelParams import LoadModelParams +from voice_changer.utils.ModelSlotGenerator import ModelSlotGenerator + + +class RVCModelSlotGenerator(ModelSlotGenerator): + @classmethod + def loadModel(cls, props: LoadModelParams): + slotInfo: RVCModelSlot = RVCModelSlot() + for file in props.files: + if file.kind == "rvcModel": + slotInfo.modelFile = file.name + elif file.kind == "rvcIndex": + slotInfo.indexFile = file.name + slotInfo.defaultTune = 0 + slotInfo.defaultIndexRatio = 0 + slotInfo.defaultProtect = 0.5 + slotInfo.isONNX = slotInfo.modelFile.endswith(".onnx") + slotInfo.name = os.path.splitext(os.path.basename(slotInfo.modelFile))[0] + # slotInfo.iconFile = "/assets/icons/noimage.png" + + if slotInfo.isONNX: + cls._setInfoByONNX(slotInfo) + else: + cls._setInfoByPytorch(slotInfo) + return slotInfo + + @classmethod + def _setInfoByPytorch(cls, slot: ModelSlot): + cpt = torch.load(slot.modelFile, map_location="cpu") + config_len = len(cpt["config"]) + + if config_len == 18: + # Original RVC + slot.f0 = True if cpt["f0"] == 1 else False + version = cpt.get("version", "v1") + if version is None or version == "v1": + slot.modelType = EnumInferenceTypes.pyTorchRVC.value if slot.f0 else EnumInferenceTypes.pyTorchRVCNono.value + slot.embChannels = 256 + slot.embOutputLayer = 9 + slot.useFinalProj = True + slot.embedder = EnumEmbedderTypes.hubert.value + print("[Voice Changer] Official Model(pyTorch) : v1") + else: + slot.modelType = EnumInferenceTypes.pyTorchRVCv2.value if slot.f0 else EnumInferenceTypes.pyTorchRVCv2Nono.value + slot.embChannels = 768 + slot.embOutputLayer = 12 + slot.useFinalProj = False + slot.embedder = EnumEmbedderTypes.hubert.value + print("[Voice Changer] Official Model(pyTorch) : v2") + + else: + # DDPN RVC + slot.f0 = True if cpt["f0"] == 1 else False + slot.modelType = EnumInferenceTypes.pyTorchWebUI.value if slot.f0 else EnumInferenceTypes.pyTorchWebUINono.value + slot.embChannels = cpt["config"][17] + slot.embOutputLayer = cpt["embedder_output_layer"] if "embedder_output_layer" in cpt else 9 + if slot.embChannels == 256: + slot.useFinalProj = True + else: + slot.useFinalProj = False + + # DDPNモデルの情報を表示 + if slot.embChannels == 256 and slot.embOutputLayer == 9 and slot.useFinalProj is True: + print("[Voice Changer] DDPN Model(pyTorch) : Official v1 like") + elif slot.embChannels == 768 and slot.embOutputLayer == 12 and slot.useFinalProj is False: + print("[Voice Changer] DDPN Model(pyTorch): Official v2 like") + else: + print(f"[Voice Changer] DDPN Model(pyTorch): ch:{slot.embChannels}, L:{slot.embOutputLayer}, FP:{slot.useFinalProj}") + + slot.embedder = cpt["embedder_name"] + if slot.embedder.endswith("768"): + slot.embedder = slot.embedder[:-3] + + # if slot.embedder == EnumEmbedderTypes.hubert.value: + # slot.embedder = EnumEmbedderTypes.hubert + # elif slot.embedder == EnumEmbedderTypes.contentvec.value: + # slot.embedder = EnumEmbedderTypes.contentvec + # elif slot.embedder == EnumEmbedderTypes.hubert_jp.value: + # slot.embedder = EnumEmbedderTypes.hubert_jp + # else: + # raise RuntimeError("[Voice Changer][setInfoByONNX] unknown embedder") + + slot.samplingRate = cpt["config"][-1] + + del cpt + + @classmethod + def _setInfoByONNX(cls, slot: ModelSlot): + tmp_onnx_session = onnxruntime.InferenceSession(slot.modelFile, providers=["CPUExecutionProvider"]) + modelmeta = tmp_onnx_session.get_modelmeta() + try: + metadata = json.loads(modelmeta.custom_metadata_map["metadata"]) + + # slot.modelType = metadata["modelType"] + slot.embChannels = metadata["embChannels"] + + slot.embOutputLayer = metadata["embOutputLayer"] if "embOutputLayer" in metadata else 9 + slot.useFinalProj = metadata["useFinalProj"] if "useFinalProj" in metadata else True if slot.embChannels == 256 else False + + if slot.embChannels == 256: + slot.useFinalProj = True + else: + slot.useFinalProj = False + + # ONNXモデルの情報を表示 + if slot.embChannels == 256 and slot.embOutputLayer == 9 and slot.useFinalProj is True: + print("[Voice Changer] ONNX Model: Official v1 like") + elif slot.embChannels == 768 and slot.embOutputLayer == 12 and slot.useFinalProj is False: + print("[Voice Changer] ONNX Model: Official v2 like") + else: + print(f"[Voice Changer] ONNX Model: ch:{slot.embChannels}, L:{slot.embOutputLayer}, FP:{slot.useFinalProj}") + + if "embedder" not in metadata: + slot.embedder = EnumEmbedderTypes.hubert.value + else: + slot.embedder = metadata["embedder"] + # elif metadata["embedder"] == EnumEmbedderTypes.hubert.value: + # slot.embedder = EnumEmbedderTypes.hubert + # elif metadata["embedder"] == EnumEmbedderTypes.contentvec.value: + # slot.embedder = EnumEmbedderTypes.contentvec + # elif metadata["embedder"] == EnumEmbedderTypes.hubert_jp.value: + # slot.embedder = EnumEmbedderTypes.hubert_jp + # else: + # raise RuntimeError("[Voice Changer][setInfoByONNX] unknown embedder") + + slot.f0 = metadata["f0"] + slot.modelType = EnumInferenceTypes.onnxRVC.value if slot.f0 else EnumInferenceTypes.onnxRVCNono.value + slot.samplingRate = metadata["samplingRate"] + slot.deprecated = False + + except Exception as e: + slot.modelType = EnumInferenceTypes.onnxRVC.value + slot.embChannels = 256 + slot.embedder = EnumEmbedderTypes.hubert.value + slot.f0 = True + slot.samplingRate = 48000 + slot.deprecated = True + + print("[Voice Changer] setInfoByONNX", e) + print("[Voice Changer] ############## !!!! CAUTION !!!! ####################") + print("[Voice Changer] This onnxfie is depricated. Please regenerate onnxfile.") + print("[Voice Changer] ############## !!!! CAUTION !!!! ####################") + + del tmp_onnx_session diff --git a/server/voice_changer/RVC/RVCSettings.py b/server/voice_changer/RVC/RVCSettings.py index 25f1381e..49549670 100644 --- a/server/voice_changer/RVC/RVCSettings.py +++ b/server/voice_changer/RVC/RVCSettings.py @@ -7,12 +7,9 @@ class RVCSettings: dstId: int = 0 f0Detector: str = "harvest" # dio or harvest - tran: int = 20 + tran: int = 12 silentThreshold: float = 0.00001 - extraConvertSize: int = 1024 * 32 - clusterInferRatio: float = 0.1 - - framework: str = "PyTorch" # PyTorch or ONNX + extraConvertSize: int = 1024 * 4 indexRatio: float = 0 protect: float = 0.5 @@ -21,8 +18,8 @@ class RVCSettings: modelSamplingRate: int = 48000 speakers: dict[str, int] = field(default_factory=lambda: {}) - isHalf: int = 1 # 0:off, 1:on - enableDirectML: int = 0 # 0:off, 1:on + # isHalf: int = 1 # 0:off, 1:on + # enableDirectML: int = 0 # 0:off, 1:on # ↓mutableな物だけ列挙 intData = [ "gpu", @@ -30,11 +27,7 @@ class RVCSettings: "tran", "extraConvertSize", "rvcQuality", - "modelSamplingRate", "silenceFront", - "modelSlotIndex", - "isHalf", - "enableDirectML", ] floatData = ["silentThreshold", "indexRatio", "protect"] - strData = ["framework", "f0Detector"] + strData = ["f0Detector"] diff --git a/server/voice_changer/VoiceChangerManager.py b/server/voice_changer/VoiceChangerManager.py index 0ecf8a7b..894c7d3b 100644 --- a/server/voice_changer/VoiceChangerManager.py +++ b/server/voice_changer/VoiceChangerManager.py @@ -7,7 +7,7 @@ from voice_changer.Local.ServerDevice import ServerDevice, ServerDeviceCallbacks from voice_changer.ModelSlotManager import ModelSlotManager from voice_changer.VoiceChanger import VoiceChanger from const import UPLOAD_DIR, ModelType -from voice_changer.utils.LoadModelParams import LoadModelParamFile, LoadModelParams, LoadModelParams2 +from voice_changer.utils.LoadModelParams import LoadModelParams from voice_changer.utils.VoiceChangerModel import AudioInOut from voice_changer.utils.VoiceChangerParams import VoiceChangerParams from dataclasses import dataclass, asdict, field @@ -85,20 +85,15 @@ class VoiceChangerManager(ServerDeviceCallbacks): cls._instance.voiceChanger = VoiceChanger(params) return cls._instance - def loadModel(self, props: LoadModelParams): - paramDict = props.params - if paramDict["sampleId"] is not None: + def loadModel(self, params: LoadModelParams): + if params.isSampleMode: # サンプルダウンロード - downloadSample(self.params.sample_mode, paramDict["sampleId"], self.params.model_dir, props.slot, {"useIndex": paramDict["rvcIndexDownload"]}) + downloadSample(self.params.sample_mode, params.sampleId, self.params.model_dir, params.slot, {"useIndex": params.params["rvcIndexDownload"]}) self.modelSlotManager.getAllSlotInfo(reload=True) info = {"status": "OK"} return info - elif paramDict["voiceChangerType"]: - # 新しいアップローダ - # Dataを展開 - params = LoadModelParams2(**paramDict) - params.files = [LoadModelParamFile(**x) for x in paramDict["files"]] - + else: + # アップローダ # ファイルをslotにコピー for file in params.files: print("FILE", file) @@ -116,42 +111,32 @@ class VoiceChangerManager(ServerDeviceCallbacks): # メタデータ作成(各VCで定義) if params.voiceChangerType == "RVC": - from voice_changer.RVC.RVC import RVC # 起動時にインポートするとパラメータが取れない。 + from voice_changer.RVC.RVCModelSlotGenerator import RVCModelSlotGenerator # 起動時にインポートするとパラメータが取れない。 - slotInfo = RVC.loadModel2(params) + slotInfo = RVCModelSlotGenerator.loadModel(params) self.modelSlotManager.save_model_slot(params.slot, slotInfo) elif params.voiceChangerType == "MMVCv13": from voice_changer.MMVCv13.MMVCv13 import MMVCv13 - slotInfo = MMVCv13.loadModel2(params) + slotInfo = MMVCv13.loadModel(params) self.modelSlotManager.save_model_slot(params.slot, slotInfo) elif params.voiceChangerType == "MMVCv15": from voice_changer.MMVCv15.MMVCv15 import MMVCv15 - slotInfo = MMVCv15.loadModel2(params) + slotInfo = MMVCv15.loadModel(params) self.modelSlotManager.save_model_slot(params.slot, slotInfo) elif params.voiceChangerType == "so-vits-svc-40": from voice_changer.SoVitsSvc40.SoVitsSvc40 import SoVitsSvc40 - slotInfo = SoVitsSvc40.loadModel2(params) + slotInfo = SoVitsSvc40.loadModel(params) self.modelSlotManager.save_model_slot(params.slot, slotInfo) elif params.voiceChangerType == "DDSP-SVC": from voice_changer.DDSP_SVC.DDSP_SVC import DDSP_SVC - slotInfo = DDSP_SVC.loadModel2(params) + slotInfo = DDSP_SVC.loadModel(params) self.modelSlotManager.save_model_slot(params.slot, slotInfo) print("params", params) - else: - # 古いアップローダ - print("[Voice Canger]: upload models........") - info = self.voiceChanger.loadModel(props) - if hasattr(info, "status") and info["status"] == "NG": - return info - else: - info["status"] = "OK" - return info - def get_info(self): data = asdict(self.settings) data["gpus"] = self.gpus diff --git a/server/voice_changer/utils/LoadModelParams.py b/server/voice_changer/utils/LoadModelParams.py index 8525fd0e..dcc30dff 100644 --- a/server/voice_changer/utils/LoadModelParams.py +++ b/server/voice_changer/utils/LoadModelParams.py @@ -1,27 +1,8 @@ from dataclasses import dataclass -from typing import Any from const import VoiceChangerType from typing import Literal, TypeAlias - -@dataclass -class FilePaths: - configFilename: str | None - pyTorchModelFilename: str | None - onnxModelFilename: str | None - clusterTorchModelFilename: str | None - featureFilename: str | None - indexFilename: str | None - - -@dataclass -class LoadModelParams: - slot: int - isHalf: bool - params: Any - - LoadModelParamFileKind: TypeAlias = Literal[ "mmvcv13Config", "mmvcv13Model", @@ -47,9 +28,10 @@ class LoadModelParamFile: @dataclass -class LoadModelParams2: +class LoadModelParams: voiceChangerType: VoiceChangerType slot: int isSampleMode: bool sampleId: str files: list[LoadModelParamFile] + params: dict diff --git a/server/voice_changer/utils/ModelSlotGenerator.py b/server/voice_changer/utils/ModelSlotGenerator.py new file mode 100644 index 00000000..c9327824 --- /dev/null +++ b/server/voice_changer/utils/ModelSlotGenerator.py @@ -0,0 +1,9 @@ +from typing import Protocol + +from voice_changer.utils.LoadModelParams import LoadModelParams + + +class ModelSlotGenerator(Protocol): + @classmethod + def loadModel(self, params: LoadModelParams): + ... diff --git a/server/voice_changer/utils/VoiceChangerModel.py b/server/voice_changer/utils/VoiceChangerModel.py index d2ca6410..7dd4fda9 100644 --- a/server/voice_changer/utils/VoiceChangerModel.py +++ b/server/voice_changer/utils/VoiceChangerModel.py @@ -21,10 +21,8 @@ class VoiceChangerModel(Protocol): def inference(self, data: tuple[Any, ...]) -> Any: ... - def generate_input( - self, newData: AudioInOut, inputSize: int, crossfadeSize: int - ) -> tuple[Any, ...]: + def generate_input(self, newData: AudioInOut, inputSize: int, crossfadeSize: int, solaSearchFrame: int) -> tuple[Any, ...]: ... - def update_settings(self, key: str, val: Any) -> bool: + def update_settings(self, key: str, val: int | float | str) -> bool: ...