Closed RobinSchmidt closed 2 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
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
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)
they look really weird in the time domain - especially with low sidelobe attenuation:
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.
these spikes get even more pronounced, when the window length is increased - here with length 128.
spectra:
time-domain:
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:
and the windows themselves like this:
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])
for comparison - here again Dolph-Chebychev with the same length (64):
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):
they are non-monotonic and go below zero in the time-domain - which may seem like weird feature for a "window" function:
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....
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...