Skip to article frontmatterSkip to article content
Site not loading correctly?

This may be due to an incorrect BASE_URL configuration. See the MyST Documentation for reference.

Individual Sound Analysis

Waveform, spectrogramme et paramètres acoustiques pour chaque son.

import subprocess
subprocess.run(["pip", "install", "librosa"], capture_output=True)
!pip install librosa
print("✓ librosa installé")
Requirement already satisfied: librosa in /home/ocean/ENTER/lib/python3.13/site-packages (0.11.0)
Requirement already satisfied: audioread>=2.1.9 in /home/ocean/ENTER/lib/python3.13/site-packages (from librosa) (3.1.0)
Requirement already satisfied: numba>=0.51.0 in /home/ocean/ENTER/lib/python3.13/site-packages (from librosa) (0.65.1)
Requirement already satisfied: numpy>=1.22.3 in /home/ocean/ENTER/lib/python3.13/site-packages (from librosa) (2.4.4)
Requirement already satisfied: scipy>=1.6.0 in /home/ocean/ENTER/lib/python3.13/site-packages (from librosa) (1.17.1)
Requirement already satisfied: scikit-learn>=1.1.0 in /home/ocean/ENTER/lib/python3.13/site-packages (from librosa) (1.8.0)
Requirement already satisfied: joblib>=1.0 in /home/ocean/ENTER/lib/python3.13/site-packages (from librosa) (1.5.3)
Requirement already satisfied: decorator>=4.3.0 in /home/ocean/ENTER/lib/python3.13/site-packages (from librosa) (5.2.1)
Requirement already satisfied: soundfile>=0.12.1 in /home/ocean/ENTER/lib/python3.13/site-packages (from librosa) (0.13.1)
Requirement already satisfied: pooch>=1.1 in /home/ocean/ENTER/lib/python3.13/site-packages (from librosa) (1.9.0)
Requirement already satisfied: soxr>=0.3.2 in /home/ocean/ENTER/lib/python3.13/site-packages (from librosa) (1.1.0)
Requirement already satisfied: typing_extensions>=4.1.1 in /home/ocean/ENTER/lib/python3.13/site-packages (from librosa) (4.15.0)
Requirement already satisfied: lazy_loader>=0.1 in /home/ocean/ENTER/lib/python3.13/site-packages (from librosa) (0.5)
Requirement already satisfied: msgpack>=1.0 in /home/ocean/ENTER/lib/python3.13/site-packages (from librosa) (1.1.1)
Requirement already satisfied: standard-aifc in /home/ocean/ENTER/lib/python3.13/site-packages (from librosa) (3.13.0)
Requirement already satisfied: standard-sunau in /home/ocean/ENTER/lib/python3.13/site-packages (from librosa) (3.13.0)
Requirement already satisfied: packaging in /home/ocean/ENTER/lib/python3.13/site-packages (from lazy_loader>=0.1->librosa) (26.0)
Requirement already satisfied: llvmlite<0.48,>=0.47.0dev0 in /home/ocean/ENTER/lib/python3.13/site-packages (from numba>=0.51.0->librosa) (0.47.0)
Requirement already satisfied: platformdirs>=2.5.0 in /home/ocean/ENTER/lib/python3.13/site-packages (from pooch>=1.1->librosa) (4.9.4)
Requirement already satisfied: requests>=2.19.0 in /home/ocean/ENTER/lib/python3.13/site-packages (from pooch>=1.1->librosa) (2.33.1)
Requirement already satisfied: charset_normalizer<4,>=2 in /home/ocean/ENTER/lib/python3.13/site-packages (from requests>=2.19.0->pooch>=1.1->librosa) (3.4.4)
Requirement already satisfied: idna<4,>=2.5 in /home/ocean/ENTER/lib/python3.13/site-packages (from requests>=2.19.0->pooch>=1.1->librosa) (3.11)
Requirement already satisfied: urllib3<3,>=1.26 in /home/ocean/ENTER/lib/python3.13/site-packages (from requests>=2.19.0->pooch>=1.1->librosa) (2.6.3)
Requirement already satisfied: certifi>=2023.5.7 in /home/ocean/ENTER/lib/python3.13/site-packages (from requests>=2.19.0->pooch>=1.1->librosa) (2026.4.22)
Requirement already satisfied: threadpoolctl>=3.2.0 in /home/ocean/ENTER/lib/python3.13/site-packages (from scikit-learn>=1.1.0->librosa) (3.5.0)
Requirement already satisfied: cffi>=1.0 in /home/ocean/ENTER/lib/python3.13/site-packages (from soundfile>=0.12.1->librosa) (1.17.1)
Requirement already satisfied: pycparser in /home/ocean/ENTER/lib/python3.13/site-packages (from cffi>=1.0->soundfile>=0.12.1->librosa) (3.0)
Requirement already satisfied: standard-chunk in /home/ocean/ENTER/lib/python3.13/site-packages (from standard-aifc->librosa) (3.13.0)
Requirement already satisfied: audioop-lts in /home/ocean/ENTER/lib/python3.13/site-packages (from standard-aifc->librosa) (0.2.2)
✓ librosa installé
import os
import json
import numpy as np
import pandas as pd
import plotly.graph_objects as go
from plotly.subplots import make_subplots
import ipywidgets as widgets
from IPython.display import display, Audio
import librosa
import warnings
warnings.filterwarnings('ignore')
outputs_folder = "../outputs"
data = []
for sound_folder in os.listdir(outputs_folder):
    json_path = os.path.join(outputs_folder, sound_folder, "results.json")
    if os.path.exists(json_path):
        with open(json_path, "r") as f:
            result = json.load(f)
            result["group"] = sound_folder[0]
            data.append(result)

