<!-- canonical: https://jmrplens.github.io/phonometry/es/guides/levels/ -->
Source: https://jmrplens.github.io/phonometry/es/guides/levels/

Una medición de ruido rara vez termina en una forma de onda: termina en un
puñado de números únicos que se pueden contrastar con un límite, un
reglamento o un informe. Esta página es esa cadena de reducción, calculada
directamente sobre la señal calibrada en pascales y no sobre lecturas de un
sonómetro: el nivel continuo equivalente $L_{eq}$/$L_{Aeq}$, los niveles
percentiles $L_N$, las medidas de sucesos y de pico ($L_{AE}$/SEL,
$L_{Cpeak}$), la dosis de ruido de IEC 61252 y los descriptores de día
completo $L_{den}$/$L_{dn}$ con los niveles de evaluación de ISO 1996-1.
Trabajar desde la señal significa aplicar cada definición (una integral, un
percentil, una suma de energías) de forma exacta, sin aproximaciones de
detector ni de pantalla por medio.

Qué descriptor encaja con qué pregunta sigue las familias de magnitudes de
ISO 1996-1 (BS 7445-1 es la guía de práctica de medición sobre esa misma
elección, y Bies, Hansen y Howard 2017, §2.5 las repasa en paralelo):

- **Exposición acumulada en un intervalo**: $L_{eq}$/$L_{Aeq}$, la media
  energética. Responde a "cuánto sonido llegó en total", sin importar cómo
  se repartió en el tiempo.
- **Cómo se distribuyó el nivel fluctuante**: los percentiles $L_N$:
  $L_{90}$ como nivel de fondo, $L_{10}$ como indicador de intrusión de
  tráfico, $L_{50}$ como mediana. Dos señales con el mismo $L_{Aeq}$ pueden
  tener dispersiones $L_{10} - L_{90}$ muy distintas.
- **Sucesos aislados de duraciones distintas, comparados con justicia**:
  SEL, toda la energía del suceso normalizada a un segundo.
- **Cribado de riesgo auditivo**: $L_{Cpeak}$ y las medidas de dosis, que
  alimentan el flujo laboral de
  [Exposición laboral (ISO 9612)](/phonometry/es/guides/occupational-exposure/).
- **Molestia comunitaria a largo plazo**: $L_{den}$/$L_{dn}$ y los niveles
  de evaluación de ISO 1996-1, que penalizan la energía de tarde y noche
  antes de promediar el día.

Conviene mantener nítidas dos fronteras con las páginas hermanas. Las
métricas integradas de esta página evitan deliberadamente el detector
exponencial: $L_{eq}$ y SEL no tienen constante de tiempo, y las balísticas
Fast/Slow solo entran por los niveles percentiles, definidos sobre la traza
de nivel con ponderación temporal (ver
[Ponderación temporal](/phonometry/es/guides/time-weighting/)). Y todo lo
de esta página asume la señal ya en pascales: el factor de sensibilidad que
la lleva ahí es el asunto de
[Calibración](/phonometry/es/guides/calibration/).

## Leq y LAeq

El nivel continuo equivalente integra la presión al cuadrado durante el tiempo
de medición:

$$
L_{eq} = 10\log_{10}\left(\frac{1}{T}\int_0^T \frac{p^2(t)}{p_0^2}\ dt\right) \text{ dB}, \qquad p_0 = 20\ \mu\text{Pa}
$$

y $L_{Aeq}$ es la misma integral tras ponderar A la señal. $L_N$ es el nivel
superado el $N\ \%$ del tiempo: el percentil $(100-N)$ de la distribución del
nivel con ponderación temporal.

```python

from phonometry import metrology

# recording: una captura de micrófono calibrada (Pa) — grabada con tu cadena de medición. Sintetizada aquí para que la guía funcione por sí sola.
fs = 48000
recording = 0.2 * np.sin(2 * np.pi * 1000 * np.arange(fs) / fs)
sensitivity = 1.0                                    # calibration_factor (ver Calibración)

# Nivel continuo equivalente de toda la grabación
level = metrology.leq(recording, calibration_factor=sensitivity)

# Leq ponderado A (la métrica estándar de ruido ambiental)
la = metrology.laeq(recording, fs, calibration_factor=sensitivity)
```

Ambas aceptan señales 1D (devuelven un escalar) o arrays 2D
`[channels, samples]` (devuelven un nivel por canal), y admiten `dbfs=True` para
análisis digital a fondo de escala (la calibración no aplica en modo dBFS).

