26
$\begingroup$

Firstly, I am new to DSP and have no real education in it, but I am developing an audio visualization program and I am representing an FFT array as vertical bars as in a typical frequency spectrum visualization.

The problem I had was that the audio signal values changed too rapidly to produce a pleasing visual output if I just mapped the FFT values directly:

enter image description here

So I apply a simple function to the values in order to "smooth out" the result:

// pseudo-code
delta = fftValue - smoothedFftValue;
smoothedFftValue += delta * 0.2; 
// 0.2 is arbitrary - the lower the number, the more "smoothing"

In other words, I am taking the current value and comparing it to the last, and then adding a fraction of that delta to the last value. The result looks like this:

enter image description here

So my question is:

  1. Is this a well-established pattern or function for which a term already exsits? Is so, what is the term? I use "smoothing" above but I am aware that this means something very specific in DSP and may not be correct. Other than that it seemed maybe related to a volume envelope, but also not quite the same thing.

  2. Are there better approaches or further study on solutions to this which I should look at?

Thanks for your time and apologies if this is a stupid question (reading other discussions here, I am aware that my knowledge is much lower than the average it seems).

$\endgroup$
  • 1
    $\begingroup$ Now I'm wondering what you get if you take the smoothed FFT and inverse-FFT it. $\endgroup$ – user253751 Nov 2 '16 at 1:05
  • $\begingroup$ Would it be more straightforward to just do the first answer in a different order? current_value = current_value * decay; if (new_value > current_value) { current_value = new_value; } $\endgroup$ – Richard Forster Nov 2 '16 at 14:03
  • $\begingroup$ @immibis This should be a reverb from my understanding. Correct me, if I'm wrong. $\endgroup$ – Andreas Nov 2 '16 at 15:15
  • $\begingroup$ Sure, and an optimizing compiler will produce the same implementation. The key point was to get the correct result when (current_value*decay) < new_value < current_value. $\endgroup$ – Richard Forster Nov 2 '16 at 19:53
  • 2
    $\begingroup$ I really like this question. It is one of those where someone trying a few things out accidentally discovers themselves at the bottom of an enormous tree of knowledge (Infinite Impulse Response filters, specifically). Meanwhile, people who are already climbing up the tree can describe all the cool things that they have already discovered amongst the branches... $\endgroup$ – DrMcCleod Nov 4 '16 at 11:08
37
$\begingroup$

What you've implemented is a single-pole lowpass filter, sometimes called a leaky integrator. Your signal has the difference equation:

$$ y[n] = 0.8 y[n-1] + 0.2 x[n] $$

where $x[n]$ is the input (the unsmoothed bin value) and $y[n]$ is the smoothed bin value. This is a common way of implementing a simple, low-complexity lowpass filter. I've written about them several times before in previous answers; see [1] [2] [3].

$\endgroup$
  • 4
    $\begingroup$ Thanks a lot for this. So, so helpful. Googling on my own is like being lost at sea when it comes to DSP stuff. Just having a couple of terms to search gives me something to grasp. $\endgroup$ – Michael Bromley Nov 1 '16 at 19:45
  • 3
    $\begingroup$ I wonder. I think the OP applies this filter on the series of values in the individual bins in the frequency domain. A normal low-pass is applied on the series of samples in the time domain. Is the effect the same (I don’t think so, because the high frequency parts are still in the signal, but … their intensity changes more slowly?)? If not, could you elaborate on what the filter actually does to the signal in the time domain? $\endgroup$ – Jonas Schäfer Nov 2 '16 at 6:30
  • 3
    $\begingroup$ @JonasWielicki I think aim is smoothning each individual bin value, so that it does not change very rapidly. also the low pass filter(as explained in answer) is applicable to any time series irrespective of its domain(time or frequency or anything else). $\endgroup$ – arpit jain Nov 2 '16 at 8:43
  • $\begingroup$ @arpitjain I understand that. I’d simply like to know if there’s any understanding (not necessarily by you, the OP or the answerer) how it affects the time domain when you do that. $\endgroup$ – Jonas Schäfer Nov 2 '16 at 13:20
  • $\begingroup$ @JonasWielicki The operation is a convolution in the frequency domain, so it translates to a multiplication (of the corresponding (inverse) Fourier transforms) in the time domain. $\endgroup$ – MBaz Nov 2 '16 at 14:01
