Ir al contenido

Cepstrum, ecos y espectro de la envolvente

Normas aplicables: ISO 5348Referencias: Havelock et al. 2008Bendat y Piersol 2010

Los estimadores espectrales describen qué frecuencias contiene una señal; esta página cubre lo que se esconde en la forma de ese espectro. El cepstrum - la transformada de Fourier inversa del espectro logarítmico - vive en phonometry.signals y convierte dos problemas espectrales difíciles en simple localización de picos: el rizado espectral periódico (un eco, una familia de armónicos) colapsa en un único pico en la quefrencia de su periodo, y la envolvente espectral suave se separa de la estructura fina mediante un simple enventanado - liftering - en el dominio de la quefrencia. La misma maquinaria extiende la envolvente de Hilbert con un espectro de la envolvente en el que las modulaciones de amplitud se vuelven líneas discretas.

Todo el truco es una cadena de cuatro pasos: el logaritmo convierte un eco multiplicativo en ondulación espectral aditiva, y la FFT inversa colapsa esa ondulación en un único pico de quefrencia.

Diagrama de bloques de la cadena del cepstrum: una señal formada por una ondícula fuente más un eco con coeficiente de reflexión 0,5 a 8 milisegundos produce un espectro ondulado con periodo de 125 hercios, tomar el logaritmo del módulo al cuadrado convierte el eco multiplicativo en ondulación aditiva, y la FFT inversa aterriza en el eje de quefrencia, dibujado debajo con la ondícula fuente concentrada bajo 2 milisegundos, un pico de altura 0,5 exactamente en 8 milisegundos, un segundo rahmónico negativo de menos 0,125 al doble del retardo, y un corte de lifter discontinuo en 4 milisegundos que separa el lado paso bajo de la envolvente del lado paso alto de la ondulación; los pies dan la serie de alturas de los rahmónicos y las cotas de la ondulación de más 3,5 y menos 6,0 decibeliosDiagrama de bloques de la cadena del cepstrum: una señal formada por una ondícula fuente más un eco con coeficiente de reflexión 0,5 a 8 milisegundos produce un espectro ondulado con periodo de 125 hercios, tomar el logaritmo del módulo al cuadrado convierte el eco multiplicativo en ondulación aditiva, y la FFT inversa aterriza en el eje de quefrencia, dibujado debajo con la ondícula fuente concentrada bajo 2 milisegundos, un pico de altura 0,5 exactamente en 8 milisegundos, un segundo rahmónico negativo de menos 0,125 al doble del retardo, y un corte de lifter discontinuo en 4 milisegundos que separa el lado paso bajo de la envolvente del lado paso alto de la ondulación; los pies dan la serie de alturas de los rahmónicos y las cotas de la ondulación de más 3,5 y menos 6,0 decibelios

El vocabulario es el juego de palabras deliberado de Bogert sobre el dominio que refleja, que es el único dato que hace los nombres memorables en lugar de arbitrarios:

TérminoReflejaQué esUnidades
cepstrumespectroel espectro de un espectro logarítmicounidades de la señal
quefrenciafrecuenciasu variable independientesegundos
rahmónicosarmónicoslos picos que se repiten a lo largo de ella en segundos
lifteringfiltradoseleccionar un tramo de ella

Como el logaritmo convierte la convolución en la suma , componentes que se solapan en el espectro se suman - y se separan - en el dominio cepstral (Havelock cap. 27, Ecs. (22)-(23)). cepstrum calcula las tres variantes estándar sobre el eje de quefrencia:

  • 'power' (por defecto): la DFT inversa de (Fig. 21 de Milner). Real, par y ciega a la fase - el caballo de batalla para detectar ecos y familias de armónicos. Es el cepstrum con signo del espectro logarítmico de potencia según Milner; el «cepstrum de potencia» original de Bogert (1963) eleva al cuadrado una vez más y es no negativo - la biblioteca sigue a Milner en todo, así que los rahmónicos negativos conservan su signo;
  • 'real': la DFT inversa de - exactamente la mitad del cepstrum de potencia, y la cantidad cuyo plegado causal es la reconstrucción de fase mínima (más abajo);
  • 'complex': la DFT inversa de con la fase desenrollada y su componente lineal eliminada (Havelock cap. 87, Ec. (14)). Conserva la fase, así que es invertible: la puerta de entrada a la deconvolución homomórfica.
