# Detecting a single frequency in noisy data

I am not very experienced in signal processing, and it seems like this should be a simple problem. I have two computers, one plays a tone a 19 kHz at a sampling rate of 44.1 kHz, and the other listens with a sampling rate of 44.1 kHz and tries to find if the 19kHz tone is present. The transmission of the signal is in a noisy environment, and I have tried to find the amplitude of the 19 kHz wave using an FFT as well as Goertzel, but neither has given me a conclusive value (the amplitudes are very small).

For the FFT, I am using JTransform, running the forwardFFT, then finding the bin in which 19 kHz lies and getting the amplitude by (imaginary * imaginary + real * real) for the components of that frequency bin.

For Goertzel, I followed the pseudo-code on this site: http://www.mstarlabs.com/dsp/goertzel/goertzel.html. I feel like both the FFT and Goertzel should give the same amplitude if the sample size is the same, but they give different values for that frequency bin.

I expect the amplitude to be greater than 10, but I do not believe this is working. I believe I need to at least filter out the noise below 19 kHz as a first step, but am unsure. Maybe some highpass filtering should be done first? Any suggestions on how to detect the 19 kHz sine wave? Thank you. Updated:

Here is a plot of the raw data I am getting from the microphone:

I feel like this is just noise, but I am unsure.

• try a lower frequency tone first - say 1kHz. How long is your window? Does the frequency stay at 19kHz or vary? Jun 8, 2013 at 8:45
• Inclusion of data or plots of your data showing the problem would improve this. If you can't add pictures (too low a rep), upload them to an image-sharing site and post the links here.
– Peter K.
Jun 8, 2013 at 15:12
• If that 'raw data' is in the time domain then there is something wrong with it - the samples should not have such a strong negative bias. Oct 8, 2013 at 17:41
• To test your setup you should use a lower frequency tone, one which is not so close to the nyquist of your sampling frequency, and increase the amplitude such that the 'raw data' clearly demonstrates a sinusoidal appearance. Only then can you practically test your signal processing. Oct 8, 2013 at 17:43
• I agree with @PAK-9: The data you plot is very poor quality. It doesn't look like it's being acquired correctly (or perhaps plotted correctly).
– Peter K.
Oct 9, 2013 at 12:30

## 3 Answers

If your goal is to find only the frequency then its an easy task . Magnitude = sqrt(real*real + img*img) This number will always be positive. Now , find the maximum value of magnitude in the array.

also, frequency = max magnitude*(Fs/N)

Fs = sampling Frequency(44100 in your case) , N = size of FFT Now you have the frequency. But the numerical value depends upon the fft size that you are using i.e 512 size will result in accuracy of 86Hz (+- 86) , 1024 => 43Hz and so on. So , the frequency will be 189__ or 190__ something :)

• Welcome to DSP SE. What do you mean by: frequency = max magnitude*(Fs/N), because it is not straightforward (no functions are given, I suspect that you mean index by max magnitude). Regarding math formatting, please get familiar with following tutorial.
– jojeck
Jul 9, 2014 at 16:41
• exactly , max index. I just meant that if you are getting real and imaginary values , 90-95% part is already done. Jul 10, 2014 at 6:40
• could you please write an elaborate answer? @BingoBango91 Dec 5, 2017 at 22:00

For a decision criteria, compare the energy in the 19 kHz FFT result bin to other adjacent frequency bins and decide whether the magnitudes are different by a statistically sufficient amount, given your noise distribution and level.

You might also want the determine, via other means, that the speaker response curve and microphone anti-aliasing filter in your setup don't roll off below 19 kHz.

• The setup is on an android phone. The speakers should be able to produce up to 21 kHz or so. I know the android market has tone generators that go this high, and playing back these tones shows up on a frequency series plot. Jun 10, 2013 at 3:06
• @Batman: In my experience, you can rarely trust the specs on consumer-grade speakers and microphones. Since 19kHz is inaudible to most, and very attenuated to the rest, you should definitely do a lot of sanity checking along the way. Oct 8, 2013 at 18:54

I think the answer lies in finding an algorithm in which you process the pcm file for only one frequency instead of many like an FFT does. So like you tell the routine to look for whatever frequency [< +/- 0.5 HZ] and it will tell you in some resulting number the amplitude or energy of that specific frequency. I have never seen such an algorithm published and free to use by the general public. In like BASIC or FORTRAN language. Yet, I know, such a single purpose utility program must exist.