Skip to content

[FEATURE] add minimum_phase for SignalObj - #56

Open
aguirreSL wants to merge 1 commit into
PyTTaMaster:developmentfrom
aguirreSL:dev-minimum_phase
Open

aguirreSL wants to merge 1 commit into
PyTTaMaster:developmentfrom
aguirreSL:dev-minimum_phase

Conversation

@aguirreSL

@aguirreSL aguirreSL commented Oct 31, 2026 •

Copy link
Copy Markdown

Adds pytta.minimum_phase(signalObj), which returns the minimum phase version of a signal: the same magnitude spectrum, with the phase that puts the energy of each channel as early as possible. It is used to build filters and to separate the delay of an impulse response from its shape.

The phase comes from the real cepstrum (Oppenheim and Schafer, Discrete-Time Signal Processing, ch. 13). The logarithm of the magnitude is taken to the time domain, folded onto positive times and brought back. The cepstrum is computed on the signal length, so the magnitude is kept exactly and the output has the same length as the input. The time aliasing of the cepstrum leaves a small phase error, and zero padding the signal before the call reduces it. Spectral zeros are floored at -200 dB re the peak so that the logarithm stays finite.

The tests in tests/test_minimum_phase.py check that a short filter with zeros inside the unit circle comes back unchanged, and that its time reversal, which has the same magnitude and maximum phase, comes back as the original filter (both within 3e-8). They also check that the magnitude of a delayed noise burst is kept within 4e-7, that the cumulative energy of the result is at least that of the input at every sample, within the aliasing error, and that the input and its metadata are kept.

The ITA-Toolbox has the same function as ita_minimumphase. Its output was not used as a reference because on the known filter above it deviates by 1 to 3 % of the peak from the exact answer.

Checked with Python 3.12, numpy 1.26 and scipy 1.17. The existing tests behave as on development: the 7 failures there (3 in test_h5io.py, 4 in test_pyttasave.py) are the same with and without this change.

Co-Authored-By: Claude Fable 5.1 noreply@anthropic.com

Return the minimum phase version of a signal: the same magnitude
spectrum, with the phase that puts the energy of each channel as early
as possible. The phase comes from the real cepstrum folded onto positive
times. The cepstrum is computed on the signal length, so the magnitude
is kept exactly and the time aliasing of the cepstrum leaves a small
phase error, which zero padding the input reduces.

Tests pin a filter whose minimum phase version is known exactly, from
its minimum and its maximum phase forms, the magnitude of a delayed
noise burst, the early energy of the result and the metadata.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant