Arduino FFT – Post Processing

In using the Arduino FFT library for our ESP32 based project, we select the following sampling information:

SAMPLE_RATE = 10240
SAMPLES = 512

The reason we don’t go higher is that we just don’t need to. Mathematics says that this gives us frequency analysis up to 5120 Khz, and that’s a very high frequency to listen to.

We then sample the data in a timed loop, then run:

FFT.Windowing( FFT_WIN_TYP_HAMMING, FFT_FORWARD );
FFT.Compute( FFT_FORWARD );
FFT.ComplexToMagnitude();

Linear or Logarithmic Values

We now end up with an array of real values, which we can then process into our 512 fftBin[] results, of which only bins 3-255 contain usable information. Initial questions are:

  1. Volume is measured in decibels, and a signal at 83dB is twice as loud as one at 80dB. The question is, do we convert our FFT results to logarithmic values to make the results linear.
  2. Do we then apply a filter to those results in order to normalize the data, as you may not get an even frequency response? Oh, and this is made more difficult since we support multiple microphone types.

Summary Frequency Bins

Our next step is to create 16 summary bins out of the 252 viable fftBin’s.

Since frequency change is best displayed logarithmically, those fftBin’s are distributed in a similar manner in that fftResult[0] only gets the values of 2 bins, while at the high end, fftResult[15] get the values of 62 bins. Oh, and that distribution was NOT easy to figure out.

Squelch

Due to the nature of the microphones, we also initially measure the background noise and create a table of values to apply to the fftResult bins in order to ‘squelch’ that noise. We also have an adjustable Squelch setting in order to take into account different microphones and environments.

Spikes

In the ESP32 environment, we see a significant number of volume spikes. For basic volume reactive routines, I can smooth the value out over several iterations, but should we do anything about that in an FFT environment?

Automatic Gain Control

Do we provide some method for automatic Gain Control so that the led’s are active even in low volume environments or louder ones? One method would be to use a Proportional Integral Control loop. Intensity is currently only adjustable by the intensity slider on a ‘per effect’ basis.

Frequency Distribution to Bins

For those 16 fftResult bins, do we perform further processing, and a Biquad filter was mentioned.

1. Do we filter the volume of the results using a Biquad (or similar) filter?
2. Do we adjust the distribution of the fftBin[] values to the fftResult[] bins using that filter?
3. If the latter, how would we do so?
4. How about using a couple of sliders to determine start/stop frequency bins?

More questions/issues?

Comments are closed.