Frequency Domain Processing

For all of you early adopters from earlier in 2017, I wanted to let you know that there is now an example for doing frequency-domain processing!

I added it to the Tympan_Library repository a couple of months ago. So if you have an old version of the library, you’ll have to update your Tympan_Library from GitHub. You can do this either by downloading a new ZIP file, or by using one of the many Git tools (such as GitHub Desktop).

The new frequency-domain example is under Examples -> 04-FrequencyDomain. As of right now (October 2017), there is only one example program and it’s called LowpassFilter_FD because that is all it does: it is a lowpass filter in the frequency domain.

By “frequency domain”, I mean that I use an FFT to convert the original “time domain” audio data into its frequency components. The audio data is now in the frequency domain. I then step through each frequency bin and, for those frequency bins above the cutoff frequency, I reduce their values by 30 dB. Finally, I convert the frequency data back into the time-domain via an IFFT. This is “frequency-domain processing”.

In this example, the FFT size is 128 samples. This sets the frequency resolution of the processing. Given that my sample rate is set to 24 kHz, the frequency resolution is approximately 24000 / 128 = 188 Hz. If you want more resolution, you need a longer FFT.

A complete FFT-IFFT cycle is performed every audio block that passes through the Tympan. In this example software, the audio block size is 32 samples. So, a 128 point FFT is performed every 32 samples. The other 128-32 = 96 points are the older audio data that has been used in previous calculations. My underlying software routines handle all of this data shuffling. It’s not something that you have to worry about.

If you want to change the FFT size, it needs to be a power of 2 (ie, 32, 64, 128, 256, 512) and it needs to be an integer multiple of the audio block size. Some valid combinations (Audio Block Size, FFT Size) are: (16, 64), (32, 64), (32, 128), (64, 128), (128, 256), (128, 512). Others will probably work, too, as long as you satisfy the rule that the FFT size is both a power of 2 and an integer multiple of the block size.

In the future, I hope to add more frequency-domain processing examples. But, hopefully this can get you started!

Chip

Through email, I’ve gotten asked about CPU utilization for different FFT sizes. So, I did some experiments using the LowpassFilter_FD example shown above. Here’s what I found:

All of these tests used a sample rate of 24 kHz. I varied the size of the audio blocks and I varied the size of the FFT blocks. As an example, for an audio block of 32 samples (green line) I could do FFT sizes from 64 to 256 points. The CPU utilization ranged from 9% to 35%.

A curious result shown in this graph is that the curves are not smooth…the CPU utilization does not increase smoothly with FFT size. Instead, the CPU utilization is jagged. The system seems to require fewer-than-expected CPU cycles for FFT sizes of 64, 256, and 1024. It seems to require more-than-expected CPU cycles for FFT sizes of 32, 128, and 512. I’m guessing that what we’re seeing is the down-deep effect of the radix-2 vs radix-4 forms of the underlying FFT libraries: the radix-4 (64, 256, 1024) is more efficient than the radix-2 (32, 128, 512).

But, back to the main point, the Teensy-based Tympan is able to do a pretty good amount of processing in the frequency domain. For my favorite audio block size (N=32), you’re free to choose an FFT size of 64, 128, or 256.

Chip