df = pd.DataFrame(data)
audio_dir = os.path.abspath("../data/sounds")
df["audio_path"] = df["file"].apply(lambda x: os.path.join(audio_dir, x))
print(f"✓ {len(df)} sons chargés")
✓ 52 sons chargés
def show_sound_details(filename):
    path = df[df["file"] == filename]["audio_path"].values[0]
    y, sr = librosa.load(path, sr=None)
    times = np.linspace(0, len(y)/sr, len(y))
    D = librosa.amplitude_to_db(np.abs(librosa.stft(y)), ref=np.max)
    freqs = librosa.fft_frequencies(sr=sr)
    frames = librosa.frames_to_time(np.arange(D.shape[1]), sr=sr)

    fig = make_subplots(rows=2, cols=1,
                        subplot_titles=(f"Waveform — {filename}", "Spectrogramme"),
                        vertical_spacing=0.15)
    fig.add_trace(go.Scatter(x=times, y=y, mode="lines",
                             line=dict(color="#1f77b4", width=0.8)), row=1, col=1)
    fig.add_trace(go.Heatmap(z=D, x=frames, y=freqs,
                             colorscale="Viridis", colorbar=dict(title="dB")), row=2, col=1)
    fig.update_layout(title=f"Analyse : {filename}", height=600, showlegend=False)
    fig.update_xaxes(title_text="Temps (s)", row=1, col=1)
    fig.update_xaxes(title_text="Temps (s)", row=2, col=1)
    fig.update_yaxes(title_text="Amplitude", row=1, col=1)
    fig.update_yaxes(title_text="Fréquence (Hz)", row=2, col=1)
    fig.show()

def show_sound_params(filename):
    row = df[df["file"] == filename].iloc[0]
    params = {
        "Paramètre": ["Durée (s)", "F0 moyen (Hz)", "Variabilité F0",
                      "Intensité (RMS)", "Centroïde spectral (Hz)",
                      "Largeur de bande (Hz)", "Rolloff spectral (Hz)"],
        "Valeur": [
            f"{row['duration']:.3f}", f"{row['f0_mean']:.2f}",
            f"{row['f0_variability']:.2f}", f"{row['global_intensity']:.5f}",
            f"{row['spectral_centroid_mean']:.2f}",
            f"{row['spectral_bandwidth_mean']:.2f}",
            f"{row['spectral_rolloff_mean']:.2f}"
        ]
    }
    fig = go.Figure(data=[go.Table(
        header=dict(values=["Paramètre", "Valeur"],
                    fill_color="#1f77b4", font=dict(color="white", size=13), align="left"),
        cells=dict(values=[params["Paramètre"], params["Valeur"]],
                   fill_color="lavender", align="left", font=dict(size=12))
    )])
    fig.update_layout(title=f"Paramètres — {filename} (Groupe {row['group']})", height=300)
    fig.show()
audio_out = widgets.Output()
file_selector = widgets.Dropdown(options=df["file"].tolist(), description="Son")
button = widgets.Button(description="▶ Jouer le son")

def on_click(b):
    path = df[df["file"] == file_selector.value]["audio_path"].values[0]
    with audio_out:
        audio_out.clear_output()
        display(Audio(path, autoplay=True))

def on_file_change(change):
    if change["name"] == "value":
        show_sound_params(change["new"])
        show_sound_details(change["new"])

button.on_click(on_click)
file_selector.observe(on_file_change)

display(file_selector, button, audio_out)
show_sound_params(file_selector.value)
show_sound_details(file_selector.value)
Loading...
Loading...
Loading...
Loading...
Loading...