¿Por qué la media *energética* y no la media aritmética de los valores en dB?
Porque las dosis sonoras se suman como energía: dos periodos a 60 dB y 80 dB no
promedian 70 dB; la mitad a 80 dB domina y $L_{eq}$ = 77 dB. Promediar
decibelios directamente subestima cualquier ruido fluctuante. $L_{eq}$ es el
nivel del sonido *estacionario* que transporta la misma energía que el real,
fluctuante, y por eso las normativas se redactan en términos de él.

La misma regla gobierna cualquier combinación de niveles: niveles de periodo
en un valor de día completo, posiciones de micrófono en un promedio de sala,
mediciones repetidas en una media. Combina energías,
`10 * np.log10(np.mean(10 ** (L / 10)))`, nunca los valores en dB. El error
de la media aritmética es unilateral (siempre lee de menos) y crece con la
dispersión, así que no se cancela con muchas mediciones: con valores
repartidos en 10 dB ya cuesta un par de decibelios. Las pocas fórmulas
normativas que sí promedian decibelios directamente son aproximaciones
deliberadas y lo declaran (ISO 1996-2 ofrece una como sustituto de la
incertidumbre por mediciones repetidas y avisa de que se infla cuando los
niveles se dispersan más de 3 dB, ver la sección de incertidumbre más abajo);
en todo lo demás, energía.

### Parámetros de `leq()` / `laeq()`

| Parámetro | Tipo / forma | Unidades | Rango / valor por defecto | Notas |
| :--- | :--- | :--- | :--- | :--- |
| `x` | array 1D o 2D | unidades digitales (o Pa si está calibrada) | no vacío | 2D es `[channels, samples]`; devuelve un nivel por canal |
| `fs` | int | Hz | > 0 (solo `laeq`) | `leq` no necesita frecuencia de muestreo (integral RMS pura) |
| `calibration_factor` | float | Pa por unidad digital | por defecto `1.0` | De `sensitivity()` |
| `dbfs` | bool | — | por defecto `False` | `True`: 0 dBFS = seno RMS a fondo de escala; ignora la calibración |

## Niveles percentiles (LN)

`ln_levels` calcula niveles estadísticos a partir de la envolvente con
ponderación temporal: **L10** es el nivel superado el 10 % del tiempo (picos de
eventos), **L50** la mediana y **L90** el nivel de fondo.

```python

from phonometry import metrology

# Un tono constante da L10 = L50 = L90; los percentiles solo cuentan algo con un
# nivel *fluctuante*. Sintetizamos 3 s alternando entre medio segundo tranquilo
# y otro ~10 dB más fuerte para que los estadísticos se separen.
fs = 48000
rng = np.random.default_rng(0)
segment = fs // 2                                  # 0.5 s por nivel
quiet = 0.02 * rng.standard_normal(segment)        # fondo
loud = 0.06 * rng.standard_normal(segment)         # eventos ~10 dB más fuertes
varying = np.tile(np.concatenate([quiet, loud]), 3)

stats = metrology.ln_levels(varying, fs, n=(10, 50, 90), weighting="A")
print(f"LA10={stats[10]:.1f}  LA50={stats[50]:.1f}  LA90={stats[90]:.1f} dB")
# LA10=66.6  LA50=65.2  LA90=58.5 dB  -> L10 (eventos) > L50 (mediana) > L90 (fondo)
```

*L10 sigue los picos de los eventos, L50 el nivel mediano y L90 el fondo.*

<details>
<summary>Mostrar el código de esta figura</summary>

```python

from phonometry import metrology

# La señal fluctuante del ejemplo de ln_levels: 0.5 s de fondo alternando
# con 0.5 s de eventos ~10 dB más fuertes, repetido 3 veces
fs = 48000
rng = np.random.default_rng(0)
segment = fs // 2
quiet = 0.02 * rng.standard_normal(segment)
loud = 0.06 * rng.standard_normal(segment)
varying = np.tile(np.concatenate([quiet, loud]), 3)

# Envolvente cuadrática media Fast -> nivel frente al tiempo, y los percentiles
envelope = metrology.time_weighting(varying, fs, mode="fast")
level_t = 10 * np.log10(np.maximum(envelope, 1e-12) / (2e-5) ** 2)
stats = metrology.ln_levels(varying, fs, n=(10, 50, 90))
t = np.arange(varying.size) / fs

fig, ax = plt.subplots()
ax.plot(t, level_t, linewidth=0.8, label="Nivel Fast Lp(t)")
for i, (n_value, style) in enumerate([(10, "--"), (50, "-"), (90, "-.")], 1):
    ax.axhline(float(stats[n_value]), color=f"C{i}", linestyle=style,
               label=f"L{n_value} = {stats[n_value]:.1f} dB")
ax.set(xlabel="Tiempo [s]", ylabel="Nivel [dB]")
ax.legend(loc="lower right")
plt.show()
```

