Go Down

Topic: FFT on Arduino, the audio spectrum is cluttered? (Read 18740 times) previous topic - next topic

aidvllasaliu

Hello guys!

I have been tackling this problem for a long time now and didn't want to be a burdon to anyone, hence I never really
posted any question about this in the forum earlier.

So basically, I downloaded both the FFT and FHT libraries from Open Music Lab's website.

I hooked my Arduino Uno to the computer, hooked an audio input (my computer's audio out) to the arduino,
and did a Sine wave sweep test.

I was expecting some results like the gentleman in the video below achieved, but I can't get the same results.

I have tried both the FFT and FHT library original examples (no modifications), both give me the same results on Arduino Uno, Mega 2560, Mini 05 and Sparkfun pro Micro 16MHz.

Can anybody help me with this?

Mr Chris Roberts demonstrates his results in his video:
http://www.youtube.com/watch?v=tOEyceIypHI

My results look like this:
http://www.youtube.com/watch?v=560xoI_M7Cc

And I would like to have results looking like this:
http://www.youtube.com/watch?v=5fXaMQTWVmg


Basically what I want is a clean spectrum.

EDIT: I have searched the web, searched the forum, tried to modify the code. Nothing changes anything. Still get the same results.

robtillaart

Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)


robtillaart

Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

DVDdoug

FFT is beyond my mathematical & programming abilities... 

I've never seen a perfect FFT spectrum.   It's my understanding that it theoretically takes an infinite number of samples and in infinitely-long unchanging signal to get a perfect result.    In the real world, a window of a certain number of samples it taken (representing a small amount of time).    There's a discontinuity where the window starts & stops, so there are various window shaping and window overlapping algorithms to compensate.   These all have various compromises. 

The bit depth and sample rate may also affect FFT accuracy (or sample rate may just be a different way of thinking about window size).

Magician

Haven't try Open Music software, but looking at video #2, I'm sure  you have a problem in this part:
Quote
I hooked my Arduino Uno to the computer, hooked an audio input (my computer's audio out) to the arduino,
and did a Sine wave sweep test.
How exactly you connect audio input? Video shows great amount of DC and all harmonics above 2-nd, which is remarkable indicator  that sampling heavy distorted.  Show your connection diagram.

aidvllasaliu


your FFT shows all harmonics I think!


Yes I think so too!


FFT is beyond my mathematical & programming abilities... 

I've never seen a perfect FFT spectrum.   It's my understanding that it theoretically takes an infinite number of samples and in infinitely-long unchanging signal to get a perfect result.    In the real world, a window of a certain number of samples it taken (representing a small amount of time).    There's a discontinuity where the window starts & stops, so there are various window shaping and window overlapping algorithms to compensate.   These all have various compromises. 

The bit depth and sample rate may also affect FFT accuracy (or sample rate may just be a different way of thinking about window size).


I see!
As long as I can differentiate frequencies from each other, that's all I need.


Haven't try Open Music software, but looking at video #2, I'm sure  you have a problem in this part:
Quote
I hooked my Arduino Uno to the computer, hooked an audio input (my computer's audio out) to the arduino,
and did a Sine wave sweep test.
How exactly you connect audio input? Video shows great amount of DC and all harmonics above 2-nd, which is remarkable indicator  that sampling heavy distorted.  Show your connection diagram.


Basically:
Arduino > USB
Computer Audio Out Ground > Arduino Ground
Computer Audio Out Left > Arduino Analog 0

pito

In order to get a "perfect" FFT spectrum:
1. you must use an anti-aliasing filter at the ADC input
2. you have to use a "FFT window" function applied over your input data, there are at least of dozen of various ones (see wiki)
3. you have to average many FFT spectra, the accuracy with S spectra is sqrt(S) with FFT
4. you have to cut off the spectral lines from N/2..N (N - number of input samples)
5. you have to use floating point math with FFT
Happy ffting :)

jremington

#8
Mar 13, 2014, 10:07 pm Last Edit: Mar 14, 2014, 03:40 am by jremington Reason: 1
Keep in mind that with 10-bit sampling, the highest frequency that can be "minimally" sampled by the Arduino (according to the Nyquist Theorem) is about 4.8 kHz. If any frequencies higher than 4.8 kHz are present in the input to the FFT, the result will show strong aliasing, which show up as signals of frequency (4.8 - f kHz).   So, as f increases above 4.8 kHz, the aliased peak in the spectrum moves down. This aliasing effect is very clearly shown in the first video that you posted. Much of the distortion or clipping in the signal shows up as aliasing.

DC signals, necessarily present initially because the ADC samples only from 0 to 5 V (or 3.3V), show up as strong peaks in the lowest bins, unless you subtract off the DC average before transforming.

Also, you don't say what representation of the spectrum you are displaying. If it is a log scale power spectrum, the large peaks in the spectrum are compressed downwards and there will always be a noise level visible.

aidvllasaliu


In order to get a "perfect" FFT spectrum:
1. you must use an anti-aliasing filter at the ADC input
2. you have to use a "FFT window" function applied over your input data, there are at least of dozen of various ones (see wiki)
3. you have to average many FFT spectra, the accuracy with S spectra is sqrt(S) with FFT
4. you have to cut off the spectral lines from N/2..N (N - number of input samples)
5. you have to use floating point math with FFT
Happy ffting :)


