<!-- canonical: https://jmrplens.github.io/phonometry/es/signals/spectra/system-measurement/ -->
Source: https://jmrplens.github.io/phonometry/es/signals/spectra/system-measurement/

La [guía de acústica de salas](/phonometry/es/buildings/rooms/room-acoustics/)
recupera respuestas al impulso con los dos caballos de batalla de la
ISO 18233: el barrido exponencial y la MLS. Esta página añade la capa de
ingeniería de medición a su alrededor, tomada de la literatura de medición de
funciones de transferencia y no de una norma: los **pares complementarios de
Golay** (una tercera excitación cuya deconvolución está *exactamente* libre
de ruido de correlación), los **barridos conformados** cuyo espectro de
magnitud sigue cualquier objetivo prescrito conservando el factor de cresta
de un seno barrido, y la **inversión regularizada** de una respuesta medida -
la herramienta que convierte la respuesta medida de un altavoz o micrófono en
un ecualizador seguro, y el puente entre las dos anteriores: la inversa de
una respuesta medida es el objetivo espectral natural para el barrido de la
siguiente medición.

Las dos herramientas de adquisición recuperan la respuesta con su propia
deconvolución: correlación con el par en Golay y división espectral por el
espectro del barrido en los barridos conformados. Las tres herramientas de esta
página viven en el mismo marco de dos canales que dibuja el diagrama, un
generador que excita el altavoz en ensayo, un canal con la referencia eléctrica
y otro con el micrófono, y solo se diferencian en la excitación y en la
deconvolución. El par de Golay del §1 recupera la respuesta por correlación con
los códigos; el barrido conformado del §2, por división espectral; y la vía de
ruido de banda ancha que el propio diagrama anota, que pertenece a la
[guía de electroacústica](/phonometry/es/devices/electroacoustics/electroacoustics/),
por el estimador $H_1 = G_{xy}/G_{xx}$ con una coherencia que lo vigila. La
inversión regularizada del §3 trabaja después sobre la respuesta medida que
salga de cualquiera de ellas.

## 1. Pares complementarios de Golay

Un par de Golay son dos secuencias binarias $a$ y $b$ de longitud $L = 2^n$,
construidas con una recursión de dos líneas (Havelock, Parte I, Cap. 6,
Ec. (1)): partiendo de $a_1 = (+1, +1)$ y $b_1 = (+1, -1)$, cada paso hace
$a_{k+1} = [\,a_k \mid b_k\,]$ y $b_{k+1} = [\,a_k \mid -b_k\,]$, duplicando la
longitud cada vez, de modo que `golay_pair(14)` devuelve dos códigos de
$2^{14} = 16384$ muestras. Su propiedad definitoria es
*algebraica*, no aproximada: las dos autocorrelaciones periódicas suman

$$
\sum_j a_j a_{j+k} + b_j b_{j+k} \;=\;
\begin{cases} 2L & k = 0\\ 0 & k \ne 0, \end{cases}
$$

una delta exacta (Ec. (2)). La autocorrelación de una MLS tiene un residuo
$-1$ en cada retardo no nulo; los lóbulos laterales de Golay se cancelan
idénticamente. La medición emite cada código por turnos - reproducir $a$
periódicamente, grabar un periodo en régimen estacionario, y lo mismo con
$b$ - y suma las dos correlaciones cruzadas circulares (Ec. (4)): para un
sistema lineal e invariante en el tiempo sin ruido, la respuesta al impulso
vuelve con precisión de máquina, una identidad de forma cerrada que los tests
y el [informe de conformidad](/phonometry/es/reference/conformance/) fijan
en `1e-13`.

