Tuesday, January 17, 2012

FFT based simple Spectrum Analyzer with Source Code

i am writing this blogpost to pay homage to my alma mater... i was not at my level best to understand all aspects of Electonics & Telecommunication, the Microprocessor, the Digital Communication, the Digital Signal processing as taught by my professors... however, after so many years while playing around with different software, i understand how valuable was their contribution to make me an engineer. i remember, how important was the lesson of digital communication, and digital signal processing taught by Dr. T.K.Sen... i remember how important was the lesson of Microprocessor taught by A.R.... i remember how important was the lectures of Maths during our engineering course... i remember how important were the concepts of Fourier Transformation, FFT, DFT, Laplace Transformation, Matrix algebra and Complex Algebra...Hats off to all those professors who in spite of all odds helped a small town boy see the outer world...

You can install this FFT based simple Spectrum Analyzer with a sampling frequency of 8 KHz and audio encoding as 16 bit PCM from google play at https://play.google.com/store/apps/details?id=com.somitsolutions.android.spectrumanalyzer
i was so excited when i finished the coding part (of course with the help of Google...) and saw its working on a real device...

here are the a screenshot i have taken from an Android device...


and here (https://gitlab.com/som.mukhopadhyay/FFTBasedSpectrumAnalyzer) goes the source code which may help someone interested in Android...

33 comments:

Unknown said...

hi! thanks for sharing your code with us who also need and interested with this FFT based project. Is it okay if I ask you a question? Since I am very new in Android and doesn't have much knowledge in programming, I would like to ask you If is it possible to also extract the voice from which I utter through your project? Because I have seen and tried your code and it's a perfect step toward the project which I am trying to make. I plan to get the pitch and tone from voice then implement a feature extraction algorithm to match to the corresponding features I want to attain. Is it possible? your help will truly be appreciated! :)

Unknown said...

and oh I forgot also to ask where did the audio goes? here in your project? what happened to the voice which I utter? thanks again and sorry for asking so much :)

Somenath said...

see the function AudioRecord. This android function actually converts your Audio data in some discrete form using Pulse Code Modulation (remember Nyquist theory of Sampling) and stores in a buffer the size of which we calculate using the AudioRecord.getMinBuffersize function. These discrete values are then passed through a library function called RealDoubleFFT.ft to get the fourier co-efficients. These co-efficients are then plotted in the graph. So, in short to answer your question your voice goes to a buffer of discrete values.

Unknown said...

Sorry to bother, can I ask what's the use of different classes you have made under the ca.uol.aig.fftpack package especially the
RealDoubleFFT_Mixed.java class. What are those many letters was for? Great work by the way. thanks for sharing!

Mike said...

Hi! Could I ask why it's necessary to divide each element of buffer array by 32768.0? Where did this nuber came from?
Line 85 of SoundRecordAndAnalysisActivity.java

Mike said...

... hmm I believe I've added 3 coments instead of 1 by mistake. Sorry :(

Mike said...

Sorry for bothering you again. Of course 32768 came from 16 bit int maximum size... Wake up brain! Ehh...

Somenath said...

@Mike, its a scaling factor. as we have taken 16 bit PCM, if we divide each element by 2 to the power 15, the values that will be fed to the FT function will vary from 0 to 1...

Devarun Bhattacharya said...
This comment has been removed by the author.
Unknown said...

I used both this and "Pro android Media" but I think this works better.
But when I touch a button for stop and touch one more for restart, the spectrum usually goes down - it lives less than 5 seconds and doesn't work -.
Could you give me an answer about the matter?

Somenath said...

@Hwan it is working in the same manner in my device as well. once you start the app and rotate you will have to press the start-stop-start button. then it works. i will look into the matter.

Unknown said...

@Somenath Yes, I just press button one more time and it changed start-stop-start. However it still doesn't work. I wonder if you are cell is different with me. My cell is Galuxy III and the system version is 4.1.2(Jelly bean) I can show you the screenshot and I appreciate to you if you show it.

Somenath said...

@Hwan, my device is Samsung Galaxy Y having Android 2.3.6. However, i would like to say you that i tested this app earlier on a different Galaxy Y phone which i think had Android 2.1 or 2.2 and it worked perfectly there. I am not sure what is happening. anyway i will look into the matter.

