---
title: "Ponderación frecuencial (A, B, C, D, G, AU, Z)"
description: "Ponderación frecuencial A/C/Z según IEC 61672-1 (clase 1, con modo de precisión en alta frecuencia), ponderación G de infrasonido según ISO 7196, las curvas históricas B (ANSI S1.4-1983) y D (IEC 537) y la AU según IEC 61012 para sonido audible en presencia de ultrasonidos."
references:
  - type: article
    authors: ["Fletcher, H.", "Munson, W. A."]
    year: 1933
    title: "Loudness, its definition, measurement and calculation"
    journal: "The Journal of the Acoustical Society of America"
    volume: 5
    issue: 2
    pages: "82-108"
    doi: "10.1121/1.1915637"
    note: "Las mediciones originales de igual sonoridad; la curva A invierte su isófona de 40 fonios (sección 1)."
  - type: standard
    organization: "International Organization for Standardization"
    year: 2023
    title: "Acoustics — Normal equal-loudness-level contours"
    designation: "ISO 226:2023"
    url: "https://www.iso.org/standard/83117.html"
    note: "Las sucesoras modernas de las curvas de Fletcher y Munson, dibujadas en el diagrama de la sección 1."
  - type: standard
    organization: "International Electrotechnical Commission"
    year: 2013
    title: "Electroacoustics — Sound level meters — Part 1: Specifications"
    designation: "IEC 61672-1:2013"
    url: "https://webstore.iec.ch/en/publication/5708"
    note: "Las curvas de ponderación frecuencial A, C y Z normativas (la definición analítica del Anexo E a partir de cuatro frecuencias de esquina, normalizadas a 0 dB en 1 kHz), las tolerancias de clase 1 que el diseño high_accuracy mantiene hasta 16 kHz y los límites de aceptación de clase 1 y clase 2 de la Tabla 3 que comprueba verify_weighting_class en la sección 8."
  - type: standard
    organization: "International Organization for Standardization"
    year: 1995
    title: "Acoustics — Frequency-weighting characteristic for infrasound measurements"
    designation: "ISO 7196:1995"
    url: "https://www.iso.org/standard/13813.html"
    note: "La definición de polos y ceros de la ponderación G (Tabla 1), verificada frente a todos los valores nominales de respuesta de la Tabla 2 (0,25 Hz a 315 Hz)."
  - type: standard
    organization: "American National Standards Institute"
    year: 1983
    title: "Specification for Sound Level Meters"
    designation: "ANSI S1.4-1983"
    note: "La ponderación B histórica: definición analítica del Apéndice C (fórmula C2), objetivos de diseño de la Tabla IV y límites de tolerancia de la Tabla V que comprueba verify_weighting_class en la sección 8."
  - type: standard
    organization: "International Electrotechnical Commission"
    year: 1990
    title: "Filters for the measurement of audible sound in the presence of ultrasound"
    designation: "IEC 61012:1990"
    url: "https://webstore.iec.ch/en/publication/4383"
    note: "La ponderación AU: posiciones de los polos de la ponderación U (Tabla 2), respuestas nominales y tolerancias (Tabla 1) y la definición combinada AU del apartado 2.2."
  - type: standard
    organization: "International Electrotechnical Commission"
    year: 1976
    title: "Frequency weighting for the measurement of aircraft noise (D-weighting)"
    designation: "IEC 537:1976 (retirada)"
    note: "La ponderación D, implementada desde su función de transferencia racional publicada y contrastada con dos implementaciones independientes y con la curva tabulada reeditada en NASA CR-3406 (Tabla SLD-I)."
  - type: report
    authors: ["Bennett, R. L.", "Pearsons, K. S."]
    year: 1981
    title: "Handbook of Aircraft Noise Metrics"
    institution: "NASA"
    number: "NASA CR-3406"
    url: "https://ntrs.nasa.gov/citations/19810013341"
    note: "Reedita la tabla de la ponderación D de IEC 537 (Tabla SLD-I) usada para anclar la respuesta D en CI."
---

import ThemeImage from '../../../../components/ThemeImage.astro';

Las curvas de ponderación frecuencial simulan la sensibilidad del oído humano.
A, C y Z están especificadas en **IEC 61672-1:2013**; la curva G de
infrasonido, en **ISO 7196:1995**. Tres curvas más completan la familia: la
histórica **B** (ANSI S1.4-1983), la **D** de ruido de aeronaves de la
retirada IEC 537 y la **AU** (IEC 61012) para sonido audible en presencia de
ultrasonidos (sección 4).