import numpy as np
from phonometry import cepstrum
fs = 48000.0
rng = np.random.default_rng(1)
x = rng.standard_normal(4096)
res = cepstrum(x, fs, kind="power")
print(res.quefrencies[:3], res.cepstrum.shape) # eje de quefrencia, en s
res.plot(language="es")
Los cepstra de potencia, real y complejo de una ondícula con un eco de 8 milisegundos superpuestos frente a la quefrencia hasta 20 milisegundos: los tres llevan un pico positivo nítido en 8 milisegundos y uno negativo pequeño en 16 milisegundos, la ondícula fuente llena la región por debajo de unos 2 milisegundos, y un recuadro ampliado sobre el primer rahmónico muestra los picos de potencia y complejo llegando a 0,5 mientras el cepstrum real llega exactamente a la mitadLos cepstra de potencia, real y complejo de una ondícula con un eco de 8 milisegundos superpuestos frente a la quefrencia hasta 20 milisegundos: los tres llevan un pico positivo nítido en 8 milisegundos y uno negativo pequeño en 16 milisegundos, la ondícula fuente llena la región por debajo de unos 2 milisegundos, y un recuadro ampliado sobre el primer rahmónico muestra los picos de potencia y complejo llegando a 0,5 mientras el cepstrum real llega exactamente a la mitad

Las tres variantes de un mismo registro con eco (una ondícula de banda limitada más una reflexión en 8 ms, ). Las tres llevan los rahmónicos en 8 y 16 ms con alturas y (convención con signo de Milner); el recuadro muestra el cepstrum real exactamente a la mitad del de potencia, y la ondícula fuente se concentra por debajo de 2 ms.

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 cepstrum
fs = 48000.0
# Una ondícula fuente de banda limitada más una reflexión en 8 ms (a = 0,5)
b, a = sp_signal.butter(2, 0.3)
s = np.zeros(4096)
s[37:37 + 256] = sp_signal.lfilter(b, a, np.r_[1.0, np.zeros(255)])
x = s + 0.5 * np.roll(s, 384)
# Una línea por variante: cada CepstrumResult se dibuja solo:
cepstrum(x, fs, kind="power").plot(language="es")
plt.show()
# Las tres variantes superpuestas a mano en un mismo eje de quefrencia:
fig, ax = plt.subplots()
for kind, style in (("power", "-"), ("real", "--"), ("complex", ":")):
res = cepstrum(x, fs, kind=kind)
q_ms = 1e3 * res.quefrencies
mask = (q_ms > 0.5) & (q_ms <= 20.0)
ax.plot(q_ms[mask], res.cepstrum[mask], style, label=f"cepstrum {kind}")
ax.set(xlabel="Quefrencia [ms]", ylabel="Cepstrum")
ax.legend()
plt.show()

El resultado lleva el eje de quefrencia periódico completo (0 .. (nfft-1)/fs); las quefrencias por encima de nfft/(2·fs) son las quefrencias negativas especulares, donde los cepstra de potencia y real (que son pares) se repiten y el cepstrum complejo guarda su contenido anticausal (de fase no mínima). El relleno de ceros vía nfft reduce el aliasing temporal cepstral cuando el espectro logarítmico tiene rasgos abruptos, exactamente igual que el relleno oversample de minimum_phase.

2. Detección de ecos: el tren de picos rahmónicos

Sección titulada «2. Detección de ecos: el tren de picos rahmónicos»

Una reflexión única multiplica el espectro por - un rizado de periodo en toda la banda. Su logaritmo se expande, para , en la serie exactamente sumable