Haha, yeah "happy"...


Keep in mind that with 10-bit sampling, the highest frequency that can be "minimally" sampled by the Arduino (according to the Nyquist Theorem) is about 4.5 kHz. If any frequencies higher than 4.5 kHz are present in the input to the FFT, the result will show strong aliasing, which show up as signals of frequency (f - 4.5 kHz).   This aliasing effect is very clearly shown in the first video that you posted. Much of the distortion or clipping in the signal shows up as aliasing.

DC signals, necessarily present initially because the ADC samples only from 0 to 5 V (or 3.3V), show up as strong peaks in the lowest bins, unless you subtract off the DC average before transforming.

Also, you don't say what representation of the spectrum you are displaying. If it is a log scale power spectrum, the large peaks in the spectrum are compressed downwards and there will always be a noise level visible.


Hmmmmm...

But how come my aliasing is so strong?

I'm not so worried about noise, it can always be filtered out somehow.

So... do you guys have any suggestion on how fix this issue?

Other people get clear results except me  =(

4.5 Khz is more than enough for my applicaton.

I know spoon-feeding with code isn't anything anybody wants to do,
but could anyone at least try the Open Music Lab libraries and see what results you get?

As I said before, I have tried to modify the code, but the results are pretty much the same,
so using the original examples should be fine, so that we can get a good reference.

Magician

Quote
Computer Audio Out Ground > Arduino Ground
Computer Audio Out Left > Arduino Analog 0
Don't. You are not only getting wrong results, but potentially could destroy your arduino.  Here is right way to feed AC to analog input:
http://interface.khm.de/index.php/lab/experiments/arduino-realtime-audio-processing/

el_supremo

The number of bits in a sample does not determine the minimum or maximum sampling frequency. It determines the quantisation signal-to-noise ratio which for a sample of B bits is approximately 6*B dB.
The reason that, on a Uno or similar processor, the audio is limited to about 4.5kHz is because about the fastest you can sample the ADC is 9kHz.

Pete
Don't send me technical questions via Private Message.

jremington

#12
Mar 14, 2014, 02:45 am Last Edit: Mar 14, 2014, 03:44 am by jremington Reason: 1
@Pete: On the Atmega-based Arduino, the number of bits per sample does determine the upper sampling frequency. If you choose 8 bit sampling, then you can sample at about 40 kHz, with a 20 kHz upper frequency (Nyquist limit).

@OP: If you want to see what the FFT is capable of, you have to make certain of your input signal. A mathematically pure, single tone (unachievable in practice) will give a single sharp peak. You can approximate this by feeding the FFT input with a precalculated sine wave, pretending that it came from the ADC and see what happens. As it is, your actual audio signal probably is quite noisy and distorted.

aidvllasaliu


@Pete: On the Atmega-based Arduino, the number of bits per sample does determine the upper sampling frequency. If you choose 8 bit sampling, then you can sample at about 40 kHz, with a 20 kHz upper frequency (Nyquist limit).

@OP: If you want to see what the FFT is capable of, you have to make certain of your input signal. A mathematically pure, single tone (unachievable in practice) will give a single sharp peak. You can approximate this by feeding the FFT input with a precalculated sine wave, pretending that it came from the ADC and see what happens. As it is, your actual audio signal probably is quite noisy and distorted.

I tried something like that and the FFT worked fine!



Quote
Computer Audio Out Ground > Arduino Ground
Computer Audio Out Left > Arduino Analog 0
Don't. You are not only getting wrong results, but potentially could destroy your arduino.  Here is right way to feed AC to analog input:
http://interface.khm.de/index.php/lab/experiments/arduino-realtime-audio-processing/



Great success!

I followed the diagram as showed in the link and it all works fine now, just as expected!

Allthough I replaced the 100k resistors with 120k, the 10k resistor with 8.2k and the 4.7nF capacitor with 1uF.

Thanks you so so much!!!!

Here's the results in the following video:
http://www.youtube.com/watch?v=7QG74MYQsDM

BTW: as you can see in the video, the frequency response if VERY good. it recognizes frequencies up to 20 KHz  :smiley-eek:
I know it is good but why? You guys told me only 4.7 KHz would b recognizable???

Thanks a LOT to EVERYONE!

I'll be coming back for more questions so that I can fine tune this project and eventually upload my project so that more people can have good use of it  XD

aidvllasaliu

Ok, so now I have modified the FHT code a little bit.

I hooked the audio signal to A1, and it turns out that most of the unwanted signal is being leaked to A0.
So I thought why not take the leaked signal in A0  and remove it from A1 as noise cancellation.

After testing out all of the Analog inputs I noticed that the Unwanted signal is being leaked throughout all of the
analog inputs, but the music itself is less noticable the further away you go from the noise reference input.
So I connected the Audio signal to A5 instead, and use A0 as noise reference.

Works pretty good :D

Ok, now I will create a new thread regarding other things about FFT.

Once again guys, thank you a lot!

The cluttering is fixed Magician  :D

I attached my sketch so you can try it out for yourself :)

Go Up