From 889874ecafc45704d0f0db17584dc2ce2e49f0f4 Mon Sep 17 00:00:00 2001
From: Hina <79749008+hinabl@users.noreply.github.com>
Date: Thu, 28 Sep 2023 19:18:21 +0800
Subject: [PATCH 01/28] Added Auto Sampling Rate
The Model Uploader Colab Cell is probably more buggy now but it works....
---
...fied_Realtime_Voice_Changer_on_Colab.ipynb | 119 ++++++++++++------
1 file changed, 83 insertions(+), 36 deletions(-)
diff --git a/Hina_Modified_Realtime_Voice_Changer_on_Colab.ipynb b/Hina_Modified_Realtime_Voice_Changer_on_Colab.ipynb
index ebbab41f..dbcc76ff 100644
--- a/Hina_Modified_Realtime_Voice_Changer_on_Colab.ipynb
+++ b/Hina_Modified_Realtime_Voice_Changer_on_Colab.ipynb
@@ -1,15 +1,5 @@
{
"cells": [
-{
- "cell_type": "markdown",
- "metadata": {
- "id": "view-in-github",
- "colab_type": "text"
- },
- "source": [
- ""
- ]
- },
{
"cell_type": "markdown",
"metadata": {
@@ -147,21 +137,22 @@
"#@markdown ---\n",
"import os\n",
"import json\n",
+ "from IPython.display import Image\n",
"\n",
"\n",
"#@markdown #Model Number `(Default is 0)` you can add multiple models as long as you change the number!\n",
- "model_number = \"0\" #@param ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12', '13', '14', '15', '16', '17', '18', '19', '20', '21', '22', '23', '24', '25', '26', '27', '28', '29', '30', '31', '32', '33', '34', '35', '36', '37', '38', '39', '40', '41', '42', '43', '44', '45', '46', '47', '48', '49', '50', '51', '52', '53', '54', '55', '56', '57', '58', '59', '60', '61', '62', '63', '64', '65', '66', '67', '68', '69', '70', '71', '72', '73', '74', '75', '76', '77', '78', '79', '80', '81', '82', '83', '84', '85', '86', '87', '88', '89', '90', '91', '92', '93', '94', '95', '96', '97', '98', '99', '100', '101', '102', '103', '104', '105', '106', '107', '108', '109', '110', '111', '112', '113', '114', '115', '116', '117', '118', '119', '120', '121', '122', '123', '124', '125', '126', '127', '128', '129', '130', '131', '132', '133', '134', '135', '136', '137', '138', '139', '140', '141', '142', '143', '144', '145', '146', '147', '148', '149', '150', '151', '152', '153', '154', '155', '156', '157', '158', '159', '160', '161', '162', '163', '164', '165', '166', '167', '168', '169', '170', '171', '172', '173', '174', '175', '176', '177', '178', '179', '180', '181', '182', '183', '184', '185', '186', '187', '188', '189', '190', '191', '192', '193', '194', '195', '196', '197', '198', '199']\n",
+ "model_number = \"6\" #@param ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12', '13', '14', '15', '16', '17', '18', '19', '20', '21', '22', '23', '24', '25', '26', '27', '28', '29', '30', '31', '32', '33', '34', '35', '36', '37', '38', '39', '40', '41', '42', '43', '44', '45', '46', '47', '48', '49', '50', '51', '52', '53', '54', '55', '56', '57', '58', '59', '60', '61', '62', '63', '64', '65', '66', '67', '68', '69', '70', '71', '72', '73', '74', '75', '76', '77', '78', '79', '80', '81', '82', '83', '84', '85', '86', '87', '88', '89', '90', '91', '92', '93', '94', '95', '96', '97', '98', '99', '100', '101', '102', '103', '104', '105', '106', '107', '108', '109', '110', '111', '112', '113', '114', '115', '116', '117', '118', '119', '120', '121', '122', '123', '124', '125', '126', '127', '128', '129', '130', '131', '132', '133', '134', '135', '136', '137', '138', '139', '140', '141', '142', '143', '144', '145', '146', '147', '148', '149', '150', '151', '152', '153', '154', '155', '156', '157', '158', '159', '160', '161', '162', '163', '164', '165', '166', '167', '168', '169', '170', '171', '172', '173', '174', '175', '176', '177', '178', '179', '180', '181', '182', '183', '184', '185', '186', '187', '188', '189', '190', '191', '192', '193', '194', '195', '196', '197', '198', '199']\n",
"\n",
"!rm -rf model_dir/$model_number\n",
"#@markdown ---\n",
"#@markdown #**[Optional]** Add an icon to the model `(can be any image/leave empty for no image)`\n",
- "icon_link = \"https://cdn.donmai.us/original/8a/92/8a924397e9aac922e94bdc1f28ff978a.jpg\" #@param {type:\"string\"}\n",
+ "icon_link = \"https://cdn.discordapp.com/attachments/1144453160912572506/1144453161210351697/mika.png?ex=65163190&is=6514e010&hm=6cfc987d42e448b2912f5225e2c865df92d688c8dc46a135c2cca32682a3f3ea&\" #@param {type:\"string\"}\n",
"#@markdown ---\n",
"icon_link = '\"'+icon_link+'\"'\n",
"!mkdir model_dir\n",
"!mkdir model_dir/$model_number\n",
"#@markdown #Put your model's download link here `(must be a zip file)`\n",
- "model_link = \"https://huggingface.co/HinaBl/Akatsuki/resolve/main/akatsuki_200epoch.zip\" #@param {type:\"string\"}\n",
+ "model_link = \"https://huggingface.co/Kit-Lemonfoot/kitlemonfoot_rvc_models/resolve/main/Mika%20Melatika%20(Speaking)(KitLemonfoot).zip\" #@param {type:\"string\"}\n",
"model_link = '\"'+model_link+'\"'\n",
"!curl -L $model_link > model.zip\n",
"\n",
@@ -171,6 +162,7 @@
" iconFile = \"icon.png\"\n",
" !curl -L $icon_link > model_dir/$model_number/icon.png\n",
"else:\n",
+ " iconFile = \"\"\n",
" print(\"icon_link is empty, so no icon file will be downloaded.\")\n",
"#@markdown ---\n",
"\n",
@@ -190,32 +182,83 @@
"Tune = 12 #@param {type:\"slider\",min:-50,max:50,step:1}\n",
"Index = 0 #@param {type:\"slider\",min:0,max:1,step:0.1}\n",
"#@markdown ---\n",
- "#@markdown #Parameter Option `(Ignore if theres a Parameter File)`\n",
- "Slot_Index = -1 #@param [-1,0,1] {type:\"raw\"}\n",
- "Sampling_Rate = 48000 #@param [32000,40000,48000] {type:\"raw\"}\n",
"\n",
"# @markdown #**[Optional]** Parameter file for your voice model\n",
"#@markdown _(must be named params.json)_ (Leave Empty for Default)\n",
"param_link = \"\" #@param {type:\"string\"}\n",
"if param_link == \"\":\n",
- " model_dir = \"model_dir/\"+model_number+\"/\"\n",
+ " from voice_changer.RVC.RVCModelSlotGenerator import RVCModelSlotGenerator\n",
+ " from voice_changer.VoiceChangerParamsManager import VoiceChangerParamsManager\n",
+ " from voice_changer.utils.LoadModelParams import LoadModelParamFile, LoadModelParams\n",
+ " from voice_changer.utils.VoiceChangerParams import VoiceChangerParams\n",
"\n",
- " # Find the .pth and .index files in the model_dir/0 directory\n",
- " pth_files = [f for f in os.listdir(model_dir) if f.endswith(\".pth\")]\n",
- " index_files = [f for f in os.listdir(model_dir) if f.endswith(\".index\")]\n",
+ " model_dir1 = \"model_dir/\"+model_number+\"/\"\n",
"\n",
- " if pth_files and index_files:\n",
- " # Take the first .pth and .index file as model and index names\n",
+ " is_pth = True # Set this to True if you want to search for .pth files, or False for .onnx files\n",
+ " file_extension = \".pth\" if is_pth else \".onnx\"\n",
+ "\n",
+ " # pth_files = [f for f in os.listdir(model_dir1) if f.endswith(file_extension)]\n",
+ "\n",
+ " pth_files = [f for f in os.listdir(model_dir1) if f.endswith(\".pth\") or f.endswith(\".onnx\")]\n",
+ " print(pth_files)\n",
+ " index_files = [f for f in os.listdir(model_dir1) if f.endswith(\".index\")]\n",
+ "\n",
+ "\n",
+ "\n",
+ "\n",
+ " if pth_files:\n",
" model_name = pth_files[0].replace(\".pth\", \"\")\n",
+ "\n",
+ " else:\n",
+ " model_name = \"Null\"\n",
+ " if index_files:\n",
" index_name = index_files[0].replace(\".index\", \"\")\n",
" else:\n",
- " # Set default values if no .pth and .index files are found\n",
- " model_name = \"Null\"\n",
- " index_name = \"Null\"\n",
+ " index_name = \"\"\n",
"\n",
- " # Define the content for params.json\n",
+ " original_string = str(pth_files)\n",
+ " string_pth_files = original_string[2:-2]\n",
+ " print(\"IM A STRING\"+original_string)\n",
+ "\n",
+ " print(model_name)\n",
+ " voiceChangerParams = VoiceChangerParams(\n",
+ " model_dir=\"./model_dir/\"+model_number,\n",
+ " content_vec_500=\"\",\n",
+ " content_vec_500_onnx=\"\",\n",
+ " content_vec_500_onnx_on=\"\",\n",
+ " hubert_base=\"\",\n",
+ " hubert_base_jp=\"\",\n",
+ " hubert_soft=\"\",\n",
+ " nsf_hifigan=\"\",\n",
+ " crepe_onnx_full=\"\",\n",
+ " crepe_onnx_tiny=\"\",\n",
+ " rmvpe=\"\",\n",
+ " rmvpe_onnx=\"\",\n",
+ " sample_mode=\"\"\n",
+ " )\n",
+ " vcparams = VoiceChangerParamsManager.get_instance()\n",
+ " vcparams.setParams(voiceChangerParams)\n",
+ "\n",
+ " file = LoadModelParamFile(\n",
+ " name=string_pth_files,\n",
+ " kind=\"rvcModel\",\n",
+ " dir=\"\",\n",
+ " )\n",
+ "\n",
+ " loadParam = LoadModelParams(\n",
+ " voiceChangerType=\"RVC\",\n",
+ " files=[file],\n",
+ " slot=\"\",\n",
+ " isSampleMode=False,\n",
+ " sampleId=\"\",\n",
+ " params={},\n",
+ " )\n",
+ " slotInfo = RVCModelSlotGenerator.loadModel(loadParam)\n",
+ " print(slotInfo.samplingRate)\n",
+ "\n",
+ "#----------------Make the Json File-----------\n",
" params_content = {\n",
- " \"slotIndex\": Slot_Index,\n",
+ " \"slotIndex\": -1,\n",
" \"voiceChangerType\": \"RVC\",\n",
" \"name\": model_name,\n",
" \"description\": \"\",\n",
@@ -225,14 +268,14 @@
" \"speakers\": {\n",
" \"0\": \"target\"\n",
" },\n",
- " \"modelFile\": f\"{model_name}.pth\",\n",
+ " \"modelFile\": string_pth_files,\n",
" \"indexFile\": f\"{index_name}.index\",\n",
" \"defaultTune\": Tune,\n",
" \"defaultIndexRatio\": Index,\n",
" \"defaultProtect\": 0.5,\n",
" \"isONNX\": False,\n",
" \"modelType\": \"pyTorchRVCv2\",\n",
- " \"samplingRate\": Sampling_Rate,\n",
+ " \"samplingRate\": slotInfo.samplingRate,\n",
" \"f0\": True,\n",
" \"embChannels\": 768,\n",
" \"embOutputLayer\": 12,\n",
@@ -243,16 +286,18 @@
" }\n",
"\n",
" # Write the content to params.json\n",
- " with open(f\"{model_dir}/params.json\", \"w\") as param_file:\n",
+ " with open(f\"{model_dir1}/params.json\", \"w\") as param_file:\n",
" json.dump(params_content, param_file)\n",
"\n",
+ "\n",
"# !unzip model.zip -d model_dir/0/\n",
"clear_output()\n",
- "print(\"\\033[92mModel with the name of \"+model_name+\" has been Imported!\")\n"
+ "print(\"\\033[92mModel with the name of \"+model_name+\" has been Imported to slot \"+model_number)\n",
+ "Image(url=icon_link)"
],
"metadata": {
- "cellView": "form",
- "id": "_ZtbKUVUgN3G"
+ "id": "_ZtbKUVUgN3G",
+ "cellView": "form"
},
"execution_count": null,
"outputs": []
@@ -270,7 +315,8 @@
"print(\"\\033[92mSuccessfully removed Model is slot \"+Delete_Slot)\n"
],
"metadata": {
- "id": "P9g6rG1-KUwt"
+ "id": "P9g6rG1-KUwt",
+ "cellView": "form"
},
"execution_count": null,
"outputs": []
@@ -279,7 +325,8 @@
"cell_type": "code",
"execution_count": null,
"metadata": {
- "id": "lLWQuUd7WW9U"
+ "id": "lLWQuUd7WW9U",
+ "cellView": "form"
},
"outputs": [],
"source": [
@@ -440,4 +487,4 @@
},
"nbformat": 4,
"nbformat_minor": 0
-}
+}
\ No newline at end of file
From 8d3a0f8c7313917438f24bac03f3f198f3a61219 Mon Sep 17 00:00:00 2001
From: Hina <79749008+hinabl@users.noreply.github.com>
Date: Fri, 29 Sep 2023 00:44:13 +0800
Subject: [PATCH 02/28] Created using Colaboratory
---
...ified_Realtime_Voice_Changer_on_Colab.ipynb | 18 ++++++++++++++----
1 file changed, 14 insertions(+), 4 deletions(-)
diff --git a/Hina_Modified_Realtime_Voice_Changer_on_Colab.ipynb b/Hina_Modified_Realtime_Voice_Changer_on_Colab.ipynb
index dbcc76ff..8035d256 100644
--- a/Hina_Modified_Realtime_Voice_Changer_on_Colab.ipynb
+++ b/Hina_Modified_Realtime_Voice_Changer_on_Colab.ipynb
@@ -1,5 +1,15 @@
{
"cells": [
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "view-in-github",
+ "colab_type": "text"
+ },
+ "source": [
+ ""
+ ]
+ },
{
"cell_type": "markdown",
"metadata": {
@@ -141,7 +151,7 @@
"\n",
"\n",
"#@markdown #Model Number `(Default is 0)` you can add multiple models as long as you change the number!\n",
- "model_number = \"6\" #@param ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12', '13', '14', '15', '16', '17', '18', '19', '20', '21', '22', '23', '24', '25', '26', '27', '28', '29', '30', '31', '32', '33', '34', '35', '36', '37', '38', '39', '40', '41', '42', '43', '44', '45', '46', '47', '48', '49', '50', '51', '52', '53', '54', '55', '56', '57', '58', '59', '60', '61', '62', '63', '64', '65', '66', '67', '68', '69', '70', '71', '72', '73', '74', '75', '76', '77', '78', '79', '80', '81', '82', '83', '84', '85', '86', '87', '88', '89', '90', '91', '92', '93', '94', '95', '96', '97', '98', '99', '100', '101', '102', '103', '104', '105', '106', '107', '108', '109', '110', '111', '112', '113', '114', '115', '116', '117', '118', '119', '120', '121', '122', '123', '124', '125', '126', '127', '128', '129', '130', '131', '132', '133', '134', '135', '136', '137', '138', '139', '140', '141', '142', '143', '144', '145', '146', '147', '148', '149', '150', '151', '152', '153', '154', '155', '156', '157', '158', '159', '160', '161', '162', '163', '164', '165', '166', '167', '168', '169', '170', '171', '172', '173', '174', '175', '176', '177', '178', '179', '180', '181', '182', '183', '184', '185', '186', '187', '188', '189', '190', '191', '192', '193', '194', '195', '196', '197', '198', '199']\n",
+ "model_number = \"0\" #@param ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12', '13', '14', '15', '16', '17', '18', '19', '20', '21', '22', '23', '24', '25', '26', '27', '28', '29', '30', '31', '32', '33', '34', '35', '36', '37', '38', '39', '40', '41', '42', '43', '44', '45', '46', '47', '48', '49', '50', '51', '52', '53', '54', '55', '56', '57', '58', '59', '60', '61', '62', '63', '64', '65', '66', '67', '68', '69', '70', '71', '72', '73', '74', '75', '76', '77', '78', '79', '80', '81', '82', '83', '84', '85', '86', '87', '88', '89', '90', '91', '92', '93', '94', '95', '96', '97', '98', '99', '100', '101', '102', '103', '104', '105', '106', '107', '108', '109', '110', '111', '112', '113', '114', '115', '116', '117', '118', '119', '120', '121', '122', '123', '124', '125', '126', '127', '128', '129', '130', '131', '132', '133', '134', '135', '136', '137', '138', '139', '140', '141', '142', '143', '144', '145', '146', '147', '148', '149', '150', '151', '152', '153', '154', '155', '156', '157', '158', '159', '160', '161', '162', '163', '164', '165', '166', '167', '168', '169', '170', '171', '172', '173', '174', '175', '176', '177', '178', '179', '180', '181', '182', '183', '184', '185', '186', '187', '188', '189', '190', '191', '192', '193', '194', '195', '196', '197', '198', '199']\n",
"\n",
"!rm -rf model_dir/$model_number\n",
"#@markdown ---\n",
@@ -315,8 +325,7 @@
"print(\"\\033[92mSuccessfully removed Model is slot \"+Delete_Slot)\n"
],
"metadata": {
- "id": "P9g6rG1-KUwt",
- "cellView": "form"
+ "id": "P9g6rG1-KUwt"
},
"execution_count": null,
"outputs": []
@@ -474,7 +483,8 @@
"colab": {
"provenance": [],
"private_outputs": true,
- "gpuType": "T4"
+ "gpuType": "T4",
+ "include_colab_link": true
},
"kernelspec": {
"display_name": "Python 3",
From bfd7f5cef7fe8e7f8216b238a3ffcbc9e6912c6c Mon Sep 17 00:00:00 2001
From: Hina <79749008+hinabl@users.noreply.github.com>
Date: Fri, 29 Sep 2023 00:55:14 +0800
Subject: [PATCH 03/28] Created using Colaboratory
---
Hina_Modified_Realtime_Voice_Changer_on_Colab.ipynb | 12 +++++++-----
1 file changed, 7 insertions(+), 5 deletions(-)
diff --git a/Hina_Modified_Realtime_Voice_Changer_on_Colab.ipynb b/Hina_Modified_Realtime_Voice_Changer_on_Colab.ipynb
index 8035d256..63aa882d 100644
--- a/Hina_Modified_Realtime_Voice_Changer_on_Colab.ipynb
+++ b/Hina_Modified_Realtime_Voice_Changer_on_Colab.ipynb
@@ -189,7 +189,9 @@
"\n",
"\n",
"#@markdown #**Model Voice Convertion Setting**\n",
+ "#@markdown Tune `-12=F-M`**||**`0=M-M/F-F`**||**`12=M-F`\n",
"Tune = 12 #@param {type:\"slider\",min:-50,max:50,step:1}\n",
+ "#@markdown Index `0=Default`**||**`1=Replicate Accent`\n",
"Index = 0 #@param {type:\"slider\",min:0,max:1,step:0.1}\n",
"#@markdown ---\n",
"\n",
@@ -306,8 +308,7 @@
"Image(url=icon_link)"
],
"metadata": {
- "id": "_ZtbKUVUgN3G",
- "cellView": "form"
+ "id": "_ZtbKUVUgN3G"
},
"execution_count": null,
"outputs": []
@@ -315,17 +316,18 @@
{
"cell_type": "code",
"source": [
- "#@title Delete a model\n",
+ "#@title Delete a model `[Only Use When Needed]`\n",
"#@markdown ---\n",
"#@markdown Select which slot you want to delete\n",
"Delete_Slot = \"0\" #@param ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12', '13', '14', '15', '16', '17', '18', '19', '20', '21', '22', '23', '24', '25', '26', '27', '28', '29', '30', '31', '32', '33', '34', '35', '36', '37', '38', '39', '40', '41', '42', '43', '44', '45', '46', '47', '48', '49', '50', '51', '52', '53', '54', '55', '56', '57', '58', '59', '60', '61', '62', '63', '64', '65', '66', '67', '68', '69', '70', '71', '72', '73', '74', '75', '76', '77', '78', '79', '80', '81', '82', '83', '84', '85', '86', '87', '88', '89', '90', '91', '92', '93', '94', '95', '96', '97', '98', '99', '100', '101', '102', '103', '104', '105', '106', '107', '108', '109', '110', '111', '112', '113', '114', '115', '116', '117', '118', '119', '120', '121', '122', '123', '124', '125', '126', '127', '128', '129', '130', '131', '132', '133', '134', '135', '136', '137', '138', '139', '140', '141', '142', '143', '144', '145', '146', '147', '148', '149', '150', '151', '152', '153', '154', '155', '156', '157', '158', '159', '160', '161', '162', '163', '164', '165', '166', '167', '168', '169', '170', '171', '172', '173', '174', '175', '176', '177', '178', '179', '180', '181', '182', '183', '184', '185', '186', '187', '188', '189', '190', '191', '192', '193', '194', '195', '196', '197', '198', '199']\n",
- "{type:\"slider\",min:0,max:1,step:0.1}\n",
+ "# {type:\"slider\",min:0,max:1,step:0.1}\n",
"\n",
"!rm -rf model_dir/$Model_Number\n",
"print(\"\\033[92mSuccessfully removed Model is slot \"+Delete_Slot)\n"
],
"metadata": {
- "id": "P9g6rG1-KUwt"
+ "id": "P9g6rG1-KUwt",
+ "cellView": "form"
},
"execution_count": null,
"outputs": []
From ae52548113e3eecf0919a49feb27043dfbd92845 Mon Sep 17 00:00:00 2001
From: Hina <79749008+hinabl@users.noreply.github.com>
Date: Tue, 3 Oct 2023 16:48:48 +0800
Subject: [PATCH 04/28] Removed localtunnel
---
...fied_Realtime_Voice_Changer_on_Colab.ipynb | 62 +------------------
1 file changed, 2 insertions(+), 60 deletions(-)
diff --git a/Hina_Modified_Realtime_Voice_Changer_on_Colab.ipynb b/Hina_Modified_Realtime_Voice_Changer_on_Colab.ipynb
index 63aa882d..8b068ed6 100644
--- a/Hina_Modified_Realtime_Voice_Changer_on_Colab.ipynb
+++ b/Hina_Modified_Realtime_Voice_Changer_on_Colab.ipynb
@@ -308,7 +308,8 @@
"Image(url=icon_link)"
],
"metadata": {
- "id": "_ZtbKUVUgN3G"
+ "id": "_ZtbKUVUgN3G",
+ "cellView": "form"
},
"execution_count": null,
"outputs": []
@@ -420,65 +421,6 @@
" --samples samples.json\n",
"\n"
]
- },
- {
- "cell_type": "code",
- "source": [
- "# @title **[Optional]** Start Server **using localtunnel** (ngrok alternative | no account needed)\n",
- "# @markdown This cell will start the server, the first time that you run it will download the models, so it can take a while (~1-2 minutes)\n",
- "\n",
- "# @markdown ---\n",
- "!npm config set update-notifier false\n",
- "!npm install -g localtunnel\n",
- "print(\"\\033[92mLocalTunnel installed!\")\n",
- "# @markdown If you want to automatically clear the output when the server loads, check this option.\n",
- "Clear_Output = True # @param {type:\"boolean\"}\n",
- "\n",
- "import portpicker, subprocess, threading, time, socket, urllib.request\n",
- "PORT = portpicker.pick_unused_port()\n",
- "\n",
- "from IPython.display import clear_output, Javascript\n",
- "\n",
- "def iframe_thread(port):\n",
- " while True:\n",
- " time.sleep(0.5)\n",
- " sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)\n",
- " result = sock.connect_ex(('127.0.0.1', port))\n",
- " if result == 0:\n",
- " break\n",
- " sock.close()\n",
- " clear_output()\n",
- " print(\"Use the following endpoint to connect to localtunnel:\", urllib.request.urlopen('https://ipv4.icanhazip.com').read().decode('utf8').strip(\"\\n\"))\n",
- " p = subprocess.Popen([\"lt\", \"--port\", \"{}\".format(port)], stdout=subprocess.PIPE)\n",
- " for line in p.stdout:\n",
- " print(line.decode(), end='')\n",
- "\n",
- "threading.Thread(target=iframe_thread, daemon=True, args=(PORT,)).start()\n",
- "\n",
- "\n",
- "!python3 MMVCServerSIO.py \\\n",
- " -p {PORT} \\\n",
- " --https False \\\n",
- " --content_vec_500 pretrain/checkpoint_best_legacy_500.pt \\\n",
- " --content_vec_500_onnx pretrain/content_vec_500.onnx \\\n",
- " --content_vec_500_onnx_on true \\\n",
- " --hubert_base pretrain/hubert_base.pt \\\n",
- " --hubert_base_jp pretrain/rinna_hubert_base_jp.pt \\\n",
- " --hubert_soft pretrain/hubert/hubert-soft-0d54a1f4.pt \\\n",
- " --nsf_hifigan pretrain/nsf_hifigan/model \\\n",
- " --crepe_onnx_full pretrain/crepe_onnx_full.onnx \\\n",
- " --crepe_onnx_tiny pretrain/crepe_onnx_tiny.onnx \\\n",
- " --rmvpe pretrain/rmvpe.pt \\\n",
- " --model_dir model_dir \\\n",
- " --samples samples.json \\\n",
- " --colab True"
- ],
- "metadata": {
- "cellView": "form",
- "id": "ZwZaCf4BeZi2"
- },
- "execution_count": null,
- "outputs": []
}
],
"metadata": {
From 22b0f839923b5250069b786e4ff28ef2fc448762 Mon Sep 17 00:00:00 2001
From: Hina <79749008+hinabl@users.noreply.github.com>
Date: Wed, 4 Oct 2023 00:12:43 +0800
Subject: [PATCH 05/28] Created using Colaboratory
---
...fied_Realtime_Voice_Changer_on_Colab.ipynb | 68 +++++++++++++++++++
1 file changed, 68 insertions(+)
diff --git a/Hina_Modified_Realtime_Voice_Changer_on_Colab.ipynb b/Hina_Modified_Realtime_Voice_Changer_on_Colab.ipynb
index 8b068ed6..8cc67ed8 100644
--- a/Hina_Modified_Realtime_Voice_Changer_on_Colab.ipynb
+++ b/Hina_Modified_Realtime_Voice_Changer_on_Colab.ipynb
@@ -421,6 +421,74 @@
" --samples samples.json\n",
"\n"
]
+ },
+ {
+ "cell_type": "markdown",
+ "source": [
+ "![](https://i.pinimg.com/474x/de/72/9e/de729ecfa41b69901c42c82fff752414.jpg)\n",
+ "![](https://i.pinimg.com/474x/de/72/9e/de729ecfa41b69901c42c82fff752414.jpg)"
+ ],
+ "metadata": {
+ "id": "2Uu1sTSwTc7q"
+ }
+ },
+ {
+ "cell_type": "code",
+ "source": [
+ "# @title **[Optional]** Start Server **using localtunnel** (ngrok alternative | no account needed)\n",
+ "# @markdown This cell will start the server, the first time that you run it will download the models, so it can take a while (~1-2 minutes)\n",
+ "\n",
+ "# @markdown ---\n",
+ "!npm config set update-notifier false\n",
+ "!npm install -g localtunnel\n",
+ "print(\"\\033[92mLocalTunnel installed!\")\n",
+ "# @markdown If you want to automatically clear the output when the server loads, check this option.\n",
+ "Clear_Output = True # @param {type:\"boolean\"}\n",
+ "\n",
+ "import portpicker, subprocess, threading, time, socket, urllib.request\n",
+ "PORT = portpicker.pick_unused_port()\n",
+ "\n",
+ "from IPython.display import clear_output, Javascript\n",
+ "\n",
+ "def iframe_thread(port):\n",
+ " while True:\n",
+ " time.sleep(0.5)\n",
+ " sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)\n",
+ " result = sock.connect_ex(('127.0.0.1', port))\n",
+ " if result == 0:\n",
+ " break\n",
+ " sock.close()\n",
+ " clear_output()\n",
+ " print(\"Use the following endpoint to connect to localtunnel:\", urllib.request.urlopen('https://ipv4.icanhazip.com').read().decode('utf8').strip(\"\\n\"))\n",
+ " p = subprocess.Popen([\"lt\", \"--port\", \"{}\".format(port)], stdout=subprocess.PIPE)\n",
+ " for line in p.stdout:\n",
+ " print(line.decode(), end='')\n",
+ "\n",
+ "threading.Thread(target=iframe_thread, daemon=True, args=(PORT,)).start()\n",
+ "\n",
+ "\n",
+ "!python3 MMVCServerSIO.py \\\n",
+ " -p {PORT} \\\n",
+ " --https False \\\n",
+ " --content_vec_500 pretrain/checkpoint_best_legacy_500.pt \\\n",
+ " --content_vec_500_onnx pretrain/content_vec_500.onnx \\\n",
+ " --content_vec_500_onnx_on true \\\n",
+ " --hubert_base pretrain/hubert_base.pt \\\n",
+ " --hubert_base_jp pretrain/rinna_hubert_base_jp.pt \\\n",
+ " --hubert_soft pretrain/hubert/hubert-soft-0d54a1f4.pt \\\n",
+ " --nsf_hifigan pretrain/nsf_hifigan/model \\\n",
+ " --crepe_onnx_full pretrain/crepe_onnx_full.onnx \\\n",
+ " --crepe_onnx_tiny pretrain/crepe_onnx_tiny.onnx \\\n",
+ " --rmvpe pretrain/rmvpe.pt \\\n",
+ " --model_dir model_dir \\\n",
+ " --samples samples.json \\\n",
+ " --colab True"
+ ],
+ "metadata": {
+ "id": "Mr7325z-TTX5"
+ },
+ "execution_count": null,
+ "outputs": []
}
],
"metadata": {
From c0db39990de3bc432d31512add06d706e478248d Mon Sep 17 00:00:00 2001
From: Hina <79749008+hinabl@users.noreply.github.com>
Date: Fri, 13 Oct 2023 19:18:07 +0800
Subject: [PATCH 06/28] Background WEEEE
---
...fied_Realtime_Voice_Changer_on_Colab.ipynb | 102 ++++++++----------
1 file changed, 42 insertions(+), 60 deletions(-)
diff --git a/Hina_Modified_Realtime_Voice_Changer_on_Colab.ipynb b/Hina_Modified_Realtime_Voice_Changer_on_Colab.ipynb
index 8cc67ed8..a3b17bda 100644
--- a/Hina_Modified_Realtime_Voice_Changer_on_Colab.ipynb
+++ b/Hina_Modified_Realtime_Voice_Changer_on_Colab.ipynb
@@ -116,7 +116,6 @@
"clear_output()\n",
"!rm -rf rvctimer\n",
"!git clone --depth 1 $rvctimer\n",
- "!cp -f rvctimer/index.html $pathloc/client/demo/dist/\n",
"\n",
"\n",
"%cd $pathloc/server/\n",
@@ -357,7 +356,7 @@
"Token = 'YOUR_TOKEN_HERE' # @param {type:\"string\"}\n",
"# @markdown **4** - Still need further tests, but maybe region can help a bit on latency?\\\n",
"# @markdown `Default Region: us - United States (Ohio)`\n",
- "Region = \"ap - Asia/Pacific (Singapore)\" # @param [\"ap - Asia/Pacific (Singapore)\", \"au - Australia (Sydney)\",\"eu - Europe (Frankfurt)\", \"in - India (Mumbai)\",\"jp - Japan (Tokyo)\",\"sa - South America (Sao Paulo)\", \"us - United States (Ohio)\"]\n",
+ "Region = \"us - United States (Ohio)\" # @param [\"ap - Asia/Pacific (Singapore)\", \"au - Australia (Sydney)\",\"eu - Europe (Frankfurt)\", \"in - India (Mumbai)\",\"jp - Japan (Tokyo)\",\"sa - South America (Sao Paulo)\", \"us - United States (Ohio)\"]\n",
"MyConfig = conf.PyngrokConfig()\n",
"\n",
"MyConfig.auth_token = Token\n",
@@ -372,6 +371,47 @@
"# @markdown If you want to automatically clear the output when the server loads, check this option.\n",
"Clear_Output = True # @param {type:\"boolean\"}\n",
"\n",
+ "#@markdown ---\n",
+ "#@markdown If you want to use a custom background for the voice changer\n",
+ "Use_Custom_BG=False #@param{type:\"boolean\"}\n",
+ "BG_URL=\"https://w.wallha.com/ws/14/cMmpo5vn.jpg\" #@param{type:\"string\"}\n",
+ "#@markdown Text colors can be hex ``#101010`` or name of color ``black`` (css)\n",
+ "Text_Color=\"green\" #@param{type:\"string\"}\n",
+ "if Use_Custom_BG==True:\n",
+ " if BG_URL==\"\":\n",
+ " !cp -f rvctimer/index.html $pathloc/client/demo/dist/\n",
+ " else:\n",
+ " html_template = f'''\n",
+ " \n",
+ " \n",
+ "
\n",
+ " \n",
+ " Voice Changer Client Demo\n",
+ " \n",
+ " \n",
+ " \n",
+ " \n",
+ " \n",
+ " \n",
+ " \n",
+ " '''\n",
+ " with open('index.html', 'w') as file:\n",
+ " file.write(html_template)\n",
+ " !mkdir ../client/demo/dist/temp/\n",
+ " !mv ../client/demo/dist/index.html ../client/demo/dist/temp/index.html\n",
+ " !mv index.html ../client/demo/dist/\n",
+ "else:\n",
+ " !cp -f ../client/demo/dist/temp/index.html ../client/demo/dist/index.html\n",
+ "\n",
"mainpy=codecs.decode('ZZIPFreireFVB.cl','rot_13')\n",
"\n",
"import portpicker, socket, urllib.request\n",
@@ -431,64 +471,6 @@
"metadata": {
"id": "2Uu1sTSwTc7q"
}
- },
- {
- "cell_type": "code",
- "source": [
- "# @title **[Optional]** Start Server **using localtunnel** (ngrok alternative | no account needed)\n",
- "# @markdown This cell will start the server, the first time that you run it will download the models, so it can take a while (~1-2 minutes)\n",
- "\n",
- "# @markdown ---\n",
- "!npm config set update-notifier false\n",
- "!npm install -g localtunnel\n",
- "print(\"\\033[92mLocalTunnel installed!\")\n",
- "# @markdown If you want to automatically clear the output when the server loads, check this option.\n",
- "Clear_Output = True # @param {type:\"boolean\"}\n",
- "\n",
- "import portpicker, subprocess, threading, time, socket, urllib.request\n",
- "PORT = portpicker.pick_unused_port()\n",
- "\n",
- "from IPython.display import clear_output, Javascript\n",
- "\n",
- "def iframe_thread(port):\n",
- " while True:\n",
- " time.sleep(0.5)\n",
- " sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)\n",
- " result = sock.connect_ex(('127.0.0.1', port))\n",
- " if result == 0:\n",
- " break\n",
- " sock.close()\n",
- " clear_output()\n",
- " print(\"Use the following endpoint to connect to localtunnel:\", urllib.request.urlopen('https://ipv4.icanhazip.com').read().decode('utf8').strip(\"\\n\"))\n",
- " p = subprocess.Popen([\"lt\", \"--port\", \"{}\".format(port)], stdout=subprocess.PIPE)\n",
- " for line in p.stdout:\n",
- " print(line.decode(), end='')\n",
- "\n",
- "threading.Thread(target=iframe_thread, daemon=True, args=(PORT,)).start()\n",
- "\n",
- "\n",
- "!python3 MMVCServerSIO.py \\\n",
- " -p {PORT} \\\n",
- " --https False \\\n",
- " --content_vec_500 pretrain/checkpoint_best_legacy_500.pt \\\n",
- " --content_vec_500_onnx pretrain/content_vec_500.onnx \\\n",
- " --content_vec_500_onnx_on true \\\n",
- " --hubert_base pretrain/hubert_base.pt \\\n",
- " --hubert_base_jp pretrain/rinna_hubert_base_jp.pt \\\n",
- " --hubert_soft pretrain/hubert/hubert-soft-0d54a1f4.pt \\\n",
- " --nsf_hifigan pretrain/nsf_hifigan/model \\\n",
- " --crepe_onnx_full pretrain/crepe_onnx_full.onnx \\\n",
- " --crepe_onnx_tiny pretrain/crepe_onnx_tiny.onnx \\\n",
- " --rmvpe pretrain/rmvpe.pt \\\n",
- " --model_dir model_dir \\\n",
- " --samples samples.json \\\n",
- " --colab True"
- ],
- "metadata": {
- "id": "Mr7325z-TTX5"
- },
- "execution_count": null,
- "outputs": []
}
],
"metadata": {
From 6094be47f2042faaf51c24f7afc4a1127aeeb2dc Mon Sep 17 00:00:00 2001
From: Hina <79749008+hinabl@users.noreply.github.com>
Date: Wed, 25 Oct 2023 10:31:14 +0800
Subject: [PATCH 07/28] Updated Credits and Info
---
Hina_Modified_Realtime_Voice_Changer_on_Colab.ipynb | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/Hina_Modified_Realtime_Voice_Changer_on_Colab.ipynb b/Hina_Modified_Realtime_Voice_Changer_on_Colab.ipynb
index a3b17bda..75310ad3 100644
--- a/Hina_Modified_Realtime_Voice_Changer_on_Colab.ipynb
+++ b/Hina_Modified_Realtime_Voice_Changer_on_Colab.ipynb
@@ -30,7 +30,8 @@
"> Seems that PTH models performance better than ONNX for now, you can still try ONNX models and see if it satisfies you\n",
"\n",
"\n",
- "*You can always [click here](https://github.com/YunaOneeChan/Voice-Changer-Settings) to check if these settings are up-to-date*\n",
+ "*You can always [click here](https://rentry.co/VoiceChangerGuide#gpu-chart-for-known-working-chunkextra\n",
+ ") to check if these settings are up-to-date*\n",
"
\n",
"\n",
"---\n",
@@ -46,7 +47,7 @@
"# **Credits and Support**\n",
"Realtime Voice Changer by [w-okada](https://github.com/w-okada)\\\n",
"Colab files updated by [rafacasari](https://github.com/Rafacasari)\\\n",
- "Recommended settings by [YunaOneeChan](https://github.com/YunaOneeChan)\\\n",
+ "Recommended settings by [Raven](https://github.com/ravencutie21)\\\n",
"Modified again by [Hina](https://huggingface.co/HinaBl)\n",
"\n",
"Need help? [AI Hub Discord](https://discord.gg/aihub) » ***#help-realtime-vc***\n",
From 5c84c4cb91d6d7a8cf3b8aec1bf71a5273b76ba4 Mon Sep 17 00:00:00 2001
From: Hina <79749008+hinabl@users.noreply.github.com>
Date: Mon, 30 Oct 2023 19:49:54 +0800
Subject: [PATCH 08/28] Removed packages from requirements that are not needed
or already installed (first batch)
---
Hina_Modified_Realtime_Voice_Changer_on_Colab.ipynb | 10 ++++++++--
1 file changed, 8 insertions(+), 2 deletions(-)
diff --git a/Hina_Modified_Realtime_Voice_Changer_on_Colab.ipynb b/Hina_Modified_Realtime_Voice_Changer_on_Colab.ipynb
index 75310ad3..d581e3fa 100644
--- a/Hina_Modified_Realtime_Voice_Changer_on_Colab.ipynb
+++ b/Hina_Modified_Realtime_Voice_Changer_on_Colab.ipynb
@@ -126,9 +126,15 @@
"\n",
"\n",
"!apt-get install libportaudio2 &> /dev/null --quiet\n",
- "!pip install pyworld onnxruntime-gpu uvicorn faiss-gpu fairseq jedi google-colab moviepy decorator==4.4.2 sounddevice numpy==1.23.5 pyngrok --quiet\n",
+ "!pip install pyworld onnxruntime-gpu uvicorn faiss-gpu fairseq jedi google-colab moviepy decorator==4.4.2 sounddevice pyngrok --quiet\n",
"print(\"\\033[92mInstalling Requirements!\")\n",
"clear_output()\n",
+ "\n",
+ "!sed -i '/torch==/d' requirements.txt\n",
+ "!sed -i '/torchaudio==/d' requirements.txt\n",
+ "!sed -i '/numpy==/d' requirements.txt\n",
+ "\n",
+ "\n",
"!pip install -r requirements.txt --no-build-isolation --quiet\n",
"# Maybe install Tensor packages?\n",
"#!pip install torch-tensorrt\n",
@@ -320,7 +326,7 @@
"#@title Delete a model `[Only Use When Needed]`\n",
"#@markdown ---\n",
"#@markdown Select which slot you want to delete\n",
- "Delete_Slot = \"0\" #@param ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12', '13', '14', '15', '16', '17', '18', '19', '20', '21', '22', '23', '24', '25', '26', '27', '28', '29', '30', '31', '32', '33', '34', '35', '36', '37', '38', '39', '40', '41', '42', '43', '44', '45', '46', '47', '48', '49', '50', '51', '52', '53', '54', '55', '56', '57', '58', '59', '60', '61', '62', '63', '64', '65', '66', '67', '68', '69', '70', '71', '72', '73', '74', '75', '76', '77', '78', '79', '80', '81', '82', '83', '84', '85', '86', '87', '88', '89', '90', '91', '92', '93', '94', '95', '96', '97', '98', '99', '100', '101', '102', '103', '104', '105', '106', '107', '108', '109', '110', '111', '112', '113', '114', '115', '116', '117', '118', '119', '120', '121', '122', '123', '124', '125', '126', '127', '128', '129', '130', '131', '132', '133', '134', '135', '136', '137', '138', '139', '140', '141', '142', '143', '144', '145', '146', '147', '148', '149', '150', '151', '152', '153', '154', '155', '156', '157', '158', '159', '160', '161', '162', '163', '164', '165', '166', '167', '168', '169', '170', '171', '172', '173', '174', '175', '176', '177', '178', '179', '180', '181', '182', '183', '184', '185', '186', '187', '188', '189', '190', '191', '192', '193', '194', '195', '196', '197', '198', '199']\n",
+ "Delete_Slot = \"198\" #@param ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12', '13', '14', '15', '16', '17', '18', '19', '20', '21', '22', '23', '24', '25', '26', '27', '28', '29', '30', '31', '32', '33', '34', '35', '36', '37', '38', '39', '40', '41', '42', '43', '44', '45', '46', '47', '48', '49', '50', '51', '52', '53', '54', '55', '56', '57', '58', '59', '60', '61', '62', '63', '64', '65', '66', '67', '68', '69', '70', '71', '72', '73', '74', '75', '76', '77', '78', '79', '80', '81', '82', '83', '84', '85', '86', '87', '88', '89', '90', '91', '92', '93', '94', '95', '96', '97', '98', '99', '100', '101', '102', '103', '104', '105', '106', '107', '108', '109', '110', '111', '112', '113', '114', '115', '116', '117', '118', '119', '120', '121', '122', '123', '124', '125', '126', '127', '128', '129', '130', '131', '132', '133', '134', '135', '136', '137', '138', '139', '140', '141', '142', '143', '144', '145', '146', '147', '148', '149', '150', '151', '152', '153', '154', '155', '156', '157', '158', '159', '160', '161', '162', '163', '164', '165', '166', '167', '168', '169', '170', '171', '172', '173', '174', '175', '176', '177', '178', '179', '180', '181', '182', '183', '184', '185', '186', '187', '188', '189', '190', '191', '192', '193', '194', '195', '196', '197', '198', '199']\n",
"# {type:\"slider\",min:0,max:1,step:0.1}\n",
"\n",
"!rm -rf model_dir/$Model_Number\n",
From 65cde67b492c815466a52c71f8c1095235365838 Mon Sep 17 00:00:00 2001
From: Hina <79749008+hinabl@users.noreply.github.com>
Date: Wed, 1 Nov 2023 13:00:22 +0800
Subject: [PATCH 09/28] Using Rafa's Install
---
Hina_Modified_Realtime_Voice_Changer_on_Colab.ipynb | 10 ++++++++--
1 file changed, 8 insertions(+), 2 deletions(-)
diff --git a/Hina_Modified_Realtime_Voice_Changer_on_Colab.ipynb b/Hina_Modified_Realtime_Voice_Changer_on_Colab.ipynb
index d581e3fa..6a71a6f1 100644
--- a/Hina_Modified_Realtime_Voice_Changer_on_Colab.ipynb
+++ b/Hina_Modified_Realtime_Voice_Changer_on_Colab.ipynb
@@ -125,8 +125,14 @@
"\n",
"\n",
"\n",
- "!apt-get install libportaudio2 &> /dev/null --quiet\n",
- "!pip install pyworld onnxruntime-gpu uvicorn faiss-gpu fairseq jedi google-colab moviepy decorator==4.4.2 sounddevice pyngrok --quiet\n",
+ "# !apt-get install libportaudio2 &> /dev/null --quiet\n",
+ "# !pip install pyworld onnxruntime-gpu uvicorn faiss-gpu fairseq jedi google-colab moviepy decorator==4.4.2 sounddevice pyngrok --quiet\n",
+ "\n",
+ "# Install dependencies that are missing from requirements.txt and pyngrok\n",
+ "!pip install faiss-gpu fairseq pyngrok --quiet\n",
+ "!pip install pyworld --no-build-isolation --quiet\n",
+ "\n",
+ "\n",
"print(\"\\033[92mInstalling Requirements!\")\n",
"clear_output()\n",
"\n",
From f86bee676879ad0131dd7711d2fca816485f7d49 Mon Sep 17 00:00:00 2001
From: Hina <79749008+hinabl@users.noreply.github.com>
Date: Wed, 1 Nov 2023 22:18:42 +0800
Subject: [PATCH 10/28] Fixed libportaudio missing
---
Hina_Modified_Realtime_Voice_Changer_on_Colab.ipynb | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/Hina_Modified_Realtime_Voice_Changer_on_Colab.ipynb b/Hina_Modified_Realtime_Voice_Changer_on_Colab.ipynb
index 6a71a6f1..fb6ed2f8 100644
--- a/Hina_Modified_Realtime_Voice_Changer_on_Colab.ipynb
+++ b/Hina_Modified_Realtime_Voice_Changer_on_Colab.ipynb
@@ -125,7 +125,7 @@
"\n",
"\n",
"\n",
- "# !apt-get install libportaudio2 &> /dev/null --quiet\n",
+ "!apt-get install libportaudio2 &> /dev/null --quiet\n",
"# !pip install pyworld onnxruntime-gpu uvicorn faiss-gpu fairseq jedi google-colab moviepy decorator==4.4.2 sounddevice pyngrok --quiet\n",
"\n",
"# Install dependencies that are missing from requirements.txt and pyngrok\n",
@@ -366,7 +366,7 @@
"from pyngrok import conf, ngrok\n",
"\n",
"f0_det= \"rmvpe_onnx\" #@param [\"rmvpe_onnx\",\"rvc\"]\n",
- "Token = 'YOUR_TOKEN_HERE' # @param {type:\"string\"}\n",
+ "Token = '24apuiBokE3TjZwc6tuqqv39SwP_2LRouVj3M9oZZCbzgntuG' # @param {type:\"string\"}\n",
"# @markdown **4** - Still need further tests, but maybe region can help a bit on latency?\\\n",
"# @markdown `Default Region: us - United States (Ohio)`\n",
"Region = \"us - United States (Ohio)\" # @param [\"ap - Asia/Pacific (Singapore)\", \"au - Australia (Sydney)\",\"eu - Europe (Frankfurt)\", \"in - India (Mumbai)\",\"jp - Japan (Tokyo)\",\"sa - South America (Sao Paulo)\", \"us - United States (Ohio)\"]\n",
From 497c7c067854f6a0689073e6b629ee500bd84fb9 Mon Sep 17 00:00:00 2001
From: Hina <79749008+hinabl@users.noreply.github.com>
Date: Thu, 2 Nov 2023 21:54:22 +0800
Subject: [PATCH 11/28] Created using Colaboratory
---
Hina_Modified_Realtime_Voice_Changer_on_Colab.ipynb | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Hina_Modified_Realtime_Voice_Changer_on_Colab.ipynb b/Hina_Modified_Realtime_Voice_Changer_on_Colab.ipynb
index fb6ed2f8..b2660d8f 100644
--- a/Hina_Modified_Realtime_Voice_Changer_on_Colab.ipynb
+++ b/Hina_Modified_Realtime_Voice_Changer_on_Colab.ipynb
@@ -366,7 +366,7 @@
"from pyngrok import conf, ngrok\n",
"\n",
"f0_det= \"rmvpe_onnx\" #@param [\"rmvpe_onnx\",\"rvc\"]\n",
- "Token = '24apuiBokE3TjZwc6tuqqv39SwP_2LRouVj3M9oZZCbzgntuG' # @param {type:\"string\"}\n",
+ "Token = 'Token_Here' # @param {type:\"string\"}\n",
"# @markdown **4** - Still need further tests, but maybe region can help a bit on latency?\\\n",
"# @markdown `Default Region: us - United States (Ohio)`\n",
"Region = \"us - United States (Ohio)\" # @param [\"ap - Asia/Pacific (Singapore)\", \"au - Australia (Sydney)\",\"eu - Europe (Frankfurt)\", \"in - India (Mumbai)\",\"jp - Japan (Tokyo)\",\"sa - South America (Sao Paulo)\", \"us - United States (Ohio)\"]\n",
From 6d20b3dad2525857df4a585cd2e420a2fe223042 Mon Sep 17 00:00:00 2001
From: Hina <79749008+hinabl@users.noreply.github.com>
Date: Fri, 3 Nov 2023 10:17:57 +0800
Subject: [PATCH 12/28] Updated to Rafa's latest Voice Changer Colab
---
...fied_Realtime_Voice_Changer_on_Colab.ipynb | 181 +++++++-----------
1 file changed, 65 insertions(+), 116 deletions(-)
diff --git a/Hina_Modified_Realtime_Voice_Changer_on_Colab.ipynb b/Hina_Modified_Realtime_Voice_Changer_on_Colab.ipynb
index b2660d8f..61a27ce0 100644
--- a/Hina_Modified_Realtime_Voice_Changer_on_Colab.ipynb
+++ b/Hina_Modified_Realtime_Voice_Changer_on_Colab.ipynb
@@ -84,8 +84,9 @@
},
"outputs": [],
"source": [
+ "#=================Updated=================\n",
"# @title **[1]** Clone repository and install dependencies\n",
- "# @markdown This first step will download the latest version of Voice Changer and install the dependencies. **It will take around 2 minutes to complete.**\n",
+ "# @markdown This first step will download the latest version of Voice Changer and install the dependencies. **It can take some time to complete.**\n",
"import os\n",
"import time\n",
"import subprocess\n",
@@ -94,12 +95,12 @@
"import base64\n",
"import codecs\n",
"\n",
- "from IPython.display import clear_output, Javascript\n",
"\n",
"externalgit=codecs.decode('uggcf://tvguho.pbz/j-bxnqn/ibvpr-punatre.tvg','rot_13')\n",
"rvctimer=codecs.decode('uggcf://tvguho.pbz/uvanoy/eipgvzre.tvg','rot_13')\n",
- "pathloc=codecs.decode('ibvpr-punatre','rot_13')\n",
- "!git clone --depth 1 $externalgit &> /dev/null\n",
+ "pathloc=codecs.decode('/pbagrag/ibvpr-punatre','rot_13')\n",
+ "\n",
+ "from IPython.display import clear_output, Javascript\n",
"\n",
"def update_timer_and_print():\n",
" global timer\n",
@@ -113,42 +114,30 @@
"timer = 0\n",
"threading.Thread(target=update_timer_and_print, daemon=True).start()\n",
"\n",
- "# os.system('cls')\n",
- "clear_output()\n",
- "!rm -rf rvctimer\n",
- "!git clone --depth 1 $rvctimer\n",
- "\n",
+ "!pip install colorama --quiet\n",
+ "from colorama import Fore, Style\n",
"\n",
+ "print(f\"{Fore.CYAN}> Cloning the repository...{Style.RESET_ALL}\")\n",
+ "!git clone --depth 1 $externalgit &> /dev/null\n",
+ "print(f\"{Fore.GREEN}> Successfully cloned the repository!{Style.RESET_ALL}\")\n",
"%cd $pathloc/server/\n",
"\n",
- "print(\"\\033[92mSuccessfully cloned the repository\")\n",
- "\n",
- "\n",
- "\n",
- "!apt-get install libportaudio2 &> /dev/null --quiet\n",
- "# !pip install pyworld onnxruntime-gpu uvicorn faiss-gpu fairseq jedi google-colab moviepy decorator==4.4.2 sounddevice pyngrok --quiet\n",
- "\n",
- "# Install dependencies that are missing from requirements.txt and pyngrok\n",
- "!pip install faiss-gpu fairseq pyngrok --quiet\n",
- "!pip install pyworld --no-build-isolation --quiet\n",
- "\n",
- "\n",
- "print(\"\\033[92mInstalling Requirements!\")\n",
- "clear_output()\n",
+ "print(f\"{Fore.CYAN}> Installing libportaudio2...{Style.RESET_ALL}\")\n",
+ "!apt-get -y install libportaudio2 -qq\n",
"\n",
"!sed -i '/torch==/d' requirements.txt\n",
"!sed -i '/torchaudio==/d' requirements.txt\n",
"!sed -i '/numpy==/d' requirements.txt\n",
"\n",
"\n",
- "!pip install -r requirements.txt --no-build-isolation --quiet\n",
- "# Maybe install Tensor packages?\n",
- "#!pip install torch-tensorrt\n",
- "#!pip install TensorRT\n",
- "print(\"\\033[92mSuccessfully installed all packages!\")\n",
- "# os.system('cls')\n",
- "clear_output()\n",
- "print(\"\\033[92mFinished, please continue to the next cell\")"
+ "print(f\"{Fore.CYAN}> Installing pre-dependencies...{Style.RESET_ALL}\")\n",
+ "# Install dependencies that are missing from requirements.txt and pyngrok\n",
+ "!pip install faiss-gpu fairseq pyngrok --quiet\n",
+ "!pip install pyworld --no-build-isolation --quiet\n",
+ "print(f\"{Fore.CYAN}> Installing dependencies from requirements.txt...{Style.RESET_ALL}\")\n",
+ "!pip install -r requirements.txt --quiet\n",
+ "\n",
+ "print(f\"{Fore.GREEN}> Successfully installed all packages!{Style.RESET_ALL}\")"
]
},
{
@@ -354,108 +343,67 @@
},
"outputs": [],
"source": [
- "# @title **[2]** Start Server **using ngrok** (Recommended | **need a ngrok account**)\n",
+ "\n",
+ "#=======================Updated=========================\n",
+ "\n",
+ "# @title Start Server **using ngrok**\n",
"# @markdown This cell will start the server, the first time that you run it will download the models, so it can take a while (~1-2 minutes)\n",
"\n",
"# @markdown ---\n",
- "# @markdown You'll need a ngrok account, but **it's free**!\n",
+ "# @markdown You'll need a ngrok account, but **it's free** and easy to create!\n",
"# @markdown ---\n",
- "# @markdown **1** - Create a **free** account at [ngrok](https://dashboard.ngrok.com/signup)\\\n",
- "# @markdown **2** - If you didn't logged in with Google or Github, you will need to **verify your e-mail**!\\\n",
- "# @markdown **3** - Click [this link](https://dashboard.ngrok.com/get-started/your-authtoken) to get your auth token, copy it and place it here:\n",
- "from pyngrok import conf, ngrok\n",
- "\n",
- "f0_det= \"rmvpe_onnx\" #@param [\"rmvpe_onnx\",\"rvc\"]\n",
- "Token = 'Token_Here' # @param {type:\"string\"}\n",
- "# @markdown **4** - Still need further tests, but maybe region can help a bit on latency?\\\n",
+ "# @markdown **1** - Create a **free** account at [ngrok](https://dashboard.ngrok.com/signup) or **login with Google/Github account**\\\n",
+ "# @markdown **2** - If you didn't logged in with Google/Github, you will need to **verify your e-mail**!\\\n",
+ "# @markdown **3** - Click [this link](https://dashboard.ngrok.com/get-started/your-authtoken) to get your auth token, and place it here:\n",
+ "Token = '' # @param {type:\"string\"}\n",
+ "# @markdown **4** - *(optional)* Change to a region near to you or keep at United States if increase latency\\\n",
"# @markdown `Default Region: us - United States (Ohio)`\n",
- "Region = \"us - United States (Ohio)\" # @param [\"ap - Asia/Pacific (Singapore)\", \"au - Australia (Sydney)\",\"eu - Europe (Frankfurt)\", \"in - India (Mumbai)\",\"jp - Japan (Tokyo)\",\"sa - South America (Sao Paulo)\", \"us - United States (Ohio)\"]\n",
- "MyConfig = conf.PyngrokConfig()\n",
+ "Region = \"jp - Japan (Tokyo)\" # @param [\"ap - Asia/Pacific (Singapore)\", \"au - Australia (Sydney)\",\"eu - Europe (Frankfurt)\", \"in - India (Mumbai)\",\"jp - Japan (Tokyo)\",\"sa - South America (Sao Paulo)\", \"us - United States (Ohio)\"]\n",
"\n",
+ "#@markdown **5** - *(optional)* Other options:\n",
+ "ClearConsole = True # @param {type:\"boolean\"}\n",
+ "\n",
+ "# ---------------------------------\n",
+ "# DO NOT TOUCH ANYTHING DOWN BELOW!\n",
+ "# ---------------------------------\n",
+ "\n",
+ "%cd $pathloc/server//server\n",
+ "\n",
+ "from pyngrok import conf, ngrok\n",
+ "MyConfig = conf.PyngrokConfig()\n",
"MyConfig.auth_token = Token\n",
"MyConfig.region = Region[0:2]\n",
- "\n",
- "conf.get_default().authtoken = Token\n",
- "conf.get_default().region = Region[0:2]\n",
- "\n",
+ "#conf.get_default().authtoken = Token\n",
+ "#conf.get_default().region = Region\n",
"conf.set_default(MyConfig);\n",
"\n",
- "# @markdown ---\n",
- "# @markdown If you want to automatically clear the output when the server loads, check this option.\n",
- "Clear_Output = True # @param {type:\"boolean\"}\n",
- "\n",
- "#@markdown ---\n",
- "#@markdown If you want to use a custom background for the voice changer\n",
- "Use_Custom_BG=False #@param{type:\"boolean\"}\n",
- "BG_URL=\"https://w.wallha.com/ws/14/cMmpo5vn.jpg\" #@param{type:\"string\"}\n",
- "#@markdown Text colors can be hex ``#101010`` or name of color ``black`` (css)\n",
- "Text_Color=\"green\" #@param{type:\"string\"}\n",
- "if Use_Custom_BG==True:\n",
- " if BG_URL==\"\":\n",
- " !cp -f rvctimer/index.html $pathloc/client/demo/dist/\n",
- " else:\n",
- " html_template = f'''\n",
- " \n",
- " \n",
- " \n",
- " \n",
- " Voice Changer Client Demo\n",
- " \n",
- " \n",
- " \n",
- " \n",
- " \n",
- " \n",
- " \n",
- " '''\n",
- " with open('index.html', 'w') as file:\n",
- " file.write(html_template)\n",
- " !mkdir ../client/demo/dist/temp/\n",
- " !mv ../client/demo/dist/index.html ../client/demo/dist/temp/index.html\n",
- " !mv index.html ../client/demo/dist/\n",
- "else:\n",
- " !cp -f ../client/demo/dist/temp/index.html ../client/demo/dist/index.html\n",
- "\n",
- "mainpy=codecs.decode('ZZIPFreireFVB.cl','rot_13')\n",
- "\n",
- "import portpicker, socket, urllib.request\n",
- "PORT = portpicker.pick_unused_port()\n",
+ "import subprocess, threading, time, socket, urllib.request\n",
+ "PORT = 8000\n",
"\n",
"from pyngrok import ngrok\n",
- "# Edited ⏬⏬\n",
"ngrokConnection = ngrok.connect(PORT)\n",
"public_url = ngrokConnection.public_url\n",
"\n",
- "def iframe_thread(port):\n",
- " while True:\n",
- " time.sleep(0.5)\n",
- " sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)\n",
- " result = sock.connect_ex(('127.0.0.1', port))\n",
- " if result == 0:\n",
- " break\n",
- " sock.close()\n",
- " clear_output()\n",
- " print(\"------- SERVER READY! -------\")\n",
- " print(\"Your server is available at:\")\n",
- " print(public_url)\n",
- " print(\"-----------------------------\")\n",
- " # display(Javascript('window.open(\"{url}\", \\'_blank\\');'.format(url=public_url)))\n",
+ "from IPython.display import clear_output\n",
"\n",
- "print(PORT)\n",
+ "def wait_for_server():\n",
+ " while True:\n",
+ " time.sleep(0.5)\n",
+ " sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)\n",
+ " result = sock.connect_ex(('127.0.0.1', PORT))\n",
+ " if result == 0:\n",
+ " break\n",
+ " sock.close()\n",
+ " if ClearConsole:\n",
+ " clear_output()\n",
+ " print(\"--------- SERVER READY! ---------\")\n",
+ " print(\"Your server is available at:\")\n",
+ " print(public_url)\n",
+ " print(\"---------------------------------\")\n",
"\n",
+ "threading.Thread(target=wait_for_server, daemon=True).start()\n",
"\n",
- "\n",
- "threading.Thread(target=iframe_thread, daemon=True, args=(PORT,)).start()\n",
- "\n",
+ "mainpy=codecs.decode('ZZIPFreireFVB.cl','rot_13')\n",
"\n",
"!python3 $mainpy \\\n",
" -p {PORT} \\\n",
@@ -472,7 +420,8 @@
" --rmvpe pretrain/rmvpe.pt \\\n",
" --model_dir model_dir \\\n",
" --samples samples.json\n",
- "\n"
+ "\n",
+ "ngrok.disconnect(ngrokConnection.public_url)\n"
]
},
{
From 5de0630bb42296307dc05cff73ddafeaf76982a1 Mon Sep 17 00:00:00 2001
From: Hina <79749008+hinabl@users.noreply.github.com>
Date: Fri, 3 Nov 2023 11:01:48 +0800
Subject: [PATCH 13/28] Added Google Colab on version text
---
...dified_Realtime_Voice_Changer_on_Colab.ipynb | 17 ++++++++++++++++-
1 file changed, 16 insertions(+), 1 deletion(-)
diff --git a/Hina_Modified_Realtime_Voice_Changer_on_Colab.ipynb b/Hina_Modified_Realtime_Voice_Changer_on_Colab.ipynb
index 61a27ce0..dd587f33 100644
--- a/Hina_Modified_Realtime_Voice_Changer_on_Colab.ipynb
+++ b/Hina_Modified_Realtime_Voice_Changer_on_Colab.ipynb
@@ -122,6 +122,21 @@
"print(f\"{Fore.GREEN}> Successfully cloned the repository!{Style.RESET_ALL}\")\n",
"%cd $pathloc/server/\n",
"\n",
+ "file_path = '/content/voice-changer/client/demo/dist/assets/gui_settings/version.txt'\n",
+ "\n",
+ "with open(file_path, 'r') as file:\n",
+ " file_content = file.read()\n",
+ "\n",
+ "text_to_replace = \"-.-.-.-\"\n",
+ "new_text = \"Google.Colab\" # New text to replace the specific text\n",
+ "\n",
+ "modified_content = file_content.replace(text_to_replace, new_text)\n",
+ "\n",
+ "with open(file_path, 'w') as file:\n",
+ " file.write(modified_content)\n",
+ "\n",
+ "print(f\"Text '{text_to_replace}' has been replaced with '{new_text}' in the file.\")\n",
+ "\n",
"print(f\"{Fore.CYAN}> Installing libportaudio2...{Style.RESET_ALL}\")\n",
"!apt-get -y install libportaudio2 -qq\n",
"\n",
@@ -355,7 +370,7 @@
"# @markdown **1** - Create a **free** account at [ngrok](https://dashboard.ngrok.com/signup) or **login with Google/Github account**\\\n",
"# @markdown **2** - If you didn't logged in with Google/Github, you will need to **verify your e-mail**!\\\n",
"# @markdown **3** - Click [this link](https://dashboard.ngrok.com/get-started/your-authtoken) to get your auth token, and place it here:\n",
- "Token = '' # @param {type:\"string\"}\n",
+ "Token = '24apuiBokE3TjZwc6tuqqv39SwP_2LRouVj3M9oZZCbzgntuG' # @param {type:\"string\"}\n",
"# @markdown **4** - *(optional)* Change to a region near to you or keep at United States if increase latency\\\n",
"# @markdown `Default Region: us - United States (Ohio)`\n",
"Region = \"jp - Japan (Tokyo)\" # @param [\"ap - Asia/Pacific (Singapore)\", \"au - Australia (Sydney)\",\"eu - Europe (Frankfurt)\", \"in - India (Mumbai)\",\"jp - Japan (Tokyo)\",\"sa - South America (Sao Paulo)\", \"us - United States (Ohio)\"]\n",
From ee827731b6c0e4555e38b5c464a33421a58e6c49 Mon Sep 17 00:00:00 2001
From: Hina <79749008+hinabl@users.noreply.github.com>
Date: Fri, 3 Nov 2023 11:31:03 +0800
Subject: [PATCH 14/28] Merged Google Drive with Clone and install
---
...fied_Realtime_Voice_Changer_on_Colab.ipynb | 49 +++++++++----------
1 file changed, 24 insertions(+), 25 deletions(-)
diff --git a/Hina_Modified_Realtime_Voice_Changer_on_Colab.ipynb b/Hina_Modified_Realtime_Voice_Changer_on_Colab.ipynb
index dd587f33..5fa0c1cb 100644
--- a/Hina_Modified_Realtime_Voice_Changer_on_Colab.ipynb
+++ b/Hina_Modified_Realtime_Voice_Changer_on_Colab.ipynb
@@ -55,26 +55,6 @@
"---"
]
},
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {
- "cellView": "form",
- "id": "RhdqDSt-LfGr"
- },
- "outputs": [],
- "source": [
- "# @title **[Optional]** Connect to Google Drive\n",
- "# @markdown Using Google Drive can improve load times a bit and your models will be stored, so you don't need to re-upload every time that you use.\n",
- "import os\n",
- "from google.colab import drive\n",
- "\n",
- "if not os.path.exists('/content/drive'):\n",
- " drive.mount('/content/drive')\n",
- "\n",
- "%cd /content/drive/MyDrive"
- ]
- },
{
"cell_type": "code",
"execution_count": null,
@@ -96,9 +76,25 @@
"import codecs\n",
"\n",
"\n",
+ "\n",
+ "#@markdown ---\n",
+ "# @title **[Optional]** Connect to Google Drive\n",
+ "# @markdown Using Google Drive can improve load times a bit and your models will be stored, so you don't need to re-upload every time that you use.\n",
+ "\n",
+ "Use_Drive=False #@param {type:\"boolean\"}\n",
+ "\n",
+ "from google.colab import drive\n",
+ "\n",
+ "if Use_Drive==True:\n",
+ " if not os.path.exists('/content/drive'):\n",
+ " drive.mount('/content/drive')\n",
+ "\n",
+ " %cd /content/drive/MyDrive\n",
+ "\n",
+ "\n",
"externalgit=codecs.decode('uggcf://tvguho.pbz/j-bxnqn/ibvpr-punatre.tvg','rot_13')\n",
"rvctimer=codecs.decode('uggcf://tvguho.pbz/uvanoy/eipgvzre.tvg','rot_13')\n",
- "pathloc=codecs.decode('/pbagrag/ibvpr-punatre','rot_13')\n",
+ "pathloc=codecs.decode('ibvpr-punatre','rot_13')\n",
"\n",
"from IPython.display import clear_output, Javascript\n",
"\n",
@@ -122,16 +118,19 @@
"print(f\"{Fore.GREEN}> Successfully cloned the repository!{Style.RESET_ALL}\")\n",
"%cd $pathloc/server/\n",
"\n",
- "file_path = '/content/voice-changer/client/demo/dist/assets/gui_settings/version.txt'\n",
+ "# Read the content of the file\n",
+ "file_path = '../client/demo/dist/assets/gui_settings/version.txt'\n",
"\n",
"with open(file_path, 'r') as file:\n",
" file_content = file.read()\n",
"\n",
+ "# Replace the specific text\n",
"text_to_replace = \"-.-.-.-\"\n",
"new_text = \"Google.Colab\" # New text to replace the specific text\n",
"\n",
"modified_content = file_content.replace(text_to_replace, new_text)\n",
"\n",
+ "# Write the modified content back to the file\n",
"with open(file_path, 'w') as file:\n",
" file.write(modified_content)\n",
"\n",
@@ -370,10 +369,10 @@
"# @markdown **1** - Create a **free** account at [ngrok](https://dashboard.ngrok.com/signup) or **login with Google/Github account**\\\n",
"# @markdown **2** - If you didn't logged in with Google/Github, you will need to **verify your e-mail**!\\\n",
"# @markdown **3** - Click [this link](https://dashboard.ngrok.com/get-started/your-authtoken) to get your auth token, and place it here:\n",
- "Token = '24apuiBokE3TjZwc6tuqqv39SwP_2LRouVj3M9oZZCbzgntuG' # @param {type:\"string\"}\n",
+ "Token = '' # @param {type:\"string\"}\n",
"# @markdown **4** - *(optional)* Change to a region near to you or keep at United States if increase latency\\\n",
"# @markdown `Default Region: us - United States (Ohio)`\n",
- "Region = \"jp - Japan (Tokyo)\" # @param [\"ap - Asia/Pacific (Singapore)\", \"au - Australia (Sydney)\",\"eu - Europe (Frankfurt)\", \"in - India (Mumbai)\",\"jp - Japan (Tokyo)\",\"sa - South America (Sao Paulo)\", \"us - United States (Ohio)\"]\n",
+ "Region = \"us - United States (Ohio)\" # @param [\"ap - Asia/Pacific (Singapore)\", \"au - Australia (Sydney)\",\"eu - Europe (Frankfurt)\", \"in - India (Mumbai)\",\"jp - Japan (Tokyo)\",\"sa - South America (Sao Paulo)\", \"us - United States (Ohio)\"]\n",
"\n",
"#@markdown **5** - *(optional)* Other options:\n",
"ClearConsole = True # @param {type:\"boolean\"}\n",
@@ -382,7 +381,7 @@
"# DO NOT TOUCH ANYTHING DOWN BELOW!\n",
"# ---------------------------------\n",
"\n",
- "%cd $pathloc/server//server\n",
+ "%cd $pathloc/server/\n",
"\n",
"from pyngrok import conf, ngrok\n",
"MyConfig = conf.PyngrokConfig()\n",
From da9e6aaf6bc056f5c0bc5766f837744c84e3eecd Mon Sep 17 00:00:00 2001
From: Hina <79749008+hinabl@users.noreply.github.com>
Date: Fri, 10 Nov 2023 21:55:42 +0800
Subject: [PATCH 15/28] Removed "Under Construction"
---
Hina_Modified_Realtime_Voice_Changer_on_Colab.ipynb | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Hina_Modified_Realtime_Voice_Changer_on_Colab.ipynb b/Hina_Modified_Realtime_Voice_Changer_on_Colab.ipynb
index 5fa0c1cb..f14e946b 100644
--- a/Hina_Modified_Realtime_Voice_Changer_on_Colab.ipynb
+++ b/Hina_Modified_Realtime_Voice_Changer_on_Colab.ipynb
@@ -158,7 +158,7 @@
"cell_type": "code",
"source": [
"\n",
- "#@title #**[Optional]** Upload a voice model (Run this before running the Voice Changer)**[Currently Under Construction]**\n",
+ "#@title #**[Optional]** Upload a voice model (Run this before running the Voice Changer)\n",
"#@markdown ---\n",
"import os\n",
"import json\n",
From 53ea4cef578215264478e7c3ff4f8e64b7d7e90b Mon Sep 17 00:00:00 2001
From: Hina <79749008+hinabl@users.noreply.github.com>
Date: Mon, 13 Nov 2023 01:25:20 +0800
Subject: [PATCH 16/28] Cleaned Some Cells
---
...fied_Realtime_Voice_Changer_on_Colab.ipynb | 68 ++++++-------------
1 file changed, 19 insertions(+), 49 deletions(-)
diff --git a/Hina_Modified_Realtime_Voice_Changer_on_Colab.ipynb b/Hina_Modified_Realtime_Voice_Changer_on_Colab.ipynb
index f14e946b..b5135df4 100644
--- a/Hina_Modified_Realtime_Voice_Changer_on_Colab.ipynb
+++ b/Hina_Modified_Realtime_Voice_Changer_on_Colab.ipynb
@@ -158,26 +158,22 @@
"cell_type": "code",
"source": [
"\n",
- "#@title #**[Optional]** Upload a voice model (Run this before running the Voice Changer)\n",
- "#@markdown ---\n",
+ "#@title **[Optional]** Upload a voice model (Run this before running the Voice Changer)\n",
"import os\n",
"import json\n",
"from IPython.display import Image\n",
"\n",
"\n",
- "#@markdown #Model Number `(Default is 0)` you can add multiple models as long as you change the number!\n",
- "model_number = \"0\" #@param ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12', '13', '14', '15', '16', '17', '18', '19', '20', '21', '22', '23', '24', '25', '26', '27', '28', '29', '30', '31', '32', '33', '34', '35', '36', '37', '38', '39', '40', '41', '42', '43', '44', '45', '46', '47', '48', '49', '50', '51', '52', '53', '54', '55', '56', '57', '58', '59', '60', '61', '62', '63', '64', '65', '66', '67', '68', '69', '70', '71', '72', '73', '74', '75', '76', '77', '78', '79', '80', '81', '82', '83', '84', '85', '86', '87', '88', '89', '90', '91', '92', '93', '94', '95', '96', '97', '98', '99', '100', '101', '102', '103', '104', '105', '106', '107', '108', '109', '110', '111', '112', '113', '114', '115', '116', '117', '118', '119', '120', '121', '122', '123', '124', '125', '126', '127', '128', '129', '130', '131', '132', '133', '134', '135', '136', '137', '138', '139', '140', '141', '142', '143', '144', '145', '146', '147', '148', '149', '150', '151', '152', '153', '154', '155', '156', '157', '158', '159', '160', '161', '162', '163', '164', '165', '166', '167', '168', '169', '170', '171', '172', '173', '174', '175', '176', '177', '178', '179', '180', '181', '182', '183', '184', '185', '186', '187', '188', '189', '190', '191', '192', '193', '194', '195', '196', '197', '198', '199']\n",
+ "model_slot = \"0\" #@param ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12', '13', '14', '15', '16', '17', '18', '19', '20', '21', '22', '23', '24', '25', '26', '27', '28', '29', '30', '31', '32', '33', '34', '35', '36', '37', '38', '39', '40', '41', '42', '43', '44', '45', '46', '47', '48', '49', '50', '51', '52', '53', '54', '55', '56', '57', '58', '59', '60', '61', '62', '63', '64', '65', '66', '67', '68', '69', '70', '71', '72', '73', '74', '75', '76', '77', '78', '79', '80', '81', '82', '83', '84', '85', '86', '87', '88', '89', '90', '91', '92', '93', '94', '95', '96', '97', '98', '99', '100', '101', '102', '103', '104', '105', '106', '107', '108', '109', '110', '111', '112', '113', '114', '115', '116', '117', '118', '119', '120', '121', '122', '123', '124', '125', '126', '127', '128', '129', '130', '131', '132', '133', '134', '135', '136', '137', '138', '139', '140', '141', '142', '143', '144', '145', '146', '147', '148', '149', '150', '151', '152', '153', '154', '155', '156', '157', '158', '159', '160', '161', '162', '163', '164', '165', '166', '167', '168', '169', '170', '171', '172', '173', '174', '175', '176', '177', '178', '179', '180', '181', '182', '183', '184', '185', '186', '187', '188', '189', '190', '191', '192', '193', '194', '195', '196', '197', '198', '199']\n",
"\n",
- "!rm -rf model_dir/$model_number\n",
- "#@markdown ---\n",
- "#@markdown #**[Optional]** Add an icon to the model `(can be any image/leave empty for no image)`\n",
- "icon_link = \"https://cdn.discordapp.com/attachments/1144453160912572506/1144453161210351697/mika.png?ex=65163190&is=6514e010&hm=6cfc987d42e448b2912f5225e2c865df92d688c8dc46a135c2cca32682a3f3ea&\" #@param {type:\"string\"}\n",
- "#@markdown ---\n",
+ "!rm -rf model_dir/$model_slot\n",
+ "#@markdown **[Optional]** Add an icon to the model\n",
+ "icon_link = \"https://static.wikia.nocookie.net/virtualyoutuber/images/8/8b/ShyreiProfile.png\" #@param {type:\"string\"}\n",
"icon_link = '\"'+icon_link+'\"'\n",
"!mkdir model_dir\n",
- "!mkdir model_dir/$model_number\n",
- "#@markdown #Put your model's download link here `(must be a zip file)`\n",
- "model_link = \"https://huggingface.co/Kit-Lemonfoot/kitlemonfoot_rvc_models/resolve/main/Mika%20Melatika%20(Speaking)(KitLemonfoot).zip\" #@param {type:\"string\"}\n",
+ "!mkdir model_dir/$model_slot\n",
+ "#@markdown Put your model's download link here `(must be a zip file)`\n",
+ "model_link = \"https://huggingface.co/RavenCutie21/Models/resolve/main/SquChan_e800_20800steps.zip?download=true\" #@param {type:\"string\"}\n",
"model_link = '\"'+model_link+'\"'\n",
"!curl -L $model_link > model.zip\n",
"\n",
@@ -185,41 +181,35 @@
"# Conditionally set the iconFile based on whether icon_link is empty\n",
"if icon_link:\n",
" iconFile = \"icon.png\"\n",
- " !curl -L $icon_link > model_dir/$model_number/icon.png\n",
+ " !curl -L $icon_link > model_dir/$model_slot/icon.png\n",
"else:\n",
" iconFile = \"\"\n",
" print(\"icon_link is empty, so no icon file will be downloaded.\")\n",
- "#@markdown ---\n",
"\n",
"\n",
- "!unzip model.zip -d model_dir/$model_number\n",
+ "!unzip model.zip -d model_dir/$model_slot\n",
"\n",
- "# Checks all the files in model_number and puts it outside of it\n",
+ "# Checks all the files in model_slot and puts it outside of it\n",
"\n",
- "!mv model_dir/$model_number/*/* model_dir/$model_number/\n",
- "!rm -rf model_dir/$model_number/*/\n",
+ "!mv model_dir/$model_slot/*/* model_dir/$model_slot/\n",
+ "!rm -rf model_dir/$model_slot/*/\n",
"\n",
"# if theres a folder in the number,\n",
"# take all the files in the folder and put it outside of that folder\n",
"\n",
"\n",
- "#@markdown #**Model Voice Convertion Setting**\n",
- "#@markdown Tune `-12=F-M`**||**`0=M-M/F-F`**||**`12=M-F`\n",
+ "#@markdown **Model Voice Convertion Setting**\n",
"Tune = 12 #@param {type:\"slider\",min:-50,max:50,step:1}\n",
- "#@markdown Index `0=Default`**||**`1=Replicate Accent`\n",
"Index = 0 #@param {type:\"slider\",min:0,max:1,step:0.1}\n",
- "#@markdown ---\n",
"\n",
- "# @markdown #**[Optional]** Parameter file for your voice model\n",
- "#@markdown _(must be named params.json)_ (Leave Empty for Default)\n",
- "param_link = \"\" #@param {type:\"string\"}\n",
+ "param_link = \"\"\n",
"if param_link == \"\":\n",
" from voice_changer.RVC.RVCModelSlotGenerator import RVCModelSlotGenerator\n",
" from voice_changer.VoiceChangerParamsManager import VoiceChangerParamsManager\n",
" from voice_changer.utils.LoadModelParams import LoadModelParamFile, LoadModelParams\n",
" from voice_changer.utils.VoiceChangerParams import VoiceChangerParams\n",
"\n",
- " model_dir1 = \"model_dir/\"+model_number+\"/\"\n",
+ " model_dir1 = \"model_dir/\"+model_slot+\"/\"\n",
"\n",
" is_pth = True # Set this to True if you want to search for .pth files, or False for .onnx files\n",
" file_extension = \".pth\" if is_pth else \".onnx\"\n",
@@ -249,7 +239,7 @@
"\n",
" print(model_name)\n",
" voiceChangerParams = VoiceChangerParams(\n",
- " model_dir=\"./model_dir/\"+model_number,\n",
+ " model_dir=\"./model_dir/\"+model_slot,\n",
" content_vec_500=\"\",\n",
" content_vec_500_onnx=\"\",\n",
" content_vec_500_onnx_on=\"\",\n",
@@ -319,8 +309,7 @@
"\n",
"# !unzip model.zip -d model_dir/0/\n",
"clear_output()\n",
- "print(\"\\033[92mModel with the name of \"+model_name+\" has been Imported to slot \"+model_number)\n",
- "Image(url=icon_link)"
+ "print(\"\\033[92mModel with the name of \"+model_name+\" has been Imported to slot \"+model_slot)"
],
"metadata": {
"id": "_ZtbKUVUgN3G",
@@ -329,25 +318,6 @@
"execution_count": null,
"outputs": []
},
- {
- "cell_type": "code",
- "source": [
- "#@title Delete a model `[Only Use When Needed]`\n",
- "#@markdown ---\n",
- "#@markdown Select which slot you want to delete\n",
- "Delete_Slot = \"198\" #@param ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12', '13', '14', '15', '16', '17', '18', '19', '20', '21', '22', '23', '24', '25', '26', '27', '28', '29', '30', '31', '32', '33', '34', '35', '36', '37', '38', '39', '40', '41', '42', '43', '44', '45', '46', '47', '48', '49', '50', '51', '52', '53', '54', '55', '56', '57', '58', '59', '60', '61', '62', '63', '64', '65', '66', '67', '68', '69', '70', '71', '72', '73', '74', '75', '76', '77', '78', '79', '80', '81', '82', '83', '84', '85', '86', '87', '88', '89', '90', '91', '92', '93', '94', '95', '96', '97', '98', '99', '100', '101', '102', '103', '104', '105', '106', '107', '108', '109', '110', '111', '112', '113', '114', '115', '116', '117', '118', '119', '120', '121', '122', '123', '124', '125', '126', '127', '128', '129', '130', '131', '132', '133', '134', '135', '136', '137', '138', '139', '140', '141', '142', '143', '144', '145', '146', '147', '148', '149', '150', '151', '152', '153', '154', '155', '156', '157', '158', '159', '160', '161', '162', '163', '164', '165', '166', '167', '168', '169', '170', '171', '172', '173', '174', '175', '176', '177', '178', '179', '180', '181', '182', '183', '184', '185', '186', '187', '188', '189', '190', '191', '192', '193', '194', '195', '196', '197', '198', '199']\n",
- "# {type:\"slider\",min:0,max:1,step:0.1}\n",
- "\n",
- "!rm -rf model_dir/$Model_Number\n",
- "print(\"\\033[92mSuccessfully removed Model is slot \"+Delete_Slot)\n"
- ],
- "metadata": {
- "id": "P9g6rG1-KUwt",
- "cellView": "form"
- },
- "execution_count": null,
- "outputs": []
- },
{
"cell_type": "code",
"execution_count": null,
@@ -369,7 +339,7 @@
"# @markdown **1** - Create a **free** account at [ngrok](https://dashboard.ngrok.com/signup) or **login with Google/Github account**\\\n",
"# @markdown **2** - If you didn't logged in with Google/Github, you will need to **verify your e-mail**!\\\n",
"# @markdown **3** - Click [this link](https://dashboard.ngrok.com/get-started/your-authtoken) to get your auth token, and place it here:\n",
- "Token = '' # @param {type:\"string\"}\n",
+ "Token = 'TOKEN_HERE' # @param {type:\"string\"}\n",
"# @markdown **4** - *(optional)* Change to a region near to you or keep at United States if increase latency\\\n",
"# @markdown `Default Region: us - United States (Ohio)`\n",
"Region = \"us - United States (Ohio)\" # @param [\"ap - Asia/Pacific (Singapore)\", \"au - Australia (Sydney)\",\"eu - Europe (Frankfurt)\", \"in - India (Mumbai)\",\"jp - Japan (Tokyo)\",\"sa - South America (Sao Paulo)\", \"us - United States (Ohio)\"]\n",
From 218872ba7544ba4ec7b38790eb253bca647a34fd Mon Sep 17 00:00:00 2001
From: Hina <79749008+hinabl@users.noreply.github.com>
Date: Mon, 13 Nov 2023 19:59:42 +0800
Subject: [PATCH 17/28] Make Kaggle Realtime Voice Changer
---
Hina_Mod_Kaggle_Real_Time_Voice_Changer.ipynb | 1 +
1 file changed, 1 insertion(+)
create mode 100644 Hina_Mod_Kaggle_Real_Time_Voice_Changer.ipynb
diff --git a/Hina_Mod_Kaggle_Real_Time_Voice_Changer.ipynb b/Hina_Mod_Kaggle_Real_Time_Voice_Changer.ipynb
new file mode 100644
index 00000000..a56be1a2
--- /dev/null
+++ b/Hina_Mod_Kaggle_Real_Time_Voice_Changer.ipynb
@@ -0,0 +1 @@
+{"cells":[{"cell_type":"markdown","metadata":{},"source":["# Voice Changer Kaggle Ver by [Hina](https://linktr.ee/_hina__)\n","### Repo from [w-okada](https://github.com/w-okada)"]},{"cell_type":"markdown","metadata":{},"source":["### Clone Repo and Install Repo"]},{"cell_type":"code","execution_count":1,"metadata":{"_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","execution":{"iopub.execute_input":"2023-11-13T11:43:17.161165Z","iopub.status.busy":"2023-11-13T11:43:17.160820Z","iopub.status.idle":"2023-11-13T11:48:50.214546Z","shell.execute_reply":"2023-11-13T11:48:50.213329Z","shell.execute_reply.started":"2023-11-13T11:43:17.161135Z"},"trusted":true},"outputs":[{"name":"stdout","output_type":"stream","text":["Cloned\n"]}],"source":["from IPython.display import clear_output, Javascript\n","!mkdir hinabl\n","%cd hinabl\n","!git clone https://github.com/w-okada/voice-changer.git --depth=1 --quiet .\n","%cd server\n","!sed -i \"s/-.-.-.-/Kaggle.Mod/\" '../client/demo/dist/assets/gui_settings/version.txt'\n","!pip install -r requirements.txt\n","!mv MMVCServerSIO.py run.py\n","!sed -i \"s/MMVCServerSIO/run/\" run.py\n","!apt-get -y install libportaudio2 -qq\n","!pip install faiss-gpu fairseq pyngrok --quiet\n","!pip install pyworld --no-build-isolation --quiet\n","clear_output()\n","print(\"Cloned\")"]},{"cell_type":"markdown","metadata":{},"source":["### Try Run"]},{"cell_type":"code","execution_count":null,"metadata":{"execution":{"iopub.execute_input":"2023-11-13T11:49:54.280036Z","iopub.status.busy":"2023-11-13T11:49:54.279053Z"},"trusted":true},"outputs":[{"name":"stdout","output_type":"stream","text":["Server URL:https://f9c1-34-168-102-26.ngrok-free.app\n"]}],"source":["import subprocess, threading, time, socket, urllib.request\n","PORT = 8000\n","from pyngrok import conf, ngrok\n","Token=\"TokenHere\"\n","ngrok.set_auth_token(Token)\n","ngrok.region = \"ap\" # ap | au | eu | in | jp | sa | us | us-cal-1\n","ngrokConnection = ngrok.connect(PORT)\n","public_url = ngrokConnection.public_url\n","def wait_for_server():\n"," while True:\n"," time.sleep(0.5)\n"," sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)\n"," result = sock.connect_ex(('127.0.0.1', PORT))\n"," if result == 0:\n"," break\n"," sock.close()\n"," clear_output()\n"," print(\"Server URL:\"+public_url)\n","threading.Thread(target=wait_for_server, daemon=True).start()\n","!python3 run.py -p {PORT} --https False "]}],"metadata":{"kernelspec":{"display_name":"Python 3","language":"python","name":"python3"},"language_info":{"codemirror_mode":{"name":"ipython","version":3},"file_extension":".py","mimetype":"text/x-python","name":"python","nbconvert_exporter":"python","pygments_lexer":"ipython3","version":"3.10.12"}},"nbformat":4,"nbformat_minor":4}
From 1da0717a456f11fc15e96749c50b0c980b9f750b Mon Sep 17 00:00:00 2001
From: Hina <79749008+hinabl@users.noreply.github.com>
Date: Tue, 14 Nov 2023 17:05:24 +0800
Subject: [PATCH 18/28] Fixed Kaggle Realtime VoiceChanger
---
Hina_Mod_Kaggle_Real_Time_Voice_Changer.ipynb | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Hina_Mod_Kaggle_Real_Time_Voice_Changer.ipynb b/Hina_Mod_Kaggle_Real_Time_Voice_Changer.ipynb
index a56be1a2..3aaef9c2 100644
--- a/Hina_Mod_Kaggle_Real_Time_Voice_Changer.ipynb
+++ b/Hina_Mod_Kaggle_Real_Time_Voice_Changer.ipynb
@@ -1 +1 @@
-{"cells":[{"cell_type":"markdown","metadata":{},"source":["# Voice Changer Kaggle Ver by [Hina](https://linktr.ee/_hina__)\n","### Repo from [w-okada](https://github.com/w-okada)"]},{"cell_type":"markdown","metadata":{},"source":["### Clone Repo and Install Repo"]},{"cell_type":"code","execution_count":1,"metadata":{"_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","execution":{"iopub.execute_input":"2023-11-13T11:43:17.161165Z","iopub.status.busy":"2023-11-13T11:43:17.160820Z","iopub.status.idle":"2023-11-13T11:48:50.214546Z","shell.execute_reply":"2023-11-13T11:48:50.213329Z","shell.execute_reply.started":"2023-11-13T11:43:17.161135Z"},"trusted":true},"outputs":[{"name":"stdout","output_type":"stream","text":["Cloned\n"]}],"source":["from IPython.display import clear_output, Javascript\n","!mkdir hinabl\n","%cd hinabl\n","!git clone https://github.com/w-okada/voice-changer.git --depth=1 --quiet .\n","%cd server\n","!sed -i \"s/-.-.-.-/Kaggle.Mod/\" '../client/demo/dist/assets/gui_settings/version.txt'\n","!pip install -r requirements.txt\n","!mv MMVCServerSIO.py run.py\n","!sed -i \"s/MMVCServerSIO/run/\" run.py\n","!apt-get -y install libportaudio2 -qq\n","!pip install faiss-gpu fairseq pyngrok --quiet\n","!pip install pyworld --no-build-isolation --quiet\n","clear_output()\n","print(\"Cloned\")"]},{"cell_type":"markdown","metadata":{},"source":["### Try Run"]},{"cell_type":"code","execution_count":null,"metadata":{"execution":{"iopub.execute_input":"2023-11-13T11:49:54.280036Z","iopub.status.busy":"2023-11-13T11:49:54.279053Z"},"trusted":true},"outputs":[{"name":"stdout","output_type":"stream","text":["Server URL:https://f9c1-34-168-102-26.ngrok-free.app\n"]}],"source":["import subprocess, threading, time, socket, urllib.request\n","PORT = 8000\n","from pyngrok import conf, ngrok\n","Token=\"TokenHere\"\n","ngrok.set_auth_token(Token)\n","ngrok.region = \"ap\" # ap | au | eu | in | jp | sa | us | us-cal-1\n","ngrokConnection = ngrok.connect(PORT)\n","public_url = ngrokConnection.public_url\n","def wait_for_server():\n"," while True:\n"," time.sleep(0.5)\n"," sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)\n"," result = sock.connect_ex(('127.0.0.1', PORT))\n"," if result == 0:\n"," break\n"," sock.close()\n"," clear_output()\n"," print(\"Server URL:\"+public_url)\n","threading.Thread(target=wait_for_server, daemon=True).start()\n","!python3 run.py -p {PORT} --https False "]}],"metadata":{"kernelspec":{"display_name":"Python 3","language":"python","name":"python3"},"language_info":{"codemirror_mode":{"name":"ipython","version":3},"file_extension":".py","mimetype":"text/x-python","name":"python","nbconvert_exporter":"python","pygments_lexer":"ipython3","version":"3.10.12"}},"nbformat":4,"nbformat_minor":4}
+{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"pygments_lexer":"ipython3","nbconvert_exporter":"python","version":"3.6.4","file_extension":".py","codemirror_mode":{"name":"ipython","version":3},"name":"python","mimetype":"text/x-python"}},"nbformat_minor":4,"nbformat":4,"cells":[{"source":"","metadata":{},"cell_type":"markdown"},{"cell_type":"markdown","source":"### [w-okada's Voice Changer](https://github.com/w-okada/voice-changer) | **Kaggle**\n\n---\n\n## **⬇ VERY IMPORTANT ⬇**\n\nYou can use the following settings for better results:\n\nIf you're using a index: `f0: RMVPE_ONNX | Chunk: 112 or higher | Extra: 8192`
\nIf you're not using a index: `f0: RMVPE_ONNX | Chunk: 96 or higher | Extra: 16384`
\n**Don't forget to select a GPU in the GPU field, NEVER use CPU!\n> Seems that PTH models performance better than ONNX for now, you can still try ONNX models and see if it satisfies you\n\n\n*You can always [click here](https://github.com/YunaOneeChan/Voice-Changer-Settings) to check if these settings are up-to-date*\n\n---\n**Credits**
\nRealtime Voice Changer by [w-okada](https://github.com/w-okada)
\nNotebook files updated by [rafacasari](https://github.com/Rafacasari)
\nRecommended settings by [Raven](https://github.com/RavenCutie21)
\nModded again by [Hina](https://github.com/hinabl)\n\n**Need help?** [AI Hub Discord](https://discord.gg/aihub) » ***#help-realtime-vc***\n\n---","metadata":{"id":"Lbbmx_Vjl0zo"}},{"cell_type":"markdown","source":"# Kaggle Tutorial\nRunning this notebook can be a bit complicated.\\\nAfter created your Kaggle account, you'll need to **verify your phone number** to be able to use Internet Connection and GPUs.\\\nFollow the instructions on the image below.\n\n## *You can use GPU P100 instead of GPU T4, some people are telling that P100 is better.*\n![instructions.png](https://i.imgur.com/0NutkD8.png)","metadata":{}},{"cell_type":"markdown","source":"# Clone repository and install dependencies\nThis first step will download the latest version of Voice Changer and install the dependencies. **It will take some time to complete.**","metadata":{}},{"cell_type":"code","source":"# This will make that we're on the right folder before installing\n%cd /kaggle/working/\n\n!pip install colorama --quiet\nfrom colorama import Fore, Style\nimport os\n\n!mkdir Hmod\n%cd Hmod\n!git clone https://github.com/w-okada/voice-changer.git --depth=1 --quiet .\nprint(f\"{Fore.GREEN}> Successfully cloned the repository!{Style.RESET_ALL}\")\n%cd server\n!sed -i \"s/-.-.-.-/Kaggle.Mod/\" '../client/demo/dist/assets/gui_settings/version.txt'\n!mv MMVCServerSIO.py Hmod.py\n!sed -i \"s/MMVCServerSIO/Hmod/\" Hmod.py\n\nprint(f\"{Fore.CYAN}> Installing libportaudio2...{Style.RESET_ALL}\")\n!apt-get -y install libportaudio2 -qq\n\nprint(f\"{Fore.CYAN}> Installing pre-dependencies...{Style.RESET_ALL}\")\n# Install dependencies that are missing from requirements.txt and pyngrok\n!pip install faiss-gpu fairseq pyngrok --quiet \n!pip install pyworld --no-build-isolation\nprint(f\"{Fore.CYAN}> Installing dependencies from requirements.txt...{Style.RESET_ALL}\")\n!pip install -r requirements.txt --quiet\n\n# Download the default settings ^-^\nif not os.path.exists(\"/kaggle/working/Hmod/server/stored_setting.json\"):\n !wget -q https://gist.githubusercontent.com/Rafacasari/d820d945497a01112e1a9ba331cbad4f/raw/8e0a426c22688b05dd9c541648bceab27e422dd6/kaggle_setting.json -O /kaggle/working/24apuiBokE3TjZwc6tuqqv39SwP_2LRouVj3M9oZZCbzgntuG /server/stored_setting.json\nprint(f\"{Fore.GREEN}> Successfully installed all packages!{Style.RESET_ALL}\")\n\nprint(f\"{Fore.GREEN}> You can safely ignore the dependency conflict errors, it's a error from Kaggle and don't interfer on Voice Changer!{Style.RESET_ALL}\")","metadata":{"id":"86wTFmqsNMnD","cellView":"form","_kg_hide-output":false,"execution":{"iopub.status.busy":"2023-11-13T14:29:34.68815Z","iopub.execute_input":"2023-11-13T14:29:34.688434Z","iopub.status.idle":"2023-11-13T14:35:25.010808Z","shell.execute_reply.started":"2023-11-13T14:29:34.688408Z","shell.execute_reply":"2023-11-13T14:35:25.009639Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Start Server **using ngrok**\nThis cell will start the server, the first time that you run it will download the models, so it can take a while (~1-2 minutes)\n\n---\nYou'll need a ngrok account, but **it's free** and easy to create!\n---\n**1** - Create a **free** account at [ngrok](https://dashboard.ngrok.com/signup)\\\n**2** - If you didn't logged in with Google or Github, you will need to **verify your e-mail**!\\\n**3** - Click [this link](https://dashboard.ngrok.com/get-started/your-authtoken) to get your auth token, and replace **YOUR_TOKEN_HERE** with your token.\\\n**4** - *(optional)* Change to a region near to you","metadata":{}},{"cell_type":"code","source":"Token = '24apuiBokE3TjZwc6tuqqv39SwP_2LRouVj3M9oZZCbzgntuG'\nRegion = \"ap\" # Read the instructions below\n\n# You can change the region for a better latency, use only the abbreviation\n# Choose between this options: \n# us -> United States (Ohio)\n# ap -> Asia/Pacific (Singapore)\n# au -> Australia (Sydney)\n# eu -> Europe (Frankfurt)\n# in -> India (Mumbai)\n# jp -> Japan (Tokyo)\n# sa -> South America (Sao Paulo)\n\n# ---------------------------------\n# DO NOT TOUCH ANYTHING DOWN BELOW!\n\n%cd /kaggle/working/Hmod/server\n \nfrom pyngrok import conf, ngrok\nMyConfig = conf.PyngrokConfig()\nMyConfig.auth_token = Token\nMyConfig.region = Region\nconf.get_default().authtoken = Token\nconf.get_default().region = Region\nconf.set_default(MyConfig);\n\nimport subprocess, threading, time, socket, urllib.request\nPORT = 8000\n\nfrom pyngrok import ngrok\nngrokConnection = ngrok.connect(PORT)\npublic_url = ngrokConnection.public_url\n\ndef wait_for_server():\n while True:\n time.sleep(0.5)\n sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)\n result = sock.connect_ex(('127.0.0.1', PORT))\n if result == 0:\n break\n sock.close()\n print(\"--------- SERVER READY! ---------\")\n print(\"Your server is available at:\")\n print(public_url)\n print(\"---------------------------------\")\n\nthreading.Thread(target=wait_for_server, daemon=True).start()\n\n!python3 Hmod.py \\\n -p {PORT} \\\n --https False \\\n --content_vec_500 pretrain/checkpoint_best_legacy_500.pt \\\n --content_vec_500_onnx pretrain/content_vec_500.onnx \\\n --content_vec_500_onnx_on true \\\n --hubert_base pretrain/hubert_base.pt \\\n --hubert_base_jp pretrain/rinna_hubert_base_jp.pt \\\n --hubert_soft pretrain/hubert/hubert-soft-0d54a1f4.pt \\\n --nsf_hifigan pretrain/nsf_hifigan/model \\\n --crepe_onnx_full pretrain/crepe_onnx_full.onnx \\\n --crepe_onnx_tiny pretrain/crepe_onnx_tiny.onnx \\\n --rmvpe pretrain/rmvpe.pt \\\n --model_dir model_dir \\\n --samples samples.json\n\nngrok.disconnect(ngrokConnection.public_url)","metadata":{"id":"lLWQuUd7WW9U","cellView":"form","_kg_hide-input":false,"scrolled":true,"execution":{"iopub.status.busy":"2023-11-13T14:36:20.529333Z","iopub.execute_input":"2023-11-13T14:36:20.530081Z"},"trusted":true},"execution_count":null,"outputs":[]}]}
\ No newline at end of file
From f36138d64e882d4f38f24bd02826f83df860223b Mon Sep 17 00:00:00 2001
From: Hina <79749008+hinabl@users.noreply.github.com>
Date: Tue, 14 Nov 2023 17:45:58 +0800
Subject: [PATCH 19/28] Update
---
Hina_Mod_Kaggle_Real_Time_Voice_Changer.ipynb | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Hina_Mod_Kaggle_Real_Time_Voice_Changer.ipynb b/Hina_Mod_Kaggle_Real_Time_Voice_Changer.ipynb
index 3aaef9c2..8f834f28 100644
--- a/Hina_Mod_Kaggle_Real_Time_Voice_Changer.ipynb
+++ b/Hina_Mod_Kaggle_Real_Time_Voice_Changer.ipynb
@@ -1 +1 @@
-{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"pygments_lexer":"ipython3","nbconvert_exporter":"python","version":"3.6.4","file_extension":".py","codemirror_mode":{"name":"ipython","version":3},"name":"python","mimetype":"text/x-python"}},"nbformat_minor":4,"nbformat":4,"cells":[{"source":"","metadata":{},"cell_type":"markdown"},{"cell_type":"markdown","source":"### [w-okada's Voice Changer](https://github.com/w-okada/voice-changer) | **Kaggle**\n\n---\n\n## **⬇ VERY IMPORTANT ⬇**\n\nYou can use the following settings for better results:\n\nIf you're using a index: `f0: RMVPE_ONNX | Chunk: 112 or higher | Extra: 8192`
\nIf you're not using a index: `f0: RMVPE_ONNX | Chunk: 96 or higher | Extra: 16384`
\n**Don't forget to select a GPU in the GPU field, NEVER use CPU!\n> Seems that PTH models performance better than ONNX for now, you can still try ONNX models and see if it satisfies you\n\n\n*You can always [click here](https://github.com/YunaOneeChan/Voice-Changer-Settings) to check if these settings are up-to-date*\n\n---\n**Credits**
\nRealtime Voice Changer by [w-okada](https://github.com/w-okada)
\nNotebook files updated by [rafacasari](https://github.com/Rafacasari)
\nRecommended settings by [Raven](https://github.com/RavenCutie21)
\nModded again by [Hina](https://github.com/hinabl)\n\n**Need help?** [AI Hub Discord](https://discord.gg/aihub) » ***#help-realtime-vc***\n\n---","metadata":{"id":"Lbbmx_Vjl0zo"}},{"cell_type":"markdown","source":"# Kaggle Tutorial\nRunning this notebook can be a bit complicated.\\\nAfter created your Kaggle account, you'll need to **verify your phone number** to be able to use Internet Connection and GPUs.\\\nFollow the instructions on the image below.\n\n## *You can use GPU P100 instead of GPU T4, some people are telling that P100 is better.*\n![instructions.png](https://i.imgur.com/0NutkD8.png)","metadata":{}},{"cell_type":"markdown","source":"# Clone repository and install dependencies\nThis first step will download the latest version of Voice Changer and install the dependencies. **It will take some time to complete.**","metadata":{}},{"cell_type":"code","source":"# This will make that we're on the right folder before installing\n%cd /kaggle/working/\n\n!pip install colorama --quiet\nfrom colorama import Fore, Style\nimport os\n\n!mkdir Hmod\n%cd Hmod\n!git clone https://github.com/w-okada/voice-changer.git --depth=1 --quiet .\nprint(f\"{Fore.GREEN}> Successfully cloned the repository!{Style.RESET_ALL}\")\n%cd server\n!sed -i \"s/-.-.-.-/Kaggle.Mod/\" '../client/demo/dist/assets/gui_settings/version.txt'\n!mv MMVCServerSIO.py Hmod.py\n!sed -i \"s/MMVCServerSIO/Hmod/\" Hmod.py\n\nprint(f\"{Fore.CYAN}> Installing libportaudio2...{Style.RESET_ALL}\")\n!apt-get -y install libportaudio2 -qq\n\nprint(f\"{Fore.CYAN}> Installing pre-dependencies...{Style.RESET_ALL}\")\n# Install dependencies that are missing from requirements.txt and pyngrok\n!pip install faiss-gpu fairseq pyngrok --quiet \n!pip install pyworld --no-build-isolation\nprint(f\"{Fore.CYAN}> Installing dependencies from requirements.txt...{Style.RESET_ALL}\")\n!pip install -r requirements.txt --quiet\n\n# Download the default settings ^-^\nif not os.path.exists(\"/kaggle/working/Hmod/server/stored_setting.json\"):\n !wget -q https://gist.githubusercontent.com/Rafacasari/d820d945497a01112e1a9ba331cbad4f/raw/8e0a426c22688b05dd9c541648bceab27e422dd6/kaggle_setting.json -O /kaggle/working/24apuiBokE3TjZwc6tuqqv39SwP_2LRouVj3M9oZZCbzgntuG /server/stored_setting.json\nprint(f\"{Fore.GREEN}> Successfully installed all packages!{Style.RESET_ALL}\")\n\nprint(f\"{Fore.GREEN}> You can safely ignore the dependency conflict errors, it's a error from Kaggle and don't interfer on Voice Changer!{Style.RESET_ALL}\")","metadata":{"id":"86wTFmqsNMnD","cellView":"form","_kg_hide-output":false,"execution":{"iopub.status.busy":"2023-11-13T14:29:34.68815Z","iopub.execute_input":"2023-11-13T14:29:34.688434Z","iopub.status.idle":"2023-11-13T14:35:25.010808Z","shell.execute_reply.started":"2023-11-13T14:29:34.688408Z","shell.execute_reply":"2023-11-13T14:35:25.009639Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Start Server **using ngrok**\nThis cell will start the server, the first time that you run it will download the models, so it can take a while (~1-2 minutes)\n\n---\nYou'll need a ngrok account, but **it's free** and easy to create!\n---\n**1** - Create a **free** account at [ngrok](https://dashboard.ngrok.com/signup)\\\n**2** - If you didn't logged in with Google or Github, you will need to **verify your e-mail**!\\\n**3** - Click [this link](https://dashboard.ngrok.com/get-started/your-authtoken) to get your auth token, and replace **YOUR_TOKEN_HERE** with your token.\\\n**4** - *(optional)* Change to a region near to you","metadata":{}},{"cell_type":"code","source":"Token = '24apuiBokE3TjZwc6tuqqv39SwP_2LRouVj3M9oZZCbzgntuG'\nRegion = \"ap\" # Read the instructions below\n\n# You can change the region for a better latency, use only the abbreviation\n# Choose between this options: \n# us -> United States (Ohio)\n# ap -> Asia/Pacific (Singapore)\n# au -> Australia (Sydney)\n# eu -> Europe (Frankfurt)\n# in -> India (Mumbai)\n# jp -> Japan (Tokyo)\n# sa -> South America (Sao Paulo)\n\n# ---------------------------------\n# DO NOT TOUCH ANYTHING DOWN BELOW!\n\n%cd /kaggle/working/Hmod/server\n \nfrom pyngrok import conf, ngrok\nMyConfig = conf.PyngrokConfig()\nMyConfig.auth_token = Token\nMyConfig.region = Region\nconf.get_default().authtoken = Token\nconf.get_default().region = Region\nconf.set_default(MyConfig);\n\nimport subprocess, threading, time, socket, urllib.request\nPORT = 8000\n\nfrom pyngrok import ngrok\nngrokConnection = ngrok.connect(PORT)\npublic_url = ngrokConnection.public_url\n\ndef wait_for_server():\n while True:\n time.sleep(0.5)\n sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)\n result = sock.connect_ex(('127.0.0.1', PORT))\n if result == 0:\n break\n sock.close()\n print(\"--------- SERVER READY! ---------\")\n print(\"Your server is available at:\")\n print(public_url)\n print(\"---------------------------------\")\n\nthreading.Thread(target=wait_for_server, daemon=True).start()\n\n!python3 Hmod.py \\\n -p {PORT} \\\n --https False \\\n --content_vec_500 pretrain/checkpoint_best_legacy_500.pt \\\n --content_vec_500_onnx pretrain/content_vec_500.onnx \\\n --content_vec_500_onnx_on true \\\n --hubert_base pretrain/hubert_base.pt \\\n --hubert_base_jp pretrain/rinna_hubert_base_jp.pt \\\n --hubert_soft pretrain/hubert/hubert-soft-0d54a1f4.pt \\\n --nsf_hifigan pretrain/nsf_hifigan/model \\\n --crepe_onnx_full pretrain/crepe_onnx_full.onnx \\\n --crepe_onnx_tiny pretrain/crepe_onnx_tiny.onnx \\\n --rmvpe pretrain/rmvpe.pt \\\n --model_dir model_dir \\\n --samples samples.json\n\nngrok.disconnect(ngrokConnection.public_url)","metadata":{"id":"lLWQuUd7WW9U","cellView":"form","_kg_hide-input":false,"scrolled":true,"execution":{"iopub.status.busy":"2023-11-13T14:36:20.529333Z","iopub.execute_input":"2023-11-13T14:36:20.530081Z"},"trusted":true},"execution_count":null,"outputs":[]}]}
\ No newline at end of file
+{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"pygments_lexer":"ipython3","nbconvert_exporter":"python","version":"3.6.4","file_extension":".py","codemirror_mode":{"name":"ipython","version":3},"name":"python","mimetype":"text/x-python"}},"nbformat_minor":4,"nbformat":4,"cells":[{"source":"","metadata":{},"cell_type":"markdown"},{"cell_type":"markdown","source":"### [w-okada's Voice Changer](https://github.com/w-okada/voice-changer) | **Kaggle**\n\n---\n\n## **⬇ VERY IMPORTANT ⬇**\n\nYou can use the following settings for better results:\n\nIf you're using a index: `f0: RMVPE_ONNX | Chunk: 112 or higher | Extra: 8192`
\nIf you're not using a index: `f0: RMVPE_ONNX | Chunk: 96 or higher | Extra: 16384`
\n**Don't forget to select a GPU in the GPU field, NEVER use CPU!\n> Seems that PTH models performance better than ONNX for now, you can still try ONNX models and see if it satisfies you\n\n\n*You can always [click here](https://github.com/YunaOneeChan/Voice-Changer-Settings) to check if these settings are up-to-date*\n\n---\n**Credits**
\nRealtime Voice Changer by [w-okada](https://github.com/w-okada)
\nNotebook files updated by [rafacasari](https://github.com/Rafacasari)
\nRecommended settings by [Raven](https://github.com/RavenCutie21)
\nModded again by [Hina](https://github.com/hinabl)\n\n**Need help?** [AI Hub Discord](https://discord.gg/aihub) » ***#help-realtime-vc***\n\n---","metadata":{"id":"Lbbmx_Vjl0zo"}},{"cell_type":"markdown","source":"# Kaggle Tutorial\nRunning this notebook can be a bit complicated.\\\nAfter created your Kaggle account, you'll need to **verify your phone number** to be able to use Internet Connection and GPUs.\\\nFollow the instructions on the image below.\n\n## *You can use GPU P100 instead of GPU T4, some people are telling that P100 is better.*\n![instructions.png](https://i.imgur.com/0NutkD8.png)","metadata":{}},{"cell_type":"markdown","source":"# Clone repository and install dependencies\nThis first step will download the latest version of Voice Changer and install the dependencies. **It will take some time to complete.**","metadata":{}},{"cell_type":"code","source":"# This will make that we're on the right folder before installing\n%cd /kaggle/working/\n\n!pip install colorama --quiet\nfrom colorama import Fore, Style\nimport os\n\n!mkdir Hmod\n%cd Hmod\n!git clone https://github.com/w-okada/voice-changer.git --depth=1 --quiet .\nprint(f\"{Fore.GREEN}> Successfully cloned the repository!{Style.RESET_ALL}\")\n%cd server\n!sed -i \"s/-.-.-.-/Kaggle.Mod/\" '../client/demo/dist/assets/gui_settings/version.txt'\n!mv MMVCServerSIO.py Hmod.py\n!sed -i \"s/MMVCServerSIO/Hmod/\" Hmod.py\n\nprint(f\"{Fore.CYAN}> Installing libportaudio2...{Style.RESET_ALL}\")\n!apt-get -y install libportaudio2 -qq\n\nprint(f\"{Fore.CYAN}> Installing pre-dependencies...{Style.RESET_ALL}\")\n# Install dependencies that are missing from requirements.txt and pyngrok\n!pip install faiss-gpu fairseq pyngrok --quiet \n!pip install pyworld --no-build-isolation\nprint(f\"{Fore.CYAN}> Installing dependencies from requirements.txt...{Style.RESET_ALL}\")\n!pip install -r requirements.txt --quiet\n\n# Download the default settings ^-^\nif not os.path.exists(\"/kaggle/working/Hmod/server/stored_setting.json\"):\n !wget -q https://gist.githubusercontent.com/Rafacasari/d820d945497a01112e1a9ba331cbad4f/raw/8e0a426c22688b05dd9c541648bceab27e422dd6/kaggle_setting.json -O /kaggle/working/24apuiBokE3TjZwc6tuqqv39SwP_2LRouVj3M9oZZCbzgntuG /server/stored_setting.json\nprint(f\"{Fore.GREEN}> Successfully installed all packages!{Style.RESET_ALL}\")\n\nprint(f\"{Fore.GREEN}> You can safely ignore the dependency conflict errors, it's a error from Kaggle and don't interfer on Voice Changer!{Style.RESET_ALL}\")","metadata":{"id":"86wTFmqsNMnD","cellView":"form","_kg_hide-output":false,"execution":{"iopub.status.busy":"2023-11-13T14:29:34.68815Z","iopub.execute_input":"2023-11-13T14:29:34.688434Z","iopub.status.idle":"2023-11-13T14:35:25.010808Z","shell.execute_reply.started":"2023-11-13T14:29:34.688408Z","shell.execute_reply":"2023-11-13T14:35:25.009639Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Start Server **using ngrok**\nThis cell will start the server, the first time that you run it will download the models, so it can take a while (~1-2 minutes)\n\n---\nYou'll need a ngrok account, but **it's free** and easy to create!\n---\n**1** - Create a **free** account at [ngrok](https://dashboard.ngrok.com/signup)\\\n**2** - If you didn't logged in with Google or Github, you will need to **verify your e-mail**!\\\n**3** - Click [this link](https://dashboard.ngrok.com/get-started/your-authtoken) to get your auth token, and replace **YOUR_TOKEN_HERE** with your token.\\\n**4** - *(optional)* Change to a region near to you","metadata":{}},{"cell_type":"code","source":"Token = 'Token_Here'\nRegion = \"ap\" # Read the instructions below\n\n# You can change the region for a better latency, use only the abbreviation\n# Choose between this options: \n# us -> United States (Ohio)\n# ap -> Asia/Pacific (Singapore)\n# au -> Australia (Sydney)\n# eu -> Europe (Frankfurt)\n# in -> India (Mumbai)\n# jp -> Japan (Tokyo)\n# sa -> South America (Sao Paulo)\n\n# ---------------------------------\n# DO NOT TOUCH ANYTHING DOWN BELOW!\n\n%cd /kaggle/working/Hmod/server\n \nfrom pyngrok import conf, ngrok\nMyConfig = conf.PyngrokConfig()\nMyConfig.auth_token = Token\nMyConfig.region = Region\nconf.get_default().authtoken = Token\nconf.get_default().region = Region\nconf.set_default(MyConfig);\n\nimport subprocess, threading, time, socket, urllib.request\nPORT = 8000\n\nfrom pyngrok import ngrok\nngrokConnection = ngrok.connect(PORT)\npublic_url = ngrokConnection.public_url\n\ndef wait_for_server():\n while True:\n time.sleep(0.5)\n sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)\n result = sock.connect_ex(('127.0.0.1', PORT))\n if result == 0:\n break\n sock.close()\n print(\"--------- SERVER READY! ---------\")\n print(\"Your server is available at:\")\n print(public_url)\n print(\"---------------------------------\")\n\nthreading.Thread(target=wait_for_server, daemon=True).start()\n\n!python3 Hmod.py \\\n -p {PORT} \\\n --https False \\\n --content_vec_500 pretrain/checkpoint_best_legacy_500.pt \\\n --content_vec_500_onnx pretrain/content_vec_500.onnx \\\n --content_vec_500_onnx_on true \\\n --hubert_base pretrain/hubert_base.pt \\\n --hubert_base_jp pretrain/rinna_hubert_base_jp.pt \\\n --hubert_soft pretrain/hubert/hubert-soft-0d54a1f4.pt \\\n --nsf_hifigan pretrain/nsf_hifigan/model \\\n --crepe_onnx_full pretrain/crepe_onnx_full.onnx \\\n --crepe_onnx_tiny pretrain/crepe_onnx_tiny.onnx \\\n --rmvpe pretrain/rmvpe.pt \\\n --model_dir model_dir \\\n --samples samples.json\n\nngrok.disconnect(ngrokConnection.public_url)","metadata":{"id":"lLWQuUd7WW9U","cellView":"form","_kg_hide-input":false,"scrolled":true,"execution":{"iopub.status.busy":"2023-11-13T14:36:20.529333Z","iopub.execute_input":"2023-11-13T14:36:20.530081Z"},"trusted":true},"execution_count":null,"outputs":[]}]}
\ No newline at end of file
From 818f2470e3fe37c38fde1bdb9b44378bb6f75042 Mon Sep 17 00:00:00 2001
From: tg-develop
Date: Sat, 18 Nov 2023 11:49:31 +0100
Subject: [PATCH 20/28] Added guide for AMD Linux Setup
---
README_en.md | 2 +
tutorials/images/amd_gpu_select.png | Bin 0 -> 63477 bytes
tutorials/images/wine_device.png | Bin 0 -> 95943 bytes
tutorials/tutorial_anaconda_amd_rocm.md | 108 ++++++++++++++++++++++++
4 files changed, 110 insertions(+)
create mode 100644 tutorials/images/amd_gpu_select.png
create mode 100644 tutorials/images/wine_device.png
create mode 100644 tutorials/tutorial_anaconda_amd_rocm.md
diff --git a/README_en.md b/README_en.md
index 5f5799ee..4ac5706f 100644
--- a/README_en.md
+++ b/README_en.md
@@ -113,6 +113,8 @@ To run docker, see [start docker](docker_vcclient/README_en.md).
To run on Anaconda venv, see [server developer's guide](README_dev_en.md)
+To run on Linux using an AMD GPU, see [setup guide linux](tutorials/tutorial_anaconda_amd_rocm.md)
+
# Real-time performance
Conversion is almost instantaneous when using GPU.
diff --git a/tutorials/images/amd_gpu_select.png b/tutorials/images/amd_gpu_select.png
new file mode 100644
index 0000000000000000000000000000000000000000..98d109ec2707ea3a562d6cfe9dbf28b5bc5c5c77
GIT binary patch
literal 63477
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