Take the 2-minute tour ×

I'm trying to build a gadget that detects pistol shots using Android. It's a part of a training aid for pistol shooters that tells how the shots are distributed in time and I use a HTC Tattoo for testing.

I use the MediaRecorder and its getMaxAmplitude method to get the highest amplitude during the last 1/100 s but it does not work as expected; speech gives me values from getMaxAmplitude in the range from 0 to about 25000 while the pistol shots (or shouting!) only reaches about 15000. With a sampling frequency of 8kHz there should be some samples with considerably high level.

Anyone who knows how these things work? Are there filters that are applied before registering the max amplitude. If so, is it hardware or software?

Thanks, /George

share|improve this question
If you got a bunch of phones with that working you could scatter them around and, with the aid of their GPS systems, use them to locate snipers. –  Spike Mar 19 '10 at 12:49
are you sure your calling getMaxAmplitude at the right time? "Returns the maximum absolute amplitude that was sampled since the last call to this method" you could be sampling it at the wrong time? –  Donal Rafferty Mar 19 '10 at 12:56
@Spike: if Apple rejected "Shake the Baby", I assume Google would have to reject "Spot the Sniper". –  MusiGenesis Mar 19 '10 at 12:58
Donald, I call the function 100 times/second since that is the resultion i need for the time of the shot, and I see that my app reacts on speech. The spectrum of a shot is 3kHz and up a bit higher than normal speech. Perhaps there is a low-pass filter in the mic input :-( –  George Mar 19 '10 at 13:08
@Donal Rafferty: I ran into the problem you are describing. I'm not sure how quickly Android polls the amplitude, but if you do yours too quick then it will return a lot of 0's. –  TheSageMage May 25 '11 at 16:14
add comment

4 Answers

It seems there's an AGC (Automatic Gain Control) filter in place. You should also be able to identify the shot by its frequency characteristics. I would expect it to show up across most of the audible spectrum, but get a spectrum analyzer (there are a few on the app market, like SpectralView) and try identifying the event by its frequency "signature" and amplitude. If you clap your hands what do you get for max amplitude? You could also try covering the phone with something to muffle the sound like a few layers of cloth

share|improve this answer
Shouting and clapping hands are also dampened so you're probably right about the AGC. But will it kick that quickly? The getMaxAmplitude seemed like a good shortcut to avoid doing the spectrum analysis... Thanks! –  George Mar 19 '10 at 13:25
add comment

It seems like AGC is in the media recorder. When I use AudioRecord I can detect shots using the amplitude even though it sometimes reacts on sounds other than shots. This is not a problem since the shooter usually doesn't make any other noise while shooting. But I will do some FFT too to get it perfect :-)

share|improve this answer
add comment

Sounds like you figured out your agc problem. One further suggestion: I'm not sure the FFT is the right tool for the job. You might have better detection and lower CPU use with a sliding power estimator.

e.g. signal => square => moving average => peak detection

All of the above can be implemented very efficiently using fixed point math, which fits well with mobile android platforms.

You can find more info by searching for "Parseval's Theorem" and "CIC filter" (cascaded integrator comb)

share|improve this answer
add comment

Sorry for the late response; I didn't see this question until I started searching for a different problem...

I have started an application to do what I think you're attempting. It's an audio-based lap timer (button to start/stop recording, and loud audio noises for lap setting). It' not finished, but might provide you with a decent base to get started.

Right now, it allows you to monitor the signal volume coming from the mic, and set the ambient noise amount. It's also using the new BSD license, so feel free to check out the code here: http://code.google.com/p/audio-timer/. It's set up to use the 1.5 API to include as many devices as possible.

It's not finished, in that it has two main issues:

  1. The audio capture doesn't currently work for emulated devices because of the unsupported frequency requested
  2. The timer functionality doesn't work yet - was focusing on getting the audio capture first.

I'm looking into the frequency support, but Android doesn't seem to have a way to find out which frequencies are supported without trial and error per-device.

I also have on my local dev machine some extra code to create a layout for the listview items to display "lap" information. Got sidetracked by the frequency problem though. But since the display and audio capture are pretty much done, using the system time to fill in the display values for timing information should be relatively straightforward, and then it shouldn't be too difficult to add the ability to export the data table to a CSV on the SD card.

Let me know if you want to join this project, or if you have any questions.

share|improve this answer
add comment

Your Answer


