# B4A Class [B4x] FFT class

Discussion in 'Additional libraries, classes and official updates' started by klaus, Apr 25, 2017.

This class performs Fast Fourier Transformations forward and inverse.
The class is exactly the same for B4A, B4i and B4J.

A FFT library already exists, but only for B4A.

A Fast Fourier Transformation transforms a signal from its original domain (mostly the time domain) into its representation in the frequency domain.

The number N of samples in the original domain must be a power of 2?
Examples: 256, 1024, 2048, 4096 etc.

In theory, the source signal must have a real and an imaginary part.
In time signals the imaginary samples are all 0, this is treated internally in the class, no need to transmit them.
The result of an FFT is two signals real and imaginary.
Which can also be represented by magnitude and phase.

In concrete applications, the magnitude of the frequency signal is mostly used, therefore the Forward method returns the Magnitude.
The phase, real and imaginary signals can be accessed as properties.

Methods:

Forward(Real() As Double) As Double() performs a FFT calculation
Real = an array of N Doubles representing the Real time signal.
Returns the Magnitude of the frequency domain N/2 + 1 samples.

Inverse(Real() As Double, Imag() As Double) As Double() performs an inverse FFT calculation
Real = an array of N/2 + 1 Doubles representing the real part of the frequency signal.
Imag = an array of N/2 + 1 Doubles representing the imaginary part of the frequency signal.
Returns the inverse frequency real signal, N samples.

Properties:

Magnitude = magnitude of the frequency signal N/2 + 1 samples, read only.

Phase = phase of the frequency signal N/2 + 1 samples, read only.

Real = real part of the frequency signal N/2 + 1 samples, read only.

Imag = imaginary part of the frequency signal N/2 + 1 samples, read only.

ModeDegrees = True (default), the phase signal is in degrees otherwise in radians.

Window = NONE or Hann, applies no window or a Hann window.

Demo programs:

Attached a demo project for each product B4A, B4i and B4J, they all include the FFT class which is the same for all three.

The program can:

Calculate different input signals.

Calculate forward and inverse FFTs.

Display the different signals.

Apply a Window.

For Android phones and iPhones tap on the chart to show the menu.

On Android and iOS tablets and in the B4J project the menu is always visible.

Concrete B4A application: FFT_Record

The program reads the microphone signal.

Switch between Time and FFT

Generate a sound composed of three frequencies: 500, 1000 and 2000

Change the scale up and down

Display the signal values when moving the finger over the diagram.

#### Attached Files:

File size:
12.4 KB
Views:
122
File size:
6.9 KB
Views:
43
File size:
7.1 KB
Views:
86
• ###### FFT_Record.zip
File size:
54.3 KB
Views:
140

Hi @klaus

Great job as usual !

Compared to the library (which is only for B4A) is there any improvment (performance or something else) ?
JP

Great work Klaus!

@freedom2000
I haven't made speed comparisons between the two.
The main goal was to have FFT for the three products.
You could make libraries with the class, I don't know if there would be speed improvements.

freedom2000 likes this.

Thank you Klaus..
Great work that will help a lot in some of my projects.

I am trying to understand how FFT_Record works and modifying it for saving (not displaying) FFT data to a file.

I see that you are calling the sub Record with a timer every 300ms
Code:
`Timer1.Initialize("Timer1", 300)...Private Sub Timer1_Tick    RecordEnd Sub`
But in the Record Sub you exit from the While loop only after 500ms
Code:
`If DateTime.Now > StartTime + "500" Then Exit`
What does that mean?
The FFT is calculate over 300ms or 500ms chunk?

It is a TimeOut limit.

When i click on the "Go" button it sets StartTime so on the first execution of the Do While it exits after 500ms, but in the following Do While it exits immediately because StartTime is never set anymore.
I feel confused, why Does that Timeout limit is needed?

Thank you

I tested it again and the timeout is only necessary for the first time.
Without this line the program hangs in the While/Do loop.
Don't ask me why, I found this as a workaround and it works.

Last edited: Feb 3, 2019

Yes you are right, the loop must have a condition for exiting from the loop. But if you remove the loop the program still works correctly:

Code:
`'Do While True        sound = AR.ReadShort(0, BufferSize)        DataSize = DataSize + sound.Length                       'If DateTime.Now > StartTime + "500" Then Exit 'Loop`
I think the loop it is only needed in the original code of Audiorecord example bacause it records for 10 seconds and it need to check during the loop execution if the program already recorded for 10 seconds or not.
But in this case you call the sub Record every 300ms so you don't need any other loop for getting data from the audio source.

klaus likes this.

Thank you, Klaus, for sharing this great library.
Is it possible to calculate one main frequence of a pitch, from the array? It could be very usful for a music intrument tuner.

What exactly do you mean?
Detect frequency peaks?
Is THIS what you are looking for, it's a B4A project?
I haven't updated this project with this class.

I think the frequency peak is not enough to calculate the accurate basic frequence (in your sound file of the FFT-Record sample it is 500 Hz). I need an output that gives me only the basic pitch, but with even 1 Hz difference (499 Hz, 500 Hz, 501 Hz) accuracity. Do you think it is possible with FFT? Yes, it's a B4A project.

Sorry, but I still don't understand what exactly you want to do.
What exactly do you mean with only the basic pitch?
If you want a frequeny increment (accuracy) of 1Hz, the duration of the time signal must be 1 second.
Which means 44100 time samples.
But the number of samples for FFT must be a power of 2.
So at least 32768 samples which represents 0.743 second therefore a 1.346 frequency increment (accuracy).

What I want to do is a kind of guitar tuner. You play the pitch "a", this is 440 Hz. If you play 441 Hz the tuner will tell you, to tune the guitar a bit lower. Thats why I only need the fundamental frequency (in that case 440 Hz) and not the overtone (which would be in that case 880 Hz, ...). I could calculate the peak of the FFT array, but I think it is not good enough, to detect small differences between 440 Hz and 441 Hz. I now allready wrote an algorythm, which seems to work. I can public it, if someone is interested...

I would be interest in.

Here is my small first tuner project. It analyzes the fundamental frequency of a soundwave in two steps:
1. findig the first periode in the wave and creating an array with periode positions
2. comparing the first periode with later periodes and calculating the accurate wavelenght
I tested with piano, clarinet and singing. Piano and clarinet worked fine, singing sometimes, but this is more my voice than the algorythm.
Anyhow I would be glad, if somebody has a better solution. As a musician I would have some ideas, how to make better tuners, more practical in orchester. But at first I need a good and stabil calculation of the fundamental frequency.

#### Attached Files:

• ###### Tuner.zip
File size:
410.8 KB
Views:
48

Nice piece of work!
I tested it quickly with my guitar and it seems to work fine although I need some more time to check if tuning up or tuning down is suggested correctly but it seems to do that fine. I used to tune my guitar by ear once but I have lost that "ability" for now, probably because I have not been playing for years.
Just for fun, I tried it also with electric piano (always tuned) and it detected tones correctly.
Keep up the good work and if you decide to publish it on Google Play, please let us know!

What regards the coding, this stuff is a bit over my head and I am sure there are other users who can suggest improvements if needed. In my opinion, it worked already very fast.