```python

from scipy import signal
from phonometry import golay_impulse_response, golay_pair

fs = 48000
pair = golay_pair(14)                       # dos códigos de 16384 muestras

# Medición simulada: reproducir cada código periódicamente y grabar un
# periodo en régimen estacionario de un sistema paso banda tipo sala.
b, a = signal.butter(2, [80.0, 12000.0], btype="bandpass", fs=fs)
length = pair[0].size
rec_a = signal.lfilter(b, a, np.tile(pair[0], 3))[2 * length:]
rec_b = signal.lfilter(b, a, np.tile(pair[1], 3))[2 * length:]

ir = golay_impulse_response(rec_a, rec_b, pair, fs=fs)
print(ir.method, ir.size)                   # golay 16384
ir.plot(language="es")
```

*La recuperación de Golay de la respuesta al impulso de un sistema paso
banda: la suma de las correlaciones complementarias cae sobre la respuesta
verdadera con precisión de máquina (error máximo $2\cdot10^{-14}$ aquí), la
identidad de forma cerrada que fijan los tests.*

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

```python

from scipy import signal
from phonometry import golay_impulse_response, golay_pair

fs = 48000
pair = golay_pair(14)                       # dos códigos de 16384 muestras
b, a = signal.butter(2, [200.0, 2000.0], btype="bandpass", fs=fs)
length = pair[0].size
rec_a = signal.lfilter(b, a, np.tile(pair[0], 3))[2 * length:]
rec_b = signal.lfilter(b, a, np.tile(pair[1], 3))[2 * length:]

ir = golay_impulse_response(rec_a, rec_b, pair, fs=fs)

# Una línea: la respuesta al impulso recuperada:
ir.plot(language="es")
plt.show()

# A mano, contra la respuesta verdadera del sistema:
impulse = np.zeros(length)
impulse[0] = 1.0
true_ir = signal.lfilter(b, a, impulse)
err = np.max(np.abs(np.asarray(ir) - true_ir))

t_ms = 1e3 * np.arange(length) / fs
view = t_ms <= 6.0
fig, ax = plt.subplots()
ax.plot(t_ms[view], np.asarray(ir)[view], label="RI recuperada")
ax.plot(t_ms[view], true_ir[view], "r--",
        label="Respuesta verdadera del sistema")
ax.set(xlabel="Tiempo [ms]", ylabel="Amplitud",
       title=f"máx |recuperada - verdadera| = {err:.1e}")
ax.legend()
plt.show()
```

</details>

El resultado es el mismo
[`ImpulseResponseResult`](/phonometry/es/reference/api/rooms/impulse-response/)
que devuelven los frontales de barrido y MLS, así que todo lo que viene después -
[parámetros de sala](/phonometry/es/buildings/rooms/room-acoustics/), curvas de
caída, [STI](/phonometry/es/perception/speech/speech-transmission/) - lo consume sin
cambios. Las grabaciones de varios periodos se promedian síncronamente, de
modo que el ruido de fondo no correlacionado cae 3 dB por duplicación mientras la
parte determinista permanece exacta. Los compromisos son un espejo de la
MLS: la recuperación es circular (el sistema debe decaer dentro de un
periodo del código, o un `ImpulseResponseWarning` señala la cola con
aliasing), los productos de distorsión se reparten por el periodo en vez de
separarse como en un barrido, y los dos regímenes estacionarios secuenciales
hacen del par el más expuesto de la familia a la variación temporal (Sec. 2
de Xiang) - el precio de la complementariedad exacta.

### Cómo se pasa el par en la práctica

El fragmento de arriba finge la adquisición con `lfilter`, que da por supuesto
sin decirlo un lazo de latencia cero y exacto a la muestra. Una tirada real tiene
cuatro decisiones.

**Emisión.** Reproduce cada código uno tras otro y **descarta al menos un periodo
entero** antes de conservar nada, para que el sistema alcance el régimen
estacionario periódico que supone la correlación circular, la misma condición que
impone el aviso de aliasing, vista desde el otro lado. Después conserva un número
entero de periodos, y repite con el segundo código sin tocar ganancia ni
geometría.

