diff --git a/tortoise_tts.ipynb b/tortoise_tts.ipynb index 8c38bdb..b0230e3 100644 --- a/tortoise_tts.ipynb +++ b/tortoise_tts.ipynb @@ -40,7 +40,8 @@ "source": [ "!git clone https://github.com/neonbjb/tortoise-tts.git\n", "%cd tortoise-tts\n", - "!pip install -r requirements.txt" + "!pip3 install -r requirements.txt\n", + "!python3 setup.py install" ] }, { @@ -54,8 +55,8 @@ "\n", "import IPython\n", "\n", - "from api import TextToSpeech\n", - "from utils.audio import load_audio, get_voices\n", + "from tortoise.api import TextToSpeech\n", + "from tortoise.utils.audio import load_audio, load_voice, load_voices\n", "\n", "# This will download all the models used by Tortoise from the HF hub.\n", "tts = TextToSpeech()" @@ -66,20 +67,6 @@ "execution_count": null, "outputs": [] }, - { - "cell_type": "code", - "source": [ - "# List all the voices available. These are just some random clips I've gathered\n", - "# from the internet as well as a few voices from the training dataset.\n", - "# Feel free to add your own clips to the voices/ folder.\n", - "%ls voices" - ], - "metadata": { - "id": "SSleVnRAiEE2" - }, - "execution_count": null, - "outputs": [] - }, { "cell_type": "code", "source": [ @@ -94,8 +81,6 @@ "Though as for that the passing there\n", "Had worn them really about the same,\"\"\"\n", "\n", - "# Pick one of the voices from above\n", - "voice = 'train_dotrice'\n", "# Pick a \"preset mode\" to determine quality. Options: {\"ultra_fast\", \"fast\" (default), \"standard\", \"high_quality\"}. See docs in api.py\n", "preset = \"fast\"" ], @@ -108,15 +93,32 @@ { "cell_type": "code", "source": [ - "# Fetch the voice references and forward execute!\n", - "voices = get_voices()\n", - "cond_paths = voices[voice]\n", - "conds = []\n", - "for cond_path in cond_paths:\n", - " c = load_audio(cond_path, 22050)\n", - " conds.append(c)\n", + "# Tortoise will attempt to mimic voices you provide. It comes pre-packaged\n", + "# with some voices you might recognize.\n", "\n", - "gen = tts.tts_with_preset(text, conds, preset)\n", + "# Let's list all the voices available. These are just some random clips I've gathered\n", + "# from the internet as well as a few voices from the training dataset.\n", + "# Feel free to add your own clips to the voices/ folder.\n", + "%ls tortoise/voices\n", + "\n", + "IPython.display.Audio('tortoise/voices/tom/1.wav')" + ], + "metadata": { + "id": "SSleVnRAiEE2" + }, + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "source": [ + "# Pick one of the voices from the output above\n", + "voice = 'tom'\n", + "\n", + "# Load it and send it through Tortoise.\n", + "voice_samples, conditioning_latents = load_voice(voice)\n", + "gen = tts.tts_with_preset(text, voice_samples=voice_samples, conditioning_latents=conditioning_latents, \n", + " preset=preset)\n", "torchaudio.save('generated.wav', gen.squeeze(0).cpu(), 24000)\n", "IPython.display.Audio('generated.wav')" ], @@ -129,19 +131,29 @@ { "cell_type": "code", "source": [ - "# You can add as many conditioning voices as you want together. Combining\n", - "# clips from multiple voices takes the mean of the latent space for all\n", - "# voices. This creates a novel voice that is a combination of the two inputs.\n", + "# Tortoise can also generate speech using a random voice. The voice changes each time you execute this!\n", + "# (Note: random voices can be prone to strange utterances)\n", + "gen = tts.tts_with_preset(text, voice_samples=None, conditioning_latents=None, preset=preset)\n", + "torchaudio.save('generated.wav', gen.squeeze(0).cpu(), 24000)\n", + "IPython.display.Audio('generated.wav')" + ], + "metadata": { + "id": "16Xs2SSC3BXa" + }, + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "source": [ + "# You can also combine conditioning voices. Combining voices produces a new voice\n", + "# with traits from all the parents.\n", "#\n", "# Lets see what it would sound like if Picard and Kirk had a kid with a penchant for philosophy:\n", - "conds = []\n", - "for v in ['pat', 'william']:\n", - " cond_paths = voices[v]\n", - " for cond_path in cond_paths:\n", - " c = load_audio(cond_path, 22050)\n", - " conds.append(c)\n", + "voice_samples, conditioning_latents = load_voices(['pat', 'william'])\n", "\n", - "gen = tts.tts_with_preset(\"They used to say that if man was meant to fly, he’d have wings. But he did fly. He discovered he had to.\", conds, preset)\n", + "gen = tts.tts_with_preset(\"They used to say that if man was meant to fly, he’d have wings. But he did fly. He discovered he had to.\", \n", + " voice_samples=None, conditioning_latents=None, preset=preset)\n", "torchaudio.save('captain_kirkard.wav', gen.squeeze(0).cpu(), 24000)\n", "IPython.display.Audio('captain_kirkard.wav')" ], @@ -150,6 +162,24 @@ }, "execution_count": null, "outputs": [] + }, + { + "cell_type": "code", + "source": [ + "del tts # Will break other cells, but necessary to conserve RAM if you want to run this cell.\n", + "\n", + "# Tortoise comes with some scripts that does a lot of the lifting for you. For example,\n", + "# read.py will read a text file for you.\n", + "!python3 tortoise/read.py --voice=train_atkins --textfile=tortoise/data/riding_hood.txt --preset=ultra_fast --output_path=.\n", + "\n", + "IPython.display.Audio('train_atkins/combined.wav')\n", + "# This will take awhile.." + ], + "metadata": { + "id": "t66yqWgu68KL" + }, + "execution_count": null, + "outputs": [] } ] } \ No newline at end of file