{"cells":[{"metadata":{},"cell_type":"markdown","source":"### Update : \n#### Added audio widget to physically analyse the changes\n\n# 🦉 Cornell Birdcall Identification:\n![](https://imgc.artprintimages.com/img/print/a-tawny-frogmouth-owl-podargus-strigoides-at-the-fort-worth-zoo_u-l-pncfu00.jpg?h=550&p=0&w=550&background=fbfbfb)\n\n# Introduction:\n### This notebook aims at analysing various transformations and important functions that can be used to encode/transform audio data","execution_count":null},{"metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"cell_type":"code","source":"import torch\nimport torchaudio\nimport matplotlib.pyplot as plt\nimport numpy as np\nimport pandas as pd\n\nimport librosa\nimport librosa.display\n\nimport IPython.display as ipd","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## Picking up a random Audiofile for all the operatons moving forward","execution_count":null},{"metadata":{"_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","trusted":true},"cell_type":"code","source":"# filename = \"../input/birdsong-recognition/train_audio/nutwoo/XC462016.mp3\"\nfilename = '../input/birdsong-recognition/train_audio/balori/XC101614.mp3'\n\nwaveform, sample_rate = torchaudio.load(filename)\n\nprint(\"Shape of waveform {}\".format(waveform.size()))\nprint(\"Sample rate of wavefor {}\".format(sample_rate))\n\nplt.figure(figsize=(14,5))\nplt.plot(waveform.t()) # transpose\n","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## Original Audio:","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"ipd.Audio(waveform, rate=sample_rate)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Transformations:\n## ***torchaudio.transforms***\n### Torchaudio supports the [following](https://pytorch.org/audio/transforms.html) transformations. We will be looking at some of them here.","execution_count":null},{"metadata":{},"cell_type":"markdown","source":"## Transformation : Log of spectrogram on log scale","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"specgram = torchaudio.transforms.Spectrogram()(waveform)\n\nprint(\"Shape of Spectrogram {}\".format(specgram.size()))\n\nplt.figure(figsize=(14,5))\nplt.imshow(specgram.log2()[0,:,:1200].numpy(), cmap='gray')","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## Transformation : MelSpectrogram on log scale","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"specgram = torchaudio.transforms.MelSpectrogram()(waveform)\n\nprint(\"Shape of MelSpectrogram {}\".format(specgram.size()))\n\nplt.figure(figsize=(14,5))\nplt.imshow(specgram.log2()[0,:,:1000].numpy(), cmap='gray')","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## Transformation : Resampling the waveform, one channel at a time","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"new_sample_rate = sample_rate / 10\n\nchannel = 0\n\nresampled = torchaudio.transforms.Resample(sample_rate, new_sample_rate)(waveform[channel,:].view(1,-1))\n\nprint(\"Shape of resampled waveform: {}\".format(resampled.size()))\n\nplt.figure(figsize=(14,5))\nplt.plot(resampled[0,:].numpy())","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## Resampled Audio:","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"ipd.Audio(resampled, rate=new_sample_rate)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## Transformation : Mu-Law encoding\n### The signal must be between [-1,1] for Mu-Law encoding","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"print(\"Min. of waveform {} \\n Max. of waveform {} \\n Mean of waveform {}\".format(waveform.min(), waveform.max(), waveform.mean()))","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"### Our signal is already between [-1, 1], but had it not been, we would have used the following normalizing function","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"def normalize(signal):\n    signal_minusmean = signal - signal.mean()\n    return signal_minusmean / signal_minusmean.abs().max()\n\n#Normalizing waveform\n# print(\"After normalizing waveform...\")\n# print(\"Min. of waveform {}\".format(normalize(waveform).min().item()))\n# print(\"Max. of waveform {}\".format(normalize(waveform).max().item()))\n# print(\"Mean. of waveform {}\".format(normalize(waveform).mean().item()))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Applying Mu Law encoding\nencoded = torchaudio.transforms.MuLawEncoding()(waveform)\n\nprint(\"Shape of encoded waveform {}\".format(encoded.size()))\n\nplt.figure(figsize=(14,5))\nplt.plot(encoded[0,:].numpy())","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## Mu-Law encoded Audio:","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"ipd.Audio(encoded, rate=sample_rate)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## Now lets decode this waveform","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"reconstructed = torchaudio.transforms.MuLawDecoding()(encoded)\n\nprint(\"Shape of recovered waveform {}\".format(reconstructed.size()))\n\nplt.figure(figsize=(14,5))\nplt.plot(reconstructed[0,:].numpy())","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## Decoded Audio:","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"ipd.Audio(reconstructed, rate=sample_rate)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"### Sounds like original only !","execution_count":null},{"metadata":{},"cell_type":"markdown","source":"## Comparing original waveform with its reconstructed version","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"err = ((waveform-reconstructed).abs() / waveform.abs()).median()\n\nprint(\"Median error difference between original waveform and its reconstructed version is {:.2%}\".format(err))","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Functions:\n## All these transformations that we saw till now rely on stateless *functions* for their computations, which are availabe under *torchaudio.functional*\n## torchaudio.functional\n### Functions to perform common audio operations [Link](https://pytorch.org/audio/functional.html)","execution_count":null},{"metadata":{},"cell_type":"markdown","source":"## Functional: Mu Law encoding using functional ","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"mu_law_encoding_waveform = torchaudio.functional.mu_law_encoding(waveform, quantization_channels=256)\n\nprint(\"Shape of transformed waveform: {}\".format(mu_law_encoding_waveform.size()))\n\nplt.figure(figsize=(14,5))\nplt.plot(mu_law_encoding_waveform[0,:].numpy())","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"### Observe how the output from *torchaudio.functional.mu_law_encoding* is same as output from *torchaudio.transforms.MuLawEncoding *","execution_count":null},{"metadata":{},"cell_type":"markdown","source":"## Functional: Compute_deltas \n### To compute delta cofficients of a tensor","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"computed = torchaudio.functional.compute_deltas(specgram.contiguous(), win_length=3)\n\nprint(\"Shape of Computed deltas {}\".format(computed.size()))\n\nplt.figure(figsize=(14,5))\nplt.imshow(computed.log2()[0,:,:1000].numpy(), cmap='gray')","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## Functional: gain\n### Applies amplification/attenuation to the whole waveform****","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"gain_waveform = torchaudio.functional.gain(waveform, gain_db=5.0)\n\nprint(\"Min. of gain_waveform {} \\nMax. of gain_waveform {} \\nMean of gain_waveform {}\".format(gain_waveform.min(), gain_waveform.max(), gain_waveform.mean()))","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## gain_waveform Audio:","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"ipd.Audio(gain_waveform, rate=sample_rate)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## Functional: dither\n### Increases the perceived dynamic range of audio stored at a particular bit-depth","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"dither_waveform = torchaudio.functional.dither(waveform)\nprint(\"Min of dither_waveform: {}\\nMax of dither_waveform: {}\\nMean of dither_waveform: {}\".format(dither_waveform.min(), dither_waveform.max(), dither_waveform.mean()))","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## Dither_waveform Audio:","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"ipd.Audio(dither_waveform, rate=sample_rate)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Applying Filters to our waveform: using torchaudio.functional","execution_count":null},{"metadata":{},"cell_type":"markdown","source":"## Filters : Low-pass filter(Second order)","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"lowpass_waveform = torchaudio.functional.lowpass_biquad(waveform, sample_rate, cutoff_freq=3000)\n\nprint(\"Min. of lowpass_waveform: {}\\nMax. of lowpass_waveform: {}\\nMean of lowpass_waveform: {}\".format(lowpass_waveform.min(), lowpass_waveform.max(), lowpass_waveform.mean()))\n\nplt.figure(figsize=(14,5))\nplt.plot(lowpass_waveform.t().numpy())","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## Filtered (low-pass) Audio:","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"ipd.Audio(lowpass_waveform, rate=sample_rate)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## Filters : High-pass filter(Second order)","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"highpass_waveform = torchaudio.functional.highpass_biquad(waveform, sample_rate, cutoff_freq=2000)\n\nprint(\"Min of highpass_waveform: {}\\nMax of highpass_waveform: {}\\nMean of highpass_waveform: {}\".format(highpass_waveform.min(), highpass_waveform.max(), highpass_waveform.mean()))\n\nplt.figure(figsize=(14,5))\nplt.plot(highpass_waveform.t().numpy())","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## Filtered (high-pass) Audio:","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"ipd.Audio(highpass_waveform, rate=sample_rate)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"### Reference:    torchaudio [tutorial](https://pytorch.org/tutorials/beginner/audio_preprocessing_tutorial.html#functional)","execution_count":null},{"metadata":{},"cell_type":"markdown","source":"# If you like my kernel, do upvote 🕊️🕊️🕊️","execution_count":null}],"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"pygments_lexer":"ipython3","nbconvert_exporter":"python","version":"3.6.4","file_extension":".py","codemirror_mode":{"name":"ipython","version":3},"name":"python","mimetype":"text/x-python"}},"nbformat":4,"nbformat_minor":4}