question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. ItĀ collects links to all the places you might be looking at while hunting down a tough bug.

And, if youā€™re still stuck at the end, weā€™re happy to hop on a call to see how we can help out.

`hann_window` does not obey COLA; therefore, it cannot be used with `istft`

See original GitHub issue

šŸ› Bug

In order to enable inversion of an STFT via the inverse STFT in istft, it is sufficient that the signal windowing obeys the constraint of ā€œConstant OverLap Addā€ (COLA). This ensures that every point in the input data is equally weighted, thereby avoiding aliasing and allowing full reconstruction. https://docs.scipy.org/doc/scipy/reference/generated/scipy.signal.check_COLA.html

Learn more: https://ccrma.stanford.edu/~jos/sasp/Mathematical_Definition_STFT.html#19930

To Reproduce

>>> from scipy import signal
>>> import torch
>>> signal.check_COLA(signal.hann(1024, sym=False), 1024, 1024 - 256)
True
>>> signal.check_COLA(torch.hann_window(1024).numpy(), 1024, 1024 - 256)
False
>>> window = torch.hann_window(1024).numpy()
>>> window[0] *= 0.5
>>> window[-1] *= 0.5
>>> signal.check_COLA(window, 1024, 1024 - 256)
False

Expected behavior

The expected behavior is that the hann window is implemented such that it is useable with istft.

Issue Analytics

  • State:open
  • Created 4 years ago
  • Comments:11 (6 by maintainers)

github_iconTop GitHub Comments

1reaction
f0kcommented, Apr 30, 2020

This seems to be a precision issue:

>>> import scipy.signal
>>> import torch
>>> w1 = scipy.signal.hann(1024, sym=False)
>>> w2 = torch.hann(1024)
>>> w3 = torch.hann(1024, dtype=torch.float64)
>>> scipy.signal.check_COLA(w1, 1024, 512)
True
>>> scipy.signal.check_COLA(w2.numpy(), 1024, 512)
False
>>> scipy.signal.check_COLA(w3.numpy(), 1024, 512)
True

So it works when letting Pytorch compute the window in double precision like scipy. It also works when converting back to single precision, for both:

>>> scipy.signal.check_COLA(w1.astype(np.float32), 1024, 512)
True
>>> scipy.signal.check_COLA(w3.numpy().astype(np.float32), 1024, 512)
True

I suppose the right modification would be to copy scipy and to test for COLA.

The scipy code is here: https://github.com/scipy/scipy/blob/6d576be/scipy/signal/windows/windows.py#L109-L118, called with a=(0.5, 0.5). The Pytorch code is here: https://github.com/pytorch/pytorch/blob/bca8280/aten/src/ATen/native/TensorFactories.cpp#L894-L899, called with alpha=0.5, beta=0.5. Not sure if thereā€™s any way to get more accurate results in single precision? Otherwise what we could do in torchaudio would be to create the window in double precision and convert it to the target dtype afterwards.

@faroit The window is off by a minimum of 5e-3. That is a large difference, in my opinion. Weā€™re not talking about 1^-10. (See the second comment)

@PetrochukM: Itā€™s 5-e9 in your second comment. But thatā€™s for the last coefficient; the maximum difference is around 1.2e-7. In any case, thereā€™s a way to pass scipyā€™s COLA test with a float32 window, but not with the one produced by torch.hann_window(1024), so we could improve things a little.

0reactions
PetrochukMcommented, Apr 30, 2020

@f0k Thanks for looking into this! Also, I was totally wrong with the maximum difference, thanks for correcting me!

It sounds like there is a little bit of room for improvement. It also sounds like there is still room in replicating librosa and scripyā€™s behavior.

Read more comments on GitHub >

github_iconTop Results From Across the Web

scipy.signal.check_COLA ā€” SciPy v1.9.3 Manual
If window is array_like it will be used directly as the window and its length must be nperseg ... ā€œSymmetricalā€ Hann window (for...
Read more >
Some examples of windows that satisfy COLA Rectangular ...
COLA is not true for 25% (1/4) overlap, though:>>> signal. ... the inverse STFT in`istft`, the signal windowing must obey the constraint of...
Read more >
MATLAB iscola - MathWorks
This MATLAB function checks that the specified window and overlap satisfy the Constant Overlap-Add (COLA) Constraint to ensure that the Inverse Short-TimeĀ ...
Read more >
reconstructing signal with tensorflow.contrib.signal causes ...
E.g. librosa's istft does, and that's what i'd expect. Maybe this is not the norm? ii) What about the severe amp modulation at...
Read more >
https://fsapps.nwcg.gov/gtac/CourseDownloads/IP/Ca...
Defaults to 'boxcar'. nfft : int, optional Length of the FFT used. ... check_COLA(signal.boxcar(100), 100, 75) True COLA is not true for 25%...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found