RobinSchmidt / RS-MET

Codebase for RS-MET products (Robin Schmidt's Music Engineering Tools)
Other
56 stars 6 forks source link

Window functions #272

Closed RobinSchmidt closed 2 years ago

RobinSchmidt commented 5 years ago

i just wanted to create a thread to collect information about and discuss window functions. the obvious place to start is the wikipedia entry on this topic:

https://en.wikipedia.org/wiki/Window_function

it has in its links section a link to that very interesting paper:

"Spectrum and spectral density estimation by the Discrete Fourier transform (DFT), including a comprehensive list of window functions and some new flat-top windows" http://edoc.mpg.de/395068

which has a long list of potentially useful windows (along with general explanations).

typically, when selecting a window, we have to make a trade-off between various requirements: narrow mainlobe, low maximum sidelobe level, sidelobe rolloff, spectral amplitude flatness, summing-up-to-a-constant when overlapped (mostly relevant only for overlap-add (re)synthesis), etc....tbc...

RobinSchmidt commented 5 years ago

a very interesting window is the dolph-chebychev window:

https://en.wikipedia.org/wiki/Window_function#Dolph%E2%80%93Chebyshev_window

if the only two parameters, that we care about, are mainlobe-width and (maximum) sidelobe-level, the window is optimal. it minimizes the mainlobe width for given sidelobe level or minimizes the sidelobe level for given mainlobe width (however you want to approach it). that makes the sidelobes equiripple, so the sidelobes do not roll off at all (so the sidelobe rolloff is worst). here are some plots of the window spectra for sidelobe levels between -20dB and -100dB

image

i don't have it available in the library yet because its implementation is somewhat complicated. the plot was created with a prototypical implementation taken from here:

http://practicalcryptography.com/miscellaneous/machine-learning/implementing-dolph-chebyshev-window/

which is not really suitable for production code, since it scales with O(N^2) where N is the length of the window. production code should use an FFT based O(N*log(N)) algorithm.

i think, mainlobe-width vs. sidelobe-level are indeed the two main features that we should care about most for sinusoidal modeling, so i should add this window to the library soon

RobinSchmidt commented 4 years ago

yay! i have it working now. it's available in the library as rsWindowFunction::dolphChebychev. this was really a bitchy one to implement. the formulas that you find online or in books like here

https://www.dsprelated.com/freebooks/sasp/Dolph_Chebyshev_Window.html https://en.wikipedia.org/wiki/Window_function#Dolph%E2%80%93Chebyshev_window

just don't work. fortunately, i could find a working implementation in the scipy codebase:

https://github.com/scipy/scipy/blob/v0.19.0/scipy/signal/windows.py#L1293-L1416

which i could reverse engineer and base my own implementation on. i think, this window should be the most suitable one for the analysis of sinusoidal models because there, we indeed care about the mainlobe-width and maximum sidelobe level - and we do not really care about whether the sidelobes fall off or not. hamming, blackman etc. are well and good but this one should be better (if only slightly so) - but the bigger boon is that we now can continuously adjust between hamming-like and blackman-like and beyond. hamming-like would be the blue (sidelobe level around 40 dB) and blackman the green (60 dB)

RobinSchmidt commented 4 years ago

they look really weird in the time domain - especially with low sidelobe attenuation:

image

these spiky high values at the start and end...weird....but they do have useful spectra. hmmm...well....i guess, the non-decreasing sidelobes create the spikes - non-decreasing means that all frequencies have the same amplitude (aside from the overlaid comb-like spectrum) and that tends to create spike-like discontinuities? or something? yea - maybe.

RobinSchmidt commented 4 years ago

these spikes get even more pronounced, when the window length is increased - here with length 128.

spectra: image

time-domain: image

RobinSchmidt commented 4 years ago

there's a whole zoo of window functions out there. i even invented my own - defined as a cosine sum window:

https://en.wikipedia.org/wiki/Window_function#Cosine-sum_windows

and obtaining the weight-coefficients by imposing the constraint that a certain number of derivatives should vanish at the endpoints. this leads to a roll-off of the sidelobes which gets steeper with increasing number of cosines. the spectra look like this:

image

and the windows themselves like this:

image

the first of this class is the rectangular, the next is the Hanning and then come unnamed successors. they could become useful, when we need a window with a good roll-off behavior. i think, the window used in windowed-sinc interpolation could be such a case. at the moment, i'm using blackman there, too (if i remember correctly). sage code for getting the coeffs of the 3rd order window looks like this:

var("t a0 a1 a2 a3")
f(t)  = a0 + a1*cos(pi*t) + a2*cos(2*pi*t) + a3*cos(3*pi*t)
f2(t) = diff(f(t), t, 2) # 2nd derivative
f4(t) = diff(f(t), t, 4) # 4th derivative
eq1 = f(0)  == 1         # 1st requirement
eq2 = f(1)  == 0         # 2nd requirement
eq3 = f2(1) == 0         # 3rd requirement
eq4 = f4(1) == 0         # 4th requirement
solve([eq1,eq2,eq3,eq4],[a0,a1,a2,a3])

https://sagecell.sagemath.org/?z=eJxtzsEOwiAMBuD7nqLRC5scRuG6J1k8NA4iiTrHkOe33aKZiyQ99M8H_IWSOmSgFsgAIZA91FVQuQboJD1x3lzGWT1jwyGvuKzYfAO7BHYNqoByuYMhhqDkIQ1ZA9ZwBHwMMPgUC-VYfBXcP-lEunzdSj8ZdkG10qoDA59zBDNnSH56xeTv_pGZ4kLNStsNle9_qRWKYnfUpj11Qt0fKlW3dB5vxaueK2vuwmN53Fn31GoymlCTPddvR0pjjw==&lang=sage&interacts=eJyLjgUAARUAuQ==

RobinSchmidt commented 4 years ago

for comparison - here again Dolph-Chebychev with the same length (64): image image

RobinSchmidt commented 4 years ago

here are couple of "flat-top" windows from this article: http://edoc.mpg.de/395068 they have a flat top in the spectral domain which makes them suitable for estimating spectral amplitudes even when the frequencies of the input signal do not happen to align very well with the bin-center frequencies of the FFT (i should really use one of these in my spectrum-analyzer plugin): image

they are non-monotonic and go below zero in the time-domain - which may seem like weird feature for a "window" function:

image

RobinSchmidt commented 4 years ago

hey! what is this!

https://en.wikipedia.org/wiki/Window_function#Hann%E2%80%93Poisson_window https://ccrma.stanford.edu/~jos/sasp/Hann_Poisson_Window.html

...a window without sidelobes? :-O ....that could be useful...i have to implement it....