Ir al contenido

Medición de sistemas: Golay, barridos, inversión

Referencias: Havelock et al. 2008Müller y Massarani 2001Kirkeby y Nelson 1999Golay 1961

La guía de acústica de salas 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, por el estimador 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.

Cadena de medición de respuesta en frecuencia a dos canales: un generador de señal con ruido de banda ancha o un barrido alimenta un amplificador de potencia y el altavoz en ensayo, un micrófono de medición recoge la salida acústica, el canal 1 lleva la referencia eléctrica x(t) y el canal 2 la respuesta del micrófono y(t), el análisis FFT de dos canales con segmentos Hann promediados a la Welch con 50 por ciento de solape produce los espectros Gxx, Gyy y Gxy, y dos cajas de resultado dan el estimador H1 igual a Gxy entre Gxx, insesgado con ruido a la salida, y la coherencia gamma cuadrado igual al módulo al cuadrado de Gxy entre el producto Gxx por Gyy, que vale uno en un camino lineal sin ruido y cae con ruido, distorsión o un retardo que deriva o está desalineadoCadena de medición de respuesta en frecuencia a dos canales: un generador de señal con ruido de banda ancha o un barrido alimenta un amplificador de potencia y el altavoz en ensayo, un micrófono de medición recoge la salida acústica, el canal 1 lleva la referencia eléctrica x(t) y el canal 2 la respuesta del micrófono y(t), el análisis FFT de dos canales con segmentos Hann promediados a la Welch con 50 por ciento de solape produce los espectros Gxx, Gyy y Gxy, y dos cajas de resultado dan el estimador H1 igual a Gxy entre Gxx, insesgado con ruido a la salida, y la coherencia gamma cuadrado igual al módulo al cuadrado de Gxy entre el producto Gxx por Gyy, que vale uno en un camino lineal sin ruido y cae con ruido, distorsión o un retardo que deriva o está desalineado

Un par de Golay son dos secuencias binarias y de longitud , construidas con una recursión de dos líneas (Havelock, Parte I, Cap. 6, Ec. (1)): partiendo de y , cada paso hace y , duplicando la longitud cada vez, de modo que golay_pair(14) devuelve dos códigos de muestras. Su propiedad definitoria es algebraica, no aproximada: las dos autocorrelaciones periódicas suman

una delta exacta (Ec. (2)). La autocorrelación de una MLS tiene un residuo 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 periódicamente, grabar un periodo en régimen estacionario, y lo mismo con - 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 fijan en 1e-13.

import numpy as np
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 respuesta al impulso de un sistema paso banda recuperada con un par de Golay durante los primeros seis milisegundos, dibujada encima de la respuesta verdadera discontinua sin diferencia visible, y una nota que dice máximo de recuperada menos verdadera igual a 2,1e-14, identidad exacta sin ruidoLa respuesta al impulso de un sistema paso banda recuperada con un par de Golay durante los primeros seis milisegundos, dibujada encima de la respuesta verdadera discontinua sin diferencia visible, y una nota que dice máximo de recuperada menos verdadera igual a 2,1e-14, identidad exacta sin ruido

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 aquí), la identidad de forma cerrada que fijan los tests.

Mostrar el código de esta figura
import matplotlib.pyplot as plt
import numpy as np
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()

El resultado es el mismo ImpulseResponseResult que devuelven los frontales de barrido y MLS, así que todo lo que viene después - parámetros de sala, curvas de caída, STI - 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.

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 y de 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) 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

Sección titulada «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 , hacer crecer el retardo de grupo en proporción a la potencia del objetivo,

(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):

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")
Dos paneles para un barrido conformado rosa de 50 hercios a 5 kilohercios: la forma de onda temporal con una envolvente casi constante durante dos segundos y, debajo, el espectro de Welch del barrido cayendo tres decibelios por octava exactamente sobre la línea discontinua del objetivo rosa dentro de la banda sombreada del barridoDos paneles para un barrido conformado rosa de 50 hercios a 5 kilohercios: la forma de onda temporal con una envolvente casi constante durante dos segundos y, debajo, el espectro de Welch del barrido cayendo tres decibelios por octava exactamente sobre la línea discontinua del objetivo rosa dentro de la banda sombreada del barrido

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.