**Alineación, que es la que falla en silencio.** La recuperación es una
correlación cruzada circular, así que cualquier latencia entre el flujo emitido y
el grabado aparece como una *rotación* de la respuesta al impulso: molesta, pero
recuperable. El daño de verdad es que **las dos grabaciones hay que cortarlas en
el mismo desplazamiento**: la complementariedad exacta solo sobrevive si los
registros de $a$ y de $b$ están alineados entre sí a la muestra, y una
discrepancia de una sola muestra destruye la cancelación de lóbulos laterales
sobre la que se apoya todo el método, dejando un suelo levantado que parece
ruido. Consigue el desplazamiento una vez con un canal de retorno (graba la
excitación eléctrica junto al micrófono y mídelo con `time_delay` de la página de
[estimación de retardos](/phonometry/es/signals/spectra/correlation-delay/)) y
después aplica el mismo corte a los dos.

**Nivel y fondo.** Ajusta el amplificador de modo que el pico del código deje
margen tanto en el altavoz como en el convertidor: los códigos de Golay son
binarios, así que su factor de cresta es el peor de la familia, y el recorte se
manifiesta como un suelo de ruido levantado y no como un artefacto evidente.
Graba primero un periodo de silencio y comprueba que la respuesta queda muy por
encima de él, porque el par rechaza el ruido solo promediando periodos.

**Invariancia temporal,** que la página ya nombra: mantén la sala cerrada, la
temperatura estable, y pasa los dos códigos uno detrás de otro y no con una hora
de diferencia.

## 2. Barridos con un espectro objetivo arbitrario

La energía de un barrido en una frecuencia dada puede fijarse de dos maneras:
con su amplitud, o con *cuánto tiempo permanece en ella*. La síntesis en el
dominio de la frecuencia de Müller y Massarani (Secs. 4.2-4.3) usa la
segunda palanca: definir la magnitud objetivo $|H(f)|$, hacer crecer el
retardo de grupo en proporción a la potencia del objetivo,

$$
\tau_\mathrm{G}(f) = \tau_\mathrm{G}(f - df) + C\,|H(f)|^2,\qquad
C = \frac{\tau_\mathrm{G}(f_\mathrm{end}) - \tau_\mathrm{G}(f_\mathrm{start})}{\sum |H(f)|^2},
$$

(Ecs. (11)-(12)), integrar el retardo de grupo en una fase, y aplicar la FFT
inversa. El barrido sigue entonces *cualquier* forma espectral con una
envolvente casi constante, manteniendo el factor de cresta cerca del ideal
de 3,01 dB de un seno barrido - a diferencia de una señal de ruido con el
mismo espectro, que queda ~6 dB por encima. `shaped_sweep_signal` implementa
la construcción con los detalles de limitación en banda y de fase en Nyquist
del artículo; `target` es `"pink"` (el énfasis clásico de medición de salas,
por defecto), `"white"`, o cualquier par `(frecuencias_hz, magnitud_db)`:

```python
from phonometry import shaped_sweep_signal

fs = 48000
sweep = shaped_sweep_signal(fs, 50.0, 5000.0, 2.0, target="pink")
print(round(sweep.crest_factor_db, 1))      # 4.2 (dB; el ideal es 3,02)
sweep.plot(language="es")
```

*Los dos paneles son la misma afirmación vista dos veces. La envolvente es plana
porque la forma se compró con tiempo de permanencia y no con amplitud, que es
por lo que el factor de cresta es de 4,22 dB: 1,2 dB por encima del ideal de
3,01 dB de un seno barrido y unos 6 dB por debajo del ruido conformado con el
mismo espectro. El espectro de Welch medido ajusta −3,013 dB/octava y se queda
a menos de 0,74 dB del objetivo rosa en toda la banda de 50 Hz a 5 kHz, así que
lo que ve el amplificador es el objetivo y no una aproximación suya.*

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