así que el cepstrum lleva un tren de picos en los rahmónicos con amplitudes (su suma es ), independientemente del espectro de la propia , que se concentra en las quefrencias bajas. En el cepstrum con signo del espectro logarítmico de potencia (kind='power', la convención de Milner) la altura del primer pico es el coeficiente de reflexión - con su signo - más lo que el cepstrum de la fuente aporte en esa quefrencia (despreciable para fuentes de banda ancha, cuyo cepstrum se concentra en las quefrencias bajas); sobre un impulso ideal con eco la identidad es una forma cerrada que los tests y la batería de conformidad fijan a 1e-10. echo_detection automatiza la lectura: busca el mayor pico de |cepstrum| en la banda de búsqueda (así una reflexión inversora, , se encuentra en su retardo verdadero en vez de perderse), refina el retardo por interpolación cuadrática a través del pico y sus vecinos, y devuelve como coeficiente de reflexión el valor del pico con su signo. Cuando el retardo verdadero cae entre muestras, el rahmónico se reparte entre bins de quefrencia vecinos: el retardo interpolado sigue acertando, pero el coeficiente devuelto subestima (hasta cerca del 65 % de su valor a mitad de camino entre muestras).

import numpy as np
from phonometry import echo_detection
fs = 48000.0
rng = np.random.default_rng(2)
s = rng.standard_normal(12000) # fuente de banda ancha
x = s + 0.5 * np.roll(s, 384) # eco: 8 ms, a = 0.5
res = echo_detection(x, fs, min_quefrency=0.002)
print(res.delay, res.reflection_coefficient) # 0.008 s, ~0.5
res.plot(language="es")
Cepstrum de potencia de una respuesta al impulso con una reflexión frente a la quefrencia en milisegundos: un pico positivo afilado exactamente a 8 milisegundos marcado como eco detectado, un segundo rahmónico negativo menor a 16 milisegundos, la envolvente de la fuente en las quefrencias bajas fuera de la banda de búsqueda sombreada y una línea discontinua en el retardo verdaderoCepstrum de potencia de una respuesta al impulso con una reflexión frente a la quefrencia en milisegundos: un pico positivo afilado exactamente a 8 milisegundos marcado como eco detectado, un segundo rahmónico negativo menor a 16 milisegundos, la envolvente de la fuente en las quefrencias bajas fuera de la banda de búsqueda sombreada y una línea discontinua en el retardo verdadero

El cepstrum lee el eco en el eje y no en la forma de onda: el pico detectado cae en 8,000 ms y se levanta 0,488 frente al verdadero. La confirmación es el pequeño pico negativo de 16,0 ms, −0,126 contra el de la serie: una periodicidad espectral ajena no tiene por qué producir un tren de rahmónicos alternantes, así que el segundo pico es lo que separa un eco de una casualidad. Todo lo que queda a la izquierda de la banda sombreada es la envolvente de la propia fuente, que es por lo que la búsqueda empieza por encima de ella.

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 echo_detection, noise_signal
fs = 48000.0
n = 12000
impulse = np.zeros(n)
impulse[0] = 1.0
b, a = sp_signal.butter(2, [0.004, 0.9], btype="bandpass")
direct = sp_signal.lfilter(b, a, impulse) # clic de banda ancha
ir = direct + 0.5 * np.roll(direct, int(0.008 * fs)) # eco a 8 ms
ir += noise_signal(fs, n / fs, color="white", rms=1e-4, seed=13)
res = echo_detection(ir, fs, min_quefrency=0.002)
fig, ax = plt.subplots(figsize=(10, 6))
half = res.nfft // 2 + 1
ax.plot(1e3 * res.quefrencies[:half], res.cepstrum[:half], lw=1.1)
ax.axvline(8.0, ls="--", color="k", label="Retardo verdadero del eco")
ax.plot([1e3 * res.delay], [res.reflection_coefficient], "v", ms=10,
label="Pico detectado (altura = reflexión a)")
ax.set_xlim(0.0, 30.0)
ax.set_xlabel("Quefrencia [ms]")
ax.set_ylabel("Cepstrum")
ax.legend()
plt.show()

La banda de búsqueda empieza por encima de la región de quefrencias bajas que ocupa la envolvente espectral de la propia fuente (min_quefrency, por defecto 16 muestras) y termina en la mitad no ambigua del eje (max_quefrency). Los trenes de picos por reverberación de la sismología (Havelock cap. 87) son la misma firma a escala geofísica. Fíjate en el segundo rahmónico negativo en de la figura: el término de la serie, una confirmación útil de que un pico es de verdad un eco y no una periodicidad espectral sin relación.