</details>

Opciones: `mode` selecciona la ponderación temporal de la envolvente (`'fast'`, `'slow'`,
`'impulse'`), `weighting` aplica antes la ponderación A/C, y
`calibration_factor`/`dbfs` se comportan como en `leq`. El transitorio de ataque
del integrador (~5τ) se descarta antes de calcular los percentiles, de modo que
la rampa inicial de asentamiento no cuenta en los percentiles bajos.

Formalmente, $L_N$ es el percentil $(100-N)$ de la distribución del nivel con
ponderación temporal: la grabación se convierte primero en una envolvente de
nivel frente a tiempo (Fast por defecto), y $L_{10}$ es el valor de la
envolvente superado el 10 % del tiempo. Eso hace que la *elección de la
ponderación temporal forme parte de la métrica*: un $L_{10}$ con envolvente
Slow es sistemáticamente más bajo que con una Fast en ruido impulsivo, por lo
que las normativas siempre indican la ponderación temporal.

### Leer Leq frente a los percentiles

$L_{eq}$ y la familia $L_N$ responden preguntas distintas sobre el mismo
historial de niveles. $L_{eq}$ es una media energética, así que los momentos más
ruidosos la dominan: un solo segundo a 100 dB eleva el $L_{eq}$ de una hora
por lo demás estable a 60 dB hasta unos 66 dB, mientras que $L_{90}$,
$L_{50}$ e incluso $L_{10}$ apenas se mueven (un evento de un segundo ocupa
mucho menos del 10 % de la hora). Los percentiles son estadísticos de rango,
robustos frente a eventos raros por construcción. En la práctica:

- **$L_{eq}$ (y $L_{Aeq}$)** es la métrica de dosis: las normativas, la
  exposición y los modelos de molestia se escriben con ella precisamente
  *porque* se niega a ignorar los eventos ruidosos raros.
- **$L_{90}$** estima el nivel residual (de fondo) bajo una fuente
  intermitente, que es como lo usa el Anexo I de ISO 1996-2.
- **$L_{10}$** sigue los picos de los eventos; la separación
  $L_{10} - L_{90}$ es un indicador rápido de intermitencia.
- **$L_{eq} - L_{50}$** mide lo "picudo" que es el historial: en ruido
  estacionario casi coinciden, y cuanto más fluctúa el nivel más sube
  $L_{eq}$ por encima de la mediana (para una distribución gaussiana de
  niveles con desviación típica $\sigma$ dB,
  $L_{eq} \approx L_{50} + 0{,}115\,\sigma^2$).

Una precaución: los percentiles no se combinan. Dos horas con $L_{90}$
conocidos no dan el $L_{90}$ de las dos horas con ninguna fórmula;
recalcúlalo sobre la envolvente conjunta. Los valores de $L_{eq}$, en cambio,
se combinan exactamente promediando energías ponderadas por el tiempo, que es
lo que hace `composite_rating_level` más abajo.

### Parámetros de `ln_levels()`

| Parámetro | Tipo / forma | Unidades | Rango / valor por defecto | Notas |
| :--- | :--- | :--- | :--- | :--- |
| `x` | array 1D o 2D | unidades digitales | no vacío | 2D devuelve diccionarios por canal |
| `fs` | int | Hz | > 0 | Lo necesita el detector de envolvente |
| `n` | tupla de ints | % | por defecto `(10, 50, 90)` | Cualquier porcentaje de excedencia, p. ej. `(1, 5, 95)` |
| `mode` | str | — | `'fast'` (por defecto), `'slow'`, `'impulse'` | Ponderación temporal IEC 61672-1 de la envolvente |
| `weighting` | str o None | — | `'A'`, `'C'`, `'G'`, `'Z'`, `None` (por defecto) | Ponderación frecuencial previa a la envolvente |
| `calibration_factor` / `dbfs` | float / bool | — | como `leq` | Misma semántica que en `leq()` |

## Métricas de pico, evento y ocupacionales

