{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "Collapsed": "false"
   },
   "outputs": [],
   "source": [
    "%matplotlib inline\n",
    "\n",
    "from TTS.utils.audio import AudioProcessor\n",
    "from TTS.tts.utils.visual import plot_spectrogram\n",
    "from TTS.config import load_config\n",
    "\n",
    "import IPython.display as ipd\n",
    "import glob"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "Collapsed": "false"
   },
   "outputs": [],
   "source": [
    "from TTS.config.shared_configs import BaseAudioConfig\n",
    "CONFIG = BaseAudioConfig()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## ✍️ Set these values "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "data_path = \"/root/wav48_silence_trimmed/\"\n",
    "file_ext = \".flac\""
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Read audio files"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "file_paths = glob.glob(data_path + f\"/**/*{file_ext}\", recursive=True)\n",
    "\n",
    "# Change this to the index of the desired file listed below\n",
    "sample_file_index = 10\n",
    "\n",
    "SAMPLE_FILE_PATH = file_paths[sample_file_index]\n",
    "\n",
    "print(\"File list, by index:\")\n",
    "dict(enumerate(file_paths))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "Collapsed": "false"
   },
   "source": [
    "## ✍️ Set Audio Processor\n",
    "Play with the AP parameters until you find a good fit with the synthesis speech below.\n",
    "\n",
    "The default values are loaded from your config.json file, so you only need to\n",
    "uncomment and modify values below that you'd like to tune."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "Collapsed": "false"
   },
   "outputs": [],
   "source": [
    "tune_params={\n",
    " 'num_mels': 80,          # In general, you don't need to change this. \n",
    " 'fft_size': 2400,        # In general, you don't need to change this.\n",
    " 'frame_length_ms': 50, \n",
    " 'frame_shift_ms': 12.5,\n",
    " 'sample_rate': 48000,    # This must match the sample rate of the dataset.\n",
    " 'hop_length': None,       # In general, you don't need to change this.\n",
    " 'win_length': 1024,      # In general, you don't need to change this.\n",
    " 'preemphasis': 0.98,     # In general, 0 gives better voice recovery but makes training harder. If your model does not train, try 0.97 - 0.99.\n",
    " 'min_level_db': -100,\n",
    " 'ref_level_db': 0,       # The base DB; increase until all background noise is removed in the spectrogram, then lower until you hear better speech below.\n",
    " 'power': 1.5,            # Change this value and listen to the synthesized voice. 1.2 - 1.5 are resonable values.\n",
    " 'griffin_lim_iters': 60, # Quality does not improve for values > 60\n",
    " 'mel_fmin': 0.0,         # Adjust this and check mel-spectrogram-based voice synthesis below.\n",
    " 'mel_fmax': 8000.0,      # Adjust this and check mel-spectrogram-based voice synthesis below.\n",
    " 'do_trim_silence': True  # If you dataset has some silience at the beginning or end, this trims it. Check the AP.load_wav() below,if it causes any difference for the loaded audio file.\n",
    "}\n",
    "\n",
    "# These options have to be forced off in order to avoid errors about the \n",
    "# pre-calculated not matching the options being tuned.\n",
    "reset={\n",
    " 'signal_norm': True,  # check this if you want to test normalization parameters.\n",
    " 'stats_path': None,\n",
    " 'symmetric_norm': False,\n",
    " 'max_norm': 1,\n",
    " 'clip_norm': True,\n",
    "}\n",
    "\n",
    "# Override select parts of loaded config with parameters above\n",
    "tuned_config = CONFIG.copy()\n",
    "tuned_config.update(reset)\n",
    "tuned_config.update(tune_params)\n",
    "\n",
    "AP = AudioProcessor(**tuned_config);"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "Collapsed": "false"
   },
   "source": [
    "### Check audio loading "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "Collapsed": "false"
   },
   "outputs": [],
   "source": [
    "wav = AP.load_wav(SAMPLE_FILE_PATH)\n",
    "ipd.Audio(data=wav, rate=AP.sample_rate) "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "Collapsed": "false"
   },
   "source": [
    "### Generate Mel-Spectrogram and Re-synthesis with GL"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "AP.power = 1.5"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "mel = AP.melspectrogram(wav)\n",
    "print(\"Max:\", mel.max())\n",
    "print(\"Min:\", mel.min())\n",
    "print(\"Mean:\", mel.mean())\n",
    "plot_spectrogram(mel.T, AP, output_fig=True)\n",
    "\n",
    "wav_gen = AP.inv_melspectrogram(mel)\n",
    "ipd.Audio(wav_gen, rate=AP.sample_rate)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "Collapsed": "false"
   },
   "source": [
    "### Generate Linear-Spectrogram and Re-synthesis with GL"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "Collapsed": "false"
   },
   "outputs": [],
   "source": [
    "spec = AP.spectrogram(wav)\n",
    "print(\"Max:\", spec.max())\n",
    "print(\"Min:\", spec.min())\n",
    "print(\"Mean:\", spec.mean())\n",
    "plot_spectrogram(spec.T, AP, output_fig=True)\n",
    "\n",
    "wav_gen = AP.inv_spectrogram(spec)\n",
    "ipd.Audio(wav_gen, rate=AP.sample_rate)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "Collapsed": "false"
   },
   "source": [
    "### Compare values for a certain parameter\n",
    "\n",
    "Optimize your parameters by comparing different values per parameter at a time."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "Collapsed": "false"
   },
   "outputs": [],
   "source": [
    "from librosa import display\n",
    "from matplotlib import pylab as plt\n",
    "import IPython\n",
    "plt.rcParams['figure.figsize'] = (20.0, 16.0)\n",
    "\n",
    "def compare_values(attribute, values):\n",
    "    \"\"\"\n",
    "    attributes (str): the names of the attribute you like to test.\n",
    "    values (list): list of values to compare.\n",
    "    \"\"\"\n",
    "    file = SAMPLE_FILE_PATH\n",
    "    wavs = []\n",
    "    for idx, val in enumerate(values):\n",
    "        set_val_cmd = \"AP.{}={}\".format(attribute, val)\n",
    "        exec(set_val_cmd)\n",
    "        wav = AP.load_wav(file)\n",
    "        spec = AP.spectrogram(wav)\n",
    "        spec_norm = AP.denormalize(spec.T)\n",
    "        plt.subplot(len(values), 2, 2*idx + 1)\n",
    "        plt.imshow(spec_norm.T, aspect=\"auto\", origin=\"lower\")\n",
    "        #         plt.colorbar()\n",
    "        plt.tight_layout()\n",
    "        wav_gen = AP.inv_spectrogram(spec)\n",
    "        wavs.append(wav_gen)\n",
    "        plt.subplot(len(values), 2, 2*idx + 2)\n",
    "        display.waveshow(wav, alpha=0.5)\n",
    "        display.waveshow(wav_gen, alpha=0.25)\n",
    "        plt.title(\"{}={}\".format(attribute, val))\n",
    "        plt.tight_layout()\n",
    "    \n",
    "    wav = AP.load_wav(file)\n",
    "    print(\" > Ground-truth\")\n",
    "    IPython.display.display(IPython.display.Audio(wav, rate=AP.sample_rate))\n",
    "    \n",
    "    for idx, wav_gen in enumerate(wavs):\n",
    "        val = values[idx]\n",
    "        print(\" > {} = {}\".format(attribute, val))\n",
    "        IPython.display.display(IPython.display.Audio(wav_gen, rate=AP.sample_rate))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "Collapsed": "false"
   },
   "outputs": [],
   "source": [
    "compare_values(\"preemphasis\", [0, 0.5, 0.97, 0.98, 0.99])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "Collapsed": "false"
   },
   "outputs": [],
   "source": [
    "compare_values(\"ref_level_db\", [2, 5, 10, 15, 20, 25, 30, 35, 40])"
   ]
  }
 ],
 "metadata": {
  "interpreter": {
   "hash": "27648abe09795c3a768a281b31f7524fcf66a207e733f8ecda3a4e1fd1059fb0"
  },
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.9.5"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