Todo lo anterior corre sobre un clic sintético, y lo que el método consume de verdad es una respuesta al impulso. Mídela con cualquiera de las excitaciones de la biblioteca (un barrido exponencial, una MLS o la pareja de Golay de medición de sistemas), mantén el sonido directo y la reflexión dentro de un mismo registro y pásale la respuesta al impulso directamente a echo_detection.

El retardo es una diferencia de longitud de camino. , así que los 8 ms de la página a 343 m/s significan que el camino reflejado es 2,74 m más largo que el directo, lo que fija el reflector una vez conocidas las posiciones de fuente y receptor. Haz la conversión con la temperatura que mediste, no con 343: la velocidad del sonido se mueve unos 0,6 m/s por kelvin, que es un 0,2 % sobre la distancia por cada grado.

El coeficiente es una razón de amplitudes en el micrófono, no una propiedad de la superficie. significa que la reflexión llega con la mitad de amplitud que el sonido directo (una cuarta parte de la energía), y las dos juntas ondulan el espectro de magnitud entre y dB, que es la ondulación que aísla el §3. Pero ya lleva dentro la divergencia esférica de más del camino largo, así que el factor de reflexión propio de la superficie es . Para un retardo de 8 ms sobre un camino directo de 1 m esa razón es 3,74, así que , un número que no puede pasar de uno, lo que significa que una aparente por encima de no es en absoluto una única reflexión especular. Donde es válido, el coeficiente de absorción a ese ángulo de incidencia es ; las páginas de absorción son las dueñas de las vías normalizadas hacia la misma magnitud.

Un pico negativo es una inversión de fase. Una frontera de presión nula, o un camino eléctrico invertido, cambia el signo de la reflexión, y con él el de toda la serie de rahmónicos.

Cuatro condiciones deciden si el número significa algo:

  1. min_quefrency por encima de la duración de la llegada directa, para que la envolvente espectral de la propia fuente quede fuera de la banda de búsqueda.
  2. La reflexión al menos 10 dB por encima del fondo de ruido de la respuesta.
  3. El segundo rahmónico presente en con el signo opuesto, la comprobación que separa un eco real de una periodicidad espectral sin relación.
  4. Un tramo analizado varias veces mayor que el retardo buscado. La ondulación tiene periodo en frecuencia y un registro de duración solo resuelve el espectro hasta ; enventanar la respuesta alrededor de las llegadas que interesan también evita que reflexiones posteriores añadan rahmónicos propios.
Alzado dibujado a escala: una fuente y un micrófono de medición separados 1 m a 1,2 m sobre un suelo duro, el camino directo de 1,00 m trazado en recta y el camino reflejado en el suelo de 2,60 m trazado a través de la fuente imagen bajo el plano del suelo, lo que da una diferencia de camino de 1,60 m y un retardo de 4,7 ms a 343 m por segundo; un segundo panel repite la construcción para una pared lateral a 1,37 m, que da los 8 ms y los 2,74 m propios de la páginaAlzado dibujado a escala: una fuente y un micrófono de medición separados 1 m a 1,2 m sobre un suelo duro, el camino directo de 1,00 m trazado en recta y el camino reflejado en el suelo de 2,60 m trazado a través de la fuente imagen bajo el plano del suelo, lo que da una diferencia de camino de 1,60 m y un retardo de 4,7 ms a 343 m por segundo; un segundo panel repite la construcción para una pared lateral a 1,37 m, que da los 8 ms y los 2,74 m propios de la página

3. Liftering: envolvente frente a estructura fina

Sección titulada «3. Liftering: envolvente frente a estructura fina»

Filtrar en el dominio de la quefrencia se llama liftering (Havelock cap. 27, sec. 4.3). Un lifter paso bajo conserva las quefrencias por debajo del corte y devuelve la envolvente log-espectral suave con el rizado eliminado; un lifter paso alto conserva el complemento - solo el rizado. Los dos modos son exactamente complementarios en dB, porque la partición es lineal en el dominio logarítmico:

import numpy as np
from phonometry import lifter
fs = 48000.0
rng = np.random.default_rng(3)
s = rng.standard_normal(12000)
x = s + 0.5 * np.roll(s, 384) # el mismo eco de 8 ms
low = lifter(x, fs, cutoff=0.004, mode="lowpass") # envolvente de ln|X|
high = lifter(x, fs, cutoff=0.004, mode="highpass") # el rizado del eco
print(np.allclose(low.liftered_db + high.liftered_db, low.spectrum_db))
low.plot(language="es")
Dos paneles entre 500 y 2000 hercios para una ondícula que lleva un eco puro de 8 milisegundos: el espectro logarítmico oscila con un rizado de 125 hercios alrededor de la envolvente plana del lifter paso bajo, y debajo el rizado aislado por el lifter paso alto oscila exactamente entre las cotas discontinuas de forma cerrada en más 3,5 y menos 6 decibeliosDos paneles entre 500 y 2000 hercios para una ondícula que lleva un eco puro de 8 milisegundos: el espectro logarítmico oscila con un rizado de 125 hercios alrededor de la envolvente plana del lifter paso bajo, y debajo el rizado aislado por el lifter paso alto oscila exactamente entre las cotas discontinuas de forma cerrada en más 3,5 y menos 6 decibelios

El reparto del lifter de 4 ms sobre un registro de eco puro: el lado paso bajo devuelve la envolvente espectral suave, el lado paso alto aísla el rizado de 125 Hz del eco, oscilando exactamente entre las formas cerradas y dB.

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 lifter
fs = 48000.0
# Una ondícula de banda limitada con un eco puro de 8 ms (a = 0,5), de modo
# que el rizado del paso alto tiene las cotas exactas de forma cerrada.
b, a = sp_signal.butter(2, 0.3)
s = np.zeros(4096)
s[37:37 + 256] = sp_signal.lfilter(b, a, np.r_[1.0, np.zeros(255)])
x = s + 0.5 * np.roll(s, 384)
low = lifter(x, fs, cutoff=0.004, mode="lowpass")
high = lifter(x, fs, cutoff=0.004, mode="highpass")
# Una línea: el cepstrum con el corte y los dos espectros logarítmicos:
low.plot(language="es")
plt.show()
# El reparto envolvente/rizado a mano, ampliado a 500-2000 Hz:
band = (low.frequencies >= 500) & (low.frequencies <= 2000)
fig, axes = plt.subplots(2, 1, sharex=True)
axes[0].semilogx(low.frequencies[band], low.spectrum_db[band], "0.6",
lw=0.7, label="Espectro logarítmico")
axes[0].semilogx(low.frequencies[band], low.liftered_db[band], lw=2,
label="Lifter paso bajo: envolvente")
axes[1].semilogx(high.frequencies[band], high.liftered_db[band], "r",
label="Lifter paso alto: rizado")
for bound in (20 * np.log10(1.5), 20 * np.log10(0.5)):
axes[1].axhline(bound, color="g", linestyle="--")
axes[1].set_xlabel("Frecuencia [Hz]")
for ax in axes:
ax.set_ylabel("Magnitud [dB]")
ax.legend()
plt.show()

Para la señal de eco puro el rizado del paso alto oscila entre las formas cerradas y dB, otro oráculo que fijan los tests. En análisis de voz la misma operación separa la envolvente del tracto vocal (formantes) de los armónicos de la excitación; aquí es la herramienta general para separar «lo suave de lo periódico» en cualquier respuesta en magnitud medida.

4. El cepstrum complejo y la conexión con la fase mínima

Sección titulada «4. El cepstrum complejo y la conexión con la fase mínima»

El cepstrum complejo conserva la fase desenrollada, así que la transformada es de ida y vuelta: CepstrumResult.invert() restaura el registro con precisión de máquina, incluida la componente de fase lineal (retardo puro) que la transformada directa elimina y guarda en linear_phase_samples:

import numpy as np
from scipy import signal as sp_signal
from phonometry import cepstrum
fs = 48000.0
x = np.zeros(2048)
b, a = sp_signal.butter(2, 0.3)
x[37:293] = sp_signal.lfilter(b, a, np.r_[1.0, np.zeros(255)])
res = cepstrum(x, fs, kind="complex")
print(res.linear_phase_samples) # negativo: retardo eliminado
print(np.max(np.abs(res.invert() - x))) # ~1e-14
res.plot(language="es") # el cepstrum complejo frente a la quefrencia

