I'm performing a series of FFTs on windowed extracts of an input signal, to get a frequency spectrum over time. This is for a visualisation - I'd like to keep the window small, so the visualisation is fast-moving and responsive.

I'm only interested in the amplitude. Occasionally, two or more frequencies are close enough that the amplitude flickers wildly with the interference pattern between the two.

What ways are there to reduce this flickering, that will disturb my time-domain responsiveness less than increasing the window length?

(For reference, this is the visualisation - I'm not concerned with the "flashes" when something happens in the audio, but the juddering is not good.)

  • $\begingroup$ Is the processing done realtime? $\endgroup$ Mar 30 '16 at 19:29
  • $\begingroup$ No, this is an offline thing. $\endgroup$
    – cloudfeet
    Apr 1 '16 at 11:13

My suggestion is to low pass filter the FFT slices.

Suppose your current FFTs are: $$ X(n,k) = {\tt FFT}\{x[n] \cdot w_n[n]\} $$ where your signal is $x[n]$ and the window $w_n[n]$ enforces how much of the signal you want to include in the FFT at time $n$.

Then form: $$ Y(n,k) = \alpha \cdot Y(n-1,k) + (1-\alpha) \cdot X(n,k) $$ where $\alpha$ is a fraction between 0 and 1 (probably around 0.7 to 0.99).

This will effectively apply a first order lowpass filter to your FFTs.

Another possibility:

$$ Y(n,k) = {\tt median}\{X(n,k)\} $$

where the median is taken over the last $M$ values of $X(n,k)$ i.e. $\{ X(n,k), X(n-1,k), \ldots, X(N-M+1, k)\}$.

  • $\begingroup$ So, most solutions are quite likely to smudge the spectra the time domain, but this seems like it might do it particularly strongly. At α = 0.7, what are the advantages of this over tripling the window length (which would obviously reduce the maximum possible speed of the "flicker" by 3)? $\endgroup$
    – cloudfeet
    Mar 30 '16 at 15:44
  • $\begingroup$ This will clearly smear the time domain too. The main advantage is it's somewhat less computationally intensive than just increasing the window length. @cloudfeet : See my edit. A non-smearing approach might be to use a median filter. $\endgroup$
    – Peter K.
    Mar 30 '16 at 17:22
  • $\begingroup$ Yeah, a median filter is cool - but wouldn't that erase legitimate peaks? Like, if I clapped there'd be a spike, but the median filter would remove it. $\endgroup$
    – cloudfeet
    Apr 1 '16 at 11:14
  • $\begingroup$ @cloudfeet That depends on the time resolution between FFTs, but yes, it could. You may be able to take a hybrid approach: average out the middle 50% of samples in the window. Without actual data it's hard for me to say much more. $\endgroup$
    – Peter K.
    Apr 1 '16 at 11:27
  • $\begingroup$ A possible modification to the first order lowpass is to use a smaller $\alpha$ when $X(n, k) > Y(n-1, k)$. This makes it react to peaks faster than it decays after the peak. $\endgroup$ Apr 2 '16 at 21:44

If you know how close the frequency bands are that are causing the flicker by beating against each other, you can try to post filter that beat-frequency band out of the sequences of FFTs across time used for the visualization animation.

I don't think filtering before the FFTs will help, since the problem of beating is between adjacent FFT windows, not within the windows, due to the desire to use short windows. (If two nearby frequency spectra cancel out due to being of opposite phase, nothing you can do in that window will bring them back.)

Averaging or a median filtering across window results in time might also help, but that might reduce other frequency transients between windows more than a notch filter and/or band re-assignment (move the beat-frequency band to DC, etc.)


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.