<ThemeImage src="https://raw.githubusercontent.com/jmrplens/phonometry/main/.github/images/weighting_responses_es.svg" alt="Curvas de ponderación A, B, C, D, AU y Z con zoom de la región positiva de la curva A (+1,27 dB en 2,5 kHz)" width="80%" loading="eager" />

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

```python
import matplotlib.pyplot as plt
import numpy as np
from phonometry import metrology

# Medimos la respuesta de cada curva: ponderamos un impulso unitario
# centrado y tomamos su espectro (búfer de 1 s -> resolución de 1 Hz).
fs = 48000
impulse = np.zeros(fs)
impulse[fs // 2] = 1.0
freqs = np.fft.rfftfreq(fs, 1 / fs)

fig, ax = plt.subplots(figsize=(9, 5))
for curve in ("A", "B", "C", "D", "AU", "Z"):
    spectrum = np.fft.rfft(metrology.weighting_filter(impulse, fs, curve=curve))
    ax.semilogx(freqs[1:], 20 * np.log10(np.abs(spectrum[1:]) + np.finfo(float).eps),
                label=curve)
ax.set(xlim=(10, 20000), ylim=(-80, 15),
       xlabel="Frecuencia [Hz]", ylabel="Respuesta [dB]")
ax.grid(True, which="both", alpha=0.3)
ax.legend()
plt.show()
```

</details>

* **Ponderación A (`A`):** estándar para ruido ambiental (IEC 61672-1).
* **Ponderación C (`C`):** para presión sonora de pico y ruido de alto nivel.
* **Ponderación Z (`Z`):** ponderación cero, respuesta completamente plana.
* **Ponderación G (`G`):** ponderación de infrasonido según ISO 7196 (ver más abajo).
* **Ponderación B (`B`):** curva intermedia histórica de ANSI S1.4-1983 (sección 4).
* **Ponderación D (`D`):** ponderación de ruido de aeronaves de la retirada IEC 537 (sección 4).
* **Ponderación AU (`AU`):** ponderación A con el corte de ultrasonidos de IEC 61012 (sección 4).

## 1. De dónde vienen las curvas

Las curvas A y C son líneas isofónicas invertidas, congeladas en filtros:
**A** aproxima la inversa de la histórica línea isofónica de 40 fonios (niveles
bajos, donde el oído descarta los graves con más agresividad) y **C** la más
plana de ~100 fonios (niveles altos). IEC 61672-1:2013 (Anexo E) define ambas
analíticamente a partir de cuatro frecuencias de esquina:

$$
f_1 = 20{,}599\ \text{Hz}, \quad f_2 = 107{,}653\ \text{Hz}, \quad
f_3 = 737{,}862\ \text{Hz}, \quad f_4 = 12194{,}217\ \text{Hz}
$$

C es un paso-banda con polos dobles en $f_1$ y $f_4$ (2 ceros en el origen);
A añade los polos $f_2$ y $f_3$ (4 ceros), y por eso sigue cayendo en los
medios-graves. Ambas se normalizan a exactamente 0 dB en 1 kHz. Z es la
ausencia de ponderación. La derivación completa de polos y ceros está en la
página de [Teoría](/phonometry/es/reference/theory/signal-analysis/).

<ThemeImage src="https://raw.githubusercontent.com/jmrplens/phonometry/main/.github/images/diagram_equal_loudness_weighting_es.svg" alt="Líneas isofónicas según ISO 226 a la izquierda, con la isófona de 40 fonios resaltada; a la derecha la curva de ponderación A superpuesta a la isófona de 40 fonios invertida, mostrando que A es la isófona volteada congelada en un filtro realizable" width="92%" />

### Una breve historia: A, B, C y Z

