\n",
+ "\n",
+ "if \"Files\" not in locals():\n",
+ "\traise SystemExit(\"Requirements were not installed!\\nPlease run the first cell.\")\n",
+ "\n",
+ "if not Files:\n",
+ "\traise SystemExit(\"No files has been found!\")\n",
+ "\n",
+ "#-=-=-=-#\n",
+ "\n",
+ "Value = \"44 100 Hz\" #@param [\"29 400 Hz\", \"32 000 Hz\", \"33 075 Hz\", \"44 100 Hz\"]\n",
+ "Samplerate = Value.lower().split(\"hz\")[0]\n",
+ "Samplerate = \"\".join((Character for Character in Samplerate if Character.isdigit()))\n",
+ "\n",
+ "#-=-=-=-#\n",
+ "\n",
+ "for Input in Files:\n",
+ "\tInput_Object = mFile(Input)\n",
+ "\tInput_Name = os.path.basename(Input)\n",
+ "\tInput_MIME = Input_Object.mime[0].lower().split(\"/\")\n",
+ "\n",
+ "\tif Input_Object.info.sample_rate > int(Samplerate):\n",
+ "\t\tif Input_MIME[1] == \"wav\":\n",
+ "\t\t\tos.environ[\"FILE_INPUT\"] = Input\n",
+ "\t\t\tos.environ[\"FILE_OUTPUT\"] = \"_\".join(os.path.splitext(Input))\n",
+ "\t\t\tos.environ[\"SAMPLERATE\"] = Samplerate\n",
+ "\n",
+ "\t\t\trprint('[b #00CC00]Changing sample rate of \"{0}\" from {1} to {2}...[/]'.format(\n",
+ "\t\t\t\tInput_Name, Input_Object.info.sample_rate, Samplerate\n",
+ "\t\t\t))\n",
+ "\t\t\t!ffmpeg -i \"$FILE_INPUT\" -hide_banner -loglevel 16 \\\n",
+ "\t\t\t\t-af asetrate=$SAMPLERATE -map_metadata 0 -map_metadata 0:s:0 \\\n",
+ "\t\t\t\t-fflags +bitexact -flags:v +bitexact -flags:a +bitexact \\\n",
+ "\t\t\t\t\"$FILE_OUTPUT\"\n",
+ "\n",
+ "\t\t\tos.remove(Input)\n",
+ "\t\t\tos.rename(os.environ[\"FILE_OUTPUT\"], Input)\n",
+ "\t\telse:\n",
+ "\t\t\trprint(f'[b #FF0000]\"{Input_Name}\" is not a WAV file, sample rate was not changed.[/]')"
+ ],
+ "metadata": {
+ "cellView": "form",
+ "id": "hh91uhqmPRA4"
+ }
+ },
+ {
+ "cell_type": "markdown",
+ "source": [
+ "#
**3.** Separate โ
"
+ ],
+ "metadata": {
+ "id": "NyA8NMGtDoJn"
+ }
+ },
+ {
+ "cell_type": "code",
+ "source": [
+ "#@title
Configure ๐
\n",
+ "#@markdown > *Premade presets.
If not `None`, settings below will be overwritten by the preset values. *\n",
+ "Preset = \"None\" #@param [\"None\", \"jarredou Notebook (01st January 2024) [jarredou] [Original]\"]\n",
+ "\n",
+ "#@markdown ---\n",
+ "\n",
+ "BigShifts = 7 # @param {type: \"slider\", min: 3, max: 11, step: 1}\n",
+ "Demucs_Overlap = 0.6 #@param {type: \"slider\", min: 0, max: 0.95, step: 0.05}\n",
+ "Bit_Depth = \"32-bit\" #@param [\"16-bit\", \"32-bit\"]\n",
+ "Bit_Depth = Bit_Depth.split(\"-\")[0]\n",
+ "\n",
+ "#@markdown ---\n",
+ "\n",
+ "#@markdown ## `InstVoc` Settings\n",
+ "\n",
+ "InstVoc_Overlap = 1 #@param {type: \"slider\", min: 1, max: 40, step: 1}\n",
+ "InstVoc_Weight = 8 #@param {type: \"slider\", min: 0, max: 10, step: 1}\n",
+ "\n",
+ "#@markdown ---\n",
+ "\n",
+ "#@markdown ## `VitLarge` Settings\n",
+ "\n",
+ "VitLarge_Overlap = 1 #@param {type: \"slider\", min: 1, max: 40, step:1}\n",
+ "VitLarge_Weight = 5 #@param {type: \"slider\", min: 0, max: 10, step: 1}\n",
+ "\n",
+ "#@markdown ---\n",
+ "\n",
+ "#@markdown ## `VocFT` Settings\n",
+ "\n",
+ "VocFT_Enabled = True #@param {type: \"boolean\"}\n",
+ "VocFT_Overlap = 0.1 #@param {type: \"slider\", min: 0, max: 0.99, step: 0.01}\n",
+ "VocFT_Weight = 2 #@param {type: \"slider\", min: 0, max: 10, step: 1}\n",
+ "\n",
+ "#-=-=-=-#\n",
+ "\n",
+ "if \"os\" not in locals():\n",
+ "\traise SystemExit(\"Requirements were not installed!\\nPlease run the first cell.\")\\\n",
+ "\n",
+ "#-=-=-=-#\n",
+ "# Configure preset\n",
+ "\n",
+ "Preset_Display = Preset\n",
+ "Preset = Preset.lower()\n",
+ "\n",
+ "p = {\n",
+ "\t\"BigShifts\": BigShifts,\n",
+ "\t\"Demucs Overlap\": Demucs_Overlap,\n",
+ "\t\"Bit Depth\": Bit_Depth,\n",
+ "\t\"InstVoc Overlap\": InstVoc_Overlap,\n",
+ "\t\"InstVoc Weight\": InstVoc_Weight,\n",
+ "\t\"VitLarge Overlap\": VitLarge_Overlap,\n",
+ "\t\"VitLarge Weight\": VitLarge_Weight,\n",
+ "\t\"VocFT Enabled\": VocFT_Enabled,\n",
+ "\t\"VocFT Overlap\": VocFT_Overlap,\n",
+ "\t\"VocFT Weight\": VocFT_Weight\n",
+ "}\n",
+ "\n",
+ "if Preset.endswith(\"[original]\"):\n",
+ "\tp[\"BigShifts\"] = 7\n",
+ "\tp[\"Demucs Overlap\"] = 0.6\n",
+ "\tp[\"Bit Depth\"] = 16\n",
+ "\tp[\"InstVoc Overlap\"] = 1\n",
+ "\tp[\"InstVoc Weight\"] = 8\n",
+ "\tp[\"VitLarge Overlap\"] = 1\n",
+ "\tp[\"VitLarge Weight\"] = 5\n",
+ "\tp[\"VocFT Enabled\"] = False\n",
+ "\tp[\"VocFT Overlap\"] = 0.1\n",
+ "\tp[\"VocFT Weight\"] = 2\n",
+ "\n",
+ "p[\"Bit Depth\"] = \"PCM_16\" if p[\"Bit Depth\"] == 16 else \"FLOAT\"\n",
+ "p[\"VocFT Enabled\"] = str(p[\"VocFT Enabled\"]).lower()\n",
+ "\n",
+ "#-=-=-=-#\n",
+ "# Output\n",
+ "\n",
+ "Longest_Key_Length = len(sorted(p, key = len)[-1])\n",
+ "\n",
+ "if Preset != \"none\":\n",
+ "\trprint(\"Preset:\", f\"[b i #44AAFF]{Preset_Display}[/]\\n\")\n",
+ "\n",
+ "#-=-=-=-#\n",
+ "\n",
+ "print(\"Settings:\")\n",
+ "for Key, Value in p.items():\n",
+ "\tif Value is False:\n",
+ "\t\tValue = \"\"\n",
+ "\n",
+ "\tValue = str(Value)\n",
+ "\tos.environ[\"_\".join(Key.upper().strip().split())] = Value\n",
+ "\n",
+ "\trprint(\" [i #FFCC00]{0}[/][b #00CC00]{1}[/]\".format(\n",
+ "\t\tKey.ljust(Longest_Key_Length + 5, \" \"), Value\n",
+ "\t))"
+ ],
+ "metadata": {
+ "id": "RtyMpqReO5YM",
+ "cellView": "form"
+ }
+ },
+ {
+ "cell_type": "code",
+ "source": [
+ "#@title #
**Run**
\n",
+ "#@markdown > ## โ ๏ธ
**Previously processed files will be removed without warning!** \n",
+ "\n",
+ "#@markdown ---\n",
+ "\n",
+ "Sort_Files_by = \"Upload order ๐ข\" #@param [\"Upload order ๐ข\", \"Duration ๐\", \"Size โ๏ธ\"]\n",
+ "Sort_Files_by = Sort_Files_by.lower()\n",
+ "Descending = False #@param {type: \"boolean\"}\n",
+ "\n",
+ "#-=-=-=-#\n",
+ "\n",
+ "os.environ[\"DIRECTORY_PRIMARY\"] = Directory_Primary\n",
+ "\n",
+ "#-=-=-=-#\n",
+ "# Files removal\n",
+ "\n",
+ "Files_Outputs = []\n",
+ "\n",
+ "for File in Path(Directory_Outputs).rglob(\"*\"):\n",
+ "\tFile = str(File.resolve())\n",
+ "\tif is_colab:\n",
+ "\t\tif \".ipynb_checkpoints\" not in os.path.basename(File):\n",
+ "\t\t\tFiles_Outputs.append(File)\n",
+ "\telse:\n",
+ "\t\tFiles_Outputs.append(File)\n",
+ "\n",
+ "for File in Files_Outputs:\n",
+ "\tif os.path.isfile(File):\n",
+ "\t\tos.remove(File)\n",
+ "\n",
+ "for File in Files_Outputs:\n",
+ "\tif os.path.isdir(File):\n",
+ "\t\trmtree(File)\n",
+ "\n",
+ "#-=-=-=-#\n",
+ "# Sorting files\n",
+ "\n",
+ "Files_Sorted = Files\n",
+ "if \"duration\" in Sort_Files_by:\n",
+ "\tFiles_Sorted = {File: mFile(File).info.length for File in Files}\n",
+ "\tFiles_Sorted = sorted(Files_Sorted.items(), key = lambda x: x[1])\n",
+ "\tFiles_Sorted = list(dict(Files_Sorted))\n",
+ "if \"size\" in Sort_Files_by:\n",
+ "\tFiles_Sorted = sorted(Files, key = os.path.getsize)\n",
+ "\n",
+ "if Descending:\n",
+ "\tFiles_Sorted = Files_Sorted[::-1]\n",
+ "\n",
+ "#-=-=-=-#\n",
+ "\n",
+ "Runtime = time()\n",
+ "Counter = 1\n",
+ "\n",
+ "torch.cuda.empty_cache()\n",
+ "\n",
+ "for Input in Files_Sorted:\n",
+ "\tInput_Object = mFile(Input)\n",
+ "\tInput_Split = os.path.split(os.path.abspath(Input))\n",
+ "\n",
+ "\trprint(\"[b][#44AAFF]{0}.[/] [i]{1} [#A0A0A0]({2}s) ({3})[/][/][/]\".format(\n",
+ "\t\tstr(Counter).rjust(len(str(len(Files))) + 1, \"0\"),\n",
+ "\t\tos.path.basename(Input).ljust(Longest_File_Name_Length, \" \"),\n",
+ "\t\tround(Input_Object.info.length, 3),\n",
+ "\t\tfdb_size(Input)\n",
+ "\t))\n",
+ "\n",
+ "\tos.environ[\"FILE_INPUT\"] = Input\n",
+ "\tos.environ[\"DIRECTORY_OUTPUTS\"] = os.path.join(Directory_Outputs, os.path.basename(Input))\n",
+ "\n",
+ "\t!python $DIRECTORY_PRIMARY/inference.py -q \\\n",
+ "\t\t--input_audio \"$FILE_INPUT\" \\\n",
+ "\t\t--output_folder \"$DIRECTORY_OUTPUTS\" \\\n",
+ "\t\t--weight_InstVoc $INSTVOC_WEIGHT \\\n",
+ "\t\t--weight_VOCFT $VOCFT_WEIGHT \\\n",
+ "\t\t--weight_VitLarge $VITLARGE_WEIGHT \\\n",
+ "\t\t--overlap_VOCFT $VOCFT_OVERLAP \\\n",
+ "\t\t--overlap_InstVoc $INSTVOC_OVERLAP \\\n",
+ "\t\t--overlap_VitLarge $VITLARGE_OVERLAP \\\n",
+ "\t\t--overlap_demucs $DEMUCS_OVERLAP \\\n",
+ "\t\t--BigShifts $BIGSHIFTS \\\n",
+ "\t\t--output_format $BIT_DEPTH \\\n",
+ "\t\t--large_gpu --use_VOCFT $VOCFT_ENABLED | grep -v \"created\"\n",
+ "\n",
+ "\t# Cleanup\n",
+ "\tfor File in Path(os.environ[\"DIRECTORY_OUTPUTS\"]).rglob(\"*\"):\n",
+ "\t\tFile = str(File.resolve())\n",
+ "\n",
+ "\t\tos.rename(\n",
+ "\t\t\tFile,\n",
+ "\t\t\tos.path.join(\n",
+ "\t\t\t\tos.path.split(File)[0],\n",
+ "\t\t\t\tos.path.split(File)[1].split(\"_\")[-1]\n",
+ "\t\t\t)\n",
+ "\t\t)\n",
+ "\n",
+ "\ttorch.cuda.empty_cache()\n",
+ "\tCounter += 1\n",
+ "\n",
+ "\tif all((len(Files) > 1, Input != Files_Sorted[-1])):\n",
+ "\t\tprint()\n",
+ "\n",
+ "#-=-=-=-#\n",
+ "\n",
+ "torch.cuda.empty_cache()\n",
+ "\n",
+ "__Run_Time = time() - Runtime\n",
+ "print(\"\\n\" + \"โ\" * 32 + \"\\n\")\n",
+ "rprint(\"[b #00CC00]Done![/]\")\n",
+ "rprint(\"Runtime: [b #44AAFF]{0}[/] [i #A0A0A0](avg. {1} per file)[/]\".format(\n",
+ "\tstr(timedelta(seconds = __Run_Time))[2:-3],\n",
+ "\tstr(timedelta(seconds = __Run_Time / len(Files)))[2:-3]\n",
+ "))"
+ ],
+ "metadata": {
+ "id": "pGJWlVU-C_SY",
+ "cellView": "form"
+ }
+ },
+ {
+ "cell_type": "markdown",
+ "source": [
+ "#
Utils โ๏ธ
"
+ ],
+ "metadata": {
+ "id": "XfDlrVA9Qc1x"
+ }
+ },
+ {
+ "cell_type": "code",
+ "source": [
+ "#@title
Change processed audio files sample rate โ๏ธ
\n",
+ "\n",
+ "Value = \"48 000 Hz\" #@param [\"29 400 Hz\", \"32 000 Hz\", \"33 075 Hz\", \"44 100 Hz\", \"48 000 Hz\", \"96 000 Hz\", \"192 000 Hz\"]\n",
+ "Samplerate = Value.lower().split(\"hz\")[0]\n",
+ "Samplerate = \"\".join((Character for Character in Samplerate if Character.isdigit()))\n",
+ "\n",
+ "#-=-=-=-#\n",
+ "\n",
+ "Files_Final = []\n",
+ "\n",
+ "for Input in Path(Directory_Outputs).rglob(\"*\"):\n",
+ "\tInput = str(Input.resolve())\n",
+ "\n",
+ "\tif os.path.isfile(Input):\n",
+ "\t\tInput_Name = os.path.relpath(Input, Directory_Outputs)\n",
+ "\n",
+ "\t\tos.environ[\"FILE_INPUT\"] = Input\n",
+ "\t\tos.environ[\"FILE_OUTPUT\"] = \"_\".join(os.path.splitext(Input))\n",
+ "\t\tos.environ[\"SAMPLERATE\"] = Samplerate\n",
+ "\n",
+ "\t\tif mFile(Input).info.sample_rate != int(Samplerate):\n",
+ "\t\t\trprint('[b #00CC00]Changing sample rate of \"{0}\" from {1} to {2}...[/]'.format(\n",
+ "\t\t\t\tInput_Name, Input_Object.info.sample_rate, Samplerate\n",
+ "\t\t\t))\n",
+ "\t\t\t!ffmpeg -y -i \"$FILE_INPUT\" -hide_banner -loglevel 16 \\\n",
+ "\t\t\t\t-af asetrate=$SAMPLERATE -map_metadata 0 -map_metadata 0:s:0 \\\n",
+ "\t\t\t\t-fflags +bitexact -flags:v +bitexact -flags:a +bitexact \\\n",
+ "\t\t\t\t\"$FILE_OUTPUT\"\n",
+ "\n",
+ "\t\t\tos.remove(Input)\n",
+ "\t\t\tos.rename(os.environ[\"FILE_OUTPUT\"], Input)"
+ ],
+ "metadata": {
+ "cellView": "form",
+ "id": "y1CyjzaHAdbf"
+ }
+ },
+ {
+ "cell_type": "code",
+ "source": [
+ "#@title
Convert output files to `FLAC` ๐ถ
\n",
+ "\n",
+ "Bit_Depth = \"24-bit\" #@param [\"16-bit\", \"24-bit\"]\n",
+ "Bit_Depth = Bit_Depth.split(\"-\")[0]\n",
+ "Normalize_dB = 1 # @param {type: \"slider\", min: -6, max: 1, step: 1}\n",
+ "#@markdown > โน๏ธ To
**disable** normalization, set `Normalize_dB` to **`1`**.\n",
+ "\n",
+ "#-=-=-=-#\n",
+ "\n",
+ "Target = \"FLAC\"\n",
+ "Target = Target.split()[0].lower().strip(\".\")\n",
+ "\n",
+ "#-=-=-=-#\n",
+ "\n",
+ "os.environ[\"BIT_DEPTH\"] = \"-b \" + Bit_Depth\n",
+ "os.environ[\"NORMALIZE\"] = (\"--norm \" + str(Normalize_dB)) if Normalize_dB < 1 else \"\"\n",
+ "\n",
+ "for File in Path(Directory_Outputs).rglob(\"*.*\"):\n",
+ "\tInput = str(File.resolve())\n",
+ "\n",
+ "\tif os.path.isfile(Input):\n",
+ "\t\tInput_MIME = mFile(Input).mime[0].lower().split(\"/\")\n",
+ "\t\tInput_Name = os.path.relpath(Input, Directory_Outputs)\n",
+ "\n",
+ "\t\tOutput_FLAC = os.path.splitext(Input)[0], f\".{Target.lower()}\"\n",
+ "\t\tOutput = \"_\".join(Output_FLAC)\n",
+ "\n",
+ "\t\tos.environ[\"INPUT\"] = Input\n",
+ "\t\tos.environ[\"OUTPUT\"] = Output\n",
+ "\n",
+ "\t\trprint('[b i]{1}onverting [#44AAFF]\"{0}\"[/] to FLAC...[/]'.format(\n",
+ "\t\t\tInput_Name,\n",
+ "\t\t\t(\"rec\" if Input_MIME[1] == \"flac\" else \"c\").capitalize()\n",
+ "\t\t))\n",
+ "\n",
+ "\t\t!sox \"$INPUT\" -D $BIT_DEPTH -C 8 $NORMALIZE --comment \"\" -G \"$OUTPUT\" -V0\n",
+ "\n",
+ "\t\tos.remove(Input)\n",
+ "\t\tos.rename(Output, \"\".join(Output_FLAC))"
+ ],
+ "metadata": {
+ "cellView": "form",
+ "id": "nxkupjCJpf5R"
+ }
+ },
+ {
+ "cell_type": "code",
+ "source": [
+ "#@title
Download archive with output files ๐๏ธ
\n",
+ "Emphasize_archive_file_name = True #@param {type: \"boolean\"}\n",
+ "Beggining = \"!_\" if Emphasize_archive_file_name else \"\"\n",
+ "\n",
+ "#@markdown > โน๏ธ Pushes the archive file to top of the explorer's file list (**if** it's sorted by name) by putting `!_` to its file name beggining.\n",
+ "\n",
+ "#-=-=-=-#\n",
+ "\n",
+ "__Padding = 7\n",
+ "Archive_File = Beggining + \"_\".join((__title__, str(time()).split(\".\")[1][:__Padding].rjust(__Padding, \"0\")))\n",
+ "Archive_File += \".zip\"\n",
+ "Archive_File = os.path.abspath(Archive_File)\n",
+ "\n",
+ "#-=-=-=-#\n",
+ "\n",
+ "# Archive Creation\n",
+ "print(\"Making Archive...\")\n",
+ "with ZipFile(Archive_File, \"w\", 14, 1, 9) as Archive:\n",
+ "\tfor File in Path(Directory_Outputs).rglob(\"*.*\"):\n",
+ "\t\tFile = str(File.resolve())\n",
+ "\n",
+ "\t\tif os.path.isfile(File):\n",
+ "\t\t\tArcName = os.path.relpath(File, Directory_Outputs)\n",
+ "\n",
+ "\t\t\trprint(f'\\t[b i]Writing [#44AACC]\"{ArcName}\"[/]...')\n",
+ "\t\t\tArchive.write(File, ArcName)\n",
+ "\n",
+ "#-=-=-=-#\n",
+ "\n",
+ "files.download(Archive_File)"
+ ],
+ "metadata": {
+ "cellView": "form",
+ "id": "rpPfi2g7gnTi"
+ }
+ },
+ {
+ "cell_type": "code",
+ "source": [
+ "#@title
Terminate runtime after specified time ๐\n",
+ "#@markdown In case if you don't want to waste this account's resources while performing other tasks.\n",
+ "#@markdown > ###
**This cancellable action is irreversible and will result in loss of ALL session data!** \n",
+ "\n",
+ "#@markdown
\n",
+ "#@markdown
\n",
+ "#@markdown Time sheet \n",
+ "#@markdown\n",
+ "#@markdown \n",
+ "#@markdown\n",
+ "#@markdown | Seconds | Minutes |\n",
+ "#@markdown |:-|:-|\n",
+ "#@markdown | `60` | `1` |\n",
+ "#@markdown | `300` | `5` |\n",
+ "#@markdown | `600` | `10` |\n",
+ "#@markdown | `1800` | `30` |\n",
+ "#@markdown | `3600` | `60` |\n",
+ "#@markdown \n",
+ "\n",
+ "#@markdown ---\n",
+ "\n",
+ "Seconds_Default = 30\n",
+ "Seconds = 300 # @param {type: \"integer\"}\n",
+ "\n",
+ "if Seconds < 0:\n",
+ "\trprint(f\"[b][#FFCC00]Seconds are[/] [#FF0000]< 0[/][#FFCC00], defaulting to[/] [#FF0000]{Seconds_Default}[/][#FFCC00].[/][/]\")\n",
+ "\n",
+ "__Spaces = \" \" * 8\n",
+ "\n",
+ "\n",
+ "\n",
+ "if is_colab:\n",
+ "\ttry:\n",
+ "\t\tfor i in range(Seconds, -1, -1):\n",
+ "\t\t\tprint(\"\\r\", end = f\"Runtime will be terminated in {i} seconds...\" + __Spaces)\n",
+ "\n",
+ "\t\trprint(\"\\n\\n[b #FF0000]Runtime has been terminated.[/]\")\n",
+ "\t\truntime.unassign()\n",
+ "\texcept (KeyboardInterrupt, EOFError):\n",
+ "\t\tprint()\n",
+ "\t\trprint(\"[b #FF0000]Operation cancelled by user.[/]\")\n",
+ "else:\n",
+ "\trprint(\"[b #FFCC00]Not in Colab, unsupported.[/]\")"
+ ],
+ "metadata": {
+ "id": "rhKs_AmESZew",
+ "cellView": "form"
+ }
+ }
+ ]
+}
\ No newline at end of file
diff --git a/Notebooks/AI/Audio/Upscale/HiFi_GAN_BWE.ipynb b/Notebooks/AI/Audio/Upscale/HiFi_GAN_BWE.ipynb
new file mode 100644
index 0000000..8ed15e7
--- /dev/null
+++ b/Notebooks/AI/Audio/Upscale/HiFi_GAN_BWE.ipynb
@@ -0,0 +1,929 @@
+{
+ "nbformat": 4,
+ "nbformat_minor": 0,
+ "metadata": {
+ "colab": {
+ "name": "HiFi GAN BWE",
+ "provenance": [],
+ "collapsed_sections": [
+ "pPR2kVUB1r_1",
+ "wWMN_sT-ugof",
+ "XfDlrVA9Qc1x"
+ ]
+ },
+ "kernelspec": {
+ "name": "python3",
+ "display_name": "Python 3"
+ },
+ "language_info": {
+ "name": "python"
+ }
+ },
+ "cells": [
+ {
+ "cell_type": "markdown",
+ "source": [
+ "#
**HiFi GAN BWE ๐โ๏ธ๐ถ** \n",
+ "\n",
+ "> โ๏ธ
[...] unoffical implementation of the **HiFi-GAN+ model for audio bandwidth extension**, from the paper [โ**B** and**w** idth **E** xtension is All You Needโ](https://doi.org/10.1109/ICASSP39728.2021.9413575) by Jiaqi Su, Yunyun Wang, Adam Finkelstein, and Zeyu Jin. \n",
+ "\n",
+ "> ๐
The model **takes a band-limited audio signal** (usually `8`/`16`/`24`kHz) and **attempts to reconstruct the high frequency components needed to restore a full-band signal at** 48kHz 1 . \n",
+ "\n",
+ "> ๐ถ
This is useful for **upsampling low-rate outputs from upstream tasks like text-to-speech, voice conversion**, etc. or enhancing audio that was filtered to remove high frequency noise. \n",
+ "\n",
+ "
\n",
+ "\n",
+ "### Features:\n",
+ "- URL support ๐\n",
+ "- **Multiple output target samplerates**
1 ๐\n",
+ "\n",
+ "
\n",
+ "\n",
+ "
"
+ ],
+ "metadata": {
+ "id": "6d9RBy68rV7-"
+ }
+ },
+ {
+ "cell_type": "markdown",
+ "source": [
+ "#
**1.** Re/install requirements ๐ฅ
"
+ ],
+ "metadata": {
+ "id": "pPR2kVUB1r_1"
+ }
+ },
+ {
+ "cell_type": "code",
+ "source": [
+ "#@markdown > โน๏ธ Runtime does not need to be restarted.\n",
+ "import os\n",
+ "import time\n",
+ "import torch\n",
+ "import locale\n",
+ "import warnings\n",
+ "import numpy as np\n",
+ "from time import time\n",
+ "from pathlib import Path\n",
+ "from shutil import rmtree\n",
+ "from zipfile import ZipFile\n",
+ "from datetime import timedelta\n",
+ "from rich import print as rprint\n",
+ "from mimetypes import guess_type\n",
+ "from scipy.io.wavfile import write\n",
+ "from requests import Session, utils\n",
+ "\n",
+ "try:\n",
+ "\tfrom google.colab import files, runtime\n",
+ "\tis_colab = True\n",
+ "except ImportError:\n",
+ "\tis_colab = False\n",
+ "\n",
+ "GPU = torch.cuda.device_count()\n",
+ "warnings.filterwarnings(\"ignore\")\n",
+ "locale.getpreferredencoding = lambda: \"UTF-8\"\n",
+ "\n",
+ "#-=-=-=-#\n",
+ "# Metadata\n",
+ "\n",
+ "__title__ = \"HiFi GAN BWE\"\n",
+ "__author__ = \"kubinka0505\"\n",
+ "__date__ = \"04th December 2023\"\n",
+ "__title__ = __title__.replace(\" \", \"_\")\n",
+ "\n",
+ "#-=-=-=-#\n",
+ "# Modules & packages\n",
+ "\n",
+ "requirements = {\n",
+ "\t\"modules\": [\"mutagen\", \"hifi_gan_bwe\"],\n",
+ "\t\"packages\": [\"sox\"]\n",
+ "}\n",
+ "\n",
+ "if GPU:\n",
+ "\tGPU_Name = torch.cuda.get_device_name(torch.cuda.current_device())\n",
+ "\trprint(\"[b #00CC00]GPU Available![/] [#A0A0A0]({0})[/]\".format(GPU_Name))\n",
+ "else:\n",
+ "\trprint(\"[#FFCC00][b]GPU Unavailable!\\n[/]Processing may be slower.[/]\")\n",
+ "\n",
+ "print(\"\\n\" + \"โ\" * 32 + \"\\n\")\n",
+ "\n",
+ "try:\n",
+ "\t__modules = requirements[\"modules\"]\n",
+ "\t__packages = requirements[\"packages\"]\n",
+ "\n",
+ "\tif __modules:\n",
+ "\t\tfor Name in __modules:\n",
+ "\t\t\t!pip uninstall {Name} -y -q | grep -v \"WARNING: Skip\"\n",
+ "\t\t\t!pip install -U {Name} --progress-bar off | grep -v \"already\"\n",
+ "\t\t\tif all((len(__modules) > 1, Name != __modules[-1])):\n",
+ "\t\t\t\tprint()\n",
+ "\n",
+ "\tif __packages:\n",
+ "\t\tfor Name in __packages:\n",
+ "\t\t\t!apt-get install --reinstall {Name} -qq > /dev/null 2 >&1\n",
+ "\t\t\tif all((len(__packages) > 1, Name != __packages[-1])):\n",
+ "\t\t\t\tprint()\n",
+ "\n",
+ "\timport audioread\n",
+ "\tfrom mutagen import File as mFile\n",
+ "\tfrom hifi_gan_bwe import BandwidthExtender\n",
+ "\n",
+ "\t#-=-=-=-#\n",
+ "\t# Requests\n",
+ "\n",
+ "\tsession = Session()\n",
+ "\tsession.headers.update(\n",
+ "\t\t{\n",
+ "\t\t\t\"User-Agent\":\n",
+ "\t\t\t\"Mozilla/5.0 (Windows NT 10.0; Win32; x32) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36\"\n",
+ "\t\t}\n",
+ "\t)\n",
+ "\n",
+ "\t#-=-=-=-#\n",
+ "\t# Models\n",
+ "\n",
+ "\tprint(\"\\n\" + \"โ\" * 32 + \"\\n\")\n",
+ "\tModels = {\n",
+ "\t\t\"hifi-gan-bwe-10-42890e3-vctk-48kHz\": \"\"\"\n",
+ "\t\t\tSame as [i]bwe-05[/], but [b]uses bandlimited interpolation for upsampling, [u]for reduced noise and aliasing[/][/].\n",
+ "\t\t\t[u]Uses the same parameters as resampy's \"kaiser_best\" mode[/]\n",
+ "\t\t\t\"\"\",\n",
+ "\t\t\"hifi-gan-bwe-11-d5f542d-vctk-8kHz-48kHz\": \"Same as [i]bwe-10[/], but [b]trained only on [i]8 000 Hz[/i][/] sources, [b u]for specialized upsampling[/]\",\n",
+ "\t\t\"hifi-gan-bwe-12-b086d8b-vctk-16kHz-48kHz\": \"Same as [i]bwe-10[/], but [b]trained only on [i]16 000 Hz[/][/] sources, [b u]for specialized upsampling[/]\",\n",
+ "\t\t\"hifi-gan-bwe-13-59f00ca-vctk-24kHz-48kHz\": \"Same as [i]bwe-10[/], but [b]trained only on [i]24 000 Hz[/][/] sources, [b u]for specialized upsampling[/]\",\n",
+ "\t\t\"hifi-gan-bwe-05-cd9f4ca-vctk-48kHz\": \"Trained for 200K iterations on the VCTK [b u]speech dataset with noise agumentation[/] from the DNS Challenge dataset\"\n",
+ "\t}\n",
+ "\n",
+ "\trmtree(os.path.expanduser(\"~/.local/hifi-gan-bwe\"), True)\n",
+ "\tfor Key, Value in Models.items():\n",
+ "\t\tModels[Key] = Value.replace(\"\\t\", \"\").strip(\"\\n\\t\")\n",
+ "\t\tBandwidthExtender.from_pretrained(Key)\n",
+ "\n",
+ "\t#-=-=-=-#\n",
+ "\t# Functions\n",
+ "\n",
+ "\tdef fdb_size(obj: str, extended_units: bool = False, bits: bool = False, recursive: bool = False) -> str:\n",
+ "\t\t\"\"\"\n",
+ "\t\tArgs:\n",
+ "\t\t\tobj: Bytes integer or string path of existing file or directory.\n",
+ "\t\t\textended_units: Extends the unit of the result, i.e. \"Megabytes\" instead of \"MB\".\n",
+ "\t\t\tbits: Uses decimal divider (1000) instead of binary one. (1024)\n",
+ "\t\t\trecursive: Iterate subdirectories, applicable only if `obj` is directory. (slow!)\n",
+ "\n",
+ "\t\tReturns:\n",
+ "\t\t\tHuman-readable files size string.\n",
+ "\t\t\"\"\"\n",
+ "\t\t# Setup\n",
+ "\n",
+ "\t\tif bits:\n",
+ "\t\t\tBits = 1000\n",
+ "\t\t\tBits_Display_Single = \"bit\"\n",
+ "\t\t\tBits_Display_Multiple = \"bits\"\n",
+ "\t\telse:\n",
+ "\t\t\tBits = 1024\n",
+ "\t\t\tBits_Display_Single = \"byte\"\n",
+ "\t\t\tBits_Display_Multiple = \"bytes\"\n",
+ "\n",
+ "\t\tUnits = {\n",
+ "\t\t\t\"\":\t \"\",\n",
+ "\t\t\t\"K\": \"kilo\",\n",
+ "\t\t\t\"M\": \"mega\",\n",
+ "\t\t\t\"G\": \"giga\",\n",
+ "\t\t\t\"T\": \"tera\",\n",
+ "\t\t\t\"P\": \"peta\",\n",
+ "\t\t\t\"E\": \"exa\",\n",
+ "\t\t\t\"Z\": \"zetta\",\n",
+ "\t\t\t\"Y\": \"yotta\",\n",
+ "\t\t\t\"R\": \"ronna\",\n",
+ "\t\t\t\"Q\": \"quetta\"\n",
+ "\t\t}\n",
+ "\n",
+ "\t\t#-=-=-=-#\n",
+ "\t\t# Search for files\n",
+ "\n",
+ "\t\tif isinstance(obj, str):\n",
+ "\t\t\tpath = str(Path(obj).resolve())\n",
+ "\n",
+ "\t\t\tif not os.path.exists(path):\n",
+ "\t\t\t\traise FileNotFoundError(path)\n",
+ "\n",
+ "\t\t\tif os.path.isfile(obj):\n",
+ "\t\t\t\tFiles = [obj]\n",
+ "\t\t\telse:\n",
+ "\t\t\t\tWildcard = \"*\"\n",
+ "\t\t\t\tif recursive:\n",
+ "\t\t\t\t\tWildcard += \"*/*\"\n",
+ "\t\t\t\tFiles = list(Path(obj).glob(Wildcard))\n",
+ "\t\t\t\tfor File in Files:\n",
+ "\t\t\t\t\tFiles[Files.index(File)] = str(File.resolve())\n",
+ "\n",
+ "\t\t\tFiles = map(os.path.getsize, Files)\n",
+ "\t\t\tBytes = sum(Files)\n",
+ "\t\telse:\n",
+ "\t\t\tBytes = obj\n",
+ "\n",
+ "\t\t#-=-=-=-#\n",
+ "\t\t# Calculate integer\n",
+ "\n",
+ "\t\tfor Unit in Units:\n",
+ "\t\t\tif Bytes < Bits:\n",
+ "\t\t\t\tbreak\n",
+ "\t\t\tBytes /= Bits\n",
+ "\n",
+ "\t\t#-=-=-=-#\n",
+ "\t\t# Ending conditions\n",
+ "\n",
+ "\t\tif extended_units:\n",
+ "\t\t\tif Bytes == 1:\n",
+ "\t\t\t\tBits_Display = Bits_Display_Single\n",
+ "\t\t\telse:\n",
+ "\t\t\t\tBits_Display = Bits_Display_Multiple\n",
+ "\t\t\tUnit = (Units[Unit] + Bits_Display).capitalize()\n",
+ "\t\telse:\n",
+ "\t\t\tUnit += \"B\"\n",
+ "\n",
+ "\t\t#-=-=-=-#\n",
+ "\t\t# Add zero to integer\n",
+ "\n",
+ "\t\tif \".\" in str(Bytes):\n",
+ "\t\t\tBytes = round(Bytes, 2)\n",
+ "\t\t\tBytes = str(Bytes).split(\".\")\n",
+ "\t\t\tBytes[1] = Bytes[1][:2]\n",
+ "\t\t\tBytes[1] = Bytes[1].ljust(2, \"0\")\n",
+ "\t\t\tBytes = \".\".join(Bytes)\n",
+ "\n",
+ "\t\tBytes = str(Bytes)\n",
+ "\n",
+ "\t\t#-=-=-=-#\n",
+ "\t\t# Return string\n",
+ "\n",
+ "\t\treturn \" \".join((Bytes, Unit))\n",
+ "\n",
+ "\t#-=-=-=-#\n",
+ "\t# Directories\n",
+ "\n",
+ "\tDirectory_Main = os.path.abspath(__title__)\n",
+ "\tDirectory_Primary = os.path.join(Directory_Main, \"Repository\")\n",
+ "\tDirectory_Inputs = os.path.join(Directory_Main, \"_inputs\")\n",
+ "\tDirectory_Outputs = os.path.join(Directory_Main, \"_outputs\")\n",
+ "\n",
+ "\tif os.path.exists(Directory_Primary):\n",
+ "\t\trmtree(Directory_Primary)\n",
+ "\n",
+ "\tfor Directory in Directory_Inputs, Directory_Outputs:\n",
+ "\t\tos.makedirs(Directory, exist_ok = True)\n",
+ "except (KeyboardInterrupt, EOFError):\n",
+ "\tprint(\"\\n\" + \"โ\" * 32 + \"\\n\" + \"Operation cancelled by user.\")"
+ ],
+ "metadata": {
+ "id": "9ezDwM6lbQ9s",
+ "cellView": "form"
+ }
+ },
+ {
+ "cell_type": "markdown",
+ "source": [
+ "#
**2.** Upload files ๐ค
"
+ ],
+ "metadata": {
+ "id": "cOXSJNbzrDmk"
+ }
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "dNrOJkouZFlx",
+ "cellView": "form"
+ },
+ "source": [
+ "#@markdown > ๐๏ธ
**URL of `ZIP` archive with files is supported.**\n",
+ "\n",
+ "Direct_URL = \"\" #@param {type: \"string\"}\n",
+ "Allow_non_WAV_URL = True #@param {type: \"boolean\"}\n",
+ "__URL_Fail = False if Direct_URL else True\n",
+ "\n",
+ "#@markdown ---\n",
+ "\n",
+ "#@markdown > โน๏ธ `Lazy Unpacking` determines whether **files from the archive should only be unpacked if their file name extension** is in the `Formats` variable.\n",
+ "\n",
+ "Lazy_Unpacking = True #@param {type: \"boolean\"}\n",
+ "Formats = \"AAC, AIFF, ALAC, APE, FLAC, M4A, MP3, OGG, OPUS, WAV, WV\" #@param {type: \"string\"}\n",
+ "Formats = [Format.lower().strip() for Format in Formats.split(\",\")]\n",
+ "\n",
+ "#@markdown ---\n",
+ "\n",
+ "Ask_to_upload_files_if_download_succeeds = True #@param {type: \"boolean\"}\n",
+ "Remove_previously_uploaded_files_and_subdirectories = True #@param {type: \"boolean\"}\n",
+ "\n",
+ "#-=-=-=-#\n",
+ "\n",
+ "if \"rmtree\" not in locals():\n",
+ "\traise SystemExit(\"Requirements were not installed!\\nPlease run the first cell.\")\n",
+ "\n",
+ "if \"Files\" not in locals():\n",
+ "\tFiles = []\n",
+ "\n",
+ "#-=-=-=-#\n",
+ "\n",
+ "__Directory_Base = os.getcwd()\n",
+ "\n",
+ "# `os.chdir` since `files.upload` does not have the target directory argument\n",
+ "os.chdir(Directory_Inputs)\n",
+ "\n",
+ "if Remove_previously_uploaded_files_and_subdirectories:\n",
+ "\tFiles_Inputs = []\n",
+ "\tfor File in Path(Directory_Inputs).rglob(\"*\"):\n",
+ "\t\tFile = str(File.resolve())\n",
+ "\t\tif is_colab:\n",
+ "\t\t\tif \".ipynb_checkpoints\" not in os.path.basename(File):\n",
+ "\t\t\t\tFiles_Inputs.append(File)\n",
+ "\t\telse:\n",
+ "\t\t\tFile_Inputs.append(File)\n",
+ "\n",
+ "\tfor File in Files_Inputs:\n",
+ "\t\tif os.path.isfile(File):\n",
+ "\t\t\tos.remove(File)\n",
+ "\t\t\trprint('Removed [b #44AAFF]\"{0}\"[/]'.format(\n",
+ "\t\t\t\tos.path.relpath(File, Directory_Inputs)\n",
+ "\t\t\t))\n",
+ "\n",
+ "\tfor File in Files_Inputs:\n",
+ "\t\tif os.path.isdir(File):\n",
+ "\t\t\trmtree(File)\n",
+ "\n",
+ "\tif Files_Inputs:\n",
+ "\t\tprint(\"\\n\" + \"โ\" * 32 + \"\\n\")\n",
+ "\n",
+ "\tFiles = []\n",
+ "\n",
+ "#-=-=-=-#\n",
+ "\n",
+ "Allowed_Specifiers = \"http\", \"https\", \"ftp\"\n",
+ "Allowed_Specifiers = [Specifier + \"://\" for Specifier in Allowed_Specifiers]\n",
+ "Allowed_Specifiers = tuple(Allowed_Specifiers)\n",
+ "\n",
+ "if Direct_URL.lower().startswith(Allowed_Specifiers):\n",
+ "\tfor Delimiter in ((\"?\", \"&\", \"#\")):\n",
+ "\t\tDownloaded_File_Location = Direct_URL.split(Delimiter)[0]\n",
+ "\n",
+ "\tDownloaded_File_Location = utils.unquote(Downloaded_File_Location.split(\"/\")[-1])\n",
+ "\n",
+ "\t__URL_Fail = False\n",
+ "\ttry:\n",
+ "\t\tSession_obj = session.get(Direct_URL, stream = 1)\n",
+ "\texcept Exception:\n",
+ "\t\t__URL_Fail = True\n",
+ "\n",
+ "\tif __URL_Fail:\n",
+ "\t\trprint(\"[b #FF0000]Provided URL is invalid![/]\")\n",
+ "\t\t__URL_Fail = True\n",
+ "\n",
+ "\tif not __URL_Fail:\n",
+ "\t\twith Session_obj as Site:\n",
+ "\t\t\tif Site.ok:\n",
+ "\t\t\t\tSite_MIME = Site.headers[\"content-type\"].lower().split()[0].split(\";\")[0].split(\"/\")\n",
+ "\t\t\t\tif Site_MIME[0] == \"audio\":\n",
+ "\t\t\t\t\tif any((Site_MIME[1].endswith(\"wav\"), Allow_non_WAV_URL)):\n",
+ "\t\t\t\t\t\twith open(Downloaded_File_Location, \"wb\") as File:\n",
+ "\t\t\t\t\t\t\trprint(f'Downloading [b #00CC00]\"{Downloaded_File_Location}\"[/]...')\n",
+ "\n",
+ "\t\t\t\t\t\t\tfor Chunk in Site.iter_content(chunk_size = 1024):\n",
+ "\t\t\t\t\t\t\t\tif Chunk:\n",
+ "\t\t\t\t\t\t\t\t\tFile.write(Chunk)\n",
+ "\t\t\t\t\t\t\tFiles.append(Downloaded_File_Location)\n",
+ "\t\t\t\t\telse:\n",
+ "\t\t\t\t\t\trprint(\"[b #FF0000]Permission to download non-WAV files was not granted.[/]\")\n",
+ "\t\t\t\t\t\t__URL_Fail = True\n",
+ "\t\t\t\telse:\n",
+ "\t\t\t\t\t# ZIP Archive Handling\n",
+ "\t\t\t\t\tif \"/\".join(Site_MIME) == \"application/zip\":\n",
+ "\t\t\t\t\t\twith open(Downloaded_File_Location, \"wb\") as File:\n",
+ "\t\t\t\t\t\t\trprint(f'Downloading [b #00CC00]\"{Downloaded_File_Location}\"[/]...')\n",
+ "\n",
+ "\t\t\t\t\t\t\tfor Chunk in Site.iter_content(chunk_size = 1024):\n",
+ "\t\t\t\t\t\t\t\tif Chunk:\n",
+ "\t\t\t\t\t\t\t\t\tFile.write(Chunk)\n",
+ "\n",
+ "\t\t\t\t\t\ttry:\n",
+ "\t\t\t\t\t\t\tArchive_Files_Amount = 0\n",
+ "\t\t\t\t\t\t\twith ZipFile(Downloaded_File_Location) as Archive:\n",
+ "\t\t\t\t\t\t\t\tfor Archive_File in Archive.infolist():\n",
+ "\t\t\t\t\t\t\t\t\tif Lazy_Unpacking:\n",
+ "\t\t\t\t\t\t\t\t\t\tif os.path.splitext(Archive_File.filename.lower())[1][1:] in Formats:\n",
+ "\t\t\t\t\t\t\t\t\t\t\tArchive_Files_Amount += 1\n",
+ "\t\t\t\t\t\t\t\t\t\t\tArchive.extract(Archive_File)\n",
+ "\t\t\t\t\t\t\t\t\telse:\n",
+ "\t\t\t\t\t\t\t\t\t\tArchive_Files_Amount += 1\n",
+ "\t\t\t\t\t\t\t\t\t\tArchive.extract(Archive_File)\n",
+ "\n",
+ "\t\t\t\t\t\t\tos.remove(Downloaded_File_Location)\n",
+ "\n",
+ "\t\t\t\t\t\t\t#-=-=-=-#\n",
+ "\n",
+ "\t\t\t\t\t\t\tfor File in Path().rglob(\"*.*\"):\n",
+ "\t\t\t\t\t\t\t\tFile = str(File.resolve())\n",
+ "\n",
+ "\t\t\t\t\t\t\t\tif os.path.isfile(File):\n",
+ "\t\t\t\t\t\t\t\t\tFiles.append(File)\n",
+ "\n",
+ "\t\t\t\t\t\t\trprint(f\"[b #00CC00]{Archive_Files_Amount} files from main directory were extracted successfully![/]\")\n",
+ "\t\t\t\t\t\texcept RuntimeError:\n",
+ "\t\t\t\t\t\t\trprint(\"[b #FF0000]Files extraction was not successful due to password requirement, file corruption or other internal error.[/]\")\n",
+ "\t\t\t\t\t\t\t__URL_Fail = True\n",
+ "\t\t\t\t\telse:\n",
+ "\t\t\t\t\t\trprint(\"[b #FF0000]Provided URL is not an audio file.[/] [i #A0A0A0](undetected MIME type in header)[/]\")\n",
+ "\t\t\t\t\t\t__URL_Fail = True\n",
+ "\t\t\telse:\n",
+ "\t\t\t\trprint(\"[b #FF0000]Failed to fetch the URL due to {0} status code. ({1})[/]\".format(\n",
+ "\t\t\t\t\tSite.status_code, Site.reason.title()\n",
+ "\t\t\t\t))\n",
+ "\t\t\t\t__URL_Fail = True\n",
+ "\n",
+ "#-=-=-=-#\n",
+ "# Upload files\n",
+ "\n",
+ "__Cancel_Permission = \"\" if __URL_Fail else \" [i #A0A0A0](can be cancelled)[/]\"\n",
+ "\n",
+ "if any((Ask_to_upload_files_if_download_succeeds, __URL_Fail)):\n",
+ "\tprint(\"\\n\" + \"โ\" * 32 + \"\\n\")\n",
+ "\trprint(f\"Upload [b #44AAFF]AUDIO[/] files{__Cancel_Permission}\")\n",
+ "\n",
+ "\ttry:\n",
+ "\t\tfor File in files.upload():\n",
+ "\t\t\tFiles.append(File)\n",
+ "\texcept TypeError:\n",
+ "\t\tpass\n",
+ "\texcept (KeyboardInterrupt, EOFError):\n",
+ "\t\trprint(\"\\n\\n[b #FFCC00]File upload cancelled.[/]\")\n",
+ "\n",
+ "\tFiles = [str(Path(File).resolve()) for File in Files]\n",
+ "\tif is_colab:\n",
+ "\t\tFiles = [File for File in Files if os.path.basename(File) != \".ipynb_checkpoints\"]\n",
+ "\tFiles = list(set(Files))\n",
+ "\n",
+ "#-=-=-=-#\n",
+ "# Check for files\n",
+ "\n",
+ "Files = [os.path.abspath(File) for File in Files]\n",
+ "\n",
+ "err = 0\n",
+ "try:\n",
+ "\t# Use this later for string formatting\n",
+ "\tLongest_File_Name_Length = [File.split(Directory_Inputs)[1][1:] for File in Files]\n",
+ "\tLongest_File_Name_Length.sort(key = len)\n",
+ "\tLongest_File_Name_Length = len(Longest_File_Name_Length[-1])\n",
+ "except IndexError:\n",
+ "\terr = 1\n",
+ "\n",
+ "if err:\n",
+ "\traise SystemExit(\"No uploaded files has been found.\")\n",
+ "\n",
+ "#-=-=-=-#\n",
+ "\n",
+ "os.chdir(__Directory_Base)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "source": [
+ "#@title Verify files and convert them to `WAV` โ๏ธ
\n",
+ "#@markdown > โ ๏ธ **Files whose [MIME type](https://wikipedia.org/wiki/Media_type)'s first segment will not be detected as `audio` will be removed without warning.**\n",
+ "if \"Files\" not in locals():\n",
+ "\traise SystemExit(\"Requirements were not installed!\\nPlease run the first cell.\")\n",
+ "\n",
+ "if not Files:\n",
+ "\traise SystemExit(\"No files has been found!\")\n",
+ "\n",
+ "#-=-=-=-#\n",
+ "\n",
+ "Target = \"WAV\"\n",
+ "\n",
+ "#-=-=-=-#\n",
+ "\n",
+ "Target = Target.split()[0].upper().strip(\".\")\n",
+ "\n",
+ "for Input in Files:\n",
+ "\tInput_Split = os.path.split(os.path.abspath(Input))\n",
+ "\tInput_Name = Input_Split[1]\n",
+ "\n",
+ "\ttry:\n",
+ "\t\tInput_MIME = mFile(Input).mime\n",
+ "\texcept AttributeError:\n",
+ "\t\tInput_MIME = guess_type(Input)\n",
+ "\tInput_MIME = Input_MIME[0].lower().split(\"/\")\n",
+ "\n",
+ "\tif Input_MIME[0] == \"audio\":\n",
+ "\t\tif Input_MIME[1] != Target.lower():\n",
+ "\t\t\tos.environ[\"FILE_INPUT\"] = Input\n",
+ "\t\t\tos.environ[\"FILE_OUTPUT\"] = os.path.splitext(Input)[0] + f\".{Target.lower()}\"\n",
+ "\n",
+ "\t\t\trprint(f'[b #00CC00]\"{Input_Name}\" is not a {Target} file, converting...[/]')\n",
+ "\t\t\t!ffmpeg -y -i \"$FILE_INPUT\" -hide_banner -loglevel 16 \\\n",
+ "\t\t\t\t-map_metadata 0 -map_metadata 0:s:0 \\\n",
+ "\t\t\t\t-fflags +bitexact -flags:v +bitexact -flags:a +bitexact \\\n",
+ "\t\t\t\t\"$FILE_OUTPUT\"\n",
+ "\n",
+ "\t\t\tFiles[Files.index(Input)] = os.environ[\"FILE_OUTPUT\"]\n",
+ "\t\t\tos.remove(Input)\n",
+ "\telse:\n",
+ "\t\trprint(f'[b #FF0000]\"{Input_Name}\" is not an audio file, removing[/]')\n",
+ "\t\tFiles.remove(Input)\n",
+ "\t\tos.remove(Input)\n",
+ "\n",
+ "#-=-=-=-#\n",
+ "\n",
+ "if not Files:\n",
+ "\traise SystemExit(\"No files has been found!\")"
+ ],
+ "metadata": {
+ "id": "k3XKgCi0EWyP",
+ "cellView": "form"
+ }
+ },
+ {
+ "cell_type": "markdown",
+ "source": [
+ "# **3.** Process ๐
"
+ ],
+ "metadata": {
+ "id": "wWMN_sT-ugof"
+ }
+ },
+ {
+ "cell_type": "code",
+ "source": [
+ "#@title Load Model โ๏ธ
\n",
+ "#@markdown | Name | Quality (speech) | Quality (music) | Details |\n",
+ "#@markdown |:-|:-|:-|:-|\n",
+ "#@markdown | `hifi-gan-bwe-10-42890e3-vctk-48kHz` | โญ | โญ | Same as bwe-05, but uses bandlimited interpolation for upsampling, for reduced noise and aliasing. Uses the same parameters as resampy's [`kaiser_best`](https://github.com/bmcfee/resampy/blob/5f46888e8b52402f2c62f374b39b93e0743543ad/resampy/filters.py#L9) mode. |\n",
+ "#@markdown | `hifi-gan-bwe-11-d5f542d-vctk-8kHz-48kHz` | โญโญ | โญ | Same as bwe-10, but trained only on 8kHz sources, for specialized upsampling. |\n",
+ "#@markdown | `hifi-gan-bwe-12-b086d8b-vctk-16kHz-48kHz` | โญโญโญ | โญ | Same as bwe-10, but trained only on 16kHz sources, for specialized upsampling. |\n",
+ "#@markdown | `hifi-gan-bwe-13-59f00ca-vctk-24kHz-48kHz` | โญโญโญโญ | โญโญ | Same as bwe-10, but trained only on 24kHz sources, for specialized upsampling. |\n",
+ "#@markdown | `hifi-gan-bwe-05-cd9f4ca-vctk-48kHz` | โญโญโญโญโญ | โญโญโญโญ | Trained for 200K iterations on the VCTK speech dataset with noise agumentation from the DNS Challenge dataset. |\n",
+ "\n",
+ "#@markdown ---\n",
+ "\n",
+ "if \"Models\" not in locals():\n",
+ "\trprint(\"[b #FF0000]Requirements were not installed!\\nPlease run the first cell.[/]\")\n",
+ "\n",
+ "Model_Name = \"hifi-gan-bwe-05-cd9f4ca-vctk-48kHz\" #@param [\"hifi-gan-bwe-10-42890e3-vctk-48kHz\", \"hifi-gan-bwe-11-d5f542d-vctk-8kHz-48kHz\", \"hifi-gan-bwe-12-b086d8b-vctk-16kHz-48kHz\", \"hifi-gan-bwe-13-59f00ca-vctk-24kHz-48kHz\", \"hifi-gan-bwe-05-cd9f4ca-vctk-48kHz\"]\n",
+ "Model = BandwidthExtender.from_pretrained(Model_Name)\n",
+ "\n",
+ "#-=-=-=-#\n",
+ "\n",
+ "rprint('[b][#00CC00]Successfully loaded \"{0}\" model.[/]'.format(Model_Name))\n",
+ "print()\n",
+ "rprint(\"\\nDetails: {0}.\".format(Models[Model_Name]))"
+ ],
+ "metadata": {
+ "id": "quPFIMVHZYZz",
+ "cellView": "form"
+ }
+ },
+ {
+ "cell_type": "code",
+ "source": [
+ "#@title # **Run**
\n",
+ "#@markdown Select $\\ge1$ output target samplerates.\n",
+ "SR_44100 = False #@param {type: \"boolean\"}\n",
+ "SR_48000 = True #@param {type: \"boolean\"}\n",
+ "SR_96000 = False #@param {type: \"boolean\"}\n",
+ "SR_192000 = False #@param {type: \"boolean\"}\n",
+ "\n",
+ "SR_BASE = int(48_000)\n",
+ "Target_Samplerates = {\n",
+ "\t44_100: SR_44100,\n",
+ "\tSR_BASE: SR_48000,\n",
+ "\t96_000: SR_96000,\n",
+ "\t192_000: SR_192000\n",
+ "}\n",
+ "\n",
+ "Sampling_Factors = {}\n",
+ "for Key in Target_Samplerates:\n",
+ "\tif Key != SR_BASE:\n",
+ "\t\tSampling_Factors.update({Key: Key / SR_BASE})\n",
+ "Sampling_Factors.update({SR_BASE: 1})\n",
+ "\n",
+ "Target_Samplerates = [int(Key) for Key, Value in Target_Samplerates.items() if Value]\n",
+ "\n",
+ "if not Target_Samplerates:\n",
+ "\traise SystemExit(\"No target samplerates were selected!\")\n",
+ "\n",
+ "#@markdown > โ ๏ธ **Output target samplerates above `48 000 Hz`:**\n",
+ "#@markdown > - **Takes longer to process **\n",
+ "#@markdown > - **Uses MUCH more RAM and may lead to the notebook failure! **\n",
+ "#@markdown > - **Changes frequency balance**\n",
+ "#@markdown > - **Was tested only on the `hifi-gan-bwe-05-cd9f4ca-vctk-48kHz` model ** \n",
+ "#@markdown\n",
+ "\n",
+ "#@markdown > ## โ ๏ธ **Previously processed files will be removed without warning!** \n",
+ "\n",
+ "#@markdown > โน๏ธ **Files that duration exceeds $10$ seconds are not recommended!** \n",
+ "\n",
+ "#@markdown ---\n",
+ "\n",
+ "Sort_Files_by = \"Upload order ๐ข\" #@param [\"Upload order ๐ข\", \"Duration ๐\", \"Size โ๏ธ\"]\n",
+ "Sort_Files_by = Sort_Files_by.lower()\n",
+ "Descending = False #@param {type: \"boolean\"}\n",
+ "\n",
+ "#@markdown ---\n",
+ "\n",
+ "Upscale_Internal_Gain = 0 # @param {type: \"slider\", min: 0, max: 6, step: 1}\n",
+ "\n",
+ "#-=-=-=-#\n",
+ "# Files removal\n",
+ "\n",
+ "Files_Outputs = []\n",
+ "\n",
+ "for File in Path(Directory_Outputs).rglob(\"*\"):\n",
+ "\tFile = str(File.resolve())\n",
+ "\tif is_colab:\n",
+ "\t\tif \".ipynb_checkpoints\" not in os.path.basename(File):\n",
+ "\t\t\tFiles_Outputs.append(File)\n",
+ "\telse:\n",
+ "\t\tFiles_Outputs.append(File)\n",
+ "\n",
+ "for File in Files_Outputs:\n",
+ "\tif os.path.isfile(File):\n",
+ "\t\tos.remove(File)\n",
+ "\n",
+ "for File in Files_Outputs:\n",
+ "\tif os.path.isdir(File):\n",
+ "\t\trmtree(File)\n",
+ "\n",
+ "#-=-=-=-#\n",
+ "# Sorting files\n",
+ "\n",
+ "Files_Sorted = Files\n",
+ "if \"duration\" in Sort_Files_by:\n",
+ "\tFiles_Sorted = {File: mFile(File).info.length for File in Files}\n",
+ "\tFiles_Sorted = sorted(Files_Sorted.items(), key = lambda x: x[1])\n",
+ "\tFiles_Sorted = list(dict(Files_Sorted))\n",
+ "if \"size\" in Sort_Files_by:\n",
+ "\tFiles_Sorted = sorted(Files, key = os.path.getsize)\n",
+ "\n",
+ "if Descending:\n",
+ "\tFiles_Sorted = Files_Sorted[::-1]\n",
+ "\n",
+ "#-=-=-=-#\n",
+ "\n",
+ "Runtime = time()\n",
+ "Counter_Samplerates = 1\n",
+ "\n",
+ "torch.cuda.empty_cache()\n",
+ "\n",
+ "try:\n",
+ "\twith torch.no_grad():\n",
+ "\t\tfor Output_Target_Samplerate in Target_Samplerates:\n",
+ "\t\t\tOutput_Target_Samplerate_Display = f\"{Output_Target_Samplerate:,}\".split(\",\")\n",
+ "\t\t\tOutput_Target_Samplerate_Display = \" \".join(Output_Target_Samplerate_Display) + \" Hz\"\n",
+ "\t\t\tCounter_Samplerates_Display = str(Counter_Samplerates).rjust(len(str(len(Target_Samplerates))) + 1, \"0\")\n",
+ "\n",
+ "\t\t\trprint(\"[b][#44AAFF]{0}.[/] Processing ([#44AAFF]{1}[/])[/]\".format(\n",
+ "\t\t\t\tCounter_Samplerates_Display,\n",
+ "\t\t\t\tOutput_Target_Samplerate_Display\n",
+ "\t\t\t))\n",
+ "\n",
+ "\t\t\tCounter = 1\n",
+ "\t\t\tfor Input in Files_Sorted:\n",
+ "\t\t\t\tCounter_Display = str(Counter).rjust(len(str(len(Files_Sorted))) + 1, \"0\")\n",
+ "\t\t\t\t# Output file\n",
+ "\t\t\t\tInput_Split = os.path.split(os.path.abspath(Input))\n",
+ "\n",
+ "\t\t\t\tOutput = os.path.join(\n",
+ "\t\t\t\t\tDirectory_Outputs,\n",
+ "\t\t\t\t\tos.path.relpath(Input_Split[0], Directory_Inputs),\n",
+ "\t\t\t\t\t\"_\".join((\n",
+ "\t\t\t\t\t\tos.path.splitext(Input_Split[1])[0],\n",
+ "\t\t\t\t\t\t\"scaled\",\n",
+ "\t\t\t\t\t\tstr(Output_Target_Samplerate)\n",
+ "\t\t\t\t\t)) + os.path.splitext(Input_Split[1])[1]\n",
+ "\t\t\t\t)\n",
+ "\n",
+ "\t\t\t\tif not os.path.exists(os.path.dirname(Output)):\n",
+ "\t\t\t\t\tos.makedirs(os.path.dirname(Output), exist_ok = True)\n",
+ "\n",
+ "\t\t\t\t#-=-=-=-#\n",
+ "\t\t\t\t# Data\n",
+ "\n",
+ "\t\t\t\twith audioread.audio_open(Input) as File_Object:\n",
+ "\t\t\t\t\tSamplerate = File_Object.samplerate\n",
+ "\t\t\t\t\tAudio_Data = (\n",
+ "\t\t\t\t\t\tnp.hstack([np.frombuffer(b, dtype = np.int16) for b in File_Object])\n",
+ "\t\t\t\t\t\t.reshape([-1, File_Object.channels])\n",
+ "\t\t\t\t\t\t.astype(np.float32)\n",
+ "\t\t\t\t\t) / (32767 - (Upscale_Internal_Gain * 1024))\n",
+ "\n",
+ "\t\t\t\t#-=-=-=-#\n",
+ "\t\t\t\t# Scale\n",
+ "\n",
+ "\t\t\t\tFile_Object = mFile(Input)\n",
+ "\t\t\t\tMSR = Model.sample_rate\n",
+ "\n",
+ "\t\t\t\trprint(\" [b][#FFCC00]{0}.[/] [i]{1} [#A0A0A0]({2}s) ({3})[/][/][/]\".format(\n",
+ "\t\t\t\t\tCounter_Display,\n",
+ "\n",
+ "\t\t\t\t\tos.path.join(\n",
+ "\t\t\t\t\t\tos.path.relpath(Input_Split[0], Directory_Inputs)[2:],\n",
+ "\t\t\t\t\t\tInput_Split[1]\n",
+ "\t\t\t\t\t).ljust(Longest_File_Name_Length, \" \"),\n",
+ "\n",
+ "\t\t\t\t\tround(File_Object.info.length, 3),\n",
+ "\t\t\t\t\tfdb_size(Input)\n",
+ "\t\t\t\t))\n",
+ "\n",
+ "\t\t\t\t# Main\n",
+ "\t\t\t\ttorch.cuda.empty_cache()\n",
+ "\t\t\t\tAudio_Data = np.stack([\n",
+ "\t\t\t\t\tModel(torch.from_numpy(x),\n",
+ "\t\t\t\t\tint(Samplerate / Sampling_Factors[Output_Target_Samplerate])\n",
+ "\t\t\t\t\t) for x in Audio_Data.T]).T\n",
+ "\t\t\t\twrite(\n",
+ "\t\t\t\t\tOutput,\n",
+ "\t\t\t\t\tint(MSR * Sampling_Factors[Output_Target_Samplerate]),\n",
+ "\t\t\t\t\tAudio_Data\n",
+ "\t\t\t\t)\n",
+ "\n",
+ "\t\t\t\tCounter += 1\n",
+ "\n",
+ "\t\t\t#-=-=-=-#\n",
+ "\n",
+ "\t\t\tif all((len(Target_Samplerates) > 1, Output_Target_Samplerate != Target_Samplerates[-1])):\n",
+ "\t\t\t\tprint()\n",
+ "\n",
+ "\t\t\tCounter_Samplerates += 1\n",
+ "except (KeyboardInterrupt, EOFError):\n",
+ "\trprint(\"[#FF0000]Operation cancelled by user.[/]\")\n",
+ "\n",
+ "torch.cuda.empty_cache()\n",
+ "\n",
+ "#-=-=-=-#\n",
+ "\n",
+ "__Run_Time = time() - Runtime\n",
+ "print(\"\\n\" + \"โ\" * 32 + \"\\n\")\n",
+ "rprint(\"[b #00CC00]Done![/]\")\n",
+ "rprint(\"Runtime: [b #44AAFF]{0}[/]\".format(\n",
+ "\tstr(timedelta(seconds = __Run_Time))[2:-3]\n",
+ "))\n",
+ "rprint(\"\\t[i #A0A0A0]avg. {0} per file[/]\".format(\n",
+ "\tstr(timedelta(seconds = __Run_Time / len(Files)))[2:-3]\n",
+ "))\n",
+ "rprint(\"\\t[i #A0A0A0]avg. {0} per samplerate[/]\".format(\n",
+ "\tstr(timedelta(seconds = (__Run_Time / len(Files)) / len(Target_Samplerates)))[2:-3]\n",
+ "))"
+ ],
+ "metadata": {
+ "id": "4ni9ii4SeEPe",
+ "cellView": "form"
+ }
+ },
+ {
+ "cell_type": "markdown",
+ "source": [
+ "# Utils โ๏ธ
"
+ ],
+ "metadata": {
+ "id": "XfDlrVA9Qc1x"
+ }
+ },
+ {
+ "cell_type": "code",
+ "source": [
+ "#@title Convert output files to `FLAC` ๐ถ
\n",
+ "\n",
+ "Bit_Depth = \"24-bit\" #@param [\"16-bit\", \"24-bit\"]\n",
+ "Bit_Depth = Bit_Depth.split(\"-\")[0]\n",
+ "Normalize_dB = 1 # @param {type: \"slider\", min: -6, max: 1, step: 1}\n",
+ "#@markdown > โน๏ธ To **disable** normalization, set `Normalize_dB` to **`1`**.\n",
+ "\n",
+ "#-=-=-=-#\n",
+ "\n",
+ "Target = \"FLAC\"\n",
+ "Target = Target.split()[0].lower().strip(\".\")\n",
+ "\n",
+ "#-=-=-=-#\n",
+ "\n",
+ "os.environ[\"BIT_DEPTH\"] = \"-b \" + Bit_Depth\n",
+ "os.environ[\"NORMALIZE\"] = (\"--norm \" + str(Normalize_dB)) if Normalize_dB < 1 else \"\"\n",
+ "\n",
+ "for File in Path(Directory_Outputs).rglob(\"*.*\"):\n",
+ "\tInput = str(File.resolve())\n",
+ "\n",
+ "\tif os.path.isfile(Input):\n",
+ "\t\tInput_MIME = mFile(Input).mime[0].lower().split(\"/\")\n",
+ "\t\tInput_Name = os.path.relpath(Input, Directory_Main)\n",
+ "\n",
+ "\t\tOutput_FLAC = os.path.splitext(Input)[0], f\".{Target.lower()}\"\n",
+ "\t\tOutput = \"_\".join(Output_FLAC)\n",
+ "\n",
+ "\t\tos.environ[\"FILE_INPUT\"] = Input\n",
+ "\t\tos.environ[\"FILE_OUTPUT\"] = Output\n",
+ "\n",
+ "\t\trprint('[b i]{1}onverting [#44AAFF]\"{0}\"[/] to FLAC...[/]'.format(\n",
+ "\t\t\tInput_Name,\n",
+ "\t\t\t(\"rec\" if Input_MIME[1] == \"flac\" else \"c\").capitalize()\n",
+ "\t\t))\n",
+ "\t\t!sox \"$FILE_INPUT\" -D $BIT_DEPTH -C 8 $NORMALIZE --comment \"\" -G \"$FILE_OUTPUT\" -V0\n",
+ "\n",
+ "\t\tos.remove(Input)\n",
+ "\t\tos.rename(Output, \"\".join(Output_FLAC))"
+ ],
+ "metadata": {
+ "cellView": "form",
+ "id": "nxkupjCJpf5R"
+ }
+ },
+ {
+ "cell_type": "code",
+ "source": [
+ "#@title Download archive with output files ๐๏ธ
\n",
+ "Emphasize_Archive_File_Name = True #@param {type: \"boolean\"}\n",
+ "Beggining = \"!_\" if Emphasize_Archive_File_Name else \"\"\n",
+ "\n",
+ "#@markdown > โน๏ธ Pushes the archive file to top of the explorer's file list (**if** it's sorted by name) by putting `!_` to its file name beggining.\n",
+ "\n",
+ "#-=-=-=-#\n",
+ "\n",
+ "__Padding = 7\n",
+ "Archive_File = Beggining + \"_\".join((__title__, str(time()).split(\".\")[1][:__Padding].rjust(__Padding, \"0\")))\n",
+ "Archive_File += \".zip\"\n",
+ "Archive_File = os.path.abspath(Archive_File)\n",
+ "\n",
+ "#-=-=-=-#\n",
+ "\n",
+ "# Archive Creation\n",
+ "print(\"Making Archive...\")\n",
+ "with ZipFile(Archive_File, \"w\", 14, 1, 9) as Archive:\n",
+ "\tfor File in Path(Directory_Outputs).rglob(\"*.*\"):\n",
+ "\t\tFile = str(File.resolve())\n",
+ "\n",
+ "\t\tif os.path.isfile(File):\n",
+ "\t\t\tArcName = os.path.relpath(File, Directory_Outputs)\n",
+ "\n",
+ "\t\t\trprint(f'\\t[b i]Writing [#44AACC]\"{ArcName}\"[/]...')\n",
+ "\t\t\tArchive.write(File, ArcName)\n",
+ "\n",
+ "#-=-=-=-#\n",
+ "\n",
+ "files.download(Archive_File)"
+ ],
+ "metadata": {
+ "id": "rpPfi2g7gnTi",
+ "cellView": "form"
+ }
+ },
+ {
+ "cell_type": "code",
+ "source": [
+ "#@title Terminate runtime after specified time ๐\n",
+ "#@markdown In case if you don't want to waste this account's resources while performing other tasks.\n",
+ "#@markdown > ### **This cancellable action is irreversible and will result in loss of ALL session data!** \n",
+ "\n",
+ "#@markdown \n",
+ "#@markdown \n",
+ "#@markdown Time sheet \n",
+ "#@markdown\n",
+ "#@markdown \n",
+ "#@markdown\n",
+ "#@markdown | Seconds | Minutes |\n",
+ "#@markdown |:-|:-|\n",
+ "#@markdown | `60` | `1` |\n",
+ "#@markdown | `300` | `5` |\n",
+ "#@markdown | `600` | `10` |\n",
+ "#@markdown | `1800` | `30` |\n",
+ "#@markdown | `3600` | `60` |\n",
+ "#@markdown \n",
+ "\n",
+ "#@markdown ---\n",
+ "\n",
+ "Seconds_Default = 30\n",
+ "Seconds = 300 # @param {type: \"integer\"}\n",
+ "\n",
+ "if Seconds < 0:\n",
+ "\trprint(f\"[b][#FFCC00]Seconds are[/] [#FF0000]< 0[/][#FFCC00], defaulting to[/] [#FF0000]{Seconds_Default}[/][#FFCC00].[/][/]\")\n",
+ "\n",
+ "__Spaces = \" \" * 8\n",
+ "\n",
+ "\n",
+ "\n",
+ "if is_colab:\n",
+ "\ttry:\n",
+ "\t\tfor i in range(Seconds, -1, -1):\n",
+ "\t\t\tprint(\"\\r\", end = f\"Runtime will be terminated in {i} seconds...\" + __Spaces)\n",
+ "\n",
+ "\t\trprint(\"\\n\\n[b #FF0000]Runtime has been terminated.[/]\")\n",
+ "\t\truntime.unassign()\n",
+ "\texcept (KeyboardInterrupt, EOFError):\n",
+ "\t\tprint()\n",
+ "\t\trprint(\"[b #FF0000]Operation cancelled by user.[/]\")\n",
+ "else:\n",
+ "\trprint(\"[b #FFCC00]Not in Colab, unsupported.[/]\")"
+ ],
+ "metadata": {
+ "id": "rhKs_AmESZew",
+ "cellView": "form"
+ }
+ }
+ ]
+}
\ No newline at end of file
diff --git a/Notebooks/AI/Audio/_Speech/Clone/Coqui_XTTS.ipynb b/Notebooks/AI/Audio/_Speech/Clone/Coqui_XTTS.ipynb
new file mode 100644
index 0000000..abe52f7
--- /dev/null
+++ b/Notebooks/AI/Audio/_Speech/Clone/Coqui_XTTS.ipynb
@@ -0,0 +1,1075 @@
+{
+ "nbformat": 4,
+ "nbformat_minor": 0,
+ "metadata": {
+ "colab": {
+ "name": "Coqui XTTS",
+ "provenance": [],
+ "collapsed_sections": [
+ "XfDlrVA9Qc1x"
+ ],
+ "gpuType": "T4"
+ },
+ "kernelspec": {
+ "display_name": "Python 3",
+ "name": "python3"
+ },
+ "language_info": {
+ "name": "python"
+ },
+ "accelerator": "GPU"
+ },
+ "cells": [
+ {
+ "cell_type": "markdown",
+ "source": [
+ "# **COQUI ๐ธ** \n",
+ "\n",
+ "> *Compact implementation of [**`camenduru/coqui-XTTS-colab`**](camenduru/coqui-XTTS-colab).*\n",
+ "\n",
+ " \n",
+ "\n",
+ "### Features:\n",
+ "- URL support ๐\n",
+ "- **Batch processing** ๐ฐ\n",
+ "\n",
+ " \n",
+ "\n",
+ " "
+ ],
+ "metadata": {
+ "id": "0D-OWUaK7rjM"
+ }
+ },
+ {
+ "cell_type": "markdown",
+ "source": [
+ "# **1.** Re/install requirements ๐ฅ `โ03m56s`
"
+ ],
+ "metadata": {
+ "id": "mekHMX3m7oIt"
+ }
+ },
+ {
+ "cell_type": "code",
+ "source": [
+ "#@markdown > โน๏ธ Runtime does not need to be restarted.\n",
+ "import os\n",
+ "import re\n",
+ "import time\n",
+ "import torch\n",
+ "import locale\n",
+ "import warnings\n",
+ "import torchaudio\n",
+ "from time import time\n",
+ "from pathlib import Path\n",
+ "from shutil import rmtree\n",
+ "from zipfile import ZipFile\n",
+ "from datetime import timedelta\n",
+ "from rich import print as rprint\n",
+ "from mimetypes import guess_type\n",
+ "from psutil import virtual_memory\n",
+ "from requests import Session, utils\n",
+ "from contextlib import redirect_stdout\n",
+ "from IPython.display import clear_output\n",
+ "\n",
+ "try:\n",
+ "\tfrom google.colab import files, runtime\n",
+ "\tis_colab = True\n",
+ "except ImportError:\n",
+ "\tis_colab = False\n",
+ "\n",
+ "GPU = torch.cuda.device_count()\n",
+ "warnings.filterwarnings(\"ignore\")\n",
+ "locale.getpreferredencoding = lambda: \"UTF-8\"\n",
+ "\n",
+ "#-=-=-=-#\n",
+ "# Metadata\n",
+ "\n",
+ "__title__ = \"Coqui XTTS\"\n",
+ "__author__ = \"kubinka0505\"\n",
+ "__date__ = \"31st December 2023\"\n",
+ "__title__ = __title__.replace(\" \", \"_\")\n",
+ "\n",
+ "#-=-=-=-#\n",
+ "# Modules & packages\n",
+ "\n",
+ "requirements = {\n",
+ "\t\"modules\": [\"TTS==0.21.1\", \"langid\", \"unidic-lite\", \"unidic\", \"deepspeed\", \"mutagen\"],\n",
+ "\t\"packages\": [\"sox\"]\n",
+ "}\n",
+ "\n",
+ "if GPU:\n",
+ "\tGPU_Name = torch.cuda.get_device_name(torch.cuda.current_device())\n",
+ "\trprint(\"[b #00CC00]GPU Available![/] [#A0A0A0]({0})[/]\".format(GPU_Name))\n",
+ "else:\n",
+ "\trprint(\"[#FF0000][b]GPU Unavailable!\\n[/]Processing will be impossible - requirements will not be installed.[/]\")\n",
+ "\traise SystemExit()\n",
+ "\n",
+ "print(\"\\n\" + \"โ\" * 32 + \"\\n\")\n",
+ "\n",
+ "try:\n",
+ "\t__modules = requirements[\"modules\"]\n",
+ "\t__packages = requirements[\"packages\"]\n",
+ "\n",
+ "\tif __modules:\n",
+ "\t\tfor Name in __modules:\n",
+ "\t\t\t!pip uninstall {Name} -y -q | grep -v \"WARNING: Skip\"\n",
+ "\t\t\t!pip install -U {Name} --progress-bar off | grep -v \"already\"\n",
+ "\t\t\tif all((len(__modules) > 1, Name != __modules[-1])):\n",
+ "\t\t\t\tprint()\n",
+ "\n",
+ "\tprint()\n",
+ "\n",
+ "\t!pip install numpy==1.22.0 --force-reinstall\n",
+ "\t!python -m unidic download\n",
+ "\n",
+ "\tif __packages:\n",
+ "\t\tfor Name in __packages:\n",
+ "\t\t\t!apt-get install --reinstall {Name} -qq > /dev/null 2 >&1\n",
+ "\t\t\tif all((len(__packages) > 1, Name != __packages[-1])):\n",
+ "\t\t\t\tprint()\n",
+ "\n",
+ "\timport langid\n",
+ "\tfrom TTS.api import TTS\n",
+ "\tfrom TTS.tts.configs.xtts_config import XttsConfig\n",
+ "\tfrom TTS.tts.models.xtts import Xtts\n",
+ "\tfrom TTS.utils.manage import ModelManager\n",
+ "\tfrom TTS.utils.generic_utils import get_user_data_dir\n",
+ "\n",
+ "\tfrom mutagen import File as mFile\n",
+ "\n",
+ "\tos.environ[\"COQUI_TOS_AGREED\"] = \"1\"\n",
+ "\n",
+ "\t#-=-=-=-#\n",
+ "\t# Requests\n",
+ "\n",
+ "\tsession = Session()\n",
+ "\tsession.headers.update(\n",
+ "\t\t{\n",
+ "\t\t\t\"User-Agent\":\n",
+ "\t\t\t\"Mozilla/5.0 (Windows NT 10.0; Win32; x32) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36\"\n",
+ "\t\t}\n",
+ "\t)\n",
+ "\n",
+ "\t#-=-=-=-#\n",
+ "\t# Functions\n",
+ "\n",
+ "\tdef fdb_size(obj: str, extended_units: bool = False, bits: bool = False, recursive: bool = False) -> str:\n",
+ "\t\t\"\"\"\n",
+ "\t\tArgs:\n",
+ "\t\t\tobj: Bytes integer or string path of existing file or directory.\n",
+ "\t\t\textended_units: Extends the unit of the result, i.e. \"Megabytes\" instead of \"MB\".\n",
+ "\t\t\tbits: Uses decimal divider (1000) instead of binary one. (1024)\n",
+ "\t\t\trecursive: Iterate subdirectories, applicable only if `obj` is directory. (slow!)\n",
+ "\n",
+ "\t\tReturns:\n",
+ "\t\t\tHuman-readable files size string.\n",
+ "\t\t\"\"\"\n",
+ "\t\t# Setup\n",
+ "\n",
+ "\t\tif bits:\n",
+ "\t\t\tBits = 1000\n",
+ "\t\t\tBits_Display_Single = \"bit\"\n",
+ "\t\t\tBits_Display_Multiple = \"bits\"\n",
+ "\t\telse:\n",
+ "\t\t\tBits = 1024\n",
+ "\t\t\tBits_Display_Single = \"byte\"\n",
+ "\t\t\tBits_Display_Multiple = \"bytes\"\n",
+ "\n",
+ "\t\tUnits = {\n",
+ "\t\t\t\"\":\t \"\",\n",
+ "\t\t\t\"K\": \"kilo\",\n",
+ "\t\t\t\"M\": \"mega\",\n",
+ "\t\t\t\"G\": \"giga\",\n",
+ "\t\t\t\"T\": \"tera\",\n",
+ "\t\t\t\"P\": \"peta\",\n",
+ "\t\t\t\"E\": \"exa\",\n",
+ "\t\t\t\"Z\": \"zetta\",\n",
+ "\t\t\t\"Y\": \"yotta\",\n",
+ "\t\t\t\"R\": \"ronna\",\n",
+ "\t\t\t\"Q\": \"quetta\"\n",
+ "\t\t}\n",
+ "\n",
+ "\t\t#-=-=-=-#\n",
+ "\t\t# Search for files\n",
+ "\n",
+ "\t\tif isinstance(obj, str):\n",
+ "\t\t\tpath = str(Path(obj).resolve())\n",
+ "\n",
+ "\t\t\tif not os.path.exists(path):\n",
+ "\t\t\t\traise FileNotFoundError(path)\n",
+ "\n",
+ "\t\t\tif os.path.isfile(obj):\n",
+ "\t\t\t\tFiles = [obj]\n",
+ "\t\t\telse:\n",
+ "\t\t\t\tWildcard = \"*\"\n",
+ "\t\t\t\tif recursive:\n",
+ "\t\t\t\t\tWildcard += \"*/*\"\n",
+ "\t\t\t\tFiles = list(Path(obj).glob(Wildcard))\n",
+ "\t\t\t\tfor File in Files:\n",
+ "\t\t\t\t\tFiles[Files.index(File)] = str(File.resolve())\n",
+ "\n",
+ "\t\t\tFiles = map(os.path.getsize, Files)\n",
+ "\t\t\tBytes = sum(Files)\n",
+ "\t\telse:\n",
+ "\t\t\tBytes = obj\n",
+ "\n",
+ "\t\t#-=-=-=-#\n",
+ "\t\t# Calculate integer\n",
+ "\n",
+ "\t\tfor Unit in Units:\n",
+ "\t\t\tif Bytes < Bits:\n",
+ "\t\t\t\tbreak\n",
+ "\t\t\tBytes /= Bits\n",
+ "\n",
+ "\t\t#-=-=-=-#\n",
+ "\t\t# Ending conditions\n",
+ "\n",
+ "\t\tif extended_units:\n",
+ "\t\t\tif Bytes == 1:\n",
+ "\t\t\t\tBits_Display = Bits_Display_Single\n",
+ "\t\t\telse:\n",
+ "\t\t\t\tBits_Display = Bits_Display_Multiple\n",
+ "\t\t\tUnit = (Units[Unit] + Bits_Display).capitalize()\n",
+ "\t\telse:\n",
+ "\t\t\tUnit += \"B\"\n",
+ "\n",
+ "\t\t#-=-=-=-#\n",
+ "\t\t# Add zero to integer\n",
+ "\n",
+ "\t\tif \".\" in str(Bytes):\n",
+ "\t\t\tBytes = round(Bytes, 2)\n",
+ "\t\t\tBytes = str(Bytes).split(\".\")\n",
+ "\t\t\tBytes[1] = Bytes[1][:2]\n",
+ "\t\t\tBytes[1] = Bytes[1].ljust(2, \"0\")\n",
+ "\t\t\tBytes = \".\".join(Bytes)\n",
+ "\n",
+ "\t\tBytes = str(Bytes)\n",
+ "\n",
+ "\t\t#-=-=-=-#\n",
+ "\t\t# Return string\n",
+ "\n",
+ "\t\treturn \" \".join((Bytes, Unit))\n",
+ "\n",
+ "\t#-=-=-=-#\n",
+ "\t# Directories\n",
+ "\n",
+ "\tDirectory_Main = os.path.abspath(__title__)\n",
+ "\tDirectory_Primary = os.path.join(Directory_Main, \"Repository\")\n",
+ "\tDirectory_Inputs = os.path.join(Directory_Main, \"_Inputs\")\n",
+ "\tDirectory_Outputs = os.path.join(Directory_Main, \"_Outputs\")\n",
+ "\n",
+ "\tfor Directory in Directory_Inputs, Directory_Outputs:\n",
+ "\t\trmtree(Directory, True)\n",
+ "\t\tos.makedirs(Directory, exist_ok = True)\n",
+ "except (KeyboardInterrupt, EOFError):\n",
+ "\tprint(\"\\n\" + \"โ\" * 32 + \"\\n\" + \"Operation cancelled by user.\")"
+ ],
+ "metadata": {
+ "id": "ctLvxT2RxEyR",
+ "cellView": "form"
+ }
+ },
+ {
+ "cell_type": "markdown",
+ "source": [
+ "# **2.** Upload files ๐ค
"
+ ],
+ "metadata": {
+ "id": "h9Sg8W6159zf"
+ }
+ },
+ {
+ "cell_type": "code",
+ "source": [
+ "#@markdown > ๐๏ธ **URL of `ZIP` archive with files is supported.**\n",
+ "\n",
+ "Direct_URL = \"\" #@param {type: \"string\"}\n",
+ "Allow_non_WAV_URL = True #@param {type: \"boolean\"}\n",
+ "__URL_Fail = False if Direct_URL else True\n",
+ "\n",
+ "#@markdown ---\n",
+ "\n",
+ "#@markdown > โน๏ธ `Lazy Unpacking` determines whether **files from the archive should only be unpacked if their file name extension** is in the `Formats` variable.\n",
+ "\n",
+ "Lazy_Unpacking = True #@param {type: \"boolean\"}\n",
+ "Formats = \"AAC, AIFF, ALAC, APE, FLAC, M4A, MP3, OGG, OPUS, WAV, WV\" #@param {type: \"string\"}\n",
+ "Formats = [Format.lower().strip() for Format in Formats.split(\",\")]\n",
+ "\n",
+ "#@markdown ---\n",
+ "\n",
+ "Ask_to_upload_files_if_download_succeeds = True #@param {type: \"boolean\"}\n",
+ "Remove_previously_uploaded_files_and_subdirectories = True #@param {type: \"boolean\"}\n",
+ "\n",
+ "#-=-=-=-#\n",
+ "\n",
+ "if \"rmtree\" not in locals():\n",
+ "\traise SystemExit(\"Requirements were not installed!\\nPlease run the first cell.\")\n",
+ "\n",
+ "if \"Files\" not in locals():\n",
+ "\tFiles = []\n",
+ "\n",
+ "#-=-=-=-#\n",
+ "\n",
+ "__Directory_Base = os.getcwd()\n",
+ "\n",
+ "# `os.chdir` since `files.upload` does not have the target directory argument\n",
+ "os.chdir(Directory_Inputs)\n",
+ "\n",
+ "if Remove_previously_uploaded_files_and_subdirectories:\n",
+ "\tFiles_Inputs = []\n",
+ "\tfor File in Path(Directory_Inputs).rglob(\"*\"):\n",
+ "\t\tFile = str(File.resolve())\n",
+ "\t\tif is_colab:\n",
+ "\t\t\tif \".ipynb_checkpoints\" not in os.path.basename(File):\n",
+ "\t\t\t\tFiles_Inputs.append(File)\n",
+ "\t\telse:\n",
+ "\t\t\tFile_Inputs.append(File)\n",
+ "\n",
+ "\tfor File in Files_Inputs:\n",
+ "\t\tif os.path.isfile(File):\n",
+ "\t\t\tos.remove(File)\n",
+ "\t\t\trprint('Removed [b #44AAFF]\"{0}\"[/]'.format(\n",
+ "\t\t\t\tos.path.relpath(File, Directory_Inputs)\n",
+ "\t\t\t))\n",
+ "\n",
+ "\tfor File in Files_Inputs:\n",
+ "\t\tif os.path.isdir(File):\n",
+ "\t\t\trmtree(File)\n",
+ "\n",
+ "\tif Files_Inputs:\n",
+ "\t\tprint(\"\\n\" + \"โ\" * 32 + \"\\n\")\n",
+ "\n",
+ "\tFiles = []\n",
+ "\n",
+ "#-=-=-=-#\n",
+ "\n",
+ "Allowed_Specifiers = \"http\", \"https\", \"ftp\"\n",
+ "Allowed_Specifiers = [Specifier + \"://\" for Specifier in Allowed_Specifiers]\n",
+ "Allowed_Specifiers = tuple(Allowed_Specifiers)\n",
+ "\n",
+ "if Direct_URL.lower().startswith(Allowed_Specifiers):\n",
+ "\tfor Delimiter in ((\"?\", \"&\", \"#\")):\n",
+ "\t\tDirect_URL = Direct_URL.split(Delimiter)[0]\n",
+ "\n",
+ "\tDownloaded_File_Location = utils.unquote(Direct_URL.split(\"/\")[-1])\n",
+ "\n",
+ "\t__URL_Fail = False\n",
+ "\ttry:\n",
+ "\t\tSession_obj = session.get(Direct_URL, stream = 1)\n",
+ "\texcept Exception:\n",
+ "\t\t__URL_Fail = True\n",
+ "\n",
+ "\tif __URL_Fail:\n",
+ "\t\trprint(\"[b #FF0000]Provided URL is invalid![/]\")\n",
+ "\t\t__URL_Fail = True\n",
+ "\n",
+ "\tif not __URL_Fail:\n",
+ "\t\twith Session_obj as Site:\n",
+ "\t\t\tif Site.ok:\n",
+ "\t\t\t\tSite_MIME = Site.headers[\"content-type\"].lower().split()[0].split(\";\")[0].split(\"/\")\n",
+ "\t\t\t\tif Site_MIME[0] == \"audio\":\n",
+ "\t\t\t\t\tif any((Site_MIME[1].endswith(\"wav\"), Allow_non_WAV_URL)):\n",
+ "\t\t\t\t\t\twith open(Downloaded_File_Location, \"wb\") as File:\n",
+ "\t\t\t\t\t\t\trprint(f'Downloading [b #00CC00]\"{Downloaded_File_Location}\"[/]...')\n",
+ "\n",
+ "\t\t\t\t\t\t\tfor Chunk in Site.iter_content(chunk_size = 1024):\n",
+ "\t\t\t\t\t\t\t\tif Chunk:\n",
+ "\t\t\t\t\t\t\t\t\tFile.write(Chunk)\n",
+ "\t\t\t\t\t\t\tFiles.append(Downloaded_File_Location)\n",
+ "\t\t\t\t\telse:\n",
+ "\t\t\t\t\t\trprint(\"[b #FF0000]Permission to download non-WAV files was not granted.[/]\")\n",
+ "\t\t\t\t\t\t__URL_Fail = True\n",
+ "\t\t\t\telse:\n",
+ "\t\t\t\t\t# ZIP Archive Handling\n",
+ "\t\t\t\t\tif \"/\".join(Site_MIME) == \"application/zip\":\n",
+ "\t\t\t\t\t\twith open(Downloaded_File_Location, \"wb\") as File:\n",
+ "\t\t\t\t\t\t\trprint(f'Downloading [b #00CC00]\"{Downloaded_File_Location}\"[/]...')\n",
+ "\n",
+ "\t\t\t\t\t\t\tfor Chunk in Site.iter_content(chunk_size = 1024):\n",
+ "\t\t\t\t\t\t\t\tif Chunk:\n",
+ "\t\t\t\t\t\t\t\t\tFile.write(Chunk)\n",
+ "\n",
+ "\t\t\t\t\t\ttry:\n",
+ "\t\t\t\t\t\t\tArchive_Files_Amount = 0\n",
+ "\t\t\t\t\t\t\twith ZipFile(Downloaded_File_Location) as Archive:\n",
+ "\t\t\t\t\t\t\t\tfor Archive_File in Archive.infolist():\n",
+ "\t\t\t\t\t\t\t\t\tif Lazy_Unpacking:\n",
+ "\t\t\t\t\t\t\t\t\t\tif os.path.splitext(Archive_File.filename.lower())[1][1:] in Formats:\n",
+ "\t\t\t\t\t\t\t\t\t\t\tArchive_Files_Amount += 1\n",
+ "\t\t\t\t\t\t\t\t\t\t\tArchive.extract(Archive_File)\n",
+ "\t\t\t\t\t\t\t\t\telse:\n",
+ "\t\t\t\t\t\t\t\t\t\tArchive_Files_Amount += 1\n",
+ "\t\t\t\t\t\t\t\t\t\tArchive.extract(Archive_File)\n",
+ "\n",
+ "\t\t\t\t\t\t\tos.remove(Downloaded_File_Location)\n",
+ "\n",
+ "\t\t\t\t\t\t\t#-=-=-=-#\n",
+ "\n",
+ "\t\t\t\t\t\t\tfor File in Path().rglob(\"*.*\"):\n",
+ "\t\t\t\t\t\t\t\tFile = str(File.resolve())\n",
+ "\n",
+ "\t\t\t\t\t\t\t\tif os.path.isfile(File):\n",
+ "\t\t\t\t\t\t\t\t\tFiles.append(File)\n",
+ "\n",
+ "\t\t\t\t\t\t\trprint(f\"[b #00CC00]{Archive_Files_Amount} files from main directory were extracted successfully![/]\")\n",
+ "\t\t\t\t\t\texcept RuntimeError:\n",
+ "\t\t\t\t\t\t\trprint(\"[b #FF0000]Files extraction was not successful due to password requirement, file corruption or other internal error.[/]\")\n",
+ "\t\t\t\t\t\t\t__URL_Fail = True\n",
+ "\t\t\t\t\telse:\n",
+ "\t\t\t\t\t\trprint(\"[b #FF0000]Provided URL is not an audio file.[/] [i #A0A0A0](undetected MIME type in header)[/]\")\n",
+ "\t\t\t\t\t\t__URL_Fail = True\n",
+ "\t\t\telse:\n",
+ "\t\t\t\trprint(\"[b #FF0000]Failed to fetch the URL due to {0} status code. ({1})[/]\".format(\n",
+ "\t\t\t\t\tSite.status_code, Site.reason.title()\n",
+ "\t\t\t\t))\n",
+ "\t\t\t\t__URL_Fail = True\n",
+ "\n",
+ "#-=-=-=-#\n",
+ "# Upload files\n",
+ "\n",
+ "__Cancel_Permission = \"\" if __URL_Fail else \" [i #A0A0A0](can be cancelled)[/]\"\n",
+ "\n",
+ "if any((Ask_to_upload_files_if_download_succeeds, __URL_Fail)):\n",
+ "\tprint(\"\\n\" + \"โ\" * 32 + \"\\n\")\n",
+ "\trprint(f\"Upload [b #44AAFF]AUDIO[/] files{__Cancel_Permission}\")\n",
+ "\n",
+ "\ttry:\n",
+ "\t\tfor File in files.upload():\n",
+ "\t\t\tFiles.append(File)\n",
+ "\texcept TypeError:\n",
+ "\t\tpass\n",
+ "\texcept (KeyboardInterrupt, EOFError):\n",
+ "\t\trprint(\"\\n\\n[b #FFCC00]File upload cancelled.[/]\")\n",
+ "\n",
+ "\tFiles = [str(Path(File).resolve()) for File in Files]\n",
+ "\tif is_colab:\n",
+ "\t\tFiles = [File for File in Files if os.path.basename(File) != \".ipynb_checkpoints\"]\n",
+ "\tFiles = list(set(Files))\n",
+ "\n",
+ "#-=-=-=-#\n",
+ "# Check for files\n",
+ "\n",
+ "Files = [os.path.abspath(File) for File in Files]\n",
+ "\n",
+ "err = 0\n",
+ "try:\n",
+ "\t# Use this later for string formatting\n",
+ "\tLongest_File_Name_Length = [File.split(Directory_Inputs)[1][1:] for File in Files]\n",
+ "\tLongest_File_Name_Length.sort(key = len)\n",
+ "\tLongest_File_Name_Length = len(Longest_File_Name_Length[-1])\n",
+ "except IndexError:\n",
+ "\terr = 1\n",
+ "\n",
+ "if err:\n",
+ "\traise SystemExit(\"No uploaded files has been found.\")\n",
+ "\n",
+ "#-=-=-=-#\n",
+ "\n",
+ "os.chdir(__Directory_Base)"
+ ],
+ "metadata": {
+ "cellView": "form",
+ "id": "c5fYSLEj5_zv"
+ }
+ },
+ {
+ "cell_type": "code",
+ "source": [
+ "#@title Verify files and convert them to `WAV` โ๏ธ
\n",
+ "#@markdown > โ ๏ธ **Files whose [MIME type](https://wikipedia.org/wiki/Media_type)'s first segment will not be detected as `audio` will be removed without warning.**\n",
+ "if \"Files\" not in locals():\n",
+ "\traise SystemExit(\"Requirements were not installed!\\nPlease run the first cell.\")\n",
+ "\n",
+ "if not Files:\n",
+ "\traise SystemExit(\"No files has been found!\")\n",
+ "\n",
+ "#-=-=-=-#\n",
+ "\n",
+ "Target = \"WAV\"\n",
+ "\n",
+ "#-=-=-=-#\n",
+ "\n",
+ "Target = Target.split()[0].upper().strip(\".\")\n",
+ "\n",
+ "for Input in Files:\n",
+ "\tInput_Name = os.path.basename(Input)\n",
+ "\n",
+ "\ttry:\n",
+ "\t\tInput_MIME = mFile(Input).mime\n",
+ "\texcept AttributeError:\n",
+ "\t\tInput_MIME = guess_type(Input)\n",
+ "\tInput_MIME = Input_MIME[0].lower().split(\"/\")\n",
+ "\n",
+ "\tif Input_MIME[0] == \"audio\":\n",
+ "\t\tif Input_MIME[1] != Target.lower():\n",
+ "\t\t\tos.environ[\"FILE_INPUT\"] = Input\n",
+ "\t\t\tos.environ[\"FILE_OUTPUT\"] = os.path.splitext(Input)[0] + f\".{Target.lower()}\"\n",
+ "\n",
+ "\t\t\trprint(f'[b #00CC00]\"{Input_Name}\" is not a {Target} file, converting...[/]')\n",
+ "\t\t\t!ffmpeg -i \"$FILE_INPUT\" -hide_banner -loglevel 16 \\\n",
+ "\t\t\t\t-map_metadata 0 -map_metadata 0:s:0 \\\n",
+ "\t\t\t\t-fflags +bitexact -flags:v +bitexact -flags:a +bitexact \\\n",
+ "\t\t\t\t\"$FILE_OUTPUT\"\n",
+ "\n",
+ "\t\t\tFiles[Files.index(Input)] = os.environ[\"FILE_OUTPUT\"]\n",
+ "\t\t\tos.remove(Input)\n",
+ "\telse:\n",
+ "\t\trprint(f'[b #FF0000]\"{Input_Name}\" is not an audio file, removing[/]')\n",
+ "\t\tFiles.remove(Input)\n",
+ "\t\tos.remove(Input)\n",
+ "\n",
+ "#-=-=-=-#\n",
+ "\n",
+ "if not Files:\n",
+ "\traise SystemExit(\"No files has been found!\")"
+ ],
+ "metadata": {
+ "cellView": "form",
+ "id": "yeSfavNJ9ndO"
+ }
+ },
+ {
+ "cell_type": "markdown",
+ "source": [
+ "# **3.** Generate ๐ฃ๏ธ
"
+ ],
+ "metadata": {
+ "id": "i0dxtaLy9_eN"
+ }
+ },
+ {
+ "cell_type": "code",
+ "source": [
+ "#@title Setup `(โ02m19s)` โ๏ธ
\n",
+ "# For unknown reasons, takes over 6 minutes to install while put in the first cell\n",
+ "\n",
+ "# Download XTTS\n",
+ "model_name = \"tts_models/multilingual/multi-dataset/xtts_v2\"\n",
+ "model_path = os.path.join(get_user_data_dir(\"tts\"), model_name.replace(\"/\", \"--\"))\n",
+ "\n",
+ "config_json = os.path.join(model_path, \"config.json\")\n",
+ "vocab_json = os.path.join(model_path, \"vocab.json\")\n",
+ "\n",
+ "if os.path.exists(model_path):\n",
+ "\trmtree(model_path)\n",
+ "\n",
+ "# Download model\n",
+ "with redirect_stdout(None):\n",
+ "\tModelManager().download_model(model_name)\n",
+ "\n",
+ "config = XttsConfig()\n",
+ "config.load_json(config_json)\n",
+ "\n",
+ "# Loading model\n",
+ "model = Xtts.init_from_config(config)\n",
+ "model.load_checkpoint(\n",
+ "\tconfig,\n",
+ "\tcheckpoint_path = os.path.join(model_path, \"model.pth\"),\n",
+ "\tvocab_path = vocab_json,\n",
+ "\teval = True,\n",
+ "\tuse_deepspeed = True,\n",
+ ")\n",
+ "model.cuda()\n",
+ "\n",
+ "supported_languages = config.languages"
+ ],
+ "metadata": {
+ "id": "8CTi2dx0L-mB",
+ "cellView": "form"
+ }
+ },
+ {
+ "cell_type": "code",
+ "source": [
+ "#@title # **Upload prompts file** ๐๐ค
\n",
+ "\n",
+ "Prompts = \"\"\"\n",
+ "\n",
+ "# This line is ignored\n",
+ "\n",
+ "# Please write your dialogs here\n",
+ "\n",
+ "\"\"\"\n",
+ "\n",
+ "#-=-=-=-#\n",
+ "\n",
+ "Languages = {\n",
+ "\t#\"id\": (\"long_name\", characters_limit),\n",
+ "\t\"en\": [\"English\", 250],\n",
+ "\t\"es\": [\"Spanish\", 239],\n",
+ "\t\"fr\": [\"French\", 273],\n",
+ "\t\"de\": [\"Deutsch\", 253],\n",
+ "\t\"it\": [\"Italian\", 213],\n",
+ "\t\"pt\": [\"Portuguese\", 203],\n",
+ "\t\"tr\": [\"Turkish\", 226],\n",
+ "\t\"ru\": [\"Russian\", 182],\n",
+ "\t\"nl\": [\"Dutch\", 251],\n",
+ "\t\"pl\": [\"Polish\", 224],\n",
+ "\t\"cs\": [\"Czech\", 186],\n",
+ "\t\"ar\": [\"Arabic\", 166],\n",
+ "\t\"zh-cn\": [\"Chinese\", 82],\n",
+ "\t\"ja\": [\"Japanese\", 71],\n",
+ "\t\"ko\": [\"Korean\", 95],\n",
+ "\t\"hu\": [\"Hungarian\", 224]\n",
+ "}\n",
+ "\n",
+ "#@markdown - **Can be modified inside this cell as a `Prompts` multiline string variable** \n",
+ "\n",
+ "Upload_Prompt_File = True #@param {type: \"boolean\"}\n",
+ "\n",
+ "#@markdown - Saved to `_prompt.txt`, inside main directory.\n",
+ "#@markdown - Separated by pipe: `|`\n",
+ "#@markdown\n",
+ "#@markdown ---\n",
+ "\n",
+ "#@markdown ### Parameters:\n",
+ "#@markdown `speaker_name` `|``language_code` `|``Some text` `|``OUTPUT_NAME` \n",
+ "\n",
+ "#@markdown \n",
+ "\n",
+ "#@markdown `speaker_name` : Existing file without extension inside `/content/Coqui_XTTS/_inputs` directory.\n",
+ "\n",
+ "#@markdown `language_code` : Short language code like `en` (English), `de` (Deutsch) [etc](https://hf.co/coqui/XTTS-v2#languages).\n",
+ "#@markdown - *If `auto`, `none` or `x`, language is being recognized from prompt by the [`langid`](https://github.com/saffsd/langid.py) module.*\n",
+ "\n",
+ "#@markdown `Some text` : A string shorter than the number of characters assigned to the language.\n",
+ "#@markdown - [[**Languages character limits** ]](https://github.com/coqui-ai/TTS/blob/5dcc16d1931538e5bce7cb20c1986df371ee8cd6/TTS/tts/layers/xtts/tokenizer.py#L597-L614)\n",
+ "#@markdown - *The reason for the limit is models inability for longer text processing.*\n",
+ "#@markdown - *Colab prompt **display** is truncated to `75` characters.*\n",
+ "\n",
+ "#@markdown `OUTPUT_NAME` : Output file name in `Directory_Outputs` directory.\n",
+ "#@markdown - *Optional, if not passed file is saved as `Some_text` `.wav`*\n",
+ "#@markdown - *Truncated to 150 characters by default.*\n",
+ "\n",
+ "#@markdown ---\n",
+ "\n",
+ "#@markdown ## Example file structure\n",
+ "\n",
+ "#@markdown ```ini\n",
+ "#@markdown # Lines that are empty or that start with a #, like this one are ignored\n",
+ "#@markdown # Each element of list is stripped out of spaces - it can look like a table\n",
+ "#@markdown\n",
+ "#@markdown # 01. Dialogs of former/USA presidents alive in 2024\n",
+ "#@markdown biden | x | Hi Barack and Donald | HI_BIDEN\n",
+ "#@markdown obama | x | Hi Joe and Donald | HI_OBAMA\n",
+ "#@markdown # kennedy | x | I should not be here | HI_KENNEDY\n",
+ "#@markdown # adams | x | I was not even recorded | HI_ADAMS\n",
+ "#@markdown trump | x | Hi Joe and Barrack | HI_TRUMP\n",
+ "#@markdown\n",
+ "#@markdown # 02. (...)\n",
+ "#@markdown speaker_01|it|Ora so parlare italiano!\n",
+ "#@markdown speaker_02|en|I can speak in english\n",
+ "#@markdown speaker_01|de|I am experimenting\n",
+ "#@markdown\n",
+ "#@markdown # 03. (...)\n",
+ "#@markdown ```\n",
+ "\n",
+ "#-=-=-=-#\n",
+ "\n",
+ "IDs = {v[0]: k for k, v in Languages.items()}\n",
+ "\n",
+ "if Upload_Prompt_File:\n",
+ "\tfn = \"_prompt.txt\"\n",
+ "\tfn = os.path.join(Directory_Inputs, fn)\n",
+ "\n",
+ "\tif os.path.exists(fn):\n",
+ "\t\tos.remove(fn)\n",
+ "\n",
+ "\terr = 0\n",
+ "\ttry:\n",
+ "\t\tfiles.upload_file(fn)\n",
+ "\n",
+ "\t\twith open(fn, \"r\", encoding = \"UTF-8\") as File:\n",
+ "\t\t\tPrompts = File.read()\n",
+ "\texcept ValueError:\n",
+ "\t\terr = 1\n",
+ "\n",
+ "\tif err:\n",
+ "\t\tprint()\n",
+ "\t\trprint(f\"[b #FFCC00] File upload aborted, using prompts variable.[/]\")\n",
+ "\t\tprint(\"\\n\" + \"โ\" * 32)\n",
+ "\n",
+ "#-=-=-=-#\n",
+ "# Old\n",
+ "\n",
+ "Prompts_List = Prompts.strip(\"\\n\")\n",
+ "Prompts_List = Prompts_List.split(\"\\n\")\n",
+ "Prompts_List = [Line for Line in Prompts_List if Line]\n",
+ "__Lines_Old = len(Prompts_List)\n",
+ "\n",
+ "# New\n",
+ "Prompts_List = [Line for Line in Prompts_List if not Line.startswith(\"#\")]\n",
+ "__Lines_New = len(Prompts_List)\n",
+ "\n",
+ "__Ignored = __Lines_Old - __Lines_New\n",
+ "\n",
+ "print()\n",
+ "rprint(\"[b #{0}]Found {1} prompts, {2} {3} ignored.[/]\".format(\n",
+ "\t\"00CC00\" if __Lines_New else \"FF0000\",\n",
+ "\t__Lines_New, __Ignored,\n",
+ "\t\"was\" if __Ignored < 2 else \"were\"\n",
+ "))"
+ ],
+ "metadata": {
+ "id": "WyX8llI5-4O7",
+ "cellView": "form"
+ }
+ },
+ {
+ "cell_type": "code",
+ "source": [
+ "#@title # **Run**
\n",
+ "\n",
+ "def commaFix(s: str) -> str:\n",
+ "\treturn re.sub(\"([^\\x00-\\x7F]|\\w)(\\.|\\ใ|\\?)\", r\"\\1 \\2\\2\", s)\n",
+ "\n",
+ "#@markdown > ## โ ๏ธ **Previously processed files with same speakers will be removed without warning!** \n",
+ "\n",
+ "#@markdown > ## ๐ **Returns `24 000 Hz` mono files.** \n",
+ "#@markdown > \n",
+ "#@markdown > #### *See also:* [**HiFi GAN BWE**](https://colab.research.google.com/github/kubinka0505/colab-notebooks/blob/master/Notebooks/AI/Audio/Upscale/HiFi_GAN_BWE.ipynb) โจ\n",
+ "\n",
+ "#@markdown ---\n",
+ "\n",
+ "#@markdown > *Performs `Prompt = re.sub(\"([^\\x00-\\x7F]|\\w)(\\.|\\ใ|\\?)\", r\"\\1 \\2\\2\", Prompt)` for each `Prompt`*\n",
+ "\n",
+ "Use_Comma_Fix = True #@param {type: \"boolean\"}\n",
+ "Max_Prompt_Display_Length = 75\n",
+ "Truncate_Output_Name_After = 150\n",
+ "\n",
+ "#@markdown ---\n",
+ "\n",
+ "#@markdown > ### *Internal Coqui XTTS variables. Do not modify unless you are sure what you are doing.*\n",
+ "Length_GPT_Condition = 30 #@param {type: \"integer\"}\n",
+ "Length_GPT_Condition_Chunk = 4 #@param {type: \"integer\"}\n",
+ "Length_Reference_Max = 60 #@param {type: \"integer\"}\n",
+ "\n",
+ "#@markdown > *If `Length_Reference_Max` is `0`, the seconds of `speaker_name` file are taken.*\n",
+ "\n",
+ "Repetition_Penalty = 5.0 #@param {type: \"number\"}\n",
+ "Temperature = 0.75 # @param {type:\"slider\", min:0.01, max:0.99, step:0.01}\n",
+ "\n",
+ "#@markdown ---\n",
+ "\n",
+ "#@markdown ### Other settings\n",
+ "Clear_Colab_console_output_after_each_prompt = False #@param {type: \"boolean\"}\n",
+ "\n",
+ "#-=-=-=-#\n",
+ "\n",
+ "if not \"model\" in locals():\n",
+ "\traise Exception(\"No model has been found! Please run the previous cell.\")\n",
+ "\n",
+ "#-=-=-=-#\n",
+ "# Preprocess prompts\n",
+ "\n",
+ "Prompts_List = Prompts.strip(\"\\n\")\n",
+ "Prompts_List = Prompts_List.split(\"\\n\")\n",
+ "\n",
+ "Prompts_List = [\n",
+ "\tLine for Line in Prompts_List\n",
+ "\tif not Line.startswith(\"#\")\n",
+ "]\n",
+ "\n",
+ "IDs = {v[0]: k for k, v in Languages.items()}\n",
+ "Prompts_List = [Line for Line in Prompts_List if Line]\n",
+ "\n",
+ "#-=-=-=-#\n",
+ "\n",
+ "Runtime = time()\n",
+ "Counter = 1\n",
+ "\n",
+ "for Line in Prompts_List:\n",
+ "\tElements = Line.split(\"|\")\n",
+ "\tElements = [Element.strip() for Element in Elements]\n",
+ "\n",
+ "\t#-=-=-=-#\n",
+ "\n",
+ "\tSpeaker_Name = Elements[0]\n",
+ "\tLanguage = Elements[1]\n",
+ "\tPrompt_String = Elements[2]\n",
+ "\n",
+ "\tSpeaker_Path = os.path.join(Directory_Inputs, Speaker_Name) + \".wav\"\n",
+ "\tSpeaker_Display = os.path.splitext(os.path.basename(Speaker_Path))[0]\n",
+ "\n",
+ "\tif Language.lower().startswith((\"auto\", \"none\", \"x\")):\n",
+ "\t\tLanguage = None\n",
+ "\n",
+ "\tif Use_Comma_Fix:\n",
+ "\t\tPrompt_String = commaFix(Prompt_String)\n",
+ "\n",
+ "\tif Language:\n",
+ "\t\tif Language in Languages:\n",
+ "\t\t\tLanguage = IDs[Languages[Language][0]]\n",
+ "\t\telse:\n",
+ "\t\t\traise ValueError(\"Unsupported language\")\n",
+ "\telse:\n",
+ "\t\tPredicted = langid.classify(Prompt_String)[0].strip()\n",
+ "\n",
+ "\t\tif Predicted == \"zh\":\n",
+ "\t\t\tPredicted = \"zh-cn\"\n",
+ "\n",
+ "\t\tif Language != Predicted:\n",
+ "\t\t\tLanguage = Predicted\n",
+ "\n",
+ "\tMaxLen = Languages[Language][1]\n",
+ "\tLanguage_Display = Languages[Language][0]\n",
+ "\n",
+ "\t#-=-=-=-#\n",
+ "\t# Errors\n",
+ "\n",
+ "\tif os.path.basename(Speaker_Path) not in os.listdir(Directory_Inputs):\n",
+ "\t\traise FileNotFoundError(Speaker_Path)\n",
+ "\n",
+ "\tif len(Prompt_String) > MaxLen:\n",
+ "\t\trprint(\"[b #44AAFF]Prompt string length exceeds {}, truncating[/]\")\n",
+ "\t\tPrompt_String = Prompt_String[:MaxLen]\n",
+ "\n",
+ "\tif len(Prompt_String) < Max_Prompt_Display_Length:\n",
+ "\t\tPrompt_Display = f'\"{Prompt_String}\"'\n",
+ "\telse:\n",
+ "\t\tPrompt_Display = f'\"{Prompt_String[:Max_Prompt_Display_Length]}(...)\"'\n",
+ "\n",
+ "\t#-=-=-=-#\n",
+ "\t# Print information\n",
+ "\n",
+ "\tCounter_Display = str(Counter).rjust(len(str(len(Prompts_List))) + 1, \"0\")\n",
+ "\n",
+ "\tprint(f\"{Counter_Display}.\")\n",
+ "\tprint(\" Speaker Name: \", Speaker_Display)\n",
+ "\tprint(\" Language: \", \"{0} ({1} characters limit)\".format(Language_Display, MaxLen))\n",
+ "\tprint(\" Prompt: \", Prompt_Display)\n",
+ "\n",
+ "\t#-=-=-=-#\n",
+ "\t# Setup output file name\n",
+ "\n",
+ "\tif len(Elements) > 3:\n",
+ "\t\toutput_name = Elements[3]\n",
+ "\t\trprint(\" Output Name: \", output_name)\n",
+ "\telse:\n",
+ "\t\toutput_name = re.sub(r\"[,.;@#?!&$]+\\ *\", \"_\", Prompt_String).replace(\"_\", \" \")\n",
+ "\t\toutput_name = output_name.split()\n",
+ "\t\toutput_name = \"_\".join([x for x in output_name if output_name])\n",
+ "\n",
+ "\toutput_name = output_name[:Truncate_Output_Name_After]\n",
+ "\toutput_path = os.path.join(Directory_Outputs, Speaker_Display, output_name + \".wav\")\n",
+ "\toutput_path = os.path.abspath(output_path)\n",
+ "\n",
+ "\toutput_dir = os.path.dirname(output_path)\n",
+ "\n",
+ "\tif not os.path.exists(output_dir):\n",
+ "\t\tos.makedirs(output_dir, exist_ok = True)\n",
+ "\n",
+ "\tif os.path.exists(output_path):\n",
+ "\t\tos.remove(output_path)\n",
+ "\n",
+ "\t# Run\n",
+ "\tif not Length_Reference_Max:\n",
+ "\t\tLength_Reference_Max = round(mFile(Speaker_Path).info.length)\n",
+ "\n",
+ "\ttorch.cuda.empty_cache()\n",
+ "\n",
+ "\t(gpt_cond_latent, speaker_embedding) = model.get_conditioning_latents(\n",
+ "\t\taudio_path = Speaker_Path,\n",
+ "\t\tgpt_cond_len = Length_GPT_Condition,\n",
+ "\t\tgpt_cond_chunk_len = Length_GPT_Condition_Chunk,\n",
+ "\t\tmax_ref_length = Length_Reference_Max\n",
+ "\t)\n",
+ "\n",
+ "\tout = model.inference(\n",
+ "\t\tPrompt_String, Language,\n",
+ "\t\tgpt_cond_latent, speaker_embedding,\n",
+ "\t\trepetition_penalty = Repetition_Penalty,\n",
+ "\t\ttemperature = Temperature,\n",
+ "\t)\n",
+ "\n",
+ "\ttorchaudio.save(\n",
+ "\t\toutput_path,\n",
+ "\t\ttorch.tensor(out[\"wav\"]).unsqueeze(0),\n",
+ "\t\t24000\n",
+ "\t)\n",
+ "\n",
+ "\tif Clear_Colab_console_output_after_each_prompt:\n",
+ "\t\tif Line != Prompts_List[-1]:\n",
+ "\t\t\tclear_output(wait = True)\n",
+ "\telse:\n",
+ "\t\tprint()\n",
+ "\n",
+ "\t\trprint('[b][#44AAFF]\\nSaved to \"{0}\" [#A0A0A0]({1}s) ({2})[/][/]'.format(\n",
+ "\t\t\tos.path.relpath(output_path, Directory_Outputs),\n",
+ "\t\t\tround(mFile(output_path).info.length, 3),\n",
+ "\t\t\tfdb_size(output_path)\n",
+ "\t\t))\n",
+ "\n",
+ "\t\tif Line != Prompts_List[-1]:\n",
+ "\t\t\tprint(\"\\n\" + \"โ\" * 32 + \"\\n\")\n",
+ "\n",
+ "\tCounter += 1\n",
+ "\n",
+ "#-=-=-=-#\n",
+ "\n",
+ "__Run_Time = time() - Runtime\n",
+ "print(\"\\n\" + \"โ\" * 32 + \"\\n\")\n",
+ "rprint(\"[b #00CC00]Done![/]\")\n",
+ "rprint(\"Runtime: [b #44AAFF]{0}[/] [i #A0A0A0](avg. {1} per line)[/]\".format(\n",
+ "\tstr(timedelta(seconds = __Run_Time))[2:-3],\n",
+ "\tstr(timedelta(seconds = __Run_Time / len(Prompts_List)))[2:-3]\n",
+ "))"
+ ],
+ "metadata": {
+ "id": "QCrlHuDDWpB2",
+ "cellView": "form"
+ }
+ },
+ {
+ "cell_type": "markdown",
+ "source": [
+ "# Utils โ๏ธ
"
+ ],
+ "metadata": {
+ "id": "XfDlrVA9Qc1x"
+ }
+ },
+ {
+ "cell_type": "code",
+ "source": [
+ "#@title Convert output files to `FLAC` ๐ถ
\n",
+ "\n",
+ "Bit_Depth = \"24-bit\" #@param [\"16-bit\", \"24-bit\"]\n",
+ "Bit_Depth = Bit_Depth.split(\"-\")[0]\n",
+ "Normalize_dB = 1 # @param {type: \"slider\", min: -6, max: 1, step: 1}\n",
+ "#@markdown > โน๏ธ To **disable** normalization, set `Normalize_dB` to **`1`**.\n",
+ "\n",
+ "#-=-=-=-#\n",
+ "\n",
+ "Target = \"FLAC\"\n",
+ "Target = Target.split()[0].lower().strip(\".\")\n",
+ "\n",
+ "#-=-=-=-#\n",
+ "\n",
+ "os.environ[\"BIT_DEPTH\"] = \"-b \" + Bit_Depth\n",
+ "os.environ[\"NORMALIZE\"] = (\"--norm \" + str(Normalize_dB)) if Normalize_dB < 1 else \"\"\n",
+ "\n",
+ "for File in Path(Directory_Outputs).rglob(\"*.*\"):\n",
+ "\tInput = str(File.resolve())\n",
+ "\n",
+ "\tif os.path.isfile(Input):\n",
+ "\t\tInput_MIME = mFile(Input).mime[0].lower().split(\"/\")\n",
+ "\t\tInput_Name = os.path.relpath(Input, Directory_Outputs)\n",
+ "\n",
+ "\t\tOutput_FLAC = os.path.splitext(Input)[0], f\".{Target.lower()}\"\n",
+ "\t\tOutput_Temp = \"_\".join(Output_FLAC)\n",
+ "\t\tOutput_FLAC = \"\".join(Output_FLAC)\n",
+ "\n",
+ "\t\tos.environ[\"INPUT\"] = Input\n",
+ "\t\tos.environ[\"OUTPUT\"] = Output_Temp\n",
+ "\n",
+ "\t\trprint('[b i]{1}onverting [#44AAFF]\"{0}\"[/] to FLAC...[/]'.format(\n",
+ "\t\t\tInput_Name,\n",
+ "\t\t\t(\"rec\" if Input_MIME[1] == \"flac\" else \"c\").capitalize()\n",
+ "\t\t))\n",
+ "\n",
+ "\t\t!sox \"$INPUT\" -D $BIT_DEPTH -C 8 $NORMALIZE --comment \"\" -G \"$OUTPUT\" -V0\n",
+ "\n",
+ "\t\tos.remove(Input)\n",
+ "\t\tos.rename(Output_Temp, Output_FLAC)"
+ ],
+ "metadata": {
+ "cellView": "form",
+ "id": "nxkupjCJpf5R"
+ }
+ },
+ {
+ "cell_type": "code",
+ "source": [
+ "#@title Download archive with output files ๐๏ธ
\n",
+ "Emphasize_archive_file_name = True #@param {type: \"boolean\"}\n",
+ "Beggining = \"!_\" if Emphasize_archive_file_name else \"\"\n",
+ "\n",
+ "#@markdown > โน๏ธ Pushes the archive file to top of the explorer's file list (**if** it's sorted by name) by putting `!_` to its file name beggining.\n",
+ "\n",
+ "#-=-=-=-#\n",
+ "\n",
+ "__Padding = 7\n",
+ "Archive_File = Beggining + \"_\".join((__title__, str(time()).split(\".\")[1][:__Padding].rjust(__Padding, \"0\")))\n",
+ "Archive_File += \".zip\"\n",
+ "Archive_File = os.path.abspath(Archive_File)\n",
+ "\n",
+ "#-=-=-=-#\n",
+ "\n",
+ "# Archive Creation\n",
+ "print(\"Making Archive...\")\n",
+ "with ZipFile(Archive_File, \"w\", 14, 1, 9) as Archive:\n",
+ "\tfor File in Path(Directory_Outputs).rglob(\"*.*\"):\n",
+ "\t\tFile = str(File.resolve())\n",
+ "\n",
+ "\t\tif os.path.isfile(File):\n",
+ "\t\t\tArcName = os.path.relpath(File, Directory_Outputs)\n",
+ "\n",
+ "\t\t\trprint(f'\\t[b i]Writing [#44AACC]\"{ArcName}\"[/]...')\n",
+ "\t\t\tArchive.write(File, ArcName)\n",
+ "\n",
+ "#-=-=-=-#\n",
+ "\n",
+ "files.download(Archive_File)"
+ ],
+ "metadata": {
+ "cellView": "form",
+ "id": "rpPfi2g7gnTi"
+ }
+ },
+ {
+ "cell_type": "code",
+ "source": [
+ "#@title Terminate runtime after specified time ๐\n",
+ "#@markdown In case if you don't want to waste this account's resources while performing other tasks.\n",
+ "#@markdown > ### **This cancellable action is irreversible and will result in loss of ALL session data!** \n",
+ "\n",
+ "#@markdown \n",
+ "#@markdown \n",
+ "#@markdown Time sheet \n",
+ "#@markdown\n",
+ "#@markdown \n",
+ "#@markdown\n",
+ "#@markdown | Seconds | Minutes |\n",
+ "#@markdown |:-|:-|\n",
+ "#@markdown | `60` | `1` |\n",
+ "#@markdown | `300` | `5` |\n",
+ "#@markdown | `600` | `10` |\n",
+ "#@markdown | `1800` | `30` |\n",
+ "#@markdown | `3600` | `60` |\n",
+ "#@markdown \n",
+ "\n",
+ "#@markdown ---\n",
+ "\n",
+ "Seconds_Default = 30\n",
+ "Seconds = 300 # @param {type: \"integer\"}\n",
+ "\n",
+ "if Seconds < 0:\n",
+ "\trprint(f\"[b][#FFCC00]Seconds are[/] [#FF0000]< 0[/][#FFCC00], defaulting to[/] [#FF0000]{Seconds_Default}[/][#FFCC00].[/][/]\")\n",
+ "\n",
+ "__Spaces = \" \" * 8\n",
+ "\n",
+ "\n",
+ "\n",
+ "if is_colab:\n",
+ "\ttry:\n",
+ "\t\tfor i in range(Seconds, -1, -1):\n",
+ "\t\t\tprint(\"\\r\", end = f\"Runtime will be terminated in {i} seconds...\" + __Spaces)\n",
+ "\n",
+ "\t\trprint(\"\\n\\n[b #FF0000]Runtime has been terminated.[/]\")\n",
+ "\t\truntime.unassign()\n",
+ "\texcept (KeyboardInterrupt, EOFError):\n",
+ "\t\tprint()\n",
+ "\t\trprint(\"[b #FF0000]Operation cancelled by user.[/]\")\n",
+ "else:\n",
+ "\trprint(\"[b #FFCC00]Not in Colab, unsupported.[/]\")"
+ ],
+ "metadata": {
+ "id": "rhKs_AmESZew",
+ "cellView": "form"
+ }
+ }
+ ]
+}
\ No newline at end of file
diff --git a/Notebooks/AI/Audio/_Speech/Clone/Coqui_XTTS/Run.py b/Notebooks/AI/Audio/_Speech/Clone/Coqui_XTTS/Run.py
new file mode 100644
index 0000000..4193b8c
--- /dev/null
+++ b/Notebooks/AI/Audio/_Speech/Clone/Coqui_XTTS/Run.py
@@ -0,0 +1,29 @@
+"""Static version of Coqui XTTS Notebook."""
+__title__ = "Coqui XTTS"
+__author__ = "kubinka0505"
+__date__ = "31st December 2023"
+__title__ = __title__.replace(" ", "_")
+
+#-=-=-=-#
+
+# Does not print information about output file
+Clear_console_output_after_each_prompt = False
+
+# If None, the first found ".txt" file from the current directory is taken
+Prompts_File = "prompts.txt"
+
+Pause_on_finish = False
+
+#-=-=-=-#
+
+exec(open("src/setup_variables.pyw", "r", encoding = "UTF-8").read())
+exec(open("src/setup_prompts.pyw", "r", encoding = "UTF-8").read())
+exec(open("src/setup_tts.pyw", "r", encoding = "UTF-8").read())
+
+__Run_Time_Start = time() - Runtime_Start
+print("Setup took {0}".format(
+ str(timedelta(seconds = __Run_Time_Start))[2:-3])
+)
+
+exec(open("src/setup_runner.pyw", "r", encoding = "UTF-8").read())
+exec(open("src/setup_end.pyw", "r", encoding = "UTF-8").read())
\ No newline at end of file
diff --git a/Notebooks/AI/Audio/_Speech/Clone/Coqui_XTTS/src/setup_end.pyw b/Notebooks/AI/Audio/_Speech/Clone/Coqui_XTTS/src/setup_end.pyw
new file mode 100644
index 0000000..353395f
--- /dev/null
+++ b/Notebooks/AI/Audio/_Speech/Clone/Coqui_XTTS/src/setup_end.pyw
@@ -0,0 +1,5 @@
+print("\a")
+
+if Pause_on_finish:
+ cmd = "pause" if is_NT else 'read -n1 -r -p "Press any key to continue. . ." key'
+ os.system(cmd)
\ No newline at end of file
diff --git a/Notebooks/AI/Audio/_Speech/Clone/Coqui_XTTS/src/setup_prompts.pyw b/Notebooks/AI/Audio/_Speech/Clone/Coqui_XTTS/src/setup_prompts.pyw
new file mode 100644
index 0000000..2f39a97
--- /dev/null
+++ b/Notebooks/AI/Audio/_Speech/Clone/Coqui_XTTS/src/setup_prompts.pyw
@@ -0,0 +1,46 @@
+# Setup prompts
+rprint("[b #00CC00]Retrieving prompts...[/]")
+
+IDs = {v[0]: k for k, v in Languages.items()}
+
+#-=-=-=-#
+
+if Prompts_File:
+ Prompts_File = os.path.abspath(Prompts_File)
+
+ if not os.path.exists(Prompts_File):
+ raise FileNotFoundError(Prompts_File)
+else:
+ Prompts_File = [str(File.resolve()) for File in Path().glob("*.txt")]
+
+ if not Prompts_File:
+ raise FileNotFoundError("No .txt files has been found in the current directory")
+
+ Prompts_File = sorted(Prompts_File, key = os.path.getmtime)[0]
+
+with open(Prompts_File, "r", encoding = "UTF-8") as File:
+ Prompts = File.read()
+
+#-=-=-=-#
+# Old
+
+Prompts_List = Prompts.strip("\n")
+Prompts_List = Prompts_List.split("\n")
+Prompts_List = [Line for Line in Prompts_List if Line]
+__Lines_Old = len(Prompts_List)
+
+# New
+Prompts_List = [Line for Line in Prompts_List if not Line.startswith("#")]
+__Lines_New = len(Prompts_List)
+
+__Ignored = __Lines_Old - __Lines_New
+
+rprint("[b #{0}]Found {1} prompts, {2} {3} ignored.[/]".format(
+ "00CC00" if __Lines_New else "FF0000",
+ __Lines_New, __Ignored,
+ "was" if __Ignored == 1 else "were"
+))
+
+if not Prompts_List:
+ print()
+ raise ValueError("No prompts found.")
\ No newline at end of file
diff --git a/Notebooks/AI/Audio/_Speech/Clone/Coqui_XTTS/src/setup_runner.pyw b/Notebooks/AI/Audio/_Speech/Clone/Coqui_XTTS/src/setup_runner.pyw
new file mode 100644
index 0000000..b1d105e
--- /dev/null
+++ b/Notebooks/AI/Audio/_Speech/Clone/Coqui_XTTS/src/setup_runner.pyw
@@ -0,0 +1,147 @@
+Runtime = time()
+Counter = 1
+
+def commaFix(s: str) -> str:
+ return re.sub("([^\x00-\x7F]|\w)(\.|\ใ|\?)", r"\1 \2\2", s)
+
+#-=-=-=-#
+
+for Line in Prompts_List:
+ Elements = Line.split("|")
+ Elements = [Element.strip() for Element in Elements]
+
+ #-=-=-=-#
+
+ Speaker_Name = Elements[0]
+ Language = Elements[1]
+ Prompt_String = Elements[2]
+
+ Speaker_Path = os.path.join(Directory_Inputs, Speaker_Name) + ".flac"
+ Speaker_Display = os.path.splitext(os.path.basename(Speaker_Path))[0]
+
+ if Language.lower().startswith(("auto", "none", "x")):
+ Language = None
+
+ if Use_Comma_Fix:
+ Prompt_String = commaFix(Prompt_String)
+
+ if Language:
+ if Language in Languages:
+ Language = IDs[Languages[Language][0]]
+ else:
+ raise ValueError("Unsupported language")
+ else:
+ Predicted = langid.classify(Prompt_String)[0].strip()
+
+ if Predicted == "zh":
+ Predicted = "zh-cn"
+
+ if Language != Predicted:
+ Language = Predicted
+
+ MaxLen = Languages[Language][1]
+ Language_Display = Languages[Language][0]
+
+ #-=-=-=-#
+ # Errors
+
+ if os.path.basename(Speaker_Path) not in os.listdir(Directory_Inputs):
+ raise FileNotFoundError(Speaker_Path)
+
+ if len(Prompt_String) > MaxLen:
+ rprint(f"[b #44AAFF]Prompt string length exceeds {MaxLen}, truncating[/]")
+ Prompt_String = Prompt_String[:MaxLen]
+
+ if len(Prompt_String) < Max_Prompt_Display_Length:
+ Prompt_Display = f'"{Prompt_String}"'
+ else:
+ Prompt_Display = f'"{Prompt_String[:Max_Prompt_Display_Length]}(...)"'
+
+ #-=-=-=-#
+ # Print information
+
+ Counter_Display = str(Counter).rjust(len(str(len(Prompts_List))) + 1, "0")
+
+ print(f"{Counter_Display}.")
+ print(" Speaker Name: ", Speaker_Display)
+ print(" Language: ", "{0} ({1} characters limit)".format(Language_Display, MaxLen))
+ print(" Prompt: ", Prompt_Display)
+
+ #-=-=-=-#
+ # Setup output file name
+
+ if len(Elements) > 3:
+ output_name = Elements[3]
+ rprint(" Output Name: ", output_name)
+ else:
+ output_name = re.sub(r"[,.;@#?!&$]+\ *", "_", Prompt_String).replace("_", " ")
+ output_name = output_name.split()
+ output_name = "_".join([x for x in output_name if output_name])
+
+ output_name = output_name[:Truncate_Output_Name_After]
+ output_path = os.path.join(Directory_Outputs, Speaker_Display, output_name + ".wav")
+ output_path = os.path.abspath(output_path)
+
+ output_dir = os.path.dirname(output_path)
+
+ if not os.path.exists(output_dir):
+ os.makedirs(output_dir, exist_ok = True)
+
+ if os.path.exists(output_path):
+ os.remove(output_path)
+
+ # Run
+ if not Length_Reference_Max:
+ Length_Reference_Max = round(mFile(Speaker_Path).info.length)
+
+ torch.cuda.empty_cache()
+
+ #-=-=-=-#
+
+ (gpt_cond_latent, speaker_embedding) = model.get_conditioning_latents(
+ audio_path = Speaker_Path,
+ gpt_cond_len = Length_GPT_Condition,
+ gpt_cond_chunk_len = Length_GPT_Condition_Chunk,
+ max_ref_length = Length_Reference_Max
+ )
+
+ out = model.inference(
+ Prompt_String, Language,
+ gpt_cond_latent, speaker_embedding,
+ repetition_penalty = Repetition_Penalty,
+ temperature = Temperature,
+ )
+
+ torchaudio.save(
+ output_path,
+ torch.tensor(out["wav"]).unsqueeze(0),
+ 24000
+ )
+
+ if Clear_console_output_after_each_prompt:
+ if Line != Prompts_List[-1]:
+ cmd = "cls" if is_NT else "clear"
+ os.system(cmd)
+ else:
+ print()
+
+ rprint('[b][#44AAFF]\nSaved to "{0}" [#A0A0A0]({1}s) ({2})[/][/]'.format(
+ os.path.relpath(output_path, Directory_Main),
+ round(mFile(output_path).info.length, 3),
+ fdb_size(output_path)
+ ))
+
+ if Line != Prompts_List[-1]:
+ print("\n" + "โ" * 32 + "\n")
+
+ Counter += 1
+
+#-=-=-=-#
+
+__Run_Time = time() - Runtime
+print("\n" + "โ" * 32 + "\n")
+rprint("[b #00CC00]Done![/]")
+rprint("Runtime: [b #44AAFF]{0}[/] [i #A0A0A0](avg. {1} per line)[/]".format(
+ str(timedelta(seconds = __Run_Time))[2:-3],
+ str(timedelta(seconds = __Run_Time / len(Prompts_List)))[2:-3]
+))
\ No newline at end of file
diff --git a/Notebooks/AI/Audio/_Speech/Clone/Coqui_XTTS/src/setup_tts.pyw b/Notebooks/AI/Audio/_Speech/Clone/Coqui_XTTS/src/setup_tts.pyw
new file mode 100644
index 0000000..1003c05
--- /dev/null
+++ b/Notebooks/AI/Audio/_Speech/Clone/Coqui_XTTS/src/setup_tts.pyw
@@ -0,0 +1,48 @@
+print()
+rprint("[b #FFCC00]Importing TTS modules...[/]")
+
+from TTS.api import TTS
+from TTS.tts.configs.xtts_config import XttsConfig
+from TTS.tts.models.xtts import Xtts
+from TTS.utils.manage import ModelManager
+from TTS.utils.generic_utils import get_user_data_dir
+
+os.environ["COQUI_TOS_AGREED"] = "1"
+
+#-=-=-=-#
+
+rprint("[b #FFCC00]Retrieving model...[/]")
+
+# Download XTTS
+model_name = "tts_models/multilingual/multi-dataset/xtts_v2"
+model_path = os.path.join(get_user_data_dir("tts"), model_name.replace("/", "--"))
+ckpt_path = os.path.join(model_path, "model.pth")
+
+config_json = os.path.join(model_path, "config.json")
+vocab_json = os.path.join(model_path, "vocab.json")
+
+if not os.path.exists(model_path):
+ # Download model
+ rprint("[b #FFCC00]Downloading model...[/]")
+ ModelManager().download_model(model_name)
+#else:
+# rmtree(model_path)
+
+rprint("[b #FFCC00]Configuring...[/]")
+config = XttsConfig()
+config.load_json(config_json)
+
+# Loading model
+model = Xtts.init_from_config(config)
+model.load_checkpoint(
+ config,
+ checkpoint_path = ckpt_path,
+ vocab_path = vocab_json,
+ eval = True,
+ use_deepspeed = False
+)
+model.cuda()
+
+supported_languages = config.languages
+
+print("\n" + "โ" * 32 + "\n")
\ No newline at end of file
diff --git a/Notebooks/AI/Audio/_Speech/Clone/Coqui_XTTS/src/setup_variables.pyw b/Notebooks/AI/Audio/_Speech/Clone/Coqui_XTTS/src/setup_variables.pyw
new file mode 100644
index 0000000..5242389
--- /dev/null
+++ b/Notebooks/AI/Audio/_Speech/Clone/Coqui_XTTS/src/setup_variables.pyw
@@ -0,0 +1,157 @@
+from time import time
+Runtime_Start = time()
+
+import os
+import re
+import torch
+import langid
+import torchaudio
+from pathlib import Path
+from shutil import rmtree
+from datetime import timedelta
+from rich import print as rprint
+from mutagen import File as mFile
+
+Use_Comma_Fix = True
+Max_Prompt_Display_Length = 75
+Truncate_Output_Name_After = 50
+
+Length_GPT_Condition = 30
+Length_GPT_Condition_Chunk = 4
+Length_Reference_Max = 60
+Repetition_Penalty = 5.0
+Temperature = 0.75
+
+#-=-=-=-#
+
+is_NT = os.sys.platform.lower().startswith("win")
+
+Languages = {
+ #"id": ("long_name", characters_limit),
+ "en": ["English", 250],
+ "es": ["Spanish", 239],
+ "fr": ["French", 273],
+ "de": ["Deutsch", 253],
+ "it": ["Italian", 213],
+ "pt": ["Portuguese", 203],
+ "tr": ["Turkish", 226],
+ "ru": ["Russian", 182],
+ "nl": ["Dutch", 251],
+ "pl": ["Polish", 224],
+ "cs": ["Czech", 186],
+ "ar": ["Arabic", 166],
+ "zh-cn": ["Chinese", 82],
+ "ja": ["Japanese", 71],
+ "ko": ["Korean", 95],
+ "hu": ["Hungarian", 224]
+}
+
+#-=-=-=-#
+# Directories
+
+Directory_Main = os.getcwd()
+Directory_Main = os.path.abspath(Directory_Main)
+Directory_Inputs = os.path.join(Directory_Main, "_inputs")
+Directory_Outputs = os.path.join(Directory_Main, "_outputs")
+
+for Directory in Directory_Inputs, Directory_Outputs:
+ os.makedirs(Directory, exist_ok = True)
+
+#-=-=-=-#
+
+def fdb_size(obj: str, extended_units: bool = False, bits: bool = False, recursive: bool = False) -> str:
+ """
+ Args:
+ obj: Bytes integer or string path of existing file or directory.
+ extended_units: Extends the unit of the result, i.e. "Megabytes" instead of "MB".
+ bits: Uses decimal divider (1000) instead of binary one. (1024)
+ recursive: Iterate subdirectories, applicable only if `obj` is directory. (slow!)
+
+ Returns:
+ Human-readable files size string.
+ """
+ # Setup
+
+ if bits:
+ Bits = 1000
+ Bits_Display_Single = "bit"
+ Bits_Display_Multiple = "bits"
+ else:
+ Bits = 1024
+ Bits_Display_Single = "byte"
+ Bits_Display_Multiple = "bytes"
+
+ Units = {
+ "": "",
+ "K": "kilo",
+ "M": "mega",
+ "G": "giga",
+ "T": "tera",
+ "P": "peta",
+ "E": "exa",
+ "Z": "zetta",
+ "Y": "yotta",
+ "R": "ronna",
+ "Q": "quetta"
+ }
+
+ #-=-=-=-#
+ # Search for files
+
+ if isinstance(obj, str):
+ path = str(Path(obj).resolve())
+
+ if not os.path.exists(path):
+ raise FileNotFoundError(path)
+
+ if os.path.isfile(obj):
+ Files = [obj]
+ else:
+ Wildcard = "*"
+ if recursive:
+ Wildcard += "*/*"
+ Files = list(Path(obj).glob(Wildcard))
+ for File in Files:
+ Files[Files.index(File)] = str(File.resolve())
+
+ Files = map(os.path.getsize, Files)
+ Bytes = sum(Files)
+ else:
+ Bytes = obj
+
+ #-=-=-=-#
+ # Calculate integer
+
+ for Unit in Units:
+ if Bytes < Bits:
+ break
+ Bytes /= Bits
+
+ #-=-=-=-#
+ # Ending conditions
+
+ if extended_units:
+ if Bytes == 1:
+ Bits_Display = Bits_Display_Single
+ else:
+ Bits_Display = Bits_Display_Multiple
+ Unit = (Units[Unit] + Bits_Display).capitalize()
+ else:
+ Unit += "B"
+
+ #-=-=-=-#
+ # Add zero to integer
+
+ if "." in str(Bytes):
+ Bytes = round(Bytes, 2)
+ Bytes = str(Bytes).split(".")
+ Bytes[1] = Bytes[1][:2]
+ Bytes[1] = Bytes[1].ljust(2, "0")
+ Bytes = ".".join(Bytes)
+
+ Bytes = str(Bytes)
+
+ #-=-=-=-#
+ # Return string
+
+ return " ".join((Bytes, Unit))
\ No newline at end of file
diff --git a/Notebooks/AI/Visual/Generate/Stable-Diffusion-WebUI/Config/config.json b/Notebooks/AI/Visual/Generate/Stable-Diffusion-WebUI/Config/config.json
new file mode 100644
index 0000000..b706c0a
--- /dev/null
+++ b/Notebooks/AI/Visual/Generate/Stable-Diffusion-WebUI/Config/config.json
@@ -0,0 +1,155 @@
+{
+ "samples_save": true,
+ "samples_format": "jpg",
+ "samples_filename_pattern": "",
+ "save_images_add_number": true,
+ "grid_save": true,
+ "grid_format": "jpg",
+ "grid_extended_filename": true,
+ "grid_only_if_multiple": true,
+ "grid_prevent_empty_spots": false,
+ "n_rows": -1,
+ "enable_pnginfo": true,
+ "save_txt": false,
+ "save_images_before_face_restoration": false,
+ "jpeg_quality": 100,
+ "export_for_4chan": false,
+ "use_original_name_batch": false,
+ "save_selected_only": true,
+ "do_not_add_watermark": true,
+ "outdir_samples": "",
+ "outdir_txt2img_samples": "outputs/txt2img-images",
+ "outdir_img2img_samples": "outputs/img2img-images",
+ "outdir_extras_samples": "outputs/extras-images",
+ "outdir_grids": "",
+ "outdir_txt2img_grids": "outputs/txt2img-grids",
+ "outdir_img2img_grids": "outputs/img2img-grids",
+ "outdir_save": "log/images",
+ "save_to_dirs": false,
+ "grid_save_to_dirs": false,
+ "use_save_to_dirs_for_ui": false,
+ "directories_filename_pattern": "",
+ "directories_max_prompt_words": 8,
+ "ESRGAN_tile": 192,
+ "ESRGAN_tile_overlap": 8,
+ "realesrgan_enabled_models": [
+ "R-ESRGAN x4+",
+ "R-ESRGAN x4+ Anime6B",
+ "R-ESRGAN General 4xV3",
+ "R-ESRGAN AnimeVideo",
+ "R-ESRGAN 4x+",
+ "R-ESRGAN 4x+ Anime6B",
+ "R-ESRGAN General WDN 4xV3",
+ "R-ESRGAN 2x+"
+ ],
+ "SWIN_tile": 192,
+ "SWIN_tile_overlap": 8,
+ "ldsr_steps": 100,
+ "upscaler_for_img2img": "R-ESRGAN General 4xV3",
+ "use_scale_latent_for_hires_fix": false,
+ "face_restoration_model": "GFPGAN",
+ "code_former_weight": 0.5,
+ "face_restoration_unload": false,
+ "memmon_poll_rate": 4,
+ "samples_log_stdout": false,
+ "multiple_tqdm": true,
+ "unload_models_when_training": false,
+ "dataset_filename_word_regex": "",
+ "dataset_filename_join_string": " ",
+ "training_image_repeats_per_epoch": 1,
+ "training_write_csv_every": 500.0,
+ "sd_model_checkpoint": null,
+ "sd_checkpoint_cache": 0,
+ "sd_hypernetwork": "None",
+ "sd_hypernetwork_strength": 1,
+ "img2img_color_correction": false,
+ "save_images_before_color_correction": false,
+ "img2img_fix_steps": false,
+ "enable_quantization": false,
+ "enable_emphasis": true,
+ "use_old_emphasis_implementation": false,
+ "enable_batch_seeds": true,
+ "comma_padding_backtrack": 20,
+ "filter_nsfw": false,
+ "CLIP_stop_at_last_layers": 1,
+ "random_artist_categories": [],
+ "interrogate_keep_models_in_memory": false,
+ "interrogate_use_builtin_artists": true,
+ "interrogate_return_ranks": false,
+ "interrogate_clip_num_beams": 1,
+ "interrogate_clip_min_length": 24,
+ "interrogate_clip_max_length": 48,
+ "interrogate_clip_dict_limit": 1500.0,
+ "interrogate_deepbooru_score_threshold": 0.5,
+ "deepbooru_sort_alpha": true,
+ "deepbooru_use_spaces": false,
+ "deepbooru_escape": true,
+ "show_progressbar": true,
+ "show_progress_every_n_steps": 0,
+ "show_progress_grid": true,
+ "return_grid": false,
+ "do_not_show_images": false,
+ "add_model_hash_to_info": true,
+ "add_model_name_to_info": false,
+ "disable_weights_auto_swap": false,
+ "font": "",
+ "js_modal_lightbox": true,
+ "js_modal_lightbox_initially_zoomed": true,
+ "show_progress_in_title": true,
+ "quicksettings": "sd_model_checkpoint",
+ "localization": "None",
+ "hide_samplers": [],
+ "eta_ddim": 0,
+ "eta_ancestral": 1,
+ "ddim_discretize": "uniform",
+ "s_churn": 0,
+ "s_tmin": 0,
+ "s_noise": 1,
+ "eta_noise_seed_delta": 0,
+ "training_xattention_optimizations": false,
+ "inpainting_mask_weight": 1,
+ "send_seed": true,
+ "ais_exif_pnginfo_group": [
+ "aesthetic_score",
+ "cfg_scale",
+ "sampler",
+ "sd_model_hash",
+ "seed",
+ "hash"
+ ],
+ "ais_windows_tag_group": [
+ "aesthetic_score",
+ "sampler",
+ "cfg_scale",
+ "seed",
+ "sd_model_hash",
+ "hash"
+ ],
+ "ais_windows_category_group": [
+ "aesthetic_score",
+ "cfg_scale",
+ "sampler",
+ "sd_model_hash",
+ "seed",
+ "hash"
+ ],
+ "ais_generation_params_text_group": [
+ "aesthetic_score",
+ "sampler",
+ "cfg_scale",
+ "seed",
+ "sd_model_hash",
+ "hash"
+ ],
+ "ais_force_cpu": false,
+ "images_history_preload": false,
+ "images_history_page_columns": 6.0,
+ "images_history_page_rows": 6.0,
+ "images_history_pages_perload": 20.0,
+ "inspiration_max_samples": 4,
+ "inspiration_rows_num": 4,
+ "inspiration_cols_num": 6,
+ "save_images_before_highres_fix": false,
+ "save_optimizer_state": false,
+ "sd_vae": "auto"
+}
\ No newline at end of file
diff --git a/Notebooks/AI/Visual/Generate/Stable-Diffusion-WebUI/Config/styles.csv b/Notebooks/AI/Visual/Generate/Stable-Diffusion-WebUI/Config/styles.csv
new file mode 100644
index 0000000..6371f41
--- /dev/null
+++ b/Notebooks/AI/Visual/Generate/Stable-Diffusion-WebUI/Config/styles.csv
@@ -0,0 +1,74 @@
+๏ปฟname,prompt,negative_prompt
+None,,,
+DEFAULT: Positive,"(masterpiece: 2.0), YOUR_PROMPT_HERE,
+best quality, highest quality, high quality,
+ultra-detailed, highly detailed,
+hyperrealistic, realistic",
+DEFAULT: Negative,,"text, extra digits, fewer digits,
+(bad proportions: 2.0), (bad anatomy: 2.0),
+(deformed face: 2.0), (poorly drawn face: 1.0),
+(bad hands: 2.0), (bad fingers: 2.5), (missing finger: 1.0), (mutated hands and fingers: 2.0),
+cropped, blurry, low resolution, lowres,
+normal quality, low quality, worst quality,
+jpeg, (jpeg artifacts: 2.0), (jpg artifacts: 2.0)"
+GENERAL: Art,"portrait, illustration, (cinematic: 1.5),",
+ARTIST: Claude Monet,"(Claude Monet painting: 2.0), (painting: 1.5),
+(impressionism: 1.0), (modernism: 1.0)
+
+a bit of abstraction,
+
+(Barbizon school art: 0.75),
+(Alfred Sisley: 0.75),
+(Auguste Renoir: 0.75),
+(Jean Frederic Bazille: 0.75),
+(Johan Barthold Jongkind: 0.75),
+(William Turner: 0.75),
+(John Constable: 0.75)",
+ARTIST: Gustav Klimt,"(Gustav Klimt painting: 2.0), (painting: 1.5),
+(modernism: 0.25), (symbolism: 0.25), (modernism: 1.0),
+(Japanese art: 0.25), (Chinese art: 0.25), (Ancient Egyptian art: 0.25), (Mycenaean art: 0.25),
+
+(Egon Schiele art: 0.75),
+(Courtney Adams art: 0.75),
+(Fletcher Sibthorp art: 0.75),
+(Kimon Loghi art: 0.75),
+(Kevin Wasden art: 0.75),
+(Nagura Hiroo art: 0.75)",
+ARTIST: Leonardo Da Vinci,"(Leonardo da Vinci painting: 2.0), (painting: 1.5),
+(renessaince art: 1.0), italian art),
+
+(sharp contours: 1.0), (sfumato: 1.0), (chiaroscuro: 1.0), (aria restretta: 1.0), (lumo libero: 1.0), (3d perspective: 1.0),
+(flemish painters: 0.25), (venetian painters: 0.5),
+
+(Michelangelo art: 0.5), (Rafael Santi art: 0.25)",
+ARTIST: Michelangelo,"(Michelangelo frescoes: 2.0),
+(renessaince art: 1.0), (italian art: 0.5), (biblical art: 0.75), (symbolism: 0.25),
+
+(Leonardo da Vinci art: 0.5), (Rafael Santi art: 0.25)",
+ARTIST: Pablo Picasso,"(Pablo Picasso painting: 2.0),
+(postimpressionism: 1.0), (symbolism: 1.0), (surrealism: 1.0), (modernism: 1.0),
+(analytical cubism: 0.5), (synthetical cubism: 0.5),
+
+(abstract work: 0.5), (geometrical shapes: 0.5), (layers: 0.5),
+
+(Iberian art: 0.25), (African art: 0.25),
+(Paulo Cezanne art: 0.5),
+(Henri de Toulouse-Lautrec art: 0.5),
+(Georges Braque art: 0.5)",
+ARTIST: Rembrandt,"(Rembrandt painting: 2.0),
+(Baroque art: 0.25), (biblical art: 0.75),
+(Dutch Golden Age art: 0.5),
+
+(light effects: 0.5), (deep shadows: 0.25),
+
+(Caravaggio art: 0.5),
+(Carel Fabritius art: 0.5),
+(Pieter de Hooch art: 0.5),
+(Vincent van Gogh art: 0.25)",
+ARTIST: Vincent van Gogh,"(Vincent van Gogh painting: 2.0),
+(postimpressionism: 1.0), (neoimpressionism: 1.0), (pointilism: 0.75), (japonaiserie: 0.25),
+
+(oil on canvas: 1.5),
+(impasto: 0.25), (brushstokes of thickly laid-on paint: 1.0), (spiraling movements: 1.5),
+
+(Jean-Francois Millet art: 0.25)",
\ No newline at end of file
diff --git a/Notebooks/AI/Visual/Generate/Stable-Diffusion-WebUI/Config/ui-config.json b/Notebooks/AI/Visual/Generate/Stable-Diffusion-WebUI/Config/ui-config.json
new file mode 100644
index 0000000..9b14b5d
--- /dev/null
+++ b/Notebooks/AI/Visual/Generate/Stable-Diffusion-WebUI/Config/ui-config.json
@@ -0,0 +1,677 @@
+{
+ "txt2img/Prompt/visible": true,
+ "txt2img/Prompt/value": "",
+ "txt2img/Negative prompt/visible": true,
+ "txt2img/Negative prompt/value": "",
+ "txt2img/Style 1/value": "DEFAULT: Positive",
+ "txt2img/Style 1/visible": true,
+ "txt2img/Style 2/value": "DEFAULT: Negative",
+ "txt2img/Style 2/visible": true,
+ "txt2img/Sampling Steps/visible": true,
+ "txt2img/Sampling Steps/value": 25,
+ "txt2img/Sampling Steps/minimum": 1,
+ "txt2img/Sampling Steps/maximum": 150,
+ "txt2img/Sampling Steps/step": 1,
+ "txt2img/Sampling method/visible": true,
+ "txt2img/Sampling method/value": "DPM2 Karras",
+ "txt2img/Width/visible": true,
+ "txt2img/Width/value": 640,
+ "txt2img/Width/minimum": 64,
+ "txt2img/Width/maximum": 2048,
+ "txt2img/Width/step": 64,
+ "txt2img/Height/visible": true,
+ "txt2img/Height/value": 640,
+ "txt2img/Height/minimum": 64,
+ "txt2img/Height/maximum": 2048,
+ "txt2img/Height/step": 64,
+ "txt2img/Restore faces/visible": true,
+ "txt2img/Restore faces/value": true,
+ "txt2img/Tiling/visible": true,
+ "txt2img/Tiling/value": false,
+ "txt2img/Highres. fix/visible": true,
+ "txt2img/Highres. fix/value": false,
+ "txt2img/Firstpass width/visible": true,
+ "txt2img/Firstpass width/value": 0,
+ "txt2img/Firstpass width/minimum": 0,
+ "txt2img/Firstpass width/maximum": 1024,
+ "txt2img/Firstpass width/step": 64,
+ "txt2img/Firstpass height/visible": true,
+ "txt2img/Firstpass height/value": 0,
+ "txt2img/Firstpass height/minimum": 0,
+ "txt2img/Firstpass height/maximum": 1024,
+ "txt2img/Firstpass height/step": 64,
+ "txt2img/Denoising strength/visible": true,
+ "txt2img/Denoising strength/value": 0.6,
+ "txt2img/Denoising strength/minimum": 0.0,
+ "txt2img/Denoising strength/maximum": 1.0,
+ "txt2img/Denoising strength/step": 0.01,
+ "txt2img/Batch count/visible": true,
+ "txt2img/Batch count/value": 4,
+ "txt2img/Batch count/minimum": 1,
+ "txt2img/Batch count/maximum": 100,
+ "txt2img/Batch count/step": 1,
+ "txt2img/Batch size/visible": true,
+ "txt2img/Batch size/value": 1,
+ "txt2img/Batch size/minimum": 1,
+ "txt2img/Batch size/maximum": 8,
+ "txt2img/Batch size/step": 1,
+ "txt2img/CFG Scale/visible": true,
+ "txt2img/CFG Scale/value": 7.5,
+ "txt2img/CFG Scale/minimum": 1.0,
+ "txt2img/CFG Scale/maximum": 30.0,
+ "txt2img/CFG Scale/step": 0.5,
+ "txt2img/Seed/visible": true,
+ "txt2img/Seed/value": -1.0,
+ "txt2img/Extra/visible": true,
+ "txt2img/Extra/value": false,
+ "txt2img/Variation seed/visible": true,
+ "txt2img/Variation seed/value": -1.0,
+ "txt2img/Variation strength/visible": true,
+ "txt2img/Variation strength/value": 0.0,
+ "txt2img/Variation strength/minimum": 0,
+ "txt2img/Variation strength/maximum": 1,
+ "txt2img/Variation strength/step": 0.01,
+ "txt2img/Resize seed from width/visible": true,
+ "txt2img/Resize seed from width/value": 0,
+ "txt2img/Resize seed from width/minimum": 0,
+ "txt2img/Resize seed from width/maximum": 2048,
+ "txt2img/Resize seed from width/step": 64,
+ "txt2img/Resize seed from height/visible": true,
+ "txt2img/Resize seed from height/value": 0,
+ "txt2img/Resize seed from height/minimum": 0,
+ "txt2img/Resize seed from height/maximum": 2048,
+ "txt2img/Resize seed from height/step": 64,
+ "txt2img/Script/value": "None",
+ "txt2img/Script/visible": true,
+ "customscript/custom_code.py/txt2img/Python code/value": "",
+ "customscript/prompt_matrix.py/txt2img/Put variable parts at start of prompt/value": false,
+ "customscript/prompts_from_file.py/txt2img/Iterate seed every line/value": false,
+ "customscript/prompts_from_file.py/txt2img/List of prompt inputs/value": "",
+ "customscript/xy_grid.py/txt2img/X values/value": "",
+ "customscript/xy_grid.py/txt2img/Y values/value": "",
+ "customscript/xy_grid.py/txt2img/Draw legend/value": true,
+ "customscript/xy_grid.py/txt2img/Include Separate Images/value": false,
+ "customscript/xy_grid.py/txt2img/Keep -1 for seeds/value": false,
+ "txt2img/Make Zip when Save?/visible": true,
+ "txt2img/Make Zip when Save?/value": true,
+ "img2img/Prompt/visible": true,
+ "img2img/Prompt/value": "",
+ "img2img/Negative prompt/visible": true,
+ "img2img/Negative prompt/value": "",
+ "img2img/Style 1/value": "None",
+ "img2img/Style 1/visible": true,
+ "img2img/Style 2/value": "None",
+ "img2img/Style 2/visible": true,
+ "img2img/Mask blur/visible": true,
+ "img2img/Mask blur/value": 4,
+ "img2img/Mask blur/minimum": 0,
+ "img2img/Mask blur/maximum": 64,
+ "img2img/Mask blur/step": 1,
+ "img2img/Mask mode/visible": true,
+ "img2img/Mask mode/value": "Draw mask",
+ "img2img/Masking mode/visible": true,
+ "img2img/Masking mode/value": "Inpaint masked",
+ "img2img/Masked content/visible": true,
+ "img2img/Masked content/value": "original",
+ "img2img/Inpaint at full resolution/visible": true,
+ "img2img/Inpaint at full resolution/value": true,
+ "img2img/Inpaint at full resolution padding, pixels/visible": true,
+ "img2img/Inpaint at full resolution padding, pixels/value": 32,
+ "img2img/Inpaint at full resolution padding, pixels/minimum": 0,
+ "img2img/Inpaint at full resolution padding, pixels/maximum": 256,
+ "img2img/Inpaint at full resolution padding, pixels/step": 4,
+ "img2img/Input directory/visible": true,
+ "img2img/Input directory/value": "",
+ "img2img/Output directory/visible": true,
+ "img2img/Output directory/value": "",
+ "img2img/Resize mode/visible": true,
+ "img2img/Resize mode/value": "Just resize",
+ "img2img/Sampling Steps/visible": true,
+ "img2img/Sampling Steps/value": 30,
+ "img2img/Sampling Steps/minimum": 1,
+ "img2img/Sampling Steps/maximum": 150,
+ "img2img/Sampling Steps/step": 1,
+ "img2img/Sampling method/visible": true,
+ "img2img/Sampling method/value": "DDIM",
+ "img2img/Width/visible": true,
+ "img2img/Width/value": 512,
+ "img2img/Width/minimum": 64,
+ "img2img/Width/maximum": 2048,
+ "img2img/Width/step": 64,
+ "img2img/Height/visible": true,
+ "img2img/Height/value": 512,
+ "img2img/Height/minimum": 64,
+ "img2img/Height/maximum": 2048,
+ "img2img/Height/step": 64,
+ "img2img/Restore faces/visible": true,
+ "img2img/Restore faces/value": true,
+ "img2img/Tiling/visible": true,
+ "img2img/Tiling/value": false,
+ "img2img/Batch count/visible": true,
+ "img2img/Batch count/value": 3,
+ "img2img/Batch count/minimum": 1,
+ "img2img/Batch count/maximum": 100,
+ "img2img/Batch count/step": 1,
+ "img2img/Batch size/visible": true,
+ "img2img/Batch size/value": 1,
+ "img2img/Batch size/minimum": 1,
+ "img2img/Batch size/maximum": 8,
+ "img2img/Batch size/step": 1,
+ "img2img/CFG Scale/visible": true,
+ "img2img/CFG Scale/value": 12.5,
+ "img2img/CFG Scale/minimum": 1.0,
+ "img2img/CFG Scale/maximum": 30.0,
+ "img2img/CFG Scale/step": 0.5,
+ "img2img/Denoising strength/visible": true,
+ "img2img/Denoising strength/value": 0.75,
+ "img2img/Denoising strength/minimum": 0.0,
+ "img2img/Denoising strength/maximum": 1.0,
+ "img2img/Denoising strength/step": 0.01,
+ "img2img/Seed/visible": true,
+ "img2img/Seed/value": -1.0,
+ "img2img/Extra/visible": true,
+ "img2img/Extra/value": false,
+ "img2img/Variation seed/visible": true,
+ "img2img/Variation seed/value": -1.0,
+ "img2img/Variation strength/visible": true,
+ "img2img/Variation strength/value": 0.0,
+ "img2img/Variation strength/minimum": 0,
+ "img2img/Variation strength/maximum": 1,
+ "img2img/Variation strength/step": 0.01,
+ "img2img/Resize seed from width/visible": true,
+ "img2img/Resize seed from width/value": 0,
+ "img2img/Resize seed from width/minimum": 0,
+ "img2img/Resize seed from width/maximum": 2048,
+ "img2img/Resize seed from width/step": 64,
+ "img2img/Resize seed from height/visible": true,
+ "img2img/Resize seed from height/value": 0,
+ "img2img/Resize seed from height/minimum": 0,
+ "img2img/Resize seed from height/maximum": 2048,
+ "img2img/Resize seed from height/step": 64,
+ "img2img/Script/value": "None",
+ "img2img/Script/visible": true,
+ "customscript/custom_code.py/img2img/Python code/value": "",
+ "customscript/img2imgalt.py/img2img/Override `Sampling method` to Euler?(this method is built for it)/value": true,
+ "customscript/img2imgalt.py/img2img/Override `prompt` to the same value as `original prompt`?(and `negative prompt`)/value": true,
+ "customscript/img2imgalt.py/img2img/Original prompt/value": "",
+ "customscript/img2imgalt.py/img2img/Original negative prompt/value": "",
+ "customscript/img2imgalt.py/img2img/Override `Sampling Steps` to the same value as `Decode steps`?/value": true,
+ "customscript/img2imgalt.py/img2img/Decode steps/value": 50,
+ "customscript/img2imgalt.py/img2img/Decode steps/minimum": 1,
+ "customscript/img2imgalt.py/img2img/Decode steps/maximum": 150,
+ "customscript/img2imgalt.py/img2img/Decode steps/step": 1,
+ "customscript/img2imgalt.py/img2img/Override `Denoising strength` to 1?/value": true,
+ "customscript/img2imgalt.py/img2img/Decode CFG scale/value": 7.5,
+ "customscript/img2imgalt.py/img2img/Decode CFG scale/minimum": 0.0,
+ "customscript/img2imgalt.py/img2img/Decode CFG scale/maximum": 15.0,
+ "customscript/img2imgalt.py/img2img/Decode CFG scale/step": 0.1,
+ "customscript/img2imgalt.py/img2img/Randomness/value": 0.0,
+ "customscript/img2imgalt.py/img2img/Randomness/minimum": 0.0,
+ "customscript/img2imgalt.py/img2img/Randomness/maximum": 1.0,
+ "customscript/img2imgalt.py/img2img/Randomness/step": 0.01,
+ "customscript/img2imgalt.py/img2img/Sigma adjustment for finding noise for image/value": false,
+ "customscript/loopback.py/img2img/Loops/value": 4,
+ "customscript/loopback.py/img2img/Loops/minimum": 1,
+ "customscript/loopback.py/img2img/Loops/maximum": 32,
+ "customscript/loopback.py/img2img/Loops/step": 1,
+ "customscript/loopback.py/img2img/Denoising strength change factor/value": 1,
+ "customscript/loopback.py/img2img/Denoising strength change factor/minimum": 0.9,
+ "customscript/loopback.py/img2img/Denoising strength change factor/maximum": 1.1,
+ "customscript/loopback.py/img2img/Denoising strength change factor/step": 0.01,
+ "customscript/outpainting_mk_2.py/img2img/Pixels to expand/value": 128,
+ "customscript/outpainting_mk_2.py/img2img/Pixels to expand/minimum": 8,
+ "customscript/outpainting_mk_2.py/img2img/Pixels to expand/maximum": 256,
+ "customscript/outpainting_mk_2.py/img2img/Pixels to expand/step": 8,
+ "customscript/outpainting_mk_2.py/img2img/Mask blur/value": 8,
+ "customscript/outpainting_mk_2.py/img2img/Mask blur/minimum": 0,
+ "customscript/outpainting_mk_2.py/img2img/Mask blur/maximum": 64,
+ "customscript/outpainting_mk_2.py/img2img/Mask blur/step": 1,
+ "customscript/outpainting_mk_2.py/img2img/Fall-off exponent (lower=higher detail)/value": 1.0,
+ "customscript/outpainting_mk_2.py/img2img/Fall-off exponent (lower=higher detail)/minimum": 0.0,
+ "customscript/outpainting_mk_2.py/img2img/Fall-off exponent (lower=higher detail)/maximum": 4.0,
+ "customscript/outpainting_mk_2.py/img2img/Fall-off exponent (lower=higher detail)/step": 0.01,
+ "customscript/outpainting_mk_2.py/img2img/Color variation/value": 0.05,
+ "customscript/outpainting_mk_2.py/img2img/Color variation/minimum": 0.0,
+ "customscript/outpainting_mk_2.py/img2img/Color variation/maximum": 1.0,
+ "customscript/outpainting_mk_2.py/img2img/Color variation/step": 0.01,
+ "customscript/poor_mans_outpainting.py/img2img/Pixels to expand/value": 128,
+ "customscript/poor_mans_outpainting.py/img2img/Pixels to expand/minimum": 8,
+ "customscript/poor_mans_outpainting.py/img2img/Pixels to expand/maximum": 256,
+ "customscript/poor_mans_outpainting.py/img2img/Pixels to expand/step": 8,
+ "customscript/poor_mans_outpainting.py/img2img/Mask blur/value": 4,
+ "customscript/poor_mans_outpainting.py/img2img/Mask blur/minimum": 0,
+ "customscript/poor_mans_outpainting.py/img2img/Mask blur/maximum": 64,
+ "customscript/poor_mans_outpainting.py/img2img/Mask blur/step": 1,
+ "customscript/poor_mans_outpainting.py/img2img/Masked content/value": "fill",
+ "customscript/prompt_matrix.py/img2img/Put variable parts at start of prompt/value": false,
+ "customscript/prompts_from_file.py/img2img/Iterate seed every line/value": false,
+ "customscript/prompts_from_file.py/img2img/List of prompt inputs/value": "",
+ "customscript/sd_upscale.py/img2img/Tile overlap/value": 64,
+ "customscript/sd_upscale.py/img2img/Tile overlap/minimum": 0,
+ "customscript/sd_upscale.py/img2img/Tile overlap/maximum": 256,
+ "customscript/sd_upscale.py/img2img/Tile overlap/step": 16,
+ "customscript/sd_upscale.py/img2img/Upscaler/value": "None",
+ "customscript/xy_grid.py/img2img/X values/value": "",
+ "customscript/xy_grid.py/img2img/Y values/value": "",
+ "customscript/xy_grid.py/img2img/Draw legend/value": true,
+ "customscript/xy_grid.py/img2img/Include Separate Images/value": false,
+ "customscript/xy_grid.py/img2img/Keep -1 for seeds/value": false,
+ "img2img/Make Zip when Save?/visible": true,
+ "img2img/Make Zip when Save?/value": true,
+ "extras/Input directory/visible": true,
+ "extras/Input directory/value": "",
+ "extras/Output directory/visible": true,
+ "extras/Output directory/value": "",
+ "extras/Show result images/visible": true,
+ "extras/Show result images/value": true,
+ "extras/Resize/visible": true,
+ "extras/Resize/value": 2,
+ "extras/Resize/minimum": 1.0,
+ "extras/Resize/maximum": 4.0,
+ "extras/Resize/step": 0.05,
+ "extras/Width/visible": true,
+ "extras/Width/value": 1024,
+ "extras/Height/visible": true,
+ "extras/Height/value": 1024,
+ "extras/Crop to fit/visible": true,
+ "extras/Crop to fit/value": false,
+ "extras/Upscaler 1/visible": true,
+ "extras/Upscaler 1/value": "R-ESRGAN General WDN 4xV3",
+ "extras/Upscaler 2/visible": true,
+ "extras/Upscaler 2/value": "R-ESRGAN General 4xV3",
+ "extras/Upscaler 2 visibility/visible": true,
+ "extras/Upscaler 2 visibility/value": 0.0,
+ "extras/Upscaler 2 visibility/minimum": 0.0,
+ "extras/Upscaler 2 visibility/maximum": 1.0,
+ "extras/Upscaler 2 visibility/step": 0.001,
+ "extras/GFPGAN visibility/visible": true,
+ "extras/GFPGAN visibility/value": 0.0,
+ "extras/GFPGAN visibility/minimum": 0.0,
+ "extras/GFPGAN visibility/maximum": 1.0,
+ "extras/GFPGAN visibility/step": 0.001,
+ "extras/CodeFormer visibility/visible": true,
+ "extras/CodeFormer visibility/value": 0,
+ "extras/CodeFormer visibility/minimum": 0.0,
+ "extras/CodeFormer visibility/maximum": 1.0,
+ "extras/CodeFormer visibility/step": 0.001,
+ "extras/CodeFormer weight (0 = maximum effect, 1 = minimum effect)/visible": true,
+ "extras/CodeFormer weight (0 = maximum effect, 1 = minimum effect)/value": 0,
+ "extras/CodeFormer weight (0 = maximum effect, 1 = minimum effect)/minimum": 0.0,
+ "extras/CodeFormer weight (0 = maximum effect, 1 = minimum effect)/maximum": 1.0,
+ "extras/CodeFormer weight (0 = maximum effect, 1 = minimum effect)/step": 0.001,
+ "extras/Upscale Before Restoring Faces/visible": true,
+ "extras/Upscale Before Restoring Faces/value": true,
+ "modelmerger/Custom Name (Optional)/visible": true,
+ "modelmerger/Custom Name (Optional)/value": "",
+ "modelmerger/Multiplier (M) - set to 0 to get model A/visible": true,
+ "modelmerger/Multiplier (M) - set to 0 to get model A/value": 0.3,
+ "modelmerger/Multiplier (M) - set to 0 to get model A/minimum": 0.0,
+ "modelmerger/Multiplier (M) - set to 0 to get model A/maximum": 1.0,
+ "modelmerger/Multiplier (M) - set to 0 to get model A/step": 0.05,
+ "modelmerger/Interpolation Method/visible": true,
+ "modelmerger/Interpolation Method/value": "Weighted sum",
+ "modelmerger/Save as float16/visible": true,
+ "modelmerger/Save as float16/value": false,
+ "customscript/aesthetic.py/txt2img/Aesthetic weight/visible": true,
+ "customscript/aesthetic.py/txt2img/Aesthetic weight/value": 0.9,
+ "customscript/aesthetic.py/txt2img/Aesthetic weight/minimum": 0,
+ "customscript/aesthetic.py/txt2img/Aesthetic weight/maximum": 1,
+ "customscript/aesthetic.py/txt2img/Aesthetic weight/step": 0.01,
+ "customscript/aesthetic.py/txt2img/Aesthetic steps/visible": true,
+ "customscript/aesthetic.py/txt2img/Aesthetic steps/value": 15,
+ "customscript/aesthetic.py/txt2img/Aesthetic steps/minimum": 0,
+ "customscript/aesthetic.py/txt2img/Aesthetic steps/maximum": 50,
+ "customscript/aesthetic.py/txt2img/Aesthetic steps/step": 1,
+ "customscript/aesthetic.py/txt2img/Aesthetic learning rate/visible": true,
+ "customscript/aesthetic.py/txt2img/Aesthetic learning rate/value": "0.0001",
+ "customscript/aesthetic.py/txt2img/Slerp interpolation/visible": true,
+ "customscript/aesthetic.py/txt2img/Slerp interpolation/value": false,
+ "customscript/aesthetic.py/txt2img/Aesthetic text for imgs/visible": true,
+ "customscript/aesthetic.py/txt2img/Aesthetic text for imgs/value": "",
+ "customscript/aesthetic.py/txt2img/Slerp angle/visible": true,
+ "customscript/aesthetic.py/txt2img/Slerp angle/value": 0.1,
+ "customscript/aesthetic.py/txt2img/Slerp angle/minimum": 0,
+ "customscript/aesthetic.py/txt2img/Slerp angle/maximum": 1,
+ "customscript/aesthetic.py/txt2img/Slerp angle/step": 0.01,
+ "customscript/aesthetic.py/txt2img/Is negative text/visible": true,
+ "customscript/aesthetic.py/txt2img/Is negative text/value": false,
+ "customscript/prompts_from_file.py/txt2img/Use same random seed for all lines/value": false,
+ "customscript/inspiration.py/txt2img/Prompt words before artist or style name/value": "a painting in",
+ "customscript/inspiration.py/txt2img/Prompt words after artist or style name/value": "style",
+ "customscript/inspiration.py/txt2img/Negative Prompt/value": "picture frame, portrait photo",
+ "customscript/inspiration.py/txt2img/Batch size/value": 1.0,
+ "customscript/inspiration.py/txt2img/Batch count/value": 2.0,
+ "customscript/aesthetic.py/img2img/Aesthetic weight/visible": true,
+ "customscript/aesthetic.py/img2img/Aesthetic weight/value": 0.9,
+ "customscript/aesthetic.py/img2img/Aesthetic weight/minimum": 0,
+ "customscript/aesthetic.py/img2img/Aesthetic weight/maximum": 1,
+ "customscript/aesthetic.py/img2img/Aesthetic weight/step": 0.01,
+ "customscript/aesthetic.py/img2img/Aesthetic steps/visible": true,
+ "customscript/aesthetic.py/img2img/Aesthetic steps/value": 15,
+ "customscript/aesthetic.py/img2img/Aesthetic steps/minimum": 0,
+ "customscript/aesthetic.py/img2img/Aesthetic steps/maximum": 50,
+ "customscript/aesthetic.py/img2img/Aesthetic steps/step": 1,
+ "customscript/aesthetic.py/img2img/Aesthetic learning rate/visible": true,
+ "customscript/aesthetic.py/img2img/Aesthetic learning rate/value": "0.0001",
+ "customscript/aesthetic.py/img2img/Slerp interpolation/visible": true,
+ "customscript/aesthetic.py/img2img/Slerp interpolation/value": false,
+ "customscript/aesthetic.py/img2img/Aesthetic text for imgs/visible": true,
+ "customscript/aesthetic.py/img2img/Aesthetic text for imgs/value": "",
+ "customscript/aesthetic.py/img2img/Slerp angle/visible": true,
+ "customscript/aesthetic.py/img2img/Slerp angle/value": 0.1,
+ "customscript/aesthetic.py/img2img/Slerp angle/minimum": 0,
+ "customscript/aesthetic.py/img2img/Slerp angle/maximum": 1,
+ "customscript/aesthetic.py/img2img/Slerp angle/step": 0.01,
+ "customscript/aesthetic.py/img2img/Is negative text/visible": true,
+ "customscript/aesthetic.py/img2img/Is negative text/value": false,
+ "customscript/prompts_from_file.py/img2img/Use same random seed for all lines/value": false,
+ "customscript/inspiration.py/img2img/Prompt words before artist or style name/value": "a painting in",
+ "customscript/inspiration.py/img2img/Prompt words after artist or style name/value": "style",
+ "customscript/inspiration.py/img2img/Negative Prompt/value": "picture frame, portrait photo",
+ "customscript/inspiration.py/img2img/Batch size/value": 1.0,
+ "customscript/inspiration.py/img2img/Batch count/value": 2.0,
+ "txt2img/Styles/visible": true,
+ "txt2img/Styles/value": [],
+ "txt2img/Sampling steps/visible": true,
+ "txt2img/Sampling steps/value": 20,
+ "txt2img/Sampling steps/minimum": 1,
+ "txt2img/Sampling steps/maximum": 150,
+ "txt2img/Sampling steps/step": 1,
+ "txt2img/Hires. fix/visible": true,
+ "txt2img/Hires. fix/value": false,
+ "txt2img/Upscaler/visible": true,
+ "txt2img/Upscaler/value": "Latent",
+ "txt2img/Hires steps/visible": true,
+ "txt2img/Hires steps/value": 0,
+ "txt2img/Hires steps/minimum": 0,
+ "txt2img/Hires steps/maximum": 150,
+ "txt2img/Hires steps/step": 1,
+ "txt2img/Upscale by/visible": true,
+ "txt2img/Upscale by/value": 2.0,
+ "txt2img/Upscale by/minimum": 1.0,
+ "txt2img/Upscale by/maximum": 4.0,
+ "txt2img/Upscale by/step": 0.05,
+ "txt2img/Resize width to/visible": true,
+ "txt2img/Resize width to/value": 0,
+ "txt2img/Resize width to/minimum": 0,
+ "txt2img/Resize width to/maximum": 2048,
+ "txt2img/Resize width to/step": 8,
+ "txt2img/Resize height to/visible": true,
+ "txt2img/Resize height to/value": 0,
+ "txt2img/Resize height to/minimum": 0,
+ "txt2img/Resize height to/maximum": 2048,
+ "txt2img/Resize height to/step": 8,
+ "customscript/custom_code.py/txt2img/Python code/visible": true,
+ "customscript/prompt_matrix.py/txt2img/Put variable parts at start of prompt/visible": true,
+ "customscript/prompt_matrix.py/txt2img/Use different seed for each picture/visible": true,
+ "customscript/prompt_matrix.py/txt2img/Use different seed for each picture/value": false,
+ "customscript/prompts_from_file.py/txt2img/Iterate seed every line/visible": true,
+ "customscript/prompts_from_file.py/txt2img/Use same random seed for all lines/visible": true,
+ "customscript/prompts_from_file.py/txt2img/List of prompt inputs/visible": true,
+ "customscript/xy_grid.py/txt2img/X type/visible": true,
+ "customscript/xy_grid.py/txt2img/X type/value": "Seed",
+ "customscript/xy_grid.py/txt2img/X values/visible": true,
+ "customscript/xy_grid.py/txt2img/Y type/visible": true,
+ "customscript/xy_grid.py/txt2img/Y type/value": "Nothing",
+ "customscript/xy_grid.py/txt2img/Y values/visible": true,
+ "customscript/xy_grid.py/txt2img/Draw legend/visible": true,
+ "customscript/xy_grid.py/txt2img/Include Separate Images/visible": true,
+ "customscript/xy_grid.py/txt2img/Keep -1 for seeds/visible": true,
+ "img2img/Styles/visible": true,
+ "img2img/Styles/value": [],
+ "img2img/Mask transparency/value": 0,
+ "img2img/Mask transparency/minimum": 0,
+ "img2img/Mask transparency/maximum": 100,
+ "img2img/Mask transparency/step": 1,
+ "img2img/Inpaint area/visible": true,
+ "img2img/Inpaint area/value": "Whole picture",
+ "img2img/Only masked padding, pixels/visible": true,
+ "img2img/Only masked padding, pixels/value": 32,
+ "img2img/Only masked padding, pixels/minimum": 0,
+ "img2img/Only masked padding, pixels/maximum": 256,
+ "img2img/Only masked padding, pixels/step": 4,
+ "img2img/Sampling steps/visible": true,
+ "img2img/Sampling steps/value": 20,
+ "img2img/Sampling steps/minimum": 1,
+ "img2img/Sampling steps/maximum": 150,
+ "img2img/Sampling steps/step": 1,
+ "customscript/custom_code.py/img2img/Python code/visible": true,
+ "customscript/img2imgalt.py/img2img/Override `Sampling method` to Euler?(this method is built for it)/visible": true,
+ "customscript/img2imgalt.py/img2img/Override `prompt` to the same value as `original prompt`?(and `negative prompt`)/visible": true,
+ "customscript/img2imgalt.py/img2img/Original prompt/visible": true,
+ "customscript/img2imgalt.py/img2img/Original negative prompt/visible": true,
+ "customscript/img2imgalt.py/img2img/Override `Sampling Steps` to the same value as `Decode steps`?/visible": true,
+ "customscript/img2imgalt.py/img2img/Decode steps/visible": true,
+ "customscript/img2imgalt.py/img2img/Override `Denoising strength` to 1?/visible": true,
+ "customscript/img2imgalt.py/img2img/Decode CFG scale/visible": true,
+ "customscript/img2imgalt.py/img2img/Randomness/visible": true,
+ "customscript/img2imgalt.py/img2img/Sigma adjustment for finding noise for image/visible": true,
+ "customscript/loopback.py/img2img/Loops/visible": true,
+ "customscript/loopback.py/img2img/Denoising strength change factor/visible": true,
+ "customscript/outpainting_mk_2.py/img2img/Pixels to expand/visible": true,
+ "customscript/outpainting_mk_2.py/img2img/Mask blur/visible": true,
+ "customscript/outpainting_mk_2.py/img2img/Fall-off exponent (lower=higher detail)/visible": true,
+ "customscript/outpainting_mk_2.py/img2img/Color variation/visible": true,
+ "customscript/poor_mans_outpainting.py/img2img/Pixels to expand/visible": true,
+ "customscript/poor_mans_outpainting.py/img2img/Mask blur/visible": true,
+ "customscript/poor_mans_outpainting.py/img2img/Masked content/visible": true,
+ "customscript/prompt_matrix.py/img2img/Put variable parts at start of prompt/visible": true,
+ "customscript/prompt_matrix.py/img2img/Use different seed for each picture/visible": true,
+ "customscript/prompt_matrix.py/img2img/Use different seed for each picture/value": false,
+ "customscript/prompts_from_file.py/img2img/Iterate seed every line/visible": true,
+ "customscript/prompts_from_file.py/img2img/Use same random seed for all lines/visible": true,
+ "customscript/prompts_from_file.py/img2img/List of prompt inputs/visible": true,
+ "customscript/sd_upscale.py/img2img/Tile overlap/visible": true,
+ "customscript/sd_upscale.py/img2img/Scale Factor/visible": true,
+ "customscript/sd_upscale.py/img2img/Scale Factor/value": 2.0,
+ "customscript/sd_upscale.py/img2img/Scale Factor/minimum": 1.0,
+ "customscript/sd_upscale.py/img2img/Scale Factor/maximum": 4.0,
+ "customscript/sd_upscale.py/img2img/Scale Factor/step": 0.05,
+ "customscript/sd_upscale.py/img2img/Upscaler/visible": true,
+ "customscript/xy_grid.py/img2img/X type/visible": true,
+ "customscript/xy_grid.py/img2img/X type/value": "Seed",
+ "customscript/xy_grid.py/img2img/X values/visible": true,
+ "customscript/xy_grid.py/img2img/Y type/visible": true,
+ "customscript/xy_grid.py/img2img/Y type/value": "Nothing",
+ "customscript/xy_grid.py/img2img/Y values/visible": true,
+ "customscript/xy_grid.py/img2img/Draw legend/visible": true,
+ "customscript/xy_grid.py/img2img/Include Separate Images/visible": true,
+ "customscript/xy_grid.py/img2img/Keep -1 for seeds/visible": true,
+ "customscript/postprocessing_upscale.py/extras/Resize/visible": true,
+ "customscript/postprocessing_upscale.py/extras/Resize/value": 4,
+ "customscript/postprocessing_upscale.py/extras/Resize/minimum": 1.0,
+ "customscript/postprocessing_upscale.py/extras/Resize/maximum": 8.0,
+ "customscript/postprocessing_upscale.py/extras/Resize/step": 0.05,
+ "customscript/postprocessing_upscale.py/extras/Width/visible": true,
+ "customscript/postprocessing_upscale.py/extras/Width/value": 512,
+ "customscript/postprocessing_upscale.py/extras/Height/visible": true,
+ "customscript/postprocessing_upscale.py/extras/Height/value": 512,
+ "customscript/postprocessing_upscale.py/extras/Crop to fit/visible": true,
+ "customscript/postprocessing_upscale.py/extras/Crop to fit/value": true,
+ "customscript/postprocessing_upscale.py/extras/Upscaler 1/visible": true,
+ "customscript/postprocessing_upscale.py/extras/Upscaler 1/value": "None",
+ "customscript/postprocessing_upscale.py/extras/Upscaler 2/visible": true,
+ "customscript/postprocessing_upscale.py/extras/Upscaler 2/value": "None",
+ "customscript/postprocessing_upscale.py/extras/Upscaler 2 visibility/visible": true,
+ "customscript/postprocessing_upscale.py/extras/Upscaler 2 visibility/value": 0.0,
+ "customscript/postprocessing_upscale.py/extras/Upscaler 2 visibility/minimum": 0.0,
+ "customscript/postprocessing_upscale.py/extras/Upscaler 2 visibility/maximum": 1.0,
+ "customscript/postprocessing_upscale.py/extras/Upscaler 2 visibility/step": 0.001,
+ "customscript/postprocessing_gfpgan.py/extras/GFPGAN visibility/visible": true,
+ "customscript/postprocessing_gfpgan.py/extras/GFPGAN visibility/value": 0,
+ "customscript/postprocessing_gfpgan.py/extras/GFPGAN visibility/minimum": 0.0,
+ "customscript/postprocessing_gfpgan.py/extras/GFPGAN visibility/maximum": 1.0,
+ "customscript/postprocessing_gfpgan.py/extras/GFPGAN visibility/step": 0.001,
+ "customscript/postprocessing_codeformer.py/extras/CodeFormer visibility/visible": true,
+ "customscript/postprocessing_codeformer.py/extras/CodeFormer visibility/value": 0,
+ "customscript/postprocessing_codeformer.py/extras/CodeFormer visibility/minimum": 0.0,
+ "customscript/postprocessing_codeformer.py/extras/CodeFormer visibility/maximum": 1.0,
+ "customscript/postprocessing_codeformer.py/extras/CodeFormer visibility/step": 0.001,
+ "customscript/postprocessing_codeformer.py/extras/CodeFormer weight (0 = maximum effect, 1 = minimum effect)/visible": true,
+ "customscript/postprocessing_codeformer.py/extras/CodeFormer weight (0 = maximum effect, 1 = minimum effect)/value": 0,
+ "customscript/postprocessing_codeformer.py/extras/CodeFormer weight (0 = maximum effect, 1 = minimum effect)/minimum": 0.0,
+ "customscript/postprocessing_codeformer.py/extras/CodeFormer weight (0 = maximum effect, 1 = minimum effect)/maximum": 1.0,
+ "customscript/postprocessing_codeformer.py/extras/CodeFormer weight (0 = maximum effect, 1 = minimum effect)/step": 0.001,
+ "modelmerger/Primary model (A)/visible": true,
+ "modelmerger/Primary model (A)/value": null,
+ "modelmerger/Secondary model (B)/visible": true,
+ "modelmerger/Secondary model (B)/value": null,
+ "modelmerger/Tertiary model (C)/visible": true,
+ "modelmerger/Tertiary model (C)/value": null,
+ "modelmerger/Checkpoint format/visible": true,
+ "modelmerger/Checkpoint format/value": "ckpt",
+ "modelmerger/Copy config from/visible": true,
+ "modelmerger/Copy config from/value": "A, B or C",
+ "modelmerger/Bake in VAE/visible": true,
+ "modelmerger/Bake in VAE/value": "None",
+ "modelmerger/Discard weights with matching name/visible": true,
+ "modelmerger/Discard weights with matching name/value": "",
+ "train/Name/visible": true,
+ "train/Name/value": "",
+ "train/Initialization text/visible": true,
+ "train/Initialization text/value": "*",
+ "train/Number of vectors per token/visible": true,
+ "train/Number of vectors per token/value": 1,
+ "train/Number of vectors per token/minimum": 1,
+ "train/Number of vectors per token/maximum": 75,
+ "train/Number of vectors per token/step": 1,
+ "train/Overwrite Old Embedding/visible": true,
+ "train/Overwrite Old Embedding/value": false,
+ "train/Enter hypernetwork layer structure/visible": true,
+ "train/Enter hypernetwork layer structure/value": "1, 2, 1",
+ "train/Select activation function of hypernetwork. Recommended : Swish / Linear(none)/visible": true,
+ "train/Select activation function of hypernetwork. Recommended : Swish / Linear(none)/value": "linear",
+ "train/Select Layer weights initialization. Recommended: Kaiming for relu-like, Xavier for sigmoid-like, Normal otherwise/visible": true,
+ "train/Select Layer weights initialization. Recommended: Kaiming for relu-like, Xavier for sigmoid-like, Normal otherwise/value": "Normal",
+ "train/Add layer normalization/visible": true,
+ "train/Add layer normalization/value": false,
+ "train/Use dropout/visible": true,
+ "train/Use dropout/value": false,
+ "train/Enter hypernetwork Dropout structure (or empty). Recommended : 0~0.35 incrementing sequence: 0, 0.05, 0.15/visible": true,
+ "train/Enter hypernetwork Dropout structure (or empty). Recommended : 0~0.35 incrementing sequence: 0, 0.05, 0.15/value": "0, 0, 0",
+ "train/Overwrite Old Hypernetwork/visible": true,
+ "train/Overwrite Old Hypernetwork/value": false,
+ "train/Source directory/visible": true,
+ "train/Source directory/value": "",
+ "train/Destination directory/visible": true,
+ "train/Destination directory/value": "",
+ "train/Width/visible": true,
+ "train/Width/value": 512,
+ "train/Width/minimum": 64,
+ "train/Width/maximum": 2048,
+ "train/Width/step": 8,
+ "train/Height/visible": true,
+ "train/Height/value": 512,
+ "train/Height/minimum": 64,
+ "train/Height/maximum": 2048,
+ "train/Height/step": 8,
+ "train/Existing Caption txt Action/visible": true,
+ "train/Existing Caption txt Action/value": "ignore",
+ "train/Create flipped copies/visible": true,
+ "train/Create flipped copies/value": false,
+ "train/Split oversized images/visible": true,
+ "train/Split oversized images/value": false,
+ "train/Auto focal point crop/visible": true,
+ "train/Auto focal point crop/value": false,
+ "train/Auto-sized crop/visible": true,
+ "train/Auto-sized crop/value": false,
+ "train/Use BLIP for caption/visible": true,
+ "train/Use BLIP for caption/value": false,
+ "train/Use deepbooru for caption/visible": true,
+ "train/Use deepbooru for caption/value": false,
+ "train/Split image threshold/visible": true,
+ "train/Split image threshold/value": 0.5,
+ "train/Split image threshold/minimum": 0.0,
+ "train/Split image threshold/maximum": 1.0,
+ "train/Split image threshold/step": 0.05,
+ "train/Split image overlap ratio/visible": true,
+ "train/Split image overlap ratio/value": 0.2,
+ "train/Split image overlap ratio/minimum": 0.0,
+ "train/Split image overlap ratio/maximum": 0.9,
+ "train/Split image overlap ratio/step": 0.05,
+ "train/Focal point face weight/visible": true,
+ "train/Focal point face weight/value": 0.9,
+ "train/Focal point face weight/minimum": 0.0,
+ "train/Focal point face weight/maximum": 1.0,
+ "train/Focal point face weight/step": 0.05,
+ "train/Focal point entropy weight/visible": true,
+ "train/Focal point entropy weight/value": 0.15,
+ "train/Focal point entropy weight/minimum": 0.0,
+ "train/Focal point entropy weight/maximum": 1.0,
+ "train/Focal point entropy weight/step": 0.05,
+ "train/Focal point edges weight/visible": true,
+ "train/Focal point edges weight/value": 0.5,
+ "train/Focal point edges weight/minimum": 0.0,
+ "train/Focal point edges weight/maximum": 1.0,
+ "train/Focal point edges weight/step": 0.05,
+ "train/Create debug image/visible": true,
+ "train/Create debug image/value": false,
+ "train/Dimension lower bound/visible": true,
+ "train/Dimension lower bound/value": 384,
+ "train/Dimension lower bound/minimum": 64,
+ "train/Dimension lower bound/maximum": 2048,
+ "train/Dimension lower bound/step": 8,
+ "train/Dimension upper bound/visible": true,
+ "train/Dimension upper bound/value": 768,
+ "train/Dimension upper bound/minimum": 64,
+ "train/Dimension upper bound/maximum": 2048,
+ "train/Dimension upper bound/step": 8,
+ "train/Area lower bound/visible": true,
+ "train/Area lower bound/value": 4096,
+ "train/Area lower bound/minimum": 4096,
+ "train/Area lower bound/maximum": 4194304,
+ "train/Area lower bound/step": 1,
+ "train/Area upper bound/visible": true,
+ "train/Area upper bound/value": 409600,
+ "train/Area upper bound/minimum": 4096,
+ "train/Area upper bound/maximum": 4194304,
+ "train/Area upper bound/step": 1,
+ "train/Resizing objective/visible": true,
+ "train/Resizing objective/value": "Maximize area",
+ "train/Error threshold/visible": true,
+ "train/Error threshold/value": 0.1,
+ "train/Error threshold/minimum": 0,
+ "train/Error threshold/maximum": 1,
+ "train/Error threshold/step": 0.01,
+ "train/Embedding/visible": true,
+ "train/Embedding/value": null,
+ "train/Hypernetwork/visible": true,
+ "train/Hypernetwork/value": null,
+ "train/Embedding Learning rate/visible": true,
+ "train/Embedding Learning rate/value": "0.005",
+ "train/Hypernetwork Learning rate/visible": true,
+ "train/Hypernetwork Learning rate/value": "0.00001",
+ "train/Gradient Clipping/visible": true,
+ "train/Gradient Clipping/value": "disabled",
+ "train/Batch size/visible": true,
+ "train/Batch size/value": 1,
+ "train/Gradient accumulation steps/visible": true,
+ "train/Gradient accumulation steps/value": 1,
+ "train/Dataset directory/visible": true,
+ "train/Dataset directory/value": "",
+ "train/Log directory/visible": true,
+ "train/Log directory/value": "textual_inversion",
+ "train/Prompt template/visible": true,
+ "train/Prompt template/value": "style_filewords.txt",
+ "train/Do not resize images/visible": true,
+ "train/Do not resize images/value": false,
+ "train/Max steps/visible": true,
+ "train/Max steps/value": 100000,
+ "train/Save an image to log directory every N steps, 0 to disable/visible": true,
+ "train/Save an image to log directory every N steps, 0 to disable/value": 500,
+ "train/Save a copy of embedding to log directory every N steps, 0 to disable/visible": true,
+ "train/Save a copy of embedding to log directory every N steps, 0 to disable/value": 500,
+ "train/Save images with embedding in PNG chunks/visible": true,
+ "train/Save images with embedding in PNG chunks/value": true,
+ "train/Read parameters (prompt, etc...) from txt2img tab when making previews/visible": true,
+ "train/Read parameters (prompt, etc...) from txt2img tab when making previews/value": false,
+ "train/Shuffle tags by ',' when creating prompts./visible": true,
+ "train/Shuffle tags by ',' when creating prompts./value": false,
+ "train/Drop out tags when creating prompts./visible": true,
+ "train/Drop out tags when creating prompts./value": 0,
+ "train/Drop out tags when creating prompts./minimum": 0,
+ "train/Drop out tags when creating prompts./maximum": 1,
+ "train/Drop out tags when creating prompts./step": 0.1,
+ "train/Choose latent sampling method/visible": true,
+ "train/Choose latent sampling method/value": "once"
+}
\ No newline at end of file
diff --git a/Notebooks/AI/Visual/Generate/Stable-Diffusion-WebUI/Stable-Diffusion_WebUI.ipynb b/Notebooks/AI/Visual/Generate/Stable-Diffusion-WebUI/Stable-Diffusion_WebUI.ipynb
new file mode 100644
index 0000000..ac66b0c
--- /dev/null
+++ b/Notebooks/AI/Visual/Generate/Stable-Diffusion-WebUI/Stable-Diffusion_WebUI.ipynb
@@ -0,0 +1,747 @@
+{
+ "metadata": {
+ "accelerator": "GPU",
+ "colab": {
+ "name": "Stable-Diffusion-WebUI (Old)",
+ "collapsed_sections": [
+ "n6stH_uiejQc",
+ "PbAjvcMog1LM"
+ ]
+ },
+ "gpuClass": "standard",
+ "kernelspec": {
+ "display_name": "Python 3",
+ "name": "python3"
+ },
+ "language_info": {
+ "name": "python"
+ }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 0,
+ "cells": [
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "gfKvWAVnz8OB"
+ },
+ "source": [
+ "[Stable Diffusion WebUI ](https://github.com/AUTOMATIC1111/stable-diffusion-webui) \n",
+ " \n",
+ "\n",
+ "โน๏ธ ***Requires [HuggingFace](https://hf.co/login) account!***\n",
+ "\n",
+ "---"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "61-1k-wIfY9Y"
+ },
+ "source": [
+ "# ๐ Documentation"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "StGCee2ofS0a"
+ },
+ "source": [
+ "## ๐ Useful Websites Index\n",
+ "\n"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "source": [
+ "| โ | Website | Additional Description | Language |\n",
+ "|:-:|:-:|:-:|:-:|\n",
+ "| 01 | **[Models List](https://rentry.org/sdmodels)** | Contains over `150` models. | ๐บ๐ธ English |\n",
+ "| 02 | [DreamBooth models library](https://hf.co/sd-dreambooth-library) | Contains over `200` models in different styles **and quality**. | ๐บ๐ธ English |\n",
+ "| 03 | [Subreddit](https://www.reddit.com/r/StableDiffusion/new) | | ๐บ๐ธ English |\n",
+ "| 04 | **[Prompts library](https://publicprompts.art/prompts-library)** | Small. | ๐บ๐ธ English |\n",
+ "| 05 | [Stable Diffusion prompt guide](https://prompthero.com/stable-diffusion-prompt-guide#top) | Childish. | ๐บ๐ธ English |\n",
+ "| 06 | [*ExHentai* translated tags](https://github.com/scooderic/exhentai-tags-chinese-translation) | Useful with creating anime pornography. | ๐บ๐ธ English |\n",
+ "| 07 | [***NovelAI Tag Experiments***](https://zele.st/NovelAI) | May be useful with anime models. | ๐บ๐ธ English |\n",
+ "| 08 | [Anime models Keywords](https://paste.ubuntu.com/p/dFBhdJR8PQ) | | ๐ฏ๐ต Japanese |\n",
+ "| 09 | **[HuggingFace space community creations](https://hf.co/spaces/stabilityai/stable-diffusion/discussions)** | Created with [Stable Diffusion `v1.4`](https://hf.co/CompVis/stable-diffusion-v1-4) | ๐บ๐ธ English |"
+ ],
+ "metadata": {
+ "id": "ferH77QwL4cJ"
+ }
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "QoaRp0emf6LN"
+ },
+ "source": [
+ "---\n",
+ "# ๐ฅ๏ธ Program"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "n6stH_uiejQc"
+ },
+ "source": [
+ "## ๐ **Main**"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "cellView": "form",
+ "id": "nC5n0manejQg"
+ },
+ "source": [
+ "#@title ## **1.** Install requirements.\n",
+ "#@markdown - [`Stable-Diffusion-WebUI`](https://github.com/AUTOMATIC1111/stable-diffusion-webui)\n",
+ "#@markdown - [`JPEGOptim`](https://github.com/tjko/jpegoptim)\n",
+ "\n",
+ "#@markdown ---\n",
+ "\n",
+ "WebUI_Version = \"08 November 2022\" #@param [\"Latest\", \"08 November 2022\"]\n",
+ "\n",
+ "#@markdown \n",
+ "#@markdown\n",
+ "#@markdown | Version | Simpler GUI | Image previews | `.safetensors` | Plugins | Hypernetworks | AddNet |\n",
+ "#@markdown |:-:|:-:|:-:|:-:|:-:|:-:|:-:|\n",
+ "#@markdown | Latest | โ | [**โ**](https://github.com/AUTOMATIC1111/stable-diffusion-webui/discussions/4092) | โ๏ธ | โ๏ธ | โ๏ธ | โ๏ธ | โ๏ธ |\n",
+ "#@markdown | 08 November 2022 | โ๏ธ | **โ** | โ | โ | โ | โ |\n",
+ "\n",
+ "#@markdown ---\n",
+ "\n",
+ "#@markdown # ๐ Custom configuration\n",
+ "#@markdown Input **direct links** to files. ๐\n",
+ "URL_Config_JSON = \"https://raw.githubusercontent.com/kubinka0505/colab-notebooks/master/Notebooks/AI/Visual/Generate/Stable-Diffusion-WebUI/Config/config.json\" #@param {type: \"string\"}\n",
+ "URL_Styles_CSV = \"https://raw.githubusercontent.com/kubinka0505/colab-notebooks/master/Notebooks/AI/Visual/Generate/Stable-Diffusion-WebUI/Config/styles.csv\" #@param {type: \"string\"}\n",
+ "URL_UI_Config_JSON = \"https://raw.githubusercontent.com/kubinka0505/colab-notebooks/master/Notebooks/AI/Visual/Generate/Stable-Diffusion-WebUI/Config/ui-config.json\" #@param {type: \"string\"}\n",
+ "URL_Style_CSS = \"\" #@param {type: \"string\"}\n",
+ "\n",
+ "#-=-=-=-#\n",
+ "\n",
+ "import sys\n",
+ "import cv2\n",
+ "import json\n",
+ "import IPython\n",
+ "from os import *\n",
+ "from time import time\n",
+ "from gc import collect\n",
+ "from pathlib import Path\n",
+ "from shutil import rmtree\n",
+ "from requests import head\n",
+ "from PIL import ImageColor\n",
+ "from zipfile import ZipFile\n",
+ "from tensorflow import config\n",
+ "from subprocess import getoutput\n",
+ "from torch.cuda import empty_cache\n",
+ "del open\n",
+ "\n",
+ "try:\n",
+ "\tfrom google.colab import drive, files\n",
+ "\tis_Colab = 1\n",
+ "\tPython = \"python\"\n",
+ "\t__Return = \"\"\n",
+ "except ImportError:\n",
+ "\tis_Colab = 0\n",
+ "\tPython = sys.executable\n",
+ "\t__Return = \"\\r\"\n",
+ "__Return += \" \" * 150\n",
+ "\n",
+ "GPU = config.list_physical_devices(\"GPU\")[0].device_type == \"GPU\"\n",
+ "if not GPU:\n",
+ "\traise SystemExit(\"GPU unavailable, exiting\")\n",
+ "\n",
+ "chdir(\"/content/\")\n",
+ "system(\"\")\n",
+ "\n",
+ "#-=-=-=-#\n",
+ "\n",
+ "__author__ = \"kubinka0505\"\n",
+ "__credits__ = [\n",
+ "\t\"exlolicon\",\n",
+ "\t\"Voldy\",\n",
+ "\t\"FuouM\",\n",
+ "\t\"Neo Hidamari\",\n",
+ "\t\"kubinka0505\"\n",
+ "]\n",
+ "__version__ = \"1.3\"\n",
+ "__date__ = \"27.01.2023\"\n",
+ "\n",
+ "#-=-=-=-#\n",
+ "\n",
+ "def DirSize(Directory: str) -> int:\n",
+ "\t\"\"\"Calculates folder size recursively\"\"\"\n",
+ "\tSize = 0\n",
+ "\tfor File in Path(Directory).rglob(\"*.*\"):\n",
+ "\t\tSize += path.getsize(File)\n",
+ "\t#-=-=-=-#\n",
+ "\treturn Size\n",
+ "\n",
+ "def HumanReadableSize(Bytes: float) -> str:\n",
+ "\t\"\"\"Returns human-readable file size\"\"\"\n",
+ "\tfor Unit in [\"B\", \"KB\", \"MB\", \"GB\"]:\n",
+ "\t\tif Bytes < 1024:\n",
+ "\t\t\tbreak\n",
+ "\t\tBytes /= 1024.\n",
+ "\t#-=-=-=-#\n",
+ "\treturn \"{0} {1}\".format(round(Bytes, 2), Unit)\n",
+ "\n",
+ "#-=-=-=-#\n",
+ "\n",
+ "__Path = \"/content/stable-diffusion-webui/\"\n",
+ "if path.exists(__Path):\n",
+ "\trmtree(__Path)\n",
+ "\n",
+ "#-=-=-=-#\n",
+ "\n",
+ "# - Languages - #\n",
+ "__LanguageRepos = {\n",
+ "\t\"Chinese (Simplified)\": \"https://github.com/dtlnor/stable-diffusion-webui-localization-zh_CN\",\n",
+ "\t\"Chinese (Traditional)\": \"https://github.com/benlisquare/stable-diffusion-webui-localization-zh_TW\",\n",
+ "\t\"German\": \"https://github.com/Strothis/stable-diffusion-webui-de_DE\",\n",
+ "\t\"Italian\": \"https://github.com/Harvester62/stable-diffusion-webui-localization-it_IT\",\n",
+ "\t\"Japanese\": \"https://github.com/yuuki76/webui-localization-ja_JP\",\n",
+ "\t\"Korean\": \"https://github.com/36DB/stable-diffusion-webui-localization-ko_KR\",\n",
+ "\t\"Norwegian\": \"https://github.com/Cyanz83/stable-diffusion-webui-localization-no_NO\",\n",
+ "\t\"Portuguese\": \"https://github.com/M-art-ucci/stable-diffusion-webui-localization-pt_BR\",\n",
+ "\t\"Spanish\": \"https://github.com/innovaciones/stable-diffusion-webui-localization-es_ES\",\n",
+ "\t\"Turkish\": \"https://github.com/camenduru/stable-diffusion-webui-localization-tr_TR\"\n",
+ "}\n",
+ "\n",
+ "# - Custom Configuration - #\n",
+ "__Styles = {\n",
+ "\t\"config.json\": URL_Config_JSON,\n",
+ "\t\"styles.csv\": URL_Styles_CSV,\n",
+ "\t\"ui-config.json\": URL_UI_Config_JSON,\n",
+ "\t\"style.css\": URL_Style_CSS\n",
+ "}\n",
+ "\n",
+ "#-=-=-=-#\n",
+ "\n",
+ "__C = ImageColor.getrgb(\"#0F0\")\n",
+ "__C_Green = f\"\\033[1m\\x1b[38;2;{__C[0]};{__C[1]};{__C[2]}m\"\n",
+ "__C_Reset = \"\\33[0m\"\n",
+ "printC = lambda Text, Prefix = \"\\n\": \\\n",
+ "\tprint(f\"{__C_Green}{Prefix}Installing {str(Text)}...{__C_Reset}\")\n",
+ "\n",
+ "printC(\"Stable-Diffusion-WebUI\", \"\")\n",
+ "if \"Latest\" in WebUI_Version:\n",
+ "\tAuthor = \"AUTOMATIC1111\"\n",
+ "else:\n",
+ "\tAuthor = \"kubinka0505\"\n",
+ "\t!pip install -U fastapi==0.90.1\n",
+ "Repository = f\"https://github.com/{Author}/stable-diffusion-webui\"\n",
+ "\n",
+ "!git clone $Repository\n",
+ "chdir(__Path)\n",
+ "\n",
+ "printC(\"Stable-Diffusion-WebUI dependencies\")\n",
+ "!COMMANDLINE_ARGS=\"--exit\" REQS_FILE=\"requirements.txt\" $Python launch.py\n",
+ "print()\n",
+ "\n",
+ "#-=-=-=-#\n",
+ "\n",
+ "print(\"โ\" * 32)\n",
+ "\n",
+ "printC(\"JPEGOptim\")\n",
+ "!apt-get install jpegoptim\n",
+ "\n",
+ "#-=-=-=-#\n",
+ "\n",
+ "if \"Latest\" in WebUI_Version:\n",
+ "\tchdir(path.join(__Path, \"localizations/\"))\n",
+ "\tprintC(\"Languages\")\n",
+ "\n",
+ "\tif path.exists(\"./localizations\"):\n",
+ "\t\trmtree(\"./localizations\")\n",
+ "\n",
+ "\tCounter = 1\n",
+ "\tfor Name, Repository in __LanguageRepos.items():\n",
+ "\t\t#-=-=-=-#\n",
+ "\t\t# Author\n",
+ "\t\tUser = Repository.split(\"/\")[3]\n",
+ "\t\t# Repository name\n",
+ "\t\tName = Repository.split(\"/\")[-1]\n",
+ "\t\t# Language code\n",
+ "\t\tFile = Repository.split(\"-\")[-1] + \".json\"\n",
+ "\t\t#-=-=-=-#\n",
+ "\t\tRepository = f\"https://raw.githubusercontent.com/{User}/{Name}/master/localizations/{File}\"\n",
+ "\t\tprint(f\"\\t[{__Counter}/{len(__Languages.values())}] {Name}...\", end = __Return)\n",
+ "\t\t!curl -s -Lo $File $Repository > /dev/null\n",
+ "\n",
+ "\tchdir(__Path)\n",
+ " \n",
+ "printC(\"Custom Configuration\")\n",
+ "for Key, Value in __Styles.items():\n",
+ "\tKey = path.abspath(Key)\n",
+ "\tif path.exists(Key):\n",
+ "\t\tif Value:\n",
+ "\t\t\tremove(Key)\n",
+ "\tif Value:\n",
+ "\t\twith head(Value, allow_redirects = 1) as Site:\n",
+ "\t\t\tprint(f'\\rDownloading \"{Key.split(sep)[-1]}\"', end = __Return)\n",
+ "\t\t\tif not Site.ok:\n",
+ "\t\t\t\traise SystemExit('Can\\'t fetch \"{0}\" file: {1} (\"{2}\").'.format(\n",
+ "\t\t\t\t\tSite.url.split(\"/\")[-1], Site.status_code, Site.reason\n",
+ "\t\t\t\t\t)\n",
+ "\t\t\t\t)\n",
+ "\t\t\t!curl -Lo $Key $Value"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "DQC21mwk3Rpn",
+ "cellView": "form"
+ },
+ "source": [
+ "#@title # **2.** Install **diffusers**.\n",
+ "#@markdown ### โน๏ธ **Most models are pruned `EMA`s in `float16` format.**\n",
+ "\n",
+ "#@markdown | โ | Name | Version | Size | `CKPT` | `VAE` | Trained on | Trigger phrase(prompt beggining) |\n",
+ "#@markdown |:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|\n",
+ "#@markdown | 01 | [Stable Diffusion](https://hf.co/runwayml/stable-diffusion-v1-5) | 1.5 |**`4.27 GB`** | โ๏ธ | โ | *Latent, [Stable Diffusion `v1.2`](http://hf.co/CompVis/stable-diffusion-v1-2)* | |\n",
+ "#@markdown | 02 | [Stable Diffusion](https://hf.co/CompVis/stable-diffusion-v1-4) | 1.4 | **`4.00 GB`** | โ๏ธ |\tโ | *Latent, [Stable Diffusion `v1.2`](http://hf.co/CompVis/stable-diffusion-v1-2)* | |\n",
+ "#@markdown | 03 | [OpenJourney](https://hf.co/prompthero/midjourney-v4-diffusion) | 4.0 | **`2.13 GB`** | โ๏ธ | โ | Midjourney images | `mdjrny-v4 style` |\n",
+ "#@markdown | 04 | [DreamLike PhotoReal](https://hf.co/dreamlike-art/dreamlike-photoreal-2.0) | 2.0 | **`2.13 GB`** | โ๏ธ | โ | [Stable Diffusion `v1.5`](https://hf.co/runwayml/stable-diffusion-v1-5) | `photo` *(optional)* |\n",
+ "#@markdown | 05 | [ProtoGen](https://hf.co/darkstorm2150/Protogen_x5.3_Official_Release) | 5.3 | **`1.72 GB`** | โ๏ธ | โ | | |\n",
+ "#@markdown | 06 | Novel AI | | **`4.13 GB`** | โ๏ธ | **โ๏ธ** | | |\n",
+ "#@markdown | 07 | [AniReal](https://hf.co/Hosioka/AniReal) | 1.3 | **`2.13 GB`** | **โ** | **โ๏ธ** | *Danbooru* photorealistic anime illustrations | [**Danbooru tags**](https://danbooru.donmai.us/tags?commit=Search&search[order]=count)\n",
+ "#@markdown | 08 | [Anything](https://hf.co/andite/anything-v4.0) | 4.5 | **`3.85 GB`** | โ๏ธ | **โ๏ธ** | | |\n",
+ "#@markdown | 09 | [AbyssOrangeMix](https://hf.co/WarriorMama777/OrangeMixs) (SFW) | | **`5.98 GB`** | โ๏ธ | **โ๏ธ** | | |\n",
+ "#@markdown | 10 | [BloodOrangeMix](https://hf.co/WarriorMama777/OrangeMixs) (NSFW) | | **`5.98 GB`** | โ๏ธ | **โ๏ธ** | | |\n",
+ "#@markdown | 11 | [PastelMix](https://hf.co/andite/pastel-mix) | | **`2.13 GB`** | โ๏ธ | **โ๏ธ** | | `mksks style` *(optional)* |\n",
+ "#@markdown | 12 | [Kenshi](https://hf.co/SweetLuna/Kenshi) | 1.0 | **`4.27 GB`** | โ๏ธ | **โ๏ธ** | Multiple models merge | (`WLOP`, `Nixeu`, `Guweiz`) *(optional)* |\n",
+ "#@markdown | 13 | [Archer Diffusion](https://hf.co/nitrosocke/archer-diffusion) | 3.0 | **`2.13 GB`** | โ๏ธ | โ | TV-show \"[Archer](https://wikipedia.org/wiki/Archer_(2009_TV_series))\" pictures | `archer style` |\n",
+ "#@markdown | 14 | [seek.art Mega](https://hf.co/coreco/seek.art_MEGA) | 1.0 | **`2.13 GB`** | โ๏ธ | โ | |\n",
+ "#@markdown | 15 | [3D Style](https://hf.co/Guizmus/SD_DreamerCommunities_Collection) | 1.0 | **`2.13 GB`** | โ๏ธ | โ | [Stable Diffusion `v1.5`](https://hf.co/runwayml/stable-diffusion-v1-5) | `3D Style`\n",
+ "#@markdown | 16 | [Redshift Diffusion](https://hf.co/nitrosocke/redshift-diffusion) | 1.0 | **`2.13 GB`** | โ๏ธ | โ | High resolution 3D artworks | `redshift style` |\n",
+ "#@markdown | 17 | [Elden Ring Diffusion](https://hf.co/nitrosocke/elden-ring-diffusion) | 2.0 | **`2.13 GB`** | โ๏ธ | โ | \"[Elden Ring](https://wikipedia.org/wiki/Elden_Ring)\" video game art | `elden ring style` |\n",
+ "#@markdown | 18 | [Robo Diffusion](https://hf.co/nousr/robo-diffusion) | 2.0 | `4.27 GB` | โ๏ธ | โ | \"*Finetuned Stable Diffusion*\" | `nousr robot` |\n",
+ "#@markdown | 19 | [Van Gogh Diffusion](https://hf.co/dallinmackay/Van-Gogh-diffusion) | 2.0 | `4.27 GB` | โ๏ธ | โ | Screenshots of the \"[Loving Vincent](https://en.wikipedia.org/wiki/Loving_Vincent)\" movie | `lvngvncnt` |\n",
+ "#@markdown | 20 | [PaperCut Model](https://hf.co/Fictiverse/Stable_Diffusion_PaperCut_Model) | 1.0 | `4.27 GB` | โ๏ธ | โ | Paper cut images | `PaperCut` |\n",
+ "#@markdown | 21 | [App Icons Generator DreamBooth](https://publicprompts.art/app-icons-generator-v1-dreambooth-model) | 1.0 | `2.13 GB` | โ๏ธ | **N/A** | | `SKSKS app icon` |\n",
+ "\n",
+ "#@markdown ---\n",
+ "\n",
+ "#@markdown โ๏ธ Token can be obtained from **[HuggingFace account settings](http://hf.co/settings/tokens)**.\n",
+ "\n",
+ "#@markdown Official *`Stable Diffusion`* models may require it.\n",
+ "Token = \"\" #@param {type: \"string\"}\n",
+ "__Header = f\"Authorization: Bearer {Token}\"\n",
+ "#@markdown *(This is the moment where you should save this notebook copy to your Google Drive)*\n",
+ "\n",
+ "#@markdown ---\n",
+ "\n",
+ "#@markdown ## ๐ฅ **Models**\n",
+ "\n",
+ "#@markdown General Purpose\n",
+ "Stable_Diffusion_v15 = True #@param {type: \"boolean\"}\n",
+ "Stable_Diffusion_v14 = False #@param {type: \"boolean\"}\n",
+ "OpenJourney_v4 = False #@param {type: \"boolean\"}\n",
+ "DreamLike_PhotoReal_v2 = True #@param {type: \"boolean\"}\n",
+ "ProtoGen_v53 = True #@param {type: \"boolean\"}\n",
+ "\n",
+ "#@markdown Anime\n",
+ "Novel_AI = False #@param {type: \"boolean\"}\n",
+ "AniReal_v1 = False #@param {type: \"boolean\"}\n",
+ "Anything_v45 = True #@param {type: \"boolean\"}\n",
+ "AbyssOrangeMix_v1 = False #@param {type: \"boolean\"}\n",
+ "BloodOrangeMix_v1 = True #@param {type: \"boolean\"}\n",
+ "PastelMix_v1 = True #@param {type: \"boolean\"}\n",
+ "Kenshi_v1 = False #@param {type: \"boolean\"}\n",
+ "\n",
+ "#@markdown Cartoons\n",
+ "Archer_Diffusion_v3 = False #@param {type: \"boolean\"}\n",
+ "\n",
+ "#@markdown Art\n",
+ "Seek_Art_Mega_v1 = True #@param {type: \"boolean\"}\n",
+ "_3D_Style_v1 = True #@param {type: \"boolean\"}\n",
+ "Redshift_Diffusion_v1 = False #@param {type: \"boolean\"}\n",
+ "Elden_Ring_Diffusion_v3 = False #@param {type: \"boolean\"}\n",
+ "Robo_Diffusion_v2 = False #@param {type: \"boolean\"}\n",
+ "Van_Gogh_Diffusion_v1 = False #@param {type: \"boolean\"}\n",
+ "PaperCut_Model_v1 = False #@param {type: \"boolean\"}\n",
+ "\n",
+ "#@markdown Miscellaneous\n",
+ "App_Icons_Generator_DreamBooth_v1 = False #@param {type: \"boolean\"}\n",
+ "\n",
+ "#-=-=-=-#\n",
+ "\n",
+ "try:\n",
+ "\tchdir(path.join(__Path, \"models\"))\n",
+ "except NameError:\n",
+ "\traise SystemExit(\"Requirements weren't installed!\\nPlease run the first cell.\")\n",
+ "\n",
+ "__Models = {\n",
+ "\t# General Purpose\n",
+ "\t\"Stable_Diffusion_v15\": [\n",
+ "\t\t\"https://hf.co/runwayml/stable-diffusion-v1-5/resolve/main/v1-5-pruned-emaonly.ckpt\"\n",
+ "\t],\n",
+ "\t\"Stable_Diffusion_v14\": [\n",
+ "\t\t\"https://hf.co/CompVis/stable-diffusion-v-1-4-original/resolve/main/sd-v1-4.ckpt\"\n",
+ "\t],\n",
+ "\t\"OpenJourney_v4\": [\n",
+ "\t\t\"https://hf.co/prompthero/openjourney/resolve/main/mdjrny-v4.ckpt\"\n",
+ "\t],\n",
+ "\t\"DreamLike_PhotoReal_v2\": [\n",
+ "\t\t\"https://hf.co/dreamlike-art/dreamlike-photoreal-2.0/resolve/main/dreamlike-photoreal-2.0.ckpt\"\n",
+ "\t],\n",
+ "\t\"ProtoGen_v53\": [\n",
+ "\t\t\"https://hf.co/darkstorm2150/Protogen_x5.3_Official_Release/resolve/main/ProtoGen_X5.3-pruned-fp16.ckpt\"\n",
+ "\t],\n",
+ "\t# Anime\n",
+ "\t\"Novel_AI\": [\n",
+ "\t\t\"https://cloudflare-ipfs.com/ipfs/bafybeicpamreyp2bsocyk3hpxr7ixb2g2rnrequub3j2ahrkdxbvfbvjc4/model.ckpt\",\n",
+ "\t\t\"https://hf.co/WarriorMama777/OrangeMixs/resolve/main/VAEs/orangemix.vae.pt\"\n",
+ "\t],\n",
+ "\t\"AniReal_v1\": [\n",
+ "\t\t\"https://hf.co/Hosioka/AniReal/resolve/main/AniReal.safetensors\",\n",
+ "\t\t\"https://hf.co/Hosioka/AniReal/resolve/main/AniReal.vae.pt\"\n",
+ "\t],\n",
+ "\t\"Anything_v45\": [\n",
+ "\t\t\"https://hf.co/andite/anything-v4.0/resolve/main/anything-v4.5-pruned-fp16.ckpt\",\n",
+ "\t\t\"https://hf.co/andite/anything-v4.0/resolve/main/anything-v4.0.vae.pt\"\n",
+ "\t],\n",
+ "\t\"AbyssOrangeMix_v1\": [\n",
+ "\t\t\"https://hf.co/WarriorMama777/OrangeMixs/resolve/main/Models/AbyssOrangeMix/AbyssOrangeMix_base.ckpt\",\n",
+ "\t\t\"https://hf.co/WarriorMama777/OrangeMixs/resolve/main/VAEs/orangemix.vae.pt\"\n",
+ "\t],\n",
+ "\t\"BloodOrangeMix_v1\": [\n",
+ "\t\t\"https://hf.co/WarriorMama777/OrangeMixs/resolve/main/Models/BloodOrangeMix/BloodOrangeMix_half.ckpt\",\n",
+ "\t\t\"https://hf.co/WarriorMama777/OrangeMixs/resolve/main/VAEs/orangemix.vae.pt\"\n",
+ "\t],\n",
+ "\t\"PastelMix_v1\": [\n",
+ "\t\t\"https://hf.co/andite/pastel-mix/resolve/main/pastelmix-fp16.ckpt\",\n",
+ "\t\t\"https://hf.co/andite/pastel-mix/resolve/main/pastel-waifu-diffusion.vae.pt\"\n",
+ "\t],\n",
+ "\t\"Kenshi_v1\": [\n",
+ "\t\t\"https://hf.co/SweetLuna/Kenshi/resolve/main/KENSHI%2001/KENSHI01_Pruned.ckpt\",\n",
+ "\t\t\"https://hf.co/hakurei/waifu-diffusion-v1-4/resolve/main/vae/kl-f8-anime.ckpt\",\n",
+ "\t],\n",
+ "\t# Cartoon\n",
+ "\t\"Archer_Diffusion_v3\": [\n",
+ "\t\t\"https://hf.co/nitrosocke/archer-diffusion/resolve/main/archer-v1.ckpt\"\n",
+ "\t],\n",
+ "\t# Art\n",
+ "\t\"Seek_Art_Mega_v1\": [\n",
+ "\t\t\"https://hf.co/coreco/seek.art_MEGA/resolve/main/seek_art_mega_v1.ckpt\"\n",
+ "\t],\n",
+ "\t\"_3D_Style_v1\": [\n",
+ "\t\t\"https://hf.co/Guizmus/SD_DreamerCommunities_Collection/resolve/main/diffusers/3DStyle/3DStyle-v1.ckpt\"\n",
+ "\t],\n",
+ "\t\"Redshift_Diffusion_v1\": [\n",
+ "\t\t\"https://hf.co/nitrosocke/redshift-diffusion/resolve/main/redshift-diffusion-v1.ckpt\"\n",
+ "\t],\n",
+ "\t\"Elden_Ring_Diffusion_v3\": [\n",
+ "\t\t\"https://hf.co/nitrosocke/elden-ring-diffusion/resolve/main/eldenRing-v3-pruned.ckpt\"\n",
+ "\t],\n",
+ "\t\"Robo_Diffusion_v2\": [\n",
+ "\t\t\"https://hf.co/nousr/robo-diffusion-2-base/resolve/main/robo-diffusion-v2-base.ckpt\"\n",
+ "\t],\n",
+ "\t\"Van_Gogh_Diffusion_v1\": [\n",
+ "\t\t\"https://hf.co/dallinmackay/Van-Gogh-diffusion/resolve/main/Van-Gogh-Style-lvngvncnt-v2.ckpt\"\n",
+ "\t],\n",
+ "\t\"PaperCut_Model_v1\": [\n",
+ "\t\t\"https://hf.co/Fictiverse/Stable_Diffusion_PaperCut_Model/resolve/main/PaperCut_v1.ckpt\"\n",
+ "\t],\n",
+ "\t# Miscellaneous\n",
+ "\t\"App_Icons_Generator_DreamBooth_v1\": [\n",
+ "\t\t\"https://drive.google.com/uc?id=1TNZTQfk0CNZg7nwy033olwOpQAkcglAN\"\n",
+ "\t]\n",
+ "}\n",
+ "\n",
+ "if not any([eval(Key) for Key in __Models.keys()]):\n",
+ "\t# ๐ #\n",
+ "\traise Warning(\"What do you want to do?\")\n",
+ "\n",
+ "#-=-=-=-#\n",
+ "\n",
+ "# Verify URLs\n",
+ "print(f\"{__C_Green}Verifying URL existence{__C_Reset}\")\n",
+ "try:\n",
+ "\tfor Key, Value in __Models.items():\n",
+ "\t\tfor URL in Value:\n",
+ "\t\t\twith head(URL, headers={\"Authorization\": r\"Bearer {Token}\"}, allow_redirects = 1) as Site:\n",
+ "\t\t\t\tprint(f\"\\r\\t{URL}\", end = __Return)\n",
+ "\t\t\t\tif not Site.ok:\n",
+ "\t\t\t\t\traise SystemExit('Can\\'t fetch \"{0}\" file: {1} (\"{2}\").'.format(\n",
+ "\t\t\t\t\t\tSite.url.split(\"/\")[-1], Site.status_code, Site.reason\n",
+ "\t\t\t\t\t\t)\n",
+ "\t\t\t\t\t)\n",
+ "except KeyboardInterrupt:\n",
+ "\tpass\n",
+ "\n",
+ "IPython.display.clear_output()\n",
+ "\n",
+ "#-=-=-=-#\n",
+ "\n",
+ "for Key, Value in __Models.items():\n",
+ "\tif Key in locals():\n",
+ "\t\tif eval(Key):\n",
+ "\t\t\tprintC(Key, \"\")\n",
+ "\t\t\tfor Model_URL in Value:\n",
+ "\t\t\t\t# Diffusers\n",
+ "\t\t\t\tfor Format in (\"ckpt\", \"safetensors\"):\n",
+ "\t\t\t\t\tif Model_URL.lower().endswith(Format):\n",
+ "\t\t\t\t\t\tif all((Model_URL.lower().endswith(\"safetensors\"), \"Latest\" not in WebUI_Version)):\n",
+ "\t\t\t\t\t\t\traise Warning('\".safetensors\" model format isn\\'t supported in this version.\\nPlease read the first cell.')\n",
+ "\t\t\t\t\t\t\tbreak\n",
+ "\t\t\t\t\t\telse:\n",
+ "\t\t\t\t\t\t\tDirectory = path.abspath(\"Stable-diffusion\")\n",
+ "\t\t\t\t\t\t\tModel_Path = path.join(f\"{Key}.{Format}\")\n",
+ "\t\t\t\t# VAEs\n",
+ "\t\t\t\tfor Format in (\".vae.pt\", \".bin\"):\n",
+ "\t\t\t\t\tif Format in Model_URL.lower():\n",
+ "\t\t\t\t\t\tDirectory = path.abspath(\"VAE\")\n",
+ "\t\t\t\t\t\t#-=-=-=-#\n",
+ "\t\t\t\t\t\t__VAE_FP = Model_URL.lower().split(\"/\")[-1].split(\".\")[1:]\n",
+ "\t\t\t\t\t\t__VAE_FP = \".\".join(__VAE_FP)\n",
+ "\t\t\t\t\t\t__VAE_FP = \".\" + __VAE_FP.lstrip(\".\")\n",
+ "\t\t\t\t\t\t__VAE_FP = __VAE_FP.replace(\".0.vae.pt\", \".vae.pt\")\t# not fixing that\n",
+ "\t\t\t\t\t\t#-=-=-=-#\n",
+ "\t\t\t\t\t\tModel_Path = path.join(Key +__VAE_FP)\n",
+ "\t\t\t\tModel_Path = path.join(Directory, Model_Path)\n",
+ "\t\t\t\tprint(Model_Path)\n",
+ "\t\t\t\t#-=-=-=-#\n",
+ "\t\t\t\tif path.exists(Model_Path):\n",
+ "\t\t\t\t\tremove(Model_Path)\n",
+ "\t\t\t\t#-=-=-=-#\n",
+ "\t\t\t\ttry:\n",
+ "\t\t\t\t\tif \"drive.google\" in Model_URL.lower():\n",
+ "\t\t\t\t\t\t!gdown $Model_URL -O $Model_Path\n",
+ "\t\t\t\t\telse:\n",
+ "\t\t\t\t\t\t!curl \\\n",
+ "\t\t\t\t\t\t\t-A \"Mozilla/5.0 (iPhone; CPU iPhone OS 14_6 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.0.3 Mobile/15E148 Safari/604.1\" \\\n",
+ "\t\t\t\t\t\t\t-H \"$__Header\" \\\n",
+ "\t\t\t\t\t\t\t-Lo $Model_Path \\\n",
+ "\t\t\t\t\t\t\t$Model_URL\n",
+ "\t\t\t\t\t\tprint()\n",
+ "\t\t\t\texcept KeyboardInterrupt:\n",
+ "\t\t\t\t\tprint(f'Cancelled download of the \"{Key}\" model.')"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "cellView": "form",
+ "id": "2KMeCP1nejQh"
+ },
+ "source": [
+ "#@title ## **3.** Run.\n",
+ "Language = \"๐บ๐ธ English\" #@param [\"๐จ๐ณ Chinese (Simplified)\", \"๐จ๐ณ Chinese (Traditional)\", \"๐บ๐ธ English\", \"๐ฉ๐ช German\", \"๐ฎ๐น Italian\", \"๐ฏ๐ต Japanese\", \"๐ฐ๐ท Korean\", \"๐ณ๐ด Norwegian\", \"๐ต๐น Portuguese\", \"๐ช๐ธ Spanish\", \"๐น๐ท Turkish\"]\n",
+ "#@markdown โ ๏ธ **Doesn't work if `WebUI_Version` is not `Latest`.** \n",
+ "\n",
+ "#@markdown ---\n",
+ "Alert_Notification = True #@param {\"type\": \"boolean\"}\n",
+ "#@markdown โ ๏ธ **Check only if you are running all subcells from the `Main` at the same time.** \n",
+ "\n",
+ "#@markdown ---\n",
+ "Debug_Mode = True #@param {\"type\": \"boolean\"}\n",
+ "#@markdown Launch **even if no models were installed** .\n",
+ "\n",
+ "#@markdown ---\n",
+ "\n",
+ "try:\n",
+ "\timport fastapi\n",
+ "except ImportError:\n",
+ "\traise SystemExit(\"GPU Requirements weren't installed!\\nPlease run the first cell.\")\n",
+ "\n",
+ "#-=-=-=-#\n",
+ "\n",
+ "Language = \" \".join(Language.split(\" \")[1:])\n",
+ "__Languages = {\n",
+ "\t\t\"Chinese (Simplified)\": \"zh_CN\",\n",
+ "\t\t\"Chinese (Traditional)\": \"zh_TW\",\n",
+ "\t\t\"Deutsch\": \"de_DE\",\n",
+ "\t\t\"English\": \"None\",\n",
+ "\t\t\"Italian\": \"it_IT\",\n",
+ "\t\t\"Japanese\": \"ja_JP\",\n",
+ "\t\t\"Korean\": \"ko_KR\",\n",
+ "\t\t\"Norwegian\": \"no_NO\",\n",
+ "\t\t\"Portuguese\": \"pt_BR\",\n",
+ "\t\t\"Spanish\": \"es_ES\",\n",
+ "\t\t\"Turkish\": \"tr_TR\"\n",
+ "}\n",
+ "\n",
+ "chdir(__Path)\n",
+ "with open(\"config.json\", \"r+\") as File:\n",
+ "\tData = json.load(File)\n",
+ "\t#-=-=-=#\n",
+ "\tif \"Latest\" in WebUI_Version:\n",
+ "\t\tData[\"localization\"] = __Languages[Language]\n",
+ "\t\tMSG = f\"Launguage set to {Language}.\"\n",
+ "\telse:\n",
+ "\t\tMSG = \"Using older version, cannot change language.\"\n",
+ "\tprint(MSG)\n",
+ "\t#-=-=-=-#\n",
+ "\tFile.seek(0)\n",
+ "\tjson.dump(Data, File, indent = 4)\n",
+ "\tFile.truncate()\n",
+ "\n",
+ "print()\n",
+ "print(\"โ\" * 32)\n",
+ "\n",
+ "#-=-=-=-#\n",
+ "\n",
+ "Debug_Flag = \"\"\n",
+ "if not len(list(Path().rglob(\"*.ckpt\"))):\n",
+ "\tprint()\n",
+ "\tif not Debug_Mode:\n",
+ "\t\traise SystemExit(\"No models found, exiting.\\nPlease run subcell 2 from `Main` cell to install models.\")\n",
+ "\telse:\n",
+ "\t\tprint(\"No models detected, running in the debug mode.\")\n",
+ "\t\tDebug_Flag = \"--ui-debug-mode\"\n",
+ "\n",
+ "#-=-=-=-#\n",
+ "\n",
+ "# Reserve RAM space\n",
+ "collect()\n",
+ "empty_cache()\n",
+ "\n",
+ "print()\n",
+ "if Alert_Notification:\n",
+ "\tdisplay(IPython.display.Javascript('alert(\"Starting soon...\")'))\n",
+ "\n",
+ "!$Python webui.py \\\n",
+ "\t--no-half \\\n",
+ "\t--allow-code \\\n",
+ "\t--precision full \\\n",
+ "\t--share \\\n",
+ "\t$Debug_Flag \\\n",
+ "\t--autolaunch \\\n",
+ "\t--disable-safe-unpickle"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "PbAjvcMog1LM"
+ },
+ "source": [
+ "## โ๏ธ Useful optional postprocessing commands (***use after *** session ends)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "cellView": "form",
+ "id": "sLOycNVfacB9"
+ },
+ "source": [
+ "#@title ### ๐ผ๏ธ Convert all output images to HQ `JPG` and optimize ๐\n",
+ "#@markdown ## โ ๏ธ **This cell can only be run once!!!** \n",
+ "\n",
+ "try:\n",
+ "\tchdir(path.join(__Path, \"outputs\"))\n",
+ "except NameError:\n",
+ "\traise SystemExit(\"Requirements weren't installed!\\nPlease run the first cell.\")\n",
+ "\n",
+ "#-=-=-=-#\n",
+ "\n",
+ "__Size_In = DirSize(\".\")\n",
+ "__Counter = 1\n",
+ "__Images = []\n",
+ "\n",
+ "# Add Images\n",
+ "for File in Path().rglob(\"*\"):\n",
+ "\tFile = path.abspath(str(File.resolve()))\n",
+ "\tif path.exists(File):\n",
+ "\t\tif path.isfile(File):\n",
+ "\t\t\t__Images += [File]\n",
+ "\n",
+ "# Convert Images\n",
+ "for File in __Images:\n",
+ "\tprint(f\"\\r[{__Counter}/{len(__Images)}] Converting images...\", end = __Return)\n",
+ "\t#-=-=-=-#\n",
+ "\tName = path.splitext(File)[0] + \".jpg\"\n",
+ "\t#-=-=-=-#\n",
+ "\tIMG = cv2.imread(File)\n",
+ "\tIMG = cv2.cvtColor(IMG, cv2.COLOR_BGR2RGB)\n",
+ "\tcv2.imwrite(Name, IMG, [int(cv2.IMWRITE_JPEG_QUALITY), 100])\n",
+ "\tremove(File)\n",
+ "\t#-=-=-=-#\n",
+ "\t!jpegoptim -o -m 100 --all-progressive --strip-all \"$Name\" -q\n",
+ "\t__Counter += 1\n",
+ "\n",
+ "#-=-=-=-#\n",
+ "\n",
+ "__Size_Out = DirSize(\".\")\n",
+ "\n",
+ "if __Size_In == __Size_Out:\n",
+ "\t__Percentage = \"0.00\"\n",
+ "else:\n",
+ "\t__Percentage = round((100 - (__Size_Out / __Size_In) * 100), 2)\n",
+ "\n",
+ "__Size_Reduced = HumanReadableSize(__Size_In - __Size_Out)\n",
+ "__Size_In = HumanReadableSize(__Size_In)\n",
+ "__Size_Out = HumanReadableSize(DirSize(\".\"))\n",
+ "\n",
+ "print(f\"\\nSize reduced from {__Size_In} to {__Size_Out} (-{__Size_Reduced}, {__Percentage}%)\")"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "cellView": "form",
+ "id": "81bkjYwJg1LP"
+ },
+ "source": [
+ "#@title ### ๐๏ธ Output images management\n",
+ "\n",
+ "try:\n",
+ "\tif not path.exists(path.join(__Path, \"outputs/\")):\n",
+ "\t\traise NameError\n",
+ "except NameError:\n",
+ "\traise SystemExit(\"Requirements weren't installed!\\nPlease run the first cell.\")\n",
+ "\n",
+ "chdir(path.join(__Path, \"outputs/\"))\n",
+ "\n",
+ "__Date = str(time()).split(\".\")[-1]\n",
+ "\n",
+ "#-=-=-=-#\n",
+ "\n",
+ "Action = \"๐ฅ Get Archive\" #@param [\"๐ฅ Get Archive\", \"๐ค Copy pictures to Google Drive\"]\n",
+ "if \"Archive\" in Action:\n",
+ "\t__Counter = 1\n",
+ "\tArchive_Name = path.abspath(\"/content/\" + \"_\".join([\n",
+ "\t\t\"SD WebUI\", Path().resolve().name.title(), __Date\n",
+ "\t\t]) + \".zip\"\n",
+ "\t).replace(\" \", \"_\")\n",
+ "\t#-=-=-=-#\n",
+ "\tif path.exists(Archive_Name):\n",
+ "\t\tremove(Archive_Name)\n",
+ "\t#-=-=-=-#\n",
+ "\t__Outputs = [\"./\" + str(File.resolve()).split(getcwd())[-1] for File in Path().rglob(\"*\")]\n",
+ "\ttry:\n",
+ "\t\twith ZipFile(Archive_Name, \"w\", 14) as Archive:\n",
+ "\t\t\tfor File in __Outputs:\n",
+ "\t\t\t\tprint(f\"\\r[{__Counter}/{len(__Outputs)}] Adding \"{File}\" to archive...\", end = __Return)\n",
+ "\t\t\t\tArchive.write(File)\n",
+ "\t\t\t\t__Counter += 1\n",
+ "\texcept OSError:\n",
+ "\t\tremove(Archive_Name)\n",
+ "\texcept KeyboardInterrupt:\n",
+ "\t\tprint(\"File packing interrupted, saving.\")\n",
+ "\tprint()\n",
+ "\tif is_Colab:\n",
+ "\t\tfiles.download(Archive_Name)\n",
+ "\telse:\n",
+ "\t\tprint(\"\\nDone!\")\n",
+ "elif is_Colab:\n",
+ "\ttry:\n",
+ "\t\tdrive.mount(\"/content/drive\", force_remount = 0)\n",
+ "\texcept:\n",
+ "\t\tprint(\" mounting drive / with drive path variables\")\n",
+ "\t!cp -r /outputs \"/content/drive/MyDrive/!_SD_WebUI/Images/$__Date\"\n",
+ "else:\n",
+ "\traise Warning(\"Not in Google Colab, cannot upload.\")"
+ ]
+ }
+ ]
+}
\ No newline at end of file
diff --git a/Notebooks/General/Math/Music/Calculators.ipynb b/Notebooks/General/Math/Music/Calculators.ipynb
new file mode 100644
index 0000000..1950f70
--- /dev/null
+++ b/Notebooks/General/Math/Music/Calculators.ipynb
@@ -0,0 +1,179 @@
+{
+ "nbformat": 4,
+ "nbformat_minor": 0,
+ "metadata": {
+ "colab": {
+ "name": "Music Calculators",
+ "provenance": []
+ },
+ "kernelspec": {
+ "name": "python3",
+ "display_name": "Python 3"
+ },
+ "language_info": {
+ "name": "python"
+ }
+ },
+ "cells": [
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": ""
+ },
+ "source": [
+ "Music functions related to pitch and time. ๐ถ "
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": ""
+ },
+ "source": [
+ "# **Various** โ๏ธ"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "",
+ "cellView": "form"
+ },
+ "source": [
+ "#@title ## Closest value to given BPM that can be used for *Dancing Waveform Experiment*\n",
+ "#@markdown Float values are esmaited.\n",
+ "BPM = 130.000 #@param {type:\"number\"}\n",
+ "#---#\n",
+ "\n",
+ "BPMs = []\n",
+ "Values = []\n",
+ "\n",
+ "#---#\n",
+ "\n",
+ "def frange(start = 0, stop = None, step = 1) -> list:\n",
+ "\t\"\"\"Range with floats support\"\"\"\n",
+ "\tn = int(round((stop - start)/float(step)))\n",
+ "\tif n > 1:\n",
+ "\t\treturn [start + step*i for i in range(n+1)]\n",
+ "\telif n == 1:\n",
+ "\t\treturn [start]\n",
+ "\telse:\n",
+ "\t\treturn []\n",
+ "\n",
+ "for Value in frange(1, BPM, 0.001):\n",
+ "\tValues += [round(Value, 3)]\n",
+ "\n",
+ "for BPM in Values:\n",
+ "\tif not len(str(BPM / 60).split(\".\")[-1]) > 2:\n",
+ "\t\tBPMs += [BPM]\n",
+ "\n",
+ "print(min(BPMs, key = lambda Value: abs(Value - BPM)), \"BPM\")"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "",
+ "cellView": "form"
+ },
+ "source": [
+ "#@title ## Time stretch or pitch shift required to convert `From` BPM to `Target` BPM.\n",
+ "#@markdown Works with sample rates too.\n",
+ "From = 135 #@param {type: \"number\"}\n",
+ "Target = 120 #@param {type: \"number\"}\n",
+ "\n",
+ "from math import *\n",
+ "Result_Pitch = ceil((1200 / log(2)) * log(Target / From))\n",
+ "Result_Time = 100 * (From / Target)\n",
+ "\n",
+ "print(\"Time stretch:\\t\" + str(round(Result_Time, 3)) + \"%\")\n",
+ "print(\"Pitch shift:\\t\" + str(Result_Pitch), \"cents\")"
+ ],
+ "outputs": [
+ {
+ "output_type": "stream",
+ "name": "stdout",
+ "text": [
+ "Time stretch:\t112.5%\n",
+ "Pitch shift:\t-203 cents\n"
+ ]
+ }
+ ]
+ },
+ {
+ "cell_type": "code",
+ "source": [
+ "#@title ## Resample by cents.\n",
+ "#@markdown Values are esmaited.\n",
+ "SampleRate = 44100 #@param {type: \"number\"}\n",
+ "Resample_by = -50 #@param {type: \"number\"}\n",
+ "\n",
+ "if Resample_by < 0:\n",
+ "\tSign = \"\"\n",
+ "\tResample_by_Display = \" \".join((str(Resample_by)[0], str(Resample_by)[1:]))\n",
+ "else:\n",
+ "\tSign = \"+ \"\n",
+ "\tResample_by_Display = Resample_by\n",
+ "\n",
+ "from math import *\n",
+ "for Frequency in range(1, SampleRate):\n",
+ "\tResult = (1200 / log(2)) * log(Frequency / SampleRate * 2)\n",
+ "\tif round(Result) == Resample_by:\n",
+ "\t\tif Resample_by:\n",
+ "\t\t\tFrequency *= 2\n",
+ "\t\telse:\n",
+ "\t\t\tFrequency = SampleRate\n",
+ "\t\tprint(f\"{SampleRate} Hz {Sign}{Resample_by_Display} cents โ {Frequency} Hz\")\n",
+ "\t\tbreak"
+ ],
+ "metadata": {
+ "id": "",
+ "cellView": "form"
+ },
+ "outputs": [
+ {
+ "output_type": "stream",
+ "name": "stdout",
+ "text": [
+ "44100 Hz - 50 cents โ 42834 Hz\n"
+ ]
+ }
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "gYRXEkCeHtg1"
+ },
+ "source": [
+ "# ๐ **Time**"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "",
+ "cellView": "form"
+ },
+ "source": [
+ "#@title ## Length of beat and bar. (`4/4`)\n",
+ "BPM = 135.000 #@param {type:\"number\"}\n",
+ "\n",
+ "print(f\"\"\"\n",
+ "Length of one beat:\\t60 รท {BPM} โ {str(round(60 / BPM, 5))} s\n",
+ "Length of one bar:\\t240 รท {BPM} โ {str(round(240 / BPM, 5))} s\n",
+ "\"\"\"[1:-1])"
+ ],
+ "outputs": [
+ {
+ "output_type": "stream",
+ "name": "stdout",
+ "text": [
+ "Length of one beat:\t60 รท 120 โ 0.5 s\n",
+ "Length of one bar:\t240 รท 120 โ 2.0 s\n"
+ ]
+ }
+ ]
+ }
+ ]
+}
\ No newline at end of file
diff --git a/Notebooks/General/Media/Audio/Unisonizer.ipynb b/Notebooks/General/Media/Audio/Unisonizer.ipynb
new file mode 100644
index 0000000..2615f38
--- /dev/null
+++ b/Notebooks/General/Media/Audio/Unisonizer.ipynb
@@ -0,0 +1,158 @@
+{
+ "nbformat": 4,
+ "nbformat_minor": 0,
+ "metadata": {
+ "colab": {
+ "name": "Unisonizer",
+ "provenance": [],
+ "collapsed_sections": []
+ },
+ "kernelspec": {
+ "name": "python3",
+ "display_name": "Python 3"
+ }
+ },
+ "cells": [
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": ""
+ },
+ "source": [
+ "Upload as many files as You want.\n",
+ "Notebook will automatically create exclusive folders for them. ๐\n"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "cellView": "form",
+ "id": ""
+ },
+ "source": [
+ "#@title โ Install modules. **(Required for the first time usage!)**\n",
+ "%%capture\n",
+ "!rm -rf sample_data\n",
+ "!python -m pip install py7zr pydub"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "",
+ "cellView": "form"
+ },
+ "source": [
+ "#@title โ Remove ALL files. This action is irreversible! \n",
+ "#@markdown - **Required to restart processing!**\n",
+ "%%capture\n",
+ "%cd /content\n",
+ "!rm -rf *"
+ ],
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "",
+ "cellView": "form"
+ },
+ "source": [
+ "#@title โ Upload files and Unisonize! \n",
+ "import os\n",
+ "from py7zr import *\n",
+ "from pydub import *\n",
+ "from IPython.display import *\n",
+ "from datetime import datetime\n",
+ "from google.colab import files\n",
+ "from itertools import zip_longest\n",
+ "\n",
+ "#---#\n",
+ "\n",
+ "__author__ = \"kubinka0505\"\n",
+ "__credits__ = __author__\n",
+ "__version__ = \"1.0\"\n",
+ "__date__ = \"07.02.2021\"\n",
+ " \n",
+ "#---#\n",
+ "\n",
+ "Format = \"WAV\" #@param [\"MP3\", \"OGG\", \"WAV\", \"FLAC\"]\n",
+ "Invert_Phase_for_Even_Files = False #@param {type:\"boolean\"}\n",
+ "\n",
+ "#@markdown - After processing files will be packed to `Audio.7z` archive and **downloaded automatically**.\n",
+ "\n",
+ "#---#\n",
+ "\n",
+ "os.chdir(\"/content/\")\n",
+ "\n",
+ "__Time = \"\".join(list(filter(lambda s:s.isdigit(),str(datetime.now()).split(\" \")[1].split(\".\")[0])))\n",
+ "ArchiveName = \"Audio_{0}.7z\".format(__Time)\n",
+ "AfterName = \"_stereo\"\n",
+ "\n",
+ "if os.listdir() == [\".config\", \".ipynb_checkpoints\"]: Files = files.upload()\n",
+ "\n",
+ "Files = sorted([x for x in os.listdir() if x.endswith(\".{0}\".format(Format.lower()))], key = str)\n",
+ "Files_Sorted = [[y, x] for x, y in zip_longest(Files[1::2], Files[::2])]\n",
+ "\n",
+ "# Create folder for each uploaded file\n",
+ "for _Files in Files_Sorted:\n",
+ "\tFolderName = _Files[0].split(\".\")[0]\n",
+ "\tos.mkdir(FolderName)\n",
+ "\tos.rename(_Files[0], \"{0}/{1}\".format(FolderName, _Files[0]))\n",
+ "\tos.rename(_Files[1], \"{0}/{1}\".format(FolderName, _Files[1]))\n",
+ "\n",
+ "Folders = sorted(next(os.walk(\".\"))[1], key = str)[2:]\n",
+ "\n",
+ "# Modify each audio file in previously created folders\n",
+ "for Folder in Folders:\n",
+ "\tos.chdir(\"/content/{0}\".format(Folder))\n",
+ "\n",
+ "\tFiles__ = os.listdir()\n",
+ "\n",
+ "\tName = \"{0}{1}.{2}\".format(Files__[0].split(\".\")[0], AfterName, Format.lower())\n",
+ "\n",
+ "\t#---#\n",
+ "\n",
+ "\tprint(\"\\r\", end = \"Processing {0}...\".format(Folder))\n",
+ "\tLeft = AudioSegment.from_file(Files__[0])\n",
+ "\tRight = AudioSegment.from_file(Files__[1])\n",
+ "\tif Invert_Phase_for_Even_Files == True: Right = Right.invert_phase()\n",
+ "\n",
+ "\tLeft = Left.pan(-1)\n",
+ "\tRight = Right.pan(1)\n",
+ "\n",
+ "\tLeft = Left.normalize(headroom = 0)\n",
+ "\tRight = Right.normalize(headroom = 0)\n",
+ "\n",
+ "\tMulti = Left.overlay(Right)\n",
+ "\tMulti = Multi.normalize(headroom = 0)\n",
+ "\n",
+ "\tMulti.export(Name, format = Format)\n",
+ "\n",
+ "\t# Move modified file and remove uploaded files\n",
+ "\tos.remove(Files__[0])\n",
+ "\tos.remove(Files__[1])\n",
+ "\tos.rename(\"{0}/{1}\".format(os.getcwd(), Name), \"{0}/{1}\".format(os.path.realpath(\"..\"), Name))\n",
+ "\tos.rmdir(os.getcwd())\n",
+ "\tos.chdir(\"..\")\n",
+ "\n",
+ "os.chdir(\"/content/\")\n",
+ "with SevenZipFile(\n",
+ "\tArchiveName,\n",
+ "\t\"w\",\n",
+ "\tfilters = [{\"id\": FILTER_LZMA2, \"preset\": PRESET_DEFAULT}]\n",
+ "\t) as Archive:\n",
+ "\t\tfor x in os.listdir():\n",
+ "\t\t\tif x.endswith(Format.lower()):\n",
+ "\t\t\t\tArchive.write(x)\n",
+ "\n",
+ "if len(os.listdir()) != 2: files.download(ArchiveName)"
+ ],
+ "execution_count": null,
+ "outputs": []
+ }
+ ]
+}
diff --git a/Notebooks/General/Media/Visual/Mixed/Hybrid_Image_Video_Cropper/Vertical.ipynb b/Notebooks/General/Media/Visual/Mixed/Hybrid_Image_Video_Cropper/Vertical.ipynb
new file mode 100644
index 0000000..9a62ddc
--- /dev/null
+++ b/Notebooks/General/Media/Visual/Mixed/Hybrid_Image_Video_Cropper/Vertical.ipynb
@@ -0,0 +1,233 @@
+{
+ "nbformat": 4,
+ "nbformat_minor": 0,
+ "metadata": {
+ "colab": {
+ "name": "Hybrid Image / Video Cropper [Vertical]",
+ "provenance": [],
+ "collapsed_sections": []
+ },
+ "kernelspec": {
+ "name": "python3",
+ "display_name": "Python 3"
+ },
+ "language_info": {
+ "name": "python"
+ }
+ },
+ "cells": [
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "",
+ "cellView": "form"
+ },
+ "outputs": [],
+ "source": [
+ "#@title # **1. ** Upload files and setup code\n",
+ "Static_Image_URL = \"\" #@param {type: \"string\"}\n",
+ "Audio_Top_URL = \"\" #@param {type: \"string\"}\n",
+ "Audio_Bottom_URL = \"\" #@param {type: \"string\"}\n",
+ "#@markdown โน๏ธ Leave empty for manual upload.\n",
+ "\n",
+ "#-=-=-=-#\n",
+ "\n",
+ "!pip install ffpb mutagen -q\n",
+ "\n",
+ "import os\n",
+ "from zipfile import *\n",
+ "from PIL import Image as IMG\n",
+ "from base64 import b64encode\n",
+ "from requests import Session\n",
+ "from shutil import copyfileobj\n",
+ "from google.colab import files\n",
+ "from mutagen import File as mFile\n",
+ "from IPython.display import display, HTML\n",
+ "\n",
+ "#-=-=-=-#\n",
+ "\n",
+ "!rm -rf *\n",
+ "Error = lambda exc: SystemExit(exc[0].upper() + exc[1:] + \".\")\n",
+ "\n",
+ "session = Session()\n",
+ "session.headers.update(\n",
+ "\t{\n",
+ "\t\t\"User-Agent\":\n",
+ "\t\t\"Mozilla/5.0 (Windows NT 10.0; Win32; x32) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36\"\n",
+ "\t}\n",
+ ")\n",
+ "get = session.get\n",
+ "\n",
+ "def Clamp(Number: float, Minimum: float, Maximum: float) -> float:\n",
+ "\t\"\"\"Limits `Number` in range (`Minimum`, `Maximum`).\"\"\"\n",
+ "\treturn max(min(Maximum, Number), Minimum)\n",
+ "\n",
+ "def Download(URL: str, Verbose: bool = True) -> str:\n",
+ "\t\"\"\"Downloads the URL to local directory.\"\"\"\n",
+ "\tURL = URL.split(\"#\")[0].split(\"?\")[0].split(\"&\")[0]\n",
+ "\tFile_Name = URL.split(\"/\")[-1]\n",
+ "\t#-=-=-=-#\n",
+ "\ttry:\n",
+ "\t\twith get(URL, stream = 1) as Site:\n",
+ "\t\t\tif Site.ok:\n",
+ "\t\t\t\twith open(File_Name, \"wb\") as File:\n",
+ "\t\t\t\t\tif Verbose:\n",
+ "\t\t\t\t\t\tprint(f\"Downloading {File_Name}...\")\n",
+ "\t\t\t\t\tcopyfileobj(Site.raw, File)\n",
+ "\t\t\telse:\n",
+ "\t\t\t\traise Error(f\"URL returned status code {Site.stats_code} - {Site.reason.title()}\")\n",
+ "\texcept OSError:\n",
+ "\t\traise Error(\"Invalid URL\")\n",
+ "\t#-=-=-=-#\n",
+ "\treturn File_Name\n",
+ "\n",
+ "#-=-=-=-#\n",
+ "\n",
+ "Files_Upload_Dict = {\n",
+ "\t\"Static_Image\": Static_Image_URL,\n",
+ "\t\"Audio_Top\": Audio_Top_URL,\n",
+ "\t\"Audio_Bottom\": Audio_Bottom_URL\n",
+ "}\n",
+ "\n",
+ "for Key, Value in Files_Upload_Dict.items():\n",
+ "\tif \"Top\" in Key:\n",
+ "\t\tif not Value:\n",
+ "\t\t\tprint()\n",
+ "\t#-=-=-=-#\n",
+ "\tif Value:\n",
+ "\t\texec(f'{Key} = Download(\"{Value}\")')\n",
+ "\telse:\n",
+ "\t\tprint(f'Upload {\" \".join(Key.split(\"_\")).upper()}...')\n",
+ "\t\ttry:\n",
+ "\t\t\texec(f\"{Key} = list(files.upload().keys())[-1]\")\n",
+ "\t\texcept:\n",
+ "\t\t\traise Error(\"File selection aborted\")\n",
+ "\texec(f'{Key} = {Key}.split(os.sep)[-1]')\n",
+ "\n",
+ "IMG_File = Static_Image\n",
+ "SND_Top = Audio_Top\n",
+ "SND_Bottom = Audio_Bottom\n",
+ "\n",
+ "#-=-=-=-#\n",
+ "\n",
+ "print(\"\\nUploaded successfully!\")"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "source": [
+ "#@title # **2. ** Encode\n",
+ "#@markdown ## Video ๐น\n",
+ "Preview_Width = 250 #@param {type: \"slider\", min: 75, max: 500, step: 1}\n",
+ "Preview_Width = str(Preview_Width)\n",
+ "\n",
+ "#@markdown ---\n",
+ "#@markdown ## Audio ๐\n",
+ "Top_Gain = -2.5 #@param {type: \"slider\", min: -5, max: 5, step: 0.1}\n",
+ "Inverse_Positions = False #@param {type: \"boolean\"}\n",
+ "\n",
+ "Top_Gain = str(Top_Gain)\n",
+ "if Inverse_Positions:\n",
+ "\tSND1 = SND_Top\n",
+ "\tSND2 = SND_Bottom\n",
+ "\t#-=-=-=-#\n",
+ "\tSND_Top = SND2\n",
+ "\tSND_Bottom = SND1\n",
+ "\t#-=-=-=-#\n",
+ "\tdel SND1, SND2\n",
+ "\n",
+ "#-=-=-=-#\n",
+ "\n",
+ "Video = \".\".join(IMG_File.split(os.sep)[-1].replace(\" \", \"_\").split(\".\")[:-1])\n",
+ "\n",
+ "env = os.environ\n",
+ "env[\"IMG\"] = IMG_File\n",
+ "\n",
+ "Minimum_Bitrate = 16 * 6\n",
+ "for Key, Value in {\"Top\": 1, \"Bottom\": 2}.items():\n",
+ "\tSND = \"SND_\" + Key\n",
+ "\n",
+ "\t_AF = \"AF_\" + Key\n",
+ "\t_Box = \"Box_\" + Key\n",
+ "\t_Gain = \"Gain_\" + Key\n",
+ "\t_Bitrate = \"Bitrate_\" + Key\n",
+ "\t_Duration = \"Duration_\" + Key\n",
+ "\t_Video = \"Video_\" + Key\n",
+ "\n",
+ "\t#-=-=-=-#\n",
+ "\n",
+ "\ttry:\n",
+ "\t\texec(f'{_AF} = mFile({SND})')\n",
+ "\t\tenv[SND] = eval(SND)\n",
+ "\texcept:\n",
+ "\t\traise Error(\"Files not found\")\n",
+ "\tenv[_Bitrate] = str(eval(\n",
+ "\t\tf\"Clamp({_AF}.info.bitrate // 1000, Minimum_Bitrate, Minimum_Bitrate * 4)\"\n",
+ "\t\t)\n",
+ "\t)\n",
+ "\tenv[_Box] = \"iw:ih/2:0:0\" if Key == \"Top\" else \"iw:ih/2:0:ih/2\"\n",
+ "\tenv[_Gain] = Top_Gain if Key == \"Top\" else \"0\"\n",
+ "\tenv[_Bitrate] += \"k\"\n",
+ "\tenv[_Duration] = str(eval(f\"{_AF}.info.length\"))\n",
+ "\tenv[_Video] = Video + f\"_{Value}.mp4\"\n",
+ "\tprint(f\"Encoding {Key.lower()} video...\")\n",
+ "\n",
+ "\t#-=-=-=-#\n",
+ "\n",
+ "\t!ffpb -y -strict 2 -loop 1 -ss 0 -i \"{IMG_File}\" -i \"{env[SND]}\" \\\n",
+ "\t-movflags faststart \\\n",
+ "\t-vf \"pad=ceil(iw/2)*2:ceil(ih/2)*2,crop={env[_Box]}\" \\\n",
+ "\t-af \"volume={env[_Gain]}dB\" \\\n",
+ "\t-pix_fmt yuv420p -tune stillimage -sws_flags lanczos \\\n",
+ "\t-c:v libx264 -c:a aac -b:a {env[_Bitrate]} -to {env[_Duration]} \"{env[_Video]}\"\n",
+ "\t\n",
+ "\t#-=-=-=-#\n",
+ "\n",
+ "\tprint()\n",
+ "\n",
+ "#-=-=-=-#\n",
+ "\n",
+ "\n",
+ "display(\n",
+ "\tHTML(\"\"\"\n",
+ "\t\t \n",
+ "\t\t\n",
+ "\t\t\t\n",
+ "\t\t\t\t\n",
+ "\t\t\t \n",
+ "\t\t\t\n",
+ "\t\t\t\t\n",
+ "\t\t\t \n",
+ "\t\t
\n",
+ "\t\t \n",
+ "\t\"\"\".format(\n",
+ "\t\t\"data:video/mp4;base64,\" + b64encode(open(f\"{Video}_1.mp4\", \"rb\").read()).decode(),\n",
+ "\t\t\"data:video/mp4;base64,\" + b64encode(open(f\"{Video}_2.mp4\", \"rb\").read()).decode(),\n",
+ "\t\tPreview_Width\n",
+ "\t\t,)\n",
+ "\t)\n",
+ ")\n",
+ "\n",
+ "#-=-=-=-#\n",
+ "\n",
+ "os.chdir(\"/content/\")\n",
+ "print(\"Downloading archive...\")\n",
+ "Archive_Name = f\"{Video}_SBS.zip\"\n",
+ "Archive = ZipFile(Archive_Name, \"w\", 14)\n",
+ "for Number in [1, 2]:\n",
+ "\tArchive.write(f\"{Video}_{str(Number)}.mp4\")\n",
+ "\n",
+ "files.download(Archive_Name)"
+ ],
+ "metadata": {
+ "id": "",
+ "cellView": "form"
+ },
+ "outputs": []
+ }
+ ]
+}
\ No newline at end of file
diff --git a/Notebooks/General/Media/Visual/Video/Simple_Video_Re-Encoder.ipynb b/Notebooks/General/Media/Visual/Video/Simple_Video_Re-Encoder.ipynb
new file mode 100644
index 0000000..78684d0
--- /dev/null
+++ b/Notebooks/General/Media/Visual/Video/Simple_Video_Re-Encoder.ipynb
@@ -0,0 +1,221 @@
+{
+ "nbformat": 4,
+ "nbformat_minor": 0,
+ "metadata": {
+ "colab": {
+ "name": "Simple Video Re-Encoder",
+ "provenance": [],
+ "collapsed_sections": []
+ },
+ "kernelspec": {
+ "display_name": "Python 3",
+ "name": "python3"
+ },
+ "language_info": {
+ "name": "python"
+ }
+ },
+ "cells": [
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": ""
+ },
+ "source": [
+ "# *Simple Video Re-Encoder*\n",
+ "Made with `FFmpeg`"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "",
+ "cellView": "form"
+ },
+ "source": [
+ "#@title # โฎ Upload and process video\n",
+ "#@markdown ##### ...after filling the forms below โฌ๏ธ\n",
+ "#@markdown ---\n",
+ "\n",
+ "#@markdown ## `File ๐`\n",
+ "URL = \"\" #@param {type:\"string\"}\n",
+ "Keep_Metadata = False #@param {type:\"boolean\"}\n",
+ "Output_Preview_Volume = 7.5 #@param {type:\"slider\", min:0.1, max:50, step:0.1}\n",
+ "#@markdown ## `Audio ๐`\n",
+ "Channels = \"Copy\" #@param [\"Mono\", \"Stereo\", \"Copy\"]\n",
+ "Bitrate_kbps = \"320\" #@param ['320', '256', '224', '192', '160', '128', '96']\n",
+ "Samplerate_Hz = \"Copy\" #@param [\"48 000\", \"44 100\", \"32 000\", \"Copy\"]\n",
+ "#@markdown ## `Video ๐ฅ`\n",
+ "Bitrate_mbps = \"Copy\" #@param [\"10\", \"9\", \"8\", \"7\", \"6\", \"5\", \"4\", \"3\", \"2\", \"Copy\"]\n",
+ "Output_Format_and_Codec = \"MP4 (x264)\" #@param [\"MP4 (x264)\", \"WEBM (VP9)\"]\n",
+ "#@markdown ---\n",
+ "#@markdown ## Notes โ ๏ธ\n",
+ "#@markdown - All previous files are removed on each new upload.\n",
+ "#@markdown - `Copy` statement means inheritance of original attribute of uploaded file.\n",
+ "\n",
+ "URL = URL.split(\"?\")[0].split(\"#\")[0]\n",
+ "Keep_Metadata = \"-map 0 -map_metadata 0:s:0 \" if not Keep_Metadata else \"\"\n",
+ "Output_Preview_Volume /= 100\n",
+ "Audio_Channels = (\"-ac \" + (\"1\" if Channels == \"Mono\" else \"2\")) if not Channels == \"Copy\" else \"\"\n",
+ "Audio_Bitrate = \"-b:a \" + str(Bitrate_kbps) + \"k\"\n",
+ "Samplerate = (\"-ar \" + Samplerate_Hz.replace(\" \", \"\")) if not Samplerate_Hz == \"Copy\" else \"\"\n",
+ "Video_Bitrate = (\"-b:v \" + str(int(Bitrate_mbps) * 1000) + \"k\") if not Bitrate_mbps == \"Copy\" else \"\"\n",
+ "Output_Format_and_Codec = [Param.lower() for Param in Output_Format_and_Codec.split(\" \")]\n",
+ "Output_Format = Output_Format_and_Codec[0]\n",
+ "Video_Codec = \"-c:v \" + (\"lib\" if Output_Format == \"mp4\" else \"\") + Output_Format_and_Codec[1][1:-1]\n",
+ "\n",
+ "#---#\n",
+ "\n",
+ "from re import sub\n",
+ "from time import time\n",
+ "from shutil import rmtree\n",
+ "from os import *; del open\n",
+ "from datetime import timedelta\n",
+ "from google.colab import files\n",
+ "from base64 import b64encode as b64\n",
+ "from requests import get, exceptions\n",
+ "from IPython.display import display, HTML\n",
+ "\n",
+ "#---#\n",
+ "\n",
+ "__author__\t\t\t\t= \"kubinka0505\"\n",
+ "__copyright__\t\t= __author__\n",
+ "__credits__\t\t\t\t= __author__\n",
+ "__version__\t\t\t\t= \"1.0\"\n",
+ "__date__\t\t\t\t\t= \"08.08.2021\"\n",
+ "__status__\t\t\t\t= \"Mature\"\n",
+ "__license__\t\t\t\t= \"GPL V3\"\n",
+ "\n",
+ "#---#\n",
+ "\n",
+ "chdir(\"/content/\")\n",
+ "CWD = getcwd()\n",
+ "chdir(\"..\")\n",
+ "\n",
+ "for Command in [rmtree, mkdir, chdir]:\n",
+ "\tCommand(CWD)\n",
+ "\n",
+ "#---#\n",
+ "\n",
+ "def File_Size(Size: bytes):\n",
+ "\tfor Unit in ['B', 'KB', 'MB', 'GB', 'TB', 'PB']:\n",
+ "\t\tif Size < 1024. or Unit == \"PB\": \n",
+ "\t\t\tbreak\n",
+ "\t\tSize /= 1024.\n",
+ "\treturn \"{0} {1}\".format(round(Size, 2), Unit)\n",
+ "\n",
+ "class Styles():\n",
+ "\t\"\"\"Formatted Prints.\"\"\"\n",
+ "\tLightRed\t= \"\\33[31m\"\n",
+ "\tBlue\t\t\t= \"\\33[34m\"\n",
+ "\tRed\t\t\t\t= \"\\33[91m\"\n",
+ "\tGreen\t\t\t= \"\\33[92m\"\n",
+ "\tYellow\t\t= \"\\33[93m\"\n",
+ "\tCyan\t\t\t= \"\\33[96m\"\n",
+ "\tBold\t\t\t= \"\\33[1m\"\n",
+ "\tUnderline\t= \"\\33[4m\"\n",
+ "\tReset\t\t\t= \"\\33[0m\"\n",
+ "\n",
+ "Allowed_Formats = [\"AVI\", \"MKV\", \"MOV\", \"MP4\", \"WEBM\"]\n",
+ "\n",
+ "#---#\n",
+ "\n",
+ "if not URL:\n",
+ "\ttry:\n",
+ "\t\tFile = [Key for Key in files.upload().keys()][0]\n",
+ "\t\tprint()\n",
+ "\texcept (TypeError, IndexError, KeyboardInterrupt):\n",
+ "\t\traise SystemExit(\"File upload aborted.\")\n",
+ "else:\n",
+ "\tprint(\"Uploading from {0}URL{1}...\".format(\n",
+ "\t\tStyles.Yellow, Styles.Reset\n",
+ "\t\t)\n",
+ "\t)\n",
+ "\t\n",
+ "\tFile = URL.split(\"/\")[-1]\n",
+ "\twith open(File, \"wb\") as File_:\n",
+ "\t\ttry:\n",
+ "\t\t\tRequest = get(URL)\n",
+ "\t\texcept exceptions.MissingSchema:\n",
+ "\t\t\t\traise SystemExit(\"Invalid URL.\")\n",
+ "\t\tif Request.status_code == 200:\n",
+ "\t\t\tFile_.write(Request.content)\n",
+ "\t\telse:\n",
+ "\t\t\traise SystemExit(\"Cannot import URL - {2}{0}{3} ({2}{1}{3})\".format(\n",
+ "\t\t\t\tRequest.status_code, Request.reason, Styles.Red, Styles.Reset)\n",
+ "\t\t\t)\n",
+ "try:\n",
+ "\tIn = path.abspath(File)\n",
+ "\tIn_NEW = sub(\"[^\\w\\-_\\. ]\", \"_\", In.split(\"/\")[-1]).replace(\" \", \"_\")\n",
+ "\trename(In, In_NEW)\n",
+ "\tIn = path.abspath(In_NEW)\n",
+ "\n",
+ "\tOut = In.split(\".\")[0] + \"_new.\" + Output_Format\n",
+ "\n",
+ "\tif not In.split(\".\")[-1].upper() in Allowed_Formats:\n",
+ "\t\tchmod(In, 0o777)\n",
+ "\t\tremove(In)\n",
+ "\t\tprint(\"{2}{0}{3}: Uploaded file is not a video!\\nAllowed formats: {1}\".format(\n",
+ "\t\t\tTypeError.__class__.__name__ + \"{1}, {0}\".join(Allowed_Formats).format(\n",
+ "\t\t\t\tStyles.Red, Styles.Reset\n",
+ "\t\t\t),\n",
+ "\t\t\tStyles.Red, Styles.Reset\n",
+ "\t\t\t)\n",
+ "\t\t)\n",
+ "\n",
+ "\t#---#\n",
+ "\n",
+ "\tenviron[\"IN\"] = In\n",
+ "\tenviron[\"OUT\"] = Out\n",
+ "\tenviron[\"AC\"] = Audio_Channels\n",
+ "\tenviron[\"BA\"] = Audio_Bitrate\n",
+ "\tenviron[\"AR\"] = Samplerate\n",
+ "\tenviron[\"BV\"] = Video_Bitrate\n",
+ "\tenviron[\"CV\"] = Video_Codec\n",
+ "\tenviron[\"MD\"] = Keep_Metadata\n",
+ "\n",
+ "\tprint(\"Re-encoding...\")\n",
+ "\t__STA_TIME = time()\n",
+ "\t!ffmpeg -i \"$IN\" $BV $CV $AC $AR $BA $MD \"$OUT\" -y -hide_banner -loglevel warning\n",
+ "\n",
+ "\t#---#\n",
+ "\n",
+ "\tSize_IN = path.getsize(In)\n",
+ "\tSize_OUT = path.getsize(Out)\n",
+ "\tPercentage = round(\n",
+ "\t\t\t100 - (\n",
+ "\t\t\t\tfloat(str(Size_OUT).split(\" \")[0]) / float(str(Size_IN).split(\" \")[0])\n",
+ "\t\t\t) * 100, 3\n",
+ "\t\t) if not Size_IN == Size_OUT else \"0.00\"\n",
+ "\tprint(\"\"\"\n",
+ "\tSize changed by:\\t{4}{2}%{8}\n",
+ "\tBase file size:\\t\\t{5}{0}{8}\n",
+ "\tNew file size:\\t\\t{6}{1}{8}\n",
+ "\n",
+ "\tWork time: {7}{3}{8}\\n\"\"\".replace(\"\\n\t\", \"\\n\").format(\n",
+ "\t\tFile_Size(Size_IN), File_Size(Size_OUT), Percentage,\n",
+ "\t\tstr(timedelta(seconds = -__STA_TIME + time()))[2:-3],\n",
+ "\t\tStyles.Cyan, Styles.LightRed, Styles.Green, Styles.Blue, Styles.Reset\n",
+ "\t\t)\n",
+ "\t)\n",
+ "\n",
+ "\tB64 = \"data:video/{0};base64,\".format(Output_Format) + b64(open(Out, \"rb\").read()).decode()\n",
+ "\n",
+ "\tdisplay(\n",
+ "\t\tHTML(\n",
+ "\t\t\t\"\"\"\n",
+ "\t\t\t \"\"\".format(\n",
+ "\t\t\t\tB64, Output_Format, Output_Preview_Volume)\n",
+ "\t\t\t)\n",
+ "\t\t)\n",
+ "\n",
+ "\tprint()\n",
+ "\tfiles.download(Out)\n",
+ "except Exception as Error:\n",
+ "\tprint(Error.__class__.__name__ + \": \" + Error)"
+ ],
+ "execution_count": null,
+ "outputs": []
+ }
+ ]
+}
diff --git a/Notebooks/General/Text/Inkscape_HTML_Nodes_Delimiter/Notebook.ipynb b/Notebooks/General/Text/Inkscape_HTML_Nodes_Delimiter/Notebook.ipynb
new file mode 100644
index 0000000..e4dad49
--- /dev/null
+++ b/Notebooks/General/Text/Inkscape_HTML_Nodes_Delimiter/Notebook.ipynb
@@ -0,0 +1,141 @@
+{
+ "nbformat": 4,
+ "nbformat_minor": 0,
+ "metadata": {
+ "colab": {
+ "name": "Inkscape HTML Nodes Delimiter",
+ "provenance": [],
+ "collapsed_sections": []
+ },
+ "kernelspec": {
+ "name": "python3",
+ "display_name": "Python 3"
+ },
+ "language_info": {
+ "name": "python"
+ }
+ },
+ "cells": [
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "",
+ "cellView": "form"
+ },
+ "source": [
+ "#@title ## โฐ Open **`HTML`** webpage file\n",
+ "\n",
+ "from zipfile import *\n",
+ "from shutil import rmtree\n",
+ "from sys import *; del path\n",
+ "from os import *; del open\n",
+ "from google.colab import files\n",
+ "\n",
+ "CWD = \"/content/\"\n",
+ "rmtree(CWD)\n",
+ "mkdir(CWD)\n",
+ "chdir(CWD)\n",
+ "\n",
+ "#---#\n",
+ "\n",
+ "__author__ = \"kubinka0505\"\n",
+ "__credits__ = __author__\n",
+ "__version__ = \"1.0\"\n",
+ "__date__ = \"02.08.2021\"\n",
+ "\n",
+ "#---#\n",
+ "\n",
+ "def Folder_Size():\n",
+ "\t\"\"\"Calculates folder size recursively\"\"\"\n",
+ "\tSize = 0\n",
+ "\tfor Root, Dirs, Files in walk(\".\"):\n",
+ "\t\tfor File in Files:\n",
+ "\t\t\tPath = path.join(Root, File)\n",
+ "\t\t\tif not path.islink(Path):\n",
+ "\t\t\t\tSize += path.getsize(Path)\n",
+ "\treturn Size\n",
+ "\n",
+ "def File_Size(Bytes: float) -> str:\n",
+ "\t\"\"\"Returns human-readable file size\"\"\"\n",
+ "\tfor Unit in [\"B\", \"KB\", \"MB\", \"GB\", \"TB\", \"PB\"]:\n",
+ "\t\tif Bytes < 1024.: break\n",
+ "\t\tBytes /= 1024.\n",
+ "\treturn \"{0} {1}\".format(round(Bytes, 2), Unit)\n",
+ "\n",
+ "#---#\n",
+ "\n",
+ "try:\n",
+ "\ttry: files.upload()\n",
+ "\texcept KeyboardInterrupt: raise Exception\n",
+ "\n",
+ "\tFile = next(walk(\".\"))[2][0]\n",
+ "\n",
+ "\tif File: File = open(path.abspath(File), encoding = \"U8\")\n",
+ "\telse: raise Exception\n",
+ "except:\n",
+ "\traise IndexError(\"No file given!\")\n",
+ "\n",
+ "Folder_Name = File.name.split(\".\")[0] + \"_Nodes\"\n",
+ "\n",
+ "#---#\n",
+ "\n",
+ "Content\t= File.read()\n",
+ "Content\t= Content.replace(\"\\t\", \"\")\n",
+ "Begin\t= Content.find(\"ctx.moveTo(\")\n",
+ "Content\t= Content[Begin:].split(\"ctx.fill(\")[0].strip().split(\"\\n\")\n",
+ "\n",
+ "#---#\n",
+ "\n",
+ "Formats = (\"HTM\", \"HTML\")\n",
+ "if not File.name.upper().endswith(Formats):\n",
+ "\ttry:\n",
+ "\t\traise OSError(\"Only single simple webpages format files are supported ({0})\".format(\n",
+ "\t\t\t\", \".join(Formats).strip()\n",
+ "\t\t)\n",
+ "\t)\n",
+ "\texcept Exception as Error:\n",
+ "\t\traise SystemExit(\"{0}: {1}\".format(Error.__class__.__name__, Error))\n",
+ "\n",
+ "for Line in Content:\n",
+ "\tif \"ctx.bezier\" in Line:\n",
+ "\t\ttry:\n",
+ "\t\t\traise AttributeError(\"SVG file contains bezier curves\")\n",
+ "\t\texcept Exception as Error:\n",
+ "\t\t\texit(\"{0}: {1}\".format(Error.__class__.__name__, Error))\n",
+ "\n",
+ "try: mkdir(Folder_Name)\n",
+ "except FileExistsError: pass\n",
+ "chdir(Folder_Name)\n",
+ "\n",
+ "#---#\n",
+ "\n",
+ "X = \"\\n\".join([Line.split(\", \")[1].split(\");\")[0] for Line in Content])\n",
+ "X += \"{0}{1}{0}\".format(\"\\n\", X.split(\"\\n\")[0])\n",
+ "\n",
+ "Y = \"\\n\".join([Line.split(\"(\")[1].split(\",\")[0] for Line in Content])\n",
+ "Y += \"{0}{1}{0}\".format(\"\\n\", Y.split(\"\\n\")[0])\n",
+ "\n",
+ "open(\"X.txt\", \"w\", encoding = \"U8\").write(X)\n",
+ "open(\"Y.txt\", \"w\", encoding = \"U8\").write(Y)\n",
+ "\n",
+ "#---#\n",
+ "\n",
+ "print(\"\\nSuccessfully saved {0} nodes ({1})\".format(\n",
+ "\tlen([Line for Line in Content]),\n",
+ "\tFile_Size(Folder_Size())\n",
+ "\t)\n",
+ ")\n",
+ "\n",
+ "#---#\n",
+ "\n",
+ "print(\"Creating archive...\")\n",
+ "Archive_Name = path.abspath(Folder_Name + \".zip\")\n",
+ "Archive = ZipFile(Archive_Name, \"w\", ZIP_LZMA)\n",
+ "[Archive.write(File) for File in next(walk(\".\"))[2]]\n",
+ "files.download(Archive_Name)"
+ ],
+ "execution_count": null,
+ "outputs": []
+ }
+ ]
+}
diff --git a/Notebooks/General/Text/Inkscape_HTML_Nodes_Delimiter/Standalone.pyw b/Notebooks/General/Text/Inkscape_HTML_Nodes_Delimiter/Standalone.pyw
new file mode 100644
index 0000000..eda60b6
--- /dev/null
+++ b/Notebooks/General/Text/Inkscape_HTML_Nodes_Delimiter/Standalone.pyw
@@ -0,0 +1,133 @@
+"""Script delimiting Inkscape's HTML node points
+Can be used as both CLI and GUI"""
+from sys import *; del path
+from os import *; del open
+from subprocess import call
+from tkinter import Tk, messagebox as msgbox, filedialog as fd
+chdir(path.abspath(path.dirname(__file__)))
+
+#---#
+
+__author__ = "kubinka0505"
+__credits__ = __author__
+__version__ = "1.0"
+__date__ = "02.08.2021"
+
+#---#
+
+root = Tk()
+root.withdraw()
+
+#---#
+
+def Folder_Size():
+ """Calculates folder size recursively"""
+ Size = 0
+ for Root, Dirs, Files in walk("."):
+ for File in Files:
+ Path = path.join(Root, File)
+ if not path.islink(Path):
+ Size += path.getsize(Path)
+ return Size
+
+def File_Size(Bytes: float) -> str:
+ """Returns human-readable file size"""
+ for Unit in ["B", "KB", "MB", "GB"]:
+ if Bytes < 1024.: break
+ Bytes /= 1024.
+ return "{0} {1}".format(round(Bytes, 2), Unit)
+
+#---#
+
+try:
+ try:
+ File = argv[1]
+ except IndexError:
+ File = fd.askopenfilename(
+ initialdir = getcwd(),
+ filetypes = [
+ ("Hypertext Markup Language Files", "*.html *htm"),
+ ("All Files", "*.*")
+ ]
+ )
+ if File:
+ File = open(path.abspath(File), encoding = "U8")
+ else:
+ raise IndexError
+except IndexError:
+ exit("No file given!")
+
+Folder_Name = File.name.split(".")[0] + "_Nodes"
+
+#---#
+
+Content = File.read()
+Content = Content.replace("\t", "")
+Begin = Content.find("ctx.moveTo(")
+Content = Content[Begin:].split("ctx.fill(")[0].strip().split("\n")
+
+#---#
+
+Formats = ("HTM", "HTML")
+if not File.name.upper().endswith(Formats):
+ try:
+ raise OSError("Only single simple webpages format files are supported ({0})".format(
+ ", ".join(Formats).strip()
+ )
+ )
+ except Exception as Error:
+ msgbox.showerror(
+ title = Error.__class__.__name__,
+ message = Error
+ )
+ exit("{0}: {1}".format(Error.__class__.__name__, Error))
+
+for Line in Content:
+ if "ctx.bezier" in Line:
+ try:
+ raise AttributeError("SVG file contains bezier curves")
+ except Exception as Error:
+ msgbox.showerror(
+ title = Error.__class__.__name__,
+ message = Error
+ )
+ exit("{0}: {1}".format(Error.__class__.__name__, Error))
+
+try:
+ mkdir(Folder_Name)
+except FileExistsError:
+ pass
+chdir(Folder_Name)
+
+#---#
+
+X = "\n".join([Line.split(", ")[1].split(");")[0] for Line in Content])
+X += "{0}{1}{0}".format("\n", X.split("\n")[0])
+
+Y = "\n".join([Line.split("(")[1].split(",")[0] for Line in Content])
+Y += "{0}{1}{0}".format("\n", Y.split("\n")[0])
+
+open("X.txt", "w", encoding = "U8").write(X)
+open("Y.txt", "w", encoding = "U8").write(Y)
+
+#---#
+
+Message = "Successfully {0} nodes ({1})\n\nDo You want to open containing folder?".format(
+ len([Line for Line in Content]),
+ File_Size(Folder_Size())
+ )
+
+print(Message.split("\n")[0] + "\a")
+Message = msgbox.showinfo(
+ title = "Success",
+ message = Message
+)
+
+#---#
+
+Command = "nautilus"
+if platform.startswith("win"):
+ Command = "start /max"
+
+if Message == "ok":
+ call(Command + " .", shell = True)
diff --git a/ReadMe.md b/ReadMe.md
new file mode 100644
index 0000000..46219f6
--- /dev/null
+++ b/ReadMe.md
@@ -0,0 +1,29 @@
+
+ Colab Notebooks ๐
+
+
+
+ ใ
+
+
+---
+
+## General
+
+| Name | Description | URL |
+|:---:|:---:|:---:|
+| `Hybrid Image / Video Cropper` (Vertical) | Crops the image into two horizontal pieces and maps a different sound file to each, resulting with two videos. | [ ](https://colab.research.google.com/github/kubinka0505/colab-notebooks/blob/master/Notebooks/General/Media/Visual/Mixed/Hybrid_Image_Video_Cropper/Vertical.ipynb) |
+| `Inkscape HTML Nodes Delimiter` | Extracts simple coordinates of Inkscape's HTML files and saves it as two files. Its main purpose is easing work with [vectorscope arts creations](https://www.youtube.com/watch?v=aLJeInPJ9oo), but perhaps not only. | [ ](https://colab.research.google.com/github/kubinka0505/colab-notebooks/blob/master/Notebooks/General/Text/Inkscape_HTML_Nodes_Delimiter/Notebook.ipynb) [ ](https://colab.research.google.com/github/kubinka0505/colab-notebooks/blob/master/Notebooks/General/Text/Inkscape_HTML_Nodes_Delimiter/Standalone.pyw) |
+| `Music Calculators` | Calculators for various music functions related to pitch and time.| [ ](https://colab.research.google.com/github/kubinka0505/colab-notebooks/blob/master/Notebooks/General/Math/Music/Calculators.ipynb) |
+| `Simple Video Re-Encoder` | Simple *yet* detailed video re-encoder with advanced configuration. | [ ](https://colab.research.google.com/github/kubinka0505/colab-notebooks/blob/master/Notebooks/General/Media/Visual/Video/Simple_Video_Re-Encoder.ipynb) |
+| `Unisonizer` | Pans pairs of files on max opposite values. **`WAV` files recommended!** | [ ](https://colab.research.google.com/github/kubinka0505/colab-notebooks/blob/master/Notebooks/General/Media/Audio/Unisonizer.ipynb)
+
+## AI
+| Name | Description | URL |
+|:---:|:---:|:---:|
+| `Stable Diffusion WebUI` | Clear and user-friendly [`Stable-Diffusion-WebUI`](https://github.com/AUTOMATIC1111/stable-diffusion-webui) wrapper with useful websites, models selector, custom configuration and more. | [ ](https://colab.research.google.com/github/kubinka0505/colab-notebooks/blob/master/Notebooks/AI/Visual/Generate/Stable-Diffusion-WebUI/Stable-Diffusion_WebUI.ipynb) |
+| `Audio Separation` - `MDX23C` | User-friendly wrapper for the [jarredou](https://github.com/jarredou)'s [fork](https://github.com/jarredou/MVSEP-MDX23-Colab_v2) of [ZFTurbo](https://github.com/ZFTurbo)'s [MDX23C](https://github.com/ZFTurbo/MVSEP-MDX23-music-separation-model) audio separation model. | [ ](https://colab.research.google.com/github/kubinka0505/colab-notebooks/blob/master/Notebooks/AI/Audio/Separate/MDX23C.ipynb) |
+| `Audio Separation` - `Drumsep` | Customized [Drumsep](https://github.com/inagoy/drumsep) notebook by [inagoy](https://github.com/inagoy). | [ ](https://colab.research.google.com/github/kubinka0505/colab-notebooks/blob/master/Notebooks/AI/Audio/Separate/Drumsep.ipynb) |
+| `Audio Generation` - `AudioCraft` | User-friendly wrapper for the Meta's [`AudioCraft`](https://github.com/facebookresearch/audiocraft) audio generation models. | [ ](https://colab.research.google.com/github/kubinka0505/colab-notebooks/blob/master/Notebooks/AI/Audio/Generate/AudioCraft.ipynb) |
+| `Audio Upscale` - `HiFi GAN BWE` | Customized [`HiFi GAN BWE`](https://github.com/brentspell/hifi-gan-bwe) notebook by [brentspell](https://github.com/brentspell). | [ ](https://colab.research.google.com/github/kubinka0505/colab-notebooks/blob/master/Notebooks/AI/Audio/Upscale/HiFi_GAN_BWE.ipynb) |
+| `Speech Cloning` - `Coqui XTTS` | Compact implementation of the [camenduru](https://github.com/camenduru)'s [`coqui-XTTS-colab.`](https://github.com/camenduru/coqui-XTTS-colab) Gradio app. | [ ](https://colab.research.google.com/github/kubinka0505/colab-notebooks/blob/master/Notebooks/AI/Audio/_Speech/Clone/Coqui_XTTS.ipynb) |
\ No newline at end of file