{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Split utterances using VAD" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Let say you have a long audio sample, and you want to cut to small samples based on utterances. Malaya-speech can help you!" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "
\n", "\n", "This tutorial is available as an IPython notebook at [malaya-speech/example/split-utterances](https://github.com/huseinzol05/malaya-speech/tree/master/example/utterances).\n", " \n", "
" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "
\n", "\n", "This module is language independent, so it save to use on different languages.\n", " \n", "
" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "
\n", "\n", "This is an application of malaya-speech Pipeline, read more about malaya-speech Pipeline at [malaya-speech/example/pipeline](https://github.com/huseinzol05/malaya-speech/tree/master/example/pipeline).\n", " \n", "
" ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [], "source": [ "import malaya_speech\n", "import numpy as np\n", "from malaya_speech import Pipeline" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### List available VAD model" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
Size (MB)Quantized Size (MB)Accuracy
vggvox-v170.817.700.9500
vggvox-v231.17.920.9594
speakernet20.35.180.9000
\n", "
" ], "text/plain": [ " Size (MB) Quantized Size (MB) Accuracy\n", "vggvox-v1 70.8 17.70 0.9500\n", "vggvox-v2 31.1 7.92 0.9594\n", "speakernet 20.3 5.18 0.9000" ] }, "execution_count": 2, "metadata": {}, "output_type": "execute_result" } ], "source": [ "malaya_speech.vad.available_model()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Load deep model\n", "\n", "I will load quantized model, we found out VAD quantized models have the same accuracy as normal models, read more about VAD at https://malaya-speech.readthedocs.io/en/latest/load-vad.html" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "WARNING:root:Load quantized model will cause accuracy drop.\n" ] } ], "source": [ "vad = malaya_speech.vad.deep_model(model = 'vggvox-v2', quantized = True)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Load long samples" ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "294.504" ] }, "execution_count": 4, "metadata": {}, "output_type": "execute_result" } ], "source": [ "y, sr = malaya_speech.load('speech/podcast/2x5%20Ep%2010.wav')\n", "len(y) / sr" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "294 seconds!" ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [ { "data": { "text/html": [ "\n", " \n", " " ], "text/plain": [ "" ] }, "execution_count": 5, "metadata": {}, "output_type": "execute_result" } ], "source": [ "import IPython.display as ipd\n", "\n", "ipd.Audio(y[:sr * 10], rate = sr)" ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [], "source": [ "from pydub import AudioSegment\n", "import numpy as np\n", "\n", "sr = 16000\n", "sound = AudioSegment.from_file('speech/video/70_Peratus_Gaji_Rakyat_Malaysia_Dibelanjakan_Untuk_Barang_Keperluan.mp3')\n", "samples = sound.set_frame_rate(sr).set_channels(1).get_array_of_samples()" ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [], "source": [ "samples = np.array(samples)\n", "samples = malaya_speech.utils.astype.int_to_float(samples)" ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "110.106125" ] }, "execution_count": 8, "metadata": {}, "output_type": "execute_result" } ], "source": [ "len(samples) / sr" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Initiate pipeline\n", "\n", "Read more how to use Malaya-Speech VAD model at https://malaya-speech.readthedocs.io/en/latest/load-vad.html#How-to-detect-Voice-Activity." ] }, { "cell_type": "code", "execution_count": 9, "metadata": {}, "outputs": [ { "data": { "image/png": "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\n", "text/plain": [ "" ] }, "execution_count": 9, "metadata": {}, "output_type": "execute_result" } ], "source": [ "p = Pipeline()\n", "\n", "pipeline = (\n", " p.map(malaya_speech.utils.generator.frames, frame_duration_ms = 30)\n", " .batching(5)\n", " .foreach_map(vad.predict)\n", " .flatten()\n", ")\n", "p.visualize()" ] }, { "cell_type": "code", "execution_count": 10, "metadata": { "scrolled": true }, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "/Users/huseinzolkepli/Documents/tf-1.15/env/lib/python3.7/site-packages/librosa/core/spectrum.py:224: UserWarning: n_fft=512 is too small for input signal of length=480\n", " n_fft, y.shape[-1]\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "CPU times: user 5min 34s, sys: 52.3 s, total: 6min 27s\n", "Wall time: 1min 22s\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "/Users/huseinzolkepli/Documents/tf-1.15/env/lib/python3.7/site-packages/librosa/core/spectrum.py:224: UserWarning: n_fft=512 is too small for input signal of length=384\n", " n_fft, y.shape[-1]\n" ] }, { "data": { "text/plain": [ "dict_keys(['frames', 'batching', 'predict', 'flatten'])" ] }, "execution_count": 10, "metadata": {}, "output_type": "execute_result" } ], "source": [ "%%time\n", "\n", "result = p(y)\n", "result.keys()" ] }, { "cell_type": "code", "execution_count": 11, "metadata": {}, "outputs": [], "source": [ "frames = result['frames']\n", "frames_vad = [\n", " (frame, result['flatten'][no]) for no, frame in enumerate(frames)\n", "]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Split utterances based on size negative VAD\n", "\n", "So to split based on negative VAD, we need to use `malaya_speech.split.split_vad`,\n", "\n", "```python\n", "def split_vad(\n", " frames,\n", " n: int = 3,\n", " negative_threshold: float = 0.1,\n", " silent_trail: int = 500,\n", " sample_rate: int = 16000,\n", " use_negative_as_silent: bool = False,\n", "):\n", " \"\"\"\n", " Split a sample into multiple samples based `n` size of negative VAD.\n", "\n", " Parameters\n", " ----------\n", " frames: List[Tuple[Frame, label]]\n", " n: int, optional (default=3)\n", " `n` size of negative VAD to assume in one subsample.\n", " negative_threshold: float, optional (default = 0.1)\n", " If `negative_threshold` is 0.1, means that, length negative samples must at least 0.1 second.\n", " silent_trail: int, optional (default = 500)\n", " If an element is not a voice activity, append with `silent_trail` frame size. \n", " sample_rate: int, optional (default = 16000)\n", " sample rate for frames.\n", " use_negative_as_silent: bool, optional (default = False)\n", " If True, will use negative VAD as silent, else, use zeros array size of `silent_trail`.\n", "\n", " Returns\n", " -------\n", " result : List[Frame]\n", " \"\"\"\n", "```" ] }, { "cell_type": "code", "execution_count": 12, "metadata": {}, "outputs": [], "source": [ "splitted = malaya_speech.split.split_vad(frames_vad)" ] }, { "cell_type": "code", "execution_count": 13, "metadata": {}, "outputs": [ { "data": { "text/html": [ "\n", " \n", " " ], "text/plain": [ "" ] }, "execution_count": 13, "metadata": {}, "output_type": "execute_result" } ], "source": [ "ipd.Audio(splitted[0].array, rate = sr)" ] }, { "cell_type": "code", "execution_count": 14, "metadata": {}, "outputs": [ { "data": { "text/html": [ "\n", " \n", " " ], "text/plain": [ "" ] }, "execution_count": 14, "metadata": {}, "output_type": "execute_result" } ], "source": [ "ipd.Audio(splitted[1].array, rate = sr)" ] }, { "cell_type": "code", "execution_count": 15, "metadata": {}, "outputs": [ { "data": { "text/html": [ "\n", " \n", " " ], "text/plain": [ "" ] }, "execution_count": 15, "metadata": {}, "output_type": "execute_result" } ], "source": [ "ipd.Audio(splitted[2].array, rate = sr)" ] }, { "cell_type": "code", "execution_count": 16, "metadata": {}, "outputs": [ { "data": { "text/html": [ "\n", " \n", " " ], "text/plain": [ "" ] }, "execution_count": 16, "metadata": {}, "output_type": "execute_result" } ], "source": [ "ipd.Audio(splitted[3].array, rate = sr)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Split utterances based on maximum duration VAD\n", "\n", "So to split based on maximum duration VAD, we need to use `malaya_speech.split.split_vad_duration`,\n", "\n", "```python\n", "def split_vad_duration(\n", " frames,\n", " max_duration: float = 5.0,\n", " negative_threshold: float = 0.1,\n", " silent_trail = 500,\n", " sample_rate: int = 16000,\n", " use_negative_as_silent: bool = False,\n", "):\n", " \"\"\"\n", " Split a sample into multiple samples based maximum duration of voice activities.\n", "\n", " Parameters\n", " ----------\n", " frames: List[Tuple[Frame, label]]\n", " max_duration: float, optional (default = 5.0)\n", " Maximum duration to assume one sample combined from voice activities.\n", " negative_threshold: float, optional (default = 0.1)\n", " If `negative_threshold` is 0.1, means that, length negative samples must at least 0.1 second.\n", " silent_trail: int, optional (default = 500)\n", " If an element is not a voice activity, append with `silent_trail` frame size.\n", " sample_rate: int, optional (default = 16000)\n", " sample rate for frames.\n", " use_negative_as_silent: bool, optional (default = False)\n", " If True, will use negative VAD as silent, else, use zeros array size of `silent_trail`.\n", "\n", " Returns\n", " -------\n", " result : List[Frame]\n", " \"\"\"\n", "```" ] }, { "cell_type": "code", "execution_count": 17, "metadata": {}, "outputs": [], "source": [ "splitted = malaya_speech.split.split_vad_duration(frames_vad, negative_threshold = 0.3)" ] }, { "cell_type": "code", "execution_count": 18, "metadata": {}, "outputs": [ { "data": { "text/html": [ "\n", " \n", " " ], "text/plain": [ "" ] }, "execution_count": 18, "metadata": {}, "output_type": "execute_result" } ], "source": [ "ipd.Audio(splitted[0].array, rate = sr)" ] }, { "cell_type": "code", "execution_count": 19, "metadata": {}, "outputs": [ { "data": { "text/html": [ "\n", " \n", " " ], "text/plain": [ "" ] }, "execution_count": 19, "metadata": {}, "output_type": "execute_result" } ], "source": [ "ipd.Audio(splitted[1].array, rate = sr)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "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.7.7" } }, "nbformat": 4, "nbformat_minor": 4 }