{"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_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"Exploration and Normalization","metadata":{}},{"cell_type":"code","source":"# This Python 3 environment comes with many helpful analytics libraries installed\n# It is defined by the kaggle/python Docker image: https://github.com/kaggle/docker-python\n# For example, here's several helpful packages to load\n\nimport numpy as np # linear algebra\nimport pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\n\n# Input data files are available in the read-only \"../input/\" directory\n# For example, running this (by clicking run or pressing Shift+Enter) will list all files under the input directory\n\nimport os\nfor dirname, _, filenames in os.walk('/kaggle/input'):\n    for filename in filenames:\n        pass # print(os.path.join(dirname, filename))\n\n# You can write up to 5GB to the current directory (/kaggle/working/) that gets preserved as output when you create a version using \"Save & Run All\" \n# You can also write temporary files to /kaggle/temp/, but they won't be saved outside of the current session","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import numpy as np\nimport pandas as pd\n\nimport matplotlib.pyplot as plt\nimport seaborn as sns\n\nfrom IPython.display import Audio, clear_output, display, HTML\n\nimport librosa\nimport librosa.display\n\n","metadata":{"_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"sample_file = \"/kaggle/input/birdsong-recognition/train_audio/scoori/XC265149.mp3\"\n# sample_file = \"/kaggle/input/birdsong-recognition/example_test_audio/BLKFR-10-CPL_20190611_093000.pt540.mp3\"\nsample_audio = librosa.load(sample_file)\ny, sr = sample_audio","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"sample_audio, y.shape[0], sr","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Let's make and display a mel-scaled power (energy-squared) spectrogram\nS = librosa.feature.melspectrogram(y, sr=sr, n_mels=128)\n\n# Convert to log scale (dB). We'll use the peak power (max) as reference.\nlog_S = librosa.power_to_db(S, ref=np.max)\n\n# Make a new figure\nplt.figure(figsize=(12,4))\n\n# Display the spectrogram on a mel scale\n# sample rate and hop length parameters are used to render the time axis\nlibrosa.display.specshow(log_S, sr=sr, x_axis='time', y_axis='mel')\n\n# Put a descriptive title on the plot\nplt.title('mel power spectrogram')\n\n# draw a color bar\nplt.colorbar(format='%+02.0f dB')\n\n# Make the figure layout compact\nplt.tight_layout()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Harmonic-percussive source separation\n# Before doing any signal analysis, let's pull apart the harmonic and percussive components of the audio. This is pretty easy to do with the effects module.\n\ny_harmonic, y_percussive = librosa.effects.hpss(y)\n# What do the spectrograms look like?\n# Let's make and display a mel-scaled power (energy-squared) spectrogram\nS_harmonic   = librosa.feature.melspectrogram(y_harmonic, sr=sr)\nS_percussive = librosa.feature.melspectrogram(y_percussive, sr=sr)\n\n# Convert to log scale (dB). We'll use the peak power as reference.\nlog_Sh = librosa.power_to_db(S_harmonic, ref=np.max)\nlog_Sp = librosa.power_to_db(S_percussive, ref=np.max)\n\n# Make a new figure\nplt.figure(figsize=(12,6))\n\nplt.subplot(2,1,1)\n# Display the spectrogram on a mel scale\nlibrosa.display.specshow(log_Sh, sr=sr, y_axis='mel')\n\n# Put a descriptive title on the plot\nplt.title('mel power spectrogram (Harmonic)')\n\n# draw a color bar\nplt.colorbar(format='%+02.0f dB')\n\nplt.subplot(2,1,2)\nlibrosa.display.specshow(log_Sp, sr=sr, x_axis='time', y_axis='mel')\n\n# Put a descriptive title on the plot\nplt.title('mel power spectrogram (Percussive)')\n\n# draw a color bar\nplt.colorbar(format='%+02.0f dB')\n\n# Make the figure layout compact\nplt.tight_layout()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Chromagram\n# Next, we'll extract Chroma features to represent pitch class information.\n\n# We'll use a CQT-based chromagram with 36 bins-per-octave in the CQT analysis.  An STFT-based implementation also exists in chroma_stft()\n# We'll use the harmonic component to avoid pollution from transients\nC = librosa.feature.chroma_cqt(y=y_harmonic, sr=sr, bins_per_octave=36)\n\n# Make a new figure\nplt.figure(figsize=(12,4))\n\n# Display the chromagram: the energy in each chromatic pitch class as a function of time\n# To make sure that the colors span the full range of chroma values, set vmin and vmax\nlibrosa.display.specshow(C, sr=sr, x_axis='time', y_axis='chroma', vmin=0, vmax=1)\n\nplt.title('Chromagram')\nplt.colorbar()\n\nplt.tight_layout()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# MFCC\n# Mel-frequency cepstral coefficients are commonly used to represent texture or timbre of sound.\n\n# Next, we'll extract the top 13 Mel-frequency cepstral coefficients (MFCCs)\nmfcc        = librosa.feature.mfcc(S=log_S, n_mfcc=13)\n\n# Let's pad on the first and second deltas while we're at it\ndelta_mfcc  = librosa.feature.delta(mfcc)\ndelta2_mfcc = librosa.feature.delta(mfcc, order=2)\n\n# How do they look?  We'll show each in its own subplot\nplt.figure(figsize=(12, 6))\n\nplt.subplot(3,1,1)\nlibrosa.display.specshow(mfcc)\nplt.ylabel('MFCC')\nplt.colorbar()\n\nplt.subplot(3,1,2)\nlibrosa.display.specshow(delta_mfcc)\nplt.ylabel('MFCC-$\\Delta$')\nplt.colorbar()\n\nplt.subplot(3,1,3)\nlibrosa.display.specshow(delta2_mfcc, sr=sr, x_axis='time')\nplt.ylabel('MFCC-$\\Delta^2$')\nplt.colorbar()\n\nplt.tight_layout()\n\n# For future use, we'll stack these together into one matrix\nM = np.vstack([mfcc, delta_mfcc, delta2_mfcc])","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Beat tracking\n# The beat tracker returns an estimate of the tempo (in beats per minute) and frame indices of beat events.\n# The input can be either an audio time series (as we do below), or an onset strength envelope as calculated by librosa.onset.onset_strength().\n\n# Now, let's run the beat tracker.\n# We'll use the percussive component for this part\nplt.figure(figsize=(12, 6))\ntempo, beats = librosa.beat.beat_track(y=y_percussive, sr=sr)\n\n# Let's re-draw the spectrogram, but this time, overlay the detected beats\nplt.figure(figsize=(12,4))\nlibrosa.display.specshow(log_S, sr=sr, x_axis='time', y_axis='mel')\n\n# Let's draw transparent lines over the beat frames\nplt.vlines(librosa.frames_to_time(beats),\n           1, 0.5 * sr,\n           colors='w', linestyles='-', linewidth=2, alpha=0.5)\n\nplt.axis('tight')\n\nplt.colorbar(format='%+02.0f dB')\n\nplt.tight_layout();","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print('Estimated tempo:        %.2f BPM' % tempo)\n\nprint('First 5 beat frames:   ', beats[:5])\n\n# Frame numbers are great and all, but when do those beats occur?\nprint('First 5 beat times:    ', librosa.frames_to_time(beats[:5], sr=sr))\n\n# We could also get frame numbers from times by librosa.time_to_frames()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Beat-synchronous feature aggregation\n# Once we've located the beat events, we can use them to summarize the feature content of each beat.\n\n# This can be useful for reducing data dimensionality, and removing transient noise from the features.\n# feature.sync will summarize each beat event by the mean feature vector within that beat\n\nM_sync = librosa.util.sync(M, beats)\n\nplt.figure(figsize=(12,6))\n\n# Let's plot the original and beat-synchronous features against each other\nplt.subplot(2,1,1)\nlibrosa.display.specshow(M)\nplt.title('MFCC-$\\Delta$-$\\Delta^2$')\n\n# We can also use pyplot *ticks directly\n# Let's mark off the raw MFCC and the delta features\nplt.yticks(np.arange(0, M.shape[0], 13), ['MFCC', '$\\Delta$', '$\\Delta^2$'])\n\nplt.colorbar()\n\nplt.subplot(2,1,2)\n# librosa can generate axis ticks from arbitrary timestamps and beat events also\nlibrosa.display.specshow(M_sync, x_axis='time',\n                         x_coords=librosa.frames_to_time(librosa.util.fix_frames(beats)))\n\nplt.yticks(np.arange(0, M_sync.shape[0], 13), ['MFCC', '$\\Delta$', '$\\Delta^2$'])             \nplt.title('Beat-synchronous MFCC-$\\Delta$-$\\Delta^2$')\nplt.colorbar()\n\nplt.tight_layout()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Beat synchronization is flexible.\n# Instead of computing the mean delta-MFCC within each beat, let's do beat-synchronous chroma\n# We can replace the mean with any statistical aggregation function, such as min, max, or median.\n\nC_sync = librosa.util.sync(C, beats, aggregate=np.median)\n\nplt.figure(figsize=(12,6))\n\nplt.subplot(2, 1, 1)\nlibrosa.display.specshow(C, sr=sr, y_axis='chroma', vmin=0.0, vmax=1.0, x_axis='time')\n\nplt.title('Chroma')\nplt.colorbar()\n\nplt.subplot(2, 1, 2)\nlibrosa.display.specshow(C_sync, y_axis='chroma', vmin=0.0, vmax=1.0, x_axis='time', \n                         x_coords=librosa.frames_to_time(librosa.util.fix_frames(beats)))\n\n\nplt.title('Beat-synchronous Chroma (median aggregation)')\n\nplt.colorbar()\nplt.tight_layout()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Get annotation data","metadata":{}},{"cell_type":"code","source":"train_df = pd.read_csv(\"../input/birdsong-recognition/train.csv\")\ntrain_df.shape","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_df[train_df.filename==\"XC265149.mp3\"].T.to_dict()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"y.shape[0]/sr","metadata":{"trusted":true},"execution_count":null,"outputs":[]}]}