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

Cómo devuelve una superficie el sonido incidente (cuánto dispersa fuera de la
dirección especular, con qué uniformidad reparte lo que dispersa y cuánto
absorbe) se mide con una familia de métodos dedicados. La **cámara reverberante**
proporciona el *coeficiente de dispersión* de incidencia aleatoria de una
superficie comparando las caídas con la muestra inmóvil y en rotación
(ISO 17497-1). Un **goniómetro en campo libre** mide la respuesta polar del
sonido reflejado y la condensa en un *coeficiente de difusión* (ISO 17497-2). Y
sobre un pavimento, un altavoz y un solo micrófono recuperan la *absorción in
situ* del firme, ya sea sobre una superficie extensa restando la onda incidente
(ISO 13472-1) o a través de un pequeño tubo apoyado sobre la superficie
(ISO 13472-2). Esta página cubre los cuatro.

Los coeficientes de dispersión y de difusión responden a preguntas distintas y no
son intercambiables: la dispersión es *cuánta* energía abandona la dirección
especular; la difusión es *cuán uniformemente* se reparte en ángulo la energía
reflejada.

## 1. Coeficiente de dispersión de incidencia aleatoria (ISO 17497-1)

El coeficiente de dispersión $s$ es la fracción de energía reflejada que **no**
abandona la superficie en la dirección especular. ISO 17497-1 lo mide en una cámara
reverberante a partir de cuatro situaciones de tiempo de reverberación: con la
muestra de ensayo montada sobre una plataforma giratoria y mantenida
**inmóvil**, y con la plataforma **en rotación** (que promedia y elimina la
reflexión especular coherente en fase), cada una con y sin una placa base
reflectante.

**Absorción a partir del tiempo de reverberación (cláusula 6).** Cada situación se
convierte en un coeficiente de absorción de Sabine con el propio término de
atenuación del aire de la norma:

$$
\alpha = 55{,}3\,\frac{V}{S}\left(\frac{1}{c_2 T_2} - \frac{1}{c_1 T_1}\right)
        - 4\,\frac{V}{S}\,(m_2 - m_1),
$$

donde $V$ es el volumen de la sala, $S$ el área de la muestra, $T$ el tiempo de
reverberación, $c$ la velocidad del sonido (ec. (2): $c = 343{,}2\sqrt{(273{,}15+t)/293{,}15}$)
y $m$ el coeficiente de atenuación en potencia del aire. El par **inmóvil** da la
absorción de incidencia aleatoria $\alpha_s$ (ec. (1)); el par **en rotación** da
la absorción especular $\alpha_{spec}$ (ec. (4)).

**Coeficiente de dispersión (ec. (5)).** Ambos se combinan en

$$
s = \frac{\alpha_{spec} - \alpha_s}{1 - \alpha_s}.
$$

Una superficie totalmente especular refleja toda su energía no absorbida en la
dirección especular, de modo que $\alpha_{spec} = \alpha_s$ y $s = 0$; un difusor
fuerte envía energía en todas direcciones, elevando $\alpha_{spec}$ hacia 1 y $s$
hacia 1.

```python
from phonometry import materials

# Cuatro situaciones de tiempo de reverberación reducidas a dos coeficientes de absorción.
# alpha_s del par inmóvil (ec. 1); alpha_spec del par en rotación (ec. 4).
# V = 200 m^3, S = 10 m^2, c = 343.2 m/s en todo momento.
alpha_s = materials.random_incidence_absorption(200.0, 10.0, c1=343.2, T1=8.0,
                                         c2=343.2, T2=6.0)
alpha_spec = materials.specular_absorption_coefficient(200.0, 10.0, c3=343.2, T3=7.5,
                                                c4=343.2, T4=5.0)
s = materials.scattering_coefficient(alpha_spec, alpha_s)   # ec. (5)
print(round(float(alpha_s), 4))     # 0.1343
print(round(float(alpha_spec), 4))  # 0.2148
print(round(float(s), 4))           # 0.0931
```

Sobre una medición completa en tercios de octava, `scattering_coefficient_spectrum`
empareja los $\alpha_{spec}$ y $\alpha_s$ por banda con sus centros de banda y
devuelve un `ScatteringResult` representable:

```python

from phonometry import materials

# Una medición de 13 bandas (250-4000 Hz): la absorción de incidencia aleatoria
# alpha_s (muestra inmóvil) y la absorción especular alpha_spec (plataforma en
# rotación). Un difusor dispersa más con la frecuencia, así que s(f) crece.
freqs = np.array([250, 315, 400, 500, 630, 800, 1000,
                  1250, 1600, 2000, 2500, 3150, 4000], float)
alpha_s = np.full_like(freqs, 0.10)
alpha_spec = 0.11 + 0.75 * (np.log10(freqs / 250) / np.log10(4000 / 250))

result = materials.scattering_coefficient_spectrum(freqs, alpha_spec, alpha_s)
print(np.round(result.scattering[[0, 6, 12]], 3))   # [0.011 0.428 0.844]
result.plot()   # s(f) en eje de frecuencia logarítmico, de 0 a 1 (requiere matplotlib)
```