La cadena va de las mediciones de igual sonoridad de Fletcher y Munson en
1933 a la primera norma estadounidense de sonómetros (1936), que dio a los
medidores respuestas conmutables para que la lectura aproximara la
sonoridad a distintos niveles: **A** de la isófona de 40 fonios para sonidos
débiles, **B** de la de ~70 fonios para los moderados y una respuesta plana
para los fuertes (la curva **C** propiamente dicha, reflejo de la isófona
más plana de ~100 fonios, llegó con la revisión de 1944). Conmutar curvas
según el nivel murió en la práctica (las
lecturas saltaban en los puntos de cambio y las mediciones de campo dejaban
de ser comparables), pero A sobrevivió sola: décadas de datos de daño
auditivo y de molestia comunitaria se habían recogido con ella, y
correlaciona con ambos casi tan bien como métricas mucho más elaboradas.
IEC 61672-1 (primera edición, 2002) remató la limpieza: B se eliminó, A y C
se conservaron con tolerancias más estrictas y **Z** se introdujo para
sustituir el "lineal" mal especificado de los sonómetros antiguos, que
variaba según el fabricante. La curva B (y la curva D de ruido de aeronaves,
que corrió la misma suerte) sigue disponible para datos históricos; véase la
sección 4.

### Cuándo importa C − A

Como A descarta los graves y C los conserva, la diferencia
$L_{Ceq} - L_{Aeq}$ es un indicador de un solo número del contenido en
baja frecuencia:

- **Por debajo de unos 10 dB**: espectro de banda ancha ordinario; el nivel
  ponderado A lo califica con justicia.
- **En torno a 15 a 20 dB o más**: la energía se concentra en las bajas
  frecuencias (retumbo de climatización, compresores, graves de música a
  través de una pared). El nivel ponderado A entonces subestima el problema;
  mira el espectro de octavas y, por debajo de 20 Hz, pasa a la curva G.
- **La selección de protectores auditivos**: el método HML de ISO 4869-2 se
  apoya exactamente en esta diferencia C menos A para decidir cuánta
  atenuación en baja frecuencia debe aportar el protector (el método SNR,
  más simple, la esquiva trabajando directamente con el nivel ponderado C).

```python
import numpy as np
from phonometry import metrology

# Un retumbo de 50 Hz bajo un siseo ligero: débil en A, fuerte en C.
fs = 48000
t = np.arange(10 * fs) / fs
rng = np.random.default_rng(1)
x = 0.2 * np.sin(2 * np.pi * 50 * t) + 0.01 * rng.standard_normal(t.size)

la = metrology.leq(metrology.weighting_filter(x, fs, curve="A"))
lc = metrology.leq(metrology.weighting_filter(x, fs, curve="C"))
print(f"LAeq = {la:.1f} dB   LCeq = {lc:.1f} dB   C - A = {lc - la:.1f} dB")
# LAeq = 52.4 dB   LCeq = 75.7 dB   C - A = 23.2 dB
# C - A por encima de 20 dB: el número ponderado A ocultaría el retumbo.
```

## 2. Uso básico

```python
import numpy as np
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)

# Aplicar ponderación A a la señal cruda
weighted_signal = metrology.weighting_filter(recording, fs, curve='A')

# Aplicar ponderación C para análisis de picos
c_weighted_signal = metrology.weighting_filter(recording, fs, curve='C')
```

## 3. Infrasonido: ponderación G (ISO 7196)

La **ponderación frecuencial G** (ISO 7196:1995) valora el infrasonido igual que
la ponderación A valora el ruido audible. Se define por una configuración de
polos y ceros con ganancia de 0 dB en 10 Hz, sube a 12 dB/octava entre 1 Hz y
20 Hz (siguiendo el crecimiento abrupto de la percepción en esa banda) y cae a
24 dB/octava fuera de ella. Úsala con fuentes con energía significativa por
debajo de 20 Hz (aerogeneradores, climatización, voladuras):

```python
import numpy as np
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)

g_weighted = metrology.weighting_filter(recording, fs, curve='G')
```

<ThemeImage src="https://raw.githubusercontent.com/jmrplens/phonometry/main/.github/images/g_weighting_response_es.svg" alt="Respuesta en frecuencia de la ponderación G de 0,1 Hz a 1 kHz con los valores nominales de la Tabla 2 de ISO 7196 superpuestos" width="80%" />

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

```python
import matplotlib.pyplot as plt
import numpy as np
from phonometry import metrology

# Medimos la respuesta G: ponderamos un impulso unitario centrado y
# tomamos su espectro. Un búfer largo da la resolución que necesita el
# rango de infrasonido (20 s -> 0,05 Hz).
fs = 4000
impulse = np.zeros(20 * fs)
impulse[impulse.size // 2] = 1.0
freqs = np.fft.rfftfreq(impulse.size, 1 / fs)
spectrum = np.fft.rfft(metrology.weighting_filter(impulse, fs, curve="G"))

fig, ax = plt.subplots(figsize=(9, 5))
ax.semilogx(freqs[1:],
            20 * np.log10(np.abs(spectrum[1:]) + np.finfo(float).eps))
ax.plot(10, 0, "o", color="tab:red", label="0 dB en 10 Hz")
ax.set(xlim=(0.1, 1000), ylim=(-90, 15),
       xlabel="Frecuencia [Hz]", ylabel="Respuesta de la ponderación G [dB]")
ax.grid(True, which="both", alpha=0.3)
ax.legend()
plt.show()
```