Entre el logaritmo y la transformada inversa se puede editar lo que se quiera - eso es la deconvolución homomórfica (Havelock cap. 87, sec. 3.3): anular los rahmónicos elimina un eco, conservar solo las quefrencias bajas extrae la ondícula de la fuente. Una señal de fase mínima tiene un cepstrum complejo causal, y por eso plegar el cepstrum real sobre las quefrencias positivas reconstruye la fase mínima a partir de únicamente: minimum_phase y phase_decomposition corren sobre ese mismo núcleo de plegado (Bendat y Piersol sec. 13.1.4; Tohyama, en Havelock cap. 75, edita la reverberación manipulando exactamente estas partes causal y anticausal).

La ida y vuelta de arriba sale exacta con precisión de máquina porque el registro es suave, sin ruido y casi de fase mínima. El cepstrum complejo no es robusto en general, y la razón es la fase. Necesita una fase desenrollada que se pueda seguir de forma continua por toda la banda, y allí donde la magnitud se acerca a cero (un cero profundo, un cero cerca de la circunferencia unidad) la fase gira en el espacio de uno o dos bins y el desenrollador puede saltar en el sentido equivocado. Todas las quefrencias de ahí en adelante heredan el error. Los cepstra de potencia y real son inmunes, porque ni siquiera miran la fase.

Tres salvaguardas. Rellena con ceros mediante nfft para que la fase quede muestreada lo bastante fina como para que el desenrollador la siga; mantén alta la relación señal-ruido del registro en las bandas que importan, porque el ruido aditivo aleatoriza la fase justo donde la magnitud es pequeña; y comprueba la ida y vuelta con invert() antes de fiarte de ningún cepstrum editado: un desenrollado fallido se manifiesta al instante como un error de reconstrucción muy por encima de 1e-10. Cuando el registro no da para tanto, usa el cepstrum de potencia para la detección y el plegado del cepstrum real de minimum_phase cuando solo hace falta una fase coherente con la magnitud.

5. El espectro de la envolvente: modulaciones como líneas

Sección titulada «5. El espectro de la envolvente: modulaciones como líneas»

Donde el cepstrum encuentra periodicidades del espectro, el espectro de la envolvente encuentra periodicidades de la amplitud. La sección 13.3 de Bendat y Piersol (Fig. 13.11) formaliza la estructura: un detector de envolvente, un eliminador de continua y una vista espectral de lo que queda. envelope_spectrum pasa la envolvente de Hilbert (kind="magnitude", el valor práctico por defecto) o el detector cuadrático del libro (kind="squared") por exactamente esa cadena, escalada por la ganancia coherente de la ventana para que una modulación sinusoidal cuya frecuencia cae en un bin de análisis se lea como una línea con su amplitud exacta (las líneas fuera de bin leen de menos por la pérdida de scalloping de la ventana, hasta cerca de 1,4 dB con la Hann por defecto). El argumento opcional band=(low, high) reproduce el filtro paso banda de entrada de la figura 13.11 del libro - la cadena clásica de envolvente para rodamientos: aislar con un paso banda de fase cero la banda de resonancia estructural que excitan los impactos del defecto y después obtener su envolvente - de modo que un interferente fuera de banda llega muy atenuado al detector (la caída de un Butterworth de cuarto orden aplicado hacia delante y hacia atrás; el rechazo es finito, y el paso de fase cero deja pequeños transitorios en los bordes del registro).

Para un tono AM con en un bin de análisis las formas cerradas son:

kindnivel mediolínea en línea en
'magnitude'-
'squared'
import numpy as np
from phonometry import envelope_spectrum
fs = 8192.0
t = np.arange(int(4 * fs)) / fs
x = (1.0 + 0.4 * np.cos(2 * np.pi * 25.0 * t)) * np.cos(2 * np.pi * 1000.0 * t)
res = envelope_spectrum(x, fs)
k = int(round(25.0 * res.nfft / fs))
print(res.mean_level, res.amplitude[k]) # ~1.0 y ~0.4
res.plot(language="es")
Espectro de la envolvente de un tono de un kilohercio modulado en amplitud dentro de ruido, frente a la frecuencia hasta cien hercios: una única línea afilada en la frecuencia de modulación de veinticinco hercios que alcanza exactamente la referencia punteada de amplitud cero coma cuatro, con un suelo de ruido plano en el restoEspectro de la envolvente de un tono de un kilohercio modulado en amplitud dentro de ruido, frente a la frecuencia hasta cien hercios: una única línea afilada en la frecuencia de modulación de veinticinco hercios que alcanza exactamente la referencia punteada de amplitud cero coma cuatro, con un suelo de ruido plano en el resto