```python

from scipy import signal as sp_signal
from phonometry import shaped_sweep_signal

fs = 48000
res = shaped_sweep_signal(fs, 50.0, 5000.0, 2.0, target="pink")
x = np.asarray(res)

nperseg = 8192   # 75 % de solape: con 50 % un barrido riza ~2 dB
freqs, psd = sp_signal.welch(x, fs=fs, nperseg=nperseg,
                             noverlap=3 * nperseg // 4)
welch_db = 10.0 * np.log10(psd)
welch_db -= welch_db[(freqs >= 50.0) & (freqs <= 5000.0)].max()
target_db = 20.0 * np.log10(np.maximum(res.magnitude, 1e-300))
target_db -= target_db[(res.frequencies >= 50.0)
                       & (res.frequencies <= 5000.0)].max()

fig, axes = plt.subplots(2, 1, figsize=(10, 7))
axes[0].plot(np.arange(x.size) / fs, x, lw=0.5)
axes[0].set_xlabel("Tiempo [s]")
axes[0].set_ylabel("Amplitud")
axes[1].semilogx(freqs[1:], welch_db[1:], lw=1.3,
                 label="Espectro de Welch")
axes[1].semilogx(res.frequencies[1:], target_db[1:], "r--",
                 label="Objetivo rosa (-3 dB por octava)")
axes[1].axvspan(50.0, 5000.0, alpha=0.08, label="Banda del barrido")
axes[1].set_xlabel("Frecuencia [Hz]")
axes[1].set_ylabel("Nivel re máximo en banda [dB]")
axes[1].set_ylim(-60.0, 8.0)
axes[1].legend()
plt.tight_layout()
plt.show()
```

</details>

Los metadatos de la síntesis viajan con el resultado: `frequencies` y
`magnitude` son la magnitud exacta, limitada en banda, impuesta al espectro;
`group_delay` es la trayectoria tiempo-frecuencia del barrido, y
`crest_factor_db` la relación pico/RMS conseguida. El propósito de la
conformación es ingeniería de la relación señal-ruido: adaptar el espectro
emitido al ruido de fondo del recinto (o a los límites de potencia del
altavoz) compra una SNR independiente de la frecuencia que ningún
posprocesado puede recuperar (Müller y Massarani, Sec. 3).

La deconvolución no necesita nada nuevo: el resultado actúa como su propio
array de referencia para el
[método espectral](/phonometry/es/buildings/rooms/room-acoustics/) de
`impulse_response`, que divide de nuevo la coloración del barrido:

```python

from scipy import signal
from phonometry import impulse_response, shaped_sweep_signal

fs = 48000
freqs = np.array([50.0, 200.0, 1000.0, 8000.0])
emphasis = np.array([12.0, 6.0, 0.0, 0.0])   # refuerzo LF contra el retumbo
sweep = shaped_sweep_signal(fs, 50.0, 8000.0, 3.0,
                            target=(freqs, emphasis))

# Medición simulada de un sistema conocido (sustituir por emitir/grabar):
b, a = signal.butter(2, [200.0, 4000.0], btype="bandpass", fs=fs)
excitation = np.concatenate([np.asarray(sweep), np.zeros(fs)])
recorded = signal.lfilter(b, a, excitation)

ir = impulse_response(recorded, excitation, fs, length=fs)
ir.plot(language="es")
```

El énfasis vuelve a ponderar el suelo de ruido de la medición, no la
respuesta recuperada. Una sutileza heredada de la limitación dura en banda:
el núcleo limitador de banda de la deconvolución es de fase cero, así que una
pequeña cola anticausal queda al final del búfer completo de deconvolución -
usa `return_full=True` cuando persigas décimas de dB en los bordes de la
banda.

### Elegir el objetivo, el nivel y la duración

El `emphasis = np.array([12.0, 6.0, 0.0, 0.0])` de arriba es una afirmación, no
una medida. Cinco decisiones la convierten en una.

- **El objetivo sale del fondo.** Mide primero el fondo en la posición del
  micrófono con `power_spectral_density`, suavízalo a tercios de octava y usa su
  *forma* más el margen que quieras como objetivo del barrido. El espectro
  emitido sigue entonces al ruido y la respuesta deconvolucionada tiene una
  relación señal-ruido plana, en lugar de una banda media buena y una octava
  grave inservible.
