tags:

views:

751

answers:

9

The Dell Streak has been discovered to have an FM radio which has very crude controls. 'Scanning' is unavailable by default, so my question is does anyone know how, using Java on Android, one might 'listen' to the FM radio as we iterate up through the frequency range detecting white noise (or a good signal) so as to act much like a normal radio's seek function?

+3  A: 

For white noise detection you need to do FFT and see that it has more or less continious spectrum. But recording from FM might be a problem.

BarsMonster
+16  A: 

Use a Fast Fourier Transform.

This is what you can use a Fast Fourier Transform for. It analyzes the signal and determines the strength of the signal at various frequencies. If there's a spike in the FFT curve at all, it should indicate that the signal is not simply white noise.

Here is a library which supports FFT's. Also, here is a blog with source code in case you want to learn about what the FFT does.

Erick Robertson
How many milliseconds of audio do you need to collect before being able to apply a usable FFT?
Nicolas Raoul
You are talking here about the EM signal he would get. FFT can help but PLL would be better. Unfortunately you don't have that signal...
BenoitParis
Any fft window size over about 32 samples will give perfectly useable values for testing of noisyness (32 instances is enough for the white noise entropy to average out enough in comparison to acoustic details). I would recommend ffting sparsely, around 1/10th of the whole signal and keeping the window under 200 samples, it avoids wastefull processing demands and incidentally doesnt wash out localised/percussive type sounds in an overly long measure.
strainer
Important note: *"If there's a spike in the FFT curve at all"* has to be evaluated with a correct understanding of the statistics of random measurements. The result of this is that there will be cases with very clear signals and cases with clear lack of signals but also cases with peaks at the few-sigma level which could be either. For those, sample again---maybe with a longer sample, too.
dmckee
+7  A: 

If you don't have FFT tools available, just a wild suggestion:
Try to compress a few milliseconds of audio.

A typical feature of noise is that it compresses much less than clear signal.

Nicolas Raoul
That's an interesting way to do it but I have doubts...would it be able to recognise a channel that had a low amount of noise? Also it would be very dependant on the compression algorithm used - what would be a good algorithm?
CiscoIPPhone
That's really a wild suggestion. Do you think about lossless compression (zip) or audio compression like mp3 or ogg?
Andreas_D
Extremely wild indeed! I was thinking about something like zip, but now that you say this, mp3/ogg is a very interesting idea, closer to doing a FFT actually.
Nicolas Raoul
Just wanted to clarify that you mean data compression as opposed to audio compression.
steamer25
strainer's idea is much better than mine.
Nicolas Raoul
+1  A: 

Do you have a subscription to the IEEE Xplore library? There are countless papers (one picked at random) on this very topic.

A very simplistic method would be to observe the "flatness" of the power spectral density. One could take this by using a Fast Fourier Transform of the signal in the time domain and find the standard deviation of the spectral density. If it is below some threshold, you have your white noise.

Sedate Alien
A: 

The main question here is: what type of signal do you have access to?

I bet you don't have direct access to the analog EM signal directly. So no use of FFT on this signal possible. You can't also try to build a phased-lock loop, which is the way your standard old radio tuner works ("Scanning" in your case).

Your only option is indeed to pick one frequency and listen too it (and try do detect when it's noise with FFT on sound). You might even only have access to the FFTed signal.

Problem here: If you want to detect a potential frequency using white noise you will pick up signals too easily.


Anyway, here is what I would try to do with this strategy:

Double integrate the autocorrelation of the spectral density over a fraction of a second of audio. And this for each frequency.

Then look for a FM frequency where this number is maxed.

Little explanation here:

  • Spectral density gives you a signal which most used frequencies are maxed.
  • If a bit of time later if the same frequencies are maxed then you have some supposedly clear audio. You get this by integrating the autocorrelation the spectral density for one audio frequency for a fraction of a second (using some function that grows larger than linear might also work)
  • You then just have to integrate this for all audio frequencies

Also be careful to normalize the integrals: a loud white noise signal should not get a higher score than a clear but low audio signal.

BenoitParis
Compressing might also help (ressource intensive maybe?)
BenoitParis
+5  A: 

As far as I know there is no API or even drivers for the FM Radio in the Android SDK and unless Dell releases one you will have to roll your own. It's actually even worse than that. All(?) new chipsets has FM Radio but not all phones has an FM Radio application.

The old Windows Mobile had the same problem.

Jonas Elfström
+9  A: 

I have done some practical work on this specific area, i would recommend (if you have a little time for it) to try just a little experimentation before resorting to fft'ing. The pcm stream can be interpreted very complexely and subtly (as per high quality filtering and resampling) but can also be practically treated for many purposes as the path of a wiggly line.

White noise is unpredictable shaking of the line, which is never-the-less quite continuous in intensity (rms, absolute mean..) Acoustic content is recurrent wiggling and occasional surprises (jumps, leaps) :]