La línea no es proporcional a la modulación: es la modulación. Con en un bin de análisis el detector de magnitud lee 0,3996 frente a la forma cerrada , y mean_level lee 1,001 frente a . Ese es el sentido de escalar por la ganancia coherente de la ventana: la ordenada es una profundidad de modulación, no un nivel cualquiera. A su alrededor el suelo se queda cerca de 5×10⁻⁴, así que la línea se despega unos 58 dB incluso con ruido blanco al 3 % de la portadora, que es por lo que la cadena encuentra defectos de rodamiento que el espectro de la propia portadora esconde.

Mostrar el código de esta figura
import matplotlib.pyplot as plt
import numpy as np
from phonometry import envelope_spectrum, noise_signal
fs = 8192.0
seconds = 4.0
t = np.arange(int(seconds * fs)) / fs
x = (1.0 + 0.4 * np.cos(2 * np.pi * 25.0 * t)) * np.cos(2 * np.pi * 1000.0 * t)
x += noise_signal(fs, seconds, color="white", rms=0.03, seed=8)
res = envelope_spectrum(x, fs)
fig, ax = plt.subplots(figsize=(10, 6))
ax.plot(res.frequencies, res.amplitude, lw=1.4,
label="Espectro de la envolvente")
ax.axvline(25.0, ls="--", color="k", label="Frecuencia de modulación")
ax.axhline(0.4, ls=":", color="r",
label=r"Amplitud exacta de la línea $A_0 m$")
ax.set_xlim(0.0, 100.0)
ax.set_xlabel("Frecuencia [Hz]")
ax.set_ylabel("Amplitud de modulación")
ax.legend()
plt.show()

Los defectos de rodamientos y engranajes, el zumbido de la red eléctrica y la modulación de amplitud de los aerogeneradores aparecen así: líneas en la frecuencia de modulación y sus armónicos, limpiamente separadas del espectro de la propia portadora. La media de la envolvente que elimina la etapa de continua se conserva en mean_level (la amplitud de la portadora para el detector de magnitud), y remove_dc=False omite el eliminador cuando importa la línea de continua absoluta.

El argumento de la banda es donde se gana o se pierde la cadena de rodamientos, y ni la banda ni el transductor son una elección libre.

La banda. Pasa primero un espectro simple del registro bruto y busca la joroba ancha que excitan los impactos del defecto, una resonancia estructural del soporte, normalmente en algún punto entre 1 y 20 kHz para rodamientos de elementos rodantes. Coloca la banda alrededor de esa joroba. Hazla varias veces más ancha que la mayor tasa de repetición que necesites ver (de tres a cinco veces la mayor frecuencia de defecto, para que sus armónicos sobrevivan al detector), y elige al menos 2,56 veces el extremo superior de la banda. Cuando haya dos jorobas candidatas, quédate con aquella cuyo espectro de la envolvente dé mayor relación línea-fondo: la banda es una elección de relación señal-ruido, no una constante física. Una banda demasiado ancha vuelve a admitir las componentes fuertes de baja frecuencia que el filtro de entrada existe para eliminar; una demasiado estrecha deja a la envolvente sin energía de impacto; y el paso de fase cero deja transitorios en los dos bordes del registro, así que recórtalos antes de leer amplitudes.

El montaje. La frecuencia superior utilizable la fija la resonancia del acelerómetro montado, no el límite de la hoja de características del sensor, y esa es justamente la banda que necesita la cadena de rodamientos. El montaje atornillado o con una capa fina de adhesivo mantiene utilizable un acelerómetro de uso general hasta unos 10 kHz; una base magnética suele hundir eso a un par de kilohercios, y una sonda de mano a cerca de 1 kHz, es decir, el montaje por sí solo puede destruir la banda de la que depende el método. Pon el sensor sobre el soporte del rodamiento, en la zona de carga, tan cerca de la pista exterior como permita la máquina, con su eje en la dirección de la carga y el cable con descarga de tracción. ISO 5348 es la referencia de montaje.