```python

from phonometry import metrology

# recording: una captura de micrófono calibrada (Pa) — grabada con tu cadena de medición. Sintetizada aquí para que la guía funcione por sí sola.
fs = 48000
recording = 0.2 * np.sin(2 * np.pi * 1000 * np.arange(fs) / fs)
sensitivity = 1.0                                    # calibration_factor (ver Calibración)

# Pico ponderado C (IEC 61672-1 §5.13): los límites de acción laborales usan esto
peak = metrology.lc_peak(recording, fs, calibration_factor=sensitivity)

# Un único evento de ruido y una muestra de jornada (fragmentos de una grabación real)
event = recording
shift_sample = recording

# Nivel de exposición sonora: nivel del evento normalizado a 1 s (LAE)
lae = metrology.sel(event, fs, weighting="A", calibration_factor=sensitivity)

# Dosis diaria de ruido (IEC 61252): exposición en Pa²·h y LEX,8h / LEP,d
E = metrology.sound_exposure(shift_sample, fs, duration_hours=8, calibration_factor=sensitivity)
lex = metrology.lex_8h(shift_sample, fs, duration_hours=8, calibration_factor=sensitivity)
```

`lc_peak` está verificado contra las respuestas de referencia de ciclo
único/semiciclo de la Tabla 5 de IEC 61672-1:2013, `sel` contra la columna LAE
de la Tabla 4, y las funciones de dosis contra las anclas de IEC 61252
(3,2 Pa²h ↔ exactamente 90 dB). `lc_peak` sobremuestrea (polifásico) la señal
ponderada C por `oversample` (por defecto `8`) antes de tomar el máximo,
recuperando el verdadero pico inter-muestra: un máximo en rejilla subestima los
tonos de HF sostenidos hasta ~1,15 dB (un tono de 8 kHz a 48 kHz tiene solo
6 muestras/ciclo). Usa `oversample=1` para detectar el pico en la rejilla
original. Con `duration_hours`, la entrada se trata como muestra representativa
de ese periodo de exposición; sin él, la entrada es el evento completo.

### SEL: comparar eventos de distinta duración

Un paso de tren de 4 s y otro de 30 s no pueden compararse solo por su
$L_{Aeq}$: el evento más largo entrega más energía al mismo nivel. El **nivel
de exposición sonora** comprime la energía del evento *completo* en
exactamente un segundo:

$$
L_E = L_{eq,T} + 10\log_{10}\frac{T}{T_0}, \qquad T_0 = 1\ \text{s}
$$

de modo que los eventos de cualquier duración resultan directamente
comparables, y $N$ eventos idénticos se suman como $+10\log_{10}N$. Es el
bloque básico de los modelos de ruido aeroportuario y ferroviario.

<details>
<summary>Mostrar el código de esta figura</summary>

```python

from phonometry import metrology

# El paso de un vehículo: ruido bajo una envolvente de energía gaussiana (análisis en dBFS)
fs = 48000
t = np.arange(int(8.0 * fs)) / fs
rng = np.random.default_rng(11)
x = 0.3 * np.exp(-0.5 * ((t - 4.0) / 1.1) ** 2) * rng.standard_normal(t.size)

level = 10 * np.log10(np.maximum(metrology.time_weighting(x, fs, mode="fast"), 1e-12))
l_sel = float(metrology.sel(x, fs, dbfs=True))
l_eq = float(metrology.leq(x, dbfs=True))
print(f"Leq = {l_eq:.1f} dBFS, SEL = {l_sel:.1f} dBFS")
# Leq = -16.6 dBFS, SEL = -7.6 dBFS -> el bloque de 1 s lleva la energía del evento

fig, ax = plt.subplots()
ax.plot(t, level, linewidth=1.0, label="Nivel Fast del evento")
ax.hlines(l_eq, 0, 8, color="C2", linestyle="--",
          label=f"Leq sobre el evento completo = {l_eq:.1f} dBFS")
ax.fill_between([3.5, 4.5], -55, l_sel, color="C1", alpha=0.25)
ax.hlines(l_sel, 3.5, 4.5, color="C1", linewidth=2,
          label=f"SEL = {l_sel:.1f} dBFS: la misma energía en 1 s")
ax.set(xlabel="Tiempo [s]", ylabel="Nivel [dBFS]", ylim=(-55, l_sel + 6))
ax.legend(loc="lower left")
plt.show()
```

</details>

### Dosis de ruido: exposición sonora y LEX,8h

Las normativas laborales limitan la *dosis* diaria, no el nivel. IEC 61252 la
expresa como **exposición sonora** $E$ en pascales al cuadrado por hora (la
integral temporal de la presión ponderada A al cuadrado) y el **nivel
normalizado a 8 h** equivalente:

$$
E = \int_0^T p_A^2(t)\ dt \quad [\text{Pa}^2\text{h}], \qquad
L_{EX,8h} = 10\log_{10}\frac{E}{8\ \text{h} \cdot p_0^2}
$$