*El coeficiente de dispersión asciende con la frecuencia: a baja frecuencia el
relieve de la superficie es pequeño frente a la longitud de onda y la reflexión
permanece especular ($s \to 0$); al acortarse la longitud de onda el relieve
dispersa más energía fuera de la dirección especular ($s \to 1$).*

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

```python

from phonometry import materials

# Una medición de 13 bandas (250-4000 Hz): la absorción de incidencia aleatoria
# alpha_s (muestra inmóvil) y la absorción especular alpha_spec (plataforma en
# rotación). Un difusor dispersa más con la frecuencia, así que s(f) crece.
freqs = np.array([250, 315, 400, 500, 630, 800, 1000,
                  1250, 1600, 2000, 2500, 3150, 4000], float)
alpha_s = np.full_like(freqs, 0.10)
alpha_spec = 0.11 + 0.75 * (np.log10(freqs / 250) / np.log10(4000 / 250))
result = materials.scattering_coefficient_spectrum(freqs, alpha_spec, alpha_s)

# result es el ScatteringResult calculado arriba. En una línea:
result.plot(language="es")
plt.show()

# A mano, a partir de los campos del resultado, replicando lo que dibuja ScatteringResult.plot():
fig, ax = plt.subplots()
ax.semilogx(result.frequencies, result.scattering, "o-", color="#1f77b4")
ax.set_xlabel("Frecuencia [Hz]")
ax.set_ylabel("Coeficiente de dispersión s")
ax.set_ylim(0.0, 1.0)
ax.set_title("Coeficiente de dispersión de incidencia aleatoria (ISO 17497-1)")
plt.show()
```

</details>

**Comprobación de la placa base (cláusula 6.4, Tabla 1).** La placa base vacía
debe dispersar por sí sola de forma despreciable, o sesgaría el resultado.
ISO 17497-1 limita el coeficiente de dispersión de la placa base por banda de
tercio de octava; la librería expone esos límites y un comprobador.

```python
from phonometry import materials

# Los techos normativos por banda (Tabla 1): 0.05 hasta 500 Hz, ascendiendo a 0.25.
# materials.BASE_PLATE_BANDS es la tupla de bandas; materials.BASE_PLATE_MAX_SCATTERING asigna banda -> techo.
print(materials.BASE_PLATE_BANDS[0], materials.BASE_PLATE_MAX_SCATTERING[100])   # 100 0.05

# Una placa base cuya dispersión medida se mantiene bajo el techo pasa en silencio;
# una banda que lo supera lanza un ScatteringDiffusionWarning que lista las infractoras.
materials.check_base_plate_scattering([0.02] * len(materials.BASE_PLATE_BANDS))
```

### Ficha de informe de ensayo de dispersión

`ScatteringResult.report(path)` genera un informe de ensayo de dispersión
acreditado de una página (ISO 17497-1): una cabecera de metadatos (probeta, área
de muestra $S$, volumen de sala $V$, sala de ensayo, clima), la tabla por tercio
de octava de la absorción de incidencia aleatoria $\alpha_s$ y el coeficiente de
dispersión $s$ junto a la curva $s(f)$ sobre un eje de bandas categórico, y un
titular de caracterización enmarcado. Es una caracterización, por lo que no hay
veredicto de apto/no apto. `verbose=True` añade la columna de absorción especular
$\alpha_{spec}$ y `language="es"` genera la ficha en español. Requiere el extra de
informes (`pip install phonometry[report]`).

## 2. Coeficiente de difusión (ISO 17497-2)

El coeficiente de difusión $d$ mide la **uniformidad espacial** del sonido
reflejado, no cuánto se dispersa. Un goniómetro barre un receptor sobre un arco
polar y registra el nivel reflejado $L_i$ en cada ángulo; el coeficiente es la
autocorrelación normalizada de la distribución de energía polar.

**Autocorrelación (fórmula (5)).** Para $n$ receptores con espaciado angular
igual, con $p_i = 10^{L_i/10}$ la energía de banda en el receptor $i$,

$$
d = \frac{\left(\sum_i p_i\right)^2 - \sum_i p_i^2}
         {(n-1)\,\sum_i p_i^2}.
$$

Una respuesta polar perfectamente uniforme ($L_i$ todos iguales) da $d = 1$; un
único lóbulo especular agudo da $d = 0$. Cuando los receptores subtienden ángulos
sólidos desiguales, la fórmula (6) pondera por área cada energía con $N_i$ de la
fórmula (8), y esos factores de área se evalúan en **radianes**, razón por la que
un espaciado de 5° en el cenit produce un peso cercano a 1,57, no a 51,9.

