{"cells":[{"metadata":{},"cell_type":"markdown","source":"A short notebook to explore the spectrograms of the different species. Generates:\n- a \"regular\" spectrogram using matplotlib,\n- a mel-spectrogram using librosa,\n- signal image reversed from the fourier transformations\n- both for the full one minute in the sample, and for cropped signal data containing only the given sample window\n\nI have no experience with audio analysis, spectrograms, etc., so any improvement suggestions are welcome."},{"metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"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)\n\nimport librosa\nimport librosa.display\nimport soundfile as sf\nimport os\nimport glob\nimport matplotlib.pyplot as plt\nfrom tqdm.auto import tqdm\nfrom scipy.fft import fft, fftfreq, rfft, rfftfreq, irfft","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"trainfiles = glob.glob( '../input/rfcx-species-audio-detection/train/*.flac' )\ntestfiles = glob.glob( '../input/rfcx-species-audio-detection/test/*.flac' )\nlen(trainfiles), len(testfiles), trainfiles[0]","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_kg_hide-input":true},"cell_type":"code","source":"df_train_tp = pd.read_csv( '../input/rfcx-species-audio-detection/train_tp.csv' )\ndf_train_tp[\"filepath\"] = df_train_tp[\"recording_id\"].apply(lambda rid: f\"../input/rfcx-species-audio-detection/train/{rid}.flac\")\ndf_train_tp['t_dif'] = df_train_tp['t_max'] - df_train_tp['t_min']\ndf_train_tp['f_dif'] = df_train_tp['f_max'] - df_train_tp['f_min']\ndf_train_tp[\"truepos\"] = \"1\"\n\ndf_train_fp = pd.read_csv( '../input/rfcx-species-audio-detection/train_fp.csv' )\ndf_train_fp[\"filepath\"] = df_train_fp[\"recording_id\"].apply(lambda rid: f\"../input/rfcx-species-audio-detection/train/{rid}.flac\")\ndf_train_fp['t_dif'] = df_train_fp['t_max'] - df_train_fp['t_min']\ndf_train_fp['f_dif'] = df_train_fp['f_max'] - df_train_fp['f_min']\ndf_train_fp[\"truepos\"] = 0\n\ndf_train_full = pd.concat([df_train_tp, df_train_fp])\n\ndf_train_tp.shape, df_train_fp.shape","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def collect_bird_metrics(df, species_id):\n    df = df[df[\"species_id\"] == species_id]\n    df_metrics = df.describe()\n    return df_metrics\n\nall_metrics = []\nfor x in range(24):\n    metrics = collect_bird_metrics(df_train_full, x)\n    all_metrics.append(metrics)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_kg_hide-input":true},"cell_type":"code","source":"# Plot the spectrogram\n\nsampling_frequency = 48000\nvisualize_fft_bins = False\n\ndef row_spectrogram(row, zoom, show_fft):\n    dataitem, samplerate = sf.read(row[\"filepath\"])\n    start_time = row[\"t_min\"]\n    start_time = float(start_time)\n    start_sample = start_time * sampling_frequency\n    start_sample = int(start_sample)\n    end_time = row[\"t_max\"] \n    end_sample = end_time * sampling_frequency\n    end_time = float(end_time)\n    end_sample = int(end_sample)\n    if zoom:\n        dataitem = dataitem[start_sample:end_sample]\n    freq_bottom = row[\"f_min\"]\n    freq_top = row[\"f_max\"]\n\n    if not zoom:\n        plt.figure(figsize=(8,5))\n        plt.title(\"Full one minute spectrogram with sample time and frequency highlighted\")\n        plt.axvspan(start_time, end_time, color='red', alpha=0.1)\n    else:\n        plt.figure(figsize=(5,5))\n        plt.title(\"Sample time cropped spectrogram\")\n    plt.axhspan(freq_bottom, freq_top, color='red', alpha=0.3)\n    powerSpectrum, freqenciesFound, time, imageAxis = plt.specgram(dataitem, Fs=sampling_frequency)\n    plt.xlabel('Time')\n    plt.ylabel('Frequency')\n    plt.show()\n    \n    plt.figure(figsize=(8,5))\n    if not zoom:\n        plt.title('Full one minute Mel spectrogram, with full frequency range')\n        mel_spectrogram = librosa.feature.melspectrogram(y=dataitem,\n                                                             sr=samplerate,\n                                                             n_mels=256,\n                                                             fmax=samplerate/2,\n                                                             hop_length=128)\n    else:\n        plt.title('Mel spectrogram for signal time and frequency range')\n        #256 mels produced empty streaks, reduced to 128\n        mel_spectrogram = librosa.feature.melspectrogram(y=dataitem,\n                                                             sr=samplerate,\n                                                             n_mels=128,\n                                                             hop_length=64,\n                                                             fmax=freq_top,\n                                                             fmin=freq_bottom)\n\n    librosa.display.specshow(librosa.power_to_db(mel_spectrogram,ref=np.max),\n                              y_axis='mel', x_axis='time')\n    plt.colorbar(format='%+2.0f dB')\n    plt.tight_layout()\n\n    if show_fft:\n        bird_fft(dataitem, freq_bottom, freq_top, zoom)\n\ndef bird_spectrograms(df, species_id, idxs, zoom=False, show_fft=False):\n    df = df[df[\"species_id\"] == species_id]\n    df = df.iloc[idxs]\n    for index, row in df.iterrows():\n        print(f\"plotting row {index}:\\n{row}\")\n        row_spectrogram(row, False, show_fft)\n        if zoom:\n            print(f\"plotting (zoomed) sample area only: {row['t_min']}s to {row['t_max']}s\")\n            row_spectrogram(row, True, show_fft)\n    \n    \n#https://realpython.com/python-scipy-fft/\ndef bird_fft(dataitem, freq_bottom, freq_top, zoom):\n    yf = rfft(dataitem)\n#    xf = rfftfreq(dataitem.shape[0], 1 / sampling_frequency * 100)\n    xf = rfftfreq(dataitem.shape[0], 1 / sampling_frequency)\n\n    if visualize_fft_bins:\n        plt.figure(figsize=(8,5))\n        if not zoom:\n            plt.title(\"Full one minute FFT frequency weights\")\n        else:\n            plt.title(\"Sample range FFT frequency weights\")\n        plt.plot(xf, np.abs(yf))\n        plt.show()\n    \n    # The maximum frequency is half the sample rate (yes, I copied this from the internet :)\n    points_per_freq = len(xf) / (sampling_frequency / 2)\n\n    target_idx_bottom = int(points_per_freq * freq_bottom)\n    target_idx_top = int(points_per_freq * freq_top)\n    yf[target_idx_top:] = 0\n    yf[:target_idx_bottom] = 0\n\n    if visualize_fft_bins:\n        plt.figure(figsize=(8,5))\n        if not zoom:\n            plt.title(\"Full FFT frequency weights for sample time\")\n        else:\n            plt.title(\"Sample frequency range FFT frequency weights for sample time\")\n        plt.plot(xf, np.abs(yf))\n        plt.show()\n\n    #reverse the fft data back to signal without the filtered parts\n    new_sig = irfft(yf)\n\n    plt.figure(figsize=(8,5))\n    if not zoom:\n        plt.title(\"Reversed signal from sample FFT frequency weights, cropped to sample freq range\")\n    else:\n        plt.title(\"Reversed signal from sample FFT frequency weights, cropped to sample time and freq range\")\n    plt.plot(new_sig)\n    plt.show()\n    \n    #the following will draw a spectrogram for the filtered signal range(s)\n#    plt.figure(figsize=(8,5))\n#    powerSpectrum, freqenciesFound, time, imageAxis = plt.specgram(new_sig, Fs=sampling_frequency)\n#    plt.title(\"Spectrogram from above FFT reversed signal\")\n#    plt.xlabel('Time')\n#    plt.ylabel('Frequency')\n#    plt.show()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"indices_to_plot = [0,1,2]","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Species 1"},{"metadata":{"trusted":true},"cell_type":"code","source":"x=0","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"display(all_metrics[x])\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"bird_spectrograms(df_train_tp, x, indices_to_plot, True, True)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Species 2"},{"metadata":{"trusted":true},"cell_type":"code","source":"x=1","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"display(all_metrics[x])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"bird_spectrograms(df_train_tp, x, indices_to_plot, True, True)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Species 3"},{"metadata":{"trusted":true},"cell_type":"code","source":"x = 2","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"display(all_metrics[x])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"bird_spectrograms(df_train_tp, x, indices_to_plot, True, True)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Species 4"},{"metadata":{"trusted":true},"cell_type":"code","source":"x = 3","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"display(all_metrics[x])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"bird_spectrograms(df_train_tp, x, indices_to_plot, True, True)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Species 5"},{"metadata":{"trusted":true},"cell_type":"code","source":"x = 4","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"display(all_metrics[x])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"bird_spectrograms(df_train_tp, x, indices_to_plot, True, True)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Species 6"},{"metadata":{"trusted":true},"cell_type":"code","source":"x = 5","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"display(all_metrics[x])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"bird_spectrograms(df_train_tp, x, indices_to_plot, True, True)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Species 7"},{"metadata":{"trusted":true},"cell_type":"code","source":"x = 6","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"display(all_metrics[x])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"bird_spectrograms(df_train_tp, x, indices_to_plot, True, True)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Species 8"},{"metadata":{"trusted":true},"cell_type":"code","source":"x = 7","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"display(all_metrics[x])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"bird_spectrograms(df_train_tp, x, indices_to_plot, True, True)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Species 9"},{"metadata":{"trusted":true},"cell_type":"code","source":"x = 8","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"display(all_metrics[x])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"bird_spectrograms(df_train_tp, x, indices_to_plot, True, True)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Species 10"},{"metadata":{"trusted":true},"cell_type":"code","source":"x = 9","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"display(all_metrics[x])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"bird_spectrograms(df_train_tp, x, indices_to_plot, True, True)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Species 11"},{"metadata":{"trusted":true},"cell_type":"code","source":"x = 10","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"display(all_metrics[x])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"bird_spectrograms(df_train_tp, x, indices_to_plot, True, True)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Species 12"},{"metadata":{"trusted":true},"cell_type":"code","source":"x = 11","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"display(all_metrics[x])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"bird_spectrograms(df_train_tp, x, indices_to_plot, True, True)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Species 13"},{"metadata":{"trusted":true},"cell_type":"code","source":"x = 12","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"display(all_metrics[x])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"bird_spectrograms(df_train_tp, x, indices_to_plot, True, True)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Species 14"},{"metadata":{"trusted":true},"cell_type":"code","source":"x = 13","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"display(all_metrics[x])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"bird_spectrograms(df_train_tp, x, indices_to_plot, True, True)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Species 15"},{"metadata":{"trusted":true},"cell_type":"code","source":"x = 14","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"display(all_metrics[x])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"bird_spectrograms(df_train_tp, x, indices_to_plot, True, True)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Species 16"},{"metadata":{"trusted":true},"cell_type":"code","source":"x = 15","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"display(all_metrics[x])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"bird_spectrograms(df_train_tp, x, indices_to_plot, True, True)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Species 17"},{"metadata":{"trusted":true},"cell_type":"code","source":"x = 16","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"display(all_metrics[x])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"bird_spectrograms(df_train_tp, x, indices_to_plot, True, True)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Species 18"},{"metadata":{"trusted":true},"cell_type":"code","source":"x = 17","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"display(all_metrics[x])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"bird_spectrograms(df_train_tp, x, indices_to_plot, True, True)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Species 19"},{"metadata":{"trusted":true},"cell_type":"code","source":"x = 18","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"display(all_metrics[x])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"bird_spectrograms(df_train_tp, x, indices_to_plot, True, True)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Species 20"},{"metadata":{"trusted":true},"cell_type":"code","source":"x = 19","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"display(all_metrics[x])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"bird_spectrograms(df_train_tp, x, indices_to_plot, True, True)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Species 21"},{"metadata":{"trusted":true},"cell_type":"code","source":"x = 20","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"display(all_metrics[x])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"bird_spectrograms(df_train_tp, x, indices_to_plot, True, True)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Species 22"},{"metadata":{"trusted":true},"cell_type":"code","source":"x = 21","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"display(all_metrics[x])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"bird_spectrograms(df_train_tp, x, indices_to_plot, True, True)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Species 23"},{"metadata":{"trusted":true},"cell_type":"code","source":"x = 22","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"display(all_metrics[x])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"bird_spectrograms(df_train_tp, x, indices_to_plot, True, True)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Species 24"},{"metadata":{"trusted":true},"cell_type":"code","source":"x = 23","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"display(all_metrics[x])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"bird_spectrograms(df_train_tp, x, indices_to_plot, True, True)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"","execution_count":null,"outputs":[]}],"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}