{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "06cb5da9",
   "metadata": {},
   "outputs": [],
   "source": [
    "import os\n",
    "os.environ[\"CUDA_VISIBLE_DEVICES\"] = \"\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "bf70f34f",
   "metadata": {},
   "outputs": [],
   "source": [
    "import os\n",
    "import re\n",
    "import json\n",
    "import tqdm\n",
    "import uuid\n",
    "import funcy\n",
    "import numpy as np\n",
    "from suno_utils.audio import Audio, Token, Tokens\n",
    "from suno_utils.utils.numbers import safe_round\n",
    "from suno_utils.utils.text import normalize_whitespace, write_jsonl\n",
    "from suno_utils.web.harvest import get_file_ext, get_filename\n",
    "\n",
    "RAW_BASE_DIR = \"/mnt/data-ssd-1/data/private/customer/speechly/gcp_bucket/\"\n",
    "RAW_AUDIO_DIRS = [\n",
    "    os.path.join(RAW_BASE_DIR, \"titktok/english-100h/en\"),\n",
    "]\n",
    "\n",
    "BASE_DIR = \"/mnt/data-ssd-1/data/private/customer/speechly/2022-12-02_tiktok-100h-en\"\n",
    "\n",
    "AUDIO_DIR = os.path.join(BASE_DIR, \"audio\")\n",
    "TO_REV_DIR = os.path.join(BASE_DIR, \"to_rev\")\n",
    "TO_REV_AUDIO_DIR = os.path.join(TO_REV_DIR, \"audio\")\n",
    "FROM_REV_DIR = os.path.join(BASE_DIR, \"from_rev\")\n",
    "\n",
    "SEGMENT_DATE_DIR = \"2022_12_02\"\n",
    "SEGMENTS_DIR = os.path.join(BASE_DIR, \"pipeline\", SEGMENT_DATE_DIR, \"segments\")\n",
    "ARTIFACTS_DIR = os.path.join(BASE_DIR, \"pipeline\", SEGMENT_DATE_DIR, \"artifacts\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "c769f21a",
   "metadata": {},
   "outputs": [],
   "source": [
    "os.makedirs(AUDIO_DIR, exist_ok=True)\n",
    "os.makedirs(TO_REV_DIR, exist_ok=True)\n",
    "os.makedirs(TO_REV_AUDIO_DIR, exist_ok=True)\n",
    "os.makedirs(FROM_REV_DIR, exist_ok=True)\n",
    "os.makedirs(SEGMENTS_DIR, exist_ok=True)\n",
    "os.makedirs(ARTIFACTS_DIR, exist_ok=True)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "c3cd79ed",
   "metadata": {},
   "outputs": [],
   "source": [
    "GLOBAL_HOTWORDS = []"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "3bf11bab",
   "metadata": {},
   "source": [
    "## Prepare rev data"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "id": "66845519",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "100.02 hours of audio\n"
     ]
    }
   ],
   "source": [
    "# save in dir with known sample rate as wavs and keep track of id\n",
    "SAMPLE_RATE = 16_000\n",
    "EXPECTED_FILE_TYPE = \"wav\"\n",
    "\n",
    "filepaths_info = []\n",
    "duraions_s = []\n",
    "for raw_audio_dir in RAW_AUDIO_DIRS:\n",
    "    for fn in tqdm.tqdm(os.listdir(raw_audio_dir)):\n",
    "        if get_file_ext(fn) != EXPECTED_FILE_TYPE:\n",
    "            print(\"found unknown file:\", fn)\n",
    "            continue\n",
    "        uid = str(uuid.uuid4())\n",
    "        from_fp = os.path.join(raw_audio_dir, fn)\n",
    "        to_fp = os.path.join(AUDIO_DIR, f\"{uid}.wav\")\n",
    "        audio = Audio.from_file(from_fp, sample_rate=SAMPLE_RATE, byte_width=2)\n",
    "        duraions_s.append(audio.duration_s)\n",
    "        audio.to_wav(to_fp)\n",
    "        filepaths_info.append((uid, from_fp, to_fp))\n",
    "print(round(np.sum(duraions_s) / 60 / 60, 2), \"hours of audio\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "id": "deb0bebc",
   "metadata": {},
   "outputs": [],
   "source": [
    "with open(os.path.join(BASE_DIR, \"raw_data_manifest.json\"), \"w\") as f:\n",
    "    json.dump(filepaths_info, f)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "id": "4da818da",
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "47.1 mins of audio (8.1% overhead)\n",
      "45.1 mins of audio (8.0% overhead)\n",
      "45.9 mins of audio (7.7% overhead)\n",
      "45.1 mins of audio (7.4% overhead)\n",
      "45.4 mins of audio (6.8% overhead)\n",
      "45.0 mins of audio (7.9% overhead)\n",
      "45.2 mins of audio (7.8% overhead)\n",
      "45.0 mins of audio (8.3% overhead)\n",
      "45.1 mins of audio (8.0% overhead)\n",
      "45.6 mins of audio (7.5% overhead)\n",
      "45.3 mins of audio (8.0% overhead)\n",
      "45.0 mins of audio (7.8% overhead)\n",
      "46.7 mins of audio (8.3% overhead)\n",
      "45.0 mins of audio (7.6% overhead)\n",
      "46.0 mins of audio (6.7% overhead)\n",
      "45.2 mins of audio (6.6% overhead)\n",
      "45.3 mins of audio (7.7% overhead)\n",
      "45.2 mins of audio (7.4% overhead)\n",
      "45.1 mins of audio (6.4% overhead)\n",
      "45.8 mins of audio (6.8% overhead)\n",
      "45.6 mins of audio (6.5% overhead)\n",
      "45.2 mins of audio (8.6% overhead)\n",
      "45.2 mins of audio (7.6% overhead)\n",
      "45.5 mins of audio (8.4% overhead)\n",
      "45.2 mins of audio (7.7% overhead)\n",
      "46.0 mins of audio (7.3% overhead)\n",
      "45.1 mins of audio (9.3% overhead)\n",
      "45.2 mins of audio (8.6% overhead)\n",
      "46.5 mins of audio (6.2% overhead)\n",
      "46.7 mins of audio (7.0% overhead)\n",
      "45.1 mins of audio (6.9% overhead)\n",
      "45.6 mins of audio (8.4% overhead)\n",
      "45.4 mins of audio (7.9% overhead)\n",
      "45.1 mins of audio (7.6% overhead)\n",
      "45.3 mins of audio (8.1% overhead)\n",
      "45.2 mins of audio (7.6% overhead)\n",
      "45.4 mins of audio (7.5% overhead)\n",
      "46.0 mins of audio (7.3% overhead)\n",
      "45.3 mins of audio (7.4% overhead)\n",
      "45.1 mins of audio (7.0% overhead)\n",
      "46.3 mins of audio (7.2% overhead)\n",
      "45.0 mins of audio (6.6% overhead)\n",
      "45.1 mins of audio (6.5% overhead)\n",
      "45.2 mins of audio (8.0% overhead)\n",
      "46.1 mins of audio (6.9% overhead)\n",
      "45.1 mins of audio (6.4% overhead)\n",
      "45.7 mins of audio (6.9% overhead)\n",
      "45.0 mins of audio (7.4% overhead)\n",
      "45.4 mins of audio (7.4% overhead)\n",
      "45.2 mins of audio (7.3% overhead)\n",
      "45.1 mins of audio (8.0% overhead)\n",
      "47.1 mins of audio (8.5% overhead)\n",
      "45.1 mins of audio (7.3% overhead)\n",
      "46.1 mins of audio (7.2% overhead)\n",
      "45.5 mins of audio (8.0% overhead)\n",
      "45.2 mins of audio (7.7% overhead)\n",
      "45.2 mins of audio (7.1% overhead)\n",
      "45.1 mins of audio (7.6% overhead)\n",
      "45.8 mins of audio (6.7% overhead)\n",
      "45.1 mins of audio (7.0% overhead)\n",
      "45.4 mins of audio (8.5% overhead)\n",
      "45.0 mins of audio (7.6% overhead)\n",
      "45.7 mins of audio (7.3% overhead)\n",
      "45.0 mins of audio (7.4% overhead)\n",
      "45.1 mins of audio (8.3% overhead)\n",
      "45.0 mins of audio (6.8% overhead)\n",
      "45.2 mins of audio (8.0% overhead)\n",
      "45.2 mins of audio (7.1% overhead)\n",
      "45.1 mins of audio (7.0% overhead)\n",
      "45.2 mins of audio (8.2% overhead)\n",
      "45.3 mins of audio (7.3% overhead)\n",
      "46.3 mins of audio (8.2% overhead)\n",
      "45.8 mins of audio (7.8% overhead)\n",
      "46.5 mins of audio (6.4% overhead)\n",
      "46.4 mins of audio (7.1% overhead)\n",
      "45.5 mins of audio (7.6% overhead)\n",
      "45.3 mins of audio (7.5% overhead)\n",
      "45.2 mins of audio (7.2% overhead)\n",
      "45.1 mins of audio (8.0% overhead)\n",
      "45.0 mins of audio (6.0% overhead)\n",
      "45.0 mins of audio (6.7% overhead)\n",
      "45.1 mins of audio (7.0% overhead)\n",
      "45.2 mins of audio (6.3% overhead)\n",
      "45.1 mins of audio (8.2% overhead)\n",
      "46.3 mins of audio (8.7% overhead)\n",
      "45.1 mins of audio (8.3% overhead)\n",
      "45.5 mins of audio (6.4% overhead)\n",
      "45.2 mins of audio (8.0% overhead)\n",
      "45.6 mins of audio (7.1% overhead)\n",
      "45.1 mins of audio (7.0% overhead)\n",
      "45.7 mins of audio (8.1% overhead)\n",
      "45.0 mins of audio (7.6% overhead)\n",
      "45.1 mins of audio (8.2% overhead)\n",
      "45.2 mins of audio (7.8% overhead)\n",
      "45.0 mins of audio (7.0% overhead)\n",
      "45.2 mins of audio (6.9% overhead)\n",
      "45.1 mins of audio (7.6% overhead)\n",
      "45.7 mins of audio (8.5% overhead)\n",
      "45.2 mins of audio (7.9% overhead)\n",
      "45.4 mins of audio (7.4% overhead)\n",
      "45.0 mins of audio (7.2% overhead)\n",
      "45.5 mins of audio (7.7% overhead)\n",
      "45.0 mins of audio (7.4% overhead)\n",
      "45.2 mins of audio (6.6% overhead)\n",
      "45.3 mins of audio (7.9% overhead)\n",
      "46.0 mins of audio (6.8% overhead)\n",
      "46.1 mins of audio (6.7% overhead)\n",
      "45.2 mins of audio (6.9% overhead)\n",
      "45.3 mins of audio (8.2% overhead)\n",
      "45.1 mins of audio (9.1% overhead)\n",
      "45.0 mins of audio (8.3% overhead)\n",
      "45.4 mins of audio (8.3% overhead)\n",
      "45.2 mins of audio (7.8% overhead)\n",
      "45.1 mins of audio (7.8% overhead)\n",
      "45.1 mins of audio (7.4% overhead)\n",
      "46.2 mins of audio (6.9% overhead)\n",
      "45.4 mins of audio (6.8% overhead)\n",
      "45.3 mins of audio (9.1% overhead)\n",
      "46.1 mins of audio (6.9% overhead)\n",
      "45.1 mins of audio (6.8% overhead)\n",
      "45.5 mins of audio (7.0% overhead)\n",
      "45.2 mins of audio (7.1% overhead)\n",
      "45.0 mins of audio (6.3% overhead)\n",
      "45.2 mins of audio (6.4% overhead)\n",
      "45.2 mins of audio (8.2% overhead)\n",
      "45.0 mins of audio (6.9% overhead)\n",
      "45.5 mins of audio (7.0% overhead)\n",
      "45.5 mins of audio (8.0% overhead)\n",
      "45.1 mins of audio (8.0% overhead)\n",
      "37.8 mins of audio (7.5% overhead)\n"
     ]
    }
   ],
   "source": [
    "MIN_REV_FILE_DURATION_S = 45 * 60\n",
    "INDICATOR_AUDIO_DIR = \"/mnt/data-ssd-1/data/custom/segment_indicators\"\n",
    "SILENCE_DURATION_S = 0.25\n",
    "\n",
    "audio_rev_metas = []\n",
    "tmp_segments_audio = []\n",
    "tmp_segments_meta = []\n",
    "base_tmp_n = 1001\n",
    "tmp_n = base_tmp_n\n",
    "for n_step, (uid, _, filepath) in enumerate(filepaths_info):\n",
    "    # add indicator\n",
    "    indicator_str = str(tmp_n).zfill(4)\n",
    "    tmp_indicator_audios = []\n",
    "    for c in indicator_str:\n",
    "        tmp_indicator_audios.append(\n",
    "            Audio.from_file(\n",
    "                os.path.join(INDICATOR_AUDIO_DIR, f\"{c}_fast.wav\"), \n",
    "                sample_rate=SAMPLE_RATE, \n",
    "                byte_width=2,\n",
    "            )\n",
    "        )\n",
    "    indicator_audio = Audio.concatenate(tmp_indicator_audios)\n",
    "    tmp_segments_audio.append(indicator_audio)\n",
    "    tmp_segments_meta.append({\n",
    "        \"segment_number\": tmp_n,\n",
    "        \"type\": \"indicator\",\n",
    "        \"duration_s\": indicator_audio.duration_s,\n",
    "        \"indicator_str\": indicator_str,\n",
    "    })\n",
    "    # add silence\n",
    "    if SILENCE_DURATION_S > 0:\n",
    "        silence_audio = Audio.from_array(\n",
    "            np.zeros(int(SAMPLE_RATE * SILENCE_DURATION_S), dtype=np.int16), SAMPLE_RATE\n",
    "        )\n",
    "        tmp_segments_audio.append(silence_audio)\n",
    "        tmp_segments_meta.append({\n",
    "            \"segment_number\": tmp_n,\n",
    "            \"type\": \"silence\",\n",
    "            \"duration_s\": SILENCE_DURATION_S,\n",
    "        })\n",
    "    # add audio\n",
    "    audio = Audio.from_file(filepath, sample_rate=SAMPLE_RATE, byte_width=2)\n",
    "#     audio = remove_music(audio, wet=1.0, model_name=\"mdx_extra_q\")\n",
    "    tmp_segments_audio.append(audio)\n",
    "    tmp_segments_meta.append({\n",
    "        \"segment_number\": tmp_n,\n",
    "        \"type\": \"speech\",\n",
    "        \"duration_s\": audio.duration_s,\n",
    "        \"orginial_audio_offset_s\": 0,\n",
    "        \"orginial_audio_uid\": uid,\n",
    "    })\n",
    "    # add silence\n",
    "    if SILENCE_DURATION_S > 0:\n",
    "        silence_audio = Audio.from_array(\n",
    "            np.zeros(int(SAMPLE_RATE * SILENCE_DURATION_S), dtype=np.int16), SAMPLE_RATE\n",
    "        )\n",
    "        tmp_segments_audio.append(silence_audio)\n",
    "        tmp_segments_meta.append({\n",
    "            \"segment_number\": tmp_n,\n",
    "            \"type\": \"silence\",\n",
    "            \"duration_s\": SILENCE_DURATION_S,\n",
    "        })\n",
    "    # prep for next step and decide if we make new file\n",
    "    tmp_n += 1\n",
    "    running_duration_s = np.sum([e[\"duration_s\"] for e in tmp_segments_meta])\n",
    "    if (\n",
    "        (running_duration_s >= MIN_REV_FILE_DURATION_S) or \n",
    "        (n_step == len(filepaths_info) - 1 and running_duration_s > 0)\n",
    "    ):\n",
    "        audio_rev = Audio.concatenate(tmp_segments_audio)\n",
    "        running_speech_duration_s = np.sum([e[\"duration_s\"] for e in tmp_segments_meta if e[\"type\"] == \"speech\"])\n",
    "        print(\"{} mins of audio ({}% overhead)\".format(\n",
    "            round(running_duration_s / 60, 1),\n",
    "            round((1 - running_speech_duration_s / running_duration_s) * 100, 1)\n",
    "        )) \n",
    "        uid = str(uuid.uuid4())\n",
    "        rev_audio_filepath = os.path.join(TO_REV_AUDIO_DIR, f\"{uid}.mp3\")\n",
    "        audio_rev.to_mp3(rev_audio_filepath)\n",
    "        audio_rev_metas.append({\n",
    "            \"uid\": uid,\n",
    "            \"audio_filepath\": rev_audio_filepath,\n",
    "            \"segments_meta\": tmp_segments_meta,\n",
    "            \"duration_s\": audio_rev.duration_s,\n",
    "        })\n",
    "        tmp_segments_audio = []\n",
    "        tmp_segments_meta = []\n",
    "        tmp_n = base_tmp_n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "id": "4d16d48e",
   "metadata": {},
   "outputs": [],
   "source": [
    "with open(os.path.join(TO_REV_DIR, f\"audio_rev_metas.json\"), \"w\") as f:\n",
    "    json.dump(audio_rev_metas, f)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "f7c8714f",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "a453909d",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "id": "5fc18307",
   "metadata": {},
   "source": [
    "## (optional) investigate"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "id": "dc409c9d",
   "metadata": {},
   "outputs": [],
   "source": [
    "with open(os.path.join(TO_REV_DIR, f\"audio_rev_metas.json\")) as f:\n",
    "    audio_rev_metas = json.load(f)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "id": "ea85a5f2",
   "metadata": {},
   "outputs": [],
   "source": [
    "# with open(os.path.join(RAW_DATA_DIR, \"transcripts.tsv\")) as f:\n",
    "#     transcripts = [e.split(\"\\t\") for e in f.read().strip().split(\"\\n\")]\n",
    "# assert(all([len(e) == 2 for e in transcripts]))\n",
    "# transcripts = [(uid, text.lower()) for uid, text in transcripts]\n",
    "# print(len(transcripts), \"transcripts\")\n",
    "# transcripts[:2]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 33,
   "id": "0adcd0a0",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "\n",
       "<audio controls=\"controls\" autobuffer=\"autobuffer\" style=\"width:100%;\">\n",
       "  <source src=\"../../../suno_stream_links/2c40cb60-a90e-4dfc-b1ef-f7a0c9567def.mp3\"/>\n",
       "  Your browser does not support the audio element.\n",
       "</audio>\n"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "Audio.play_audio(audio_rev_metas[0][\"audio_filepath\"])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 34,
   "id": "1a7d97ec",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "\n",
       "<audio controls=\"controls\" autobuffer=\"autobuffer\" style=\"width:100%;\">\n",
       "  <source src=\"../../../suno_stream_links/cc438a1c-84e8-446d-a9bf-92b363ee81d4.mp3\"/>\n",
       "  Your browser does not support the audio element.\n",
       "</audio>\n"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "Audio.play_audio(audio_rev_metas[-1][\"audio_filepath\"])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 35,
   "id": "58a2ca6f",
   "metadata": {},
   "outputs": [],
   "source": [
    "# audio_rev_metas[0][\"segments_meta\"][:10]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 36,
   "id": "41e4dbe5",
   "metadata": {},
   "outputs": [],
   "source": [
    "# audio_rev_metas[-1][\"segments_meta\"][:10]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "4ec55b65",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "426ba2c3",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "dfc212cd",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "id": "88a9e9cc",
   "metadata": {},
   "source": [
    "## Send stuff to rev"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 37,
   "id": "05fbe672",
   "metadata": {},
   "outputs": [],
   "source": [
    "from suno_utils.web.rev import get_auth_string, upload_file, make_order, make_cc_order\n",
    "\n",
    "with open(\"/home/georg/.secrets/secrets.json\") as f:\n",
    "    secrets = json.load(f)\n",
    "    \n",
    "CLIENT_API_KEY = secrets[\"REV_CLIENT_API_KEY\"]\n",
    "USER_API_KEY = secrets[\"REV_USER_API_KEY\"]\n",
    "AUTH_STR = get_auth_string(CLIENT_API_KEY, USER_API_KEY)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 38,
   "id": "2db71de1",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "108.1 hours total\n"
     ]
    }
   ],
   "source": [
    "with open(os.path.join(TO_REV_DIR, f\"audio_rev_metas.json\")) as f:\n",
    "    audio_rev_metas = json.load(f)\n",
    "\n",
    "ORDER_REF_STR = \"sl_tt_100h_en\"\n",
    "\n",
    "tot_duration_s = np.sum([m[\"duration_s\"] for m in audio_rev_metas])\n",
    "print(round(tot_duration_s / 60 / 60, 1), \"hours total\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 39,
   "id": "8c66f7f9",
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "100%|████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 143/143 [11:11<00:00,  4.69s/it]\n"
     ]
    }
   ],
   "source": [
    "order_items = []\n",
    "for m in tqdm.tqdm(audio_rev_metas):\n",
    "    media_loc = upload_file(AUTH_STR, m[\"audio_filepath\"], file_ref_str=m[\"uid\"])\n",
    "    order_items.append(\n",
    "        {\n",
    "            \"media_loc\": media_loc,\n",
    "            \"hotwords\": GLOBAL_HOTWORDS,\n",
    "            \"duration_s\": int(np.ceil(m[\"duration_s\"])),\n",
    "            \"uuid\": m[\"uid\"],\n",
    "        }\n",
    "    )"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 40,
   "id": "a0ee5f4f",
   "metadata": {},
   "outputs": [],
   "source": [
    "with open(os.path.join(TO_REV_DIR, \"01_order_items.json\"), \"w\") as f:\n",
    "    json.dump(order_items, f)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 41,
   "id": "8318e46f",
   "metadata": {},
   "outputs": [],
   "source": [
    "# order_number = make_order(AUTH_STR, order_items, order_ref_str=ORDER_REF_STR)\n",
    "order_number = make_cc_order(AUTH_STR, order_items, order_ref_str=ORDER_REF_STR)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 42,
   "id": "27549d51",
   "metadata": {},
   "outputs": [],
   "source": [
    "with open(os.path.join(TO_REV_DIR, \"02_order_numer.txt\"), \"w\") as f:\n",
    "    f.write(order_number)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "0096715b",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "576b2bef",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "id": "b33dc8e0",
   "metadata": {},
   "source": [
    "## Get rev stuff"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 50,
   "id": "e8b59ece",
   "metadata": {},
   "outputs": [],
   "source": [
    "from suno_utils.web.rev import get_auth_string, get_finished_order, get_transcript\n",
    "\n",
    "with open(\"/home/georg/.secrets/secrets.json\") as f:\n",
    "    secrets = json.load(f)\n",
    "    \n",
    "CLIENT_API_KEY = secrets[\"REV_CLIENT_API_KEY\"]\n",
    "USER_API_KEY = secrets[\"REV_USER_API_KEY\"]\n",
    "AUTH_STR = get_auth_string(CLIENT_API_KEY, USER_API_KEY)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 51,
   "id": "9e4e40af",
   "metadata": {},
   "outputs": [],
   "source": [
    "with open(os.path.join(TO_REV_DIR, \"02_order_numer.txt\")) as f:\n",
    "    order_number = f.read()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 103,
   "id": "d2a371b5",
   "metadata": {},
   "outputs": [],
   "source": [
    "# # grab while still in progress\n",
    "# from suno_utils.web.rev import _get_order_details, _parse_order_response\n",
    "# order_details = _get_order_details(AUTH_STR, order_number)\n",
    "# _, transcript_metas = _parse_order_response(order_details)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 110,
   "id": "9275ae0d",
   "metadata": {},
   "outputs": [],
   "source": [
    "# grab all of it\n",
    "transcript_metas = get_finished_order(AUTH_STR, order_number, blocking=False)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 111,
   "id": "df28d887",
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "100%|████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 143/143 [00:01<00:00, 83.29it/s]\n"
     ]
    }
   ],
   "source": [
    "# 143 total\n",
    "for transcript_meta in tqdm.tqdm(transcript_metas):\n",
    "    transcript_filepath = os.path.join(FROM_REV_DIR, transcript_meta[\"uuid\"] + \".srt\")\n",
    "    if os.path.exists(transcript_filepath):\n",
    "        continue\n",
    "    transcript_subrip = get_transcript(AUTH_STR, transcript_meta)\n",
    "    with open(transcript_filepath, \"w\") as f:\n",
    "        f.write(transcript_subrip)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 112,
   "id": "ed8a84c6",
   "metadata": {},
   "outputs": [],
   "source": [
    "# !rm /mnt/data-ssd-1/data/private/customer/speechly/2022-12-02_tiktok-100h-en/from_rev/34e4a624-2c2f-42f3-a1e2-98a46bb2b75b.srt"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 115,
   "id": "5aa6d928",
   "metadata": {},
   "outputs": [],
   "source": [
    "# !cp srt_fixup/* /mnt/data-ssd-1/data/private/customer/speechly/2022-12-02_tiktok-100h-en/from_rev/"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 116,
   "id": "4a0c1b53",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "- One, zero, seven, four.\r",
      "\r\n"
     ]
    }
   ],
   "source": [
    "!cat /mnt/data-ssd-1/data/private/customer/speechly/2022-12-02_tiktok-100h-en/from_rev/34e4a624-2c2f-42f3-a1e2-98a46bb2b75b.srt | grep 'One, zero, seven, four'"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "880bc74f",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "3ea6f440",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "c0c1c29c",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "id": "b15ce9de",
   "metadata": {},
   "source": [
    "## Parsing rev subrips"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "2b80ff9a",
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "[NeMo W 2022-12-08 10:52:15 nemo_logging:349] /home/georg/venvs/ml/lib/python3.8/site-packages/hydra/core/plugins.py:227: UserWarning: \n",
      "    \tError importing 'hydra_plugins.hydra_colorlog'.\n",
      "    \tPlugin is incompatible with this Hydra version or buggy.\n",
      "    \tRecommended to uninstall or upgrade plugin.\n",
      "    \t\tImportError : cannot import name 'SearchPathPlugin' from 'hydra.plugins' (/home/georg/venvs/ml/lib/python3.8/site-packages/hydra/plugins/__init__.py)\n",
      "      warnings.warn(\n",
      "    \n",
      "[NeMo W 2022-12-08 10:52:15 optimizers:67] Could not import distributed_fused_adam optimizer from Apex\n",
      "[NeMo W 2022-12-08 10:52:16 nemo_logging:349] /home/georg/venvs/ml/lib/python3.8/site-packages/torch/jit/annotations.py:296: UserWarning: TorchScript will treat type annotations of Tensor dtype-specific subtypes as if they are normal Tensors. dtype constraints are not enforced in compilation either.\n",
      "      warnings.warn(\"TorchScript will treat type annotations of Tensor \"\n",
      "    \n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[NeMo I 2022-12-08 10:52:17 post_processing:50] Post processing graph was restored from /tmp/prod_nemo_fst_georg/en_tn_post_processing.far.\n"
     ]
    }
   ],
   "source": [
    "import string\n",
    "from nltk.corpus import words as nltk_words\n",
    "from suno_utils.utils.numbers import safe_round\n",
    "from suno_utils.audio.data_model import Token, Tokens, TEXT, TAG\n",
    "from suno_utils.customers.sanas.pipeline import get_segments\n",
    "from suno_utils.utils.text import normalize_whitespace\n",
    "\n",
    "COMMON_EN_WORDS = set(nltk_words.words())\n",
    "\n",
    "def _parse_srt(transcript_srt):\n",
    "    blocks = []\n",
    "    for block in transcript_srt.strip().split(\"\\n\\n\"):\n",
    "        lines = block.strip().split(\"\\n\")\n",
    "        segment_nr = int(lines[0])\n",
    "        start_str, end_str = lines[1].split(\" --> \")\n",
    "        h, m, s = start_str.split(\":\")\n",
    "        start_s = int(h) * 60**2 + int(m) * 60 + float(s.replace(\",\", \".\"))\n",
    "        h, m, s = end_str.split(\":\")\n",
    "        end_s = int(h) * 60**2 + int(m) * 60 + float(s.replace(\",\", \".\"))\n",
    "        text_lines = lines[2:]\n",
    "        blocks.append({\n",
    "            \"segment_nr\": segment_nr, \n",
    "            \"offset_s\": safe_round(start_s),\n",
    "            \"duration_s\": safe_round(end_s - start_s),\n",
    "            \"text_lines\": text_lines, \n",
    "        })\n",
    "    if blocks[0][\"segment_nr\"] != 1:\n",
    "        raise ValueError(\"First block doesn't start with 1.\")\n",
    "    if any(np.diff([e[\"segment_nr\"] for e in blocks]) != 1):\n",
    "        raise ValueError(\"Parsed block numbers are not consecutive.\")\n",
    "    return blocks\n",
    "\n",
    "def _tag_repl(m):\n",
    "    s = m.group()\n",
    "    if s is not None:\n",
    "        s = s.lower()\n",
    "        s = re.sub(r\"[\\(\\)]\", \" \", s.lower())\n",
    "        s = normalize_whitespace(s)\n",
    "        s = s.replace(\" \", \"_\")\n",
    "        return f\" [{s}] \"\n",
    "\n",
    "def _partial_word_repl(m):\n",
    "    s = m.group()\n",
    "    word = s.strip(\".- \")\n",
    "    probably_fragment = word not in COMMON_EN_WORDS\n",
    "    if probably_fragment:\n",
    "        return f\"{word}* -- \"\n",
    "    else:\n",
    "        return f\"{word} -- \"\n",
    "\n",
    "from suno_utils.utils.text import make_unique_list\n",
    "\n",
    "def _desetify_meta_repl(m):\n",
    "    s = m.group()\n",
    "    tags = re.findall(r\"\\[.*?\\]\", s)\n",
    "    tags = make_unique_list(tags)\n",
    "    return \" {} \".format(\" \".join(tags))\n",
    "    \n",
    "ALLOWED_TAGS = set([\n",
    "    \"laughter\", \"foreign_language\", \"inaudible\", \"music\", \"redacted\", \"crosstalk\", \"beep\"\n",
    "])\n",
    "\n",
    "def _standardize_tags(text):\n",
    "    # collapse meta tags and filter\n",
    "    for m in list(re.finditer(r\"\\[.*?\\]\", text))[::-1]:\n",
    "        tag_text = text[m.start() + 1:m.end() - 1]\n",
    "        # collapse notation\n",
    "        if \"foreign\" in tag_text:\n",
    "            tag_text = \"foreign_language\"\n",
    "        if \"laugh\" in tag_text:\n",
    "            tag_text = \"laughter\"\n",
    "        if \"indistinct\" in tag_text or \"mumbl\" in tag_text:\n",
    "            tag_text = \"inaudible\"\n",
    "        if \"music\" in tag_text or \"\\\"\" in tag_text or \"plays\" in tag_text or \"sing\" in tag_text:\n",
    "            tag_text = \"music\"\n",
    "        if \"chatter\" in tag_text:\n",
    "            tag_text = \"crosstalk\"\n",
    "        # filter\n",
    "        if tag_text in ALLOWED_TAGS:\n",
    "            cleaned_tag_text = f\"[{tag_text}]\"\n",
    "        else:\n",
    "            cleaned_tag_text = \"\"\n",
    "        text = text[:m.start()] + cleaned_tag_text + text[m.end():]\n",
    "    return text\n",
    "    \n",
    "# speechly style choices\n",
    "repeat_ptn = r\"\"\n",
    "for a, b in zip(string.ascii_uppercase, string.ascii_lowercase):\n",
    "    repeat_ptn += r\"[\" + a + b + r\"]\" + b + \"{2,}|\"\n",
    "repeat_ptn = repeat_ptn[:-1]\n",
    "\n",
    "def _repeat_repl(m):\n",
    "    return m.group()[:2]\n",
    "\n",
    "def _consolidate_style_choices(text):\n",
    "    # 'cause -> cause\n",
    "    text = text.replace(\"'em\", \"em\")\n",
    "    text = text.replace(\"'Til\", \"Til\")\n",
    "    text = text.replace(\"'til\", \"til\")\n",
    "    text = text.replace(\"'Till\", \"Til\")\n",
    "    text = text.replace(\"'till\", \"til\")\n",
    "    text = text.replace(\"'Cause\", \"Cause\")\n",
    "    text = text.replace(\"'cause\", \"cause\")\n",
    "    text = text.replace(\"'Bout\", \"Bout\")\n",
    "    text = text.replace(\"'bout\", \"bout\")\n",
    "    text = text.replace(\"'round\", \"round\")\n",
    "    text = text.replace(\"'neath\", \"neath\")\n",
    "    text = text.replace(\"'member\", \"member\")\n",
    "    text = text.replace(\"Imma\", \"I'ma\")\n",
    "    text = text.replace(\"imma\", \"i'ma\")\n",
    "    # fittin', flippin' -> ing\n",
    "    text = re.sub(r\"in\\'(?=\\s|$)\", \"ing\", text)\n",
    "    # word repl\n",
    "    text = re.sub(r\"\\b([Bb])ruh\\b\", \"\\\\1ro\", text)\n",
    "    text = re.sub(r\"\\b([Yy])up\\b\", \"\\\\1ep\", text)\n",
    "    text = re.sub(r\"\\b([Cc])uz\\b\", \"\\\\1ause\", text)\n",
    "    # Mmm, ooooh\n",
    "    text = re.sub(repeat_ptn, _repeat_repl, text)\n",
    "    text = re.sub(r\"\\b([Oo])oh\\b\", \"\\\\1h\", text)\n",
    "    text = re.sub(r\"\\b([Uu])uh\\b\", \"\\\\1h\", text)\n",
    "    text = re.sub(r\"\\b([Aa])ah\\b\", \"\\\\1h\", text)\n",
    "    return text\n",
    "    \n",
    "def parse_rev_captions(transcript_srt, lang=\"en\"):\n",
    "    if lang != \"en\":\n",
    "        raise NotImplementedError(\"only en is supported for now.\")\n",
    "    if len(re.findall(r\"\\(beep\\)\", transcript_srt)) >= 3:\n",
    "        print(\"careful, lots of (beep) detected\")\n",
    "    cur_speaker_id = 0\n",
    "    token_list = []\n",
    "    for block in _parse_srt(transcript_srt):\n",
    "        lines = block[\"text_lines\"]\n",
    "        if len(lines) == 0:\n",
    "            continue\n",
    "        # handle music lyrics\n",
    "        annotated_lines = []\n",
    "        cur_lyrics = False\n",
    "        for line in lines:\n",
    "            is_start = re.match(r\"^\\s*♪.*\", line)\n",
    "            is_end = re.match(r\".*♪\\s*$\", line)\n",
    "            if is_start:\n",
    "                line = line.strip()[1:]\n",
    "            if is_end:\n",
    "                line = line.strip()[:-1]\n",
    "            if is_start and is_end:\n",
    "                annotated_lines.append((line, True))\n",
    "                cur_lyrics = False\n",
    "            elif is_start:\n",
    "                annotated_lines.append((line, True))\n",
    "                cur_lyrics = True\n",
    "            elif is_end:\n",
    "                annotated_lines.append((line, True))\n",
    "                cur_lyrics = False\n",
    "            else:\n",
    "                annotated_lines.append((line, False))\n",
    "            if re.match(r\".*♪\\s*$\", line):\n",
    "                cur_lyrics = False\n",
    "        # merge if no lyrics and if no new speaker\n",
    "        if all([not is_lyrics for _, is_lyrics in annotated_lines]):\n",
    "            merged_lines = []\n",
    "            tmp_lines = []\n",
    "            for line, _ in annotated_lines:\n",
    "                if re.search(r\"^\\s*\\-\", line):\n",
    "                    if len(tmp_lines) > 0:\n",
    "                        merged_lines.append((\" \".join([s.strip() for s in tmp_lines]), False))\n",
    "                        tmp_lines = []\n",
    "                tmp_lines.append(line)\n",
    "            if len(tmp_lines) > 0:\n",
    "                merged_lines.append((\" \".join([s.strip() for s in tmp_lines]), False))\n",
    "                tmp_lines = []\n",
    "        else:\n",
    "            merged_lines = annotated_lines[:]\n",
    "        # add actual lines\n",
    "        for raw_line, is_lyrics in merged_lines:\n",
    "            # handle speaker change\n",
    "            line = raw_line.strip()\n",
    "            if line[:1] == \"-\":\n",
    "                cur_speaker_id += 1\n",
    "                line = line[1:].strip()\n",
    "            # handle meta tags\n",
    "            if re.search(r\"\\([^\\)]*\\(\", line):  # treat nested by brute forcing\n",
    "                line = re.sub(r\"\\((.*)\\)\", _tag_repl, line)\n",
    "            line = re.sub(r\"\\((.*?)\\)\", _tag_repl, line)\n",
    "            # handle redacted\n",
    "            line = re.sub(r\"[^\\s]*\\*+\", \" [redacted] \", line)\n",
    "            # handle hesitations and word fragments\n",
    "            line = re.sub(r\"\\s\\-[\\s\\-]*\", \" -- \", line)  # handle single dash\n",
    "            # TODO: this fails for eg. He said \"Yes-\".\n",
    "            line = re.sub(r\"[A-Za-z]+(\\.{2,}|\\-(\\s|$))\", _partial_word_repl, line)\n",
    "            line = re.sub(r\"\\.{2,}\", \" \", line)  # we only keep interruptions as --\n",
    "            # collapse meta tags and discard if necessary\n",
    "            line = _standardize_tags(line)\n",
    "            # discard partial tags (usually nested)\n",
    "            line = re.sub(r\"^[^\\[]{,20}\\]\", \"\", line)\n",
    "            # clean standalone punctuation (from behind tags)\n",
    "#             line = re.sub(r\"(\\[.*?\\])([\\.\\,\\!\\?\\s]+)\", \" \\\\2 \\\\1 \", line)  # swap with meta\n",
    "            line = re.sub(r\"\\][\\.\\,\\!\\?\\-\\s]+\", \"] \", line)  # remove if two consecutive metas\n",
    "            line = re.sub(r\"[\\.\\,\\!\\?\\-\\s]*\\s([\\.\\,\\!\\?])\", \"\\\\1\", line)\n",
    "            line = re.sub(r\"(^|\\s+)[\\.\\,\\?\\!\\-\\s]+\", \" \", line)\n",
    "            # specific style choices\n",
    "            line = _consolidate_style_choices(line)\n",
    "            # add tokens\n",
    "            line = normalize_whitespace(line)\n",
    "            if len(line) == 0:\n",
    "                continue\n",
    "            tokens = []\n",
    "            for s in line.split():\n",
    "                # identify word fragment\n",
    "                if re.match(r\"^[^\\*]+\\*$\", s):\n",
    "                    is_fragment = True\n",
    "                    s = s[:-1]\n",
    "                else:\n",
    "                    is_fragment = False\n",
    "                if s[:1] == \"[\" and s[-1:] == \"]\":\n",
    "                    is_text = False\n",
    "                elif s == \"--\":\n",
    "                    is_text = False\n",
    "                else:\n",
    "                    is_text = True\n",
    "                if is_text:\n",
    "                    token = Token(\n",
    "                        s, \n",
    "                        speaker_id=cur_speaker_id, \n",
    "                        type=TEXT, \n",
    "                        metadata={\"is_lyrics\": is_lyrics},\n",
    "                    )\n",
    "                else:\n",
    "                    token = Token(s, type=TAG)\n",
    "                if token.type == TAG and len(tokens) > 0 and token == tokens[-1]:\n",
    "                    # skip consecutive meta tokens\n",
    "                    continue\n",
    "                tokens.append(token)\n",
    "                if is_fragment:\n",
    "                     tokens.append(Token(\"[word_fragment_boundary]\", type=TAG))\n",
    "            token_list.extend(tokens)\n",
    "    # do things with global context\n",
    "    # de-setify metas\n",
    "    cleaned_tokens = []\n",
    "    tmp_tokens = []\n",
    "    for token in token_list:\n",
    "        if token.type != TAG:\n",
    "            if len(tmp_tokens) > 0:\n",
    "                cleaned_tokens.extend(tmp_tokens)\n",
    "                tmp_tokens = []\n",
    "            cleaned_tokens.append(token)\n",
    "        else:\n",
    "            if token.value not in set([t.value for t in tmp_tokens]):\n",
    "                tmp_tokens.append(token)\n",
    "    if len(tmp_tokens) > 0:\n",
    "        cleaned_tokens.extend(tmp_tokens)\n",
    "        tmp_tokens = []\n",
    "    transcript_tokens = Tokens(cleaned_tokens)\n",
    "    return transcript_tokens"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "id": "00e04fcf",
   "metadata": {},
   "outputs": [],
   "source": [
    "with open(os.path.join(TO_REV_DIR, f\"audio_rev_metas.json\")) as f:\n",
    "    audio_rev_metas = json.load(f)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "id": "936b45dd",
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "126/126 segments retained in 142a4022-329c-4c4a-aaf3-bdc8775ed4e7.\n",
      "119/119 segments retained in 79d7cd91-5a2c-433b-a125-c5536c87b29f.\n",
      "116/116 segments retained in 76966739-a515-4b3a-8661-33c8be569806.\n",
      "careful, lots of (beep) detected\n",
      "110/110 segments retained in b0391727-d931-4113-a851-7205d1f9f201.\n",
      "102/102 segments retained in 92297065-dcc5-41bb-accb-d15d795c3a01.\n",
      "117/117 segments retained in f2d2d379-8617-4e6e-9f75-aa0726141c18.\n",
      "115/115 segments retained in fcd35870-5f60-4289-b226-0ba87a0b8ec0.\n",
      "123/123 segments retained in 58f42442-ad3a-41ec-9f84-10773a052027.\n",
      "118/118 segments retained in 4bd691db-1933-472e-a33d-1fe59968910e.\n",
      "112/112 segments retained in a973ac7b-cd5c-401d-8b7c-a0c5a63e84f9.\n",
      "careful, lots of (beep) detected\n",
      "119/119 segments retained in f915de02-eb76-412f-a2e3-2071c75ca325.\n",
      "115/115 segments retained in d43b82e1-6b67-4247-a664-cbf9bd7e793e.\n",
      "128/128 segments retained in b7a05a26-3ed2-4f5d-bb24-c4438175b51b.\n",
      "112/112 segments retained in 34e4a624-2c2f-42f3-a1e2-98a46bb2b75b.\n",
      "102/102 segments retained in 316f8411-08c2-4b5f-8362-d942716364dc.\n",
      "98/98 segments retained in c88b079e-f177-4867-8256-ef8f2d6629e0.\n",
      "114/114 segments retained in 3b5d8aba-8aac-4e07-9143-181f34f0db41.\n",
      "109/109 segments retained in 3b031ccd-1d3e-42f6-93bf-cfc958a63c8b.\n",
      "94/94 segments retained in 14dfa2cc-df34-4895-bb28-da8d2116a522.\n",
      "102/102 segments retained in 1a591e35-72e2-4976-8ec3-fc8096077701.\n",
      "97/97 segments retained in 41f98d99-ab3b-4bd7-b088-c0d0dce9157a.\n",
      "127/127 segments retained in 1e3859f4-6feb-45b5-801a-eb62c4f90a08.\n",
      "112/112 segments retained in 8f69815b-3cec-48eb-acd0-e1a781d8f882.\n",
      "125/125 segments retained in a86add9f-fcee-4634-8ffb-f7ab3af6c4db.\n",
      "114/114 segments retained in 0a03a664-5796-4b09-976d-a4359c2b7c05.\n",
      "110/110 segments retained in c220a437-b92d-4c29-9e02-f3c5f569d22f.\n",
      "137/137 segments retained in 168071cb-5298-4e03-a0c7-af4e0c987b7b.\n",
      "128/128 segments retained in a59764e3-9e56-418b-8ef2-756e88df9606.\n",
      "94/94 segments retained in 929c54a7-4494-405b-a98e-00e8c6392546.\n",
      "107/107 segments retained in 6b5e2ac2-b195-48be-bea2-59914cb19fa4.\n",
      "careful, lots of (beep) detected\n",
      "102/102 segments retained in 48972eda-1ff8-46c7-8a88-e25513463e43.\n",
      "125/125 segments retained in a9a27141-6300-44c8-8368-06b25e9d1e57.\n",
      "118/118 segments retained in 66117e64-a213-497c-b8e9-9c163b605af4.\n",
      "careful, lots of (beep) detected\n",
      "112/112 segments retained in 8005a6b7-52da-4f5d-a630-328caa14846f.\n",
      "120/120 segments retained in 2126ebd4-2b8b-4174-8081-107531fb3eb4.\n",
      "113/113 segments retained in e37beee3-f52a-470b-a7da-ec75b1ab9c3a.\n",
      "111/111 segments retained in a73c00c7-57e3-4867-9c72-79af531eb9c6.\n",
      "111/111 segments retained in ca53d9ff-a8c2-4125-886d-b0a3b15fe96f.\n",
      "110/110 segments retained in c6c2d25e-2b25-4ae5-bc98-e751585d46e7.\n",
      "103/103 segments retained in ac151616-a92a-4ea6-a89a-4c025e4922e0.\n",
      "110/110 segments retained in 9521c853-ac50-4b8c-9fa7-39e56eb55367.\n",
      "98/98 segments retained in 57e721c0-50ed-418c-83dc-c596137467e4.\n",
      "careful, lots of (beep) detected\n",
      "129/129 segments retained in 55031147-b818-40ed-8380-b1b98d7595cb.\n",
      "105/105 segments retained in 6e4adef6-0390-4f59-9f60-7f4948777f85.\n",
      "120/120 segments retained in 3fed77f0-dbdd-4100-b610-da2a31ea741b.\n",
      "96/96 segments retained in 44c1beaa-3587-4752-919a-1e515030346c.\n",
      "100/100 segments retained in 08ee6a98-4b2e-4ff1-a10c-887508e47252.\n",
      "careful, lots of (beep) detected\n",
      "111/111 segments retained in b157d55f-cfef-4650-957d-d44b9b0c1805.\n",
      "110/110 segments retained in 1e55b4ab-5478-447c-9968-6d63b8b3627e.\n",
      "105/105 segments retained in edc23034-8535-495f-b8e1-cb32adec7b2f.\n",
      "careful, lots of (beep) detected\n",
      "102/102 segments retained in d5f8561f-1997-4689-8dd9-9cdf3e204573.\n",
      "116/116 segments retained in cd1081ce-83bb-4af6-9b8a-82ebc28e3ca1.\n",
      "114/114 segments retained in 71879711-0126-4f91-915e-14706e01cd5d.\n",
      "111/111 segments retained in 48dae73a-44f5-408e-80ce-6de76bb697a1.\n",
      "106/106 segments retained in dc78689d-23f2-4c2a-8126-004e60f7ae6c.\n",
      "96/96 segments retained in 8168f708-0495-48de-80d5-ecac7fc4587a.\n",
      "119/119 segments retained in ef593c6c-d40e-477b-9795-ef093d93cb1a.\n",
      "104/104 segments retained in 0dcf046d-2a36-44d3-9a76-bff3a96cbb16.\n",
      "94/94 segments retained in 9635b262-a184-45c7-a404-304cb22ee025.\n",
      "103/103 segments retained in b9cd7f41-377e-4273-a080-46737a8f2349.\n",
      "109/109 segments retained in 5a274194-62ac-45ae-b216-d3779ab4d4cc.\n",
      "110/110 segments retained in 78a0640d-04ad-40a1-8139-1f4e621f656b.\n",
      "108/108 segments retained in dbb69205-c946-4bac-933c-dbab3d353d75.\n",
      "118/118 segments retained in 70592681-8042-4d6a-99f0-38b24f697fd4.\n",
      "131/131 segments retained in ac0c8fe6-e24c-4a04-9811-8716be1eddb2.\n",
      "108/108 segments retained in 403cfd8d-898a-4926-be68-70bec9c46e5e.\n",
      "109/109 segments retained in d6e09a80-3fc4-4b26-a5bb-911b3fc283cf.\n",
      "119/119 segments retained in d9076425-836e-4a60-b27b-332597c9bd0a.\n",
      "114/114 segments retained in 86909de7-c06a-4282-9294-2dd49558a7d5.\n",
      "105/105 segments retained in 22f345f4-35b3-4469-aade-cc9c6914e49b.\n",
      "112/112 segments retained in 2826a58c-363d-4646-9188-658df536d9db.\n",
      "100/100 segments retained in fca87e3c-f43f-4c1c-9e94-a50a38a47138.\n",
      "104/104 segments retained in 4cac1d62-9e46-48c6-b92d-166040a696b1.\n",
      "127/127 segments retained in afe980e0-38ac-419a-932e-468548cb10ec.\n",
      "113/113 segments retained in a15700ea-9b5d-4395-81c0-2b0a4fb18f96.\n",
      "109/109 segments retained in 5b941516-4043-4868-9cf9-70f15f330160.\n",
      "109/109 segments retained in 5afbfbcd-d5e7-411e-be91-7c07819cc2c8.\n",
      "123/123 segments retained in e5c68e69-3116-4915-9676-9c97a21908a2.\n",
      "101/101 segments retained in bc2d7c6d-4c67-411c-84af-4194494062ec.\n",
      "118/118 segments retained in c3c480d3-1347-49c1-9192-b577d0068bb5.\n",
      "106/106 segments retained in e04541b1-1e97-44bc-a803-dced7a9b5543.\n",
      "104/104 segments retained in 65889b08-b56c-452e-b69c-5898742b9809.\n",
      "careful, lots of (beep) detected\n",
      "121/121 segments retained in d6fafc66-0c6e-4023-b8ba-368275de69a9.\n",
      "109/109 segments retained in 95c58e1a-c823-4901-8ef3-70ea4bf488f9.\n",
      "125/125 segments retained in 9dd718fb-9478-4487-87fb-51dfc3d7f5cc.\n",
      "117/117 segments retained in dcbab770-8727-46e1-a094-58436e5b6da6.\n",
      "97/97 segments retained in 8e24ab28-42eb-46d5-ba45-da9a01e750cb.\n",
      "careful, lots of (beep) detected\n",
      "108/108 segments retained in f722e804-2ade-42f4-8d64-e2ace30b5b9b.\n",
      "114/114 segments retained in c34ca2b4-3b1f-4088-a831-9cb6a2df12ab.\n",
      "112/112 segments retained in d139704f-fb8b-49a7-9db6-4aa5ac9f28dd.\n",
      "107/107 segments retained in 7dbc78a8-b21c-435e-8d19-8e22eb32d4c0.\n",
      "119/119 segments retained in 00210e3e-3a0f-419a-a94f-513e2eb7b66f.\n",
      "89/89 segments retained in 8b7d7e4d-ac4f-41d8-94cf-6a55bb28d237.\n",
      "99/99 segments retained in 6f8f3c72-51ed-41af-9bfa-b48157b29d56.\n",
      "careful, lots of (beep) detected\n",
      "104/104 segments retained in 82550488-0836-4cd2-8d0d-43cf4624648f.\n",
      "94/94 segments retained in 6ad2e030-4c3e-4bda-8804-ae5da60b0670.\n",
      "121/121 segments retained in 17540763-b243-4c32-be21-7b8d52ad0645.\n",
      "132/132 segments retained in fc28f445-b2c3-483f-970e-86a5de1efe37.\n",
      "123/123 segments retained in 2db3a859-b2d0-47d5-879a-3fea3fe5c7a3.\n",
      "careful, lots of (beep) detected\n",
      "95/95 segments retained in 713e4847-f798-4629-a893-532b6735778e.\n",
      "119/119 segments retained in ede0cc16-19ed-476c-8940-120c29adb8ec.\n",
      "106/106 segments retained in 8d3a6cc5-14b9-40b4-9bbd-a0518dfd8740.\n",
      "103/103 segments retained in 5dcc9a30-a2b9-4c54-8756-f431419910a7.\n",
      "122/122 segments retained in a1f1f7cc-56e0-4686-9c6d-9862c1a4c538.\n",
      "112/112 segments retained in aacac44f-de90-4e7a-99d4-86f00abb39d1.\n",
      "122/122 segments retained in 941333f3-76f8-4d84-9448-f2c68571822e.\n",
      "115/115 segments retained in 87ac1f53-9f95-4b63-9d3d-ae66f8fdb956.\n",
      "103/103 segments retained in 97526b04-cdf5-4621-aa72-19d9619d0210.\n",
      "103/103 segments retained in dd2cbd24-dc9a-4478-974e-82391dd49cee.\n",
      "careful, lots of (beep) detected\n",
      "113/113 segments retained in a4346ae1-3dc2-4f40-96a8-76d3b752c135.\n",
      "127/127 segments retained in d3138c7f-f16a-4dba-a32b-493019a3f55e.\n",
      "117/117 segments retained in 53647bd7-f422-41d9-8476-bbb8da60c474.\n",
      "careful, lots of (beep) detected\n",
      "110/110 segments retained in 02ca74ad-2551-4e7b-8480-e1d2a250425a.\n",
      "107/107 segments retained in d5e13f0e-db4e-4af9-bc92-c0b381f24dad.\n",
      "115/115 segments retained in dcfd4d4d-fb19-439b-9ec8-c1349d97dd5a.\n",
      "110/110 segments retained in 75b92e49-5d5c-47e7-8fe5-5a709bef4593.\n",
      "careful, lots of (beep) detected\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "98/98 segments retained in 794c145c-8567-46a4-8ff1-6995bd45ebb7.\n",
      "118/118 segments retained in 645a394e-fd53-4553-a8c4-4749e56feef1.\n",
      "102/102 segments retained in fabc56fb-4e91-4e36-957c-e75e7ffc1ce9.\n",
      "101/101 segments retained in eb055456-83ed-4ae2-ba69-9bc0c386f845.\n",
      "102/102 segments retained in 335b9eaa-6942-4651-b9c4-049a070e50db.\n",
      "122/122 segments retained in 4080a0aa-d452-4d27-ad7c-cd9da7a00399.\n",
      "135/135 segments retained in b4190139-747a-4bef-915b-76a48de474ae.\n",
      "122/122 segments retained in 7c9474c4-c3db-4bf9-9de2-0df322027b5a.\n",
      "124/124 segments retained in df110844-2591-47f9-896f-19e62b73d88c.\n",
      "116/116 segments retained in c0fbeb96-f93d-40f1-ab63-726f5e46278e.\n",
      "116/116 segments retained in 41d0fc55-bb6d-4599-a0dd-afabff5c2af4.\n",
      "110/110 segments retained in f23f92bc-3f67-4721-b8a5-740026b77b06.\n",
      "105/105 segments retained in c4a0fc19-d8d5-48bb-95f0-29d045bb6e6c.\n",
      "101/101 segments retained in 57bf5c63-bf1f-4831-a5c5-48e6b2832d29.\n",
      "136/136 segments retained in 0cc21484-5111-4f43-9405-49fd30d674cb.\n",
      "104/104 segments retained in 915bb747-0b0e-4cb5-bad3-5e4d3ca79f73.\n",
      "101/101 segments retained in 0ce45ad4-5223-4d16-b0dc-56896712e41f.\n",
      "105/105 segments retained in 1629b471-a40a-4b6e-82e1-cd8667a4d77c.\n",
      "106/106 segments retained in 9ac4e269-8ec5-4487-be06-e0972bc466f5.\n",
      "93/93 segments retained in 93958fd1-609e-4a8a-a830-63fc2932bda7.\n",
      "95/95 segments retained in 25e7bfde-aa82-4ee9-87f8-b83f4b4156b1.\n",
      "121/121 segments retained in ad67ebdf-0e90-4151-9eec-b3785586de4c.\n",
      "102/102 segments retained in e67383a1-0e8b-4364-ac1f-29cade5528bd.\n",
      "104/104 segments retained in 9a32b7db-a7ba-46ad-abcc-1cfce30d8b4e.\n",
      "120/120 segments retained in bb9161fb-4edf-48c1-91a2-da99026392a7.\n",
      "118/118 segments retained in 8d09c315-cb60-4e9a-b05d-329585f7da06.\n",
      "93/93 segments retained in b897f60f-c3e1-4480-96e1-b7fc2ff0e174.\n"
     ]
    }
   ],
   "source": [
    "# from suno_utils.web.rev import parse_transcript\n",
    "segment_transcripts = []\n",
    "for m in audio_rev_metas:\n",
    "#     if m[\"uid\"] != \"34e4a624-2c2f-42f3-a1e2-98a46bb2b75b\":\n",
    "#         continue\n",
    "    srt_filepath = os.path.join(FROM_REV_DIR, m[\"uid\"] + \".srt\")\n",
    "    if not os.path.exists(srt_filepath):\n",
    "        print(\"not found, skipping...\")\n",
    "        continue\n",
    "    with open(srt_filepath) as f:\n",
    "        transcript_srt = f.read().strip(\"\\ufeff\")\n",
    "    try:\n",
    "        rev_transcript = parse_rev_captions(transcript_srt)\n",
    "    except Exception as e:\n",
    "        print(f\"ERROR in {m['uid']}: {str(e)}\")\n",
    "        continue\n",
    "    speech_segment_info = [mm for mm in m[\"segments_meta\"] if mm[\"type\"] == \"speech\"]\n",
    "    n_segments = len(speech_segment_info)\n",
    "    min_segment_n = m[\"segments_meta\"][0][\"segment_number\"]\n",
    "    max_segment_n = m[\"segments_meta\"][-1][\"segment_number\"]\n",
    "    assert(len(speech_segment_info) == max_segment_n - min_segment_n + 1)\n",
    "    token_segments = get_segments(\n",
    "        rev_transcript, min_segment_n, max_segment_n, global_indicator_speaker=False, n_indicator_digits=4,\n",
    "    )\n",
    "    segment_transcripts_chunk = []\n",
    "    missing_ids = set(range(min_segment_n, max_segment_n+1))\n",
    "    for segment_idx, tokens in token_segments:\n",
    "        segment_info = speech_segment_info[segment_idx-min_segment_n]\n",
    "        segment_transcripts_chunk.append({\n",
    "            \"uid\": segment_info[\"orginial_audio_uid\"],\n",
    "            \"duration_s\": segment_info[\"duration_s\"],\n",
    "            \"transcript\": tokens.anonymize_speakers(),\n",
    "        })\n",
    "        missing_ids -= set([segment_idx])\n",
    "    missing_ids = sorted([str(n) for n in missing_ids])\n",
    "    missing_str = \"\"\n",
    "    if len(missing_ids) > 0:\n",
    "        missing_str = \" (\" + \",\".join(missing_ids[:5])\n",
    "        if len(missing_ids) > 5:\n",
    "            missing_str += \"...\"\n",
    "        missing_str += \")\"\n",
    "    print(\"{}/{} segments retained in {}{}.\".format(\n",
    "        len(segment_transcripts_chunk), n_segments, m[\"uid\"], missing_str\n",
    "    ))\n",
    "    segment_transcripts.extend(segment_transcripts_chunk)\n",
    "#     break"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "id": "8f2027b8",
   "metadata": {},
   "outputs": [],
   "source": [
    "# TODO: some music lyrics with hashtag: #I got hundreds on me\n",
    "# TODO: [word_fragment_boundary] looks often wrong"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "id": "2cbe6494",
   "metadata": {},
   "outputs": [],
   "source": [
    "# for m in segment_transcripts[:5]:\n",
    "#     print(m[\"uid\"])\n",
    "#     print(m[\"transcript\"].text)\n",
    "#     print(\"-\"*10)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "id": "136464c0",
   "metadata": {},
   "outputs": [],
   "source": [
    "# print(transcript_srt)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "id": "50313c41",
   "metadata": {},
   "outputs": [],
   "source": [
    "# segment_uid = \"d1bf2bea-0c9e-4223-9bb5-45ffa0acd428\"\n",
    "# for m in segments_manifest:\n",
    "#     if m[\"id\"] == segment_uid:\n",
    "#         print(\"transcript id:\", m[\"source_transcript_id\"])\n",
    "#         break"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "id": "90178e26",
   "metadata": {},
   "outputs": [],
   "source": [
    "# save as json\n",
    "import copy\n",
    "l = []\n",
    "for m in segment_transcripts:\n",
    "    e = copy.deepcopy(m)\n",
    "    e[\"transcript\"] = e[\"transcript\"].as_dict()\n",
    "    l.append(e)\n",
    "with open(os.path.join(BASE_DIR, \"parsed_transcripts.json\"), \"w\") as f:\n",
    "    json.dump(l, f)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "4f02f420",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "703efe1d",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "9937474e",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "id": "2624f95e",
   "metadata": {},
   "source": [
    "## prepare pipeline"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "id": "9433c48a",
   "metadata": {},
   "outputs": [],
   "source": [
    "# map segment id to rev submission id\n",
    "with open(os.path.join(TO_REV_DIR, f\"audio_rev_metas.json\")) as f:\n",
    "    audio_rev_metas = json.load(f)\n",
    "segment_to_rev_id = {}\n",
    "for m in audio_rev_metas:\n",
    "    rev_id = m[\"uid\"]\n",
    "    for mm in m[\"segments_meta\"]:\n",
    "        if mm[\"type\"] != \"speech\":\n",
    "            continue\n",
    "        segment_to_rev_id[mm[\"orginial_audio_uid\"]] = rev_id"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "id": "a29859c9",
   "metadata": {},
   "outputs": [],
   "source": [
    "with open(os.path.join(BASE_DIR, \"parsed_transcripts.json\")) as f:\n",
    "    segment_transcripts = json.load(f)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "id": "020e71bb",
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "100%|███████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 15893/15893 [01:09<00:00, 230.03it/s]\n"
     ]
    }
   ],
   "source": [
    "manifest = []\n",
    "for m in tqdm.tqdm(segment_transcripts):\n",
    "    segment_filepath = os.path.join(AUDIO_DIR, m[\"uid\"] + \".wav\")                          \n",
    "    new_segment_filepath = os.path.join(SEGMENTS_DIR, \"{}.wav\".format(m[\"uid\"]))\n",
    "    if not os.path.exists(new_segment_filepath):\n",
    "        audio = Audio.from_file(segment_filepath, sample_rate=16_000, byte_width=2)\n",
    "        audio.to_wav(new_segment_filepath)\n",
    "    manifest.append({\n",
    "        \"id\": m[\"uid\"],\n",
    "        \"uri\": new_segment_filepath,\n",
    "        \"duration_s\": m[\"duration_s\"],\n",
    "        \"transcript\": {\"tokens\": m[\"transcript\"]},\n",
    "        \"ignore_segment\": False,\n",
    "        \"ignore_reason\": \"\",\n",
    "        \"source_audio_offset_s\": 0,\n",
    "        \"source_audio_uri\": segment_filepath,\n",
    "        \"source_audio_id\": m[\"uid\"],\n",
    "        \"source_transcript_id\": segment_to_rev_id[m[\"uid\"]],\n",
    "        \"source_transcript_uri\": os.path.join(FROM_REV_DIR, segment_to_rev_id[m[\"uid\"]] + \".srt\"),\n",
    "    })"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "id": "cee8873a",
   "metadata": {},
   "outputs": [],
   "source": [
    "with open(os.path.join(ARTIFACTS_DIR, \"01_segment_meta.json\"), \"w\") as f:\n",
    "    json.dump(manifest, f)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "96c9e4f4",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "6cf2b71d",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "id": "651e980e",
   "metadata": {},
   "source": [
    "## QA"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "id": "a8dae9e1",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "100.0 hours\n"
     ]
    }
   ],
   "source": [
    "with open(os.path.join(ARTIFACTS_DIR, \"01_segment_meta.json\")) as f:\n",
    "    segments_manifest = json.load(f)\n",
    "print(round(np.sum([e[\"duration_s\"] for e in segments_manifest]) / 60 / 60, 1), \"hours\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "id": "ae6f9277",
   "metadata": {},
   "outputs": [],
   "source": [
    "# TODO: rev parse \"You-\"\n",
    "# TODO: mistake\n",
    "#   d1bf2bea-0c9e-4223-9bb5-45ffa0acd428\n",
    "#   John 3:20. I'm gonna read 1st John 3:18 through 20, cause I think that helps to understand this a little \n",
    "#   bit more. And here's what it says, little children [word_fragment_boundary] Zero, teo, zero. Episode page \n",
    "#   18 is four lines as the ending section of a paragraph on the previous page, and then there's a page break "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "id": "6a5f0e8c",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "dd4e2b86-ad76-4c2b-9ccd-982c6c474eb8\n",
      "Whacked mini mushroom.\n"
     ]
    },
    {
     "data": {
      "text/html": [
       "\n",
       "<audio controls=\"controls\" autobuffer=\"autobuffer\" style=\"width:100%;\">\n",
       "  <source src=\"../../../suno_stream_links/b0d37745-254f-40aa-9085-60a73bf7b795.wav\"/>\n",
       "  Your browser does not support the audio element.\n",
       "</audio>\n"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "----------\n",
      "a5ab68dc-c9fc-4058-8dbb-9bb5f99c764a\n",
      "The Emergencies Act enabled local authorities to end the illegal blockades. We've heard from the commissioner of the RCMP, police chiefs, experts, and political leadership that it was essential to the police response. And that it offered precision and clarity as they did their important work. But even after all this is ended, conservative MPs still can't pick a lane. Canadians want to know, do they stand with blockaders or do they stand with Canadian communities? Police were clear that they needed tools not held by any federal, provincial, or territorial law. It was only after we got advice from law enforcement that we invoked The Emergencies Act. As for you, Madame Chair, did yourself or anyone in the OPS request the invocation of The Emergency Act? I did not make that request. I'm not aware of anybody else in the Otto police service who did.\n"
     ]
    },
    {
     "data": {
      "text/html": [
       "\n",
       "<audio controls=\"controls\" autobuffer=\"autobuffer\" style=\"width:100%;\">\n",
       "  <source src=\"../../../suno_stream_links/53c5b5a2-878a-4b7c-b2f5-03847783e115.wav\"/>\n",
       "  Your browser does not support the audio element.\n",
       "</audio>\n"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "----------\n",
      "6398522a-acd5-41fb-9c8f-960ea59f29f4\n",
      "Because if I want him, I could have him I aint cappin', that's the thing If I let him eat this something You might never get him back ♪ ♪ I don't\n"
     ]
    },
    {
     "data": {
      "text/html": [
       "\n",
       "<audio controls=\"controls\" autobuffer=\"autobuffer\" style=\"width:100%;\">\n",
       "  <source src=\"../../../suno_stream_links/f2298ad5-bcc0-4b63-b9dc-c675d4dae3a1.wav\"/>\n",
       "  Your browser does not support the audio element.\n",
       "</audio>\n"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "----------\n",
      "26c6356c-cf6f-42a3-8681-7ee4f29de935\n",
      "Where you going, Eds? If you lived here you'd be home by now. Come join the clown, Eds. You'll float down here. We all float down here. Yes, we do. [laughter]\n"
     ]
    },
    {
     "data": {
      "text/html": [
       "\n",
       "<audio controls=\"controls\" autobuffer=\"autobuffer\" style=\"width:100%;\">\n",
       "  <source src=\"../../../suno_stream_links/45fe94a0-6938-4d8d-8852-ed6e1b311999.wav\"/>\n",
       "  Your browser does not support the audio element.\n",
       "</audio>\n"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "----------\n",
      "7fe67580-d9f9-4ebd-a3ec-39f6ca853d6b\n",
      "Jennifer Lopez makes a very emotional speech at tonight's MTV Music awards. But some of you who know me, know this person, and I wanna take this moment to do this. I want to thank Benny Medina. Wow. He doesn't like me to talk about him. He likes to be in the background. You know \"Jerry Maguire\" where he is like the half of the thing. He's that guy. But he's more than just my manager. If there's one person, who believed in me from the beginning, from the first time I played [word_fragment_boundary]\n"
     ]
    },
    {
     "data": {
      "text/html": [
       "\n",
       "<audio controls=\"controls\" autobuffer=\"autobuffer\" style=\"width:100%;\">\n",
       "  <source src=\"../../../suno_stream_links/528abdc2-4254-4d17-b207-d85ee9eaba20.wav\"/>\n",
       "  Your browser does not support the audio element.\n",
       "</audio>\n"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "----------\n"
     ]
    }
   ],
   "source": [
    "import random\n",
    "# random ones\n",
    "# l = [e for e in segments_manifest if len(e[\"transcript\"][\"tokens\"]) == 0]\n",
    "l = segments_manifest[:]\n",
    "random.shuffle(l)\n",
    "for e in l[:5]:\n",
    "    print(e[\"id\"])\n",
    "    print(Tokens.from_dict(e[\"transcript\"][\"tokens\"]).text)\n",
    "    Audio.play_audio(e[\"uri\"])\n",
    "    print(\"-\"*10)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "081a8b29",
   "metadata": {},
   "outputs": [],
   "source": [
    "# # get rev id for segment\n",
    "# segment_uid = \"846622bb-b4ab-439c-9316-3683831bafbe\"\n",
    "# for m in segments_manifest:\n",
    "#     if m[\"id\"] == segment_uid:\n",
    "#         print(m[\"source_transcript_id\"])\n",
    "#         break"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "a574e8b2",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "36eb7b98",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "id": "7b8ddb47",
   "metadata": {},
   "source": [
    "## run pipeline"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 90,
   "id": "1e319351",
   "metadata": {},
   "outputs": [],
   "source": [
    "# # reset pipeline\n",
    "# !mv /mnt/data-ssd-1/data/private/customer/speechly/2022-12-02_tiktok-100h-en/pipeline/2022_12_02/artifacts/01_segment_meta.json /tmp/01_segment_meta.json\n",
    "# !rm -rf /mnt/data-ssd-1/data/private/customer/speechly/2022-12-02_tiktok-100h-en/pipeline/2022_12_02/artifacts/*\n",
    "# !mv /tmp/01_segment_meta.json /mnt/data-ssd-1/data/private/customer/speechly/2022-12-02_tiktok-100h-en/pipeline/2022_12_02/artifacts/"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 57,
   "id": "7fcf3139",
   "metadata": {},
   "outputs": [],
   "source": [
    "# # 17mins for 40h\n",
    "# CUDA_VISIBLE_DEVICES=\"\" python /home/georg/notebooks/customers/speechly/tiktok_100h_en/run_modified_pipeline.py"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "245bf746",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "b01ea31f",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "id": "0a83b4f7",
   "metadata": {},
   "source": [
    "## Check difficult norm stuff"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "id": "a1c4d36f",
   "metadata": {},
   "outputs": [],
   "source": [
    "# from suno_utils.utils.text_normalizer import normalize, NORMALIZER, _normalize"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "id": "0e5a473a",
   "metadata": {},
   "outputs": [],
   "source": [
    "# $68,500\n",
    "# $68,500\n",
    "# $73,745 \n",
    "# $59,395\n",
    "# $1,800 eighteen hundred\n",
    "# 7,800 pounds seventy eight hundred pounds"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "id": "646395d1",
   "metadata": {},
   "outputs": [],
   "source": [
    "# NORMALIZER.normalize(\n",
    "#     text=\"$1,800\",\n",
    "#     verbose=False,\n",
    "#     n_tagged=-1,\n",
    "#     punct_post_process=False,\n",
    "# )"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 92,
   "id": "66508929",
   "metadata": {},
   "outputs": [],
   "source": [
    "# CUSTOM_NORM_RULES = [\n",
    "#     (re.compile(r\"\\$\"), \" \"),\n",
    "#     (re.compile(r\"\\b([0-9])\\,([0-9])00\\b\"), \"\\\\1\\\\2 hundred\"),\n",
    "#     (re.compile(r\"\\$([0-9])\\,([0-9])00\\b\"), \"\\\\1\\\\2 hundred\"),\n",
    "# ]\n",
    "\n",
    "# _normalize(\n",
    "#     text_list=\"$1,800\",\n",
    "#     asr_prediction=\"eighteen hundred\",\n",
    "#     custom_norm_rules=CUSTOM_NORM_RULES,\n",
    "# )"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "066dea18",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "fb1aec05",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "id": "cfa1946d",
   "metadata": {},
   "source": [
    "## look at results"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "id": "30275498",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "100.0 hours\n"
     ]
    }
   ],
   "source": [
    "with open(os.path.join(ARTIFACTS_DIR, \"02_segment_meta_post_norm_and_asr.json\")) as f:\n",
    "    segments_manifest = json.load(f)\n",
    "print(round(np.sum([e[\"duration_s\"] for e in segments_manifest]) / 60 / 60, 1), \"hours\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 80,
   "id": "80a25aba",
   "metadata": {},
   "outputs": [],
   "source": [
    "# make reverse map for rev so we know submitted file and segment number \n",
    "with open(os.path.join(TO_REV_DIR, f\"audio_rev_metas.json\")) as f:\n",
    "    audio_rev_metas = json.load(f)\n",
    "segment_to_rev_map = {}\n",
    "for m in audio_rev_metas:\n",
    "    rev_id = m[\"uid\"]\n",
    "    for mm in m[\"segments_meta\"]:\n",
    "        if mm[\"type\"] != \"speech\":\n",
    "            continue\n",
    "        segment_to_rev_map[mm[\"orginial_audio_uid\"]] = {\n",
    "            \"segment_nr\": mm[\"segment_number\"],\n",
    "            \"rev_id\": rev_id,\n",
    "        }"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "id": "5848265d",
   "metadata": {
    "scrolled": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "60141325-3091-4839-a9ad-79a3482e7f2e\n",
      "Thanks for having me over man. Where I can hang this jacket girl? Pass me. Girl, you know you're just like family man. You always welcome here. Wait, where you get this jacket from? This thing look familiar. Natasha, come. Yeah ma. What happened? Who is the girl that me never see she before? Ma that's my best friend Savitri? Mm mm. No, cut that thing out bout best friend. The girl envy are your bad I telling you. My spirit don't text you. Don't like she Natasha. No man. You don't know she like I do. All right. You're gonna learn the hard way. That's not Ramesh jacket?\n",
      "thanks for having me over man where i can hang this jacket girl pass me girl you know you're just like family man you always welcome here wait where you get this jacket from this thing look familiar natasha come yeah ma what happened who is the girl that me never see she before ma that's my best friend savitri mm mm no cut that thing out bout best friend the girl envy are your bad i telling you my spirit don't text you don't like she natasha no man you don't know she like i do all right you're gonna learn the hard way that's not ramesh jacket\n"
     ]
    },
    {
     "data": {
      "text/html": [
       "\n",
       "<audio controls=\"controls\" autobuffer=\"autobuffer\" style=\"width:100%;\">\n",
       "  <source src=\"../../../suno_stream_links/7596c111-a883-45fb-aa09-31db70a48262.wav\"/>\n",
       "  Your browser does not support the audio element.\n",
       "</audio>\n"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "----------\n",
      "455d4d0c-8c0e-442e-a6c6-46b48327d66b\n",
      "[foreign_language]\n",
      "[foreign_language]\n"
     ]
    },
    {
     "data": {
      "text/html": [
       "\n",
       "<audio controls=\"controls\" autobuffer=\"autobuffer\" style=\"width:100%;\">\n",
       "  <source src=\"../../../suno_stream_links/95296767-905e-4ba3-a5fe-7f6895bc9565.wav\"/>\n",
       "  Your browser does not support the audio element.\n",
       "</audio>\n"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "----------\n",
      "a580d701-dbfb-4869-af29-2e5812459659\n",
      "Like the birds of a feather, baby. We real life made For each other. And it's hard to keep my cool. When other bitches trying to get with my dude. And when other chickens trying to get in my coop. Cause you're a one in a million.\n",
      "like the birds of a feather baby we real life made for each other and it's hard to keep my cool when other bitches trying to get with my dude and when other chickens trying to get in my coop cause you're a one in a million\n"
     ]
    },
    {
     "data": {
      "text/html": [
       "\n",
       "<audio controls=\"controls\" autobuffer=\"autobuffer\" style=\"width:100%;\">\n",
       "  <source src=\"../../../suno_stream_links/7dabddef-64f1-4880-b1ba-bc3f32db8eb9.wav\"/>\n",
       "  Your browser does not support the audio element.\n",
       "</audio>\n"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "----------\n",
      "8e69cfbd-d1ed-402b-9378-b4e89092ef20\n",
      "That the American medical system is designed to provide the least amount of healthcare possible. Oh it's even way worse than that. You know, a couple weeks ago the United States was found guilty of crimes against humanity? Do you wanna know how they determine one of the ways in which the United States does that? Through the medical system. The United States is found guilty of genocide against indigenous and black folk. And they said the means through which they do that is medical access and keeping those two groups of people away from medical care. And this is why I always tell people that racism is inherently disabling. The two groups with the highest rate of disability in this country: Black folk and indigenous folk. Why? Because once you introduce disability in somebody's life, especially in the United States, the eugenics takes over for society and it makes it a lot easier for society to isolate and dispose of that person with nobody caring. And that's why racism, ableism, always go hand in hand.\n",
      "that the american medical system is designed to provide the least amount of healthcare possible oh it's even way worse than that you know a couple weeks ago the united states was found guilty of crimes against humanity do you wanna know how they determine one of the ways in which the united states does that through the medical system the united states is found guilty of genocide against indigenous and black folk and they said the means through which they do that is medical access and keeping those two groups of people away from medical care and this is why i always tell people that racism is inherently disabling the two groups with the highest rate of disability in this country black folk and indigenous folk why because once you introduce disability in somebody's life especially in the united states the eugenics takes over for society and it makes it a lot easier for society to isolate and dispose of that person with nobody caring and that's why racism ableism always go hand in hand\n"
     ]
    },
    {
     "data": {
      "text/html": [
       "\n",
       "<audio controls=\"controls\" autobuffer=\"autobuffer\" style=\"width:100%;\">\n",
       "  <source src=\"../../../suno_stream_links/e65983e6-9e3b-4ba2-a2b5-2228790f0000.wav\"/>\n",
       "  Your browser does not support the audio element.\n",
       "</audio>\n"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "----------\n",
      "02e34388-46c9-4f72-95e2-d28197ee1514\n",
      "Oh, sushi! Sushi! [laughter] [inaudible]\n",
      "oh sushi sushi [laughter] [inaudible]\n"
     ]
    },
    {
     "data": {
      "text/html": [
       "\n",
       "<audio controls=\"controls\" autobuffer=\"autobuffer\" style=\"width:100%;\">\n",
       "  <source src=\"../../../suno_stream_links/8c1b2887-9896-4355-b571-b734bade2fc2.wav\"/>\n",
       "  Your browser does not support the audio element.\n",
       "</audio>\n"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "----------\n"
     ]
    }
   ],
   "source": [
    "import random\n",
    "# random ones\n",
    "# l = [e for e in segments_manifest if len(e[\"transcript\"][\"tokens\"]) == 0]\n",
    "l = segments_manifest[:]\n",
    "random.shuffle(l)\n",
    "for e in l[:5]:\n",
    "    print(e[\"id\"])\n",
    "    print(Tokens.from_dict(e[\"transcript\"][\"tokens\"]).text)\n",
    "    print(Tokens.from_dict(e[\"transcript_normalized\"][\"tokens\"]).text)\n",
    "    Audio.play_audio(e[\"uri\"])\n",
    "    print(\"-\"*10)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 41,
   "id": "dab452cf",
   "metadata": {},
   "outputs": [],
   "source": [
    "import random\n",
    "# random ones\n",
    "# l = [e for e in segments_manifest if len(e[\"transcript\"][\"tokens\"]) == 0]\n",
    "l = segments_manifest[:]\n",
    "random.shuffle(l)\n",
    "n = 0\n",
    "for e in l:\n",
    "    text = Tokens.from_dict(e[\"transcript\"][\"tokens\"]).text\n",
    "    if not any((\n",
    "        re.search(r\"[0-9][^\\s0-9\\,\\.][^0-9]\", text),\n",
    "        re.search(r\"[^0-9][^\\s0-9\\,\\.][0-9]\", text),\n",
    "    )):\n",
    "        continue\n",
    "    print(e[\"id\"])\n",
    "    print(text)\n",
    "    print(Tokens.from_dict(e[\"transcript_normalized\"][\"tokens\"]).text)\n",
    "    Audio.play_audio(e[\"uri\"])\n",
    "    print(\"-\"*10)\n",
    "    n += 1\n",
    "    if n >= 5:\n",
    "        break"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 70,
   "id": "3df5f48f",
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "100%|██████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 15893/15893 [00:11<00:00, 1416.51it/s]\n"
     ]
    }
   ],
   "source": [
    "from suno_utils.utils.metrics import get_wer, get_cer\n",
    "data = []\n",
    "for m in tqdm.tqdm(segments_manifest):\n",
    "    norm_text = Tokens.from_dict(m[\"transcript_normalized\"][\"tokens\"]).plaintext\n",
    "    asr_text = m[\"transcript_asr\"][\"transcript\"]\n",
    "    text = Tokens.from_dict(m[\"transcript\"][\"tokens\"]).text\n",
    "    data.append((\n",
    "        m[\"id\"],\n",
    "        m[\"uri\"],\n",
    "        round(m[\"duration_s\"], 1),\n",
    "        text,\n",
    "        norm_text,\n",
    "        asr_text,\n",
    "        get_wer(norm_text, asr_text),\n",
    "        get_cer(norm_text, asr_text),\n",
    "    ))\n",
    "import pandas as pd\n",
    "df = pd.DataFrame(data, columns=[\"id\", \"uri\", \"duration_s\", \"text\", \"norm_text\", \"asr_text\", \"wer\", \"cer\"])\n",
    "df[\"text_rate\"] = df[\"norm_text\"].str.len() / df[\"duration_s\"]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "729a641c",
   "metadata": {},
   "outputs": [],
   "source": [
    "# output rev ID and segment number so we can check!!"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 74,
   "id": "353724cb",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "44bb63b9-a64f-4d57-8f30-1726768f2b76\n",
      "TEXT:Rebecca, oh wow, my girlfriend like you own her. That's a fun way to introduce someone. That's not what he meant. But it's cool that you'd assume that if I did have a problem I wouldn't stand up for myself. Yeah, well Dan's a great clarifier so I'm glad we got that cleared up. Nothing to clear up. There was something to clear up and I did. Yeah, on a date or something you need to plan a little adventures now that you're married and like the passion is gone, that's cool. No we were just hungry and wanted to try this restaurant cause we like trying new things together. Oh so you need each other to try new things because you're afraid to do things alone. Oh wow, so you think my wife should stay at home? Oh you think she belongs at home? Cool. I didn't say that. You said that. You said it. You said that. You said it. You said that. You said it. You said that. That is not what I meant at all. Now what about you guys? Have you been together long? Probably not right, you don't seem like the type. Only been dating for about two months. Wow, two months. That's a really long time for you, right, because you're really scared of commitment or something? No, I'm just an independent guy who's willing to wait for the right situation, doesn't just jump at the first [inaudible] I get. So get like you Dan, right, cool? Or you just haven't gotten over some weird childhood shit and keep replaying this same failed romantic situation over and over in your mind. You know, either or. Neither nor. Either or and I'm right. Neither nor.\n",
      "NORM:rebecca oh wow my girlfriend like you own her that's a fun way to introduce someone that's not what he meant but it's cool that you'd assume that if i did have a problem i wouldn't stand up for myself yeah well dan's a great clarifier so i'm glad we got that cleared up nothing to clear up there was something to clear up and i did yeah on a date or something you need to plan a little adventures now that you're married and like the passion is gone that's cool no we were just hungry and wanted to try this restaurant cause we like trying new things together oh so you need each other to try new things because you're afraid to do things alone oh wow so you think my wife should stay at home oh you think she belongs at home cool i didn't say that you said that you said it you said that you said it you said that you said it you said that that is not what i meant at all now what about you guys have you been together long probably not right you don't seem like the type only been dating for about two months wow two months that's a really long time for you right because you're really scared of commitment or something no i'm just an independent guy who's willing to wait for the right situation doesn't just jump at the first i get so get like you dan right cool or you just haven't gotten over some weird childhood shit and keep replaying this same failed romantic situation over and over in your mind you know either or neither nor either or and i'm right neither nor\n",
      "ASR: reec o wow my girlfriend like you o her that's a fun way to introdece someone that's not what he meant but it's caol that you'd assume that if i did have a problem i wouldn't stand up for myself yeah well dan's a great clarifier so i'm glad we got that clear thats' a clearer wasning to clear up and i did going to date or something youeed to play a little adventures o if you're married and like the passions go that's caol now we're just hungry and want to try this restaants we like trying ne things together al so you need each other to try new things because you're afraid to do things along o w you thinkmy wife shoul say home o you think she belongs at home i didn't say that you said that you said it you said that you said it you said that you said it you said that you said it is not what i meant at all now what about you guys have you been together long probably not right you don't seem like the time date for about two months wow two months that's a really long time for you right because you're really scared of commitment or something i'm just ipind of guy who's wen you wait for the right situation doesn't just jump at the firs s ms i get like you di' right cool or you just haven't goten over somewhere childhoodhoud keep re playing the same failed romantic situation over and over in your mind you know either or neither nor either or and i'm righting or\n"
     ]
    },
    {
     "data": {
      "text/html": [
       "\n",
       "<audio controls=\"controls\" autobuffer=\"autobuffer\" style=\"width:100%;\">\n",
       "  <source src=\"../../../suno_stream_links/db84de19-55f0-4b06-8ad9-3f1cbd53ce45.wav\"/>\n",
       "  Your browser does not support the audio element.\n",
       "</audio>\n"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "----------\n",
      "611d2e22-1784-443d-928a-b979a5bba056\n",
      "TEXT:Nigga talking shit, put the metal to his mouth Now i call his ass brace face Hmm And your bitch up for grabs like a sweepstakes I'ma eat her ass like a cheesecake Hmm\n",
      "NORM:nigga talking shit put the metal to his mouth now i call his ass brace face hmm and your bitch up for grabs like a sweepstakes i'ma eat her ass like a cheesecake hmm\n",
      "ASR: s but the middle does not right face your bak a grad like a fweesteake on eat like a cheesegate\n"
     ]
    },
    {
     "data": {
      "text/html": [
       "\n",
       "<audio controls=\"controls\" autobuffer=\"autobuffer\" style=\"width:100%;\">\n",
       "  <source src=\"../../../suno_stream_links/fcb09d37-5fa5-48e1-b245-5f978db6fed5.wav\"/>\n",
       "  Your browser does not support the audio element.\n",
       "</audio>\n"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "----------\n",
      "16674e32-b292-4c14-91f8-ec305f1f336d\n",
      "TEXT:I found out that my fiance and I are related. It turns out the fiance is actually her biological father and they didn't find this out until after the engagement the first time they brought him around the family and the mom instantly recognized him and spilled the beans. But basically this all happened because the mom got pregnant when she was 16 with her high school sweetheart who was 14. So the grandparents were pissed and they sent her away to live with her aunt to have the child and they lost connection and never knew what happened to each other. Follow so you never have to watch an entire video or two ever again.\n",
      "NORM:i found out that my fiance and i are related it turns out the fiance is actually her biological father and they didn't find this out until after the engagement the first time they brought him around the family and the mom instantly recognized him and spilled the beans but basically this all happened because the mom got pregnant when she was sixteen with her high school sweetheart who was fourteen so the grandparents were pissed and they sent her away to live with her aunt to have the child and they lost connection and never knew what happened to each other follow so you never have to watch an entire video or two ever again\n",
      "ASR: i found out that my fiance and i are related it turns out the fiancee is actually her biological father and they didn't find this out until after the engagement the first time they brought him around the family and the mom instantly recognized him and spilled the beans but basically this all happened because the mom got pregnant when she was sixteen with her high school sweetheart who was fourteen so the grandparents were pissed and they sent her away to live with her aunt to have the child and they lost connection and never knew what happened to each other folsey and never have to watch an entire video or report to ever again\n"
     ]
    },
    {
     "data": {
      "text/html": [
       "\n",
       "<audio controls=\"controls\" autobuffer=\"autobuffer\" style=\"width:100%;\">\n",
       "  <source src=\"../../../suno_stream_links/570e6e1e-c363-4569-a2ed-4336e5ad1515.wav\"/>\n",
       "  Your browser does not support the audio element.\n",
       "</audio>\n"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "----------\n",
      "8e846814-4872-4bf6-8b08-a5bb746ee90c\n",
      "TEXT:Next up on True Crime Time We have someone who I do have at least one other video about Graham Young. And as you likely know by now, these take me a very long time. So if you can like, comment, share, copy link, let me know if this is on your For You Page, anything to help me get views I appreciate you to the fullest extent of the law and also as you know, I appreciate you to the fullest extent of the law merch coming soon. Okay, so Graham Frederick Young was born on September 7th, 1947 and he lived until August 1st, 1990. He is best known as the Teacup Poisoner and later the Saint Alban's Poisoner and was an English serial killer who used poison to kill his victims. I feel like it's very ironic that an English serial killer poisoned people's tea to kill them. Graham was obsessed with poisons from an early age and he began poisoning relatives and school friends by lacing their food and drink with thallium and antimony. He was was caught when a school teacher became concerned about his interest in poisons and contacted the police. In 1962 at the age of 14, he was charged with administering poison to his father, sister, and schoolfriend and was detained at the Broadmoor Hospital. He would later also claim responsibility for the death of his stepmother, though he was never charged with this crime. Graham was born in Neasden in Middlesex on September 7th, 1947 to Frederick and Molly Young. He had an older sister Winifred. Molly died of tuberculosis plerosis when Graham was 14 weeks old and he was sent by his father to live with an uncle and aunt while his sister went to live with their grandparents. Several years later, Frederick Young remarried to another woman named Molly and the family was reunited. From an early age, Graham was fascinated by poisons and their effects and read extensively about Hitler and Nazi Germany. William Palmer, the Victorian Poisoner, also became a hero of his. In 1959, Graham passed his 11 plus and went to grammar school and also started reading books on advanced toxicology. After he was sent to Broadmoor Hospital after the events of 1952, the presiding judge stipulated that he shouldn't be released without the home secretary's authorization for 15 years. In 1971 he was deemed rehabilitated and released from Broadmoor and found a job as a storekeeper at a factory in Bovingdon, Hertfordshire. His duties there included making tea for his colleagues. Soon he began poisoning his workmates, resulting in two fatalities and several others left critically ill. But the deaths were initially attributed to a mysterious bug. However, Young's odd behavior and his pension for showing off his the considerable knowledge of poisons, aroused suspicions and he was arrested. He died of a heart attack in prison in 1990 when he was only 42 years old.\n",
      "NORM:next up on true crime time we have someone who i do have at least one other video about graham young and as you likely know by now these take me a very long time so if you can like comment share copy link let me know if this is on your for you page anything to help me get views i appreciate you to the fullest extent of the law and also as you know i appreciate you to the fullest extent of the law merch coming soon okay so graham frederick young was born on september seventh one nine four seven and he lived until august first one nine nine oh he is best known as the teacup poisoner and later the saint alban's poisoner and was an english serial killer who used poison to kill his victims i feel like it's very ironic that an english serial killer poisoned people's tea to kill them graham was obsessed with poisons from an early age and he began poisoning relatives and school friends by lacing their food and drink with thallium and antimony he was was caught when a school teacher became concerned about his interest in poisons and contacted the police in nineteen sixty two at the age of fourteen he was charged with administering poison to his father sister and schoolfriend and was detained at the broadmoor hospital he would later also claim responsibility for the death of his stepmother though he was never charged with this crime graham was born in neasden in middlesex on september seven one nine four seven to frederick and molly young he had an older sister winifred molly died of tuberculosis plerosis when graham was fourteen weeks old and he was sent by his father to live with an uncle and aunt while his sister went to live with their grandparents several years later frederick young remarried to another woman named molly and the family was reunited from an early age graham was fascinated by poisons and their effects and read extensively about hitler and nazi germany william palmer the victorian poisoner also became a hero of his in nineteen fifty nine graham passed his eleven plus and went to grammar school and also started reading books on advanced toxicology after he was sent to broadmoor hospital after the events of nineteen fifty two the presiding judge stipulated that he shouldn't be released without the home secretary's authorization for fifteen years in nineteen seventy one he was deemed rehabilitated and released from broadmoor and found a job as a storekeeper at a factory in bovingdon hertfordshire his duties there included making tea for his colleagues soon he began poisoning his workmates resulting in two fatalities and several others left critically ill but the deaths were initially attributed to a mysterious bug however young's odd behavior and his pension for showing off his the considerable knowledge of poisons aroused suspicions and he was arrested he died of a heart attack in prison in nineteen ninety when he was only forty two years old\n",
      "ASR: up on true crime time we have someone who i do at least one other video about graham young and as you likely know by now the sing very long times if you can like comment share a copylink let me know this is on for you page anything to help me abuse i appreciate you to the fullest extent of the law and also as you know i appreciate you to the fullest extent of the law merge coming soon ok so graham frederick young was born on september seventh one hundred fort seven and he lived into august first one nine hundred he is best known as the tea cup poisoner and later the same albms poisoner and was an english serial killer heo used poison to kill his victims i feel like it's very ironic that an english serial killer poisoned people's tea to kill them graham was obsessed with poisons from an early age and he began poisoning relatives and school friends by lacing their food and drink with alm and antimony he was caught when a school teacher became concerned about his interest in poisons and contacted the police in on ne thousanred and sixty two at the age of fourteen he was charged with administering poison to his father's sister and school friend and detained at the broadmore hospital he would later also claim responsibility for the death of his stepmother though he was never charged with this crime and was born thesn in middlesex on september seven one hundred andty seve to frederck and molly young yet an older sister when a fred molly died of tuberculosis plesy when graam was fourteen weeks old and he was sent by his father to live with an uncle and aunt while his sister went to live with their grandparents several years later frederick young remarried to another woman named molly and the family was reunited from an early age graham was fascinated by poisons and their effects and read extensively about hitler and nazi germany william palmer the victorian poisoner also became a hero of his nineteen fifty nine graham passed his eleven plus and went to grammar school and also started reading books on advanced toxicology after he was sent to broadmore hospital after the events of nineteen sixty two presiding judge stipulated that he shouldn't be released without the home secretary's authorization for fifteen years in nineteen seventy one he was deemed rehabilitated and released from broadmore and found a job as a storekeeper at a factory in bowington hertfordshire his duties there included making tea for his colleagues soon he began poisoning his workmates resulting in two fatalities and several others left critically ill but the deaths were initially attributed to a mysterious bug barbara young's odd behavior and his pension for showing off his considerable knowledge of poisons aroused suspicions and he was arrested out of a heart attack in prison in nineteen net when was only forty two years old\n"
     ]
    },
    {
     "data": {
      "text/html": [
       "\n",
       "<audio controls=\"controls\" autobuffer=\"autobuffer\" style=\"width:100%;\">\n",
       "  <source src=\"../../../suno_stream_links/a9f6a437-6ff6-4882-8be6-1a2b474471d1.wav\"/>\n",
       "  Your browser does not support the audio element.\n",
       "</audio>\n"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "----------\n",
      "fcf22c04-a747-4eed-beab-308309068392\n",
      "TEXT:That's what I said. I said that she was doing way too much, yesterday she came in here, she was trying to throw her weight around. She was puffing and puffing, I was about to blow that bitch house down. You better tell her to school before she crawl and crawl before she walked and tell her don't think about running cause she ain't gonna get far. That's what I said, that's what I said. Go ahead, put that in the record, please.\n",
      "NORM:that's what i said i said that she was doing way too much yesterday she came in here she was trying to throw her weight around she was puffing and puffing i was about to blow that bitch house down you better tell her to school before she crawl and crawl before she walked and tell her don't think about running cause she ain't gonna get far that's what i said that's what i said go ahead put that in the record please\n",
      "ASR: that's that i said that she was doing way too much yesterday she came here she was trying to throw a way around she was heuping to pupping not but the blow e the test down you better t the scool before she crawling froablyfore she w and so don't think about becaus she go get far that's what i sad that's what i say goheare but that in the record but\n"
     ]
    },
    {
     "data": {
      "text/html": [
       "\n",
       "<audio controls=\"controls\" autobuffer=\"autobuffer\" style=\"width:100%;\">\n",
       "  <source src=\"../../../suno_stream_links/83fff6ea-ee86-4d6a-9e8f-8f69f48b7db0.wav\"/>\n",
       "  Your browser does not support the audio element.\n",
       "</audio>\n"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "----------\n"
     ]
    }
   ],
   "source": [
    "for _, row in df.sort_values(by=\"text_rate\", ascending=False).head().iterrows():\n",
    "    print(row[\"id\"])\n",
    "    print(\"TEXT:\" + row[\"text\"])\n",
    "    print(\"NORM:\" + row[\"norm_text\"])\n",
    "    print(\"ASR: \" + row[\"asr_text\"])\n",
    "    Audio.play_audio(row[\"uri\"])\n",
    "    print(\"-\"*10)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "503a2e5d",
   "metadata": {},
   "outputs": [],
   "source": [
    "for _, row in df.sort_values(by=\"cer\", ascending=False).head().iterrows():\n",
    "    print(row[\"id\"])\n",
    "    print(\"TEXT:\" + row[\"text\"])\n",
    "    print(\"NORM:\" + row[\"norm_text\"])\n",
    "    print(\"ASR: \" + row[\"asr_text\"])\n",
    "    Audio.play_audio(row[\"uri\"])\n",
    "    print(\"-\"*10)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 82,
   "id": "6b7e3c3c",
   "metadata": {
    "scrolled": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "9b74a16a-673a-43fa-b552-418cd88d141e\n",
      "rev: 97526b04-cdf5-4621-aa72-19d9619d0210 -- 1048\n",
      "TEXT:[music]\n",
      "NORM:\n",
      "ASR: have pop thang wrapp stup gang don't wrap up bang down time gang butcause you cran well wal brin jud we bran\n"
     ]
    },
    {
     "data": {
      "text/html": [
       "\n",
       "<audio controls=\"controls\" autobuffer=\"autobuffer\" style=\"width:100%;\">\n",
       "  <source src=\"../../../suno_stream_links/53c8b43b-b4db-4541-90b7-398100b6f9dd.wav\"/>\n",
       "  Your browser does not support the audio element.\n",
       "</audio>\n"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "----------\n",
      "495cc782-5a20-4f7e-a334-08b6daa27980\n",
      "rev: 1e3859f4-6feb-45b5-801a-eb62c4f90a08 -- 1127\n",
      "TEXT:[music]\n",
      "NORM:\n",
      "ASR: your father he on me twenty dollars we don't want to he we're like twenty nerey shoppers\n"
     ]
    },
    {
     "data": {
      "text/html": [
       "\n",
       "<audio controls=\"controls\" autobuffer=\"autobuffer\" style=\"width:100%;\">\n",
       "  <source src=\"../../../suno_stream_links/fdf7bb60-603d-46a1-bfe9-132cb0c54ab3.wav\"/>\n",
       "  Your browser does not support the audio element.\n",
       "</audio>\n"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "----------\n",
      "2b209732-1801-4d7a-a8f0-3f5c9699f9cb\n",
      "rev: 8f69815b-3cec-48eb-acd0-e1a781d8f882 -- 1067\n",
      "TEXT:Part two. [music]\n",
      "NORM:part two\n",
      "ASR: songs every hispanicsh a know medding edition part two\n"
     ]
    },
    {
     "data": {
      "text/html": [
       "\n",
       "<audio controls=\"controls\" autobuffer=\"autobuffer\" style=\"width:100%;\">\n",
       "  <source src=\"../../../suno_stream_links/e7b56f0d-e810-40a3-8ff0-c7e195f25e8f.wav\"/>\n",
       "  Your browser does not support the audio element.\n",
       "</audio>\n"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "----------\n",
      "58aac96e-c4f6-4d43-b1ef-f3973695bcb2\n",
      "rev: b157d55f-cfef-4650-957d-d44b9b0c1805 -- 1043\n",
      "TEXT:[music]\n",
      "NORM:\n",
      "ASR: i don't wanto money itand\n"
     ]
    },
    {
     "data": {
      "text/html": [
       "\n",
       "<audio controls=\"controls\" autobuffer=\"autobuffer\" style=\"width:100%;\">\n",
       "  <source src=\"../../../suno_stream_links/16112af5-391f-4094-a01d-ddc2972cc30a.wav\"/>\n",
       "  Your browser does not support the audio element.\n",
       "</audio>\n"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "----------\n",
      "5b0d3f24-c565-44e5-9f02-644bfdfa5f39\n",
      "rev: 92297065-dcc5-41bb-accb-d15d795c3a01 -- 1083\n",
      "TEXT:Dude, what is he saying? [inaudible]\n",
      "NORM:dude what is he saying\n",
      "ASR: you good d do what is he saying i i don't know now right i do\n"
     ]
    },
    {
     "data": {
      "text/html": [
       "\n",
       "<audio controls=\"controls\" autobuffer=\"autobuffer\" style=\"width:100%;\">\n",
       "  <source src=\"../../../suno_stream_links/e95d5b55-0dc6-43f1-9c63-8c84e7f6e777.wav\"/>\n",
       "  Your browser does not support the audio element.\n",
       "</audio>\n"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "----------\n",
      "e6248fb6-c09f-4bc3-80c3-74d646718ac7\n",
      "rev: b157d55f-cfef-4650-957d-d44b9b0c1805 -- 1060\n",
      "TEXT:[music] Yeah.\n",
      "NORM:yeah\n",
      "ASR: yaes su\n"
     ]
    },
    {
     "data": {
      "text/html": [
       "\n",
       "<audio controls=\"controls\" autobuffer=\"autobuffer\" style=\"width:100%;\">\n",
       "  <source src=\"../../../suno_stream_links/686c1fa0-d402-4570-8c70-18c11e40f659.wav\"/>\n",
       "  Your browser does not support the audio element.\n",
       "</audio>\n"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "----------\n",
      "7382d0af-5d07-4b2e-b82c-c2a18df9db6c\n",
      "rev: b157d55f-cfef-4650-957d-d44b9b0c1805 -- 1083\n",
      "TEXT:[music]\n",
      "NORM:\n",
      "ASR: do don't like us in say rose right somembins when i mean a rain may bd business\n"
     ]
    },
    {
     "data": {
      "text/html": [
       "\n",
       "<audio controls=\"controls\" autobuffer=\"autobuffer\" style=\"width:100%;\">\n",
       "  <source src=\"../../../suno_stream_links/80f81404-8c64-459f-875e-3f90609a68f7.wav\"/>\n",
       "  Your browser does not support the audio element.\n",
       "</audio>\n"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "----------\n",
      "f9422a97-08d8-49c9-8e06-adfd5fe38ec5\n",
      "rev: 915bb747-0b0e-4cb5-bad3-5e4d3ca79f73 -- 1046\n",
      "TEXT:I tell her she should act right She just wanna talk about the time we had last night Grab the red bill, fuck your feelings The way she suck\n",
      "NORM:i tell her she should act right she just wanna talk about the time we had last night grab the red bill fuck your feelings the way she suck\n",
      "ASR: \n"
     ]
    },
    {
     "data": {
      "text/html": [
       "\n",
       "<audio controls=\"controls\" autobuffer=\"autobuffer\" style=\"width:100%;\">\n",
       "  <source src=\"../../../suno_stream_links/3d491b4b-c139-4e14-8cb4-a59fbf5dfcd9.wav\"/>\n",
       "  Your browser does not support the audio element.\n",
       "</audio>\n"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "----------\n",
      "bdac9bee-3a09-429a-9ad0-53dc8f9dc91b\n",
      "rev: 1e55b4ab-5478-447c-9968-6d63b8b3627e -- 1002\n",
      "TEXT:\n",
      "NORM:\n",
      "ASR: had the class wifet of wow and\n"
     ]
    },
    {
     "data": {
      "text/html": [
       "\n",
       "<audio controls=\"controls\" autobuffer=\"autobuffer\" style=\"width:100%;\">\n",
       "  <source src=\"../../../suno_stream_links/743e17a7-291a-45e7-afc2-99903b33bc47.wav\"/>\n",
       "  Your browser does not support the audio element.\n",
       "</audio>\n"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "----------\n",
      "2587fdfe-4047-4edf-9f1b-0c03b862767a\n",
      "rev: b4190139-747a-4bef-915b-76a48de474ae -- 1037\n",
      "TEXT:Oh, great heavens.\n",
      "NORM:oh great heavens\n",
      "ASR: a magnificent p oh great heavens\n"
     ]
    },
    {
     "data": {
      "text/html": [
       "\n",
       "<audio controls=\"controls\" autobuffer=\"autobuffer\" style=\"width:100%;\">\n",
       "  <source src=\"../../../suno_stream_links/14d131b0-dc91-4b4a-8457-0149c0247376.wav\"/>\n",
       "  Your browser does not support the audio element.\n",
       "</audio>\n"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "----------\n"
     ]
    }
   ],
   "source": [
    "for _, row in df.sort_values(by=\"cer\", ascending=False).head(10).iterrows():\n",
    "    print(row[\"id\"])\n",
    "    print(\"rev:\", segment_to_rev_map[row[\"id\"]][\"rev_id\"], \"--\", segment_to_rev_map[row[\"id\"]][\"segment_nr\"])\n",
    "    print(\"TEXT:\" + row[\"text\"])\n",
    "    print(\"NORM:\" + row[\"norm_text\"])\n",
    "    print(\"ASR: \" + row[\"asr_text\"])\n",
    "    Audio.play_audio(row[\"uri\"])\n",
    "    print(\"-\"*10)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "34165d5a",
   "metadata": {},
   "outputs": [],
   "source": [
    "# uid = \"6643b5a8-06de-45cb-a99f-351c54d49133\"\n",
    "# for e in segments_manifest:\n",
    "#     if e[\"id\"] == uid:\n",
    "#         print(\"full:\", Tokens.from_dict(e[\"transcript\"][\"tokens\"]).text)\n",
    "#         print(\"norm:\", Tokens.from_dict(e[\"transcript_normalized\"][\"tokens\"]).text)\n",
    "#         print(\"asr :\", e[\"transcript_asr\"][\"transcript\"])\n",
    "#         Audio.from_file(e[\"uri\"]).play()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "afd18433",
   "metadata": {},
   "outputs": [],
   "source": [
    "# l = []\n",
    "# for e in segments_manifest:\n",
    "#     l.extend(re.findall(r\"[a-zA-Z]+\\-[a-zA-Z]+\", Tokens.from_dict(e[\"transcript\"][\"tokens\"]).text))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "51e32035",
   "metadata": {},
   "outputs": [],
   "source": [
    "# # segment_uid = \"30815903-8a47-4d14-8557-41c352526d5d\"\n",
    "# # segment_uid = \"974c5846-5ae1-4521-9ca2-83175d563c55\"\n",
    "# # segment_uid = \"45a812db-16ef-494f-acde-6d151d012a70\"\n",
    "# segment_uid = \"383220cb-e8f1-4b6d-b39b-2d126eb50163\" \n",
    "\n",
    "# for n, m in enumerate(audio_rev_metas):\n",
    "#     rev_id = m[\"uid\"]\n",
    "#     for nn, mm in enumerate(m[\"segments_meta\"]):\n",
    "#         if mm[\"type\"] != \"speech\":\n",
    "#             continue\n",
    "#         if mm[\"orginial_audio_uid\"] == segment_uid:\n",
    "#             print(n, nn)\n",
    "#             print(audio_rev_metas[n][\"uid\"])\n",
    "#             print(audio_rev_metas[n][\"segments_meta\"][nn])\n",
    "# #             print(Tokens.from_dict(e[\"transcript\"][\"tokens\"]).text)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "539144e1",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "dc0d9e56",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "938c2793",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "id": "6b0192cb",
   "metadata": {},
   "source": [
    "## format output for speechly styleguide"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "id": "798221f7",
   "metadata": {},
   "outputs": [],
   "source": [
    "# TODO: do we need to keep dashes during norm? what about M-mhm uh-huh, ..."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "id": "290b5f06",
   "metadata": {},
   "outputs": [],
   "source": [
    "from suno_utils.web.harvest import get_filename\n",
    "\n",
    "with open(os.path.join(BASE_DIR, \"raw_data_manifest.json\")) as f:\n",
    "    filepaths_info = json.load(f)\n",
    "id_to_original_id_map = {e[0]: get_filename(e[2], keep_extension=True) for e in filepaths_info}\n",
    "inv_id_to_original_id_map = {v: k for k, v in id_to_original_id_map.items()}\n",
    "\n",
    "with open(os.path.join(ARTIFACTS_DIR, \"02_segment_meta_post_norm_and_asr.json\")) as f:\n",
    "    segments_manifest = json.load(f)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "id": "ecd8a4d5",
   "metadata": {},
   "outputs": [],
   "source": [
    "def _convert_full_transcript(tokens):\n",
    "    transcript_l = []\n",
    "    for turn in tokens.speaker_turns:\n",
    "        turn_tokens = Tokens.from_dict(turn[\"tokens\"])\n",
    "        active_lyrics = False\n",
    "        text_l = []\n",
    "        for t in turn_tokens:\n",
    "            is_lyrics = False\n",
    "            if t.metadata is not None:\n",
    "                is_lyrics = t.metadata[\"is_lyrics\"]\n",
    "            if is_lyrics and not active_lyrics:\n",
    "                text_l.append(\"<lyrics>\")\n",
    "            if not is_lyrics and active_lyrics:\n",
    "                text_l.append(\"</lyrics>\")\n",
    "            text_l.append(t.value)\n",
    "            active_lyrics = is_lyrics\n",
    "        if active_lyrics:\n",
    "            text_l.append(\"</lyrics>\")\n",
    "        text = \" \".join(text_l)\n",
    "        text = re.sub(r\"\\<lyrics\\>\\s+\", \"<lyrics>\", text)\n",
    "        text = re.sub(r\"\\s+\\<\\/lyrics\\>\", \"</lyrics>\", text)\n",
    "        transcript_l.append(text)\n",
    "    transcript = \" [speaker_change] \".join(transcript_l)\n",
    "    transcript = re.sub(r\"\\s+\\[word\\_fragment\\_boundary\\]\", \"*\", transcript)\n",
    "    # fix some basic parse mistackes\n",
    "    transcript = re.sub(r\"^\\s*\\[music\\] \\[speaker\\_change\\]\\s*\", \"[music] \", transcript)\n",
    "    transcript = re.sub(r\"\\b([Ff])cuk\\b\", \"\\\\1uck\", transcript)\n",
    "    transcript = normalize_whitespace(transcript)\n",
    "    return transcript\n",
    "\n",
    "def _convert_norm_transcript(tokens):\n",
    "    transcript = tokens.text\n",
    "    transcript = transcript.replace(\" [word_fragment_boundary]\", \"*\")\n",
    "    transcript = transcript.replace(\"[foreign_language]\", \"<f>\")\n",
    "    transcript = transcript.replace(\"[inaudible]\", \"<u>\")\n",
    "    transcript = transcript.replace(\"[crosstalk]\", \"<u>\")\n",
    "    transcript = transcript.replace(\"[redacted]\", \"<u>\")\n",
    "    transcript = transcript.replace(\"[beep]\", \"<beep>\")\n",
    "    transcript = transcript.replace(\"--\", \" \")\n",
    "    transcript = re.sub(r\"\\[.*?\\]\", \" \", transcript)\n",
    "    teanscript = re.sub(r\"\\bfcuk\\b\", \"fuck\", transcript)\n",
    "    transcript = normalize_whitespace(transcript)\n",
    "    return transcript"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "id": "b2465b35",
   "metadata": {},
   "outputs": [],
   "source": [
    "# jsonl \n",
    "\n",
    "# {\n",
    "#   \"audio\": \"0a4ac9ac-42a4-4e77-91ad-862b0509d913.wav.\", // the audio file name\n",
    "#   \"transcript\": \".....\",  // The transcript of the audio\n",
    "#   \"tags\": [ ]  // The \"OFF\" and/or \"AC\" tags if relevant to the utterance\n",
    "# }\n",
    "# Audio corrupted utterance (AC): for only severely corrupted audio files\n",
    "# Offensive utterance (OFF): profanities, bullying language, hate speech included in the audio file\n",
    "output_metadata = []\n",
    "for n, m in enumerate(segments_manifest):\n",
    "    norm_tokens = Tokens.from_dict(m[\"transcript_normalized\"][\"tokens\"])\n",
    "    tokens = Tokens.from_dict(m[\"transcript\"][\"tokens\"])\n",
    "    norm_transcript = _convert_norm_transcript(norm_tokens)\n",
    "    transcript = _convert_full_transcript(tokens)\n",
    "#     tags = []\n",
    "#     if _contains_profanity(norm_transcript):\n",
    "#         tags.append(\"OFF\")\n",
    "    original_filename = id_to_original_id_map[m[\"id\"]]\n",
    "    \n",
    "#     if \"foreign\" in transcript:\n",
    "#         print(norm_transcript)\n",
    "#         print(\"-\")\n",
    "#         print(transcript)\n",
    "#         print(\"-\"*10)\n",
    "#     if len(norm_transcript) == 0:\n",
    "#         print(norm_transcript)\n",
    "#         print(\"-\")\n",
    "#         print(transcript)\n",
    "#         print(\"-\"*10)\n",
    "        \n",
    "    # some manual overrides\n",
    "    # TODO: use CER here in future to punt and maybe reannotate\n",
    "#     if original_filename == \"c7bfc752-be04-4c91-b018-bf809ad19323.mp3\":\n",
    "#         transcript = transcript.replace(\"Banja not to this barely\", \"[foreign_language] Chef Bally\")\n",
    "#         norm_transcript = norm_transcript.replace(\"we ' re\", \"we're\")\n",
    "#     if original_filename == \"cc6284ac-dc8b-420c-9bd0-8470d2e2d88d.mp3\":\n",
    "#         transcript = \"Damn.\"\n",
    "#         norm_transcript = \"damn\"\n",
    "#         tags = [\"OFF\"]\n",
    "#     if original_filename == \"b451b2ff-0dd2-4a8b-a317-34ea67f172bd.mp3\":\n",
    "#         transcript = transcript.replace(\"I can't\", \"I can't, I can't\")\n",
    "#         norm_transcript = norm_transcript.replace(\"i can't\", \"i can't i can't\")\n",
    "#     if original_filename == \"4600e16e-fd7d-4c69-9e1d-49b1a3c2b088.mp3\":\n",
    "#         transcript = transcript.replace(\"y'all\", \"yo\")\n",
    "#         norm_transcript = norm_transcript.replace(\"y'all\", \"yo\")  \n",
    "#     if original_filename == \"3cd8a90f-8475-4d7c-84f3-07e9b7aa0227.mp3\":\n",
    "#         transcript = \"What?\"\n",
    "#         norm_transcript = \"what\"\n",
    "#     if original_filename == \"558a3f70-8f55-4b7e-9b14-6d6e2a436218.mp3\":\n",
    "#         transcript = \"<u>\"\n",
    "#         norm_transcript = \"[inaudible]\"\n",
    "#     if original_filename == \"35063d27-f049-41d1-a157-417ea07f068c.mp3\":\n",
    "#         transcript = transcript.replace(\"one zero\", \"ten\")\n",
    "\n",
    "    output_metadata.append({\n",
    "        \"audio\": original_filename,\n",
    "        \"transcript\": normalize_whitespace(norm_transcript),\n",
    "        \"transcript_full\": normalize_whitespace(transcript),\n",
    "#         \"tags\": tags,\n",
    "    })"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 31,
   "id": "1934deee",
   "metadata": {},
   "outputs": [],
   "source": [
    "# reverse IDs\n",
    "original_id_map = {}\n",
    "with open(os.path.join(BASE_DIR, \"raw_data_manifest.json\")) as f:\n",
    "    original_filepaths_info = json.load(f)\n",
    "for e in original_filepaths_info:\n",
    "    original_id_map[e[0]] = get_filename(e[1])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 32,
   "id": "ec5ef4cc",
   "metadata": {},
   "outputs": [],
   "source": [
    "out_metas = []\n",
    "for m in output_metadata:\n",
    "    nm = copy.deepcopy(m)\n",
    "    e = original_id_map[get_filename(nm[\"audio\"])]\n",
    "    nm[\"id\"] = e\n",
    "    del nm[\"audio\"]\n",
    "    out_metas.append(nm)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 33,
   "id": "a4e5e127",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'transcript': \"did you know to prepare for his role in drive ryan gosling had to drive a real car this is why he has so little dialogue in the movie as it's very difficult to drive and talk at the same time\",\n",
       " 'transcript_full': 'Did you know, to prepare for his role in \"Drive,\" Ryan Gosling had to drive a real car? This is why he has so little dialogue in the movie, as it\\'s very difficult to drive and talk at the same time.',\n",
       " 'id': '7093124584345586950'}"
      ]
     },
     "execution_count": 33,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "out_metas[0]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 34,
   "id": "00cecd18",
   "metadata": {},
   "outputs": [],
   "source": [
    "write_jsonl(out_metas, os.path.join(ARTIFACTS_DIR, \"delivery_meta.jsonl\"))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "e56a5855",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "9a2bbdb1",
   "metadata": {},
   "outputs": [],
   "source": [
    "# TODO (fix):\n",
    "\n",
    "# 7102445125288185093\n",
    "# c three po\n",
    "\n",
    "# norm mistake\n",
    "# 88b87281-ebea-4ec9-84b4-1ee1b0323305\n",
    "# Folding wing tips on the Boeing 777X. What a time to be alive\n",
    "# folding wing tips on the boeing seven hundred seventy seven x what a time to be alive\n",
    "\n",
    "# music tag missing\n",
    "# bdac9bee-3a09-429a-9ad0-53dc8f9dc91b\n",
    "# rev: 1e55b4ab-5478-447c-9968-6d63b8b3627e -- 1002\n",
    "# TEXT:\n",
    "# NORM:\n",
    "# ASR: had the class wifet of wow and"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "c75d5fab",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "d5b82470",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "75be785b",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "id": "6b0b614f",
   "metadata": {},
   "source": [
    "## Final QA"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 44,
   "id": "a61aa689",
   "metadata": {},
   "outputs": [],
   "source": [
    "from suno_utils.utils.text import read_jsonl\n",
    "output_metadata = read_jsaonl(os.path.join(ARTIFACTS_DIR, \"delivery_meta.jsonl\"))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 36,
   "id": "8a5d9f26",
   "metadata": {},
   "outputs": [],
   "source": [
    "# for e in output_metadata:\n",
    "#     if e[\"audio\"] == \"1034ef38-79aa-48de-a908-0dd6a65c1a36.mp3\":\n",
    "#         print(e[\"audio\"], \"- profanity:\", \"OFF\" in e[\"tags\"])\n",
    "#         Audio.from_file(os.path.join(BASE_DIR, \"audio\", e[\"audio\"])).play()\n",
    "#         print(e[\"transcript\"])\n",
    "#         print(\"-\")\n",
    "#         print(e[\"transcript_full\"])\n",
    "#         break"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 37,
   "id": "201ac267",
   "metadata": {},
   "outputs": [],
   "source": [
    "# # figure out rev\n",
    "# with open(os.path.join(TO_REV_DIR, f\"audio_rev_metas.json\")) as f:\n",
    "#     audio_rev_metas = json.load(f)\n",
    "# uid = inv_id_to_original_id_map[\"harrisnt_-7072462733219728682.m4v\"]\n",
    "# for rev_m in audio_rev_metas:\n",
    "#     for seg_m in rev_m[\"segments_meta\"]:\n",
    "#         if seg_m.get(\"orginial_audio_uid\") == uid:\n",
    "#             print(seg_m)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 38,
   "id": "9ccfd86b",
   "metadata": {},
   "outputs": [],
   "source": [
    "# import random\n",
    "# # random ones\n",
    "# # l = [e for e in segments_manifest if len(e[\"transcript\"][\"tokens\"]) == 0]\n",
    "# l = [e for e in output_metadata if len(e[\"transcript\"]) == 0]\n",
    "# random.shuffle(l)\n",
    "# for e in l[:5]:\n",
    "#     print(e[\"audio\"], \"- profanity:\", \"OFF\" in e[\"tags\"])\n",
    "#     Audio.from_file(os.path.join(BASE_DIR, \"audio\", e[\"audio\"])).play()\n",
    "#     print(e[\"transcript\"])\n",
    "#     print(\"-\")\n",
    "#     print(e[\"transcript_full\"])\n",
    "#     print(\"-\"*10)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 39,
   "id": "3e5ea906",
   "metadata": {},
   "outputs": [],
   "source": [
    "# for e in output_metadata:\n",
    "#     if \"Tom Hiddleston\" in e[\"transcript_full\"]:\n",
    "#         print(e[\"audio\"])\n",
    "#         Audio.play_audio(os.path.join(BASE_DIR, \"audio\", e[\"audio\"]))\n",
    "#         print(e[\"transcript\"])\n",
    "#         print(\"-\")\n",
    "#         print(e[\"transcript_full\"])\n",
    "#         print(\"-\"*10)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 46,
   "id": "f3e5cbcf",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "7033892777033321734\n"
     ]
    },
    {
     "data": {
      "text/html": [
       "\n",
       "<audio controls=\"controls\" autobuffer=\"autobuffer\" style=\"width:100%;\">\n",
       "  <source src=\"../../../suno_stream_links/d6379af0-1873-4581-ba7e-01549e72cd69.wav\"/>\n",
       "  Your browser does not support the audio element.\n",
       "</audio>\n"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "something really good is gonna happen to you after you watch this video so lock it in follow me like this video come and good luck and share it\n",
      "-\n",
      "Something really good is gonna happen to you after you watch this video. So lock it in. Follow me, like this video. Come and good luck and share it\n",
      "----------\n",
      "7105774271162584325\n"
     ]
    },
    {
     "data": {
      "text/html": [
       "\n",
       "<audio controls=\"controls\" autobuffer=\"autobuffer\" style=\"width:100%;\">\n",
       "  <source src=\"../../../suno_stream_links/6c1f8181-5796-45c7-bebd-f96ee070eda9.wav\"/>\n",
       "  Your browser does not support the audio element.\n",
       "</audio>\n"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "hello world my name is margie i'm your spanish teacher welcome to your mini lesson of today today we're going to speak about the plural normally we just stick an s after the word car cars but sometimes it's an es and when so i google it and they said after a d j s m l r y and zed you stick es yeah right are you going to learn that you're never going to learn that so i made a little riddle all the d j's d j s of the netherlands n l e rise r y zed i know rises r y z e but that's my little riddle and now you know how to make the plural of any word hope you enjoyed my lesson\n",
      "-\n",
      "Hello world, my name is Margie, I'm your Spanish teacher. Welcome to your mini lesson of today. Today we're going to speak about the plural. Normally we just stick an \"s\" after the word, car, cars, But sometimes it's an \"es,\" and when? So, I Google it, and they said after a \"d, j, s, m, l, r, y, and zed,\" you stick \"es.\" Yeah right, are you going to learn that? You're never going to learn that. So, I made a little riddle. All the \"d, j's\" \"d, j, s,\" of the Netherlands, \"n, l, e,\" rise, \"r, y, zed.\" I know rises \"r, y, z, e,\" but that's my little riddle. And now you know how to make the plural of any word. Hope you enjoyed my lesson.\n",
      "----------\n",
      "7040965026420886831\n"
     ]
    },
    {
     "data": {
      "text/html": [
       "\n",
       "<audio controls=\"controls\" autobuffer=\"autobuffer\" style=\"width:100%;\">\n",
       "  <source src=\"../../../suno_stream_links/3fbcf4a0-7ac8-4cb0-9993-721a9d318733.wav\"/>\n",
       "  Your browser does not support the audio element.\n",
       "</audio>\n"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "oh baby whoever knew the rodeo i don't expect you to fall in love i need a one night stand as a permanent i wanna hold my hand i hope you understand but when the liquor's out we going ride till the sun come up\n",
      "-\n",
      "<lyrics>Oh, baby, whoever knew the rodeo I don't expect you to fall in love I need a one night stand as a permanent I wanna hold my hand, I hope you understand But when the liquor's out We going ride till the sun come up</lyrics>\n",
      "----------\n",
      "7100040877283773739\n"
     ]
    },
    {
     "data": {
      "text/html": [
       "\n",
       "<audio controls=\"controls\" autobuffer=\"autobuffer\" style=\"width:100%;\">\n",
       "  <source src=\"../../../suno_stream_links/a303fe55-389e-4ea6-a6eb-3b1f80033342.wav\"/>\n",
       "  Your browser does not support the audio element.\n",
       "</audio>\n"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "number fifteen could i get the number fifteen\n",
      "-\n",
      "Number 15, could I get the number 15?\n",
      "----------\n",
      "7088619555899182341\n"
     ]
    },
    {
     "data": {
      "text/html": [
       "\n",
       "<audio controls=\"controls\" autobuffer=\"autobuffer\" style=\"width:100%;\">\n",
       "  <source src=\"../../../suno_stream_links/50bc235a-67a8-47e2-803f-6b0cbc734b48.wav\"/>\n",
       "  Your browser does not support the audio element.\n",
       "</audio>\n"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "i've been going out with nick nelson since i was fourteen he likes rugby and formula one animals especially dogs the marvel universe the sound felt tips make on paper rain drawing on shoes\n",
      "-\n",
      "I've been going out with Nick Nelson since I was 14. He likes rugby and Formula 1. Animals, especially dogs. The Marvel universe. The sound felt tips make on paper. Rain. Drawing on shoes.\n",
      "----------\n"
     ]
    }
   ],
   "source": [
    "import random\n",
    "assert(len(RAW_AUDIO_DIRS) == 1)\n",
    "# random ones\n",
    "# l = [e for e in segments_manifest if len(e[\"transcript\"][\"tokens\"]) == 0]\n",
    "l = output_metadata[:]\n",
    "random.shuffle(l)\n",
    "for e in l[:5]:\n",
    "    print(e[\"id\"])\n",
    "    Audio.play_audio(os.path.join(RAW_AUDIO_DIRS[0], e[\"id\"] + \".wav\"))\n",
    "    print(e[\"transcript\"])\n",
    "    print(\"-\")\n",
    "    print(e[\"transcript_full\"])\n",
    "    print(\"-\"*10)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "38a9ce1f",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "76c34c77",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "a33601a9",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "id": "9f84953b",
   "metadata": {},
   "source": [
    "## compare with their output"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "08368ccc",
   "metadata": {},
   "outputs": [],
   "source": [
    "import pandas as pd"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "18112b59",
   "metadata": {},
   "outputs": [],
   "source": [
    "with open(os.path.join(RAW_DATA_DIR, \"transcripts.tsv\")) as f:\n",
    "    sl_transcripts = [e.split(\"\\t\") for e in f.read().strip().split(\"\\n\")]\n",
    "assert(all([len(e) == 2 for e in sl_transcripts]))\n",
    "sl_transcripts = [(uid, text.lower()) for uid, text in sl_transcripts]\n",
    "print(len(sl_transcripts), \"transcripts\")\n",
    "sl_transcripts[:2]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "e038f68f",
   "metadata": {},
   "outputs": [],
   "source": [
    "test_df = pd.DataFrame(output_metadata).drop([\"tags\"], 1)\n",
    "test_df[\"uid\"] = test_df[\"audio\"].str.split(\".\").str[0]\n",
    "test_df[\"sl_transcript\"] = test_df[\"uid\"].map({k: v for k, v in sl_transcripts})"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "b1f33880",
   "metadata": {},
   "outputs": [],
   "source": [
    "from suno_utils.utils.metrics import get_wer\n",
    "test_df[\"wer\"] = [get_wer(a, b) for a, b in zip(test_df[\"transcript\"], test_df[\"sl_transcript\"])]\n",
    "test_df = test_df.sort_values(\"wer\", ascending=False).reset_index(drop=True)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "a66aa1b0",
   "metadata": {
    "scrolled": true
   },
   "outputs": [],
   "source": [
    "test_df[test_df[\"transcript\"].str.len() >= 50].head()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "dc008f15",
   "metadata": {},
   "outputs": [],
   "source": [
    "test_df[test_df[\"transcript_full\"].str.contains(r\"\\[\")].head()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "faca5ede",
   "metadata": {},
   "outputs": [],
   "source": [
    "n = 23\n",
    "row = test_df.iloc[n]\n",
    "Audio.from_file(os.path.join(AUDIO_DIR, row[\"audio\"])).play()\n",
    "print(row[\"uid\"])\n",
    "print(row[\"transcript\"])\n",
    "print(row[\"sl_transcript\"])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "22240080",
   "metadata": {},
   "outputs": [],
   "source": [
    "# segment_uid = \"30815903-8a47-4d14-8557-41c352526d5d\"\n",
    "# segment_uid = \"974c5846-5ae1-4521-9ca2-83175d563c55\"\n",
    "# segment_uid = \"45a812db-16ef-494f-acde-6d151d012a70\"\n",
    "segment_uid = \"6643b5a8-06de-45cb-a99f-351c54d49133\" \n",
    "\n",
    "for n, m in enumerate(audio_rev_metas):\n",
    "    rev_id = m[\"uid\"]\n",
    "    for nn, mm in enumerate(m[\"segments_meta\"]):\n",
    "        if mm[\"type\"] != \"speech\":\n",
    "            continue\n",
    "        if mm[\"orginial_audio_uid\"] == segment_uid:\n",
    "            print(n, nn)\n",
    "            print(audio_rev_metas[n][\"uid\"])\n",
    "            print(audio_rev_metas[n][\"segments_meta\"][nn])\n",
    "#             print(Tokens.from_dict(e[\"transcript\"][\"tokens\"]).text)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "0a50292d",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "bbd0b3b4",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "id": "980bbc48",
   "metadata": {},
   "source": [
    "## Upload"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "41a7cdec",
   "metadata": {},
   "source": [
    "gsutil -m cp /mnt/data-ssd-1/data/private/customer/speechly/2022-12-02_tiktok-100h-en/pipeline/2022_12_02/artifacts/delivery_meta.jsonl gs://speechly-suno-wtyfeusyax/titktok/output/en_100h_annotations.jsonl"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "57948a36",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "d51f20f8",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "id": "36ae3093",
   "metadata": {},
   "source": [
    "## Playground"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "dd4d76ba",
   "metadata": {},
   "outputs": [],
   "source": [
    "import os\n",
    "import numpy as np\n",
    "from suno_utils.audio import Audio\n",
    "\n",
    "tt_d = \"/mnt/data-ssd-1/data/private/customer/speechly/gcp_bucket/titktok/multilingual-50h/en/\"\n",
    "tt_fns = [fn for fn in os.listdir(tt_d) if fn.endswith(\".wav\")]\n",
    "yt_d = \"/mnt/data-ssd-1/data/private/customer/speechly/gcp_bucket/youtube/multilingual-50h/en/\"\n",
    "yt_fns = [fn for fn in os.listdir(yt_d) if fn.endswith(\".wav\")]\n",
    "print(\n",
    "    round(np.sum([\n",
    "        Audio.get_details(os.path.join(tt_d, fn), attempt_using_header=True)[\"duration_s\"] for fn in tt_fns\n",
    "    ]) / 60 / 60, 1), \n",
    "    \"hours of tiktok\"\n",
    ")\n",
    "print(\n",
    "    round(np.sum([\n",
    "        Audio.get_details(os.path.join(yt_d, fn), attempt_using_header=True)[\"duration_s\"] for fn in yt_fns\n",
    "    ]) / 60 / 60, 1), \n",
    "    \"hours of youtube\"\n",
    ")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "365702d4",
   "metadata": {},
   "outputs": [],
   "source": [
    "# TODO: mistake\n",
    "#   It says to read verse 20, 1st John 3:20.\n",
    "#   Zero, teo, zero. Episode page"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 37,
   "id": "a0b2e806",
   "metadata": {},
   "outputs": [],
   "source": [
    "transcript_tokens = Tokens.from_text(\"It says to read verse 20, 1st John 3:20. Zero, teo, zero. Episode page\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 50,
   "id": "b9674b89",
   "metadata": {},
   "outputs": [],
   "source": [
    "from suno_utils.customers.sanas.pipeline import _digitify, _find_valid_indicators"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 48,
   "id": "dda2a125",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "20\n",
      "1\n",
      "\n",
      "320\n",
      "0\n",
      "\n",
      "0\n",
      "\n",
      "\n"
     ]
    }
   ],
   "source": [
    "indicator_speaker_id = None\n",
    "\n",
    "indicator_tokens = []\n",
    "prev_n = -2\n",
    "last_speaker_id = None\n",
    "for n, token in enumerate(transcript_tokens):\n",
    "    # if we know indicator speaker id then skip others\n",
    "    if indicator_speaker_id is not None and indicator_speaker_id != token.speaker_id:\n",
    "        last_speaker_id = token.speaker_id\n",
    "        continue\n",
    "    parsed_number = _digitify(token.value)\n",
    "    print(parsed_number)\n",
    "    if len(parsed_number) == 0:\n",
    "        last_speaker_id = token.speaker_id\n",
    "        continue\n",
    "    # if multiple tokens in a row pass then add to previous\n",
    "    if n - prev_n == 1 and last_speaker_id == token.speaker_id:\n",
    "        indicator_tokens[-1] = (\n",
    "            indicator_tokens[-1][0],\n",
    "            indicator_tokens[-1][1] + parsed_number,\n",
    "        )\n",
    "    elif token.speaker_id is None or last_speaker_id != token.speaker_id:\n",
    "        indicator_tokens.append((n, parsed_number))\n",
    "    else:\n",
    "        # TODO: if not new speaker then we don't add?\n",
    "        last_speaker_id = token.speaker_id\n",
    "        continue\n",
    "    prev_n = n\n",
    "    last_speaker_id = token.speaker_id"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "a53ef220",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "ac828916",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "88b9adb8",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "50209cc1",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "055c42ab",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "ff7c5d47",
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "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.8.10"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