La animación siguiente ejecuta ese experimento de goniómetro numéricamente: el
mismo frente de onda plano incide sobre un panel rígido plano y sobre un
difusor de Schroeder (un perfil de residuos cuadráticos con N = 7), y la
energía dispersada sobre el arco de receptores convierte un haz especular
colimado (d = 0,32) en un abanico ancho (d = 0,63).

La respuesta de un solo plano de abajo es la predicción en campo lejano de una
geometría de difusor publicada: un difusor de residuos cuadráticos $N = 7$ de
6 periodos, 3,6 m de anchura total y 0,2 m de profundidad máxima de pozo (la
fila "N = 7 QRD, 6 periods, 0.2 m deep" de Cox & D'Antonio, *Acoustic
Absorbers and Diffusers*, 3.ª ed., Apéndice B; el QRD comercial N = 7 medido
por Hargreaves, Cox, Lam & D'Antonio, *J. Acoust. Soc. Am.* 108(4), 1710-1720,
2000, Tabla I) y su panel de referencia plano de igual huella, a 1000 Hz,
incidencia normal, en el semicírculo estándar de 37 puntos (espaciado de 5°,
de $-90°$ a $+90°$). Los mismos niveles del modelo alimentan el conjunto de
conformidad de phonometry como oráculo aritmético de las Fórmulas (5) y (7);
el anclaje externo de terceros compara la difusión normalizada del modelo
promediada por banda con la tabla BEM publicada del Apéndice B en las bandas
de 200-400 Hz (acuerdo dentro de 0,01; en todo el rango publicado de
100-5000 Hz la desviación absoluta media modelo-BEM ronda 0,09, porque la
difracción de borde queda fuera del modelo de Fraunhofer).

La propia superficie merece dibujarse antes de predecir nada con ella.
`plot_qrd_geometry` convierte la secuencia de profundidades en el perfil de
pozos a escala de abajo, y una `DiffuserPolarResponse` predicha retiene su
geometría, así que `qrd.plot_geometry()` dibuja la superficie para la que se
calculó.

*Dos de los seis periodos, a escala: los residuos cuadráticos $n^2 \bmod 7$
convertidos en una superficie construible. La frecuencia de diseño de
490 Hz es la que deja el pozo más profundo exactamente en 200 mm.*

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

```python

from phonometry import materials

# El QRD N = 7 publicado: ancho de pozo 3,6 m / 42, pozo más profundo 0,2 m.
depths = materials.qrd_well_depths(7, 490.0, speed_of_sound=343.0)
pitch = 3.6 / 42                  # 42 pozos a lo ancho del panel de 3,6 m
fin = 0.005                       # aletas finas, incluidas en el paso
materials.plot_qrd_geometry(depths, pitch - fin, fin_width=fin, periods=2,
                            language="es")
plt.show()

# Una DiffuserPolarResponse predicha retiene su geometría, así que
# qrd.plot_geometry() dibuja el perfil para el que se calculó (los 6 periodos).
```

</details>

```python
from phonometry import materials

# La geometría publicada: QRD N = 7, 6 periodos, 3,6 m de ancho, 0,2 m de
# profundidad (Cox & D'Antonio 3.ª ed., Apéndice B; Hargreaves et al. 2000,
# Tabla I). La frecuencia de diseño de 490 Hz deja el pozo más profundo en
# exactamente 0,2 m.
depths = materials.qrd_well_depths(7, 490.0)   # [0, 0.05, 0.2, 0.1, ...] m
qrd = materials.predict_diffuser_polar_response(
    3.6 / 42, 1000.0, depths=depths, periods=6)
# El panel de referencia plano: la misma huella de 3,6 m con pozos a cero.
flat = materials.predict_diffuser_polar_response(
    3.6 / 42, 1000.0, depths=[0.0] * 7, periods=6)

qrd.plot()   # respuesta polar predicha, d en el título (requiere matplotlib)

d = materials.directional_diffusion_coefficient(qrd.levels)    # fórmula (5)
print(round(float(d), 4))            # 0.1099
d_ref = materials.directional_diffusion_coefficient(flat.levels)
print(round(float(d_ref), 4))        # 0.0049

# Normaliza frente a la referencia plana para aislar el efecto propio del
# difusor (fórmula (7)): d_n = (d - d_ref) / (1 - d_ref).
d_n = materials.normalized_diffusion_coefficient(d, d_ref)
print(round(float(d_n), 4))          # 0.1055

# Valor de incidencia aleatoria: promedia los coeficientes de banda sobre las
# posiciones de fuente, con la ponderación 2-D de la norma (0 grados -> 1,
# +/-30/+/-60 grados -> 3).
d_random = materials.random_incidence_diffusion(
    [0.5, 0.2, 0.2, 0.2, 0.2], weights=materials.TWO_DIMENSIONAL_SOURCE_WEIGHTS)
print(round(float(d_random), 4))     # 0.2231
```