</details>

La implementación sigue exactamente los polos/ceros de la Tabla 1 de ISO 7196 y
se verifica en CI contra todos los valores nominales de respuesta de la Tabla 2
(0,25 Hz a 315 Hz). `WeightingFilter(fs, "G")` admite el mismo procesado
multicanal y por bloques que A/C. Los niveles medidos con la curva G se
expresan como L<sub>pG</sub> (o L<sub>Geq</sub> para el nivel equivalente).

## 4. Curvas históricas y de propósito especial: B, D y AU

Tres curvas más completan la familia. Las tres comparten la maquinaria de las
curvas de IEC 61672-1 (0 dB en 1 kHz, sobremuestreo `high_accuracy`,
procesado multicanal y por bloques con estado).

### B (ANSI S1.4-1983, histórica)

La curva intermedia del esquema original de conmutación por niveles A/B/C,
trazada a partir de la isófona de ~70 fonios. Analíticamente es la
ponderación C con un cero más en el origen y un polo real adicional en
$f_5 = 158{,}49\ \text{Hz}$ (Apéndice C de ANSI S1.4-1983), así que descarta
menos graves que A y más que C. Se eliminó cuando IEC 61672-1 sustituyó a las
normas de sonómetros anteriores; úsala solo para reproducir datos históricos
y mediciones tomadas bajo códigos nacionales antiguos (algunos procedimientos
de ensayo de automoción heredados publicaban dB(B)). La implementación sigue
las constantes del Apéndice C de ANSI S1.4-1983 y está anclada en CI a los
valores de respuesta de la Tabla IV, dentro de la máscara más estricta de la
Tabla V (Tipo 0).

### D (IEC 537, retirada: ruido de aeronaves)

La ponderación D aproximaba las curvas de *ruidosidad percibida* del índice
de nivel de ruido percibido (PNL), para que un sonómetro corriente pudiera
estimar el ruido de aeronaves: la joroba de +11,5 dB en torno a 3,15 kHz es
donde más molesta el silbido de la turbomaquinaria (deliberadamente *no* es
un rasgo de igual sonoridad). El manual de métricas de ruido de aeronaves de
la NASA da la clásica regla aproximada $L_{PN} \approx L_D + 7\ \text{dB}$.
IEC 537 fue retirada y la práctica de certificación actual calcula el EPNL a
partir de análisis en tercios de octava o usa niveles ponderados A, así que
`D` se ofrece para datos históricos y comparaciones. Con la norma no
disponible, la implementación usa la función de transferencia racional de
IEC 537, ampliamente publicada, contrastada con dos implementaciones
independientes (los polos y ceros de SQAT y la forma cerrada de librosa, que
coinciden dentro de 0,002 dB) y anclada en CI a la tabla de IEC 537 reeditada
en NASA CR-3406.

```python
import numpy as np
from phonometry import metrology

# Un silbido de 3,15 kHz cae justo en la joroba de la ponderación D:
# D lo valora 10 dB *más fuerte* que A.
fs = 96000
t = np.arange(fs) / fs
whine = 0.1 * np.sin(2 * np.pi * 3150 * t)

ld = metrology.leq(metrology.weighting_filter(whine, fs, curve="D"))
la = metrology.leq(metrology.weighting_filter(whine, fs, curve="A"))
print(f"LD = {ld:.1f} dB   LA = {la:.1f} dB")
# LD = 82.5 dB   LA = 72.2 dB
```

### AU (IEC 61012, vigente: sonido audible en presencia de ultrasonidos)

La única de las tres aún en vigor. `AU` es la ponderación A en cascada con el
filtro paso-bajo **U** de IEC 61012:1990 (seis polos, Tabla 2): plana
respecto a A hasta 10 kHz y con un corte abrupto después (-13 dB a 16 kHz,
-61,8 dB a 40 kHz para U sola). Úsala cuando componentes ultrasónicos
intensos (limpiadores y soldadores ultrasónicos, ahuyentadores de roedores,
algunos disuasorios de espacios públicos) se colarían en una lectura
ponderada A a través del rechazo imperfecto del sonómetro en alta frecuencia
y sobreestimarían la exposición *audible*:

```python
import numpy as np
from phonometry import metrology

# Tono de 1 kHz (audible) enterrado bajo una componente ultrasónica fuerte de 25 kHz.
fs = 96000
t = np.arange(fs) / fs
audible = 0.1 * np.sin(2 * np.pi * 1000 * t)
x = audible + 1.0 * np.sin(2 * np.pi * 25000 * t)

la = metrology.leq(metrology.weighting_filter(x, fs, curve="A"))
lau = metrology.leq(metrology.weighting_filter(x, fs, curve="AU"))
la_ref = metrology.leq(metrology.weighting_filter(audible, fs, curve="A"))
print(f"LA = {la:.1f} dB   LAU = {lau:.1f} dB   solo audible = {la_ref:.1f} dB")
# LA = 78.6 dB   LAU = 71.0 dB   solo audible = 71.0 dB
# El ultrasonido infla LA en 7,6 dB; AU recupera el nivel audible.
```

El ultrasonido solo llega a un filtro digital si la frecuencia de muestreo lo
captura, así que mide a 96 kHz o más (a 48 kHz no hay nada por encima de
24 kHz que rechazar); el diseño AU sobremuestrea internamente hacia 288 kHz
para mantener preciso el corte abrupto de U. Los niveles se expresan como
L<sub>AU</sub>. La implementación sigue exactamente las posiciones de polos
de la Tabla 2 (reproducen todos los valores nominales de la Tabla 1 dentro
de 0,05 dB) y se verifica en CI contra las tolerancias de la Tabla 1 hasta
40 kHz.

## 5. Parámetros de `weighting_filter()` / `WeightingFilter`

| Parámetro | Tipo | Unidades | Rango / por defecto | Notas |
| :--- | :--- | :--- | :--- | :--- |
| `x` | array 1D o 2D | cualquiera | no vacío | 2D es `[channels, samples]` |
| `fs` | int | Hz | > 0 | |
| `curve` | str | — | `'A'` (por defecto), `'B'`, `'C'`, `'D'`, `'G'`, `'AU'`, `'Z'` | `'G'` según ISO 7196 (infrasonido); `'B'`/`'D'` históricas (§4); `'AU'` según IEC 61012 (§4); `'Z'` es un bypass |
| `high_accuracy` | bool | — | por defecto `True` (función); en la clase, `None` se resuelve a `not stateful` | Sobremuestreo interno que mantiene A/C en clase 1 hasta 16 kHz; detalles en el §7 |
| `stateful` | bool (solo clase) | — | por defecto `False` | Conserva el estado del filtro entre bloques (streaming) |
| `steady_ic` | bool (solo clase) | — | por defecto `False` | Condiciones iniciales estacionarias (sin transitorio de arranque) |

## 6. Objeto de filtro reutilizable

Si ponderas muchas señales con los mismos parámetros, diseña el filtro una sola vez:

```python
import numpy as np
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)

wf = metrology.WeightingFilter(fs, "A")
signals = [recording]                # tu lote de grabaciones
for recording in signals:
    weighted = wf.filter(recording)
```

## 7. Precisión en alta frecuencia (`high_accuracy`)

Un diseño con transformación bilineal simple comprime la respuesta cerca de
Nyquist: a fs = 48 kHz el error de la curva A a 12,5 kHz alcanza −2,7 dB, fuera
de la tolerancia **clase 1** de IEC 61672-1 (+2,0/−2,5 dB).

Por defecto (`high_accuracy=True`), phonometry diseña y ejecuta el filtro de
ponderación a una frecuencia interna sobremuestreada (hasta 8×, alcanzando
≥ 144 kHz a frecuencias de audio habituales; una entrada de 96 kHz funciona
a ×2) y diezma de vuelta, manteniendo la respuesta dentro de las tolerancias
de clase 1 hasta 16 kHz (error ≈ −0,5 dB a 12,5 kHz para fs = 48 kHz).

<ThemeImage src="https://raw.githubusercontent.com/jmrplens/phonometry/main/.github/images/weighting_accuracy_hf_es.svg" alt="Precisión en alta frecuencia de la ponderación A a 48 kHz: curva analítica frente a bilineal simple y diseño sobremuestreado, con error" width="80%" />

