B4A Library FFT Fast Fourier transform library

A new B4X FFT library does exits, the library in this thread is only valid for B4A.

The ownership of this post has been changed by Erel from agraham to klaus, with agrahams agreement, to allow me to edit this post with the update of the FFT library.

agrahams original text.
About nine months ago Klaus and I collaborated on a Basic4ppc library and demonstration program to perform forward and inverse Fast Fourier Transforms.

We have collaborated once again to port the library and demo to Basic4android.


Update 2014.08.03
The library has been updated after the bug report here.
The demo program has been 'rewritten' to take advantage of the B4A improvements since december 2010.
 

Attachments

  • FFT_lib_V1_2.zip
    4.7 KB · Views: 1,018
  • FFTDemoV1_2.zip
    25 KB · Views: 937
  • Time1.png
    Time1.png
    51.7 KB · Views: 1,205
  • FFT1.png
    FFT1.png
    47.4 KB · Views: 1,103
  • List.png
    List.png
    72.8 KB · Views: 1,031
Last edited:

daniel69

Member
Licensed User
Longtime User
Not in a near future.
I will look to make a Class, no time schedule, I don't have the knowledge to write libraries.

Just to be clear, the library was written by Andrew Graham (agraham).
I made a small change in the library, and as Andrew is now less active in the forum Erel changed the ownership of the first post from agraham to mine (with Andrews agreement) to let me update the first post.
I wrote the demo program.

Thanks Klaus ... I'll try to make a post in the forum (in the B4i wishlist forum)
 

sorex

Expert
Licensed User
Longtime User
@klaus : can we use this lib on a returned soundbuffer to display a waveform or frequency bars? (from the MIC or stream)

or will it be too slow?
 

klaus

Expert
Licensed User
Longtime User
can we use this lib on a returned soundbuffer to display a waveform or frequency bars?
Waveform no.

Frequency bars, I don't know, I have never tested it.
It depends also on the number of time signal items you want to take into account.
 

NeoTechni

Well-Known Member
Licensed User
Longtime User
Using another library on this site somewhere to get the audio data in real time, I use this to get the frequency bars

B4X:
Type Histogram(Values As List, Highest As Int, Inc As Int)
	Dim TimeMin As Double=1000000,TimeMax As Double =-1000000, FFTMax As Double ,  FFTLimit As Double, FFTThreshold = 0.8 As Double, N_Samples As Int , CursorScaleFreq As Double , FFTprev As Int 
	Dim FFT1 As FFT

Sub RecData2Histogram(SampleRate As Int, recData() As Short) As Histogram ', recData() As Double =  fft1.CopyArray(srcData)
	Dim tempHist As Histogram ,  soundD() As Double = CopyRecDataD(SampleRate, recData), N_2 As Int = soundD.Length * 0.5 ,FFTPeaks As List 
	Dim FFTReal(N_2) As Double, FFTImg(N_2) As Double, FFTAmp(N_2) As Double
	
	tempHist.Initialize 
	tempHist.Values.Initialize 
	
	FFT1.Transform2(soundD, FFTReal, FFTImg )
	FFTAmp = FFT1.ToAmplitude(FFTReal,FFTImg)
	PeakDetect(FFTAmp)
	
	tempHist.Inc = 1
	tempHist.Highest = FFTMax' TimeMax
	tempHist.values.AddAll(FFTAmp)
	
	Return tempHist
End Sub
 

daniel69

Member
Licensed User
Longtime User
Hi Klaus!! Let me know when you start to make the ios class of this project ... badly need it ...
 

padvou

Active Member
Licensed User
Longtime User
Thank you very much for the library and the test project posted.
Could you please help me figure out why I get this?
B4X:
** Activity (main) Create, isFirst = true **


** Activity (main) Resume **


Start Recording


Sampling...


32768


AR state: 1


java.lang.RuntimeException: FFT: Real and Imaginary arrays are incorrect length!


    at anywheresoftware.b4a.agraham.fft.FFT.Transform2(FFT.java:253)
    at b4a.example.main._initcalulation(main.java:739)
    at b4a.example.main._btncalc_click(main.java:458)
    at java.lang.reflect.Method.invokeNative(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:515)
    at anywheresoftware.b4a.BA.raiseEvent2(BA.java:175)
    at anywheresoftware.b4a.BA.raiseEvent2(BA.java:163)
    at anywheresoftware.b4a.BA.raiseEvent(BA.java:159)
    at anywheresoftware.b4a.objects.ViewWrapper$1.onClick(ViewWrapper.java:66)
    at android.view.View.performClick(View.java:4424)
    at android.view.View$PerformClick.run(View.java:18383)
    at android.os.Handler.handleCallback(Handler.java:733)
    at android.os.Handler.dispatchMessage(Handler.java:95)
    at android.os.Looper.loop(Looper.java:137)
    at android.app.ActivityThread.main(ActivityThread.java:4998)
    at java.lang.reflect.Method.invokeNative(Native Method)


    at java.lang.reflect.Method.invoke(Method.java:515)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:811)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:627)
    at dalvik.system.NativeStart.main(Native Method)
java.lang.RuntimeException: FFT: Real and Imaginary arrays are incorrect length!
 

padvou

Active Member
Licensed User
Longtime User
Using another library on this site somewhere to get the audio data in real time, I use this to get the frequency bars

B4X:
Type Histogram(Values As List, Highest As Int, Inc As Int)
    Dim TimeMin As Double=1000000,TimeMax As Double =-1000000, FFTMax As Double ,  FFTLimit As Double, FFTThreshold = 0.8 As Double, N_Samples As Int , CursorScaleFreq As Double , FFTprev As Int
    Dim FFT1 As FFT

