{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.7.9","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"none","dataSources":[{"sourceId":25954,"databundleVersionId":2091745,"sourceType":"competition"},{"sourceId":33246,"databundleVersionId":3221581,"sourceType":"competition"},{"sourceId":44224,"databundleVersionId":5188730,"sourceType":"competition"},{"sourceId":91844,"databundleVersionId":11361821,"sourceType":"competition"}],"dockerImageVersionId":30060,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":false}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"# Interactive Spectogram Viewer","metadata":{}},{"cell_type":"markdown","source":"### Original kernel by [@linainversez](https://www.kaggle.com/linainversez): [spectrogram-viewer](https://www.kaggle.com/linainversez/spectrogram-viewer) ","metadata":{}},{"cell_type":"markdown","source":"#### Update:\n- V7: modified for 2025 dataset (14/03/2025)","metadata":{}},{"cell_type":"markdown","source":"### Run in interactive mode to view spectrograms","metadata":{}},{"cell_type":"code","source":"!pip install -U ipywidgets","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-03-15T14:33:56.820783Z","iopub.execute_input":"2025-03-15T14:33:56.821221Z","iopub.status.idle":"2025-03-15T14:34:07.140700Z","shell.execute_reply.started":"2025-03-15T14:33:56.821175Z","shell.execute_reply":"2025-03-15T14:34:07.139569Z"},"_kg_hide-input":true,"_kg_hide-output":true,"collapsed":true,"jupyter":{"outputs_hidden":true}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"!jupyter nbextension enable --py widgetsnbextension","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-03-15T14:34:07.142476Z","iopub.execute_input":"2025-03-15T14:34:07.142774Z","iopub.status.idle":"2025-03-15T14:34:08.634730Z","shell.execute_reply.started":"2025-03-15T14:34:07.142745Z","shell.execute_reply":"2025-03-15T14:34:08.633437Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import numpy as np # linear algebra\nimport pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\nimport glob\nimport librosa\nimport librosa.display\nimport matplotlib.pyplot as plt\nimport matplotlib.patches as patches\nfrom ipywidgets import interact\nfrom ipywidgets import widgets\nfrom IPython.display import display","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","_kg_hide-input":true,"execution":{"iopub.status.busy":"2025-03-15T14:34:45.907990Z","iopub.execute_input":"2025-03-15T14:34:45.908419Z","iopub.status.idle":"2025-03-15T14:34:45.913730Z","shell.execute_reply.started":"2025-03-15T14:34:45.908387Z","shell.execute_reply":"2025-03-15T14:34:45.912468Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# TRAIN_FILES = glob.glob( '../input/birdclef-2021/train_short_audio/*/*.ogg' )\n# df = pd.read_csv('../input/birdclef-2021/train_metadata.csv')\n\n# TRAIN_FILES = glob.glob( '../input/birdclef-2022/train_audio/*/*.ogg' )\n# df = pd.read_csv('../input/birdclef-2022/train_metadata.csv')\n\n# INPUT = '/kaggle/input/birdclef-2023'\nINPUT = '/kaggle/input/birdclef-2025'\nTRAIN_FILES = glob.glob(f'{INPUT}/train_audio/*/*.ogg' )\ndf = pd.read_csv(f'{INPUT}/train.csv')\n\n# fft params\nSR = 32000\nN_FFT = 1024 #2048 #1024\nHOP_LEN = 512\nFMIN = 40 #20\nFMAX = 15000 #16000\n# CLIP_LENGTH = 5 # 7 # number of seconds to clip around the sound\n# START_TIME = 1  # start 2 seconds before t_min\n\n## If you want to see ALL birds \nBIRD_CODE = {p:i for i,p in enumerate(sorted(df.primary_label.unique()))}\nINV_BIRD_CODE = {i:p for i,p in enumerate(sorted(df.primary_label.unique()))}\nN_CLASS = len(BIRD_CODE) # 152\n\nprint('Number of audios:', len(TRAIN_FILES) ) # 62874\nprint('Number of classes:', N_CLASS ) # 152","metadata":{"execution":{"iopub.status.busy":"2025-03-15T14:34:46.220692Z","iopub.execute_input":"2025-03-15T14:34:46.221162Z","iopub.status.idle":"2025-03-15T14:34:49.303591Z","shell.execute_reply.started":"2025-03-15T14:34:46.221124Z","shell.execute_reply":"2025-03-15T14:34:49.302384Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"## Helper Functions","metadata":{}},{"cell_type":"code","source":"# def get_full_path(bird_class, recording_id):\n#     return f'../input/birdclef-2021/train_short_audio/{bird_class}/{recording_id}'\n\n# def pad_truncate_sequence(x, max_len):\n#     if len(x) < max_len:\n#         return np.concatenate((x, np.zeros(max_len - len(x)))) # pad back\n#     else:\n#         return x[0 : max_len]\n\n# def cut_audio(audio, t_min, start_time=START_TIME):\n#     start = max(0, t_min - start_time)\n#     end = start + CLIP_LENGTH\n#     snippet = audio[int(start*SR):int(end*SR)]\n#     if t_min - start_time < 0:\n#         return t_min, pad_truncate_sequence(snippet, CLIP_LENGTH*SR)\n#     else:\n#         return START_TIME, pad_truncate_sequence(snippet, CLIP_LENGTH*SR)\n\ndef get_full_path(bird_class, recording_id):\n    return f'{INPUT}/train_audio/{recording_id}'\n\n\ndef load_audio(bird_class, recording_id):\n    audio, _ = librosa.core.load(get_full_path(bird_class, recording_id), sr=SR, mono=True)\n    return audio\n\ndef create_spectrogram_from_row(row):\n    recording_id = row.filename\n    bird_class = row.primary_label\n    audio = load_audio(bird_class, recording_id)\n    #start, audio = cut_audio(audio, t_min)\n    stft = librosa.stft(audio, n_fft=N_FFT, hop_length=HOP_LEN, win_length=N_FFT)\n    S_db = librosa.amplitude_to_db(np.abs(stft), ref=np.max)\n    fig, ax = plt.subplots(figsize=(15,6))\n    ax.set_title(f\"[Bird: {bird_class}] Spectrogram of Audio:{recording_id.split('/')[-1]}\", fontsize=15)\n    img = librosa.display.specshow(S_db, hop_length=HOP_LEN, sr=SR, fmin=FMIN, fmax=FMAX, x_axis='time', y_axis='hz')  # ['linear', 'log', 'mel']\n    # ax.add_patch(patches.Rectangle(xy=(start, f_min), width=t_max-t_min, height=f_max-f_min, ec='#00ff00', fill=False) )\n    fig.colorbar(img, ax=ax)","metadata":{"_kg_hide-input":true,"execution":{"iopub.status.busy":"2025-03-15T14:34:49.305622Z","iopub.execute_input":"2025-03-15T14:34:49.305938Z","iopub.status.idle":"2025-03-15T14:34:49.314784Z","shell.execute_reply.started":"2025-03-15T14:34:49.305907Z","shell.execute_reply":"2025-03-15T14:34:49.313328Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def update_x_range(*args):\n    image_slider.max = df[df.primary_label == INV_BIRD_CODE[int(species_dropdown.value)]].shape[0]-1\n    \nimage_slider = widgets.IntSlider(min=0, max=df[df.primary_label == INV_BIRD_CODE[0]].shape[0]-1, value=0)\nspecies_dropdown = widgets.Dropdown(options=list(range(N_CLASS)), value=0) ## BIRD_CODE    \nimage_slider.observe(update_x_range, 'value')\n\ndef view_image(audio_idx, bird_id):\n    sub_df = df[df.primary_label == INV_BIRD_CODE[int(bird_id)]]\n    create_spectrogram_from_row(sub_df.iloc[audio_idx])","metadata":{"_kg_hide-input":true,"execution":{"iopub.status.busy":"2025-03-15T14:34:49.890925Z","iopub.execute_input":"2025-03-15T14:34:49.891300Z","iopub.status.idle":"2025-03-15T14:34:49.921469Z","shell.execute_reply.started":"2025-03-15T14:34:49.891271Z","shell.execute_reply":"2025-03-15T14:34:49.920263Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# Spectogram Viewer","metadata":{}},{"cell_type":"code","source":"#### Run in interactive mode to view spectrograms\n\n## audio_idx: no of audio file for selected bird \n## bird_id: bird id class 0-20 or 0-151, see INV_BIRD_CODE\n\ninteract(view_image, audio_idx=image_slider, bird_id=species_dropdown);","metadata":{"execution":{"iopub.status.busy":"2025-03-15T14:34:50.715343Z","iopub.execute_input":"2025-03-15T14:34:50.715706Z","iopub.status.idle":"2025-03-15T14:34:53.164593Z","shell.execute_reply.started":"2025-03-15T14:34:50.715675Z","shell.execute_reply":"2025-03-15T14:34:53.163373Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"INV_BIRD_CODE","metadata":{"_kg_hide-input":true,"_kg_hide-output":true,"execution":{"iopub.status.busy":"2023-03-08T00:25:52.214114Z","iopub.execute_input":"2023-03-08T00:25:52.214670Z","iopub.status.idle":"2023-03-08T00:25:52.233411Z","shell.execute_reply.started":"2023-03-08T00:25:52.214602Z","shell.execute_reply":"2023-03-08T00:25:52.232419Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"","metadata":{},"outputs":[],"execution_count":null}]}