El ancla que conviene memorizar: **3,2 Pa²h ⇔ exactamente 90 dB durante 8 h**
(la suite de CI lo verifica). La mitad de dosis son −3 dB; el doble de
duración al mismo nivel son +3 dB.

### Parámetros de pico / evento / dosis

| Función | Parámetros clave | Devuelve | Ancla normativa |
| :--- | :--- | :--- | :--- |
| `lc_peak(x, fs, calibration_factor=1.0, dbfs=False)` | `dbfs=True` referencia el *pico* a fondo de escala (`1.0`), no el RMS | LCpeak [dB] | IEC 61672-1 §5.13, ráfagas de tono de la Tabla 5 |
| `sel(x, fs, weighting=None, ...)` | `weighting='A'` da el LAE | SEL [dB] | IEC 61672-1 Tabla 4 (columna LAE) |
| `sound_exposure(x, fs, duration_hours=None, ...)` | `duration_hours` trata `x` como muestra de ese periodo | E [Pa²h] | IEC 61252 |
| `lex_8h(x, fs, duration_hours=None, ...)` | misma semántica de muestreo | LEX,8h [dB] | IEC 61252 (≡ LEP,d) |

`lex_8h` califica *una* grabación; componer una jornada laboral completa a
partir de muestras por tarea o por función, con el presupuesto normativo de
incertidumbre de la ISO 9612, continúa en
[Exposición al ruido en el trabajo](/phonometry/es/guides/occupational-exposure/).

## Ruido ambiental: Lden, Ldn y niveles de evaluación (ISO 1996-1)

La evaluación regulatoria del ruido pondera más las tardes y las noches.
`lden()` implementa el nivel día-tarde-noche de ISO 1996-1:2016 (3.6.4:
+5 dB tarde, +10 dB noche, periodos 12/4/8 h por defecto, ajustables porque
cada país los define distinto), `ldn()` la variante día-noche (3.6.5) y
`composite_rating_level()` el compuesto general de jornada completa del
apartado 6.5 (Fórmulas 5-6) para periodos arbitrarios con ajustes por fuente o
carácter (Tabla A.1: p. ej. +5 dB impulsivo regular, +12 dB altamente
impulsivo, +3 a +6 dB tonos prominentes):

```python
from phonometry import environmental

l = environmental.lden(63.2, 58.1, 51.4)                      # desde LAeq por periodo
r = environmental.composite_rating_level([(63.2, 12, 0.0),    # día
                            (58.1, 4, 5.0),     # tarde (+5)
                            (51.4, 8, 10.0)])   # noche (+10) == environmental.lden
```

<details>
<summary>Mostrar el código de esta figura</summary>

```python

from phonometry import environmental

# LAeq horario sintético de una vía urbana (dB), horas 00 a 23
laeq_h = np.array([48, 46, 45, 45, 46, 50, 56, 64, 66, 65, 63, 63,
                   64, 63, 63, 64, 65, 66, 65, 64, 63, 62, 61, 50], dtype=float)

def period_leq(idx):
    return 10 * np.log10(np.mean(10 ** (laeq_h[idx] / 10)))  # media energética

ld = period_leq(np.arange(7, 19))                # día 07-19
le = period_leq(np.arange(19, 23))               # tarde 19-23
ln_ = period_leq(np.r_[23, np.arange(0, 7)])     # noche 23-07
l_den = environmental.lden(ld, le, ln_)
print(f"Lden = {l_den:.1f} dB")   # Lden = 64.3 dB

fig, ax = plt.subplots()
ax.axvspan(19, 23, color="C1", alpha=0.15)                                # tarde
ax.axvspan(23, 24, color="C0", alpha=0.15); ax.axvspan(0, 7, color="C0", alpha=0.15)
ax.step(np.arange(25), np.r_[laeq_h, laeq_h[-1]], where="post",
        color="0.3", label="LAeq horario")
ax.hlines(ld, 7, 19, color="C2", linestyle="--", label="Ldía (+0 dB)")
ax.hlines(le + 5, 19, 23, color="C1", linestyle="--", label="Ltarde + 5 dB")
ax.hlines([ln_ + 10, ln_ + 10], [23, 0], [24, 7], color="C0",
          linestyle="--", label="Lnoche + 10 dB")
ax.hlines(l_den, 0, 24, color="C3", linewidth=2, label=f"Lden = {l_den:.1f} dB")
ax.set(xlabel="Hora del día", ylabel="Nivel [dB]", xlim=(0, 24))
ax.legend(loc="upper left", fontsize=8, ncol=2)
plt.show()
```

</details>

### Parámetros de `lden()` / `ldn()` / `composite_rating_level()`