- **La duración sale del margen que te falte.** Duplicar la longitud del barrido
  compra unos 3 dB de relación señal-ruido en la respuesta deconvolucionada, así
  que la duración es aritmética, acotada por arriba por la invariancia temporal
  del sistema: una sala con aire en movimiento, o un altavoz que se calienta,
  pone el techo mucho antes que la aritmética.
- **El registro necesita cola.** La excitación tiene que llevar un silencio al
  menos tan largo como la caída del sistema después del barrido, que es para lo
  que está el `np.zeros(fs)` de los fragmentos de arriba.
- **El énfasis en baja frecuencia tiene un tope físico.** La excursión del
  altavoz y el margen del amplificador te paran mucho antes que la síntesis.
  Sube el nivel hasta que la respuesta deje de ser lineal y luego baja un poco:
  compara dos tiradas separadas 6 dB y, si las respuestas deconvolucionadas
  difieren, ya te habías pasado.
- **Conformar no cuesta la separación de la distorsión.** Esa separación es una
  propiedad del *retardo de grupo* del barrido, no de su magnitud: el $k$-ésimo
  armónico de una frecuencia instantánea $f$ llega en el instante en que el
  barrido pasa por $kf$, así que mientras el retardo de grupo sea monótono, cosa
  que la recursión garantiza para cualquier objetivo no nulo, los productos de
  distorsión siguen deconvolucionándose a tiempos anteriores a la respuesta
  lineal. Conformar solo cambia cuánto antes, porque un objetivo que permanece
  más tiempo en las frecuencias bajas reparte los paquetes armónicos de otra
  manera que la permanencia constante por octava del barrido exponencial. Esos
  paquetes separados se leen en
  [distorsión con barrido sinusoidal](/phonometry/es/devices/electroacoustics/swept-sine-distortion/).

## 3. Inversión espectral regularizada

### Medir la respuesta que vas a invertir

La inversión vale lo que valga su entrada, y la respuesta medida de un altavoz no
es un paso banda sintético. Mide en el eje de referencia y a una distancia
declarada (1 m es el convenio de IEC 60268-5 que usa la
[guía de altavoces](/phonometry/es/devices/electroacoustics/loudspeakers/)) con un
micrófono de medición, en cámara anecoica si la tienes. Si no la tienes, separa
fuente y micrófono de todas las superficies tanto como permita la sala y
**enventana en el tiempo la respuesta al impulso antes de la primera reflexión**.
Esa ventana fija la frecuencia válida más baja: para una fuente y un micrófono a
1,2 m sobre un suelo duro y separados 1 m, la reflexión del suelo llega 4,7 ms
después del sonido directo, así que la respuesta enventanada solo vale por encima
de unos $1/4{,}7\ \text{ms} \approx 210$ Hz. Pon `f_range` dentro de la banda que
la ventana haya validado de verdad y deja que la regularización limite todo lo
que quede fuera, porque ecualizar una respuesta en sala sin enventanar mete los
modos de la sala dentro del filtro, y esos modos se mueven con el micrófono. Por
debajo del límite de la ventana, la alternativa habitual es una medida sobre
plano rígido.

Ecualizar con una respuesta medida significa invertirla, y un recíproco puro
$1/H(f)$ se dispara allí donde el sistema radia poca energía - un valle en
banda, todo lo que queda fuera de banda - convirtiendo el ecualizador en un
amplificador de ruido. Müller y Massarani confinan la inversión con un paso
banda (Secs. 3.1, 4.5); la forma general de ese confinamiento es la
regularización de Tikhonov dependiente de la frecuencia de Kirkeby y Nelson,

$$
H_\mathrm{inv}(f) = \frac{H^*(f)}{|H(f)|^2 + \varepsilon(f)},
$$