Unknown said...

I got it what you mean but maybe I should read the project more time. And if you okay, please visit my blog (http://myconfession.tistory.com/139) and see the screenshot. thanks~

Unknown said...

Hi, Somenath Mukhopadhyay.
Thank for your sharing.
It's so good.
Is it ok if I ask you a question?
Instead of showing the frequency on the "imageView1"?
Is there any way to save as file?
And as you know, is there any way to company the frequency based on Spectrum Analyzer?
I will appreciate much if you can help me.

Thank you,
Thomas

Somenath said...

@Hữu Tài Lê see this link

http://stackoverflow.com/questions/9078715/how-to-save-a-bitmap-image-with-imageview-onclick

Mobility Talk said...

Thank you so much..This code helping me lot..Can you please present the detailed tutorials...

Omer Ahmed said...

You was a great help! Thanks :)

Unknown said...

Dear Sir,
It is great to see your code. I'm an Android beginner and I would like to make an App to detect audio frequency up to 20Khz. Your code is really helpful. I find the int frequency 8000 is limited to audio input of 4Khz. In case of detect up to 20Khz, I change the int frequency from 8000 to 16000 and works fine for audio up to 8Khz. But when set frequency to 40000 ( bcoz I want to detect max 20KHz ), the screen cannot show the graph. Could you please advise how I can modify the code to achieve such wider range frequency ? thank you very much in-advance.

Somenath said...

@Keith, i think at present the maximum sampling frequency supported by Android is 44.1 khz. hence according to the nyquist theorem the maximum audio frequency it can support is approximately 22 khz. however, it all depends on the actual hardware device. i am not sure which device you are using. but please do a bit research on your device capability vis-a-vis audio frequency.

Putri Utami said...

Hi!
I also doing this kind of project. Do you know how to make graphics that contain value of frequency as x axis and value of sound level as y?
thank you ^^

Putri Utami said...

Hi!
thank for sharing your code! this really helpful, but do you know how to get the frequencies in this project and make a graphic that draw the frequencies as x axis and sound level as y?

Putri Utami said...

Hi! thanks for sharing your code! this really helpful. I want to get the frequency value from recording and draw graphic with frequencies as x axis and sound level as y, do you know how to do that? I hope you can help me..
Thanks..

Unknown said...

Hi! thank you a lot for the code! :)
i would like to know how it is possible to get the frequency of a note played with an instrument... with this code i can display its graph, but what about the frequency?

Somenath said...

Hi everybody... my laptop is not functioning... hence the delay for this comment... for all who want to extract the frequency from the FFT co-efficients look at this post look

here

hope this helps...

DEXTER said...

Hi Somenath,
Thanks for sharing your code. Can you help with pitch detection, I am trying to use it to detect the guitar note/chord

Thanks
Dexter

Neetha said...

Hi Somenath,

Thanks for this code! I run it on my phone and it works perfectly, but when I put a break point after AudioRecord.read() call, and then run the App through my phone, I see no values coming into the returned array in Eclipse (all values are 0.0). Do you know why this is happening? Can you please guide? I am using a similar code in my App and am facing this issue! Any help or suggestion will be appreciated.. Thanks alot for the code again :)

Jagmohan said...

Hi Somenath,

Thanks for the code. It works fine on my phone. I would like to know how to take inverse fft of toTransform. Also what are the real and imaginary coefficients of the fft contained inside toTransform.

I will greatly appreciate your input on this.

Thanks & Regards,
Jagmohan Singh

Ashish said...

Hello Somenath,

Thanks for this informative post and the code.
I am new with Android. I downloaded the project from Git and tried to import it in Android studio, but the import failed. Could you please let me know if I am missing anything?

Anonymous said...

Interesting, I can't seem to se a link to the code, would really like to have a look for a research project, but can seem to find the link.

Anyone still have a link or does this still function?

Somenath said...

@Thomas Bodetti, the link is at the end of the discussion... anyway, here i am giving it again...

Spectrum Analyzer

Unknown said...

Great!

Can I ask what is the meaning of negative value after doing FFT? Is it an imaginary part? Thanks.

Somenath said...

@Nathan Jenifer... Please have a look at the following link. You will get the answer...

http://dsp.stackexchange.com/questions/431/what-is-the-physical-significance-of-negative-frequencies