| Función | Parámetros clave | Notas |
| :--- | :--- | :--- |
| `lden(lday, levening, lnight, hours=(12, 4, 8))` | LAeq por periodo [dB]; `hours` debe sumar 24 | +5 dB tarde, +10 dB noche (3.6.4) |
| `ldn(lday, lnight, hours=(15, 9))` | | +10 dB noche (3.6.5) |
| `composite_rating_level(periods)` | iterable de `(level_db, hours, adjustment_db)` | Fórmulas generales (5)-(6); ajustes según la Tabla A.1 |

Dónde pones el micrófono cambia el número: ISO 1996-2 fija las posiciones del receptor y sus correcciones de fachada. El diagrama es contexto de medida; aplica las correcciones a tus niveles antes del análisis:

Combínalo con `laeq()` por periodo para ir de grabaciones a Lden, y con los
veredictos `tone_to_noise_ratio()` / `prominence_ratio()` de
[Tonos discretos prominentes](/phonometry/es/guides/tone-prominence/) para
justificar ajustes tonales.

## Determinación de niveles: ajuste tonal, ruido residual e incertidumbre (ISO 1996-2)

ISO 1996-2:2017 es la parte de **determinación**: cómo el nivel medido se
convierte en nivel de valoración y se reporta con su incertidumbre. La *suma* del
nivel de valoración y las penalizaciones por periodo están en ISO 1996-1 (arriba);
ISO 1996-2 aporta el ajuste tonal, la corrección de ruido residual y el
presupuesto de incertidumbre.

**Ajuste tonal (método de ingeniería, Anexo C).** A partir del nivel tonal
sumado en energía $L_{pt}$ y el nivel de ruido enmascarante $L_{pn}$ en la banda
crítica alrededor de un tono, la audibilidad sobre el umbral de enmascaramiento es
$\Delta L_{ta} = L_{pt} - L_{pn} + 2 + \lg[1 + (f_c/502)^{2.5}]$ dB (Fórmula (C.3)),
y el ajuste es $K_t = 0$ para $\Delta L_{ta} < 4$, $K_t = \Delta L_{ta} - 4$ para
$4 \le \Delta L_{ta} \le 10$ y $K_t = 6$ por encima (Fórmulas (C.4)–(C.6)). El
ancho de banda crítico es 100 Hz hasta 500 Hz y el 20 % de $f_c$ por encima
(Tabla C.1). El **método de cribado** en tercios de octava (`tonal_seeking_survey`)
marca una banda que supera a ambas vecinas en 15/8/5 dB (baja/media/alta), y
`tonal_adjustment_from_mean_audibility` mapea la audibilidad media de ISO/PAS 20065
a $K_t$ (Tabla J.1).

<details>
<summary>Mostrar el código de esta figura</summary>

```python

from phonometry import environmental

# ISO 1996-2:2007 Anexo C.5, Ejemplo 2 (dos tonos cerca de 400 Hz):
res = environmental.assess_tonal_audibility(tone_level=54.1, masking_noise_level=45.2,
                              centre_frequency=430.0)
print(res.audibility, res.adjustment)   # ΔLta ≈ 11,1 dB -> Kt = 6 dB
res.plot(language="es")
plt.show()
```
</details>