`directional_diffusion` mantiene los ángulos de los receptores junto a los
niveles de un barrido completo de goniómetro y devuelve un `DiffusionResult`
representable. Reutilizando los niveles polares del QRD de arriba:

```python

from phonometry import materials

# qrd.levels: los 37 niveles predichos del QRD del ejemplo de arriba.
angles = np.arange(-90.0, 90.5, 5.0)

result = materials.directional_diffusion(angles, qrd.levels)
print(round(result.coefficient, 2))   # 0.11
result.plot()   # respuesta polar reflejada, d en el título (requiere matplotlib)
```

*La matriz periódica de QRD divide la energía reflejada en un abanico de
lóbulos de red discretos en lugar de un único pico especular, pero seis
repeticiones del mismo periodo concentran la energía en esas pocas
direcciones, así que el coeficiente de difusión por autocorrelación se queda
en un valor modesto ($d \approx 0{,}11$). El panel de referencia plano colapsa
solo en la dirección especular y baja a $d \approx 0{,}005$; esta penalización
por lóbulos de las matrices periódicas es justo el motivo por el que
Cox & D'Antonio recomiendan disposiciones moduladas.*

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

```python

from phonometry import materials

# qrd.levels: los 37 niveles predichos L_i del QRD N = 7 de seis periodos del
# ejemplo de arriba (modelo de campo lejano de Fraunhofer, geometría publicada
# del Apéndice B de Cox & D'Antonio, 1000 Hz, incidencia normal) en el
# semicírculo de -90 a 90 grados con espaciado de 5 grados. La matriz
# periódica concentra la energía en lóbulos de red, así que el coeficiente d
# de la fórmula (5) es modesto.
angles = np.arange(-90.0, 90.5, 5.0)
result = materials.directional_diffusion(angles, qrd.levels)

# result es el DiffusionResult calculado arriba. En una línea:
result.plot(language="es")
plt.show()

# A mano: un diagrama polar de los niveles, con d anotado en el título.
fig, ax = plt.subplots(subplot_kw={"projection": "polar"})
theta = np.radians(result.angles)
ax.plot(theta, result.levels, "o-", color="#1f77b4")
ax.fill(theta, result.levels, color="#1f77b4", alpha=0.15)
ax.set_theta_zero_location("N")
ax.set_theta_direction(-1)
ax.set_thetamin(-90)
ax.set_thetamax(90)
ax.set_title(f"Difusión direccional  d = {result.coefficient:.2f}  (ISO 17497-2)")
plt.show()
```

</details>

### Ficha de informe de ensayo de difusión

Reunido a lo largo de las bandas de tercio de octava, el coeficiente de difusión
$d(f)$ forma un `DiffusionSpectrum`, cuyo `report(path)` genera un informe de
ensayo de difusión de una página (ISO 17497-2, Cláusula 8.5): la tabla por banda
de $d$ junto a la curva $d(f)$ con eje de bandas, con un titular de
caracterización enmarcado. Según la Cláusula 8.4, el coeficiente de incidencia
aleatoria es a su vez una magnitud por banda, la media de los coeficientes
direccionales sobre las posiciones de fuente banda a banda (**no** una media a
través de las frecuencias), de modo que aquí $d$ es un coeficiente por banda.
`verbose=True` añade la columna del coeficiente normalizado $d_n$ a la tabla (la
curva siempre dibuja $d_n$ como acompañante cuando está presente).

```python

from phonometry import materials

# Un coeficiente de difusión por banda (aquí un ejemplo en forma cerrada). En la
# práctica, la d de incidencia aleatoria de cada banda es la media, sobre las
# posiciones de fuente, de los coeficientes direccionales: para la banda k, se
# promedia directional_diffusion_coefficient sobre las fuentes con
# random_incidence_diffusion (Cláusula 8.4).
freqs = np.array([250, 500, 1000, 2000, 4000], float)
d = np.array([0.30, 0.45, 0.60, 0.75, 0.88])
spectrum = materials.diffusion_spectrum(freqs, d)
spectrum.plot()    # d(f) en el eje de bandas (requiere matplotlib)
spectrum.report("difusion.pdf")   # ficha de una página (requiere phonometry[report])
```

La respuesta polar de una sola banda también es informable: `DiffusionResult.report(path)`
genera la tabla de ángulo de recepción / nivel reflejado corregido junto al
diagrama polar semicircular, enmarcando el coeficiente de difusión direccional de
esa banda.

### Predicción de la difusión a partir del diseño de un difusor