Sub RecData2Histogram(SampleRate As Int, recData() As Short) As Histogram ', recData() As Double =  fft1.CopyArray(srcData)
    Dim tempHist As Histogram ,  soundD() As Double = CopyRecDataD(SampleRate, recData), N_2 As Int = soundD.Length * 0.5 ,FFTPeaks As List
    Dim FFTReal(N_2) As Double, FFTImg(N_2) As Double, FFTAmp(N_2) As Double
   
    tempHist.Initialize
    tempHist.Values.Initialize
   
    FFT1.Transform2(soundD, FFTReal, FFTImg )
    FFTAmp = FFT1.ToAmplitude(FFTReal,FFTImg)
    PeakDetect(FFTAmp)
   
    tempHist.Inc = 1
    tempHist.Highest = FFTMax' TimeMax
    tempHist.values.AddAll(FFTAmp)
   
    Return tempHist
End Sub

Hello and thank you for posting this code.
How is this implemented in a project?
I mean I would like to get the frequency of a tone recorded by the device mic.
 

padvou

Active Member
Licensed User
Longtime User
Thank you very much for the library and the test project posted.
Could you please help me figure out why I get this?
B4X:
** Activity (main) Create, isFirst = true **


** Activity (main) Resume **


Start Recording


Sampling...


32768


AR state: 1


java.lang.RuntimeException: FFT: Real and Imaginary arrays are incorrect length!


    at anywheresoftware.b4a.agraham.fft.FFT.Transform2(FFT.java:253)
    at b4a.example.main._initcalulation(main.java:739)
    at b4a.example.main._btncalc_click(main.java:458)
    at java.lang.reflect.Method.invokeNative(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:515)
    at anywheresoftware.b4a.BA.raiseEvent2(BA.java:175)
    at anywheresoftware.b4a.BA.raiseEvent2(BA.java:163)
    at anywheresoftware.b4a.BA.raiseEvent(BA.java:159)
    at anywheresoftware.b4a.objects.ViewWrapper$1.onClick(ViewWrapper.java:66)
    at android.view.View.performClick(View.java:4424)
    at android.view.View$PerformClick.run(View.java:18383)
    at android.os.Handler.handleCallback(Handler.java:733)
    at android.os.Handler.dispatchMessage(Handler.java:95)
    at android.os.Looper.loop(Looper.java:137)
    at android.app.ActivityThread.main(ActivityThread.java:4998)
    at java.lang.reflect.Method.invokeNative(Native Method)


    at java.lang.reflect.Method.invoke(Method.java:515)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:811)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:627)
    at dalvik.system.NativeStart.main(Native Method)
java.lang.RuntimeException: FFT: Real and Imaginary arrays are incorrect length!

Would the following do the trick?
B4X:
Public N = 16384 As Int
    Public N_2 = N / 2 As Int
   
    Public soundD(N) As Double

    Public FFT1 As FFT
    Public FFTReal(N_2+1) As Double 'added +1
    Public FFTImg(N_2+1) As Double 'added +1
    Public FFTAmp(N_2) As Double
 

klaus

Expert
Licensed User
Longtime User
@padvou
Sorry for answering only today, but I was on travel for a week so no B4x.
The declarations must be:
B4X:
Public N = 16384 As Int
Public N_2 = N / 2 As Int
Public N_21 = N_2 + 1 As Int
Public soundD(N) As Double
Public FFT1 As FFT
Public FFTReal(N_21) As Double
Public FFTImg(N_21) As Double
Public FFTAmp(N_21) As Double
' Public FFTPhase(N_21) As Double
for use with Transform2 and Inverse2.
 
Last edited:

padvou

Active Member
Licensed User
Longtime User
@klaus
Thank you very much for responding to me.
Could you please also tell me what this is:
The second Spinner allows to change the threashold for peak detection
What is the threshold for peak detection?
 

Medel

Member
Licensed User
Longtime User
Hi, my name's Luis, i've been trying to use the FreqDetect.zip but i get the error:
"An error has occurred in sub: java.lang.RuntimeException: FFT: Real and Imaginary arrays are incorrect lenght! Continue?"

I also tried the FFT_Freq_Detect and i also get the same error...

This is the sound file that i've been using to check if the frequency is correct:


Does anyone have the same error? any suggestion? Thanks for any tip in advance
 

Medel

Member
Licensed User
Longtime User
Hi again, i've solve my problem reading the past post from Klaus, just change it like in the picture.

Thanks Klaus and Graham, awesome work!!!
 

Attachments

  • just change this.png
    just change this.png
    163.5 KB · Views: 296

techknight

Well-Known Member
Licensed User
Longtime User
I like your FreqDetect Zip, but I need to modify it somehow and I am not sure how.

I dont need graphs or anything, but what I do need is realtime monitoring of the mic for frequency peaks and amplitudes. Then I have a stored list with the certain frequencies and amplitudes stored, soon as I hit a match between stored list and FFT list, it fires an event.

Your FFT program can basically do that, but it requires "recording" which I dont want. I need realtime live monitoring so the instant the sound is heard, analyzed, then matched it fires an event. Event runs, and then it keeps on moving until its heard again.
 

techknight

Well-Known Member
Licensed User
Longtime User
Just tried the FFT detect and I dont think it works. Both of my phones keep showing the same 3 peaks, no matter if the room is silent or if I am playing something, plus I have to keep hitting record over and over. its NOT realtime!

any thoughts???

Peaks are 500.65, 899.1, and 1300.7 no matter what.
 
Top