# Una resonancia estructural de 3 kHz excitada a una frecuencia de defecto de
# 120 Hz, bajo una línea de 50 Hz tres veces más fuerte: el paso banda es lo
# que las separa.
t_s = np.arange(int(4 * fs)) / fs
ring = np.sin(2 * np.pi * 3000.0 * t_s) * np.exp(-(t_s % (1 / 120.0)) / 0.001)
raw = ring + 3.0 * np.sin(2 * np.pi * 50.0 * t_s)
wide = envelope_spectrum(raw, fs)
narrow = envelope_spectrum(raw, fs, band=(2000.0, 4000.0))
k120 = int(round(120.0 * wide.nfft / fs))
print(round(wide.amplitude[k120], 4), # 0,0093: enterrada
round(narrow.amplitude[k120], 4)) # 0,1964: 26 dB mejor

Las líneas que produce la cadena se identifican por su frecuencia, no por su amplitud, y las familias cinemáticas que les ponen nombre (paso de bola por la pista exterior y por la interior, giro de la bola, jaula, engrane y sus bandas laterales a la frecuencia de eje) se calculan a partir de la geometría y la velocidad de eje en Frecuencias de fallo de máquinas, que las dibuja directamente sobre un espectro de la envolvente como este. Pasar la envolvente sobre el residual de un promedio síncrono elimina antes las componentes deterministas del engranaje y deja limpias las líneas del rodamiento.

El cepstrum parte de las mismas convenciones FFT de registro único que los estimadores espectrales calibrados, y su núcleo de plegado es literalmente el que hay dentro de minimum_phase - la refactorización queda fijada bit a bit en los tests. El espectro de la envolvente es la vista en frecuencia de la misma señal analítica que la envolvente de Hilbert devuelve en el tiempo, y un preanálisis natural antes de las métricas dedicadas de modulación de amplitud de aerogeneradores: el espectro de la envolvente dice si hay modulación y a qué ritmo, las métricas del dominio la cuantifican normativamente.

  • Cubierto

    Las tres variantes del cepstrum y el liftering del Handbook of Signal Processing in Acoustics de Havelock, Kuwano y Vorländer (cepstrum, lifter, capítulos 27 y 87), el retardo de un único eco y el coeficiente de reflexión leídos en el cepstrum de potencia (echo_detection), el cepstrum complejo invertible y su ida y vuelta homomórfica (CepstrumResult.invert), y el espectro de la envolvente del capítulo 13 de Bendat y Piersol (envelope_spectrum) con sus líneas de forma cerrada para un tono AM.

  • No cubierto

    echo_detection solo elige el mayor pico cepstral de la banda de búsqueda, así que una respuesta con varios ecos solapados necesita localización manual de picos o llamadas repetidas sobre bandas más estrechas: no es un separador multi-eco. El módulo tampoco tiene un cepstrum en escala mel ni de tipo MFCC para rasgos de audio perceptual: lifter y cepstrum trabajan solo sobre el espectro logarítmico en frecuencia lineal.

  • Bendat, J. S. y Piersol, A. G. (2010). Random data: Analysis and measurement procedures (4.ª ed.). Wiley. https://doi.org/10.1002/9781118032428Sección 13.1.4 (la relación de Hilbert entre log-magnitud y fase tras el plegado de fase mínima) y sección 13.3 con la figura 13.11 (detección de envolvente seguida de eliminación de la continua, la estructura del espectro de la envolvente). ISBN 978-0-470-24877-5.
  • 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-0Capítulo 27 (Milner: la transformada cepstral como DFT inversa del espectro logarítmico de potencia, la quefrencia, liftering paso bajo/paso alto), capítulo 87 (Neelamani: el cepstrum complejo, deconvolución homomórfica, trenes de picos periódicos por reverberación) y capítulo 75 (Tohyama: manipulación fase mínima/paso todo en el dominio cepstral). ISBN 978-0-387-77698-9.
  • International Organization for Standardization. (2021). Mechanical vibration and shock — Mechanical mounting of accelerometers (ISO 5348:2021). Los métodos de montaje que hay detrás de la frecuencia superior utilizable de una medición de análisis de envolvente: montaje atornillado y pegado frente a bases magnéticas y sondas de mano.