con $\varepsilon(f)$ pequeña dentro de la banda a ecualizar y grande fuera. En
banda, la magnitud ecualizada $|H \cdot H_\mathrm{inv}|$ se desvía de la unidad
exactamente en $\varepsilon/(|H|^2 + \varepsilon)$ - una forma cerrada que la
batería de conformidad comprueba bin a bin - y fuera de banda la ganancia del
filtro nunca puede superar $1/(2\sqrt{\varepsilon})$, el máximo analítico de
$x/(x^2 + \varepsilon)$. Un retardo de modelado de medio bloque del filtro hace
causal la inversa, en general anticausal, de una
respuesta de fase mixta (Kirkeby y Nelson, Sec. 2.4).

```python

from scipy import signal
from phonometry import regularized_inverse_filter

fs = 48000.0
# Una respuesta medida tipo altavoz (sustituir por una RI medida).
b, a = signal.butter(2, [100.0, 8000.0], btype="bandpass", fs=fs)
imp = np.zeros(2048)
imp[0] = 1.0
h = signal.lfilter(b, a, imp)

inv = regularized_inverse_filter(h, fs, f_range=(200.0, 4000.0))
print(round(inv.flatness_db, 5))    # 1e-05 (dB: desviación en banda de 0 dB)
print(round(inv.max_gain_db, 1))    # -6.0 (dB: refuerzo fuera de banda acotado)
inv.plot(language="es")
```

*La curva verde es toda la prueba: dentro de la banda ecualizada se aparta de
0 dB como mucho 9×10⁻⁶ dB, que es $\varepsilon/(|H|^2+\varepsilon)$ evaluada
bin a bin y no un resultado ajustado. Fuera de ella la inversa roja se detiene
en lugar de trepar: el refuerzo queda acotado en −6,03 dB respecto de la unidad
en banda, el máximo analítico $1/(2\sqrt\varepsilon)$. Un $1/H$ a secas se
saldría por arriba de este eje justo en las dos zonas donde la respuesta azul se
sale por abajo.*

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

```python

from scipy import signal
from phonometry import regularized_inverse_filter

fs = 48000.0
b, a = signal.butter(2, [100.0, 8000.0], btype="bandpass", fs=fs)
imp = np.zeros(2048)
imp[0] = 1.0
h = signal.lfilter(b, a, imp)

res = regularized_inverse_filter(h, fs, f_range=(200.0, 4000.0))
f = res.frequencies[1:]
h_mag = np.abs(res.response_spectrum)[1:]
inv_mag = np.abs(res.spectrum)[1:]
peak = h_mag.max()

fig, ax = plt.subplots(figsize=(10, 6))
ax.semilogx(f, 20 * np.log10(h_mag / peak), label="Medida $|H|$")
ax.semilogx(f, 20 * np.log10(inv_mag * peak),
            label=r"Inversa $|H_{\mathrm{inv}}|$")
ax.semilogx(f, 20 * np.log10(h_mag * inv_mag), lw=1.8,
            label=r"Ecualizada $|H \cdot H_{\mathrm{inv}}|$")
ax.axvspan(200.0, 4000.0, alpha=0.08, label="Banda ecualizada")
ax.set_ylim(-50.0, 15.0)
ax.set_xlabel("Frecuencia [Hz]")
ax.set_ylabel("Magnitud [dB]")
ax.legend()
plt.show()
```

</details>

Ambos niveles de regularización son fracciones del pico de $|H|^2$,
generalizando la `regularization` escalar de `impulse_response`:
`regularization_inside` (por defecto `1e-6`) fija con qué exactitud se
aplana la banda, `regularization_outside` (por defecto `1.0`) limita el
refuerzo fuera de banda 6 dB *por debajo* de la unidad en banda, y un fundido
geométrico de `transition_octaves` octavas (por defecto 1/3) conecta ambos
suavemente. El `apply()` del resultado ecualiza cualquier grabación con el
retardo de modelado ya eliminado, y la función acepta directamente un
`ImpulseResponseResult` - su frecuencia de muestreo viaja con él:

```python

from scipy import signal
from phonometry import (impulse_response, regularized_inverse_filter,
                        sweep_signal)

fs = 48000
sweep = sweep_signal(fs, 50.0, 20000.0, 1.0)
excitation = np.concatenate([sweep, np.zeros(fs // 2)])
b, a = signal.butter(2, [100.0, 8000.0], btype="bandpass", fs=fs)
recorded = signal.lfilter(b, a, excitation)     # en la práctica: emitir/grabar

ir = impulse_response(recorded, excitation, fs)  # vale cualquier frontal
inv = regularized_inverse_filter(ir, f_range=(200.0, 10000.0))
flat_recording = inv.apply(recorded)             # retardo ya eliminado
inv.plot(language="es")   # magnitudes medida, inversa y ecualizada (figura de arriba)
```

### Invertir una respuesta medida

Dos costumbres separan un ecualizador que funciona de un amplificador de ruido.

**Suaviza primero la magnitud.** Un `fractional_octave_smoothing` de sexto a
tercio de octava es la elección habitual, para que la inversa apunte a la
tendencia y no a los valles. Un valle es un patrón de interferencia local: se
mueve con el micrófono, así que no se puede ecualizar en ningún sitio salvo en
ese punto, y reforzarlo gasta margen para amplificar ruido.

**Regulariza como una medida, no como una señal sintética.** Sobre una respuesta
medida, `regularization_inside` va en el intervalo de 1e-3 a 1e-2, lo que limita
el aplanado en banda a unas décimas de decibelio y acota el refuerzo; el valor
por defecto 1e-6 que da la planitud de 1e-5 dB de arriba solo tiene sentido con
una respuesta sintética sin ruido, y esperar ese número de una medida real es el
error. Lee en consecuencia los dos números que se informan: `flatness_db` es cómo
de plana sale la banda, y `max_gain_db` el refuerzo en el peor caso que el filtro
puede llegar a aplicar, el número que hay que contrastar con el margen del
amplificador antes de reproducir nada a través de él.

Conviene decir sin rodeos la asimetría en la que se apoya el oficio: **corta
hondo y refuerza con timidez.** Un pico es una resonancia y existe en todas
partes; un hundimiento suele ser interferencia y solo existe en el micrófono.

### Cerrando el círculo: preénfasis desde una respuesta medida

Las dos mitades de esta página componen el propio flujo de trabajo de
Müller y Massarani (su Fig. 18): medir el altavoz, invertir su respuesta en
la banda de transmisión y entregar la magnitud inversa a la síntesis del
barrido como objetivo - la siguiente medición radia entonces un espectro
acústico *plano*, con la ecualización hecha por la excitación en vez de por
un posprocesado que amplifica ruido:

```python

from scipy import signal
from phonometry import regularized_inverse_filter, shaped_sweep_signal

fs = 48000.0
b, a = signal.butter(2, [100.0, 8000.0], btype="bandpass", fs=fs)
imp = np.zeros(2048)
imp[0] = 1.0
h = signal.lfilter(b, a, imp)                    # la respuesta medida

inv = regularized_inverse_filter(h, fs, f_range=(200.0, 4000.0))
target_db = 20.0 * np.log10(
    np.abs(inv.spectrum[1:]) * np.abs(inv.response_spectrum).max()
)
sweep = shaped_sweep_signal(int(fs), 200.0, 4000.0, 3.0,
                            target=(inv.frequencies[1:], target_db))
sweep.plot(language="es")   # forma de onda y espectro contra el objetivo invertido
```

## Relación con las demás herramientas

El par de Golay se une a `sweep_signal` y `mls_signal` en la
[familia de adquisición ISO 18233](/phonometry/es/buildings/rooms/room-acoustics/),
y las tres se diferencian en cuatro ejes que deciden una medición real:

| | Par de Golay | Barrido exponencial | MLS |
| :--- | :--- | :--- | :--- |
| SNR por unidad de tiempo | las tres son deterministas y ganan 3 dB por duplicación del tiempo de medición, pero el par dedica la mitad de su tiempo a cada código y paga por ello **3 dB** frente a un único barrido de la misma duración total | referencia | como el par, menos el segundo código |
| Distorsión | repartida por el periodo como un suelo con aspecto de ruido | separada en una región *anterior* a la respuesta lineal, donde se puede leer o descartar | repartida, como en el par |
| Variación temporal | la más frágil: exige dos regímenes estacionarios idénticos, y la deriva levanta el suelo de ruido en vez de dar un error evidente | una sola pasada, así que solo esa pasada tiene que ser estacionaria | una pasada periódica |
| Truncamiento | una caída más larga que un periodo se envuelve sobre el principio (el aviso de aliasing de arriba) | solo necesita que se le añada silencio suficiente | se envuelve, como en el par |

Así pues: el barrido por el rechazo de la distorsión, la MLS por hardware
heredado, y el par cuando importe la deconvolución exacta y libre de ruido de
correlación de un *montaje estacionario* (bancos de HRTF, útiles de
calibración), donde 3 dB de relación señal-ruido salen baratos y a lo que se ha
venido es al último decimal de la respuesta al impulso. El análisis armónico de
lo que los barridos *descartan* vive en
[distorsión con seno barrido](/phonometry/es/devices/electroacoustics/swept-sine-distortion/).
La maquinaria de Welch usada para verificar el barrido conformado es la
página de [análisis espectral calibrado](/phonometry/es/signals/spectra/spectral-analysis/),
y las respuestas ecualizadas alimentan la misma cadena posterior que
cualquier [respuesta al impulso](/phonometry/es/buildings/rooms/room-acoustics/).

## Qué cubre esta guía

El par complementario de Golay (Golay 1961; Havelock, Kuwano y Vorländer eds.,
2008, parte I, cap. 6 de Xiang): la recursión de adjunción, la identidad
exacta de autocorrelaciones complementarias y la recuperación por suma de
correlaciones, implementadas por `golay_pair` y `golay_impulse_response`. La
síntesis de barridos por retardo de grupo de Müller y Massarani (2001, secs.
4.2-4.3), implementada por `shaped_sweep_signal`. La regularización de
Tikhonov dependiente de la frecuencia de Kirkeby y Nelson (1999, Ec. 17 y sec.
2.4), implementada por `regularized_inverse_filter`.

Son métodos de ingeniería de medición tomados de la literatura de funciones de
transferencia, no de una norma de certificación, así que no hay ningún
apartado de cumplimiento contra el que comprobar. La inversión original de
Kirkeby y Nelson apunta a la reproducción sonora multialtavoz, con una
regularización matricial para la cancelación de diafonía entre varios canales.
`regularized_inverse_filter` implementa solo el caso escalar de un único canal
de su Ec. 17.

## Véase también

- [Acústica de salas](/phonometry/es/buildings/rooms/room-acoustics/): las excitaciones de barrido y MLS de ISO 18233 junto a las que se sitúa el par de Golay.
- [Distorsión con seno barrido](/phonometry/es/devices/electroacoustics/swept-sine-distortion/): leer los paquetes armónicos que un barrido separa.
- [Altavoces](/phonometry/es/devices/electroacoustics/loudspeakers/): el eje de referencia, la distancia y las condiciones de campo libre que necesita la respuesta medida.
- [Análisis espectral calibrado](/phonometry/es/signals/spectra/spectral-analysis/): la maquinaria de Welch que verifica el barrido conformado, y el suavizado que la inversión quiere antes.
- [Correlación y retardo](/phonometry/es/signals/spectra/correlation-delay/): la medida de retorno que alinea los dos registros de Golay.
- Referencia de la API: [`signals.inversion`](/phonometry/es/reference/api/signals/inversion/).