Non-noise like content of a signal may be estimated by performing quick calculations on a running window of the pcm stream.

For example, noise will strongly tend to have a higher value for the absolute integral of its derivative, than non-noise. I think that is the academic way of saying this:

loop(n+1 to n.length)
{ sumd0+= abs(pcm[n]); 
  sumd1+= abs(pcm[n]-pcm[n-1]); 
}

wNoiseRatio = ?0.8; //quite easily discovered, bit tricky to calculate.

if((sumd1/sumd0)<wNoiseRatio)
{ /*not like noise*/ }

Also, the running absolute average over ~16 to ~30 samples of white noise will tend to vary less, over white noise than acoustic signal:

loop(n+24 to n.length-16)
{ runAbsAve1 += abs(pcm[n]) - abs(pcm[n-24]); }

loop(n+24+16 to n.length)
{ runAbsAve2 += abs(pcm[n]) - abs(pcm[n-24]); }

unusualDif= 5; //a factor. tighter values for longer measures.

if(abs(runAbsAve1-runAbsAve2)>(runAbsAve1+runAbsAve2)/(2*unusualDif))
{ /*not like noise*/ }

This concerns how white noise tends to be non-sporadic over large enough span to average out its entropy. Acoustic content is sporadic (localised power) and recurrent (repetitive power). The simple test reacts to acoustic content with lower frequencies and could be drowned out by high frequency content. There are simple to apply lowpass filters which could help (and no doubt other adaptions).

Also, the root mean square can be divided by the mean absolute sum providing another ratio which should be particular to white noise, though i cant figure what it is right now. The ratio will also differ for the signals derivatives as well.

I think of these as being simple formulaic signatures of noise. I'm sure there are more.. Sorry to not be more specific, it is fuzzy and imprecise advice, but so is performing simple tests on the output of an fft. For better explaination and more ideas perhaps check out statistical and stochastic(?) measurements of entropy and randomness on wikipedia etc.

strainer
+1 I thinks it is the easiest and most performant solution. By derivating, it will indeed detect the randomistic nature of noise. And it works even with short sampling time, which means fast scanning.
Nicolas Raoul
It must be a good point because my explaination was/is so messy. I've tried fixing it up a bit.
strainer
Thanks for this - the remark below about Android having no API access could be (and probably is) a stumbling block, but if I do have any access then I will probably adopt this method.
Antony Koch
Thanks, I noticed Jonas' warning too. It will be a shame if you can't peek at the audio stream somehow and control volume and seek on the radio. I would have hoped that an open platform should provide access like that. Goodluck'
strainer
A: 

Several people have mentioned the FFT, which you'll want to do, but to then detect white noise you need to make sure that the magnitude is relatively constant over the range of audio frequencies. You'll want to look at magnitudes only, you can throw away the phases. You can compute an average and standard deviation for the magnitudes in O(N) time. For white noise, you should find the standard deviation to be a relatively small fraction of the average. If I remember my statistics right, it should be about (1/sqrt(N)) of the average.

Will Ware
+1  A: 

Just high pass filtering it will give a good idea, and has sometimes been used for squelch on fm radios.

Note that this is comparable to what the derivative suggestion was getting at - taking the derivative is a simple form of high pass filter, and taking the absolute value of that a crude way of measuring power.

Chris Stratton