Nov
13
2011

Calculating Noise Levels From Uncalibrated Microphones

I’ve recently started creating more features for my WP7 app, Oscilloscope.

Currently all it does is take input from the phone’s microphone, and then displays a waveform on screen, which aside from looking quite cool is fairly gimmicky – I want it to actually have some sort of usefulness, naturally the first thing that would be useful would be knowing the loudness of the noise (in decibels).

The problem with this is that the microphone returns values ranging between 0 and 255 (i.e. a byte), and thus this information is not given, and meant I would have to use this information somehow to calculate it. After a search on the Internet to see how other developers have done it, I discovered that generally without specialised hardware it was not possible, or this value was not required for the developer (so they stopped trying to gain a solution), so I guess doing it the easy way was out of the question!

I next looked up what the actual definition of a decibel was, and this was when I stumbled upon the 10 log rule. Basically what it says is that if you have two different power levels, the 10 log rule will tell you the difference (in dB) between the two (i.e. $difference\ in\ dB = 10 \log({\frac{power_2}{power_1}})$)- note that it is important to remember that a decibel is just a measurement of scale!
This rule is fantastic as it means if I know the “power” of one waveform, and can calculate the difference of another and simply add the known level on it – thus achieving exactly what I wanted!

The only problem now remaining is getting this reference waveform, one of the problems mentioned in my initial searches was that it was impossible because the microphones had not been calibrated, I guess this means I’ll need to perform some sort of software calibration then!
After a few more searches I discovered that typical silence occurs at about 30dB, so what I can do is simply sample some “silence” from the phone and assume this to be my reference of 30dB, although this will not give me 100% correct values (since my reference is probably slightly incorrect), I now have all the basic components I require in order to calculate the noise level in dB.

The final step now is producing a single value from the waveform to use as the “power”, if you haven’t done much signal processing before, you might be tempted to calculate the mean of all the values, although this seems like a sensible idea, if you consider that the AC voltage from the mains alternates is effectively a sinusoidal wave, the mean will be about zero – not very useful! Instead, what is calculated is the RMS (Root Mean Square) value, the name basically describes what you do, you calculate the mean of all the values squared, then square root it (in the case of a sine wave this can be simplified to $\frac{x}{\sqrt{2}}$ where x is your peak value), so this is done once with the reference waveform (as this is all the information required), and then this is calculated with each new waveform I receive from the microphone, the units of these two waveforms don’t matter, so long as they are both the same; what is important is the ratio between the two (as I said earlier, dB is simply a scale of sorts).

I can then throw these values into the 10 log rule and finally get a decibel reading from the microphone!

1 comment

1. Paul Foster says:

Hi Sam,

I’m playing with the MIT Project HiJack on Windows Phone. I like your oscilloscope app but I need one addition to be able to reproduce the iphone HiJack Oscilloscope solution quickly. Can you please drop me an email?

thanks
Paul