B4A Library FFT Fast Fourier transform library

merlin2049er

Well-Known Member
Licensed User
Hey, that's neat.

Someone emailed me about developing an arduino sketch that would decode an audio string (of characters) thru a devices speaker, then then re-interpret them on the other devices mic and display the string.

ie, like chirp-io. I have no idea if the arduino would be able to pull off this in real-time. I suggested maybe switching to something like a raspberry pi, and was waiting for chirp-io to release it's api.

Good thing is there was no deadline. lol. I'll see if I can get something like this done on the android.
 
Last edited:

Marcob

Member
Licensed User
Hi,
I've tested this library and according to the results it seems that the input samples are internally windowed before running the FFT algorithm. Is there anyone that knows what kind of window function it is used here ?
 

Marcob

Member
Licensed User
There is no windowing in the library.
This is very surprising. In my test I entered a pure sine wave signal to the mic input and I observed the graphical FFT response.
I tried with different frequencies but in any case there is no evidence of the leakage effect, the graphs show always a clear simmetric shape. This is a behavior typical of windowed samples...I wonder how that could be got without a proper weighting of the input.
 

klaus

Expert
Licensed User
Without knowing exactly what you have done it's impossible to give a concrete answer.
Are you sure that your sine wave is really pure without any noise ?

I know that there is no windowing in the library.
In the demo program there are pure sines set for the time signal and we get pure single frequency lines.
If there were any windowing we would get several lines for each frequency, at least 3 lines with Hanning windowing.
 

Marcob

Member
Licensed User
I investigated a little deeper and you were right, as a matter of fact the leackage effect is present, it was necessary to show the amplitude in a logaritmic scale in order to appreciate it. Thanks a lot for your feedback.
 

maso1975

Member
Licensed User
Hi all,

for more i searched the internet, I read a lot about sampling teroría do not understand how to do it, could someone give an example of how to calculate the Hz frequency of a sample, please I need help.

from what I understand, I can calculate it using the Amplitude array, I think the way to do it is Frequency = 1 / T, where T is the period of time between samples, but as calculation or determine T?


Thank you.
 

klaus

Expert
Licensed User
What exactly do you want to do ?
What exactly do you mean with frequency of a sample ?
Do you want to analyse signal ?
What kind of signal ?
What shape ?
etc.
If you have a pure sine with a time period of T,
then the frequency of the sine is f = 1 / T.
If you have a periodic signal with a time period of T,
then the fundamental frequency of the signal is f = 1 / T, but you will have overlayed harmonic frequencies (Fourier series).
 

maso1975

Member
Licensed User
for example, show an EditText frequency in Hz sound captured through the Mic.

thanks for your quick response
 
Last edited:

maso1975

Member
Licensed User
I have made an example of for and I have modified as follows:

Dim N As Int

N = 16384

Dim sound (N) As Byte
Dim SoundD (N) As Double

DataSize = 0
Log ("Sample ...")
Do While True
As Int Dim Sum
AR.ReadBytes sound = (0, BufferSize)
DataSize = DataSize + Sound.length

If Record.IsInterrupted Then Exit

If DateTime.Now> StartTime + "1000" Then Exit
Loop

For cont = 0 To Sound.length - 1
SoundD (cont) = sound (cont)
Next

As Dim FFT FFT
Dim FFTReal (N / 2) As Double
Dim FFTImg (N / 2) As Double
Dim FFTAmp (N / 2) As Double
FFT.Transform2 (Soundd, FFTReal, FFTImg)
FFTAmp = FFT.ToAmplitude (FFTReal, FFTImg)


As Int Dim Freq
For cont = 0 To Sound.length - 1


Freq = f = 1 / T) ¿¿¿ T ???
Log ("FREQ:" & Freq)

Next

End Sub
 
Last edited:

klaus

Expert
Licensed User
In a FFT signal the x axis represents frequencies and not time !
So you need to know the sample frequency of the signal.
Then one sample step in the frequency domain is Sample frequence / Number of samples.
As an example : Sample frequency = 44100 Hz and Number of samples = 16384
The frequency step is 44100 / 16384 = 2.692 Hz

You must do a peak detection in the FFTAmpl array and with the sample index of the peak you can calculate the frequecy f = frequency step * peak index.
The first peak is the fundamental frequency of the signal.
Do you know the amplitude of the signal ?
The number of samples in FFTAmpl is N/2 so your loop should be For cont = 0 To N / 2
 

NeoTechni

Well-Known Member
Licensed User
Could you dumb that down for us?

I know how to get a sample from the mic, what would we do to pass it to the FFT library to get a bunch of frequency ranges?
 

maso1975

Member
Licensed User
Thanks Klaus,

time I think I'm on track, I would like to look at the code because I'm not sure that is correct.

To generate the frequency use http://www.basic4ppc.com/android/forum/threads/audio-library-v1-2-beeper.11816/#content (BeepFreq.zip) from another device, and the result I get is the half the generated value, for example: if I generate a tone of 500Hz, the result I get in the code is 250hz.

B4X:
    'SampleRate = Sample Frecuency (44100).
    'N = Samples Number (16384).
    'Step frecuency = SampleRate/N = 2.692 Hz (44100 / 16384 = 2.692 Hz).
       
    Dim N As Int
    N = 16384

    Dim sound(N) As Byte
    Dim soundD(N) As Double

    DataSize=0
    Log("Sampling...")
    Do While True
        Dim Sum As Int
        sound = AR.ReadBytes(0,BufferSize)
        DataSize = DataSize + sound.Length
               
        If Record.IsInterrupted Then Exit

        If DateTime.Now > StartTime + "1000" Then Exit
    Loop
   
    For cont = 0 To sound.Length -1
        soundD(cont) = sound(cont)
    Next

    Dim FFT As FFT
    Dim FFTReal(N/2) As Double
    Dim FFTImg(N/2) As Double
    Dim FFTAmp(N/2) As Double
    FFT.Transform2(soundD, FFTReal, FFTImg)
    FFTAmp = FFT.ToAmplitude(FFTReal,FFTImg)
'    FFTPhas = FFT.ToPhase(FFTReal, FFTImg)
   
    Dim Peak As Int = 0
   
    For cont = 0 To N/2 -1
           
        If (FFTAmp(cont) > FFTAmp(Peak)) Then
            Peak = cont
        End If
                               
            Log(SampleRate / N * Peak) 'Frecuency.
    Next



thanks again for your help.
 

klaus

Expert
Licensed User
Could you post the code that reads the samples and the code that generates the signal and I will look at it, would be easier than creating the code myself.
This might be interesting for other users.
 

klaus

Expert
Licensed User
@maso1975
Are you sure that the code in FreqDetect is complete ?
I don't get any record.
I have no experience with the Threading library.
I had a look at the demo in the Threading library and there are Thread.Start routines, but I don't see any Record.Start call in your code ?


 
Last edited:
Top