**Corrección de ruido residual (Cláusula 10.4).** `residual_sound_correction()`
aplica $L = 10\lg(10^{L'/10} - 10^{L_\text{res}/10})$ (Fórmula (16)). Con un
residual dentro de 3 dB del nivel medido no se permite corrección alguna: el
valor reportable es entonces el nivel medido *sin corregir* $L'$, como cota
superior del sonido específico (expuesto como `reportable_upper_bound`, con
`reliable=False`). `gaussian_residual_level()` estima el residual a partir de
niveles percentiles (Anexo I) y rechaza ordenaciones de percentiles
invertidas.

**Incertidumbre de medición (Cláusula 4, Anexo F).**
`combined_standard_uncertainty()` forma $u = \sqrt{\sum (c_j u_j)^2}$ (Fórmula (2))
y `environmental_expanded_uncertainty()` aplica $k = 2$ (95 %) o $k = 1.3$ (80 %);
`residual_correction_uncertainty()` lleva la sensibilidad de la corrección residual
(Fórmulas (F.7)/(F.8)) y `uncertainty_from_repeated_measurements()` la
incertidumbre típica de mediciones repetidas: la vía primaria en el dominio
de energía (Fórmulas (17)+(19)), con el sustituto en niveles de la Nota 2
(Fórmula (20)) reportado al lado como `approximate_uncertainty` y un aviso
cuando los niveles se dispersan más de 3 dB, donde el sustituto se infla
groseramente.

```python
from phonometry import environmental

tonal = environmental.assess_tonal_audibility(54.1, 45.2, 430.0)  # TonalAssessmentResult
kt = tonal.adjustment                                             # 6 dB
tonal.plot()   # esta audibilidad sobre la curva de Kt, como en la figura de arriba
corr = environmental.residual_sound_correction(measured_level=58.0, residual_level=50.0)
u = environmental.combined_standard_uncertainty([0.59, 0.3, 2.0, 0.40, 0.38])  # 2,18 dB (G.2)
environmental.expanded_uncertainty(u)                            # 4,36 dB (k = 2)
```

## Espectrograma de octavas (niveles vs tiempo)

Análisis de octava fraccional en tiempo corto: un nivel por banda y ventana,
alineado en el tiempo entre bandas.

```python

from phonometry import metrology

# recording: una captura de micrófono calibrada (Pa) — grabada con tu cadena de medición. Sintetizada aquí para que la guía funcione por sí sola.
fs = 48000
recording = 0.2 * np.sin(2 * np.pi * 1000 * np.arange(fs) / fs)

bank = metrology.OctaveFilterBank(fs=48000, fraction=3)
levels, freq, times = bank.spectrogram(recording, window_time=0.125, overlap=0.5)
# levels: (bandas, ventanas) — listo para pcolormesh(times, freq, levels)
```

*Un barrido logarítmico y dos ráfagas de tono, resueltos en el tiempo y en
bandas normalizadas de tercio de octava.*

<details>
<summary>Mostrar el código de esta figura</summary>

```python

from scipy.signal import chirp
from phonometry import metrology

# Barrido logarítmico de 80 Hz -> 8 kHz más dos ráfagas de tono, con algo de ruido
fs = 48000
t = np.arange(int(4.0 * fs)) / fs
x = 0.5 * chirp(t, f0=80, t1=4.0, f1=8000, method="logarithmic")
x[int(1.0 * fs):int(1.3 * fs)] += np.sin(2 * np.pi * 4000 * t[: int(0.3 * fs)])
x[int(2.5 * fs):int(2.8 * fs)] += np.sin(2 * np.pi * 250 * t[: int(0.3 * fs)])
x += 0.01 * np.random.default_rng(42).standard_normal(t.size)

bank = metrology.OctaveFilterBank(fs=fs, fraction=3, order=6, limits=[50.0, 12000.0])
levels, freq, times = bank.spectrogram(x, window_time=0.125, overlap=0.5)

fig, ax = plt.subplots()
mesh = ax.pcolormesh(times, freq, levels, shading="auto")
ax.set_yscale("log")
ax.set(xlabel="Tiempo [s]", ylabel="Frecuencia [Hz]")
fig.colorbar(mesh, label="Nivel [dB]")
plt.show()
```

</details>

- Una entrada multicanal `(channels, samples)` devuelve `(channels, bands, frames)`.
- `times` contiene el centro de cada ventana en segundos.
- `mode='peak'` da niveles de pico por ventana en lugar de RMS.
- `zero_phase=True` filtra las bandas hacia delante y atrás para que el retardo
  de grupo por banda no desplace las ventanas (solo análisis offline).

### Parámetros de `OctaveFilterBank.spectrogram()`

| Parámetro | Tipo | Unidades | Rango / valor por defecto | Notas |
| :--- | :--- | :--- | :--- | :--- |
| `x` | array 1D o 2D | unidades digitales | no vacío | 2D devuelve `(channels, bands, frames)` |
| `window_time` | float | s | > 0; por defecto `0.125` | Longitud de la ventana (0,125 s replica Fast) |
| `overlap` | float | — | 0 ≤ overlap < 1; por defecto `0.5` | Fracción de solape entre ventanas (0 = sin solape) |
| `mode` | str | — | `'rms'` (por defecto) o `'peak'` | Detector por ventana |
| `detrend` | bool | — | por defecto `True` | Elimina el offset DC de cada banda antes del nivel (mejora la precisión en graves) |
| `zero_phase` | bool | — | por defecto `False` | Filtrado hacia delante y atrás (solo offline) |
| `calibration_factor` / `dbfs` | — | — | solo constructor | Se fijan en `OctaveFilterBank(...)`, no por llamada |

Consulta [Calibración y dBFS](/phonometry/es/guides/calibration/) para
convertir unidades digitales a SPL físico, y
[Ponderación temporal](/phonometry/es/guides/time-weighting/) para los
detalles de la envolvente. Las estrategias ocupacionales de la ISO 9612
continúan en
[Exposición al ruido en el trabajo](/phonometry/es/guides/occupational-exposure/),
los veredictos de prominencia tonal de ECMA-418-1 en
[Tonos discretos prominentes](/phonometry/es/guides/tone-prominence/), y las
curvas isofónicas de ISO 226 viven con las métricas de percepción en
[Sonoridad](/phonometry/es/guides/loudness/). Que un único Leq sea un
resumen justo de una medición es, de entrada, una cuestión de
estacionariedad: los tests de
[calificación de datos](/phonometry/es/guides/data-qualification/) la
responden objetivamente a partir de medias cuadráticas por segmento.

## Qué cubre esta guía

**Cubierto.** La balística de envolvente Fast/Slow/Impulse de la IEC
61672-1:2013 que hay tras los niveles percentiles, el pico ponderado C del
apartado 5.13 (`lc_peak`, verificado frente a la Tabla 5) y el nivel de
exposición sonora (`sel`, verificado frente a la columna LAE de la Tabla
4); la exposición sonora y el LEX,8h de la IEC 61252:1993
(`sound_exposure`, `lex_8h`); el Lden, el Ldn y el nivel de valoración
compuesto de la ISO 1996-1:2016 (apartado 6.5,
`environmental.lden`/`ldn`/`composite_rating_level`); y el ajuste tonal
(anexo C), la corrección de ruido residual (apartado 10.4) y el balance de
incertidumbre de medida (apartado 4, anexo F) de la ISO 1996-2:2017.

**No cubierto.** La IEC 61252 se revisó en 2025; aquí solo están las
fórmulas de la primera edición implementada (1993), no las de la más
reciente. La ISO 1996-2 fija las posiciones del receptor y las
correcciones de fachada que convierten una medida en bruto en el nivel que
esperan las funciones de esta página: esos procedimientos de posición y
corrección no están implementados, solo la aritmética que sigue una vez
aplicados.

## Véase también

- [Ponderación temporal](/phonometry/es/guides/time-weighting/): el detector Fast/Slow/Impulse sobre el que se definen los niveles percentiles.
- [Calibración](/phonometry/es/guides/calibration/): el factor de sensibilidad que convierte unidades digitales en los pascales que todo nivel de esta página asume.
- [Exposición laboral (ISO 9612)](/phonometry/es/guides/occupational-exposure/): las estrategias de medición en el puesto de trabajo que alimentan las medidas de dosis.
- [Multicanal y rendimiento](/phonometry/es/guides/multichannel/): niveles por canal y cómo combinarlos energéticamente.
- Referencia de la API: [`metrology.levels`](/phonometry/es/reference/api/levels/levels/), [`environmental.measurement`](/phonometry/es/reference/api/environment/measurement/) y [`environmental.rating`](/phonometry/es/reference/api/environment/rating/).

## Respuestas rápidas

### ¿Cuál es la diferencia entre Leq y SEL?

$L_{eq}$ es el nivel continuo equivalente: la media energética de la presión
al cuadrado durante el tiempo de medición $T$, referida a
$p_0 = 20\ \mu\text{Pa}$. El SEL, el nivel de exposición sonora ($L_{AE}$ si
está ponderado A), comprime la energía del evento completo en exactamente un
segundo: $L_E = L_{eq,T} + 10\log_{10}(T/T_0)$ con $T_0 = 1\ \text{s}$, de
modo que los eventos de cualquier duración resultan directamente comparables
y $N$ eventos idénticos se suman como $+10\log_{10}N$.

### ¿Qué exposición sonora corresponde a 90 dB en una jornada de 8 horas?

Según IEC 61252:1993, la exposición sonora $E$ es la integral temporal de la
presión ponderada A al cuadrado, expresada en pascales al cuadrado por hora,
y $L_{EX,8h}$ (equivalente a $L_{EP,d}$) es el nivel correspondiente
normalizado a 8 h. El ancla que conviene memorizar: 3,2 Pa²h corresponde a
exactamente 90 dB durante 8 h. La mitad de dosis son -3 dB, y el doble de
duración al mismo nivel son +3 dB.

### ¿Qué penalizaciones aplica Lden a la tarde y a la noche?

$L_{den}$, el nivel día-tarde-noche de ISO 1996-1:2016 (3.6.4), suma +5 dB
al nivel de tarde y +10 dB al de noche antes de promediar energéticamente el
día completo, con periodos por defecto de 12, 4 y 8 horas, ajustables porque
cada país los define distinto. La variante día-noche $L_{dn}$ (3.6.5)
conserva solo la penalización de +10 dB de noche.