*El diseño bilineal simple (rojo) cruza la tolerancia de clase 1 cerca de
12,5 kHz; el diseño sobremuestreado (azul) se mantiene junto a la curva analítica.*

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

```python
import matplotlib.pyplot as plt
import numpy as np
from phonometry import metrology

# Respuesta medida de ambos diseños a fs = 48 kHz: ponderamos un impulso
# unitario centrado y tomamos su espectro...
fs = 48000
impulse = np.zeros(fs)
impulse[fs // 2] = 1.0
freqs = np.fft.rfftfreq(fs, 1 / fs)[1:]

# ...frente a la curva A analítica de IEC 61672-1 construida con las
# cuatro frecuencias de esquina de la sección 1, normalizada a 0 dB en 1 kHz.
f1, f2, f3, f4 = 20.599, 107.653, 737.862, 12194.217
gain = (f4**2 * freqs**4) / ((freqs**2 + f1**2)
        * np.sqrt((freqs**2 + f2**2) * (freqs**2 + f3**2))
        * (freqs**2 + f4**2))
analytic = 20 * np.log10(gain / gain[np.argmin(np.abs(freqs - 1000))])

fig, ax = plt.subplots(figsize=(9, 5))
ax.semilogx(freqs, analytic, "k--", label="Analítica (IEC 61672-1)")
for high_accuracy, label in ((False, "Bilineal simple"),
                             (True, "Sobremuestreado (por defecto)")):
    weighted = metrology.weighting_filter(impulse, fs, curve="A",
                                high_accuracy=high_accuracy)
    response = 20 * np.log10(np.abs(np.fft.rfft(weighted))
                             + np.finfo(float).eps)[1:]
    ax.semilogx(freqs, response, label=label)
ax.set(xlim=(1000, 20000), ylim=(-12, 3),
       xlabel="Frecuencia [Hz]", ylabel="Respuesta de la ponderación A [dB]")
ax.grid(True, which="both", alpha=0.3)
ax.legend()
plt.show()
```

</details>

- `high_accuracy=False` restaura el comportamiento bilineal clásico.
- Con `'G'` el indicador se ignora en silencio: su rango de 0,25–315 Hz ya es
  exacto con el diseño simple.
- El **procesado por bloques (stateful)** usa siempre el diseño clásico: el
  remuestreo FIR interno es incompatible con la continuidad entre bloques. Pasar
  `high_accuracy=True` junto con `stateful=True` lanza un `ValueError`.

```python
import numpy as np
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)

# Comportamiento clásico explícito
y = metrology.weighting_filter(recording, fs, curve="A", high_accuracy=False)

# Procesado por bloques con estado (diseño clásico, estado entre bloques)
wf = metrology.WeightingFilter(fs, "A", stateful=True)
blocks = [recording]                 # tu secuencia de bloques de señal
for block in blocks:
    weighted = wf.filter(block)
```

Consulta [Procesado por bloques](/phonometry/es/guides/block-processing/) para
el flujo en streaming y [Teoría](/phonometry/es/reference/theory/signal-analysis/) para las
definiciones analíticas de las curvas.

## 8. Verificación frente a las tablas de tolerancias (IEC 61672-1, ANSI S1.4, IEC 61012)

`verify_weighting_class` comprueba un filtro de ponderación frente a los
límites de aceptación de **IEC 61672-1:2013** (Tabla 3). Evalúa la respuesta
relativa del filtro en la frecuencia *exacta* en base 10 que hay detrás de
cada etiqueta nominal por debajo de Nyquist (los objetivos de diseño de la
Tabla 3 se calculan en $f = 1000 \cdot 10^{n/10}$, p. ej. 15 848,9 Hz para
«16 kHz»; la IEC 61672-3 ensaya en esas mismas frecuencias), resta la
ponderación objetivo de diseño e informa de la clase de prestaciones por
frecuencia con su margen en dB. Un barrido logarítmico denso impone además el
apartado 5.5.7 *entre* las frecuencias nominales (la desviación respecto al
objetivo analítico del anexo E debe mantenerse dentro del mayor de los dos
límites adyacentes, de modo que una resonancia o un notch entre nominales no
puede pasar) y, cuando filas de la Tabla 3 con límite inferior finito quedan
por encima de Nyquist, el veredicto se marca `range_limited` (atestigua solo
las frecuencias comprobadas, no la conformidad completa de 10 Hz a 20 kHz):

