{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "ab6c7d18",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Populating the interactive namespace from numpy and matplotlib\n"
     ]
    }
   ],
   "source": [
    "%pylab inline"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "8a4404a3",
   "metadata": {},
   "outputs": [],
   "source": [
    "import os\n",
    "os.environ[\"CUDA_VISIBLE_DEVICES\"] = \"0\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "e4f3f4a2",
   "metadata": {},
   "outputs": [],
   "source": [
    "import json\n",
    "from suno_utils.audio import Audio\n",
    "from suno_utils.tasks.asr import transcribe, LmConfig\n",
    "\n",
    "DATA_DIR = \"/home/georg/notebooks/customers/nooks/sample_10/\"\n",
    "\n",
    "with open(DATA_DIR + \"annotations.json\") as f:\n",
    "    annotations = json.load(f)\n",
    "    \n",
    "filepaths = [DATA_DIR + fn for fn in os.listdir(DATA_DIR) if fn.endswith(\".wav\")]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "938b015c",
   "metadata": {},
   "outputs": [],
   "source": [
    "# voicemail:\n",
    "#     1 channel (prob use asr on both even if 2)\n",
    "#     terms: \"your call\", \"voicemail\", \"voice mail\", \"messages\", \"mailbox\", \"after the tone\", \"your message\", \"at the tone\"\n",
    "#         \"hi you have reached XXX XXX i can't make it to the phone right now, but please leave me a message\"\n",
    "#         (one person talking for at least 5 mins)\n",
    "        \n",
    "# human:\n",
    "#     only 1 channel of conversation\n",
    "    \n",
    "# dialtree: (leading up to a call?)\n",
    "#     1 channel (prob use asr on both even if 2)\n",
    "#     terms: \"thank you for calling\", \"please listen carefully as our menu options have changed\", \"please press [0-9]\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "id": "86ada964",
   "metadata": {},
   "outputs": [],
   "source": [
    "voicemail_search_terms = [\n",
    "    \"your call\", \n",
    "    \"voicemail\",\n",
    "    \"voice mail\",\n",
    "    \"message\",\n",
    "    \"messages\", \n",
    "    \"mailbox\", \n",
    "    \"after the tone\",  \n",
    "    \"at the tone\", \n",
    "    \"you have reached\", \n",
    "    \"you've reached\",\n",
    "    \"you reached\",\n",
    "]\n",
    "dialtree_search_terms = [\n",
    "    \"thank you for calling\", \n",
    "    \"please listen carefully\", \n",
    "    \"our menu options have changed\",\n",
    "    \"our menu options changed\",\n",
    "    \"please press\",\n",
    "]\n",
    "voicemail_re = re.compile(r\"|\".join([\n",
    "    r\"\\b\" + re.escape(s) + r\"\\b\" for s in sorted(voicemail_search_terms, key=lambda x: len(x), reverse=True)\n",
    "]))\n",
    "dialtree_re = re.compile(r\"|\".join([\n",
    "    r\"\\b\" + re.escape(s) + r\"\\b\" for s in sorted(dialtree_search_terms, key=lambda x: len(x), reverse=True)\n",
    "]))\n",
    "hotwords = []\n",
    "for s in voicemail_search_terms + dialtree_search_terms:\n",
    "    hotwords.extend(s.split())\n",
    "hotwords = set(hotwords)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "id": "58d8303b",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "6e5deffb05734daebb1ff3d165ef01ef",
       "version_major": 2,
       "version_minor": 0
      },
      "text/plain": [
       "Transcribing:   0%|          | 0/3 [00:00<?, ?it/s]"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Exception in thread QueueFeederThread:\n",
      "Traceback (most recent call last):\n",
      "  File \"/usr/lib/python3.8/multiprocessing/queues.py\", line 235, in _feed\n",
      "Exception in thread QueueFeederThread:\n",
      "Traceback (most recent call last):\n",
      "  File \"/usr/lib/python3.8/multiprocessing/queues.py\", line 235, in _feed\n",
      "Exception in thread QueueFeederThread:\n",
      "Traceback (most recent call last):\n",
      "  File \"/usr/lib/python3.8/multiprocessing/queues.py\", line 235, in _feed\n",
      "Exception in thread QueueFeederThread:\n",
      "    Traceback (most recent call last):\n",
      "  File \"/usr/lib/python3.8/multiprocessing/queues.py\", line 235, in _feed\n",
      "    close()\n",
      "  File \"/usr/lib/python3.8/multiprocessing/connection.py\", line 177, in close\n",
      "close()\n",
      "  File \"/usr/lib/python3.8/multiprocessing/connection.py\", line 177, in close\n",
      "    self._close()\n",
      "  File \"/usr/lib/python3.8/multiprocessing/connection.py\", line 361, in _close\n",
      "Exception in thread     close()    self._close()\n",
      "  File \"/usr/lib/python3.8/multiprocessing/connection.py\", line 361, in _close\n",
      "        _close(self._handle)\n",
      "OSError: [Errno 9] Bad file descriptor\n",
      "\n",
      "During handling of the above exception, another exception occurred:\n",
      "\n",
      "Traceback (most recent call last):\n",
      "  File \"/usr/lib/python3.8/threading.py\", line 932, in _bootstrap_inner\n",
      "\n",
      "_close(self._handle)\n",
      "OSError:   File \"/usr/lib/python3.8/multiprocessing/connection.py\", line 177, in close\n",
      "QueueFeederThread:\n",
      "Traceback (most recent call last):\n",
      "  File \"/usr/lib/python3.8/multiprocessing/queues.py\", line 235, in _feed\n",
      "    [Errno 9] Bad file descriptor\n",
      "\n",
      "During handling of the above exception, another exception occurred:\n",
      "\n",
      "Traceback (most recent call last):\n",
      "  File \"/usr/lib/python3.8/threading.py\", line 932, in _bootstrap_inner\n",
      "    self._close()\n",
      "  File \"/usr/lib/python3.8/multiprocessing/connection.py\", line 361, in _close\n",
      "close()\n",
      "  File \"/usr/lib/python3.8/multiprocessing/connection.py\", line 177, in close\n",
      "    self._close()\n",
      "  File \"/usr/lib/python3.8/multiprocessing/connection.py\", line 361, in _close\n",
      "            _close(self._handle)\n",
      "OSError: [Errno 9] Bad file descriptor\n",
      "\n",
      "During handling of the above exception, another exception occurred:\n",
      "\n",
      "Traceback (most recent call last):\n",
      "  File \"/usr/lib/python3.8/threading.py\", line 932, in _bootstrap_inner\n",
      "self.run()    self.run()\n",
      "  File \"/usr/lib/python3.8/threading.py\", line 870, in run\n",
      "self.run()\n",
      "  File \"/usr/lib/python3.8/threading.py\", line 870, in run\n",
      "\n",
      "  File \"/usr/lib/python3.8/threading.py\", line 870, in run\n",
      "        close()\n",
      "  File \"/usr/lib/python3.8/multiprocessing/connection.py\", line 177, in close\n",
      "    self._target(*self._args, **self._kwargs)\n",
      "  File \"/usr/lib/python3.8/multiprocessing/queues.py\", line 266, in _feed\n",
      "        self._target(*self._args, **self._kwargs)\n",
      "  File \"/usr/lib/python3.8/multiprocessing/queues.py\", line 266, in _feed\n",
      "    self._close()\n",
      "  File \"/usr/lib/python3.8/multiprocessing/connection.py\", line 361, in _close\n",
      "    queue_sem.release()\n",
      "ValueError: semaphore or lock released too many times\n",
      "self._target(*self._args, **self._kwargs)\n",
      "  File \"/usr/lib/python3.8/multiprocessing/queues.py\", line 266, in _feed\n",
      "_close(self._handle)    queue_sem.release()\n",
      "ValueError: semaphore or lock released too many times\n",
      "    \n",
      "_close(self._handle)\n",
      "OSError: [Errno 9] Bad file descriptor\n",
      "\n",
      "During handling of the above exception, another exception occurred:\n",
      "\n",
      "Traceback (most recent call last):\n",
      "  File \"/usr/lib/python3.8/threading.py\", line 932, in _bootstrap_inner\n",
      "OSError: [Errno 9] Bad file descriptor\n",
      "\n",
      "During handling of the above exception, another exception occurred:\n",
      "\n",
      "Traceback (most recent call last):\n",
      "  File \"/usr/lib/python3.8/threading.py\", line 932, in _bootstrap_inner\n",
      "    queue_sem.release()\n",
      "ValueError: semaphore or lock released too many times\n",
      "    self.run()\n",
      "  File \"/usr/lib/python3.8/threading.py\", line 870, in run\n",
      "    self.run()\n",
      "  File \"/usr/lib/python3.8/threading.py\", line 870, in run\n",
      "    self._target(*self._args, **self._kwargs)\n",
      "  File \"/usr/lib/python3.8/multiprocessing/queues.py\", line 266, in _feed\n",
      "    self._target(*self._args, **self._kwargs)\n",
      "  File \"/usr/lib/python3.8/multiprocessing/queues.py\", line 266, in _feed\n",
      "    queue_sem.release()\n",
      "ValueError: semaphore or lock released too many times\n",
      "    queue_sem.release()\n",
      "ValueError: semaphore or lock released too many times\n"
     ]
    }
   ],
   "source": [
    "lm_config = LmConfig(hotwords=hotwords, hotword_weight=10.0, n_cores=5, beam_width=5)\n",
    "transcripts = transcribe(filepaths, mode=\"tokens\", lm_config=lm_config)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "id": "732016f0",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "CF0c61dbc4e2a2c99ebc55c7967b4a801a -- (voicemail)\n",
      "is_human: 0.0%\n",
      "is_voicemail: 80.0%\n",
      "is_dialtree:: 20.0%\n",
      "----------\n",
      "CF0b32d3dda35d65b2a41ac47b3dbb27e3 -- (human)\n",
      "is_human: 82.8%\n",
      "is_voicemail: 0%\n",
      "is_dialtree:: 0%\n",
      "----------\n",
      "CF0deb69a0893b26074eb1405c71df2d82 -- (dialtree)\n",
      "is_human: 0.0%\n",
      "is_voicemail: 0.0%\n",
      "is_dialtree:: 100.0%\n",
      "----------\n",
      "CF00a2885085a90c3e2573bc58376e135e -- (voicemail)\n",
      "is_human: 0.0%\n",
      "is_voicemail: 100.0%\n",
      "is_dialtree:: 0.0%\n",
      "----------\n",
      "CF0c44394b88fac43be624c147c12bd9c2 -- (human)\n",
      "is_human: 100.0%\n",
      "is_voicemail: 0%\n",
      "is_dialtree:: 0%\n",
      "----------\n",
      "CF0cb4f2ea926d776f45fbfdbcdace89f3 -- (voicemail)\n",
      "is_human: 0.0%\n",
      "is_voicemail: 100.0%\n",
      "is_dialtree:: 0.0%\n",
      "----------\n",
      "CF0bfe0e0c35d18ccff841b2fb140b8340 -- (voicemail)\n",
      "is_human: 0.0%\n",
      "is_voicemail: 100.0%\n",
      "is_dialtree:: 0.0%\n",
      "----------\n",
      "CF00b11766876ca9d2ca3a81e2ed69f9c2 -- (voicemail)\n",
      "is_human: 0.0%\n",
      "is_voicemail: 100.0%\n",
      "is_dialtree:: 0.0%\n",
      "----------\n",
      "CF0a500a0f39b995caedac5e82211b9ae0 -- (voicemail)\n",
      "is_human: 0.0%\n",
      "is_voicemail: 0.0%\n",
      "is_dialtree:: 100.0%\n",
      "----------\n",
      "CF0ce6f9f27aab38e69894a20e31da59ca -- (dialtree)\n",
      "is_human: 0.0%\n",
      "is_voicemail: 100.0%\n",
      "is_dialtree:: 0.0%\n",
      "----------\n",
      "CF0c6ea89164b9884f57600ecc986986cc -- (voicemail)\n",
      "is_human: 0.0%\n",
      "is_voicemail: 100.0%\n",
      "is_dialtree:: 0.0%\n",
      "----------\n"
     ]
    }
   ],
   "source": [
    "for (uid, label), transcript in zip(annotations.items(), transcripts):\n",
    "    intro_duration_s = 6\n",
    "    speech_pct = round(np.sum([\n",
    "        ts[1] - ts[0] for t, ts, c in transcript if len(t.strip()) > 0 and ts[1] <= intro_duration_s\n",
    "    ]) / intro_duration_s * 100, 1)\n",
    "    keyword_duration_s = 20\n",
    "    text = \"\".join([t for t, ts, _ in transcript if ts[1] <= keyword_duration_s])\n",
    "    voicemail_terms = voicemail_re.findall(text)\n",
    "    dialtree_terms = dialtree_re.findall(text)\n",
    "    print(\"{} -- ({})\".format(uid, label))\n",
    "    human_pct = (1 - (np.clip(speech_pct, a_min=5, a_max=30) - 5) / 25)\n",
    "    print(\"is_human: {}%\".format(round(human_pct * 100, 1)))\n",
    "    if human_pct >= 0.7 and len(voicemail_terms) == 0 and len(dialtree_terms) == 0:\n",
    "        voicemail_pct = 0\n",
    "        dialtree_pct = 0\n",
    "    elif len(voicemail_terms) == 0 and len(dialtree_terms) == 0:\n",
    "        voicemail_pct = 0.5\n",
    "        dialtree_pct = 0.5\n",
    "    else:\n",
    "        voicemail_pct = len(voicemail_terms) / (len(voicemail_terms) + len(dialtree_terms))\n",
    "        dialtree_pct = len(dialtree_terms) / (len(voicemail_terms) + len(dialtree_terms))\n",
    "    print(\"is_voicemail: {}%\".format(round(voicemail_pct * 100, 1)))\n",
    "    print(\"is_dialtree:: {}%\".format(round(dialtree_pct * 100, 1)))\n",
    "    print(\"-\" * 10)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "90818b55",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "eda295ee",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "7cb49441",
   "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
}
