Forum Rule: Always post complete source code & details to reproduce any issue!

Thread: Audio Library and 4096 point FFT on Teensy 3.6

1. Originally Posted by LoShu
Thank you so much for your quick response, Frank.

Looks like a good solution. I need time to digest. I shall let you know the result, but it takes time.
BTW, a good starting point could be:

1.) take the AudioGrabber object by DerekR as-it-is for the FFT256 at standard sample rate
2.) modify the AudioGrabber object (include the code for lowpass filtering and downsampling inside the object) and add that to your audio project.

2. Will do.
Thanks a lot, Frank.

3. It seems that this thread has split into a couple of somewhat disparate conversations:
1) Getting the audio library 4096 FFT to work, which I think has been established?
2) Analyzing/displaying partial frequency regions of an FFT. (See #44)

Let's discuss the latter:
As you are aware, spectral information is normally displayed in "Bode" form where
- Magnitude is displayed on a log/log scale (x is log of frequency - but usually labeled in Hz, y is log of magnitude usually in dB.
- Phase is displayed on log/linear form, where again frequency is in log form, but y (phase is shown on a linear scale in units of degrees or radians)

BUT this doesn't mean you need some sort of special FFT! Engineering/scientific software packages, such as MATLAB, simply compute their displays using a normal linear FFT analysis, then take the necessary logs of the bin frequencies and magnitude and display the data in Bode form. Why can't that be done here?
Note: You can't go down to dc (0 Hz) because log(0) = -infinity, so you need to choose a suitable minimum frequency (bin) for your display.

I note the displays shown in the thread go from 20 Hz to 20 kHz - ie 3 decades of frequency. Since the FFT bin frequencies are n*f_sample/Nfft, to get down to 20 Hz for n = 1 we need Nfft > 44100/20 or >2205 (you could probably get away with 2048, where bin 1 corresponds to 21.5 Hz). Can you use decimation in this case? No - because you need to keep the analysis Nyquist frequency above 20 kHz (the highest in the display). So, unfortunately, you seem to be stuck with a large FFT if you want to duplicate this display...

The computational "cost" of an FFT is roughly proportional to Nfft*log_2(Nfft) so you might expect that the 2048 FFT will take about 46% of the time of a 4096 FFT...

BUT, if you are happy to make 50 Hz your minimum frequency, then a length 1024 FFT will do the trick, bin 1 is now 43 Hz, and you might expect the FFT to be 5 times faster than the 4096 one. Now we're talking

1)
I also think that the 4096 FFT has been established. However as I mentioned in my previous post in #37 and #42. I don't understand why it doesn't work in my T3.6. I very much like to make it work and test its performance.
In post #4 by duff, he mentioned about CMSIS v1.1.0. I cannot find any file named CMSIS, is it referring to "core_cm4.h"? The version of this file in my computer is v3.01. I don't know whether it is the cause of the problem, any opinion?

2)
a) "simply compute their displays using a normal linear FFT analysis, then take the necessary logs of the bin frequencies". Agree, it is a matter of the minimum frequency (bin). I want to decrease the min frequency (bin) to around 10 Hz.

b) 2048 FFT will give a min frequency (bin) to around 20 Hz. It is better than 1024 FFT. I would like to try if it can be implemented in simple way. I found a lot of information relating to the 4096 FFT, but less on 2048 FFT. Any example I can follow?

c) According to Frank in #49, he suggested a Zoom FFT plus a 256 FFT working in parallel. It would give a min frequency (bin) even down to around 5 Hz. I am studying his suggestion, but, due to my limited theoretical knowledge, it may take me a long time.

d) My understanding is that to lower the min frequency bin to x Hz, you need at least 1/x seconds. (e.g. a min frequency bin of 10Hz you require a update time of at least 0.1 Second. correct me if I am wrong). If this is correct, I don't know if it applies to zoom FFT as well. If it applies, a 0.2 second update time seems long.

e)I very much hope to get the 4096 FFT work first (which I need assistance). Because it has been established, and I think it will be simpler. If the update time of 0.1 S is too long (to be tested after it is working), I would consider to use 2048 FFT. I shall study the zoom FFT option in parallel.

5. Originally Posted by FLEOX
Hi!

I've just made a quick test with the 4096FFT (using the files goldhausen has provided). It seems to work ok with the ILI9341_t3n Library (using frame buffer) I get 22 FPS.
I'm using the Audio Library and have no issues with using the 4096FFT.

In my project I would like to visualize the audio spectrum pre and post filtering (20 Hz ... 20kHz).
As you can see on the picture, my frequency-axis is not linear. I try to get better resolution especially in the lower frequency range (20 Hz ... 320 Hz), therefore the 4096FFT gets handy with a Frequency Bin resolution of ca. 11 Hz.
Although this works, I agree with DD4WH, the "ZoomFFT" would be a much better approach to solve this "low-frequency" problem.

Is there a "ready to use" ZoomFFT library available that works with the audio library?