Mostrar el código de esta figura
import matplotlib.pyplot as plt
import numpy as np
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()

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 de impulse_response, que divide de nuevo la coloración del barrido:

import numpy as np
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.

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 -ésimo armónico de una frecuencia instantánea llega en el instante en que el barrido pasa por , 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.

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) 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 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 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,

con pequeña dentro de la banda a ecualizar y grande fuera. En banda, la magnitud ecualizada se desvía de la unidad exactamente en - una forma cerrada que la batería de conformidad comprueba bin a bin - y fuera de banda la ganancia del filtro nunca puede superar , el máximo analítico de . 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).

import numpy as np
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")
Magnitudes sobre frecuencia logarítmica para una inversión regularizada de una respuesta paso banda: la respuesta medida en azul, el filtro inverso en rojo reflejándola dentro de la banda ecualizada sombreada de 200 hercios a 4 kilohercios, y el producto ecualizado en verde leyendo exactamente cero decibelios en la banda y cayendo fuera, donde la regularización limita la gananciaMagnitudes sobre frecuencia logarítmica para una inversión regularizada de una respuesta paso banda: la respuesta medida en azul, el filtro inverso en rojo reflejándola dentro de la banda ecualizada sombreada de 200 hercios a 4 kilohercios, y el producto ecualizado en verde leyendo exactamente cero decibelios en la banda y cayendo fuera, donde la regularización limita la ganancia

La curva verde es toda la prueba: dentro de la banda ecualizada se aparta de 0 dB como mucho 9×10⁻⁶ dB, que es 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 . Un a secas se saldría por arriba de este eje justo en las dos zonas donde la respuesta azul se sale por abajo.

Mostrar el código de esta figura
import matplotlib.pyplot as plt
import numpy as np
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()

Ambos niveles de regularización son fracciones del pico de , 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:

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

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

Sección titulada «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:

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

El par de Golay se une a sweep_signal y mls_signal en la familia de adquisición ISO 18233, y las tres se diferencian en cuatro ejes que deciden una medición real:

Par de GolayBarrido exponencialMLS
SNR por unidad de tiempolas 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 totalreferenciacomo el par, menos el segundo código
Distorsiónrepartida por el periodo como un suelo con aspecto de ruidoseparada en una región anterior a la respuesta lineal, donde se puede leer o descartarrepartida, como en el par
Variación temporalla 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 evidenteuna sola pasada, así que solo esa pasada tiene que ser estacionariauna pasada periódica
Truncamientouna 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 suficientese 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. La maquinaria de Welch usada para verificar el barrido conformado es la página de análisis espectral calibrado, y las respuestas ecualizadas alimentan la misma cadena posterior que cualquier respuesta al impulso.

  • Cubierto

    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.

  • No cubierto

    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.

  • Golay, M. J. E. (1961). Complementary series. IRE Transactions on Information Theory, 7(2), 82-87. https://doi.org/10.1109/TIT.1961.1057620La construcción original de los pares complementarios del §1.
  • Havelock, D., Kuwano, S. y Vorländer, M. (Eds.). (2008). Handbook of signal processing in acoustics. Springer. https://doi.org/10.1007/978-0-387-30441-0Parte I, capítulo 6 (Xiang, Digital Sequences): la recursión de Golay del §1, la identidad de autocorrelaciones complementarias de la Ec. (2) y el procedimiento de recuperación en frecuencia de la Ec. (4) y la Fig. 2. ISBN 978-0-387-77698-9.
  • Kirkeby, O. y Nelson, P. A. (1999). Digital filter design for inversion problems in sound reproduction. Journal of the Audio Engineering Society, 47(7/8), 583-595. La regularización de Tikhonov dependiente de la frecuencia del §3 (su Ec. (17)) y el retardo de modelado que hace causal la inversa de fase mixta (Sec. 2.4).
  • Müller, S. y Massarani, P. (2001). Transfer-function measurement with sweeps. Journal of the Audio Engineering Society, 49(6), 443-471. El capítulo de síntesis de barridos tras el §2: construcción en el dominio de la frecuencia a partir de magnitud y retardo de grupo (Sec. 4.2), la recursión del retardo de grupo para espectros de magnitud arbitrarios (Sec. 4.3, Ecs. (11)-(12)) y la discusión de inversión de banda limitada de las Secs. 3.1 y 4.5. Se consultó la edición extendida "Director's Cut".