El coeficiente de autocorrelación anterior reduce una respuesta polar *medida*.
El mismo coeficiente puede *predecirse* a partir del diseño físico de un difusor
de rejilla de fase de Schroeder, de modo que una secuencia de profundidades de
pozo pueda evaluarse antes de fabricar una muestra.
`predict_diffuser_polar_response` evalúa el modelo de Fraunhofer (campo lejano)
de plano único de Cox y D'Antonio: cada pozo de fondo rígido y profundidad $d_n$
aporta un coeficiente de reflexión de presión $R_n = e^{-2 j k d_n}$, y la
presión dispersada al ángulo de reflexión $\theta$ para una fuente con incidencia
$\psi$ es la suma sobre los pozos de la superficie periódica (Ec. (5.8)),

$$
p(\theta) = F(\theta) \sum_n R_n \, e^{\,j k x_n (\sin\psi + \sin\theta)},
$$

con $x_n$ el centro del pozo y $k = 2\pi f / c$. Los niveles polares predichos
$L_i = 20\lg|p(\theta_i)|$ alimentan el mismo `directional_diffusion_coefficient`
que una medición. Para un difusor de residuo cuadrático la secuencia de
profundidades se obtiene del generador primo $N$ y la frecuencia de diseño $f_0$
(Ecs. (10.2)/(10.3)): $s_n = n^2 \bmod N$ y $d_n = s_n \lambda_0 / (2N)$ con
$\lambda_0 = c/f_0$.

```python

from phonometry import materials

# Un difusor de residuo cuadratico N = 7, frecuencia de diseno 500 Hz.
depths = materials.qrd_well_depths(7, 500.0)   # Ecs. (10.2)/(10.3)
print(np.round(depths * 100, 1))               # profundidades de pozo en cm:
                                               # [ 0.   4.9 19.6  9.8  9.8 19.6  4.9]

# Respuesta polar de campo lejano predicha a una frecuencia (5 periodos
# repetidos, pozos de 10 cm), reducida al coeficiente de difusion direccional
# ISO 17497-2.
surface = materials.predict_diffuser_polar_response(0.10, 2000.0, depths=depths,
                                                    periods=5)
print(round(surface.coefficient, 3))           # 0.210
surface.plot()   # respuesta polar predicha, d en el titulo (requiere matplotlib)

# La variante de espectro normaliza banda a banda frente a la referencia plana
# de la misma huella (Formula (7)): el panel plano se aplica a cero exacto y el
# QRD queda muy por encima.
freqs = np.array([500, 1000, 2000, 4000], float)
qrd = materials.predicted_diffusion_spectrum(0.10, freqs, depths=depths, periods=5)
print(np.round(qrd.normalized, 3))             # [0.352 0.275 0.208 0.073]

flat = materials.predicted_diffusion_spectrum(0.10, freqs,
                                        depths=np.zeros_like(depths), periods=5)
print(np.round(flat.normalized, 3))            # [0. 0. 0. 0.]
```

*Predicho solo a partir del diseño: el QRD N = 7 reparte la energía reflejada
mucho más uniformemente que el panel plano de la misma huella, de modo que su
coeficiente de difusión predicho queda muy por encima de la referencia plana
casi especular en toda la banda. Se trata de una estimación de diseño en campo
lejano, no un sustituto de una medición ISO 17497-2; como todo modelo de Fourier
de difusores pierde precisión a baja frecuencia, en ángulos rasantes y para
superficies muy absorbentes. Se puede pasar una secuencia arbitraria de
coeficientes de reflexión complejos por pozo mediante el argumento `reflection`,
de modo que una superficie de admitancia o cargada con resonadores calculada en
otro lugar pueda evaluarse igual.*

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

```python

from phonometry import materials

# QRD N = 7 (frecuencia de diseno 500 Hz, pozos de 10 cm, cinco periodos) frente
# al panel plano de la misma huella, sobre las bandas de tercio de octava.
freqs = np.array([250, 315, 400, 500, 630, 800, 1000, 1250, 1600,
                  2000, 2500, 3150, 4000, 5000], float)
depths = materials.qrd_well_depths(7, 500.0)
qrd = materials.predicted_diffusion_spectrum(0.10, freqs, depths=depths, periods=5)

# El DiffusionSpectrum dibuja la d(f) predicha directamente. Una linea:
qrd.plot(language="es")
plt.show()

# A mano: d(f) predicha para el QRD frente a la referencia plana.
flat = materials.predicted_diffusion_spectrum(0.10, freqs,
                                depths=np.zeros_like(depths), periods=5,
                                normalize=False)
fig, ax = plt.subplots()
ax.semilogx(freqs, qrd.diffusion, "o-", color="#1f77b4", label="Diseno QRD N = 7")
ax.semilogx(freqs, flat.diffusion, "s--", color="#d62728", label="Panel plano")
ax.set_ylim(0.0, 1.0)
ax.set_xlabel("Frecuencia [Hz]")
ax.set_ylabel("Coeficiente de difusion predicho d")
ax.legend()
plt.show()
```

</details>

## ¿Dispersión o difusión? Dos coeficientes, dos trabajos