```python
from phonometry import metrology

result = metrology.verify_weighting_class(metrology.WeightingFilter(48000, "A"))
print(result["overall_class"])          # 1
print(result["range_limited"])          # False
print(result["between_nominals"])       # {'worst_freq': ..., 'margin_class1_db': ...}
print(result["bands"][20])
# {'freq': 1000.0, 'class': 1, 'deviation_db': 0.0, 'margin_class1_db': 0.7, 'margin_class2_db': 1.0}
```

La máscara de aceptación de la Tabla 3 también es pública:
`weighting_class_limits(1)` devuelve las 34 frecuencias nominales con los
límites de desviación inferior/superior (un límite inferior de `-inf` significa
que solo se aplica el superior). Los límites cualifican la *desviación* respecto
al objetivo de diseño, por lo que son idénticos para A, C y Z.

El mismo verificador cubre las curvas de la sección 4 que tienen tablas de
tolerancias publicadas. Para `B` usa ANSI S1.4-1983 (objetivos de diseño de
la Tabla IV, límites de la Tabla V) y los veredictos de «clase» se leen como
los **Tipos** de instrumento 1 y 2 de la norma. Para `AU` usa la Tabla 1 de
IEC 61012:1990 (A nominal + U nominal con las tolerancias de filtro como
unidad separada, cero en la referencia de 1 kHz); IEC 61012 publica un único
juego de tolerancias, así que ambos márgenes coinciden y el veredicto es
simplemente conforme (1) o no (`None`) — ten en cuenta que comprobar las
filas por encima de 20 kHz requiere `fs` ≥ 96 kHz (por debajo se descartan y
el veredicto queda `range_limited`). `G` y `D` se rechazan: ISO 7196 define
una única tolerancia de ±1 dB sin estructura de clases y la retirada IEC 537
no dejó tabla de tolerancias (ambas curvas se anclan numéricamente en el
informe de conformidad de CI).

<ThemeImage src="https://raw.githubusercontent.com/jmrplens/phonometry/main/.github/images/weighting_class_mask_es.svg" alt="Desviaciones de las ponderaciones A y C a 48 kHz dentro del corredor de aceptación de clase 1 de la Tabla 3 de IEC 61672-1, con los límites más amplios de clase 2 punteados" width="80%" />

*Los diseños sobremuestreados A y C (azul, morado) se mantienen cerca de
desviación cero, holgadamente dentro del corredor de clase 1 (sombreado); los
límites más amplios de clase 2 se muestran punteados. El corredor se ensancha
en los extremos de banda donde solo se aplica un límite unilateral.*

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

```python
import matplotlib.pyplot as plt
import numpy as np
from phonometry import metrology

freqs, lower1, upper1 = metrology.weighting_class_limits(1)
_, lower2, upper2 = metrology.weighting_class_limits(2)
lo1, lo2 = np.clip(lower1, -7, 7), np.clip(lower2, -7, 7)

fig, ax = plt.subplots(figsize=(10, 6.5))
ax.fill_between(freqs, lo1, upper1, step="mid", alpha=0.10,
                label="Región de aceptación de clase 1")
ax.plot(freqs, upper1, drawstyle="steps-mid", label="Límite superior/inferior de clase 1")
ax.plot(freqs, lo1, drawstyle="steps-mid", color="C1")
ax.plot(freqs, upper2, ":", drawstyle="steps-mid", label="Límite superior/inferior de clase 2")
ax.plot(freqs, lo2, ":", drawstyle="steps-mid", color="C2")

for curve, marker in (("A", "o"), ("C", "s")):
    bands = metrology.verify_weighting_class(metrology.WeightingFilter(48000, curve))["bands"]
    f = [b["freq"] for b in bands]
    dev = [b["deviation_db"] for b in bands]
    ax.plot(f, dev, marker=marker, label=f"Desviación de la ponderación {curve} (48 kHz)")

ax.set(xscale="log", xlim=(10, 20000), ylim=(-7, 7),
       xlabel="Frecuencia [Hz]", ylabel="Desviación respecto al objetivo de diseño [dB]")
ax.legend(fontsize=8, ncol=2)
plt.show()
```

</details>

## Véase también

- Referencia de la API: [`metrology.parametric_filters`](/phonometry/es/reference/api/filters/parametric-filters/) y [`metrology.compliance`](/phonometry/es/reference/api/filters/compliance/).
