signals.cepstrum
La referencia de la API se publica en inglés en los dos idiomas: se genera a partir de los docstrings del código, que son su texto original.
Cepstral analysis: real/power/complex cepstrum, liftering and echo detection.
The cepstrum is the inverse Fourier transform of the logarithm of a spectrum. Because the log turns the convolution into the sum (Havelock, Kahle & Cocchi (eds.), Handbook of Signal Processing in Acoustics, Springer 2008: Milner, Ch. 27, Eqs. (22)-(23)), components that overlap hopelessly in the spectrum separate cleanly in the cepstral domain — the smooth spectral envelope collapses onto the low quefrencies (the time-like axis of the cepstrum, in seconds) while periodic spectral ripple from harmonics, reflections or echoes concentrates at the quefrency of its period. Three variants are standard:
- the power cepstrum, the inverse transform of the log power spectrum (Milner Fig. 21) — real, even, phase-blind. (Convention note: Bogert, Healy & Tukey’s original 1963 power cepstrum squares once more, ; this module follows Milner’s linear throughout.);
- the real cepstrum, the inverse transform of
— exactly half
the power cepstrum, and the quantity whose causal folding yields the
minimum-phase reconstruction of
phonometry.minimum_phase(Bendat & Piersol, Random Data, 4th ed., Sec. 13.1.4; Tohyama in Havelock Ch. 75 manipulates minimum-phase and all-pass components the same way); - the complex cepstrum, the inverse transform of the full complex logarithm with the phase unwrapped (Neelamani in Havelock Ch. 87, Eq. (14)) — invertible, hence the engine of homomorphic deconvolution.
Echoes. A single reflection multiplies the spectrum by , whose complex logarithm expands (for ) into the exactly summable series
so the cepstrum carries a spike train at the rahmonics with
amplitudes (their sum is
): a peak at
exactly the echo delay whose height reads out the reflection coefficient.
echo_detection automates that reading on the power cepstrum, where
the first rahmonic’s height is a itself.
Liftering — filtering in the quefrency domain (Milner Sec. 4.3) — splits a log spectrum into its smooth envelope (low quefrencies kept by a lowpass lifter) and its fine structure (highpass): the classical route to a spectral envelope free of harmonic ripple, or to the ripple alone.
All estimators here operate on a single record with one FFT of length
nfft (even, at least the record length; the record is zero-padded up
to it). The discrete cepstrum is the inverse DFT of the log of a
sampled spectrum, so it is time-aliased when the log spectrum has
features sharper than the grid resolves; zero-padding nfft is the
remedy, exactly like the oversample padding of
phonometry.minimum_phase, whose cepstral folding core
(_fold_causal) this module shares.
Auto-generated from the source docstrings by
scripts/generate_api_docs.py(make api-docs). Do not edit by hand.
cepstrum
Section titled “cepstrum”cepstrum( x: NDArray[np.float64] | list[float], fs: float, *, kind: str = 'power', nfft: int | None = None,) -> CepstrumResultCepstrum of a record: power, real or complex.
"power": inverse DFT ofln|X|^2(Milner Fig. 21 in Havelock Ch. 27). Even, phase-blind; an echo of reflection coefficientaat delayt0shows rahmonics of amplitude(-1)^{n+1} a^n / nat quefrenciesn t0— heightaat the delay itself."real": inverse DFT ofln|X|— exactly half the power cepstrum. Folding it causally is the minimum-phase reconstruction (seephonometry.minimum_phase, which shares this module’s folding core)."complex": inverse DFT ofln|X| + j arg Xwith the phase unwrapped and its linear component removed (Neelamani Eq. (14) in Havelock Ch. 87). Real-valued for a real record, and invertible:CepstrumResult.invertreturns the signal.
Parameters
| Name | Description |
|---|---|
x | Signal, 1-D. |
fs | Sample rate, in Hz. |
kind | "power" (default), "real" or "complex". |
nfft | Even FFT length, at least x.size (default: the record length, rounded up to even). Zero-padding reduces the cepstral time-aliasing of sharp log-spectrum features. |
Returns: A CepstrumResult.
Raises
| Exception | When |
|---|---|
| ValueError | If the inputs or parameters are invalid. |
CepstrumResult
Section titled “CepstrumResult”CepstrumResult( quefrencies: NDArray[np.float64], cepstrum: NDArray[np.float64], kind: str, fs: float, nfft: int, linear_phase_samples: int,)A cepstrum over its full quefrency axis.
The quefrency axis runs 0 .. (nfft-1)/fs; quefrencies above
nfft/(2 fs) are the negative (anticausal) quefrencies of the
periodic axis. The power and real cepstra are even about that midpoint,
so their first half carries everything; the complex cepstrum is not
(its causal/anticausal split is what separates minimum-phase from
all-pass content, Havelock Ch. 75).
Attributes
| Name | Description |
|---|---|
quefrencies | Quefrency axis, in seconds. |
cepstrum | Cepstrum values (real-valued for the three kinds). |
kind | "power", "real" or "complex". |
fs | Sample rate of the analysed record, in Hz. |
nfft | FFT length used (even; the record is zero-padded to it). |
linear_phase_samples | Linear-phase component removed from the unwrapped phase before the complex cepstrum: the integer number of half-turns at the Nyquist bin, roughly minus the bulk delay in samples (0 for the other kinds, and for a minimum-phase record); restored by invert. |
CepstrumResult.invert()
Section titled “CepstrumResult.invert()”CepstrumResult.invert() -> NDArray[np.float64]Reconstruct the record from a complex cepstrum.
Applies the forward chain in reverse — DFT, restore the removed
linear phase, exponentiate, inverse DFT (the homomorphic
deconvolution round trip of Neelamani Sec. 3.3) — and returns the
zero-padded record, length nfft. Only the complex cepstrum
keeps the phase, so only it is invertible.
Returns: The reconstructed signal, length nfft.
Raises
| Exception | When |
|---|---|
| ValueError | If kind is not "complex". |
CepstrumResult.plot()
Section titled “CepstrumResult.plot()”CepstrumResult.plot( ax: Axes | None = None, *, language: str = 'en', **kwargs: Any,) -> AxesPlot the cepstrum against quefrency (positive quefrencies).
Parameters
| Name | Description |
|---|---|
language | Label language, "en" (default) or "es". |
echo_detection
Section titled “echo_detection”echo_detection( x: NDArray[np.float64] | list[float], fs: float, *, min_quefrency: float | None = None, max_quefrency: float | None = None, nfft: int | None = None,) -> EchoDetectionResultDetect an echo as the largest power-cepstrum peak in a quefrency band.
A reflection leaves a spike of
height a — positive or negative with the sign of the reflection —
at quefrency in the power cepstrum (module note; the
seismic
reverberation spike trains of Neelamani Sec. 3.3 are the same
signature), regardless of the spectrum of s itself, which
concentrates at low quefrencies. The peak is therefore picked on
|cepstrum|, so an inverting reflection (, e.g. a
pressure-release boundary) is found at its true delay, and the
signed cepstrum value at the peak is returned as the reflection
coefficient. The search band starts above the low-quefrency region
occupied by the source’s spectral envelope: raise min_quefrency
if the source is very reverberant or narrowband.
The delay is refined by quadratic interpolation of |cepstrum|
around the peak; see EchoDetectionResult for the bin-splitting
caveat on the coefficient at off-sample delays.
Parameters
| Name | Description |
|---|---|
x | Signal (an impulse response, or any record with an in-record echo), 1-D. |
fs | Sample rate, in Hz. |
min_quefrency | Lower edge of the searched band, in seconds (default 16 samples, clearing the immediate quefrency-zero region; raise it above the source’s envelope quefrencies when needed). |
max_quefrency | Upper edge of the searched band, in seconds (default and maximum: half the FFT length, the end of the unambiguous quefrency axis). |
nfft | Even FFT length, at least x.size (default: the record length, rounded up to even). |
Returns: An EchoDetectionResult.
Raises
| Exception | When |
|---|---|
| ValueError | If the inputs or parameters are invalid. |
EchoDetectionResult
Section titled “EchoDetectionResult”EchoDetectionResult( quefrencies: NDArray[np.float64], cepstrum: NDArray[np.float64], delay: float, delay_samples: int, reflection_coefficient: float, search_range: tuple[float, float], fs: float, nfft: int,)An echo delay and reflection coefficient read off the power cepstrum.
Attributes
| Name | Description |
|---|---|
quefrencies | Quefrency axis, in seconds. |
cepstrum | Power cepstrum searched. |
delay | The echo delay, in seconds: the quefrency of the largest |cepstrum| peak in the searched band, refined by quadratic (parabolic) interpolation of |cepstrum| through the peak sample and its two neighbours, so an off-sample delay is estimated to a fraction of a sample. |
delay_samples | The peak position in whole samples (no interpolation): the index at which reflection_coefficient is read, so delay differs from delay_samples/fs by the interpolated sub-sample offset (at most half a sample). |
reflection_coefficient | Signed cepstrum value at the peak sample. For a single in-record echo the power cepstrum’s first rahmonic height is exactly a — of either sign — (the term of the series), so the value estimates the reflection coefficient directly, including its polarity. When the true delay falls between samples the rahmonic is split across neighbouring quefrency bins and the reported coefficient underestimates (down to roughly 65 % of it for a delay midway between samples); the interpolated delay is unaffected. |
search_range | The (min, max) quefrency band searched, s. |
fs | Sample rate of the analysed record, in Hz. |
nfft | FFT length used. |
EchoDetectionResult.plot()
Section titled “EchoDetectionResult.plot()”EchoDetectionResult.plot( ax: Axes | None = None, *, language: str = 'en', **kwargs: Any,) -> AxesPlot the power cepstrum with the detected echo marked.
Parameters
| Name | Description |
|---|---|
language | Label language, "en" (default) or "es". |
lifter
Section titled “lifter”lifter( x: NDArray[np.float64] | list[float], fs: float, cutoff: float, *, mode: str = 'lowpass', nfft: int | None = None,) -> LifterResultLifter a record’s log spectrum: keep quefrencies below or above a cutoff.
Liftering is filtering in the quefrency domain (Milner Sec. 4.3 in
Havelock Ch. 27): the real cepstrum is windowed and transformed back
to a log-magnitude spectrum. A lowpass lifter keeps quefrencies
below cutoff (and the quefrency-zero mean level), recovering the
smooth spectral envelope with the harmonic or echo ripple removed; a
highpass lifter keeps the complement, isolating the ripple. The two
modes are exactly complementary in dB.
Parameters
| Name | Description |
|---|---|
x | Signal, 1-D. |
fs | Sample rate, in Hz. |
cutoff | Cutoff quefrency, in seconds; must resolve to at least one sample and at most nfft/2 samples. |
mode | "lowpass" (default) or "highpass". |
nfft | Even FFT length, at least x.size (default: the record length, rounded up to even). |
Returns: A LifterResult.
Raises
| Exception | When |
|---|---|
| ValueError | If the inputs or parameters are invalid. |
LifterResult
Section titled “LifterResult”LifterResult( frequencies: NDArray[np.float64], spectrum_db: NDArray[np.float64], liftered_db: NDArray[np.float64], quefrencies: NDArray[np.float64], cepstrum: NDArray[np.float64], cutoff: float, mode: str, fs: float, nfft: int,)A log spectrum split by liftering (Milner Sec. 4.3).
Attributes
| Name | Description |
|---|---|
frequencies | Frequency axis, in Hz. |
spectrum_db | Log-magnitude spectrum of the record, in dB. |
liftered_db | Log-magnitude spectrum rebuilt from the kept quefrencies alone, in dB. Lowpass and highpass parts add up to spectrum_db exactly (the split is linear in the log). |
quefrencies | Quefrency axis of the underlying real cepstrum, s. |
cepstrum | The real cepstrum the lifter window was applied to. |
cutoff | Lifter cutoff quefrency, in seconds. |
mode | "lowpass" (spectral envelope) or "highpass" (fine structure). |
fs | Sample rate of the analysed record, in Hz. |
nfft | FFT length used. |
LifterResult.plot()
Section titled “LifterResult.plot()”LifterResult.plot( ax: Axes | None = None, *, language: str = 'en', **kwargs: Any,) -> Axes | NDArray[Any]Plot the cepstrum with the cutoff and the two log spectra.
With ax given, only the spectrum panel is drawn on it.
Parameters
| Name | Description |
|---|---|
language | Label language, "en" (default) or "es". |