Attachment 16937
Hi FLEOX,

I understand that you have no issue with using FFT4096. I am also using the files goldhausen has provided. FFT1024 runs with no issue, however, when I changed the FFT1024 to FFt4096, the same sketch can compile and upload but without any printout. I can't find the reason why. The following is what I have done:

1) In order to eliminate any wrong doings, I have reinstalled the Arduino (v 1.8.9) and Teensyduino (v 1.47).
2) Copied the the Analyze_fft4096.cpp and Analyze_fft4096.h file from #24.
3) Replaced the files Audio.h ; data_windows.c and keywords.txt by those in #24.
(By the way, I am still working on the Windows XP system.)

I used the sketch posted in #1 by blacktronics, only change is commented out the line "fft1.averageTogether(8);"

I should be very grateful if you could have a look at what I have done and see what was wrong.

Thank you so much.

6. AudioGrabber object for the FFT256.

Originally Posted by DerekR
A couple of suggestions:
1) In the original post it was mentioned that it was only the lower part of the spectrum that is of interest. You might try a "zoom FFT" approach (google it), and examine only what you want. This would allow you to use a smaller FFT and retain the resolution you want.

2) In order to keep the processing time low within the update time of the Audio library, I often extract the data from the internal data stream and process it in the loop() as a lower priority task. To that end I've written a set of "audioGrabbers" that assemble a given length block of Audio data (say 256 complex data elements, or 512 real data points) and then signal that a block is available. In loop() I check the "new data available" flag and then "grab" the data, and process it. I double-buffer it so that there are no data collisions while grabbing occurs. For example, I use this method for spectral analysis in my SDR (software-defined-radio) work. I currently don't have a 1024 length grabber written, but I'd be happy to throw one together for you...
Derek,
Can you pass me the audioGrabbers object for fft256 please?

7. Sure. Do you want the complex or real? Give me an hour or so... I'll upload them both on the forum under this thread.

Aside: I was getting the grabbers ready to upload as a library to GitHub three days ago when I decided to test them on the T4. And that was a huge mistake - you can read about it on the General Discussion part on the forum in my thread today about "bricking" the T4. Anyway it took 3 days to resolve the problem. It had nothing to do with my code, but was a problem with Teensyduino 1.48beta1. The solution is that if you want to use the grabbers with a T4 you must install Teensyduino 1.48beta2 which was just announced this morning!

8. Thank you Derek,

1) I want complex.
2) Timing is ok for me. I am doing it purely for my own interest, no time frame. Do it in your leisure. I am going for a month's holiday starting next week. I can read the forum via smart phone, but cannot do any testing. Hard luck.
3) I planned to buy T4 after my holiday, I would also like to have a try after I got the T4.

I have been through most of the information suggested by you and Frank, and have drawn up the following concept (Correct me if it is wrong):

a) Audio from standard Audio Library, with sampling frequency of 44.1 Khz. It can be from adc, mic, line-in or waveform generator.

b) Use a standard FFT256 from Audio Library for High frequency components.
- Resolution around (44100/2)/128 = 170 Hz
- update rate = (1/441000)*256 = 5.8 ms

c) Use another standard FFT256 from Audio Library for low frequency, with one out of 32th sampling speed.
- Resolution around (44100/2/32)/128 = 5.4 Hz
- update rate = (1/441000)*32*256 =186 ms

186 ms is a bit long, I would rather sacrify the resolution a bit to around 10 Hz, i.e.
With one out of 16 sampling speed.
- Resolution around (44100/2/16)/128 = 10.8 Hz
- update rate = (1/441000)*16*256 =93 ms ( A bit more acceptable)

However, the location of the lowpass filter is a question. It can be :

Option 1)
The low frequency FFT (LF FFT) takes every 32th sample from the same audio stream as high frequency FFT (HF FFT). The question is where to put the lowpass filter. If I put the lowpass filter before the audio stream, the HF FFT will lost the high frequency components. If we don't insert the lowpass filter, we would have aliasing problem.

Option 2)
The HF FFT takes the sample directly from the audio stream, while the LF FFT takes every 32th sample from the lowpass filtered audio stream. The system would have to sample alternatively, (because we are using one adc only) i.e. .... HF FFT 〉 LF FFT 〉HF FFT 〉 LF FFT 〉.... In this option, the update rate of the high frequency FFT is equal to low frequency FFT that is equal to the sum of the update rates of the HF FFT + LF FFT. This is not acceptable at HF FFT because when waiting for the LF FFT taking sample, data will be lost.

Any idea how to solve the above problem?

The ideal situation will be to make a audio object, with one audio stream input and with two audio stream output, one for the HF FFT and the other for LF FFT. The anti-aliasing filter to be within the object.

Thank you very much for your patience to go through such a long writing.

9. Hi everyone!
I'm sorry for the very late reply to this discussion. I was very busy the last few weeks.