Los dos coeficientes anteriores se tratan de forma rutinaria como
intercambiables, en fichas de producto y a veces en manuales de simulación. No
lo son, y ninguno puede calcularse a partir del otro. El coeficiente de
dispersión $s$ (ISO 17497-1) hace **contabilidad de energía**: qué fracción de
la energía reflejada abandona la dirección especular. No dice nada sobre a
dónde va esa energía. El coeficiente de difusión $d$ (ISO 17497-2) califica la
**calidad espacial**: cuán uniformemente cubre la energía reflejada el arco de
receptores, para una dirección de fuente cada vez. No dice nada sobre cómo se
reparte la energía entre el lóbulo especular y el resto.

Un par de contraejemplos los mantiene separados. Un elemento curvo o inclinado
que *redirige* la reflexión concentra casi toda la energía reflejada en un
lóbulo intenso alejado de la dirección especular: casi todo es no especular,
así que $s$ es alto, pero el haz queda tan colimado como el de un espejo, así
que $d$ se mantiene bajo. A la inversa, un panel plano pequeño medido a baja
frecuencia envía casi toda la energía reflejada hacia la dirección especular,
así que $s$ se queda cerca de cero, y sin embargo la difracción de borde
reparte esa reflexión tan ampliamente sobre el arco de receptores que el $d$
medido sale sorprendentemente alto. Un $s$ alto no significa uniforme; un $d$
decente no significa que se dispersara mucha energía.

**Cuál usar en diseño.** Los dos números sirven a consumidores distintos:

- **El coeficiente de dispersión alimenta la simulación de salas.** Los
  motores de acústica geométrica deciden en cada reflexión de pared cuánta
  energía continúa especularmente y cuánta se redistribuye; el $s$ de
  incidencia aleatoria por banda de cada superficie es precisamente ese
  reparto, que es lo que ISO 17497-1 se redactó para suministrar. Equivocarlo
  se traduce en predicciones erróneas de tiempo de reverberación y claridad
  en salas no mezcladoras.
- **El coeficiente de difusión califica difusores.** Cuando la tarea es
  deshacer un eco, un flutter o una reflexión focalizada, lo que importa es
  que la energía reflejada se reparta en ángulo, y $d$ mide exactamente eso.
  El $d_n$ normalizado (fórmula (7)) resta además la difracción de borde que
  exhibe todo panel finito, de modo que productos de tamaños distintos puedan
  compararse con justicia.