17
$\begingroup$

[EDIT: added some history, old papers (I love them) and punch cards]

You used, with $a=0.2$ the form: $$y(n) = y(n–1) + a[x(n) – y(n–1)]\,,$$ sometimes written as: $$y(n) = ax(n) + (1 – a)y(n–1)\,.$$

The first above version avoids one multiply. It yields a linear, causal, infinite impulse response filter. Story goes back to and through Poisson, Kolmogorov-Zurbenko Adaptive Filters, Brown (Statistical Forecasting for Inventory Control. McGraw-Hill, 1959), Holt (1957) and Winters (1960). It is implemented as a recursive filtering known under different names:

The "exponential" in the name is related to the impulse response with the geometric progression, that samples an exponential decay: $h[n]=(1-a)u[n]a^n$.

For an historical note, Robert G. Brown and Arthur D. Little used this method in 1956 in Exponential smoothing for predicting demand, apparently for the tobacco industry. A little more history and explanations can be found in Holt-Winters Forecasting for Dummies (or Developers) - Part I. Peter Zehna offers a critical review in Some remarks on exponential smoothing, 1966. A chapter by R. Brown in Encyclopedia of Operations Research and Management Science (Google books) dates the history back to 1944, the readable pages are reproduced here:

Exponential smoothing, p. 205, Encyclopedia of Operations Research and Management Science

Exponential smoothing, p. 206, Encyclopedia of Operations Research and Management Science

Many methods extend this smoothing, which lacks validity when the data has a trend or seasonality. Some of such are known as double or triple exponential smoothing, and Holt-Winters filters.

You can also check: How does this “simple filter” work?

$\endgroup$
  • 1
    $\begingroup$ Thanks, this is excellent. As mentioned, I am totally new to this so some of your answer will take further research for me to fully appreciate, but it certainly answers my question and then some. If not for the other, earlier answer, this is also of course worthy of acceptance as the answer. $\endgroup$ – Michael Bromley Nov 1 '16 at 19:58
  • 1
    $\begingroup$ Small correction, Winters 1(960) should be Winters (1960) I assume $\endgroup$ – SGR Nov 2 '16 at 15:36
9
$\begingroup$

Are there better approaches or further study on solutions to this which I should look at?

The normal approach for audio meters is a "lossy peak detector".

if new_value > current_value
  current_value = new_value;
else
 current_value = current_value * decay;  

This reacts immediately to any new or peak or transient in the signal but it lingers on for a while so it creates a much less hectic picture. Decay should be a constant between 0 and 1. It controls how quickly the bars come done with 0 being instantaneous and 1 being never.

$\endgroup$
  • $\begingroup$ I note that this bears similarities to an assignment I did in college, a very tinny-sounding MIDI (created in a previous assignment) was improved by convolving (and scaling to match peaks and durations) the (completely rectangular) note signals with a triangular signal that ramped up very sharply (though not instantly), and then decayed gradually, to produce a sharp note that died off “naturally.” Vast improvement in the sound of the song (Fur Elise in this case). $\endgroup$ – KRyan Nov 3 '16 at 4:36
  • $\begingroup$ I guess you'd want to keep new_value if it's greater than current_value * decay $\endgroup$ – user276648 May 24 '17 at 7:39
6
$\begingroup$

Around US DoD contractor circles, this particular filter is frequently called an "alpha filter", because it can be characterized with one parameter that is traditionally named "alpha".

It is directly analogous to a simpe analog RC low-pass filter.

They are extremely simple, have serious limitations, but they have the undeniable advantage over more complex (and complicated!) filters that, if you steer clear of their problem areas, they get the job done.

$\endgroup$
3
$\begingroup$

As mentioned in other answers, this is a Single Pole Recursive filter, a type of infinite impulse response (IIR) filter.

A great resource for information on this and other DSP features is Steven W. Smith's The Scientist and Engineer's Guide to Digital Signal Processing: infinite impulse response (IIR)

...each point in the output signal is found by multiplying the values from the input signal by the "a" coefficients, multiplying the previously calculated values from the output signal by the "b" coefficients, and adding the products together.. Notice that there isn't a value for b0, because this corresponds to the sample being calculated. Equation 19-1 is called the recursion equation, and filters that use it are called recursive filters. The "a" and "b" values that define the filter are called the recursion coefficients.

$\endgroup$

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.