Of course I will post the complete source code of my project. I've made two small code examples how I achieved my results. One of them is just a simple 4096-FFT of a sine wave .
I'm using Arduino 1.8.10 with Teensyduino 1.48 Beta #1
For getting the high display update rate I had to change the F_BUS Speed from 60 MHz to 120 MHz in the kinetis.h file.
Important to know is, that I run the Teensy 3.6 on 240 MHz CPU Speed.

For those of you who are interested in my setup:
In my project (Audio Class-D Amplifier with integrated DSP) the purpose of the Teensy 3.6 is only to visualize the audio spectrum (pre and post the processing).
The actual signal processing of the audio data gets done on a specific Audio-DSP (ADAU1401). Therefor the main clock Source of the System is the DSP not the Teensy.
The Teensy 3.6 gets the audio data via I2S in slave mode (24-Bit, 48 kHz sample rate) and converts it to a 16-Bit audio stream (by taking to 2 most significant Bytes).
The Left Channel of the I2S Stream is representing the Mono-Signal (pre processed), the right channel is used for the Mono-Signal after the DSP processing.

As you know, my goal is to get the best possible display resolution of the FFT for both Mono-Signals (pre and post processing).
I'm as well very interested in the zoom FFT or the very similar "log FFT".

Currently I still have a lot of other things to get done until I can work further on this project.
But I hope that there are some other motivated people to work on this topic!

Best regards
Florian

FFT-Display_DMA_4096_Demo.zip
FFT-Display_DMA_4096_Sinewave.zip

10. Thank you very much for you reply, Flexo.
I shall try accordingly, however, I am going for a month's holiday starting next week. I shall let keep you informed of the test result, though it may be at least one month later. Sorry about that.

11. Originally Posted by LoShu

c) Use another standard FFT256 from Audio Library for low frequency, with one out of 32th sampling speed.
- Resolution around (44100/2/32)/128 = 5.4 Hz
- update rate = (1/441000)*32*256 =186 ms

186 ms is a bit long, I would rather sacrify the resolution a bit to around 10 Hz, i.e.
With one out of 16 sampling speed.
Dont worry about the update rate: you can do the following:

for every block of 128samples:
* lowpass @689Hz
* take every 32th sample --> so you get 4 new samples for every new audio block arriving
* perform FFT256 with the 4 new samples and rest of the FFT buffer is filled with the old samples --> so you need a "moving window buffer" which is subsequently filled with the decimated samples
* that gives you resolution of 5.4Hz AND update rate as for the high frequencies

However, the location of the lowpass filter is a question. It can be :

Option 1)
The low frequency FFT (LF FFT) takes every 32th sample from the same audio stream as high frequency FFT (HF FFT). The question is where to put the lowpass filter. If I put the lowpass filter before the audio stream, the HF FFT will lost the high frequency components. If we don't insert the lowpass filter, we would have aliasing problem.

Option 2)
The HF FFT takes the sample directly from the audio stream, while the LF FFT takes every 32th sample from the lowpass filtered audio stream. The system would have to sample alternatively, (because we are using one adc only) i.e. .... HF FFT 〉 LF FFT 〉HF FFT 〉 LF FFT 〉.... In this option, the update rate of the high frequency FFT is equal to low frequency FFT that is equal to the sum of the update rates of the HF FFT + LF FFT. This is not acceptable at HF FFT because when waiting for the LF FFT taking sample, data will be lost.

Any idea how to solve the above problem?
You need two objects: the standard FFT, which analyses the high frequencies, and another object, the ZoomFFT object. Both receive the same audio stream and process it independently from each other. Or, like you proposed:
The ideal situation will be to make a audio object, with one audio stream input and with two audio stream output, one for the HF FFT and the other for LF FFT. The anti-aliasing filter to be within the object.

12. @LoShu -As you requested I have attached a zip file Grabber256.zip containing two "grabbers":
1 AudioGrabberComplex256
2 AudioGrabberReal256
in separate folders, each with a simple example of their use.

I have several other variants, in buffer lengths and in function, and I'm currently preparing them for upload to GitHub.
Let me know if you have questions.

Derek

13. Hi Frank,

Thanks a lot for your response. I am sorry that I have missed that point that the "moving window buffer" can solve the updating rate problem. I shall go ahead for a trial. I shall come back to you in case I encounter any problem.

By the way, I would still like to clarify one point:

You mentioned:
"
every block of 128 samples:
* lowpass @689Hz
* take every 32th sample --> so you get 4 new samples for every new audio block arriving
* perform FFT256 with the 4 new samples and rest of the FFT buffer is filled with the old samples
"

I think for FFT256, every block should have 256 samples. Shall get 8 new samples for every new audio block arriving for "moving window buffer".

Thanks.

14. Hi Derek,

Thank you very much for the files. I shall study in detail and would come back to you again if I need any clarification.

Posting Permissions

• You may not post new threads
• You may not post replies
• You may not post attachments
• You may not edit your posts
•