Intercambiarlos falla en ambos sentidos: un coeficiente de difusión metido en
la casilla de dispersión de un simulador sesga el reparto de energía, y un
coeficiente de dispersión citado como prueba de "difusión" puede describir una
superficie que simplemente redirige la reflexión problemática a otro sitio.
Ambos coeficientes son funciones por banda de tercio de octava que en general
crecen cuando el relieve de la superficie deja de ser pequeño frente a la
longitud de onda; un número único ciego a la frecuencia ("dispersa el 90 % del
sonido") no es ninguno de los dos.

## 3. Absorción in situ de pavimentos: técnica de sustracción (ISO 13472-1)

En campo no hay cámara reverberante. ISO 13472-1 mide la absorción acústica de un
pavimento (o de cualquier superficie plana extensa) *in situ* disparando un
impulso desde un altavoz a la altura $d_s$ hacia la superficie y registrando la
respuesta al impulso en un micrófono a la altura $d_m$. Las componentes
**incidente** y **reflejada** se separan en el tiempo con una ventana de
Adrienne; su función de transferencia da el factor de reflexión y de ahí la
absorción.

**Divergencia geométrica (cláusula 4.1).** La onda reflejada recorre más camino
que la directa, así que se atenúa por el factor de divergencia geométrica

$$
K_r = \frac{d_s - d_m}{d_s + d_m},
$$

que vale $2/3$ para la geometría obligatoria $d_s = 1{,}25$ m, $d_m = 0{,}25$ m. La
absorción se obtiene de los espectros incidente y reflejado enventanados $H_i$,
$H_r$:

$$
\alpha(f) = 1 - \frac{1}{K_r^2}\left|\frac{H_r(f)}{H_i(f)}\right|^2.
$$

```python

from phonometry import materials

# Una respuesta al impulso incidente limitada en banda y una reflexión de
# pavimento sintética hr = Kr * r0 * delayed(hi): una reflexión de magnitud
# r0 = 0.4, retardada por el camino adicional y escalada por el factor de
# divergencia geométrica Kr.
fs, n = 48000.0, 4096
t = np.arange(n) / fs
hi = np.zeros(n)
hi[:64] = np.hanning(64) * np.cos(2.0 * np.pi * 1500.0 * t[:64])

kr = materials.geometric_spreading_factor()          # (ds - dm)/(ds + dm) = 2/3
hr = kr * 0.4 * np.roll(hi, 96)

# Absorción de banda estrecha, luego reducida a tercios de octava en 250-4000 Hz.
alpha = materials.insitu_absorption_coefficient(hi, hr)   # 1 - (1/Kr^2)|Hr/Hi|^2
freq = np.fft.rfftfreq(n, 1.0 / fs)
centres, band = materials.one_third_octave_absorption(freq, alpha)
print(round(kr, 4))                # 0.6667
print(round(float(band[2]), 3))    # 0.84  (alpha = 1 - 0.4^2 = 0.84)
```

**Ventana de Adrienne (cláusula 6.4).** La ventana temporal que aísla la
reflexión solo exige un flanco de subida abrupto, una porción plana de 5 ms y un
flanco de bajada de coseno cuadrado o Blackman-Harris; las duraciones exactas se
informan en cada medición, no son fijas, así que aquí son configurables.

```python
from phonometry import materials

# Por defecto: flanco de subida de 0.5 ms, meseta de 5 ms, bajada Blackman-Harris de 5 ms.
w = materials.adrienne_window(48000.0)
print(w.shape[0])          # 504 muestras a 48 kHz
print(round(float(w.max()), 3))   # 1.0  (la meseta y los flancos se encuentran en la unidad)
```

**Espectro de principio a fin.** `insitu_absorption_spectrum` ejecuta toda la
cadena (de las respuestas al impulso incidente y reflejada enventanadas a la
absorción de banda estrecha y de ahí a las bandas de tercio de octava) y devuelve
un `InsituAbsorptionResult` representable:

```python

from phonometry import materials
from scipy.signal import firwin, lfilter

# Una medición sintética pero realista. hi es un impulso incidente unitario; la
# reflexión del pavimento hr = Kr * r0 * roll(hi, shift) usa el factor de
# divergencia geométrica Kr, un r0 levemente dependiente de la frecuencia (un
# suave paso-bajo, de modo que una superficie porosa refleja menos al subir la
# frecuencia) y el retardo del camino reflejado shift = round(2 dm / c * fs).
fs, n = 48000.0, 8192
kr = materials.geometric_spreading_factor()           # (ds - dm)/(ds + dm) = 2/3
hi = np.zeros(n)
hi[0] = 1.0
taps = firwin(41, 1200.0, fs=fs)
taps = taps / taps.sum()
shift = int(round(2.0 * 0.25 / 340.0 * fs))     # retardo del camino reflejado 2 dm / c
hr = kr * 0.85 * np.roll(lfilter(taps, 1.0, hi), shift)

result = materials.insitu_absorption_spectrum(hi, hr, fs)
print(result.frequencies[[0, -1]].astype(int))     # [ 250 4000]
print(np.round(result.absorption[[0, 6, 12]], 2))  # [0.31 0.65 1.  ]
result.plot()   # diagrama de barras alpha(f) en 250-4000 Hz (requiere matplotlib)
```

*La absorción crece con la frecuencia porque la superficie refleja menos energía
de alta frecuencia, exactamente como dicta el factor de reflexión paso-bajo
$r_0(f)$ a través de $\alpha = 1 - (1/K_r^2)\,|H_r/H_i|^2$.*

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

```python

from scipy.signal import firwin, lfilter
from phonometry import materials

# Una medición sintética pero realista. hi es un impulso incidente unitario; la
# reflexión del pavimento hr = Kr * r0 * roll(hi, shift) usa el factor de
# divergencia geométrica Kr, un r0 levemente dependiente de la frecuencia (un
# suave paso-bajo, de modo que una superficie porosa refleja menos al subir la
# frecuencia) y el retardo del camino reflejado shift = round(2 dm / c * fs).
fs, n = 48000.0, 8192
kr = materials.geometric_spreading_factor()           # (ds - dm)/(ds + dm) = 2/3
hi = np.zeros(n)
hi[0] = 1.0
taps = firwin(41, 1200.0, fs=fs)
taps = taps / taps.sum()
shift = int(round(2.0 * 0.25 / 340.0 * fs))     # retardo del camino reflejado 2 dm / c
hr = kr * 0.85 * np.roll(lfilter(taps, 1.0, hi), shift)
result = materials.insitu_absorption_spectrum(hi, hr, fs)

# result es el InsituAbsorptionResult calculado arriba. En una línea:
result.plot(language="es")
plt.show()

# A mano: un diagrama de barras de alpha sobre las bandas de tercio de octava.
freqs = result.frequencies
positions = np.arange(freqs.size)
fig, ax = plt.subplots()
ax.bar(positions, np.nan_to_num(result.absorption), width=0.7, color="#1f77b4")
ax.set_xticks(positions)
ax.set_xticklabels([f"{f:g}" for f in freqs], rotation=45, ha="right")
ax.set_xlabel("Frecuencia [Hz]")
ax.set_ylabel("Coeficiente de absorción alpha")
ax.set_ylim(0.0, 1.0)
ax.set_title("Absorción in situ de pavimentos (ISO 13472-1)")
plt.show()
```

</details>

**Área máxima muestreada (Anexo A).** La ventana temporal finita limita cuánta
superficie contribuye a la reflexión. El área máxima muestreada es un círculo
cuyo radio la librería calcula a partir de la geometría y la anchura de la
ventana; el ejemplo trabajado del Anexo A ($d_s = 1{,}25$ m, $d_m = 0{,}25$ m,
$c = 340$ m/s, ventana plana de 5 ms) da unos 1,34 m.

```python
from phonometry import materials
print(round(materials.max_sampled_area_radius(5.0e-3), 3))   # 1.343  (metros)
```

## 4. Absorción in situ de pavimentos: método puntual (ISO 13472-2)

Para parches más pequeños, ISO 13472-2 sella un tubo circular corto sobre la
superficie y mide la absorción con el método de la función de transferencia de
dos micrófonos de ISO 10534-2. La librería aporta la geometría del método puntual
y los ayudantes de validez; el propio DSP de la función de transferencia es la
rutina de tubo de impedancia `two_microphone_impedance` (véase la
[guía de Materiales acústicos](/phonometry/es/guides/materials/)).

**Límites de onda plana (cláusula 5.4).** El tubo solo soporta ondas planas por
debajo de

$$
f_u = 0{,}58\,\frac{c_0}{d},
$$

con $d$ el diámetro del tubo, y el espaciado de micrófonos $s$ debe situarse entre
$0{,}05\,c_0/f_{min}$ y $0{,}45\,c_0/f_{max}$. El rango informado son las bandas de
tercio de octava de 250 a 1600 Hz.

```python
from phonometry import materials

# Frecuencia superior utilizable de un tubo de 100 mm y la ventana de espaciado válida.
print(round(materials.spot_tube_upper_frequency(0.100, 343.0), 1))      # 1989.4 Hz
s_min, s_max = materials.spot_microphone_spacing_bounds(
    343.0, f_min=220.0, f_max=1800.0)
print(round(s_min, 3), round(s_max, 3))    # 0.078 0.086  (metros)
```

## Qué cubre esta guía

**Cubierto.** El coeficiente de dispersión de incidencia aleatoria de la
ISO 17497-1:2004+A1:2014 (las relaciones de absorción a partir del tiempo
de reverberación del apartado 6 y la Fórmula (5)) con los límites de placa
base de la Tabla 1, mediante `materials.random_incidence_absorption`,
`materials.specular_absorption_coefficient`, `materials.scattering_coefficient`,
`materials.scattering_coefficient_spectrum` y
`materials.check_base_plate_scattering`; el coeficiente de difusión
direccional y de incidencia aleatoria de la ISO 17497-2:2012 (Fórmulas (5) a
(8)) mediante `materials.directional_diffusion` y
`materials.random_incidence_diffusion`, más el modelo de predicción de
difusor de Fraunhofer de Cox y D'Antonio; la técnica de sustracción de la
ISO 13472-1:2002 (la propagación geométrica del apartado 4.1, la ventana
temporal Adrienne del apartado 6.4 y el radio de área muestreada del anexo
A) mediante `materials.insitu_absorption_spectrum` y sus piezas; y el
límite de frecuencia de onda plana y la geometría de separación de
micrófonos del método puntual de la ISO 13472-2:2010.

**No cubierto.** Ambas normas de absorción in situ de pavimentos se han
revisado desde entonces (ISO 13472-1:2022, ISO 13472-2:2025); aquí solo
están implementadas las ediciones anteriores de 2002 y 2010, como indican
las notas de referencia de arriba. El procesado de función de transferencia
propio de la ISO 13472-2 tampoco está implementado en este módulo: solo se
proporcionan la geometría y las funciones de validación, y el DSP de dos
micrófonos real es la rutina ISO 10534-2 de la
[guía de Materiales Acústicos](/phonometry/es/guides/materials/). El modelo
de predicción de difusor de Fraunhofer es una estimación de diseño, no
forma parte de la ISO 17497-2 en sí, y sus propios límites declarados
(pierde precisión a baja frecuencia, en ángulos rasantes y para superficies
muy absorbentes, e ignora la difracción de borde) hacen que no sustituya a
una medición real del coeficiente de difusión.

## Véase también

- [Propagación en exteriores](/phonometry/es/guides/outdoor-propagation/): el
  modelo completo de absorción atmosférica de ISO 9613-1, cuyo coeficiente de
  tono puro consumen las relaciones de atenuación del aire de ISO 17497-1.
- Referencia de la API: [`materials.scattering_diffusion`](/phonometry/es/reference/api/materials/scattering-diffusion/) y [`materials.road_absorption`](/phonometry/es/reference/api/materials/road-absorption/).
