Android Question recognize a sound with the FFT library

Nkalampika

Active Member
Licensed User
Hello I would like to recognize a sound (beep) that is in a wav file and compare it with a direct sound! how to do it ?
 

klaus

Expert
Licensed User
What exactly did you do?
I tested the program with N = 128 and it works.
Anyway, for a beep test with low sample values you are loosing accuracy.
With 1024 samples, the frequency resolution is 43.1 Hz quite unaccurate.
 
Last edited:
Upvote 0

jemajuca

Member
Licensed User
Hi Klaus!
Something seems different. I just tested BeepTest from this thread, with N = 128 and it slows and turns irresponsive.
I'm testing on release mode with #BridgeLogger: True, and Audio library version 1.63.
The unfiltered log outputs this:

ViewPostImeInputStage processPointer 0
ViewPostImeInputStage processPointer 1
Skipped 30 frames! The application may be doing too much work on its main thread.
Skipped 53 frames! The application may be doing too much work on its main thread.
ViewPostImeInputStage processPointer 0
ViewPostImeInputStage processPointer 1
Skipped 115 frames! The application may be doing too much work on its main thread.
Skipped 268 frames! The application may be doing too much work on its main thread.
Background sticky concurrent mark sweep GC freed 85406(10MB) AllocSpace objects, 0(0B) LOS objects, 21% free, 38MB/49MB, paused 9.697ms total 87.706ms
Skipped 1320 frames! The application may be doing too much work on its main thread.
...

I will try with a different audio library version.
 
Upvote 0

klaus

Expert
Licensed User
The problem is that the time for calculation and display is longer than the aquisition time.
Therefore the buffer size is increasing too much providing memory overflow.
Just for testing, I tryed this code in the Record routine:
B4X:
'        For i = 0 To N - 1    'deletes the used values from the buffer
'            TimeBuffer.RemoveAt(0)
'        Next
        TimeBuffer.Clear
The program works, but it is missing samples.
 
Upvote 0

canalrun

Well-Known Member
Licensed User
I have done that before – recognize a tone in real time using FFT's. I believe I may have used Klaus' FFT library or I may have used my own. Search this Forum for "Canalrun FFT", maybe I uploaded it, I don't remember.

Barry.

I have been lurking on this thread. Back around post #10 I mentioned a project I had done years ago. I was able to find that project and have included a Dropbox link:
https://www.dropbox.com/s/cryql0u29xbz85y/CRSpec.zip?dl=0
It is too big to attach.

upload_2018-11-21_20-1-36.png


The link points to a zip file that includes the APK, B4A project with source, library files, and Java library source. I compiled the library using Eclipse and the Simple Library Compiler.

The library source contains the source code for a fast implementation of an FFT. I think the speed gain in this particular FFT implementation might come from the fact that it pre-computes and stores the FFT coefficients.

The library also contains code to read audio data from the microphone. My implementation allows the audio data buffer size to be set. I set this to the same size as my FFT – to make things easier.

The example app displays real-time spectrum. The audio input is from the microphone. It also includes five generated sign waveforms to test the FFT execution (the above display is generated by Test3).

A little warning: I built this app with an old version of B4A, 4.30. The App requires the permission READ_AUDIO which I believe now has to be allowed at run time. I use a target SDK of 19. I test with android 6.0. I'm not sure how it will operate on more modern devices.

I use a sample rate of 22050, an audio buffer and FFT size of 1024. I compute and display the square root of magnitude squares. According to my rough timing calculations the FFT with signal generation, scaling, and mag squares requires about 0.8 ms on my Samsung S5. With a sample rate at 22050 and an audio buffer of 1024, this gives a buffer rate of about 46 ms - real-time is easily achieved.

One of the original applications earlier in this thread was to detect the duration of a tone (beep). Detecting a tone is similar to my ultimate application using this library.

What I might do is determine the frequency of the beep: The beep will show up as a peak in one of the displayed magnitude bins. Figure out which bin it shows up in then continuously process FFTs looking for a signal threshold crossing in that bin. Count the number of consecutive audio buffers with that threshold crossing to get the duration.

Barry.
 

Attachments

  • upload_2018-11-21_20-26-43.png
    upload_2018-11-21_20-26-43.png
    14.1 KB · Views: 105
  • upload_2018-11-21_20-26-51.png
    upload_2018-11-21_20-26-51.png
    14.1 KB · Views: 99
Last edited:
Upvote 0

jemajuca

Member
Licensed User
What kind of signal do want to measure?
Depending on the signal type, there is no real period (example: sounds).
The signal is a sound generated with a microcontroller. It is squared.


I have been lurking on this thread. Back around post #10 I mentioned a project I had done years ago. I was able to find that project and have included...
Thank you for sharing this.
In a first try, it throws an error:

B4A Version: 8.50
Parsing code. (0.00s)
Building folders structure. (0.02s)
Compiling code. (0.03s)
Compiling layouts code. (0.02s)
Organizing libraries. (0.01s)
Generating R file. Error
ERROR: Unable to open class file gen\canalrun\apps\spect\R.java: No such file or directory
 
Upvote 0

klaus

Expert
Licensed User
The signal is a sound generated with a microcontroller. It is squared.
With a quare signal it would be more efficient to check directly the time signal.

In a first try, it throws an error:
Try the attached one.
You need the CRSpectrum library included in canalruns' zip file and the NanoTime library.
 

Attachments

  • CRSpec1.zip
    122.5 KB · Views: 158
Upvote 0

jemajuca

Member
Licensed User
Hi Klaus.
For any reason I was getting that error, even with the two libraries installed.
Now, testing your code, it is running OK.
Thank you.
 
Upvote 0

canalrun

Well-Known Member
Licensed User
With a quare signal it would be more efficient to check directly the time signal.


Try the attached one.
You need the CRSpectrum library included in canalruns' zip file and the NanoTime library.

Yes, as Klaus mentions I forgot to include the instructions for compiling the B4A example.

Place the two CRSpectrum library files I include in the lib directory into your B4A additional libraries folder.

I also use the NanoTime library from stevel05. This can be found on the forum. It should be downloaded and the two library files included in the additional libraries folder.

Barry.
 
Upvote 0

canalrun

Well-Known Member
Licensed User
Hello. Unfortunately I haven't updated the library and I am no longer able to compile libraries on my workstation.

I have, more recently, uploaded the source code for an FFT test app. The most useful thing in this upload is a module containing the full source code for a very fast FFT. It should be little trouble to utilize this rather than my older library.

 
Upvote 0

emexes

Expert
Licensed User
I will try it.

I need to detect a known frequency from a morse code using your example.
The morse code dot duration is 100ms and dash is 300ms and the frequency of the signal is 2KHz.

If your app just needs to detect Morse code tones, and you can't get a FFT library going on whatever device you're currently working with, let me know. FFT is great, but for detecting simple tones of a known frequency, it is a large hammer to crack a small nut. ✌

Edit: if you do get the FFT going and your app working again, then stick with that. 🍻
 
Upvote 0

jemajuca

Member
Licensed User
Thank you for point that.
It is not just a morse tone. I need to detect different known frequencies in a signal stream, so FFT seems to be the best way.
 
Upvote 0
Top